linux/drivers/video/imxfb.c
<<
>>
Prefs
   1/*
   2 *  Freescale i.MX Frame Buffer device driver
   3 *
   4 *  Copyright (C) 2004 Sascha Hauer, Pengutronix
   5 *   Based on acornfb.c Copyright (C) Russell King.
   6 *
   7 * This file is subject to the terms and conditions of the GNU General Public
   8 * License.  See the file COPYING in the main directory of this archive for
   9 * more details.
  10 *
  11 * Please direct your questions and comments on this driver to the following
  12 * email address:
  13 *
  14 *      linux-arm-kernel@lists.arm.linux.org.uk
  15 */
  16
  17#include <linux/module.h>
  18#include <linux/kernel.h>
  19#include <linux/errno.h>
  20#include <linux/string.h>
  21#include <linux/interrupt.h>
  22#include <linux/slab.h>
  23#include <linux/mm.h>
  24#include <linux/fb.h>
  25#include <linux/delay.h>
  26#include <linux/init.h>
  27#include <linux/ioport.h>
  28#include <linux/cpufreq.h>
  29#include <linux/clk.h>
  30#include <linux/platform_device.h>
  31#include <linux/dma-mapping.h>
  32#include <linux/io.h>
  33#include <linux/math64.h>
  34
  35#include <mach/imxfb.h>
  36#include <mach/hardware.h>
  37
  38/*
  39 * Complain if VAR is out of range.
  40 */
  41#define DEBUG_VAR 1
  42
  43#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || \
  44        (defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE) && \
  45                defined(CONFIG_FB_IMX_MODULE))
  46#define PWMR_BACKLIGHT_AVAILABLE
  47#endif
  48
  49#define DRIVER_NAME "imx-fb"
  50
  51#define LCDC_SSA        0x00
  52
  53#define LCDC_SIZE       0x04
  54#define SIZE_XMAX(x)    ((((x) >> 4) & 0x3f) << 20)
  55
  56#define YMAX_MASK       (cpu_is_mx1() ? 0x1ff : 0x3ff)
  57#define SIZE_YMAX(y)    ((y) & YMAX_MASK)
  58
  59#define LCDC_VPW        0x08
  60#define VPW_VPW(x)      ((x) & 0x3ff)
  61
  62#define LCDC_CPOS       0x0C
  63#define CPOS_CC1        (1<<31)
  64#define CPOS_CC0        (1<<30)
  65#define CPOS_OP         (1<<28)
  66#define CPOS_CXP(x)     (((x) & 3ff) << 16)
  67
  68#ifdef CONFIG_ARCH_MX1
  69#define CPOS_CYP(y)     ((y) & 0x1ff)
  70#else
  71#define CPOS_CYP(y)     ((y) & 0x3ff)
  72#endif
  73
  74#define LCDC_LCWHB      0x10
  75#define LCWHB_BK_EN     (1<<31)
  76#define LCWHB_CW(w)     (((w) & 0x1f) << 24)
  77#define LCWHB_CH(h)     (((h) & 0x1f) << 16)
  78#define LCWHB_BD(x)     ((x) & 0xff)
  79
  80#define LCDC_LCHCC      0x14
  81
  82#ifdef CONFIG_ARCH_MX1
  83#define LCHCC_CUR_COL_R(r) (((r) & 0x1f) << 11)
  84#define LCHCC_CUR_COL_G(g) (((g) & 0x3f) << 5)
  85#define LCHCC_CUR_COL_B(b) ((b) & 0x1f)
  86#else
  87#define LCHCC_CUR_COL_R(r) (((r) & 0x3f) << 12)
  88#define LCHCC_CUR_COL_G(g) (((g) & 0x3f) << 6)
  89#define LCHCC_CUR_COL_B(b) ((b) & 0x3f)
  90#endif
  91
  92#define LCDC_PCR        0x18
  93
  94#define LCDC_HCR        0x1C
  95#define HCR_H_WIDTH(x)  (((x) & 0x3f) << 26)
  96#define HCR_H_WAIT_1(x) (((x) & 0xff) << 8)
  97#define HCR_H_WAIT_2(x) ((x) & 0xff)
  98
  99#define LCDC_VCR        0x20
 100#define VCR_V_WIDTH(x)  (((x) & 0x3f) << 26)
 101#define VCR_V_WAIT_1(x) (((x) & 0xff) << 8)
 102#define VCR_V_WAIT_2(x) ((x) & 0xff)
 103
 104#define LCDC_POS        0x24
 105#define POS_POS(x)      ((x) & 1f)
 106
 107#define LCDC_LSCR1      0x28
 108/* bit fields in imxfb.h */
 109
 110#define LCDC_PWMR       0x2C
 111/* bit fields in imxfb.h */
 112
 113#define LCDC_DMACR      0x30
 114/* bit fields in imxfb.h */
 115
 116#define LCDC_RMCR       0x34
 117
 118#ifdef CONFIG_ARCH_MX1
 119#define RMCR_LCDC_EN    (1<<1)
 120#else
 121#define RMCR_LCDC_EN    0
 122#endif
 123
 124#define RMCR_SELF_REF   (1<<0)
 125
 126#define LCDC_LCDICR     0x38
 127#define LCDICR_INT_SYN  (1<<2)
 128#define LCDICR_INT_CON  (1)
 129
 130#define LCDC_LCDISR     0x40
 131#define LCDISR_UDR_ERR  (1<<3)
 132#define LCDISR_ERR_RES  (1<<2)
 133#define LCDISR_EOF      (1<<1)
 134#define LCDISR_BOF      (1<<0)
 135
 136/* Used fb-mode. Can be set on kernel command line, therefore file-static. */
 137static const char *fb_mode;
 138
 139
 140/*
 141 * These are the bitfields for each
 142 * display depth that we support.
 143 */
 144struct imxfb_rgb {
 145        struct fb_bitfield      red;
 146        struct fb_bitfield      green;
 147        struct fb_bitfield      blue;
 148        struct fb_bitfield      transp;
 149};
 150
 151struct imxfb_info {
 152        struct platform_device  *pdev;
 153        void __iomem            *regs;
 154        struct clk              *clk;
 155
 156        /*
 157         * These are the addresses we mapped
 158         * the framebuffer memory region to.
 159         */
 160        dma_addr_t              map_dma;
 161        u_char                  *map_cpu;
 162        u_int                   map_size;
 163
 164        u_char                  *screen_cpu;
 165        dma_addr_t              screen_dma;
 166        u_int                   palette_size;
 167
 168        dma_addr_t              dbar1;
 169        dma_addr_t              dbar2;
 170
 171        u_int                   pcr;
 172        u_int                   pwmr;
 173        u_int                   lscr1;
 174        u_int                   dmacr;
 175        u_int                   cmap_inverse:1,
 176                                cmap_static:1,
 177                                unused:30;
 178
 179        struct imx_fb_videomode *mode;
 180        int                     num_modes;
 181#ifdef PWMR_BACKLIGHT_AVAILABLE
 182        struct backlight_device *bl;
 183#endif
 184
 185        void (*lcd_power)(int);
 186        void (*backlight_power)(int);
 187};
 188
 189#define IMX_NAME        "IMX"
 190
 191/*
 192 * Minimum X and Y resolutions
 193 */
 194#define MIN_XRES        64
 195#define MIN_YRES        64
 196
 197/* Actually this really is 18bit support, the lowest 2 bits of each colour
 198 * are unused in hardware. We claim to have 24bit support to make software
 199 * like X work, which does not support 18bit.
 200 */
 201static struct imxfb_rgb def_rgb_18 = {
 202        .red    = {.offset = 16, .length = 8,},
 203        .green  = {.offset = 8, .length = 8,},
 204        .blue   = {.offset = 0, .length = 8,},
 205        .transp = {.offset = 0, .length = 0,},
 206};
 207
 208static struct imxfb_rgb def_rgb_16_tft = {
 209        .red    = {.offset = 11, .length = 5,},
 210        .green  = {.offset = 5, .length = 6,},
 211        .blue   = {.offset = 0, .length = 5,},
 212        .transp = {.offset = 0, .length = 0,},
 213};
 214
 215static struct imxfb_rgb def_rgb_16_stn = {
 216        .red    = {.offset = 8, .length = 4,},
 217        .green  = {.offset = 4, .length = 4,},
 218        .blue   = {.offset = 0, .length = 4,},
 219        .transp = {.offset = 0, .length = 0,},
 220};
 221
 222static struct imxfb_rgb def_rgb_8 = {
 223        .red    = {.offset = 0, .length = 8,},
 224        .green  = {.offset = 0, .length = 8,},
 225        .blue   = {.offset = 0, .length = 8,},
 226        .transp = {.offset = 0, .length = 0,},
 227};
 228
 229static int imxfb_activate_var(struct fb_var_screeninfo *var,
 230                struct fb_info *info);
 231
 232static inline u_int chan_to_field(u_int chan, struct fb_bitfield *bf)
 233{
 234        chan &= 0xffff;
 235        chan >>= 16 - bf->length;
 236        return chan << bf->offset;
 237}
 238
 239static int imxfb_setpalettereg(u_int regno, u_int red, u_int green, u_int blue,
 240                u_int trans, struct fb_info *info)
 241{
 242        struct imxfb_info *fbi = info->par;
 243        u_int val, ret = 1;
 244
 245#define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16)
 246        if (regno < fbi->palette_size) {
 247                val = (CNVT_TOHW(red, 4) << 8) |
 248                      (CNVT_TOHW(green,4) << 4) |
 249                      CNVT_TOHW(blue,  4);
 250
 251                writel(val, fbi->regs + 0x800 + (regno << 2));
 252                ret = 0;
 253        }
 254        return ret;
 255}
 256
 257static int imxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
 258                   u_int trans, struct fb_info *info)
 259{
 260        struct imxfb_info *fbi = info->par;
 261        unsigned int val;
 262        int ret = 1;
 263
 264        /*
 265         * If inverse mode was selected, invert all the colours
 266         * rather than the register number.  The register number
 267         * is what you poke into the framebuffer to produce the
 268         * colour you requested.
 269         */
 270        if (fbi->cmap_inverse) {
 271                red   = 0xffff - red;
 272                green = 0xffff - green;
 273                blue  = 0xffff - blue;
 274        }
 275
 276        /*
 277         * If greyscale is true, then we convert the RGB value
 278         * to greyscale no mater what visual we are using.
 279         */
 280        if (info->var.grayscale)
 281                red = green = blue = (19595 * red + 38470 * green +
 282                                        7471 * blue) >> 16;
 283
 284        switch (info->fix.visual) {
 285        case FB_VISUAL_TRUECOLOR:
 286                /*
 287                 * 12 or 16-bit True Colour.  We encode the RGB value
 288                 * according to the RGB bitfield information.
 289                 */
 290                if (regno < 16) {
 291                        u32 *pal = info->pseudo_palette;
 292
 293                        val  = chan_to_field(red, &info->var.red);
 294                        val |= chan_to_field(green, &info->var.green);
 295                        val |= chan_to_field(blue, &info->var.blue);
 296
 297                        pal[regno] = val;
 298                        ret = 0;
 299                }
 300                break;
 301
 302        case FB_VISUAL_STATIC_PSEUDOCOLOR:
 303        case FB_VISUAL_PSEUDOCOLOR:
 304                ret = imxfb_setpalettereg(regno, red, green, blue, trans, info);
 305                break;
 306        }
 307
 308        return ret;
 309}
 310
 311static const struct imx_fb_videomode *imxfb_find_mode(struct imxfb_info *fbi)
 312{
 313        struct imx_fb_videomode *m;
 314        int i;
 315
 316        for (i = 0, m = &fbi->mode[0]; i < fbi->num_modes; i++, m++) {
 317                if (!strcmp(m->mode.name, fb_mode))
 318                        return m;
 319        }
 320        return NULL;
 321}
 322
 323/*
 324 *  imxfb_check_var():
 325 *    Round up in the following order: bits_per_pixel, xres,
 326 *    yres, xres_virtual, yres_virtual, xoffset, yoffset, grayscale,
 327 *    bitfields, horizontal timing, vertical timing.
 328 */
 329static int imxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 330{
 331        struct imxfb_info *fbi = info->par;
 332        struct imxfb_rgb *rgb;
 333        const struct imx_fb_videomode *imxfb_mode;
 334        unsigned long lcd_clk;
 335        unsigned long long tmp;
 336        u32 pcr = 0;
 337
 338        if (var->xres < MIN_XRES)
 339                var->xres = MIN_XRES;
 340        if (var->yres < MIN_YRES)
 341                var->yres = MIN_YRES;
 342
 343        imxfb_mode = imxfb_find_mode(fbi);
 344        if (!imxfb_mode)
 345                return -EINVAL;
 346
 347        var->xres               = imxfb_mode->mode.xres;
 348        var->yres               = imxfb_mode->mode.yres;
 349        var->bits_per_pixel     = imxfb_mode->bpp;
 350        var->pixclock           = imxfb_mode->mode.pixclock;
 351        var->hsync_len          = imxfb_mode->mode.hsync_len;
 352        var->left_margin        = imxfb_mode->mode.left_margin;
 353        var->right_margin       = imxfb_mode->mode.right_margin;
 354        var->vsync_len          = imxfb_mode->mode.vsync_len;
 355        var->upper_margin       = imxfb_mode->mode.upper_margin;
 356        var->lower_margin       = imxfb_mode->mode.lower_margin;
 357        var->sync               = imxfb_mode->mode.sync;
 358        var->xres_virtual       = max(var->xres_virtual, var->xres);
 359        var->yres_virtual       = max(var->yres_virtual, var->yres);
 360
 361        pr_debug("var->bits_per_pixel=%d\n", var->bits_per_pixel);
 362
 363        lcd_clk = clk_get_rate(fbi->clk);
 364
 365        tmp = var->pixclock * (unsigned long long)lcd_clk;
 366
 367        do_div(tmp, 1000000);
 368
 369        if (do_div(tmp, 1000000) > 500000)
 370                tmp++;
 371
 372        pcr = (unsigned int)tmp;
 373
 374        if (--pcr > 0x3F) {
 375                pcr = 0x3F;
 376                printk(KERN_WARNING "Must limit pixel clock to %luHz\n",
 377                                lcd_clk / pcr);
 378        }
 379
 380        switch (var->bits_per_pixel) {
 381        case 32:
 382                pcr |= PCR_BPIX_18;
 383                rgb = &def_rgb_18;
 384                break;
 385        case 16:
 386        default:
 387                if (cpu_is_mx1())
 388                        pcr |= PCR_BPIX_12;
 389                else
 390                        pcr |= PCR_BPIX_16;
 391
 392                if (imxfb_mode->pcr & PCR_TFT)
 393                        rgb = &def_rgb_16_tft;
 394                else
 395                        rgb = &def_rgb_16_stn;
 396                break;
 397        case 8:
 398                pcr |= PCR_BPIX_8;
 399                rgb = &def_rgb_8;
 400                break;
 401        }
 402
 403        /* add sync polarities */
 404        pcr |= imxfb_mode->pcr & ~(0x3f | (7 << 25));
 405
 406        fbi->pcr = pcr;
 407
 408        /*
 409         * Copy the RGB parameters for this display
 410         * from the machine specific parameters.
 411         */
 412        var->red    = rgb->red;
 413        var->green  = rgb->green;
 414        var->blue   = rgb->blue;
 415        var->transp = rgb->transp;
 416
 417        pr_debug("RGBT length = %d:%d:%d:%d\n",
 418                var->red.length, var->green.length, var->blue.length,
 419                var->transp.length);
 420
 421        pr_debug("RGBT offset = %d:%d:%d:%d\n",
 422                var->red.offset, var->green.offset, var->blue.offset,
 423                var->transp.offset);
 424
 425        return 0;
 426}
 427
 428/*
 429 * imxfb_set_par():
 430 *      Set the user defined part of the display for the specified console
 431 */
 432static int imxfb_set_par(struct fb_info *info)
 433{
 434        struct imxfb_info *fbi = info->par;
 435        struct fb_var_screeninfo *var = &info->var;
 436
 437        if (var->bits_per_pixel == 16 || var->bits_per_pixel == 32)
 438                info->fix.visual = FB_VISUAL_TRUECOLOR;
 439        else if (!fbi->cmap_static)
 440                info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
 441        else {
 442                /*
 443                 * Some people have weird ideas about wanting static
 444                 * pseudocolor maps.  I suspect their user space
 445                 * applications are broken.
 446                 */
 447                info->fix.visual = FB_VISUAL_STATIC_PSEUDOCOLOR;
 448        }
 449
 450        info->fix.line_length = var->xres_virtual * var->bits_per_pixel / 8;
 451        fbi->palette_size = var->bits_per_pixel == 8 ? 256 : 16;
 452
 453        imxfb_activate_var(var, info);
 454
 455        return 0;
 456}
 457
 458#ifdef PWMR_BACKLIGHT_AVAILABLE
 459static int imxfb_bl_get_brightness(struct backlight_device *bl)
 460{
 461        struct imxfb_info *fbi = bl_get_data(bl);
 462
 463        return readl(fbi->regs + LCDC_PWMR) & 0xFF;
 464}
 465
 466static int imxfb_bl_update_status(struct backlight_device *bl)
 467{
 468        struct imxfb_info *fbi = bl_get_data(bl);
 469        int brightness = bl->props.brightness;
 470
 471        if (bl->props.power != FB_BLANK_UNBLANK)
 472                brightness = 0;
 473        if (bl->props.fb_blank != FB_BLANK_UNBLANK)
 474                brightness = 0;
 475
 476        fbi->pwmr = (fbi->pwmr & ~0xFF) | brightness;
 477
 478        if (bl->props.fb_blank != FB_BLANK_UNBLANK)
 479                clk_enable(fbi->clk);
 480        writel(fbi->pwmr, fbi->regs + LCDC_PWMR);
 481        if (bl->props.fb_blank != FB_BLANK_UNBLANK)
 482                clk_disable(fbi->clk);
 483
 484        return 0;
 485}
 486
 487static const struct backlight_ops imxfb_lcdc_bl_ops = {
 488        .update_status = imxfb_bl_update_status,
 489        .get_brightness = imxfb_bl_get_brightness,
 490};
 491
 492static void imxfb_init_backlight(struct imxfb_info *fbi)
 493{
 494        struct backlight_properties props;
 495        struct backlight_device *bl;
 496
 497        if (fbi->bl)
 498                return;
 499
 500        memset(&props, 0, sizeof(struct backlight_properties));
 501        props.max_brightness = 0xff;
 502        writel(fbi->pwmr, fbi->regs + LCDC_PWMR);
 503
 504        bl = backlight_device_register("imxfb-bl", &fbi->pdev->dev, fbi,
 505                                       &imxfb_lcdc_bl_ops, &props);
 506        if (IS_ERR(bl)) {
 507                dev_err(&fbi->pdev->dev, "error %ld on backlight register\n",
 508                                PTR_ERR(bl));
 509                return;
 510        }
 511
 512        fbi->bl = bl;
 513        bl->props.power = FB_BLANK_UNBLANK;
 514        bl->props.fb_blank = FB_BLANK_UNBLANK;
 515        bl->props.brightness = imxfb_bl_get_brightness(bl);
 516}
 517
 518static void imxfb_exit_backlight(struct imxfb_info *fbi)
 519{
 520        if (fbi->bl)
 521                backlight_device_unregister(fbi->bl);
 522}
 523#endif
 524
 525static void imxfb_enable_controller(struct imxfb_info *fbi)
 526{
 527        pr_debug("Enabling LCD controller\n");
 528
 529        writel(fbi->screen_dma, fbi->regs + LCDC_SSA);
 530
 531        /* panning offset 0 (0 pixel offset)        */
 532        writel(0x00000000, fbi->regs + LCDC_POS);
 533
 534        /* disable hardware cursor */
 535        writel(readl(fbi->regs + LCDC_CPOS) & ~(CPOS_CC0 | CPOS_CC1),
 536                fbi->regs + LCDC_CPOS);
 537
 538        writel(RMCR_LCDC_EN, fbi->regs + LCDC_RMCR);
 539
 540        clk_enable(fbi->clk);
 541
 542        if (fbi->backlight_power)
 543                fbi->backlight_power(1);
 544        if (fbi->lcd_power)
 545                fbi->lcd_power(1);
 546}
 547
 548static void imxfb_disable_controller(struct imxfb_info *fbi)
 549{
 550        pr_debug("Disabling LCD controller\n");
 551
 552        if (fbi->backlight_power)
 553                fbi->backlight_power(0);
 554        if (fbi->lcd_power)
 555                fbi->lcd_power(0);
 556
 557        clk_disable(fbi->clk);
 558
 559        writel(0, fbi->regs + LCDC_RMCR);
 560}
 561
 562static int imxfb_blank(int blank, struct fb_info *info)
 563{
 564        struct imxfb_info *fbi = info->par;
 565
 566        pr_debug("imxfb_blank: blank=%d\n", blank);
 567
 568        switch (blank) {
 569        case FB_BLANK_POWERDOWN:
 570        case FB_BLANK_VSYNC_SUSPEND:
 571        case FB_BLANK_HSYNC_SUSPEND:
 572        case FB_BLANK_NORMAL:
 573                imxfb_disable_controller(fbi);
 574                break;
 575
 576        case FB_BLANK_UNBLANK:
 577                imxfb_enable_controller(fbi);
 578                break;
 579        }
 580        return 0;
 581}
 582
 583static struct fb_ops imxfb_ops = {
 584        .owner          = THIS_MODULE,
 585        .fb_check_var   = imxfb_check_var,
 586        .fb_set_par     = imxfb_set_par,
 587        .fb_setcolreg   = imxfb_setcolreg,
 588        .fb_fillrect    = cfb_fillrect,
 589        .fb_copyarea    = cfb_copyarea,
 590        .fb_imageblit   = cfb_imageblit,
 591        .fb_blank       = imxfb_blank,
 592};
 593
 594/*
 595 * imxfb_activate_var():
 596 *      Configures LCD Controller based on entries in var parameter.  Settings are
 597 *      only written to the controller if changes were made.
 598 */
 599static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *info)
 600{
 601        struct imxfb_info *fbi = info->par;
 602
 603        pr_debug("var: xres=%d hslen=%d lm=%d rm=%d\n",
 604                var->xres, var->hsync_len,
 605                var->left_margin, var->right_margin);
 606        pr_debug("var: yres=%d vslen=%d um=%d bm=%d\n",
 607                var->yres, var->vsync_len,
 608                var->upper_margin, var->lower_margin);
 609
 610#if DEBUG_VAR
 611        if (var->xres < 16        || var->xres > 1024)
 612                printk(KERN_ERR "%s: invalid xres %d\n",
 613                        info->fix.id, var->xres);
 614        if (var->hsync_len < 1    || var->hsync_len > 64)
 615                printk(KERN_ERR "%s: invalid hsync_len %d\n",
 616                        info->fix.id, var->hsync_len);
 617        if (var->left_margin > 255)
 618                printk(KERN_ERR "%s: invalid left_margin %d\n",
 619                        info->fix.id, var->left_margin);
 620        if (var->right_margin > 255)
 621                printk(KERN_ERR "%s: invalid right_margin %d\n",
 622                        info->fix.id, var->right_margin);
 623        if (var->yres < 1 || var->yres > YMAX_MASK)
 624                printk(KERN_ERR "%s: invalid yres %d\n",
 625                        info->fix.id, var->yres);
 626        if (var->vsync_len > 100)
 627                printk(KERN_ERR "%s: invalid vsync_len %d\n",
 628                        info->fix.id, var->vsync_len);
 629        if (var->upper_margin > 63)
 630                printk(KERN_ERR "%s: invalid upper_margin %d\n",
 631                        info->fix.id, var->upper_margin);
 632        if (var->lower_margin > 255)
 633                printk(KERN_ERR "%s: invalid lower_margin %d\n",
 634                        info->fix.id, var->lower_margin);
 635#endif
 636
 637        /* physical screen start address            */
 638        writel(VPW_VPW(var->xres * var->bits_per_pixel / 8 / 4),
 639                fbi->regs + LCDC_VPW);
 640
 641        writel(HCR_H_WIDTH(var->hsync_len - 1) |
 642                HCR_H_WAIT_1(var->right_margin - 1) |
 643                HCR_H_WAIT_2(var->left_margin - 3),
 644                fbi->regs + LCDC_HCR);
 645
 646        writel(VCR_V_WIDTH(var->vsync_len) |
 647                VCR_V_WAIT_1(var->lower_margin) |
 648                VCR_V_WAIT_2(var->upper_margin),
 649                fbi->regs + LCDC_VCR);
 650
 651        writel(SIZE_XMAX(var->xres) | SIZE_YMAX(var->yres),
 652                        fbi->regs + LCDC_SIZE);
 653
 654        writel(fbi->pcr, fbi->regs + LCDC_PCR);
 655#ifndef PWMR_BACKLIGHT_AVAILABLE
 656        writel(fbi->pwmr, fbi->regs + LCDC_PWMR);
 657#endif
 658        writel(fbi->lscr1, fbi->regs + LCDC_LSCR1);
 659        writel(fbi->dmacr, fbi->regs + LCDC_DMACR);
 660
 661        return 0;
 662}
 663
 664#ifdef CONFIG_PM
 665/*
 666 * Power management hooks.  Note that we won't be called from IRQ context,
 667 * unlike the blank functions above, so we may sleep.
 668 */
 669static int imxfb_suspend(struct platform_device *dev, pm_message_t state)
 670{
 671        struct fb_info *info = platform_get_drvdata(dev);
 672        struct imxfb_info *fbi = info->par;
 673
 674        pr_debug("%s\n", __func__);
 675
 676        imxfb_disable_controller(fbi);
 677        return 0;
 678}
 679
 680static int imxfb_resume(struct platform_device *dev)
 681{
 682        struct fb_info *info = platform_get_drvdata(dev);
 683        struct imxfb_info *fbi = info->par;
 684
 685        pr_debug("%s\n", __func__);
 686
 687        imxfb_enable_controller(fbi);
 688        return 0;
 689}
 690#else
 691#define imxfb_suspend   NULL
 692#define imxfb_resume    NULL
 693#endif
 694
 695static int __init imxfb_init_fbinfo(struct platform_device *pdev)
 696{
 697        struct imx_fb_platform_data *pdata = pdev->dev.platform_data;
 698        struct fb_info *info = dev_get_drvdata(&pdev->dev);
 699        struct imxfb_info *fbi = info->par;
 700        struct imx_fb_videomode *m;
 701        int i;
 702
 703        pr_debug("%s\n",__func__);
 704
 705        info->pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL);
 706        if (!info->pseudo_palette)
 707                return -ENOMEM;
 708
 709        memset(fbi, 0, sizeof(struct imxfb_info));
 710
 711        strlcpy(info->fix.id, IMX_NAME, sizeof(info->fix.id));
 712
 713        info->fix.type                  = FB_TYPE_PACKED_PIXELS;
 714        info->fix.type_aux              = 0;
 715        info->fix.xpanstep              = 0;
 716        info->fix.ypanstep              = 0;
 717        info->fix.ywrapstep             = 0;
 718        info->fix.accel                 = FB_ACCEL_NONE;
 719
 720        info->var.nonstd                = 0;
 721        info->var.activate              = FB_ACTIVATE_NOW;
 722        info->var.height                = -1;
 723        info->var.width = -1;
 724        info->var.accel_flags           = 0;
 725        info->var.vmode                 = FB_VMODE_NONINTERLACED;
 726
 727        info->fbops                     = &imxfb_ops;
 728        info->flags                     = FBINFO_FLAG_DEFAULT |
 729                                          FBINFO_READS_FAST;
 730        info->var.grayscale             = pdata->cmap_greyscale;
 731        fbi->cmap_inverse               = pdata->cmap_inverse;
 732        fbi->cmap_static                = pdata->cmap_static;
 733        fbi->lscr1                      = pdata->lscr1;
 734        fbi->dmacr                      = pdata->dmacr;
 735        fbi->pwmr                       = pdata->pwmr;
 736        fbi->lcd_power                  = pdata->lcd_power;
 737        fbi->backlight_power            = pdata->backlight_power;
 738
 739        for (i = 0, m = &pdata->mode[0]; i < pdata->num_modes; i++, m++)
 740                info->fix.smem_len = max_t(size_t, info->fix.smem_len,
 741                                m->mode.xres * m->mode.yres * m->bpp / 8);
 742
 743        return 0;
 744}
 745
 746static int __init imxfb_probe(struct platform_device *pdev)
 747{
 748        struct imxfb_info *fbi;
 749        struct fb_info *info;
 750        struct imx_fb_platform_data *pdata;
 751        struct resource *res;
 752        int ret, i;
 753
 754        dev_info(&pdev->dev, "i.MX Framebuffer driver\n");
 755
 756        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 757        if (!res)
 758                return -ENODEV;
 759
 760        pdata = pdev->dev.platform_data;
 761        if (!pdata) {
 762                dev_err(&pdev->dev,"No platform_data available\n");
 763                return -ENOMEM;
 764        }
 765
 766        info = framebuffer_alloc(sizeof(struct imxfb_info), &pdev->dev);
 767        if (!info)
 768                return -ENOMEM;
 769
 770        fbi = info->par;
 771
 772        if (!fb_mode)
 773                fb_mode = pdata->mode[0].mode.name;
 774
 775        platform_set_drvdata(pdev, info);
 776
 777        ret = imxfb_init_fbinfo(pdev);
 778        if (ret < 0)
 779                goto failed_init;
 780
 781        res = request_mem_region(res->start, resource_size(res),
 782                                DRIVER_NAME);
 783        if (!res) {
 784                ret = -EBUSY;
 785                goto failed_req;
 786        }
 787
 788        fbi->clk = clk_get(&pdev->dev, NULL);
 789        if (IS_ERR(fbi->clk)) {
 790                ret = PTR_ERR(fbi->clk);
 791                dev_err(&pdev->dev, "unable to get clock: %d\n", ret);
 792                goto failed_getclock;
 793        }
 794
 795        fbi->regs = ioremap(res->start, resource_size(res));
 796        if (fbi->regs == NULL) {
 797                dev_err(&pdev->dev, "Cannot map frame buffer registers\n");
 798                goto failed_ioremap;
 799        }
 800
 801        if (!pdata->fixed_screen_cpu) {
 802                fbi->map_size = PAGE_ALIGN(info->fix.smem_len);
 803                fbi->map_cpu = dma_alloc_writecombine(&pdev->dev,
 804                                fbi->map_size, &fbi->map_dma, GFP_KERNEL);
 805
 806                if (!fbi->map_cpu) {
 807                        dev_err(&pdev->dev, "Failed to allocate video RAM: %d\n", ret);
 808                        ret = -ENOMEM;
 809                        goto failed_map;
 810                }
 811
 812                info->screen_base = fbi->map_cpu;
 813                fbi->screen_cpu = fbi->map_cpu;
 814                fbi->screen_dma = fbi->map_dma;
 815                info->fix.smem_start = fbi->screen_dma;
 816        } else {
 817                /* Fixed framebuffer mapping enables location of the screen in eSRAM */
 818                fbi->map_cpu = pdata->fixed_screen_cpu;
 819                fbi->map_dma = pdata->fixed_screen_dma;
 820                info->screen_base = fbi->map_cpu;
 821                fbi->screen_cpu = fbi->map_cpu;
 822                fbi->screen_dma = fbi->map_dma;
 823                info->fix.smem_start = fbi->screen_dma;
 824        }
 825
 826        if (pdata->init) {
 827                ret = pdata->init(fbi->pdev);
 828                if (ret)
 829                        goto failed_platform_init;
 830        }
 831
 832        fbi->mode = pdata->mode;
 833        fbi->num_modes = pdata->num_modes;
 834
 835        INIT_LIST_HEAD(&info->modelist);
 836        for (i = 0; i < pdata->num_modes; i++)
 837                fb_add_videomode(&pdata->mode[i].mode, &info->modelist);
 838
 839        /*
 840         * This makes sure that our colour bitfield
 841         * descriptors are correctly initialised.
 842         */
 843        imxfb_check_var(&info->var, info);
 844
 845        ret = fb_alloc_cmap(&info->cmap, 1 << info->var.bits_per_pixel, 0);
 846        if (ret < 0)
 847                goto failed_cmap;
 848
 849        imxfb_set_par(info);
 850        ret = register_framebuffer(info);
 851        if (ret < 0) {
 852                dev_err(&pdev->dev, "failed to register framebuffer\n");
 853                goto failed_register;
 854        }
 855
 856        imxfb_enable_controller(fbi);
 857        fbi->pdev = pdev;
 858#ifdef PWMR_BACKLIGHT_AVAILABLE
 859        imxfb_init_backlight(fbi);
 860#endif
 861
 862        return 0;
 863
 864failed_register:
 865        fb_dealloc_cmap(&info->cmap);
 866failed_cmap:
 867        if (pdata->exit)
 868                pdata->exit(fbi->pdev);
 869failed_platform_init:
 870        if (!pdata->fixed_screen_cpu)
 871                dma_free_writecombine(&pdev->dev,fbi->map_size,fbi->map_cpu,
 872                        fbi->map_dma);
 873failed_map:
 874        clk_put(fbi->clk);
 875failed_getclock:
 876        iounmap(fbi->regs);
 877failed_ioremap:
 878        release_mem_region(res->start, resource_size(res));
 879failed_req:
 880        kfree(info->pseudo_palette);
 881failed_init:
 882        platform_set_drvdata(pdev, NULL);
 883        framebuffer_release(info);
 884        return ret;
 885}
 886
 887static int __devexit imxfb_remove(struct platform_device *pdev)
 888{
 889        struct imx_fb_platform_data *pdata;
 890        struct fb_info *info = platform_get_drvdata(pdev);
 891        struct imxfb_info *fbi = info->par;
 892        struct resource *res;
 893
 894        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 895
 896        imxfb_disable_controller(fbi);
 897
 898#ifdef PWMR_BACKLIGHT_AVAILABLE
 899        imxfb_exit_backlight(fbi);
 900#endif
 901        unregister_framebuffer(info);
 902
 903        pdata = pdev->dev.platform_data;
 904        if (pdata->exit)
 905                pdata->exit(fbi->pdev);
 906
 907        fb_dealloc_cmap(&info->cmap);
 908        kfree(info->pseudo_palette);
 909        framebuffer_release(info);
 910
 911        iounmap(fbi->regs);
 912        release_mem_region(res->start, resource_size(res));
 913        clk_disable(fbi->clk);
 914        clk_put(fbi->clk);
 915
 916        platform_set_drvdata(pdev, NULL);
 917
 918        return 0;
 919}
 920
 921void  imxfb_shutdown(struct platform_device * dev)
 922{
 923        struct fb_info *info = platform_get_drvdata(dev);
 924        struct imxfb_info *fbi = info->par;
 925        imxfb_disable_controller(fbi);
 926}
 927
 928static struct platform_driver imxfb_driver = {
 929        .suspend        = imxfb_suspend,
 930        .resume         = imxfb_resume,
 931        .remove         = __devexit_p(imxfb_remove),
 932        .shutdown       = imxfb_shutdown,
 933        .driver         = {
 934                .name   = DRIVER_NAME,
 935        },
 936};
 937
 938static int imxfb_setup(void)
 939{
 940#ifndef MODULE
 941        char *opt, *options = NULL;
 942
 943        if (fb_get_options("imxfb", &options))
 944                return -ENODEV;
 945
 946        if (!options || !*options)
 947                return 0;
 948
 949        while ((opt = strsep(&options, ",")) != NULL) {
 950                if (!*opt)
 951                        continue;
 952                else
 953                        fb_mode = opt;
 954        }
 955#endif
 956        return 0;
 957}
 958
 959int __init imxfb_init(void)
 960{
 961        int ret = imxfb_setup();
 962
 963        if (ret < 0)
 964                return ret;
 965
 966        return platform_driver_probe(&imxfb_driver, imxfb_probe);
 967}
 968
 969static void __exit imxfb_cleanup(void)
 970{
 971        platform_driver_unregister(&imxfb_driver);
 972}
 973
 974module_init(imxfb_init);
 975module_exit(imxfb_cleanup);
 976
 977MODULE_DESCRIPTION("Freescale i.MX framebuffer driver");
 978MODULE_AUTHOR("Sascha Hauer, Pengutronix");
 979MODULE_LICENSE("GPL");
 980