2 * Frame Buffer Device for Toshiba Mobile IO(TMIO) controller
4 * Copyright(C) 2005-2006 Chris Humbert
5 * Copyright(C) 2005 Dirk Opfer
6 * Copytight(C) 2007,2008 Dmitry Baryshkov
9 * drivers/video/w100fb.c
10 * code written by Sharp/Lineo for 2.4 kernels
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;
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.
22 #include <linux/kernel.h>
23 #include <linux/module.h>
24 #include <linux/platform_device.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>
35 * accelerator commands
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))
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
100 /* a FIFO is always allocated, even if acceleration is not used */
101 #define TMIOFB_FIFO_SIZE 512
104 * LCD Host Controller Configuration Register
106 * This iomem area supports only 16-bit IO.
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 */
122 * LCD Control Register
124 * This iomem area supports only 16-bit IO.
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 */
194 static char *mode_option __devinitdata
;
197 u32 pseudo_palette
[16];
199 #ifdef CONFIG_FB_TMIO_ACCELL
200 wait_queue_head_t wait_acc
;
208 /*--------------------------------------------------------------------------*/
211 * reasons for an interrupt:
213 * 0100 0001 accelerator command completed
214 * 2000 0001 vsync start
215 * 2000 0002 display start
216 * 2000 0004 line number match(0x1ff mask???)
218 static irqreturn_t
tmiofb_irq(int irq
, void *__info
)
220 struct fb_info
*info
= __info
;
221 struct tmiofb_par
*par
= info
->par
;
222 unsigned int bbisc
= tmio_ioread16(par
->lcr
+ LCR_BBISC
);
225 tmio_iowrite16(bbisc
, par
->lcr
+ LCR_BBISC
);
227 #ifdef CONFIG_FB_TMIO_ACCELL
229 * We were in polling mode and now we got correct irq.
230 * Switch back to IRQ-based sync of command FIFO
232 if (unlikely(par
->use_polling
&& irq
!= -1)) {
233 printk(KERN_INFO
"tmiofb: switching to waitq\n");
234 par
->use_polling
= false;
238 wake_up(&par
->wait_acc
);
245 /*--------------------------------------------------------------------------*/
249 * Turns off the LCD controller and LCD host controller.
251 static int tmiofb_hw_stop(struct platform_device
*dev
)
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
;
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
);
266 * Initializes the LCD host controller.
268 static int tmiofb_hw_init(struct platform_device
*dev
)
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];
277 if (nlcr
== NULL
|| vram
== NULL
)
282 tmio_iowrite16(0x003a, par
->ccr
+ CCR_UGCC
);
283 tmio_iowrite16(0x003a, par
->ccr
+ CCR_GCC
);
284 tmio_iowrite16(0x3f00, par
->ccr
+ CCR_USC
);
286 msleep(2); /* wait for device to settle */
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
);
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
);
310 * Sets the LCD controller's output resolution and pixel clock
312 static void tmiofb_hw_mode(struct platform_device
*dev
)
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
;
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);
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 */
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
);
354 /*--------------------------------------------------------------------------*/
356 #ifdef CONFIG_FB_TMIO_ACCELL
357 static int __must_check
358 tmiofb_acc_wait(struct fb_info
*info
, unsigned int ccs
)
360 struct tmiofb_par
*par
= info
->par
;
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.
366 if (irqs_disabled() || par
->use_polling
) {
368 while (tmio_ioread16(par
->lcr
+ LCR_CCS
) > ccs
) {
372 pr_err("tmiofb: timeout waiting for %d\n",
376 tmiofb_irq(-1, info
);
379 if (!wait_event_interruptible_timeout(par
->wait_acc
,
380 tmio_ioread16(par
->lcr
+ LCR_CCS
) <= ccs
,
382 pr_err("tmiofb: timeout waiting for %d\n", ccs
);
391 * Writes an accelerator command to the accelerator's FIFO.
394 tmiofb_acc_write(struct fb_info
*info
, const u32
*cmd
, unsigned int count
)
396 struct tmiofb_par
*par
= info
->par
;
399 ret
= tmiofb_acc_wait(info
, TMIOFB_FIFO_SIZE
- count
);
403 for (; count
; count
--, cmd
++) {
404 tmio_iowrite16(*cmd
>> 16, par
->lcr
+ LCR_CMDH
);
405 tmio_iowrite16(*cmd
, par
->lcr
+ LCR_CMDL
);
412 * Wait for the accelerator to finish its operations before writing
413 * to the framebuffer for consistent display output.
415 static int tmiofb_sync(struct fb_info
*fbi
)
417 struct tmiofb_par
*par
= fbi
->par
;
422 ret
= tmiofb_acc_wait(fbi
, 0);
424 while (tmio_ioread16(par
->lcr
+ LCR_BBES
) & 2) { /* blit active */
428 printk(KERN_ERR
"timeout waiting for blit to end!\n");
437 tmiofb_fillrect(struct fb_info
*fbi
, const struct fb_fillrect
*rect
)
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
),
447 if (fbi
->state
!= FBINFO_STATE_RUNNING
||
448 fbi
->flags
& FBINFO_HWACCEL_DISABLED
) {
449 cfb_fillrect(fbi
, rect
);
453 tmiofb_acc_write(fbi
, cmd
, ARRAY_SIZE(cmd
));
457 tmiofb_copyarea(struct fb_info
*fbi
, const struct fb_copyarea
*area
)
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),
467 if (fbi
->state
!= FBINFO_STATE_RUNNING
||
468 fbi
->flags
& FBINFO_HWACCEL_DISABLED
) {
469 cfb_copyarea(fbi
, area
);
473 tmiofb_acc_write(fbi
, cmd
, ARRAY_SIZE(cmd
));
477 static void tmiofb_clearscreen(struct fb_info
*info
)
479 const struct fb_fillrect rect
= {
482 .width
= info
->mode
->xres
,
483 .height
= info
->mode
->yres
,
488 info
->fbops
->fb_fillrect(info
, &rect
);
491 static int tmiofb_vblank(struct fb_info
*fbi
, struct fb_vblank
*vblank
)
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
;
498 vblank
->vcount
= vcount
;
499 vblank
->flags
= FB_VBLANK_HAVE_VBLANK
| FB_VBLANK_HAVE_VCOUNT
500 | FB_VBLANK_HAVE_VSYNC
;
502 if (vcount
< mode
->vsync_len
)
503 vblank
->flags
|= FB_VBLANK_VSYNCING
;
505 if (vcount
< vds
|| vcount
> vds
+ mode
->yres
)
506 vblank
->flags
|= FB_VBLANK_VBLANKING
;
512 static int tmiofb_ioctl(struct fb_info
*fbi
,
513 unsigned int cmd
, unsigned long arg
)
516 case FBIOGET_VBLANK
: {
517 struct fb_vblank vblank
= {0};
518 void __user
*argp
= (void __user
*) arg
;
520 tmiofb_vblank(fbi
, &vblank
);
521 if (copy_to_user(argp
, &vblank
, sizeof vblank
))
526 #ifdef CONFIG_FB_TMIO_ACCELL
527 case FBIO_TMIO_ACC_SYNC
:
531 case FBIO_TMIO_ACC_WRITE
: {
532 u32 __user
*argp
= (void __user
*) arg
;
536 if (get_user(len
, argp
))
538 if (len
> ARRAY_SIZE(acc
))
540 if (copy_from_user(acc
, argp
+ 1, sizeof(u32
) * len
))
543 return tmiofb_acc_write(fbi
, acc
, len
);
551 /*--------------------------------------------------------------------------*/
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.
557 static struct fb_videomode
*
558 tmiofb_find_mode(struct fb_info
*info
, struct fb_var_screeninfo
*var
)
560 struct tmio_fb_data
*data
=
561 mfd_get_data(to_platform_device(info
->device
));
562 struct fb_videomode
*best
= NULL
;
565 for (i
= 0; i
< data
->num_modes
; i
++) {
566 struct fb_videomode
*mode
= data
->modes
+ i
;
568 if (mode
->xres
>= var
->xres
&& mode
->yres
>= var
->yres
569 && (!best
|| (mode
->xres
< best
->xres
570 && mode
->yres
< best
->yres
)))
577 static int tmiofb_check_var(struct fb_var_screeninfo
*var
, struct fb_info
*info
)
580 struct fb_videomode
*mode
;
581 struct tmio_fb_data
*data
=
582 mfd_get_data(to_platform_device(info
->device
));
584 mode
= tmiofb_find_mode(info
, var
);
585 if (!mode
|| var
->bits_per_pixel
> 16)
588 fb_videomode_to_var(var
, mode
);
590 var
->xres_virtual
= mode
->xres
;
591 var
->yres_virtual
= info
->screen_size
/ (mode
->xres
* 2);
593 if (var
->yres_virtual
< var
->yres
)
598 var
->bits_per_pixel
= 16;
600 var
->red
.offset
= 11;
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;
609 var
->height
= data
->height
; /* mm */
610 var
->width
= data
->width
; /* mm */
615 static int tmiofb_set_par(struct fb_info
*info
)
617 struct fb_var_screeninfo
*var
= &info
->var
;
618 struct fb_videomode
*mode
;
620 mode
= tmiofb_find_mode(info
, var
);
625 info
->fix
.line_length
= info
->mode
->xres
*
626 var
->bits_per_pixel
/ 8;
628 tmiofb_hw_mode(to_platform_device(info
->device
));
629 tmiofb_clearscreen(info
);
633 static int tmiofb_setcolreg(unsigned regno
, unsigned red
, unsigned green
,
634 unsigned blue
, unsigned transp
,
635 struct fb_info
*info
)
637 struct tmiofb_par
*par
= info
->par
;
639 if (regno
< ARRAY_SIZE(par
->pseudo_palette
)) {
640 par
->pseudo_palette
[regno
] =
642 ((green
& 0xfc00) >> 5) |
643 ((blue
& 0xf800) >> 11);
650 static int tmiofb_blank(int blank
, struct fb_info
*info
)
653 * everything is done in lcd/bl drivers.
654 * this is purely to make sysfs happy and work.
659 static struct fb_ops tmiofb_ops
= {
660 .owner
= THIS_MODULE
,
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
,
673 .fb_fillrect
= cfb_fillrect
,
674 .fb_copyarea
= cfb_copyarea
,
678 /*--------------------------------------------------------------------------*/
680 static int __devinit
tmiofb_probe(struct platform_device
*dev
)
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
;
693 * This is the only way ATM to disable the fb
696 dev_err(&dev
->dev
, "NULL platform data!\n");
700 info
= framebuffer_alloc(sizeof(struct tmiofb_par
), &dev
->dev
);
707 #ifdef CONFIG_FB_TMIO_ACCELL
708 init_waitqueue_head(&par
->wait_acc
);
710 par
->use_polling
= true;
712 info
->flags
= FBINFO_DEFAULT
| FBINFO_HWACCEL_COPYAREA
713 | FBINFO_HWACCEL_FILLRECT
;
715 info
->flags
= FBINFO_DEFAULT
;
718 info
->fbops
= &tmiofb_ops
;
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
;
731 par
->ccr
= ioremap(ccr
->start
, resource_size(ccr
));
734 goto err_ioremap_ccr
;
737 par
->lcr
= ioremap(info
->fix
.mmio_start
, info
->fix
.mmio_len
);
740 goto err_ioremap_lcr
;
743 info
->screen_base
= ioremap(info
->fix
.smem_start
, info
->fix
.smem_len
);
744 if (!info
->screen_base
) {
746 goto err_ioremap_vram
;
749 retval
= request_irq(irq
, &tmiofb_irq
, IRQF_DISABLED
,
750 dev_name(&dev
->dev
), info
);
753 goto err_request_irq
;
755 platform_set_drvdata(dev
, info
);
757 retval
= fb_find_mode(&info
->var
, info
, mode_option
,
758 data
->modes
, data
->num_modes
,
766 retval
= cell
->enable(dev
);
771 retval
= tmiofb_hw_init(dev
);
775 fb_videomode_to_modelist(data
->modes
, data
->num_modes
,
778 retval
= register_framebuffer(info
);
780 goto err_register_framebuffer
;
782 printk(KERN_INFO
"fb%d: %s frame buffer device\n",
783 info
->node
, info
->fix
.id
);
787 err_register_framebuffer
:
795 platform_set_drvdata(dev
, NULL
);
798 iounmap(info
->screen_base
);
804 framebuffer_release(info
);
808 static int __devexit
tmiofb_remove(struct platform_device
*dev
)
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
;
817 unregister_framebuffer(info
);
824 platform_set_drvdata(dev
, NULL
);
828 iounmap(info
->screen_base
);
832 framebuffer_release(info
);
839 static void tmiofb_dump_regs(struct platform_device
*dev
)
841 struct fb_info
*info
= platform_get_drvdata(dev
);
842 struct tmiofb_par
*par
= info
->par
;
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));
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));
934 static int tmiofb_suspend(struct platform_device
*dev
, pm_message_t state
)
936 struct fb_info
*info
= platform_get_drvdata(dev
);
937 #ifdef CONFIG_FB_TMIO_ACCELL
938 struct tmiofb_par
*par
= info
->par
;
940 const struct mfd_cell
*cell
= mfd_get_cell(dev
);
945 fb_set_suspend(info
, 1);
947 if (info
->fbops
->fb_sync
)
948 info
->fbops
->fb_sync(info
);
951 #ifdef CONFIG_FB_TMIO_ACCELL
953 * The fb should be usable even if interrupts are disabled (and they are
954 * during suspend/resume). Switch temporary to forced polling.
956 printk(KERN_INFO
"tmiofb: switching to polling\n");
957 par
->use_polling
= true;
962 retval
= cell
->suspend(dev
);
969 static int tmiofb_resume(struct platform_device
*dev
)
971 struct fb_info
*info
= platform_get_drvdata(dev
);
972 const struct mfd_cell
*cell
= mfd_get_cell(dev
);
978 retval
= cell
->resume(dev
);
983 tmiofb_irq(-1, info
);
989 fb_set_suspend(info
, 0);
995 #define tmiofb_suspend NULL
996 #define tmiofb_resume NULL
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
,
1008 /*--------------------------------------------------------------------------*/
1011 static void __init
tmiofb_setup(char *options
)
1015 if (!options
|| !*options
)
1018 while ((this_opt
= strsep(&options
, ",")) != NULL
) {
1028 static int __init
tmiofb_init(void)
1031 char *option
= NULL
;
1033 if (fb_get_options("tmiofb", &option
))
1035 tmiofb_setup(option
);
1037 return platform_driver_register(&tmiofb_driver
);
1040 static void __exit
tmiofb_cleanup(void)
1042 platform_driver_unregister(&tmiofb_driver
);
1045 module_init(tmiofb_init
);
1046 module_exit(tmiofb_cleanup
);
1048 MODULE_DESCRIPTION("TMIO framebuffer driver");
1049 MODULE_AUTHOR("Chris Humbert, Dirk Opfer, Dmitry Baryshkov");
1050 MODULE_LICENSE("GPL");