]> git.baikalelectronics.ru Git - arm-tf.git/commitdiff
feat(allwinner): add support for Allwinner T507 SoC
authorMikhail Kalashnikov <iuncuim@gmail.com>
Mon, 27 Mar 2023 15:36:14 +0000 (18:36 +0300)
committerAndre Przywara <andre.przywara@arm.com>
Wed, 26 Apr 2023 16:45:29 +0000 (17:45 +0100)
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
plat/allwinner/common/sunxi_cpu_ops.c
plat/allwinner/common/sunxi_pm.c

index 3e9ce511f50191a3113cf0f6d5c5cc08b1f352ec..8e967dcde06d3f85d3143b654a176c528c3f4865 100644 (file)
@@ -23,6 +23,8 @@ There is one build target per supported SoC:
 +------+-------------------+
 | H313 | sun50i_h616       |
 +------+-------------------+
+| T507 | sun50i_h616       |
++------+-------------------+
 | R329 | sun50i_r329       |
 +------+-------------------+
 
index 46e7090ab71a27ee23d63fcac35c522a712252f4..30841e2eab6f6eb06f34c6181cd647b01c68b557 100644 (file)
 #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)
index 3772b4a572d82883aecd9a3627ec46b319f52106..ebc406b91ad4db8d73c0afce21a9ff2a05dd23e7 100644 (file)
@@ -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) {