5 * Stefano Babic, DENX Software Engineering, sbabic@denx.de.
7 * Copyright (C) 2008-2009 MontaVista Software Inc.
8 * Copyright (C) 2008-2009 Texas Instruments Inc
10 * Based on the LCD driver for TI Avalanche processors written by
11 * Ajay Singh and Shalom Hai.
13 * SPDX-License-Identifier: GPL-2.0+
19 #include <linux/list.h>
23 #include <asm/errno.h>
25 #include <asm/arch/cpu.h>
27 #include "videomodes.h"
28 #include <asm/arch/da8xx-fb.h>
30 #define DRIVER_NAME "da8xx_lcdc"
32 #define LCD_VERSION_1 1
33 #define LCD_VERSION_2 2
35 #define BIT(x) (1 << (x))
37 /* LCD Status Register */
38 #define LCD_END_OF_FRAME1 BIT(9)
39 #define LCD_END_OF_FRAME0 BIT(8)
40 #define LCD_PL_LOAD_DONE BIT(6)
41 #define LCD_FIFO_UNDERFLOW BIT(5)
42 #define LCD_SYNC_LOST BIT(2)
44 /* LCD DMA Control Register */
45 #define LCD_DMA_BURST_SIZE(x) ((x) << 4)
46 #define LCD_DMA_BURST_SIZE_MASK (0x7 << 4)
47 #define LCD_DMA_BURST_1 0x0
48 #define LCD_DMA_BURST_2 0x1
49 #define LCD_DMA_BURST_4 0x2
50 #define LCD_DMA_BURST_8 0x3
51 #define LCD_DMA_BURST_16 0x4
52 #define LCD_V1_END_OF_FRAME_INT_ENA BIT(2)
53 #define LCD_V2_END_OF_FRAME0_INT_ENA BIT(8)
54 #define LCD_V2_END_OF_FRAME1_INT_ENA BIT(9)
55 #define LCD_DUAL_FRAME_BUFFER_ENABLE BIT(0)
57 /* LCD Control Register */
58 #define LCD_CLK_DIVISOR(x) ((x) << 8)
59 #define LCD_RASTER_MODE 0x01
61 /* LCD Raster Control Register */
62 #define LCD_PALETTE_LOAD_MODE(x) ((x) << 20)
63 #define PALETTE_AND_DATA 0x00
64 #define PALETTE_ONLY 0x01
65 #define DATA_ONLY 0x02
67 #define LCD_MONO_8BIT_MODE BIT(9)
68 #define LCD_RASTER_ORDER BIT(8)
69 #define LCD_TFT_MODE BIT(7)
70 #define LCD_V1_UNDERFLOW_INT_ENA BIT(6)
71 #define LCD_V2_UNDERFLOW_INT_ENA BIT(5)
72 #define LCD_V1_PL_INT_ENA BIT(4)
73 #define LCD_V2_PL_INT_ENA BIT(6)
74 #define LCD_MONOCHROME_MODE BIT(1)
75 #define LCD_RASTER_ENABLE BIT(0)
76 #define LCD_TFT_ALT_ENABLE BIT(23)
77 #define LCD_STN_565_ENABLE BIT(24)
78 #define LCD_TFT24 BIT(25)
79 #define LCD_TFT24_UNPACKED BIT(26)
80 #define LCD_V2_DMA_CLK_EN BIT(2)
81 #define LCD_V2_LIDD_CLK_EN BIT(1)
82 #define LCD_V2_CORE_CLK_EN BIT(0)
83 #define LCD_V2_LPP_B10 26
85 /* LCD Raster Timing 2 Register */
86 #define LCD_AC_BIAS_TRANSITIONS_PER_INT(x) ((x) << 16)
87 #define LCD_AC_BIAS_FREQUENCY(x) ((x) << 8)
88 #define LCD_SYNC_CTRL BIT(25)
89 #define LCD_SYNC_EDGE BIT(24)
90 #define LCD_INVERT_PIXEL_CLOCK BIT(22)
91 #define LCD_INVERT_LINE_CLOCK BIT(21)
92 #define LCD_INVERT_FRAME_CLOCK BIT(20)
94 /* Clock reset register */
95 #define LCD_CLK_MAIN_RESET BIT(3)
98 struct da8xx_lcd_regs {
102 u32 lidd_ctrl; /* 0x0c */
103 u32 lidd_cs0_conf; /* 0x10 */
104 u32 lidd_cs0_addr; /* 0x14 */
105 u32 lidd_cs0_data; /* 0x18 */
106 u32 lidd_cs1_conf; /* 0x1c */
107 u32 lidd_cs1_addr; /* 0x20 */
108 u32 lidd_cs1_data; /* 0x24 */
109 u32 raster_ctrl; /* 0x28 */
110 u32 raster_timing_0; /* 0x2c */
111 u32 raster_timing_1; /* 0x30 */
112 u32 raster_timing_2; /* 0x34 */
113 u32 raster_subpanel; /* 0x38 */
114 u32 reserved; /* 0x3c */
115 u32 dma_ctrl; /* 0x40 */
116 u32 dma_frm_buf_base_addr_0; /* 0x44 */
117 u32 dma_frm_buf_ceiling_addr_0; /* 0x48 */
118 u32 dma_frm_buf_base_addr_1; /* 0x4c */
119 u32 dma_frm_buf_ceiling_addr_1; /* 0x50 */
120 u32 rsrvd1; /* 0x54 */
121 u32 raw_stat; /* 0x58 */
122 u32 masked_stat; /* 0x5c */
123 u32 int_enable_set; /* 0x60 */
124 u32 int_enable_clr; /* 0x64 */
125 u32 end_of_int_ind; /* 0x68 */
126 u32 clk_enable; /* 0x6c */
127 u32 clk_reset; /* 0x70 */
130 #define LCD_NUM_BUFFERS 1
132 #define WSI_TIMEOUT 50
133 #define PALETTE_SIZE 256
134 #define LEFT_MARGIN 64
135 #define RIGHT_MARGIN 64
136 #define UPPER_MARGIN 32
137 #define LOWER_MARGIN 32
139 DECLARE_GLOBAL_DATA_PTR;
141 static struct da8xx_lcd_regs *da8xx_fb_reg_base;
142 static unsigned int lcd_revision;
145 static GraphicDevice gpanel;
146 static const struct da8xx_panel *lcd_panel;
147 static struct fb_info *da8xx_fb_info;
148 static int bits_x_pixel;
149 static u32 (*lcdc_irq_handler)(void);
151 static inline unsigned int lcdc_read(u32 *addr)
156 static inline void lcdc_write(unsigned int val, u32 *addr)
161 struct da8xx_fb_par {
162 unsigned long p_palette_base;
163 void *v_palette_base;
164 dma_addr_t vram_phys;
165 unsigned long vram_size;
167 unsigned int dma_start;
168 unsigned int dma_end;
169 struct clk *lcdc_clk;
171 unsigned short pseudo_palette[16];
172 unsigned int palette_sz;
173 unsigned int pxl_clk;
179 /* Variable Screen Information */
180 static struct fb_var_screeninfo da8xx_fb_var = {
188 .pixclock = 46666, /* 46us - AUO display */
190 .left_margin = LEFT_MARGIN,
191 .right_margin = RIGHT_MARGIN,
192 .upper_margin = UPPER_MARGIN,
193 .lower_margin = LOWER_MARGIN,
195 .vmode = FB_VMODE_NONINTERLACED
198 static struct fb_fix_screeninfo da8xx_fb_fix = {
199 .id = "DA8xx FB Drv",
200 .type = FB_TYPE_PACKED_PIXELS,
202 .visual = FB_VISUAL_PSEUDOCOLOR,
206 .accel = FB_ACCEL_NONE
209 static const struct display_panel disp_panel = {
213 .panel_shade = COLOR_ACTIVE,
216 static const struct lcd_ctrl_config lcd_cfg = {
226 .invert_line_clock = 1,
227 .invert_frm_clock = 1,
233 /* Enable the Raster Engine of the LCD Controller */
234 static inline void lcd_enable_raster(void)
238 /* Bring LCDC out of reset */
239 if (lcd_revision == LCD_VERSION_2)
240 lcdc_write(0, &da8xx_fb_reg_base->clk_reset);
242 reg = lcdc_read(&da8xx_fb_reg_base->raster_ctrl);
243 if (!(reg & LCD_RASTER_ENABLE))
244 lcdc_write(reg | LCD_RASTER_ENABLE,
245 &da8xx_fb_reg_base->raster_ctrl);
248 /* Disable the Raster Engine of the LCD Controller */
249 static inline void lcd_disable_raster(void)
253 reg = lcdc_read(&da8xx_fb_reg_base->raster_ctrl);
254 if (reg & LCD_RASTER_ENABLE)
255 lcdc_write(reg & ~LCD_RASTER_ENABLE,
256 &da8xx_fb_reg_base->raster_ctrl);
257 if (lcd_revision == LCD_VERSION_2)
258 /* Write 1 to reset LCDC */
259 lcdc_write(LCD_CLK_MAIN_RESET, &da8xx_fb_reg_base->clk_reset);
262 static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
270 /* init reg to clear PLM (loading mode) fields */
271 reg_ras = lcdc_read(&da8xx_fb_reg_base->raster_ctrl);
272 reg_ras &= ~(3 << 20);
274 reg_dma = lcdc_read(&da8xx_fb_reg_base->dma_ctrl);
276 if (load_mode == LOAD_DATA) {
277 start = par->dma_start;
280 reg_ras |= LCD_PALETTE_LOAD_MODE(DATA_ONLY);
281 if (lcd_revision == LCD_VERSION_1) {
282 reg_dma |= LCD_V1_END_OF_FRAME_INT_ENA;
284 reg_int = lcdc_read(&da8xx_fb_reg_base->int_enable_set) |
285 LCD_V2_END_OF_FRAME0_INT_ENA |
286 LCD_V2_END_OF_FRAME1_INT_ENA;
288 &da8xx_fb_reg_base->int_enable_set);
290 #if (LCD_NUM_BUFFERS == 2)
291 reg_dma |= LCD_DUAL_FRAME_BUFFER_ENABLE;
292 lcdc_write(start, &da8xx_fb_reg_base->dma_frm_buf_base_addr_0);
293 lcdc_write(end, &da8xx_fb_reg_base->dma_frm_buf_ceiling_addr_0);
294 lcdc_write(start, &da8xx_fb_reg_base->dma_frm_buf_base_addr_1);
295 lcdc_write(end, &da8xx_fb_reg_base->dma_frm_buf_ceiling_addr_1);
297 reg_dma &= ~LCD_DUAL_FRAME_BUFFER_ENABLE;
298 lcdc_write(start, &da8xx_fb_reg_base->dma_frm_buf_base_addr_0);
299 lcdc_write(end, &da8xx_fb_reg_base->dma_frm_buf_ceiling_addr_0);
300 lcdc_write(0, &da8xx_fb_reg_base->dma_frm_buf_base_addr_1);
301 lcdc_write(0, &da8xx_fb_reg_base->dma_frm_buf_ceiling_addr_1);
303 } else if (load_mode == LOAD_PALETTE) {
304 start = par->p_palette_base;
305 end = start + par->palette_sz - 1;
307 reg_ras |= LCD_PALETTE_LOAD_MODE(PALETTE_ONLY);
309 if (lcd_revision == LCD_VERSION_1) {
310 reg_ras |= LCD_V1_PL_INT_ENA;
312 reg_int = lcdc_read(&da8xx_fb_reg_base->int_enable_set) |
314 lcdc_write(reg_int, &da8xx_fb_reg_base->int_enable_set);
316 lcdc_write(start, &da8xx_fb_reg_base->dma_frm_buf_base_addr_0);
317 lcdc_write(end, &da8xx_fb_reg_base->dma_frm_buf_ceiling_addr_0);
320 lcdc_write(reg_dma, &da8xx_fb_reg_base->dma_ctrl);
321 lcdc_write(reg_ras, &da8xx_fb_reg_base->raster_ctrl);
324 * The Raster enable bit must be set after all other control fields are
330 /* Configure the Burst Size of DMA */
331 static int lcd_cfg_dma(int burst_size)
335 reg = lcdc_read(&da8xx_fb_reg_base->dma_ctrl);
336 reg &= ~LCD_DMA_BURST_SIZE_MASK;
337 switch (burst_size) {
339 reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_1);
342 reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_2);
345 reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_4);
348 reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_8);
351 reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_16);
356 lcdc_write(reg, &da8xx_fb_reg_base->dma_ctrl);
361 static void lcd_cfg_ac_bias(int period, int transitions_per_int)
365 /* Set the AC Bias Period and Number of Transisitons per Interrupt */
366 reg = lcdc_read(&da8xx_fb_reg_base->raster_timing_2) & 0xFFF00000;
367 reg |= LCD_AC_BIAS_FREQUENCY(period) |
368 LCD_AC_BIAS_TRANSITIONS_PER_INT(transitions_per_int);
369 lcdc_write(reg, &da8xx_fb_reg_base->raster_timing_2);
372 static void lcd_cfg_horizontal_sync(int back_porch, int pulse_width,
377 reg = lcdc_read(&da8xx_fb_reg_base->raster_timing_0) & 0xf;
378 reg |= ((back_porch & 0xff) << 24)
379 | ((front_porch & 0xff) << 16)
380 | ((pulse_width & 0x3f) << 10);
381 lcdc_write(reg, &da8xx_fb_reg_base->raster_timing_0);
384 static void lcd_cfg_vertical_sync(int back_porch, int pulse_width,
389 reg = lcdc_read(&da8xx_fb_reg_base->raster_timing_1) & 0x3ff;
390 reg |= ((back_porch & 0xff) << 24)
391 | ((front_porch & 0xff) << 16)
392 | ((pulse_width & 0x3f) << 10);
393 lcdc_write(reg, &da8xx_fb_reg_base->raster_timing_1);
396 static int lcd_cfg_display(const struct lcd_ctrl_config *cfg)
401 reg = lcdc_read(&da8xx_fb_reg_base->raster_ctrl) & ~(LCD_TFT_MODE |
403 LCD_MONOCHROME_MODE |
407 switch (cfg->p_disp_panel->panel_shade) {
409 reg |= LCD_MONOCHROME_MODE;
410 if (cfg->mono_8bit_mode)
411 reg |= LCD_MONO_8BIT_MODE;
415 if (cfg->tft_alt_mode)
416 reg |= LCD_TFT_ALT_ENABLE;
420 if (cfg->stn_565_mode)
421 reg |= LCD_STN_565_ENABLE;
428 /* enable additional interrupts here */
429 if (lcd_revision == LCD_VERSION_1) {
430 reg |= LCD_V1_UNDERFLOW_INT_ENA;
432 if (bits_x_pixel >= 24)
435 reg |= LCD_TFT24_UNPACKED;
436 reg_int = lcdc_read(&da8xx_fb_reg_base->int_enable_set) |
437 LCD_V2_UNDERFLOW_INT_ENA;
438 lcdc_write(reg_int, &da8xx_fb_reg_base->int_enable_set);
441 lcdc_write(reg, &da8xx_fb_reg_base->raster_ctrl);
443 reg = lcdc_read(&da8xx_fb_reg_base->raster_timing_2);
446 reg |= LCD_SYNC_CTRL;
448 reg &= ~LCD_SYNC_CTRL;
451 reg |= LCD_SYNC_EDGE;
453 reg &= ~LCD_SYNC_EDGE;
455 if (cfg->invert_line_clock)
456 reg |= LCD_INVERT_LINE_CLOCK;
458 reg &= ~LCD_INVERT_LINE_CLOCK;
460 if (cfg->invert_frm_clock)
461 reg |= LCD_INVERT_FRAME_CLOCK;
463 reg &= ~LCD_INVERT_FRAME_CLOCK;
465 lcdc_write(reg, &da8xx_fb_reg_base->raster_timing_2);
470 static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
471 u32 bpp, u32 raster_order)
475 /* Set the Panel Width */
476 /* Pixels per line = (PPL + 1)*16 */
477 /* Pixels per line = (PPL + 1)*16 */
478 if (lcd_revision == LCD_VERSION_1) {
480 * 0x3F in bits 4..9 gives max horizontal resolution = 1024
486 * 0x7F in bits 4..10 gives max horizontal resolution = 2048
492 reg = lcdc_read(&da8xx_fb_reg_base->raster_timing_0);
494 if (lcd_revision == LCD_VERSION_1) {
495 reg |= ((width >> 4) - 1) << 4;
497 width = (width >> 4) - 1;
498 reg |= ((width & 0x3f) << 4) | ((width & 0x40) >> 3);
500 lcdc_write(reg, &da8xx_fb_reg_base->raster_timing_0);
502 /* Set the Panel Height */
503 /* Set bits 9:0 of Lines Per Pixel */
504 reg = lcdc_read(&da8xx_fb_reg_base->raster_timing_1);
505 reg = ((height - 1) & 0x3ff) | (reg & 0xfffffc00);
506 lcdc_write(reg, &da8xx_fb_reg_base->raster_timing_1);
508 /* Set bit 10 of Lines Per Pixel */
509 if (lcd_revision == LCD_VERSION_2) {
510 reg = lcdc_read(&da8xx_fb_reg_base->raster_timing_2);
511 reg |= ((height - 1) & 0x400) << 16;
512 lcdc_write(reg, &da8xx_fb_reg_base->raster_timing_2);
515 /* Set the Raster Order of the Frame Buffer */
516 reg = lcdc_read(&da8xx_fb_reg_base->raster_ctrl) & ~(1 << 8);
518 reg |= LCD_RASTER_ORDER;
519 lcdc_write(reg, &da8xx_fb_reg_base->raster_ctrl);
527 par->palette_sz = 16 * 2;
531 par->palette_sz = 256 * 2;
541 static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
542 unsigned blue, unsigned transp,
543 struct fb_info *info)
545 struct da8xx_fb_par *par = info->par;
546 unsigned short *palette = par->v_palette_base;
553 if (info->fix.visual == FB_VISUAL_DIRECTCOLOR)
556 if (info->var.bits_per_pixel == 8) {
561 pal = (red & 0x0f00);
562 pal |= (green & 0x00f0);
563 pal |= (blue & 0x000f);
565 if (palette[regno] != pal) {
567 palette[regno] = pal;
569 } else if ((info->var.bits_per_pixel >= 16) && regno < 16) {
570 red >>= (16 - info->var.red.length);
571 red <<= info->var.red.offset;
573 green >>= (16 - info->var.green.length);
574 green <<= info->var.green.offset;
576 blue >>= (16 - info->var.blue.length);
577 blue <<= info->var.blue.offset;
579 par->pseudo_palette[regno] = red | green | blue;
581 if (palette[0] != 0x4000) {
587 /* Update the palette in the h/w as needed. */
589 lcd_blit(LOAD_PALETTE, par);
594 static void lcd_reset(struct da8xx_fb_par *par)
596 /* Disable the Raster if previously Enabled */
597 lcd_disable_raster();
599 /* DMA has to be disabled */
600 lcdc_write(0, &da8xx_fb_reg_base->dma_ctrl);
601 lcdc_write(0, &da8xx_fb_reg_base->raster_ctrl);
603 if (lcd_revision == LCD_VERSION_2) {
604 lcdc_write(0, &da8xx_fb_reg_base->int_enable_set);
605 /* Write 1 to reset */
606 lcdc_write(LCD_CLK_MAIN_RESET, &da8xx_fb_reg_base->clk_reset);
607 lcdc_write(0, &da8xx_fb_reg_base->clk_reset);
611 static void lcd_calc_clk_divider(struct da8xx_fb_par *par)
613 unsigned int lcd_clk, div;
615 #ifndef CONFIG_AM33XX
616 /* Get clock from sysclk2 */
617 lcd_clk = clk_get(2);
619 lcd_clk = lcdc_clk_rate();
621 /* calculate divisor so that the resulting clock is rounded down */
622 div = (lcd_clk + par->pxl_clk - 1)/ par->pxl_clk;
628 debug("LCD Clock: %u.%03uMHz Divider: 0x%08x PixClk requested: %u.%03uMHz actual: %u.%03uMHz\n",
629 lcd_clk / 1000000, lcd_clk / 1000 % 1000, div,
630 par->pxl_clk / 1000000, par->pxl_clk / 1000 % 1000,
631 lcd_clk / div / 1000000, lcd_clk / div / 1000 % 1000);
633 /* Configure the LCD clock divisor. */
634 lcdc_write(LCD_CLK_DIVISOR(div) | LCD_RASTER_MODE,
635 &da8xx_fb_reg_base->ctrl);
637 if (lcd_revision == LCD_VERSION_2)
638 lcdc_write(LCD_V2_DMA_CLK_EN | LCD_V2_LIDD_CLK_EN |
639 LCD_V2_CORE_CLK_EN, &da8xx_fb_reg_base->clk_enable);
643 static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
644 const struct da8xx_panel *panel)
651 /* Calculate the divider */
652 lcd_calc_clk_divider(par);
654 if (panel->invert_pxl_clk)
655 lcdc_write((lcdc_read(&da8xx_fb_reg_base->raster_timing_2) |
656 LCD_INVERT_PIXEL_CLOCK),
657 &da8xx_fb_reg_base->raster_timing_2);
659 lcdc_write((lcdc_read(&da8xx_fb_reg_base->raster_timing_2) &
660 ~LCD_INVERT_PIXEL_CLOCK),
661 &da8xx_fb_reg_base->raster_timing_2);
663 /* Configure the DMA burst size. */
664 ret = lcd_cfg_dma(cfg->dma_burst_sz);
668 /* Configure the AC bias properties. */
669 lcd_cfg_ac_bias(cfg->ac_bias, cfg->ac_bias_intrpt);
671 /* Configure the vertical and horizontal sync properties. */
672 lcd_cfg_vertical_sync(panel->vbp, panel->vsw, panel->vfp);
673 lcd_cfg_horizontal_sync(panel->hbp, panel->hsw, panel->hfp);
675 /* Configure for display */
676 ret = lcd_cfg_display(cfg);
680 if (QVGA != cfg->p_disp_panel->panel_type)
683 if (cfg->bpp <= cfg->p_disp_panel->max_bpp &&
684 cfg->bpp >= cfg->p_disp_panel->min_bpp)
687 bpp = cfg->p_disp_panel->max_bpp;
690 ret = lcd_cfg_frame_buffer(par, (unsigned int)panel->width,
691 (unsigned int)panel->height, bpp,
697 lcdc_write((lcdc_read(&da8xx_fb_reg_base->raster_ctrl) & 0xfff00fff) |
698 (cfg->fdd << 12), &da8xx_fb_reg_base->raster_ctrl);
703 static void lcdc_dma_start(void)
705 struct da8xx_fb_par *par = da8xx_fb_info->par;
706 lcdc_write(par->dma_start,
707 &da8xx_fb_reg_base->dma_frm_buf_base_addr_0);
708 lcdc_write(par->dma_end,
709 &da8xx_fb_reg_base->dma_frm_buf_ceiling_addr_0);
711 &da8xx_fb_reg_base->dma_frm_buf_base_addr_1);
713 &da8xx_fb_reg_base->dma_frm_buf_ceiling_addr_1);
716 /* IRQ handler for version 2 of LCDC */
717 static u32 lcdc_irq_handler_rev02(void)
720 struct da8xx_fb_par *par = da8xx_fb_info->par;
721 u32 stat = lcdc_read(&da8xx_fb_reg_base->masked_stat);
723 debug("%s: stat=%08x\n", __func__, stat);
725 if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {
726 debug("LCD_SYNC_LOST\n");
727 lcd_disable_raster();
728 lcdc_write(stat, &da8xx_fb_reg_base->masked_stat);
731 } else if (stat & LCD_PL_LOAD_DONE) {
732 debug("LCD_PL_LOAD_DONE\n");
734 * Must disable raster before changing state of any control bit.
735 * And also must be disabled before clearing the PL loading
736 * interrupt via the following write to the status register. If
737 * this is done after then one gets multiple PL done interrupts.
739 lcd_disable_raster();
741 lcdc_write(stat, &da8xx_fb_reg_base->masked_stat);
743 /* Disable PL completion inerrupt */
744 lcdc_write(LCD_V2_PL_INT_ENA,
745 &da8xx_fb_reg_base->int_enable_clr);
747 /* Setup and start data loading mode */
748 lcd_blit(LOAD_DATA, par);
749 ret = LCD_PL_LOAD_DONE;
750 } else if (stat & (LCD_END_OF_FRAME0 | LCD_END_OF_FRAME1)) {
752 lcdc_write(stat, &da8xx_fb_reg_base->masked_stat);
754 if (stat & LCD_END_OF_FRAME0) {
755 debug("LCD_END_OF_FRAME0\n");
757 lcdc_write(par->dma_start,
758 &da8xx_fb_reg_base->dma_frm_buf_base_addr_0);
759 lcdc_write(par->dma_end,
760 &da8xx_fb_reg_base->dma_frm_buf_ceiling_addr_0);
762 if (stat & LCD_END_OF_FRAME1) {
763 debug("LCD_END_OF_FRAME1\n");
764 lcdc_write(par->dma_start,
765 &da8xx_fb_reg_base->dma_frm_buf_base_addr_1);
766 lcdc_write(par->dma_end,
767 &da8xx_fb_reg_base->dma_frm_buf_ceiling_addr_1);
770 ret = (stat & LCD_END_OF_FRAME0) ?
771 LCD_END_OF_FRAME0 : LCD_END_OF_FRAME1;
773 lcdc_write(0, &da8xx_fb_reg_base->end_of_int_ind);
777 static u32 lcdc_irq_handler_rev01(void)
779 struct da8xx_fb_par *par = da8xx_fb_info->par;
780 u32 stat = lcdc_read(&da8xx_fb_reg_base->stat);
783 if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {
784 debug("LCD_SYNC_LOST\n");
785 lcd_disable_raster();
786 lcdc_write(stat, &da8xx_fb_reg_base->stat);
788 return LCD_SYNC_LOST;
789 } else if (stat & LCD_PL_LOAD_DONE) {
790 debug("LCD_PL_LOAD_DONE\n");
792 * Must disable raster before changing state of any control bit.
793 * And also must be disabled before clearing the PL loading
794 * interrupt via the following write to the status register. If
795 * this is done after then one gets multiple PL done interrupts.
797 lcd_disable_raster();
799 lcdc_write(stat, &da8xx_fb_reg_base->stat);
801 /* Disable PL completion inerrupt */
802 reg_ras = lcdc_read(&da8xx_fb_reg_base->raster_ctrl);
803 reg_ras &= ~LCD_V1_PL_INT_ENA;
804 lcdc_write(reg_ras, &da8xx_fb_reg_base->raster_ctrl);
806 /* Setup and start data loading mode */
807 lcd_blit(LOAD_DATA, par);
808 return LCD_PL_LOAD_DONE;
809 } else if (stat & (LCD_END_OF_FRAME0 | LCD_END_OF_FRAME1)) {
811 lcdc_write(stat, &da8xx_fb_reg_base->stat);
813 if (stat & LCD_END_OF_FRAME0) {
814 debug("LCD_END_OF_FRAME0\n");
816 lcdc_write(par->dma_start,
817 &da8xx_fb_reg_base->dma_frm_buf_base_addr_0);
818 lcdc_write(par->dma_end,
819 &da8xx_fb_reg_base->dma_frm_buf_ceiling_addr_0);
822 if (stat & LCD_END_OF_FRAME1) {
823 debug("LCD_END_OF_FRAME1\n");
824 lcdc_write(par->dma_start,
825 &da8xx_fb_reg_base->dma_frm_buf_base_addr_1);
826 lcdc_write(par->dma_end,
827 &da8xx_fb_reg_base->dma_frm_buf_ceiling_addr_1);
830 return (stat & LCD_END_OF_FRAME0) ?
831 LCD_END_OF_FRAME0 : LCD_END_OF_FRAME1;
836 static u32 wait_for_event(u32 event)
842 ret = lcdc_irq_handler();
846 } while (--timeout > 0);
849 printf("%s: event %d not hit\n", __func__, event);
857 void *video_hw_init(void)
859 struct da8xx_fb_par *par;
864 printf("Display not initialized\n");
868 gpanel.winSizeX = lcd_panel->width;
869 gpanel.winSizeY = lcd_panel->height;
870 gpanel.plnSizeX = lcd_panel->width;
871 gpanel.plnSizeY = lcd_panel->height;
873 switch (bits_x_pixel) {
875 gpanel.gdfBytesPP = 4;
876 gpanel.gdfIndex = GDF_32BIT_X888RGB;
879 gpanel.gdfBytesPP = 2;
880 gpanel.gdfIndex = GDF_16BIT_565RGB;
883 gpanel.gdfBytesPP = 1;
884 gpanel.gdfIndex = GDF__8BIT_INDEX;
887 da8xx_fb_reg_base = (struct da8xx_lcd_regs *)DAVINCI_LCD_CNTL_BASE;
889 /* Determine LCD IP Version */
891 lcd_revision = lcdc_read(&da8xx_fb_reg_base->revid);
892 switch (lcd_revision & 0xfff00000) {
894 lcd_revision = LCD_VERSION_1;
898 lcd_revision = LCD_VERSION_2;
902 printf("Unknown PID Reg value 0x%08x, defaulting to LCD revision 1\n",
904 lcd_revision = LCD_VERSION_1;
907 debug("Resolution: %dx%d %d\n",
912 size = sizeof(struct fb_info) + sizeof(struct da8xx_fb_par);
913 da8xx_fb_info = malloc(size);
914 debug("da8xx_fb_info at %p\n", da8xx_fb_info);
916 if (!da8xx_fb_info) {
917 printf("Memory allocation failed for fb_info\n");
920 memset(da8xx_fb_info, 0, size);
921 p = (char *)da8xx_fb_info;
922 da8xx_fb_info->par = p + sizeof(struct fb_info);
923 debug("da8xx_par at %x\n", (unsigned int)da8xx_fb_info->par);
925 par = da8xx_fb_info->par;
926 par->pxl_clk = lcd_panel->pxl_clk;
928 if (lcd_init(par, &lcd_cfg, lcd_panel) < 0) {
929 printf("lcd_init failed\n");
933 /* allocate frame buffer */
934 par->vram_size = lcd_panel->width * lcd_panel->height * lcd_cfg.bpp;
935 par->vram_size = par->vram_size * LCD_NUM_BUFFERS / 8;
938 par->vram_virt = (void *)gd->fb_base;
940 par->vram_virt = malloc(par->vram_size);
942 par->vram_phys = (dma_addr_t) par->vram_virt;
943 debug("Requesting 0x%lx bytes for framebuffer at 0x%p\n",
944 par->vram_size, par->vram_virt);
945 if (!par->vram_virt) {
946 printf("GLCD: malloc for frame buffer failed\n");
950 gpanel.frameAdrs = (unsigned int)par->vram_virt;
951 da8xx_fb_info->screen_base = par->vram_virt;
952 da8xx_fb_fix.smem_start = gpanel.frameAdrs;
953 da8xx_fb_fix.smem_len = par->vram_size;
954 da8xx_fb_fix.line_length = (lcd_panel->width * lcd_cfg.bpp) / 8;
955 debug("%s: vram_virt: %p size %ux%u=%lu bpp %u\n", __func__,
956 par->vram_virt, lcd_panel->width, lcd_panel->height,
957 par->vram_size, lcd_cfg.bpp);
958 par->dma_start = par->vram_phys;
959 par->dma_end = par->dma_start + lcd_panel->height *
960 da8xx_fb_fix.line_length - 1;
962 /* allocate palette buffer */
963 par->v_palette_base = malloc(PALETTE_SIZE);
964 if (!par->v_palette_base) {
965 printf("GLCD: malloc for palette buffer failed\n");
966 goto err_release_fb_mem;
968 memset(par->v_palette_base, 0, PALETTE_SIZE);
969 par->p_palette_base = (unsigned long)par->v_palette_base;
972 da8xx_fb_var.xres = lcd_panel->width;
973 da8xx_fb_var.xres_virtual = lcd_panel->width;
975 da8xx_fb_var.yres = lcd_panel->height;
976 da8xx_fb_var.yres_virtual = lcd_panel->height * LCD_NUM_BUFFERS;
978 da8xx_fb_var.grayscale =
979 lcd_cfg.p_disp_panel->panel_shade == MONOCHROME ? 1 : 0;
980 da8xx_fb_var.bits_per_pixel = lcd_cfg.bpp;
982 da8xx_fb_var.hsync_len = lcd_panel->hsw;
983 da8xx_fb_var.vsync_len = lcd_panel->vsw;
985 /* Initialize fbinfo */
986 da8xx_fb_info->flags = FBINFO_FLAG_DEFAULT;
987 da8xx_fb_info->fix = da8xx_fb_fix;
988 da8xx_fb_info->var = da8xx_fb_var;
989 da8xx_fb_info->pseudo_palette = par->pseudo_palette;
990 da8xx_fb_info->fix.visual = (da8xx_fb_info->var.bits_per_pixel <= 8) ?
991 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
993 if (lcd_revision == LCD_VERSION_1)
994 lcdc_irq_handler = lcdc_irq_handler_rev01;
996 lcdc_irq_handler = lcdc_irq_handler_rev02;
998 /* Clear interrupt */
999 memset(par->vram_virt, 0, par->vram_size);
1000 lcd_disable_raster();
1001 lcdc_write(0xFFFF, &da8xx_fb_reg_base->stat);
1002 debug("Palette at 0x%08lx size %u\n", par->p_palette_base,
1006 /* Load a default palette */
1007 fb_setcolreg(0, 0, 0, 0, 0xffff, da8xx_fb_info);
1009 /* Check that the palette is loaded */
1010 wait_for_event(LCD_PL_LOAD_DONE);
1012 /* Wait until DMA is working */
1013 wait_for_event(LCD_END_OF_FRAME0);
1019 free(par->vram_virt);
1023 free(da8xx_fb_info);
1028 void da8xx_fb_disable(void)
1030 lcd_reset(da8xx_fb_info->par);
1033 void video_set_lut(unsigned int index, /* color number */
1034 unsigned char r, /* red */
1035 unsigned char g, /* green */
1036 unsigned char b /* blue */
1041 void da8xx_video_init(const struct da8xx_panel *panel, int bits_pixel)
1044 bits_x_pixel = bits_pixel;