1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * linux/arch/arm/mach-pxa/saar.c
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Support for the Marvell PXA930 Handheld Platform (aka SAAR)
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * Copyright (C) 2007-2008 Marvell International Ltd.
8*4882a593Smuzhiyun */
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun #include <linux/module.h>
11*4882a593Smuzhiyun #include <linux/kernel.h>
12*4882a593Smuzhiyun #include <linux/interrupt.h>
13*4882a593Smuzhiyun #include <linux/init.h>
14*4882a593Smuzhiyun #include <linux/platform_device.h>
15*4882a593Smuzhiyun #include <linux/clk.h>
16*4882a593Smuzhiyun #include <linux/gpio.h>
17*4882a593Smuzhiyun #include <linux/delay.h>
18*4882a593Smuzhiyun #include <linux/fb.h>
19*4882a593Smuzhiyun #include <linux/i2c.h>
20*4882a593Smuzhiyun #include <linux/platform_data/i2c-pxa.h>
21*4882a593Smuzhiyun #include <linux/smc91x.h>
22*4882a593Smuzhiyun #include <linux/mfd/da903x.h>
23*4882a593Smuzhiyun #include <linux/mtd/mtd.h>
24*4882a593Smuzhiyun #include <linux/mtd/partitions.h>
25*4882a593Smuzhiyun #include <linux/mtd/onenand.h>
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun #include <asm/mach-types.h>
28*4882a593Smuzhiyun #include <asm/mach/arch.h>
29*4882a593Smuzhiyun #include <asm/mach/flash.h>
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun #include "pxa930.h"
32*4882a593Smuzhiyun #include <linux/platform_data/video-pxafb.h>
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun #include "devices.h"
35*4882a593Smuzhiyun #include "generic.h"
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun #define GPIO_LCD_RESET (16)
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun /* SAAR MFP configurations */
40*4882a593Smuzhiyun static mfp_cfg_t saar_mfp_cfg[] __initdata = {
41*4882a593Smuzhiyun /* LCD */
42*4882a593Smuzhiyun GPIO23_LCD_DD0,
43*4882a593Smuzhiyun GPIO24_LCD_DD1,
44*4882a593Smuzhiyun GPIO25_LCD_DD2,
45*4882a593Smuzhiyun GPIO26_LCD_DD3,
46*4882a593Smuzhiyun GPIO27_LCD_DD4,
47*4882a593Smuzhiyun GPIO28_LCD_DD5,
48*4882a593Smuzhiyun GPIO29_LCD_DD6,
49*4882a593Smuzhiyun GPIO44_LCD_DD7,
50*4882a593Smuzhiyun GPIO21_LCD_CS,
51*4882a593Smuzhiyun GPIO22_LCD_VSYNC,
52*4882a593Smuzhiyun GPIO17_LCD_FCLK_RD,
53*4882a593Smuzhiyun GPIO18_LCD_LCLK_A0,
54*4882a593Smuzhiyun GPIO19_LCD_PCLK_WR,
55*4882a593Smuzhiyun GPIO16_GPIO, /* LCD reset */
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun /* Ethernet */
58*4882a593Smuzhiyun DF_nCS1_nCS3,
59*4882a593Smuzhiyun GPIO97_GPIO,
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun /* DFI */
62*4882a593Smuzhiyun DF_INT_RnB_ND_INT_RnB,
63*4882a593Smuzhiyun DF_nRE_nOE_ND_nRE,
64*4882a593Smuzhiyun DF_nWE_ND_nWE,
65*4882a593Smuzhiyun DF_CLE_nOE_ND_CLE,
66*4882a593Smuzhiyun DF_nADV1_ALE_ND_ALE,
67*4882a593Smuzhiyun DF_nADV2_ALE_nCS3,
68*4882a593Smuzhiyun DF_nCS0_ND_nCS0,
69*4882a593Smuzhiyun DF_IO0_ND_IO0,
70*4882a593Smuzhiyun DF_IO1_ND_IO1,
71*4882a593Smuzhiyun DF_IO2_ND_IO2,
72*4882a593Smuzhiyun DF_IO3_ND_IO3,
73*4882a593Smuzhiyun DF_IO4_ND_IO4,
74*4882a593Smuzhiyun DF_IO5_ND_IO5,
75*4882a593Smuzhiyun DF_IO6_ND_IO6,
76*4882a593Smuzhiyun DF_IO7_ND_IO7,
77*4882a593Smuzhiyun DF_IO8_ND_IO8,
78*4882a593Smuzhiyun DF_IO9_ND_IO9,
79*4882a593Smuzhiyun DF_IO10_ND_IO10,
80*4882a593Smuzhiyun DF_IO11_ND_IO11,
81*4882a593Smuzhiyun DF_IO12_ND_IO12,
82*4882a593Smuzhiyun DF_IO13_ND_IO13,
83*4882a593Smuzhiyun DF_IO14_ND_IO14,
84*4882a593Smuzhiyun DF_IO15_ND_IO15,
85*4882a593Smuzhiyun };
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun #define SAAR_ETH_PHYS (0x14000000)
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun static struct resource smc91x_resources[] = {
90*4882a593Smuzhiyun [0] = {
91*4882a593Smuzhiyun .start = (SAAR_ETH_PHYS + 0x300),
92*4882a593Smuzhiyun .end = (SAAR_ETH_PHYS + 0xfffff),
93*4882a593Smuzhiyun .flags = IORESOURCE_MEM,
94*4882a593Smuzhiyun },
95*4882a593Smuzhiyun [1] = {
96*4882a593Smuzhiyun .start = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO97)),
97*4882a593Smuzhiyun .end = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO97)),
98*4882a593Smuzhiyun .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
99*4882a593Smuzhiyun }
100*4882a593Smuzhiyun };
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun static struct smc91x_platdata saar_smc91x_info = {
103*4882a593Smuzhiyun .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT | SMC91X_USE_DMA,
104*4882a593Smuzhiyun };
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun static struct platform_device smc91x_device = {
107*4882a593Smuzhiyun .name = "smc91x",
108*4882a593Smuzhiyun .id = 0,
109*4882a593Smuzhiyun .num_resources = ARRAY_SIZE(smc91x_resources),
110*4882a593Smuzhiyun .resource = smc91x_resources,
111*4882a593Smuzhiyun .dev = {
112*4882a593Smuzhiyun .platform_data = &saar_smc91x_info,
113*4882a593Smuzhiyun },
114*4882a593Smuzhiyun };
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun #if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
117*4882a593Smuzhiyun static uint16_t lcd_power_on[] = {
118*4882a593Smuzhiyun /* single frame */
119*4882a593Smuzhiyun SMART_CMD_NOOP,
120*4882a593Smuzhiyun SMART_CMD(0x00),
121*4882a593Smuzhiyun SMART_DELAY(0),
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun SMART_CMD_NOOP,
124*4882a593Smuzhiyun SMART_CMD(0x00),
125*4882a593Smuzhiyun SMART_DELAY(0),
126*4882a593Smuzhiyun
127*4882a593Smuzhiyun SMART_CMD_NOOP,
128*4882a593Smuzhiyun SMART_CMD(0x00),
129*4882a593Smuzhiyun SMART_DELAY(0),
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun SMART_CMD_NOOP,
132*4882a593Smuzhiyun SMART_CMD(0x00),
133*4882a593Smuzhiyun SMART_DELAY(10),
134*4882a593Smuzhiyun
135*4882a593Smuzhiyun /* calibration control */
136*4882a593Smuzhiyun SMART_CMD(0x00),
137*4882a593Smuzhiyun SMART_CMD(0xA4),
138*4882a593Smuzhiyun SMART_DAT(0x80),
139*4882a593Smuzhiyun SMART_DAT(0x01),
140*4882a593Smuzhiyun SMART_DELAY(150),
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun /*Power-On Init sequence*/
143*4882a593Smuzhiyun SMART_CMD(0x00), /* output ctrl */
144*4882a593Smuzhiyun SMART_CMD(0x01),
145*4882a593Smuzhiyun SMART_DAT(0x01),
146*4882a593Smuzhiyun SMART_DAT(0x00),
147*4882a593Smuzhiyun SMART_CMD(0x00), /* wave ctrl */
148*4882a593Smuzhiyun SMART_CMD(0x02),
149*4882a593Smuzhiyun SMART_DAT(0x07),
150*4882a593Smuzhiyun SMART_DAT(0x00),
151*4882a593Smuzhiyun SMART_CMD(0x00),
152*4882a593Smuzhiyun SMART_CMD(0x03), /* entry mode */
153*4882a593Smuzhiyun SMART_DAT(0xD0),
154*4882a593Smuzhiyun SMART_DAT(0x30),
155*4882a593Smuzhiyun SMART_CMD(0x00),
156*4882a593Smuzhiyun SMART_CMD(0x08), /* display ctrl 2 */
157*4882a593Smuzhiyun SMART_DAT(0x08),
158*4882a593Smuzhiyun SMART_DAT(0x08),
159*4882a593Smuzhiyun SMART_CMD(0x00),
160*4882a593Smuzhiyun SMART_CMD(0x09), /* display ctrl 3 */
161*4882a593Smuzhiyun SMART_DAT(0x04),
162*4882a593Smuzhiyun SMART_DAT(0x2F),
163*4882a593Smuzhiyun SMART_CMD(0x00),
164*4882a593Smuzhiyun SMART_CMD(0x0A), /* display ctrl 4 */
165*4882a593Smuzhiyun SMART_DAT(0x00),
166*4882a593Smuzhiyun SMART_DAT(0x08),
167*4882a593Smuzhiyun SMART_CMD(0x00),
168*4882a593Smuzhiyun SMART_CMD(0x0D), /* Frame Marker position */
169*4882a593Smuzhiyun SMART_DAT(0x00),
170*4882a593Smuzhiyun SMART_DAT(0x08),
171*4882a593Smuzhiyun SMART_CMD(0x00),
172*4882a593Smuzhiyun SMART_CMD(0x60), /* Driver output control */
173*4882a593Smuzhiyun SMART_DAT(0x27),
174*4882a593Smuzhiyun SMART_DAT(0x00),
175*4882a593Smuzhiyun SMART_CMD(0x00),
176*4882a593Smuzhiyun SMART_CMD(0x61), /* Base image display control */
177*4882a593Smuzhiyun SMART_DAT(0x00),
178*4882a593Smuzhiyun SMART_DAT(0x01),
179*4882a593Smuzhiyun SMART_CMD(0x00),
180*4882a593Smuzhiyun SMART_CMD(0x30), /* Y settings 30h-3Dh */
181*4882a593Smuzhiyun SMART_DAT(0x07),
182*4882a593Smuzhiyun SMART_DAT(0x07),
183*4882a593Smuzhiyun SMART_CMD(0x00),
184*4882a593Smuzhiyun SMART_CMD(0x31),
185*4882a593Smuzhiyun SMART_DAT(0x00),
186*4882a593Smuzhiyun SMART_DAT(0x07),
187*4882a593Smuzhiyun SMART_CMD(0x00),
188*4882a593Smuzhiyun SMART_CMD(0x32), /* Timing(3), ASW HOLD=0.5CLK */
189*4882a593Smuzhiyun SMART_DAT(0x04),
190*4882a593Smuzhiyun SMART_DAT(0x00),
191*4882a593Smuzhiyun SMART_CMD(0x00),
192*4882a593Smuzhiyun SMART_CMD(0x33), /* Timing(4), CKV ST=0CLK, CKV ED=1CLK */
193*4882a593Smuzhiyun SMART_DAT(0x03),
194*4882a593Smuzhiyun SMART_DAT(0x03),
195*4882a593Smuzhiyun SMART_CMD(0x00),
196*4882a593Smuzhiyun SMART_CMD(0x34),
197*4882a593Smuzhiyun SMART_DAT(0x00),
198*4882a593Smuzhiyun SMART_DAT(0x00),
199*4882a593Smuzhiyun SMART_CMD(0x00),
200*4882a593Smuzhiyun SMART_CMD(0x35),
201*4882a593Smuzhiyun SMART_DAT(0x02),
202*4882a593Smuzhiyun SMART_DAT(0x05),
203*4882a593Smuzhiyun SMART_CMD(0x00),
204*4882a593Smuzhiyun SMART_CMD(0x36),
205*4882a593Smuzhiyun SMART_DAT(0x1F),
206*4882a593Smuzhiyun SMART_DAT(0x1F),
207*4882a593Smuzhiyun SMART_CMD(0x00),
208*4882a593Smuzhiyun SMART_CMD(0x37),
209*4882a593Smuzhiyun SMART_DAT(0x07),
210*4882a593Smuzhiyun SMART_DAT(0x07),
211*4882a593Smuzhiyun SMART_CMD(0x00),
212*4882a593Smuzhiyun SMART_CMD(0x38),
213*4882a593Smuzhiyun SMART_DAT(0x00),
214*4882a593Smuzhiyun SMART_DAT(0x07),
215*4882a593Smuzhiyun SMART_CMD(0x00),
216*4882a593Smuzhiyun SMART_CMD(0x39),
217*4882a593Smuzhiyun SMART_DAT(0x04),
218*4882a593Smuzhiyun SMART_DAT(0x00),
219*4882a593Smuzhiyun SMART_CMD(0x00),
220*4882a593Smuzhiyun SMART_CMD(0x3A),
221*4882a593Smuzhiyun SMART_DAT(0x03),
222*4882a593Smuzhiyun SMART_DAT(0x03),
223*4882a593Smuzhiyun SMART_CMD(0x00),
224*4882a593Smuzhiyun SMART_CMD(0x3B),
225*4882a593Smuzhiyun SMART_DAT(0x00),
226*4882a593Smuzhiyun SMART_DAT(0x00),
227*4882a593Smuzhiyun SMART_CMD(0x00),
228*4882a593Smuzhiyun SMART_CMD(0x3C),
229*4882a593Smuzhiyun SMART_DAT(0x02),
230*4882a593Smuzhiyun SMART_DAT(0x05),
231*4882a593Smuzhiyun SMART_CMD(0x00),
232*4882a593Smuzhiyun SMART_CMD(0x3D),
233*4882a593Smuzhiyun SMART_DAT(0x1F),
234*4882a593Smuzhiyun SMART_DAT(0x1F),
235*4882a593Smuzhiyun SMART_CMD(0x00), /* Display control 1 */
236*4882a593Smuzhiyun SMART_CMD(0x07),
237*4882a593Smuzhiyun SMART_DAT(0x00),
238*4882a593Smuzhiyun SMART_DAT(0x01),
239*4882a593Smuzhiyun SMART_CMD(0x00), /* Power control 5 */
240*4882a593Smuzhiyun SMART_CMD(0x17),
241*4882a593Smuzhiyun SMART_DAT(0x00),
242*4882a593Smuzhiyun SMART_DAT(0x01),
243*4882a593Smuzhiyun SMART_CMD(0x00), /* Power control 1 */
244*4882a593Smuzhiyun SMART_CMD(0x10),
245*4882a593Smuzhiyun SMART_DAT(0x10),
246*4882a593Smuzhiyun SMART_DAT(0xB0),
247*4882a593Smuzhiyun SMART_CMD(0x00), /* Power control 2 */
248*4882a593Smuzhiyun SMART_CMD(0x11),
249*4882a593Smuzhiyun SMART_DAT(0x01),
250*4882a593Smuzhiyun SMART_DAT(0x30),
251*4882a593Smuzhiyun SMART_CMD(0x00), /* Power control 3 */
252*4882a593Smuzhiyun SMART_CMD(0x12),
253*4882a593Smuzhiyun SMART_DAT(0x01),
254*4882a593Smuzhiyun SMART_DAT(0x9E),
255*4882a593Smuzhiyun SMART_CMD(0x00), /* Power control 4 */
256*4882a593Smuzhiyun SMART_CMD(0x13),
257*4882a593Smuzhiyun SMART_DAT(0x17),
258*4882a593Smuzhiyun SMART_DAT(0x00),
259*4882a593Smuzhiyun SMART_CMD(0x00), /* Power control 3 */
260*4882a593Smuzhiyun SMART_CMD(0x12),
261*4882a593Smuzhiyun SMART_DAT(0x01),
262*4882a593Smuzhiyun SMART_DAT(0xBE),
263*4882a593Smuzhiyun SMART_DELAY(100),
264*4882a593Smuzhiyun
265*4882a593Smuzhiyun /* display mode : 240*320 */
266*4882a593Smuzhiyun SMART_CMD(0x00), /* RAM address set(H) 0*/
267*4882a593Smuzhiyun SMART_CMD(0x20),
268*4882a593Smuzhiyun SMART_DAT(0x00),
269*4882a593Smuzhiyun SMART_DAT(0x00),
270*4882a593Smuzhiyun SMART_CMD(0x00), /* RAM address set(V) 4*/
271*4882a593Smuzhiyun SMART_CMD(0x21),
272*4882a593Smuzhiyun SMART_DAT(0x00),
273*4882a593Smuzhiyun SMART_DAT(0x00),
274*4882a593Smuzhiyun SMART_CMD(0x00), /* Start of Window RAM address set(H) 8*/
275*4882a593Smuzhiyun SMART_CMD(0x50),
276*4882a593Smuzhiyun SMART_DAT(0x00),
277*4882a593Smuzhiyun SMART_DAT(0x00),
278*4882a593Smuzhiyun SMART_CMD(0x00), /* End of Window RAM address set(H) 12*/
279*4882a593Smuzhiyun SMART_CMD(0x51),
280*4882a593Smuzhiyun SMART_DAT(0x00),
281*4882a593Smuzhiyun SMART_DAT(0xEF),
282*4882a593Smuzhiyun SMART_CMD(0x00), /* Start of Window RAM address set(V) 16*/
283*4882a593Smuzhiyun SMART_CMD(0x52),
284*4882a593Smuzhiyun SMART_DAT(0x00),
285*4882a593Smuzhiyun SMART_DAT(0x00),
286*4882a593Smuzhiyun SMART_CMD(0x00), /* End of Window RAM address set(V) 20*/
287*4882a593Smuzhiyun SMART_CMD(0x53),
288*4882a593Smuzhiyun SMART_DAT(0x01),
289*4882a593Smuzhiyun SMART_DAT(0x3F),
290*4882a593Smuzhiyun SMART_CMD(0x00), /* Panel interface control 1 */
291*4882a593Smuzhiyun SMART_CMD(0x90),
292*4882a593Smuzhiyun SMART_DAT(0x00),
293*4882a593Smuzhiyun SMART_DAT(0x1A),
294*4882a593Smuzhiyun SMART_CMD(0x00), /* Panel interface control 2 */
295*4882a593Smuzhiyun SMART_CMD(0x92),
296*4882a593Smuzhiyun SMART_DAT(0x04),
297*4882a593Smuzhiyun SMART_DAT(0x00),
298*4882a593Smuzhiyun SMART_CMD(0x00), /* Panel interface control 3 */
299*4882a593Smuzhiyun SMART_CMD(0x93),
300*4882a593Smuzhiyun SMART_DAT(0x00),
301*4882a593Smuzhiyun SMART_DAT(0x05),
302*4882a593Smuzhiyun SMART_DELAY(20),
303*4882a593Smuzhiyun };
304*4882a593Smuzhiyun
305*4882a593Smuzhiyun static uint16_t lcd_panel_on[] = {
306*4882a593Smuzhiyun SMART_CMD(0x00),
307*4882a593Smuzhiyun SMART_CMD(0x07),
308*4882a593Smuzhiyun SMART_DAT(0x00),
309*4882a593Smuzhiyun SMART_DAT(0x21),
310*4882a593Smuzhiyun SMART_DELAY(1),
311*4882a593Smuzhiyun
312*4882a593Smuzhiyun SMART_CMD(0x00),
313*4882a593Smuzhiyun SMART_CMD(0x07),
314*4882a593Smuzhiyun SMART_DAT(0x00),
315*4882a593Smuzhiyun SMART_DAT(0x61),
316*4882a593Smuzhiyun SMART_DELAY(100),
317*4882a593Smuzhiyun
318*4882a593Smuzhiyun SMART_CMD(0x00),
319*4882a593Smuzhiyun SMART_CMD(0x07),
320*4882a593Smuzhiyun SMART_DAT(0x01),
321*4882a593Smuzhiyun SMART_DAT(0x73),
322*4882a593Smuzhiyun SMART_DELAY(1),
323*4882a593Smuzhiyun };
324*4882a593Smuzhiyun
325*4882a593Smuzhiyun static uint16_t lcd_panel_off[] = {
326*4882a593Smuzhiyun SMART_CMD(0x00),
327*4882a593Smuzhiyun SMART_CMD(0x07),
328*4882a593Smuzhiyun SMART_DAT(0x00),
329*4882a593Smuzhiyun SMART_DAT(0x72),
330*4882a593Smuzhiyun SMART_DELAY(40),
331*4882a593Smuzhiyun
332*4882a593Smuzhiyun SMART_CMD(0x00),
333*4882a593Smuzhiyun SMART_CMD(0x07),
334*4882a593Smuzhiyun SMART_DAT(0x00),
335*4882a593Smuzhiyun SMART_DAT(0x01),
336*4882a593Smuzhiyun SMART_DELAY(1),
337*4882a593Smuzhiyun
338*4882a593Smuzhiyun SMART_CMD(0x00),
339*4882a593Smuzhiyun SMART_CMD(0x07),
340*4882a593Smuzhiyun SMART_DAT(0x00),
341*4882a593Smuzhiyun SMART_DAT(0x00),
342*4882a593Smuzhiyun SMART_DELAY(1),
343*4882a593Smuzhiyun };
344*4882a593Smuzhiyun
345*4882a593Smuzhiyun static uint16_t lcd_power_off[] = {
346*4882a593Smuzhiyun SMART_CMD(0x00),
347*4882a593Smuzhiyun SMART_CMD(0x10),
348*4882a593Smuzhiyun SMART_DAT(0x00),
349*4882a593Smuzhiyun SMART_DAT(0x80),
350*4882a593Smuzhiyun
351*4882a593Smuzhiyun SMART_CMD(0x00),
352*4882a593Smuzhiyun SMART_CMD(0x11),
353*4882a593Smuzhiyun SMART_DAT(0x01),
354*4882a593Smuzhiyun SMART_DAT(0x60),
355*4882a593Smuzhiyun
356*4882a593Smuzhiyun SMART_CMD(0x00),
357*4882a593Smuzhiyun SMART_CMD(0x12),
358*4882a593Smuzhiyun SMART_DAT(0x01),
359*4882a593Smuzhiyun SMART_DAT(0xAE),
360*4882a593Smuzhiyun SMART_DELAY(40),
361*4882a593Smuzhiyun
362*4882a593Smuzhiyun SMART_CMD(0x00),
363*4882a593Smuzhiyun SMART_CMD(0x10),
364*4882a593Smuzhiyun SMART_DAT(0x00),
365*4882a593Smuzhiyun SMART_DAT(0x00),
366*4882a593Smuzhiyun };
367*4882a593Smuzhiyun
368*4882a593Smuzhiyun static uint16_t update_framedata[] = {
369*4882a593Smuzhiyun /* set display ram: 240*320 */
370*4882a593Smuzhiyun SMART_CMD(0x00), /* RAM address set(H) 0*/
371*4882a593Smuzhiyun SMART_CMD(0x20),
372*4882a593Smuzhiyun SMART_DAT(0x00),
373*4882a593Smuzhiyun SMART_DAT(0x00),
374*4882a593Smuzhiyun SMART_CMD(0x00), /* RAM address set(V) 4*/
375*4882a593Smuzhiyun SMART_CMD(0x21),
376*4882a593Smuzhiyun SMART_DAT(0x00),
377*4882a593Smuzhiyun SMART_DAT(0x00),
378*4882a593Smuzhiyun SMART_CMD(0x00), /* Start of Window RAM address set(H) 8 */
379*4882a593Smuzhiyun SMART_CMD(0x50),
380*4882a593Smuzhiyun SMART_DAT(0x00),
381*4882a593Smuzhiyun SMART_DAT(0x00),
382*4882a593Smuzhiyun SMART_CMD(0x00), /* End of Window RAM address set(H) 12 */
383*4882a593Smuzhiyun SMART_CMD(0x51),
384*4882a593Smuzhiyun SMART_DAT(0x00),
385*4882a593Smuzhiyun SMART_DAT(0xEF),
386*4882a593Smuzhiyun SMART_CMD(0x00), /* Start of Window RAM address set(V) 16 */
387*4882a593Smuzhiyun SMART_CMD(0x52),
388*4882a593Smuzhiyun SMART_DAT(0x00),
389*4882a593Smuzhiyun SMART_DAT(0x00),
390*4882a593Smuzhiyun SMART_CMD(0x00), /* End of Window RAM address set(V) 20 */
391*4882a593Smuzhiyun SMART_CMD(0x53),
392*4882a593Smuzhiyun SMART_DAT(0x01),
393*4882a593Smuzhiyun SMART_DAT(0x3F),
394*4882a593Smuzhiyun
395*4882a593Smuzhiyun /* wait for vsync cmd before transferring frame data */
396*4882a593Smuzhiyun SMART_CMD_WAIT_FOR_VSYNC,
397*4882a593Smuzhiyun
398*4882a593Smuzhiyun /* write ram */
399*4882a593Smuzhiyun SMART_CMD(0x00),
400*4882a593Smuzhiyun SMART_CMD(0x22),
401*4882a593Smuzhiyun
402*4882a593Smuzhiyun /* write frame data */
403*4882a593Smuzhiyun SMART_CMD_WRITE_FRAME,
404*4882a593Smuzhiyun };
405*4882a593Smuzhiyun
ltm022a97a_lcd_power(int on,struct fb_var_screeninfo * var)406*4882a593Smuzhiyun static void ltm022a97a_lcd_power(int on, struct fb_var_screeninfo *var)
407*4882a593Smuzhiyun {
408*4882a593Smuzhiyun static int pin_requested = 0;
409*4882a593Smuzhiyun struct fb_info *info = container_of(var, struct fb_info, var);
410*4882a593Smuzhiyun int err;
411*4882a593Smuzhiyun
412*4882a593Smuzhiyun if (!pin_requested) {
413*4882a593Smuzhiyun err = gpio_request(GPIO_LCD_RESET, "lcd reset");
414*4882a593Smuzhiyun if (err) {
415*4882a593Smuzhiyun pr_err("failed to request gpio for LCD reset\n");
416*4882a593Smuzhiyun return;
417*4882a593Smuzhiyun }
418*4882a593Smuzhiyun
419*4882a593Smuzhiyun gpio_direction_output(GPIO_LCD_RESET, 0);
420*4882a593Smuzhiyun pin_requested = 1;
421*4882a593Smuzhiyun }
422*4882a593Smuzhiyun
423*4882a593Smuzhiyun if (on) {
424*4882a593Smuzhiyun gpio_set_value(GPIO_LCD_RESET, 0); msleep(100);
425*4882a593Smuzhiyun gpio_set_value(GPIO_LCD_RESET, 1); msleep(10);
426*4882a593Smuzhiyun
427*4882a593Smuzhiyun pxafb_smart_queue(info, ARRAY_AND_SIZE(lcd_power_on));
428*4882a593Smuzhiyun pxafb_smart_queue(info, ARRAY_AND_SIZE(lcd_panel_on));
429*4882a593Smuzhiyun } else {
430*4882a593Smuzhiyun pxafb_smart_queue(info, ARRAY_AND_SIZE(lcd_panel_off));
431*4882a593Smuzhiyun pxafb_smart_queue(info, ARRAY_AND_SIZE(lcd_power_off));
432*4882a593Smuzhiyun }
433*4882a593Smuzhiyun
434*4882a593Smuzhiyun err = pxafb_smart_flush(info);
435*4882a593Smuzhiyun if (err)
436*4882a593Smuzhiyun pr_err("%s: timed out\n", __func__);
437*4882a593Smuzhiyun }
438*4882a593Smuzhiyun
ltm022a97a_update(struct fb_info * info)439*4882a593Smuzhiyun static void ltm022a97a_update(struct fb_info *info)
440*4882a593Smuzhiyun {
441*4882a593Smuzhiyun pxafb_smart_queue(info, ARRAY_AND_SIZE(update_framedata));
442*4882a593Smuzhiyun pxafb_smart_flush(info);
443*4882a593Smuzhiyun }
444*4882a593Smuzhiyun
445*4882a593Smuzhiyun static struct pxafb_mode_info toshiba_ltm022a97a_modes[] = {
446*4882a593Smuzhiyun [0] = {
447*4882a593Smuzhiyun .xres = 240,
448*4882a593Smuzhiyun .yres = 320,
449*4882a593Smuzhiyun .bpp = 16,
450*4882a593Smuzhiyun .a0csrd_set_hld = 30,
451*4882a593Smuzhiyun .a0cswr_set_hld = 30,
452*4882a593Smuzhiyun .wr_pulse_width = 30,
453*4882a593Smuzhiyun .rd_pulse_width = 30,
454*4882a593Smuzhiyun .op_hold_time = 30,
455*4882a593Smuzhiyun .cmd_inh_time = 60,
456*4882a593Smuzhiyun
457*4882a593Smuzhiyun /* L_LCLK_A0 and L_LCLK_RD active low */
458*4882a593Smuzhiyun .sync = FB_SYNC_HOR_HIGH_ACT |
459*4882a593Smuzhiyun FB_SYNC_VERT_HIGH_ACT,
460*4882a593Smuzhiyun },
461*4882a593Smuzhiyun };
462*4882a593Smuzhiyun
463*4882a593Smuzhiyun static struct pxafb_mach_info saar_lcd_info = {
464*4882a593Smuzhiyun .modes = toshiba_ltm022a97a_modes,
465*4882a593Smuzhiyun .num_modes = 1,
466*4882a593Smuzhiyun .lcd_conn = LCD_SMART_PANEL_8BPP | LCD_PCLK_EDGE_FALL,
467*4882a593Smuzhiyun .pxafb_lcd_power = ltm022a97a_lcd_power,
468*4882a593Smuzhiyun .smart_update = ltm022a97a_update,
469*4882a593Smuzhiyun };
470*4882a593Smuzhiyun
saar_init_lcd(void)471*4882a593Smuzhiyun static void __init saar_init_lcd(void)
472*4882a593Smuzhiyun {
473*4882a593Smuzhiyun pxa_set_fb_info(NULL, &saar_lcd_info);
474*4882a593Smuzhiyun }
475*4882a593Smuzhiyun #else
saar_init_lcd(void)476*4882a593Smuzhiyun static inline void saar_init_lcd(void) {}
477*4882a593Smuzhiyun #endif
478*4882a593Smuzhiyun
479*4882a593Smuzhiyun #if defined(CONFIG_I2C_PXA) || defined(CONFIG_I2C_PXA_MODULE)
480*4882a593Smuzhiyun static struct da9034_backlight_pdata saar_da9034_backlight = {
481*4882a593Smuzhiyun .output_current = 4, /* 4mA */
482*4882a593Smuzhiyun };
483*4882a593Smuzhiyun
484*4882a593Smuzhiyun static struct da903x_subdev_info saar_da9034_subdevs[] = {
485*4882a593Smuzhiyun [0] = {
486*4882a593Smuzhiyun .name = "da903x-backlight",
487*4882a593Smuzhiyun .id = DA9034_ID_WLED,
488*4882a593Smuzhiyun .platform_data = &saar_da9034_backlight,
489*4882a593Smuzhiyun },
490*4882a593Smuzhiyun };
491*4882a593Smuzhiyun
492*4882a593Smuzhiyun static struct da903x_platform_data saar_da9034_info = {
493*4882a593Smuzhiyun .num_subdevs = ARRAY_SIZE(saar_da9034_subdevs),
494*4882a593Smuzhiyun .subdevs = saar_da9034_subdevs,
495*4882a593Smuzhiyun };
496*4882a593Smuzhiyun
497*4882a593Smuzhiyun static struct i2c_board_info saar_i2c_info[] = {
498*4882a593Smuzhiyun [0] = {
499*4882a593Smuzhiyun .type = "da9034",
500*4882a593Smuzhiyun .addr = 0x34,
501*4882a593Smuzhiyun .platform_data = &saar_da9034_info,
502*4882a593Smuzhiyun .irq = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO83)),
503*4882a593Smuzhiyun },
504*4882a593Smuzhiyun };
505*4882a593Smuzhiyun
saar_init_i2c(void)506*4882a593Smuzhiyun static void __init saar_init_i2c(void)
507*4882a593Smuzhiyun {
508*4882a593Smuzhiyun pxa_set_i2c_info(NULL);
509*4882a593Smuzhiyun i2c_register_board_info(0, ARRAY_AND_SIZE(saar_i2c_info));
510*4882a593Smuzhiyun }
511*4882a593Smuzhiyun #else
saar_init_i2c(void)512*4882a593Smuzhiyun static inline void saar_init_i2c(void) {}
513*4882a593Smuzhiyun #endif
514*4882a593Smuzhiyun
515*4882a593Smuzhiyun #if defined(CONFIG_MTD_ONENAND) || defined(CONFIG_MTD_ONENAND_MODULE)
516*4882a593Smuzhiyun static struct mtd_partition saar_onenand_partitions[] = {
517*4882a593Smuzhiyun {
518*4882a593Smuzhiyun .name = "bootloader",
519*4882a593Smuzhiyun .offset = 0,
520*4882a593Smuzhiyun .size = SZ_1M,
521*4882a593Smuzhiyun .mask_flags = MTD_WRITEABLE,
522*4882a593Smuzhiyun }, {
523*4882a593Smuzhiyun .name = "reserved",
524*4882a593Smuzhiyun .offset = MTDPART_OFS_APPEND,
525*4882a593Smuzhiyun .size = SZ_128K,
526*4882a593Smuzhiyun .mask_flags = MTD_WRITEABLE,
527*4882a593Smuzhiyun }, {
528*4882a593Smuzhiyun .name = "reserved",
529*4882a593Smuzhiyun .offset = MTDPART_OFS_APPEND,
530*4882a593Smuzhiyun .size = SZ_8M,
531*4882a593Smuzhiyun .mask_flags = MTD_WRITEABLE,
532*4882a593Smuzhiyun }, {
533*4882a593Smuzhiyun .name = "kernel",
534*4882a593Smuzhiyun .offset = MTDPART_OFS_APPEND,
535*4882a593Smuzhiyun .size = (SZ_2M + SZ_1M),
536*4882a593Smuzhiyun .mask_flags = 0,
537*4882a593Smuzhiyun }, {
538*4882a593Smuzhiyun .name = "filesystem",
539*4882a593Smuzhiyun .offset = MTDPART_OFS_APPEND,
540*4882a593Smuzhiyun .size = SZ_32M + SZ_16M,
541*4882a593Smuzhiyun .mask_flags = 0,
542*4882a593Smuzhiyun }
543*4882a593Smuzhiyun };
544*4882a593Smuzhiyun
545*4882a593Smuzhiyun static struct onenand_platform_data saar_onenand_info = {
546*4882a593Smuzhiyun .parts = saar_onenand_partitions,
547*4882a593Smuzhiyun .nr_parts = ARRAY_SIZE(saar_onenand_partitions),
548*4882a593Smuzhiyun };
549*4882a593Smuzhiyun
550*4882a593Smuzhiyun #define SMC_CS0_PHYS_BASE (0x10000000)
551*4882a593Smuzhiyun
552*4882a593Smuzhiyun static struct resource saar_resource_onenand[] = {
553*4882a593Smuzhiyun [0] = {
554*4882a593Smuzhiyun .start = SMC_CS0_PHYS_BASE,
555*4882a593Smuzhiyun .end = SMC_CS0_PHYS_BASE + SZ_1M,
556*4882a593Smuzhiyun .flags = IORESOURCE_MEM,
557*4882a593Smuzhiyun },
558*4882a593Smuzhiyun };
559*4882a593Smuzhiyun
560*4882a593Smuzhiyun static struct platform_device saar_device_onenand = {
561*4882a593Smuzhiyun .name = "onenand-flash",
562*4882a593Smuzhiyun .id = -1,
563*4882a593Smuzhiyun .dev = {
564*4882a593Smuzhiyun .platform_data = &saar_onenand_info,
565*4882a593Smuzhiyun },
566*4882a593Smuzhiyun .resource = saar_resource_onenand,
567*4882a593Smuzhiyun .num_resources = ARRAY_SIZE(saar_resource_onenand),
568*4882a593Smuzhiyun };
569*4882a593Smuzhiyun
saar_init_onenand(void)570*4882a593Smuzhiyun static void __init saar_init_onenand(void)
571*4882a593Smuzhiyun {
572*4882a593Smuzhiyun platform_device_register(&saar_device_onenand);
573*4882a593Smuzhiyun }
574*4882a593Smuzhiyun #else
saar_init_onenand(void)575*4882a593Smuzhiyun static void __init saar_init_onenand(void) {}
576*4882a593Smuzhiyun #endif
577*4882a593Smuzhiyun
saar_init(void)578*4882a593Smuzhiyun static void __init saar_init(void)
579*4882a593Smuzhiyun {
580*4882a593Smuzhiyun /* initialize MFP configurations */
581*4882a593Smuzhiyun pxa3xx_mfp_config(ARRAY_AND_SIZE(saar_mfp_cfg));
582*4882a593Smuzhiyun
583*4882a593Smuzhiyun pxa_set_ffuart_info(NULL);
584*4882a593Smuzhiyun pxa_set_btuart_info(NULL);
585*4882a593Smuzhiyun pxa_set_stuart_info(NULL);
586*4882a593Smuzhiyun
587*4882a593Smuzhiyun platform_device_register(&smc91x_device);
588*4882a593Smuzhiyun saar_init_onenand();
589*4882a593Smuzhiyun
590*4882a593Smuzhiyun saar_init_i2c();
591*4882a593Smuzhiyun saar_init_lcd();
592*4882a593Smuzhiyun }
593*4882a593Smuzhiyun
594*4882a593Smuzhiyun MACHINE_START(SAAR, "PXA930 Handheld Platform (aka SAAR)")
595*4882a593Smuzhiyun /* Maintainer: Eric Miao <eric.miao@marvell.com> */
596*4882a593Smuzhiyun .atag_offset = 0x100,
597*4882a593Smuzhiyun .map_io = pxa3xx_map_io,
598*4882a593Smuzhiyun .nr_irqs = PXA_NR_IRQS,
599*4882a593Smuzhiyun .init_irq = pxa3xx_init_irq,
600*4882a593Smuzhiyun .handle_irq = pxa3xx_handle_irq,
601*4882a593Smuzhiyun .init_time = pxa_timer_init,
602*4882a593Smuzhiyun .init_machine = saar_init,
603*4882a593Smuzhiyun .restart = pxa_restart,
604*4882a593Smuzhiyun MACHINE_END
605