Merge branch 'topic/oss' into for-linus
[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/fb.h>
16 #include <linux/clk.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 <video/sh_mobile_lcdc.h>
22 #include <asm/atomic.h>
23
24 #define PALETTE_NR 16
25
26 struct sh_mobile_lcdc_priv;
27 struct sh_mobile_lcdc_chan {
28         struct sh_mobile_lcdc_priv *lcdc;
29         unsigned long *reg_offs;
30         unsigned long ldmt1r_value;
31         unsigned long enabled; /* ME and SE in LDCNT2R */
32         struct sh_mobile_lcdc_chan_cfg cfg;
33         u32 pseudo_palette[PALETTE_NR];
34         struct fb_info *info;
35         dma_addr_t dma_handle;
36         struct fb_deferred_io defio;
37         struct scatterlist *sglist;
38         unsigned long frame_end;
39         wait_queue_head_t frame_end_wait;
40 };
41
42 struct sh_mobile_lcdc_priv {
43         void __iomem *base;
44         int irq;
45 #ifdef CONFIG_HAVE_CLK
46         atomic_t clk_usecnt;
47         struct clk *dot_clk;
48         struct clk *clk;
49 #endif
50         unsigned long lddckr;
51         struct sh_mobile_lcdc_chan ch[2];
52         int started;
53 };
54
55 /* shared registers */
56 #define _LDDCKR 0x410
57 #define _LDDCKSTPR 0x414
58 #define _LDINTR 0x468
59 #define _LDSR 0x46c
60 #define _LDCNT1R 0x470
61 #define _LDCNT2R 0x474
62 #define _LDDDSR 0x47c
63 #define _LDDWD0R 0x800
64 #define _LDDRDR 0x840
65 #define _LDDWAR 0x900
66 #define _LDDRAR 0x904
67
68 /* per-channel registers */
69 enum { LDDCKPAT1R, LDDCKPAT2R, LDMT1R, LDMT2R, LDMT3R, LDDFR, LDSM1R,
70        LDSM2R, LDSA1R, LDMLSR, LDHCNR, LDHSYNR, LDVLNR, LDVSYNR, LDPMR };
71
72 static unsigned long lcdc_offs_mainlcd[] = {
73         [LDDCKPAT1R] = 0x400,
74         [LDDCKPAT2R] = 0x404,
75         [LDMT1R] = 0x418,
76         [LDMT2R] = 0x41c,
77         [LDMT3R] = 0x420,
78         [LDDFR] = 0x424,
79         [LDSM1R] = 0x428,
80         [LDSM2R] = 0x42c,
81         [LDSA1R] = 0x430,
82         [LDMLSR] = 0x438,
83         [LDHCNR] = 0x448,
84         [LDHSYNR] = 0x44c,
85         [LDVLNR] = 0x450,
86         [LDVSYNR] = 0x454,
87         [LDPMR] = 0x460,
88 };
89
90 static unsigned long lcdc_offs_sublcd[] = {
91         [LDDCKPAT1R] = 0x408,
92         [LDDCKPAT2R] = 0x40c,
93         [LDMT1R] = 0x600,
94         [LDMT2R] = 0x604,
95         [LDMT3R] = 0x608,
96         [LDDFR] = 0x60c,
97         [LDSM1R] = 0x610,
98         [LDSM2R] = 0x614,
99         [LDSA1R] = 0x618,
100         [LDMLSR] = 0x620,
101         [LDHCNR] = 0x624,
102         [LDHSYNR] = 0x628,
103         [LDVLNR] = 0x62c,
104         [LDVSYNR] = 0x630,
105         [LDPMR] = 0x63c,
106 };
107
108 #define START_LCDC      0x00000001
109 #define LCDC_RESET      0x00000100
110 #define DISPLAY_BEU     0x00000008
111 #define LCDC_ENABLE     0x00000001
112 #define LDINTR_FE       0x00000400
113 #define LDINTR_FS       0x00000004
114
115 static void lcdc_write_chan(struct sh_mobile_lcdc_chan *chan,
116                             int reg_nr, unsigned long data)
117 {
118         iowrite32(data, chan->lcdc->base + chan->reg_offs[reg_nr]);
119 }
120
121 static unsigned long lcdc_read_chan(struct sh_mobile_lcdc_chan *chan,
122                                     int reg_nr)
123 {
124         return ioread32(chan->lcdc->base + chan->reg_offs[reg_nr]);
125 }
126
127 static void lcdc_write(struct sh_mobile_lcdc_priv *priv,
128                        unsigned long reg_offs, unsigned long data)
129 {
130         iowrite32(data, priv->base + reg_offs);
131 }
132
133 static unsigned long lcdc_read(struct sh_mobile_lcdc_priv *priv,
134                                unsigned long reg_offs)
135 {
136         return ioread32(priv->base + reg_offs);
137 }
138
139 static void lcdc_wait_bit(struct sh_mobile_lcdc_priv *priv,
140                           unsigned long reg_offs,
141                           unsigned long mask, unsigned long until)
142 {
143         while ((lcdc_read(priv, reg_offs) & mask) != until)
144                 cpu_relax();
145 }
146
147 static int lcdc_chan_is_sublcd(struct sh_mobile_lcdc_chan *chan)
148 {
149         return chan->cfg.chan == LCDC_CHAN_SUBLCD;
150 }
151
152 static void lcdc_sys_write_index(void *handle, unsigned long data)
153 {
154         struct sh_mobile_lcdc_chan *ch = handle;
155
156         lcdc_write(ch->lcdc, _LDDWD0R, data | 0x10000000);
157         lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0);
158         lcdc_write(ch->lcdc, _LDDWAR, 1 | (lcdc_chan_is_sublcd(ch) ? 2 : 0));
159 }
160
161 static void lcdc_sys_write_data(void *handle, unsigned long data)
162 {
163         struct sh_mobile_lcdc_chan *ch = handle;
164
165         lcdc_write(ch->lcdc, _LDDWD0R, data | 0x11000000);
166         lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0);
167         lcdc_write(ch->lcdc, _LDDWAR, 1 | (lcdc_chan_is_sublcd(ch) ? 2 : 0));
168 }
169
170 static unsigned long lcdc_sys_read_data(void *handle)
171 {
172         struct sh_mobile_lcdc_chan *ch = handle;
173
174         lcdc_write(ch->lcdc, _LDDRDR, 0x01000000);
175         lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0);
176         lcdc_write(ch->lcdc, _LDDRAR, 1 | (lcdc_chan_is_sublcd(ch) ? 2 : 0));
177         udelay(1);
178
179         return lcdc_read(ch->lcdc, _LDDRDR) & 0xffff;
180 }
181
182 struct sh_mobile_lcdc_sys_bus_ops sh_mobile_lcdc_sys_bus_ops = {
183         lcdc_sys_write_index,
184         lcdc_sys_write_data,
185         lcdc_sys_read_data,
186 };
187
188 #ifdef CONFIG_HAVE_CLK
189 static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv)
190 {
191         if (atomic_inc_and_test(&priv->clk_usecnt)) {
192                 clk_enable(priv->clk);
193                 if (priv->dot_clk)
194                         clk_enable(priv->dot_clk);
195         }
196 }
197
198 static void sh_mobile_lcdc_clk_off(struct sh_mobile_lcdc_priv *priv)
199 {
200         if (atomic_sub_return(1, &priv->clk_usecnt) == -1) {
201                 if (priv->dot_clk)
202                         clk_disable(priv->dot_clk);
203                 clk_disable(priv->clk);
204         }
205 }
206 #else
207 static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv) {}
208 static void sh_mobile_lcdc_clk_off(struct sh_mobile_lcdc_priv *priv) {}
209 #endif
210
211 static int sh_mobile_lcdc_sginit(struct fb_info *info,
212                                   struct list_head *pagelist)
213 {
214         struct sh_mobile_lcdc_chan *ch = info->par;
215         unsigned int nr_pages_max = info->fix.smem_len >> PAGE_SHIFT;
216         struct page *page;
217         int nr_pages = 0;
218
219         sg_init_table(ch->sglist, nr_pages_max);
220
221         list_for_each_entry(page, pagelist, lru)
222                 sg_set_page(&ch->sglist[nr_pages++], page, PAGE_SIZE, 0);
223
224         return nr_pages;
225 }
226
227 static void sh_mobile_lcdc_deferred_io(struct fb_info *info,
228                                        struct list_head *pagelist)
229 {
230         struct sh_mobile_lcdc_chan *ch = info->par;
231         unsigned int nr_pages;
232
233         /* enable clocks before accessing hardware */
234         sh_mobile_lcdc_clk_on(ch->lcdc);
235
236         nr_pages = sh_mobile_lcdc_sginit(info, pagelist);
237         dma_map_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE);
238
239         /* trigger panel update */
240         lcdc_write_chan(ch, LDSM2R, 1);
241
242         dma_unmap_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE);
243 }
244
245 static void sh_mobile_lcdc_deferred_io_touch(struct fb_info *info)
246 {
247         struct fb_deferred_io *fbdefio = info->fbdefio;
248
249         if (fbdefio)
250                 schedule_delayed_work(&info->deferred_work, fbdefio->delay);
251 }
252
253 static irqreturn_t sh_mobile_lcdc_irq(int irq, void *data)
254 {
255         struct sh_mobile_lcdc_priv *priv = data;
256         struct sh_mobile_lcdc_chan *ch;
257         unsigned long tmp;
258         int is_sub;
259         int k;
260
261         /* acknowledge interrupt */
262         tmp = lcdc_read(priv, _LDINTR);
263         tmp &= 0xffffff00; /* mask in high 24 bits */
264         tmp |= 0x000000ff ^ LDINTR_FS; /* status in low 8 */
265         lcdc_write(priv, _LDINTR, tmp);
266
267         /* figure out if this interrupt is for main or sub lcd */
268         is_sub = (lcdc_read(priv, _LDSR) & (1 << 10)) ? 1 : 0;
269
270         /* wake up channel and disable clocks*/
271         for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
272                 ch = &priv->ch[k];
273
274                 if (!ch->enabled)
275                         continue;
276
277                 if (is_sub == lcdc_chan_is_sublcd(ch)) {
278                         ch->frame_end = 1;
279                         wake_up(&ch->frame_end_wait);
280
281                         sh_mobile_lcdc_clk_off(priv);
282                 }
283         }
284
285         return IRQ_HANDLED;
286 }
287
288 static void sh_mobile_lcdc_start_stop(struct sh_mobile_lcdc_priv *priv,
289                                       int start)
290 {
291         unsigned long tmp = lcdc_read(priv, _LDCNT2R);
292         int k;
293
294         /* start or stop the lcdc */
295         if (start)
296                 lcdc_write(priv, _LDCNT2R, tmp | START_LCDC);
297         else
298                 lcdc_write(priv, _LDCNT2R, tmp & ~START_LCDC);
299
300         /* wait until power is applied/stopped on all channels */
301         for (k = 0; k < ARRAY_SIZE(priv->ch); k++)
302                 if (lcdc_read(priv, _LDCNT2R) & priv->ch[k].enabled)
303                         while (1) {
304                                 tmp = lcdc_read_chan(&priv->ch[k], LDPMR) & 3;
305                                 if (start && tmp == 3)
306                                         break;
307                                 if (!start && tmp == 0)
308                                         break;
309                                 cpu_relax();
310                         }
311
312         if (!start)
313                 lcdc_write(priv, _LDDCKSTPR, 1); /* stop dotclock */
314 }
315
316 static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
317 {
318         struct sh_mobile_lcdc_chan *ch;
319         struct fb_videomode *lcd_cfg;
320         struct sh_mobile_lcdc_board_cfg *board_cfg;
321         unsigned long tmp;
322         int k, m;
323         int ret = 0;
324
325         /* enable clocks before accessing the hardware */
326         for (k = 0; k < ARRAY_SIZE(priv->ch); k++)
327                 if (priv->ch[k].enabled)
328                         sh_mobile_lcdc_clk_on(priv);
329
330         /* reset */
331         lcdc_write(priv, _LDCNT2R, lcdc_read(priv, _LDCNT2R) | LCDC_RESET);
332         lcdc_wait_bit(priv, _LDCNT2R, LCDC_RESET, 0);
333
334         /* enable LCDC channels */
335         tmp = lcdc_read(priv, _LDCNT2R);
336         tmp |= priv->ch[0].enabled;
337         tmp |= priv->ch[1].enabled;
338         lcdc_write(priv, _LDCNT2R, tmp);
339
340         /* read data from external memory, avoid using the BEU for now */
341         lcdc_write(priv, _LDCNT2R, lcdc_read(priv, _LDCNT2R) & ~DISPLAY_BEU);
342
343         /* stop the lcdc first */
344         sh_mobile_lcdc_start_stop(priv, 0);
345
346         /* configure clocks */
347         tmp = priv->lddckr;
348         for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
349                 ch = &priv->ch[k];
350
351                 if (!priv->ch[k].enabled)
352                         continue;
353
354                 m = ch->cfg.clock_divider;
355                 if (!m)
356                         continue;
357
358                 if (m == 1)
359                         m = 1 << 6;
360                 tmp |= m << (lcdc_chan_is_sublcd(ch) ? 8 : 0);
361
362                 lcdc_write_chan(ch, LDDCKPAT1R, 0x00000000);
363                 lcdc_write_chan(ch, LDDCKPAT2R, (1 << (m/2)) - 1);
364         }
365
366         lcdc_write(priv, _LDDCKR, tmp);
367
368         /* start dotclock again */
369         lcdc_write(priv, _LDDCKSTPR, 0);
370         lcdc_wait_bit(priv, _LDDCKSTPR, ~0, 0);
371
372         /* interrupts are disabled to begin with */
373         lcdc_write(priv, _LDINTR, 0);
374
375         for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
376                 ch = &priv->ch[k];
377                 lcd_cfg = &ch->cfg.lcd_cfg;
378
379                 if (!ch->enabled)
380                         continue;
381
382                 tmp = ch->ldmt1r_value;
383                 tmp |= (lcd_cfg->sync & FB_SYNC_VERT_HIGH_ACT) ? 0 : 1 << 28;
384                 tmp |= (lcd_cfg->sync & FB_SYNC_HOR_HIGH_ACT) ? 0 : 1 << 27;
385                 tmp |= (ch->cfg.flags & LCDC_FLAGS_DWPOL) ? 1 << 26 : 0;
386                 tmp |= (ch->cfg.flags & LCDC_FLAGS_DIPOL) ? 1 << 25 : 0;
387                 tmp |= (ch->cfg.flags & LCDC_FLAGS_DAPOL) ? 1 << 24 : 0;
388                 tmp |= (ch->cfg.flags & LCDC_FLAGS_HSCNT) ? 1 << 17 : 0;
389                 tmp |= (ch->cfg.flags & LCDC_FLAGS_DWCNT) ? 1 << 16 : 0;
390                 lcdc_write_chan(ch, LDMT1R, tmp);
391
392                 /* setup SYS bus */
393                 lcdc_write_chan(ch, LDMT2R, ch->cfg.sys_bus_cfg.ldmt2r);
394                 lcdc_write_chan(ch, LDMT3R, ch->cfg.sys_bus_cfg.ldmt3r);
395
396                 /* horizontal configuration */
397                 tmp = lcd_cfg->xres + lcd_cfg->hsync_len;
398                 tmp += lcd_cfg->left_margin;
399                 tmp += lcd_cfg->right_margin;
400                 tmp /= 8; /* HTCN */
401                 tmp |= (lcd_cfg->xres / 8) << 16; /* HDCN */
402                 lcdc_write_chan(ch, LDHCNR, tmp);
403
404                 tmp = lcd_cfg->xres;
405                 tmp += lcd_cfg->right_margin;
406                 tmp /= 8; /* HSYNP */
407                 tmp |= (lcd_cfg->hsync_len / 8) << 16; /* HSYNW */
408                 lcdc_write_chan(ch, LDHSYNR, tmp);
409
410                 /* power supply */
411                 lcdc_write_chan(ch, LDPMR, 0);
412
413                 /* vertical configuration */
414                 tmp = lcd_cfg->yres + lcd_cfg->vsync_len;
415                 tmp += lcd_cfg->upper_margin;
416                 tmp += lcd_cfg->lower_margin; /* VTLN */
417                 tmp |= lcd_cfg->yres << 16; /* VDLN */
418                 lcdc_write_chan(ch, LDVLNR, tmp);
419
420                 tmp = lcd_cfg->yres;
421                 tmp += lcd_cfg->lower_margin; /* VSYNP */
422                 tmp |= lcd_cfg->vsync_len << 16; /* VSYNW */
423                 lcdc_write_chan(ch, LDVSYNR, tmp);
424
425                 board_cfg = &ch->cfg.board_cfg;
426                 if (board_cfg->setup_sys)
427                         ret = board_cfg->setup_sys(board_cfg->board_data, ch,
428                                                    &sh_mobile_lcdc_sys_bus_ops);
429                 if (ret)
430                         return ret;
431         }
432
433         /* word and long word swap */
434         lcdc_write(priv, _LDDDSR, lcdc_read(priv, _LDDDSR) | 6);
435
436         for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
437                 ch = &priv->ch[k];
438
439                 if (!priv->ch[k].enabled)
440                         continue;
441
442                 /* set bpp format in PKF[4:0] */
443                 tmp = lcdc_read_chan(ch, LDDFR);
444                 tmp &= ~(0x0001001f);
445                 tmp |= (ch->info->var.bits_per_pixel == 16) ? 3 : 0;
446                 lcdc_write_chan(ch, LDDFR, tmp);
447
448                 /* point out our frame buffer */
449                 lcdc_write_chan(ch, LDSA1R, ch->info->fix.smem_start);
450
451                 /* set line size */
452                 lcdc_write_chan(ch, LDMLSR, ch->info->fix.line_length);
453
454                 /* setup deferred io if SYS bus */
455                 tmp = ch->cfg.sys_bus_cfg.deferred_io_msec;
456                 if (ch->ldmt1r_value & (1 << 12) && tmp) {
457                         ch->defio.deferred_io = sh_mobile_lcdc_deferred_io;
458                         ch->defio.delay = msecs_to_jiffies(tmp);
459                         ch->info->fbdefio = &ch->defio;
460                         fb_deferred_io_init(ch->info);
461
462                         /* one-shot mode */
463                         lcdc_write_chan(ch, LDSM1R, 1);
464
465                         /* enable "Frame End Interrupt Enable" bit */
466                         lcdc_write(priv, _LDINTR, LDINTR_FE);
467
468                 } else {
469                         /* continuous read mode */
470                         lcdc_write_chan(ch, LDSM1R, 0);
471                 }
472         }
473
474         /* display output */
475         lcdc_write(priv, _LDCNT1R, LCDC_ENABLE);
476
477         /* start the lcdc */
478         sh_mobile_lcdc_start_stop(priv, 1);
479         priv->started = 1;
480
481         /* tell the board code to enable the panel */
482         for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
483                 ch = &priv->ch[k];
484                 if (!ch->enabled)
485                         continue;
486
487                 board_cfg = &ch->cfg.board_cfg;
488                 if (board_cfg->display_on)
489                         board_cfg->display_on(board_cfg->board_data);
490         }
491
492         return 0;
493 }
494
495 static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
496 {
497         struct sh_mobile_lcdc_chan *ch;
498         struct sh_mobile_lcdc_board_cfg *board_cfg;
499         int k;
500
501         /* clean up deferred io and ask board code to disable panel */
502         for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
503                 ch = &priv->ch[k];
504                 if (!ch->enabled)
505                         continue;
506
507                 /* deferred io mode:
508                  * flush frame, and wait for frame end interrupt
509                  * clean up deferred io and enable clock
510                  */
511                 if (ch->info->fbdefio) {
512                         ch->frame_end = 0;
513                         schedule_delayed_work(&ch->info->deferred_work, 0);
514                         wait_event(ch->frame_end_wait, ch->frame_end);
515                         fb_deferred_io_cleanup(ch->info);
516                         ch->info->fbdefio = NULL;
517                         sh_mobile_lcdc_clk_on(priv);
518                 }
519
520                 board_cfg = &ch->cfg.board_cfg;
521                 if (board_cfg->display_off)
522                         board_cfg->display_off(board_cfg->board_data);
523
524         }
525
526         /* stop the lcdc */
527         if (priv->started) {
528                 sh_mobile_lcdc_start_stop(priv, 0);
529                 priv->started = 0;
530         }
531
532         /* stop clocks */
533         for (k = 0; k < ARRAY_SIZE(priv->ch); k++)
534                 if (priv->ch[k].enabled)
535                         sh_mobile_lcdc_clk_off(priv);
536 }
537
538 static int sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch)
539 {
540         int ifm, miftyp;
541
542         switch (ch->cfg.interface_type) {
543         case RGB8: ifm = 0; miftyp = 0; break;
544         case RGB9: ifm = 0; miftyp = 4; break;
545         case RGB12A: ifm = 0; miftyp = 5; break;
546         case RGB12B: ifm = 0; miftyp = 6; break;
547         case RGB16: ifm = 0; miftyp = 7; break;
548         case RGB18: ifm = 0; miftyp = 10; break;
549         case RGB24: ifm = 0; miftyp = 11; break;
550         case SYS8A: ifm = 1; miftyp = 0; break;
551         case SYS8B: ifm = 1; miftyp = 1; break;
552         case SYS8C: ifm = 1; miftyp = 2; break;
553         case SYS8D: ifm = 1; miftyp = 3; break;
554         case SYS9: ifm = 1; miftyp = 4; break;
555         case SYS12: ifm = 1; miftyp = 5; break;
556         case SYS16A: ifm = 1; miftyp = 7; break;
557         case SYS16B: ifm = 1; miftyp = 8; break;
558         case SYS16C: ifm = 1; miftyp = 9; break;
559         case SYS18: ifm = 1; miftyp = 10; break;
560         case SYS24: ifm = 1; miftyp = 11; break;
561         default: goto bad;
562         }
563
564         /* SUBLCD only supports SYS interface */
565         if (lcdc_chan_is_sublcd(ch)) {
566                 if (ifm == 0)
567                         goto bad;
568                 else
569                         ifm = 0;
570         }
571
572         ch->ldmt1r_value = (ifm << 12) | miftyp;
573         return 0;
574  bad:
575         return -EINVAL;
576 }
577
578 static int sh_mobile_lcdc_setup_clocks(struct platform_device *pdev,
579                                        int clock_source,
580                                        struct sh_mobile_lcdc_priv *priv)
581 {
582 #ifdef CONFIG_HAVE_CLK
583         char clk_name[8];
584 #endif
585         char *str;
586         int icksel;
587
588         switch (clock_source) {
589         case LCDC_CLK_BUS: str = "bus_clk"; icksel = 0; break;
590         case LCDC_CLK_PERIPHERAL: str = "peripheral_clk"; icksel = 1; break;
591         case LCDC_CLK_EXTERNAL: str = NULL; icksel = 2; break;
592         default:
593                 return -EINVAL;
594         }
595
596         priv->lddckr = icksel << 16;
597
598 #ifdef CONFIG_HAVE_CLK
599         atomic_set(&priv->clk_usecnt, -1);
600         snprintf(clk_name, sizeof(clk_name), "lcdc%d", pdev->id);
601         priv->clk = clk_get(&pdev->dev, clk_name);
602         if (IS_ERR(priv->clk)) {
603                 dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
604                 return PTR_ERR(priv->clk);
605         }
606         
607         if (str) {
608                 priv->dot_clk = clk_get(&pdev->dev, str);
609                 if (IS_ERR(priv->dot_clk)) {
610                         dev_err(&pdev->dev, "cannot get dot clock %s\n", str);
611                         clk_put(priv->clk);
612                         return PTR_ERR(priv->dot_clk);
613                 }
614         }
615 #endif
616
617         return 0;
618 }
619
620 static int sh_mobile_lcdc_setcolreg(u_int regno,
621                                     u_int red, u_int green, u_int blue,
622                                     u_int transp, struct fb_info *info)
623 {
624         u32 *palette = info->pseudo_palette;
625
626         if (regno >= PALETTE_NR)
627                 return -EINVAL;
628
629         /* only FB_VISUAL_TRUECOLOR supported */
630
631         red >>= 16 - info->var.red.length;
632         green >>= 16 - info->var.green.length;
633         blue >>= 16 - info->var.blue.length;
634         transp >>= 16 - info->var.transp.length;
635
636         palette[regno] = (red << info->var.red.offset) |
637           (green << info->var.green.offset) |
638           (blue << info->var.blue.offset) |
639           (transp << info->var.transp.offset);
640
641         return 0;
642 }
643
644 static struct fb_fix_screeninfo sh_mobile_lcdc_fix  = {
645         .id =           "SH Mobile LCDC",
646         .type =         FB_TYPE_PACKED_PIXELS,
647         .visual =       FB_VISUAL_TRUECOLOR,
648         .accel =        FB_ACCEL_NONE,
649 };
650
651 static void sh_mobile_lcdc_fillrect(struct fb_info *info,
652                                     const struct fb_fillrect *rect)
653 {
654         sys_fillrect(info, rect);
655         sh_mobile_lcdc_deferred_io_touch(info);
656 }
657
658 static void sh_mobile_lcdc_copyarea(struct fb_info *info,
659                                     const struct fb_copyarea *area)
660 {
661         sys_copyarea(info, area);
662         sh_mobile_lcdc_deferred_io_touch(info);
663 }
664
665 static void sh_mobile_lcdc_imageblit(struct fb_info *info,
666                                      const struct fb_image *image)
667 {
668         sys_imageblit(info, image);
669         sh_mobile_lcdc_deferred_io_touch(info);
670 }
671
672 static struct fb_ops sh_mobile_lcdc_ops = {
673         .fb_setcolreg   = sh_mobile_lcdc_setcolreg,
674         .fb_read        = fb_sys_read,
675         .fb_write       = fb_sys_write,
676         .fb_fillrect    = sh_mobile_lcdc_fillrect,
677         .fb_copyarea    = sh_mobile_lcdc_copyarea,
678         .fb_imageblit   = sh_mobile_lcdc_imageblit,
679 };
680
681 static int sh_mobile_lcdc_set_bpp(struct fb_var_screeninfo *var, int bpp)
682 {
683         switch (bpp) {
684         case 16: /* PKF[4:0] = 00011 - RGB 565 */
685                 var->red.offset = 11;
686                 var->red.length = 5;
687                 var->green.offset = 5;
688                 var->green.length = 6;
689                 var->blue.offset = 0;
690                 var->blue.length = 5;
691                 var->transp.offset = 0;
692                 var->transp.length = 0;
693                 break;
694
695         case 32: /* PKF[4:0] = 00000 - RGB 888
696                   * sh7722 pdf says 00RRGGBB but reality is GGBB00RR
697                   * this may be because LDDDSR has word swap enabled..
698                   */
699                 var->red.offset = 0;
700                 var->red.length = 8;
701                 var->green.offset = 24;
702                 var->green.length = 8;
703                 var->blue.offset = 16;
704                 var->blue.length = 8;
705                 var->transp.offset = 0;
706                 var->transp.length = 0;
707                 break;
708         default:
709                 return -EINVAL;
710         }
711         var->bits_per_pixel = bpp;
712         var->red.msb_right = 0;
713         var->green.msb_right = 0;
714         var->blue.msb_right = 0;
715         var->transp.msb_right = 0;
716         return 0;
717 }
718
719 static int sh_mobile_lcdc_suspend(struct device *dev)
720 {
721         struct platform_device *pdev = to_platform_device(dev);
722
723         sh_mobile_lcdc_stop(platform_get_drvdata(pdev));
724         return 0;
725 }
726
727 static int sh_mobile_lcdc_resume(struct device *dev)
728 {
729         struct platform_device *pdev = to_platform_device(dev);
730
731         return sh_mobile_lcdc_start(platform_get_drvdata(pdev));
732 }
733
734 static struct dev_pm_ops sh_mobile_lcdc_dev_pm_ops = {
735         .suspend = sh_mobile_lcdc_suspend,
736         .resume = sh_mobile_lcdc_resume,
737 };
738
739 static int sh_mobile_lcdc_remove(struct platform_device *pdev);
740
741 static int __init sh_mobile_lcdc_probe(struct platform_device *pdev)
742 {
743         struct fb_info *info;
744         struct sh_mobile_lcdc_priv *priv;
745         struct sh_mobile_lcdc_info *pdata;
746         struct sh_mobile_lcdc_chan_cfg *cfg;
747         struct resource *res;
748         int error;
749         void *buf;
750         int i, j;
751
752         if (!pdev->dev.platform_data) {
753                 dev_err(&pdev->dev, "no platform data defined\n");
754                 error = -EINVAL;
755                 goto err0;
756         }
757
758         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
759         i = platform_get_irq(pdev, 0);
760         if (!res || i < 0) {
761                 dev_err(&pdev->dev, "cannot get platform resources\n");
762                 error = -ENOENT;
763                 goto err0;
764         }
765
766         priv = kzalloc(sizeof(*priv), GFP_KERNEL);
767         if (!priv) {
768                 dev_err(&pdev->dev, "cannot allocate device data\n");
769                 error = -ENOMEM;
770                 goto err0;
771         }
772
773         error = request_irq(i, sh_mobile_lcdc_irq, IRQF_DISABLED,
774                             dev_name(&pdev->dev), priv);
775         if (error) {
776                 dev_err(&pdev->dev, "unable to request irq\n");
777                 goto err1;
778         }
779
780         priv->irq = i;
781         platform_set_drvdata(pdev, priv);
782         pdata = pdev->dev.platform_data;
783
784         j = 0;
785         for (i = 0; i < ARRAY_SIZE(pdata->ch); i++) {
786                 priv->ch[j].lcdc = priv;
787                 memcpy(&priv->ch[j].cfg, &pdata->ch[i], sizeof(pdata->ch[i]));
788
789                 error = sh_mobile_lcdc_check_interface(&priv->ch[i]);
790                 if (error) {
791                         dev_err(&pdev->dev, "unsupported interface type\n");
792                         goto err1;
793                 }
794                 init_waitqueue_head(&priv->ch[i].frame_end_wait);
795
796                 switch (pdata->ch[i].chan) {
797                 case LCDC_CHAN_MAINLCD:
798                         priv->ch[j].enabled = 1 << 1;
799                         priv->ch[j].reg_offs = lcdc_offs_mainlcd;
800                         j++;
801                         break;
802                 case LCDC_CHAN_SUBLCD:
803                         priv->ch[j].enabled = 1 << 2;
804                         priv->ch[j].reg_offs = lcdc_offs_sublcd;
805                         j++;
806                         break;
807                 }
808         }
809
810         if (!j) {
811                 dev_err(&pdev->dev, "no channels defined\n");
812                 error = -EINVAL;
813                 goto err1;
814         }
815
816         error = sh_mobile_lcdc_setup_clocks(pdev, pdata->clock_source, priv);
817         if (error) {
818                 dev_err(&pdev->dev, "unable to setup clocks\n");
819                 goto err1;
820         }
821
822         priv->base = ioremap_nocache(res->start, (res->end - res->start) + 1);
823
824         for (i = 0; i < j; i++) {
825                 cfg = &priv->ch[i].cfg;
826
827                 priv->ch[i].info = framebuffer_alloc(0, &pdev->dev);
828                 if (!priv->ch[i].info) {
829                         dev_err(&pdev->dev, "unable to allocate fb_info\n");
830                         error = -ENOMEM;
831                         break;
832                 }
833
834                 info = priv->ch[i].info;
835                 info->fbops = &sh_mobile_lcdc_ops;
836                 info->var.xres = info->var.xres_virtual = cfg->lcd_cfg.xres;
837                 info->var.yres = info->var.yres_virtual = cfg->lcd_cfg.yres;
838                 info->var.width = cfg->lcd_size_cfg.width;
839                 info->var.height = cfg->lcd_size_cfg.height;
840                 info->var.activate = FB_ACTIVATE_NOW;
841                 error = sh_mobile_lcdc_set_bpp(&info->var, cfg->bpp);
842                 if (error)
843                         break;
844
845                 info->fix = sh_mobile_lcdc_fix;
846                 info->fix.line_length = cfg->lcd_cfg.xres * (cfg->bpp / 8);
847                 info->fix.smem_len = info->fix.line_length * cfg->lcd_cfg.yres;
848
849                 buf = dma_alloc_coherent(&pdev->dev, info->fix.smem_len,
850                                          &priv->ch[i].dma_handle, GFP_KERNEL);
851                 if (!buf) {
852                         dev_err(&pdev->dev, "unable to allocate buffer\n");
853                         error = -ENOMEM;
854                         break;
855                 }
856
857                 info->pseudo_palette = &priv->ch[i].pseudo_palette;
858                 info->flags = FBINFO_FLAG_DEFAULT;
859
860                 error = fb_alloc_cmap(&info->cmap, PALETTE_NR, 0);
861                 if (error < 0) {
862                         dev_err(&pdev->dev, "unable to allocate cmap\n");
863                         dma_free_coherent(&pdev->dev, info->fix.smem_len,
864                                           buf, priv->ch[i].dma_handle);
865                         break;
866                 }
867
868                 memset(buf, 0, info->fix.smem_len);
869                 info->fix.smem_start = priv->ch[i].dma_handle;
870                 info->screen_base = buf;
871                 info->device = &pdev->dev;
872                 info->par = &priv->ch[i];
873         }
874
875         if (error)
876                 goto err1;
877
878         error = sh_mobile_lcdc_start(priv);
879         if (error) {
880                 dev_err(&pdev->dev, "unable to start hardware\n");
881                 goto err1;
882         }
883
884         for (i = 0; i < j; i++) {
885                 struct sh_mobile_lcdc_chan *ch = priv->ch + i;
886
887                 info = ch->info;
888
889                 if (info->fbdefio) {
890                         priv->ch->sglist = vmalloc(sizeof(struct scatterlist) *
891                                         info->fix.smem_len >> PAGE_SHIFT);
892                         if (!priv->ch->sglist) {
893                                 dev_err(&pdev->dev, "cannot allocate sglist\n");
894                                 goto err1;
895                         }
896                 }
897
898                 error = register_framebuffer(info);
899                 if (error < 0)
900                         goto err1;
901
902                 dev_info(info->dev,
903                          "registered %s/%s as %dx%d %dbpp.\n",
904                          pdev->name,
905                          (ch->cfg.chan == LCDC_CHAN_MAINLCD) ?
906                          "mainlcd" : "sublcd",
907                          (int) ch->cfg.lcd_cfg.xres,
908                          (int) ch->cfg.lcd_cfg.yres,
909                          ch->cfg.bpp);
910
911                 /* deferred io mode: disable clock to save power */
912                 if (info->fbdefio)
913                         sh_mobile_lcdc_clk_off(priv);
914         }
915
916         return 0;
917  err1:
918         sh_mobile_lcdc_remove(pdev);
919  err0:
920         return error;
921 }
922
923 static int sh_mobile_lcdc_remove(struct platform_device *pdev)
924 {
925         struct sh_mobile_lcdc_priv *priv = platform_get_drvdata(pdev);
926         struct fb_info *info;
927         int i;
928
929         for (i = 0; i < ARRAY_SIZE(priv->ch); i++)
930                 if (priv->ch[i].info->dev)
931                         unregister_framebuffer(priv->ch[i].info);
932
933         sh_mobile_lcdc_stop(priv);
934
935         for (i = 0; i < ARRAY_SIZE(priv->ch); i++) {
936                 info = priv->ch[i].info;
937
938                 if (!info || !info->device)
939                         continue;
940
941                 if (priv->ch[i].sglist)
942                         vfree(priv->ch[i].sglist);
943
944                 dma_free_coherent(&pdev->dev, info->fix.smem_len,
945                                   info->screen_base, priv->ch[i].dma_handle);
946                 fb_dealloc_cmap(&info->cmap);
947                 framebuffer_release(info);
948         }
949
950 #ifdef CONFIG_HAVE_CLK
951         if (priv->dot_clk)
952                 clk_put(priv->dot_clk);
953         clk_put(priv->clk);
954 #endif
955
956         if (priv->base)
957                 iounmap(priv->base);
958
959         if (priv->irq)
960                 free_irq(priv->irq, priv);
961         kfree(priv);
962         return 0;
963 }
964
965 static struct platform_driver sh_mobile_lcdc_driver = {
966         .driver         = {
967                 .name           = "sh_mobile_lcdc_fb",
968                 .owner          = THIS_MODULE,
969                 .pm             = &sh_mobile_lcdc_dev_pm_ops,
970         },
971         .probe          = sh_mobile_lcdc_probe,
972         .remove         = sh_mobile_lcdc_remove,
973 };
974
975 static int __init sh_mobile_lcdc_init(void)
976 {
977         return platform_driver_register(&sh_mobile_lcdc_driver);
978 }
979
980 static void __exit sh_mobile_lcdc_exit(void)
981 {
982         platform_driver_unregister(&sh_mobile_lcdc_driver);
983 }
984
985 module_init(sh_mobile_lcdc_init);
986 module_exit(sh_mobile_lcdc_exit);
987
988 MODULE_DESCRIPTION("SuperH Mobile LCDC Framebuffer driver");
989 MODULE_AUTHOR("Magnus Damm <damm@opensource.se>");
990 MODULE_LICENSE("GPL v2");