]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/video/exynos/exynos_dp_reg.c
drivers/video/sunxvr2500.c: fix error return code
[mirror_ubuntu-bionic-kernel.git] / drivers / video / exynos / exynos_dp_reg.c
CommitLineData
e9474be4
JH
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 <video/exynos_dp.h>
18
e9474be4
JH
19#include "exynos_dp_core.h"
20#include "exynos_dp_reg.h"
21
22#define COMMON_INT_MASK_1 (0)
23#define COMMON_INT_MASK_2 (0)
24#define COMMON_INT_MASK_3 (0)
25#define COMMON_INT_MASK_4 (0)
26#define INT_STA_MASK (0)
27
28void exynos_dp_enable_video_mute(struct exynos_dp_device *dp, bool enable)
29{
30 u32 reg;
31
32 if (enable) {
33 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
34 reg |= HDCP_VIDEO_MUTE;
35 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
36 } else {
37 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
38 reg &= ~HDCP_VIDEO_MUTE;
39 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
40 }
41}
42
43void exynos_dp_stop_video(struct exynos_dp_device *dp)
44{
45 u32 reg;
46
47 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
48 reg &= ~VIDEO_EN;
49 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
50}
51
52void exynos_dp_lane_swap(struct exynos_dp_device *dp, bool enable)
53{
54 u32 reg;
55
56 if (enable)
57 reg = LANE3_MAP_LOGIC_LANE_0 | LANE2_MAP_LOGIC_LANE_1 |
58 LANE1_MAP_LOGIC_LANE_2 | LANE0_MAP_LOGIC_LANE_3;
59 else
60 reg = LANE3_MAP_LOGIC_LANE_3 | LANE2_MAP_LOGIC_LANE_2 |
61 LANE1_MAP_LOGIC_LANE_1 | LANE0_MAP_LOGIC_LANE_0;
62
63 writel(reg, dp->reg_base + EXYNOS_DP_LANE_MAP);
64}
65
8affaf5c
JH
66void exynos_dp_init_analog_param(struct exynos_dp_device *dp)
67{
68 u32 reg;
69
70 reg = TX_TERMINAL_CTRL_50_OHM;
71 writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_1);
72
73 reg = SEL_24M | TX_DVDD_BIT_1_0625V;
74 writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_2);
75
76 reg = DRIVE_DVDD_BIT_1_0625V | VCO_BIT_600_MICRO;
77 writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_3);
78
79 reg = PD_RING_OSC | AUX_TERMINAL_CTRL_50_OHM |
80 TX_CUR1_2X | TX_CUR_8_MA;
81 writel(reg, dp->reg_base + EXYNOS_DP_PLL_FILTER_CTL_1);
82
83 reg = CH3_AMP_400_MV | CH2_AMP_400_MV |
84 CH1_AMP_400_MV | CH0_AMP_400_MV;
85 writel(reg, dp->reg_base + EXYNOS_DP_TX_AMP_TUNING_CTL);
86}
87
e9474be4
JH
88void exynos_dp_init_interrupt(struct exynos_dp_device *dp)
89{
90 /* Set interrupt pin assertion polarity as high */
91 writel(INT_POL, dp->reg_base + EXYNOS_DP_INT_CTL);
92
93 /* Clear pending regisers */
94 writel(0xff, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1);
95 writel(0x4f, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_2);
96 writel(0xe0, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_3);
97 writel(0xe7, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4);
98 writel(0x63, dp->reg_base + EXYNOS_DP_INT_STA);
99
100 /* 0:mask,1: unmask */
101 writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_1);
102 writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_2);
103 writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_3);
104 writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_4);
105 writel(0x00, dp->reg_base + EXYNOS_DP_INT_STA_MASK);
106}
107
108void exynos_dp_reset(struct exynos_dp_device *dp)
109{
110 u32 reg;
111
e9474be4
JH
112 exynos_dp_stop_video(dp);
113 exynos_dp_enable_video_mute(dp, 0);
114
115 reg = MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N |
116 AUD_FIFO_FUNC_EN_N | AUD_FUNC_EN_N |
117 HDCP_FUNC_EN_N | SW_FUNC_EN_N;
118 writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1);
119
120 reg = SSC_FUNC_EN_N | AUX_FUNC_EN_N |
121 SERDES_FIFO_FUNC_EN_N |
122 LS_CLK_DOMAIN_FUNC_EN_N;
123 writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2);
124
a2c81bc1 125 usleep_range(20, 30);
e9474be4
JH
126
127 exynos_dp_lane_swap(dp, 0);
128
129 writel(0x0, dp->reg_base + EXYNOS_DP_SYS_CTL_1);
130 writel(0x40, dp->reg_base + EXYNOS_DP_SYS_CTL_2);
131 writel(0x0, dp->reg_base + EXYNOS_DP_SYS_CTL_3);
132 writel(0x0, dp->reg_base + EXYNOS_DP_SYS_CTL_4);
133
134 writel(0x0, dp->reg_base + EXYNOS_DP_PKT_SEND_CTL);
135 writel(0x0, dp->reg_base + EXYNOS_DP_HDCP_CTL);
136
137 writel(0x5e, dp->reg_base + EXYNOS_DP_HPD_DEGLITCH_L);
138 writel(0x1a, dp->reg_base + EXYNOS_DP_HPD_DEGLITCH_H);
139
140 writel(0x10, dp->reg_base + EXYNOS_DP_LINK_DEBUG_CTL);
141
142 writel(0x0, dp->reg_base + EXYNOS_DP_PHY_TEST);
143
144 writel(0x0, dp->reg_base + EXYNOS_DP_VIDEO_FIFO_THRD);
145 writel(0x20, dp->reg_base + EXYNOS_DP_AUDIO_MARGIN);
146
147 writel(0x4, dp->reg_base + EXYNOS_DP_M_VID_GEN_FILTER_TH);
148 writel(0x2, dp->reg_base + EXYNOS_DP_M_AUD_GEN_FILTER_TH);
149
150 writel(0x00000101, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
151
8affaf5c 152 exynos_dp_init_analog_param(dp);
e9474be4
JH
153 exynos_dp_init_interrupt(dp);
154}
155
24db03a8
JH
156void exynos_dp_swreset(struct exynos_dp_device *dp)
157{
158 writel(RESET_DP_TX, dp->reg_base + EXYNOS_DP_TX_SW_RESET);
159}
160
e9474be4
JH
161void exynos_dp_config_interrupt(struct exynos_dp_device *dp)
162{
163 u32 reg;
164
165 /* 0: mask, 1: unmask */
166 reg = COMMON_INT_MASK_1;
167 writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_1);
168
169 reg = COMMON_INT_MASK_2;
170 writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_2);
171
172 reg = COMMON_INT_MASK_3;
173 writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_3);
174
175 reg = COMMON_INT_MASK_4;
176 writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_4);
177
178 reg = INT_STA_MASK;
179 writel(reg, dp->reg_base + EXYNOS_DP_INT_STA_MASK);
180}
181
182u32 exynos_dp_get_pll_lock_status(struct exynos_dp_device *dp)
183{
184 u32 reg;
185
186 reg = readl(dp->reg_base + EXYNOS_DP_DEBUG_CTL);
187 if (reg & PLL_LOCK)
188 return PLL_LOCKED;
189 else
190 return PLL_UNLOCKED;
191}
192
193void exynos_dp_set_pll_power_down(struct exynos_dp_device *dp, bool enable)
194{
195 u32 reg;
196
197 if (enable) {
198 reg = readl(dp->reg_base + EXYNOS_DP_PLL_CTL);
199 reg |= DP_PLL_PD;
200 writel(reg, dp->reg_base + EXYNOS_DP_PLL_CTL);
201 } else {
202 reg = readl(dp->reg_base + EXYNOS_DP_PLL_CTL);
203 reg &= ~DP_PLL_PD;
204 writel(reg, dp->reg_base + EXYNOS_DP_PLL_CTL);
205 }
206}
207
208void exynos_dp_set_analog_power_down(struct exynos_dp_device *dp,
209 enum analog_power_block block,
210 bool enable)
211{
212 u32 reg;
213
214 switch (block) {
215 case AUX_BLOCK:
216 if (enable) {
217 reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
218 reg |= AUX_PD;
219 writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
220 } else {
221 reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
222 reg &= ~AUX_PD;
223 writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
224 }
225 break;
226 case CH0_BLOCK:
227 if (enable) {
228 reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
229 reg |= CH0_PD;
230 writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
231 } else {
232 reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
233 reg &= ~CH0_PD;
234 writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
235 }
236 break;
237 case CH1_BLOCK:
238 if (enable) {
239 reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
240 reg |= CH1_PD;
241 writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
242 } else {
243 reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
244 reg &= ~CH1_PD;
245 writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
246 }
247 break;
248 case CH2_BLOCK:
249 if (enable) {
250 reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
251 reg |= CH2_PD;
252 writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
253 } else {
254 reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
255 reg &= ~CH2_PD;
256 writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
257 }
258 break;
259 case CH3_BLOCK:
260 if (enable) {
261 reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
262 reg |= CH3_PD;
263 writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
264 } else {
265 reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
266 reg &= ~CH3_PD;
267 writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
268 }
269 break;
270 case ANALOG_TOTAL:
271 if (enable) {
272 reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
273 reg |= DP_PHY_PD;
274 writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
275 } else {
276 reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
277 reg &= ~DP_PHY_PD;
278 writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
279 }
280 break;
281 case POWER_ALL:
282 if (enable) {
283 reg = DP_PHY_PD | AUX_PD | CH3_PD | CH2_PD |
284 CH1_PD | CH0_PD;
285 writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
286 } else {
287 writel(0x00, dp->reg_base + EXYNOS_DP_PHY_PD);
288 }
289 break;
290 default:
291 break;
292 }
293}
294
295void exynos_dp_init_analog_func(struct exynos_dp_device *dp)
296{
297 u32 reg;
b5cfeed6 298 int timeout_loop = 0;
e9474be4
JH
299
300 exynos_dp_set_analog_power_down(dp, POWER_ALL, 0);
301
302 reg = PLL_LOCK_CHG;
303 writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1);
304
305 reg = readl(dp->reg_base + EXYNOS_DP_DEBUG_CTL);
306 reg &= ~(F_PLL_LOCK | PLL_LOCK_CTRL);
307 writel(reg, dp->reg_base + EXYNOS_DP_DEBUG_CTL);
308
309 /* Power up PLL */
b5cfeed6 310 if (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
e9474be4
JH
311 exynos_dp_set_pll_power_down(dp, 0);
312
b5cfeed6
JH
313 while (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
314 timeout_loop++;
315 if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
316 dev_err(dp->dev, "failed to get pll lock status\n");
317 return;
318 }
319 usleep_range(10, 20);
320 }
321 }
322
e9474be4
JH
323 /* Enable Serdes FIFO function and Link symbol clock domain module */
324 reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_2);
325 reg &= ~(SERDES_FIFO_FUNC_EN_N | LS_CLK_DOMAIN_FUNC_EN_N
326 | AUX_FUNC_EN_N);
327 writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2);
328}
329
330void exynos_dp_init_hpd(struct exynos_dp_device *dp)
331{
332 u32 reg;
333
334 reg = HOTPLUG_CHG | HPD_LOST | PLUG;
335 writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4);
336
337 reg = INT_HPD;
338 writel(reg, dp->reg_base + EXYNOS_DP_INT_STA);
339
340 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3);
341 reg &= ~(F_HPD | HPD_CTRL);
342 writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3);
343}
344
345void exynos_dp_reset_aux(struct exynos_dp_device *dp)
346{
347 u32 reg;
348
349 /* Disable AUX channel module */
350 reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_2);
351 reg |= AUX_FUNC_EN_N;
352 writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2);
353}
354
355void exynos_dp_init_aux(struct exynos_dp_device *dp)
356{
357 u32 reg;
358
359 /* Clear inerrupts related to AUX channel */
360 reg = RPLY_RECEIV | AUX_ERR;
361 writel(reg, dp->reg_base + EXYNOS_DP_INT_STA);
362
363 exynos_dp_reset_aux(dp);
364
365 /* Disable AUX transaction H/W retry */
366 reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) | AUX_HW_RETRY_COUNT_SEL(0)|
367 AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
368 writel(reg, dp->reg_base + EXYNOS_DP_AUX_HW_RETRY_CTL) ;
369
370 /* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */
371 reg = DEFER_CTRL_EN | DEFER_COUNT(1);
372 writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_DEFER_CTL);
373
374 /* Enable AUX channel module */
375 reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_2);
376 reg &= ~AUX_FUNC_EN_N;
377 writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2);
378}
379
380int exynos_dp_get_plug_in_status(struct exynos_dp_device *dp)
381{
382 u32 reg;
383
384 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3);
385 if (reg & HPD_STATUS)
386 return 0;
387
388 return -EINVAL;
389}
390
391void exynos_dp_enable_sw_function(struct exynos_dp_device *dp)
392{
393 u32 reg;
394
395 reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_1);
396 reg &= ~SW_FUNC_EN_N;
397 writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1);
398}
399
400int exynos_dp_start_aux_transaction(struct exynos_dp_device *dp)
401{
402 int reg;
403 int retval = 0;
bada5537 404 int timeout_loop = 0;
e9474be4
JH
405
406 /* Enable AUX CH operation */
407 reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2);
408 reg |= AUX_EN;
409 writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2);
410
411 /* Is AUX CH command reply received? */
412 reg = readl(dp->reg_base + EXYNOS_DP_INT_STA);
bada5537
JH
413 while (!(reg & RPLY_RECEIV)) {
414 timeout_loop++;
415 if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
416 dev_err(dp->dev, "AUX CH command reply failed!\n");
417 return -ETIMEDOUT;
418 }
e9474be4 419 reg = readl(dp->reg_base + EXYNOS_DP_INT_STA);
bada5537
JH
420 usleep_range(10, 11);
421 }
e9474be4
JH
422
423 /* Clear interrupt source for AUX CH command reply */
424 writel(RPLY_RECEIV, dp->reg_base + EXYNOS_DP_INT_STA);
425
426 /* Clear interrupt source for AUX CH access error */
427 reg = readl(dp->reg_base + EXYNOS_DP_INT_STA);
428 if (reg & AUX_ERR) {
429 writel(AUX_ERR, dp->reg_base + EXYNOS_DP_INT_STA);
430 return -EREMOTEIO;
431 }
432
433 /* Check AUX CH error access status */
434 reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_STA);
435 if ((reg & AUX_STATUS_MASK) != 0) {
436 dev_err(dp->dev, "AUX CH error happens: %d\n\n",
437 reg & AUX_STATUS_MASK);
438 return -EREMOTEIO;
439 }
440
441 return retval;
442}
443
444int exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp,
445 unsigned int reg_addr,
446 unsigned char data)
447{
448 u32 reg;
449 int i;
450 int retval;
451
452 for (i = 0; i < 3; i++) {
453 /* Clear AUX CH data buffer */
454 reg = BUF_CLR;
455 writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
456
457 /* Select DPCD device address */
458 reg = AUX_ADDR_7_0(reg_addr);
459 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
460 reg = AUX_ADDR_15_8(reg_addr);
461 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8);
462 reg = AUX_ADDR_19_16(reg_addr);
463 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16);
464
465 /* Write data buffer */
466 reg = (unsigned int)data;
467 writel(reg, dp->reg_base + EXYNOS_DP_BUF_DATA_0);
468
469 /*
470 * Set DisplayPort transaction and write 1 byte
471 * If bit 3 is 1, DisplayPort transaction.
472 * If Bit 3 is 0, I2C transaction.
473 */
474 reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE;
475 writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
476
477 /* Start AUX transaction */
478 retval = exynos_dp_start_aux_transaction(dp);
479 if (retval == 0)
480 break;
481 else
482 dev_err(dp->dev, "Aux Transaction fail!\n");
483 }
484
485 return retval;
486}
487
488int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
489 unsigned int reg_addr,
490 unsigned char *data)
491{
492 u32 reg;
493 int i;
494 int retval;
495
496 for (i = 0; i < 10; i++) {
497 /* Clear AUX CH data buffer */
498 reg = BUF_CLR;
499 writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
500
501 /* Select DPCD device address */
502 reg = AUX_ADDR_7_0(reg_addr);
503 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
504 reg = AUX_ADDR_15_8(reg_addr);
505 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8);
506 reg = AUX_ADDR_19_16(reg_addr);
507 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16);
508
509 /*
510 * Set DisplayPort transaction and read 1 byte
511 * If bit 3 is 1, DisplayPort transaction.
512 * If Bit 3 is 0, I2C transaction.
513 */
514 reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_READ;
515 writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
516
517 /* Start AUX transaction */
518 retval = exynos_dp_start_aux_transaction(dp);
519 if (retval == 0)
520 break;
521 else
522 dev_err(dp->dev, "Aux Transaction fail!\n");
523 }
524
525 /* Read data buffer */
526 reg = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0);
527 *data = (unsigned char)(reg & 0xff);
528
529 return retval;
530}
531
532int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
533 unsigned int reg_addr,
534 unsigned int count,
535 unsigned char data[])
536{
537 u32 reg;
538 unsigned int start_offset;
539 unsigned int cur_data_count;
540 unsigned int cur_data_idx;
541 int i;
542 int retval = 0;
543
544 /* Clear AUX CH data buffer */
545 reg = BUF_CLR;
546 writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
547
548 start_offset = 0;
549 while (start_offset < count) {
550 /* Buffer size of AUX CH is 16 * 4bytes */
551 if ((count - start_offset) > 16)
552 cur_data_count = 16;
553 else
554 cur_data_count = count - start_offset;
555
556 for (i = 0; i < 10; i++) {
557 /* Select DPCD device address */
558 reg = AUX_ADDR_7_0(reg_addr + start_offset);
559 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
560 reg = AUX_ADDR_15_8(reg_addr + start_offset);
561 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8);
562 reg = AUX_ADDR_19_16(reg_addr + start_offset);
563 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16);
564
565 for (cur_data_idx = 0; cur_data_idx < cur_data_count;
566 cur_data_idx++) {
567 reg = data[start_offset + cur_data_idx];
568 writel(reg, dp->reg_base + EXYNOS_DP_BUF_DATA_0
569 + 4 * cur_data_idx);
570 }
571
572 /*
573 * Set DisplayPort transaction and write
574 * If bit 3 is 1, DisplayPort transaction.
575 * If Bit 3 is 0, I2C transaction.
576 */
577 reg = AUX_LENGTH(cur_data_count) |
578 AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE;
579 writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
580
581 /* Start AUX transaction */
582 retval = exynos_dp_start_aux_transaction(dp);
583 if (retval == 0)
584 break;
585 else
586 dev_err(dp->dev, "Aux Transaction fail!\n");
587 }
588
589 start_offset += cur_data_count;
590 }
591
592 return retval;
593}
594
595int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp,
596 unsigned int reg_addr,
597 unsigned int count,
598 unsigned char data[])
599{
600 u32 reg;
601 unsigned int start_offset;
602 unsigned int cur_data_count;
603 unsigned int cur_data_idx;
604 int i;
605 int retval = 0;
606
607 /* Clear AUX CH data buffer */
608 reg = BUF_CLR;
609 writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
610
611 start_offset = 0;
612 while (start_offset < count) {
613 /* Buffer size of AUX CH is 16 * 4bytes */
614 if ((count - start_offset) > 16)
615 cur_data_count = 16;
616 else
617 cur_data_count = count - start_offset;
618
619 /* AUX CH Request Transaction process */
620 for (i = 0; i < 10; i++) {
621 /* Select DPCD device address */
622 reg = AUX_ADDR_7_0(reg_addr + start_offset);
623 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
624 reg = AUX_ADDR_15_8(reg_addr + start_offset);
625 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8);
626 reg = AUX_ADDR_19_16(reg_addr + start_offset);
627 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16);
628
629 /*
630 * Set DisplayPort transaction and read
631 * If bit 3 is 1, DisplayPort transaction.
632 * If Bit 3 is 0, I2C transaction.
633 */
634 reg = AUX_LENGTH(cur_data_count) |
635 AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_READ;
636 writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
637
638 /* Start AUX transaction */
639 retval = exynos_dp_start_aux_transaction(dp);
640 if (retval == 0)
641 break;
642 else
643 dev_err(dp->dev, "Aux Transaction fail!\n");
644 }
645
646 for (cur_data_idx = 0; cur_data_idx < cur_data_count;
647 cur_data_idx++) {
648 reg = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0
649 + 4 * cur_data_idx);
650 data[start_offset + cur_data_idx] =
651 (unsigned char)reg;
652 }
653
654 start_offset += cur_data_count;
655 }
656
657 return retval;
658}
659
660int exynos_dp_select_i2c_device(struct exynos_dp_device *dp,
661 unsigned int device_addr,
662 unsigned int reg_addr)
663{
664 u32 reg;
665 int retval;
666
667 /* Set EDID device address */
668 reg = device_addr;
669 writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
670 writel(0x0, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8);
671 writel(0x0, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16);
672
673 /* Set offset from base address of EDID device */
674 writel(reg_addr, dp->reg_base + EXYNOS_DP_BUF_DATA_0);
675
676 /*
677 * Set I2C transaction and write address
678 * If bit 3 is 1, DisplayPort transaction.
679 * If Bit 3 is 0, I2C transaction.
680 */
681 reg = AUX_TX_COMM_I2C_TRANSACTION | AUX_TX_COMM_MOT |
682 AUX_TX_COMM_WRITE;
683 writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
684
685 /* Start AUX transaction */
686 retval = exynos_dp_start_aux_transaction(dp);
687 if (retval != 0)
688 dev_err(dp->dev, "Aux Transaction fail!\n");
689
690 return retval;
691}
692
693int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
694 unsigned int device_addr,
695 unsigned int reg_addr,
696 unsigned int *data)
697{
698 u32 reg;
699 int i;
700 int retval;
701
702 for (i = 0; i < 10; i++) {
703 /* Clear AUX CH data buffer */
704 reg = BUF_CLR;
705 writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
706
707 /* Select EDID device */
708 retval = exynos_dp_select_i2c_device(dp, device_addr, reg_addr);
709 if (retval != 0) {
710 dev_err(dp->dev, "Select EDID device fail!\n");
711 continue;
712 }
713
714 /*
715 * Set I2C transaction and read data
716 * If bit 3 is 1, DisplayPort transaction.
717 * If Bit 3 is 0, I2C transaction.
718 */
719 reg = AUX_TX_COMM_I2C_TRANSACTION |
720 AUX_TX_COMM_READ;
721 writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
722
723 /* Start AUX transaction */
724 retval = exynos_dp_start_aux_transaction(dp);
725 if (retval == 0)
726 break;
727 else
728 dev_err(dp->dev, "Aux Transaction fail!\n");
729 }
730
731 /* Read data */
732 if (retval == 0)
733 *data = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0);
734
735 return retval;
736}
737
738int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
739 unsigned int device_addr,
740 unsigned int reg_addr,
741 unsigned int count,
742 unsigned char edid[])
743{
744 u32 reg;
745 unsigned int i, j;
746 unsigned int cur_data_idx;
747 unsigned int defer = 0;
748 int retval = 0;
749
750 for (i = 0; i < count; i += 16) {
751 for (j = 0; j < 100; j++) {
752 /* Clear AUX CH data buffer */
753 reg = BUF_CLR;
754 writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
755
756 /* Set normal AUX CH command */
757 reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2);
758 reg &= ~ADDR_ONLY;
759 writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2);
760
761 /*
762 * If Rx sends defer, Tx sends only reads
ff0c2642 763 * request without sending address
e9474be4
JH
764 */
765 if (!defer)
766 retval = exynos_dp_select_i2c_device(dp,
767 device_addr, reg_addr + i);
768 else
769 defer = 0;
770
771 if (retval == 0) {
772 /*
773 * Set I2C transaction and write data
774 * If bit 3 is 1, DisplayPort transaction.
775 * If Bit 3 is 0, I2C transaction.
776 */
777 reg = AUX_LENGTH(16) |
778 AUX_TX_COMM_I2C_TRANSACTION |
779 AUX_TX_COMM_READ;
780 writel(reg, dp->reg_base +
781 EXYNOS_DP_AUX_CH_CTL_1);
782
783 /* Start AUX transaction */
784 retval = exynos_dp_start_aux_transaction(dp);
785 if (retval == 0)
786 break;
787 else
788 dev_err(dp->dev, "Aux Transaction fail!\n");
789 }
790 /* Check if Rx sends defer */
791 reg = readl(dp->reg_base + EXYNOS_DP_AUX_RX_COMM);
792 if (reg == AUX_RX_COMM_AUX_DEFER ||
793 reg == AUX_RX_COMM_I2C_DEFER) {
794 dev_err(dp->dev, "Defer: %d\n\n", reg);
795 defer = 1;
796 }
797 }
798
799 for (cur_data_idx = 0; cur_data_idx < 16; cur_data_idx++) {
800 reg = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0
801 + 4 * cur_data_idx);
802 edid[i + cur_data_idx] = (unsigned char)reg;
803 }
804 }
805
806 return retval;
807}
808
809void exynos_dp_set_link_bandwidth(struct exynos_dp_device *dp, u32 bwtype)
810{
811 u32 reg;
812
813 reg = bwtype;
814 if ((bwtype == LINK_RATE_2_70GBPS) || (bwtype == LINK_RATE_1_62GBPS))
815 writel(reg, dp->reg_base + EXYNOS_DP_LINK_BW_SET);
816}
817
818void exynos_dp_get_link_bandwidth(struct exynos_dp_device *dp, u32 *bwtype)
819{
820 u32 reg;
821
822 reg = readl(dp->reg_base + EXYNOS_DP_LINK_BW_SET);
823 *bwtype = reg;
824}
825
826void exynos_dp_set_lane_count(struct exynos_dp_device *dp, u32 count)
827{
828 u32 reg;
829
830 reg = count;
831 writel(reg, dp->reg_base + EXYNOS_DP_LANE_COUNT_SET);
832}
833
834void exynos_dp_get_lane_count(struct exynos_dp_device *dp, u32 *count)
835{
836 u32 reg;
837
838 reg = readl(dp->reg_base + EXYNOS_DP_LANE_COUNT_SET);
839 *count = reg;
840}
841
842void exynos_dp_enable_enhanced_mode(struct exynos_dp_device *dp, bool enable)
843{
844 u32 reg;
845
846 if (enable) {
847 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4);
848 reg |= ENHANCED;
849 writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4);
850 } else {
851 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4);
852 reg &= ~ENHANCED;
853 writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4);
854 }
855}
856
857void exynos_dp_set_training_pattern(struct exynos_dp_device *dp,
858 enum pattern_set pattern)
859{
860 u32 reg;
861
862 switch (pattern) {
863 case PRBS7:
864 reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_PRBS7;
865 writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
866 break;
867 case D10_2:
868 reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_D10_2;
869 writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
870 break;
871 case TRAINING_PTN1:
872 reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN1;
873 writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
874 break;
875 case TRAINING_PTN2:
876 reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN2;
877 writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
878 break;
879 case DP_NONE:
880 reg = SCRAMBLING_ENABLE |
881 LINK_QUAL_PATTERN_SET_DISABLE |
882 SW_TRAINING_PATTERN_SET_NORMAL;
883 writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
884 break;
885 default:
886 break;
887 }
888}
889
890void exynos_dp_set_lane0_pre_emphasis(struct exynos_dp_device *dp, u32 level)
891{
892 u32 reg;
893
894 reg = level << PRE_EMPHASIS_SET_SHIFT;
895 writel(reg, dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL);
896}
897
898void exynos_dp_set_lane1_pre_emphasis(struct exynos_dp_device *dp, u32 level)
899{
900 u32 reg;
901
902 reg = level << PRE_EMPHASIS_SET_SHIFT;
903 writel(reg, dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL);
904}
905
906void exynos_dp_set_lane2_pre_emphasis(struct exynos_dp_device *dp, u32 level)
907{
908 u32 reg;
909
910 reg = level << PRE_EMPHASIS_SET_SHIFT;
911 writel(reg, dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL);
912}
913
914void exynos_dp_set_lane3_pre_emphasis(struct exynos_dp_device *dp, u32 level)
915{
916 u32 reg;
917
918 reg = level << PRE_EMPHASIS_SET_SHIFT;
919 writel(reg, dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL);
920}
921
922void exynos_dp_set_lane0_link_training(struct exynos_dp_device *dp,
923 u32 training_lane)
924{
925 u32 reg;
926
927 reg = training_lane;
928 writel(reg, dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL);
929}
930
931void exynos_dp_set_lane1_link_training(struct exynos_dp_device *dp,
932 u32 training_lane)
933{
934 u32 reg;
935
936 reg = training_lane;
937 writel(reg, dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL);
938}
939
940void exynos_dp_set_lane2_link_training(struct exynos_dp_device *dp,
941 u32 training_lane)
942{
943 u32 reg;
944
945 reg = training_lane;
946 writel(reg, dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL);
947}
948
949void exynos_dp_set_lane3_link_training(struct exynos_dp_device *dp,
950 u32 training_lane)
951{
952 u32 reg;
953
954 reg = training_lane;
955 writel(reg, dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL);
956}
957
958u32 exynos_dp_get_lane0_link_training(struct exynos_dp_device *dp)
959{
960 u32 reg;
961
962 reg = readl(dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL);
963 return reg;
964}
965
966u32 exynos_dp_get_lane1_link_training(struct exynos_dp_device *dp)
967{
968 u32 reg;
969
970 reg = readl(dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL);
971 return reg;
972}
973
974u32 exynos_dp_get_lane2_link_training(struct exynos_dp_device *dp)
975{
976 u32 reg;
977
978 reg = readl(dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL);
979 return reg;
980}
981
982u32 exynos_dp_get_lane3_link_training(struct exynos_dp_device *dp)
983{
984 u32 reg;
985
986 reg = readl(dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL);
987 return reg;
988}
989
990void exynos_dp_reset_macro(struct exynos_dp_device *dp)
991{
992 u32 reg;
993
994 reg = readl(dp->reg_base + EXYNOS_DP_PHY_TEST);
995 reg |= MACRO_RST;
996 writel(reg, dp->reg_base + EXYNOS_DP_PHY_TEST);
997
998 /* 10 us is the minimum reset time. */
a2c81bc1 999 usleep_range(10, 20);
e9474be4
JH
1000
1001 reg &= ~MACRO_RST;
1002 writel(reg, dp->reg_base + EXYNOS_DP_PHY_TEST);
1003}
1004
1005int exynos_dp_init_video(struct exynos_dp_device *dp)
1006{
1007 u32 reg;
1008
1009 reg = VSYNC_DET | VID_FORMAT_CHG | VID_CLK_CHG;
1010 writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1);
1011
1012 reg = 0x0;
1013 writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_1);
1014
1015 reg = CHA_CRI(4) | CHA_CTRL;
1016 writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_2);
1017
1018 reg = 0x0;
1019 writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3);
1020
1021 reg = VID_HRES_TH(2) | VID_VRES_TH(0);
1022 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_8);
1023
1024 return 0;
1025}
1026
1027void exynos_dp_set_video_color_format(struct exynos_dp_device *dp,
1028 u32 color_depth,
1029 u32 color_space,
1030 u32 dynamic_range,
1031 u32 ycbcr_coeff)
1032{
1033 u32 reg;
1034
1035 /* Configure the input color depth, color space, dynamic range */
1036 reg = (dynamic_range << IN_D_RANGE_SHIFT) |
1037 (color_depth << IN_BPC_SHIFT) |
1038 (color_space << IN_COLOR_F_SHIFT);
1039 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_2);
1040
1041 /* Set Input Color YCbCr Coefficients to ITU601 or ITU709 */
1042 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_3);
1043 reg &= ~IN_YC_COEFFI_MASK;
1044 if (ycbcr_coeff)
1045 reg |= IN_YC_COEFFI_ITU709;
1046 else
1047 reg |= IN_YC_COEFFI_ITU601;
1048 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_3);
1049}
1050
1051int exynos_dp_is_slave_video_stream_clock_on(struct exynos_dp_device *dp)
1052{
1053 u32 reg;
1054
1055 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_1);
1056 writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_1);
1057
1058 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_1);
1059
1060 if (!(reg & DET_STA)) {
1061 dev_dbg(dp->dev, "Input stream clock not detected.\n");
1062 return -EINVAL;
1063 }
1064
1065 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_2);
1066 writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_2);
1067
1068 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_2);
1069 dev_dbg(dp->dev, "wait SYS_CTL_2.\n");
1070
1071 if (reg & CHA_STA) {
1072 dev_dbg(dp->dev, "Input stream clk is changing\n");
1073 return -EINVAL;
1074 }
1075
1076 return 0;
1077}
1078
1079void exynos_dp_set_video_cr_mn(struct exynos_dp_device *dp,
1080 enum clock_recovery_m_value_type type,
1081 u32 m_value,
1082 u32 n_value)
1083{
1084 u32 reg;
1085
1086 if (type == REGISTER_M) {
1087 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4);
1088 reg |= FIX_M_VID;
1089 writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4);
1090 reg = m_value & 0xff;
1091 writel(reg, dp->reg_base + EXYNOS_DP_M_VID_0);
1092 reg = (m_value >> 8) & 0xff;
1093 writel(reg, dp->reg_base + EXYNOS_DP_M_VID_1);
1094 reg = (m_value >> 16) & 0xff;
1095 writel(reg, dp->reg_base + EXYNOS_DP_M_VID_2);
1096
1097 reg = n_value & 0xff;
1098 writel(reg, dp->reg_base + EXYNOS_DP_N_VID_0);
1099 reg = (n_value >> 8) & 0xff;
1100 writel(reg, dp->reg_base + EXYNOS_DP_N_VID_1);
1101 reg = (n_value >> 16) & 0xff;
1102 writel(reg, dp->reg_base + EXYNOS_DP_N_VID_2);
1103 } else {
1104 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4);
1105 reg &= ~FIX_M_VID;
1106 writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4);
1107
1108 writel(0x00, dp->reg_base + EXYNOS_DP_N_VID_0);
1109 writel(0x80, dp->reg_base + EXYNOS_DP_N_VID_1);
1110 writel(0x00, dp->reg_base + EXYNOS_DP_N_VID_2);
1111 }
1112}
1113
1114void exynos_dp_set_video_timing_mode(struct exynos_dp_device *dp, u32 type)
1115{
1116 u32 reg;
1117
1118 if (type == VIDEO_TIMING_FROM_CAPTURE) {
1119 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
1120 reg &= ~FORMAT_SEL;
1121 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
1122 } else {
1123 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
1124 reg |= FORMAT_SEL;
1125 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
1126 }
1127}
1128
1129void exynos_dp_enable_video_master(struct exynos_dp_device *dp, bool enable)
1130{
1131 u32 reg;
1132
1133 if (enable) {
1134 reg = readl(dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
1135 reg &= ~VIDEO_MODE_MASK;
1136 reg |= VIDEO_MASTER_MODE_EN | VIDEO_MODE_MASTER_MODE;
1137 writel(reg, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
1138 } else {
1139 reg = readl(dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
1140 reg &= ~VIDEO_MODE_MASK;
1141 reg |= VIDEO_MODE_SLAVE_MODE;
1142 writel(reg, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
1143 }
1144}
1145
1146void exynos_dp_start_video(struct exynos_dp_device *dp)
1147{
1148 u32 reg;
1149
1150 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
1151 reg |= VIDEO_EN;
1152 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
1153}
1154
1155int exynos_dp_is_video_stream_on(struct exynos_dp_device *dp)
1156{
1157 u32 reg;
1158
1159 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3);
1160 writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3);
1161
1162 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3);
1163 if (!(reg & STRM_VALID)) {
1164 dev_dbg(dp->dev, "Input video stream is not detected.\n");
1165 return -EINVAL;
1166 }
1167
1168 return 0;
1169}
1170
1171void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp,
1172 struct video_info *video_info)
1173{
1174 u32 reg;
1175
1176 reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_1);
1177 reg &= ~(MASTER_VID_FUNC_EN_N|SLAVE_VID_FUNC_EN_N);
1178 reg |= MASTER_VID_FUNC_EN_N;
1179 writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1);
1180
1181 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
1182 reg &= ~INTERACE_SCAN_CFG;
1183 reg |= (video_info->interlaced << 2);
1184 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
1185
1186 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
1187 reg &= ~VSYNC_POLARITY_CFG;
1188 reg |= (video_info->v_sync_polarity << 1);
1189 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
1190
1191 reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
1192 reg &= ~HSYNC_POLARITY_CFG;
1193 reg |= (video_info->h_sync_polarity << 0);
1194 writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
1195
1196 reg = AUDIO_MODE_SPDIF_MODE | VIDEO_MODE_SLAVE_MODE;
1197 writel(reg, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
1198}
1199
1200void exynos_dp_enable_scrambling(struct exynos_dp_device *dp)
1201{
1202 u32 reg;
1203
1204 reg = readl(dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
1205 reg &= ~SCRAMBLING_DISABLE;
1206 writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
1207}
1208
1209void exynos_dp_disable_scrambling(struct exynos_dp_device *dp)
1210{
1211 u32 reg;
1212
1213 reg = readl(dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
1214 reg |= SCRAMBLING_DISABLE;
1215 writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
1216}