1 /* 2 * Porting to u-boot: 3 * 4 * (C) Copyright 2011 5 * Stefano Babic, DENX Software Engineering, sbabic@denx.de. 6 * 7 * Copyright (C) 2008-2009 MontaVista Software Inc. 8 * Copyright (C) 2008-2009 Texas Instruments Inc 9 * 10 * Based on the LCD driver for TI Avalanche processors written by 11 * Ajay Singh and Shalom Hai. 12 * 13 * SPDX-License-Identifier: GPL-2.0+ 14 */ 15 16 #include <common.h> 17 #include <malloc.h> 18 #include <video_fb.h> 19 #include <linux/list.h> 20 #include <linux/fb.h> 21 22 #include <asm/errno.h> 23 #include <asm/io.h> 24 #include <asm/arch/hardware.h> 25 26 #include "videomodes.h" 27 #include <asm/arch/da8xx-fb.h> 28 29 #define DRIVER_NAME "da8xx_lcdc" 30 31 /* LCD Status Register */ 32 #define LCD_END_OF_FRAME1 (1 << 9) 33 #define LCD_END_OF_FRAME0 (1 << 8) 34 #define LCD_PL_LOAD_DONE (1 << 6) 35 #define LCD_FIFO_UNDERFLOW (1 << 5) 36 #define LCD_SYNC_LOST (1 << 2) 37 38 /* LCD DMA Control Register */ 39 #define LCD_DMA_BURST_SIZE(x) ((x) << 4) 40 #define LCD_DMA_BURST_1 0x0 41 #define LCD_DMA_BURST_2 0x1 42 #define LCD_DMA_BURST_4 0x2 43 #define LCD_DMA_BURST_8 0x3 44 #define LCD_DMA_BURST_16 0x4 45 #define LCD_END_OF_FRAME_INT_ENA (1 << 2) 46 #define LCD_DUAL_FRAME_BUFFER_ENABLE (1 << 0) 47 48 /* LCD Control Register */ 49 #define LCD_CLK_DIVISOR(x) ((x) << 8) 50 #define LCD_RASTER_MODE 0x01 51 52 /* LCD Raster Control Register */ 53 #define LCD_PALETTE_LOAD_MODE(x) ((x) << 20) 54 #define PALETTE_AND_DATA 0x00 55 #define PALETTE_ONLY 0x01 56 #define DATA_ONLY 0x02 57 58 #define LCD_MONO_8BIT_MODE (1 << 9) 59 #define LCD_RASTER_ORDER (1 << 8) 60 #define LCD_TFT_MODE (1 << 7) 61 #define LCD_UNDERFLOW_INT_ENA (1 << 6) 62 #define LCD_PL_ENABLE (1 << 4) 63 #define LCD_MONOCHROME_MODE (1 << 1) 64 #define LCD_RASTER_ENABLE (1 << 0) 65 #define LCD_TFT_ALT_ENABLE (1 << 23) 66 #define LCD_STN_565_ENABLE (1 << 24) 67 68 /* LCD Raster Timing 2 Register */ 69 #define LCD_AC_BIAS_TRANSITIONS_PER_INT(x) ((x) << 16) 70 #define LCD_AC_BIAS_FREQUENCY(x) ((x) << 8) 71 #define LCD_SYNC_CTRL (1 << 25) 72 #define LCD_SYNC_EDGE (1 << 24) 73 #define LCD_INVERT_PIXEL_CLOCK (1 << 22) 74 #define LCD_INVERT_LINE_CLOCK (1 << 21) 75 #define LCD_INVERT_FRAME_CLOCK (1 << 20) 76 77 /* LCD Block */ 78 struct da8xx_lcd_regs { 79 u32 revid; 80 u32 ctrl; 81 u32 stat; 82 u32 lidd_ctrl; 83 u32 lidd_cs0_conf; 84 u32 lidd_cs0_addr; 85 u32 lidd_cs0_data; 86 u32 lidd_cs1_conf; 87 u32 lidd_cs1_addr; 88 u32 lidd_cs1_data; 89 u32 raster_ctrl; 90 u32 raster_timing_0; 91 u32 raster_timing_1; 92 u32 raster_timing_2; 93 u32 raster_subpanel; 94 u32 reserved; 95 u32 dma_ctrl; 96 u32 dma_frm_buf_base_addr_0; 97 u32 dma_frm_buf_ceiling_addr_0; 98 u32 dma_frm_buf_base_addr_1; 99 u32 dma_frm_buf_ceiling_addr_1; 100 }; 101 102 #define LCD_NUM_BUFFERS 1 103 104 #define WSI_TIMEOUT 50 105 #define PALETTE_SIZE 256 106 #define LEFT_MARGIN 64 107 #define RIGHT_MARGIN 64 108 #define UPPER_MARGIN 32 109 #define LOWER_MARGIN 32 110 111 #define calc_fbsize() (panel.plnSizeX * panel.plnSizeY * panel.gdfBytesPP) 112 113 static struct da8xx_lcd_regs *da8xx_fb_reg_base; 114 115 DECLARE_GLOBAL_DATA_PTR; 116 117 /* graphics setup */ 118 static GraphicDevice gpanel; 119 static const struct da8xx_panel *lcd_panel; 120 static struct fb_info *da8xx_fb_info; 121 static int bits_x_pixel; 122 123 static inline unsigned int lcdc_read(u32 *addr) 124 { 125 return (unsigned int)readl(addr); 126 } 127 128 static inline void lcdc_write(unsigned int val, u32 *addr) 129 { 130 writel(val, addr); 131 } 132 133 struct da8xx_fb_par { 134 u32 p_palette_base; 135 unsigned char *v_palette_base; 136 dma_addr_t vram_phys; 137 unsigned long vram_size; 138 void *vram_virt; 139 unsigned int dma_start; 140 unsigned int dma_end; 141 struct clk *lcdc_clk; 142 int irq; 143 unsigned short pseudo_palette[16]; 144 unsigned int palette_sz; 145 unsigned int pxl_clk; 146 int blank; 147 int vsync_flag; 148 int vsync_timeout; 149 }; 150 151 152 /* Variable Screen Information */ 153 static struct fb_var_screeninfo da8xx_fb_var = { 154 .xoffset = 0, 155 .yoffset = 0, 156 .transp = {0, 0, 0}, 157 .nonstd = 0, 158 .activate = 0, 159 .height = -1, 160 .width = -1, 161 .pixclock = 46666, /* 46us - AUO display */ 162 .accel_flags = 0, 163 .left_margin = LEFT_MARGIN, 164 .right_margin = RIGHT_MARGIN, 165 .upper_margin = UPPER_MARGIN, 166 .lower_margin = LOWER_MARGIN, 167 .sync = 0, 168 .vmode = FB_VMODE_NONINTERLACED 169 }; 170 171 static struct fb_fix_screeninfo da8xx_fb_fix = { 172 .id = "DA8xx FB Drv", 173 .type = FB_TYPE_PACKED_PIXELS, 174 .type_aux = 0, 175 .visual = FB_VISUAL_PSEUDOCOLOR, 176 .xpanstep = 0, 177 .ypanstep = 1, 178 .ywrapstep = 0, 179 .accel = FB_ACCEL_NONE 180 }; 181 182 static const struct display_panel disp_panel = { 183 QVGA, 184 16, 185 16, 186 COLOR_ACTIVE, 187 }; 188 189 static const struct lcd_ctrl_config lcd_cfg = { 190 &disp_panel, 191 .ac_bias = 255, 192 .ac_bias_intrpt = 0, 193 .dma_burst_sz = 16, 194 .bpp = 16, 195 .fdd = 255, 196 .tft_alt_mode = 0, 197 .stn_565_mode = 0, 198 .mono_8bit_mode = 0, 199 .invert_line_clock = 1, 200 .invert_frm_clock = 1, 201 .sync_edge = 0, 202 .sync_ctrl = 1, 203 .raster_order = 0, 204 }; 205 206 /* Enable the Raster Engine of the LCD Controller */ 207 static inline void lcd_enable_raster(void) 208 { 209 u32 reg; 210 211 reg = lcdc_read(&da8xx_fb_reg_base->raster_ctrl); 212 if (!(reg & LCD_RASTER_ENABLE)) 213 lcdc_write(reg | LCD_RASTER_ENABLE, 214 &da8xx_fb_reg_base->raster_ctrl); 215 } 216 217 /* Disable the Raster Engine of the LCD Controller */ 218 static inline void lcd_disable_raster(void) 219 { 220 u32 reg; 221 222 reg = lcdc_read(&da8xx_fb_reg_base->raster_ctrl); 223 if (reg & LCD_RASTER_ENABLE) 224 lcdc_write(reg & ~LCD_RASTER_ENABLE, 225 &da8xx_fb_reg_base->raster_ctrl); 226 } 227 228 static void lcd_blit(int load_mode, struct da8xx_fb_par *par) 229 { 230 u32 start; 231 u32 end; 232 u32 reg_ras; 233 u32 reg_dma; 234 235 /* init reg to clear PLM (loading mode) fields */ 236 reg_ras = lcdc_read(&da8xx_fb_reg_base->raster_ctrl); 237 reg_ras &= ~(3 << 20); 238 239 reg_dma = lcdc_read(&da8xx_fb_reg_base->dma_ctrl); 240 241 if (load_mode == LOAD_DATA) { 242 start = par->dma_start; 243 end = par->dma_end; 244 245 reg_ras |= LCD_PALETTE_LOAD_MODE(DATA_ONLY); 246 reg_dma |= LCD_END_OF_FRAME_INT_ENA; 247 248 #if (LCD_NUM_BUFFERS == 2) 249 reg_dma |= LCD_DUAL_FRAME_BUFFER_ENABLE; 250 lcdc_write(start, &da8xx_fb_reg_base->dma_frm_buf_base_addr_0); 251 lcdc_write(end, &da8xx_fb_reg_base->dma_frm_buf_ceiling_addr_0); 252 lcdc_write(start, &da8xx_fb_reg_base->dma_frm_buf_base_addr_1); 253 lcdc_write(end, &da8xx_fb_reg_base->dma_frm_buf_ceiling_addr_1); 254 #else 255 reg_dma &= ~LCD_DUAL_FRAME_BUFFER_ENABLE; 256 lcdc_write(start, &da8xx_fb_reg_base->dma_frm_buf_base_addr_0); 257 lcdc_write(end, &da8xx_fb_reg_base->dma_frm_buf_ceiling_addr_0); 258 lcdc_write(0, &da8xx_fb_reg_base->dma_frm_buf_base_addr_1); 259 lcdc_write(0, &da8xx_fb_reg_base->dma_frm_buf_ceiling_addr_1); 260 #endif 261 262 } else if (load_mode == LOAD_PALETTE) { 263 start = par->p_palette_base; 264 end = start + par->palette_sz - 1; 265 266 reg_ras |= LCD_PALETTE_LOAD_MODE(PALETTE_ONLY); 267 reg_ras |= LCD_PL_ENABLE; 268 269 lcdc_write(start, &da8xx_fb_reg_base->dma_frm_buf_base_addr_0); 270 lcdc_write(end, &da8xx_fb_reg_base->dma_frm_buf_ceiling_addr_0); 271 } 272 273 lcdc_write(reg_dma, &da8xx_fb_reg_base->dma_ctrl); 274 lcdc_write(reg_ras, &da8xx_fb_reg_base->raster_ctrl); 275 276 /* 277 * The Raster enable bit must be set after all other control fields are 278 * set. 279 */ 280 lcd_enable_raster(); 281 } 282 283 /* Configure the Burst Size of DMA */ 284 static int lcd_cfg_dma(int burst_size) 285 { 286 u32 reg; 287 288 reg = lcdc_read(&da8xx_fb_reg_base->dma_ctrl) & 0x00000001; 289 switch (burst_size) { 290 case 1: 291 reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_1); 292 break; 293 case 2: 294 reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_2); 295 break; 296 case 4: 297 reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_4); 298 break; 299 case 8: 300 reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_8); 301 break; 302 case 16: 303 reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_16); 304 break; 305 default: 306 return -EINVAL; 307 } 308 lcdc_write(reg, &da8xx_fb_reg_base->dma_ctrl); 309 310 return 0; 311 } 312 313 static void lcd_cfg_ac_bias(int period, int transitions_per_int) 314 { 315 u32 reg; 316 317 /* Set the AC Bias Period and Number of Transisitons per Interrupt */ 318 reg = lcdc_read(&da8xx_fb_reg_base->raster_timing_2) & 0xFFF00000; 319 reg |= LCD_AC_BIAS_FREQUENCY(period) | 320 LCD_AC_BIAS_TRANSITIONS_PER_INT(transitions_per_int); 321 lcdc_write(reg, &da8xx_fb_reg_base->raster_timing_2); 322 } 323 324 static void lcd_cfg_horizontal_sync(int back_porch, int pulse_width, 325 int front_porch) 326 { 327 u32 reg; 328 329 reg = lcdc_read(&da8xx_fb_reg_base->raster_timing_0) & 0xf; 330 reg |= ((back_porch & 0xff) << 24) 331 | ((front_porch & 0xff) << 16) 332 | ((pulse_width & 0x3f) << 10); 333 lcdc_write(reg, &da8xx_fb_reg_base->raster_timing_0); 334 } 335 336 static void lcd_cfg_vertical_sync(int back_porch, int pulse_width, 337 int front_porch) 338 { 339 u32 reg; 340 341 reg = lcdc_read(&da8xx_fb_reg_base->raster_timing_1) & 0x3ff; 342 reg |= ((back_porch & 0xff) << 24) 343 | ((front_porch & 0xff) << 16) 344 | ((pulse_width & 0x3f) << 10); 345 lcdc_write(reg, &da8xx_fb_reg_base->raster_timing_1); 346 } 347 348 static int lcd_cfg_display(const struct lcd_ctrl_config *cfg) 349 { 350 u32 reg; 351 352 reg = lcdc_read(&da8xx_fb_reg_base->raster_ctrl) & ~(LCD_TFT_MODE | 353 LCD_MONO_8BIT_MODE | 354 LCD_MONOCHROME_MODE); 355 356 switch (cfg->p_disp_panel->panel_shade) { 357 case MONOCHROME: 358 reg |= LCD_MONOCHROME_MODE; 359 if (cfg->mono_8bit_mode) 360 reg |= LCD_MONO_8BIT_MODE; 361 break; 362 case COLOR_ACTIVE: 363 reg |= LCD_TFT_MODE; 364 if (cfg->tft_alt_mode) 365 reg |= LCD_TFT_ALT_ENABLE; 366 break; 367 368 case COLOR_PASSIVE: 369 if (cfg->stn_565_mode) 370 reg |= LCD_STN_565_ENABLE; 371 break; 372 373 default: 374 return -EINVAL; 375 } 376 377 /* enable additional interrupts here */ 378 reg |= LCD_UNDERFLOW_INT_ENA; 379 380 lcdc_write(reg, &da8xx_fb_reg_base->raster_ctrl); 381 382 reg = lcdc_read(&da8xx_fb_reg_base->raster_timing_2); 383 384 if (cfg->sync_ctrl) 385 reg |= LCD_SYNC_CTRL; 386 else 387 reg &= ~LCD_SYNC_CTRL; 388 389 if (cfg->sync_edge) 390 reg |= LCD_SYNC_EDGE; 391 else 392 reg &= ~LCD_SYNC_EDGE; 393 394 if (cfg->invert_line_clock) 395 reg |= LCD_INVERT_LINE_CLOCK; 396 else 397 reg &= ~LCD_INVERT_LINE_CLOCK; 398 399 if (cfg->invert_frm_clock) 400 reg |= LCD_INVERT_FRAME_CLOCK; 401 else 402 reg &= ~LCD_INVERT_FRAME_CLOCK; 403 404 lcdc_write(reg, &da8xx_fb_reg_base->raster_timing_2); 405 406 return 0; 407 } 408 409 static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height, 410 u32 bpp, u32 raster_order) 411 { 412 u32 reg; 413 414 /* Set the Panel Width */ 415 /* Pixels per line = (PPL + 1)*16 */ 416 /*0x3F in bits 4..9 gives max horisontal resolution = 1024 pixels*/ 417 width &= 0x3f0; 418 reg = lcdc_read(&da8xx_fb_reg_base->raster_timing_0); 419 reg &= 0xfffffc00; 420 reg |= ((width >> 4) - 1) << 4; 421 lcdc_write(reg, &da8xx_fb_reg_base->raster_timing_0); 422 423 /* Set the Panel Height */ 424 reg = lcdc_read(&da8xx_fb_reg_base->raster_timing_1); 425 reg = ((height - 1) & 0x3ff) | (reg & 0xfffffc00); 426 lcdc_write(reg, &da8xx_fb_reg_base->raster_timing_1); 427 428 /* Set the Raster Order of the Frame Buffer */ 429 reg = lcdc_read(&da8xx_fb_reg_base->raster_ctrl) & ~(1 << 8); 430 if (raster_order) 431 reg |= LCD_RASTER_ORDER; 432 lcdc_write(reg, &da8xx_fb_reg_base->raster_ctrl); 433 434 switch (bpp) { 435 case 1: 436 case 2: 437 case 4: 438 case 16: 439 par->palette_sz = 16 * 2; 440 break; 441 442 case 8: 443 par->palette_sz = 256 * 2; 444 break; 445 446 default: 447 return -EINVAL; 448 } 449 450 return 0; 451 } 452 453 static int fb_setcolreg(unsigned regno, unsigned red, unsigned green, 454 unsigned blue, unsigned transp, 455 struct fb_info *info) 456 { 457 struct da8xx_fb_par *par = info->par; 458 unsigned short *palette = (unsigned short *) par->v_palette_base; 459 u_short pal; 460 int update_hw = 0; 461 462 if (regno > 255) 463 return 1; 464 465 if (info->fix.visual == FB_VISUAL_DIRECTCOLOR) 466 return 1; 467 468 if (info->var.bits_per_pixel == 8) { 469 red >>= 4; 470 green >>= 8; 471 blue >>= 12; 472 473 pal = (red & 0x0f00); 474 pal |= (green & 0x00f0); 475 pal |= (blue & 0x000f); 476 477 if (palette[regno] != pal) { 478 update_hw = 1; 479 palette[regno] = pal; 480 } 481 } else if ((info->var.bits_per_pixel == 16) && regno < 16) { 482 red >>= (16 - info->var.red.length); 483 red <<= info->var.red.offset; 484 485 green >>= (16 - info->var.green.length); 486 green <<= info->var.green.offset; 487 488 blue >>= (16 - info->var.blue.length); 489 blue <<= info->var.blue.offset; 490 491 par->pseudo_palette[regno] = red | green | blue; 492 493 if (palette[0] != 0x4000) { 494 update_hw = 1; 495 palette[0] = 0x4000; 496 } 497 } 498 499 /* Update the palette in the h/w as needed. */ 500 if (update_hw) 501 lcd_blit(LOAD_PALETTE, par); 502 503 return 0; 504 } 505 506 static void lcd_reset(struct da8xx_fb_par *par) 507 { 508 /* Disable the Raster if previously Enabled */ 509 lcd_disable_raster(); 510 511 /* DMA has to be disabled */ 512 lcdc_write(0, &da8xx_fb_reg_base->dma_ctrl); 513 lcdc_write(0, &da8xx_fb_reg_base->raster_ctrl); 514 } 515 516 static void lcd_calc_clk_divider(struct da8xx_fb_par *par) 517 { 518 unsigned int lcd_clk, div; 519 520 /* Get clock from sysclk2 */ 521 lcd_clk = clk_get(2); 522 523 div = lcd_clk / par->pxl_clk; 524 debug("LCD Clock: 0x%x Divider: 0x%x PixClk: 0x%x\n", 525 lcd_clk, div, par->pxl_clk); 526 527 /* Configure the LCD clock divisor. */ 528 lcdc_write(LCD_CLK_DIVISOR(div) | 529 (LCD_RASTER_MODE & 0x1), &da8xx_fb_reg_base->ctrl); 530 } 531 532 static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg, 533 const struct da8xx_panel *panel) 534 { 535 u32 bpp; 536 int ret = 0; 537 538 lcd_reset(par); 539 540 /* Calculate the divider */ 541 lcd_calc_clk_divider(par); 542 543 if (panel->invert_pxl_clk) 544 lcdc_write((lcdc_read(&da8xx_fb_reg_base->raster_timing_2) | 545 LCD_INVERT_PIXEL_CLOCK), 546 &da8xx_fb_reg_base->raster_timing_2); 547 else 548 lcdc_write((lcdc_read(&da8xx_fb_reg_base->raster_timing_2) & 549 ~LCD_INVERT_PIXEL_CLOCK), 550 &da8xx_fb_reg_base->raster_timing_2); 551 552 /* Configure the DMA burst size. */ 553 ret = lcd_cfg_dma(cfg->dma_burst_sz); 554 if (ret < 0) 555 return ret; 556 557 /* Configure the AC bias properties. */ 558 lcd_cfg_ac_bias(cfg->ac_bias, cfg->ac_bias_intrpt); 559 560 /* Configure the vertical and horizontal sync properties. */ 561 lcd_cfg_vertical_sync(panel->vbp, panel->vsw, panel->vfp); 562 lcd_cfg_horizontal_sync(panel->hbp, panel->hsw, panel->hfp); 563 564 /* Configure for disply */ 565 ret = lcd_cfg_display(cfg); 566 if (ret < 0) 567 return ret; 568 569 if (QVGA != cfg->p_disp_panel->panel_type) 570 return -EINVAL; 571 572 if (cfg->bpp <= cfg->p_disp_panel->max_bpp && 573 cfg->bpp >= cfg->p_disp_panel->min_bpp) 574 bpp = cfg->bpp; 575 else 576 bpp = cfg->p_disp_panel->max_bpp; 577 if (bpp == 12) 578 bpp = 16; 579 ret = lcd_cfg_frame_buffer(par, (unsigned int)panel->width, 580 (unsigned int)panel->height, bpp, 581 cfg->raster_order); 582 if (ret < 0) 583 return ret; 584 585 /* Configure FDD */ 586 lcdc_write((lcdc_read(&da8xx_fb_reg_base->raster_ctrl) & 0xfff00fff) | 587 (cfg->fdd << 12), &da8xx_fb_reg_base->raster_ctrl); 588 589 return 0; 590 } 591 592 static void lcdc_dma_start(void) 593 { 594 struct da8xx_fb_par *par = da8xx_fb_info->par; 595 lcdc_write(par->dma_start, 596 &da8xx_fb_reg_base->dma_frm_buf_base_addr_0); 597 lcdc_write(par->dma_end, 598 &da8xx_fb_reg_base->dma_frm_buf_ceiling_addr_0); 599 lcdc_write(0, 600 &da8xx_fb_reg_base->dma_frm_buf_base_addr_1); 601 lcdc_write(0, 602 &da8xx_fb_reg_base->dma_frm_buf_ceiling_addr_1); 603 } 604 605 static u32 lcdc_irq_handler(void) 606 { 607 struct da8xx_fb_par *par = da8xx_fb_info->par; 608 u32 stat = lcdc_read(&da8xx_fb_reg_base->stat); 609 u32 reg_ras; 610 611 if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) { 612 debug("LCD_SYNC_LOST\n"); 613 lcd_disable_raster(); 614 lcdc_write(stat, &da8xx_fb_reg_base->stat); 615 lcd_enable_raster(); 616 return LCD_SYNC_LOST; 617 } else if (stat & LCD_PL_LOAD_DONE) { 618 debug("LCD_PL_LOAD_DONE\n"); 619 /* 620 * Must disable raster before changing state of any control bit. 621 * And also must be disabled before clearing the PL loading 622 * interrupt via the following write to the status register. If 623 * this is done after then one gets multiple PL done interrupts. 624 */ 625 lcd_disable_raster(); 626 627 lcdc_write(stat, &da8xx_fb_reg_base->stat); 628 629 /* Disable PL completion inerrupt */ 630 reg_ras = lcdc_read(&da8xx_fb_reg_base->raster_ctrl); 631 reg_ras &= ~LCD_PL_ENABLE; 632 lcdc_write(reg_ras, &da8xx_fb_reg_base->raster_ctrl); 633 634 /* Setup and start data loading mode */ 635 lcd_blit(LOAD_DATA, par); 636 return LCD_PL_LOAD_DONE; 637 } else { 638 lcdc_write(stat, &da8xx_fb_reg_base->stat); 639 640 if (stat & LCD_END_OF_FRAME0) 641 debug("LCD_END_OF_FRAME0\n"); 642 643 lcdc_write(par->dma_start, 644 &da8xx_fb_reg_base->dma_frm_buf_base_addr_0); 645 lcdc_write(par->dma_end, 646 &da8xx_fb_reg_base->dma_frm_buf_ceiling_addr_0); 647 par->vsync_flag = 1; 648 return LCD_END_OF_FRAME0; 649 } 650 return stat; 651 } 652 653 static u32 wait_for_event(u32 event) 654 { 655 u32 timeout = 50000; 656 u32 ret; 657 658 do { 659 ret = lcdc_irq_handler(); 660 udelay(1000); 661 } while (!(ret & event)); 662 663 if (timeout <= 0) { 664 printf("%s: event %d not hit\n", __func__, event); 665 return -1; 666 } 667 668 return 0; 669 670 } 671 672 void *video_hw_init(void) 673 { 674 struct da8xx_fb_par *par; 675 u32 size; 676 char *p; 677 678 if (!lcd_panel) { 679 printf("Display not initialized\n"); 680 return NULL; 681 } 682 gpanel.winSizeX = lcd_panel->width; 683 gpanel.winSizeY = lcd_panel->height; 684 gpanel.plnSizeX = lcd_panel->width; 685 gpanel.plnSizeY = lcd_panel->height; 686 687 switch (bits_x_pixel) { 688 case 24: 689 gpanel.gdfBytesPP = 4; 690 gpanel.gdfIndex = GDF_32BIT_X888RGB; 691 break; 692 case 16: 693 gpanel.gdfBytesPP = 2; 694 gpanel.gdfIndex = GDF_16BIT_565RGB; 695 break; 696 default: 697 gpanel.gdfBytesPP = 1; 698 gpanel.gdfIndex = GDF__8BIT_INDEX; 699 break; 700 } 701 702 da8xx_fb_reg_base = (struct da8xx_lcd_regs *)DAVINCI_LCD_CNTL_BASE; 703 704 debug("Resolution: %dx%d %x\n", 705 gpanel.winSizeX, 706 gpanel.winSizeY, 707 lcd_cfg.bpp); 708 709 size = sizeof(struct fb_info) + sizeof(struct da8xx_fb_par); 710 da8xx_fb_info = malloc(size); 711 debug("da8xx_fb_info at %x\n", (unsigned int)da8xx_fb_info); 712 713 if (!da8xx_fb_info) { 714 printf("Memory allocation failed for fb_info\n"); 715 return NULL; 716 } 717 memset(da8xx_fb_info, 0, size); 718 p = (char *)da8xx_fb_info; 719 da8xx_fb_info->par = p + sizeof(struct fb_info); 720 debug("da8xx_par at %x\n", (unsigned int)da8xx_fb_info->par); 721 722 par = da8xx_fb_info->par; 723 par->pxl_clk = lcd_panel->pxl_clk; 724 725 if (lcd_init(par, &lcd_cfg, lcd_panel) < 0) { 726 printf("lcd_init failed\n"); 727 goto err_release_fb; 728 } 729 730 /* allocate frame buffer */ 731 par->vram_size = lcd_panel->width * lcd_panel->height * lcd_cfg.bpp; 732 par->vram_size = par->vram_size * LCD_NUM_BUFFERS / 8; 733 734 par->vram_virt = malloc(par->vram_size); 735 736 par->vram_phys = (dma_addr_t) par->vram_virt; 737 debug("Requesting 0x%x bytes for framebuffer at 0x%x\n", 738 (unsigned int)par->vram_size, 739 (unsigned int)par->vram_virt); 740 if (!par->vram_virt) { 741 printf("GLCD: malloc for frame buffer failed\n"); 742 goto err_release_fb; 743 } 744 745 gpanel.frameAdrs = (unsigned int)par->vram_virt; 746 da8xx_fb_info->screen_base = (char *) par->vram_virt; 747 da8xx_fb_fix.smem_start = gpanel.frameAdrs; 748 da8xx_fb_fix.smem_len = par->vram_size; 749 da8xx_fb_fix.line_length = (lcd_panel->width * lcd_cfg.bpp) / 8; 750 751 par->dma_start = par->vram_phys; 752 par->dma_end = par->dma_start + lcd_panel->height * 753 da8xx_fb_fix.line_length - 1; 754 755 /* allocate palette buffer */ 756 par->v_palette_base = malloc(PALETTE_SIZE); 757 if (!par->v_palette_base) { 758 printf("GLCD: malloc for palette buffer failed\n"); 759 goto err_release_fb_mem; 760 } 761 memset(par->v_palette_base, 0, PALETTE_SIZE); 762 par->p_palette_base = (unsigned int)par->v_palette_base; 763 764 /* Initialize par */ 765 da8xx_fb_info->var.bits_per_pixel = lcd_cfg.bpp; 766 767 da8xx_fb_var.xres = lcd_panel->width; 768 da8xx_fb_var.xres_virtual = lcd_panel->width; 769 770 da8xx_fb_var.yres = lcd_panel->height; 771 da8xx_fb_var.yres_virtual = lcd_panel->height * LCD_NUM_BUFFERS; 772 773 da8xx_fb_var.grayscale = 774 lcd_cfg.p_disp_panel->panel_shade == MONOCHROME ? 1 : 0; 775 da8xx_fb_var.bits_per_pixel = lcd_cfg.bpp; 776 777 da8xx_fb_var.hsync_len = lcd_panel->hsw; 778 da8xx_fb_var.vsync_len = lcd_panel->vsw; 779 780 /* Initialize fbinfo */ 781 da8xx_fb_info->flags = FBINFO_FLAG_DEFAULT; 782 da8xx_fb_info->fix = da8xx_fb_fix; 783 da8xx_fb_info->var = da8xx_fb_var; 784 da8xx_fb_info->pseudo_palette = par->pseudo_palette; 785 da8xx_fb_info->fix.visual = (da8xx_fb_info->var.bits_per_pixel <= 8) ? 786 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; 787 788 /* Clear interrupt */ 789 memset((void *)par->vram_virt, 0, par->vram_size); 790 lcd_disable_raster(); 791 lcdc_write(0xFFFF, &da8xx_fb_reg_base->stat); 792 debug("Palette at 0x%x size %d\n", par->p_palette_base, 793 par->palette_sz); 794 lcdc_dma_start(); 795 796 /* Load a default palette */ 797 fb_setcolreg(0, 0, 0, 0, 0xffff, da8xx_fb_info); 798 799 /* Check that the palette is loaded */ 800 wait_for_event(LCD_PL_LOAD_DONE); 801 802 /* Wait until DMA is working */ 803 wait_for_event(LCD_END_OF_FRAME0); 804 805 return (void *)&gpanel; 806 807 err_release_fb_mem: 808 free(par->vram_virt); 809 810 err_release_fb: 811 free(da8xx_fb_info); 812 813 return NULL; 814 } 815 816 void video_set_lut(unsigned int index, /* color number */ 817 unsigned char r, /* red */ 818 unsigned char g, /* green */ 819 unsigned char b /* blue */ 820 ) 821 { 822 823 return; 824 } 825 826 void da8xx_video_init(const struct da8xx_panel *panel, int bits_pixel) 827 { 828 lcd_panel = panel; 829 bits_x_pixel = bits_pixel; 830 } 831