Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
kernel_linux
提交
3315764e
K
kernel_linux
项目概览
OpenHarmony
/
kernel_linux
上一次同步 4 年多
通知
15
Star
8
Fork
2
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
kernel_linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
3315764e
编写于
12月 08, 2014
作者:
T
Tomi Valkeinen
浏览文件
操作
浏览文件
下载
差异文件
Merge branches '3.19/omapdss' and '3.19/simplefb' into fbdev
Merge fbdev topic branches.
上级
34685627
f3b7d0ef
b14c9929
变更
39
展开全部
隐藏空白更改
内联
并排
Showing
39 changed file
with
2352 addition
and
1709 deletion
+2352
-1709
Documentation/devicetree/bindings/video/simple-framebuffer-sunxi.txt
...on/devicetree/bindings/video/simple-framebuffer-sunxi.txt
+33
-0
Documentation/devicetree/bindings/video/simple-framebuffer.txt
...entation/devicetree/bindings/video/simple-framebuffer.txt
+64
-4
MAINTAINERS
MAINTAINERS
+8
-0
drivers/video/console/fbcon.c
drivers/video/console/fbcon.c
+1
-1
drivers/video/fbdev/omap2/displays-new/connector-hdmi.c
drivers/video/fbdev/omap2/displays-new/connector-hdmi.c
+0
-99
drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c
drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c
+1
-0
drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c
drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c
+1
-56
drivers/video/fbdev/omap2/dss/Kconfig
drivers/video/fbdev/omap2/dss/Kconfig
+0
-7
drivers/video/fbdev/omap2/dss/Makefile
drivers/video/fbdev/omap2/dss/Makefile
+1
-1
drivers/video/fbdev/omap2/dss/dispc.c
drivers/video/fbdev/omap2/dss/dispc.c
+10
-10
drivers/video/fbdev/omap2/dss/dpi.c
drivers/video/fbdev/omap2/dss/dpi.c
+202
-125
drivers/video/fbdev/omap2/dss/dsi.c
drivers/video/fbdev/omap2/dss/dsi.c
+240
-419
drivers/video/fbdev/omap2/dss/dss-of.c
drivers/video/fbdev/omap2/dss/dss-of.c
+40
-18
drivers/video/fbdev/omap2/dss/dss.c
drivers/video/fbdev/omap2/dss/dss.c
+86
-37
drivers/video/fbdev/omap2/dss/dss.h
drivers/video/fbdev/omap2/dss/dss.h
+117
-108
drivers/video/fbdev/omap2/dss/dss_features.c
drivers/video/fbdev/omap2/dss/dss_features.c
+0
-42
drivers/video/fbdev/omap2/dss/dss_features.h
drivers/video/fbdev/omap2/dss/dss_features.h
+0
-12
drivers/video/fbdev/omap2/dss/hdmi.h
drivers/video/fbdev/omap2/dss/hdmi.h
+42
-29
drivers/video/fbdev/omap2/dss/hdmi4.c
drivers/video/fbdev/omap2/dss/hdmi4.c
+160
-178
drivers/video/fbdev/omap2/dss/hdmi4_core.c
drivers/video/fbdev/omap2/dss/hdmi4_core.c
+0
-14
drivers/video/fbdev/omap2/dss/hdmi4_core.h
drivers/video/fbdev/omap2/dss/hdmi4_core.h
+0
-4
drivers/video/fbdev/omap2/dss/hdmi5.c
drivers/video/fbdev/omap2/dss/hdmi5.c
+165
-173
drivers/video/fbdev/omap2/dss/hdmi5_core.c
drivers/video/fbdev/omap2/dss/hdmi5_core.c
+4
-7
drivers/video/fbdev/omap2/dss/hdmi5_core.h
drivers/video/fbdev/omap2/dss/hdmi5_core.h
+0
-2
drivers/video/fbdev/omap2/dss/hdmi_common.c
drivers/video/fbdev/omap2/dss/hdmi_common.c
+0
-2
drivers/video/fbdev/omap2/dss/hdmi_phy.c
drivers/video/fbdev/omap2/dss/hdmi_phy.c
+11
-20
drivers/video/fbdev/omap2/dss/hdmi_pll.c
drivers/video/fbdev/omap2/dss/hdmi_pll.c
+137
-176
drivers/video/fbdev/omap2/dss/hdmi_wp.c
drivers/video/fbdev/omap2/dss/hdmi_wp.c
+12
-4
drivers/video/fbdev/omap2/dss/output.c
drivers/video/fbdev/omap2/dss/output.c
+16
-3
drivers/video/fbdev/omap2/dss/pll.c
drivers/video/fbdev/omap2/dss/pll.c
+378
-0
drivers/video/fbdev/omap2/dss/sdi.c
drivers/video/fbdev/omap2/dss/sdi.c
+1
-1
drivers/video/fbdev/simplefb.c
drivers/video/fbdev/simplefb.c
+151
-11
include/linux/of.h
include/linux/of.h
+1
-2
include/sound/omap-hdmi-audio.h
include/sound/omap-hdmi-audio.h
+43
-0
include/video/omapdss.h
include/video/omapdss.h
+4
-41
sound/soc/omap/Kconfig
sound/soc/omap/Kconfig
+14
-12
sound/soc/omap/Makefile
sound/soc/omap/Makefile
+2
-4
sound/soc/omap/omap-hdmi-audio.c
sound/soc/omap/omap-hdmi-audio.c
+407
-0
sound/soc/omap/omap-hdmi-card.c
sound/soc/omap/omap-hdmi-card.c
+0
-87
未找到文件。
Documentation/devicetree/bindings/video/simple-framebuffer-sunxi.txt
0 → 100644
浏览文件 @
3315764e
Sunxi specific Simple Framebuffer bindings
This binding documents sunxi specific extensions to the simple-framebuffer
bindings. The sunxi simplefb u-boot code relies on the devicetree containing
pre-populated simplefb nodes.
These extensions are intended so that u-boot can select the right node based
on which pipeline is being used. As such they are solely intended for
firmware / bootloader use, and the OS should ignore them.
Required properties:
- compatible: "allwinner,simple-framebuffer"
- allwinner,pipeline, one of:
"de_be0-lcd0"
"de_be1-lcd1"
"de_be0-lcd0-hdmi"
"de_be1-lcd1-hdmi"
Example:
chosen {
#address-cells = <1>;
#size-cells = <1>;
ranges;
framebuffer@0 {
compatible = "allwinner,simple-framebuffer", "simple-framebuffer";
allwinner,pipeline = "de_be0-lcd0-hdmi";
clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 43>,
<&ahb_gates 44>;
status = "disabled";
};
};
Documentation/devicetree/bindings/video/simple-framebuffer.txt
浏览文件 @
3315764e
Simple Framebuffer
Simple Framebuffer
A simple frame-buffer describes a raw memory region that may be rendered to,
A simple frame-buffer describes a frame-buffer setup by firmware or
with the assumption that the display hardware has already been set up to scan
the bootloader, with the assumption that the display hardware has already
out from that buffer.
been set up to scan out from the memory pointed to by the reg property.
Since simplefb nodes represent runtime information they must be sub-nodes of
the chosen node (*). Simplefb nodes must be named "framebuffer@<address>".
If the devicetree contains nodes for the display hardware used by a simplefb,
then the simplefb node must contain a property called "display", which
contains a phandle pointing to the primary display hw node, so that the OS
knows which simplefb to disable when handing over control to a driver for the
real hardware. The bindings for the hw nodes must specify which node is
considered the primary node.
It is advised to add display# aliases to help the OS determine how to number
things. If display# aliases are used, then if the simplefb node contains a
"display" property then the /aliases/display# path must point to the display
hw node the "display" property points to, otherwise it must point directly
to the simplefb node.
If a simplefb node represents the preferred console for user interaction,
then the chosen node's stdout-path property should point to it, or to the
primary display hw node, as with display# aliases. If display aliases are
used then it should be set to the alias instead.
It is advised that devicetree files contain pre-filled, disabled framebuffer
nodes, so that the firmware only needs to update the mode information and
enable them. This way if e.g. later on support for more display clocks get
added, the simplefb nodes will already contain this info and the firmware
does not need to be updated.
If pre-filled framebuffer nodes are used, the firmware may need extra
information to find the right node. In that case an extra platform specific
compatible and platform specific properties should be used and documented,
see e.g. simple-framebuffer-sunxi.txt .
Required properties:
Required properties:
- compatible: "simple-framebuffer"
- compatible: "simple-framebuffer"
...
@@ -14,13 +46,41 @@ Required properties:
...
@@ -14,13 +46,41 @@ Required properties:
- r5g6b5 (16-bit pixels, d[15:11]=r, d[10:5]=g, d[4:0]=b).
- r5g6b5 (16-bit pixels, d[15:11]=r, d[10:5]=g, d[4:0]=b).
- a8b8g8r8 (32-bit pixels, d[31:24]=a, d[23:16]=b, d[15:8]=g, d[7:0]=r).
- a8b8g8r8 (32-bit pixels, d[31:24]=a, d[23:16]=b, d[15:8]=g, d[7:0]=r).
Optional properties:
- clocks : List of clocks used by the framebuffer. Clocks listed here
are expected to already be configured correctly. The OS must
ensure these clocks are not modified or disabled while the
simple framebuffer remains active.
- display : phandle pointing to the primary display hardware node
Example:
Example:
framebuffer {
aliases {
display0 = &lcdc0;
}
chosen {
framebuffer0: framebuffer@1d385000 {
compatible = "simple-framebuffer";
compatible = "simple-framebuffer";
reg = <0x1d385000 (1600 * 1200 * 2)>;
reg = <0x1d385000 (1600 * 1200 * 2)>;
width = <1600>;
width = <1600>;
height = <1200>;
height = <1200>;
stride = <(1600 * 2)>;
stride = <(1600 * 2)>;
format = "r5g6b5";
format = "r5g6b5";
clocks = <&ahb_gates 36>, <&ahb_gates 43>, <&ahb_gates 44>;
display = <&lcdc0>;
};
stdout-path = "display0";
};
soc@01c00000 {
lcdc0: lcdc@1c0c000 {
compatible = "allwinner,sun4i-a10-lcdc";
...
};
};
};
*) Older devicetree files may have a compatible = "simple-framebuffer" node
in a different place, operating systems must first enumerate any compatible
nodes found under chosen and then check for other compatible nodes.
MAINTAINERS
浏览文件 @
3315764e
...
@@ -8442,6 +8442,14 @@ F: drivers/media/usb/siano/
...
@@ -8442,6 +8442,14 @@ F: drivers/media/usb/siano/
F: drivers/media/usb/siano/
F: drivers/media/usb/siano/
F: drivers/media/mmc/siano/
F: drivers/media/mmc/siano/
SIMPLEFB FB DRIVER
M: Hans de Goede <hdegoede@redhat.com>
L: linux-fbdev@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/video/simple-framebuffer.txt
F: drivers/video/fbdev/simplefb.c
F: include/linux/platform_data/simplefb.h
SH_VEU V4L2 MEM2MEM DRIVER
SH_VEU V4L2 MEM2MEM DRIVER
L: linux-media@vger.kernel.org
L: linux-media@vger.kernel.org
S: Orphan
S: Orphan
...
...
drivers/video/console/fbcon.c
浏览文件 @
3315764e
...
@@ -3624,7 +3624,7 @@ static int __init fb_console_init(void)
...
@@ -3624,7 +3624,7 @@ static int __init fb_console_init(void)
return
0
;
return
0
;
}
}
module_init
(
fb_console_init
);
fs_initcall
(
fb_console_init
);
#ifdef MODULE
#ifdef MODULE
...
...
drivers/video/fbdev/omap2/displays-new/connector-hdmi.c
浏览文件 @
3315764e
...
@@ -170,98 +170,6 @@ static bool hdmic_detect(struct omap_dss_device *dssdev)
...
@@ -170,98 +170,6 @@ static bool hdmic_detect(struct omap_dss_device *dssdev)
return
in
->
ops
.
hdmi
->
detect
(
in
);
return
in
->
ops
.
hdmi
->
detect
(
in
);
}
}
static
int
hdmic_audio_enable
(
struct
omap_dss_device
*
dssdev
)
{
struct
panel_drv_data
*
ddata
=
to_panel_data
(
dssdev
);
struct
omap_dss_device
*
in
=
ddata
->
in
;
int
r
;
/* enable audio only if the display is active */
if
(
!
omapdss_device_is_enabled
(
dssdev
))
return
-
EPERM
;
r
=
in
->
ops
.
hdmi
->
audio_enable
(
in
);
if
(
r
)
return
r
;
dssdev
->
audio_state
=
OMAP_DSS_AUDIO_ENABLED
;
return
0
;
}
static
void
hdmic_audio_disable
(
struct
omap_dss_device
*
dssdev
)
{
struct
panel_drv_data
*
ddata
=
to_panel_data
(
dssdev
);
struct
omap_dss_device
*
in
=
ddata
->
in
;
in
->
ops
.
hdmi
->
audio_disable
(
in
);
dssdev
->
audio_state
=
OMAP_DSS_AUDIO_DISABLED
;
}
static
int
hdmic_audio_start
(
struct
omap_dss_device
*
dssdev
)
{
struct
panel_drv_data
*
ddata
=
to_panel_data
(
dssdev
);
struct
omap_dss_device
*
in
=
ddata
->
in
;
int
r
;
/*
* No need to check the panel state. It was checked when trasitioning
* to AUDIO_ENABLED.
*/
if
(
dssdev
->
audio_state
!=
OMAP_DSS_AUDIO_ENABLED
)
return
-
EPERM
;
r
=
in
->
ops
.
hdmi
->
audio_start
(
in
);
if
(
r
)
return
r
;
dssdev
->
audio_state
=
OMAP_DSS_AUDIO_PLAYING
;
return
0
;
}
static
void
hdmic_audio_stop
(
struct
omap_dss_device
*
dssdev
)
{
struct
panel_drv_data
*
ddata
=
to_panel_data
(
dssdev
);
struct
omap_dss_device
*
in
=
ddata
->
in
;
in
->
ops
.
hdmi
->
audio_stop
(
in
);
dssdev
->
audio_state
=
OMAP_DSS_AUDIO_ENABLED
;
}
static
bool
hdmic_audio_supported
(
struct
omap_dss_device
*
dssdev
)
{
struct
panel_drv_data
*
ddata
=
to_panel_data
(
dssdev
);
struct
omap_dss_device
*
in
=
ddata
->
in
;
if
(
!
omapdss_device_is_enabled
(
dssdev
))
return
false
;
return
in
->
ops
.
hdmi
->
audio_supported
(
in
);
}
static
int
hdmic_audio_config
(
struct
omap_dss_device
*
dssdev
,
struct
omap_dss_audio
*
audio
)
{
struct
panel_drv_data
*
ddata
=
to_panel_data
(
dssdev
);
struct
omap_dss_device
*
in
=
ddata
->
in
;
int
r
;
/* config audio only if the display is active */
if
(
!
omapdss_device_is_enabled
(
dssdev
))
return
-
EPERM
;
r
=
in
->
ops
.
hdmi
->
audio_config
(
in
,
audio
);
if
(
r
)
return
r
;
dssdev
->
audio_state
=
OMAP_DSS_AUDIO_CONFIGURED
;
return
0
;
}
static
int
hdmic_set_hdmi_mode
(
struct
omap_dss_device
*
dssdev
,
bool
hdmi_mode
)
static
int
hdmic_set_hdmi_mode
(
struct
omap_dss_device
*
dssdev
,
bool
hdmi_mode
)
{
{
struct
panel_drv_data
*
ddata
=
to_panel_data
(
dssdev
);
struct
panel_drv_data
*
ddata
=
to_panel_data
(
dssdev
);
...
@@ -296,13 +204,6 @@ static struct omap_dss_driver hdmic_driver = {
...
@@ -296,13 +204,6 @@ static struct omap_dss_driver hdmic_driver = {
.
detect
=
hdmic_detect
,
.
detect
=
hdmic_detect
,
.
set_hdmi_mode
=
hdmic_set_hdmi_mode
,
.
set_hdmi_mode
=
hdmic_set_hdmi_mode
,
.
set_hdmi_infoframe
=
hdmic_set_infoframe
,
.
set_hdmi_infoframe
=
hdmic_set_infoframe
,
.
audio_enable
=
hdmic_audio_enable
,
.
audio_disable
=
hdmic_audio_disable
,
.
audio_start
=
hdmic_audio_start
,
.
audio_stop
=
hdmic_audio_stop
,
.
audio_supported
=
hdmic_audio_supported
,
.
audio_config
=
hdmic_audio_config
,
};
};
static
int
hdmic_probe_pdata
(
struct
platform_device
*
pdev
)
static
int
hdmic_probe_pdata
(
struct
platform_device
*
pdev
)
...
...
drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c
浏览文件 @
3315764e
...
@@ -249,6 +249,7 @@ static int tfp410_probe(struct platform_device *pdev)
...
@@ -249,6 +249,7 @@ static int tfp410_probe(struct platform_device *pdev)
dssdev
->
output_type
=
OMAP_DISPLAY_TYPE_DVI
;
dssdev
->
output_type
=
OMAP_DISPLAY_TYPE_DVI
;
dssdev
->
owner
=
THIS_MODULE
;
dssdev
->
owner
=
THIS_MODULE
;
dssdev
->
phy
.
dpi
.
data_lines
=
ddata
->
data_lines
;
dssdev
->
phy
.
dpi
.
data_lines
=
ddata
->
data_lines
;
dssdev
->
port_num
=
1
;
r
=
omapdss_register_output
(
dssdev
);
r
=
omapdss_register_output
(
dssdev
);
if
(
r
)
{
if
(
r
)
{
...
...
drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c
浏览文件 @
3315764e
...
@@ -193,55 +193,6 @@ static bool tpd_detect(struct omap_dss_device *dssdev)
...
@@ -193,55 +193,6 @@ static bool tpd_detect(struct omap_dss_device *dssdev)
return
gpio_get_value_cansleep
(
ddata
->
hpd_gpio
);
return
gpio_get_value_cansleep
(
ddata
->
hpd_gpio
);
}
}
static
int
tpd_audio_enable
(
struct
omap_dss_device
*
dssdev
)
{
struct
panel_drv_data
*
ddata
=
to_panel_data
(
dssdev
);
struct
omap_dss_device
*
in
=
ddata
->
in
;
return
in
->
ops
.
hdmi
->
audio_enable
(
in
);
}
static
void
tpd_audio_disable
(
struct
omap_dss_device
*
dssdev
)
{
struct
panel_drv_data
*
ddata
=
to_panel_data
(
dssdev
);
struct
omap_dss_device
*
in
=
ddata
->
in
;
in
->
ops
.
hdmi
->
audio_disable
(
in
);
}
static
int
tpd_audio_start
(
struct
omap_dss_device
*
dssdev
)
{
struct
panel_drv_data
*
ddata
=
to_panel_data
(
dssdev
);
struct
omap_dss_device
*
in
=
ddata
->
in
;
return
in
->
ops
.
hdmi
->
audio_start
(
in
);
}
static
void
tpd_audio_stop
(
struct
omap_dss_device
*
dssdev
)
{
struct
panel_drv_data
*
ddata
=
to_panel_data
(
dssdev
);
struct
omap_dss_device
*
in
=
ddata
->
in
;
in
->
ops
.
hdmi
->
audio_stop
(
in
);
}
static
bool
tpd_audio_supported
(
struct
omap_dss_device
*
dssdev
)
{
struct
panel_drv_data
*
ddata
=
to_panel_data
(
dssdev
);
struct
omap_dss_device
*
in
=
ddata
->
in
;
return
in
->
ops
.
hdmi
->
audio_supported
(
in
);
}
static
int
tpd_audio_config
(
struct
omap_dss_device
*
dssdev
,
struct
omap_dss_audio
*
audio
)
{
struct
panel_drv_data
*
ddata
=
to_panel_data
(
dssdev
);
struct
omap_dss_device
*
in
=
ddata
->
in
;
return
in
->
ops
.
hdmi
->
audio_config
(
in
,
audio
);
}
static
int
tpd_set_infoframe
(
struct
omap_dss_device
*
dssdev
,
static
int
tpd_set_infoframe
(
struct
omap_dss_device
*
dssdev
,
const
struct
hdmi_avi_infoframe
*
avi
)
const
struct
hdmi_avi_infoframe
*
avi
)
{
{
...
@@ -275,13 +226,6 @@ static const struct omapdss_hdmi_ops tpd_hdmi_ops = {
...
@@ -275,13 +226,6 @@ static const struct omapdss_hdmi_ops tpd_hdmi_ops = {
.
detect
=
tpd_detect
,
.
detect
=
tpd_detect
,
.
set_infoframe
=
tpd_set_infoframe
,
.
set_infoframe
=
tpd_set_infoframe
,
.
set_hdmi_mode
=
tpd_set_hdmi_mode
,
.
set_hdmi_mode
=
tpd_set_hdmi_mode
,
.
audio_enable
=
tpd_audio_enable
,
.
audio_disable
=
tpd_audio_disable
,
.
audio_start
=
tpd_audio_start
,
.
audio_stop
=
tpd_audio_stop
,
.
audio_supported
=
tpd_audio_supported
,
.
audio_config
=
tpd_audio_config
,
};
};
static
int
tpd_probe_pdata
(
struct
platform_device
*
pdev
)
static
int
tpd_probe_pdata
(
struct
platform_device
*
pdev
)
...
@@ -409,6 +353,7 @@ static int tpd_probe(struct platform_device *pdev)
...
@@ -409,6 +353,7 @@ static int tpd_probe(struct platform_device *pdev)
dssdev
->
type
=
OMAP_DISPLAY_TYPE_HDMI
;
dssdev
->
type
=
OMAP_DISPLAY_TYPE_HDMI
;
dssdev
->
output_type
=
OMAP_DISPLAY_TYPE_HDMI
;
dssdev
->
output_type
=
OMAP_DISPLAY_TYPE_HDMI
;
dssdev
->
owner
=
THIS_MODULE
;
dssdev
->
owner
=
THIS_MODULE
;
dssdev
->
port_num
=
1
;
in
=
ddata
->
in
;
in
=
ddata
->
in
;
...
...
drivers/video/fbdev/omap2/dss/Kconfig
浏览文件 @
3315764e
...
@@ -74,9 +74,6 @@ config OMAP4_DSS_HDMI
...
@@ -74,9 +74,6 @@ config OMAP4_DSS_HDMI
help
help
HDMI support for OMAP4 based SoCs.
HDMI support for OMAP4 based SoCs.
config OMAP4_DSS_HDMI_AUDIO
bool
config OMAP5_DSS_HDMI
config OMAP5_DSS_HDMI
bool "HDMI support for OMAP5"
bool "HDMI support for OMAP5"
default n
default n
...
@@ -86,10 +83,6 @@ config OMAP5_DSS_HDMI
...
@@ -86,10 +83,6 @@ config OMAP5_DSS_HDMI
Definition Multimedia Interface. See http://www.hdmi.org/ for HDMI
Definition Multimedia Interface. See http://www.hdmi.org/ for HDMI
specification.
specification.
config OMAP5_DSS_HDMI_AUDIO
depends on OMAP5_DSS_HDMI
bool
config OMAP2_DSS_SDI
config OMAP2_DSS_SDI
bool "SDI support"
bool "SDI support"
default n
default n
...
...
drivers/video/fbdev/omap2/dss/Makefile
浏览文件 @
3315764e
...
@@ -2,7 +2,7 @@ obj-$(CONFIG_OMAP2_DSS_INIT) += omapdss-boot-init.o
...
@@ -2,7 +2,7 @@ obj-$(CONFIG_OMAP2_DSS_INIT) += omapdss-boot-init.o
obj-$(CONFIG_OMAP2_DSS)
+=
omapdss.o
obj-$(CONFIG_OMAP2_DSS)
+=
omapdss.o
# Core DSS files
# Core DSS files
omapdss-y
:=
core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o
\
omapdss-y
:=
core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o
\
output.o dss-of.o
output.o dss-of.o
pll.o
# DSS compat layer files
# DSS compat layer files
omapdss-y
+=
manager.o manager-sysfs.o overlay.o overlay-sysfs.o apply.o
\
omapdss-y
+=
manager.o manager-sysfs.o overlay.o overlay-sysfs.o apply.o
\
dispc-compat.o display-sysfs.o
dispc-compat.o display-sysfs.o
...
...
drivers/video/fbdev/omap2/dss/dispc.c
浏览文件 @
3315764e
...
@@ -3028,7 +3028,7 @@ static void dispc_mgr_get_lcd_divisor(enum omap_channel channel, int *lck_div,
...
@@ -3028,7 +3028,7 @@ static void dispc_mgr_get_lcd_divisor(enum omap_channel channel, int *lck_div,
unsigned
long
dispc_fclk_rate
(
void
)
unsigned
long
dispc_fclk_rate
(
void
)
{
{
struct
platform_device
*
dsidev
;
struct
dss_pll
*
pll
;
unsigned
long
r
=
0
;
unsigned
long
r
=
0
;
switch
(
dss_get_dispc_clk_source
())
{
switch
(
dss_get_dispc_clk_source
())
{
...
@@ -3036,12 +3036,12 @@ unsigned long dispc_fclk_rate(void)
...
@@ -3036,12 +3036,12 @@ unsigned long dispc_fclk_rate(void)
r
=
dss_get_dispc_clk_rate
();
r
=
dss_get_dispc_clk_rate
();
break
;
break
;
case
OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC
:
case
OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC
:
dsidev
=
dsi_get_dsidev_from_id
(
0
);
pll
=
dss_pll_find
(
"dsi0"
);
r
=
dsi_get_pll_hsdiv_dispc_rate
(
dsidev
)
;
r
=
pll
->
cinfo
.
clkout
[
0
]
;
break
;
break
;
case
OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC
:
case
OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC
:
dsidev
=
dsi_get_dsidev_from_id
(
1
);
pll
=
dss_pll_find
(
"dsi1"
);
r
=
dsi_get_pll_hsdiv_dispc_rate
(
dsidev
)
;
r
=
pll
->
cinfo
.
clkout
[
0
]
;
break
;
break
;
default:
default:
BUG
();
BUG
();
...
@@ -3053,7 +3053,7 @@ unsigned long dispc_fclk_rate(void)
...
@@ -3053,7 +3053,7 @@ unsigned long dispc_fclk_rate(void)
unsigned
long
dispc_mgr_lclk_rate
(
enum
omap_channel
channel
)
unsigned
long
dispc_mgr_lclk_rate
(
enum
omap_channel
channel
)
{
{
struct
platform_device
*
dsidev
;
struct
dss_pll
*
pll
;
int
lcd
;
int
lcd
;
unsigned
long
r
;
unsigned
long
r
;
u32
l
;
u32
l
;
...
@@ -3068,12 +3068,12 @@ unsigned long dispc_mgr_lclk_rate(enum omap_channel channel)
...
@@ -3068,12 +3068,12 @@ unsigned long dispc_mgr_lclk_rate(enum omap_channel channel)
r
=
dss_get_dispc_clk_rate
();
r
=
dss_get_dispc_clk_rate
();
break
;
break
;
case
OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC
:
case
OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC
:
dsidev
=
dsi_get_dsidev_from_id
(
0
);
pll
=
dss_pll_find
(
"dsi0"
);
r
=
dsi_get_pll_hsdiv_dispc_rate
(
dsidev
)
;
r
=
pll
->
cinfo
.
clkout
[
0
]
;
break
;
break
;
case
OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC
:
case
OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC
:
dsidev
=
dsi_get_dsidev_from_id
(
1
);
pll
=
dss_pll_find
(
"dsi1"
);
r
=
dsi_get_pll_hsdiv_dispc_rate
(
dsidev
)
;
r
=
pll
->
cinfo
.
clkout
[
0
]
;
break
;
break
;
default:
default:
BUG
();
BUG
();
...
...
drivers/video/fbdev/omap2/dss/dpi.c
浏览文件 @
3315764e
...
@@ -31,17 +31,20 @@
...
@@ -31,17 +31,20 @@
#include <linux/regulator/consumer.h>
#include <linux/regulator/consumer.h>
#include <linux/string.h>
#include <linux/string.h>
#include <linux/of.h>
#include <linux/of.h>
#include <linux/clk.h>
#include <video/omapdss.h>
#include <video/omapdss.h>
#include "dss.h"
#include "dss.h"
#include "dss_features.h"
#include "dss_features.h"
static
struct
{
#define HSDIV_DISPC 0
struct
dpi_data
{
struct
platform_device
*
pdev
;
struct
platform_device
*
pdev
;
struct
regulator
*
vdds_dsi_reg
;
struct
regulator
*
vdds_dsi_reg
;
struct
platform_device
*
dsidev
;
struct
dss_pll
*
pll
;
struct
mutex
lock
;
struct
mutex
lock
;
...
@@ -52,9 +55,20 @@ static struct {
...
@@ -52,9 +55,20 @@ static struct {
struct
omap_dss_device
output
;
struct
omap_dss_device
output
;
bool
port_initialized
;
bool
port_initialized
;
}
dpi
;
};
static
struct
dpi_data
*
dpi_get_data_from_dssdev
(
struct
omap_dss_device
*
dssdev
)
{
return
container_of
(
dssdev
,
struct
dpi_data
,
output
);
}
/* only used in non-DT mode */
static
struct
dpi_data
*
dpi_get_data_from_pdev
(
struct
platform_device
*
pdev
)
{
return
dev_get_drvdata
(
&
pdev
->
dev
);
}
static
struct
platform_device
*
dpi_get_dsidev
(
enum
omap_channel
channel
)
static
struct
dss_pll
*
dpi_get_pll
(
enum
omap_channel
channel
)
{
{
/*
/*
* XXX we can't currently use DSI PLL for DPI with OMAP3, as the DSI PLL
* XXX we can't currently use DSI PLL for DPI with OMAP3, as the DSI PLL
...
@@ -75,9 +89,9 @@ static struct platform_device *dpi_get_dsidev(enum omap_channel channel)
...
@@ -75,9 +89,9 @@ static struct platform_device *dpi_get_dsidev(enum omap_channel channel)
case
OMAPDSS_VER_OMAP4
:
case
OMAPDSS_VER_OMAP4
:
switch
(
channel
)
{
switch
(
channel
)
{
case
OMAP_DSS_CHANNEL_LCD
:
case
OMAP_DSS_CHANNEL_LCD
:
return
ds
i_get_dsidev_from_id
(
0
);
return
ds
s_pll_find
(
"dsi0"
);
case
OMAP_DSS_CHANNEL_LCD2
:
case
OMAP_DSS_CHANNEL_LCD2
:
return
ds
i_get_dsidev_from_id
(
1
);
return
ds
s_pll_find
(
"dsi1"
);
default:
default:
return
NULL
;
return
NULL
;
}
}
...
@@ -85,9 +99,9 @@ static struct platform_device *dpi_get_dsidev(enum omap_channel channel)
...
@@ -85,9 +99,9 @@ static struct platform_device *dpi_get_dsidev(enum omap_channel channel)
case
OMAPDSS_VER_OMAP5
:
case
OMAPDSS_VER_OMAP5
:
switch
(
channel
)
{
switch
(
channel
)
{
case
OMAP_DSS_CHANNEL_LCD
:
case
OMAP_DSS_CHANNEL_LCD
:
return
ds
i_get_dsidev_from_id
(
0
);
return
ds
s_pll_find
(
"dsi0"
);
case
OMAP_DSS_CHANNEL_LCD3
:
case
OMAP_DSS_CHANNEL_LCD3
:
return
ds
i_get_dsidev_from_id
(
1
);
return
ds
s_pll_find
(
"dsi1"
);
default:
default:
return
NULL
;
return
NULL
;
}
}
...
@@ -114,7 +128,7 @@ static enum omap_dss_clk_source dpi_get_alt_clk_src(enum omap_channel channel)
...
@@ -114,7 +128,7 @@ static enum omap_dss_clk_source dpi_get_alt_clk_src(enum omap_channel channel)
}
}
struct
dpi_clk_calc_ctx
{
struct
dpi_clk_calc_ctx
{
struct
platform_device
*
dsidev
;
struct
dss_pll
*
pll
;
/* inputs */
/* inputs */
...
@@ -122,7 +136,7 @@ struct dpi_clk_calc_ctx {
...
@@ -122,7 +136,7 @@ struct dpi_clk_calc_ctx {
/* outputs */
/* outputs */
struct
ds
i
_clock_info
dsi_cinfo
;
struct
ds
s_pll
_clock_info
dsi_cinfo
;
unsigned
long
fck
;
unsigned
long
fck
;
struct
dispc_clock_info
dispc_cinfo
;
struct
dispc_clock_info
dispc_cinfo
;
};
};
...
@@ -154,7 +168,7 @@ static bool dpi_calc_dispc_cb(int lckd, int pckd, unsigned long lck,
...
@@ -154,7 +168,7 @@ static bool dpi_calc_dispc_cb(int lckd, int pckd, unsigned long lck,
}
}
static
bool
dpi_calc_hsdiv_cb
(
int
reg
m_dispc
,
unsigned
long
dispc
,
static
bool
dpi_calc_hsdiv_cb
(
int
m_dispc
,
unsigned
long
dispc
,
void
*
data
)
void
*
data
)
{
{
struct
dpi_clk_calc_ctx
*
ctx
=
data
;
struct
dpi_clk_calc_ctx
*
ctx
=
data
;
...
@@ -164,30 +178,31 @@ static bool dpi_calc_hsdiv_cb(int regm_dispc, unsigned long dispc,
...
@@ -164,30 +178,31 @@ static bool dpi_calc_hsdiv_cb(int regm_dispc, unsigned long dispc,
* shifted. So skip all odd dividers when the pixel clock is on the
* shifted. So skip all odd dividers when the pixel clock is on the
* higher side.
* higher side.
*/
*/
if
(
regm_dispc
>
1
&&
reg
m_dispc
%
2
!=
0
&&
ctx
->
pck_min
>=
100000000
)
if
(
m_dispc
>
1
&&
m_dispc
%
2
!=
0
&&
ctx
->
pck_min
>=
100000000
)
return
false
;
return
false
;
ctx
->
dsi_cinfo
.
regm_dispc
=
reg
m_dispc
;
ctx
->
dsi_cinfo
.
mX
[
HSDIV_DISPC
]
=
m_dispc
;
ctx
->
dsi_cinfo
.
dsi_pll_hsdiv_dispc_clk
=
dispc
;
ctx
->
dsi_cinfo
.
clkout
[
HSDIV_DISPC
]
=
dispc
;
return
dispc_div_calc
(
dispc
,
ctx
->
pck_min
,
ctx
->
pck_max
,
return
dispc_div_calc
(
dispc
,
ctx
->
pck_min
,
ctx
->
pck_max
,
dpi_calc_dispc_cb
,
ctx
);
dpi_calc_dispc_cb
,
ctx
);
}
}
static
bool
dpi_calc_pll_cb
(
int
regn
,
int
reg
m
,
unsigned
long
fint
,
static
bool
dpi_calc_pll_cb
(
int
n
,
int
m
,
unsigned
long
fint
,
unsigned
long
pll
,
unsigned
long
clkdco
,
void
*
data
)
void
*
data
)
{
{
struct
dpi_clk_calc_ctx
*
ctx
=
data
;
struct
dpi_clk_calc_ctx
*
ctx
=
data
;
ctx
->
dsi_cinfo
.
regn
=
reg
n
;
ctx
->
dsi_cinfo
.
n
=
n
;
ctx
->
dsi_cinfo
.
regm
=
reg
m
;
ctx
->
dsi_cinfo
.
m
=
m
;
ctx
->
dsi_cinfo
.
fint
=
fint
;
ctx
->
dsi_cinfo
.
fint
=
fint
;
ctx
->
dsi_cinfo
.
clk
in4ddr
=
pll
;
ctx
->
dsi_cinfo
.
clk
dco
=
clkdco
;
return
dsi_hsdiv_calc
(
ctx
->
dsidev
,
pll
,
ctx
->
pck_min
,
return
dss_pll_hsdiv_calc
(
ctx
->
pll
,
clkdco
,
dpi_calc_hsdiv_cb
,
ctx
);
ctx
->
pck_min
,
dss_feat_get_param_max
(
FEAT_PARAM_DSS_FCK
),
dpi_calc_hsdiv_cb
,
ctx
);
}
}
static
bool
dpi_calc_dss_cb
(
unsigned
long
fck
,
void
*
data
)
static
bool
dpi_calc_dss_cb
(
unsigned
long
fck
,
void
*
data
)
...
@@ -200,23 +215,23 @@ static bool dpi_calc_dss_cb(unsigned long fck, void *data)
...
@@ -200,23 +215,23 @@ static bool dpi_calc_dss_cb(unsigned long fck, void *data)
dpi_calc_dispc_cb
,
ctx
);
dpi_calc_dispc_cb
,
ctx
);
}
}
static
bool
dpi_dsi_clk_calc
(
unsigned
long
pck
,
struct
dpi_clk_calc_ctx
*
ctx
)
static
bool
dpi_dsi_clk_calc
(
struct
dpi_data
*
dpi
,
unsigned
long
pck
,
struct
dpi_clk_calc_ctx
*
ctx
)
{
{
unsigned
long
clkin
;
unsigned
long
clkin
;
unsigned
long
pll_min
,
pll_max
;
unsigned
long
pll_min
,
pll_max
;
clkin
=
dsi_get_pll_clkin
(
dpi
.
dsidev
);
memset
(
ctx
,
0
,
sizeof
(
*
ctx
));
memset
(
ctx
,
0
,
sizeof
(
*
ctx
));
ctx
->
dsidev
=
dpi
.
dsidev
;
ctx
->
pll
=
dpi
->
pll
;
ctx
->
pck_min
=
pck
-
1000
;
ctx
->
pck_min
=
pck
-
1000
;
ctx
->
pck_max
=
pck
+
1000
;
ctx
->
pck_max
=
pck
+
1000
;
ctx
->
dsi_cinfo
.
clkin
=
clkin
;
pll_min
=
0
;
pll_min
=
0
;
pll_max
=
0
;
pll_max
=
0
;
return
dsi_pll_calc
(
dpi
.
dsidev
,
clkin
,
clkin
=
clk_get_rate
(
ctx
->
pll
->
clkin
);
return
dss_pll_calc
(
ctx
->
pll
,
clkin
,
pll_min
,
pll_max
,
pll_min
,
pll_max
,
dpi_calc_pll_cb
,
ctx
);
dpi_calc_pll_cb
,
ctx
);
}
}
...
@@ -252,7 +267,7 @@ static bool dpi_dss_clk_calc(unsigned long pck, struct dpi_clk_calc_ctx *ctx)
...
@@ -252,7 +267,7 @@ static bool dpi_dss_clk_calc(unsigned long pck, struct dpi_clk_calc_ctx *ctx)
static
int
dpi_set_dsi_clk
(
enum
omap_channel
channel
,
static
int
dpi_set_dsi_clk
(
struct
dpi_data
*
dpi
,
enum
omap_channel
channel
,
unsigned
long
pck_req
,
unsigned
long
*
fck
,
int
*
lck_div
,
unsigned
long
pck_req
,
unsigned
long
*
fck
,
int
*
lck_div
,
int
*
pck_div
)
int
*
pck_div
)
{
{
...
@@ -260,28 +275,28 @@ static int dpi_set_dsi_clk(enum omap_channel channel,
...
@@ -260,28 +275,28 @@ static int dpi_set_dsi_clk(enum omap_channel channel,
int
r
;
int
r
;
bool
ok
;
bool
ok
;
ok
=
dpi_dsi_clk_calc
(
pck_req
,
&
ctx
);
ok
=
dpi_dsi_clk_calc
(
dpi
,
pck_req
,
&
ctx
);
if
(
!
ok
)
if
(
!
ok
)
return
-
EINVAL
;
return
-
EINVAL
;
r
=
ds
i_pll_set_clock_div
(
dpi
.
dsidev
,
&
ctx
.
dsi_cinfo
);
r
=
ds
s_pll_set_config
(
dpi
->
pll
,
&
ctx
.
dsi_cinfo
);
if
(
r
)
if
(
r
)
return
r
;
return
r
;
dss_select_lcd_clk_source
(
channel
,
dss_select_lcd_clk_source
(
channel
,
dpi_get_alt_clk_src
(
channel
));
dpi_get_alt_clk_src
(
channel
));
dpi
.
mgr_config
.
clock_info
=
ctx
.
dispc_cinfo
;
dpi
->
mgr_config
.
clock_info
=
ctx
.
dispc_cinfo
;
*
fck
=
ctx
.
dsi_cinfo
.
dsi_pll_hsdiv_dispc_clk
;
*
fck
=
ctx
.
dsi_cinfo
.
clkout
[
HSDIV_DISPC
]
;
*
lck_div
=
ctx
.
dispc_cinfo
.
lck_div
;
*
lck_div
=
ctx
.
dispc_cinfo
.
lck_div
;
*
pck_div
=
ctx
.
dispc_cinfo
.
pck_div
;
*
pck_div
=
ctx
.
dispc_cinfo
.
pck_div
;
return
0
;
return
0
;
}
}
static
int
dpi_set_dispc_clk
(
unsigned
long
pck_req
,
unsigned
long
*
fck
,
static
int
dpi_set_dispc_clk
(
struct
dpi_data
*
dpi
,
unsigned
long
pck_req
,
int
*
lck_div
,
int
*
pck_div
)
unsigned
long
*
fck
,
int
*
lck_div
,
int
*
pck_div
)
{
{
struct
dpi_clk_calc_ctx
ctx
;
struct
dpi_clk_calc_ctx
ctx
;
int
r
;
int
r
;
...
@@ -295,7 +310,7 @@ static int dpi_set_dispc_clk(unsigned long pck_req, unsigned long *fck,
...
@@ -295,7 +310,7 @@ static int dpi_set_dispc_clk(unsigned long pck_req, unsigned long *fck,
if
(
r
)
if
(
r
)
return
r
;
return
r
;
dpi
.
mgr_config
.
clock_info
=
ctx
.
dispc_cinfo
;
dpi
->
mgr_config
.
clock_info
=
ctx
.
dispc_cinfo
;
*
fck
=
ctx
.
fck
;
*
fck
=
ctx
.
fck
;
*
lck_div
=
ctx
.
dispc_cinfo
.
lck_div
;
*
lck_div
=
ctx
.
dispc_cinfo
.
lck_div
;
...
@@ -304,19 +319,21 @@ static int dpi_set_dispc_clk(unsigned long pck_req, unsigned long *fck,
...
@@ -304,19 +319,21 @@ static int dpi_set_dispc_clk(unsigned long pck_req, unsigned long *fck,
return
0
;
return
0
;
}
}
static
int
dpi_set_mode
(
struct
omap_overlay_manager
*
mgr
)
static
int
dpi_set_mode
(
struct
dpi_data
*
dpi
)
{
{
struct
omap_video_timings
*
t
=
&
dpi
.
timings
;
struct
omap_dss_device
*
out
=
&
dpi
->
output
;
struct
omap_overlay_manager
*
mgr
=
out
->
manager
;
struct
omap_video_timings
*
t
=
&
dpi
->
timings
;
int
lck_div
=
0
,
pck_div
=
0
;
int
lck_div
=
0
,
pck_div
=
0
;
unsigned
long
fck
=
0
;
unsigned
long
fck
=
0
;
unsigned
long
pck
;
unsigned
long
pck
;
int
r
=
0
;
int
r
=
0
;
if
(
dpi
.
dsidev
)
if
(
dpi
->
pll
)
r
=
dpi_set_dsi_clk
(
mgr
->
id
,
t
->
pixelclock
,
&
fck
,
r
=
dpi_set_dsi_clk
(
dpi
,
mgr
->
id
,
t
->
pixelclock
,
&
fck
,
&
lck_div
,
&
pck_div
);
&
lck_div
,
&
pck_div
);
else
else
r
=
dpi_set_dispc_clk
(
t
->
pixelclock
,
&
fck
,
r
=
dpi_set_dispc_clk
(
dpi
,
t
->
pixelclock
,
&
fck
,
&
lck_div
,
&
pck_div
);
&
lck_div
,
&
pck_div
);
if
(
r
)
if
(
r
)
return
r
;
return
r
;
...
@@ -335,28 +352,32 @@ static int dpi_set_mode(struct omap_overlay_manager *mgr)
...
@@ -335,28 +352,32 @@ static int dpi_set_mode(struct omap_overlay_manager *mgr)
return
0
;
return
0
;
}
}
static
void
dpi_config_lcd_manager
(
struct
omap_overlay_manager
*
mgr
)
static
void
dpi_config_lcd_manager
(
struct
dpi_data
*
dpi
)
{
{
dpi
.
mgr_config
.
io_pad_mode
=
DSS_IO_PAD_MODE_BYPASS
;
struct
omap_dss_device
*
out
=
&
dpi
->
output
;
struct
omap_overlay_manager
*
mgr
=
out
->
manager
;
dpi
->
mgr_config
.
io_pad_mode
=
DSS_IO_PAD_MODE_BYPASS
;
dpi
.
mgr_config
.
stallmode
=
false
;
dpi
->
mgr_config
.
stallmode
=
false
;
dpi
.
mgr_config
.
fifohandcheck
=
false
;
dpi
->
mgr_config
.
fifohandcheck
=
false
;
dpi
.
mgr_config
.
video_port_width
=
dpi
.
data_lines
;
dpi
->
mgr_config
.
video_port_width
=
dpi
->
data_lines
;
dpi
.
mgr_config
.
lcden_sig_polarity
=
0
;
dpi
->
mgr_config
.
lcden_sig_polarity
=
0
;
dss_mgr_set_lcd_config
(
mgr
,
&
dpi
.
mgr_config
);
dss_mgr_set_lcd_config
(
mgr
,
&
dpi
->
mgr_config
);
}
}
static
int
dpi_display_enable
(
struct
omap_dss_device
*
dssdev
)
static
int
dpi_display_enable
(
struct
omap_dss_device
*
dssdev
)
{
{
struct
omap_dss_device
*
out
=
&
dpi
.
output
;
struct
dpi_data
*
dpi
=
dpi_get_data_from_dssdev
(
dssdev
);
struct
omap_dss_device
*
out
=
&
dpi
->
output
;
int
r
;
int
r
;
mutex_lock
(
&
dpi
.
lock
);
mutex_lock
(
&
dpi
->
lock
);
if
(
dss_has_feature
(
FEAT_DPI_USES_VDDS_DSI
)
&&
!
dpi
.
vdds_dsi_reg
)
{
if
(
dss_has_feature
(
FEAT_DPI_USES_VDDS_DSI
)
&&
!
dpi
->
vdds_dsi_reg
)
{
DSSERR
(
"no VDSS_DSI regulator
\n
"
);
DSSERR
(
"no VDSS_DSI regulator
\n
"
);
r
=
-
ENODEV
;
r
=
-
ENODEV
;
goto
err_no_reg
;
goto
err_no_reg
;
...
@@ -369,7 +390,7 @@ static int dpi_display_enable(struct omap_dss_device *dssdev)
...
@@ -369,7 +390,7 @@ static int dpi_display_enable(struct omap_dss_device *dssdev)
}
}
if
(
dss_has_feature
(
FEAT_DPI_USES_VDDS_DSI
))
{
if
(
dss_has_feature
(
FEAT_DPI_USES_VDDS_DSI
))
{
r
=
regulator_enable
(
dpi
.
vdds_dsi_reg
);
r
=
regulator_enable
(
dpi
->
vdds_dsi_reg
);
if
(
r
)
if
(
r
)
goto
err_reg_enable
;
goto
err_reg_enable
;
}
}
...
@@ -378,25 +399,21 @@ static int dpi_display_enable(struct omap_dss_device *dssdev)
...
@@ -378,25 +399,21 @@ static int dpi_display_enable(struct omap_dss_device *dssdev)
if
(
r
)
if
(
r
)
goto
err_get_dispc
;
goto
err_get_dispc
;
r
=
dss_dpi_select_source
(
out
->
manager
->
id
);
r
=
dss_dpi_select_source
(
out
->
port_num
,
out
->
manager
->
id
);
if
(
r
)
if
(
r
)
goto
err_src_sel
;
goto
err_src_sel
;
if
(
dpi
.
dsidev
)
{
if
(
dpi
->
pll
)
{
r
=
dsi_runtime_get
(
dpi
.
dsidev
);
r
=
dss_pll_enable
(
dpi
->
pll
);
if
(
r
)
goto
err_get_dsi
;
r
=
dsi_pll_init
(
dpi
.
dsidev
,
0
,
1
);
if
(
r
)
if
(
r
)
goto
err_dsi_pll_init
;
goto
err_dsi_pll_init
;
}
}
r
=
dpi_set_mode
(
out
->
manager
);
r
=
dpi_set_mode
(
dpi
);
if
(
r
)
if
(
r
)
goto
err_set_mode
;
goto
err_set_mode
;
dpi_config_lcd_manager
(
out
->
manager
);
dpi_config_lcd_manager
(
dpi
);
mdelay
(
2
);
mdelay
(
2
);
...
@@ -404,78 +421,80 @@ static int dpi_display_enable(struct omap_dss_device *dssdev)
...
@@ -404,78 +421,80 @@ static int dpi_display_enable(struct omap_dss_device *dssdev)
if
(
r
)
if
(
r
)
goto
err_mgr_enable
;
goto
err_mgr_enable
;
mutex_unlock
(
&
dpi
.
lock
);
mutex_unlock
(
&
dpi
->
lock
);
return
0
;
return
0
;
err_mgr_enable:
err_mgr_enable:
err_set_mode:
err_set_mode:
if
(
dpi
.
dsidev
)
if
(
dpi
->
pll
)
ds
i_pll_uninit
(
dpi
.
dsidev
,
true
);
ds
s_pll_disable
(
dpi
->
pll
);
err_dsi_pll_init:
err_dsi_pll_init:
if
(
dpi
.
dsidev
)
dsi_runtime_put
(
dpi
.
dsidev
);
err_get_dsi:
err_src_sel:
err_src_sel:
dispc_runtime_put
();
dispc_runtime_put
();
err_get_dispc:
err_get_dispc:
if
(
dss_has_feature
(
FEAT_DPI_USES_VDDS_DSI
))
if
(
dss_has_feature
(
FEAT_DPI_USES_VDDS_DSI
))
regulator_disable
(
dpi
.
vdds_dsi_reg
);
regulator_disable
(
dpi
->
vdds_dsi_reg
);
err_reg_enable:
err_reg_enable:
err_no_out_mgr:
err_no_out_mgr:
err_no_reg:
err_no_reg:
mutex_unlock
(
&
dpi
.
lock
);
mutex_unlock
(
&
dpi
->
lock
);
return
r
;
return
r
;
}
}
static
void
dpi_display_disable
(
struct
omap_dss_device
*
dssdev
)
static
void
dpi_display_disable
(
struct
omap_dss_device
*
dssdev
)
{
{
struct
omap_overlay_manager
*
mgr
=
dpi
.
output
.
manager
;
struct
dpi_data
*
dpi
=
dpi_get_data_from_dssdev
(
dssdev
);
struct
omap_overlay_manager
*
mgr
=
dpi
->
output
.
manager
;
mutex_lock
(
&
dpi
.
lock
);
mutex_lock
(
&
dpi
->
lock
);
dss_mgr_disable
(
mgr
);
dss_mgr_disable
(
mgr
);
if
(
dpi
.
dsidev
)
{
if
(
dpi
->
pll
)
{
dss_select_lcd_clk_source
(
mgr
->
id
,
OMAP_DSS_CLK_SRC_FCK
);
dss_select_lcd_clk_source
(
mgr
->
id
,
OMAP_DSS_CLK_SRC_FCK
);
dsi_pll_uninit
(
dpi
.
dsidev
,
true
);
dss_pll_disable
(
dpi
->
pll
);
dsi_runtime_put
(
dpi
.
dsidev
);
}
}
dispc_runtime_put
();
dispc_runtime_put
();
if
(
dss_has_feature
(
FEAT_DPI_USES_VDDS_DSI
))
if
(
dss_has_feature
(
FEAT_DPI_USES_VDDS_DSI
))
regulator_disable
(
dpi
.
vdds_dsi_reg
);
regulator_disable
(
dpi
->
vdds_dsi_reg
);
mutex_unlock
(
&
dpi
.
lock
);
mutex_unlock
(
&
dpi
->
lock
);
}
}
static
void
dpi_set_timings
(
struct
omap_dss_device
*
dssdev
,
static
void
dpi_set_timings
(
struct
omap_dss_device
*
dssdev
,
struct
omap_video_timings
*
timings
)
struct
omap_video_timings
*
timings
)
{
{
struct
dpi_data
*
dpi
=
dpi_get_data_from_dssdev
(
dssdev
);
DSSDBG
(
"dpi_set_timings
\n
"
);
DSSDBG
(
"dpi_set_timings
\n
"
);
mutex_lock
(
&
dpi
.
lock
);
mutex_lock
(
&
dpi
->
lock
);
dpi
.
timings
=
*
timings
;
dpi
->
timings
=
*
timings
;
mutex_unlock
(
&
dpi
.
lock
);
mutex_unlock
(
&
dpi
->
lock
);
}
}
static
void
dpi_get_timings
(
struct
omap_dss_device
*
dssdev
,
static
void
dpi_get_timings
(
struct
omap_dss_device
*
dssdev
,
struct
omap_video_timings
*
timings
)
struct
omap_video_timings
*
timings
)
{
{
mutex_lock
(
&
dpi
.
lock
);
struct
dpi_data
*
dpi
=
dpi_get_data_from_dssdev
(
dssdev
);
mutex_lock
(
&
dpi
->
lock
);
*
timings
=
dpi
.
timings
;
*
timings
=
dpi
->
timings
;
mutex_unlock
(
&
dpi
.
lock
);
mutex_unlock
(
&
dpi
->
lock
);
}
}
static
int
dpi_check_timings
(
struct
omap_dss_device
*
dssdev
,
static
int
dpi_check_timings
(
struct
omap_dss_device
*
dssdev
,
struct
omap_video_timings
*
timings
)
struct
omap_video_timings
*
timings
)
{
{
struct
omap_overlay_manager
*
mgr
=
dpi
.
output
.
manager
;
struct
dpi_data
*
dpi
=
dpi_get_data_from_dssdev
(
dssdev
);
struct
omap_overlay_manager
*
mgr
=
dpi
->
output
.
manager
;
int
lck_div
,
pck_div
;
int
lck_div
,
pck_div
;
unsigned
long
fck
;
unsigned
long
fck
;
unsigned
long
pck
;
unsigned
long
pck
;
...
@@ -488,12 +507,12 @@ static int dpi_check_timings(struct omap_dss_device *dssdev,
...
@@ -488,12 +507,12 @@ static int dpi_check_timings(struct omap_dss_device *dssdev,
if
(
timings
->
pixelclock
==
0
)
if
(
timings
->
pixelclock
==
0
)
return
-
EINVAL
;
return
-
EINVAL
;
if
(
dpi
.
dsidev
)
{
if
(
dpi
->
pll
)
{
ok
=
dpi_dsi_clk_calc
(
timings
->
pixelclock
,
&
ctx
);
ok
=
dpi_dsi_clk_calc
(
dpi
,
timings
->
pixelclock
,
&
ctx
);
if
(
!
ok
)
if
(
!
ok
)
return
-
EINVAL
;
return
-
EINVAL
;
fck
=
ctx
.
dsi_cinfo
.
dsi_pll_hsdiv_dispc_clk
;
fck
=
ctx
.
dsi_cinfo
.
clkout
[
HSDIV_DISPC
]
;
}
else
{
}
else
{
ok
=
dpi_dss_clk_calc
(
timings
->
pixelclock
,
&
ctx
);
ok
=
dpi_dss_clk_calc
(
timings
->
pixelclock
,
&
ctx
);
if
(
!
ok
)
if
(
!
ok
)
...
@@ -514,74 +533,69 @@ static int dpi_check_timings(struct omap_dss_device *dssdev,
...
@@ -514,74 +533,69 @@ static int dpi_check_timings(struct omap_dss_device *dssdev,
static
void
dpi_set_data_lines
(
struct
omap_dss_device
*
dssdev
,
int
data_lines
)
static
void
dpi_set_data_lines
(
struct
omap_dss_device
*
dssdev
,
int
data_lines
)
{
{
mutex_lock
(
&
dpi
.
lock
);
struct
dpi_data
*
dpi
=
dpi_get_data_from_dssdev
(
dssdev
);
dpi
.
data_lines
=
data_lines
;
mutex_lock
(
&
dpi
->
lock
)
;
mutex_unlock
(
&
dpi
.
lock
);
dpi
->
data_lines
=
data_lines
;
mutex_unlock
(
&
dpi
->
lock
);
}
}
static
int
dpi_verify_dsi_pll
(
struct
platform_device
*
dsidev
)
static
int
dpi_verify_dsi_pll
(
struct
dss_pll
*
pll
)
{
{
int
r
;
int
r
;
/* do initial setup with the PLL to see if it is operational */
/* do initial setup with the PLL to see if it is operational */
r
=
ds
i_runtime_get
(
dsidev
);
r
=
ds
s_pll_enable
(
pll
);
if
(
r
)
if
(
r
)
return
r
;
return
r
;
r
=
dsi_pll_init
(
dsidev
,
0
,
1
);
dss_pll_disable
(
pll
);
if
(
r
)
{
dsi_runtime_put
(
dsidev
);
return
r
;
}
dsi_pll_uninit
(
dsidev
,
true
);
dsi_runtime_put
(
dsidev
);
return
0
;
return
0
;
}
}
static
int
dpi_init_regulator
(
void
)
static
int
dpi_init_regulator
(
struct
dpi_data
*
dpi
)
{
{
struct
regulator
*
vdds_dsi
;
struct
regulator
*
vdds_dsi
;
if
(
!
dss_has_feature
(
FEAT_DPI_USES_VDDS_DSI
))
if
(
!
dss_has_feature
(
FEAT_DPI_USES_VDDS_DSI
))
return
0
;
return
0
;
if
(
dpi
.
vdds_dsi_reg
)
if
(
dpi
->
vdds_dsi_reg
)
return
0
;
return
0
;
vdds_dsi
=
devm_regulator_get
(
&
dpi
.
pdev
->
dev
,
"vdds_dsi"
);
vdds_dsi
=
devm_regulator_get
(
&
dpi
->
pdev
->
dev
,
"vdds_dsi"
);
if
(
IS_ERR
(
vdds_dsi
))
{
if
(
IS_ERR
(
vdds_dsi
))
{
if
(
PTR_ERR
(
vdds_dsi
)
!=
-
EPROBE_DEFER
)
if
(
PTR_ERR
(
vdds_dsi
)
!=
-
EPROBE_DEFER
)
DSSERR
(
"can't get VDDS_DSI regulator
\n
"
);
DSSERR
(
"can't get VDDS_DSI regulator
\n
"
);
return
PTR_ERR
(
vdds_dsi
);
return
PTR_ERR
(
vdds_dsi
);
}
}
dpi
.
vdds_dsi_reg
=
vdds_dsi
;
dpi
->
vdds_dsi_reg
=
vdds_dsi
;
return
0
;
return
0
;
}
}
static
void
dpi_init_pll
(
void
)
static
void
dpi_init_pll
(
struct
dpi_data
*
dpi
)
{
{
struct
platform_device
*
dsidev
;
struct
dss_pll
*
pll
;
if
(
dpi
.
dsidev
)
if
(
dpi
->
pll
)
return
;
return
;
dsidev
=
dpi_get_dsidev
(
dpi
.
output
.
dispc_channel
);
pll
=
dpi_get_pll
(
dpi
->
output
.
dispc_channel
);
if
(
!
dsidev
)
if
(
!
pll
)
return
;
return
;
if
(
dpi_verify_dsi_pll
(
dsidev
))
{
if
(
dpi_verify_dsi_pll
(
pll
))
{
DSSWARN
(
"DSI PLL not operational
\n
"
);
DSSWARN
(
"DSI PLL not operational
\n
"
);
return
;
return
;
}
}
dpi
.
dsidev
=
dsidev
;
dpi
->
pll
=
pll
;
}
}
/*
/*
...
@@ -590,7 +604,7 @@ static void dpi_init_pll(void)
...
@@ -590,7 +604,7 @@ static void dpi_init_pll(void)
* the channel in some more dynamic manner, or get the channel as a user
* the channel in some more dynamic manner, or get the channel as a user
* parameter.
* parameter.
*/
*/
static
enum
omap_channel
dpi_get_channel
(
void
)
static
enum
omap_channel
dpi_get_channel
(
int
port_num
)
{
{
switch
(
omapdss_get_version
())
{
switch
(
omapdss_get_version
())
{
case
OMAPDSS_VER_OMAP24xx
:
case
OMAPDSS_VER_OMAP24xx
:
...
@@ -618,14 +632,15 @@ static enum omap_channel dpi_get_channel(void)
...
@@ -618,14 +632,15 @@ static enum omap_channel dpi_get_channel(void)
static
int
dpi_connect
(
struct
omap_dss_device
*
dssdev
,
static
int
dpi_connect
(
struct
omap_dss_device
*
dssdev
,
struct
omap_dss_device
*
dst
)
struct
omap_dss_device
*
dst
)
{
{
struct
dpi_data
*
dpi
=
dpi_get_data_from_dssdev
(
dssdev
);
struct
omap_overlay_manager
*
mgr
;
struct
omap_overlay_manager
*
mgr
;
int
r
;
int
r
;
r
=
dpi_init_regulator
();
r
=
dpi_init_regulator
(
dpi
);
if
(
r
)
if
(
r
)
return
r
;
return
r
;
dpi_init_pll
();
dpi_init_pll
(
dpi
);
mgr
=
omap_dss_get_overlay_manager
(
dssdev
->
dispc_channel
);
mgr
=
omap_dss_get_overlay_manager
(
dssdev
->
dispc_channel
);
if
(
!
mgr
)
if
(
!
mgr
)
...
@@ -676,13 +691,14 @@ static const struct omapdss_dpi_ops dpi_ops = {
...
@@ -676,13 +691,14 @@ static const struct omapdss_dpi_ops dpi_ops = {
static
void
dpi_init_output
(
struct
platform_device
*
pdev
)
static
void
dpi_init_output
(
struct
platform_device
*
pdev
)
{
{
struct
omap_dss_device
*
out
=
&
dpi
.
output
;
struct
dpi_data
*
dpi
=
dpi_get_data_from_pdev
(
pdev
);
struct
omap_dss_device
*
out
=
&
dpi
->
output
;
out
->
dev
=
&
pdev
->
dev
;
out
->
dev
=
&
pdev
->
dev
;
out
->
id
=
OMAP_DSS_OUTPUT_DPI
;
out
->
id
=
OMAP_DSS_OUTPUT_DPI
;
out
->
output_type
=
OMAP_DISPLAY_TYPE_DPI
;
out
->
output_type
=
OMAP_DISPLAY_TYPE_DPI
;
out
->
name
=
"dpi.0"
;
out
->
name
=
"dpi.0"
;
out
->
dispc_channel
=
dpi_get_channel
();
out
->
dispc_channel
=
dpi_get_channel
(
0
);
out
->
ops
.
dpi
=
&
dpi_ops
;
out
->
ops
.
dpi
=
&
dpi_ops
;
out
->
owner
=
THIS_MODULE
;
out
->
owner
=
THIS_MODULE
;
...
@@ -691,16 +707,69 @@ static void dpi_init_output(struct platform_device *pdev)
...
@@ -691,16 +707,69 @@ static void dpi_init_output(struct platform_device *pdev)
static
void
__exit
dpi_uninit_output
(
struct
platform_device
*
pdev
)
static
void
__exit
dpi_uninit_output
(
struct
platform_device
*
pdev
)
{
{
struct
omap_dss_device
*
out
=
&
dpi
.
output
;
struct
dpi_data
*
dpi
=
dpi_get_data_from_pdev
(
pdev
);
struct
omap_dss_device
*
out
=
&
dpi
->
output
;
omapdss_unregister_output
(
out
);
}
static
void
dpi_init_output_port
(
struct
platform_device
*
pdev
,
struct
device_node
*
port
)
{
struct
dpi_data
*
dpi
=
port
->
data
;
struct
omap_dss_device
*
out
=
&
dpi
->
output
;
int
r
;
u32
port_num
;
r
=
of_property_read_u32
(
port
,
"reg"
,
&
port_num
);
if
(
r
)
port_num
=
0
;
switch
(
port_num
)
{
case
2
:
out
->
name
=
"dpi.2"
;
break
;
case
1
:
out
->
name
=
"dpi.1"
;
break
;
case
0
:
default:
out
->
name
=
"dpi.0"
;
break
;
}
out
->
dev
=
&
pdev
->
dev
;
out
->
id
=
OMAP_DSS_OUTPUT_DPI
;
out
->
output_type
=
OMAP_DISPLAY_TYPE_DPI
;
out
->
dispc_channel
=
dpi_get_channel
(
port_num
);
out
->
port_num
=
port_num
;
out
->
ops
.
dpi
=
&
dpi_ops
;
out
->
owner
=
THIS_MODULE
;
omapdss_register_output
(
out
);
}
static
void
__exit
dpi_uninit_output_port
(
struct
device_node
*
port
)
{
struct
dpi_data
*
dpi
=
port
->
data
;
struct
omap_dss_device
*
out
=
&
dpi
->
output
;
omapdss_unregister_output
(
out
);
omapdss_unregister_output
(
out
);
}
}
static
int
omap_dpi_probe
(
struct
platform_device
*
pdev
)
static
int
omap_dpi_probe
(
struct
platform_device
*
pdev
)
{
{
dpi
.
pdev
=
pdev
;
struct
dpi_data
*
dpi
;
dpi
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
dpi
),
GFP_KERNEL
);
if
(
!
dpi
)
return
-
ENOMEM
;
mutex_init
(
&
dpi
.
lock
);
dpi
->
pdev
=
pdev
;
dev_set_drvdata
(
&
pdev
->
dev
,
dpi
);
mutex_init
(
&
dpi
->
lock
);
dpi_init_output
(
pdev
);
dpi_init_output
(
pdev
);
...
@@ -736,10 +805,15 @@ void __exit dpi_uninit_platform_driver(void)
...
@@ -736,10 +805,15 @@ void __exit dpi_uninit_platform_driver(void)
int
__init
dpi_init_port
(
struct
platform_device
*
pdev
,
struct
device_node
*
port
)
int
__init
dpi_init_port
(
struct
platform_device
*
pdev
,
struct
device_node
*
port
)
{
{
struct
dpi_data
*
dpi
;
struct
device_node
*
ep
;
struct
device_node
*
ep
;
u32
datalines
;
u32
datalines
;
int
r
;
int
r
;
dpi
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
dpi
),
GFP_KERNEL
);
if
(
!
dpi
)
return
-
ENOMEM
;
ep
=
omapdss_of_get_next_endpoint
(
port
,
NULL
);
ep
=
omapdss_of_get_next_endpoint
(
port
,
NULL
);
if
(
!
ep
)
if
(
!
ep
)
return
0
;
return
0
;
...
@@ -750,17 +824,18 @@ int __init dpi_init_port(struct platform_device *pdev, struct device_node *port)
...
@@ -750,17 +824,18 @@ int __init dpi_init_port(struct platform_device *pdev, struct device_node *port)
goto
err_datalines
;
goto
err_datalines
;
}
}
dpi
.
data_lines
=
datalines
;
dpi
->
data_lines
=
datalines
;
of_node_put
(
ep
);
of_node_put
(
ep
);
dpi
.
pdev
=
pdev
;
dpi
->
pdev
=
pdev
;
port
->
data
=
dpi
;
mutex_init
(
&
dpi
.
lock
);
mutex_init
(
&
dpi
->
lock
);
dpi_init_output
(
pdev
);
dpi_init_output
_port
(
pdev
,
port
);
dpi
.
port_initialized
=
true
;
dpi
->
port_initialized
=
true
;
return
0
;
return
0
;
...
@@ -770,10 +845,12 @@ int __init dpi_init_port(struct platform_device *pdev, struct device_node *port)
...
@@ -770,10 +845,12 @@ int __init dpi_init_port(struct platform_device *pdev, struct device_node *port)
return
r
;
return
r
;
}
}
void
__exit
dpi_uninit_port
(
void
)
void
__exit
dpi_uninit_port
(
struct
device_node
*
port
)
{
{
if
(
!
dpi
.
port_initialized
)
struct
dpi_data
*
dpi
=
port
->
data
;
if
(
!
dpi
->
port_initialized
)
return
;
return
;
dpi_uninit_output
(
dpi
.
pdev
);
dpi_uninit_output
_port
(
port
);
}
}
drivers/video/fbdev/omap2/dss/dsi.c
浏览文件 @
3315764e
此差异已折叠。
点击以展开。
drivers/video/fbdev/omap2/dss/dss-of.c
浏览文件 @
3315764e
...
@@ -20,6 +20,8 @@
...
@@ -20,6 +20,8 @@
#include <video/omapdss.h>
#include <video/omapdss.h>
#include "dss.h"
struct
device_node
*
struct
device_node
*
omapdss_of_get_next_port
(
const
struct
device_node
*
parent
,
omapdss_of_get_next_port
(
const
struct
device_node
*
parent
,
struct
device_node
*
prev
)
struct
device_node
*
prev
)
...
@@ -84,20 +86,17 @@ omapdss_of_get_next_endpoint(const struct device_node *parent,
...
@@ -84,20 +86,17 @@ omapdss_of_get_next_endpoint(const struct device_node *parent,
}
}
EXPORT_SYMBOL_GPL
(
omapdss_of_get_next_endpoint
);
EXPORT_SYMBOL_GPL
(
omapdss_of_get_next_endpoint
);
static
struct
device_node
*
struct
device_node
*
dss_of_port_get_parent_device
(
struct
device_node
*
port
)
omapdss_of_get_remote_device_node
(
const
struct
device_node
*
node
)
{
{
struct
device_node
*
np
;
struct
device_node
*
np
;
int
i
;
int
i
;
np
=
of_parse_phandle
(
node
,
"remote-endpoint"
,
0
);
if
(
!
port
)
if
(
!
np
)
return
NULL
;
return
NULL
;
np
=
of_get_next_parent
(
np
);
np
=
of_get_next_parent
(
port
);
for
(
i
=
0
;
i
<
3
&&
np
;
++
i
)
{
for
(
i
=
0
;
i
<
2
&&
np
;
++
i
)
{
struct
property
*
prop
;
struct
property
*
prop
;
prop
=
of_find_property
(
np
,
"compatible"
,
NULL
);
prop
=
of_find_property
(
np
,
"compatible"
,
NULL
);
...
@@ -111,6 +110,31 @@ omapdss_of_get_remote_device_node(const struct device_node *node)
...
@@ -111,6 +110,31 @@ omapdss_of_get_remote_device_node(const struct device_node *node)
return
NULL
;
return
NULL
;
}
}
u32
dss_of_port_get_port_number
(
struct
device_node
*
port
)
{
int
r
;
u32
reg
;
r
=
of_property_read_u32
(
port
,
"reg"
,
&
reg
);
if
(
r
)
reg
=
0
;
return
reg
;
}
static
struct
device_node
*
omapdss_of_get_remote_port
(
const
struct
device_node
*
node
)
{
struct
device_node
*
np
;
np
=
of_parse_phandle
(
node
,
"remote-endpoint"
,
0
);
if
(
!
np
)
return
NULL
;
np
=
of_get_next_parent
(
np
);
return
np
;
}
struct
device_node
*
struct
device_node
*
omapdss_of_get_first_endpoint
(
const
struct
device_node
*
parent
)
omapdss_of_get_first_endpoint
(
const
struct
device_node
*
parent
)
{
{
...
@@ -133,27 +157,25 @@ struct omap_dss_device *
...
@@ -133,27 +157,25 @@ struct omap_dss_device *
omapdss_of_find_source_for_first_ep
(
struct
device_node
*
node
)
omapdss_of_find_source_for_first_ep
(
struct
device_node
*
node
)
{
{
struct
device_node
*
ep
;
struct
device_node
*
ep
;
struct
device_node
*
src_
node
;
struct
device_node
*
src_
port
;
struct
omap_dss_device
*
src
;
struct
omap_dss_device
*
src
;
ep
=
omapdss_of_get_first_endpoint
(
node
);
ep
=
omapdss_of_get_first_endpoint
(
node
);
if
(
!
ep
)
if
(
!
ep
)
return
ERR_PTR
(
-
EINVAL
);
return
ERR_PTR
(
-
EINVAL
);
src_node
=
omapdss_of_get_remote_device_node
(
ep
);
src_port
=
omapdss_of_get_remote_port
(
ep
);
if
(
!
src_port
)
{
of_node_put
(
ep
);
of_node_put
(
ep
);
if
(
!
src_node
)
return
ERR_PTR
(
-
EINVAL
);
return
ERR_PTR
(
-
EINVAL
);
}
src
=
omap_dss_find_output_by_node
(
src_node
);
of_node_put
(
ep
);
of_node_put
(
src_node
);
src
=
omap_dss_find_output_by_port_node
(
src_port
);
if
(
!
src
)
of_node_put
(
src_port
);
return
ERR_PTR
(
-
EPROBE_DEFER
);
return
src
;
return
src
?
src
:
ERR_PTR
(
-
EPROBE_DEFER
)
;
}
}
EXPORT_SYMBOL_GPL
(
omapdss_of_find_source_for_first_ep
);
EXPORT_SYMBOL_GPL
(
omapdss_of_find_source_for_first_ep
);
drivers/video/fbdev/omap2/dss/dss.c
浏览文件 @
3315764e
...
@@ -70,7 +70,9 @@ struct dss_features {
...
@@ -70,7 +70,9 @@ struct dss_features {
u8
fck_div_max
;
u8
fck_div_max
;
u8
dss_fck_multiplier
;
u8
dss_fck_multiplier
;
const
char
*
parent_clk_name
;
const
char
*
parent_clk_name
;
int
(
*
dpi_select_source
)(
enum
omap_channel
channel
);
enum
omap_display_type
*
ports
;
int
num_ports
;
int
(
*
dpi_select_source
)(
int
port
,
enum
omap_channel
channel
);
};
};
static
struct
{
static
struct
{
...
@@ -294,7 +296,6 @@ static void dss_dump_regs(struct seq_file *s)
...
@@ -294,7 +296,6 @@ static void dss_dump_regs(struct seq_file *s)
static
void
dss_select_dispc_clk_source
(
enum
omap_dss_clk_source
clk_src
)
static
void
dss_select_dispc_clk_source
(
enum
omap_dss_clk_source
clk_src
)
{
{
struct
platform_device
*
dsidev
;
int
b
;
int
b
;
u8
start
,
end
;
u8
start
,
end
;
...
@@ -304,13 +305,9 @@ static void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src)
...
@@ -304,13 +305,9 @@ static void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src)
break
;
break
;
case
OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC
:
case
OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC
:
b
=
1
;
b
=
1
;
dsidev
=
dsi_get_dsidev_from_id
(
0
);
dsi_wait_pll_hsdiv_dispc_active
(
dsidev
);
break
;
break
;
case
OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC
:
case
OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC
:
b
=
2
;
b
=
2
;
dsidev
=
dsi_get_dsidev_from_id
(
1
);
dsi_wait_pll_hsdiv_dispc_active
(
dsidev
);
break
;
break
;
default:
default:
BUG
();
BUG
();
...
@@ -327,7 +324,6 @@ static void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src)
...
@@ -327,7 +324,6 @@ static void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src)
void
dss_select_dsi_clk_source
(
int
dsi_module
,
void
dss_select_dsi_clk_source
(
int
dsi_module
,
enum
omap_dss_clk_source
clk_src
)
enum
omap_dss_clk_source
clk_src
)
{
{
struct
platform_device
*
dsidev
;
int
b
,
pos
;
int
b
,
pos
;
switch
(
clk_src
)
{
switch
(
clk_src
)
{
...
@@ -337,14 +333,10 @@ void dss_select_dsi_clk_source(int dsi_module,
...
@@ -337,14 +333,10 @@ void dss_select_dsi_clk_source(int dsi_module,
case
OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI
:
case
OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI
:
BUG_ON
(
dsi_module
!=
0
);
BUG_ON
(
dsi_module
!=
0
);
b
=
1
;
b
=
1
;
dsidev
=
dsi_get_dsidev_from_id
(
0
);
dsi_wait_pll_hsdiv_dsi_active
(
dsidev
);
break
;
break
;
case
OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI
:
case
OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI
:
BUG_ON
(
dsi_module
!=
1
);
BUG_ON
(
dsi_module
!=
1
);
b
=
1
;
b
=
1
;
dsidev
=
dsi_get_dsidev_from_id
(
1
);
dsi_wait_pll_hsdiv_dsi_active
(
dsidev
);
break
;
break
;
default:
default:
BUG
();
BUG
();
...
@@ -360,7 +352,6 @@ void dss_select_dsi_clk_source(int dsi_module,
...
@@ -360,7 +352,6 @@ void dss_select_dsi_clk_source(int dsi_module,
void
dss_select_lcd_clk_source
(
enum
omap_channel
channel
,
void
dss_select_lcd_clk_source
(
enum
omap_channel
channel
,
enum
omap_dss_clk_source
clk_src
)
enum
omap_dss_clk_source
clk_src
)
{
{
struct
platform_device
*
dsidev
;
int
b
,
ix
,
pos
;
int
b
,
ix
,
pos
;
if
(
!
dss_has_feature
(
FEAT_LCD_CLK_SRC
))
{
if
(
!
dss_has_feature
(
FEAT_LCD_CLK_SRC
))
{
...
@@ -375,15 +366,11 @@ void dss_select_lcd_clk_source(enum omap_channel channel,
...
@@ -375,15 +366,11 @@ void dss_select_lcd_clk_source(enum omap_channel channel,
case
OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC
:
case
OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC
:
BUG_ON
(
channel
!=
OMAP_DSS_CHANNEL_LCD
);
BUG_ON
(
channel
!=
OMAP_DSS_CHANNEL_LCD
);
b
=
1
;
b
=
1
;
dsidev
=
dsi_get_dsidev_from_id
(
0
);
dsi_wait_pll_hsdiv_dispc_active
(
dsidev
);
break
;
break
;
case
OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC
:
case
OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC
:
BUG_ON
(
channel
!=
OMAP_DSS_CHANNEL_LCD2
&&
BUG_ON
(
channel
!=
OMAP_DSS_CHANNEL_LCD2
&&
channel
!=
OMAP_DSS_CHANNEL_LCD3
);
channel
!=
OMAP_DSS_CHANNEL_LCD3
);
b
=
1
;
b
=
1
;
dsidev
=
dsi_get_dsidev_from_id
(
1
);
dsi_wait_pll_hsdiv_dispc_active
(
dsidev
);
break
;
break
;
default:
default:
BUG
();
BUG
();
...
@@ -564,7 +551,7 @@ enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void)
...
@@ -564,7 +551,7 @@ enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void)
return
REG_GET
(
DSS_CONTROL
,
15
,
15
);
return
REG_GET
(
DSS_CONTROL
,
15
,
15
);
}
}
static
int
dss_dpi_select_source_omap2_omap3
(
enum
omap_channel
channel
)
static
int
dss_dpi_select_source_omap2_omap3
(
int
port
,
enum
omap_channel
channel
)
{
{
if
(
channel
!=
OMAP_DSS_CHANNEL_LCD
)
if
(
channel
!=
OMAP_DSS_CHANNEL_LCD
)
return
-
EINVAL
;
return
-
EINVAL
;
...
@@ -572,7 +559,7 @@ static int dss_dpi_select_source_omap2_omap3(enum omap_channel channel)
...
@@ -572,7 +559,7 @@ static int dss_dpi_select_source_omap2_omap3(enum omap_channel channel)
return
0
;
return
0
;
}
}
static
int
dss_dpi_select_source_omap4
(
enum
omap_channel
channel
)
static
int
dss_dpi_select_source_omap4
(
int
port
,
enum
omap_channel
channel
)
{
{
int
val
;
int
val
;
...
@@ -592,7 +579,7 @@ static int dss_dpi_select_source_omap4(enum omap_channel channel)
...
@@ -592,7 +579,7 @@ static int dss_dpi_select_source_omap4(enum omap_channel channel)
return
0
;
return
0
;
}
}
static
int
dss_dpi_select_source_omap5
(
enum
omap_channel
channel
)
static
int
dss_dpi_select_source_omap5
(
int
port
,
enum
omap_channel
channel
)
{
{
int
val
;
int
val
;
...
@@ -618,9 +605,9 @@ static int dss_dpi_select_source_omap5(enum omap_channel channel)
...
@@ -618,9 +605,9 @@ static int dss_dpi_select_source_omap5(enum omap_channel channel)
return
0
;
return
0
;
}
}
int
dss_dpi_select_source
(
enum
omap_channel
channel
)
int
dss_dpi_select_source
(
int
port
,
enum
omap_channel
channel
)
{
{
return
dss
.
feat
->
dpi_select_source
(
channel
);
return
dss
.
feat
->
dpi_select_source
(
port
,
channel
);
}
}
static
int
dss_get_clocks
(
void
)
static
int
dss_get_clocks
(
void
)
...
@@ -689,6 +676,16 @@ void dss_debug_dump_clocks(struct seq_file *s)
...
@@ -689,6 +676,16 @@ void dss_debug_dump_clocks(struct seq_file *s)
}
}
#endif
#endif
static
enum
omap_display_type
omap2plus_ports
[]
=
{
OMAP_DISPLAY_TYPE_DPI
,
};
static
enum
omap_display_type
omap34xx_ports
[]
=
{
OMAP_DISPLAY_TYPE_DPI
,
OMAP_DISPLAY_TYPE_SDI
,
};
static
const
struct
dss_features
omap24xx_dss_feats
__initconst
=
{
static
const
struct
dss_features
omap24xx_dss_feats
__initconst
=
{
/*
/*
* fck div max is really 16, but the divider range has gaps. The range
* fck div max is really 16, but the divider range has gaps. The range
...
@@ -698,6 +695,8 @@ static const struct dss_features omap24xx_dss_feats __initconst = {
...
@@ -698,6 +695,8 @@ static const struct dss_features omap24xx_dss_feats __initconst = {
.
dss_fck_multiplier
=
2
,
.
dss_fck_multiplier
=
2
,
.
parent_clk_name
=
"core_ck"
,
.
parent_clk_name
=
"core_ck"
,
.
dpi_select_source
=
&
dss_dpi_select_source_omap2_omap3
,
.
dpi_select_source
=
&
dss_dpi_select_source_omap2_omap3
,
.
ports
=
omap2plus_ports
,
.
num_ports
=
ARRAY_SIZE
(
omap2plus_ports
),
};
};
static
const
struct
dss_features
omap34xx_dss_feats
__initconst
=
{
static
const
struct
dss_features
omap34xx_dss_feats
__initconst
=
{
...
@@ -705,6 +704,8 @@ static const struct dss_features omap34xx_dss_feats __initconst = {
...
@@ -705,6 +704,8 @@ static const struct dss_features omap34xx_dss_feats __initconst = {
.
dss_fck_multiplier
=
2
,
.
dss_fck_multiplier
=
2
,
.
parent_clk_name
=
"dpll4_ck"
,
.
parent_clk_name
=
"dpll4_ck"
,
.
dpi_select_source
=
&
dss_dpi_select_source_omap2_omap3
,
.
dpi_select_source
=
&
dss_dpi_select_source_omap2_omap3
,
.
ports
=
omap34xx_ports
,
.
num_ports
=
ARRAY_SIZE
(
omap34xx_ports
),
};
};
static
const
struct
dss_features
omap3630_dss_feats
__initconst
=
{
static
const
struct
dss_features
omap3630_dss_feats
__initconst
=
{
...
@@ -712,6 +713,8 @@ static const struct dss_features omap3630_dss_feats __initconst = {
...
@@ -712,6 +713,8 @@ static const struct dss_features omap3630_dss_feats __initconst = {
.
dss_fck_multiplier
=
1
,
.
dss_fck_multiplier
=
1
,
.
parent_clk_name
=
"dpll4_ck"
,
.
parent_clk_name
=
"dpll4_ck"
,
.
dpi_select_source
=
&
dss_dpi_select_source_omap2_omap3
,
.
dpi_select_source
=
&
dss_dpi_select_source_omap2_omap3
,
.
ports
=
omap2plus_ports
,
.
num_ports
=
ARRAY_SIZE
(
omap2plus_ports
),
};
};
static
const
struct
dss_features
omap44xx_dss_feats
__initconst
=
{
static
const
struct
dss_features
omap44xx_dss_feats
__initconst
=
{
...
@@ -719,6 +722,8 @@ static const struct dss_features omap44xx_dss_feats __initconst = {
...
@@ -719,6 +722,8 @@ static const struct dss_features omap44xx_dss_feats __initconst = {
.
dss_fck_multiplier
=
1
,
.
dss_fck_multiplier
=
1
,
.
parent_clk_name
=
"dpll_per_x2_ck"
,
.
parent_clk_name
=
"dpll_per_x2_ck"
,
.
dpi_select_source
=
&
dss_dpi_select_source_omap4
,
.
dpi_select_source
=
&
dss_dpi_select_source_omap4
,
.
ports
=
omap2plus_ports
,
.
num_ports
=
ARRAY_SIZE
(
omap2plus_ports
),
};
};
static
const
struct
dss_features
omap54xx_dss_feats
__initconst
=
{
static
const
struct
dss_features
omap54xx_dss_feats
__initconst
=
{
...
@@ -726,6 +731,8 @@ static const struct dss_features omap54xx_dss_feats __initconst = {
...
@@ -726,6 +731,8 @@ static const struct dss_features omap54xx_dss_feats __initconst = {
.
dss_fck_multiplier
=
1
,
.
dss_fck_multiplier
=
1
,
.
parent_clk_name
=
"dpll_per_x2_ck"
,
.
parent_clk_name
=
"dpll_per_x2_ck"
,
.
dpi_select_source
=
&
dss_dpi_select_source_omap5
,
.
dpi_select_source
=
&
dss_dpi_select_source_omap5
,
.
ports
=
omap2plus_ports
,
.
num_ports
=
ARRAY_SIZE
(
omap2plus_ports
),
};
};
static
const
struct
dss_features
am43xx_dss_feats
__initconst
=
{
static
const
struct
dss_features
am43xx_dss_feats
__initconst
=
{
...
@@ -733,6 +740,8 @@ static const struct dss_features am43xx_dss_feats __initconst = {
...
@@ -733,6 +740,8 @@ static const struct dss_features am43xx_dss_feats __initconst = {
.
dss_fck_multiplier
=
0
,
.
dss_fck_multiplier
=
0
,
.
parent_clk_name
=
NULL
,
.
parent_clk_name
=
NULL
,
.
dpi_select_source
=
&
dss_dpi_select_source_omap2_omap3
,
.
dpi_select_source
=
&
dss_dpi_select_source_omap2_omap3
,
.
ports
=
omap2plus_ports
,
.
num_ports
=
ARRAY_SIZE
(
omap2plus_ports
),
};
};
static
int
__init
dss_init_features
(
struct
platform_device
*
pdev
)
static
int
__init
dss_init_features
(
struct
platform_device
*
pdev
)
...
@@ -798,37 +807,77 @@ static int __init dss_init_ports(struct platform_device *pdev)
...
@@ -798,37 +807,77 @@ static int __init dss_init_ports(struct platform_device *pdev)
if
(
!
port
)
if
(
!
port
)
return
0
;
return
0
;
if
(
dss
.
feat
->
num_ports
==
0
)
return
0
;
do
{
do
{
enum
omap_display_type
port_type
;
u32
reg
;
u32
reg
;
r
=
of_property_read_u32
(
port
,
"reg"
,
&
reg
);
r
=
of_property_read_u32
(
port
,
"reg"
,
&
reg
);
if
(
r
)
if
(
r
)
reg
=
0
;
reg
=
0
;
#ifdef CONFIG_OMAP2_DSS_DPI
if
(
reg
>=
dss
.
feat
->
num_ports
)
if
(
reg
==
0
)
continue
;
dpi_init_port
(
pdev
,
port
);
#endif
#ifdef CONFIG_OMAP2_DSS_SDI
port_type
=
dss
.
feat
->
ports
[
reg
];
if
(
reg
==
1
)
sdi_init_port
(
pdev
,
port
);
#endif
switch
(
port_type
)
{
case
OMAP_DISPLAY_TYPE_DPI
:
dpi_init_port
(
pdev
,
port
);
break
;
case
OMAP_DISPLAY_TYPE_SDI
:
sdi_init_port
(
pdev
,
port
);
break
;
default:
break
;
}
}
while
((
port
=
omapdss_of_get_next_port
(
parent
,
port
))
!=
NULL
);
}
while
((
port
=
omapdss_of_get_next_port
(
parent
,
port
))
!=
NULL
);
return
0
;
return
0
;
}
}
static
void
__exit
dss_uninit_ports
(
void
)
static
void
__exit
dss_uninit_ports
(
struct
platform_device
*
pdev
)
{
{
#ifdef CONFIG_OMAP2_DSS_DPI
struct
device_node
*
parent
=
pdev
->
dev
.
of_node
;
dpi_uninit_port
();
struct
device_node
*
port
;
#endif
#ifdef CONFIG_OMAP2_DSS_SDI
if
(
parent
==
NULL
)
sdi_uninit_port
();
return
;
#endif
port
=
omapdss_of_get_next_port
(
parent
,
NULL
);
if
(
!
port
)
return
;
if
(
dss
.
feat
->
num_ports
==
0
)
return
;
do
{
enum
omap_display_type
port_type
;
u32
reg
;
int
r
;
r
=
of_property_read_u32
(
port
,
"reg"
,
&
reg
);
if
(
r
)
reg
=
0
;
if
(
reg
>=
dss
.
feat
->
num_ports
)
continue
;
port_type
=
dss
.
feat
->
ports
[
reg
];
switch
(
port_type
)
{
case
OMAP_DISPLAY_TYPE_DPI
:
dpi_uninit_port
(
port
);
break
;
case
OMAP_DISPLAY_TYPE_SDI
:
sdi_uninit_port
(
port
);
break
;
default:
break
;
}
}
while
((
port
=
omapdss_of_get_next_port
(
parent
,
port
))
!=
NULL
);
}
}
/* DSS HW IP initialisation */
/* DSS HW IP initialisation */
...
@@ -910,7 +959,7 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
...
@@ -910,7 +959,7 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
static
int
__exit
omap_dsshw_remove
(
struct
platform_device
*
pdev
)
static
int
__exit
omap_dsshw_remove
(
struct
platform_device
*
pdev
)
{
{
dss_uninit_ports
();
dss_uninit_ports
(
pdev
);
pm_runtime_disable
(
&
pdev
->
dev
);
pm_runtime_disable
(
&
pdev
->
dev
);
...
...
drivers/video/fbdev/omap2/dss/dss.h
浏览文件 @
3315764e
...
@@ -100,35 +100,77 @@ enum dss_writeback_channel {
...
@@ -100,35 +100,77 @@ enum dss_writeback_channel {
DSS_WB_LCD3_MGR
=
7
,
DSS_WB_LCD3_MGR
=
7
,
};
};
struct
dispc_clock_info
{
struct
dss_pll
;
#define DSS_PLL_MAX_HSDIVS 4
/*
* Type-A PLLs: clkout[]/mX[] refer to hsdiv outputs m4, m5, m6, m7.
* Type-B PLLs: clkout[0] refers to m2.
*/
struct
dss_pll_clock_info
{
/* rates that we get with dividers below */
/* rates that we get with dividers below */
unsigned
long
lck
;
unsigned
long
fint
;
unsigned
long
pck
;
unsigned
long
clkdco
;
unsigned
long
clkout
[
DSS_PLL_MAX_HSDIVS
];
/* dividers */
/* dividers */
u16
lck_div
;
u16
n
;
u16
pck_div
;
u16
m
;
u32
mf
;
u16
mX
[
DSS_PLL_MAX_HSDIVS
];
u16
sd
;
};
struct
dss_pll_ops
{
int
(
*
enable
)(
struct
dss_pll
*
pll
);
void
(
*
disable
)(
struct
dss_pll
*
pll
);
int
(
*
set_config
)(
struct
dss_pll
*
pll
,
const
struct
dss_pll_clock_info
*
cinfo
);
};
struct
dss_pll_hw
{
unsigned
n_max
;
unsigned
m_min
;
unsigned
m_max
;
unsigned
mX_max
;
unsigned
long
fint_min
,
fint_max
;
unsigned
long
clkdco_min
,
clkdco_low
,
clkdco_max
;
u8
n_msb
,
n_lsb
;
u8
m_msb
,
m_lsb
;
u8
mX_msb
[
DSS_PLL_MAX_HSDIVS
],
mX_lsb
[
DSS_PLL_MAX_HSDIVS
];
bool
has_stopmode
;
bool
has_freqsel
;
bool
has_selfreqdco
;
bool
has_refsel
;
};
};
struct
dsi_clock_info
{
struct
dss_pll
{
const
char
*
name
;
struct
clk
*
clkin
;
struct
regulator
*
regulator
;
void
__iomem
*
base
;
const
struct
dss_pll_hw
*
hw
;
const
struct
dss_pll_ops
*
ops
;
struct
dss_pll_clock_info
cinfo
;
};
struct
dispc_clock_info
{
/* rates that we get with dividers below */
/* rates that we get with dividers below */
unsigned
long
fint
;
unsigned
long
lck
;
unsigned
long
clkin4ddr
;
unsigned
long
pck
;
unsigned
long
clkin
;
unsigned
long
dsi_pll_hsdiv_dispc_clk
;
/* OMAP3: DSI1_PLL_CLK
* OMAP4: PLLx_CLK1 */
unsigned
long
dsi_pll_hsdiv_dsi_clk
;
/* OMAP3: DSI2_PLL_CLK
* OMAP4: PLLx_CLK2 */
unsigned
long
lp_clk
;
/* dividers */
/* dividers */
u16
regn
;
u16
lck_div
;
u16
regm
;
u16
pck_div
;
u16
regm_dispc
;
/* OMAP3: REGM3
* OMAP4: REGM4 */
u16
regm_dsi
;
/* OMAP3: REGM4
* OMAP4: REGM5 */
u16
lp_clk_div
;
};
};
struct
dss_lcd_mgr_config
{
struct
dss_lcd_mgr_config
{
...
@@ -209,12 +251,16 @@ int dss_init_platform_driver(void) __init;
...
@@ -209,12 +251,16 @@ int dss_init_platform_driver(void) __init;
void
dss_uninit_platform_driver
(
void
);
void
dss_uninit_platform_driver
(
void
);
unsigned
long
dss_get_dispc_clk_rate
(
void
);
unsigned
long
dss_get_dispc_clk_rate
(
void
);
int
dss_dpi_select_source
(
enum
omap_channel
channel
);
int
dss_dpi_select_source
(
int
port
,
enum
omap_channel
channel
);
void
dss_select_hdmi_venc_clk_source
(
enum
dss_hdmi_venc_clk_source_select
);
void
dss_select_hdmi_venc_clk_source
(
enum
dss_hdmi_venc_clk_source_select
);
enum
dss_hdmi_venc_clk_source_select
dss_get_hdmi_venc_clk_source
(
void
);
enum
dss_hdmi_venc_clk_source_select
dss_get_hdmi_venc_clk_source
(
void
);
const
char
*
dss_get_generic_clk_source_name
(
enum
omap_dss_clk_source
clk_src
);
const
char
*
dss_get_generic_clk_source_name
(
enum
omap_dss_clk_source
clk_src
);
void
dss_dump_clocks
(
struct
seq_file
*
s
);
void
dss_dump_clocks
(
struct
seq_file
*
s
);
/* dss-of */
struct
device_node
*
dss_of_port_get_parent_device
(
struct
device_node
*
port
);
u32
dss_of_port_get_port_number
(
struct
device_node
*
port
);
#if defined(CONFIG_OMAP2_DSS_DEBUGFS)
#if defined(CONFIG_OMAP2_DSS_DEBUGFS)
void
dss_debug_dump_clocks
(
struct
seq_file
*
s
);
void
dss_debug_dump_clocks
(
struct
seq_file
*
s
);
#endif
#endif
...
@@ -244,16 +290,22 @@ bool dss_div_calc(unsigned long pck, unsigned long fck_min,
...
@@ -244,16 +290,22 @@ bool dss_div_calc(unsigned long pck, unsigned long fck_min,
int
sdi_init_platform_driver
(
void
)
__init
;
int
sdi_init_platform_driver
(
void
)
__init
;
void
sdi_uninit_platform_driver
(
void
)
__exit
;
void
sdi_uninit_platform_driver
(
void
)
__exit
;
#ifdef CONFIG_OMAP2_DSS_SDI
int
sdi_init_port
(
struct
platform_device
*
pdev
,
struct
device_node
*
port
)
__init
;
int
sdi_init_port
(
struct
platform_device
*
pdev
,
struct
device_node
*
port
)
__init
;
void
sdi_uninit_port
(
void
)
__exit
;
void
sdi_uninit_port
(
struct
device_node
*
port
)
__exit
;
#else
static
inline
int
__init
sdi_init_port
(
struct
platform_device
*
pdev
,
struct
device_node
*
port
)
{
return
0
;
}
static
inline
void
__exit
sdi_uninit_port
(
struct
device_node
*
port
)
{
}
#endif
/* DSI */
/* DSI */
typedef
bool
(
*
dsi_pll_calc_func
)(
int
regn
,
int
regm
,
unsigned
long
fint
,
unsigned
long
pll
,
void
*
data
);
typedef
bool
(
*
dsi_hsdiv_calc_func
)(
int
regm_dispc
,
unsigned
long
dispc
,
void
*
data
);
#ifdef CONFIG_OMAP2_DSS_DSI
#ifdef CONFIG_OMAP2_DSS_DSI
struct
dentry
;
struct
dentry
;
...
@@ -262,104 +314,36 @@ struct file_operations;
...
@@ -262,104 +314,36 @@ struct file_operations;
int
dsi_init_platform_driver
(
void
)
__init
;
int
dsi_init_platform_driver
(
void
)
__init
;
void
dsi_uninit_platform_driver
(
void
)
__exit
;
void
dsi_uninit_platform_driver
(
void
)
__exit
;
int
dsi_runtime_get
(
struct
platform_device
*
dsidev
);
void
dsi_runtime_put
(
struct
platform_device
*
dsidev
);
void
dsi_dump_clocks
(
struct
seq_file
*
s
);
void
dsi_dump_clocks
(
struct
seq_file
*
s
);
void
dsi_irq_handler
(
void
);
void
dsi_irq_handler
(
void
);
u8
dsi_get_pixel_size
(
enum
omap_dss_dsi_pixel_format
fmt
);
u8
dsi_get_pixel_size
(
enum
omap_dss_dsi_pixel_format
fmt
);
unsigned
long
dsi_get_pll_clkin
(
struct
platform_device
*
dsidev
);
bool
dsi_hsdiv_calc
(
struct
platform_device
*
dsidev
,
unsigned
long
pll
,
unsigned
long
out_min
,
dsi_hsdiv_calc_func
func
,
void
*
data
);
bool
dsi_pll_calc
(
struct
platform_device
*
dsidev
,
unsigned
long
clkin
,
unsigned
long
pll_min
,
unsigned
long
pll_max
,
dsi_pll_calc_func
func
,
void
*
data
);
unsigned
long
dsi_get_pll_hsdiv_dispc_rate
(
struct
platform_device
*
dsidev
);
int
dsi_pll_set_clock_div
(
struct
platform_device
*
dsidev
,
struct
dsi_clock_info
*
cinfo
);
int
dsi_pll_init
(
struct
platform_device
*
dsidev
,
bool
enable_hsclk
,
bool
enable_hsdiv
);
void
dsi_pll_uninit
(
struct
platform_device
*
dsidev
,
bool
disconnect_lanes
);
void
dsi_wait_pll_hsdiv_dispc_active
(
struct
platform_device
*
dsidev
);
void
dsi_wait_pll_hsdiv_dsi_active
(
struct
platform_device
*
dsidev
);
struct
platform_device
*
dsi_get_dsidev_from_id
(
int
module
);
#else
#else
static
inline
int
dsi_runtime_get
(
struct
platform_device
*
dsidev
)
{
return
0
;
}
static
inline
void
dsi_runtime_put
(
struct
platform_device
*
dsidev
)
{
}
static
inline
u8
dsi_get_pixel_size
(
enum
omap_dss_dsi_pixel_format
fmt
)
static
inline
u8
dsi_get_pixel_size
(
enum
omap_dss_dsi_pixel_format
fmt
)
{
{
WARN
(
"%s: DSI not compiled in, returning pixel_size as 0
\n
"
,
__func__
);
WARN
(
"%s: DSI not compiled in, returning pixel_size as 0
\n
"
,
__func__
);
return
0
;
return
0
;
}
}
static
inline
unsigned
long
dsi_get_pll_hsdiv_dispc_rate
(
struct
platform_device
*
dsidev
)
{
WARN
(
"%s: DSI not compiled in, returning rate as 0
\n
"
,
__func__
);
return
0
;
}
static
inline
int
dsi_pll_set_clock_div
(
struct
platform_device
*
dsidev
,
struct
dsi_clock_info
*
cinfo
)
{
WARN
(
"%s: DSI not compiled in
\n
"
,
__func__
);
return
-
ENODEV
;
}
static
inline
int
dsi_pll_init
(
struct
platform_device
*
dsidev
,
bool
enable_hsclk
,
bool
enable_hsdiv
)
{
WARN
(
"%s: DSI not compiled in
\n
"
,
__func__
);
return
-
ENODEV
;
}
static
inline
void
dsi_pll_uninit
(
struct
platform_device
*
dsidev
,
bool
disconnect_lanes
)
{
}
static
inline
void
dsi_wait_pll_hsdiv_dispc_active
(
struct
platform_device
*
dsidev
)
{
}
static
inline
void
dsi_wait_pll_hsdiv_dsi_active
(
struct
platform_device
*
dsidev
)
{
}
static
inline
struct
platform_device
*
dsi_get_dsidev_from_id
(
int
module
)
{
return
NULL
;
}
static
inline
unsigned
long
dsi_get_pll_clkin
(
struct
platform_device
*
dsidev
)
{
return
0
;
}
static
inline
bool
dsi_hsdiv_calc
(
struct
platform_device
*
dsidev
,
unsigned
long
pll
,
unsigned
long
out_min
,
dsi_hsdiv_calc_func
func
,
void
*
data
)
{
return
false
;
}
static
inline
bool
dsi_pll_calc
(
struct
platform_device
*
dsidev
,
unsigned
long
clkin
,
unsigned
long
pll_min
,
unsigned
long
pll_max
,
dsi_pll_calc_func
func
,
void
*
data
)
{
return
false
;
}
#endif
#endif
/* DPI */
/* DPI */
int
dpi_init_platform_driver
(
void
)
__init
;
int
dpi_init_platform_driver
(
void
)
__init
;
void
dpi_uninit_platform_driver
(
void
)
__exit
;
void
dpi_uninit_platform_driver
(
void
)
__exit
;
#ifdef CONFIG_OMAP2_DSS_DPI
int
dpi_init_port
(
struct
platform_device
*
pdev
,
struct
device_node
*
port
)
__init
;
int
dpi_init_port
(
struct
platform_device
*
pdev
,
struct
device_node
*
port
)
__init
;
void
dpi_uninit_port
(
void
)
__exit
;
void
dpi_uninit_port
(
struct
device_node
*
port
)
__exit
;
#else
static
inline
int
__init
dpi_init_port
(
struct
platform_device
*
pdev
,
struct
device_node
*
port
)
{
return
0
;
}
static
inline
void
__exit
dpi_uninit_port
(
struct
device_node
*
port
)
{
}
#endif
/* DISPC */
/* DISPC */
int
dispc_init_platform_driver
(
void
)
__init
;
int
dispc_init_platform_driver
(
void
)
__init
;
...
@@ -438,4 +422,29 @@ static inline void dss_collect_irq_stats(u32 irqstatus, unsigned *irq_arr)
...
@@ -438,4 +422,29 @@ static inline void dss_collect_irq_stats(u32 irqstatus, unsigned *irq_arr)
}
}
#endif
#endif
/* PLL */
typedef
bool
(
*
dss_pll_calc_func
)(
int
n
,
int
m
,
unsigned
long
fint
,
unsigned
long
clkdco
,
void
*
data
);
typedef
bool
(
*
dss_hsdiv_calc_func
)(
int
m_dispc
,
unsigned
long
dispc
,
void
*
data
);
int
dss_pll_register
(
struct
dss_pll
*
pll
);
void
dss_pll_unregister
(
struct
dss_pll
*
pll
);
struct
dss_pll
*
dss_pll_find
(
const
char
*
name
);
int
dss_pll_enable
(
struct
dss_pll
*
pll
);
void
dss_pll_disable
(
struct
dss_pll
*
pll
);
int
dss_pll_set_config
(
struct
dss_pll
*
pll
,
const
struct
dss_pll_clock_info
*
cinfo
);
bool
dss_pll_hsdiv_calc
(
const
struct
dss_pll
*
pll
,
unsigned
long
clkdco
,
unsigned
long
out_min
,
unsigned
long
out_max
,
dss_hsdiv_calc_func
func
,
void
*
data
);
bool
dss_pll_calc
(
const
struct
dss_pll
*
pll
,
unsigned
long
clkin
,
unsigned
long
pll_min
,
unsigned
long
pll_max
,
dss_pll_calc_func
func
,
void
*
data
);
int
dss_pll_write_config_type_a
(
struct
dss_pll
*
pll
,
const
struct
dss_pll_clock_info
*
cinfo
);
int
dss_pll_write_config_type_b
(
struct
dss_pll
*
pll
,
const
struct
dss_pll_clock_info
*
cinfo
);
#endif
#endif
drivers/video/fbdev/omap2/dss/dss_features.c
浏览文件 @
3315764e
...
@@ -72,10 +72,6 @@ static const struct dss_reg_field omap2_dss_reg_fields[] = {
...
@@ -72,10 +72,6 @@ static const struct dss_reg_field omap2_dss_reg_fields[] = {
[
FEAT_REG_HORIZONTALACCU
]
=
{
9
,
0
},
[
FEAT_REG_HORIZONTALACCU
]
=
{
9
,
0
},
[
FEAT_REG_VERTICALACCU
]
=
{
25
,
16
},
[
FEAT_REG_VERTICALACCU
]
=
{
25
,
16
},
[
FEAT_REG_DISPC_CLK_SWITCH
]
=
{
0
,
0
},
[
FEAT_REG_DISPC_CLK_SWITCH
]
=
{
0
,
0
},
[
FEAT_REG_DSIPLL_REGN
]
=
{
0
,
0
},
[
FEAT_REG_DSIPLL_REGM
]
=
{
0
,
0
},
[
FEAT_REG_DSIPLL_REGM_DISPC
]
=
{
0
,
0
},
[
FEAT_REG_DSIPLL_REGM_DSI
]
=
{
0
,
0
},
};
};
static
const
struct
dss_reg_field
omap3_dss_reg_fields
[]
=
{
static
const
struct
dss_reg_field
omap3_dss_reg_fields
[]
=
{
...
@@ -87,10 +83,6 @@ static const struct dss_reg_field omap3_dss_reg_fields[] = {
...
@@ -87,10 +83,6 @@ static const struct dss_reg_field omap3_dss_reg_fields[] = {
[
FEAT_REG_HORIZONTALACCU
]
=
{
9
,
0
},
[
FEAT_REG_HORIZONTALACCU
]
=
{
9
,
0
},
[
FEAT_REG_VERTICALACCU
]
=
{
25
,
16
},
[
FEAT_REG_VERTICALACCU
]
=
{
25
,
16
},
[
FEAT_REG_DISPC_CLK_SWITCH
]
=
{
0
,
0
},
[
FEAT_REG_DISPC_CLK_SWITCH
]
=
{
0
,
0
},
[
FEAT_REG_DSIPLL_REGN
]
=
{
7
,
1
},
[
FEAT_REG_DSIPLL_REGM
]
=
{
18
,
8
},
[
FEAT_REG_DSIPLL_REGM_DISPC
]
=
{
22
,
19
},
[
FEAT_REG_DSIPLL_REGM_DSI
]
=
{
26
,
23
},
};
};
static
const
struct
dss_reg_field
am43xx_dss_reg_fields
[]
=
{
static
const
struct
dss_reg_field
am43xx_dss_reg_fields
[]
=
{
...
@@ -113,10 +105,6 @@ static const struct dss_reg_field omap4_dss_reg_fields[] = {
...
@@ -113,10 +105,6 @@ static const struct dss_reg_field omap4_dss_reg_fields[] = {
[
FEAT_REG_HORIZONTALACCU
]
=
{
10
,
0
},
[
FEAT_REG_HORIZONTALACCU
]
=
{
10
,
0
},
[
FEAT_REG_VERTICALACCU
]
=
{
26
,
16
},
[
FEAT_REG_VERTICALACCU
]
=
{
26
,
16
},
[
FEAT_REG_DISPC_CLK_SWITCH
]
=
{
9
,
8
},
[
FEAT_REG_DISPC_CLK_SWITCH
]
=
{
9
,
8
},
[
FEAT_REG_DSIPLL_REGN
]
=
{
8
,
1
},
[
FEAT_REG_DSIPLL_REGM
]
=
{
20
,
9
},
[
FEAT_REG_DSIPLL_REGM_DISPC
]
=
{
25
,
21
},
[
FEAT_REG_DSIPLL_REGM_DSI
]
=
{
30
,
26
},
};
};
static
const
struct
dss_reg_field
omap5_dss_reg_fields
[]
=
{
static
const
struct
dss_reg_field
omap5_dss_reg_fields
[]
=
{
...
@@ -128,10 +116,6 @@ static const struct dss_reg_field omap5_dss_reg_fields[] = {
...
@@ -128,10 +116,6 @@ static const struct dss_reg_field omap5_dss_reg_fields[] = {
[
FEAT_REG_HORIZONTALACCU
]
=
{
10
,
0
},
[
FEAT_REG_HORIZONTALACCU
]
=
{
10
,
0
},
[
FEAT_REG_VERTICALACCU
]
=
{
26
,
16
},
[
FEAT_REG_VERTICALACCU
]
=
{
26
,
16
},
[
FEAT_REG_DISPC_CLK_SWITCH
]
=
{
9
,
7
},
[
FEAT_REG_DISPC_CLK_SWITCH
]
=
{
9
,
7
},
[
FEAT_REG_DSIPLL_REGN
]
=
{
8
,
1
},
[
FEAT_REG_DSIPLL_REGM
]
=
{
20
,
9
},
[
FEAT_REG_DSIPLL_REGM_DISPC
]
=
{
25
,
21
},
[
FEAT_REG_DSIPLL_REGM_DSI
]
=
{
30
,
26
},
};
};
static
const
enum
omap_display_type
omap2_dss_supported_displays
[]
=
{
static
const
enum
omap_display_type
omap2_dss_supported_displays
[]
=
{
...
@@ -437,12 +421,6 @@ static const char * const omap5_dss_clk_source_names[] = {
...
@@ -437,12 +421,6 @@ static const char * const omap5_dss_clk_source_names[] = {
static
const
struct
dss_param_range
omap2_dss_param_range
[]
=
{
static
const
struct
dss_param_range
omap2_dss_param_range
[]
=
{
[
FEAT_PARAM_DSS_FCK
]
=
{
0
,
133000000
},
[
FEAT_PARAM_DSS_FCK
]
=
{
0
,
133000000
},
[
FEAT_PARAM_DSS_PCD
]
=
{
2
,
255
},
[
FEAT_PARAM_DSS_PCD
]
=
{
2
,
255
},
[
FEAT_PARAM_DSIPLL_REGN
]
=
{
0
,
0
},
[
FEAT_PARAM_DSIPLL_REGM
]
=
{
0
,
0
},
[
FEAT_PARAM_DSIPLL_REGM_DISPC
]
=
{
0
,
0
},
[
FEAT_PARAM_DSIPLL_REGM_DSI
]
=
{
0
,
0
},
[
FEAT_PARAM_DSIPLL_FINT
]
=
{
0
,
0
},
[
FEAT_PARAM_DSIPLL_LPDIV
]
=
{
0
,
0
},
[
FEAT_PARAM_DOWNSCALE
]
=
{
1
,
2
},
[
FEAT_PARAM_DOWNSCALE
]
=
{
1
,
2
},
/*
/*
* Assuming the line width buffer to be 768 pixels as OMAP2 DISPC
* Assuming the line width buffer to be 768 pixels as OMAP2 DISPC
...
@@ -454,11 +432,6 @@ static const struct dss_param_range omap2_dss_param_range[] = {
...
@@ -454,11 +432,6 @@ static const struct dss_param_range omap2_dss_param_range[] = {
static
const
struct
dss_param_range
omap3_dss_param_range
[]
=
{
static
const
struct
dss_param_range
omap3_dss_param_range
[]
=
{
[
FEAT_PARAM_DSS_FCK
]
=
{
0
,
173000000
},
[
FEAT_PARAM_DSS_FCK
]
=
{
0
,
173000000
},
[
FEAT_PARAM_DSS_PCD
]
=
{
1
,
255
},
[
FEAT_PARAM_DSS_PCD
]
=
{
1
,
255
},
[
FEAT_PARAM_DSIPLL_REGN
]
=
{
0
,
(
1
<<
7
)
-
1
},
[
FEAT_PARAM_DSIPLL_REGM
]
=
{
0
,
(
1
<<
11
)
-
1
},
[
FEAT_PARAM_DSIPLL_REGM_DISPC
]
=
{
0
,
(
1
<<
4
)
-
1
},
[
FEAT_PARAM_DSIPLL_REGM_DSI
]
=
{
0
,
(
1
<<
4
)
-
1
},
[
FEAT_PARAM_DSIPLL_FINT
]
=
{
750000
,
2100000
},
[
FEAT_PARAM_DSIPLL_LPDIV
]
=
{
1
,
(
1
<<
13
)
-
1
},
[
FEAT_PARAM_DSIPLL_LPDIV
]
=
{
1
,
(
1
<<
13
)
-
1
},
[
FEAT_PARAM_DSI_FCK
]
=
{
0
,
173000000
},
[
FEAT_PARAM_DSI_FCK
]
=
{
0
,
173000000
},
[
FEAT_PARAM_DOWNSCALE
]
=
{
1
,
4
},
[
FEAT_PARAM_DOWNSCALE
]
=
{
1
,
4
},
...
@@ -475,11 +448,6 @@ static const struct dss_param_range am43xx_dss_param_range[] = {
...
@@ -475,11 +448,6 @@ static const struct dss_param_range am43xx_dss_param_range[] = {
static
const
struct
dss_param_range
omap4_dss_param_range
[]
=
{
static
const
struct
dss_param_range
omap4_dss_param_range
[]
=
{
[
FEAT_PARAM_DSS_FCK
]
=
{
0
,
186000000
},
[
FEAT_PARAM_DSS_FCK
]
=
{
0
,
186000000
},
[
FEAT_PARAM_DSS_PCD
]
=
{
1
,
255
},
[
FEAT_PARAM_DSS_PCD
]
=
{
1
,
255
},
[
FEAT_PARAM_DSIPLL_REGN
]
=
{
0
,
(
1
<<
8
)
-
1
},
[
FEAT_PARAM_DSIPLL_REGM
]
=
{
0
,
(
1
<<
12
)
-
1
},
[
FEAT_PARAM_DSIPLL_REGM_DISPC
]
=
{
0
,
(
1
<<
5
)
-
1
},
[
FEAT_PARAM_DSIPLL_REGM_DSI
]
=
{
0
,
(
1
<<
5
)
-
1
},
[
FEAT_PARAM_DSIPLL_FINT
]
=
{
500000
,
2500000
},
[
FEAT_PARAM_DSIPLL_LPDIV
]
=
{
0
,
(
1
<<
13
)
-
1
},
[
FEAT_PARAM_DSIPLL_LPDIV
]
=
{
0
,
(
1
<<
13
)
-
1
},
[
FEAT_PARAM_DSI_FCK
]
=
{
0
,
170000000
},
[
FEAT_PARAM_DSI_FCK
]
=
{
0
,
170000000
},
[
FEAT_PARAM_DOWNSCALE
]
=
{
1
,
4
},
[
FEAT_PARAM_DOWNSCALE
]
=
{
1
,
4
},
...
@@ -489,11 +457,6 @@ static const struct dss_param_range omap4_dss_param_range[] = {
...
@@ -489,11 +457,6 @@ static const struct dss_param_range omap4_dss_param_range[] = {
static
const
struct
dss_param_range
omap5_dss_param_range
[]
=
{
static
const
struct
dss_param_range
omap5_dss_param_range
[]
=
{
[
FEAT_PARAM_DSS_FCK
]
=
{
0
,
209250000
},
[
FEAT_PARAM_DSS_FCK
]
=
{
0
,
209250000
},
[
FEAT_PARAM_DSS_PCD
]
=
{
1
,
255
},
[
FEAT_PARAM_DSS_PCD
]
=
{
1
,
255
},
[
FEAT_PARAM_DSIPLL_REGN
]
=
{
0
,
(
1
<<
8
)
-
1
},
[
FEAT_PARAM_DSIPLL_REGM
]
=
{
0
,
(
1
<<
12
)
-
1
},
[
FEAT_PARAM_DSIPLL_REGM_DISPC
]
=
{
0
,
(
1
<<
5
)
-
1
},
[
FEAT_PARAM_DSIPLL_REGM_DSI
]
=
{
0
,
(
1
<<
5
)
-
1
},
[
FEAT_PARAM_DSIPLL_FINT
]
=
{
150000
,
52000000
},
[
FEAT_PARAM_DSIPLL_LPDIV
]
=
{
0
,
(
1
<<
13
)
-
1
},
[
FEAT_PARAM_DSIPLL_LPDIV
]
=
{
0
,
(
1
<<
13
)
-
1
},
[
FEAT_PARAM_DSI_FCK
]
=
{
0
,
209250000
},
[
FEAT_PARAM_DSI_FCK
]
=
{
0
,
209250000
},
[
FEAT_PARAM_DOWNSCALE
]
=
{
1
,
4
},
[
FEAT_PARAM_DOWNSCALE
]
=
{
1
,
4
},
...
@@ -517,7 +480,6 @@ static const enum dss_feat_id omap3430_dss_feat_list[] = {
...
@@ -517,7 +480,6 @@ static const enum dss_feat_id omap3430_dss_feat_list[] = {
FEAT_LINEBUFFERSPLIT
,
FEAT_LINEBUFFERSPLIT
,
FEAT_ROWREPEATENABLE
,
FEAT_ROWREPEATENABLE
,
FEAT_RESIZECONF
,
FEAT_RESIZECONF
,
FEAT_DSI_PLL_FREQSEL
,
FEAT_DSI_REVERSE_TXCLKESC
,
FEAT_DSI_REVERSE_TXCLKESC
,
FEAT_VENC_REQUIRES_TV_DAC_CLK
,
FEAT_VENC_REQUIRES_TV_DAC_CLK
,
FEAT_CPR
,
FEAT_CPR
,
...
@@ -537,7 +499,6 @@ static const enum dss_feat_id am35xx_dss_feat_list[] = {
...
@@ -537,7 +499,6 @@ static const enum dss_feat_id am35xx_dss_feat_list[] = {
FEAT_LINEBUFFERSPLIT
,
FEAT_LINEBUFFERSPLIT
,
FEAT_ROWREPEATENABLE
,
FEAT_ROWREPEATENABLE
,
FEAT_RESIZECONF
,
FEAT_RESIZECONF
,
FEAT_DSI_PLL_FREQSEL
,
FEAT_DSI_REVERSE_TXCLKESC
,
FEAT_DSI_REVERSE_TXCLKESC
,
FEAT_VENC_REQUIRES_TV_DAC_CLK
,
FEAT_VENC_REQUIRES_TV_DAC_CLK
,
FEAT_CPR
,
FEAT_CPR
,
...
@@ -572,7 +533,6 @@ static const enum dss_feat_id omap3630_dss_feat_list[] = {
...
@@ -572,7 +533,6 @@ static const enum dss_feat_id omap3630_dss_feat_list[] = {
FEAT_ROWREPEATENABLE
,
FEAT_ROWREPEATENABLE
,
FEAT_RESIZECONF
,
FEAT_RESIZECONF
,
FEAT_DSI_PLL_PWR_BUG
,
FEAT_DSI_PLL_PWR_BUG
,
FEAT_DSI_PLL_FREQSEL
,
FEAT_CPR
,
FEAT_CPR
,
FEAT_PRELOAD
,
FEAT_PRELOAD
,
FEAT_FIR_COEF_V
,
FEAT_FIR_COEF_V
,
...
@@ -654,8 +614,6 @@ static const enum dss_feat_id omap5_dss_feat_list[] = {
...
@@ -654,8 +614,6 @@ static const enum dss_feat_id omap5_dss_feat_list[] = {
FEAT_ALPHA_FREE_ZORDER
,
FEAT_ALPHA_FREE_ZORDER
,
FEAT_FIFO_MERGE
,
FEAT_FIFO_MERGE
,
FEAT_BURST_2D
,
FEAT_BURST_2D
,
FEAT_DSI_PLL_SELFREQDCO
,
FEAT_DSI_PLL_REFSEL
,
FEAT_DSI_PHY_DCC
,
FEAT_DSI_PHY_DCC
,
FEAT_MFLAG
,
FEAT_MFLAG
,
};
};
...
...
drivers/video/fbdev/omap2/dss/dss_features.h
浏览文件 @
3315764e
...
@@ -41,7 +41,6 @@ enum dss_feat_id {
...
@@ -41,7 +41,6 @@ enum dss_feat_id {
FEAT_LCD_CLK_SRC
,
FEAT_LCD_CLK_SRC
,
/* DSI-PLL power command 0x3 is not working */
/* DSI-PLL power command 0x3 is not working */
FEAT_DSI_PLL_PWR_BUG
,
FEAT_DSI_PLL_PWR_BUG
,
FEAT_DSI_PLL_FREQSEL
,
FEAT_DSI_DCS_CMD_CONFIG_VC
,
FEAT_DSI_DCS_CMD_CONFIG_VC
,
FEAT_DSI_VC_OCP_WIDTH
,
FEAT_DSI_VC_OCP_WIDTH
,
FEAT_DSI_REVERSE_TXCLKESC
,
FEAT_DSI_REVERSE_TXCLKESC
,
...
@@ -61,8 +60,6 @@ enum dss_feat_id {
...
@@ -61,8 +60,6 @@ enum dss_feat_id {
/* An unknown HW bug causing the normal FIFO thresholds not to work */
/* An unknown HW bug causing the normal FIFO thresholds not to work */
FEAT_OMAP3_DSI_FIFO_BUG
,
FEAT_OMAP3_DSI_FIFO_BUG
,
FEAT_BURST_2D
,
FEAT_BURST_2D
,
FEAT_DSI_PLL_SELFREQDCO
,
FEAT_DSI_PLL_REFSEL
,
FEAT_DSI_PHY_DCC
,
FEAT_DSI_PHY_DCC
,
FEAT_MFLAG
,
FEAT_MFLAG
,
};
};
...
@@ -77,20 +74,11 @@ enum dss_feat_reg_field {
...
@@ -77,20 +74,11 @@ enum dss_feat_reg_field {
FEAT_REG_HORIZONTALACCU
,
FEAT_REG_HORIZONTALACCU
,
FEAT_REG_VERTICALACCU
,
FEAT_REG_VERTICALACCU
,
FEAT_REG_DISPC_CLK_SWITCH
,
FEAT_REG_DISPC_CLK_SWITCH
,
FEAT_REG_DSIPLL_REGN
,
FEAT_REG_DSIPLL_REGM
,
FEAT_REG_DSIPLL_REGM_DISPC
,
FEAT_REG_DSIPLL_REGM_DSI
,
};
};
enum
dss_range_param
{
enum
dss_range_param
{
FEAT_PARAM_DSS_FCK
,
FEAT_PARAM_DSS_FCK
,
FEAT_PARAM_DSS_PCD
,
FEAT_PARAM_DSS_PCD
,
FEAT_PARAM_DSIPLL_REGN
,
FEAT_PARAM_DSIPLL_REGM
,
FEAT_PARAM_DSIPLL_REGM_DISPC
,
FEAT_PARAM_DSIPLL_REGM_DSI
,
FEAT_PARAM_DSIPLL_FINT
,
FEAT_PARAM_DSIPLL_LPDIV
,
FEAT_PARAM_DSIPLL_LPDIV
,
FEAT_PARAM_DSI_FCK
,
FEAT_PARAM_DSI_FCK
,
FEAT_PARAM_DOWNSCALE
,
FEAT_PARAM_DOWNSCALE
,
...
...
drivers/video/fbdev/omap2/dss/hdmi.h
浏览文件 @
3315764e
...
@@ -101,13 +101,6 @@ enum hdmi_core_hdmi_dvi {
...
@@ -101,13 +101,6 @@ enum hdmi_core_hdmi_dvi {
HDMI_HDMI
=
1
HDMI_HDMI
=
1
};
};
enum
hdmi_clk_refsel
{
HDMI_REFSEL_PCLK
=
0
,
HDMI_REFSEL_REF1
=
1
,
HDMI_REFSEL_REF2
=
2
,
HDMI_REFSEL_SYSCLK
=
3
};
enum
hdmi_packing_mode
{
enum
hdmi_packing_mode
{
HDMI_PACK_10b_RGB_YUV444
=
0
,
HDMI_PACK_10b_RGB_YUV444
=
0
,
HDMI_PACK_24b_RGB_YUV444_YUV422
=
1
,
HDMI_PACK_24b_RGB_YUV444_YUV422
=
1
,
...
@@ -160,7 +153,8 @@ enum hdmi_audio_blk_strt_end_sig {
...
@@ -160,7 +153,8 @@ enum hdmi_audio_blk_strt_end_sig {
enum
hdmi_core_audio_layout
{
enum
hdmi_core_audio_layout
{
HDMI_AUDIO_LAYOUT_2CH
=
0
,
HDMI_AUDIO_LAYOUT_2CH
=
0
,
HDMI_AUDIO_LAYOUT_8CH
=
1
HDMI_AUDIO_LAYOUT_8CH
=
1
,
HDMI_AUDIO_LAYOUT_6CH
=
2
};
};
enum
hdmi_core_cts_mode
{
enum
hdmi_core_cts_mode
{
...
@@ -191,17 +185,6 @@ struct hdmi_config {
...
@@ -191,17 +185,6 @@ struct hdmi_config {
enum
hdmi_core_hdmi_dvi
hdmi_dvi_mode
;
enum
hdmi_core_hdmi_dvi
hdmi_dvi_mode
;
};
};
/* HDMI PLL structure */
struct
hdmi_pll_info
{
u16
regn
;
u16
regm
;
u32
regmf
;
u16
regm2
;
u16
regsd
;
u16
dcofreq
;
enum
hdmi_clk_refsel
refsel
;
};
struct
hdmi_audio_format
{
struct
hdmi_audio_format
{
enum
hdmi_stereo_channels
stereo_channels
;
enum
hdmi_stereo_channels
stereo_channels
;
u8
active_chnnls_msk
;
u8
active_chnnls_msk
;
...
@@ -249,12 +232,15 @@ struct hdmi_core_audio_config {
...
@@ -249,12 +232,15 @@ struct hdmi_core_audio_config {
struct
hdmi_wp_data
{
struct
hdmi_wp_data
{
void
__iomem
*
base
;
void
__iomem
*
base
;
phys_addr_t
phys_base
;
};
};
struct
hdmi_pll_data
{
struct
hdmi_pll_data
{
struct
dss_pll
pll
;
void
__iomem
*
base
;
void
__iomem
*
base
;
struct
hdmi_
pll_info
info
;
struct
hdmi_
wp_data
*
wp
;
};
};
struct
hdmi_phy_data
{
struct
hdmi_phy_data
{
...
@@ -316,16 +302,19 @@ void hdmi_wp_video_config_timing(struct hdmi_wp_data *wp,
...
@@ -316,16 +302,19 @@ void hdmi_wp_video_config_timing(struct hdmi_wp_data *wp,
void
hdmi_wp_init_vid_fmt_timings
(
struct
hdmi_video_format
*
video_fmt
,
void
hdmi_wp_init_vid_fmt_timings
(
struct
hdmi_video_format
*
video_fmt
,
struct
omap_video_timings
*
timings
,
struct
hdmi_config
*
param
);
struct
omap_video_timings
*
timings
,
struct
hdmi_config
*
param
);
int
hdmi_wp_init
(
struct
platform_device
*
pdev
,
struct
hdmi_wp_data
*
wp
);
int
hdmi_wp_init
(
struct
platform_device
*
pdev
,
struct
hdmi_wp_data
*
wp
);
phys_addr_t
hdmi_wp_get_audio_dma_addr
(
struct
hdmi_wp_data
*
wp
);
/* HDMI PLL funcs */
/* HDMI PLL funcs */
int
hdmi_pll_enable
(
struct
hdmi_pll_data
*
pll
,
struct
hdmi_wp_data
*
wp
);
void
hdmi_pll_disable
(
struct
hdmi_pll_data
*
pll
,
struct
hdmi_wp_data
*
wp
);
void
hdmi_pll_dump
(
struct
hdmi_pll_data
*
pll
,
struct
seq_file
*
s
);
void
hdmi_pll_dump
(
struct
hdmi_pll_data
*
pll
,
struct
seq_file
*
s
);
void
hdmi_pll_compute
(
struct
hdmi_pll_data
*
pll
,
unsigned
long
clkin
,
int
phy
);
void
hdmi_pll_compute
(
struct
hdmi_pll_data
*
pll
,
int
hdmi_pll_init
(
struct
platform_device
*
pdev
,
struct
hdmi_pll_data
*
pll
);
unsigned
long
target_tmds
,
struct
dss_pll_clock_info
*
pi
);
int
hdmi_pll_init
(
struct
platform_device
*
pdev
,
struct
hdmi_pll_data
*
pll
,
struct
hdmi_wp_data
*
wp
);
void
hdmi_pll_uninit
(
struct
hdmi_pll_data
*
hpll
);
/* HDMI PHY funcs */
/* HDMI PHY funcs */
int
hdmi_phy_configure
(
struct
hdmi_phy_data
*
phy
,
struct
hdmi_config
*
cfg
);
int
hdmi_phy_configure
(
struct
hdmi_phy_data
*
phy
,
unsigned
long
hfbitclk
,
unsigned
long
lfbitclk
);
void
hdmi_phy_dump
(
struct
hdmi_phy_data
*
phy
,
struct
seq_file
*
s
);
void
hdmi_phy_dump
(
struct
hdmi_phy_data
*
phy
,
struct
seq_file
*
s
);
int
hdmi_phy_init
(
struct
platform_device
*
pdev
,
struct
hdmi_phy_data
*
phy
);
int
hdmi_phy_init
(
struct
platform_device
*
pdev
,
struct
hdmi_phy_data
*
phy
);
int
hdmi_phy_parse_lanes
(
struct
hdmi_phy_data
*
phy
,
const
u32
*
lanes
);
int
hdmi_phy_parse_lanes
(
struct
hdmi_phy_data
*
phy
,
const
u32
*
lanes
);
...
@@ -334,7 +323,7 @@ int hdmi_phy_parse_lanes(struct hdmi_phy_data *phy, const u32 *lanes);
...
@@ -334,7 +323,7 @@ int hdmi_phy_parse_lanes(struct hdmi_phy_data *phy, const u32 *lanes);
int
hdmi_parse_lanes_of
(
struct
platform_device
*
pdev
,
struct
device_node
*
ep
,
int
hdmi_parse_lanes_of
(
struct
platform_device
*
pdev
,
struct
device_node
*
ep
,
struct
hdmi_phy_data
*
phy
);
struct
hdmi_phy_data
*
phy
);
#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) || defined(CONFIG_OMAP5_DSS_HDMI_AUDIO)
/* Audio funcs */
int
hdmi_compute_acr
(
u32
pclk
,
u32
sample_freq
,
u32
*
n
,
u32
*
cts
);
int
hdmi_compute_acr
(
u32
pclk
,
u32
sample_freq
,
u32
*
n
,
u32
*
cts
);
int
hdmi_wp_audio_enable
(
struct
hdmi_wp_data
*
wp
,
bool
enable
);
int
hdmi_wp_audio_enable
(
struct
hdmi_wp_data
*
wp
,
bool
enable
);
int
hdmi_wp_audio_core_req_enable
(
struct
hdmi_wp_data
*
wp
,
bool
enable
);
int
hdmi_wp_audio_core_req_enable
(
struct
hdmi_wp_data
*
wp
,
bool
enable
);
...
@@ -342,9 +331,33 @@ void hdmi_wp_audio_config_format(struct hdmi_wp_data *wp,
...
@@ -342,9 +331,33 @@ void hdmi_wp_audio_config_format(struct hdmi_wp_data *wp,
struct
hdmi_audio_format
*
aud_fmt
);
struct
hdmi_audio_format
*
aud_fmt
);
void
hdmi_wp_audio_config_dma
(
struct
hdmi_wp_data
*
wp
,
void
hdmi_wp_audio_config_dma
(
struct
hdmi_wp_data
*
wp
,
struct
hdmi_audio_dma
*
aud_dma
);
struct
hdmi_audio_dma
*
aud_dma
);
static
inline
bool
hdmi_mode_has_audio
(
int
mode
)
static
inline
bool
hdmi_mode_has_audio
(
struct
hdmi_config
*
cfg
)
{
{
return
mode
==
HDMI_HDMI
?
true
:
false
;
return
cfg
->
hdmi_dvi_
mode
==
HDMI_HDMI
?
true
:
false
;
}
}
#endif
/* HDMI DRV data */
struct
omap_hdmi
{
struct
mutex
lock
;
struct
platform_device
*
pdev
;
struct
hdmi_wp_data
wp
;
struct
hdmi_pll_data
pll
;
struct
hdmi_phy_data
phy
;
struct
hdmi_core_data
core
;
struct
hdmi_config
cfg
;
struct
regulator
*
vdda_reg
;
bool
core_enabled
;
bool
display_enabled
;
struct
omap_dss_device
output
;
struct
platform_device
*
audio_pdev
;
void
(
*
audio_abort_cb
)(
struct
device
*
dev
);
int
wp_idlemode
;
};
#endif
#endif
drivers/video/fbdev/omap2/dss/hdmi4.c
浏览文件 @
3315764e
...
@@ -33,29 +33,14 @@
...
@@ -33,29 +33,14 @@
#include <linux/gpio.h>
#include <linux/gpio.h>
#include <linux/regulator/consumer.h>
#include <linux/regulator/consumer.h>
#include <video/omapdss.h>
#include <video/omapdss.h>
#include <sound/omap-hdmi-audio.h>
#include "hdmi4_core.h"
#include "hdmi4_core.h"
#include "dss.h"
#include "dss.h"
#include "dss_features.h"
#include "dss_features.h"
#include "hdmi.h"
static
struct
{
static
struct
omap_hdmi
hdmi
;
struct
mutex
lock
;
struct
platform_device
*
pdev
;
struct
hdmi_wp_data
wp
;
struct
hdmi_pll_data
pll
;
struct
hdmi_phy_data
phy
;
struct
hdmi_core_data
core
;
struct
hdmi_config
cfg
;
struct
clk
*
sys_clk
;
struct
regulator
*
vdda_hdmi_dac_reg
;
bool
core_enabled
;
struct
omap_dss_device
output
;
}
hdmi
;
static
int
hdmi_runtime_get
(
void
)
static
int
hdmi_runtime_get
(
void
)
{
{
...
@@ -117,7 +102,7 @@ static int hdmi_init_regulator(void)
...
@@ -117,7 +102,7 @@ static int hdmi_init_regulator(void)
int
r
;
int
r
;
struct
regulator
*
reg
;
struct
regulator
*
reg
;
if
(
hdmi
.
vdda_
hdmi_dac_
reg
!=
NULL
)
if
(
hdmi
.
vdda_reg
!=
NULL
)
return
0
;
return
0
;
reg
=
devm_regulator_get
(
&
hdmi
.
pdev
->
dev
,
"vdda"
);
reg
=
devm_regulator_get
(
&
hdmi
.
pdev
->
dev
,
"vdda"
);
...
@@ -137,7 +122,7 @@ static int hdmi_init_regulator(void)
...
@@ -137,7 +122,7 @@ static int hdmi_init_regulator(void)
}
}
}
}
hdmi
.
vdda_
hdmi_dac_
reg
=
reg
;
hdmi
.
vdda_reg
=
reg
;
return
0
;
return
0
;
}
}
...
@@ -146,7 +131,7 @@ static int hdmi_power_on_core(struct omap_dss_device *dssdev)
...
@@ -146,7 +131,7 @@ static int hdmi_power_on_core(struct omap_dss_device *dssdev)
{
{
int
r
;
int
r
;
r
=
regulator_enable
(
hdmi
.
vdda_
hdmi_dac_
reg
);
r
=
regulator_enable
(
hdmi
.
vdda_reg
);
if
(
r
)
if
(
r
)
return
r
;
return
r
;
...
@@ -162,7 +147,7 @@ static int hdmi_power_on_core(struct omap_dss_device *dssdev)
...
@@ -162,7 +147,7 @@ static int hdmi_power_on_core(struct omap_dss_device *dssdev)
return
0
;
return
0
;
err_runtime_get:
err_runtime_get:
regulator_disable
(
hdmi
.
vdda_
hdmi_dac_
reg
);
regulator_disable
(
hdmi
.
vdda_reg
);
return
r
;
return
r
;
}
}
...
@@ -172,7 +157,7 @@ static void hdmi_power_off_core(struct omap_dss_device *dssdev)
...
@@ -172,7 +157,7 @@ static void hdmi_power_off_core(struct omap_dss_device *dssdev)
hdmi
.
core_enabled
=
false
;
hdmi
.
core_enabled
=
false
;
hdmi_runtime_put
();
hdmi_runtime_put
();
regulator_disable
(
hdmi
.
vdda_
hdmi_dac_
reg
);
regulator_disable
(
hdmi
.
vdda_reg
);
}
}
static
int
hdmi_power_on_full
(
struct
omap_dss_device
*
dssdev
)
static
int
hdmi_power_on_full
(
struct
omap_dss_device
*
dssdev
)
...
@@ -180,8 +165,8 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
...
@@ -180,8 +165,8 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
int
r
;
int
r
;
struct
omap_video_timings
*
p
;
struct
omap_video_timings
*
p
;
struct
omap_overlay_manager
*
mgr
=
hdmi
.
output
.
manager
;
struct
omap_overlay_manager
*
mgr
=
hdmi
.
output
.
manager
;
unsigned
long
phy
;
struct
hdmi_wp_data
*
wp
=
&
hdmi
.
wp
;
struct
hdmi_wp_data
*
wp
=
&
hdmi
.
wp
;
struct
dss_pll_clock_info
hdmi_cinfo
=
{
0
};
r
=
hdmi_power_on_core
(
dssdev
);
r
=
hdmi_power_on_core
(
dssdev
);
if
(
r
)
if
(
r
)
...
@@ -195,19 +180,22 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
...
@@ -195,19 +180,22 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
DSSDBG
(
"hdmi_power_on x_res= %d y_res = %d
\n
"
,
p
->
x_res
,
p
->
y_res
);
DSSDBG
(
"hdmi_power_on x_res= %d y_res = %d
\n
"
,
p
->
x_res
,
p
->
y_res
);
/* the functions below use kHz pixel clock. TODO: change to Hz */
hdmi_pll_compute
(
&
hdmi
.
pll
,
p
->
pixelclock
,
&
hdmi_cinfo
);
phy
=
p
->
pixelclock
/
1000
;
hdmi_pll_compute
(
&
hdmi
.
pll
,
clk_get_rate
(
hdmi
.
sys_clk
),
phy
);
/* config the PLL and PHY hdmi_set_pll_pwrfirst */
r
=
dss_pll_enable
(
&
hdmi
.
pll
.
pll
);
r
=
hdmi_pll_enable
(
&
hdmi
.
pll
,
&
hdmi
.
wp
);
if
(
r
)
{
if
(
r
)
{
DSS
DBG
(
"Failed to lock
PLL
\n
"
);
DSS
ERR
(
"Failed to enable
PLL
\n
"
);
goto
err_pll_enable
;
goto
err_pll_enable
;
}
}
r
=
hdmi_phy_configure
(
&
hdmi
.
phy
,
&
hdmi
.
cfg
);
r
=
dss_pll_set_config
(
&
hdmi
.
pll
.
pll
,
&
hdmi_cinfo
);
if
(
r
)
{
DSSERR
(
"Failed to configure PLL
\n
"
);
goto
err_pll_cfg
;
}
r
=
hdmi_phy_configure
(
&
hdmi
.
phy
,
hdmi_cinfo
.
clkdco
,
hdmi_cinfo
.
clkout
[
0
]);
if
(
r
)
{
if
(
r
)
{
DSSDBG
(
"Failed to configure PHY
\n
"
);
DSSDBG
(
"Failed to configure PHY
\n
"
);
goto
err_phy_cfg
;
goto
err_phy_cfg
;
...
@@ -244,7 +232,8 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
...
@@ -244,7 +232,8 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
err_phy_cfg:
err_phy_cfg:
hdmi_wp_set_phy_pwr
(
&
hdmi
.
wp
,
HDMI_PHYPWRCMD_OFF
);
hdmi_wp_set_phy_pwr
(
&
hdmi
.
wp
,
HDMI_PHYPWRCMD_OFF
);
err_phy_pwr:
err_phy_pwr:
hdmi_pll_disable
(
&
hdmi
.
pll
,
&
hdmi
.
wp
);
err_pll_cfg:
dss_pll_disable
(
&
hdmi
.
pll
.
pll
);
err_pll_enable:
err_pll_enable:
hdmi_power_off_core
(
dssdev
);
hdmi_power_off_core
(
dssdev
);
return
-
EIO
;
return
-
EIO
;
...
@@ -262,7 +251,7 @@ static void hdmi_power_off_full(struct omap_dss_device *dssdev)
...
@@ -262,7 +251,7 @@ static void hdmi_power_off_full(struct omap_dss_device *dssdev)
hdmi_wp_set_phy_pwr
(
&
hdmi
.
wp
,
HDMI_PHYPWRCMD_OFF
);
hdmi_wp_set_phy_pwr
(
&
hdmi
.
wp
,
HDMI_PHYPWRCMD_OFF
);
hdmi_pll_disable
(
&
hdmi
.
pll
,
&
hdmi
.
wp
);
dss_pll_disable
(
&
hdmi
.
pll
.
pll
);
hdmi_power_off_core
(
dssdev
);
hdmi_power_off_core
(
dssdev
);
}
}
...
@@ -352,6 +341,8 @@ static int hdmi_display_enable(struct omap_dss_device *dssdev)
...
@@ -352,6 +341,8 @@ static int hdmi_display_enable(struct omap_dss_device *dssdev)
goto
err0
;
goto
err0
;
}
}
hdmi
.
display_enabled
=
true
;
mutex_unlock
(
&
hdmi
.
lock
);
mutex_unlock
(
&
hdmi
.
lock
);
return
0
;
return
0
;
...
@@ -366,8 +357,13 @@ static void hdmi_display_disable(struct omap_dss_device *dssdev)
...
@@ -366,8 +357,13 @@ static void hdmi_display_disable(struct omap_dss_device *dssdev)
mutex_lock
(
&
hdmi
.
lock
);
mutex_lock
(
&
hdmi
.
lock
);
if
(
hdmi
.
audio_pdev
&&
hdmi
.
audio_abort_cb
)
hdmi
.
audio_abort_cb
(
&
hdmi
.
audio_pdev
->
dev
);
hdmi_power_off_full
(
dssdev
);
hdmi_power_off_full
(
dssdev
);
hdmi
.
display_enabled
=
false
;
mutex_unlock
(
&
hdmi
.
lock
);
mutex_unlock
(
&
hdmi
.
lock
);
}
}
...
@@ -404,21 +400,6 @@ static void hdmi_core_disable(struct omap_dss_device *dssdev)
...
@@ -404,21 +400,6 @@ static void hdmi_core_disable(struct omap_dss_device *dssdev)
mutex_unlock
(
&
hdmi
.
lock
);
mutex_unlock
(
&
hdmi
.
lock
);
}
}
static
int
hdmi_get_clocks
(
struct
platform_device
*
pdev
)
{
struct
clk
*
clk
;
clk
=
devm_clk_get
(
&
pdev
->
dev
,
"sys_clk"
);
if
(
IS_ERR
(
clk
))
{
DSSERR
(
"can't get sys_clk
\n
"
);
return
PTR_ERR
(
clk
);
}
hdmi
.
sys_clk
=
clk
;
return
0
;
}
static
int
hdmi_connect
(
struct
omap_dss_device
*
dssdev
,
static
int
hdmi_connect
(
struct
omap_dss_device
*
dssdev
,
struct
omap_dss_device
*
dst
)
struct
omap_dss_device
*
dst
)
{
{
...
@@ -484,112 +465,6 @@ static int hdmi_read_edid(struct omap_dss_device *dssdev,
...
@@ -484,112 +465,6 @@ static int hdmi_read_edid(struct omap_dss_device *dssdev,
return
r
;
return
r
;
}
}
#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
static
int
hdmi_audio_enable
(
struct
omap_dss_device
*
dssdev
)
{
int
r
;
mutex_lock
(
&
hdmi
.
lock
);
if
(
!
hdmi_mode_has_audio
(
hdmi
.
cfg
.
hdmi_dvi_mode
))
{
r
=
-
EPERM
;
goto
err
;
}
r
=
hdmi_wp_audio_enable
(
&
hdmi
.
wp
,
true
);
if
(
r
)
goto
err
;
mutex_unlock
(
&
hdmi
.
lock
);
return
0
;
err:
mutex_unlock
(
&
hdmi
.
lock
);
return
r
;
}
static
void
hdmi_audio_disable
(
struct
omap_dss_device
*
dssdev
)
{
hdmi_wp_audio_enable
(
&
hdmi
.
wp
,
false
);
}
static
int
hdmi_audio_start
(
struct
omap_dss_device
*
dssdev
)
{
return
hdmi4_audio_start
(
&
hdmi
.
core
,
&
hdmi
.
wp
);
}
static
void
hdmi_audio_stop
(
struct
omap_dss_device
*
dssdev
)
{
hdmi4_audio_stop
(
&
hdmi
.
core
,
&
hdmi
.
wp
);
}
static
bool
hdmi_audio_supported
(
struct
omap_dss_device
*
dssdev
)
{
bool
r
;
mutex_lock
(
&
hdmi
.
lock
);
r
=
hdmi_mode_has_audio
(
hdmi
.
cfg
.
hdmi_dvi_mode
);
mutex_unlock
(
&
hdmi
.
lock
);
return
r
;
}
static
int
hdmi_audio_config
(
struct
omap_dss_device
*
dssdev
,
struct
omap_dss_audio
*
audio
)
{
int
r
;
u32
pclk
=
hdmi
.
cfg
.
timings
.
pixelclock
;
mutex_lock
(
&
hdmi
.
lock
);
if
(
!
hdmi_mode_has_audio
(
hdmi
.
cfg
.
hdmi_dvi_mode
))
{
r
=
-
EPERM
;
goto
err
;
}
r
=
hdmi4_audio_config
(
&
hdmi
.
core
,
&
hdmi
.
wp
,
audio
,
pclk
);
if
(
r
)
goto
err
;
mutex_unlock
(
&
hdmi
.
lock
);
return
0
;
err:
mutex_unlock
(
&
hdmi
.
lock
);
return
r
;
}
#else
static
int
hdmi_audio_enable
(
struct
omap_dss_device
*
dssdev
)
{
return
-
EPERM
;
}
static
void
hdmi_audio_disable
(
struct
omap_dss_device
*
dssdev
)
{
}
static
int
hdmi_audio_start
(
struct
omap_dss_device
*
dssdev
)
{
return
-
EPERM
;
}
static
void
hdmi_audio_stop
(
struct
omap_dss_device
*
dssdev
)
{
}
static
bool
hdmi_audio_supported
(
struct
omap_dss_device
*
dssdev
)
{
return
false
;
}
static
int
hdmi_audio_config
(
struct
omap_dss_device
*
dssdev
,
struct
omap_dss_audio
*
audio
)
{
return
-
EPERM
;
}
#endif
static
int
hdmi_set_infoframe
(
struct
omap_dss_device
*
dssdev
,
static
int
hdmi_set_infoframe
(
struct
omap_dss_device
*
dssdev
,
const
struct
hdmi_avi_infoframe
*
avi
)
const
struct
hdmi_avi_infoframe
*
avi
)
{
{
...
@@ -618,13 +493,6 @@ static const struct omapdss_hdmi_ops hdmi_ops = {
...
@@ -618,13 +493,6 @@ static const struct omapdss_hdmi_ops hdmi_ops = {
.
read_edid
=
hdmi_read_edid
,
.
read_edid
=
hdmi_read_edid
,
.
set_infoframe
=
hdmi_set_infoframe
,
.
set_infoframe
=
hdmi_set_infoframe
,
.
set_hdmi_mode
=
hdmi_set_hdmi_mode
,
.
set_hdmi_mode
=
hdmi_set_hdmi_mode
,
.
audio_enable
=
hdmi_audio_enable
,
.
audio_disable
=
hdmi_audio_disable
,
.
audio_start
=
hdmi_audio_start
,
.
audio_stop
=
hdmi_audio_stop
,
.
audio_supported
=
hdmi_audio_supported
,
.
audio_config
=
hdmi_audio_config
,
};
};
static
void
hdmi_init_output
(
struct
platform_device
*
pdev
)
static
void
hdmi_init_output
(
struct
platform_device
*
pdev
)
...
@@ -642,7 +510,7 @@ static void hdmi_init_output(struct platform_device *pdev)
...
@@ -642,7 +510,7 @@ static void hdmi_init_output(struct platform_device *pdev)
omapdss_register_output
(
out
);
omapdss_register_output
(
out
);
}
}
static
void
__exit
hdmi_uninit_output
(
struct
platform_device
*
pdev
)
static
void
hdmi_uninit_output
(
struct
platform_device
*
pdev
)
{
{
struct
omap_dss_device
*
out
=
&
hdmi
.
output
;
struct
omap_dss_device
*
out
=
&
hdmi
.
output
;
...
@@ -671,6 +539,112 @@ static int hdmi_probe_of(struct platform_device *pdev)
...
@@ -671,6 +539,112 @@ static int hdmi_probe_of(struct platform_device *pdev)
return
r
;
return
r
;
}
}
/* Audio callbacks */
static
int
hdmi_audio_startup
(
struct
device
*
dev
,
void
(
*
abort_cb
)(
struct
device
*
dev
))
{
struct
omap_hdmi
*
hd
=
dev_get_drvdata
(
dev
);
int
ret
=
0
;
mutex_lock
(
&
hd
->
lock
);
if
(
!
hdmi_mode_has_audio
(
&
hd
->
cfg
)
||
!
hd
->
display_enabled
)
{
ret
=
-
EPERM
;
goto
out
;
}
hd
->
audio_abort_cb
=
abort_cb
;
out:
mutex_unlock
(
&
hd
->
lock
);
return
ret
;
}
static
int
hdmi_audio_shutdown
(
struct
device
*
dev
)
{
struct
omap_hdmi
*
hd
=
dev_get_drvdata
(
dev
);
mutex_lock
(
&
hd
->
lock
);
hd
->
audio_abort_cb
=
NULL
;
mutex_unlock
(
&
hd
->
lock
);
return
0
;
}
static
int
hdmi_audio_start
(
struct
device
*
dev
)
{
struct
omap_hdmi
*
hd
=
dev_get_drvdata
(
dev
);
WARN_ON
(
!
hdmi_mode_has_audio
(
&
hd
->
cfg
));
WARN_ON
(
!
hd
->
display_enabled
);
hdmi_wp_audio_enable
(
&
hd
->
wp
,
true
);
hdmi4_audio_start
(
&
hd
->
core
,
&
hd
->
wp
);
return
0
;
}
static
void
hdmi_audio_stop
(
struct
device
*
dev
)
{
struct
omap_hdmi
*
hd
=
dev_get_drvdata
(
dev
);
WARN_ON
(
!
hdmi_mode_has_audio
(
&
hd
->
cfg
));
WARN_ON
(
!
hd
->
display_enabled
);
hdmi4_audio_stop
(
&
hd
->
core
,
&
hd
->
wp
);
hdmi_wp_audio_enable
(
&
hd
->
wp
,
false
);
}
static
int
hdmi_audio_config
(
struct
device
*
dev
,
struct
omap_dss_audio
*
dss_audio
)
{
struct
omap_hdmi
*
hd
=
dev_get_drvdata
(
dev
);
int
ret
;
mutex_lock
(
&
hd
->
lock
);
if
(
!
hdmi_mode_has_audio
(
&
hd
->
cfg
)
||
!
hd
->
display_enabled
)
{
ret
=
-
EPERM
;
goto
out
;
}
ret
=
hdmi4_audio_config
(
&
hd
->
core
,
&
hd
->
wp
,
dss_audio
,
hd
->
cfg
.
timings
.
pixelclock
);
out:
mutex_unlock
(
&
hd
->
lock
);
return
ret
;
}
static
const
struct
omap_hdmi_audio_ops
hdmi_audio_ops
=
{
.
audio_startup
=
hdmi_audio_startup
,
.
audio_shutdown
=
hdmi_audio_shutdown
,
.
audio_start
=
hdmi_audio_start
,
.
audio_stop
=
hdmi_audio_stop
,
.
audio_config
=
hdmi_audio_config
,
};
static
int
hdmi_audio_register
(
struct
device
*
dev
)
{
struct
omap_hdmi_audio_pdata
pdata
=
{
.
dev
=
dev
,
.
dss_version
=
omapdss_get_version
(),
.
audio_dma_addr
=
hdmi_wp_get_audio_dma_addr
(
&
hdmi
.
wp
),
.
ops
=
&
hdmi_audio_ops
,
};
hdmi
.
audio_pdev
=
platform_device_register_data
(
dev
,
"omap-hdmi-audio"
,
PLATFORM_DEVID_AUTO
,
&
pdata
,
sizeof
(
pdata
));
if
(
IS_ERR
(
hdmi
.
audio_pdev
))
return
PTR_ERR
(
hdmi
.
audio_pdev
);
return
0
;
}
/* HDMI HW IP initialisation */
/* HDMI HW IP initialisation */
static
int
omapdss_hdmihw_probe
(
struct
platform_device
*
pdev
)
static
int
omapdss_hdmihw_probe
(
struct
platform_device
*
pdev
)
{
{
...
@@ -678,6 +652,7 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
...
@@ -678,6 +652,7 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
int
irq
;
int
irq
;
hdmi
.
pdev
=
pdev
;
hdmi
.
pdev
=
pdev
;
dev_set_drvdata
(
&
pdev
->
dev
,
&
hdmi
);
mutex_init
(
&
hdmi
.
lock
);
mutex_init
(
&
hdmi
.
lock
);
...
@@ -691,28 +666,23 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
...
@@ -691,28 +666,23 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
if
(
r
)
if
(
r
)
return
r
;
return
r
;
r
=
hdmi_pll_init
(
pdev
,
&
hdmi
.
pll
);
r
=
hdmi_pll_init
(
pdev
,
&
hdmi
.
pll
,
&
hdmi
.
wp
);
if
(
r
)
if
(
r
)
return
r
;
return
r
;
r
=
hdmi_phy_init
(
pdev
,
&
hdmi
.
phy
);
r
=
hdmi_phy_init
(
pdev
,
&
hdmi
.
phy
);
if
(
r
)
if
(
r
)
return
r
;
goto
er
r
;
r
=
hdmi4_core_init
(
pdev
,
&
hdmi
.
core
);
r
=
hdmi4_core_init
(
pdev
,
&
hdmi
.
core
);
if
(
r
)
if
(
r
)
return
r
;
goto
err
;
r
=
hdmi_get_clocks
(
pdev
);
if
(
r
)
{
DSSERR
(
"can't get clocks
\n
"
);
return
r
;
}
irq
=
platform_get_irq
(
pdev
,
0
);
irq
=
platform_get_irq
(
pdev
,
0
);
if
(
irq
<
0
)
{
if
(
irq
<
0
)
{
DSSERR
(
"platform_get_irq failed
\n
"
);
DSSERR
(
"platform_get_irq failed
\n
"
);
return
-
ENODEV
;
r
=
-
ENODEV
;
goto
err
;
}
}
r
=
devm_request_threaded_irq
(
&
pdev
->
dev
,
irq
,
r
=
devm_request_threaded_irq
(
&
pdev
->
dev
,
irq
,
...
@@ -720,22 +690,38 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
...
@@ -720,22 +690,38 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
IRQF_ONESHOT
,
"OMAP HDMI"
,
&
hdmi
.
wp
);
IRQF_ONESHOT
,
"OMAP HDMI"
,
&
hdmi
.
wp
);
if
(
r
)
{
if
(
r
)
{
DSSERR
(
"HDMI IRQ request failed
\n
"
);
DSSERR
(
"HDMI IRQ request failed
\n
"
);
return
r
;
goto
er
r
;
}
}
pm_runtime_enable
(
&
pdev
->
dev
);
pm_runtime_enable
(
&
pdev
->
dev
);
hdmi_init_output
(
pdev
);
hdmi_init_output
(
pdev
);
r
=
hdmi_audio_register
(
&
pdev
->
dev
);
if
(
r
)
{
DSSERR
(
"Registering HDMI audio failed
\n
"
);
hdmi_uninit_output
(
pdev
);
pm_runtime_disable
(
&
pdev
->
dev
);
return
r
;
}
dss_debugfs_create_file
(
"hdmi"
,
hdmi_dump_regs
);
dss_debugfs_create_file
(
"hdmi"
,
hdmi_dump_regs
);
return
0
;
return
0
;
err:
hdmi_pll_uninit
(
&
hdmi
.
pll
);
return
r
;
}
}
static
int
__exit
omapdss_hdmihw_remove
(
struct
platform_device
*
pdev
)
static
int
__exit
omapdss_hdmihw_remove
(
struct
platform_device
*
pdev
)
{
{
if
(
hdmi
.
audio_pdev
)
platform_device_unregister
(
hdmi
.
audio_pdev
);
hdmi_uninit_output
(
pdev
);
hdmi_uninit_output
(
pdev
);
hdmi_pll_uninit
(
&
hdmi
.
pll
);
pm_runtime_disable
(
&
pdev
->
dev
);
pm_runtime_disable
(
&
pdev
->
dev
);
return
0
;
return
0
;
...
@@ -743,8 +729,6 @@ static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
...
@@ -743,8 +729,6 @@ static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
static
int
hdmi_runtime_suspend
(
struct
device
*
dev
)
static
int
hdmi_runtime_suspend
(
struct
device
*
dev
)
{
{
clk_disable_unprepare
(
hdmi
.
sys_clk
);
dispc_runtime_put
();
dispc_runtime_put
();
return
0
;
return
0
;
...
@@ -758,8 +742,6 @@ static int hdmi_runtime_resume(struct device *dev)
...
@@ -758,8 +742,6 @@ static int hdmi_runtime_resume(struct device *dev)
if
(
r
<
0
)
if
(
r
<
0
)
return
r
;
return
r
;
clk_prepare_enable
(
hdmi
.
sys_clk
);
return
0
;
return
0
;
}
}
...
...
drivers/video/fbdev/omap2/dss/hdmi4_core.c
浏览文件 @
3315764e
...
@@ -31,10 +31,8 @@
...
@@ -31,10 +31,8 @@
#include <linux/platform_device.h>
#include <linux/platform_device.h>
#include <linux/string.h>
#include <linux/string.h>
#include <linux/seq_file.h>
#include <linux/seq_file.h>
#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
#include <sound/asound.h>
#include <sound/asound.h>
#include <sound/asoundef.h>
#include <sound/asoundef.h>
#endif
#include "hdmi4_core.h"
#include "hdmi4_core.h"
#include "dss_features.h"
#include "dss_features.h"
...
@@ -530,7 +528,6 @@ void hdmi4_core_dump(struct hdmi_core_data *core, struct seq_file *s)
...
@@ -530,7 +528,6 @@ void hdmi4_core_dump(struct hdmi_core_data *core, struct seq_file *s)
DUMPCOREAV
(
HDMI_CORE_AV_CEC_ADDR_ID
);
DUMPCOREAV
(
HDMI_CORE_AV_CEC_ADDR_ID
);
}
}
#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
static
void
hdmi_core_audio_config
(
struct
hdmi_core_data
*
core
,
static
void
hdmi_core_audio_config
(
struct
hdmi_core_data
*
core
,
struct
hdmi_core_audio_config
*
cfg
)
struct
hdmi_core_audio_config
*
cfg
)
{
{
...
@@ -877,17 +874,6 @@ void hdmi4_audio_stop(struct hdmi_core_data *core, struct hdmi_wp_data *wp)
...
@@ -877,17 +874,6 @@ void hdmi4_audio_stop(struct hdmi_core_data *core, struct hdmi_wp_data *wp)
hdmi_wp_audio_core_req_enable
(
wp
,
false
);
hdmi_wp_audio_core_req_enable
(
wp
,
false
);
}
}
int
hdmi4_audio_get_dma_port
(
u32
*
offset
,
u32
*
size
)
{
if
(
!
offset
||
!
size
)
return
-
EINVAL
;
*
offset
=
HDMI_WP_AUDIO_DATA
;
*
size
=
4
;
return
0
;
}
#endif
int
hdmi4_core_init
(
struct
platform_device
*
pdev
,
struct
hdmi_core_data
*
core
)
int
hdmi4_core_init
(
struct
platform_device
*
pdev
,
struct
hdmi_core_data
*
core
)
{
{
struct
resource
*
res
;
struct
resource
*
res
;
...
...
drivers/video/fbdev/omap2/dss/hdmi4_core.h
浏览文件 @
3315764e
...
@@ -266,12 +266,8 @@ void hdmi4_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
...
@@ -266,12 +266,8 @@ void hdmi4_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
void
hdmi4_core_dump
(
struct
hdmi_core_data
*
core
,
struct
seq_file
*
s
);
void
hdmi4_core_dump
(
struct
hdmi_core_data
*
core
,
struct
seq_file
*
s
);
int
hdmi4_core_init
(
struct
platform_device
*
pdev
,
struct
hdmi_core_data
*
core
);
int
hdmi4_core_init
(
struct
platform_device
*
pdev
,
struct
hdmi_core_data
*
core
);
#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
int
hdmi4_audio_start
(
struct
hdmi_core_data
*
core
,
struct
hdmi_wp_data
*
wp
);
int
hdmi4_audio_start
(
struct
hdmi_core_data
*
core
,
struct
hdmi_wp_data
*
wp
);
void
hdmi4_audio_stop
(
struct
hdmi_core_data
*
core
,
struct
hdmi_wp_data
*
wp
);
void
hdmi4_audio_stop
(
struct
hdmi_core_data
*
core
,
struct
hdmi_wp_data
*
wp
);
int
hdmi4_audio_config
(
struct
hdmi_core_data
*
core
,
struct
hdmi_wp_data
*
wp
,
int
hdmi4_audio_config
(
struct
hdmi_core_data
*
core
,
struct
hdmi_wp_data
*
wp
,
struct
omap_dss_audio
*
audio
,
u32
pclk
);
struct
omap_dss_audio
*
audio
,
u32
pclk
);
int
hdmi4_audio_get_dma_port
(
u32
*
offset
,
u32
*
size
);
#endif
#endif
#endif
drivers/video/fbdev/omap2/dss/hdmi5.c
浏览文件 @
3315764e
...
@@ -38,29 +38,13 @@
...
@@ -38,29 +38,13 @@
#include <linux/gpio.h>
#include <linux/gpio.h>
#include <linux/regulator/consumer.h>
#include <linux/regulator/consumer.h>
#include <video/omapdss.h>
#include <video/omapdss.h>
#include <sound/omap-hdmi-audio.h>
#include "hdmi5_core.h"
#include "hdmi5_core.h"
#include "dss.h"
#include "dss.h"
#include "dss_features.h"
#include "dss_features.h"
static
struct
{
static
struct
omap_hdmi
hdmi
;
struct
mutex
lock
;
struct
platform_device
*
pdev
;
struct
hdmi_wp_data
wp
;
struct
hdmi_pll_data
pll
;
struct
hdmi_phy_data
phy
;
struct
hdmi_core_data
core
;
struct
hdmi_config
cfg
;
struct
clk
*
sys_clk
;
struct
regulator
*
vdda_reg
;
bool
core_enabled
;
struct
omap_dss_device
output
;
}
hdmi
;
static
int
hdmi_runtime_get
(
void
)
static
int
hdmi_runtime_get
(
void
)
{
{
...
@@ -198,7 +182,7 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
...
@@ -198,7 +182,7 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
int
r
;
int
r
;
struct
omap_video_timings
*
p
;
struct
omap_video_timings
*
p
;
struct
omap_overlay_manager
*
mgr
=
hdmi
.
output
.
manager
;
struct
omap_overlay_manager
*
mgr
=
hdmi
.
output
.
manager
;
unsigned
long
phy
;
struct
dss_pll_clock_info
hdmi_cinfo
=
{
0
}
;
r
=
hdmi_power_on_core
(
dssdev
);
r
=
hdmi_power_on_core
(
dssdev
);
if
(
r
)
if
(
r
)
...
@@ -208,24 +192,27 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
...
@@ -208,24 +192,27 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
DSSDBG
(
"hdmi_power_on x_res= %d y_res = %d
\n
"
,
p
->
x_res
,
p
->
y_res
);
DSSDBG
(
"hdmi_power_on x_res= %d y_res = %d
\n
"
,
p
->
x_res
,
p
->
y_res
);
/* the functions below use kHz pixel clock. TODO: change to Hz */
hdmi_pll_compute
(
&
hdmi
.
pll
,
p
->
pixelclock
,
&
hdmi_cinfo
);
phy
=
p
->
pixelclock
/
1000
;
hdmi_pll_compute
(
&
hdmi
.
pll
,
clk_get_rate
(
hdmi
.
sys_clk
),
phy
);
/* disable and clear irqs */
/* disable and clear irqs */
hdmi_wp_clear_irqenable
(
&
hdmi
.
wp
,
0xffffffff
);
hdmi_wp_clear_irqenable
(
&
hdmi
.
wp
,
0xffffffff
);
hdmi_wp_set_irqstatus
(
&
hdmi
.
wp
,
hdmi_wp_set_irqstatus
(
&
hdmi
.
wp
,
hdmi_wp_get_irqstatus
(
&
hdmi
.
wp
));
hdmi_wp_get_irqstatus
(
&
hdmi
.
wp
));
/* config the PLL and PHY hdmi_set_pll_pwrfirst */
r
=
dss_pll_enable
(
&
hdmi
.
pll
.
pll
);
r
=
hdmi_pll_enable
(
&
hdmi
.
pll
,
&
hdmi
.
wp
);
if
(
r
)
{
if
(
r
)
{
DSS
DBG
(
"Failed to lock
PLL
\n
"
);
DSS
ERR
(
"Failed to enable
PLL
\n
"
);
goto
err_pll_enable
;
goto
err_pll_enable
;
}
}
r
=
hdmi_phy_configure
(
&
hdmi
.
phy
,
&
hdmi
.
cfg
);
r
=
dss_pll_set_config
(
&
hdmi
.
pll
.
pll
,
&
hdmi_cinfo
);
if
(
r
)
{
DSSERR
(
"Failed to configure PLL
\n
"
);
goto
err_pll_cfg
;
}
r
=
hdmi_phy_configure
(
&
hdmi
.
phy
,
hdmi_cinfo
.
clkdco
,
hdmi_cinfo
.
clkout
[
0
]);
if
(
r
)
{
if
(
r
)
{
DSSDBG
(
"Failed to start PHY
\n
"
);
DSSDBG
(
"Failed to start PHY
\n
"
);
goto
err_phy_cfg
;
goto
err_phy_cfg
;
...
@@ -262,7 +249,8 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
...
@@ -262,7 +249,8 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
hdmi_wp_set_phy_pwr
(
&
hdmi
.
wp
,
HDMI_PHYPWRCMD_OFF
);
hdmi_wp_set_phy_pwr
(
&
hdmi
.
wp
,
HDMI_PHYPWRCMD_OFF
);
err_phy_pwr:
err_phy_pwr:
err_phy_cfg:
err_phy_cfg:
hdmi_pll_disable
(
&
hdmi
.
pll
,
&
hdmi
.
wp
);
err_pll_cfg:
dss_pll_disable
(
&
hdmi
.
pll
.
pll
);
err_pll_enable:
err_pll_enable:
hdmi_power_off_core
(
dssdev
);
hdmi_power_off_core
(
dssdev
);
return
-
EIO
;
return
-
EIO
;
...
@@ -280,7 +268,7 @@ static void hdmi_power_off_full(struct omap_dss_device *dssdev)
...
@@ -280,7 +268,7 @@ static void hdmi_power_off_full(struct omap_dss_device *dssdev)
hdmi_wp_set_phy_pwr
(
&
hdmi
.
wp
,
HDMI_PHYPWRCMD_OFF
);
hdmi_wp_set_phy_pwr
(
&
hdmi
.
wp
,
HDMI_PHYPWRCMD_OFF
);
hdmi_pll_disable
(
&
hdmi
.
pll
,
&
hdmi
.
wp
);
dss_pll_disable
(
&
hdmi
.
pll
.
pll
);
hdmi_power_off_core
(
dssdev
);
hdmi_power_off_core
(
dssdev
);
}
}
...
@@ -290,6 +278,10 @@ static int hdmi_display_check_timing(struct omap_dss_device *dssdev,
...
@@ -290,6 +278,10 @@ static int hdmi_display_check_timing(struct omap_dss_device *dssdev,
{
{
struct
omap_dss_device
*
out
=
&
hdmi
.
output
;
struct
omap_dss_device
*
out
=
&
hdmi
.
output
;
/* TODO: proper interlace support */
if
(
timings
->
interlace
)
return
-
EINVAL
;
if
(
!
dispc_mgr_timings_ok
(
out
->
dispc_channel
,
timings
))
if
(
!
dispc_mgr_timings_ok
(
out
->
dispc_channel
,
timings
))
return
-
EINVAL
;
return
-
EINVAL
;
...
@@ -377,6 +369,8 @@ static int hdmi_display_enable(struct omap_dss_device *dssdev)
...
@@ -377,6 +369,8 @@ static int hdmi_display_enable(struct omap_dss_device *dssdev)
goto
err0
;
goto
err0
;
}
}
hdmi
.
display_enabled
=
true
;
mutex_unlock
(
&
hdmi
.
lock
);
mutex_unlock
(
&
hdmi
.
lock
);
return
0
;
return
0
;
...
@@ -391,8 +385,13 @@ static void hdmi_display_disable(struct omap_dss_device *dssdev)
...
@@ -391,8 +385,13 @@ static void hdmi_display_disable(struct omap_dss_device *dssdev)
mutex_lock
(
&
hdmi
.
lock
);
mutex_lock
(
&
hdmi
.
lock
);
if
(
hdmi
.
audio_pdev
&&
hdmi
.
audio_abort_cb
)
hdmi
.
audio_abort_cb
(
&
hdmi
.
audio_pdev
->
dev
);
hdmi_power_off_full
(
dssdev
);
hdmi_power_off_full
(
dssdev
);
hdmi
.
display_enabled
=
false
;
mutex_unlock
(
&
hdmi
.
lock
);
mutex_unlock
(
&
hdmi
.
lock
);
}
}
...
@@ -429,21 +428,6 @@ static void hdmi_core_disable(struct omap_dss_device *dssdev)
...
@@ -429,21 +428,6 @@ static void hdmi_core_disable(struct omap_dss_device *dssdev)
mutex_unlock
(
&
hdmi
.
lock
);
mutex_unlock
(
&
hdmi
.
lock
);
}
}
static
int
hdmi_get_clocks
(
struct
platform_device
*
pdev
)
{
struct
clk
*
clk
;
clk
=
devm_clk_get
(
&
pdev
->
dev
,
"sys_clk"
);
if
(
IS_ERR
(
clk
))
{
DSSERR
(
"can't get sys_clk
\n
"
);
return
PTR_ERR
(
clk
);
}
hdmi
.
sys_clk
=
clk
;
return
0
;
}
static
int
hdmi_connect
(
struct
omap_dss_device
*
dssdev
,
static
int
hdmi_connect
(
struct
omap_dss_device
*
dssdev
,
struct
omap_dss_device
*
dst
)
struct
omap_dss_device
*
dst
)
{
{
...
@@ -509,112 +493,6 @@ static int hdmi_read_edid(struct omap_dss_device *dssdev,
...
@@ -509,112 +493,6 @@ static int hdmi_read_edid(struct omap_dss_device *dssdev,
return
r
;
return
r
;
}
}
#if defined(CONFIG_OMAP5_DSS_HDMI_AUDIO)
static
int
hdmi_audio_enable
(
struct
omap_dss_device
*
dssdev
)
{
int
r
;
mutex_lock
(
&
hdmi
.
lock
);
if
(
!
hdmi_mode_has_audio
(
hdmi
.
cfg
.
hdmi_dvi_mode
))
{
r
=
-
EPERM
;
goto
err
;
}
r
=
hdmi_wp_audio_enable
(
&
hdmi
.
wp
,
true
);
if
(
r
)
goto
err
;
mutex_unlock
(
&
hdmi
.
lock
);
return
0
;
err:
mutex_unlock
(
&
hdmi
.
lock
);
return
r
;
}
static
void
hdmi_audio_disable
(
struct
omap_dss_device
*
dssdev
)
{
hdmi_wp_audio_enable
(
&
hdmi
.
wp
,
false
);
}
static
int
hdmi_audio_start
(
struct
omap_dss_device
*
dssdev
)
{
return
hdmi_wp_audio_core_req_enable
(
&
hdmi
.
wp
,
true
);
}
static
void
hdmi_audio_stop
(
struct
omap_dss_device
*
dssdev
)
{
hdmi_wp_audio_core_req_enable
(
&
hdmi
.
wp
,
false
);
}
static
bool
hdmi_audio_supported
(
struct
omap_dss_device
*
dssdev
)
{
bool
r
;
mutex_lock
(
&
hdmi
.
lock
);
r
=
hdmi_mode_has_audio
(
hdmi
.
cfg
.
hdmi_dvi_mode
);
mutex_unlock
(
&
hdmi
.
lock
);
return
r
;
}
static
int
hdmi_audio_config
(
struct
omap_dss_device
*
dssdev
,
struct
omap_dss_audio
*
audio
)
{
int
r
;
u32
pclk
=
hdmi
.
cfg
.
timings
.
pixelclock
;
mutex_lock
(
&
hdmi
.
lock
);
if
(
!
hdmi_mode_has_audio
(
hdmi
.
cfg
.
hdmi_dvi_mode
))
{
r
=
-
EPERM
;
goto
err
;
}
r
=
hdmi5_audio_config
(
&
hdmi
.
core
,
&
hdmi
.
wp
,
audio
,
pclk
);
if
(
r
)
goto
err
;
mutex_unlock
(
&
hdmi
.
lock
);
return
0
;
err:
mutex_unlock
(
&
hdmi
.
lock
);
return
r
;
}
#else
static
int
hdmi_audio_enable
(
struct
omap_dss_device
*
dssdev
)
{
return
-
EPERM
;
}
static
void
hdmi_audio_disable
(
struct
omap_dss_device
*
dssdev
)
{
}
static
int
hdmi_audio_start
(
struct
omap_dss_device
*
dssdev
)
{
return
-
EPERM
;
}
static
void
hdmi_audio_stop
(
struct
omap_dss_device
*
dssdev
)
{
}
static
bool
hdmi_audio_supported
(
struct
omap_dss_device
*
dssdev
)
{
return
false
;
}
static
int
hdmi_audio_config
(
struct
omap_dss_device
*
dssdev
,
struct
omap_dss_audio
*
audio
)
{
return
-
EPERM
;
}
#endif
static
int
hdmi_set_infoframe
(
struct
omap_dss_device
*
dssdev
,
static
int
hdmi_set_infoframe
(
struct
omap_dss_device
*
dssdev
,
const
struct
hdmi_avi_infoframe
*
avi
)
const
struct
hdmi_avi_infoframe
*
avi
)
{
{
...
@@ -643,13 +521,6 @@ static const struct omapdss_hdmi_ops hdmi_ops = {
...
@@ -643,13 +521,6 @@ static const struct omapdss_hdmi_ops hdmi_ops = {
.
read_edid
=
hdmi_read_edid
,
.
read_edid
=
hdmi_read_edid
,
.
set_infoframe
=
hdmi_set_infoframe
,
.
set_infoframe
=
hdmi_set_infoframe
,
.
set_hdmi_mode
=
hdmi_set_hdmi_mode
,
.
set_hdmi_mode
=
hdmi_set_hdmi_mode
,
.
audio_enable
=
hdmi_audio_enable
,
.
audio_disable
=
hdmi_audio_disable
,
.
audio_start
=
hdmi_audio_start
,
.
audio_stop
=
hdmi_audio_stop
,
.
audio_supported
=
hdmi_audio_supported
,
.
audio_config
=
hdmi_audio_config
,
};
};
static
void
hdmi_init_output
(
struct
platform_device
*
pdev
)
static
void
hdmi_init_output
(
struct
platform_device
*
pdev
)
...
@@ -667,7 +538,7 @@ static void hdmi_init_output(struct platform_device *pdev)
...
@@ -667,7 +538,7 @@ static void hdmi_init_output(struct platform_device *pdev)
omapdss_register_output
(
out
);
omapdss_register_output
(
out
);
}
}
static
void
__exit
hdmi_uninit_output
(
struct
platform_device
*
pdev
)
static
void
hdmi_uninit_output
(
struct
platform_device
*
pdev
)
{
{
struct
omap_dss_device
*
out
=
&
hdmi
.
output
;
struct
omap_dss_device
*
out
=
&
hdmi
.
output
;
...
@@ -696,6 +567,119 @@ static int hdmi_probe_of(struct platform_device *pdev)
...
@@ -696,6 +567,119 @@ static int hdmi_probe_of(struct platform_device *pdev)
return
r
;
return
r
;
}
}
/* Audio callbacks */
static
int
hdmi_audio_startup
(
struct
device
*
dev
,
void
(
*
abort_cb
)(
struct
device
*
dev
))
{
struct
omap_hdmi
*
hd
=
dev_get_drvdata
(
dev
);
int
ret
=
0
;
mutex_lock
(
&
hd
->
lock
);
if
(
!
hdmi_mode_has_audio
(
&
hd
->
cfg
)
||
!
hd
->
display_enabled
)
{
ret
=
-
EPERM
;
goto
out
;
}
hd
->
audio_abort_cb
=
abort_cb
;
out:
mutex_unlock
(
&
hd
->
lock
);
return
ret
;
}
static
int
hdmi_audio_shutdown
(
struct
device
*
dev
)
{
struct
omap_hdmi
*
hd
=
dev_get_drvdata
(
dev
);
mutex_lock
(
&
hd
->
lock
);
hd
->
audio_abort_cb
=
NULL
;
mutex_unlock
(
&
hd
->
lock
);
return
0
;
}
static
int
hdmi_audio_start
(
struct
device
*
dev
)
{
struct
omap_hdmi
*
hd
=
dev_get_drvdata
(
dev
);
WARN_ON
(
!
hdmi_mode_has_audio
(
&
hd
->
cfg
));
WARN_ON
(
!
hd
->
display_enabled
);
/* No-idle while playing audio, store the old value */
hd
->
wp_idlemode
=
REG_GET
(
hdmi
.
wp
.
base
,
HDMI_WP_SYSCONFIG
,
3
,
2
);
REG_FLD_MOD
(
hdmi
.
wp
.
base
,
HDMI_WP_SYSCONFIG
,
1
,
3
,
2
);
hdmi_wp_audio_enable
(
&
hd
->
wp
,
true
);
hdmi_wp_audio_core_req_enable
(
&
hd
->
wp
,
true
);
return
0
;
}
static
void
hdmi_audio_stop
(
struct
device
*
dev
)
{
struct
omap_hdmi
*
hd
=
dev_get_drvdata
(
dev
);
WARN_ON
(
!
hdmi_mode_has_audio
(
&
hd
->
cfg
));
WARN_ON
(
!
hd
->
display_enabled
);
hdmi_wp_audio_core_req_enable
(
&
hd
->
wp
,
false
);
hdmi_wp_audio_enable
(
&
hd
->
wp
,
false
);
/* Playback stopped, restore original idlemode */
REG_FLD_MOD
(
hdmi
.
wp
.
base
,
HDMI_WP_SYSCONFIG
,
hd
->
wp_idlemode
,
3
,
2
);
}
static
int
hdmi_audio_config
(
struct
device
*
dev
,
struct
omap_dss_audio
*
dss_audio
)
{
struct
omap_hdmi
*
hd
=
dev_get_drvdata
(
dev
);
int
ret
;
mutex_lock
(
&
hd
->
lock
);
if
(
!
hdmi_mode_has_audio
(
&
hd
->
cfg
)
||
!
hd
->
display_enabled
)
{
ret
=
-
EPERM
;
goto
out
;
}
ret
=
hdmi5_audio_config
(
&
hd
->
core
,
&
hd
->
wp
,
dss_audio
,
hd
->
cfg
.
timings
.
pixelclock
);
out:
mutex_unlock
(
&
hd
->
lock
);
return
ret
;
}
static
const
struct
omap_hdmi_audio_ops
hdmi_audio_ops
=
{
.
audio_startup
=
hdmi_audio_startup
,
.
audio_shutdown
=
hdmi_audio_shutdown
,
.
audio_start
=
hdmi_audio_start
,
.
audio_stop
=
hdmi_audio_stop
,
.
audio_config
=
hdmi_audio_config
,
};
static
int
hdmi_audio_register
(
struct
device
*
dev
)
{
struct
omap_hdmi_audio_pdata
pdata
=
{
.
dev
=
dev
,
.
dss_version
=
omapdss_get_version
(),
.
audio_dma_addr
=
hdmi_wp_get_audio_dma_addr
(
&
hdmi
.
wp
),
.
ops
=
&
hdmi_audio_ops
,
};
hdmi
.
audio_pdev
=
platform_device_register_data
(
dev
,
"omap-hdmi-audio"
,
PLATFORM_DEVID_AUTO
,
&
pdata
,
sizeof
(
pdata
));
if
(
IS_ERR
(
hdmi
.
audio_pdev
))
return
PTR_ERR
(
hdmi
.
audio_pdev
);
return
0
;
}
/* HDMI HW IP initialisation */
/* HDMI HW IP initialisation */
static
int
omapdss_hdmihw_probe
(
struct
platform_device
*
pdev
)
static
int
omapdss_hdmihw_probe
(
struct
platform_device
*
pdev
)
{
{
...
@@ -703,6 +687,7 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
...
@@ -703,6 +687,7 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
int
irq
;
int
irq
;
hdmi
.
pdev
=
pdev
;
hdmi
.
pdev
=
pdev
;
dev_set_drvdata
(
&
pdev
->
dev
,
&
hdmi
);
mutex_init
(
&
hdmi
.
lock
);
mutex_init
(
&
hdmi
.
lock
);
...
@@ -716,28 +701,23 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
...
@@ -716,28 +701,23 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
if
(
r
)
if
(
r
)
return
r
;
return
r
;
r
=
hdmi_pll_init
(
pdev
,
&
hdmi
.
pll
);
r
=
hdmi_pll_init
(
pdev
,
&
hdmi
.
pll
,
&
hdmi
.
wp
);
if
(
r
)
if
(
r
)
return
r
;
return
r
;
r
=
hdmi_phy_init
(
pdev
,
&
hdmi
.
phy
);
r
=
hdmi_phy_init
(
pdev
,
&
hdmi
.
phy
);
if
(
r
)
if
(
r
)
return
r
;
goto
er
r
;
r
=
hdmi5_core_init
(
pdev
,
&
hdmi
.
core
);
r
=
hdmi5_core_init
(
pdev
,
&
hdmi
.
core
);
if
(
r
)
if
(
r
)
return
r
;
goto
err
;
r
=
hdmi_get_clocks
(
pdev
);
if
(
r
)
{
DSSERR
(
"can't get clocks
\n
"
);
return
r
;
}
irq
=
platform_get_irq
(
pdev
,
0
);
irq
=
platform_get_irq
(
pdev
,
0
);
if
(
irq
<
0
)
{
if
(
irq
<
0
)
{
DSSERR
(
"platform_get_irq failed
\n
"
);
DSSERR
(
"platform_get_irq failed
\n
"
);
return
-
ENODEV
;
r
=
-
ENODEV
;
goto
err
;
}
}
r
=
devm_request_threaded_irq
(
&
pdev
->
dev
,
irq
,
r
=
devm_request_threaded_irq
(
&
pdev
->
dev
,
irq
,
...
@@ -745,22 +725,38 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
...
@@ -745,22 +725,38 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
IRQF_ONESHOT
,
"OMAP HDMI"
,
&
hdmi
.
wp
);
IRQF_ONESHOT
,
"OMAP HDMI"
,
&
hdmi
.
wp
);
if
(
r
)
{
if
(
r
)
{
DSSERR
(
"HDMI IRQ request failed
\n
"
);
DSSERR
(
"HDMI IRQ request failed
\n
"
);
return
r
;
goto
er
r
;
}
}
pm_runtime_enable
(
&
pdev
->
dev
);
pm_runtime_enable
(
&
pdev
->
dev
);
hdmi_init_output
(
pdev
);
hdmi_init_output
(
pdev
);
r
=
hdmi_audio_register
(
&
pdev
->
dev
);
if
(
r
)
{
DSSERR
(
"Registering HDMI audio failed %d
\n
"
,
r
);
hdmi_uninit_output
(
pdev
);
pm_runtime_disable
(
&
pdev
->
dev
);
return
r
;
}
dss_debugfs_create_file
(
"hdmi"
,
hdmi_dump_regs
);
dss_debugfs_create_file
(
"hdmi"
,
hdmi_dump_regs
);
return
0
;
return
0
;
err:
hdmi_pll_uninit
(
&
hdmi
.
pll
);
return
r
;
}
}
static
int
__exit
omapdss_hdmihw_remove
(
struct
platform_device
*
pdev
)
static
int
__exit
omapdss_hdmihw_remove
(
struct
platform_device
*
pdev
)
{
{
if
(
hdmi
.
audio_pdev
)
platform_device_unregister
(
hdmi
.
audio_pdev
);
hdmi_uninit_output
(
pdev
);
hdmi_uninit_output
(
pdev
);
hdmi_pll_uninit
(
&
hdmi
.
pll
);
pm_runtime_disable
(
&
pdev
->
dev
);
pm_runtime_disable
(
&
pdev
->
dev
);
return
0
;
return
0
;
...
@@ -768,8 +764,6 @@ static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
...
@@ -768,8 +764,6 @@ static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
static
int
hdmi_runtime_suspend
(
struct
device
*
dev
)
static
int
hdmi_runtime_suspend
(
struct
device
*
dev
)
{
{
clk_disable_unprepare
(
hdmi
.
sys_clk
);
dispc_runtime_put
();
dispc_runtime_put
();
return
0
;
return
0
;
...
@@ -783,8 +777,6 @@ static int hdmi_runtime_resume(struct device *dev)
...
@@ -783,8 +777,6 @@ static int hdmi_runtime_resume(struct device *dev)
if
(
r
<
0
)
if
(
r
<
0
)
return
r
;
return
r
;
clk_prepare_enable
(
hdmi
.
sys_clk
);
return
0
;
return
0
;
}
}
...
...
drivers/video/fbdev/omap2/dss/hdmi5_core.c
浏览文件 @
3315764e
...
@@ -30,10 +30,8 @@
...
@@ -30,10 +30,8 @@
#include <linux/string.h>
#include <linux/string.h>
#include <linux/seq_file.h>
#include <linux/seq_file.h>
#include <drm/drm_edid.h>
#include <drm/drm_edid.h>
#if defined(CONFIG_OMAP5_DSS_HDMI_AUDIO)
#include <sound/asound.h>
#include <sound/asound.h>
#include <sound/asoundef.h>
#include <sound/asoundef.h>
#endif
#include "hdmi5_core.h"
#include "hdmi5_core.h"
...
@@ -644,9 +642,6 @@ void hdmi5_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
...
@@ -644,9 +642,6 @@ void hdmi5_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
hdmi_core_enable_interrupts
(
core
);
hdmi_core_enable_interrupts
(
core
);
}
}
#if defined(CONFIG_OMAP5_DSS_HDMI_AUDIO)
static
void
hdmi5_core_audio_config
(
struct
hdmi_core_data
*
core
,
static
void
hdmi5_core_audio_config
(
struct
hdmi_core_data
*
core
,
struct
hdmi_core_audio_config
*
cfg
)
struct
hdmi_core_audio_config
*
cfg
)
{
{
...
@@ -721,7 +716,7 @@ static void hdmi5_core_audio_config(struct hdmi_core_data *core,
...
@@ -721,7 +716,7 @@ static void hdmi5_core_audio_config(struct hdmi_core_data *core,
/* Source number */
/* Source number */
val
=
cfg
->
iec60958_cfg
->
status
[
2
]
&
IEC958_AES2_CON_SOURCE
;
val
=
cfg
->
iec60958_cfg
->
status
[
2
]
&
IEC958_AES2_CON_SOURCE
;
REG_FLD_MOD
(
base
,
HDMI_CORE_FC_AUDSCHNLS
(
2
),
val
,
3
,
4
);
REG_FLD_MOD
(
base
,
HDMI_CORE_FC_AUDSCHNLS
(
2
),
val
,
3
,
0
);
/* Channel number right 0 */
/* Channel number right 0 */
REG_FLD_MOD
(
base
,
HDMI_CORE_FC_AUDSCHNLS
(
3
),
2
,
3
,
0
);
REG_FLD_MOD
(
base
,
HDMI_CORE_FC_AUDSCHNLS
(
3
),
2
,
3
,
0
);
...
@@ -879,6 +874,9 @@ int hdmi5_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
...
@@ -879,6 +874,9 @@ int hdmi5_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
/* only LPCM atm */
/* only LPCM atm */
audio_format
.
type
=
HDMI_AUDIO_TYPE_LPCM
;
audio_format
.
type
=
HDMI_AUDIO_TYPE_LPCM
;
/* only allowed option */
audio_format
.
sample_order
=
HDMI_AUDIO_SAMPLE_LEFT_FIRST
;
/* disable start/stop signals of IEC 60958 blocks */
/* disable start/stop signals of IEC 60958 blocks */
audio_format
.
en_sig_blk_strt_end
=
HDMI_AUDIO_BLOCK_SIG_STARTEND_ON
;
audio_format
.
en_sig_blk_strt_end
=
HDMI_AUDIO_BLOCK_SIG_STARTEND_ON
;
...
@@ -894,7 +892,6 @@ int hdmi5_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
...
@@ -894,7 +892,6 @@ int hdmi5_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
return
0
;
return
0
;
}
}
#endif
int
hdmi5_core_init
(
struct
platform_device
*
pdev
,
struct
hdmi_core_data
*
core
)
int
hdmi5_core_init
(
struct
platform_device
*
pdev
,
struct
hdmi_core_data
*
core
)
{
{
...
...
drivers/video/fbdev/omap2/dss/hdmi5_core.h
浏览文件 @
3315764e
...
@@ -299,8 +299,6 @@ void hdmi5_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
...
@@ -299,8 +299,6 @@ void hdmi5_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
struct
hdmi_config
*
cfg
);
struct
hdmi_config
*
cfg
);
int
hdmi5_core_init
(
struct
platform_device
*
pdev
,
struct
hdmi_core_data
*
core
);
int
hdmi5_core_init
(
struct
platform_device
*
pdev
,
struct
hdmi_core_data
*
core
);
#if defined(CONFIG_OMAP5_DSS_HDMI_AUDIO)
int
hdmi5_audio_config
(
struct
hdmi_core_data
*
core
,
struct
hdmi_wp_data
*
wp
,
int
hdmi5_audio_config
(
struct
hdmi_core_data
*
core
,
struct
hdmi_wp_data
*
wp
,
struct
omap_dss_audio
*
audio
,
u32
pclk
);
struct
omap_dss_audio
*
audio
,
u32
pclk
);
#endif
#endif
#endif
drivers/video/fbdev/omap2/dss/hdmi_common.c
浏览文件 @
3315764e
...
@@ -48,7 +48,6 @@ int hdmi_parse_lanes_of(struct platform_device *pdev, struct device_node *ep,
...
@@ -48,7 +48,6 @@ int hdmi_parse_lanes_of(struct platform_device *pdev, struct device_node *ep,
return
0
;
return
0
;
}
}
#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
int
hdmi_compute_acr
(
u32
pclk
,
u32
sample_freq
,
u32
*
n
,
u32
*
cts
)
int
hdmi_compute_acr
(
u32
pclk
,
u32
sample_freq
,
u32
*
n
,
u32
*
cts
)
{
{
u32
deep_color
;
u32
deep_color
;
...
@@ -147,4 +146,3 @@ int hdmi_compute_acr(u32 pclk, u32 sample_freq, u32 *n, u32 *cts)
...
@@ -147,4 +146,3 @@ int hdmi_compute_acr(u32 pclk, u32 sample_freq, u32 *n, u32 *cts)
return
0
;
return
0
;
}
}
#endif
drivers/video/fbdev/omap2/dss/hdmi_phy.c
浏览文件 @
3315764e
...
@@ -20,9 +20,7 @@
...
@@ -20,9 +20,7 @@
struct
hdmi_phy_features
{
struct
hdmi_phy_features
{
bool
bist_ctrl
;
bool
bist_ctrl
;
bool
calc_freqout
;
bool
ldo_voltage
;
bool
ldo_voltage
;
unsigned
long
dcofreq_min
;
unsigned
long
max_phy
;
unsigned
long
max_phy
;
};
};
...
@@ -132,7 +130,8 @@ static void hdmi_phy_configure_lanes(struct hdmi_phy_data *phy)
...
@@ -132,7 +130,8 @@ static void hdmi_phy_configure_lanes(struct hdmi_phy_data *phy)
REG_FLD_MOD
(
phy
->
base
,
HDMI_TXPHY_PAD_CFG_CTRL
,
pol_val
,
30
,
27
);
REG_FLD_MOD
(
phy
->
base
,
HDMI_TXPHY_PAD_CFG_CTRL
,
pol_val
,
30
,
27
);
}
}
int
hdmi_phy_configure
(
struct
hdmi_phy_data
*
phy
,
struct
hdmi_config
*
cfg
)
int
hdmi_phy_configure
(
struct
hdmi_phy_data
*
phy
,
unsigned
long
hfbitclk
,
unsigned
long
lfbitclk
)
{
{
u8
freqout
;
u8
freqout
;
...
@@ -149,20 +148,16 @@ int hdmi_phy_configure(struct hdmi_phy_data *phy, struct hdmi_config *cfg)
...
@@ -149,20 +148,16 @@ int hdmi_phy_configure(struct hdmi_phy_data *phy, struct hdmi_config *cfg)
if
(
phy_feat
->
bist_ctrl
)
if
(
phy_feat
->
bist_ctrl
)
REG_FLD_MOD
(
phy
->
base
,
HDMI_TXPHY_BIST_CONTROL
,
1
,
11
,
11
);
REG_FLD_MOD
(
phy
->
base
,
HDMI_TXPHY_BIST_CONTROL
,
1
,
11
,
11
);
if
(
phy_feat
->
calc_freqout
)
{
/*
/* DCOCLK/10 is pixel clock, compare pclk with DCOCLK_MIN/10 */
* If the hfbitclk != lfbitclk, it means the lfbitclk was configured
u32
dco_min
=
phy_feat
->
dcofreq_min
/
10
;
* to be used for TMDS.
u32
pclk
=
cfg
->
timings
.
pixelclock
;
*/
if
(
hfbitclk
!=
lfbitclk
)
if
(
pclk
<
dco_min
)
freqout
=
0
;
freqout
=
0
;
else
if
(
hfbitclk
/
10
<
phy_feat
->
max_phy
)
else
if
((
pclk
>=
dco_min
)
&&
(
pclk
<
phy_feat
->
max_phy
))
freqout
=
1
;
else
freqout
=
2
;
}
else
{
freqout
=
1
;
freqout
=
1
;
}
else
freqout
=
2
;
/*
/*
* Write to phy address 0 to configure the clock
* Write to phy address 0 to configure the clock
...
@@ -184,17 +179,13 @@ int hdmi_phy_configure(struct hdmi_phy_data *phy, struct hdmi_config *cfg)
...
@@ -184,17 +179,13 @@ int hdmi_phy_configure(struct hdmi_phy_data *phy, struct hdmi_config *cfg)
static
const
struct
hdmi_phy_features
omap44xx_phy_feats
=
{
static
const
struct
hdmi_phy_features
omap44xx_phy_feats
=
{
.
bist_ctrl
=
false
,
.
bist_ctrl
=
false
,
.
calc_freqout
=
false
,
.
ldo_voltage
=
true
,
.
ldo_voltage
=
true
,
.
dcofreq_min
=
500000000
,
.
max_phy
=
185675000
,
.
max_phy
=
185675000
,
};
};
static
const
struct
hdmi_phy_features
omap54xx_phy_feats
=
{
static
const
struct
hdmi_phy_features
omap54xx_phy_feats
=
{
.
bist_ctrl
=
true
,
.
bist_ctrl
=
true
,
.
calc_freqout
=
true
,
.
ldo_voltage
=
false
,
.
ldo_voltage
=
false
,
.
dcofreq_min
=
750000000
,
.
max_phy
=
186000000
,
.
max_phy
=
186000000
,
};
};
...
...
drivers/video/fbdev/omap2/dss/hdmi_pll.c
浏览文件 @
3315764e
...
@@ -15,26 +15,13 @@
...
@@ -15,26 +15,13 @@
#include <linux/err.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <video/omapdss.h>
#include <video/omapdss.h>
#include "dss.h"
#include "dss.h"
#include "hdmi.h"
#include "hdmi.h"
#define HDMI_DEFAULT_REGN 16
#define HDMI_DEFAULT_REGM2 1
struct
hdmi_pll_features
{
bool
sys_reset
;
/* this is a hack, need to replace it with a better computation of M2 */
bool
bound_dcofreq
;
unsigned
long
fint_min
,
fint_max
;
u16
regm_max
;
unsigned
long
dcofreq_low_min
,
dcofreq_low_max
;
unsigned
long
dcofreq_high_min
,
dcofreq_high_max
;
};
static
const
struct
hdmi_pll_features
*
pll_feat
;
void
hdmi_pll_dump
(
struct
hdmi_pll_data
*
pll
,
struct
seq_file
*
s
)
void
hdmi_pll_dump
(
struct
hdmi_pll_data
*
pll
,
struct
seq_file
*
s
)
{
{
#define DUMPPLL(r) seq_printf(s, "%-35s %08x\n", #r,\
#define DUMPPLL(r) seq_printf(s, "%-35s %08x\n", #r,\
...
@@ -51,228 +38,189 @@ void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s)
...
@@ -51,228 +38,189 @@ void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s)
DUMPPLL
(
PLLCTRL_CFG4
);
DUMPPLL
(
PLLCTRL_CFG4
);
}
}
void
hdmi_pll_compute
(
struct
hdmi_pll_data
*
pll
,
unsigned
long
clkin
,
int
phy
)
void
hdmi_pll_compute
(
struct
hdmi_pll_data
*
pll
,
unsigned
long
target_tmds
,
struct
dss_pll_clock_info
*
pi
)
{
{
struct
hdmi_pll_info
*
pi
=
&
pll
->
info
;
unsigned
long
fint
,
clkdco
,
clkout
;
unsigned
long
refclk
;
unsigned
long
target_bitclk
,
target_clkdco
;
u32
mf
;
unsigned
long
min_dco
;
unsigned
n
,
m
,
mf
,
m2
,
sd
;
unsigned
long
clkin
;
const
struct
dss_pll_hw
*
hw
=
pll
->
pll
.
hw
;
/* use our funky units */
clkin
=
clk_get_rate
(
pll
->
pll
.
clkin
);
clkin
/=
10000
;
/*
DSSDBG
(
"clkin %lu, target tmds %lu
\n
"
,
clkin
,
target_tmds
);
* Input clock is predivided by N + 1
* out put of which is reference clk
*/
pi
->
regn
=
HDMI_DEFAULT_REGN
;
target_bitclk
=
target_tmds
*
10
;
refclk
=
clkin
/
pi
->
regn
;
/* Fint */
n
=
DIV_ROUND_UP
(
clkin
,
hw
->
fint_max
);
fint
=
clkin
/
n
;
/* temorary hack to make sure DCO freq isn't calculated too low */
/* adjust m2 so that the clkdco will be high enough */
if
(
pll_feat
->
bound_dcofreq
&&
phy
<=
65000
)
min_dco
=
roundup
(
hw
->
clkdco_min
,
fint
);
pi
->
regm2
=
3
;
m2
=
DIV_ROUND_UP
(
min_dco
,
target_bitclk
);
else
if
(
m2
==
0
)
pi
->
regm2
=
HDMI_DEFAULT_REGM2
;
m2
=
1
;
/*
* multiplier is pixel_clk/ref_clk
* Multiplying by 100 to avoid fractional part removal
*/
pi
->
regm
=
phy
*
pi
->
regm2
/
refclk
;
/*
* fractional multiplier is remainder of the difference between
* multiplier and actual phy(required pixel clock thus should be
* multiplied by 2^18(262144) divided by the reference clock
*/
mf
=
(
phy
-
pi
->
regm
/
pi
->
regm2
*
refclk
)
*
262144
;
pi
->
regmf
=
pi
->
regm2
*
mf
/
refclk
;
/*
* Dcofreq should be set to 1 if required pixel clock
* is greater than 1000MHz
*/
pi
->
dcofreq
=
phy
>
1000
*
100
;
pi
->
regsd
=
((
pi
->
regm
*
clkin
/
10
)
/
(
pi
->
regn
*
250
)
+
5
)
/
10
;
/* Set the reference clock to sysclk reference */
pi
->
refsel
=
HDMI_REFSEL_SYSCLK
;
DSSDBG
(
"M = %d Mf = %d
\n
"
,
pi
->
regm
,
pi
->
regmf
);
DSSDBG
(
"range = %d sd = %d
\n
"
,
pi
->
dcofreq
,
pi
->
regsd
);
}
target_clkdco
=
target_bitclk
*
m2
;
m
=
target_clkdco
/
fint
;
static
int
hdmi_pll_config
(
struct
hdmi_pll_data
*
pll
)
clkdco
=
fint
*
m
;
{
u32
r
;
struct
hdmi_pll_info
*
fmt
=
&
pll
->
info
;
/* PLL start always use manual mode */
/* adjust clkdco with fractional mf */
REG_FLD_MOD
(
pll
->
base
,
PLLCTRL_PLL_CONTROL
,
0x0
,
0
,
0
);
if
(
WARN_ON
(
target_clkdco
-
clkdco
>
fint
))
mf
=
0
;
r
=
hdmi_read_reg
(
pll
->
base
,
PLLCTRL_CFG1
);
r
=
FLD_MOD
(
r
,
fmt
->
regm
,
20
,
9
);
/* CFG1_PLL_REGM */
r
=
FLD_MOD
(
r
,
fmt
->
regn
-
1
,
8
,
1
);
/* CFG1_PLL_REGN */
hdmi_write_reg
(
pll
->
base
,
PLLCTRL_CFG1
,
r
);
r
=
hdmi_read_reg
(
pll
->
base
,
PLLCTRL_CFG2
);
r
=
FLD_MOD
(
r
,
0x0
,
12
,
12
);
/* PLL_HIGHFREQ divide by 2 */
r
=
FLD_MOD
(
r
,
0x1
,
13
,
13
);
/* PLL_REFEN */
r
=
FLD_MOD
(
r
,
0x0
,
14
,
14
);
/* PHY_CLKINEN de-assert during locking */
r
=
FLD_MOD
(
r
,
fmt
->
refsel
,
22
,
21
);
/* REFSEL */
if
(
fmt
->
dcofreq
)
r
=
FLD_MOD
(
r
,
0x4
,
3
,
1
);
/* 1000MHz and 2000MHz */
else
else
r
=
FLD_MOD
(
r
,
0x2
,
3
,
1
);
/* 500MHz and 1000MHz */
mf
=
(
u32
)
div_u64
(
262144ull
*
(
target_clkdco
-
clkdco
),
fint
);
hdmi_write_reg
(
pll
->
base
,
PLLCTRL_CFG2
,
r
);
REG_FLD_MOD
(
pll
->
base
,
PLLCTRL_CFG3
,
fmt
->
regsd
,
17
,
10
);
r
=
hdmi_read_reg
(
pll
->
base
,
PLLCTRL_CFG4
);
if
(
mf
>
0
)
r
=
FLD_MOD
(
r
,
fmt
->
regm2
,
24
,
18
);
clkdco
+=
(
u32
)
div_u64
((
u64
)
mf
*
fint
,
262144
);
r
=
FLD_MOD
(
r
,
fmt
->
regmf
,
17
,
0
);
hdmi_write_reg
(
pll
->
base
,
PLLCTRL_CFG4
,
r
);
/* go now */
clkout
=
clkdco
/
m2
;
REG_FLD_MOD
(
pll
->
base
,
PLLCTRL_PLL_GO
,
0x1
,
0
,
0
);
/* wait for bit change */
/* sigma-delta */
if
(
hdmi_wait_for_bit_change
(
pll
->
base
,
PLLCTRL_PLL_GO
,
sd
=
DIV_ROUND_UP
(
fint
*
m
,
250000000
);
0
,
0
,
0
)
!=
0
)
{
DSSERR
(
"PLL GO bit not clearing
\n
"
);
return
-
ETIMEDOUT
;
}
/* Wait till the lock bit is set in PLL status */
DSSDBG
(
"N = %u, M = %u, M.f = %u, M2 = %u, SD = %u
\n
"
,
if
(
hdmi_wait_for_bit_change
(
pll
->
base
,
n
,
m
,
mf
,
m2
,
sd
);
PLLCTRL_PLL_STATUS
,
1
,
1
,
1
)
!=
1
)
{
DSSDBG
(
"Fint %lu, clkdco %lu, clkout %lu
\n
"
,
fint
,
clkdco
,
clkout
);
DSSERR
(
"cannot lock PLL
\n
"
);
DSSERR
(
"CFG1 0x%x
\n
"
,
hdmi_read_reg
(
pll
->
base
,
PLLCTRL_CFG1
));
DSSERR
(
"CFG2 0x%x
\n
"
,
hdmi_read_reg
(
pll
->
base
,
PLLCTRL_CFG2
));
DSSERR
(
"CFG4 0x%x
\n
"
,
hdmi_read_reg
(
pll
->
base
,
PLLCTRL_CFG4
));
return
-
ETIMEDOUT
;
}
DSSDBG
(
"PLL locked!
\n
"
);
pi
->
n
=
n
;
pi
->
m
=
m
;
pi
->
mf
=
mf
;
pi
->
mX
[
0
]
=
m2
;
pi
->
sd
=
sd
;
return
0
;
pi
->
fint
=
fint
;
pi
->
clkdco
=
clkdco
;
pi
->
clkout
[
0
]
=
clkout
;
}
}
static
int
hdmi_pll_reset
(
struct
hdmi_pll_data
*
pll
)
static
int
hdmi_pll_enable
(
struct
dss_pll
*
dsspll
)
{
/* SYSRESET controlled by power FSM */
REG_FLD_MOD
(
pll
->
base
,
PLLCTRL_PLL_CONTROL
,
pll_feat
->
sys_reset
,
3
,
3
);
/* READ 0x0 reset is in progress */
if
(
hdmi_wait_for_bit_change
(
pll
->
base
,
PLLCTRL_PLL_STATUS
,
0
,
0
,
1
)
!=
1
)
{
DSSERR
(
"Failed to sysreset PLL
\n
"
);
return
-
ETIMEDOUT
;
}
return
0
;
}
int
hdmi_pll_enable
(
struct
hdmi_pll_data
*
pll
,
struct
hdmi_wp_data
*
wp
)
{
{
struct
hdmi_pll_data
*
pll
=
container_of
(
dsspll
,
struct
hdmi_pll_data
,
pll
);
struct
hdmi_wp_data
*
wp
=
pll
->
wp
;
u16
r
=
0
;
u16
r
=
0
;
r
=
hdmi_wp_set_pll_pwr
(
wp
,
HDMI_PLLPWRCMD_ALLOFF
);
if
(
r
)
return
r
;
r
=
hdmi_wp_set_pll_pwr
(
wp
,
HDMI_PLLPWRCMD_BOTHON_ALLCLKS
);
r
=
hdmi_wp_set_pll_pwr
(
wp
,
HDMI_PLLPWRCMD_BOTHON_ALLCLKS
);
if
(
r
)
if
(
r
)
return
r
;
return
r
;
r
=
hdmi_pll_reset
(
pll
);
if
(
r
)
return
r
;
r
=
hdmi_pll_config
(
pll
);
if
(
r
)
return
r
;
return
0
;
return
0
;
}
}
void
hdmi_pll_disable
(
struct
hdmi_pll_data
*
pll
,
struct
hdmi_wp_data
*
wp
)
static
void
hdmi_pll_disable
(
struct
dss_pll
*
dsspll
)
{
{
struct
hdmi_pll_data
*
pll
=
container_of
(
dsspll
,
struct
hdmi_pll_data
,
pll
);
struct
hdmi_wp_data
*
wp
=
pll
->
wp
;
hdmi_wp_set_pll_pwr
(
wp
,
HDMI_PLLPWRCMD_ALLOFF
);
hdmi_wp_set_pll_pwr
(
wp
,
HDMI_PLLPWRCMD_ALLOFF
);
}
}
static
const
struct
hdmi_pll_features
omap44xx_pll_feats
=
{
static
const
struct
dss_pll_ops
dsi_pll_ops
=
{
.
sys_reset
=
false
,
.
enable
=
hdmi_pll_enable
,
.
bound_dcofreq
=
false
,
.
disable
=
hdmi_pll_disable
,
.
fint_min
=
500000
,
.
set_config
=
dss_pll_write_config_type_b
,
.
fint_max
=
2500000
,
.
regm_max
=
4095
,
.
dcofreq_low_min
=
500000000
,
.
dcofreq_low_max
=
1000000000
,
.
dcofreq_high_min
=
1000000000
,
.
dcofreq_high_max
=
2000000000
,
};
};
static
const
struct
hdmi_pll_features
omap54xx_pll_feats
=
{
static
const
struct
dss_pll_hw
dss_omap4_hdmi_pll_hw
=
{
.
sys_reset
=
true
,
.
n_max
=
255
,
.
bound_dcofreq
=
true
,
.
m_min
=
20
,
.
fint_min
=
620000
,
.
m_max
=
4095
,
.
fint_max
=
2500000
,
.
mX_max
=
127
,
.
regm_max
=
2046
,
.
fint_min
=
500000
,
.
dcofreq_low_min
=
750000000
,
.
fint_max
=
2500000
,
.
dcofreq_low_max
=
1500000000
,
.
clkdco_max
=
1800000000
,
.
dcofreq_high_min
=
1250000000
,
.
dcofreq_high_max
=
2500000000UL
,
.
clkdco_min
=
500000000
,
.
clkdco_low
=
1000000000
,
.
clkdco_max
=
2000000000
,
.
n_msb
=
8
,
.
n_lsb
=
1
,
.
m_msb
=
20
,
.
m_lsb
=
9
,
.
mX_msb
[
0
]
=
24
,
.
mX_lsb
[
0
]
=
18
,
.
has_selfreqdco
=
true
,
};
};
static
int
hdmi_pll_init_features
(
struct
platform_device
*
pdev
)
static
const
struct
dss_pll_hw
dss_omap5_hdmi_pll_hw
=
{
.
n_max
=
255
,
.
m_min
=
20
,
.
m_max
=
2045
,
.
mX_max
=
127
,
.
fint_min
=
620000
,
.
fint_max
=
2500000
,
.
clkdco_max
=
1800000000
,
.
clkdco_min
=
750000000
,
.
clkdco_low
=
1500000000
,
.
clkdco_max
=
2500000000UL
,
.
n_msb
=
8
,
.
n_lsb
=
1
,
.
m_msb
=
20
,
.
m_lsb
=
9
,
.
mX_msb
[
0
]
=
24
,
.
mX_lsb
[
0
]
=
18
,
.
has_selfreqdco
=
true
,
.
has_refsel
=
true
,
};
static
int
dsi_init_pll_data
(
struct
platform_device
*
pdev
,
struct
hdmi_pll_data
*
hpll
)
{
{
struct
hdmi_pll_features
*
dst
;
struct
dss_pll
*
pll
=
&
hpll
->
pll
;
const
struct
hdmi_pll_features
*
src
;
struct
clk
*
clk
;
int
r
;
dst
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
dst
),
GFP_KERNEL
);
clk
=
devm_clk_get
(
&
pdev
->
dev
,
"sys_clk"
);
if
(
!
dst
)
{
if
(
IS_ERR
(
clk
)
)
{
dev_err
(
&
pdev
->
dev
,
"Failed to allocate HDMI PHY Features
\n
"
);
DSSERR
(
"can't get sys_clk
\n
"
);
return
-
ENOMEM
;
return
PTR_ERR
(
clk
)
;
}
}
pll
->
name
=
"hdmi"
;
pll
->
base
=
hpll
->
base
;
pll
->
clkin
=
clk
;
switch
(
omapdss_get_version
())
{
switch
(
omapdss_get_version
())
{
case
OMAPDSS_VER_OMAP4430_ES1
:
case
OMAPDSS_VER_OMAP4430_ES1
:
case
OMAPDSS_VER_OMAP4430_ES2
:
case
OMAPDSS_VER_OMAP4430_ES2
:
case
OMAPDSS_VER_OMAP4
:
case
OMAPDSS_VER_OMAP4
:
src
=
&
omap44xx_pll_feats
;
pll
->
hw
=
&
dss_omap4_hdmi_pll_hw
;
break
;
break
;
case
OMAPDSS_VER_OMAP5
:
case
OMAPDSS_VER_OMAP5
:
src
=
&
omap54xx_pll_feats
;
pll
->
hw
=
&
dss_omap5_hdmi_pll_hw
;
break
;
break
;
default:
default:
return
-
ENODEV
;
return
-
ENODEV
;
}
}
memcpy
(
dst
,
src
,
sizeof
(
*
dst
));
pll
->
ops
=
&
dsi_pll_ops
;
pll_feat
=
dst
;
r
=
dss_pll_register
(
pll
);
if
(
r
)
return
r
;
return
0
;
return
0
;
}
}
int
hdmi_pll_init
(
struct
platform_device
*
pdev
,
struct
hdmi_pll_data
*
pll
)
int
hdmi_pll_init
(
struct
platform_device
*
pdev
,
struct
hdmi_pll_data
*
pll
,
struct
hdmi_wp_data
*
wp
)
{
{
int
r
;
int
r
;
struct
resource
*
res
;
struct
resource
*
res
;
r
=
hdmi_pll_init_features
(
pdev
);
pll
->
wp
=
wp
;
if
(
r
)
return
r
;
res
=
platform_get_resource_byname
(
pdev
,
IORESOURCE_MEM
,
"pll"
);
res
=
platform_get_resource_byname
(
pdev
,
IORESOURCE_MEM
,
"pll"
);
if
(
!
res
)
{
if
(
!
res
)
{
...
@@ -286,5 +234,18 @@ int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll)
...
@@ -286,5 +234,18 @@ int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll)
return
PTR_ERR
(
pll
->
base
);
return
PTR_ERR
(
pll
->
base
);
}
}
r
=
dsi_init_pll_data
(
pdev
,
pll
);
if
(
r
)
{
DSSERR
(
"failed to init HDMI PLL
\n
"
);
return
r
;
}
return
0
;
return
0
;
}
}
void
hdmi_pll_uninit
(
struct
hdmi_pll_data
*
hpll
)
{
struct
dss_pll
*
pll
=
&
hpll
->
pll
;
dss_pll_unregister
(
pll
);
}
drivers/video/fbdev/omap2/dss/hdmi_wp.c
浏览文件 @
3315764e
...
@@ -185,7 +185,6 @@ void hdmi_wp_init_vid_fmt_timings(struct hdmi_video_format *video_fmt,
...
@@ -185,7 +185,6 @@ void hdmi_wp_init_vid_fmt_timings(struct hdmi_video_format *video_fmt,
timings
->
interlace
=
param
->
timings
.
interlace
;
timings
->
interlace
=
param
->
timings
.
interlace
;
}
}
#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) || defined(CONFIG_OMAP5_DSS_HDMI_AUDIO)
void
hdmi_wp_audio_config_format
(
struct
hdmi_wp_data
*
wp
,
void
hdmi_wp_audio_config_format
(
struct
hdmi_wp_data
*
wp
,
struct
hdmi_audio_format
*
aud_fmt
)
struct
hdmi_audio_format
*
aud_fmt
)
{
{
...
@@ -194,8 +193,12 @@ void hdmi_wp_audio_config_format(struct hdmi_wp_data *wp,
...
@@ -194,8 +193,12 @@ void hdmi_wp_audio_config_format(struct hdmi_wp_data *wp,
DSSDBG
(
"Enter hdmi_wp_audio_config_format
\n
"
);
DSSDBG
(
"Enter hdmi_wp_audio_config_format
\n
"
);
r
=
hdmi_read_reg
(
wp
->
base
,
HDMI_WP_AUDIO_CFG
);
r
=
hdmi_read_reg
(
wp
->
base
,
HDMI_WP_AUDIO_CFG
);
r
=
FLD_MOD
(
r
,
aud_fmt
->
stereo_channels
,
26
,
24
);
if
(
omapdss_get_version
()
==
OMAPDSS_VER_OMAP4430_ES1
||
r
=
FLD_MOD
(
r
,
aud_fmt
->
active_chnnls_msk
,
23
,
16
);
omapdss_get_version
()
==
OMAPDSS_VER_OMAP4430_ES2
||
omapdss_get_version
()
==
OMAPDSS_VER_OMAP4
)
{
r
=
FLD_MOD
(
r
,
aud_fmt
->
stereo_channels
,
26
,
24
);
r
=
FLD_MOD
(
r
,
aud_fmt
->
active_chnnls_msk
,
23
,
16
);
}
r
=
FLD_MOD
(
r
,
aud_fmt
->
en_sig_blk_strt_end
,
5
,
5
);
r
=
FLD_MOD
(
r
,
aud_fmt
->
en_sig_blk_strt_end
,
5
,
5
);
r
=
FLD_MOD
(
r
,
aud_fmt
->
type
,
4
,
4
);
r
=
FLD_MOD
(
r
,
aud_fmt
->
type
,
4
,
4
);
r
=
FLD_MOD
(
r
,
aud_fmt
->
justification
,
3
,
3
);
r
=
FLD_MOD
(
r
,
aud_fmt
->
justification
,
3
,
3
);
...
@@ -236,7 +239,6 @@ int hdmi_wp_audio_core_req_enable(struct hdmi_wp_data *wp, bool enable)
...
@@ -236,7 +239,6 @@ int hdmi_wp_audio_core_req_enable(struct hdmi_wp_data *wp, bool enable)
return
0
;
return
0
;
}
}
#endif
int
hdmi_wp_init
(
struct
platform_device
*
pdev
,
struct
hdmi_wp_data
*
wp
)
int
hdmi_wp_init
(
struct
platform_device
*
pdev
,
struct
hdmi_wp_data
*
wp
)
{
{
...
@@ -247,6 +249,7 @@ int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp)
...
@@ -247,6 +249,7 @@ int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp)
DSSERR
(
"can't get WP mem resource
\n
"
);
DSSERR
(
"can't get WP mem resource
\n
"
);
return
-
EINVAL
;
return
-
EINVAL
;
}
}
wp
->
phys_base
=
res
->
start
;
wp
->
base
=
devm_ioremap_resource
(
&
pdev
->
dev
,
res
);
wp
->
base
=
devm_ioremap_resource
(
&
pdev
->
dev
,
res
);
if
(
IS_ERR
(
wp
->
base
))
{
if
(
IS_ERR
(
wp
->
base
))
{
...
@@ -256,3 +259,8 @@ int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp)
...
@@ -256,3 +259,8 @@ int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp)
return
0
;
return
0
;
}
}
phys_addr_t
hdmi_wp_get_audio_dma_addr
(
struct
hdmi_wp_data
*
wp
)
{
return
wp
->
phys_base
+
HDMI_WP_AUDIO_DATA
;
}
drivers/video/fbdev/omap2/dss/output.c
浏览文件 @
3315764e
...
@@ -19,6 +19,7 @@
...
@@ -19,6 +19,7 @@
#include <linux/module.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <video/omapdss.h>
#include <video/omapdss.h>
...
@@ -131,18 +132,30 @@ struct omap_dss_device *omap_dss_find_output(const char *name)
...
@@ -131,18 +132,30 @@ struct omap_dss_device *omap_dss_find_output(const char *name)
}
}
EXPORT_SYMBOL
(
omap_dss_find_output
);
EXPORT_SYMBOL
(
omap_dss_find_output
);
struct
omap_dss_device
*
omap_dss_find_output_by_
node
(
struct
device_node
*
node
)
struct
omap_dss_device
*
omap_dss_find_output_by_
port_node
(
struct
device_node
*
port
)
{
{
struct
device_node
*
src_node
;
struct
omap_dss_device
*
out
;
struct
omap_dss_device
*
out
;
u32
reg
;
src_node
=
dss_of_port_get_parent_device
(
port
);
if
(
!
src_node
)
return
NULL
;
reg
=
dss_of_port_get_port_number
(
port
);
list_for_each_entry
(
out
,
&
output_list
,
list
)
{
list_for_each_entry
(
out
,
&
output_list
,
list
)
{
if
(
out
->
dev
->
of_node
==
node
)
if
(
out
->
dev
->
of_node
==
src_node
&&
out
->
port_num
==
reg
)
{
of_node_put
(
src_node
);
return
omap_dss_get_device
(
out
);
return
omap_dss_get_device
(
out
);
}
}
}
of_node_put
(
src_node
);
return
NULL
;
return
NULL
;
}
}
EXPORT_SYMBOL
(
omap_dss_find_output_by_node
);
EXPORT_SYMBOL
(
omap_dss_find_output_by_
port_
node
);
struct
omap_dss_device
*
omapdss_find_output_from_display
(
struct
omap_dss_device
*
dssdev
)
struct
omap_dss_device
*
omapdss_find_output_from_display
(
struct
omap_dss_device
*
dssdev
)
{
{
...
...
drivers/video/fbdev/omap2/dss/pll.c
0 → 100644
浏览文件 @
3315764e
此差异已折叠。
点击以展开。
drivers/video/fbdev/omap2/dss/sdi.c
浏览文件 @
3315764e
...
@@ -425,7 +425,7 @@ int __init sdi_init_port(struct platform_device *pdev, struct device_node *port)
...
@@ -425,7 +425,7 @@ int __init sdi_init_port(struct platform_device *pdev, struct device_node *port)
return
r
;
return
r
;
}
}
void
__exit
sdi_uninit_port
(
void
)
void
__exit
sdi_uninit_port
(
struct
device_node
*
port
)
{
{
if
(
!
sdi
.
port_initialized
)
if
(
!
sdi
.
port_initialized
)
return
;
return
;
...
...
drivers/video/fbdev/simplefb.c
浏览文件 @
3315764e
...
@@ -26,6 +26,8 @@
...
@@ -26,6 +26,8 @@
#include <linux/module.h>
#include <linux/module.h>
#include <linux/platform_data/simplefb.h>
#include <linux/platform_data/simplefb.h>
#include <linux/platform_device.h>
#include <linux/platform_device.h>
#include <linux/clk-provider.h>
#include <linux/of_platform.h>
static
struct
fb_fix_screeninfo
simplefb_fix
=
{
static
struct
fb_fix_screeninfo
simplefb_fix
=
{
.
id
=
"simple"
,
.
id
=
"simple"
,
...
@@ -41,6 +43,8 @@ static struct fb_var_screeninfo simplefb_var = {
...
@@ -41,6 +43,8 @@ static struct fb_var_screeninfo simplefb_var = {
.
vmode
=
FB_VMODE_NONINTERLACED
,
.
vmode
=
FB_VMODE_NONINTERLACED
,
};
};
#define PSEUDO_PALETTE_SIZE 16
static
int
simplefb_setcolreg
(
u_int
regno
,
u_int
red
,
u_int
green
,
u_int
blue
,
static
int
simplefb_setcolreg
(
u_int
regno
,
u_int
red
,
u_int
green
,
u_int
blue
,
u_int
transp
,
struct
fb_info
*
info
)
u_int
transp
,
struct
fb_info
*
info
)
{
{
...
@@ -50,7 +54,7 @@ static int simplefb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
...
@@ -50,7 +54,7 @@ static int simplefb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
u32
cb
=
blue
>>
(
16
-
info
->
var
.
blue
.
length
);
u32
cb
=
blue
>>
(
16
-
info
->
var
.
blue
.
length
);
u32
value
;
u32
value
;
if
(
regno
>=
16
)
if
(
regno
>=
PSEUDO_PALETTE_SIZE
)
return
-
EINVAL
;
return
-
EINVAL
;
value
=
(
cr
<<
info
->
var
.
red
.
offset
)
|
value
=
(
cr
<<
info
->
var
.
red
.
offset
)
|
...
@@ -163,11 +167,113 @@ static int simplefb_parse_pd(struct platform_device *pdev,
...
@@ -163,11 +167,113 @@ static int simplefb_parse_pd(struct platform_device *pdev,
return
0
;
return
0
;
}
}
struct
simplefb_par
{
u32
palette
[
PSEUDO_PALETTE_SIZE
];
#if defined CONFIG_OF && defined CONFIG_COMMON_CLK
int
clk_count
;
struct
clk
**
clks
;
#endif
};
#if defined CONFIG_OF && defined CONFIG_COMMON_CLK
/*
* Clock handling code.
*
* Here we handle the clocks property of our "simple-framebuffer" dt node.
* This is necessary so that we can make sure that any clocks needed by
* the display engine that the bootloader set up for us (and for which it
* provided a simplefb dt node), stay up, for the life of the simplefb
* driver.
*
* When the driver unloads, we cleanly disable, and then release the clocks.
*
* We only complain about errors here, no action is taken as the most likely
* error can only happen due to a mismatch between the bootloader which set
* up simplefb, and the clock definitions in the device tree. Chances are
* that there are no adverse effects, and if there are, a clean teardown of
* the fb probe will not help us much either. So just complain and carry on,
* and hope that the user actually gets a working fb at the end of things.
*/
static
int
simplefb_clocks_init
(
struct
simplefb_par
*
par
,
struct
platform_device
*
pdev
)
{
struct
device_node
*
np
=
pdev
->
dev
.
of_node
;
struct
clk
*
clock
;
int
i
,
ret
;
if
(
dev_get_platdata
(
&
pdev
->
dev
)
||
!
np
)
return
0
;
par
->
clk_count
=
of_clk_get_parent_count
(
np
);
if
(
par
->
clk_count
<=
0
)
return
0
;
par
->
clks
=
kcalloc
(
par
->
clk_count
,
sizeof
(
struct
clk
*
),
GFP_KERNEL
);
if
(
!
par
->
clks
)
return
-
ENOMEM
;
for
(
i
=
0
;
i
<
par
->
clk_count
;
i
++
)
{
clock
=
of_clk_get
(
np
,
i
);
if
(
IS_ERR
(
clock
))
{
if
(
PTR_ERR
(
clock
)
==
-
EPROBE_DEFER
)
{
while
(
--
i
>=
0
)
{
if
(
par
->
clks
[
i
])
clk_put
(
par
->
clks
[
i
]);
}
kfree
(
par
->
clks
);
return
-
EPROBE_DEFER
;
}
dev_err
(
&
pdev
->
dev
,
"%s: clock %d not found: %ld
\n
"
,
__func__
,
i
,
PTR_ERR
(
clock
));
continue
;
}
par
->
clks
[
i
]
=
clock
;
}
for
(
i
=
0
;
i
<
par
->
clk_count
;
i
++
)
{
if
(
par
->
clks
[
i
])
{
ret
=
clk_prepare_enable
(
par
->
clks
[
i
]);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"%s: failed to enable clock %d: %d
\n
"
,
__func__
,
i
,
ret
);
clk_put
(
par
->
clks
[
i
]);
par
->
clks
[
i
]
=
NULL
;
}
}
}
return
0
;
}
static
void
simplefb_clocks_destroy
(
struct
simplefb_par
*
par
)
{
int
i
;
if
(
!
par
->
clks
)
return
;
for
(
i
=
0
;
i
<
par
->
clk_count
;
i
++
)
{
if
(
par
->
clks
[
i
])
{
clk_disable_unprepare
(
par
->
clks
[
i
]);
clk_put
(
par
->
clks
[
i
]);
}
}
kfree
(
par
->
clks
);
}
#else
static
int
simplefb_clocks_init
(
struct
simplefb_par
*
par
,
struct
platform_device
*
pdev
)
{
return
0
;
}
static
void
simplefb_clocks_destroy
(
struct
simplefb_par
*
par
)
{
}
#endif
static
int
simplefb_probe
(
struct
platform_device
*
pdev
)
static
int
simplefb_probe
(
struct
platform_device
*
pdev
)
{
{
int
ret
;
int
ret
;
struct
simplefb_params
params
;
struct
simplefb_params
params
;
struct
fb_info
*
info
;
struct
fb_info
*
info
;
struct
simplefb_par
*
par
;
struct
resource
*
mem
;
struct
resource
*
mem
;
if
(
fb_get_options
(
"simplefb"
,
NULL
))
if
(
fb_get_options
(
"simplefb"
,
NULL
))
...
@@ -188,11 +294,13 @@ static int simplefb_probe(struct platform_device *pdev)
...
@@ -188,11 +294,13 @@ static int simplefb_probe(struct platform_device *pdev)
return
-
EINVAL
;
return
-
EINVAL
;
}
}
info
=
framebuffer_alloc
(
sizeof
(
u32
)
*
16
,
&
pdev
->
dev
);
info
=
framebuffer_alloc
(
sizeof
(
struct
simplefb_par
)
,
&
pdev
->
dev
);
if
(
!
info
)
if
(
!
info
)
return
-
ENOMEM
;
return
-
ENOMEM
;
platform_set_drvdata
(
pdev
,
info
);
platform_set_drvdata
(
pdev
,
info
);
par
=
info
->
par
;
info
->
fix
=
simplefb_fix
;
info
->
fix
=
simplefb_fix
;
info
->
fix
.
smem_start
=
mem
->
start
;
info
->
fix
.
smem_start
=
mem
->
start
;
info
->
fix
.
smem_len
=
resource_size
(
mem
);
info
->
fix
.
smem_len
=
resource_size
(
mem
);
...
@@ -211,8 +319,8 @@ static int simplefb_probe(struct platform_device *pdev)
...
@@ -211,8 +319,8 @@ static int simplefb_probe(struct platform_device *pdev)
info
->
apertures
=
alloc_apertures
(
1
);
info
->
apertures
=
alloc_apertures
(
1
);
if
(
!
info
->
apertures
)
{
if
(
!
info
->
apertures
)
{
framebuffer_release
(
info
)
;
ret
=
-
ENOMEM
;
return
-
ENOMEM
;
goto
error_fb_release
;
}
}
info
->
apertures
->
ranges
[
0
].
base
=
info
->
fix
.
smem_start
;
info
->
apertures
->
ranges
[
0
].
base
=
info
->
fix
.
smem_start
;
info
->
apertures
->
ranges
[
0
].
size
=
info
->
fix
.
smem_len
;
info
->
apertures
->
ranges
[
0
].
size
=
info
->
fix
.
smem_len
;
...
@@ -222,10 +330,14 @@ static int simplefb_probe(struct platform_device *pdev)
...
@@ -222,10 +330,14 @@ static int simplefb_probe(struct platform_device *pdev)
info
->
screen_base
=
ioremap_wc
(
info
->
fix
.
smem_start
,
info
->
screen_base
=
ioremap_wc
(
info
->
fix
.
smem_start
,
info
->
fix
.
smem_len
);
info
->
fix
.
smem_len
);
if
(
!
info
->
screen_base
)
{
if
(
!
info
->
screen_base
)
{
framebuffer_release
(
info
)
;
ret
=
-
ENOMEM
;
return
-
ENODEV
;
goto
error_fb_release
;
}
}
info
->
pseudo_palette
=
(
void
*
)(
info
+
1
);
info
->
pseudo_palette
=
par
->
palette
;
ret
=
simplefb_clocks_init
(
par
,
pdev
);
if
(
ret
<
0
)
goto
error_unmap
;
dev_info
(
&
pdev
->
dev
,
"framebuffer at 0x%lx, 0x%x bytes, mapped to 0x%p
\n
"
,
dev_info
(
&
pdev
->
dev
,
"framebuffer at 0x%lx, 0x%x bytes, mapped to 0x%p
\n
"
,
info
->
fix
.
smem_start
,
info
->
fix
.
smem_len
,
info
->
fix
.
smem_start
,
info
->
fix
.
smem_len
,
...
@@ -238,21 +350,29 @@ static int simplefb_probe(struct platform_device *pdev)
...
@@ -238,21 +350,29 @@ static int simplefb_probe(struct platform_device *pdev)
ret
=
register_framebuffer
(
info
);
ret
=
register_framebuffer
(
info
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
dev_err
(
&
pdev
->
dev
,
"Unable to register simplefb: %d
\n
"
,
ret
);
dev_err
(
&
pdev
->
dev
,
"Unable to register simplefb: %d
\n
"
,
ret
);
iounmap
(
info
->
screen_base
);
goto
error_clocks
;
framebuffer_release
(
info
);
return
ret
;
}
}
dev_info
(
&
pdev
->
dev
,
"fb%d: simplefb registered!
\n
"
,
info
->
node
);
dev_info
(
&
pdev
->
dev
,
"fb%d: simplefb registered!
\n
"
,
info
->
node
);
return
0
;
return
0
;
error_clocks:
simplefb_clocks_destroy
(
par
);
error_unmap:
iounmap
(
info
->
screen_base
);
error_fb_release:
framebuffer_release
(
info
);
return
ret
;
}
}
static
int
simplefb_remove
(
struct
platform_device
*
pdev
)
static
int
simplefb_remove
(
struct
platform_device
*
pdev
)
{
{
struct
fb_info
*
info
=
platform_get_drvdata
(
pdev
);
struct
fb_info
*
info
=
platform_get_drvdata
(
pdev
);
struct
simplefb_par
*
par
=
info
->
par
;
unregister_framebuffer
(
info
);
unregister_framebuffer
(
info
);
simplefb_clocks_destroy
(
par
);
framebuffer_release
(
info
);
framebuffer_release
(
info
);
return
0
;
return
0
;
...
@@ -273,7 +393,27 @@ static struct platform_driver simplefb_driver = {
...
@@ -273,7 +393,27 @@ static struct platform_driver simplefb_driver = {
.
probe
=
simplefb_probe
,
.
probe
=
simplefb_probe
,
.
remove
=
simplefb_remove
,
.
remove
=
simplefb_remove
,
};
};
module_platform_driver
(
simplefb_driver
);
static
int
__init
simplefb_init
(
void
)
{
int
ret
;
struct
device_node
*
np
;
ret
=
platform_driver_register
(
&
simplefb_driver
);
if
(
ret
)
return
ret
;
if
(
IS_ENABLED
(
CONFIG_OF
)
&&
of_chosen
)
{
for_each_child_of_node
(
of_chosen
,
np
)
{
if
(
of_device_is_compatible
(
np
,
"simple-framebuffer"
))
of_platform_device_create
(
np
,
NULL
,
NULL
);
}
}
return
0
;
}
fs_initcall
(
simplefb_init
);
MODULE_AUTHOR
(
"Stephen Warren <swarren@wwwdotorg.org>"
);
MODULE_AUTHOR
(
"Stephen Warren <swarren@wwwdotorg.org>"
);
MODULE_DESCRIPTION
(
"Simple framebuffer driver"
);
MODULE_DESCRIPTION
(
"Simple framebuffer driver"
);
...
...
include/linux/of.h
浏览文件 @
3315764e
...
@@ -105,8 +105,6 @@ static inline struct device_node *of_node_get(struct device_node *node)
...
@@ -105,8 +105,6 @@ static inline struct device_node *of_node_get(struct device_node *node)
static
inline
void
of_node_put
(
struct
device_node
*
node
)
{
}
static
inline
void
of_node_put
(
struct
device_node
*
node
)
{
}
#endif
/* !CONFIG_OF_DYNAMIC */
#endif
/* !CONFIG_OF_DYNAMIC */
#ifdef CONFIG_OF
/* Pointer for first entry in chain of all nodes. */
/* Pointer for first entry in chain of all nodes. */
extern
struct
device_node
*
of_allnodes
;
extern
struct
device_node
*
of_allnodes
;
extern
struct
device_node
*
of_chosen
;
extern
struct
device_node
*
of_chosen
;
...
@@ -114,6 +112,7 @@ extern struct device_node *of_aliases;
...
@@ -114,6 +112,7 @@ extern struct device_node *of_aliases;
extern
struct
device_node
*
of_stdout
;
extern
struct
device_node
*
of_stdout
;
extern
raw_spinlock_t
devtree_lock
;
extern
raw_spinlock_t
devtree_lock
;
#ifdef CONFIG_OF
static
inline
bool
of_have_populated_dt
(
void
)
static
inline
bool
of_have_populated_dt
(
void
)
{
{
return
of_allnodes
!=
NULL
;
return
of_allnodes
!=
NULL
;
...
...
sound/soc/omap/omap-hdmi
.h
→
include/sound/omap-hdmi-audio
.h
浏览文件 @
3315764e
此差异已折叠。
点击以展开。
include/video/omapdss.h
浏览文件 @
3315764e
此差异已折叠。
点击以展开。
sound/soc/omap/Kconfig
浏览文件 @
3315764e
此差异已折叠。
点击以展开。
sound/soc/omap/Makefile
浏览文件 @
3315764e
此差异已折叠。
点击以展开。
sound/soc/omap/omap-hdmi.c
→
sound/soc/omap/omap-hdmi
-audio
.c
浏览文件 @
3315764e
此差异已折叠。
点击以展开。
sound/soc/omap/omap-hdmi-card.c
已删除
100644 → 0
浏览文件 @
34685627
此差异已折叠。
点击以展开。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录