aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-pxa
diff options
context:
space:
mode:
authorRichard Purdie <rpurdie@rpsys.net>2005-09-06 18:19:05 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-07 19:57:53 -0400
commit41b1bce80b43f7c6a6c64006b2abe3a8d52ab120 (patch)
tree729b4693ea52f4fcd53bfe5474d6c274bc2347ca /arch/arm/mach-pxa
parentaac51f09d96a0acfb73c1d1c0796358bb47ea07b (diff)
[PATCH] w100fb: Update corgi platform code to match new driver
This patch moves the platform specific Sharp SL-C7x0 LCD code from the w100fb driver into a more appropriate place and updates the Corgi code to match the new w100fb driver. It also updates the corgi touchscreen code to match the new simplified interface available from w100fb. Signed-off-by: Richard Purdie <rpurdie@rpsys.net> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/arm/mach-pxa')
-rw-r--r--arch/arm/mach-pxa/Makefile2
-rw-r--r--arch/arm/mach-pxa/corgi.c35
-rw-r--r--arch/arm/mach-pxa/corgi_lcd.c396
3 files changed, 398 insertions, 35 deletions
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index efc2f657184e..33dae99ec2d8 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -11,7 +11,7 @@ obj-$(CONFIG_PXA27x) += pxa27x.o
11obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o 11obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o
12obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o 12obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o
13obj-$(CONFIG_ARCH_PXA_IDP) += idp.o 13obj-$(CONFIG_ARCH_PXA_IDP) += idp.o
14obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o corgi_ssp.o ssp.o 14obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o corgi_ssp.o corgi_lcd.o ssp.o
15obj-$(CONFIG_MACH_POODLE) += poodle.o 15obj-$(CONFIG_MACH_POODLE) += poodle.o
16 16
17# Support for blinky lights 17# Support for blinky lights
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index 06ea730e8675..453be2948533 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -39,7 +39,6 @@
39 39
40#include <asm/mach/sharpsl_param.h> 40#include <asm/mach/sharpsl_param.h>
41#include <asm/hardware/scoop.h> 41#include <asm/hardware/scoop.h>
42#include <video/w100fb.h>
43 42
44#include "generic.h" 43#include "generic.h"
45 44
@@ -87,7 +86,7 @@ struct platform_device corgiscoop_device = {
87 * also use scoop functions and this makes the power up/down order 86 * also use scoop functions and this makes the power up/down order
88 * work correctly. 87 * work correctly.
89 */ 88 */
90static struct platform_device corgissp_device = { 89struct platform_device corgissp_device = {
91 .name = "corgi-ssp", 90 .name = "corgi-ssp",
92 .dev = { 91 .dev = {
93 .parent = &corgiscoop_device.dev, 92 .parent = &corgiscoop_device.dev,
@@ -97,35 +96,6 @@ static struct platform_device corgissp_device = {
97 96
98 97
99/* 98/*
100 * Corgi w100 Frame Buffer Device
101 */
102static struct w100fb_mach_info corgi_fb_info = {
103 .w100fb_ssp_send = corgi_ssp_lcdtg_send,
104 .comadj = -1,
105 .phadadj = -1,
106};
107
108static struct resource corgi_fb_resources[] = {
109 [0] = {
110 .start = 0x08000000,
111 .end = 0x08ffffff,
112 .flags = IORESOURCE_MEM,
113 },
114};
115
116static struct platform_device corgifb_device = {
117 .name = "w100fb",
118 .id = -1,
119 .dev = {
120 .platform_data = &corgi_fb_info,
121 .parent = &corgissp_device.dev,
122 },
123 .num_resources = ARRAY_SIZE(corgi_fb_resources),
124 .resource = corgi_fb_resources,
125};
126
127
128/*
129 * Corgi Backlight Device 99 * Corgi Backlight Device
130 */ 100 */
131static struct platform_device corgibl_device = { 101static struct platform_device corgibl_device = {
@@ -243,9 +213,6 @@ static struct platform_device *devices[] __initdata = {
243 213
244static void __init corgi_init(void) 214static void __init corgi_init(void)
245{ 215{
246 corgi_fb_info.comadj=sharpsl_param.comadj;
247 corgi_fb_info.phadadj=sharpsl_param.phadadj;
248
249 pxa_gpio_mode(CORGI_GPIO_USB_PULLUP | GPIO_OUT); 216 pxa_gpio_mode(CORGI_GPIO_USB_PULLUP | GPIO_OUT);
250 pxa_set_udc_info(&udc_info); 217 pxa_set_udc_info(&udc_info);
251 pxa_set_mci_info(&corgi_mci_platform_data); 218 pxa_set_mci_info(&corgi_mci_platform_data);
diff --git a/arch/arm/mach-pxa/corgi_lcd.c b/arch/arm/mach-pxa/corgi_lcd.c
new file mode 100644
index 000000000000..deac29c00290
--- /dev/null
+++ b/arch/arm/mach-pxa/corgi_lcd.c
@@ -0,0 +1,396 @@
1/*
2 * linux/drivers/video/w100fb.c
3 *
4 * Corgi LCD Specific Code for ATI Imageon w100 (Wallaby)
5 *
6 * Copyright (C) 2005 Richard Purdie
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13
14#include <linux/delay.h>
15#include <linux/kernel.h>
16#include <linux/device.h>
17#include <asm/arch/corgi.h>
18#include <asm/mach/sharpsl_param.h>
19#include <video/w100fb.h>
20
21/* Register Addresses */
22#define RESCTL_ADRS 0x00
23#define PHACTRL_ADRS 0x01
24#define DUTYCTRL_ADRS 0x02
25#define POWERREG0_ADRS 0x03
26#define POWERREG1_ADRS 0x04
27#define GPOR3_ADRS 0x05
28#define PICTRL_ADRS 0x06
29#define POLCTRL_ADRS 0x07
30
31/* Resgister Bit Definitions */
32#define RESCTL_QVGA 0x01
33#define RESCTL_VGA 0x00
34
35#define POWER1_VW_ON 0x01 /* VW Supply FET ON */
36#define POWER1_GVSS_ON 0x02 /* GVSS(-8V) Power Supply ON */
37#define POWER1_VDD_ON 0x04 /* VDD(8V),SVSS(-4V) Power Supply ON */
38
39#define POWER1_VW_OFF 0x00 /* VW Supply FET OFF */
40#define POWER1_GVSS_OFF 0x00 /* GVSS(-8V) Power Supply OFF */
41#define POWER1_VDD_OFF 0x00 /* VDD(8V),SVSS(-4V) Power Supply OFF */
42
43#define POWER0_COM_DCLK 0x01 /* COM Voltage DC Bias DAC Serial Data Clock */
44#define POWER0_COM_DOUT 0x02 /* COM Voltage DC Bias DAC Serial Data Out */
45#define POWER0_DAC_ON 0x04 /* DAC Power Supply ON */
46#define POWER0_COM_ON 0x08 /* COM Powewr Supply ON */
47#define POWER0_VCC5_ON 0x10 /* VCC5 Power Supply ON */
48
49#define POWER0_DAC_OFF 0x00 /* DAC Power Supply OFF */
50#define POWER0_COM_OFF 0x00 /* COM Powewr Supply OFF */
51#define POWER0_VCC5_OFF 0x00 /* VCC5 Power Supply OFF */
52
53#define PICTRL_INIT_STATE 0x01
54#define PICTRL_INIOFF 0x02
55#define PICTRL_POWER_DOWN 0x04
56#define PICTRL_COM_SIGNAL_OFF 0x08
57#define PICTRL_DAC_SIGNAL_OFF 0x10
58
59#define POLCTRL_SYNC_POL_FALL 0x01
60#define POLCTRL_EN_POL_FALL 0x02
61#define POLCTRL_DATA_POL_FALL 0x04
62#define POLCTRL_SYNC_ACT_H 0x08
63#define POLCTRL_EN_ACT_L 0x10
64
65#define POLCTRL_SYNC_POL_RISE 0x00
66#define POLCTRL_EN_POL_RISE 0x00
67#define POLCTRL_DATA_POL_RISE 0x00
68#define POLCTRL_SYNC_ACT_L 0x00
69#define POLCTRL_EN_ACT_H 0x00
70
71#define PHACTRL_PHASE_MANUAL 0x01
72#define DEFAULT_PHAD_QVGA (9)
73#define DEFAULT_COMADJ (125)
74
75/*
76 * This is only a psuedo I2C interface. We can't use the standard kernel
77 * routines as the interface is write only. We just assume the data is acked...
78 */
79static void lcdtg_ssp_i2c_send(u8 data)
80{
81 corgi_ssp_lcdtg_send(POWERREG0_ADRS, data);
82 udelay(10);
83}
84
85static void lcdtg_i2c_send_bit(u8 data)
86{
87 lcdtg_ssp_i2c_send(data);
88 lcdtg_ssp_i2c_send(data | POWER0_COM_DCLK);
89 lcdtg_ssp_i2c_send(data);
90}
91
92static void lcdtg_i2c_send_start(u8 base)
93{
94 lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK | POWER0_COM_DOUT);
95 lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK);
96 lcdtg_ssp_i2c_send(base);
97}
98
99static void lcdtg_i2c_send_stop(u8 base)
100{
101 lcdtg_ssp_i2c_send(base);
102 lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK);
103 lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK | POWER0_COM_DOUT);
104}
105
106static void lcdtg_i2c_send_byte(u8 base, u8 data)
107{
108 int i;
109 for (i = 0; i < 8; i++) {
110 if (data & 0x80)
111 lcdtg_i2c_send_bit(base | POWER0_COM_DOUT);
112 else
113 lcdtg_i2c_send_bit(base);
114 data <<= 1;
115 }
116}
117
118static void lcdtg_i2c_wait_ack(u8 base)
119{
120 lcdtg_i2c_send_bit(base);
121}
122
123static void lcdtg_set_common_voltage(u8 base_data, u8 data)
124{
125 /* Set Common Voltage to M62332FP via I2C */
126 lcdtg_i2c_send_start(base_data);
127 lcdtg_i2c_send_byte(base_data, 0x9c);
128 lcdtg_i2c_wait_ack(base_data);
129 lcdtg_i2c_send_byte(base_data, 0x00);
130 lcdtg_i2c_wait_ack(base_data);
131 lcdtg_i2c_send_byte(base_data, data);
132 lcdtg_i2c_wait_ack(base_data);
133 lcdtg_i2c_send_stop(base_data);
134}
135
136/* Set Phase Adjuct */
137static void lcdtg_set_phadadj(struct w100fb_par *par)
138{
139 int adj;
140 switch(par->xres) {
141 case 480:
142 case 640:
143 /* Setting for VGA */
144 adj = sharpsl_param.phadadj;
145 if (adj < 0) {
146 adj = PHACTRL_PHASE_MANUAL;
147 } else {
148 adj = ((adj & 0x0f) << 1) | PHACTRL_PHASE_MANUAL;
149 }
150 break;
151 case 240:
152 case 320:
153 default:
154 /* Setting for QVGA */
155 adj = (DEFAULT_PHAD_QVGA << 1) | PHACTRL_PHASE_MANUAL;
156 break;
157 }
158
159 corgi_ssp_lcdtg_send(PHACTRL_ADRS, adj);
160}
161
162static int lcd_inited;
163
164static void lcdtg_hw_init(struct w100fb_par *par)
165{
166 if (!lcd_inited) {
167 int comadj;
168
169 /* Initialize Internal Logic & Port */
170 corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_POWER_DOWN | PICTRL_INIOFF | PICTRL_INIT_STATE
171 | PICTRL_COM_SIGNAL_OFF | PICTRL_DAC_SIGNAL_OFF);
172
173 corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_OFF
174 | POWER0_COM_OFF | POWER0_VCC5_OFF);
175
176 corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_OFF);
177
178 /* VDD(+8V), SVSS(-4V) ON */
179 corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_ON);
180 mdelay(3);
181
182 /* DAC ON */
183 corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON
184 | POWER0_COM_OFF | POWER0_VCC5_OFF);
185
186 /* INIB = H, INI = L */
187 /* PICTL[0] = H , PICTL[1] = PICTL[2] = PICTL[4] = L */
188 corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_INIT_STATE | PICTRL_COM_SIGNAL_OFF);
189
190 /* Set Common Voltage */
191 comadj = sharpsl_param.comadj;
192 if (comadj < 0)
193 comadj = DEFAULT_COMADJ;
194 lcdtg_set_common_voltage((POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_OFF), comadj);
195
196 /* VCC5 ON, DAC ON */
197 corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON |
198 POWER0_COM_OFF | POWER0_VCC5_ON);
199
200 /* GVSS(-8V) ON, VDD ON */
201 corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_ON | POWER1_VDD_ON);
202 mdelay(2);
203
204 /* COM SIGNAL ON (PICTL[3] = L) */
205 corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_INIT_STATE);
206
207 /* COM ON, DAC ON, VCC5_ON */
208 corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON
209 | POWER0_COM_ON | POWER0_VCC5_ON);
210
211 /* VW ON, GVSS ON, VDD ON */
212 corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_ON | POWER1_GVSS_ON | POWER1_VDD_ON);
213
214 /* Signals output enable */
215 corgi_ssp_lcdtg_send(PICTRL_ADRS, 0);
216
217 /* Set Phase Adjuct */
218 lcdtg_set_phadadj(par);
219
220 /* Initialize for Input Signals from ATI */
221 corgi_ssp_lcdtg_send(POLCTRL_ADRS, POLCTRL_SYNC_POL_RISE | POLCTRL_EN_POL_RISE
222 | POLCTRL_DATA_POL_RISE | POLCTRL_SYNC_ACT_L | POLCTRL_EN_ACT_H);
223 udelay(1000);
224
225 lcd_inited=1;
226 } else {
227 lcdtg_set_phadadj(par);
228 }
229
230 switch(par->xres) {
231 case 480:
232 case 640:
233 /* Set Lcd Resolution (VGA) */
234 corgi_ssp_lcdtg_send(RESCTL_ADRS, RESCTL_VGA);
235 break;
236 case 240:
237 case 320:
238 default:
239 /* Set Lcd Resolution (QVGA) */
240 corgi_ssp_lcdtg_send(RESCTL_ADRS, RESCTL_QVGA);
241 break;
242 }
243}
244
245static void lcdtg_suspend(struct w100fb_par *par)
246{
247 /* 60Hz x 2 frame = 16.7msec x 2 = 33.4 msec */
248 mdelay(34);
249
250 /* (1)VW OFF */
251 corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_ON | POWER1_VDD_ON);
252
253 /* (2)COM OFF */
254 corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_COM_SIGNAL_OFF);
255 corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_ON);
256
257 /* (3)Set Common Voltage Bias 0V */
258 lcdtg_set_common_voltage(POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_ON, 0);
259
260 /* (4)GVSS OFF */
261 corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_ON);
262
263 /* (5)VCC5 OFF */
264 corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_OFF);
265
266 /* (6)Set PDWN, INIOFF, DACOFF */
267 corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_INIOFF | PICTRL_DAC_SIGNAL_OFF |
268 PICTRL_POWER_DOWN | PICTRL_COM_SIGNAL_OFF);
269
270 /* (7)DAC OFF */
271 corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_DAC_OFF | POWER0_COM_OFF | POWER0_VCC5_OFF);
272
273 /* (8)VDD OFF */
274 corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_OFF);
275
276 lcd_inited = 0;
277}
278
279static struct w100_tg_info corgi_lcdtg_info = {
280 .change=lcdtg_hw_init,
281 .suspend=lcdtg_suspend,
282 .resume=lcdtg_hw_init,
283};
284
285/*
286 * Corgi w100 Frame Buffer Device
287 */
288
289static struct w100_mem_info corgi_fb_mem = {
290 .ext_cntl = 0x00040003,
291 .sdram_mode_reg = 0x00650021,
292 .ext_timing_cntl = 0x10002a4a,
293 .io_cntl = 0x7ff87012,
294 .size = 0x1fffff,
295};
296
297static struct w100_gen_regs corgi_fb_regs = {
298 .lcd_format = 0x00000003,
299 .lcdd_cntl1 = 0x01CC0000,
300 .lcdd_cntl2 = 0x0003FFFF,
301 .genlcd_cntl1 = 0x00FFFF0D,
302 .genlcd_cntl2 = 0x003F3003,
303 .genlcd_cntl3 = 0x000102aa,
304};
305
306static struct w100_gpio_regs corgi_fb_gpio = {
307 .init_data1 = 0x000000bf,
308 .init_data2 = 0x00000000,
309 .gpio_dir1 = 0x00000000,
310 .gpio_oe1 = 0x03c0feff,
311 .gpio_dir2 = 0x00000000,
312 .gpio_oe2 = 0x00000000,
313};
314
315static struct w100_mode corgi_fb_modes[] = {
316{
317 .xres = 480,
318 .yres = 640,
319 .left_margin = 0x56,
320 .right_margin = 0x55,
321 .upper_margin = 0x03,
322 .lower_margin = 0x00,
323 .crtc_ss = 0x82360056,
324 .crtc_ls = 0xA0280000,
325 .crtc_gs = 0x80280028,
326 .crtc_vpos_gs = 0x02830002,
327 .crtc_rev = 0x00400008,
328 .crtc_dclk = 0xA0000000,
329 .crtc_gclk = 0x8015010F,
330 .crtc_goe = 0x80100110,
331 .crtc_ps1_active = 0x41060010,
332 .pll_freq = 75,
333 .fast_pll_freq = 100,
334 .sysclk_src = CLK_SRC_PLL,
335 .sysclk_divider = 0,
336 .pixclk_src = CLK_SRC_PLL,
337 .pixclk_divider = 2,
338 .pixclk_divider_rotated = 6,
339},{
340 .xres = 240,
341 .yres = 320,
342 .left_margin = 0x27,
343 .right_margin = 0x2e,
344 .upper_margin = 0x01,
345 .lower_margin = 0x00,
346 .crtc_ss = 0x81170027,
347 .crtc_ls = 0xA0140000,
348 .crtc_gs = 0xC0140014,
349 .crtc_vpos_gs = 0x00010141,
350 .crtc_rev = 0x00400008,
351 .crtc_dclk = 0xA0000000,
352 .crtc_gclk = 0x8015010F,
353 .crtc_goe = 0x80100110,
354 .crtc_ps1_active = 0x41060010,
355 .pll_freq = 0,
356 .fast_pll_freq = 0,
357 .sysclk_src = CLK_SRC_XTAL,
358 .sysclk_divider = 0,
359 .pixclk_src = CLK_SRC_XTAL,
360 .pixclk_divider = 1,
361 .pixclk_divider_rotated = 1,
362},
363
364};
365
366static struct w100fb_mach_info corgi_fb_info = {
367 .tg = &corgi_lcdtg_info,
368 .init_mode = INIT_MODE_ROTATED,
369 .mem = &corgi_fb_mem,
370 .regs = &corgi_fb_regs,
371 .modelist = &corgi_fb_modes[0],
372 .num_modes = 2,
373 .gpio = &corgi_fb_gpio,
374 .xtal_freq = 12500000,
375 .xtal_dbl = 0,
376};
377
378static struct resource corgi_fb_resources[] = {
379 [0] = {
380 .start = 0x08000000,
381 .end = 0x08ffffff,
382 .flags = IORESOURCE_MEM,
383 },
384};
385
386struct platform_device corgifb_device = {
387 .name = "w100fb",
388 .id = -1,
389 .num_resources = ARRAY_SIZE(corgi_fb_resources),
390 .resource = corgi_fb_resources,
391 .dev = {
392 .platform_data = &corgi_fb_info,
393 .parent = &corgissp_device.dev,
394 },
395
396};