From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751890AbeBWNih (ORCPT ); Fri, 23 Feb 2018 08:38:37 -0500 Received: from mail.free-electrons.com ([62.4.15.54]:48910 "EHLO mail.free-electrons.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751863AbeBWNif (ORCPT ); Fri, 23 Feb 2018 08:38:35 -0500 From: =?UTF-8?q?Myl=C3=A8ne=20Josserand?= To: maxime.ripard@bootlin.com, linux@armlinux.org.uk, wens@csie.org, robh+dt@kernel.org, mark.rutland@arm.com Cc: devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, clabbe.montjoie@gmail.com, thomas.petazzoni@bootlin.com, mylene.josserand@bootlin.com, quentin.schulz@bootlin.com Subject: [PATCH v4 03/10] ARM: sun8i: smp: Add support for A83T Date: Fri, 23 Feb 2018 14:37:35 +0100 Message-Id: <20180223133742.26044-4-mylene.josserand@bootlin.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180223133742.26044-1-mylene.josserand@bootlin.com> References: <20180223133742.26044-1-mylene.josserand@bootlin.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add the support for A83T. A83T SoC has an additional register than A80 to handle CPU configurations: R_CPUS_CFG. Information about the register comes from Allwinner's BSP driver. An important difference is the Power Off Gating register for clusters which is BIT(4) in case of SUN9I-A80 and BIT(0) in case of SUN8I-A83T. Signed-off-by: Mylène Josserand --- arch/arm/mach-sunxi/Kconfig | 2 +- arch/arm/mach-sunxi/mc_smp.c | 168 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 162 insertions(+), 8 deletions(-) diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig index ce53ceaf4cc5..a0ad35c41c02 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig @@ -51,7 +51,7 @@ config MACH_SUN9I config ARCH_SUNXI_MC_SMP bool depends on SMP - default MACH_SUN9I + default y if MACH_SUN9I || MACH_SUN8I select ARM_CCI400_PORT_CTRL select ARM_CPU_SUSPEND diff --git a/arch/arm/mach-sunxi/mc_smp.c b/arch/arm/mach-sunxi/mc_smp.c index de02e5662557..3bd9066a1422 100644 --- a/arch/arm/mach-sunxi/mc_smp.c +++ b/arch/arm/mach-sunxi/mc_smp.c @@ -55,22 +55,32 @@ #define CPUCFG_CX_RST_CTRL_L2_RST BIT(8) #define CPUCFG_CX_RST_CTRL_CX_RST(n) BIT(4 + (n)) #define CPUCFG_CX_RST_CTRL_CORE_RST(n) BIT(n) +#define CPUCFG_CX_RST_CTRL_CORE_RST_ALL (0xf << 0) #define PRCM_CPU_PO_RST_CTRL(c) (0x4 + 0x4 * (c)) #define PRCM_CPU_PO_RST_CTRL_CORE(n) BIT(n) #define PRCM_CPU_PO_RST_CTRL_CORE_ALL 0xf #define PRCM_PWROFF_GATING_REG(c) (0x100 + 0x4 * (c)) +/* The power off register for clusters are different from SUN9I and SUN8I */ +#define PRCM_PWROFF_GATING_REG_CLUSTER_SUN8I BIT(0) #define PRCM_PWROFF_GATING_REG_CLUSTER_SUN9I BIT(4) #define PRCM_PWROFF_GATING_REG_CORE(n) BIT(n) #define PRCM_PWR_SWITCH_REG(c, cpu) (0x140 + 0x10 * (c) + 0x4 * (cpu)) #define PRCM_CPU_SOFT_ENTRY_REG 0x164 +/* R_CPUCFG registers, specific to SUN8I */ +#define R_CPUCFG_CLUSTER_PO_RST_CTRL(c) (0x30 + (c) * 0x4) +#define R_CPUCFG_CLUSTER_PO_RST_CTRL_CORE(n) BIT(n) +#define R_CPUCFG_CPU_SOFT_ENTRY_REG 0x01a4 + #define CPU0_SUPPORT_HOTPLUG_MAGIC0 0xFA50392F #define CPU0_SUPPORT_HOTPLUG_MAGIC1 0x790DCA3A static void __iomem *cpucfg_base; +static void __iomem *r_cpucfg_base; static void __iomem *prcm_base; static void __iomem *sram_b_smp_base; +static bool is_sun9i; static bool sunxi_core_is_cortex_a15(unsigned int core, unsigned int cluster) { @@ -157,6 +167,16 @@ static int sunxi_cpu_powerup(unsigned int cpu, unsigned int cluster) reg &= ~PRCM_CPU_PO_RST_CTRL_CORE(cpu); writel(reg, prcm_base + PRCM_CPU_PO_RST_CTRL(cluster)); + if (r_cpucfg_base) { + /* assert cpu power-on reset */ + reg = readl(r_cpucfg_base + + R_CPUCFG_CLUSTER_PO_RST_CTRL(cluster)); + reg &= ~(R_CPUCFG_CLUSTER_PO_RST_CTRL_CORE(cpu)); + writel(reg, r_cpucfg_base + + R_CPUCFG_CLUSTER_PO_RST_CTRL(cluster)); + udelay(10); + } + /* Cortex-A7: hold L1 reset disable signal low */ if (!sunxi_core_is_cortex_a15(cpu, cluster)) { reg = readl(cpucfg_base + CPUCFG_CX_CTRL_REG0(cluster)); @@ -180,17 +200,37 @@ static int sunxi_cpu_powerup(unsigned int cpu, unsigned int cluster) /* open power switch */ sunxi_cpu_power_switch_set(cpu, cluster, true); + /* Handle A83T bit swap */ + if (!is_sun9i) { + if (cpu == 0) + cpu = 4; + } + /* clear processor power gate */ reg = readl(prcm_base + PRCM_PWROFF_GATING_REG(cluster)); reg &= ~PRCM_PWROFF_GATING_REG_CORE(cpu); writel(reg, prcm_base + PRCM_PWROFF_GATING_REG(cluster)); udelay(20); + if (!is_sun9i) { + if (cpu == 4) + cpu = 0; + } + /* de-assert processor power-on reset */ reg = readl(prcm_base + PRCM_CPU_PO_RST_CTRL(cluster)); reg |= PRCM_CPU_PO_RST_CTRL_CORE(cpu); writel(reg, prcm_base + PRCM_CPU_PO_RST_CTRL(cluster)); + if (r_cpucfg_base) { + reg = readl(r_cpucfg_base + + R_CPUCFG_CLUSTER_PO_RST_CTRL(cluster)); + reg |= R_CPUCFG_CLUSTER_PO_RST_CTRL_CORE(cpu); + writel(reg, r_cpucfg_base + + R_CPUCFG_CLUSTER_PO_RST_CTRL(cluster)); + udelay(10); + } + /* de-assert all processor resets */ reg = readl(cpucfg_base + CPUCFG_CX_RST_CTRL(cluster)); reg |= CPUCFG_CX_RST_CTRL_DBG_RST(cpu); @@ -212,6 +252,14 @@ static int sunxi_cluster_powerup(unsigned int cluster) if (cluster >= SUNXI_NR_CLUSTERS) return -EINVAL; + /* For A83T, assert cluster cores resets */ + if (!is_sun9i) { + reg = readl(cpucfg_base + CPUCFG_CX_RST_CTRL(cluster)); + reg &= ~CPUCFG_CX_RST_CTRL_CORE_RST_ALL; /* Core Reset */ + writel(reg, cpucfg_base + CPUCFG_CX_RST_CTRL(cluster)); + udelay(10); + } + /* assert ACINACTM */ reg = readl(cpucfg_base + CPUCFG_CX_CTRL_REG1(cluster)); reg |= CPUCFG_CX_CTRL_REG1_ACINACTM; @@ -222,6 +270,16 @@ static int sunxi_cluster_powerup(unsigned int cluster) reg &= ~PRCM_CPU_PO_RST_CTRL_CORE_ALL; writel(reg, prcm_base + PRCM_CPU_PO_RST_CTRL(cluster)); + /* assert cluster cores resets */ + if (r_cpucfg_base) { + reg = readl(r_cpucfg_base + + R_CPUCFG_CLUSTER_PO_RST_CTRL(cluster)); + reg &= ~CPUCFG_CX_RST_CTRL_CORE_RST_ALL; + writel(reg, r_cpucfg_base + + R_CPUCFG_CLUSTER_PO_RST_CTRL(cluster)); + udelay(10); + } + /* assert cluster resets */ reg = readl(cpucfg_base + CPUCFG_CX_RST_CTRL(cluster)); reg &= ~CPUCFG_CX_RST_CTRL_DBG_SOC_RST; @@ -252,7 +310,10 @@ static int sunxi_cluster_powerup(unsigned int cluster) /* clear cluster power gate */ reg = readl(prcm_base + PRCM_PWROFF_GATING_REG(cluster)); - reg &= ~PRCM_PWROFF_GATING_REG_CLUSTER_SUN9I; + if (is_sun9i) + reg &= ~PRCM_PWROFF_GATING_REG_CLUSTER_SUN9I; + else + reg &= ~PRCM_PWROFF_GATING_REG_CLUSTER_SUN8I; writel(reg, prcm_base + PRCM_PWROFF_GATING_REG(cluster)); udelay(20); @@ -516,7 +577,8 @@ static int sunxi_cluster_powerdown(unsigned int cluster) /* gate cluster power */ pr_debug("%s: gate cluster power\n", __func__); reg = readl(prcm_base + PRCM_PWROFF_GATING_REG(cluster)); - reg |= PRCM_PWROFF_GATING_REG_CLUSTER_SUN9I; + if (is_sun9i) + reg |= PRCM_PWROFF_GATING_REG_CLUSTER_SUN9I; writel(reg, prcm_base + PRCM_PWROFF_GATING_REG(cluster)); udelay(20); @@ -762,12 +824,92 @@ static void sun9i_iounmap(void) iounmap(prcm_base); } +static int sun8i_dt_parsing(struct resource res) +{ + struct device_node *node, *cpucfg_node; + int ret; + + node = of_find_compatible_node(NULL, NULL, + "allwinner,sun8i-a83t-r-ccu"); + if (!node) + return -ENODEV; + + /* + * Unfortunately we can not request the I/O region for the PRCM. + * It is shared with the PRCM clock. + */ + prcm_base = of_iomap(node, 0); + of_node_put(node); + if (!prcm_base) { + pr_err("%s: failed to map PRCM registers\n", __func__); + iounmap(prcm_base); + return -ENOMEM; + } + + cpucfg_node = of_find_compatible_node(NULL, NULL, + "allwinner,sun8i-a83t-cpucfg"); + if (!cpucfg_node) { + ret = -ENODEV; + pr_err("%s: CPUCFG not available\n", __func__); + goto err_unmap_prcm; + } + + cpucfg_base = of_io_request_and_map(cpucfg_node, 0, "sunxi-mc-smp"); + if (IS_ERR(cpucfg_base)) { + ret = PTR_ERR(cpucfg_base); + pr_err("%s: failed to map CPUCFG registers: %d\n", + __func__, ret); + goto err_put_cpucfg_node; + } + + node = of_find_compatible_node(NULL, NULL, + "allwinner,sun8i-a83t-r-cpucfg"); + if (!node) { + ret = -ENODEV; + goto err_unmap_release_cpucfg; + } + + r_cpucfg_base = of_iomap(node, 0); + if (!r_cpucfg_base) { + pr_err("%s: failed to map R-CPUCFG registers\n", + __func__); + ret = -ENOMEM; + goto err_put_node; + } + + /* We don't need the CPUCFG device node anymore */ + of_node_put(cpucfg_node); + of_node_put(node); + + return 0; +err_put_node: + of_node_put(node); +err_unmap_release_cpucfg: + iounmap(cpucfg_base); + of_address_to_resource(cpucfg_node, 0, &res); + release_mem_region(res.start, resource_size(&res)); +err_put_cpucfg_node: + of_node_put(cpucfg_node); +err_unmap_prcm: + iounmap(prcm_base); + + return ret; +} + +static void sun8i_iounmap(void) +{ + iounmap(r_cpucfg_base); + iounmap(cpucfg_base); + iounmap(prcm_base); +} + static int __init sunxi_mc_smp_init(void) { struct resource res; int ret; - if (!of_machine_is_compatible("allwinner,sun9i-a80")) + if (!of_machine_is_compatible("allwinner,sun9i-a80") && + !of_machine_is_compatible("allwinner,sun8i-a83t")) return -ENODEV; if (!sunxi_mc_smp_cpu_table_init()) @@ -778,7 +920,12 @@ static int __init sunxi_mc_smp_init(void) return -ENODEV; } - ret = sun9i_dt_parsing(res); + is_sun9i = of_machine_is_compatible("allwinner,sun9i-a80"); + + if (is_sun9i) + ret = sun9i_dt_parsing(res); + else + ret = sun8i_dt_parsing(res); if (ret) { pr_err("%s: failed to parse DT: %d\n", __func__, ret); return ret; @@ -789,13 +936,20 @@ static int __init sunxi_mc_smp_init(void) if (ret) { pr_err("%s: failed to configure boot cluster: %d\n", __func__, ret); - sun9i_iounmap(); + if (is_sun9i) + sun9i_iounmap(); + else + sun8i_iounmap(); return ret; } /* Set the hardware entry point address */ - writel(__pa_symbol(sunxi_mc_smp_secondary_startup), - prcm_base + PRCM_CPU_SOFT_ENTRY_REG); + if (is_sun9i) + writel(__pa_symbol(sunxi_mc_smp_secondary_startup), + prcm_base + PRCM_CPU_SOFT_ENTRY_REG); + else + writel(__pa_symbol(sunxi_mc_smp_secondary_startup), + r_cpucfg_base + R_CPUCFG_CPU_SOFT_ENTRY_REG); /* Actually enable multi cluster SMP */ smp_set_ops(&sunxi_mc_smp_smp_ops); -- 2.11.0 From mboxrd@z Thu Jan 1 00:00:00 1970 From: =?UTF-8?q?Myl=C3=A8ne=20Josserand?= Subject: [PATCH v4 03/10] ARM: sun8i: smp: Add support for A83T Date: Fri, 23 Feb 2018 14:37:35 +0100 Message-ID: <20180223133742.26044-4-mylene.josserand@bootlin.com> References: <20180223133742.26044-1-mylene.josserand@bootlin.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <20180223133742.26044-1-mylene.josserand@bootlin.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=m.gmane.org@lists.infradead.org To: maxime.ripard@bootlin.com, linux@armlinux.org.uk, wens@csie.org, robh+dt@kernel.org, mark.rutland@arm.com Cc: devicetree@vger.kernel.org, quentin.schulz@bootlin.com, linux-kernel@vger.kernel.org, clabbe.montjoie@gmail.com, thomas.petazzoni@bootlin.com, mylene.josserand@bootlin.com, linux-arm-kernel@lists.infradead.org List-Id: devicetree@vger.kernel.org QWRkIHRoZSBzdXBwb3J0IGZvciBBODNULgoKQTgzVCBTb0MgaGFzIGFuIGFkZGl0aW9uYWwgcmVn aXN0ZXIgdGhhbiBBODAgdG8gaGFuZGxlIENQVSBjb25maWd1cmF0aW9uczoKUl9DUFVTX0NGRy4g SW5mb3JtYXRpb24gYWJvdXQgdGhlIHJlZ2lzdGVyIGNvbWVzIGZyb20gQWxsd2lubmVyJ3MgQlNQ CmRyaXZlci4KQW4gaW1wb3J0YW50IGRpZmZlcmVuY2UgaXMgdGhlIFBvd2VyIE9mZiBHYXRpbmcg cmVnaXN0ZXIgZm9yIGNsdXN0ZXJzCndoaWNoIGlzIEJJVCg0KSBpbiBjYXNlIG9mIFNVTjlJLUE4 MCBhbmQgQklUKDApIGluIGNhc2Ugb2YgU1VOOEktQTgzVC4KClNpZ25lZC1vZmYtYnk6IE15bMOo bmUgSm9zc2VyYW5kIDxteWxlbmUuam9zc2VyYW5kQGJvb3RsaW4uY29tPgotLS0KIGFyY2gvYXJt L21hY2gtc3VueGkvS2NvbmZpZyAgfCAgIDIgKy0KIGFyY2gvYXJtL21hY2gtc3VueGkvbWNfc21w LmMgfCAxNjggKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKystLQogMiBm aWxlcyBjaGFuZ2VkLCAxNjIgaW5zZXJ0aW9ucygrKSwgOCBkZWxldGlvbnMoLSkKCmRpZmYgLS1n aXQgYS9hcmNoL2FybS9tYWNoLXN1bnhpL0tjb25maWcgYi9hcmNoL2FybS9tYWNoLXN1bnhpL0tj b25maWcKaW5kZXggY2U1M2NlYWY0Y2M1Li5hMGFkMzVjNDFjMDIgMTAwNjQ0Ci0tLSBhL2FyY2gv YXJtL21hY2gtc3VueGkvS2NvbmZpZworKysgYi9hcmNoL2FybS9tYWNoLXN1bnhpL0tjb25maWcK QEAgLTUxLDcgKzUxLDcgQEAgY29uZmlnIE1BQ0hfU1VOOUkKIGNvbmZpZyBBUkNIX1NVTlhJX01D X1NNUAogCWJvb2wKIAlkZXBlbmRzIG9uIFNNUAotCWRlZmF1bHQgTUFDSF9TVU45SQorCWRlZmF1 bHQgeSBpZiBNQUNIX1NVTjlJIHx8IE1BQ0hfU1VOOEkKIAlzZWxlY3QgQVJNX0NDSTQwMF9QT1JU X0NUUkwKIAlzZWxlY3QgQVJNX0NQVV9TVVNQRU5ECiAKZGlmZiAtLWdpdCBhL2FyY2gvYXJtL21h Y2gtc3VueGkvbWNfc21wLmMgYi9hcmNoL2FybS9tYWNoLXN1bnhpL21jX3NtcC5jCmluZGV4IGRl MDJlNTY2MjU1Ny4uM2JkOTA2NmExNDIyIDEwMDY0NAotLS0gYS9hcmNoL2FybS9tYWNoLXN1bnhp L21jX3NtcC5jCisrKyBiL2FyY2gvYXJtL21hY2gtc3VueGkvbWNfc21wLmMKQEAgLTU1LDIyICs1 NSwzMiBAQAogI2RlZmluZSBDUFVDRkdfQ1hfUlNUX0NUUkxfTDJfUlNUCUJJVCg4KQogI2RlZmlu ZSBDUFVDRkdfQ1hfUlNUX0NUUkxfQ1hfUlNUKG4pCUJJVCg0ICsgKG4pKQogI2RlZmluZSBDUFVD RkdfQ1hfUlNUX0NUUkxfQ09SRV9SU1QobikJQklUKG4pCisjZGVmaW5lIENQVUNGR19DWF9SU1Rf Q1RSTF9DT1JFX1JTVF9BTEwJKDB4ZiA8PCAwKQogCiAjZGVmaW5lIFBSQ01fQ1BVX1BPX1JTVF9D VFJMKGMpCQkoMHg0ICsgMHg0ICogKGMpKQogI2RlZmluZSBQUkNNX0NQVV9QT19SU1RfQ1RSTF9D T1JFKG4pCUJJVChuKQogI2RlZmluZSBQUkNNX0NQVV9QT19SU1RfQ1RSTF9DT1JFX0FMTAkweGYK ICNkZWZpbmUgUFJDTV9QV1JPRkZfR0FUSU5HX1JFRyhjKQkoMHgxMDAgKyAweDQgKiAoYykpCisv KiBUaGUgcG93ZXIgb2ZmIHJlZ2lzdGVyIGZvciBjbHVzdGVycyBhcmUgZGlmZmVyZW50IGZyb20g U1VOOUkgYW5kIFNVTjhJICovCisjZGVmaW5lIFBSQ01fUFdST0ZGX0dBVElOR19SRUdfQ0xVU1RF Ul9TVU44SQlCSVQoMCkKICNkZWZpbmUgUFJDTV9QV1JPRkZfR0FUSU5HX1JFR19DTFVTVEVSX1NV TjlJCUJJVCg0KQogI2RlZmluZSBQUkNNX1BXUk9GRl9HQVRJTkdfUkVHX0NPUkUobikJQklUKG4p CiAjZGVmaW5lIFBSQ01fUFdSX1NXSVRDSF9SRUcoYywgY3B1KQkoMHgxNDAgKyAweDEwICogKGMp ICsgMHg0ICogKGNwdSkpCiAjZGVmaW5lIFBSQ01fQ1BVX1NPRlRfRU5UUllfUkVHCQkweDE2NAog CisvKiBSX0NQVUNGRyByZWdpc3RlcnMsIHNwZWNpZmljIHRvIFNVTjhJICovCisjZGVmaW5lIFJf Q1BVQ0ZHX0NMVVNURVJfUE9fUlNUX0NUUkwoYykJKDB4MzAgKyAoYykgKiAweDQpCisjZGVmaW5l IFJfQ1BVQ0ZHX0NMVVNURVJfUE9fUlNUX0NUUkxfQ09SRShuKQlCSVQobikKKyNkZWZpbmUgUl9D UFVDRkdfQ1BVX1NPRlRfRU5UUllfUkVHCTB4MDFhNAorCiAjZGVmaW5lIENQVTBfU1VQUE9SVF9I T1RQTFVHX01BR0lDMAkweEZBNTAzOTJGCiAjZGVmaW5lIENQVTBfU1VQUE9SVF9IT1RQTFVHX01B R0lDMQkweDc5MERDQTNBCiAKIHN0YXRpYyB2b2lkIF9faW9tZW0gKmNwdWNmZ19iYXNlOworc3Rh dGljIHZvaWQgX19pb21lbSAqcl9jcHVjZmdfYmFzZTsKIHN0YXRpYyB2b2lkIF9faW9tZW0gKnBy Y21fYmFzZTsKIHN0YXRpYyB2b2lkIF9faW9tZW0gKnNyYW1fYl9zbXBfYmFzZTsKK3N0YXRpYyBi b29sIGlzX3N1bjlpOwogCiBzdGF0aWMgYm9vbCBzdW54aV9jb3JlX2lzX2NvcnRleF9hMTUodW5z aWduZWQgaW50IGNvcmUsIHVuc2lnbmVkIGludCBjbHVzdGVyKQogewpAQCAtMTU3LDYgKzE2Nywx NiBAQCBzdGF0aWMgaW50IHN1bnhpX2NwdV9wb3dlcnVwKHVuc2lnbmVkIGludCBjcHUsIHVuc2ln bmVkIGludCBjbHVzdGVyKQogCXJlZyAmPSB+UFJDTV9DUFVfUE9fUlNUX0NUUkxfQ09SRShjcHUp OwogCXdyaXRlbChyZWcsIHByY21fYmFzZSArIFBSQ01fQ1BVX1BPX1JTVF9DVFJMKGNsdXN0ZXIp KTsKIAorCWlmIChyX2NwdWNmZ19iYXNlKSB7CisJCS8qIGFzc2VydCBjcHUgcG93ZXItb24gcmVz ZXQgKi8KKwkJcmVnICA9IHJlYWRsKHJfY3B1Y2ZnX2Jhc2UgKworCQkJICAgICBSX0NQVUNGR19D TFVTVEVSX1BPX1JTVF9DVFJMKGNsdXN0ZXIpKTsKKwkJcmVnICY9IH4oUl9DUFVDRkdfQ0xVU1RF Ul9QT19SU1RfQ1RSTF9DT1JFKGNwdSkpOworCQl3cml0ZWwocmVnLCByX2NwdWNmZ19iYXNlICsK KwkJICAgICAgIFJfQ1BVQ0ZHX0NMVVNURVJfUE9fUlNUX0NUUkwoY2x1c3RlcikpOworCQl1ZGVs YXkoMTApOworCX0KKwogCS8qIENvcnRleC1BNzogaG9sZCBMMSByZXNldCBkaXNhYmxlIHNpZ25h bCBsb3cgKi8KIAlpZiAoIXN1bnhpX2NvcmVfaXNfY29ydGV4X2ExNShjcHUsIGNsdXN0ZXIpKSB7 CiAJCXJlZyA9IHJlYWRsKGNwdWNmZ19iYXNlICsgQ1BVQ0ZHX0NYX0NUUkxfUkVHMChjbHVzdGVy KSk7CkBAIC0xODAsMTcgKzIwMCwzNyBAQCBzdGF0aWMgaW50IHN1bnhpX2NwdV9wb3dlcnVwKHVu c2lnbmVkIGludCBjcHUsIHVuc2lnbmVkIGludCBjbHVzdGVyKQogCS8qIG9wZW4gcG93ZXIgc3dp dGNoICovCiAJc3VueGlfY3B1X3Bvd2VyX3N3aXRjaF9zZXQoY3B1LCBjbHVzdGVyLCB0cnVlKTsK IAorCS8qIEhhbmRsZSBBODNUIGJpdCBzd2FwICovCisJaWYgKCFpc19zdW45aSkgeworCQlpZiAo Y3B1ID09IDApCisJCQljcHUgPSA0OworCX0KKwogCS8qIGNsZWFyIHByb2Nlc3NvciBwb3dlciBn YXRlICovCiAJcmVnID0gcmVhZGwocHJjbV9iYXNlICsgUFJDTV9QV1JPRkZfR0FUSU5HX1JFRyhj bHVzdGVyKSk7CiAJcmVnICY9IH5QUkNNX1BXUk9GRl9HQVRJTkdfUkVHX0NPUkUoY3B1KTsKIAl3 cml0ZWwocmVnLCBwcmNtX2Jhc2UgKyBQUkNNX1BXUk9GRl9HQVRJTkdfUkVHKGNsdXN0ZXIpKTsK IAl1ZGVsYXkoMjApOwogCisJaWYgKCFpc19zdW45aSkgeworCQlpZiAoY3B1ID09IDQpCisJCQlj cHUgPSAwOworCX0KKwogCS8qIGRlLWFzc2VydCBwcm9jZXNzb3IgcG93ZXItb24gcmVzZXQgKi8K IAlyZWcgPSByZWFkbChwcmNtX2Jhc2UgKyBQUkNNX0NQVV9QT19SU1RfQ1RSTChjbHVzdGVyKSk7 CiAJcmVnIHw9IFBSQ01fQ1BVX1BPX1JTVF9DVFJMX0NPUkUoY3B1KTsKIAl3cml0ZWwocmVnLCBw cmNtX2Jhc2UgKyBQUkNNX0NQVV9QT19SU1RfQ1RSTChjbHVzdGVyKSk7CiAKKwlpZiAocl9jcHVj ZmdfYmFzZSkgeworCQlyZWcgID0gcmVhZGwocl9jcHVjZmdfYmFzZSArCisJCQkgICAgIFJfQ1BV Q0ZHX0NMVVNURVJfUE9fUlNUX0NUUkwoY2x1c3RlcikpOworCQlyZWcgfD0gUl9DUFVDRkdfQ0xV U1RFUl9QT19SU1RfQ1RSTF9DT1JFKGNwdSk7CisJCXdyaXRlbChyZWcsIHJfY3B1Y2ZnX2Jhc2Ug KworCQkgICAgICAgUl9DUFVDRkdfQ0xVU1RFUl9QT19SU1RfQ1RSTChjbHVzdGVyKSk7CisJCXVk ZWxheSgxMCk7CisJfQorCiAJLyogZGUtYXNzZXJ0IGFsbCBwcm9jZXNzb3IgcmVzZXRzICovCiAJ cmVnID0gcmVhZGwoY3B1Y2ZnX2Jhc2UgKyBDUFVDRkdfQ1hfUlNUX0NUUkwoY2x1c3RlcikpOwog CXJlZyB8PSBDUFVDRkdfQ1hfUlNUX0NUUkxfREJHX1JTVChjcHUpOwpAQCAtMjEyLDYgKzI1Miwx NCBAQCBzdGF0aWMgaW50IHN1bnhpX2NsdXN0ZXJfcG93ZXJ1cCh1bnNpZ25lZCBpbnQgY2x1c3Rl cikKIAlpZiAoY2x1c3RlciA+PSBTVU5YSV9OUl9DTFVTVEVSUykKIAkJcmV0dXJuIC1FSU5WQUw7 CiAKKwkvKiBGb3IgQTgzVCwgYXNzZXJ0IGNsdXN0ZXIgY29yZXMgcmVzZXRzICovCisJaWYgKCFp c19zdW45aSkgeworCQlyZWcgPSByZWFkbChjcHVjZmdfYmFzZSArIENQVUNGR19DWF9SU1RfQ1RS TChjbHVzdGVyKSk7CisJCXJlZyAmPSB+Q1BVQ0ZHX0NYX1JTVF9DVFJMX0NPUkVfUlNUX0FMTDsg ICAvKiBDb3JlIFJlc2V0ICAgICovCisJCXdyaXRlbChyZWcsIGNwdWNmZ19iYXNlICsgQ1BVQ0ZH X0NYX1JTVF9DVFJMKGNsdXN0ZXIpKTsKKwkJdWRlbGF5KDEwKTsKKwl9CisKIAkvKiBhc3NlcnQg QUNJTkFDVE0gKi8KIAlyZWcgPSByZWFkbChjcHVjZmdfYmFzZSArIENQVUNGR19DWF9DVFJMX1JF RzEoY2x1c3RlcikpOwogCXJlZyB8PSBDUFVDRkdfQ1hfQ1RSTF9SRUcxX0FDSU5BQ1RNOwpAQCAt MjIyLDYgKzI3MCwxNiBAQCBzdGF0aWMgaW50IHN1bnhpX2NsdXN0ZXJfcG93ZXJ1cCh1bnNpZ25l ZCBpbnQgY2x1c3RlcikKIAlyZWcgJj0gflBSQ01fQ1BVX1BPX1JTVF9DVFJMX0NPUkVfQUxMOwog CXdyaXRlbChyZWcsIHByY21fYmFzZSArIFBSQ01fQ1BVX1BPX1JTVF9DVFJMKGNsdXN0ZXIpKTsK IAorCS8qIGFzc2VydCBjbHVzdGVyIGNvcmVzIHJlc2V0cyAqLworCWlmIChyX2NwdWNmZ19iYXNl KSB7CisJCXJlZyAgPSByZWFkbChyX2NwdWNmZ19iYXNlICsKKwkJCSAgICAgUl9DUFVDRkdfQ0xV U1RFUl9QT19SU1RfQ1RSTChjbHVzdGVyKSk7CisJCXJlZyAmPSB+Q1BVQ0ZHX0NYX1JTVF9DVFJM X0NPUkVfUlNUX0FMTDsKKwkJd3JpdGVsKHJlZywgcl9jcHVjZmdfYmFzZSArCisJCSAgICAgICBS X0NQVUNGR19DTFVTVEVSX1BPX1JTVF9DVFJMKGNsdXN0ZXIpKTsKKwkJdWRlbGF5KDEwKTsKKwl9 CisKIAkvKiBhc3NlcnQgY2x1c3RlciByZXNldHMgKi8KIAlyZWcgPSByZWFkbChjcHVjZmdfYmFz ZSArIENQVUNGR19DWF9SU1RfQ1RSTChjbHVzdGVyKSk7CiAJcmVnICY9IH5DUFVDRkdfQ1hfUlNU X0NUUkxfREJHX1NPQ19SU1Q7CkBAIC0yNTIsNyArMzEwLDEwIEBAIHN0YXRpYyBpbnQgc3VueGlf Y2x1c3Rlcl9wb3dlcnVwKHVuc2lnbmVkIGludCBjbHVzdGVyKQogCiAJLyogY2xlYXIgY2x1c3Rl ciBwb3dlciBnYXRlICovCiAJcmVnID0gcmVhZGwocHJjbV9iYXNlICsgUFJDTV9QV1JPRkZfR0FU SU5HX1JFRyhjbHVzdGVyKSk7Ci0JcmVnICY9IH5QUkNNX1BXUk9GRl9HQVRJTkdfUkVHX0NMVVNU RVJfU1VOOUk7CisJaWYgKGlzX3N1bjlpKQorCQlyZWcgJj0gflBSQ01fUFdST0ZGX0dBVElOR19S RUdfQ0xVU1RFUl9TVU45STsKKwllbHNlCisJCXJlZyAmPSB+UFJDTV9QV1JPRkZfR0FUSU5HX1JF R19DTFVTVEVSX1NVTjhJOwogCXdyaXRlbChyZWcsIHByY21fYmFzZSArIFBSQ01fUFdST0ZGX0dB VElOR19SRUcoY2x1c3RlcikpOwogCXVkZWxheSgyMCk7CiAKQEAgLTUxNiw3ICs1NzcsOCBAQCBz dGF0aWMgaW50IHN1bnhpX2NsdXN0ZXJfcG93ZXJkb3duKHVuc2lnbmVkIGludCBjbHVzdGVyKQog CS8qIGdhdGUgY2x1c3RlciBwb3dlciAqLwogCXByX2RlYnVnKCIlczogZ2F0ZSBjbHVzdGVyIHBv d2VyXG4iLCBfX2Z1bmNfXyk7CiAJcmVnID0gcmVhZGwocHJjbV9iYXNlICsgUFJDTV9QV1JPRkZf R0FUSU5HX1JFRyhjbHVzdGVyKSk7Ci0JcmVnIHw9IFBSQ01fUFdST0ZGX0dBVElOR19SRUdfQ0xV U1RFUl9TVU45STsKKwlpZiAoaXNfc3VuOWkpCisJCXJlZyB8PSBQUkNNX1BXUk9GRl9HQVRJTkdf UkVHX0NMVVNURVJfU1VOOUk7CiAJd3JpdGVsKHJlZywgcHJjbV9iYXNlICsgUFJDTV9QV1JPRkZf R0FUSU5HX1JFRyhjbHVzdGVyKSk7CiAJdWRlbGF5KDIwKTsKIApAQCAtNzYyLDEyICs4MjQsOTIg QEAgc3RhdGljIHZvaWQgc3VuOWlfaW91bm1hcCh2b2lkKQogCWlvdW5tYXAocHJjbV9iYXNlKTsK IH0KIAorc3RhdGljIGludCBzdW44aV9kdF9wYXJzaW5nKHN0cnVjdCByZXNvdXJjZSByZXMpCit7 CisJc3RydWN0IGRldmljZV9ub2RlICpub2RlLCAqY3B1Y2ZnX25vZGU7CisJaW50IHJldDsKKwor CW5vZGUgPSBvZl9maW5kX2NvbXBhdGlibGVfbm9kZShOVUxMLCBOVUxMLAorCQkJCSAgICAgICAi YWxsd2lubmVyLHN1bjhpLWE4M3Qtci1jY3UiKTsKKwlpZiAoIW5vZGUpCisJCXJldHVybiAtRU5P REVWOworCisJLyoKKwkgKiBVbmZvcnR1bmF0ZWx5IHdlIGNhbiBub3QgcmVxdWVzdCB0aGUgSS9P IHJlZ2lvbiBmb3IgdGhlIFBSQ00uCisJICogSXQgaXMgc2hhcmVkIHdpdGggdGhlIFBSQ00gY2xv Y2suCisJICovCisJcHJjbV9iYXNlID0gb2ZfaW9tYXAobm9kZSwgMCk7CisJb2Zfbm9kZV9wdXQo bm9kZSk7CisJaWYgKCFwcmNtX2Jhc2UpIHsKKwkJcHJfZXJyKCIlczogZmFpbGVkIHRvIG1hcCBQ UkNNIHJlZ2lzdGVyc1xuIiwgX19mdW5jX18pOworCQlpb3VubWFwKHByY21fYmFzZSk7CisJCXJl dHVybiAtRU5PTUVNOworCX0KKworCWNwdWNmZ19ub2RlID0gb2ZfZmluZF9jb21wYXRpYmxlX25v ZGUoTlVMTCwgTlVMTCwKKwkJCQkJICAgICAgImFsbHdpbm5lcixzdW44aS1hODN0LWNwdWNmZyIp OworCWlmICghY3B1Y2ZnX25vZGUpIHsKKwkJcmV0ID0gLUVOT0RFVjsKKwkJcHJfZXJyKCIlczog Q1BVQ0ZHIG5vdCBhdmFpbGFibGVcbiIsIF9fZnVuY19fKTsKKwkJZ290byBlcnJfdW5tYXBfcHJj bTsKKwl9CisKKwljcHVjZmdfYmFzZSA9IG9mX2lvX3JlcXVlc3RfYW5kX21hcChjcHVjZmdfbm9k ZSwgMCwgInN1bnhpLW1jLXNtcCIpOworCWlmIChJU19FUlIoY3B1Y2ZnX2Jhc2UpKSB7CisJCXJl dCA9IFBUUl9FUlIoY3B1Y2ZnX2Jhc2UpOworCQlwcl9lcnIoIiVzOiBmYWlsZWQgdG8gbWFwIENQ VUNGRyByZWdpc3RlcnM6ICVkXG4iLAorCQkgICAgICAgX19mdW5jX18sIHJldCk7CisJCWdvdG8g ZXJyX3B1dF9jcHVjZmdfbm9kZTsKKwl9CisKKwlub2RlID0gb2ZfZmluZF9jb21wYXRpYmxlX25v ZGUoTlVMTCwgTlVMTCwKKwkJCQkgICAgICAgImFsbHdpbm5lcixzdW44aS1hODN0LXItY3B1Y2Zn Iik7CisJaWYgKCFub2RlKSB7CisJCXJldCA9IC1FTk9ERVY7CisJCWdvdG8gZXJyX3VubWFwX3Jl bGVhc2VfY3B1Y2ZnOworCX0KKworCXJfY3B1Y2ZnX2Jhc2UgPSBvZl9pb21hcChub2RlLCAwKTsK KwlpZiAoIXJfY3B1Y2ZnX2Jhc2UpIHsKKwkJcHJfZXJyKCIlczogZmFpbGVkIHRvIG1hcCBSLUNQ VUNGRyByZWdpc3RlcnNcbiIsCisJCSAgICAgICBfX2Z1bmNfXyk7CisJCXJldCA9IC1FTk9NRU07 CisJCWdvdG8gZXJyX3B1dF9ub2RlOworCX0KKworCS8qIFdlIGRvbid0IG5lZWQgdGhlIENQVUNG RyBkZXZpY2Ugbm9kZSBhbnltb3JlICovCisJb2Zfbm9kZV9wdXQoY3B1Y2ZnX25vZGUpOworCW9m X25vZGVfcHV0KG5vZGUpOworCisJcmV0dXJuIDA7CitlcnJfcHV0X25vZGU6CisJb2Zfbm9kZV9w dXQobm9kZSk7CitlcnJfdW5tYXBfcmVsZWFzZV9jcHVjZmc6CisJaW91bm1hcChjcHVjZmdfYmFz ZSk7CisJb2ZfYWRkcmVzc190b19yZXNvdXJjZShjcHVjZmdfbm9kZSwgMCwgJnJlcyk7CisJcmVs ZWFzZV9tZW1fcmVnaW9uKHJlcy5zdGFydCwgcmVzb3VyY2Vfc2l6ZSgmcmVzKSk7CitlcnJfcHV0 X2NwdWNmZ19ub2RlOgorCW9mX25vZGVfcHV0KGNwdWNmZ19ub2RlKTsKK2Vycl91bm1hcF9wcmNt OgorCWlvdW5tYXAocHJjbV9iYXNlKTsKKworCXJldHVybiByZXQ7Cit9CisKK3N0YXRpYyB2b2lk IHN1bjhpX2lvdW5tYXAodm9pZCkKK3sKKwlpb3VubWFwKHJfY3B1Y2ZnX2Jhc2UpOworCWlvdW5t YXAoY3B1Y2ZnX2Jhc2UpOworCWlvdW5tYXAocHJjbV9iYXNlKTsKK30KKwogc3RhdGljIGludCBf X2luaXQgc3VueGlfbWNfc21wX2luaXQodm9pZCkKIHsKIAlzdHJ1Y3QgcmVzb3VyY2UgcmVzOwog CWludCByZXQ7CiAKLQlpZiAoIW9mX21hY2hpbmVfaXNfY29tcGF0aWJsZSgiYWxsd2lubmVyLHN1 bjlpLWE4MCIpKQorCWlmICghb2ZfbWFjaGluZV9pc19jb21wYXRpYmxlKCJhbGx3aW5uZXIsc3Vu OWktYTgwIikgJiYKKwkgICAgIW9mX21hY2hpbmVfaXNfY29tcGF0aWJsZSgiYWxsd2lubmVyLHN1 bjhpLWE4M3QiKSkKIAkJcmV0dXJuIC1FTk9ERVY7CiAKIAlpZiAoIXN1bnhpX21jX3NtcF9jcHVf dGFibGVfaW5pdCgpKQpAQCAtNzc4LDcgKzkyMCwxMiBAQCBzdGF0aWMgaW50IF9faW5pdCBzdW54 aV9tY19zbXBfaW5pdCh2b2lkKQogCQlyZXR1cm4gLUVOT0RFVjsKIAl9CiAKLQlyZXQgPSBzdW45 aV9kdF9wYXJzaW5nKHJlcyk7CisJaXNfc3VuOWkgPSBvZl9tYWNoaW5lX2lzX2NvbXBhdGlibGUo ImFsbHdpbm5lcixzdW45aS1hODAiKTsKKworCWlmIChpc19zdW45aSkKKwkJcmV0ID0gc3VuOWlf ZHRfcGFyc2luZyhyZXMpOworCWVsc2UKKwkJcmV0ID0gc3VuOGlfZHRfcGFyc2luZyhyZXMpOwog CWlmIChyZXQpIHsKIAkJcHJfZXJyKCIlczogZmFpbGVkIHRvIHBhcnNlIERUOiAlZFxuIiwgX19m dW5jX18sIHJldCk7CiAJCXJldHVybiByZXQ7CkBAIC03ODksMTMgKzkzNiwyMCBAQCBzdGF0aWMg aW50IF9faW5pdCBzdW54aV9tY19zbXBfaW5pdCh2b2lkKQogCWlmIChyZXQpIHsKIAkJcHJfZXJy KCIlczogZmFpbGVkIHRvIGNvbmZpZ3VyZSBib290IGNsdXN0ZXI6ICVkXG4iLAogCQkgICAgICAg X19mdW5jX18sIHJldCk7Ci0JCXN1bjlpX2lvdW5tYXAoKTsKKwkJaWYgKGlzX3N1bjlpKQorCQkJ c3VuOWlfaW91bm1hcCgpOworCQllbHNlCisJCQlzdW44aV9pb3VubWFwKCk7CiAJCXJldHVybiBy ZXQ7CiAJfQogCiAJLyogU2V0IHRoZSBoYXJkd2FyZSBlbnRyeSBwb2ludCBhZGRyZXNzICovCi0J d3JpdGVsKF9fcGFfc3ltYm9sKHN1bnhpX21jX3NtcF9zZWNvbmRhcnlfc3RhcnR1cCksCi0JICAg ICAgIHByY21fYmFzZSArIFBSQ01fQ1BVX1NPRlRfRU5UUllfUkVHKTsKKwlpZiAoaXNfc3VuOWkp CisJCXdyaXRlbChfX3BhX3N5bWJvbChzdW54aV9tY19zbXBfc2Vjb25kYXJ5X3N0YXJ0dXApLAor CQkgICAgICAgcHJjbV9iYXNlICsgUFJDTV9DUFVfU09GVF9FTlRSWV9SRUcpOworCWVsc2UKKwkJ d3JpdGVsKF9fcGFfc3ltYm9sKHN1bnhpX21jX3NtcF9zZWNvbmRhcnlfc3RhcnR1cCksCisJCSAg ICAgICByX2NwdWNmZ19iYXNlICsgUl9DUFVDRkdfQ1BVX1NPRlRfRU5UUllfUkVHKTsKIAogCS8q IEFjdHVhbGx5IGVuYWJsZSBtdWx0aSBjbHVzdGVyIFNNUCAqLwogCXNtcF9zZXRfb3BzKCZzdW54 aV9tY19zbXBfc21wX29wcyk7Ci0tIAoyLjExLjAKCgpfX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fXwpsaW51eC1hcm0ta2VybmVsIG1haWxpbmcgbGlzdApsaW51 eC1hcm0ta2VybmVsQGxpc3RzLmluZnJhZGVhZC5vcmcKaHR0cDovL2xpc3RzLmluZnJhZGVhZC5v cmcvbWFpbG1hbi9saXN0aW5mby9saW51eC1hcm0ta2VybmVsCg== From mboxrd@z Thu Jan 1 00:00:00 1970 From: mylene.josserand@bootlin.com (=?UTF-8?q?Myl=C3=A8ne=20Josserand?=) Date: Fri, 23 Feb 2018 14:37:35 +0100 Subject: [PATCH v4 03/10] ARM: sun8i: smp: Add support for A83T In-Reply-To: <20180223133742.26044-1-mylene.josserand@bootlin.com> References: <20180223133742.26044-1-mylene.josserand@bootlin.com> Message-ID: <20180223133742.26044-4-mylene.josserand@bootlin.com> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org Add the support for A83T. A83T SoC has an additional register than A80 to handle CPU configurations: R_CPUS_CFG. Information about the register comes from Allwinner's BSP driver. An important difference is the Power Off Gating register for clusters which is BIT(4) in case of SUN9I-A80 and BIT(0) in case of SUN8I-A83T. Signed-off-by: Myl?ne Josserand --- arch/arm/mach-sunxi/Kconfig | 2 +- arch/arm/mach-sunxi/mc_smp.c | 168 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 162 insertions(+), 8 deletions(-) diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig index ce53ceaf4cc5..a0ad35c41c02 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig @@ -51,7 +51,7 @@ config MACH_SUN9I config ARCH_SUNXI_MC_SMP bool depends on SMP - default MACH_SUN9I + default y if MACH_SUN9I || MACH_SUN8I select ARM_CCI400_PORT_CTRL select ARM_CPU_SUSPEND diff --git a/arch/arm/mach-sunxi/mc_smp.c b/arch/arm/mach-sunxi/mc_smp.c index de02e5662557..3bd9066a1422 100644 --- a/arch/arm/mach-sunxi/mc_smp.c +++ b/arch/arm/mach-sunxi/mc_smp.c @@ -55,22 +55,32 @@ #define CPUCFG_CX_RST_CTRL_L2_RST BIT(8) #define CPUCFG_CX_RST_CTRL_CX_RST(n) BIT(4 + (n)) #define CPUCFG_CX_RST_CTRL_CORE_RST(n) BIT(n) +#define CPUCFG_CX_RST_CTRL_CORE_RST_ALL (0xf << 0) #define PRCM_CPU_PO_RST_CTRL(c) (0x4 + 0x4 * (c)) #define PRCM_CPU_PO_RST_CTRL_CORE(n) BIT(n) #define PRCM_CPU_PO_RST_CTRL_CORE_ALL 0xf #define PRCM_PWROFF_GATING_REG(c) (0x100 + 0x4 * (c)) +/* The power off register for clusters are different from SUN9I and SUN8I */ +#define PRCM_PWROFF_GATING_REG_CLUSTER_SUN8I BIT(0) #define PRCM_PWROFF_GATING_REG_CLUSTER_SUN9I BIT(4) #define PRCM_PWROFF_GATING_REG_CORE(n) BIT(n) #define PRCM_PWR_SWITCH_REG(c, cpu) (0x140 + 0x10 * (c) + 0x4 * (cpu)) #define PRCM_CPU_SOFT_ENTRY_REG 0x164 +/* R_CPUCFG registers, specific to SUN8I */ +#define R_CPUCFG_CLUSTER_PO_RST_CTRL(c) (0x30 + (c) * 0x4) +#define R_CPUCFG_CLUSTER_PO_RST_CTRL_CORE(n) BIT(n) +#define R_CPUCFG_CPU_SOFT_ENTRY_REG 0x01a4 + #define CPU0_SUPPORT_HOTPLUG_MAGIC0 0xFA50392F #define CPU0_SUPPORT_HOTPLUG_MAGIC1 0x790DCA3A static void __iomem *cpucfg_base; +static void __iomem *r_cpucfg_base; static void __iomem *prcm_base; static void __iomem *sram_b_smp_base; +static bool is_sun9i; static bool sunxi_core_is_cortex_a15(unsigned int core, unsigned int cluster) { @@ -157,6 +167,16 @@ static int sunxi_cpu_powerup(unsigned int cpu, unsigned int cluster) reg &= ~PRCM_CPU_PO_RST_CTRL_CORE(cpu); writel(reg, prcm_base + PRCM_CPU_PO_RST_CTRL(cluster)); + if (r_cpucfg_base) { + /* assert cpu power-on reset */ + reg = readl(r_cpucfg_base + + R_CPUCFG_CLUSTER_PO_RST_CTRL(cluster)); + reg &= ~(R_CPUCFG_CLUSTER_PO_RST_CTRL_CORE(cpu)); + writel(reg, r_cpucfg_base + + R_CPUCFG_CLUSTER_PO_RST_CTRL(cluster)); + udelay(10); + } + /* Cortex-A7: hold L1 reset disable signal low */ if (!sunxi_core_is_cortex_a15(cpu, cluster)) { reg = readl(cpucfg_base + CPUCFG_CX_CTRL_REG0(cluster)); @@ -180,17 +200,37 @@ static int sunxi_cpu_powerup(unsigned int cpu, unsigned int cluster) /* open power switch */ sunxi_cpu_power_switch_set(cpu, cluster, true); + /* Handle A83T bit swap */ + if (!is_sun9i) { + if (cpu == 0) + cpu = 4; + } + /* clear processor power gate */ reg = readl(prcm_base + PRCM_PWROFF_GATING_REG(cluster)); reg &= ~PRCM_PWROFF_GATING_REG_CORE(cpu); writel(reg, prcm_base + PRCM_PWROFF_GATING_REG(cluster)); udelay(20); + if (!is_sun9i) { + if (cpu == 4) + cpu = 0; + } + /* de-assert processor power-on reset */ reg = readl(prcm_base + PRCM_CPU_PO_RST_CTRL(cluster)); reg |= PRCM_CPU_PO_RST_CTRL_CORE(cpu); writel(reg, prcm_base + PRCM_CPU_PO_RST_CTRL(cluster)); + if (r_cpucfg_base) { + reg = readl(r_cpucfg_base + + R_CPUCFG_CLUSTER_PO_RST_CTRL(cluster)); + reg |= R_CPUCFG_CLUSTER_PO_RST_CTRL_CORE(cpu); + writel(reg, r_cpucfg_base + + R_CPUCFG_CLUSTER_PO_RST_CTRL(cluster)); + udelay(10); + } + /* de-assert all processor resets */ reg = readl(cpucfg_base + CPUCFG_CX_RST_CTRL(cluster)); reg |= CPUCFG_CX_RST_CTRL_DBG_RST(cpu); @@ -212,6 +252,14 @@ static int sunxi_cluster_powerup(unsigned int cluster) if (cluster >= SUNXI_NR_CLUSTERS) return -EINVAL; + /* For A83T, assert cluster cores resets */ + if (!is_sun9i) { + reg = readl(cpucfg_base + CPUCFG_CX_RST_CTRL(cluster)); + reg &= ~CPUCFG_CX_RST_CTRL_CORE_RST_ALL; /* Core Reset */ + writel(reg, cpucfg_base + CPUCFG_CX_RST_CTRL(cluster)); + udelay(10); + } + /* assert ACINACTM */ reg = readl(cpucfg_base + CPUCFG_CX_CTRL_REG1(cluster)); reg |= CPUCFG_CX_CTRL_REG1_ACINACTM; @@ -222,6 +270,16 @@ static int sunxi_cluster_powerup(unsigned int cluster) reg &= ~PRCM_CPU_PO_RST_CTRL_CORE_ALL; writel(reg, prcm_base + PRCM_CPU_PO_RST_CTRL(cluster)); + /* assert cluster cores resets */ + if (r_cpucfg_base) { + reg = readl(r_cpucfg_base + + R_CPUCFG_CLUSTER_PO_RST_CTRL(cluster)); + reg &= ~CPUCFG_CX_RST_CTRL_CORE_RST_ALL; + writel(reg, r_cpucfg_base + + R_CPUCFG_CLUSTER_PO_RST_CTRL(cluster)); + udelay(10); + } + /* assert cluster resets */ reg = readl(cpucfg_base + CPUCFG_CX_RST_CTRL(cluster)); reg &= ~CPUCFG_CX_RST_CTRL_DBG_SOC_RST; @@ -252,7 +310,10 @@ static int sunxi_cluster_powerup(unsigned int cluster) /* clear cluster power gate */ reg = readl(prcm_base + PRCM_PWROFF_GATING_REG(cluster)); - reg &= ~PRCM_PWROFF_GATING_REG_CLUSTER_SUN9I; + if (is_sun9i) + reg &= ~PRCM_PWROFF_GATING_REG_CLUSTER_SUN9I; + else + reg &= ~PRCM_PWROFF_GATING_REG_CLUSTER_SUN8I; writel(reg, prcm_base + PRCM_PWROFF_GATING_REG(cluster)); udelay(20); @@ -516,7 +577,8 @@ static int sunxi_cluster_powerdown(unsigned int cluster) /* gate cluster power */ pr_debug("%s: gate cluster power\n", __func__); reg = readl(prcm_base + PRCM_PWROFF_GATING_REG(cluster)); - reg |= PRCM_PWROFF_GATING_REG_CLUSTER_SUN9I; + if (is_sun9i) + reg |= PRCM_PWROFF_GATING_REG_CLUSTER_SUN9I; writel(reg, prcm_base + PRCM_PWROFF_GATING_REG(cluster)); udelay(20); @@ -762,12 +824,92 @@ static void sun9i_iounmap(void) iounmap(prcm_base); } +static int sun8i_dt_parsing(struct resource res) +{ + struct device_node *node, *cpucfg_node; + int ret; + + node = of_find_compatible_node(NULL, NULL, + "allwinner,sun8i-a83t-r-ccu"); + if (!node) + return -ENODEV; + + /* + * Unfortunately we can not request the I/O region for the PRCM. + * It is shared with the PRCM clock. + */ + prcm_base = of_iomap(node, 0); + of_node_put(node); + if (!prcm_base) { + pr_err("%s: failed to map PRCM registers\n", __func__); + iounmap(prcm_base); + return -ENOMEM; + } + + cpucfg_node = of_find_compatible_node(NULL, NULL, + "allwinner,sun8i-a83t-cpucfg"); + if (!cpucfg_node) { + ret = -ENODEV; + pr_err("%s: CPUCFG not available\n", __func__); + goto err_unmap_prcm; + } + + cpucfg_base = of_io_request_and_map(cpucfg_node, 0, "sunxi-mc-smp"); + if (IS_ERR(cpucfg_base)) { + ret = PTR_ERR(cpucfg_base); + pr_err("%s: failed to map CPUCFG registers: %d\n", + __func__, ret); + goto err_put_cpucfg_node; + } + + node = of_find_compatible_node(NULL, NULL, + "allwinner,sun8i-a83t-r-cpucfg"); + if (!node) { + ret = -ENODEV; + goto err_unmap_release_cpucfg; + } + + r_cpucfg_base = of_iomap(node, 0); + if (!r_cpucfg_base) { + pr_err("%s: failed to map R-CPUCFG registers\n", + __func__); + ret = -ENOMEM; + goto err_put_node; + } + + /* We don't need the CPUCFG device node anymore */ + of_node_put(cpucfg_node); + of_node_put(node); + + return 0; +err_put_node: + of_node_put(node); +err_unmap_release_cpucfg: + iounmap(cpucfg_base); + of_address_to_resource(cpucfg_node, 0, &res); + release_mem_region(res.start, resource_size(&res)); +err_put_cpucfg_node: + of_node_put(cpucfg_node); +err_unmap_prcm: + iounmap(prcm_base); + + return ret; +} + +static void sun8i_iounmap(void) +{ + iounmap(r_cpucfg_base); + iounmap(cpucfg_base); + iounmap(prcm_base); +} + static int __init sunxi_mc_smp_init(void) { struct resource res; int ret; - if (!of_machine_is_compatible("allwinner,sun9i-a80")) + if (!of_machine_is_compatible("allwinner,sun9i-a80") && + !of_machine_is_compatible("allwinner,sun8i-a83t")) return -ENODEV; if (!sunxi_mc_smp_cpu_table_init()) @@ -778,7 +920,12 @@ static int __init sunxi_mc_smp_init(void) return -ENODEV; } - ret = sun9i_dt_parsing(res); + is_sun9i = of_machine_is_compatible("allwinner,sun9i-a80"); + + if (is_sun9i) + ret = sun9i_dt_parsing(res); + else + ret = sun8i_dt_parsing(res); if (ret) { pr_err("%s: failed to parse DT: %d\n", __func__, ret); return ret; @@ -789,13 +936,20 @@ static int __init sunxi_mc_smp_init(void) if (ret) { pr_err("%s: failed to configure boot cluster: %d\n", __func__, ret); - sun9i_iounmap(); + if (is_sun9i) + sun9i_iounmap(); + else + sun8i_iounmap(); return ret; } /* Set the hardware entry point address */ - writel(__pa_symbol(sunxi_mc_smp_secondary_startup), - prcm_base + PRCM_CPU_SOFT_ENTRY_REG); + if (is_sun9i) + writel(__pa_symbol(sunxi_mc_smp_secondary_startup), + prcm_base + PRCM_CPU_SOFT_ENTRY_REG); + else + writel(__pa_symbol(sunxi_mc_smp_secondary_startup), + r_cpucfg_base + R_CPUCFG_CPU_SOFT_ENTRY_REG); /* Actually enable multi cluster SMP */ smp_set_ops(&sunxi_mc_smp_smp_ops); -- 2.11.0