1/*
2 *  linux/arch/arm/mach-pxa/mainstone.c
3 *
4 *  Support for the Intel HCDDBBVA0 Development Platform.
5 *  (go figure how they came up with such name...)
6 *
7 *  Author:	Nicolas Pitre
8 *  Created:	Nov 05, 2002
9 *  Copyright:	MontaVista Software Inc.
10 *
11 *  This program is free software; you can redistribute it and/or modify
12 *  it under the terms of the GNU General Public License version 2 as
13 *  published by the Free Software Foundation.
14 */
15
16#include <linux/init.h>
17#include <linux/platform_device.h>
18#include <linux/sysdev.h>
19#include <linux/interrupt.h>
20#include <linux/sched.h>
21#include <linux/bitops.h>
22#include <linux/fb.h>
23#include <linux/ioport.h>
24#include <linux/mtd/mtd.h>
25#include <linux/mtd/partitions.h>
26
27#include <asm/types.h>
28#include <asm/setup.h>
29#include <asm/memory.h>
30#include <asm/mach-types.h>
31#include <asm/hardware.h>
32#include <asm/irq.h>
33#include <asm/sizes.h>
34
35#include <asm/mach/arch.h>
36#include <asm/mach/map.h>
37#include <asm/mach/irq.h>
38#include <asm/mach/flash.h>
39
40#include <asm/arch/pxa-regs.h>
41#include <asm/arch/mainstone.h>
42#include <asm/arch/audio.h>
43#include <asm/arch/pxafb.h>
44#include <asm/arch/mmc.h>
45#include <asm/arch/irda.h>
46#include <asm/arch/ohci.h>
47
48#include "generic.h"
49
50
51static unsigned long mainstone_irq_enabled;
52
53static void mainstone_mask_irq(unsigned int irq)
54{
55	int mainstone_irq = (irq - MAINSTONE_IRQ(0));
56	MST_INTMSKENA = (mainstone_irq_enabled &= ~(1 << mainstone_irq));
57}
58
59static void mainstone_unmask_irq(unsigned int irq)
60{
61	int mainstone_irq = (irq - MAINSTONE_IRQ(0));
62	/* the irq can be acknowledged only if deasserted, so it's done here */
63	MST_INTSETCLR &= ~(1 << mainstone_irq);
64	MST_INTMSKENA = (mainstone_irq_enabled |= (1 << mainstone_irq));
65}
66
67static struct irq_chip mainstone_irq_chip = {
68	.name		= "FPGA",
69	.ack		= mainstone_mask_irq,
70	.mask		= mainstone_mask_irq,
71	.unmask		= mainstone_unmask_irq,
72};
73
74static void mainstone_irq_handler(unsigned int irq, struct irq_desc *desc)
75{
76	unsigned long pending = MST_INTSETCLR & mainstone_irq_enabled;
77	do {
78		GEDR(0) = GPIO_bit(0);  /* clear useless edge notification */
79		if (likely(pending)) {
80			irq = MAINSTONE_IRQ(0) + __ffs(pending);
81			desc = irq_desc + irq;
82			desc_handle_irq(irq, desc);
83		}
84		pending = MST_INTSETCLR & mainstone_irq_enabled;
85	} while (pending);
86}
87
88static void __init mainstone_init_irq(void)
89{
90	int irq;
91
92	pxa_init_irq();
93
94	/* setup extra Mainstone irqs */
95	for(irq = MAINSTONE_IRQ(0); irq <= MAINSTONE_IRQ(15); irq++) {
96		set_irq_chip(irq, &mainstone_irq_chip);
97		set_irq_handler(irq, handle_level_irq);
98		if (irq == MAINSTONE_IRQ(10) || irq == MAINSTONE_IRQ(14))
99			set_irq_flags(irq, IRQF_VALID | IRQF_PROBE | IRQF_NOAUTOEN);
100		else
101			set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
102	}
103	set_irq_flags(MAINSTONE_IRQ(8), 0);
104	set_irq_flags(MAINSTONE_IRQ(12), 0);
105
106	MST_INTMSKENA = 0;
107	MST_INTSETCLR = 0;
108
109	set_irq_chained_handler(IRQ_GPIO(0), mainstone_irq_handler);
110	set_irq_type(IRQ_GPIO(0), IRQT_FALLING);
111}
112
113#ifdef CONFIG_PM
114
115static int mainstone_irq_resume(struct sys_device *dev)
116{
117	MST_INTMSKENA = mainstone_irq_enabled;
118	return 0;
119}
120
121static struct sysdev_class mainstone_irq_sysclass = {
122	set_kset_name("cpld_irq"),
123	.resume = mainstone_irq_resume,
124};
125
126static struct sys_device mainstone_irq_device = {
127	.cls = &mainstone_irq_sysclass,
128};
129
130static int __init mainstone_irq_device_init(void)
131{
132	int ret = sysdev_class_register(&mainstone_irq_sysclass);
133	if (ret == 0)
134		ret = sysdev_register(&mainstone_irq_device);
135	return ret;
136}
137
138device_initcall(mainstone_irq_device_init);
139
140#endif
141
142
143static struct resource smc91x_resources[] = {
144	[0] = {
145		.start	= (MST_ETH_PHYS + 0x300),
146		.end	= (MST_ETH_PHYS + 0xfffff),
147		.flags	= IORESOURCE_MEM,
148	},
149	[1] = {
150		.start	= MAINSTONE_IRQ(3),
151		.end	= MAINSTONE_IRQ(3),
152		.flags	= IORESOURCE_IRQ,
153	}
154};
155
156static struct platform_device smc91x_device = {
157	.name		= "smc91x",
158	.id		= 0,
159	.num_resources	= ARRAY_SIZE(smc91x_resources),
160	.resource	= smc91x_resources,
161};
162
163static int mst_audio_startup(struct snd_pcm_substream *substream, void *priv)
164{
165	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
166		MST_MSCWR2 &= ~MST_MSCWR2_AC97_SPKROFF;
167	return 0;
168}
169
170static void mst_audio_shutdown(struct snd_pcm_substream *substream, void *priv)
171{
172	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
173		MST_MSCWR2 |= MST_MSCWR2_AC97_SPKROFF;
174}
175
176static long mst_audio_suspend_mask;
177
178static void mst_audio_suspend(void *priv)
179{
180	mst_audio_suspend_mask = MST_MSCWR2;
181	MST_MSCWR2 |= MST_MSCWR2_AC97_SPKROFF;
182}
183
184static void mst_audio_resume(void *priv)
185{
186	MST_MSCWR2 &= mst_audio_suspend_mask | ~MST_MSCWR2_AC97_SPKROFF;
187}
188
189static pxa2xx_audio_ops_t mst_audio_ops = {
190	.startup	= mst_audio_startup,
191	.shutdown	= mst_audio_shutdown,
192	.suspend	= mst_audio_suspend,
193	.resume		= mst_audio_resume,
194};
195
196static struct platform_device mst_audio_device = {
197	.name		= "pxa2xx-ac97",
198	.id		= -1,
199	.dev		= { .platform_data = &mst_audio_ops },
200};
201
202static struct resource flash_resources[] = {
203	[0] = {
204		.start	= PXA_CS0_PHYS,
205		.end	= PXA_CS0_PHYS + SZ_64M - 1,
206		.flags	= IORESOURCE_MEM,
207	},
208	[1] = {
209		.start	= PXA_CS1_PHYS,
210		.end	= PXA_CS1_PHYS + SZ_64M - 1,
211		.flags	= IORESOURCE_MEM,
212	},
213};
214
215static struct mtd_partition mainstoneflash0_partitions[] = {
216	{
217		.name =		"Bootloader",
218		.size =		0x00040000,
219		.offset =	0,
220		.mask_flags =	MTD_WRITEABLE  /* force read-only */
221	},{
222		.name =		"Kernel",
223		.size =		0x00400000,
224		.offset =	0x00040000,
225	},{
226		.name =		"Filesystem",
227		.size =		MTDPART_SIZ_FULL,
228		.offset =	0x00440000
229	}
230};
231
232static struct flash_platform_data mst_flash_data[2] = {
233	{
234		.map_name	= "cfi_probe",
235		.parts		= mainstoneflash0_partitions,
236		.nr_parts	= ARRAY_SIZE(mainstoneflash0_partitions),
237	}, {
238		.map_name	= "cfi_probe",
239		.parts		= NULL,
240		.nr_parts	= 0,
241	}
242};
243
244static struct platform_device mst_flash_device[2] = {
245	{
246		.name		= "pxa2xx-flash",
247		.id		= 0,
248		.dev = {
249			.platform_data = &mst_flash_data[0],
250		},
251		.resource = &flash_resources[0],
252		.num_resources = 1,
253	},
254	{
255		.name		= "pxa2xx-flash",
256		.id		= 1,
257		.dev = {
258			.platform_data = &mst_flash_data[1],
259		},
260		.resource = &flash_resources[1],
261		.num_resources = 1,
262	},
263};
264
265static void mainstone_backlight_power(int on)
266{
267	if (on) {
268		pxa_gpio_mode(GPIO16_PWM0_MD);
269		pxa_set_cken(CKEN_PWM0, 1);
270		PWM_CTRL0 = 0;
271		PWM_PWDUTY0 = 0x3ff;
272		PWM_PERVAL0 = 0x3ff;
273	} else {
274		PWM_CTRL0 = 0;
275		PWM_PWDUTY0 = 0x0;
276		PWM_PERVAL0 = 0x3FF;
277		pxa_set_cken(CKEN_PWM0, 0);
278	}
279}
280
281static struct pxafb_mode_info toshiba_ltm04c380k_mode = {
282	.pixclock		= 50000,
283	.xres			= 640,
284	.yres			= 480,
285	.bpp			= 16,
286	.hsync_len		= 1,
287	.left_margin		= 0x9f,
288	.right_margin		= 1,
289	.vsync_len		= 44,
290	.upper_margin		= 0,
291	.lower_margin		= 0,
292	.sync			= FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
293};
294
295static struct pxafb_mode_info toshiba_ltm035a776c_mode = {
296	.pixclock		= 110000,
297	.xres			= 240,
298	.yres			= 320,
299	.bpp			= 16,
300	.hsync_len		= 4,
301	.left_margin		= 8,
302	.right_margin		= 20,
303	.vsync_len		= 3,
304	.upper_margin		= 1,
305	.lower_margin		= 10,
306	.sync			= FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
307};
308
309static struct pxafb_mach_info mainstone_pxafb_info = {
310	.num_modes      	= 1,
311	.lccr0			= LCCR0_Act,
312	.lccr3			= LCCR3_PCP,
313	.pxafb_backlight_power	= mainstone_backlight_power,
314};
315
316static int mainstone_mci_init(struct device *dev, irq_handler_t mstone_detect_int, void *data)
317{
318	int err;
319
320	/*
321	 * setup GPIO for PXA27x MMC controller
322	 */
323	pxa_gpio_mode(GPIO32_MMCCLK_MD);
324	pxa_gpio_mode(GPIO112_MMCCMD_MD);
325	pxa_gpio_mode(GPIO92_MMCDAT0_MD);
326	pxa_gpio_mode(GPIO109_MMCDAT1_MD);
327	pxa_gpio_mode(GPIO110_MMCDAT2_MD);
328	pxa_gpio_mode(GPIO111_MMCDAT3_MD);
329
330	/* make sure SD/Memory Stick multiplexer's signals
331	 * are routed to MMC controller
332	 */
333	MST_MSCWR1 &= ~MST_MSCWR1_MS_SEL;
334
335	err = request_irq(MAINSTONE_MMC_IRQ, mstone_detect_int, IRQF_DISABLED,
336			     "MMC card detect", data);
337	if (err) {
338		printk(KERN_ERR "mainstone_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
339		return -1;
340	}
341
342	return 0;
343}
344
345static void mainstone_mci_setpower(struct device *dev, unsigned int vdd)
346{
347	struct pxamci_platform_data* p_d = dev->platform_data;
348
349	if (( 1 << vdd) & p_d->ocr_mask) {
350		printk(KERN_DEBUG "%s: on\n", __FUNCTION__);
351		MST_MSCWR1 |= MST_MSCWR1_MMC_ON;
352		MST_MSCWR1 &= ~MST_MSCWR1_MS_SEL;
353	} else {
354		printk(KERN_DEBUG "%s: off\n", __FUNCTION__);
355		MST_MSCWR1 &= ~MST_MSCWR1_MMC_ON;
356	}
357}
358
359static void mainstone_mci_exit(struct device *dev, void *data)
360{
361	free_irq(MAINSTONE_MMC_IRQ, data);
362}
363
364static struct pxamci_platform_data mainstone_mci_platform_data = {
365	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
366	.init 		= mainstone_mci_init,
367	.setpower 	= mainstone_mci_setpower,
368	.exit		= mainstone_mci_exit,
369};
370
371static void mainstone_irda_transceiver_mode(struct device *dev, int mode)
372{
373	unsigned long flags;
374
375	local_irq_save(flags);
376	if (mode & IR_SIRMODE) {
377		MST_MSCWR1 &= ~MST_MSCWR1_IRDA_FIR;
378	} else if (mode & IR_FIRMODE) {
379		MST_MSCWR1 |= MST_MSCWR1_IRDA_FIR;
380	}
381	if (mode & IR_OFF) {
382		MST_MSCWR1 = (MST_MSCWR1 & ~MST_MSCWR1_IRDA_MASK) | MST_MSCWR1_IRDA_OFF;
383	} else {
384		MST_MSCWR1 = (MST_MSCWR1 & ~MST_MSCWR1_IRDA_MASK) | MST_MSCWR1_IRDA_FULL;
385	}
386	local_irq_restore(flags);
387}
388
389static struct pxaficp_platform_data mainstone_ficp_platform_data = {
390	.transceiver_cap  = IR_SIRMODE | IR_FIRMODE | IR_OFF,
391	.transceiver_mode = mainstone_irda_transceiver_mode,
392};
393
394static struct platform_device *platform_devices[] __initdata = {
395	&smc91x_device,
396	&mst_audio_device,
397	&mst_flash_device[0],
398	&mst_flash_device[1],
399};
400
401static int mainstone_ohci_init(struct device *dev)
402{
403	/* setup Port1 GPIO pin. */
404	pxa_gpio_mode( 88 | GPIO_ALT_FN_1_IN);	/* USBHPWR1 */
405	pxa_gpio_mode( 89 | GPIO_ALT_FN_2_OUT);	/* USBHPEN1 */
406
407	/* Set the Power Control Polarity Low and Power Sense
408	   Polarity Low to active low. */
409	UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) &
410		~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE);
411
412	return 0;
413}
414
415static struct pxaohci_platform_data mainstone_ohci_platform_data = {
416	.port_mode	= PMM_PERPORT_MODE,
417	.init		= mainstone_ohci_init,
418};
419
420static void __init mainstone_init(void)
421{
422	int SW7 = 0;
423
424	mst_flash_data[0].width = (BOOT_DEF & 1) ? 2 : 4;
425	mst_flash_data[1].width = 4;
426
427	/* Compensate for SW7 which swaps the flash banks */
428	mst_flash_data[SW7].name = "processor-flash";
429	mst_flash_data[SW7 ^ 1].name = "mainboard-flash";
430
431	printk(KERN_NOTICE "Mainstone configured to boot from %s\n",
432	       mst_flash_data[0].name);
433
434	/* system bus arbiter setting
435	 * - Core_Park
436	 * - LCD_wt:DMA_wt:CORE_Wt = 2:3:4
437	 */
438	ARB_CNTRL = ARB_CORE_PARK | 0x234;
439
440	/*
441	 * On Mainstone, we route AC97_SYSCLK via GPIO45 to
442	 * the audio daughter card
443	 */
444	pxa_gpio_mode(GPIO45_SYSCLK_AC97_MD);
445
446	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
447
448	/* reading Mainstone's "Virtual Configuration Register"
449	   might be handy to select LCD type here */
450	if (0)
451		mainstone_pxafb_info.modes = &toshiba_ltm04c380k_mode;
452	else
453		mainstone_pxafb_info.modes = &toshiba_ltm035a776c_mode;
454
455	set_pxa_fb_info(&mainstone_pxafb_info);
456
457	pxa_set_mci_info(&mainstone_mci_platform_data);
458	pxa_set_ficp_info(&mainstone_ficp_platform_data);
459	pxa_set_ohci_info(&mainstone_ohci_platform_data);
460}
461
462
463static struct map_desc mainstone_io_desc[] __initdata = {
464  	{	/* CPLD */
465		.virtual	=  MST_FPGA_VIRT,
466		.pfn		= __phys_to_pfn(MST_FPGA_PHYS),
467		.length		= 0x00100000,
468		.type		= MT_DEVICE
469	}
470};
471
472static void __init mainstone_map_io(void)
473{
474	pxa_map_io();
475	iotable_init(mainstone_io_desc, ARRAY_SIZE(mainstone_io_desc));
476
477	/* initialize sleep mode regs (wake-up sources, etc) */
478	PGSR0 = 0x00008800;
479	PGSR1 = 0x00000002;
480	PGSR2 = 0x0001FC00;
481	PGSR3 = 0x00001F81;
482	PWER  = 0xC0000002;
483	PRER  = 0x00000002;
484	PFER  = 0x00000002;
485 	/*	for use I SRAM as framebuffer.	*/
486 	PSLR |= 0xF04;
487 	PCFR = 0x66;
488 	/*	For Keypad wakeup.	*/
489 	KPC &=~KPC_ASACT;
490 	KPC |=KPC_AS;
491 	PKWR  = 0x000FD000;
492 	/*	Need read PKWR back after set it.	*/
493 	PKWR;
494}
495
496MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)")
497	/* Maintainer: MontaVista Software Inc. */
498	.phys_io	= 0x40000000,
499	.boot_params	= 0xa0000100,	/* BLOB boot parameter setting */
500	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
501	.map_io		= mainstone_map_io,
502	.init_irq	= mainstone_init_irq,
503	.timer		= &pxa_timer,
504	.init_machine	= mainstone_init,
505MACHINE_END
506