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