1 /* 2 * Copyright (C) 2012 Samsung Electronics 3 * 4 * Author: InKi Dae <inki.dae@samsung.com> 5 * Author: Donghwa Lee <dh09.lee@samsung.com> 6 * 7 * SPDX-License-Identifier: GPL-2.0+ 8 */ 9 10 #include <config.h> 11 #include <common.h> 12 #include <div64.h> 13 #include <lcd.h> 14 #include <fdtdec.h> 15 #include <libfdt.h> 16 #include <asm/io.h> 17 #include <asm/arch/cpu.h> 18 #include <asm/arch/clock.h> 19 #include <asm/arch/clk.h> 20 #include <asm/arch/mipi_dsim.h> 21 #include <asm/arch/dp_info.h> 22 #include <asm/arch/system.h> 23 #include <asm/gpio.h> 24 #include <asm-generic/errno.h> 25 26 #include "exynos_fb.h" 27 28 DECLARE_GLOBAL_DATA_PTR; 29 30 struct vidinfo panel_info = { 31 /* 32 * Insert a value here so that we don't end up in the BSS 33 * Reference: drivers/video/tegra.c 34 */ 35 .vl_col = -1, 36 }; 37 38 static void exynos_fimd_set_dualrgb(struct vidinfo *pvid, unsigned int enabled) 39 { 40 struct exynos_fb *fimd_ctrl = pvid->fimd_ctrl; 41 unsigned int cfg = 0; 42 43 if (enabled) { 44 cfg = EXYNOS_DUALRGB_BYPASS_DUAL | EXYNOS_DUALRGB_LINESPLIT | 45 EXYNOS_DUALRGB_VDEN_EN_ENABLE; 46 47 /* in case of Line Split mode, MAIN_CNT doesn't neet to set. */ 48 cfg |= EXYNOS_DUALRGB_SUB_CNT(pvid->vl_col / 2) | 49 EXYNOS_DUALRGB_MAIN_CNT(0); 50 } 51 52 writel(cfg, &fimd_ctrl->dualrgb); 53 } 54 55 static void exynos_fimd_set_dp_clkcon(struct vidinfo *pvid, 56 unsigned int enabled) 57 { 58 struct exynos_fb *fimd_ctrl = pvid->fimd_ctrl; 59 unsigned int cfg = 0; 60 61 if (enabled) 62 cfg = EXYNOS_DP_CLK_ENABLE; 63 64 writel(cfg, &fimd_ctrl->dp_mie_clkcon); 65 } 66 67 static void exynos_fimd_set_par(struct vidinfo *pvid, unsigned int win_id) 68 { 69 struct exynos_fb *fimd_ctrl = pvid->fimd_ctrl; 70 unsigned int cfg = 0; 71 72 /* set window control */ 73 cfg = readl((unsigned int)&fimd_ctrl->wincon0 + 74 EXYNOS_WINCON(win_id)); 75 76 cfg &= ~(EXYNOS_WINCON_BITSWP_ENABLE | EXYNOS_WINCON_BYTESWP_ENABLE | 77 EXYNOS_WINCON_HAWSWP_ENABLE | EXYNOS_WINCON_WSWP_ENABLE | 78 EXYNOS_WINCON_BURSTLEN_MASK | EXYNOS_WINCON_BPPMODE_MASK | 79 EXYNOS_WINCON_INRGB_MASK | EXYNOS_WINCON_DATAPATH_MASK); 80 81 /* DATAPATH is DMA */ 82 cfg |= EXYNOS_WINCON_DATAPATH_DMA; 83 84 cfg |= EXYNOS_WINCON_HAWSWP_ENABLE; 85 86 /* dma burst is 16 */ 87 cfg |= EXYNOS_WINCON_BURSTLEN_16WORD; 88 89 switch (pvid->vl_bpix) { 90 case 4: 91 cfg |= EXYNOS_WINCON_BPPMODE_16BPP_565; 92 break; 93 default: 94 cfg |= EXYNOS_WINCON_BPPMODE_24BPP_888; 95 break; 96 } 97 98 writel(cfg, (unsigned int)&fimd_ctrl->wincon0 + 99 EXYNOS_WINCON(win_id)); 100 101 /* set window position to x=0, y=0*/ 102 cfg = EXYNOS_VIDOSD_LEFT_X(0) | EXYNOS_VIDOSD_TOP_Y(0); 103 writel(cfg, (unsigned int)&fimd_ctrl->vidosd0a + 104 EXYNOS_VIDOSD(win_id)); 105 106 cfg = EXYNOS_VIDOSD_RIGHT_X(pvid->vl_col - 1) | 107 EXYNOS_VIDOSD_BOTTOM_Y(pvid->vl_row - 1) | 108 EXYNOS_VIDOSD_RIGHT_X_E(1) | 109 EXYNOS_VIDOSD_BOTTOM_Y_E(0); 110 111 writel(cfg, (unsigned int)&fimd_ctrl->vidosd0b + 112 EXYNOS_VIDOSD(win_id)); 113 114 /* set window size for window0*/ 115 cfg = EXYNOS_VIDOSD_SIZE(pvid->vl_col * pvid->vl_row); 116 writel(cfg, (unsigned int)&fimd_ctrl->vidosd0c + 117 EXYNOS_VIDOSD(win_id)); 118 } 119 120 static void exynos_fimd_set_buffer_address(struct vidinfo *pvid, 121 unsigned int win_id, 122 ulong lcd_base_addr) 123 { 124 struct exynos_fb *fimd_ctrl = pvid->fimd_ctrl; 125 unsigned long start_addr, end_addr; 126 127 start_addr = lcd_base_addr; 128 end_addr = start_addr + ((pvid->vl_col * (NBITS(pvid->vl_bpix) / 8)) * 129 pvid->vl_row); 130 131 writel(start_addr, (unsigned int)&fimd_ctrl->vidw00add0b0 + 132 EXYNOS_BUFFER_OFFSET(win_id)); 133 writel(end_addr, (unsigned int)&fimd_ctrl->vidw00add1b0 + 134 EXYNOS_BUFFER_OFFSET(win_id)); 135 } 136 137 static void exynos_fimd_set_clock(struct vidinfo *pvid) 138 { 139 struct exynos_fb *fimd_ctrl = pvid->fimd_ctrl; 140 unsigned int cfg = 0, div = 0, remainder, remainder_div; 141 unsigned long pixel_clock; 142 unsigned long long src_clock; 143 144 if (pvid->dual_lcd_enabled) { 145 pixel_clock = pvid->vl_freq * 146 (pvid->vl_hspw + pvid->vl_hfpd + 147 pvid->vl_hbpd + pvid->vl_col / 2) * 148 (pvid->vl_vspw + pvid->vl_vfpd + 149 pvid->vl_vbpd + pvid->vl_row); 150 } else if (pvid->interface_mode == FIMD_CPU_INTERFACE) { 151 pixel_clock = pvid->vl_freq * 152 pvid->vl_width * pvid->vl_height * 153 (pvid->cs_setup + pvid->wr_setup + 154 pvid->wr_act + pvid->wr_hold + 1); 155 } else { 156 pixel_clock = pvid->vl_freq * 157 (pvid->vl_hspw + pvid->vl_hfpd + 158 pvid->vl_hbpd + pvid->vl_col) * 159 (pvid->vl_vspw + pvid->vl_vfpd + 160 pvid->vl_vbpd + pvid->vl_row); 161 } 162 163 cfg = readl(&fimd_ctrl->vidcon0); 164 cfg &= ~(EXYNOS_VIDCON0_CLKSEL_MASK | EXYNOS_VIDCON0_CLKVALUP_MASK | 165 EXYNOS_VIDCON0_CLKVAL_F(0xFF) | EXYNOS_VIDCON0_VCLKEN_MASK | 166 EXYNOS_VIDCON0_CLKDIR_MASK); 167 cfg |= (EXYNOS_VIDCON0_CLKSEL_SCLK | EXYNOS_VIDCON0_CLKVALUP_ALWAYS | 168 EXYNOS_VIDCON0_VCLKEN_NORMAL | EXYNOS_VIDCON0_CLKDIR_DIVIDED); 169 170 src_clock = (unsigned long long) get_lcd_clk(); 171 172 /* get quotient and remainder. */ 173 remainder = do_div(src_clock, pixel_clock); 174 div = src_clock; 175 176 remainder *= 10; 177 remainder_div = remainder / pixel_clock; 178 179 /* round about one places of decimals. */ 180 if (remainder_div >= 5) 181 div++; 182 183 /* in case of dual lcd mode. */ 184 if (pvid->dual_lcd_enabled) 185 div--; 186 187 cfg |= EXYNOS_VIDCON0_CLKVAL_F(div - 1); 188 writel(cfg, &fimd_ctrl->vidcon0); 189 } 190 191 void exynos_set_trigger(struct vidinfo *pvid) 192 { 193 struct exynos_fb *fimd_ctrl = pvid->fimd_ctrl; 194 unsigned int cfg = 0; 195 196 cfg = readl(&fimd_ctrl->trigcon); 197 198 cfg |= (EXYNOS_I80SOFT_TRIG_EN | EXYNOS_I80START_TRIG); 199 200 writel(cfg, &fimd_ctrl->trigcon); 201 } 202 203 int exynos_is_i80_frame_done(struct vidinfo *pvid) 204 { 205 struct exynos_fb *fimd_ctrl = pvid->fimd_ctrl; 206 unsigned int cfg = 0; 207 int status; 208 209 cfg = readl(&fimd_ctrl->trigcon); 210 211 /* frame done func is valid only when TRIMODE[0] is set to 1. */ 212 status = (cfg & EXYNOS_I80STATUS_TRIG_DONE) == 213 EXYNOS_I80STATUS_TRIG_DONE; 214 215 return status; 216 } 217 218 static void exynos_fimd_lcd_on(struct vidinfo *pvid) 219 { 220 struct exynos_fb *fimd_ctrl = pvid->fimd_ctrl; 221 unsigned int cfg = 0; 222 223 /* display on */ 224 cfg = readl(&fimd_ctrl->vidcon0); 225 cfg |= (EXYNOS_VIDCON0_ENVID_ENABLE | EXYNOS_VIDCON0_ENVID_F_ENABLE); 226 writel(cfg, &fimd_ctrl->vidcon0); 227 } 228 229 static void exynos_fimd_window_on(struct vidinfo *pvid, unsigned int win_id) 230 { 231 struct exynos_fb *fimd_ctrl = pvid->fimd_ctrl; 232 unsigned int cfg = 0; 233 234 /* enable window */ 235 cfg = readl((unsigned int)&fimd_ctrl->wincon0 + 236 EXYNOS_WINCON(win_id)); 237 cfg |= EXYNOS_WINCON_ENWIN_ENABLE; 238 writel(cfg, (unsigned int)&fimd_ctrl->wincon0 + 239 EXYNOS_WINCON(win_id)); 240 241 cfg = readl(&fimd_ctrl->winshmap); 242 cfg |= EXYNOS_WINSHMAP_CH_ENABLE(win_id); 243 writel(cfg, &fimd_ctrl->winshmap); 244 } 245 246 void exynos_fimd_lcd_off(struct vidinfo *pvid) 247 { 248 struct exynos_fb *fimd_ctrl = pvid->fimd_ctrl; 249 unsigned int cfg = 0; 250 251 cfg = readl(&fimd_ctrl->vidcon0); 252 cfg &= (EXYNOS_VIDCON0_ENVID_DISABLE | EXYNOS_VIDCON0_ENVID_F_DISABLE); 253 writel(cfg, &fimd_ctrl->vidcon0); 254 } 255 256 void exynos_fimd_window_off(struct vidinfo *pvid, unsigned int win_id) 257 { 258 struct exynos_fb *fimd_ctrl = pvid->fimd_ctrl; 259 unsigned int cfg = 0; 260 261 cfg = readl((unsigned int)&fimd_ctrl->wincon0 + 262 EXYNOS_WINCON(win_id)); 263 cfg &= EXYNOS_WINCON_ENWIN_DISABLE; 264 writel(cfg, (unsigned int)&fimd_ctrl->wincon0 + 265 EXYNOS_WINCON(win_id)); 266 267 cfg = readl(&fimd_ctrl->winshmap); 268 cfg &= ~EXYNOS_WINSHMAP_CH_DISABLE(win_id); 269 writel(cfg, &fimd_ctrl->winshmap); 270 } 271 272 /* 273 * The reset value for FIMD SYSMMU register MMU_CTRL is 3 274 * on Exynos5420 and newer versions. 275 * This means FIMD SYSMMU is on by default on Exynos5420 276 * and newer versions. 277 * Since in u-boot we don't use SYSMMU, we should disable 278 * those FIMD SYSMMU. 279 * Note that there are 2 SYSMMU for FIMD: m0 and m1. 280 * m0 handles windows 0 and 4, and m1 handles windows 1, 2 and 3. 281 * We disable both of them here. 282 */ 283 void exynos_fimd_disable_sysmmu(void) 284 { 285 u32 *sysmmufimd; 286 unsigned int node; 287 int node_list[2]; 288 int count; 289 int i; 290 291 count = fdtdec_find_aliases_for_id(gd->fdt_blob, "fimd", 292 COMPAT_SAMSUNG_EXYNOS_SYSMMU, node_list, 2); 293 for (i = 0; i < count; i++) { 294 node = node_list[i]; 295 if (node <= 0) { 296 debug("Can't get device node for fimd sysmmu\n"); 297 return; 298 } 299 300 sysmmufimd = (u32 *)fdtdec_get_addr(gd->fdt_blob, node, "reg"); 301 if (!sysmmufimd) { 302 debug("Can't get base address for sysmmu fimdm0"); 303 return; 304 } 305 306 writel(0x0, sysmmufimd); 307 } 308 } 309 310 void exynos_fimd_lcd_init(struct vidinfo *pvid, ulong lcd_base_address) 311 { 312 struct exynos_fb *fimd_ctrl; 313 unsigned int cfg = 0, rgb_mode; 314 unsigned int offset; 315 unsigned int node; 316 317 node = fdtdec_next_compatible(gd->fdt_blob, 318 0, COMPAT_SAMSUNG_EXYNOS_FIMD); 319 if (node <= 0) 320 debug("exynos_fb: Can't get device node for fimd\n"); 321 322 fimd_ctrl = (struct exynos_fb *)fdtdec_get_addr(gd->fdt_blob, node, 323 "reg"); 324 if (fimd_ctrl == NULL) 325 debug("Can't get the FIMD base address\n"); 326 pvid->fimd_ctrl = fimd_ctrl; 327 328 if (fdtdec_get_bool(gd->fdt_blob, node, "samsung,disable-sysmmu")) 329 exynos_fimd_disable_sysmmu(); 330 331 offset = exynos_fimd_get_base_offset(); 332 333 rgb_mode = pvid->rgb_mode; 334 335 if (pvid->interface_mode == FIMD_RGB_INTERFACE) { 336 cfg |= EXYNOS_VIDCON0_VIDOUT_RGB; 337 writel(cfg, &fimd_ctrl->vidcon0); 338 339 cfg = readl(&fimd_ctrl->vidcon2); 340 cfg &= ~(EXYNOS_VIDCON2_WB_MASK | 341 EXYNOS_VIDCON2_TVFORMATSEL_MASK | 342 EXYNOS_VIDCON2_TVFORMATSEL_YUV_MASK); 343 cfg |= EXYNOS_VIDCON2_WB_DISABLE; 344 writel(cfg, &fimd_ctrl->vidcon2); 345 346 /* set polarity */ 347 cfg = 0; 348 if (!pvid->vl_clkp) 349 cfg |= EXYNOS_VIDCON1_IVCLK_RISING_EDGE; 350 if (!pvid->vl_hsp) 351 cfg |= EXYNOS_VIDCON1_IHSYNC_INVERT; 352 if (!pvid->vl_vsp) 353 cfg |= EXYNOS_VIDCON1_IVSYNC_INVERT; 354 if (!pvid->vl_dp) 355 cfg |= EXYNOS_VIDCON1_IVDEN_INVERT; 356 357 writel(cfg, (unsigned int)&fimd_ctrl->vidcon1 + offset); 358 359 /* set timing */ 360 cfg = EXYNOS_VIDTCON0_VFPD(pvid->vl_vfpd - 1); 361 cfg |= EXYNOS_VIDTCON0_VBPD(pvid->vl_vbpd - 1); 362 cfg |= EXYNOS_VIDTCON0_VSPW(pvid->vl_vspw - 1); 363 writel(cfg, (unsigned int)&fimd_ctrl->vidtcon0 + offset); 364 365 cfg = EXYNOS_VIDTCON1_HFPD(pvid->vl_hfpd - 1); 366 cfg |= EXYNOS_VIDTCON1_HBPD(pvid->vl_hbpd - 1); 367 cfg |= EXYNOS_VIDTCON1_HSPW(pvid->vl_hspw - 1); 368 369 writel(cfg, (unsigned int)&fimd_ctrl->vidtcon1 + offset); 370 371 /* set lcd size */ 372 cfg = EXYNOS_VIDTCON2_HOZVAL(pvid->vl_col - 1) | 373 EXYNOS_VIDTCON2_LINEVAL(pvid->vl_row - 1) | 374 EXYNOS_VIDTCON2_HOZVAL_E(pvid->vl_col - 1) | 375 EXYNOS_VIDTCON2_LINEVAL_E(pvid->vl_row - 1); 376 377 writel(cfg, (unsigned int)&fimd_ctrl->vidtcon2 + offset); 378 } 379 380 /* set display mode */ 381 cfg = readl(&fimd_ctrl->vidcon0); 382 cfg &= ~EXYNOS_VIDCON0_PNRMODE_MASK; 383 cfg |= (rgb_mode << EXYNOS_VIDCON0_PNRMODE_SHIFT); 384 writel(cfg, &fimd_ctrl->vidcon0); 385 386 /* set par */ 387 exynos_fimd_set_par(pvid, pvid->win_id); 388 389 /* set memory address */ 390 exynos_fimd_set_buffer_address(pvid, pvid->win_id, lcd_base_address); 391 392 /* set buffer size */ 393 cfg = EXYNOS_VIDADDR_PAGEWIDTH(pvid->vl_col * 394 NBITS(pvid->vl_bpix) / 8) | 395 EXYNOS_VIDADDR_PAGEWIDTH_E(pvid->vl_col * 396 NBITS(pvid->vl_bpix) / 8) | 397 EXYNOS_VIDADDR_OFFSIZE(0) | 398 EXYNOS_VIDADDR_OFFSIZE_E(0); 399 400 writel(cfg, (unsigned int)&fimd_ctrl->vidw00add2 + 401 EXYNOS_BUFFER_SIZE(pvid->win_id)); 402 403 /* set clock */ 404 exynos_fimd_set_clock(pvid); 405 406 /* set rgb mode to dual lcd. */ 407 exynos_fimd_set_dualrgb(pvid, pvid->dual_lcd_enabled); 408 409 /* display on */ 410 exynos_fimd_lcd_on(pvid); 411 412 /* window on */ 413 exynos_fimd_window_on(pvid, pvid->win_id); 414 415 exynos_fimd_set_dp_clkcon(pvid, pvid->dp_enabled); 416 } 417 418 unsigned long exynos_fimd_calc_fbsize(struct vidinfo *pvid) 419 { 420 return pvid->vl_col * pvid->vl_row * (NBITS(pvid->vl_bpix) / 8); 421 } 422 423 ushort *configuration_get_cmap(void) 424 { 425 #if defined(CONFIG_LCD_LOGO) 426 return bmp_logo_palette; 427 #else 428 return NULL; 429 #endif 430 } 431 432 static void exynos_lcd_init(struct vidinfo *vid, ulong lcd_base) 433 { 434 exynos_fimd_lcd_init(vid, lcd_base); 435 436 /* Enable flushing after LCD writes if requested */ 437 lcd_set_flush_dcache(1); 438 } 439 440 __weak void exynos_cfg_lcd_gpio(void) 441 { 442 } 443 444 __weak void exynos_backlight_on(unsigned int onoff) 445 { 446 } 447 448 __weak void exynos_reset_lcd(void) 449 { 450 } 451 452 __weak void exynos_lcd_power_on(void) 453 { 454 } 455 456 __weak void exynos_cfg_ldo(void) 457 { 458 } 459 460 __weak void exynos_enable_ldo(unsigned int onoff) 461 { 462 } 463 464 __weak void exynos_backlight_reset(void) 465 { 466 } 467 468 __weak int exynos_lcd_misc_init(struct vidinfo *vid) 469 { 470 return 0; 471 } 472 473 static void lcd_panel_on(struct vidinfo *vid) 474 { 475 struct gpio_desc pwm_out_gpio; 476 struct gpio_desc bl_en_gpio; 477 unsigned int node; 478 479 udelay(vid->init_delay); 480 481 exynos_backlight_reset(); 482 483 exynos_cfg_lcd_gpio(); 484 485 exynos_lcd_power_on(); 486 487 udelay(vid->power_on_delay); 488 489 if (vid->dp_enabled) 490 exynos_init_dp(); 491 492 exynos_reset_lcd(); 493 494 udelay(vid->reset_delay); 495 496 exynos_backlight_on(1); 497 498 node = fdtdec_next_compatible(gd->fdt_blob, 0, 499 COMPAT_SAMSUNG_EXYNOS_FIMD); 500 if (node <= 0) { 501 debug("FIMD: Can't get device node for FIMD\n"); 502 return; 503 } 504 gpio_request_by_name_nodev(gd->fdt_blob, node, "samsung,pwm-out-gpio", 505 0, &pwm_out_gpio, 506 GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); 507 508 gpio_request_by_name_nodev(gd->fdt_blob, node, "samsung,bl-en-gpio", 0, 509 &bl_en_gpio, 510 GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); 511 512 exynos_cfg_ldo(); 513 514 exynos_enable_ldo(1); 515 516 if (vid->mipi_enabled) 517 exynos_mipi_dsi_init(panel_info.dsim_platform_data_dt); 518 } 519 520 int exynos_lcd_early_init(const void *blob) 521 { 522 unsigned int node; 523 node = fdtdec_next_compatible(blob, 0, COMPAT_SAMSUNG_EXYNOS_FIMD); 524 if (node <= 0) { 525 debug("exynos_fb: Can't get device node for fimd\n"); 526 return -ENODEV; 527 } 528 529 panel_info.vl_col = fdtdec_get_int(blob, node, "samsung,vl-col", 0); 530 if (panel_info.vl_col == 0) { 531 debug("Can't get XRES\n"); 532 return -ENXIO; 533 } 534 535 panel_info.vl_row = fdtdec_get_int(blob, node, "samsung,vl-row", 0); 536 if (panel_info.vl_row == 0) { 537 debug("Can't get YRES\n"); 538 return -ENXIO; 539 } 540 541 panel_info.vl_width = fdtdec_get_int(blob, node, 542 "samsung,vl-width", 0); 543 544 panel_info.vl_height = fdtdec_get_int(blob, node, 545 "samsung,vl-height", 0); 546 547 panel_info.vl_freq = fdtdec_get_int(blob, node, "samsung,vl-freq", 0); 548 if (panel_info.vl_freq == 0) { 549 debug("Can't get refresh rate\n"); 550 return -ENXIO; 551 } 552 553 if (fdtdec_get_bool(blob, node, "samsung,vl-clkp")) 554 panel_info.vl_clkp = CONFIG_SYS_LOW; 555 556 if (fdtdec_get_bool(blob, node, "samsung,vl-oep")) 557 panel_info.vl_oep = CONFIG_SYS_LOW; 558 559 if (fdtdec_get_bool(blob, node, "samsung,vl-hsp")) 560 panel_info.vl_hsp = CONFIG_SYS_LOW; 561 562 if (fdtdec_get_bool(blob, node, "samsung,vl-vsp")) 563 panel_info.vl_vsp = CONFIG_SYS_LOW; 564 565 if (fdtdec_get_bool(blob, node, "samsung,vl-dp")) 566 panel_info.vl_dp = CONFIG_SYS_LOW; 567 568 panel_info.vl_bpix = fdtdec_get_int(blob, node, "samsung,vl-bpix", 0); 569 if (panel_info.vl_bpix == 0) { 570 debug("Can't get bits per pixel\n"); 571 return -ENXIO; 572 } 573 574 panel_info.vl_hspw = fdtdec_get_int(blob, node, "samsung,vl-hspw", 0); 575 if (panel_info.vl_hspw == 0) { 576 debug("Can't get hsync width\n"); 577 return -ENXIO; 578 } 579 580 panel_info.vl_hfpd = fdtdec_get_int(blob, node, "samsung,vl-hfpd", 0); 581 if (panel_info.vl_hfpd == 0) { 582 debug("Can't get right margin\n"); 583 return -ENXIO; 584 } 585 586 panel_info.vl_hbpd = (u_char)fdtdec_get_int(blob, node, 587 "samsung,vl-hbpd", 0); 588 if (panel_info.vl_hbpd == 0) { 589 debug("Can't get left margin\n"); 590 return -ENXIO; 591 } 592 593 panel_info.vl_vspw = (u_char)fdtdec_get_int(blob, node, 594 "samsung,vl-vspw", 0); 595 if (panel_info.vl_vspw == 0) { 596 debug("Can't get vsync width\n"); 597 return -ENXIO; 598 } 599 600 panel_info.vl_vfpd = fdtdec_get_int(blob, node, 601 "samsung,vl-vfpd", 0); 602 if (panel_info.vl_vfpd == 0) { 603 debug("Can't get lower margin\n"); 604 return -ENXIO; 605 } 606 607 panel_info.vl_vbpd = fdtdec_get_int(blob, node, "samsung,vl-vbpd", 0); 608 if (panel_info.vl_vbpd == 0) { 609 debug("Can't get upper margin\n"); 610 return -ENXIO; 611 } 612 613 panel_info.vl_cmd_allow_len = fdtdec_get_int(blob, node, 614 "samsung,vl-cmd-allow-len", 0); 615 616 panel_info.win_id = fdtdec_get_int(blob, node, "samsung,winid", 0); 617 panel_info.init_delay = fdtdec_get_int(blob, node, 618 "samsung,init-delay", 0); 619 panel_info.power_on_delay = fdtdec_get_int(blob, node, 620 "samsung,power-on-delay", 0); 621 panel_info.reset_delay = fdtdec_get_int(blob, node, 622 "samsung,reset-delay", 0); 623 panel_info.interface_mode = fdtdec_get_int(blob, node, 624 "samsung,interface-mode", 0); 625 panel_info.mipi_enabled = fdtdec_get_int(blob, node, 626 "samsung,mipi-enabled", 0); 627 panel_info.dp_enabled = fdtdec_get_int(blob, node, 628 "samsung,dp-enabled", 0); 629 panel_info.cs_setup = fdtdec_get_int(blob, node, 630 "samsung,cs-setup", 0); 631 panel_info.wr_setup = fdtdec_get_int(blob, node, 632 "samsung,wr-setup", 0); 633 panel_info.wr_act = fdtdec_get_int(blob, node, "samsung,wr-act", 0); 634 panel_info.wr_hold = fdtdec_get_int(blob, node, "samsung,wr-hold", 0); 635 636 panel_info.logo_on = fdtdec_get_int(blob, node, "samsung,logo-on", 0); 637 if (panel_info.logo_on) { 638 panel_info.logo_width = fdtdec_get_int(blob, node, 639 "samsung,logo-width", 0); 640 panel_info.logo_height = fdtdec_get_int(blob, node, 641 "samsung,logo-height", 0); 642 panel_info.logo_addr = fdtdec_get_int(blob, node, 643 "samsung,logo-addr", 0); 644 } 645 646 panel_info.rgb_mode = fdtdec_get_int(blob, node, 647 "samsung,rgb-mode", 0); 648 panel_info.pclk_name = fdtdec_get_int(blob, node, 649 "samsung,pclk-name", 0); 650 panel_info.sclk_div = fdtdec_get_int(blob, node, 651 "samsung,sclk-div", 0); 652 panel_info.dual_lcd_enabled = fdtdec_get_int(blob, node, 653 "samsung,dual-lcd-enabled", 0); 654 655 return 0; 656 } 657 658 void lcd_ctrl_init(void *lcdbase) 659 { 660 set_system_display_ctrl(); 661 set_lcd_clk(); 662 663 #ifdef CONFIG_EXYNOS_MIPI_DSIM 664 exynos_init_dsim_platform_data(&panel_info); 665 #endif 666 exynos_lcd_misc_init(&panel_info); 667 668 exynos_lcd_init(&panel_info, (ulong)lcdbase); 669 } 670 671 void lcd_enable(void) 672 { 673 if (panel_info.logo_on) { 674 memset((void *)gd->fb_base, 0, 675 panel_info.vl_width * panel_info.vl_height * 676 (NBITS(panel_info.vl_bpix) >> 3)); 677 } 678 679 lcd_panel_on(&panel_info); 680 } 681 682 /* dummy function */ 683 void lcd_setcolreg(ushort regno, ushort red, ushort green, ushort blue) 684 { 685 return; 686 } 687