diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-08 12:52:16 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-08 12:52:16 -0400 |
commit | e9f37d3a8d126e73f5737ef548cdf6f618e295e4 (patch) | |
tree | 831eb4952637828a7bbafa361185e0ca57aa86ed /drivers/video | |
parent | 5fb6b953bb7aa86a9c8ea760934982cedc45c52b (diff) | |
parent | c39b06951f1dc2e384650288676c5b7dcc0ec92c (diff) |
Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux
Pull drm updates from Dave Airlie:
"Highlights:
- drm:
Generic display port aux features, primary plane support, drm
master management fixes, logging cleanups, enforced locking checks
(instead of docs), documentation improvements, minor number
handling cleanup, pseudofs for shared inodes.
- ttm:
add ability to allocate from both ends
- i915:
broadwell features, power domain and runtime pm, per-process
address space infrastructure (not enabled)
- msm:
power management, hdmi audio support
- nouveau:
ongoing GPU fault recovery, initial maxwell support, random fixes
- exynos:
refactored driver to clean up a lot of abstraction, DP support
moved into drm, LVDS bridge support added, parallel panel support
- gma500:
SGX MMU support, SGX irq handling, asle irq work fixes
- radeon:
video engine bringup, ring handling fixes, use dp aux helpers
- vmwgfx:
add rendernode support"
* 'drm-next' of git://people.freedesktop.org/~airlied/linux: (849 commits)
DRM: armada: fix corruption while loading cursors
drm/dp_helper: don't return EPROTO for defers (v2)
drm/bridge: export ptn3460_init function
drm/exynos: remove MODULE_DEVICE_TABLE definitions
ARM: dts: exynos4412-trats2: enable exynos/fimd node
ARM: dts: exynos4210-trats: enable exynos/fimd node
ARM: dts: exynos4412-trats2: add panel node
ARM: dts: exynos4210-trats: add panel node
ARM: dts: exynos4: add MIPI DSI Master node
drm/panel: add S6E8AA0 driver
ARM: dts: exynos4210-universal_c210: add proper panel node
drm/panel: add ld9040 driver
panel/ld9040: add DT bindings
panel/s6e8aa0: add DT bindings
drm/exynos: add DSIM driver
exynos/dsim: add DT bindings
drm/exynos: disallow fbdev initialization if no device is connected
drm/mipi_dsi: create dsi devices only for nodes with reg property
drm/mipi_dsi: add flags to DSI messages
Skip intel_crt_init for Dell XPS 8700
...
Diffstat (limited to 'drivers/video')
-rw-r--r-- | drivers/video/exynos/Kconfig | 7 | ||||
-rw-r--r-- | drivers/video/exynos/Makefile | 1 | ||||
-rw-r--r-- | drivers/video/exynos/exynos_dp_core.c | 1156 | ||||
-rw-r--r-- | drivers/video/exynos/exynos_dp_core.h | 320 | ||||
-rw-r--r-- | drivers/video/exynos/exynos_dp_reg.c | 1243 | ||||
-rw-r--r-- | drivers/video/exynos/exynos_dp_reg.h | 366 |
6 files changed, 0 insertions, 3093 deletions
diff --git a/drivers/video/exynos/Kconfig b/drivers/video/exynos/Kconfig index eb6f2b059821..fcf2d48ac6d1 100644 --- a/drivers/video/exynos/Kconfig +++ b/drivers/video/exynos/Kconfig | |||
@@ -29,11 +29,4 @@ config EXYNOS_LCD_S6E8AX0 | |||
29 | If you have an S6E8AX0 MIPI AMOLED LCD Panel, say Y to enable its | 29 | If you have an S6E8AX0 MIPI AMOLED LCD Panel, say Y to enable its |
30 | LCD control driver. | 30 | LCD control driver. |
31 | 31 | ||
32 | config EXYNOS_DP | ||
33 | bool "EXYNOS DP driver support" | ||
34 | depends on ARCH_EXYNOS | ||
35 | default n | ||
36 | help | ||
37 | This enables support for DP device. | ||
38 | |||
39 | endif # EXYNOS_VIDEO | 32 | endif # EXYNOS_VIDEO |
diff --git a/drivers/video/exynos/Makefile b/drivers/video/exynos/Makefile index ec7772e452a9..b5b1bd228abb 100644 --- a/drivers/video/exynos/Makefile +++ b/drivers/video/exynos/Makefile | |||
@@ -5,4 +5,3 @@ | |||
5 | obj-$(CONFIG_EXYNOS_MIPI_DSI) += exynos_mipi_dsi.o exynos_mipi_dsi_common.o \ | 5 | obj-$(CONFIG_EXYNOS_MIPI_DSI) += exynos_mipi_dsi.o exynos_mipi_dsi_common.o \ |
6 | exynos_mipi_dsi_lowlevel.o | 6 | exynos_mipi_dsi_lowlevel.o |
7 | obj-$(CONFIG_EXYNOS_LCD_S6E8AX0) += s6e8ax0.o | 7 | obj-$(CONFIG_EXYNOS_LCD_S6E8AX0) += s6e8ax0.o |
8 | obj-$(CONFIG_EXYNOS_DP) += exynos_dp_core.o exynos_dp_reg.o | ||
diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c deleted file mode 100644 index 5e1a71580051..000000000000 --- a/drivers/video/exynos/exynos_dp_core.c +++ /dev/null | |||
@@ -1,1156 +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/slab.h> | ||
16 | #include <linux/err.h> | ||
17 | #include <linux/clk.h> | ||
18 | #include <linux/io.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | #include <linux/delay.h> | ||
21 | #include <linux/of.h> | ||
22 | #include <linux/phy/phy.h> | ||
23 | |||
24 | #include "exynos_dp_core.h" | ||
25 | |||
26 | static int exynos_dp_init_dp(struct exynos_dp_device *dp) | ||
27 | { | ||
28 | exynos_dp_reset(dp); | ||
29 | |||
30 | exynos_dp_swreset(dp); | ||
31 | |||
32 | exynos_dp_init_analog_param(dp); | ||
33 | exynos_dp_init_interrupt(dp); | ||
34 | |||
35 | /* SW defined function Normal operation */ | ||
36 | exynos_dp_enable_sw_function(dp); | ||
37 | |||
38 | exynos_dp_config_interrupt(dp); | ||
39 | exynos_dp_init_analog_func(dp); | ||
40 | |||
41 | exynos_dp_init_hpd(dp); | ||
42 | exynos_dp_init_aux(dp); | ||
43 | |||
44 | return 0; | ||
45 | } | ||
46 | |||
47 | static int exynos_dp_detect_hpd(struct exynos_dp_device *dp) | ||
48 | { | ||
49 | int timeout_loop = 0; | ||
50 | |||
51 | while (exynos_dp_get_plug_in_status(dp) != 0) { | ||
52 | timeout_loop++; | ||
53 | if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) { | ||
54 | dev_err(dp->dev, "failed to get hpd plug status\n"); | ||
55 | return -ETIMEDOUT; | ||
56 | } | ||
57 | usleep_range(10, 11); | ||
58 | } | ||
59 | |||
60 | return 0; | ||
61 | } | ||
62 | |||
63 | static unsigned char exynos_dp_calc_edid_check_sum(unsigned char *edid_data) | ||
64 | { | ||
65 | int i; | ||
66 | unsigned char sum = 0; | ||
67 | |||
68 | for (i = 0; i < EDID_BLOCK_LENGTH; i++) | ||
69 | sum = sum + edid_data[i]; | ||
70 | |||
71 | return sum; | ||
72 | } | ||
73 | |||
74 | static int exynos_dp_read_edid(struct exynos_dp_device *dp) | ||
75 | { | ||
76 | unsigned char edid[EDID_BLOCK_LENGTH * 2]; | ||
77 | unsigned int extend_block = 0; | ||
78 | unsigned char sum; | ||
79 | unsigned char test_vector; | ||
80 | int retval; | ||
81 | |||
82 | /* | ||
83 | * EDID device address is 0x50. | ||
84 | * However, if necessary, you must have set upper address | ||
85 | * into E-EDID in I2C device, 0x30. | ||
86 | */ | ||
87 | |||
88 | /* Read Extension Flag, Number of 128-byte EDID extension blocks */ | ||
89 | retval = exynos_dp_read_byte_from_i2c(dp, I2C_EDID_DEVICE_ADDR, | ||
90 | EDID_EXTENSION_FLAG, | ||
91 | &extend_block); | ||
92 | if (retval) | ||
93 | return retval; | ||
94 | |||
95 | if (extend_block > 0) { | ||
96 | dev_dbg(dp->dev, "EDID data includes a single extension!\n"); | ||
97 | |||
98 | /* Read EDID data */ | ||
99 | retval = exynos_dp_read_bytes_from_i2c(dp, I2C_EDID_DEVICE_ADDR, | ||
100 | EDID_HEADER_PATTERN, | ||
101 | EDID_BLOCK_LENGTH, | ||
102 | &edid[EDID_HEADER_PATTERN]); | ||
103 | if (retval != 0) { | ||
104 | dev_err(dp->dev, "EDID Read failed!\n"); | ||
105 | return -EIO; | ||
106 | } | ||
107 | sum = exynos_dp_calc_edid_check_sum(edid); | ||
108 | if (sum != 0) { | ||
109 | dev_err(dp->dev, "EDID bad checksum!\n"); | ||
110 | return -EIO; | ||
111 | } | ||
112 | |||
113 | /* Read additional EDID data */ | ||
114 | retval = exynos_dp_read_bytes_from_i2c(dp, | ||
115 | I2C_EDID_DEVICE_ADDR, | ||
116 | EDID_BLOCK_LENGTH, | ||
117 | EDID_BLOCK_LENGTH, | ||
118 | &edid[EDID_BLOCK_LENGTH]); | ||
119 | if (retval != 0) { | ||
120 | dev_err(dp->dev, "EDID Read failed!\n"); | ||
121 | return -EIO; | ||
122 | } | ||
123 | sum = exynos_dp_calc_edid_check_sum(&edid[EDID_BLOCK_LENGTH]); | ||
124 | if (sum != 0) { | ||
125 | dev_err(dp->dev, "EDID bad checksum!\n"); | ||
126 | return -EIO; | ||
127 | } | ||
128 | |||
129 | exynos_dp_read_byte_from_dpcd(dp, DPCD_ADDR_TEST_REQUEST, | ||
130 | &test_vector); | ||
131 | if (test_vector & DPCD_TEST_EDID_READ) { | ||
132 | exynos_dp_write_byte_to_dpcd(dp, | ||
133 | DPCD_ADDR_TEST_EDID_CHECKSUM, | ||
134 | edid[EDID_BLOCK_LENGTH + EDID_CHECKSUM]); | ||
135 | exynos_dp_write_byte_to_dpcd(dp, | ||
136 | DPCD_ADDR_TEST_RESPONSE, | ||
137 | DPCD_TEST_EDID_CHECKSUM_WRITE); | ||
138 | } | ||
139 | } else { | ||
140 | dev_info(dp->dev, "EDID data does not include any extensions.\n"); | ||
141 | |||
142 | /* Read EDID data */ | ||
143 | retval = exynos_dp_read_bytes_from_i2c(dp, | ||
144 | I2C_EDID_DEVICE_ADDR, | ||
145 | EDID_HEADER_PATTERN, | ||
146 | EDID_BLOCK_LENGTH, | ||
147 | &edid[EDID_HEADER_PATTERN]); | ||
148 | if (retval != 0) { | ||
149 | dev_err(dp->dev, "EDID Read failed!\n"); | ||
150 | return -EIO; | ||
151 | } | ||
152 | sum = exynos_dp_calc_edid_check_sum(edid); | ||
153 | if (sum != 0) { | ||
154 | dev_err(dp->dev, "EDID bad checksum!\n"); | ||
155 | return -EIO; | ||
156 | } | ||
157 | |||
158 | exynos_dp_read_byte_from_dpcd(dp, | ||
159 | DPCD_ADDR_TEST_REQUEST, | ||
160 | &test_vector); | ||
161 | if (test_vector & DPCD_TEST_EDID_READ) { | ||
162 | exynos_dp_write_byte_to_dpcd(dp, | ||
163 | DPCD_ADDR_TEST_EDID_CHECKSUM, | ||
164 | edid[EDID_CHECKSUM]); | ||
165 | exynos_dp_write_byte_to_dpcd(dp, | ||
166 | DPCD_ADDR_TEST_RESPONSE, | ||
167 | DPCD_TEST_EDID_CHECKSUM_WRITE); | ||
168 | } | ||
169 | } | ||
170 | |||
171 | dev_err(dp->dev, "EDID Read success!\n"); | ||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | static int exynos_dp_handle_edid(struct exynos_dp_device *dp) | ||
176 | { | ||
177 | u8 buf[12]; | ||
178 | int i; | ||
179 | int retval; | ||
180 | |||
181 | /* Read DPCD DPCD_ADDR_DPCD_REV~RECEIVE_PORT1_CAP_1 */ | ||
182 | retval = exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_DPCD_REV, | ||
183 | 12, buf); | ||
184 | if (retval) | ||
185 | return retval; | ||
186 | |||
187 | /* Read EDID */ | ||
188 | for (i = 0; i < 3; i++) { | ||
189 | retval = exynos_dp_read_edid(dp); | ||
190 | if (!retval) | ||
191 | break; | ||
192 | } | ||
193 | |||
194 | return retval; | ||
195 | } | ||
196 | |||
197 | static void exynos_dp_enable_rx_to_enhanced_mode(struct exynos_dp_device *dp, | ||
198 | bool enable) | ||
199 | { | ||
200 | u8 data; | ||
201 | |||
202 | exynos_dp_read_byte_from_dpcd(dp, DPCD_ADDR_LANE_COUNT_SET, &data); | ||
203 | |||
204 | if (enable) | ||
205 | exynos_dp_write_byte_to_dpcd(dp, DPCD_ADDR_LANE_COUNT_SET, | ||
206 | DPCD_ENHANCED_FRAME_EN | | ||
207 | DPCD_LANE_COUNT_SET(data)); | ||
208 | else | ||
209 | exynos_dp_write_byte_to_dpcd(dp, DPCD_ADDR_LANE_COUNT_SET, | ||
210 | DPCD_LANE_COUNT_SET(data)); | ||
211 | } | ||
212 | |||
213 | static int exynos_dp_is_enhanced_mode_available(struct exynos_dp_device *dp) | ||
214 | { | ||
215 | u8 data; | ||
216 | int retval; | ||
217 | |||
218 | exynos_dp_read_byte_from_dpcd(dp, DPCD_ADDR_MAX_LANE_COUNT, &data); | ||
219 | retval = DPCD_ENHANCED_FRAME_CAP(data); | ||
220 | |||
221 | return retval; | ||
222 | } | ||
223 | |||
224 | static void exynos_dp_set_enhanced_mode(struct exynos_dp_device *dp) | ||
225 | { | ||
226 | u8 data; | ||
227 | |||
228 | data = exynos_dp_is_enhanced_mode_available(dp); | ||
229 | exynos_dp_enable_rx_to_enhanced_mode(dp, data); | ||
230 | exynos_dp_enable_enhanced_mode(dp, data); | ||
231 | } | ||
232 | |||
233 | static void exynos_dp_training_pattern_dis(struct exynos_dp_device *dp) | ||
234 | { | ||
235 | exynos_dp_set_training_pattern(dp, DP_NONE); | ||
236 | |||
237 | exynos_dp_write_byte_to_dpcd(dp, | ||
238 | DPCD_ADDR_TRAINING_PATTERN_SET, | ||
239 | DPCD_TRAINING_PATTERN_DISABLED); | ||
240 | } | ||
241 | |||
242 | static void exynos_dp_set_lane_lane_pre_emphasis(struct exynos_dp_device *dp, | ||
243 | int pre_emphasis, int lane) | ||
244 | { | ||
245 | switch (lane) { | ||
246 | case 0: | ||
247 | exynos_dp_set_lane0_pre_emphasis(dp, pre_emphasis); | ||
248 | break; | ||
249 | case 1: | ||
250 | exynos_dp_set_lane1_pre_emphasis(dp, pre_emphasis); | ||
251 | break; | ||
252 | |||
253 | case 2: | ||
254 | exynos_dp_set_lane2_pre_emphasis(dp, pre_emphasis); | ||
255 | break; | ||
256 | |||
257 | case 3: | ||
258 | exynos_dp_set_lane3_pre_emphasis(dp, pre_emphasis); | ||
259 | break; | ||
260 | } | ||
261 | } | ||
262 | |||
263 | static int exynos_dp_link_start(struct exynos_dp_device *dp) | ||
264 | { | ||
265 | u8 buf[4]; | ||
266 | int lane, lane_count, pll_tries, retval; | ||
267 | |||
268 | lane_count = dp->link_train.lane_count; | ||
269 | |||
270 | dp->link_train.lt_state = CLOCK_RECOVERY; | ||
271 | dp->link_train.eq_loop = 0; | ||
272 | |||
273 | for (lane = 0; lane < lane_count; lane++) | ||
274 | dp->link_train.cr_loop[lane] = 0; | ||
275 | |||
276 | /* Set link rate and count as you want to establish*/ | ||
277 | exynos_dp_set_link_bandwidth(dp, dp->link_train.link_rate); | ||
278 | exynos_dp_set_lane_count(dp, dp->link_train.lane_count); | ||
279 | |||
280 | /* Setup RX configuration */ | ||
281 | buf[0] = dp->link_train.link_rate; | ||
282 | buf[1] = dp->link_train.lane_count; | ||
283 | retval = exynos_dp_write_bytes_to_dpcd(dp, DPCD_ADDR_LINK_BW_SET, | ||
284 | 2, buf); | ||
285 | if (retval) | ||
286 | return retval; | ||
287 | |||
288 | /* Set TX pre-emphasis to minimum */ | ||
289 | for (lane = 0; lane < lane_count; lane++) | ||
290 | exynos_dp_set_lane_lane_pre_emphasis(dp, | ||
291 | PRE_EMPHASIS_LEVEL_0, lane); | ||
292 | |||
293 | /* Wait for PLL lock */ | ||
294 | pll_tries = 0; | ||
295 | while (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) { | ||
296 | if (pll_tries == DP_TIMEOUT_LOOP_COUNT) { | ||
297 | dev_err(dp->dev, "Wait for PLL lock timed out\n"); | ||
298 | return -ETIMEDOUT; | ||
299 | } | ||
300 | |||
301 | pll_tries++; | ||
302 | usleep_range(90, 120); | ||
303 | } | ||
304 | |||
305 | /* Set training pattern 1 */ | ||
306 | exynos_dp_set_training_pattern(dp, TRAINING_PTN1); | ||
307 | |||
308 | /* Set RX training pattern */ | ||
309 | retval = exynos_dp_write_byte_to_dpcd(dp, | ||
310 | DPCD_ADDR_TRAINING_PATTERN_SET, | ||
311 | DPCD_SCRAMBLING_DISABLED | DPCD_TRAINING_PATTERN_1); | ||
312 | if (retval) | ||
313 | return retval; | ||
314 | |||
315 | for (lane = 0; lane < lane_count; lane++) | ||
316 | buf[lane] = DPCD_PRE_EMPHASIS_PATTERN2_LEVEL0 | | ||
317 | DPCD_VOLTAGE_SWING_PATTERN1_LEVEL0; | ||
318 | |||
319 | retval = exynos_dp_write_bytes_to_dpcd(dp, DPCD_ADDR_TRAINING_LANE0_SET, | ||
320 | lane_count, buf); | ||
321 | |||
322 | return retval; | ||
323 | } | ||
324 | |||
325 | static unsigned char exynos_dp_get_lane_status(u8 link_status[2], int lane) | ||
326 | { | ||
327 | int shift = (lane & 1) * 4; | ||
328 | u8 link_value = link_status[lane>>1]; | ||
329 | |||
330 | return (link_value >> shift) & 0xf; | ||
331 | } | ||
332 | |||
333 | static int exynos_dp_clock_recovery_ok(u8 link_status[2], int lane_count) | ||
334 | { | ||
335 | int lane; | ||
336 | u8 lane_status; | ||
337 | |||
338 | for (lane = 0; lane < lane_count; lane++) { | ||
339 | lane_status = exynos_dp_get_lane_status(link_status, lane); | ||
340 | if ((lane_status & DPCD_LANE_CR_DONE) == 0) | ||
341 | return -EINVAL; | ||
342 | } | ||
343 | return 0; | ||
344 | } | ||
345 | |||
346 | static int exynos_dp_channel_eq_ok(u8 link_status[2], u8 link_align, | ||
347 | int lane_count) | ||
348 | { | ||
349 | int lane; | ||
350 | u8 lane_status; | ||
351 | |||
352 | if ((link_align & DPCD_INTERLANE_ALIGN_DONE) == 0) | ||
353 | return -EINVAL; | ||
354 | |||
355 | for (lane = 0; lane < lane_count; lane++) { | ||
356 | lane_status = exynos_dp_get_lane_status(link_status, lane); | ||
357 | lane_status &= DPCD_CHANNEL_EQ_BITS; | ||
358 | if (lane_status != DPCD_CHANNEL_EQ_BITS) | ||
359 | return -EINVAL; | ||
360 | } | ||
361 | |||
362 | return 0; | ||
363 | } | ||
364 | |||
365 | static unsigned char exynos_dp_get_adjust_request_voltage(u8 adjust_request[2], | ||
366 | int lane) | ||
367 | { | ||
368 | int shift = (lane & 1) * 4; | ||
369 | u8 link_value = adjust_request[lane>>1]; | ||
370 | |||
371 | return (link_value >> shift) & 0x3; | ||
372 | } | ||
373 | |||
374 | static unsigned char exynos_dp_get_adjust_request_pre_emphasis( | ||
375 | u8 adjust_request[2], | ||
376 | int lane) | ||
377 | { | ||
378 | int shift = (lane & 1) * 4; | ||
379 | u8 link_value = adjust_request[lane>>1]; | ||
380 | |||
381 | return ((link_value >> shift) & 0xc) >> 2; | ||
382 | } | ||
383 | |||
384 | static void exynos_dp_set_lane_link_training(struct exynos_dp_device *dp, | ||
385 | u8 training_lane_set, int lane) | ||
386 | { | ||
387 | switch (lane) { | ||
388 | case 0: | ||
389 | exynos_dp_set_lane0_link_training(dp, training_lane_set); | ||
390 | break; | ||
391 | case 1: | ||
392 | exynos_dp_set_lane1_link_training(dp, training_lane_set); | ||
393 | break; | ||
394 | |||
395 | case 2: | ||
396 | exynos_dp_set_lane2_link_training(dp, training_lane_set); | ||
397 | break; | ||
398 | |||
399 | case 3: | ||
400 | exynos_dp_set_lane3_link_training(dp, training_lane_set); | ||
401 | break; | ||
402 | } | ||
403 | } | ||
404 | |||
405 | static unsigned int exynos_dp_get_lane_link_training( | ||
406 | struct exynos_dp_device *dp, | ||
407 | int lane) | ||
408 | { | ||
409 | u32 reg; | ||
410 | |||
411 | switch (lane) { | ||
412 | case 0: | ||
413 | reg = exynos_dp_get_lane0_link_training(dp); | ||
414 | break; | ||
415 | case 1: | ||
416 | reg = exynos_dp_get_lane1_link_training(dp); | ||
417 | break; | ||
418 | case 2: | ||
419 | reg = exynos_dp_get_lane2_link_training(dp); | ||
420 | break; | ||
421 | case 3: | ||
422 | reg = exynos_dp_get_lane3_link_training(dp); | ||
423 | break; | ||
424 | default: | ||
425 | WARN_ON(1); | ||
426 | return 0; | ||
427 | } | ||
428 | |||
429 | return reg; | ||
430 | } | ||
431 | |||
432 | static void exynos_dp_reduce_link_rate(struct exynos_dp_device *dp) | ||
433 | { | ||
434 | exynos_dp_training_pattern_dis(dp); | ||
435 | exynos_dp_set_enhanced_mode(dp); | ||
436 | |||
437 | dp->link_train.lt_state = FAILED; | ||
438 | } | ||
439 | |||
440 | static void exynos_dp_get_adjust_training_lane(struct exynos_dp_device *dp, | ||
441 | u8 adjust_request[2]) | ||
442 | { | ||
443 | int lane, lane_count; | ||
444 | u8 voltage_swing, pre_emphasis, training_lane; | ||
445 | |||
446 | lane_count = dp->link_train.lane_count; | ||
447 | for (lane = 0; lane < lane_count; lane++) { | ||
448 | voltage_swing = exynos_dp_get_adjust_request_voltage( | ||
449 | adjust_request, lane); | ||
450 | pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis( | ||
451 | adjust_request, lane); | ||
452 | training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) | | ||
453 | DPCD_PRE_EMPHASIS_SET(pre_emphasis); | ||
454 | |||
455 | if (voltage_swing == VOLTAGE_LEVEL_3) | ||
456 | training_lane |= DPCD_MAX_SWING_REACHED; | ||
457 | if (pre_emphasis == PRE_EMPHASIS_LEVEL_3) | ||
458 | training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED; | ||
459 | |||
460 | dp->link_train.training_lane[lane] = training_lane; | ||
461 | } | ||
462 | } | ||
463 | |||
464 | static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp) | ||
465 | { | ||
466 | int lane, lane_count, retval; | ||
467 | u8 voltage_swing, pre_emphasis, training_lane; | ||
468 | u8 link_status[2], adjust_request[2]; | ||
469 | |||
470 | usleep_range(100, 101); | ||
471 | |||
472 | lane_count = dp->link_train.lane_count; | ||
473 | |||
474 | retval = exynos_dp_read_bytes_from_dpcd(dp, | ||
475 | DPCD_ADDR_LANE0_1_STATUS, 2, link_status); | ||
476 | if (retval) | ||
477 | return retval; | ||
478 | |||
479 | retval = exynos_dp_read_bytes_from_dpcd(dp, | ||
480 | DPCD_ADDR_ADJUST_REQUEST_LANE0_1, 2, adjust_request); | ||
481 | if (retval) | ||
482 | return retval; | ||
483 | |||
484 | if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) { | ||
485 | /* set training pattern 2 for EQ */ | ||
486 | exynos_dp_set_training_pattern(dp, TRAINING_PTN2); | ||
487 | |||
488 | retval = exynos_dp_write_byte_to_dpcd(dp, | ||
489 | DPCD_ADDR_TRAINING_PATTERN_SET, | ||
490 | DPCD_SCRAMBLING_DISABLED | | ||
491 | DPCD_TRAINING_PATTERN_2); | ||
492 | if (retval) | ||
493 | return retval; | ||
494 | |||
495 | dev_info(dp->dev, "Link Training Clock Recovery success\n"); | ||
496 | dp->link_train.lt_state = EQUALIZER_TRAINING; | ||
497 | } else { | ||
498 | for (lane = 0; lane < lane_count; lane++) { | ||
499 | training_lane = exynos_dp_get_lane_link_training( | ||
500 | dp, lane); | ||
501 | voltage_swing = exynos_dp_get_adjust_request_voltage( | ||
502 | adjust_request, lane); | ||
503 | pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis( | ||
504 | adjust_request, lane); | ||
505 | |||
506 | if (DPCD_VOLTAGE_SWING_GET(training_lane) == | ||
507 | voltage_swing && | ||
508 | DPCD_PRE_EMPHASIS_GET(training_lane) == | ||
509 | pre_emphasis) | ||
510 | dp->link_train.cr_loop[lane]++; | ||
511 | |||
512 | if (dp->link_train.cr_loop[lane] == MAX_CR_LOOP || | ||
513 | voltage_swing == VOLTAGE_LEVEL_3 || | ||
514 | pre_emphasis == PRE_EMPHASIS_LEVEL_3) { | ||
515 | dev_err(dp->dev, "CR Max reached (%d,%d,%d)\n", | ||
516 | dp->link_train.cr_loop[lane], | ||
517 | voltage_swing, pre_emphasis); | ||
518 | exynos_dp_reduce_link_rate(dp); | ||
519 | return -EIO; | ||
520 | } | ||
521 | } | ||
522 | } | ||
523 | |||
524 | exynos_dp_get_adjust_training_lane(dp, adjust_request); | ||
525 | |||
526 | for (lane = 0; lane < lane_count; lane++) | ||
527 | exynos_dp_set_lane_link_training(dp, | ||
528 | dp->link_train.training_lane[lane], lane); | ||
529 | |||
530 | retval = exynos_dp_write_bytes_to_dpcd(dp, | ||
531 | DPCD_ADDR_TRAINING_LANE0_SET, lane_count, | ||
532 | dp->link_train.training_lane); | ||
533 | if (retval) | ||
534 | return retval; | ||
535 | |||
536 | return retval; | ||
537 | } | ||
538 | |||
539 | static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp) | ||
540 | { | ||
541 | int lane, lane_count, retval; | ||
542 | u32 reg; | ||
543 | u8 link_align, link_status[2], adjust_request[2]; | ||
544 | |||
545 | usleep_range(400, 401); | ||
546 | |||
547 | lane_count = dp->link_train.lane_count; | ||
548 | |||
549 | retval = exynos_dp_read_bytes_from_dpcd(dp, | ||
550 | DPCD_ADDR_LANE0_1_STATUS, 2, link_status); | ||
551 | if (retval) | ||
552 | return retval; | ||
553 | |||
554 | if (exynos_dp_clock_recovery_ok(link_status, lane_count)) { | ||
555 | exynos_dp_reduce_link_rate(dp); | ||
556 | return -EIO; | ||
557 | } | ||
558 | |||
559 | retval = exynos_dp_read_bytes_from_dpcd(dp, | ||
560 | DPCD_ADDR_ADJUST_REQUEST_LANE0_1, 2, adjust_request); | ||
561 | if (retval) | ||
562 | return retval; | ||
563 | |||
564 | retval = exynos_dp_read_byte_from_dpcd(dp, | ||
565 | DPCD_ADDR_LANE_ALIGN_STATUS_UPDATED, &link_align); | ||
566 | if (retval) | ||
567 | return retval; | ||
568 | |||
569 | exynos_dp_get_adjust_training_lane(dp, adjust_request); | ||
570 | |||
571 | if (!exynos_dp_channel_eq_ok(link_status, link_align, lane_count)) { | ||
572 | /* traing pattern Set to Normal */ | ||
573 | exynos_dp_training_pattern_dis(dp); | ||
574 | |||
575 | dev_info(dp->dev, "Link Training success!\n"); | ||
576 | |||
577 | exynos_dp_get_link_bandwidth(dp, ®); | ||
578 | dp->link_train.link_rate = reg; | ||
579 | dev_dbg(dp->dev, "final bandwidth = %.2x\n", | ||
580 | dp->link_train.link_rate); | ||
581 | |||
582 | exynos_dp_get_lane_count(dp, ®); | ||
583 | dp->link_train.lane_count = reg; | ||
584 | dev_dbg(dp->dev, "final lane count = %.2x\n", | ||
585 | dp->link_train.lane_count); | ||
586 | |||
587 | /* set enhanced mode if available */ | ||
588 | exynos_dp_set_enhanced_mode(dp); | ||
589 | dp->link_train.lt_state = FINISHED; | ||
590 | |||
591 | return 0; | ||
592 | } | ||
593 | |||
594 | /* not all locked */ | ||
595 | dp->link_train.eq_loop++; | ||
596 | |||
597 | if (dp->link_train.eq_loop > MAX_EQ_LOOP) { | ||
598 | dev_err(dp->dev, "EQ Max loop\n"); | ||
599 | exynos_dp_reduce_link_rate(dp); | ||
600 | return -EIO; | ||
601 | } | ||
602 | |||
603 | for (lane = 0; lane < lane_count; lane++) | ||
604 | exynos_dp_set_lane_link_training(dp, | ||
605 | dp->link_train.training_lane[lane], lane); | ||
606 | |||
607 | retval = exynos_dp_write_bytes_to_dpcd(dp, DPCD_ADDR_TRAINING_LANE0_SET, | ||
608 | lane_count, dp->link_train.training_lane); | ||
609 | |||
610 | return retval; | ||
611 | } | ||
612 | |||
613 | static void exynos_dp_get_max_rx_bandwidth(struct exynos_dp_device *dp, | ||
614 | u8 *bandwidth) | ||
615 | { | ||
616 | u8 data; | ||
617 | |||
618 | /* | ||
619 | * For DP rev.1.1, Maximum link rate of Main Link lanes | ||
620 | * 0x06 = 1.62 Gbps, 0x0a = 2.7 Gbps | ||
621 | */ | ||
622 | exynos_dp_read_byte_from_dpcd(dp, DPCD_ADDR_MAX_LINK_RATE, &data); | ||
623 | *bandwidth = data; | ||
624 | } | ||
625 | |||
626 | static void exynos_dp_get_max_rx_lane_count(struct exynos_dp_device *dp, | ||
627 | u8 *lane_count) | ||
628 | { | ||
629 | u8 data; | ||
630 | |||
631 | /* | ||
632 | * For DP rev.1.1, Maximum number of Main Link lanes | ||
633 | * 0x01 = 1 lane, 0x02 = 2 lanes, 0x04 = 4 lanes | ||
634 | */ | ||
635 | exynos_dp_read_byte_from_dpcd(dp, DPCD_ADDR_MAX_LANE_COUNT, &data); | ||
636 | *lane_count = DPCD_MAX_LANE_COUNT(data); | ||
637 | } | ||
638 | |||
639 | static void exynos_dp_init_training(struct exynos_dp_device *dp, | ||
640 | enum link_lane_count_type max_lane, | ||
641 | enum link_rate_type max_rate) | ||
642 | { | ||
643 | /* | ||
644 | * MACRO_RST must be applied after the PLL_LOCK to avoid | ||
645 | * the DP inter pair skew issue for at least 10 us | ||
646 | */ | ||
647 | exynos_dp_reset_macro(dp); | ||
648 | |||
649 | /* Initialize by reading RX's DPCD */ | ||
650 | exynos_dp_get_max_rx_bandwidth(dp, &dp->link_train.link_rate); | ||
651 | exynos_dp_get_max_rx_lane_count(dp, &dp->link_train.lane_count); | ||
652 | |||
653 | if ((dp->link_train.link_rate != LINK_RATE_1_62GBPS) && | ||
654 | (dp->link_train.link_rate != LINK_RATE_2_70GBPS)) { | ||
655 | dev_err(dp->dev, "Rx Max Link Rate is abnormal :%x !\n", | ||
656 | dp->link_train.link_rate); | ||
657 | dp->link_train.link_rate = LINK_RATE_1_62GBPS; | ||
658 | } | ||
659 | |||
660 | if (dp->link_train.lane_count == 0) { | ||
661 | dev_err(dp->dev, "Rx Max Lane count is abnormal :%x !\n", | ||
662 | dp->link_train.lane_count); | ||
663 | dp->link_train.lane_count = (u8)LANE_COUNT1; | ||
664 | } | ||
665 | |||
666 | /* Setup TX lane count & rate */ | ||
667 | if (dp->link_train.lane_count > max_lane) | ||
668 | dp->link_train.lane_count = max_lane; | ||
669 | if (dp->link_train.link_rate > max_rate) | ||
670 | dp->link_train.link_rate = max_rate; | ||
671 | |||
672 | /* All DP analog module power up */ | ||
673 | exynos_dp_set_analog_power_down(dp, POWER_ALL, 0); | ||
674 | } | ||
675 | |||
676 | static int exynos_dp_sw_link_training(struct exynos_dp_device *dp) | ||
677 | { | ||
678 | int retval = 0, training_finished = 0; | ||
679 | |||
680 | dp->link_train.lt_state = START; | ||
681 | |||
682 | /* Process here */ | ||
683 | while (!retval && !training_finished) { | ||
684 | switch (dp->link_train.lt_state) { | ||
685 | case START: | ||
686 | retval = exynos_dp_link_start(dp); | ||
687 | if (retval) | ||
688 | dev_err(dp->dev, "LT link start failed!\n"); | ||
689 | break; | ||
690 | case CLOCK_RECOVERY: | ||
691 | retval = exynos_dp_process_clock_recovery(dp); | ||
692 | if (retval) | ||
693 | dev_err(dp->dev, "LT CR failed!\n"); | ||
694 | break; | ||
695 | case EQUALIZER_TRAINING: | ||
696 | retval = exynos_dp_process_equalizer_training(dp); | ||
697 | if (retval) | ||
698 | dev_err(dp->dev, "LT EQ failed!\n"); | ||
699 | break; | ||
700 | case FINISHED: | ||
701 | training_finished = 1; | ||
702 | break; | ||
703 | case FAILED: | ||
704 | return -EREMOTEIO; | ||
705 | } | ||
706 | } | ||
707 | if (retval) | ||
708 | dev_err(dp->dev, "eDP link training failed (%d)\n", retval); | ||
709 | |||
710 | return retval; | ||
711 | } | ||
712 | |||
713 | static int exynos_dp_set_link_train(struct exynos_dp_device *dp, | ||
714 | u32 count, | ||
715 | u32 bwtype) | ||
716 | { | ||
717 | int i; | ||
718 | int retval; | ||
719 | |||
720 | for (i = 0; i < DP_TIMEOUT_LOOP_COUNT; i++) { | ||
721 | exynos_dp_init_training(dp, count, bwtype); | ||
722 | retval = exynos_dp_sw_link_training(dp); | ||
723 | if (retval == 0) | ||
724 | break; | ||
725 | |||
726 | usleep_range(100, 110); | ||
727 | } | ||
728 | |||
729 | return retval; | ||
730 | } | ||
731 | |||
732 | static int exynos_dp_config_video(struct exynos_dp_device *dp) | ||
733 | { | ||
734 | int retval = 0; | ||
735 | int timeout_loop = 0; | ||
736 | int done_count = 0; | ||
737 | |||
738 | exynos_dp_config_video_slave_mode(dp); | ||
739 | |||
740 | exynos_dp_set_video_color_format(dp); | ||
741 | |||
742 | if (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) { | ||
743 | dev_err(dp->dev, "PLL is not locked yet.\n"); | ||
744 | return -EINVAL; | ||
745 | } | ||
746 | |||
747 | for (;;) { | ||
748 | timeout_loop++; | ||
749 | if (exynos_dp_is_slave_video_stream_clock_on(dp) == 0) | ||
750 | break; | ||
751 | if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) { | ||
752 | dev_err(dp->dev, "Timeout of video streamclk ok\n"); | ||
753 | return -ETIMEDOUT; | ||
754 | } | ||
755 | |||
756 | usleep_range(1, 2); | ||
757 | } | ||
758 | |||
759 | /* Set to use the register calculated M/N video */ | ||
760 | exynos_dp_set_video_cr_mn(dp, CALCULATED_M, 0, 0); | ||
761 | |||
762 | /* For video bist, Video timing must be generated by register */ | ||
763 | exynos_dp_set_video_timing_mode(dp, VIDEO_TIMING_FROM_CAPTURE); | ||
764 | |||
765 | /* Disable video mute */ | ||
766 | exynos_dp_enable_video_mute(dp, 0); | ||
767 | |||
768 | /* Configure video slave mode */ | ||
769 | exynos_dp_enable_video_master(dp, 0); | ||
770 | |||
771 | /* Enable video */ | ||
772 | exynos_dp_start_video(dp); | ||
773 | |||
774 | timeout_loop = 0; | ||
775 | |||
776 | for (;;) { | ||
777 | timeout_loop++; | ||
778 | if (exynos_dp_is_video_stream_on(dp) == 0) { | ||
779 | done_count++; | ||
780 | if (done_count > 10) | ||
781 | break; | ||
782 | } else if (done_count) { | ||
783 | done_count = 0; | ||
784 | } | ||
785 | if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) { | ||
786 | dev_err(dp->dev, "Timeout of video streamclk ok\n"); | ||
787 | return -ETIMEDOUT; | ||
788 | } | ||
789 | |||
790 | usleep_range(1000, 1001); | ||
791 | } | ||
792 | |||
793 | if (retval != 0) | ||
794 | dev_err(dp->dev, "Video stream is not detected!\n"); | ||
795 | |||
796 | return retval; | ||
797 | } | ||
798 | |||
799 | static void exynos_dp_enable_scramble(struct exynos_dp_device *dp, bool enable) | ||
800 | { | ||
801 | u8 data; | ||
802 | |||
803 | if (enable) { | ||
804 | exynos_dp_enable_scrambling(dp); | ||
805 | |||
806 | exynos_dp_read_byte_from_dpcd(dp, | ||
807 | DPCD_ADDR_TRAINING_PATTERN_SET, | ||
808 | &data); | ||
809 | exynos_dp_write_byte_to_dpcd(dp, | ||
810 | DPCD_ADDR_TRAINING_PATTERN_SET, | ||
811 | (u8)(data & ~DPCD_SCRAMBLING_DISABLED)); | ||
812 | } else { | ||
813 | exynos_dp_disable_scrambling(dp); | ||
814 | |||
815 | exynos_dp_read_byte_from_dpcd(dp, | ||
816 | DPCD_ADDR_TRAINING_PATTERN_SET, | ||
817 | &data); | ||
818 | exynos_dp_write_byte_to_dpcd(dp, | ||
819 | DPCD_ADDR_TRAINING_PATTERN_SET, | ||
820 | (u8)(data | DPCD_SCRAMBLING_DISABLED)); | ||
821 | } | ||
822 | } | ||
823 | |||
824 | static irqreturn_t exynos_dp_irq_handler(int irq, void *arg) | ||
825 | { | ||
826 | struct exynos_dp_device *dp = arg; | ||
827 | |||
828 | enum dp_irq_type irq_type; | ||
829 | |||
830 | irq_type = exynos_dp_get_irq_type(dp); | ||
831 | switch (irq_type) { | ||
832 | case DP_IRQ_TYPE_HP_CABLE_IN: | ||
833 | dev_dbg(dp->dev, "Received irq - cable in\n"); | ||
834 | schedule_work(&dp->hotplug_work); | ||
835 | exynos_dp_clear_hotplug_interrupts(dp); | ||
836 | break; | ||
837 | case DP_IRQ_TYPE_HP_CABLE_OUT: | ||
838 | dev_dbg(dp->dev, "Received irq - cable out\n"); | ||
839 | exynos_dp_clear_hotplug_interrupts(dp); | ||
840 | break; | ||
841 | case DP_IRQ_TYPE_HP_CHANGE: | ||
842 | /* | ||
843 | * We get these change notifications once in a while, but there | ||
844 | * is nothing we can do with them. Just ignore it for now and | ||
845 | * only handle cable changes. | ||
846 | */ | ||
847 | dev_dbg(dp->dev, "Received irq - hotplug change; ignoring.\n"); | ||
848 | exynos_dp_clear_hotplug_interrupts(dp); | ||
849 | break; | ||
850 | default: | ||
851 | dev_err(dp->dev, "Received irq - unknown type!\n"); | ||
852 | break; | ||
853 | } | ||
854 | return IRQ_HANDLED; | ||
855 | } | ||
856 | |||
857 | static void exynos_dp_hotplug(struct work_struct *work) | ||
858 | { | ||
859 | struct exynos_dp_device *dp; | ||
860 | int ret; | ||
861 | |||
862 | dp = container_of(work, struct exynos_dp_device, hotplug_work); | ||
863 | |||
864 | ret = exynos_dp_detect_hpd(dp); | ||
865 | if (ret) { | ||
866 | /* Cable has been disconnected, we're done */ | ||
867 | return; | ||
868 | } | ||
869 | |||
870 | ret = exynos_dp_handle_edid(dp); | ||
871 | if (ret) { | ||
872 | dev_err(dp->dev, "unable to handle edid\n"); | ||
873 | return; | ||
874 | } | ||
875 | |||
876 | ret = exynos_dp_set_link_train(dp, dp->video_info->lane_count, | ||
877 | dp->video_info->link_rate); | ||
878 | if (ret) { | ||
879 | dev_err(dp->dev, "unable to do link train\n"); | ||
880 | return; | ||
881 | } | ||
882 | |||
883 | exynos_dp_enable_scramble(dp, 1); | ||
884 | exynos_dp_enable_rx_to_enhanced_mode(dp, 1); | ||
885 | exynos_dp_enable_enhanced_mode(dp, 1); | ||
886 | |||
887 | exynos_dp_set_lane_count(dp, dp->video_info->lane_count); | ||
888 | exynos_dp_set_link_bandwidth(dp, dp->video_info->link_rate); | ||
889 | |||
890 | exynos_dp_init_video(dp); | ||
891 | ret = exynos_dp_config_video(dp); | ||
892 | if (ret) | ||
893 | dev_err(dp->dev, "unable to config video\n"); | ||
894 | } | ||
895 | |||
896 | static struct video_info *exynos_dp_dt_parse_pdata(struct device *dev) | ||
897 | { | ||
898 | struct device_node *dp_node = dev->of_node; | ||
899 | struct video_info *dp_video_config; | ||
900 | |||
901 | dp_video_config = devm_kzalloc(dev, | ||
902 | sizeof(*dp_video_config), GFP_KERNEL); | ||
903 | if (!dp_video_config) { | ||
904 | dev_err(dev, "memory allocation for video config failed\n"); | ||
905 | return ERR_PTR(-ENOMEM); | ||
906 | } | ||
907 | |||
908 | dp_video_config->h_sync_polarity = | ||
909 | of_property_read_bool(dp_node, "hsync-active-high"); | ||
910 | |||
911 | dp_video_config->v_sync_polarity = | ||
912 | of_property_read_bool(dp_node, "vsync-active-high"); | ||
913 | |||
914 | dp_video_config->interlaced = | ||
915 | of_property_read_bool(dp_node, "interlaced"); | ||
916 | |||
917 | if (of_property_read_u32(dp_node, "samsung,color-space", | ||
918 | &dp_video_config->color_space)) { | ||
919 | dev_err(dev, "failed to get color-space\n"); | ||
920 | return ERR_PTR(-EINVAL); | ||
921 | } | ||
922 | |||
923 | if (of_property_read_u32(dp_node, "samsung,dynamic-range", | ||
924 | &dp_video_config->dynamic_range)) { | ||
925 | dev_err(dev, "failed to get dynamic-range\n"); | ||
926 | return ERR_PTR(-EINVAL); | ||
927 | } | ||
928 | |||
929 | if (of_property_read_u32(dp_node, "samsung,ycbcr-coeff", | ||
930 | &dp_video_config->ycbcr_coeff)) { | ||
931 | dev_err(dev, "failed to get ycbcr-coeff\n"); | ||
932 | return ERR_PTR(-EINVAL); | ||
933 | } | ||
934 | |||
935 | if (of_property_read_u32(dp_node, "samsung,color-depth", | ||
936 | &dp_video_config->color_depth)) { | ||
937 | dev_err(dev, "failed to get color-depth\n"); | ||
938 | return ERR_PTR(-EINVAL); | ||
939 | } | ||
940 | |||
941 | if (of_property_read_u32(dp_node, "samsung,link-rate", | ||
942 | &dp_video_config->link_rate)) { | ||
943 | dev_err(dev, "failed to get link-rate\n"); | ||
944 | return ERR_PTR(-EINVAL); | ||
945 | } | ||
946 | |||
947 | if (of_property_read_u32(dp_node, "samsung,lane-count", | ||
948 | &dp_video_config->lane_count)) { | ||
949 | dev_err(dev, "failed to get lane-count\n"); | ||
950 | return ERR_PTR(-EINVAL); | ||
951 | } | ||
952 | |||
953 | return dp_video_config; | ||
954 | } | ||
955 | |||
956 | static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp) | ||
957 | { | ||
958 | struct device_node *dp_phy_node = of_node_get(dp->dev->of_node); | ||
959 | u32 phy_base; | ||
960 | int ret = 0; | ||
961 | |||
962 | dp_phy_node = of_find_node_by_name(dp_phy_node, "dptx-phy"); | ||
963 | if (!dp_phy_node) { | ||
964 | dp->phy = devm_phy_get(dp->dev, "dp"); | ||
965 | if (IS_ERR(dp->phy)) | ||
966 | return PTR_ERR(dp->phy); | ||
967 | else | ||
968 | return 0; | ||
969 | } | ||
970 | |||
971 | if (of_property_read_u32(dp_phy_node, "reg", &phy_base)) { | ||
972 | dev_err(dp->dev, "failed to get reg for dptx-phy\n"); | ||
973 | ret = -EINVAL; | ||
974 | goto err; | ||
975 | } | ||
976 | |||
977 | if (of_property_read_u32(dp_phy_node, "samsung,enable-mask", | ||
978 | &dp->enable_mask)) { | ||
979 | dev_err(dp->dev, "failed to get enable-mask for dptx-phy\n"); | ||
980 | ret = -EINVAL; | ||
981 | goto err; | ||
982 | } | ||
983 | |||
984 | dp->phy_addr = ioremap(phy_base, SZ_4); | ||
985 | if (!dp->phy_addr) { | ||
986 | dev_err(dp->dev, "failed to ioremap dp-phy\n"); | ||
987 | ret = -ENOMEM; | ||
988 | goto err; | ||
989 | } | ||
990 | |||
991 | err: | ||
992 | of_node_put(dp_phy_node); | ||
993 | |||
994 | return ret; | ||
995 | } | ||
996 | |||
997 | static void exynos_dp_phy_init(struct exynos_dp_device *dp) | ||
998 | { | ||
999 | if (dp->phy) { | ||
1000 | phy_power_on(dp->phy); | ||
1001 | } else if (dp->phy_addr) { | ||
1002 | u32 reg; | ||
1003 | |||
1004 | reg = __raw_readl(dp->phy_addr); | ||
1005 | reg |= dp->enable_mask; | ||
1006 | __raw_writel(reg, dp->phy_addr); | ||
1007 | } | ||
1008 | } | ||
1009 | |||
1010 | static void exynos_dp_phy_exit(struct exynos_dp_device *dp) | ||
1011 | { | ||
1012 | if (dp->phy) { | ||
1013 | phy_power_off(dp->phy); | ||
1014 | } else if (dp->phy_addr) { | ||
1015 | u32 reg; | ||
1016 | |||
1017 | reg = __raw_readl(dp->phy_addr); | ||
1018 | reg &= ~(dp->enable_mask); | ||
1019 | __raw_writel(reg, dp->phy_addr); | ||
1020 | } | ||
1021 | } | ||
1022 | |||
1023 | static int exynos_dp_probe(struct platform_device *pdev) | ||
1024 | { | ||
1025 | struct resource *res; | ||
1026 | struct exynos_dp_device *dp; | ||
1027 | |||
1028 | int ret = 0; | ||
1029 | |||
1030 | dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device), | ||
1031 | GFP_KERNEL); | ||
1032 | if (!dp) { | ||
1033 | dev_err(&pdev->dev, "no memory for device data\n"); | ||
1034 | return -ENOMEM; | ||
1035 | } | ||
1036 | |||
1037 | dp->dev = &pdev->dev; | ||
1038 | |||
1039 | dp->video_info = exynos_dp_dt_parse_pdata(&pdev->dev); | ||
1040 | if (IS_ERR(dp->video_info)) | ||
1041 | return PTR_ERR(dp->video_info); | ||
1042 | |||
1043 | ret = exynos_dp_dt_parse_phydata(dp); | ||
1044 | if (ret) | ||
1045 | return ret; | ||
1046 | |||
1047 | dp->clock = devm_clk_get(&pdev->dev, "dp"); | ||
1048 | if (IS_ERR(dp->clock)) { | ||
1049 | dev_err(&pdev->dev, "failed to get clock\n"); | ||
1050 | return PTR_ERR(dp->clock); | ||
1051 | } | ||
1052 | |||
1053 | clk_prepare_enable(dp->clock); | ||
1054 | |||
1055 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1056 | |||
1057 | dp->reg_base = devm_ioremap_resource(&pdev->dev, res); | ||
1058 | if (IS_ERR(dp->reg_base)) | ||
1059 | return PTR_ERR(dp->reg_base); | ||
1060 | |||
1061 | dp->irq = platform_get_irq(pdev, 0); | ||
1062 | if (dp->irq == -ENXIO) { | ||
1063 | dev_err(&pdev->dev, "failed to get irq\n"); | ||
1064 | return -ENODEV; | ||
1065 | } | ||
1066 | |||
1067 | INIT_WORK(&dp->hotplug_work, exynos_dp_hotplug); | ||
1068 | |||
1069 | exynos_dp_phy_init(dp); | ||
1070 | |||
1071 | exynos_dp_init_dp(dp); | ||
1072 | |||
1073 | ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler, 0, | ||
1074 | "exynos-dp", dp); | ||
1075 | if (ret) { | ||
1076 | dev_err(&pdev->dev, "failed to request irq\n"); | ||
1077 | return ret; | ||
1078 | } | ||
1079 | |||
1080 | platform_set_drvdata(pdev, dp); | ||
1081 | |||
1082 | return 0; | ||
1083 | } | ||
1084 | |||
1085 | static int exynos_dp_remove(struct platform_device *pdev) | ||
1086 | { | ||
1087 | struct exynos_dp_device *dp = platform_get_drvdata(pdev); | ||
1088 | |||
1089 | flush_work(&dp->hotplug_work); | ||
1090 | |||
1091 | exynos_dp_phy_exit(dp); | ||
1092 | |||
1093 | clk_disable_unprepare(dp->clock); | ||
1094 | |||
1095 | |||
1096 | return 0; | ||
1097 | } | ||
1098 | |||
1099 | #ifdef CONFIG_PM_SLEEP | ||
1100 | static int exynos_dp_suspend(struct device *dev) | ||
1101 | { | ||
1102 | struct exynos_dp_device *dp = dev_get_drvdata(dev); | ||
1103 | |||
1104 | disable_irq(dp->irq); | ||
1105 | |||
1106 | flush_work(&dp->hotplug_work); | ||
1107 | |||
1108 | exynos_dp_phy_exit(dp); | ||
1109 | |||
1110 | clk_disable_unprepare(dp->clock); | ||
1111 | |||
1112 | return 0; | ||
1113 | } | ||
1114 | |||
1115 | static int exynos_dp_resume(struct device *dev) | ||
1116 | { | ||
1117 | struct exynos_dp_device *dp = dev_get_drvdata(dev); | ||
1118 | |||
1119 | exynos_dp_phy_init(dp); | ||
1120 | |||
1121 | clk_prepare_enable(dp->clock); | ||
1122 | |||
1123 | exynos_dp_init_dp(dp); | ||
1124 | |||
1125 | enable_irq(dp->irq); | ||
1126 | |||
1127 | return 0; | ||
1128 | } | ||
1129 | #endif | ||
1130 | |||
1131 | static const struct dev_pm_ops exynos_dp_pm_ops = { | ||
1132 | SET_SYSTEM_SLEEP_PM_OPS(exynos_dp_suspend, exynos_dp_resume) | ||
1133 | }; | ||
1134 | |||
1135 | static const struct of_device_id exynos_dp_match[] = { | ||
1136 | { .compatible = "samsung,exynos5-dp" }, | ||
1137 | {}, | ||
1138 | }; | ||
1139 | MODULE_DEVICE_TABLE(of, exynos_dp_match); | ||
1140 | |||
1141 | static struct platform_driver exynos_dp_driver = { | ||
1142 | .probe = exynos_dp_probe, | ||
1143 | .remove = exynos_dp_remove, | ||
1144 | .driver = { | ||
1145 | .name = "exynos-dp", | ||
1146 | .owner = THIS_MODULE, | ||
1147 | .pm = &exynos_dp_pm_ops, | ||
1148 | .of_match_table = exynos_dp_match, | ||
1149 | }, | ||
1150 | }; | ||
1151 | |||
1152 | module_platform_driver(exynos_dp_driver); | ||
1153 | |||
1154 | MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>"); | ||
1155 | MODULE_DESCRIPTION("Samsung SoC DP Driver"); | ||
1156 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/exynos/exynos_dp_core.h b/drivers/video/exynos/exynos_dp_core.h deleted file mode 100644 index 607e36d0c147..000000000000 --- a/drivers/video/exynos/exynos_dp_core.h +++ /dev/null | |||
@@ -1,320 +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 | #define DP_TIMEOUT_LOOP_COUNT 100 | ||
17 | #define MAX_CR_LOOP 5 | ||
18 | #define MAX_EQ_LOOP 5 | ||
19 | |||
20 | enum link_rate_type { | ||
21 | LINK_RATE_1_62GBPS = 0x06, | ||
22 | LINK_RATE_2_70GBPS = 0x0a | ||
23 | }; | ||
24 | |||
25 | enum link_lane_count_type { | ||
26 | LANE_COUNT1 = 1, | ||
27 | LANE_COUNT2 = 2, | ||
28 | LANE_COUNT4 = 4 | ||
29 | }; | ||
30 | |||
31 | enum link_training_state { | ||
32 | START, | ||
33 | CLOCK_RECOVERY, | ||
34 | EQUALIZER_TRAINING, | ||
35 | FINISHED, | ||
36 | FAILED | ||
37 | }; | ||
38 | |||
39 | enum voltage_swing_level { | ||
40 | VOLTAGE_LEVEL_0, | ||
41 | VOLTAGE_LEVEL_1, | ||
42 | VOLTAGE_LEVEL_2, | ||
43 | VOLTAGE_LEVEL_3, | ||
44 | }; | ||
45 | |||
46 | enum pre_emphasis_level { | ||
47 | PRE_EMPHASIS_LEVEL_0, | ||
48 | PRE_EMPHASIS_LEVEL_1, | ||
49 | PRE_EMPHASIS_LEVEL_2, | ||
50 | PRE_EMPHASIS_LEVEL_3, | ||
51 | }; | ||
52 | |||
53 | enum pattern_set { | ||
54 | PRBS7, | ||
55 | D10_2, | ||
56 | TRAINING_PTN1, | ||
57 | TRAINING_PTN2, | ||
58 | DP_NONE | ||
59 | }; | ||
60 | |||
61 | enum color_space { | ||
62 | COLOR_RGB, | ||
63 | COLOR_YCBCR422, | ||
64 | COLOR_YCBCR444 | ||
65 | }; | ||
66 | |||
67 | enum color_depth { | ||
68 | COLOR_6, | ||
69 | COLOR_8, | ||
70 | COLOR_10, | ||
71 | COLOR_12 | ||
72 | }; | ||
73 | |||
74 | enum color_coefficient { | ||
75 | COLOR_YCBCR601, | ||
76 | COLOR_YCBCR709 | ||
77 | }; | ||
78 | |||
79 | enum dynamic_range { | ||
80 | VESA, | ||
81 | CEA | ||
82 | }; | ||
83 | |||
84 | enum pll_status { | ||
85 | PLL_UNLOCKED, | ||
86 | PLL_LOCKED | ||
87 | }; | ||
88 | |||
89 | enum clock_recovery_m_value_type { | ||
90 | CALCULATED_M, | ||
91 | REGISTER_M | ||
92 | }; | ||
93 | |||
94 | enum video_timing_recognition_type { | ||
95 | VIDEO_TIMING_FROM_CAPTURE, | ||
96 | VIDEO_TIMING_FROM_REGISTER | ||
97 | }; | ||
98 | |||
99 | enum analog_power_block { | ||
100 | AUX_BLOCK, | ||
101 | CH0_BLOCK, | ||
102 | CH1_BLOCK, | ||
103 | CH2_BLOCK, | ||
104 | CH3_BLOCK, | ||
105 | ANALOG_TOTAL, | ||
106 | POWER_ALL | ||
107 | }; | ||
108 | |||
109 | enum dp_irq_type { | ||
110 | DP_IRQ_TYPE_HP_CABLE_IN, | ||
111 | DP_IRQ_TYPE_HP_CABLE_OUT, | ||
112 | DP_IRQ_TYPE_HP_CHANGE, | ||
113 | DP_IRQ_TYPE_UNKNOWN, | ||
114 | }; | ||
115 | |||
116 | struct video_info { | ||
117 | char *name; | ||
118 | |||
119 | bool h_sync_polarity; | ||
120 | bool v_sync_polarity; | ||
121 | bool interlaced; | ||
122 | |||
123 | enum color_space color_space; | ||
124 | enum dynamic_range dynamic_range; | ||
125 | enum color_coefficient ycbcr_coeff; | ||
126 | enum color_depth color_depth; | ||
127 | |||
128 | enum link_rate_type link_rate; | ||
129 | enum link_lane_count_type lane_count; | ||
130 | }; | ||
131 | |||
132 | struct link_train { | ||
133 | int eq_loop; | ||
134 | int cr_loop[4]; | ||
135 | |||
136 | u8 link_rate; | ||
137 | u8 lane_count; | ||
138 | u8 training_lane[4]; | ||
139 | |||
140 | enum link_training_state lt_state; | ||
141 | }; | ||
142 | |||
143 | struct exynos_dp_device { | ||
144 | struct device *dev; | ||
145 | struct clk *clock; | ||
146 | unsigned int irq; | ||
147 | void __iomem *reg_base; | ||
148 | void __iomem *phy_addr; | ||
149 | unsigned int enable_mask; | ||
150 | |||
151 | struct video_info *video_info; | ||
152 | struct link_train link_train; | ||
153 | struct work_struct hotplug_work; | ||
154 | struct phy *phy; | ||
155 | }; | ||
156 | |||
157 | /* exynos_dp_reg.c */ | ||
158 | void exynos_dp_enable_video_mute(struct exynos_dp_device *dp, bool enable); | ||
159 | void exynos_dp_stop_video(struct exynos_dp_device *dp); | ||
160 | void exynos_dp_lane_swap(struct exynos_dp_device *dp, bool enable); | ||
161 | void exynos_dp_init_analog_param(struct exynos_dp_device *dp); | ||
162 | void exynos_dp_init_interrupt(struct exynos_dp_device *dp); | ||
163 | void exynos_dp_reset(struct exynos_dp_device *dp); | ||
164 | void exynos_dp_swreset(struct exynos_dp_device *dp); | ||
165 | void exynos_dp_config_interrupt(struct exynos_dp_device *dp); | ||
166 | enum pll_status exynos_dp_get_pll_lock_status(struct exynos_dp_device *dp); | ||
167 | void exynos_dp_set_pll_power_down(struct exynos_dp_device *dp, bool enable); | ||
168 | void exynos_dp_set_analog_power_down(struct exynos_dp_device *dp, | ||
169 | enum analog_power_block block, | ||
170 | bool enable); | ||
171 | void exynos_dp_init_analog_func(struct exynos_dp_device *dp); | ||
172 | void exynos_dp_init_hpd(struct exynos_dp_device *dp); | ||
173 | enum dp_irq_type exynos_dp_get_irq_type(struct exynos_dp_device *dp); | ||
174 | void exynos_dp_clear_hotplug_interrupts(struct exynos_dp_device *dp); | ||
175 | void exynos_dp_reset_aux(struct exynos_dp_device *dp); | ||
176 | void exynos_dp_init_aux(struct exynos_dp_device *dp); | ||
177 | int exynos_dp_get_plug_in_status(struct exynos_dp_device *dp); | ||
178 | void exynos_dp_enable_sw_function(struct exynos_dp_device *dp); | ||
179 | int exynos_dp_start_aux_transaction(struct exynos_dp_device *dp); | ||
180 | int exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp, | ||
181 | unsigned int reg_addr, | ||
182 | unsigned char data); | ||
183 | int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp, | ||
184 | unsigned int reg_addr, | ||
185 | unsigned char *data); | ||
186 | int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp, | ||
187 | unsigned int reg_addr, | ||
188 | unsigned int count, | ||
189 | unsigned char data[]); | ||
190 | int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp, | ||
191 | unsigned int reg_addr, | ||
192 | unsigned int count, | ||
193 | unsigned char data[]); | ||
194 | int exynos_dp_select_i2c_device(struct exynos_dp_device *dp, | ||
195 | unsigned int device_addr, | ||
196 | unsigned int reg_addr); | ||
197 | int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp, | ||
198 | unsigned int device_addr, | ||
199 | unsigned int reg_addr, | ||
200 | unsigned int *data); | ||
201 | int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp, | ||
202 | unsigned int device_addr, | ||
203 | unsigned int reg_addr, | ||
204 | unsigned int count, | ||
205 | unsigned char edid[]); | ||
206 | void exynos_dp_set_link_bandwidth(struct exynos_dp_device *dp, u32 bwtype); | ||
207 | void exynos_dp_get_link_bandwidth(struct exynos_dp_device *dp, u32 *bwtype); | ||
208 | void exynos_dp_set_lane_count(struct exynos_dp_device *dp, u32 count); | ||
209 | void exynos_dp_get_lane_count(struct exynos_dp_device *dp, u32 *count); | ||
210 | void exynos_dp_enable_enhanced_mode(struct exynos_dp_device *dp, bool enable); | ||
211 | void exynos_dp_set_training_pattern(struct exynos_dp_device *dp, | ||
212 | enum pattern_set pattern); | ||
213 | void exynos_dp_set_lane0_pre_emphasis(struct exynos_dp_device *dp, u32 level); | ||
214 | void exynos_dp_set_lane1_pre_emphasis(struct exynos_dp_device *dp, u32 level); | ||
215 | void exynos_dp_set_lane2_pre_emphasis(struct exynos_dp_device *dp, u32 level); | ||
216 | void exynos_dp_set_lane3_pre_emphasis(struct exynos_dp_device *dp, u32 level); | ||
217 | void exynos_dp_set_lane0_link_training(struct exynos_dp_device *dp, | ||
218 | u32 training_lane); | ||
219 | void exynos_dp_set_lane1_link_training(struct exynos_dp_device *dp, | ||
220 | u32 training_lane); | ||
221 | void exynos_dp_set_lane2_link_training(struct exynos_dp_device *dp, | ||
222 | u32 training_lane); | ||
223 | void exynos_dp_set_lane3_link_training(struct exynos_dp_device *dp, | ||
224 | u32 training_lane); | ||
225 | u32 exynos_dp_get_lane0_link_training(struct exynos_dp_device *dp); | ||
226 | u32 exynos_dp_get_lane1_link_training(struct exynos_dp_device *dp); | ||
227 | u32 exynos_dp_get_lane2_link_training(struct exynos_dp_device *dp); | ||
228 | u32 exynos_dp_get_lane3_link_training(struct exynos_dp_device *dp); | ||
229 | void exynos_dp_reset_macro(struct exynos_dp_device *dp); | ||
230 | void exynos_dp_init_video(struct exynos_dp_device *dp); | ||
231 | |||
232 | void exynos_dp_set_video_color_format(struct exynos_dp_device *dp); | ||
233 | int exynos_dp_is_slave_video_stream_clock_on(struct exynos_dp_device *dp); | ||
234 | void exynos_dp_set_video_cr_mn(struct exynos_dp_device *dp, | ||
235 | enum clock_recovery_m_value_type type, | ||
236 | u32 m_value, | ||
237 | u32 n_value); | ||
238 | void exynos_dp_set_video_timing_mode(struct exynos_dp_device *dp, u32 type); | ||
239 | void exynos_dp_enable_video_master(struct exynos_dp_device *dp, bool enable); | ||
240 | void exynos_dp_start_video(struct exynos_dp_device *dp); | ||
241 | int exynos_dp_is_video_stream_on(struct exynos_dp_device *dp); | ||
242 | void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp); | ||
243 | void exynos_dp_enable_scrambling(struct exynos_dp_device *dp); | ||
244 | void exynos_dp_disable_scrambling(struct exynos_dp_device *dp); | ||
245 | |||
246 | /* I2C EDID Chip ID, Slave Address */ | ||
247 | #define I2C_EDID_DEVICE_ADDR 0x50 | ||
248 | #define I2C_E_EDID_DEVICE_ADDR 0x30 | ||
249 | |||
250 | #define EDID_BLOCK_LENGTH 0x80 | ||
251 | #define EDID_HEADER_PATTERN 0x00 | ||
252 | #define EDID_EXTENSION_FLAG 0x7e | ||
253 | #define EDID_CHECKSUM 0x7f | ||
254 | |||
255 | /* Definition for DPCD Register */ | ||
256 | #define DPCD_ADDR_DPCD_REV 0x0000 | ||
257 | #define DPCD_ADDR_MAX_LINK_RATE 0x0001 | ||
258 | #define DPCD_ADDR_MAX_LANE_COUNT 0x0002 | ||
259 | #define DPCD_ADDR_LINK_BW_SET 0x0100 | ||
260 | #define DPCD_ADDR_LANE_COUNT_SET 0x0101 | ||
261 | #define DPCD_ADDR_TRAINING_PATTERN_SET 0x0102 | ||
262 | #define DPCD_ADDR_TRAINING_LANE0_SET 0x0103 | ||
263 | #define DPCD_ADDR_LANE0_1_STATUS 0x0202 | ||
264 | #define DPCD_ADDR_LANE_ALIGN_STATUS_UPDATED 0x0204 | ||
265 | #define DPCD_ADDR_ADJUST_REQUEST_LANE0_1 0x0206 | ||
266 | #define DPCD_ADDR_ADJUST_REQUEST_LANE2_3 0x0207 | ||
267 | #define DPCD_ADDR_TEST_REQUEST 0x0218 | ||
268 | #define DPCD_ADDR_TEST_RESPONSE 0x0260 | ||
269 | #define DPCD_ADDR_TEST_EDID_CHECKSUM 0x0261 | ||
270 | #define DPCD_ADDR_SINK_POWER_STATE 0x0600 | ||
271 | |||
272 | /* DPCD_ADDR_MAX_LANE_COUNT */ | ||
273 | #define DPCD_ENHANCED_FRAME_CAP(x) (((x) >> 7) & 0x1) | ||
274 | #define DPCD_MAX_LANE_COUNT(x) ((x) & 0x1f) | ||
275 | |||
276 | /* DPCD_ADDR_LANE_COUNT_SET */ | ||
277 | #define DPCD_ENHANCED_FRAME_EN (0x1 << 7) | ||
278 | #define DPCD_LANE_COUNT_SET(x) ((x) & 0x1f) | ||
279 | |||
280 | /* DPCD_ADDR_TRAINING_PATTERN_SET */ | ||
281 | #define DPCD_SCRAMBLING_DISABLED (0x1 << 5) | ||
282 | #define DPCD_SCRAMBLING_ENABLED (0x0 << 5) | ||
283 | #define DPCD_TRAINING_PATTERN_2 (0x2 << 0) | ||
284 | #define DPCD_TRAINING_PATTERN_1 (0x1 << 0) | ||
285 | #define DPCD_TRAINING_PATTERN_DISABLED (0x0 << 0) | ||
286 | |||
287 | /* DPCD_ADDR_TRAINING_LANE0_SET */ | ||
288 | #define DPCD_MAX_PRE_EMPHASIS_REACHED (0x1 << 5) | ||
289 | #define DPCD_PRE_EMPHASIS_SET(x) (((x) & 0x3) << 3) | ||
290 | #define DPCD_PRE_EMPHASIS_GET(x) (((x) >> 3) & 0x3) | ||
291 | #define DPCD_PRE_EMPHASIS_PATTERN2_LEVEL0 (0x0 << 3) | ||
292 | #define DPCD_MAX_SWING_REACHED (0x1 << 2) | ||
293 | #define DPCD_VOLTAGE_SWING_SET(x) (((x) & 0x3) << 0) | ||
294 | #define DPCD_VOLTAGE_SWING_GET(x) (((x) >> 0) & 0x3) | ||
295 | #define DPCD_VOLTAGE_SWING_PATTERN1_LEVEL0 (0x0 << 0) | ||
296 | |||
297 | /* DPCD_ADDR_LANE0_1_STATUS */ | ||
298 | #define DPCD_LANE_SYMBOL_LOCKED (0x1 << 2) | ||
299 | #define DPCD_LANE_CHANNEL_EQ_DONE (0x1 << 1) | ||
300 | #define DPCD_LANE_CR_DONE (0x1 << 0) | ||
301 | #define DPCD_CHANNEL_EQ_BITS (DPCD_LANE_CR_DONE| \ | ||
302 | DPCD_LANE_CHANNEL_EQ_DONE|\ | ||
303 | DPCD_LANE_SYMBOL_LOCKED) | ||
304 | |||
305 | /* DPCD_ADDR_LANE_ALIGN__STATUS_UPDATED */ | ||
306 | #define DPCD_LINK_STATUS_UPDATED (0x1 << 7) | ||
307 | #define DPCD_DOWNSTREAM_PORT_STATUS_CHANGED (0x1 << 6) | ||
308 | #define DPCD_INTERLANE_ALIGN_DONE (0x1 << 0) | ||
309 | |||
310 | /* DPCD_ADDR_TEST_REQUEST */ | ||
311 | #define DPCD_TEST_EDID_READ (0x1 << 2) | ||
312 | |||
313 | /* DPCD_ADDR_TEST_RESPONSE */ | ||
314 | #define DPCD_TEST_EDID_CHECKSUM_WRITE (0x1 << 2) | ||
315 | |||
316 | /* DPCD_ADDR_SINK_POWER_STATE */ | ||
317 | #define DPCD_SET_POWER_STATE_D0 (0x1 << 0) | ||
318 | #define DPCD_SET_POWER_STATE_D4 (0x2 << 0) | ||
319 | |||
320 | #endif /* _EXYNOS_DP_CORE_H */ | ||
diff --git a/drivers/video/exynos/exynos_dp_reg.c b/drivers/video/exynos/exynos_dp_reg.c deleted file mode 100644 index b70da5052ff0..000000000000 --- a/drivers/video/exynos/exynos_dp_reg.c +++ /dev/null | |||
@@ -1,1243 +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 | |||
17 | #include "exynos_dp_core.h" | ||
18 | #include "exynos_dp_reg.h" | ||
19 | |||
20 | #define COMMON_INT_MASK_1 0 | ||
21 | #define COMMON_INT_MASK_2 0 | ||
22 | #define COMMON_INT_MASK_3 0 | ||
23 | #define COMMON_INT_MASK_4 (HOTPLUG_CHG | HPD_LOST | PLUG) | ||
24 | #define INT_STA_MASK INT_HPD | ||
25 | |||
26 | void exynos_dp_enable_video_mute(struct exynos_dp_device *dp, bool enable) | ||
27 | { | ||
28 | u32 reg; | ||
29 | |||
30 | if (enable) { | ||
31 | reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); | ||
32 | reg |= HDCP_VIDEO_MUTE; | ||
33 | writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); | ||
34 | } else { | ||
35 | reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); | ||
36 | reg &= ~HDCP_VIDEO_MUTE; | ||
37 | writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); | ||
38 | } | ||
39 | } | ||
40 | |||
41 | void exynos_dp_stop_video(struct exynos_dp_device *dp) | ||
42 | { | ||
43 | u32 reg; | ||
44 | |||
45 | reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); | ||
46 | reg &= ~VIDEO_EN; | ||
47 | writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); | ||
48 | } | ||
49 | |||
50 | void exynos_dp_lane_swap(struct exynos_dp_device *dp, bool enable) | ||
51 | { | ||
52 | u32 reg; | ||
53 | |||
54 | if (enable) | ||
55 | reg = LANE3_MAP_LOGIC_LANE_0 | LANE2_MAP_LOGIC_LANE_1 | | ||
56 | LANE1_MAP_LOGIC_LANE_2 | LANE0_MAP_LOGIC_LANE_3; | ||
57 | else | ||
58 | reg = LANE3_MAP_LOGIC_LANE_3 | LANE2_MAP_LOGIC_LANE_2 | | ||
59 | LANE1_MAP_LOGIC_LANE_1 | LANE0_MAP_LOGIC_LANE_0; | ||
60 | |||
61 | writel(reg, dp->reg_base + EXYNOS_DP_LANE_MAP); | ||
62 | } | ||
63 | |||
64 | void exynos_dp_init_analog_param(struct exynos_dp_device *dp) | ||
65 | { | ||
66 | u32 reg; | ||
67 | |||
68 | reg = TX_TERMINAL_CTRL_50_OHM; | ||
69 | writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_1); | ||
70 | |||
71 | reg = SEL_24M | TX_DVDD_BIT_1_0625V; | ||
72 | writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_2); | ||
73 | |||
74 | reg = DRIVE_DVDD_BIT_1_0625V | VCO_BIT_600_MICRO; | ||
75 | writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_3); | ||
76 | |||
77 | reg = PD_RING_OSC | AUX_TERMINAL_CTRL_50_OHM | | ||
78 | TX_CUR1_2X | TX_CUR_16_MA; | ||
79 | writel(reg, dp->reg_base + EXYNOS_DP_PLL_FILTER_CTL_1); | ||
80 | |||
81 | reg = CH3_AMP_400_MV | CH2_AMP_400_MV | | ||
82 | CH1_AMP_400_MV | CH0_AMP_400_MV; | ||
83 | writel(reg, dp->reg_base + EXYNOS_DP_TX_AMP_TUNING_CTL); | ||
84 | } | ||
85 | |||
86 | void exynos_dp_init_interrupt(struct exynos_dp_device *dp) | ||
87 | { | ||
88 | /* Set interrupt pin assertion polarity as high */ | ||
89 | writel(INT_POL1 | INT_POL0, dp->reg_base + EXYNOS_DP_INT_CTL); | ||
90 | |||
91 | /* Clear pending regisers */ | ||
92 | writel(0xff, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1); | ||
93 | writel(0x4f, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_2); | ||
94 | writel(0xe0, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_3); | ||
95 | writel(0xe7, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4); | ||
96 | writel(0x63, dp->reg_base + EXYNOS_DP_INT_STA); | ||
97 | |||
98 | /* 0:mask,1: unmask */ | ||
99 | writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_1); | ||
100 | writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_2); | ||
101 | writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_3); | ||
102 | writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_4); | ||
103 | writel(0x00, dp->reg_base + EXYNOS_DP_INT_STA_MASK); | ||
104 | } | ||
105 | |||
106 | void exynos_dp_reset(struct exynos_dp_device *dp) | ||
107 | { | ||
108 | u32 reg; | ||
109 | |||
110 | exynos_dp_stop_video(dp); | ||
111 | exynos_dp_enable_video_mute(dp, 0); | ||
112 | |||
113 | reg = MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N | | ||
114 | AUD_FIFO_FUNC_EN_N | AUD_FUNC_EN_N | | ||
115 | HDCP_FUNC_EN_N | SW_FUNC_EN_N; | ||
116 | writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1); | ||
117 | |||
118 | reg = SSC_FUNC_EN_N | AUX_FUNC_EN_N | | ||
119 | SERDES_FIFO_FUNC_EN_N | | ||
120 | LS_CLK_DOMAIN_FUNC_EN_N; | ||
121 | writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2); | ||
122 | |||
123 | usleep_range(20, 30); | ||
124 | |||
125 | exynos_dp_lane_swap(dp, 0); | ||
126 | |||
127 | writel(0x0, dp->reg_base + EXYNOS_DP_SYS_CTL_1); | ||
128 | writel(0x40, dp->reg_base + EXYNOS_DP_SYS_CTL_2); | ||
129 | writel(0x0, dp->reg_base + EXYNOS_DP_SYS_CTL_3); | ||
130 | writel(0x0, dp->reg_base + EXYNOS_DP_SYS_CTL_4); | ||
131 | |||
132 | writel(0x0, dp->reg_base + EXYNOS_DP_PKT_SEND_CTL); | ||
133 | writel(0x0, dp->reg_base + EXYNOS_DP_HDCP_CTL); | ||
134 | |||
135 | writel(0x5e, dp->reg_base + EXYNOS_DP_HPD_DEGLITCH_L); | ||
136 | writel(0x1a, dp->reg_base + EXYNOS_DP_HPD_DEGLITCH_H); | ||
137 | |||
138 | writel(0x10, dp->reg_base + EXYNOS_DP_LINK_DEBUG_CTL); | ||
139 | |||
140 | writel(0x0, dp->reg_base + EXYNOS_DP_PHY_TEST); | ||
141 | |||
142 | writel(0x0, dp->reg_base + EXYNOS_DP_VIDEO_FIFO_THRD); | ||
143 | writel(0x20, dp->reg_base + EXYNOS_DP_AUDIO_MARGIN); | ||
144 | |||
145 | writel(0x4, dp->reg_base + EXYNOS_DP_M_VID_GEN_FILTER_TH); | ||
146 | writel(0x2, dp->reg_base + EXYNOS_DP_M_AUD_GEN_FILTER_TH); | ||
147 | |||
148 | writel(0x00000101, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL); | ||
149 | } | ||
150 | |||
151 | void exynos_dp_swreset(struct exynos_dp_device *dp) | ||
152 | { | ||
153 | writel(RESET_DP_TX, dp->reg_base + EXYNOS_DP_TX_SW_RESET); | ||
154 | } | ||
155 | |||
156 | void exynos_dp_config_interrupt(struct exynos_dp_device *dp) | ||
157 | { | ||
158 | u32 reg; | ||
159 | |||
160 | /* 0: mask, 1: unmask */ | ||
161 | reg = COMMON_INT_MASK_1; | ||
162 | writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_1); | ||
163 | |||
164 | reg = COMMON_INT_MASK_2; | ||
165 | writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_2); | ||
166 | |||
167 | reg = COMMON_INT_MASK_3; | ||
168 | writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_3); | ||
169 | |||
170 | reg = COMMON_INT_MASK_4; | ||
171 | writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_4); | ||
172 | |||
173 | reg = INT_STA_MASK; | ||
174 | writel(reg, dp->reg_base + EXYNOS_DP_INT_STA_MASK); | ||
175 | } | ||
176 | |||
177 | enum pll_status exynos_dp_get_pll_lock_status(struct exynos_dp_device *dp) | ||
178 | { | ||
179 | u32 reg; | ||
180 | |||
181 | reg = readl(dp->reg_base + EXYNOS_DP_DEBUG_CTL); | ||
182 | if (reg & PLL_LOCK) | ||
183 | return PLL_LOCKED; | ||
184 | else | ||
185 | return PLL_UNLOCKED; | ||
186 | } | ||
187 | |||
188 | void exynos_dp_set_pll_power_down(struct exynos_dp_device *dp, bool enable) | ||
189 | { | ||
190 | u32 reg; | ||
191 | |||
192 | if (enable) { | ||
193 | reg = readl(dp->reg_base + EXYNOS_DP_PLL_CTL); | ||
194 | reg |= DP_PLL_PD; | ||
195 | writel(reg, dp->reg_base + EXYNOS_DP_PLL_CTL); | ||
196 | } else { | ||
197 | reg = readl(dp->reg_base + EXYNOS_DP_PLL_CTL); | ||
198 | reg &= ~DP_PLL_PD; | ||
199 | writel(reg, dp->reg_base + EXYNOS_DP_PLL_CTL); | ||
200 | } | ||
201 | } | ||
202 | |||
203 | void exynos_dp_set_analog_power_down(struct exynos_dp_device *dp, | ||
204 | enum analog_power_block block, | ||
205 | bool enable) | ||
206 | { | ||
207 | u32 reg; | ||
208 | |||
209 | switch (block) { | ||
210 | case AUX_BLOCK: | ||
211 | if (enable) { | ||
212 | reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); | ||
213 | reg |= AUX_PD; | ||
214 | writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); | ||
215 | } else { | ||
216 | reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); | ||
217 | reg &= ~AUX_PD; | ||
218 | writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); | ||
219 | } | ||
220 | break; | ||
221 | case CH0_BLOCK: | ||
222 | if (enable) { | ||
223 | reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); | ||
224 | reg |= CH0_PD; | ||
225 | writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); | ||
226 | } else { | ||
227 | reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); | ||
228 | reg &= ~CH0_PD; | ||
229 | writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); | ||
230 | } | ||
231 | break; | ||
232 | case CH1_BLOCK: | ||
233 | if (enable) { | ||
234 | reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); | ||
235 | reg |= CH1_PD; | ||
236 | writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); | ||
237 | } else { | ||
238 | reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); | ||
239 | reg &= ~CH1_PD; | ||
240 | writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); | ||
241 | } | ||
242 | break; | ||
243 | case CH2_BLOCK: | ||
244 | if (enable) { | ||
245 | reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); | ||
246 | reg |= CH2_PD; | ||
247 | writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); | ||
248 | } else { | ||
249 | reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); | ||
250 | reg &= ~CH2_PD; | ||
251 | writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); | ||
252 | } | ||
253 | break; | ||
254 | case CH3_BLOCK: | ||
255 | if (enable) { | ||
256 | reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); | ||
257 | reg |= CH3_PD; | ||
258 | writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); | ||
259 | } else { | ||
260 | reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); | ||
261 | reg &= ~CH3_PD; | ||
262 | writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); | ||
263 | } | ||
264 | break; | ||
265 | case ANALOG_TOTAL: | ||
266 | if (enable) { | ||
267 | reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); | ||
268 | reg |= DP_PHY_PD; | ||
269 | writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); | ||
270 | } else { | ||
271 | reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); | ||
272 | reg &= ~DP_PHY_PD; | ||
273 | writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); | ||
274 | } | ||
275 | break; | ||
276 | case POWER_ALL: | ||
277 | if (enable) { | ||
278 | reg = DP_PHY_PD | AUX_PD | CH3_PD | CH2_PD | | ||
279 | CH1_PD | CH0_PD; | ||
280 | writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); | ||
281 | } else { | ||
282 | writel(0x00, dp->reg_base + EXYNOS_DP_PHY_PD); | ||
283 | } | ||
284 | break; | ||
285 | default: | ||
286 | break; | ||
287 | } | ||
288 | } | ||
289 | |||
290 | void exynos_dp_init_analog_func(struct exynos_dp_device *dp) | ||
291 | { | ||
292 | u32 reg; | ||
293 | int timeout_loop = 0; | ||
294 | |||
295 | exynos_dp_set_analog_power_down(dp, POWER_ALL, 0); | ||
296 | |||
297 | reg = PLL_LOCK_CHG; | ||
298 | writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1); | ||
299 | |||
300 | reg = readl(dp->reg_base + EXYNOS_DP_DEBUG_CTL); | ||
301 | reg &= ~(F_PLL_LOCK | PLL_LOCK_CTRL); | ||
302 | writel(reg, dp->reg_base + EXYNOS_DP_DEBUG_CTL); | ||
303 | |||
304 | /* Power up PLL */ | ||
305 | if (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) { | ||
306 | exynos_dp_set_pll_power_down(dp, 0); | ||
307 | |||
308 | while (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) { | ||
309 | timeout_loop++; | ||
310 | if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) { | ||
311 | dev_err(dp->dev, "failed to get pll lock status\n"); | ||
312 | return; | ||
313 | } | ||
314 | usleep_range(10, 20); | ||
315 | } | ||
316 | } | ||
317 | |||
318 | /* Enable Serdes FIFO function and Link symbol clock domain module */ | ||
319 | reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_2); | ||
320 | reg &= ~(SERDES_FIFO_FUNC_EN_N | LS_CLK_DOMAIN_FUNC_EN_N | ||
321 | | AUX_FUNC_EN_N); | ||
322 | writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2); | ||
323 | } | ||
324 | |||
325 | void exynos_dp_clear_hotplug_interrupts(struct exynos_dp_device *dp) | ||
326 | { | ||
327 | u32 reg; | ||
328 | |||
329 | reg = HOTPLUG_CHG | HPD_LOST | PLUG; | ||
330 | writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4); | ||
331 | |||
332 | reg = INT_HPD; | ||
333 | writel(reg, dp->reg_base + EXYNOS_DP_INT_STA); | ||
334 | } | ||
335 | |||
336 | void exynos_dp_init_hpd(struct exynos_dp_device *dp) | ||
337 | { | ||
338 | u32 reg; | ||
339 | |||
340 | exynos_dp_clear_hotplug_interrupts(dp); | ||
341 | |||
342 | reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3); | ||
343 | reg &= ~(F_HPD | HPD_CTRL); | ||
344 | writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3); | ||
345 | } | ||
346 | |||
347 | enum dp_irq_type exynos_dp_get_irq_type(struct exynos_dp_device *dp) | ||
348 | { | ||
349 | u32 reg; | ||
350 | |||
351 | /* Parse hotplug interrupt status register */ | ||
352 | reg = readl(dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4); | ||
353 | |||
354 | if (reg & PLUG) | ||
355 | return DP_IRQ_TYPE_HP_CABLE_IN; | ||
356 | |||
357 | if (reg & HPD_LOST) | ||
358 | return DP_IRQ_TYPE_HP_CABLE_OUT; | ||
359 | |||
360 | if (reg & HOTPLUG_CHG) | ||
361 | return DP_IRQ_TYPE_HP_CHANGE; | ||
362 | |||
363 | return DP_IRQ_TYPE_UNKNOWN; | ||
364 | } | ||
365 | |||
366 | void exynos_dp_reset_aux(struct exynos_dp_device *dp) | ||
367 | { | ||
368 | u32 reg; | ||
369 | |||
370 | /* Disable AUX channel module */ | ||
371 | reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_2); | ||
372 | reg |= AUX_FUNC_EN_N; | ||
373 | writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2); | ||
374 | } | ||
375 | |||
376 | void exynos_dp_init_aux(struct exynos_dp_device *dp) | ||
377 | { | ||
378 | u32 reg; | ||
379 | |||
380 | /* Clear inerrupts related to AUX channel */ | ||
381 | reg = RPLY_RECEIV | AUX_ERR; | ||
382 | writel(reg, dp->reg_base + EXYNOS_DP_INT_STA); | ||
383 | |||
384 | exynos_dp_reset_aux(dp); | ||
385 | |||
386 | /* Disable AUX transaction H/W retry */ | ||
387 | reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) | AUX_HW_RETRY_COUNT_SEL(0)| | ||
388 | AUX_HW_RETRY_INTERVAL_600_MICROSECONDS; | ||
389 | writel(reg, dp->reg_base + EXYNOS_DP_AUX_HW_RETRY_CTL) ; | ||
390 | |||
391 | /* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */ | ||
392 | reg = DEFER_CTRL_EN | DEFER_COUNT(1); | ||
393 | writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_DEFER_CTL); | ||
394 | |||
395 | /* Enable AUX channel module */ | ||
396 | reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_2); | ||
397 | reg &= ~AUX_FUNC_EN_N; | ||
398 | writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2); | ||
399 | } | ||
400 | |||
401 | int exynos_dp_get_plug_in_status(struct exynos_dp_device *dp) | ||
402 | { | ||
403 | u32 reg; | ||
404 | |||
405 | reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3); | ||
406 | if (reg & HPD_STATUS) | ||
407 | return 0; | ||
408 | |||
409 | return -EINVAL; | ||
410 | } | ||
411 | |||
412 | void exynos_dp_enable_sw_function(struct exynos_dp_device *dp) | ||
413 | { | ||
414 | u32 reg; | ||
415 | |||
416 | reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_1); | ||
417 | reg &= ~SW_FUNC_EN_N; | ||
418 | writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1); | ||
419 | } | ||
420 | |||
421 | int exynos_dp_start_aux_transaction(struct exynos_dp_device *dp) | ||
422 | { | ||
423 | int reg; | ||
424 | int retval = 0; | ||
425 | int timeout_loop = 0; | ||
426 | |||
427 | /* Enable AUX CH operation */ | ||
428 | reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2); | ||
429 | reg |= AUX_EN; | ||
430 | writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2); | ||
431 | |||
432 | /* Is AUX CH command reply received? */ | ||
433 | reg = readl(dp->reg_base + EXYNOS_DP_INT_STA); | ||
434 | while (!(reg & RPLY_RECEIV)) { | ||
435 | timeout_loop++; | ||
436 | if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) { | ||
437 | dev_err(dp->dev, "AUX CH command reply failed!\n"); | ||
438 | return -ETIMEDOUT; | ||
439 | } | ||
440 | reg = readl(dp->reg_base + EXYNOS_DP_INT_STA); | ||
441 | usleep_range(10, 11); | ||
442 | } | ||
443 | |||
444 | /* Clear interrupt source for AUX CH command reply */ | ||
445 | writel(RPLY_RECEIV, dp->reg_base + EXYNOS_DP_INT_STA); | ||
446 | |||
447 | /* Clear interrupt source for AUX CH access error */ | ||
448 | reg = readl(dp->reg_base + EXYNOS_DP_INT_STA); | ||
449 | if (reg & AUX_ERR) { | ||
450 | writel(AUX_ERR, dp->reg_base + EXYNOS_DP_INT_STA); | ||
451 | return -EREMOTEIO; | ||
452 | } | ||
453 | |||
454 | /* Check AUX CH error access status */ | ||
455 | reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_STA); | ||
456 | if ((reg & AUX_STATUS_MASK) != 0) { | ||
457 | dev_err(dp->dev, "AUX CH error happens: %d\n\n", | ||
458 | reg & AUX_STATUS_MASK); | ||
459 | return -EREMOTEIO; | ||
460 | } | ||
461 | |||
462 | return retval; | ||
463 | } | ||
464 | |||
465 | int exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp, | ||
466 | unsigned int reg_addr, | ||
467 | unsigned char data) | ||
468 | { | ||
469 | u32 reg; | ||
470 | int i; | ||
471 | int retval; | ||
472 | |||
473 | for (i = 0; i < 3; i++) { | ||
474 | /* Clear AUX CH data buffer */ | ||
475 | reg = BUF_CLR; | ||
476 | writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); | ||
477 | |||
478 | /* Select DPCD device address */ | ||
479 | reg = AUX_ADDR_7_0(reg_addr); | ||
480 | writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0); | ||
481 | reg = AUX_ADDR_15_8(reg_addr); | ||
482 | writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8); | ||
483 | reg = AUX_ADDR_19_16(reg_addr); | ||
484 | writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16); | ||
485 | |||
486 | /* Write data buffer */ | ||
487 | reg = (unsigned int)data; | ||
488 | writel(reg, dp->reg_base + EXYNOS_DP_BUF_DATA_0); | ||
489 | |||
490 | /* | ||
491 | * Set DisplayPort transaction and write 1 byte | ||
492 | * If bit 3 is 1, DisplayPort transaction. | ||
493 | * If Bit 3 is 0, I2C transaction. | ||
494 | */ | ||
495 | reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE; | ||
496 | writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1); | ||
497 | |||
498 | /* Start AUX transaction */ | ||
499 | retval = exynos_dp_start_aux_transaction(dp); | ||
500 | if (retval == 0) | ||
501 | break; | ||
502 | else | ||
503 | dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", | ||
504 | __func__); | ||
505 | } | ||
506 | |||
507 | return retval; | ||
508 | } | ||
509 | |||
510 | int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp, | ||
511 | unsigned int reg_addr, | ||
512 | unsigned char *data) | ||
513 | { | ||
514 | u32 reg; | ||
515 | int i; | ||
516 | int retval; | ||
517 | |||
518 | for (i = 0; i < 3; i++) { | ||
519 | /* Clear AUX CH data buffer */ | ||
520 | reg = BUF_CLR; | ||
521 | writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); | ||
522 | |||
523 | /* Select DPCD device address */ | ||
524 | reg = AUX_ADDR_7_0(reg_addr); | ||
525 | writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0); | ||
526 | reg = AUX_ADDR_15_8(reg_addr); | ||
527 | writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8); | ||
528 | reg = AUX_ADDR_19_16(reg_addr); | ||
529 | writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16); | ||
530 | |||
531 | /* | ||
532 | * Set DisplayPort transaction and read 1 byte | ||
533 | * If bit 3 is 1, DisplayPort transaction. | ||
534 | * If Bit 3 is 0, I2C transaction. | ||
535 | */ | ||
536 | reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_READ; | ||
537 | writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1); | ||
538 | |||
539 | /* Start AUX transaction */ | ||
540 | retval = exynos_dp_start_aux_transaction(dp); | ||
541 | if (retval == 0) | ||
542 | break; | ||
543 | else | ||
544 | dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", | ||
545 | __func__); | ||
546 | } | ||
547 | |||
548 | /* Read data buffer */ | ||
549 | reg = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0); | ||
550 | *data = (unsigned char)(reg & 0xff); | ||
551 | |||
552 | return retval; | ||
553 | } | ||
554 | |||
555 | int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp, | ||
556 | unsigned int reg_addr, | ||
557 | unsigned int count, | ||
558 | unsigned char data[]) | ||
559 | { | ||
560 | u32 reg; | ||
561 | unsigned int start_offset; | ||
562 | unsigned int cur_data_count; | ||
563 | unsigned int cur_data_idx; | ||
564 | int i; | ||
565 | int retval = 0; | ||
566 | |||
567 | /* Clear AUX CH data buffer */ | ||
568 | reg = BUF_CLR; | ||
569 | writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); | ||
570 | |||
571 | start_offset = 0; | ||
572 | while (start_offset < count) { | ||
573 | /* Buffer size of AUX CH is 16 * 4bytes */ | ||
574 | if ((count - start_offset) > 16) | ||
575 | cur_data_count = 16; | ||
576 | else | ||
577 | cur_data_count = count - start_offset; | ||
578 | |||
579 | for (i = 0; i < 3; i++) { | ||
580 | /* Select DPCD device address */ | ||
581 | reg = AUX_ADDR_7_0(reg_addr + start_offset); | ||
582 | writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0); | ||
583 | reg = AUX_ADDR_15_8(reg_addr + start_offset); | ||
584 | writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8); | ||
585 | reg = AUX_ADDR_19_16(reg_addr + start_offset); | ||
586 | writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16); | ||
587 | |||
588 | for (cur_data_idx = 0; cur_data_idx < cur_data_count; | ||
589 | cur_data_idx++) { | ||
590 | reg = data[start_offset + cur_data_idx]; | ||
591 | writel(reg, dp->reg_base + EXYNOS_DP_BUF_DATA_0 | ||
592 | + 4 * cur_data_idx); | ||
593 | } | ||
594 | |||
595 | /* | ||
596 | * Set DisplayPort transaction and write | ||
597 | * If bit 3 is 1, DisplayPort transaction. | ||
598 | * If Bit 3 is 0, I2C transaction. | ||
599 | */ | ||
600 | reg = AUX_LENGTH(cur_data_count) | | ||
601 | AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE; | ||
602 | writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1); | ||
603 | |||
604 | /* Start AUX transaction */ | ||
605 | retval = exynos_dp_start_aux_transaction(dp); | ||
606 | if (retval == 0) | ||
607 | break; | ||
608 | else | ||
609 | dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", | ||
610 | __func__); | ||
611 | } | ||
612 | |||
613 | start_offset += cur_data_count; | ||
614 | } | ||
615 | |||
616 | return retval; | ||
617 | } | ||
618 | |||
619 | int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp, | ||
620 | unsigned int reg_addr, | ||
621 | unsigned int count, | ||
622 | unsigned char data[]) | ||
623 | { | ||
624 | u32 reg; | ||
625 | unsigned int start_offset; | ||
626 | unsigned int cur_data_count; | ||
627 | unsigned int cur_data_idx; | ||
628 | int i; | ||
629 | int retval = 0; | ||
630 | |||
631 | /* Clear AUX CH data buffer */ | ||
632 | reg = BUF_CLR; | ||
633 | writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); | ||
634 | |||
635 | start_offset = 0; | ||
636 | while (start_offset < count) { | ||
637 | /* Buffer size of AUX CH is 16 * 4bytes */ | ||
638 | if ((count - start_offset) > 16) | ||
639 | cur_data_count = 16; | ||
640 | else | ||
641 | cur_data_count = count - start_offset; | ||
642 | |||
643 | /* AUX CH Request Transaction process */ | ||
644 | for (i = 0; i < 3; i++) { | ||
645 | /* Select DPCD device address */ | ||
646 | reg = AUX_ADDR_7_0(reg_addr + start_offset); | ||
647 | writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0); | ||
648 | reg = AUX_ADDR_15_8(reg_addr + start_offset); | ||
649 | writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8); | ||
650 | reg = AUX_ADDR_19_16(reg_addr + start_offset); | ||
651 | writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16); | ||
652 | |||
653 | /* | ||
654 | * Set DisplayPort transaction and read | ||
655 | * If bit 3 is 1, DisplayPort transaction. | ||
656 | * If Bit 3 is 0, I2C transaction. | ||
657 | */ | ||
658 | reg = AUX_LENGTH(cur_data_count) | | ||
659 | AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_READ; | ||
660 | writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1); | ||
661 | |||
662 | /* Start AUX transaction */ | ||
663 | retval = exynos_dp_start_aux_transaction(dp); | ||
664 | if (retval == 0) | ||
665 | break; | ||
666 | else | ||
667 | dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", | ||
668 | __func__); | ||
669 | } | ||
670 | |||
671 | for (cur_data_idx = 0; cur_data_idx < cur_data_count; | ||
672 | cur_data_idx++) { | ||
673 | reg = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0 | ||
674 | + 4 * cur_data_idx); | ||
675 | data[start_offset + cur_data_idx] = | ||
676 | (unsigned char)reg; | ||
677 | } | ||
678 | |||
679 | start_offset += cur_data_count; | ||
680 | } | ||
681 | |||
682 | return retval; | ||
683 | } | ||
684 | |||
685 | int exynos_dp_select_i2c_device(struct exynos_dp_device *dp, | ||
686 | unsigned int device_addr, | ||
687 | unsigned int reg_addr) | ||
688 | { | ||
689 | u32 reg; | ||
690 | int retval; | ||
691 | |||
692 | /* Set EDID device address */ | ||
693 | reg = device_addr; | ||
694 | writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0); | ||
695 | writel(0x0, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8); | ||
696 | writel(0x0, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16); | ||
697 | |||
698 | /* Set offset from base address of EDID device */ | ||
699 | writel(reg_addr, dp->reg_base + EXYNOS_DP_BUF_DATA_0); | ||
700 | |||
701 | /* | ||
702 | * Set I2C transaction and write address | ||
703 | * If bit 3 is 1, DisplayPort transaction. | ||
704 | * If Bit 3 is 0, I2C transaction. | ||
705 | */ | ||
706 | reg = AUX_TX_COMM_I2C_TRANSACTION | AUX_TX_COMM_MOT | | ||
707 | AUX_TX_COMM_WRITE; | ||
708 | writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1); | ||
709 | |||
710 | /* Start AUX transaction */ | ||
711 | retval = exynos_dp_start_aux_transaction(dp); | ||
712 | if (retval != 0) | ||
713 | dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__); | ||
714 | |||
715 | return retval; | ||
716 | } | ||
717 | |||
718 | int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp, | ||
719 | unsigned int device_addr, | ||
720 | unsigned int reg_addr, | ||
721 | unsigned int *data) | ||
722 | { | ||
723 | u32 reg; | ||
724 | int i; | ||
725 | int retval; | ||
726 | |||
727 | for (i = 0; i < 3; i++) { | ||
728 | /* Clear AUX CH data buffer */ | ||
729 | reg = BUF_CLR; | ||
730 | writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); | ||
731 | |||
732 | /* Select EDID device */ | ||
733 | retval = exynos_dp_select_i2c_device(dp, device_addr, reg_addr); | ||
734 | if (retval != 0) | ||
735 | continue; | ||
736 | |||
737 | /* | ||
738 | * Set I2C transaction and read data | ||
739 | * If bit 3 is 1, DisplayPort transaction. | ||
740 | * If Bit 3 is 0, I2C transaction. | ||
741 | */ | ||
742 | reg = AUX_TX_COMM_I2C_TRANSACTION | | ||
743 | AUX_TX_COMM_READ; | ||
744 | writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1); | ||
745 | |||
746 | /* Start AUX transaction */ | ||
747 | retval = exynos_dp_start_aux_transaction(dp); | ||
748 | if (retval == 0) | ||
749 | break; | ||
750 | else | ||
751 | dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", | ||
752 | __func__); | ||
753 | } | ||
754 | |||
755 | /* Read data */ | ||
756 | if (retval == 0) | ||
757 | *data = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0); | ||
758 | |||
759 | return retval; | ||
760 | } | ||
761 | |||
762 | int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp, | ||
763 | unsigned int device_addr, | ||
764 | unsigned int reg_addr, | ||
765 | unsigned int count, | ||
766 | unsigned char edid[]) | ||
767 | { | ||
768 | u32 reg; | ||
769 | unsigned int i, j; | ||
770 | unsigned int cur_data_idx; | ||
771 | unsigned int defer = 0; | ||
772 | int retval = 0; | ||
773 | |||
774 | for (i = 0; i < count; i += 16) { | ||
775 | for (j = 0; j < 3; j++) { | ||
776 | /* Clear AUX CH data buffer */ | ||
777 | reg = BUF_CLR; | ||
778 | writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); | ||
779 | |||
780 | /* Set normal AUX CH command */ | ||
781 | reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2); | ||
782 | reg &= ~ADDR_ONLY; | ||
783 | writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2); | ||
784 | |||
785 | /* | ||
786 | * If Rx sends defer, Tx sends only reads | ||
787 | * request without sending address | ||
788 | */ | ||
789 | if (!defer) | ||
790 | retval = exynos_dp_select_i2c_device(dp, | ||
791 | device_addr, reg_addr + i); | ||
792 | else | ||
793 | defer = 0; | ||
794 | |||
795 | if (retval == 0) { | ||
796 | /* | ||
797 | * Set I2C transaction and write data | ||
798 | * If bit 3 is 1, DisplayPort transaction. | ||
799 | * If Bit 3 is 0, I2C transaction. | ||
800 | */ | ||
801 | reg = AUX_LENGTH(16) | | ||
802 | AUX_TX_COMM_I2C_TRANSACTION | | ||
803 | AUX_TX_COMM_READ; | ||
804 | writel(reg, dp->reg_base + | ||
805 | EXYNOS_DP_AUX_CH_CTL_1); | ||
806 | |||
807 | /* Start AUX transaction */ | ||
808 | retval = exynos_dp_start_aux_transaction(dp); | ||
809 | if (retval == 0) | ||
810 | break; | ||
811 | else | ||
812 | dev_dbg(dp->dev, | ||
813 | "%s: Aux Transaction fail!\n", | ||
814 | __func__); | ||
815 | } | ||
816 | /* Check if Rx sends defer */ | ||
817 | reg = readl(dp->reg_base + EXYNOS_DP_AUX_RX_COMM); | ||
818 | if (reg == AUX_RX_COMM_AUX_DEFER || | ||
819 | reg == AUX_RX_COMM_I2C_DEFER) { | ||
820 | dev_err(dp->dev, "Defer: %d\n\n", reg); | ||
821 | defer = 1; | ||
822 | } | ||
823 | } | ||
824 | |||
825 | for (cur_data_idx = 0; cur_data_idx < 16; cur_data_idx++) { | ||
826 | reg = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0 | ||
827 | + 4 * cur_data_idx); | ||
828 | edid[i + cur_data_idx] = (unsigned char)reg; | ||
829 | } | ||
830 | } | ||
831 | |||
832 | return retval; | ||
833 | } | ||
834 | |||
835 | void exynos_dp_set_link_bandwidth(struct exynos_dp_device *dp, u32 bwtype) | ||
836 | { | ||
837 | u32 reg; | ||
838 | |||
839 | reg = bwtype; | ||
840 | if ((bwtype == LINK_RATE_2_70GBPS) || (bwtype == LINK_RATE_1_62GBPS)) | ||
841 | writel(reg, dp->reg_base + EXYNOS_DP_LINK_BW_SET); | ||
842 | } | ||
843 | |||
844 | void exynos_dp_get_link_bandwidth(struct exynos_dp_device *dp, u32 *bwtype) | ||
845 | { | ||
846 | u32 reg; | ||
847 | |||
848 | reg = readl(dp->reg_base + EXYNOS_DP_LINK_BW_SET); | ||
849 | *bwtype = reg; | ||
850 | } | ||
851 | |||
852 | void exynos_dp_set_lane_count(struct exynos_dp_device *dp, u32 count) | ||
853 | { | ||
854 | u32 reg; | ||
855 | |||
856 | reg = count; | ||
857 | writel(reg, dp->reg_base + EXYNOS_DP_LANE_COUNT_SET); | ||
858 | } | ||
859 | |||
860 | void exynos_dp_get_lane_count(struct exynos_dp_device *dp, u32 *count) | ||
861 | { | ||
862 | u32 reg; | ||
863 | |||
864 | reg = readl(dp->reg_base + EXYNOS_DP_LANE_COUNT_SET); | ||
865 | *count = reg; | ||
866 | } | ||
867 | |||
868 | void exynos_dp_enable_enhanced_mode(struct exynos_dp_device *dp, bool enable) | ||
869 | { | ||
870 | u32 reg; | ||
871 | |||
872 | if (enable) { | ||
873 | reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4); | ||
874 | reg |= ENHANCED; | ||
875 | writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4); | ||
876 | } else { | ||
877 | reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4); | ||
878 | reg &= ~ENHANCED; | ||
879 | writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4); | ||
880 | } | ||
881 | } | ||
882 | |||
883 | void exynos_dp_set_training_pattern(struct exynos_dp_device *dp, | ||
884 | enum pattern_set pattern) | ||
885 | { | ||
886 | u32 reg; | ||
887 | |||
888 | switch (pattern) { | ||
889 | case PRBS7: | ||
890 | reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_PRBS7; | ||
891 | writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); | ||
892 | break; | ||
893 | case D10_2: | ||
894 | reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_D10_2; | ||
895 | writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); | ||
896 | break; | ||
897 | case TRAINING_PTN1: | ||
898 | reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN1; | ||
899 | writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); | ||
900 | break; | ||
901 | case TRAINING_PTN2: | ||
902 | reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN2; | ||
903 | writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); | ||
904 | break; | ||
905 | case DP_NONE: | ||
906 | reg = SCRAMBLING_ENABLE | | ||
907 | LINK_QUAL_PATTERN_SET_DISABLE | | ||
908 | SW_TRAINING_PATTERN_SET_NORMAL; | ||
909 | writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); | ||
910 | break; | ||
911 | default: | ||
912 | break; | ||
913 | } | ||
914 | } | ||
915 | |||
916 | void exynos_dp_set_lane0_pre_emphasis(struct exynos_dp_device *dp, u32 level) | ||
917 | { | ||
918 | u32 reg; | ||
919 | |||
920 | reg = readl(dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL); | ||
921 | reg &= ~PRE_EMPHASIS_SET_MASK; | ||
922 | reg |= level << PRE_EMPHASIS_SET_SHIFT; | ||
923 | writel(reg, dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL); | ||
924 | } | ||
925 | |||
926 | void exynos_dp_set_lane1_pre_emphasis(struct exynos_dp_device *dp, u32 level) | ||
927 | { | ||
928 | u32 reg; | ||
929 | |||
930 | reg = readl(dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL); | ||
931 | reg &= ~PRE_EMPHASIS_SET_MASK; | ||
932 | reg |= level << PRE_EMPHASIS_SET_SHIFT; | ||
933 | writel(reg, dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL); | ||
934 | } | ||
935 | |||
936 | void exynos_dp_set_lane2_pre_emphasis(struct exynos_dp_device *dp, u32 level) | ||
937 | { | ||
938 | u32 reg; | ||
939 | |||
940 | reg = readl(dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL); | ||
941 | reg &= ~PRE_EMPHASIS_SET_MASK; | ||
942 | reg |= level << PRE_EMPHASIS_SET_SHIFT; | ||
943 | writel(reg, dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL); | ||
944 | } | ||
945 | |||
946 | void exynos_dp_set_lane3_pre_emphasis(struct exynos_dp_device *dp, u32 level) | ||
947 | { | ||
948 | u32 reg; | ||
949 | |||
950 | reg = readl(dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL); | ||
951 | reg &= ~PRE_EMPHASIS_SET_MASK; | ||
952 | reg |= level << PRE_EMPHASIS_SET_SHIFT; | ||
953 | writel(reg, dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL); | ||
954 | } | ||
955 | |||
956 | void exynos_dp_set_lane0_link_training(struct exynos_dp_device *dp, | ||
957 | u32 training_lane) | ||
958 | { | ||
959 | u32 reg; | ||
960 | |||
961 | reg = training_lane; | ||
962 | writel(reg, dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL); | ||
963 | } | ||
964 | |||
965 | void exynos_dp_set_lane1_link_training(struct exynos_dp_device *dp, | ||
966 | u32 training_lane) | ||
967 | { | ||
968 | u32 reg; | ||
969 | |||
970 | reg = training_lane; | ||
971 | writel(reg, dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL); | ||
972 | } | ||
973 | |||
974 | void exynos_dp_set_lane2_link_training(struct exynos_dp_device *dp, | ||
975 | u32 training_lane) | ||
976 | { | ||
977 | u32 reg; | ||
978 | |||
979 | reg = training_lane; | ||
980 | writel(reg, dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL); | ||
981 | } | ||
982 | |||
983 | void exynos_dp_set_lane3_link_training(struct exynos_dp_device *dp, | ||
984 | u32 training_lane) | ||
985 | { | ||
986 | u32 reg; | ||
987 | |||
988 | reg = training_lane; | ||
989 | writel(reg, dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL); | ||
990 | } | ||
991 | |||
992 | u32 exynos_dp_get_lane0_link_training(struct exynos_dp_device *dp) | ||
993 | { | ||
994 | u32 reg; | ||
995 | |||
996 | reg = readl(dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL); | ||
997 | return reg; | ||
998 | } | ||
999 | |||
1000 | u32 exynos_dp_get_lane1_link_training(struct exynos_dp_device *dp) | ||
1001 | { | ||
1002 | u32 reg; | ||
1003 | |||
1004 | reg = readl(dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL); | ||
1005 | return reg; | ||
1006 | } | ||
1007 | |||
1008 | u32 exynos_dp_get_lane2_link_training(struct exynos_dp_device *dp) | ||
1009 | { | ||
1010 | u32 reg; | ||
1011 | |||
1012 | reg = readl(dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL); | ||
1013 | return reg; | ||
1014 | } | ||
1015 | |||
1016 | u32 exynos_dp_get_lane3_link_training(struct exynos_dp_device *dp) | ||
1017 | { | ||
1018 | u32 reg; | ||
1019 | |||
1020 | reg = readl(dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL); | ||
1021 | return reg; | ||
1022 | } | ||
1023 | |||
1024 | void exynos_dp_reset_macro(struct exynos_dp_device *dp) | ||
1025 | { | ||
1026 | u32 reg; | ||
1027 | |||
1028 | reg = readl(dp->reg_base + EXYNOS_DP_PHY_TEST); | ||
1029 | reg |= MACRO_RST; | ||
1030 | writel(reg, dp->reg_base + EXYNOS_DP_PHY_TEST); | ||
1031 | |||
1032 | /* 10 us is the minimum reset time. */ | ||
1033 | usleep_range(10, 20); | ||
1034 | |||
1035 | reg &= ~MACRO_RST; | ||
1036 | writel(reg, dp->reg_base + EXYNOS_DP_PHY_TEST); | ||
1037 | } | ||
1038 | |||
1039 | void exynos_dp_init_video(struct exynos_dp_device *dp) | ||
1040 | { | ||
1041 | u32 reg; | ||
1042 | |||
1043 | reg = VSYNC_DET | VID_FORMAT_CHG | VID_CLK_CHG; | ||
1044 | writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1); | ||
1045 | |||
1046 | reg = 0x0; | ||
1047 | writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_1); | ||
1048 | |||
1049 | reg = CHA_CRI(4) | CHA_CTRL; | ||
1050 | writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_2); | ||
1051 | |||
1052 | reg = 0x0; | ||
1053 | writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3); | ||
1054 | |||
1055 | reg = VID_HRES_TH(2) | VID_VRES_TH(0); | ||
1056 | writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_8); | ||
1057 | } | ||
1058 | |||
1059 | void exynos_dp_set_video_color_format(struct exynos_dp_device *dp) | ||
1060 | { | ||
1061 | u32 reg; | ||
1062 | |||
1063 | /* Configure the input color depth, color space, dynamic range */ | ||
1064 | reg = (dp->video_info->dynamic_range << IN_D_RANGE_SHIFT) | | ||
1065 | (dp->video_info->color_depth << IN_BPC_SHIFT) | | ||
1066 | (dp->video_info->color_space << IN_COLOR_F_SHIFT); | ||
1067 | writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_2); | ||
1068 | |||
1069 | /* Set Input Color YCbCr Coefficients to ITU601 or ITU709 */ | ||
1070 | reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_3); | ||
1071 | reg &= ~IN_YC_COEFFI_MASK; | ||
1072 | if (dp->video_info->ycbcr_coeff) | ||
1073 | reg |= IN_YC_COEFFI_ITU709; | ||
1074 | else | ||
1075 | reg |= IN_YC_COEFFI_ITU601; | ||
1076 | writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_3); | ||
1077 | } | ||
1078 | |||
1079 | int exynos_dp_is_slave_video_stream_clock_on(struct exynos_dp_device *dp) | ||
1080 | { | ||
1081 | u32 reg; | ||
1082 | |||
1083 | reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_1); | ||
1084 | writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_1); | ||
1085 | |||
1086 | reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_1); | ||
1087 | |||
1088 | if (!(reg & DET_STA)) { | ||
1089 | dev_dbg(dp->dev, "Input stream clock not detected.\n"); | ||
1090 | return -EINVAL; | ||
1091 | } | ||
1092 | |||
1093 | reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_2); | ||
1094 | writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_2); | ||
1095 | |||
1096 | reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_2); | ||
1097 | dev_dbg(dp->dev, "wait SYS_CTL_2.\n"); | ||
1098 | |||
1099 | if (reg & CHA_STA) { | ||
1100 | dev_dbg(dp->dev, "Input stream clk is changing\n"); | ||
1101 | return -EINVAL; | ||
1102 | } | ||
1103 | |||
1104 | return 0; | ||
1105 | } | ||
1106 | |||
1107 | void exynos_dp_set_video_cr_mn(struct exynos_dp_device *dp, | ||
1108 | enum clock_recovery_m_value_type type, | ||
1109 | u32 m_value, | ||
1110 | u32 n_value) | ||
1111 | { | ||
1112 | u32 reg; | ||
1113 | |||
1114 | if (type == REGISTER_M) { | ||
1115 | reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4); | ||
1116 | reg |= FIX_M_VID; | ||
1117 | writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4); | ||
1118 | reg = m_value & 0xff; | ||
1119 | writel(reg, dp->reg_base + EXYNOS_DP_M_VID_0); | ||
1120 | reg = (m_value >> 8) & 0xff; | ||
1121 | writel(reg, dp->reg_base + EXYNOS_DP_M_VID_1); | ||
1122 | reg = (m_value >> 16) & 0xff; | ||
1123 | writel(reg, dp->reg_base + EXYNOS_DP_M_VID_2); | ||
1124 | |||
1125 | reg = n_value & 0xff; | ||
1126 | writel(reg, dp->reg_base + EXYNOS_DP_N_VID_0); | ||
1127 | reg = (n_value >> 8) & 0xff; | ||
1128 | writel(reg, dp->reg_base + EXYNOS_DP_N_VID_1); | ||
1129 | reg = (n_value >> 16) & 0xff; | ||
1130 | writel(reg, dp->reg_base + EXYNOS_DP_N_VID_2); | ||
1131 | } else { | ||
1132 | reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4); | ||
1133 | reg &= ~FIX_M_VID; | ||
1134 | writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4); | ||
1135 | |||
1136 | writel(0x00, dp->reg_base + EXYNOS_DP_N_VID_0); | ||
1137 | writel(0x80, dp->reg_base + EXYNOS_DP_N_VID_1); | ||
1138 | writel(0x00, dp->reg_base + EXYNOS_DP_N_VID_2); | ||
1139 | } | ||
1140 | } | ||
1141 | |||
1142 | void exynos_dp_set_video_timing_mode(struct exynos_dp_device *dp, u32 type) | ||
1143 | { | ||
1144 | u32 reg; | ||
1145 | |||
1146 | if (type == VIDEO_TIMING_FROM_CAPTURE) { | ||
1147 | reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); | ||
1148 | reg &= ~FORMAT_SEL; | ||
1149 | writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); | ||
1150 | } else { | ||
1151 | reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); | ||
1152 | reg |= FORMAT_SEL; | ||
1153 | writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); | ||
1154 | } | ||
1155 | } | ||
1156 | |||
1157 | void exynos_dp_enable_video_master(struct exynos_dp_device *dp, bool enable) | ||
1158 | { | ||
1159 | u32 reg; | ||
1160 | |||
1161 | if (enable) { | ||
1162 | reg = readl(dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL); | ||
1163 | reg &= ~VIDEO_MODE_MASK; | ||
1164 | reg |= VIDEO_MASTER_MODE_EN | VIDEO_MODE_MASTER_MODE; | ||
1165 | writel(reg, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL); | ||
1166 | } else { | ||
1167 | reg = readl(dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL); | ||
1168 | reg &= ~VIDEO_MODE_MASK; | ||
1169 | reg |= VIDEO_MODE_SLAVE_MODE; | ||
1170 | writel(reg, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL); | ||
1171 | } | ||
1172 | } | ||
1173 | |||
1174 | void exynos_dp_start_video(struct exynos_dp_device *dp) | ||
1175 | { | ||
1176 | u32 reg; | ||
1177 | |||
1178 | reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); | ||
1179 | reg |= VIDEO_EN; | ||
1180 | writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); | ||
1181 | } | ||
1182 | |||
1183 | int exynos_dp_is_video_stream_on(struct exynos_dp_device *dp) | ||
1184 | { | ||
1185 | u32 reg; | ||
1186 | |||
1187 | reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3); | ||
1188 | writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3); | ||
1189 | |||
1190 | reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3); | ||
1191 | if (!(reg & STRM_VALID)) { | ||
1192 | dev_dbg(dp->dev, "Input video stream is not detected.\n"); | ||
1193 | return -EINVAL; | ||
1194 | } | ||
1195 | |||
1196 | return 0; | ||
1197 | } | ||
1198 | |||
1199 | void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp) | ||
1200 | { | ||
1201 | u32 reg; | ||
1202 | |||
1203 | reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_1); | ||
1204 | reg &= ~(MASTER_VID_FUNC_EN_N|SLAVE_VID_FUNC_EN_N); | ||
1205 | reg |= MASTER_VID_FUNC_EN_N; | ||
1206 | writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1); | ||
1207 | |||
1208 | reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); | ||
1209 | reg &= ~INTERACE_SCAN_CFG; | ||
1210 | reg |= (dp->video_info->interlaced << 2); | ||
1211 | writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); | ||
1212 | |||
1213 | reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); | ||
1214 | reg &= ~VSYNC_POLARITY_CFG; | ||
1215 | reg |= (dp->video_info->v_sync_polarity << 1); | ||
1216 | writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); | ||
1217 | |||
1218 | reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); | ||
1219 | reg &= ~HSYNC_POLARITY_CFG; | ||
1220 | reg |= (dp->video_info->h_sync_polarity << 0); | ||
1221 | writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); | ||
1222 | |||
1223 | reg = AUDIO_MODE_SPDIF_MODE | VIDEO_MODE_SLAVE_MODE; | ||
1224 | writel(reg, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL); | ||
1225 | } | ||
1226 | |||
1227 | void exynos_dp_enable_scrambling(struct exynos_dp_device *dp) | ||
1228 | { | ||
1229 | u32 reg; | ||
1230 | |||
1231 | reg = readl(dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); | ||
1232 | reg &= ~SCRAMBLING_DISABLE; | ||
1233 | writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); | ||
1234 | } | ||
1235 | |||
1236 | void exynos_dp_disable_scrambling(struct exynos_dp_device *dp) | ||
1237 | { | ||
1238 | u32 reg; | ||
1239 | |||
1240 | reg = readl(dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); | ||
1241 | reg |= SCRAMBLING_DISABLE; | ||
1242 | writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); | ||
1243 | } | ||
diff --git a/drivers/video/exynos/exynos_dp_reg.h b/drivers/video/exynos/exynos_dp_reg.h deleted file mode 100644 index 2e9bd0e0b9f2..000000000000 --- a/drivers/video/exynos/exynos_dp_reg.h +++ /dev/null | |||
@@ -1,366 +0,0 @@ | |||
1 | /* | ||
2 | * Register definition file for Samsung DP 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 | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #ifndef _EXYNOS_DP_REG_H | ||
13 | #define _EXYNOS_DP_REG_H | ||
14 | |||
15 | #define EXYNOS_DP_TX_SW_RESET 0x14 | ||
16 | #define EXYNOS_DP_FUNC_EN_1 0x18 | ||
17 | #define EXYNOS_DP_FUNC_EN_2 0x1C | ||
18 | #define EXYNOS_DP_VIDEO_CTL_1 0x20 | ||
19 | #define EXYNOS_DP_VIDEO_CTL_2 0x24 | ||
20 | #define EXYNOS_DP_VIDEO_CTL_3 0x28 | ||
21 | |||
22 | #define EXYNOS_DP_VIDEO_CTL_8 0x3C | ||
23 | #define EXYNOS_DP_VIDEO_CTL_10 0x44 | ||
24 | |||
25 | #define EXYNOS_DP_LANE_MAP 0x35C | ||
26 | |||
27 | #define EXYNOS_DP_ANALOG_CTL_1 0x370 | ||
28 | #define EXYNOS_DP_ANALOG_CTL_2 0x374 | ||
29 | #define EXYNOS_DP_ANALOG_CTL_3 0x378 | ||
30 | #define EXYNOS_DP_PLL_FILTER_CTL_1 0x37C | ||
31 | #define EXYNOS_DP_TX_AMP_TUNING_CTL 0x380 | ||
32 | |||
33 | #define EXYNOS_DP_AUX_HW_RETRY_CTL 0x390 | ||
34 | |||
35 | #define EXYNOS_DP_COMMON_INT_STA_1 0x3C4 | ||
36 | #define EXYNOS_DP_COMMON_INT_STA_2 0x3C8 | ||
37 | #define EXYNOS_DP_COMMON_INT_STA_3 0x3CC | ||
38 | #define EXYNOS_DP_COMMON_INT_STA_4 0x3D0 | ||
39 | #define EXYNOS_DP_INT_STA 0x3DC | ||
40 | #define EXYNOS_DP_COMMON_INT_MASK_1 0x3E0 | ||
41 | #define EXYNOS_DP_COMMON_INT_MASK_2 0x3E4 | ||
42 | #define EXYNOS_DP_COMMON_INT_MASK_3 0x3E8 | ||
43 | #define EXYNOS_DP_COMMON_INT_MASK_4 0x3EC | ||
44 | #define EXYNOS_DP_INT_STA_MASK 0x3F8 | ||
45 | #define EXYNOS_DP_INT_CTL 0x3FC | ||
46 | |||
47 | #define EXYNOS_DP_SYS_CTL_1 0x600 | ||
48 | #define EXYNOS_DP_SYS_CTL_2 0x604 | ||
49 | #define EXYNOS_DP_SYS_CTL_3 0x608 | ||
50 | #define EXYNOS_DP_SYS_CTL_4 0x60C | ||
51 | |||
52 | #define EXYNOS_DP_PKT_SEND_CTL 0x640 | ||
53 | #define EXYNOS_DP_HDCP_CTL 0x648 | ||
54 | |||
55 | #define EXYNOS_DP_LINK_BW_SET 0x680 | ||
56 | #define EXYNOS_DP_LANE_COUNT_SET 0x684 | ||
57 | #define EXYNOS_DP_TRAINING_PTN_SET 0x688 | ||
58 | #define EXYNOS_DP_LN0_LINK_TRAINING_CTL 0x68C | ||
59 | #define EXYNOS_DP_LN1_LINK_TRAINING_CTL 0x690 | ||
60 | #define EXYNOS_DP_LN2_LINK_TRAINING_CTL 0x694 | ||
61 | #define EXYNOS_DP_LN3_LINK_TRAINING_CTL 0x698 | ||
62 | |||
63 | #define EXYNOS_DP_DEBUG_CTL 0x6C0 | ||
64 | #define EXYNOS_DP_HPD_DEGLITCH_L 0x6C4 | ||
65 | #define EXYNOS_DP_HPD_DEGLITCH_H 0x6C8 | ||
66 | #define EXYNOS_DP_LINK_DEBUG_CTL 0x6E0 | ||
67 | |||
68 | #define EXYNOS_DP_M_VID_0 0x700 | ||
69 | #define EXYNOS_DP_M_VID_1 0x704 | ||
70 | #define EXYNOS_DP_M_VID_2 0x708 | ||
71 | #define EXYNOS_DP_N_VID_0 0x70C | ||
72 | #define EXYNOS_DP_N_VID_1 0x710 | ||
73 | #define EXYNOS_DP_N_VID_2 0x714 | ||
74 | |||
75 | #define EXYNOS_DP_PLL_CTL 0x71C | ||
76 | #define EXYNOS_DP_PHY_PD 0x720 | ||
77 | #define EXYNOS_DP_PHY_TEST 0x724 | ||
78 | |||
79 | #define EXYNOS_DP_VIDEO_FIFO_THRD 0x730 | ||
80 | #define EXYNOS_DP_AUDIO_MARGIN 0x73C | ||
81 | |||
82 | #define EXYNOS_DP_M_VID_GEN_FILTER_TH 0x764 | ||
83 | #define EXYNOS_DP_M_AUD_GEN_FILTER_TH 0x778 | ||
84 | #define EXYNOS_DP_AUX_CH_STA 0x780 | ||
85 | #define EXYNOS_DP_AUX_CH_DEFER_CTL 0x788 | ||
86 | #define EXYNOS_DP_AUX_RX_COMM 0x78C | ||
87 | #define EXYNOS_DP_BUFFER_DATA_CTL 0x790 | ||
88 | #define EXYNOS_DP_AUX_CH_CTL_1 0x794 | ||
89 | #define EXYNOS_DP_AUX_ADDR_7_0 0x798 | ||
90 | #define EXYNOS_DP_AUX_ADDR_15_8 0x79C | ||
91 | #define EXYNOS_DP_AUX_ADDR_19_16 0x7A0 | ||
92 | #define EXYNOS_DP_AUX_CH_CTL_2 0x7A4 | ||
93 | |||
94 | #define EXYNOS_DP_BUF_DATA_0 0x7C0 | ||
95 | |||
96 | #define EXYNOS_DP_SOC_GENERAL_CTL 0x800 | ||
97 | |||
98 | /* EXYNOS_DP_TX_SW_RESET */ | ||
99 | #define RESET_DP_TX (0x1 << 0) | ||
100 | |||
101 | /* EXYNOS_DP_FUNC_EN_1 */ | ||
102 | #define MASTER_VID_FUNC_EN_N (0x1 << 7) | ||
103 | #define SLAVE_VID_FUNC_EN_N (0x1 << 5) | ||
104 | #define AUD_FIFO_FUNC_EN_N (0x1 << 4) | ||
105 | #define AUD_FUNC_EN_N (0x1 << 3) | ||
106 | #define HDCP_FUNC_EN_N (0x1 << 2) | ||
107 | #define CRC_FUNC_EN_N (0x1 << 1) | ||
108 | #define SW_FUNC_EN_N (0x1 << 0) | ||
109 | |||
110 | /* EXYNOS_DP_FUNC_EN_2 */ | ||
111 | #define SSC_FUNC_EN_N (0x1 << 7) | ||
112 | #define AUX_FUNC_EN_N (0x1 << 2) | ||
113 | #define SERDES_FIFO_FUNC_EN_N (0x1 << 1) | ||
114 | #define LS_CLK_DOMAIN_FUNC_EN_N (0x1 << 0) | ||
115 | |||
116 | /* EXYNOS_DP_VIDEO_CTL_1 */ | ||
117 | #define VIDEO_EN (0x1 << 7) | ||
118 | #define HDCP_VIDEO_MUTE (0x1 << 6) | ||
119 | |||
120 | /* EXYNOS_DP_VIDEO_CTL_1 */ | ||
121 | #define IN_D_RANGE_MASK (0x1 << 7) | ||
122 | #define IN_D_RANGE_SHIFT (7) | ||
123 | #define IN_D_RANGE_CEA (0x1 << 7) | ||
124 | #define IN_D_RANGE_VESA (0x0 << 7) | ||
125 | #define IN_BPC_MASK (0x7 << 4) | ||
126 | #define IN_BPC_SHIFT (4) | ||
127 | #define IN_BPC_12_BITS (0x3 << 4) | ||
128 | #define IN_BPC_10_BITS (0x2 << 4) | ||
129 | #define IN_BPC_8_BITS (0x1 << 4) | ||
130 | #define IN_BPC_6_BITS (0x0 << 4) | ||
131 | #define IN_COLOR_F_MASK (0x3 << 0) | ||
132 | #define IN_COLOR_F_SHIFT (0) | ||
133 | #define IN_COLOR_F_YCBCR444 (0x2 << 0) | ||
134 | #define IN_COLOR_F_YCBCR422 (0x1 << 0) | ||
135 | #define IN_COLOR_F_RGB (0x0 << 0) | ||
136 | |||
137 | /* EXYNOS_DP_VIDEO_CTL_3 */ | ||
138 | #define IN_YC_COEFFI_MASK (0x1 << 7) | ||
139 | #define IN_YC_COEFFI_SHIFT (7) | ||
140 | #define IN_YC_COEFFI_ITU709 (0x1 << 7) | ||
141 | #define IN_YC_COEFFI_ITU601 (0x0 << 7) | ||
142 | #define VID_CHK_UPDATE_TYPE_MASK (0x1 << 4) | ||
143 | #define VID_CHK_UPDATE_TYPE_SHIFT (4) | ||
144 | #define VID_CHK_UPDATE_TYPE_1 (0x1 << 4) | ||
145 | #define VID_CHK_UPDATE_TYPE_0 (0x0 << 4) | ||
146 | |||
147 | /* EXYNOS_DP_VIDEO_CTL_8 */ | ||
148 | #define VID_HRES_TH(x) (((x) & 0xf) << 4) | ||
149 | #define VID_VRES_TH(x) (((x) & 0xf) << 0) | ||
150 | |||
151 | /* EXYNOS_DP_VIDEO_CTL_10 */ | ||
152 | #define FORMAT_SEL (0x1 << 4) | ||
153 | #define INTERACE_SCAN_CFG (0x1 << 2) | ||
154 | #define VSYNC_POLARITY_CFG (0x1 << 1) | ||
155 | #define HSYNC_POLARITY_CFG (0x1 << 0) | ||
156 | |||
157 | /* EXYNOS_DP_LANE_MAP */ | ||
158 | #define LANE3_MAP_LOGIC_LANE_0 (0x0 << 6) | ||
159 | #define LANE3_MAP_LOGIC_LANE_1 (0x1 << 6) | ||
160 | #define LANE3_MAP_LOGIC_LANE_2 (0x2 << 6) | ||
161 | #define LANE3_MAP_LOGIC_LANE_3 (0x3 << 6) | ||
162 | #define LANE2_MAP_LOGIC_LANE_0 (0x0 << 4) | ||
163 | #define LANE2_MAP_LOGIC_LANE_1 (0x1 << 4) | ||
164 | #define LANE2_MAP_LOGIC_LANE_2 (0x2 << 4) | ||
165 | #define LANE2_MAP_LOGIC_LANE_3 (0x3 << 4) | ||
166 | #define LANE1_MAP_LOGIC_LANE_0 (0x0 << 2) | ||
167 | #define LANE1_MAP_LOGIC_LANE_1 (0x1 << 2) | ||
168 | #define LANE1_MAP_LOGIC_LANE_2 (0x2 << 2) | ||
169 | #define LANE1_MAP_LOGIC_LANE_3 (0x3 << 2) | ||
170 | #define LANE0_MAP_LOGIC_LANE_0 (0x0 << 0) | ||
171 | #define LANE0_MAP_LOGIC_LANE_1 (0x1 << 0) | ||
172 | #define LANE0_MAP_LOGIC_LANE_2 (0x2 << 0) | ||
173 | #define LANE0_MAP_LOGIC_LANE_3 (0x3 << 0) | ||
174 | |||
175 | /* EXYNOS_DP_ANALOG_CTL_1 */ | ||
176 | #define TX_TERMINAL_CTRL_50_OHM (0x1 << 4) | ||
177 | |||
178 | /* EXYNOS_DP_ANALOG_CTL_2 */ | ||
179 | #define SEL_24M (0x1 << 3) | ||
180 | #define TX_DVDD_BIT_1_0625V (0x4 << 0) | ||
181 | |||
182 | /* EXYNOS_DP_ANALOG_CTL_3 */ | ||
183 | #define DRIVE_DVDD_BIT_1_0625V (0x4 << 5) | ||
184 | #define VCO_BIT_600_MICRO (0x5 << 0) | ||
185 | |||
186 | /* EXYNOS_DP_PLL_FILTER_CTL_1 */ | ||
187 | #define PD_RING_OSC (0x1 << 6) | ||
188 | #define AUX_TERMINAL_CTRL_50_OHM (0x2 << 4) | ||
189 | #define TX_CUR1_2X (0x1 << 2) | ||
190 | #define TX_CUR_16_MA (0x3 << 0) | ||
191 | |||
192 | /* EXYNOS_DP_TX_AMP_TUNING_CTL */ | ||
193 | #define CH3_AMP_400_MV (0x0 << 24) | ||
194 | #define CH2_AMP_400_MV (0x0 << 16) | ||
195 | #define CH1_AMP_400_MV (0x0 << 8) | ||
196 | #define CH0_AMP_400_MV (0x0 << 0) | ||
197 | |||
198 | /* EXYNOS_DP_AUX_HW_RETRY_CTL */ | ||
199 | #define AUX_BIT_PERIOD_EXPECTED_DELAY(x) (((x) & 0x7) << 8) | ||
200 | #define AUX_HW_RETRY_INTERVAL_MASK (0x3 << 3) | ||
201 | #define AUX_HW_RETRY_INTERVAL_600_MICROSECONDS (0x0 << 3) | ||
202 | #define AUX_HW_RETRY_INTERVAL_800_MICROSECONDS (0x1 << 3) | ||
203 | #define AUX_HW_RETRY_INTERVAL_1000_MICROSECONDS (0x2 << 3) | ||
204 | #define AUX_HW_RETRY_INTERVAL_1800_MICROSECONDS (0x3 << 3) | ||
205 | #define AUX_HW_RETRY_COUNT_SEL(x) (((x) & 0x7) << 0) | ||
206 | |||
207 | /* EXYNOS_DP_COMMON_INT_STA_1 */ | ||
208 | #define VSYNC_DET (0x1 << 7) | ||
209 | #define PLL_LOCK_CHG (0x1 << 6) | ||
210 | #define SPDIF_ERR (0x1 << 5) | ||
211 | #define SPDIF_UNSTBL (0x1 << 4) | ||
212 | #define VID_FORMAT_CHG (0x1 << 3) | ||
213 | #define AUD_CLK_CHG (0x1 << 2) | ||
214 | #define VID_CLK_CHG (0x1 << 1) | ||
215 | #define SW_INT (0x1 << 0) | ||
216 | |||
217 | /* EXYNOS_DP_COMMON_INT_STA_2 */ | ||
218 | #define ENC_EN_CHG (0x1 << 6) | ||
219 | #define HW_BKSV_RDY (0x1 << 3) | ||
220 | #define HW_SHA_DONE (0x1 << 2) | ||
221 | #define HW_AUTH_STATE_CHG (0x1 << 1) | ||
222 | #define HW_AUTH_DONE (0x1 << 0) | ||
223 | |||
224 | /* EXYNOS_DP_COMMON_INT_STA_3 */ | ||
225 | #define AFIFO_UNDER (0x1 << 7) | ||
226 | #define AFIFO_OVER (0x1 << 6) | ||
227 | #define R0_CHK_FLAG (0x1 << 5) | ||
228 | |||
229 | /* EXYNOS_DP_COMMON_INT_STA_4 */ | ||
230 | #define PSR_ACTIVE (0x1 << 7) | ||
231 | #define PSR_INACTIVE (0x1 << 6) | ||
232 | #define SPDIF_BI_PHASE_ERR (0x1 << 5) | ||
233 | #define HOTPLUG_CHG (0x1 << 2) | ||
234 | #define HPD_LOST (0x1 << 1) | ||
235 | #define PLUG (0x1 << 0) | ||
236 | |||
237 | /* EXYNOS_DP_INT_STA */ | ||
238 | #define INT_HPD (0x1 << 6) | ||
239 | #define HW_TRAINING_FINISH (0x1 << 5) | ||
240 | #define RPLY_RECEIV (0x1 << 1) | ||
241 | #define AUX_ERR (0x1 << 0) | ||
242 | |||
243 | /* EXYNOS_DP_INT_CTL */ | ||
244 | #define SOFT_INT_CTRL (0x1 << 2) | ||
245 | #define INT_POL1 (0x1 << 1) | ||
246 | #define INT_POL0 (0x1 << 0) | ||
247 | |||
248 | /* EXYNOS_DP_SYS_CTL_1 */ | ||
249 | #define DET_STA (0x1 << 2) | ||
250 | #define FORCE_DET (0x1 << 1) | ||
251 | #define DET_CTRL (0x1 << 0) | ||
252 | |||
253 | /* EXYNOS_DP_SYS_CTL_2 */ | ||
254 | #define CHA_CRI(x) (((x) & 0xf) << 4) | ||
255 | #define CHA_STA (0x1 << 2) | ||
256 | #define FORCE_CHA (0x1 << 1) | ||
257 | #define CHA_CTRL (0x1 << 0) | ||
258 | |||
259 | /* EXYNOS_DP_SYS_CTL_3 */ | ||
260 | #define HPD_STATUS (0x1 << 6) | ||
261 | #define F_HPD (0x1 << 5) | ||
262 | #define HPD_CTRL (0x1 << 4) | ||
263 | #define HDCP_RDY (0x1 << 3) | ||
264 | #define STRM_VALID (0x1 << 2) | ||
265 | #define F_VALID (0x1 << 1) | ||
266 | #define VALID_CTRL (0x1 << 0) | ||
267 | |||
268 | /* EXYNOS_DP_SYS_CTL_4 */ | ||
269 | #define FIX_M_AUD (0x1 << 4) | ||
270 | #define ENHANCED (0x1 << 3) | ||
271 | #define FIX_M_VID (0x1 << 2) | ||
272 | #define M_VID_UPDATE_CTRL (0x3 << 0) | ||
273 | |||
274 | /* EXYNOS_DP_TRAINING_PTN_SET */ | ||
275 | #define SCRAMBLER_TYPE (0x1 << 9) | ||
276 | #define HW_LINK_TRAINING_PATTERN (0x1 << 8) | ||
277 | #define SCRAMBLING_DISABLE (0x1 << 5) | ||
278 | #define SCRAMBLING_ENABLE (0x0 << 5) | ||
279 | #define LINK_QUAL_PATTERN_SET_MASK (0x3 << 2) | ||
280 | #define LINK_QUAL_PATTERN_SET_PRBS7 (0x3 << 2) | ||
281 | #define LINK_QUAL_PATTERN_SET_D10_2 (0x1 << 2) | ||
282 | #define LINK_QUAL_PATTERN_SET_DISABLE (0x0 << 2) | ||
283 | #define SW_TRAINING_PATTERN_SET_MASK (0x3 << 0) | ||
284 | #define SW_TRAINING_PATTERN_SET_PTN2 (0x2 << 0) | ||
285 | #define SW_TRAINING_PATTERN_SET_PTN1 (0x1 << 0) | ||
286 | #define SW_TRAINING_PATTERN_SET_NORMAL (0x0 << 0) | ||
287 | |||
288 | /* EXYNOS_DP_LN0_LINK_TRAINING_CTL */ | ||
289 | #define PRE_EMPHASIS_SET_MASK (0x3 << 3) | ||
290 | #define PRE_EMPHASIS_SET_SHIFT (3) | ||
291 | |||
292 | /* EXYNOS_DP_DEBUG_CTL */ | ||
293 | #define PLL_LOCK (0x1 << 4) | ||
294 | #define F_PLL_LOCK (0x1 << 3) | ||
295 | #define PLL_LOCK_CTRL (0x1 << 2) | ||
296 | #define PN_INV (0x1 << 0) | ||
297 | |||
298 | /* EXYNOS_DP_PLL_CTL */ | ||
299 | #define DP_PLL_PD (0x1 << 7) | ||
300 | #define DP_PLL_RESET (0x1 << 6) | ||
301 | #define DP_PLL_LOOP_BIT_DEFAULT (0x1 << 4) | ||
302 | #define DP_PLL_REF_BIT_1_1250V (0x5 << 0) | ||
303 | #define DP_PLL_REF_BIT_1_2500V (0x7 << 0) | ||
304 | |||
305 | /* EXYNOS_DP_PHY_PD */ | ||
306 | #define DP_PHY_PD (0x1 << 5) | ||
307 | #define AUX_PD (0x1 << 4) | ||
308 | #define CH3_PD (0x1 << 3) | ||
309 | #define CH2_PD (0x1 << 2) | ||
310 | #define CH1_PD (0x1 << 1) | ||
311 | #define CH0_PD (0x1 << 0) | ||
312 | |||
313 | /* EXYNOS_DP_PHY_TEST */ | ||
314 | #define MACRO_RST (0x1 << 5) | ||
315 | #define CH1_TEST (0x1 << 1) | ||
316 | #define CH0_TEST (0x1 << 0) | ||
317 | |||
318 | /* EXYNOS_DP_AUX_CH_STA */ | ||
319 | #define AUX_BUSY (0x1 << 4) | ||
320 | #define AUX_STATUS_MASK (0xf << 0) | ||
321 | |||
322 | /* EXYNOS_DP_AUX_CH_DEFER_CTL */ | ||
323 | #define DEFER_CTRL_EN (0x1 << 7) | ||
324 | #define DEFER_COUNT(x) (((x) & 0x7f) << 0) | ||
325 | |||
326 | /* EXYNOS_DP_AUX_RX_COMM */ | ||
327 | #define AUX_RX_COMM_I2C_DEFER (0x2 << 2) | ||
328 | #define AUX_RX_COMM_AUX_DEFER (0x2 << 0) | ||
329 | |||
330 | /* EXYNOS_DP_BUFFER_DATA_CTL */ | ||
331 | #define BUF_CLR (0x1 << 7) | ||
332 | #define BUF_DATA_COUNT(x) (((x) & 0x1f) << 0) | ||
333 | |||
334 | /* EXYNOS_DP_AUX_CH_CTL_1 */ | ||
335 | #define AUX_LENGTH(x) (((x - 1) & 0xf) << 4) | ||
336 | #define AUX_TX_COMM_MASK (0xf << 0) | ||
337 | #define AUX_TX_COMM_DP_TRANSACTION (0x1 << 3) | ||
338 | #define AUX_TX_COMM_I2C_TRANSACTION (0x0 << 3) | ||
339 | #define AUX_TX_COMM_MOT (0x1 << 2) | ||
340 | #define AUX_TX_COMM_WRITE (0x0 << 0) | ||
341 | #define AUX_TX_COMM_READ (0x1 << 0) | ||
342 | |||
343 | /* EXYNOS_DP_AUX_ADDR_7_0 */ | ||
344 | #define AUX_ADDR_7_0(x) (((x) >> 0) & 0xff) | ||
345 | |||
346 | /* EXYNOS_DP_AUX_ADDR_15_8 */ | ||
347 | #define AUX_ADDR_15_8(x) (((x) >> 8) & 0xff) | ||
348 | |||
349 | /* EXYNOS_DP_AUX_ADDR_19_16 */ | ||
350 | #define AUX_ADDR_19_16(x) (((x) >> 16) & 0x0f) | ||
351 | |||
352 | /* EXYNOS_DP_AUX_CH_CTL_2 */ | ||
353 | #define ADDR_ONLY (0x1 << 1) | ||
354 | #define AUX_EN (0x1 << 0) | ||
355 | |||
356 | /* EXYNOS_DP_SOC_GENERAL_CTL */ | ||
357 | #define AUDIO_MODE_SPDIF_MODE (0x1 << 8) | ||
358 | #define AUDIO_MODE_MASTER_MODE (0x0 << 8) | ||
359 | #define MASTER_VIDEO_INTERLACE_EN (0x1 << 4) | ||
360 | #define VIDEO_MASTER_CLK_SEL (0x1 << 2) | ||
361 | #define VIDEO_MASTER_MODE_EN (0x1 << 1) | ||
362 | #define VIDEO_MODE_MASK (0x1 << 0) | ||
363 | #define VIDEO_MODE_SLAVE_MODE (0x1 << 0) | ||
364 | #define VIDEO_MODE_MASTER_MODE (0x0 << 0) | ||
365 | |||
366 | #endif /* _EXYNOS_DP_REG_H */ | ||