[U-Boot] [PATCH 01/10] sunxi: Also set Auxiliary Ctl SMP bit in SPL

There is no reason not to and this make the #ifdef-ery easier to read.
Signed-off-by: Hans de Goede hdegoede@redhat.com --- arch/arm/cpu/armv7/sunxi/board.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c index c1b4cf5..6471c6b 100644 --- a/arch/arm/cpu/armv7/sunxi/board.c +++ b/arch/arm/cpu/armv7/sunxi/board.c @@ -94,8 +94,9 @@ void s_init(void) * access gets messed up (seems cache related) */ setbits_le32(SUNXI_SRAMC_BASE + 0x44, 0x1800); #endif -#if !defined CONFIG_SPL_BUILD && (defined CONFIG_MACH_SUN7I || \ - defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I) +#if defined CONFIG_MACH_SUN6I || \ + defined CONFIG_MACH_SUN7I || \ + defined CONFIG_MACH_SUN8I /* Enable SMP mode for CPU0, by setting bit 6 of Auxiliary Ctl reg */ asm volatile( "mrc p15, 0, r0, c1, c0, 1\n"

We do not use irqs in u-boot so remove the unused irq field, and all the #ifdef-ery around the irq initialization.
Signed-off-by: Hans de Goede hdegoede@redhat.com --- arch/arm/cpu/armv7/sunxi/usbc.c | 16 ---------------- 1 file changed, 16 deletions(-)
diff --git a/arch/arm/cpu/armv7/sunxi/usbc.c b/arch/arm/cpu/armv7/sunxi/usbc.c index a0e9604..80e4fc9 100644 --- a/arch/arm/cpu/armv7/sunxi/usbc.c +++ b/arch/arm/cpu/armv7/sunxi/usbc.c @@ -42,38 +42,22 @@ static struct sunxi_usbc_hcd { int ahb_clk_mask; int gpio_vbus; int gpio_vbus_det; - int irq; int id; } sunxi_usbc_hcd[] = { { .usb_rst_mask = CCM_USB_CTRL_PHY0_RST | CCM_USB_CTRL_PHY0_CLK, .ahb_clk_mask = 1 << AHB_GATE_OFFSET_USB0, -#if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I - .irq = 71, -#else - .irq = 38, -#endif .id = 0, }, { .usb_rst_mask = CCM_USB_CTRL_PHY1_RST | CCM_USB_CTRL_PHY1_CLK, .ahb_clk_mask = 1 << AHB_GATE_OFFSET_USB_EHCI0, -#if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I - .irq = 72, -#else - .irq = 39, -#endif .id = 1, }, #if (CONFIG_USB_MAX_CONTROLLER_COUNT > 1) { .usb_rst_mask = CCM_USB_CTRL_PHY2_RST | CCM_USB_CTRL_PHY2_CLK, .ahb_clk_mask = 1 << AHB_GATE_OFFSET_USB_EHCI1, -#ifdef CONFIG_MACH_SUN6I - .irq = 74, -#else - .irq = 40, -#endif .id = 2, } #endif

On Tue, 2015-04-14 at 18:06 +0200, Hans de Goede wrote:
We do not use irqs in u-boot so remove the unused irq field, and all the #ifdef-ery around the irq initialization.
Signed-off-by: Hans de Goede hdegoede@redhat.com
Acked-by: Ian Campbell ijc@hellion.org.uk

sun6i and newer (derived) SoCs such as the sun8i-a23, sun8i-a33 and sun9i have a various things in common, like having separate ahb reset control registers, the SID living inside the pmic, custom pmic busses, new style watchdog, etc.
This commit introduces a new hidden ARCH_SUN6I Kconfig bool which can be used to check for these features avoiding the need for an ever growing list of "#if defined CONFIG_MACH_SUN?I" conditionals as we add support for more "new style" sunxi SoCs.
Signed-off-by: Hans de Goede hdegoede@redhat.com --- arch/arm/cpu/armv7/sunxi/board.c | 18 +++++++++--------- arch/arm/cpu/armv7/sunxi/cpu_info.c | 2 +- arch/arm/cpu/armv7/sunxi/usbc.c | 4 ++-- arch/arm/include/asm/arch-sunxi/cpu_sun4i.h | 12 ++++++------ arch/arm/include/asm/arch-sunxi/mmc.h | 3 +-- arch/arm/include/asm/arch-sunxi/timer.h | 8 ++++---- board/sunxi/Kconfig | 9 +++++++++ board/sunxi/gmac.c | 6 +++--- drivers/mmc/sunxi_mmc.c | 3 +-- drivers/video/sunxi_display.c | 10 +++++----- 10 files changed, 41 insertions(+), 34 deletions(-)
diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c index 6471c6b..30d5974 100644 --- a/arch/arm/cpu/armv7/sunxi/board.c +++ b/arch/arm/cpu/armv7/sunxi/board.c @@ -173,7 +173,15 @@ void board_init_f(ulong dummy)
void reset_cpu(ulong addr) { -#if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN5I) || defined(CONFIG_MACH_SUN7I) +#ifdef CONFIG_ARCH_SUN6I + 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); +#else static const struct sunxi_wdog *wdog = &((struct sunxi_timer_reg *)SUNXI_TIMER_BASE)->wdog;
@@ -185,14 +193,6 @@ void reset_cpu(ulong addr) /* sun5i sometimes gets stuck without this */ writel(WDT_MODE_RESET_EN | WDT_MODE_EN, &wdog->mode); } -#else /* CONFIG_MACH_SUN6I || CONFIG_MACH_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 }
diff --git a/arch/arm/cpu/armv7/sunxi/cpu_info.c b/arch/arm/cpu/armv7/sunxi/cpu_info.c index b6cb9de..c3ec20d 100644 --- a/arch/arm/cpu/armv7/sunxi/cpu_info.c +++ b/arch/arm/cpu/armv7/sunxi/cpu_info.c @@ -76,7 +76,7 @@ int print_cpuinfo(void)
int sunxi_get_sid(unsigned int *sid) { -#if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I +#ifdef CONFIG_ARCH_SUN6I #ifdef CONFIG_AXP221_POWER return axp221_get_sid(sid); #else diff --git a/arch/arm/cpu/armv7/sunxi/usbc.c b/arch/arm/cpu/armv7/sunxi/usbc.c index 80e4fc9..85b3448 100644 --- a/arch/arm/cpu/armv7/sunxi/usbc.c +++ b/arch/arm/cpu/armv7/sunxi/usbc.c @@ -218,7 +218,7 @@ void sunxi_usbc_enable(int index)
setbits_le32(&ccm->usb_clk_cfg, sunxi_usbc->usb_rst_mask); setbits_le32(&ccm->ahb_gate0, sunxi_usbc->ahb_clk_mask); -#if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I +#ifdef CONFIG_ARCH_SUN6I setbits_le32(&ccm->ahb_reset0_cfg, sunxi_usbc->ahb_clk_mask); #endif
@@ -238,7 +238,7 @@ void sunxi_usbc_disable(int index) if (sunxi_usbc->id != 0) sunxi_usb_passby(sunxi_usbc, !SUNXI_USB_PASSBY_EN);
-#if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I +#ifdef CONFIG_ARCH_SUN6I clrbits_le32(&ccm->ahb_reset0_cfg, sunxi_usbc->ahb_clk_mask); #endif clrbits_le32(&ccm->ahb_gate0, sunxi_usbc->ahb_clk_mask); diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h index dae6069..3360e87 100644 --- a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h +++ b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h @@ -37,7 +37,7 @@ #define SUNXI_MMC1_BASE 0x01c10000 #define SUNXI_MMC2_BASE 0x01c11000 #define SUNXI_MMC3_BASE 0x01c12000 -#if !defined CONFIG_MACH_SUN6I && !defined CONFIG_MACH_SUN8I +#ifndef CONFIG_ARCH_SUN6I #define SUNXI_USB0_BASE 0x01c13000 #define SUNXI_USB1_BASE 0x01c14000 #endif @@ -45,15 +45,15 @@ #define SUNXI_HDMI_BASE 0x01c16000 #define SUNXI_SPI2_BASE 0x01c17000 #define SUNXI_SATA_BASE 0x01c18000 -#if !defined CONFIG_MACH_SUN6I && !defined CONFIG_MACH_SUN8I +#ifdef CONFIG_ARCH_SUN6I +#define SUNXI_USB0_BASE 0x01c19000 +#define SUNXI_USB1_BASE 0x01c1a000 +#define SUNXI_USB2_BASE 0x01c1b000 +#else #define SUNXI_PATA_BASE 0x01c19000 #define SUNXI_ACE_BASE 0x01c1a000 #define SUNXI_TVE1_BASE 0x01c1b000 #define SUNXI_USB2_BASE 0x01c1c000 -#else -#define SUNXI_USB0_BASE 0x01c19000 -#define SUNXI_USB1_BASE 0x01c1a000 -#define SUNXI_USB2_BASE 0x01c1b000 #endif #define SUNXI_CSI1_BASE 0x01c1d000 #define SUNXI_TZASC_BASE 0x01c1e000 diff --git a/arch/arm/include/asm/arch-sunxi/mmc.h b/arch/arm/include/asm/arch-sunxi/mmc.h index 74833b5..bd1987c 100644 --- a/arch/arm/include/asm/arch-sunxi/mmc.h +++ b/arch/arm/include/asm/arch-sunxi/mmc.h @@ -43,8 +43,7 @@ struct sunxi_mmc { u32 chda; /* 0x90 */ u32 cbda; /* 0x94 */ u32 res1[26]; -#if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN8I) || \ - defined(CONFIG_MACH_SUN9I) +#ifdef CONFIG_ARCH_SUN6I u32 res2[64]; #endif u32 fifo; /* 0x100 / 0x200 FIFO access address */ diff --git a/arch/arm/include/asm/arch-sunxi/timer.h b/arch/arm/include/asm/arch-sunxi/timer.h index 9a5e488..a6cc443 100644 --- a/arch/arm/include/asm/arch-sunxi/timer.h +++ b/arch/arm/include/asm/arch-sunxi/timer.h @@ -67,7 +67,10 @@ struct sunxi_timer_reg { struct sunxi_timer timer[6]; /* We have 6 timers */ u8 res2[16]; struct sunxi_avs avs; -#if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN5I) || defined(CONFIG_MACH_SUN7I) +#ifdef CONFIG_ARCH_SUN6I + u8 res3[16]; + struct sunxi_wdog wdog[5]; /* We have 5 watchdogs */ +#else struct sunxi_wdog wdog; /* 0x90 */ /* XXX the following is not accurate for sun5i/sun7i */ struct sunxi_64cnt cnt64; /* 0xa0 */ @@ -77,9 +80,6 @@ struct sunxi_timer_reg { struct sunxi_tgp tgp[4]; u8 res5[8]; u32 cpu_cfg; -#else /* CONFIG_MACH_SUN6I || CONFIG_MACH_SUN8I || ... */ - u8 res3[16]; - struct sunxi_wdog wdog[5]; /* We have 5 watchdogs */ #endif };
diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index ccc2080..34044f8 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -1,5 +1,12 @@ if ARCH_SUNXI
+config ARCH_SUN6I + bool + ---help--- + Select this for sunxi SoCs which have sun6i like periphery, like + separate ahb reset control registers, custom pmic bus, new style + watchdog, etc. + choice prompt "Sunxi SoC Variant"
@@ -15,6 +22,7 @@ config MACH_SUN5I
config MACH_SUN6I bool "sun6i (Allwinner A31)" + select ARCH_SUN6I select CPU_V7 select SUPPORT_SPL
@@ -28,6 +36,7 @@ config MACH_SUN7I
config MACH_SUN8I bool "sun8i (Allwinner A23)" + select ARCH_SUN6I select CPU_V7 select SUPPORT_SPL
diff --git a/board/sunxi/gmac.c b/board/sunxi/gmac.c index 63a7360..2cba891 100644 --- a/board/sunxi/gmac.c +++ b/board/sunxi/gmac.c @@ -13,11 +13,11 @@ int sunxi_gmac_initialize(bd_t *bis) (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
/* Set up clock gating */ -#ifndef CONFIG_MACH_SUN6I - setbits_le32(&ccm->ahb_gate1, 0x1 << AHB_GATE_OFFSET_GMAC); -#else +#ifdef CONFIG_ARCH_SUN6I setbits_le32(&ccm->ahb_reset0_cfg, 0x1 << AHB_RESET_OFFSET_GMAC); setbits_le32(&ccm->ahb_gate0, 0x1 << AHB_GATE_OFFSET_GMAC); +#else + setbits_le32(&ccm->ahb_gate1, 0x1 << AHB_GATE_OFFSET_GMAC); #endif
/* Set MII clock */ diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index 2233545..fcc278d 100644 --- a/drivers/mmc/sunxi_mmc.c +++ b/drivers/mmc/sunxi_mmc.c @@ -151,8 +151,7 @@ static int mmc_clk_io_on(int sdc_no) /* config ahb clock */ setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MMC(sdc_no));
-#if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN8I) || \ - defined(CONFIG_MACH_SUN9I) +#ifdef CONFIG_ARCH_SUN6I /* unassert reset */ setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MMC(sdc_no)); #endif diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c index d2341b0..e132b75 100644 --- a/drivers/video/sunxi_display.c +++ b/drivers/video/sunxi_display.c @@ -84,7 +84,7 @@ static int sunxi_hdmi_hpd_detect(int hpd_delay) CCM_HDMI_CTRL_PLL3);
/* Set ahb gating to pass */ -#ifdef CONFIG_MACH_SUN6I +#ifdef CONFIG_ARCH_SUN6I setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_HDMI); #endif setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_HDMI); @@ -113,7 +113,7 @@ static void sunxi_hdmi_shutdown(void) clrbits_le32(&hdmi->ctrl, SUNXI_HDMI_CTRL_ENABLE); clrbits_le32(&ccm->hdmi_clk_cfg, CCM_HDMI_CTRL_GATE); clrbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_HDMI); -#ifdef CONFIG_MACH_SUN6I +#ifdef CONFIG_ARCH_SUN6I clrbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_HDMI); #endif clock_set_pll3(0); @@ -404,7 +404,7 @@ static void sunxi_composer_init(void)
sunxi_frontend_init();
-#if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I +#ifdef CONFIG_ARCH_SUN6I /* Reset off */ setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_DE_BE0); #endif @@ -549,7 +549,7 @@ static void sunxi_lcdc_init(void) (struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE;
/* Reset off */ -#if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I +#ifdef CONFIG_ARCH_SUN6I setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_LCD0); #else setbits_le32(&ccm->lcd0_ch0_clk_cfg, CCM_LCD_CH0_CTRL_RST); @@ -942,7 +942,7 @@ static void sunxi_vga_enable(void)
static void sunxi_drc_init(void) { -#if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I +#ifdef CONFIG_ARCH_SUN6I struct sunxi_ccm_reg * const ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;

On 14 April 2015 at 18:06, Hans de Goede hdegoede@redhat.com wrote:
sun6i and newer (derived) SoCs such as the sun8i-a23, sun8i-a33 and sun9i have a various things in common, like having separate ahb reset control registers, the SID living inside the pmic, custom pmic busses, new style watchdog, etc.
This commit introduces a new hidden ARCH_SUN6I Kconfig bool which can be used to check for these features avoiding the need for an ever growing list of "#if defined CONFIG_MACH_SUN?I" conditionals as we add support for more "new style" sunxi SoCs.
Signed-off-by: Hans de Goede hdegoede@redhat.com
arch/arm/cpu/armv7/sunxi/board.c | 18 +++++++++--------- arch/arm/cpu/armv7/sunxi/cpu_info.c | 2 +- arch/arm/cpu/armv7/sunxi/usbc.c | 4 ++-- arch/arm/include/asm/arch-sunxi/cpu_sun4i.h | 12 ++++++------ arch/arm/include/asm/arch-sunxi/mmc.h | 3 +-- arch/arm/include/asm/arch-sunxi/timer.h | 8 ++++---- board/sunxi/Kconfig | 9 +++++++++ board/sunxi/gmac.c | 6 +++--- drivers/mmc/sunxi_mmc.c | 3 +-- drivers/video/sunxi_display.c | 10 +++++----- 10 files changed, 41 insertions(+), 34 deletions(-)
diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c index 6471c6b..30d5974 100644 --- a/arch/arm/cpu/armv7/sunxi/board.c +++ b/arch/arm/cpu/armv7/sunxi/board.c @@ -173,7 +173,15 @@ void board_init_f(ulong dummy)
void reset_cpu(ulong addr) { -#if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN5I) || defined(CONFIG_MACH_SUN7I) +#ifdef CONFIG_ARCH_SUN6I
Hello,
this looks wrong.
Either this is ARCH_SUNXI and it coverts all or it's ARCH_SUN6I and then SUN4I and SUN5I should still be checked separately.
diff --git a/arch/arm/include/asm/arch-sunxi/timer.h b/arch/arm/include/asm/arch-sunxi/timer.h index 9a5e488..a6cc443 100644 --- a/arch/arm/include/asm/arch-sunxi/timer.h +++ b/arch/arm/include/asm/arch-sunxi/timer.h @@ -67,7 +67,10 @@ struct sunxi_timer_reg { struct sunxi_timer timer[6]; /* We have 6 timers */ u8 res2[16]; struct sunxi_avs avs; -#if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN5I) || defined(CONFIG_MACH_SUN7I) +#ifdef CONFIG_ARCH_SUN6I
ditto
Thanks
Michal

Hi,
On 15-04-15 08:51, Michal Suchanek wrote:
On 14 April 2015 at 18:06, Hans de Goede hdegoede@redhat.com wrote:
sun6i and newer (derived) SoCs such as the sun8i-a23, sun8i-a33 and sun9i have a various things in common, like having separate ahb reset control registers, the SID living inside the pmic, custom pmic busses, new style watchdog, etc.
This commit introduces a new hidden ARCH_SUN6I Kconfig bool which can be used to check for these features avoiding the need for an ever growing list of "#if defined CONFIG_MACH_SUN?I" conditionals as we add support for more "new style" sunxi SoCs.
Signed-off-by: Hans de Goede hdegoede@redhat.com
arch/arm/cpu/armv7/sunxi/board.c | 18 +++++++++--------- arch/arm/cpu/armv7/sunxi/cpu_info.c | 2 +- arch/arm/cpu/armv7/sunxi/usbc.c | 4 ++-- arch/arm/include/asm/arch-sunxi/cpu_sun4i.h | 12 ++++++------ arch/arm/include/asm/arch-sunxi/mmc.h | 3 +-- arch/arm/include/asm/arch-sunxi/timer.h | 8 ++++---- board/sunxi/Kconfig | 9 +++++++++ board/sunxi/gmac.c | 6 +++--- drivers/mmc/sunxi_mmc.c | 3 +-- drivers/video/sunxi_display.c | 10 +++++----- 10 files changed, 41 insertions(+), 34 deletions(-)
diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c index 6471c6b..30d5974 100644 --- a/arch/arm/cpu/armv7/sunxi/board.c +++ b/arch/arm/cpu/armv7/sunxi/board.c @@ -173,7 +173,15 @@ void board_init_f(ulong dummy)
void reset_cpu(ulong addr) { -#if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN5I) || defined(CONFIG_MACH_SUN7I) +#ifdef CONFIG_ARCH_SUN6I
Hello,
this looks wrong.
Either this is ARCH_SUNXI and it coverts all or it's ARCH_SUN6I and then SUN4I and SUN5I should still be checked separately.
Look closer, the blocks before / after the #else are swapped to avoid needing to use #ifndef without good reason as that is ugly.
diff --git a/arch/arm/include/asm/arch-sunxi/timer.h b/arch/arm/include/asm/arch-sunxi/timer.h index 9a5e488..a6cc443 100644 --- a/arch/arm/include/asm/arch-sunxi/timer.h +++ b/arch/arm/include/asm/arch-sunxi/timer.h @@ -67,7 +67,10 @@ struct sunxi_timer_reg { struct sunxi_timer timer[6]; /* We have 6 timers */ u8 res2[16]; struct sunxi_avs avs; -#if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN5I) || defined(CONFIG_MACH_SUN7I) +#ifdef CONFIG_ARCH_SUN6I
Same here.
Regards,
Hans

On 15 April 2015 at 09:35, Hans de Goede hdegoede@redhat.com wrote:
Hi,
On 15-04-15 08:51, Michal Suchanek wrote:
On 14 April 2015 at 18:06, Hans de Goede hdegoede@redhat.com wrote:
sun6i and newer (derived) SoCs such as the sun8i-a23, sun8i-a33 and sun9i have a various things in common, like having separate ahb reset control registers, the SID living inside the pmic, custom pmic busses, new style watchdog, etc.
This commit introduces a new hidden ARCH_SUN6I Kconfig bool which can be used to check for these features avoiding the need for an ever growing list of "#if defined CONFIG_MACH_SUN?I" conditionals as we add support for more "new style" sunxi SoCs.
Signed-off-by: Hans de Goede hdegoede@redhat.com
arch/arm/cpu/armv7/sunxi/board.c | 18 +++++++++--------- arch/arm/cpu/armv7/sunxi/cpu_info.c | 2 +- arch/arm/cpu/armv7/sunxi/usbc.c | 4 ++-- arch/arm/include/asm/arch-sunxi/cpu_sun4i.h | 12 ++++++------ arch/arm/include/asm/arch-sunxi/mmc.h | 3 +-- arch/arm/include/asm/arch-sunxi/timer.h | 8 ++++---- board/sunxi/Kconfig | 9 +++++++++ board/sunxi/gmac.c | 6 +++--- drivers/mmc/sunxi_mmc.c | 3 +-- drivers/video/sunxi_display.c | 10 +++++----- 10 files changed, 41 insertions(+), 34 deletions(-)
diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c index 6471c6b..30d5974 100644 --- a/arch/arm/cpu/armv7/sunxi/board.c +++ b/arch/arm/cpu/armv7/sunxi/board.c @@ -173,7 +173,15 @@ void board_init_f(ulong dummy)
void reset_cpu(ulong addr) { -#if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN5I) || defined(CONFIG_MACH_SUN7I) +#ifdef CONFIG_ARCH_SUN6I
Hello,
this looks wrong.
Either this is ARCH_SUNXI and it coverts all or it's ARCH_SUN6I and then SUN4I and SUN5I should still be checked separately.
Look closer, the blocks before / after the #else are swapped to avoid needing to use #ifndef without good reason as that is ugly.
So you mean that
ARCH_SUN6I is !defined(MACH_SUN4I) && !defined(MACH_SUN5I) && !defined(MACH_SUN7I) && (defined(MACH_SUN6I) || defined(MACH_SUN8I) || defined(MACH_SUN9I))
Now that is ugly.
This probably needs a better name then.
Thanks
Michal

Hi,
On 15-04-15 10:01, Michal Suchanek wrote:
On 15 April 2015 at 09:35, Hans de Goede hdegoede@redhat.com wrote:
Hi,
On 15-04-15 08:51, Michal Suchanek wrote:
On 14 April 2015 at 18:06, Hans de Goede hdegoede@redhat.com wrote:
sun6i and newer (derived) SoCs such as the sun8i-a23, sun8i-a33 and sun9i have a various things in common, like having separate ahb reset control registers, the SID living inside the pmic, custom pmic busses, new style watchdog, etc.
This commit introduces a new hidden ARCH_SUN6I Kconfig bool which can be used to check for these features avoiding the need for an ever growing list of "#if defined CONFIG_MACH_SUN?I" conditionals as we add support for more "new style" sunxi SoCs.
Signed-off-by: Hans de Goede hdegoede@redhat.com
arch/arm/cpu/armv7/sunxi/board.c | 18 +++++++++--------- arch/arm/cpu/armv7/sunxi/cpu_info.c | 2 +- arch/arm/cpu/armv7/sunxi/usbc.c | 4 ++-- arch/arm/include/asm/arch-sunxi/cpu_sun4i.h | 12 ++++++------ arch/arm/include/asm/arch-sunxi/mmc.h | 3 +-- arch/arm/include/asm/arch-sunxi/timer.h | 8 ++++---- board/sunxi/Kconfig | 9 +++++++++ board/sunxi/gmac.c | 6 +++--- drivers/mmc/sunxi_mmc.c | 3 +-- drivers/video/sunxi_display.c | 10 +++++----- 10 files changed, 41 insertions(+), 34 deletions(-)
diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c index 6471c6b..30d5974 100644 --- a/arch/arm/cpu/armv7/sunxi/board.c +++ b/arch/arm/cpu/armv7/sunxi/board.c @@ -173,7 +173,15 @@ void board_init_f(ulong dummy)
void reset_cpu(ulong addr) { -#if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN5I) || defined(CONFIG_MACH_SUN7I) +#ifdef CONFIG_ARCH_SUN6I
Hello,
this looks wrong.
Either this is ARCH_SUNXI and it coverts all or it's ARCH_SUN6I and then SUN4I and SUN5I should still be checked separately.
Look closer, the blocks before / after the #else are swapped to avoid needing to use #ifndef without good reason as that is ugly.
So you mean that
ARCH_SUN6I is !defined(MACH_SUN4I) && !defined(MACH_SUN5I) && !defined(MACH_SUN7I) && (defined(MACH_SUN6I) || defined(MACH_SUN8I) || defined(MACH_SUN9I))
Now that is ugly.
This probably needs a better name then.
What this needs is less bikeshedding and you to actually take your time to properly read the patch.
If you read the help text in the Kconfig file then you will see that
ARCH_SUN6I is set for sun6i derived designs, which all have a number of things in common, such as having separate ahb reset registers in the ccm.
Regards,
Hans
Thanks
Michal

On 15 April 2015 at 10:07, Hans de Goede hdegoede@redhat.com wrote:
Hi,
On 15-04-15 10:01, Michal Suchanek wrote:
On 15 April 2015 at 09:35, Hans de Goede hdegoede@redhat.com wrote:
Hi,
On 15-04-15 08:51, Michal Suchanek wrote:
On 14 April 2015 at 18:06, Hans de Goede hdegoede@redhat.com wrote:
sun6i and newer (derived) SoCs such as the sun8i-a23, sun8i-a33 and sun9i have a various things in common, like having separate ahb reset control registers, the SID living inside the pmic, custom pmic busses, new style watchdog, etc.
This commit introduces a new hidden ARCH_SUN6I Kconfig bool which can be used to check for these features avoiding the need for an ever growing list of "#if defined CONFIG_MACH_SUN?I" conditionals as we add support for more "new style" sunxi SoCs.
Signed-off-by: Hans de Goede hdegoede@redhat.com
arch/arm/cpu/armv7/sunxi/board.c | 18 +++++++++--------- arch/arm/cpu/armv7/sunxi/cpu_info.c | 2 +- arch/arm/cpu/armv7/sunxi/usbc.c | 4 ++-- arch/arm/include/asm/arch-sunxi/cpu_sun4i.h | 12 ++++++------ arch/arm/include/asm/arch-sunxi/mmc.h | 3 +-- arch/arm/include/asm/arch-sunxi/timer.h | 8 ++++---- board/sunxi/Kconfig | 9 +++++++++ board/sunxi/gmac.c | 6 +++--- drivers/mmc/sunxi_mmc.c | 3 +-- drivers/video/sunxi_display.c | 10 +++++----- 10 files changed, 41 insertions(+), 34 deletions(-)
diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c index 6471c6b..30d5974 100644 --- a/arch/arm/cpu/armv7/sunxi/board.c +++ b/arch/arm/cpu/armv7/sunxi/board.c @@ -173,7 +173,15 @@ void board_init_f(ulong dummy)
void reset_cpu(ulong addr) { -#if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN5I) || defined(CONFIG_MACH_SUN7I) +#ifdef CONFIG_ARCH_SUN6I
Hello,
this looks wrong.
Either this is ARCH_SUNXI and it coverts all or it's ARCH_SUN6I and then SUN4I and SUN5I should still be checked separately.
Look closer, the blocks before / after the #else are swapped to avoid needing to use #ifndef without good reason as that is ugly.
So you mean that
ARCH_SUN6I is !defined(MACH_SUN4I) && !defined(MACH_SUN5I) && !defined(MACH_SUN7I) && (defined(MACH_SUN6I) || defined(MACH_SUN8I) || defined(MACH_SUN9I))
Now that is ugly.
This probably needs a better name then.
What this needs is less bikeshedding and you to actually take your time to properly read the patch.
If you read the help text in the Kconfig file then you will see that
ARCH_SUN6I is set for sun6i derived designs, which all have a number of things in common, such as having separate ahb reset registers in the ccm.
Sorry, I see the code is technically correct.
However, if the purpose of this patch was to make the code clearer then it fails at that.
It is unclear even reading the commit message, and that is not included in the code.
It is not obvious which MACH_SUN?I are ARCH_SUN6I derived. So if you can come up with a descriptive name for 'a number of things in common, such as having separate ahb reset registers in the ccm' that's fine otherwise this obfuscates the code, not clarifies.
That's not to say that simplifying the ifdefs does not have some value. Just expect 'WTH does SUN7I not select SUN6I?' come up from time to time.
Thanks
Michal

On Wed, 2015-04-15 at 10:45 +0200, Michal Suchanek wrote:
It is not obvious which MACH_SUN?I are ARCH_SUN6I derived. So if you can come up with a descriptive name for 'a number of things in common, such as having separate ahb reset registers in the ccm' that's fine otherwise this obfuscates the code, not clarifies.
I don't particularly object to the patch but this occurred to me too. I suppose the rule is "first sunxi to look this way".
How about we call groups of similar SoCs a "generation", i.e. ARCH_SUNXI_GEN2 is what is called ARCH_SUN6I here, meaning GEN1 would be SUN4/5/7I.
I've deliberately not considered SUN1/2/3I since I don't know much about them, and we don't support them AFAIK, but perhaps the generation numbers I've picked should be larger to accommodate them.
Ian.

Hi,
On 15-04-15 21:47, Ian Campbell wrote:
On Wed, 2015-04-15 at 10:45 +0200, Michal Suchanek wrote:
It is not obvious which MACH_SUN?I are ARCH_SUN6I derived. So if you can come up with a descriptive name for 'a number of things in common, such as having separate ahb reset registers in the ccm' that's fine otherwise this obfuscates the code, not clarifies.
I don't particularly object to the patch but this occurred to me too. I suppose the rule is "first sunxi to look this way".
How about we call groups of similar SoCs a "generation", i.e. ARCH_SUNXI_GEN2 is what is called ARCH_SUN6I here, meaning GEN1 would be SUN4/5/7I.
I like the GEN idea, but not the numbering as it is a bit too arbitrary how about: ARCH_SUNXI_GEN_SUN6I or (better I think) just SUNXI_GEN_SUN6I ?
I know that does not solve the fact that MACH_SUN7I is SUNXI_GEN_SUN4I but we cannot fix that, at least this way it will be explicit.
Regards,
Hans

On Thu, 2015-04-16 at 09:23 +0200, Hans de Goede wrote:
Hi,
On 15-04-15 21:47, Ian Campbell wrote:
On Wed, 2015-04-15 at 10:45 +0200, Michal Suchanek wrote:
It is not obvious which MACH_SUN?I are ARCH_SUN6I derived. So if you can come up with a descriptive name for 'a number of things in common, such as having separate ahb reset registers in the ccm' that's fine otherwise this obfuscates the code, not clarifies.
I don't particularly object to the patch but this occurred to me too. I suppose the rule is "first sunxi to look this way".
How about we call groups of similar SoCs a "generation", i.e. ARCH_SUNXI_GEN2 is what is called ARCH_SUN6I here, meaning GEN1 would be SUN4/5/7I.
I like the GEN idea, but not the numbering as it is a bit too arbitrary how about: ARCH_SUNXI_GEN_SUN6I or (better I think) just SUNXI_GEN_SUN6I ?
Works for me (I agree the second is better too).
I know that does not solve the fact that MACH_SUN7I is SUNXI_GEN_SUN4I but we cannot fix that, at least this way it will be explicit.
Regards,
Hans

On 14 April 2015 at 18:06, Hans de Goede hdegoede@redhat.com wrote:
--- a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h +++ b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h @@ -37,7 +37,7 @@ #define SUNXI_MMC1_BASE 0x01c10000 #define SUNXI_MMC2_BASE 0x01c11000 #define SUNXI_MMC3_BASE 0x01c12000 -#if !defined CONFIG_MACH_SUN6I && !defined CONFIG_MACH_SUN8I +#ifndef CONFIG_ARCH_SUN6I #define SUNXI_USB0_BASE 0x01c13000 #define SUNXI_USB1_BASE 0x01c14000 #endif @@ -45,15 +45,15 @@ #define SUNXI_HDMI_BASE 0x01c16000 #define SUNXI_SPI2_BASE 0x01c17000 #define SUNXI_SATA_BASE 0x01c18000 -#if !defined CONFIG_MACH_SUN6I && !defined CONFIG_MACH_SUN8I +#ifdef CONFIG_ARCH_SUN6I
Also here #ifndef is changed to #ifdef
Thanks
Michal

Hi,
On 15-04-15 09:00, Michal Suchanek wrote:
On 14 April 2015 at 18:06, Hans de Goede hdegoede@redhat.com wrote:
--- a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h +++ b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h @@ -37,7 +37,7 @@ #define SUNXI_MMC1_BASE 0x01c10000 #define SUNXI_MMC2_BASE 0x01c11000 #define SUNXI_MMC3_BASE 0x01c12000 -#if !defined CONFIG_MACH_SUN6I && !defined CONFIG_MACH_SUN8I +#ifndef CONFIG_ARCH_SUN6I #define SUNXI_USB0_BASE 0x01c13000 #define SUNXI_USB1_BASE 0x01c14000 #endif @@ -45,15 +45,15 @@ #define SUNXI_HDMI_BASE 0x01c16000 #define SUNXI_SPI2_BASE 0x01c17000 #define SUNXI_SATA_BASE 0x01c18000 -#if !defined CONFIG_MACH_SUN6I && !defined CONFIG_MACH_SUN8I +#ifdef CONFIG_ARCH_SUN6I
Also here #ifndef is changed to #ifdef
And the same here too.
Regards,
Hans

This is a preparation patch for adding A33 support, which will have a mach name of sun8i-a33.
Signed-off-by: Hans de Goede hdegoede@redhat.com --- arch/arm/cpu/armv7/sunxi/Makefile | 8 ++++---- arch/arm/cpu/armv7/sunxi/board.c | 8 ++++---- arch/arm/cpu/armv7/sunxi/cpu_info.c | 2 +- .../cpu/armv7/sunxi/{dram_sun8i.c => dram_sun8i_a23.c} | 0 arch/arm/cpu/armv7/sunxi/rsb.c | 2 +- arch/arm/include/asm/arch-sunxi/clock.h | 3 ++- arch/arm/include/asm/arch-sunxi/clock_sun6i.h | 6 +++--- arch/arm/include/asm/arch-sunxi/dram.h | 4 ++-- .../asm/arch-sunxi/{dram_sun8i.h => dram_sun8i_a23.h} | 0 board/sunxi/Kconfig | 15 ++++++++------- board/sunxi/board.c | 4 ++-- configs/Ippo_q8h_v1_2_defconfig | 2 +- configs/Ippo_q8h_v5_defconfig | 2 +- drivers/power/Kconfig | 4 ++-- include/configs/sunxi-common.h | 2 +- 15 files changed, 32 insertions(+), 30 deletions(-) rename arch/arm/cpu/armv7/sunxi/{dram_sun8i.c => dram_sun8i_a23.c} (100%) rename arch/arm/include/asm/arch-sunxi/{dram_sun8i.h => dram_sun8i_a23.h} (100%)
diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile index 4bb12ad..b2e5e5d 100644 --- a/arch/arm/cpu/armv7/sunxi/Makefile +++ b/arch/arm/cpu/armv7/sunxi/Makefile @@ -15,16 +15,16 @@ obj-y += dram_helpers.o obj-y += pinmux.o obj-y += usbc.o obj-$(CONFIG_MACH_SUN6I) += prcm.o -obj-$(CONFIG_MACH_SUN8I) += prcm.o +obj-$(CONFIG_MACH_SUN8I_A23) += prcm.o obj-$(CONFIG_MACH_SUN9I) += prcm.o obj-$(CONFIG_MACH_SUN6I) += p2wi.o -obj-$(CONFIG_MACH_SUN8I) += rsb.o +obj-$(CONFIG_MACH_SUN8I_A23) += rsb.o obj-$(CONFIG_MACH_SUN9I) += rsb.o obj-$(CONFIG_MACH_SUN4I) += clock_sun4i.o obj-$(CONFIG_MACH_SUN5I) += clock_sun4i.o obj-$(CONFIG_MACH_SUN6I) += clock_sun6i.o obj-$(CONFIG_MACH_SUN7I) += clock_sun4i.o -obj-$(CONFIG_MACH_SUN8I) += clock_sun6i.o +obj-$(CONFIG_MACH_SUN8I_A23) += clock_sun6i.o obj-$(CONFIG_MACH_SUN9I) += clock_sun9i.o
ifndef CONFIG_SPL_BUILD @@ -38,6 +38,6 @@ obj-$(CONFIG_MACH_SUN4I) += dram_sun4i.o obj-$(CONFIG_MACH_SUN5I) += dram_sun4i.o obj-$(CONFIG_MACH_SUN6I) += dram_sun6i.o obj-$(CONFIG_MACH_SUN7I) += dram_sun4i.o -obj-$(CONFIG_MACH_SUN8I) += dram_sun8i.o +obj-$(CONFIG_MACH_SUN8I_A23) += dram_sun8i_a23.o obj-y += fel_utils.o endif diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c index 30d5974..7ce79af 100644 --- a/arch/arm/cpu/armv7/sunxi/board.c +++ b/arch/arm/cpu/armv7/sunxi/board.c @@ -46,7 +46,7 @@ static int gpio_init(void) sunxi_gpio_set_cfgpin(SUNXI_GPB(22), SUNXI_GPIO_INPUT); sunxi_gpio_set_cfgpin(SUNXI_GPB(23), SUNXI_GPIO_INPUT); #endif -#if defined(CONFIG_MACH_SUN8I) +#if defined(CONFIG_MACH_SUN8I_A23) sunxi_gpio_set_cfgpin(SUNXI_GPF(2), SUN8I_GPF_UART0_TX); sunxi_gpio_set_cfgpin(SUNXI_GPF(4), SUN8I_GPF_UART0_RX); #else @@ -70,7 +70,7 @@ static int gpio_init(void) sunxi_gpio_set_cfgpin(SUNXI_GPG(3), SUN5I_GPG_UART1); sunxi_gpio_set_cfgpin(SUNXI_GPG(4), SUN5I_GPG_UART1); sunxi_gpio_set_pull(SUNXI_GPG(4), SUNXI_GPIO_PULL_UP); -#elif CONFIG_CONS_INDEX == 5 && defined(CONFIG_MACH_SUN8I) +#elif CONFIG_CONS_INDEX == 5 && defined(CONFIG_MACH_SUN8I_A23) sunxi_gpio_set_cfgpin(SUNXI_GPL(2), SUN8I_GPL_R_UART); sunxi_gpio_set_cfgpin(SUNXI_GPL(3), SUN8I_GPL_R_UART); sunxi_gpio_set_pull(SUNXI_GPL(3), SUNXI_GPIO_PULL_UP); @@ -89,14 +89,14 @@ void spl_board_load_image(void)
void s_init(void) { -#if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I +#if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I_A23 /* Magic (undocmented) value taken from boot0, without this DRAM * access gets messed up (seems cache related) */ setbits_le32(SUNXI_SRAMC_BASE + 0x44, 0x1800); #endif #if defined CONFIG_MACH_SUN6I || \ defined CONFIG_MACH_SUN7I || \ - defined CONFIG_MACH_SUN8I + defined CONFIG_MACH_SUN8I_A23 /* 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 c3ec20d..6143038 100644 --- a/arch/arm/cpu/armv7/sunxi/cpu_info.c +++ b/arch/arm/cpu/armv7/sunxi/cpu_info.c @@ -64,7 +64,7 @@ int print_cpuinfo(void) } #elif defined CONFIG_MACH_SUN7I puts("CPU: Allwinner A20 (SUN7I)\n"); -#elif defined CONFIG_MACH_SUN8I +#elif defined CONFIG_MACH_SUN8I_A23 puts("CPU: Allwinner A23 (SUN8I)\n"); #else #warning Please update cpu_info.c with correct CPU information diff --git a/arch/arm/cpu/armv7/sunxi/dram_sun8i.c b/arch/arm/cpu/armv7/sunxi/dram_sun8i_a23.c similarity index 100% rename from arch/arm/cpu/armv7/sunxi/dram_sun8i.c rename to arch/arm/cpu/armv7/sunxi/dram_sun8i_a23.c diff --git a/arch/arm/cpu/armv7/sunxi/rsb.c b/arch/arm/cpu/armv7/sunxi/rsb.c index f115a9c..d8d4957 100644 --- a/arch/arm/cpu/armv7/sunxi/rsb.c +++ b/arch/arm/cpu/armv7/sunxi/rsb.c @@ -20,7 +20,7 @@ static int rsb_set_device_mode(void);
static void rsb_cfg_io(void) { -#ifdef CONFIG_MACH_SUN8I +#if defined CONFIG_MACH_SUN8I_A23 sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN8I_GPL_R_RSB); sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN8I_GPL_R_RSB); sunxi_gpio_set_pull(SUNXI_GPL(0), 1); diff --git a/arch/arm/include/asm/arch-sunxi/clock.h b/arch/arm/include/asm/arch-sunxi/clock.h index 3e5d999..ad4fb26 100644 --- a/arch/arm/include/asm/arch-sunxi/clock.h +++ b/arch/arm/include/asm/arch-sunxi/clock.h @@ -15,7 +15,8 @@ #define CLK_GATE_CLOSE 0x0
/* clock control module regs definition */ -#if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN8I) +#if defined(CONFIG_MACH_SUN6I) || \ + defined(CONFIG_MACH_SUN8I_A23) #include <asm/arch/clock_sun6i.h> #elif defined(CONFIG_MACH_SUN9I) #include <asm/arch/clock_sun9i.h> diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h index 8a80385..d625970 100644 --- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h +++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h @@ -280,10 +280,10 @@ struct sunxi_ccm_reg { #define CCM_HDMI_CTRL_DDC_GATE (0x1 << 30) #define CCM_HDMI_CTRL_GATE (0x1 << 31)
-#ifndef CONFIG_MACH_SUN8I -#define MBUS_CLK_DEFAULT 0x81000001 /* PLL6 / 2 */ -#else +#if defined CONFIG_MACH_SUN8I_A23 #define MBUS_CLK_DEFAULT 0x81000003 /* PLL6 / 4 */ +#else +#define MBUS_CLK_DEFAULT 0x81000001 /* PLL6 / 2 */ #endif
#define CCM_PLL5_PATTERN 0xd1303333 diff --git a/arch/arm/include/asm/arch-sunxi/dram.h b/arch/arm/include/asm/arch-sunxi/dram.h index aedd194..bb96cc5 100644 --- a/arch/arm/include/asm/arch-sunxi/dram.h +++ b/arch/arm/include/asm/arch-sunxi/dram.h @@ -18,8 +18,8 @@ /* dram regs definition */ #if defined(CONFIG_MACH_SUN6I) #include <asm/arch/dram_sun6i.h> -#elif defined(CONFIG_MACH_SUN8I) -#include <asm/arch/dram_sun8i.h> +#elif defined(CONFIG_MACH_SUN8I_A23) +#include <asm/arch/dram_sun8i_a23.h> #else #include <asm/arch/dram_sun4i.h> #endif diff --git a/arch/arm/include/asm/arch-sunxi/dram_sun8i.h b/arch/arm/include/asm/arch-sunxi/dram_sun8i_a23.h similarity index 100% rename from arch/arm/include/asm/arch-sunxi/dram_sun8i.h rename to arch/arm/include/asm/arch-sunxi/dram_sun8i_a23.h diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index 34044f8..92922b8 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -34,7 +34,7 @@ config MACH_SUN7I select SUPPORT_SPL select ARMV7_BOOT_SEC_DEFAULT if OLD_SUNXI_KERNEL_COMPAT
-config MACH_SUN8I +config MACH_SUN8I_A23 bool "sun8i (Allwinner A23)" select ARCH_SUN6I select CPU_V7 @@ -44,7 +44,7 @@ endchoice
config DRAM_CLK int "sunxi dram clock speed" - default 312 if MACH_SUN6I || MACH_SUN8I + default 312 if MACH_SUN6I || MACH_SUN8I_A23 default 360 if MACH_SUN4I || MACH_SUN5I || MACH_SUN7I ---help--- Set the dram clock speed, valid range 240 - 480, must be a multiple @@ -61,7 +61,7 @@ endif
config DRAM_ZQ int "sunxi dram zq value" - default 123 if MACH_SUN4I || MACH_SUN5I || MACH_SUN6I || MACH_SUN8I + default 123 if MACH_SUN4I || MACH_SUN5I || MACH_SUN6I || MACH_SUN8I_A23 default 127 if MACH_SUN7I ---help--- Set the dram zq value. @@ -143,14 +143,15 @@ endif
config SYS_CLK_FREQ default 912000000 if MACH_SUN7I - default 1008000000 if MACH_SUN4I || MACH_SUN5I || MACH_SUN6I || MACH_SUN8I + default 1008000000 if MACH_SUN4I || MACH_SUN5I || MACH_SUN6I + default 1008000000 if MACH_SUN8I_A23
config SYS_CONFIG_NAME default "sun4i" if MACH_SUN4I default "sun5i" if MACH_SUN5I default "sun6i" if MACH_SUN6I default "sun7i" if MACH_SUN7I - default "sun8i" if MACH_SUN8I + default "sun8i" if MACH_SUN8I_A23
config SYS_BOARD default "sunxi" @@ -288,7 +289,7 @@ config VIDEO
config VIDEO_HDMI boolean "HDMI output support" - depends on VIDEO && !MACH_SUN8I + depends on VIDEO && !MACH_SUN8I_A23 default y ---help--- Say Y here to add support for outputting video over HDMI. @@ -302,7 +303,7 @@ config VIDEO_VGA
config VIDEO_VGA_VIA_LCD boolean "VGA via LCD controller support" - depends on VIDEO && (MACH_SUN5I || MACH_SUN6I || MACH_SUN8I) + depends on VIDEO && (MACH_SUN5I || MACH_SUN6I || MACH_SUN8I_A23) default n ---help--- Say Y here to add support for external DACs connected to the parallel diff --git a/board/sunxi/board.c b/board/sunxi/board.c index 7633d65..83ef0e5 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -116,7 +116,7 @@ static void mmc_pinmux_setup(int sdc) sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); sunxi_gpio_set_drv(pin, 2); } -#elif defined(CONFIG_MACH_SUN8I) +#elif defined(CONFIG_MACH_SUN8I_A23) if (pins == SUNXI_GPIO_D) { /* SDC1: PD2-PD7 */ for (pin = SUNXI_GPD(2); pin <= SUNXI_GPD(7); pin++) { @@ -181,7 +181,7 @@ static void mmc_pinmux_setup(int sdc) sunxi_gpio_set_pull(SUNXI_GPC(24), SUNXI_GPIO_PULL_UP); sunxi_gpio_set_drv(SUNXI_GPC(24), 2); } -#elif defined(CONFIG_MACH_SUN8I) +#elif defined(CONFIG_MACH_SUN8I_A23) /* SDC2: PC5-PC6, PC8-PC16 */ for (pin = SUNXI_GPC(5); pin <= SUNXI_GPC(6); pin++) { sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2); diff --git a/configs/Ippo_q8h_v1_2_defconfig b/configs/Ippo_q8h_v1_2_defconfig index e003b4c..d9455c8 100644 --- a/configs/Ippo_q8h_v1_2_defconfig +++ b/configs/Ippo_q8h_v1_2_defconfig @@ -11,7 +11,7 @@ CONFIG_VIDEO_LCD_BL_EN="PH6" CONFIG_VIDEO_LCD_BL_PWM="PH0" CONFIG_ARM=y CONFIG_ARCH_SUNXI=y -CONFIG_MACH_SUN8I=y +CONFIG_MACH_SUN8I_A23=y CONFIG_DRAM_CLK=432 # zq = 0xf74a CONFIG_DRAM_ZQ=63306 diff --git a/configs/Ippo_q8h_v5_defconfig b/configs/Ippo_q8h_v5_defconfig index 87d898e..4cc9a5e 100644 --- a/configs/Ippo_q8h_v5_defconfig +++ b/configs/Ippo_q8h_v5_defconfig @@ -11,7 +11,7 @@ CONFIG_VIDEO_LCD_BL_EN="PH6" CONFIG_VIDEO_LCD_BL_PWM="PH0" CONFIG_ARM=y CONFIG_ARCH_SUNXI=y -CONFIG_MACH_SUN8I=y +CONFIG_MACH_SUN8I_A23=y CONFIG_DRAM_CLK=480 # zq = 0xf777 CONFIG_DRAM_ZQ=63351 diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index f8f0239..39051e4 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -1,6 +1,6 @@ config AXP221_POWER boolean "axp221 / axp223 pmic support" - depends on MACH_SUN6I || MACH_SUN8I + depends on MACH_SUN6I || MACH_SUN8I_A23 default y ---help--- Say y here to enable support for the axp221 / axp223 pmic found on most @@ -47,7 +47,7 @@ config AXP221_ALDO2_VOLT int "axp221 aldo2 voltage" depends on AXP221_POWER default 0 if MACH_SUN6I - default 2500 if MACH_SUN8I + default 2500 if MACH_SUN8I_A23 ---help--- Set the voltage (mV) to program the axp221 aldo2 at, set to 0 to disable aldo2. On sun6i (A31) boards this is typically unused and diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index 1f7a1cb..ba4d66c 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -237,7 +237,7 @@ extern int soft_i2c_gpio_scl; #endif #elif CONFIG_CONS_INDEX == 2 && defined(CONFIG_MACH_SUN5I) #define OF_STDOUT_PATH "/soc@01c00000/serial@01c28400:115200" -#elif CONFIG_CONS_INDEX == 5 && defined(CONFIG_MACH_SUN8I) +#elif CONFIG_CONS_INDEX == 5 && defined(CONFIG_MACH_SUN8I_A23) #define OF_STDOUT_PATH "/soc@01c00000/serial@01f02800:115200" #else #error Unsupported console port nr. Please fix stdout-path in sunxi-common.h.

On Tue, 2015-04-14 at 18:06 +0200, Hans de Goede wrote:
This is a preparation patch for adding A33 support, which will have a mach name of sun8i-a33.
And, presumably, differs substantially from sun8i-a23, to the extent it should likely have been a new sunNi but we are stuck with what AW did, sigh, oh well.
Signed-off-by: Hans de Goede hdegoede@redhat.com
Acked-by: Ian Campbell ian.campbell@citrix.com

Hi,
On 15-04-15 21:49, Ian Campbell wrote:
On Tue, 2015-04-14 at 18:06 +0200, Hans de Goede wrote:
This is a preparation patch for adding A33 support, which will have a mach name of sun8i-a33.
And, presumably, differs substantially from sun8i-a23, to the extent it should likely have been a new sunNi but we are stuck with what AW did, sigh, oh well.
Actually other then having a different DRAM controller / MBUS setup, the differences are very minor (what I know sofar is a few slightly different bits in the otg controller/phy, and the SID is back inside the SoC).
Signed-off-by: Hans de Goede hdegoede@redhat.com
Acked-by: Ian Campbell ian.campbell@citrix.com
Regards,
Hans

Add support for the new second DRAM PLL found on the A33 SoC.
Signed-off-by: Hans de Goede hdegoede@redhat.com --- arch/arm/cpu/armv7/sunxi/clock_sun6i.c | 18 +++++++++++++++ arch/arm/include/asm/arch-sunxi/clock.h | 3 ++- arch/arm/include/asm/arch-sunxi/clock_sun6i.h | 33 +++++++++++++++++++++++---- 3 files changed, 49 insertions(+), 5 deletions(-)
diff --git a/arch/arm/cpu/armv7/sunxi/clock_sun6i.c b/arch/arm/cpu/armv7/sunxi/clock_sun6i.c index e2a7867..3bfa122 100644 --- a/arch/arm/cpu/armv7/sunxi/clock_sun6i.c +++ b/arch/arm/cpu/armv7/sunxi/clock_sun6i.c @@ -170,6 +170,24 @@ void clock_set_pll5(unsigned int clk, bool sigma_delta_enable) udelay(5500); }
+#ifdef CONFIG_MACH_SUN8I_A33 +void clock_set_pll11(unsigned int clk, bool sigma_delta_enable) +{ + struct sunxi_ccm_reg * const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + + if (sigma_delta_enable) + writel(CCM_PLL11_PATTERN, &ccm->pll5_pattern_cfg); + + writel(CCM_PLL11_CTRL_EN | CCM_PLL11_CTRL_UPD | + (sigma_delta_enable ? CCM_PLL11_CTRL_SIGMA_DELTA_EN : 0) | + CCM_PLL11_CTRL_N(clk / 24000000), &ccm->pll11_cfg); + + while (readl(&ccm->pll11_cfg) & CCM_PLL11_CTRL_UPD) + ; +} +#endif + 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 ad4fb26..8d1eebe 100644 --- a/arch/arm/include/asm/arch-sunxi/clock.h +++ b/arch/arm/include/asm/arch-sunxi/clock.h @@ -16,7 +16,8 @@
/* clock control module regs definition */ #if defined(CONFIG_MACH_SUN6I) || \ - defined(CONFIG_MACH_SUN8I_A23) + defined(CONFIG_MACH_SUN8I_A23) || \ + defined(CONFIG_MACH_SUN8I_A33) #include <asm/arch/clock_sun6i.h> #elif defined(CONFIG_MACH_SUN9I) #include <asm/arch/clock_sun9i.h> diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h index d625970..c88b140 100644 --- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h +++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h @@ -31,7 +31,7 @@ struct sunxi_ccm_reg { u32 mipi_pll_cfg; /* 0x40 MIPI pll control */ u32 pll9_cfg; /* 0x44 pll9 control */ u32 pll10_cfg; /* 0x48 pll10 control */ - u32 reserved8; + u32 pll11_cfg; /* 0x4c pll11 (ddr1) control (A33 only) */ 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 */ @@ -63,7 +63,8 @@ struct sunxi_ccm_reg { 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_pll_cfg; /* 0xf8 PLL_DDR cfg register, A33 only */ + u32 mbus_reset; /* 0xfc MBUS reset control, A33 only */ u32 dram_clk_gate; /* 0x100 DRAM module gating */ u32 be0_clk_cfg; /* 0x104 BE0 module clock */ u32 be1_clk_cfg; /* 0x108 BE1 module clock */ @@ -126,7 +127,9 @@ struct sunxi_ccm_reg { 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 pll11_pattern_cfg0; /* 0x2ac PLL11 Pattern config0, A33 only */ + u32 pll11_pattern_cfg1; /* 0x2b0 PLL11 Pattern config0, A33 only */ + u32 reserved22[3]; 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 */ @@ -195,6 +198,11 @@ struct sunxi_ccm_reg { #define CCM_PLL6_CTRL_K_SHIFT 4 #define CCM_PLL6_CTRL_K_MASK (0x3 << CCM_PLL6_CTRL_K_SHIFT)
+#define CCM_PLL11_CTRL_N(n) ((((n) - 1) & 0x3f) << 8) +#define CCM_PLL11_CTRL_SIGMA_DELTA_EN (0x1 << 24) +#define CCM_PLL11_CTRL_UPD (0x1 << 30) +#define CCM_PLL11_CTRL_EN (0x1 << 31) + #define AHB1_ABP1_DIV_DEFAULT 0x00002020
#define AXI_GATE_OFFSET_DRAM 0 @@ -216,6 +224,7 @@ struct sunxi_ccm_reg {
/* ahb_gate1 offsets */ #define AHB_GATE_OFFSET_DRC0 25 +#define AHB_GATE_OFFSET_DE_FE0 14 #define AHB_GATE_OFFSET_DE_BE0 12 #define AHB_GATE_OFFSET_HDMI 11 #define AHB_GATE_OFFSET_LCD1 5 @@ -248,12 +257,23 @@ struct sunxi_ccm_reg {
#define MDFS_CLK_DEFAULT 0x81000002 /* PLL6 / 3 */
+#define CCM_DRAMCLK_CFG_DIV(x) ((x - 1) << 0) +#define CCM_DRAMCLK_CFG_DIV_MASK (0xf << 0) #define CCM_DRAMCLK_CFG_DIV0(x) ((x - 1) << 8) #define CCM_DRAMCLK_CFG_DIV0_MASK (0xf << 8) #define CCM_DRAMCLK_CFG_UPD (0x1 << 16) #define CCM_DRAMCLK_CFG_RST (0x1 << 31)
+#define CCM_DRAMPLL_CFG_SRC_PLL5 (0x0 << 16) /* Select PLL5 (DDR0) */ +#define CCM_DRAMPLL_CFG_SRC_PLL11 (0x1 << 16) /* Select PLL11 (DDR1) */ +#define CCM_DRAMPLL_CFG_SRC_MASK (0x1 << 16) + +#define CCM_MBUS_RESET_RESET (0x1 << 31) + +#define CCM_DRAM_GATE_OFFSET_DE_FE0 24 +#define CCM_DRAM_GATE_OFFSET_DE_FE1 25 #define CCM_DRAM_GATE_OFFSET_DE_BE0 26 +#define CCM_DRAM_GATE_OFFSET_DE_BE1 27
#define CCM_LCD_CH0_CTRL_PLL3 (0 << 24) #define CCM_LCD_CH0_CTRL_PLL7 (1 << 24) @@ -280,13 +300,15 @@ struct sunxi_ccm_reg { #define CCM_HDMI_CTRL_DDC_GATE (0x1 << 30) #define CCM_HDMI_CTRL_GATE (0x1 << 31)
-#if defined CONFIG_MACH_SUN8I_A23 +#if defined CONFIG_MACH_SUN8I_A23 || defined CONFIG_MACH_SUN8I_A33 #define MBUS_CLK_DEFAULT 0x81000003 /* PLL6 / 4 */ #else #define MBUS_CLK_DEFAULT 0x81000001 /* PLL6 / 2 */ #endif +#define MBUS_CLK_GATE (0x1 << 31)
#define CCM_PLL5_PATTERN 0xd1303333 +#define CCM_PLL11_PATTERN 0xf5860000
/* ahb_reset0 offsets */ #define AHB_RESET_OFFSET_GMAC 17 @@ -299,7 +321,9 @@ struct sunxi_ccm_reg { #define AHB_RESET_OFFSET_SS 5
/* ahb_reset1 offsets */ +#define AHB_RESET_OFFSET_SAT 26 #define AHB_RESET_OFFSET_DRC0 25 +#define AHB_RESET_OFFSET_DE_FE0 14 #define AHB_RESET_OFFSET_DE_BE0 12 #define AHB_RESET_OFFSET_HDMI 11 #define AHB_RESET_OFFSET_LCD1 5 @@ -326,6 +350,7 @@ struct sunxi_ccm_reg { void clock_set_pll1(unsigned int hz); void clock_set_pll3(unsigned int hz); void clock_set_pll5(unsigned int clk, bool sigma_delta_enable); +void clock_set_pll11(unsigned int clk, bool sigma_delta_enable); unsigned int clock_get_pll6(void); #endif

On Tue, 2015-04-14 at 18:06 +0200, Hans de Goede wrote:
Add support for the new second DRAM PLL found on the A33 SoC.
Signed-off-by: Hans de Goede hdegoede@redhat.com
Acked-by: Ian Campbell ijc@hellion.org.uk

From: Vishnu Patekar vishnupatekar0510@gmail.com
Based on Allwinner dram init code from the a33 bsp: https://github.com/allwinner-zh/bootloader/blob/master/basic_loader/bsp/bsp_...
Initial u-boot port by Vishnu Patekar, major cleanup / rewrite by Hans de Goede.
Signed-off-by: Vishnu Patekar vishnupatekar0510@gmail.com Signed-off-by: Hans de Goede hdegoede@redhat.com --- arch/arm/cpu/armv7/sunxi/dram_sun8i_a33.c | 363 +++++++++++++++++++++++ arch/arm/include/asm/arch-sunxi/dram.h | 2 + arch/arm/include/asm/arch-sunxi/dram_sun8i_a33.h | 179 +++++++++++ 3 files changed, 544 insertions(+) create mode 100644 arch/arm/cpu/armv7/sunxi/dram_sun8i_a33.c create mode 100644 arch/arm/include/asm/arch-sunxi/dram_sun8i_a33.h
diff --git a/arch/arm/cpu/armv7/sunxi/dram_sun8i_a33.c b/arch/arm/cpu/armv7/sunxi/dram_sun8i_a33.c new file mode 100644 index 0000000..987fc5d --- /dev/null +++ b/arch/arm/cpu/armv7/sunxi/dram_sun8i_a33.c @@ -0,0 +1,363 @@ +/* + * Sun8i a33 platform dram controller init. + * + * (C) Copyright 2007-2015 Allwinner Technology Co. + * Jerry Wang wangflord@allwinnertech.com + * (C) Copyright 2015 Vishnu Patekar vishnupatekar0510@gmail.com + * (C) Copyright 2015 Hans de Goede hdegoede@redhat.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <common.h> +#include <errno.h> +#include <asm/io.h> +#include <asm/arch/clock.h> +#include <asm/arch/dram.h> +#include <asm/arch/prcm.h> + +/* PLL runs at 2x dram-clk, controller runs at PLL / 4 (dram-clk / 2) */ +#define DRAM_CLK_MUL 2 +#define DRAM_CLK_DIV 4 +#define DRAM_SIGMA_DELTA_ENABLE 1 +#define DRAM_ODT_EN 0 + +struct dram_para { + u8 cs1; + u8 seq; + u8 bank; + u8 rank; + u8 rows; + u8 bus_width; + u16 page_size; +}; + +static void mctl_set_cr(struct dram_para *para) +{ + struct sunxi_mctl_com_reg * const mctl_com = + (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 | + (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) | + MCTL_CR_BANK(para->bank) | MCTL_CR_RANK(para->rank), + &mctl_com->cr); +} + +static void auto_detect_dram_size(struct dram_para *para) +{ + u8 orig_rank = para->rank; + int rows, columns; + + /* Row detect */ + para->page_size = 512; + para->seq = 1; + para->rows = 16; + para->rank = 1; + mctl_set_cr(para); + for (rows = 11 ; rows < 16 ; rows++) { + if (mctl_mem_matches(1 << (rows + 9))) /* row-column */ + break; + } + + /* Column (page size) detect */ + para->rows = 11; + para->page_size = 8192; + mctl_set_cr(para); + for (columns = 9 ; columns < 13 ; columns++) { + if (mctl_mem_matches(1 << columns)) + break; + } + + para->seq = 0; + para->rank = orig_rank; + para->rows = rows; + para->page_size = 1 << columns; + mctl_set_cr(para); +} + +static inline int ns_to_t(int nanoseconds) +{ + const unsigned int ctrl_freq = + CONFIG_DRAM_CLK * DRAM_CLK_MUL / DRAM_CLK_DIV; + + return (ctrl_freq * nanoseconds + 999) / 1000; +} + +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; + u8 tfaw = ns_to_t(50); + u8 trrd = max(ns_to_t(10), 4); + u8 trcd = ns_to_t(15); + u8 trc = ns_to_t(53); + u8 txp = max(ns_to_t(8), 3); + u8 twtr = max(ns_to_t(8), 4); + u8 trtp = max(ns_to_t(8), 4); + u8 twr = max(ns_to_t(15), 3); + u8 trp = ns_to_t(15); + u8 tras = ns_to_t(38); + + u16 trefi = ns_to_t(7800) / 32; + u16 trfc = ns_to_t(350); + + /* Fixed timing parameters */ + u8 tmrw = 0; + u8 tmrd = 4; + u8 tmod = 12; + u8 tcke = 3; + u8 tcksrx = 5; + u8 tcksre = 5; + u8 tckesr = 4; + u8 trasmax = 24; + u8 tcl = 6; /* CL 12 */ + u8 tcwl = 4; /* CWL 8 */ + u8 t_rdata_en = 4; + u8 wr_latency = 2; + + u32 tdinit0 = (500 * CONFIG_DRAM_CLK) + 1; /* 500us */ + u32 tdinit1 = (360 * CONFIG_DRAM_CLK) / 1000 + 1; /* 360ns */ + u32 tdinit2 = (200 * CONFIG_DRAM_CLK) + 1; /* 200us */ + u32 tdinit3 = (1 * CONFIG_DRAM_CLK) + 1; /* 1us */ + + u8 twtp = tcwl + 2 + twr; /* WL + BL / 2 + tWR */ + u8 twr2rd = tcwl + 2 + twtr; /* WL + BL / 2 + tWTR */ + u8 trd2wr = tcl + 2 + 1 - tcwl; /* RL + BL / 2 + 2 - WL */ + + /* 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); + /* Set dram timing */ + reg_val = (twtp << 24) | (tfaw << 16) | (trasmax << 8) | (tras << 0); + writel(reg_val, &mctl_ctl->dramtmg0); + reg_val = (txp << 16) | (trtp << 8) | (trc << 0); + writel(reg_val, &mctl_ctl->dramtmg1); + reg_val = (tcwl << 24) | (tcl << 16) | (trd2wr << 8) | (twr2rd << 0); + writel(reg_val, &mctl_ctl->dramtmg2); + reg_val = (tmrw << 16) | (tmrd << 12) | (tmod << 0); + writel(reg_val, &mctl_ctl->dramtmg3); + reg_val = (trcd << 24) | (tccd << 16) | (trrd << 8) | (trp << 0); + writel(reg_val, &mctl_ctl->dramtmg4); + reg_val = (tcksrx << 24) | (tcksre << 16) | (tckesr << 8) | (tcke << 0); + writel(reg_val, &mctl_ctl->dramtmg5); + /* Set two rank timing and exit self-refresh timing */ + reg_val = readl(&mctl_ctl->dramtmg8); + reg_val &= ~(0xff << 8); + reg_val &= ~(0xff << 0); + reg_val |= (0x33 << 8); + reg_val |= (0x8 << 0); + writel(reg_val, &mctl_ctl->dramtmg8); + /* Set phy interface time */ + reg_val = (0x2 << 24) | (t_rdata_en << 16) | (0x1 << 8) + | (wr_latency << 0); + /* PHY interface write latency and read latency configure */ + writel(reg_val, &mctl_ctl->pitmg0); + /* Set phy time PTR0-2 use default */ + writel(((tdinit0 << 0) | (tdinit1 << 20)), &mctl_ctl->ptr3); + writel(((tdinit2 << 0) | (tdinit3 << 20)), &mctl_ctl->ptr4); + /* Set refresh timing */ + reg_val = (trefi << 16) | (trfc << 0); + writel(reg_val, &mctl_ctl->rfshtmg); +} + +static void mctl_set_pir(u32 val) +{ + struct sunxi_mctl_ctl_reg * const mctl_ctl = + (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE; + + writel(val, &mctl_ctl->pir); + mctl_await_completion(&mctl_ctl->pgsr0, 0x1, 0x1); +} + +static void mctl_data_train_cfg(struct dram_para *para) +{ + struct sunxi_mctl_ctl_reg * const mctl_ctl = + (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE; + + if (para->rank == 2) + clrsetbits_le32(&mctl_ctl->dtcr, 0x3 << 24, 0x3 << 24); + else + clrsetbits_le32(&mctl_ctl->dtcr, 0x3 << 24, 0x1 << 24); +} + +static int mctl_train_dram(struct dram_para *para) +{ + struct sunxi_mctl_ctl_reg * const mctl_ctl = + (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE; + + mctl_data_train_cfg(para); + mctl_set_pir(0x1f3); + + return ((readl(&mctl_ctl->pgsr0) >> 20) & 0xff) ? -EIO : 0; +} + +static int mctl_channel_init(struct dram_para *para) +{ + struct sunxi_mctl_ctl_reg * const mctl_ctl = + (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE; + struct sunxi_mctl_com_reg * const mctl_com = + (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE; + u32 low_data_lines_status; /* Training status of datalines 0 - 7 */ + u32 high_data_lines_status; /* Training status of datalines 8 - 15 */ + + auto_set_timing_para(para); + + /* Disable dram VTC */ + clrbits_le32(&mctl_ctl->pgcr0, 0x3f << 0); + + /* Set ODT */ + if ((CONFIG_DRAM_CLK > 400) && DRAM_ODT_EN) { + setbits_le32(DXnGCR0(0), 0x3 << 9); + setbits_le32(DXnGCR0(1), 0x3 << 9); + } else { + clrbits_le32(DXnGCR0(0), 0x3 << 9); + clrbits_le32(DXnGCR0(1), 0x3 << 9); + } + + /* set PLL configuration */ + if (CONFIG_DRAM_CLK >= 480) + setbits_le32(&mctl_ctl->pllgcr, 0x1 << 18); + else + setbits_le32(&mctl_ctl->pllgcr, 0x3 << 18); + + /* Auto detect dram config, set 2 rank and 16bit bus-width */ + para->cs1 = 0; + para->rank = 2; + para->bus_width = 16; + mctl_set_cr(para); + + /* Open DQS gating */ + clrbits_le32(&mctl_ctl->pgcr2, (0x3 << 6)); + clrbits_le32(&mctl_ctl->dqsgmr, (0x1 << 8) | (0x7)); + + mctl_data_train_cfg(para); + + /* ZQ calibration */ + writel(CONFIG_DRAM_ZQ & 0xff, &mctl_ctl->zqcr1); + /* CA calibration */ + mctl_set_pir(0x00000003); + /* More ZQ calibration */ + writel(readl(&mctl_ctl->zqsr0) | 0x10000000, &mctl_ctl->zqcr2); + writel((CONFIG_DRAM_ZQ >> 8) & 0xff, &mctl_ctl->zqcr1); + + /* DQS gate training */ + if (mctl_train_dram(para) != 0) { + low_data_lines_status = (readl(DXnGSR0(0)) >> 24) & 0x03; + high_data_lines_status = (readl(DXnGSR0(1)) >> 24) & 0x03; + + if (low_data_lines_status == 0x3) + return -EIO; + + /* DRAM has only one rank */ + para->rank = 1; + mctl_set_cr(para); + + if (low_data_lines_status == high_data_lines_status) + goto done; /* 16 bit bus, 1 rank */ + + if (!(low_data_lines_status & high_data_lines_status)) { + /* Retry 16 bit bus-width with CS1 set */ + para->cs1 = 1; + mctl_set_cr(para); + if (mctl_train_dram(para) == 0) + goto done; + } + + /* Try 8 bit bus-width */ + writel(0x0, DXnGCR0(1)); /* Disable high DQ */ + para->cs1 = 0; + para->bus_width = 8; + mctl_set_cr(para); + if (mctl_train_dram(para) != 0) + return -EIO; + } +done: + /* Check the dramc status */ + mctl_await_completion(&mctl_ctl->statr, 0x1, 0x1); + + /* Close DQS gating */ + setbits_le32(&mctl_ctl->pgcr2, 0x3 << 6); + + /* Enable master access */ + writel(0xffffffff, &mctl_com->maer); + + return 0; +} + +static void mctl_sys_init(struct dram_para *para) +{ + struct sunxi_ccm_reg * const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + struct sunxi_mctl_ctl_reg * const mctl_ctl = + (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE; + struct sunxi_mctl_com_reg * const mctl_com = + (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE; + + clrsetbits_le32(&ccm->dram_pll_cfg, CCM_DRAMPLL_CFG_SRC_MASK, + CCM_DRAMPLL_CFG_SRC_PLL11); + + clock_set_pll11(CONFIG_DRAM_CLK * 1000000 * DRAM_CLK_MUL, + DRAM_SIGMA_DELTA_ENABLE); + + clrsetbits_le32(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_DIV_MASK, + CCM_DRAMCLK_CFG_DIV(DRAM_CLK_DIV) | + 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 << AHB_RESET_OFFSET_MCTL); + setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MCTL); + setbits_le32(&ccm->mbus_reset, CCM_MBUS_RESET_RESET); + setbits_le32(&ccm->mbus0_clk_cfg, MBUS_CLK_GATE); + + /* Set dram master access priority */ + writel(0x0, &mctl_com->mapr); + writel(0x0f802f01, &mctl_ctl->sched); + writel(0x0000400f, &mctl_ctl->clken); /* normal */ + + udelay(10); +} + +unsigned long sunxi_dram_init(void) +{ + struct sunxi_mctl_com_reg * const mctl_com = + (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE; + struct sunxi_mctl_ctl_reg * const mctl_ctl = + (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE; + + struct dram_para para = { + .cs1 = 0, + .bank = 1, + .rank = 1, + .rows = 15, + .bus_width = 16, + .page_size = 2048, + }; + + mctl_sys_init(¶); + + if (mctl_channel_init(¶) != 0) + return 0; + + auto_detect_dram_size(¶); + + /* Enable master software clk */ + writel(readl(&mctl_com->swonr) | 0x3ffff, &mctl_com->swonr); + + /* Set DRAM ODT MAP */ + if (para.rank == 2) + writel(0x00000303, &mctl_ctl->odtmap); + else + writel(0x00000201, &mctl_ctl->odtmap); + + return para.page_size * (para.bus_width / 8) * + (1 << (para.bank + para.rank + para.rows)); +} diff --git a/arch/arm/include/asm/arch-sunxi/dram.h b/arch/arm/include/asm/arch-sunxi/dram.h index bb96cc5..273f80f 100644 --- a/arch/arm/include/asm/arch-sunxi/dram.h +++ b/arch/arm/include/asm/arch-sunxi/dram.h @@ -20,6 +20,8 @@ #include <asm/arch/dram_sun6i.h> #elif defined(CONFIG_MACH_SUN8I_A23) #include <asm/arch/dram_sun8i_a23.h> +#elif defined(CONFIG_MACH_SUN8I_A33) +#include <asm/arch/dram_sun8i_a33.h> #else #include <asm/arch/dram_sun4i.h> #endif diff --git a/arch/arm/include/asm/arch-sunxi/dram_sun8i_a33.h b/arch/arm/include/asm/arch-sunxi/dram_sun8i_a33.h new file mode 100644 index 0000000..afe6dc8 --- /dev/null +++ b/arch/arm/include/asm/arch-sunxi/dram_sun8i_a33.h @@ -0,0 +1,179 @@ +/* + * Sun8i platform dram controller register and constant defines + * + * (C) Copyright 2007-2015 Allwinner Technology Co. + * Jerry Wang wangflord@allwinnertech.com + * (C) Copyright 2015 Vishnu Patekar vishnupatekar0510@gmail.com + * (C) Copyright 2014-2015 Hans de Goede hdegoede@redhat.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _SUNXI_DRAM_SUN8I_A33_H +#define _SUNXI_DRAM_SUN8I_A33_H + +struct sunxi_mctl_com_reg { + u32 cr; /* 0x00 */ + u32 ccr; /* 0x04 controller configuration register */ + u32 dbgcr; /* 0x08 */ + u8 res0[0x4]; /* 0x0c */ + u32 mcr0_0; /* 0x10 */ + u32 mcr1_0; /* 0x14 */ + u32 mcr0_1; /* 0x18 */ + u32 mcr1_1; /* 0x1c */ + u32 mcr0_2; /* 0x20 */ + u32 mcr1_2; /* 0x24 */ + u32 mcr0_3; /* 0x28 */ + u32 mcr1_3; /* 0x2c */ + u32 mcr0_4; /* 0x30 */ + u32 mcr1_4; /* 0x34 */ + u32 mcr0_5; /* 0x38 */ + u32 mcr1_5; /* 0x3c */ + u32 mcr0_6; /* 0x40 */ + u32 mcr1_6; /* 0x44 */ + u32 mcr0_7; /* 0x48 */ + u32 mcr1_7; /* 0x4c */ + u32 mcr0_8; /* 0x50 */ + u32 mcr1_8; /* 0x54 */ + u32 mcr0_9; /* 0x58 */ + u32 mcr1_9; /* 0x5c */ + u32 mcr0_10; /* 0x60 */ + u32 mcr1_10; /* 0x64 */ + u32 mcr0_11; /* 0x68 */ + u32 mcr1_11; /* 0x6c */ + u32 mcr0_12; /* 0x70 */ + u32 mcr1_12; /* 0x74 */ + u32 mcr0_13; /* 0x78 */ + u32 mcr1_13; /* 0x7c */ + u32 mcr0_14; /* 0x80 */ + u32 mcr1_14; /* 0x84 */ + u32 mcr0_15; /* 0x88 */ + u32 mcr1_15; /* 0x8c */ + u32 bwcr; /* 0x90 */ + u32 maer; /* 0x94 */ + u32 mapr; /* 0x98 */ + u32 mcgcr; /* 0x9c */ + u32 bwctr; /* 0xa0 */ + u8 res2[0x8]; /* 0xa4 */ + u32 swoffr; /* 0xac */ + u8 res3[0x10]; /* 0xb0 */ + u32 swonr; /* 0xc0 */ + u8 res4[0x3c]; /* 0xc4 */ + u32 mdfscr; /* 0x100 */ + u32 mdfsmer; /* 0x104 */ +}; + +struct sunxi_mctl_ctl_reg { + u32 pir; /* 0x00 */ + u32 pwrctl; /* 0x04 */ + u32 mrctrl0; /* 0x08 */ + u32 clken; /* 0x0c */ + u32 pgsr0; /* 0x10 */ + u32 pgsr1; /* 0x14 */ + u32 statr; /* 0x18 */ + u8 res1[0x14]; /* 0x1c */ + u32 mr0; /* 0x30 */ + u32 mr1; /* 0x34 */ + u32 mr2; /* 0x38 */ + u32 mr3; /* 0x3c */ + u32 pllgcr; /* 0x40 */ + u32 ptr0; /* 0x44 */ + u32 ptr1; /* 0x48 */ + u32 ptr2; /* 0x4c */ + u32 ptr3; /* 0x50 */ + u32 ptr4; /* 0x54 */ + u32 dramtmg0; /* 0x58 dram timing parameters register 0 */ + u32 dramtmg1; /* 0x5c dram timing parameters register 1 */ + u32 dramtmg2; /* 0x60 dram timing parameters register 2 */ + u32 dramtmg3; /* 0x64 dram timing parameters register 3 */ + u32 dramtmg4; /* 0x68 dram timing parameters register 4 */ + u32 dramtmg5; /* 0x6c dram timing parameters register 5 */ + u32 dramtmg6; /* 0x70 dram timing parameters register 6 */ + u32 dramtmg7; /* 0x74 dram timing parameters register 7 */ + u32 dramtmg8; /* 0x78 dram timing parameters register 8 */ + u32 odtcfg; /* 0x7c */ + u32 pitmg0; /* 0x80 */ + u32 pitmg1; /* 0x84 */ + u8 res2[0x4]; /* 0x88 */ + u32 rfshctl0; /* 0x8c */ + u32 rfshtmg; /* 0x90 */ + u32 rfshctl1; /* 0x94 */ + u32 pwrtmg; /* 0x98 */ + u8 res3[0x20]; /* 0x9c */ + u32 dqsgmr; /* 0xbc */ + u32 dtcr; /* 0xc0 */ + u32 dtar0; /* 0xc4 */ + u32 dtar1; /* 0xc8 */ + u32 dtar2; /* 0xcc */ + u32 dtar3; /* 0xd0 */ + u32 dtdr0; /* 0xd4 */ + u32 dtdr1; /* 0xd8 */ + u32 dtmr0; /* 0xdc */ + u32 dtmr1; /* 0xe0 */ + u32 dtbmr; /* 0xe4 */ + u32 catr0; /* 0xe8 */ + u32 catr1; /* 0xec */ + u32 dtedr0; /* 0xf0 */ + u32 dtedr1; /* 0xf4 */ + u8 res4[0x8]; /* 0xf8 */ + u32 pgcr0; /* 0x100 */ + u32 pgcr1; /* 0x104 */ + u32 pgcr2; /* 0x108 */ + u8 res5[0x4]; /* 0x10c */ + u32 iovcr0; /* 0x110 */ + u32 iovcr1; /* 0x114 */ + u32 dqsdr; /* 0x118 */ + u32 dxccr; /* 0x11c */ + u32 odtmap; /* 0x120 */ + u32 zqctl0; /* 0x124 */ + u32 zqctl1; /* 0x128 */ + u8 res6[0x14]; /* 0x12c */ + u32 zqcr0; /* 0x140 zq control register 0 */ + u32 zqcr1; /* 0x144 zq control register 1 */ + u32 zqcr2; /* 0x148 zq control register 2 */ + u32 zqsr0; /* 0x14c zq status register 0 */ + u32 zqsr1; /* 0x150 zq status register 1 */ + u8 res7[0x6c]; /* 0x154 */ + u32 sched; /* 0x1c0 */ + u32 perfhpr0; /* 0x1c4 */ + u32 perfhpr1; /* 0x1c8 */ + u32 perflpr0; /* 0x1cc */ + u32 perflpr1; /* 0x1d0 */ + u32 perfwr0; /* 0x1d4 */ + u32 perfwr1; /* 0x1d8 */ +}; + +#define DXnGTR(x) (SUNXI_DRAM_CTL0_BASE + 0x00000340 + 0x80 * x) +#define DXnGCR0(x) (SUNXI_DRAM_CTL0_BASE + 0x00000344 + 0x80 * x) +#define DXnGSR0(x) (SUNXI_DRAM_CTL0_BASE + 0x00000348 + 0x80 * x) +#define DXnGSR1(x) (SUNXI_DRAM_CTL0_BASE + 0x0000034c + 0x80 * x) +#define DXnGSR2(x) (SUNXI_DRAM_CTL0_BASE + 0x00000350 + 0x80 * x) + +/* + * DRAM common (sunxi_mctl_com_reg) register constants. + */ +#define MCTL_CR_RANK_MASK (3 << 0) +#define MCTL_CR_RANK(x) (((x) - 1) << 0) +#define MCTL_CR_BANK_MASK (3 << 2) +#define MCTL_CR_BANK(x) ((x) << 2) +#define MCTL_CR_ROW_MASK (0xf << 4) +#define MCTL_CR_ROW(x) (((x) - 1) << 4) +#define MCTL_CR_PAGE_SIZE_MASK (0xf << 8) +#define MCTL_CR_PAGE_SIZE(x) ((fls(x) - 4) << 8) +#define MCTL_CR_BUSW_MASK (7 << 12) +#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_CHANNEL_MASK (1 << 19) +#define MCTL_CR_CHANNEL(x) (((x) - 1) << 19) +#define MCTL_CR_UNKNOWN (0x4 << 20) +#define MCTL_CR_CS1_CONTROL(x) ((x) << 24) + +/* DRAM control (sunxi_mctl_ctl_reg) register constants */ +#define MCTL_MR0 0x1c70 /* CL=11, WR=12 */ +#define MCTL_MR1 0x40 +#define MCTL_MR2 0x18 /* CWL=8 */ +#define MCTL_MR3 0x0 + +#endif /* _SUNXI_DRAM_SUN8I_A33_H */

On Tue, 2015-04-14 at 18:06 +0200, Hans de Goede wrote:
From: Vishnu Patekar vishnupatekar0510@gmail.com
Based on Allwinner dram init code from the a33 bsp: https://github.com/allwinner-zh/bootloader/blob/master/basic_loader/bsp/bsp_...
Initial u-boot port by Vishnu Patekar, major cleanup / rewrite by Hans de Goede.
Signed-off-by: Vishnu Patekar vishnupatekar0510@gmail.com Signed-off-by: Hans de Goede hdegoede@redhat.com
- /* Set dram timing */
- reg_val = (twtp << 24) | (tfaw << 16) | (trasmax << 8) | (tras << 0);
- writel(reg_val, &mctl_ctl->dramtmg0);
- reg_val = (txp << 16) | (trtp << 8) | (trc << 0);
- writel(reg_val, &mctl_ctl->dramtmg1);
- reg_val = (tcwl << 24) | (tcl << 16) | (trd2wr << 8) | (twr2rd << 0);
- writel(reg_val, &mctl_ctl->dramtmg2);
- reg_val = (tmrw << 16) | (tmrd << 12) | (tmod << 0);
- writel(reg_val, &mctl_ctl->dramtmg3);
- reg_val = (trcd << 24) | (tccd << 16) | (trrd << 8) | (trp << 0);
- writel(reg_val, &mctl_ctl->dramtmg4);
- reg_val = (tcksrx << 24) | (tcksre << 16) | (tckesr << 8) | (tcke << 0);
- writel(reg_val, &mctl_ctl->dramtmg5);
There's a lot of magic numbers here (and in the following code), although in this particular context (with the named var) unless they are the same elsewhere I'm not sure #defines would improve things much, but I think some of the other stuff likely would.
Assuming you have any idea what the bits are, I suppose that per usual we don't really know because -ENODOC?
Ian.

Hi,
On 15-04-15 21:56, Ian Campbell wrote:
On Tue, 2015-04-14 at 18:06 +0200, Hans de Goede wrote:
From: Vishnu Patekar vishnupatekar0510@gmail.com
Based on Allwinner dram init code from the a33 bsp: https://github.com/allwinner-zh/bootloader/blob/master/basic_loader/bsp/bsp_...
Initial u-boot port by Vishnu Patekar, major cleanup / rewrite by Hans de Goede.
Signed-off-by: Vishnu Patekar vishnupatekar0510@gmail.com Signed-off-by: Hans de Goede hdegoede@redhat.com
- /* Set dram timing */
- reg_val = (twtp << 24) | (tfaw << 16) | (trasmax << 8) | (tras << 0);
- writel(reg_val, &mctl_ctl->dramtmg0);
- reg_val = (txp << 16) | (trtp << 8) | (trc << 0);
- writel(reg_val, &mctl_ctl->dramtmg1);
- reg_val = (tcwl << 24) | (tcl << 16) | (trd2wr << 8) | (twr2rd << 0);
- writel(reg_val, &mctl_ctl->dramtmg2);
- reg_val = (tmrw << 16) | (tmrd << 12) | (tmod << 0);
- writel(reg_val, &mctl_ctl->dramtmg3);
- reg_val = (trcd << 24) | (tccd << 16) | (trrd << 8) | (trp << 0);
- writel(reg_val, &mctl_ctl->dramtmg4);
- reg_val = (tcksrx << 24) | (tcksre << 16) | (tckesr << 8) | (tcke << 0);
- writel(reg_val, &mctl_ctl->dramtmg5);
There's a lot of magic numbers here (and in the following code), although in this particular context (with the named var) unless they are the same elsewhere I'm not sure #defines would improve things much, but I think some of the other stuff likely would.
Assuming you have any idea what the bits are, I suppose that per usual we don't really know because -ENODOC?
Right the problem here is -ENODOC, the magic values come from the allwinnner code and in the cases where we do not have named variables (as we do in the above blurb) we've no clue what we're doing really, so I think adding defines there will only obfuscate things.
Can you give a short description of the cases where you believe that adding defines would be a good idea ?
Regards,
Hans

On Thu, 2015-04-16 at 09:27 +0200, Hans de Goede wrote:
Hi,
On 15-04-15 21:56, Ian Campbell wrote:
On Tue, 2015-04-14 at 18:06 +0200, Hans de Goede wrote:
From: Vishnu Patekar vishnupatekar0510@gmail.com
Based on Allwinner dram init code from the a33 bsp: https://github.com/allwinner-zh/bootloader/blob/master/basic_loader/bsp/bsp_...
Initial u-boot port by Vishnu Patekar, major cleanup / rewrite by Hans de Goede.
Signed-off-by: Vishnu Patekar vishnupatekar0510@gmail.com Signed-off-by: Hans de Goede hdegoede@redhat.com
- /* Set dram timing */
- reg_val = (twtp << 24) | (tfaw << 16) | (trasmax << 8) | (tras << 0);
- writel(reg_val, &mctl_ctl->dramtmg0);
- reg_val = (txp << 16) | (trtp << 8) | (trc << 0);
- writel(reg_val, &mctl_ctl->dramtmg1);
- reg_val = (tcwl << 24) | (tcl << 16) | (trd2wr << 8) | (twr2rd << 0);
- writel(reg_val, &mctl_ctl->dramtmg2);
- reg_val = (tmrw << 16) | (tmrd << 12) | (tmod << 0);
- writel(reg_val, &mctl_ctl->dramtmg3);
- reg_val = (trcd << 24) | (tccd << 16) | (trrd << 8) | (trp << 0);
- writel(reg_val, &mctl_ctl->dramtmg4);
- reg_val = (tcksrx << 24) | (tcksre << 16) | (tckesr << 8) | (tcke << 0);
- writel(reg_val, &mctl_ctl->dramtmg5);
There's a lot of magic numbers here (and in the following code), although in this particular context (with the named var) unless they are the same elsewhere I'm not sure #defines would improve things much, but I think some of the other stuff likely would.
Assuming you have any idea what the bits are, I suppose that per usual we don't really know because -ENODOC?
Right the problem here is -ENODOC, the magic values come from the allwinnner code and in the cases where we do not have named variables (as we do in the above blurb) we've no clue what we're doing really, so I think adding defines there will only obfuscate things.
Can you give a short description of the cases where you believe that adding defines would be a good idea ?
Anywhere where we know the meanings ;-) If that's nowhere then the magic numbers are fine (which is what my final paragraph was trying to say, but not very clearly).
Ian.

Hi,
On 04/16/2015 11:09 AM, Ian Campbell wrote:
On Thu, 2015-04-16 at 09:27 +0200, Hans de Goede wrote:
Hi,
On 15-04-15 21:56, Ian Campbell wrote:
On Tue, 2015-04-14 at 18:06 +0200, Hans de Goede wrote:
From: Vishnu Patekar vishnupatekar0510@gmail.com
Based on Allwinner dram init code from the a33 bsp: https://github.com/allwinner-zh/bootloader/blob/master/basic_loader/bsp/bsp_...
Initial u-boot port by Vishnu Patekar, major cleanup / rewrite by Hans de Goede.
Signed-off-by: Vishnu Patekar vishnupatekar0510@gmail.com Signed-off-by: Hans de Goede hdegoede@redhat.com
- /* Set dram timing */
- reg_val = (twtp << 24) | (tfaw << 16) | (trasmax << 8) | (tras << 0);
- writel(reg_val, &mctl_ctl->dramtmg0);
- reg_val = (txp << 16) | (trtp << 8) | (trc << 0);
- writel(reg_val, &mctl_ctl->dramtmg1);
- reg_val = (tcwl << 24) | (tcl << 16) | (trd2wr << 8) | (twr2rd << 0);
- writel(reg_val, &mctl_ctl->dramtmg2);
- reg_val = (tmrw << 16) | (tmrd << 12) | (tmod << 0);
- writel(reg_val, &mctl_ctl->dramtmg3);
- reg_val = (trcd << 24) | (tccd << 16) | (trrd << 8) | (trp << 0);
- writel(reg_val, &mctl_ctl->dramtmg4);
- reg_val = (tcksrx << 24) | (tcksre << 16) | (tckesr << 8) | (tcke << 0);
- writel(reg_val, &mctl_ctl->dramtmg5);
There's a lot of magic numbers here (and in the following code), although in this particular context (with the named var) unless they are the same elsewhere I'm not sure #defines would improve things much, but I think some of the other stuff likely would.
Assuming you have any idea what the bits are, I suppose that per usual we don't really know because -ENODOC?
Right the problem here is -ENODOC, the magic values come from the allwinnner code and in the cases where we do not have named variables (as we do in the above blurb) we've no clue what we're doing really, so I think adding defines there will only obfuscate things.
Can you give a short description of the cases where you believe that adding defines would be a good idea ?
Anywhere where we know the meanings ;-) If that's nowhere then the magic numbers are fine (which is what my final paragraph was trying to say, but not very clearly).
Ok, so I've gone over the entire dram init code another time, and I've not been able to find a single place where I can add a define with a meaningful name to replace the magic values.
So no v2 for this patch, can I get an ack for v1 ?
Regards,
Hans

On Sun, 2015-04-26 at 20:31 +0200, Hans de Goede wrote:
Ok, so I've gone over the entire dram init code another time, and I've not been able to find a single place where I can add a define with a meaningful name to replace the magic values.
OK, thanks for double checking.
So no v2 for this patch, can I get an ack for v1 ?
Acked-by: Ian Campbell ijc@hellion.org.uk
Ian.

For unknown reasons the A33 needs the end of the memory we report to the kernel to be aligned to a multiple of 4 MiB. Without this things will hang when we hand over control to the kernel.
Signed-off-by: Hans de Goede hdegoede@redhat.com --- drivers/video/sunxi_display.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c index e132b75..7a63094 100644 --- a/drivers/video/sunxi_display.c +++ b/drivers/video/sunxi_display.c @@ -1275,6 +1275,15 @@ int sunxi_simplefb_setup(void *blob) */ start = gd->bd->bi_dram[0].start; size = gd->bd->bi_dram[0].size - sunxi_display.fb_size; + /* + * For unknown reasons the A33 needs the end of the memory we report to + * the kernel to be aligned to a multiple of 4 MiB. Without this things + * will hang when we hand over control to the kernel. + */ +#ifdef CONFIG_MACH_SUN8I_A33 + size &= ~(4 * 1024 * 1024 - 1); +#endif + ret = fdt_fixup_memory_banks(blob, &start, &size, 1); if (ret) { eprintf("Cannot setup simplefb: Error reserving memory\n");

On Tue, 2015-04-14 at 18:06 +0200, Hans de Goede wrote:
For unknown reasons the A33 needs the end of the memory we report to the kernel to be aligned to a multiple of 4 MiB.
Do you really mean "the A33 needs" (as in the processor itself) or do you actually mean "the A33 kernel port"?
If the latter than can't that be investigated/fixed instead of hacked here? That would be far more preferable.
Ian.

Hi,
On 15-04-15 21:57, Ian Campbell wrote:
On Tue, 2015-04-14 at 18:06 +0200, Hans de Goede wrote:
For unknown reasons the A33 needs the end of the memory we report to the kernel to be aligned to a multiple of 4 MiB.
Do you really mean "the A33 needs" (as in the processor itself) or do you actually mean "the A33 kernel port"?
If the latter than can't that be investigated/fixed instead of hacked here? That would be far more preferable.
I mean the former, it seems that the SoC itself cannot handle dram ranges with different cache policies which are not aligned to 4 MiB, at least that is my WAG what is going on here.
I've been using an a23 dtb + generic multi-platform kernel for my testing (as said before the a33 really is almost the same design), and that boots fine without this alignment hack on an actual A23 device, so this is not a kernel limitation.
I'm not entirely happy with this semi-magic workaround either, but it took me a day to find it, and then I tried to find a better solution / more satisfying answer as to why for another day, so at this point my vision on this is that we will just have to live with it.
Regards,
Hans

On Thu, Apr 16, 2015 at 08:32:03AM +0100, Hans de Goede wrote:
Hi,
On 15-04-15 21:57, Ian Campbell wrote:
On Tue, 2015-04-14 at 18:06 +0200, Hans de Goede wrote:
For unknown reasons the A33 needs the end of the memory we report to the kernel to be aligned to a multiple of 4 MiB.
Do you really mean "the A33 needs" (as in the processor itself) or do you actually mean "the A33 kernel port"?
If the latter than can't that be investigated/fixed instead of hacked here? That would be far more preferable.
I mean the former, it seems that the SoC itself cannot handle dram ranges with different cache policies which are not aligned to 4 MiB, at least that is my WAG what is going on here.
That sounds incredibly suspicious.
What do you mean w.r.t. different cache policies -- what does that have to do with the end of DRAM? What problem do you see?
It would be worth reporting this on lakml.
I've been using an a23 dtb + generic multi-platform kernel for my testing (as said before the a33 really is almost the same design), and that boots fine without this alignment hack on an actual A23 device, so this is not a kernel limitation.
Not necessarily. Is RAM at the same location on both SoCs? What about other devices and carevouts?
It could be htat the stars happen to align and we're finally caught out by some dodgy maths.
Mark.

Hi,
On 16-04-15 19:35, Mark Rutland wrote:
On Thu, Apr 16, 2015 at 08:32:03AM +0100, Hans de Goede wrote:
Hi,
On 15-04-15 21:57, Ian Campbell wrote:
On Tue, 2015-04-14 at 18:06 +0200, Hans de Goede wrote:
For unknown reasons the A33 needs the end of the memory we report to the kernel to be aligned to a multiple of 4 MiB.
Do you really mean "the A33 needs" (as in the processor itself) or do you actually mean "the A33 kernel port"?
If the latter than can't that be investigated/fixed instead of hacked here? That would be far more preferable.
I mean the former, it seems that the SoC itself cannot handle dram ranges with different cache policies which are not aligned to 4 MiB, at least that is my WAG what is going on here.
That sounds incredibly suspicious.
What do you mean w.r.t. different cache policies -- what does that have to do with the end of DRAM?
We carve out a framebuffer at the end of DRAM, and then report less DRAM then we actually have to the kernel. This framebuffer then gets picked up by the kernel through simplefb, which will map it with a different cache policy then the normal part of the DRAM has.
What problem do you see?
Depending on the framebuffer-size the kernel either boots or does not boot, when it does not boot it does nothing (I've a serial console) earlyprintk does not help, I was looking into setting up an early console (should be a matter of just putting in the right parameters) when I found out that if I modify the framebuffer size that fixes things.
After experimenting more it seems that keeping the last pixel of the framebuffer at the very end of DRAM is not a problem (so this does not seem to be a display engine problem), things start to work when I make the carve out at the end bigger.
On the very similar A23 giving the kernel all of the DRAM except for the framebuffer (aligned to a multiple of 4k) works just fine.
Sometimes I can get away with just making the carve-out bigger without aligning it to a multiple of 4 MiB, but an alignment to 4 MiB seems to always work independent of the framebuffer size.
It would be worth reporting this on lakml.
If you still think that after the above explanation I'll start a new thread on lakml with contents more targeted at kernel devs.
I've been using an a23 dtb + generic multi-platform kernel for my testing (as said before the a33 really is almost the same design), and that boots fine without this alignment hack on an actual A23 device, so this is not a kernel limitation.
Not necessarily. Is RAM at the same location on both SoCs? What about other devices and carevouts?
Everything is the same on both SoCs except that one has 2 Cortex A7 cores and the new one with the problem has 4 Cortex A7 cores, and a new dram controller / mbus subsystem to keep the 4 cores fed.
It could be htat the stars happen to align and we're finally caught out by some dodgy maths.
I don't think that that is the case here.
Regards,
Hans

On Thu, Apr 16, 2015 at 08:12:31PM +0100, Hans de Goede wrote:
Hi,
On 16-04-15 19:35, Mark Rutland wrote:
On Thu, Apr 16, 2015 at 08:32:03AM +0100, Hans de Goede wrote:
Hi,
On 15-04-15 21:57, Ian Campbell wrote:
On Tue, 2015-04-14 at 18:06 +0200, Hans de Goede wrote:
For unknown reasons the A33 needs the end of the memory we report to the kernel to be aligned to a multiple of 4 MiB.
Do you really mean "the A33 needs" (as in the processor itself) or do you actually mean "the A33 kernel port"?
If the latter than can't that be investigated/fixed instead of hacked here? That would be far more preferable.
I mean the former, it seems that the SoC itself cannot handle dram ranges with different cache policies which are not aligned to 4 MiB, at least that is my WAG what is going on here.
That sounds incredibly suspicious.
What do you mean w.r.t. different cache policies -- what does that have to do with the end of DRAM?
We carve out a framebuffer at the end of DRAM, and then report less DRAM then we actually have to the kernel. This framebuffer then gets picked up by the kernel through simplefb, which will map it with a different cache policy then the normal part of the DRAM has.
I see. Thanks for the clarification.
What problem do you see?
Depending on the framebuffer-size the kernel either boots or does not boot, when it does not boot it does nothing (I've a serial console) earlyprintk does not help, I was looking into setting up an early console (should be a matter of just putting in the right parameters) when I found out that if I modify the framebuffer size that fixes things.
Ok. So we don't know if the kernel is stuck somewhere or everything is completely hosed, then?
I take it you can't get JTAG worknig via the SD card slot?
After experimenting more it seems that keeping the last pixel of the framebuffer at the very end of DRAM is not a problem (so this does not seem to be a display engine problem), things start to work when I make the carve out at the end bigger.
On the very similar A23 giving the kernel all of the DRAM except for the framebuffer (aligned to a multiple of 4k) works just fine.
Sometimes I can get away with just making the carve-out bigger without aligning it to a multiple of 4 MiB, but an alignment to 4 MiB seems to always work independent of the framebuffer size.
It would be worth reporting this on lakml.
If you still think that after the above explanation I'll start a new thread on lakml with contents more targeted at kernel devs.
I think it would be worthwhile. This could be one instance of an issue in the memory system that we might hit elsewhere. Even if we don't come to another solution, it'll at least make it visible to others.
I've been using an a23 dtb + generic multi-platform kernel for my testing (as said before the a33 really is almost the same design), and that boots fine without this alignment hack on an actual A23 device, so this is not a kernel limitation.
Not necessarily. Is RAM at the same location on both SoCs? What about other devices and carevouts?
Everything is the same on both SoCs except that one has 2 Cortex A7 cores and the new one with the problem has 4 Cortex A7 cores, and a new dram controller / mbus subsystem to keep the 4 cores fed.
It could be htat the stars happen to align and we're finally caught out by some dodgy maths.
I don't think that that is the case here.
Yeah. The memory subsystem differences sound like the chief suspects.
Do we know if the A7s in the A23 and A33 are different revisions (and which bits are set in their aux registers)? It could be that some memory system features is enabled on one but not the other, or something like that.
Mark.

Hi Mark,
On 17-04-15 12:20, Mark Rutland wrote:
On Thu, Apr 16, 2015 at 08:12:31PM +0100, Hans de Goede wrote:
Hi,
On 16-04-15 19:35, Mark Rutland wrote:
On Thu, Apr 16, 2015 at 08:32:03AM +0100, Hans de Goede wrote:
Hi,
On 15-04-15 21:57, Ian Campbell wrote:
On Tue, 2015-04-14 at 18:06 +0200, Hans de Goede wrote:
For unknown reasons the A33 needs the end of the memory we report to the kernel to be aligned to a multiple of 4 MiB.
Do you really mean "the A33 needs" (as in the processor itself) or do you actually mean "the A33 kernel port"?
If the latter than can't that be investigated/fixed instead of hacked here? That would be far more preferable.
I mean the former, it seems that the SoC itself cannot handle dram ranges with different cache policies which are not aligned to 4 MiB, at least that is my WAG what is going on here.
That sounds incredibly suspicious.
What do you mean w.r.t. different cache policies -- what does that have to do with the end of DRAM?
We carve out a framebuffer at the end of DRAM, and then report less DRAM then we actually have to the kernel. This framebuffer then gets picked up by the kernel through simplefb, which will map it with a different cache policy then the normal part of the DRAM has.
I see. Thanks for the clarification.
What problem do you see?
Depending on the framebuffer-size the kernel either boots or does not boot, when it does not boot it does nothing (I've a serial console) earlyprintk does not help, I was looking into setting up an early console (should be a matter of just putting in the right parameters) when I found out that if I modify the framebuffer size that fixes things.
Ok. So we don't know if the kernel is stuck somewhere or everything is completely hosed, then?
I take it you can't get JTAG worknig via the SD card slot?
After experimenting more it seems that keeping the last pixel of the framebuffer at the very end of DRAM is not a problem (so this does not seem to be a display engine problem), things start to work when I make the carve out at the end bigger.
On the very similar A23 giving the kernel all of the DRAM except for the framebuffer (aligned to a multiple of 4k) works just fine.
Sometimes I can get away with just making the carve-out bigger without aligning it to a multiple of 4 MiB, but an alignment to 4 MiB seems to always work independent of the framebuffer size.
It would be worth reporting this on lakml.
If you still think that after the above explanation I'll start a new thread on lakml with contents more targeted at kernel devs.
I think it would be worthwhile. This could be one instance of an issue in the memory system that we might hit elsewhere. Even if we don't come to another solution, it'll at least make it visible to others.
So it seems that I'm not the only one seeing this, and I've been wrongly blaming it on the A33, instead it seems to be a kernel bug, triggered on my A33 due to the display resolution it has.
For details see:
http://www.spinics.net/lists/arm-kernel/msg413811.html
Regards,
Hans

Hi Hans,
So it seems that I'm not the only one seeing this, and I've been wrongly blaming it on the A33, instead it seems to be a kernel bug, triggered on my A33 due to the display resolution it has.
For details see:
That's good news; far less scary than a HW issue.
Would you mind replying on that thread to give it a bit more visibility?
Thanks, Mark.

From: Vishnu Patekar vishnupatekar0510@gmail.com
Signed-off-by: Vishnu Patekar vishnupatekar0510@gmail.com Signed-off-by: Hans de Goede hdegoede@redhat.com --- arch/arm/cpu/armv7/sunxi/Makefile | 4 ++++ arch/arm/cpu/armv7/sunxi/board.c | 8 +++++--- arch/arm/cpu/armv7/sunxi/cpu_info.c | 2 ++ arch/arm/cpu/armv7/sunxi/rsb.c | 2 +- arch/arm/cpu/armv7/sunxi/usbc.c | 8 ++++++++ board/sunxi/Kconfig | 19 ++++++++++++++----- board/sunxi/board.c | 4 ++-- drivers/power/Kconfig | 4 ++-- drivers/usb/musb-new/musb_regs.h | 5 +++++ drivers/video/sunxi_display.c | 3 +++ include/configs/sunxi-common.h | 3 ++- 11 files changed, 48 insertions(+), 14 deletions(-)
diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile index b2e5e5d..b299635 100644 --- a/arch/arm/cpu/armv7/sunxi/Makefile +++ b/arch/arm/cpu/armv7/sunxi/Makefile @@ -16,15 +16,18 @@ obj-y += pinmux.o obj-y += usbc.o obj-$(CONFIG_MACH_SUN6I) += prcm.o obj-$(CONFIG_MACH_SUN8I_A23) += prcm.o +obj-$(CONFIG_MACH_SUN8I_A33) += prcm.o obj-$(CONFIG_MACH_SUN9I) += prcm.o obj-$(CONFIG_MACH_SUN6I) += p2wi.o obj-$(CONFIG_MACH_SUN8I_A23) += rsb.o +obj-$(CONFIG_MACH_SUN8I_A33) += rsb.o obj-$(CONFIG_MACH_SUN9I) += rsb.o obj-$(CONFIG_MACH_SUN4I) += clock_sun4i.o obj-$(CONFIG_MACH_SUN5I) += clock_sun4i.o obj-$(CONFIG_MACH_SUN6I) += clock_sun6i.o obj-$(CONFIG_MACH_SUN7I) += clock_sun4i.o obj-$(CONFIG_MACH_SUN8I_A23) += clock_sun6i.o +obj-$(CONFIG_MACH_SUN8I_A33) += clock_sun6i.o obj-$(CONFIG_MACH_SUN9I) += clock_sun9i.o
ifndef CONFIG_SPL_BUILD @@ -39,5 +42,6 @@ obj-$(CONFIG_MACH_SUN5I) += dram_sun4i.o obj-$(CONFIG_MACH_SUN6I) += dram_sun6i.o obj-$(CONFIG_MACH_SUN7I) += dram_sun4i.o obj-$(CONFIG_MACH_SUN8I_A23) += dram_sun8i_a23.o +obj-$(CONFIG_MACH_SUN8I_A33) += dram_sun8i_a33.o obj-y += fel_utils.o endif diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c index 7ce79af..283e3ab 100644 --- a/arch/arm/cpu/armv7/sunxi/board.c +++ b/arch/arm/cpu/armv7/sunxi/board.c @@ -46,7 +46,7 @@ static int gpio_init(void) sunxi_gpio_set_cfgpin(SUNXI_GPB(22), SUNXI_GPIO_INPUT); sunxi_gpio_set_cfgpin(SUNXI_GPB(23), SUNXI_GPIO_INPUT); #endif -#if defined(CONFIG_MACH_SUN8I_A23) +#if defined(CONFIG_MACH_SUN8I_A23) || defined(CONFIG_MACH_SUN8I_A33) sunxi_gpio_set_cfgpin(SUNXI_GPF(2), SUN8I_GPF_UART0_TX); sunxi_gpio_set_cfgpin(SUNXI_GPF(4), SUN8I_GPF_UART0_RX); #else @@ -70,7 +70,8 @@ static int gpio_init(void) sunxi_gpio_set_cfgpin(SUNXI_GPG(3), SUN5I_GPG_UART1); sunxi_gpio_set_cfgpin(SUNXI_GPG(4), SUN5I_GPG_UART1); sunxi_gpio_set_pull(SUNXI_GPG(4), SUNXI_GPIO_PULL_UP); -#elif CONFIG_CONS_INDEX == 5 && defined(CONFIG_MACH_SUN8I_A23) +#elif CONFIG_CONS_INDEX == 5 && \ + (defined(CONFIG_MACH_SUN8I_A23) || defined(CONFIG_MACH_SUN8I_A33)) sunxi_gpio_set_cfgpin(SUNXI_GPL(2), SUN8I_GPL_R_UART); sunxi_gpio_set_cfgpin(SUNXI_GPL(3), SUN8I_GPL_R_UART); sunxi_gpio_set_pull(SUNXI_GPL(3), SUNXI_GPIO_PULL_UP); @@ -96,7 +97,8 @@ void s_init(void) #endif #if defined CONFIG_MACH_SUN6I || \ defined CONFIG_MACH_SUN7I || \ - defined CONFIG_MACH_SUN8I_A23 + defined CONFIG_MACH_SUN8I_A23 || \ + defined CONFIG_MACH_SUN8I_A33 /* 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 6143038..fda62ab 100644 --- a/arch/arm/cpu/armv7/sunxi/cpu_info.c +++ b/arch/arm/cpu/armv7/sunxi/cpu_info.c @@ -66,6 +66,8 @@ int print_cpuinfo(void) puts("CPU: Allwinner A20 (SUN7I)\n"); #elif defined CONFIG_MACH_SUN8I_A23 puts("CPU: Allwinner A23 (SUN8I)\n"); +#elif defined CONFIG_MACH_SUN8I_A33 + puts("CPU: Allwinner A33 (SUN8I)\n"); #else #warning Please update cpu_info.c with correct CPU information puts("CPU: SUNXI Family\n"); diff --git a/arch/arm/cpu/armv7/sunxi/rsb.c b/arch/arm/cpu/armv7/sunxi/rsb.c index d8d4957..076592b 100644 --- a/arch/arm/cpu/armv7/sunxi/rsb.c +++ b/arch/arm/cpu/armv7/sunxi/rsb.c @@ -20,7 +20,7 @@ static int rsb_set_device_mode(void);
static void rsb_cfg_io(void) { -#if defined CONFIG_MACH_SUN8I_A23 +#if defined CONFIG_MACH_SUN8I_A23 || defined CONFIG_MACH_SUN8I_A33 sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN8I_GPL_R_RSB); sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN8I_GPL_R_RSB); sunxi_gpio_set_pull(SUNXI_GPL(0), 1); diff --git a/arch/arm/cpu/armv7/sunxi/usbc.c b/arch/arm/cpu/armv7/sunxi/usbc.c index 85b3448..515549d 100644 --- a/arch/arm/cpu/armv7/sunxi/usbc.c +++ b/arch/arm/cpu/armv7/sunxi/usbc.c @@ -28,7 +28,11 @@ #endif
#define SUNXI_USB_PMU_IRQ_ENABLE 0x800 +#ifdef CONFIG_MACH_SUN8I_A33 +#define SUNXI_USB_CSR 0x410 +#else #define SUNXI_USB_CSR 0x404 +#endif #define SUNXI_USB_PASSBY_EN 1
#define SUNXI_EHCI_AHB_ICHR8_EN (1 << 10) @@ -103,6 +107,10 @@ static void usb_phy_write(struct sunxi_usbc_hcd *sunxi_usbc, int addr, int j = 0, usbc_bit = 0; void *dest = sunxi_usbc_get_io_base(0) + SUNXI_USB_CSR;
+#ifdef CONFIG_MACH_SUN8I_A33 + writel(0, dest); +#endif + usbc_bit = 1 << (sunxi_usbc->id * 2); for (j = 0; j < len; j++) { /* set the bit address to be written */ diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index 92922b8..a4095d9 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -40,11 +40,17 @@ config MACH_SUN8I_A23 select CPU_V7 select SUPPORT_SPL
+config MACH_SUN8I_A33 + bool "sun8i (Allwinner A33)" + select ARCH_SUN6I + select CPU_V7 + select SUPPORT_SPL + endchoice
config DRAM_CLK int "sunxi dram clock speed" - default 312 if MACH_SUN6I || MACH_SUN8I_A23 + default 312 if MACH_SUN6I || MACH_SUN8I_A23 || MACH_SUN8I_A33 default 360 if MACH_SUN4I || MACH_SUN5I || MACH_SUN7I ---help--- Set the dram clock speed, valid range 240 - 480, must be a multiple @@ -61,7 +67,8 @@ endif
config DRAM_ZQ int "sunxi dram zq value" - default 123 if MACH_SUN4I || MACH_SUN5I || MACH_SUN6I || MACH_SUN8I_A23 + default 123 if MACH_SUN4I || MACH_SUN5I || MACH_SUN6I + default 123 if MACH_SUN8I_A23 || MACH_SUN8I_A33 default 127 if MACH_SUN7I ---help--- Set the dram zq value. @@ -144,7 +151,7 @@ endif config SYS_CLK_FREQ default 912000000 if MACH_SUN7I default 1008000000 if MACH_SUN4I || MACH_SUN5I || MACH_SUN6I - default 1008000000 if MACH_SUN8I_A23 + default 1008000000 if MACH_SUN8I_A23 || MACH_SUN8I_A33
config SYS_CONFIG_NAME default "sun4i" if MACH_SUN4I @@ -152,6 +159,7 @@ config SYS_CONFIG_NAME default "sun6i" if MACH_SUN6I default "sun7i" if MACH_SUN7I default "sun8i" if MACH_SUN8I_A23 + default "sun8i" if MACH_SUN8I_A33
config SYS_BOARD default "sunxi" @@ -289,7 +297,7 @@ config VIDEO
config VIDEO_HDMI boolean "HDMI output support" - depends on VIDEO && !MACH_SUN8I_A23 + depends on VIDEO && !MACH_SUN8I_A23 && !MACH_SUN8I_A33 default y ---help--- Say Y here to add support for outputting video over HDMI. @@ -303,7 +311,8 @@ config VIDEO_VGA
config VIDEO_VGA_VIA_LCD boolean "VGA via LCD controller support" - depends on VIDEO && (MACH_SUN5I || MACH_SUN6I || MACH_SUN8I_A23) + depends on VIDEO + depends on MACH_SUN5I || MACH_SUN6I || MACH_SUN8I_A23 || MACH_SUN8I_A33 default n ---help--- Say Y here to add support for external DACs connected to the parallel diff --git a/board/sunxi/board.c b/board/sunxi/board.c index 83ef0e5..a50a9f5 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -116,7 +116,7 @@ static void mmc_pinmux_setup(int sdc) sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); sunxi_gpio_set_drv(pin, 2); } -#elif defined(CONFIG_MACH_SUN8I_A23) +#elif defined(CONFIG_MACH_SUN8I_A23) || defined(CONFIG_MACH_SUN8I_A33) if (pins == SUNXI_GPIO_D) { /* SDC1: PD2-PD7 */ for (pin = SUNXI_GPD(2); pin <= SUNXI_GPD(7); pin++) { @@ -181,7 +181,7 @@ static void mmc_pinmux_setup(int sdc) sunxi_gpio_set_pull(SUNXI_GPC(24), SUNXI_GPIO_PULL_UP); sunxi_gpio_set_drv(SUNXI_GPC(24), 2); } -#elif defined(CONFIG_MACH_SUN8I_A23) +#elif defined(CONFIG_MACH_SUN8I_A23) || defined(CONFIG_MACH_SUN8I_A33) /* SDC2: PC5-PC6, PC8-PC16 */ for (pin = SUNXI_GPC(5); pin <= SUNXI_GPC(6); pin++) { sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2); diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 39051e4..02ea6c1 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -1,6 +1,6 @@ config AXP221_POWER boolean "axp221 / axp223 pmic support" - depends on MACH_SUN6I || MACH_SUN8I_A23 + depends on MACH_SUN6I || MACH_SUN8I_A23 || MACH_SUN8I_A33 default y ---help--- Say y here to enable support for the axp221 / axp223 pmic found on most @@ -47,7 +47,7 @@ config AXP221_ALDO2_VOLT int "axp221 aldo2 voltage" depends on AXP221_POWER default 0 if MACH_SUN6I - default 2500 if MACH_SUN8I_A23 + default 2500 if MACH_SUN8I_A23 || MACH_SUN8I_A33 ---help--- Set the voltage (mV) to program the axp221 aldo2 at, set to 0 to disable aldo2. On sun6i (A31) boards this is typically unused and diff --git a/drivers/usb/musb-new/musb_regs.h b/drivers/usb/musb-new/musb_regs.h index 27e4ed4..90288c4 100644 --- a/drivers/usb/musb-new/musb_regs.h +++ b/drivers/usb/musb-new/musb_regs.h @@ -458,8 +458,13 @@ static inline u8 musb_read_ulpi_buscontrol(void __iomem *mbase)
static inline u8 musb_read_configdata(void __iomem *mbase) { +#ifdef CONFIG_MACH_SUN8I_A33 + /* <Sigh> allwinner saves a reg, and we need to hardcode this */ + return 0xde; +#else musb_writeb(mbase, MUSB_INDEX, 0); return musb_readb(mbase, 0x10 + MUSB_CONFIGDATA); +#endif }
static inline u16 musb_read_hwvers(void __iomem *mbase) diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c index 7a63094..07c7a18 100644 --- a/drivers/video/sunxi_display.c +++ b/drivers/video/sunxi_display.c @@ -947,6 +947,9 @@ static void sunxi_drc_init(void) (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
/* On sun6i the drc must be clocked even when in pass-through mode */ +#ifdef CONFIG_MACH_SUN8I_A33 + setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_SAT); +#endif setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_DRC0); clock_set_de_mod_clock(&ccm->iep_drc0_clk_cfg, 300000000); #endif diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index ba4d66c..16c92b1 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -237,7 +237,8 @@ extern int soft_i2c_gpio_scl; #endif #elif CONFIG_CONS_INDEX == 2 && defined(CONFIG_MACH_SUN5I) #define OF_STDOUT_PATH "/soc@01c00000/serial@01c28400:115200" -#elif CONFIG_CONS_INDEX == 5 && defined(CONFIG_MACH_SUN8I_A23) +#elif CONFIG_CONS_INDEX == 5 && \ + (defined(CONFIG_MACH_SUN8I_A23) || defined(CONFIG_MACH_SUN8I_A33)) #define OF_STDOUT_PATH "/soc@01c00000/serial@01f02800:115200" #else #error Unsupported console port nr. Please fix stdout-path in sunxi-common.h.

On Tue, 2015-04-14 at 18:06 +0200, Hans de Goede wrote:
From: Vishnu Patekar vishnupatekar0510@gmail.com
A quick comment on what "basic" here means, i.e. "prcm, rsb, clocks as per sun6i", etc would be good.
Signed-off-by: Vishnu Patekar vishnupatekar0510@gmail.com Signed-off-by: Hans de Goede hdegoede@redhat.com
Did you make non-trivial mods or is this S-o-b just a passing it along one? (In the latter case I won't bother to review deeply myself unless you want me to)
@@ -103,6 +107,10 @@ static void usb_phy_write(struct sunxi_usbc_hcd *sunxi_usbc, int addr, int j = 0, usbc_bit = 0; void *dest = sunxi_usbc_get_io_base(0) + SUNXI_USB_CSR;
+#ifdef CONFIG_MACH_SUN8I_A33
- writel(0, dest);
+#endif
Some undocumented/commented magic? Ian

Hi,
On 15-04-15 22:00, Ian Campbell wrote:
On Tue, 2015-04-14 at 18:06 +0200, Hans de Goede wrote:
From: Vishnu Patekar vishnupatekar0510@gmail.com
A quick comment on what "basic" here means, i.e. "prcm, rsb, clocks as per sun6i", etc would be good.
Actually the Basic is misleading here, since this adds full support, usb controller, display output, etc. everything works, so I'll drop the Basic from the Subject and add a proper commit message.
Signed-off-by: Vishnu Patekar vishnupatekar0510@gmail.com Signed-off-by: Hans de Goede hdegoede@redhat.com
Did you make non-trivial mods or is this S-o-b just a passing it along one? (In the latter case I won't bother to review deeply myself unless you want me to)
I made non-trivial mods, both the display driver and usb driver changes are all from my hand.
@@ -103,6 +107,10 @@ static void usb_phy_write(struct sunxi_usbc_hcd *sunxi_usbc, int addr, int j = 0, usbc_bit = 0; void *dest = sunxi_usbc_get_io_base(0) + SUNXI_USB_CSR;
+#ifdef CONFIG_MACH_SUN8I_A33
- writel(0, dest);
+#endif
Some undocumented/commented magic?
Pretty much, I took this from the Allwinner sources which have a comment along the lines of this needs to be explicitly initialized to 0 on A33, I can add such a comment if you want me to.
Regards,
Hans

On Thu, 2015-04-16 at 09:35 +0200, Hans de Goede wrote:
Hi,
On 15-04-15 22:00, Ian Campbell wrote:
On Tue, 2015-04-14 at 18:06 +0200, Hans de Goede wrote:
From: Vishnu Patekar vishnupatekar0510@gmail.com
A quick comment on what "basic" here means, i.e. "prcm, rsb, clocks as per sun6i", etc would be good.
Actually the Basic is misleading here, since this adds full support, usb controller, display output, etc. everything works, so I'll drop the Basic from the Subject and add a proper commit message.
Signed-off-by: Vishnu Patekar vishnupatekar0510@gmail.com Signed-off-by: Hans de Goede hdegoede@redhat.com
Did you make non-trivial mods or is this S-o-b just a passing it along one? (In the latter case I won't bother to review deeply myself unless you want me to)
I made non-trivial mods, both the display driver and usb driver changes are all from my hand.
@@ -103,6 +107,10 @@ static void usb_phy_write(struct sunxi_usbc_hcd *sunxi_usbc, int addr, int j = 0, usbc_bit = 0; void *dest = sunxi_usbc_get_io_base(0) + SUNXI_USB_CSR;
+#ifdef CONFIG_MACH_SUN8I_A33
- writel(0, dest);
+#endif
Some undocumented/commented magic?
Pretty much, I took this from the Allwinner sources which have a comment along the lines of this needs to be explicitly initialized to 0 on A33, I can add such a comment if you want me to.
I think a comment would be good, lest someone in the future think it was put there for as known reason.
Ian.

From: Vishnu Patekar vishnupatekar0510@gmail.com
The Astar MID756 is a 7" tablet using the A33 SoC with a 800x480 LCD screen, 512M RAM, 8G ROM and integrated sdio wifi.
Also see: http://linux-sunxi.org/Softwinner_astar-rda
Signed-off-by: Vishnu Patekar vishnupatekar0510@gmail.com Signed-off-by: Hans de Goede hdegoede@redhat.com --- board/sunxi/MAINTAINERS | 5 +++++ configs/Astar_MID756_defconfig | 25 +++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 configs/Astar_MID756_defconfig
diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS index f368d6f..eb3675f 100644 --- a/board/sunxi/MAINTAINERS +++ b/board/sunxi/MAINTAINERS @@ -61,6 +61,11 @@ M: Paul Kocialkowski contact@paulk.fr S: Maintained F: configs/Ampe_A76_defconfig
+Astar MID756 BOARD +M: VishnuPatekar vishnupatekar0510@gmail.com +S: Maintained +F: configs/Astar_MID756_defconfig + COLOMBUS BOARD M: Maxime Ripard maxime.ripard@free-electrons.com S: Maintained diff --git a/configs/Astar_MID756_defconfig b/configs/Astar_MID756_defconfig new file mode 100644 index 0000000..2634a27 --- /dev/null +++ b/configs/Astar_MID756_defconfig @@ -0,0 +1,25 @@ +# The Astar MID756 is a 7" tablet using the A33 SoC with a 800x480 LCD screen, +# 512M RAM, 8G ROM and integrated sdio wifi. +# +# Also see: http://linux-sunxi.org/Softwinner_astar-rda +CONFIG_SPL=y +CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=5" +CONFIG_FDTFILE="sun8i-a33-astar-mid756.dtb" +CONFIG_USB_MUSB_SUNXI=y +CONFIG_USB0_VBUS_PIN="AXP0-VBUS-ENABLE" +CONFIG_USB0_VBUS_DET="AXP0-VBUS-DETECT" +CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:87,ri:168,up:31,lo:13,hs:1,vs:1,sync:3,vmode:0" +CONFIG_VIDEO_LCD_DCLK_PHASE=0 +CONFIG_VIDEO_LCD_POWER="PH7" +CONFIG_VIDEO_LCD_BL_EN="PH6" +CONFIG_VIDEO_LCD_BL_PWM="PH0" +CONFIG_ARM=y +CONFIG_ARCH_SUNXI=y +CONFIG_MACH_SUN8I_A33=y +CONFIG_DRAM_CLK=480 +# zq = 0x3bbb +CONFIG_DRAM_ZQ=15291 +# Wifi power +CONFIG_AXP221_DLDO1_VOLT=3300 +# aldo1 is connected to VCC-IO, VCC-PD, VCC-USB and VCC-HP +CONFIG_AXP221_ALDO1_VOLT=3000

On Tue, 2015-04-14 at 18:07 +0200, Hans de Goede wrote:
From: Vishnu Patekar vishnupatekar0510@gmail.com
The Astar MID756 is a 7" tablet using the A33 SoC with a 800x480 LCD screen, 512M RAM, 8G ROM and integrated sdio wifi.
Also see: http://linux-sunxi.org/Softwinner_astar-rda
Signed-off-by: Vishnu Patekar vishnupatekar0510@gmail.com Signed-off-by: Hans de Goede hdegoede@redhat.com
Acked-by: Ian Campbell ijc@hellion.org.uk

On Thu, Apr 16, 2015 at 4:01 AM, Ian Campbell ijc@hellion.org.uk wrote:
On Tue, 2015-04-14 at 18:07 +0200, Hans de Goede wrote:
From: Vishnu Patekar vishnupatekar0510@gmail.com
The Astar MID756 is a 7" tablet using the A33 SoC with a 800x480 LCD screen, 512M RAM, 8G ROM and integrated sdio wifi.
Sorry for digging up old stuff, but this board seems to be poorly named.
It is clearly a relative of the Q8 family, having Q8_A23_A33_V1.6 printed on the board. "Softwinner astar-rda" does not really identify the board, rather just the kernel. "Softwinner" is seen in all Allwinner stock kernels. "RDA" likely means the kernel is a variant with support for the RDA WiFi chip.
I would label this as another Q8H revision. The board has similar dimensions and layout to previous ones.
Regards ChenYu
P.S. I've ordered a Q8 style A33 tablet which should arrive soon. We'll see what board variant it has inside.
Also see: http://linux-sunxi.org/Softwinner_astar-rda
Signed-off-by: Vishnu Patekar vishnupatekar0510@gmail.com Signed-off-by: Hans de Goede hdegoede@redhat.com
Acked-by: Ian Campbell ijc@hellion.org.uk
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

Hi,
On 05/04/2015 05:48 PM, Chen-Yu Tsai wrote:
On Thu, Apr 16, 2015 at 4:01 AM, Ian Campbell ijc@hellion.org.uk wrote:
On Tue, 2015-04-14 at 18:07 +0200, Hans de Goede wrote:
From: Vishnu Patekar vishnupatekar0510@gmail.com
The Astar MID756 is a 7" tablet using the A33 SoC with a 800x480 LCD screen, 512M RAM, 8G ROM and integrated sdio wifi.
Sorry for digging up old stuff, but this board seems to be poorly named.
It is clearly a relative of the Q8 family, having Q8_A23_A33_V1.6 printed on the board. "Softwinner astar-rda" does not really identify the board, rather just the kernel. "Softwinner" is seen in all Allwinner stock kernels. "RDA" likely means the kernel is a variant with support for the RDA WiFi chip.
I would label this as another Q8H revision. The board has similar dimensions and layout to previous ones.
I tend to agree I would welcome a patch to rename it, please coordinate this with the board MAINTAINER.
Regards,
Hans

Add a defconfig for generic 7" tablets using the Ippo q8h v1.2 pcb, with an A33 SoC (the pcb can take an A23 or an A33), and a 1024x600 LCD.
Signed-off-by: Hans de Goede hdegoede@redhat.com --- board/sunxi/MAINTAINERS | 1 + configs/Ippo_q8h_v1_2_a33_1024x600_defconfig | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 configs/Ippo_q8h_v1_2_a33_1024x600_defconfig
diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS index eb3675f..9f6bd13 100644 --- a/board/sunxi/MAINTAINERS +++ b/board/sunxi/MAINTAINERS @@ -38,6 +38,7 @@ F: configs/qt840a_defconfig F: configs/Wits_Pro_A20_DKT_defconfig F: include/configs/sun8i.h F: configs/Ippo_q8h_v1_2_defconfig +F: configs/Ippo_q8h_v1_2_a33_1024x600_defconfig
A20-OLINUXINO-LIME BOARD M: FUKAUMI Naoki naobsd@gmail.com diff --git a/configs/Ippo_q8h_v1_2_a33_1024x600_defconfig b/configs/Ippo_q8h_v1_2_a33_1024x600_defconfig new file mode 100644 index 0000000..52a390d --- /dev/null +++ b/configs/Ippo_q8h_v1_2_a33_1024x600_defconfig @@ -0,0 +1,23 @@ +# This is a defconfig for generic 7" tablets using the Ippo q8h v1.2 pcb, +# with an A33 SoC (the pcb can take an A23 or an A33), and a 1024x600 LCD +CONFIG_SPL=y +CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=5" +CONFIG_FDTFILE="sun8i-a33-ippo-q8h-v1.2-lcd1024x600.dtb" +CONFIG_USB_MUSB_SUNXI=y +CONFIG_USB0_VBUS_PIN="AXP0-VBUS-ENABLE" +CONFIG_USB0_VBUS_DET="AXP0-VBUS-DETECT" +CONFIG_VIDEO_LCD_MODE="x:1024,y:600,depth:18,pclk_khz:51000,le:159,ri:160,up:22,lo:12,hs:1,vs:1,sync:3,vmode:0" +CONFIG_VIDEO_LCD_DCLK_PHASE=0 +CONFIG_VIDEO_LCD_POWER="PH7" +CONFIG_VIDEO_LCD_BL_EN="PH6" +CONFIG_VIDEO_LCD_BL_PWM="PH0" +CONFIG_ARM=y +CONFIG_ARCH_SUNXI=y +CONFIG_MACH_SUN8I_A33=y +CONFIG_DRAM_CLK=480 +# zq = 0x3bbb +CONFIG_DRAM_ZQ=15291 +# Wifi power +CONFIG_AXP221_DLDO1_VOLT=3300 +# aldo1 is connected to VCC-IO, VCC-PD, VCC-USB and VCC-HP +CONFIG_AXP221_ALDO1_VOLT=3000

On Tue, 2015-04-14 at 18:07 +0200, Hans de Goede wrote:
Add a defconfig for generic 7" tablets using the Ippo q8h v1.2 pcb, with an A33 SoC (the pcb can take an A23 or an A33), and a 1024x600 LCD.
Signed-off-by: Hans de Goede hdegoede@redhat.com
Acked-by: Ian Campbell ijc@hellion.org.uk

On Tue, 2015-04-14 at 18:06 +0200, Hans de Goede wrote:
There is no reason not to and this make the #ifdef-ery easier to read.
Signed-off-by: Hans de Goede hdegoede@redhat.com
Acked-by: Ian Campbell ian.campbell@citrix.com
participants (5)
-
Chen-Yu Tsai
-
Hans de Goede
-
Ian Campbell
-
Mark Rutland
-
Michal Suchanek