summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/Kconfig6
-rw-r--r--arch/arm/cpu/armv7/sunxi/Makefile4
-rw-r--r--arch/arm/cpu/armv7/sunxi/board.c38
-rw-r--r--arch/arm/cpu/armv7/sunxi/clock_sun4i.c11
-rw-r--r--arch/arm/cpu/armv7/sunxi/clock_sun6i.c76
-rw-r--r--arch/arm/cpu/armv7/sunxi/cpu_info.c4
-rw-r--r--arch/arm/cpu/armv7/sunxi/dram.c36
-rw-r--r--arch/arm/cpu/armv7/sunxi/prcm.c35
-rw-r--r--arch/arm/include/asm/arch-sunxi/clock.h5
-rw-r--r--arch/arm/include/asm/arch-sunxi/clock_sun4i.h3
-rw-r--r--arch/arm/include/asm/arch-sunxi/clock_sun6i.h205
-rw-r--r--arch/arm/include/asm/arch-sunxi/cpu.h10
-rw-r--r--arch/arm/include/asm/arch-sunxi/gpio.h45
-rw-r--r--arch/arm/include/asm/arch-sunxi/mmc.h7
-rw-r--r--arch/arm/include/asm/arch-sunxi/prcm.h238
-rw-r--r--arch/arm/include/asm/arch-sunxi/timer.h23
-rw-r--r--arch/arm/include/asm/arch-sunxi/watchdog.h44
17 files changed, 749 insertions, 41 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 109d49f57d..8f910f39a3 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -450,9 +450,15 @@ config TARGET_SUN4I
config TARGET_SUN5I
bool "Support sun5i"
+config TARGET_SUN6I
+ bool "Support sun6i"
+
config TARGET_SUN7I
bool "Support sun7i"
+config TARGET_SUN8I
+ bool "Support sun8i"
+
config TARGET_SNOWBALL
bool "Support snowball"
diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile
index e9721b27b6..24f1daee64 100644
--- a/arch/arm/cpu/armv7/sunxi/Makefile
+++ b/arch/arm/cpu/armv7/sunxi/Makefile
@@ -11,9 +11,13 @@ obj-y += timer.o
obj-y += board.o
obj-y += clock.o
obj-y += pinmux.o
+obj-$(CONFIG_SUN6I) += prcm.o
+obj-$(CONFIG_SUN8I) += prcm.o
obj-$(CONFIG_SUN4I) += clock_sun4i.o
obj-$(CONFIG_SUN5I) += clock_sun4i.o
+obj-$(CONFIG_SUN6I) += clock_sun6i.o
obj-$(CONFIG_SUN7I) += clock_sun4i.o
+obj-$(CONFIG_SUN8I) += clock_sun6i.o
ifndef CONFIG_SPL_BUILD
obj-y += cpu_info.o
diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c
index f2cedbb156..06eb6768e8 100644
--- a/arch/arm/cpu/armv7/sunxi/board.c
+++ b/arch/arm/cpu/armv7/sunxi/board.c
@@ -50,18 +50,35 @@ u32 spl_boot_mode(void)
int gpio_init(void)
{
-#if CONFIG_CONS_INDEX == 1 && (defined(CONFIG_SUN4I) || defined(CONFIG_SUN7I))
+#if CONFIG_CONS_INDEX == 1 && defined(CONFIG_UART0_PORT_F)
+#if defined(CONFIG_SUN4I) || defined(CONFIG_SUN7I)
+ /* disable GPB22,23 as uart0 tx,rx to avoid conflict */
+ sunxi_gpio_set_cfgpin(SUNXI_GPB(22), SUNXI_GPIO_INPUT);
+ sunxi_gpio_set_cfgpin(SUNXI_GPB(23), SUNXI_GPIO_INPUT);
+#endif
+ sunxi_gpio_set_cfgpin(SUNXI_GPF(2), SUNXI_GPF2_UART0_TX);
+ sunxi_gpio_set_cfgpin(SUNXI_GPF(4), SUNXI_GPF4_UART0_RX);
+ sunxi_gpio_set_pull(SUNXI_GPF(4), 1);
+#elif CONFIG_CONS_INDEX == 1 && (defined(CONFIG_SUN4I) || defined(CONFIG_SUN7I))
sunxi_gpio_set_cfgpin(SUNXI_GPB(22), SUN4I_GPB22_UART0_TX);
sunxi_gpio_set_cfgpin(SUNXI_GPB(23), SUN4I_GPB23_UART0_RX);
- sunxi_gpio_set_pull(SUNXI_GPB(23), 1);
+ sunxi_gpio_set_pull(SUNXI_GPB(23), SUNXI_GPIO_PULL_UP);
#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_SUN5I)
sunxi_gpio_set_cfgpin(SUNXI_GPB(19), SUN5I_GPB19_UART0_TX);
sunxi_gpio_set_cfgpin(SUNXI_GPB(20), SUN5I_GPB20_UART0_RX);
- sunxi_gpio_set_pull(SUNXI_GPB(20), 1);
+ sunxi_gpio_set_pull(SUNXI_GPB(20), SUNXI_GPIO_PULL_UP);
+#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_SUN6I)
+ sunxi_gpio_set_cfgpin(SUNXI_GPH(20), SUN6I_GPH20_UART0_TX);
+ sunxi_gpio_set_cfgpin(SUNXI_GPH(21), SUN6I_GPH21_UART0_RX);
+ sunxi_gpio_set_pull(SUNXI_GPH(21), SUNXI_GPIO_PULL_UP);
#elif CONFIG_CONS_INDEX == 2 && defined(CONFIG_SUN5I)
sunxi_gpio_set_cfgpin(SUNXI_GPG(3), SUN5I_GPG3_UART1_TX);
sunxi_gpio_set_cfgpin(SUNXI_GPG(4), SUN5I_GPG4_UART1_RX);
- sunxi_gpio_set_pull(SUNXI_GPG(4), 1);
+ sunxi_gpio_set_pull(SUNXI_GPG(4), SUNXI_GPIO_PULL_UP);
+#elif CONFIG_CONS_INDEX == 5 && defined(CONFIG_SUN8I)
+ sunxi_gpio_set_cfgpin(SUNXI_GPL(2), SUN8I_GPL2_R_UART_TX);
+ sunxi_gpio_set_cfgpin(SUNXI_GPL(3), SUN8I_GPL3_R_UART_RX);
+ sunxi_gpio_set_pull(SUNXI_GPL(3), SUNXI_GPIO_PULL_UP);
#else
#error Unsupported console port number. Please fix pin mux settings in board.c
#endif
@@ -71,6 +88,7 @@ int gpio_init(void)
void reset_cpu(ulong addr)
{
+#if defined(CONFIG_SUN4I) || defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)
static const struct sunxi_wdog *wdog =
&((struct sunxi_timer_reg *)SUNXI_TIMER_BASE)->wdog;
@@ -82,12 +100,22 @@ void reset_cpu(ulong addr)
/* sun5i sometimes gets stuck without this */
writel(WDT_MODE_RESET_EN | WDT_MODE_EN, &wdog->mode);
}
+#else /* CONFIG_SUN6I || CONFIG_SUN8I || .. */
+ static const struct sunxi_wdog *wdog =
+ ((struct sunxi_timer_reg *)SUNXI_TIMER_BASE)->wdog;
+
+ /* Set the watchdog for its shortest interval (.5s) and wait */
+ writel(WDT_CFG_RESET, &wdog->cfg);
+ writel(WDT_MODE_EN, &wdog->mode);
+ writel(WDT_CTRL_KEY | WDT_CTRL_RESTART, &wdog->ctl);
+#endif
}
/* do some early init */
void s_init(void)
{
-#if !defined CONFIG_SPL_BUILD && (defined CONFIG_SUN7I || defined CONFIG_SUN6I)
+#if !defined CONFIG_SPL_BUILD && (defined CONFIG_SUN7I || \
+ defined CONFIG_SUN6I || defined CONFIG_SUN8I)
/* Enable SMP mode for CPU0, by setting bit 6 of Auxiliary Ctl reg */
asm volatile(
"mrc p15, 0, r0, c1, c0, 1\n"
diff --git a/arch/arm/cpu/armv7/sunxi/clock_sun4i.c b/arch/arm/cpu/armv7/sunxi/clock_sun4i.c
index ecbdb0162b..4a0d64fb30 100644
--- a/arch/arm/cpu/armv7/sunxi/clock_sun4i.c
+++ b/arch/arm/cpu/armv7/sunxi/clock_sun4i.c
@@ -180,6 +180,17 @@ void clock_set_pll1(unsigned int hz)
}
#endif
+unsigned int clock_get_pll5p(void)
+{
+ struct sunxi_ccm_reg *const ccm =
+ (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+ uint32_t rval = readl(&ccm->pll5_cfg);
+ int n = ((rval & CCM_PLL5_CTRL_N_MASK) >> CCM_PLL5_CTRL_N_SHIFT);
+ int k = ((rval & CCM_PLL5_CTRL_K_MASK) >> CCM_PLL5_CTRL_K_SHIFT) + 1;
+ int p = ((rval & CCM_PLL5_CTRL_P_MASK) >> CCM_PLL5_CTRL_P_SHIFT);
+ return (24000000 * n * k) >> p;
+}
+
unsigned int clock_get_pll6(void)
{
struct sunxi_ccm_reg *const ccm =
diff --git a/arch/arm/cpu/armv7/sunxi/clock_sun6i.c b/arch/arm/cpu/armv7/sunxi/clock_sun6i.c
new file mode 100644
index 0000000000..1eae9767d0
--- /dev/null
+++ b/arch/arm/cpu/armv7/sunxi/clock_sun6i.c
@@ -0,0 +1,76 @@
+/*
+ * sun6i specific clock code
+ *
+ * (C) Copyright 2007-2012
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Tom Cubie <tangliang@allwinnertech.com>
+ *
+ * (C) Copyright 2013 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/prcm.h>
+#include <asm/arch/sys_proto.h>
+
+void clock_init_uart(void)
+{
+ struct sunxi_ccm_reg *const ccm =
+ (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+
+#if CONFIG_CONS_INDEX < 5
+ /* uart clock source is apb2 */
+ writel(APB2_CLK_SRC_OSC24M|
+ APB2_CLK_RATE_N_1|
+ APB2_CLK_RATE_M(1),
+ &ccm->apb2_div);
+
+ /* open the clock for uart */
+ setbits_le32(&ccm->apb2_gate,
+ CLK_GATE_OPEN << (APB2_GATE_UART_SHIFT +
+ CONFIG_CONS_INDEX - 1));
+
+ /* deassert uart reset */
+ setbits_le32(&ccm->apb2_reset_cfg,
+ 1 << (APB2_RESET_UART_SHIFT +
+ CONFIG_CONS_INDEX - 1));
+#else
+ /* enable R_PIO and R_UART clocks, and de-assert resets */
+ prcm_apb0_enable(PRCM_APB0_GATE_PIO | PRCM_APB0_GATE_UART);
+#endif
+
+ /* Dup with clock_init_safe(), drop once sun6i SPL support lands */
+ writel(PLL6_CFG_DEFAULT, &ccm->pll6_cfg);
+}
+
+int clock_twi_onoff(int port, int state)
+{
+ struct sunxi_ccm_reg *const ccm =
+ (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+
+ if (port > 3)
+ return -1;
+
+ /* set the apb clock gate for twi */
+ if (state)
+ setbits_le32(&ccm->apb2_gate,
+ CLK_GATE_OPEN << (APB2_GATE_TWI_SHIFT+port));
+ else
+ clrbits_le32(&ccm->apb2_gate,
+ CLK_GATE_OPEN << (APB2_GATE_TWI_SHIFT+port));
+
+ return 0;
+}
+
+unsigned int clock_get_pll6(void)
+{
+ struct sunxi_ccm_reg *const ccm =
+ (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+ uint32_t rval = readl(&ccm->pll6_cfg);
+ int n = ((rval & CCM_PLL6_CTRL_N_MASK) >> CCM_PLL6_CTRL_N_SHIFT) + 1;
+ int k = ((rval & CCM_PLL6_CTRL_K_MASK) >> CCM_PLL6_CTRL_K_SHIFT) + 1;
+ return 24000000 * n * k / 2;
+}
diff --git a/arch/arm/cpu/armv7/sunxi/cpu_info.c b/arch/arm/cpu/armv7/sunxi/cpu_info.c
index 5cf35acc1e..4f2a09cd2e 100644
--- a/arch/arm/cpu/armv7/sunxi/cpu_info.c
+++ b/arch/arm/cpu/armv7/sunxi/cpu_info.c
@@ -23,8 +23,12 @@ int print_cpuinfo(void)
case 7: puts("CPU: Allwinner A10s (SUN5I)\n"); break;
default: puts("CPU: Allwinner A1X (SUN5I)\n");
}
+#elif defined CONFIG_SUN6I
+ puts("CPU: Allwinner A31 (SUN6I)\n");
#elif defined CONFIG_SUN7I
puts("CPU: Allwinner A20 (SUN7I)\n");
+#elif defined CONFIG_SUN8I
+ puts("CPU: Allwinner A23 (SUN8I)\n");
#else
#warning Please update cpu_info.c with correct CPU information
puts("CPU: SUNXI Family\n");
diff --git a/arch/arm/cpu/armv7/sunxi/dram.c b/arch/arm/cpu/armv7/sunxi/dram.c
index 584f7420d7..3cf3cbf19a 100644
--- a/arch/arm/cpu/armv7/sunxi/dram.c
+++ b/arch/arm/cpu/armv7/sunxi/dram.c
@@ -252,15 +252,9 @@ static void mctl_setup_dram_clock(u32 clk, u32 mbus_clk)
{
u32 reg_val;
struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
-
- /* PLL5P and PLL6 are the potential clock sources for MBUS */
- u32 pll6x_div, pll5p_div;
- u32 pll6x_clk = clock_get_pll6() / 1000000;
- u32 pll5p_clk = clk / 24 * 48;
+ u32 pll5p_clk, pll6x_clk;
+ u32 pll5p_div, pll6x_div;
u32 pll5p_rate, pll6x_rate;
-#ifdef CONFIG_SUN7I
- pll6x_clk *= 2; /* sun7i uses PLL6*2, sun5i uses just PLL6 */
-#endif
/* setup DRAM PLL */
reg_val = readl(&ccm->pll5_cfg);
@@ -268,33 +262,32 @@ static void mctl_setup_dram_clock(u32 clk, u32 mbus_clk)
reg_val &= ~CCM_PLL5_CTRL_K_MASK; /* set K to 0 (x1) */
reg_val &= ~CCM_PLL5_CTRL_N_MASK; /* set N to 0 (x0) */
reg_val &= ~CCM_PLL5_CTRL_P_MASK; /* set P to 0 (x1) */
+#ifdef CONFIG_OLD_SUNXI_KERNEL_COMPAT
+ /* Old kernels are hardcoded to P=1 (divide by 2) */
+ reg_val |= CCM_PLL5_CTRL_P(1);
+#endif
if (clk >= 540 && clk < 552) {
- /* dram = 540MHz, pll5p = 1080MHz */
- pll5p_clk = 1080;
+ /* dram = 540MHz */
reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2));
reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(3));
reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(15));
} else if (clk >= 512 && clk < 528) {
- /* dram = 512MHz, pll5p = 1536MHz */
- pll5p_clk = 1536;
+ /* dram = 512MHz */
reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(3));
reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(4));
reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(16));
} else if (clk >= 496 && clk < 504) {
- /* dram = 496MHz, pll5p = 1488MHz */
- pll5p_clk = 1488;
+ /* dram = 496MHz */
reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(3));
reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(2));
reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(31));
} else if (clk >= 468 && clk < 480) {
- /* dram = 468MHz, pll5p = 936MHz */
- pll5p_clk = 936;
+ /* dram = 468MHz */
reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2));
reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(3));
reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(13));
} else if (clk >= 396 && clk < 408) {
- /* dram = 396MHz, pll5p = 792MHz */
- pll5p_clk = 792;
+ /* dram = 396MHz */
reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2));
reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(3));
reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(11));
@@ -322,6 +315,13 @@ static void mctl_setup_dram_clock(u32 clk, u32 mbus_clk)
/* setup MBUS clock */
if (!mbus_clk)
mbus_clk = 300;
+
+ /* PLL5P and PLL6 are the potential clock sources for MBUS */
+ pll6x_clk = clock_get_pll6() / 1000000;
+#ifdef CONFIG_SUN7I
+ pll6x_clk *= 2; /* sun7i uses PLL6*2, sun5i uses just PLL6 */
+#endif
+ pll5p_clk = clock_get_pll5p() / 1000000;
pll6x_div = DIV_ROUND_UP(pll6x_clk, mbus_clk);
pll5p_div = DIV_ROUND_UP(pll5p_clk, mbus_clk);
pll6x_rate = pll6x_clk / pll6x_div;
diff --git a/arch/arm/cpu/armv7/sunxi/prcm.c b/arch/arm/cpu/armv7/sunxi/prcm.c
new file mode 100644
index 0000000000..19b4938dc9
--- /dev/null
+++ b/arch/arm/cpu/armv7/sunxi/prcm.c
@@ -0,0 +1,35 @@
+/*
+ * Sunxi A31 Power Management Unit
+ *
+ * (C) Copyright 2013 Oliver Schinagl <oliver@schinagl.nl>
+ * http://linux-sunxi.org
+ *
+ * Based on sun6i sources and earlier U-Boot Allwinner A10 SPL work
+ *
+ * (C) Copyright 2006-2013
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Berg Xing <bergxing@allwinnertech.com>
+ * Tom Cubie <tangliang@allwinnertech.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/prcm.h>
+#include <asm/arch/sys_proto.h>
+
+/* APB0 clock gate and reset bit offsets are the same. */
+void prcm_apb0_enable(u32 flags)
+{
+ struct sunxi_prcm_reg *prcm =
+ (struct sunxi_prcm_reg *)SUNXI_PRCM_BASE;
+
+ /* open the clock for module */
+ setbits_le32(&prcm->apb0_gate, flags);
+
+ /* deassert reset for module */
+ setbits_le32(&prcm->apb0_reset, flags);
+}
diff --git a/arch/arm/include/asm/arch-sunxi/clock.h b/arch/arm/include/asm/arch-sunxi/clock.h
index 5669f392fa..c562f621c2 100644
--- a/arch/arm/include/asm/arch-sunxi/clock.h
+++ b/arch/arm/include/asm/arch-sunxi/clock.h
@@ -15,12 +15,17 @@
#define CLK_GATE_CLOSE 0x0
/* clock control module regs definition */
+#if defined(CONFIG_SUN6I) || defined(CONFIG_SUN8I)
+#include <asm/arch/clock_sun6i.h>
+#else
#include <asm/arch/clock_sun4i.h>
+#endif
#ifndef __ASSEMBLY__
int clock_init(void);
int clock_twi_onoff(int port, int state);
void clock_set_pll1(unsigned int hz);
+unsigned int clock_get_pll5p(void);
unsigned int clock_get_pll6(void);
void clock_init_safe(void);
void clock_init_uart(void);
diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun4i.h b/arch/arm/include/asm/arch-sunxi/clock_sun4i.h
index 1ba997adf9..90af8e2506 100644
--- a/arch/arm/include/asm/arch-sunxi/clock_sun4i.h
+++ b/arch/arm/include/asm/arch-sunxi/clock_sun4i.h
@@ -199,13 +199,16 @@ struct sunxi_ccm_reg {
#define CCM_PLL5_CTRL_M1_MASK CCM_PLL5_CTRL_M1(0x3)
#define CCM_PLL5_CTRL_M1_X(n) ((n) - 1)
#define CCM_PLL5_CTRL_K(n) (((n) & 0x3) << 4)
+#define CCM_PLL5_CTRL_K_SHIFT 4
#define CCM_PLL5_CTRL_K_MASK CCM_PLL5_CTRL_K(0x3)
#define CCM_PLL5_CTRL_K_X(n) ((n) - 1)
#define CCM_PLL5_CTRL_LDO (0x1 << 7)
#define CCM_PLL5_CTRL_N(n) (((n) & 0x1f) << 8)
+#define CCM_PLL5_CTRL_N_SHIFT 8
#define CCM_PLL5_CTRL_N_MASK CCM_PLL5_CTRL_N(0x1f)
#define CCM_PLL5_CTRL_N_X(n) (n)
#define CCM_PLL5_CTRL_P(n) (((n) & 0x3) << 16)
+#define CCM_PLL5_CTRL_P_SHIFT 16
#define CCM_PLL5_CTRL_P_MASK CCM_PLL5_CTRL_P(0x3)
#define CCM_PLL5_CTRL_P_X(n) ((n) - 1)
#define CCM_PLL5_CTRL_BW (0x1 << 18)
diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
new file mode 100644
index 0000000000..1397b35889
--- /dev/null
+++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
@@ -0,0 +1,205 @@
+/*
+ * sun6i clock register definitions
+ *
+ * (C) Copyright 2007-2011
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Tom Cubie <tangliang@allwinnertech.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _SUNXI_CLOCK_SUN6I_H
+#define _SUNXI_CLOCK_SUN6I_H
+
+struct sunxi_ccm_reg {
+ u32 pll1_cfg; /* 0x00 pll1 control */
+ u32 reserved0;
+ u32 pll2_cfg; /* 0x08 pll2 control */
+ u32 reserved1;
+ u32 pll3_cfg; /* 0x10 pll3 control */
+ u32 reserved2;
+ u32 pll4_cfg; /* 0x18 pll4 control */
+ u32 reserved3;
+ u32 pll5_cfg; /* 0x20 pll5 control */
+ u32 reserved4;
+ u32 pll6_cfg; /* 0x28 pll6 control */
+ u32 reserved5;
+ u32 pll7_cfg; /* 0x30 pll7 control */
+ u32 reserved6;
+ u32 pll8_cfg; /* 0x38 pll8 control */
+ u32 reserved7;
+ u32 mipi_pll_cfg; /* 0x40 MIPI pll control */
+ u32 pll9_cfg; /* 0x44 pll9 control */
+ u32 pll10_cfg; /* 0x48 pll10 control */
+ u32 reserved8;
+ u32 cpu_axi_cfg; /* 0x50 CPU/AXI divide ratio */
+ u32 ahb1_apb1_div; /* 0x54 AHB1/APB1 divide ratio */
+ u32 apb2_div; /* 0x58 APB2 divide ratio */
+ u32 axi_gate; /* 0x5c axi module clock gating */
+ u32 ahb_gate0; /* 0x60 ahb module clock gating 0 */
+ u32 ahb_gate1; /* 0x64 ahb module clock gating 1 */
+ u32 apb1_gate; /* 0x68 apb1 module clock gating */
+ u32 apb2_gate; /* 0x6c apb2 module clock gating */
+ u32 reserved9[4];
+ u32 nand0_clk_cfg; /* 0x80 nand0 clock control */
+ u32 nand1_clk_cfg; /* 0x84 nand1 clock control */
+ u32 sd0_clk_cfg; /* 0x88 sd0 clock control */
+ u32 sd1_clk_cfg; /* 0x8c sd1 clock control */
+ u32 sd2_clk_cfg; /* 0x90 sd2 clock control */
+ u32 sd3_clk_cfg; /* 0x94 sd3 clock control */
+ u32 ts_clk_cfg; /* 0x98 transport stream clock control */
+ u32 ss_clk_cfg; /* 0x9c security system clock control */
+ u32 spi0_clk_cfg; /* 0xa0 spi0 clock control */
+ u32 spi1_clk_cfg; /* 0xa4 spi1 clock control */
+ u32 spi2_clk_cfg; /* 0xa8 spi2 clock control */
+ u32 spi3_clk_cfg; /* 0xac spi3 clock control */
+ u32 i2s0_clk_cfg; /* 0xb0 I2S0 clock control*/
+ u32 i2s1_clk_cfg; /* 0xb4 I2S1 clock control */
+ u32 reserved10[2];
+ u32 spdif_clk_cfg; /* 0xc0 SPDIF clock control */
+ u32 reserved11[2];
+ u32 usb_clk_cfg; /* 0xcc USB clock control */
+ u32 gmac_clk_cfg; /* 0xd0 GMAC clock control */
+ u32 reserved12[7];
+ u32 mdfs_clk_cfg; /* 0xf0 MDFS clock control */
+ u32 dram_clk_cfg; /* 0xf4 DRAM configuration clock control */
+ u32 reserved13[2];
+ u32 dram_clk_gate; /* 0x100 DRAM module gating */
+ u32 be0_clk_cfg; /* 0x104 BE0 module clock */
+ u32 be1_clk_cfg; /* 0x108 BE1 module clock */
+ u32 fe0_clk_cfg; /* 0x10c FE0 module clock */
+ u32 fe1_clk_cfg; /* 0x110 FE1 module clock */
+ u32 mp_clk_cfg; /* 0x114 MP module clock */
+ u32 lcd0_ch0_clk_cfg; /* 0x118 LCD0 CH0 module clock */
+ u32 lcd1_ch0_clk_cfg; /* 0x11c LCD1 CH0 module clock */
+ u32 reserved14[3];
+ u32 lcd0_ch1_clk_cfg; /* 0x12c LCD0 CH1 module clock */
+ u32 lcd1_ch1_clk_cfg; /* 0x130 LCD1 CH1 module clock */
+ u32 csi0_clk_cfg; /* 0x134 CSI0 module clock */
+ u32 csi1_clk_cfg; /* 0x138 CSI1 module clock */
+ u32 ve_clk_cfg; /* 0x13c VE module clock */
+ u32 adda_clk_cfg; /* 0x140 ADDA module clock */
+ u32 avs_clk_cfg; /* 0x144 AVS module clock */
+ u32 dmic_clk_cfg; /* 0x148 Digital Mic module clock*/
+ u32 reserved15;
+ u32 hdmi_clk_cfg; /* 0x150 HDMI module clock */
+ u32 ps_clk_cfg; /* 0x154 PS module clock */
+ u32 mtc_clk_cfg; /* 0x158 MTC module clock */
+ u32 mbus0_clk_cfg; /* 0x15c MBUS0 module clock */
+ u32 mbus1_clk_cfg; /* 0x160 MBUS1 module clock */
+ u32 reserved16;
+ u32 mipi_dsi_clk_cfg; /* 0x168 MIPI DSI clock control */
+ u32 mipi_csi_clk_cfg; /* 0x16c MIPI CSI clock control */
+ u32 reserved17[4];
+ u32 iep_drc0_clk_cfg; /* 0x180 IEP DRC0 module clock */
+ u32 iep_drc1_clk_cfg; /* 0x184 IEP DRC1 module clock */
+ u32 iep_deu0_clk_cfg; /* 0x188 IEP DEU0 module clock */
+ u32 iep_deu1_clk_cfg; /* 0x18c IEP DEU1 module clock */
+ u32 reserved18[4];
+ u32 gpu_core_clk_cfg; /* 0x1a0 GPU core clock config */
+ u32 gpu_mem_clk_cfg; /* 0x1a4 GPU memory clock config */
+ u32 gpu_hyd_clk_cfg; /* 0x1a0 GPU HYD clock config */
+ u32 reserved19[21];
+ u32 pll_lock; /* 0x200 PLL Lock Time */
+ u32 pll1_lock; /* 0x204 PLL1 Lock Time */
+ u32 reserved20[6];
+ u32 pll1_bias_cfg; /* 0x220 PLL1 Bias config */
+ u32 pll2_bias_cfg; /* 0x224 PLL2 Bias config */
+ u32 pll3_bias_cfg; /* 0x228 PLL3 Bias config */
+ u32 pll4_bias_cfg; /* 0x22c PLL4 Bias config */
+ u32 pll5_bias_cfg; /* 0x230 PLL5 Bias config */
+ u32 pll6_bias_cfg; /* 0x234 PLL6 Bias config */
+ u32 pll7_bias_cfg; /* 0x238 PLL7 Bias config */
+ u32 pll8_bias_cfg; /* 0x23c PLL8 Bias config */
+ u32 mipi_bias_cfg; /* 0x240 MIPI Bias config */
+ u32 pll9_bias_cfg; /* 0x244 PLL9 Bias config */
+ u32 pll10_bias_cfg; /* 0x248 PLL10 Bias config */
+ u32 reserved21[13];
+ u32 pll1_pattern_cfg; /* 0x280 PLL1 Pattern config */
+ u32 pll2_pattern_cfg; /* 0x284 PLL2 Pattern config */
+ u32 pll3_pattern_cfg; /* 0x288 PLL3 Pattern config */
+ u32 pll4_pattern_cfg; /* 0x28c PLL4 Pattern config */
+ u32 pll5_pattern_cfg; /* 0x290 PLL5 Pattern config */
+ u32 pll6_pattern_cfg; /* 0x294 PLL6 Pattern config */
+ u32 pll7_pattern_cfg; /* 0x298 PLL7 Pattern config */
+ u32 pll8_pattern_cfg; /* 0x29c PLL8 Pattern config */
+ u32 mipi_pattern_cfg; /* 0x2a0 MIPI Pattern config */
+ u32 pll9_pattern_cfg; /* 0x2a4 PLL9 Pattern config */
+ u32 pll10_pattern_cfg; /* 0x2a8 PLL10 Pattern config */
+ u32 reserved22[5];
+ u32 ahb_reset0_cfg; /* 0x2c0 AHB1 Reset 0 config */
+ u32 ahb_reset1_cfg; /* 0x2c4 AHB1 Reset 1 config */
+ u32 ahb_reset2_cfg; /* 0x2c8 AHB1 Reset 2 config */
+ u32 reserved23;
+ u32 apb1_reset_cfg; /* 0x2d0 APB1 Reset config */
+ u32 reserved24;
+ u32 apb2_reset_cfg; /* 0x2d8 APB2 Reset config */
+};
+
+/* apb2 bit field */
+#define APB2_CLK_SRC_LOSC (0x0 << 24)
+#define APB2_CLK_SRC_OSC24M (0x1 << 24)
+#define APB2_CLK_SRC_PLL6 (0x2 << 24)
+#define APB2_CLK_SRC_MASK (0x3 << 24)
+#define APB2_CLK_RATE_N_1 (0x0 << 16)
+#define APB2_CLK_RATE_N_2 (0x1 << 16)
+#define APB2_CLK_RATE_N_4 (0x2 << 16)
+#define APB2_CLK_RATE_N_8 (0x3 << 16)
+#define APB2_CLK_RATE_N_MASK (3 << 16)
+#define APB2_CLK_RATE_M(m) (((m)-1) << 0)
+#define APB2_CLK_RATE_M_MASK (0x1f << 0)
+
+/* apb2 gate field */
+#define APB2_GATE_UART_SHIFT (16)
+#define APB2_GATE_UART_MASK (0xff << APB2_GATE_UART_SHIFT)
+#define APB2_GATE_TWI_SHIFT (0)
+#define APB2_GATE_TWI_MASK (0xf << APB2_GATE_TWI_SHIFT)
+
+/* cpu_axi_cfg bits */
+#define AXI_DIV_SHIFT 0
+#define ATB_DIV_SHIFT 8
+#define CPU_CLK_SRC_SHIFT 16
+
+#define AXI_DIV_1 0
+#define AXI_DIV_2 1
+#define AXI_DIV_3 2
+#define AXI_DIV_4 3
+#define ATB_DIV_1 0
+#define ATB_DIV_2 1
+#define ATB_DIV_4 2
+#define CPU_CLK_SRC_OSC24M 1
+#define CPU_CLK_SRC_PLL1 2
+
+#define PLL1_CFG_DEFAULT 0x90011b21
+
+#define PLL6_CFG_DEFAULT 0x90041811
+
+#define CCM_PLL6_CTRL_N_SHIFT 8
+#define CCM_PLL6_CTRL_N_MASK (0x1f << CCM_PLL6_CTRL_N_SHIFT)
+#define CCM_PLL6_CTRL_K_SHIFT 4
+#define CCM_PLL6_CTRL_K_MASK (0x3 << CCM_PLL6_CTRL_K_SHIFT)
+
+#define AHB_GATE_OFFSET_MMC3 11
+#define AHB_GATE_OFFSET_MMC2 10
+#define AHB_GATE_OFFSET_MMC1 9
+#define AHB_GATE_OFFSET_MMC0 8
+#define AHB_GATE_OFFSET_MMC(n) (AHB_GATE_OFFSET_MMC0 + (n))
+
+#define CCM_MMC_CTRL_OSCM24 (0x0 << 24)
+#define CCM_MMC_CTRL_PLL6 (0x1 << 24)
+
+#define CCM_MMC_CTRL_ENABLE (0x1 << 31)
+
+#define AHB_RESET_OFFSET_MMC3 11
+#define AHB_RESET_OFFSET_MMC2 10
+#define AHB_RESET_OFFSET_MMC1 9
+#define AHB_RESET_OFFSET_MMC0 8
+#define AHB_RESET_OFFSET_MMC(n) (AHB_RESET_OFFSET_MMC0 + (n))
+
+/* apb2 reset */
+#define APB2_RESET_UART_SHIFT (16)
+#define APB2_RESET_UART_MASK (0xff << APB2_RESET_UART_SHIFT)
+#define APB2_RESET_TWI_SHIFT (0)
+#define APB2_RESET_TWI_MASK (0xf << APB2_RESET_TWI_SHIFT)
+
+#endif /* _SUNXI_CLOCK_SUN6I_H */
diff --git a/arch/arm/include/asm/arch-sunxi/cpu.h b/arch/arm/include/asm/arch-sunxi/cpu.h
index a987e51d57..0de79a0d50 100644
--- a/arch/arm/include/asm/arch-sunxi/cpu.h
+++ b/arch/arm/include/asm/arch-sunxi/cpu.h
@@ -95,6 +95,11 @@
#define SUNXI_MALI400_BASE 0x01c40000
#define SUNXI_GMAC_BASE 0x01c50000
+#define SUNXI_DRAM_COM_BASE 0x01c62000
+#define SUNXI_DRAM_CTL_BASE 0x01c63000
+#define SUNXI_DRAM_PHY_CH1_BASE 0x01c65000
+#define SUNXI_DRAM_PHY_CH2_BASE 0x01c66000
+
/* module sram */
#define SUNXI_SRAM_C_BASE 0x01d00000
@@ -105,6 +110,11 @@
#define SUNXI_MP_BASE 0x01e80000
#define SUNXI_AVG_BASE 0x01ea0000
+#define SUNXI_PRCM_BASE 0x01f01400
+#define SUNXI_R_UART_BASE 0x01f02800
+#define SUNXI_R_PIO_BASE 0x01f02c00
+#define SUNXI_P2WI_BASE 0x01f03400
+
/* CoreSight Debug Module */
#define SUNXI_CSDM_BASE 0x3f500000
diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h
index f7f3d8c41a..7bb649950a 100644
--- a/arch/arm/include/asm/arch-sunxi/gpio.h
+++ b/arch/arm/include/asm/arch-sunxi/gpio.h
@@ -10,6 +10,7 @@
#define _SUNXI_GPIO_H
#include <linux/types.h>
+#include <asm/arch/cpu.h>
/*
* sunxi has 9 banks of gpio, they are:
@@ -27,8 +28,27 @@
#define SUNXI_GPIO_G 6
#define SUNXI_GPIO_H 7
#define SUNXI_GPIO_I 8
+
+/*
+ * This defines the number of GPIO banks for the _main_ GPIO controller.
+ * You should fix up the padding in struct sunxi_gpio_reg below if you
+ * change this.
+ */
#define SUNXI_GPIO_BANKS 9
+/*
+ * sun6i/sun8i and later SoCs have an additional GPIO controller (R_PIO)
+ * at a different register offset.
+ *
+ * sun6i has 2 banks:
+ * PL0 - PL8 | PM0 - PM7
+ *
+ * sun8i has 1 bank:
+ * PL0 - PL11
+ */
+#define SUNXI_GPIO_L 11
+#define SUNXI_GPIO_M 12
+
struct sunxi_gpio {
u32 cfg[4];
u32 dat;
@@ -50,8 +70,9 @@ struct sunxi_gpio_reg {
struct sunxi_gpio_int gpio_int;
};
-#define BANK_TO_GPIO(bank) \
- &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[bank]
+#define BANK_TO_GPIO(bank) (((bank) < SUNXI_GPIO_L) ? \
+ &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[bank] : \
+ &((struct sunxi_gpio_reg *)SUNXI_R_PIO_BASE)->gpio_bank[(bank) - SUNXI_GPIO_L])
#define GPIO_BANK(pin) ((pin) >> 5)
#define GPIO_NUM(pin) ((pin) & 0x1f)
@@ -75,6 +96,8 @@ struct sunxi_gpio_reg {
#define SUNXI_GPIO_G_NR 32
#define SUNXI_GPIO_H_NR 32
#define SUNXI_GPIO_I_NR 32
+#define SUNXI_GPIO_L_NR 32
+#define SUNXI_GPIO_M_NR 32
#define SUNXI_GPIO_NEXT(__gpio) \
((__gpio##_START) + (__gpio##_NR) + 0)
@@ -89,6 +112,8 @@ enum sunxi_gpio_number {
SUNXI_GPIO_G_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_F),
SUNXI_GPIO_H_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_G),
SUNXI_GPIO_I_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_H),
+ SUNXI_GPIO_L_START = 352,
+ SUNXI_GPIO_M_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_L),
};
/* SUNXI GPIO number definitions */
@@ -101,6 +126,8 @@ enum sunxi_gpio_number {
#define SUNXI_GPG(_nr) (SUNXI_GPIO_G_START + (_nr))
#define SUNXI_GPH(_nr) (SUNXI_GPIO_H_START + (_nr))
#define SUNXI_GPI(_nr) (SUNXI_GPIO_I_START + (_nr))
+#define SUNXI_GPL(_nr) (SUNXI_GPIO_L_START + (_nr))
+#define SUNXI_GPM(_nr) (SUNXI_GPIO_M_START + (_nr))
/* GPIO pin function config */
#define SUNXI_GPIO_INPUT 0
@@ -117,6 +144,8 @@ enum sunxi_gpio_number {
#define SUN5I_GPB19_UART0_TX 2
#define SUN5I_GPB20_UART0_RX 2
+#define SUN5I_GPG3_SDC1 2
+
#define SUN5I_GPG3_UART1_TX 4
#define SUN5I_GPG4_UART1_RX 4
@@ -125,15 +154,27 @@ enum sunxi_gpio_number {
#define SUNXI_GPF0_SDC0 2
#define SUNXI_GPF2_SDC0 2
+
+#ifdef CONFIG_SUN8I
+#define SUNXI_GPF2_UART0_TX 3
+#define SUNXI_GPF4_UART0_RX 3
+#else
#define SUNXI_GPF2_UART0_TX 4
#define SUNXI_GPF4_UART0_RX 4
+#endif
#define SUN4I_GPG0_SDC1 4
#define SUN4I_GPH22_SDC1 5
+#define SUN6I_GPH20_UART0_TX 2
+#define SUN6I_GPH21_UART0_RX 2
+
#define SUN4I_GPI4_SDC3 2
+#define SUN8I_GPL2_R_UART_TX 2
+#define SUN8I_GPL3_R_UART_RX 2
+
/* GPIO pin pull-up/down config */
#define SUNXI_GPIO_PULL_DISABLE 0
#define SUNXI_GPIO_PULL_UP 1
diff --git a/arch/arm/include/asm/arch-sunxi/mmc.h b/arch/arm/include/asm/arch-sunxi/mmc.h
index 53196e3b02..8a216740a7 100644
--- a/arch/arm/include/asm/arch-sunxi/mmc.h
+++ b/arch/arm/include/asm/arch-sunxi/mmc.h
@@ -43,7 +43,10 @@ struct sunxi_mmc {
u32 chda; /* 0x90 */
u32 cbda; /* 0x94 */
u32 res1[26];
- u32 fifo; /* 0x100 FIFO access address */
+#if defined(CONFIG_SUN6I) || defined(CONFIG_SUN8I)
+ u32 res2[64];
+#endif
+ u32 fifo; /* 0x100 (0x200 on sun6i) FIFO access address */
};
#define SUNXI_MMC_CLK_POWERSAVE (0x1 << 17)
@@ -120,5 +123,5 @@ struct sunxi_mmc {
#define SUNXI_MMC_IDIE_TXIRQ (0x1 << 0)
#define SUNXI_MMC_IDIE_RXIRQ (0x1 << 1)
-int sunxi_mmc_init(int sdc_no);
+struct mmc *sunxi_mmc_init(int sdc_no);
#endif /* _SUNXI_MMC_H */
diff --git a/arch/arm/include/asm/arch-sunxi/prcm.h b/arch/arm/include/asm/arch-sunxi/prcm.h
new file mode 100644
index 0000000000..3d3bfa6cd1
--- /dev/null
+++ b/arch/arm/include/asm/arch-sunxi/prcm.h
@@ -0,0 +1,238 @@
+/*
+ * Sunxi A31 Power Management Unit register definition.
+ *
+ * (C) Copyright 2013 Oliver Schinagl <oliver@schinagl.nl>
+ * http://linux-sunxi.org
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Berg Xing <bergxing@allwinnertech.com>
+ * Tom Cubie <tangliang@allwinnertech.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _SUNXI_PRCM_H
+#define _SUNXI_PRCM_H
+
+#define __PRCM_CPUS_CFG_PRE(n) (((n) & 0x3) << 4)
+#define PRCM_CPUS_CFG_PRE_MASK __PRCM_CPUS_CFG_PRE(0x3)
+#define __PRCM_CPUS_CFG_PRE_DIV(n) (((n) >> 1) - 1)
+#define PRCM_CPUS_CFG_PRE_DIV(n) \
+ __PRCM_CPUS_CFG_PRE(__PRCM_CPUS_CFG_CLK_PRE(n))
+#define __PRCM_CPUS_CFG_POST(n) (((n) & 0x1f) << 8)
+#define PRCM_CPUS_CFG_POST_MASK __PRCM_CPUS_CFG_POST(0x1f)
+#define __PRCM_CPUS_CFG_POST_DIV(n) ((n) - 1)
+#define PRCM_CPUS_CFG_POST_DIV(n) \
+ __PRCM_CPUS_CFG_POST_DIV(__PRCM_CPUS_CFG_POST_DIV(n))
+#define __PRCM_CPUS_CFG_CLK_SRC(n) (((n) & 0x3) << 16)
+#define PRCM_CPUS_CFG_CLK_SRC_MASK __PRCM_CPUS_CFG_CLK_SRC(0x3)
+#define __PRCM_CPUS_CFG_CLK_SRC_LOSC 0x0
+#define __PRCM_CPUS_CFG_CLK_SRC_HOSC 0x1
+#define __PRCM_CPUS_CFG_CLK_SRC_PLL6 0x2
+#define __PRCM_CPUS_CFG_CLK_SRC_PDIV 0x3
+#define PRCM_CPUS_CFG_CLK_SRC_LOSC \
+ __PRCM_CPUS_CFG_CLK_SRC(__PRCM_CPUS_CFG_CLK_SRC_LOSC)
+#define PRCM_CPUS_CFG_CLK_SRC_HOSC \
+ __PRCM_CPUS_CFG_CLK_SRC(__PRCM_CPUS_CFG_CLK_SRC_HOSC)
+#define PRCM_CPUS_CFG_CLK_SRC_PLL6 \
+ __PRCM_CPUS_CFG_CLK_SRC(__PRCM_CPUS_CFG_CLK_SRC_PLL6)
+#define PRCM_CPUS_CFG_CLK_SRC_PDIV \
+ __PRCM_CPUS_CFG_CLK_SRC(__PRCM_CPUS_CFG_CLK_SRC_PDIV)
+
+#define __PRCM_APB0_RATIO(n) (((n) & 0x3) << 0)
+#define PRCM_APB0_RATIO_DIV_MASK __PRCM_APB0_RATIO_DIV(0x3)
+#define __PRCM_APB0_RATIO_DIV(n) (((n) >> 1) - 1)
+#define PRCM_APB0_RATIO_DIV(n) \
+ __PRCM_APB0_RATIO(__PRCM_APB0_RATIO_DIV(n))
+
+#define PRCM_CPU_CFG_NEON_CLK_EN (0x1 << 0)
+#define PRCM_CPU_CFG_CPU_CLK_EN (0x1 << 1)
+
+#define PRCM_APB0_GATE_PIO (0x1 << 0)
+#define PRCM_APB0_GATE_IR (0x1 << 1)
+#define PRCM_APB0_GATE_TIMER01 (0x1 << 2)
+#define PRCM_APB0_GATE_P2WI (0x1 << 3)
+#define PRCM_APB0_GATE_UART (0x1 << 4)
+#define PRCM_APB0_GATE_1WIRE (0x1 << 5)
+#define PRCM_APB0_GATE_I2C (0x1 << 6)
+
+#define PRCM_APB0_RESET_PIO (0x1 << 0)
+#define PRCM_APB0_RESET_IR (0x1 << 1)
+#define PRCM_APB0_RESET_TIMER01 (0x1 << 2)
+#define PRCM_APB0_RESET_P2WI (0x1 << 3)
+#define PRCM_APB0_RESET_UART (0x1 << 4)
+#define PRCM_APB0_RESET_1WIRE (0x1 << 5)
+#define PRCM_APB0_RESET_I2C (0x1 << 6)
+
+#define PRCM_PLL_CTRL_PLL_BIAS (0x1 << 0)
+#define PRCM_PLL_CTRL_HOSC_GAIN_ENH (0x1 << 1)
+#define __PRCM_PLL_CTRL_USB_CLK_SRC(n) (((n) & 0x3) << 4)
+#define PRCM_PLL_CTRL_USB_CLK_SRC_MASK \
+ __PRCM_PLL_CTRL_USB_CLK_SRC(0x3)
+#define __PRCM_PLL_CTRL_USB_CLK_0 0x0
+#define __PRCM_PLL_CTRL_USB_CLK_1 0x1
+#define __PRCM_PLL_CTRL_USB_CLK_2 0x2
+#define __PRCM_PLL_CTRL_USB_CLK_3 0x3
+#define PRCM_PLL_CTRL_USB_CLK_0 \
+ __PRCM_PLL_CTRL_USB_CLK_SRC(__PRCM_PLL_CTRL_USB_CLK_0)
+#define PRCM_PLL_CTRL_USB_CLK_1 \
+ __PRCM_PLL_CTRL_USB_CLK_SRC(__PRCM_PLL_CTRL_USB_CLK_1)
+#define PRCM_PLL_CTRL_USB_CLK_2 \
+ __PRCM_PLL_CTRL_USB_CLK_SRC(__PRCM_PLL_CTRL_USB_CLK_2)
+#define PRCM_PLL_CTRL_USB_CLK_3 \
+ __PRCM_PLL_CTRL_USB_CLK_SRC(__PRCM_PLL_CTRL_USB_CLK_3)
+#define __PRCM_PLL_CTRL_INT_PLL_IN_SEL(n) (((n) & 0x3) << 12)
+#define PRCM_PLL_CTRL_INT_PLL_IN_SEL_MASK \
+ __PRCM_PLL_CTRL_INT_PLL_IN_SEL(0x3)
+#define PRCM_PLL_CTRL_INT_PLL_IN_SEL(n) \
+ __PRCM_PLL_CTRL_INT_PLL_IN_SEL(n)
+#define __PRCM_PLL_CTRL_HOSC_CLK_SEL(n) (((n) & 0x3) << 20)
+#define PRCM_PLL_CTRL_HOSC_CLK_SEL_MASK \
+ __PRCM_PLL_CTRL_HOSC_CLK_SEL(0x3)
+#define __PRCM_PLL_CTRL_HOSC_CLK_0 0x0
+#define __PRCM_PLL_CTRL_HOSC_CLK_1 0x1
+#define __PRCM_PLL_CTRL_HOSC_CLK_2 0x2
+#define __PRCM_PLL_CTRL_HOSC_CLK_3 0x3
+#define PRCM_PLL_CTRL_HOSC_CLK_0 \
+ __PRCM_PLL_CTRL_HOSC_CLK_SEL(__PRCM_PLL_CTRL_HOSC_CLK_0)
+#define PRCM_PLL_CTRL_HOSC_CLK_1 \
+ __PRCM_PLL_CTRL_HOSC_CLK_SEL(__PRCM_PLL_CTRL_HOSC_CLK_1)
+#define PRCM_PLL_CTRL_HOSC_CLK_2 \
+ __PRCM_PLL_CTRL_HOSC_CLK_SEL(__PRCM_PLL_CTRL_HOSC_CLK_2)
+#define PRCM_PLL_CTRL_HOSC_CLK_3 \
+ __PRCM_PLL_CTRL_HOSC_CLK_SEL(__PRCM_PLL_CTRL_HOSC_CLK_3)
+#define PRCM_PLL_CTRL_PLL_TST_SRC_EXT (0x1 << 24)
+#define PRCM_PLL_CTRL_LDO_DIGITAL_EN (0x1 << 0)
+#define PRCM_PLL_CTRL_LDO_ANALOG_EN (0x1 << 1)
+#define PRCM_PLL_CTRL_EXT_OSC_EN (0x1 << 2)
+#define PRCM_PLL_CTRL_CLK_TST_EN (0x1 << 3)
+#define PRCM_PLL_CTRL_IN_PWR_HIGH (0x1 << 15) /* 3.3 for hi 2.5 for lo */
+#define __PRCM_PLL_CTRL_VDD_LDO_OUT(n) (((n) & 0x7) << 16)
+#define PRCM_PLL_CTRL_LDO_OUT_MASK \
+ __PRCM_PLL_CTRL_LDO_OUT(0x7)
+/* When using the low voltage 20 mV steps, and high voltage 30 mV steps */
+#define PRCM_PLL_CTRL_LDO_OUT_L(n) \
+ __PRCM_PLL_CTRL_VDD_LDO_OUT((((n) - 1000) / 20) & 0x7)
+#define PRCM_PLL_CTRL_LDO_OUT_H(n) \
+ __PRCM_PLL_CTRL_VDD_LDO_OUT((((n) - 1160) / 30) & 0x7)
+#define PRCM_PLL_CTRL_LDO_OUT_LV(n) \
+ __PRCM_PLL_CTRL_VDD_LDO_OUT((((n) & 0x7) * 20) + 1000)
+#define PRCM_PLL_CTRL_LDO_OUT_HV(n) \
+ __PRCM_PLL_CTRL_VDD_LDO_OUT((((n) & 0x7) * 30) + 1160)
+#define PRCM_PLL_CTRL_LDO_KEY (0xa7 << 24)
+
+#define PRCM_CLK_1WIRE_GATE (0x1 << 31)
+
+#define __PRCM_CLK_MOD0_M(n) (((n) & 0xf) << 0)
+#define PRCM_CLK_MOD0_M_MASK __PRCM_CLK_MOD0_M(0xf)
+#define __PRCM_CLK_MOD0_M_X(n) (n - 1)
+#define PRCM_CLK_MOD0_M(n) __PRCM_CLK_MOD0_M(__PRCM_CLK_MOD0_M_X(n))
+#define PRCM_CLK_MOD0_OUT_PHASE(n) (((n) & 0x7) << 8)
+#define PRCM_CLK_MOD0_OUT_PHASE_MASK(n) PRCM_CLK_MOD0_OUT_PHASE(0x7)
+#define _PRCM_CLK_MOD0_N(n) (((n) & 0x3) << 16)
+#define PRCM_CLK_MOD0_N_MASK __PRCM_CLK_MOD_N(0x3)
+#define __PRCM_CLK_MOD0_N_X(n) (((n) >> 1) - 1)
+#define PRCM_CLK_MOD0_N(n) __PRCM_CLK_MOD0_N(__PRCM_CLK_MOD0_N_X(n))
+#define PRCM_CLK_MOD0_SMPL_PHASE(n) (((n) & 0x7) << 20)
+#define PRCM_CLK_MOD0_SMPL_PHASE_MASK PRCM_CLK_MOD0_SMPL_PHASE(0x7)
+#define PRCM_CLK_MOD0_SRC_SEL(n) (((n) & 0x7) << 24)
+#define PRCM_CLK_MOD0_SRC_SEL_MASK PRCM_CLK_MOD0_SRC_SEL(0x7)
+#define PRCM_CLK_MOD0_GATE_EN (0x1 << 31)
+
+#define PRCM_APB0_RESET_PIO (0x1 << 0)
+#define PRCM_APB0_RESET_IR (0x1 << 1)
+#define PRCM_APB0_RESET_TIMER01 (0x1 << 2)
+#define PRCM_APB0_RESET_P2WI (0x1 << 3)
+#define PRCM_APB0_RESET_UART (0x1 << 4)
+#define PRCM_APB0_RESET_1WIRE (0x1 << 5)
+#define PRCM_APB0_RESET_I2C (0x1 << 6)
+
+#define __PRCM_CLK_OUTD_M(n) (((n) & 0x7) << 8)
+#define PRCM_CLK_OUTD_M_MASK __PRCM_CLK_OUTD_M(0x7)
+#define __PRCM_CLK_OUTD_M_X() ((n) - 1)
+#define PRCM_CLK_OUTD_M(n) __PRCM_CLK_OUTD_M(__PRCM_CLK_OUTD_M_X(n))
+#define __PRCM_CLK_OUTD_N(n) (((n) & 0x7) << 20)
+#define PRCM_CLK_OUTD_N_MASK __PRCM_CLK_OUTD_N(0x7)
+#define __PRCM_CLK_OUTD_N_X(n) (((n) >> 1) - 1)
+#define PRCM_CLK_OUTD_N(n) __PRCM_CLK_OUTD_N(__PRCM_CLK_OUTD_N_X(n)
+#define __PRCM_CLK_OUTD_SRC_SEL(n) (((n) & 0x3) << 24)
+#define PRCM_CLK_OUTD_SRC_SEL_MASK __PRCM_CLK_OUTD_SRC_SEL(0x3)
+#define __PRCM_CLK_OUTD_SRC_LOSC2 0x0
+#define __PRCM_CLK_OUTD_SRC_LOSC 0x1
+#define __PRCM_CLK_OUTD_SRC_HOSC 0x2
+#define __PRCM_CLK_OUTD_SRC_ERR 0x3
+#define PRCM_CLK_OUTD_SRC_LOSC2 \
+#deifne __PRCM_CLK_OUTD_SRC_SEL(__PRCM_CLK_OUTD_SRC_LOSC2)
+#define PRCM_CLK_OUTD_SRC_LOSC \
+#deifne __PRCM_CLK_OUTD_SRC_SEL(__PRCM_CLK_OUTD_SRC_LOSC)
+#define PRCM_CLK_OUTD_SRC_HOSC \
+#deifne __PRCM_CLK_OUTD_SRC_SEL(__PRCM_CLK_OUTD_SRC_HOSC)
+#define PRCM_CLK_OUTD_SRC_ERR \
+#deifne __PRCM_CLK_OUTD_SRC_SEL(__PRCM_CLK_OUTD_SRC_ERR)
+#define PRCM_CLK_OUTD_EN (0x1 << 31)
+
+#define PRCM_CPU0_PWROFF (0x1 << 0)
+#define PRCM_CPU1_PWROFF (0x1 << 1)
+#define PRCM_CPU2_PWROFF (0x1 << 2)
+#define PRCM_CPU3_PWROFF (0x1 << 3)
+#define PRCM_CPU_ALL_PWROFF (0xf << 0)
+
+#define PRCM_VDD_SYS_DRAM_CH0_PAD_HOLD_PWROFF (0x1 << 0)
+#define PRCM_VDD_SYS_DRAM_CH1_PAD_HOLD_PWROFF (0x1 << 1)
+#define PRCM_VDD_SYS_AVCC_A_PWROFF (0x1 << 2)
+#define PRCM_VDD_SYS_CPU0_VDD_PWROFF (0x1 << 3)
+
+#define PRCM_VDD_GPU_PWROFF (0x1 << 0)
+
+#define PRCM_VDD_SYS_RESET (0x1 << 0)
+
+#define PRCM_CPU1_PWR_CLAMP(n) (((n) & 0xff) << 0)
+#define PRCM_CPU1_PWR_CLAMP_MASK PRCM_CPU1_PWR_CLAMP(0xff)
+
+#define PRCM_CPU2_PWR_CLAMP(n) (((n) & 0xff) << 0)
+#define PRCM_CPU2_PWR_CLAMP_MASK PRCM_CPU2_PWR_CLAMP(0xff)
+
+#define PRCM_CPU3_PWR_CLAMP(n) (((n) & 0xff) << 0)
+#define PRCM_CPU3_PWR_CLAMP_MASK PRCM_CPU3_PWR_CLAMP(0xff)
+
+#ifndef __ASSEMBLY__
+struct sunxi_prcm_reg {
+ u32 cpus_cfg; /* 0x000 */
+ u8 res0[0x8]; /* 0x004 */
+ u32 apb0_ratio; /* 0x00c */
+ u32 cpu0_cfg; /* 0x010 */
+ u32 cpu1_cfg; /* 0x014 */
+ u32 cpu2_cfg; /* 0x018 */
+ u32 cpu3_cfg; /* 0x01c */
+ u8 res1[0x8]; /* 0x020 */
+ u32 apb0_gate; /* 0x028 */
+ u8 res2[0x14]; /* 0x02c */
+ u32 pll_ctrl0; /* 0x040 */
+ u32 pll_ctrl1; /* 0x044 */
+ u8 res3[0x8]; /* 0x048 */
+ u32 clk_1wire; /* 0x050 */
+ u32 clk_ir; /* 0x054 */
+ u8 res4[0x58]; /* 0x058 */
+ u32 apb0_reset; /* 0x0b0 */
+ u8 res5[0x3c]; /* 0x0b4 */
+ u32 clk_outd; /* 0x0f0 */
+ u8 res6[0xc]; /* 0x0f4 */
+ u32 cpu_pwroff; /* 0x100 */
+ u8 res7[0xc]; /* 0x104 */
+ u32 vdd_sys_pwroff; /* 0x110 */
+ u8 res8[0x4]; /* 0x114 */
+ u32 gpu_pwroff; /* 0x118 */
+ u8 res9[0x4]; /* 0x11c */
+ u32 vdd_pwr_reset; /* 0x120 */
+ u8 res10[0x20]; /* 0x124 */
+ u32 cpu1_pwr_clamp; /* 0x144 */
+ u32 cpu2_pwr_clamp; /* 0x148 */
+ u32 cpu3_pwr_clamp; /* 0x14c */
+ u8 res11[0x30]; /* 0x150 */
+ u32 dram_pwr; /* 0x180 */
+ u8 res12[0xc]; /* 0x184 */
+ u32 dram_tst; /* 0x190 */
+};
+
+void prcm_apb0_enable(u32 flags);
+#endif /* __ASSEMBLY__ */
+#endif /* _PRCM_H */
diff --git a/arch/arm/include/asm/arch-sunxi/timer.h b/arch/arm/include/asm/arch-sunxi/timer.h
index 58e14fd0f7..03a0684c79 100644
--- a/arch/arm/include/asm/arch-sunxi/timer.h
+++ b/arch/arm/include/asm/arch-sunxi/timer.h
@@ -11,14 +11,10 @@
#ifndef _SUNXI_TIMER_H_
#define _SUNXI_TIMER_H_
-#define WDT_CTRL_RESTART (0x1 << 0)
-#define WDT_CTRL_KEY (0x0a57 << 1)
-#define WDT_MODE_EN (0x1 << 0)
-#define WDT_MODE_RESET_EN (0x1 << 1)
-
#ifndef __ASSEMBLY__
#include <linux/types.h>
+#include <asm/arch/watchdog.h>
/* General purpose timer */
struct sunxi_timer {
@@ -43,12 +39,6 @@ struct sunxi_64cnt {
u32 hi; /* 0xa8 */
};
-/* Watchdog */
-struct sunxi_wdog {
- u32 ctl; /* 0x90 */
- u32 mode; /* 0x94 */
-};
-
/* Rtc */
struct sunxi_rtc {
u32 ctl; /* 0x100 */
@@ -77,15 +67,20 @@ struct sunxi_timer_reg {
struct sunxi_timer timer[6]; /* We have 6 timers */
u8 res2[16];
struct sunxi_avs avs;
- struct sunxi_wdog wdog;
- u8 res3[8];
- struct sunxi_64cnt cnt64;
+#if defined(CONFIG_SUN4I) || defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)
+ struct sunxi_wdog wdog; /* 0x90 */
+ /* XXX the following is not accurate for sun5i/sun7i */
+ struct sunxi_64cnt cnt64; /* 0xa0 */
u8 res4[0x58];
struct sunxi_rtc rtc;
struct sunxi_alarm alarm;
struct sunxi_tgp tgp[4];
u8 res5[8];
u32 cpu_cfg;
+#else /* CONFIG_SUN6I || CONFIG_SUN8I || ... */
+ u8 res3[16];
+ struct sunxi_wdog wdog[5]; /* We have 5 watchdogs */
+#endif
};
#endif /* __ASSEMBLY__ */
diff --git a/arch/arm/include/asm/arch-sunxi/watchdog.h b/arch/arm/include/asm/arch-sunxi/watchdog.h
new file mode 100644
index 0000000000..ccc8fa32c4
--- /dev/null
+++ b/arch/arm/include/asm/arch-sunxi/watchdog.h
@@ -0,0 +1,44 @@
+/*
+ * (C) Copyright 2014
+ * Chen-Yu Tsai <wens@csie.org>
+ *
+ * Watchdog register definitions
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _SUNXI_WATCHDOG_H_
+#define _SUNXI_WATCHDOG_H_
+
+#define WDT_CTRL_RESTART (0x1 << 0)
+#define WDT_CTRL_KEY (0x0a57 << 1)
+
+#if defined(CONFIG_SUN4I) || defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)
+
+#define WDT_MODE_EN (0x1 << 0)
+#define WDT_MODE_RESET_EN (0x1 << 1)
+
+struct sunxi_wdog {
+ u32 ctl; /* 0x00 */
+ u32 mode; /* 0x04 */
+ u32 res[2];
+};
+
+#else
+
+#define WDT_CFG_RESET (0x1)
+#define WDT_MODE_EN (0x1)
+
+struct sunxi_wdog {
+ u32 irq_en; /* 0x00 */
+ u32 irq_sta; /* 0x04 */
+ u32 res1[2];
+ u32 ctl; /* 0x10 */
+ u32 cfg; /* 0x14 */
+ u32 mode; /* 0x18 */
+ u32 res2;
+};
+
+#endif
+
+#endif /* _SUNXI_WATCHDOG_H_ */