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