From 220e6cf7b793d702596506a8c4bf1f4fd4040df1 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 7 Jun 2011 10:02:55 -0500 Subject: ARM: add Highbank core platform support This adds basic support for the Calxeda Highbank platform. Signed-off-by: Rob Herring Reviewed-by: Jamie Iles Reviewed-by: Shawn Guo --- arch/arm/mach-highbank/Makefile | 2 + arch/arm/mach-highbank/Makefile.boot | 1 + arch/arm/mach-highbank/clock.c | 62 +++++++++ arch/arm/mach-highbank/core.h | 9 ++ arch/arm/mach-highbank/highbank.c | 145 ++++++++++++++++++++++ arch/arm/mach-highbank/include/mach/debug-macro.S | 19 +++ arch/arm/mach-highbank/include/mach/entry-macro.S | 7 ++ arch/arm/mach-highbank/include/mach/gpio.h | 1 + arch/arm/mach-highbank/include/mach/io.h | 7 ++ 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 | 1 + arch/arm/mach-highbank/lluart.c | 34 +++++ arch/arm/mach-highbank/sysregs.h | 52 ++++++++ arch/arm/mach-highbank/system.c | 33 +++++ 18 files changed, 421 insertions(+) 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/lluart.c create mode 100644 arch/arm/mach-highbank/sysregs.h create mode 100644 arch/arm/mach-highbank/system.c (limited to 'arch/arm/mach-highbank') diff --git a/arch/arm/mach-highbank/Makefile b/arch/arm/mach-highbank/Makefile new file mode 100644 index 00000000000..da7f81a6953 --- /dev/null +++ b/arch/arm/mach-highbank/Makefile @@ -0,0 +1,2 @@ +obj-y := clock.o highbank.o system.o +obj-$(CONFIG_DEBUG_HIGHBANK_UART) += lluart.o diff --git a/arch/arm/mach-highbank/Makefile.boot b/arch/arm/mach-highbank/Makefile.boot new file mode 100644 index 00000000000..dae9661a768 --- /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 00000000000..c25a2ae4fde --- /dev/null +++ b/arch/arm/mach-highbank/clock.c @@ -0,0 +1,62 @@ +/* + * 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 00000000000..7e33fc94cd1 --- /dev/null +++ b/arch/arm/mach-highbank/core.h @@ -0,0 +1,9 @@ +extern void highbank_set_cpu_jump(int cpu, void *jump_addr); +extern void highbank_clocks_init(void); +extern void __iomem *scu_base_addr; +#ifdef CONFIG_DEBUG_HIGHBANK_UART +extern void highbank_lluart_map_io(void); +#else +static inline void highbank_lluart_map_io(void) {} +#endif + diff --git a/arch/arm/mach-highbank/highbank.c b/arch/arm/mach-highbank/highbank.c new file mode 100644 index 00000000000..b82dcf08e74 --- /dev/null +++ b/arch/arm/mach-highbank/highbank.c @@ -0,0 +1,145 @@ +/* + * 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 + +#include "core.h" +#include "sysregs.h" + +void __iomem *sregs_base; + +#define HB_SCU_VIRT_BASE 0xfee00000 +void __iomem *scu_base_addr = ((void __iomem *)(HB_SCU_VIRT_BASE)); + +static struct map_desc scu_io_desc __initdata = { + .virtual = HB_SCU_VIRT_BASE, + .pfn = 0, /* run-time */ + .length = SZ_4K, + .type = MT_DEVICE, +}; + +static void __init highbank_scu_map_io(void) +{ + unsigned long base; + + /* Get SCU base */ + asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (base)); + + scu_io_desc.pfn = __phys_to_pfn(base); + iotable_init(&scu_io_desc, 1); +} + +static void __init highbank_map_io(void) +{ + highbank_scu_map_io(); + highbank_lluart_map_io(); +} + +#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); +} + +const static struct of_device_id irq_match[] = { + { .compatible = "arm,cortex-a9-gic", .data = gic_of_init, }, + {} +}; + +static void __init highbank_init_irq(void) +{ + of_irq_init(irq_match); + l2x0_of_init(0, ~0UL); +} + +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); + WARN_ON(!sregs_base); + + np = of_find_compatible_node(NULL, NULL, "arm,sp804"); + timer_base = of_iomap(np, 0); + WARN_ON(!timer_base); + 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) +{ + hignbank_set_pwr_shutdown(); + scu_power_mode(scu_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, + .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 00000000000..cb57fe5bcd0 --- /dev/null +++ b/arch/arm/mach-highbank/include/mach/debug-macro.S @@ -0,0 +1,19 @@ +/* + * 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,tmp + 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 00000000000..73c11297509 --- /dev/null +++ b/arch/arm/mach-highbank/include/mach/entry-macro.S @@ -0,0 +1,7 @@ +#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 00000000000..40a8c178f10 --- /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 00000000000..70cfa3ba769 --- /dev/null +++ b/arch/arm/mach-highbank/include/mach/io.h @@ -0,0 +1,7 @@ +#ifndef __MACH_IO_H +#define __MACH_IO_H + +#define __io(a) ({ (void)(a); __typesafe_io(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 00000000000..9746aab14e9 --- /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 00000000000..40a8c178f10 --- /dev/null +++ b/arch/arm/mach-highbank/include/mach/memory.h @@ -0,0 +1 @@ +/* empty */ 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 00000000000..7e8192296ca --- /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 00000000000..88dac7a55a9 --- /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 00000000000..bbe20e69632 --- /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 00000000000..1969e954277 --- /dev/null +++ b/arch/arm/mach-highbank/include/mach/vmalloc.h @@ -0,0 +1 @@ +#define VMALLOC_END 0xFEE00000UL diff --git a/arch/arm/mach-highbank/lluart.c b/arch/arm/mach-highbank/lluart.c new file mode 100644 index 00000000000..371575019f3 --- /dev/null +++ b/arch/arm/mach-highbank/lluart.c @@ -0,0 +1,34 @@ +/* + * 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 + +#define HB_DEBUG_LL_PHYS_BASE 0xfff36000 +#define HB_DEBUG_LL_VIRT_BASE 0xfee36000 + +static struct map_desc lluart_io_desc __initdata = { + .virtual = HB_DEBUG_LL_VIRT_BASE, + .pfn = __phys_to_pfn(HB_DEBUG_LL_PHYS_BASE), + .length = SZ_4K, + .type = MT_DEVICE, +}; + +void __init highbank_lluart_map_io(void) +{ + iotable_init(&lluart_io_desc, 1); +} diff --git a/arch/arm/mach-highbank/sysregs.h b/arch/arm/mach-highbank/sysregs.h new file mode 100644 index 00000000000..0e913389f44 --- /dev/null +++ b/arch/arm/mach-highbank/sysregs.h @@ -0,0 +1,52 @@ +/* + * 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_ + +#include + +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 + +static inline void hignbank_set_pwr_suspend(void) +{ + writel(HB_PWR_SUSPEND, sregs_base + HB_SREG_A9_PWR_REQ); +} + +static inline void hignbank_set_pwr_shutdown(void) +{ + writel(HB_PWR_SHUTDOWN, sregs_base + HB_SREG_A9_PWR_REQ); +} + +static inline void hignbank_set_pwr_soft_reset(void) +{ + writel(HB_PWR_SOFT_RESET, sregs_base + HB_SREG_A9_PWR_REQ); +} + +static inline void hignbank_set_pwr_hard_reset(void) +{ + writel(HB_PWR_HARD_RESET, sregs_base + HB_SREG_A9_PWR_REQ); +} + +#endif diff --git a/arch/arm/mach-highbank/system.c b/arch/arm/mach-highbank/system.c new file mode 100644 index 00000000000..53f0c4c5ef1 --- /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') + hignbank_set_pwr_hard_reset(); + else + hignbank_set_pwr_soft_reset(); + + scu_power_mode(scu_base_addr, SCU_PM_POWEROFF); + cpu_do_idle(); +} + -- cgit v1.2.3