aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2016-04-05 19:57:33 -0400
committerDave Airlie <airlied@redhat.com>2016-04-05 19:57:33 -0400
commitd00b39c17573ece6f5fb1385314877d29f540db8 (patch)
tree859eda0522e4a5bbfd727c07ec210686cb799b08
parent85bd5ac371c844f66918dda8c83145a26a55f9f2 (diff)
parent7b4b7a8db439dca4342a0424b3d99d878a4e5a12 (diff)
Merge branch 'drm-next-analogix-dp-v2' of github.com:yakir-Yang/linux into drm-next
This pull request want to land the analogix_dp driver into drm/bridge directory, which reused the Exynos DP code, and add Rockchip DP support. And those patches have been: * 'drm-next-analogix-dp-v2' of github.com:yakir-Yang/linux: drm: bridge: analogix/dp: Fix the possible dead lock in bridge disable time drm: bridge: analogix/dp: add panel prepare/unprepare in suspend/resume time drm: bridge: analogix/dp: add edid modes parse in get_modes method drm: bridge: analogix/dp: move hpd detect to connector detect function drm: bridge: analogix/dp: try force hpd after plug in lookup failed drm: bridge: analogix/dp: add max link rate and lane count limit for RK3288 drm: bridge: analogix/dp: add some rk3288 special registers setting dt-bindings: add document for rockchip variant of analogix_dp drm: rockchip: dp: add rockchip platform dp driver ARM: dts: exynos/dp: remove some properties that deprecated by analogix_dp driver dt-bindings: add document for analogix display port driver drm: bridge: analogix/dp: dynamic parse sync_pol & interlace & dynamic_range drm: bridge: analogix/dp: remove duplicate configuration of link rate and link count drm: bridge: analogix/dp: fix some obvious code style drm: bridge: analogix/dp: rename register constants drm/exynos: dp: rename implementation specific driver part drm: bridge: analogix/dp: split exynos dp driver to bridge directory
-rw-r--r--Documentation/devicetree/bindings/display/bridge/analogix_dp.txt52
-rw-r--r--Documentation/devicetree/bindings/display/exynos/exynos_dp.txt93
-rw-r--r--Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt92
-rw-r--r--arch/arm/boot/dts/exynos5250-arndale.dts2
-rw-r--r--arch/arm/boot/dts/exynos5250-smdk5250.dts2
-rw-r--r--arch/arm/boot/dts/exynos5250-snow-common.dtsi4
-rw-r--r--arch/arm/boot/dts/exynos5250-spring.dts4
-rw-r--r--arch/arm/boot/dts/exynos5420-peach-pit.dts4
-rw-r--r--arch/arm/boot/dts/exynos5420-smdk5420.dts2
-rw-r--r--arch/arm/boot/dts/exynos5800-peach-pi.dts2
-rw-r--r--drivers/gpu/drm/bridge/Kconfig2
-rw-r--r--drivers/gpu/drm/bridge/Makefile1
-rw-r--r--drivers/gpu/drm/bridge/analogix/Kconfig3
-rw-r--r--drivers/gpu/drm/bridge/analogix/Makefile2
-rw-r--r--drivers/gpu/drm/bridge/analogix/analogix_dp_core.c1430
-rw-r--r--drivers/gpu/drm/bridge/analogix/analogix_dp_core.h281
-rw-r--r--drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c1320
-rw-r--r--drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h (renamed from drivers/gpu/drm/exynos/exynos_dp_reg.h)270
-rw-r--r--drivers/gpu/drm/exynos/Kconfig3
-rw-r--r--drivers/gpu/drm/exynos/Makefile2
-rw-r--r--drivers/gpu/drm/exynos/exynos_dp.c314
-rw-r--r--drivers/gpu/drm/exynos/exynos_dp_core.c1499
-rw-r--r--drivers/gpu/drm/exynos/exynos_dp_core.h282
-rw-r--r--drivers/gpu/drm/exynos/exynos_dp_reg.c1263
-rw-r--r--drivers/gpu/drm/rockchip/Kconfig9
-rw-r--r--drivers/gpu/drm/rockchip/Makefile1
-rw-r--r--drivers/gpu/drm/rockchip/analogix_dp-rockchip.c384
-rw-r--r--include/drm/bridge/analogix_dp.h41
28 files changed, 4106 insertions, 3258 deletions
diff --git a/Documentation/devicetree/bindings/display/bridge/analogix_dp.txt b/Documentation/devicetree/bindings/display/bridge/analogix_dp.txt
new file mode 100644
index 000000000000..4f2ba8c13d92
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/bridge/analogix_dp.txt
@@ -0,0 +1,52 @@
1Analogix Display Port bridge bindings
2
3Required properties for dp-controller:
4 -compatible:
5 platform specific such as:
6 * "samsung,exynos5-dp"
7 * "rockchip,rk3288-dp"
8 -reg:
9 physical base address of the controller and length
10 of memory mapped region.
11 -interrupts:
12 interrupt combiner values.
13 -clocks:
14 from common clock binding: handle to dp clock.
15 -clock-names:
16 from common clock binding: Shall be "dp".
17 -interrupt-parent:
18 phandle to Interrupt combiner node.
19 -phys:
20 from general PHY binding: the phandle for the PHY device.
21 -phy-names:
22 from general PHY binding: Should be "dp".
23
24Optional properties for dp-controller:
25 -force-hpd:
26 Indicate driver need force hpd when hpd detect failed, this
27 is used for some eDP screen which don't have hpd signal.
28 -hpd-gpios:
29 Hotplug detect GPIO.
30 Indicates which GPIO should be used for hotplug detection
31 -port@[X]: SoC specific port nodes with endpoint definitions as defined
32 in Documentation/devicetree/bindings/media/video-interfaces.txt,
33 please refer to the SoC specific binding document:
34 * Documentation/devicetree/bindings/display/exynos/exynos_dp.txt
35 * Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
36
37[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
38-------------------------------------------------------------------------------
39
40Example:
41
42 dp-controller {
43 compatible = "samsung,exynos5-dp";
44 reg = <0x145b0000 0x10000>;
45 interrupts = <10 3>;
46 interrupt-parent = <&combiner>;
47 clocks = <&clock 342>;
48 clock-names = "dp";
49
50 phys = <&dp_phy>;
51 phy-names = "dp";
52 };
diff --git a/Documentation/devicetree/bindings/display/exynos/exynos_dp.txt b/Documentation/devicetree/bindings/display/exynos/exynos_dp.txt
index fe4a7a2dea9c..ade5d8eebf85 100644
--- a/Documentation/devicetree/bindings/display/exynos/exynos_dp.txt
+++ b/Documentation/devicetree/bindings/display/exynos/exynos_dp.txt
@@ -1,20 +1,3 @@
1Device-Tree bindings for Samsung Exynos Embedded DisplayPort Transmitter(eDP)
2
3DisplayPort is industry standard to accommodate the growing board adoption
4of digital display technology within the PC and CE industries.
5It consolidates the internal and external connection methods to reduce device
6complexity and cost. It also supports necessary features for important cross
7industry applications and provides performance scalability to enable the next
8generation of displays that feature higher color depths, refresh rates, and
9display resolutions.
10
11eDP (embedded display port) device is compliant with Embedded DisplayPort
12standard as follows,
13- DisplayPort standard 1.1a for Exynos5250 and Exynos5260.
14- DisplayPort standard 1.3 for Exynos5422s and Exynos5800.
15
16eDP resides between FIMD and panel or FIMD and bridge such as LVDS.
17
18The Exynos display port interface should be configured based on 1The Exynos display port interface should be configured based on
19the type of panel connected to it. 2the type of panel connected to it.
20 3
@@ -48,26 +31,6 @@ Required properties for dp-controller:
48 from general PHY binding: the phandle for the PHY device. 31 from general PHY binding: the phandle for the PHY device.
49 -phy-names: 32 -phy-names:
50 from general PHY binding: Should be "dp". 33 from general PHY binding: Should be "dp".
51 -samsung,color-space:
52 input video data format.
53 COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2
54 -samsung,dynamic-range:
55 dynamic range for input video data.
56 VESA = 0, CEA = 1
57 -samsung,ycbcr-coeff:
58 YCbCr co-efficients for input video.
59 COLOR_YCBCR601 = 0, COLOR_YCBCR709 = 1
60 -samsung,color-depth:
61 number of bits per colour component.
62 COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
63 -samsung,link-rate:
64 link rate supported by the panel.
65 LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A
66 -samsung,lane-count:
67 number of lanes supported by the panel.
68 LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4
69 - display-timings: timings for the connected panel as described by
70 Documentation/devicetree/bindings/display/display-timing.txt
71 34
72Optional properties for dp-controller: 35Optional properties for dp-controller:
73 -interlaced: 36 -interlaced:
@@ -83,17 +46,31 @@ Optional properties for dp-controller:
83 Hotplug detect GPIO. 46 Hotplug detect GPIO.
84 Indicates which GPIO should be used for hotplug 47 Indicates which GPIO should be used for hotplug
85 detection 48 detection
86Video interfaces: 49 -video interfaces: Device node can contain video interface port
87 Device node can contain video interface port nodes according to [1]. 50 nodes according to [1].
88 The following are properties specific to those nodes: 51 - display-timings: timings for the connected panel as described by
89 52 Documentation/devicetree/bindings/display/panel/display-timing.txt
90 endpoint node connected to bridge or panel node: 53
91 - remote-endpoint: specifies the endpoint in panel or bridge node. 54For the below properties, please refer to Analogix DP binding document:
92 This node is required in all kinds of exynos dp 55 * Documentation/devicetree/bindings/display/bridge/analogix_dp.txt
93 to represent the connection between dp and bridge 56 -phys (required)
94 or dp and panel. 57 -phy-names (required)
95 58 -hpd-gpios (optional)
96[1]: Documentation/devicetree/bindings/media/video-interfaces.txt 59 force-hpd (optional)
60
61Deprecated properties for DisplayPort:
62-interlaced: deprecated prop that can parsed from drm_display_mode.
63-vsync-active-high: deprecated prop that can parsed from drm_display_mode.
64-hsync-active-high: deprecated prop that can parsed from drm_display_mode.
65-samsung,ycbcr-coeff: deprecated prop that can parsed from drm_display_mode.
66-samsung,dynamic-range: deprecated prop that can parsed from drm_display_mode.
67-samsung,color-space: deprecated prop that can parsed from drm_display_info.
68-samsung,color-depth: deprecated prop that can parsed from drm_display_info.
69-samsung,link-rate: deprecated prop that can reading from monitor by dpcd method.
70-samsung,lane-count: deprecated prop that can reading from monitor by dpcd method.
71-samsung,hpd-gpio: deprecated name for hpd-gpios.
72
73-------------------------------------------------------------------------------
97 74
98Example: 75Example:
99 76
@@ -112,13 +89,6 @@ SOC specific portion:
112 89
113Board Specific portion: 90Board Specific portion:
114 dp-controller { 91 dp-controller {
115 samsung,color-space = <0>;
116 samsung,dynamic-range = <0>;
117 samsung,ycbcr-coeff = <0>;
118 samsung,color-depth = <1>;
119 samsung,link-rate = <0x0a>;
120 samsung,lane-count = <4>;
121
122 display-timings { 92 display-timings {
123 native-mode = <&lcd_timing>; 93 native-mode = <&lcd_timing>;
124 lcd_timing: 1366x768 { 94 lcd_timing: 1366x768 {
@@ -135,18 +105,9 @@ Board Specific portion:
135 }; 105 };
136 106
137 ports { 107 ports {
138 port { 108 port@0 {
139 dp_out: endpoint { 109 dp_out: endpoint {
140 remote-endpoint = <&dp_in>; 110 remote-endpoint = <&bridge_in>;
141 };
142 };
143 };
144
145 panel {
146 ...
147 port {
148 dp_in: endpoint {
149 remote-endpoint = <&dp_out>;
150 }; 111 };
151 }; 112 };
152 }; 113 };
diff --git a/Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt b/Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt
new file mode 100644
index 000000000000..e832ff98fd61
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt
@@ -0,0 +1,92 @@
1Rockchip RK3288 specific extensions to the Analogix Display Port
2================================
3
4Required properties:
5- compatible: "rockchip,rk3288-edp";
6
7- reg: physical base address of the controller and length
8
9- clocks: from common clock binding: handle to dp clock.
10 of memory mapped region.
11
12- clock-names: from common clock binding:
13 Required elements: "dp" "pclk"
14
15- resets: Must contain an entry for each entry in reset-names.
16 See ../reset/reset.txt for details.
17
18- pinctrl-names: Names corresponding to the chip hotplug pinctrl states.
19- pinctrl-0: pin-control mode. should be <&edp_hpd>
20
21- reset-names: Must include the name "dp"
22
23- rockchip,grf: this soc should set GRF regs, so need get grf here.
24
25- ports: there are 2 port nodes with endpoint definitions as defined in
26 Documentation/devicetree/bindings/media/video-interfaces.txt.
27 Port 0: contained 2 endpoints, connecting to the output of vop.
28 Port 1: contained 1 endpoint, connecting to the input of panel.
29
30For the below properties, please refer to Analogix DP binding document:
31 * Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
32- phys (required)
33- phy-names (required)
34- hpd-gpios (optional)
35- force-hpd (optional)
36-------------------------------------------------------------------------------
37
38Example:
39 dp-controller: dp@ff970000 {
40 compatible = "rockchip,rk3288-dp";
41 reg = <0xff970000 0x4000>;
42 interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
43 clocks = <&cru SCLK_EDP>, <&cru PCLK_EDP_CTRL>;
44 clock-names = "dp", "pclk";
45 phys = <&dp_phy>;
46 phy-names = "dp";
47
48 rockchip,grf = <&grf>;
49 resets = <&cru 111>;
50 reset-names = "dp";
51
52 pinctrl-names = "default";
53 pinctrl-0 = <&edp_hpd>;
54
55 status = "disabled";
56
57 ports {
58 #address-cells = <1>;
59 #size-cells = <0>;
60 edp_in: port@0 {
61 reg = <0>;
62 #address-cells = <1>;
63 #size-cells = <0>;
64 edp_in_vopb: endpoint@0 {
65 reg = <0>;
66 remote-endpoint = <&vopb_out_edp>;
67 };
68 edp_in_vopl: endpoint@1 {
69 reg = <1>;
70 remote-endpoint = <&vopl_out_edp>;
71 };
72 };
73
74 edp_out: port@1 {
75 reg = <1>;
76 #address-cells = <1>;
77 #size-cells = <0>;
78 edp_out_panel: endpoint {
79 reg = <0>;
80 remote-endpoint = <&panel_in_edp>
81 };
82 };
83 };
84 };
85
86 pinctrl {
87 edp {
88 edp_hpd: edp-hpd {
89 rockchip,pins = <7 11 RK_FUNC_2 &pcfg_pull_none>;
90 };
91 };
92 };
diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts
index 8b2acc74aa76..85d819217d17 100644
--- a/arch/arm/boot/dts/exynos5250-arndale.dts
+++ b/arch/arm/boot/dts/exynos5250-arndale.dts
@@ -124,8 +124,6 @@
124&dp { 124&dp {
125 status = "okay"; 125 status = "okay";
126 samsung,color-space = <0>; 126 samsung,color-space = <0>;
127 samsung,dynamic-range = <0>;
128 samsung,ycbcr-coeff = <0>;
129 samsung,color-depth = <1>; 127 samsung,color-depth = <1>;
130 samsung,link-rate = <0x0a>; 128 samsung,link-rate = <0x0a>;
131 samsung,lane-count = <4>; 129 samsung,lane-count = <4>;
diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts
index 0f5dcd418af8..f30c2dbba4f5 100644
--- a/arch/arm/boot/dts/exynos5250-smdk5250.dts
+++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts
@@ -80,8 +80,6 @@
80 80
81&dp { 81&dp {
82 samsung,color-space = <0>; 82 samsung,color-space = <0>;
83 samsung,dynamic-range = <0>;
84 samsung,ycbcr-coeff = <0>;
85 samsung,color-depth = <1>; 83 samsung,color-depth = <1>;
86 samsung,link-rate = <0x0a>; 84 samsung,link-rate = <0x0a>;
87 samsung,lane-count = <4>; 85 samsung,lane-count = <4>;
diff --git a/arch/arm/boot/dts/exynos5250-snow-common.dtsi b/arch/arm/boot/dts/exynos5250-snow-common.dtsi
index 95210ef6a6b5..746808f401e5 100644
--- a/arch/arm/boot/dts/exynos5250-snow-common.dtsi
+++ b/arch/arm/boot/dts/exynos5250-snow-common.dtsi
@@ -236,12 +236,10 @@
236 pinctrl-names = "default"; 236 pinctrl-names = "default";
237 pinctrl-0 = <&dp_hpd>; 237 pinctrl-0 = <&dp_hpd>;
238 samsung,color-space = <0>; 238 samsung,color-space = <0>;
239 samsung,dynamic-range = <0>;
240 samsung,ycbcr-coeff = <0>;
241 samsung,color-depth = <1>; 239 samsung,color-depth = <1>;
242 samsung,link-rate = <0x0a>; 240 samsung,link-rate = <0x0a>;
243 samsung,lane-count = <2>; 241 samsung,lane-count = <2>;
244 samsung,hpd-gpio = <&gpx0 7 GPIO_ACTIVE_HIGH>; 242 hpd-gpios = <&gpx0 7 GPIO_ACTIVE_HIGH>;
245 243
246 ports { 244 ports {
247 port@0 { 245 port@0 {
diff --git a/arch/arm/boot/dts/exynos5250-spring.dts b/arch/arm/boot/dts/exynos5250-spring.dts
index 0f500cb1eb2d..c607bed575d9 100644
--- a/arch/arm/boot/dts/exynos5250-spring.dts
+++ b/arch/arm/boot/dts/exynos5250-spring.dts
@@ -74,12 +74,10 @@
74 pinctrl-names = "default"; 74 pinctrl-names = "default";
75 pinctrl-0 = <&dp_hpd_gpio>; 75 pinctrl-0 = <&dp_hpd_gpio>;
76 samsung,color-space = <0>; 76 samsung,color-space = <0>;
77 samsung,dynamic-range = <0>;
78 samsung,ycbcr-coeff = <0>;
79 samsung,color-depth = <1>; 77 samsung,color-depth = <1>;
80 samsung,link-rate = <0x0a>; 78 samsung,link-rate = <0x0a>;
81 samsung,lane-count = <1>; 79 samsung,lane-count = <1>;
82 samsung,hpd-gpio = <&gpc3 0 GPIO_ACTIVE_HIGH>; 80 hpd-gpios = <&gpc3 0 GPIO_ACTIVE_HIGH>;
83}; 81};
84 82
85&ehci { 83&ehci {
diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts
index 3981ddb25036..7ddb6a066b28 100644
--- a/arch/arm/boot/dts/exynos5420-peach-pit.dts
+++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
@@ -157,12 +157,10 @@
157 pinctrl-names = "default"; 157 pinctrl-names = "default";
158 pinctrl-0 = <&dp_hpd_gpio>; 158 pinctrl-0 = <&dp_hpd_gpio>;
159 samsung,color-space = <0>; 159 samsung,color-space = <0>;
160 samsung,dynamic-range = <0>;
161 samsung,ycbcr-coeff = <0>;
162 samsung,color-depth = <1>; 160 samsung,color-depth = <1>;
163 samsung,link-rate = <0x06>; 161 samsung,link-rate = <0x06>;
164 samsung,lane-count = <2>; 162 samsung,lane-count = <2>;
165 samsung,hpd-gpio = <&gpx2 6 GPIO_ACTIVE_HIGH>; 163 hpd-gpios = <&gpx2 6 GPIO_ACTIVE_HIGH>;
166 164
167 ports { 165 ports {
168 port@0 { 166 port@0 {
diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts
index 0785fedf441e..288817daa16c 100644
--- a/arch/arm/boot/dts/exynos5420-smdk5420.dts
+++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts
@@ -102,8 +102,6 @@
102 pinctrl-names = "default"; 102 pinctrl-names = "default";
103 pinctrl-0 = <&dp_hpd>; 103 pinctrl-0 = <&dp_hpd>;
104 samsung,color-space = <0>; 104 samsung,color-space = <0>;
105 samsung,dynamic-range = <0>;
106 samsung,ycbcr-coeff = <0>;
107 samsung,color-depth = <1>; 105 samsung,color-depth = <1>;
108 samsung,link-rate = <0x0a>; 106 samsung,link-rate = <0x0a>;
109 samsung,lane-count = <4>; 107 samsung,lane-count = <4>;
diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
index 6e9edc1610c4..6ba9aec15485 100644
--- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
+++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
@@ -157,8 +157,6 @@
157 pinctrl-names = "default"; 157 pinctrl-names = "default";
158 pinctrl-0 = <&dp_hpd_gpio>; 158 pinctrl-0 = <&dp_hpd_gpio>;
159 samsung,color-space = <0>; 159 samsung,color-space = <0>;
160 samsung,dynamic-range = <0>;
161 samsung,ycbcr-coeff = <0>;
162 samsung,color-depth = <1>; 160 samsung,color-depth = <1>;
163 samsung,link-rate = <0x0a>; 161 samsung,link-rate = <0x0a>;
164 samsung,lane-count = <2>; 162 samsung,lane-count = <2>;
diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index 27e2022de89d..efd94e00c3e5 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -40,4 +40,6 @@ config DRM_PARADE_PS8622
40 ---help--- 40 ---help---
41 Parade eDP-LVDS bridge chip driver. 41 Parade eDP-LVDS bridge chip driver.
42 42
43source "drivers/gpu/drm/bridge/analogix/Kconfig"
44
43endmenu 45endmenu
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index f13c33d67c03..ff821f4b5833 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -4,3 +4,4 @@ obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
4obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o 4obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o
5obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o 5obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o
6obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o 6obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o
7obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix/
diff --git a/drivers/gpu/drm/bridge/analogix/Kconfig b/drivers/gpu/drm/bridge/analogix/Kconfig
new file mode 100644
index 000000000000..80f286fa3a69
--- /dev/null
+++ b/drivers/gpu/drm/bridge/analogix/Kconfig
@@ -0,0 +1,3 @@
1config DRM_ANALOGIX_DP
2 tristate
3 depends on DRM
diff --git a/drivers/gpu/drm/bridge/analogix/Makefile b/drivers/gpu/drm/bridge/analogix/Makefile
new file mode 100644
index 000000000000..cd4010ba6890
--- /dev/null
+++ b/drivers/gpu/drm/bridge/analogix/Makefile
@@ -0,0 +1,2 @@
1analogix_dp-objs := analogix_dp_core.o analogix_dp_reg.o
2obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix_dp.o
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
new file mode 100644
index 000000000000..7699597070a1
--- /dev/null
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -0,0 +1,1430 @@
1/*
2* Analogix DP (Display Port) core interface driver.
3*
4* Copyright (C) 2012 Samsung Electronics Co., Ltd.
5* Author: Jingoo Han <jg1.han@samsung.com>
6*
7* This program is free software; you can redistribute it and/or modify it
8* under the terms of the GNU General Public License as published by the
9* Free Software Foundation; either version 2 of the License, or (at your
10* option) any later version.
11*/
12
13#include <linux/module.h>
14#include <linux/platform_device.h>
15#include <linux/err.h>
16#include <linux/clk.h>
17#include <linux/io.h>
18#include <linux/interrupt.h>
19#include <linux/of.h>
20#include <linux/of_gpio.h>
21#include <linux/gpio.h>
22#include <linux/component.h>
23#include <linux/phy/phy.h>
24
25#include <drm/drmP.h>
26#include <drm/drm_atomic_helper.h>
27#include <drm/drm_crtc.h>
28#include <drm/drm_crtc_helper.h>
29#include <drm/drm_panel.h>
30
31#include <drm/bridge/analogix_dp.h>
32
33#include "analogix_dp_core.h"
34
35#define to_dp(nm) container_of(nm, struct analogix_dp_device, nm)
36
37struct bridge_init {
38 struct i2c_client *client;
39 struct device_node *node;
40};
41
42static void analogix_dp_init_dp(struct analogix_dp_device *dp)
43{
44 analogix_dp_reset(dp);
45
46 analogix_dp_swreset(dp);
47
48 analogix_dp_init_analog_param(dp);
49 analogix_dp_init_interrupt(dp);
50
51 /* SW defined function Normal operation */
52 analogix_dp_enable_sw_function(dp);
53
54 analogix_dp_config_interrupt(dp);
55 analogix_dp_init_analog_func(dp);
56
57 analogix_dp_init_hpd(dp);
58 analogix_dp_init_aux(dp);
59}
60
61static int analogix_dp_detect_hpd(struct analogix_dp_device *dp)
62{
63 int timeout_loop = 0;
64
65 while (timeout_loop < DP_TIMEOUT_LOOP_COUNT) {
66 if (analogix_dp_get_plug_in_status(dp) == 0)
67 return 0;
68
69 timeout_loop++;
70 usleep_range(10, 11);
71 }
72
73 /*
74 * Some edp screen do not have hpd signal, so we can't just
75 * return failed when hpd plug in detect failed, DT property
76 * "force-hpd" would indicate whether driver need this.
77 */
78 if (!dp->force_hpd)
79 return -ETIMEDOUT;
80
81 /*
82 * The eDP TRM indicate that if HPD_STATUS(RO) is 0, AUX CH
83 * will not work, so we need to give a force hpd action to
84 * set HPD_STATUS manually.
85 */
86 dev_dbg(dp->dev, "failed to get hpd plug status, try to force hpd\n");
87
88 analogix_dp_force_hpd(dp);
89
90 if (analogix_dp_get_plug_in_status(dp) != 0) {
91 dev_err(dp->dev, "failed to get hpd plug in status\n");
92 return -EINVAL;
93 }
94
95 dev_dbg(dp->dev, "success to get plug in status after force hpd\n");
96
97 return 0;
98}
99
100static unsigned char analogix_dp_calc_edid_check_sum(unsigned char *edid_data)
101{
102 int i;
103 unsigned char sum = 0;
104
105 for (i = 0; i < EDID_BLOCK_LENGTH; i++)
106 sum = sum + edid_data[i];
107
108 return sum;
109}
110
111static int analogix_dp_read_edid(struct analogix_dp_device *dp)
112{
113 unsigned char *edid = dp->edid;
114 unsigned int extend_block = 0;
115 unsigned char sum;
116 unsigned char test_vector;
117 int retval;
118
119 /*
120 * EDID device address is 0x50.
121 * However, if necessary, you must have set upper address
122 * into E-EDID in I2C device, 0x30.
123 */
124
125 /* Read Extension Flag, Number of 128-byte EDID extension blocks */
126 retval = analogix_dp_read_byte_from_i2c(dp, I2C_EDID_DEVICE_ADDR,
127 EDID_EXTENSION_FLAG,
128 &extend_block);
129 if (retval)
130 return retval;
131
132 if (extend_block > 0) {
133 dev_dbg(dp->dev, "EDID data includes a single extension!\n");
134
135 /* Read EDID data */
136 retval = analogix_dp_read_bytes_from_i2c(dp,
137 I2C_EDID_DEVICE_ADDR,
138 EDID_HEADER_PATTERN,
139 EDID_BLOCK_LENGTH,
140 &edid[EDID_HEADER_PATTERN]);
141 if (retval != 0) {
142 dev_err(dp->dev, "EDID Read failed!\n");
143 return -EIO;
144 }
145 sum = analogix_dp_calc_edid_check_sum(edid);
146 if (sum != 0) {
147 dev_err(dp->dev, "EDID bad checksum!\n");
148 return -EIO;
149 }
150
151 /* Read additional EDID data */
152 retval = analogix_dp_read_bytes_from_i2c(dp,
153 I2C_EDID_DEVICE_ADDR,
154 EDID_BLOCK_LENGTH,
155 EDID_BLOCK_LENGTH,
156 &edid[EDID_BLOCK_LENGTH]);
157 if (retval != 0) {
158 dev_err(dp->dev, "EDID Read failed!\n");
159 return -EIO;
160 }
161 sum = analogix_dp_calc_edid_check_sum(&edid[EDID_BLOCK_LENGTH]);
162 if (sum != 0) {
163 dev_err(dp->dev, "EDID bad checksum!\n");
164 return -EIO;
165 }
166
167 analogix_dp_read_byte_from_dpcd(dp, DP_TEST_REQUEST,
168 &test_vector);
169 if (test_vector & DP_TEST_LINK_EDID_READ) {
170 analogix_dp_write_byte_to_dpcd(dp,
171 DP_TEST_EDID_CHECKSUM,
172 edid[EDID_BLOCK_LENGTH + EDID_CHECKSUM]);
173 analogix_dp_write_byte_to_dpcd(dp,
174 DP_TEST_RESPONSE,
175 DP_TEST_EDID_CHECKSUM_WRITE);
176 }
177 } else {
178 dev_info(dp->dev, "EDID data does not include any extensions.\n");
179
180 /* Read EDID data */
181 retval = analogix_dp_read_bytes_from_i2c(dp,
182 I2C_EDID_DEVICE_ADDR, EDID_HEADER_PATTERN,
183 EDID_BLOCK_LENGTH, &edid[EDID_HEADER_PATTERN]);
184 if (retval != 0) {
185 dev_err(dp->dev, "EDID Read failed!\n");
186 return -EIO;
187 }
188 sum = analogix_dp_calc_edid_check_sum(edid);
189 if (sum != 0) {
190 dev_err(dp->dev, "EDID bad checksum!\n");
191 return -EIO;
192 }
193
194 analogix_dp_read_byte_from_dpcd(dp, DP_TEST_REQUEST,
195 &test_vector);
196 if (test_vector & DP_TEST_LINK_EDID_READ) {
197 analogix_dp_write_byte_to_dpcd(dp,
198 DP_TEST_EDID_CHECKSUM, edid[EDID_CHECKSUM]);
199 analogix_dp_write_byte_to_dpcd(dp,
200 DP_TEST_RESPONSE, DP_TEST_EDID_CHECKSUM_WRITE);
201 }
202 }
203
204 dev_dbg(dp->dev, "EDID Read success!\n");
205 return 0;
206}
207
208static int analogix_dp_handle_edid(struct analogix_dp_device *dp)
209{
210 u8 buf[12];
211 int i;
212 int retval;
213
214 /* Read DPCD DP_DPCD_REV~RECEIVE_PORT1_CAP_1 */
215 retval = analogix_dp_read_bytes_from_dpcd(dp, DP_DPCD_REV, 12, buf);
216 if (retval)
217 return retval;
218
219 /* Read EDID */
220 for (i = 0; i < 3; i++) {
221 retval = analogix_dp_read_edid(dp);
222 if (!retval)
223 break;
224 }
225
226 return retval;
227}
228
229static void
230analogix_dp_enable_rx_to_enhanced_mode(struct analogix_dp_device *dp,
231 bool enable)
232{
233 u8 data;
234
235 analogix_dp_read_byte_from_dpcd(dp, DP_LANE_COUNT_SET, &data);
236
237 if (enable)
238 analogix_dp_write_byte_to_dpcd(dp, DP_LANE_COUNT_SET,
239 DP_LANE_COUNT_ENHANCED_FRAME_EN |
240 DPCD_LANE_COUNT_SET(data));
241 else
242 analogix_dp_write_byte_to_dpcd(dp, DP_LANE_COUNT_SET,
243 DPCD_LANE_COUNT_SET(data));
244}
245
246static int analogix_dp_is_enhanced_mode_available(struct analogix_dp_device *dp)
247{
248 u8 data;
249 int retval;
250
251 analogix_dp_read_byte_from_dpcd(dp, DP_MAX_LANE_COUNT, &data);
252 retval = DPCD_ENHANCED_FRAME_CAP(data);
253
254 return retval;
255}
256
257static void analogix_dp_set_enhanced_mode(struct analogix_dp_device *dp)
258{
259 u8 data;
260
261 data = analogix_dp_is_enhanced_mode_available(dp);
262 analogix_dp_enable_rx_to_enhanced_mode(dp, data);
263 analogix_dp_enable_enhanced_mode(dp, data);
264}
265
266static void analogix_dp_training_pattern_dis(struct analogix_dp_device *dp)
267{
268 analogix_dp_set_training_pattern(dp, DP_NONE);
269
270 analogix_dp_write_byte_to_dpcd(dp, DP_TRAINING_PATTERN_SET,
271 DP_TRAINING_PATTERN_DISABLE);
272}
273
274static void
275analogix_dp_set_lane_lane_pre_emphasis(struct analogix_dp_device *dp,
276 int pre_emphasis, int lane)
277{
278 switch (lane) {
279 case 0:
280 analogix_dp_set_lane0_pre_emphasis(dp, pre_emphasis);
281 break;
282 case 1:
283 analogix_dp_set_lane1_pre_emphasis(dp, pre_emphasis);
284 break;
285
286 case 2:
287 analogix_dp_set_lane2_pre_emphasis(dp, pre_emphasis);
288 break;
289
290 case 3:
291 analogix_dp_set_lane3_pre_emphasis(dp, pre_emphasis);
292 break;
293 }
294}
295
296static int analogix_dp_link_start(struct analogix_dp_device *dp)
297{
298 u8 buf[4];
299 int lane, lane_count, pll_tries, retval;
300
301 lane_count = dp->link_train.lane_count;
302
303 dp->link_train.lt_state = CLOCK_RECOVERY;
304 dp->link_train.eq_loop = 0;
305
306 for (lane = 0; lane < lane_count; lane++)
307 dp->link_train.cr_loop[lane] = 0;
308
309 /* Set link rate and count as you want to establish*/
310 analogix_dp_set_link_bandwidth(dp, dp->link_train.link_rate);
311 analogix_dp_set_lane_count(dp, dp->link_train.lane_count);
312
313 /* Setup RX configuration */
314 buf[0] = dp->link_train.link_rate;
315 buf[1] = dp->link_train.lane_count;
316 retval = analogix_dp_write_bytes_to_dpcd(dp, DP_LINK_BW_SET, 2, buf);
317 if (retval)
318 return retval;
319
320 /* Set TX pre-emphasis to minimum */
321 for (lane = 0; lane < lane_count; lane++)
322 analogix_dp_set_lane_lane_pre_emphasis(dp,
323 PRE_EMPHASIS_LEVEL_0, lane);
324
325 /* Wait for PLL lock */
326 pll_tries = 0;
327 while (analogix_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
328 if (pll_tries == DP_TIMEOUT_LOOP_COUNT) {
329 dev_err(dp->dev, "Wait for PLL lock timed out\n");
330 return -ETIMEDOUT;
331 }
332
333 pll_tries++;
334 usleep_range(90, 120);
335 }
336
337 /* Set training pattern 1 */
338 analogix_dp_set_training_pattern(dp, TRAINING_PTN1);
339
340 /* Set RX training pattern */
341 retval = analogix_dp_write_byte_to_dpcd(dp,
342 DP_TRAINING_PATTERN_SET,
343 DP_LINK_SCRAMBLING_DISABLE | DP_TRAINING_PATTERN_1);
344 if (retval)
345 return retval;
346
347 for (lane = 0; lane < lane_count; lane++)
348 buf[lane] = DP_TRAIN_PRE_EMPH_LEVEL_0 |
349 DP_TRAIN_VOLTAGE_SWING_LEVEL_0;
350
351 retval = analogix_dp_write_bytes_to_dpcd(dp, DP_TRAINING_LANE0_SET,
352 lane_count, buf);
353
354 return retval;
355}
356
357static unsigned char analogix_dp_get_lane_status(u8 link_status[2], int lane)
358{
359 int shift = (lane & 1) * 4;
360 u8 link_value = link_status[lane >> 1];
361
362 return (link_value >> shift) & 0xf;
363}
364
365static int analogix_dp_clock_recovery_ok(u8 link_status[2], int lane_count)
366{
367 int lane;
368 u8 lane_status;
369
370 for (lane = 0; lane < lane_count; lane++) {
371 lane_status = analogix_dp_get_lane_status(link_status, lane);
372 if ((lane_status & DP_LANE_CR_DONE) == 0)
373 return -EINVAL;
374 }
375 return 0;
376}
377
378static int analogix_dp_channel_eq_ok(u8 link_status[2], u8 link_align,
379 int lane_count)
380{
381 int lane;
382 u8 lane_status;
383
384 if ((link_align & DP_INTERLANE_ALIGN_DONE) == 0)
385 return -EINVAL;
386
387 for (lane = 0; lane < lane_count; lane++) {
388 lane_status = analogix_dp_get_lane_status(link_status, lane);
389 lane_status &= DP_CHANNEL_EQ_BITS;
390 if (lane_status != DP_CHANNEL_EQ_BITS)
391 return -EINVAL;
392 }
393
394 return 0;
395}
396
397static unsigned char
398analogix_dp_get_adjust_request_voltage(u8 adjust_request[2], int lane)
399{
400 int shift = (lane & 1) * 4;
401 u8 link_value = adjust_request[lane >> 1];
402
403 return (link_value >> shift) & 0x3;
404}
405
406static unsigned char analogix_dp_get_adjust_request_pre_emphasis(
407 u8 adjust_request[2],
408 int lane)
409{
410 int shift = (lane & 1) * 4;
411 u8 link_value = adjust_request[lane >> 1];
412
413 return ((link_value >> shift) & 0xc) >> 2;
414}
415
416static void analogix_dp_set_lane_link_training(struct analogix_dp_device *dp,
417 u8 training_lane_set, int lane)
418{
419 switch (lane) {
420 case 0:
421 analogix_dp_set_lane0_link_training(dp, training_lane_set);
422 break;
423 case 1:
424 analogix_dp_set_lane1_link_training(dp, training_lane_set);
425 break;
426
427 case 2:
428 analogix_dp_set_lane2_link_training(dp, training_lane_set);
429 break;
430
431 case 3:
432 analogix_dp_set_lane3_link_training(dp, training_lane_set);
433 break;
434 }
435}
436
437static unsigned int
438analogix_dp_get_lane_link_training(struct analogix_dp_device *dp,
439 int lane)
440{
441 u32 reg;
442
443 switch (lane) {
444 case 0:
445 reg = analogix_dp_get_lane0_link_training(dp);
446 break;
447 case 1:
448 reg = analogix_dp_get_lane1_link_training(dp);
449 break;
450 case 2:
451 reg = analogix_dp_get_lane2_link_training(dp);
452 break;
453 case 3:
454 reg = analogix_dp_get_lane3_link_training(dp);
455 break;
456 default:
457 WARN_ON(1);
458 return 0;
459 }
460
461 return reg;
462}
463
464static void analogix_dp_reduce_link_rate(struct analogix_dp_device *dp)
465{
466 analogix_dp_training_pattern_dis(dp);
467 analogix_dp_set_enhanced_mode(dp);
468
469 dp->link_train.lt_state = FAILED;
470}
471
472static void analogix_dp_get_adjust_training_lane(struct analogix_dp_device *dp,
473 u8 adjust_request[2])
474{
475 int lane, lane_count;
476 u8 voltage_swing, pre_emphasis, training_lane;
477
478 lane_count = dp->link_train.lane_count;
479 for (lane = 0; lane < lane_count; lane++) {
480 voltage_swing = analogix_dp_get_adjust_request_voltage(
481 adjust_request, lane);
482 pre_emphasis = analogix_dp_get_adjust_request_pre_emphasis(
483 adjust_request, lane);
484 training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
485 DPCD_PRE_EMPHASIS_SET(pre_emphasis);
486
487 if (voltage_swing == VOLTAGE_LEVEL_3)
488 training_lane |= DP_TRAIN_MAX_SWING_REACHED;
489 if (pre_emphasis == PRE_EMPHASIS_LEVEL_3)
490 training_lane |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
491
492 dp->link_train.training_lane[lane] = training_lane;
493 }
494}
495
496static int analogix_dp_process_clock_recovery(struct analogix_dp_device *dp)
497{
498 int lane, lane_count, retval;
499 u8 voltage_swing, pre_emphasis, training_lane;
500 u8 link_status[2], adjust_request[2];
501
502 usleep_range(100, 101);
503
504 lane_count = dp->link_train.lane_count;
505
506 retval = analogix_dp_read_bytes_from_dpcd(dp,
507 DP_LANE0_1_STATUS, 2, link_status);
508 if (retval)
509 return retval;
510
511 retval = analogix_dp_read_bytes_from_dpcd(dp,
512 DP_ADJUST_REQUEST_LANE0_1, 2, adjust_request);
513 if (retval)
514 return retval;
515
516 if (analogix_dp_clock_recovery_ok(link_status, lane_count) == 0) {
517 /* set training pattern 2 for EQ */
518 analogix_dp_set_training_pattern(dp, TRAINING_PTN2);
519
520 retval = analogix_dp_write_byte_to_dpcd(dp,
521 DP_TRAINING_PATTERN_SET,
522 DP_LINK_SCRAMBLING_DISABLE |
523 DP_TRAINING_PATTERN_2);
524 if (retval)
525 return retval;
526
527 dev_info(dp->dev, "Link Training Clock Recovery success\n");
528 dp->link_train.lt_state = EQUALIZER_TRAINING;
529 } else {
530 for (lane = 0; lane < lane_count; lane++) {
531 training_lane = analogix_dp_get_lane_link_training(
532 dp, lane);
533 voltage_swing = analogix_dp_get_adjust_request_voltage(
534 adjust_request, lane);
535 pre_emphasis = analogix_dp_get_adjust_request_pre_emphasis(
536 adjust_request, lane);
537
538 if (DPCD_VOLTAGE_SWING_GET(training_lane) ==
539 voltage_swing &&
540 DPCD_PRE_EMPHASIS_GET(training_lane) ==
541 pre_emphasis)
542 dp->link_train.cr_loop[lane]++;
543
544 if (dp->link_train.cr_loop[lane] == MAX_CR_LOOP ||
545 voltage_swing == VOLTAGE_LEVEL_3 ||
546 pre_emphasis == PRE_EMPHASIS_LEVEL_3) {
547 dev_err(dp->dev, "CR Max reached (%d,%d,%d)\n",
548 dp->link_train.cr_loop[lane],
549 voltage_swing, pre_emphasis);
550 analogix_dp_reduce_link_rate(dp);
551 return -EIO;
552 }
553 }
554 }
555
556 analogix_dp_get_adjust_training_lane(dp, adjust_request);
557
558 for (lane = 0; lane < lane_count; lane++)
559 analogix_dp_set_lane_link_training(dp,
560 dp->link_train.training_lane[lane], lane);
561
562 retval = analogix_dp_write_bytes_to_dpcd(dp,
563 DP_TRAINING_LANE0_SET, lane_count,
564 dp->link_train.training_lane);
565 if (retval)
566 return retval;
567
568 return retval;
569}
570
571static int analogix_dp_process_equalizer_training(struct analogix_dp_device *dp)
572{
573 int lane, lane_count, retval;
574 u32 reg;
575 u8 link_align, link_status[2], adjust_request[2];
576
577 usleep_range(400, 401);
578
579 lane_count = dp->link_train.lane_count;
580
581 retval = analogix_dp_read_bytes_from_dpcd(dp,
582 DP_LANE0_1_STATUS, 2, link_status);
583 if (retval)
584 return retval;
585
586 if (analogix_dp_clock_recovery_ok(link_status, lane_count)) {
587 analogix_dp_reduce_link_rate(dp);
588 return -EIO;
589 }
590
591 retval = analogix_dp_read_bytes_from_dpcd(dp,
592 DP_ADJUST_REQUEST_LANE0_1, 2, adjust_request);
593 if (retval)
594 return retval;
595
596 retval = analogix_dp_read_byte_from_dpcd(dp,
597 DP_LANE_ALIGN_STATUS_UPDATED, &link_align);
598 if (retval)
599 return retval;
600
601 analogix_dp_get_adjust_training_lane(dp, adjust_request);
602
603 if (!analogix_dp_channel_eq_ok(link_status, link_align, lane_count)) {
604 /* traing pattern Set to Normal */
605 analogix_dp_training_pattern_dis(dp);
606
607 dev_info(dp->dev, "Link Training success!\n");
608
609 analogix_dp_get_link_bandwidth(dp, &reg);
610 dp->link_train.link_rate = reg;
611 dev_dbg(dp->dev, "final bandwidth = %.2x\n",
612 dp->link_train.link_rate);
613
614 analogix_dp_get_lane_count(dp, &reg);
615 dp->link_train.lane_count = reg;
616 dev_dbg(dp->dev, "final lane count = %.2x\n",
617 dp->link_train.lane_count);
618
619 /* set enhanced mode if available */
620 analogix_dp_set_enhanced_mode(dp);
621 dp->link_train.lt_state = FINISHED;
622
623 return 0;
624 }
625
626 /* not all locked */
627 dp->link_train.eq_loop++;
628
629 if (dp->link_train.eq_loop > MAX_EQ_LOOP) {
630 dev_err(dp->dev, "EQ Max loop\n");
631 analogix_dp_reduce_link_rate(dp);
632 return -EIO;
633 }
634
635 for (lane = 0; lane < lane_count; lane++)
636 analogix_dp_set_lane_link_training(dp,
637 dp->link_train.training_lane[lane], lane);
638
639 retval = analogix_dp_write_bytes_to_dpcd(dp, DP_TRAINING_LANE0_SET,
640 lane_count, dp->link_train.training_lane);
641
642 return retval;
643}
644
645static void analogix_dp_get_max_rx_bandwidth(struct analogix_dp_device *dp,
646 u8 *bandwidth)
647{
648 u8 data;
649
650 /*
651 * For DP rev.1.1, Maximum link rate of Main Link lanes
652 * 0x06 = 1.62 Gbps, 0x0a = 2.7 Gbps
653 * For DP rev.1.2, Maximum link rate of Main Link lanes
654 * 0x06 = 1.62 Gbps, 0x0a = 2.7 Gbps, 0x14 = 5.4Gbps
655 */
656 analogix_dp_read_byte_from_dpcd(dp, DP_MAX_LINK_RATE, &data);
657 *bandwidth = data;
658}
659
660static void analogix_dp_get_max_rx_lane_count(struct analogix_dp_device *dp,
661 u8 *lane_count)
662{
663 u8 data;
664
665 /*
666 * For DP rev.1.1, Maximum number of Main Link lanes
667 * 0x01 = 1 lane, 0x02 = 2 lanes, 0x04 = 4 lanes
668 */
669 analogix_dp_read_byte_from_dpcd(dp, DP_MAX_LANE_COUNT, &data);
670 *lane_count = DPCD_MAX_LANE_COUNT(data);
671}
672
673static void analogix_dp_init_training(struct analogix_dp_device *dp,
674 enum link_lane_count_type max_lane,
675 int max_rate)
676{
677 /*
678 * MACRO_RST must be applied after the PLL_LOCK to avoid
679 * the DP inter pair skew issue for at least 10 us
680 */
681 analogix_dp_reset_macro(dp);
682
683 /* Initialize by reading RX's DPCD */
684 analogix_dp_get_max_rx_bandwidth(dp, &dp->link_train.link_rate);
685 analogix_dp_get_max_rx_lane_count(dp, &dp->link_train.lane_count);
686
687 if ((dp->link_train.link_rate != DP_LINK_BW_1_62) &&
688 (dp->link_train.link_rate != DP_LINK_BW_2_7) &&
689 (dp->link_train.link_rate != DP_LINK_BW_5_4)) {
690 dev_err(dp->dev, "Rx Max Link Rate is abnormal :%x !\n",
691 dp->link_train.link_rate);
692 dp->link_train.link_rate = DP_LINK_BW_1_62;
693 }
694
695 if (dp->link_train.lane_count == 0) {
696 dev_err(dp->dev, "Rx Max Lane count is abnormal :%x !\n",
697 dp->link_train.lane_count);
698 dp->link_train.lane_count = (u8)LANE_COUNT1;
699 }
700
701 /* Setup TX lane count & rate */
702 if (dp->link_train.lane_count > max_lane)
703 dp->link_train.lane_count = max_lane;
704 if (dp->link_train.link_rate > max_rate)
705 dp->link_train.link_rate = max_rate;
706
707 /* All DP analog module power up */
708 analogix_dp_set_analog_power_down(dp, POWER_ALL, 0);
709}
710
711static int analogix_dp_sw_link_training(struct analogix_dp_device *dp)
712{
713 int retval = 0, training_finished = 0;
714
715 dp->link_train.lt_state = START;
716
717 /* Process here */
718 while (!retval && !training_finished) {
719 switch (dp->link_train.lt_state) {
720 case START:
721 retval = analogix_dp_link_start(dp);
722 if (retval)
723 dev_err(dp->dev, "LT link start failed!\n");
724 break;
725 case CLOCK_RECOVERY:
726 retval = analogix_dp_process_clock_recovery(dp);
727 if (retval)
728 dev_err(dp->dev, "LT CR failed!\n");
729 break;
730 case EQUALIZER_TRAINING:
731 retval = analogix_dp_process_equalizer_training(dp);
732 if (retval)
733 dev_err(dp->dev, "LT EQ failed!\n");
734 break;
735 case FINISHED:
736 training_finished = 1;
737 break;
738 case FAILED:
739 return -EREMOTEIO;
740 }
741 }
742 if (retval)
743 dev_err(dp->dev, "eDP link training failed (%d)\n", retval);
744
745 return retval;
746}
747
748static int analogix_dp_set_link_train(struct analogix_dp_device *dp,
749 u32 count, u32 bwtype)
750{
751 int i;
752 int retval;
753
754 for (i = 0; i < DP_TIMEOUT_LOOP_COUNT; i++) {
755 analogix_dp_init_training(dp, count, bwtype);
756 retval = analogix_dp_sw_link_training(dp);
757 if (retval == 0)
758 break;
759
760 usleep_range(100, 110);
761 }
762
763 return retval;
764}
765
766static int analogix_dp_config_video(struct analogix_dp_device *dp)
767{
768 int retval = 0;
769 int timeout_loop = 0;
770 int done_count = 0;
771
772 analogix_dp_config_video_slave_mode(dp);
773
774 analogix_dp_set_video_color_format(dp);
775
776 if (analogix_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
777 dev_err(dp->dev, "PLL is not locked yet.\n");
778 return -EINVAL;
779 }
780
781 for (;;) {
782 timeout_loop++;
783 if (analogix_dp_is_slave_video_stream_clock_on(dp) == 0)
784 break;
785 if (timeout_loop > DP_TIMEOUT_LOOP_COUNT) {
786 dev_err(dp->dev, "Timeout of video streamclk ok\n");
787 return -ETIMEDOUT;
788 }
789
790 usleep_range(1, 2);
791 }
792
793 /* Set to use the register calculated M/N video */
794 analogix_dp_set_video_cr_mn(dp, CALCULATED_M, 0, 0);
795
796 /* For video bist, Video timing must be generated by register */
797 analogix_dp_set_video_timing_mode(dp, VIDEO_TIMING_FROM_CAPTURE);
798
799 /* Disable video mute */
800 analogix_dp_enable_video_mute(dp, 0);
801
802 /* Configure video slave mode */
803 analogix_dp_enable_video_master(dp, 0);
804
805 timeout_loop = 0;
806
807 for (;;) {
808 timeout_loop++;
809 if (analogix_dp_is_video_stream_on(dp) == 0) {
810 done_count++;
811 if (done_count > 10)
812 break;
813 } else if (done_count) {
814 done_count = 0;
815 }
816 if (timeout_loop > DP_TIMEOUT_LOOP_COUNT) {
817 dev_err(dp->dev, "Timeout of video streamclk ok\n");
818 return -ETIMEDOUT;
819 }
820
821 usleep_range(1000, 1001);
822 }
823
824 if (retval != 0)
825 dev_err(dp->dev, "Video stream is not detected!\n");
826
827 return retval;
828}
829
830static void analogix_dp_enable_scramble(struct analogix_dp_device *dp,
831 bool enable)
832{
833 u8 data;
834
835 if (enable) {
836 analogix_dp_enable_scrambling(dp);
837
838 analogix_dp_read_byte_from_dpcd(dp, DP_TRAINING_PATTERN_SET,
839 &data);
840 analogix_dp_write_byte_to_dpcd(dp,
841 DP_TRAINING_PATTERN_SET,
842 (u8)(data & ~DP_LINK_SCRAMBLING_DISABLE));
843 } else {
844 analogix_dp_disable_scrambling(dp);
845
846 analogix_dp_read_byte_from_dpcd(dp, DP_TRAINING_PATTERN_SET,
847 &data);
848 analogix_dp_write_byte_to_dpcd(dp,
849 DP_TRAINING_PATTERN_SET,
850 (u8)(data | DP_LINK_SCRAMBLING_DISABLE));
851 }
852}
853
854static irqreturn_t analogix_dp_hardirq(int irq, void *arg)
855{
856 struct analogix_dp_device *dp = arg;
857 irqreturn_t ret = IRQ_NONE;
858 enum dp_irq_type irq_type;
859
860 irq_type = analogix_dp_get_irq_type(dp);
861 if (irq_type != DP_IRQ_TYPE_UNKNOWN) {
862 analogix_dp_mute_hpd_interrupt(dp);
863 ret = IRQ_WAKE_THREAD;
864 }
865
866 return ret;
867}
868
869static irqreturn_t analogix_dp_irq_thread(int irq, void *arg)
870{
871 struct analogix_dp_device *dp = arg;
872 enum dp_irq_type irq_type;
873
874 irq_type = analogix_dp_get_irq_type(dp);
875 if (irq_type & DP_IRQ_TYPE_HP_CABLE_IN ||
876 irq_type & DP_IRQ_TYPE_HP_CABLE_OUT) {
877 dev_dbg(dp->dev, "Detected cable status changed!\n");
878 if (dp->drm_dev)
879 drm_helper_hpd_irq_event(dp->drm_dev);
880 }
881
882 if (irq_type != DP_IRQ_TYPE_UNKNOWN) {
883 analogix_dp_clear_hotplug_interrupts(dp);
884 analogix_dp_unmute_hpd_interrupt(dp);
885 }
886
887 return IRQ_HANDLED;
888}
889
890static void analogix_dp_commit(struct analogix_dp_device *dp)
891{
892 int ret;
893
894 /* Keep the panel disabled while we configure video */
895 if (dp->plat_data->panel) {
896 if (drm_panel_disable(dp->plat_data->panel))
897 DRM_ERROR("failed to disable the panel\n");
898 }
899
900 ret = analogix_dp_set_link_train(dp, dp->video_info.max_lane_count,
901 dp->video_info.max_link_rate);
902 if (ret) {
903 dev_err(dp->dev, "unable to do link train\n");
904 return;
905 }
906
907 analogix_dp_enable_scramble(dp, 1);
908 analogix_dp_enable_rx_to_enhanced_mode(dp, 1);
909 analogix_dp_enable_enhanced_mode(dp, 1);
910
911 analogix_dp_init_video(dp);
912 ret = analogix_dp_config_video(dp);
913 if (ret)
914 dev_err(dp->dev, "unable to config video\n");
915
916 /* Safe to enable the panel now */
917 if (dp->plat_data->panel) {
918 if (drm_panel_enable(dp->plat_data->panel))
919 DRM_ERROR("failed to enable the panel\n");
920 }
921
922 /* Enable video */
923 analogix_dp_start_video(dp);
924}
925
926int analogix_dp_get_modes(struct drm_connector *connector)
927{
928 struct analogix_dp_device *dp = to_dp(connector);
929 struct edid *edid = (struct edid *)dp->edid;
930 int num_modes = 0;
931
932 if (analogix_dp_handle_edid(dp) == 0) {
933 drm_mode_connector_update_edid_property(&dp->connector, edid);
934 num_modes += drm_add_edid_modes(&dp->connector, edid);
935 }
936
937 if (dp->plat_data->panel)
938 num_modes += drm_panel_get_modes(dp->plat_data->panel);
939
940 if (dp->plat_data->get_modes)
941 num_modes += dp->plat_data->get_modes(dp->plat_data);
942
943 return num_modes;
944}
945
946static struct drm_encoder *
947analogix_dp_best_encoder(struct drm_connector *connector)
948{
949 struct analogix_dp_device *dp = to_dp(connector);
950
951 return dp->encoder;
952}
953
954static const struct drm_connector_helper_funcs analogix_dp_connector_helper_funcs = {
955 .get_modes = analogix_dp_get_modes,
956 .best_encoder = analogix_dp_best_encoder,
957};
958
959enum drm_connector_status
960analogix_dp_detect(struct drm_connector *connector, bool force)
961{
962 struct analogix_dp_device *dp = to_dp(connector);
963
964 if (analogix_dp_detect_hpd(dp))
965 return connector_status_disconnected;
966
967 return connector_status_connected;
968}
969
970static void analogix_dp_connector_destroy(struct drm_connector *connector)
971{
972 drm_connector_unregister(connector);
973 drm_connector_cleanup(connector);
974
975}
976
977static const struct drm_connector_funcs analogix_dp_connector_funcs = {
978 .dpms = drm_atomic_helper_connector_dpms,
979 .fill_modes = drm_helper_probe_single_connector_modes,
980 .detect = analogix_dp_detect,
981 .destroy = analogix_dp_connector_destroy,
982 .reset = drm_atomic_helper_connector_reset,
983 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
984 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
985};
986
987static int analogix_dp_bridge_attach(struct drm_bridge *bridge)
988{
989 struct analogix_dp_device *dp = bridge->driver_private;
990 struct drm_encoder *encoder = dp->encoder;
991 struct drm_connector *connector = &dp->connector;
992 int ret;
993
994 if (!bridge->encoder) {
995 DRM_ERROR("Parent encoder object not found");
996 return -ENODEV;
997 }
998
999 connector->polled = DRM_CONNECTOR_POLL_HPD;
1000
1001 ret = drm_connector_init(dp->drm_dev, connector,
1002 &analogix_dp_connector_funcs,
1003 DRM_MODE_CONNECTOR_eDP);
1004 if (ret) {
1005 DRM_ERROR("Failed to initialize connector with drm\n");
1006 return ret;
1007 }
1008
1009 drm_connector_helper_add(connector,
1010 &analogix_dp_connector_helper_funcs);
1011 drm_mode_connector_attach_encoder(connector, encoder);
1012
1013 /*
1014 * NOTE: the connector registration is implemented in analogix
1015 * platform driver, that to say connector would be exist after
1016 * plat_data->attch return, that's why we record the connector
1017 * point after plat attached.
1018 */
1019 if (dp->plat_data->attach) {
1020 ret = dp->plat_data->attach(dp->plat_data, bridge, connector);
1021 if (ret) {
1022 DRM_ERROR("Failed at platform attch func\n");
1023 return ret;
1024 }
1025 }
1026
1027 if (dp->plat_data->panel) {
1028 ret = drm_panel_attach(dp->plat_data->panel, &dp->connector);
1029 if (ret) {
1030 DRM_ERROR("Failed to attach panel\n");
1031 return ret;
1032 }
1033 }
1034
1035 return 0;
1036}
1037
1038static void analogix_dp_bridge_enable(struct drm_bridge *bridge)
1039{
1040 struct analogix_dp_device *dp = bridge->driver_private;
1041
1042 if (dp->dpms_mode == DRM_MODE_DPMS_ON)
1043 return;
1044
1045 pm_runtime_get_sync(dp->dev);
1046
1047 if (dp->plat_data->power_on)
1048 dp->plat_data->power_on(dp->plat_data);
1049
1050 phy_power_on(dp->phy);
1051 analogix_dp_init_dp(dp);
1052 enable_irq(dp->irq);
1053 analogix_dp_commit(dp);
1054
1055 dp->dpms_mode = DRM_MODE_DPMS_ON;
1056}
1057
1058static void analogix_dp_bridge_disable(struct drm_bridge *bridge)
1059{
1060 struct analogix_dp_device *dp = bridge->driver_private;
1061
1062 if (dp->dpms_mode != DRM_MODE_DPMS_ON)
1063 return;
1064
1065 if (dp->plat_data->panel) {
1066 if (drm_panel_disable(dp->plat_data->panel)) {
1067 DRM_ERROR("failed to disable the panel\n");
1068 return;
1069 }
1070 }
1071
1072 disable_irq(dp->irq);
1073 phy_power_off(dp->phy);
1074
1075 if (dp->plat_data->power_off)
1076 dp->plat_data->power_off(dp->plat_data);
1077
1078 pm_runtime_put_sync(dp->dev);
1079
1080 dp->dpms_mode = DRM_MODE_DPMS_OFF;
1081}
1082
1083static void analogix_dp_bridge_mode_set(struct drm_bridge *bridge,
1084 struct drm_display_mode *orig_mode,
1085 struct drm_display_mode *mode)
1086{
1087 struct analogix_dp_device *dp = bridge->driver_private;
1088 struct drm_display_info *display_info = &dp->connector.display_info;
1089 struct video_info *video = &dp->video_info;
1090 struct device_node *dp_node = dp->dev->of_node;
1091 int vic;
1092
1093 /* Input video interlaces & hsync pol & vsync pol */
1094 video->interlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE);
1095 video->v_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NVSYNC);
1096 video->h_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NHSYNC);
1097
1098 /* Input video dynamic_range & colorimetry */
1099 vic = drm_match_cea_mode(mode);
1100 if ((vic == 6) || (vic == 7) || (vic == 21) || (vic == 22) ||
1101 (vic == 2) || (vic == 3) || (vic == 17) || (vic == 18)) {
1102 video->dynamic_range = CEA;
1103 video->ycbcr_coeff = COLOR_YCBCR601;
1104 } else if (vic) {
1105 video->dynamic_range = CEA;
1106 video->ycbcr_coeff = COLOR_YCBCR709;
1107 } else {
1108 video->dynamic_range = VESA;
1109 video->ycbcr_coeff = COLOR_YCBCR709;
1110 }
1111
1112 /* Input vide bpc and color_formats */
1113 switch (display_info->bpc) {
1114 case 12:
1115 video->color_depth = COLOR_12;
1116 break;
1117 case 10:
1118 video->color_depth = COLOR_10;
1119 break;
1120 case 8:
1121 video->color_depth = COLOR_8;
1122 break;
1123 case 6:
1124 video->color_depth = COLOR_6;
1125 break;
1126 default:
1127 video->color_depth = COLOR_8;
1128 break;
1129 }
1130 if (display_info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
1131 video->color_space = COLOR_YCBCR444;
1132 else if (display_info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
1133 video->color_space = COLOR_YCBCR422;
1134 else if (display_info->color_formats & DRM_COLOR_FORMAT_RGB444)
1135 video->color_space = COLOR_RGB;
1136 else
1137 video->color_space = COLOR_RGB;
1138
1139 /*
1140 * NOTE: those property parsing code is used for providing backward
1141 * compatibility for samsung platform.
1142 * Due to we used the "of_property_read_u32" interfaces, when this
1143 * property isn't present, the "video_info" can keep the original
1144 * values and wouldn't be modified.
1145 */
1146 of_property_read_u32(dp_node, "samsung,color-space",
1147 &video->color_space);
1148 of_property_read_u32(dp_node, "samsung,dynamic-range",
1149 &video->dynamic_range);
1150 of_property_read_u32(dp_node, "samsung,ycbcr-coeff",
1151 &video->ycbcr_coeff);
1152 of_property_read_u32(dp_node, "samsung,color-depth",
1153 &video->color_depth);
1154 if (of_property_read_bool(dp_node, "hsync-active-high"))
1155 video->h_sync_polarity = true;
1156 if (of_property_read_bool(dp_node, "vsync-active-high"))
1157 video->v_sync_polarity = true;
1158 if (of_property_read_bool(dp_node, "interlaced"))
1159 video->interlaced = true;
1160}
1161
1162static void analogix_dp_bridge_nop(struct drm_bridge *bridge)
1163{
1164 /* do nothing */
1165}
1166
1167static const struct drm_bridge_funcs analogix_dp_bridge_funcs = {
1168 .enable = analogix_dp_bridge_enable,
1169 .disable = analogix_dp_bridge_disable,
1170 .pre_enable = analogix_dp_bridge_nop,
1171 .post_disable = analogix_dp_bridge_nop,
1172 .mode_set = analogix_dp_bridge_mode_set,
1173 .attach = analogix_dp_bridge_attach,
1174};
1175
1176static int analogix_dp_create_bridge(struct drm_device *drm_dev,
1177 struct analogix_dp_device *dp)
1178{
1179 struct drm_bridge *bridge;
1180 int ret;
1181
1182 bridge = devm_kzalloc(drm_dev->dev, sizeof(*bridge), GFP_KERNEL);
1183 if (!bridge) {
1184 DRM_ERROR("failed to allocate for drm bridge\n");
1185 return -ENOMEM;
1186 }
1187
1188 dp->bridge = bridge;
1189
1190 dp->encoder->bridge = bridge;
1191 bridge->driver_private = dp;
1192 bridge->encoder = dp->encoder;
1193 bridge->funcs = &analogix_dp_bridge_funcs;
1194
1195 ret = drm_bridge_attach(drm_dev, bridge);
1196 if (ret) {
1197 DRM_ERROR("failed to attach drm bridge\n");
1198 return -EINVAL;
1199 }
1200
1201 return 0;
1202}
1203
1204static int analogix_dp_dt_parse_pdata(struct analogix_dp_device *dp)
1205{
1206 struct device_node *dp_node = dp->dev->of_node;
1207 struct video_info *video_info = &dp->video_info;
1208
1209 switch (dp->plat_data->dev_type) {
1210 case RK3288_DP:
1211 /*
1212 * Like Rk3288 DisplayPort TRM indicate that "Main link
1213 * containing 4 physical lanes of 2.7/1.62 Gbps/lane".
1214 */
1215 video_info->max_link_rate = 0x0A;
1216 video_info->max_lane_count = 0x04;
1217 break;
1218 case EXYNOS_DP:
1219 /*
1220 * NOTE: those property parseing code is used for
1221 * providing backward compatibility for samsung platform.
1222 */
1223 of_property_read_u32(dp_node, "samsung,link-rate",
1224 &video_info->max_link_rate);
1225 of_property_read_u32(dp_node, "samsung,lane-count",
1226 &video_info->max_lane_count);
1227 break;
1228 }
1229
1230 return 0;
1231}
1232
1233int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev,
1234 struct analogix_dp_plat_data *plat_data)
1235{
1236 struct platform_device *pdev = to_platform_device(dev);
1237 struct analogix_dp_device *dp;
1238 struct resource *res;
1239 unsigned int irq_flags;
1240 int ret;
1241
1242 if (!plat_data) {
1243 dev_err(dev, "Invalided input plat_data\n");
1244 return -EINVAL;
1245 }
1246
1247 dp = devm_kzalloc(dev, sizeof(struct analogix_dp_device), GFP_KERNEL);
1248 if (!dp)
1249 return -ENOMEM;
1250
1251 dev_set_drvdata(dev, dp);
1252
1253 dp->dev = &pdev->dev;
1254 dp->dpms_mode = DRM_MODE_DPMS_OFF;
1255
1256 /*
1257 * platform dp driver need containor_of the plat_data to get
1258 * the driver private data, so we need to store the point of
1259 * plat_data, not the context of plat_data.
1260 */
1261 dp->plat_data = plat_data;
1262
1263 ret = analogix_dp_dt_parse_pdata(dp);
1264 if (ret)
1265 return ret;
1266
1267 dp->phy = devm_phy_get(dp->dev, "dp");
1268 if (IS_ERR(dp->phy)) {
1269 dev_err(dp->dev, "no DP phy configured\n");
1270 ret = PTR_ERR(dp->phy);
1271 if (ret) {
1272 /*
1273 * phy itself is not enabled, so we can move forward
1274 * assigning NULL to phy pointer.
1275 */
1276 if (ret == -ENOSYS || ret == -ENODEV)
1277 dp->phy = NULL;
1278 else
1279 return ret;
1280 }
1281 }
1282
1283 dp->clock = devm_clk_get(&pdev->dev, "dp");
1284 if (IS_ERR(dp->clock)) {
1285 dev_err(&pdev->dev, "failed to get clock\n");
1286 return PTR_ERR(dp->clock);
1287 }
1288
1289 clk_prepare_enable(dp->clock);
1290
1291 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1292
1293 dp->reg_base = devm_ioremap_resource(&pdev->dev, res);
1294 if (IS_ERR(dp->reg_base))
1295 return PTR_ERR(dp->reg_base);
1296
1297 dp->force_hpd = of_property_read_bool(dev->of_node, "force-hpd");
1298
1299 dp->hpd_gpio = of_get_named_gpio(dev->of_node, "hpd-gpios", 0);
1300 if (!gpio_is_valid(dp->hpd_gpio))
1301 dp->hpd_gpio = of_get_named_gpio(dev->of_node,
1302 "samsung,hpd-gpio", 0);
1303
1304 if (gpio_is_valid(dp->hpd_gpio)) {
1305 /*
1306 * Set up the hotplug GPIO from the device tree as an interrupt.
1307 * Simply specifying a different interrupt in the device tree
1308 * doesn't work since we handle hotplug rather differently when
1309 * using a GPIO. We also need the actual GPIO specifier so
1310 * that we can get the current state of the GPIO.
1311 */
1312 ret = devm_gpio_request_one(&pdev->dev, dp->hpd_gpio, GPIOF_IN,
1313 "hpd_gpio");
1314 if (ret) {
1315 dev_err(&pdev->dev, "failed to get hpd gpio\n");
1316 return ret;
1317 }
1318 dp->irq = gpio_to_irq(dp->hpd_gpio);
1319 irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
1320 } else {
1321 dp->hpd_gpio = -ENODEV;
1322 dp->irq = platform_get_irq(pdev, 0);
1323 irq_flags = 0;
1324 }
1325
1326 if (dp->irq == -ENXIO) {
1327 dev_err(&pdev->dev, "failed to get irq\n");
1328 return -ENODEV;
1329 }
1330
1331 pm_runtime_enable(dev);
1332
1333 phy_power_on(dp->phy);
1334
1335 if (dp->plat_data->panel) {
1336 if (drm_panel_prepare(dp->plat_data->panel)) {
1337 DRM_ERROR("failed to setup the panel\n");
1338 return -EBUSY;
1339 }
1340 }
1341
1342 analogix_dp_init_dp(dp);
1343
1344 ret = devm_request_threaded_irq(&pdev->dev, dp->irq,
1345 analogix_dp_hardirq,
1346 analogix_dp_irq_thread,
1347 irq_flags, "analogix-dp", dp);
1348 if (ret) {
1349 dev_err(&pdev->dev, "failed to request irq\n");
1350 goto err_disable_pm_runtime;
1351 }
1352 disable_irq(dp->irq);
1353
1354 dp->drm_dev = drm_dev;
1355 dp->encoder = dp->plat_data->encoder;
1356
1357 ret = analogix_dp_create_bridge(drm_dev, dp);
1358 if (ret) {
1359 DRM_ERROR("failed to create bridge (%d)\n", ret);
1360 drm_encoder_cleanup(dp->encoder);
1361 goto err_disable_pm_runtime;
1362 }
1363
1364 return 0;
1365
1366err_disable_pm_runtime:
1367 pm_runtime_disable(dev);
1368
1369 return ret;
1370}
1371EXPORT_SYMBOL_GPL(analogix_dp_bind);
1372
1373void analogix_dp_unbind(struct device *dev, struct device *master,
1374 void *data)
1375{
1376 struct analogix_dp_device *dp = dev_get_drvdata(dev);
1377
1378 analogix_dp_bridge_disable(dp->bridge);
1379
1380 if (dp->plat_data->panel) {
1381 if (drm_panel_unprepare(dp->plat_data->panel))
1382 DRM_ERROR("failed to turnoff the panel\n");
1383 }
1384
1385 pm_runtime_disable(dev);
1386}
1387EXPORT_SYMBOL_GPL(analogix_dp_unbind);
1388
1389#ifdef CONFIG_PM
1390int analogix_dp_suspend(struct device *dev)
1391{
1392 struct analogix_dp_device *dp = dev_get_drvdata(dev);
1393
1394 clk_disable_unprepare(dp->clock);
1395
1396 if (dp->plat_data->panel) {
1397 if (drm_panel_unprepare(dp->plat_data->panel))
1398 DRM_ERROR("failed to turnoff the panel\n");
1399 }
1400
1401 return 0;
1402}
1403EXPORT_SYMBOL_GPL(analogix_dp_suspend);
1404
1405int analogix_dp_resume(struct device *dev)
1406{
1407 struct analogix_dp_device *dp = dev_get_drvdata(dev);
1408 int ret;
1409
1410 ret = clk_prepare_enable(dp->clock);
1411 if (ret < 0) {
1412 DRM_ERROR("Failed to prepare_enable the clock clk [%d]\n", ret);
1413 return ret;
1414 }
1415
1416 if (dp->plat_data->panel) {
1417 if (drm_panel_prepare(dp->plat_data->panel)) {
1418 DRM_ERROR("failed to setup the panel\n");
1419 return -EBUSY;
1420 }
1421 }
1422
1423 return 0;
1424}
1425EXPORT_SYMBOL_GPL(analogix_dp_resume);
1426#endif
1427
1428MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>");
1429MODULE_DESCRIPTION("Analogix DP Core Driver");
1430MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
new file mode 100644
index 000000000000..f09275d40f70
--- /dev/null
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
@@ -0,0 +1,281 @@
1/*
2 * Header file for Analogix DP (Display Port) core interface driver.
3 *
4 * Copyright (C) 2012 Samsung Electronics Co., Ltd.
5 * Author: Jingoo Han <jg1.han@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#ifndef _ANALOGIX_DP_CORE_H
14#define _ANALOGIX_DP_CORE_H
15
16#include <drm/drm_crtc.h>
17#include <drm/drm_dp_helper.h>
18
19#define DP_TIMEOUT_LOOP_COUNT 100
20#define MAX_CR_LOOP 5
21#define MAX_EQ_LOOP 5
22
23/* I2C EDID Chip ID, Slave Address */
24#define I2C_EDID_DEVICE_ADDR 0x50
25#define I2C_E_EDID_DEVICE_ADDR 0x30
26
27#define EDID_BLOCK_LENGTH 0x80
28#define EDID_HEADER_PATTERN 0x00
29#define EDID_EXTENSION_FLAG 0x7e
30#define EDID_CHECKSUM 0x7f
31
32/* DP_MAX_LANE_COUNT */
33#define DPCD_ENHANCED_FRAME_CAP(x) (((x) >> 7) & 0x1)
34#define DPCD_MAX_LANE_COUNT(x) ((x) & 0x1f)
35
36/* DP_LANE_COUNT_SET */
37#define DPCD_LANE_COUNT_SET(x) ((x) & 0x1f)
38
39/* DP_TRAINING_LANE0_SET */
40#define DPCD_PRE_EMPHASIS_SET(x) (((x) & 0x3) << 3)
41#define DPCD_PRE_EMPHASIS_GET(x) (((x) >> 3) & 0x3)
42#define DPCD_VOLTAGE_SWING_SET(x) (((x) & 0x3) << 0)
43#define DPCD_VOLTAGE_SWING_GET(x) (((x) >> 0) & 0x3)
44
45enum link_lane_count_type {
46 LANE_COUNT1 = 1,
47 LANE_COUNT2 = 2,
48 LANE_COUNT4 = 4
49};
50
51enum link_training_state {
52 START,
53 CLOCK_RECOVERY,
54 EQUALIZER_TRAINING,
55 FINISHED,
56 FAILED
57};
58
59enum voltage_swing_level {
60 VOLTAGE_LEVEL_0,
61 VOLTAGE_LEVEL_1,
62 VOLTAGE_LEVEL_2,
63 VOLTAGE_LEVEL_3,
64};
65
66enum pre_emphasis_level {
67 PRE_EMPHASIS_LEVEL_0,
68 PRE_EMPHASIS_LEVEL_1,
69 PRE_EMPHASIS_LEVEL_2,
70 PRE_EMPHASIS_LEVEL_3,
71};
72
73enum pattern_set {
74 PRBS7,
75 D10_2,
76 TRAINING_PTN1,
77 TRAINING_PTN2,
78 DP_NONE
79};
80
81enum color_space {
82 COLOR_RGB,
83 COLOR_YCBCR422,
84 COLOR_YCBCR444
85};
86
87enum color_depth {
88 COLOR_6,
89 COLOR_8,
90 COLOR_10,
91 COLOR_12
92};
93
94enum color_coefficient {
95 COLOR_YCBCR601,
96 COLOR_YCBCR709
97};
98
99enum dynamic_range {
100 VESA,
101 CEA
102};
103
104enum pll_status {
105 PLL_UNLOCKED,
106 PLL_LOCKED
107};
108
109enum clock_recovery_m_value_type {
110 CALCULATED_M,
111 REGISTER_M
112};
113
114enum video_timing_recognition_type {
115 VIDEO_TIMING_FROM_CAPTURE,
116 VIDEO_TIMING_FROM_REGISTER
117};
118
119enum analog_power_block {
120 AUX_BLOCK,
121 CH0_BLOCK,
122 CH1_BLOCK,
123 CH2_BLOCK,
124 CH3_BLOCK,
125 ANALOG_TOTAL,
126 POWER_ALL
127};
128
129enum dp_irq_type {
130 DP_IRQ_TYPE_HP_CABLE_IN,
131 DP_IRQ_TYPE_HP_CABLE_OUT,
132 DP_IRQ_TYPE_HP_CHANGE,
133 DP_IRQ_TYPE_UNKNOWN,
134};
135
136struct video_info {
137 char *name;
138
139 bool h_sync_polarity;
140 bool v_sync_polarity;
141 bool interlaced;
142
143 enum color_space color_space;
144 enum dynamic_range dynamic_range;
145 enum color_coefficient ycbcr_coeff;
146 enum color_depth color_depth;
147
148 int max_link_rate;
149 enum link_lane_count_type max_lane_count;
150};
151
152struct link_train {
153 int eq_loop;
154 int cr_loop[4];
155
156 u8 link_rate;
157 u8 lane_count;
158 u8 training_lane[4];
159
160 enum link_training_state lt_state;
161};
162
163struct analogix_dp_device {
164 struct drm_encoder *encoder;
165 struct device *dev;
166 struct drm_device *drm_dev;
167 struct drm_connector connector;
168 struct drm_bridge *bridge;
169 struct clk *clock;
170 unsigned int irq;
171 void __iomem *reg_base;
172
173 struct video_info video_info;
174 struct link_train link_train;
175 struct phy *phy;
176 int dpms_mode;
177 int hpd_gpio;
178 bool force_hpd;
179 unsigned char edid[EDID_BLOCK_LENGTH * 2];
180
181 struct analogix_dp_plat_data *plat_data;
182};
183
184/* analogix_dp_reg.c */
185void analogix_dp_enable_video_mute(struct analogix_dp_device *dp, bool enable);
186void analogix_dp_stop_video(struct analogix_dp_device *dp);
187void analogix_dp_lane_swap(struct analogix_dp_device *dp, bool enable);
188void analogix_dp_init_analog_param(struct analogix_dp_device *dp);
189void analogix_dp_init_interrupt(struct analogix_dp_device *dp);
190void analogix_dp_reset(struct analogix_dp_device *dp);
191void analogix_dp_swreset(struct analogix_dp_device *dp);
192void analogix_dp_config_interrupt(struct analogix_dp_device *dp);
193void analogix_dp_mute_hpd_interrupt(struct analogix_dp_device *dp);
194void analogix_dp_unmute_hpd_interrupt(struct analogix_dp_device *dp);
195enum pll_status analogix_dp_get_pll_lock_status(struct analogix_dp_device *dp);
196void analogix_dp_set_pll_power_down(struct analogix_dp_device *dp, bool enable);
197void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp,
198 enum analog_power_block block,
199 bool enable);
200void analogix_dp_init_analog_func(struct analogix_dp_device *dp);
201void analogix_dp_init_hpd(struct analogix_dp_device *dp);
202void analogix_dp_force_hpd(struct analogix_dp_device *dp);
203enum dp_irq_type analogix_dp_get_irq_type(struct analogix_dp_device *dp);
204void analogix_dp_clear_hotplug_interrupts(struct analogix_dp_device *dp);
205void analogix_dp_reset_aux(struct analogix_dp_device *dp);
206void analogix_dp_init_aux(struct analogix_dp_device *dp);
207int analogix_dp_get_plug_in_status(struct analogix_dp_device *dp);
208void analogix_dp_enable_sw_function(struct analogix_dp_device *dp);
209int analogix_dp_start_aux_transaction(struct analogix_dp_device *dp);
210int analogix_dp_write_byte_to_dpcd(struct analogix_dp_device *dp,
211 unsigned int reg_addr,
212 unsigned char data);
213int analogix_dp_read_byte_from_dpcd(struct analogix_dp_device *dp,
214 unsigned int reg_addr,
215 unsigned char *data);
216int analogix_dp_write_bytes_to_dpcd(struct analogix_dp_device *dp,
217 unsigned int reg_addr,
218 unsigned int count,
219 unsigned char data[]);
220int analogix_dp_read_bytes_from_dpcd(struct analogix_dp_device *dp,
221 unsigned int reg_addr,
222 unsigned int count,
223 unsigned char data[]);
224int analogix_dp_select_i2c_device(struct analogix_dp_device *dp,
225 unsigned int device_addr,
226 unsigned int reg_addr);
227int analogix_dp_read_byte_from_i2c(struct analogix_dp_device *dp,
228 unsigned int device_addr,
229 unsigned int reg_addr,
230 unsigned int *data);
231int analogix_dp_read_bytes_from_i2c(struct analogix_dp_device *dp,
232 unsigned int device_addr,
233 unsigned int reg_addr,
234 unsigned int count,
235 unsigned char edid[]);
236void analogix_dp_set_link_bandwidth(struct analogix_dp_device *dp, u32 bwtype);
237void analogix_dp_get_link_bandwidth(struct analogix_dp_device *dp, u32 *bwtype);
238void analogix_dp_set_lane_count(struct analogix_dp_device *dp, u32 count);
239void analogix_dp_get_lane_count(struct analogix_dp_device *dp, u32 *count);
240void analogix_dp_enable_enhanced_mode(struct analogix_dp_device *dp,
241 bool enable);
242void analogix_dp_set_training_pattern(struct analogix_dp_device *dp,
243 enum pattern_set pattern);
244void analogix_dp_set_lane0_pre_emphasis(struct analogix_dp_device *dp,
245 u32 level);
246void analogix_dp_set_lane1_pre_emphasis(struct analogix_dp_device *dp,
247 u32 level);
248void analogix_dp_set_lane2_pre_emphasis(struct analogix_dp_device *dp,
249 u32 level);
250void analogix_dp_set_lane3_pre_emphasis(struct analogix_dp_device *dp,
251 u32 level);
252void analogix_dp_set_lane0_link_training(struct analogix_dp_device *dp,
253 u32 training_lane);
254void analogix_dp_set_lane1_link_training(struct analogix_dp_device *dp,
255 u32 training_lane);
256void analogix_dp_set_lane2_link_training(struct analogix_dp_device *dp,
257 u32 training_lane);
258void analogix_dp_set_lane3_link_training(struct analogix_dp_device *dp,
259 u32 training_lane);
260u32 analogix_dp_get_lane0_link_training(struct analogix_dp_device *dp);
261u32 analogix_dp_get_lane1_link_training(struct analogix_dp_device *dp);
262u32 analogix_dp_get_lane2_link_training(struct analogix_dp_device *dp);
263u32 analogix_dp_get_lane3_link_training(struct analogix_dp_device *dp);
264void analogix_dp_reset_macro(struct analogix_dp_device *dp);
265void analogix_dp_init_video(struct analogix_dp_device *dp);
266
267void analogix_dp_set_video_color_format(struct analogix_dp_device *dp);
268int analogix_dp_is_slave_video_stream_clock_on(struct analogix_dp_device *dp);
269void analogix_dp_set_video_cr_mn(struct analogix_dp_device *dp,
270 enum clock_recovery_m_value_type type,
271 u32 m_value,
272 u32 n_value);
273void analogix_dp_set_video_timing_mode(struct analogix_dp_device *dp, u32 type);
274void analogix_dp_enable_video_master(struct analogix_dp_device *dp,
275 bool enable);
276void analogix_dp_start_video(struct analogix_dp_device *dp);
277int analogix_dp_is_video_stream_on(struct analogix_dp_device *dp);
278void analogix_dp_config_video_slave_mode(struct analogix_dp_device *dp);
279void analogix_dp_enable_scrambling(struct analogix_dp_device *dp);
280void analogix_dp_disable_scrambling(struct analogix_dp_device *dp);
281#endif /* _ANALOGIX_DP_CORE_H */
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
new file mode 100644
index 000000000000..49205ef02be3
--- /dev/null
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -0,0 +1,1320 @@
1/*
2 * Analogix DP (Display port) core register interface driver.
3 *
4 * Copyright (C) 2012 Samsung Electronics Co., Ltd.
5 * Author: Jingoo Han <jg1.han@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/device.h>
14#include <linux/io.h>
15#include <linux/delay.h>
16#include <linux/gpio.h>
17
18#include <drm/bridge/analogix_dp.h>
19
20#include "analogix_dp_core.h"
21#include "analogix_dp_reg.h"
22
23#define COMMON_INT_MASK_1 0
24#define COMMON_INT_MASK_2 0
25#define COMMON_INT_MASK_3 0
26#define COMMON_INT_MASK_4 (HOTPLUG_CHG | HPD_LOST | PLUG)
27#define INT_STA_MASK INT_HPD
28
29void analogix_dp_enable_video_mute(struct analogix_dp_device *dp, bool enable)
30{
31 u32 reg;
32
33 if (enable) {
34 reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
35 reg |= HDCP_VIDEO_MUTE;
36 writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
37 } else {
38 reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
39 reg &= ~HDCP_VIDEO_MUTE;
40 writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
41 }
42}
43
44void analogix_dp_stop_video(struct analogix_dp_device *dp)
45{
46 u32 reg;
47
48 reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
49 reg &= ~VIDEO_EN;
50 writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
51}
52
53void analogix_dp_lane_swap(struct analogix_dp_device *dp, bool enable)
54{
55 u32 reg;
56
57 if (enable)
58 reg = LANE3_MAP_LOGIC_LANE_0 | LANE2_MAP_LOGIC_LANE_1 |
59 LANE1_MAP_LOGIC_LANE_2 | LANE0_MAP_LOGIC_LANE_3;
60 else
61 reg = LANE3_MAP_LOGIC_LANE_3 | LANE2_MAP_LOGIC_LANE_2 |
62 LANE1_MAP_LOGIC_LANE_1 | LANE0_MAP_LOGIC_LANE_0;
63
64 writel(reg, dp->reg_base + ANALOGIX_DP_LANE_MAP);
65}
66
67void analogix_dp_init_analog_param(struct analogix_dp_device *dp)
68{
69 u32 reg;
70
71 reg = TX_TERMINAL_CTRL_50_OHM;
72 writel(reg, dp->reg_base + ANALOGIX_DP_ANALOG_CTL_1);
73
74 reg = SEL_24M | TX_DVDD_BIT_1_0625V;
75 writel(reg, dp->reg_base + ANALOGIX_DP_ANALOG_CTL_2);
76
77 if (dp->plat_data && (dp->plat_data->dev_type == RK3288_DP)) {
78 writel(REF_CLK_24M, dp->reg_base + ANALOGIX_DP_PLL_REG_1);
79 writel(0x95, dp->reg_base + ANALOGIX_DP_PLL_REG_2);
80 writel(0x40, dp->reg_base + ANALOGIX_DP_PLL_REG_3);
81 writel(0x58, dp->reg_base + ANALOGIX_DP_PLL_REG_4);
82 writel(0x22, dp->reg_base + ANALOGIX_DP_PLL_REG_5);
83 }
84
85 reg = DRIVE_DVDD_BIT_1_0625V | VCO_BIT_600_MICRO;
86 writel(reg, dp->reg_base + ANALOGIX_DP_ANALOG_CTL_3);
87
88 reg = PD_RING_OSC | AUX_TERMINAL_CTRL_50_OHM |
89 TX_CUR1_2X | TX_CUR_16_MA;
90 writel(reg, dp->reg_base + ANALOGIX_DP_PLL_FILTER_CTL_1);
91
92 reg = CH3_AMP_400_MV | CH2_AMP_400_MV |
93 CH1_AMP_400_MV | CH0_AMP_400_MV;
94 writel(reg, dp->reg_base + ANALOGIX_DP_TX_AMP_TUNING_CTL);
95}
96
97void analogix_dp_init_interrupt(struct analogix_dp_device *dp)
98{
99 /* Set interrupt pin assertion polarity as high */
100 writel(INT_POL1 | INT_POL0, dp->reg_base + ANALOGIX_DP_INT_CTL);
101
102 /* Clear pending regisers */
103 writel(0xff, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_1);
104 writel(0x4f, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_2);
105 writel(0xe0, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_3);
106 writel(0xe7, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_4);
107 writel(0x63, dp->reg_base + ANALOGIX_DP_INT_STA);
108
109 /* 0:mask,1: unmask */
110 writel(0x00, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_1);
111 writel(0x00, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_2);
112 writel(0x00, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_3);
113 writel(0x00, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_4);
114 writel(0x00, dp->reg_base + ANALOGIX_DP_INT_STA_MASK);
115}
116
117void analogix_dp_reset(struct analogix_dp_device *dp)
118{
119 u32 reg;
120
121 analogix_dp_stop_video(dp);
122 analogix_dp_enable_video_mute(dp, 0);
123
124 reg = MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N |
125 AUD_FIFO_FUNC_EN_N | AUD_FUNC_EN_N |
126 HDCP_FUNC_EN_N | SW_FUNC_EN_N;
127 writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
128
129 reg = SSC_FUNC_EN_N | AUX_FUNC_EN_N |
130 SERDES_FIFO_FUNC_EN_N |
131 LS_CLK_DOMAIN_FUNC_EN_N;
132 writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
133
134 usleep_range(20, 30);
135
136 analogix_dp_lane_swap(dp, 0);
137
138 writel(0x0, dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
139 writel(0x40, dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
140 writel(0x0, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
141 writel(0x0, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
142
143 writel(0x0, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
144 writel(0x0, dp->reg_base + ANALOGIX_DP_HDCP_CTL);
145
146 writel(0x5e, dp->reg_base + ANALOGIX_DP_HPD_DEGLITCH_L);
147 writel(0x1a, dp->reg_base + ANALOGIX_DP_HPD_DEGLITCH_H);
148
149 writel(0x10, dp->reg_base + ANALOGIX_DP_LINK_DEBUG_CTL);
150
151 writel(0x0, dp->reg_base + ANALOGIX_DP_PHY_TEST);
152
153 writel(0x0, dp->reg_base + ANALOGIX_DP_VIDEO_FIFO_THRD);
154 writel(0x20, dp->reg_base + ANALOGIX_DP_AUDIO_MARGIN);
155
156 writel(0x4, dp->reg_base + ANALOGIX_DP_M_VID_GEN_FILTER_TH);
157 writel(0x2, dp->reg_base + ANALOGIX_DP_M_AUD_GEN_FILTER_TH);
158
159 writel(0x00000101, dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
160}
161
162void analogix_dp_swreset(struct analogix_dp_device *dp)
163{
164 writel(RESET_DP_TX, dp->reg_base + ANALOGIX_DP_TX_SW_RESET);
165}
166
167void analogix_dp_config_interrupt(struct analogix_dp_device *dp)
168{
169 u32 reg;
170
171 /* 0: mask, 1: unmask */
172 reg = COMMON_INT_MASK_1;
173 writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_1);
174
175 reg = COMMON_INT_MASK_2;
176 writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_2);
177
178 reg = COMMON_INT_MASK_3;
179 writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_3);
180
181 reg = COMMON_INT_MASK_4;
182 writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_4);
183
184 reg = INT_STA_MASK;
185 writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA_MASK);
186}
187
188void analogix_dp_mute_hpd_interrupt(struct analogix_dp_device *dp)
189{
190 u32 reg;
191
192 /* 0: mask, 1: unmask */
193 reg = readl(dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_4);
194 reg &= ~COMMON_INT_MASK_4;
195 writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_4);
196
197 reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA_MASK);
198 reg &= ~INT_STA_MASK;
199 writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA_MASK);
200}
201
202void analogix_dp_unmute_hpd_interrupt(struct analogix_dp_device *dp)
203{
204 u32 reg;
205
206 /* 0: mask, 1: unmask */
207 reg = COMMON_INT_MASK_4;
208 writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_4);
209
210 reg = INT_STA_MASK;
211 writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA_MASK);
212}
213
214enum pll_status analogix_dp_get_pll_lock_status(struct analogix_dp_device *dp)
215{
216 u32 reg;
217
218 reg = readl(dp->reg_base + ANALOGIX_DP_DEBUG_CTL);
219 if (reg & PLL_LOCK)
220 return PLL_LOCKED;
221 else
222 return PLL_UNLOCKED;
223}
224
225void analogix_dp_set_pll_power_down(struct analogix_dp_device *dp, bool enable)
226{
227 u32 reg;
228
229 if (enable) {
230 reg = readl(dp->reg_base + ANALOGIX_DP_PLL_CTL);
231 reg |= DP_PLL_PD;
232 writel(reg, dp->reg_base + ANALOGIX_DP_PLL_CTL);
233 } else {
234 reg = readl(dp->reg_base + ANALOGIX_DP_PLL_CTL);
235 reg &= ~DP_PLL_PD;
236 writel(reg, dp->reg_base + ANALOGIX_DP_PLL_CTL);
237 }
238}
239
240void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp,
241 enum analog_power_block block,
242 bool enable)
243{
244 u32 reg;
245 u32 phy_pd_addr = ANALOGIX_DP_PHY_PD;
246
247 if (dp->plat_data && (dp->plat_data->dev_type == RK3288_DP))
248 phy_pd_addr = ANALOGIX_DP_PD;
249
250 switch (block) {
251 case AUX_BLOCK:
252 if (enable) {
253 reg = readl(dp->reg_base + phy_pd_addr);
254 reg |= AUX_PD;
255 writel(reg, dp->reg_base + phy_pd_addr);
256 } else {
257 reg = readl(dp->reg_base + phy_pd_addr);
258 reg &= ~AUX_PD;
259 writel(reg, dp->reg_base + phy_pd_addr);
260 }
261 break;
262 case CH0_BLOCK:
263 if (enable) {
264 reg = readl(dp->reg_base + phy_pd_addr);
265 reg |= CH0_PD;
266 writel(reg, dp->reg_base + phy_pd_addr);
267 } else {
268 reg = readl(dp->reg_base + phy_pd_addr);
269 reg &= ~CH0_PD;
270 writel(reg, dp->reg_base + phy_pd_addr);
271 }
272 break;
273 case CH1_BLOCK:
274 if (enable) {
275 reg = readl(dp->reg_base + phy_pd_addr);
276 reg |= CH1_PD;
277 writel(reg, dp->reg_base + phy_pd_addr);
278 } else {
279 reg = readl(dp->reg_base + phy_pd_addr);
280 reg &= ~CH1_PD;
281 writel(reg, dp->reg_base + phy_pd_addr);
282 }
283 break;
284 case CH2_BLOCK:
285 if (enable) {
286 reg = readl(dp->reg_base + phy_pd_addr);
287 reg |= CH2_PD;
288 writel(reg, dp->reg_base + phy_pd_addr);
289 } else {
290 reg = readl(dp->reg_base + phy_pd_addr);
291 reg &= ~CH2_PD;
292 writel(reg, dp->reg_base + phy_pd_addr);
293 }
294 break;
295 case CH3_BLOCK:
296 if (enable) {
297 reg = readl(dp->reg_base + phy_pd_addr);
298 reg |= CH3_PD;
299 writel(reg, dp->reg_base + phy_pd_addr);
300 } else {
301 reg = readl(dp->reg_base + phy_pd_addr);
302 reg &= ~CH3_PD;
303 writel(reg, dp->reg_base + phy_pd_addr);
304 }
305 break;
306 case ANALOG_TOTAL:
307 if (enable) {
308 reg = readl(dp->reg_base + phy_pd_addr);
309 reg |= DP_PHY_PD;
310 writel(reg, dp->reg_base + phy_pd_addr);
311 } else {
312 reg = readl(dp->reg_base + phy_pd_addr);
313 reg &= ~DP_PHY_PD;
314 writel(reg, dp->reg_base + phy_pd_addr);
315 }
316 break;
317 case POWER_ALL:
318 if (enable) {
319 reg = DP_PHY_PD | AUX_PD | CH3_PD | CH2_PD |
320 CH1_PD | CH0_PD;
321 writel(reg, dp->reg_base + phy_pd_addr);
322 } else {
323 writel(0x00, dp->reg_base + phy_pd_addr);
324 }
325 break;
326 default:
327 break;
328 }
329}
330
331void analogix_dp_init_analog_func(struct analogix_dp_device *dp)
332{
333 u32 reg;
334 int timeout_loop = 0;
335
336 analogix_dp_set_analog_power_down(dp, POWER_ALL, 0);
337
338 reg = PLL_LOCK_CHG;
339 writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_1);
340
341 reg = readl(dp->reg_base + ANALOGIX_DP_DEBUG_CTL);
342 reg &= ~(F_PLL_LOCK | PLL_LOCK_CTRL);
343 writel(reg, dp->reg_base + ANALOGIX_DP_DEBUG_CTL);
344
345 /* Power up PLL */
346 if (analogix_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
347 analogix_dp_set_pll_power_down(dp, 0);
348
349 while (analogix_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
350 timeout_loop++;
351 if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
352 dev_err(dp->dev, "failed to get pll lock status\n");
353 return;
354 }
355 usleep_range(10, 20);
356 }
357 }
358
359 /* Enable Serdes FIFO function and Link symbol clock domain module */
360 reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
361 reg &= ~(SERDES_FIFO_FUNC_EN_N | LS_CLK_DOMAIN_FUNC_EN_N
362 | AUX_FUNC_EN_N);
363 writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
364}
365
366void analogix_dp_clear_hotplug_interrupts(struct analogix_dp_device *dp)
367{
368 u32 reg;
369
370 if (gpio_is_valid(dp->hpd_gpio))
371 return;
372
373 reg = HOTPLUG_CHG | HPD_LOST | PLUG;
374 writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_4);
375
376 reg = INT_HPD;
377 writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA);
378}
379
380void analogix_dp_init_hpd(struct analogix_dp_device *dp)
381{
382 u32 reg;
383
384 if (gpio_is_valid(dp->hpd_gpio))
385 return;
386
387 analogix_dp_clear_hotplug_interrupts(dp);
388
389 reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
390 reg &= ~(F_HPD | HPD_CTRL);
391 writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
392}
393
394void analogix_dp_force_hpd(struct analogix_dp_device *dp)
395{
396 u32 reg;
397
398 reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
399 reg = (F_HPD | HPD_CTRL);
400 writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
401}
402
403enum dp_irq_type analogix_dp_get_irq_type(struct analogix_dp_device *dp)
404{
405 u32 reg;
406
407 if (gpio_is_valid(dp->hpd_gpio)) {
408 reg = gpio_get_value(dp->hpd_gpio);
409 if (reg)
410 return DP_IRQ_TYPE_HP_CABLE_IN;
411 else
412 return DP_IRQ_TYPE_HP_CABLE_OUT;
413 } else {
414 /* Parse hotplug interrupt status register */
415 reg = readl(dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_4);
416
417 if (reg & PLUG)
418 return DP_IRQ_TYPE_HP_CABLE_IN;
419
420 if (reg & HPD_LOST)
421 return DP_IRQ_TYPE_HP_CABLE_OUT;
422
423 if (reg & HOTPLUG_CHG)
424 return DP_IRQ_TYPE_HP_CHANGE;
425
426 return DP_IRQ_TYPE_UNKNOWN;
427 }
428}
429
430void analogix_dp_reset_aux(struct analogix_dp_device *dp)
431{
432 u32 reg;
433
434 /* Disable AUX channel module */
435 reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
436 reg |= AUX_FUNC_EN_N;
437 writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
438}
439
440void analogix_dp_init_aux(struct analogix_dp_device *dp)
441{
442 u32 reg;
443
444 /* Clear inerrupts related to AUX channel */
445 reg = RPLY_RECEIV | AUX_ERR;
446 writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA);
447
448 analogix_dp_reset_aux(dp);
449
450 /* Disable AUX transaction H/W retry */
451 if (dp->plat_data && (dp->plat_data->dev_type == RK3288_DP))
452 reg = AUX_BIT_PERIOD_EXPECTED_DELAY(0) |
453 AUX_HW_RETRY_COUNT_SEL(3) |
454 AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
455 else
456 reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) |
457 AUX_HW_RETRY_COUNT_SEL(0) |
458 AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
459 writel(reg, dp->reg_base + ANALOGIX_DP_AUX_HW_RETRY_CTL);
460
461 /* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */
462 reg = DEFER_CTRL_EN | DEFER_COUNT(1);
463 writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_DEFER_CTL);
464
465 /* Enable AUX channel module */
466 reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
467 reg &= ~AUX_FUNC_EN_N;
468 writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
469}
470
471int analogix_dp_get_plug_in_status(struct analogix_dp_device *dp)
472{
473 u32 reg;
474
475 if (gpio_is_valid(dp->hpd_gpio)) {
476 if (gpio_get_value(dp->hpd_gpio))
477 return 0;
478 } else {
479 reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
480 if (reg & HPD_STATUS)
481 return 0;
482 }
483
484 return -EINVAL;
485}
486
487void analogix_dp_enable_sw_function(struct analogix_dp_device *dp)
488{
489 u32 reg;
490
491 reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
492 reg &= ~SW_FUNC_EN_N;
493 writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
494}
495
496int analogix_dp_start_aux_transaction(struct analogix_dp_device *dp)
497{
498 int reg;
499 int retval = 0;
500 int timeout_loop = 0;
501
502 /* Enable AUX CH operation */
503 reg = readl(dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2);
504 reg |= AUX_EN;
505 writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2);
506
507 /* Is AUX CH command reply received? */
508 reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
509 while (!(reg & RPLY_RECEIV)) {
510 timeout_loop++;
511 if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
512 dev_err(dp->dev, "AUX CH command reply failed!\n");
513 return -ETIMEDOUT;
514 }
515 reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
516 usleep_range(10, 11);
517 }
518
519 /* Clear interrupt source for AUX CH command reply */
520 writel(RPLY_RECEIV, dp->reg_base + ANALOGIX_DP_INT_STA);
521
522 /* Clear interrupt source for AUX CH access error */
523 reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
524 if (reg & AUX_ERR) {
525 writel(AUX_ERR, dp->reg_base + ANALOGIX_DP_INT_STA);
526 return -EREMOTEIO;
527 }
528
529 /* Check AUX CH error access status */
530 reg = readl(dp->reg_base + ANALOGIX_DP_AUX_CH_STA);
531 if ((reg & AUX_STATUS_MASK) != 0) {
532 dev_err(dp->dev, "AUX CH error happens: %d\n\n",
533 reg & AUX_STATUS_MASK);
534 return -EREMOTEIO;
535 }
536
537 return retval;
538}
539
540int analogix_dp_write_byte_to_dpcd(struct analogix_dp_device *dp,
541 unsigned int reg_addr,
542 unsigned char data)
543{
544 u32 reg;
545 int i;
546 int retval;
547
548 for (i = 0; i < 3; i++) {
549 /* Clear AUX CH data buffer */
550 reg = BUF_CLR;
551 writel(reg, dp->reg_base + ANALOGIX_DP_BUFFER_DATA_CTL);
552
553 /* Select DPCD device address */
554 reg = AUX_ADDR_7_0(reg_addr);
555 writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_7_0);
556 reg = AUX_ADDR_15_8(reg_addr);
557 writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_15_8);
558 reg = AUX_ADDR_19_16(reg_addr);
559 writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_19_16);
560
561 /* Write data buffer */
562 reg = (unsigned int)data;
563 writel(reg, dp->reg_base + ANALOGIX_DP_BUF_DATA_0);
564
565 /*
566 * Set DisplayPort transaction and write 1 byte
567 * If bit 3 is 1, DisplayPort transaction.
568 * If Bit 3 is 0, I2C transaction.
569 */
570 reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE;
571 writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_1);
572
573 /* Start AUX transaction */
574 retval = analogix_dp_start_aux_transaction(dp);
575 if (retval == 0)
576 break;
577
578 dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
579 }
580
581 return retval;
582}
583
584int analogix_dp_read_byte_from_dpcd(struct analogix_dp_device *dp,
585 unsigned int reg_addr,
586 unsigned char *data)
587{
588 u32 reg;
589 int i;
590 int retval;
591
592 for (i = 0; i < 3; i++) {
593 /* Clear AUX CH data buffer */
594 reg = BUF_CLR;
595 writel(reg, dp->reg_base + ANALOGIX_DP_BUFFER_DATA_CTL);
596
597 /* Select DPCD device address */
598 reg = AUX_ADDR_7_0(reg_addr);
599 writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_7_0);
600 reg = AUX_ADDR_15_8(reg_addr);
601 writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_15_8);
602 reg = AUX_ADDR_19_16(reg_addr);
603 writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_19_16);
604
605 /*
606 * Set DisplayPort transaction and read 1 byte
607 * If bit 3 is 1, DisplayPort transaction.
608 * If Bit 3 is 0, I2C transaction.
609 */
610 reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_READ;
611 writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_1);
612
613 /* Start AUX transaction */
614 retval = analogix_dp_start_aux_transaction(dp);
615 if (retval == 0)
616 break;
617
618 dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
619 }
620
621 /* Read data buffer */
622 reg = readl(dp->reg_base + ANALOGIX_DP_BUF_DATA_0);
623 *data = (unsigned char)(reg & 0xff);
624
625 return retval;
626}
627
628int analogix_dp_write_bytes_to_dpcd(struct analogix_dp_device *dp,
629 unsigned int reg_addr,
630 unsigned int count,
631 unsigned char data[])
632{
633 u32 reg;
634 unsigned int start_offset;
635 unsigned int cur_data_count;
636 unsigned int cur_data_idx;
637 int i;
638 int retval = 0;
639
640 /* Clear AUX CH data buffer */
641 reg = BUF_CLR;
642 writel(reg, dp->reg_base + ANALOGIX_DP_BUFFER_DATA_CTL);
643
644 start_offset = 0;
645 while (start_offset < count) {
646 /* Buffer size of AUX CH is 16 * 4bytes */
647 if ((count - start_offset) > 16)
648 cur_data_count = 16;
649 else
650 cur_data_count = count - start_offset;
651
652 for (i = 0; i < 3; i++) {
653 /* Select DPCD device address */
654 reg = AUX_ADDR_7_0(reg_addr + start_offset);
655 writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_7_0);
656 reg = AUX_ADDR_15_8(reg_addr + start_offset);
657 writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_15_8);
658 reg = AUX_ADDR_19_16(reg_addr + start_offset);
659 writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_19_16);
660
661 for (cur_data_idx = 0; cur_data_idx < cur_data_count;
662 cur_data_idx++) {
663 reg = data[start_offset + cur_data_idx];
664 writel(reg, dp->reg_base +
665 ANALOGIX_DP_BUF_DATA_0 +
666 4 * cur_data_idx);
667 }
668
669 /*
670 * Set DisplayPort transaction and write
671 * If bit 3 is 1, DisplayPort transaction.
672 * If Bit 3 is 0, I2C transaction.
673 */
674 reg = AUX_LENGTH(cur_data_count) |
675 AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE;
676 writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_1);
677
678 /* Start AUX transaction */
679 retval = analogix_dp_start_aux_transaction(dp);
680 if (retval == 0)
681 break;
682
683 dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
684 __func__);
685 }
686
687 start_offset += cur_data_count;
688 }
689
690 return retval;
691}
692
693int analogix_dp_read_bytes_from_dpcd(struct analogix_dp_device *dp,
694 unsigned int reg_addr,
695 unsigned int count,
696 unsigned char data[])
697{
698 u32 reg;
699 unsigned int start_offset;
700 unsigned int cur_data_count;
701 unsigned int cur_data_idx;
702 int i;
703 int retval = 0;
704
705 /* Clear AUX CH data buffer */
706 reg = BUF_CLR;
707 writel(reg, dp->reg_base + ANALOGIX_DP_BUFFER_DATA_CTL);
708
709 start_offset = 0;
710 while (start_offset < count) {
711 /* Buffer size of AUX CH is 16 * 4bytes */
712 if ((count - start_offset) > 16)
713 cur_data_count = 16;
714 else
715 cur_data_count = count - start_offset;
716
717 /* AUX CH Request Transaction process */
718 for (i = 0; i < 3; i++) {
719 /* Select DPCD device address */
720 reg = AUX_ADDR_7_0(reg_addr + start_offset);
721 writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_7_0);
722 reg = AUX_ADDR_15_8(reg_addr + start_offset);
723 writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_15_8);
724 reg = AUX_ADDR_19_16(reg_addr + start_offset);
725 writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_19_16);
726
727 /*
728 * Set DisplayPort transaction and read
729 * If bit 3 is 1, DisplayPort transaction.
730 * If Bit 3 is 0, I2C transaction.
731 */
732 reg = AUX_LENGTH(cur_data_count) |
733 AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_READ;
734 writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_1);
735
736 /* Start AUX transaction */
737 retval = analogix_dp_start_aux_transaction(dp);
738 if (retval == 0)
739 break;
740
741 dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
742 __func__);
743 }
744
745 for (cur_data_idx = 0; cur_data_idx < cur_data_count;
746 cur_data_idx++) {
747 reg = readl(dp->reg_base + ANALOGIX_DP_BUF_DATA_0
748 + 4 * cur_data_idx);
749 data[start_offset + cur_data_idx] =
750 (unsigned char)reg;
751 }
752
753 start_offset += cur_data_count;
754 }
755
756 return retval;
757}
758
759int analogix_dp_select_i2c_device(struct analogix_dp_device *dp,
760 unsigned int device_addr,
761 unsigned int reg_addr)
762{
763 u32 reg;
764 int retval;
765
766 /* Set EDID device address */
767 reg = device_addr;
768 writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_7_0);
769 writel(0x0, dp->reg_base + ANALOGIX_DP_AUX_ADDR_15_8);
770 writel(0x0, dp->reg_base + ANALOGIX_DP_AUX_ADDR_19_16);
771
772 /* Set offset from base address of EDID device */
773 writel(reg_addr, dp->reg_base + ANALOGIX_DP_BUF_DATA_0);
774
775 /*
776 * Set I2C transaction and write address
777 * If bit 3 is 1, DisplayPort transaction.
778 * If Bit 3 is 0, I2C transaction.
779 */
780 reg = AUX_TX_COMM_I2C_TRANSACTION | AUX_TX_COMM_MOT |
781 AUX_TX_COMM_WRITE;
782 writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_1);
783
784 /* Start AUX transaction */
785 retval = analogix_dp_start_aux_transaction(dp);
786 if (retval != 0)
787 dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
788
789 return retval;
790}
791
792int analogix_dp_read_byte_from_i2c(struct analogix_dp_device *dp,
793 unsigned int device_addr,
794 unsigned int reg_addr,
795 unsigned int *data)
796{
797 u32 reg;
798 int i;
799 int retval;
800
801 for (i = 0; i < 3; i++) {
802 /* Clear AUX CH data buffer */
803 reg = BUF_CLR;
804 writel(reg, dp->reg_base + ANALOGIX_DP_BUFFER_DATA_CTL);
805
806 /* Select EDID device */
807 retval = analogix_dp_select_i2c_device(dp, device_addr,
808 reg_addr);
809 if (retval != 0)
810 continue;
811
812 /*
813 * Set I2C transaction and read data
814 * If bit 3 is 1, DisplayPort transaction.
815 * If Bit 3 is 0, I2C transaction.
816 */
817 reg = AUX_TX_COMM_I2C_TRANSACTION |
818 AUX_TX_COMM_READ;
819 writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_1);
820
821 /* Start AUX transaction */
822 retval = analogix_dp_start_aux_transaction(dp);
823 if (retval == 0)
824 break;
825
826 dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
827 }
828
829 /* Read data */
830 if (retval == 0)
831 *data = readl(dp->reg_base + ANALOGIX_DP_BUF_DATA_0);
832
833 return retval;
834}
835
836int analogix_dp_read_bytes_from_i2c(struct analogix_dp_device *dp,
837 unsigned int device_addr,
838 unsigned int reg_addr,
839 unsigned int count,
840 unsigned char edid[])
841{
842 u32 reg;
843 unsigned int i, j;
844 unsigned int cur_data_idx;
845 unsigned int defer = 0;
846 int retval = 0;
847
848 for (i = 0; i < count; i += 16) {
849 for (j = 0; j < 3; j++) {
850 /* Clear AUX CH data buffer */
851 reg = BUF_CLR;
852 writel(reg, dp->reg_base + ANALOGIX_DP_BUFFER_DATA_CTL);
853
854 /* Set normal AUX CH command */
855 reg = readl(dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2);
856 reg &= ~ADDR_ONLY;
857 writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2);
858
859 /*
860 * If Rx sends defer, Tx sends only reads
861 * request without sending address
862 */
863 if (!defer)
864 retval = analogix_dp_select_i2c_device(dp,
865 device_addr, reg_addr + i);
866 else
867 defer = 0;
868
869 if (retval == 0) {
870 /*
871 * Set I2C transaction and write data
872 * If bit 3 is 1, DisplayPort transaction.
873 * If Bit 3 is 0, I2C transaction.
874 */
875 reg = AUX_LENGTH(16) |
876 AUX_TX_COMM_I2C_TRANSACTION |
877 AUX_TX_COMM_READ;
878 writel(reg, dp->reg_base +
879 ANALOGIX_DP_AUX_CH_CTL_1);
880
881 /* Start AUX transaction */
882 retval = analogix_dp_start_aux_transaction(dp);
883 if (retval == 0)
884 break;
885
886 dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
887 __func__);
888 }
889 /* Check if Rx sends defer */
890 reg = readl(dp->reg_base + ANALOGIX_DP_AUX_RX_COMM);
891 if (reg == AUX_RX_COMM_AUX_DEFER ||
892 reg == AUX_RX_COMM_I2C_DEFER) {
893 dev_err(dp->dev, "Defer: %d\n\n", reg);
894 defer = 1;
895 }
896 }
897
898 for (cur_data_idx = 0; cur_data_idx < 16; cur_data_idx++) {
899 reg = readl(dp->reg_base + ANALOGIX_DP_BUF_DATA_0
900 + 4 * cur_data_idx);
901 edid[i + cur_data_idx] = (unsigned char)reg;
902 }
903 }
904
905 return retval;
906}
907
908void analogix_dp_set_link_bandwidth(struct analogix_dp_device *dp, u32 bwtype)
909{
910 u32 reg;
911
912 reg = bwtype;
913 if ((bwtype == DP_LINK_BW_2_7) || (bwtype == DP_LINK_BW_1_62))
914 writel(reg, dp->reg_base + ANALOGIX_DP_LINK_BW_SET);
915}
916
917void analogix_dp_get_link_bandwidth(struct analogix_dp_device *dp, u32 *bwtype)
918{
919 u32 reg;
920
921 reg = readl(dp->reg_base + ANALOGIX_DP_LINK_BW_SET);
922 *bwtype = reg;
923}
924
925void analogix_dp_set_lane_count(struct analogix_dp_device *dp, u32 count)
926{
927 u32 reg;
928
929 reg = count;
930 writel(reg, dp->reg_base + ANALOGIX_DP_LANE_COUNT_SET);
931}
932
933void analogix_dp_get_lane_count(struct analogix_dp_device *dp, u32 *count)
934{
935 u32 reg;
936
937 reg = readl(dp->reg_base + ANALOGIX_DP_LANE_COUNT_SET);
938 *count = reg;
939}
940
941void analogix_dp_enable_enhanced_mode(struct analogix_dp_device *dp,
942 bool enable)
943{
944 u32 reg;
945
946 if (enable) {
947 reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
948 reg |= ENHANCED;
949 writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
950 } else {
951 reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
952 reg &= ~ENHANCED;
953 writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
954 }
955}
956
957void analogix_dp_set_training_pattern(struct analogix_dp_device *dp,
958 enum pattern_set pattern)
959{
960 u32 reg;
961
962 switch (pattern) {
963 case PRBS7:
964 reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_PRBS7;
965 writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
966 break;
967 case D10_2:
968 reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_D10_2;
969 writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
970 break;
971 case TRAINING_PTN1:
972 reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN1;
973 writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
974 break;
975 case TRAINING_PTN2:
976 reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN2;
977 writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
978 break;
979 case DP_NONE:
980 reg = SCRAMBLING_ENABLE |
981 LINK_QUAL_PATTERN_SET_DISABLE |
982 SW_TRAINING_PATTERN_SET_NORMAL;
983 writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
984 break;
985 default:
986 break;
987 }
988}
989
990void analogix_dp_set_lane0_pre_emphasis(struct analogix_dp_device *dp,
991 u32 level)
992{
993 u32 reg;
994
995 reg = readl(dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL);
996 reg &= ~PRE_EMPHASIS_SET_MASK;
997 reg |= level << PRE_EMPHASIS_SET_SHIFT;
998 writel(reg, dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL);
999}
1000
1001void analogix_dp_set_lane1_pre_emphasis(struct analogix_dp_device *dp,
1002 u32 level)
1003{
1004 u32 reg;
1005
1006 reg = readl(dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL);
1007 reg &= ~PRE_EMPHASIS_SET_MASK;
1008 reg |= level << PRE_EMPHASIS_SET_SHIFT;
1009 writel(reg, dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL);
1010}
1011
1012void analogix_dp_set_lane2_pre_emphasis(struct analogix_dp_device *dp,
1013 u32 level)
1014{
1015 u32 reg;
1016
1017 reg = readl(dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL);
1018 reg &= ~PRE_EMPHASIS_SET_MASK;
1019 reg |= level << PRE_EMPHASIS_SET_SHIFT;
1020 writel(reg, dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL);
1021}
1022
1023void analogix_dp_set_lane3_pre_emphasis(struct analogix_dp_device *dp,
1024 u32 level)
1025{
1026 u32 reg;
1027
1028 reg = readl(dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL);
1029 reg &= ~PRE_EMPHASIS_SET_MASK;
1030 reg |= level << PRE_EMPHASIS_SET_SHIFT;
1031 writel(reg, dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL);
1032}
1033
1034void analogix_dp_set_lane0_link_training(struct analogix_dp_device *dp,
1035 u32 training_lane)
1036{
1037 u32 reg;
1038
1039 reg = training_lane;
1040 writel(reg, dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL);
1041}
1042
1043void analogix_dp_set_lane1_link_training(struct analogix_dp_device *dp,
1044 u32 training_lane)
1045{
1046 u32 reg;
1047
1048 reg = training_lane;
1049 writel(reg, dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL);
1050}
1051
1052void analogix_dp_set_lane2_link_training(struct analogix_dp_device *dp,
1053 u32 training_lane)
1054{
1055 u32 reg;
1056
1057 reg = training_lane;
1058 writel(reg, dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL);
1059}
1060
1061void analogix_dp_set_lane3_link_training(struct analogix_dp_device *dp,
1062 u32 training_lane)
1063{
1064 u32 reg;
1065
1066 reg = training_lane;
1067 writel(reg, dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL);
1068}
1069
1070u32 analogix_dp_get_lane0_link_training(struct analogix_dp_device *dp)
1071{
1072 u32 reg;
1073
1074 reg = readl(dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL);
1075 return reg;
1076}
1077
1078u32 analogix_dp_get_lane1_link_training(struct analogix_dp_device *dp)
1079{
1080 u32 reg;
1081
1082 reg = readl(dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL);
1083 return reg;
1084}
1085
1086u32 analogix_dp_get_lane2_link_training(struct analogix_dp_device *dp)
1087{
1088 u32 reg;
1089
1090 reg = readl(dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL);
1091 return reg;
1092}
1093
1094u32 analogix_dp_get_lane3_link_training(struct analogix_dp_device *dp)
1095{
1096 u32 reg;
1097
1098 reg = readl(dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL);
1099 return reg;
1100}
1101
1102void analogix_dp_reset_macro(struct analogix_dp_device *dp)
1103{
1104 u32 reg;
1105
1106 reg = readl(dp->reg_base + ANALOGIX_DP_PHY_TEST);
1107 reg |= MACRO_RST;
1108 writel(reg, dp->reg_base + ANALOGIX_DP_PHY_TEST);
1109
1110 /* 10 us is the minimum reset time. */
1111 usleep_range(10, 20);
1112
1113 reg &= ~MACRO_RST;
1114 writel(reg, dp->reg_base + ANALOGIX_DP_PHY_TEST);
1115}
1116
1117void analogix_dp_init_video(struct analogix_dp_device *dp)
1118{
1119 u32 reg;
1120
1121 reg = VSYNC_DET | VID_FORMAT_CHG | VID_CLK_CHG;
1122 writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_1);
1123
1124 reg = 0x0;
1125 writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
1126
1127 reg = CHA_CRI(4) | CHA_CTRL;
1128 writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
1129
1130 reg = 0x0;
1131 writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
1132
1133 reg = VID_HRES_TH(2) | VID_VRES_TH(0);
1134 writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_8);
1135}
1136
1137void analogix_dp_set_video_color_format(struct analogix_dp_device *dp)
1138{
1139 u32 reg;
1140
1141 /* Configure the input color depth, color space, dynamic range */
1142 reg = (dp->video_info.dynamic_range << IN_D_RANGE_SHIFT) |
1143 (dp->video_info.color_depth << IN_BPC_SHIFT) |
1144 (dp->video_info.color_space << IN_COLOR_F_SHIFT);
1145 writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_2);
1146
1147 /* Set Input Color YCbCr Coefficients to ITU601 or ITU709 */
1148 reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_3);
1149 reg &= ~IN_YC_COEFFI_MASK;
1150 if (dp->video_info.ycbcr_coeff)
1151 reg |= IN_YC_COEFFI_ITU709;
1152 else
1153 reg |= IN_YC_COEFFI_ITU601;
1154 writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_3);
1155}
1156
1157int analogix_dp_is_slave_video_stream_clock_on(struct analogix_dp_device *dp)
1158{
1159 u32 reg;
1160
1161 reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
1162 writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
1163
1164 reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
1165
1166 if (!(reg & DET_STA)) {
1167 dev_dbg(dp->dev, "Input stream clock not detected.\n");
1168 return -EINVAL;
1169 }
1170
1171 reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
1172 writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
1173
1174 reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
1175 dev_dbg(dp->dev, "wait SYS_CTL_2.\n");
1176
1177 if (reg & CHA_STA) {
1178 dev_dbg(dp->dev, "Input stream clk is changing\n");
1179 return -EINVAL;
1180 }
1181
1182 return 0;
1183}
1184
1185void analogix_dp_set_video_cr_mn(struct analogix_dp_device *dp,
1186 enum clock_recovery_m_value_type type,
1187 u32 m_value, u32 n_value)
1188{
1189 u32 reg;
1190
1191 if (type == REGISTER_M) {
1192 reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
1193 reg |= FIX_M_VID;
1194 writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
1195 reg = m_value & 0xff;
1196 writel(reg, dp->reg_base + ANALOGIX_DP_M_VID_0);
1197 reg = (m_value >> 8) & 0xff;
1198 writel(reg, dp->reg_base + ANALOGIX_DP_M_VID_1);
1199 reg = (m_value >> 16) & 0xff;
1200 writel(reg, dp->reg_base + ANALOGIX_DP_M_VID_2);
1201
1202 reg = n_value & 0xff;
1203 writel(reg, dp->reg_base + ANALOGIX_DP_N_VID_0);
1204 reg = (n_value >> 8) & 0xff;
1205 writel(reg, dp->reg_base + ANALOGIX_DP_N_VID_1);
1206 reg = (n_value >> 16) & 0xff;
1207 writel(reg, dp->reg_base + ANALOGIX_DP_N_VID_2);
1208 } else {
1209 reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
1210 reg &= ~FIX_M_VID;
1211 writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
1212
1213 writel(0x00, dp->reg_base + ANALOGIX_DP_N_VID_0);
1214 writel(0x80, dp->reg_base + ANALOGIX_DP_N_VID_1);
1215 writel(0x00, dp->reg_base + ANALOGIX_DP_N_VID_2);
1216 }
1217}
1218
1219void analogix_dp_set_video_timing_mode(struct analogix_dp_device *dp, u32 type)
1220{
1221 u32 reg;
1222
1223 if (type == VIDEO_TIMING_FROM_CAPTURE) {
1224 reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
1225 reg &= ~FORMAT_SEL;
1226 writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
1227 } else {
1228 reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
1229 reg |= FORMAT_SEL;
1230 writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
1231 }
1232}
1233
1234void analogix_dp_enable_video_master(struct analogix_dp_device *dp, bool enable)
1235{
1236 u32 reg;
1237
1238 if (enable) {
1239 reg = readl(dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
1240 reg &= ~VIDEO_MODE_MASK;
1241 reg |= VIDEO_MASTER_MODE_EN | VIDEO_MODE_MASTER_MODE;
1242 writel(reg, dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
1243 } else {
1244 reg = readl(dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
1245 reg &= ~VIDEO_MODE_MASK;
1246 reg |= VIDEO_MODE_SLAVE_MODE;
1247 writel(reg, dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
1248 }
1249}
1250
1251void analogix_dp_start_video(struct analogix_dp_device *dp)
1252{
1253 u32 reg;
1254
1255 reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
1256 reg |= VIDEO_EN;
1257 writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
1258}
1259
1260int analogix_dp_is_video_stream_on(struct analogix_dp_device *dp)
1261{
1262 u32 reg;
1263
1264 reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
1265 writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
1266
1267 reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
1268 if (!(reg & STRM_VALID)) {
1269 dev_dbg(dp->dev, "Input video stream is not detected.\n");
1270 return -EINVAL;
1271 }
1272
1273 return 0;
1274}
1275
1276void analogix_dp_config_video_slave_mode(struct analogix_dp_device *dp)
1277{
1278 u32 reg;
1279
1280 reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
1281 reg &= ~(MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N);
1282 reg |= MASTER_VID_FUNC_EN_N;
1283 writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
1284
1285 reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
1286 reg &= ~INTERACE_SCAN_CFG;
1287 reg |= (dp->video_info.interlaced << 2);
1288 writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
1289
1290 reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
1291 reg &= ~VSYNC_POLARITY_CFG;
1292 reg |= (dp->video_info.v_sync_polarity << 1);
1293 writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
1294
1295 reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
1296 reg &= ~HSYNC_POLARITY_CFG;
1297 reg |= (dp->video_info.h_sync_polarity << 0);
1298 writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
1299
1300 reg = AUDIO_MODE_SPDIF_MODE | VIDEO_MODE_SLAVE_MODE;
1301 writel(reg, dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
1302}
1303
1304void analogix_dp_enable_scrambling(struct analogix_dp_device *dp)
1305{
1306 u32 reg;
1307
1308 reg = readl(dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
1309 reg &= ~SCRAMBLING_DISABLE;
1310 writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
1311}
1312
1313void analogix_dp_disable_scrambling(struct analogix_dp_device *dp)
1314{
1315 u32 reg;
1316
1317 reg = readl(dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
1318 reg |= SCRAMBLING_DISABLE;
1319 writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
1320}
diff --git a/drivers/gpu/drm/exynos/exynos_dp_reg.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h
index 2e9bd0e0b9f2..337912b0aeab 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_reg.h
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Register definition file for Samsung DP driver 2 * Register definition file for Analogix DP core driver
3 * 3 *
4 * Copyright (C) 2012 Samsung Electronics Co., Ltd. 4 * Copyright (C) 2012 Samsung Electronics Co., Ltd.
5 * Author: Jingoo Han <jg1.han@samsung.com> 5 * Author: Jingoo Han <jg1.han@samsung.com>
@@ -9,96 +9,104 @@
9 * published by the Free Software Foundation. 9 * published by the Free Software Foundation.
10 */ 10 */
11 11
12#ifndef _EXYNOS_DP_REG_H 12#ifndef _ANALOGIX_DP_REG_H
13#define _EXYNOS_DP_REG_H 13#define _ANALOGIX_DP_REG_H
14 14
15#define EXYNOS_DP_TX_SW_RESET 0x14 15#define ANALOGIX_DP_TX_SW_RESET 0x14
16#define EXYNOS_DP_FUNC_EN_1 0x18 16#define ANALOGIX_DP_FUNC_EN_1 0x18
17#define EXYNOS_DP_FUNC_EN_2 0x1C 17#define ANALOGIX_DP_FUNC_EN_2 0x1C
18#define EXYNOS_DP_VIDEO_CTL_1 0x20 18#define ANALOGIX_DP_VIDEO_CTL_1 0x20
19#define EXYNOS_DP_VIDEO_CTL_2 0x24 19#define ANALOGIX_DP_VIDEO_CTL_2 0x24
20#define EXYNOS_DP_VIDEO_CTL_3 0x28 20#define ANALOGIX_DP_VIDEO_CTL_3 0x28
21 21
22#define EXYNOS_DP_VIDEO_CTL_8 0x3C 22#define ANALOGIX_DP_VIDEO_CTL_8 0x3C
23#define EXYNOS_DP_VIDEO_CTL_10 0x44 23#define ANALOGIX_DP_VIDEO_CTL_10 0x44
24 24
25#define EXYNOS_DP_LANE_MAP 0x35C 25#define ANALOGIX_DP_PLL_REG_1 0xfc
26 26#define ANALOGIX_DP_PLL_REG_2 0x9e4
27#define EXYNOS_DP_ANALOG_CTL_1 0x370 27#define ANALOGIX_DP_PLL_REG_3 0x9e8
28#define EXYNOS_DP_ANALOG_CTL_2 0x374 28#define ANALOGIX_DP_PLL_REG_4 0x9ec
29#define EXYNOS_DP_ANALOG_CTL_3 0x378 29#define ANALOGIX_DP_PLL_REG_5 0xa00
30#define EXYNOS_DP_PLL_FILTER_CTL_1 0x37C 30
31#define EXYNOS_DP_TX_AMP_TUNING_CTL 0x380 31#define ANALOGIX_DP_PD 0x12c
32 32
33#define EXYNOS_DP_AUX_HW_RETRY_CTL 0x390 33#define ANALOGIX_DP_LANE_MAP 0x35C
34 34
35#define EXYNOS_DP_COMMON_INT_STA_1 0x3C4 35#define ANALOGIX_DP_ANALOG_CTL_1 0x370
36#define EXYNOS_DP_COMMON_INT_STA_2 0x3C8 36#define ANALOGIX_DP_ANALOG_CTL_2 0x374
37#define EXYNOS_DP_COMMON_INT_STA_3 0x3CC 37#define ANALOGIX_DP_ANALOG_CTL_3 0x378
38#define EXYNOS_DP_COMMON_INT_STA_4 0x3D0 38#define ANALOGIX_DP_PLL_FILTER_CTL_1 0x37C
39#define EXYNOS_DP_INT_STA 0x3DC 39#define ANALOGIX_DP_TX_AMP_TUNING_CTL 0x380
40#define EXYNOS_DP_COMMON_INT_MASK_1 0x3E0 40
41#define EXYNOS_DP_COMMON_INT_MASK_2 0x3E4 41#define ANALOGIX_DP_AUX_HW_RETRY_CTL 0x390
42#define EXYNOS_DP_COMMON_INT_MASK_3 0x3E8 42
43#define EXYNOS_DP_COMMON_INT_MASK_4 0x3EC 43#define ANALOGIX_DP_COMMON_INT_STA_1 0x3C4
44#define EXYNOS_DP_INT_STA_MASK 0x3F8 44#define ANALOGIX_DP_COMMON_INT_STA_2 0x3C8
45#define EXYNOS_DP_INT_CTL 0x3FC 45#define ANALOGIX_DP_COMMON_INT_STA_3 0x3CC
46 46#define ANALOGIX_DP_COMMON_INT_STA_4 0x3D0
47#define EXYNOS_DP_SYS_CTL_1 0x600 47#define ANALOGIX_DP_INT_STA 0x3DC
48#define EXYNOS_DP_SYS_CTL_2 0x604 48#define ANALOGIX_DP_COMMON_INT_MASK_1 0x3E0
49#define EXYNOS_DP_SYS_CTL_3 0x608 49#define ANALOGIX_DP_COMMON_INT_MASK_2 0x3E4
50#define EXYNOS_DP_SYS_CTL_4 0x60C 50#define ANALOGIX_DP_COMMON_INT_MASK_3 0x3E8
51 51#define ANALOGIX_DP_COMMON_INT_MASK_4 0x3EC
52#define EXYNOS_DP_PKT_SEND_CTL 0x640 52#define ANALOGIX_DP_INT_STA_MASK 0x3F8
53#define EXYNOS_DP_HDCP_CTL 0x648 53#define ANALOGIX_DP_INT_CTL 0x3FC
54 54
55#define EXYNOS_DP_LINK_BW_SET 0x680 55#define ANALOGIX_DP_SYS_CTL_1 0x600
56#define EXYNOS_DP_LANE_COUNT_SET 0x684 56#define ANALOGIX_DP_SYS_CTL_2 0x604
57#define EXYNOS_DP_TRAINING_PTN_SET 0x688 57#define ANALOGIX_DP_SYS_CTL_3 0x608
58#define EXYNOS_DP_LN0_LINK_TRAINING_CTL 0x68C 58#define ANALOGIX_DP_SYS_CTL_4 0x60C
59#define EXYNOS_DP_LN1_LINK_TRAINING_CTL 0x690 59
60#define EXYNOS_DP_LN2_LINK_TRAINING_CTL 0x694 60#define ANALOGIX_DP_PKT_SEND_CTL 0x640
61#define EXYNOS_DP_LN3_LINK_TRAINING_CTL 0x698 61#define ANALOGIX_DP_HDCP_CTL 0x648
62 62
63#define EXYNOS_DP_DEBUG_CTL 0x6C0 63#define ANALOGIX_DP_LINK_BW_SET 0x680
64#define EXYNOS_DP_HPD_DEGLITCH_L 0x6C4 64#define ANALOGIX_DP_LANE_COUNT_SET 0x684
65#define EXYNOS_DP_HPD_DEGLITCH_H 0x6C8 65#define ANALOGIX_DP_TRAINING_PTN_SET 0x688
66#define EXYNOS_DP_LINK_DEBUG_CTL 0x6E0 66#define ANALOGIX_DP_LN0_LINK_TRAINING_CTL 0x68C
67 67#define ANALOGIX_DP_LN1_LINK_TRAINING_CTL 0x690
68#define EXYNOS_DP_M_VID_0 0x700 68#define ANALOGIX_DP_LN2_LINK_TRAINING_CTL 0x694
69#define EXYNOS_DP_M_VID_1 0x704 69#define ANALOGIX_DP_LN3_LINK_TRAINING_CTL 0x698
70#define EXYNOS_DP_M_VID_2 0x708 70
71#define EXYNOS_DP_N_VID_0 0x70C 71#define ANALOGIX_DP_DEBUG_CTL 0x6C0
72#define EXYNOS_DP_N_VID_1 0x710 72#define ANALOGIX_DP_HPD_DEGLITCH_L 0x6C4
73#define EXYNOS_DP_N_VID_2 0x714 73#define ANALOGIX_DP_HPD_DEGLITCH_H 0x6C8
74 74#define ANALOGIX_DP_LINK_DEBUG_CTL 0x6E0
75#define EXYNOS_DP_PLL_CTL 0x71C 75
76#define EXYNOS_DP_PHY_PD 0x720 76#define ANALOGIX_DP_M_VID_0 0x700
77#define EXYNOS_DP_PHY_TEST 0x724 77#define ANALOGIX_DP_M_VID_1 0x704
78 78#define ANALOGIX_DP_M_VID_2 0x708
79#define EXYNOS_DP_VIDEO_FIFO_THRD 0x730 79#define ANALOGIX_DP_N_VID_0 0x70C
80#define EXYNOS_DP_AUDIO_MARGIN 0x73C 80#define ANALOGIX_DP_N_VID_1 0x710
81 81#define ANALOGIX_DP_N_VID_2 0x714
82#define EXYNOS_DP_M_VID_GEN_FILTER_TH 0x764 82
83#define EXYNOS_DP_M_AUD_GEN_FILTER_TH 0x778 83#define ANALOGIX_DP_PLL_CTL 0x71C
84#define EXYNOS_DP_AUX_CH_STA 0x780 84#define ANALOGIX_DP_PHY_PD 0x720
85#define EXYNOS_DP_AUX_CH_DEFER_CTL 0x788 85#define ANALOGIX_DP_PHY_TEST 0x724
86#define EXYNOS_DP_AUX_RX_COMM 0x78C 86
87#define EXYNOS_DP_BUFFER_DATA_CTL 0x790 87#define ANALOGIX_DP_VIDEO_FIFO_THRD 0x730
88#define EXYNOS_DP_AUX_CH_CTL_1 0x794 88#define ANALOGIX_DP_AUDIO_MARGIN 0x73C
89#define EXYNOS_DP_AUX_ADDR_7_0 0x798 89
90#define EXYNOS_DP_AUX_ADDR_15_8 0x79C 90#define ANALOGIX_DP_M_VID_GEN_FILTER_TH 0x764
91#define EXYNOS_DP_AUX_ADDR_19_16 0x7A0 91#define ANALOGIX_DP_M_AUD_GEN_FILTER_TH 0x778
92#define EXYNOS_DP_AUX_CH_CTL_2 0x7A4 92#define ANALOGIX_DP_AUX_CH_STA 0x780
93 93#define ANALOGIX_DP_AUX_CH_DEFER_CTL 0x788
94#define EXYNOS_DP_BUF_DATA_0 0x7C0 94#define ANALOGIX_DP_AUX_RX_COMM 0x78C
95 95#define ANALOGIX_DP_BUFFER_DATA_CTL 0x790
96#define EXYNOS_DP_SOC_GENERAL_CTL 0x800 96#define ANALOGIX_DP_AUX_CH_CTL_1 0x794
97 97#define ANALOGIX_DP_AUX_ADDR_7_0 0x798
98/* EXYNOS_DP_TX_SW_RESET */ 98#define ANALOGIX_DP_AUX_ADDR_15_8 0x79C
99#define ANALOGIX_DP_AUX_ADDR_19_16 0x7A0
100#define ANALOGIX_DP_AUX_CH_CTL_2 0x7A4
101
102#define ANALOGIX_DP_BUF_DATA_0 0x7C0
103
104#define ANALOGIX_DP_SOC_GENERAL_CTL 0x800
105
106/* ANALOGIX_DP_TX_SW_RESET */
99#define RESET_DP_TX (0x1 << 0) 107#define RESET_DP_TX (0x1 << 0)
100 108
101/* EXYNOS_DP_FUNC_EN_1 */ 109/* ANALOGIX_DP_FUNC_EN_1 */
102#define MASTER_VID_FUNC_EN_N (0x1 << 7) 110#define MASTER_VID_FUNC_EN_N (0x1 << 7)
103#define SLAVE_VID_FUNC_EN_N (0x1 << 5) 111#define SLAVE_VID_FUNC_EN_N (0x1 << 5)
104#define AUD_FIFO_FUNC_EN_N (0x1 << 4) 112#define AUD_FIFO_FUNC_EN_N (0x1 << 4)
@@ -107,17 +115,17 @@
107#define CRC_FUNC_EN_N (0x1 << 1) 115#define CRC_FUNC_EN_N (0x1 << 1)
108#define SW_FUNC_EN_N (0x1 << 0) 116#define SW_FUNC_EN_N (0x1 << 0)
109 117
110/* EXYNOS_DP_FUNC_EN_2 */ 118/* ANALOGIX_DP_FUNC_EN_2 */
111#define SSC_FUNC_EN_N (0x1 << 7) 119#define SSC_FUNC_EN_N (0x1 << 7)
112#define AUX_FUNC_EN_N (0x1 << 2) 120#define AUX_FUNC_EN_N (0x1 << 2)
113#define SERDES_FIFO_FUNC_EN_N (0x1 << 1) 121#define SERDES_FIFO_FUNC_EN_N (0x1 << 1)
114#define LS_CLK_DOMAIN_FUNC_EN_N (0x1 << 0) 122#define LS_CLK_DOMAIN_FUNC_EN_N (0x1 << 0)
115 123
116/* EXYNOS_DP_VIDEO_CTL_1 */ 124/* ANALOGIX_DP_VIDEO_CTL_1 */
117#define VIDEO_EN (0x1 << 7) 125#define VIDEO_EN (0x1 << 7)
118#define HDCP_VIDEO_MUTE (0x1 << 6) 126#define HDCP_VIDEO_MUTE (0x1 << 6)
119 127
120/* EXYNOS_DP_VIDEO_CTL_1 */ 128/* ANALOGIX_DP_VIDEO_CTL_1 */
121#define IN_D_RANGE_MASK (0x1 << 7) 129#define IN_D_RANGE_MASK (0x1 << 7)
122#define IN_D_RANGE_SHIFT (7) 130#define IN_D_RANGE_SHIFT (7)
123#define IN_D_RANGE_CEA (0x1 << 7) 131#define IN_D_RANGE_CEA (0x1 << 7)
@@ -134,7 +142,7 @@
134#define IN_COLOR_F_YCBCR422 (0x1 << 0) 142#define IN_COLOR_F_YCBCR422 (0x1 << 0)
135#define IN_COLOR_F_RGB (0x0 << 0) 143#define IN_COLOR_F_RGB (0x0 << 0)
136 144
137/* EXYNOS_DP_VIDEO_CTL_3 */ 145/* ANALOGIX_DP_VIDEO_CTL_3 */
138#define IN_YC_COEFFI_MASK (0x1 << 7) 146#define IN_YC_COEFFI_MASK (0x1 << 7)
139#define IN_YC_COEFFI_SHIFT (7) 147#define IN_YC_COEFFI_SHIFT (7)
140#define IN_YC_COEFFI_ITU709 (0x1 << 7) 148#define IN_YC_COEFFI_ITU709 (0x1 << 7)
@@ -144,17 +152,21 @@
144#define VID_CHK_UPDATE_TYPE_1 (0x1 << 4) 152#define VID_CHK_UPDATE_TYPE_1 (0x1 << 4)
145#define VID_CHK_UPDATE_TYPE_0 (0x0 << 4) 153#define VID_CHK_UPDATE_TYPE_0 (0x0 << 4)
146 154
147/* EXYNOS_DP_VIDEO_CTL_8 */ 155/* ANALOGIX_DP_VIDEO_CTL_8 */
148#define VID_HRES_TH(x) (((x) & 0xf) << 4) 156#define VID_HRES_TH(x) (((x) & 0xf) << 4)
149#define VID_VRES_TH(x) (((x) & 0xf) << 0) 157#define VID_VRES_TH(x) (((x) & 0xf) << 0)
150 158
151/* EXYNOS_DP_VIDEO_CTL_10 */ 159/* ANALOGIX_DP_VIDEO_CTL_10 */
152#define FORMAT_SEL (0x1 << 4) 160#define FORMAT_SEL (0x1 << 4)
153#define INTERACE_SCAN_CFG (0x1 << 2) 161#define INTERACE_SCAN_CFG (0x1 << 2)
154#define VSYNC_POLARITY_CFG (0x1 << 1) 162#define VSYNC_POLARITY_CFG (0x1 << 1)
155#define HSYNC_POLARITY_CFG (0x1 << 0) 163#define HSYNC_POLARITY_CFG (0x1 << 0)
156 164
157/* EXYNOS_DP_LANE_MAP */ 165/* ANALOGIX_DP_PLL_REG_1 */
166#define REF_CLK_24M (0x1 << 1)
167#define REF_CLK_27M (0x0 << 1)
168
169/* ANALOGIX_DP_LANE_MAP */
158#define LANE3_MAP_LOGIC_LANE_0 (0x0 << 6) 170#define LANE3_MAP_LOGIC_LANE_0 (0x0 << 6)
159#define LANE3_MAP_LOGIC_LANE_1 (0x1 << 6) 171#define LANE3_MAP_LOGIC_LANE_1 (0x1 << 6)
160#define LANE3_MAP_LOGIC_LANE_2 (0x2 << 6) 172#define LANE3_MAP_LOGIC_LANE_2 (0x2 << 6)
@@ -172,30 +184,30 @@
172#define LANE0_MAP_LOGIC_LANE_2 (0x2 << 0) 184#define LANE0_MAP_LOGIC_LANE_2 (0x2 << 0)
173#define LANE0_MAP_LOGIC_LANE_3 (0x3 << 0) 185#define LANE0_MAP_LOGIC_LANE_3 (0x3 << 0)
174 186
175/* EXYNOS_DP_ANALOG_CTL_1 */ 187/* ANALOGIX_DP_ANALOG_CTL_1 */
176#define TX_TERMINAL_CTRL_50_OHM (0x1 << 4) 188#define TX_TERMINAL_CTRL_50_OHM (0x1 << 4)
177 189
178/* EXYNOS_DP_ANALOG_CTL_2 */ 190/* ANALOGIX_DP_ANALOG_CTL_2 */
179#define SEL_24M (0x1 << 3) 191#define SEL_24M (0x1 << 3)
180#define TX_DVDD_BIT_1_0625V (0x4 << 0) 192#define TX_DVDD_BIT_1_0625V (0x4 << 0)
181 193
182/* EXYNOS_DP_ANALOG_CTL_3 */ 194/* ANALOGIX_DP_ANALOG_CTL_3 */
183#define DRIVE_DVDD_BIT_1_0625V (0x4 << 5) 195#define DRIVE_DVDD_BIT_1_0625V (0x4 << 5)
184#define VCO_BIT_600_MICRO (0x5 << 0) 196#define VCO_BIT_600_MICRO (0x5 << 0)
185 197
186/* EXYNOS_DP_PLL_FILTER_CTL_1 */ 198/* ANALOGIX_DP_PLL_FILTER_CTL_1 */
187#define PD_RING_OSC (0x1 << 6) 199#define PD_RING_OSC (0x1 << 6)
188#define AUX_TERMINAL_CTRL_50_OHM (0x2 << 4) 200#define AUX_TERMINAL_CTRL_50_OHM (0x2 << 4)
189#define TX_CUR1_2X (0x1 << 2) 201#define TX_CUR1_2X (0x1 << 2)
190#define TX_CUR_16_MA (0x3 << 0) 202#define TX_CUR_16_MA (0x3 << 0)
191 203
192/* EXYNOS_DP_TX_AMP_TUNING_CTL */ 204/* ANALOGIX_DP_TX_AMP_TUNING_CTL */
193#define CH3_AMP_400_MV (0x0 << 24) 205#define CH3_AMP_400_MV (0x0 << 24)
194#define CH2_AMP_400_MV (0x0 << 16) 206#define CH2_AMP_400_MV (0x0 << 16)
195#define CH1_AMP_400_MV (0x0 << 8) 207#define CH1_AMP_400_MV (0x0 << 8)
196#define CH0_AMP_400_MV (0x0 << 0) 208#define CH0_AMP_400_MV (0x0 << 0)
197 209
198/* EXYNOS_DP_AUX_HW_RETRY_CTL */ 210/* ANALOGIX_DP_AUX_HW_RETRY_CTL */
199#define AUX_BIT_PERIOD_EXPECTED_DELAY(x) (((x) & 0x7) << 8) 211#define AUX_BIT_PERIOD_EXPECTED_DELAY(x) (((x) & 0x7) << 8)
200#define AUX_HW_RETRY_INTERVAL_MASK (0x3 << 3) 212#define AUX_HW_RETRY_INTERVAL_MASK (0x3 << 3)
201#define AUX_HW_RETRY_INTERVAL_600_MICROSECONDS (0x0 << 3) 213#define AUX_HW_RETRY_INTERVAL_600_MICROSECONDS (0x0 << 3)
@@ -204,7 +216,7 @@
204#define AUX_HW_RETRY_INTERVAL_1800_MICROSECONDS (0x3 << 3) 216#define AUX_HW_RETRY_INTERVAL_1800_MICROSECONDS (0x3 << 3)
205#define AUX_HW_RETRY_COUNT_SEL(x) (((x) & 0x7) << 0) 217#define AUX_HW_RETRY_COUNT_SEL(x) (((x) & 0x7) << 0)
206 218
207/* EXYNOS_DP_COMMON_INT_STA_1 */ 219/* ANALOGIX_DP_COMMON_INT_STA_1 */
208#define VSYNC_DET (0x1 << 7) 220#define VSYNC_DET (0x1 << 7)
209#define PLL_LOCK_CHG (0x1 << 6) 221#define PLL_LOCK_CHG (0x1 << 6)
210#define SPDIF_ERR (0x1 << 5) 222#define SPDIF_ERR (0x1 << 5)
@@ -214,19 +226,19 @@
214#define VID_CLK_CHG (0x1 << 1) 226#define VID_CLK_CHG (0x1 << 1)
215#define SW_INT (0x1 << 0) 227#define SW_INT (0x1 << 0)
216 228
217/* EXYNOS_DP_COMMON_INT_STA_2 */ 229/* ANALOGIX_DP_COMMON_INT_STA_2 */
218#define ENC_EN_CHG (0x1 << 6) 230#define ENC_EN_CHG (0x1 << 6)
219#define HW_BKSV_RDY (0x1 << 3) 231#define HW_BKSV_RDY (0x1 << 3)
220#define HW_SHA_DONE (0x1 << 2) 232#define HW_SHA_DONE (0x1 << 2)
221#define HW_AUTH_STATE_CHG (0x1 << 1) 233#define HW_AUTH_STATE_CHG (0x1 << 1)
222#define HW_AUTH_DONE (0x1 << 0) 234#define HW_AUTH_DONE (0x1 << 0)
223 235
224/* EXYNOS_DP_COMMON_INT_STA_3 */ 236/* ANALOGIX_DP_COMMON_INT_STA_3 */
225#define AFIFO_UNDER (0x1 << 7) 237#define AFIFO_UNDER (0x1 << 7)
226#define AFIFO_OVER (0x1 << 6) 238#define AFIFO_OVER (0x1 << 6)
227#define R0_CHK_FLAG (0x1 << 5) 239#define R0_CHK_FLAG (0x1 << 5)
228 240
229/* EXYNOS_DP_COMMON_INT_STA_4 */ 241/* ANALOGIX_DP_COMMON_INT_STA_4 */
230#define PSR_ACTIVE (0x1 << 7) 242#define PSR_ACTIVE (0x1 << 7)
231#define PSR_INACTIVE (0x1 << 6) 243#define PSR_INACTIVE (0x1 << 6)
232#define SPDIF_BI_PHASE_ERR (0x1 << 5) 244#define SPDIF_BI_PHASE_ERR (0x1 << 5)
@@ -234,29 +246,29 @@
234#define HPD_LOST (0x1 << 1) 246#define HPD_LOST (0x1 << 1)
235#define PLUG (0x1 << 0) 247#define PLUG (0x1 << 0)
236 248
237/* EXYNOS_DP_INT_STA */ 249/* ANALOGIX_DP_INT_STA */
238#define INT_HPD (0x1 << 6) 250#define INT_HPD (0x1 << 6)
239#define HW_TRAINING_FINISH (0x1 << 5) 251#define HW_TRAINING_FINISH (0x1 << 5)
240#define RPLY_RECEIV (0x1 << 1) 252#define RPLY_RECEIV (0x1 << 1)
241#define AUX_ERR (0x1 << 0) 253#define AUX_ERR (0x1 << 0)
242 254
243/* EXYNOS_DP_INT_CTL */ 255/* ANALOGIX_DP_INT_CTL */
244#define SOFT_INT_CTRL (0x1 << 2) 256#define SOFT_INT_CTRL (0x1 << 2)
245#define INT_POL1 (0x1 << 1) 257#define INT_POL1 (0x1 << 1)
246#define INT_POL0 (0x1 << 0) 258#define INT_POL0 (0x1 << 0)
247 259
248/* EXYNOS_DP_SYS_CTL_1 */ 260/* ANALOGIX_DP_SYS_CTL_1 */
249#define DET_STA (0x1 << 2) 261#define DET_STA (0x1 << 2)
250#define FORCE_DET (0x1 << 1) 262#define FORCE_DET (0x1 << 1)
251#define DET_CTRL (0x1 << 0) 263#define DET_CTRL (0x1 << 0)
252 264
253/* EXYNOS_DP_SYS_CTL_2 */ 265/* ANALOGIX_DP_SYS_CTL_2 */
254#define CHA_CRI(x) (((x) & 0xf) << 4) 266#define CHA_CRI(x) (((x) & 0xf) << 4)
255#define CHA_STA (0x1 << 2) 267#define CHA_STA (0x1 << 2)
256#define FORCE_CHA (0x1 << 1) 268#define FORCE_CHA (0x1 << 1)
257#define CHA_CTRL (0x1 << 0) 269#define CHA_CTRL (0x1 << 0)
258 270
259/* EXYNOS_DP_SYS_CTL_3 */ 271/* ANALOGIX_DP_SYS_CTL_3 */
260#define HPD_STATUS (0x1 << 6) 272#define HPD_STATUS (0x1 << 6)
261#define F_HPD (0x1 << 5) 273#define F_HPD (0x1 << 5)
262#define HPD_CTRL (0x1 << 4) 274#define HPD_CTRL (0x1 << 4)
@@ -265,13 +277,13 @@
265#define F_VALID (0x1 << 1) 277#define F_VALID (0x1 << 1)
266#define VALID_CTRL (0x1 << 0) 278#define VALID_CTRL (0x1 << 0)
267 279
268/* EXYNOS_DP_SYS_CTL_4 */ 280/* ANALOGIX_DP_SYS_CTL_4 */
269#define FIX_M_AUD (0x1 << 4) 281#define FIX_M_AUD (0x1 << 4)
270#define ENHANCED (0x1 << 3) 282#define ENHANCED (0x1 << 3)
271#define FIX_M_VID (0x1 << 2) 283#define FIX_M_VID (0x1 << 2)
272#define M_VID_UPDATE_CTRL (0x3 << 0) 284#define M_VID_UPDATE_CTRL (0x3 << 0)
273 285
274/* EXYNOS_DP_TRAINING_PTN_SET */ 286/* ANALOGIX_DP_TRAINING_PTN_SET */
275#define SCRAMBLER_TYPE (0x1 << 9) 287#define SCRAMBLER_TYPE (0x1 << 9)
276#define HW_LINK_TRAINING_PATTERN (0x1 << 8) 288#define HW_LINK_TRAINING_PATTERN (0x1 << 8)
277#define SCRAMBLING_DISABLE (0x1 << 5) 289#define SCRAMBLING_DISABLE (0x1 << 5)
@@ -285,24 +297,24 @@
285#define SW_TRAINING_PATTERN_SET_PTN1 (0x1 << 0) 297#define SW_TRAINING_PATTERN_SET_PTN1 (0x1 << 0)
286#define SW_TRAINING_PATTERN_SET_NORMAL (0x0 << 0) 298#define SW_TRAINING_PATTERN_SET_NORMAL (0x0 << 0)
287 299
288/* EXYNOS_DP_LN0_LINK_TRAINING_CTL */ 300/* ANALOGIX_DP_LN0_LINK_TRAINING_CTL */
289#define PRE_EMPHASIS_SET_MASK (0x3 << 3) 301#define PRE_EMPHASIS_SET_MASK (0x3 << 3)
290#define PRE_EMPHASIS_SET_SHIFT (3) 302#define PRE_EMPHASIS_SET_SHIFT (3)
291 303
292/* EXYNOS_DP_DEBUG_CTL */ 304/* ANALOGIX_DP_DEBUG_CTL */
293#define PLL_LOCK (0x1 << 4) 305#define PLL_LOCK (0x1 << 4)
294#define F_PLL_LOCK (0x1 << 3) 306#define F_PLL_LOCK (0x1 << 3)
295#define PLL_LOCK_CTRL (0x1 << 2) 307#define PLL_LOCK_CTRL (0x1 << 2)
296#define PN_INV (0x1 << 0) 308#define PN_INV (0x1 << 0)
297 309
298/* EXYNOS_DP_PLL_CTL */ 310/* ANALOGIX_DP_PLL_CTL */
299#define DP_PLL_PD (0x1 << 7) 311#define DP_PLL_PD (0x1 << 7)
300#define DP_PLL_RESET (0x1 << 6) 312#define DP_PLL_RESET (0x1 << 6)
301#define DP_PLL_LOOP_BIT_DEFAULT (0x1 << 4) 313#define DP_PLL_LOOP_BIT_DEFAULT (0x1 << 4)
302#define DP_PLL_REF_BIT_1_1250V (0x5 << 0) 314#define DP_PLL_REF_BIT_1_1250V (0x5 << 0)
303#define DP_PLL_REF_BIT_1_2500V (0x7 << 0) 315#define DP_PLL_REF_BIT_1_2500V (0x7 << 0)
304 316
305/* EXYNOS_DP_PHY_PD */ 317/* ANALOGIX_DP_PHY_PD */
306#define DP_PHY_PD (0x1 << 5) 318#define DP_PHY_PD (0x1 << 5)
307#define AUX_PD (0x1 << 4) 319#define AUX_PD (0x1 << 4)
308#define CH3_PD (0x1 << 3) 320#define CH3_PD (0x1 << 3)
@@ -310,28 +322,28 @@
310#define CH1_PD (0x1 << 1) 322#define CH1_PD (0x1 << 1)
311#define CH0_PD (0x1 << 0) 323#define CH0_PD (0x1 << 0)
312 324
313/* EXYNOS_DP_PHY_TEST */ 325/* ANALOGIX_DP_PHY_TEST */
314#define MACRO_RST (0x1 << 5) 326#define MACRO_RST (0x1 << 5)
315#define CH1_TEST (0x1 << 1) 327#define CH1_TEST (0x1 << 1)
316#define CH0_TEST (0x1 << 0) 328#define CH0_TEST (0x1 << 0)
317 329
318/* EXYNOS_DP_AUX_CH_STA */ 330/* ANALOGIX_DP_AUX_CH_STA */
319#define AUX_BUSY (0x1 << 4) 331#define AUX_BUSY (0x1 << 4)
320#define AUX_STATUS_MASK (0xf << 0) 332#define AUX_STATUS_MASK (0xf << 0)
321 333
322/* EXYNOS_DP_AUX_CH_DEFER_CTL */ 334/* ANALOGIX_DP_AUX_CH_DEFER_CTL */
323#define DEFER_CTRL_EN (0x1 << 7) 335#define DEFER_CTRL_EN (0x1 << 7)
324#define DEFER_COUNT(x) (((x) & 0x7f) << 0) 336#define DEFER_COUNT(x) (((x) & 0x7f) << 0)
325 337
326/* EXYNOS_DP_AUX_RX_COMM */ 338/* ANALOGIX_DP_AUX_RX_COMM */
327#define AUX_RX_COMM_I2C_DEFER (0x2 << 2) 339#define AUX_RX_COMM_I2C_DEFER (0x2 << 2)
328#define AUX_RX_COMM_AUX_DEFER (0x2 << 0) 340#define AUX_RX_COMM_AUX_DEFER (0x2 << 0)
329 341
330/* EXYNOS_DP_BUFFER_DATA_CTL */ 342/* ANALOGIX_DP_BUFFER_DATA_CTL */
331#define BUF_CLR (0x1 << 7) 343#define BUF_CLR (0x1 << 7)
332#define BUF_DATA_COUNT(x) (((x) & 0x1f) << 0) 344#define BUF_DATA_COUNT(x) (((x) & 0x1f) << 0)
333 345
334/* EXYNOS_DP_AUX_CH_CTL_1 */ 346/* ANALOGIX_DP_AUX_CH_CTL_1 */
335#define AUX_LENGTH(x) (((x - 1) & 0xf) << 4) 347#define AUX_LENGTH(x) (((x - 1) & 0xf) << 4)
336#define AUX_TX_COMM_MASK (0xf << 0) 348#define AUX_TX_COMM_MASK (0xf << 0)
337#define AUX_TX_COMM_DP_TRANSACTION (0x1 << 3) 349#define AUX_TX_COMM_DP_TRANSACTION (0x1 << 3)
@@ -340,20 +352,20 @@
340#define AUX_TX_COMM_WRITE (0x0 << 0) 352#define AUX_TX_COMM_WRITE (0x0 << 0)
341#define AUX_TX_COMM_READ (0x1 << 0) 353#define AUX_TX_COMM_READ (0x1 << 0)
342 354
343/* EXYNOS_DP_AUX_ADDR_7_0 */ 355/* ANALOGIX_DP_AUX_ADDR_7_0 */
344#define AUX_ADDR_7_0(x) (((x) >> 0) & 0xff) 356#define AUX_ADDR_7_0(x) (((x) >> 0) & 0xff)
345 357
346/* EXYNOS_DP_AUX_ADDR_15_8 */ 358/* ANALOGIX_DP_AUX_ADDR_15_8 */
347#define AUX_ADDR_15_8(x) (((x) >> 8) & 0xff) 359#define AUX_ADDR_15_8(x) (((x) >> 8) & 0xff)
348 360
349/* EXYNOS_DP_AUX_ADDR_19_16 */ 361/* ANALOGIX_DP_AUX_ADDR_19_16 */
350#define AUX_ADDR_19_16(x) (((x) >> 16) & 0x0f) 362#define AUX_ADDR_19_16(x) (((x) >> 16) & 0x0f)
351 363
352/* EXYNOS_DP_AUX_CH_CTL_2 */ 364/* ANALOGIX_DP_AUX_CH_CTL_2 */
353#define ADDR_ONLY (0x1 << 1) 365#define ADDR_ONLY (0x1 << 1)
354#define AUX_EN (0x1 << 0) 366#define AUX_EN (0x1 << 0)
355 367
356/* EXYNOS_DP_SOC_GENERAL_CTL */ 368/* ANALOGIX_DP_SOC_GENERAL_CTL */
357#define AUDIO_MODE_SPDIF_MODE (0x1 << 8) 369#define AUDIO_MODE_SPDIF_MODE (0x1 << 8)
358#define AUDIO_MODE_MASTER_MODE (0x0 << 8) 370#define AUDIO_MODE_MASTER_MODE (0x0 << 8)
359#define MASTER_VIDEO_INTERLACE_EN (0x1 << 4) 371#define MASTER_VIDEO_INTERLACE_EN (0x1 << 4)
@@ -363,4 +375,4 @@
363#define VIDEO_MODE_SLAVE_MODE (0x1 << 0) 375#define VIDEO_MODE_SLAVE_MODE (0x1 << 0)
364#define VIDEO_MODE_MASTER_MODE (0x0 << 0) 376#define VIDEO_MODE_MASTER_MODE (0x0 << 0)
365 377
366#endif /* _EXYNOS_DP_REG_H */ 378#endif /* _ANALOGIX_DP_REG_H */
diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index f17d39279596..2fadd8275fa5 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -71,8 +71,9 @@ config DRM_EXYNOS_DSI
71 This enables support for Exynos MIPI-DSI device. 71 This enables support for Exynos MIPI-DSI device.
72 72
73config DRM_EXYNOS_DP 73config DRM_EXYNOS_DP
74 bool "Display Port" 74 bool "EXYNOS specific extensions for Analogix DP driver"
75 depends on DRM_EXYNOS_FIMD || DRM_EXYNOS7_DECON 75 depends on DRM_EXYNOS_FIMD || DRM_EXYNOS7_DECON
76 select DRM_ANALOGIX_DP
76 default DRM_EXYNOS 77 default DRM_EXYNOS
77 select DRM_PANEL 78 select DRM_PANEL
78 help 79 help
diff --git a/drivers/gpu/drm/exynos/Makefile b/drivers/gpu/drm/exynos/Makefile
index 968b31c522b2..126b0a1915db 100644
--- a/drivers/gpu/drm/exynos/Makefile
+++ b/drivers/gpu/drm/exynos/Makefile
@@ -12,7 +12,7 @@ exynosdrm-$(CONFIG_DRM_EXYNOS5433_DECON) += exynos5433_drm_decon.o
12exynosdrm-$(CONFIG_DRM_EXYNOS7_DECON) += exynos7_drm_decon.o 12exynosdrm-$(CONFIG_DRM_EXYNOS7_DECON) += exynos7_drm_decon.o
13exynosdrm-$(CONFIG_DRM_EXYNOS_DPI) += exynos_drm_dpi.o 13exynosdrm-$(CONFIG_DRM_EXYNOS_DPI) += exynos_drm_dpi.o
14exynosdrm-$(CONFIG_DRM_EXYNOS_DSI) += exynos_drm_dsi.o 14exynosdrm-$(CONFIG_DRM_EXYNOS_DSI) += exynos_drm_dsi.o
15exynosdrm-$(CONFIG_DRM_EXYNOS_DP) += exynos_dp_core.o exynos_dp_reg.o 15exynosdrm-$(CONFIG_DRM_EXYNOS_DP) += exynos_dp.o
16exynosdrm-$(CONFIG_DRM_EXYNOS_MIXER) += exynos_mixer.o 16exynosdrm-$(CONFIG_DRM_EXYNOS_MIXER) += exynos_mixer.o
17exynosdrm-$(CONFIG_DRM_EXYNOS_HDMI) += exynos_hdmi.o 17exynosdrm-$(CONFIG_DRM_EXYNOS_HDMI) += exynos_hdmi.o
18exynosdrm-$(CONFIG_DRM_EXYNOS_VIDI) += exynos_drm_vidi.o 18exynosdrm-$(CONFIG_DRM_EXYNOS_VIDI) += exynos_drm_vidi.o
diff --git a/drivers/gpu/drm/exynos/exynos_dp.c b/drivers/gpu/drm/exynos/exynos_dp.c
new file mode 100644
index 000000000000..8ae3d51b5b33
--- /dev/null
+++ b/drivers/gpu/drm/exynos/exynos_dp.c
@@ -0,0 +1,314 @@
1/*
2 * Samsung SoC DP (Display Port) interface driver.
3 *
4 * Copyright (C) 2012 Samsung Electronics Co., Ltd.
5 * Author: Jingoo Han <jg1.han@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/module.h>
14#include <linux/platform_device.h>
15#include <linux/err.h>
16#include <linux/clk.h>
17#include <linux/of_graph.h>
18#include <linux/component.h>
19#include <video/of_display_timing.h>
20#include <video/of_videomode.h>
21#include <video/videomode.h>
22
23#include <drm/drmP.h>
24#include <drm/drm_crtc.h>
25#include <drm/drm_crtc_helper.h>
26#include <drm/drm_panel.h>
27
28#include <drm/bridge/analogix_dp.h>
29#include <drm/exynos_drm.h>
30
31#include "exynos_drm_crtc.h"
32
33#define to_dp(nm) container_of(nm, struct exynos_dp_device, nm)
34
35struct exynos_dp_device {
36 struct drm_encoder encoder;
37 struct drm_connector connector;
38 struct drm_bridge *ptn_bridge;
39 struct drm_device *drm_dev;
40 struct device *dev;
41
42 struct videomode vm;
43 struct analogix_dp_plat_data plat_data;
44};
45
46int exynos_dp_crtc_clock_enable(struct analogix_dp_plat_data *plat_data,
47 bool enable)
48{
49 struct exynos_dp_device *dp = to_dp(plat_data);
50 struct drm_encoder *encoder = &dp->encoder;
51 struct exynos_drm_crtc *crtc;
52
53 if (!encoder)
54 return -1;
55
56 crtc = to_exynos_crtc(encoder->crtc);
57 if (crtc && crtc->ops && crtc->ops->clock_enable)
58 crtc->ops->clock_enable(crtc, enable);
59
60 return 0;
61}
62
63static int exynos_dp_poweron(struct analogix_dp_plat_data *plat_data)
64{
65 return exynos_dp_crtc_clock_enable(plat_data, true);
66}
67
68static int exynos_dp_poweroff(struct analogix_dp_plat_data *plat_data)
69{
70 return exynos_dp_crtc_clock_enable(plat_data, false);
71}
72
73static int exynos_dp_get_modes(struct analogix_dp_plat_data *plat_data)
74{
75 struct exynos_dp_device *dp = to_dp(plat_data);
76 struct drm_connector *connector = &dp->connector;
77 struct drm_display_mode *mode;
78 int num_modes = 0;
79
80 if (dp->plat_data.panel)
81 return num_modes;
82
83 mode = drm_mode_create(connector->dev);
84 if (!mode) {
85 DRM_ERROR("failed to create a new display mode.\n");
86 return num_modes;
87 }
88
89 drm_display_mode_from_videomode(&dp->vm, mode);
90 connector->display_info.width_mm = mode->width_mm;
91 connector->display_info.height_mm = mode->height_mm;
92
93 mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
94 drm_mode_set_name(mode);
95 drm_mode_probed_add(connector, mode);
96
97 return num_modes + 1;
98}
99
100static int exynos_dp_bridge_attach(struct analogix_dp_plat_data *plat_data,
101 struct drm_bridge *bridge,
102 struct drm_connector *connector)
103{
104 struct exynos_dp_device *dp = to_dp(plat_data);
105 struct drm_encoder *encoder = &dp->encoder;
106 int ret;
107
108 drm_connector_register(connector);
109
110 /* Pre-empt DP connector creation if there's a bridge */
111 if (dp->ptn_bridge) {
112 bridge->next = dp->ptn_bridge;
113 dp->ptn_bridge->encoder = encoder;
114 ret = drm_bridge_attach(encoder->dev, dp->ptn_bridge);
115 if (ret) {
116 DRM_ERROR("Failed to attach bridge to drm\n");
117 bridge->next = NULL;
118 return ret;
119 }
120 }
121
122 return 0;
123}
124
125static void exynos_dp_mode_set(struct drm_encoder *encoder,
126 struct drm_display_mode *mode,
127 struct drm_display_mode *adjusted_mode)
128{
129}
130
131static void exynos_dp_nop(struct drm_encoder *encoder)
132{
133 /* do nothing */
134}
135
136static const struct drm_encoder_helper_funcs exynos_dp_encoder_helper_funcs = {
137 .mode_set = exynos_dp_mode_set,
138 .enable = exynos_dp_nop,
139 .disable = exynos_dp_nop,
140};
141
142static const struct drm_encoder_funcs exynos_dp_encoder_funcs = {
143 .destroy = drm_encoder_cleanup,
144};
145
146static int exynos_dp_dt_parse_panel(struct exynos_dp_device *dp)
147{
148 int ret;
149
150 ret = of_get_videomode(dp->dev->of_node, &dp->vm, OF_USE_NATIVE_MODE);
151 if (ret) {
152 DRM_ERROR("failed: of_get_videomode() : %d\n", ret);
153 return ret;
154 }
155 return 0;
156}
157
158static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
159{
160 struct exynos_dp_device *dp = dev_get_drvdata(dev);
161 struct drm_encoder *encoder = &dp->encoder;
162 struct drm_device *drm_dev = data;
163 int pipe, ret;
164
165 /*
166 * Just like the probe function said, we don't need the
167 * device drvrate anymore, we should leave the charge to
168 * analogix dp driver, set the device drvdata to NULL.
169 */
170 dev_set_drvdata(dev, NULL);
171
172 dp->dev = dev;
173 dp->drm_dev = drm_dev;
174
175 dp->plat_data.dev_type = EXYNOS_DP;
176 dp->plat_data.power_on = exynos_dp_poweron;
177 dp->plat_data.power_off = exynos_dp_poweroff;
178 dp->plat_data.attach = exynos_dp_bridge_attach;
179 dp->plat_data.get_modes = exynos_dp_get_modes;
180
181 if (!dp->plat_data.panel && !dp->ptn_bridge) {
182 ret = exynos_dp_dt_parse_panel(dp);
183 if (ret)
184 return ret;
185 }
186
187 pipe = exynos_drm_crtc_get_pipe_from_type(drm_dev,
188 EXYNOS_DISPLAY_TYPE_LCD);
189 if (pipe < 0)
190 return pipe;
191
192 encoder->possible_crtcs = 1 << pipe;
193
194 DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
195
196 drm_encoder_init(drm_dev, encoder, &exynos_dp_encoder_funcs,
197 DRM_MODE_ENCODER_TMDS, NULL);
198
199 drm_encoder_helper_add(encoder, &exynos_dp_encoder_helper_funcs);
200
201 dp->plat_data.encoder = encoder;
202
203 return analogix_dp_bind(dev, dp->drm_dev, &dp->plat_data);
204}
205
206static void exynos_dp_unbind(struct device *dev, struct device *master,
207 void *data)
208{
209 return analogix_dp_unbind(dev, master, data);
210}
211
212static const struct component_ops exynos_dp_ops = {
213 .bind = exynos_dp_bind,
214 .unbind = exynos_dp_unbind,
215};
216
217static int exynos_dp_probe(struct platform_device *pdev)
218{
219 struct device *dev = &pdev->dev;
220 struct device_node *np = NULL, *endpoint = NULL;
221 struct exynos_dp_device *dp;
222
223 dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),
224 GFP_KERNEL);
225 if (!dp)
226 return -ENOMEM;
227
228 /*
229 * We just use the drvdata until driver run into component
230 * add function, and then we would set drvdata to null, so
231 * that analogix dp driver would take charge of the drvdata.
232 */
233 platform_set_drvdata(pdev, dp);
234
235 /* This is for the backward compatibility. */
236 np = of_parse_phandle(dev->of_node, "panel", 0);
237 if (np) {
238 dp->plat_data.panel = of_drm_find_panel(np);
239 of_node_put(np);
240 if (!dp->plat_data.panel)
241 return -EPROBE_DEFER;
242 goto out;
243 }
244
245 endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
246 if (endpoint) {
247 np = of_graph_get_remote_port_parent(endpoint);
248 if (np) {
249 /* The remote port can be either a panel or a bridge */
250 dp->plat_data.panel = of_drm_find_panel(np);
251 if (!dp->plat_data.panel) {
252 dp->ptn_bridge = of_drm_find_bridge(np);
253 if (!dp->ptn_bridge) {
254 of_node_put(np);
255 return -EPROBE_DEFER;
256 }
257 }
258 of_node_put(np);
259 } else {
260 DRM_ERROR("no remote endpoint device node found.\n");
261 return -EINVAL;
262 }
263 } else {
264 DRM_ERROR("no port endpoint subnode found.\n");
265 return -EINVAL;
266 }
267
268out:
269 return component_add(&pdev->dev, &exynos_dp_ops);
270}
271
272static int exynos_dp_remove(struct platform_device *pdev)
273{
274 component_del(&pdev->dev, &exynos_dp_ops);
275
276 return 0;
277}
278
279#ifdef CONFIG_PM
280static int exynos_dp_suspend(struct device *dev)
281{
282 return analogix_dp_suspend(dev);
283}
284
285static int exynos_dp_resume(struct device *dev)
286{
287 return analogix_dp_resume(dev);
288}
289#endif
290
291static const struct dev_pm_ops exynos_dp_pm_ops = {
292 SET_RUNTIME_PM_OPS(exynos_dp_suspend, exynos_dp_resume, NULL)
293};
294
295static const struct of_device_id exynos_dp_match[] = {
296 { .compatible = "samsung,exynos5-dp" },
297 {},
298};
299MODULE_DEVICE_TABLE(of, exynos_dp_match);
300
301struct platform_driver dp_driver = {
302 .probe = exynos_dp_probe,
303 .remove = exynos_dp_remove,
304 .driver = {
305 .name = "exynos-dp",
306 .owner = THIS_MODULE,
307 .pm = &exynos_dp_pm_ops,
308 .of_match_table = exynos_dp_match,
309 },
310};
311
312MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>");
313MODULE_DESCRIPTION("Samsung Specific Analogix-DP Driver Extension");
314MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c
deleted file mode 100644
index cff8dc788820..000000000000
--- a/drivers/gpu/drm/exynos/exynos_dp_core.c
+++ /dev/null
@@ -1,1499 +0,0 @@
1/*
2 * Samsung SoC DP (Display Port) interface driver.
3 *
4 * Copyright (C) 2012 Samsung Electronics Co., Ltd.
5 * Author: Jingoo Han <jg1.han@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/module.h>
14#include <linux/platform_device.h>
15#include <linux/err.h>
16#include <linux/clk.h>
17#include <linux/io.h>
18#include <linux/interrupt.h>
19#include <linux/of.h>
20#include <linux/of_gpio.h>
21#include <linux/of_graph.h>
22#include <linux/gpio.h>
23#include <linux/component.h>
24#include <linux/phy/phy.h>
25#include <video/of_display_timing.h>
26#include <video/of_videomode.h>
27
28#include <drm/drmP.h>
29#include <drm/drm_crtc.h>
30#include <drm/drm_crtc_helper.h>
31#include <drm/drm_atomic_helper.h>
32#include <drm/drm_panel.h>
33
34#include "exynos_dp_core.h"
35#include "exynos_drm_crtc.h"
36
37#define ctx_from_connector(c) container_of(c, struct exynos_dp_device, \
38 connector)
39
40static inline struct exynos_drm_crtc *dp_to_crtc(struct exynos_dp_device *dp)
41{
42 return to_exynos_crtc(dp->encoder.crtc);
43}
44
45static inline struct exynos_dp_device *encoder_to_dp(
46 struct drm_encoder *e)
47{
48 return container_of(e, struct exynos_dp_device, encoder);
49}
50
51struct bridge_init {
52 struct i2c_client *client;
53 struct device_node *node;
54};
55
56static void exynos_dp_init_dp(struct exynos_dp_device *dp)
57{
58 exynos_dp_reset(dp);
59
60 exynos_dp_swreset(dp);
61
62 exynos_dp_init_analog_param(dp);
63 exynos_dp_init_interrupt(dp);
64
65 /* SW defined function Normal operation */
66 exynos_dp_enable_sw_function(dp);
67
68 exynos_dp_config_interrupt(dp);
69 exynos_dp_init_analog_func(dp);
70
71 exynos_dp_init_hpd(dp);
72 exynos_dp_init_aux(dp);
73}
74
75static int exynos_dp_detect_hpd(struct exynos_dp_device *dp)
76{
77 int timeout_loop = 0;
78
79 while (exynos_dp_get_plug_in_status(dp) != 0) {
80 timeout_loop++;
81 if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
82 dev_err(dp->dev, "failed to get hpd plug status\n");
83 return -ETIMEDOUT;
84 }
85 usleep_range(10, 11);
86 }
87
88 return 0;
89}
90
91static unsigned char exynos_dp_calc_edid_check_sum(unsigned char *edid_data)
92{
93 int i;
94 unsigned char sum = 0;
95
96 for (i = 0; i < EDID_BLOCK_LENGTH; i++)
97 sum = sum + edid_data[i];
98
99 return sum;
100}
101
102static int exynos_dp_read_edid(struct exynos_dp_device *dp)
103{
104 unsigned char edid[EDID_BLOCK_LENGTH * 2];
105 unsigned int extend_block = 0;
106 unsigned char sum;
107 unsigned char test_vector;
108 int retval;
109
110 /*
111 * EDID device address is 0x50.
112 * However, if necessary, you must have set upper address
113 * into E-EDID in I2C device, 0x30.
114 */
115
116 /* Read Extension Flag, Number of 128-byte EDID extension blocks */
117 retval = exynos_dp_read_byte_from_i2c(dp, I2C_EDID_DEVICE_ADDR,
118 EDID_EXTENSION_FLAG,
119 &extend_block);
120 if (retval)
121 return retval;
122
123 if (extend_block > 0) {
124 dev_dbg(dp->dev, "EDID data includes a single extension!\n");
125
126 /* Read EDID data */
127 retval = exynos_dp_read_bytes_from_i2c(dp, I2C_EDID_DEVICE_ADDR,
128 EDID_HEADER_PATTERN,
129 EDID_BLOCK_LENGTH,
130 &edid[EDID_HEADER_PATTERN]);
131 if (retval != 0) {
132 dev_err(dp->dev, "EDID Read failed!\n");
133 return -EIO;
134 }
135 sum = exynos_dp_calc_edid_check_sum(edid);
136 if (sum != 0) {
137 dev_err(dp->dev, "EDID bad checksum!\n");
138 return -EIO;
139 }
140
141 /* Read additional EDID data */
142 retval = exynos_dp_read_bytes_from_i2c(dp,
143 I2C_EDID_DEVICE_ADDR,
144 EDID_BLOCK_LENGTH,
145 EDID_BLOCK_LENGTH,
146 &edid[EDID_BLOCK_LENGTH]);
147 if (retval != 0) {
148 dev_err(dp->dev, "EDID Read failed!\n");
149 return -EIO;
150 }
151 sum = exynos_dp_calc_edid_check_sum(&edid[EDID_BLOCK_LENGTH]);
152 if (sum != 0) {
153 dev_err(dp->dev, "EDID bad checksum!\n");
154 return -EIO;
155 }
156
157 exynos_dp_read_byte_from_dpcd(dp, DP_TEST_REQUEST,
158 &test_vector);
159 if (test_vector & DP_TEST_LINK_EDID_READ) {
160 exynos_dp_write_byte_to_dpcd(dp,
161 DP_TEST_EDID_CHECKSUM,
162 edid[EDID_BLOCK_LENGTH + EDID_CHECKSUM]);
163 exynos_dp_write_byte_to_dpcd(dp,
164 DP_TEST_RESPONSE,
165 DP_TEST_EDID_CHECKSUM_WRITE);
166 }
167 } else {
168 dev_info(dp->dev, "EDID data does not include any extensions.\n");
169
170 /* Read EDID data */
171 retval = exynos_dp_read_bytes_from_i2c(dp,
172 I2C_EDID_DEVICE_ADDR,
173 EDID_HEADER_PATTERN,
174 EDID_BLOCK_LENGTH,
175 &edid[EDID_HEADER_PATTERN]);
176 if (retval != 0) {
177 dev_err(dp->dev, "EDID Read failed!\n");
178 return -EIO;
179 }
180 sum = exynos_dp_calc_edid_check_sum(edid);
181 if (sum != 0) {
182 dev_err(dp->dev, "EDID bad checksum!\n");
183 return -EIO;
184 }
185
186 exynos_dp_read_byte_from_dpcd(dp,
187 DP_TEST_REQUEST,
188 &test_vector);
189 if (test_vector & DP_TEST_LINK_EDID_READ) {
190 exynos_dp_write_byte_to_dpcd(dp,
191 DP_TEST_EDID_CHECKSUM,
192 edid[EDID_CHECKSUM]);
193 exynos_dp_write_byte_to_dpcd(dp,
194 DP_TEST_RESPONSE,
195 DP_TEST_EDID_CHECKSUM_WRITE);
196 }
197 }
198
199 dev_dbg(dp->dev, "EDID Read success!\n");
200 return 0;
201}
202
203static int exynos_dp_handle_edid(struct exynos_dp_device *dp)
204{
205 u8 buf[12];
206 int i;
207 int retval;
208
209 /* Read DPCD DP_DPCD_REV~RECEIVE_PORT1_CAP_1 */
210 retval = exynos_dp_read_bytes_from_dpcd(dp, DP_DPCD_REV,
211 12, buf);
212 if (retval)
213 return retval;
214
215 /* Read EDID */
216 for (i = 0; i < 3; i++) {
217 retval = exynos_dp_read_edid(dp);
218 if (!retval)
219 break;
220 }
221
222 return retval;
223}
224
225static void exynos_dp_enable_rx_to_enhanced_mode(struct exynos_dp_device *dp,
226 bool enable)
227{
228 u8 data;
229
230 exynos_dp_read_byte_from_dpcd(dp, DP_LANE_COUNT_SET, &data);
231
232 if (enable)
233 exynos_dp_write_byte_to_dpcd(dp, DP_LANE_COUNT_SET,
234 DP_LANE_COUNT_ENHANCED_FRAME_EN |
235 DPCD_LANE_COUNT_SET(data));
236 else
237 exynos_dp_write_byte_to_dpcd(dp, DP_LANE_COUNT_SET,
238 DPCD_LANE_COUNT_SET(data));
239}
240
241static int exynos_dp_is_enhanced_mode_available(struct exynos_dp_device *dp)
242{
243 u8 data;
244 int retval;
245
246 exynos_dp_read_byte_from_dpcd(dp, DP_MAX_LANE_COUNT, &data);
247 retval = DPCD_ENHANCED_FRAME_CAP(data);
248
249 return retval;
250}
251
252static void exynos_dp_set_enhanced_mode(struct exynos_dp_device *dp)
253{
254 u8 data;
255
256 data = exynos_dp_is_enhanced_mode_available(dp);
257 exynos_dp_enable_rx_to_enhanced_mode(dp, data);
258 exynos_dp_enable_enhanced_mode(dp, data);
259}
260
261static void exynos_dp_training_pattern_dis(struct exynos_dp_device *dp)
262{
263 exynos_dp_set_training_pattern(dp, DP_NONE);
264
265 exynos_dp_write_byte_to_dpcd(dp,
266 DP_TRAINING_PATTERN_SET,
267 DP_TRAINING_PATTERN_DISABLE);
268}
269
270static void exynos_dp_set_lane_lane_pre_emphasis(struct exynos_dp_device *dp,
271 int pre_emphasis, int lane)
272{
273 switch (lane) {
274 case 0:
275 exynos_dp_set_lane0_pre_emphasis(dp, pre_emphasis);
276 break;
277 case 1:
278 exynos_dp_set_lane1_pre_emphasis(dp, pre_emphasis);
279 break;
280
281 case 2:
282 exynos_dp_set_lane2_pre_emphasis(dp, pre_emphasis);
283 break;
284
285 case 3:
286 exynos_dp_set_lane3_pre_emphasis(dp, pre_emphasis);
287 break;
288 }
289}
290
291static int exynos_dp_link_start(struct exynos_dp_device *dp)
292{
293 u8 buf[4];
294 int lane, lane_count, pll_tries, retval;
295
296 lane_count = dp->link_train.lane_count;
297
298 dp->link_train.lt_state = CLOCK_RECOVERY;
299 dp->link_train.eq_loop = 0;
300
301 for (lane = 0; lane < lane_count; lane++)
302 dp->link_train.cr_loop[lane] = 0;
303
304 /* Set link rate and count as you want to establish*/
305 exynos_dp_set_link_bandwidth(dp, dp->link_train.link_rate);
306 exynos_dp_set_lane_count(dp, dp->link_train.lane_count);
307
308 /* Setup RX configuration */
309 buf[0] = dp->link_train.link_rate;
310 buf[1] = dp->link_train.lane_count;
311 retval = exynos_dp_write_bytes_to_dpcd(dp, DP_LINK_BW_SET,
312 2, buf);
313 if (retval)
314 return retval;
315
316 /* Set TX pre-emphasis to minimum */
317 for (lane = 0; lane < lane_count; lane++)
318 exynos_dp_set_lane_lane_pre_emphasis(dp,
319 PRE_EMPHASIS_LEVEL_0, lane);
320
321 /* Wait for PLL lock */
322 pll_tries = 0;
323 while (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
324 if (pll_tries == DP_TIMEOUT_LOOP_COUNT) {
325 dev_err(dp->dev, "Wait for PLL lock timed out\n");
326 return -ETIMEDOUT;
327 }
328
329 pll_tries++;
330 usleep_range(90, 120);
331 }
332
333 /* Set training pattern 1 */
334 exynos_dp_set_training_pattern(dp, TRAINING_PTN1);
335
336 /* Set RX training pattern */
337 retval = exynos_dp_write_byte_to_dpcd(dp,
338 DP_TRAINING_PATTERN_SET,
339 DP_LINK_SCRAMBLING_DISABLE | DP_TRAINING_PATTERN_1);
340 if (retval)
341 return retval;
342
343 for (lane = 0; lane < lane_count; lane++)
344 buf[lane] = DP_TRAIN_PRE_EMPH_LEVEL_0 |
345 DP_TRAIN_VOLTAGE_SWING_LEVEL_0;
346
347 retval = exynos_dp_write_bytes_to_dpcd(dp, DP_TRAINING_LANE0_SET,
348 lane_count, buf);
349
350 return retval;
351}
352
353static unsigned char exynos_dp_get_lane_status(u8 link_status[2], int lane)
354{
355 int shift = (lane & 1) * 4;
356 u8 link_value = link_status[lane>>1];
357
358 return (link_value >> shift) & 0xf;
359}
360
361static int exynos_dp_clock_recovery_ok(u8 link_status[2], int lane_count)
362{
363 int lane;
364 u8 lane_status;
365
366 for (lane = 0; lane < lane_count; lane++) {
367 lane_status = exynos_dp_get_lane_status(link_status, lane);
368 if ((lane_status & DP_LANE_CR_DONE) == 0)
369 return -EINVAL;
370 }
371 return 0;
372}
373
374static int exynos_dp_channel_eq_ok(u8 link_status[2], u8 link_align,
375 int lane_count)
376{
377 int lane;
378 u8 lane_status;
379
380 if ((link_align & DP_INTERLANE_ALIGN_DONE) == 0)
381 return -EINVAL;
382
383 for (lane = 0; lane < lane_count; lane++) {
384 lane_status = exynos_dp_get_lane_status(link_status, lane);
385 lane_status &= DP_CHANNEL_EQ_BITS;
386 if (lane_status != DP_CHANNEL_EQ_BITS)
387 return -EINVAL;
388 }
389
390 return 0;
391}
392
393static unsigned char exynos_dp_get_adjust_request_voltage(u8 adjust_request[2],
394 int lane)
395{
396 int shift = (lane & 1) * 4;
397 u8 link_value = adjust_request[lane>>1];
398
399 return (link_value >> shift) & 0x3;
400}
401
402static unsigned char exynos_dp_get_adjust_request_pre_emphasis(
403 u8 adjust_request[2],
404 int lane)
405{
406 int shift = (lane & 1) * 4;
407 u8 link_value = adjust_request[lane>>1];
408
409 return ((link_value >> shift) & 0xc) >> 2;
410}
411
412static void exynos_dp_set_lane_link_training(struct exynos_dp_device *dp,
413 u8 training_lane_set, int lane)
414{
415 switch (lane) {
416 case 0:
417 exynos_dp_set_lane0_link_training(dp, training_lane_set);
418 break;
419 case 1:
420 exynos_dp_set_lane1_link_training(dp, training_lane_set);
421 break;
422
423 case 2:
424 exynos_dp_set_lane2_link_training(dp, training_lane_set);
425 break;
426
427 case 3:
428 exynos_dp_set_lane3_link_training(dp, training_lane_set);
429 break;
430 }
431}
432
433static unsigned int exynos_dp_get_lane_link_training(
434 struct exynos_dp_device *dp,
435 int lane)
436{
437 u32 reg;
438
439 switch (lane) {
440 case 0:
441 reg = exynos_dp_get_lane0_link_training(dp);
442 break;
443 case 1:
444 reg = exynos_dp_get_lane1_link_training(dp);
445 break;
446 case 2:
447 reg = exynos_dp_get_lane2_link_training(dp);
448 break;
449 case 3:
450 reg = exynos_dp_get_lane3_link_training(dp);
451 break;
452 default:
453 WARN_ON(1);
454 return 0;
455 }
456
457 return reg;
458}
459
460static void exynos_dp_reduce_link_rate(struct exynos_dp_device *dp)
461{
462 exynos_dp_training_pattern_dis(dp);
463 exynos_dp_set_enhanced_mode(dp);
464
465 dp->link_train.lt_state = FAILED;
466}
467
468static void exynos_dp_get_adjust_training_lane(struct exynos_dp_device *dp,
469 u8 adjust_request[2])
470{
471 int lane, lane_count;
472 u8 voltage_swing, pre_emphasis, training_lane;
473
474 lane_count = dp->link_train.lane_count;
475 for (lane = 0; lane < lane_count; lane++) {
476 voltage_swing = exynos_dp_get_adjust_request_voltage(
477 adjust_request, lane);
478 pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
479 adjust_request, lane);
480 training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
481 DPCD_PRE_EMPHASIS_SET(pre_emphasis);
482
483 if (voltage_swing == VOLTAGE_LEVEL_3)
484 training_lane |= DP_TRAIN_MAX_SWING_REACHED;
485 if (pre_emphasis == PRE_EMPHASIS_LEVEL_3)
486 training_lane |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
487
488 dp->link_train.training_lane[lane] = training_lane;
489 }
490}
491
492static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
493{
494 int lane, lane_count, retval;
495 u8 voltage_swing, pre_emphasis, training_lane;
496 u8 link_status[2], adjust_request[2];
497
498 usleep_range(100, 101);
499
500 lane_count = dp->link_train.lane_count;
501
502 retval = exynos_dp_read_bytes_from_dpcd(dp,
503 DP_LANE0_1_STATUS, 2, link_status);
504 if (retval)
505 return retval;
506
507 retval = exynos_dp_read_bytes_from_dpcd(dp,
508 DP_ADJUST_REQUEST_LANE0_1, 2, adjust_request);
509 if (retval)
510 return retval;
511
512 if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) {
513 /* set training pattern 2 for EQ */
514 exynos_dp_set_training_pattern(dp, TRAINING_PTN2);
515
516 retval = exynos_dp_write_byte_to_dpcd(dp,
517 DP_TRAINING_PATTERN_SET,
518 DP_LINK_SCRAMBLING_DISABLE |
519 DP_TRAINING_PATTERN_2);
520 if (retval)
521 return retval;
522
523 dev_info(dp->dev, "Link Training Clock Recovery success\n");
524 dp->link_train.lt_state = EQUALIZER_TRAINING;
525 } else {
526 for (lane = 0; lane < lane_count; lane++) {
527 training_lane = exynos_dp_get_lane_link_training(
528 dp, lane);
529 voltage_swing = exynos_dp_get_adjust_request_voltage(
530 adjust_request, lane);
531 pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
532 adjust_request, lane);
533
534 if (DPCD_VOLTAGE_SWING_GET(training_lane) ==
535 voltage_swing &&
536 DPCD_PRE_EMPHASIS_GET(training_lane) ==
537 pre_emphasis)
538 dp->link_train.cr_loop[lane]++;
539
540 if (dp->link_train.cr_loop[lane] == MAX_CR_LOOP ||
541 voltage_swing == VOLTAGE_LEVEL_3 ||
542 pre_emphasis == PRE_EMPHASIS_LEVEL_3) {
543 dev_err(dp->dev, "CR Max reached (%d,%d,%d)\n",
544 dp->link_train.cr_loop[lane],
545 voltage_swing, pre_emphasis);
546 exynos_dp_reduce_link_rate(dp);
547 return -EIO;
548 }
549 }
550 }
551
552 exynos_dp_get_adjust_training_lane(dp, adjust_request);
553
554 for (lane = 0; lane < lane_count; lane++)
555 exynos_dp_set_lane_link_training(dp,
556 dp->link_train.training_lane[lane], lane);
557
558 retval = exynos_dp_write_bytes_to_dpcd(dp,
559 DP_TRAINING_LANE0_SET, lane_count,
560 dp->link_train.training_lane);
561 if (retval)
562 return retval;
563
564 return retval;
565}
566
567static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
568{
569 int lane, lane_count, retval;
570 u32 reg;
571 u8 link_align, link_status[2], adjust_request[2];
572
573 usleep_range(400, 401);
574
575 lane_count = dp->link_train.lane_count;
576
577 retval = exynos_dp_read_bytes_from_dpcd(dp,
578 DP_LANE0_1_STATUS, 2, link_status);
579 if (retval)
580 return retval;
581
582 if (exynos_dp_clock_recovery_ok(link_status, lane_count)) {
583 exynos_dp_reduce_link_rate(dp);
584 return -EIO;
585 }
586
587 retval = exynos_dp_read_bytes_from_dpcd(dp,
588 DP_ADJUST_REQUEST_LANE0_1, 2, adjust_request);
589 if (retval)
590 return retval;
591
592 retval = exynos_dp_read_byte_from_dpcd(dp,
593 DP_LANE_ALIGN_STATUS_UPDATED, &link_align);
594 if (retval)
595 return retval;
596
597 exynos_dp_get_adjust_training_lane(dp, adjust_request);
598
599 if (!exynos_dp_channel_eq_ok(link_status, link_align, lane_count)) {
600 /* traing pattern Set to Normal */
601 exynos_dp_training_pattern_dis(dp);
602
603 dev_info(dp->dev, "Link Training success!\n");
604
605 exynos_dp_get_link_bandwidth(dp, &reg);
606 dp->link_train.link_rate = reg;
607 dev_dbg(dp->dev, "final bandwidth = %.2x\n",
608 dp->link_train.link_rate);
609
610 exynos_dp_get_lane_count(dp, &reg);
611 dp->link_train.lane_count = reg;
612 dev_dbg(dp->dev, "final lane count = %.2x\n",
613 dp->link_train.lane_count);
614
615 /* set enhanced mode if available */
616 exynos_dp_set_enhanced_mode(dp);
617 dp->link_train.lt_state = FINISHED;
618
619 return 0;
620 }
621
622 /* not all locked */
623 dp->link_train.eq_loop++;
624
625 if (dp->link_train.eq_loop > MAX_EQ_LOOP) {
626 dev_err(dp->dev, "EQ Max loop\n");
627 exynos_dp_reduce_link_rate(dp);
628 return -EIO;
629 }
630
631 for (lane = 0; lane < lane_count; lane++)
632 exynos_dp_set_lane_link_training(dp,
633 dp->link_train.training_lane[lane], lane);
634
635 retval = exynos_dp_write_bytes_to_dpcd(dp, DP_TRAINING_LANE0_SET,
636 lane_count, dp->link_train.training_lane);
637
638 return retval;
639}
640
641static void exynos_dp_get_max_rx_bandwidth(struct exynos_dp_device *dp,
642 u8 *bandwidth)
643{
644 u8 data;
645
646 /*
647 * For DP rev.1.1, Maximum link rate of Main Link lanes
648 * 0x06 = 1.62 Gbps, 0x0a = 2.7 Gbps
649 */
650 exynos_dp_read_byte_from_dpcd(dp, DP_MAX_LINK_RATE, &data);
651 *bandwidth = data;
652}
653
654static void exynos_dp_get_max_rx_lane_count(struct exynos_dp_device *dp,
655 u8 *lane_count)
656{
657 u8 data;
658
659 /*
660 * For DP rev.1.1, Maximum number of Main Link lanes
661 * 0x01 = 1 lane, 0x02 = 2 lanes, 0x04 = 4 lanes
662 */
663 exynos_dp_read_byte_from_dpcd(dp, DP_MAX_LANE_COUNT, &data);
664 *lane_count = DPCD_MAX_LANE_COUNT(data);
665}
666
667static void exynos_dp_init_training(struct exynos_dp_device *dp,
668 enum link_lane_count_type max_lane,
669 enum link_rate_type max_rate)
670{
671 /*
672 * MACRO_RST must be applied after the PLL_LOCK to avoid
673 * the DP inter pair skew issue for at least 10 us
674 */
675 exynos_dp_reset_macro(dp);
676
677 /* Initialize by reading RX's DPCD */
678 exynos_dp_get_max_rx_bandwidth(dp, &dp->link_train.link_rate);
679 exynos_dp_get_max_rx_lane_count(dp, &dp->link_train.lane_count);
680
681 if ((dp->link_train.link_rate != LINK_RATE_1_62GBPS) &&
682 (dp->link_train.link_rate != LINK_RATE_2_70GBPS)) {
683 dev_err(dp->dev, "Rx Max Link Rate is abnormal :%x !\n",
684 dp->link_train.link_rate);
685 dp->link_train.link_rate = LINK_RATE_1_62GBPS;
686 }
687
688 if (dp->link_train.lane_count == 0) {
689 dev_err(dp->dev, "Rx Max Lane count is abnormal :%x !\n",
690 dp->link_train.lane_count);
691 dp->link_train.lane_count = (u8)LANE_COUNT1;
692 }
693
694 /* Setup TX lane count & rate */
695 if (dp->link_train.lane_count > max_lane)
696 dp->link_train.lane_count = max_lane;
697 if (dp->link_train.link_rate > max_rate)
698 dp->link_train.link_rate = max_rate;
699
700 /* All DP analog module power up */
701 exynos_dp_set_analog_power_down(dp, POWER_ALL, 0);
702}
703
704static int exynos_dp_sw_link_training(struct exynos_dp_device *dp)
705{
706 int retval = 0, training_finished = 0;
707
708 dp->link_train.lt_state = START;
709
710 /* Process here */
711 while (!retval && !training_finished) {
712 switch (dp->link_train.lt_state) {
713 case START:
714 retval = exynos_dp_link_start(dp);
715 if (retval)
716 dev_err(dp->dev, "LT link start failed!\n");
717 break;
718 case CLOCK_RECOVERY:
719 retval = exynos_dp_process_clock_recovery(dp);
720 if (retval)
721 dev_err(dp->dev, "LT CR failed!\n");
722 break;
723 case EQUALIZER_TRAINING:
724 retval = exynos_dp_process_equalizer_training(dp);
725 if (retval)
726 dev_err(dp->dev, "LT EQ failed!\n");
727 break;
728 case FINISHED:
729 training_finished = 1;
730 break;
731 case FAILED:
732 return -EREMOTEIO;
733 }
734 }
735 if (retval)
736 dev_err(dp->dev, "eDP link training failed (%d)\n", retval);
737
738 return retval;
739}
740
741static int exynos_dp_set_link_train(struct exynos_dp_device *dp,
742 u32 count,
743 u32 bwtype)
744{
745 int i;
746 int retval;
747
748 for (i = 0; i < DP_TIMEOUT_LOOP_COUNT; i++) {
749 exynos_dp_init_training(dp, count, bwtype);
750 retval = exynos_dp_sw_link_training(dp);
751 if (retval == 0)
752 break;
753
754 usleep_range(100, 110);
755 }
756
757 return retval;
758}
759
760static int exynos_dp_config_video(struct exynos_dp_device *dp)
761{
762 int retval = 0;
763 int timeout_loop = 0;
764 int done_count = 0;
765
766 exynos_dp_config_video_slave_mode(dp);
767
768 exynos_dp_set_video_color_format(dp);
769
770 if (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
771 dev_err(dp->dev, "PLL is not locked yet.\n");
772 return -EINVAL;
773 }
774
775 for (;;) {
776 timeout_loop++;
777 if (exynos_dp_is_slave_video_stream_clock_on(dp) == 0)
778 break;
779 if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
780 dev_err(dp->dev, "Timeout of video streamclk ok\n");
781 return -ETIMEDOUT;
782 }
783
784 usleep_range(1, 2);
785 }
786
787 /* Set to use the register calculated M/N video */
788 exynos_dp_set_video_cr_mn(dp, CALCULATED_M, 0, 0);
789
790 /* For video bist, Video timing must be generated by register */
791 exynos_dp_set_video_timing_mode(dp, VIDEO_TIMING_FROM_CAPTURE);
792
793 /* Disable video mute */
794 exynos_dp_enable_video_mute(dp, 0);
795
796 /* Configure video slave mode */
797 exynos_dp_enable_video_master(dp, 0);
798
799 timeout_loop = 0;
800
801 for (;;) {
802 timeout_loop++;
803 if (exynos_dp_is_video_stream_on(dp) == 0) {
804 done_count++;
805 if (done_count > 10)
806 break;
807 } else if (done_count) {
808 done_count = 0;
809 }
810 if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
811 dev_err(dp->dev, "Timeout of video streamclk ok\n");
812 return -ETIMEDOUT;
813 }
814
815 usleep_range(1000, 1001);
816 }
817
818 if (retval != 0)
819 dev_err(dp->dev, "Video stream is not detected!\n");
820
821 return retval;
822}
823
824static void exynos_dp_enable_scramble(struct exynos_dp_device *dp, bool enable)
825{
826 u8 data;
827
828 if (enable) {
829 exynos_dp_enable_scrambling(dp);
830
831 exynos_dp_read_byte_from_dpcd(dp,
832 DP_TRAINING_PATTERN_SET,
833 &data);
834 exynos_dp_write_byte_to_dpcd(dp,
835 DP_TRAINING_PATTERN_SET,
836 (u8)(data & ~DP_LINK_SCRAMBLING_DISABLE));
837 } else {
838 exynos_dp_disable_scrambling(dp);
839
840 exynos_dp_read_byte_from_dpcd(dp,
841 DP_TRAINING_PATTERN_SET,
842 &data);
843 exynos_dp_write_byte_to_dpcd(dp,
844 DP_TRAINING_PATTERN_SET,
845 (u8)(data | DP_LINK_SCRAMBLING_DISABLE));
846 }
847}
848
849static irqreturn_t exynos_dp_irq_handler(int irq, void *arg)
850{
851 struct exynos_dp_device *dp = arg;
852
853 enum dp_irq_type irq_type;
854
855 irq_type = exynos_dp_get_irq_type(dp);
856 switch (irq_type) {
857 case DP_IRQ_TYPE_HP_CABLE_IN:
858 dev_dbg(dp->dev, "Received irq - cable in\n");
859 schedule_work(&dp->hotplug_work);
860 exynos_dp_clear_hotplug_interrupts(dp);
861 break;
862 case DP_IRQ_TYPE_HP_CABLE_OUT:
863 dev_dbg(dp->dev, "Received irq - cable out\n");
864 exynos_dp_clear_hotplug_interrupts(dp);
865 break;
866 case DP_IRQ_TYPE_HP_CHANGE:
867 /*
868 * We get these change notifications once in a while, but there
869 * is nothing we can do with them. Just ignore it for now and
870 * only handle cable changes.
871 */
872 dev_dbg(dp->dev, "Received irq - hotplug change; ignoring.\n");
873 exynos_dp_clear_hotplug_interrupts(dp);
874 break;
875 default:
876 dev_err(dp->dev, "Received irq - unknown type!\n");
877 break;
878 }
879 return IRQ_HANDLED;
880}
881
882static void exynos_dp_hotplug(struct work_struct *work)
883{
884 struct exynos_dp_device *dp;
885
886 dp = container_of(work, struct exynos_dp_device, hotplug_work);
887
888 if (dp->drm_dev)
889 drm_helper_hpd_irq_event(dp->drm_dev);
890}
891
892static void exynos_dp_commit(struct drm_encoder *encoder)
893{
894 struct exynos_dp_device *dp = encoder_to_dp(encoder);
895 int ret;
896
897 /* Keep the panel disabled while we configure video */
898 if (dp->panel) {
899 if (drm_panel_disable(dp->panel))
900 DRM_ERROR("failed to disable the panel\n");
901 }
902
903 ret = exynos_dp_detect_hpd(dp);
904 if (ret) {
905 /* Cable has been disconnected, we're done */
906 return;
907 }
908
909 ret = exynos_dp_handle_edid(dp);
910 if (ret) {
911 dev_err(dp->dev, "unable to handle edid\n");
912 return;
913 }
914
915 ret = exynos_dp_set_link_train(dp, dp->video_info->lane_count,
916 dp->video_info->link_rate);
917 if (ret) {
918 dev_err(dp->dev, "unable to do link train\n");
919 return;
920 }
921
922 exynos_dp_enable_scramble(dp, 1);
923 exynos_dp_enable_rx_to_enhanced_mode(dp, 1);
924 exynos_dp_enable_enhanced_mode(dp, 1);
925
926 exynos_dp_set_lane_count(dp, dp->video_info->lane_count);
927 exynos_dp_set_link_bandwidth(dp, dp->video_info->link_rate);
928
929 exynos_dp_init_video(dp);
930 ret = exynos_dp_config_video(dp);
931 if (ret)
932 dev_err(dp->dev, "unable to config video\n");
933
934 /* Safe to enable the panel now */
935 if (dp->panel) {
936 if (drm_panel_enable(dp->panel))
937 DRM_ERROR("failed to enable the panel\n");
938 }
939
940 /* Enable video */
941 exynos_dp_start_video(dp);
942}
943
944static enum drm_connector_status exynos_dp_detect(
945 struct drm_connector *connector, bool force)
946{
947 return connector_status_connected;
948}
949
950static void exynos_dp_connector_destroy(struct drm_connector *connector)
951{
952 drm_connector_unregister(connector);
953 drm_connector_cleanup(connector);
954}
955
956static const struct drm_connector_funcs exynos_dp_connector_funcs = {
957 .dpms = drm_atomic_helper_connector_dpms,
958 .fill_modes = drm_helper_probe_single_connector_modes,
959 .detect = exynos_dp_detect,
960 .destroy = exynos_dp_connector_destroy,
961 .reset = drm_atomic_helper_connector_reset,
962 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
963 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
964};
965
966static int exynos_dp_get_modes(struct drm_connector *connector)
967{
968 struct exynos_dp_device *dp = ctx_from_connector(connector);
969 struct drm_display_mode *mode;
970
971 if (dp->panel)
972 return drm_panel_get_modes(dp->panel);
973
974 mode = drm_mode_create(connector->dev);
975 if (!mode) {
976 DRM_ERROR("failed to create a new display mode.\n");
977 return 0;
978 }
979
980 drm_display_mode_from_videomode(&dp->vm, mode);
981 connector->display_info.width_mm = mode->width_mm;
982 connector->display_info.height_mm = mode->height_mm;
983
984 mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
985 drm_mode_set_name(mode);
986 drm_mode_probed_add(connector, mode);
987
988 return 1;
989}
990
991static struct drm_encoder *exynos_dp_best_encoder(
992 struct drm_connector *connector)
993{
994 struct exynos_dp_device *dp = ctx_from_connector(connector);
995
996 return &dp->encoder;
997}
998
999static const struct drm_connector_helper_funcs exynos_dp_connector_helper_funcs = {
1000 .get_modes = exynos_dp_get_modes,
1001 .best_encoder = exynos_dp_best_encoder,
1002};
1003
1004/* returns the number of bridges attached */
1005static int exynos_drm_attach_lcd_bridge(struct exynos_dp_device *dp,
1006 struct drm_encoder *encoder)
1007{
1008 int ret;
1009
1010 encoder->bridge->next = dp->ptn_bridge;
1011 dp->ptn_bridge->encoder = encoder;
1012 ret = drm_bridge_attach(encoder->dev, dp->ptn_bridge);
1013 if (ret) {
1014 DRM_ERROR("Failed to attach bridge to drm\n");
1015 return ret;
1016 }
1017
1018 return 0;
1019}
1020
1021static int exynos_dp_bridge_attach(struct drm_bridge *bridge)
1022{
1023 struct exynos_dp_device *dp = bridge->driver_private;
1024 struct drm_encoder *encoder = &dp->encoder;
1025 struct drm_connector *connector = &dp->connector;
1026 int ret;
1027
1028 /* Pre-empt DP connector creation if there's a bridge */
1029 if (dp->ptn_bridge) {
1030 ret = exynos_drm_attach_lcd_bridge(dp, encoder);
1031 if (!ret)
1032 return 0;
1033 }
1034
1035 connector->polled = DRM_CONNECTOR_POLL_HPD;
1036
1037 ret = drm_connector_init(dp->drm_dev, connector,
1038 &exynos_dp_connector_funcs, DRM_MODE_CONNECTOR_eDP);
1039 if (ret) {
1040 DRM_ERROR("Failed to initialize connector with drm\n");
1041 return ret;
1042 }
1043
1044 drm_connector_helper_add(connector, &exynos_dp_connector_helper_funcs);
1045 drm_connector_register(connector);
1046 drm_mode_connector_attach_encoder(connector, encoder);
1047
1048 if (dp->panel)
1049 ret = drm_panel_attach(dp->panel, &dp->connector);
1050
1051 return ret;
1052}
1053
1054static void exynos_dp_bridge_enable(struct drm_bridge *bridge)
1055{
1056 struct exynos_dp_device *dp = bridge->driver_private;
1057 struct exynos_drm_crtc *crtc = dp_to_crtc(dp);
1058
1059 if (dp->dpms_mode == DRM_MODE_DPMS_ON)
1060 return;
1061
1062 pm_runtime_get_sync(dp->dev);
1063
1064 if (dp->panel) {
1065 if (drm_panel_prepare(dp->panel)) {
1066 DRM_ERROR("failed to setup the panel\n");
1067 return;
1068 }
1069 }
1070
1071 if (crtc->ops->clock_enable)
1072 crtc->ops->clock_enable(dp_to_crtc(dp), true);
1073
1074 phy_power_on(dp->phy);
1075 exynos_dp_init_dp(dp);
1076 enable_irq(dp->irq);
1077 exynos_dp_commit(&dp->encoder);
1078
1079 dp->dpms_mode = DRM_MODE_DPMS_ON;
1080}
1081
1082static void exynos_dp_bridge_disable(struct drm_bridge *bridge)
1083{
1084 struct exynos_dp_device *dp = bridge->driver_private;
1085 struct exynos_drm_crtc *crtc = dp_to_crtc(dp);
1086
1087 if (dp->dpms_mode != DRM_MODE_DPMS_ON)
1088 return;
1089
1090 if (dp->panel) {
1091 if (drm_panel_disable(dp->panel)) {
1092 DRM_ERROR("failed to disable the panel\n");
1093 return;
1094 }
1095 }
1096
1097 disable_irq(dp->irq);
1098 flush_work(&dp->hotplug_work);
1099 phy_power_off(dp->phy);
1100
1101 if (crtc->ops->clock_enable)
1102 crtc->ops->clock_enable(dp_to_crtc(dp), false);
1103
1104 if (dp->panel) {
1105 if (drm_panel_unprepare(dp->panel))
1106 DRM_ERROR("failed to turnoff the panel\n");
1107 }
1108
1109 pm_runtime_put_sync(dp->dev);
1110
1111 dp->dpms_mode = DRM_MODE_DPMS_OFF;
1112}
1113
1114static void exynos_dp_bridge_nop(struct drm_bridge *bridge)
1115{
1116 /* do nothing */
1117}
1118
1119static const struct drm_bridge_funcs exynos_dp_bridge_funcs = {
1120 .enable = exynos_dp_bridge_enable,
1121 .disable = exynos_dp_bridge_disable,
1122 .pre_enable = exynos_dp_bridge_nop,
1123 .post_disable = exynos_dp_bridge_nop,
1124 .attach = exynos_dp_bridge_attach,
1125};
1126
1127static int exynos_dp_create_connector(struct drm_encoder *encoder)
1128{
1129 struct exynos_dp_device *dp = encoder_to_dp(encoder);
1130 struct drm_device *drm_dev = dp->drm_dev;
1131 struct drm_bridge *bridge;
1132 int ret;
1133
1134 bridge = devm_kzalloc(drm_dev->dev, sizeof(*bridge), GFP_KERNEL);
1135 if (!bridge) {
1136 DRM_ERROR("failed to allocate for drm bridge\n");
1137 return -ENOMEM;
1138 }
1139
1140 dp->bridge = bridge;
1141
1142 encoder->bridge = bridge;
1143 bridge->driver_private = dp;
1144 bridge->encoder = encoder;
1145 bridge->funcs = &exynos_dp_bridge_funcs;
1146
1147 ret = drm_bridge_attach(drm_dev, bridge);
1148 if (ret) {
1149 DRM_ERROR("failed to attach drm bridge\n");
1150 return -EINVAL;
1151 }
1152
1153 return 0;
1154}
1155
1156static void exynos_dp_mode_set(struct drm_encoder *encoder,
1157 struct drm_display_mode *mode,
1158 struct drm_display_mode *adjusted_mode)
1159{
1160}
1161
1162static void exynos_dp_enable(struct drm_encoder *encoder)
1163{
1164}
1165
1166static void exynos_dp_disable(struct drm_encoder *encoder)
1167{
1168}
1169
1170static const struct drm_encoder_helper_funcs exynos_dp_encoder_helper_funcs = {
1171 .mode_set = exynos_dp_mode_set,
1172 .enable = exynos_dp_enable,
1173 .disable = exynos_dp_disable,
1174};
1175
1176static const struct drm_encoder_funcs exynos_dp_encoder_funcs = {
1177 .destroy = drm_encoder_cleanup,
1178};
1179
1180static struct video_info *exynos_dp_dt_parse_pdata(struct device *dev)
1181{
1182 struct device_node *dp_node = dev->of_node;
1183 struct video_info *dp_video_config;
1184
1185 dp_video_config = devm_kzalloc(dev,
1186 sizeof(*dp_video_config), GFP_KERNEL);
1187 if (!dp_video_config)
1188 return ERR_PTR(-ENOMEM);
1189
1190 dp_video_config->h_sync_polarity =
1191 of_property_read_bool(dp_node, "hsync-active-high");
1192
1193 dp_video_config->v_sync_polarity =
1194 of_property_read_bool(dp_node, "vsync-active-high");
1195
1196 dp_video_config->interlaced =
1197 of_property_read_bool(dp_node, "interlaced");
1198
1199 if (of_property_read_u32(dp_node, "samsung,color-space",
1200 &dp_video_config->color_space)) {
1201 dev_err(dev, "failed to get color-space\n");
1202 return ERR_PTR(-EINVAL);
1203 }
1204
1205 if (of_property_read_u32(dp_node, "samsung,dynamic-range",
1206 &dp_video_config->dynamic_range)) {
1207 dev_err(dev, "failed to get dynamic-range\n");
1208 return ERR_PTR(-EINVAL);
1209 }
1210
1211 if (of_property_read_u32(dp_node, "samsung,ycbcr-coeff",
1212 &dp_video_config->ycbcr_coeff)) {
1213 dev_err(dev, "failed to get ycbcr-coeff\n");
1214 return ERR_PTR(-EINVAL);
1215 }
1216
1217 if (of_property_read_u32(dp_node, "samsung,color-depth",
1218 &dp_video_config->color_depth)) {
1219 dev_err(dev, "failed to get color-depth\n");
1220 return ERR_PTR(-EINVAL);
1221 }
1222
1223 if (of_property_read_u32(dp_node, "samsung,link-rate",
1224 &dp_video_config->link_rate)) {
1225 dev_err(dev, "failed to get link-rate\n");
1226 return ERR_PTR(-EINVAL);
1227 }
1228
1229 if (of_property_read_u32(dp_node, "samsung,lane-count",
1230 &dp_video_config->lane_count)) {
1231 dev_err(dev, "failed to get lane-count\n");
1232 return ERR_PTR(-EINVAL);
1233 }
1234
1235 return dp_video_config;
1236}
1237
1238static int exynos_dp_dt_parse_panel(struct exynos_dp_device *dp)
1239{
1240 int ret;
1241
1242 ret = of_get_videomode(dp->dev->of_node, &dp->vm, OF_USE_NATIVE_MODE);
1243 if (ret) {
1244 DRM_ERROR("failed: of_get_videomode() : %d\n", ret);
1245 return ret;
1246 }
1247 return 0;
1248}
1249
1250static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
1251{
1252 struct exynos_dp_device *dp = dev_get_drvdata(dev);
1253 struct platform_device *pdev = to_platform_device(dev);
1254 struct drm_device *drm_dev = data;
1255 struct drm_encoder *encoder = &dp->encoder;
1256 struct resource *res;
1257 unsigned int irq_flags;
1258 int pipe, ret = 0;
1259
1260 dp->dev = &pdev->dev;
1261 dp->dpms_mode = DRM_MODE_DPMS_OFF;
1262
1263 dp->video_info = exynos_dp_dt_parse_pdata(&pdev->dev);
1264 if (IS_ERR(dp->video_info))
1265 return PTR_ERR(dp->video_info);
1266
1267 dp->phy = devm_phy_get(dp->dev, "dp");
1268 if (IS_ERR(dp->phy)) {
1269 dev_err(dp->dev, "no DP phy configured\n");
1270 ret = PTR_ERR(dp->phy);
1271 if (ret) {
1272 /*
1273 * phy itself is not enabled, so we can move forward
1274 * assigning NULL to phy pointer.
1275 */
1276 if (ret == -ENOSYS || ret == -ENODEV)
1277 dp->phy = NULL;
1278 else
1279 return ret;
1280 }
1281 }
1282
1283 if (!dp->panel && !dp->ptn_bridge) {
1284 ret = exynos_dp_dt_parse_panel(dp);
1285 if (ret)
1286 return ret;
1287 }
1288
1289 dp->clock = devm_clk_get(&pdev->dev, "dp");
1290 if (IS_ERR(dp->clock)) {
1291 dev_err(&pdev->dev, "failed to get clock\n");
1292 return PTR_ERR(dp->clock);
1293 }
1294
1295 clk_prepare_enable(dp->clock);
1296
1297 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1298
1299 dp->reg_base = devm_ioremap_resource(&pdev->dev, res);
1300 if (IS_ERR(dp->reg_base))
1301 return PTR_ERR(dp->reg_base);
1302
1303 dp->hpd_gpio = of_get_named_gpio(dev->of_node, "samsung,hpd-gpio", 0);
1304
1305 if (gpio_is_valid(dp->hpd_gpio)) {
1306 /*
1307 * Set up the hotplug GPIO from the device tree as an interrupt.
1308 * Simply specifying a different interrupt in the device tree
1309 * doesn't work since we handle hotplug rather differently when
1310 * using a GPIO. We also need the actual GPIO specifier so
1311 * that we can get the current state of the GPIO.
1312 */
1313 ret = devm_gpio_request_one(&pdev->dev, dp->hpd_gpio, GPIOF_IN,
1314 "hpd_gpio");
1315 if (ret) {
1316 dev_err(&pdev->dev, "failed to get hpd gpio\n");
1317 return ret;
1318 }
1319 dp->irq = gpio_to_irq(dp->hpd_gpio);
1320 irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
1321 } else {
1322 dp->hpd_gpio = -ENODEV;
1323 dp->irq = platform_get_irq(pdev, 0);
1324 irq_flags = 0;
1325 }
1326
1327 if (dp->irq == -ENXIO) {
1328 dev_err(&pdev->dev, "failed to get irq\n");
1329 return -ENODEV;
1330 }
1331
1332 INIT_WORK(&dp->hotplug_work, exynos_dp_hotplug);
1333
1334 ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler,
1335 irq_flags, "exynos-dp", dp);
1336 if (ret) {
1337 dev_err(&pdev->dev, "failed to request irq\n");
1338 return ret;
1339 }
1340 disable_irq(dp->irq);
1341
1342 dp->drm_dev = drm_dev;
1343
1344 pipe = exynos_drm_crtc_get_pipe_from_type(drm_dev,
1345 EXYNOS_DISPLAY_TYPE_LCD);
1346 if (pipe < 0)
1347 return pipe;
1348
1349 encoder->possible_crtcs = 1 << pipe;
1350
1351 DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
1352
1353 drm_encoder_init(drm_dev, encoder, &exynos_dp_encoder_funcs,
1354 DRM_MODE_ENCODER_TMDS, NULL);
1355
1356 drm_encoder_helper_add(encoder, &exynos_dp_encoder_helper_funcs);
1357
1358 ret = exynos_dp_create_connector(encoder);
1359 if (ret) {
1360 DRM_ERROR("failed to create connector ret = %d\n", ret);
1361 drm_encoder_cleanup(encoder);
1362 return ret;
1363 }
1364
1365 return 0;
1366}
1367
1368static void exynos_dp_unbind(struct device *dev, struct device *master,
1369 void *data)
1370{
1371 struct exynos_dp_device *dp = dev_get_drvdata(dev);
1372
1373 exynos_dp_disable(&dp->encoder);
1374}
1375
1376static const struct component_ops exynos_dp_ops = {
1377 .bind = exynos_dp_bind,
1378 .unbind = exynos_dp_unbind,
1379};
1380
1381static int exynos_dp_probe(struct platform_device *pdev)
1382{
1383 struct device *dev = &pdev->dev;
1384 struct device_node *np = NULL, *endpoint = NULL;
1385 struct exynos_dp_device *dp;
1386 int ret;
1387
1388 dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),
1389 GFP_KERNEL);
1390 if (!dp)
1391 return -ENOMEM;
1392
1393 platform_set_drvdata(pdev, dp);
1394
1395 /* This is for the backward compatibility. */
1396 np = of_parse_phandle(dev->of_node, "panel", 0);
1397 if (np) {
1398 dp->panel = of_drm_find_panel(np);
1399 of_node_put(np);
1400 if (!dp->panel)
1401 return -EPROBE_DEFER;
1402 goto out;
1403 }
1404
1405 endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
1406 if (endpoint) {
1407 np = of_graph_get_remote_port_parent(endpoint);
1408 if (np) {
1409 /* The remote port can be either a panel or a bridge */
1410 dp->panel = of_drm_find_panel(np);
1411 if (!dp->panel) {
1412 dp->ptn_bridge = of_drm_find_bridge(np);
1413 if (!dp->ptn_bridge) {
1414 of_node_put(np);
1415 return -EPROBE_DEFER;
1416 }
1417 }
1418 of_node_put(np);
1419 } else {
1420 DRM_ERROR("no remote endpoint device node found.\n");
1421 return -EINVAL;
1422 }
1423 } else {
1424 DRM_ERROR("no port endpoint subnode found.\n");
1425 return -EINVAL;
1426 }
1427
1428out:
1429 pm_runtime_enable(dev);
1430
1431 ret = component_add(&pdev->dev, &exynos_dp_ops);
1432 if (ret)
1433 goto err_disable_pm_runtime;
1434
1435 return ret;
1436
1437err_disable_pm_runtime:
1438 pm_runtime_disable(dev);
1439
1440 return ret;
1441}
1442
1443static int exynos_dp_remove(struct platform_device *pdev)
1444{
1445 pm_runtime_disable(&pdev->dev);
1446 component_del(&pdev->dev, &exynos_dp_ops);
1447
1448 return 0;
1449}
1450
1451#ifdef CONFIG_PM
1452static int exynos_dp_suspend(struct device *dev)
1453{
1454 struct exynos_dp_device *dp = dev_get_drvdata(dev);
1455
1456 clk_disable_unprepare(dp->clock);
1457
1458 return 0;
1459}
1460
1461static int exynos_dp_resume(struct device *dev)
1462{
1463 struct exynos_dp_device *dp = dev_get_drvdata(dev);
1464 int ret;
1465
1466 ret = clk_prepare_enable(dp->clock);
1467 if (ret < 0) {
1468 DRM_ERROR("Failed to prepare_enable the clock clk [%d]\n", ret);
1469 return ret;
1470 }
1471
1472 return 0;
1473}
1474#endif
1475
1476static const struct dev_pm_ops exynos_dp_pm_ops = {
1477 SET_RUNTIME_PM_OPS(exynos_dp_suspend, exynos_dp_resume, NULL)
1478};
1479
1480static const struct of_device_id exynos_dp_match[] = {
1481 { .compatible = "samsung,exynos5-dp" },
1482 {},
1483};
1484MODULE_DEVICE_TABLE(of, exynos_dp_match);
1485
1486struct platform_driver dp_driver = {
1487 .probe = exynos_dp_probe,
1488 .remove = exynos_dp_remove,
1489 .driver = {
1490 .name = "exynos-dp",
1491 .owner = THIS_MODULE,
1492 .pm = &exynos_dp_pm_ops,
1493 .of_match_table = exynos_dp_match,
1494 },
1495};
1496
1497MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>");
1498MODULE_DESCRIPTION("Samsung SoC DP Driver");
1499MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.h b/drivers/gpu/drm/exynos/exynos_dp_core.h
deleted file mode 100644
index b5c2d8f47f9c..000000000000
--- a/drivers/gpu/drm/exynos/exynos_dp_core.h
+++ /dev/null
@@ -1,282 +0,0 @@
1/*
2 * Header file for Samsung DP (Display Port) interface driver.
3 *
4 * Copyright (C) 2012 Samsung Electronics Co., Ltd.
5 * Author: Jingoo Han <jg1.han@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#ifndef _EXYNOS_DP_CORE_H
14#define _EXYNOS_DP_CORE_H
15
16#include <drm/drm_crtc.h>
17#include <drm/drm_dp_helper.h>
18#include <drm/exynos_drm.h>
19#include <video/videomode.h>
20
21#include "exynos_drm_drv.h"
22
23#define DP_TIMEOUT_LOOP_COUNT 100
24#define MAX_CR_LOOP 5
25#define MAX_EQ_LOOP 5
26
27enum link_rate_type {
28 LINK_RATE_1_62GBPS = 0x06,
29 LINK_RATE_2_70GBPS = 0x0a
30};
31
32enum link_lane_count_type {
33 LANE_COUNT1 = 1,
34 LANE_COUNT2 = 2,
35 LANE_COUNT4 = 4
36};
37
38enum link_training_state {
39 START,
40 CLOCK_RECOVERY,
41 EQUALIZER_TRAINING,
42 FINISHED,
43 FAILED
44};
45
46enum voltage_swing_level {
47 VOLTAGE_LEVEL_0,
48 VOLTAGE_LEVEL_1,
49 VOLTAGE_LEVEL_2,
50 VOLTAGE_LEVEL_3,
51};
52
53enum pre_emphasis_level {
54 PRE_EMPHASIS_LEVEL_0,
55 PRE_EMPHASIS_LEVEL_1,
56 PRE_EMPHASIS_LEVEL_2,
57 PRE_EMPHASIS_LEVEL_3,
58};
59
60enum pattern_set {
61 PRBS7,
62 D10_2,
63 TRAINING_PTN1,
64 TRAINING_PTN2,
65 DP_NONE
66};
67
68enum color_space {
69 COLOR_RGB,
70 COLOR_YCBCR422,
71 COLOR_YCBCR444
72};
73
74enum color_depth {
75 COLOR_6,
76 COLOR_8,
77 COLOR_10,
78 COLOR_12
79};
80
81enum color_coefficient {
82 COLOR_YCBCR601,
83 COLOR_YCBCR709
84};
85
86enum dynamic_range {
87 VESA,
88 CEA
89};
90
91enum pll_status {
92 PLL_UNLOCKED,
93 PLL_LOCKED
94};
95
96enum clock_recovery_m_value_type {
97 CALCULATED_M,
98 REGISTER_M
99};
100
101enum video_timing_recognition_type {
102 VIDEO_TIMING_FROM_CAPTURE,
103 VIDEO_TIMING_FROM_REGISTER
104};
105
106enum analog_power_block {
107 AUX_BLOCK,
108 CH0_BLOCK,
109 CH1_BLOCK,
110 CH2_BLOCK,
111 CH3_BLOCK,
112 ANALOG_TOTAL,
113 POWER_ALL
114};
115
116enum dp_irq_type {
117 DP_IRQ_TYPE_HP_CABLE_IN,
118 DP_IRQ_TYPE_HP_CABLE_OUT,
119 DP_IRQ_TYPE_HP_CHANGE,
120 DP_IRQ_TYPE_UNKNOWN,
121};
122
123struct video_info {
124 char *name;
125
126 bool h_sync_polarity;
127 bool v_sync_polarity;
128 bool interlaced;
129
130 enum color_space color_space;
131 enum dynamic_range dynamic_range;
132 enum color_coefficient ycbcr_coeff;
133 enum color_depth color_depth;
134
135 enum link_rate_type link_rate;
136 enum link_lane_count_type lane_count;
137};
138
139struct link_train {
140 int eq_loop;
141 int cr_loop[4];
142
143 u8 link_rate;
144 u8 lane_count;
145 u8 training_lane[4];
146
147 enum link_training_state lt_state;
148};
149
150struct exynos_dp_device {
151 struct drm_encoder encoder;
152 struct device *dev;
153 struct drm_device *drm_dev;
154 struct drm_connector connector;
155 struct drm_panel *panel;
156 struct drm_bridge *bridge;
157 struct drm_bridge *ptn_bridge;
158 struct clk *clock;
159 unsigned int irq;
160 void __iomem *reg_base;
161
162 struct video_info *video_info;
163 struct link_train link_train;
164 struct work_struct hotplug_work;
165 struct phy *phy;
166 int dpms_mode;
167 int hpd_gpio;
168 struct videomode vm;
169};
170
171/* exynos_dp_reg.c */
172void exynos_dp_enable_video_mute(struct exynos_dp_device *dp, bool enable);
173void exynos_dp_stop_video(struct exynos_dp_device *dp);
174void exynos_dp_lane_swap(struct exynos_dp_device *dp, bool enable);
175void exynos_dp_init_analog_param(struct exynos_dp_device *dp);
176void exynos_dp_init_interrupt(struct exynos_dp_device *dp);
177void exynos_dp_reset(struct exynos_dp_device *dp);
178void exynos_dp_swreset(struct exynos_dp_device *dp);
179void exynos_dp_config_interrupt(struct exynos_dp_device *dp);
180enum pll_status exynos_dp_get_pll_lock_status(struct exynos_dp_device *dp);
181void exynos_dp_set_pll_power_down(struct exynos_dp_device *dp, bool enable);
182void exynos_dp_set_analog_power_down(struct exynos_dp_device *dp,
183 enum analog_power_block block,
184 bool enable);
185void exynos_dp_init_analog_func(struct exynos_dp_device *dp);
186void exynos_dp_init_hpd(struct exynos_dp_device *dp);
187enum dp_irq_type exynos_dp_get_irq_type(struct exynos_dp_device *dp);
188void exynos_dp_clear_hotplug_interrupts(struct exynos_dp_device *dp);
189void exynos_dp_reset_aux(struct exynos_dp_device *dp);
190void exynos_dp_init_aux(struct exynos_dp_device *dp);
191int exynos_dp_get_plug_in_status(struct exynos_dp_device *dp);
192void exynos_dp_enable_sw_function(struct exynos_dp_device *dp);
193int exynos_dp_start_aux_transaction(struct exynos_dp_device *dp);
194int exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp,
195 unsigned int reg_addr,
196 unsigned char data);
197int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
198 unsigned int reg_addr,
199 unsigned char *data);
200int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
201 unsigned int reg_addr,
202 unsigned int count,
203 unsigned char data[]);
204int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp,
205 unsigned int reg_addr,
206 unsigned int count,
207 unsigned char data[]);
208int exynos_dp_select_i2c_device(struct exynos_dp_device *dp,
209 unsigned int device_addr,
210 unsigned int reg_addr);
211int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
212 unsigned int device_addr,
213 unsigned int reg_addr,
214 unsigned int *data);
215int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
216 unsigned int device_addr,
217 unsigned int reg_addr,
218 unsigned int count,
219 unsigned char edid[]);
220void exynos_dp_set_link_bandwidth(struct exynos_dp_device *dp, u32 bwtype);
221void exynos_dp_get_link_bandwidth(struct exynos_dp_device *dp, u32 *bwtype);
222void exynos_dp_set_lane_count(struct exynos_dp_device *dp, u32 count);
223void exynos_dp_get_lane_count(struct exynos_dp_device *dp, u32 *count);
224void exynos_dp_enable_enhanced_mode(struct exynos_dp_device *dp, bool enable);
225void exynos_dp_set_training_pattern(struct exynos_dp_device *dp,
226 enum pattern_set pattern);
227void exynos_dp_set_lane0_pre_emphasis(struct exynos_dp_device *dp, u32 level);
228void exynos_dp_set_lane1_pre_emphasis(struct exynos_dp_device *dp, u32 level);
229void exynos_dp_set_lane2_pre_emphasis(struct exynos_dp_device *dp, u32 level);
230void exynos_dp_set_lane3_pre_emphasis(struct exynos_dp_device *dp, u32 level);
231void exynos_dp_set_lane0_link_training(struct exynos_dp_device *dp,
232 u32 training_lane);
233void exynos_dp_set_lane1_link_training(struct exynos_dp_device *dp,
234 u32 training_lane);
235void exynos_dp_set_lane2_link_training(struct exynos_dp_device *dp,
236 u32 training_lane);
237void exynos_dp_set_lane3_link_training(struct exynos_dp_device *dp,
238 u32 training_lane);
239u32 exynos_dp_get_lane0_link_training(struct exynos_dp_device *dp);
240u32 exynos_dp_get_lane1_link_training(struct exynos_dp_device *dp);
241u32 exynos_dp_get_lane2_link_training(struct exynos_dp_device *dp);
242u32 exynos_dp_get_lane3_link_training(struct exynos_dp_device *dp);
243void exynos_dp_reset_macro(struct exynos_dp_device *dp);
244void exynos_dp_init_video(struct exynos_dp_device *dp);
245
246void exynos_dp_set_video_color_format(struct exynos_dp_device *dp);
247int exynos_dp_is_slave_video_stream_clock_on(struct exynos_dp_device *dp);
248void exynos_dp_set_video_cr_mn(struct exynos_dp_device *dp,
249 enum clock_recovery_m_value_type type,
250 u32 m_value,
251 u32 n_value);
252void exynos_dp_set_video_timing_mode(struct exynos_dp_device *dp, u32 type);
253void exynos_dp_enable_video_master(struct exynos_dp_device *dp, bool enable);
254void exynos_dp_start_video(struct exynos_dp_device *dp);
255int exynos_dp_is_video_stream_on(struct exynos_dp_device *dp);
256void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp);
257void exynos_dp_enable_scrambling(struct exynos_dp_device *dp);
258void exynos_dp_disable_scrambling(struct exynos_dp_device *dp);
259
260/* I2C EDID Chip ID, Slave Address */
261#define I2C_EDID_DEVICE_ADDR 0x50
262#define I2C_E_EDID_DEVICE_ADDR 0x30
263
264#define EDID_BLOCK_LENGTH 0x80
265#define EDID_HEADER_PATTERN 0x00
266#define EDID_EXTENSION_FLAG 0x7e
267#define EDID_CHECKSUM 0x7f
268
269/* DP_MAX_LANE_COUNT */
270#define DPCD_ENHANCED_FRAME_CAP(x) (((x) >> 7) & 0x1)
271#define DPCD_MAX_LANE_COUNT(x) ((x) & 0x1f)
272
273/* DP_LANE_COUNT_SET */
274#define DPCD_LANE_COUNT_SET(x) ((x) & 0x1f)
275
276/* DP_TRAINING_LANE0_SET */
277#define DPCD_PRE_EMPHASIS_SET(x) (((x) & 0x3) << 3)
278#define DPCD_PRE_EMPHASIS_GET(x) (((x) >> 3) & 0x3)
279#define DPCD_VOLTAGE_SWING_SET(x) (((x) & 0x3) << 0)
280#define DPCD_VOLTAGE_SWING_GET(x) (((x) >> 0) & 0x3)
281
282#endif /* _EXYNOS_DP_CORE_H */
diff --git a/drivers/gpu/drm/exynos/exynos_dp_reg.c b/drivers/gpu/drm/exynos/exynos_dp_reg.c
deleted file mode 100644
index c1f87a2a9284..000000000000
--- a/drivers/gpu/drm/exynos/exynos_dp_reg.c
+++ /dev/null
@@ -1,1263 +0,0 @@
1/*
2 * Samsung DP (Display port) register interface driver.
3 *
4 * Copyright (C) 2012 Samsung Electronics Co., Ltd.
5 * Author: Jingoo Han <jg1.han@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/device.h>
14#include <linux/io.h>
15#include <linux/delay.h>
16#include <linux/gpio.h>
17
18#include "exynos_dp_core.h"
19#include "exynos_dp_reg.h"
20
21#define COMMON_INT_MASK_1 0
22#define COMMON_INT_MASK_2 0
23#define COMMON_INT_MASK_3 0
24#define COMMON_INT_MASK_4 (HOTPLUG_CHG | HPD_LOST | PLUG)
25#define INT_STA_MASK INT_HPD
26
27void exynos_dp_enable_video_mute(struct exynos_dp_device *dp, bool enable)
28{
29 u32 reg;
30
31 if (enable) {
32 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
33 reg |= HDCP_VIDEO_MUTE;
34 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
35 } else {
36 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
37 reg &= ~HDCP_VIDEO_MUTE;
38 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
39 }
40}
41
42void exynos_dp_stop_video(struct exynos_dp_device *dp)
43{
44 u32 reg;
45
46 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
47 reg &= ~VIDEO_EN;
48 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
49}
50
51void exynos_dp_lane_swap(struct exynos_dp_device *dp, bool enable)
52{
53 u32 reg;
54
55 if (enable)
56 reg = LANE3_MAP_LOGIC_LANE_0 | LANE2_MAP_LOGIC_LANE_1 |
57 LANE1_MAP_LOGIC_LANE_2 | LANE0_MAP_LOGIC_LANE_3;
58 else
59 reg = LANE3_MAP_LOGIC_LANE_3 | LANE2_MAP_LOGIC_LANE_2 |
60 LANE1_MAP_LOGIC_LANE_1 | LANE0_MAP_LOGIC_LANE_0;
61
62 writel(reg, dp->reg_base + EXYNOS_DP_LANE_MAP);
63}
64
65void exynos_dp_init_analog_param(struct exynos_dp_device *dp)
66{
67 u32 reg;
68
69 reg = TX_TERMINAL_CTRL_50_OHM;
70 writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_1);
71
72 reg = SEL_24M | TX_DVDD_BIT_1_0625V;
73 writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_2);
74
75 reg = DRIVE_DVDD_BIT_1_0625V | VCO_BIT_600_MICRO;
76 writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_3);
77
78 reg = PD_RING_OSC | AUX_TERMINAL_CTRL_50_OHM |
79 TX_CUR1_2X | TX_CUR_16_MA;
80 writel(reg, dp->reg_base + EXYNOS_DP_PLL_FILTER_CTL_1);
81
82 reg = CH3_AMP_400_MV | CH2_AMP_400_MV |
83 CH1_AMP_400_MV | CH0_AMP_400_MV;
84 writel(reg, dp->reg_base + EXYNOS_DP_TX_AMP_TUNING_CTL);
85}
86
87void exynos_dp_init_interrupt(struct exynos_dp_device *dp)
88{
89 /* Set interrupt pin assertion polarity as high */
90 writel(INT_POL1 | INT_POL0, dp->reg_base + EXYNOS_DP_INT_CTL);
91
92 /* Clear pending regisers */
93 writel(0xff, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1);
94 writel(0x4f, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_2);
95 writel(0xe0, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_3);
96 writel(0xe7, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4);
97 writel(0x63, dp->reg_base + EXYNOS_DP_INT_STA);
98
99 /* 0:mask,1: unmask */
100 writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_1);
101 writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_2);
102 writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_3);
103 writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_4);
104 writel(0x00, dp->reg_base + EXYNOS_DP_INT_STA_MASK);
105}
106
107void exynos_dp_reset(struct exynos_dp_device *dp)
108{
109 u32 reg;
110
111 exynos_dp_stop_video(dp);
112 exynos_dp_enable_video_mute(dp, 0);
113
114 reg = MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N |
115 AUD_FIFO_FUNC_EN_N | AUD_FUNC_EN_N |
116 HDCP_FUNC_EN_N | SW_FUNC_EN_N;
117 writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1);
118
119 reg = SSC_FUNC_EN_N | AUX_FUNC_EN_N |
120 SERDES_FIFO_FUNC_EN_N |
121 LS_CLK_DOMAIN_FUNC_EN_N;
122 writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2);
123
124 usleep_range(20, 30);
125
126 exynos_dp_lane_swap(dp, 0);
127
128 writel(0x0, dp->reg_base + EXYNOS_DP_SYS_CTL_1);
129 writel(0x40, dp->reg_base + EXYNOS_DP_SYS_CTL_2);
130 writel(0x0, dp->reg_base + EXYNOS_DP_SYS_CTL_3);
131 writel(0x0, dp->reg_base + EXYNOS_DP_SYS_CTL_4);
132
133 writel(0x0, dp->reg_base + EXYNOS_DP_PKT_SEND_CTL);
134 writel(0x0, dp->reg_base + EXYNOS_DP_HDCP_CTL);
135
136 writel(0x5e, dp->reg_base + EXYNOS_DP_HPD_DEGLITCH_L);
137 writel(0x1a, dp->reg_base + EXYNOS_DP_HPD_DEGLITCH_H);
138
139 writel(0x10, dp->reg_base + EXYNOS_DP_LINK_DEBUG_CTL);
140
141 writel(0x0, dp->reg_base + EXYNOS_DP_PHY_TEST);
142
143 writel(0x0, dp->reg_base + EXYNOS_DP_VIDEO_FIFO_THRD);
144 writel(0x20, dp->reg_base + EXYNOS_DP_AUDIO_MARGIN);
145
146 writel(0x4, dp->reg_base + EXYNOS_DP_M_VID_GEN_FILTER_TH);
147 writel(0x2, dp->reg_base + EXYNOS_DP_M_AUD_GEN_FILTER_TH);
148
149 writel(0x00000101, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
150}
151
152void exynos_dp_swreset(struct exynos_dp_device *dp)
153{
154 writel(RESET_DP_TX, dp->reg_base + EXYNOS_DP_TX_SW_RESET);
155}
156
157void exynos_dp_config_interrupt(struct exynos_dp_device *dp)
158{
159 u32 reg;
160
161 /* 0: mask, 1: unmask */
162 reg = COMMON_INT_MASK_1;
163 writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_1);
164
165 reg = COMMON_INT_MASK_2;
166 writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_2);
167
168 reg = COMMON_INT_MASK_3;
169 writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_3);
170
171 reg = COMMON_INT_MASK_4;
172 writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_4);
173
174 reg = INT_STA_MASK;
175 writel(reg, dp->reg_base + EXYNOS_DP_INT_STA_MASK);
176}
177
178enum pll_status exynos_dp_get_pll_lock_status(struct exynos_dp_device *dp)
179{
180 u32 reg;
181
182 reg = readl(dp->reg_base + EXYNOS_DP_DEBUG_CTL);
183 if (reg & PLL_LOCK)
184 return PLL_LOCKED;
185 else
186 return PLL_UNLOCKED;
187}
188
189void exynos_dp_set_pll_power_down(struct exynos_dp_device *dp, bool enable)
190{
191 u32 reg;
192
193 if (enable) {
194 reg = readl(dp->reg_base + EXYNOS_DP_PLL_CTL);
195 reg |= DP_PLL_PD;
196 writel(reg, dp->reg_base + EXYNOS_DP_PLL_CTL);
197 } else {
198 reg = readl(dp->reg_base + EXYNOS_DP_PLL_CTL);
199 reg &= ~DP_PLL_PD;
200 writel(reg, dp->reg_base + EXYNOS_DP_PLL_CTL);
201 }
202}
203
204void exynos_dp_set_analog_power_down(struct exynos_dp_device *dp,
205 enum analog_power_block block,
206 bool enable)
207{
208 u32 reg;
209
210 switch (block) {
211 case AUX_BLOCK:
212 if (enable) {
213 reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
214 reg |= AUX_PD;
215 writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
216 } else {
217 reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
218 reg &= ~AUX_PD;
219 writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
220 }
221 break;
222 case CH0_BLOCK:
223 if (enable) {
224 reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
225 reg |= CH0_PD;
226 writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
227 } else {
228 reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
229 reg &= ~CH0_PD;
230 writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
231 }
232 break;
233 case CH1_BLOCK:
234 if (enable) {
235 reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
236 reg |= CH1_PD;
237 writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
238 } else {
239 reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
240 reg &= ~CH1_PD;
241 writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
242 }
243 break;
244 case CH2_BLOCK:
245 if (enable) {
246 reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
247 reg |= CH2_PD;
248 writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
249 } else {
250 reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
251 reg &= ~CH2_PD;
252 writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
253 }
254 break;
255 case CH3_BLOCK:
256 if (enable) {
257 reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
258 reg |= CH3_PD;
259 writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
260 } else {
261 reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
262 reg &= ~CH3_PD;
263 writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
264 }
265 break;
266 case ANALOG_TOTAL:
267 if (enable) {
268 reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
269 reg |= DP_PHY_PD;
270 writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
271 } else {
272 reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
273 reg &= ~DP_PHY_PD;
274 writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
275 }
276 break;
277 case POWER_ALL:
278 if (enable) {
279 reg = DP_PHY_PD | AUX_PD | CH3_PD | CH2_PD |
280 CH1_PD | CH0_PD;
281 writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
282 } else {
283 writel(0x00, dp->reg_base + EXYNOS_DP_PHY_PD);
284 }
285 break;
286 default:
287 break;
288 }
289}
290
291void exynos_dp_init_analog_func(struct exynos_dp_device *dp)
292{
293 u32 reg;
294 int timeout_loop = 0;
295
296 exynos_dp_set_analog_power_down(dp, POWER_ALL, 0);
297
298 reg = PLL_LOCK_CHG;
299 writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1);
300
301 reg = readl(dp->reg_base + EXYNOS_DP_DEBUG_CTL);
302 reg &= ~(F_PLL_LOCK | PLL_LOCK_CTRL);
303 writel(reg, dp->reg_base + EXYNOS_DP_DEBUG_CTL);
304
305 /* Power up PLL */
306 if (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
307 exynos_dp_set_pll_power_down(dp, 0);
308
309 while (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
310 timeout_loop++;
311 if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
312 dev_err(dp->dev, "failed to get pll lock status\n");
313 return;
314 }
315 usleep_range(10, 20);
316 }
317 }
318
319 /* Enable Serdes FIFO function and Link symbol clock domain module */
320 reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_2);
321 reg &= ~(SERDES_FIFO_FUNC_EN_N | LS_CLK_DOMAIN_FUNC_EN_N
322 | AUX_FUNC_EN_N);
323 writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2);
324}
325
326void exynos_dp_clear_hotplug_interrupts(struct exynos_dp_device *dp)
327{
328 u32 reg;
329
330 if (gpio_is_valid(dp->hpd_gpio))
331 return;
332
333 reg = HOTPLUG_CHG | HPD_LOST | PLUG;
334 writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4);
335
336 reg = INT_HPD;
337 writel(reg, dp->reg_base + EXYNOS_DP_INT_STA);
338}
339
340void exynos_dp_init_hpd(struct exynos_dp_device *dp)
341{
342 u32 reg;
343
344 if (gpio_is_valid(dp->hpd_gpio))
345 return;
346
347 exynos_dp_clear_hotplug_interrupts(dp);
348
349 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3);
350 reg &= ~(F_HPD | HPD_CTRL);
351 writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3);
352}
353
354enum dp_irq_type exynos_dp_get_irq_type(struct exynos_dp_device *dp)
355{
356 u32 reg;
357
358 if (gpio_is_valid(dp->hpd_gpio)) {
359 reg = gpio_get_value(dp->hpd_gpio);
360 if (reg)
361 return DP_IRQ_TYPE_HP_CABLE_IN;
362 else
363 return DP_IRQ_TYPE_HP_CABLE_OUT;
364 } else {
365 /* Parse hotplug interrupt status register */
366 reg = readl(dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4);
367
368 if (reg & PLUG)
369 return DP_IRQ_TYPE_HP_CABLE_IN;
370
371 if (reg & HPD_LOST)
372 return DP_IRQ_TYPE_HP_CABLE_OUT;
373
374 if (reg & HOTPLUG_CHG)
375 return DP_IRQ_TYPE_HP_CHANGE;
376
377 return DP_IRQ_TYPE_UNKNOWN;
378 }
379}
380
381void exynos_dp_reset_aux(struct exynos_dp_device *dp)
382{
383 u32 reg;
384
385 /* Disable AUX channel module */
386 reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_2);
387 reg |= AUX_FUNC_EN_N;
388 writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2);
389}
390
391void exynos_dp_init_aux(struct exynos_dp_device *dp)
392{
393 u32 reg;
394
395 /* Clear inerrupts related to AUX channel */
396 reg = RPLY_RECEIV | AUX_ERR;
397 writel(reg, dp->reg_base + EXYNOS_DP_INT_STA);
398
399 exynos_dp_reset_aux(dp);
400
401 /* Disable AUX transaction H/W retry */
402 reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) | AUX_HW_RETRY_COUNT_SEL(0)|
403 AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
404 writel(reg, dp->reg_base + EXYNOS_DP_AUX_HW_RETRY_CTL);
405
406 /* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */
407 reg = DEFER_CTRL_EN | DEFER_COUNT(1);
408 writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_DEFER_CTL);
409
410 /* Enable AUX channel module */
411 reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_2);
412 reg &= ~AUX_FUNC_EN_N;
413 writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2);
414}
415
416int exynos_dp_get_plug_in_status(struct exynos_dp_device *dp)
417{
418 u32 reg;
419
420 if (gpio_is_valid(dp->hpd_gpio)) {
421 if (gpio_get_value(dp->hpd_gpio))
422 return 0;
423 } else {
424 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3);
425 if (reg & HPD_STATUS)
426 return 0;
427 }
428
429 return -EINVAL;
430}
431
432void exynos_dp_enable_sw_function(struct exynos_dp_device *dp)
433{
434 u32 reg;
435
436 reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_1);
437 reg &= ~SW_FUNC_EN_N;
438 writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1);
439}
440
441int exynos_dp_start_aux_transaction(struct exynos_dp_device *dp)
442{
443 int reg;
444 int retval = 0;
445 int timeout_loop = 0;
446
447 /* Enable AUX CH operation */
448 reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2);
449 reg |= AUX_EN;
450 writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2);
451
452 /* Is AUX CH command reply received? */
453 reg = readl(dp->reg_base + EXYNOS_DP_INT_STA);
454 while (!(reg & RPLY_RECEIV)) {
455 timeout_loop++;
456 if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
457 dev_err(dp->dev, "AUX CH command reply failed!\n");
458 return -ETIMEDOUT;
459 }
460 reg = readl(dp->reg_base + EXYNOS_DP_INT_STA);
461 usleep_range(10, 11);
462 }
463
464 /* Clear interrupt source for AUX CH command reply */
465 writel(RPLY_RECEIV, dp->reg_base + EXYNOS_DP_INT_STA);
466
467 /* Clear interrupt source for AUX CH access error */
468 reg = readl(dp->reg_base + EXYNOS_DP_INT_STA);
469 if (reg & AUX_ERR) {
470 writel(AUX_ERR, dp->reg_base + EXYNOS_DP_INT_STA);
471 return -EREMOTEIO;
472 }
473
474 /* Check AUX CH error access status */
475 reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_STA);
476 if ((reg & AUX_STATUS_MASK) != 0) {
477 dev_err(dp->dev, "AUX CH error happens: %d\n\n",
478 reg & AUX_STATUS_MASK);
479 return -EREMOTEIO;
480 }
481
482 return retval;
483}
484
485int exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp,
486 unsigned int reg_addr,
487 unsigned char data)
488{
489 u32 reg;
490 int i;
491 int retval;
492
493 for (i = 0; i < 3; i++) {
494 /* Clear AUX CH data buffer */
495 reg = BUF_CLR;
496 writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
497
498 /* Select DPCD device address */
499 reg = AUX_ADDR_7_0(reg_addr);
500 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
501 reg = AUX_ADDR_15_8(reg_addr);
502 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8);
503 reg = AUX_ADDR_19_16(reg_addr);
504 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16);
505
506 /* Write data buffer */
507 reg = (unsigned int)data;
508 writel(reg, dp->reg_base + EXYNOS_DP_BUF_DATA_0);
509
510 /*
511 * Set DisplayPort transaction and write 1 byte
512 * If bit 3 is 1, DisplayPort transaction.
513 * If Bit 3 is 0, I2C transaction.
514 */
515 reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE;
516 writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
517
518 /* Start AUX transaction */
519 retval = exynos_dp_start_aux_transaction(dp);
520 if (retval == 0)
521 break;
522 else
523 dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
524 __func__);
525 }
526
527 return retval;
528}
529
530int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
531 unsigned int reg_addr,
532 unsigned char *data)
533{
534 u32 reg;
535 int i;
536 int retval;
537
538 for (i = 0; i < 3; i++) {
539 /* Clear AUX CH data buffer */
540 reg = BUF_CLR;
541 writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
542
543 /* Select DPCD device address */
544 reg = AUX_ADDR_7_0(reg_addr);
545 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
546 reg = AUX_ADDR_15_8(reg_addr);
547 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8);
548 reg = AUX_ADDR_19_16(reg_addr);
549 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16);
550
551 /*
552 * Set DisplayPort transaction and read 1 byte
553 * If bit 3 is 1, DisplayPort transaction.
554 * If Bit 3 is 0, I2C transaction.
555 */
556 reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_READ;
557 writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
558
559 /* Start AUX transaction */
560 retval = exynos_dp_start_aux_transaction(dp);
561 if (retval == 0)
562 break;
563 else
564 dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
565 __func__);
566 }
567
568 /* Read data buffer */
569 reg = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0);
570 *data = (unsigned char)(reg & 0xff);
571
572 return retval;
573}
574
575int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
576 unsigned int reg_addr,
577 unsigned int count,
578 unsigned char data[])
579{
580 u32 reg;
581 unsigned int start_offset;
582 unsigned int cur_data_count;
583 unsigned int cur_data_idx;
584 int i;
585 int retval = 0;
586
587 /* Clear AUX CH data buffer */
588 reg = BUF_CLR;
589 writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
590
591 start_offset = 0;
592 while (start_offset < count) {
593 /* Buffer size of AUX CH is 16 * 4bytes */
594 if ((count - start_offset) > 16)
595 cur_data_count = 16;
596 else
597 cur_data_count = count - start_offset;
598
599 for (i = 0; i < 3; i++) {
600 /* Select DPCD device address */
601 reg = AUX_ADDR_7_0(reg_addr + start_offset);
602 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
603 reg = AUX_ADDR_15_8(reg_addr + start_offset);
604 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8);
605 reg = AUX_ADDR_19_16(reg_addr + start_offset);
606 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16);
607
608 for (cur_data_idx = 0; cur_data_idx < cur_data_count;
609 cur_data_idx++) {
610 reg = data[start_offset + cur_data_idx];
611 writel(reg, dp->reg_base + EXYNOS_DP_BUF_DATA_0
612 + 4 * cur_data_idx);
613 }
614
615 /*
616 * Set DisplayPort transaction and write
617 * If bit 3 is 1, DisplayPort transaction.
618 * If Bit 3 is 0, I2C transaction.
619 */
620 reg = AUX_LENGTH(cur_data_count) |
621 AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE;
622 writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
623
624 /* Start AUX transaction */
625 retval = exynos_dp_start_aux_transaction(dp);
626 if (retval == 0)
627 break;
628 else
629 dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
630 __func__);
631 }
632
633 start_offset += cur_data_count;
634 }
635
636 return retval;
637}
638
639int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp,
640 unsigned int reg_addr,
641 unsigned int count,
642 unsigned char data[])
643{
644 u32 reg;
645 unsigned int start_offset;
646 unsigned int cur_data_count;
647 unsigned int cur_data_idx;
648 int i;
649 int retval = 0;
650
651 /* Clear AUX CH data buffer */
652 reg = BUF_CLR;
653 writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
654
655 start_offset = 0;
656 while (start_offset < count) {
657 /* Buffer size of AUX CH is 16 * 4bytes */
658 if ((count - start_offset) > 16)
659 cur_data_count = 16;
660 else
661 cur_data_count = count - start_offset;
662
663 /* AUX CH Request Transaction process */
664 for (i = 0; i < 3; i++) {
665 /* Select DPCD device address */
666 reg = AUX_ADDR_7_0(reg_addr + start_offset);
667 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
668 reg = AUX_ADDR_15_8(reg_addr + start_offset);
669 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8);
670 reg = AUX_ADDR_19_16(reg_addr + start_offset);
671 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16);
672
673 /*
674 * Set DisplayPort transaction and read
675 * If bit 3 is 1, DisplayPort transaction.
676 * If Bit 3 is 0, I2C transaction.
677 */
678 reg = AUX_LENGTH(cur_data_count) |
679 AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_READ;
680 writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
681
682 /* Start AUX transaction */
683 retval = exynos_dp_start_aux_transaction(dp);
684 if (retval == 0)
685 break;
686 else
687 dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
688 __func__);
689 }
690
691 for (cur_data_idx = 0; cur_data_idx < cur_data_count;
692 cur_data_idx++) {
693 reg = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0
694 + 4 * cur_data_idx);
695 data[start_offset + cur_data_idx] =
696 (unsigned char)reg;
697 }
698
699 start_offset += cur_data_count;
700 }
701
702 return retval;
703}
704
705int exynos_dp_select_i2c_device(struct exynos_dp_device *dp,
706 unsigned int device_addr,
707 unsigned int reg_addr)
708{
709 u32 reg;
710 int retval;
711
712 /* Set EDID device address */
713 reg = device_addr;
714 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
715 writel(0x0, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8);
716 writel(0x0, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16);
717
718 /* Set offset from base address of EDID device */
719 writel(reg_addr, dp->reg_base + EXYNOS_DP_BUF_DATA_0);
720
721 /*
722 * Set I2C transaction and write address
723 * If bit 3 is 1, DisplayPort transaction.
724 * If Bit 3 is 0, I2C transaction.
725 */
726 reg = AUX_TX_COMM_I2C_TRANSACTION | AUX_TX_COMM_MOT |
727 AUX_TX_COMM_WRITE;
728 writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
729
730 /* Start AUX transaction */
731 retval = exynos_dp_start_aux_transaction(dp);
732 if (retval != 0)
733 dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
734
735 return retval;
736}
737
738int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
739 unsigned int device_addr,
740 unsigned int reg_addr,
741 unsigned int *data)
742{
743 u32 reg;
744 int i;
745 int retval;
746
747 for (i = 0; i < 3; i++) {
748 /* Clear AUX CH data buffer */
749 reg = BUF_CLR;
750 writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
751
752 /* Select EDID device */
753 retval = exynos_dp_select_i2c_device(dp, device_addr, reg_addr);
754 if (retval != 0)
755 continue;
756
757 /*
758 * Set I2C transaction and read data
759 * If bit 3 is 1, DisplayPort transaction.
760 * If Bit 3 is 0, I2C transaction.
761 */
762 reg = AUX_TX_COMM_I2C_TRANSACTION |
763 AUX_TX_COMM_READ;
764 writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
765
766 /* Start AUX transaction */
767 retval = exynos_dp_start_aux_transaction(dp);
768 if (retval == 0)
769 break;
770 else
771 dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
772 __func__);
773 }
774
775 /* Read data */
776 if (retval == 0)
777 *data = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0);
778
779 return retval;
780}
781
782int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
783 unsigned int device_addr,
784 unsigned int reg_addr,
785 unsigned int count,
786 unsigned char edid[])
787{
788 u32 reg;
789 unsigned int i, j;
790 unsigned int cur_data_idx;
791 unsigned int defer = 0;
792 int retval = 0;
793
794 for (i = 0; i < count; i += 16) {
795 for (j = 0; j < 3; j++) {
796 /* Clear AUX CH data buffer */
797 reg = BUF_CLR;
798 writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
799
800 /* Set normal AUX CH command */
801 reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2);
802 reg &= ~ADDR_ONLY;
803 writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2);
804
805 /*
806 * If Rx sends defer, Tx sends only reads
807 * request without sending address
808 */
809 if (!defer)
810 retval = exynos_dp_select_i2c_device(dp,
811 device_addr, reg_addr + i);
812 else
813 defer = 0;
814
815 if (retval == 0) {
816 /*
817 * Set I2C transaction and write data
818 * If bit 3 is 1, DisplayPort transaction.
819 * If Bit 3 is 0, I2C transaction.
820 */
821 reg = AUX_LENGTH(16) |
822 AUX_TX_COMM_I2C_TRANSACTION |
823 AUX_TX_COMM_READ;
824 writel(reg, dp->reg_base +
825 EXYNOS_DP_AUX_CH_CTL_1);
826
827 /* Start AUX transaction */
828 retval = exynos_dp_start_aux_transaction(dp);
829 if (retval == 0)
830 break;
831 else
832 dev_dbg(dp->dev,
833 "%s: Aux Transaction fail!\n",
834 __func__);
835 }
836 /* Check if Rx sends defer */
837 reg = readl(dp->reg_base + EXYNOS_DP_AUX_RX_COMM);
838 if (reg == AUX_RX_COMM_AUX_DEFER ||
839 reg == AUX_RX_COMM_I2C_DEFER) {
840 dev_err(dp->dev, "Defer: %d\n\n", reg);
841 defer = 1;
842 }
843 }
844
845 for (cur_data_idx = 0; cur_data_idx < 16; cur_data_idx++) {
846 reg = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0
847 + 4 * cur_data_idx);
848 edid[i + cur_data_idx] = (unsigned char)reg;
849 }
850 }
851
852 return retval;
853}
854
855void exynos_dp_set_link_bandwidth(struct exynos_dp_device *dp, u32 bwtype)
856{
857 u32 reg;
858
859 reg = bwtype;
860 if ((bwtype == LINK_RATE_2_70GBPS) || (bwtype == LINK_RATE_1_62GBPS))
861 writel(reg, dp->reg_base + EXYNOS_DP_LINK_BW_SET);
862}
863
864void exynos_dp_get_link_bandwidth(struct exynos_dp_device *dp, u32 *bwtype)
865{
866 u32 reg;
867
868 reg = readl(dp->reg_base + EXYNOS_DP_LINK_BW_SET);
869 *bwtype = reg;
870}
871
872void exynos_dp_set_lane_count(struct exynos_dp_device *dp, u32 count)
873{
874 u32 reg;
875
876 reg = count;
877 writel(reg, dp->reg_base + EXYNOS_DP_LANE_COUNT_SET);
878}
879
880void exynos_dp_get_lane_count(struct exynos_dp_device *dp, u32 *count)
881{
882 u32 reg;
883
884 reg = readl(dp->reg_base + EXYNOS_DP_LANE_COUNT_SET);
885 *count = reg;
886}
887
888void exynos_dp_enable_enhanced_mode(struct exynos_dp_device *dp, bool enable)
889{
890 u32 reg;
891
892 if (enable) {
893 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4);
894 reg |= ENHANCED;
895 writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4);
896 } else {
897 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4);
898 reg &= ~ENHANCED;
899 writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4);
900 }
901}
902
903void exynos_dp_set_training_pattern(struct exynos_dp_device *dp,
904 enum pattern_set pattern)
905{
906 u32 reg;
907
908 switch (pattern) {
909 case PRBS7:
910 reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_PRBS7;
911 writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
912 break;
913 case D10_2:
914 reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_D10_2;
915 writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
916 break;
917 case TRAINING_PTN1:
918 reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN1;
919 writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
920 break;
921 case TRAINING_PTN2:
922 reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN2;
923 writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
924 break;
925 case DP_NONE:
926 reg = SCRAMBLING_ENABLE |
927 LINK_QUAL_PATTERN_SET_DISABLE |
928 SW_TRAINING_PATTERN_SET_NORMAL;
929 writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
930 break;
931 default:
932 break;
933 }
934}
935
936void exynos_dp_set_lane0_pre_emphasis(struct exynos_dp_device *dp, u32 level)
937{
938 u32 reg;
939
940 reg = readl(dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL);
941 reg &= ~PRE_EMPHASIS_SET_MASK;
942 reg |= level << PRE_EMPHASIS_SET_SHIFT;
943 writel(reg, dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL);
944}
945
946void exynos_dp_set_lane1_pre_emphasis(struct exynos_dp_device *dp, u32 level)
947{
948 u32 reg;
949
950 reg = readl(dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL);
951 reg &= ~PRE_EMPHASIS_SET_MASK;
952 reg |= level << PRE_EMPHASIS_SET_SHIFT;
953 writel(reg, dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL);
954}
955
956void exynos_dp_set_lane2_pre_emphasis(struct exynos_dp_device *dp, u32 level)
957{
958 u32 reg;
959
960 reg = readl(dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL);
961 reg &= ~PRE_EMPHASIS_SET_MASK;
962 reg |= level << PRE_EMPHASIS_SET_SHIFT;
963 writel(reg, dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL);
964}
965
966void exynos_dp_set_lane3_pre_emphasis(struct exynos_dp_device *dp, u32 level)
967{
968 u32 reg;
969
970 reg = readl(dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL);
971 reg &= ~PRE_EMPHASIS_SET_MASK;
972 reg |= level << PRE_EMPHASIS_SET_SHIFT;
973 writel(reg, dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL);
974}
975
976void exynos_dp_set_lane0_link_training(struct exynos_dp_device *dp,
977 u32 training_lane)
978{
979 u32 reg;
980
981 reg = training_lane;
982 writel(reg, dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL);
983}
984
985void exynos_dp_set_lane1_link_training(struct exynos_dp_device *dp,
986 u32 training_lane)
987{
988 u32 reg;
989
990 reg = training_lane;
991 writel(reg, dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL);
992}
993
994void exynos_dp_set_lane2_link_training(struct exynos_dp_device *dp,
995 u32 training_lane)
996{
997 u32 reg;
998
999 reg = training_lane;
1000 writel(reg, dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL);
1001}
1002
1003void exynos_dp_set_lane3_link_training(struct exynos_dp_device *dp,
1004 u32 training_lane)
1005{
1006 u32 reg;
1007
1008 reg = training_lane;
1009 writel(reg, dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL);
1010}
1011
1012u32 exynos_dp_get_lane0_link_training(struct exynos_dp_device *dp)
1013{
1014 u32 reg;
1015
1016 reg = readl(dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL);
1017 return reg;
1018}
1019
1020u32 exynos_dp_get_lane1_link_training(struct exynos_dp_device *dp)
1021{
1022 u32 reg;
1023
1024 reg = readl(dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL);
1025 return reg;
1026}
1027
1028u32 exynos_dp_get_lane2_link_training(struct exynos_dp_device *dp)
1029{
1030 u32 reg;
1031
1032 reg = readl(dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL);
1033 return reg;
1034}
1035
1036u32 exynos_dp_get_lane3_link_training(struct exynos_dp_device *dp)
1037{
1038 u32 reg;
1039
1040 reg = readl(dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL);
1041 return reg;
1042}
1043
1044void exynos_dp_reset_macro(struct exynos_dp_device *dp)
1045{
1046 u32 reg;
1047
1048 reg = readl(dp->reg_base + EXYNOS_DP_PHY_TEST);
1049 reg |= MACRO_RST;
1050 writel(reg, dp->reg_base + EXYNOS_DP_PHY_TEST);
1051
1052 /* 10 us is the minimum reset time. */
1053 usleep_range(10, 20);
1054
1055 reg &= ~MACRO_RST;
1056 writel(reg, dp->reg_base + EXYNOS_DP_PHY_TEST);
1057}
1058
1059void exynos_dp_init_video(struct exynos_dp_device *dp)
1060{
1061 u32 reg;
1062
1063 reg = VSYNC_DET | VID_FORMAT_CHG | VID_CLK_CHG;
1064 writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1);
1065
1066 reg = 0x0;
1067 writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_1);
1068
1069 reg = CHA_CRI(4) | CHA_CTRL;
1070 writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_2);
1071
1072 reg = 0x0;
1073 writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3);
1074
1075 reg = VID_HRES_TH(2) | VID_VRES_TH(0);
1076 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_8);
1077}
1078
1079void exynos_dp_set_video_color_format(struct exynos_dp_device *dp)
1080{
1081 u32 reg;
1082
1083 /* Configure the input color depth, color space, dynamic range */
1084 reg = (dp->video_info->dynamic_range << IN_D_RANGE_SHIFT) |
1085 (dp->video_info->color_depth << IN_BPC_SHIFT) |
1086 (dp->video_info->color_space << IN_COLOR_F_SHIFT);
1087 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_2);
1088
1089 /* Set Input Color YCbCr Coefficients to ITU601 or ITU709 */
1090 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_3);
1091 reg &= ~IN_YC_COEFFI_MASK;
1092 if (dp->video_info->ycbcr_coeff)
1093 reg |= IN_YC_COEFFI_ITU709;
1094 else
1095 reg |= IN_YC_COEFFI_ITU601;
1096 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_3);
1097}
1098
1099int exynos_dp_is_slave_video_stream_clock_on(struct exynos_dp_device *dp)
1100{
1101 u32 reg;
1102
1103 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_1);
1104 writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_1);
1105
1106 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_1);
1107
1108 if (!(reg & DET_STA)) {
1109 dev_dbg(dp->dev, "Input stream clock not detected.\n");
1110 return -EINVAL;
1111 }
1112
1113 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_2);
1114 writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_2);
1115
1116 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_2);
1117 dev_dbg(dp->dev, "wait SYS_CTL_2.\n");
1118
1119 if (reg & CHA_STA) {
1120 dev_dbg(dp->dev, "Input stream clk is changing\n");
1121 return -EINVAL;
1122 }
1123
1124 return 0;
1125}
1126
1127void exynos_dp_set_video_cr_mn(struct exynos_dp_device *dp,
1128 enum clock_recovery_m_value_type type,
1129 u32 m_value,
1130 u32 n_value)
1131{
1132 u32 reg;
1133
1134 if (type == REGISTER_M) {
1135 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4);
1136 reg |= FIX_M_VID;
1137 writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4);
1138 reg = m_value & 0xff;
1139 writel(reg, dp->reg_base + EXYNOS_DP_M_VID_0);
1140 reg = (m_value >> 8) & 0xff;
1141 writel(reg, dp->reg_base + EXYNOS_DP_M_VID_1);
1142 reg = (m_value >> 16) & 0xff;
1143 writel(reg, dp->reg_base + EXYNOS_DP_M_VID_2);
1144
1145 reg = n_value & 0xff;
1146 writel(reg, dp->reg_base + EXYNOS_DP_N_VID_0);
1147 reg = (n_value >> 8) & 0xff;
1148 writel(reg, dp->reg_base + EXYNOS_DP_N_VID_1);
1149 reg = (n_value >> 16) & 0xff;
1150 writel(reg, dp->reg_base + EXYNOS_DP_N_VID_2);
1151 } else {
1152 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4);
1153 reg &= ~FIX_M_VID;
1154 writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4);
1155
1156 writel(0x00, dp->reg_base + EXYNOS_DP_N_VID_0);
1157 writel(0x80, dp->reg_base + EXYNOS_DP_N_VID_1);
1158 writel(0x00, dp->reg_base + EXYNOS_DP_N_VID_2);
1159 }
1160}
1161
1162void exynos_dp_set_video_timing_mode(struct exynos_dp_device *dp, u32 type)
1163{
1164 u32 reg;
1165
1166 if (type == VIDEO_TIMING_FROM_CAPTURE) {
1167 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
1168 reg &= ~FORMAT_SEL;
1169 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
1170 } else {
1171 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
1172 reg |= FORMAT_SEL;
1173 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
1174 }
1175}
1176
1177void exynos_dp_enable_video_master(struct exynos_dp_device *dp, bool enable)
1178{
1179 u32 reg;
1180
1181 if (enable) {
1182 reg = readl(dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
1183 reg &= ~VIDEO_MODE_MASK;
1184 reg |= VIDEO_MASTER_MODE_EN | VIDEO_MODE_MASTER_MODE;
1185 writel(reg, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
1186 } else {
1187 reg = readl(dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
1188 reg &= ~VIDEO_MODE_MASK;
1189 reg |= VIDEO_MODE_SLAVE_MODE;
1190 writel(reg, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
1191 }
1192}
1193
1194void exynos_dp_start_video(struct exynos_dp_device *dp)
1195{
1196 u32 reg;
1197
1198 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
1199 reg |= VIDEO_EN;
1200 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
1201}
1202
1203int exynos_dp_is_video_stream_on(struct exynos_dp_device *dp)
1204{
1205 u32 reg;
1206
1207 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3);
1208 writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3);
1209
1210 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3);
1211 if (!(reg & STRM_VALID)) {
1212 dev_dbg(dp->dev, "Input video stream is not detected.\n");
1213 return -EINVAL;
1214 }
1215
1216 return 0;
1217}
1218
1219void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp)
1220{
1221 u32 reg;
1222
1223 reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_1);
1224 reg &= ~(MASTER_VID_FUNC_EN_N|SLAVE_VID_FUNC_EN_N);
1225 reg |= MASTER_VID_FUNC_EN_N;
1226 writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1);
1227
1228 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
1229 reg &= ~INTERACE_SCAN_CFG;
1230 reg |= (dp->video_info->interlaced << 2);
1231 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
1232
1233 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
1234 reg &= ~VSYNC_POLARITY_CFG;
1235 reg |= (dp->video_info->v_sync_polarity << 1);
1236 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
1237
1238 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
1239 reg &= ~HSYNC_POLARITY_CFG;
1240 reg |= (dp->video_info->h_sync_polarity << 0);
1241 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
1242
1243 reg = AUDIO_MODE_SPDIF_MODE | VIDEO_MODE_SLAVE_MODE;
1244 writel(reg, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
1245}
1246
1247void exynos_dp_enable_scrambling(struct exynos_dp_device *dp)
1248{
1249 u32 reg;
1250
1251 reg = readl(dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
1252 reg &= ~SCRAMBLING_DISABLE;
1253 writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
1254}
1255
1256void exynos_dp_disable_scrambling(struct exynos_dp_device *dp)
1257{
1258 u32 reg;
1259
1260 reg = readl(dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
1261 reg |= SCRAMBLING_DISABLE;
1262 writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
1263}
diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index 76b3362c5e59..d30bdc38a760 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -16,6 +16,15 @@ config DRM_ROCKCHIP
16 2D or 3D acceleration; acceleration is performed by other 16 2D or 3D acceleration; acceleration is performed by other
17 IP found on the SoC. 17 IP found on the SoC.
18 18
19config ROCKCHIP_ANALOGIX_DP
20 tristate "Rockchip specific extensions for Analogix DP driver"
21 depends on DRM_ROCKCHIP
22 select DRM_ANALOGIX_DP
23 help
24 This selects support for Rockchip SoC specific extensions
25 for the Analogix Core DP driver. If you want to enable DP
26 on RK3288 based SoC, you should selet this option.
27
19config ROCKCHIP_DW_HDMI 28config ROCKCHIP_DW_HDMI
20 tristate "Rockchip specific extensions for Synopsys DW HDMI" 29 tristate "Rockchip specific extensions for Synopsys DW HDMI"
21 depends on DRM_ROCKCHIP 30 depends on DRM_ROCKCHIP
diff --git a/drivers/gpu/drm/rockchip/Makefile b/drivers/gpu/drm/rockchip/Makefile
index df8fbef17791..05d07138a2b2 100644
--- a/drivers/gpu/drm/rockchip/Makefile
+++ b/drivers/gpu/drm/rockchip/Makefile
@@ -6,6 +6,7 @@ rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o \
6 rockchip_drm_gem.o rockchip_drm_vop.o 6 rockchip_drm_gem.o rockchip_drm_vop.o
7rockchipdrm-$(CONFIG_DRM_FBDEV_EMULATION) += rockchip_drm_fbdev.o 7rockchipdrm-$(CONFIG_DRM_FBDEV_EMULATION) += rockchip_drm_fbdev.o
8 8
9obj-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o
9obj-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o 10obj-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
10obj-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi.o 11obj-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi.o
11obj-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o 12obj-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
new file mode 100644
index 000000000000..a1d94d8d9443
--- /dev/null
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -0,0 +1,384 @@
1/*
2 * Rockchip SoC DP (Display Port) interface driver.
3 *
4 * Copyright (C) Fuzhou Rockchip Electronics Co., Ltd.
5 * Author: Andy Yan <andy.yan@rock-chips.com>
6 * Yakir Yang <ykk@rock-chips.com>
7 * Jeff Chen <jeff.chen@rock-chips.com>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 */
14
15#include <linux/component.h>
16#include <linux/mfd/syscon.h>
17#include <linux/of_graph.h>
18#include <linux/regmap.h>
19#include <linux/reset.h>
20#include <linux/clk.h>
21
22#include <drm/drmP.h>
23#include <drm/drm_crtc_helper.h>
24#include <drm/drm_dp_helper.h>
25#include <drm/drm_of.h>
26#include <drm/drm_panel.h>
27
28#include <video/of_videomode.h>
29#include <video/videomode.h>
30
31#include <drm/bridge/analogix_dp.h>
32
33#include "rockchip_drm_drv.h"
34#include "rockchip_drm_vop.h"
35
36#define to_dp(nm) container_of(nm, struct rockchip_dp_device, nm)
37
38/* dp grf register offset */
39#define GRF_SOC_CON6 0x025c
40#define GRF_EDP_LCD_SEL_MASK BIT(5)
41#define GRF_EDP_SEL_VOP_LIT BIT(5)
42#define GRF_EDP_SEL_VOP_BIG 0
43
44struct rockchip_dp_device {
45 struct drm_device *drm_dev;
46 struct device *dev;
47 struct drm_encoder encoder;
48 struct drm_display_mode mode;
49
50 struct clk *pclk;
51 struct regmap *grf;
52 struct reset_control *rst;
53
54 struct analogix_dp_plat_data plat_data;
55};
56
57static int rockchip_dp_pre_init(struct rockchip_dp_device *dp)
58{
59 reset_control_assert(dp->rst);
60 usleep_range(10, 20);
61 reset_control_deassert(dp->rst);
62
63 return 0;
64}
65
66static int rockchip_dp_poweron(struct analogix_dp_plat_data *plat_data)
67{
68 struct rockchip_dp_device *dp = to_dp(plat_data);
69 int ret;
70
71 ret = clk_prepare_enable(dp->pclk);
72 if (ret < 0) {
73 dev_err(dp->dev, "failed to enable pclk %d\n", ret);
74 return ret;
75 }
76
77 ret = rockchip_dp_pre_init(dp);
78 if (ret < 0) {
79 dev_err(dp->dev, "failed to dp pre init %d\n", ret);
80 return ret;
81 }
82
83 return 0;
84}
85
86static int rockchip_dp_powerdown(struct analogix_dp_plat_data *plat_data)
87{
88 struct rockchip_dp_device *dp = to_dp(plat_data);
89
90 clk_disable_unprepare(dp->pclk);
91
92 return 0;
93}
94
95static bool
96rockchip_dp_drm_encoder_mode_fixup(struct drm_encoder *encoder,
97 const struct drm_display_mode *mode,
98 struct drm_display_mode *adjusted_mode)
99{
100 /* do nothing */
101 return true;
102}
103
104static void rockchip_dp_drm_encoder_mode_set(struct drm_encoder *encoder,
105 struct drm_display_mode *mode,
106 struct drm_display_mode *adjusted)
107{
108 /* do nothing */
109}
110
111static void rockchip_dp_drm_encoder_enable(struct drm_encoder *encoder)
112{
113 struct rockchip_dp_device *dp = to_dp(encoder);
114 int ret;
115 u32 val;
116
117 /*
118 * FIXME(Yakir): driver should configure the CRTC output video
119 * mode with the display information which indicated the monitor
120 * support colorimetry.
121 *
122 * But don't know why the CRTC driver seems could only output the
123 * RGBaaa rightly. For example, if connect the "innolux,n116bge"
124 * eDP screen, EDID would indicated that screen only accepted the
125 * 6bpc mode. But if I configure CRTC to RGB666 output, then eDP
126 * screen would show a blue picture (RGB888 show a green picture).
127 * But if I configure CTRC to RGBaaa, and eDP driver still keep
128 * RGB666 input video mode, then screen would works prefect.
129 */
130 ret = rockchip_drm_crtc_mode_config(encoder->crtc,
131 DRM_MODE_CONNECTOR_eDP,
132 ROCKCHIP_OUT_MODE_AAAA);
133 if (ret < 0) {
134 dev_err(dp->dev, "Could not set crtc mode config (%d)\n", ret);
135 return;
136 }
137
138 ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, encoder);
139 if (ret < 0)
140 return;
141
142 if (ret)
143 val = GRF_EDP_SEL_VOP_LIT | (GRF_EDP_LCD_SEL_MASK << 16);
144 else
145 val = GRF_EDP_SEL_VOP_BIG | (GRF_EDP_LCD_SEL_MASK << 16);
146
147 dev_dbg(dp->dev, "vop %s output to dp\n", (ret) ? "LIT" : "BIG");
148
149 ret = regmap_write(dp->grf, GRF_SOC_CON6, val);
150 if (ret != 0) {
151 dev_err(dp->dev, "Could not write to GRF: %d\n", ret);
152 return;
153 }
154}
155
156static void rockchip_dp_drm_encoder_nop(struct drm_encoder *encoder)
157{
158 /* do nothing */
159}
160
161static struct drm_encoder_helper_funcs rockchip_dp_encoder_helper_funcs = {
162 .mode_fixup = rockchip_dp_drm_encoder_mode_fixup,
163 .mode_set = rockchip_dp_drm_encoder_mode_set,
164 .enable = rockchip_dp_drm_encoder_enable,
165 .disable = rockchip_dp_drm_encoder_nop,
166};
167
168static void rockchip_dp_drm_encoder_destroy(struct drm_encoder *encoder)
169{
170 drm_encoder_cleanup(encoder);
171}
172
173static struct drm_encoder_funcs rockchip_dp_encoder_funcs = {
174 .destroy = rockchip_dp_drm_encoder_destroy,
175};
176
177static int rockchip_dp_init(struct rockchip_dp_device *dp)
178{
179 struct device *dev = dp->dev;
180 struct device_node *np = dev->of_node;
181 int ret;
182
183 dp->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
184 if (IS_ERR(dp->grf)) {
185 dev_err(dev, "failed to get rockchip,grf property\n");
186 return PTR_ERR(dp->grf);
187 }
188
189 dp->pclk = devm_clk_get(dev, "pclk");
190 if (IS_ERR(dp->pclk)) {
191 dev_err(dev, "failed to get pclk property\n");
192 return PTR_ERR(dp->pclk);
193 }
194
195 dp->rst = devm_reset_control_get(dev, "dp");
196 if (IS_ERR(dp->rst)) {
197 dev_err(dev, "failed to get dp reset control\n");
198 return PTR_ERR(dp->rst);
199 }
200
201 ret = clk_prepare_enable(dp->pclk);
202 if (ret < 0) {
203 dev_err(dp->dev, "failed to enable pclk %d\n", ret);
204 return ret;
205 }
206
207 ret = rockchip_dp_pre_init(dp);
208 if (ret < 0) {
209 dev_err(dp->dev, "failed to pre init %d\n", ret);
210 return ret;
211 }
212
213 return 0;
214}
215
216static int rockchip_dp_drm_create_encoder(struct rockchip_dp_device *dp)
217{
218 struct drm_encoder *encoder = &dp->encoder;
219 struct drm_device *drm_dev = dp->drm_dev;
220 struct device *dev = dp->dev;
221 int ret;
222
223 encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev,
224 dev->of_node);
225 DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
226
227 ret = drm_encoder_init(drm_dev, encoder, &rockchip_dp_encoder_funcs,
228 DRM_MODE_ENCODER_TMDS, NULL);
229 if (ret) {
230 DRM_ERROR("failed to initialize encoder with drm\n");
231 return ret;
232 }
233
234 drm_encoder_helper_add(encoder, &rockchip_dp_encoder_helper_funcs);
235
236 return 0;
237}
238
239static int rockchip_dp_bind(struct device *dev, struct device *master,
240 void *data)
241{
242 struct rockchip_dp_device *dp = dev_get_drvdata(dev);
243 struct drm_device *drm_dev = data;
244 int ret;
245
246 /*
247 * Just like the probe function said, we don't need the
248 * device drvrate anymore, we should leave the charge to
249 * analogix dp driver, set the device drvdata to NULL.
250 */
251 dev_set_drvdata(dev, NULL);
252
253 ret = rockchip_dp_init(dp);
254 if (ret < 0)
255 return ret;
256
257 dp->drm_dev = drm_dev;
258
259 ret = rockchip_dp_drm_create_encoder(dp);
260 if (ret) {
261 DRM_ERROR("failed to create drm encoder\n");
262 return ret;
263 }
264
265 dp->plat_data.encoder = &dp->encoder;
266
267 dp->plat_data.dev_type = RK3288_DP;
268 dp->plat_data.power_on = rockchip_dp_poweron;
269 dp->plat_data.power_off = rockchip_dp_powerdown;
270
271 return analogix_dp_bind(dev, dp->drm_dev, &dp->plat_data);
272}
273
274static void rockchip_dp_unbind(struct device *dev, struct device *master,
275 void *data)
276{
277 return analogix_dp_unbind(dev, master, data);
278}
279
280static const struct component_ops rockchip_dp_component_ops = {
281 .bind = rockchip_dp_bind,
282 .unbind = rockchip_dp_unbind,
283};
284
285static int rockchip_dp_probe(struct platform_device *pdev)
286{
287 struct device *dev = &pdev->dev;
288 struct device_node *panel_node, *port, *endpoint;
289 struct rockchip_dp_device *dp;
290 struct drm_panel *panel;
291
292 port = of_graph_get_port_by_id(dev->of_node, 1);
293 if (!port) {
294 dev_err(dev, "can't find output port\n");
295 return -EINVAL;
296 }
297
298 endpoint = of_get_child_by_name(port, "endpoint");
299 of_node_put(port);
300 if (!endpoint) {
301 dev_err(dev, "no output endpoint found\n");
302 return -EINVAL;
303 }
304
305 panel_node = of_graph_get_remote_port_parent(endpoint);
306 of_node_put(endpoint);
307 if (!panel_node) {
308 dev_err(dev, "no output node found\n");
309 return -EINVAL;
310 }
311
312 panel = of_drm_find_panel(panel_node);
313 if (!panel) {
314 DRM_ERROR("failed to find panel\n");
315 of_node_put(panel_node);
316 return -EPROBE_DEFER;
317 }
318
319 of_node_put(panel_node);
320
321 dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL);
322 if (!dp)
323 return -ENOMEM;
324
325 dp->dev = dev;
326
327 dp->plat_data.panel = panel;
328
329 /*
330 * We just use the drvdata until driver run into component
331 * add function, and then we would set drvdata to null, so
332 * that analogix dp driver could take charge of the drvdata.
333 */
334 platform_set_drvdata(pdev, dp);
335
336 return component_add(dev, &rockchip_dp_component_ops);
337}
338
339static int rockchip_dp_remove(struct platform_device *pdev)
340{
341 component_del(&pdev->dev, &rockchip_dp_component_ops);
342
343 return 0;
344}
345
346#ifdef CONFIG_PM_SLEEP
347static int rockchip_dp_suspend(struct device *dev)
348{
349 return analogix_dp_suspend(dev);
350}
351
352static int rockchip_dp_resume(struct device *dev)
353{
354 return analogix_dp_resume(dev);
355}
356#endif
357
358static const struct dev_pm_ops rockchip_dp_pm_ops = {
359 SET_SYSTEM_SLEEP_PM_OPS(rockchip_dp_suspend, rockchip_dp_resume)
360};
361
362static const struct of_device_id rockchip_dp_dt_ids[] = {
363 {.compatible = "rockchip,rk3288-dp",},
364 {}
365};
366MODULE_DEVICE_TABLE(of, rockchip_dp_dt_ids);
367
368static struct platform_driver rockchip_dp_driver = {
369 .probe = rockchip_dp_probe,
370 .remove = rockchip_dp_remove,
371 .driver = {
372 .name = "rockchip-dp",
373 .owner = THIS_MODULE,
374 .pm = &rockchip_dp_pm_ops,
375 .of_match_table = of_match_ptr(rockchip_dp_dt_ids),
376 },
377};
378
379module_platform_driver(rockchip_dp_driver);
380
381MODULE_AUTHOR("Yakir Yang <ykk@rock-chips.com>");
382MODULE_AUTHOR("Jeff chen <jeff.chen@rock-chips.com>");
383MODULE_DESCRIPTION("Rockchip Specific Analogix-DP Driver Extension");
384MODULE_LICENSE("GPL v2");
diff --git a/include/drm/bridge/analogix_dp.h b/include/drm/bridge/analogix_dp.h
new file mode 100644
index 000000000000..25afb31f0389
--- /dev/null
+++ b/include/drm/bridge/analogix_dp.h
@@ -0,0 +1,41 @@
1/*
2 * Analogix DP (Display Port) Core interface driver.
3 *
4 * Copyright (C) 2015 Rockchip Electronics Co., Ltd.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11#ifndef _ANALOGIX_DP_H_
12#define _ANALOGIX_DP_H_
13
14#include <drm/drm_crtc.h>
15
16enum analogix_dp_devtype {
17 EXYNOS_DP,
18 RK3288_DP,
19};
20
21struct analogix_dp_plat_data {
22 enum analogix_dp_devtype dev_type;
23 struct drm_panel *panel;
24 struct drm_encoder *encoder;
25 struct drm_connector *connector;
26
27 int (*power_on)(struct analogix_dp_plat_data *);
28 int (*power_off)(struct analogix_dp_plat_data *);
29 int (*attach)(struct analogix_dp_plat_data *, struct drm_bridge *,
30 struct drm_connector *);
31 int (*get_modes)(struct analogix_dp_plat_data *);
32};
33
34int analogix_dp_resume(struct device *dev);
35int analogix_dp_suspend(struct device *dev);
36
37int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev,
38 struct analogix_dp_plat_data *plat_data);
39void analogix_dp_unbind(struct device *dev, struct device *master, void *data);
40
41#endif /* _ANALOGIX_DP_H_ */