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