1 /* SPDX-License-Identifier: GPL-2.0-only */
3 /* Samsung DP (Display port) register interface driver. */
5 #include <device/mmio.h>
6 #include <console/console.h>
11 #include <soc/dp-core.h>
13 #include <soc/periph.h>
16 void s5p_dp_reset(struct s5p_dp_device
*dp
)
19 struct exynos5_dp
*base
= dp
->base
;
21 write32(&base
->dp_tx_sw_reset
, RESET_DP_TX
);
24 clrbits32(&base
->video_ctl_1
, VIDEO_EN
);
25 clrbits32(&base
->video_ctl_1
, HDCP_VIDEO_MUTE
);
27 reg
= MASTER_VID_FUNC_EN_N
| SLAVE_VID_FUNC_EN_N
|
28 AUD_FIFO_FUNC_EN_N
| AUD_FUNC_EN_N
|
29 HDCP_FUNC_EN_N
| SW_FUNC_EN_N
;
30 write32(&base
->func_en_1
, reg
);
32 reg
= SSC_FUNC_EN_N
| AUX_FUNC_EN_N
|
33 SERDES_FIFO_FUNC_EN_N
|
34 LS_CLK_DOMAIN_FUNC_EN_N
;
35 write32(&base
->func_en_2
, reg
);
39 reg
= LANE3_MAP_LOGIC_LANE_3
| LANE2_MAP_LOGIC_LANE_2
|
40 LANE1_MAP_LOGIC_LANE_1
| LANE0_MAP_LOGIC_LANE_0
;
42 write32(&base
->lane_map
, reg
);
44 write32(&base
->sys_ctl_1
, 0x0);
45 write32(&base
->sys_ctl_2
, 0x40);
46 write32(&base
->sys_ctl_3
, 0x0);
47 write32(&base
->sys_ctl_4
, 0x0);
49 write32(&base
->pkt_send_ctl
, 0x0);
50 write32(&base
->dp_hdcp_ctl
, 0x0);
52 write32(&base
->dp_hpd_deglitch_l
, 0x5e);
53 write32(&base
->dp_hpd_deglitch_h
, 0x1a);
55 write32(&base
->dp_debug_ctl
, 0x10);
57 write32(&base
->dp_phy_test
, 0x0);
59 write32(&base
->dp_video_fifo_thrd
, 0x0);
60 write32(&base
->dp_audio_margin
, 0x20);
62 write32(&base
->m_vid_gen_filter_th
, 0x4);
63 write32(&base
->m_aud_gen_filter_th
, 0x2);
65 write32(&base
->soc_general_ctl
, 0x00000101);
67 /* Set Analog Parameters */
68 write32(&base
->analog_ctl_1
, 0x10);
69 write32(&base
->analog_ctl_2
, 0x0C);
70 write32(&base
->analog_ctl_3
, 0x85);
71 write32(&base
->pll_filter_ctl_1
, 0x66);
72 write32(&base
->tx_amp_tuning_ctl
, 0x0);
74 /* Set interrupt pin assertion polarity as high */
75 write32(&base
->int_ctl
, INT_POL0
| INT_POL1
);
77 /* Clear pending registers */
78 write32(&base
->common_int_sta_1
, 0xff);
79 write32(&base
->common_int_sta_2
, 0x4f);
80 write32(&base
->common_int_sta_3
, 0xe0);
81 write32(&base
->common_int_sta_4
, 0xe7);
82 write32(&base
->dp_int_sta
, 0x63);
84 /* 0:mask,1: unmask */
85 write32(&base
->common_int_mask_1
, 0x00);
86 write32(&base
->common_int_mask_2
, 0x00);
87 write32(&base
->common_int_mask_3
, 0x00);
88 write32(&base
->common_int_mask_4
, 0x00);
89 write32(&base
->int_sta_mask
, 0x00);
92 unsigned int s5p_dp_get_pll_lock_status(struct s5p_dp_device
*dp
)
96 reg
= read32(&dp
->base
->dp_debug_ctl
);
103 int s5p_dp_init_analog_func(struct s5p_dp_device
*dp
)
107 struct exynos5_dp
*base
= dp
->base
;
109 write32(&base
->dp_phy_pd
, 0x00);
112 write32(&base
->common_int_sta_1
, reg
);
114 clrbits32(&base
->dp_debug_ctl
, (F_PLL_LOCK
| PLL_LOCK_CTRL
));
117 if (s5p_dp_get_pll_lock_status(dp
) == PLL_UNLOCKED
) {
118 clrbits32(&base
->dp_pll_ctl
, DP_PLL_PD
);
120 stopwatch_init_msecs_expire(&sw
, PLL_LOCK_TIMEOUT
);
122 while (s5p_dp_get_pll_lock_status(dp
) == PLL_UNLOCKED
) {
123 if (stopwatch_expired(&sw
)) {
124 printk(BIOS_ERR
, "%s: PLL is not locked\n",
131 /* Enable Serdes FIFO function and Link symbol clock domain module */
132 clrbits32(&base
->func_en_2
, (SERDES_FIFO_FUNC_EN_N
|
133 LS_CLK_DOMAIN_FUNC_EN_N
| AUX_FUNC_EN_N
));
137 void s5p_dp_init_aux(struct s5p_dp_device
*dp
)
140 struct exynos5_dp
*base
= dp
->base
;
142 /* Clear interrupts related to AUX channel */
143 reg
= RPLY_RECEIV
| AUX_ERR
;
144 write32(&base
->dp_int_sta
, reg
);
146 /* Disable AUX channel module */
147 setbits32(&base
->func_en_2
, AUX_FUNC_EN_N
);
149 /* Disable AUX transaction H/W retry */
150 reg
= (3 & AUX_BIT_PERIOD_MASK
) << AUX_BIT_PERIOD_SHIFT
;
151 reg
|= (0 & AUX_HW_RETRY_COUNT_MASK
) << AUX_HW_RETRY_COUNT_SHIFT
;
152 reg
|= (AUX_HW_RETRY_INTERVAL_600_US
<< AUX_HW_RETRY_INTERVAL_SHIFT
);
153 write32(&base
->aux_hw_retry_ctl
, reg
);
155 /* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */
157 reg
|= (1 & DEFER_COUNT_MASK
) << DEFER_COUNT_SHIFT
;
158 write32(&base
->aux_ch_defer_dtl
, reg
);
160 /* Enable AUX channel module */
161 clrbits32(&base
->func_en_2
, AUX_FUNC_EN_N
);
164 int s5p_dp_start_aux_transaction(struct s5p_dp_device
*dp
)
167 struct exynos5_dp
*base
= dp
->base
;
169 /* Enable AUX CH operation */
170 setbits32(&base
->aux_ch_ctl_2
, AUX_EN
);
172 /* Is AUX CH command reply received? */
173 reg
= read32(&base
->dp_int_sta
);
174 while (!(reg
& RPLY_RECEIV
))
175 reg
= read32(&base
->dp_int_sta
);
177 /* Clear interrupt source for AUX CH command reply */
178 write32(&base
->dp_int_sta
, RPLY_RECEIV
);
180 /* Clear interrupt source for AUX CH access error */
181 reg
= read32(&base
->dp_int_sta
);
183 printk(BIOS_ERR
, "%s: AUX_ERR encountered, dp_int_sta: "
184 "0x%02x\n", __func__
, reg
);
185 write32(&base
->dp_int_sta
, AUX_ERR
);
189 /* Check AUX CH error access status */
190 reg
= read32(&base
->dp_int_sta
);
191 if ((reg
& AUX_STATUS_MASK
) != 0) {
192 printk(BIOS_ERR
, "AUX CH error happens: %d\n\n",
193 reg
& AUX_STATUS_MASK
);
200 int s5p_dp_write_byte_to_dpcd(struct s5p_dp_device
*dp
,
201 unsigned int reg_addr
,
207 struct exynos5_dp
*base
= dp
->base
;
209 for (i
= 0; i
< MAX_AUX_RETRY_COUNT
; i
++) {
210 /* Clear AUX CH data buffer */
211 write32(&base
->buf_data_ctl
, BUF_CLR
);
213 /* Select DPCD device address */
214 reg
= reg_addr
>> AUX_ADDR_7_0_SHIFT
;
215 reg
&= AUX_ADDR_7_0_MASK
;
216 write32(&base
->aux_addr_7_0
, reg
);
217 reg
= reg_addr
>> AUX_ADDR_15_8_SHIFT
;
218 reg
&= AUX_ADDR_15_8_MASK
;
219 write32(&base
->aux_addr_15_8
, reg
);
220 reg
= reg_addr
>> AUX_ADDR_19_16_SHIFT
;
221 reg
&= AUX_ADDR_19_16_MASK
;
222 write32(&base
->aux_addr_19_16
, reg
);
224 /* Write data buffer */
225 reg
= (unsigned int)data
;
226 write32(&base
->buf_data_0
, reg
);
229 * Set DisplayPort transaction and write 1 byte
230 * If bit 3 is 1, DisplayPort transaction.
231 * If Bit 3 is 0, I2C transaction.
233 reg
= AUX_TX_COMM_DP_TRANSACTION
| AUX_TX_COMM_WRITE
;
234 write32(&base
->aux_ch_ctl_1
, reg
);
236 /* Start AUX transaction */
237 retval
= s5p_dp_start_aux_transaction(dp
);
241 printk(BIOS_DEBUG
, "Aux Transaction fail!\n");
247 int s5p_dp_read_byte_from_dpcd(struct s5p_dp_device
*dp
,
248 unsigned int reg_addr
,
254 struct exynos5_dp
*base
= dp
->base
;
256 for (i
= 0; i
< MAX_AUX_RETRY_COUNT
; i
++) {
257 /* Clear AUX CH data buffer */
258 write32(&base
->buf_data_ctl
, BUF_CLR
);
260 /* Select DPCD device address */
261 reg
= reg_addr
>> AUX_ADDR_7_0_SHIFT
;
262 reg
&= AUX_ADDR_7_0_MASK
;
263 write32(&base
->aux_addr_7_0
, reg
);
264 reg
= reg_addr
>> AUX_ADDR_15_8_SHIFT
;
265 reg
&= AUX_ADDR_15_8_MASK
;
266 write32(&base
->aux_addr_15_8
, reg
);
267 reg
= reg_addr
>> AUX_ADDR_19_16_SHIFT
;
268 reg
&= AUX_ADDR_19_16_MASK
;
269 write32(&base
->aux_addr_19_16
, reg
);
272 * Set DisplayPort transaction and read 1 byte
273 * If bit 3 is 1, DisplayPort transaction.
274 * If Bit 3 is 0, I2C transaction.
276 reg
= AUX_TX_COMM_DP_TRANSACTION
| AUX_TX_COMM_READ
;
277 write32(&base
->aux_ch_ctl_1
, reg
);
279 /* Start AUX transaction */
280 retval
= s5p_dp_start_aux_transaction(dp
);
284 printk(BIOS_DEBUG
, "Aux Transaction fail!\n");
287 /* Read data buffer */
289 reg
= read32(&base
->buf_data_0
);
290 *data
= (unsigned char)(reg
& 0xff);
296 void s5p_dp_init_video(struct s5p_dp_device
*dp
)
299 struct exynos5_dp
*base
= dp
->base
;
301 reg
= VSYNC_DET
| VID_FORMAT_CHG
| VID_CLK_CHG
;
302 write32(&base
->common_int_sta_1
, reg
);
305 write32(&base
->sys_ctl_1
, reg
);
307 reg
= (4 & CHA_CRI_MASK
) << CHA_CRI_SHIFT
;
309 write32(&base
->sys_ctl_2
, reg
);
312 write32(&base
->sys_ctl_3
, reg
);
315 void s5p_dp_set_video_color_format(struct s5p_dp_device
*dp
,
316 unsigned int color_depth
,
317 unsigned int color_space
,
318 unsigned int dynamic_range
,
322 struct exynos5_dp
*base
= dp
->base
;
324 /* Configure the input color depth, color space, dynamic range */
325 reg
= (dynamic_range
<< IN_D_RANGE_SHIFT
) |
326 (color_depth
<< IN_BPC_SHIFT
) |
327 (color_space
<< IN_COLOR_F_SHIFT
);
328 write32(&base
->video_ctl_2
, reg
);
330 /* Set Input Color YCbCr Coefficients to ITU601 or ITU709 */
331 reg
= read32(&base
->video_ctl_3
);
332 reg
&= ~IN_YC_COEFFI_MASK
;
334 reg
|= IN_YC_COEFFI_ITU709
;
336 reg
|= IN_YC_COEFFI_ITU601
;
337 write32(&base
->video_ctl_3
, reg
);
340 int s5p_dp_is_slave_video_stream_clock_on(struct s5p_dp_device
*dp
)
343 struct exynos5_dp
*base
= dp
->base
;
345 reg
= read32(&base
->sys_ctl_1
);
346 write32(&base
->sys_ctl_1
, reg
);
348 reg
= read32(&base
->sys_ctl_1
);
350 if (!(reg
& DET_STA
))
353 reg
= read32(&base
->sys_ctl_2
);
354 write32(&base
->sys_ctl_2
, reg
);
356 reg
= read32(&base
->sys_ctl_2
);
359 printk(BIOS_DEBUG
, "Input stream clk is changing\n");
366 void s5p_dp_set_video_cr_mn(struct s5p_dp_device
*dp
,
367 enum clock_recovery_m_value_type type
,
368 unsigned int m_value
,
369 unsigned int n_value
)
372 struct exynos5_dp
*base
= dp
->base
;
374 if (type
== REGISTER_M
) {
375 setbits32(&base
->sys_ctl_4
, FIX_M_VID
);
377 reg
= m_value
>> M_VID_0_VALUE_SHIFT
;
378 write32(&base
->m_vid_0
, reg
);
380 reg
= (m_value
>> M_VID_1_VALUE_SHIFT
);
381 write32(&base
->m_vid_1
, reg
);
383 reg
= (m_value
>> M_VID_2_VALUE_SHIFT
);
384 write32(&base
->m_vid_2
, reg
);
386 reg
= n_value
>> N_VID_0_VALUE_SHIFT
;
387 write32(&base
->n_vid_0
, reg
);
389 reg
= (n_value
>> N_VID_1_VALUE_SHIFT
);
390 write32(&base
->n_vid_1
, reg
);
392 reg
= (n_value
>> N_VID_2_VALUE_SHIFT
);
393 write32(&base
->n_vid_2
, reg
);
395 clrbits32(&base
->sys_ctl_4
, FIX_M_VID
);
397 write32(&base
->n_vid_0
, 0x00);
398 write32(&base
->n_vid_1
, 0x80);
399 write32(&base
->n_vid_2
, 0x00);
403 void s5p_dp_enable_video_master(struct s5p_dp_device
*dp
)
406 struct exynos5_dp
*base
= dp
->base
;
408 reg
= read32(&base
->soc_general_ctl
);
409 reg
&= ~VIDEO_MODE_MASK
;
410 reg
|= VIDEO_MODE_SLAVE_MODE
;
411 write32(&base
->soc_general_ctl
, reg
);
414 int s5p_dp_is_video_stream_on(struct s5p_dp_device
*dp
)
418 struct exynos5_dp
*base
= dp
->base
;
420 /* Wait for 4 VSYNC_DET interrupts */
421 stopwatch_init_msecs_expire(&sw
, STREAM_ON_TIMEOUT
);
424 reg
= read32(&base
->common_int_sta_1
);
425 if (reg
& VSYNC_DET
) {
427 write32(&base
->common_int_sta_1
, reg
| VSYNC_DET
);
431 } while (!stopwatch_expired(&sw
));
434 printk(BIOS_DEBUG
, "%s timeout\n", __func__
);
441 void s5p_dp_config_video_slave_mode(struct s5p_dp_device
*dp
,
442 struct video_info
*video_info
)
445 struct exynos5_dp
*base
= dp
->base
;
447 reg
= read32(&base
->func_en_1
);
448 reg
&= ~(MASTER_VID_FUNC_EN_N
|SLAVE_VID_FUNC_EN_N
);
449 reg
|= MASTER_VID_FUNC_EN_N
;
450 write32(&base
->func_en_1
, reg
);
452 reg
= read32(&base
->video_ctl_10
);
453 reg
&= ~INTERACE_SCAN_CFG
;
454 reg
|= (video_info
->interlaced
<< 2);
455 write32(&base
->video_ctl_10
, reg
);
457 reg
= read32(&base
->video_ctl_10
);
458 reg
&= ~VSYNC_POLARITY_CFG
;
459 reg
|= (video_info
->v_sync_polarity
<< 1);
460 write32(&base
->video_ctl_10
, reg
);
462 reg
= read32(&base
->video_ctl_10
);
463 reg
&= ~HSYNC_POLARITY_CFG
;
464 reg
|= (video_info
->h_sync_polarity
<< 0);
465 write32(&base
->video_ctl_10
, reg
);
467 reg
= AUDIO_MODE_SPDIF_MODE
| VIDEO_MODE_SLAVE_MODE
;
468 write32(&base
->soc_general_ctl
, reg
);
471 void s5p_dp_wait_hw_link_training_done(struct s5p_dp_device
*dp
)
474 struct exynos5_dp
*base
= dp
->base
;
476 reg
= read32(&base
->dp_hw_link_training
);
477 while (reg
& HW_TRAINING_EN
)
478 reg
= read32(&base
->dp_hw_link_training
);