From mboxrd@z Thu Jan 1 00:00:00 1970 From: robherring2@gmail.com (Rob Herring) Date: Tue, 16 Aug 2011 15:34:54 -0500 Subject: [PATCH 2/6] ARM: add Highbank core platform support In-Reply-To: <1313526898-19920-1-git-send-email-robherring2@gmail.com> References: <1313526898-19920-1-git-send-email-robherring2@gmail.com> Message-ID: <1313526898-19920-3-git-send-email-robherring2@gmail.com> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org From: Rob Herring This adds basic support for the Calxeda Highbank platform. Signed-off-by: Rob Herring --- arch/arm/Kconfig | 17 ++ arch/arm/Makefile | 1 + arch/arm/mach-highbank/Makefile | 1 + arch/arm/mach-highbank/Makefile.boot | 1 + arch/arm/mach-highbank/clock.c | 63 ++++++++ arch/arm/mach-highbank/core.h | 3 + arch/arm/mach-highbank/highbank.c | 164 +++++++++++++++++++++ arch/arm/mach-highbank/include/mach/debug-macro.S | 20 +++ arch/arm/mach-highbank/include/mach/entry-macro.S | 9 + arch/arm/mach-highbank/include/mach/gpio.h | 1 + arch/arm/mach-highbank/include/mach/io.h | 8 + arch/arm/mach-highbank/include/mach/irqs.h | 6 + arch/arm/mach-highbank/include/mach/memory.h | 1 + arch/arm/mach-highbank/include/mach/system.h | 26 ++++ arch/arm/mach-highbank/include/mach/timex.h | 6 + arch/arm/mach-highbank/include/mach/uncompress.h | 9 + arch/arm/mach-highbank/include/mach/vmalloc.h | 6 + arch/arm/mach-highbank/sysregs.h | 30 ++++ arch/arm/mach-highbank/system.c | 33 ++++ arch/arm/mm/Kconfig | 2 +- 20 files changed, 406 insertions(+), 1 deletions(-) create mode 100644 arch/arm/mach-highbank/Makefile create mode 100644 arch/arm/mach-highbank/Makefile.boot create mode 100644 arch/arm/mach-highbank/clock.c create mode 100644 arch/arm/mach-highbank/core.h create mode 100644 arch/arm/mach-highbank/highbank.c create mode 100644 arch/arm/mach-highbank/include/mach/debug-macro.S create mode 100644 arch/arm/mach-highbank/include/mach/entry-macro.S create mode 100644 arch/arm/mach-highbank/include/mach/gpio.h create mode 100644 arch/arm/mach-highbank/include/mach/io.h create mode 100644 arch/arm/mach-highbank/include/mach/irqs.h create mode 100644 arch/arm/mach-highbank/include/mach/memory.h create mode 100644 arch/arm/mach-highbank/include/mach/system.h create mode 100644 arch/arm/mach-highbank/include/mach/timex.h create mode 100644 arch/arm/mach-highbank/include/mach/uncompress.h create mode 100644 arch/arm/mach-highbank/include/mach/vmalloc.h create mode 100644 arch/arm/mach-highbank/sysregs.h create mode 100644 arch/arm/mach-highbank/system.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 5ebc5d9..eecee3d 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -318,6 +318,23 @@ config ARCH_BCMRING help Support for Broadcom's BCMRing platform. +config ARCH_HIGHBANK + bool "Calxeda Highbank-based" + select CPU_V7 + select AUTO_ZRELADDR + select ARM_PATCH_PHYS_VIRT + select ARM_GIC + select HAVE_ARM_SCU + select ARM_AMBA + select ARM_TIMER_SP804 + select PL330 + select CLKDEV_LOOKUP + select GENERIC_CLOCKEVENTS + select USE_OF + select ARCH_WANT_OPTIONAL_GPIOLIB + help + Support for the Calxeda Highbank SoC based boards. + config ARCH_CLPS711X bool "Cirrus Logic CLPS711x/EP721x-based" select CPU_ARM720T diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 70c424e..451097e 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -141,6 +141,7 @@ machine-$(CONFIG_ARCH_EBSA110) := ebsa110 machine-$(CONFIG_ARCH_EP93XX) := ep93xx machine-$(CONFIG_ARCH_GEMINI) := gemini machine-$(CONFIG_ARCH_H720X) := h720x +machine-$(CONFIG_ARCH_HIGHBANK) := highbank machine-$(CONFIG_ARCH_INTEGRATOR) := integrator machine-$(CONFIG_ARCH_IOP13XX) := iop13xx machine-$(CONFIG_ARCH_IOP32X) := iop32x diff --git a/arch/arm/mach-highbank/Makefile b/arch/arm/mach-highbank/Makefile new file mode 100644 index 0000000..b5de3b9 --- /dev/null +++ b/arch/arm/mach-highbank/Makefile @@ -0,0 +1 @@ +obj-y := clock.o highbank.o system.o diff --git a/arch/arm/mach-highbank/Makefile.boot b/arch/arm/mach-highbank/Makefile.boot new file mode 100644 index 0000000..dae9661 --- /dev/null +++ b/arch/arm/mach-highbank/Makefile.boot @@ -0,0 +1 @@ +zreladdr-y := 0x00008000 diff --git a/arch/arm/mach-highbank/clock.c b/arch/arm/mach-highbank/clock.c new file mode 100644 index 0000000..8464e14 --- /dev/null +++ b/arch/arm/mach-highbank/clock.c @@ -0,0 +1,63 @@ +/* + * Copyright 2011 Calxeda, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ +#include +#include +#include +#include +#include + + +struct clk { + unsigned long rate; +}; + +int clk_enable(struct clk *clk) +{ + return 0; +} + +void clk_disable(struct clk *clk) +{} + +unsigned long clk_get_rate(struct clk *clk) +{ + return clk->rate; +} + +long clk_round_rate(struct clk *clk, unsigned long rate) +{ + return clk->rate; +} + +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + return 0; +} + +static struct clk eclk = { .rate = 200000000 }; +static struct clk pclk = { .rate = 150000000 }; + +static struct clk_lookup lookups[] = { + { .clk = &pclk, .con_id = "apb_pclk", }, + { .clk = &pclk, .dev_id = "sp804", }, + { .clk = &eclk, .dev_id = "ffe0e000.sdhci", }, + { .clk = &pclk, .dev_id = "fff36000.serial", }, +}; + +void __init highbank_clocks_init(void) +{ + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); +} diff --git a/arch/arm/mach-highbank/core.h b/arch/arm/mach-highbank/core.h new file mode 100644 index 0000000..b5aa45f --- /dev/null +++ b/arch/arm/mach-highbank/core.h @@ -0,0 +1,3 @@ +extern void highbank_set_cpu_jump(int cpu, void *jump_addr); +extern void __iomem *a9_base_addr; +extern void highbank_clocks_init(void); diff --git a/arch/arm/mach-highbank/highbank.c b/arch/arm/mach-highbank/highbank.c new file mode 100644 index 0000000..49bbd13 --- /dev/null +++ b/arch/arm/mach-highbank/highbank.c @@ -0,0 +1,164 @@ +/* + * Copyright 2010-2011 Calxeda, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "core.h" +#include "sysregs.h" + +#define HB_DEBUG_LL_PHYS_BASE 0xfff36000 + +/* Static virtual mappings */ +#define HB_DEBUG_LL_VIRT_BASE 0xfee36000 +#define HB_MPIC_VIRT_BASE 0xfee00000 + +void __iomem *a9_base_addr = ((void __iomem *)(HB_MPIC_VIRT_BASE)); +void __iomem *sregs_base; + +static struct map_desc highbank_io_desc[] __initdata = { + { + .virtual = HB_MPIC_VIRT_BASE, + .pfn = 0, /* run-time */ + .length = SZ_4K, + .type = MT_DEVICE, + }, +#ifdef CONFIG_DEBUG_LL + { + .virtual = HB_DEBUG_LL_VIRT_BASE, + .pfn = __phys_to_pfn(HB_DEBUG_LL_PHYS_BASE), + .length = SZ_4K, + .type = MT_DEVICE, + }, +#endif +}; + +static void __init highbank_map_io(void) +{ + unsigned long base; + + /* Get SCU base */ + asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (base)); + + highbank_io_desc[0].pfn = __phys_to_pfn(base); + iotable_init(highbank_io_desc, ARRAY_SIZE(highbank_io_desc)); +} + +#define HB_JUMP_TABLE_PHYS(cpu) (0x40 + (0x10 * (cpu))) +#define HB_JUMP_TABLE_VIRT(cpu) phys_to_virt(HB_JUMP_TABLE_PHYS(cpu)) + +void highbank_set_cpu_jump(int cpu, void *jump_addr) +{ + writel(BSYM(virt_to_phys(jump_addr)), HB_JUMP_TABLE_VIRT(cpu)); + __cpuc_flush_dcache_area(HB_JUMP_TABLE_VIRT(cpu), 16); + outer_clean_range(HB_JUMP_TABLE_PHYS(cpu), + HB_JUMP_TABLE_PHYS(cpu) + 15); +} + +void highbank_init_irq(void) +{ + struct device_node *node; + struct of_intc_desc desc; + int n = 0; + + memset(&desc, 0, sizeof(desc)); + desc.controller = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-gic"); + gic_of_init(&desc); + node = desc.controller; + for_each_child_of_node(node, desc.controller) { + gic_of_ppi_init(&desc); + } + + for_each_compatible_node(node, NULL, "arm,pl061") { + irq_domain_add_simple(node, 160 + (8 * n)); + n++; + } + +#ifdef CONFIG_CACHE_L2X0 + l2x0_of_init(0, ~0UL); +#endif +} + +static void __init highbank_timer_init(void) +{ + int irq; + struct device_node *np; + void __iomem *timer_base; + + /* Map system registers */ + np = of_find_compatible_node(NULL, NULL, "calxeda,hb-sregs"); + sregs_base = of_iomap(np, 0); + + np = of_find_compatible_node(NULL, NULL, "arm,sp804"); + timer_base = of_iomap(np, 0); + irq = irq_of_parse_and_map(np, 0); + + highbank_clocks_init(); + + sp804_clocksource_init(timer_base + 0x20, "timer1"); + sp804_clockevents_init(timer_base, irq, "timer0"); +} + +static struct sys_timer highbank_timer = { + .init = highbank_timer_init, +}; + +static void highbank_power_off(void) +{ + writel(HB_PWR_SHUTDOWN, sregs_base + HB_SREG_A9_PWR_REQ); + scu_power_mode(a9_base_addr, SCU_PM_POWEROFF); + + while (1) + cpu_do_idle(); +} + +static void __init highbank_init(void) +{ + pm_power_off = highbank_power_off; + + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); +} + +static const char *highbank_match[] __initconst = { + "calxeda,highbank", + NULL, +}; + +DT_MACHINE_START(HIGHBANK, "Highbank") + .map_io = highbank_map_io, + .init_irq = highbank_init_irq, + .nr_irqs = NR_IRQS, + .timer = &highbank_timer, + .init_machine = highbank_init, + .dt_compat = highbank_match, +MACHINE_END diff --git a/arch/arm/mach-highbank/include/mach/debug-macro.S b/arch/arm/mach-highbank/include/mach/debug-macro.S new file mode 100644 index 0000000..f56096f --- /dev/null +++ b/arch/arm/mach-highbank/include/mach/debug-macro.S @@ -0,0 +1,20 @@ +/* + * Debugging macro include header + * + * Copyright (C) 1994-1999 Russell King + * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + + .macro addruart,rp,rv + movw \rv, #0x6000 + movt \rv, #0xfee3 + movw \rp, #0x6000 + movt \rp, #0xfff3 + .endm + +#include + diff --git a/arch/arm/mach-highbank/include/mach/entry-macro.S b/arch/arm/mach-highbank/include/mach/entry-macro.S new file mode 100644 index 0000000..56be409 --- /dev/null +++ b/arch/arm/mach-highbank/include/mach/entry-macro.S @@ -0,0 +1,9 @@ +#include +#include + + .macro disable_fiq + .endm + + .macro arch_ret_to_user, tmp1, tmp2 + .endm + diff --git a/arch/arm/mach-highbank/include/mach/gpio.h b/arch/arm/mach-highbank/include/mach/gpio.h new file mode 100644 index 0000000..40a8c17 --- /dev/null +++ b/arch/arm/mach-highbank/include/mach/gpio.h @@ -0,0 +1 @@ +/* empty */ diff --git a/arch/arm/mach-highbank/include/mach/io.h b/arch/arm/mach-highbank/include/mach/io.h new file mode 100644 index 0000000..5a37da2 --- /dev/null +++ b/arch/arm/mach-highbank/include/mach/io.h @@ -0,0 +1,8 @@ +#ifndef __MACH_IO_H +#define __MACH_IO_H + +#define IO_SPACE_LIMIT 0 +#define __io(a) ((void __iomem *)0) +#define __mem_pci(a) (a) + +#endif diff --git a/arch/arm/mach-highbank/include/mach/irqs.h b/arch/arm/mach-highbank/include/mach/irqs.h new file mode 100644 index 0000000..9746aab --- /dev/null +++ b/arch/arm/mach-highbank/include/mach/irqs.h @@ -0,0 +1,6 @@ +#ifndef __MACH_IRQS_H +#define __MACH_IRQS_H + +#define NR_IRQS 192 + +#endif diff --git a/arch/arm/mach-highbank/include/mach/memory.h b/arch/arm/mach-highbank/include/mach/memory.h new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/arch/arm/mach-highbank/include/mach/memory.h @@ -0,0 +1 @@ + diff --git a/arch/arm/mach-highbank/include/mach/system.h b/arch/arm/mach-highbank/include/mach/system.h new file mode 100644 index 0000000..7e81922 --- /dev/null +++ b/arch/arm/mach-highbank/include/mach/system.h @@ -0,0 +1,26 @@ +/* + * Copyright 2010-2011 Calxeda, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ +#ifndef __MACH_SYSTEM_H +#define __MACH_SYSTEM_H + +static inline void arch_idle(void) +{ + cpu_do_idle(); +} + +extern void arch_reset(char mode, const char *cmd); + +#endif diff --git a/arch/arm/mach-highbank/include/mach/timex.h b/arch/arm/mach-highbank/include/mach/timex.h new file mode 100644 index 0000000..88dac7a --- /dev/null +++ b/arch/arm/mach-highbank/include/mach/timex.h @@ -0,0 +1,6 @@ +#ifndef __MACH_TIMEX_H +#define __MACH_TIMEX_H + +#define CLOCK_TICK_RATE 1000000 + +#endif diff --git a/arch/arm/mach-highbank/include/mach/uncompress.h b/arch/arm/mach-highbank/include/mach/uncompress.h new file mode 100644 index 0000000..bbe20e6 --- /dev/null +++ b/arch/arm/mach-highbank/include/mach/uncompress.h @@ -0,0 +1,9 @@ +#ifndef __MACH_UNCOMPRESS_H +#define __MACH_UNCOMPRESS_H + +#define putc(c) +#define flush() +#define arch_decomp_setup() +#define arch_decomp_wdog() + +#endif diff --git a/arch/arm/mach-highbank/include/mach/vmalloc.h b/arch/arm/mach-highbank/include/mach/vmalloc.h new file mode 100644 index 0000000..1a3e398 --- /dev/null +++ b/arch/arm/mach-highbank/include/mach/vmalloc.h @@ -0,0 +1,6 @@ +#ifndef __MACH_VMALLOC_H +#define __MACH_VMALLOC_H + +#define VMALLOC_END 0xFEE00000UL + +#endif diff --git a/arch/arm/mach-highbank/sysregs.h b/arch/arm/mach-highbank/sysregs.h new file mode 100644 index 0000000..98ce973 --- /dev/null +++ b/arch/arm/mach-highbank/sysregs.h @@ -0,0 +1,30 @@ +/* + * Copyright 2011 Calxeda, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ +#ifndef _MACH_HIGHBANK__SYSREGS_H_ +#define _MACH_HIGHBANK__SYSREGS_H_ + +extern void __iomem *sregs_base; + +#define HB_SREG_A9_PWR_REQ 0xf00 +#define HB_SREG_A9_BOOT_STAT 0xf04 +#define HB_SREG_A9_BOOT_DATA 0xf08 + +#define HB_PWR_SUSPEND 0 +#define HB_PWR_SOFT_RESET 1 +#define HB_PWR_HARD_RESET 2 +#define HB_PWR_SHUTDOWN 3 + +#endif diff --git a/arch/arm/mach-highbank/system.c b/arch/arm/mach-highbank/system.c new file mode 100644 index 0000000..f8d1419 --- /dev/null +++ b/arch/arm/mach-highbank/system.c @@ -0,0 +1,33 @@ +/* + * Copyright 2011 Calxeda, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ +#include +#include +#include + +#include "core.h" +#include "sysregs.h" + +void arch_reset(char mode, const char *cmd) +{ + if (mode == 'h') + writel(HB_PWR_HARD_RESET, sregs_base + HB_SREG_A9_PWR_REQ); + else + writel(HB_PWR_SOFT_RESET, sregs_base + HB_SREG_A9_PWR_REQ); + + scu_power_mode(a9_base_addr, SCU_PM_POWEROFF); + cpu_do_idle(); +} + diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 88633fe..7d5fff7 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -822,7 +822,7 @@ config CACHE_L2X0 REALVIEW_EB_A9MP || SOC_IMX35 || SOC_IMX31 || MACH_REALVIEW_PBX || \ ARCH_NOMADIK || ARCH_OMAP4 || ARCH_EXYNOS4 || ARCH_TEGRA || \ ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || ARCH_SHMOBILE || \ - ARCH_PRIMA2 || ARCH_ZYNQ || ARCH_CNS3XXX + ARCH_PRIMA2 || ARCH_ZYNQ || ARCH_CNS3XXX || ARCH_HIGHBANK default y select OUTER_CACHE select OUTER_CACHE_SYNC -- 1.7.4.1