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/vmalloc.h>
  21#include <linux/ioctl.h>
  22#include <linux/slab.h>
  23#include <linux/console.h>
  24#include <video/sh_mobile_lcdc.h>
  25#include <asm/atomic.h>
  26
  27#include "sh_mobile_lcdcfb.h"
  28
  29#define SIDE_B_OFFSET 0x1000
  30#define MIRROR_OFFSET 0x2000
  31
  32/* shared registers */
  33#define _LDDCKR 0x410
  34#define _LDDCKSTPR 0x414
  35#define _LDINTR 0x468
  36#define _LDSR 0x46c
  37#define _LDCNT1R 0x470
  38#define _LDCNT2R 0x474
  39#define _LDRCNTR 0x478
  40#define _LDDDSR 0x47c
  41#define _LDDWD0R 0x800
  42#define _LDDRDR 0x840
  43#define _LDDWAR 0x900
  44#define _LDDRAR 0x904
  45
  46/* shared registers and their order for context save/restore */
  47static int lcdc_shared_regs[] = {
  48        _LDDCKR,
  49        _LDDCKSTPR,
  50        _LDINTR,
  51        _LDDDSR,
  52        _LDCNT1R,
  53        _LDCNT2R,
  54};
  55#define NR_SHARED_REGS ARRAY_SIZE(lcdc_shared_regs)
  56
  57#define MAX_XRES 1920
  58#define MAX_YRES 1080
  59
  60static unsigned long lcdc_offs_mainlcd[NR_CH_REGS] = {
  61        [LDDCKPAT1R] = 0x400,
  62        [LDDCKPAT2R] = 0x404,
  63        [LDMT1R] = 0x418,
  64        [LDMT2R] = 0x41c,
  65        [LDMT3R] = 0x420,
  66        [LDDFR] = 0x424,
  67        [LDSM1R] = 0x428,
  68        [LDSM2R] = 0x42c,
  69        [LDSA1R] = 0x430,
  70        [LDMLSR] = 0x438,
  71        [LDHCNR] = 0x448,
  72        [LDHSYNR] = 0x44c,
  73        [LDVLNR] = 0x450,
  74        [LDVSYNR] = 0x454,
  75        [LDPMR] = 0x460,
  76        [LDHAJR] = 0x4a0,
  77};
  78
  79static unsigned long lcdc_offs_sublcd[NR_CH_REGS] = {
  80        [LDDCKPAT1R] = 0x408,
  81        [LDDCKPAT2R] = 0x40c,
  82        [LDMT1R] = 0x600,
  83        [LDMT2R] = 0x604,
  84        [LDMT3R] = 0x608,
  85        [LDDFR] = 0x60c,
  86        [LDSM1R] = 0x610,
  87        [LDSM2R] = 0x614,
  88        [LDSA1R] = 0x618,
  89        [LDMLSR] = 0x620,
  90        [LDHCNR] = 0x624,
  91        [LDHSYNR] = 0x628,
  92        [LDVLNR] = 0x62c,
  93        [LDVSYNR] = 0x630,
  94        [LDPMR] = 0x63c,
  95};
  96
  97#define START_LCDC      0x00000001
  98#define LCDC_RESET      0x00000100
  99#define DISPLAY_BEU     0x00000008
 100#define LCDC_ENABLE     0x00000001
 101#define LDINTR_FE       0x00000400
 102#define LDINTR_VSE      0x00000200
 103#define LDINTR_VEE      0x00000100
 104#define LDINTR_FS       0x00000004
 105#define LDINTR_VSS      0x00000002
 106#define LDINTR_VES      0x00000001
 107#define LDRCNTR_SRS     0x00020000
 108#define LDRCNTR_SRC     0x00010000
 109#define LDRCNTR_MRS     0x00000002
 110#define LDRCNTR_MRC     0x00000001
 111#define LDSR_MRS        0x00000100
 112
 113static const struct fb_videomode default_720p = {
 114        .name = "HDMI 720p",
 115        .xres = 1280,
 116        .yres = 720,
 117
 118        .left_margin = 220,
 119        .right_margin = 110,
 120        .hsync_len = 40,
 121
 122        .upper_margin = 20,
 123        .lower_margin = 5,
 124        .vsync_len = 5,
 125
 126        .pixclock = 13468,
 127        .refresh = 60,
 128        .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
 129};
 130
 131struct sh_mobile_lcdc_priv {
 132        void __iomem *base;
 133        int irq;
 134        atomic_t hw_usecnt;
 135        struct device *dev;
 136        struct clk *dot_clk;
 137        unsigned long lddckr;
 138        struct sh_mobile_lcdc_chan ch[2];
 139        struct notifier_block notifier;
 140        unsigned long saved_shared_regs[NR_SHARED_REGS];
 141        int started;
 142        int forced_bpp; /* 2 channel LCDC must share bpp setting */
 143};
 144
 145static bool banked(int reg_nr)
 146{
 147        switch (reg_nr) {
 148        case LDMT1R:
 149        case LDMT2R:
 150        case LDMT3R:
 151        case LDDFR:
 152        case LDSM1R:
 153        case LDSA1R:
 154        case LDMLSR:
 155        case LDHCNR:
 156        case LDHSYNR:
 157        case LDVLNR:
 158        case LDVSYNR:
 159                return true;
 160        }
 161        return false;
 162}
 163
 164static void lcdc_write_chan(struct sh_mobile_lcdc_chan *chan,
 165                            int reg_nr, unsigned long data)
 166{
 167        iowrite32(data, chan->lcdc->base + chan->reg_offs[reg_nr]);
 168        if (banked(reg_nr))
 169                iowrite32(data, chan->lcdc->base + chan->reg_offs[reg_nr] +
 170                          SIDE_B_OFFSET);
 171}
 172
 173static void lcdc_write_chan_mirror(struct sh_mobile_lcdc_chan *chan,
 174                            int reg_nr, unsigned long data)
 175{
 176        iowrite32(data, chan->lcdc->base + chan->reg_offs[reg_nr] +
 177                  MIRROR_OFFSET);
 178}
 179
 180static unsigned long lcdc_read_chan(struct sh_mobile_lcdc_chan *chan,
 181                                    int reg_nr)
 182{
 183        return ioread32(chan->lcdc->base + chan->reg_offs[reg_nr]);
 184}
 185
 186static void lcdc_write(struct sh_mobile_lcdc_priv *priv,
 187                       unsigned long reg_offs, unsigned long data)
 188{
 189        iowrite32(data, priv->base + reg_offs);
 190}
 191
 192static unsigned long lcdc_read(struct sh_mobile_lcdc_priv *priv,
 193                               unsigned long reg_offs)
 194{
 195        return ioread32(priv->base + reg_offs);
 196}
 197
 198static void lcdc_wait_bit(struct sh_mobile_lcdc_priv *priv,
 199                          unsigned long reg_offs,
 200                          unsigned long mask, unsigned long until)
 201{
 202        while ((lcdc_read(priv, reg_offs) & mask) != until)
 203                cpu_relax();
 204}
 205
 206static int lcdc_chan_is_sublcd(struct sh_mobile_lcdc_chan *chan)
 207{
 208        return chan->cfg.chan == LCDC_CHAN_SUBLCD;
 209}
 210
 211static void lcdc_sys_write_index(void *handle, unsigned long data)
 212{
 213        struct sh_mobile_lcdc_chan *ch = handle;
 214
 215        lcdc_write(ch->lcdc, _LDDWD0R, data | 0x10000000);
 216        lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0);
 217        lcdc_write(ch->lcdc, _LDDWAR, 1 | (lcdc_chan_is_sublcd(ch) ? 2 : 0));
 218        lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0);
 219}
 220
 221static void lcdc_sys_write_data(void *handle, unsigned long data)
 222{
 223        struct sh_mobile_lcdc_chan *ch = handle;
 224
 225        lcdc_write(ch->lcdc, _LDDWD0R, data | 0x11000000);
 226        lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0);
 227        lcdc_write(ch->lcdc, _LDDWAR, 1 | (lcdc_chan_is_sublcd(ch) ? 2 : 0));
 228        lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0);
 229}
 230
 231static unsigned long lcdc_sys_read_data(void *handle)
 232{
 233        struct sh_mobile_lcdc_chan *ch = handle;
 234
 235        lcdc_write(ch->lcdc, _LDDRDR, 0x01000000);
 236        lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0);
 237        lcdc_write(ch->lcdc, _LDDRAR, 1 | (lcdc_chan_is_sublcd(ch) ? 2 : 0));
 238        udelay(1);
 239        lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0);
 240
 241        return lcdc_read(ch->lcdc, _LDDRDR) & 0x3ffff;
 242}
 243
 244struct sh_mobile_lcdc_sys_bus_ops sh_mobile_lcdc_sys_bus_ops = {
 245        lcdc_sys_write_index,
 246        lcdc_sys_write_data,
 247        lcdc_sys_read_data,
 248};
 249
 250static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv)
 251{
 252        if (atomic_inc_and_test(&priv->hw_usecnt)) {
 253                pm_runtime_get_sync(priv->dev);
 254                if (priv->dot_clk)
 255                        clk_enable(priv->dot_clk);
 256        }
 257}
 258
 259static void sh_mobile_lcdc_clk_off(struct sh_mobile_lcdc_priv *priv)
 260{
 261        if (atomic_sub_return(1, &priv->hw_usecnt) == -1) {
 262                if (priv->dot_clk)
 263                        clk_disable(priv->dot_clk);
 264                pm_runtime_put(priv->dev);
 265        }
 266}
 267
 268static int sh_mobile_lcdc_sginit(struct fb_info *info,
 269                                  struct list_head *pagelist)
 270{
 271        struct sh_mobile_lcdc_chan *ch = info->par;
 272        unsigned int nr_pages_max = info->fix.smem_len >> PAGE_SHIFT;
 273        struct page *page;
 274        int nr_pages = 0;
 275
 276        sg_init_table(ch->sglist, nr_pages_max);
 277
 278        list_for_each_entry(page, pagelist, lru)
 279                sg_set_page(&ch->sglist[nr_pages++], page, PAGE_SIZE, 0);
 280
 281        return nr_pages;
 282}
 283
 284static void sh_mobile_lcdc_deferred_io(struct fb_info *info,
 285                                       struct list_head *pagelist)
 286{
 287        struct sh_mobile_lcdc_chan *ch = info->par;
 288        struct sh_mobile_lcdc_board_cfg *bcfg = &ch->cfg.board_cfg;
 289
 290        /* enable clocks before accessing hardware */
 291        sh_mobile_lcdc_clk_on(ch->lcdc);
 292
 293        /*
 294         * It's possible to get here without anything on the pagelist via
 295         * sh_mobile_lcdc_deferred_io_touch() or via a userspace fsync()
 296         * invocation. In the former case, the acceleration routines are
 297         * stepped in to when using the framebuffer console causing the
 298         * workqueue to be scheduled without any dirty pages on the list.
 299         *
 300         * Despite this, a panel update is still needed given that the
 301         * acceleration routines have their own methods for writing in
 302         * that still need to be updated.
 303         *
 304         * The fsync() and empty pagelist case could be optimized for,
 305         * but we don't bother, as any application exhibiting such
 306         * behaviour is fundamentally broken anyways.
 307         */
 308        if (!list_empty(pagelist)) {
 309                unsigned int nr_pages = sh_mobile_lcdc_sginit(info, pagelist);
 310
 311                /* trigger panel update */
 312                dma_map_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE);
 313                if (bcfg->start_transfer)
 314                        bcfg->start_transfer(bcfg->board_data, ch,
 315                                             &sh_mobile_lcdc_sys_bus_ops);
 316                lcdc_write_chan(ch, LDSM2R, 1);
 317                dma_unmap_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE);
 318        } else {
 319                if (bcfg->start_transfer)
 320                        bcfg->start_transfer(bcfg->board_data, ch,
 321                                             &sh_mobile_lcdc_sys_bus_ops);
 322                lcdc_write_chan(ch, LDSM2R, 1);
 323        }
 324}
 325
 326static void sh_mobile_lcdc_deferred_io_touch(struct fb_info *info)
 327{
 328        struct fb_deferred_io *fbdefio = info->fbdefio;
 329
 330        if (fbdefio)
 331                schedule_delayed_work(&info->deferred_work, fbdefio->delay);
 332}
 333
 334static irqreturn_t sh_mobile_lcdc_irq(int irq, void *data)
 335{
 336        struct sh_mobile_lcdc_priv *priv = data;
 337        struct sh_mobile_lcdc_chan *ch;
 338        unsigned long tmp;
 339        unsigned long ldintr;
 340        int is_sub;
 341        int k;
 342
 343        /* acknowledge interrupt */
 344        ldintr = tmp = lcdc_read(priv, _LDINTR);
 345        /*
 346         * disable further VSYNC End IRQs, preserve all other enabled IRQs,
 347         * write 0 to bits 0-6 to ack all triggered IRQs.
 348         */
 349        tmp &= 0xffffff00 & ~LDINTR_VEE;
 350        lcdc_write(priv, _LDINTR, tmp);
 351
 352        /* figure out if this interrupt is for main or sub lcd */
 353        is_sub = (lcdc_read(priv, _LDSR) & (1 << 10)) ? 1 : 0;
 354
 355        /* wake up channel and disable clocks */
 356        for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
 357                ch = &priv->ch[k];
 358
 359                if (!ch->enabled)
 360                        continue;
 361
 362                /* Frame Start */
 363                if (ldintr & LDINTR_FS) {
 364                        if (is_sub == lcdc_chan_is_sublcd(ch)) {
 365                                ch->frame_end = 1;
 366                                wake_up(&ch->frame_end_wait);
 367
 368                                sh_mobile_lcdc_clk_off(priv);
 369                        }
 370                }
 371
 372                /* VSYNC End */
 373                if (ldintr & LDINTR_VES)
 374                        complete(&ch->vsync_completion);
 375        }
 376
 377        return IRQ_HANDLED;
 378}
 379
 380static void sh_mobile_lcdc_start_stop(struct sh_mobile_lcdc_priv *priv,
 381                                      int start)
 382{
 383        unsigned long tmp = lcdc_read(priv, _LDCNT2R);
 384        int k;
 385
 386        /* start or stop the lcdc */
 387        if (start)
 388                lcdc_write(priv, _LDCNT2R, tmp | START_LCDC);
 389        else
 390                lcdc_write(priv, _LDCNT2R, tmp & ~START_LCDC);
 391
 392        /* wait until power is applied/stopped on all channels */
 393        for (k = 0; k < ARRAY_SIZE(priv->ch); k++)
 394                if (lcdc_read(priv, _LDCNT2R) & priv->ch[k].enabled)
 395                        while (1) {
 396                                tmp = lcdc_read_chan(&priv->ch[k], LDPMR) & 3;
 397                                if (start && tmp == 3)
 398                                        break;
 399                                if (!start && tmp == 0)
 400                                        break;
 401                                cpu_relax();
 402                        }
 403
 404        if (!start)
 405                lcdc_write(priv, _LDDCKSTPR, 1); /* stop dotclock */
 406}
 407
 408static void sh_mobile_lcdc_geometry(struct sh_mobile_lcdc_chan *ch)
 409{
 410        struct fb_var_screeninfo *var = &ch->info->var, *display_var = &ch->display_var;
 411        unsigned long h_total, hsync_pos, display_h_total;
 412        u32 tmp;
 413
 414        tmp = ch->ldmt1r_value;
 415        tmp |= (var->sync & FB_SYNC_VERT_HIGH_ACT) ? 0 : 1 << 28;
 416        tmp |= (var->sync & FB_SYNC_HOR_HIGH_ACT) ? 0 : 1 << 27;
 417        tmp |= (ch->cfg.flags & LCDC_FLAGS_DWPOL) ? 1 << 26 : 0;
 418        tmp |= (ch->cfg.flags & LCDC_FLAGS_DIPOL) ? 1 << 25 : 0;
 419        tmp |= (ch->cfg.flags & LCDC_FLAGS_DAPOL) ? 1 << 24 : 0;
 420        tmp |= (ch->cfg.flags & LCDC_FLAGS_HSCNT) ? 1 << 17 : 0;
 421        tmp |= (ch->cfg.flags & LCDC_FLAGS_DWCNT) ? 1 << 16 : 0;
 422        lcdc_write_chan(ch, LDMT1R, tmp);
 423
 424        /* setup SYS bus */
 425        lcdc_write_chan(ch, LDMT2R, ch->cfg.sys_bus_cfg.ldmt2r);
 426        lcdc_write_chan(ch, LDMT3R, ch->cfg.sys_bus_cfg.ldmt3r);
 427
 428        /* horizontal configuration */
 429        h_total = display_var->xres + display_var->hsync_len +
 430                display_var->left_margin + display_var->right_margin;
 431        tmp = h_total / 8; /* HTCN */
 432        tmp |= (min(display_var->xres, var->xres) / 8) << 16; /* HDCN */
 433        lcdc_write_chan(ch, LDHCNR, tmp);
 434
 435        hsync_pos = display_var->xres + display_var->right_margin;
 436        tmp = hsync_pos / 8; /* HSYNP */
 437        tmp |= (display_var->hsync_len / 8) << 16; /* HSYNW */
 438        lcdc_write_chan(ch, LDHSYNR, tmp);
 439
 440        /* vertical configuration */
 441        tmp = display_var->yres + display_var->vsync_len +
 442                display_var->upper_margin + display_var->lower_margin; /* VTLN */
 443        tmp |= min(display_var->yres, var->yres) << 16; /* VDLN */
 444        lcdc_write_chan(ch, LDVLNR, tmp);
 445
 446        tmp = display_var->yres + display_var->lower_margin; /* VSYNP */
 447        tmp |= display_var->vsync_len << 16; /* VSYNW */
 448        lcdc_write_chan(ch, LDVSYNR, tmp);
 449
 450        /* Adjust horizontal synchronisation for HDMI */
 451        display_h_total = display_var->xres + display_var->hsync_len +
 452                display_var->left_margin + display_var->right_margin;
 453        tmp = ((display_var->xres & 7) << 24) |
 454                ((display_h_total & 7) << 16) |
 455                ((display_var->hsync_len & 7) << 8) |
 456                hsync_pos;
 457        lcdc_write_chan(ch, LDHAJR, tmp);
 458}
 459
 460static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
 461{
 462        struct sh_mobile_lcdc_chan *ch;
 463        struct sh_mobile_lcdc_board_cfg *board_cfg;
 464        unsigned long tmp;
 465        int bpp = 0;
 466        int k, m;
 467        int ret = 0;
 468
 469        /* enable clocks before accessing the hardware */
 470        for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
 471                if (priv->ch[k].enabled) {
 472                        sh_mobile_lcdc_clk_on(priv);
 473                        if (!bpp)
 474                                bpp = priv->ch[k].info->var.bits_per_pixel;
 475                }
 476        }
 477
 478        /* reset */
 479        lcdc_write(priv, _LDCNT2R, lcdc_read(priv, _LDCNT2R) | LCDC_RESET);
 480        lcdc_wait_bit(priv, _LDCNT2R, LCDC_RESET, 0);
 481
 482        /* enable LCDC channels */
 483        tmp = lcdc_read(priv, _LDCNT2R);
 484        tmp |= priv->ch[0].enabled;
 485        tmp |= priv->ch[1].enabled;
 486        lcdc_write(priv, _LDCNT2R, tmp);
 487
 488        /* read data from external memory, avoid using the BEU for now */
 489        lcdc_write(priv, _LDCNT2R, lcdc_read(priv, _LDCNT2R) & ~DISPLAY_BEU);
 490
 491        /* stop the lcdc first */
 492        sh_mobile_lcdc_start_stop(priv, 0);
 493
 494        /* configure clocks */
 495        tmp = priv->lddckr;
 496        for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
 497                ch = &priv->ch[k];
 498
 499                if (!priv->ch[k].enabled)
 500                        continue;
 501
 502                m = ch->cfg.clock_divider;
 503                if (!m)
 504                        continue;
 505
 506                if (m == 1)
 507                        m = 1 << 6;
 508                tmp |= m << (lcdc_chan_is_sublcd(ch) ? 8 : 0);
 509
 510                /* FIXME: sh7724 can only use 42, 48, 54 and 60 for the divider denominator */
 511                lcdc_write_chan(ch, LDDCKPAT1R, 0);
 512                lcdc_write_chan(ch, LDDCKPAT2R, (1 << (m/2)) - 1);
 513        }
 514
 515        lcdc_write(priv, _LDDCKR, tmp);
 516
 517        /* start dotclock again */
 518        lcdc_write(priv, _LDDCKSTPR, 0);
 519        lcdc_wait_bit(priv, _LDDCKSTPR, ~0, 0);
 520
 521        /* interrupts are disabled to begin with */
 522        lcdc_write(priv, _LDINTR, 0);
 523
 524        for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
 525                ch = &priv->ch[k];
 526
 527                if (!ch->enabled)
 528                        continue;
 529
 530                sh_mobile_lcdc_geometry(ch);
 531
 532                /* power supply */
 533                lcdc_write_chan(ch, LDPMR, 0);
 534
 535                board_cfg = &ch->cfg.board_cfg;
 536                if (board_cfg->setup_sys)
 537                        ret = board_cfg->setup_sys(board_cfg->board_data, ch,
 538                                                   &sh_mobile_lcdc_sys_bus_ops);
 539                if (ret)
 540                        return ret;
 541        }
 542
 543        /* word and long word swap */
 544        switch (bpp) {
 545        case 16:
 546                lcdc_write(priv, _LDDDSR, lcdc_read(priv, _LDDDSR) | 6);
 547                break;
 548        case 24:
 549                lcdc_write(priv, _LDDDSR, lcdc_read(priv, _LDDDSR) | 7);
 550                break;
 551        case 32:
 552                lcdc_write(priv, _LDDDSR, lcdc_read(priv, _LDDDSR) | 4);
 553                break;
 554        }
 555
 556        for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
 557                ch = &priv->ch[k];
 558
 559                if (!priv->ch[k].enabled)
 560                        continue;
 561
 562                /* set bpp format in PKF[4:0] */
 563                tmp = lcdc_read_chan(ch, LDDFR);
 564                tmp &= ~0x0001001f;
 565                switch (ch->info->var.bits_per_pixel) {
 566                case 16:
 567                        tmp |= 0x03;
 568                        break;
 569                case 24:
 570                        tmp |= 0x0b;
 571                        break;
 572                case 32:
 573                        break;
 574                }
 575                lcdc_write_chan(ch, LDDFR, tmp);
 576
 577                /* point out our frame buffer */
 578                lcdc_write_chan(ch, LDSA1R, ch->info->fix.smem_start);
 579
 580                /* set line size */
 581                lcdc_write_chan(ch, LDMLSR, ch->info->fix.line_length);
 582
 583                /* setup deferred io if SYS bus */
 584                tmp = ch->cfg.sys_bus_cfg.deferred_io_msec;
 585                if (ch->ldmt1r_value & (1 << 12) && tmp) {
 586                        ch->defio.deferred_io = sh_mobile_lcdc_deferred_io;
 587                        ch->defio.delay = msecs_to_jiffies(tmp);
 588                        ch->info->fbdefio = &ch->defio;
 589                        fb_deferred_io_init(ch->info);
 590
 591                        /* one-shot mode */
 592                        lcdc_write_chan(ch, LDSM1R, 1);
 593
 594                        /* enable "Frame End Interrupt Enable" bit */
 595                        lcdc_write(priv, _LDINTR, LDINTR_FE);
 596
 597                } else {
 598                        /* continuous read mode */
 599                        lcdc_write_chan(ch, LDSM1R, 0);
 600                }
 601        }
 602
 603        /* display output */
 604        lcdc_write(priv, _LDCNT1R, LCDC_ENABLE);
 605
 606        /* start the lcdc */
 607        sh_mobile_lcdc_start_stop(priv, 1);
 608        priv->started = 1;
 609
 610        /* tell the board code to enable the panel */
 611        for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
 612                ch = &priv->ch[k];
 613                if (!ch->enabled)
 614                        continue;
 615
 616                board_cfg = &ch->cfg.board_cfg;
 617                if (try_module_get(board_cfg->owner) && board_cfg->display_on) {
 618                        board_cfg->display_on(board_cfg->board_data, ch->info);
 619                        module_put(board_cfg->owner);
 620                }
 621        }
 622
 623        return 0;
 624}
 625
 626static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
 627{
 628        struct sh_mobile_lcdc_chan *ch;
 629        struct sh_mobile_lcdc_board_cfg *board_cfg;
 630        int k;
 631
 632        /* clean up deferred io and ask board code to disable panel */
 633        for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
 634                ch = &priv->ch[k];
 635                if (!ch->enabled)
 636                        continue;
 637
 638                /* deferred io mode:
 639                 * flush frame, and wait for frame end interrupt
 640                 * clean up deferred io and enable clock
 641                 */
 642                if (ch->info && ch->info->fbdefio) {
 643                        ch->frame_end = 0;
 644                        schedule_delayed_work(&ch->info->deferred_work, 0);
 645                        wait_event(ch->frame_end_wait, ch->frame_end);
 646                        fb_deferred_io_cleanup(ch->info);
 647                        ch->info->fbdefio = NULL;
 648                        sh_mobile_lcdc_clk_on(priv);
 649                }
 650
 651                board_cfg = &ch->cfg.board_cfg;
 652                if (try_module_get(board_cfg->owner) && board_cfg->display_off) {
 653                        board_cfg->display_off(board_cfg->board_data);
 654                        module_put(board_cfg->owner);
 655                }
 656        }
 657
 658        /* stop the lcdc */
 659        if (priv->started) {
 660                sh_mobile_lcdc_start_stop(priv, 0);
 661                priv->started = 0;
 662        }
 663
 664        /* stop clocks */
 665        for (k = 0; k < ARRAY_SIZE(priv->ch); k++)
 666                if (priv->ch[k].enabled)
 667                        sh_mobile_lcdc_clk_off(priv);
 668}
 669
 670static int sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch)
 671{
 672        int ifm, miftyp;
 673
 674        switch (ch->cfg.interface_type) {
 675        case RGB8: ifm = 0; miftyp = 0; break;
 676        case RGB9: ifm = 0; miftyp = 4; break;
 677        case RGB12A: ifm = 0; miftyp = 5; break;
 678        case RGB12B: ifm = 0; miftyp = 6; break;
 679        case RGB16: ifm = 0; miftyp = 7; break;
 680        case RGB18: ifm = 0; miftyp = 10; break;
 681        case RGB24: ifm = 0; miftyp = 11; break;
 682        case SYS8A: ifm = 1; miftyp = 0; break;
 683        case SYS8B: ifm = 1; miftyp = 1; break;
 684        case SYS8C: ifm = 1; miftyp = 2; break;
 685        case SYS8D: ifm = 1; miftyp = 3; break;
 686        case SYS9: ifm = 1; miftyp = 4; break;
 687        case SYS12: ifm = 1; miftyp = 5; break;
 688        case SYS16A: ifm = 1; miftyp = 7; break;
 689        case SYS16B: ifm = 1; miftyp = 8; break;
 690        case SYS16C: ifm = 1; miftyp = 9; break;
 691        case SYS18: ifm = 1; miftyp = 10; break;
 692        case SYS24: ifm = 1; miftyp = 11; break;
 693        default: goto bad;
 694        }
 695
 696        /* SUBLCD only supports SYS interface */
 697        if (lcdc_chan_is_sublcd(ch)) {
 698                if (ifm == 0)
 699                        goto bad;
 700                else
 701                        ifm = 0;
 702        }
 703
 704        ch->ldmt1r_value = (ifm << 12) | miftyp;
 705        return 0;
 706 bad:
 707        return -EINVAL;
 708}
 709
 710static int sh_mobile_lcdc_setup_clocks(struct platform_device *pdev,
 711                                       int clock_source,
 712                                       struct sh_mobile_lcdc_priv *priv)
 713{
 714        char *str;
 715        int icksel;
 716
 717        switch (clock_source) {
 718        case LCDC_CLK_BUS: str = "bus_clk"; icksel = 0; break;
 719        case LCDC_CLK_PERIPHERAL: str = "peripheral_clk"; icksel = 1; break;
 720        case LCDC_CLK_EXTERNAL: str = NULL; icksel = 2; break;
 721        default:
 722                return -EINVAL;
 723        }
 724
 725        priv->lddckr = icksel << 16;
 726
 727        if (str) {
 728                priv->dot_clk = clk_get(&pdev->dev, str);
 729                if (IS_ERR(priv->dot_clk)) {
 730                        dev_err(&pdev->dev, "cannot get dot clock %s\n", str);
 731                        return PTR_ERR(priv->dot_clk);
 732                }
 733        }
 734
 735        /* Runtime PM support involves two step for this driver:
 736         * 1) Enable Runtime PM
 737         * 2) Force Runtime PM Resume since hardware is accessed from probe()
 738         */
 739        priv->dev = &pdev->dev;
 740        pm_runtime_enable(priv->dev);
 741        pm_runtime_resume(priv->dev);
 742        return 0;
 743}
 744
 745static int sh_mobile_lcdc_setcolreg(u_int regno,
 746                                    u_int red, u_int green, u_int blue,
 747                                    u_int transp, struct fb_info *info)
 748{
 749        u32 *palette = info->pseudo_palette;
 750
 751        if (regno >= PALETTE_NR)
 752                return -EINVAL;
 753
 754        /* only FB_VISUAL_TRUECOLOR supported */
 755
 756        red >>= 16 - info->var.red.length;
 757        green >>= 16 - info->var.green.length;
 758        blue >>= 16 - info->var.blue.length;
 759        transp >>= 16 - info->var.transp.length;
 760
 761        palette[regno] = (red << info->var.red.offset) |
 762          (green << info->var.green.offset) |
 763          (blue << info->var.blue.offset) |
 764          (transp << info->var.transp.offset);
 765
 766        return 0;
 767}
 768
 769static struct fb_fix_screeninfo sh_mobile_lcdc_fix  = {
 770        .id =           "SH Mobile LCDC",
 771        .type =         FB_TYPE_PACKED_PIXELS,
 772        .visual =       FB_VISUAL_TRUECOLOR,
 773        .accel =        FB_ACCEL_NONE,
 774        .xpanstep =     0,
 775        .ypanstep =     1,
 776        .ywrapstep =    0,
 777};
 778
 779static void sh_mobile_lcdc_fillrect(struct fb_info *info,
 780                                    const struct fb_fillrect *rect)
 781{
 782        sys_fillrect(info, rect);
 783        sh_mobile_lcdc_deferred_io_touch(info);
 784}
 785
 786static void sh_mobile_lcdc_copyarea(struct fb_info *info,
 787                                    const struct fb_copyarea *area)
 788{
 789        sys_copyarea(info, area);
 790        sh_mobile_lcdc_deferred_io_touch(info);
 791}
 792
 793static void sh_mobile_lcdc_imageblit(struct fb_info *info,
 794                                     const struct fb_image *image)
 795{
 796        sys_imageblit(info, image);
 797        sh_mobile_lcdc_deferred_io_touch(info);
 798}
 799
 800static int sh_mobile_fb_pan_display(struct fb_var_screeninfo *var,
 801                                     struct fb_info *info)
 802{
 803        struct sh_mobile_lcdc_chan *ch = info->par;
 804        struct sh_mobile_lcdc_priv *priv = ch->lcdc;
 805        unsigned long ldrcntr;
 806        unsigned long new_pan_offset;
 807
 808        new_pan_offset = (var->yoffset * info->fix.line_length) +
 809                (var->xoffset * (info->var.bits_per_pixel / 8));
 810
 811        if (new_pan_offset == ch->pan_offset)
 812                return 0;       /* No change, do nothing */
 813
 814        ldrcntr = lcdc_read(priv, _LDRCNTR);
 815
 816        /* Set the source address for the next refresh */
 817        lcdc_write_chan_mirror(ch, LDSA1R, ch->dma_handle + new_pan_offset);
 818        if (lcdc_chan_is_sublcd(ch))
 819                lcdc_write(ch->lcdc, _LDRCNTR, ldrcntr ^ LDRCNTR_SRS);
 820        else
 821                lcdc_write(ch->lcdc, _LDRCNTR, ldrcntr ^ LDRCNTR_MRS);
 822
 823        ch->pan_offset = new_pan_offset;
 824
 825        sh_mobile_lcdc_deferred_io_touch(info);
 826
 827        return 0;
 828}
 829
 830static int sh_mobile_wait_for_vsync(struct fb_info *info)
 831{
 832        struct sh_mobile_lcdc_chan *ch = info->par;
 833        unsigned long ldintr;
 834        int ret;
 835
 836        /* Enable VSync End interrupt */
 837        ldintr = lcdc_read(ch->lcdc, _LDINTR);
 838        ldintr |= LDINTR_VEE;
 839        lcdc_write(ch->lcdc, _LDINTR, ldintr);
 840
 841        ret = wait_for_completion_interruptible_timeout(&ch->vsync_completion,
 842                                                        msecs_to_jiffies(100));
 843        if (!ret)
 844                return -ETIMEDOUT;
 845
 846        return 0;
 847}
 848
 849static int sh_mobile_ioctl(struct fb_info *info, unsigned int cmd,
 850                       unsigned long arg)
 851{
 852        int retval;
 853
 854        switch (cmd) {
 855        case FBIO_WAITFORVSYNC:
 856                retval = sh_mobile_wait_for_vsync(info);
 857                break;
 858
 859        default:
 860                retval = -ENOIOCTLCMD;
 861                break;
 862        }
 863        return retval;
 864}
 865
 866static void sh_mobile_fb_reconfig(struct fb_info *info)
 867{
 868        struct sh_mobile_lcdc_chan *ch = info->par;
 869        struct fb_videomode mode1, mode2;
 870        struct fb_event event;
 871        int evnt = FB_EVENT_MODE_CHANGE_ALL;
 872
 873        if (ch->use_count > 1 || (ch->use_count == 1 && !info->fbcon_par))
 874                /* More framebuffer users are active */
 875                return;
 876
 877        fb_var_to_videomode(&mode1, &ch->display_var);
 878        fb_var_to_videomode(&mode2, &info->var);
 879
 880        if (fb_mode_is_equal(&mode1, &mode2))
 881                return;
 882
 883        /* Display has been re-plugged, framebuffer is free now, reconfigure */
 884        if (fb_set_var(info, &ch->display_var) < 0)
 885                /* Couldn't reconfigure, hopefully, can continue as before */
 886                return;
 887
 888        info->fix.line_length = mode1.xres * (ch->cfg.bpp / 8);
 889
 890        /*
 891         * fb_set_var() calls the notifier change internally, only if
 892         * FBINFO_MISC_USEREVENT flag is set. Since we do not want to fake a
 893         * user event, we have to call the chain ourselves.
 894         */
 895        event.info = info;
 896        event.data = &mode1;
 897        fb_notifier_call_chain(evnt, &event);
 898}
 899
 900/*
 901 * Locking: both .fb_release() and .fb_open() are called with info->lock held if
 902 * user == 1, or with console sem held, if user == 0.
 903 */
 904static int sh_mobile_release(struct fb_info *info, int user)
 905{
 906        struct sh_mobile_lcdc_chan *ch = info->par;
 907
 908        mutex_lock(&ch->open_lock);
 909        dev_dbg(info->dev, "%s(): %d users\n", __func__, ch->use_count);
 910
 911        ch->use_count--;
 912
 913        /* Nothing to reconfigure, when called from fbcon */
 914        if (user) {
 915                console_lock();
 916                sh_mobile_fb_reconfig(info);
 917                console_unlock();
 918        }
 919
 920        mutex_unlock(&ch->open_lock);
 921
 922        return 0;
 923}
 924
 925static int sh_mobile_open(struct fb_info *info, int user)
 926{
 927        struct sh_mobile_lcdc_chan *ch = info->par;
 928
 929        mutex_lock(&ch->open_lock);
 930        ch->use_count++;
 931
 932        dev_dbg(info->dev, "%s(): %d users\n", __func__, ch->use_count);
 933        mutex_unlock(&ch->open_lock);
 934
 935        return 0;
 936}
 937
 938static int sh_mobile_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 939{
 940        struct sh_mobile_lcdc_chan *ch = info->par;
 941        struct sh_mobile_lcdc_priv *p = ch->lcdc;
 942
 943        if (var->xres > MAX_XRES || var->yres > MAX_YRES ||
 944            var->xres * var->yres * (ch->cfg.bpp / 8) * 2 > info->fix.smem_len) {
 945                dev_warn(info->dev, "Invalid info: %u-%u-%u-%u x %u-%u-%u-%u @ %lukHz!\n",
 946                         var->left_margin, var->xres, var->right_margin, var->hsync_len,
 947                         var->upper_margin, var->yres, var->lower_margin, var->vsync_len,
 948                         PICOS2KHZ(var->pixclock));
 949                return -EINVAL;
 950        }
 951
 952        /* only accept the forced_bpp for dual channel configurations */
 953        if (p->forced_bpp && p->forced_bpp != var->bits_per_pixel)
 954                return -EINVAL;
 955
 956        switch (var->bits_per_pixel) {
 957        case 16: /* PKF[4:0] = 00011 - RGB 565 */
 958        case 24: /* PKF[4:0] = 01011 - RGB 888 */
 959        case 32: /* PKF[4:0] = 00000 - RGBA 888 */
 960                break;
 961        default:
 962                return -EINVAL;
 963        }
 964
 965        return 0;
 966}
 967
 968static struct fb_ops sh_mobile_lcdc_ops = {
 969        .owner          = THIS_MODULE,
 970        .fb_setcolreg   = sh_mobile_lcdc_setcolreg,
 971        .fb_read        = fb_sys_read,
 972        .fb_write       = fb_sys_write,
 973        .fb_fillrect    = sh_mobile_lcdc_fillrect,
 974        .fb_copyarea    = sh_mobile_lcdc_copyarea,
 975        .fb_imageblit   = sh_mobile_lcdc_imageblit,
 976        .fb_pan_display = sh_mobile_fb_pan_display,
 977        .fb_ioctl       = sh_mobile_ioctl,
 978        .fb_open        = sh_mobile_open,
 979        .fb_release     = sh_mobile_release,
 980        .fb_check_var   = sh_mobile_check_var,
 981};
 982
 983static int sh_mobile_lcdc_set_bpp(struct fb_var_screeninfo *var, int bpp)
 984{
 985        switch (bpp) {
 986        case 16: /* PKF[4:0] = 00011 - RGB 565 */
 987                var->red.offset = 11;
 988                var->red.length = 5;
 989                var->green.offset = 5;
 990                var->green.length = 6;
 991                var->blue.offset = 0;
 992                var->blue.length = 5;
 993                var->transp.offset = 0;
 994                var->transp.length = 0;
 995                break;
 996
 997        case 24: /* PKF[4:0] = 01011 - RGB 888 */
 998                var->red.offset = 16;
 999                var->red.length = 8;
1000                var->green.offset = 8;
1001                var->green.length = 8;
1002                var->blue.offset = 0;
1003                var->blue.length = 8;
1004                var->transp.offset = 0;
1005                var->transp.length = 0;
1006                break;
1007
1008        case 32: /* PKF[4:0] = 00000 - RGBA 888 */
1009                var->red.offset = 16;
1010                var->red.length = 8;
1011                var->green.offset = 8;
1012                var->green.length = 8;
1013                var->blue.offset = 0;
1014                var->blue.length = 8;
1015                var->transp.offset = 24;
1016                var->transp.length = 8;
1017                break;
1018        default:
1019                return -EINVAL;
1020        }
1021        var->bits_per_pixel = bpp;
1022        var->red.msb_right = 0;
1023        var->green.msb_right = 0;
1024        var->blue.msb_right = 0;
1025        var->transp.msb_right = 0;
1026        return 0;
1027}
1028
1029static int sh_mobile_lcdc_suspend(struct device *dev)
1030{
1031        struct platform_device *pdev = to_platform_device(dev);
1032
1033        sh_mobile_lcdc_stop(platform_get_drvdata(pdev));
1034        return 0;
1035}
1036
1037static int sh_mobile_lcdc_resume(struct device *dev)
1038{
1039        struct platform_device *pdev = to_platform_device(dev);
1040
1041        return sh_mobile_lcdc_start(platform_get_drvdata(pdev));
1042}
1043
1044static int sh_mobile_lcdc_runtime_suspend(struct device *dev)
1045{
1046        struct platform_device *pdev = to_platform_device(dev);
1047        struct sh_mobile_lcdc_priv *p = platform_get_drvdata(pdev);
1048        struct sh_mobile_lcdc_chan *ch;
1049        int k, n;
1050
1051        /* save per-channel registers */
1052        for (k = 0; k < ARRAY_SIZE(p->ch); k++) {
1053                ch = &p->ch[k];
1054                if (!ch->enabled)
1055                        continue;
1056                for (n = 0; n < NR_CH_REGS; n++)
1057                        ch->saved_ch_regs[n] = lcdc_read_chan(ch, n);
1058        }
1059
1060        /* save shared registers */
1061        for (n = 0; n < NR_SHARED_REGS; n++)
1062                p->saved_shared_regs[n] = lcdc_read(p, lcdc_shared_regs[n]);
1063
1064        /* turn off LCDC hardware */
1065        lcdc_write(p, _LDCNT1R, 0);
1066        return 0;
1067}
1068
1069static int sh_mobile_lcdc_runtime_resume(struct device *dev)
1070{
1071        struct platform_device *pdev = to_platform_device(dev);
1072        struct sh_mobile_lcdc_priv *p = platform_get_drvdata(pdev);
1073        struct sh_mobile_lcdc_chan *ch;
1074        int k, n;
1075
1076        /* restore per-channel registers */
1077        for (k = 0; k < ARRAY_SIZE(p->ch); k++) {
1078                ch = &p->ch[k];
1079                if (!ch->enabled)
1080                        continue;
1081                for (n = 0; n < NR_CH_REGS; n++)
1082                        lcdc_write_chan(ch, n, ch->saved_ch_regs[n]);
1083        }
1084
1085        /* restore shared registers */
1086        for (n = 0; n < NR_SHARED_REGS; n++)
1087                lcdc_write(p, lcdc_shared_regs[n], p->saved_shared_regs[n]);
1088
1089        return 0;
1090}
1091
1092static const struct dev_pm_ops sh_mobile_lcdc_dev_pm_ops = {
1093        .suspend = sh_mobile_lcdc_suspend,
1094        .resume = sh_mobile_lcdc_resume,
1095        .runtime_suspend = sh_mobile_lcdc_runtime_suspend,
1096        .runtime_resume = sh_mobile_lcdc_runtime_resume,
1097};
1098
1099/* locking: called with info->lock held */
1100static int sh_mobile_lcdc_notify(struct notifier_block *nb,
1101                                 unsigned long action, void *data)
1102{
1103        struct fb_event *event = data;
1104        struct fb_info *info = event->info;
1105        struct sh_mobile_lcdc_chan *ch = info->par;
1106        struct sh_mobile_lcdc_board_cfg *board_cfg = &ch->cfg.board_cfg;
1107        int ret;
1108
1109        if (&ch->lcdc->notifier != nb)
1110                return NOTIFY_DONE;
1111
1112        dev_dbg(info->dev, "%s(): action = %lu, data = %p\n",
1113                __func__, action, event->data);
1114
1115        switch(action) {
1116        case FB_EVENT_SUSPEND:
1117                if (try_module_get(board_cfg->owner) && board_cfg->display_off) {
1118                        board_cfg->display_off(board_cfg->board_data);
1119                        module_put(board_cfg->owner);
1120                }
1121                pm_runtime_put(info->device);
1122                sh_mobile_lcdc_stop(ch->lcdc);
1123                break;
1124        case FB_EVENT_RESUME:
1125                mutex_lock(&ch->open_lock);
1126                sh_mobile_fb_reconfig(info);
1127                mutex_unlock(&ch->open_lock);
1128
1129                /* HDMI must be enabled before LCDC configuration */
1130                if (try_module_get(board_cfg->owner) && board_cfg->display_on) {
1131                        board_cfg->display_on(board_cfg->board_data, info);
1132                        module_put(board_cfg->owner);
1133                }
1134
1135                ret = sh_mobile_lcdc_start(ch->lcdc);
1136                if (!ret)
1137                        pm_runtime_get_sync(info->device);
1138        }
1139
1140        return NOTIFY_OK;
1141}
1142
1143static int sh_mobile_lcdc_remove(struct platform_device *pdev);
1144
1145static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
1146{
1147        struct fb_info *info;
1148        struct sh_mobile_lcdc_priv *priv;
1149        struct sh_mobile_lcdc_info *pdata = pdev->dev.platform_data;
1150        struct resource *res;
1151        int error;
1152        void *buf;
1153        int i, j;
1154
1155        if (!pdata) {
1156                dev_err(&pdev->dev, "no platform data defined\n");
1157                return -EINVAL;
1158        }
1159
1160        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1161        i = platform_get_irq(pdev, 0);
1162        if (!res || i < 0) {
1163                dev_err(&pdev->dev, "cannot get platform resources\n");
1164                return -ENOENT;
1165        }
1166
1167        priv = kzalloc(sizeof(*priv), GFP_KERNEL);
1168        if (!priv) {
1169                dev_err(&pdev->dev, "cannot allocate device data\n");
1170                return -ENOMEM;
1171        }
1172
1173        platform_set_drvdata(pdev, priv);
1174
1175        error = request_irq(i, sh_mobile_lcdc_irq, IRQF_DISABLED,
1176                            dev_name(&pdev->dev), priv);
1177        if (error) {
1178                dev_err(&pdev->dev, "unable to request irq\n");
1179                goto err1;
1180        }
1181
1182        priv->irq = i;
1183        atomic_set(&priv->hw_usecnt, -1);
1184
1185        j = 0;
1186        for (i = 0; i < ARRAY_SIZE(pdata->ch); i++) {
1187                struct sh_mobile_lcdc_chan *ch = priv->ch + j;
1188
1189                ch->lcdc = priv;
1190                memcpy(&ch->cfg, &pdata->ch[i], sizeof(pdata->ch[i]));
1191
1192                error = sh_mobile_lcdc_check_interface(ch);
1193                if (error) {
1194                        dev_err(&pdev->dev, "unsupported interface type\n");
1195                        goto err1;
1196                }
1197                init_waitqueue_head(&ch->frame_end_wait);
1198                init_completion(&ch->vsync_completion);
1199                ch->pan_offset = 0;
1200
1201                switch (pdata->ch[i].chan) {
1202                case LCDC_CHAN_MAINLCD:
1203                        ch->enabled = 1 << 1;
1204                        ch->reg_offs = lcdc_offs_mainlcd;
1205                        j++;
1206                        break;
1207                case LCDC_CHAN_SUBLCD:
1208                        ch->enabled = 1 << 2;
1209                        ch->reg_offs = lcdc_offs_sublcd;
1210                        j++;
1211                        break;
1212                }
1213        }
1214
1215        if (!j) {
1216                dev_err(&pdev->dev, "no channels defined\n");
1217                error = -EINVAL;
1218                goto err1;
1219        }
1220
1221        /* for dual channel LCDC (MAIN + SUB) force shared bpp setting */
1222        if (j == 2)
1223                priv->forced_bpp = pdata->ch[0].bpp;
1224
1225        priv->base = ioremap_nocache(res->start, resource_size(res));
1226        if (!priv->base)
1227                goto err1;
1228
1229        error = sh_mobile_lcdc_setup_clocks(pdev, pdata->clock_source, priv);
1230        if (error) {
1231                dev_err(&pdev->dev, "unable to setup clocks\n");
1232                goto err1;
1233        }
1234
1235        for (i = 0; i < j; i++) {
1236                struct fb_var_screeninfo *var;
1237                const struct fb_videomode *lcd_cfg, *max_cfg = NULL;
1238                struct sh_mobile_lcdc_chan *ch = priv->ch + i;
1239                struct sh_mobile_lcdc_chan_cfg *cfg = &ch->cfg;
1240                const struct fb_videomode *mode = cfg->lcd_cfg;
1241                unsigned long max_size = 0;
1242                int k;
1243                int num_cfg;
1244
1245                ch->info = framebuffer_alloc(0, &pdev->dev);
1246                if (!ch->info) {
1247                        dev_err(&pdev->dev, "unable to allocate fb_info\n");
1248                        error = -ENOMEM;
1249                        break;
1250                }
1251
1252                info = ch->info;
1253                var = &info->var;
1254                info->fbops = &sh_mobile_lcdc_ops;
1255                info->par = ch;
1256
1257                mutex_init(&ch->open_lock);
1258
1259                for (k = 0, lcd_cfg = mode;
1260                     k < cfg->num_cfg && lcd_cfg;
1261                     k++, lcd_cfg++) {
1262                        unsigned long size = lcd_cfg->yres * lcd_cfg->xres;
1263
1264                        if (size > max_size) {
1265                                max_cfg = lcd_cfg;
1266                                max_size = size;
1267                        }
1268                }
1269
1270                if (!mode)
1271                        max_size = MAX_XRES * MAX_YRES;
1272                else if (max_cfg)
1273                        dev_dbg(&pdev->dev, "Found largest videomode %ux%u\n",
1274                                max_cfg->xres, max_cfg->yres);
1275
1276                info->fix = sh_mobile_lcdc_fix;
1277                info->fix.smem_len = max_size * (cfg->bpp / 8) * 2;
1278
1279                if (!mode) {
1280                        mode = &default_720p;
1281                        num_cfg = 1;
1282                } else {
1283                        num_cfg = cfg->num_cfg;
1284                }
1285
1286                fb_videomode_to_modelist(mode, num_cfg, &info->modelist);
1287
1288                fb_videomode_to_var(var, mode);
1289                var->width = cfg->lcd_size_cfg.width;
1290                var->height = cfg->lcd_size_cfg.height;
1291                /* Default Y virtual resolution is 2x panel size */
1292                var->yres_virtual = var->yres * 2;
1293                var->activate = FB_ACTIVATE_NOW;
1294
1295                error = sh_mobile_lcdc_set_bpp(var, cfg->bpp);
1296                if (error)
1297                        break;
1298
1299                buf = dma_alloc_coherent(&pdev->dev, info->fix.smem_len,
1300                                         &ch->dma_handle, GFP_KERNEL);
1301                if (!buf) {
1302                        dev_err(&pdev->dev, "unable to allocate buffer\n");
1303                        error = -ENOMEM;
1304                        break;
1305                }
1306
1307                info->pseudo_palette = &ch->pseudo_palette;
1308                info->flags = FBINFO_FLAG_DEFAULT;
1309
1310                error = fb_alloc_cmap(&info->cmap, PALETTE_NR, 0);
1311                if (error < 0) {
1312                        dev_err(&pdev->dev, "unable to allocate cmap\n");
1313                        dma_free_coherent(&pdev->dev, info->fix.smem_len,
1314                                          buf, ch->dma_handle);
1315                        break;
1316                }
1317
1318                info->fix.smem_start = ch->dma_handle;
1319                info->fix.line_length = var->xres * (cfg->bpp / 8);
1320                info->screen_base = buf;
1321                info->device = &pdev->dev;
1322                ch->display_var = *var;
1323        }
1324
1325        if (error)
1326                goto err1;
1327
1328        error = sh_mobile_lcdc_start(priv);
1329        if (error) {
1330                dev_err(&pdev->dev, "unable to start hardware\n");
1331                goto err1;
1332        }
1333
1334        for (i = 0; i < j; i++) {
1335                struct sh_mobile_lcdc_chan *ch = priv->ch + i;
1336
1337                info = ch->info;
1338
1339                if (info->fbdefio) {
1340                        ch->sglist = vmalloc(sizeof(struct scatterlist) *
1341                                        info->fix.smem_len >> PAGE_SHIFT);
1342                        if (!ch->sglist) {
1343                                dev_err(&pdev->dev, "cannot allocate sglist\n");
1344                                goto err1;
1345                        }
1346                }
1347
1348                error = register_framebuffer(info);
1349                if (error < 0)
1350                        goto err1;
1351
1352                dev_info(info->dev,
1353                         "registered %s/%s as %dx%d %dbpp.\n",
1354                         pdev->name,
1355                         (ch->cfg.chan == LCDC_CHAN_MAINLCD) ?
1356                         "mainlcd" : "sublcd",
1357                         info->var.xres, info->var.yres,
1358                         ch->cfg.bpp);
1359
1360                /* deferred io mode: disable clock to save power */
1361                if (info->fbdefio || info->state == FBINFO_STATE_SUSPENDED)
1362                        sh_mobile_lcdc_clk_off(priv);
1363        }
1364
1365        /* Failure ignored */
1366        priv->notifier.notifier_call = sh_mobile_lcdc_notify;
1367        fb_register_client(&priv->notifier);
1368
1369        return 0;
1370err1:
1371        sh_mobile_lcdc_remove(pdev);
1372
1373        return error;
1374}
1375
1376static int sh_mobile_lcdc_remove(struct platform_device *pdev)
1377{
1378        struct sh_mobile_lcdc_priv *priv = platform_get_drvdata(pdev);
1379        struct fb_info *info;
1380        int i;
1381
1382        fb_unregister_client(&priv->notifier);
1383
1384        for (i = 0; i < ARRAY_SIZE(priv->ch); i++)
1385                if (priv->ch[i].info && priv->ch[i].info->dev)
1386                        unregister_framebuffer(priv->ch[i].info);
1387
1388        sh_mobile_lcdc_stop(priv);
1389
1390        for (i = 0; i < ARRAY_SIZE(priv->ch); i++) {
1391                info = priv->ch[i].info;
1392
1393                if (!info || !info->device)
1394                        continue;
1395
1396                if (priv->ch[i].sglist)
1397                        vfree(priv->ch[i].sglist);
1398
1399                if (info->screen_base)
1400                        dma_free_coherent(&pdev->dev, info->fix.smem_len,
1401                                          info->screen_base,
1402                                          priv->ch[i].dma_handle);
1403                fb_dealloc_cmap(&info->cmap);
1404                framebuffer_release(info);
1405        }
1406
1407        if (priv->dot_clk)
1408                clk_put(priv->dot_clk);
1409
1410        if (priv->dev)
1411                pm_runtime_disable(priv->dev);
1412
1413        if (priv->base)
1414                iounmap(priv->base);
1415
1416        if (priv->irq)
1417                free_irq(priv->irq, priv);
1418        kfree(priv);
1419        return 0;
1420}
1421
1422static struct platform_driver sh_mobile_lcdc_driver = {
1423        .driver         = {
1424                .name           = "sh_mobile_lcdc_fb",
1425                .owner          = THIS_MODULE,
1426                .pm             = &sh_mobile_lcdc_dev_pm_ops,
1427        },
1428        .probe          = sh_mobile_lcdc_probe,
1429        .remove         = sh_mobile_lcdc_remove,
1430};
1431
1432static int __init sh_mobile_lcdc_init(void)
1433{
1434        return platform_driver_register(&sh_mobile_lcdc_driver);
1435}
1436
1437static void __exit sh_mobile_lcdc_exit(void)
1438{
1439        platform_driver_unregister(&sh_mobile_lcdc_driver);
1440}
1441
1442module_init(sh_mobile_lcdc_init);
1443module_exit(sh_mobile_lcdc_exit);
1444
1445MODULE_DESCRIPTION("SuperH Mobile LCDC Framebuffer driver");
1446MODULE_AUTHOR("Magnus Damm <damm@opensource.se>");
1447MODULE_LICENSE("GPL v2");
1448