2 * This file is part of the coreboot project.
4 * Copyright 2013 Google Inc.
5 * Copyright (C) 2012 Samsung Electronics
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
17 /* LCD driver for Exynos */
20 #include <console/console.h>
23 #include <soc/dp-core.h>
26 #include <soc/power.h>
27 #include <soc/sysreg.h>
33 * Here is the rough outline of how we bring up the display:
34 * 1. Upon power-on Sink generates a hot plug detection pulse thru HPD
35 * 2. Source determines video mode by reading DPCD receiver capability field
36 * (DPCD 00000h to 0000Dh) including eDP CP capability register (DPCD
38 * 3. Sink replies DPCD receiver capability field.
39 * 4. Source starts EDID read thru I2C-over-AUX.
40 * 5. Sink replies EDID thru I2C-over-AUX.
41 * 6. Source determines link configuration, such as MAX_LINK_RATE and
42 * MAX_LANE_COUNT. Source also determines which type of eDP Authentication
43 * method to use and writes DPCD link configuration field (DPCD 00100h to
44 * 0010Ah) including eDP configuration set (DPCD 0010Ah).
45 * 7. Source starts link training. Sink does clock recovery and equalization.
46 * 8. Source reads DPCD link status field (DPCD 00200h to 0020Bh).
47 * 9. Sink replies DPCD link status field. If main link is not stable, Source
49 * 10. Source sends MSA (Main Stream Attribute) data. Sink extracts video
50 * parameters and recovers stream clock.
51 * 11. Source sends video data.
54 /* To help debug any init errors here, define a list of possible errors */
56 ERR_PLL_NOT_UNLOCKED
= 2,
59 ERR_DPCD_READ_ERROR1
, /* 5 */
61 ERR_DPCD_WRITE_ERROR1
,
63 ERR_DPCD_WRITE_ERROR2
,
65 ERR_PLL_NOT_LOCKED
, /* 10 */
67 ERR_PRE_EMPHASIS_LEVELS
,
68 ERR_LINK_RATE_ABNORMAL
,
69 ERR_MAX_LANE_COUNT_ABNORMAL
,
70 ERR_LINK_TRAINING_FAILURE
,
71 ERR_MISSING_DP_BASE
, /* 15 */
75 /* ok, this is stupid, but we're going to leave the variables in here until we
76 * know it works. One cleanup task at a time.
96 void *lcd_console_address
; /* Start of console buffer */
101 /* Bypass FIMD of DISP1_BLK */
102 static void fimd_bypass(void)
104 setbits_le32(&exynos_sysreg
->disp1blk_cfg
, FIMDBYPASS_DISP1
);
105 exynos_sysreg
->disp1blk_cfg
&= ~FIMDBYPASS_DISP1
;
109 * Initialize display controller.
111 * @param lcdbase pointer to the base address of framebuffer.
112 * @param pd pointer to the main panel_data structure
114 void fb_init(unsigned long int fb_size
, void *lcdbase
,
115 struct exynos5_fimd_panel
*pd
)
119 fb_size
= ALIGN(fb_size
, 4096);
121 write32(&exynos_disp_ctrl
->vidcon1
, pd
->ivclk
| pd
->fixvclk
);
122 val
= ENVID_ON
| ENVID_F_ON
| (pd
->clkval_f
<< CLKVAL_F_OFFSET
);
123 write32(&exynos_fimd
->vidcon0
, val
);
125 val
= (pd
->vsync
<< VSYNC_PULSE_WIDTH_OFFSET
) |
126 (pd
->lower_margin
<< V_FRONT_PORCH_OFFSET
) |
127 (pd
->upper_margin
<< V_BACK_PORCH_OFFSET
);
128 write32(&exynos_disp_ctrl
->vidtcon0
, val
);
130 val
= (pd
->hsync
<< HSYNC_PULSE_WIDTH_OFFSET
) |
131 (pd
->right_margin
<< H_FRONT_PORCH_OFFSET
) |
132 (pd
->left_margin
<< H_BACK_PORCH_OFFSET
);
133 write32(&exynos_disp_ctrl
->vidtcon1
, val
);
135 val
= ((pd
->xres
- 1) << HOZVAL_OFFSET
) |
136 ((pd
->yres
- 1) << LINEVAL_OFFSET
);
137 write32(&exynos_disp_ctrl
->vidtcon2
, val
);
139 write32(&exynos_fimd
->vidw00add0b0
, (unsigned int)lcdbase
);
140 write32(&exynos_fimd
->vidw00add1b0
, (unsigned int)lcdbase
+ fb_size
);
142 write32(&exynos_fimd
->vidw00add2
, pd
->xres
* 2);
144 val
= ((pd
->xres
- 1) << OSD_RIGHTBOTX_F_OFFSET
);
145 val
|= ((pd
->yres
- 1) << OSD_RIGHTBOTY_F_OFFSET
);
146 write32(&exynos_fimd
->vidosd0b
, val
);
147 write32(&exynos_fimd
->vidosd0c
, pd
->xres
* pd
->yres
);
149 setbits_le32(&exynos_fimd
->shadowcon
, CHANNEL0_EN
);
151 val
= BPPMODE_F_RGB_16BIT_565
<< BPPMODE_F_OFFSET
;
152 val
|= ENWIN_F_ENABLE
| HALF_WORD_SWAP_EN
;
153 write32(&exynos_fimd
->wincon0
, val
);
155 /* DPCLKCON_ENABLE */
156 write32(&exynos_fimd
->dpclkcon
, 1 << 1);
160 void exynos_fimd_disable(void)
162 write32(&exynos_fimd
->wincon0
, 0);
163 clrbits_le32(&exynos_fimd
->shadowcon
, CHANNEL0_EN
);
168 * Configure DP in slave mode and wait for video stream.
170 * param dp pointer to main s5p-dp structure
171 * param video_info pointer to main video_info structure.
174 static int s5p_dp_config_video(struct s5p_dp_device
*dp
,
175 struct video_info
*video_info
)
178 struct exynos5_dp
*base
= dp
->base
;
180 s5p_dp_config_video_slave_mode(dp
, video_info
);
182 s5p_dp_set_video_color_format(dp
, video_info
->color_depth
,
183 video_info
->color_space
,
184 video_info
->dynamic_range
,
185 video_info
->ycbcr_coeff
);
187 if (s5p_dp_get_pll_lock_status(dp
) == PLL_UNLOCKED
) {
188 printk(BIOS_DEBUG
, "PLL is not locked yet.\n");
189 return -ERR_PLL_NOT_UNLOCKED
;
192 stopwatch_init_msecs_expire(&sw
, STREAM_ON_TIMEOUT
);
194 if (s5p_dp_is_slave_video_stream_clock_on(dp
) == 0) {
198 } while (!stopwatch_expired(&sw
));
201 printk(BIOS_ERR
, "Video Clock Not ok after %ldus.\n",
202 stopwatch_duration_usecs(&sw
));
203 return -ERR_VIDEO_CLOCK_BAD
;
206 /* Set to use the register calculated M/N video */
207 s5p_dp_set_video_cr_mn(dp
, CALCULATED_M
, 0, 0);
209 clrbits_le32(&base
->video_ctl_10
, FORMAT_SEL
);
211 /* Disable video mute */
212 clrbits_le32(&base
->video_ctl_1
, HDCP_VIDEO_MUTE
);
214 /* Configure video slave mode */
215 s5p_dp_enable_video_master(dp
);
218 setbits_le32(&base
->video_ctl_1
, VIDEO_EN
);
219 timeout
= s5p_dp_is_video_stream_on(dp
);
222 printk(BIOS_DEBUG
, "Video Stream Not on\n");
223 return -ERR_VIDEO_STREAM_BAD
;
230 * Set DP to enhanced mode. We use this for EVT1
231 * param dp pointer to main s5p-dp structure
234 static int s5p_dp_enable_rx_to_enhanced_mode(struct s5p_dp_device
*dp
)
238 if (s5p_dp_read_byte_from_dpcd(dp
, DPCD_ADDR_LANE_COUNT_SET
, &data
)) {
239 printk(BIOS_DEBUG
, "DPCD read error\n");
240 return -ERR_DPCD_READ_ERROR1
;
242 if (s5p_dp_write_byte_to_dpcd(dp
, DPCD_ADDR_LANE_COUNT_SET
,
243 DPCD_ENHANCED_FRAME_EN
|
244 (data
& DPCD_LANE_COUNT_SET_MASK
))) {
245 printk(BIOS_DEBUG
, "DPCD write error\n");
246 return -ERR_DPCD_WRITE_ERROR1
;
253 * Enable scrambles mode. We use this for EVT1
254 * param dp pointer to main s5p-dp structure
257 static int s5p_dp_enable_scramble(struct s5p_dp_device
*dp
)
260 struct exynos5_dp
*base
= dp
->base
;
262 clrbits_le32(&base
->dp_training_ptn_set
, SCRAMBLING_DISABLE
);
264 if (s5p_dp_read_byte_from_dpcd(dp
, DPCD_ADDR_TRAINING_PATTERN_SET
,
266 printk(BIOS_DEBUG
, "DPCD read error\n");
267 return -ERR_DPCD_READ_ERROR2
;
270 if (s5p_dp_write_byte_to_dpcd(dp
, DPCD_ADDR_TRAINING_PATTERN_SET
,
271 (u8
)(data
& ~DPCD_SCRAMBLING_DISABLED
))) {
272 printk(BIOS_DEBUG
, "DPCD write error\n");
273 return -ERR_DPCD_WRITE_ERROR2
;
280 * Reset DP and prepare DP for init training
281 * param dp pointer to main s5p-dp structure
283 static int s5p_dp_init_dp(struct s5p_dp_device
*dp
)
286 struct exynos5_dp
*base
= dp
->base
;
288 for (i
= 0; i
< DP_INIT_TRIES
; i
++) {
291 /* SW defined function Normal operation */
292 clrbits_le32(&base
->func_en_1
, SW_FUNC_EN_N
);
294 ret
= s5p_dp_init_analog_func(dp
);
299 printk(BIOS_DEBUG
, "LCD retry init, attempt=%d ret=%d\n", i
, ret
);
301 if (i
== DP_INIT_TRIES
) {
302 printk(BIOS_DEBUG
, "LCD initialization failed, ret=%d\n", ret
);
312 * Set pre-emphasis level
313 * param dp pointer to main s5p-dp structure
314 * param pre_emphasis pre-emphasis level
315 * param lane lane number(0 - 3)
318 static int s5p_dp_set_lane_lane_pre_emphasis(struct s5p_dp_device
*dp
,
319 int pre_emphasis
, int lane
)
322 struct exynos5_dp
*base
= dp
->base
;
324 reg
= pre_emphasis
<< PRE_EMPHASIS_SET_SHIFT
;
327 write32(&base
->ln0_link_trn_ctl
, reg
);
330 write32(&base
->ln1_link_trn_ctl
, reg
);
334 write32(&base
->ln2_link_trn_ctl
, reg
);
338 write32(&base
->ln3_link_trn_ctl
, reg
);
341 printk(BIOS_DEBUG
, "%s: Invalid lane %d\n", __func__
, lane
);
342 return -ERR_INVALID_LANE
;
348 * Read supported bandwidth type
349 * param dp pointer to main s5p-dp structure
350 * param bandwidth pointer to variable holding bandwidth type
352 static void s5p_dp_get_max_rx_bandwidth(struct s5p_dp_device
*dp
,
358 * For DP rev.1.1, Maximum link rate of Main Link lanes
359 * 0x06 = 1.62 Gbps, 0x0a = 2.7 Gbps
361 s5p_dp_read_byte_from_dpcd(dp
, DPCD_ADDR_MAX_LINK_RATE
, &data
);
366 * Reset DP and prepare DP for init training
367 * param dp pointer to main s5p-dp structure
368 * param lane_count pointer to variable holding no of lanes
370 static void s5p_dp_get_max_rx_lane_count(struct s5p_dp_device
*dp
,
376 * For DP rev.1.1, Maximum number of Main Link lanes
377 * 0x01 = 1 lane, 0x02 = 2 lanes, 0x04 = 4 lanes
379 s5p_dp_read_byte_from_dpcd(dp
, DPCD_ADDR_MAX_LANE_COUNT
, &data
);
380 *lane_count
= data
& DPCD_MAX_LANE_COUNT_MASK
;
384 * DP H/w Link Training. Set DPCD link rate and bandwidth.
385 * param dp pointer to main s5p-dp structure
386 * param max_lane No of lanes
387 * param max_rate bandwidth
390 static int s5p_dp_hw_link_training(struct s5p_dp_device
*dp
,
391 unsigned int max_lane
,
392 unsigned int max_rate
)
394 int pll_is_locked
= 0;
398 struct exynos5_dp
*base
= dp
->base
;
401 clrbits_le32(&base
->video_ctl_1
, VIDEO_EN
);
403 stopwatch_init_msecs_expire(&sw
, PLL_LOCK_TIMEOUT
);
405 while ((pll_is_locked
= s5p_dp_get_pll_lock_status(dp
)) == PLL_UNLOCKED
) {
406 if (stopwatch_expired(&sw
)) {
407 /* Ignore this error, and try to continue */
408 printk(BIOS_ERR
, "PLL is not locked yet.\n");
412 printk(BIOS_SPEW
, "PLL is %slocked\n",
413 pll_is_locked
== PLL_LOCKED
? "": "not ");
415 setbits_le32(&base
->dp_phy_test
, MACRO_RST
);
417 /* 10 us is the minimum reset time. */
420 clrbits_le32(&base
->dp_phy_test
, MACRO_RST
);
422 /* Set TX pre-emphasis to minimum */
423 for (lane
= 0; lane
< max_lane
; lane
++)
424 if (s5p_dp_set_lane_lane_pre_emphasis(dp
,
425 PRE_EMPHASIS_LEVEL_0
, lane
)) {
426 printk(BIOS_DEBUG
, "Unable to set pre emphasis level\n");
427 return -ERR_PRE_EMPHASIS_LEVELS
;
430 /* All DP analog module power up */
431 write32(&base
->dp_phy_pd
, 0x00);
433 /* Initialize by reading RX's DPCD */
434 s5p_dp_get_max_rx_bandwidth(dp
, &dp
->link_train
.link_rate
);
435 s5p_dp_get_max_rx_lane_count(dp
, &dp
->link_train
.lane_count
);
437 printk(BIOS_SPEW
, "%s: rate 0x%x, lane_count %d\n", __func__
,
438 dp
->link_train
.link_rate
, dp
->link_train
.lane_count
);
440 if ((dp
->link_train
.link_rate
!= LINK_RATE_1_62GBPS
) &&
441 (dp
->link_train
.link_rate
!= LINK_RATE_2_70GBPS
)) {
442 printk(BIOS_DEBUG
, "Rx Max Link Rate is abnormal :%x !\n",
443 dp
->link_train
.link_rate
);
445 return -ERR_LINK_RATE_ABNORMAL
;
448 if (dp
->link_train
.lane_count
== 0) {
449 printk(BIOS_DEBUG
, "Rx Max Lane count is abnormal :%x !\n",
450 dp
->link_train
.lane_count
);
452 return -ERR_MAX_LANE_COUNT_ABNORMAL
;
455 /* Setup TX lane count & rate */
456 if (dp
->link_train
.lane_count
> max_lane
)
457 dp
->link_train
.lane_count
= max_lane
;
458 if (dp
->link_train
.link_rate
> max_rate
)
459 dp
->link_train
.link_rate
= max_rate
;
461 /* Set link rate and count as you want to establish*/
462 write32(&base
->lane_count_set
, dp
->link_train
.lane_count
);
463 write32(&base
->link_bw_set
, dp
->link_train
.link_rate
);
465 /* Set sink to D0 (Sink Not Ready) mode. */
466 s5p_dp_write_byte_to_dpcd(dp
, DPCD_ADDR_SINK_POWER_STATE
,
467 DPCD_SET_POWER_STATE_D0
);
469 /* Start HW link training */
470 write32(&base
->dp_hw_link_training
, HW_TRAINING_EN
);
472 /* Wait until HW link training done */
473 s5p_dp_wait_hw_link_training_done(dp
);
475 /* Get hardware link training status */
476 data
= read32(&base
->dp_hw_link_training
);
477 printk(BIOS_SPEW
, "hardware link training status: 0x%08x\n", data
);
479 printk(BIOS_ERR
, " H/W link training failure: 0x%x\n", data
);
480 return -ERR_LINK_TRAINING_FAILURE
;
483 /* Get Link Bandwidth */
484 data
= read32(&base
->link_bw_set
);
486 dp
->link_train
.link_rate
= data
;
488 data
= read32(&base
->lane_count_set
);
489 dp
->link_train
.lane_count
= data
;
490 printk(BIOS_SPEW
, "Done training: Link bandwidth: 0x%x, lane_count: %d\n",
491 dp
->link_train
.link_rate
, data
);
497 * Initialize DP display
499 int dp_controller_init(struct s5p_dp_device
*dp_device
)
502 struct s5p_dp_device
*dp
= dp_device
;
503 struct exynos5_dp
*base
;
505 clock_init_dp_clock();
507 power_enable_dp_phy();
508 ret
= s5p_dp_init_dp(dp
);
510 printk(BIOS_ERR
, "%s: Could not initialize dp\n", __func__
);
514 ret
= s5p_dp_hw_link_training(dp
, dp
->video_info
->lane_count
,
515 dp
->video_info
->link_rate
);
517 printk(BIOS_ERR
, "unable to do link train\n");
520 /* Minimum delay after H/w Link training */
523 ret
= s5p_dp_enable_scramble(dp
);
525 printk(BIOS_ERR
, "unable to set scramble mode\n");
529 ret
= s5p_dp_enable_rx_to_enhanced_mode(dp
);
531 printk(BIOS_ERR
, "unable to set enhanced mode\n");
537 /* Enable enhanced mode */
538 setbits_le32(&base
->sys_ctl_4
, ENHANCED
);
540 write32(&base
->lane_count_set
, dp
->link_train
.lane_count
);
541 write32(&base
->link_bw_set
, dp
->link_train
.link_rate
);
543 s5p_dp_init_video(dp
);
544 ret
= s5p_dp_config_video(dp
, dp
->video_info
);
546 printk(BIOS_ERR
, "unable to config video\n");
554 * Init the LCD controller
556 * @param lcdbase Base address of LCD frame buffer
557 * @return 0 if ok, -ve error code on error
559 int lcd_ctrl_init(unsigned long int fb_size
,
560 struct exynos5_fimd_panel
*panel_data
, void *lcdbase
)
565 fb_init(fb_size
, lcdbase
, panel_data
);