linux/drivers/video/fbdev/amba-clcd.c
<<
>>
Prefs
   1/*
   2 *  linux/drivers/video/amba-clcd.c
   3 *
   4 * Copyright (C) 2001 ARM Limited, by David A Rusling
   5 * Updated to 2.5, Deep Blue Solutions Ltd.
   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
   9 * for more details.
  10 *
  11 *  ARM PrimeCell PL110 Color LCD Controller
  12 */
  13#include <linux/dma-mapping.h>
  14#include <linux/module.h>
  15#include <linux/kernel.h>
  16#include <linux/errno.h>
  17#include <linux/string.h>
  18#include <linux/slab.h>
  19#include <linux/delay.h>
  20#include <linux/mm.h>
  21#include <linux/fb.h>
  22#include <linux/init.h>
  23#include <linux/ioport.h>
  24#include <linux/list.h>
  25#include <linux/amba/bus.h>
  26#include <linux/amba/clcd.h>
  27#include <linux/bitops.h>
  28#include <linux/clk.h>
  29#include <linux/hardirq.h>
  30#include <linux/of.h>
  31#include <linux/of_address.h>
  32#include <linux/of_graph.h>
  33#include <linux/backlight.h>
  34#include <video/display_timing.h>
  35#include <video/of_display_timing.h>
  36#include <video/videomode.h>
  37
  38#include "amba-clcd-nomadik.h"
  39#include "amba-clcd-versatile.h"
  40
  41#define to_clcd(info)   container_of(info, struct clcd_fb, fb)
  42
  43/* This is limited to 16 characters when displayed by X startup */
  44static const char *clcd_name = "CLCD FB";
  45
  46/*
  47 * Unfortunately, the enable/disable functions may be called either from
  48 * process or IRQ context, and we _need_ to delay.  This is _not_ good.
  49 */
  50static inline void clcdfb_sleep(unsigned int ms)
  51{
  52        if (in_atomic()) {
  53                mdelay(ms);
  54        } else {
  55                msleep(ms);
  56        }
  57}
  58
  59static inline void clcdfb_set_start(struct clcd_fb *fb)
  60{
  61        unsigned long ustart = fb->fb.fix.smem_start;
  62        unsigned long lstart;
  63
  64        ustart += fb->fb.var.yoffset * fb->fb.fix.line_length;
  65        lstart = ustart + fb->fb.var.yres * fb->fb.fix.line_length / 2;
  66
  67        writel(ustart, fb->regs + CLCD_UBAS);
  68        writel(lstart, fb->regs + CLCD_LBAS);
  69}
  70
  71static void clcdfb_disable(struct clcd_fb *fb)
  72{
  73        u32 val;
  74
  75        if (fb->board->disable)
  76                fb->board->disable(fb);
  77
  78        if (fb->panel->backlight) {
  79                fb->panel->backlight->props.power = FB_BLANK_POWERDOWN;
  80                backlight_update_status(fb->panel->backlight);
  81        }
  82
  83        val = readl(fb->regs + fb->off_cntl);
  84        if (val & CNTL_LCDPWR) {
  85                val &= ~CNTL_LCDPWR;
  86                writel(val, fb->regs + fb->off_cntl);
  87
  88                clcdfb_sleep(20);
  89        }
  90        if (val & CNTL_LCDEN) {
  91                val &= ~CNTL_LCDEN;
  92                writel(val, fb->regs + fb->off_cntl);
  93        }
  94
  95        /*
  96         * Disable CLCD clock source.
  97         */
  98        if (fb->clk_enabled) {
  99                fb->clk_enabled = false;
 100                clk_disable(fb->clk);
 101        }
 102}
 103
 104static void clcdfb_enable(struct clcd_fb *fb, u32 cntl)
 105{
 106        /*
 107         * Enable the CLCD clock source.
 108         */
 109        if (!fb->clk_enabled) {
 110                fb->clk_enabled = true;
 111                clk_enable(fb->clk);
 112        }
 113
 114        /*
 115         * Bring up by first enabling..
 116         */
 117        cntl |= CNTL_LCDEN;
 118        writel(cntl, fb->regs + fb->off_cntl);
 119
 120        clcdfb_sleep(20);
 121
 122        /*
 123         * and now apply power.
 124         */
 125        cntl |= CNTL_LCDPWR;
 126        writel(cntl, fb->regs + fb->off_cntl);
 127
 128        /*
 129         * Turn on backlight
 130         */
 131        if (fb->panel->backlight) {
 132                fb->panel->backlight->props.power = FB_BLANK_UNBLANK;
 133                backlight_update_status(fb->panel->backlight);
 134        }
 135
 136        /*
 137         * finally, enable the interface.
 138         */
 139        if (fb->board->enable)
 140                fb->board->enable(fb);
 141}
 142
 143static int
 144clcdfb_set_bitfields(struct clcd_fb *fb, struct fb_var_screeninfo *var)
 145{
 146        u32 caps;
 147        int ret = 0;
 148
 149        if (fb->panel->caps && fb->board->caps)
 150                caps = fb->panel->caps & fb->board->caps;
 151        else {
 152                /* Old way of specifying what can be used */
 153                caps = fb->panel->cntl & CNTL_BGR ?
 154                        CLCD_CAP_BGR : CLCD_CAP_RGB;
 155                /* But mask out 444 modes as they weren't supported */
 156                caps &= ~CLCD_CAP_444;
 157        }
 158
 159        /* Only TFT panels can do RGB888/BGR888 */
 160        if (!(fb->panel->cntl & CNTL_LCDTFT))
 161                caps &= ~CLCD_CAP_888;
 162
 163        memset(&var->transp, 0, sizeof(var->transp));
 164
 165        var->red.msb_right = 0;
 166        var->green.msb_right = 0;
 167        var->blue.msb_right = 0;
 168
 169        switch (var->bits_per_pixel) {
 170        case 1:
 171        case 2:
 172        case 4:
 173        case 8:
 174                /* If we can't do 5551, reject */
 175                caps &= CLCD_CAP_5551;
 176                if (!caps) {
 177                        ret = -EINVAL;
 178                        break;
 179                }
 180
 181                var->red.length         = var->bits_per_pixel;
 182                var->red.offset         = 0;
 183                var->green.length       = var->bits_per_pixel;
 184                var->green.offset       = 0;
 185                var->blue.length        = var->bits_per_pixel;
 186                var->blue.offset        = 0;
 187                break;
 188
 189        case 16:
 190                /* If we can't do 444, 5551 or 565, reject */
 191                if (!(caps & (CLCD_CAP_444 | CLCD_CAP_5551 | CLCD_CAP_565))) {
 192                        ret = -EINVAL;
 193                        break;
 194                }
 195
 196                /*
 197                 * Green length can be 4, 5 or 6 depending whether
 198                 * we're operating in 444, 5551 or 565 mode.
 199                 */
 200                if (var->green.length == 4 && caps & CLCD_CAP_444)
 201                        caps &= CLCD_CAP_444;
 202                if (var->green.length == 5 && caps & CLCD_CAP_5551)
 203                        caps &= CLCD_CAP_5551;
 204                else if (var->green.length == 6 && caps & CLCD_CAP_565)
 205                        caps &= CLCD_CAP_565;
 206                else {
 207                        /*
 208                         * PL110 officially only supports RGB555,
 209                         * but may be wired up to allow RGB565.
 210                         */
 211                        if (caps & CLCD_CAP_565) {
 212                                var->green.length = 6;
 213                                caps &= CLCD_CAP_565;
 214                        } else if (caps & CLCD_CAP_5551) {
 215                                var->green.length = 5;
 216                                caps &= CLCD_CAP_5551;
 217                        } else {
 218                                var->green.length = 4;
 219                                caps &= CLCD_CAP_444;
 220                        }
 221                }
 222
 223                if (var->green.length >= 5) {
 224                        var->red.length = 5;
 225                        var->blue.length = 5;
 226                } else {
 227                        var->red.length = 4;
 228                        var->blue.length = 4;
 229                }
 230                break;
 231        case 24:
 232                if (fb->vendor->packed_24_bit_pixels) {
 233                        var->red.length = 8;
 234                        var->green.length = 8;
 235                        var->blue.length = 8;
 236                } else {
 237                        ret = -EINVAL;
 238                }
 239                break;
 240        case 32:
 241                /* If we can't do 888, reject */
 242                caps &= CLCD_CAP_888;
 243                if (!caps) {
 244                        ret = -EINVAL;
 245                        break;
 246                }
 247
 248                var->red.length = 8;
 249                var->green.length = 8;
 250                var->blue.length = 8;
 251                break;
 252        default:
 253                ret = -EINVAL;
 254                break;
 255        }
 256
 257        /*
 258         * >= 16bpp displays have separate colour component bitfields
 259         * encoded in the pixel data.  Calculate their position from
 260         * the bitfield length defined above.
 261         */
 262        if (ret == 0 && var->bits_per_pixel >= 16) {
 263                bool bgr, rgb;
 264
 265                bgr = caps & CLCD_CAP_BGR && var->blue.offset == 0;
 266                rgb = caps & CLCD_CAP_RGB && var->red.offset == 0;
 267
 268                if (!bgr && !rgb)
 269                        /*
 270                         * The requested format was not possible, try just
 271                         * our capabilities.  One of BGR or RGB must be
 272                         * supported.
 273                         */
 274                        bgr = caps & CLCD_CAP_BGR;
 275
 276                if (bgr) {
 277                        var->blue.offset = 0;
 278                        var->green.offset = var->blue.offset + var->blue.length;
 279                        var->red.offset = var->green.offset + var->green.length;
 280                } else {
 281                        var->red.offset = 0;
 282                        var->green.offset = var->red.offset + var->red.length;
 283                        var->blue.offset = var->green.offset + var->green.length;
 284                }
 285        }
 286
 287        return ret;
 288}
 289
 290static int clcdfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 291{
 292        struct clcd_fb *fb = to_clcd(info);
 293        int ret = -EINVAL;
 294
 295        if (fb->board->check)
 296                ret = fb->board->check(fb, var);
 297
 298        if (ret == 0 &&
 299            var->xres_virtual * var->bits_per_pixel / 8 *
 300            var->yres_virtual > fb->fb.fix.smem_len)
 301                ret = -EINVAL;
 302
 303        if (ret == 0)
 304                ret = clcdfb_set_bitfields(fb, var);
 305
 306        return ret;
 307}
 308
 309static int clcdfb_set_par(struct fb_info *info)
 310{
 311        struct clcd_fb *fb = to_clcd(info);
 312        struct clcd_regs regs;
 313
 314        fb->fb.fix.line_length = fb->fb.var.xres_virtual *
 315                                 fb->fb.var.bits_per_pixel / 8;
 316
 317        if (fb->fb.var.bits_per_pixel <= 8)
 318                fb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR;
 319        else
 320                fb->fb.fix.visual = FB_VISUAL_TRUECOLOR;
 321
 322        fb->board->decode(fb, &regs);
 323
 324        clcdfb_disable(fb);
 325
 326        /* Some variants must be clocked here */
 327        if (fb->vendor->clock_timregs && !fb->clk_enabled) {
 328                fb->clk_enabled = true;
 329                clk_enable(fb->clk);
 330        }
 331
 332        writel(regs.tim0, fb->regs + CLCD_TIM0);
 333        writel(regs.tim1, fb->regs + CLCD_TIM1);
 334        writel(regs.tim2, fb->regs + CLCD_TIM2);
 335        writel(regs.tim3, fb->regs + CLCD_TIM3);
 336
 337        clcdfb_set_start(fb);
 338
 339        clk_set_rate(fb->clk, (1000000000 / regs.pixclock) * 1000);
 340
 341        fb->clcd_cntl = regs.cntl;
 342
 343        clcdfb_enable(fb, regs.cntl);
 344
 345#ifdef DEBUG
 346        printk(KERN_INFO
 347               "CLCD: Registers set to\n"
 348               "  %08x %08x %08x %08x\n"
 349               "  %08x %08x %08x %08x\n",
 350                readl(fb->regs + CLCD_TIM0), readl(fb->regs + CLCD_TIM1),
 351                readl(fb->regs + CLCD_TIM2), readl(fb->regs + CLCD_TIM3),
 352                readl(fb->regs + CLCD_UBAS), readl(fb->regs + CLCD_LBAS),
 353                readl(fb->regs + fb->off_ienb), readl(fb->regs + fb->off_cntl));
 354#endif
 355
 356        return 0;
 357}
 358
 359static inline u32 convert_bitfield(int val, struct fb_bitfield *bf)
 360{
 361        unsigned int mask = (1 << bf->length) - 1;
 362
 363        return (val >> (16 - bf->length) & mask) << bf->offset;
 364}
 365
 366/*
 367 *  Set a single color register. The values supplied have a 16 bit
 368 *  magnitude.  Return != 0 for invalid regno.
 369 */
 370static int
 371clcdfb_setcolreg(unsigned int regno, unsigned int red, unsigned int green,
 372                 unsigned int blue, unsigned int transp, struct fb_info *info)
 373{
 374        struct clcd_fb *fb = to_clcd(info);
 375
 376        if (regno < 16)
 377                fb->cmap[regno] = convert_bitfield(transp, &fb->fb.var.transp) |
 378                                  convert_bitfield(blue, &fb->fb.var.blue) |
 379                                  convert_bitfield(green, &fb->fb.var.green) |
 380                                  convert_bitfield(red, &fb->fb.var.red);
 381
 382        if (fb->fb.fix.visual == FB_VISUAL_PSEUDOCOLOR && regno < 256) {
 383                int hw_reg = CLCD_PALETTE + ((regno * 2) & ~3);
 384                u32 val, mask, newval;
 385
 386                newval  = (red >> 11)  & 0x001f;
 387                newval |= (green >> 6) & 0x03e0;
 388                newval |= (blue >> 1)  & 0x7c00;
 389
 390                /*
 391                 * 3.2.11: if we're configured for big endian
 392                 * byte order, the palette entries are swapped.
 393                 */
 394                if (fb->clcd_cntl & CNTL_BEBO)
 395                        regno ^= 1;
 396
 397                if (regno & 1) {
 398                        newval <<= 16;
 399                        mask = 0x0000ffff;
 400                } else {
 401                        mask = 0xffff0000;
 402                }
 403
 404                val = readl(fb->regs + hw_reg) & mask;
 405                writel(val | newval, fb->regs + hw_reg);
 406        }
 407
 408        return regno > 255;
 409}
 410
 411/*
 412 *  Blank the screen if blank_mode != 0, else unblank. If blank == NULL
 413 *  then the caller blanks by setting the CLUT (Color Look Up Table) to all
 414 *  black. Return 0 if blanking succeeded, != 0 if un-/blanking failed due
 415 *  to e.g. a video mode which doesn't support it. Implements VESA suspend
 416 *  and powerdown modes on hardware that supports disabling hsync/vsync:
 417 *    blank_mode == 2: suspend vsync
 418 *    blank_mode == 3: suspend hsync
 419 *    blank_mode == 4: powerdown
 420 */
 421static int clcdfb_blank(int blank_mode, struct fb_info *info)
 422{
 423        struct clcd_fb *fb = to_clcd(info);
 424
 425        if (blank_mode != 0) {
 426                clcdfb_disable(fb);
 427        } else {
 428                clcdfb_enable(fb, fb->clcd_cntl);
 429        }
 430        return 0;
 431}
 432
 433static int clcdfb_mmap(struct fb_info *info,
 434                       struct vm_area_struct *vma)
 435{
 436        struct clcd_fb *fb = to_clcd(info);
 437        unsigned long len, off = vma->vm_pgoff << PAGE_SHIFT;
 438        int ret = -EINVAL;
 439
 440        len = info->fix.smem_len;
 441
 442        if (off <= len && vma->vm_end - vma->vm_start <= len - off &&
 443            fb->board->mmap)
 444                ret = fb->board->mmap(fb, vma);
 445
 446        return ret;
 447}
 448
 449static struct fb_ops clcdfb_ops = {
 450        .owner          = THIS_MODULE,
 451        .fb_check_var   = clcdfb_check_var,
 452        .fb_set_par     = clcdfb_set_par,
 453        .fb_setcolreg   = clcdfb_setcolreg,
 454        .fb_blank       = clcdfb_blank,
 455        .fb_fillrect    = cfb_fillrect,
 456        .fb_copyarea    = cfb_copyarea,
 457        .fb_imageblit   = cfb_imageblit,
 458        .fb_mmap        = clcdfb_mmap,
 459};
 460
 461static int clcdfb_register(struct clcd_fb *fb)
 462{
 463        int ret;
 464
 465        /*
 466         * ARM PL111 always has IENB at 0x1c; it's only PL110
 467         * which is reversed on some platforms.
 468         */
 469        if (amba_manf(fb->dev) == 0x41 && amba_part(fb->dev) == 0x111) {
 470                fb->off_ienb = CLCD_PL111_IENB;
 471                fb->off_cntl = CLCD_PL111_CNTL;
 472        } else {
 473                if (of_machine_is_compatible("arm,versatile-ab") ||
 474                    of_machine_is_compatible("arm,versatile-pb")) {
 475                        fb->off_ienb = CLCD_PL111_IENB;
 476                        fb->off_cntl = CLCD_PL111_CNTL;
 477                } else {
 478                        fb->off_ienb = CLCD_PL110_IENB;
 479                        fb->off_cntl = CLCD_PL110_CNTL;
 480                }
 481        }
 482
 483        fb->clk = clk_get(&fb->dev->dev, NULL);
 484        if (IS_ERR(fb->clk)) {
 485                ret = PTR_ERR(fb->clk);
 486                goto out;
 487        }
 488
 489        ret = clk_prepare(fb->clk);
 490        if (ret)
 491                goto free_clk;
 492
 493        fb->fb.device           = &fb->dev->dev;
 494
 495        fb->fb.fix.mmio_start   = fb->dev->res.start;
 496        fb->fb.fix.mmio_len     = resource_size(&fb->dev->res);
 497
 498        fb->regs = ioremap(fb->fb.fix.mmio_start, fb->fb.fix.mmio_len);
 499        if (!fb->regs) {
 500                printk(KERN_ERR "CLCD: unable to remap registers\n");
 501                ret = -ENOMEM;
 502                goto clk_unprep;
 503        }
 504
 505        fb->fb.fbops            = &clcdfb_ops;
 506        fb->fb.flags            = FBINFO_FLAG_DEFAULT;
 507        fb->fb.pseudo_palette   = fb->cmap;
 508
 509        strncpy(fb->fb.fix.id, clcd_name, sizeof(fb->fb.fix.id));
 510        fb->fb.fix.type         = FB_TYPE_PACKED_PIXELS;
 511        fb->fb.fix.type_aux     = 0;
 512        fb->fb.fix.xpanstep     = 0;
 513        fb->fb.fix.ypanstep     = 0;
 514        fb->fb.fix.ywrapstep    = 0;
 515        fb->fb.fix.accel        = FB_ACCEL_NONE;
 516
 517        fb->fb.var.xres         = fb->panel->mode.xres;
 518        fb->fb.var.yres         = fb->panel->mode.yres;
 519        fb->fb.var.xres_virtual = fb->panel->mode.xres;
 520        fb->fb.var.yres_virtual = fb->panel->mode.yres;
 521        fb->fb.var.bits_per_pixel = fb->panel->bpp;
 522        fb->fb.var.grayscale    = fb->panel->grayscale;
 523        fb->fb.var.pixclock     = fb->panel->mode.pixclock;
 524        fb->fb.var.left_margin  = fb->panel->mode.left_margin;
 525        fb->fb.var.right_margin = fb->panel->mode.right_margin;
 526        fb->fb.var.upper_margin = fb->panel->mode.upper_margin;
 527        fb->fb.var.lower_margin = fb->panel->mode.lower_margin;
 528        fb->fb.var.hsync_len    = fb->panel->mode.hsync_len;
 529        fb->fb.var.vsync_len    = fb->panel->mode.vsync_len;
 530        fb->fb.var.sync         = fb->panel->mode.sync;
 531        fb->fb.var.vmode        = fb->panel->mode.vmode;
 532        fb->fb.var.activate     = FB_ACTIVATE_NOW;
 533        fb->fb.var.nonstd       = 0;
 534        fb->fb.var.height       = fb->panel->height;
 535        fb->fb.var.width        = fb->panel->width;
 536        fb->fb.var.accel_flags  = 0;
 537
 538        fb->fb.monspecs.hfmin   = 0;
 539        fb->fb.monspecs.hfmax   = 100000;
 540        fb->fb.monspecs.vfmin   = 0;
 541        fb->fb.monspecs.vfmax   = 400;
 542        fb->fb.monspecs.dclkmin = 1000000;
 543        fb->fb.monspecs.dclkmax = 100000000;
 544
 545        /*
 546         * Make sure that the bitfields are set appropriately.
 547         */
 548        clcdfb_set_bitfields(fb, &fb->fb.var);
 549
 550        /*
 551         * Allocate colourmap.
 552         */
 553        ret = fb_alloc_cmap(&fb->fb.cmap, 256, 0);
 554        if (ret)
 555                goto unmap;
 556
 557        /*
 558         * Ensure interrupts are disabled.
 559         */
 560        writel(0, fb->regs + fb->off_ienb);
 561
 562        fb_set_var(&fb->fb, &fb->fb.var);
 563
 564        dev_info(&fb->dev->dev, "%s hardware, %s display\n",
 565                 fb->board->name, fb->panel->mode.name);
 566
 567        ret = register_framebuffer(&fb->fb);
 568        if (ret == 0)
 569                goto out;
 570
 571        printk(KERN_ERR "CLCD: cannot register framebuffer (%d)\n", ret);
 572
 573        fb_dealloc_cmap(&fb->fb.cmap);
 574 unmap:
 575        iounmap(fb->regs);
 576 clk_unprep:
 577        clk_unprepare(fb->clk);
 578 free_clk:
 579        clk_put(fb->clk);
 580 out:
 581        return ret;
 582}
 583
 584#ifdef CONFIG_OF
 585static int clcdfb_of_get_dpi_panel_mode(struct device_node *node,
 586                struct clcd_panel *clcd_panel)
 587{
 588        int err;
 589        struct display_timing timing;
 590        struct videomode video;
 591
 592        err = of_get_display_timing(node, "panel-timing", &timing);
 593        if (err)
 594                return err;
 595
 596        videomode_from_timing(&timing, &video);
 597
 598        err = fb_videomode_from_videomode(&video, &clcd_panel->mode);
 599        if (err)
 600                return err;
 601
 602        /* Set up some inversion flags */
 603        if (timing.flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)
 604                clcd_panel->tim2 |= TIM2_IPC;
 605        else if (!(timing.flags & DISPLAY_FLAGS_PIXDATA_POSEDGE))
 606                /*
 607                 * To preserve backwards compatibility, the IPC (inverted
 608                 * pixel clock) flag needs to be set on any display that
 609                 * doesn't explicitly specify that the pixel clock is
 610                 * active on the negative or positive edge.
 611                 */
 612                clcd_panel->tim2 |= TIM2_IPC;
 613
 614        if (timing.flags & DISPLAY_FLAGS_HSYNC_LOW)
 615                clcd_panel->tim2 |= TIM2_IHS;
 616
 617        if (timing.flags & DISPLAY_FLAGS_VSYNC_LOW)
 618                clcd_panel->tim2 |= TIM2_IVS;
 619
 620        if (timing.flags & DISPLAY_FLAGS_DE_LOW)
 621                clcd_panel->tim2 |= TIM2_IOE;
 622
 623        return 0;
 624}
 625
 626static int clcdfb_snprintf_mode(char *buf, int size, struct fb_videomode *mode)
 627{
 628        return snprintf(buf, size, "%ux%u@%u", mode->xres, mode->yres,
 629                        mode->refresh);
 630}
 631
 632static int clcdfb_of_get_backlight(struct device_node *endpoint,
 633                                   struct clcd_panel *clcd_panel)
 634{
 635        struct device_node *panel;
 636        struct device_node *backlight;
 637
 638        panel = of_graph_get_remote_port_parent(endpoint);
 639        if (!panel)
 640                return -ENODEV;
 641
 642        /* Look up the optional backlight phandle */
 643        backlight = of_parse_phandle(panel, "backlight", 0);
 644        if (backlight) {
 645                clcd_panel->backlight = of_find_backlight_by_node(backlight);
 646                of_node_put(backlight);
 647
 648                if (!clcd_panel->backlight)
 649                        return -EPROBE_DEFER;
 650        }
 651        return 0;
 652}
 653
 654static int clcdfb_of_get_mode(struct device *dev, struct device_node *endpoint,
 655                struct clcd_panel *clcd_panel)
 656{
 657        int err;
 658        struct device_node *panel;
 659        struct fb_videomode *mode;
 660        char *name;
 661        int len;
 662
 663        panel = of_graph_get_remote_port_parent(endpoint);
 664        if (!panel)
 665                return -ENODEV;
 666
 667        /* Only directly connected DPI panels supported for now */
 668        if (of_device_is_compatible(panel, "panel-dpi"))
 669                err = clcdfb_of_get_dpi_panel_mode(panel, clcd_panel);
 670        else
 671                err = -ENOENT;
 672        if (err)
 673                return err;
 674        mode = &clcd_panel->mode;
 675
 676        len = clcdfb_snprintf_mode(NULL, 0, mode);
 677        name = devm_kzalloc(dev, len + 1, GFP_KERNEL);
 678        if (!name)
 679                return -ENOMEM;
 680
 681        clcdfb_snprintf_mode(name, len + 1, mode);
 682        mode->name = name;
 683
 684        return 0;
 685}
 686
 687static int clcdfb_of_init_tft_panel(struct clcd_fb *fb, u32 r0, u32 g0, u32 b0)
 688{
 689        static struct {
 690                unsigned int part;
 691                u32 r0, g0, b0;
 692                u32 caps;
 693        } panels[] = {
 694                { 0x110, 1,  7, 13, CLCD_CAP_5551 },
 695                { 0x110, 0,  8, 16, CLCD_CAP_888 },
 696                { 0x110, 16, 8, 0,  CLCD_CAP_888 },
 697                { 0x111, 4, 14, 20, CLCD_CAP_444 },
 698                { 0x111, 3, 11, 19, CLCD_CAP_444 | CLCD_CAP_5551 },
 699                { 0x111, 3, 10, 19, CLCD_CAP_444 | CLCD_CAP_5551 |
 700                                    CLCD_CAP_565 },
 701                { 0x111, 0,  8, 16, CLCD_CAP_444 | CLCD_CAP_5551 |
 702                                    CLCD_CAP_565 | CLCD_CAP_888 },
 703        };
 704        int i;
 705
 706        /* Bypass pixel clock divider */
 707        fb->panel->tim2 |= TIM2_BCD;
 708
 709        /* TFT display, vert. comp. interrupt at the start of the back porch */
 710        fb->panel->cntl |= CNTL_LCDTFT | CNTL_LCDVCOMP(1);
 711
 712        fb->panel->caps = 0;
 713
 714        /* Match the setup with known variants */
 715        for (i = 0; i < ARRAY_SIZE(panels) && !fb->panel->caps; i++) {
 716                if (amba_part(fb->dev) != panels[i].part)
 717                        continue;
 718                if (g0 != panels[i].g0)
 719                        continue;
 720                if (r0 == panels[i].r0 && b0 == panels[i].b0)
 721                        fb->panel->caps = panels[i].caps;
 722        }
 723
 724        /*
 725         * If we actually physically connected the R lines to B and
 726         * vice versa
 727         */
 728        if (r0 != 0 && b0 == 0)
 729                fb->panel->bgr_connection = true;
 730
 731        if (fb->panel->caps && fb->vendor->st_bitmux_control) {
 732                /*
 733                 * Set up the special bits for the Nomadik control register
 734                 * (other platforms tend to do this through an external
 735                 * register).
 736                 */
 737
 738                /* Offset of the highest used color */
 739                int maxoff = max3(r0, g0, b0);
 740                /* Most significant bit out, highest used bit */
 741                int msb = 0;
 742
 743                if (fb->panel->caps & CLCD_CAP_888) {
 744                        msb = maxoff + 8 - 1;
 745                } else if (fb->panel->caps & CLCD_CAP_565) {
 746                        msb = maxoff + 5 - 1;
 747                        fb->panel->cntl |= CNTL_ST_1XBPP_565;
 748                } else if (fb->panel->caps & CLCD_CAP_5551) {
 749                        msb = maxoff + 5 - 1;
 750                        fb->panel->cntl |= CNTL_ST_1XBPP_5551;
 751                } else if (fb->panel->caps & CLCD_CAP_444) {
 752                        msb = maxoff + 4 - 1;
 753                        fb->panel->cntl |= CNTL_ST_1XBPP_444;
 754                }
 755
 756                /* Send out as many bits as we need */
 757                if (msb > 17)
 758                        fb->panel->cntl |= CNTL_ST_CDWID_24;
 759                else if (msb > 15)
 760                        fb->panel->cntl |= CNTL_ST_CDWID_18;
 761                else if (msb > 11)
 762                        fb->panel->cntl |= CNTL_ST_CDWID_16;
 763                else
 764                        fb->panel->cntl |= CNTL_ST_CDWID_12;
 765        }
 766
 767        return fb->panel->caps ? 0 : -EINVAL;
 768}
 769
 770static int clcdfb_of_init_display(struct clcd_fb *fb)
 771{
 772        struct device_node *endpoint;
 773        int err;
 774        unsigned int bpp;
 775        u32 max_bandwidth;
 776        u32 tft_r0b0g0[3];
 777
 778        fb->panel = devm_kzalloc(&fb->dev->dev, sizeof(*fb->panel), GFP_KERNEL);
 779        if (!fb->panel)
 780                return -ENOMEM;
 781
 782        /*
 783         * Fetch the panel endpoint.
 784         */
 785        endpoint = of_graph_get_next_endpoint(fb->dev->dev.of_node, NULL);
 786        if (!endpoint)
 787                return -ENODEV;
 788
 789        if (fb->vendor->init_panel) {
 790                err = fb->vendor->init_panel(fb, endpoint);
 791                if (err)
 792                        return err;
 793        }
 794
 795        err = clcdfb_of_get_backlight(endpoint, fb->panel);
 796        if (err)
 797                return err;
 798
 799        err = clcdfb_of_get_mode(&fb->dev->dev, endpoint, fb->panel);
 800        if (err)
 801                return err;
 802
 803        err = of_property_read_u32(fb->dev->dev.of_node, "max-memory-bandwidth",
 804                        &max_bandwidth);
 805        if (!err) {
 806                /*
 807                 * max_bandwidth is in bytes per second and pixclock in
 808                 * pico-seconds, so the maximum allowed bits per pixel is
 809                 *   8 * max_bandwidth / (PICOS2KHZ(pixclock) * 1000)
 810                 * Rearrange this calculation to avoid overflow and then ensure
 811                 * result is a valid format.
 812                 */
 813                bpp = max_bandwidth / (1000 / 8)
 814                        / PICOS2KHZ(fb->panel->mode.pixclock);
 815                bpp = rounddown_pow_of_two(bpp);
 816                if (bpp > 32)
 817                        bpp = 32;
 818        } else
 819                bpp = 32;
 820        fb->panel->bpp = bpp;
 821
 822#ifdef CONFIG_CPU_BIG_ENDIAN
 823        fb->panel->cntl |= CNTL_BEBO;
 824#endif
 825        fb->panel->width = -1;
 826        fb->panel->height = -1;
 827
 828        if (of_property_read_u32_array(endpoint,
 829                        "arm,pl11x,tft-r0g0b0-pads",
 830                        tft_r0b0g0, ARRAY_SIZE(tft_r0b0g0)) != 0)
 831                return -ENOENT;
 832
 833        return clcdfb_of_init_tft_panel(fb, tft_r0b0g0[0],
 834                                        tft_r0b0g0[1],  tft_r0b0g0[2]);
 835}
 836
 837static int clcdfb_of_vram_setup(struct clcd_fb *fb)
 838{
 839        int err;
 840        struct device_node *memory;
 841        u64 size;
 842
 843        err = clcdfb_of_init_display(fb);
 844        if (err)
 845                return err;
 846
 847        memory = of_parse_phandle(fb->dev->dev.of_node, "memory-region", 0);
 848        if (!memory)
 849                return -ENODEV;
 850
 851        fb->fb.screen_base = of_iomap(memory, 0);
 852        if (!fb->fb.screen_base)
 853                return -ENOMEM;
 854
 855        fb->fb.fix.smem_start = of_translate_address(memory,
 856                        of_get_address(memory, 0, &size, NULL));
 857        fb->fb.fix.smem_len = size;
 858
 859        return 0;
 860}
 861
 862static int clcdfb_of_vram_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
 863{
 864        unsigned long off, user_size, kernel_size;
 865
 866
 867        off = vma->vm_pgoff << PAGE_SHIFT;
 868        user_size = vma->vm_end - vma->vm_start;
 869        kernel_size = fb->fb.fix.smem_len;
 870
 871        if (off >= kernel_size || user_size > (kernel_size - off))
 872                return -ENXIO;
 873
 874        return remap_pfn_range(vma, vma->vm_start,
 875                        __phys_to_pfn(fb->fb.fix.smem_start) + vma->vm_pgoff,
 876                        user_size,
 877                        pgprot_writecombine(vma->vm_page_prot));
 878}
 879
 880static void clcdfb_of_vram_remove(struct clcd_fb *fb)
 881{
 882        iounmap(fb->fb.screen_base);
 883}
 884
 885static int clcdfb_of_dma_setup(struct clcd_fb *fb)
 886{
 887        unsigned long framesize;
 888        dma_addr_t dma;
 889        int err;
 890
 891        err = clcdfb_of_init_display(fb);
 892        if (err)
 893                return err;
 894
 895        framesize = fb->panel->mode.xres * fb->panel->mode.yres *
 896                        fb->panel->bpp / 8;
 897        fb->fb.screen_base = dma_alloc_coherent(&fb->dev->dev, framesize,
 898                        &dma, GFP_KERNEL);
 899        if (!fb->fb.screen_base)
 900                return -ENOMEM;
 901
 902        fb->fb.fix.smem_start = dma;
 903        fb->fb.fix.smem_len = framesize;
 904
 905        return 0;
 906}
 907
 908static int clcdfb_of_dma_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
 909{
 910        return dma_mmap_wc(&fb->dev->dev, vma, fb->fb.screen_base,
 911                           fb->fb.fix.smem_start, fb->fb.fix.smem_len);
 912}
 913
 914static void clcdfb_of_dma_remove(struct clcd_fb *fb)
 915{
 916        dma_free_coherent(&fb->dev->dev, fb->fb.fix.smem_len,
 917                        fb->fb.screen_base, fb->fb.fix.smem_start);
 918}
 919
 920static struct clcd_board *clcdfb_of_get_board(struct amba_device *dev)
 921{
 922        struct clcd_board *board = devm_kzalloc(&dev->dev, sizeof(*board),
 923                        GFP_KERNEL);
 924        struct device_node *node = dev->dev.of_node;
 925
 926        if (!board)
 927                return NULL;
 928
 929        board->name = of_node_full_name(node);
 930        board->caps = CLCD_CAP_ALL;
 931        board->check = clcdfb_check;
 932        board->decode = clcdfb_decode;
 933        if (of_find_property(node, "memory-region", NULL)) {
 934                board->setup = clcdfb_of_vram_setup;
 935                board->mmap = clcdfb_of_vram_mmap;
 936                board->remove = clcdfb_of_vram_remove;
 937        } else {
 938                board->setup = clcdfb_of_dma_setup;
 939                board->mmap = clcdfb_of_dma_mmap;
 940                board->remove = clcdfb_of_dma_remove;
 941        }
 942
 943        return board;
 944}
 945#else
 946static struct clcd_board *clcdfb_of_get_board(struct amba_device *dev)
 947{
 948        return NULL;
 949}
 950#endif
 951
 952static int clcdfb_probe(struct amba_device *dev, const struct amba_id *id)
 953{
 954        struct clcd_board *board = dev_get_platdata(&dev->dev);
 955        struct clcd_vendor_data *vendor = id->data;
 956        struct clcd_fb *fb;
 957        int ret;
 958
 959        if (!board)
 960                board = clcdfb_of_get_board(dev);
 961
 962        if (!board)
 963                return -EINVAL;
 964
 965        if (vendor->init_board) {
 966                ret = vendor->init_board(dev, board);
 967                if (ret)
 968                        return ret;
 969        }
 970
 971        ret = dma_set_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32));
 972        if (ret)
 973                goto out;
 974
 975        ret = amba_request_regions(dev, NULL);
 976        if (ret) {
 977                printk(KERN_ERR "CLCD: unable to reserve regs region\n");
 978                goto out;
 979        }
 980
 981        fb = kzalloc(sizeof(struct clcd_fb), GFP_KERNEL);
 982        if (!fb) {
 983                printk(KERN_INFO "CLCD: could not allocate new clcd_fb struct\n");
 984                ret = -ENOMEM;
 985                goto free_region;
 986        }
 987
 988        fb->dev = dev;
 989        fb->vendor = vendor;
 990        fb->board = board;
 991
 992        dev_info(&fb->dev->dev, "PL%03x designer %02x rev%u at 0x%08llx\n",
 993                amba_part(dev), amba_manf(dev), amba_rev(dev),
 994                (unsigned long long)dev->res.start);
 995
 996        ret = fb->board->setup(fb);
 997        if (ret)
 998                goto free_fb;
 999
1000        ret = clcdfb_register(fb);
1001        if (ret == 0) {
1002                amba_set_drvdata(dev, fb);
1003                goto out;
1004        }
1005
1006        fb->board->remove(fb);
1007 free_fb:
1008        kfree(fb);
1009 free_region:
1010        amba_release_regions(dev);
1011 out:
1012        return ret;
1013}
1014
1015static int clcdfb_remove(struct amba_device *dev)
1016{
1017        struct clcd_fb *fb = amba_get_drvdata(dev);
1018
1019        clcdfb_disable(fb);
1020        unregister_framebuffer(&fb->fb);
1021        if (fb->fb.cmap.len)
1022                fb_dealloc_cmap(&fb->fb.cmap);
1023        iounmap(fb->regs);
1024        clk_unprepare(fb->clk);
1025        clk_put(fb->clk);
1026
1027        fb->board->remove(fb);
1028
1029        kfree(fb);
1030
1031        amba_release_regions(dev);
1032
1033        return 0;
1034}
1035
1036static struct clcd_vendor_data vendor_arm = {
1037        /* Sets up the versatile board displays */
1038        .init_panel = versatile_clcd_init_panel,
1039};
1040
1041static struct clcd_vendor_data vendor_nomadik = {
1042        .clock_timregs = true,
1043        .packed_24_bit_pixels = true,
1044        .st_bitmux_control = true,
1045        .init_board = nomadik_clcd_init_board,
1046        .init_panel = nomadik_clcd_init_panel,
1047};
1048
1049static struct amba_id clcdfb_id_table[] = {
1050        {
1051                .id     = 0x00041110,
1052                .mask   = 0x000ffffe,
1053                .data   = &vendor_arm,
1054        },
1055        /* ST Electronics Nomadik variant */
1056        {
1057                .id     = 0x00180110,
1058                .mask   = 0x00fffffe,
1059                .data   = &vendor_nomadik,
1060        },
1061        { 0, 0 },
1062};
1063
1064MODULE_DEVICE_TABLE(amba, clcdfb_id_table);
1065
1066static struct amba_driver clcd_driver = {
1067        .drv            = {
1068                .name   = "clcd-pl11x",
1069        },
1070        .probe          = clcdfb_probe,
1071        .remove         = clcdfb_remove,
1072        .id_table       = clcdfb_id_table,
1073};
1074
1075static int __init amba_clcdfb_init(void)
1076{
1077        if (fb_get_options("ambafb", NULL))
1078                return -ENODEV;
1079
1080        return amba_driver_register(&clcd_driver);
1081}
1082
1083module_init(amba_clcdfb_init);
1084
1085static void __exit amba_clcdfb_exit(void)
1086{
1087        amba_driver_unregister(&clcd_driver);
1088}
1089
1090module_exit(amba_clcdfb_exit);
1091
1092MODULE_DESCRIPTION("ARM PrimeCell PL110 CLCD core driver");
1093MODULE_LICENSE("GPL");
1094