linux/drivers/video/sh_mobile_lcdcfb.c
<<
>>
Prefs
   1/*
   2 * SuperH Mobile LCDC Framebuffer
   3 *
   4 * Copyright (c) 2008 Magnus Damm
   5 *
   6 * This file is subject to the terms and conditions of the GNU General Public
   7 * License.  See the file "COPYING" in the main directory of this archive
   8 * for more details.
   9 */
  10
  11#include <linux/kernel.h>
  12#include <linux/init.h>
  13#include <linux/delay.h>
  14#include <linux/mm.h>
  15#include <linux/clk.h>
  16#include <linux/pm_runtime.h>
  17#include <linux/platform_device.h>
  18#include <linux/dma-mapping.h>
  19#include <linux/interrupt.h>
  20#include <linux/videodev2.h>
  21#include <linux/vmalloc.h>
  22#include <linux/ioctl.h>
  23#include <linux/slab.h>
  24#include <linux/console.h>
  25#include <linux/backlight.h>
  26#include <linux/gpio.h>
  27#include <linux/module.h>
  28#include <video/sh_mobile_lcdc.h>
  29#include <video/sh_mobile_meram.h>
  30#include <linux/atomic.h>
  31
  32#include "sh_mobile_lcdcfb.h"
  33
  34#define SIDE_B_OFFSET 0x1000
  35#define MIRROR_OFFSET 0x2000
  36
  37#define MAX_XRES 1920
  38#define MAX_YRES 1080
  39
  40static unsigned long lcdc_offs_mainlcd[NR_CH_REGS] = {
  41        [LDDCKPAT1R] = 0x400,
  42        [LDDCKPAT2R] = 0x404,
  43        [LDMT1R] = 0x418,
  44        [LDMT2R] = 0x41c,
  45        [LDMT3R] = 0x420,
  46        [LDDFR] = 0x424,
  47        [LDSM1R] = 0x428,
  48        [LDSM2R] = 0x42c,
  49        [LDSA1R] = 0x430,
  50        [LDSA2R] = 0x434,
  51        [LDMLSR] = 0x438,
  52        [LDHCNR] = 0x448,
  53        [LDHSYNR] = 0x44c,
  54        [LDVLNR] = 0x450,
  55        [LDVSYNR] = 0x454,
  56        [LDPMR] = 0x460,
  57        [LDHAJR] = 0x4a0,
  58};
  59
  60static unsigned long lcdc_offs_sublcd[NR_CH_REGS] = {
  61        [LDDCKPAT1R] = 0x408,
  62        [LDDCKPAT2R] = 0x40c,
  63        [LDMT1R] = 0x600,
  64        [LDMT2R] = 0x604,
  65        [LDMT3R] = 0x608,
  66        [LDDFR] = 0x60c,
  67        [LDSM1R] = 0x610,
  68        [LDSM2R] = 0x614,
  69        [LDSA1R] = 0x618,
  70        [LDMLSR] = 0x620,
  71        [LDHCNR] = 0x624,
  72        [LDHSYNR] = 0x628,
  73        [LDVLNR] = 0x62c,
  74        [LDVSYNR] = 0x630,
  75        [LDPMR] = 0x63c,
  76};
  77
  78static const struct fb_videomode default_720p = {
  79        .name = "HDMI 720p",
  80        .xres = 1280,
  81        .yres = 720,
  82
  83        .left_margin = 220,
  84        .right_margin = 110,
  85        .hsync_len = 40,
  86
  87        .upper_margin = 20,
  88        .lower_margin = 5,
  89        .vsync_len = 5,
  90
  91        .pixclock = 13468,
  92        .refresh = 60,
  93        .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
  94};
  95
  96struct sh_mobile_lcdc_priv {
  97        void __iomem *base;
  98        int irq;
  99        atomic_t hw_usecnt;
 100        struct device *dev;
 101        struct clk *dot_clk;
 102        unsigned long lddckr;
 103        struct sh_mobile_lcdc_chan ch[2];
 104        struct notifier_block notifier;
 105        int started;
 106        int forced_fourcc; /* 2 channel LCDC must share fourcc setting */
 107        struct sh_mobile_meram_info *meram_dev;
 108};
 109
 110static bool banked(int reg_nr)
 111{
 112        switch (reg_nr) {
 113        case LDMT1R:
 114        case LDMT2R:
 115        case LDMT3R:
 116        case LDDFR:
 117        case LDSM1R:
 118        case LDSA1R:
 119        case LDSA2R:
 120        case LDMLSR:
 121        case LDHCNR:
 122        case LDHSYNR:
 123        case LDVLNR:
 124        case LDVSYNR:
 125                return true;
 126        }
 127        return false;
 128}
 129
 130static void lcdc_write_chan(struct sh_mobile_lcdc_chan *chan,
 131                            int reg_nr, unsigned long data)
 132{
 133        iowrite32(data, chan->lcdc->base + chan->reg_offs[reg_nr]);
 134        if (banked(reg_nr))
 135                iowrite32(data, chan->lcdc->base + chan->reg_offs[reg_nr] +
 136                          SIDE_B_OFFSET);
 137}
 138
 139static void lcdc_write_chan_mirror(struct sh_mobile_lcdc_chan *chan,
 140                            int reg_nr, unsigned long data)
 141{
 142        iowrite32(data, chan->lcdc->base + chan->reg_offs[reg_nr] +
 143                  MIRROR_OFFSET);
 144}
 145
 146static unsigned long lcdc_read_chan(struct sh_mobile_lcdc_chan *chan,
 147                                    int reg_nr)
 148{
 149        return ioread32(chan->lcdc->base + chan->reg_offs[reg_nr]);
 150}
 151
 152static void lcdc_write(struct sh_mobile_lcdc_priv *priv,
 153                       unsigned long reg_offs, unsigned long data)
 154{
 155        iowrite32(data, priv->base + reg_offs);
 156}
 157
 158static unsigned long lcdc_read(struct sh_mobile_lcdc_priv *priv,
 159                               unsigned long reg_offs)
 160{
 161        return ioread32(priv->base + reg_offs);
 162}
 163
 164static void lcdc_wait_bit(struct sh_mobile_lcdc_priv *priv,
 165                          unsigned long reg_offs,
 166                          unsigned long mask, unsigned long until)
 167{
 168        while ((lcdc_read(priv, reg_offs) & mask) != until)
 169                cpu_relax();
 170}
 171
 172static int lcdc_chan_is_sublcd(struct sh_mobile_lcdc_chan *chan)
 173{
 174        return chan->cfg.chan == LCDC_CHAN_SUBLCD;
 175}
 176
 177static void lcdc_sys_write_index(void *handle, unsigned long data)
 178{
 179        struct sh_mobile_lcdc_chan *ch = handle;
 180
 181        lcdc_write(ch->lcdc, _LDDWD0R, data | LDDWDxR_WDACT);
 182        lcdc_wait_bit(ch->lcdc, _LDSR, LDSR_AS, 0);
 183        lcdc_write(ch->lcdc, _LDDWAR, LDDWAR_WA |
 184                   (lcdc_chan_is_sublcd(ch) ? 2 : 0));
 185        lcdc_wait_bit(ch->lcdc, _LDSR, LDSR_AS, 0);
 186}
 187
 188static void lcdc_sys_write_data(void *handle, unsigned long data)
 189{
 190        struct sh_mobile_lcdc_chan *ch = handle;
 191
 192        lcdc_write(ch->lcdc, _LDDWD0R, data | LDDWDxR_WDACT | LDDWDxR_RSW);
 193        lcdc_wait_bit(ch->lcdc, _LDSR, LDSR_AS, 0);
 194        lcdc_write(ch->lcdc, _LDDWAR, LDDWAR_WA |
 195                   (lcdc_chan_is_sublcd(ch) ? 2 : 0));
 196        lcdc_wait_bit(ch->lcdc, _LDSR, LDSR_AS, 0);
 197}
 198
 199static unsigned long lcdc_sys_read_data(void *handle)
 200{
 201        struct sh_mobile_lcdc_chan *ch = handle;
 202
 203        lcdc_write(ch->lcdc, _LDDRDR, LDDRDR_RSR);
 204        lcdc_wait_bit(ch->lcdc, _LDSR, LDSR_AS, 0);
 205        lcdc_write(ch->lcdc, _LDDRAR, LDDRAR_RA |
 206                   (lcdc_chan_is_sublcd(ch) ? 2 : 0));
 207        udelay(1);
 208        lcdc_wait_bit(ch->lcdc, _LDSR, LDSR_AS, 0);
 209
 210        return lcdc_read(ch->lcdc, _LDDRDR) & LDDRDR_DRD_MASK;
 211}
 212
 213struct sh_mobile_lcdc_sys_bus_ops sh_mobile_lcdc_sys_bus_ops = {
 214        lcdc_sys_write_index,
 215        lcdc_sys_write_data,
 216        lcdc_sys_read_data,
 217};
 218
 219static int sh_mobile_format_fourcc(const struct fb_var_screeninfo *var)
 220{
 221        if (var->grayscale > 1)
 222                return var->grayscale;
 223
 224        switch (var->bits_per_pixel) {
 225        case 16:
 226                return V4L2_PIX_FMT_RGB565;
 227        case 24:
 228                return V4L2_PIX_FMT_BGR24;
 229        case 32:
 230                return V4L2_PIX_FMT_BGR32;
 231        default:
 232                return 0;
 233        }
 234}
 235
 236static int sh_mobile_format_is_fourcc(const struct fb_var_screeninfo *var)
 237{
 238        return var->grayscale > 1;
 239}
 240
 241static bool sh_mobile_format_is_yuv(const struct fb_var_screeninfo *var)
 242{
 243        if (var->grayscale <= 1)
 244                return false;
 245
 246        switch (var->grayscale) {
 247        case V4L2_PIX_FMT_NV12:
 248        case V4L2_PIX_FMT_NV21:
 249        case V4L2_PIX_FMT_NV16:
 250        case V4L2_PIX_FMT_NV61:
 251        case V4L2_PIX_FMT_NV24:
 252        case V4L2_PIX_FMT_NV42:
 253                return true;
 254
 255        default:
 256                return false;
 257        }
 258}
 259
 260static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv)
 261{
 262        if (atomic_inc_and_test(&priv->hw_usecnt)) {
 263                if (priv->dot_clk)
 264                        clk_enable(priv->dot_clk);
 265                pm_runtime_get_sync(priv->dev);
 266                if (priv->meram_dev && priv->meram_dev->pdev)
 267                        pm_runtime_get_sync(&priv->meram_dev->pdev->dev);
 268        }
 269}
 270
 271static void sh_mobile_lcdc_clk_off(struct sh_mobile_lcdc_priv *priv)
 272{
 273        if (atomic_sub_return(1, &priv->hw_usecnt) == -1) {
 274                if (priv->meram_dev && priv->meram_dev->pdev)
 275                        pm_runtime_put_sync(&priv->meram_dev->pdev->dev);
 276                pm_runtime_put(priv->dev);
 277                if (priv->dot_clk)
 278                        clk_disable(priv->dot_clk);
 279        }
 280}
 281
 282static int sh_mobile_lcdc_sginit(struct fb_info *info,
 283                                  struct list_head *pagelist)
 284{
 285        struct sh_mobile_lcdc_chan *ch = info->par;
 286        unsigned int nr_pages_max = info->fix.smem_len >> PAGE_SHIFT;
 287        struct page *page;
 288        int nr_pages = 0;
 289
 290        sg_init_table(ch->sglist, nr_pages_max);
 291
 292        list_for_each_entry(page, pagelist, lru)
 293                sg_set_page(&ch->sglist[nr_pages++], page, PAGE_SIZE, 0);
 294
 295        return nr_pages;
 296}
 297
 298static void sh_mobile_lcdc_deferred_io(struct fb_info *info,
 299                                       struct list_head *pagelist)
 300{
 301        struct sh_mobile_lcdc_chan *ch = info->par;
 302        struct sh_mobile_lcdc_board_cfg *bcfg = &ch->cfg.board_cfg;
 303
 304        /* enable clocks before accessing hardware */
 305        sh_mobile_lcdc_clk_on(ch->lcdc);
 306
 307        /*
 308         * It's possible to get here without anything on the pagelist via
 309         * sh_mobile_lcdc_deferred_io_touch() or via a userspace fsync()
 310         * invocation. In the former case, the acceleration routines are
 311         * stepped in to when using the framebuffer console causing the
 312         * workqueue to be scheduled without any dirty pages on the list.
 313         *
 314         * Despite this, a panel update is still needed given that the
 315         * acceleration routines have their own methods for writing in
 316         * that still need to be updated.
 317         *
 318         * The fsync() and empty pagelist case could be optimized for,
 319         * but we don't bother, as any application exhibiting such
 320         * behaviour is fundamentally broken anyways.
 321         */
 322        if (!list_empty(pagelist)) {
 323                unsigned int nr_pages = sh_mobile_lcdc_sginit(info, pagelist);
 324
 325                /* trigger panel update */
 326                dma_map_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE);
 327                if (bcfg->start_transfer)
 328                        bcfg->start_transfer(bcfg->board_data, ch,
 329                                             &sh_mobile_lcdc_sys_bus_ops);
 330                lcdc_write_chan(ch, LDSM2R, LDSM2R_OSTRG);
 331                dma_unmap_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE);
 332        } else {
 333                if (bcfg->start_transfer)
 334                        bcfg->start_transfer(bcfg->board_data, ch,
 335                                             &sh_mobile_lcdc_sys_bus_ops);
 336                lcdc_write_chan(ch, LDSM2R, LDSM2R_OSTRG);
 337        }
 338}
 339
 340static void sh_mobile_lcdc_deferred_io_touch(struct fb_info *info)
 341{
 342        struct fb_deferred_io *fbdefio = info->fbdefio;
 343
 344        if (fbdefio)
 345                schedule_delayed_work(&info->deferred_work, fbdefio->delay);
 346}
 347
 348static irqreturn_t sh_mobile_lcdc_irq(int irq, void *data)
 349{
 350        struct sh_mobile_lcdc_priv *priv = data;
 351        struct sh_mobile_lcdc_chan *ch;
 352        unsigned long ldintr;
 353        int is_sub;
 354        int k;
 355
 356        /* Acknowledge interrupts and disable further VSYNC End IRQs. */
 357        ldintr = lcdc_read(priv, _LDINTR);
 358        lcdc_write(priv, _LDINTR, (ldintr ^ LDINTR_STATUS_MASK) & ~LDINTR_VEE);
 359
 360        /* figure out if this interrupt is for main or sub lcd */
 361        is_sub = (lcdc_read(priv, _LDSR) & LDSR_MSS) ? 1 : 0;
 362
 363        /* wake up channel and disable clocks */
 364        for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
 365                ch = &priv->ch[k];
 366
 367                if (!ch->enabled)
 368                        continue;
 369
 370                /* Frame End */
 371                if (ldintr & LDINTR_FS) {
 372                        if (is_sub == lcdc_chan_is_sublcd(ch)) {
 373                                ch->frame_end = 1;
 374                                wake_up(&ch->frame_end_wait);
 375
 376                                sh_mobile_lcdc_clk_off(priv);
 377                        }
 378                }
 379
 380                /* VSYNC End */
 381                if (ldintr & LDINTR_VES)
 382                        complete(&ch->vsync_completion);
 383        }
 384
 385        return IRQ_HANDLED;
 386}
 387
 388static void sh_mobile_lcdc_start_stop(struct sh_mobile_lcdc_priv *priv,
 389                                      int start)
 390{
 391        unsigned long tmp = lcdc_read(priv, _LDCNT2R);
 392        int k;
 393
 394        /* start or stop the lcdc */
 395        if (start)
 396                lcdc_write(priv, _LDCNT2R, tmp | LDCNT2R_DO);
 397        else
 398                lcdc_write(priv, _LDCNT2R, tmp & ~LDCNT2R_DO);
 399
 400        /* wait until power is applied/stopped on all channels */
 401        for (k = 0; k < ARRAY_SIZE(priv->ch); k++)
 402                if (lcdc_read(priv, _LDCNT2R) & priv->ch[k].enabled)
 403                        while (1) {
 404                                tmp = lcdc_read_chan(&priv->ch[k], LDPMR)
 405                                    & LDPMR_LPS;
 406                                if (start && tmp == LDPMR_LPS)
 407                                        break;
 408                                if (!start && tmp == 0)
 409                                        break;
 410                                cpu_relax();
 411                        }
 412
 413        if (!start)
 414                lcdc_write(priv, _LDDCKSTPR, 1); /* stop dotclock */
 415}
 416
 417static void sh_mobile_lcdc_geometry(struct sh_mobile_lcdc_chan *ch)
 418{
 419        struct fb_var_screeninfo *var = &ch->info->var, *display_var = &ch->display_var;
 420        unsigned long h_total, hsync_pos, display_h_total;
 421        u32 tmp;
 422
 423        tmp = ch->ldmt1r_value;
 424        tmp |= (var->sync & FB_SYNC_VERT_HIGH_ACT) ? 0 : LDMT1R_VPOL;
 425        tmp |= (var->sync & FB_SYNC_HOR_HIGH_ACT) ? 0 : LDMT1R_HPOL;
 426        tmp |= (ch->cfg.flags & LCDC_FLAGS_DWPOL) ? LDMT1R_DWPOL : 0;
 427        tmp |= (ch->cfg.flags & LCDC_FLAGS_DIPOL) ? LDMT1R_DIPOL : 0;
 428        tmp |= (ch->cfg.flags & LCDC_FLAGS_DAPOL) ? LDMT1R_DAPOL : 0;
 429        tmp |= (ch->cfg.flags & LCDC_FLAGS_HSCNT) ? LDMT1R_HSCNT : 0;
 430        tmp |= (ch->cfg.flags & LCDC_FLAGS_DWCNT) ? LDMT1R_DWCNT : 0;
 431        lcdc_write_chan(ch, LDMT1R, tmp);
 432
 433        /* setup SYS bus */
 434        lcdc_write_chan(ch, LDMT2R, ch->cfg.sys_bus_cfg.ldmt2r);
 435        lcdc_write_chan(ch, LDMT3R, ch->cfg.sys_bus_cfg.ldmt3r);
 436
 437        /* horizontal configuration */
 438        h_total = display_var->xres + display_var->hsync_len +
 439                display_var->left_margin + display_var->right_margin;
 440        tmp = h_total / 8; /* HTCN */
 441        tmp |= (min(display_var->xres, var->xres) / 8) << 16; /* HDCN */
 442        lcdc_write_chan(ch, LDHCNR, tmp);
 443
 444        hsync_pos = display_var->xres + display_var->right_margin;
 445        tmp = hsync_pos / 8; /* HSYNP */
 446        tmp |= (display_var->hsync_len / 8) << 16; /* HSYNW */
 447        lcdc_write_chan(ch, LDHSYNR, tmp);
 448
 449        /* vertical configuration */
 450        tmp = display_var->yres + display_var->vsync_len +
 451                display_var->upper_margin + display_var->lower_margin; /* VTLN */
 452        tmp |= min(display_var->yres, var->yres) << 16; /* VDLN */
 453        lcdc_write_chan(ch, LDVLNR, tmp);
 454
 455        tmp = display_var->yres + display_var->lower_margin; /* VSYNP */
 456        tmp |= display_var->vsync_len << 16; /* VSYNW */
 457        lcdc_write_chan(ch, LDVSYNR, tmp);
 458
 459        /* Adjust horizontal synchronisation for HDMI */
 460        display_h_total = display_var->xres + display_var->hsync_len +
 461                display_var->left_margin + display_var->right_margin;
 462        tmp = ((display_var->xres & 7) << 24) |
 463                ((display_h_total & 7) << 16) |
 464                ((display_var->hsync_len & 7) << 8) |
 465                (hsync_pos & 7);
 466        lcdc_write_chan(ch, LDHAJR, tmp);
 467}
 468
 469/*
 470 * __sh_mobile_lcdc_start - Configure and tart the LCDC
 471 * @priv: LCDC device
 472 *
 473 * Configure all enabled channels and start the LCDC device. All external
 474 * devices (clocks, MERAM, panels, ...) are not touched by this function.
 475 */
 476static void __sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
 477{
 478        struct sh_mobile_lcdc_chan *ch;
 479        unsigned long tmp;
 480        int k, m;
 481
 482        /* Enable LCDC channels. Read data from external memory, avoid using the
 483         * BEU for now.
 484         */
 485        lcdc_write(priv, _LDCNT2R, priv->ch[0].enabled | priv->ch[1].enabled);
 486
 487        /* Stop the LCDC first and disable all interrupts. */
 488        sh_mobile_lcdc_start_stop(priv, 0);
 489        lcdc_write(priv, _LDINTR, 0);
 490
 491        /* Configure power supply, dot clocks and start them. */
 492        tmp = priv->lddckr;
 493        for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
 494                ch = &priv->ch[k];
 495                if (!ch->enabled)
 496                        continue;
 497
 498                /* Power supply */
 499                lcdc_write_chan(ch, LDPMR, 0);
 500
 501                m = ch->cfg.clock_divider;
 502                if (!m)
 503                        continue;
 504
 505                /* FIXME: sh7724 can only use 42, 48, 54 and 60 for the divider
 506                 * denominator.
 507                 */
 508                lcdc_write_chan(ch, LDDCKPAT1R, 0);
 509                lcdc_write_chan(ch, LDDCKPAT2R, (1 << (m/2)) - 1);
 510
 511                if (m == 1)
 512                        m = LDDCKR_MOSEL;
 513                tmp |= m << (lcdc_chan_is_sublcd(ch) ? 8 : 0);
 514        }
 515
 516        lcdc_write(priv, _LDDCKR, tmp);
 517        lcdc_write(priv, _LDDCKSTPR, 0);
 518        lcdc_wait_bit(priv, _LDDCKSTPR, ~0, 0);
 519
 520        /* Setup geometry, format, frame buffer memory and operation mode. */
 521        for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
 522                ch = &priv->ch[k];
 523                if (!ch->enabled)
 524                        continue;
 525
 526                sh_mobile_lcdc_geometry(ch);
 527
 528                switch (sh_mobile_format_fourcc(&ch->info->var)) {
 529                case V4L2_PIX_FMT_RGB565:
 530                        tmp = LDDFR_PKF_RGB16;
 531                        break;
 532                case V4L2_PIX_FMT_BGR24:
 533                        tmp = LDDFR_PKF_RGB24;
 534                        break;
 535                case V4L2_PIX_FMT_BGR32:
 536                        tmp = LDDFR_PKF_ARGB32;
 537                        break;
 538                case V4L2_PIX_FMT_NV12:
 539                case V4L2_PIX_FMT_NV21:
 540                        tmp = LDDFR_CC | LDDFR_YF_420;
 541                        break;
 542                case V4L2_PIX_FMT_NV16:
 543                case V4L2_PIX_FMT_NV61:
 544                        tmp = LDDFR_CC | LDDFR_YF_422;
 545                        break;
 546                case V4L2_PIX_FMT_NV24:
 547                case V4L2_PIX_FMT_NV42:
 548                        tmp = LDDFR_CC | LDDFR_YF_444;
 549                        break;
 550                }
 551
 552                if (sh_mobile_format_is_yuv(&ch->info->var)) {
 553                        switch (ch->info->var.colorspace) {
 554                        case V4L2_COLORSPACE_REC709:
 555                                tmp |= LDDFR_CF1;
 556                                break;
 557                        case V4L2_COLORSPACE_JPEG:
 558                                tmp |= LDDFR_CF0;
 559                                break;
 560                        }
 561                }
 562
 563                lcdc_write_chan(ch, LDDFR, tmp);
 564                lcdc_write_chan(ch, LDMLSR, ch->pitch);
 565                lcdc_write_chan(ch, LDSA1R, ch->base_addr_y);
 566                if (sh_mobile_format_is_yuv(&ch->info->var))
 567                        lcdc_write_chan(ch, LDSA2R, ch->base_addr_c);
 568
 569                /* When using deferred I/O mode, configure the LCDC for one-shot
 570                 * operation and enable the frame end interrupt. Otherwise use
 571                 * continuous read mode.
 572                 */
 573                if (ch->ldmt1r_value & LDMT1R_IFM &&
 574                    ch->cfg.sys_bus_cfg.deferred_io_msec) {
 575                        lcdc_write_chan(ch, LDSM1R, LDSM1R_OS);
 576                        lcdc_write(priv, _LDINTR, LDINTR_FE);
 577                } else {
 578                        lcdc_write_chan(ch, LDSM1R, 0);
 579                }
 580        }
 581
 582        /* Word and long word swap. */
 583        switch (sh_mobile_format_fourcc(&priv->ch[0].info->var)) {
 584        case V4L2_PIX_FMT_RGB565:
 585        case V4L2_PIX_FMT_NV21:
 586        case V4L2_PIX_FMT_NV61:
 587        case V4L2_PIX_FMT_NV42:
 588                tmp = LDDDSR_LS | LDDDSR_WS;
 589                break;
 590        case V4L2_PIX_FMT_BGR24:
 591        case V4L2_PIX_FMT_NV12:
 592        case V4L2_PIX_FMT_NV16:
 593        case V4L2_PIX_FMT_NV24:
 594                tmp = LDDDSR_LS | LDDDSR_WS | LDDDSR_BS;
 595                break;
 596        case V4L2_PIX_FMT_BGR32:
 597        default:
 598                tmp = LDDDSR_LS;
 599                break;
 600        }
 601        lcdc_write(priv, _LDDDSR, tmp);
 602
 603        /* Enable the display output. */
 604        lcdc_write(priv, _LDCNT1R, LDCNT1R_DE);
 605        sh_mobile_lcdc_start_stop(priv, 1);
 606        priv->started = 1;
 607}
 608
 609static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
 610{
 611        struct sh_mobile_meram_info *mdev = priv->meram_dev;
 612        struct sh_mobile_lcdc_board_cfg *board_cfg;
 613        struct sh_mobile_lcdc_chan *ch;
 614        unsigned long tmp;
 615        int ret;
 616        int k;
 617
 618        /* enable clocks before accessing the hardware */
 619        for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
 620                if (priv->ch[k].enabled)
 621                        sh_mobile_lcdc_clk_on(priv);
 622        }
 623
 624        /* reset */
 625        lcdc_write(priv, _LDCNT2R, lcdc_read(priv, _LDCNT2R) | LDCNT2R_BR);
 626        lcdc_wait_bit(priv, _LDCNT2R, LDCNT2R_BR, 0);
 627
 628        for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
 629                ch = &priv->ch[k];
 630
 631                if (!ch->enabled)
 632                        continue;
 633
 634                board_cfg = &ch->cfg.board_cfg;
 635                if (board_cfg->setup_sys) {
 636                        ret = board_cfg->setup_sys(board_cfg->board_data, ch,
 637                                                   &sh_mobile_lcdc_sys_bus_ops);
 638                        if (ret)
 639                                return ret;
 640                }
 641        }
 642
 643        /* Compute frame buffer base address and pitch for each channel. */
 644        for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
 645                struct sh_mobile_meram_cfg *cfg;
 646                int pixelformat;
 647
 648                ch = &priv->ch[k];
 649                if (!ch->enabled)
 650                        continue;
 651
 652                ch->base_addr_y = ch->info->fix.smem_start;
 653                ch->base_addr_c = ch->base_addr_y
 654                                + ch->info->var.xres
 655                                * ch->info->var.yres_virtual;
 656                ch->pitch = ch->info->fix.line_length;
 657
 658                /* Enable MERAM if possible. */
 659                cfg = ch->cfg.meram_cfg;
 660                if (mdev == NULL || mdev->ops == NULL || cfg == NULL)
 661                        continue;
 662
 663                /* we need to de-init configured ICBs before we can
 664                 * re-initialize them.
 665                 */
 666                if (ch->meram_enabled) {
 667                        mdev->ops->meram_unregister(mdev, cfg);
 668                        ch->meram_enabled = 0;
 669                }
 670
 671                switch (sh_mobile_format_fourcc(&ch->info->var)) {
 672                case V4L2_PIX_FMT_NV12:
 673                case V4L2_PIX_FMT_NV21:
 674                case V4L2_PIX_FMT_NV16:
 675                case V4L2_PIX_FMT_NV61:
 676                        pixelformat = SH_MOBILE_MERAM_PF_NV;
 677                        break;
 678                case V4L2_PIX_FMT_NV24:
 679                case V4L2_PIX_FMT_NV42:
 680                        pixelformat = SH_MOBILE_MERAM_PF_NV24;
 681                        break;
 682                case V4L2_PIX_FMT_RGB565:
 683                case V4L2_PIX_FMT_BGR24:
 684                case V4L2_PIX_FMT_BGR32:
 685                default:
 686                        pixelformat = SH_MOBILE_MERAM_PF_RGB;
 687                        break;
 688                }
 689
 690                ret = mdev->ops->meram_register(mdev, cfg, ch->pitch,
 691                                        ch->info->var.yres, pixelformat,
 692                                        ch->base_addr_y, ch->base_addr_c,
 693                                        &ch->base_addr_y, &ch->base_addr_c,
 694                                        &ch->pitch);
 695                if (!ret)
 696                        ch->meram_enabled = 1;
 697        }
 698
 699        /* Start the LCDC. */
 700        __sh_mobile_lcdc_start(priv);
 701
 702        /* Setup deferred I/O, tell the board code to enable the panels, and
 703         * turn backlight on.
 704         */
 705        for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
 706                ch = &priv->ch[k];
 707                if (!ch->enabled)
 708                        continue;
 709
 710                tmp = ch->cfg.sys_bus_cfg.deferred_io_msec;
 711                if (ch->ldmt1r_value & LDMT1R_IFM && tmp) {
 712                        ch->defio.deferred_io = sh_mobile_lcdc_deferred_io;
 713                        ch->defio.delay = msecs_to_jiffies(tmp);
 714                        ch->info->fbdefio = &ch->defio;
 715                        fb_deferred_io_init(ch->info);
 716                }
 717
 718                board_cfg = &ch->cfg.board_cfg;
 719                if (board_cfg->display_on && try_module_get(board_cfg->owner)) {
 720                        board_cfg->display_on(board_cfg->board_data, ch->info);
 721                        module_put(board_cfg->owner);
 722                }
 723
 724                if (ch->bl) {
 725                        ch->bl->props.power = FB_BLANK_UNBLANK;
 726                        backlight_update_status(ch->bl);
 727                }
 728        }
 729
 730        return 0;
 731}
 732
 733static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
 734{
 735        struct sh_mobile_lcdc_chan *ch;
 736        struct sh_mobile_lcdc_board_cfg *board_cfg;
 737        int k;
 738
 739        /* clean up deferred io and ask board code to disable panel */
 740        for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
 741                ch = &priv->ch[k];
 742                if (!ch->enabled)
 743                        continue;
 744
 745                /* deferred io mode:
 746                 * flush frame, and wait for frame end interrupt
 747                 * clean up deferred io and enable clock
 748                 */
 749                if (ch->info && ch->info->fbdefio) {
 750                        ch->frame_end = 0;
 751                        schedule_delayed_work(&ch->info->deferred_work, 0);
 752                        wait_event(ch->frame_end_wait, ch->frame_end);
 753                        fb_deferred_io_cleanup(ch->info);
 754                        ch->info->fbdefio = NULL;
 755                        sh_mobile_lcdc_clk_on(priv);
 756                }
 757
 758                if (ch->bl) {
 759                        ch->bl->props.power = FB_BLANK_POWERDOWN;
 760                        backlight_update_status(ch->bl);
 761                }
 762
 763                board_cfg = &ch->cfg.board_cfg;
 764                if (board_cfg->display_off && try_module_get(board_cfg->owner)) {
 765                        board_cfg->display_off(board_cfg->board_data);
 766                        module_put(board_cfg->owner);
 767                }
 768
 769                /* disable the meram */
 770                if (ch->meram_enabled) {
 771                        struct sh_mobile_meram_cfg *cfg;
 772                        struct sh_mobile_meram_info *mdev;
 773                        cfg = ch->cfg.meram_cfg;
 774                        mdev = priv->meram_dev;
 775                        mdev->ops->meram_unregister(mdev, cfg);
 776                        ch->meram_enabled = 0;
 777                }
 778
 779        }
 780
 781        /* stop the lcdc */
 782        if (priv->started) {
 783                sh_mobile_lcdc_start_stop(priv, 0);
 784                priv->started = 0;
 785        }
 786
 787        /* stop clocks */
 788        for (k = 0; k < ARRAY_SIZE(priv->ch); k++)
 789                if (priv->ch[k].enabled)
 790                        sh_mobile_lcdc_clk_off(priv);
 791}
 792
 793static int sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch)
 794{
 795        int interface_type = ch->cfg.interface_type;
 796
 797        switch (interface_type) {
 798        case RGB8:
 799        case RGB9:
 800        case RGB12A:
 801        case RGB12B:
 802        case RGB16:
 803        case RGB18:
 804        case RGB24:
 805        case SYS8A:
 806        case SYS8B:
 807        case SYS8C:
 808        case SYS8D:
 809        case SYS9:
 810        case SYS12:
 811        case SYS16A:
 812        case SYS16B:
 813        case SYS16C:
 814        case SYS18:
 815        case SYS24:
 816                break;
 817        default:
 818                return -EINVAL;
 819        }
 820
 821        /* SUBLCD only supports SYS interface */
 822        if (lcdc_chan_is_sublcd(ch)) {
 823                if (!(interface_type & LDMT1R_IFM))
 824                        return -EINVAL;
 825
 826                interface_type &= ~LDMT1R_IFM;
 827        }
 828
 829        ch->ldmt1r_value = interface_type;
 830        return 0;
 831}
 832
 833static int sh_mobile_lcdc_setup_clocks(struct platform_device *pdev,
 834                                       int clock_source,
 835                                       struct sh_mobile_lcdc_priv *priv)
 836{
 837        char *str;
 838
 839        switch (clock_source) {
 840        case LCDC_CLK_BUS:
 841                str = "bus_clk";
 842                priv->lddckr = LDDCKR_ICKSEL_BUS;
 843                break;
 844        case LCDC_CLK_PERIPHERAL:
 845                str = "peripheral_clk";
 846                priv->lddckr = LDDCKR_ICKSEL_MIPI;
 847                break;
 848        case LCDC_CLK_EXTERNAL:
 849                str = NULL;
 850                priv->lddckr = LDDCKR_ICKSEL_HDMI;
 851                break;
 852        default:
 853                return -EINVAL;
 854        }
 855
 856        if (str) {
 857                priv->dot_clk = clk_get(&pdev->dev, str);
 858                if (IS_ERR(priv->dot_clk)) {
 859                        dev_err(&pdev->dev, "cannot get dot clock %s\n", str);
 860                        return PTR_ERR(priv->dot_clk);
 861                }
 862        }
 863
 864        /* Runtime PM support involves two step for this driver:
 865         * 1) Enable Runtime PM
 866         * 2) Force Runtime PM Resume since hardware is accessed from probe()
 867         */
 868        priv->dev = &pdev->dev;
 869        pm_runtime_enable(priv->dev);
 870        pm_runtime_resume(priv->dev);
 871        return 0;
 872}
 873
 874static int sh_mobile_lcdc_setcolreg(u_int regno,
 875                                    u_int red, u_int green, u_int blue,
 876                                    u_int transp, struct fb_info *info)
 877{
 878        u32 *palette = info->pseudo_palette;
 879
 880        if (regno >= PALETTE_NR)
 881                return -EINVAL;
 882
 883        /* only FB_VISUAL_TRUECOLOR supported */
 884
 885        red >>= 16 - info->var.red.length;
 886        green >>= 16 - info->var.green.length;
 887        blue >>= 16 - info->var.blue.length;
 888        transp >>= 16 - info->var.transp.length;
 889
 890        palette[regno] = (red << info->var.red.offset) |
 891          (green << info->var.green.offset) |
 892          (blue << info->var.blue.offset) |
 893          (transp << info->var.transp.offset);
 894
 895        return 0;
 896}
 897
 898static struct fb_fix_screeninfo sh_mobile_lcdc_fix  = {
 899        .id =           "SH Mobile LCDC",
 900        .type =         FB_TYPE_PACKED_PIXELS,
 901        .visual =       FB_VISUAL_TRUECOLOR,
 902        .accel =        FB_ACCEL_NONE,
 903        .xpanstep =     0,
 904        .ypanstep =     1,
 905        .ywrapstep =    0,
 906        .capabilities = FB_CAP_FOURCC,
 907};
 908
 909static void sh_mobile_lcdc_fillrect(struct fb_info *info,
 910                                    const struct fb_fillrect *rect)
 911{
 912        sys_fillrect(info, rect);
 913        sh_mobile_lcdc_deferred_io_touch(info);
 914}
 915
 916static void sh_mobile_lcdc_copyarea(struct fb_info *info,
 917                                    const struct fb_copyarea *area)
 918{
 919        sys_copyarea(info, area);
 920        sh_mobile_lcdc_deferred_io_touch(info);
 921}
 922
 923static void sh_mobile_lcdc_imageblit(struct fb_info *info,
 924                                     const struct fb_image *image)
 925{
 926        sys_imageblit(info, image);
 927        sh_mobile_lcdc_deferred_io_touch(info);
 928}
 929
 930static int sh_mobile_fb_pan_display(struct fb_var_screeninfo *var,
 931                                     struct fb_info *info)
 932{
 933        struct sh_mobile_lcdc_chan *ch = info->par;
 934        struct sh_mobile_lcdc_priv *priv = ch->lcdc;
 935        unsigned long ldrcntr;
 936        unsigned long new_pan_offset;
 937        unsigned long base_addr_y, base_addr_c;
 938        unsigned long c_offset;
 939        bool yuv = sh_mobile_format_is_yuv(&info->var);
 940
 941        if (!yuv)
 942                new_pan_offset = var->yoffset * info->fix.line_length
 943                               + var->xoffset * (info->var.bits_per_pixel / 8);
 944        else
 945                new_pan_offset = var->yoffset * info->fix.line_length
 946                               + var->xoffset;
 947
 948        if (new_pan_offset == ch->pan_offset)
 949                return 0;       /* No change, do nothing */
 950
 951        ldrcntr = lcdc_read(priv, _LDRCNTR);
 952
 953        /* Set the source address for the next refresh */
 954        base_addr_y = ch->dma_handle + new_pan_offset;
 955        if (yuv) {
 956                /* Set y offset */
 957                c_offset = var->yoffset * info->fix.line_length
 958                         * (info->var.bits_per_pixel - 8) / 8;
 959                base_addr_c = ch->dma_handle
 960                            + info->var.xres * info->var.yres_virtual
 961                            + c_offset;
 962                /* Set x offset */
 963                if (sh_mobile_format_fourcc(&info->var) == V4L2_PIX_FMT_NV24)
 964                        base_addr_c += 2 * var->xoffset;
 965                else
 966                        base_addr_c += var->xoffset;
 967        }
 968
 969        if (ch->meram_enabled) {
 970                struct sh_mobile_meram_cfg *cfg;
 971                struct sh_mobile_meram_info *mdev;
 972                int ret;
 973
 974                cfg = ch->cfg.meram_cfg;
 975                mdev = priv->meram_dev;
 976                ret = mdev->ops->meram_update(mdev, cfg,
 977                                        base_addr_y, base_addr_c,
 978                                        &base_addr_y, &base_addr_c);
 979                if (ret)
 980                        return ret;
 981        }
 982
 983        ch->base_addr_y = base_addr_y;
 984        ch->base_addr_c = base_addr_c;
 985
 986        lcdc_write_chan_mirror(ch, LDSA1R, base_addr_y);
 987        if (yuv)
 988                lcdc_write_chan_mirror(ch, LDSA2R, base_addr_c);
 989
 990        if (lcdc_chan_is_sublcd(ch))
 991                lcdc_write(ch->lcdc, _LDRCNTR, ldrcntr ^ LDRCNTR_SRS);
 992        else
 993                lcdc_write(ch->lcdc, _LDRCNTR, ldrcntr ^ LDRCNTR_MRS);
 994
 995        ch->pan_offset = new_pan_offset;
 996
 997        sh_mobile_lcdc_deferred_io_touch(info);
 998
 999        return 0;
1000}
1001
1002static int sh_mobile_wait_for_vsync(struct fb_info *info)
1003{
1004        struct sh_mobile_lcdc_chan *ch = info->par;
1005        unsigned long ldintr;
1006        int ret;
1007
1008        /* Enable VSync End interrupt and be careful not to acknowledge any
1009         * pending interrupt.
1010         */
1011        ldintr = lcdc_read(ch->lcdc, _LDINTR);
1012        ldintr |= LDINTR_VEE | LDINTR_STATUS_MASK;
1013        lcdc_write(ch->lcdc, _LDINTR, ldintr);
1014
1015        ret = wait_for_completion_interruptible_timeout(&ch->vsync_completion,
1016                                                        msecs_to_jiffies(100));
1017        if (!ret)
1018                return -ETIMEDOUT;
1019
1020        return 0;
1021}
1022
1023static int sh_mobile_ioctl(struct fb_info *info, unsigned int cmd,
1024                       unsigned long arg)
1025{
1026        int retval;
1027
1028        switch (cmd) {
1029        case FBIO_WAITFORVSYNC:
1030                retval = sh_mobile_wait_for_vsync(info);
1031                break;
1032
1033        default:
1034                retval = -ENOIOCTLCMD;
1035                break;
1036        }
1037        return retval;
1038}
1039
1040static void sh_mobile_fb_reconfig(struct fb_info *info)
1041{
1042        struct sh_mobile_lcdc_chan *ch = info->par;
1043        struct fb_videomode mode1, mode2;
1044        struct fb_event event;
1045        int evnt = FB_EVENT_MODE_CHANGE_ALL;
1046
1047        if (ch->use_count > 1 || (ch->use_count == 1 && !info->fbcon_par))
1048                /* More framebuffer users are active */
1049                return;
1050
1051        fb_var_to_videomode(&mode1, &ch->display_var);
1052        fb_var_to_videomode(&mode2, &info->var);
1053
1054        if (fb_mode_is_equal(&mode1, &mode2))
1055                return;
1056
1057        /* Display has been re-plugged, framebuffer is free now, reconfigure */
1058        if (fb_set_var(info, &ch->display_var) < 0)
1059                /* Couldn't reconfigure, hopefully, can continue as before */
1060                return;
1061
1062        /*
1063         * fb_set_var() calls the notifier change internally, only if
1064         * FBINFO_MISC_USEREVENT flag is set. Since we do not want to fake a
1065         * user event, we have to call the chain ourselves.
1066         */
1067        event.info = info;
1068        event.data = &mode1;
1069        fb_notifier_call_chain(evnt, &event);
1070}
1071
1072/*
1073 * Locking: both .fb_release() and .fb_open() are called with info->lock held if
1074 * user == 1, or with console sem held, if user == 0.
1075 */
1076static int sh_mobile_release(struct fb_info *info, int user)
1077{
1078        struct sh_mobile_lcdc_chan *ch = info->par;
1079
1080        mutex_lock(&ch->open_lock);
1081        dev_dbg(info->dev, "%s(): %d users\n", __func__, ch->use_count);
1082
1083        ch->use_count--;
1084
1085        /* Nothing to reconfigure, when called from fbcon */
1086        if (user) {
1087                console_lock();
1088                sh_mobile_fb_reconfig(info);
1089                console_unlock();
1090        }
1091
1092        mutex_unlock(&ch->open_lock);
1093
1094        return 0;
1095}
1096
1097static int sh_mobile_open(struct fb_info *info, int user)
1098{
1099        struct sh_mobile_lcdc_chan *ch = info->par;
1100
1101        mutex_lock(&ch->open_lock);
1102        ch->use_count++;
1103
1104        dev_dbg(info->dev, "%s(): %d users\n", __func__, ch->use_count);
1105        mutex_unlock(&ch->open_lock);
1106
1107        return 0;
1108}
1109
1110static int sh_mobile_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1111{
1112        struct sh_mobile_lcdc_chan *ch = info->par;
1113        struct sh_mobile_lcdc_priv *p = ch->lcdc;
1114        unsigned int best_dist = (unsigned int)-1;
1115        unsigned int best_xres = 0;
1116        unsigned int best_yres = 0;
1117        unsigned int i;
1118
1119        if (var->xres > MAX_XRES || var->yres > MAX_YRES)
1120                return -EINVAL;
1121
1122        /* If board code provides us with a list of available modes, make sure
1123         * we use one of them. Find the mode closest to the requested one. The
1124         * distance between two modes is defined as the size of the
1125         * non-overlapping parts of the two rectangles.
1126         */
1127        for (i = 0; i < ch->cfg.num_cfg; ++i) {
1128                const struct fb_videomode *mode = &ch->cfg.lcd_cfg[i];
1129                unsigned int dist;
1130
1131                /* We can only round up. */
1132                if (var->xres > mode->xres || var->yres > mode->yres)
1133                        continue;
1134
1135                dist = var->xres * var->yres + mode->xres * mode->yres
1136                     - 2 * min(var->xres, mode->xres)
1137                         * min(var->yres, mode->yres);
1138
1139                if (dist < best_dist) {
1140                        best_xres = mode->xres;
1141                        best_yres = mode->yres;
1142                        best_dist = dist;
1143                }
1144        }
1145
1146        /* If no available mode can be used, return an error. */
1147        if (ch->cfg.num_cfg != 0) {
1148                if (best_dist == (unsigned int)-1)
1149                        return -EINVAL;
1150
1151                var->xres = best_xres;
1152                var->yres = best_yres;
1153        }
1154
1155        /* Make sure the virtual resolution is at least as big as the visible
1156         * resolution.
1157         */
1158        if (var->xres_virtual < var->xres)
1159                var->xres_virtual = var->xres;
1160        if (var->yres_virtual < var->yres)
1161                var->yres_virtual = var->yres;
1162
1163        if (sh_mobile_format_is_fourcc(var)) {
1164                switch (var->grayscale) {
1165                case V4L2_PIX_FMT_NV12:
1166                case V4L2_PIX_FMT_NV21:
1167                        var->bits_per_pixel = 12;
1168                        break;
1169                case V4L2_PIX_FMT_RGB565:
1170                case V4L2_PIX_FMT_NV16:
1171                case V4L2_PIX_FMT_NV61:
1172                        var->bits_per_pixel = 16;
1173                        break;
1174                case V4L2_PIX_FMT_BGR24:
1175                case V4L2_PIX_FMT_NV24:
1176                case V4L2_PIX_FMT_NV42:
1177                        var->bits_per_pixel = 24;
1178                        break;
1179                case V4L2_PIX_FMT_BGR32:
1180                        var->bits_per_pixel = 32;
1181                        break;
1182                default:
1183                        return -EINVAL;
1184                }
1185
1186                /* Default to RGB and JPEG color-spaces for RGB and YUV formats
1187                 * respectively.
1188                 */
1189                if (!sh_mobile_format_is_yuv(var))
1190                        var->colorspace = V4L2_COLORSPACE_SRGB;
1191                else if (var->colorspace != V4L2_COLORSPACE_REC709)
1192                        var->colorspace = V4L2_COLORSPACE_JPEG;
1193        } else {
1194                if (var->bits_per_pixel <= 16) {                /* RGB 565 */
1195                        var->bits_per_pixel = 16;
1196                        var->red.offset = 11;
1197                        var->red.length = 5;
1198                        var->green.offset = 5;
1199                        var->green.length = 6;
1200                        var->blue.offset = 0;
1201                        var->blue.length = 5;
1202                        var->transp.offset = 0;
1203                        var->transp.length = 0;
1204                } else if (var->bits_per_pixel <= 24) {         /* RGB 888 */
1205                        var->bits_per_pixel = 24;
1206                        var->red.offset = 16;
1207                        var->red.length = 8;
1208                        var->green.offset = 8;
1209                        var->green.length = 8;
1210                        var->blue.offset = 0;
1211                        var->blue.length = 8;
1212                        var->transp.offset = 0;
1213                        var->transp.length = 0;
1214                } else if (var->bits_per_pixel <= 32) {         /* RGBA 888 */
1215                        var->bits_per_pixel = 32;
1216                        var->red.offset = 16;
1217                        var->red.length = 8;
1218                        var->green.offset = 8;
1219                        var->green.length = 8;
1220                        var->blue.offset = 0;
1221                        var->blue.length = 8;
1222                        var->transp.offset = 24;
1223                        var->transp.length = 8;
1224                } else
1225                        return -EINVAL;
1226
1227                var->red.msb_right = 0;
1228                var->green.msb_right = 0;
1229                var->blue.msb_right = 0;
1230                var->transp.msb_right = 0;
1231        }
1232
1233        /* Make sure we don't exceed our allocated memory. */
1234        if (var->xres_virtual * var->yres_virtual * var->bits_per_pixel / 8 >
1235            info->fix.smem_len)
1236                return -EINVAL;
1237
1238        /* only accept the forced_fourcc for dual channel configurations */
1239        if (p->forced_fourcc &&
1240            p->forced_fourcc != sh_mobile_format_fourcc(var))
1241                return -EINVAL;
1242
1243        return 0;
1244}
1245
1246static int sh_mobile_set_par(struct fb_info *info)
1247{
1248        struct sh_mobile_lcdc_chan *ch = info->par;
1249        u32 line_length = info->fix.line_length;
1250        int ret;
1251
1252        sh_mobile_lcdc_stop(ch->lcdc);
1253
1254        if (sh_mobile_format_is_yuv(&info->var))
1255                info->fix.line_length = info->var.xres;
1256        else
1257                info->fix.line_length = info->var.xres
1258                                      * info->var.bits_per_pixel / 8;
1259
1260        ret = sh_mobile_lcdc_start(ch->lcdc);
1261        if (ret < 0) {
1262                dev_err(info->dev, "%s: unable to restart LCDC\n", __func__);
1263                info->fix.line_length = line_length;
1264        }
1265
1266        if (sh_mobile_format_is_fourcc(&info->var)) {
1267                info->fix.type = FB_TYPE_FOURCC;
1268                info->fix.visual = FB_VISUAL_FOURCC;
1269        } else {
1270                info->fix.type = FB_TYPE_PACKED_PIXELS;
1271                info->fix.visual = FB_VISUAL_TRUECOLOR;
1272        }
1273
1274        return ret;
1275}
1276
1277/*
1278 * Screen blanking. Behavior is as follows:
1279 * FB_BLANK_UNBLANK: screen unblanked, clocks enabled
1280 * FB_BLANK_NORMAL: screen blanked, clocks enabled
1281 * FB_BLANK_VSYNC,
1282 * FB_BLANK_HSYNC,
1283 * FB_BLANK_POWEROFF: screen blanked, clocks disabled
1284 */
1285static int sh_mobile_lcdc_blank(int blank, struct fb_info *info)
1286{
1287        struct sh_mobile_lcdc_chan *ch = info->par;
1288        struct sh_mobile_lcdc_priv *p = ch->lcdc;
1289
1290        /* blank the screen? */
1291        if (blank > FB_BLANK_UNBLANK && ch->blank_status == FB_BLANK_UNBLANK) {
1292                struct fb_fillrect rect = {
1293                        .width = info->var.xres,
1294                        .height = info->var.yres,
1295                };
1296                sh_mobile_lcdc_fillrect(info, &rect);
1297        }
1298        /* turn clocks on? */
1299        if (blank <= FB_BLANK_NORMAL && ch->blank_status > FB_BLANK_NORMAL) {
1300                sh_mobile_lcdc_clk_on(p);
1301        }
1302        /* turn clocks off? */
1303        if (blank > FB_BLANK_NORMAL && ch->blank_status <= FB_BLANK_NORMAL) {
1304                /* make sure the screen is updated with the black fill before
1305                 * switching the clocks off. one vsync is not enough since
1306                 * blanking may occur in the middle of a refresh. deferred io
1307                 * mode will reenable the clocks and update the screen in time,
1308                 * so it does not need this. */
1309                if (!info->fbdefio) {
1310                        sh_mobile_wait_for_vsync(info);
1311                        sh_mobile_wait_for_vsync(info);
1312                }
1313                sh_mobile_lcdc_clk_off(p);
1314        }
1315
1316        ch->blank_status = blank;
1317        return 0;
1318}
1319
1320static struct fb_ops sh_mobile_lcdc_ops = {
1321        .owner          = THIS_MODULE,
1322        .fb_setcolreg   = sh_mobile_lcdc_setcolreg,
1323        .fb_read        = fb_sys_read,
1324        .fb_write       = fb_sys_write,
1325        .fb_fillrect    = sh_mobile_lcdc_fillrect,
1326        .fb_copyarea    = sh_mobile_lcdc_copyarea,
1327        .fb_imageblit   = sh_mobile_lcdc_imageblit,
1328        .fb_blank       = sh_mobile_lcdc_blank,
1329        .fb_pan_display = sh_mobile_fb_pan_display,
1330        .fb_ioctl       = sh_mobile_ioctl,
1331        .fb_open        = sh_mobile_open,
1332        .fb_release     = sh_mobile_release,
1333        .fb_check_var   = sh_mobile_check_var,
1334        .fb_set_par     = sh_mobile_set_par,
1335};
1336
1337static int sh_mobile_lcdc_update_bl(struct backlight_device *bdev)
1338{
1339        struct sh_mobile_lcdc_chan *ch = bl_get_data(bdev);
1340        struct sh_mobile_lcdc_board_cfg *cfg = &ch->cfg.board_cfg;
1341        int brightness = bdev->props.brightness;
1342
1343        if (bdev->props.power != FB_BLANK_UNBLANK ||
1344            bdev->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK))
1345                brightness = 0;
1346
1347        return cfg->set_brightness(cfg->board_data, brightness);
1348}
1349
1350static int sh_mobile_lcdc_get_brightness(struct backlight_device *bdev)
1351{
1352        struct sh_mobile_lcdc_chan *ch = bl_get_data(bdev);
1353        struct sh_mobile_lcdc_board_cfg *cfg = &ch->cfg.board_cfg;
1354
1355        return cfg->get_brightness(cfg->board_data);
1356}
1357
1358static int sh_mobile_lcdc_check_fb(struct backlight_device *bdev,
1359                                   struct fb_info *info)
1360{
1361        return (info->bl_dev == bdev);
1362}
1363
1364static struct backlight_ops sh_mobile_lcdc_bl_ops = {
1365        .options        = BL_CORE_SUSPENDRESUME,
1366        .update_status  = sh_mobile_lcdc_update_bl,
1367        .get_brightness = sh_mobile_lcdc_get_brightness,
1368        .check_fb       = sh_mobile_lcdc_check_fb,
1369};
1370
1371static struct backlight_device *sh_mobile_lcdc_bl_probe(struct device *parent,
1372                                               struct sh_mobile_lcdc_chan *ch)
1373{
1374        struct backlight_device *bl;
1375
1376        bl = backlight_device_register(ch->cfg.bl_info.name, parent, ch,
1377                                       &sh_mobile_lcdc_bl_ops, NULL);
1378        if (IS_ERR(bl)) {
1379                dev_err(parent, "unable to register backlight device: %ld\n",
1380                        PTR_ERR(bl));
1381                return NULL;
1382        }
1383
1384        bl->props.max_brightness = ch->cfg.bl_info.max_brightness;
1385        bl->props.brightness = bl->props.max_brightness;
1386        backlight_update_status(bl);
1387
1388        return bl;
1389}
1390
1391static void sh_mobile_lcdc_bl_remove(struct backlight_device *bdev)
1392{
1393        backlight_device_unregister(bdev);
1394}
1395
1396static int sh_mobile_lcdc_suspend(struct device *dev)
1397{
1398        struct platform_device *pdev = to_platform_device(dev);
1399
1400        sh_mobile_lcdc_stop(platform_get_drvdata(pdev));
1401        return 0;
1402}
1403
1404static int sh_mobile_lcdc_resume(struct device *dev)
1405{
1406        struct platform_device *pdev = to_platform_device(dev);
1407
1408        return sh_mobile_lcdc_start(platform_get_drvdata(pdev));
1409}
1410
1411static int sh_mobile_lcdc_runtime_suspend(struct device *dev)
1412{
1413        struct platform_device *pdev = to_platform_device(dev);
1414        struct sh_mobile_lcdc_priv *priv = platform_get_drvdata(pdev);
1415
1416        /* turn off LCDC hardware */
1417        lcdc_write(priv, _LDCNT1R, 0);
1418
1419        return 0;
1420}
1421
1422static int sh_mobile_lcdc_runtime_resume(struct device *dev)
1423{
1424        struct platform_device *pdev = to_platform_device(dev);
1425        struct sh_mobile_lcdc_priv *priv = platform_get_drvdata(pdev);
1426
1427        __sh_mobile_lcdc_start(priv);
1428
1429        return 0;
1430}
1431
1432static const struct dev_pm_ops sh_mobile_lcdc_dev_pm_ops = {
1433        .suspend = sh_mobile_lcdc_suspend,
1434        .resume = sh_mobile_lcdc_resume,
1435        .runtime_suspend = sh_mobile_lcdc_runtime_suspend,
1436        .runtime_resume = sh_mobile_lcdc_runtime_resume,
1437};
1438
1439/* locking: called with info->lock held */
1440static int sh_mobile_lcdc_notify(struct notifier_block *nb,
1441                                 unsigned long action, void *data)
1442{
1443        struct fb_event *event = data;
1444        struct fb_info *info = event->info;
1445        struct sh_mobile_lcdc_chan *ch = info->par;
1446        struct sh_mobile_lcdc_board_cfg *board_cfg = &ch->cfg.board_cfg;
1447
1448        if (&ch->lcdc->notifier != nb)
1449                return NOTIFY_DONE;
1450
1451        dev_dbg(info->dev, "%s(): action = %lu, data = %p\n",
1452                __func__, action, event->data);
1453
1454        switch(action) {
1455        case FB_EVENT_SUSPEND:
1456                if (board_cfg->display_off && try_module_get(board_cfg->owner)) {
1457                        board_cfg->display_off(board_cfg->board_data);
1458                        module_put(board_cfg->owner);
1459                }
1460                sh_mobile_lcdc_stop(ch->lcdc);
1461                break;
1462        case FB_EVENT_RESUME:
1463                mutex_lock(&ch->open_lock);
1464                sh_mobile_fb_reconfig(info);
1465                mutex_unlock(&ch->open_lock);
1466
1467                /* HDMI must be enabled before LCDC configuration */
1468                if (board_cfg->display_on && try_module_get(board_cfg->owner)) {
1469                        board_cfg->display_on(board_cfg->board_data, info);
1470                        module_put(board_cfg->owner);
1471                }
1472
1473                sh_mobile_lcdc_start(ch->lcdc);
1474        }
1475
1476        return NOTIFY_OK;
1477}
1478
1479static int sh_mobile_lcdc_remove(struct platform_device *pdev)
1480{
1481        struct sh_mobile_lcdc_priv *priv = platform_get_drvdata(pdev);
1482        struct fb_info *info;
1483        int i;
1484
1485        fb_unregister_client(&priv->notifier);
1486
1487        for (i = 0; i < ARRAY_SIZE(priv->ch); i++)
1488                if (priv->ch[i].info && priv->ch[i].info->dev)
1489                        unregister_framebuffer(priv->ch[i].info);
1490
1491        sh_mobile_lcdc_stop(priv);
1492
1493        for (i = 0; i < ARRAY_SIZE(priv->ch); i++) {
1494                info = priv->ch[i].info;
1495
1496                if (!info || !info->device)
1497                        continue;
1498
1499                if (priv->ch[i].sglist)
1500                        vfree(priv->ch[i].sglist);
1501
1502                if (info->screen_base)
1503                        dma_free_coherent(&pdev->dev, info->fix.smem_len,
1504                                          info->screen_base,
1505                                          priv->ch[i].dma_handle);
1506                fb_dealloc_cmap(&info->cmap);
1507                framebuffer_release(info);
1508        }
1509
1510        for (i = 0; i < ARRAY_SIZE(priv->ch); i++) {
1511                if (priv->ch[i].bl)
1512                        sh_mobile_lcdc_bl_remove(priv->ch[i].bl);
1513        }
1514
1515        if (priv->dot_clk)
1516                clk_put(priv->dot_clk);
1517
1518        if (priv->dev)
1519                pm_runtime_disable(priv->dev);
1520
1521        if (priv->base)
1522                iounmap(priv->base);
1523
1524        if (priv->irq)
1525                free_irq(priv->irq, priv);
1526        kfree(priv);
1527        return 0;
1528}
1529
1530static int __devinit sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_chan *ch,
1531                                                 struct device *dev)
1532{
1533        struct sh_mobile_lcdc_chan_cfg *cfg = &ch->cfg;
1534        const struct fb_videomode *max_mode;
1535        const struct fb_videomode *mode;
1536        struct fb_var_screeninfo *var;
1537        struct fb_info *info;
1538        unsigned int max_size;
1539        int num_cfg;
1540        void *buf;
1541        int ret;
1542        int i;
1543
1544        mutex_init(&ch->open_lock);
1545
1546        /* Allocate the frame buffer device. */
1547        ch->info = framebuffer_alloc(0, dev);
1548        if (!ch->info) {
1549                dev_err(dev, "unable to allocate fb_info\n");
1550                return -ENOMEM;
1551        }
1552
1553        info = ch->info;
1554        info->fbops = &sh_mobile_lcdc_ops;
1555        info->par = ch;
1556        info->pseudo_palette = &ch->pseudo_palette;
1557        info->flags = FBINFO_FLAG_DEFAULT;
1558
1559        /* Iterate through the modes to validate them and find the highest
1560         * resolution.
1561         */
1562        max_mode = NULL;
1563        max_size = 0;
1564
1565        for (i = 0, mode = cfg->lcd_cfg; i < cfg->num_cfg; i++, mode++) {
1566                unsigned int size = mode->yres * mode->xres;
1567
1568                /* NV12/NV21 buffers must have even number of lines */
1569                if ((cfg->fourcc == V4L2_PIX_FMT_NV12 ||
1570                     cfg->fourcc == V4L2_PIX_FMT_NV21) && (mode->yres & 0x1)) {
1571                        dev_err(dev, "yres must be multiple of 2 for YCbCr420 "
1572                                "mode.\n");
1573                        return -EINVAL;
1574                }
1575
1576                if (size > max_size) {
1577                        max_mode = mode;
1578                        max_size = size;
1579                }
1580        }
1581
1582        if (!max_size)
1583                max_size = MAX_XRES * MAX_YRES;
1584        else
1585                dev_dbg(dev, "Found largest videomode %ux%u\n",
1586                        max_mode->xres, max_mode->yres);
1587
1588        /* Create the mode list. */
1589        if (cfg->lcd_cfg == NULL) {
1590                mode = &default_720p;
1591                num_cfg = 1;
1592        } else {
1593                mode = cfg->lcd_cfg;
1594                num_cfg = cfg->num_cfg;
1595        }
1596
1597        fb_videomode_to_modelist(mode, num_cfg, &info->modelist);
1598
1599        /* Initialize variable screen information using the first mode as
1600         * default. The default Y virtual resolution is twice the panel size to
1601         * allow for double-buffering.
1602         */
1603        var = &info->var;
1604        fb_videomode_to_var(var, mode);
1605        var->width = cfg->lcd_size_cfg.width;
1606        var->height = cfg->lcd_size_cfg.height;
1607        var->yres_virtual = var->yres * 2;
1608        var->activate = FB_ACTIVATE_NOW;
1609
1610        switch (cfg->fourcc) {
1611        case V4L2_PIX_FMT_RGB565:
1612                var->bits_per_pixel = 16;
1613                break;
1614        case V4L2_PIX_FMT_BGR24:
1615                var->bits_per_pixel = 24;
1616                break;
1617        case V4L2_PIX_FMT_BGR32:
1618                var->bits_per_pixel = 32;
1619                break;
1620        default:
1621                var->grayscale = cfg->fourcc;
1622                break;
1623        }
1624
1625        /* Make sure the memory size check won't fail. smem_len is initialized
1626         * later based on var.
1627         */
1628        info->fix.smem_len = UINT_MAX;
1629        ret = sh_mobile_check_var(var, info);
1630        if (ret)
1631                return ret;
1632
1633        max_size = max_size * var->bits_per_pixel / 8 * 2;
1634
1635        /* Allocate frame buffer memory and color map. */
1636        buf = dma_alloc_coherent(dev, max_size, &ch->dma_handle, GFP_KERNEL);
1637        if (!buf) {
1638                dev_err(dev, "unable to allocate buffer\n");
1639                return -ENOMEM;
1640        }
1641
1642        ret = fb_alloc_cmap(&info->cmap, PALETTE_NR, 0);
1643        if (ret < 0) {
1644                dev_err(dev, "unable to allocate cmap\n");
1645                dma_free_coherent(dev, max_size, buf, ch->dma_handle);
1646                return ret;
1647        }
1648
1649        /* Initialize fixed screen information. Restrict pan to 2 lines steps
1650         * for NV12 and NV21.
1651         */
1652        info->fix = sh_mobile_lcdc_fix;
1653        info->fix.smem_start = ch->dma_handle;
1654        info->fix.smem_len = max_size;
1655        if (cfg->fourcc == V4L2_PIX_FMT_NV12 ||
1656            cfg->fourcc == V4L2_PIX_FMT_NV21)
1657                info->fix.ypanstep = 2;
1658
1659        if (sh_mobile_format_is_yuv(var)) {
1660                info->fix.line_length = var->xres;
1661                info->fix.visual = FB_VISUAL_FOURCC;
1662        } else {
1663                info->fix.line_length = var->xres * var->bits_per_pixel / 8;
1664                info->fix.visual = FB_VISUAL_TRUECOLOR;
1665        }
1666
1667        info->screen_base = buf;
1668        info->device = dev;
1669        ch->display_var = *var;
1670
1671        return 0;
1672}
1673
1674static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
1675{
1676        struct sh_mobile_lcdc_info *pdata = pdev->dev.platform_data;
1677        struct sh_mobile_lcdc_priv *priv;
1678        struct resource *res;
1679        int num_channels;
1680        int error;
1681        int i;
1682
1683        if (!pdata) {
1684                dev_err(&pdev->dev, "no platform data defined\n");
1685                return -EINVAL;
1686        }
1687
1688        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1689        i = platform_get_irq(pdev, 0);
1690        if (!res || i < 0) {
1691                dev_err(&pdev->dev, "cannot get platform resources\n");
1692                return -ENOENT;
1693        }
1694
1695        priv = kzalloc(sizeof(*priv), GFP_KERNEL);
1696        if (!priv) {
1697                dev_err(&pdev->dev, "cannot allocate device data\n");
1698                return -ENOMEM;
1699        }
1700
1701        platform_set_drvdata(pdev, priv);
1702
1703        error = request_irq(i, sh_mobile_lcdc_irq, 0,
1704                            dev_name(&pdev->dev), priv);
1705        if (error) {
1706                dev_err(&pdev->dev, "unable to request irq\n");
1707                goto err1;
1708        }
1709
1710        priv->irq = i;
1711        atomic_set(&priv->hw_usecnt, -1);
1712
1713        for (i = 0, num_channels = 0; i < ARRAY_SIZE(pdata->ch); i++) {
1714                struct sh_mobile_lcdc_chan *ch = priv->ch + num_channels;
1715
1716                ch->lcdc = priv;
1717                memcpy(&ch->cfg, &pdata->ch[i], sizeof(pdata->ch[i]));
1718
1719                error = sh_mobile_lcdc_check_interface(ch);
1720                if (error) {
1721                        dev_err(&pdev->dev, "unsupported interface type\n");
1722                        goto err1;
1723                }
1724                init_waitqueue_head(&ch->frame_end_wait);
1725                init_completion(&ch->vsync_completion);
1726                ch->pan_offset = 0;
1727
1728                /* probe the backlight is there is one defined */
1729                if (ch->cfg.bl_info.max_brightness)
1730                        ch->bl = sh_mobile_lcdc_bl_probe(&pdev->dev, ch);
1731
1732                switch (pdata->ch[i].chan) {
1733                case LCDC_CHAN_MAINLCD:
1734                        ch->enabled = LDCNT2R_ME;
1735                        ch->reg_offs = lcdc_offs_mainlcd;
1736                        num_channels++;
1737                        break;
1738                case LCDC_CHAN_SUBLCD:
1739                        ch->enabled = LDCNT2R_SE;
1740                        ch->reg_offs = lcdc_offs_sublcd;
1741                        num_channels++;
1742                        break;
1743                }
1744        }
1745
1746        if (!num_channels) {
1747                dev_err(&pdev->dev, "no channels defined\n");
1748                error = -EINVAL;
1749                goto err1;
1750        }
1751
1752        /* for dual channel LCDC (MAIN + SUB) force shared format setting */
1753        if (num_channels == 2)
1754                priv->forced_fourcc = pdata->ch[0].fourcc;
1755
1756        priv->base = ioremap_nocache(res->start, resource_size(res));
1757        if (!priv->base)
1758                goto err1;
1759
1760        error = sh_mobile_lcdc_setup_clocks(pdev, pdata->clock_source, priv);
1761        if (error) {
1762                dev_err(&pdev->dev, "unable to setup clocks\n");
1763                goto err1;
1764        }
1765
1766        priv->meram_dev = pdata->meram_dev;
1767
1768        for (i = 0; i < num_channels; i++) {
1769                struct sh_mobile_lcdc_chan *ch = priv->ch + i;
1770
1771                error = sh_mobile_lcdc_channel_init(ch, &pdev->dev);
1772                if (error)
1773                        goto err1;
1774        }
1775
1776        error = sh_mobile_lcdc_start(priv);
1777        if (error) {
1778                dev_err(&pdev->dev, "unable to start hardware\n");
1779                goto err1;
1780        }
1781
1782        for (i = 0; i < num_channels; i++) {
1783                struct sh_mobile_lcdc_chan *ch = priv->ch + i;
1784                struct fb_info *info = ch->info;
1785
1786                if (info->fbdefio) {
1787                        ch->sglist = vmalloc(sizeof(struct scatterlist) *
1788                                        info->fix.smem_len >> PAGE_SHIFT);
1789                        if (!ch->sglist) {
1790                                dev_err(&pdev->dev, "cannot allocate sglist\n");
1791                                goto err1;
1792                        }
1793                }
1794
1795                info->bl_dev = ch->bl;
1796
1797                error = register_framebuffer(info);
1798                if (error < 0)
1799                        goto err1;
1800
1801                dev_info(info->dev, "registered %s/%s as %dx%d %dbpp.\n",
1802                         pdev->name, (ch->cfg.chan == LCDC_CHAN_MAINLCD) ?
1803                         "mainlcd" : "sublcd", info->var.xres, info->var.yres,
1804                         info->var.bits_per_pixel);
1805
1806                /* deferred io mode: disable clock to save power */
1807                if (info->fbdefio || info->state == FBINFO_STATE_SUSPENDED)
1808                        sh_mobile_lcdc_clk_off(priv);
1809        }
1810
1811        /* Failure ignored */
1812        priv->notifier.notifier_call = sh_mobile_lcdc_notify;
1813        fb_register_client(&priv->notifier);
1814
1815        return 0;
1816err1:
1817        sh_mobile_lcdc_remove(pdev);
1818
1819        return error;
1820}
1821
1822static struct platform_driver sh_mobile_lcdc_driver = {
1823        .driver         = {
1824                .name           = "sh_mobile_lcdc_fb",
1825                .owner          = THIS_MODULE,
1826                .pm             = &sh_mobile_lcdc_dev_pm_ops,
1827        },
1828        .probe          = sh_mobile_lcdc_probe,
1829        .remove         = sh_mobile_lcdc_remove,
1830};
1831
1832module_platform_driver(sh_mobile_lcdc_driver);
1833
1834MODULE_DESCRIPTION("SuperH Mobile LCDC Framebuffer driver");
1835MODULE_AUTHOR("Magnus Damm <damm@opensource.se>");
1836MODULE_LICENSE("GPL v2");
1837
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.