mm: thp: set the accessed flag for old pages on access fault
[pandora-kernel.git] / 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 console_lock() */
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 tmio_fb_data *data = dev->dev.platform_data;
254         struct fb_info *info = platform_get_drvdata(dev);
255         struct tmiofb_par *par = info->par;
256
257         tmio_iowrite16(0, par->ccr + CCR_UGCC);
258         tmio_iowrite16(0, par->lcr + LCR_GM);
259         data->lcd_set_power(dev, 0);
260         tmio_iowrite16(0x0010, par->lcr + LCR_LCDCCRC);
261
262         return 0;
263 }
264
265 /*
266  * Initializes the LCD host controller.
267  */
268 static int tmiofb_hw_init(struct platform_device *dev)
269 {
270         const struct mfd_cell *cell = mfd_get_cell(dev);
271         struct fb_info *info = platform_get_drvdata(dev);
272         struct tmiofb_par *par = info->par;
273         const struct resource *nlcr = &cell->resources[0];
274         const struct resource *vram = &cell->resources[2];
275         unsigned long base;
276
277         if (nlcr == NULL || vram == NULL)
278                 return -EINVAL;
279
280         base = nlcr->start;
281
282         tmio_iowrite16(0x003a, par->ccr + CCR_UGCC);
283         tmio_iowrite16(0x003a, par->ccr + CCR_GCC);
284         tmio_iowrite16(0x3f00, par->ccr + CCR_USC);
285
286         msleep(2); /* wait for device to settle */
287
288         tmio_iowrite16(0x0000, par->ccr + CCR_USC);
289         tmio_iowrite16(base >> 16, par->ccr + CCR_BASEH);
290         tmio_iowrite16(base, par->ccr + CCR_BASEL);
291         tmio_iowrite16(0x0002, par->ccr + CCR_CMD); /* base address enable */
292         tmio_iowrite16(0x40a8, par->ccr + CCR_VRAMRTC); /* VRAMRC, VRAMTC */
293         tmio_iowrite16(0x0018, par->ccr + CCR_VRAMSAC); /* VRAMSTS, VRAMAC */
294         tmio_iowrite16(0x0002, par->ccr + CCR_VRAMBC);
295         msleep(2); /* wait for device to settle */
296         tmio_iowrite16(0x000b, par->ccr + CCR_VRAMBC);
297
298         base = vram->start + info->screen_size;
299         tmio_iowrite16(base >> 16, par->lcr + LCR_CFSAH);
300         tmio_iowrite16(base, par->lcr + LCR_CFSAL);
301         tmio_iowrite16(TMIOFB_FIFO_SIZE - 1, par->lcr + LCR_CFS);
302         tmio_iowrite16(1, par->lcr + LCR_CFC);
303         tmio_iowrite16(1, par->lcr + LCR_BBIE);
304         tmio_iowrite16(0, par->lcr + LCR_CFWS);
305
306         return 0;
307 }
308
309 /*
310  * Sets the LCD controller's output resolution and pixel clock
311  */
312 static void tmiofb_hw_mode(struct platform_device *dev)
313 {
314         struct tmio_fb_data *data = dev->dev.platform_data;
315         struct fb_info *info = platform_get_drvdata(dev);
316         struct fb_videomode *mode = info->mode;
317         struct tmiofb_par *par = info->par;
318         unsigned int i;
319
320         tmio_iowrite16(0, par->lcr + LCR_GM);
321         data->lcd_set_power(dev, 0);
322         tmio_iowrite16(0x0010, par->lcr + LCR_LCDCCRC);
323         data->lcd_mode(dev, mode);
324         data->lcd_set_power(dev, 1);
325
326         tmio_iowrite16(info->fix.line_length, par->lcr + LCR_VHPN);
327         tmio_iowrite16(0, par->lcr + LCR_GDSAH);
328         tmio_iowrite16(0, par->lcr + LCR_GDSAL);
329         tmio_iowrite16(info->fix.line_length >> 16, par->lcr + LCR_VHPCH);
330         tmio_iowrite16(info->fix.line_length, par->lcr + LCR_VHPCL);
331         tmio_iowrite16(i = 0, par->lcr + LCR_HSS);
332         tmio_iowrite16(i += mode->hsync_len, par->lcr + LCR_HSE);
333         tmio_iowrite16(i += mode->left_margin, par->lcr + LCR_HDS);
334         tmio_iowrite16(i += mode->xres + mode->right_margin, par->lcr + LCR_HT);
335         tmio_iowrite16(mode->xres, par->lcr + LCR_HNP);
336         tmio_iowrite16(i = 0, par->lcr + LCR_VSS);
337         tmio_iowrite16(i += mode->vsync_len, par->lcr + LCR_VSE);
338         tmio_iowrite16(i += mode->upper_margin, par->lcr + LCR_VDS);
339         tmio_iowrite16(i += mode->yres, par->lcr + LCR_ILN);
340         tmio_iowrite16(i += mode->lower_margin, par->lcr + LCR_VT);
341         tmio_iowrite16(3, par->lcr + LCR_MISC); /* RGB565 mode */
342         tmio_iowrite16(1, par->lcr + LCR_GM); /* VRAM enable */
343         tmio_iowrite16(0x4007, par->lcr + LCR_LCDCC);
344         tmio_iowrite16(3, par->lcr + LCR_SP);  /* sync polarity */
345
346         tmio_iowrite16(0x0010, par->lcr + LCR_LCDCCRC);
347         msleep(5); /* wait for device to settle */
348         tmio_iowrite16(0x0014, par->lcr + LCR_LCDCCRC); /* STOP_CKP */
349         msleep(5); /* wait for device to settle */
350         tmio_iowrite16(0x0015, par->lcr + LCR_LCDCCRC); /* STOP_CKP|SOFT_RESET*/
351         tmio_iowrite16(0xfffa, par->lcr + LCR_VCS);
352 }
353
354 /*--------------------------------------------------------------------------*/
355
356 #ifdef CONFIG_FB_TMIO_ACCELL
357 static int __must_check
358 tmiofb_acc_wait(struct fb_info *info, unsigned int ccs)
359 {
360         struct tmiofb_par *par = info->par;
361         /*
362          * This code can be called with interrupts disabled.
363          * So instead of relaying on irq to trigger the event,
364          * poll the state till the necessary command is executed.
365          */
366         if (irqs_disabled() || par->use_polling) {
367                 int i = 0;
368                 while (tmio_ioread16(par->lcr + LCR_CCS) > ccs) {
369                         udelay(1);
370                         i++;
371                         if (i > 10000) {
372                                 pr_err("tmiofb: timeout waiting for %d\n",
373                                                 ccs);
374                                 return -ETIMEDOUT;
375                         }
376                         tmiofb_irq(-1, info);
377                 }
378         } else {
379                 if (!wait_event_interruptible_timeout(par->wait_acc,
380                                 tmio_ioread16(par->lcr + LCR_CCS) <= ccs,
381                                 1000)) {
382                         pr_err("tmiofb: timeout waiting for %d\n", ccs);
383                         return -ETIMEDOUT;
384                 }
385         }
386
387         return 0;
388 }
389
390 /*
391  * Writes an accelerator command to the accelerator's FIFO.
392  */
393 static int
394 tmiofb_acc_write(struct fb_info *info, const u32 *cmd, unsigned int count)
395 {
396         struct tmiofb_par *par = info->par;
397         int ret;
398
399         ret = tmiofb_acc_wait(info, TMIOFB_FIFO_SIZE - count);
400         if (ret)
401                 return ret;
402
403         for (; count; count--, cmd++) {
404                 tmio_iowrite16(*cmd >> 16, par->lcr + LCR_CMDH);
405                 tmio_iowrite16(*cmd, par->lcr + LCR_CMDL);
406         }
407
408         return ret;
409 }
410
411 /*
412  * Wait for the accelerator to finish its operations before writing
413  * to the framebuffer for consistent display output.
414  */
415 static int tmiofb_sync(struct fb_info *fbi)
416 {
417         struct tmiofb_par *par = fbi->par;
418
419         int ret;
420         int i = 0;
421
422         ret = tmiofb_acc_wait(fbi, 0);
423
424         while (tmio_ioread16(par->lcr + LCR_BBES) & 2) { /* blit active */
425                 udelay(1);
426                 i++ ;
427                 if (i > 10000) {
428                         printk(KERN_ERR "timeout waiting for blit to end!\n");
429                         return -ETIMEDOUT;
430                 }
431         }
432
433         return ret;
434 }
435
436 static void
437 tmiofb_fillrect(struct fb_info *fbi, const struct fb_fillrect *rect)
438 {
439         const u32 cmd[] = {
440                 TMIOFB_ACC_DSADR((rect->dy * fbi->mode->xres + rect->dx) * 2),
441                 TMIOFB_ACC_DHPIX(rect->width - 1),
442                 TMIOFB_ACC_DVPIX(rect->height - 1),
443                 TMIOFB_ACC_FILL(rect->color),
444                 TMIOFB_ACC_FLGO,
445         };
446
447         if (fbi->state != FBINFO_STATE_RUNNING ||
448             fbi->flags & FBINFO_HWACCEL_DISABLED) {
449                 cfb_fillrect(fbi, rect);
450                 return;
451         }
452
453         tmiofb_acc_write(fbi, cmd, ARRAY_SIZE(cmd));
454 }
455
456 static void
457 tmiofb_copyarea(struct fb_info *fbi, const struct fb_copyarea *area)
458 {
459         const u32 cmd[] = {
460                 TMIOFB_ACC_DSADR((area->dy * fbi->mode->xres + area->dx) * 2),
461                 TMIOFB_ACC_DHPIX(area->width - 1),
462                 TMIOFB_ACC_DVPIX(area->height - 1),
463                 TMIOFB_ACC_SSADR((area->sy * fbi->mode->xres + area->sx) * 2),
464                 TMIOFB_ACC_SCGO,
465         };
466
467         if (fbi->state != FBINFO_STATE_RUNNING ||
468             fbi->flags & FBINFO_HWACCEL_DISABLED) {
469                 cfb_copyarea(fbi, area);
470                 return;
471         }
472
473         tmiofb_acc_write(fbi, cmd, ARRAY_SIZE(cmd));
474 }
475 #endif
476
477 static void tmiofb_clearscreen(struct fb_info *info)
478 {
479         const struct fb_fillrect rect = {
480                 .dx     = 0,
481                 .dy     = 0,
482                 .width  = info->mode->xres,
483                 .height = info->mode->yres,
484                 .color  = 0,
485                 .rop    = ROP_COPY,
486         };
487
488         info->fbops->fb_fillrect(info, &rect);
489 }
490
491 static int tmiofb_vblank(struct fb_info *fbi, struct fb_vblank *vblank)
492 {
493         struct tmiofb_par *par = fbi->par;
494         struct fb_videomode *mode = fbi->mode;
495         unsigned int vcount = tmio_ioread16(par->lcr + LCR_CDLN);
496         unsigned int vds = mode->vsync_len + mode->upper_margin;
497
498         vblank->vcount = vcount;
499         vblank->flags = FB_VBLANK_HAVE_VBLANK | FB_VBLANK_HAVE_VCOUNT
500                                                 | FB_VBLANK_HAVE_VSYNC;
501
502         if (vcount < mode->vsync_len)
503                 vblank->flags |= FB_VBLANK_VSYNCING;
504
505         if (vcount < vds || vcount > vds + mode->yres)
506                 vblank->flags |= FB_VBLANK_VBLANKING;
507
508         return 0;
509 }
510
511
512 static int tmiofb_ioctl(struct fb_info *fbi,
513                 unsigned int cmd, unsigned long arg)
514 {
515         switch (cmd) {
516         case FBIOGET_VBLANK: {
517                 struct fb_vblank vblank = {0};
518                 void __user *argp = (void __user *) arg;
519
520                 tmiofb_vblank(fbi, &vblank);
521                 if (copy_to_user(argp, &vblank, sizeof vblank))
522                         return -EFAULT;
523                 return 0;
524         }
525
526 #ifdef CONFIG_FB_TMIO_ACCELL
527         case FBIO_TMIO_ACC_SYNC:
528                 tmiofb_sync(fbi);
529                 return 0;
530
531         case FBIO_TMIO_ACC_WRITE: {
532                 u32 __user *argp = (void __user *) arg;
533                 u32 len;
534                 u32 acc[16];
535
536                 if (get_user(len, argp))
537                         return -EFAULT;
538                 if (len > ARRAY_SIZE(acc))
539                         return -EINVAL;
540                 if (copy_from_user(acc, argp + 1, sizeof(u32) * len))
541                         return -EFAULT;
542
543                 return tmiofb_acc_write(fbi, acc, len);
544         }
545 #endif
546         }
547
548         return -ENOTTY;
549 }
550
551 /*--------------------------------------------------------------------------*/
552
553 /* Select the smallest mode that allows the desired resolution to be
554  * displayed.  If desired, the x and y parameters can be rounded up to
555  * match the selected mode.
556  */
557 static struct fb_videomode *
558 tmiofb_find_mode(struct fb_info *info, struct fb_var_screeninfo *var)
559 {
560         struct tmio_fb_data *data = info->device->platform_data;
561         struct fb_videomode *best = NULL;
562         int i;
563
564         for (i = 0; i < data->num_modes; i++) {
565                 struct fb_videomode *mode = data->modes + i;
566
567                 if (mode->xres >= var->xres && mode->yres >= var->yres
568                                 && (!best || (mode->xres < best->xres
569                                            && mode->yres < best->yres)))
570                         best = mode;
571         }
572
573         return best;
574 }
575
576 static int tmiofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
577 {
578
579         struct fb_videomode *mode;
580         struct tmio_fb_data *data = info->device->platform_data;
581
582         mode = tmiofb_find_mode(info, var);
583         if (!mode || var->bits_per_pixel > 16)
584                 return -EINVAL;
585
586         fb_videomode_to_var(var, mode);
587
588         var->xres_virtual = mode->xres;
589         var->yres_virtual = info->screen_size / (mode->xres * 2);
590
591         if (var->yres_virtual < var->yres)
592                 return -EINVAL;
593
594         var->xoffset = 0;
595         var->yoffset = 0;
596         var->bits_per_pixel = 16;
597         var->grayscale = 0;
598         var->red.offset = 11;
599         var->red.length = 5;
600         var->green.offset = 5;
601         var->green.length = 6;
602         var->blue.offset = 0;
603         var->blue.length = 5;
604         var->transp.offset = 0;
605         var->transp.length = 0;
606         var->nonstd = 0;
607         var->height = data->height; /* mm */
608         var->width = data->width; /* mm */
609         var->rotate = 0;
610         return 0;
611 }
612
613 static int tmiofb_set_par(struct fb_info *info)
614 {
615         struct fb_var_screeninfo *var = &info->var;
616         struct fb_videomode *mode;
617
618         mode = tmiofb_find_mode(info, var);
619         if (!mode)
620                 return -EINVAL;
621
622         info->mode = mode;
623         info->fix.line_length = info->mode->xres *
624                         var->bits_per_pixel / 8;
625
626         tmiofb_hw_mode(to_platform_device(info->device));
627         tmiofb_clearscreen(info);
628         return 0;
629 }
630
631 static int tmiofb_setcolreg(unsigned regno, unsigned red, unsigned green,
632                            unsigned blue, unsigned transp,
633                            struct fb_info *info)
634 {
635         struct tmiofb_par *par = info->par;
636
637         if (regno < ARRAY_SIZE(par->pseudo_palette)) {
638                 par->pseudo_palette[regno] =
639                         ((red & 0xf800)) |
640                         ((green & 0xfc00) >>  5) |
641                         ((blue & 0xf800) >> 11);
642                 return 0;
643         }
644
645         return -EINVAL;
646 }
647
648 static int tmiofb_blank(int blank, struct fb_info *info)
649 {
650         /*
651          * everything is done in lcd/bl drivers.
652          * this is purely to make sysfs happy and work.
653          */
654         return 0;
655 }
656
657 static struct fb_ops tmiofb_ops = {
658         .owner          = THIS_MODULE,
659
660         .fb_ioctl       = tmiofb_ioctl,
661         .fb_check_var   = tmiofb_check_var,
662         .fb_set_par     = tmiofb_set_par,
663         .fb_setcolreg   = tmiofb_setcolreg,
664         .fb_blank       = tmiofb_blank,
665         .fb_imageblit   = cfb_imageblit,
666 #ifdef CONFIG_FB_TMIO_ACCELL
667         .fb_sync        = tmiofb_sync,
668         .fb_fillrect    = tmiofb_fillrect,
669         .fb_copyarea    = tmiofb_copyarea,
670 #else
671         .fb_fillrect    = cfb_fillrect,
672         .fb_copyarea    = cfb_copyarea,
673 #endif
674 };
675
676 /*--------------------------------------------------------------------------*/
677
678 static int __devinit tmiofb_probe(struct platform_device *dev)
679 {
680         const struct mfd_cell *cell = mfd_get_cell(dev);
681         struct tmio_fb_data *data = dev->dev.platform_data;
682         struct resource *ccr = platform_get_resource(dev, IORESOURCE_MEM, 1);
683         struct resource *lcr = platform_get_resource(dev, IORESOURCE_MEM, 0);
684         struct resource *vram = platform_get_resource(dev, IORESOURCE_MEM, 2);
685         int irq = platform_get_irq(dev, 0);
686         struct fb_info *info;
687         struct tmiofb_par *par;
688         int retval;
689
690         /*
691          * This is the only way ATM to disable the fb
692          */
693         if (data == NULL) {
694                 dev_err(&dev->dev, "NULL platform data!\n");
695                 return -EINVAL;
696         }
697
698         info = framebuffer_alloc(sizeof(struct tmiofb_par), &dev->dev);
699
700         if (!info)
701                 return -ENOMEM;
702
703         par = info->par;
704
705 #ifdef CONFIG_FB_TMIO_ACCELL
706         init_waitqueue_head(&par->wait_acc);
707
708         par->use_polling = true;
709
710         info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA
711                         | FBINFO_HWACCEL_FILLRECT;
712 #else
713         info->flags = FBINFO_DEFAULT;
714 #endif
715
716         info->fbops = &tmiofb_ops;
717
718         strcpy(info->fix.id, "tmio-fb");
719         info->fix.smem_start = vram->start;
720         info->fix.smem_len = resource_size(vram);
721         info->fix.type = FB_TYPE_PACKED_PIXELS;
722         info->fix.visual = FB_VISUAL_TRUECOLOR;
723         info->fix.mmio_start = lcr->start;
724         info->fix.mmio_len = resource_size(lcr);
725         info->fix.accel = FB_ACCEL_NONE;
726         info->screen_size = info->fix.smem_len - (4 * TMIOFB_FIFO_SIZE);
727         info->pseudo_palette = par->pseudo_palette;
728
729         par->ccr = ioremap(ccr->start, resource_size(ccr));
730         if (!par->ccr) {
731                 retval = -ENOMEM;
732                 goto err_ioremap_ccr;
733         }
734
735         par->lcr = ioremap(info->fix.mmio_start, info->fix.mmio_len);
736         if (!par->lcr) {
737                 retval = -ENOMEM;
738                 goto err_ioremap_lcr;
739         }
740
741         info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
742         if (!info->screen_base) {
743                 retval = -ENOMEM;
744                 goto err_ioremap_vram;
745         }
746
747         retval = request_irq(irq, &tmiofb_irq, 0,
748                                         dev_name(&dev->dev), info);
749
750         if (retval)
751                 goto err_request_irq;
752
753         platform_set_drvdata(dev, info);
754
755         retval = fb_find_mode(&info->var, info, mode_option,
756                         data->modes, data->num_modes,
757                         data->modes, 16);
758         if (!retval) {
759                 retval = -EINVAL;
760                 goto err_find_mode;
761         }
762
763         if (cell->enable) {
764                 retval = cell->enable(dev);
765                 if (retval)
766                         goto err_enable;
767         }
768
769         retval = tmiofb_hw_init(dev);
770         if (retval)
771                 goto err_hw_init;
772
773         fb_videomode_to_modelist(data->modes, data->num_modes,
774                                  &info->modelist);
775
776         retval = register_framebuffer(info);
777         if (retval < 0)
778                 goto err_register_framebuffer;
779
780         printk(KERN_INFO "fb%d: %s frame buffer device\n",
781                                 info->node, info->fix.id);
782
783         return 0;
784
785 err_register_framebuffer:
786 /*err_set_par:*/
787         tmiofb_hw_stop(dev);
788 err_hw_init:
789         if (cell->disable)
790                 cell->disable(dev);
791 err_enable:
792 err_find_mode:
793         platform_set_drvdata(dev, NULL);
794         free_irq(irq, info);
795 err_request_irq:
796         iounmap(info->screen_base);
797 err_ioremap_vram:
798         iounmap(par->lcr);
799 err_ioremap_lcr:
800         iounmap(par->ccr);
801 err_ioremap_ccr:
802         framebuffer_release(info);
803         return retval;
804 }
805
806 static int __devexit tmiofb_remove(struct platform_device *dev)
807 {
808         const struct mfd_cell *cell = mfd_get_cell(dev);
809         struct fb_info *info = platform_get_drvdata(dev);
810         int irq = platform_get_irq(dev, 0);
811         struct tmiofb_par *par;
812
813         if (info) {
814                 par = info->par;
815                 unregister_framebuffer(info);
816
817                 tmiofb_hw_stop(dev);
818
819                 if (cell->disable)
820                         cell->disable(dev);
821
822                 platform_set_drvdata(dev, NULL);
823
824                 free_irq(irq, info);
825
826                 iounmap(info->screen_base);
827                 iounmap(par->lcr);
828                 iounmap(par->ccr);
829
830                 framebuffer_release(info);
831         }
832
833         return 0;
834 }
835
836 #ifdef DEBUG
837 static void tmiofb_dump_regs(struct platform_device *dev)
838 {
839         struct fb_info *info = platform_get_drvdata(dev);
840         struct tmiofb_par *par = info->par;
841
842         printk(KERN_DEBUG "lhccr:\n");
843 #define CCR_PR(n)       printk(KERN_DEBUG "\t" #n " = \t%04x\n",\
844                 tmio_ioread16(par->ccr + CCR_ ## n));
845         CCR_PR(CMD);
846         CCR_PR(REVID);
847         CCR_PR(BASEL);
848         CCR_PR(BASEH);
849         CCR_PR(UGCC);
850         CCR_PR(GCC);
851         CCR_PR(USC);
852         CCR_PR(VRAMRTC);
853         CCR_PR(VRAMSAC);
854         CCR_PR(VRAMBC);
855 #undef CCR_PR
856
857         printk(KERN_DEBUG "lcr: \n");
858 #define LCR_PR(n)       printk(KERN_DEBUG "\t" #n " = \t%04x\n",\
859                 tmio_ioread16(par->lcr + LCR_ ## n));
860         LCR_PR(UIS);
861         LCR_PR(VHPN);
862         LCR_PR(CFSAL);
863         LCR_PR(CFSAH);
864         LCR_PR(CFS);
865         LCR_PR(CFWS);
866         LCR_PR(BBIE);
867         LCR_PR(BBISC);
868         LCR_PR(CCS);
869         LCR_PR(BBES);
870         LCR_PR(CMDL);
871         LCR_PR(CMDH);
872         LCR_PR(CFC);
873         LCR_PR(CCIFC);
874         LCR_PR(HWT);
875         LCR_PR(LCDCCRC);
876         LCR_PR(LCDCC);
877         LCR_PR(LCDCOPC);
878         LCR_PR(LCDIS);
879         LCR_PR(LCDIM);
880         LCR_PR(LCDIE);
881         LCR_PR(GDSAL);
882         LCR_PR(GDSAH);
883         LCR_PR(VHPCL);
884         LCR_PR(VHPCH);
885         LCR_PR(GM);
886         LCR_PR(HT);
887         LCR_PR(HDS);
888         LCR_PR(HSS);
889         LCR_PR(HSE);
890         LCR_PR(HNP);
891         LCR_PR(VT);
892         LCR_PR(VDS);
893         LCR_PR(VSS);
894         LCR_PR(VSE);
895         LCR_PR(CDLN);
896         LCR_PR(ILN);
897         LCR_PR(SP);
898         LCR_PR(MISC);
899         LCR_PR(VIHSS);
900         LCR_PR(VIVS);
901         LCR_PR(VIVE);
902         LCR_PR(VIVSS);
903         LCR_PR(VCCIS);
904         LCR_PR(VIDWSAL);
905         LCR_PR(VIDWSAH);
906         LCR_PR(VIDRSAL);
907         LCR_PR(VIDRSAH);
908         LCR_PR(VIPDDST);
909         LCR_PR(VIPDDET);
910         LCR_PR(VIE);
911         LCR_PR(VCS);
912         LCR_PR(VPHWC);
913         LCR_PR(VPHS);
914         LCR_PR(VPVWC);
915         LCR_PR(VPVS);
916         LCR_PR(PLHPIX);
917         LCR_PR(XS);
918         LCR_PR(XCKHW);
919         LCR_PR(STHS);
920         LCR_PR(VT2);
921         LCR_PR(YCKSW);
922         LCR_PR(YSTS);
923         LCR_PR(PPOLS);
924         LCR_PR(PRECW);
925         LCR_PR(VCLKHW);
926         LCR_PR(OC);
927 #undef LCR_PR
928 }
929 #endif
930
931 #ifdef CONFIG_PM
932 static int tmiofb_suspend(struct platform_device *dev, pm_message_t state)
933 {
934         struct fb_info *info = platform_get_drvdata(dev);
935 #ifdef CONFIG_FB_TMIO_ACCELL
936         struct tmiofb_par *par = info->par;
937 #endif
938         const struct mfd_cell *cell = mfd_get_cell(dev);
939         int retval = 0;
940
941         console_lock();
942
943         fb_set_suspend(info, 1);
944
945         if (info->fbops->fb_sync)
946                 info->fbops->fb_sync(info);
947
948
949 #ifdef CONFIG_FB_TMIO_ACCELL
950         /*
951          * The fb should be usable even if interrupts are disabled (and they are
952          * during suspend/resume). Switch temporary to forced polling.
953          */
954         printk(KERN_INFO "tmiofb: switching to polling\n");
955         par->use_polling = true;
956 #endif
957         tmiofb_hw_stop(dev);
958
959         if (cell->suspend)
960                 retval = cell->suspend(dev);
961
962         console_unlock();
963
964         return retval;
965 }
966
967 static int tmiofb_resume(struct platform_device *dev)
968 {
969         struct fb_info *info = platform_get_drvdata(dev);
970         const struct mfd_cell *cell = mfd_get_cell(dev);
971         int retval = 0;
972
973         console_lock();
974
975         if (cell->resume) {
976                 retval = cell->resume(dev);
977                 if (retval)
978                         goto out;
979         }
980
981         tmiofb_irq(-1, info);
982
983         tmiofb_hw_init(dev);
984
985         tmiofb_hw_mode(dev);
986
987         fb_set_suspend(info, 0);
988 out:
989         console_unlock();
990         return retval;
991 }
992 #else
993 #define tmiofb_suspend  NULL
994 #define tmiofb_resume   NULL
995 #endif
996
997 static struct platform_driver tmiofb_driver = {
998         .driver.name    = "tmio-fb",
999         .driver.owner   = THIS_MODULE,
1000         .probe          = tmiofb_probe,
1001         .remove         = __devexit_p(tmiofb_remove),
1002         .suspend        = tmiofb_suspend,
1003         .resume         = tmiofb_resume,
1004 };
1005
1006 /*--------------------------------------------------------------------------*/
1007
1008 #ifndef MODULE
1009 static void __init tmiofb_setup(char *options)
1010 {
1011         char *this_opt;
1012
1013         if (!options || !*options)
1014                 return;
1015
1016         while ((this_opt = strsep(&options, ",")) != NULL) {
1017                 if (!*this_opt)
1018                         continue;
1019                 /*
1020                  * FIXME
1021                  */
1022         }
1023 }
1024 #endif
1025
1026 static int __init tmiofb_init(void)
1027 {
1028 #ifndef MODULE
1029         char *option = NULL;
1030
1031         if (fb_get_options("tmiofb", &option))
1032                 return -ENODEV;
1033         tmiofb_setup(option);
1034 #endif
1035         return platform_driver_register(&tmiofb_driver);
1036 }
1037
1038 static void __exit tmiofb_cleanup(void)
1039 {
1040         platform_driver_unregister(&tmiofb_driver);
1041 }
1042
1043 module_init(tmiofb_init);
1044 module_exit(tmiofb_cleanup);
1045
1046 MODULE_DESCRIPTION("TMIO framebuffer driver");
1047 MODULE_AUTHOR("Chris Humbert, Dirk Opfer, Dmitry Baryshkov");
1048 MODULE_LICENSE("GPL");