From 573d600e7b84ccceb7283bd462c8331f818b2b69 Mon Sep 17 00:00:00 2001 From: Andre Przywara <andre.przywara@arm.com> Date: Thu, 8 Dec 2022 00:41:07 +0000 Subject: [PATCH 1/4] refactor(allwinner): consolidate sunxi_cfg.h files The header files describing the CPU cluster configuration IP block for the H6 and H616 are actually identical, so merge them into one file and move that to a common location. There is an upcoming SoC which will similarly share a header file with the R329 SoC, so move that to the same location already. In Allwinner's BSP source those two SoC groups are typically called "NCAT" and "NCAT2", so use those names for the shared header files. No functional change. Change-Id: I98318373577344dbe228a81fa331ce660df32b5f Signed-off-by: Andre Przywara <andre.przywara@arm.com> --- .../common/include/sunxi_cpucfg_ncat.h | 35 ++++++++++++++++++ .../common/include/sunxi_cpucfg_ncat2.h | 31 ++++++++++++++++ .../sun50i_h6/include/sunxi_cpucfg.h | 36 +------------------ .../sun50i_h616/include/sunxi_cpucfg.h | 36 +------------------ .../sun50i_r329/include/sunxi_cpucfg.h | 32 +---------------- 5 files changed, 69 insertions(+), 101 deletions(-) create mode 100644 plat/allwinner/common/include/sunxi_cpucfg_ncat.h create mode 100644 plat/allwinner/common/include/sunxi_cpucfg_ncat2.h diff --git a/plat/allwinner/common/include/sunxi_cpucfg_ncat.h b/plat/allwinner/common/include/sunxi_cpucfg_ncat.h new file mode 100644 index 000000000..5bfda5db9 --- /dev/null +++ b/plat/allwinner/common/include/sunxi_cpucfg_ncat.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SUNXI_CPUCFG_H +#define SUNXI_CPUCFG_H + +#include <sunxi_mmap.h> + +/* c = cluster, n = core */ +#define SUNXI_CPUCFG_CLS_CTRL_REG0(c) (SUNXI_CPUCFG_BASE + 0x0010 + (c) * 0x10) +#define SUNXI_CPUCFG_CLS_CTRL_REG1(c) (SUNXI_CPUCFG_BASE + 0x0014 + (c) * 0x10) +#define SUNXI_CPUCFG_CACHE_CFG_REG (SUNXI_CPUCFG_BASE + 0x0024) +#define SUNXI_CPUCFG_DBG_REG0 (SUNXI_CPUCFG_BASE + 0x00c0) + +#define SUNXI_CPUCFG_RST_CTRL_REG(c) (SUNXI_CPUCFG_BASE + 0x0000 + (c) * 4) +#define SUNXI_CPUCFG_RVBAR_LO_REG(n) (SUNXI_CPUCFG_BASE + 0x0040 + (n) * 8) +#define SUNXI_CPUCFG_RVBAR_HI_REG(n) (SUNXI_CPUCFG_BASE + 0x0044 + (n) * 8) + +#define SUNXI_POWERON_RST_REG(c) (SUNXI_R_CPUCFG_BASE + 0x0040 + (c) * 4) +#define SUNXI_POWEROFF_GATING_REG(c) (SUNXI_R_CPUCFG_BASE + 0x0044 + (c) * 4) +#define SUNXI_CPU_POWER_CLAMP_REG(c, n) (SUNXI_R_CPUCFG_BASE + 0x0050 + \ + (c) * 0x10 + (n) * 4) + +#define SUNXI_CPUIDLE_EN_REG (SUNXI_R_CPUCFG_BASE + 0x0100) +#define SUNXI_CORE_CLOSE_REG (SUNXI_R_CPUCFG_BASE + 0x0104) +#define SUNXI_PWR_SW_DELAY_REG (SUNXI_R_CPUCFG_BASE + 0x0140) +#define SUNXI_CONFIG_DELAY_REG (SUNXI_R_CPUCFG_BASE + 0x0144) + +#define SUNXI_AA64nAA32_REG SUNXI_CPUCFG_CLS_CTRL_REG0 +#define SUNXI_AA64nAA32_OFFSET 24 + +#endif /* SUNXI_CPUCFG_H */ diff --git a/plat/allwinner/common/include/sunxi_cpucfg_ncat2.h b/plat/allwinner/common/include/sunxi_cpucfg_ncat2.h new file mode 100644 index 000000000..9478f321a --- /dev/null +++ b/plat/allwinner/common/include/sunxi_cpucfg_ncat2.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2021 Sipeed + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SUNXI_CPUCFG_H +#define SUNXI_CPUCFG_H + +#include <sunxi_mmap.h> + +/* c = cluster, n = core */ +#define SUNXI_CPUCFG_CLS_CTRL_REG0(c) (SUNXI_C0_CPUXCFG_BASE + 0x0010) +#define SUNXI_CPUCFG_CLS_CTRL_REG1(c) (SUNXI_C0_CPUXCFG_BASE + 0x0014) +#define SUNXI_CPUCFG_CACHE_CFG_REG (SUNXI_C0_CPUXCFG_BASE + 0x0024) +#define SUNXI_CPUCFG_DBG_REG0 (SUNXI_C0_CPUXCFG_BASE + 0x00c0) + +#define SUNXI_CPUCFG_RST_CTRL_REG(c) (SUNXI_C0_CPUXCFG_BASE + 0x0000) +#define SUNXI_CPUCFG_GEN_CTRL_REG0(c) (SUNXI_CPUCFG_BASE + 0x0000) +#define SUNXI_CPUCFG_RVBAR_LO_REG(n) (SUNXI_CPUCFG_BASE + 0x0040 + (n) * 8) +#define SUNXI_CPUCFG_RVBAR_HI_REG(n) (SUNXI_CPUCFG_BASE + 0x0044 + (n) * 8) + +#define SUNXI_POWERON_RST_REG(c) (SUNXI_R_CPUCFG_BASE + 0x0040 + (c) * 4) +#define SUNXI_POWEROFF_GATING_REG(c) (SUNXI_R_CPUCFG_BASE + 0x0044 + (c) * 4) +#define SUNXI_CPU_POWER_CLAMP_REG(c, n) (SUNXI_R_CPUCFG_BASE + 0x0050 + \ + (c) * 0x10 + (n) * 4) + +#define SUNXI_AA64nAA32_REG SUNXI_CPUCFG_GEN_CTRL_REG0 +#define SUNXI_AA64nAA32_OFFSET 4 + +#endif /* SUNXI_CPUCFG_H */ diff --git a/plat/allwinner/sun50i_h6/include/sunxi_cpucfg.h b/plat/allwinner/sun50i_h6/include/sunxi_cpucfg.h index 5bfda5db9..58abfaa58 100644 --- a/plat/allwinner/sun50i_h6/include/sunxi_cpucfg.h +++ b/plat/allwinner/sun50i_h6/include/sunxi_cpucfg.h @@ -1,35 +1 @@ -/* - * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef SUNXI_CPUCFG_H -#define SUNXI_CPUCFG_H - -#include <sunxi_mmap.h> - -/* c = cluster, n = core */ -#define SUNXI_CPUCFG_CLS_CTRL_REG0(c) (SUNXI_CPUCFG_BASE + 0x0010 + (c) * 0x10) -#define SUNXI_CPUCFG_CLS_CTRL_REG1(c) (SUNXI_CPUCFG_BASE + 0x0014 + (c) * 0x10) -#define SUNXI_CPUCFG_CACHE_CFG_REG (SUNXI_CPUCFG_BASE + 0x0024) -#define SUNXI_CPUCFG_DBG_REG0 (SUNXI_CPUCFG_BASE + 0x00c0) - -#define SUNXI_CPUCFG_RST_CTRL_REG(c) (SUNXI_CPUCFG_BASE + 0x0000 + (c) * 4) -#define SUNXI_CPUCFG_RVBAR_LO_REG(n) (SUNXI_CPUCFG_BASE + 0x0040 + (n) * 8) -#define SUNXI_CPUCFG_RVBAR_HI_REG(n) (SUNXI_CPUCFG_BASE + 0x0044 + (n) * 8) - -#define SUNXI_POWERON_RST_REG(c) (SUNXI_R_CPUCFG_BASE + 0x0040 + (c) * 4) -#define SUNXI_POWEROFF_GATING_REG(c) (SUNXI_R_CPUCFG_BASE + 0x0044 + (c) * 4) -#define SUNXI_CPU_POWER_CLAMP_REG(c, n) (SUNXI_R_CPUCFG_BASE + 0x0050 + \ - (c) * 0x10 + (n) * 4) - -#define SUNXI_CPUIDLE_EN_REG (SUNXI_R_CPUCFG_BASE + 0x0100) -#define SUNXI_CORE_CLOSE_REG (SUNXI_R_CPUCFG_BASE + 0x0104) -#define SUNXI_PWR_SW_DELAY_REG (SUNXI_R_CPUCFG_BASE + 0x0140) -#define SUNXI_CONFIG_DELAY_REG (SUNXI_R_CPUCFG_BASE + 0x0144) - -#define SUNXI_AA64nAA32_REG SUNXI_CPUCFG_CLS_CTRL_REG0 -#define SUNXI_AA64nAA32_OFFSET 24 - -#endif /* SUNXI_CPUCFG_H */ +#include <sunxi_cpucfg_ncat.h> diff --git a/plat/allwinner/sun50i_h616/include/sunxi_cpucfg.h b/plat/allwinner/sun50i_h616/include/sunxi_cpucfg.h index dab663b6b..58abfaa58 100644 --- a/plat/allwinner/sun50i_h616/include/sunxi_cpucfg.h +++ b/plat/allwinner/sun50i_h616/include/sunxi_cpucfg.h @@ -1,35 +1 @@ -/* - * Copyright (c) 2017-2020, ARM Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef SUNXI_CPUCFG_H -#define SUNXI_CPUCFG_H - -#include <sunxi_mmap.h> - -/* c = cluster, n = core */ -#define SUNXI_CPUCFG_CLS_CTRL_REG0(c) (SUNXI_CPUCFG_BASE + 0x0010 + (c) * 0x10) -#define SUNXI_CPUCFG_CLS_CTRL_REG1(c) (SUNXI_CPUCFG_BASE + 0x0014 + (c) * 0x10) -#define SUNXI_CPUCFG_CACHE_CFG_REG (SUNXI_CPUCFG_BASE + 0x0024) -#define SUNXI_CPUCFG_DBG_REG0 (SUNXI_CPUCFG_BASE + 0x00c0) - -#define SUNXI_CPUCFG_RST_CTRL_REG(c) (SUNXI_CPUCFG_BASE + 0x0000 + (c) * 4) -#define SUNXI_CPUCFG_RVBAR_LO_REG(n) (SUNXI_CPUCFG_BASE + 0x0040 + (n) * 8) -#define SUNXI_CPUCFG_RVBAR_HI_REG(n) (SUNXI_CPUCFG_BASE + 0x0044 + (n) * 8) - -#define SUNXI_POWERON_RST_REG(c) (SUNXI_R_CPUCFG_BASE + 0x0040 + (c) * 4) -#define SUNXI_POWEROFF_GATING_REG(c) (SUNXI_R_CPUCFG_BASE + 0x0044 + (c) * 4) -#define SUNXI_CPU_POWER_CLAMP_REG(c, n) (SUNXI_R_CPUCFG_BASE + 0x0050 + \ - (c) * 0x10 + (n) * 4) - -#define SUNXI_CPUIDLE_EN_REG (SUNXI_R_CPUCFG_BASE + 0x0100) -#define SUNXI_CORE_CLOSE_REG (SUNXI_R_CPUCFG_BASE + 0x0104) -#define SUNXI_PWR_SW_DELAY_REG (SUNXI_R_CPUCFG_BASE + 0x0140) -#define SUNXI_CONFIG_DELAY_REG (SUNXI_R_CPUCFG_BASE + 0x0144) - -#define SUNXI_AA64nAA32_REG SUNXI_CPUCFG_CLS_CTRL_REG0 -#define SUNXI_AA64nAA32_OFFSET 24 - -#endif /* SUNXI_CPUCFG_H */ +#include <sunxi_cpucfg_ncat.h> diff --git a/plat/allwinner/sun50i_r329/include/sunxi_cpucfg.h b/plat/allwinner/sun50i_r329/include/sunxi_cpucfg.h index 9478f321a..3c3530fc7 100644 --- a/plat/allwinner/sun50i_r329/include/sunxi_cpucfg.h +++ b/plat/allwinner/sun50i_r329/include/sunxi_cpucfg.h @@ -1,31 +1 @@ -/* - * Copyright (c) 2021 Sipeed - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef SUNXI_CPUCFG_H -#define SUNXI_CPUCFG_H - -#include <sunxi_mmap.h> - -/* c = cluster, n = core */ -#define SUNXI_CPUCFG_CLS_CTRL_REG0(c) (SUNXI_C0_CPUXCFG_BASE + 0x0010) -#define SUNXI_CPUCFG_CLS_CTRL_REG1(c) (SUNXI_C0_CPUXCFG_BASE + 0x0014) -#define SUNXI_CPUCFG_CACHE_CFG_REG (SUNXI_C0_CPUXCFG_BASE + 0x0024) -#define SUNXI_CPUCFG_DBG_REG0 (SUNXI_C0_CPUXCFG_BASE + 0x00c0) - -#define SUNXI_CPUCFG_RST_CTRL_REG(c) (SUNXI_C0_CPUXCFG_BASE + 0x0000) -#define SUNXI_CPUCFG_GEN_CTRL_REG0(c) (SUNXI_CPUCFG_BASE + 0x0000) -#define SUNXI_CPUCFG_RVBAR_LO_REG(n) (SUNXI_CPUCFG_BASE + 0x0040 + (n) * 8) -#define SUNXI_CPUCFG_RVBAR_HI_REG(n) (SUNXI_CPUCFG_BASE + 0x0044 + (n) * 8) - -#define SUNXI_POWERON_RST_REG(c) (SUNXI_R_CPUCFG_BASE + 0x0040 + (c) * 4) -#define SUNXI_POWEROFF_GATING_REG(c) (SUNXI_R_CPUCFG_BASE + 0x0044 + (c) * 4) -#define SUNXI_CPU_POWER_CLAMP_REG(c, n) (SUNXI_R_CPUCFG_BASE + 0x0050 + \ - (c) * 0x10 + (n) * 4) - -#define SUNXI_AA64nAA32_REG SUNXI_CPUCFG_GEN_CTRL_REG0 -#define SUNXI_AA64nAA32_OFFSET 4 - -#endif /* SUNXI_CPUCFG_H */ +#include <sunxi_cpucfg_ncat2.h> From b15e2cda14b3ffddebd8b40cc5c31c1c0e9cbf0d Mon Sep 17 00:00:00 2001 From: Mikhail Kalashnikov <iuncuim@gmail.com> Date: Fri, 9 Dec 2022 01:56:20 +0000 Subject: [PATCH 2/4] feat(allwinner): add extra CPU control registers The die used in several variants of the Allwinner H616 SoC (H313, T507) seems to produced in at least two revisions. The newer one differs from the original by using a different CPU control register IP block. Add those newly used register offsets to the respective header file. The MMIO block itself is actually present in both variants, though the registers are different. The new registers tend to use one register per core, in contrast to one register per cluster in the older revisions. Change-Id: Ifbda1bdc67a6a16fbb901dbc83996e4a148b7602 Signed-off-by: Mikhail Kalashnikov <iuncuim@gmail.com> Signed-off-by: Andre Przywara <andre.przywara@arm.com> --- plat/allwinner/common/include/sunxi_cpucfg_ncat.h | 8 ++++++++ plat/allwinner/sun50i_h6/include/sunxi_mmap.h | 1 + plat/allwinner/sun50i_h616/include/sunxi_mmap.h | 1 + 3 files changed, 10 insertions(+) diff --git a/plat/allwinner/common/include/sunxi_cpucfg_ncat.h b/plat/allwinner/common/include/sunxi_cpucfg_ncat.h index 5bfda5db9..22828c271 100644 --- a/plat/allwinner/common/include/sunxi_cpucfg_ncat.h +++ b/plat/allwinner/common/include/sunxi_cpucfg_ncat.h @@ -13,16 +13,24 @@ #define SUNXI_CPUCFG_CLS_CTRL_REG0(c) (SUNXI_CPUCFG_BASE + 0x0010 + (c) * 0x10) #define SUNXI_CPUCFG_CLS_CTRL_REG1(c) (SUNXI_CPUCFG_BASE + 0x0014 + (c) * 0x10) #define SUNXI_CPUCFG_CACHE_CFG_REG (SUNXI_CPUCFG_BASE + 0x0024) +/* The T507 datasheet does not mention this register. */ #define SUNXI_CPUCFG_DBG_REG0 (SUNXI_CPUCFG_BASE + 0x00c0) #define SUNXI_CPUCFG_RST_CTRL_REG(c) (SUNXI_CPUCFG_BASE + 0x0000 + (c) * 4) #define SUNXI_CPUCFG_RVBAR_LO_REG(n) (SUNXI_CPUCFG_BASE + 0x0040 + (n) * 8) #define SUNXI_CPUCFG_RVBAR_HI_REG(n) (SUNXI_CPUCFG_BASE + 0x0044 + (n) * 8) +#define SUNXI_C0_CPU_CTRL_REG(n) (SUNXI_CPUCFG_BASE + 0x0060 + (n) * 4) + +#define SUNXI_CPU_CTRL_REG(n) (SUNXI_CPUSUBSYS_BASE + 0x20 + (n) * 4) +#define SUNXI_ALT_RVBAR_LO_REG(n) (SUNXI_CPUSUBSYS_BASE + 0x40 + (n) * 8) +#define SUNXI_ALT_RVBAR_HI_REG(n) (SUNXI_CPUSUBSYS_BASE + 0x44 + (n) * 8) + #define SUNXI_POWERON_RST_REG(c) (SUNXI_R_CPUCFG_BASE + 0x0040 + (c) * 4) #define SUNXI_POWEROFF_GATING_REG(c) (SUNXI_R_CPUCFG_BASE + 0x0044 + (c) * 4) #define SUNXI_CPU_POWER_CLAMP_REG(c, n) (SUNXI_R_CPUCFG_BASE + 0x0050 + \ (c) * 0x10 + (n) * 4) +#define SUNXI_CPU_UNK_REG(n) (SUNXI_R_CPUCFG_BASE + 0x0070 + (n) * 4) #define SUNXI_CPUIDLE_EN_REG (SUNXI_R_CPUCFG_BASE + 0x0100) #define SUNXI_CORE_CLOSE_REG (SUNXI_R_CPUCFG_BASE + 0x0104) diff --git a/plat/allwinner/sun50i_h6/include/sunxi_mmap.h b/plat/allwinner/sun50i_h6/include/sunxi_mmap.h index 58216d848..43133be22 100644 --- a/plat/allwinner/sun50i_h6/include/sunxi_mmap.h +++ b/plat/allwinner/sun50i_h6/include/sunxi_mmap.h @@ -59,5 +59,6 @@ #define SUNXI_R_RSB_BASE 0x07083000 #define SUNXI_R_UART_BASE 0x07080000 #define SUNXI_R_PIO_BASE 0x07022000 +#define SUNXI_CPUSUBSYS_BASE 0x08100000 #endif /* SUNXI_MMAP_H */ diff --git a/plat/allwinner/sun50i_h616/include/sunxi_mmap.h b/plat/allwinner/sun50i_h616/include/sunxi_mmap.h index 3b4f4a02e..24a4ba8e6 100644 --- a/plat/allwinner/sun50i_h616/include/sunxi_mmap.h +++ b/plat/allwinner/sun50i_h616/include/sunxi_mmap.h @@ -41,6 +41,7 @@ #define SUNXI_R_UART_BASE 0x07080000 #define SUNXI_R_I2C_BASE 0x07081400 #define SUNXI_R_RSB_BASE 0x07083000 +#define SUNXI_CPUSUBSYS_BASE 0x08100000 #define SUNXI_CPUCFG_BASE 0x09010000 #endif /* SUNXI_MMAP_H */ From fbde260b11171f0f67afbc631e22fe26366ff448 Mon Sep 17 00:00:00 2001 From: Andre Przywara <andre.przywara@arm.com> Date: Mon, 3 Apr 2023 21:33:45 +0100 Subject: [PATCH 3/4] feat(allwinner): add function to detect H616 die variant Allwinner provides a number of SoCs that use the same die as the H616. Some of those chips apparently use a slight variation of that die, that differs in the way the CPU cores' power and reset controls are handled. This die variation can be detected by reading the SRAM version register. Provide a predicate function that returns false if that die variant is used. Since the CPU power control code is shared for all supported SoCs, we provide an instance of this function for each SoC, as a static inline, and return true on all other SoCs. This allows to always use this function, and still let the compiler optimise away the unneeded branch for those older SoCs. This function is unused for now, but is needed in the next patch. Change-Id: I49e014b895b7e2f55b4e7dc2b3d8aa31cee711b5 Signed-off-by: Andre Przywara <andre.przywara@arm.com> --- plat/allwinner/common/include/sunxi_cpucfg_ncat2.h | 5 +++++ plat/allwinner/common/include/sunxi_def.h | 1 + plat/allwinner/common/sunxi_common.c | 2 +- plat/allwinner/sun50i_a64/include/sunxi_cpucfg.h | 5 +++++ plat/allwinner/sun50i_h6/include/sunxi_cpucfg.h | 5 +++++ plat/allwinner/sun50i_h616/include/sunxi_cpucfg.h | 7 +++++++ 6 files changed, 24 insertions(+), 1 deletion(-) diff --git a/plat/allwinner/common/include/sunxi_cpucfg_ncat2.h b/plat/allwinner/common/include/sunxi_cpucfg_ncat2.h index 9478f321a..d4aec1932 100644 --- a/plat/allwinner/common/include/sunxi_cpucfg_ncat2.h +++ b/plat/allwinner/common/include/sunxi_cpucfg_ncat2.h @@ -28,4 +28,9 @@ #define SUNXI_AA64nAA32_REG SUNXI_CPUCFG_GEN_CTRL_REG0 #define SUNXI_AA64nAA32_OFFSET 4 +static inline bool sunxi_cpucfg_has_per_cluster_regs(void) +{ + return true; +} + #endif /* SUNXI_CPUCFG_H */ diff --git a/plat/allwinner/common/include/sunxi_def.h b/plat/allwinner/common/include/sunxi_def.h index c17ef9529..20f6c4986 100644 --- a/plat/allwinner/common/include/sunxi_def.h +++ b/plat/allwinner/common/include/sunxi_def.h @@ -20,6 +20,7 @@ #define SUNXI_SOC_H616 0x1823 #define SUNXI_SOC_R329 0x1851 +#define SUNXI_VER_BITS_MASK 0xffU #define JEDEC_ALLWINNER_BKID 9U #define JEDEC_ALLWINNER_MFID 0x9eU diff --git a/plat/allwinner/common/sunxi_common.c b/plat/allwinner/common/sunxi_common.c index 092659c0b..62f4fcbd9 100644 --- a/plat/allwinner/common/sunxi_common.c +++ b/plat/allwinner/common/sunxi_common.c @@ -183,5 +183,5 @@ int32_t plat_get_soc_revision(void) { uint32_t reg = mmio_read_32(SRAM_VER_REG); - return reg & GENMASK_32(7, 0); + return reg & SUNXI_VER_BITS_MASK; } diff --git a/plat/allwinner/sun50i_a64/include/sunxi_cpucfg.h b/plat/allwinner/sun50i_a64/include/sunxi_cpucfg.h index aed358572..ddd53baab 100644 --- a/plat/allwinner/sun50i_a64/include/sunxi_cpucfg.h +++ b/plat/allwinner/sun50i_a64/include/sunxi_cpucfg.h @@ -36,4 +36,9 @@ #define SUNXI_AA64nAA32_REG SUNXI_CPUCFG_CLS_CTRL_REG0 #define SUNXI_AA64nAA32_OFFSET 24 +static inline bool sunxi_cpucfg_has_per_cluster_regs(void) +{ + return true; +} + #endif /* SUNXI_CPUCFG_H */ diff --git a/plat/allwinner/sun50i_h6/include/sunxi_cpucfg.h b/plat/allwinner/sun50i_h6/include/sunxi_cpucfg.h index 58abfaa58..585c51b07 100644 --- a/plat/allwinner/sun50i_h6/include/sunxi_cpucfg.h +++ b/plat/allwinner/sun50i_h6/include/sunxi_cpucfg.h @@ -1 +1,6 @@ #include <sunxi_cpucfg_ncat.h> + +static inline bool sunxi_cpucfg_has_per_cluster_regs(void) +{ + return true; +} diff --git a/plat/allwinner/sun50i_h616/include/sunxi_cpucfg.h b/plat/allwinner/sun50i_h616/include/sunxi_cpucfg.h index 58abfaa58..5c590e48b 100644 --- a/plat/allwinner/sun50i_h616/include/sunxi_cpucfg.h +++ b/plat/allwinner/sun50i_h616/include/sunxi_cpucfg.h @@ -1 +1,8 @@ +#include <plat/common/platform.h> + #include <sunxi_cpucfg_ncat.h> + +static inline bool sunxi_cpucfg_has_per_cluster_regs(void) +{ + return (plat_get_soc_revision() != 2); +} From 018c1d878fbfd696ebeda52b5188e4658b87bf75 Mon Sep 17 00:00:00 2001 From: Mikhail Kalashnikov <iuncuim@gmail.com> Date: Mon, 27 Mar 2023 18:36:14 +0300 Subject: [PATCH 4/4] feat(allwinner): add support for Allwinner T507 SoC The Allwinner T507 SoC is using the same die as the H616, but in a different package. On top of this, there is at least one different die revision out there, which uses a different CPU cluster control block. The same die revision has been spotted in some, but not all, H313 SoCs. Apart from that IP block, the rest of the SoC seems the same, so we can support them using the existing H616 port. The die revision can be auto-detected, so there is no extra build option or knowledge needed. Provide the deviating CPU power up/down sequence for the die variant. The new IP block uses per-core instead of per-cluster registers, but follows the same pattern otherwise. Since the CPU ops code is shared among all Allwinner SoCs, we need to dummy-define the new register names for the older SoCs. The actual new code is guarded by a predicate function, that is hard coded to return true on the other SoCs. Since this is a static inline function in a header file, the compiler will optimise away the unneeded branch there, so the generated code for the other SoCs stays the same. Change-Id: Ib5ade99d34b4ccb161ccde0e34f280ca6bd16ecd Signed-off-by: Mikhail Kalashnikov <iuncuim@gmail.com> Signed-off-by: Andre Przywara <andre.przywara@arm.com> --- docs/plat/allwinner.rst | 2 + plat/allwinner/common/sunxi_cpu_ops.c | 95 +++++++++++++++++++-------- plat/allwinner/common/sunxi_pm.c | 20 ++++-- 3 files changed, 87 insertions(+), 30 deletions(-) diff --git a/docs/plat/allwinner.rst b/docs/plat/allwinner.rst index 3e9ce511f..8e967dcde 100644 --- a/docs/plat/allwinner.rst +++ b/docs/plat/allwinner.rst @@ -23,6 +23,8 @@ There is one build target per supported SoC: +------+-------------------+ | H313 | sun50i_h616 | +------+-------------------+ +| T507 | sun50i_h616 | ++------+-------------------+ | R329 | sun50i_r329 | +------+-------------------+ diff --git a/plat/allwinner/common/sunxi_cpu_ops.c b/plat/allwinner/common/sunxi_cpu_ops.c index 46e7090ab..30841e2ea 100644 --- a/plat/allwinner/common/sunxi_cpu_ops.c +++ b/plat/allwinner/common/sunxi_cpu_ops.c @@ -19,6 +19,12 @@ #include <sunxi_mmap.h> #include <sunxi_private.h> +#ifndef SUNXI_C0_CPU_CTRL_REG +#define SUNXI_C0_CPU_CTRL_REG(n) 0 +#define SUNXI_CPU_UNK_REG(n) 0 +#define SUNXI_CPU_CTRL_REG(n) 0 +#endif + static void sunxi_cpu_disable_power(unsigned int cluster, unsigned int core) { if (mmio_read_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core)) == 0xff) @@ -53,15 +59,30 @@ static void sunxi_cpu_off(u_register_t mpidr) VERBOSE("PSCI: Powering off cluster %d core %d\n", cluster, core); - /* Deassert DBGPWRDUP */ - mmio_clrbits_32(SUNXI_CPUCFG_DBG_REG0, BIT(core)); - /* Activate the core output clamps, but not for core 0. */ - if (core != 0) - mmio_setbits_32(SUNXI_POWEROFF_GATING_REG(cluster), BIT(core)); - /* Assert CPU power-on reset */ - mmio_clrbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core)); - /* Remove power from the CPU */ - sunxi_cpu_disable_power(cluster, core); + if (sunxi_cpucfg_has_per_cluster_regs()) { + /* Deassert DBGPWRDUP */ + mmio_clrbits_32(SUNXI_CPUCFG_DBG_REG0, BIT(core)); + /* Activate the core output clamps, but not for core 0. */ + if (core != 0) { + mmio_setbits_32(SUNXI_POWEROFF_GATING_REG(cluster), + BIT(core)); + } + /* Assert CPU power-on reset */ + mmio_clrbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core)); + /* Remove power from the CPU */ + sunxi_cpu_disable_power(cluster, core); + } else { + /* power down(?) debug core */ + mmio_clrbits_32(SUNXI_C0_CPU_CTRL_REG(core), BIT(8)); + /* ??? Activate the core output clamps, but not for core 0 */ + if (core != 0) { + mmio_setbits_32(SUNXI_CPU_UNK_REG(core), BIT(1)); + } + /* ??? Assert CPU power-on reset ??? */ + mmio_clrbits_32(SUNXI_CPU_UNK_REG(core), BIT(0)); + /* Remove power from the CPU */ + sunxi_cpu_disable_power(cluster, core); + } } void sunxi_cpu_on(u_register_t mpidr) @@ -71,23 +92,45 @@ void sunxi_cpu_on(u_register_t mpidr) VERBOSE("PSCI: Powering on cluster %d core %d\n", cluster, core); - /* Assert CPU core reset */ - mmio_clrbits_32(SUNXI_CPUCFG_RST_CTRL_REG(cluster), BIT(core)); - /* Assert CPU power-on reset */ - mmio_clrbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core)); - /* Set CPU to start in AArch64 mode */ - mmio_setbits_32(SUNXI_AA64nAA32_REG(cluster), - BIT(SUNXI_AA64nAA32_OFFSET + core)); - /* Apply power to the CPU */ - sunxi_cpu_enable_power(cluster, core); - /* Release the core output clamps */ - mmio_clrbits_32(SUNXI_POWEROFF_GATING_REG(cluster), BIT(core)); - /* Deassert CPU power-on reset */ - mmio_setbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core)); - /* Deassert CPU core reset */ - mmio_setbits_32(SUNXI_CPUCFG_RST_CTRL_REG(cluster), BIT(core)); - /* Assert DBGPWRDUP */ - mmio_setbits_32(SUNXI_CPUCFG_DBG_REG0, BIT(core)); + if (sunxi_cpucfg_has_per_cluster_regs()) { + /* Assert CPU core reset */ + mmio_clrbits_32(SUNXI_CPUCFG_RST_CTRL_REG(cluster), BIT(core)); + /* Assert CPU power-on reset */ + mmio_clrbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core)); + /* Set CPU to start in AArch64 mode */ + mmio_setbits_32(SUNXI_AA64nAA32_REG(cluster), + BIT(SUNXI_AA64nAA32_OFFSET + core)); + /* Apply power to the CPU */ + sunxi_cpu_enable_power(cluster, core); + /* Release the core output clamps */ + mmio_clrbits_32(SUNXI_POWEROFF_GATING_REG(cluster), BIT(core)); + /* Deassert CPU power-on reset */ + mmio_setbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core)); + /* Deassert CPU core reset */ + mmio_setbits_32(SUNXI_CPUCFG_RST_CTRL_REG(cluster), BIT(core)); + /* Assert DBGPWRDUP */ + mmio_setbits_32(SUNXI_CPUCFG_DBG_REG0, BIT(core)); + } else { + /* Assert CPU core reset */ + mmio_clrbits_32(SUNXI_C0_CPU_CTRL_REG(core), BIT(0)); + /* ??? Assert CPU power-on reset ??? */ + mmio_clrbits_32(SUNXI_CPU_UNK_REG(core), BIT(0)); + + /* Set CPU to start in AArch64 mode */ + mmio_setbits_32(SUNXI_CPU_CTRL_REG(core), BIT(0)); + + /* Apply power to the CPU */ + sunxi_cpu_enable_power(cluster, core); + + /* ??? Release the core output clamps ??? */ + mmio_clrbits_32(SUNXI_CPU_UNK_REG(core), BIT(1)); + /* ??? Deassert CPU power-on reset ??? */ + mmio_setbits_32(SUNXI_CPU_UNK_REG(core), BIT(0)); + /* Deassert CPU core reset */ + mmio_setbits_32(SUNXI_C0_CPU_CTRL_REG(core), BIT(0)); + /* power up(?) debug core */ + mmio_setbits_32(SUNXI_C0_CPU_CTRL_REG(core), BIT(8)); + } } void sunxi_cpu_power_off_others(void) diff --git a/plat/allwinner/common/sunxi_pm.c b/plat/allwinner/common/sunxi_pm.c index 3772b4a57..ebc406b91 100644 --- a/plat/allwinner/common/sunxi_pm.c +++ b/plat/allwinner/common/sunxi_pm.c @@ -25,6 +25,11 @@ bool sunxi_psci_is_scpi(void) } #endif +#ifndef SUNXI_ALT_RVBAR_LO_REG +#define SUNXI_ALT_RVBAR_LO_REG(n) 0 +#define SUNXI_ALT_RVBAR_HI_REG(n) 0 +#endif + int sunxi_validate_ns_entrypoint(uintptr_t ns_entrypoint) { /* The non-secure entry point must be in DRAM */ @@ -42,10 +47,17 @@ int plat_setup_psci_ops(uintptr_t sec_entrypoint, /* Program all CPU entry points. */ for (unsigned int cpu = 0; cpu < PLATFORM_CORE_COUNT; ++cpu) { - mmio_write_32(SUNXI_CPUCFG_RVBAR_LO_REG(cpu), - sec_entrypoint & 0xffffffff); - mmio_write_32(SUNXI_CPUCFG_RVBAR_HI_REG(cpu), - sec_entrypoint >> 32); + if (sunxi_cpucfg_has_per_cluster_regs()) { + mmio_write_32(SUNXI_CPUCFG_RVBAR_LO_REG(cpu), + sec_entrypoint & 0xffffffff); + mmio_write_32(SUNXI_CPUCFG_RVBAR_HI_REG(cpu), + sec_entrypoint >> 32); + } else { + mmio_write_32(SUNXI_ALT_RVBAR_LO_REG(cpu), + sec_entrypoint & 0xffffffff); + mmio_write_32(SUNXI_ALT_RVBAR_HI_REG(cpu), + sec_entrypoint >> 32); + } } if (sunxi_set_scpi_psci_ops(psci_ops) == 0) {