From ea520947b125ebd7ce63fae2cbfb6937727eae0a Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Fri, 3 Oct 2014 20:16:21 +0800 Subject: ARM: sunxi: Use macro values for setting UART GPIO pull-ups We have already defined macros for pull-up/down values in the GPIO header. Use them instead of magic numbers when configuring the UART pins. Signed-off-by: Chen-Yu Tsai Acked-by: Ian Campbell --- arch/arm/cpu/armv7/sunxi/board.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c index f2cedbb1568..95a74c5c06a 100644 --- a/arch/arm/cpu/armv7/sunxi/board.c +++ b/arch/arm/cpu/armv7/sunxi/board.c @@ -53,15 +53,15 @@ int gpio_init(void) #if 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 == 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); #else #error Unsupported console port number. Please fix pin mux settings in board.c #endif -- cgit v1.2.3 From 93ce1e9dad42e23e5938b601c36172e8baa1b675 Mon Sep 17 00:00:00 2001 From: Oliver Schinagl Date: Fri, 3 Oct 2014 20:16:23 +0800 Subject: ARM: sun6i: Add base address for the new controllers in A31 A31 has several new and changed memory address. This patch adds them. Signed-off-by: Oliver Schinagl Signed-off-by: Hans de Goede Signed-off-by: Chen-Yu Tsai Acked-by: Ian Campbell --- arch/arm/include/asm/arch-sunxi/cpu.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/include/asm/arch-sunxi/cpu.h b/arch/arm/include/asm/arch-sunxi/cpu.h index a987e51d576..313e6c849d9 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,10 @@ #define SUNXI_MP_BASE 0x01e80000 #define SUNXI_AVG_BASE 0x01ea0000 +#define SUNXI_PRCM_BASE 0x01f01400 +#define SUNXI_R_PIO_BASE 0x01f02c00 +#define SUNXI_P2WI_BASE 0x01f03400 + /* CoreSight Debug Module */ #define SUNXI_CSDM_BASE 0x3f500000 -- cgit v1.2.3 From 174deb768c65969a3bcdab4dfbcdcb02abe9f09e Mon Sep 17 00:00:00 2001 From: Oliver Schinagl Date: Fri, 3 Oct 2014 20:16:24 +0800 Subject: ARM: sun6i: Add support for the power reset control module found on the A31 The A31 has a new module called PRCM, or Power, Reset Control Module. This module controls clocks and resets for RTC block modules, and also PLL biasing in the main clock module. This patch adds the register definitions, and also enables the clocks and resets for the RTC block PIO (pin controller) and P2WI (push-pull 2 wire interface) which is used to talk to the PMIC. Signed-off-by: Oliver Schinagl Signed-off-by: Hans de Goede [wens@csie.org: spacing fixes reported by checkpatch.pl] [wens@csie.org: Use setbits helper in PRCM init function] [wens@csie.org: rephrase commit message to explain what the hardware supports and what we actually enable] Signed-off-by: Chen-Yu Tsai Acked-by: Ian Campbell --- arch/arm/cpu/armv7/sunxi/Makefile | 1 + arch/arm/cpu/armv7/sunxi/prcm.c | 33 +++++ arch/arm/include/asm/arch-sunxi/prcm.h | 238 +++++++++++++++++++++++++++++++++ 3 files changed, 272 insertions(+) create mode 100644 arch/arm/cpu/armv7/sunxi/prcm.c create mode 100644 arch/arm/include/asm/arch-sunxi/prcm.h (limited to 'arch/arm') diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile index e9721b27b64..f0473d2ab87 100644 --- a/arch/arm/cpu/armv7/sunxi/Makefile +++ b/arch/arm/cpu/armv7/sunxi/Makefile @@ -11,6 +11,7 @@ obj-y += timer.o obj-y += board.o obj-y += clock.o obj-y += pinmux.o +obj-$(CONFIG_SUN6I) += prcm.o obj-$(CONFIG_SUN4I) += clock_sun4i.o obj-$(CONFIG_SUN5I) += clock_sun4i.o obj-$(CONFIG_SUN7I) += clock_sun4i.o diff --git a/arch/arm/cpu/armv7/sunxi/prcm.c b/arch/arm/cpu/armv7/sunxi/prcm.c new file mode 100644 index 00000000000..7b3ee893026 --- /dev/null +++ b/arch/arm/cpu/armv7/sunxi/prcm.c @@ -0,0 +1,33 @@ +/* + * Sunxi A31 Power Management Unit + * + * (C) Copyright 2013 Oliver Schinagl + * http://linux-sunxi.org + * + * Based on sun6i sources and earlier U-Boot Allwinner A10 SPL work + * + * (C) Copyright 2006-2013 + * Allwinner Technology Co., Ltd. + * Berg Xing + * Tom Cubie + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include + +void prcm_init_apb0(void) +{ + struct sunxi_prcm_reg *prcm = + (struct sunxi_prcm_reg *)SUNXI_PRCM_BASE; + + setbits_le32(&prcm->apb0_gate, PRCM_APB0_GATE_P2WI | + PRCM_APB0_GATE_PIO); + setbits_le32(&prcm->apb0_reset, PRCM_APB0_RESET_P2WI | + PRCM_APB0_RESET_PIO); +} 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 00000000000..1b40f094f51 --- /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 + * http://linux-sunxi.org + * Allwinner Technology Co., Ltd. + * Berg Xing + * Tom Cubie + * + * 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_init_apb0(void); +#endif /* __ASSEMBLY__ */ +#endif /* _PRCM_H */ -- cgit v1.2.3 From 14177e47e856a59812e8150c889e4fcdb6316dbe Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Fri, 3 Oct 2014 20:16:25 +0800 Subject: ARM: sun6i: Add clock support This patch adds the basic clocks support for the Allwinner A31 (sun6i) processor. This code will not been compiled until the build is hooked up in a later patch. It has been split out to keep the patches manageable. This includes changes from the following commits from u-boot-sunxi: a92051b ARM: sunxi: Add sun6i clock controller structure 1f72c6f ARM: sun6i: Setup the UART0 clocks 5f2e712 ARM: sunxi: Enable pll6 by default on all models 2be2f2a ARM: sunxi-mmc: Add mmc support for sun6i / A31 12e1633 ARM: sun6i: Add initial clock setup for SPL 1a9c9c6 ARM: sunxi: Split clock code into common, sun4i and sun6i code 0b194ee ARM: sun6i: Properly setup the PLL LDO in clock_init_safe b54c626 sunxi: avoid sr32 for APB1 clock setup. 68fe29c sunxi: remove magic numbers from clock_get_pll{5,6} c89867d sunxi: clocks: clock_get_pll5 prototype and coding style 501ab1e ARM: sunxi: Fix sun6i PLL6 settings 37f669b ARM: sunxi: Fix macro names for mmc and uart reset offsets 61de1e6 ARM: sunxi: Correct comment for MBUS1 register in sun6i clock definitions Signed-off-by: Maxime Ripard Signed-off-by: Ian Campbell Signed-off-by: Hans de Goede [wens@csie.org: styling fixes reported by checkpatch.pl] [wens@csie.org: drop unsupported SPL code block and unused gpio.h header] Signed-off-by: Chen-Yu Tsai Cc: Tom Cubie Acked-by: Ian Campbell --- arch/arm/cpu/armv7/sunxi/Makefile | 1 + arch/arm/cpu/armv7/sunxi/clock_sun6i.c | 70 +++++++++ arch/arm/include/asm/arch-sunxi/clock.h | 4 + arch/arm/include/asm/arch-sunxi/clock_sun6i.h | 205 ++++++++++++++++++++++++++ 4 files changed, 280 insertions(+) create mode 100644 arch/arm/cpu/armv7/sunxi/clock_sun6i.c create mode 100644 arch/arm/include/asm/arch-sunxi/clock_sun6i.h (limited to 'arch/arm') diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile index f0473d2ab87..2a42dcaaa20 100644 --- a/arch/arm/cpu/armv7/sunxi/Makefile +++ b/arch/arm/cpu/armv7/sunxi/Makefile @@ -14,6 +14,7 @@ obj-y += pinmux.o obj-$(CONFIG_SUN6I) += 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 ifndef CONFIG_SPL_BUILD 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 00000000000..8387b931aa8 --- /dev/null +++ b/arch/arm/cpu/armv7/sunxi/clock_sun6i.c @@ -0,0 +1,70 @@ +/* + * sun6i specific clock code + * + * (C) Copyright 2007-2012 + * Allwinner Technology Co., Ltd. + * Tom Cubie + * + * (C) Copyright 2013 Luke Kenneth Casson Leighton + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +void clock_init_uart(void) +{ + struct sunxi_ccm_reg *const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + + /* 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)); + + /* 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/include/asm/arch-sunxi/clock.h b/arch/arm/include/asm/arch-sunxi/clock.h index 5669f392fab..8f5d86025b3 100644 --- a/arch/arm/include/asm/arch-sunxi/clock.h +++ b/arch/arm/include/asm/arch-sunxi/clock.h @@ -15,7 +15,11 @@ #define CLK_GATE_CLOSE 0x0 /* clock control module regs definition */ +#ifdef CONFIG_SUN6I +#include +#else #include +#endif #ifndef __ASSEMBLY__ int clock_init(void); 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 00000000000..1397b358898 --- /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. + * Tom Cubie + * + * 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 */ -- cgit v1.2.3 From 1d1bd42eb08b267a0884a0fa04483daeda169f6d Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 3 Oct 2014 20:16:26 +0800 Subject: ARM: sunxi-mmc: Add mmc support for sun6i / A31 The mmc hardware on sun6i has an extra reset control that needs to be de-asserted prior to usage. Also the FIFO address is different. Signed-off-by: Hans de Goede [wens@csie.org: use setbits_le32 for reset control, drop obsolete changes, rewrite different FIFO address handling, add commit message] Signed-off-by: Chen-Yu Tsai Acked-by: Ian Campbell --- arch/arm/include/asm/arch-sunxi/mmc.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'arch/arm') diff --git a/arch/arm/include/asm/arch-sunxi/mmc.h b/arch/arm/include/asm/arch-sunxi/mmc.h index 53196e3b024..6a3118402f4 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) + u32 res2[64]; +#endif + u32 fifo; /* 0x100 (0x200 on sun6i) FIFO access address */ }; #define SUNXI_MMC_CLK_POWERSAVE (0x1 << 17) -- cgit v1.2.3 From ba1e40fdd3096d2b9a421ac03285bd49bf837959 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Fri, 3 Oct 2014 20:16:27 +0800 Subject: ARM: sun6i: Define UART0 pins for A31 UART0 is the default debug/console UART on the A31. Signed-off-by: Chen-Yu Tsai Acked-by: Ian Campbell --- arch/arm/include/asm/arch-sunxi/gpio.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h index f7f3d8c41ad..ba7e69b7b7e 100644 --- a/arch/arm/include/asm/arch-sunxi/gpio.h +++ b/arch/arm/include/asm/arch-sunxi/gpio.h @@ -132,6 +132,9 @@ enum sunxi_gpio_number { #define SUN4I_GPH22_SDC1 5 +#define SUN6I_GPH20_UART0_TX 2 +#define SUN6I_GPH21_UART0_RX 2 + #define SUN4I_GPI4_SDC3 2 /* GPIO pin pull-up/down config */ -- cgit v1.2.3 From 7711539734ac71e2156b4b04464dbffa849cd4fc Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Fri, 3 Oct 2014 20:16:28 +0800 Subject: ARM: sun6i: Setup the A31 UART0 muxing Signed-off-by: Maxime Ripard Signed-off-by: Hans de Goede [wens@csie.org: commit message was "ARM: sunxi: Setup the A31 UART0 muxing"] [wens@csie.org: reorder #ifs by SUN?I] [wens@csie.org: replace magic numbers with GPIO definitions] Signed-off-by: Chen-Yu Tsai Acked-by: Ian Campbell --- arch/arm/cpu/armv7/sunxi/board.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c index 95a74c5c06a..b6d63dbb409 100644 --- a/arch/arm/cpu/armv7/sunxi/board.c +++ b/arch/arm/cpu/armv7/sunxi/board.c @@ -58,6 +58,10 @@ int gpio_init(void) 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), 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); -- cgit v1.2.3 From 8a6564dacb7e24e82077d109d7d5992d2a14dac3 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Fri, 3 Oct 2014 20:16:29 +0800 Subject: ARM: sunxi: Add basic A31 support Add a new sun6i machine that supports UART and MMC. Signed-off-by: Maxime Ripard Signed-off-by: Hans de Goede [wens@csie.org: use SPDX labels, adapt to Kconfig system, drop ifdef around mmc and smp code, drop MACH_TYPE] Signed-off-by: Chen-Yu Tsai Acked-by: Ian Campbell --- arch/arm/Kconfig | 3 +++ arch/arm/cpu/armv7/sunxi/cpu_info.c | 2 ++ 2 files changed, 5 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 109d49f57db..4317b69e361 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -450,6 +450,9 @@ config TARGET_SUN4I config TARGET_SUN5I bool "Support sun5i" +config TARGET_SUN6I + bool "Support sun6i" + config TARGET_SUN7I bool "Support sun7i" diff --git a/arch/arm/cpu/armv7/sunxi/cpu_info.c b/arch/arm/cpu/armv7/sunxi/cpu_info.c index 5cf35acc1e6..40c4e1347c2 100644 --- a/arch/arm/cpu/armv7/sunxi/cpu_info.c +++ b/arch/arm/cpu/armv7/sunxi/cpu_info.c @@ -23,6 +23,8 @@ 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"); #else -- cgit v1.2.3 From e79c7c881047ca99191cc79b6d83ec64b898cd9b Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 2 Oct 2014 21:13:54 +0200 Subject: sunxi: When we've both mmc0 and mmc2, detect from which one we're booting sunxi SOCs can boot from both mmc0 and mmc2, detect from which one we're booting, and make that one "mmc dev 0" so that a single u-boot binary can be used for both the onboard eMMC and for external sdcards. When we're booting from mmc2, we make it dev 0 because that is where the SPL will load the tertiary payload (the actual u-boot binary in our case) from, see: common/spl/spl_mmc.c, which has dev 0 hardcoded everywhere. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- arch/arm/include/asm/arch-sunxi/mmc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/arm') diff --git a/arch/arm/include/asm/arch-sunxi/mmc.h b/arch/arm/include/asm/arch-sunxi/mmc.h index 6a3118402f4..70d787567c1 100644 --- a/arch/arm/include/asm/arch-sunxi/mmc.h +++ b/arch/arm/include/asm/arch-sunxi/mmc.h @@ -123,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 */ -- cgit v1.2.3 From bbff84b3b0092d00db1b0b77ef9043b46991d791 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 3 Oct 2014 16:44:57 +0200 Subject: sunxi: Use PG3 - PG8 as io-pins for mmc1 None of the known sunxi devices actually use mmc1 routed through PH, where as some devices do actually use mmc1 routed through PG, so change the routing of mmc1 to PG. If in the future we encounter devices with mmc1 routed through PH, we will need to change things to be a bit more flexible. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- arch/arm/include/asm/arch-sunxi/gpio.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h index ba7e69b7b7e..59122db4ce6 100644 --- a/arch/arm/include/asm/arch-sunxi/gpio.h +++ b/arch/arm/include/asm/arch-sunxi/gpio.h @@ -117,6 +117,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 -- cgit v1.2.3 From 2b679f9fa4a0166917e804a7dbf2d44a7e04f34a Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sat, 4 Oct 2014 20:37:26 +0800 Subject: ARM: sunxi: Move watchdog register definitions to separate file On later Allwinner SoCs, the watchdog hardware is by all means a separate hardware block, with its own address range and interrupt line. Move the register definitions to a separate file to facilitate supporting newer SoCs. Signed-off-by: Chen-Yu Tsai Acked-by: Ian Campbell --- arch/arm/include/asm/arch-sunxi/timer.h | 17 +++-------------- arch/arm/include/asm/arch-sunxi/watchdog.h | 24 ++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 14 deletions(-) create mode 100644 arch/arm/include/asm/arch-sunxi/watchdog.h (limited to 'arch/arm') diff --git a/arch/arm/include/asm/arch-sunxi/timer.h b/arch/arm/include/asm/arch-sunxi/timer.h index 58e14fd0f71..8ed383eb169 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 +#include /* 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,9 +67,8 @@ 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; + struct sunxi_wdog wdog; /* 0x90 */ + struct sunxi_64cnt cnt64; /* 0xa0 */ u8 res4[0x58]; struct sunxi_rtc rtc; struct sunxi_alarm alarm; 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 00000000000..5b755e37f09 --- /dev/null +++ b/arch/arm/include/asm/arch-sunxi/watchdog.h @@ -0,0 +1,24 @@ +/* + * (C) Copyright 2014 + * Chen-Yu Tsai + * + * 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) +#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]; +}; + +#endif /* _SUNXI_WATCHDOG_H_ */ -- cgit v1.2.3 From 4cdefba86d08688e96f273ee7bf9d52052362477 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sat, 4 Oct 2014 20:37:27 +0800 Subject: ARM: sunxi: Add sun6i/sun8i timer block register definition The RTC hardware has been moved out of the timer block on sun6i/sun8i. In addition, there are more watchdogs available. Also note that the timer block definition is not completely accurate for sun5i/sun7i. Various blocks are missing or have been moved out. Signed-off-by: Chen-Yu Tsai Acked-by: Ian Campbell --- arch/arm/include/asm/arch-sunxi/timer.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/include/asm/arch-sunxi/timer.h b/arch/arm/include/asm/arch-sunxi/timer.h index 8ed383eb169..03a0684c797 100644 --- a/arch/arm/include/asm/arch-sunxi/timer.h +++ b/arch/arm/include/asm/arch-sunxi/timer.h @@ -67,7 +67,9 @@ struct sunxi_timer_reg { struct sunxi_timer timer[6]; /* We have 6 timers */ u8 res2[16]; struct sunxi_avs avs; +#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; @@ -75,6 +77,10 @@ struct sunxi_timer_reg { 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__ */ -- cgit v1.2.3 From 78c396a1130a118d48068eb5615a912506050832 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sat, 4 Oct 2014 20:37:28 +0800 Subject: ARM: sunxi: Fix reset command on sun6i/sun8i The watchdog on sun6i/sun8i has a different layout. Add the new layout and fix up the setup functions so that reset works. Signed-off-by: Chen-Yu Tsai Acked-by: Ian Campbell [ ijc -- removed sun5i workaround from sun6i/sun8i codepath as discussed ] --- arch/arm/cpu/armv7/sunxi/board.c | 10 ++++++++++ arch/arm/include/asm/arch-sunxi/watchdog.h | 20 ++++++++++++++++++++ 2 files changed, 30 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c index b6d63dbb409..436df8cf2ee 100644 --- a/arch/arm/cpu/armv7/sunxi/board.c +++ b/arch/arm/cpu/armv7/sunxi/board.c @@ -75,6 +75,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; @@ -86,6 +87,15 @@ 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 */ diff --git a/arch/arm/include/asm/arch-sunxi/watchdog.h b/arch/arm/include/asm/arch-sunxi/watchdog.h index 5b755e37f09..ccc8fa32c49 100644 --- a/arch/arm/include/asm/arch-sunxi/watchdog.h +++ b/arch/arm/include/asm/arch-sunxi/watchdog.h @@ -12,6 +12,9 @@ #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) @@ -21,4 +24,21 @@ struct sunxi_wdog { 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_ */ -- cgit v1.2.3 From 7f87ad354ba79132edca3a08d1200e1acba1f612 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Wed, 22 Oct 2014 16:47:41 +0800 Subject: ARM: sunxi: Add sun8i (A23) UART0 pin mux support UART0 pin muxes on the A23 have a different function value. Signed-off-by: Chen-Yu Tsai Acked-by: Ian Campbell --- arch/arm/include/asm/arch-sunxi/gpio.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h index 59122db4ce6..7e2b16957c1 100644 --- a/arch/arm/include/asm/arch-sunxi/gpio.h +++ b/arch/arm/include/asm/arch-sunxi/gpio.h @@ -127,8 +127,14 @@ 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 -- cgit v1.2.3 From ff2b47f6a9cc10251cc601d34241ee02933c2187 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Wed, 22 Oct 2014 16:47:42 +0800 Subject: ARM: sunxi: Add support for uart0 on port F (mmc0) Allwinner SoCs provide uart0 muxed with mmc0, which can then be used with a micro SD breakout board. On the A23, this is the only way to use uart0. Signed-off-by: Chen-Yu Tsai Acked-by: Ian Campbell --- arch/arm/cpu/armv7/sunxi/board.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'arch/arm') diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c index 436df8cf2ee..7d10f10fd8d 100644 --- a/arch/arm/cpu/armv7/sunxi/board.c +++ b/arch/arm/cpu/armv7/sunxi/board.c @@ -50,7 +50,16 @@ 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), SUNXI_GPIO_PULL_UP); -- cgit v1.2.3 From e637b30b9c9f454427e7277eddb6b1f489f3bbc8 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Wed, 22 Oct 2014 16:47:43 +0800 Subject: mmc: sunxi: Add support for sun8i (A23) The Allwinner A23 SoC has reset controls like the A31 (sun6i). The FIFO address is also the same as sun6i. Re-use code added for sun6i. Signed-off-by: Chen-Yu Tsai Acked-by: Ian Campbell --- arch/arm/include/asm/arch-sunxi/mmc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/arm') diff --git a/arch/arm/include/asm/arch-sunxi/mmc.h b/arch/arm/include/asm/arch-sunxi/mmc.h index 70d787567c1..8a216740a72 100644 --- a/arch/arm/include/asm/arch-sunxi/mmc.h +++ b/arch/arm/include/asm/arch-sunxi/mmc.h @@ -43,7 +43,7 @@ struct sunxi_mmc { u32 chda; /* 0x90 */ u32 cbda; /* 0x94 */ u32 res1[26]; -#if defined(CONFIG_SUN6I) +#if defined(CONFIG_SUN6I) || defined(CONFIG_SUN8I) u32 res2[64]; #endif u32 fifo; /* 0x100 (0x200 on sun6i) FIFO access address */ -- cgit v1.2.3 From 8ebe4f429266a7cb9011f5b3ab51226297f41210 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Wed, 22 Oct 2014 16:47:44 +0800 Subject: ARM: sunxi: Add basic A23 support The basic blocks of the A23 are similar to the A31 (sun6i). Re-use sun6i code for initial clock, gpio, and uart setup. There is no SPL support for A23, as we do not have any documentation or sample code for DRAM initialization. Signed-off-by: Chen-Yu Tsai Acked-by: Ian Campbell --- arch/arm/Kconfig | 3 +++ arch/arm/cpu/armv7/sunxi/Makefile | 2 ++ arch/arm/cpu/armv7/sunxi/board.c | 3 ++- arch/arm/cpu/armv7/sunxi/cpu_info.c | 2 ++ arch/arm/include/asm/arch-sunxi/clock.h | 2 +- 5 files changed, 10 insertions(+), 2 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 4317b69e361..8f910f39a37 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -456,6 +456,9 @@ config TARGET_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 2a42dcaaa20..24f1daee647 100644 --- a/arch/arm/cpu/armv7/sunxi/Makefile +++ b/arch/arm/cpu/armv7/sunxi/Makefile @@ -12,10 +12,12 @@ 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 7d10f10fd8d..134a19874e4 100644 --- a/arch/arm/cpu/armv7/sunxi/board.c +++ b/arch/arm/cpu/armv7/sunxi/board.c @@ -110,7 +110,8 @@ void reset_cpu(ulong addr) /* 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/cpu_info.c b/arch/arm/cpu/armv7/sunxi/cpu_info.c index 40c4e1347c2..4f2a09cd2e2 100644 --- a/arch/arm/cpu/armv7/sunxi/cpu_info.c +++ b/arch/arm/cpu/armv7/sunxi/cpu_info.c @@ -27,6 +27,8 @@ int print_cpuinfo(void) 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/include/asm/arch-sunxi/clock.h b/arch/arm/include/asm/arch-sunxi/clock.h index 8f5d86025b3..012c2af72e3 100644 --- a/arch/arm/include/asm/arch-sunxi/clock.h +++ b/arch/arm/include/asm/arch-sunxi/clock.h @@ -15,7 +15,7 @@ #define CLK_GATE_CLOSE 0x0 /* clock control module regs definition */ -#ifdef CONFIG_SUN6I +#if defined(CONFIG_SUN6I) || defined(CONFIG_SUN8I) #include #else #include -- cgit v1.2.3 From e373aad32a06110e60af52c58b32d32fe8417bbd Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 22 Oct 2014 16:47:45 +0800 Subject: ARM: sunxi: Add support for R_PIO gpio banks The A31, A23 and later SoCs have an extra pin controller, called CPUs_PIO or R_PIO, which handles pin banks L and beyond. Also add a clear description about SUNXI_GPIO_BANKS, stating it only counts the number of pin banks in the _main_ pin controller. Signed-off-by: Hans de Goede [wens@csie.org: expanded commit message] [wens@csie.org: add pin bank M and expand comments] [wens@csie.org: add comment on SUNXI_GPIO_BANKS macro] Signed-off-by: Chen-Yu Tsai Acked-by: Ian Campbell --- arch/arm/include/asm/arch-sunxi/gpio.h | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h index 7e2b16957c1..de7a86aaa88 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 +#include /* * 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 -- cgit v1.2.3 From 472ed0641e73ea5c5b80f9bfa804bfe0f89eca69 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Wed, 22 Oct 2014 16:47:46 +0800 Subject: ARM: sunxi: Allow specifying module in prcm apb0 init function The prcm apb0 controls multiple modules. Allow specifying which modules to enable clocks and de-assert resets so the function can be reused. Signed-off-by: Chen-Yu Tsai Acked-by: Ian Campbell --- arch/arm/cpu/armv7/sunxi/prcm.c | 12 +++++++----- arch/arm/include/asm/arch-sunxi/prcm.h | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/cpu/armv7/sunxi/prcm.c b/arch/arm/cpu/armv7/sunxi/prcm.c index 7b3ee893026..19b4938dc97 100644 --- a/arch/arm/cpu/armv7/sunxi/prcm.c +++ b/arch/arm/cpu/armv7/sunxi/prcm.c @@ -21,13 +21,15 @@ #include #include -void prcm_init_apb0(void) +/* 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; - setbits_le32(&prcm->apb0_gate, PRCM_APB0_GATE_P2WI | - PRCM_APB0_GATE_PIO); - setbits_le32(&prcm->apb0_reset, PRCM_APB0_RESET_P2WI | - PRCM_APB0_RESET_PIO); + /* 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/prcm.h b/arch/arm/include/asm/arch-sunxi/prcm.h index 1b40f094f51..3d3bfa6cd1b 100644 --- a/arch/arm/include/asm/arch-sunxi/prcm.h +++ b/arch/arm/include/asm/arch-sunxi/prcm.h @@ -233,6 +233,6 @@ struct sunxi_prcm_reg { u32 dram_tst; /* 0x190 */ }; -void prcm_init_apb0(void); +void prcm_apb0_enable(u32 flags); #endif /* __ASSEMBLY__ */ #endif /* _PRCM_H */ -- cgit v1.2.3 From c757a50bd12b4f4f1c44a7cc42354918e8d60cd7 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Wed, 22 Oct 2014 16:47:47 +0800 Subject: ARM: sunxi: Add support for using R_UART as console The A23 only has UART0 muxed with MMC0. Some of the boards we encountered expose R_UART as a set of pads. Add support for R_UART so we can have a console while using mmc. Signed-off-by: Chen-Yu Tsai Acked-by: Ian Campbell --- arch/arm/cpu/armv7/sunxi/board.c | 4 ++++ arch/arm/cpu/armv7/sunxi/clock_sun6i.c | 6 ++++++ arch/arm/include/asm/arch-sunxi/cpu.h | 1 + arch/arm/include/asm/arch-sunxi/gpio.h | 3 +++ 4 files changed, 14 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c index 134a19874e4..06eb6768e8f 100644 --- a/arch/arm/cpu/armv7/sunxi/board.c +++ b/arch/arm/cpu/armv7/sunxi/board.c @@ -75,6 +75,10 @@ int gpio_init(void) 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), 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 diff --git a/arch/arm/cpu/armv7/sunxi/clock_sun6i.c b/arch/arm/cpu/armv7/sunxi/clock_sun6i.c index 8387b931aa8..1eae9767d0d 100644 --- a/arch/arm/cpu/armv7/sunxi/clock_sun6i.c +++ b/arch/arm/cpu/armv7/sunxi/clock_sun6i.c @@ -13,6 +13,7 @@ #include #include #include +#include #include void clock_init_uart(void) @@ -20,6 +21,7 @@ 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| @@ -35,6 +37,10 @@ void clock_init_uart(void) 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); diff --git a/arch/arm/include/asm/arch-sunxi/cpu.h b/arch/arm/include/asm/arch-sunxi/cpu.h index 313e6c849d9..0de79a0d508 100644 --- a/arch/arm/include/asm/arch-sunxi/cpu.h +++ b/arch/arm/include/asm/arch-sunxi/cpu.h @@ -111,6 +111,7 @@ #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 diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h index de7a86aaa88..7bb649950a9 100644 --- a/arch/arm/include/asm/arch-sunxi/gpio.h +++ b/arch/arm/include/asm/arch-sunxi/gpio.h @@ -172,6 +172,9 @@ enum sunxi_gpio_number { #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 -- cgit v1.2.3 From 9e54f6ee0148ae26aa673b45aaf77c2782232f48 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 22 Oct 2014 14:42:48 +0200 Subject: sunxi: Add clock_get_pll5p() function This is a preparation patch for making the pll5 "p" divisor configurable through Kconfig. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- arch/arm/cpu/armv7/sunxi/clock_sun4i.c | 11 +++++++++++ arch/arm/include/asm/arch-sunxi/clock.h | 1 + arch/arm/include/asm/arch-sunxi/clock_sun4i.h | 3 +++ 3 files changed, 15 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/cpu/armv7/sunxi/clock_sun4i.c b/arch/arm/cpu/armv7/sunxi/clock_sun4i.c index ecbdb0162b2..4a0d64fb30e 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/include/asm/arch-sunxi/clock.h b/arch/arm/include/asm/arch-sunxi/clock.h index 012c2af72e3..c562f621c22 100644 --- a/arch/arm/include/asm/arch-sunxi/clock.h +++ b/arch/arm/include/asm/arch-sunxi/clock.h @@ -25,6 +25,7 @@ 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 1ba997adf9f..90af8e25069 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) -- cgit v1.2.3 From d0dbc286036a4e4e01ca056e40d952a081162a8c Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 22 Oct 2014 14:48:38 +0200 Subject: sunxi: dram: Use clock_get_pll5p to calculate mbus, rather then hardcoding This is a preparation patch for making the pll5 "p" divisor configurable through Kconfig. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- arch/arm/cpu/armv7/sunxi/dram.c | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/cpu/armv7/sunxi/dram.c b/arch/arm/cpu/armv7/sunxi/dram.c index 584f7420d7d..0cbcf5767c3 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); @@ -269,32 +263,27 @@ static void mctl_setup_dram_clock(u32 clk, u32 mbus_clk) reg_val &= ~CCM_PLL5_CTRL_N_MASK; /* set N to 0 (x0) */ reg_val &= ~CCM_PLL5_CTRL_P_MASK; /* set P to 0 (x1) */ 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 +311,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; -- cgit v1.2.3 From accc9e446be6c3bd129315a0c5830bddccfa16da Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 22 Oct 2014 14:56:36 +0200 Subject: sunxi: Add CONFIG_OLD_SUNXI_KERNEL_COMPAT Kconfig option Add a Kconfig option which users can select when they want to boot older kernels, e.g. the linux-sunxi 3.4 kernels. For now this just forces the pll5 "p" value to 1 (divide by 2) as that is what those kernels are hardcoded too, in the future this may enable further workarounds. Signed-off-by: Hans de Goede Reviewed-by: Tom Rini -- Changes in v2: -s/CONFIG_OLD_KERNEL_COMPAT/CONFIG_OLD_SUNXI_KERNEL_COMPAT. -Move the code block setting P(1) for old kernels to where P gets cleared --- arch/arm/cpu/armv7/sunxi/dram.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/cpu/armv7/sunxi/dram.c b/arch/arm/cpu/armv7/sunxi/dram.c index 0cbcf5767c3..3cf3cbf19ad 100644 --- a/arch/arm/cpu/armv7/sunxi/dram.c +++ b/arch/arm/cpu/armv7/sunxi/dram.c @@ -262,6 +262,10 @@ 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 */ reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2)); -- cgit v1.2.3