diff mbox series

[v2,14/21] sunxi: Add support for H616 SoC

Message ID 20210111201153.1800440-15-jernej.skrabec@siol.net
State Awaiting Upstream
Delegated to: Andre Przywara
Headers show
Series sunxi: Introduce H616 support | expand

Commit Message

Jernej Škrabec Jan. 11, 2021, 8:11 p.m. UTC
H616 is very similar to H6 so most of the infrastructure can be reused.
However, two big differences are that it doesn't have functional SRAM A2
which is usually used for TF-A and it doesn't have ARISC co-processor.
It also needs bigger SPL size - 48 KiB.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 arch/arm/dts/sunxi-u-boot.dtsi                  |  8 ++++++++
 arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h |  7 +++++++
 arch/arm/mach-sunxi/Kconfig                     | 11 ++++++++++-
 arch/arm/mach-sunxi/clock_sun50i_h6.c           |  2 +-
 arch/arm/mach-sunxi/cpu_info.c                  |  2 ++
 drivers/power/Kconfig                           |  1 +
 include/configs/sunxi-common.h                  |  7 +++++++
 7 files changed, 36 insertions(+), 2 deletions(-)

Comments

Andre Przywara Jan. 23, 2021, 1:57 a.m. UTC | #1
On Mon, 11 Jan 2021 21:11:46 +0100
Jernej Skrabec <jernej.skrabec@siol.net> wrote:

> H616 is very similar to H6 so most of the infrastructure can be reused.
> However, two big differences are that it doesn't have functional SRAM A2
> which is usually used for TF-A and it doesn't have ARISC co-processor.
> It also needs bigger SPL size - 48 KiB.
> 
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>

That looks like the usual U-Boot madness (especially sunxi-common.h),
with code from the dark ages. But it works as such, even though it's
fragile. I feel we should clean this up at some point, maybe 32-bit FIT
support or the V831 support provide this opportunity.

But for now I'd rather have this merged, so somewhat reluctantly:

Reviewed-by: Andre Przywara <andre.przywara@arm.com>


Adding some comments / ideas below, in case someone gets bored:

> ---
>  arch/arm/dts/sunxi-u-boot.dtsi                  |  8 ++++++++
>  arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h |  7 +++++++
>  arch/arm/mach-sunxi/Kconfig                     | 11 ++++++++++-
>  arch/arm/mach-sunxi/clock_sun50i_h6.c           |  2 +-
>  arch/arm/mach-sunxi/cpu_info.c                  |  2 ++
>  drivers/power/Kconfig                           |  1 +
>  include/configs/sunxi-common.h                  |  7 +++++++
>  7 files changed, 36 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/dts/sunxi-u-boot.dtsi b/arch/arm/dts/sunxi-u-boot.dtsi
> index c77cf7cacf0c..abe629c55e57 100644
> --- a/arch/arm/dts/sunxi-u-boot.dtsi
> +++ b/arch/arm/dts/sunxi-u-boot.dtsi
> @@ -3,6 +3,8 @@
>  #ifdef CONFIG_MACH_SUN50I_H6
>  #define BL31_ADDR 0x104000
>  #define  SCP_ADDR 0x114000
> +#elif defined(CONFIG_MACH_SUN50I_H616)
> +#define BL31_ADDR 0x40004000
>  #else
>  #define BL31_ADDR  0x44000
>  #define  SCP_ADDR  0x50000
> @@ -61,6 +63,7 @@
>  					};
>  				};
>  
> +#ifndef CONFIG_MACH_SUN50I_H616

I wonder if there should be a config option for SCP firmware support,
which depends on !MACH_SUN50I_H616. This might come in handy when FIT
support gets extended to 32-bit SoCs, where some older ones don't have
an ARISC as well.

>  				scp {
>  					description = "SCP firmware";
>  					type = "firmware";
> @@ -73,6 +76,7 @@
>  						missing-msg = "scp-sunxi";
>  					};
>  				};
> +#endif
>  
>  				@fdt-SEQ {
>  					description = "NAME";
> @@ -87,7 +91,11 @@
>  				@config-SEQ {
>  					description = "NAME";
>  					firmware = "atf";
> +#ifdef CONFIG_MACH_SUN50I_H616
> +					loadables = "uboot";
> +#else
>  					loadables = "scp", "uboot";
> +#endif
>  					fdt = "fdt-SEQ";
>  				};
>  			};
> diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h b/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h
> index 6392cb07b472..d9cf8ae04288 100644
> --- a/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h
> +++ b/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h
> @@ -28,13 +28,20 @@
>  #define SUNXI_GIC400_BASE		0x03020000
>  #define SUNXI_IOMMU_BASE		0x030F0000
>  
> +#ifdef CONFIG_MACH_SUN50I_H6
>  #define SUNXI_DRAM_COM_BASE		0x04002000
>  #define SUNXI_DRAM_CTL0_BASE		0x04003000
>  #define SUNXI_DRAM_PHY0_BASE		0x04005000
> +#endif
>  #define SUNXI_NFC_BASE			0x04011000
>  #define SUNXI_MMC0_BASE			0x04020000
>  #define SUNXI_MMC1_BASE			0x04021000
>  #define SUNXI_MMC2_BASE			0x04022000
> +#ifdef CONFIG_MACH_SUN50I_H616
> +#define SUNXI_DRAM_COM_BASE		0x047FA000
> +#define SUNXI_DRAM_CTL0_BASE		0x047FB000
> +#define SUNXI_DRAM_PHY0_BASE		0x04800000
> +#endif
>  
>  #define SUNXI_UART0_BASE		0x05000000
>  #define SUNXI_UART1_BASE		0x05000400
> diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
> index a8571d180259..1415355750c4 100644
> --- a/arch/arm/mach-sunxi/Kconfig
> +++ b/arch/arm/mach-sunxi/Kconfig
> @@ -190,9 +190,10 @@ config MACH_SUNXI_H3_H5
>  	select SUPPORT_SPL
>  
>  # TODO: try out A80's 8GiB DRAM space
> +# TODO: H616 supports 4 GiB DRAM space
>  config SUNXI_DRAM_MAX_SIZE
>  	hex
> -	default 0xC0000000 if MACH_SUN50I || MACH_SUN50I_H5 || MACH_SUN50I_H6
> +	default 0xC0000000 if MACH_SUN50I || MACH_SUN50I_H5 || MACH_SUN50I_H6 || MACH_SUN50I_H616

Any reason you just didn't use 4GB here? Seems to compile for me. And
we don't support an AArch32 build for the H616 anyway at the moment, so
was there any issue with 2^32?

And since U-Boot creates the /memory node in the DT, this limits the
amount of memory Linux sees, doesn't it?
 
>  	default 0x80000000
>  
>  choice
> @@ -355,6 +356,12 @@ config MACH_SUN50I_H6
>  	select DRAM_SUN50I_H6
>  	select SUN50I_GEN_H6
>  
> +config MACH_SUN50I_H616
> +	bool "sun50i (Allwinner H616)"
> +	select ARM64
> +	select DRAM_SUN50I_H616
> +	select SUN50I_GEN_H6
> +
>  endchoice
>  
>  # The sun8i SoCs share a lot, this helps to avoid a lot of "if A23 || A33"
> @@ -591,6 +598,7 @@ config SYS_CLK_FREQ
>  	default 1008000000 if MACH_SUN8I
>  	default 1008000000 if MACH_SUN9I
>  	default 888000000 if MACH_SUN50I_H6
> +	default 1008000000 if MACH_SUN50I_H616
>  
>  config SYS_CONFIG_NAME
>  	default "sun4i" if MACH_SUN4I
> @@ -601,6 +609,7 @@ config SYS_CONFIG_NAME
>  	default "sun9i" if MACH_SUN9I
>  	default "sun50i" if MACH_SUN50I
>  	default "sun50i" if MACH_SUN50I_H6
> +	default "sun50i" if MACH_SUN50I_H616
>  
>  config SYS_BOARD
>  	default "sunxi"
> diff --git a/arch/arm/mach-sunxi/clock_sun50i_h6.c b/arch/arm/mach-sunxi/clock_sun50i_h6.c
> index daca02019bab..06d84eb158d7 100644
> --- a/arch/arm/mach-sunxi/clock_sun50i_h6.c
> +++ b/arch/arm/mach-sunxi/clock_sun50i_h6.c
> @@ -86,7 +86,7 @@ unsigned int clock_get_pll6(void)
>  {
>  	struct sunxi_ccm_reg *const ccm =
>  		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
> -	int m = IS_ENABLED(CONFIG_MACH_SUN50I_H6) 4 : 2;
> +	int m = IS_ENABLED(CONFIG_MACH_SUN50I_H6) ? 4 : 2;

As mentioned before, I fixed this already when this bug was introduced
a few patches earlier.

>  
>  	uint32_t rval = readl(&ccm->pll6_cfg);
>  	int n = ((rval & CCM_PLL6_CTRL_N_MASK) >> CCM_PLL6_CTRL_N_SHIFT);
> diff --git a/arch/arm/mach-sunxi/cpu_info.c b/arch/arm/mach-sunxi/cpu_info.c
> index 875e5a1a8a8e..ba33ef24300c 100644
> --- a/arch/arm/mach-sunxi/cpu_info.c
> +++ b/arch/arm/mach-sunxi/cpu_info.c
> @@ -99,6 +99,8 @@ int print_cpuinfo(void)
>  	puts("CPU:   Allwinner H5 (SUN50I)\n");
>  #elif defined CONFIG_MACH_SUN50I_H6
>  	puts("CPU:   Allwinner H6 (SUN50I)\n");
> +#elif defined CONFIG_MACH_SUN50I_H616
> +	puts("CPU:   Allwinner H616 (SUN50I)\n");
>  #else
>  #warning Please update cpu_info.c with correct CPU information
>  	puts("CPU:   SUNXI Family\n");
> diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
> index d17cf2d9112a..c5fbf1f832a9 100644
> --- a/drivers/power/Kconfig
> +++ b/drivers/power/Kconfig
> @@ -13,6 +13,7 @@ choice
>  	depends on ARCH_SUNXI
>  	default AXP209_POWER if MACH_SUN4I || MACH_SUN5I || MACH_SUN7I
>  	default AXP221_POWER if MACH_SUN6I || MACH_SUN8I_A23 || MACH_SUN8I_A33 || MACH_SUN8I_R40
> +	default AXP305_POWER if MACH_SUN50I_H616
>  	default AXP818_POWER if MACH_SUN8I_A83T
>  	default SUNXI_NO_PMIC if MACH_SUNXI_H3_H5 || MACH_SUN50I || MACH_SUN8I_V3S
>  
> diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
> index 203cb10fbabc..000f38647020 100644
> --- a/include/configs/sunxi-common.h
> +++ b/include/configs/sunxi-common.h
> @@ -178,9 +178,14 @@
>  #define LOW_LEVEL_SRAM_STACK		0x00018000
>  #endif /* !CONFIG_ARM64 */
>  #elif CONFIG_SUNXI_SRAM_ADDRESS == 0x20000
> +#ifdef CONFIG_MACH_SUN50I_H616
> +#define CONFIG_SPL_MAX_SIZE		0xbfa0		/* 48 KiB */

As Samuel mentioned, this is still an arbitrary limit, the actual limit
is much higher. But 48K is good enough for now. Actually my build here
is only slightly above 33K, so we have still some slack until we hit
this wall.

> +#define LOW_LEVEL_SRAM_STACK		0x58000

With all those values here in this nested #ifdef hell, I reckon this
should be in Kconfig (and probably other values as well).

> +#else
>  #define CONFIG_SPL_MAX_SIZE		0x7fa0		/* 32 KiB */
>  /* end of SRAM A2 on H6 for now */
>  #define LOW_LEVEL_SRAM_STACK		0x00118000
> +#endif
>  #else
>  #define CONFIG_SPL_MAX_SIZE		0x5fa0		/* 24KB on sun4i/sun7i */
>  #define LOW_LEVEL_SRAM_STACK		0x00008000	/* End of sram */
> @@ -188,7 +193,9 @@
>  
>  #define CONFIG_SPL_STACK		LOW_LEVEL_SRAM_STACK
>  
> +#ifndef CONFIG_MACH_SUN50I_H616
>  #define CONFIG_SPL_PAD_TO		32768		/* decimal for 'dd' */
> +#endif

Just a heads up: we actually don't use SPL_PAD_TO for arm64 (more
precisely: FIT images), but still we *cannot* define this if it's
smaller than CONFIG_SPL_MAX_SIZE, because of some sanity check in the
generic include/config_fallbacks.h. Meh.
But we could avoid defining this either for arm64 or for SPL_LOAD_FIT,
instead of just for the H616.


Cheers,
Andre


>  
>  
>  /* I2C */
diff mbox series

Patch

diff --git a/arch/arm/dts/sunxi-u-boot.dtsi b/arch/arm/dts/sunxi-u-boot.dtsi
index c77cf7cacf0c..abe629c55e57 100644
--- a/arch/arm/dts/sunxi-u-boot.dtsi
+++ b/arch/arm/dts/sunxi-u-boot.dtsi
@@ -3,6 +3,8 @@ 
 #ifdef CONFIG_MACH_SUN50I_H6
 #define BL31_ADDR 0x104000
 #define  SCP_ADDR 0x114000
+#elif defined(CONFIG_MACH_SUN50I_H616)
+#define BL31_ADDR 0x40004000
 #else
 #define BL31_ADDR  0x44000
 #define  SCP_ADDR  0x50000
@@ -61,6 +63,7 @@ 
 					};
 				};
 
+#ifndef CONFIG_MACH_SUN50I_H616
 				scp {
 					description = "SCP firmware";
 					type = "firmware";
@@ -73,6 +76,7 @@ 
 						missing-msg = "scp-sunxi";
 					};
 				};
+#endif
 
 				@fdt-SEQ {
 					description = "NAME";
@@ -87,7 +91,11 @@ 
 				@config-SEQ {
 					description = "NAME";
 					firmware = "atf";
+#ifdef CONFIG_MACH_SUN50I_H616
+					loadables = "uboot";
+#else
 					loadables = "scp", "uboot";
+#endif
 					fdt = "fdt-SEQ";
 				};
 			};
diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h b/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h
index 6392cb07b472..d9cf8ae04288 100644
--- a/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h
+++ b/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h
@@ -28,13 +28,20 @@ 
 #define SUNXI_GIC400_BASE		0x03020000
 #define SUNXI_IOMMU_BASE		0x030F0000
 
+#ifdef CONFIG_MACH_SUN50I_H6
 #define SUNXI_DRAM_COM_BASE		0x04002000
 #define SUNXI_DRAM_CTL0_BASE		0x04003000
 #define SUNXI_DRAM_PHY0_BASE		0x04005000
+#endif
 #define SUNXI_NFC_BASE			0x04011000
 #define SUNXI_MMC0_BASE			0x04020000
 #define SUNXI_MMC1_BASE			0x04021000
 #define SUNXI_MMC2_BASE			0x04022000
+#ifdef CONFIG_MACH_SUN50I_H616
+#define SUNXI_DRAM_COM_BASE		0x047FA000
+#define SUNXI_DRAM_CTL0_BASE		0x047FB000
+#define SUNXI_DRAM_PHY0_BASE		0x04800000
+#endif
 
 #define SUNXI_UART0_BASE		0x05000000
 #define SUNXI_UART1_BASE		0x05000400
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index a8571d180259..1415355750c4 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -190,9 +190,10 @@  config MACH_SUNXI_H3_H5
 	select SUPPORT_SPL
 
 # TODO: try out A80's 8GiB DRAM space
+# TODO: H616 supports 4 GiB DRAM space
 config SUNXI_DRAM_MAX_SIZE
 	hex
-	default 0xC0000000 if MACH_SUN50I || MACH_SUN50I_H5 || MACH_SUN50I_H6
+	default 0xC0000000 if MACH_SUN50I || MACH_SUN50I_H5 || MACH_SUN50I_H6 || MACH_SUN50I_H616
 	default 0x80000000
 
 choice
@@ -355,6 +356,12 @@  config MACH_SUN50I_H6
 	select DRAM_SUN50I_H6
 	select SUN50I_GEN_H6
 
+config MACH_SUN50I_H616
+	bool "sun50i (Allwinner H616)"
+	select ARM64
+	select DRAM_SUN50I_H616
+	select SUN50I_GEN_H6
+
 endchoice
 
 # The sun8i SoCs share a lot, this helps to avoid a lot of "if A23 || A33"
@@ -591,6 +598,7 @@  config SYS_CLK_FREQ
 	default 1008000000 if MACH_SUN8I
 	default 1008000000 if MACH_SUN9I
 	default 888000000 if MACH_SUN50I_H6
+	default 1008000000 if MACH_SUN50I_H616
 
 config SYS_CONFIG_NAME
 	default "sun4i" if MACH_SUN4I
@@ -601,6 +609,7 @@  config SYS_CONFIG_NAME
 	default "sun9i" if MACH_SUN9I
 	default "sun50i" if MACH_SUN50I
 	default "sun50i" if MACH_SUN50I_H6
+	default "sun50i" if MACH_SUN50I_H616
 
 config SYS_BOARD
 	default "sunxi"
diff --git a/arch/arm/mach-sunxi/clock_sun50i_h6.c b/arch/arm/mach-sunxi/clock_sun50i_h6.c
index daca02019bab..06d84eb158d7 100644
--- a/arch/arm/mach-sunxi/clock_sun50i_h6.c
+++ b/arch/arm/mach-sunxi/clock_sun50i_h6.c
@@ -86,7 +86,7 @@  unsigned int clock_get_pll6(void)
 {
 	struct sunxi_ccm_reg *const ccm =
 		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
-	int m = IS_ENABLED(CONFIG_MACH_SUN50I_H6) 4 : 2;
+	int m = IS_ENABLED(CONFIG_MACH_SUN50I_H6) ? 4 : 2;
 
 	uint32_t rval = readl(&ccm->pll6_cfg);
 	int n = ((rval & CCM_PLL6_CTRL_N_MASK) >> CCM_PLL6_CTRL_N_SHIFT);
diff --git a/arch/arm/mach-sunxi/cpu_info.c b/arch/arm/mach-sunxi/cpu_info.c
index 875e5a1a8a8e..ba33ef24300c 100644
--- a/arch/arm/mach-sunxi/cpu_info.c
+++ b/arch/arm/mach-sunxi/cpu_info.c
@@ -99,6 +99,8 @@  int print_cpuinfo(void)
 	puts("CPU:   Allwinner H5 (SUN50I)\n");
 #elif defined CONFIG_MACH_SUN50I_H6
 	puts("CPU:   Allwinner H6 (SUN50I)\n");
+#elif defined CONFIG_MACH_SUN50I_H616
+	puts("CPU:   Allwinner H616 (SUN50I)\n");
 #else
 #warning Please update cpu_info.c with correct CPU information
 	puts("CPU:   SUNXI Family\n");
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index d17cf2d9112a..c5fbf1f832a9 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -13,6 +13,7 @@  choice
 	depends on ARCH_SUNXI
 	default AXP209_POWER if MACH_SUN4I || MACH_SUN5I || MACH_SUN7I
 	default AXP221_POWER if MACH_SUN6I || MACH_SUN8I_A23 || MACH_SUN8I_A33 || MACH_SUN8I_R40
+	default AXP305_POWER if MACH_SUN50I_H616
 	default AXP818_POWER if MACH_SUN8I_A83T
 	default SUNXI_NO_PMIC if MACH_SUNXI_H3_H5 || MACH_SUN50I || MACH_SUN8I_V3S
 
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
index 203cb10fbabc..000f38647020 100644
--- a/include/configs/sunxi-common.h
+++ b/include/configs/sunxi-common.h
@@ -178,9 +178,14 @@ 
 #define LOW_LEVEL_SRAM_STACK		0x00018000
 #endif /* !CONFIG_ARM64 */
 #elif CONFIG_SUNXI_SRAM_ADDRESS == 0x20000
+#ifdef CONFIG_MACH_SUN50I_H616
+#define CONFIG_SPL_MAX_SIZE		0xbfa0		/* 48 KiB */
+#define LOW_LEVEL_SRAM_STACK		0x58000
+#else
 #define CONFIG_SPL_MAX_SIZE		0x7fa0		/* 32 KiB */
 /* end of SRAM A2 on H6 for now */
 #define LOW_LEVEL_SRAM_STACK		0x00118000
+#endif
 #else
 #define CONFIG_SPL_MAX_SIZE		0x5fa0		/* 24KB on sun4i/sun7i */
 #define LOW_LEVEL_SRAM_STACK		0x00008000	/* End of sram */
@@ -188,7 +193,9 @@ 
 
 #define CONFIG_SPL_STACK		LOW_LEVEL_SRAM_STACK
 
+#ifndef CONFIG_MACH_SUN50I_H616
 #define CONFIG_SPL_PAD_TO		32768		/* decimal for 'dd' */
+#endif
 
 
 /* I2C */