Merge git://git.infradead.org/iommu-2.6
[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/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 |= (priv->ch[k].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                 board_cfg = &ch->cfg.board_cfg;
485                 if (board_cfg->display_on)
486                         board_cfg->display_on(board_cfg->board_data);
487         }
488
489         return 0;
490 }
491
492 static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
493 {
494         struct sh_mobile_lcdc_chan *ch;
495         struct sh_mobile_lcdc_board_cfg *board_cfg;
496         int k;
497
498         /* clean up deferred io and ask board code to disable panel */
499         for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
500                 ch = &priv->ch[k];
501
502                 /* deferred io mode:
503                  * flush frame, and wait for frame end interrupt
504                  * clean up deferred io and enable clock
505                  */
506                 if (ch->info.fbdefio) {
507                         ch->frame_end = 0;
508                         schedule_delayed_work(&ch->info.deferred_work, 0);
509                         wait_event(ch->frame_end_wait, ch->frame_end);
510                         fb_deferred_io_cleanup(&ch->info);
511                         ch->info.fbdefio = NULL;
512                         sh_mobile_lcdc_clk_on(priv);
513                 }
514
515                 board_cfg = &ch->cfg.board_cfg;
516                 if (board_cfg->display_off)
517                         board_cfg->display_off(board_cfg->board_data);
518
519         }
520
521         /* stop the lcdc */
522         if (priv->started) {
523                 sh_mobile_lcdc_start_stop(priv, 0);
524                 priv->started = 0;
525         }
526
527         /* stop clocks */
528         for (k = 0; k < ARRAY_SIZE(priv->ch); k++)
529                 if (priv->ch[k].enabled)
530                         sh_mobile_lcdc_clk_off(priv);
531 }
532
533 static int sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch)
534 {
535         int ifm, miftyp;
536
537         switch (ch->cfg.interface_type) {
538         case RGB8: ifm = 0; miftyp = 0; break;
539         case RGB9: ifm = 0; miftyp = 4; break;
540         case RGB12A: ifm = 0; miftyp = 5; break;
541         case RGB12B: ifm = 0; miftyp = 6; break;
542         case RGB16: ifm = 0; miftyp = 7; break;
543         case RGB18: ifm = 0; miftyp = 10; break;
544         case RGB24: ifm = 0; miftyp = 11; break;
545         case SYS8A: ifm = 1; miftyp = 0; break;
546         case SYS8B: ifm = 1; miftyp = 1; break;
547         case SYS8C: ifm = 1; miftyp = 2; break;
548         case SYS8D: ifm = 1; miftyp = 3; break;
549         case SYS9: ifm = 1; miftyp = 4; break;
550         case SYS12: ifm = 1; miftyp = 5; break;
551         case SYS16A: ifm = 1; miftyp = 7; break;
552         case SYS16B: ifm = 1; miftyp = 8; break;
553         case SYS16C: ifm = 1; miftyp = 9; break;
554         case SYS18: ifm = 1; miftyp = 10; break;
555         case SYS24: ifm = 1; miftyp = 11; break;
556         default: goto bad;
557         }
558
559         /* SUBLCD only supports SYS interface */
560         if (lcdc_chan_is_sublcd(ch)) {
561                 if (ifm == 0)
562                         goto bad;
563                 else
564                         ifm = 0;
565         }
566
567         ch->ldmt1r_value = (ifm << 12) | miftyp;
568         return 0;
569  bad:
570         return -EINVAL;
571 }
572
573 static int sh_mobile_lcdc_setup_clocks(struct platform_device *pdev,
574                                        int clock_source,
575                                        struct sh_mobile_lcdc_priv *priv)
576 {
577 #ifdef CONFIG_HAVE_CLK
578         char clk_name[8];
579 #endif
580         char *str;
581         int icksel;
582
583         switch (clock_source) {
584         case LCDC_CLK_BUS: str = "bus_clk"; icksel = 0; break;
585         case LCDC_CLK_PERIPHERAL: str = "peripheral_clk"; icksel = 1; break;
586         case LCDC_CLK_EXTERNAL: str = NULL; icksel = 2; break;
587         default:
588                 return -EINVAL;
589         }
590
591         priv->lddckr = icksel << 16;
592
593 #ifdef CONFIG_HAVE_CLK
594         atomic_set(&priv->clk_usecnt, -1);
595         snprintf(clk_name, sizeof(clk_name), "lcdc%d", pdev->id);
596         priv->clk = clk_get(&pdev->dev, clk_name);
597         if (IS_ERR(priv->clk)) {
598                 dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
599                 return PTR_ERR(priv->clk);
600         }
601         
602         if (str) {
603                 priv->dot_clk = clk_get(&pdev->dev, str);
604                 if (IS_ERR(priv->dot_clk)) {
605                         dev_err(&pdev->dev, "cannot get dot clock %s\n", str);
606                         clk_put(priv->clk);
607                         return PTR_ERR(priv->dot_clk);
608                 }
609         }
610 #endif
611
612         return 0;
613 }
614
615 static int sh_mobile_lcdc_setcolreg(u_int regno,
616                                     u_int red, u_int green, u_int blue,
617                                     u_int transp, struct fb_info *info)
618 {
619         u32 *palette = info->pseudo_palette;
620
621         if (regno >= PALETTE_NR)
622                 return -EINVAL;
623
624         /* only FB_VISUAL_TRUECOLOR supported */
625
626         red >>= 16 - info->var.red.length;
627         green >>= 16 - info->var.green.length;
628         blue >>= 16 - info->var.blue.length;
629         transp >>= 16 - info->var.transp.length;
630
631         palette[regno] = (red << info->var.red.offset) |
632           (green << info->var.green.offset) |
633           (blue << info->var.blue.offset) |
634           (transp << info->var.transp.offset);
635
636         return 0;
637 }
638
639 static struct fb_fix_screeninfo sh_mobile_lcdc_fix  = {
640         .id =           "SH Mobile LCDC",
641         .type =         FB_TYPE_PACKED_PIXELS,
642         .visual =       FB_VISUAL_TRUECOLOR,
643         .accel =        FB_ACCEL_NONE,
644 };
645
646 static void sh_mobile_lcdc_fillrect(struct fb_info *info,
647                                     const struct fb_fillrect *rect)
648 {
649         sys_fillrect(info, rect);
650         sh_mobile_lcdc_deferred_io_touch(info);
651 }
652
653 static void sh_mobile_lcdc_copyarea(struct fb_info *info,
654                                     const struct fb_copyarea *area)
655 {
656         sys_copyarea(info, area);
657         sh_mobile_lcdc_deferred_io_touch(info);
658 }
659
660 static void sh_mobile_lcdc_imageblit(struct fb_info *info,
661                                      const struct fb_image *image)
662 {
663         sys_imageblit(info, image);
664         sh_mobile_lcdc_deferred_io_touch(info);
665 }
666
667 static struct fb_ops sh_mobile_lcdc_ops = {
668         .fb_setcolreg   = sh_mobile_lcdc_setcolreg,
669         .fb_read        = fb_sys_read,
670         .fb_write       = fb_sys_write,
671         .fb_fillrect    = sh_mobile_lcdc_fillrect,
672         .fb_copyarea    = sh_mobile_lcdc_copyarea,
673         .fb_imageblit   = sh_mobile_lcdc_imageblit,
674 };
675
676 static int sh_mobile_lcdc_set_bpp(struct fb_var_screeninfo *var, int bpp)
677 {
678         switch (bpp) {
679         case 16: /* PKF[4:0] = 00011 - RGB 565 */
680                 var->red.offset = 11;
681                 var->red.length = 5;
682                 var->green.offset = 5;
683                 var->green.length = 6;
684                 var->blue.offset = 0;
685                 var->blue.length = 5;
686                 var->transp.offset = 0;
687                 var->transp.length = 0;
688                 break;
689
690         case 32: /* PKF[4:0] = 00000 - RGB 888
691                   * sh7722 pdf says 00RRGGBB but reality is GGBB00RR
692                   * this may be because LDDDSR has word swap enabled..
693                   */
694                 var->red.offset = 0;
695                 var->red.length = 8;
696                 var->green.offset = 24;
697                 var->green.length = 8;
698                 var->blue.offset = 16;
699                 var->blue.length = 8;
700                 var->transp.offset = 0;
701                 var->transp.length = 0;
702                 break;
703         default:
704                 return -EINVAL;
705         }
706         var->bits_per_pixel = bpp;
707         var->red.msb_right = 0;
708         var->green.msb_right = 0;
709         var->blue.msb_right = 0;
710         var->transp.msb_right = 0;
711         return 0;
712 }
713
714 static int sh_mobile_lcdc_suspend(struct device *dev)
715 {
716         struct platform_device *pdev = to_platform_device(dev);
717
718         sh_mobile_lcdc_stop(platform_get_drvdata(pdev));
719         return 0;
720 }
721
722 static int sh_mobile_lcdc_resume(struct device *dev)
723 {
724         struct platform_device *pdev = to_platform_device(dev);
725
726         return sh_mobile_lcdc_start(platform_get_drvdata(pdev));
727 }
728
729 static struct dev_pm_ops sh_mobile_lcdc_dev_pm_ops = {
730         .suspend = sh_mobile_lcdc_suspend,
731         .resume = sh_mobile_lcdc_resume,
732 };
733
734 static int sh_mobile_lcdc_remove(struct platform_device *pdev);
735
736 static int __init sh_mobile_lcdc_probe(struct platform_device *pdev)
737 {
738         struct fb_info *info;
739         struct sh_mobile_lcdc_priv *priv;
740         struct sh_mobile_lcdc_info *pdata;
741         struct sh_mobile_lcdc_chan_cfg *cfg;
742         struct resource *res;
743         int error;
744         void *buf;
745         int i, j;
746
747         if (!pdev->dev.platform_data) {
748                 dev_err(&pdev->dev, "no platform data defined\n");
749                 error = -EINVAL;
750                 goto err0;
751         }
752
753         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
754         i = platform_get_irq(pdev, 0);
755         if (!res || i < 0) {
756                 dev_err(&pdev->dev, "cannot get platform resources\n");
757                 error = -ENOENT;
758                 goto err0;
759         }
760
761         priv = kzalloc(sizeof(*priv), GFP_KERNEL);
762         if (!priv) {
763                 dev_err(&pdev->dev, "cannot allocate device data\n");
764                 error = -ENOMEM;
765                 goto err0;
766         }
767
768         error = request_irq(i, sh_mobile_lcdc_irq, IRQF_DISABLED,
769                             dev_name(&pdev->dev), priv);
770         if (error) {
771                 dev_err(&pdev->dev, "unable to request irq\n");
772                 goto err1;
773         }
774
775         priv->irq = i;
776         platform_set_drvdata(pdev, priv);
777         pdata = pdev->dev.platform_data;
778
779         j = 0;
780         for (i = 0; i < ARRAY_SIZE(pdata->ch); i++) {
781                 priv->ch[j].lcdc = priv;
782                 memcpy(&priv->ch[j].cfg, &pdata->ch[i], sizeof(pdata->ch[i]));
783
784                 error = sh_mobile_lcdc_check_interface(&priv->ch[i]);
785                 if (error) {
786                         dev_err(&pdev->dev, "unsupported interface type\n");
787                         goto err1;
788                 }
789                 init_waitqueue_head(&priv->ch[i].frame_end_wait);
790
791                 switch (pdata->ch[i].chan) {
792                 case LCDC_CHAN_MAINLCD:
793                         priv->ch[j].enabled = 1 << 1;
794                         priv->ch[j].reg_offs = lcdc_offs_mainlcd;
795                         j++;
796                         break;
797                 case LCDC_CHAN_SUBLCD:
798                         priv->ch[j].enabled = 1 << 2;
799                         priv->ch[j].reg_offs = lcdc_offs_sublcd;
800                         j++;
801                         break;
802                 }
803         }
804
805         if (!j) {
806                 dev_err(&pdev->dev, "no channels defined\n");
807                 error = -EINVAL;
808                 goto err1;
809         }
810
811         error = sh_mobile_lcdc_setup_clocks(pdev, pdata->clock_source, priv);
812         if (error) {
813                 dev_err(&pdev->dev, "unable to setup clocks\n");
814                 goto err1;
815         }
816
817         priv->base = ioremap_nocache(res->start, (res->end - res->start) + 1);
818
819         for (i = 0; i < j; i++) {
820                 info = &priv->ch[i].info;
821                 cfg = &priv->ch[i].cfg;
822
823                 info->fbops = &sh_mobile_lcdc_ops;
824                 info->var.xres = info->var.xres_virtual = cfg->lcd_cfg.xres;
825                 info->var.yres = info->var.yres_virtual = cfg->lcd_cfg.yres;
826                 info->var.width = cfg->lcd_size_cfg.width;
827                 info->var.height = cfg->lcd_size_cfg.height;
828                 info->var.activate = FB_ACTIVATE_NOW;
829                 error = sh_mobile_lcdc_set_bpp(&info->var, cfg->bpp);
830                 if (error)
831                         break;
832
833                 info->fix = sh_mobile_lcdc_fix;
834                 info->fix.line_length = cfg->lcd_cfg.xres * (cfg->bpp / 8);
835                 info->fix.smem_len = info->fix.line_length * cfg->lcd_cfg.yres;
836
837                 buf = dma_alloc_coherent(&pdev->dev, info->fix.smem_len,
838                                          &priv->ch[i].dma_handle, GFP_KERNEL);
839                 if (!buf) {
840                         dev_err(&pdev->dev, "unable to allocate buffer\n");
841                         error = -ENOMEM;
842                         break;
843                 }
844
845                 info->pseudo_palette = &priv->ch[i].pseudo_palette;
846                 info->flags = FBINFO_FLAG_DEFAULT;
847
848                 error = fb_alloc_cmap(&info->cmap, PALETTE_NR, 0);
849                 if (error < 0) {
850                         dev_err(&pdev->dev, "unable to allocate cmap\n");
851                         dma_free_coherent(&pdev->dev, info->fix.smem_len,
852                                           buf, priv->ch[i].dma_handle);
853                         break;
854                 }
855
856                 memset(buf, 0, info->fix.smem_len);
857                 info->fix.smem_start = priv->ch[i].dma_handle;
858                 info->screen_base = buf;
859                 info->device = &pdev->dev;
860                 info->par = &priv->ch[i];
861         }
862
863         if (error)
864                 goto err1;
865
866         error = sh_mobile_lcdc_start(priv);
867         if (error) {
868                 dev_err(&pdev->dev, "unable to start hardware\n");
869                 goto err1;
870         }
871
872         for (i = 0; i < j; i++) {
873                 struct sh_mobile_lcdc_chan *ch = priv->ch + i;
874
875                 info = &ch->info;
876
877                 if (info->fbdefio) {
878                         priv->ch->sglist = vmalloc(sizeof(struct scatterlist) *
879                                         info->fix.smem_len >> PAGE_SHIFT);
880                         if (!priv->ch->sglist) {
881                                 dev_err(&pdev->dev, "cannot allocate sglist\n");
882                                 goto err1;
883                         }
884                 }
885
886                 error = register_framebuffer(info);
887                 if (error < 0)
888                         goto err1;
889
890                 dev_info(info->dev,
891                          "registered %s/%s as %dx%d %dbpp.\n",
892                          pdev->name,
893                          (ch->cfg.chan == LCDC_CHAN_MAINLCD) ?
894                          "mainlcd" : "sublcd",
895                          (int) ch->cfg.lcd_cfg.xres,
896                          (int) ch->cfg.lcd_cfg.yres,
897                          ch->cfg.bpp);
898
899                 /* deferred io mode: disable clock to save power */
900                 if (info->fbdefio)
901                         sh_mobile_lcdc_clk_off(priv);
902         }
903
904         return 0;
905  err1:
906         sh_mobile_lcdc_remove(pdev);
907  err0:
908         return error;
909 }
910
911 static int sh_mobile_lcdc_remove(struct platform_device *pdev)
912 {
913         struct sh_mobile_lcdc_priv *priv = platform_get_drvdata(pdev);
914         struct fb_info *info;
915         int i;
916
917         for (i = 0; i < ARRAY_SIZE(priv->ch); i++)
918                 if (priv->ch[i].info.dev)
919                         unregister_framebuffer(&priv->ch[i].info);
920
921         sh_mobile_lcdc_stop(priv);
922
923         for (i = 0; i < ARRAY_SIZE(priv->ch); i++) {
924                 info = &priv->ch[i].info;
925
926                 if (!info->device)
927                         continue;
928
929                 if (priv->ch[i].sglist)
930                         vfree(priv->ch[i].sglist);
931
932                 dma_free_coherent(&pdev->dev, info->fix.smem_len,
933                                   info->screen_base, priv->ch[i].dma_handle);
934                 fb_dealloc_cmap(&info->cmap);
935         }
936
937 #ifdef CONFIG_HAVE_CLK
938         if (priv->dot_clk)
939                 clk_put(priv->dot_clk);
940         clk_put(priv->clk);
941 #endif
942
943         if (priv->base)
944                 iounmap(priv->base);
945
946         if (priv->irq)
947                 free_irq(priv->irq, priv);
948         kfree(priv);
949         return 0;
950 }
951
952 static struct platform_driver sh_mobile_lcdc_driver = {
953         .driver         = {
954                 .name           = "sh_mobile_lcdc_fb",
955                 .owner          = THIS_MODULE,
956                 .pm             = &sh_mobile_lcdc_dev_pm_ops,
957         },
958         .probe          = sh_mobile_lcdc_probe,
959         .remove         = sh_mobile_lcdc_remove,
960 };
961
962 static int __init sh_mobile_lcdc_init(void)
963 {
964         return platform_driver_register(&sh_mobile_lcdc_driver);
965 }
966
967 static void __exit sh_mobile_lcdc_exit(void)
968 {
969         platform_driver_unregister(&sh_mobile_lcdc_driver);
970 }
971
972 module_init(sh_mobile_lcdc_init);
973 module_exit(sh_mobile_lcdc_exit);
974
975 MODULE_DESCRIPTION("SuperH Mobile LCDC Framebuffer driver");
976 MODULE_AUTHOR("Magnus Damm <damm@opensource.se>");
977 MODULE_LICENSE("GPL v2");