[U-Boot] [PATCH 00/12] sunxi: Allwinner H5 and OrangePi PC2 support

This series introduces support for the Allwinner H5 SoC with four Cortex-A53 cores. The SoC's peripherals are very similar to the H3, although the cores and the BROM/SRAM layout resembles the A64. The first 6 patches contain some fixes and refactoring, to make code sharing between the three mentioned SoCs easier. Patch 07/12 adds support for the H5 DRAM controller, by extending the already existing combined H3/A64 DRAM code. Patch 08/12 renames the existing CONFIG_MACH_SUN8I_H3 config symbol to let it be used by all peripheral code that can be shared between the H3 and H5. Patch 10/12 introduces the H5 SoC config option into Kconfig, which defines this shared symbol as well. Patch 11/12 adds an easy device tree, which actually uses the H3 .dtsi and overwrites nodes which are different. This is good enough for U-Boot, the DT will be changed anyway once we get the DT merged into the Linux kernel. The final patch then adds the defconfig for the OrangePi PC2 board. Since this board comes with soldered SPI flash, we enable support for it in the SPL. This has been tested by writing the SPI flash with some special sunxi-fel version. The BROM loaded and executed the SPL, which in turn loaded and executed U-Boot proper. Both parts are 64-bit only for now. Ethernet support is enabled, but fails at the moment since the EMAC driver does not support setting a GPIO to enable the external Gigabit PHY. This should be a problem for H3 boards with Gigabit as well.
At the moment this build suffers from the same problem as the A64: the ATF is missing, so Linux won't boot easily. However I finally managed to clean up the FIT extension series, which solves this problem in a quite elegant way. I will post this series after getting some sleep ;-)
This series is on top of sunxi/next, which has three yet unmerged (and unrelated) patches compared to HEAD. So it should apply to both branches.
Some of these patches will probably conflict with ongoing work from Icenowy, I am happy to rebase on any branch someone points me to.
Please have a look and let me know your opinion!
Cheers, Andre.
Andre Przywara (12): sunxi: fix ACTLR.SMP assembly routine sunxi: simplify ACTLR.SMP bit set #ifdef sunxi: configs: merge sun9i and sun50i SPL memory definitions sunxi: Kconfig: introduce CONFIG_SUNXI_HIGH_SRAM sunxi: provide ARMv8 mem_map for every ARM64 board SPI: SPL: sunxi: fix 64-bit build sunxi: DRAM: add Allwinner H5 support sunxi: prepare for sharing MACH_SUN8I_H3 config symbol sunxi: H5: add COUNTER_FREQUENCY sunxi: introduce Allwinner H5 config option sunxi: dts: add basic OrangePi PC 2 device tree file sunxi: configs: add basic OrangePi PC 2 defconfig
arch/arm/dts/Makefile | 2 + arch/arm/dts/sun50i-h5-orangepi-pc2.dts | 147 ++++++++++++++++++++++++++ arch/arm/include/asm/arch-sunxi/clock_sun6i.h | 4 +- arch/arm/include/asm/arch-sunxi/cpu.h | 1 + arch/arm/include/asm/arch-sunxi/cpu_sun4i.h | 4 +- arch/arm/include/asm/arch-sunxi/dram.h | 2 +- arch/arm/include/asm/arch-sunxi/spl.h | 2 +- arch/arm/mach-sunxi/Makefile | 2 +- arch/arm/mach-sunxi/board.c | 21 ++-- arch/arm/mach-sunxi/clock_sun6i.c | 6 +- arch/arm/mach-sunxi/cpu_info.c | 2 + arch/arm/mach-sunxi/dram_sun8i_h3.c | 97 ++++++++++++++--- arch/arm/mach-sunxi/usb_phy.c | 4 +- board/sunxi/Kconfig | 36 ++++++- board/sunxi/MAINTAINERS | 5 + configs/orangepi_pc2_defconfig | 16 +++ drivers/mtd/spi/Kconfig | 2 +- drivers/mtd/spi/sunxi_spi_spl.c | 16 +-- drivers/net/sun8i_emac.c | 2 +- drivers/power/Kconfig | 4 +- drivers/usb/host/ehci-sunxi.c | 2 +- include/configs/sun8i.h | 2 + include/configs/sunxi-common.h | 22 ++-- 23 files changed, 330 insertions(+), 71 deletions(-) create mode 100644 arch/arm/dts/sun50i-h5-orangepi-pc2.dts create mode 100644 configs/orangepi_pc2_defconfig

If we take the liberty to use register r0 to perform our bit set, we should be nice enough to tell the compiler about it. Add r0 to the clobber list to avoid potential mayhem.
Signed-off-by: Andre Przywara andre.przywara@arm.com --- arch/arm/mach-sunxi/board.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c index 52be5b0..58fbacb 100644 --- a/arch/arm/mach-sunxi/board.c +++ b/arch/arm/mach-sunxi/board.c @@ -188,7 +188,8 @@ void s_init(void) asm volatile( "mrc p15, 0, r0, c1, c0, 1\n" "orr r0, r0, #1 << 6\n" - "mcr p15, 0, r0, c1, c0, 1\n"); + "mcr p15, 0, r0, c1, c0, 1\n" + ::: "r0"); #endif #if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I_H3 /* Enable non-secure access to some peripherals */

On Fri, Jan 13, 2017 at 01:29:53AM +0000, Andre Przywara wrote:
If we take the liberty to use register r0 to perform our bit set, we should be nice enough to tell the compiler about it. Add r0 to the clobber list to avoid potential mayhem.
Signed-off-by: Andre Przywara andre.przywara@arm.com
Acked-by: Maxime Ripard maxime.ripard@free-electrons.com
Thanks, Maxime

Instead of enumerating all SoC families that need that bit set, let's just express this more clearly: The SMP bits needs to be set on SMP capable ARMv7 CPUs. It's much easier to Kconfig to express it the other way round, so we use ! NO_SMP and ! ARM64.
Signed-off-by: Andre Przywara andre.przywara@arm.com --- arch/arm/mach-sunxi/board.c | 5 +---- board/sunxi/Kconfig | 6 ++++++ 2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c index 58fbacb..5a63124 100644 --- a/arch/arm/mach-sunxi/board.c +++ b/arch/arm/mach-sunxi/board.c @@ -180,10 +180,7 @@ void s_init(void) /* No H3 BSP, boot0 seems to not modify SUNXI_SRAMC_BASE + 0x44 */ #endif
-#if defined CONFIG_MACH_SUN6I || \ - defined CONFIG_MACH_SUN7I || \ - defined CONFIG_MACH_SUN8I || \ - defined CONFIG_MACH_SUN9I +#if !defined(CONFIG_SUNXI_NO_SMP) && !defined(CONFIG_ARM64) /* 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/board/sunxi/Kconfig b/board/sunxi/Kconfig index 37b4252..79b6fa7 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -27,6 +27,10 @@ config SPL_POWER_SUPPORT config SPL_SERIAL_SUPPORT default y
+config SUNXI_NO_SMP + bool + default n + # Note only one of these may be selected at a time! But hidden choices are # not supported by Kconfig config SUNXI_GEN_SUN4I @@ -50,12 +54,14 @@ choice config MACH_SUN4I bool "sun4i (Allwinner A10)" select CPU_V7 + select SUNXI_NO_SMP select SUNXI_GEN_SUN4I select SUPPORT_SPL
config MACH_SUN5I bool "sun5i (Allwinner A13)" select CPU_V7 + select SUNXI_NO_SMP select SUNXI_GEN_SUN4I select SUPPORT_SPL

13.01.2017, 09:34, "Andre Przywara" andre.przywara@arm.com:
Instead of enumerating all SoC families that need that bit set, let's just express this more clearly: The SMP bits needs to be set on SMP capable ARMv7 CPUs. It's much easier to Kconfig to express it the other way round, so we use ! NO_SMP and ! ARM64.
How about single-core Cortex-A7?
Signed-off-by: Andre Przywara andre.przywara@arm.com
arch/arm/mach-sunxi/board.c | 5 +---- board/sunxi/Kconfig | 6 ++++++ 2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c index 58fbacb..5a63124 100644 --- a/arch/arm/mach-sunxi/board.c +++ b/arch/arm/mach-sunxi/board.c @@ -180,10 +180,7 @@ void s_init(void) /* No H3 BSP, boot0 seems to not modify SUNXI_SRAMC_BASE + 0x44 */ #endif
-#if defined CONFIG_MACH_SUN6I || \
- defined CONFIG_MACH_SUN7I || \
- defined CONFIG_MACH_SUN8I || \
- defined CONFIG_MACH_SUN9I
+#if !defined(CONFIG_SUNXI_NO_SMP) && !defined(CONFIG_ARM64) /* 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/board/sunxi/Kconfig b/board/sunxi/Kconfig index 37b4252..79b6fa7 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -27,6 +27,10 @@ config SPL_POWER_SUPPORT config SPL_SERIAL_SUPPORT default y
+config SUNXI_NO_SMP
- bool
- default n
# Note only one of these may be selected at a time! But hidden choices are # not supported by Kconfig config SUNXI_GEN_SUN4I @@ -50,12 +54,14 @@ choice config MACH_SUN4I bool "sun4i (Allwinner A10)" select CPU_V7
- select SUNXI_NO_SMP
select SUNXI_GEN_SUN4I select SUPPORT_SPL
config MACH_SUN5I bool "sun5i (Allwinner A13)" select CPU_V7
- select SUNXI_NO_SMP
select SUNXI_GEN_SUN4I select SUPPORT_SPL
-- 2.8.2

Even for the single core cortex-a7, SMP bit should be set before enabling MMU and cache.
Reference: Cortex A7 r0p5 TRM. section 4.3.31.
On Fri, Jan 13, 2017 at 12:41 PM, Icenowy Zheng icenowy@aosc.xyz wrote:
13.01.2017, 09:34, "Andre Przywara" andre.przywara@arm.com:
Instead of enumerating all SoC families that need that bit set, let's just express this more clearly: The SMP bits needs to be set on SMP capable ARMv7 CPUs. It's much easier to Kconfig to express it the other way round, so we use ! NO_SMP and ! ARM64.
How about single-core Cortex-A7?
Signed-off-by: Andre Przywara andre.przywara@arm.com
arch/arm/mach-sunxi/board.c | 5 +---- board/sunxi/Kconfig | 6 ++++++ 2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c index 58fbacb..5a63124 100644 --- a/arch/arm/mach-sunxi/board.c +++ b/arch/arm/mach-sunxi/board.c @@ -180,10 +180,7 @@ void s_init(void) /* No H3 BSP, boot0 seems to not modify SUNXI_SRAMC_BASE + 0x44 */ #endif
-#if defined CONFIG_MACH_SUN6I || \
- defined CONFIG_MACH_SUN7I || \
- defined CONFIG_MACH_SUN8I || \
- defined CONFIG_MACH_SUN9I
+#if !defined(CONFIG_SUNXI_NO_SMP) && !defined(CONFIG_ARM64) /* 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/board/sunxi/Kconfig b/board/sunxi/Kconfig index 37b4252..79b6fa7 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -27,6 +27,10 @@ config SPL_POWER_SUPPORT config SPL_SERIAL_SUPPORT default y
+config SUNXI_NO_SMP
- bool
- default n
# Note only one of these may be selected at a time! But hidden choices are # not supported by Kconfig config SUNXI_GEN_SUN4I @@ -50,12 +54,14 @@ choice config MACH_SUN4I bool "sun4i (Allwinner A10)" select CPU_V7
- select SUNXI_NO_SMP select SUNXI_GEN_SUN4I select SUPPORT_SPL
config MACH_SUN5I bool "sun5i (Allwinner A13)" select CPU_V7
- select SUNXI_NO_SMP select SUNXI_GEN_SUN4I select SUPPORT_SPL
-- 2.8.2
-- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe@googlegroups.com. For more options, visit https://groups.google.com/d/optout.

On 13/01/17 08:09, Vishnu Patekar wrote: Hi Vishnu,
Even for the single core cortex-a7, SMP bit should be set before enabling MMU and cache.
Reference: Cortex A7 r0p5 TRM. section 4.3.31.
Ah, good point, thanks for the heads up. I was misled by the SMP name when answering Icenowy. So it's about coherency in general and we need the bit for TLBs and caches to work as well. Let me check what that means for the other SoCs and whether we need to rename the config symbol then.
Cheers, Andre.
On Fri, Jan 13, 2017 at 12:41 PM, Icenowy Zheng icenowy@aosc.xyz wrote:
13.01.2017, 09:34, "Andre Przywara" andre.przywara@arm.com:
Instead of enumerating all SoC families that need that bit set, let's just express this more clearly: The SMP bits needs to be set on SMP capable ARMv7 CPUs. It's much easier to Kconfig to express it the other way round, so we use ! NO_SMP and ! ARM64.
How about single-core Cortex-A7?
Signed-off-by: Andre Przywara andre.przywara@arm.com
arch/arm/mach-sunxi/board.c | 5 +---- board/sunxi/Kconfig | 6 ++++++ 2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c index 58fbacb..5a63124 100644 --- a/arch/arm/mach-sunxi/board.c +++ b/arch/arm/mach-sunxi/board.c @@ -180,10 +180,7 @@ void s_init(void) /* No H3 BSP, boot0 seems to not modify SUNXI_SRAMC_BASE + 0x44 */ #endif
-#if defined CONFIG_MACH_SUN6I || \
- defined CONFIG_MACH_SUN7I || \
- defined CONFIG_MACH_SUN8I || \
- defined CONFIG_MACH_SUN9I
+#if !defined(CONFIG_SUNXI_NO_SMP) && !defined(CONFIG_ARM64) /* 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/board/sunxi/Kconfig b/board/sunxi/Kconfig index 37b4252..79b6fa7 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -27,6 +27,10 @@ config SPL_POWER_SUPPORT config SPL_SERIAL_SUPPORT default y
+config SUNXI_NO_SMP
- bool
- default n
# Note only one of these may be selected at a time! But hidden choices are # not supported by Kconfig config SUNXI_GEN_SUN4I @@ -50,12 +54,14 @@ choice config MACH_SUN4I bool "sun4i (Allwinner A10)" select CPU_V7
- select SUNXI_NO_SMP select SUNXI_GEN_SUN4I select SUPPORT_SPL
config MACH_SUN5I bool "sun5i (Allwinner A13)" select CPU_V7
- select SUNXI_NO_SMP select SUNXI_GEN_SUN4I select SUPPORT_SPL
-- 2.8.2
-- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe@googlegroups.com. For more options, visit https://groups.google.com/d/optout.

On Fri, Jan 13, 2017 at 08:28:07AM +0000, André Przywara wrote:
On 13/01/17 08:09, Vishnu Patekar wrote: Hi Vishnu,
Even for the single core cortex-a7, SMP bit should be set before enabling MMU and cache.
Reference: Cortex A7 r0p5 TRM. section 4.3.31.
Ah, good point, thanks for the heads up. I was misled by the SMP name when answering Icenowy. So it's about coherency in general and we need the bit for TLBs and caches to work as well. Let me check what that means for the other SoCs and whether we need to rename the config symbol then.
If we still needs it, x86 has a CONFIG_SMP symbol, that would be better to just leverage that.
Thanks! Maxime

Hi,
On 16/01/17 07:44, Maxime Ripard wrote:
On Fri, Jan 13, 2017 at 08:28:07AM +0000, André Przywara wrote:
On 13/01/17 08:09, Vishnu Patekar wrote: Hi Vishnu,
Even for the single core cortex-a7, SMP bit should be set before enabling MMU and cache.
Reference: Cortex A7 r0p5 TRM. section 4.3.31.
Ah, good point, thanks for the heads up. I was misled by the SMP name when answering Icenowy. So it's about coherency in general and we need the bit for TLBs and caches to work as well. Let me check what that means for the other SoCs and whether we need to rename the config symbol then.
So I checked the other ARMv7 Cortex TRMs, in contrast to the A7 TRM they explicitly speak of cache and TLB requests from other _processors_. So it should not be needed to use caches and the MMU on a uni-core implementation (which seem to be pretty rare with Cortex-A7s). But: my understanding is that it actually controls handling coherency request from outside of the processor core, which could be from a coherent agent on the bus as well, if I get this correctly. So I think it does not hurt to enable the bit on the V3s as well and could avoid potential problems. As this lines up with what the TRM says, we should turn it on as in the other cores.
Icenowy: did you see problems with setting this bit and turned it off for a reason or was that just because the bit is named "SMP"?
If we still needs it,
First: we definitely need this symbol, since it guards an implementation defined register and the Cortex-A53 does not define it. So we have to confine its use to the ARMv7 Cortex CPUs.
x86 has a CONFIG_SMP symbol, that would be better to just leverage that.
Sounds tempting, but this seems to be a generic symbol that enables SMP support _within_ U-Boot, so it allows multiple cores to execute U-Boot code. This is clearly not what we want. Defining it seems to enable architecture specific and generic code paths in U-Boot.
I can rename this symbol if that helps to avoid confusion, for instance to read CONFIG_SUNXI_NO_ACTLR_SMP or to CONFIG_CPU_IS_NOT_SMP or CONFIG_CPU_IS_UP.
Cheers, Andre.

On Sun, Jan 22, 2017 at 01:06:47AM +0000, André Przywara wrote:
If we still needs it,
First: we definitely need this symbol, since it guards an implementation defined register and the Cortex-A53 does not define it. So we have to confine its use to the ARMv7 Cortex CPUs.
Ack.
x86 has a CONFIG_SMP symbol, that would be better to just leverage that.
Sounds tempting, but this seems to be a generic symbol that enables SMP support _within_ U-Boot, so it allows multiple cores to execute U-Boot code. This is clearly not what we want. Defining it seems to enable architecture specific and generic code paths in U-Boot.
I can rename this symbol if that helps to avoid confusion, for instance to read CONFIG_SUNXI_NO_ACTLR_SMP or to CONFIG_CPU_IS_NOT_SMP or CONFIG_CPU_IS_UP.
There's nothing sunxi specific about it, the last one is better imho.
Thanks! Maxime

On 13/01/17 04:41, Icenowy Zheng wrote:
Hi,
13.01.2017, 09:34, "Andre Przywara" andre.przywara@arm.com:
Instead of enumerating all SoC families that need that bit set, let's just express this more clearly: The SMP bits needs to be set on SMP capable ARMv7 CPUs. It's much easier to Kconfig to express it the other way round, so we use ! NO_SMP and ! ARM64.
How about single-core Cortex-A7?
Well, I had the V3s in mind already, so it should be as easy as adding:
select SUNXI_NO_SMP
to your MACH_SUN8I_V3S stanza in board/sunxi/Kconfig, actually saving you to alter the actual code #ifdefs.
Or am I missing something?
Cheers, Andre.
Signed-off-by: Andre Przywara andre.przywara@arm.com
arch/arm/mach-sunxi/board.c | 5 +---- board/sunxi/Kconfig | 6 ++++++ 2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c index 58fbacb..5a63124 100644 --- a/arch/arm/mach-sunxi/board.c +++ b/arch/arm/mach-sunxi/board.c @@ -180,10 +180,7 @@ void s_init(void) /* No H3 BSP, boot0 seems to not modify SUNXI_SRAMC_BASE + 0x44 */ #endif
-#if defined CONFIG_MACH_SUN6I || \
- defined CONFIG_MACH_SUN7I || \
- defined CONFIG_MACH_SUN8I || \
- defined CONFIG_MACH_SUN9I
+#if !defined(CONFIG_SUNXI_NO_SMP) && !defined(CONFIG_ARM64) /* 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/board/sunxi/Kconfig b/board/sunxi/Kconfig index 37b4252..79b6fa7 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -27,6 +27,10 @@ config SPL_POWER_SUPPORT config SPL_SERIAL_SUPPORT default y
+config SUNXI_NO_SMP
- bool
- default n
# Note only one of these may be selected at a time! But hidden choices are # not supported by Kconfig config SUNXI_GEN_SUN4I @@ -50,12 +54,14 @@ choice config MACH_SUN4I bool "sun4i (Allwinner A10)" select CPU_V7
- select SUNXI_NO_SMP select SUNXI_GEN_SUN4I select SUPPORT_SPL
config MACH_SUN5I bool "sun5i (Allwinner A13)" select CPU_V7
- select SUNXI_NO_SMP select SUNXI_GEN_SUN4I select SUPPORT_SPL
-- 2.8.2

For some reason we were pretty conservative when defining the maximum SPL size for the Allwinner A80(sun9i) SoC. According to the manual the SRAM A1 is even 40KB, but the BROM probably still has the 32 KiB load limit. For the sake of simplicity, merge the SPL memory definitions for the A64 and A80 SoCs, since both SoC share the BROM/SRAM A1 memory layout. This helps to further simplify this in the next patch.
Signed-off-by: Andre Przywara andre.przywara@arm.com --- include/configs/sunxi-common.h | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index d58e5ba..04957b7 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -186,12 +186,9 @@ #define CONFIG_SPL_BOARD_LOAD_IMAGE #endif
-#if defined(CONFIG_MACH_SUN9I) -#define CONFIG_SPL_TEXT_BASE 0x10040 /* sram start+header */ -#define CONFIG_SPL_MAX_SIZE 0x5fc0 /* ? KiB on sun9i */ -#elif defined(CONFIG_MACH_SUN50I) +#if defined(CONFIG_MACH_SUN9I) || defined(CONFIG_MACH_SUN50I) #define CONFIG_SPL_TEXT_BASE 0x10040 /* sram start+header */ -#define CONFIG_SPL_MAX_SIZE 0x7fc0 /* 32 KiB on sun50i */ +#define CONFIG_SPL_MAX_SIZE 0x7fc0 /* 32 KiB on sun9/50i */ #else #define CONFIG_SPL_TEXT_BASE 0x40 /* sram start+header */ #define CONFIG_SPL_MAX_SIZE 0x5fc0 /* 24KB on sun4i/sun7i */

On Fri, Jan 13, 2017 at 01:29:55AM +0000, Andre Przywara wrote:
For some reason we were pretty conservative when defining the maximum SPL size for the Allwinner A80(sun9i) SoC. According to the manual the SRAM A1 is even 40KB, but the BROM probably still has the 32 KiB load limit. For the sake of simplicity, merge the SPL memory definitions for the A64 and A80 SoCs, since both SoC share the BROM/SRAM A1 memory layout. This helps to further simplify this in the next patch.
Signed-off-by: Andre Przywara andre.przywara@arm.com
Acked-by: Maxime Ripard maxime.ripard@free-electrons.com
Thanks, Maxime

Traditionally Allwinner SoCs have their boot ROM mapped just below 4GB, while the first SRAM region is mapped at address 0. With the extended physical memory support of the A80 this was changed, so the BROM is now at address 0 and the SRAM region starts right behind this at 64KB. This configuration seems to be called "high SRAM". Instead of enumerating the SoCs which have copied this configuration, let's call a spade a spade and introduce a Kconfig option for this setup. SoCs implementing this (A80, A64 and H5, so far), can then select this configuration. Simplify the config header definition on the way.
Signed-off-by: Andre Przywara andre.przywara@arm.com --- arch/arm/include/asm/arch-sunxi/spl.h | 2 +- board/sunxi/Kconfig | 6 ++++++ include/configs/sunxi-common.h | 19 +++++++------------ 3 files changed, 14 insertions(+), 13 deletions(-)
diff --git a/arch/arm/include/asm/arch-sunxi/spl.h b/arch/arm/include/asm/arch-sunxi/spl.h index 5d7ab55..831d0c0 100644 --- a/arch/arm/include/asm/arch-sunxi/spl.h +++ b/arch/arm/include/asm/arch-sunxi/spl.h @@ -12,7 +12,7 @@ #define SPL_SIGNATURE "SPL" /* marks "sunxi" SPL header */ #define SPL_HEADER_VERSION 1
-#if defined(CONFIG_MACH_SUN9I) || defined(CONFIG_MACH_SUN50I) +#ifdef CONFIG_SUNXI_HIGH_SRAM #define SPL_ADDR 0x10000 #else #define SPL_ADDR 0x0 diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index 79b6fa7..feb6e79 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -31,6 +31,10 @@ config SUNXI_NO_SMP bool default n
+config SUNXI_HIGH_SRAM + bool + default n + # Note only one of these may be selected at a time! But hidden choices are # not supported by Kconfig config SUNXI_GEN_SUN4I @@ -124,6 +128,7 @@ config MACH_SUN8I_H3 config MACH_SUN9I bool "sun9i (Allwinner A80)" select CPU_V7 + select SUNXI_HIGH_SRAM select SUNXI_GEN_SUN6I select SUPPORT_SPL
@@ -131,6 +136,7 @@ config MACH_SUN50I bool "sun50i (Allwinner A64)" select ARM64 select SUNXI_GEN_SUN6I + select SUNXI_HIGH_SRAM select SUPPORT_SPL
endchoice diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index 04957b7..5ec43f4 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -86,7 +86,7 @@
#define CONFIG_SPL_BSS_MAX_SIZE 0x00080000 /* 512 KiB */
-#if defined(CONFIG_MACH_SUN9I) || defined(CONFIG_MACH_SUN50I) +#ifdef CONFIG_SUNXI_HIGH_SRAM /* * The A80's A1 sram starts at 0x00010000 rather then at 0x00000000 and is * slightly bigger. Note that it is possible to map the first 32 KiB of the @@ -186,29 +186,24 @@ #define CONFIG_SPL_BOARD_LOAD_IMAGE #endif
-#if defined(CONFIG_MACH_SUN9I) || defined(CONFIG_MACH_SUN50I) +#ifdef CONFIG_SUNXI_HIGH_SRAM #define CONFIG_SPL_TEXT_BASE 0x10040 /* sram start+header */ -#define CONFIG_SPL_MAX_SIZE 0x7fc0 /* 32 KiB on sun9/50i */ +#define CONFIG_SPL_MAX_SIZE 0x7fc0 /* 32 KiB */ +#define LOW_LEVEL_SRAM_STACK 0x00018000 #else #define CONFIG_SPL_TEXT_BASE 0x40 /* sram start+header */ #define CONFIG_SPL_MAX_SIZE 0x5fc0 /* 24KB on sun4i/sun7i */ +#define LOW_LEVEL_SRAM_STACK 0x00008000 /* End of sram */ #endif
+#define CONFIG_SPL_STACK LOW_LEVEL_SRAM_STACK + #ifndef CONFIG_ARM64 #define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/armv7/sunxi/u-boot-spl.lds" #endif
#define CONFIG_SPL_PAD_TO 32768 /* decimal for 'dd' */
-#if defined(CONFIG_MACH_SUN9I) || defined(CONFIG_MACH_SUN50I) -/* FIXME: 40 KiB instead of 32 KiB ? */ -#define LOW_LEVEL_SRAM_STACK 0x00018000 -#define CONFIG_SPL_STACK LOW_LEVEL_SRAM_STACK -#else -/* end of 32 KiB in sram */ -#define LOW_LEVEL_SRAM_STACK 0x00008000 /* End of sram */ -#define CONFIG_SPL_STACK LOW_LEVEL_SRAM_STACK -#endif
/* I2C */ #if defined CONFIG_AXP152_POWER || defined CONFIG_AXP209_POWER || \

On Fri, Jan 13, 2017 at 01:29:56AM +0000, Andre Przywara wrote:
Traditionally Allwinner SoCs have their boot ROM mapped just below 4GB, while the first SRAM region is mapped at address 0. With the extended physical memory support of the A80 this was changed, so the BROM is now at address 0 and the SRAM region starts right behind this at 64KB. This configuration seems to be called "high SRAM". Instead of enumerating the SoCs which have copied this configuration, let's call a spade a spade and introduce a Kconfig option for this setup. SoCs implementing this (A80, A64 and H5, so far), can then select this configuration. Simplify the config header definition on the way.
Signed-off-by: Andre Przywara andre.przywara@arm.com
Acked-by: Maxime Ripard maxime.ripard@free-electrons.com
Thanks, Maxime

Every armv8 board needs the memory map, so change the #ifdef to ARM64 to avoid enumerating every single board or SoC.
Signed-off-by: Andre Przywara andre.przywara@arm.com --- arch/arm/mach-sunxi/board.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c index 5a63124..5f9f3b8 100644 --- a/arch/arm/mach-sunxi/board.c +++ b/arch/arm/mach-sunxi/board.c @@ -40,7 +40,7 @@ struct fel_stash {
struct fel_stash fel_stash __attribute__((section(".data")));
-#ifdef CONFIG_MACH_SUN50I +#ifdef CONFIG_ARM64 #include <asm/armv8/mmu.h>
static struct mm_region sunxi_mem_map[] = {

On Fri, Jan 13, 2017 at 01:29:57AM +0000, Andre Przywara wrote:
Every armv8 board needs the memory map, so change the #ifdef to ARM64 to avoid enumerating every single board or SoC.
Signed-off-by: Andre Przywara andre.przywara@arm.com
Acked-by: Maxime Ripard maxime.ripard@free-electrons.com
Thanks, Maxime

Addresses passed on to readl and writel are expected to be of the same size as a pointer. Change the parameter types of sunxi_spi0_read_data() to make the compiler happy and allow a warning-free aarch64 compile.
Signed-off-by: Andre Przywara andre.przywara@arm.com --- drivers/mtd/spi/sunxi_spi_spl.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/mtd/spi/sunxi_spi_spl.c b/drivers/mtd/spi/sunxi_spi_spl.c index a24c115..852abd4 100644 --- a/drivers/mtd/spi/sunxi_spi_spl.c +++ b/drivers/mtd/spi/sunxi_spi_spl.c @@ -185,14 +185,14 @@ static void spi0_deinit(void) #define SPI_READ_MAX_SIZE 60 /* FIFO size, minus 4 bytes of the header */
static void sunxi_spi0_read_data(u8 *buf, u32 addr, u32 bufsize, - u32 spi_ctl_reg, - u32 spi_ctl_xch_bitmask, - u32 spi_fifo_reg, - u32 spi_tx_reg, - u32 spi_rx_reg, - u32 spi_bc_reg, - u32 spi_tc_reg, - u32 spi_bcc_reg) + ulong spi_ctl_reg, + ulong spi_ctl_xch_bitmask, + ulong spi_fifo_reg, + ulong spi_tx_reg, + ulong spi_rx_reg, + ulong spi_bc_reg, + ulong spi_tc_reg, + ulong spi_bcc_reg) { writel(4 + bufsize, spi_bc_reg); /* Burst counter (total bytes) */ writel(4, spi_tc_reg); /* Transfer counter (bytes to send) */

On Fri, Jan 13, 2017 at 01:29:58AM +0000, Andre Przywara wrote:
Addresses passed on to readl and writel are expected to be of the same size as a pointer. Change the parameter types of sunxi_spi0_read_data() to make the compiler happy and allow a warning-free aarch64 compile.
Signed-off-by: Andre Przywara andre.przywara@arm.com
How about using intptr_t and uintptr_t from include/compiler.h? It will make it clearer that these parameters should be able to hold a pointer.
drivers/mtd/spi/sunxi_spi_spl.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/mtd/spi/sunxi_spi_spl.c b/drivers/mtd/spi/sunxi_spi_spl.c index a24c115..852abd4 100644 --- a/drivers/mtd/spi/sunxi_spi_spl.c +++ b/drivers/mtd/spi/sunxi_spi_spl.c @@ -185,14 +185,14 @@ static void spi0_deinit(void) #define SPI_READ_MAX_SIZE 60 /* FIFO size, minus 4 bytes of the header */
static void sunxi_spi0_read_data(u8 *buf, u32 addr, u32 bufsize,
u32 spi_ctl_reg,
u32 spi_ctl_xch_bitmask,
u32 spi_fifo_reg,
u32 spi_tx_reg,
u32 spi_rx_reg,
u32 spi_bc_reg,
u32 spi_tc_reg,
u32 spi_bcc_reg)
ulong spi_ctl_reg,
ulong spi_ctl_xch_bitmask,
ulong spi_fifo_reg,
ulong spi_tx_reg,
ulong spi_rx_reg,
ulong spi_bc_reg,
ulong spi_tc_reg,
ulong spi_bcc_reg)
{ writel(4 + bufsize, spi_bc_reg); /* Burst counter (total bytes) */ writel(4, spi_tc_reg); /* Transfer counter (bytes to send) */ --

On 15 January 2017 at 05:17, Rask Ingemann Lambertsen rask@formelder.dk wrote:
On Fri, Jan 13, 2017 at 01:29:58AM +0000, Andre Przywara wrote:
Addresses passed on to readl and writel are expected to be of the same size as a pointer. Change the parameter types of sunxi_spi0_read_data() to make the compiler happy and allow a warning-free aarch64 compile.
Signed-off-by: Andre Przywara andre.przywara@arm.com
How about using intptr_t and uintptr_t from include/compiler.h? It will make it clearer that these parameters should be able to hold a pointer.
drivers/mtd/spi/sunxi_spi_spl.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/mtd/spi/sunxi_spi_spl.c b/drivers/mtd/spi/sunxi_spi_spl.c index a24c115..852abd4 100644 --- a/drivers/mtd/spi/sunxi_spi_spl.c +++ b/drivers/mtd/spi/sunxi_spi_spl.c @@ -185,14 +185,14 @@ static void spi0_deinit(void) #define SPI_READ_MAX_SIZE 60 /* FIFO size, minus 4 bytes of the header */
static void sunxi_spi0_read_data(u8 *buf, u32 addr, u32 bufsize,
u32 spi_ctl_reg,
u32 spi_ctl_xch_bitmask,
u32 spi_fifo_reg,
u32 spi_tx_reg,
u32 spi_rx_reg,
u32 spi_bc_reg,
u32 spi_tc_reg,
u32 spi_bcc_reg)
ulong spi_ctl_reg,
ulong spi_ctl_xch_bitmask,
ulong spi_fifo_reg,
ulong spi_tx_reg,
ulong spi_rx_reg,
ulong spi_bc_reg,
ulong spi_tc_reg,
ulong spi_bcc_reg)
{ writel(4 + bufsize, spi_bc_reg); /* Burst counter (total bytes) */ writel(4, spi_tc_reg); /* Transfer counter (bytes to send) */
We normally use ulong for addresses in U-Boot.
Reviewed-by: Simon Glass sjg@chromium.org

The DRAM controller in the Allwinner H5 SoC is again very similar to the one in the H3 and A64. Based on the existing socid parameter, add support for this controller by reusing the bulk of the code and only deviating where needed. Also add the delay line parameters taken from the boot0 and libdram disassembly. Register setup differences between H5 and H3 are courtesy of Jens Kuske.
Signed-off-by: Andre Przywara andre.przywara@arm.com --- arch/arm/include/asm/arch-sunxi/cpu.h | 1 + arch/arm/mach-sunxi/dram_sun8i_h3.c | 97 +++++++++++++++++++++++++++++------ 2 files changed, 82 insertions(+), 16 deletions(-)
diff --git a/arch/arm/include/asm/arch-sunxi/cpu.h b/arch/arm/include/asm/arch-sunxi/cpu.h index 6f96a97..e8e670e 100644 --- a/arch/arm/include/asm/arch-sunxi/cpu.h +++ b/arch/arm/include/asm/arch-sunxi/cpu.h @@ -15,5 +15,6 @@
#define SOCID_A64 0x1689 #define SOCID_H3 0x1680 +#define SOCID_H5 0x1718
#endif /* _SUNXI_CPU_H */ diff --git a/arch/arm/mach-sunxi/dram_sun8i_h3.c b/arch/arm/mach-sunxi/dram_sun8i_h3.c index 9f7cc7f..7d3b740 100644 --- a/arch/arm/mach-sunxi/dram_sun8i_h3.c +++ b/arch/arm/mach-sunxi/dram_sun8i_h3.c @@ -177,6 +177,34 @@ static void mctl_set_master_priority_a64(void) writel(0x81000004, &mctl_com->mdfs_bwlr[2]); }
+static void mctl_set_master_priority_h5(void) +{ + struct sunxi_mctl_com_reg * const mctl_com = + (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE; + + /* enable bandwidth limit windows and set windows size 1us */ + writel(399, &mctl_com->tmr); + writel((1 << 16), &mctl_com->bwcr); + + /* set cpu high priority */ + writel(0x00000001, &mctl_com->mapr); + + /* Port 2 is reserved per Allwinner's linux-3.10 source, yet + * they initialise it */ + MBUS_CONF( CPU, true, HIGHEST, 0, 300, 260, 150); + MBUS_CONF( GPU, true, HIGHEST, 0, 600, 400, 200); + MBUS_CONF(UNUSED, true, HIGHEST, 0, 512, 256, 96); + MBUS_CONF( DMA, true, HIGHEST, 0, 256, 128, 32); + MBUS_CONF( VE, true, HIGHEST, 0, 1900, 1500, 1000); + MBUS_CONF( CSI, true, HIGHEST, 0, 150, 120, 100); + MBUS_CONF( NAND, true, HIGH, 0, 256, 128, 64); + MBUS_CONF( SS, true, HIGHEST, 0, 256, 128, 64); + MBUS_CONF( TS, true, HIGHEST, 0, 256, 128, 64); + MBUS_CONF( DI, true, HIGH, 0, 1024, 256, 64); + MBUS_CONF( DE, true, HIGHEST, 3, 3400, 2400, 1024); + MBUS_CONF(DE_CFD, true, HIGHEST, 0, 600, 400, 200); +} + static void mctl_set_master_priority(uint16_t socid) { switch (socid) { @@ -186,6 +214,9 @@ static void mctl_set_master_priority(uint16_t socid) case SOCID_A64: mctl_set_master_priority_a64(); return; + case SOCID_H5: + mctl_set_master_priority_h5(); + return; } }
@@ -256,7 +287,7 @@ static void mctl_set_timing_params(uint16_t socid, struct dram_para *para)
/* set two rank timing */ clrsetbits_le32(&mctl_ctl->dramtmg[8], (0xff << 8) | (0xff << 0), - (0x66 << 8) | (0x10 << 0)); + ((socid == SOCID_H5 ? 0x33 : 0x66) << 8) | (0x10 << 0));
/* set PHY interface timing, write latency and read latency configure */ writel((0x2 << 24) | (t_rdata_en << 16) | (0x1 << 8) | @@ -391,7 +422,7 @@ static void mctl_sys_init(uint16_t socid, struct dram_para *para) CCM_DRAMCLK_CFG_DIV(1) | CCM_DRAMCLK_CFG_SRC_PLL11 | CCM_DRAMCLK_CFG_UPD); - } else if (socid == SOCID_H3) { + } else if (socid == SOCID_H3 || socid == SOCID_H5) { clock_set_pll5(CONFIG_DRAM_CLK * 2 * 1000000, false); clrsetbits_le32(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_DIV_MASK | @@ -410,7 +441,7 @@ static void mctl_sys_init(uint16_t socid, struct dram_para *para) setbits_le32(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_RST); udelay(10);
- writel(0xc00e, &mctl_ctl->clken); + writel(socid == SOCID_H5 ? 0x8000 : 0xc00e, &mctl_ctl->clken); udelay(500); }
@@ -434,7 +465,10 @@ static int mctl_channel_init(uint16_t socid, struct dram_para *para)
/* setting VTC, default disable all VT */ clrbits_le32(&mctl_ctl->pgcr[0], (1 << 30) | 0x3f); - clrsetbits_le32(&mctl_ctl->pgcr[1], 1 << 24, 1 << 26); + if (socid == SOCID_H5) + setbits_le32(&mctl_ctl->pgcr[1], (1 << 24) | (1 << 26)); + else + clrsetbits_le32(&mctl_ctl->pgcr[1], 1 << 24, 1 << 26);
/* increase DFI_PHY_UPD clock */ writel(PROTECT_MAGIC, &mctl_com->protect); @@ -444,15 +478,22 @@ static int mctl_channel_init(uint16_t socid, struct dram_para *para) udelay(100);
/* set dramc odt */ - for (i = 0; i < 4; i++) - clrsetbits_le32(&mctl_ctl->dx[i].gcr, (0x3 << 4) | - (0x1 << 1) | (0x3 << 2) | (0x3 << 12) | - (0x3 << 14), - IS_ENABLED(CONFIG_DRAM_ODT_EN) ? - DX_GCR_ODT_DYNAMIC : DX_GCR_ODT_OFF); + for (i = 0; i < 4; i++) { + u32 clearmask = (0x3 << 4) | (0x1 << 1) | (0x3 << 2) | + (0x3 << 12) | (0x3 << 14); + u32 setmask = IS_ENABLED(CONFIG_DRAM_ODT_EN) ? + DX_GCR_ODT_DYNAMIC : DX_GCR_ODT_OFF; + + if (socid == SOCID_H5) { + clearmask |= 0x2 << 8; + setmask |= 0x4 << 8; + } + clrsetbits_le32(&mctl_ctl->dx[i].gcr, clearmask, setmask); + }
/* AC PDR should always ON */ - setbits_le32(&mctl_ctl->aciocr, 0x1 << 1); + clrsetbits_le32(&mctl_ctl->aciocr, socid == SOCID_H5 ? (0x1 << 11) : 0, + 0x1 << 1);
/* set DQS auto gating PD mode */ setbits_le32(&mctl_ctl->pgcr[2], 0x3 << 6); @@ -464,7 +505,7 @@ static int mctl_channel_init(uint16_t socid, struct dram_para *para) /* dphy & aphy phase select 270 degree */ clrsetbits_le32(&mctl_ctl->pgcr[2], (0x3 << 10) | (0x3 << 8), (0x1 << 10) | (0x2 << 8)); - } else if (socid == SOCID_A64) { + } else if (socid == SOCID_A64 || socid == SOCID_H5) { /* dphy & aphy phase select ? */ clrsetbits_le32(&mctl_ctl->pgcr[2], (0x3 << 10) | (0x3 << 8), (0x0 << 10) | (0x3 << 8)); @@ -488,11 +529,12 @@ static int mctl_channel_init(uint16_t socid, struct dram_para *para)
mctl_phy_init(PIR_PLLINIT | PIR_DCAL | PIR_PHYRST | PIR_DRAMRST | PIR_DRAMINIT | PIR_QSGATE); - } else if (socid == SOCID_A64) { + } else if (socid == SOCID_A64 || socid == SOCID_H5) { clrsetbits_le32(&mctl_ctl->zqcr, 0xffffff, CONFIG_DRAM_ZQ);
mctl_phy_init(PIR_ZCAL | PIR_PLLINIT | PIR_DCAL | PIR_PHYRST | PIR_DRAMRST | PIR_DRAMINIT | PIR_QSGATE); + /* no PIR_QSGATE for H5 ???? */ }
/* detect ranks and bus width */ @@ -533,7 +575,7 @@ static int mctl_channel_init(uint16_t socid, struct dram_para *para) /* set PGCR3, CKE polarity */ if (socid == SOCID_H3) writel(0x00aa0060, &mctl_ctl->pgcr[3]); - else if (socid == SOCID_A64) + else if (socid == SOCID_A64 || socid == SOCID_H5) writel(0xc0aa0060, &mctl_ctl->pgcr[3]);
/* power down zq calibration module for power save */ @@ -604,6 +646,22 @@ static void mctl_auto_detect_dram_size(struct dram_para *para) 3, 4, 0, 3, 4, 1, 4, 0, \ 1, 1, 0, 1, 13, 5, 4 }
+#define SUN8I_H5_DX_READ_DELAYS \ + {{ 14, 15, 17, 17, 17, 17, 17, 18, 17, 3, 3 }, \ + { 21, 21, 12, 22, 21, 21, 21, 21, 21, 3, 3 }, \ + { 16, 19, 19, 17, 22, 22, 21, 22, 19, 3, 3 }, \ + { 21, 21, 22, 22, 20, 21, 19, 19, 19, 3, 3 }} +#define SUN8I_H5_DX_WRITE_DELAYS \ + {{ 1, 2, 3, 4, 3, 4, 4, 4, 6, 6, 6 }, \ + { 6, 6, 6, 5, 5, 5, 5, 5, 6, 6, 6 }, \ + { 0, 2, 4, 2, 6, 5, 5, 5, 6, 6, 6 }, \ + { 3, 3, 3, 2, 2, 1, 1, 1, 4, 4, 4 }} +#define SUN8I_H5_AC_DELAYS \ + { 0, 0, 5, 5, 0, 0, 0, 0, \ + 0, 0, 0, 0, 3, 3, 3, 3, \ + 3, 3, 3, 3, 3, 3, 3, 3, \ + 3, 3, 3, 3, 2, 0, 0 } + unsigned long sunxi_dram_init(void) { struct sunxi_mctl_com_reg * const mctl_com = @@ -625,6 +683,10 @@ unsigned long sunxi_dram_init(void) .dx_read_delays = SUN50I_A64_DX_READ_DELAYS, .dx_write_delays = SUN50I_A64_DX_WRITE_DELAYS, .ac_delays = SUN50I_A64_AC_DELAYS, +#elif defined(CONFIG_MACH_SUN50I_H5) + .dx_read_delays = SUN8I_H5_DX_READ_DELAYS, + .dx_write_delays = SUN8I_H5_DX_WRITE_DELAYS, + .ac_delays = SUN8I_H5_AC_DELAYS, #endif }; /* @@ -636,6 +698,8 @@ unsigned long sunxi_dram_init(void) uint16_t socid = SOCID_H3; #elif defined(CONFIG_MACH_SUN50I) uint16_t socid = SOCID_A64; +#elif defined(CONFIG_MACH_SUN50I_H5) + uint16_t socid = SOCID_H5; #endif
mctl_sys_init(socid, ¶); @@ -652,8 +716,9 @@ unsigned long sunxi_dram_init(void) if (socid == SOCID_H3) writel(0x0c000400, &mctl_ctl->odtcfg);
- if (socid == SOCID_A64) { - setbits_le32(&mctl_ctl->vtfcr, 2 << 8); + if (socid == SOCID_A64 || socid == SOCID_H5) { + setbits_le32(&mctl_ctl->vtfcr, + (socid == SOCID_H5 ? 3 : 2) << 8); clrbits_le32(&mctl_ctl->pgcr[2], (1 << 13)); }

On Fri, Jan 13, 2017 at 01:29:59AM +0000, Andre Przywara wrote:
The DRAM controller in the Allwinner H5 SoC is again very similar to the one in the H3 and A64. Based on the existing socid parameter, add support for this controller by reusing the bulk of the code and only deviating where needed. Also add the delay line parameters taken from the boot0 and libdram disassembly. Register setup differences between H5 and H3 are courtesy of Jens Kuske.
Signed-off-by: Andre Przywara andre.przywara@arm.com
There's a number of issues with checkpatch here, please fix them.
And there's way too many magics here, again...
Maxime

The Allwinner H5 is very close to the H3 SoC, but has ARMv8 cores. To allow sharing the clocks, GPIO and driver code easily, create an architecture agnostic MACH_SUN8I_H3_H5 Kconfig symbol. Rename the existing symbol to MACH_SUN8I_H3_H5 where code is shared and let it be selected by a new shared Kconfig option.
Signed-off-by: Andre Przywara andre.przywara@arm.com --- arch/arm/include/asm/arch-sunxi/clock_sun6i.h | 4 ++-- arch/arm/include/asm/arch-sunxi/cpu_sun4i.h | 4 ++-- arch/arm/include/asm/arch-sunxi/dram.h | 2 +- arch/arm/mach-sunxi/Makefile | 2 +- arch/arm/mach-sunxi/board.c | 11 +++++++---- arch/arm/mach-sunxi/clock_sun6i.c | 6 +++--- arch/arm/mach-sunxi/usb_phy.c | 4 ++-- board/sunxi/Kconfig | 14 +++++++++----- drivers/mtd/spi/Kconfig | 2 +- drivers/net/sun8i_emac.c | 2 +- drivers/power/Kconfig | 4 ++-- drivers/usb/host/ehci-sunxi.c | 2 +- 12 files changed, 32 insertions(+), 25 deletions(-)
diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h index 3f87672..7a56989 100644 --- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h +++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h @@ -242,7 +242,7 @@ struct sunxi_ccm_reg { /* ahb_gate0 offsets */ #define AHB_GATE_OFFSET_USB_OHCI1 30 #define AHB_GATE_OFFSET_USB_OHCI0 29 -#ifdef CONFIG_MACH_SUN8I_H3 +#ifdef CONFIG_MACH_SUN8I_H3_H5 /* * These are EHCI1 - EHCI3 in the datasheet (EHCI0 is for the OTG) we call * them 0 - 2 like they were called on older SoCs. @@ -293,7 +293,7 @@ struct sunxi_ccm_reg { #define CCM_USB_CTRL_PHY1_CLK (0x1 << 9) #define CCM_USB_CTRL_PHY2_CLK (0x1 << 10) #define CCM_USB_CTRL_PHY3_CLK (0x1 << 11) -#ifdef CONFIG_MACH_SUN8I_H3 +#ifdef CONFIG_MACH_SUN8I_H3_H5 /* * These are OHCI1 - OHCI3 in the datasheet (OHCI0 is for the OTG) we call * them 0 - 2 like they were called on older SoCs. diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h index 3c85222..cfe2cb3 100644 --- a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h +++ b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h @@ -56,7 +56,7 @@ #define SUNXI_USB2_BASE 0x01c1c000 #endif #ifdef CONFIG_SUNXI_GEN_SUN6I -#if defined(CONFIG_MACH_SUN8I_H3) || defined(CONFIG_MACH_SUN50I) +#if defined(CONFIG_MACH_SUN8I_H3_H5) || defined(CONFIG_MACH_SUN50I) #define SUNXI_USBPHY_BASE 0x01c19000 #define SUNXI_USB0_BASE 0x01c1a000 #define SUNXI_USB1_BASE 0x01c1b000 @@ -94,7 +94,7 @@ #define SUNXI_KEYPAD_BASE 0x01c23000 #define SUNXI_TZPC_BASE 0x01c23400
-#if defined(CONFIG_MACH_SUN8I_A83T) || defined(CONFIG_MACH_SUN8I_H3) || \ +#if defined(CONFIG_MACH_SUN8I_A83T) || defined(CONFIG_MACH_SUN8I_H3_H5) || \ defined(CONFIG_MACH_SUN50I) /* SID address space starts at 0x01c1400, but e-fuse is at offset 0x200 */ #define SUNXI_SIDC_BASE 0x01c14000 diff --git a/arch/arm/include/asm/arch-sunxi/dram.h b/arch/arm/include/asm/arch-sunxi/dram.h index 53e6d47..cb41bb1 100644 --- a/arch/arm/include/asm/arch-sunxi/dram.h +++ b/arch/arm/include/asm/arch-sunxi/dram.h @@ -24,7 +24,7 @@ #include <asm/arch/dram_sun8i_a33.h> #elif defined(CONFIG_MACH_SUN8I_A83T) #include <asm/arch/dram_sun8i_a83t.h> -#elif defined(CONFIG_MACH_SUN8I_H3) || defined(CONFIG_MACH_SUN50I) +#elif defined(CONFIG_MACH_SUN8I_H3_H5) || defined(CONFIG_MACH_SUN50I) #include <asm/arch/dram_sun8i_h3.h> #elif defined(CONFIG_MACH_SUN9I) #include <asm/arch/dram_sun9i.h> diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile index 7daba11..2d7f87f 100644 --- a/arch/arm/mach-sunxi/Makefile +++ b/arch/arm/mach-sunxi/Makefile @@ -48,7 +48,7 @@ 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-$(CONFIG_MACH_SUN8I_A83T) += dram_sun8i_a83t.o -obj-$(CONFIG_MACH_SUN8I_H3) += dram_sun8i_h3.o +obj-$(CONFIG_MACH_SUN8I_H3_H5) += dram_sun8i_h3.o obj-$(CONFIG_MACH_SUN9I) += dram_sun9i.o obj-$(CONFIG_MACH_SUN50I) += dram_sun8i_h3.o endif diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c index 5f9f3b8..35323e6 100644 --- a/arch/arm/mach-sunxi/board.c +++ b/arch/arm/mach-sunxi/board.c @@ -98,7 +98,7 @@ static int gpio_init(void) sunxi_gpio_set_cfgpin(SUNXI_GPB(0), SUN8I_A33_GPB_UART0); sunxi_gpio_set_cfgpin(SUNXI_GPB(1), SUN8I_A33_GPB_UART0); sunxi_gpio_set_pull(SUNXI_GPB(1), SUNXI_GPIO_PULL_UP); -#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN8I_H3) +#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN8I_H3_H5) sunxi_gpio_set_cfgpin(SUNXI_GPA(4), SUN8I_H3_GPA_UART0); sunxi_gpio_set_cfgpin(SUNXI_GPA(5), SUN8I_H3_GPA_UART0); sunxi_gpio_set_pull(SUNXI_GPA(5), SUNXI_GPIO_PULL_UP); @@ -145,6 +145,10 @@ static int spl_board_load_image(struct spl_image_info *spl_image, SPL_LOAD_IMAGE_METHOD("FEL", 0, BOOT_DEVICE_BOARD, spl_board_load_image); #endif
+__weak void tzpc_init(void) +{ +} + void s_init(void) { /* @@ -188,10 +192,9 @@ void s_init(void) "mcr p15, 0, r0, c1, c0, 1\n" ::: "r0"); #endif -#if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I_H3 - /* Enable non-secure access to some peripherals */ + + /* Enable non-secure access to some peripherals (only if needed) */ tzpc_init(); -#endif
clock_init(); timer_init(); diff --git a/arch/arm/mach-sunxi/clock_sun6i.c b/arch/arm/mach-sunxi/clock_sun6i.c index d123b3a..f9c006f 100644 --- a/arch/arm/mach-sunxi/clock_sun6i.c +++ b/arch/arm/mach-sunxi/clock_sun6i.c @@ -22,7 +22,7 @@ void clock_init_safe(void) struct sunxi_ccm_reg * const ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
-#if !defined(CONFIG_MACH_SUN8I_H3) && !defined(CONFIG_MACH_SUN50I) +#if !defined(CONFIG_MACH_SUN8I_H3_H5) && !defined(CONFIG_MACH_SUN50I) struct sunxi_prcm_reg * const prcm = (struct sunxi_prcm_reg *)SUNXI_PRCM_BASE;
@@ -51,7 +51,7 @@ void clock_init_safe(void)
void clock_init_sec(void) { -#ifdef CONFIG_MACH_SUN8I_H3 +#ifdef CONFIG_MACH_SUN8I_H3_H5 struct sunxi_ccm_reg * const ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
@@ -152,7 +152,7 @@ void clock_set_pll5(unsigned int clk, bool sigma_delta_enable) const int max_n = 32; int k = 1, m = 2;
-#ifdef CONFIG_MACH_SUN8I_H3 +#ifdef CONFIG_MACH_SUN8I_H3_H5 clrsetbits_le32(&ccm->pll5_tuning_cfg, CCM_PLL5_TUN_LOCK_TIME_MASK | CCM_PLL5_TUN_INIT_FREQ_MASK, CCM_PLL5_TUN_LOCK_TIME(2) | CCM_PLL5_TUN_INIT_FREQ(16)); diff --git a/arch/arm/mach-sunxi/usb_phy.c b/arch/arm/mach-sunxi/usb_phy.c index 278587b..e242c05 100644 --- a/arch/arm/mach-sunxi/usb_phy.c +++ b/arch/arm/mach-sunxi/usb_phy.c @@ -146,10 +146,10 @@ __maybe_unused static void usb_phy_write(struct sunxi_usb_phy *phy, int addr, } }
-#if defined(CONFIG_MACH_SUN8I_H3) || defined(CONFIG_MACH_SUN50I) +#if defined(CONFIG_MACH_SUN8I_H3_H5) || defined(CONFIG_MACH_SUN50I) static void sunxi_usb_phy_config(struct sunxi_usb_phy *phy) { -#if defined CONFIG_MACH_SUN8I_H3 +#if defined CONFIG_MACH_SUN8I_H3_H5 if (phy->id == 0) clrbits_le32(SUNXI_USBPHY_BASE + REG_PHY_UNK_H3, 0x01); #endif diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index feb6e79..2f3a847 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -51,6 +51,11 @@ config SUNXI_GEN_SUN6I watchdog, etc.
+config MACH_SUN8I_H3_H5 + bool + select SUNXI_GEN_SUN6I + select SUPPORT_SPL + choice prompt "Sunxi SoC Variant" optional @@ -121,8 +126,7 @@ config MACH_SUN8I_H3 select CPU_V7_HAS_NONSEC select CPU_V7_HAS_VIRT select ARCH_SUPPORT_PSCI - select SUNXI_GEN_SUN6I - select SUPPORT_SPL + select MACH_SUN8I_H3_H5 select ARMV7_BOOT_SEC_DEFAULT if OLD_SUNXI_KERNEL_COMPAT
config MACH_SUN9I @@ -144,7 +148,7 @@ endchoice # The sun8i SoCs share a lot, this helps to avoid a lot of "if A23 || A33" config MACH_SUN8I bool - default y if MACH_SUN8I_A23 || MACH_SUN8I_A33 || MACH_SUN8I_H3 || MACH_SUN8I_A83T + default y if MACH_SUN8I_A23 || MACH_SUN8I_A33 || MACH_SUN8I_H3_H5 || MACH_SUN8I_A83T
config RESERVE_ALLWINNER_BOOT0_HEADER bool "reserve space for Allwinner boot0 header" @@ -332,7 +336,7 @@ config OLD_SUNXI_KERNEL_COMPAT
config MMC0_CD_PIN string "Card detect pin for mmc0" - default "PF6" if MACH_SUN8I_A83T || MACH_SUN8I_H3 || MACH_SUN50I + default "PF6" if MACH_SUN8I_A83T || MACH_SUN8I_H3_H5 || MACH_SUN50I default "" ---help--- Set the card detect pin for mmc0, leave empty to not use cd. This @@ -497,7 +501,7 @@ config AXP_GPIO
config VIDEO bool "Enable graphical uboot console on HDMI, LCD or VGA" - depends on !MACH_SUN8I_A83T && !MACH_SUN8I_H3 && !MACH_SUN9I && !MACH_SUN50I + depends on !MACH_SUN8I_A83T && !MACH_SUN8I_H3_H5 && !MACH_SUN9I && !MACH_SUN50I default y ---help--- Say Y here to add support for using a cfb console on the HDMI, LCD diff --git a/drivers/mtd/spi/Kconfig b/drivers/mtd/spi/Kconfig index 1f23c8e..36c1a25 100644 --- a/drivers/mtd/spi/Kconfig +++ b/drivers/mtd/spi/Kconfig @@ -132,7 +132,7 @@ if SPL
config SPL_SPI_SUNXI bool "Support for SPI Flash on Allwinner SoCs in SPL" - depends on MACH_SUN4I || MACH_SUN5I || MACH_SUN7I || MACH_SUN8I_H3 || MACH_SUN50I + depends on MACH_SUN4I || MACH_SUN5I || MACH_SUN7I || MACH_SUN8I_H3_H5 || MACH_SUN50I ---help--- Enable support for SPI Flash. This option allows SPL to read from sunxi SPI Flash. It uses the same method as the boot ROM, so does diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c index abd9cc8..fa008fc 100644 --- a/drivers/net/sun8i_emac.c +++ b/drivers/net/sun8i_emac.c @@ -62,7 +62,7 @@
#define AHB_GATE_OFFSET_EPHY 0
-#if defined(CONFIG_MACH_SUN8I_H3) +#if defined(CONFIG_MACH_SUN8I_H3_H5) #define SUN8I_GPD8_GMAC 2 #else #define SUN8I_GPD8_GMAC 4 diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index f2c5629..82a52a8 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -12,7 +12,7 @@ choice default AXP209_POWER if MACH_SUN4I || MACH_SUN5I || MACH_SUN7I default AXP221_POWER if MACH_SUN6I || MACH_SUN8I_A23 || MACH_SUN8I_A33 default AXP818_POWER if MACH_SUN8I_A83T - default SUNXI_NO_PMIC if MACH_SUN8I_H3 || MACH_SUN50I + default SUNXI_NO_PMIC if MACH_SUN8I_H3_H5 || MACH_SUN50I
config SUNXI_NO_PMIC bool "board without a pmic" @@ -60,7 +60,7 @@ config AXP818_POWER
config SY8106A_POWER bool "SY8106A pmic support" - depends on MACH_SUN8I_H3 + depends on MACH_SUN8I_H3_H5 ---help--- Select this to enable support for the SY8106A pmic found on some H3 boards. diff --git a/drivers/usb/host/ehci-sunxi.c b/drivers/usb/host/ehci-sunxi.c index 5bb97ff..575af3c 100644 --- a/drivers/usb/host/ehci-sunxi.c +++ b/drivers/usb/host/ehci-sunxi.c @@ -45,7 +45,7 @@ static int ehci_usb_probe(struct udevice *dev) * clocks resp. phys. */ priv->ahb_gate_mask = 1 << AHB_GATE_OFFSET_USB_EHCI0; -#if defined(CONFIG_MACH_SUN8I_H3) || defined(CONFIG_MACH_SUN50I) +#if defined(CONFIG_MACH_SUN8I_H3_H5) || defined(CONFIG_MACH_SUN50I) extra_ahb_gate_mask = 1 << AHB_GATE_OFFSET_USB_OHCI0; #endif priv->phy_index = ((uintptr_t)hccr - SUNXI_USB1_BASE) / BASE_DIST;

On Fri, Jan 13, 2017 at 01:30:00AM +0000, Andre Przywara wrote:
The Allwinner H5 is very close to the H3 SoC, but has ARMv8 cores. To allow sharing the clocks, GPIO and driver code easily, create an architecture agnostic MACH_SUN8I_H3_H5 Kconfig symbol. Rename the existing symbol to MACH_SUN8I_H3_H5 where code is shared and let it be selected by a new shared Kconfig option.
This isn't really related to sun8i anymore, how about MACH_SUNXI_H3_H5?
[...]
+__weak void tzpc_init(void) +{ +}
void s_init(void) { /* @@ -188,10 +192,9 @@ void s_init(void) "mcr p15, 0, r0, c1, c0, 1\n" ::: "r0"); #endif -#if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I_H3
- /* Enable non-secure access to some peripherals */
- /* Enable non-secure access to some peripherals (only if needed) */ tzpc_init();
-#endif
This looks unrelated to your patch.
Thanks, Maxime

On 16/01/17 07:59, Maxime Ripard wrote:
On Fri, Jan 13, 2017 at 01:30:00AM +0000, Andre Przywara wrote:
The Allwinner H5 is very close to the H3 SoC, but has ARMv8 cores. To allow sharing the clocks, GPIO and driver code easily, create an architecture agnostic MACH_SUN8I_H3_H5 Kconfig symbol. Rename the existing symbol to MACH_SUN8I_H3_H5 where code is shared and let it be selected by a new shared Kconfig option.
This isn't really related to sun8i anymore, how about MACH_SUNXI_H3_H5?
Even better, I renamed it.
[...]
+__weak void tzpc_init(void) +{ +}
void s_init(void) { /* @@ -188,10 +192,9 @@ void s_init(void) "mcr p15, 0, r0, c1, c0, 1\n" ::: "r0"); #endif -#if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I_H3
- /* Enable non-secure access to some peripherals */
- /* Enable non-secure access to some peripherals (only if needed) */ tzpc_init();
-#endif
This looks unrelated to your patch.
Ah, thanks for spotting this. It was an attempt to get rid of some #ifdef's at all (by using a weak function), but I think I can just drop it in this patch to keep the patch smaller and confined to one purpose.
Cheers, Andre.

For the arch timer to work properly, we need to setup the CNTFRQ register, which is only possible in EL3. Define the arch timer frequency in sun8i.h as well, so that ARMv8's start.S can program the register correctly.
Signed-off-by: Andre Przywara andre.przywara@arm.com --- include/configs/sun8i.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/include/configs/sun8i.h b/include/configs/sun8i.h index a4c3fb6..cbb7239 100644 --- a/include/configs/sun8i.h +++ b/include/configs/sun8i.h @@ -13,6 +13,8 @@ * A23 specific configuration */
+#define COUNTER_FREQUENCY CONFIG_TIMER_CLK_FREQ + #ifdef CONFIG_USB_EHCI #define CONFIG_USB_EHCI_SUNXI #endif

On Fri, Jan 13, 2017 at 01:30:01AM +0000, Andre Przywara wrote:
For the arch timer to work properly, we need to setup the CNTFRQ register, which is only possible in EL3. Define the arch timer frequency in sun8i.h as well, so that ARMv8's start.S can program the register correctly.
Signed-off-by: Andre Przywara andre.przywara@arm.com
include/configs/sun8i.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/include/configs/sun8i.h b/include/configs/sun8i.h index a4c3fb6..cbb7239 100644 --- a/include/configs/sun8i.h +++ b/include/configs/sun8i.h @@ -13,6 +13,8 @@
- A23 specific configuration
*/
+#define COUNTER_FREQUENCY CONFIG_TIMER_CLK_FREQ
Why not convert the armv8 code to use CONFIG_TIMER_CLK_FREQ, or armv7 to use COUNTER_FREQUENCY?
The both options seem redundant.
Maxime

Hi,
On 16/01/17 08:01, Maxime Ripard wrote:
On Fri, Jan 13, 2017 at 01:30:01AM +0000, Andre Przywara wrote:
For the arch timer to work properly, we need to setup the CNTFRQ register, which is only possible in EL3. Define the arch timer frequency in sun8i.h as well, so that ARMv8's start.S can program the register correctly.
Signed-off-by: Andre Przywara andre.przywara@arm.com
include/configs/sun8i.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/include/configs/sun8i.h b/include/configs/sun8i.h index a4c3fb6..cbb7239 100644 --- a/include/configs/sun8i.h +++ b/include/configs/sun8i.h @@ -13,6 +13,8 @@
- A23 specific configuration
*/
+#define COUNTER_FREQUENCY CONFIG_TIMER_CLK_FREQ
Why not convert the armv8 code to use CONFIG_TIMER_CLK_FREQ, or armv7 to use COUNTER_FREQUENCY?
The both options seem redundant.
Good point, they indeed are. So I will drop this patch here and instead have a new one to rename the v7 users over to use COUNTER_FREQUENCY. I chose COUNTER_FREQUENCY because the other symbol has less users.
Thanks for the idea!
Cheers, Andre.

The Allwinner H5 Soc is bascially an H3 with high SRAM and ARMv8 cores. As the peripherals and the pinmuxing are almost identical, we piggy back on the shared MACH_SUN8I_H3_H5 config symbol.
Signed-off-by: Andre Przywara andre.przywara@arm.com --- arch/arm/mach-sunxi/cpu_info.c | 2 ++ board/sunxi/Kconfig | 10 ++++++++++ 2 files changed, 12 insertions(+)
diff --git a/arch/arm/mach-sunxi/cpu_info.c b/arch/arm/mach-sunxi/cpu_info.c index f1f6fd5..85633cc 100644 --- a/arch/arm/mach-sunxi/cpu_info.c +++ b/arch/arm/mach-sunxi/cpu_info.c @@ -91,6 +91,8 @@ int print_cpuinfo(void) puts("CPU: Allwinner A80 (SUN9I)\n"); #elif defined CONFIG_MACH_SUN50I puts("CPU: Allwinner A64 (SUN50I)\n"); +#elif defined CONFIG_MACH_SUN50I_H5 + puts("CPU: Allwinner H5 (SUN50I)\n"); #else #warning Please update cpu_info.c with correct CPU information puts("CPU: SUNXI Family\n"); diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index 2f3a847..89bbbe9 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -56,6 +56,11 @@ config MACH_SUN8I_H3_H5 select SUNXI_GEN_SUN6I select SUPPORT_SPL
+config MACH_SUN50I_H5 + bool + select SUNXI_HIGH_SRAM + select MACH_SUN8I_H3_H5 + choice prompt "Sunxi SoC Variant" optional @@ -143,6 +148,11 @@ config MACH_SUN50I select SUNXI_HIGH_SRAM select SUPPORT_SPL
+config MACH_SUN50I_H5_64 + bool "sun50i (Allwinner H5)" + select ARM64 + select MACH_SUN50I_H5 + endchoice
# The sun8i SoCs share a lot, this helps to avoid a lot of "if A23 || A33"

The OrangePi PC 2 is a typical SBC with the 64-bit Allwinner H5 SoC. Create a new .dts file for it by including the (32-bit) H3 SoC .dtsi and changing the differing components accordingly. This is a preliminary device tree mostly for U-Boot's own sake, it is expected to be updated once the official DT gets accepted upstream.
Signed-off-by: Andre Przywara andre.przywara@arm.com --- arch/arm/dts/Makefile | 2 + arch/arm/dts/sun50i-h5-orangepi-pc2.dts | 147 ++++++++++++++++++++++++++++++++ 2 files changed, 149 insertions(+) create mode 100644 arch/arm/dts/sun50i-h5-orangepi-pc2.dts
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 66ea0b3..70690ae 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -281,6 +281,8 @@ dtb-$(CONFIG_MACH_SUN8I_H3) += \ sun8i-h3-orangepi-plus.dtb \ sun8i-h3-orangepi-plus2e.dtb \ sun8i-h3-nanopi-neo.dtb +dtb-$(CONFIG_MACH_SUN50I_H5) += \ + sun50i-h5-orangepi-pc2.dtb dtb-$(CONFIG_MACH_SUN50I) += \ sun50i-a64-pine64-plus.dtb \ sun50i-a64-pine64.dtb diff --git a/arch/arm/dts/sun50i-h5-orangepi-pc2.dts b/arch/arm/dts/sun50i-h5-orangepi-pc2.dts new file mode 100644 index 0000000..de60f78 --- /dev/null +++ b/arch/arm/dts/sun50i-h5-orangepi-pc2.dts @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2016 ARM Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; + +#include "sun8i-h3.dtsi" + +/ { + model = "OrangePi PC 2"; + compatible = "xunlong,orangepi-pc-2", "allwinner,sun50i-h5"; + + cpus { + cpu@0 { + compatible = "arm,cortex-a53", "arm,armv8"; + enable-method = "psci"; + }; + cpu@1 { + compatible = "arm,cortex-a53", "arm,armv8"; + enable-method = "psci"; + }; + cpu@2 { + compatible = "arm,cortex-a53", "arm,armv8"; + enable-method = "psci"; + }; + cpu@3 { + compatible = "arm,cortex-a53", "arm,armv8"; + enable-method = "psci"; + }; + }; + + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; + + timer { + compatible = "arm,armv8-timer"; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory { + reg = <0x40000000 0x40000000>; + }; + + aliases { + serial0 = &uart0; + ethernet0 = &emac; + }; + + soc { + reg_vcc3v3: vcc3v3 { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + }; +}; + +&gic { + compatible = "arm,gic-400"; +}; + +&mmc0 { + compatible = "allwinner,sun50i-h5-mmc", + "allwinner,sun50i-a64-mmc", + "allwinner,sun5i-a13-mmc"; + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin>; + vmmc-supply = <®_vcc3v3>; + bus-width = <4>; + cd-gpios = <&pio 5 6 0>; + cd-inverted; + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins_a>; + status = "okay"; +}; + +&usbphy { + status = "okay"; +}; + +&ohci1 { + status = "okay"; +}; + +&ehci1 { + status = "okay"; +}; + +&emac { + pinctrl-names = "default"; + pinctrl-0 = <&emac_rgmii_pins>; + phy-mode = "rgmii"; + phy = <&phy1>; + status = "okay"; + + phy1: ethernet-phy@1 { + reg = <1>; + }; +};

The OrangePi PC 2 is a typical SBC with the 64-bit Allwinner H5 SoC. Add a (64-bit only) defconfig defining the required options to build the U-Boot proper and SPL.
Signed-off-by: Andre Przywara andre.przywara@arm.com --- board/sunxi/MAINTAINERS | 5 +++++ configs/orangepi_pc2_defconfig | 16 ++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 configs/orangepi_pc2_defconfig
diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS index 2321b8b..3f21129 100644 --- a/board/sunxi/MAINTAINERS +++ b/board/sunxi/MAINTAINERS @@ -242,6 +242,11 @@ M: Icenowy Zheng icenowy@aosc.xyz S: Maintained F: configs/orangepi_zero_defconfig
+ORANGEPI PC 2 BOARD +M: Andre Przywara andre.przywara@arm.com +S: Maintained +F: configs/orangepi_pc2_defconfig + R16 EVB PARROT BOARD M: Quentin Schulz quentin.schulz@free-electrons.com S: Maintained diff --git a/configs/orangepi_pc2_defconfig b/configs/orangepi_pc2_defconfig new file mode 100644 index 0000000..bc81ccc --- /dev/null +++ b/configs/orangepi_pc2_defconfig @@ -0,0 +1,16 @@ +CONFIG_ARM=y +CONFIG_ARCH_SUNXI=y +CONFIG_MACH_SUN50I_H5_64=y +CONFIG_SPL=y +CONFIG_DRAM_CLK=672 +CONFIG_DRAM_ZQ=3881977 +CONFIG_DEFAULT_DEVICE_TREE="sun50i-h5-orangepi-pc2" +# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +CONFIG_CONSOLE_MUX=y +# CONFIG_CMD_IMLS is not set +# CONFIG_CMD_FLASH is not set +# CONFIG_CMD_FPGA is not set +CONFIG_SUN8I_EMAC=y +CONFIG_USB_EHCI_HCD=y +CONFIG_SPL_SPI_SUNXI=y +CONFIG_SPL_SPI_FLASH_SUPPORT=y

13.01.2017, 09:34, "Andre Przywara" andre.przywara@arm.com:
This series introduces support for the Allwinner H5 SoC with four Cortex-A53 cores. The SoC's peripherals are very similar to the H3, although the cores and the BROM/SRAM layout resembles the A64. The first 6 patches contain some fixes and refactoring, to make code sharing between the three mentioned SoCs easier. Patch 07/12 adds support for the H5 DRAM controller, by extending the already existing combined H3/A64 DRAM code. Patch 08/12 renames the existing CONFIG_MACH_SUN8I_H3 config symbol to let it be used by all peripheral code that can be shared between the H3 and H5. Patch 10/12 introduces the H5 SoC config option into Kconfig, which defines this shared symbol as well. Patch 11/12 adds an easy device tree, which actually uses the H3 .dtsi and overwrites nodes which are different. This is good enough for U-Boot, the DT will be changed anyway once we get the DT merged into the Linux kernel. The final patch then adds the defconfig for the OrangePi PC2 board. Since this board comes with soldered SPI flash, we enable support for it in the SPL. This has been tested by writing the SPI flash with some special sunxi-fel version. The BROM loaded and executed the SPL, which in turn loaded and executed U-Boot proper. Both parts are 64-bit only for now. Ethernet support is enabled, but fails at the moment since the EMAC driver does not support setting a GPIO to enable the external Gigabit PHY. This should be a problem for H3 boards with Gigabit as well.
At the moment this build suffers from the same problem as the A64: the ATF is missing, so Linux won't boot easily. However I finally managed to clean up the FIT extension series, which solves this problem in a quite elegant way. I will post this series after getting some sleep ;-)
This series is on top of sunxi/next, which has three yet unmerged (and unrelated) patches compared to HEAD. So it should apply to both branches.
Some of these patches will probably conflict with ongoing work from Icenowy, I am happy to rebase on any branch someone points me to.
No. It's me who should do rebase, as I have not done everything ;-)
Please have a look and let me know your opinion!
Cheers, Andre.
Andre Przywara (12): sunxi: fix ACTLR.SMP assembly routine sunxi: simplify ACTLR.SMP bit set #ifdef sunxi: configs: merge sun9i and sun50i SPL memory definitions sunxi: Kconfig: introduce CONFIG_SUNXI_HIGH_SRAM sunxi: provide ARMv8 mem_map for every ARM64 board SPI: SPL: sunxi: fix 64-bit build sunxi: DRAM: add Allwinner H5 support sunxi: prepare for sharing MACH_SUN8I_H3 config symbol sunxi: H5: add COUNTER_FREQUENCY sunxi: introduce Allwinner H5 config option sunxi: dts: add basic OrangePi PC 2 device tree file sunxi: configs: add basic OrangePi PC 2 defconfig
arch/arm/dts/Makefile | 2 + arch/arm/dts/sun50i-h5-orangepi-pc2.dts | 147 ++++++++++++++++++++++++++ arch/arm/include/asm/arch-sunxi/clock_sun6i.h | 4 +- arch/arm/include/asm/arch-sunxi/cpu.h | 1 + arch/arm/include/asm/arch-sunxi/cpu_sun4i.h | 4 +- arch/arm/include/asm/arch-sunxi/dram.h | 2 +- arch/arm/include/asm/arch-sunxi/spl.h | 2 +- arch/arm/mach-sunxi/Makefile | 2 +- arch/arm/mach-sunxi/board.c | 21 ++-- arch/arm/mach-sunxi/clock_sun6i.c | 6 +- arch/arm/mach-sunxi/cpu_info.c | 2 + arch/arm/mach-sunxi/dram_sun8i_h3.c | 97 ++++++++++++++--- arch/arm/mach-sunxi/usb_phy.c | 4 +- board/sunxi/Kconfig | 36 ++++++- board/sunxi/MAINTAINERS | 5 + configs/orangepi_pc2_defconfig | 16 +++ drivers/mtd/spi/Kconfig | 2 +- drivers/mtd/spi/sunxi_spi_spl.c | 16 +-- drivers/net/sun8i_emac.c | 2 +- drivers/power/Kconfig | 4 +- drivers/usb/host/ehci-sunxi.c | 2 +- include/configs/sun8i.h | 2 + include/configs/sunxi-common.h | 22 ++-- 23 files changed, 330 insertions(+), 71 deletions(-) create mode 100644 arch/arm/dts/sun50i-h5-orangepi-pc2.dts create mode 100644 configs/orangepi_pc2_defconfig
-- 2.8.2
participants (7)
-
Andre Przywara
-
André Przywara
-
Icenowy Zheng
-
Maxime Ripard
-
Rask Ingemann Lambertsen
-
Simon Glass
-
Vishnu Patekar