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