From c286cdfe149531669200b66962d47fa54e9a06c1 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 20 Dec 2015 16:10:01 +0100 Subject: sunxi: Implement poweroff support for axp152 pmic Adds poweroff support for axp152 pmic. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- drivers/power/Kconfig | 1 + drivers/power/axp152.c | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index e86dd72c14..de328287fc 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -20,6 +20,7 @@ config SUNXI_NO_PMIC config AXP152_POWER boolean "axp152 pmic support" depends on MACH_SUN5I + select CMD_POWEROFF ---help--- Select this to enable support for the axp152 pmic found on most A10s boards. diff --git a/drivers/power/axp152.c b/drivers/power/axp152.c index 297258692d..cd07275d9f 100644 --- a/drivers/power/axp152.c +++ b/drivers/power/axp152.c @@ -5,6 +5,7 @@ * SPDX-License-Identifier: GPL-2.0+ */ #include +#include #include #include @@ -78,3 +79,14 @@ int axp_init(void) return 0; } + +int do_poweroff(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + pmic_bus_write(AXP152_SHUTDOWN, AXP152_POWEROFF); + + /* infinite loop during shutdown */ + while (1) {} + + /* not reached */ + return 0; +} -- cgit v1.2.1 From 467e92b35721447045c70d464c85aee8dbe0db2e Mon Sep 17 00:00:00 2001 From: Michael van Slingerland Date: Sun, 13 Dec 2015 13:17:31 +0100 Subject: sunxi: Implement poweroff support for axp209 pmic Adds poweroff support for axp209 pmic. Signed-off-by: Michael van Slingerland Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- drivers/power/Kconfig | 1 + drivers/power/axp209.c | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index de328287fc..52c9e61f24 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -28,6 +28,7 @@ config AXP152_POWER config AXP209_POWER boolean "axp209 pmic support" depends on MACH_SUN4I || MACH_SUN5I || MACH_SUN7I + select CMD_POWEROFF ---help--- Select this to enable support for the axp209 pmic found on most A10, A13 and A20 boards. diff --git a/drivers/power/axp209.c b/drivers/power/axp209.c index 71aa000daa..fc162a149e 100644 --- a/drivers/power/axp209.c +++ b/drivers/power/axp209.c @@ -6,6 +6,7 @@ */ #include +#include #include #include @@ -168,3 +169,14 @@ int axp_init(void) return 0; } + +int do_poweroff(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + pmic_bus_write(AXP209_SHUTDOWN, AXP209_POWEROFF); + + /* infinite loop during shutdown */ + while (1) {} + + /* not reached */ + return 0; +} -- cgit v1.2.1 From fe4b71b2373cf0627fbd9d9767fb66059e67eea7 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 20 Dec 2015 16:14:31 +0100 Subject: sunxi: Implement poweroff support for axp221 pmic Adds poweroff support for axp221 pmic. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- drivers/power/Kconfig | 1 + drivers/power/axp221.c | 12 ++++++++++++ include/axp221.h | 2 ++ 3 files changed, 15 insertions(+) diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 52c9e61f24..dfd60aa3fa 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -36,6 +36,7 @@ config AXP209_POWER config AXP221_POWER boolean "axp221 / axp223 pmic support" depends on MACH_SUN6I || MACH_SUN8I_A23 || MACH_SUN8I_A33 + select CMD_POWEROFF ---help--- Select this to enable support for the axp221/axp223 pmic found on most A23 and A31 boards. diff --git a/drivers/power/axp221.c b/drivers/power/axp221.c index 65802e4a71..8acadf0f9c 100644 --- a/drivers/power/axp221.c +++ b/drivers/power/axp221.c @@ -11,6 +11,7 @@ */ #include +#include #include #include #include @@ -312,3 +313,14 @@ int axp_get_sid(unsigned int *sid) return 0; } + +int do_poweroff(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + pmic_bus_write(AXP221_SHUTDOWN, AXP221_SHUTDOWN_POWEROFF); + + /* infinite loop during shutdown */ + while (1) {} + + /* not reached */ + return 0; +} diff --git a/include/axp221.h b/include/axp221.h index 0ee21b6280..04cd8c2be4 100644 --- a/include/axp221.h +++ b/include/axp221.h @@ -45,6 +45,8 @@ #define AXP221_ALDO3_CTRL 0x2a #define AXP221_VBUS_IPSOUT 0x30 #define AXP221_VBUS_IPSOUT_DRIVEBUS (1 << 2) +#define AXP221_SHUTDOWN 0x32 +#define AXP221_SHUTDOWN_POWEROFF (1 << 7) #define AXP221_MISC_CTRL 0x8f #define AXP221_MISC_CTRL_N_VBUSEN_FUNC (1 << 4) #define AXP221_PAGE 0xff -- cgit v1.2.1 From 5823664fb84612ef511136b66059710cccd71bed Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Wed, 6 Jan 2016 15:13:06 +0800 Subject: sunxi: Support Secure Memory Touch Arbiter (SMTA) in sun8i H3 Secure Memory Touch Arbiter is the same thing as the TrustZone Protection Controller found on A31/A31s. Access to many peripherals on the H3 can be controlled by the SMTA, and the settings default to secure access only. This patch supports the new settings, and sets them to allow non-secure access. Signed-off-by: Chen-Yu Tsai Acked-by: Hans de Goede Signed-off-by: Hans de Goede --- arch/arm/cpu/armv7/sunxi/Makefile | 1 + arch/arm/cpu/armv7/sunxi/board.c | 4 ++-- arch/arm/cpu/armv7/sunxi/tzpc.c | 11 ++++++++++- arch/arm/include/asm/arch-sunxi/tzpc.h | 13 ++++++++++++- 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile index dfb0a3e3c0..ce8e5717e7 100644 --- a/arch/arm/cpu/armv7/sunxi/Makefile +++ b/arch/arm/cpu/armv7/sunxi/Makefile @@ -33,6 +33,7 @@ obj-$(CONFIG_MACH_SUN8I) += clock_sun6i.o endif obj-$(CONFIG_MACH_SUN9I) += clock_sun9i.o obj-$(CONFIG_MACH_SUN6I) += tzpc.o +obj-$(CONFIG_MACH_SUN8I_H3) += tzpc.o obj-$(CONFIG_AXP152_POWER) += pmic_bus.o obj-$(CONFIG_AXP209_POWER) += pmic_bus.o diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c index 7dfb7f5340..eb5f4b686e 100644 --- a/arch/arm/cpu/armv7/sunxi/board.c +++ b/arch/arm/cpu/armv7/sunxi/board.c @@ -127,8 +127,8 @@ void s_init(void) "orr r0, r0, #1 << 6\n" "mcr p15, 0, r0, c1, c0, 1\n"); #endif -#if defined CONFIG_MACH_SUN6I - /* Enable non-secure access to the RTC */ +#if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I_H3 + /* Enable non-secure access to some peripherals */ tzpc_init(); #endif diff --git a/arch/arm/cpu/armv7/sunxi/tzpc.c b/arch/arm/cpu/armv7/sunxi/tzpc.c index 5c9c69b20b..6c8a0fd9a2 100644 --- a/arch/arm/cpu/armv7/sunxi/tzpc.c +++ b/arch/arm/cpu/armv7/sunxi/tzpc.c @@ -13,6 +13,15 @@ void tzpc_init(void) { struct sunxi_tzpc *tzpc = (struct sunxi_tzpc *)SUNXI_TZPC_BASE; +#ifdef CONFIG_MACH_SUN6I /* Enable non-secure access to the RTC */ - writel(SUNXI_TZPC_DECPORT0_RTC, &tzpc->decport0_set); + writel(SUN6I_TZPC_DECPORT0_RTC, &tzpc->decport0_set); +#endif + +#ifdef CONFIG_MACH_SUN8I_H3 + /* Enable non-secure access to all peripherals */ + writel(SUN8I_H3_TZPC_DECPORT0_ALL, &tzpc->decport0_set); + writel(SUN8I_H3_TZPC_DECPORT1_ALL, &tzpc->decport1_set); + writel(SUN8I_H3_TZPC_DECPORT2_ALL, &tzpc->decport2_set); +#endif } diff --git a/arch/arm/include/asm/arch-sunxi/tzpc.h b/arch/arm/include/asm/arch-sunxi/tzpc.h index ba4d43bc3a..95c55cd4d1 100644 --- a/arch/arm/include/asm/arch-sunxi/tzpc.h +++ b/arch/arm/include/asm/arch-sunxi/tzpc.h @@ -13,10 +13,21 @@ struct sunxi_tzpc { u32 decport0_status; /* 0x04 Status of decode protection port 0 */ u32 decport0_set; /* 0x08 Set decode protection port 0 */ u32 decport0_clear; /* 0x0c Clear decode protection port 0 */ + /* For A80 and later SoCs */ + u32 decport1_status; /* 0x10 Status of decode protection port 1 */ + u32 decport1_set; /* 0x14 Set decode protection port 1 */ + u32 decport1_clear; /* 0x18 Clear decode protection port 1 */ + u32 decport2_status; /* 0x1c Status of decode protection port 2 */ + u32 decport2_set; /* 0x20 Set decode protection port 2 */ + u32 decport2_clear; /* 0x24 Clear decode protection port 2 */ }; #endif -#define SUNXI_TZPC_DECPORT0_RTC (1 << 1) +#define SUN6I_TZPC_DECPORT0_RTC (1 << 1) + +#define SUN8I_H3_TZPC_DECPORT0_ALL 0xbe +#define SUN8I_H3_TZPC_DECPORT1_ALL 0xff +#define SUN8I_H3_TZPC_DECPORT2_ALL 0x7f void tzpc_init(void); -- cgit v1.2.1 From ed80584f3087f8d4da996cddd9807fc90f3de06c Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Wed, 6 Jan 2016 15:13:07 +0800 Subject: sunxi: Support H3 CCU security switches H3's CCU includes some switches which disable non-secure access to some of the more critical clock controls, such as MBUS, PLLs, and main platform busses. Configure them to enable non-secure access. For now the only SoC that has this feature is the H3. For other platforms just use a default (weak) empty function so things do not break. Signed-off-by: Chen-Yu Tsai Acked-by: Hans de Goede Signed-off-by: Hans de Goede --- arch/arm/cpu/armv7/sunxi/clock.c | 5 +++++ arch/arm/cpu/armv7/sunxi/clock_sun6i.c | 13 +++++++++++++ arch/arm/include/asm/arch-sunxi/clock.h | 1 + arch/arm/include/asm/arch-sunxi/clock_sun6i.h | 7 +++++++ 4 files changed, 26 insertions(+) diff --git a/arch/arm/cpu/armv7/sunxi/clock.c b/arch/arm/cpu/armv7/sunxi/clock.c index 47fb70ff7c..5cc5d25d2b 100644 --- a/arch/arm/cpu/armv7/sunxi/clock.c +++ b/arch/arm/cpu/armv7/sunxi/clock.c @@ -14,12 +14,17 @@ #include #include +__weak void clock_init_sec(void) +{ +} + int clock_init(void) { #ifdef CONFIG_SPL_BUILD clock_init_safe(); #endif clock_init_uart(); + clock_init_sec(); return 0; } diff --git a/arch/arm/cpu/armv7/sunxi/clock_sun6i.c b/arch/arm/cpu/armv7/sunxi/clock_sun6i.c index 1da5455c9a..700b605ab3 100644 --- a/arch/arm/cpu/armv7/sunxi/clock_sun6i.c +++ b/arch/arm/cpu/armv7/sunxi/clock_sun6i.c @@ -45,6 +45,19 @@ void clock_init_safe(void) } #endif +void clock_init_sec(void) +{ +#ifdef CONFIG_MACH_SUN8I_H3 + struct sunxi_ccm_reg * const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + + setbits_le32(&ccm->ccu_sec_switch, + CCM_SEC_SWITCH_MBUS_NONSEC | + CCM_SEC_SWITCH_BUS_NONSEC | + CCM_SEC_SWITCH_PLL_NONSEC); +#endif +} + void clock_init_uart(void) { #if CONFIG_CONS_INDEX < 5 diff --git a/arch/arm/include/asm/arch-sunxi/clock.h b/arch/arm/include/asm/arch-sunxi/clock.h index 8ca58ae521..6c0573fe58 100644 --- a/arch/arm/include/asm/arch-sunxi/clock.h +++ b/arch/arm/include/asm/arch-sunxi/clock.h @@ -30,6 +30,7 @@ int clock_init(void); int clock_twi_onoff(int port, int state); void clock_set_de_mod_clock(u32 *clk_cfg, unsigned int hz); void clock_init_safe(void); +void clock_init_sec(void); void clock_init_uart(void); #endif diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h index 5c76275112..554d8589ed 100644 --- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h +++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h @@ -137,6 +137,8 @@ struct sunxi_ccm_reg { u32 apb1_reset_cfg; /* 0x2d0 APB1 Reset config */ u32 reserved24; u32 apb2_reset_cfg; /* 0x2d8 APB2 Reset config */ + u32 reserved25[5]; + u32 ccu_sec_switch; /* 0x2f0 CCU Security Switch, H3 only */ }; /* apb2 bit field */ @@ -375,6 +377,11 @@ struct sunxi_ccm_reg { #define CCM_DE_CTRL_PLL10 (5 << 24) #define CCM_DE_CTRL_GATE (1 << 31) +/* CCU security switch, H3 only */ +#define CCM_SEC_SWITCH_MBUS_NONSEC (1 << 2) +#define CCM_SEC_SWITCH_BUS_NONSEC (1 << 1) +#define CCM_SEC_SWITCH_PLL_NONSEC (1 << 0) + #ifndef __ASSEMBLY__ void clock_set_pll1(unsigned int hz); void clock_set_pll3(unsigned int hz); -- cgit v1.2.1 From 96839451798961207808c1050b913ee4f114eaf0 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Wed, 6 Jan 2016 15:13:08 +0800 Subject: sunxi: Support PSCI ops on Allwinner H3 H3 has the same power sequencing procedure as the A31/A31s, which includes the power clamps. Signed-off-by: Chen-Yu Tsai Acked-by: Hans de Goede Signed-off-by: Hans de Goede --- arch/arm/cpu/armv7/sunxi/psci_sun6i.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/cpu/armv7/sunxi/psci_sun6i.S b/arch/arm/cpu/armv7/sunxi/psci_sun6i.S index 4ff46e4fc0..90b5bfd359 100644 --- a/arch/arm/cpu/armv7/sunxi/psci_sun6i.S +++ b/arch/arm/cpu/armv7/sunxi/psci_sun6i.S @@ -106,7 +106,7 @@ psci_fiq_enter: str r10, [r8, #0x100] timer_wait r10, ONE_MS -#ifdef CONFIG_MACH_SUN6I +#if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN8I_H3) @ Activate power clamp lsl r12, r9, #2 @ x4 add r12, r12, r8 @@ -170,7 +170,7 @@ psci_cpu_on: movw r0, #(SUNXI_PRCM_BASE & 0xffff) movt r0, #(SUNXI_PRCM_BASE >> 16) -#ifdef CONFIG_MACH_SUN6I +#if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN8I_H3) @ Release power clamp lsl r5, r1, #2 @ 1 register per CPU add r5, r5, r0 @ PRCM -- cgit v1.2.1 From 853f6d1ef8d3c4d7967651bc9009d96e129c9c05 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Wed, 6 Jan 2016 15:13:09 +0800 Subject: sunxi: Enable booting non-secure and virtualization for H3 Now that we support PSCI and various security switches, we can let U-boot boot Linux into non-secure and HYP mode. Signed-off-by: Chen-Yu Tsai Acked-by: Hans de Goede Signed-off-by: Hans de Goede --- board/sunxi/Kconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index 7c69be918f..8a30d08467 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -71,8 +71,11 @@ config MACH_SUN8I_A33 config MACH_SUN8I_H3 bool "sun8i (Allwinner H3)" select CPU_V7 + select CPU_V7_HAS_NONSEC + select CPU_V7_HAS_VIRT select SUNXI_GEN_SUN6I select SUPPORT_SPL + select ARMV7_BOOT_SEC_DEFAULT if OLD_SUNXI_KERNEL_COMPAT config MACH_SUN8I_A83T bool "sun8i (Allwinner A83T)" -- cgit v1.2.1 From 627b380f62802d06a9d47ec5407ef1cf7a751275 Mon Sep 17 00:00:00 2001 From: Vishnu Patekar Date: Tue, 12 Jan 2016 01:20:57 +0800 Subject: sunxi: Redundant code cleanup from a83t dram init This removes the redundant lines of code from mctl_sys_init. Signed-off-by: Vishnu Patekar Acked-by: Hans de Goede Signed-off-by: Hans de Goede --- arch/arm/cpu/armv7/sunxi/dram_sun8i_a83t.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/arch/arm/cpu/armv7/sunxi/dram_sun8i_a83t.c b/arch/arm/cpu/armv7/sunxi/dram_sun8i_a83t.c index d757e403dc..75e9746567 100644 --- a/arch/arm/cpu/armv7/sunxi/dram_sun8i_a83t.c +++ b/arch/arm/cpu/armv7/sunxi/dram_sun8i_a83t.c @@ -366,11 +366,6 @@ static void mctl_sys_init(struct dram_para *para) CCM_DRAMCLK_CFG_RST | CCM_DRAMCLK_CFG_UPD); mctl_await_completion(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_UPD, 0); - setbits_le32(&ccm->ahb_reset0_cfg, 1 << 14); - setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MCTL); - setbits_le32(&ccm->mbus_reset, CCM_MBUS_RESET_RESET); - setbits_le32(&ccm->mbus_clk_cfg, MBUS_CLK_GATE); - setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MCTL); setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MCTL); setbits_le32(&ccm->mbus_reset, CCM_MBUS_RESET_RESET); -- cgit v1.2.1 From f5fd8caf7f0e5e0c6c09eb620fc4f7564290f27b Mon Sep 17 00:00:00 2001 From: Vishnu Patekar Date: Tue, 12 Jan 2016 01:20:58 +0800 Subject: sunxi: Groundwork to support new dram type for A83T Different A83T boards have different DRAM types. Banapi M3 has LPDDR3, Allwinner Homlet v1.2 has DDR3. This adds groundwork to support for new DRAM type for A83T. Introduce CONFIG_DRAM_TYPE, It'll be 3 for DDR3 and 7 for LPDDR3, must be set in respective board defconfig. Signed-off-by: Vishnu Patekar Acked-by: Hans de Goede Signed-off-by: Hans de Goede --- arch/arm/cpu/armv7/sunxi/dram_sun8i_a83t.c | 11 ++++++++++- arch/arm/include/asm/arch-sunxi/dram_sun8i_a83t.h | 4 +++- board/sunxi/Kconfig | 6 ++++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/arch/arm/cpu/armv7/sunxi/dram_sun8i_a83t.c b/arch/arm/cpu/armv7/sunxi/dram_sun8i_a83t.c index 75e9746567..35b6c5e464 100644 --- a/arch/arm/cpu/armv7/sunxi/dram_sun8i_a83t.c +++ b/arch/arm/cpu/armv7/sunxi/dram_sun8i_a83t.c @@ -25,6 +25,7 @@ struct dram_para { u8 rank; u8 rows; u8 bus_width; + u8 dram_type; u16 page_size; }; @@ -34,7 +35,7 @@ static void mctl_set_cr(struct dram_para *para) (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE; writel(MCTL_CR_CS1_CONTROL(para->cs1) | MCTL_CR_UNKNOWN | - MCTL_CR_CHANNEL(1) | MCTL_CR_DDR3 | + MCTL_CR_CHANNEL(1) | MCTL_CR_DRAM_TYPE(para->dram_type) | (para->seq ? MCTL_CR_SEQUENCE : 0) | ((para->bus_width == 16) ? MCTL_CR_BUSW16 : MCTL_CR_BUSW8) | MCTL_CR_PAGE_SIZE(para->page_size) | MCTL_CR_ROW(para->rows) | @@ -86,6 +87,7 @@ static void auto_set_timing_para(struct dram_para *para) { struct sunxi_mctl_ctl_reg * const mctl_ctl = (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE; + u32 reg_val; u8 tccd = 2; @@ -393,6 +395,13 @@ unsigned long sunxi_dram_init(void) .page_size = 2048, }; +#if defined(CONFIG_MACH_SUN8I_A83T) +#if (CONFIG_DRAM_TYPE == 3) || (CONFIG_DRAM_TYPE == 7) + para.dram_type = CONFIG_DRAM_TYPE; +#else +#error Unsupported DRAM type, Please set DRAM type (3:DDR3, 7:LPDDR3) +#endif +#endif setbits_le32(SUNXI_PRCM_BASE + 0x1e0, 0x1 << 8); writel(0, (SUNXI_PRCM_BASE + 0x1e8)); diff --git a/arch/arm/include/asm/arch-sunxi/dram_sun8i_a83t.h b/arch/arm/include/asm/arch-sunxi/dram_sun8i_a83t.h index 2891b71b33..05b6a89e8e 100644 --- a/arch/arm/include/asm/arch-sunxi/dram_sun8i_a83t.h +++ b/arch/arm/include/asm/arch-sunxi/dram_sun8i_a83t.h @@ -186,7 +186,7 @@ struct sunxi_mctl_ctl_reg { #define MCTL_CR_BUSW8 (0 << 12) #define MCTL_CR_BUSW16 (1 << 12) #define MCTL_CR_SEQUENCE (1 << 15) -#define MCTL_CR_DDR3 (3 << 16) +#define MCTL_CR_DRAM_TYPE(x) ((x) << 16) #define MCTL_CR_CHANNEL_MASK (1 << 19) #define MCTL_CR_CHANNEL(x) (((x) - 1) << 19) #define MCTL_CR_UNKNOWN (0x4 << 20) @@ -198,4 +198,6 @@ struct sunxi_mctl_ctl_reg { #define MCTL_MR2 0x18 /* CWL=8 */ #define MCTL_MR3 0x0 +#define DRAM_TYPE_DDR3 3 +#define DRAM_TYPE_LPDDR3 7 #endif /* _SUNXI_DRAM_SUN8I_A83T_H */ diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index 8a30d08467..a334aa336d 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -95,6 +95,12 @@ config MACH_SUN8I bool default y if MACH_SUN8I_A23 || MACH_SUN8I_A33 || MACH_SUN8I_H3 || MACH_SUN8I_A83T +config DRAM_TYPE + int "sunxi dram type" + depends on MACH_SUN8I_A83T + default 3 + ---help--- + Set the dram type, 3: DDR3, 7: LPDDR3 config DRAM_CLK int "sunxi dram clock speed" -- cgit v1.2.1 From f3ad64c88ccc3cd60d9d2d7b0098bf1692fda779 Mon Sep 17 00:00:00 2001 From: Vishnu Patekar Date: Tue, 12 Jan 2016 01:20:59 +0800 Subject: sunxi: Add support for LPDDR3 for A83T Banana-pi M3 has LPDDR3 DRAM. this adds support for LPDDR3 for A83T. Mostly the timing parameters are different from DDR3. Signed-off-by: Vishnu Patekar Acked-by: Hans de Goede Signed-off-by: Hans de Goede --- arch/arm/cpu/armv7/sunxi/dram_sun8i_a83t.c | 54 ++++++++++++++++++++--- arch/arm/include/asm/arch-sunxi/dram_sun8i_a83t.h | 5 +++ 2 files changed, 54 insertions(+), 5 deletions(-) diff --git a/arch/arm/cpu/armv7/sunxi/dram_sun8i_a83t.c b/arch/arm/cpu/armv7/sunxi/dram_sun8i_a83t.c index 35b6c5e464..7c46acdbf2 100644 --- a/arch/arm/cpu/armv7/sunxi/dram_sun8i_a83t.c +++ b/arch/arm/cpu/armv7/sunxi/dram_sun8i_a83t.c @@ -131,10 +131,42 @@ static void auto_set_timing_para(struct dram_para *para) /* Set work mode register */ mctl_set_cr(para); /* Set mode register */ - writel(MCTL_MR0, &mctl_ctl->mr0); - writel(MCTL_MR1, &mctl_ctl->mr1); - writel(MCTL_MR2, &mctl_ctl->mr2); - writel(MCTL_MR3, &mctl_ctl->mr3); + if (para->dram_type == DRAM_TYPE_DDR3) { + writel(MCTL_MR0, &mctl_ctl->mr0); + writel(MCTL_MR1, &mctl_ctl->mr1); + writel(MCTL_MR2, &mctl_ctl->mr2); + writel(MCTL_MR3, &mctl_ctl->mr3); + } else if (para->dram_type == DRAM_TYPE_LPDDR3) { + writel(MCTL_LPDDR3_MR0, &mctl_ctl->mr0); + writel(MCTL_LPDDR3_MR1, &mctl_ctl->mr1); + writel(MCTL_LPDDR3_MR2, &mctl_ctl->mr2); + writel(MCTL_LPDDR3_MR3, &mctl_ctl->mr3); + + /* timing parameters for LPDDR3 */ + tfaw = max(ns_to_t(50), 4); + trrd = max(ns_to_t(10), 2); + trcd = max(ns_to_t(24), 2); + trc = ns_to_t(70); + txp = max(ns_to_t(8), 2); + twtr = max(ns_to_t(8), 2); + trtp = max(ns_to_t(8), 2); + trp = max(ns_to_t(27), 2); + tras = ns_to_t(42); + trefi = ns_to_t(3900) / 32; + trfc = ns_to_t(210); + tmrw = 5; + tmrd = 5; + tckesr = 5; + tcwl = 3; /* CWL 8 */ + t_rdata_en = 5; + tdinit0 = (200 * CONFIG_DRAM_CLK) + 1; /* 200us */ + tdinit1 = (100 * CONFIG_DRAM_CLK) / 1000 + 1; /* 100ns */ + tdinit2 = (11 * CONFIG_DRAM_CLK) + 1; /* 200us */ + tdinit3 = (1 * CONFIG_DRAM_CLK) + 1; /* 1us */ + twtp = tcwl + 4 + twr + 1; /* CWL + BL/2 + tWR */ + twr2rd = tcwl + 4 + 1 + twtr; /* WL + BL / 2 + tWTR */ + trd2wr = tcl + 4 + 5 - tcwl + 1; /* RL + BL / 2 + 2 - WL */ + } /* Set dram timing */ reg_val = (twtp << 24) | (tfaw << 16) | (trasmax << 8) | (tras << 0); writel(reg_val, &mctl_ctl->dramtmg0); @@ -289,6 +321,9 @@ static int mctl_channel_init(struct dram_para *para) clrbits_le32(&mctl_ctl->pgcr2, (0x3 << 6)); clrbits_le32(&mctl_ctl->dqsgmr, (0x1 << 8) | (0x7)); + if (para->dram_type == DRAM_TYPE_LPDDR3) + clrsetbits_le32(&mctl_ctl->dxccr, (0x1 << 27) | (0x3<<6) , + 0x1 << 31); if (readl(&mctl_com->cr) & 0x1) writel(0x00000303, &mctl_ctl->odtmap); else @@ -299,7 +334,11 @@ static int mctl_channel_init(struct dram_para *para) clrsetbits_le32(ZQnPR(0), 0x000000ff, CONFIG_DRAM_ZQ & 0xff); clrsetbits_le32(ZQnPR(1), 0x000000ff, (CONFIG_DRAM_ZQ >> 8) & 0xff); /* CA calibration */ - mctl_set_pir(0x0201f3 | 0x1<<10); + + if (para->dram_type == DRAM_TYPE_DDR3) + mctl_set_pir(0x0201f3 | 0x1<<10); + else + mctl_set_pir(0x020173 | 0x1<<10); /* DQS gate training */ if (mctl_train_dram(para) != 0) { @@ -359,6 +398,7 @@ static void mctl_sys_init(struct dram_para *para) clrbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MCTL); clrbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MCTL); clrbits_le32(&ccm->pll5_cfg, CCM_PLL5_CTRL_EN); + udelay(1000); clrbits_le32(&ccm->dram_clk_cfg, 0x01<<31); clock_set_pll5(CONFIG_DRAM_CLK * 1000000 * DRAM_CLK_MUL); @@ -373,6 +413,10 @@ static void mctl_sys_init(struct dram_para *para) setbits_le32(&ccm->mbus_reset, CCM_MBUS_RESET_RESET); setbits_le32(&ccm->mbus_clk_cfg, MBUS_CLK_GATE); + para->rank = 2; + para->bus_width = 16; + mctl_set_cr(para); + /* Set dram master access priority */ writel(0x0000e00f, &mctl_ctl->clken); /* normal */ diff --git a/arch/arm/include/asm/arch-sunxi/dram_sun8i_a83t.h b/arch/arm/include/asm/arch-sunxi/dram_sun8i_a83t.h index 05b6a89e8e..842ad3cc63 100644 --- a/arch/arm/include/asm/arch-sunxi/dram_sun8i_a83t.h +++ b/arch/arm/include/asm/arch-sunxi/dram_sun8i_a83t.h @@ -198,6 +198,11 @@ struct sunxi_mctl_ctl_reg { #define MCTL_MR2 0x18 /* CWL=8 */ #define MCTL_MR3 0x0 +#define MCTL_LPDDR3_MR0 0x0 +#define MCTL_LPDDR3_MR1 0xc3 /* twr=8, bl=8 */ +#define MCTL_LPDDR3_MR2 0xa /* RL=12, CWL=6 */ +#define MCTL_LPDDR3_MR3 0x0 + #define DRAM_TYPE_DDR3 3 #define DRAM_TYPE_LPDDR3 7 #endif /* _SUNXI_DRAM_SUN8I_A83T_H */ -- cgit v1.2.1 From cd7aa27bec4c7926350eb773ae073eebe7ad725a Mon Sep 17 00:00:00 2001 From: Vishnu Patekar Date: Tue, 12 Jan 2016 01:21:00 +0800 Subject: sunxi: Add suport for A83T based Banana-pi M3 Board Add dts and defconfig for Banana-pi M3 board. It has 2G LPDDR3, UART, ethernet, USB, HDMI, USB Sata, MIPI DSI, mic, AP6212 Wifi, etc on it. It is paired with AXP813 PMIC which is almost same as AXP818. Signed-off-by: Vishnu Patekar [hdegoede@redhat.com: rename to Sinovoip_BPI_M3_defconfig/sun8i-a83t-sinovoip-bpi-m3.dts] Signed-off-by: Hans de Goede --- arch/arm/dts/Makefile | 3 +- arch/arm/dts/sun8i-a83t-sinovoip-bpi-m3.dts | 64 +++++++++++++++++++++++++++++ board/sunxi/MAINTAINERS | 5 +++ configs/Sinovoip_BPI_M3_defconfig | 26 ++++++++++++ 4 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 arch/arm/dts/sun8i-a83t-sinovoip-bpi-m3.dts create mode 100644 configs/Sinovoip_BPI_M3_defconfig diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 641510c668..1c7d359fa6 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -183,7 +183,8 @@ dtb-$(CONFIG_MACH_SUN8I_A33) += \ sun8i-a33-q8-tablet.dtb \ sun8i-a33-sinlinx-sina33.dtb dtb-$(CONFIG_MACH_SUN8I_A83T) += \ - sun8i-a83t-allwinner-h8homlet-v2.dtb + sun8i-a83t-allwinner-h8homlet-v2.dtb \ + sun8i-a83t-sinovoip-bpi-m3.dtb dtb-$(CONFIG_MACH_SUN8I_H3) += \ sun8i-h3-orangepi-pc.dtb \ sun8i-h3-orangepi-plus.dtb diff --git a/arch/arm/dts/sun8i-a83t-sinovoip-bpi-m3.dts b/arch/arm/dts/sun8i-a83t-sinovoip-bpi-m3.dts new file mode 100644 index 0000000000..91ff3a9f60 --- /dev/null +++ b/arch/arm/dts/sun8i-a83t-sinovoip-bpi-m3.dts @@ -0,0 +1,64 @@ +/* + * Copyright 2015 Vishnu Patekar + * Vishnu Patekar + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "sun8i-a83t.dtsi" + +/ { + model = "Allwinner A83T BananaPi M3 Board v1.2"; + compatible = "bananapi,m3v1.2", "allwinner,sun8i-a83t"; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins_b>; + status = "okay"; +}; diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS index 131c3415aa..739b6fdc88 100644 --- a/board/sunxi/MAINTAINERS +++ b/board/sunxi/MAINTAINERS @@ -183,6 +183,11 @@ S: Maintained F: configs/Sinlinx_SinA33_defconfig W: http://linux-sunxi.org/Sinlinx_SinA33 +SINOVOIP BPI M3 A83T BOARD +M: VishnuPatekar +S: Maintained +F: configs/Sinovoip_BPI_M3_defconfig + WEXLER-TAB7200 BOARD M: Aleksei Mamlin S: Maintained diff --git a/configs/Sinovoip_BPI_M3_defconfig b/configs/Sinovoip_BPI_M3_defconfig new file mode 100644 index 0000000000..b96be50e89 --- /dev/null +++ b/configs/Sinovoip_BPI_M3_defconfig @@ -0,0 +1,26 @@ +CONFIG_ARM=y +CONFIG_ARCH_SUNXI=y +CONFIG_MACH_SUN8I_A83T=y +CONFIG_DRAM_CLK=480 +CONFIG_DRAM_ZQ=15355 +CONFIG_DRAM_ODT_EN=y +CONFIG_DRAM_TYPE=7 +CONFIG_SYS_EXTRA_OPTIONS="" +#CONFIG_USB0_VBUS_PIN="AXP0-VBUS-ENABLE" +#CONFIG_USB0_VBUS_DET="AXP0-VBUS-DETECT" +CONFIG_AXP_GPIO=y +#CONFIG_USB_MUSB_HOST=y +CONFIG_DEFAULT_DEVICE_TREE="sun8i-a83t-sinovoip-bpi-m3" +# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +CONFIG_SPL=y +# CONFIG_CMD_IMLS is not set +# CONFIG_CMD_FLASH is not set +# CONFIG_CMD_FPGA is not set +CONFIG_AXP_DCDC1_VOLT=3000 +CONFIG_AXP_DCDC2_VOLT=900 +CONFIG_AXP_DCDC3_VOLT=900 +CONFIG_AXP_DCDC4_VOLT=0 +CONFIG_AXP_DCDC5_VOLT=1200 +CONFIG_AXP_ALDO2_VOLT=0 +CONFIG_AXP_ALDO3_VOLT=0 +CONFIG_AXP_DLDO4_VOLT=0 -- cgit v1.2.1 From c2caf65da5d15f8e21a4438104360caa8fbb6b7f Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Tue, 12 Jan 2016 14:42:36 +0800 Subject: power: axp818: Remove duplicate register definition macros Some of the register definitions are duplicated. Drop them. Signed-off-by: Chen-Yu Tsai Acked-by: Hans de Goede Signed-off-by: Hans de Goede --- include/axp818.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/include/axp818.h b/include/axp818.h index 1dc6456950..46d05ad04b 100644 --- a/include/axp818.h +++ b/include/axp818.h @@ -32,13 +32,6 @@ #define AXP818_OUTPUT_CTRL3_ALDO2_EN (1 << 6) #define AXP818_OUTPUT_CTRL3_ALDO3_EN (1 << 7) -#define AXP818_DCDC1_CTRL 0x20 -#define AXP818_DCDC2_CTRL 0x21 -#define AXP818_DCDC3_CTRL 0x22 -#define AXP818_DCDC4_CTRL 0x23 -#define AXP818_DCDC5_CTRL 0x24 -#define AXP818_DCDC6_CTRL 0x25 - #define AXP818_DLDO1_CTRL 0x15 #define AXP818_DLDO2_CTRL 0x16 #define AXP818_DLDO3_CTRL 0x17 @@ -46,7 +39,6 @@ #define AXP818_ELDO1_CTRL 0x19 #define AXP818_ELDO2_CTRL 0x1a #define AXP818_ELDO3_CTRL 0x1b -#define AXP818_ELDO3_CTRL 0x1b #define AXP818_FLDO1_CTRL 0x1c #define AXP818_FLDO2_3_CTRL 0x1d #define AXP818_DCDC1_CTRL 0x20 -- cgit v1.2.1 From 3517a27ddb1d12154e263a4f0bf91b4b76c21536 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Tue, 12 Jan 2016 14:42:37 +0800 Subject: power: axp: merge separate DLDO functions into 1 Instead of one function for each DLDO regulator, make 1 function that takes an extra "index". Since the control bits for the DLDO regulators are contiguous, this makes the function very simple. This removes a lot of duplicate code. Signed-off-by: Chen-Yu Tsai Acked-by: Hans de Goede Signed-off-by: Hans de Goede --- board/sunxi/board.c | 8 ++--- drivers/power/axp221.c | 88 ++++++++++++-------------------------------------- include/axp_pmic.h | 5 +-- 3 files changed, 25 insertions(+), 76 deletions(-) diff --git a/board/sunxi/board.c b/board/sunxi/board.c index 1cc39e4d18..958f5c5bae 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -466,10 +466,10 @@ void sunxi_board_init(void) #endif #ifdef CONFIG_AXP221_POWER - power_failed |= axp_set_dldo1(CONFIG_AXP_DLDO1_VOLT); - power_failed |= axp_set_dldo2(CONFIG_AXP_DLDO2_VOLT); - power_failed |= axp_set_dldo3(CONFIG_AXP_DLDO3_VOLT); - power_failed |= axp_set_dldo4(CONFIG_AXP_DLDO4_VOLT); + power_failed |= axp_set_dldo(1, CONFIG_AXP_DLDO1_VOLT); + power_failed |= axp_set_dldo(2, CONFIG_AXP_DLDO2_VOLT); + power_failed |= axp_set_dldo(3, CONFIG_AXP_DLDO3_VOLT); + power_failed |= axp_set_dldo(4, CONFIG_AXP_DLDO4_VOLT); power_failed |= axp_set_eldo(1, CONFIG_AXP_ELDO1_VOLT); power_failed |= axp_set_eldo(2, CONFIG_AXP_ELDO2_VOLT); power_failed |= axp_set_eldo(3, CONFIG_AXP_ELDO3_VOLT); diff --git a/drivers/power/axp221.c b/drivers/power/axp221.c index 8acadf0f9c..cb1f88b185 100644 --- a/drivers/power/axp221.c +++ b/drivers/power/axp221.c @@ -116,74 +116,6 @@ int axp_set_dcdc5(unsigned int mvolt) AXP221_OUTPUT_CTRL1_DCDC5_EN); } -int axp_set_dldo1(unsigned int mvolt) -{ - int ret; - u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100); - - if (mvolt == 0) - return pmic_bus_clrbits(AXP221_OUTPUT_CTRL2, - AXP221_OUTPUT_CTRL2_DLDO1_EN); - - ret = pmic_bus_write(AXP221_DLDO1_CTRL, cfg); - if (ret) - return ret; - - return pmic_bus_setbits(AXP221_OUTPUT_CTRL2, - AXP221_OUTPUT_CTRL2_DLDO1_EN); -} - -int axp_set_dldo2(unsigned int mvolt) -{ - int ret; - u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100); - - if (mvolt == 0) - return pmic_bus_clrbits(AXP221_OUTPUT_CTRL2, - AXP221_OUTPUT_CTRL2_DLDO2_EN); - - ret = pmic_bus_write(AXP221_DLDO2_CTRL, cfg); - if (ret) - return ret; - - return pmic_bus_setbits(AXP221_OUTPUT_CTRL2, - AXP221_OUTPUT_CTRL2_DLDO2_EN); -} - -int axp_set_dldo3(unsigned int mvolt) -{ - int ret; - u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100); - - if (mvolt == 0) - return pmic_bus_clrbits(AXP221_OUTPUT_CTRL2, - AXP221_OUTPUT_CTRL2_DLDO3_EN); - - ret = pmic_bus_write(AXP221_DLDO3_CTRL, cfg); - if (ret) - return ret; - - return pmic_bus_setbits(AXP221_OUTPUT_CTRL2, - AXP221_OUTPUT_CTRL2_DLDO3_EN); -} - -int axp_set_dldo4(unsigned int mvolt) -{ - int ret; - u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100); - - if (mvolt == 0) - return pmic_bus_clrbits(AXP221_OUTPUT_CTRL2, - AXP221_OUTPUT_CTRL2_DLDO4_EN); - - ret = pmic_bus_write(AXP221_DLDO4_CTRL, cfg); - if (ret) - return ret; - - return pmic_bus_setbits(AXP221_OUTPUT_CTRL2, - AXP221_OUTPUT_CTRL2_DLDO4_EN); -} - int axp_set_aldo1(unsigned int mvolt) { int ret; @@ -235,6 +167,26 @@ int axp_set_aldo3(unsigned int mvolt) AXP221_OUTPUT_CTRL3_ALDO3_EN); } +int axp_set_dldo(int dldo_num, unsigned int mvolt) +{ + u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100); + int ret; + + if (dldo_num < 1 || dldo_num > 4) + return -EINVAL; + + if (mvolt == 0) + return pmic_bus_clrbits(AXP221_OUTPUT_CTRL2, + AXP221_OUTPUT_CTRL2_DLDO1_EN << (dldo_num - 1)); + + ret = pmic_bus_write(AXP221_DLDO1_CTRL + (dldo_num - 1), cfg); + if (ret) + return ret; + + return pmic_bus_setbits(AXP221_OUTPUT_CTRL2, + AXP221_OUTPUT_CTRL2_DLDO1_EN << (dldo_num - 1)); +} + int axp_set_eldo(int eldo_num, unsigned int mvolt) { int ret; diff --git a/include/axp_pmic.h b/include/axp_pmic.h index 3b01c49cc9..0f14683509 100644 --- a/include/axp_pmic.h +++ b/include/axp_pmic.h @@ -29,10 +29,7 @@ int axp_set_aldo1(unsigned int mvolt); int axp_set_aldo2(unsigned int mvolt); int axp_set_aldo3(unsigned int mvolt); int axp_set_aldo4(unsigned int mvolt); -int axp_set_dldo1(unsigned int mvolt); -int axp_set_dldo2(unsigned int mvolt); -int axp_set_dldo3(unsigned int mvolt); -int axp_set_dldo4(unsigned int mvolt); +int axp_set_dldo(int dldo_num, unsigned int mvolt); int axp_set_eldo(int eldo_num, unsigned int mvolt); int axp_init(void); int axp_get_sid(unsigned int *sid); -- cgit v1.2.1 From 0509efb7e921ca1a274bb6b9702976e74f6b2b67 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Tue, 12 Jan 2016 14:42:38 +0800 Subject: power: axp818: Add support for DLDO and ELDO regulators AXP818 provides an array of LDOs to provide power to various peripherals. None of these regulators are critical. Signed-off-by: Chen-Yu Tsai Acked-by: Hans de Goede Signed-off-by: Hans de Goede --- drivers/power/Kconfig | 12 ++++++------ drivers/power/axp818.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index dfd60aa3fa..3d49b872e8 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -167,7 +167,7 @@ config AXP_ALDO4_VOLT config AXP_DLDO1_VOLT int "axp pmic dldo1 voltage" - depends on AXP221_POWER + depends on AXP221_POWER || AXP818_POWER default 0 ---help--- Set the voltage (mV) to program the axp pmic dldo1 at, set to 0 to @@ -177,7 +177,7 @@ config AXP_DLDO1_VOLT config AXP_DLDO2_VOLT int "axp pmic dldo2 voltage" - depends on AXP221_POWER + depends on AXP221_POWER || AXP818_POWER default 0 ---help--- Set the voltage (mV) to program the axp pmic dldo2 at, set to 0 to @@ -185,7 +185,7 @@ config AXP_DLDO2_VOLT config AXP_DLDO3_VOLT int "axp pmic dldo3 voltage" - depends on AXP221_POWER + depends on AXP221_POWER || AXP818_POWER default 0 ---help--- Set the voltage (mV) to program the axp pmic dldo3 at, set to 0 to @@ -201,7 +201,7 @@ config AXP_DLDO4_VOLT config AXP_ELDO1_VOLT int "axp pmic eldo1 voltage" - depends on AXP221_POWER + depends on AXP221_POWER || AXP818_POWER default 0 ---help--- Set the voltage (mV) to program the axp pmic eldo1 at, set to 0 to @@ -209,7 +209,7 @@ config AXP_ELDO1_VOLT config AXP_ELDO2_VOLT int "axp pmic eldo2 voltage" - depends on AXP221_POWER + depends on AXP221_POWER || AXP818_POWER default 0 ---help--- Set the voltage (mV) to program the axp pmic eldo2 at, set to 0 to @@ -217,7 +217,7 @@ config AXP_ELDO2_VOLT config AXP_ELDO3_VOLT int "axp pmic eldo3 voltage" - depends on AXP221_POWER + depends on AXP221_POWER || AXP818_POWER default 0 ---help--- Set the voltage (mV) to program the axp pmic eldo3 at, set to 0 to diff --git a/drivers/power/axp818.c b/drivers/power/axp818.c index 4b21a83879..3119b64ea1 100644 --- a/drivers/power/axp818.c +++ b/drivers/power/axp818.c @@ -110,6 +110,50 @@ int axp_set_dcdc5(unsigned int mvolt) AXP818_OUTPUT_CTRL1_DCDC5_EN); } +int axp_set_dldo(int dldo_num, unsigned int mvolt) +{ + int ret; + u8 cfg; + + if (dldo_num < 1 || dldo_num > 4) + return -EINVAL; + + if (mvolt == 0) + return pmic_bus_clrbits(AXP818_OUTPUT_CTRL2, + AXP818_OUTPUT_CTRL2_DLDO1_EN << (dldo_num - 1)); + + cfg = axp818_mvolt_to_cfg(mvolt, 700, 3300, 100); + if (dldo_num == 2 && mvolt > 3300) + cfg += 1 + axp818_mvolt_to_cfg(mvolt, 3400, 4200, 200); + ret = pmic_bus_write(AXP818_ELDO1_CTRL + (dldo_num - 1), cfg); + if (ret) + return ret; + + return pmic_bus_setbits(AXP818_OUTPUT_CTRL2, + AXP818_OUTPUT_CTRL2_DLDO1_EN << (dldo_num - 1)); +} + +int axp_set_eldo(int eldo_num, unsigned int mvolt) +{ + int ret; + u8 cfg; + + if (eldo_num < 1 || eldo_num > 3) + return -EINVAL; + + if (mvolt == 0) + return pmic_bus_clrbits(AXP818_OUTPUT_CTRL2, + AXP818_OUTPUT_CTRL2_ELDO1_EN << (eldo_num - 1)); + + cfg = axp818_mvolt_to_cfg(mvolt, 700, 1900, 50); + ret = pmic_bus_write(AXP818_ELDO1_CTRL + (eldo_num - 1), cfg); + if (ret) + return ret; + + return pmic_bus_setbits(AXP818_OUTPUT_CTRL2, + AXP818_OUTPUT_CTRL2_ELDO1_EN << (eldo_num - 1)); +} + int axp_init(void) { u8 axp_chip_id; -- cgit v1.2.1 From f7b4fff3f08e75c58f1819e8e7ca68af8afa61c2 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Tue, 12 Jan 2016 14:42:39 +0800 Subject: sunxi: h8_homlet_v2: Drop LDO settings from defconfig The LDO settings in this defconfig are either wrong (ALDOs must not be 0) or the same as Kconfig defaults. Signed-off-by: Chen-Yu Tsai Acked-by: Hans de Goede Signed-off-by: Hans de Goede --- configs/h8_homlet_v2_defconfig | 3 --- 1 file changed, 3 deletions(-) diff --git a/configs/h8_homlet_v2_defconfig b/configs/h8_homlet_v2_defconfig index dc2809acb0..ecd04a6629 100644 --- a/configs/h8_homlet_v2_defconfig +++ b/configs/h8_homlet_v2_defconfig @@ -19,6 +19,3 @@ CONFIG_AXP_DCDC2_VOLT=900 CONFIG_AXP_DCDC3_VOLT=900 CONFIG_AXP_DCDC4_VOLT=0 CONFIG_AXP_DCDC5_VOLT=1500 -CONFIG_AXP_ALDO2_VOLT=0 -CONFIG_AXP_ALDO3_VOLT=0 -CONFIG_AXP_DLDO4_VOLT=0 -- cgit v1.2.1 From f3c5045a95e0b9f164178bbf8de98b9adf3b099e Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Tue, 12 Jan 2016 14:42:40 +0800 Subject: sunxi: power: axp818: Enable support for ALDOs Previously, AXP818 ALDO support was partially added to Kconfig, but never enabled in the board file, nor properly set or configured in Kconfig. The boards continue to work because the AXP818 is designed to pair with the A83T/H8, and the default voltages match the reference design's requirements. Signed-off-by: Chen-Yu Tsai Acked-by: Hans de Goede Signed-off-by: Hans de Goede --- board/sunxi/board.c | 8 +++----- drivers/power/Kconfig | 13 ++++++++++--- drivers/power/axp818.c | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 8 deletions(-) diff --git a/board/sunxi/board.c b/board/sunxi/board.c index 958f5c5bae..420481a9fb 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -452,20 +452,18 @@ void sunxi_board_init(void) power_failed |= axp_set_dcdc5(CONFIG_AXP_DCDC5_VOLT); #endif -#ifdef CONFIG_AXP221_POWER +#if defined CONFIG_AXP221_POWER || defined CONFIG_AXP818_POWER power_failed |= axp_set_aldo1(CONFIG_AXP_ALDO1_VOLT); #endif -#ifndef CONFIG_AXP818_POWER power_failed |= axp_set_aldo2(CONFIG_AXP_ALDO2_VOLT); -#endif -#if !defined(CONFIG_AXP152_POWER) && !defined(CONFIG_AXP818_POWER) +#if !defined(CONFIG_AXP152_POWER) power_failed |= axp_set_aldo3(CONFIG_AXP_ALDO3_VOLT); #endif #ifdef CONFIG_AXP209_POWER power_failed |= axp_set_aldo4(CONFIG_AXP_ALDO4_VOLT); #endif -#ifdef CONFIG_AXP221_POWER +#if defined(CONFIG_AXP221_POWER) || defined(CONFIG_AXP818_POWER) power_failed |= axp_set_dldo(1, CONFIG_AXP_DLDO1_VOLT); power_failed |= axp_set_dldo(2, CONFIG_AXP_DLDO2_VOLT); power_failed |= axp_set_dldo(3, CONFIG_AXP_DLDO3_VOLT); diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 3d49b872e8..10683a21d9 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -121,20 +121,24 @@ config AXP_DCDC5_VOLT config AXP_ALDO1_VOLT int "axp pmic (a)ldo1 voltage" - depends on AXP221_POWER + depends on AXP221_POWER || AXP818_POWER default 0 if MACH_SUN6I + default 1800 if MACH_SUN8I_A83T default 3000 if MACH_SUN8I ---help--- Set the voltage (mV) to program the axp pmic aldo1 at, set to 0 to disable aldo1. On A31 boards aldo1 is often used to power the wifi module. On A23 / A33 boards aldo1 is used for VCC-IO and should be 3.0V. + On A83T / H8 boards aldo1 is used for MIPI CSI, DSI, HDMI, EFUSE, and + should be 1.8V. config AXP_ALDO2_VOLT int "axp pmic (a)ldo2 voltage" depends on AXP152_POWER || AXP209_POWER || AXP221_POWER || AXP818_POWER default 3000 if AXP152_POWER || AXP209_POWER default 0 if MACH_SUN6I + default 1800 if MACH_SUN8I_A83T default 2500 if MACH_SUN8I ---help--- Set the voltage (mV) to program the axp pmic aldo2 at, set to 0 to @@ -143,18 +147,21 @@ config AXP_ALDO2_VOLT On A31 boards aldo2 is typically unused and should be disabled. On A31 boards aldo2 may be used for LPDDR2 then it should be 1.8V. On A23 / A33 boards aldo2 is used for VDD-DLL and should be 2.5V. + On A83T / H8 boards aldo2 powers VDD-DLL, VCC18-PLL, CPVDD, VDD18-ADC, + LPDDR2, and the codec. It should be 1.8V. config AXP_ALDO3_VOLT int "axp pmic (a)ldo3 voltage" depends on AXP209_POWER || AXP221_POWER || AXP818_POWER - default 0 if AXP209_POWER || AXP818_POWER + default 0 if AXP209_POWER default 3000 if MACH_SUN6I || MACH_SUN8I ---help--- Set the voltage (mV) to program the axp pmic aldo3 at, set to 0 to disable aldo3. On A10(s) / A13 / A20 boards aldo3 should be 2.8V. On A23 / A31 / A33 boards aldo3 is VCC-PLL and AVCC and should be 3.0V. - On A83T aldo3 is used for LVDS, DSI, MIPI, HDMI, etc. + On A83T / H8 boards aldo3 is AVCC, VCC-PL, and VCC-LED, and should be + 3.0V. config AXP_ALDO4_VOLT int "axp pmic (a)ldo4 voltage" diff --git a/drivers/power/axp818.c b/drivers/power/axp818.c index 3119b64ea1..e885d02984 100644 --- a/drivers/power/axp818.c +++ b/drivers/power/axp818.c @@ -110,6 +110,43 @@ int axp_set_dcdc5(unsigned int mvolt) AXP818_OUTPUT_CTRL1_DCDC5_EN); } +int axp_set_aldo(int aldo_num, unsigned int mvolt) +{ + int ret; + u8 cfg; + + if (aldo_num < 1 || aldo_num > 3) + return -EINVAL; + + if (mvolt == 0) + return pmic_bus_clrbits(AXP818_OUTPUT_CTRL3, + AXP818_OUTPUT_CTRL3_ALDO1_EN << (aldo_num - 1)); + + cfg = axp818_mvolt_to_cfg(mvolt, 700, 3300, 100); + ret = pmic_bus_write(AXP818_ALDO1_CTRL + (aldo_num - 1), cfg); + if (ret) + return ret; + + return pmic_bus_setbits(AXP818_OUTPUT_CTRL3, + AXP818_OUTPUT_CTRL3_ALDO1_EN << (aldo_num - 1)); +} + +/* TODO: re-work other AXP drivers to consolidate ALDO functions. */ +int axp_set_aldo1(unsigned int mvolt) +{ + return axp_set_aldo(1, mvolt); +} + +int axp_set_aldo2(unsigned int mvolt) +{ + return axp_set_aldo(2, mvolt); +} + +int axp_set_aldo3(unsigned int mvolt) +{ + return axp_set_aldo(3, mvolt); +} + int axp_set_dldo(int dldo_num, unsigned int mvolt) { int ret; -- cgit v1.2.1 From 54be0f057825b886af008d8d43a97802e5537ab6 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 22 Jan 2016 14:55:47 +0100 Subject: sunxi: Bananapro: Set LDO4 to 2.5V According to the Bananapro schematic VDD25-SATA either comes from a dedicated WL2003E25-5 LTO, or it is connected to LDO4 via a 0 Ohm resistor. In practice it seems that LDO4 is used, so enable it and set it to 2.5V. Signed-off-by: Hans de Goede --- configs/Bananapro_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/Bananapro_defconfig b/configs/Bananapro_defconfig index 40588b9326..4f4a07be56 100644 --- a/configs/Bananapro_defconfig +++ b/configs/Bananapro_defconfig @@ -17,3 +17,4 @@ CONFIG_CMD_GPIO=y CONFIG_NETCONSOLE=y CONFIG_ETH_DESIGNWARE=y CONFIG_USB_EHCI_HCD=y +CONFIG_AXP_ALDO4_VOLT=2500 -- cgit v1.2.1 From 2ca02995791484007373ae51b3e7148511f1479b Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 26 Jan 2016 16:51:14 +0100 Subject: mvtwsi: Fix breakage introduced by "Fix mvtwsi not working on sun6i and newer sunxi SoCs" "Fix mvtwsi not working on sun6i and newer sunxi SoCs" includes the following: @@ -189,7 +200,8 @@ static int twsi_start(struct i2c_adapter *adap, int expected_status) /* globally set TWSIEN in case it was not */ twsi_control_flags |= MVTWSI_CONTROL_TWSIEN; /* assert START */ - writel(twsi_control_flags | MVTWSI_CONTROL_START, &twsi->control); + twsi_control_flags |= MVTWSI_CONTROL_START | MVTWSI_CONTROL_CLEAR_IFLG; + writel(twsi_control_flags, &twsi->control); /* wait for controller to process START */ return twsi_wait(adap, expected_status); } The modification of twsi_control_flags done here was introduced while merging to fix a line > 80 chars, but twsi_control_flags is a global variable and should not be modified like this here, this commit fixes this, restoring mvtwsi functionality. Signed-off-by: Hans de Goede --- drivers/i2c/mvtwsi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/mvtwsi.c b/drivers/i2c/mvtwsi.c index 5f993b9905..221ff4fe7a 100644 --- a/drivers/i2c/mvtwsi.c +++ b/drivers/i2c/mvtwsi.c @@ -204,8 +204,8 @@ static int twsi_start(struct i2c_adapter *adap, int expected_status) /* globally set TWSIEN in case it was not */ twsi_control_flags |= MVTWSI_CONTROL_TWSIEN; /* assert START */ - twsi_control_flags |= MVTWSI_CONTROL_START | MVTWSI_CONTROL_CLEAR_IFLG; - writel(twsi_control_flags, &twsi->control); + writel(twsi_control_flags | MVTWSI_CONTROL_START | + MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control); /* wait for controller to process START */ return twsi_wait(adap, expected_status); } -- cgit v1.2.1