summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-aspeed/aspeed.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-aspeed/aspeed.c')
-rwxr-xr-xarch/arm/mach-aspeed/aspeed.c256
1 files changed, 256 insertions, 0 deletions
diff --git a/arch/arm/mach-aspeed/aspeed.c b/arch/arm/mach-aspeed/aspeed.c
new file mode 100755
index 000000000000..fadbbb666e1d
--- /dev/null
+++ b/arch/arm/mach-aspeed/aspeed.c
@@ -0,0 +1,256 @@
+#include <linux/init.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/io.h>
+#include <linux/clk-provider.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include "ast2400.h"
+
+// XXX TEMP HACKERY
+//
+// To be replaced by proper clock, pinmux and syscon drivers operating
+// from DT parameters
+
+static void __init aspeed_dt_init(void)
+{
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
+
+static const struct of_device_id aspeed_clk_match[] __initconst = {
+ {
+ .compatible = "fixed-clock",
+ .data = of_fixed_clk_setup,
+ },
+ {}
+};
+
+void __init aspeed_clk_init(void __iomem *base)
+{
+ of_clk_init(aspeed_clk_match);
+}
+
+#define AST_IO_VA 0xf0000000
+#define AST_IO_PA 0x1e600000
+#define AST_IO_SZ 0x00200000
+
+#define AST_IO(__pa) ((void __iomem *)(((__pa) & 0x001fffff) | AST_IO_VA))
+
+static struct map_desc aspeed_io_desc[] __initdata __maybe_unused = {
+ {
+ .virtual = AST_IO_VA,
+ .pfn = __phys_to_pfn(AST_IO_PA),
+ .length = AST_IO_SZ,
+ .type = MT_DEVICE
+ },
+};
+
+
+#define UART_RBR 0
+#define UART_IER 1
+#define UART_FCR 2
+#define UART_LCR 3
+#define UART_MCR 4
+#define UART_LSR 5
+#define UART_MSR 6
+#define UART_SCR 7
+#define UART_THR UART_RBR
+#define UART_IIR UART_FCR
+#define UART_DLL UART_RBR
+#define UART_DLM UART_IER
+#define UART_DLAB UART_LCR
+
+#define LSR_DR 0x01 /* Data ready */
+#define LSR_OE 0x02 /* Overrun */
+#define LSR_PE 0x04 /* Parity error */
+#define LSR_FE 0x08 /* Framing error */
+#define LSR_BI 0x10 /* Break */
+#define LSR_THRE 0x20 /* Xmit holding register empty */
+#define LSR_TEMT 0x40 /* Xmitter empty */
+#define LSR_ERR 0x80 /* Error */
+
+#define LCR_DLAB 0x80
+
+static void ast_uart_out(unsigned int reg, u8 data)
+{
+ writeb(data, AST_IO(0x1E78F000 + reg * 4));
+}
+
+static void ast_host_uart_setup(unsigned int speed, unsigned int clock)
+{
+ unsigned int dll, base_bauds;
+
+ if (clock == 0)
+ clock = 1843200;
+ if (speed == 0)
+ speed = 9600;
+
+ base_bauds = clock / 16;
+ dll = base_bauds / speed;
+
+ ast_uart_out(UART_LCR, 0x00);
+ ast_uart_out(UART_IER, 0xff);
+ ast_uart_out(UART_IER, 0x00);
+ ast_uart_out(UART_LCR, LCR_DLAB);
+ ast_uart_out(UART_DLL, dll & 0xff);
+ ast_uart_out(UART_DLM, dll >> 8);
+ /* 8 data, 1 stop, no parity */
+ ast_uart_out(UART_LCR, 0x3);
+ /* RTS/DTR */
+ ast_uart_out(UART_MCR, 0x3);
+ /* Clear & enable FIFOs */
+ ast_uart_out(UART_FCR, 0x7);
+}
+
+static void __init do_common_setup(void)
+{
+ /* Enable LPC FWH cycles, Enable LPC to AHB bridge */
+ writel(0x00000500, AST_IO(AST_BASE_LPC | 0x80));
+
+ /* Flash controller */
+ writel(0x00000003, AST_IO(AST_BASE_SPI | 0x00));
+ writel(0x00002404, AST_IO(AST_BASE_SPI | 0x04));
+
+ /* Set UART routing */
+ writel(0x00000000, AST_IO(AST_BASE_LPC | 0x9c));
+
+ /* SCU setup */
+ writel(0x01C000FF, AST_IO(AST_BASE_SCU | 0x88));
+ writel(0xC1C000FF, AST_IO(AST_BASE_SCU | 0x8c));
+ writel(0x003FA008, AST_IO(AST_BASE_SCU | 0x90));
+
+ /* Setup scratch registers */
+ writel(0x00000042, AST_IO(AST_BASE_LPC | 0x170));
+ writel(0x00008000, AST_IO(AST_BASE_LPC | 0x174));
+}
+
+static void __init do_barreleye_setup(void)
+{
+ u32 reg;
+
+ do_common_setup();
+
+ /* Setup PNOR address mapping for 64M flash */
+ writel(0x30000C00, AST_IO(AST_BASE_LPC | 0x88));
+ writel(0xFC0003FF, AST_IO(AST_BASE_LPC | 0x8C));
+
+ /* GPIO setup */
+ writel(0x9E82FCE7, AST_IO(AST_BASE_GPIO | 0x00));
+ writel(0x0370E677, AST_IO(AST_BASE_GPIO | 0x04));
+
+ /* SCU setup */
+ writel(0x01C00000, AST_IO(AST_BASE_SCU | 0x88));
+
+ /* To enable GPIOE0 pass through function debounce mode */
+ writel(0x010FFFFF, AST_IO(AST_BASE_SCU | 0xA8));
+
+ /*
+ * Do read/modify/write on power gpio to prevent resetting power on
+ * reboot
+ */
+ reg = readl(AST_IO(AST_BASE_GPIO | 0x20));
+ reg |= 0xCFC8F7FD;
+ writel(reg, AST_IO(AST_BASE_GPIO | 0x20));
+ writel(0xC738F20A, AST_IO(AST_BASE_GPIO | 0x24));
+ writel(0x0031FFAF, AST_IO(AST_BASE_GPIO | 0x80));
+
+ /* Select TIMER3 as debounce timer */
+ writel(0x00000001, AST_IO(AST_BASE_GPIO | 0x48));
+ writel(0x00000001, AST_IO(AST_BASE_GPIO | 0x4C));
+
+ /* Set debounce timer to 480000 cycles, with a pclk of 48MHz,
+ * corresponds to 20 ms. This time was found by experimentation */
+ writel(0x000EA600, AST_IO(AST_BASE_GPIO | 0x58));
+}
+
+static void __init do_palmetto_setup(void)
+{
+ do_common_setup();
+
+ /* Setup PNOR address mapping for 32M flash */
+ writel(0x30000E00, AST_IO(AST_BASE_LPC | 0x88));
+ writel(0xFE0001FF, AST_IO(AST_BASE_LPC | 0x8C));
+
+ /* GPIO setup */
+ writel(0x13008CE7, AST_IO(AST_BASE_GPIO | 0x00));
+ writel(0x0370E677, AST_IO(AST_BASE_GPIO | 0x04));
+ writel(0xDF48F7FF, AST_IO(AST_BASE_GPIO | 0x20));
+ writel(0xC738F202, AST_IO(AST_BASE_GPIO | 0x24));
+
+ /* SCU setup */
+ writel(0x01C0007F, AST_IO(AST_BASE_SCU | 0x88));
+}
+
+static void __init do_garrison_setup(void)
+{
+ do_common_setup();
+
+ /* Setup PNOR address mapping for 64M flash */
+ writel(0x30000C00, AST_IO(AST_BASE_LPC | 0x88));
+ writel(0xFC0003FF, AST_IO(AST_BASE_LPC | 0x8C));
+
+ /* SCU setup */
+ writel(0xd7000000, AST_IO(AST_BASE_SCU | 0x88));
+}
+
+#define SCU_PASSWORD 0x1688A8A8
+
+static void __init aspeed_init_early(void)
+{
+ u32 reg;
+
+ // XXX UART stuff to fix to pinmux & co
+ writel(0x02010023, AST_IO(AST_BASE_LPC | 0x9c));
+ writel(SCU_PASSWORD, AST_IO(AST_BASE_SCU)); // UNLOCK SCU
+ writel(0xcb000000, AST_IO(AST_BASE_SCU | 0x80));
+ writel(0x00fff0c0, AST_IO(AST_BASE_SCU | 0x84));
+ writel(0x10CC5E80, AST_IO(AST_BASE_SCU | 0x0c));
+
+ /* We enable the UART clock divisor in the SCU's misc control
+ * register, as the baud rates in aspeed.dtb all assume that the
+ * divisor is active
+ */
+ reg = readl(AST_IO(AST_BASE_SCU | 0x2c));
+ writel(reg | 0x00001000, AST_IO(AST_BASE_SCU | 0x2c));
+ ast_host_uart_setup(115200,0);
+
+ writel(0, AST_IO(AST_BASE_WDT | 0x0c));
+ writel(0, AST_IO(AST_BASE_WDT | 0x2c));
+
+ /*
+ * Ensure all IPs except GPIO and LPC are reset on watchdog expiry
+ */
+ writel(0x001fdff3, AST_IO(AST_BASE_SCU | 0x9c));
+
+ /*
+ * Temporary setup of AST registers until pinmux driver is complete
+ */
+ if (of_machine_is_compatible("rackspace,barreleye-bmc"))
+ do_barreleye_setup();
+ if (of_machine_is_compatible("tyan,palmetto-bmc"))
+ do_palmetto_setup();
+ if (of_machine_is_compatible("ibm,garrison-bmc"))
+ do_garrison_setup();
+
+}
+
+static void __init aspeed_map_io(void)
+{
+ iotable_init(aspeed_io_desc, ARRAY_SIZE(aspeed_io_desc));
+ debug_ll_io_init();
+
+ printk("SOC Rev: %08x\n", readl(AST_IO(AST_BASE_SCU | 0x7c)));
+}
+
+static const char *const aspeed_dt_match[] __initconst = {
+ "aspeed,ast2400",
+ NULL,
+};
+
+DT_MACHINE_START(aspeed_dt, "ASpeed SoC")
+ .map_io = aspeed_map_io,
+ .init_early = aspeed_init_early,
+ .init_machine = aspeed_dt_init,
+ .dt_compat = aspeed_dt_match,
+MACHINE_END
OpenPOWER on IntegriCloud