diff options
Diffstat (limited to 'arch/arm/mach-vexpress/v2m.c')
| -rw-r--r-- | arch/arm/mach-vexpress/v2m.c | 365 |
1 files changed, 189 insertions, 176 deletions
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c index 1edae65a0e7..6ff681a24ba 100644 --- a/arch/arm/mach-vexpress/v2m.c +++ b/arch/arm/mach-vexpress/v2m.c @@ -5,25 +5,37 @@ #include <linux/amba/bus.h> #include <linux/amba/mmci.h> #include <linux/io.h> +#include <linux/smp.h> #include <linux/init.h> +#include <linux/of_address.h> +#include <linux/of_fdt.h> +#include <linux/of_irq.h> +#include <linux/of_platform.h> #include <linux/platform_device.h> +#include <linux/ata_platform.h> #include <linux/smsc911x.h> #include <linux/spinlock.h> -#include <linux/sysdev.h> #include <linux/usb/isp1760.h> +#include <linux/mtd/physmap.h> +#include <linux/regulator/fixed.h> +#include <linux/regulator/machine.h> +#include <linux/vexpress.h> #include <linux/clkdev.h> +#include <asm/mach-types.h> #include <asm/sizes.h> -#include <asm/mach/flash.h> +#include <asm/mach/arch.h> #include <asm/mach/map.h> #include <asm/mach/time.h> #include <asm/hardware/arm_timer.h> +#include <asm/hardware/cache-l2x0.h> #include <asm/hardware/timer-sp.h> -#include <asm/hardware/sp810.h> +#include <mach/ct-ca9x4.h> #include <mach/motherboard.h> #include <plat/sched_clock.h> +#include <plat/platsmp.h> #include "core.h" @@ -35,91 +47,20 @@ static struct map_desc v2m_io_desc[] __initdata = { { - .virtual = __MMIO_P2V(V2M_PA_CS7), + .virtual = V2M_PERIPH, .pfn = __phys_to_pfn(V2M_PA_CS7), .length = SZ_128K, .type = MT_DEVICE, }, }; -void __init v2m_map_io(struct map_desc *tile, size_t num) +static void __init v2m_sp804_init(void __iomem *base, unsigned int irq) { - iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc)); - iotable_init(tile, num); -} - - -static void __init v2m_timer_init(void) -{ - u32 scctrl; - - versatile_sched_clock_init(MMIO_P2V(V2M_SYS_24MHZ), 24000000); - - /* Select 1MHz TIMCLK as the reference clock for SP804 timers */ - scctrl = readl(MMIO_P2V(V2M_SYSCTL + SCCTRL)); - scctrl |= SCCTRL_TIMEREN0SEL_TIMCLK; - scctrl |= SCCTRL_TIMEREN1SEL_TIMCLK; - writel(scctrl, MMIO_P2V(V2M_SYSCTL + SCCTRL)); - - writel(0, MMIO_P2V(V2M_TIMER0) + TIMER_CTRL); - writel(0, MMIO_P2V(V2M_TIMER1) + TIMER_CTRL); - - sp804_clocksource_init(MMIO_P2V(V2M_TIMER1)); - sp804_clockevents_init(MMIO_P2V(V2M_TIMER0), IRQ_V2M_TIMER0); -} - -struct sys_timer v2m_timer = { - .init = v2m_timer_init, -}; - - -static DEFINE_SPINLOCK(v2m_cfg_lock); - -int v2m_cfg_write(u32 devfn, u32 data) -{ - /* Configuration interface broken? */ - u32 val; - - printk("%s: writing %08x to %08x\n", __func__, data, devfn); - - devfn |= SYS_CFG_START | SYS_CFG_WRITE; - - spin_lock(&v2m_cfg_lock); - val = readl(MMIO_P2V(V2M_SYS_CFGSTAT)); - writel(val & ~SYS_CFG_COMPLETE, MMIO_P2V(V2M_SYS_CFGSTAT)); - - writel(data, MMIO_P2V(V2M_SYS_CFGDATA)); - writel(devfn, MMIO_P2V(V2M_SYS_CFGCTRL)); - - do { - val = readl(MMIO_P2V(V2M_SYS_CFGSTAT)); - } while (val == 0); - spin_unlock(&v2m_cfg_lock); - - return !!(val & SYS_CFG_ERR); -} + if (WARN_ON(!base || irq == NO_IRQ)) + return; -int v2m_cfg_read(u32 devfn, u32 *data) -{ - u32 val; - - devfn |= SYS_CFG_START; - - spin_lock(&v2m_cfg_lock); - writel(0, MMIO_P2V(V2M_SYS_CFGSTAT)); - writel(devfn, MMIO_P2V(V2M_SYS_CFGCTRL)); - - mb(); - - do { - cpu_relax(); - val = readl(MMIO_P2V(V2M_SYS_CFGSTAT)); - } while (val == 0); - - *data = readl(MMIO_P2V(V2M_SYS_CFGDATA)); - spin_unlock(&v2m_cfg_lock); - - return !!(val & SYS_CFG_ERR); + sp804_clocksource_init(base + TIMER_2_BASE, "v2m-timer1"); + sp804_clockevents_init(base + TIMER_1_BASE, irq, "v2m-timer0"); } @@ -176,6 +117,11 @@ static struct platform_device v2m_eth_device = { .dev.platform_data = &v2m_eth_config, }; +static struct regulator_consumer_supply v2m_eth_supplies[] = { + REGULATOR_SUPPLY("vddvario", "smsc911x"), + REGULATOR_SUPPLY("vdd33a", "smsc911x"), +}; + static struct resource v2m_usb_resources[] = { { .start = V2M_ISP1761, @@ -205,28 +151,8 @@ static struct platform_device v2m_usb_device = { .dev.platform_data = &v2m_usb_config, }; -static int v2m_flash_init(void) -{ - writel(0, MMIO_P2V(V2M_SYS_FLASH)); - return 0; -} - -static void v2m_flash_exit(void) -{ - writel(0, MMIO_P2V(V2M_SYS_FLASH)); -} - -static void v2m_flash_set_vpp(int on) -{ - writel(on != 0, MMIO_P2V(V2M_SYS_FLASH)); -} - -static struct flash_platform_data v2m_flash_data = { - .map_name = "cfi_probe", +static struct physmap_flash_data v2m_flash_data = { .width = 4, - .init = v2m_flash_init, - .exit = v2m_flash_exit, - .set_vpp = v2m_flash_set_vpp, }; static struct resource v2m_flash_resources[] = { @@ -242,34 +168,105 @@ static struct resource v2m_flash_resources[] = { }; static struct platform_device v2m_flash_device = { - .name = "armflash", + .name = "physmap-flash", .id = -1, .resource = v2m_flash_resources, .num_resources = ARRAY_SIZE(v2m_flash_resources), .dev.platform_data = &v2m_flash_data, }; +static struct pata_platform_info v2m_pata_data = { + .ioport_shift = 2, +}; -static unsigned int v2m_mmci_status(struct device *dev) -{ - return readl(MMIO_P2V(V2M_SYS_MCI)) & (1 << 0); -} +static struct resource v2m_pata_resources[] = { + { + .start = V2M_CF, + .end = V2M_CF + 0xff, + .flags = IORESOURCE_MEM, + }, { + .start = V2M_CF + 0x100, + .end = V2M_CF + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device v2m_cf_device = { + .name = "pata_platform", + .id = -1, + .resource = v2m_pata_resources, + .num_resources = ARRAY_SIZE(v2m_pata_resources), + .dev.platform_data = &v2m_pata_data, +}; static struct mmci_platform_data v2m_mmci_data = { .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, - .status = v2m_mmci_status, + .status = vexpress_get_mci_cardin, + .gpio_cd = -1, + .gpio_wp = -1, +}; + +static struct resource v2m_sysreg_resources[] = { + { + .start = V2M_SYSREGS, + .end = V2M_SYSREGS + 0xfff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device v2m_sysreg_device = { + .name = "vexpress-sysreg", + .id = -1, + .resource = v2m_sysreg_resources, + .num_resources = ARRAY_SIZE(v2m_sysreg_resources), +}; + +static struct platform_device v2m_muxfpga_device = { + .name = "vexpress-muxfpga", + .id = 0, + .num_resources = 1, + .resource = (struct resource []) { + VEXPRESS_RES_FUNC(0, 7), + } +}; + +static struct platform_device v2m_shutdown_device = { + .name = "vexpress-shutdown", + .id = 0, + .num_resources = 1, + .resource = (struct resource []) { + VEXPRESS_RES_FUNC(0, 8), + } +}; + +static struct platform_device v2m_reboot_device = { + .name = "vexpress-reboot", + .id = 0, + .num_resources = 1, + .resource = (struct resource []) { + VEXPRESS_RES_FUNC(0, 9), + } +}; + +static struct platform_device v2m_dvimode_device = { + .name = "vexpress-dvimode", + .id = 0, + .num_resources = 1, + .resource = (struct resource []) { + VEXPRESS_RES_FUNC(0, 11), + } }; -static AMBA_DEVICE(aaci, "mb:aaci", V2M_AACI, NULL); -static AMBA_DEVICE(mmci, "mb:mmci", V2M_MMCI, &v2m_mmci_data); -static AMBA_DEVICE(kmi0, "mb:kmi0", V2M_KMI0, NULL); -static AMBA_DEVICE(kmi1, "mb:kmi1", V2M_KMI1, NULL); -static AMBA_DEVICE(uart0, "mb:uart0", V2M_UART0, NULL); -static AMBA_DEVICE(uart1, "mb:uart1", V2M_UART1, NULL); -static AMBA_DEVICE(uart2, "mb:uart2", V2M_UART2, NULL); -static AMBA_DEVICE(uart3, "mb:uart3", V2M_UART3, NULL); -static AMBA_DEVICE(wdt, "mb:wdt", V2M_WDT, NULL); -static AMBA_DEVICE(rtc, "mb:rtc", V2M_RTC, NULL); +static AMBA_APB_DEVICE(aaci, "mb:aaci", 0, V2M_AACI, IRQ_V2M_AACI, NULL); +static AMBA_APB_DEVICE(mmci, "mb:mmci", 0, V2M_MMCI, IRQ_V2M_MMCI, &v2m_mmci_data); +static AMBA_APB_DEVICE(kmi0, "mb:kmi0", 0, V2M_KMI0, IRQ_V2M_KMI0, NULL); +static AMBA_APB_DEVICE(kmi1, "mb:kmi1", 0, V2M_KMI1, IRQ_V2M_KMI1, NULL); +static AMBA_APB_DEVICE(uart0, "mb:uart0", 0, V2M_UART0, IRQ_V2M_UART0, NULL); +static AMBA_APB_DEVICE(uart1, "mb:uart1", 0, V2M_UART1, IRQ_V2M_UART1, NULL); +static AMBA_APB_DEVICE(uart2, "mb:uart2", 0, V2M_UART2, IRQ_V2M_UART2, NULL); +static AMBA_APB_DEVICE(uart3, "mb:uart3", 0, V2M_UART3, IRQ_V2M_UART3, NULL); +static AMBA_APB_DEVICE(wdt, "mb:wdt", 0, V2M_WDT, IRQ_V2M_WDT, NULL); +static AMBA_APB_DEVICE(rtc, "mb:rtc", 0, V2M_RTC, IRQ_V2M_RTC, NULL); static struct amba_device *v2m_amba_devs[] __initdata = { &aaci_device, @@ -284,94 +281,110 @@ static struct amba_device *v2m_amba_devs[] __initdata = { &rtc_device, }; - -static long v2m_osc_round(struct clk *clk, unsigned long rate) +static void __init v2m_timer_init(void) { - return rate; + vexpress_clk_init(ioremap(V2M_SYSCTL, SZ_4K)); + v2m_sp804_init(ioremap(V2M_TIMER01, SZ_4K), IRQ_V2M_TIMER0); } -static int v2m_osc1_set(struct clk *clk, unsigned long rate) +static void __init v2m_init_early(void) { - return v2m_cfg_write(SYS_CFG_OSC | SYS_CFG_SITE_MB | 1, rate); + if (ct_desc->init_early) + ct_desc->init_early(); + versatile_sched_clock_init(vexpress_get_24mhz_clock_base(), 24000000); } -static const struct clk_ops osc1_clk_ops = { - .round = v2m_osc_round, - .set = v2m_osc1_set, -}; +struct ct_desc *ct_desc; -static struct clk osc1_clk = { - .ops = &osc1_clk_ops, - .rate = 24000000, +static struct ct_desc *ct_descs[] __initdata = { +#ifdef CONFIG_ARCH_VEXPRESS_CA9X4 + &ct_ca9x4_desc, +#endif }; -static struct clk osc2_clk = { - .rate = 24000000, -}; +static void __init v2m_populate_ct_desc(void) +{ + int i; + u32 current_tile_id; -static struct clk dummy_apb_pclk; - -static struct clk_lookup v2m_lookups[] = { - { /* AMBA bus clock */ - .con_id = "apb_pclk", - .clk = &dummy_apb_pclk, - }, { /* UART0 */ - .dev_id = "mb:uart0", - .clk = &osc2_clk, - }, { /* UART1 */ - .dev_id = "mb:uart1", - .clk = &osc2_clk, - }, { /* UART2 */ - .dev_id = "mb:uart2", - .clk = &osc2_clk, - }, { /* UART3 */ - .dev_id = "mb:uart3", - .clk = &osc2_clk, - }, { /* KMI0 */ - .dev_id = "mb:kmi0", - .clk = &osc2_clk, - }, { /* KMI1 */ - .dev_id = "mb:kmi1", - .clk = &osc2_clk, - }, { /* MMC0 */ - .dev_id = "mb:mmci", - .clk = &osc2_clk, - }, { /* CLCD */ - .dev_id = "mb:clcd", - .clk = &osc1_clk, - }, -}; + ct_desc = NULL; + current_tile_id = vexpress_get_procid(VEXPRESS_SITE_MASTER) + & V2M_CT_ID_MASK; + + for (i = 0; i < ARRAY_SIZE(ct_descs) && !ct_desc; ++i) + if (ct_descs[i]->id == current_tile_id) + ct_desc = ct_descs[i]; -static void v2m_power_off(void) + if (!ct_desc) + panic("vexpress: this kernel does not support core tile ID 0x%08x when booting via ATAGs.\n" + "You may need a device tree blob or a different kernel to boot on this board.\n", + current_tile_id); +} + +static void __init v2m_map_io(void) { - if (v2m_cfg_write(SYS_CFG_SHUTDOWN | SYS_CFG_SITE_MB, 0)) - printk(KERN_EMERG "Unable to shutdown\n"); + iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc)); + vexpress_sysreg_early_init(ioremap(V2M_SYSREGS, SZ_4K)); + v2m_populate_ct_desc(); + ct_desc->map_io(); } -static void v2m_restart(char str, const char *cmd) +static void __init v2m_init_irq(void) { - if (v2m_cfg_write(SYS_CFG_REBOOT | SYS_CFG_SITE_MB, 0)) - printk(KERN_EMERG "Unable to reboot\n"); + ct_desc->init_irq(); } -static int __init v2m_init(void) +static void __init v2m_init(void) { int i; - clkdev_add_table(v2m_lookups, ARRAY_SIZE(v2m_lookups)); + regulator_register_fixed(0, v2m_eth_supplies, + ARRAY_SIZE(v2m_eth_supplies)); + platform_device_register(&v2m_sysreg_device); platform_device_register(&v2m_pcie_i2c_device); platform_device_register(&v2m_ddc_i2c_device); platform_device_register(&v2m_flash_device); + platform_device_register(&v2m_cf_device); platform_device_register(&v2m_eth_device); platform_device_register(&v2m_usb_device); for (i = 0; i < ARRAY_SIZE(v2m_amba_devs); i++) amba_device_register(v2m_amba_devs[i], &iomem_resource); - pm_power_off = v2m_power_off; - arm_pm_restart = v2m_restart; + vexpress_syscfg_device_register(&v2m_muxfpga_device); + vexpress_syscfg_device_register(&v2m_shutdown_device); + vexpress_syscfg_device_register(&v2m_reboot_device); + vexpress_syscfg_device_register(&v2m_dvimode_device); - return 0; + ct_desc->init_tile(); } -arch_initcall(v2m_init); + +MACHINE_START(VEXPRESS, "ARM-Versatile Express") + .atag_offset = 0x100, + .smp = smp_ops(vexpress_smp_ops), + .map_io = v2m_map_io, + .init_early = v2m_init_early, + .init_irq = v2m_init_irq, + .init_time = v2m_timer_init, + .init_machine = v2m_init, +MACHINE_END + +static void __init v2m_dt_init(void) +{ + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); +} + +static const char * const v2m_dt_match[] __initconst = { + "arm,vexpress", + NULL, +}; + +DT_MACHINE_START(VEXPRESS_DT, "ARM-Versatile Express") + .dt_compat = v2m_dt_match, + .l2c_aux_val = 0x00400000, + .l2c_aux_mask = 0xfe0fffff, + .smp = smp_ops(vexpress_smp_dt_ops), + .smp_init = smp_init_ops(vexpress_smp_init_ops), + .init_machine = v2m_dt_init, +MACHINE_END |
