Merge branch 'oprofile-for-tip' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6] / drivers / video / tmiofb.c
1 /*
2  * Frame Buffer Device for Toshiba Mobile IO(TMIO) controller
3  *
4  * Copyright(C) 2005-2006 Chris Humbert
5  * Copyright(C) 2005 Dirk Opfer
6  * Copytight(C) 2007,2008 Dmitry Baryshkov
7  *
8  * Based on:
9  *      drivers/video/w100fb.c
10  *      code written by Sharp/Lineo for 2.4 kernels
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License version 2
14  * as published by the Free Software Foundation;
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  */
21
22 #include <linux/kernel.h>
23 #include <linux/module.h>
24 #include <linux/platform_device.h>
25 #include <linux/fb.h>
26 #include <linux/interrupt.h>
27 #include <linux/delay.h>
28 /* Why should fb driver call console functions? because acquire_console_sem() */
29 #include <linux/console.h>
30 #include <linux/mfd/core.h>
31 #include <linux/mfd/tmio.h>
32 #include <linux/uaccess.h>
33
34 /*
35  * accelerator commands
36  */
37 #define TMIOFB_ACC_CSADR(x)     (0x00000000 | ((x) & 0x001ffffe))
38 #define TMIOFB_ACC_CHPIX(x)     (0x01000000 | ((x) & 0x000003ff))
39 #define TMIOFB_ACC_CVPIX(x)     (0x02000000 | ((x) & 0x000003ff))
40 #define TMIOFB_ACC_PSADR(x)     (0x03000000 | ((x) & 0x00fffffe))
41 #define TMIOFB_ACC_PHPIX(x)     (0x04000000 | ((x) & 0x000003ff))
42 #define TMIOFB_ACC_PVPIX(x)     (0x05000000 | ((x) & 0x000003ff))
43 #define TMIOFB_ACC_PHOFS(x)     (0x06000000 | ((x) & 0x000003ff))
44 #define TMIOFB_ACC_PVOFS(x)     (0x07000000 | ((x) & 0x000003ff))
45 #define TMIOFB_ACC_POADR(x)     (0x08000000 | ((x) & 0x00fffffe))
46 #define TMIOFB_ACC_RSTR(x)      (0x09000000 | ((x) & 0x000000ff))
47 #define TMIOFB_ACC_TCLOR(x)     (0x0A000000 | ((x) & 0x0000ffff))
48 #define TMIOFB_ACC_FILL(x)      (0x0B000000 | ((x) & 0x0000ffff))
49 #define TMIOFB_ACC_DSADR(x)     (0x0C000000 | ((x) & 0x00fffffe))
50 #define TMIOFB_ACC_SSADR(x)     (0x0D000000 | ((x) & 0x00fffffe))
51 #define TMIOFB_ACC_DHPIX(x)     (0x0E000000 | ((x) & 0x000003ff))
52 #define TMIOFB_ACC_DVPIX(x)     (0x0F000000 | ((x) & 0x000003ff))
53 #define TMIOFB_ACC_SHPIX(x)     (0x10000000 | ((x) & 0x000003ff))
54 #define TMIOFB_ACC_SVPIX(x)     (0x11000000 | ((x) & 0x000003ff))
55 #define TMIOFB_ACC_LBINI(x)     (0x12000000 | ((x) & 0x0000ffff))
56 #define TMIOFB_ACC_LBK2(x)      (0x13000000 | ((x) & 0x0000ffff))
57 #define TMIOFB_ACC_SHBINI(x)    (0x14000000 | ((x) & 0x0000ffff))
58 #define TMIOFB_ACC_SHBK2(x)     (0x15000000 | ((x) & 0x0000ffff))
59 #define TMIOFB_ACC_SVBINI(x)    (0x16000000 | ((x) & 0x0000ffff))
60 #define TMIOFB_ACC_SVBK2(x)     (0x17000000 | ((x) & 0x0000ffff))
61
62 #define TMIOFB_ACC_CMGO         0x20000000
63 #define TMIOFB_ACC_CMGO_CEND    0x00000001
64 #define TMIOFB_ACC_CMGO_INT     0x00000002
65 #define TMIOFB_ACC_CMGO_CMOD    0x00000010
66 #define TMIOFB_ACC_CMGO_CDVRV   0x00000020
67 #define TMIOFB_ACC_CMGO_CDHRV   0x00000040
68 #define TMIOFB_ACC_CMGO_RUND    0x00008000
69 #define TMIOFB_ACC_SCGO         0x21000000
70 #define TMIOFB_ACC_SCGO_CEND    0x00000001
71 #define TMIOFB_ACC_SCGO_INT     0x00000002
72 #define TMIOFB_ACC_SCGO_ROP3    0x00000004
73 #define TMIOFB_ACC_SCGO_TRNS    0x00000008
74 #define TMIOFB_ACC_SCGO_DVRV    0x00000010
75 #define TMIOFB_ACC_SCGO_DHRV    0x00000020
76 #define TMIOFB_ACC_SCGO_SVRV    0x00000040
77 #define TMIOFB_ACC_SCGO_SHRV    0x00000080
78 #define TMIOFB_ACC_SCGO_DSTXY   0x00008000
79 #define TMIOFB_ACC_SBGO         0x22000000
80 #define TMIOFB_ACC_SBGO_CEND    0x00000001
81 #define TMIOFB_ACC_SBGO_INT     0x00000002
82 #define TMIOFB_ACC_SBGO_DVRV    0x00000010
83 #define TMIOFB_ACC_SBGO_DHRV    0x00000020
84 #define TMIOFB_ACC_SBGO_SVRV    0x00000040
85 #define TMIOFB_ACC_SBGO_SHRV    0x00000080
86 #define TMIOFB_ACC_SBGO_SBMD    0x00000100
87 #define TMIOFB_ACC_FLGO         0x23000000
88 #define TMIOFB_ACC_FLGO_CEND    0x00000001
89 #define TMIOFB_ACC_FLGO_INT     0x00000002
90 #define TMIOFB_ACC_FLGO_ROP3    0x00000004
91 #define TMIOFB_ACC_LDGO         0x24000000
92 #define TMIOFB_ACC_LDGO_CEND    0x00000001
93 #define TMIOFB_ACC_LDGO_INT     0x00000002
94 #define TMIOFB_ACC_LDGO_ROP3    0x00000004
95 #define TMIOFB_ACC_LDGO_ENDPX   0x00000008
96 #define TMIOFB_ACC_LDGO_LVRV    0x00000010
97 #define TMIOFB_ACC_LDGO_LHRV    0x00000020
98 #define TMIOFB_ACC_LDGO_LDMOD   0x00000040
99
100 /* a FIFO is always allocated, even if acceleration is not used */
101 #define TMIOFB_FIFO_SIZE        512
102
103 /*
104  * LCD Host Controller Configuration Register
105  *
106  * This iomem area supports only 16-bit IO.
107  */
108 #define CCR_CMD                 0x04 /* Command                         */
109 #define CCR_REVID               0x08 /* Revision ID                     */
110 #define CCR_BASEL               0x10 /* LCD Control Reg Base Addr Low   */
111 #define CCR_BASEH               0x12 /* LCD Control Reg Base Addr High  */
112 #define CCR_UGCC                0x40 /* Unified Gated Clock Control     */
113 #define CCR_GCC                 0x42 /* Gated Clock Control             */
114 #define CCR_USC                 0x50 /* Unified Software Clear          */
115 #define CCR_VRAMRTC             0x60 /* VRAM Timing Control             */
116                                 /* 0x61 VRAM Refresh Control            */
117 #define CCR_VRAMSAC             0x62 /* VRAM Access Control             */
118                                 /* 0x63 VRAM Status                     */
119 #define CCR_VRAMBC              0x64 /* VRAM Block Control              */
120
121 /*
122  * LCD Control Register
123  *
124  * This iomem area supports only 16-bit IO.
125  */
126 #define LCR_UIS                 0x000 /* Unified Interrupt Status       */
127 #define LCR_VHPN                0x008 /* VRAM Horizontal Pixel Number   */
128 #define LCR_CFSAL               0x00a /* Command FIFO Start Address Low */
129 #define LCR_CFSAH               0x00c /* Command FIFO Start Address High */
130 #define LCR_CFS                 0x00e /* Command FIFO Size              */
131 #define LCR_CFWS                0x010 /* Command FIFO Writeable Size    */
132 #define LCR_BBIE                0x012 /* BitBLT Interrupt Enable        */
133 #define LCR_BBISC               0x014 /* BitBLT Interrupt Status and Clear */
134 #define LCR_CCS                 0x016 /* Command Count Status           */
135 #define LCR_BBES                0x018 /* BitBLT Execution Status        */
136 #define LCR_CMDL                0x01c /* Command Low                    */
137 #define LCR_CMDH                0x01e /* Command High                   */
138 #define LCR_CFC                 0x022 /* Command FIFO Clear             */
139 #define LCR_CCIFC               0x024 /* CMOS Camera IF Control         */
140 #define LCR_HWT                 0x026 /* Hardware Test                  */
141 #define LCR_LCDCCRC             0x100 /* LCDC Clock and Reset Control   */
142 #define LCR_LCDCC               0x102 /* LCDC Control                   */
143 #define LCR_LCDCOPC             0x104 /* LCDC Output Pin Control        */
144 #define LCR_LCDIS               0x108 /* LCD Interrupt Status           */
145 #define LCR_LCDIM               0x10a /* LCD Interrupt Mask             */
146 #define LCR_LCDIE               0x10c /* LCD Interrupt Enable           */
147 #define LCR_GDSAL               0x122 /* Graphics Display Start Address Low */
148 #define LCR_GDSAH               0x124 /* Graphics Display Start Address High */
149 #define LCR_VHPCL               0x12a /* VRAM Horizontal Pixel Count Low */
150 #define LCR_VHPCH               0x12c /* VRAM Horizontal Pixel Count High */
151 #define LCR_GM                  0x12e /* Graphic Mode(VRAM access enable) */
152 #define LCR_HT                  0x140 /* Horizontal Total               */
153 #define LCR_HDS                 0x142 /* Horizontal Display Start       */
154 #define LCR_HSS                 0x144 /* H-Sync Start                   */
155 #define LCR_HSE                 0x146 /* H-Sync End                     */
156 #define LCR_HNP                 0x14c /* Horizontal Number of Pixels    */
157 #define LCR_VT                  0x150 /* Vertical Total                 */
158 #define LCR_VDS                 0x152 /* Vertical Display Start         */
159 #define LCR_VSS                 0x154 /* V-Sync Start                   */
160 #define LCR_VSE                 0x156 /* V-Sync End                     */
161 #define LCR_CDLN                0x160 /* Current Display Line Number    */
162 #define LCR_ILN                 0x162 /* Interrupt Line Number          */
163 #define LCR_SP                  0x164 /* Sync Polarity                  */
164 #define LCR_MISC                0x166 /* MISC(RGB565 mode)              */
165 #define LCR_VIHSS               0x16a /* Video Interface H-Sync Start   */
166 #define LCR_VIVS                0x16c /* Video Interface Vertical Start */
167 #define LCR_VIVE                0x16e /* Video Interface Vertical End   */
168 #define LCR_VIVSS               0x170 /* Video Interface V-Sync Start   */
169 #define LCR_VCCIS               0x17e /* Video / CMOS Camera Interface Select */
170 #define LCR_VIDWSAL             0x180 /* VI Data Write Start Address Low */
171 #define LCR_VIDWSAH             0x182 /* VI Data Write Start Address High */
172 #define LCR_VIDRSAL             0x184 /* VI Data Read Start Address Low */
173 #define LCR_VIDRSAH             0x186 /* VI Data Read Start Address High */
174 #define LCR_VIPDDST             0x188 /* VI Picture Data Display Start Timing */
175 #define LCR_VIPDDET             0x186 /* VI Picture Data Display End Timing */
176 #define LCR_VIE                 0x18c /* Video Interface Enable         */
177 #define LCR_VCS                 0x18e /* Video/Camera Select            */
178 #define LCR_VPHWC               0x194 /* Video Picture Horizontal Wait Count */
179 #define LCR_VPHS                0x196 /* Video Picture Horizontal Size  */
180 #define LCR_VPVWC               0x198 /* Video Picture Vertical Wait Count */
181 #define LCR_VPVS                0x19a /* Video Picture Vertical Size    */
182 #define LCR_PLHPIX              0x1a0 /* PLHPIX                         */
183 #define LCR_XS                  0x1a2 /* XStart                         */
184 #define LCR_XCKHW               0x1a4 /* XCK High Width                 */
185 #define LCR_STHS                0x1a8 /* STH Start                      */
186 #define LCR_VT2                 0x1aa /* Vertical Total                 */
187 #define LCR_YCKSW               0x1ac /* YCK Start Wait                 */
188 #define LCR_YSTS                0x1ae /* YST Start                      */
189 #define LCR_PPOLS               0x1b0 /* #PPOL Start                    */
190 #define LCR_PRECW               0x1b2 /* PREC Width                     */
191 #define LCR_VCLKHW              0x1b4 /* VCLK High Width                */
192 #define LCR_OC                  0x1b6 /* Output Control                 */
193
194 static char *mode_option __devinitdata;
195
196 struct tmiofb_par {
197         u32                             pseudo_palette[16];
198
199 #ifdef CONFIG_FB_TMIO_ACCELL
200         wait_queue_head_t               wait_acc;
201         bool                            use_polling;
202 #endif
203
204         void __iomem                    *ccr;
205         void __iomem                    *lcr;
206 };
207
208 /*--------------------------------------------------------------------------*/
209
210 /*
211  * reasons for an interrupt:
212  *      uis     bbisc   lcdis
213  *      0100    0001    accelerator command completed
214  *      2000    0001    vsync start
215  *      2000    0002    display start
216  *      2000    0004    line number match(0x1ff mask???)
217  */
218 static irqreturn_t tmiofb_irq(int irq, void *__info)
219 {
220         struct fb_info *info = __info;
221         struct tmiofb_par *par = info->par;
222         unsigned int bbisc = tmio_ioread16(par->lcr + LCR_BBISC);
223
224
225         tmio_iowrite16(bbisc, par->lcr + LCR_BBISC);
226
227 #ifdef CONFIG_FB_TMIO_ACCELL
228         /*
229          * We were in polling mode and now we got correct irq.
230          * Switch back to IRQ-based sync of command FIFO
231          */
232         if (unlikely(par->use_polling && irq != -1)) {
233                 printk(KERN_INFO "tmiofb: switching to waitq\n");
234                 par->use_polling = false;
235         }
236
237         if (bbisc & 1)
238                 wake_up(&par->wait_acc);
239 #endif
240
241         return IRQ_HANDLED;
242 }
243
244
245 /*--------------------------------------------------------------------------*/
246
247
248 /*
249  * Turns off the LCD controller and LCD host controller.
250  */
251 static int tmiofb_hw_stop(struct platform_device *dev)
252 {
253         struct mfd_cell *cell = dev->dev.platform_data;
254         struct tmio_fb_data *data = cell->driver_data;
255         struct fb_info *info = platform_get_drvdata(dev);
256         struct tmiofb_par *par = info->par;
257
258         tmio_iowrite16(0, par->ccr + CCR_UGCC);
259         tmio_iowrite16(0, par->lcr + LCR_GM);
260         data->lcd_set_power(dev, 0);
261         tmio_iowrite16(0x0010, par->lcr + LCR_LCDCCRC);
262
263         return 0;
264 }
265
266 /*
267  * Initializes the LCD host controller.
268  */
269 static int tmiofb_hw_init(struct platform_device *dev)
270 {
271         struct mfd_cell *cell = dev->dev.platform_data;
272         struct fb_info *info = platform_get_drvdata(dev);
273         struct tmiofb_par *par = info->par;
274         const struct resource *nlcr = &cell->resources[0];
275         const struct resource *vram = &cell->resources[2];
276         unsigned long base;
277
278         if (nlcr == NULL || vram == NULL)
279                 return -EINVAL;
280
281         base = nlcr->start;
282
283         tmio_iowrite16(0x003a, par->ccr + CCR_UGCC);
284         tmio_iowrite16(0x003a, par->ccr + CCR_GCC);
285         tmio_iowrite16(0x3f00, par->ccr + CCR_USC);
286
287         msleep(2); /* wait for device to settle */
288
289         tmio_iowrite16(0x0000, par->ccr + CCR_USC);
290         tmio_iowrite16(base >> 16, par->ccr + CCR_BASEH);
291         tmio_iowrite16(base, par->ccr + CCR_BASEL);
292         tmio_iowrite16(0x0002, par->ccr + CCR_CMD); /* base address enable */
293         tmio_iowrite16(0x40a8, par->ccr + CCR_VRAMRTC); /* VRAMRC, VRAMTC */
294         tmio_iowrite16(0x0018, par->ccr + CCR_VRAMSAC); /* VRAMSTS, VRAMAC */
295         tmio_iowrite16(0x0002, par->ccr + CCR_VRAMBC);
296         msleep(2); /* wait for device to settle */
297         tmio_iowrite16(0x000b, par->ccr + CCR_VRAMBC);
298
299         base = vram->start + info->screen_size;
300         tmio_iowrite16(base >> 16, par->lcr + LCR_CFSAH);
301         tmio_iowrite16(base, par->lcr + LCR_CFSAL);
302         tmio_iowrite16(TMIOFB_FIFO_SIZE - 1, par->lcr + LCR_CFS);
303         tmio_iowrite16(1, par->lcr + LCR_CFC);
304         tmio_iowrite16(1, par->lcr + LCR_BBIE);
305         tmio_iowrite16(0, par->lcr + LCR_CFWS);
306
307         return 0;
308 }
309
310 /*
311  * Sets the LCD controller's output resolution and pixel clock
312  */
313 static void tmiofb_hw_mode(struct platform_device *dev)
314 {
315         struct mfd_cell *cell = dev->dev.platform_data;
316         struct tmio_fb_data *data = cell->driver_data;
317         struct fb_info *info = platform_get_drvdata(dev);
318         struct fb_videomode *mode = info->mode;
319         struct tmiofb_par *par = info->par;
320         unsigned int i;
321
322         tmio_iowrite16(0, par->lcr + LCR_GM);
323         data->lcd_set_power(dev, 0);
324         tmio_iowrite16(0x0010, par->lcr + LCR_LCDCCRC);
325         data->lcd_mode(dev, mode);
326         data->lcd_set_power(dev, 1);
327
328         tmio_iowrite16(info->fix.line_length, par->lcr + LCR_VHPN);
329         tmio_iowrite16(0, par->lcr + LCR_GDSAH);
330         tmio_iowrite16(0, par->lcr + LCR_GDSAL);
331         tmio_iowrite16(info->fix.line_length >> 16, par->lcr + LCR_VHPCH);
332         tmio_iowrite16(info->fix.line_length, par->lcr + LCR_VHPCL);
333         tmio_iowrite16(i = 0, par->lcr + LCR_HSS);
334         tmio_iowrite16(i += mode->hsync_len, par->lcr + LCR_HSE);
335         tmio_iowrite16(i += mode->left_margin, par->lcr + LCR_HDS);
336         tmio_iowrite16(i += mode->xres + mode->right_margin, par->lcr + LCR_HT);
337         tmio_iowrite16(mode->xres, par->lcr + LCR_HNP);
338         tmio_iowrite16(i = 0, par->lcr + LCR_VSS);
339         tmio_iowrite16(i += mode->vsync_len, par->lcr + LCR_VSE);
340         tmio_iowrite16(i += mode->upper_margin, par->lcr + LCR_VDS);
341         tmio_iowrite16(i += mode->yres, par->lcr + LCR_ILN);
342         tmio_iowrite16(i += mode->lower_margin, par->lcr + LCR_VT);
343         tmio_iowrite16(3, par->lcr + LCR_MISC); /* RGB565 mode */
344         tmio_iowrite16(1, par->lcr + LCR_GM); /* VRAM enable */
345         tmio_iowrite16(0x4007, par->lcr + LCR_LCDCC);
346         tmio_iowrite16(3, par->lcr + LCR_SP);  /* sync polarity */
347
348         tmio_iowrite16(0x0010, par->lcr + LCR_LCDCCRC);
349         msleep(5); /* wait for device to settle */
350         tmio_iowrite16(0x0014, par->lcr + LCR_LCDCCRC); /* STOP_CKP */
351         msleep(5); /* wait for device to settle */
352         tmio_iowrite16(0x0015, par->lcr + LCR_LCDCCRC); /* STOP_CKP|SOFT_RESET*/
353         tmio_iowrite16(0xfffa, par->lcr + LCR_VCS);
354 }
355
356 /*--------------------------------------------------------------------------*/
357
358 #ifdef CONFIG_FB_TMIO_ACCELL
359 static int __must_check
360 tmiofb_acc_wait(struct fb_info *info, unsigned int ccs)
361 {
362         struct tmiofb_par *par = info->par;
363         /*
364          * This code can be called whith interrupts disabled.
365          * So instead of relaying on irq to trigger the event,
366          * poll the state till the necessary command is executed.
367          */
368         if (irqs_disabled() || par->use_polling) {
369                 int i = 0;
370                 while (tmio_ioread16(par->lcr + LCR_CCS) > ccs) {
371                         udelay(1);
372                         i++;
373                         if (i > 10000) {
374                                 pr_err("tmiofb: timeout waiting for %d\n",
375                                                 ccs);
376                                 return -ETIMEDOUT;
377                         }
378                         tmiofb_irq(-1, info);
379                 }
380         } else {
381                 if (!wait_event_interruptible_timeout(par->wait_acc,
382                                 tmio_ioread16(par->lcr + LCR_CCS) <= ccs,
383                                 1000)) {
384                         pr_err("tmiofb: timeout waiting for %d\n", ccs);
385                         return -ETIMEDOUT;
386                 }
387         }
388
389         return 0;
390 }
391
392 /*
393  * Writes an accelerator command to the accelerator's FIFO.
394  */
395 static int
396 tmiofb_acc_write(struct fb_info *info, const u32 *cmd, unsigned int count)
397 {
398         struct tmiofb_par *par = info->par;
399         int ret;
400
401         ret = tmiofb_acc_wait(info, TMIOFB_FIFO_SIZE - count);
402         if (ret)
403                 return ret;
404
405         for (; count; count--, cmd++) {
406                 tmio_iowrite16(*cmd >> 16, par->lcr + LCR_CMDH);
407                 tmio_iowrite16(*cmd, par->lcr + LCR_CMDL);
408         }
409
410         return ret;
411 }
412
413 /*
414  * Wait for the accelerator to finish its operations before writing
415  * to the framebuffer for consistent display output.
416  */
417 static int tmiofb_sync(struct fb_info *fbi)
418 {
419         struct tmiofb_par *par = fbi->par;
420
421         int ret;
422         int i = 0;
423
424         ret = tmiofb_acc_wait(fbi, 0);
425
426         while (tmio_ioread16(par->lcr + LCR_BBES) & 2) { /* blit active */
427                 udelay(1);
428                 i++ ;
429                 if (i > 10000) {
430                         printk(KERN_ERR "timeout waiting for blit to end!\n");
431                         return -ETIMEDOUT;
432                 }
433         }
434
435         return ret;
436 }
437
438 static void
439 tmiofb_fillrect(struct fb_info *fbi, const struct fb_fillrect *rect)
440 {
441         const u32 cmd[] = {
442                 TMIOFB_ACC_DSADR((rect->dy * fbi->mode->xres + rect->dx) * 2),
443                 TMIOFB_ACC_DHPIX(rect->width - 1),
444                 TMIOFB_ACC_DVPIX(rect->height - 1),
445                 TMIOFB_ACC_FILL(rect->color),
446                 TMIOFB_ACC_FLGO,
447         };
448
449         if (fbi->state != FBINFO_STATE_RUNNING ||
450             fbi->flags & FBINFO_HWACCEL_DISABLED) {
451                 cfb_fillrect(fbi, rect);
452                 return;
453         }
454
455         tmiofb_acc_write(fbi, cmd, ARRAY_SIZE(cmd));
456 }
457
458 static void
459 tmiofb_copyarea(struct fb_info *fbi, const struct fb_copyarea *area)
460 {
461         const u32 cmd[] = {
462                 TMIOFB_ACC_DSADR((area->dy * fbi->mode->xres + area->dx) * 2),
463                 TMIOFB_ACC_DHPIX(area->width - 1),
464                 TMIOFB_ACC_DVPIX(area->height - 1),
465                 TMIOFB_ACC_SSADR((area->sy * fbi->mode->xres + area->sx) * 2),
466                 TMIOFB_ACC_SCGO,
467         };
468
469         if (fbi->state != FBINFO_STATE_RUNNING ||
470             fbi->flags & FBINFO_HWACCEL_DISABLED) {
471                 cfb_copyarea(fbi, area);
472                 return;
473         }
474
475         tmiofb_acc_write(fbi, cmd, ARRAY_SIZE(cmd));
476 }
477 #endif
478
479 static void tmiofb_clearscreen(struct fb_info *info)
480 {
481         const struct fb_fillrect rect = {
482                 .dx     = 0,
483                 .dy     = 0,
484                 .width  = info->mode->xres,
485                 .height = info->mode->yres,
486                 .color  = 0,
487                 .rop    = ROP_COPY,
488         };
489
490         info->fbops->fb_fillrect(info, &rect);
491 }
492
493 static int tmiofb_vblank(struct fb_info *fbi, struct fb_vblank *vblank)
494 {
495         struct tmiofb_par *par = fbi->par;
496         struct fb_videomode *mode = fbi->mode;
497         unsigned int vcount = tmio_ioread16(par->lcr + LCR_CDLN);
498         unsigned int vds = mode->vsync_len + mode->upper_margin;
499
500         vblank->vcount = vcount;
501         vblank->flags = FB_VBLANK_HAVE_VBLANK | FB_VBLANK_HAVE_VCOUNT
502                                                 | FB_VBLANK_HAVE_VSYNC;
503
504         if (vcount < mode->vsync_len)
505                 vblank->flags |= FB_VBLANK_VSYNCING;
506
507         if (vcount < vds || vcount > vds + mode->yres)
508                 vblank->flags |= FB_VBLANK_VBLANKING;
509
510         return 0;
511 }
512
513
514 static int tmiofb_ioctl(struct fb_info *fbi,
515                 unsigned int cmd, unsigned long arg)
516 {
517         switch (cmd) {
518         case FBIOGET_VBLANK: {
519                 struct fb_vblank vblank = {0};
520                 void __user *argp = (void __user *) arg;
521
522                 tmiofb_vblank(fbi, &vblank);
523                 if (copy_to_user(argp, &vblank, sizeof vblank))
524                         return -EFAULT;
525                 return 0;
526         }
527
528 #ifdef CONFIG_FB_TMIO_ACCELL
529         case FBIO_TMIO_ACC_SYNC:
530                 tmiofb_sync(fbi);
531                 return 0;
532
533         case FBIO_TMIO_ACC_WRITE: {
534                 u32 __user *argp = (void __user *) arg;
535                 u32 len;
536                 u32 acc[16];
537
538                 if (get_user(len, argp))
539                         return -EFAULT;
540                 if (len > ARRAY_SIZE(acc))
541                         return -EINVAL;
542                 if (copy_from_user(acc, argp + 1, sizeof(u32) * len))
543                         return -EFAULT;
544
545                 return tmiofb_acc_write(fbi, acc, len);
546         }
547 #endif
548         }
549
550         return -ENOTTY;
551 }
552
553 /*--------------------------------------------------------------------------*/
554
555 /* Select the smallest mode that allows the desired resolution to be
556  * displayed.  If desired, the x and y parameters can be rounded up to
557  * match the selected mode.
558  */
559 static struct fb_videomode *
560 tmiofb_find_mode(struct fb_info *info, struct fb_var_screeninfo *var)
561 {
562         struct mfd_cell *cell =
563                 info->device->platform_data;
564         struct tmio_fb_data *data = cell->driver_data;
565         struct fb_videomode *best = NULL;
566         int i;
567
568         for (i = 0; i < data->num_modes; i++) {
569                 struct fb_videomode *mode = data->modes + i;
570
571                 if (mode->xres >= var->xres && mode->yres >= var->yres
572                                 && (!best || (mode->xres < best->xres
573                                            && mode->yres < best->yres)))
574                         best = mode;
575         }
576
577         return best;
578 }
579
580 static int tmiofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
581 {
582
583         struct fb_videomode *mode;
584         struct mfd_cell *cell =
585                 info->device->platform_data;
586         struct tmio_fb_data *data = cell->driver_data;
587
588         mode = tmiofb_find_mode(info, var);
589         if (!mode || var->bits_per_pixel > 16)
590                 return -EINVAL;
591
592         fb_videomode_to_var(var, mode);
593
594         var->xres_virtual = mode->xres;
595         var->yres_virtual = info->screen_size / (mode->xres * 2);
596
597         if (var->yres_virtual < var->yres)
598                 return -EINVAL;
599
600         var->xoffset = 0;
601         var->yoffset = 0;
602         var->bits_per_pixel = 16;
603         var->grayscale = 0;
604         var->red.offset = 11;
605         var->red.length = 5;
606         var->green.offset = 5;
607         var->green.length = 6;
608         var->blue.offset = 0;
609         var->blue.length = 5;
610         var->transp.offset = 0;
611         var->transp.length = 0;
612         var->nonstd = 0;
613         var->height = data->height; /* mm */
614         var->width = data->width; /* mm */
615         var->rotate = 0;
616         return 0;
617 }
618
619 static int tmiofb_set_par(struct fb_info *info)
620 {
621         struct fb_var_screeninfo *var = &info->var;
622         struct fb_videomode *mode;
623
624         mode = tmiofb_find_mode(info, var);
625         if (!mode)
626                 return -EINVAL;
627
628         info->mode = mode;
629         info->fix.line_length = info->mode->xres *
630                         var->bits_per_pixel / 8;
631
632         tmiofb_hw_mode(to_platform_device(info->device));
633         tmiofb_clearscreen(info);
634         return 0;
635 }
636
637 static int tmiofb_setcolreg(unsigned regno, unsigned red, unsigned green,
638                            unsigned blue, unsigned transp,
639                            struct fb_info *info)
640 {
641         struct tmiofb_par *par = info->par;
642
643         if (regno < ARRAY_SIZE(par->pseudo_palette)) {
644                 par->pseudo_palette[regno] =
645                         ((red & 0xf800)) |
646                         ((green & 0xfc00) >>  5) |
647                         ((blue & 0xf800) >> 11);
648                 return 0;
649         }
650
651         return -EINVAL;
652 }
653
654 static int tmiofb_blank(int blank, struct fb_info *info)
655 {
656         /*
657          * everything is done in lcd/bl drivers.
658          * this is purely to make sysfs happy and work.
659          */
660         return 0;
661 }
662
663 static struct fb_ops tmiofb_ops = {
664         .owner          = THIS_MODULE,
665
666         .fb_ioctl       = tmiofb_ioctl,
667         .fb_check_var   = tmiofb_check_var,
668         .fb_set_par     = tmiofb_set_par,
669         .fb_setcolreg   = tmiofb_setcolreg,
670         .fb_blank       = tmiofb_blank,
671         .fb_imageblit   = cfb_imageblit,
672 #ifdef CONFIG_FB_TMIO_ACCELL
673         .fb_sync        = tmiofb_sync,
674         .fb_fillrect    = tmiofb_fillrect,
675         .fb_copyarea    = tmiofb_copyarea,
676 #else
677         .fb_fillrect    = cfb_fillrect,
678         .fb_copyarea    = cfb_copyarea,
679 #endif
680 };
681
682 /*--------------------------------------------------------------------------*/
683
684 static int __devinit tmiofb_probe(struct platform_device *dev)
685 {
686         struct mfd_cell *cell = dev->dev.platform_data;
687         struct tmio_fb_data *data = cell->driver_data;
688         struct resource *ccr = platform_get_resource(dev, IORESOURCE_MEM, 1);
689         struct resource *lcr = platform_get_resource(dev, IORESOURCE_MEM, 0);
690         struct resource *vram = platform_get_resource(dev, IORESOURCE_MEM, 2);
691         int irq = platform_get_irq(dev, 0);
692         struct fb_info *info;
693         struct tmiofb_par *par;
694         int retval;
695
696         /*
697          * This is the only way ATM to disable the fb
698          */
699         if (data == NULL) {
700                 dev_err(&dev->dev, "NULL platform data!\n");
701                 return -EINVAL;
702         }
703
704         info = framebuffer_alloc(sizeof(struct tmiofb_par), &dev->dev);
705
706         if (!info)
707                 return -ENOMEM;
708
709         par = info->par;
710
711 #ifdef CONFIG_FB_TMIO_ACCELL
712         init_waitqueue_head(&par->wait_acc);
713
714         par->use_polling = true;
715
716         info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA
717                         | FBINFO_HWACCEL_FILLRECT;
718 #else
719         info->flags = FBINFO_DEFAULT;
720 #endif
721
722         info->fbops = &tmiofb_ops;
723
724         strcpy(info->fix.id, "tmio-fb");
725         info->fix.smem_start = vram->start;
726         info->fix.smem_len = resource_size(vram);
727         info->fix.type = FB_TYPE_PACKED_PIXELS;
728         info->fix.visual = FB_VISUAL_TRUECOLOR;
729         info->fix.mmio_start = lcr->start;
730         info->fix.mmio_len = resource_size(lcr);
731         info->fix.accel = FB_ACCEL_NONE;
732         info->screen_size = info->fix.smem_len - (4 * TMIOFB_FIFO_SIZE);
733         info->pseudo_palette = par->pseudo_palette;
734
735         par->ccr = ioremap(ccr->start, resource_size(ccr));
736         if (!par->ccr) {
737                 retval = -ENOMEM;
738                 goto err_ioremap_ccr;
739         }
740
741         par->lcr = ioremap(info->fix.mmio_start, info->fix.mmio_len);
742         if (!par->lcr) {
743                 retval = -ENOMEM;
744                 goto err_ioremap_lcr;
745         }
746
747         info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
748         if (!info->screen_base) {
749                 retval = -ENOMEM;
750                 goto err_ioremap_vram;
751         }
752
753         retval = request_irq(irq, &tmiofb_irq, IRQF_DISABLED,
754                                         dev->dev.bus_id, info);
755
756         if (retval)
757                 goto err_request_irq;
758
759         platform_set_drvdata(dev, info);
760
761         retval = fb_find_mode(&info->var, info, mode_option,
762                         data->modes, data->num_modes,
763                         data->modes, 16);
764         if (!retval) {
765                 retval = -EINVAL;
766                 goto err_find_mode;
767         }
768
769         if (cell->enable) {
770                 retval = cell->enable(dev);
771                 if (retval)
772                         goto err_enable;
773         }
774
775         retval = tmiofb_hw_init(dev);
776         if (retval)
777                 goto err_hw_init;
778
779         fb_videomode_to_modelist(data->modes, data->num_modes,
780                                  &info->modelist);
781
782         retval = register_framebuffer(info);
783         if (retval < 0)
784                 goto err_register_framebuffer;
785
786         printk(KERN_INFO "fb%d: %s frame buffer device\n",
787                                 info->node, info->fix.id);
788
789         return 0;
790
791 err_register_framebuffer:
792 /*err_set_par:*/
793         tmiofb_hw_stop(dev);
794 err_hw_init:
795         if (cell->disable)
796                 cell->disable(dev);
797 err_enable:
798 err_find_mode:
799         platform_set_drvdata(dev, NULL);
800         free_irq(irq, info);
801 err_request_irq:
802         iounmap(info->screen_base);
803 err_ioremap_vram:
804         iounmap(par->lcr);
805 err_ioremap_lcr:
806         iounmap(par->ccr);
807 err_ioremap_ccr:
808         framebuffer_release(info);
809         return retval;
810 }
811
812 static int __devexit tmiofb_remove(struct platform_device *dev)
813 {
814         struct mfd_cell *cell = dev->dev.platform_data;
815         struct fb_info *info = platform_get_drvdata(dev);
816         int irq = platform_get_irq(dev, 0);
817         struct tmiofb_par *par;
818
819         if (info) {
820                 par = info->par;
821                 unregister_framebuffer(info);
822
823                 tmiofb_hw_stop(dev);
824
825                 if (cell->disable)
826                         cell->disable(dev);
827
828                 platform_set_drvdata(dev, NULL);
829
830                 free_irq(irq, info);
831
832                 iounmap(info->screen_base);
833                 iounmap(par->lcr);
834                 iounmap(par->ccr);
835
836                 framebuffer_release(info);
837         }
838
839         return 0;
840 }
841
842 #ifdef DEBUG
843 static void tmiofb_dump_regs(struct platform_device *dev)
844 {
845         struct fb_info *info = platform_get_drvdata(dev);
846         struct tmiofb_par *par = info->par;
847
848         printk(KERN_DEBUG "lhccr:\n");
849 #define CCR_PR(n)       printk(KERN_DEBUG "\t" #n " = \t%04x\n",\
850                 tmio_ioread16(par->ccr + CCR_ ## n));
851         CCR_PR(CMD);
852         CCR_PR(REVID);
853         CCR_PR(BASEL);
854         CCR_PR(BASEH);
855         CCR_PR(UGCC);
856         CCR_PR(GCC);
857         CCR_PR(USC);
858         CCR_PR(VRAMRTC);
859         CCR_PR(VRAMSAC);
860         CCR_PR(VRAMBC);
861 #undef CCR_PR
862
863         printk(KERN_DEBUG "lcr: \n");
864 #define LCR_PR(n)       printk(KERN_DEBUG "\t" #n " = \t%04x\n",\
865                 tmio_ioread16(par->lcr + LCR_ ## n));
866         LCR_PR(UIS);
867         LCR_PR(VHPN);
868         LCR_PR(CFSAL);
869         LCR_PR(CFSAH);
870         LCR_PR(CFS);
871         LCR_PR(CFWS);
872         LCR_PR(BBIE);
873         LCR_PR(BBISC);
874         LCR_PR(CCS);
875         LCR_PR(BBES);
876         LCR_PR(CMDL);
877         LCR_PR(CMDH);
878         LCR_PR(CFC);
879         LCR_PR(CCIFC);
880         LCR_PR(HWT);
881         LCR_PR(LCDCCRC);
882         LCR_PR(LCDCC);
883         LCR_PR(LCDCOPC);
884         LCR_PR(LCDIS);
885         LCR_PR(LCDIM);
886         LCR_PR(LCDIE);
887         LCR_PR(GDSAL);
888         LCR_PR(GDSAH);
889         LCR_PR(VHPCL);
890         LCR_PR(VHPCH);
891         LCR_PR(GM);
892         LCR_PR(HT);
893         LCR_PR(HDS);
894         LCR_PR(HSS);
895         LCR_PR(HSE);
896         LCR_PR(HNP);
897         LCR_PR(VT);
898         LCR_PR(VDS);
899         LCR_PR(VSS);
900         LCR_PR(VSE);
901         LCR_PR(CDLN);
902         LCR_PR(ILN);
903         LCR_PR(SP);
904         LCR_PR(MISC);
905         LCR_PR(VIHSS);
906         LCR_PR(VIVS);
907         LCR_PR(VIVE);
908         LCR_PR(VIVSS);
909         LCR_PR(VCCIS);
910         LCR_PR(VIDWSAL);
911         LCR_PR(VIDWSAH);
912         LCR_PR(VIDRSAL);
913         LCR_PR(VIDRSAH);
914         LCR_PR(VIPDDST);
915         LCR_PR(VIPDDET);
916         LCR_PR(VIE);
917         LCR_PR(VCS);
918         LCR_PR(VPHWC);
919         LCR_PR(VPHS);
920         LCR_PR(VPVWC);
921         LCR_PR(VPVS);
922         LCR_PR(PLHPIX);
923         LCR_PR(XS);
924         LCR_PR(XCKHW);
925         LCR_PR(STHS);
926         LCR_PR(VT2);
927         LCR_PR(YCKSW);
928         LCR_PR(YSTS);
929         LCR_PR(PPOLS);
930         LCR_PR(PRECW);
931         LCR_PR(VCLKHW);
932         LCR_PR(OC);
933 #undef LCR_PR
934 }
935 #endif
936
937 #ifdef CONFIG_PM
938 static int tmiofb_suspend(struct platform_device *dev, pm_message_t state)
939 {
940         struct fb_info *info = platform_get_drvdata(dev);
941 #ifdef CONFIG_FB_TMIO_ACCELL
942         struct tmiofb_par *par = info->par;
943 #endif
944         struct mfd_cell *cell = dev->dev.platform_data;
945         int retval = 0;
946
947         acquire_console_sem();
948
949         fb_set_suspend(info, 1);
950
951         if (info->fbops->fb_sync)
952                 info->fbops->fb_sync(info);
953
954
955 #ifdef CONFIG_FB_TMIO_ACCELL
956         /*
957          * The fb should be usable even if interrupts are disabled (and they are
958          * during suspend/resume). Switch temporary to forced polling.
959          */
960         printk(KERN_INFO "tmiofb: switching to polling\n");
961         par->use_polling = true;
962 #endif
963         tmiofb_hw_stop(dev);
964
965         if (cell->suspend)
966                 retval = cell->suspend(dev);
967
968         release_console_sem();
969
970         return retval;
971 }
972
973 static int tmiofb_resume(struct platform_device *dev)
974 {
975         struct fb_info *info = platform_get_drvdata(dev);
976         struct mfd_cell *cell = dev->dev.platform_data;
977         int retval;
978
979         acquire_console_sem();
980
981         if (cell->resume) {
982                 retval = cell->resume(dev);
983                 if (retval)
984                         goto out;
985         }
986
987         tmiofb_irq(-1, info);
988
989         tmiofb_hw_init(dev);
990
991         tmiofb_hw_mode(dev);
992
993         fb_set_suspend(info, 0);
994 out:
995         release_console_sem();
996         return retval;
997 }
998 #else
999 #define tmiofb_suspend  NULL
1000 #define tmiofb_resume   NULL
1001 #endif
1002
1003 static struct platform_driver tmiofb_driver = {
1004         .driver.name    = "tmio-fb",
1005         .driver.owner   = THIS_MODULE,
1006         .probe          = tmiofb_probe,
1007         .remove         = __devexit_p(tmiofb_remove),
1008         .suspend        = tmiofb_suspend,
1009         .resume         = tmiofb_resume,
1010 };
1011
1012 /*--------------------------------------------------------------------------*/
1013
1014 #ifndef MODULE
1015 static void __init tmiofb_setup(char *options)
1016 {
1017         char *this_opt;
1018
1019         if (!options || !*options)
1020                 return;
1021
1022         while ((this_opt = strsep(&options, ",")) != NULL) {
1023                 if (!*this_opt)
1024                         continue;
1025                 /*
1026                  * FIXME
1027                  */
1028         }
1029 }
1030 #endif
1031
1032 static int __init tmiofb_init(void)
1033 {
1034 #ifndef MODULE
1035         char *option = NULL;
1036
1037         if (fb_get_options("tmiofb", &option))
1038                 return -ENODEV;
1039         tmiofb_setup(option);
1040 #endif
1041         return platform_driver_register(&tmiofb_driver);
1042 }
1043
1044 static void __exit tmiofb_cleanup(void)
1045 {
1046         platform_driver_unregister(&tmiofb_driver);
1047 }
1048
1049 module_init(tmiofb_init);
1050 module_exit(tmiofb_cleanup);
1051
1052 MODULE_DESCRIPTION("TMIO framebuffer driver");
1053 MODULE_AUTHOR("Chris Humbert, Dirk Opfer, Dmitry Baryshkov");
1054 MODULE_LICENSE("GPL");