1 /*
2  *  linux/arch/arm/mach-pxa/colibri-pxa270.c
3  *
4  *  Support for Toradex PXA270 based Colibri module
5  *  Daniel Mack <daniel@caiaq.de>
6  *  Marek Vasut <marek.vasut@gmail.com>
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 #include <linux/init.h>
14 #include <linux/interrupt.h>
15 #include <linux/moduleparam.h>
16 #include <linux/kernel.h>
17 #include <linux/mtd/mtd.h>
18 #include <linux/mtd/partitions.h>
19 #include <linux/mtd/physmap.h>
20 #include <linux/platform_device.h>
21 #include <linux/ucb1400.h>
22 
23 #include <asm/mach/arch.h>
24 #include <asm/mach/flash.h>
25 #include <asm/mach-types.h>
26 #include <asm/sizes.h>
27 
28 #include <mach/audio.h>
29 #include <mach/colibri.h>
30 #include <mach/pxa27x.h>
31 
32 #include "devices.h"
33 #include "generic.h"
34 
35 /******************************************************************************
36  * Evaluation board MFP
37  ******************************************************************************/
38 #ifdef	 CONFIG_MACH_COLIBRI_EVALBOARD
39 static mfp_cfg_t colibri_pxa270_evalboard_pin_config[] __initdata = {
40 	/* MMC */
41 	GPIO32_MMC_CLK,
42 	GPIO92_MMC_DAT_0,
43 	GPIO109_MMC_DAT_1,
44 	GPIO110_MMC_DAT_2,
45 	GPIO111_MMC_DAT_3,
46 	GPIO112_MMC_CMD,
47 	GPIO0_GPIO,	/* SD detect */
48 
49 	/* FFUART */
50 	GPIO39_FFUART_TXD,
51 	GPIO34_FFUART_RXD,
52 
53 	/* UHC */
54 	GPIO88_USBH1_PWR,
55 	GPIO89_USBH1_PEN,
56 	GPIO119_USBH2_PWR,
57 	GPIO120_USBH2_PEN,
58 
59 	/* PCMCIA */
60 	GPIO85_nPCE_1,
61 	GPIO54_nPCE_2,
62 	GPIO55_nPREG,
63 	GPIO50_nPIOR,
64 	GPIO51_nPIOW,
65 	GPIO49_nPWE,
66 	GPIO48_nPOE,
67 	GPIO57_nIOIS16,
68 	GPIO56_nPWAIT,
69 	GPIO104_PSKTSEL,
70 	GPIO53_GPIO,	/* RESET */
71 	GPIO83_GPIO,	/* BVD1 */
72 	GPIO82_GPIO,	/* BVD2 */
73 	GPIO1_GPIO,	/* READY */
74 	GPIO84_GPIO,	/* DETECT */
75 	GPIO107_GPIO,	/* PPEN */
76 
77 	/* I2C */
78 	GPIO117_I2C_SCL,
79 	GPIO118_I2C_SDA,
80 };
81 #else
82 static mfp_cfg_t colibri_pxa270_evalboard_pin_config[] __initdata = {};
83 #endif
84 
85 #ifdef	CONFIG_MACH_COLIBRI_PXA270_INCOME
86 static mfp_cfg_t income_pin_config[] __initdata = {
87 	/* MMC */
88 	GPIO32_MMC_CLK,
89 	GPIO92_MMC_DAT_0,
90 	GPIO109_MMC_DAT_1,
91 	GPIO110_MMC_DAT_2,
92 	GPIO111_MMC_DAT_3,
93 	GPIO112_MMC_CMD,
94 	GPIO0_GPIO,	/* SD detect */
95 	GPIO1_GPIO,	/* SD read-only */
96 
97 	/* FFUART */
98 	GPIO39_FFUART_TXD,
99 	GPIO34_FFUART_RXD,
100 
101 	/* BFUART */
102 	GPIO42_BTUART_RXD,
103 	GPIO43_BTUART_TXD,
104 	GPIO45_BTUART_RTS,
105 
106 	/* STUART */
107 	GPIO46_STUART_RXD,
108 	GPIO47_STUART_TXD,
109 
110 	/* UHC */
111 	GPIO88_USBH1_PWR,
112 	GPIO89_USBH1_PEN,
113 
114 	/* LCD */
115 	GPIOxx_LCD_TFT_16BPP,
116 
117 	/* PWM */
118 	GPIO16_PWM0_OUT,
119 
120 	/* I2C */
121 	GPIO117_I2C_SCL,
122 	GPIO118_I2C_SDA,
123 
124 	/* LED */
125 	GPIO54_GPIO,	/* LED A */
126 	GPIO55_GPIO,	/* LED B */
127 };
128 #else
129 static mfp_cfg_t income_pin_config[] __initdata = {};
130 #endif
131 
132 /******************************************************************************
133  * Pin configuration
134  ******************************************************************************/
135 static mfp_cfg_t colibri_pxa270_pin_config[] __initdata = {
136 	/* Ethernet */
137 	GPIO78_nCS_2,	/* Ethernet CS */
138 	GPIO114_GPIO,	/* Ethernet IRQ */
139 
140 	/* AC97 */
141 	GPIO28_AC97_BITCLK,
142 	GPIO29_AC97_SDATA_IN_0,
143 	GPIO30_AC97_SDATA_OUT,
144 	GPIO31_AC97_SYNC,
145 	GPIO95_AC97_nRESET,
146 	GPIO98_AC97_SYSCLK,
147 	GPIO113_GPIO,	/* Touchscreen IRQ */
148 };
149 
150 /******************************************************************************
151  * NOR Flash
152  ******************************************************************************/
153 #if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
154 static struct mtd_partition colibri_partitions[] = {
155 	{
156 		.name =		"Bootloader",
157 		.offset =	0x00000000,
158 		.size =		0x00040000,
159 		.mask_flags =	MTD_WRITEABLE	/* force read-only */
160 	}, {
161 		.name =		"Kernel",
162 		.offset =	0x00040000,
163 		.size =		0x00400000,
164 		.mask_flags =	0
165 	}, {
166 		.name =		"Rootfs",
167 		.offset =	0x00440000,
168 		.size =		MTDPART_SIZ_FULL,
169 		.mask_flags =	0
170 	}
171 };
172 
173 static struct physmap_flash_data colibri_flash_data[] = {
174 	{
175 		.width		= 4,			/* bankwidth in bytes */
176 		.parts		= colibri_partitions,
177 		.nr_parts	= ARRAY_SIZE(colibri_partitions)
178 	}
179 };
180 
181 static struct resource colibri_pxa270_flash_resource = {
182 	.start	= PXA_CS0_PHYS,
183 	.end	= PXA_CS0_PHYS + SZ_32M - 1,
184 	.flags	= IORESOURCE_MEM,
185 };
186 
187 static struct platform_device colibri_pxa270_flash_device = {
188 	.name	= "physmap-flash",
189 	.id	= 0,
190 	.dev 	= {
191 		.platform_data = colibri_flash_data,
192 	},
193 	.resource = &colibri_pxa270_flash_resource,
194 	.num_resources = 1,
195 };
196 
colibri_pxa270_nor_init(void)197 static void __init colibri_pxa270_nor_init(void)
198 {
199 	platform_device_register(&colibri_pxa270_flash_device);
200 }
201 #else
colibri_pxa270_nor_init(void)202 static inline void colibri_pxa270_nor_init(void) {}
203 #endif
204 
205 /******************************************************************************
206  * Ethernet
207  ******************************************************************************/
208 #if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
209 static struct resource colibri_pxa270_dm9000_resources[] = {
210 	{
211 		.start	= PXA_CS2_PHYS,
212 		.end	= PXA_CS2_PHYS + 3,
213 		.flags	= IORESOURCE_MEM,
214 	},
215 	{
216 		.start	= PXA_CS2_PHYS + 4,
217 		.end	= PXA_CS2_PHYS + 4 + 500,
218 		.flags	= IORESOURCE_MEM,
219 	},
220 	{
221 		.start	= PXA_GPIO_TO_IRQ(GPIO114_COLIBRI_PXA270_ETH_IRQ),
222 		.end	= PXA_GPIO_TO_IRQ(GPIO114_COLIBRI_PXA270_ETH_IRQ),
223 		.flags	= IORESOURCE_IRQ | IRQF_TRIGGER_RISING,
224 	},
225 };
226 
227 static struct platform_device colibri_pxa270_dm9000_device = {
228 	.name		= "dm9000",
229 	.id		= -1,
230 	.num_resources	= ARRAY_SIZE(colibri_pxa270_dm9000_resources),
231 	.resource	= colibri_pxa270_dm9000_resources,
232 };
233 
colibri_pxa270_eth_init(void)234 static void __init colibri_pxa270_eth_init(void)
235 {
236 	platform_device_register(&colibri_pxa270_dm9000_device);
237 }
238 #else
colibri_pxa270_eth_init(void)239 static inline void colibri_pxa270_eth_init(void) {}
240 #endif
241 
242 /******************************************************************************
243  * Audio and Touchscreen
244  ******************************************************************************/
245 #if	defined(CONFIG_TOUCHSCREEN_UCB1400) || \
246 	defined(CONFIG_TOUCHSCREEN_UCB1400_MODULE)
247 static pxa2xx_audio_ops_t colibri_pxa270_ac97_pdata = {
248 	.reset_gpio	= 95,
249 };
250 
251 static struct ucb1400_pdata colibri_pxa270_ucb1400_pdata = {
252 	.irq		= PXA_GPIO_TO_IRQ(GPIO113_COLIBRI_PXA270_TS_IRQ),
253 };
254 
255 static struct platform_device colibri_pxa270_ucb1400_device = {
256 	.name		= "ucb1400_core",
257 	.id		= -1,
258 	.dev		= {
259 		.platform_data = &colibri_pxa270_ucb1400_pdata,
260 	},
261 };
262 
colibri_pxa270_tsc_init(void)263 static void __init colibri_pxa270_tsc_init(void)
264 {
265 	pxa_set_ac97_info(&colibri_pxa270_ac97_pdata);
266 	platform_device_register(&colibri_pxa270_ucb1400_device);
267 }
268 #else
colibri_pxa270_tsc_init(void)269 static inline void colibri_pxa270_tsc_init(void) {}
270 #endif
271 
272 static int colibri_pxa270_baseboard;
273 core_param(colibri_pxa270_baseboard, colibri_pxa270_baseboard, int, 0444);
274 
colibri_pxa270_init(void)275 static void __init colibri_pxa270_init(void)
276 {
277 	pxa2xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa270_pin_config));
278 
279 	colibri_pxa270_nor_init();
280 	colibri_pxa270_eth_init();
281 	colibri_pxa270_tsc_init();
282 
283 	switch (colibri_pxa270_baseboard) {
284 	case COLIBRI_EVALBOARD:
285 		pxa2xx_mfp_config(ARRAY_AND_SIZE(
286 			colibri_pxa270_evalboard_pin_config));
287 		colibri_evalboard_init();
288 		break;
289 	case COLIBRI_PXA270_INCOME:
290 		pxa2xx_mfp_config(ARRAY_AND_SIZE(income_pin_config));
291 		colibri_pxa270_income_boardinit();
292 		break;
293 	default:
294 		printk(KERN_ERR "Illegal colibri_pxa270_baseboard type %d\n",
295 				colibri_pxa270_baseboard);
296 	}
297 }
298 
299 /* The "Income s.r.o. SH-Dmaster PXA270 SBC" board can be booted either
300  * with the INCOME mach type or with COLIBRI and the kernel parameter
301  * "colibri_pxa270_baseboard=1"
302  */
colibri_pxa270_income_init(void)303 static void __init colibri_pxa270_income_init(void)
304 {
305 	colibri_pxa270_baseboard = COLIBRI_PXA270_INCOME;
306 	colibri_pxa270_init();
307 }
308 
309 MACHINE_START(COLIBRI, "Toradex Colibri PXA270")
310 	.atag_offset	= 0x100,
311 	.init_machine	= colibri_pxa270_init,
312 	.map_io		= pxa27x_map_io,
313 	.init_irq	= pxa27x_init_irq,
314 	.handle_irq	= pxa27x_handle_irq,
315 	.timer		= &pxa_timer,
316 	.restart	= pxa_restart,
317 MACHINE_END
318 
319 MACHINE_START(INCOME, "Income s.r.o. SH-Dmaster PXA270 SBC")
320 	.atag_offset	= 0x100,
321 	.init_machine	= colibri_pxa270_income_init,
322 	.map_io		= pxa27x_map_io,
323 	.init_irq	= pxa27x_init_irq,
324 	.handle_irq	= pxa27x_handle_irq,
325 	.timer		= &pxa_timer,
326 	.restart	= pxa_restart,
327 MACHINE_END
328 
329