uboot/drivers/video/da8xx-fb.c
<<
>>
Prefs
   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 <linux/errno.h>
  23#include <asm/io.h>
  24#include <asm/arch/hardware.h>
  25
  26#include "videomodes.h"
  27#include "da8xx-fb.h"
  28
  29#if !defined(DA8XX_LCD_CNTL_BASE)
  30#define DA8XX_LCD_CNTL_BASE     DAVINCI_LCD_CNTL_BASE
  31#endif
  32
  33#define DRIVER_NAME "da8xx_lcdc"
  34
  35#define LCD_VERSION_1   1
  36#define LCD_VERSION_2   2
  37
  38/* LCD Status Register */
  39#define LCD_END_OF_FRAME1               (1 << 9)
  40#define LCD_END_OF_FRAME0               (1 << 8)
  41#define LCD_PL_LOAD_DONE                (1 << 6)
  42#define LCD_FIFO_UNDERFLOW              (1 << 5)
  43#define LCD_SYNC_LOST                   (1 << 2)
  44
  45/* LCD DMA Control Register */
  46#define LCD_DMA_BURST_SIZE(x)           ((x) << 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     (1 << 2)
  53#define LCD_V2_END_OF_FRAME0_INT_ENA    (1 << 8)
  54#define LCD_V2_END_OF_FRAME1_INT_ENA    (1 << 9)
  55#define LCD_DUAL_FRAME_BUFFER_ENABLE    (1 << 0)
  56
  57#define LCD_V2_TFT_24BPP_MODE           (1 << 25)
  58#define LCD_V2_TFT_24BPP_UNPACK         (1 << 26)
  59
  60/* LCD Control Register */
  61#define LCD_CLK_DIVISOR(x)              ((x) << 8)
  62#define LCD_RASTER_MODE                 0x01
  63
  64/* LCD Raster Control Register */
  65#define LCD_PALETTE_LOAD_MODE(x)        ((x) << 20)
  66#define PALETTE_AND_DATA                0x00
  67#define PALETTE_ONLY                    0x01
  68#define DATA_ONLY                       0x02
  69
  70#define LCD_MONO_8BIT_MODE              (1 << 9)
  71#define LCD_RASTER_ORDER                (1 << 8)
  72#define LCD_TFT_MODE                    (1 << 7)
  73#define LCD_V1_UNDERFLOW_INT_ENA        (1 << 6)
  74#define LCD_V2_UNDERFLOW_INT_ENA        (1 << 5)
  75#define LCD_V1_PL_INT_ENA               (1 << 4)
  76#define LCD_V2_PL_INT_ENA               (1 << 6)
  77#define LCD_MONOCHROME_MODE             (1 << 1)
  78#define LCD_RASTER_ENABLE               (1 << 0)
  79#define LCD_TFT_ALT_ENABLE              (1 << 23)
  80#define LCD_STN_565_ENABLE              (1 << 24)
  81#define LCD_V2_DMA_CLK_EN               (1 << 2)
  82#define LCD_V2_LIDD_CLK_EN              (1 << 1)
  83#define LCD_V2_CORE_CLK_EN              (1 << 0)
  84#define LCD_V2_LPP_B10                  26
  85#define LCD_V2_TFT_24BPP_MODE           (1 << 25)
  86#define LCD_V2_TFT_24BPP_UNPACK         (1 << 26)
  87
  88/* LCD Raster Timing 2 Register */
  89#define LCD_AC_BIAS_TRANSITIONS_PER_INT(x)      ((x) << 16)
  90#define LCD_AC_BIAS_FREQUENCY(x)                ((x) << 8)
  91#define LCD_SYNC_CTRL                           (1 << 25)
  92#define LCD_SYNC_EDGE                           (1 << 24)
  93#define LCD_INVERT_PIXEL_CLOCK                  (1 << 22)
  94#define LCD_INVERT_LINE_CLOCK                   (1 << 21)
  95#define LCD_INVERT_FRAME_CLOCK                  (1 << 20)
  96
  97/* Clock registers available only on Version 2 */
  98#define  LCD_CLK_MAIN_RESET                     (1 << 3)
  99/* LCD Block */
 100struct da8xx_lcd_regs {
 101        u32     revid;
 102        u32     ctrl;
 103        u32     stat;
 104        u32     lidd_ctrl;
 105        u32     lidd_cs0_conf;
 106        u32     lidd_cs0_addr;
 107        u32     lidd_cs0_data;
 108        u32     lidd_cs1_conf;
 109        u32     lidd_cs1_addr;
 110        u32     lidd_cs1_data;
 111        u32     raster_ctrl;
 112        u32     raster_timing_0;
 113        u32     raster_timing_1;
 114        u32     raster_timing_2;
 115        u32     raster_subpanel;
 116        u32     reserved;
 117        u32     dma_ctrl;
 118        u32     dma_frm_buf_base_addr_0;
 119        u32     dma_frm_buf_ceiling_addr_0;
 120        u32     dma_frm_buf_base_addr_1;
 121        u32     dma_frm_buf_ceiling_addr_1;
 122        u32     resv1;
 123        u32     raw_stat;
 124        u32     masked_stat;
 125        u32     int_ena_set;
 126        u32     int_ena_clr;
 127        u32     end_of_int_ind;
 128        /* Clock registers available only on Version 2 */
 129        u32     clk_ena;
 130        u32     clk_reset;
 131};
 132
 133#define LCD_NUM_BUFFERS 1
 134
 135#define WSI_TIMEOUT     50
 136#define PALETTE_SIZE    256
 137#define LEFT_MARGIN     64
 138#define RIGHT_MARGIN    64
 139#define UPPER_MARGIN    32
 140#define LOWER_MARGIN    32
 141#define WAIT_FOR_FRAME_DONE     true
 142#define NO_WAIT_FOR_FRAME_DONE  false
 143
 144#define calc_fbsize() (panel.plnSizeX * panel.plnSizeY * panel.gdfBytesPP)
 145
 146static struct da8xx_lcd_regs *da8xx_fb_reg_base;
 147
 148DECLARE_GLOBAL_DATA_PTR;
 149
 150/* graphics setup */
 151static GraphicDevice gpanel;
 152static const struct da8xx_panel *lcd_panel;
 153static struct fb_info *da8xx_fb_info;
 154static int bits_x_pixel;
 155static unsigned int lcd_revision;
 156const struct lcd_ctrl_config *da8xx_lcd_cfg;
 157
 158static inline unsigned int lcdc_read(u32 *addr)
 159{
 160        return (unsigned int)readl(addr);
 161}
 162
 163static inline void lcdc_write(unsigned int val, u32 *addr)
 164{
 165        writel(val, addr);
 166}
 167
 168struct da8xx_fb_par {
 169        u32                      p_palette_base;
 170        unsigned char *v_palette_base;
 171        dma_addr_t              vram_phys;
 172        unsigned long           vram_size;
 173        void                    *vram_virt;
 174        unsigned int            dma_start;
 175        unsigned int            dma_end;
 176        struct clk *lcdc_clk;
 177        int irq;
 178        unsigned short pseudo_palette[16];
 179        unsigned int palette_sz;
 180        unsigned int pxl_clk;
 181        int blank;
 182        int                     vsync_flag;
 183        int                     vsync_timeout;
 184};
 185
 186
 187/* Variable Screen Information */
 188static struct fb_var_screeninfo da8xx_fb_var = {
 189        .xoffset = 0,
 190        .yoffset = 0,
 191        .transp = {0, 0, 0},
 192        .nonstd = 0,
 193        .activate = 0,
 194        .height = -1,
 195        .width = -1,
 196        .pixclock = 46666,      /* 46us - AUO display */
 197        .accel_flags = 0,
 198        .left_margin = LEFT_MARGIN,
 199        .right_margin = RIGHT_MARGIN,
 200        .upper_margin = UPPER_MARGIN,
 201        .lower_margin = LOWER_MARGIN,
 202        .sync = 0,
 203        .vmode = FB_VMODE_NONINTERLACED
 204};
 205
 206static struct fb_fix_screeninfo da8xx_fb_fix = {
 207        .id = "DA8xx FB Drv",
 208        .type = FB_TYPE_PACKED_PIXELS,
 209        .type_aux = 0,
 210        .visual = FB_VISUAL_PSEUDOCOLOR,
 211        .xpanstep = 0,
 212        .ypanstep = 1,
 213        .ywrapstep = 0,
 214        .accel = FB_ACCEL_NONE
 215};
 216
 217/* Enable the Raster Engine of the LCD Controller */
 218static inline void lcd_enable_raster(void)
 219{
 220        u32 reg;
 221
 222        /* Put LCDC in reset for several cycles */
 223        if (lcd_revision == LCD_VERSION_2)
 224                lcdc_write(LCD_CLK_MAIN_RESET,
 225                           &da8xx_fb_reg_base->clk_reset);
 226
 227        udelay(1000);
 228        /* Bring LCDC out of reset */
 229        if (lcd_revision == LCD_VERSION_2)
 230                lcdc_write(0,
 231                           &da8xx_fb_reg_base->clk_reset);
 232
 233        udelay(1000);
 234
 235        reg = lcdc_read(&da8xx_fb_reg_base->raster_ctrl);
 236        if (!(reg & LCD_RASTER_ENABLE))
 237                lcdc_write(reg | LCD_RASTER_ENABLE,
 238                        &da8xx_fb_reg_base->raster_ctrl);
 239}
 240
 241/* Disable the Raster Engine of the LCD Controller */
 242static inline void lcd_disable_raster(bool wait_for_frame_done)
 243{
 244        u32 reg;
 245        u32 loop_cnt = 0;
 246        u32 stat;
 247        u32 i = 0;
 248
 249        if (wait_for_frame_done)
 250                loop_cnt = 5000;
 251
 252        reg = lcdc_read(&da8xx_fb_reg_base->raster_ctrl);
 253        if (reg & LCD_RASTER_ENABLE)
 254                lcdc_write(reg & ~LCD_RASTER_ENABLE,
 255                        &da8xx_fb_reg_base->raster_ctrl);
 256
 257        /* Wait for the current frame to complete */
 258        do {
 259                if (lcd_revision == LCD_VERSION_1)
 260                        stat = lcdc_read(&da8xx_fb_reg_base->stat);
 261                else
 262                        stat = lcdc_read(&da8xx_fb_reg_base->raw_stat);
 263
 264                mdelay(1);
 265        } while (!(stat & 0x01) && (i++ < loop_cnt));
 266
 267        if (lcd_revision == LCD_VERSION_1)
 268                lcdc_write(stat, &da8xx_fb_reg_base->stat);
 269        else
 270                lcdc_write(stat, &da8xx_fb_reg_base->raw_stat);
 271
 272        if ((loop_cnt != 0) && (i >= loop_cnt)) {
 273                printf("LCD Controller timed out\n");
 274                return;
 275        }
 276}
 277
 278static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
 279{
 280        u32 start;
 281        u32 end;
 282        u32 reg_ras;
 283        u32 reg_dma;
 284        u32 reg_int;
 285
 286        /* init reg to clear PLM (loading mode) fields */
 287        reg_ras = lcdc_read(&da8xx_fb_reg_base->raster_ctrl);
 288        reg_ras &= ~(3 << 20);
 289
 290        reg_dma  = lcdc_read(&da8xx_fb_reg_base->dma_ctrl);
 291
 292        if (load_mode == LOAD_DATA) {
 293                start    = par->dma_start;
 294                end      = par->dma_end;
 295
 296                reg_ras |= LCD_PALETTE_LOAD_MODE(DATA_ONLY);
 297                if (lcd_revision == LCD_VERSION_1) {
 298                        reg_dma |= LCD_V1_END_OF_FRAME_INT_ENA;
 299                } else {
 300                        reg_int = lcdc_read(&da8xx_fb_reg_base->int_ena_set) |
 301                                LCD_V2_END_OF_FRAME0_INT_ENA |
 302                                LCD_V2_END_OF_FRAME1_INT_ENA |
 303                                LCD_V2_UNDERFLOW_INT_ENA | LCD_SYNC_LOST;
 304                        lcdc_write(reg_int, &da8xx_fb_reg_base->int_ena_set);
 305                }
 306
 307#if (LCD_NUM_BUFFERS == 2)
 308                reg_dma |= LCD_DUAL_FRAME_BUFFER_ENABLE;
 309                lcdc_write(start, &da8xx_fb_reg_base->dma_frm_buf_base_addr_0);
 310                lcdc_write(end, &da8xx_fb_reg_base->dma_frm_buf_ceiling_addr_0);
 311                lcdc_write(start, &da8xx_fb_reg_base->dma_frm_buf_base_addr_1);
 312                lcdc_write(end, &da8xx_fb_reg_base->dma_frm_buf_ceiling_addr_1);
 313#else
 314                reg_dma &= ~LCD_DUAL_FRAME_BUFFER_ENABLE;
 315                lcdc_write(start, &da8xx_fb_reg_base->dma_frm_buf_base_addr_0);
 316                lcdc_write(end, &da8xx_fb_reg_base->dma_frm_buf_ceiling_addr_0);
 317                lcdc_write(0, &da8xx_fb_reg_base->dma_frm_buf_base_addr_1);
 318                lcdc_write(0, &da8xx_fb_reg_base->dma_frm_buf_ceiling_addr_1);
 319#endif
 320
 321        } else if (load_mode == LOAD_PALETTE) {
 322                start    = par->p_palette_base;
 323                end      = start + par->palette_sz - 1;
 324
 325                reg_ras |= LCD_PALETTE_LOAD_MODE(PALETTE_ONLY);
 326                if (lcd_revision == LCD_VERSION_1) {
 327                        reg_ras |= LCD_V1_PL_INT_ENA;
 328                } else {
 329                        reg_int = lcdc_read(&da8xx_fb_reg_base->int_ena_set) |
 330                                LCD_V2_PL_INT_ENA;
 331                        lcdc_write(reg_int, &da8xx_fb_reg_base->int_ena_set);
 332                }
 333
 334                lcdc_write(start, &da8xx_fb_reg_base->dma_frm_buf_base_addr_0);
 335                lcdc_write(end, &da8xx_fb_reg_base->dma_frm_buf_ceiling_addr_0);
 336        }
 337
 338        lcdc_write(reg_dma, &da8xx_fb_reg_base->dma_ctrl);
 339        lcdc_write(reg_ras, &da8xx_fb_reg_base->raster_ctrl);
 340
 341        /*
 342         * The Raster enable bit must be set after all other control fields are
 343         * set.
 344         */
 345        lcd_enable_raster();
 346}
 347
 348/* Configure the Burst Size of DMA */
 349static int lcd_cfg_dma(int burst_size)
 350{
 351        u32 reg;
 352
 353        reg = lcdc_read(&da8xx_fb_reg_base->dma_ctrl) & 0x00000001;
 354        switch (burst_size) {
 355        case 1:
 356                reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_1);
 357                break;
 358        case 2:
 359                reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_2);
 360                break;
 361        case 4:
 362                reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_4);
 363                break;
 364        case 8:
 365                reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_8);
 366                break;
 367        case 16:
 368                reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_16);
 369                break;
 370        default:
 371                return -EINVAL;
 372        }
 373        lcdc_write(reg, &da8xx_fb_reg_base->dma_ctrl);
 374
 375        return 0;
 376}
 377
 378static void lcd_cfg_ac_bias(int period, int transitions_per_int)
 379{
 380        u32 reg;
 381
 382        /* Set the AC Bias Period and Number of Transitions per Interrupt */
 383        reg = lcdc_read(&da8xx_fb_reg_base->raster_timing_2) & 0xFFF00000;
 384        reg |= LCD_AC_BIAS_FREQUENCY(period) |
 385                LCD_AC_BIAS_TRANSITIONS_PER_INT(transitions_per_int);
 386        lcdc_write(reg, &da8xx_fb_reg_base->raster_timing_2);
 387}
 388
 389static void lcd_cfg_horizontal_sync(int back_porch, int pulse_width,
 390                int front_porch)
 391{
 392        u32 reg;
 393
 394        reg = lcdc_read(&da8xx_fb_reg_base->raster_timing_0) & 0xf;
 395        reg |= ((back_porch & 0xff) << 24)
 396            | ((front_porch & 0xff) << 16)
 397            | ((pulse_width & 0x3f) << 10);
 398        lcdc_write(reg, &da8xx_fb_reg_base->raster_timing_0);
 399}
 400
 401static void lcd_cfg_vertical_sync(int back_porch, int pulse_width,
 402                int front_porch)
 403{
 404        u32 reg;
 405
 406        reg = lcdc_read(&da8xx_fb_reg_base->raster_timing_1) & 0x3ff;
 407        reg |= ((back_porch & 0xff) << 24)
 408            | ((front_porch & 0xff) << 16)
 409            | ((pulse_width & 0x3f) << 10);
 410        lcdc_write(reg, &da8xx_fb_reg_base->raster_timing_1);
 411}
 412
 413static int lcd_cfg_display(const struct lcd_ctrl_config *cfg)
 414{
 415        u32 reg;
 416        u32 reg_int;
 417
 418        reg = lcdc_read(&da8xx_fb_reg_base->raster_ctrl) & ~(LCD_TFT_MODE |
 419                                                LCD_MONO_8BIT_MODE |
 420                                                LCD_MONOCHROME_MODE);
 421
 422        switch (cfg->p_disp_panel->panel_shade) {
 423        case MONOCHROME:
 424                reg |= LCD_MONOCHROME_MODE;
 425                if (cfg->mono_8bit_mode)
 426                        reg |= LCD_MONO_8BIT_MODE;
 427                break;
 428        case COLOR_ACTIVE:
 429                reg |= LCD_TFT_MODE;
 430                if (cfg->tft_alt_mode)
 431                        reg |= LCD_TFT_ALT_ENABLE;
 432                break;
 433
 434        case COLOR_PASSIVE:
 435                if (cfg->stn_565_mode)
 436                        reg |= LCD_STN_565_ENABLE;
 437                break;
 438
 439        default:
 440                return -EINVAL;
 441        }
 442
 443        /* enable additional interrupts here */
 444        if (lcd_revision == LCD_VERSION_1) {
 445                reg |= LCD_V1_UNDERFLOW_INT_ENA;
 446        } else {
 447                reg_int = lcdc_read(&da8xx_fb_reg_base->int_ena_set) |
 448                        LCD_V2_UNDERFLOW_INT_ENA;
 449                lcdc_write(reg_int, &da8xx_fb_reg_base->int_ena_set);
 450        }
 451
 452        lcdc_write(reg, &da8xx_fb_reg_base->raster_ctrl);
 453
 454        reg = lcdc_read(&da8xx_fb_reg_base->raster_timing_2);
 455
 456        if (cfg->sync_ctrl)
 457                reg |= LCD_SYNC_CTRL;
 458        else
 459                reg &= ~LCD_SYNC_CTRL;
 460
 461        if (cfg->sync_edge)
 462                reg |= LCD_SYNC_EDGE;
 463        else
 464                reg &= ~LCD_SYNC_EDGE;
 465
 466        if (cfg->invert_line_clock)
 467                reg |= LCD_INVERT_LINE_CLOCK;
 468        else
 469                reg &= ~LCD_INVERT_LINE_CLOCK;
 470
 471        if (cfg->invert_frm_clock)
 472                reg |= LCD_INVERT_FRAME_CLOCK;
 473        else
 474                reg &= ~LCD_INVERT_FRAME_CLOCK;
 475
 476        lcdc_write(reg, &da8xx_fb_reg_base->raster_timing_2);
 477
 478        return 0;
 479}
 480
 481static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
 482                u32 bpp, u32 raster_order)
 483{
 484        u32 reg;
 485
 486        /* Set the Panel Width */
 487        /* Pixels per line = (PPL + 1)*16 */
 488        if (lcd_revision == LCD_VERSION_1) {
 489                /*
 490                 * 0x3F in bits 4..9 gives max horizontal resolution = 1024
 491                 * pixels
 492                 */
 493                width &= 0x3f0;
 494        } else {
 495                /*
 496                 * 0x7F in bits 4..10 gives max horizontal resolution = 2048
 497                 * pixels.
 498                 */
 499                width &= 0x7f0;
 500        }
 501        reg = lcdc_read(&da8xx_fb_reg_base->raster_timing_0);
 502        reg &= 0xfffffc00;
 503        if (lcd_revision == LCD_VERSION_1) {
 504                reg |= ((width >> 4) - 1) << 4;
 505        } else {
 506                width = (width >> 4) - 1;
 507                reg |= ((width & 0x3f) << 4) | ((width & 0x40) >> 3);
 508        }
 509        lcdc_write(reg, &da8xx_fb_reg_base->raster_timing_0);
 510
 511        /* Set the Panel Height */
 512        /* Set bits 9:0 of Lines Per Pixel */
 513        reg = lcdc_read(&da8xx_fb_reg_base->raster_timing_1);
 514        reg = ((height - 1) & 0x3ff) | (reg & 0xfffffc00);
 515        lcdc_write(reg, &da8xx_fb_reg_base->raster_timing_1);
 516
 517        /* Set bit 10 of Lines Per Pixel */
 518        if (lcd_revision == LCD_VERSION_2) {
 519                reg = lcdc_read(&da8xx_fb_reg_base->raster_timing_2);
 520                reg |= ((height - 1) & 0x400) << 16;
 521                lcdc_write(reg, &da8xx_fb_reg_base->raster_timing_2);
 522        }
 523
 524        /* Set the Raster Order of the Frame Buffer */
 525        reg = lcdc_read(&da8xx_fb_reg_base->raster_ctrl) & ~(1 << 8);
 526        if (raster_order)
 527                reg |= LCD_RASTER_ORDER;
 528
 529        if (bpp == 24)
 530                reg |= (LCD_TFT_MODE | LCD_V2_TFT_24BPP_MODE);
 531        else if (bpp == 32)
 532                reg |= (LCD_TFT_MODE | LCD_V2_TFT_24BPP_MODE
 533                                | LCD_V2_TFT_24BPP_UNPACK);
 534
 535        lcdc_write(reg, &da8xx_fb_reg_base->raster_ctrl);
 536
 537        switch (bpp) {
 538        case 1:
 539        case 2:
 540        case 4:
 541        case 16:
 542        case 24:
 543        case 32:
 544                par->palette_sz = 16 * 2;
 545                break;
 546
 547        case 8:
 548                par->palette_sz = 256 * 2;
 549                break;
 550
 551        default:
 552                return -EINVAL;
 553        }
 554
 555        return 0;
 556}
 557
 558static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
 559                              unsigned blue, unsigned transp,
 560                              struct fb_info *info)
 561{
 562        struct da8xx_fb_par *par = info->par;
 563        unsigned short *palette = (unsigned short *) par->v_palette_base;
 564        u_short pal;
 565        int update_hw = 0;
 566
 567        if (regno > 255)
 568                return 1;
 569
 570        if (info->fix.visual == FB_VISUAL_DIRECTCOLOR)
 571                return 1;
 572
 573        if (info->var.bits_per_pixel == 8) {
 574                red >>= 4;
 575                green >>= 8;
 576                blue >>= 12;
 577
 578                pal = (red & 0x0f00);
 579                pal |= (green & 0x00f0);
 580                pal |= (blue & 0x000f);
 581
 582                if (palette[regno] != pal) {
 583                        update_hw = 1;
 584                        palette[regno] = pal;
 585                }
 586        } else if ((info->var.bits_per_pixel == 16) && regno < 16) {
 587                red >>= (16 - info->var.red.length);
 588                red <<= info->var.red.offset;
 589
 590                green >>= (16 - info->var.green.length);
 591                green <<= info->var.green.offset;
 592
 593                blue >>= (16 - info->var.blue.length);
 594                blue <<= info->var.blue.offset;
 595
 596                par->pseudo_palette[regno] = red | green | blue;
 597
 598                if (palette[0] != 0x4000) {
 599                        update_hw = 1;
 600                        palette[0] = 0x4000;
 601                }
 602        } else if (((info->var.bits_per_pixel == 32) && regno < 32) ||
 603                   ((info->var.bits_per_pixel == 24) && regno < 24)) {
 604                red >>= (24 - info->var.red.length);
 605                red <<= info->var.red.offset;
 606
 607                green >>= (24 - info->var.green.length);
 608                green <<= info->var.green.offset;
 609
 610                blue >>= (24 - info->var.blue.length);
 611                blue <<= info->var.blue.offset;
 612
 613                par->pseudo_palette[regno] = red | green | blue;
 614
 615                if (palette[0] != 0x4000) {
 616                        update_hw = 1;
 617                        palette[0] = 0x4000;
 618                }
 619        }
 620
 621        /* Update the palette in the h/w as needed. */
 622        if (update_hw)
 623                lcd_blit(LOAD_PALETTE, par);
 624
 625        return 0;
 626}
 627
 628static void lcd_reset(struct da8xx_fb_par *par)
 629{
 630        /* Disable the Raster if previously Enabled */
 631        lcd_disable_raster(NO_WAIT_FOR_FRAME_DONE);
 632
 633        /* DMA has to be disabled */
 634        lcdc_write(0, &da8xx_fb_reg_base->dma_ctrl);
 635        lcdc_write(0, &da8xx_fb_reg_base->raster_ctrl);
 636
 637        if (lcd_revision == LCD_VERSION_2) {
 638                lcdc_write(0, &da8xx_fb_reg_base->int_ena_set);
 639                /* Write 1 to reset */
 640                lcdc_write(LCD_CLK_MAIN_RESET, &da8xx_fb_reg_base->clk_reset);
 641                lcdc_write(0, &da8xx_fb_reg_base->clk_reset);
 642        }
 643}
 644
 645static void lcd_calc_clk_divider(struct da8xx_fb_par *par)
 646{
 647        unsigned int lcd_clk, div;
 648
 649        /* Get clock from sysclk2 */
 650        lcd_clk = clk_get(2);
 651
 652        div = lcd_clk / par->pxl_clk;
 653        debug("LCD Clock: %d Divider: %d PixClk: %d\n",
 654              lcd_clk, div, par->pxl_clk);
 655
 656        /* Configure the LCD clock divisor. */
 657        lcdc_write(LCD_CLK_DIVISOR(div) |
 658                        (LCD_RASTER_MODE & 0x1), &da8xx_fb_reg_base->ctrl);
 659
 660        if (lcd_revision == LCD_VERSION_2)
 661                lcdc_write(LCD_V2_DMA_CLK_EN | LCD_V2_LIDD_CLK_EN |
 662                                LCD_V2_CORE_CLK_EN,
 663                                &da8xx_fb_reg_base->clk_ena);
 664}
 665
 666static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
 667                const struct da8xx_panel *panel)
 668{
 669        u32 bpp;
 670        int ret = 0;
 671
 672        lcd_reset(par);
 673
 674        /* Calculate the divider */
 675        lcd_calc_clk_divider(par);
 676
 677        if (panel->invert_pxl_clk)
 678                lcdc_write((lcdc_read(&da8xx_fb_reg_base->raster_timing_2) |
 679                        LCD_INVERT_PIXEL_CLOCK),
 680                         &da8xx_fb_reg_base->raster_timing_2);
 681        else
 682                lcdc_write((lcdc_read(&da8xx_fb_reg_base->raster_timing_2) &
 683                        ~LCD_INVERT_PIXEL_CLOCK),
 684                        &da8xx_fb_reg_base->raster_timing_2);
 685
 686        /* Configure the DMA burst size. */
 687        ret = lcd_cfg_dma(cfg->dma_burst_sz);
 688        if (ret < 0)
 689                return ret;
 690
 691        /* Configure the AC bias properties. */
 692        lcd_cfg_ac_bias(cfg->ac_bias, cfg->ac_bias_intrpt);
 693
 694        /* Configure the vertical and horizontal sync properties. */
 695        lcd_cfg_vertical_sync(panel->vbp, panel->vsw, panel->vfp);
 696        lcd_cfg_horizontal_sync(panel->hbp, panel->hsw, panel->hfp);
 697
 698        /* Configure for display */
 699        ret = lcd_cfg_display(cfg);
 700        if (ret < 0)
 701                return ret;
 702
 703        if ((QVGA != cfg->p_disp_panel->panel_type) &&
 704            (WVGA != cfg->p_disp_panel->panel_type))
 705                return -EINVAL;
 706
 707        if (cfg->bpp <= cfg->p_disp_panel->max_bpp &&
 708            cfg->bpp >= cfg->p_disp_panel->min_bpp)
 709                bpp = cfg->bpp;
 710        else
 711                bpp = cfg->p_disp_panel->max_bpp;
 712        if (bpp == 12)
 713                bpp = 16;
 714        ret = lcd_cfg_frame_buffer(par, (unsigned int)panel->width,
 715                                (unsigned int)panel->height, bpp,
 716                                cfg->raster_order);
 717        if (ret < 0)
 718                return ret;
 719
 720        /* Configure FDD */
 721        lcdc_write((lcdc_read(&da8xx_fb_reg_base->raster_ctrl) & 0xfff00fff) |
 722                       (cfg->fdd << 12), &da8xx_fb_reg_base->raster_ctrl);
 723
 724        return 0;
 725}
 726
 727static void lcdc_dma_start(void)
 728{
 729        struct da8xx_fb_par *par = da8xx_fb_info->par;
 730        lcdc_write(par->dma_start,
 731                &da8xx_fb_reg_base->dma_frm_buf_base_addr_0);
 732        lcdc_write(par->dma_end,
 733                &da8xx_fb_reg_base->dma_frm_buf_ceiling_addr_0);
 734        lcdc_write(0,
 735                &da8xx_fb_reg_base->dma_frm_buf_base_addr_1);
 736        lcdc_write(0,
 737                &da8xx_fb_reg_base->dma_frm_buf_ceiling_addr_1);
 738}
 739
 740static u32 lcdc_irq_handler_rev01(void)
 741{
 742        struct da8xx_fb_par *par = da8xx_fb_info->par;
 743        u32 stat = lcdc_read(&da8xx_fb_reg_base->stat);
 744        u32 reg_ras;
 745
 746        if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {
 747                debug("LCD_SYNC_LOST\n");
 748                lcd_disable_raster(NO_WAIT_FOR_FRAME_DONE);
 749                lcdc_write(stat, &da8xx_fb_reg_base->stat);
 750                lcd_enable_raster();
 751                return LCD_SYNC_LOST;
 752        } else if (stat & LCD_PL_LOAD_DONE) {
 753                debug("LCD_PL_LOAD_DONE\n");
 754                /*
 755                 * Must disable raster before changing state of any control bit.
 756                 * And also must be disabled before clearing the PL loading
 757                 * interrupt via the following write to the status register. If
 758                 * this is done after then one gets multiple PL done interrupts.
 759                 */
 760                lcd_disable_raster(NO_WAIT_FOR_FRAME_DONE);
 761
 762                lcdc_write(stat, &da8xx_fb_reg_base->stat);
 763
 764                /* Disable PL completion interrupt */
 765                reg_ras  = lcdc_read(&da8xx_fb_reg_base->raster_ctrl);
 766                reg_ras &= ~LCD_V1_PL_INT_ENA;
 767                lcdc_write(reg_ras, &da8xx_fb_reg_base->raster_ctrl);
 768
 769                /* Setup and start data loading mode */
 770                lcd_blit(LOAD_DATA, par);
 771                return LCD_PL_LOAD_DONE;
 772        } else {
 773                lcdc_write(stat, &da8xx_fb_reg_base->stat);
 774
 775                if (stat & LCD_END_OF_FRAME0)
 776                        debug("LCD_END_OF_FRAME0\n");
 777
 778                lcdc_write(par->dma_start,
 779                        &da8xx_fb_reg_base->dma_frm_buf_base_addr_0);
 780                lcdc_write(par->dma_end,
 781                        &da8xx_fb_reg_base->dma_frm_buf_ceiling_addr_0);
 782                par->vsync_flag = 1;
 783                return LCD_END_OF_FRAME0;
 784        }
 785        return stat;
 786}
 787
 788static u32 lcdc_irq_handler_rev02(void)
 789{
 790        struct da8xx_fb_par *par = da8xx_fb_info->par;
 791        u32 stat = lcdc_read(&da8xx_fb_reg_base->masked_stat);
 792        u32 reg_int;
 793
 794        if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {
 795                debug("LCD_SYNC_LOST\n");
 796                lcd_disable_raster(NO_WAIT_FOR_FRAME_DONE);
 797                lcdc_write(stat, &da8xx_fb_reg_base->masked_stat);
 798                lcd_enable_raster();
 799                lcdc_write(0, &da8xx_fb_reg_base->end_of_int_ind);
 800                return LCD_SYNC_LOST;
 801        } else if (stat & LCD_PL_LOAD_DONE) {
 802                debug("LCD_PL_LOAD_DONE\n");
 803                /*
 804                 * Must disable raster before changing state of any control bit.
 805                 * And also must be disabled before clearing the PL loading
 806                 * interrupt via the following write to the status register. If
 807                 * this is done after then one gets multiple PL done interrupts.
 808                 */
 809                lcd_disable_raster(NO_WAIT_FOR_FRAME_DONE);
 810
 811                lcdc_write(stat, &da8xx_fb_reg_base->masked_stat);
 812
 813                /* Disable PL completion interrupt */
 814                reg_int  = lcdc_read(&da8xx_fb_reg_base->int_ena_clr) |
 815                        (LCD_V2_PL_INT_ENA);
 816                lcdc_write(reg_int, &da8xx_fb_reg_base->int_ena_clr);
 817
 818                /* Setup and start data loading mode */
 819                lcd_blit(LOAD_DATA, par);
 820                lcdc_write(0, &da8xx_fb_reg_base->end_of_int_ind);
 821                return LCD_PL_LOAD_DONE;
 822        } else {
 823                lcdc_write(stat, &da8xx_fb_reg_base->masked_stat);
 824
 825                if (stat & LCD_END_OF_FRAME0)
 826                        debug("LCD_END_OF_FRAME0\n");
 827
 828                lcdc_write(par->dma_start,
 829                           &da8xx_fb_reg_base->dma_frm_buf_base_addr_0);
 830                lcdc_write(par->dma_end,
 831                           &da8xx_fb_reg_base->dma_frm_buf_ceiling_addr_0);
 832                par->vsync_flag = 1;
 833                lcdc_write(0, &da8xx_fb_reg_base->end_of_int_ind);
 834                return LCD_END_OF_FRAME0;
 835        }
 836        lcdc_write(0, &da8xx_fb_reg_base->end_of_int_ind);
 837        return stat;
 838}
 839
 840static u32 lcdc_irq_handler(void)
 841{
 842        if (lcd_revision == LCD_VERSION_1)
 843                return lcdc_irq_handler_rev01();
 844        else
 845                return lcdc_irq_handler_rev02();
 846}
 847
 848static u32 wait_for_event(u32 event)
 849{
 850        u32 timeout = 50000;
 851        u32 ret;
 852
 853        do {
 854                ret = lcdc_irq_handler();
 855                udelay(1000);
 856        } while (!(ret & event));
 857
 858        if (timeout <= 0) {
 859                printf("%s: event %d not hit\n", __func__, event);
 860                return -1;
 861        }
 862
 863        return 0;
 864
 865}
 866
 867void *video_hw_init(void)
 868{
 869        struct da8xx_fb_par *par;
 870        u32 size;
 871        u32 rev;
 872        char *p;
 873
 874        if (!lcd_panel) {
 875                printf("Display not initialized\n");
 876                return NULL;
 877        }
 878        gpanel.winSizeX = lcd_panel->width;
 879        gpanel.winSizeY = lcd_panel->height;
 880        gpanel.plnSizeX = lcd_panel->width;
 881        gpanel.plnSizeY = lcd_panel->height;
 882
 883        switch (bits_x_pixel) {
 884        case 32:
 885                gpanel.gdfBytesPP = 4;
 886                gpanel.gdfIndex = GDF_32BIT_X888RGB;
 887                break;
 888        case 24:
 889                gpanel.gdfBytesPP = 4;
 890                gpanel.gdfIndex = GDF_32BIT_X888RGB;
 891                break;
 892        case 16:
 893                gpanel.gdfBytesPP = 2;
 894                gpanel.gdfIndex = GDF_16BIT_565RGB;
 895                break;
 896        default:
 897                gpanel.gdfBytesPP = 1;
 898                gpanel.gdfIndex = GDF__8BIT_INDEX;
 899                break;
 900        }
 901
 902        da8xx_fb_reg_base = (struct da8xx_lcd_regs *)DA8XX_LCD_CNTL_BASE;
 903
 904        /* Determine LCD IP Version */
 905        rev = lcdc_read(&da8xx_fb_reg_base->revid);
 906        switch (rev) {
 907        case 0x4C100102:
 908                lcd_revision = LCD_VERSION_1;
 909                break;
 910        case 0x4F200800:
 911        case 0x4F201000:
 912                lcd_revision = LCD_VERSION_2;
 913                break;
 914        default:
 915                printf("Unknown PID Reg value 0x%x, defaulting to LCD revision 1\n",
 916                       rev);
 917                lcd_revision = LCD_VERSION_1;
 918                break;
 919        }
 920
 921        debug("rev: 0x%x Resolution: %dx%d %d\n", rev,
 922              gpanel.winSizeX,
 923              gpanel.winSizeY,
 924              da8xx_lcd_cfg->bpp);
 925
 926        size = sizeof(struct fb_info) + sizeof(struct da8xx_fb_par);
 927        da8xx_fb_info = malloc(size);
 928        debug("da8xx_fb_info at %x\n", (unsigned int)da8xx_fb_info);
 929
 930        if (!da8xx_fb_info) {
 931                printf("Memory allocation failed for fb_info\n");
 932                return NULL;
 933        }
 934        memset(da8xx_fb_info, 0, size);
 935        p = (char *)da8xx_fb_info;
 936        da8xx_fb_info->par = p +  sizeof(struct fb_info);
 937        debug("da8xx_par at %x\n", (unsigned int)da8xx_fb_info->par);
 938
 939        par = da8xx_fb_info->par;
 940        par->pxl_clk = lcd_panel->pxl_clk;
 941
 942        if (lcd_init(par, da8xx_lcd_cfg, lcd_panel) < 0) {
 943                printf("lcd_init failed\n");
 944                goto err_release_fb;
 945        }
 946
 947        /* allocate frame buffer */
 948        par->vram_size = lcd_panel->width * lcd_panel->height *
 949                        da8xx_lcd_cfg->bpp;
 950        par->vram_size = par->vram_size * LCD_NUM_BUFFERS / 8;
 951
 952        par->vram_virt = malloc(par->vram_size);
 953
 954        par->vram_phys = (dma_addr_t) par->vram_virt;
 955        debug("Requesting 0x%x bytes for framebuffer at 0x%x\n",
 956                (unsigned int)par->vram_size,
 957                (unsigned int)par->vram_virt);
 958        if (!par->vram_virt) {
 959                printf("GLCD: malloc for frame buffer failed\n");
 960                goto err_release_fb;
 961        }
 962        gd->fb_base = (int)par->vram_virt;
 963
 964        gpanel.frameAdrs = (unsigned int)par->vram_virt;
 965        da8xx_fb_info->screen_base = (char *) par->vram_virt;
 966        da8xx_fb_fix.smem_start = gpanel.frameAdrs;
 967        da8xx_fb_fix.smem_len = par->vram_size;
 968        da8xx_fb_fix.line_length = (lcd_panel->width * da8xx_lcd_cfg->bpp) / 8;
 969
 970        par->dma_start = par->vram_phys;
 971        par->dma_end   = par->dma_start + lcd_panel->height *
 972                da8xx_fb_fix.line_length - 1;
 973
 974        /* allocate palette buffer */
 975        par->v_palette_base = malloc(PALETTE_SIZE);
 976        if (!par->v_palette_base) {
 977                printf("GLCD: malloc for palette buffer failed\n");
 978                goto err_release_fb_mem;
 979        }
 980        memset(par->v_palette_base, 0, PALETTE_SIZE);
 981        par->p_palette_base = (unsigned int)par->v_palette_base;
 982
 983        /* Initialize par */
 984        da8xx_fb_info->var.bits_per_pixel = da8xx_lcd_cfg->bpp;
 985
 986        da8xx_fb_var.xres = lcd_panel->width;
 987        da8xx_fb_var.xres_virtual = lcd_panel->width;
 988
 989        da8xx_fb_var.yres         = lcd_panel->height;
 990        da8xx_fb_var.yres_virtual = lcd_panel->height * LCD_NUM_BUFFERS;
 991
 992        da8xx_fb_var.grayscale =
 993            da8xx_lcd_cfg->p_disp_panel->panel_shade == MONOCHROME ? 1 : 0;
 994        da8xx_fb_var.bits_per_pixel = da8xx_lcd_cfg->bpp;
 995
 996        da8xx_fb_var.hsync_len = lcd_panel->hsw;
 997        da8xx_fb_var.vsync_len = lcd_panel->vsw;
 998
 999        /* Initialize fbinfo */
1000        da8xx_fb_info->flags = FBINFO_FLAG_DEFAULT;
1001        da8xx_fb_info->fix = da8xx_fb_fix;
1002        da8xx_fb_info->var = da8xx_fb_var;
1003        da8xx_fb_info->pseudo_palette = par->pseudo_palette;
1004        da8xx_fb_info->fix.visual = (da8xx_fb_info->var.bits_per_pixel <= 8) ?
1005                                FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
1006
1007        /* Clear interrupt */
1008        memset((void *)par->vram_virt, 0, par->vram_size);
1009        lcd_disable_raster(NO_WAIT_FOR_FRAME_DONE);
1010        if (lcd_revision == LCD_VERSION_1)
1011                lcdc_write(0xFFFF, &da8xx_fb_reg_base->stat);
1012        else
1013                lcdc_write(0xFFFF, &da8xx_fb_reg_base->masked_stat);
1014        debug("Palette at 0x%x size %d\n", par->p_palette_base,
1015                par->palette_sz);
1016        lcdc_dma_start();
1017
1018        /* Load a default palette */
1019        fb_setcolreg(0, 0, 0, 0, 0xffff, da8xx_fb_info);
1020
1021        /* Check that the palette is loaded */
1022        wait_for_event(LCD_PL_LOAD_DONE);
1023
1024        /* Wait until DMA is working */
1025        wait_for_event(LCD_END_OF_FRAME0);
1026
1027        return (void *)&gpanel;
1028
1029err_release_fb_mem:
1030        free(par->vram_virt);
1031
1032err_release_fb:
1033        free(da8xx_fb_info);
1034
1035        return NULL;
1036}
1037
1038void da8xx_video_init(const struct da8xx_panel *panel,
1039                      const struct lcd_ctrl_config *lcd_cfg, int bits_pixel)
1040{
1041        lcd_panel = panel;
1042        da8xx_lcd_cfg = lcd_cfg;
1043        bits_x_pixel = bits_pixel;
1044}
1045