1#include <linux/device.h>
2#include <linux/dma-mapping.h>
3#include <linux/amba/bus.h>
4#include <linux/amba/clcd.h>
5#include <linux/platform_data/video-clcd-versatile.h>
6
7static struct clcd_panel vga = {
8	.mode		= {
9		.name		= "VGA",
10		.refresh	= 60,
11		.xres		= 640,
12		.yres		= 480,
13		.pixclock	= 39721,
14		.left_margin	= 40,
15		.right_margin	= 24,
16		.upper_margin	= 32,
17		.lower_margin	= 11,
18		.hsync_len	= 96,
19		.vsync_len	= 2,
20		.sync		= 0,
21		.vmode		= FB_VMODE_NONINTERLACED,
22	},
23	.width		= -1,
24	.height		= -1,
25	.tim2		= TIM2_BCD | TIM2_IPC,
26	.cntl		= CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
27	.caps		= CLCD_CAP_5551 | CLCD_CAP_565 | CLCD_CAP_888,
28	.bpp		= 16,
29};
30
31static struct clcd_panel xvga = {
32	.mode		= {
33		.name		= "XVGA",
34		.refresh	= 60,
35		.xres		= 1024,
36		.yres		= 768,
37		.pixclock	= 15748,
38		.left_margin	= 152,
39		.right_margin	= 48,
40		.upper_margin	= 23,
41		.lower_margin	= 3,
42		.hsync_len	= 104,
43		.vsync_len	= 4,
44		.sync		= 0,
45		.vmode		= FB_VMODE_NONINTERLACED,
46	},
47	.width		= -1,
48	.height		= -1,
49	.tim2		= TIM2_BCD | TIM2_IPC,
50	.cntl		= CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
51	.caps		= CLCD_CAP_5551 | CLCD_CAP_565 | CLCD_CAP_888,
52	.bpp		= 16,
53};
54
55/* Sanyo TM38QV67A02A - 3.8 inch QVGA (320x240) Color TFT */
56static struct clcd_panel sanyo_tm38qv67a02a = {
57	.mode		= {
58		.name		= "Sanyo TM38QV67A02A",
59		.refresh	= 116,
60		.xres		= 320,
61		.yres		= 240,
62		.pixclock	= 100000,
63		.left_margin	= 6,
64		.right_margin	= 6,
65		.upper_margin	= 5,
66		.lower_margin	= 5,
67		.hsync_len	= 6,
68		.vsync_len	= 6,
69		.sync		= 0,
70		.vmode		= FB_VMODE_NONINTERLACED,
71	},
72	.width		= -1,
73	.height		= -1,
74	.tim2		= TIM2_BCD,
75	.cntl		= CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
76	.caps		= CLCD_CAP_5551,
77	.bpp		= 16,
78};
79
80static struct clcd_panel sanyo_2_5_in = {
81	.mode		= {
82		.name		= "Sanyo QVGA Portrait",
83		.refresh	= 116,
84		.xres		= 240,
85		.yres		= 320,
86		.pixclock	= 100000,
87		.left_margin	= 20,
88		.right_margin	= 10,
89		.upper_margin	= 2,
90		.lower_margin	= 2,
91		.hsync_len	= 10,
92		.vsync_len	= 2,
93		.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
94		.vmode		= FB_VMODE_NONINTERLACED,
95	},
96	.width		= -1,
97	.height		= -1,
98	.tim2		= TIM2_IVS | TIM2_IHS | TIM2_IPC,
99	.cntl		= CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
100	.caps		= CLCD_CAP_5551,
101	.bpp		= 16,
102};
103
104/* Epson L2F50113T00 - 2.2 inch 176x220 Color TFT */
105static struct clcd_panel epson_l2f50113t00 = {
106	.mode		= {
107		.name		= "Epson L2F50113T00",
108		.refresh	= 390,
109		.xres		= 176,
110		.yres		= 220,
111		.pixclock	= 62500,
112		.left_margin	= 3,
113		.right_margin	= 2,
114		.upper_margin	= 1,
115		.lower_margin	= 0,
116		.hsync_len	= 3,
117		.vsync_len	= 2,
118		.sync		= 0,
119		.vmode		= FB_VMODE_NONINTERLACED,
120	},
121	.width		= -1,
122	.height		= -1,
123	.tim2		= TIM2_BCD | TIM2_IPC,
124	.cntl		= CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
125	.caps		= CLCD_CAP_5551,
126	.bpp		= 16,
127};
128
129static struct clcd_panel *panels[] = {
130	&vga,
131	&xvga,
132	&sanyo_tm38qv67a02a,
133	&sanyo_2_5_in,
134	&epson_l2f50113t00,
135};
136
137struct clcd_panel *versatile_clcd_get_panel(const char *name)
138{
139	int i;
140
141	for (i = 0; i < ARRAY_SIZE(panels); i++)
142		if (strcmp(panels[i]->mode.name, name) == 0)
143			break;
144
145	if (i < ARRAY_SIZE(panels))
146		return panels[i];
147
148	pr_err("CLCD: couldn't get parameters for panel %s\n", name);
149
150	return NULL;
151}
152
153int versatile_clcd_setup_dma(struct clcd_fb *fb, unsigned long framesize)
154{
155	dma_addr_t dma;
156
157	fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize,
158						    &dma, GFP_KERNEL);
159	if (!fb->fb.screen_base) {
160		pr_err("CLCD: unable to map framebuffer\n");
161		return -ENOMEM;
162	}
163
164	fb->fb.fix.smem_start	= dma;
165	fb->fb.fix.smem_len	= framesize;
166
167	return 0;
168}
169
170int versatile_clcd_mmap_dma(struct clcd_fb *fb, struct vm_area_struct *vma)
171{
172	return dma_mmap_writecombine(&fb->dev->dev, vma,
173				     fb->fb.screen_base,
174				     fb->fb.fix.smem_start,
175				     fb->fb.fix.smem_len);
176}
177
178void versatile_clcd_remove_dma(struct clcd_fb *fb)
179{
180	dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len,
181			      fb->fb.screen_base, fb->fb.fix.smem_start);
182}
183