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