9710bf8caeaeb13db419928dffd3a0aa5c925fcb
[cascardo/linux.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 = mfd_get_data(dev);
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 = mfd_get_data(dev);
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 whith 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 =
561                         mfd_get_data(to_platform_device(info->device));
562         struct fb_videomode *best = NULL;
563         int i;
564
565         for (i = 0; i < data->num_modes; i++) {
566                 struct fb_videomode *mode = data->modes + i;
567
568                 if (mode->xres >= var->xres && mode->yres >= var->yres
569                                 && (!best || (mode->xres < best->xres
570                                            && mode->yres < best->yres)))
571                         best = mode;
572         }
573
574         return best;
575 }
576
577 static int tmiofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
578 {
579
580         struct fb_videomode *mode;
581         struct tmio_fb_data *data =
582                         mfd_get_data(to_platform_device(info->device));
583
584         mode = tmiofb_find_mode(info, var);
585         if (!mode || var->bits_per_pixel > 16)
586                 return -EINVAL;
587
588         fb_videomode_to_var(var, mode);
589
590         var->xres_virtual = mode->xres;
591         var->yres_virtual = info->screen_size / (mode->xres * 2);
592
593         if (var->yres_virtual < var->yres)
594                 return -EINVAL;
595
596         var->xoffset = 0;
597         var->yoffset = 0;
598         var->bits_per_pixel = 16;
599         var->grayscale = 0;
600         var->red.offset = 11;
601         var->red.length = 5;
602         var->green.offset = 5;
603         var->green.length = 6;
604         var->blue.offset = 0;
605         var->blue.length = 5;
606         var->transp.offset = 0;
607         var->transp.length = 0;
608         var->nonstd = 0;
609         var->height = data->height; /* mm */
610         var->width = data->width; /* mm */
611         var->rotate = 0;
612         return 0;
613 }
614
615 static int tmiofb_set_par(struct fb_info *info)
616 {
617         struct fb_var_screeninfo *var = &info->var;
618         struct fb_videomode *mode;
619
620         mode = tmiofb_find_mode(info, var);
621         if (!mode)
622                 return -EINVAL;
623
624         info->mode = mode;
625         info->fix.line_length = info->mode->xres *
626                         var->bits_per_pixel / 8;
627
628         tmiofb_hw_mode(to_platform_device(info->device));
629         tmiofb_clearscreen(info);
630         return 0;
631 }
632
633 static int tmiofb_setcolreg(unsigned regno, unsigned red, unsigned green,
634                            unsigned blue, unsigned transp,
635                            struct fb_info *info)
636 {
637         struct tmiofb_par *par = info->par;
638
639         if (regno < ARRAY_SIZE(par->pseudo_palette)) {
640                 par->pseudo_palette[regno] =
641                         ((red & 0xf800)) |
642                         ((green & 0xfc00) >>  5) |
643                         ((blue & 0xf800) >> 11);
644                 return 0;
645         }
646
647         return -EINVAL;
648 }
649
650 static int tmiofb_blank(int blank, struct fb_info *info)
651 {
652         /*
653          * everything is done in lcd/bl drivers.
654          * this is purely to make sysfs happy and work.
655          */
656         return 0;
657 }
658
659 static struct fb_ops tmiofb_ops = {
660         .owner          = THIS_MODULE,
661
662         .fb_ioctl       = tmiofb_ioctl,
663         .fb_check_var   = tmiofb_check_var,
664         .fb_set_par     = tmiofb_set_par,
665         .fb_setcolreg   = tmiofb_setcolreg,
666         .fb_blank       = tmiofb_blank,
667         .fb_imageblit   = cfb_imageblit,
668 #ifdef CONFIG_FB_TMIO_ACCELL
669         .fb_sync        = tmiofb_sync,
670         .fb_fillrect    = tmiofb_fillrect,
671         .fb_copyarea    = tmiofb_copyarea,
672 #else
673         .fb_fillrect    = cfb_fillrect,
674         .fb_copyarea    = cfb_copyarea,
675 #endif
676 };
677
678 /*--------------------------------------------------------------------------*/
679
680 static int __devinit tmiofb_probe(struct platform_device *dev)
681 {
682         const struct mfd_cell *cell = mfd_get_cell(dev);
683         struct tmio_fb_data *data = mfd_get_data(dev);
684         struct resource *ccr = platform_get_resource(dev, IORESOURCE_MEM, 1);
685         struct resource *lcr = platform_get_resource(dev, IORESOURCE_MEM, 0);
686         struct resource *vram = platform_get_resource(dev, IORESOURCE_MEM, 2);
687         int irq = platform_get_irq(dev, 0);
688         struct fb_info *info;
689         struct tmiofb_par *par;
690         int retval;
691
692         /*
693          * This is the only way ATM to disable the fb
694          */
695         if (data == NULL) {
696                 dev_err(&dev->dev, "NULL platform data!\n");
697                 return -EINVAL;
698         }
699
700         info = framebuffer_alloc(sizeof(struct tmiofb_par), &dev->dev);
701
702         if (!info)
703                 return -ENOMEM;
704
705         par = info->par;
706
707 #ifdef CONFIG_FB_TMIO_ACCELL
708         init_waitqueue_head(&par->wait_acc);
709
710         par->use_polling = true;
711
712         info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA
713                         | FBINFO_HWACCEL_FILLRECT;
714 #else
715         info->flags = FBINFO_DEFAULT;
716 #endif
717
718         info->fbops = &tmiofb_ops;
719
720         strcpy(info->fix.id, "tmio-fb");
721         info->fix.smem_start = vram->start;
722         info->fix.smem_len = resource_size(vram);
723         info->fix.type = FB_TYPE_PACKED_PIXELS;
724         info->fix.visual = FB_VISUAL_TRUECOLOR;
725         info->fix.mmio_start = lcr->start;
726         info->fix.mmio_len = resource_size(lcr);
727         info->fix.accel = FB_ACCEL_NONE;
728         info->screen_size = info->fix.smem_len - (4 * TMIOFB_FIFO_SIZE);
729         info->pseudo_palette = par->pseudo_palette;
730
731         par->ccr = ioremap(ccr->start, resource_size(ccr));
732         if (!par->ccr) {
733                 retval = -ENOMEM;
734                 goto err_ioremap_ccr;
735         }
736
737         par->lcr = ioremap(info->fix.mmio_start, info->fix.mmio_len);
738         if (!par->lcr) {
739                 retval = -ENOMEM;
740                 goto err_ioremap_lcr;
741         }
742
743         info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
744         if (!info->screen_base) {
745                 retval = -ENOMEM;
746                 goto err_ioremap_vram;
747         }
748
749         retval = request_irq(irq, &tmiofb_irq, IRQF_DISABLED,
750                                         dev_name(&dev->dev), info);
751
752         if (retval)
753                 goto err_request_irq;
754
755         platform_set_drvdata(dev, info);
756
757         retval = fb_find_mode(&info->var, info, mode_option,
758                         data->modes, data->num_modes,
759                         data->modes, 16);
760         if (!retval) {
761                 retval = -EINVAL;
762                 goto err_find_mode;
763         }
764
765         if (cell->enable) {
766                 retval = cell->enable(dev);
767                 if (retval)
768                         goto err_enable;
769         }
770
771         retval = tmiofb_hw_init(dev);
772         if (retval)
773                 goto err_hw_init;
774
775         fb_videomode_to_modelist(data->modes, data->num_modes,
776                                  &info->modelist);
777
778         retval = register_framebuffer(info);
779         if (retval < 0)
780                 goto err_register_framebuffer;
781
782         printk(KERN_INFO "fb%d: %s frame buffer device\n",
783                                 info->node, info->fix.id);
784
785         return 0;
786
787 err_register_framebuffer:
788 /*err_set_par:*/
789         tmiofb_hw_stop(dev);
790 err_hw_init:
791         if (cell->disable)
792                 cell->disable(dev);
793 err_enable:
794 err_find_mode:
795         platform_set_drvdata(dev, NULL);
796         free_irq(irq, info);
797 err_request_irq:
798         iounmap(info->screen_base);
799 err_ioremap_vram:
800         iounmap(par->lcr);
801 err_ioremap_lcr:
802         iounmap(par->ccr);
803 err_ioremap_ccr:
804         framebuffer_release(info);
805         return retval;
806 }
807
808 static int __devexit tmiofb_remove(struct platform_device *dev)
809 {
810         const struct mfd_cell *cell = mfd_get_cell(dev);
811         struct fb_info *info = platform_get_drvdata(dev);
812         int irq = platform_get_irq(dev, 0);
813         struct tmiofb_par *par;
814
815         if (info) {
816                 par = info->par;
817                 unregister_framebuffer(info);
818
819                 tmiofb_hw_stop(dev);
820
821                 if (cell->disable)
822                         cell->disable(dev);
823
824                 platform_set_drvdata(dev, NULL);
825
826                 free_irq(irq, info);
827
828                 iounmap(info->screen_base);
829                 iounmap(par->lcr);
830                 iounmap(par->ccr);
831
832                 framebuffer_release(info);
833         }
834
835         return 0;
836 }
837
838 #ifdef DEBUG
839 static void tmiofb_dump_regs(struct platform_device *dev)
840 {
841         struct fb_info *info = platform_get_drvdata(dev);
842         struct tmiofb_par *par = info->par;
843
844         printk(KERN_DEBUG "lhccr:\n");
845 #define CCR_PR(n)       printk(KERN_DEBUG "\t" #n " = \t%04x\n",\
846                 tmio_ioread16(par->ccr + CCR_ ## n));
847         CCR_PR(CMD);
848         CCR_PR(REVID);
849         CCR_PR(BASEL);
850         CCR_PR(BASEH);
851         CCR_PR(UGCC);
852         CCR_PR(GCC);
853         CCR_PR(USC);
854         CCR_PR(VRAMRTC);
855         CCR_PR(VRAMSAC);
856         CCR_PR(VRAMBC);
857 #undef CCR_PR
858
859         printk(KERN_DEBUG "lcr: \n");
860 #define LCR_PR(n)       printk(KERN_DEBUG "\t" #n " = \t%04x\n",\
861                 tmio_ioread16(par->lcr + LCR_ ## n));
862         LCR_PR(UIS);
863         LCR_PR(VHPN);
864         LCR_PR(CFSAL);
865         LCR_PR(CFSAH);
866         LCR_PR(CFS);
867         LCR_PR(CFWS);
868         LCR_PR(BBIE);
869         LCR_PR(BBISC);
870         LCR_PR(CCS);
871         LCR_PR(BBES);
872         LCR_PR(CMDL);
873         LCR_PR(CMDH);
874         LCR_PR(CFC);
875         LCR_PR(CCIFC);
876         LCR_PR(HWT);
877         LCR_PR(LCDCCRC);
878         LCR_PR(LCDCC);
879         LCR_PR(LCDCOPC);
880         LCR_PR(LCDIS);
881         LCR_PR(LCDIM);
882         LCR_PR(LCDIE);
883         LCR_PR(GDSAL);
884         LCR_PR(GDSAH);
885         LCR_PR(VHPCL);
886         LCR_PR(VHPCH);
887         LCR_PR(GM);
888         LCR_PR(HT);
889         LCR_PR(HDS);
890         LCR_PR(HSS);
891         LCR_PR(HSE);
892         LCR_PR(HNP);
893         LCR_PR(VT);
894         LCR_PR(VDS);
895         LCR_PR(VSS);
896         LCR_PR(VSE);
897         LCR_PR(CDLN);
898         LCR_PR(ILN);
899         LCR_PR(SP);
900         LCR_PR(MISC);
901         LCR_PR(VIHSS);
902         LCR_PR(VIVS);
903         LCR_PR(VIVE);
904         LCR_PR(VIVSS);
905         LCR_PR(VCCIS);
906         LCR_PR(VIDWSAL);
907         LCR_PR(VIDWSAH);
908         LCR_PR(VIDRSAL);
909         LCR_PR(VIDRSAH);
910         LCR_PR(VIPDDST);
911         LCR_PR(VIPDDET);
912         LCR_PR(VIE);
913         LCR_PR(VCS);
914         LCR_PR(VPHWC);
915         LCR_PR(VPHS);
916         LCR_PR(VPVWC);
917         LCR_PR(VPVS);
918         LCR_PR(PLHPIX);
919         LCR_PR(XS);
920         LCR_PR(XCKHW);
921         LCR_PR(STHS);
922         LCR_PR(VT2);
923         LCR_PR(YCKSW);
924         LCR_PR(YSTS);
925         LCR_PR(PPOLS);
926         LCR_PR(PRECW);
927         LCR_PR(VCLKHW);
928         LCR_PR(OC);
929 #undef LCR_PR
930 }
931 #endif
932
933 #ifdef CONFIG_PM
934 static int tmiofb_suspend(struct platform_device *dev, pm_message_t state)
935 {
936         struct fb_info *info = platform_get_drvdata(dev);
937 #ifdef CONFIG_FB_TMIO_ACCELL
938         struct tmiofb_par *par = info->par;
939 #endif
940         const struct mfd_cell *cell = mfd_get_cell(dev);
941         int retval = 0;
942
943         console_lock();
944
945         fb_set_suspend(info, 1);
946
947         if (info->fbops->fb_sync)
948                 info->fbops->fb_sync(info);
949
950
951 #ifdef CONFIG_FB_TMIO_ACCELL
952         /*
953          * The fb should be usable even if interrupts are disabled (and they are
954          * during suspend/resume). Switch temporary to forced polling.
955          */
956         printk(KERN_INFO "tmiofb: switching to polling\n");
957         par->use_polling = true;
958 #endif
959         tmiofb_hw_stop(dev);
960
961         if (cell->suspend)
962                 retval = cell->suspend(dev);
963
964         console_unlock();
965
966         return retval;
967 }
968
969 static int tmiofb_resume(struct platform_device *dev)
970 {
971         struct fb_info *info = platform_get_drvdata(dev);
972         const struct mfd_cell *cell = mfd_get_cell(dev);
973         int retval = 0;
974
975         console_lock();
976
977         if (cell->resume) {
978                 retval = cell->resume(dev);
979                 if (retval)
980                         goto out;
981         }
982
983         tmiofb_irq(-1, info);
984
985         tmiofb_hw_init(dev);
986
987         tmiofb_hw_mode(dev);
988
989         fb_set_suspend(info, 0);
990 out:
991         console_unlock();
992         return retval;
993 }
994 #else
995 #define tmiofb_suspend  NULL
996 #define tmiofb_resume   NULL
997 #endif
998
999 static struct platform_driver tmiofb_driver = {
1000         .driver.name    = "tmio-fb",
1001         .driver.owner   = THIS_MODULE,
1002         .probe          = tmiofb_probe,
1003         .remove         = __devexit_p(tmiofb_remove),
1004         .suspend        = tmiofb_suspend,
1005         .resume         = tmiofb_resume,
1006 };
1007
1008 /*--------------------------------------------------------------------------*/
1009
1010 #ifndef MODULE
1011 static void __init tmiofb_setup(char *options)
1012 {
1013         char *this_opt;
1014
1015         if (!options || !*options)
1016                 return;
1017
1018         while ((this_opt = strsep(&options, ",")) != NULL) {
1019                 if (!*this_opt)
1020                         continue;
1021                 /*
1022                  * FIXME
1023                  */
1024         }
1025 }
1026 #endif
1027
1028 static int __init tmiofb_init(void)
1029 {
1030 #ifndef MODULE
1031         char *option = NULL;
1032
1033         if (fb_get_options("tmiofb", &option))
1034                 return -ENODEV;
1035         tmiofb_setup(option);
1036 #endif
1037         return platform_driver_register(&tmiofb_driver);
1038 }
1039
1040 static void __exit tmiofb_cleanup(void)
1041 {
1042         platform_driver_unregister(&tmiofb_driver);
1043 }
1044
1045 module_init(tmiofb_init);
1046 module_exit(tmiofb_cleanup);
1047
1048 MODULE_DESCRIPTION("TMIO framebuffer driver");
1049 MODULE_AUTHOR("Chris Humbert, Dirk Opfer, Dmitry Baryshkov");
1050 MODULE_LICENSE("GPL");