xref: /openbmc/linux/arch/arm/mach-sa1100/generic.c (revision 9a87ffc99ec8eb8d35eed7c4f816d75f5cc9662e)
1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds  * linux/arch/arm/mach-sa1100/generic.c
41da177e4SLinus Torvalds  *
51da177e4SLinus Torvalds  * Author: Nicolas Pitre
61da177e4SLinus Torvalds  *
71da177e4SLinus Torvalds  * Code common to all SA11x0 machines.
81da177e4SLinus Torvalds  */
92f8163baSRussell King #include <linux/gpio.h>
100920ca10SRussell King #include <linux/gpio/machine.h>
111da177e4SLinus Torvalds #include <linux/module.h>
121da177e4SLinus Torvalds #include <linux/kernel.h>
131da177e4SLinus Torvalds #include <linux/init.h>
141da177e4SLinus Torvalds #include <linux/delay.h>
157931d92fSRussell King #include <linux/dma-mapping.h>
161da177e4SLinus Torvalds #include <linux/pm.h>
171da177e4SLinus Torvalds #include <linux/cpufreq.h>
181da177e4SLinus Torvalds #include <linux/ioport.h>
19d052d1beSRussell King #include <linux/platform_device.h>
207b6d864bSRobin Holt #include <linux/reboot.h>
210920ca10SRussell King #include <linux/regulator/fixed.h>
220920ca10SRussell King #include <linux/regulator/machine.h>
2385e6f097SDmitry Eremin-Solenikov #include <linux/irqchip/irq-sa11x0.h>
241da177e4SLinus Torvalds 
25e1b7a72aSRussell King #include <video/sa1100fb.h>
26e1b7a72aSRussell King 
27982b465aSDmitry Eremin-Solenikov #include <soc/sa1100/pwer.h>
28982b465aSDmitry Eremin-Solenikov 
291da177e4SLinus Torvalds #include <asm/div64.h>
301da177e4SLinus Torvalds #include <asm/mach/map.h>
3114e66f76SRussell King #include <asm/mach/flash.h>
321da177e4SLinus Torvalds #include <asm/irq.h>
339f97da78SDavid Howells #include <asm/system_misc.h>
341da177e4SLinus Torvalds 
35f314f33bSRob Herring #include <mach/hardware.h>
36f314f33bSRob Herring #include <mach/irqs.h>
37da60626eSRussell King #include <mach/reset.h>
38f314f33bSRob Herring 
391da177e4SLinus Torvalds #include "generic.h"
407a8ca0a0SDmitry Eremin-Solenikov #include <clocksource/pxa.h>
411da177e4SLinus Torvalds 
421da177e4SLinus Torvalds #define NR_FREQS	16
431da177e4SLinus Torvalds 
441da177e4SLinus Torvalds /*
451da177e4SLinus Torvalds  * This table is setup for a 3.6864MHz Crystal.
461da177e4SLinus Torvalds  */
4722c8b4f1SViresh Kumar struct cpufreq_frequency_table sa11x0_freq_table[NR_FREQS+1] = {
4822c8b4f1SViresh Kumar 	{ .frequency = 59000,	/*  59.0 MHz */},
4922c8b4f1SViresh Kumar 	{ .frequency = 73700,	/*  73.7 MHz */},
5022c8b4f1SViresh Kumar 	{ .frequency = 88500,	/*  88.5 MHz */},
5122c8b4f1SViresh Kumar 	{ .frequency = 103200,	/* 103.2 MHz */},
5222c8b4f1SViresh Kumar 	{ .frequency = 118000,	/* 118.0 MHz */},
5322c8b4f1SViresh Kumar 	{ .frequency = 132700,	/* 132.7 MHz */},
5422c8b4f1SViresh Kumar 	{ .frequency = 147500,	/* 147.5 MHz */},
5522c8b4f1SViresh Kumar 	{ .frequency = 162200,	/* 162.2 MHz */},
5622c8b4f1SViresh Kumar 	{ .frequency = 176900,	/* 176.9 MHz */},
5722c8b4f1SViresh Kumar 	{ .frequency = 191700,	/* 191.7 MHz */},
5822c8b4f1SViresh Kumar 	{ .frequency = 206400,	/* 206.4 MHz */},
5922c8b4f1SViresh Kumar 	{ .frequency = 221200,	/* 221.2 MHz */},
6022c8b4f1SViresh Kumar 	{ .frequency = 235900,	/* 235.9 MHz */},
6122c8b4f1SViresh Kumar 	{ .frequency = 250700,	/* 250.7 MHz */},
6222c8b4f1SViresh Kumar 	{ .frequency = 265400,	/* 265.4 MHz */},
6322c8b4f1SViresh Kumar 	{ .frequency = 280200,	/* 280.2 MHz */},
6422c8b4f1SViresh Kumar 	{ .frequency = CPUFREQ_TABLE_END, },
651da177e4SLinus Torvalds };
661da177e4SLinus Torvalds 
sa11x0_getspeed(unsigned int cpu)671da177e4SLinus Torvalds unsigned int sa11x0_getspeed(unsigned int cpu)
681da177e4SLinus Torvalds {
691da177e4SLinus Torvalds 	if (cpu)
701da177e4SLinus Torvalds 		return 0;
7122c8b4f1SViresh Kumar 	return sa11x0_freq_table[PPCR & 0xf].frequency;
721da177e4SLinus Torvalds }
731da177e4SLinus Torvalds 
741da177e4SLinus Torvalds /*
751da177e4SLinus Torvalds  * Default power-off for SA1100
761da177e4SLinus Torvalds  */
sa1100_power_off(void)771da177e4SLinus Torvalds static void sa1100_power_off(void)
781da177e4SLinus Torvalds {
791da177e4SLinus Torvalds 	mdelay(100);
801da177e4SLinus Torvalds 	local_irq_disable();
811da177e4SLinus Torvalds 	/* disable internal oscillator, float CS lines */
821da177e4SLinus Torvalds 	PCFR = (PCFR_OPDE | PCFR_FP | PCFR_FS);
831da177e4SLinus Torvalds 	/* enable wake-up on GPIO0 (Assabet...) */
841da177e4SLinus Torvalds 	PWER = GFER = GRER = 1;
851da177e4SLinus Torvalds 	/*
861da177e4SLinus Torvalds 	 * set scratchpad to zero, just in case it is used as a
871da177e4SLinus Torvalds 	 * restart address by the bootloader.
881da177e4SLinus Torvalds 	 */
891da177e4SLinus Torvalds 	PSPR = 0;
901da177e4SLinus Torvalds 	/* enter sleep mode */
911da177e4SLinus Torvalds 	PMCR = PMCR_SF;
921da177e4SLinus Torvalds }
931da177e4SLinus Torvalds 
sa11x0_restart(enum reboot_mode mode,const char * cmd)947b6d864bSRobin Holt void sa11x0_restart(enum reboot_mode mode, const char *cmd)
95d9ca5839SRussell King {
96da60626eSRussell King 	clear_reset_status(RESET_STATUS_ALL);
97da60626eSRussell King 
987b6d864bSRobin Holt 	if (mode == REBOOT_SOFT) {
99d9ca5839SRussell King 		/* Jump into ROM at address 0 */
100d9ca5839SRussell King 		soft_restart(0);
101d9ca5839SRussell King 	} else {
102d9ca5839SRussell King 		/* Use on-chip reset capability */
103d9ca5839SRussell King 		RSRR = RSRR_SWR;
104d9ca5839SRussell King 	}
105d9ca5839SRussell King }
106d9ca5839SRussell King 
sa11x0_register_device(struct platform_device * dev,void * data)1077a5b4e16SRussell King static void sa11x0_register_device(struct platform_device *dev, void *data)
1087a5b4e16SRussell King {
1097a5b4e16SRussell King 	int err;
1107a5b4e16SRussell King 	dev->dev.platform_data = data;
1117a5b4e16SRussell King 	err = platform_device_register(dev);
1127a5b4e16SRussell King 	if (err)
1137a5b4e16SRussell King 		printk(KERN_ERR "Unable to register device %s: %d\n",
1147a5b4e16SRussell King 			dev->name, err);
1157a5b4e16SRussell King }
1167a5b4e16SRussell King 
1177a5b4e16SRussell King 
1181da177e4SLinus Torvalds static struct resource sa11x0udc_resources[] = {
119a181099eSRussell King 	[0] = DEFINE_RES_MEM(__PREG(Ser0UDCCR), SZ_64K),
120a181099eSRussell King 	[1] = DEFINE_RES_IRQ(IRQ_Ser0UDC),
1211da177e4SLinus Torvalds };
1221da177e4SLinus Torvalds 
1231da177e4SLinus Torvalds static u64 sa11x0udc_dma_mask = 0xffffffffUL;
1241da177e4SLinus Torvalds 
1251da177e4SLinus Torvalds static struct platform_device sa11x0udc_device = {
1261da177e4SLinus Torvalds 	.name		= "sa11x0-udc",
1271da177e4SLinus Torvalds 	.id		= -1,
1281da177e4SLinus Torvalds 	.dev		= {
1291da177e4SLinus Torvalds 		.dma_mask = &sa11x0udc_dma_mask,
1301da177e4SLinus Torvalds 		.coherent_dma_mask = 0xffffffff,
1311da177e4SLinus Torvalds 	},
1321da177e4SLinus Torvalds 	.num_resources	= ARRAY_SIZE(sa11x0udc_resources),
1331da177e4SLinus Torvalds 	.resource	= sa11x0udc_resources,
1341da177e4SLinus Torvalds };
1351da177e4SLinus Torvalds 
1361da177e4SLinus Torvalds static struct resource sa11x0uart1_resources[] = {
137a181099eSRussell King 	[0] = DEFINE_RES_MEM(__PREG(Ser1UTCR0), SZ_64K),
138a181099eSRussell King 	[1] = DEFINE_RES_IRQ(IRQ_Ser1UART),
1391da177e4SLinus Torvalds };
1401da177e4SLinus Torvalds 
1411da177e4SLinus Torvalds static struct platform_device sa11x0uart1_device = {
1421da177e4SLinus Torvalds 	.name		= "sa11x0-uart",
1431da177e4SLinus Torvalds 	.id		= 1,
1441da177e4SLinus Torvalds 	.num_resources	= ARRAY_SIZE(sa11x0uart1_resources),
1451da177e4SLinus Torvalds 	.resource	= sa11x0uart1_resources,
1461da177e4SLinus Torvalds };
1471da177e4SLinus Torvalds 
1481da177e4SLinus Torvalds static struct resource sa11x0uart3_resources[] = {
149a181099eSRussell King 	[0] = DEFINE_RES_MEM(__PREG(Ser3UTCR0), SZ_64K),
150a181099eSRussell King 	[1] = DEFINE_RES_IRQ(IRQ_Ser3UART),
1511da177e4SLinus Torvalds };
1521da177e4SLinus Torvalds 
1531da177e4SLinus Torvalds static struct platform_device sa11x0uart3_device = {
1541da177e4SLinus Torvalds 	.name		= "sa11x0-uart",
1551da177e4SLinus Torvalds 	.id		= 3,
1561da177e4SLinus Torvalds 	.num_resources	= ARRAY_SIZE(sa11x0uart3_resources),
1571da177e4SLinus Torvalds 	.resource	= sa11x0uart3_resources,
1581da177e4SLinus Torvalds };
1591da177e4SLinus Torvalds 
1601da177e4SLinus Torvalds static struct resource sa11x0mcp_resources[] = {
161a181099eSRussell King 	[0] = DEFINE_RES_MEM(__PREG(Ser4MCCR0), SZ_64K),
1627256ecc2SRussell King 	[1] = DEFINE_RES_MEM(__PREG(Ser4MCCR1), 4),
1637256ecc2SRussell King 	[2] = DEFINE_RES_IRQ(IRQ_Ser4MCP),
1641da177e4SLinus Torvalds };
1651da177e4SLinus Torvalds 
1661da177e4SLinus Torvalds static u64 sa11x0mcp_dma_mask = 0xffffffffUL;
1671da177e4SLinus Torvalds 
1681da177e4SLinus Torvalds static struct platform_device sa11x0mcp_device = {
1691da177e4SLinus Torvalds 	.name		= "sa11x0-mcp",
1701da177e4SLinus Torvalds 	.id		= -1,
1711da177e4SLinus Torvalds 	.dev = {
1721da177e4SLinus Torvalds 		.dma_mask = &sa11x0mcp_dma_mask,
1731da177e4SLinus Torvalds 		.coherent_dma_mask = 0xffffffff,
1741da177e4SLinus Torvalds 	},
1751da177e4SLinus Torvalds 	.num_resources	= ARRAY_SIZE(sa11x0mcp_resources),
1761da177e4SLinus Torvalds 	.resource	= sa11x0mcp_resources,
1771da177e4SLinus Torvalds };
1781da177e4SLinus Torvalds 
sa11x0_ppc_configure_mcp(void)179e36e26a8SRussell King void __init sa11x0_ppc_configure_mcp(void)
180e36e26a8SRussell King {
181e36e26a8SRussell King 	/* Setup the PPC unit for the MCP */
182e36e26a8SRussell King 	PPDR &= ~PPC_RXD4;
183e36e26a8SRussell King 	PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
184e36e26a8SRussell King 	PSDR |= PPC_RXD4;
185e36e26a8SRussell King 	PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
186e36e26a8SRussell King 	PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
187e36e26a8SRussell King }
188e36e26a8SRussell King 
sa11x0_register_mcp(struct mcp_plat_data * data)1897a5b4e16SRussell King void sa11x0_register_mcp(struct mcp_plat_data *data)
190323cdfc1SRussell King {
1917a5b4e16SRussell King 	sa11x0_register_device(&sa11x0mcp_device, data);
192323cdfc1SRussell King }
193323cdfc1SRussell King 
1941da177e4SLinus Torvalds static struct resource sa11x0ssp_resources[] = {
195a181099eSRussell King 	[0] = DEFINE_RES_MEM(0x80070000, SZ_64K),
196a181099eSRussell King 	[1] = DEFINE_RES_IRQ(IRQ_Ser4SSP),
1971da177e4SLinus Torvalds };
1981da177e4SLinus Torvalds 
1991da177e4SLinus Torvalds static u64 sa11x0ssp_dma_mask = 0xffffffffUL;
2001da177e4SLinus Torvalds 
2011da177e4SLinus Torvalds static struct platform_device sa11x0ssp_device = {
2021da177e4SLinus Torvalds 	.name		= "sa11x0-ssp",
2031da177e4SLinus Torvalds 	.id		= -1,
2041da177e4SLinus Torvalds 	.dev = {
2051da177e4SLinus Torvalds 		.dma_mask = &sa11x0ssp_dma_mask,
2061da177e4SLinus Torvalds 		.coherent_dma_mask = 0xffffffff,
2071da177e4SLinus Torvalds 	},
2081da177e4SLinus Torvalds 	.num_resources	= ARRAY_SIZE(sa11x0ssp_resources),
2091da177e4SLinus Torvalds 	.resource	= sa11x0ssp_resources,
2101da177e4SLinus Torvalds };
2111da177e4SLinus Torvalds 
2121da177e4SLinus Torvalds static struct resource sa11x0fb_resources[] = {
213a181099eSRussell King 	[0] = DEFINE_RES_MEM(0xb0100000, SZ_64K),
214a181099eSRussell King 	[1] = DEFINE_RES_IRQ(IRQ_LCD),
2151da177e4SLinus Torvalds };
2161da177e4SLinus Torvalds 
2171da177e4SLinus Torvalds static struct platform_device sa11x0fb_device = {
2181da177e4SLinus Torvalds 	.name		= "sa11x0-fb",
2191da177e4SLinus Torvalds 	.id		= -1,
2201da177e4SLinus Torvalds 	.dev = {
2211da177e4SLinus Torvalds 		.coherent_dma_mask = 0xffffffff,
2221da177e4SLinus Torvalds 	},
2231da177e4SLinus Torvalds 	.num_resources	= ARRAY_SIZE(sa11x0fb_resources),
2241da177e4SLinus Torvalds 	.resource	= sa11x0fb_resources,
2251da177e4SLinus Torvalds };
2261da177e4SLinus Torvalds 
sa11x0_register_lcd(struct sa1100fb_mach_info * inf)227e1b7a72aSRussell King void sa11x0_register_lcd(struct sa1100fb_mach_info *inf)
228e1b7a72aSRussell King {
229e1b7a72aSRussell King 	sa11x0_register_device(&sa11x0fb_device, inf);
230e1b7a72aSRussell King }
231e1b7a72aSRussell King 
sa11x0_register_pcmcia(int socket,struct gpiod_lookup_table * table)2320920ca10SRussell King void sa11x0_register_pcmcia(int socket, struct gpiod_lookup_table *table)
2330920ca10SRussell King {
2340920ca10SRussell King 	if (table)
2350920ca10SRussell King 		gpiod_add_lookup_table(table);
2360920ca10SRussell King 	platform_device_register_simple("sa11x0-pcmcia", socket, NULL, 0);
2370920ca10SRussell King }
2380920ca10SRussell King 
2391da177e4SLinus Torvalds static struct platform_device sa11x0mtd_device = {
240bcc8f3e0SUwe Kleine-König 	.name		= "sa1100-mtd",
2411da177e4SLinus Torvalds 	.id		= -1,
2421da177e4SLinus Torvalds };
2431da177e4SLinus Torvalds 
sa11x0_register_mtd(struct flash_platform_data * flash,struct resource * res,int nr)2447a5b4e16SRussell King void sa11x0_register_mtd(struct flash_platform_data *flash,
2451da177e4SLinus Torvalds 			 struct resource *res, int nr)
2461da177e4SLinus Torvalds {
24714e66f76SRussell King 	flash->name = "sa1100";
2481da177e4SLinus Torvalds 	sa11x0mtd_device.resource = res;
2491da177e4SLinus Torvalds 	sa11x0mtd_device.num_resources = nr;
2507a5b4e16SRussell King 	sa11x0_register_device(&sa11x0mtd_device, flash);
2511da177e4SLinus Torvalds }
2521da177e4SLinus Torvalds 
2533888c090SHaojian Zhuang static struct resource sa1100_rtc_resources[] = {
2549f9d27e3SDmitry Artamonow 	DEFINE_RES_MEM(0x90010000, 0x40),
2553888c090SHaojian Zhuang 	DEFINE_RES_IRQ_NAMED(IRQ_RTC1Hz, "rtc 1Hz"),
2563888c090SHaojian Zhuang 	DEFINE_RES_IRQ_NAMED(IRQ_RTCAlrm, "rtc alarm"),
2573888c090SHaojian Zhuang };
2583888c090SHaojian Zhuang 
259e842f1c8SRichard Purdie static struct platform_device sa11x0rtc_device = {
260e842f1c8SRichard Purdie 	.name		= "sa1100-rtc",
261e842f1c8SRichard Purdie 	.id		= -1,
2623888c090SHaojian Zhuang 	.num_resources	= ARRAY_SIZE(sa1100_rtc_resources),
2633888c090SHaojian Zhuang 	.resource	= sa1100_rtc_resources,
264e842f1c8SRichard Purdie };
265e842f1c8SRichard Purdie 
2667931d92fSRussell King static struct resource sa11x0dma_resources[] = {
267c2132010SRussell King 	DEFINE_RES_MEM(DMA_PHYS, DMA_SIZE),
2687931d92fSRussell King 	DEFINE_RES_IRQ(IRQ_DMA0),
2697931d92fSRussell King 	DEFINE_RES_IRQ(IRQ_DMA1),
2707931d92fSRussell King 	DEFINE_RES_IRQ(IRQ_DMA2),
2717931d92fSRussell King 	DEFINE_RES_IRQ(IRQ_DMA3),
2727931d92fSRussell King 	DEFINE_RES_IRQ(IRQ_DMA4),
2737931d92fSRussell King 	DEFINE_RES_IRQ(IRQ_DMA5),
2747931d92fSRussell King };
2757931d92fSRussell King 
2767931d92fSRussell King static u64 sa11x0dma_dma_mask = DMA_BIT_MASK(32);
2777931d92fSRussell King 
2787931d92fSRussell King static struct platform_device sa11x0dma_device = {
2797931d92fSRussell King 	.name		= "sa11x0-dma",
2807931d92fSRussell King 	.id		= -1,
2817931d92fSRussell King 	.dev = {
2827931d92fSRussell King 		.dma_mask = &sa11x0dma_dma_mask,
2837931d92fSRussell King 		.coherent_dma_mask = 0xffffffff,
2847931d92fSRussell King 	},
2857931d92fSRussell King 	.num_resources	= ARRAY_SIZE(sa11x0dma_resources),
2867931d92fSRussell King 	.resource	= sa11x0dma_resources,
2877931d92fSRussell King };
2887931d92fSRussell King 
2891da177e4SLinus Torvalds static struct platform_device *sa11x0_devices[] __initdata = {
2901da177e4SLinus Torvalds 	&sa11x0udc_device,
2911da177e4SLinus Torvalds 	&sa11x0uart1_device,
2921da177e4SLinus Torvalds 	&sa11x0uart3_device,
2931da177e4SLinus Torvalds 	&sa11x0ssp_device,
294e842f1c8SRichard Purdie 	&sa11x0rtc_device,
2957931d92fSRussell King 	&sa11x0dma_device,
2961da177e4SLinus Torvalds };
2971da177e4SLinus Torvalds 
sa1100_init(void)2981da177e4SLinus Torvalds static int __init sa1100_init(void)
2991da177e4SLinus Torvalds {
300*e86bd43bSArnd Bergmann 	struct resource wdt_res = DEFINE_RES_MEM(0x90000000, 0x20);
3011da177e4SLinus Torvalds 	pm_power_off = sa1100_power_off;
3020920ca10SRussell King 
3030920ca10SRussell King 	regulator_has_full_constraints();
3040920ca10SRussell King 
305*e86bd43bSArnd Bergmann 	platform_device_register_simple("sa1100_wdt", -1, &wdt_res, 1);
306*e86bd43bSArnd Bergmann 
3071da177e4SLinus Torvalds 	return platform_add_devices(sa11x0_devices, ARRAY_SIZE(sa11x0_devices));
3081da177e4SLinus Torvalds }
3091da177e4SLinus Torvalds 
3101da177e4SLinus Torvalds arch_initcall(sa1100_init);
3111da177e4SLinus Torvalds 
sa11x0_init_late(void)3127fea1ba5SShawn Guo void __init sa11x0_init_late(void)
3137fea1ba5SShawn Guo {
3147fea1ba5SShawn Guo 	sa11x0_pm_init();
3157fea1ba5SShawn Guo }
3161da177e4SLinus Torvalds 
sa11x0_register_fixed_regulator(int n,struct fixed_voltage_config * cfg,struct regulator_consumer_supply * supplies,unsigned num_supplies,bool uses_gpio)3170920ca10SRussell King int __init sa11x0_register_fixed_regulator(int n,
3180920ca10SRussell King 	struct fixed_voltage_config *cfg,
319efdfeb07SLinus Walleij 	struct regulator_consumer_supply *supplies, unsigned num_supplies,
320efdfeb07SLinus Walleij 	bool uses_gpio)
3210920ca10SRussell King {
3220920ca10SRussell King 	struct regulator_init_data *id;
3230920ca10SRussell King 
3240920ca10SRussell King 	cfg->init_data = id = kzalloc(sizeof(*cfg->init_data), GFP_KERNEL);
3250920ca10SRussell King 	if (!cfg->init_data)
3260920ca10SRussell King 		return -ENOMEM;
3270920ca10SRussell King 
328efdfeb07SLinus Walleij 	if (!uses_gpio)
3290920ca10SRussell King 		id->constraints.always_on = 1;
3300920ca10SRussell King 	id->constraints.name = cfg->supply_name;
3310920ca10SRussell King 	id->constraints.min_uV = cfg->microvolts;
3320920ca10SRussell King 	id->constraints.max_uV = cfg->microvolts;
3330920ca10SRussell King 	id->constraints.valid_modes_mask = REGULATOR_MODE_NORMAL;
3340920ca10SRussell King 	id->constraints.valid_ops_mask = REGULATOR_CHANGE_STATUS;
3350920ca10SRussell King 	id->consumer_supplies = supplies;
3360920ca10SRussell King 	id->num_consumer_supplies = num_supplies;
3370920ca10SRussell King 
3380920ca10SRussell King 	platform_device_register_resndata(NULL, "reg-fixed-voltage", n,
3390920ca10SRussell King 					  NULL, 0, cfg, sizeof(*cfg));
3400920ca10SRussell King 	return 0;
3410920ca10SRussell King }
3420920ca10SRussell King 
3431da177e4SLinus Torvalds /*
3441da177e4SLinus Torvalds  * Common I/O mapping:
3451da177e4SLinus Torvalds  *
3461da177e4SLinus Torvalds  * Typically, static virtual address mappings are as follow:
3471da177e4SLinus Torvalds  *
3481da177e4SLinus Torvalds  * 0xf0000000-0xf3ffffff:	miscellaneous stuff (CPLDs, etc.)
3491da177e4SLinus Torvalds  * 0xf4000000-0xf4ffffff:	SA-1111
3501da177e4SLinus Torvalds  * 0xf5000000-0xf5ffffff:	reserved (used by cache flushing area)
3511da177e4SLinus Torvalds  * 0xf6000000-0xfffeffff:	reserved (internal SA1100 IO defined above)
3521da177e4SLinus Torvalds  * 0xffff0000-0xffff0fff:	SA1100 exception vectors
3531da177e4SLinus Torvalds  * 0xffff2000-0xffff2fff:	Minicache copy_user_page area
3541da177e4SLinus Torvalds  *
3551da177e4SLinus Torvalds  * Below 0xe8000000 is reserved for vm allocation.
3561da177e4SLinus Torvalds  *
3571da177e4SLinus Torvalds  * The machine specific code must provide the extra mapping beside the
3581da177e4SLinus Torvalds  * default mapping provided here.
3591da177e4SLinus Torvalds  */
3601da177e4SLinus Torvalds 
3611da177e4SLinus Torvalds static struct map_desc standard_io_desc[] __initdata = {
36292519d82SDeepak Saxena 	{	/* PCM */
36392519d82SDeepak Saxena 		.virtual	=  0xf8000000,
36492519d82SDeepak Saxena 		.pfn		= __phys_to_pfn(0x80000000),
36592519d82SDeepak Saxena 		.length		= 0x00100000,
36692519d82SDeepak Saxena 		.type		= MT_DEVICE
36792519d82SDeepak Saxena 	}, {	/* SCM */
36892519d82SDeepak Saxena 		.virtual	=  0xfa000000,
36992519d82SDeepak Saxena 		.pfn		= __phys_to_pfn(0x90000000),
37092519d82SDeepak Saxena 		.length		= 0x00100000,
37192519d82SDeepak Saxena 		.type		= MT_DEVICE
37292519d82SDeepak Saxena 	}, {	/* MER */
37392519d82SDeepak Saxena 		.virtual	=  0xfc000000,
37492519d82SDeepak Saxena 		.pfn		= __phys_to_pfn(0xa0000000),
37592519d82SDeepak Saxena 		.length		= 0x00100000,
37692519d82SDeepak Saxena 		.type		= MT_DEVICE
37792519d82SDeepak Saxena 	}, {	/* LCD + DMA */
37892519d82SDeepak Saxena 		.virtual	=  0xfe000000,
37992519d82SDeepak Saxena 		.pfn		= __phys_to_pfn(0xb0000000),
38092519d82SDeepak Saxena 		.length		= 0x00200000,
38192519d82SDeepak Saxena 		.type		= MT_DEVICE
38292519d82SDeepak Saxena 	},
3831da177e4SLinus Torvalds };
3841da177e4SLinus Torvalds 
sa1100_map_io(void)3851da177e4SLinus Torvalds void __init sa1100_map_io(void)
3861da177e4SLinus Torvalds {
3871da177e4SLinus Torvalds 	iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));
3881da177e4SLinus Torvalds }
3891da177e4SLinus Torvalds 
sa1100_timer_init(void)3907a8ca0a0SDmitry Eremin-Solenikov void __init sa1100_timer_init(void)
3917a8ca0a0SDmitry Eremin-Solenikov {
392f4e14edfSRobert Jarzmik 	pxa_timer_nodt_init(IRQ_OST0, io_p2v(0x90000000));
3937a8ca0a0SDmitry Eremin-Solenikov }
3947a8ca0a0SDmitry Eremin-Solenikov 
39585e6f097SDmitry Eremin-Solenikov static struct resource irq_resource =
39685e6f097SDmitry Eremin-Solenikov 	DEFINE_RES_MEM_NAMED(0x90050000, SZ_64K, "irqs");
39785e6f097SDmitry Eremin-Solenikov 
sa1100_init_irq(void)39885e6f097SDmitry Eremin-Solenikov void __init sa1100_init_irq(void)
39985e6f097SDmitry Eremin-Solenikov {
40085e6f097SDmitry Eremin-Solenikov 	request_resource(&iomem_resource, &irq_resource);
40185e6f097SDmitry Eremin-Solenikov 
40285e6f097SDmitry Eremin-Solenikov 	sa11x0_init_irq_nodt(IRQ_GPIO0_SC, irq_resource.start);
40385e6f097SDmitry Eremin-Solenikov 
40485e6f097SDmitry Eremin-Solenikov 	sa1100_init_gpio();
405198b51e8SRussell King 	sa11xx_clk_init();
40685e6f097SDmitry Eremin-Solenikov }
40785e6f097SDmitry Eremin-Solenikov 
4081da177e4SLinus Torvalds /*
4091da177e4SLinus Torvalds  * Disable the memory bus request/grant signals on the SA1110 to
4101da177e4SLinus Torvalds  * ensure that we don't receive spurious memory requests.  We set
4111da177e4SLinus Torvalds  * the MBGNT signal false to ensure the SA1111 doesn't own the
4121da177e4SLinus Torvalds  * SDRAM bus.
4131da177e4SLinus Torvalds  */
sa1110_mb_disable(void)41480ea2065SRussell King void sa1110_mb_disable(void)
4151da177e4SLinus Torvalds {
4161da177e4SLinus Torvalds 	unsigned long flags;
4171da177e4SLinus Torvalds 
4181da177e4SLinus Torvalds 	local_irq_save(flags);
4191da177e4SLinus Torvalds 
4201da177e4SLinus Torvalds 	PGSR &= ~GPIO_MBGNT;
4211da177e4SLinus Torvalds 	GPCR = GPIO_MBGNT;
4221da177e4SLinus Torvalds 	GPDR = (GPDR & ~GPIO_MBREQ) | GPIO_MBGNT;
4231da177e4SLinus Torvalds 
4241da177e4SLinus Torvalds 	GAFR &= ~(GPIO_MBGNT | GPIO_MBREQ);
4251da177e4SLinus Torvalds 
4261da177e4SLinus Torvalds 	local_irq_restore(flags);
4271da177e4SLinus Torvalds }
4281da177e4SLinus Torvalds 
4291da177e4SLinus Torvalds /*
4301da177e4SLinus Torvalds  * If the system is going to use the SA-1111 DMA engines, set up
4311da177e4SLinus Torvalds  * the memory bus request/grant pins.
4321da177e4SLinus Torvalds  */
sa1110_mb_enable(void)43380ea2065SRussell King void sa1110_mb_enable(void)
4341da177e4SLinus Torvalds {
4351da177e4SLinus Torvalds 	unsigned long flags;
4361da177e4SLinus Torvalds 
4371da177e4SLinus Torvalds 	local_irq_save(flags);
4381da177e4SLinus Torvalds 
4391da177e4SLinus Torvalds 	PGSR &= ~GPIO_MBGNT;
4401da177e4SLinus Torvalds 	GPCR = GPIO_MBGNT;
4411da177e4SLinus Torvalds 	GPDR = (GPDR & ~GPIO_MBREQ) | GPIO_MBGNT;
4421da177e4SLinus Torvalds 
4431da177e4SLinus Torvalds 	GAFR |= (GPIO_MBGNT | GPIO_MBREQ);
4441da177e4SLinus Torvalds 	TUCR |= TUCR_MR;
4451da177e4SLinus Torvalds 
4461da177e4SLinus Torvalds 	local_irq_restore(flags);
4471da177e4SLinus Torvalds }
4481da177e4SLinus Torvalds 
sa11x0_gpio_set_wake(unsigned int gpio,unsigned int on)449982b465aSDmitry Eremin-Solenikov int sa11x0_gpio_set_wake(unsigned int gpio, unsigned int on)
450982b465aSDmitry Eremin-Solenikov {
451982b465aSDmitry Eremin-Solenikov 	if (on)
452982b465aSDmitry Eremin-Solenikov 		PWER |= BIT(gpio);
453982b465aSDmitry Eremin-Solenikov 	else
454982b465aSDmitry Eremin-Solenikov 		PWER &= ~BIT(gpio);
455982b465aSDmitry Eremin-Solenikov 
456982b465aSDmitry Eremin-Solenikov 	return 0;
457982b465aSDmitry Eremin-Solenikov }
458982b465aSDmitry Eremin-Solenikov 
sa11x0_sc_set_wake(unsigned int irq,unsigned int on)459982b465aSDmitry Eremin-Solenikov int sa11x0_sc_set_wake(unsigned int irq, unsigned int on)
460982b465aSDmitry Eremin-Solenikov {
461982b465aSDmitry Eremin-Solenikov 	if (BIT(irq) != IC_RTCAlrm)
462982b465aSDmitry Eremin-Solenikov 		return -EINVAL;
463982b465aSDmitry Eremin-Solenikov 
464982b465aSDmitry Eremin-Solenikov 	if (on)
465982b465aSDmitry Eremin-Solenikov 		PWER |= PWER_RTC;
466982b465aSDmitry Eremin-Solenikov 	else
467982b465aSDmitry Eremin-Solenikov 		PWER &= ~PWER_RTC;
468982b465aSDmitry Eremin-Solenikov 
469982b465aSDmitry Eremin-Solenikov 	return 0;
470982b465aSDmitry Eremin-Solenikov }
471