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
194static char *mode_option;
195
196struct 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 */
218static 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 */
251static int tmiofb_hw_stop(struct platform_device *dev)
252{
253	struct tmio_fb_data *data = dev_get_platdata(&dev->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 */
268static 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 */
312static void tmiofb_hw_mode(struct platform_device *dev)
313{
314	struct tmio_fb_data *data = dev_get_platdata(&dev->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
357static int __must_check
358tmiofb_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 */
393static int
394tmiofb_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 */
415static 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
436static void
437tmiofb_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
456static void
457tmiofb_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
477static 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
491static 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
512static 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 */
557static struct fb_videomode *
558tmiofb_find_mode(struct fb_info *info, struct fb_var_screeninfo *var)
559{
560	struct tmio_fb_data *data = dev_get_platdata(info->device);
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
576static 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 = dev_get_platdata(info->device);
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
613static 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
631static 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
648static 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
657static 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
678static int tmiofb_probe(struct platform_device *dev)
679{
680	const struct mfd_cell *cell = mfd_get_cell(dev);
681	struct tmio_fb_data *data = dev_get_platdata(&dev->dev);
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	if (ccr == NULL || lcr == NULL || vram == NULL || irq < 0) {
698		dev_err(&dev->dev, "missing resources\n");
699		return -EINVAL;
700	}
701
702	info = framebuffer_alloc(sizeof(struct tmiofb_par), &dev->dev);
703
704	if (!info)
705		return -ENOMEM;
706
707	par = info->par;
708
709#ifdef CONFIG_FB_TMIO_ACCELL
710	init_waitqueue_head(&par->wait_acc);
711
712	par->use_polling = true;
713
714	info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA
715			| FBINFO_HWACCEL_FILLRECT;
716#else
717	info->flags = FBINFO_DEFAULT;
718#endif
719
720	info->fbops = &tmiofb_ops;
721
722	strcpy(info->fix.id, "tmio-fb");
723	info->fix.smem_start = vram->start;
724	info->fix.smem_len = resource_size(vram);
725	info->fix.type = FB_TYPE_PACKED_PIXELS;
726	info->fix.visual = FB_VISUAL_TRUECOLOR;
727	info->fix.mmio_start = lcr->start;
728	info->fix.mmio_len = resource_size(lcr);
729	info->fix.accel = FB_ACCEL_NONE;
730	info->screen_size = info->fix.smem_len - (4 * TMIOFB_FIFO_SIZE);
731	info->pseudo_palette = par->pseudo_palette;
732
733	par->ccr = ioremap(ccr->start, resource_size(ccr));
734	if (!par->ccr) {
735		retval = -ENOMEM;
736		goto err_ioremap_ccr;
737	}
738
739	par->lcr = ioremap(info->fix.mmio_start, info->fix.mmio_len);
740	if (!par->lcr) {
741		retval = -ENOMEM;
742		goto err_ioremap_lcr;
743	}
744
745	info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
746	if (!info->screen_base) {
747		retval = -ENOMEM;
748		goto err_ioremap_vram;
749	}
750
751	retval = request_irq(irq, &tmiofb_irq, 0,
752					dev_name(&dev->dev), info);
753
754	if (retval)
755		goto err_request_irq;
756
757	platform_set_drvdata(dev, info);
758
759	retval = fb_find_mode(&info->var, info, mode_option,
760			data->modes, data->num_modes,
761			data->modes, 16);
762	if (!retval) {
763		retval = -EINVAL;
764		goto err_find_mode;
765	}
766
767	if (cell->enable) {
768		retval = cell->enable(dev);
769		if (retval)
770			goto err_enable;
771	}
772
773	retval = tmiofb_hw_init(dev);
774	if (retval)
775		goto err_hw_init;
776
777	fb_videomode_to_modelist(data->modes, data->num_modes,
778				 &info->modelist);
779
780	retval = register_framebuffer(info);
781	if (retval < 0)
782		goto err_register_framebuffer;
783
784	fb_info(info, "%s frame buffer device\n", info->fix.id);
785
786	return 0;
787
788err_register_framebuffer:
789/*err_set_par:*/
790	tmiofb_hw_stop(dev);
791err_hw_init:
792	if (cell->disable)
793		cell->disable(dev);
794err_enable:
795err_find_mode:
796	free_irq(irq, info);
797err_request_irq:
798	iounmap(info->screen_base);
799err_ioremap_vram:
800	iounmap(par->lcr);
801err_ioremap_lcr:
802	iounmap(par->ccr);
803err_ioremap_ccr:
804	framebuffer_release(info);
805	return retval;
806}
807
808static int 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		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
837static 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
932static 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
967static 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);
988out:
989	console_unlock();
990	return retval;
991}
992#else
993#define tmiofb_suspend	NULL
994#define tmiofb_resume	NULL
995#endif
996
997static struct platform_driver tmiofb_driver = {
998	.driver.name	= "tmio-fb",
999	.driver.owner	= THIS_MODULE,
1000	.probe		= tmiofb_probe,
1001	.remove		= tmiofb_remove,
1002	.suspend	= tmiofb_suspend,
1003	.resume		= tmiofb_resume,
1004};
1005
1006/*--------------------------------------------------------------------------*/
1007
1008#ifndef MODULE
1009static 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
1026static 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
1038static void __exit tmiofb_cleanup(void)
1039{
1040	platform_driver_unregister(&tmiofb_driver);
1041}
1042
1043module_init(tmiofb_init);
1044module_exit(tmiofb_cleanup);
1045
1046MODULE_DESCRIPTION("TMIO framebuffer driver");
1047MODULE_AUTHOR("Chris Humbert, Dirk Opfer, Dmitry Baryshkov");
1048MODULE_LICENSE("GPL");
1049