linux/drivers/video/da8xx-fb.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2008-2009 MontaVista Software Inc.
   3 * Copyright (C) 2008-2009 Texas Instruments Inc
   4 *
   5 * Based on the LCD driver for TI Avalanche processors written by
   6 * Ajay Singh and Shalom Hai.
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License as published by
  10 * the Free Software Foundation; either version 2 of the License, or
  11 * (at your option)any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  21 */
  22#include <linux/module.h>
  23#include <linux/kernel.h>
  24#include <linux/fb.h>
  25#include <linux/dma-mapping.h>
  26#include <linux/device.h>
  27#include <linux/platform_device.h>
  28#include <linux/uaccess.h>
  29#include <linux/pm_runtime.h>
  30#include <linux/interrupt.h>
  31#include <linux/wait.h>
  32#include <linux/clk.h>
  33#include <linux/cpufreq.h>
  34#include <linux/console.h>
  35#include <linux/spinlock.h>
  36#include <linux/slab.h>
  37#include <linux/delay.h>
  38#include <linux/lcm.h>
  39#include <video/da8xx-fb.h>
  40#include <asm/div64.h>
  41
  42#define DRIVER_NAME "da8xx_lcdc"
  43
  44#define LCD_VERSION_1   1
  45#define LCD_VERSION_2   2
  46
  47/* LCD Status Register */
  48#define LCD_END_OF_FRAME1               BIT(9)
  49#define LCD_END_OF_FRAME0               BIT(8)
  50#define LCD_PL_LOAD_DONE                BIT(6)
  51#define LCD_FIFO_UNDERFLOW              BIT(5)
  52#define LCD_SYNC_LOST                   BIT(2)
  53#define LCD_FRAME_DONE                  BIT(0)
  54
  55/* LCD DMA Control Register */
  56#define LCD_DMA_BURST_SIZE(x)           ((x) << 4)
  57#define LCD_DMA_BURST_1                 0x0
  58#define LCD_DMA_BURST_2                 0x1
  59#define LCD_DMA_BURST_4                 0x2
  60#define LCD_DMA_BURST_8                 0x3
  61#define LCD_DMA_BURST_16                0x4
  62#define LCD_V1_END_OF_FRAME_INT_ENA     BIT(2)
  63#define LCD_V2_END_OF_FRAME0_INT_ENA    BIT(8)
  64#define LCD_V2_END_OF_FRAME1_INT_ENA    BIT(9)
  65#define LCD_DUAL_FRAME_BUFFER_ENABLE    BIT(0)
  66
  67/* LCD Control Register */
  68#define LCD_CLK_DIVISOR(x)              ((x) << 8)
  69#define LCD_RASTER_MODE                 0x01
  70
  71/* LCD Raster Control Register */
  72#define LCD_PALETTE_LOAD_MODE(x)        ((x) << 20)
  73#define PALETTE_AND_DATA                0x00
  74#define PALETTE_ONLY                    0x01
  75#define DATA_ONLY                       0x02
  76
  77#define LCD_MONO_8BIT_MODE              BIT(9)
  78#define LCD_RASTER_ORDER                BIT(8)
  79#define LCD_TFT_MODE                    BIT(7)
  80#define LCD_V1_UNDERFLOW_INT_ENA        BIT(6)
  81#define LCD_V2_UNDERFLOW_INT_ENA        BIT(5)
  82#define LCD_V1_PL_INT_ENA               BIT(4)
  83#define LCD_V2_PL_INT_ENA               BIT(6)
  84#define LCD_MONOCHROME_MODE             BIT(1)
  85#define LCD_RASTER_ENABLE               BIT(0)
  86#define LCD_TFT_ALT_ENABLE              BIT(23)
  87#define LCD_STN_565_ENABLE              BIT(24)
  88#define LCD_V2_DMA_CLK_EN               BIT(2)
  89#define LCD_V2_LIDD_CLK_EN              BIT(1)
  90#define LCD_V2_CORE_CLK_EN              BIT(0)
  91#define LCD_V2_LPP_B10                  26
  92#define LCD_V2_TFT_24BPP_MODE           BIT(25)
  93#define LCD_V2_TFT_24BPP_UNPACK         BIT(26)
  94
  95/* LCD Raster Timing 2 Register */
  96#define LCD_AC_BIAS_TRANSITIONS_PER_INT(x)      ((x) << 16)
  97#define LCD_AC_BIAS_FREQUENCY(x)                ((x) << 8)
  98#define LCD_SYNC_CTRL                           BIT(25)
  99#define LCD_SYNC_EDGE                           BIT(24)
 100#define LCD_INVERT_PIXEL_CLOCK                  BIT(22)
 101#define LCD_INVERT_LINE_CLOCK                   BIT(21)
 102#define LCD_INVERT_FRAME_CLOCK                  BIT(20)
 103
 104/* LCD Block */
 105#define  LCD_PID_REG                            0x0
 106#define  LCD_CTRL_REG                           0x4
 107#define  LCD_STAT_REG                           0x8
 108#define  LCD_RASTER_CTRL_REG                    0x28
 109#define  LCD_RASTER_TIMING_0_REG                0x2C
 110#define  LCD_RASTER_TIMING_1_REG                0x30
 111#define  LCD_RASTER_TIMING_2_REG                0x34
 112#define  LCD_DMA_CTRL_REG                       0x40
 113#define  LCD_DMA_FRM_BUF_BASE_ADDR_0_REG        0x44
 114#define  LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG     0x48
 115#define  LCD_DMA_FRM_BUF_BASE_ADDR_1_REG        0x4C
 116#define  LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG     0x50
 117
 118/* Interrupt Registers available only in Version 2 */
 119#define  LCD_RAW_STAT_REG                       0x58
 120#define  LCD_MASKED_STAT_REG                    0x5c
 121#define  LCD_INT_ENABLE_SET_REG                 0x60
 122#define  LCD_INT_ENABLE_CLR_REG                 0x64
 123#define  LCD_END_OF_INT_IND_REG                 0x68
 124
 125/* Clock registers available only on Version 2 */
 126#define  LCD_CLK_ENABLE_REG                     0x6c
 127#define  LCD_CLK_RESET_REG                      0x70
 128#define  LCD_CLK_MAIN_RESET                     BIT(3)
 129
 130#define LCD_NUM_BUFFERS 2
 131
 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
 138
 139static void __iomem *da8xx_fb_reg_base;
 140static struct resource *lcdc_regs;
 141static unsigned int lcd_revision;
 142static irq_handler_t lcdc_irq_handler;
 143static wait_queue_head_t frame_done_wq;
 144static int frame_done_flag;
 145
 146static inline unsigned int lcdc_read(unsigned int addr)
 147{
 148        return (unsigned int)__raw_readl(da8xx_fb_reg_base + (addr));
 149}
 150
 151static inline void lcdc_write(unsigned int val, unsigned int addr)
 152{
 153        __raw_writel(val, da8xx_fb_reg_base + (addr));
 154}
 155
 156struct da8xx_fb_par {
 157        resource_size_t p_palette_base;
 158        unsigned char *v_palette_base;
 159        dma_addr_t              vram_phys;
 160        unsigned long           vram_size;
 161        void                    *vram_virt;
 162        unsigned int            dma_start;
 163        unsigned int            dma_end;
 164        struct clk *lcdc_clk;
 165        int irq;
 166        unsigned int palette_sz;
 167        unsigned int pxl_clk;
 168        int blank;
 169        wait_queue_head_t       vsync_wait;
 170        int                     vsync_flag;
 171        int                     vsync_timeout;
 172        spinlock_t              lock_for_chan_update;
 173
 174        /*
 175         * LCDC has 2 ping pong DMA channels, channel 0
 176         * and channel 1.
 177         */
 178        unsigned int            which_dma_channel_done;
 179#ifdef CONFIG_CPU_FREQ
 180        struct notifier_block   freq_transition;
 181        unsigned int            lcd_fck_rate;
 182#endif
 183        void (*panel_power_ctrl)(int);
 184        u32 pseudo_palette[16];
 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        .accel_flags = 0,
 197        .left_margin = LEFT_MARGIN,
 198        .right_margin = RIGHT_MARGIN,
 199        .upper_margin = UPPER_MARGIN,
 200        .lower_margin = LOWER_MARGIN,
 201        .sync = 0,
 202        .vmode = FB_VMODE_NONINTERLACED
 203};
 204
 205static struct fb_fix_screeninfo da8xx_fb_fix = {
 206        .id = "DA8xx FB Drv",
 207        .type = FB_TYPE_PACKED_PIXELS,
 208        .type_aux = 0,
 209        .visual = FB_VISUAL_PSEUDOCOLOR,
 210        .xpanstep = 0,
 211        .ypanstep = 1,
 212        .ywrapstep = 0,
 213        .accel = FB_ACCEL_NONE
 214};
 215
 216static struct fb_videomode known_lcd_panels[] = {
 217        /* Sharp LCD035Q3DG01 */
 218        [0] = {
 219                .name           = "Sharp_LCD035Q3DG01",
 220                .xres           = 320,
 221                .yres           = 240,
 222                .pixclock       = 4608000,
 223                .left_margin    = 6,
 224                .right_margin   = 8,
 225                .upper_margin   = 2,
 226                .lower_margin   = 2,
 227                .hsync_len      = 0,
 228                .vsync_len      = 0,
 229                .sync           = FB_SYNC_CLK_INVERT |
 230                        FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
 231        },
 232        /* Sharp LK043T1DG01 */
 233        [1] = {
 234                .name           = "Sharp_LK043T1DG01",
 235                .xres           = 480,
 236                .yres           = 272,
 237                .pixclock       = 7833600,
 238                .left_margin    = 2,
 239                .right_margin   = 2,
 240                .upper_margin   = 2,
 241                .lower_margin   = 2,
 242                .hsync_len      = 41,
 243                .vsync_len      = 10,
 244                .sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
 245                .flag           = 0,
 246        },
 247        [2] = {
 248                /* Hitachi SP10Q010 */
 249                .name           = "SP10Q010",
 250                .xres           = 320,
 251                .yres           = 240,
 252                .pixclock       = 7833600,
 253                .left_margin    = 10,
 254                .right_margin   = 10,
 255                .upper_margin   = 10,
 256                .lower_margin   = 10,
 257                .hsync_len      = 10,
 258                .vsync_len      = 10,
 259                .sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
 260                .flag           = 0,
 261        },
 262};
 263
 264/* Enable the Raster Engine of the LCD Controller */
 265static inline void lcd_enable_raster(void)
 266{
 267        u32 reg;
 268
 269        /* Put LCDC in reset for several cycles */
 270        if (lcd_revision == LCD_VERSION_2)
 271                /* Write 1 to reset LCDC */
 272                lcdc_write(LCD_CLK_MAIN_RESET, LCD_CLK_RESET_REG);
 273        mdelay(1);
 274
 275        /* Bring LCDC out of reset */
 276        if (lcd_revision == LCD_VERSION_2)
 277                lcdc_write(0, LCD_CLK_RESET_REG);
 278        mdelay(1);
 279
 280        /* Above reset sequence doesnot reset register context */
 281        reg = lcdc_read(LCD_RASTER_CTRL_REG);
 282        if (!(reg & LCD_RASTER_ENABLE))
 283                lcdc_write(reg | LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG);
 284}
 285
 286/* Disable the Raster Engine of the LCD Controller */
 287static inline void lcd_disable_raster(bool wait_for_frame_done)
 288{
 289        u32 reg;
 290        int ret;
 291
 292        reg = lcdc_read(LCD_RASTER_CTRL_REG);
 293        if (reg & LCD_RASTER_ENABLE)
 294                lcdc_write(reg & ~LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG);
 295        else
 296                /* return if already disabled */
 297                return;
 298
 299        if ((wait_for_frame_done == true) && (lcd_revision == LCD_VERSION_2)) {
 300                frame_done_flag = 0;
 301                ret = wait_event_interruptible_timeout(frame_done_wq,
 302                                frame_done_flag != 0,
 303                                msecs_to_jiffies(50));
 304                if (ret == 0)
 305                        pr_err("LCD Controller timed out\n");
 306        }
 307}
 308
 309static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
 310{
 311        u32 start;
 312        u32 end;
 313        u32 reg_ras;
 314        u32 reg_dma;
 315        u32 reg_int;
 316
 317        /* init reg to clear PLM (loading mode) fields */
 318        reg_ras = lcdc_read(LCD_RASTER_CTRL_REG);
 319        reg_ras &= ~(3 << 20);
 320
 321        reg_dma  = lcdc_read(LCD_DMA_CTRL_REG);
 322
 323        if (load_mode == LOAD_DATA) {
 324                start    = par->dma_start;
 325                end      = par->dma_end;
 326
 327                reg_ras |= LCD_PALETTE_LOAD_MODE(DATA_ONLY);
 328                if (lcd_revision == LCD_VERSION_1) {
 329                        reg_dma |= LCD_V1_END_OF_FRAME_INT_ENA;
 330                } else {
 331                        reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) |
 332                                LCD_V2_END_OF_FRAME0_INT_ENA |
 333                                LCD_V2_END_OF_FRAME1_INT_ENA |
 334                                LCD_FRAME_DONE;
 335                        lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG);
 336                }
 337                reg_dma |= LCD_DUAL_FRAME_BUFFER_ENABLE;
 338
 339                lcdc_write(start, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
 340                lcdc_write(end, LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
 341                lcdc_write(start, LCD_DMA_FRM_BUF_BASE_ADDR_1_REG);
 342                lcdc_write(end, LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG);
 343        } else if (load_mode == LOAD_PALETTE) {
 344                start    = par->p_palette_base;
 345                end      = start + par->palette_sz - 1;
 346
 347                reg_ras |= LCD_PALETTE_LOAD_MODE(PALETTE_ONLY);
 348
 349                if (lcd_revision == LCD_VERSION_1) {
 350                        reg_ras |= LCD_V1_PL_INT_ENA;
 351                } else {
 352                        reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) |
 353                                LCD_V2_PL_INT_ENA;
 354                        lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG);
 355                }
 356
 357                lcdc_write(start, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
 358                lcdc_write(end, LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
 359        }
 360
 361        lcdc_write(reg_dma, LCD_DMA_CTRL_REG);
 362        lcdc_write(reg_ras, LCD_RASTER_CTRL_REG);
 363
 364        /*
 365         * The Raster enable bit must be set after all other control fields are
 366         * set.
 367         */
 368        lcd_enable_raster();
 369}
 370
 371/* Configure the Burst Size and fifo threhold of DMA */
 372static int lcd_cfg_dma(int burst_size, int fifo_th)
 373{
 374        u32 reg;
 375
 376        reg = lcdc_read(LCD_DMA_CTRL_REG) & 0x00000001;
 377        switch (burst_size) {
 378        case 1:
 379                reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_1);
 380                break;
 381        case 2:
 382                reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_2);
 383                break;
 384        case 4:
 385                reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_4);
 386                break;
 387        case 8:
 388                reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_8);
 389                break;
 390        case 16:
 391        default:
 392                reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_16);
 393                break;
 394        }
 395
 396        reg |= (fifo_th << 8);
 397
 398        lcdc_write(reg, LCD_DMA_CTRL_REG);
 399
 400        return 0;
 401}
 402
 403static void lcd_cfg_ac_bias(int period, int transitions_per_int)
 404{
 405        u32 reg;
 406
 407        /* Set the AC Bias Period and Number of Transisitons per Interrupt */
 408        reg = lcdc_read(LCD_RASTER_TIMING_2_REG) & 0xFFF00000;
 409        reg |= LCD_AC_BIAS_FREQUENCY(period) |
 410                LCD_AC_BIAS_TRANSITIONS_PER_INT(transitions_per_int);
 411        lcdc_write(reg, LCD_RASTER_TIMING_2_REG);
 412}
 413
 414static void lcd_cfg_horizontal_sync(int back_porch, int pulse_width,
 415                int front_porch)
 416{
 417        u32 reg;
 418
 419        reg = lcdc_read(LCD_RASTER_TIMING_0_REG) & 0xf;
 420        reg |= ((back_porch & 0xff) << 24)
 421            | ((front_porch & 0xff) << 16)
 422            | ((pulse_width & 0x3f) << 10);
 423        lcdc_write(reg, LCD_RASTER_TIMING_0_REG);
 424}
 425
 426static void lcd_cfg_vertical_sync(int back_porch, int pulse_width,
 427                int front_porch)
 428{
 429        u32 reg;
 430
 431        reg = lcdc_read(LCD_RASTER_TIMING_1_REG) & 0x3ff;
 432        reg |= ((back_porch & 0xff) << 24)
 433            | ((front_porch & 0xff) << 16)
 434            | ((pulse_width & 0x3f) << 10);
 435        lcdc_write(reg, LCD_RASTER_TIMING_1_REG);
 436}
 437
 438static int lcd_cfg_display(const struct lcd_ctrl_config *cfg,
 439                struct fb_videomode *panel)
 440{
 441        u32 reg;
 442        u32 reg_int;
 443
 444        reg = lcdc_read(LCD_RASTER_CTRL_REG) & ~(LCD_TFT_MODE |
 445                                                LCD_MONO_8BIT_MODE |
 446                                                LCD_MONOCHROME_MODE);
 447
 448        switch (cfg->panel_shade) {
 449        case MONOCHROME:
 450                reg |= LCD_MONOCHROME_MODE;
 451                if (cfg->mono_8bit_mode)
 452                        reg |= LCD_MONO_8BIT_MODE;
 453                break;
 454        case COLOR_ACTIVE:
 455                reg |= LCD_TFT_MODE;
 456                if (cfg->tft_alt_mode)
 457                        reg |= LCD_TFT_ALT_ENABLE;
 458                break;
 459
 460        case COLOR_PASSIVE:
 461                /* AC bias applicable only for Pasive panels */
 462                lcd_cfg_ac_bias(cfg->ac_bias, cfg->ac_bias_intrpt);
 463                if (cfg->bpp == 12 && cfg->stn_565_mode)
 464                        reg |= LCD_STN_565_ENABLE;
 465                break;
 466
 467        default:
 468                return -EINVAL;
 469        }
 470
 471        /* enable additional interrupts here */
 472        if (lcd_revision == LCD_VERSION_1) {
 473                reg |= LCD_V1_UNDERFLOW_INT_ENA;
 474        } else {
 475                reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) |
 476                        LCD_V2_UNDERFLOW_INT_ENA;
 477                lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG);
 478        }
 479
 480        lcdc_write(reg, LCD_RASTER_CTRL_REG);
 481
 482        reg = lcdc_read(LCD_RASTER_TIMING_2_REG);
 483
 484        reg |= LCD_SYNC_CTRL;
 485
 486        if (cfg->sync_edge)
 487                reg |= LCD_SYNC_EDGE;
 488        else
 489                reg &= ~LCD_SYNC_EDGE;
 490
 491        if (panel->sync & FB_SYNC_HOR_HIGH_ACT)
 492                reg |= LCD_INVERT_LINE_CLOCK;
 493        else
 494                reg &= ~LCD_INVERT_LINE_CLOCK;
 495
 496        if (panel->sync & FB_SYNC_VERT_HIGH_ACT)
 497                reg |= LCD_INVERT_FRAME_CLOCK;
 498        else
 499                reg &= ~LCD_INVERT_FRAME_CLOCK;
 500
 501        lcdc_write(reg, LCD_RASTER_TIMING_2_REG);
 502
 503        return 0;
 504}
 505
 506static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
 507                u32 bpp, u32 raster_order)
 508{
 509        u32 reg;
 510
 511        if (bpp > 16 && lcd_revision == LCD_VERSION_1)
 512                return -EINVAL;
 513
 514        /* Set the Panel Width */
 515        /* Pixels per line = (PPL + 1)*16 */
 516        if (lcd_revision == LCD_VERSION_1) {
 517                /*
 518                 * 0x3F in bits 4..9 gives max horizontal resolution = 1024
 519                 * pixels.
 520                 */
 521                width &= 0x3f0;
 522        } else {
 523                /*
 524                 * 0x7F in bits 4..10 gives max horizontal resolution = 2048
 525                 * pixels.
 526                 */
 527                width &= 0x7f0;
 528        }
 529
 530        reg = lcdc_read(LCD_RASTER_TIMING_0_REG);
 531        reg &= 0xfffffc00;
 532        if (lcd_revision == LCD_VERSION_1) {
 533                reg |= ((width >> 4) - 1) << 4;
 534        } else {
 535                width = (width >> 4) - 1;
 536                reg |= ((width & 0x3f) << 4) | ((width & 0x40) >> 3);
 537        }
 538        lcdc_write(reg, LCD_RASTER_TIMING_0_REG);
 539
 540        /* Set the Panel Height */
 541        /* Set bits 9:0 of Lines Per Pixel */
 542        reg = lcdc_read(LCD_RASTER_TIMING_1_REG);
 543        reg = ((height - 1) & 0x3ff) | (reg & 0xfffffc00);
 544        lcdc_write(reg, LCD_RASTER_TIMING_1_REG);
 545
 546        /* Set bit 10 of Lines Per Pixel */
 547        if (lcd_revision == LCD_VERSION_2) {
 548                reg = lcdc_read(LCD_RASTER_TIMING_2_REG);
 549                reg |= ((height - 1) & 0x400) << 16;
 550                lcdc_write(reg, LCD_RASTER_TIMING_2_REG);
 551        }
 552
 553        /* Set the Raster Order of the Frame Buffer */
 554        reg = lcdc_read(LCD_RASTER_CTRL_REG) & ~(1 << 8);
 555        if (raster_order)
 556                reg |= LCD_RASTER_ORDER;
 557
 558        par->palette_sz = 16 * 2;
 559
 560        switch (bpp) {
 561        case 1:
 562        case 2:
 563        case 4:
 564        case 16:
 565                break;
 566        case 24:
 567                reg |= LCD_V2_TFT_24BPP_MODE;
 568        case 32:
 569                reg |= LCD_V2_TFT_24BPP_UNPACK;
 570                break;
 571
 572        case 8:
 573                par->palette_sz = 256 * 2;
 574                break;
 575
 576        default:
 577                return -EINVAL;
 578        }
 579
 580        lcdc_write(reg, LCD_RASTER_CTRL_REG);
 581
 582        return 0;
 583}
 584
 585#define CNVT_TOHW(val, width) ((((val) << (width)) + 0x7FFF - (val)) >> 16)
 586static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
 587                              unsigned blue, unsigned transp,
 588                              struct fb_info *info)
 589{
 590        struct da8xx_fb_par *par = info->par;
 591        unsigned short *palette = (unsigned short *) par->v_palette_base;
 592        u_short pal;
 593        int update_hw = 0;
 594
 595        if (regno > 255)
 596                return 1;
 597
 598        if (info->fix.visual == FB_VISUAL_DIRECTCOLOR)
 599                return 1;
 600
 601        if (info->var.bits_per_pixel > 16 && lcd_revision == LCD_VERSION_1)
 602                return -EINVAL;
 603
 604        switch (info->fix.visual) {
 605        case FB_VISUAL_TRUECOLOR:
 606                red = CNVT_TOHW(red, info->var.red.length);
 607                green = CNVT_TOHW(green, info->var.green.length);
 608                blue = CNVT_TOHW(blue, info->var.blue.length);
 609                break;
 610        case FB_VISUAL_PSEUDOCOLOR:
 611                switch (info->var.bits_per_pixel) {
 612                case 4:
 613                        if (regno > 15)
 614                                return -EINVAL;
 615
 616                        if (info->var.grayscale) {
 617                                pal = regno;
 618                        } else {
 619                                red >>= 4;
 620                                green >>= 8;
 621                                blue >>= 12;
 622
 623                                pal = red & 0x0f00;
 624                                pal |= green & 0x00f0;
 625                                pal |= blue & 0x000f;
 626                        }
 627                        if (regno == 0)
 628                                pal |= 0x2000;
 629                        palette[regno] = pal;
 630                        break;
 631
 632                case 8:
 633                        red >>= 4;
 634                        green >>= 8;
 635                        blue >>= 12;
 636
 637                        pal = (red & 0x0f00);
 638                        pal |= (green & 0x00f0);
 639                        pal |= (blue & 0x000f);
 640
 641                        if (palette[regno] != pal) {
 642                                update_hw = 1;
 643                                palette[regno] = pal;
 644                        }
 645                        break;
 646                }
 647                break;
 648        }
 649
 650        /* Truecolor has hardware independent palette */
 651        if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
 652                u32 v;
 653
 654                if (regno > 15)
 655                        return -EINVAL;
 656
 657                v = (red << info->var.red.offset) |
 658                        (green << info->var.green.offset) |
 659                        (blue << info->var.blue.offset);
 660
 661                switch (info->var.bits_per_pixel) {
 662                case 16:
 663                        ((u16 *) (info->pseudo_palette))[regno] = v;
 664                        break;
 665                case 24:
 666                case 32:
 667                        ((u32 *) (info->pseudo_palette))[regno] = v;
 668                        break;
 669                }
 670                if (palette[0] != 0x4000) {
 671                        update_hw = 1;
 672                        palette[0] = 0x4000;
 673                }
 674        }
 675
 676        /* Update the palette in the h/w as needed. */
 677        if (update_hw)
 678                lcd_blit(LOAD_PALETTE, par);
 679
 680        return 0;
 681}
 682#undef CNVT_TOHW
 683
 684static void lcd_reset(struct da8xx_fb_par *par)
 685{
 686        /* Disable the Raster if previously Enabled */
 687        lcd_disable_raster(false);
 688
 689        /* DMA has to be disabled */
 690        lcdc_write(0, LCD_DMA_CTRL_REG);
 691        lcdc_write(0, LCD_RASTER_CTRL_REG);
 692
 693        if (lcd_revision == LCD_VERSION_2) {
 694                lcdc_write(0, LCD_INT_ENABLE_SET_REG);
 695                /* Write 1 to reset */
 696                lcdc_write(LCD_CLK_MAIN_RESET, LCD_CLK_RESET_REG);
 697                lcdc_write(0, LCD_CLK_RESET_REG);
 698        }
 699}
 700
 701static void lcd_calc_clk_divider(struct da8xx_fb_par *par)
 702{
 703        unsigned int lcd_clk, div;
 704
 705        lcd_clk = clk_get_rate(par->lcdc_clk);
 706        div = lcd_clk / par->pxl_clk;
 707
 708        /* Configure the LCD clock divisor. */
 709        lcdc_write(LCD_CLK_DIVISOR(div) |
 710                        (LCD_RASTER_MODE & 0x1), LCD_CTRL_REG);
 711
 712        if (lcd_revision == LCD_VERSION_2)
 713                lcdc_write(LCD_V2_DMA_CLK_EN | LCD_V2_LIDD_CLK_EN |
 714                                LCD_V2_CORE_CLK_EN, LCD_CLK_ENABLE_REG);
 715
 716}
 717
 718static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
 719                struct fb_videomode *panel)
 720{
 721        u32 bpp;
 722        int ret = 0;
 723
 724        lcd_reset(par);
 725
 726        /* Calculate the divider */
 727        lcd_calc_clk_divider(par);
 728
 729        if (panel->sync & FB_SYNC_CLK_INVERT)
 730                lcdc_write((lcdc_read(LCD_RASTER_TIMING_2_REG) |
 731                        LCD_INVERT_PIXEL_CLOCK), LCD_RASTER_TIMING_2_REG);
 732        else
 733                lcdc_write((lcdc_read(LCD_RASTER_TIMING_2_REG) &
 734                        ~LCD_INVERT_PIXEL_CLOCK), LCD_RASTER_TIMING_2_REG);
 735
 736        /* Configure the DMA burst size and fifo threshold. */
 737        ret = lcd_cfg_dma(cfg->dma_burst_sz, cfg->fifo_th);
 738        if (ret < 0)
 739                return ret;
 740
 741        /* Configure the vertical and horizontal sync properties. */
 742        lcd_cfg_vertical_sync(panel->lower_margin, panel->vsync_len,
 743                        panel->upper_margin);
 744        lcd_cfg_horizontal_sync(panel->right_margin, panel->hsync_len,
 745                        panel->left_margin);
 746
 747        /* Configure for disply */
 748        ret = lcd_cfg_display(cfg, panel);
 749        if (ret < 0)
 750                return ret;
 751
 752        bpp = cfg->bpp;
 753
 754        if (bpp == 12)
 755                bpp = 16;
 756        ret = lcd_cfg_frame_buffer(par, (unsigned int)panel->xres,
 757                                (unsigned int)panel->yres, bpp,
 758                                cfg->raster_order);
 759        if (ret < 0)
 760                return ret;
 761
 762        /* Configure FDD */
 763        lcdc_write((lcdc_read(LCD_RASTER_CTRL_REG) & 0xfff00fff) |
 764                       (cfg->fdd << 12), LCD_RASTER_CTRL_REG);
 765
 766        return 0;
 767}
 768
 769/* IRQ handler for version 2 of LCDC */
 770static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg)
 771{
 772        struct da8xx_fb_par *par = arg;
 773        u32 stat = lcdc_read(LCD_MASKED_STAT_REG);
 774
 775        if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {
 776                lcd_disable_raster(false);
 777                lcdc_write(stat, LCD_MASKED_STAT_REG);
 778                lcd_enable_raster();
 779        } else if (stat & LCD_PL_LOAD_DONE) {
 780                /*
 781                 * Must disable raster before changing state of any control bit.
 782                 * And also must be disabled before clearing the PL loading
 783                 * interrupt via the following write to the status register. If
 784                 * this is done after then one gets multiple PL done interrupts.
 785                 */
 786                lcd_disable_raster(false);
 787
 788                lcdc_write(stat, LCD_MASKED_STAT_REG);
 789
 790                /* Disable PL completion interrupt */
 791                lcdc_write(LCD_V2_PL_INT_ENA, LCD_INT_ENABLE_CLR_REG);
 792
 793                /* Setup and start data loading mode */
 794                lcd_blit(LOAD_DATA, par);
 795        } else {
 796                lcdc_write(stat, LCD_MASKED_STAT_REG);
 797
 798                if (stat & LCD_END_OF_FRAME0) {
 799                        par->which_dma_channel_done = 0;
 800                        lcdc_write(par->dma_start,
 801                                   LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
 802                        lcdc_write(par->dma_end,
 803                                   LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
 804                        par->vsync_flag = 1;
 805                        wake_up_interruptible(&par->vsync_wait);
 806                }
 807
 808                if (stat & LCD_END_OF_FRAME1) {
 809                        par->which_dma_channel_done = 1;
 810                        lcdc_write(par->dma_start,
 811                                   LCD_DMA_FRM_BUF_BASE_ADDR_1_REG);
 812                        lcdc_write(par->dma_end,
 813                                   LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG);
 814                        par->vsync_flag = 1;
 815                        wake_up_interruptible(&par->vsync_wait);
 816                }
 817
 818                /* Set only when controller is disabled and at the end of
 819                 * active frame
 820                 */
 821                if (stat & BIT(0)) {
 822                        frame_done_flag = 1;
 823                        wake_up_interruptible(&frame_done_wq);
 824                }
 825        }
 826
 827        lcdc_write(0, LCD_END_OF_INT_IND_REG);
 828        return IRQ_HANDLED;
 829}
 830
 831/* IRQ handler for version 1 LCDC */
 832static irqreturn_t lcdc_irq_handler_rev01(int irq, void *arg)
 833{
 834        struct da8xx_fb_par *par = arg;
 835        u32 stat = lcdc_read(LCD_STAT_REG);
 836        u32 reg_ras;
 837
 838        if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {
 839                lcd_disable_raster(false);
 840                lcdc_write(stat, LCD_STAT_REG);
 841                lcd_enable_raster();
 842        } else if (stat & LCD_PL_LOAD_DONE) {
 843                /*
 844                 * Must disable raster before changing state of any control bit.
 845                 * And also must be disabled before clearing the PL loading
 846                 * interrupt via the following write to the status register. If
 847                 * this is done after then one gets multiple PL done interrupts.
 848                 */
 849                lcd_disable_raster(false);
 850
 851                lcdc_write(stat, LCD_STAT_REG);
 852
 853                /* Disable PL completion inerrupt */
 854                reg_ras  = lcdc_read(LCD_RASTER_CTRL_REG);
 855                reg_ras &= ~LCD_V1_PL_INT_ENA;
 856                lcdc_write(reg_ras, LCD_RASTER_CTRL_REG);
 857
 858                /* Setup and start data loading mode */
 859                lcd_blit(LOAD_DATA, par);
 860        } else {
 861                lcdc_write(stat, LCD_STAT_REG);
 862
 863                if (stat & LCD_END_OF_FRAME0) {
 864                        par->which_dma_channel_done = 0;
 865                        lcdc_write(par->dma_start,
 866                                   LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
 867                        lcdc_write(par->dma_end,
 868                                   LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
 869                        par->vsync_flag = 1;
 870                        wake_up_interruptible(&par->vsync_wait);
 871                }
 872
 873                if (stat & LCD_END_OF_FRAME1) {
 874                        par->which_dma_channel_done = 1;
 875                        lcdc_write(par->dma_start,
 876                                   LCD_DMA_FRM_BUF_BASE_ADDR_1_REG);
 877                        lcdc_write(par->dma_end,
 878                                   LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG);
 879                        par->vsync_flag = 1;
 880                        wake_up_interruptible(&par->vsync_wait);
 881                }
 882        }
 883
 884        return IRQ_HANDLED;
 885}
 886
 887static int fb_check_var(struct fb_var_screeninfo *var,
 888                        struct fb_info *info)
 889{
 890        int err = 0;
 891
 892        if (var->bits_per_pixel > 16 && lcd_revision == LCD_VERSION_1)
 893                return -EINVAL;
 894
 895        switch (var->bits_per_pixel) {
 896        case 1:
 897        case 8:
 898                var->red.offset = 0;
 899                var->red.length = 8;
 900                var->green.offset = 0;
 901                var->green.length = 8;
 902                var->blue.offset = 0;
 903                var->blue.length = 8;
 904                var->transp.offset = 0;
 905                var->transp.length = 0;
 906                var->nonstd = 0;
 907                break;
 908        case 4:
 909                var->red.offset = 0;
 910                var->red.length = 4;
 911                var->green.offset = 0;
 912                var->green.length = 4;
 913                var->blue.offset = 0;
 914                var->blue.length = 4;
 915                var->transp.offset = 0;
 916                var->transp.length = 0;
 917                var->nonstd = FB_NONSTD_REV_PIX_IN_B;
 918                break;
 919        case 16:                /* RGB 565 */
 920                var->red.offset = 11;
 921                var->red.length = 5;
 922                var->green.offset = 5;
 923                var->green.length = 6;
 924                var->blue.offset = 0;
 925                var->blue.length = 5;
 926                var->transp.offset = 0;
 927                var->transp.length = 0;
 928                var->nonstd = 0;
 929                break;
 930        case 24:
 931                var->red.offset = 16;
 932                var->red.length = 8;
 933                var->green.offset = 8;
 934                var->green.length = 8;
 935                var->blue.offset = 0;
 936                var->blue.length = 8;
 937                var->nonstd = 0;
 938                break;
 939        case 32:
 940                var->transp.offset = 24;
 941                var->transp.length = 8;
 942                var->red.offset = 16;
 943                var->red.length = 8;
 944                var->green.offset = 8;
 945                var->green.length = 8;
 946                var->blue.offset = 0;
 947                var->blue.length = 8;
 948                var->nonstd = 0;
 949                break;
 950        default:
 951                err = -EINVAL;
 952        }
 953
 954        var->red.msb_right = 0;
 955        var->green.msb_right = 0;
 956        var->blue.msb_right = 0;
 957        var->transp.msb_right = 0;
 958        return err;
 959}
 960
 961#ifdef CONFIG_CPU_FREQ
 962static int lcd_da8xx_cpufreq_transition(struct notifier_block *nb,
 963                                     unsigned long val, void *data)
 964{
 965        struct da8xx_fb_par *par;
 966
 967        par = container_of(nb, struct da8xx_fb_par, freq_transition);
 968        if (val == CPUFREQ_POSTCHANGE) {
 969                if (par->lcd_fck_rate != clk_get_rate(par->lcdc_clk)) {
 970                        par->lcd_fck_rate = clk_get_rate(par->lcdc_clk);
 971                        lcd_disable_raster(true);
 972                        lcd_calc_clk_divider(par);
 973                        if (par->blank == FB_BLANK_UNBLANK)
 974                                lcd_enable_raster();
 975                }
 976        }
 977
 978        return 0;
 979}
 980
 981static inline int lcd_da8xx_cpufreq_register(struct da8xx_fb_par *par)
 982{
 983        par->freq_transition.notifier_call = lcd_da8xx_cpufreq_transition;
 984
 985        return cpufreq_register_notifier(&par->freq_transition,
 986                                         CPUFREQ_TRANSITION_NOTIFIER);
 987}
 988
 989static inline void lcd_da8xx_cpufreq_deregister(struct da8xx_fb_par *par)
 990{
 991        cpufreq_unregister_notifier(&par->freq_transition,
 992                                    CPUFREQ_TRANSITION_NOTIFIER);
 993}
 994#endif
 995
 996static int fb_remove(struct platform_device *dev)
 997{
 998        struct fb_info *info = dev_get_drvdata(&dev->dev);
 999
1000        if (info) {
1001                struct da8xx_fb_par *par = info->par;
1002
1003#ifdef CONFIG_CPU_FREQ
1004                lcd_da8xx_cpufreq_deregister(par);
1005#endif
1006                if (par->panel_power_ctrl)
1007                        par->panel_power_ctrl(0);
1008
1009                lcd_disable_raster(true);
1010                lcdc_write(0, LCD_RASTER_CTRL_REG);
1011
1012                /* disable DMA  */
1013                lcdc_write(0, LCD_DMA_CTRL_REG);
1014
1015                unregister_framebuffer(info);
1016                fb_dealloc_cmap(&info->cmap);
1017                dma_free_coherent(NULL, PALETTE_SIZE, par->v_palette_base,
1018                                  par->p_palette_base);
1019                dma_free_coherent(NULL, par->vram_size, par->vram_virt,
1020                                  par->vram_phys);
1021                free_irq(par->irq, par);
1022                pm_runtime_put_sync(&dev->dev);
1023                pm_runtime_disable(&dev->dev);
1024                framebuffer_release(info);
1025                iounmap(da8xx_fb_reg_base);
1026                release_mem_region(lcdc_regs->start, resource_size(lcdc_regs));
1027
1028        }
1029        return 0;
1030}
1031
1032/*
1033 * Function to wait for vertical sync which for this LCD peripheral
1034 * translates into waiting for the current raster frame to complete.
1035 */
1036static int fb_wait_for_vsync(struct fb_info *info)
1037{
1038        struct da8xx_fb_par *par = info->par;
1039        int ret;
1040
1041        /*
1042         * Set flag to 0 and wait for isr to set to 1. It would seem there is a
1043         * race condition here where the ISR could have occurred just before or
1044         * just after this set. But since we are just coarsely waiting for
1045         * a frame to complete then that's OK. i.e. if the frame completed
1046         * just before this code executed then we have to wait another full
1047         * frame time but there is no way to avoid such a situation. On the
1048         * other hand if the frame completed just after then we don't need
1049         * to wait long at all. Either way we are guaranteed to return to the
1050         * user immediately after a frame completion which is all that is
1051         * required.
1052         */
1053        par->vsync_flag = 0;
1054        ret = wait_event_interruptible_timeout(par->vsync_wait,
1055                                               par->vsync_flag != 0,
1056                                               par->vsync_timeout);
1057        if (ret < 0)
1058                return ret;
1059        if (ret == 0)
1060                return -ETIMEDOUT;
1061
1062        return 0;
1063}
1064
1065static int fb_ioctl(struct fb_info *info, unsigned int cmd,
1066                          unsigned long arg)
1067{
1068        struct lcd_sync_arg sync_arg;
1069
1070        switch (cmd) {
1071        case FBIOGET_CONTRAST:
1072        case FBIOPUT_CONTRAST:
1073        case FBIGET_BRIGHTNESS:
1074        case FBIPUT_BRIGHTNESS:
1075        case FBIGET_COLOR:
1076        case FBIPUT_COLOR:
1077                return -ENOTTY;
1078        case FBIPUT_HSYNC:
1079                if (copy_from_user(&sync_arg, (char *)arg,
1080                                sizeof(struct lcd_sync_arg)))
1081                        return -EFAULT;
1082                lcd_cfg_horizontal_sync(sync_arg.back_porch,
1083                                        sync_arg.pulse_width,
1084                                        sync_arg.front_porch);
1085                break;
1086        case FBIPUT_VSYNC:
1087                if (copy_from_user(&sync_arg, (char *)arg,
1088                                sizeof(struct lcd_sync_arg)))
1089                        return -EFAULT;
1090                lcd_cfg_vertical_sync(sync_arg.back_porch,
1091                                        sync_arg.pulse_width,
1092                                        sync_arg.front_porch);
1093                break;
1094        case FBIO_WAITFORVSYNC:
1095                return fb_wait_for_vsync(info);
1096        default:
1097                return -EINVAL;
1098        }
1099        return 0;
1100}
1101
1102static int cfb_blank(int blank, struct fb_info *info)
1103{
1104        struct da8xx_fb_par *par = info->par;
1105        int ret = 0;
1106
1107        if (par->blank == blank)
1108                return 0;
1109
1110        par->blank = blank;
1111        switch (blank) {
1112        case FB_BLANK_UNBLANK:
1113                lcd_enable_raster();
1114
1115                if (par->panel_power_ctrl)
1116                        par->panel_power_ctrl(1);
1117                break;
1118        case FB_BLANK_NORMAL:
1119        case FB_BLANK_VSYNC_SUSPEND:
1120        case FB_BLANK_HSYNC_SUSPEND:
1121        case FB_BLANK_POWERDOWN:
1122                if (par->panel_power_ctrl)
1123                        par->panel_power_ctrl(0);
1124
1125                lcd_disable_raster(true);
1126                break;
1127        default:
1128                ret = -EINVAL;
1129        }
1130
1131        return ret;
1132}
1133
1134/*
1135 * Set new x,y offsets in the virtual display for the visible area and switch
1136 * to the new mode.
1137 */
1138static int da8xx_pan_display(struct fb_var_screeninfo *var,
1139                             struct fb_info *fbi)
1140{
1141        int ret = 0;
1142        struct fb_var_screeninfo new_var;
1143        struct da8xx_fb_par         *par = fbi->par;
1144        struct fb_fix_screeninfo    *fix = &fbi->fix;
1145        unsigned int end;
1146        unsigned int start;
1147        unsigned long irq_flags;
1148
1149        if (var->xoffset != fbi->var.xoffset ||
1150                        var->yoffset != fbi->var.yoffset) {
1151                memcpy(&new_var, &fbi->var, sizeof(new_var));
1152                new_var.xoffset = var->xoffset;
1153                new_var.yoffset = var->yoffset;
1154                if (fb_check_var(&new_var, fbi))
1155                        ret = -EINVAL;
1156                else {
1157                        memcpy(&fbi->var, &new_var, sizeof(new_var));
1158
1159                        start   = fix->smem_start +
1160                                new_var.yoffset * fix->line_length +
1161                                new_var.xoffset * fbi->var.bits_per_pixel / 8;
1162                        end     = start + fbi->var.yres * fix->line_length - 1;
1163                        par->dma_start  = start;
1164                        par->dma_end    = end;
1165                        spin_lock_irqsave(&par->lock_for_chan_update,
1166                                        irq_flags);
1167                        if (par->which_dma_channel_done == 0) {
1168                                lcdc_write(par->dma_start,
1169                                           LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
1170                                lcdc_write(par->dma_end,
1171                                           LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
1172                        } else if (par->which_dma_channel_done == 1) {
1173                                lcdc_write(par->dma_start,
1174                                           LCD_DMA_FRM_BUF_BASE_ADDR_1_REG);
1175                                lcdc_write(par->dma_end,
1176                                           LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG);
1177                        }
1178                        spin_unlock_irqrestore(&par->lock_for_chan_update,
1179                                        irq_flags);
1180                }
1181        }
1182
1183        return ret;
1184}
1185
1186static struct fb_ops da8xx_fb_ops = {
1187        .owner = THIS_MODULE,
1188        .fb_check_var = fb_check_var,
1189        .fb_setcolreg = fb_setcolreg,
1190        .fb_pan_display = da8xx_pan_display,
1191        .fb_ioctl = fb_ioctl,
1192        .fb_fillrect = cfb_fillrect,
1193        .fb_copyarea = cfb_copyarea,
1194        .fb_imageblit = cfb_imageblit,
1195        .fb_blank = cfb_blank,
1196};
1197
1198/* Calculate and return pixel clock period in pico seconds */
1199static unsigned int da8xxfb_pixel_clk_period(struct da8xx_fb_par *par)
1200{
1201        unsigned int lcd_clk, div;
1202        unsigned int configured_pix_clk;
1203        unsigned long long pix_clk_period_picosec = 1000000000000ULL;
1204
1205        lcd_clk = clk_get_rate(par->lcdc_clk);
1206        div = lcd_clk / par->pxl_clk;
1207        configured_pix_clk = (lcd_clk / div);
1208
1209        do_div(pix_clk_period_picosec, configured_pix_clk);
1210
1211        return pix_clk_period_picosec;
1212}
1213
1214static int fb_probe(struct platform_device *device)
1215{
1216        struct da8xx_lcdc_platform_data *fb_pdata =
1217                                                device->dev.platform_data;
1218        struct lcd_ctrl_config *lcd_cfg;
1219        struct fb_videomode *lcdc_info;
1220        struct fb_info *da8xx_fb_info;
1221        struct clk *fb_clk = NULL;
1222        struct da8xx_fb_par *par;
1223        resource_size_t len;
1224        int ret, i;
1225        unsigned long ulcm;
1226
1227        if (fb_pdata == NULL) {
1228                dev_err(&device->dev, "Can not get platform data\n");
1229                return -ENOENT;
1230        }
1231
1232        lcdc_regs = platform_get_resource(device, IORESOURCE_MEM, 0);
1233        if (!lcdc_regs) {
1234                dev_err(&device->dev,
1235                        "Can not get memory resource for LCD controller\n");
1236                return -ENOENT;
1237        }
1238
1239        len = resource_size(lcdc_regs);
1240
1241        lcdc_regs = request_mem_region(lcdc_regs->start, len, lcdc_regs->name);
1242        if (!lcdc_regs)
1243                return -EBUSY;
1244
1245        da8xx_fb_reg_base = ioremap(lcdc_regs->start, len);
1246        if (!da8xx_fb_reg_base) {
1247                ret = -EBUSY;
1248                goto err_request_mem;
1249        }
1250
1251        fb_clk = clk_get(&device->dev, "fck");
1252        if (IS_ERR(fb_clk)) {
1253                dev_err(&device->dev, "Can not get device clock\n");
1254                ret = -ENODEV;
1255                goto err_ioremap;
1256        }
1257
1258        pm_runtime_enable(&device->dev);
1259        pm_runtime_get_sync(&device->dev);
1260
1261        /* Determine LCD IP Version */
1262        switch (lcdc_read(LCD_PID_REG)) {
1263        case 0x4C100102:
1264                lcd_revision = LCD_VERSION_1;
1265                break;
1266        case 0x4F200800:
1267        case 0x4F201000:
1268                lcd_revision = LCD_VERSION_2;
1269                break;
1270        default:
1271                dev_warn(&device->dev, "Unknown PID Reg value 0x%x, "
1272                                "defaulting to LCD revision 1\n",
1273                                lcdc_read(LCD_PID_REG));
1274                lcd_revision = LCD_VERSION_1;
1275                break;
1276        }
1277
1278        for (i = 0, lcdc_info = known_lcd_panels;
1279                i < ARRAY_SIZE(known_lcd_panels);
1280                i++, lcdc_info++) {
1281                if (strcmp(fb_pdata->type, lcdc_info->name) == 0)
1282                        break;
1283        }
1284
1285        if (i == ARRAY_SIZE(known_lcd_panels)) {
1286                dev_err(&device->dev, "GLCD: No valid panel found\n");
1287                ret = -ENODEV;
1288                goto err_pm_runtime_disable;
1289        } else
1290                dev_info(&device->dev, "GLCD: Found %s panel\n",
1291                                        fb_pdata->type);
1292
1293        lcd_cfg = (struct lcd_ctrl_config *)fb_pdata->controller_data;
1294
1295        da8xx_fb_info = framebuffer_alloc(sizeof(struct da8xx_fb_par),
1296                                        &device->dev);
1297        if (!da8xx_fb_info) {
1298                dev_dbg(&device->dev, "Memory allocation failed for fb_info\n");
1299                ret = -ENOMEM;
1300                goto err_pm_runtime_disable;
1301        }
1302
1303        par = da8xx_fb_info->par;
1304        par->lcdc_clk = fb_clk;
1305#ifdef CONFIG_CPU_FREQ
1306        par->lcd_fck_rate = clk_get_rate(fb_clk);
1307#endif
1308        par->pxl_clk = lcdc_info->pixclock;
1309        if (fb_pdata->panel_power_ctrl) {
1310                par->panel_power_ctrl = fb_pdata->panel_power_ctrl;
1311                par->panel_power_ctrl(1);
1312        }
1313
1314        if (lcd_init(par, lcd_cfg, lcdc_info) < 0) {
1315                dev_err(&device->dev, "lcd_init failed\n");
1316                ret = -EFAULT;
1317                goto err_release_fb;
1318        }
1319
1320        /* allocate frame buffer */
1321        par->vram_size = lcdc_info->xres * lcdc_info->yres * lcd_cfg->bpp;
1322        ulcm = lcm((lcdc_info->xres * lcd_cfg->bpp)/8, PAGE_SIZE);
1323        par->vram_size = roundup(par->vram_size/8, ulcm);
1324        par->vram_size = par->vram_size * LCD_NUM_BUFFERS;
1325
1326        par->vram_virt = dma_alloc_coherent(NULL,
1327                                            par->vram_size,
1328                                            (resource_size_t *) &par->vram_phys,
1329                                            GFP_KERNEL | GFP_DMA);
1330        if (!par->vram_virt) {
1331                dev_err(&device->dev,
1332                        "GLCD: kmalloc for frame buffer failed\n");
1333                ret = -EINVAL;
1334                goto err_release_fb;
1335        }
1336
1337        da8xx_fb_info->screen_base = (char __iomem *) par->vram_virt;
1338        da8xx_fb_fix.smem_start    = par->vram_phys;
1339        da8xx_fb_fix.smem_len      = par->vram_size;
1340        da8xx_fb_fix.line_length   = (lcdc_info->xres * lcd_cfg->bpp) / 8;
1341
1342        par->dma_start = par->vram_phys;
1343        par->dma_end   = par->dma_start + lcdc_info->yres *
1344                da8xx_fb_fix.line_length - 1;
1345
1346        /* allocate palette buffer */
1347        par->v_palette_base = dma_alloc_coherent(NULL,
1348                                               PALETTE_SIZE,
1349                                               (resource_size_t *)
1350                                               &par->p_palette_base,
1351                                               GFP_KERNEL | GFP_DMA);
1352        if (!par->v_palette_base) {
1353                dev_err(&device->dev,
1354                        "GLCD: kmalloc for palette buffer failed\n");
1355                ret = -EINVAL;
1356                goto err_release_fb_mem;
1357        }
1358        memset(par->v_palette_base, 0, PALETTE_SIZE);
1359
1360        par->irq = platform_get_irq(device, 0);
1361        if (par->irq < 0) {
1362                ret = -ENOENT;
1363                goto err_release_pl_mem;
1364        }
1365
1366        /* Initialize par */
1367        da8xx_fb_info->var.bits_per_pixel = lcd_cfg->bpp;
1368
1369        da8xx_fb_var.xres = lcdc_info->xres;
1370        da8xx_fb_var.xres_virtual = lcdc_info->xres;
1371
1372        da8xx_fb_var.yres         = lcdc_info->yres;
1373        da8xx_fb_var.yres_virtual = lcdc_info->yres * LCD_NUM_BUFFERS;
1374
1375        da8xx_fb_var.grayscale =
1376            lcd_cfg->panel_shade == MONOCHROME ? 1 : 0;
1377        da8xx_fb_var.bits_per_pixel = lcd_cfg->bpp;
1378
1379        da8xx_fb_var.hsync_len = lcdc_info->hsync_len;
1380        da8xx_fb_var.vsync_len = lcdc_info->vsync_len;
1381        da8xx_fb_var.right_margin = lcdc_info->right_margin;
1382        da8xx_fb_var.left_margin  = lcdc_info->left_margin;
1383        da8xx_fb_var.lower_margin = lcdc_info->lower_margin;
1384        da8xx_fb_var.upper_margin = lcdc_info->upper_margin;
1385        da8xx_fb_var.pixclock = da8xxfb_pixel_clk_period(par);
1386
1387        /* Initialize fbinfo */
1388        da8xx_fb_info->flags = FBINFO_FLAG_DEFAULT;
1389        da8xx_fb_info->fix = da8xx_fb_fix;
1390        da8xx_fb_info->var = da8xx_fb_var;
1391        da8xx_fb_info->fbops = &da8xx_fb_ops;
1392        da8xx_fb_info->pseudo_palette = par->pseudo_palette;
1393        da8xx_fb_info->fix.visual = (da8xx_fb_info->var.bits_per_pixel <= 8) ?
1394                                FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
1395
1396        ret = fb_alloc_cmap(&da8xx_fb_info->cmap, PALETTE_SIZE, 0);
1397        if (ret)
1398                goto err_release_pl_mem;
1399        da8xx_fb_info->cmap.len = par->palette_sz;
1400
1401        /* initialize var_screeninfo */
1402        da8xx_fb_var.activate = FB_ACTIVATE_FORCE;
1403        fb_set_var(da8xx_fb_info, &da8xx_fb_var);
1404
1405        dev_set_drvdata(&device->dev, da8xx_fb_info);
1406
1407        /* initialize the vsync wait queue */
1408        init_waitqueue_head(&par->vsync_wait);
1409        par->vsync_timeout = HZ / 5;
1410        par->which_dma_channel_done = -1;
1411        spin_lock_init(&par->lock_for_chan_update);
1412
1413        /* Register the Frame Buffer  */
1414        if (register_framebuffer(da8xx_fb_info) < 0) {
1415                dev_err(&device->dev,
1416                        "GLCD: Frame Buffer Registration Failed!\n");
1417                ret = -EINVAL;
1418                goto err_dealloc_cmap;
1419        }
1420
1421#ifdef CONFIG_CPU_FREQ
1422        ret = lcd_da8xx_cpufreq_register(par);
1423        if (ret) {
1424                dev_err(&device->dev, "failed to register cpufreq\n");
1425                goto err_cpu_freq;
1426        }
1427#endif
1428
1429        if (lcd_revision == LCD_VERSION_1)
1430                lcdc_irq_handler = lcdc_irq_handler_rev01;
1431        else {
1432                init_waitqueue_head(&frame_done_wq);
1433                lcdc_irq_handler = lcdc_irq_handler_rev02;
1434        }
1435
1436        ret = request_irq(par->irq, lcdc_irq_handler, 0,
1437                        DRIVER_NAME, par);
1438        if (ret)
1439                goto irq_freq;
1440        return 0;
1441
1442irq_freq:
1443#ifdef CONFIG_CPU_FREQ
1444        lcd_da8xx_cpufreq_deregister(par);
1445err_cpu_freq:
1446#endif
1447        unregister_framebuffer(da8xx_fb_info);
1448
1449err_dealloc_cmap:
1450        fb_dealloc_cmap(&da8xx_fb_info->cmap);
1451
1452err_release_pl_mem:
1453        dma_free_coherent(NULL, PALETTE_SIZE, par->v_palette_base,
1454                          par->p_palette_base);
1455
1456err_release_fb_mem:
1457        dma_free_coherent(NULL, par->vram_size, par->vram_virt, par->vram_phys);
1458
1459err_release_fb:
1460        framebuffer_release(da8xx_fb_info);
1461
1462err_pm_runtime_disable:
1463        pm_runtime_put_sync(&device->dev);
1464        pm_runtime_disable(&device->dev);
1465
1466err_ioremap:
1467        iounmap(da8xx_fb_reg_base);
1468
1469err_request_mem:
1470        release_mem_region(lcdc_regs->start, len);
1471
1472        return ret;
1473}
1474
1475#ifdef CONFIG_PM
1476struct lcdc_context {
1477        u32 clk_enable;
1478        u32 ctrl;
1479        u32 dma_ctrl;
1480        u32 raster_timing_0;
1481        u32 raster_timing_1;
1482        u32 raster_timing_2;
1483        u32 int_enable_set;
1484        u32 dma_frm_buf_base_addr_0;
1485        u32 dma_frm_buf_ceiling_addr_0;
1486        u32 dma_frm_buf_base_addr_1;
1487        u32 dma_frm_buf_ceiling_addr_1;
1488        u32 raster_ctrl;
1489} reg_context;
1490
1491static void lcd_context_save(void)
1492{
1493        if (lcd_revision == LCD_VERSION_2) {
1494                reg_context.clk_enable = lcdc_read(LCD_CLK_ENABLE_REG);
1495                reg_context.int_enable_set = lcdc_read(LCD_INT_ENABLE_SET_REG);
1496        }
1497
1498        reg_context.ctrl = lcdc_read(LCD_CTRL_REG);
1499        reg_context.dma_ctrl = lcdc_read(LCD_DMA_CTRL_REG);
1500        reg_context.raster_timing_0 = lcdc_read(LCD_RASTER_TIMING_0_REG);
1501        reg_context.raster_timing_1 = lcdc_read(LCD_RASTER_TIMING_1_REG);
1502        reg_context.raster_timing_2 = lcdc_read(LCD_RASTER_TIMING_2_REG);
1503        reg_context.dma_frm_buf_base_addr_0 =
1504                lcdc_read(LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
1505        reg_context.dma_frm_buf_ceiling_addr_0 =
1506                lcdc_read(LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
1507        reg_context.dma_frm_buf_base_addr_1 =
1508                lcdc_read(LCD_DMA_FRM_BUF_BASE_ADDR_1_REG);
1509        reg_context.dma_frm_buf_ceiling_addr_1 =
1510                lcdc_read(LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG);
1511        reg_context.raster_ctrl = lcdc_read(LCD_RASTER_CTRL_REG);
1512        return;
1513}
1514
1515static void lcd_context_restore(void)
1516{
1517        if (lcd_revision == LCD_VERSION_2) {
1518                lcdc_write(reg_context.clk_enable, LCD_CLK_ENABLE_REG);
1519                lcdc_write(reg_context.int_enable_set, LCD_INT_ENABLE_SET_REG);
1520        }
1521
1522        lcdc_write(reg_context.ctrl, LCD_CTRL_REG);
1523        lcdc_write(reg_context.dma_ctrl, LCD_DMA_CTRL_REG);
1524        lcdc_write(reg_context.raster_timing_0, LCD_RASTER_TIMING_0_REG);
1525        lcdc_write(reg_context.raster_timing_1, LCD_RASTER_TIMING_1_REG);
1526        lcdc_write(reg_context.raster_timing_2, LCD_RASTER_TIMING_2_REG);
1527        lcdc_write(reg_context.dma_frm_buf_base_addr_0,
1528                        LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
1529        lcdc_write(reg_context.dma_frm_buf_ceiling_addr_0,
1530                        LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
1531        lcdc_write(reg_context.dma_frm_buf_base_addr_1,
1532                        LCD_DMA_FRM_BUF_BASE_ADDR_1_REG);
1533        lcdc_write(reg_context.dma_frm_buf_ceiling_addr_1,
1534                        LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG);
1535        lcdc_write(reg_context.raster_ctrl, LCD_RASTER_CTRL_REG);
1536        return;
1537}
1538
1539static int fb_suspend(struct platform_device *dev, pm_message_t state)
1540{
1541        struct fb_info *info = platform_get_drvdata(dev);
1542        struct da8xx_fb_par *par = info->par;
1543
1544        console_lock();
1545        if (par->panel_power_ctrl)
1546                par->panel_power_ctrl(0);
1547
1548        fb_set_suspend(info, 1);
1549        lcd_disable_raster(true);
1550        lcd_context_save();
1551        pm_runtime_put_sync(&dev->dev);
1552        console_unlock();
1553
1554        return 0;
1555}
1556static int fb_resume(struct platform_device *dev)
1557{
1558        struct fb_info *info = platform_get_drvdata(dev);
1559        struct da8xx_fb_par *par = info->par;
1560
1561        console_lock();
1562        pm_runtime_get_sync(&dev->dev);
1563        lcd_context_restore();
1564        if (par->blank == FB_BLANK_UNBLANK) {
1565                lcd_enable_raster();
1566
1567                if (par->panel_power_ctrl)
1568                        par->panel_power_ctrl(1);
1569        }
1570
1571        fb_set_suspend(info, 0);
1572        console_unlock();
1573
1574        return 0;
1575}
1576#else
1577#define fb_suspend NULL
1578#define fb_resume NULL
1579#endif
1580
1581static struct platform_driver da8xx_fb_driver = {
1582        .probe = fb_probe,
1583        .remove = fb_remove,
1584        .suspend = fb_suspend,
1585        .resume = fb_resume,
1586        .driver = {
1587                   .name = DRIVER_NAME,
1588                   .owner = THIS_MODULE,
1589                   },
1590};
1591
1592static int __init da8xx_fb_init(void)
1593{
1594        return platform_driver_register(&da8xx_fb_driver);
1595}
1596
1597static void __exit da8xx_fb_cleanup(void)
1598{
1599        platform_driver_unregister(&da8xx_fb_driver);
1600}
1601
1602module_init(da8xx_fb_init);
1603module_exit(da8xx_fb_cleanup);
1604
1605MODULE_DESCRIPTION("Framebuffer driver for TI da8xx/omap-l1xx");
1606MODULE_AUTHOR("Texas Instruments");
1607MODULE_LICENSE("GPL");
1608
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.