From patchwork Thu Jul 17 23:54:36 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 1396 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 81EC022258E for ; Thu, 17 Jul 2025 23:56:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752796616; cv=none; b=QxY3HigzjdWjey67/L3rPMfpV+58S/D57a4s2+VTM6NuCAc9Hebht+p44PDO6luqQAeaSjWoaj6FD5+E9DStQoB+WAwMac23r51ow75RDTb37SCkJb7yoGViDpe3uyG6zpntsoYI7cIx8LtQJ2G/wZaGTnZVy6mjmZywDcp14BU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752796616; c=relaxed/simple; bh=cqphqndfZWlEyysTwPm4fjqePxt0mNPRZ4cKlhFmcMA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Sx1ZzJ30GJXkHiXuDmSRIIQ+i8n0jS9n/o3ky9qYP7Q6qLOU5BTX4fzwW6Y93Co56hqkptdjW8uP9zij57JVmIx0TCV/IuaxNBshCMd6ft7kc7quvwQe0s24hSd9I4H2p1UTTtkXD4apwAyjN588On5lUllyx1rcd1DvoFKukuw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 341AB168F; Thu, 17 Jul 2025 16:56:45 -0700 (PDT) Received: from localhost.localdomain (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 9E0733F694; Thu, 17 Jul 2025 16:56:51 -0700 (PDT) From: Andre Przywara To: u-boot@lists.denx.de Cc: Jernej Skrabec , Mikhail Kalashnikov , Yixun Lan , Paul Kocialkowski , linux-sunxi@lists.linux.dev, Tom Rini Subject: [PATCH v2 01/20] sunxi: clock: H6: unify PLL control bit definitions Date: Fri, 18 Jul 2025 00:54:36 +0100 Message-ID: <20250717235455.32528-2-andre.przywara@arm.com> X-Mailer: git-send-email 2.46.3 In-Reply-To: <20250717235455.32528-1-andre.przywara@arm.com> References: <20250717235455.32528-1-andre.przywara@arm.com> Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Status: O The Allwinner PLLs share most of their control bits, they differ mostly in the factors and dividers. Drop the PLL specific definition of those common bits, and use one shared macro, for all PLLs. This requires changing the users in the SPL clock and DRAM code. Signed-off-by: Andre Przywara --- .../include/asm/arch-sunxi/clock_sun50i_h6.h | 20 +++++++------------ arch/arm/mach-sunxi/clock_sun50i_h6.c | 13 +++++++----- arch/arm/mach-sunxi/dram_sun50i_a133.c | 10 +++++----- arch/arm/mach-sunxi/dram_sun50i_h6.c | 6 +++--- arch/arm/mach-sunxi/dram_sun50i_h616.c | 6 +++--- 5 files changed, 26 insertions(+), 29 deletions(-) diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h b/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h index 575dff68804..37a620c9866 100644 --- a/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h +++ b/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h @@ -31,29 +31,23 @@ #define CCU_H6_UART_GATE_RESET 0x90c #define CCU_H6_I2C_GATE_RESET 0x91c -/* pll1 bit field */ -#define CCM_PLL1_CTRL_EN BIT(31) -#define CCM_PLL1_LDO_EN BIT(30) -#define CCM_PLL1_LOCK_EN BIT(29) -#define CCM_PLL1_LOCK BIT(28) -#define CCM_PLL1_OUT_EN BIT(27) +/* PLL bit fields */ +#define CCM_PLL_CTRL_EN BIT(31) +#define CCM_PLL_LDO_EN BIT(30) +#define CCM_PLL_LOCK_EN BIT(29) +#define CCM_PLL_LOCK BIT(28) +#define CCM_PLL_OUT_EN BIT(27) +#define CCM_PLL1_UPDATE BIT(26) #define CCM_PLL1_CLOCK_TIME_2 (2 << 24) #define CCM_PLL1_CTRL_P(p) ((p) << 16) #define CCM_PLL1_CTRL_N(n) (((n) - 1) << 8) /* pll5 bit field */ -#define CCM_PLL5_CTRL_EN BIT(31) -#define CCM_PLL5_LOCK_EN BIT(29) -#define CCM_PLL5_LOCK BIT(28) -#define CCM_PLL5_OUT_EN BIT(27) #define CCM_PLL5_CTRL_N(n) (((n) - 1) << 8) #define CCM_PLL5_CTRL_DIV1(div1) ((div1) << 0) #define CCM_PLL5_CTRL_DIV2(div0) ((div0) << 1) /* pll6 bit field */ -#define CCM_PLL6_CTRL_EN BIT(31) -#define CCM_PLL6_LOCK_EN BIT(29) -#define CCM_PLL6_LOCK BIT(28) #define CCM_PLL6_CTRL_P0_SHIFT 16 #define CCM_PLL6_CTRL_P0_MASK (0x7 << CCM_PLL6_CTRL_P0_SHIFT) #define CCM_PLL6_CTRL_N_SHIFT 8 diff --git a/arch/arm/mach-sunxi/clock_sun50i_h6.c b/arch/arm/mach-sunxi/clock_sun50i_h6.c index 3f375a51965..2f2fd5df93d 100644 --- a/arch/arm/mach-sunxi/clock_sun50i_h6.c +++ b/arch/arm/mach-sunxi/clock_sun50i_h6.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0+ + #include #include #include @@ -31,7 +33,7 @@ void clock_init_safe(void) clock_set_pll1(408000000); writel(CCM_PLL6_DEFAULT, ccm + CCU_H6_PLL6_CFG); - while (!(readl(ccm + CCU_H6_PLL6_CFG) & CCM_PLL6_LOCK)) + while (!(readl(ccm + CCU_H6_PLL6_CFG) & CCM_PLL_LOCK)) ; clrsetbits_le32(ccm + CCU_H6_CPU_AXI_CFG, @@ -85,15 +87,16 @@ void clock_set_pll1(unsigned int clk) writel(val, ccm + CCU_H6_CPU_AXI_CFG); /* clk = 24*n/p, p is ignored if clock is >288MHz */ - val = CCM_PLL1_CTRL_EN | CCM_PLL1_LOCK_EN | CCM_PLL1_CLOCK_TIME_2; + val = CCM_PLL_CTRL_EN | CCM_PLL_LOCK_EN | CCM_PLL1_CLOCK_TIME_2; val |= CCM_PLL1_CTRL_N(clk / 24000000); if (IS_ENABLED(CONFIG_MACH_SUN50I_H616) || IS_ENABLED(CONFIG_MACH_SUN50I_A133)) - val |= CCM_PLL1_OUT_EN; + val |= CCM_PLL_OUT_EN; if (IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2)) - val |= CCM_PLL1_OUT_EN | CCM_PLL1_LDO_EN; + val |= CCM_PLL_OUT_EN | CCM_PLL_LDO_EN; writel(val, ccm + CCU_H6_PLL1_CFG); - while (!(readl(ccm + CCU_H6_PLL1_CFG) & CCM_PLL1_LOCK)) {} + while (!(readl(ccm + CCU_H6_PLL1_CFG) & CCM_PLL_LOCK)) + ; /* Switch CPU to PLL1 */ val = readl(ccm + CCU_H6_CPU_AXI_CFG); diff --git a/arch/arm/mach-sunxi/dram_sun50i_a133.c b/arch/arm/mach-sunxi/dram_sun50i_a133.c index a0fca3738f4..3a231141168 100644 --- a/arch/arm/mach-sunxi/dram_sun50i_a133.c +++ b/arch/arm/mach-sunxi/dram_sun50i_a133.c @@ -78,19 +78,19 @@ static void mctl_clk_init(u32 clk) clrbits_le32(ccm + CCU_H6_MBUS_CFG, MBUS_RESET); clrbits_le32(ccm + CCU_H6_DRAM_GATE_RESET, BIT(GATE_SHIFT)); clrbits_le32(ccm + CCU_H6_DRAM_GATE_RESET, BIT(RESET_SHIFT)); - clrbits_le32(ccm + CCU_H6_PLL5_CFG, CCM_PLL5_CTRL_EN); + clrbits_le32(ccm + CCU_H6_PLL5_CFG, CCM_PLL_CTRL_EN); clrbits_le32(ccm + CCU_H6_DRAM_CLK_CFG, DRAM_MOD_RESET); udelay(5); /* Set up PLL5 clock, used for DRAM */ clrsetbits_le32(ccm + CCU_H6_PLL5_CFG, 0xff03, - CCM_PLL5_CTRL_N((clk * 2) / 24) | CCM_PLL5_CTRL_EN); + CCM_PLL5_CTRL_N((clk * 2) / 24) | CCM_PLL_CTRL_EN); setbits_le32(ccm + CCU_H6_PLL5_CFG, BIT(24)); clrsetbits_le32(ccm + CCU_H6_PLL5_CFG, 0x3, - CCM_PLL5_LOCK_EN | CCM_PLL5_CTRL_EN | BIT(30)); - clrbits_le32(ccm + CCU_H6_PLL5_CFG, 0x3 | BIT(30)); + CCM_PLL_LOCK_EN | CCM_PLL_CTRL_EN | CCM_PLL_LDO_EN); + clrbits_le32(ccm + CCU_H6_PLL5_CFG, 0x3 | CCM_PLL_LDO_EN); mctl_await_completion(ccm + CCU_H6_PLL5_CFG, - CCM_PLL5_LOCK, CCM_PLL5_LOCK); + CCM_PLL_LOCK, CCM_PLL_LOCK); /* Enable DRAM clock and gate*/ clrbits_le32(ccm + CCU_H6_DRAM_CLK_CFG, BIT(24) | BIT(25)); diff --git a/arch/arm/mach-sunxi/dram_sun50i_h6.c b/arch/arm/mach-sunxi/dram_sun50i_h6.c index 84fd64a2bfc..ea26e6dd327 100644 --- a/arch/arm/mach-sunxi/dram_sun50i_h6.c +++ b/arch/arm/mach-sunxi/dram_sun50i_h6.c @@ -167,16 +167,16 @@ static void mctl_sys_init(u32 clk_rate) clrbits_le32(ccm + CCU_H6_DRAM_GATE_RESET, BIT(0)); udelay(5); writel(0, ccm + CCU_H6_DRAM_GATE_RESET); - clrbits_le32(ccm + CCU_H6_PLL5_CFG, CCM_PLL5_CTRL_EN); + clrbits_le32(ccm + CCU_H6_PLL5_CFG, CCM_PLL_CTRL_EN); clrbits_le32(ccm + CCU_H6_DRAM_CLK_CFG, DRAM_MOD_RESET); udelay(5); /* Set PLL5 rate to doubled DRAM clock rate */ - writel(CCM_PLL5_CTRL_EN | CCM_PLL5_LOCK_EN | + writel(CCM_PLL_CTRL_EN | CCM_PLL_LOCK_EN | CCM_PLL5_CTRL_N(clk_rate * 2 / 24), ccm + CCU_H6_PLL5_CFG); mctl_await_completion(ccm + CCU_H6_PLL5_CFG, - CCM_PLL5_LOCK, CCM_PLL5_LOCK); + CCM_PLL_LOCK, CCM_PLL_LOCK); /* Configure DRAM mod clock */ writel(DRAM_CLK_SRC_PLL5, ccm + CCU_H6_DRAM_CLK_CFG); diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c b/arch/arm/mach-sunxi/dram_sun50i_h616.c index 5a59f82d1ef..877181016f3 100644 --- a/arch/arm/mach-sunxi/dram_sun50i_h616.c +++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c @@ -106,16 +106,16 @@ static void mctl_sys_init(u32 clk_rate) clrbits_le32(ccm + CCU_H6_DRAM_GATE_RESET, BIT(GATE_SHIFT)); udelay(5); clrbits_le32(ccm + CCU_H6_DRAM_GATE_RESET, BIT(RESET_SHIFT)); - clrbits_le32(ccm + CCU_H6_PLL5_CFG, CCM_PLL5_CTRL_EN); + clrbits_le32(ccm + CCU_H6_PLL5_CFG, CCM_PLL_CTRL_EN); clrbits_le32(ccm + CCU_H6_DRAM_CLK_CFG, DRAM_MOD_RESET); udelay(5); /* Set PLL5 rate to doubled DRAM clock rate */ - writel(CCM_PLL5_CTRL_EN | CCM_PLL5_LOCK_EN | CCM_PLL5_OUT_EN | + writel(CCM_PLL_CTRL_EN | CCM_PLL_LOCK_EN | CCM_PLL_OUT_EN | CCM_PLL5_CTRL_N(clk_rate * 2 / 24), ccm + CCU_H6_PLL5_CFG); mctl_await_completion(ccm + CCU_H6_PLL5_CFG, - CCM_PLL5_LOCK, CCM_PLL5_LOCK); + CCM_PLL_LOCK, CCM_PLL_LOCK); /* Configure DRAM mod clock */ writel(DRAM_CLK_SRC_PLL5, ccm + CCU_H6_DRAM_CLK_CFG); From patchwork Thu Jul 17 23:54:37 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 1395 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 20EE72309BD for ; Thu, 17 Jul 2025 23:56:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752796617; cv=none; b=S9ielsqCjPz5MRJzHORvzTIHw1Uay1GL6Xrzf7okJpCSWEegVPAoVmGH7seomhhZAyCb8xxg5+sbjcW4NOroGZuMCFsc8PFek/sxKFfZYzXaUs8zbnGquCKSAFVz5pFHQrqXFihbWD7uW15yKwVR689+JTukLNf8X/yZEz4OAgw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752796617; c=relaxed/simple; bh=5w7wJT9Ma+MQjAO3OCSa7p54JU1cUymrFijAit7nRiU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=nhFUbKGeIOH7Q370LHqUwSEqBJl3+/RZOLK4buwVA/H4mIUeqQiM54PVVZ0aXswfqsULaI7HEhnDZH9LEmLqnOhs7Cl2889UOKY+9FRv6iU3Qr7DKCfWt2T3m4vUaQtTdE/oTIP8UWPBT9UKKWRWljySjRNSxvSuhov/XjxDN+Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 8B1B61762; Thu, 17 Jul 2025 16:56:46 -0700 (PDT) Received: from localhost.localdomain (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 028E83F694; Thu, 17 Jul 2025 16:56:52 -0700 (PDT) From: Andre Przywara To: u-boot@lists.denx.de Cc: Jernej Skrabec , Mikhail Kalashnikov , Yixun Lan , Paul Kocialkowski , linux-sunxi@lists.linux.dev, Tom Rini Subject: [PATCH v2 02/20] sunxi: clock: H6: factor out clock_set_pll() Date: Fri, 18 Jul 2025 00:54:37 +0100 Message-ID: <20250717235455.32528-3-andre.przywara@arm.com> X-Mailer: git-send-email 2.46.3 In-Reply-To: <20250717235455.32528-1-andre.przywara@arm.com> References: <20250717235455.32528-1-andre.przywara@arm.com> Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Status: O The SPL initial clock setup code for the Allwinner H6 and H616 SoCs uses a simple CPU PLL setup routine, which programs all register bits at once, then waits for the LOCK bit to clear. The manual suggests to follow a certain procedure for bringing up any PLLs, which involves several register writes, one at a time, and some delays. Also the H616 and the new A523 require some tiny changes in this sequence, and the different SoCs also feature some extra bits here and there, which we should not just clear. So factor out the PLL setup routine, and make it follow the manual's suggestion. This will read the PLL register at the beginning, then tweak the bits we need to manipulate, and writes the register several times on the way. This allows to cover the specific bits for different SoCs. Besides improving the reliability of the PLL setup, this helps with the A523, which requires *three* CPU PLLs to be programmed. Signed-off-by: Andre Przywara --- .../include/asm/arch-sunxi/clock_sun50i_h6.h | 2 +- arch/arm/mach-sunxi/clock_sun50i_h6.c | 60 +++++++++++++++---- 2 files changed, 50 insertions(+), 12 deletions(-) diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h b/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h index 37a620c9866..5d6519d2367 100644 --- a/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h +++ b/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h @@ -38,8 +38,8 @@ #define CCM_PLL_LOCK BIT(28) #define CCM_PLL_OUT_EN BIT(27) #define CCM_PLL1_UPDATE BIT(26) -#define CCM_PLL1_CLOCK_TIME_2 (2 << 24) #define CCM_PLL1_CTRL_P(p) ((p) << 16) +#define CCM_PLL1_CTRL_N_MASK GENMASK(15, 8) #define CCM_PLL1_CTRL_N(n) (((n) - 1) << 8) /* pll5 bit field */ diff --git a/arch/arm/mach-sunxi/clock_sun50i_h6.c b/arch/arm/mach-sunxi/clock_sun50i_h6.c index 2f2fd5df93d..90436b45b40 100644 --- a/arch/arm/mach-sunxi/clock_sun50i_h6.c +++ b/arch/arm/mach-sunxi/clock_sun50i_h6.c @@ -4,6 +4,7 @@ #include #include #include +#include #ifdef CONFIG_XPL_BUILD void clock_init_safe(void) @@ -72,6 +73,53 @@ void clock_init_uart(void) 1 << (RESET_SHIFT + CONFIG_CONS_INDEX - 1)); } +static bool has_pll_output_gate(void) +{ + return (IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2) || + IS_ENABLED(CONFIG_MACH_SUN50I_H616) || + IS_ENABLED(CONFIG_MACH_SUN50I_A133)); +} + +/* A shared routine to program the CPU PLLs for H6, H616, T113, A523 */ +static void clock_set_pll(u32 *reg, unsigned int n) +{ + u32 val = readl(reg); + + /* clear the lock enable bit */ + val &= ~CCM_PLL_LOCK_EN; + writel(val, reg); + + /* gate the output on the newer SoCs */ + if (has_pll_output_gate()) { + val &= ~CCM_PLL_OUT_EN; + writel(val, reg); + } + + val &= ~(CCM_PLL1_CTRL_N_MASK | GENMASK(3, 0) | GENMASK(21, 16)); + val |= CCM_PLL1_CTRL_N(n); + writel(val, reg); /* program parameter */ + + val |= CCM_PLL_CTRL_EN; + if (IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2)) + val |= CCM_PLL_LDO_EN; + writel(val, reg); /* enable PLL */ + + val |= CCM_PLL_LOCK_EN; + if (IS_ENABLED(CONFIG_MACH_SUN55I_A523)) + val |= CCM_PLL1_UPDATE; + writel(val, reg); /* start locking process */ + + while (!(readl(reg) & CCM_PLL_LOCK)) { /* wait for lock bit */ + } + udelay(20); /* wait as per manual */ + + /* un-gate the output on the newer SoCs */ + if (has_pll_output_gate()) { + val |= CCM_PLL_OUT_EN; + writel(val, reg); + } +} + void clock_set_pll1(unsigned int clk) { void *const ccm = (void *)SUNXI_CCM_BASE; @@ -86,17 +134,7 @@ void clock_set_pll1(unsigned int clk) val |= CCM_CPU_AXI_MUX_OSC24M; writel(val, ccm + CCU_H6_CPU_AXI_CFG); - /* clk = 24*n/p, p is ignored if clock is >288MHz */ - val = CCM_PLL_CTRL_EN | CCM_PLL_LOCK_EN | CCM_PLL1_CLOCK_TIME_2; - val |= CCM_PLL1_CTRL_N(clk / 24000000); - if (IS_ENABLED(CONFIG_MACH_SUN50I_H616) || - IS_ENABLED(CONFIG_MACH_SUN50I_A133)) - val |= CCM_PLL_OUT_EN; - if (IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2)) - val |= CCM_PLL_OUT_EN | CCM_PLL_LDO_EN; - writel(val, ccm + CCU_H6_PLL1_CFG); - while (!(readl(ccm + CCU_H6_PLL1_CFG) & CCM_PLL_LOCK)) - ; + clock_set_pll(ccm + CCU_H6_PLL1_CFG, clk / 24000000); /* Switch CPU to PLL1 */ val = readl(ccm + CCU_H6_CPU_AXI_CFG); From patchwork Thu Jul 17 23:54:38 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 1394 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id A3F4122258E for ; Thu, 17 Jul 2025 23:56:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752796618; cv=none; b=WDs34RDRhuEvVIyVxU5m8mOxQLPFrMtMWiWffGz5owjp5ZJJ918zNtFxuiH47cZ6HwPB+obKUGIxHHkiQjIDk/YRHBuOssyelA4/OAoAyRkzv4rYK9cxgyvYbJEHRW1cJ7BS9Zn40NKkZtX5zMVL8oeYHcoJtzIgI9FB4c7fB7E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752796618; c=relaxed/simple; bh=NlyGJFS5K2FzdfT99M1CPZtoVv/AqwAgWmumUemg5Uw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=M5pi+GL1GEkfQ5KiZSQRyQZ/Mc5S1IyFz1dYOTtAvAR7lA6XSIBSwxXNR04OhreY67LJqCGmm/ybL/LDmejGQvgsvXEV7R53SCrIZUlEjdE3hW+tkZAQvFhPQGDantYJIS5DxgoN/NzY56rl8thYnjJP762QaWwURZOlR2MyXRU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id E6690176C; Thu, 17 Jul 2025 16:56:47 -0700 (PDT) Received: from localhost.localdomain (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 5B7133F694; Thu, 17 Jul 2025 16:56:54 -0700 (PDT) From: Andre Przywara To: u-boot@lists.denx.de Cc: Jernej Skrabec , Mikhail Kalashnikov , Yixun Lan , Paul Kocialkowski , linux-sunxi@lists.linux.dev, Tom Rini Subject: [PATCH v2 03/20] sunxi: clock: H6: factor out H6/H616 CPU clock setup Date: Fri, 18 Jul 2025 00:54:38 +0100 Message-ID: <20250717235455.32528-4-andre.przywara@arm.com> X-Mailer: git-send-email 2.46.3 In-Reply-To: <20250717235455.32528-1-andre.przywara@arm.com> References: <20250717235455.32528-1-andre.przywara@arm.com> Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Status: O When we program the CPU PLL, we need to switch the CPU clock source away from the PLL temporarily, then switch it back, once the PLL has stabilised. The CPU CLK register will be different on the A523, so move the current code into a separate function, to allow using a different version of that later for the A523. Signed-off-by: Andre Przywara --- arch/arm/mach-sunxi/clock_sun50i_h6.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/arch/arm/mach-sunxi/clock_sun50i_h6.c b/arch/arm/mach-sunxi/clock_sun50i_h6.c index 90436b45b40..84064c4ed86 100644 --- a/arch/arm/mach-sunxi/clock_sun50i_h6.c +++ b/arch/arm/mach-sunxi/clock_sun50i_h6.c @@ -120,29 +120,37 @@ static void clock_set_pll(u32 *reg, unsigned int n) } } -void clock_set_pll1(unsigned int clk) +static void clock_h6_set_cpu_pll(unsigned int n_factor) { void *const ccm = (void *)SUNXI_CCM_BASE; u32 val; - /* Do not support clocks < 288MHz as they need factor P */ - if (clk < 288000000) clk = 288000000; - - /* Switch to 24MHz clock while changing PLL1 */ + /* Switch CPU clock source to 24MHz HOSC while changing the PLL */ val = readl(ccm + CCU_H6_CPU_AXI_CFG); val &= ~CCM_CPU_AXI_MUX_MASK; val |= CCM_CPU_AXI_MUX_OSC24M; writel(val, ccm + CCU_H6_CPU_AXI_CFG); - clock_set_pll(ccm + CCU_H6_PLL1_CFG, clk / 24000000); + clock_set_pll(ccm + CCU_H6_PLL1_CFG, n_factor); - /* Switch CPU to PLL1 */ + /* Switch CPU clock source to the CPU PLL */ val = readl(ccm + CCU_H6_CPU_AXI_CFG); val &= ~CCM_CPU_AXI_MUX_MASK; val |= CCM_CPU_AXI_MUX_PLL_CPUX; writel(val, ccm + CCU_H6_CPU_AXI_CFG); } +void clock_set_pll1(unsigned int clk) +{ + /* Do not support clocks < 288MHz as they need factor P */ + if (clk < 288000000) + clk = 288000000; + + clk /= 24000000; + + clock_h6_set_cpu_pll(clk); +} + int clock_twi_onoff(int port, int state) { void *const ccm = (void *)SUNXI_CCM_BASE; From patchwork Thu Jul 17 23:54:39 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 1393 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 482D024110F for ; Thu, 17 Jul 2025 23:56:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752796619; cv=none; b=YXz505eFr8B1ccDJwAYk8WKSu5nKVDJh45cGgTET+wgVke0xaQuMd3Zf+9cR4szQtwbvQv4CRL+gQMXSNTkrHCmuFI84XytHcx60IhLyqYGi8VTitwzxy7bRImBWamDDtIYVu0GjFkH9eF+IuR2BrTi5hm1Lwy8x0pONwte+fX8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752796619; c=relaxed/simple; bh=ICIv2tryd6AokHxxyWy85f0ad1wgNzJ72OQdUDSVrJU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=XNySPBnspkHVgaTsNADAqE59KLUHpm8Gsdz0Scw4irQakE61CPbowBY4nAXe3KcOYz3qT/UEzk039jivY0ZOhWInHP/aIKsYoRKbTyQ6JUjKlC9Oh0lrKnTBUly1+fntLOBWge3DqBgEFWmjNcUdNMrpi3deci6QfY6QJRHzHaA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 498421BB2; Thu, 17 Jul 2025 16:56:49 -0700 (PDT) Received: from localhost.localdomain (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id B50F63F694; Thu, 17 Jul 2025 16:56:55 -0700 (PDT) From: Andre Przywara To: u-boot@lists.denx.de Cc: Jernej Skrabec , Mikhail Kalashnikov , Yixun Lan , Paul Kocialkowski , linux-sunxi@lists.linux.dev, Tom Rini Subject: [PATCH v2 04/20] sunxi: clock: H6: add A523 CPU PLL support Date: Fri, 18 Jul 2025 00:54:39 +0100 Message-ID: <20250717235455.32528-5-andre.przywara@arm.com> X-Mailer: git-send-email 2.46.3 In-Reply-To: <20250717235455.32528-1-andre.przywara@arm.com> References: <20250717235455.32528-1-andre.przywara@arm.com> Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Status: O The Allwinner A523 features 8 CPU cores, organised in two clusters, both driven by separate PLLs. Also there is the DSU PLL, which clocks the hardware that connects the cores to the rest of the system. And while the PLL registers itself are very similar, they are located in a separate register frame, outside the main CCU, and also the register controlling the CPU clock source (mux) is different. Provide a separate function that reparents the two clusters and the DSU, while their PLLs are programmed. For the actual PLL programming, we rely on the existing shared routine. The selection between the new A523 routine and the existing code is made with C if statements, but since the choice is effectively made at compile time already, the compiler optimises away the other code paths, leaving just the one required function in. Signed-off-by: Andre Przywara --- .../include/asm/arch-sunxi/clock_sun50i_h6.h | 17 ++++++++ .../include/asm/arch-sunxi/cpu_sunxi_ncat2.h | 2 + arch/arm/mach-sunxi/clock_sun50i_h6.c | 40 ++++++++++++++++++- 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h b/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h index 5d6519d2367..5881ab88573 100644 --- a/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h +++ b/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h @@ -13,6 +13,7 @@ #include #endif +/* Main CCU register offsets */ #define CCU_H6_PLL1_CFG 0x000 #define CCU_H6_PLL5_CFG 0x010 #define CCU_H6_PLL6_CFG 0x020 @@ -31,6 +32,14 @@ #define CCU_H6_UART_GATE_RESET 0x90c #define CCU_H6_I2C_GATE_RESET 0x91c +/* A523 CPU PLL offsets */ +#define CPC_CPUA_PLL_CTRL 0x04 +#define CPC_DSU_PLL_CTRL 0x08 +#define CPC_CPUB_PLL_CTRL 0x0c +#define CPC_CPUA_CLK_REG 0x60 +#define CPC_CPUB_CLK_REG 0x64 +#define CPC_DSU_CLK_REG 0x6c + /* PLL bit fields */ #define CCM_PLL_CTRL_EN BIT(31) #define CCM_PLL_LDO_EN BIT(30) @@ -42,6 +51,14 @@ #define CCM_PLL1_CTRL_N_MASK GENMASK(15, 8) #define CCM_PLL1_CTRL_N(n) (((n) - 1) << 8) +/* A523 CPU clock fields */ +#define CPU_CLK_SRC_HOSC (0 << 24) +#define CPU_CLK_SRC_CPUPLL (3 << 24) +#define CPU_CLK_CTRL_P(p) ((p) << 16) +#define CPU_CLK_APB_DIV(n) (((n) - 1) << 8) +#define CPU_CLK_PERI_DIV(m1) (((m1) - 1) << 2) +#define CPU_CLK_AXI_DIV(m) (((m) - 1) << 0) + /* pll5 bit field */ #define CCM_PLL5_CTRL_N(n) (((n) - 1) << 8) #define CCM_PLL5_CTRL_DIV1(div1) ((div1) << 0) diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h b/arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h index 908a582ae0f..c04ddb3f1d4 100644 --- a/arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h +++ b/arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h @@ -30,6 +30,8 @@ #define SUNXI_CPUCFG_BASE 0x09010000 +#define SUNXI_CPU_PLL_CFG_BASE 0x08817000 + #ifndef __ASSEMBLY__ void sunxi_board_init(void); void sunxi_reset(void); diff --git a/arch/arm/mach-sunxi/clock_sun50i_h6.c b/arch/arm/mach-sunxi/clock_sun50i_h6.c index 84064c4ed86..3a4399a9c6c 100644 --- a/arch/arm/mach-sunxi/clock_sun50i_h6.c +++ b/arch/arm/mach-sunxi/clock_sun50i_h6.c @@ -6,6 +6,10 @@ #include #include +#ifndef SUNXI_CPU_PLL_CFG_BASE +#define SUNXI_CPU_PLL_CFG_BASE 0 +#endif + #ifdef CONFIG_XPL_BUILD void clock_init_safe(void) { @@ -120,6 +124,37 @@ static void clock_set_pll(u32 *reg, unsigned int n) } } +/* Program the PLLs for both clusters plus the DSU. */ +static void clock_a523_set_cpu_plls(unsigned int n_factor) +{ + void *const cpc = (void *)SUNXI_CPU_PLL_CFG_BASE; + u32 val; + + val = CPU_CLK_SRC_HOSC | CPU_CLK_CTRL_P(0) | + CPU_CLK_APB_DIV(4) | CPU_CLK_PERI_DIV(2) | + CPU_CLK_AXI_DIV(2); + + /* Switch CPU clock source to 24MHz HOSC while changing the PLL */ + writel(val, cpc + CPC_CPUA_CLK_REG); + writel(val, cpc + CPC_CPUB_CLK_REG); + udelay(20); + writel(CPU_CLK_SRC_HOSC | CPU_CLK_CTRL_P(0), + cpc + CPC_DSU_CLK_REG); + udelay(20); + + clock_set_pll(cpc + CPC_CPUA_PLL_CTRL, n_factor); + clock_set_pll(cpc + CPC_CPUB_PLL_CTRL, n_factor); + clock_set_pll(cpc + CPC_DSU_PLL_CTRL, n_factor); + + /* Switch CPU clock source to the CPU PLL */ + clrsetbits_le32(cpc + CPC_CPUA_CLK_REG, CPU_CLK_SRC_HOSC, + CPU_CLK_SRC_CPUPLL); + clrsetbits_le32(cpc + CPC_CPUB_CLK_REG, CPU_CLK_SRC_HOSC, + CPU_CLK_SRC_CPUPLL); + clrsetbits_le32(cpc + CPC_DSU_CLK_REG, CPU_CLK_SRC_HOSC, + CPU_CLK_SRC_CPUPLL); +} + static void clock_h6_set_cpu_pll(unsigned int n_factor) { void *const ccm = (void *)SUNXI_CCM_BASE; @@ -148,7 +183,10 @@ void clock_set_pll1(unsigned int clk) clk /= 24000000; - clock_h6_set_cpu_pll(clk); + if (IS_ENABLED(CONFIG_MACH_SUN55I_A523)) + clock_a523_set_cpu_plls(clk); + else + clock_h6_set_cpu_pll(clk); } int clock_twi_onoff(int port, int state) From patchwork Thu Jul 17 23:54:40 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 1392 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 9E7122309BD for ; Thu, 17 Jul 2025 23:56:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752796620; cv=none; b=P1JNgvI+ARi5zNUIqxlVqYn7DtjuwEoyIqMaCiv8Wo+OT0J8/8GGlakxj5Y33LMSAlsOlFm1UWlqQxO4hDWdIA0NC4cxErepZgyou1+eXOAFWDHtSvJ5/af3i5Oxjn72BHz3AtZjxy0hE3MzJQEbwa9eREPTYtrMWuCamSyK8Rk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752796620; c=relaxed/simple; bh=sBQA5YZZ4DpeOgqzSFsD6vCYtWnR90Ul3xopj5n2yIE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=TZVI3Bce0hydaAW9h5kmCIqQaS55ww1o2L5rZNpWfb/jeMvQQSfrJMTl8pZLnyxTZDXKbwNyBfKMl5ZV3Yf6Tp7fUfY2jU6NWjCR2PR5hQIFpXFmlaRIpOh0Fpu4gCLMr+kqC1USzjlYUmoR08Eh32t2nOrxMyLnoX3qDsEZSps= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id A0A9F1BCA; Thu, 17 Jul 2025 16:56:50 -0700 (PDT) Received: from localhost.localdomain (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 19CD33F694; Thu, 17 Jul 2025 16:56:56 -0700 (PDT) From: Andre Przywara To: u-boot@lists.denx.de Cc: Jernej Skrabec , Mikhail Kalashnikov , Yixun Lan , Paul Kocialkowski , linux-sunxi@lists.linux.dev, Tom Rini Subject: [PATCH v2 05/20] sunxi: spl: add support for Allwinner A523 watchdog Date: Fri, 18 Jul 2025 00:54:40 +0100 Message-ID: <20250717235455.32528-6-andre.przywara@arm.com> X-Mailer: git-send-email 2.46.3 In-Reply-To: <20250717235455.32528-1-andre.przywara@arm.com> References: <20250717235455.32528-1-andre.przywara@arm.com> Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Status: O The watchdog in the Allwinner A523 SoC differs a bit from the one in the previous SoCs: it lives in a separate register frame, so no longer inside some timer device, and it manages to shuffle around some registers a bit. But it also conveniently adds a direct reset functionality, so we don't need to use a dummy timeout period. Avoid introducing a new MMIO register frame C struct, but just define the one needed register offset as a macro. Then just trigger this new direct reset functionality in the A523 specific reset_cpu() implementation. Signed-off-by: Andre Przywara --- arch/arm/include/asm/arch-sunxi/watchdog.h | 2 ++ arch/arm/mach-sunxi/board.c | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/arch/arm/include/asm/arch-sunxi/watchdog.h b/arch/arm/include/asm/arch-sunxi/watchdog.h index 38e2ef2aca3..14a6e89ccfa 100644 --- a/arch/arm/include/asm/arch-sunxi/watchdog.h +++ b/arch/arm/include/asm/arch-sunxi/watchdog.h @@ -12,6 +12,8 @@ #define WDT_CTRL_RESTART (0x1 << 0) #define WDT_CTRL_KEY (0x0a57 << 1) +#define WDT_SRST_REG 0x08 + #if defined(CONFIG_MACH_SUN4I) || \ defined(CONFIG_MACH_SUN5I) || \ defined(CONFIG_MACH_SUN7I) || \ diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c index 08d55b3a0e3..13caefda884 100644 --- a/arch/arm/mach-sunxi/board.c +++ b/arch/arm/mach-sunxi/board.c @@ -502,6 +502,12 @@ void reset_cpu(void) /* sun5i sometimes gets stuck without this */ writel(WDT_MODE_RESET_EN | WDT_MODE_EN, &wdog->mode); } +#elif defined(CONFIG_MACH_SUN55I_A523) + static const void *wdog = (void *)SUNXI_TIMER_BASE; + + writel(WDT_CTRL_KEY | WDT_CTRL_RESTART, wdog + WDT_SRST_REG); + while (1) + ; #elif defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2) #if defined(CONFIG_MACH_SUN50I_H6) /* WDOG is broken for some H6 rev. use the R_WDOG instead */ From patchwork Thu Jul 17 23:54:41 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 1391 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id CB5EF22258E for ; Thu, 17 Jul 2025 23:56:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752796621; cv=none; b=WLz/IvOKxYvwR1Q4vEmkVC8LcBtSk0Sc5yIKURFrH84QBg2Fl8IzQHFGHcKeNfXEhcIODq9H3Ar99RzDAlYTlc5rIp99a6zL6tJIfYbsILRxg0ad4n+dS/QGl2WmxGH4773ebt57GXhuf3Qj0T/f5k1lCMmvlPTMwKvktJBHPPw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752796621; c=relaxed/simple; bh=ZxzIZQI9i9s1A2yoQqnfsZLDSynMuY4HbgL9SoolkiU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mr3QGznaXAw+bdA5ZRDzb+bHl7NYq0U85ns5icDPsiDhuq9bttsYBdp5AAJBm3X8yVQF+DlSbZb+Yhj4IILc/8Z5GIt0ES7Y2+L1H0xmKXni/J6SlqtgaM93hR+PlCjk8LWk7wa/2jepy0HUp2gLxAl51awtX9uB6FiZ/sVBfwY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 0A4401596; Thu, 17 Jul 2025 16:56:52 -0700 (PDT) Received: from localhost.localdomain (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 728223F694; Thu, 17 Jul 2025 16:56:58 -0700 (PDT) From: Andre Przywara To: u-boot@lists.denx.de Cc: Jernej Skrabec , Mikhail Kalashnikov , Yixun Lan , Paul Kocialkowski , linux-sunxi@lists.linux.dev, Tom Rini Subject: [PATCH v2 06/20] clk: sunxi: Add support for the A523 CCU Date: Fri, 18 Jul 2025 00:54:41 +0100 Message-ID: <20250717235455.32528-7-andre.przywara@arm.com> X-Mailer: git-send-email 2.46.3 In-Reply-To: <20250717235455.32528-1-andre.przywara@arm.com> References: <20250717235455.32528-1-andre.przywara@arm.com> Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Status: O Add a clock driver for the main clock controller on the Allwinner A523 family of SoCs. As usual, this just describes the clock gates and reset lines for the few device that U-Boot cares about: USB, Ethernet, MMC, I2C, SPI. Signed-off-by: Andre Przywara --- drivers/clk/sunxi/Kconfig | 7 +++ drivers/clk/sunxi/Makefile | 1 + drivers/clk/sunxi/clk_a523.c | 85 +++++++++++++++++++++++++++++++++++ drivers/clk/sunxi/clk_sunxi.c | 5 +++ 4 files changed, 98 insertions(+) create mode 100644 drivers/clk/sunxi/clk_a523.c diff --git a/drivers/clk/sunxi/Kconfig b/drivers/clk/sunxi/Kconfig index f44db76c182..74e89b86301 100644 --- a/drivers/clk/sunxi/Kconfig +++ b/drivers/clk/sunxi/Kconfig @@ -129,4 +129,11 @@ config CLK_SUN50I_A100 This enables common clock driver support for platforms based on Allwinner A100/A133 SoCs. +config CLK_SUN55I_A523 + bool "Clock driver for Allwinner A523/T527" + default MACH_SUN55I_A523 + help + This enables common clock driver support for platforms based + on Allwinner A523/T527 SoC. + endif # CLK_SUNXI diff --git a/drivers/clk/sunxi/Makefile b/drivers/clk/sunxi/Makefile index 7ff71c756e0..dd33eabe2ed 100644 --- a/drivers/clk/sunxi/Makefile +++ b/drivers/clk/sunxi/Makefile @@ -25,3 +25,4 @@ obj-$(CONFIG_CLK_SUN50I_H6_R) += clk_h6_r.o obj-$(CONFIG_CLK_SUN50I_H616) += clk_h616.o obj-$(CONFIG_CLK_SUN50I_A64) += clk_a64.o obj-$(CONFIG_CLK_SUN50I_A100) += clk_a100.o +obj-$(CONFIG_CLK_SUN55I_A523) += clk_a523.o diff --git a/drivers/clk/sunxi/clk_a523.c b/drivers/clk/sunxi/clk_a523.c new file mode 100644 index 00000000000..1de95fbaf2f --- /dev/null +++ b/drivers/clk/sunxi/clk_a523.c @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) 2024 Arm Ltd. + */ + +#include +#include +#include +#include +#include + +#include +#include + +static struct ccu_clk_gate a523_gates[] = { + [CLK_PLL_PERIPH0_200M] = GATE_DUMMY, + [CLK_APB1] = GATE_DUMMY, + + [CLK_BUS_MMC0] = GATE(0x84c, BIT(0)), + [CLK_BUS_MMC1] = GATE(0x84c, BIT(1)), + [CLK_BUS_MMC2] = GATE(0x84c, BIT(2)), + [CLK_BUS_UART0] = GATE(0x90c, BIT(0)), + [CLK_BUS_UART1] = GATE(0x90c, BIT(1)), + [CLK_BUS_UART2] = GATE(0x90c, BIT(2)), + [CLK_BUS_UART3] = GATE(0x90c, BIT(3)), + [CLK_BUS_UART4] = GATE(0x90c, BIT(4)), + [CLK_BUS_UART5] = GATE(0x90c, BIT(5)), + [CLK_BUS_I2C0] = GATE(0x91c, BIT(0)), + [CLK_BUS_I2C1] = GATE(0x91c, BIT(1)), + [CLK_BUS_I2C2] = GATE(0x91c, BIT(2)), + [CLK_BUS_I2C3] = GATE(0x91c, BIT(3)), + [CLK_SPI0] = GATE(0x940, BIT(31)), + [CLK_SPI1] = GATE(0x944, BIT(31)), + [CLK_BUS_SPI0] = GATE(0x96c, BIT(0)), + [CLK_BUS_SPI1] = GATE(0x96c, BIT(1)), + + [CLK_EMAC0_25M] = GATE(0x970, BIT(30) | BIT(31)), + [CLK_EMAC1_25M] = GATE(0x974, BIT(30) | BIT(31)), + [CLK_BUS_EMAC0] = GATE(0x97c, BIT(0)), + [CLK_BUS_EMAC1] = GATE(0x98c, BIT(0)), + + [CLK_USB_OHCI0] = GATE(0xa70, BIT(31)), + [CLK_USB_OHCI1] = GATE(0xa74, BIT(31)), + [CLK_BUS_OHCI0] = GATE(0xa8c, BIT(0)), + [CLK_BUS_OHCI1] = GATE(0xa8c, BIT(1)), + [CLK_BUS_EHCI0] = GATE(0xa8c, BIT(4)), + [CLK_BUS_EHCI1] = GATE(0xa8c, BIT(5)), + [CLK_BUS_OTG] = GATE(0xa8c, BIT(8)), +}; + +static struct ccu_reset a523_resets[] = { + [RST_BUS_MMC0] = RESET(0x84c, BIT(16)), + [RST_BUS_MMC1] = RESET(0x84c, BIT(17)), + [RST_BUS_MMC2] = RESET(0x84c, BIT(18)), + [RST_BUS_UART0] = RESET(0x90c, BIT(16)), + [RST_BUS_UART1] = RESET(0x90c, BIT(17)), + [RST_BUS_UART2] = RESET(0x90c, BIT(18)), + [RST_BUS_UART3] = RESET(0x90c, BIT(19)), + [RST_BUS_UART4] = RESET(0x90c, BIT(20)), + [RST_BUS_UART5] = RESET(0x90c, BIT(21)), + [RST_BUS_I2C0] = RESET(0x91c, BIT(16)), + [RST_BUS_I2C1] = RESET(0x91c, BIT(17)), + [RST_BUS_I2C2] = RESET(0x91c, BIT(18)), + [RST_BUS_I2C3] = RESET(0x91c, BIT(19)), + [RST_BUS_SPI0] = RESET(0x96c, BIT(16)), + [RST_BUS_SPI1] = RESET(0x96c, BIT(17)), + + [RST_BUS_EMAC0] = RESET(0x97c, BIT(16)), + [RST_BUS_EMAC1] = RESET(0x98c, BIT(16) | BIT(17)), + + [RST_USB_PHY0] = RESET(0xa70, BIT(30)), + [RST_USB_PHY1] = RESET(0xa74, BIT(30)), + [RST_BUS_OHCI0] = RESET(0xa8c, BIT(16)), + [RST_BUS_OHCI1] = RESET(0xa8c, BIT(17)), + [RST_BUS_EHCI0] = RESET(0xa8c, BIT(20)), + [RST_BUS_EHCI1] = RESET(0xa8c, BIT(21)), + [RST_BUS_OTG] = RESET(0xa8c, BIT(24)), +}; + +const struct ccu_desc a523_ccu_desc = { + .gates = a523_gates, + .resets = a523_resets, + .num_gates = ARRAY_SIZE(a523_gates), + .num_resets = ARRAY_SIZE(a523_resets), +}; diff --git a/drivers/clk/sunxi/clk_sunxi.c b/drivers/clk/sunxi/clk_sunxi.c index e0765cbc6dc..30baabaafcd 100644 --- a/drivers/clk/sunxi/clk_sunxi.c +++ b/drivers/clk/sunxi/clk_sunxi.c @@ -126,6 +126,7 @@ extern const struct ccu_desc a100_ccu_desc; extern const struct ccu_desc h6_r_ccu_desc; extern const struct ccu_desc r40_ccu_desc; extern const struct ccu_desc v3s_ccu_desc; +extern const struct ccu_desc a523_ccu_desc; static const struct udevice_id sunxi_clk_ids[] = { #ifdef CONFIG_CLK_SUN4I_A10 @@ -223,6 +224,10 @@ static const struct udevice_id sunxi_clk_ids[] = { #ifdef CONFIG_CLK_SUNIV_F1C100S { .compatible = "allwinner,suniv-f1c100s-ccu", .data = (ulong)&f1c100s_ccu_desc }, +#endif +#ifdef CONFIG_CLK_SUN55I_A523 + { .compatible = "allwinner,sun55i-a523-ccu", + .data = (ulong)&a523_ccu_desc }, #endif { } }; From patchwork Thu Jul 17 23:54:42 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 1390 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 42935241676 for ; Thu, 17 Jul 2025 23:57:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752796622; cv=none; b=rOiC3jTehHewS7i/hX2eIqloYCj/ay4tXN5BfoxmLwqV+6wwInBMGrcbL2xCUfWavX72ypy66cm8aoiy6K4r9L0SR1wGtE7AYGydI9CavKMwL+n4710VxHEDbF4ca3QAMrg5vEdXmDangPQKF7blETTmEyxGOPlgXlR8yAYsR80= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752796622; c=relaxed/simple; bh=DWa6oSl3XejSulqak7tioMuB13Re+BNUyxWySZvL7rI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Dyb1bYGN4TdkIYkKscvxT/Yw8Ylbe62GpGauUx7VVRVxqS/tv0GhDQFmcduTMZ76CS5x6ilqUE+Q4FHAiPqGp+IjHzUOnXLSgZ3DvgFsG3I9xj7EDJxGn+ibfJUqPYXwB9ORZgqTrhGwJ9whPBgrewNJcVtS5lxu5lDMNABrY9g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 613871762; Thu, 17 Jul 2025 16:56:53 -0700 (PDT) Received: from localhost.localdomain (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id CB70A3F694; Thu, 17 Jul 2025 16:56:59 -0700 (PDT) From: Andre Przywara To: u-boot@lists.denx.de Cc: Jernej Skrabec , Mikhail Kalashnikov , Yixun Lan , Paul Kocialkowski , linux-sunxi@lists.linux.dev, Tom Rini Subject: [PATCH v2 07/20] clk: sunxi: Add support for the A523 -R CCU Date: Fri, 18 Jul 2025 00:54:42 +0100 Message-ID: <20250717235455.32528-8-andre.przywara@arm.com> X-Mailer: git-send-email 2.46.3 In-Reply-To: <20250717235455.32528-1-andre.przywara@arm.com> References: <20250717235455.32528-1-andre.przywara@arm.com> Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Status: O Add a clock driver for the PRCM clock controller on the Allwinner A523 family of SoCs, often also used with an "r" prefix or suffix. This just describes the clock gates and reset lines for the few devices that we would need, most prominently the R_I2C device for the PMIC. Signed-off-by: Andre Przywara --- drivers/clk/sunxi/Kconfig | 7 ++++++ drivers/clk/sunxi/Makefile | 1 + drivers/clk/sunxi/clk_a523_r.c | 39 ++++++++++++++++++++++++++++++++++ drivers/clk/sunxi/clk_sunxi.c | 5 +++++ 4 files changed, 52 insertions(+) create mode 100644 drivers/clk/sunxi/clk_a523_r.c diff --git a/drivers/clk/sunxi/Kconfig b/drivers/clk/sunxi/Kconfig index 74e89b86301..1c1cc82719c 100644 --- a/drivers/clk/sunxi/Kconfig +++ b/drivers/clk/sunxi/Kconfig @@ -136,4 +136,11 @@ config CLK_SUN55I_A523 This enables common clock driver support for platforms based on Allwinner A523/T527 SoC. +config CLK_SUN55I_A523_R + bool "Clock driver for Allwinner A523 generation PRCM" + default MACH_SUN55I_A523 + help + This enables common clock driver support for the PRCM + in Allwinner A523/T527 SoCs. + endif # CLK_SUNXI diff --git a/drivers/clk/sunxi/Makefile b/drivers/clk/sunxi/Makefile index dd33eabe2ed..93b542cebcd 100644 --- a/drivers/clk/sunxi/Makefile +++ b/drivers/clk/sunxi/Makefile @@ -26,3 +26,4 @@ obj-$(CONFIG_CLK_SUN50I_H616) += clk_h616.o obj-$(CONFIG_CLK_SUN50I_A64) += clk_a64.o obj-$(CONFIG_CLK_SUN50I_A100) += clk_a100.o obj-$(CONFIG_CLK_SUN55I_A523) += clk_a523.o +obj-$(CONFIG_CLK_SUN55I_A523_R) += clk_a523_r.o diff --git a/drivers/clk/sunxi/clk_a523_r.c b/drivers/clk/sunxi/clk_a523_r.c new file mode 100644 index 00000000000..01e613d20aa --- /dev/null +++ b/drivers/clk/sunxi/clk_a523_r.c @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) 2024 Arm Ltd. + */ + +#include +#include +#include +#include +#include +#include + +static struct ccu_clk_gate a523_r_gates[] = { + [CLK_R_AHB] = GATE_DUMMY, + [CLK_R_APB0] = GATE_DUMMY, + [CLK_R_APB1] = GATE_DUMMY, + [CLK_BUS_R_TWD] = GATE(0x12c, BIT(0)), + [CLK_BUS_R_I2C0] = GATE(0x19c, BIT(0)), + [CLK_BUS_R_I2C1] = GATE(0x19c, BIT(1)), + [CLK_BUS_R_I2C2] = GATE(0x19c, BIT(2)), + [CLK_BUS_R_RTC] = GATE(0x20c, BIT(0)), +}; + +static struct ccu_reset a523_r_resets[] = { + [RST_BUS_R_TWD] = RESET(0x12c, BIT(16)), + [RST_BUS_R_UART0] = RESET(0x18c, BIT(16)), + [RST_BUS_R_I2C0] = RESET(0x19c, BIT(16)), + [RST_BUS_R_I2C1] = RESET(0x19c, BIT(17)), + [RST_BUS_R_I2C2] = RESET(0x19c, BIT(18)), + [RST_BUS_R_PPU1] = RESET(0x1ac, BIT(17)), + [RST_BUS_R_RTC] = RESET(0x20c, BIT(16)), +}; + +const struct ccu_desc a523_r_ccu_desc = { + .gates = a523_r_gates, + .resets = a523_r_resets, + .num_gates = ARRAY_SIZE(a523_r_gates), + .num_resets = ARRAY_SIZE(a523_r_resets), +}; diff --git a/drivers/clk/sunxi/clk_sunxi.c b/drivers/clk/sunxi/clk_sunxi.c index 30baabaafcd..842a0541bd6 100644 --- a/drivers/clk/sunxi/clk_sunxi.c +++ b/drivers/clk/sunxi/clk_sunxi.c @@ -127,6 +127,7 @@ extern const struct ccu_desc h6_r_ccu_desc; extern const struct ccu_desc r40_ccu_desc; extern const struct ccu_desc v3s_ccu_desc; extern const struct ccu_desc a523_ccu_desc; +extern const struct ccu_desc a523_r_ccu_desc; static const struct udevice_id sunxi_clk_ids[] = { #ifdef CONFIG_CLK_SUN4I_A10 @@ -228,6 +229,10 @@ static const struct udevice_id sunxi_clk_ids[] = { #ifdef CONFIG_CLK_SUN55I_A523 { .compatible = "allwinner,sun55i-a523-ccu", .data = (ulong)&a523_ccu_desc }, +#endif +#ifdef CONFIG_CLK_SUN55I_A523_R + { .compatible = "allwinner,sun55i-a523-r-ccu", + .data = (ulong)&a523_r_ccu_desc }, #endif { } }; From patchwork Thu Jul 17 23:54:43 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 1389 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 9687622258E for ; Thu, 17 Jul 2025 23:57:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752796624; cv=none; b=S/DFe6T5v3hcApNurW8ylqqe+QrWgJMyMjz6gsP14Ae7O5Gor3OqsFG6B0J19BPktBDeAxreDw/LpnphwVAEDnPZLdBny69HBGu5BICv0+H8XJNncSuVhI94quD6uqcVdhDbBm08rXCYpdl9yVRGwhjVxrAo7AMtZt+IRDaVIw8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752796624; c=relaxed/simple; bh=0647fBcTLTekn8ivIcNk2hkhaiIHhuo+fOPixkHnxmE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=eXmf+QC28YFNEiBuAxRDQ/yJX6uCGW2WWRttASqS7+50BeRz3rze9Dr1BrlZZvZuNHDgCJOvpRlQuOXozkWrGgIhp1MZrfhytnjEGGjS5Z6Wti6BU6WjIqTTLVsgJ9UgNgg3q7gGg3tMhd+Jl7hMVUcZDosMbNDBjqGOLcBejFU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id BEDB01596; Thu, 17 Jul 2025 16:56:54 -0700 (PDT) Received: from localhost.localdomain (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 302203F694; Thu, 17 Jul 2025 16:57:01 -0700 (PDT) From: Andre Przywara To: u-boot@lists.denx.de Cc: Jernej Skrabec , Mikhail Kalashnikov , Yixun Lan , Paul Kocialkowski , linux-sunxi@lists.linux.dev, Tom Rini Subject: [PATCH v2 08/20] pinctrl: sunxi: add Allwinner A523 pinctrl description Date: Fri, 18 Jul 2025 00:54:43 +0100 Message-ID: <20250717235455.32528-9-andre.przywara@arm.com> X-Mailer: git-send-email 2.46.3 In-Reply-To: <20250717235455.32528-1-andre.przywara@arm.com> References: <20250717235455.32528-1-andre.przywara@arm.com> Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Status: O The new DT pinctrl binding would allow us to read the pinmux values from the DT, but it is actually easier to just continue with hardcoding the mux values in the driver, and matching them against the "function" name. Add the values for the primary and secondary pin controller on the A523. Signed-off-by: Andre Przywara --- drivers/pinctrl/sunxi/Kconfig | 10 ++++++ drivers/pinctrl/sunxi/pinctrl-sunxi.c | 50 +++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig index 65e8192a99a..54314992299 100644 --- a/drivers/pinctrl/sunxi/Kconfig +++ b/drivers/pinctrl/sunxi/Kconfig @@ -139,4 +139,14 @@ config PINCTRL_SUN20I_D1 default MACH_SUN8I_R528 select PINCTRL_SUNXI +config PINCTRL_SUN55I_A523 + bool "Support for the Allwinner A523 PIO" + default MACH_SUN55I_A523 + select PINCTRL_SUNXI + +config PINCTRL_SUN55I_A523_R + bool "Support for the Allwinner A523 R-PIO" + default MACH_SUN55I_A523 + select PINCTRL_SUNXI + endif diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c index c38edf7d4f5..03cfe23aaf8 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c @@ -759,6 +759,29 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h616_pinctrl_desc = .num_banks = 9, }; +static const struct sunxi_pinctrl_function sun55i_a523_pinctrl_functions[] = { + { "emac0", 5 }, /* PI0-PI16 */ + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "mmc0", 2 }, /* PF0-PF5 */ + { "mmc1", 2 }, /* PG0-PG5 */ + { "mmc2", 3 }, /* PC0-PC16 */ + { "spi0", 4 }, /* PC0-PC7, PC15-PC16 */ +#if IS_ENABLED(CONFIG_UART0_PORT_F) + { "uart0", 3 }, /* PF2-PF4 */ +#else + { "uart0", 2 }, /* PH0-PH1 */ +#endif + { "uart1", 2 }, /* PG6-PG7 */ +}; + +static const struct sunxi_pinctrl_desc __maybe_unused sun55i_a523_pinctrl_desc = { + .functions = sun55i_a523_pinctrl_functions, + .num_functions = ARRAY_SIZE(sun55i_a523_pinctrl_functions), + .first_bank = SUNXI_GPIO_A, + .num_banks = 11, +}; + static const struct sunxi_pinctrl_function sun50i_h616_r_pinctrl_functions[] = { { "gpio_in", 0 }, { "gpio_out", 1 }, @@ -809,6 +832,21 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun50i_a100_r_pinctrl_desc .num_banks = 1, }; +static const struct sunxi_pinctrl_function sun55i_a523_r_pinctrl_functions[] = { + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "r_i2c0", 2 }, /* PL0-PL1 */ + { "r_spi", 6 }, /* PL10-PL13 */ + { "r_uart", 2 }, /* PL2-PL3 */ +}; + +static const struct sunxi_pinctrl_desc __maybe_unused sun55i_a523_r_pinctrl_desc = { + .functions = sun55i_a523_r_pinctrl_functions, + .num_functions = ARRAY_SIZE(sun55i_a523_r_pinctrl_functions), + .first_bank = SUNXI_GPIO_L, + .num_banks = 2, +}; + static const struct udevice_id sunxi_pinctrl_ids[] = { #ifdef CONFIG_PINCTRL_SUNIV_F1C100S { @@ -983,6 +1021,18 @@ static const struct udevice_id sunxi_pinctrl_ids[] = { .compatible = "allwinner,sun50i-a100-r-pinctrl", .data = (ulong)&sun50i_a100_r_pinctrl_desc, }, +#endif +#ifdef CONFIG_PINCTRL_SUN55I_A523 + { + .compatible = "allwinner,sun55i-a523-pinctrl", + .data = (ulong)&sun55i_a523_pinctrl_desc, + }, +#endif +#ifdef CONFIG_PINCTRL_SUN55I_A523_R + { + .compatible = "allwinner,sun55i-a523-r-pinctrl", + .data = (ulong)&sun55i_a523_r_pinctrl_desc, + }, #endif {} }; From patchwork Thu Jul 17 23:54:44 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 1388 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id E14F624110F for ; Thu, 17 Jul 2025 23:57:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752796625; cv=none; b=hWrk80CPkda4K88qCEtI7R0wqDAhIlIXo6FAn0D9Ez4GzdCdmrxTVTeffEx9RSSmawIkDvhOaAgEdIC1DKkIdnfY83Idllc19IMxXgakYmGafNj8jNRnTNxkT4OzfLzzvwFYkxlpPWcnCJRL0zWeMLLhb+PFw2WFWdV7k+A41Ys= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752796625; c=relaxed/simple; bh=e+fzUfOLNaspTfeOMXji/0vP39FJQIS2YP1IvstdOWE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=eN5Nn6RPHQhCRyrRcHwwkafrzr7LsDEvXAo8S7E+PHD0INuw3fAdS4/tMebTGKcsIc4E4D8F7iTEgL/pFJzfc1x792Fje+fPehqAEU6Zgq5dAyxf0WgbvP5XqjOr2oGI8mVjvGl6YqwO3ySi3vYyuUalvIOyKu8CGRxW2MyW7os= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 21B8E168F; Thu, 17 Jul 2025 16:56:56 -0700 (PDT) Received: from localhost.localdomain (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 8D52A3F694; Thu, 17 Jul 2025 16:57:02 -0700 (PDT) From: Andre Przywara To: u-boot@lists.denx.de Cc: Jernej Skrabec , Mikhail Kalashnikov , Yixun Lan , Paul Kocialkowski , linux-sunxi@lists.linux.dev, Tom Rini Subject: [PATCH v2 09/20] sunxi: mmc: add support for Allwinner A523 MMC mod clock Date: Fri, 18 Jul 2025 00:54:44 +0100 Message-ID: <20250717235455.32528-10-andre.przywara@arm.com> X-Mailer: git-send-email 2.46.3 In-Reply-To: <20250717235455.32528-1-andre.przywara@arm.com> References: <20250717235455.32528-1-andre.przywara@arm.com> Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Status: O The Allwinner A523 SoC has a slightly changed mod clock, where the P factor, formerly a shift value, is now a second divider value. Also the input clock is not PLL_PERIPH0_2X (1200MHz) anymore, but PLL_PERIPH0_400M, so adjust the input rate calculation accordingly. Signed-off-by: Andre Przywara --- drivers/mmc/sunxi_mmc.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index 06c1e09bf26..7c85030be16 100644 --- a/drivers/mmc/sunxi_mmc.c +++ b/drivers/mmc/sunxi_mmc.c @@ -99,6 +99,15 @@ static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz) */ if (IS_ENABLED(CONFIG_MACH_SUN8I_R528)) pll_hz /= 2; + + /* + * The A523/T527 uses PERIPH0_400M as the MMC input clock, + * which is the PERIPH0 nominal rate (1200MHz) / 3. + * Together with the fixed post-divider of 2 of the MMC mod + * clock, that gives a divider of 6. + */ + if (IS_ENABLED(CONFIG_MACH_SUN55I_A523)) + pll_hz /= 6; } div = pll_hz / hz; @@ -153,6 +162,10 @@ static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz) CCM_MMC_CTRL_SCLK_DLY(sclk_dly); } + /* The A523 has a second divider, not a shift. */ + if (IS_ENABLED(CONFIG_MACH_SUN55I_A523)) + n = (1U << n) - 1; + writel(CCM_MMC_CTRL_ENABLE| pll | CCM_MMC_CTRL_N(n) | CCM_MMC_CTRL_M(div) | val, priv->mclkreg); @@ -559,7 +572,8 @@ struct mmc *sunxi_mmc_init(int sdc_no) cfg->host_caps = MMC_MODE_4BIT; if ((IS_ENABLED(CONFIG_MACH_SUN50I) || IS_ENABLED(CONFIG_MACH_SUN8I) || - IS_ENABLED(CONFIG_SUN50I_GEN_H6)) && (sdc_no == 2)) + IS_ENABLED(CONFIG_SUN50I_GEN_H6) || IS_ENABLED(CONFIG_MACH_SUN55I_A523)) && + (sdc_no == 2)) cfg->host_caps = MMC_MODE_8BIT; cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS; From patchwork Thu Jul 17 23:54:45 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 1387 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 4C1AC22258E for ; Thu, 17 Jul 2025 23:57:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752796626; cv=none; b=sYR9jSswcCwzUm/Zijl60pzL1ZBimADt1pnVJVgKAzLdp5nnoYxQsEzCehPa3bfu/YPoBvn+ofItBu3nAAzbPgBFnD1qKRhK+uQx26Nal4ZVUsXu2Wsqd4u/sg065Ul/TV+pKyViLyofrnhwi5S/uuJhwGS0A6UcaCDeLw5V5jo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752796626; c=relaxed/simple; bh=wNT4ad4nuipyupNjlCtk6rfA1fQn/WRHCL702eyjRS0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=S6EwOy7gdq1B6i0GXkIUhVonWjTgQx9YeRI4r9t21gIy2jCeObsG8zEmr7TV+VN6RWiqvxmLtPIyHDq0kxtGl50SsXKl7Rl6JujVR2Vuk7Tuo7GTi2yz1IkeGzV8hdQUzjmbSOiupN7ev7Y+AMr7kUvVM0eiCsF+DymdG8Kv+2Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 786921762; Thu, 17 Jul 2025 16:56:57 -0700 (PDT) Received: from localhost.localdomain (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id E59683F694; Thu, 17 Jul 2025 16:57:03 -0700 (PDT) From: Andre Przywara To: u-boot@lists.denx.de Cc: Jernej Skrabec , Mikhail Kalashnikov , Yixun Lan , Paul Kocialkowski , linux-sunxi@lists.linux.dev, Tom Rini Subject: [PATCH v2 10/20] power: regulator: add AXP323 support Date: Fri, 18 Jul 2025 00:54:45 +0100 Message-ID: <20250717235455.32528-11-andre.przywara@arm.com> X-Mailer: git-send-email 2.46.3 In-Reply-To: <20250717235455.32528-1-andre.przywara@arm.com> References: <20250717235455.32528-1-andre.przywara@arm.com> Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Status: O The X-Powers AXP323 is very close sibling to the AXP313A, only that it adds support for dual-phasing the first two DC/DC converters. We do not really care about this particular feature, so just add the new compatible string and tie it to the existing AXP313A support code. Signed-off-by: Andre Przywara --- drivers/power/pmic/axp.c | 1 + drivers/power/regulator/axp_regulator.c | 1 + include/axp_pmic.h | 1 + 3 files changed, 3 insertions(+) diff --git a/drivers/power/pmic/axp.c b/drivers/power/pmic/axp.c index c300fd2bbc2..1204ec00f8d 100644 --- a/drivers/power/pmic/axp.c +++ b/drivers/power/pmic/axp.c @@ -89,6 +89,7 @@ static const struct udevice_id axp_pmic_ids[] = { { .compatible = "x-powers,axp221", .data = AXP221_ID }, { .compatible = "x-powers,axp223", .data = AXP223_ID }, { .compatible = "x-powers,axp313a", .data = AXP313_ID }, + { .compatible = "x-powers,axp323", .data = AXP323_ID }, { .compatible = "x-powers,axp717", .data = AXP717_ID }, { .compatible = "x-powers,axp803", .data = AXP803_ID }, { .compatible = "x-powers,axp806", .data = AXP806_ID }, diff --git a/drivers/power/regulator/axp_regulator.c b/drivers/power/regulator/axp_regulator.c index 75cdbca30f6..7794a4f5d92 100644 --- a/drivers/power/regulator/axp_regulator.c +++ b/drivers/power/regulator/axp_regulator.c @@ -318,6 +318,7 @@ static const struct axp_regulator_plat *const axp_regulators[] = { [AXP221_ID] = axp22x_regulators, [AXP223_ID] = axp22x_regulators, [AXP313_ID] = axp313_regulators, + [AXP323_ID] = axp313_regulators, [AXP717_ID] = axp717_regulators, [AXP803_ID] = axp803_regulators, [AXP806_ID] = axp806_regulators, diff --git a/include/axp_pmic.h b/include/axp_pmic.h index ae62ef0d76d..1806a7270a0 100644 --- a/include/axp_pmic.h +++ b/include/axp_pmic.h @@ -33,6 +33,7 @@ enum { AXP221_ID, AXP223_ID, AXP313_ID, + AXP323_ID, AXP717_ID, AXP803_ID, AXP806_ID, From patchwork Thu Jul 17 23:54:46 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 1386 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id A5B8549641 for ; Thu, 17 Jul 2025 23:57:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752796627; cv=none; b=G0ILUn5hxGV4JQaQBaCdj/0bHaGVrpFYGtkN30BSPxtdSJe9FV3pVvASiwcSq/7p2jitHci6zU4hDa+hKZ/8jtQgp9M8jBNvz8PTBPNjUQxStgevCAYi9Eia6JQ0DBBgzbrZ+Ze9jFuFBR2EAzSzthdSVe+vSt6P0WTAfG6wZoA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752796627; c=relaxed/simple; bh=naCF9nhj7Ao0ka8Rj2IE+Pv0gl0my/N3H8S18o2S1nE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=d68sTxKJMCQG+74QdX3Mw9n8KPLhxGlPxR72RS+gcYsN54Y/Wts7wuhAcqXfRWr9cq0V4ggPn/IXfgG5VDUzFkbBor8pFCxi+K7ZwzMAk/I/j9Wnt1HJ7tfM4HhmTT3Hnlg3Bmet+5/e5hsGrttIFx30LgW+M5v51bsf0ErTnO8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id D3C27168F; Thu, 17 Jul 2025 16:56:58 -0700 (PDT) Received: from localhost.localdomain (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 4A0643F694; Thu, 17 Jul 2025 16:57:05 -0700 (PDT) From: Andre Przywara To: u-boot@lists.denx.de Cc: Jernej Skrabec , Mikhail Kalashnikov , Yixun Lan , Paul Kocialkowski , linux-sunxi@lists.linux.dev, Tom Rini Subject: [PATCH v2 11/20] sunxi: update cpu_sunxi_ncat2.h Date: Fri, 18 Jul 2025 00:54:46 +0100 Message-ID: <20250717235455.32528-12-andre.przywara@arm.com> X-Mailer: git-send-email 2.46.3 In-Reply-To: <20250717235455.32528-1-andre.przywara@arm.com> References: <20250717235455.32528-1-andre.przywara@arm.com> Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Status: O The cpu_sunxi_ncat2.h header file contains addresses of some peripherals that are needed for the SPL, for chips that belong to the "NCAT2" generation. The Allwinner A523 is a member of this group, but a few addresses differ, and we need a few more addresses, for playing with the core reset, for instance. Add the new addresses needed for the A523 and guard existing definitions that conflict with that new chip. Signed-off-by: Andre Przywara --- .../include/asm/arch-sunxi/cpu_sunxi_ncat2.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h b/arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h index c04ddb3f1d4..bcfdc0a41c5 100644 --- a/arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h +++ b/arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h @@ -21,14 +21,32 @@ #define SUNXI_SID_BASE 0x03006200 #define SUNXI_GIC400_BASE 0x03020000 +#ifdef CONFIG_MACH_SUN55I_A523 +#define SUNXI_DRAM_COM_BASE 0x03120000 +#define SUNXI_DRAM_CTL0_BASE 0x03130000 +#define SUNXI_DRAM_PHY0_BASE 0x03140000 +#endif + #define SUNXI_MMC0_BASE 0x04020000 #define SUNXI_MMC1_BASE 0x04021000 #define SUNXI_MMC2_BASE 0x04022000 +#ifndef CONFIG_MACH_SUN55I_A523 #define SUNXI_R_CPUCFG_BASE 0x07000400 +#endif #define SUNXI_PRCM_BASE 0x07010000 +#define SUNXI_R_WDOG_BASE 0x07020400 +#ifdef CONFIG_MACH_SUN55I_A523 +#define SUNXI_R_CPUCFG_BASE 0x07050000 +#endif +#define SUNXI_R_TWI_BASE 0x07081400 +#define SUNXI_RTC_BASE 0x07090000 +#ifdef CONFIG_MACH_SUN55I_A523 +#define SUNXI_CPUCFG_BASE 0x08815000 +#else #define SUNXI_CPUCFG_BASE 0x09010000 +#endif #define SUNXI_CPU_PLL_CFG_BASE 0x08817000 From patchwork Thu Jul 17 23:54:47 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 1385 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 0463622258E for ; Thu, 17 Jul 2025 23:57:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752796629; cv=none; b=CmkIjmQoO5Tj5CaD1YKpPJECVyg1UJf1oY64gp7oj4yDkqMdCHu6tUzcaQTaOCY6xJOV8T3r3Q4gX/T+MlPOouwAv4p3OPxRy17IKXWttJT2WiCkeLl9WupDBhQbWxtiyjcMLMkqBRkiB9BqO52E1mH85lPJFFzwCYhs7BbVxyw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752796629; c=relaxed/simple; bh=eVSHCr+/lmgCSqYiwUzjApX7kA03ejcLL5xmPX5suGw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tpLl/4ulJT/tgVidawtvUGhF60SWHcmhL0D/TLdQeORgzCJJn6LQ6TLywVvNe2+8R2GAMyEIpCePPnJMTnrZVVYrGLfrd0fz52UvlS1yKb5KNiqFcvzvf302d7hg/PPeKBpc0RPrAaAT+3ehxNUQ8LGHzKfs529Wsdc49lQxPdY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 389651762; Thu, 17 Jul 2025 16:57:00 -0700 (PDT) Received: from localhost.localdomain (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id A28B13F694; Thu, 17 Jul 2025 16:57:06 -0700 (PDT) From: Andre Przywara To: u-boot@lists.denx.de Cc: Jernej Skrabec , Mikhail Kalashnikov , Yixun Lan , Paul Kocialkowski , linux-sunxi@lists.linux.dev, Tom Rini Subject: [PATCH v2 12/20] sunxi: sun50i_h6: add A523 SPL clock setup code Date: Fri, 18 Jul 2025 00:54:47 +0100 Message-ID: <20250717235455.32528-13-andre.przywara@arm.com> X-Mailer: git-send-email 2.46.3 In-Reply-To: <20250717235455.32528-1-andre.przywara@arm.com> References: <20250717235455.32528-1-andre.przywara@arm.com> Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Status: O From: Jernej Skrabec --- .../include/asm/arch-sunxi/clock_sun50i_h6.h | 10 ++++++ arch/arm/mach-sunxi/clock_sun50i_h6.c | 32 ++++++++++++++----- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h b/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h index 5881ab88573..699d75f37c4 100644 --- a/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h +++ b/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h @@ -108,6 +108,13 @@ #define CCM_PSI_AHB1_AHB2_DEFAULT 0x03000002 #define CCM_AHB3_DEFAULT 0x03000002 #define CCM_APB1_DEFAULT 0x03000102 + +#elif CONFIG_MACH_SUN55I_A523 /* A523 */ + +#define CCM_PLL6_DEFAULT 0xe8116310 /* 1200 MHz */ +#define CCM_PSI_AHB1_AHB2_DEFAULT 0x03000002 /* 200 MHz */ +#define CCM_APB1_DEFAULT 0x03000005 /* APB0 really */ +#define CCM_APB2_DEFAULT 0x03000005 /* APB1 really */ #endif /* apb2 bit field */ @@ -127,6 +134,7 @@ /* MBUS clock bit field */ #define MBUS_ENABLE BIT(31) #define MBUS_RESET BIT(30) +#define MBUS_UPDATE BIT(27) #define MBUS_CLK_SRC_MASK GENMASK(25, 24) #define MBUS_CLK_SRC_OSCM24 (0 << 24) #define MBUS_CLK_SRC_PLL6X2 (1 << 24) @@ -139,10 +147,12 @@ #define GATE_SHIFT (0) /* DRAM clock bit field */ +#define DRAM_CLK_ENABLE BIT(31) #define DRAM_MOD_RESET BIT(30) #define DRAM_CLK_UPDATE BIT(27) #define DRAM_CLK_SRC_MASK GENMASK(25, 24) #define DRAM_CLK_SRC_PLL5 (0 << 24) +#define DRAM_CLK_M_MASK (0x1f) #define DRAM_CLK_M(m) (((m)-1) << 0) /* MMC clock bit field */ diff --git a/arch/arm/mach-sunxi/clock_sun50i_h6.c b/arch/arm/mach-sunxi/clock_sun50i_h6.c index 3a4399a9c6c..80004f13a1e 100644 --- a/arch/arm/mach-sunxi/clock_sun50i_h6.c +++ b/arch/arm/mach-sunxi/clock_sun50i_h6.c @@ -16,15 +16,22 @@ void clock_init_safe(void) void *const ccm = (void *)SUNXI_CCM_BASE; void *const prcm = (void *)SUNXI_PRCM_BASE; - if (IS_ENABLED(CONFIG_MACH_SUN50I_H616)) { - /* this seems to enable PLLs on H616 */ + if (IS_ENABLED(CONFIG_MACH_SUN50I_H616)) setbits_le32(prcm + CCU_PRCM_SYS_PWROFF_GATING, 0x10); + if (IS_ENABLED(CONFIG_MACH_SUN55I_A523)) + setbits_le32(prcm + CCU_PRCM_SYS_PWROFF_GATING, 0x200); + udelay(1); + + if (IS_ENABLED(CONFIG_MACH_SUN50I_H616) || + IS_ENABLED(CONFIG_MACH_SUN55I_A523)) setbits_le32(prcm + CCU_PRCM_RES_CAL_CTRL, 2); - } + udelay(1); if (IS_ENABLED(CONFIG_MACH_SUN50I_H616) || - IS_ENABLED(CONFIG_MACH_SUN50I_H6)) { + IS_ENABLED(CONFIG_MACH_SUN50I_H6) || + IS_ENABLED(CONFIG_MACH_SUN55I_A523)) { clrbits_le32(prcm + CCU_PRCM_RES_CAL_CTRL, 1); + udelay(1); setbits_le32(prcm + CCU_PRCM_RES_CAL_CTRL, 1); } @@ -41,9 +48,10 @@ void clock_init_safe(void) while (!(readl(ccm + CCU_H6_PLL6_CFG) & CCM_PLL_LOCK)) ; - clrsetbits_le32(ccm + CCU_H6_CPU_AXI_CFG, - CCM_CPU_AXI_APB_MASK | CCM_CPU_AXI_AXI_MASK, - CCM_CPU_AXI_DEFAULT_FACTORS); + if (!IS_ENABLED(CONFIG_MACH_SUN55I_A523)) + clrsetbits_le32(ccm + CCU_H6_CPU_AXI_CFG, + CCM_CPU_AXI_APB_MASK | CCM_CPU_AXI_AXI_MASK, + CCM_CPU_AXI_DEFAULT_FACTORS); writel(CCM_PSI_AHB1_AHB2_DEFAULT, ccm + CCU_H6_PSI_AHB1_AHB2_CFG); #ifdef CCM_AHB3_DEFAULT @@ -55,7 +63,15 @@ void clock_init_safe(void) * The mux and factor are set, but the clock will be enabled in * DRAM initialization code. */ - writel(MBUS_CLK_SRC_PLL6X2 | MBUS_CLK_M(3), ccm + CCU_H6_MBUS_CFG); + if (IS_ENABLED(CONFIG_MACH_SUN55I_A523)) { + writel(MBUS_RESET, ccm + CCU_H6_MBUS_CFG); + udelay(1); + writel(MBUS_UPDATE | MBUS_CLK_SRC_OSCM24 | MBUS_CLK_M(4), + ccm + CCU_H6_MBUS_CFG); + } else { + writel(MBUS_CLK_SRC_PLL6X2 | MBUS_CLK_M(3), + ccm + CCU_H6_MBUS_CFG); + } } void clock_init_uart(void) From patchwork Thu Jul 17 23:54:48 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 1383 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 9A2C149641 for ; Thu, 17 Jul 2025 23:57:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752796633; cv=none; b=NKdnXSJzseKH/C8sWMFQBf615PGlvfJDd4tkNSEd7kpD0HUZ1fvyhcKn0Zq+44RfIUphiT/A/ZdtbEaLCkynsp+G03x9qznIyVrnXrAUuhDkFV076EsPIxrpQJY0KOUoxYHPu84YFPTPf7ek9mYQK41wcKww9YZgri90qwQ8mx8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752796633; c=relaxed/simple; bh=HnF2omHr10mVWDt0vXW1eFRkh1JBdgP2+8ASJJQh7F4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Si87Dbv+S6/zxAJjvi3H01x+xfv5ZxE5o2iWYarvdoOnCgvEEmEv6iDFUphouEJaUDiWY589EZVAsrILpYD/GlYaPf+qX+7OT4WyeJmrtZMzBXlK/wnpA8BCxKbHj6slLsFx13SNhmMGaEdf7Nfc9I7LbHy1ZFx4u3sB2DzDcas= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id C8655168F; Thu, 17 Jul 2025 16:57:01 -0700 (PDT) Received: from localhost.localdomain (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 07B083F694; Thu, 17 Jul 2025 16:57:07 -0700 (PDT) From: Andre Przywara To: u-boot@lists.denx.de Cc: Jernej Skrabec , Mikhail Kalashnikov , Yixun Lan , Paul Kocialkowski , linux-sunxi@lists.linux.dev, Tom Rini Subject: [PATCH v2 13/20] sunxi: A523: add DRAM initialisation routine Date: Fri, 18 Jul 2025 00:54:48 +0100 Message-ID: <20250717235455.32528-14-andre.przywara@arm.com> X-Mailer: git-send-email 2.46.3 In-Reply-To: <20250717235455.32528-1-andre.przywara@arm.com> References: <20250717235455.32528-1-andre.przywara@arm.com> Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Status: O From: Jernej Skrabec DRAM init code, as per reverse engineering and matching against previous SoCs. Supports LPDDR4 for now only. --- arch/arm/include/asm/arch-sunxi/dram.h | 2 + .../include/asm/arch-sunxi/dram_sun55i_a523.h | 153 ++ arch/arm/mach-sunxi/Kconfig | 22 +- arch/arm/mach-sunxi/Makefile | 2 + arch/arm/mach-sunxi/dram_sun55i_a523.c | 1466 +++++++++++++++++ arch/arm/mach-sunxi/dram_timings/Makefile | 1 + .../arm/mach-sunxi/dram_timings/a523_lpddr4.c | 119 ++ 7 files changed, 1761 insertions(+), 4 deletions(-) create mode 100644 arch/arm/include/asm/arch-sunxi/dram_sun55i_a523.h create mode 100644 arch/arm/mach-sunxi/dram_sun55i_a523.c create mode 100644 arch/arm/mach-sunxi/dram_timings/a523_lpddr4.c diff --git a/arch/arm/include/asm/arch-sunxi/dram.h b/arch/arm/include/asm/arch-sunxi/dram.h index 0708ae3ee3b..0eccb1e6c28 100644 --- a/arch/arm/include/asm/arch-sunxi/dram.h +++ b/arch/arm/include/asm/arch-sunxi/dram.h @@ -35,6 +35,8 @@ #include #elif defined(CONFIG_MACH_SUNIV) #include +#elif defined(CONFIG_MACH_SUN55I_A523) +#include #else #include #endif diff --git a/arch/arm/include/asm/arch-sunxi/dram_sun55i_a523.h b/arch/arm/include/asm/arch-sunxi/dram_sun55i_a523.h new file mode 100644 index 00000000000..503a431da4a --- /dev/null +++ b/arch/arm/include/asm/arch-sunxi/dram_sun55i_a523.h @@ -0,0 +1,153 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * t527 dram controller register and constant defines + * + * (C) Copyright 2024 Jernej Skrabec + */ + +#ifndef _SUNXI_DRAM_SUN55I_A523_H +#define _SUNXI_DRAM_SUN55I_A523_H + +#include + +enum sunxi_dram_type { + SUNXI_DRAM_TYPE_DDR3 = 3, + SUNXI_DRAM_TYPE_DDR4, + SUNXI_DRAM_TYPE_LPDDR3 = 7, + SUNXI_DRAM_TYPE_LPDDR4 +}; + +#define MCTL_COM_UNK_008 0x008 +#define MCTL_COM_MAER0 0x020 + +/* + * Controller registers seems to be the same or at least very similar + * to those in H6. + */ +struct sunxi_mctl_ctl_reg { + u32 mstr; /* 0x000 */ + u32 statr; /* 0x004 unused */ + u32 mstr1; /* 0x008 unused */ + u32 clken; /* 0x00c */ + u32 mrctrl0; /* 0x010 unused */ + u32 mrctrl1; /* 0x014 unused */ + u32 mrstatr; /* 0x018 unused */ + u32 mrctrl2; /* 0x01c unused */ + u32 derateen; /* 0x020 unused */ + u32 derateint; /* 0x024 unused */ + u8 reserved_0x028[8]; /* 0x028 */ + u32 pwrctl; /* 0x030 */ + u32 pwrtmg; /* 0x034 unused */ + u32 hwlpctl; /* 0x038 */ + u8 reserved_0x03c[20]; /* 0x03c */ + u32 rfshctl0; /* 0x050 unused */ + u32 rfshctl1; /* 0x054 unused */ + u8 reserved_0x058[8]; /* 0x05c */ + u32 rfshctl3; /* 0x060 */ + u32 rfshtmg; /* 0x064 */ + u8 reserved_0x068[104]; /* 0x068 */ + u32 init[8]; /* 0x0d0 */ + u32 dimmctl; /* 0x0f0 unused */ + u32 rankctl; /* 0x0f4 */ + u8 reserved_0x0f8[8]; /* 0x0f8 */ + u32 dramtmg[17]; /* 0x100 */ + u8 reserved_0x144[60]; /* 0x144 */ + u32 zqctl[3]; /* 0x180 */ + u32 zqstat; /* 0x18c unused */ + u32 dfitmg0; /* 0x190 */ + u32 dfitmg1; /* 0x194 */ + u32 dfilpcfg[2]; /* 0x198 unused */ + u32 dfiupd[3]; /* 0x1a0 */ + u32 reserved_0x1ac; /* 0x1ac */ + u32 dfimisc; /* 0x1b0 */ + u32 dfitmg2; /* 0x1b4 unused */ + u32 dfitmg3; /* 0x1b8 unused */ + u32 dfistat; /* 0x1bc */ + u32 dbictl; /* 0x1c0 */ + u8 reserved_0x1c4[60]; /* 0x1c4 */ + u32 addrmap[12]; /* 0x200 */ + u8 reserved_0x230[16]; /* 0x230 */ + u32 odtcfg; /* 0x240 */ + u32 odtmap; /* 0x244 */ + u8 reserved_0x248[8]; /* 0x248 */ + u32 sched[2]; /* 0x250 */ + u8 reserved_0x258[12]; /* 0x258 */ + u32 unk_0x264; /* 0x264 */ + u8 reserved_0x268[8]; /* 0x268 */ + u32 unk_0x270; /* 0x270 */ + u8 reserved_0x274[152]; /* 0x274 */ + u32 dbgcmd; /* 0x30c unused */ + u32 dbgstat; /* 0x310 unused */ + u8 reserved_0x314[12]; /* 0x314 */ + u32 swctl; /* 0x320 */ + u32 swstat; /* 0x324 */ + u8 reserved_0x328[7768];/* 0x328 */ + u32 unk_0x2180; /* 0x2180 */ + u8 reserved_0x2184[188];/* 0x2184 */ + u32 unk_0x2240; /* 0x2240 */ + u8 reserved_0x2244[3900];/* 0x2244 */ + u32 unk_0x3180; /* 0x3180 */ + u8 reserved_0x3184[188];/* 0x3184 */ + u32 unk_0x3240; /* 0x3240 */ + u8 reserved_0x3244[3900];/* 0x3244 */ + u32 unk_0x4180; /* 0x4180 */ + u8 reserved_0x4184[188];/* 0x4184 */ + u32 unk_0x4240; /* 0x4240 */ +}; +check_member(sunxi_mctl_ctl_reg, swstat, 0x324); +check_member(sunxi_mctl_ctl_reg, unk_0x4240, 0x4240); + +#define MSTR_DEVICETYPE_DDR3 BIT(0) +#define MSTR_DEVICETYPE_LPDDR2 BIT(2) +#define MSTR_DEVICETYPE_LPDDR3 BIT(3) +#define MSTR_DEVICETYPE_DDR4 BIT(4) +#define MSTR_DEVICETYPE_LPDDR4 BIT(5) +#define MSTR_DEVICETYPE_MASK GENMASK(5, 0) +#define MSTR_2TMODE BIT(10) +#define MSTR_BUSWIDTH_FULL (0 << 12) +#define MSTR_BUSWIDTH_HALF (1 << 12) +#define MSTR_ACTIVE_RANKS(x) ((((x) == 2) ? 3 : 1) << 24) +#define MSTR_BURST_LENGTH(x) (((x) >> 1) << 16) + +#define TPR10_CA_BIT_DELAY 0xffff0000 +#define TPR10_DX_BIT_DELAY0 BIT(17) +#define TPR10_DX_BIT_DELAY1 BIT(18) +#define TPR10_WRITE_LEVELING BIT(20) +#define TPR10_READ_CALIBRATION BIT(21) +#define TPR10_READ_TRAINING BIT(22) +#define TPR10_WRITE_TRAINING BIT(23) + +struct dram_para { + enum sunxi_dram_type type; + u32 dx_odt; + u32 dx_dri; + u32 ca_dri; + u32 tpr0; + u32 tpr1; + u32 tpr2; + u32 tpr6; + u32 tpr10; +}; + +struct dram_config { + u8 cols; + u8 rows; + u8 ranks; + u8 bus_full_width; + u32 clk; + u32 odt_en; + u32 tpr11; + u32 tpr12; + u32 tpr14; +}; + +static inline int ns_to_t(int nanoseconds, u32 clk) +{ + const unsigned int ctrl_freq = clk / 2; + + return DIV_ROUND_UP(ctrl_freq * nanoseconds, 1000); +} + +void mctl_set_timing_params(u32 clk); + +#endif /* _SUNXI_DRAM_SUN55I_T527_H */ diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig index 0a7c029b15a..8aa5f1b46bf 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig @@ -57,7 +57,12 @@ config DRAM_SUN50I_A133 Select this dram controller driver for some sun50i platforms, like A133. -if DRAM_SUN50I_H616 || DRAM_SUN50I_A133 +config DRAM_SUN55I_A523 + bool + help + Select this DRAM controller driver for A523/T527 SoCs. + +if DRAM_SUN50I_H616 || DRAM_SUN50I_A133 || DRAM_SUN55I_A523 config DRAM_SUNXI_DX_ODT hex "DRAM DX ODT parameter" help @@ -170,8 +175,8 @@ config DRAM_SUNXI_TPR13 config DRAM_SUNXI_TPR14 hex "DRAM TPR14 parameter" - depends on DRAM_SUN50I_A133 - default 0x0 + depends on DRAM_SUN50I_A133 || MACH_SUN55I_A523 + default 0x48484848 help TPR14 value from vendor DRAM settings. @@ -569,7 +574,7 @@ config ARM_BOOT_HOOK_RMR This allows both the SPL and the U-Boot proper to be entered in either mode and switch to AArch64 if needed. -if SUNXI_DRAM_DW || DRAM_SUN50I_H6 || DRAM_SUN50I_H616 || DRAM_SUN50I_A133 +if SUNXI_DRAM_DW || DRAM_SUN50I_H6 || DRAM_SUN50I_H616 || DRAM_SUN50I_A133 || DRAM_SUN55I_A523 config SUNXI_DRAM_DDR3 bool @@ -587,6 +592,7 @@ config SUNXI_DRAM_DDR4 choice prompt "DRAM Type and Timing" + default SUNXI_DRAM_A523_LPDDR4 if MACH_SUN55I_A523 default SUNXI_DRAM_DDR3_1333 if !MACH_SUN8I_V3S default SUNXI_DRAM_DDR2_V3S if MACH_SUN8I_V3S @@ -670,6 +676,13 @@ config SUNXI_DRAM_DDR2_V3S This option is only for the DDR2 memory chip which is co-packaged in Allwinner V3s SoC. +config SUNXI_DRAM_A523_LPDDR4 + bool "LPDDR4 DRAM chips on the A523/T527 DRAM controller" + select SUNXI_DRAM_LPDDR4 + depends on DRAM_SUN55I_A523 + help + This option is the LPDDR4 timing used by the stock boot0 by + Allwinner. endchoice endif @@ -690,6 +703,7 @@ config DRAM_CLK default 672 if MACH_SUN50I default 744 if MACH_SUN50I_H6 default 720 if MACH_SUN50I_H616 || MACH_SUN50I_A133 + default 1200 if MACH_SUN55I_A523 ---help--- Set the dram clock speed, valid range 240 - 480 (prior to sun9i), must be a multiple of 24. For the sun9i (A80), the tested values diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile index 8eff20b77bf..579530f27e3 100644 --- a/arch/arm/mach-sunxi/Makefile +++ b/arch/arm/mach-sunxi/Makefile @@ -47,4 +47,6 @@ obj-$(CONFIG_DRAM_SUN50I_H616) += dram_sun50i_h616.o dram_dw_helpers.o obj-$(CONFIG_DRAM_SUN50I_H616) += dram_timings/ obj-$(CONFIG_DRAM_SUN50I_A133) += dram_sun50i_a133.o obj-$(CONFIG_DRAM_SUN50I_A133) += dram_timings/ +obj-$(CONFIG_MACH_SUN55I_A523) += dram_sun55i_a523.o +obj-$(CONFIG_DRAM_SUN55I_A523) += dram_timings/ endif diff --git a/arch/arm/mach-sunxi/dram_sun55i_a523.c b/arch/arm/mach-sunxi/dram_sun55i_a523.c new file mode 100644 index 00000000000..a5c4fba7784 --- /dev/null +++ b/arch/arm/mach-sunxi/dram_sun55i_a523.c @@ -0,0 +1,1466 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * sun55i A523/A527/T527/H728 platform DRAM controller driver + * + * This driver supports DDR3 and LPDDR4 memory. + * + * (C) Copyright 2024 Jernej Skrabec + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void mctl_sys_init(u32 clk_rate) +{ + void * const ccm = (void *)SUNXI_CCM_BASE; + + /* Put all DRAM-related blocks to reset state */ + clrbits_le32(ccm + CCU_H6_MBUS_CFG, MBUS_ENABLE); + clrbits_le32(ccm + CCU_H6_MBUS_CFG, MBUS_RESET); + setbits_le32(ccm + CCU_H6_MBUS_CFG, MBUS_UPDATE); + clrbits_le32(ccm + CCU_H6_DRAM_GATE_RESET, BIT(GATE_SHIFT)); + udelay(5); + clrbits_le32(ccm + CCU_H6_DRAM_GATE_RESET, BIT(RESET_SHIFT)); + clrbits_le32(ccm + CCU_H6_PLL5_CFG, CCM_PLL_CTRL_EN); + clrsetbits_le32(ccm + CCU_H6_DRAM_CLK_CFG, + DRAM_CLK_ENABLE, DRAM_CLK_UPDATE); + + udelay(5); + + /* Set PLL5 rate to doubled DRAM clock rate */ + writel(CCM_PLL_CTRL_EN | CCM_PLL_LDO_EN | CCM_PLL_LOCK_EN | + CCM_PLL_OUT_EN | CCM_PLL5_CTRL_N(clk_rate * 2 / 24), + ccm + CCU_H6_PLL5_CFG); + mctl_await_completion(ccm + CCU_H6_PLL5_CFG, + CCM_PLL_LOCK, CCM_PLL_LOCK); + + /* Configure DRAM mod clock */ + writel(DRAM_CLK_SRC_PLL5, ccm + CCU_H6_DRAM_CLK_CFG); + writel(BIT(RESET_SHIFT), ccm + CCU_H6_DRAM_GATE_RESET); + udelay(5); + setbits_le32(ccm + CCU_H6_DRAM_GATE_RESET, BIT(GATE_SHIFT)); + + /* Configure MBUS and enable DRAM clock */ + setbits_le32(ccm + CCU_H6_MBUS_CFG, MBUS_RESET | MBUS_UPDATE); + setbits_le32(ccm + CCU_H6_MBUS_CFG, MBUS_ENABLE | MBUS_UPDATE); + + clrsetbits_le32(ccm + CCU_H6_DRAM_CLK_CFG, DRAM_CLK_M_MASK, + DRAM_CLK_ENABLE | DRAM_CLK_UPDATE | DRAM_CLK_M(4)); + udelay(5); +} + +static void mctl_set_addrmap(const struct dram_config *config) +{ + struct sunxi_mctl_ctl_reg * const mctl_ctl = + (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE; + u8 cols = config->cols; + u8 rows = config->rows; + u8 ranks = config->ranks; + + if (!config->bus_full_width) + cols -= 1; + + /* Ranks */ + if (ranks == 2) + mctl_ctl->addrmap[0] = 0x1F00 | (rows + cols - 3); + else + mctl_ctl->addrmap[0] = 0x1F1F; + + /* Banks, hardcoded to 8 banks now */ + mctl_ctl->addrmap[1] = (cols - 2) | (cols - 2) << 8 | (cols - 2) << 16; + + /* Columns */ + mctl_ctl->addrmap[2] = 0; + switch (cols) { + case 7: + mctl_ctl->addrmap[3] = 0x1F1F1F00; + mctl_ctl->addrmap[4] = 0x1F1F; + break; + case 8: + mctl_ctl->addrmap[3] = 0x1F1F0000; + mctl_ctl->addrmap[4] = 0x1F1F; + break; + case 9: + mctl_ctl->addrmap[3] = 0x1F000000; + mctl_ctl->addrmap[4] = 0x1F1F; + break; + case 10: + mctl_ctl->addrmap[3] = 0; + mctl_ctl->addrmap[4] = 0x1F1F; + break; + case 11: + mctl_ctl->addrmap[3] = 0; + mctl_ctl->addrmap[4] = 0x1F00; + break; + case 12: + mctl_ctl->addrmap[3] = 0; + mctl_ctl->addrmap[4] = 0; + break; + default: + panic("Unsupported DRAM configuration: column number invalid\n"); + } + + /* Rows */ + mctl_ctl->addrmap[5] = (cols - 3) | ((cols - 3) << 8) | + ((cols - 3) << 16) | ((cols - 3) << 24); + switch (rows) { + case 13: + mctl_ctl->addrmap[6] = (cols - 3) | 0x0F0F0F00; + mctl_ctl->addrmap[7] = 0x0F0F; + break; + case 14: + mctl_ctl->addrmap[6] = (cols - 3) | ((cols - 3) << 8) | + 0x0F0F0000; + mctl_ctl->addrmap[7] = 0x0F0F; + break; + case 15: + mctl_ctl->addrmap[6] = (cols - 3) | ((cols - 3) << 8) | + ((cols - 3) << 16) | 0x0F000000; + mctl_ctl->addrmap[7] = 0x0F0F; + break; + case 16: + mctl_ctl->addrmap[6] = (cols - 3) | ((cols - 3) << 8) | + ((cols - 3) << 16) | ((cols - 3) << 24); + mctl_ctl->addrmap[7] = 0x0F0F; + break; + case 17: + mctl_ctl->addrmap[6] = (cols - 3) | ((cols - 3) << 8) | + ((cols - 3) << 16) | ((cols - 3) << 24); + mctl_ctl->addrmap[7] = (cols - 3) | 0x0F00; + break; + case 18: + mctl_ctl->addrmap[6] = (cols - 3) | ((cols - 3) << 8) | + ((cols - 3) << 16) | ((cols - 3) << 24); + mctl_ctl->addrmap[7] = (cols - 3) | ((cols - 3) << 8); + break; + default: + panic("Unsupported DRAM configuration: row number invalid\n"); + } + + /* Bank groups, DDR4 only */ + mctl_ctl->addrmap[8] = 0x3F3F; +} + +#define MASK_BYTE(reg, nr) (((reg) >> ((nr) * 8)) & 0x1f) +static void mctl_phy_configure_odt(const struct dram_para *para) +{ + u32 val_lo, val_hi; + + val_hi = para->dx_dri; + val_lo = (para->type != SUNXI_DRAM_TYPE_LPDDR4) ? para->dx_dri : + (para->tpr1 & 0x1f1f1f1f) ? para->tpr1 : 0x04040404; + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x304, 0x1f1f0000, + (MASK_BYTE(val_hi, 0) << 24) | + (MASK_BYTE(val_lo, 0) << 16)); + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x484, 0x1f1f0000, + (MASK_BYTE(val_hi, 1) << 24) | + (MASK_BYTE(val_lo, 1) << 16)); + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x604, 0x1f1f0000, + (MASK_BYTE(val_hi, 2) << 24) | + (MASK_BYTE(val_lo, 2) << 16)); + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x784, 0x1f1f0000, + (MASK_BYTE(val_hi, 3) << 24) | + (MASK_BYTE(val_lo, 3) << 16)); + + val_lo = para->ca_dri; + val_hi = para->ca_dri; + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0xf4, 0x1f1f1f1f, + (MASK_BYTE(val_hi, 0) << 24) | + (MASK_BYTE(val_lo, 0) << 16) | + (MASK_BYTE(val_hi, 1) << 8) | + (MASK_BYTE(val_lo, 1))); + + val_hi = para->dx_odt; + val_lo = (para->type == SUNXI_DRAM_TYPE_LPDDR4) ? 0 : para->dx_odt; + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x304, 0x00001f1f, + (MASK_BYTE(val_hi, 0) << 8) | MASK_BYTE(val_lo, 0)); + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x484, 0x00001f1f, + (MASK_BYTE(val_hi, 1) << 8) | MASK_BYTE(val_lo, 1)); + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x604, 0x00001f1f, + (MASK_BYTE(val_hi, 2) << 8) | MASK_BYTE(val_lo, 2)); + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x784, 0x00001f1f, + (MASK_BYTE(val_hi, 3) << 8) | MASK_BYTE(val_lo, 3)); +} + +static bool mctl_phy_write_leveling(const struct dram_para *para, + const struct dram_config *config) +{ + u32 mr2, low, high, val = 0; + bool result = true; + + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 4, 0xf00, 0xe00); + + if (para->type == SUNXI_DRAM_TYPE_LPDDR4) { + if (config->clk <= 936) + mr2 = 0x1b; + else if (config->clk <= 1200) + mr2 = 0x2d; + else + mr2 = 0x36; + writeb(mr2, SUNXI_DRAM_PHY0_BASE + 3); + } + + low = readw(SUNXI_DRAM_PHY0_BASE + 2) | 4; + high = readw(SUNXI_DRAM_PHY0_BASE + 4); + writew(low, SUNXI_DRAM_PHY0_BASE + 2); + writew(high, SUNXI_DRAM_PHY0_BASE + 4); + + if (config->bus_full_width) + val = 0xf; + else + val = 3; + + mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x62), val, val); + + low = readw(SUNXI_DRAM_PHY0_BASE + 2) & 0xfffb; + high = readw(SUNXI_DRAM_PHY0_BASE + 4); + writew(low, SUNXI_DRAM_PHY0_BASE + 2); + writew(high, SUNXI_DRAM_PHY0_BASE + 4); + + val = readl(SUNXI_DRAM_PHY0_BASE + 0x96); + if (val == 0 || val == 0x3f) + result = false; + val = readl(SUNXI_DRAM_PHY0_BASE + 0x97); //TODO: ??? + if (val == 0 || val == 0x3f) + result = false; + val = readl(SUNXI_DRAM_PHY0_BASE + 0xc6); + if (val == 0 || val == 0x3f) + result = false; + val = readl(SUNXI_DRAM_PHY0_BASE + 0xc7); //TODO: ??? + if (val == 0 || val == 0x3f) + result = false; + + low = readw(SUNXI_DRAM_PHY0_BASE + 2) & 0xff3f; + high = readw(SUNXI_DRAM_PHY0_BASE + 4); + writew(low, SUNXI_DRAM_PHY0_BASE + 2); + writew(high, SUNXI_DRAM_PHY0_BASE + 4); + + if (config->ranks == 2) { + low = (readw(SUNXI_DRAM_PHY0_BASE + 2) & 0xff3f) | 0x40; + high = readw(SUNXI_DRAM_PHY0_BASE + 4); + writew(low, SUNXI_DRAM_PHY0_BASE + 2); + writew(high, SUNXI_DRAM_PHY0_BASE + 4); + + low = readw(SUNXI_DRAM_PHY0_BASE + 2) | 4; + high = readw(SUNXI_DRAM_PHY0_BASE + 4); + writew(low, SUNXI_DRAM_PHY0_BASE + 2); + writew(high, SUNXI_DRAM_PHY0_BASE + 4); + + if (config->bus_full_width) + val = 0xf; + else + val = 3; + + mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x62), val, val); + + low = readw(SUNXI_DRAM_PHY0_BASE + 2) & 0xfffb; + high = readw(SUNXI_DRAM_PHY0_BASE + 4); + writew(low, SUNXI_DRAM_PHY0_BASE + 2); + writew(high, SUNXI_DRAM_PHY0_BASE + 4); + } + + low = readw(SUNXI_DRAM_PHY0_BASE + 2) & 0xff3f; + high = readw(SUNXI_DRAM_PHY0_BASE + 4); + writew(low, SUNXI_DRAM_PHY0_BASE + 2); + writew(high, SUNXI_DRAM_PHY0_BASE + 4); + + return result; +} + +static bool mctl_phy_read_calibration(const struct dram_para *para, + const struct dram_config *config) +{ + bool result = true; + u32 val; + + if (para->type == SUNXI_DRAM_TYPE_LPDDR4) + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x44, 0x20000000); + + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 4, 0x3c, 0x38); + setbits_le32(SUNXI_DRAM_PHY0_BASE + 4, 1); + + if (config->bus_full_width) + val = 0xf; + else + val = 3; + + while ((readl(SUNXI_DRAM_PHY0_BASE + 0x20c) & val) != val) { + if (readl(SUNXI_DRAM_PHY0_BASE + 0x20c) & 0x20) { + result = false; + break; + } + } + + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 4, 1); + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 4, 0x3c); + + if (config->ranks == 2) { + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 4, 0x3c, 0x34); + setbits_le32(SUNXI_DRAM_PHY0_BASE + 4, 1); + + while ((readl(SUNXI_DRAM_PHY0_BASE + 0x20c) & val) != val) { + if (readl(SUNXI_DRAM_PHY0_BASE + 0x20c) & 0x20) { + result = false; + break; + } + } + + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 4, 1); + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 4, 0x3c); + } + + return result; +} + +static bool mctl_phy_read_training(const struct dram_para *para, + const struct dram_config *config) +{ + u32 val1, val2, *ptr1, *ptr2; + bool result = true; + int i; + + if (para->type == SUNXI_DRAM_TYPE_LPDDR4) { + writel(0, SUNXI_DRAM_PHY0_BASE + 0x200); + writeb(0, SUNXI_DRAM_PHY0_BASE + 0x207); + writeb(0, SUNXI_DRAM_PHY0_BASE + 0x208); + writeb(0, SUNXI_DRAM_PHY0_BASE + 0x209); + writeb(0, SUNXI_DRAM_PHY0_BASE + 0x20a); + } + + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x198, 3, 2); + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x804, 0x3f, 0xf); + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x808, 0x3f, 0xf); + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0xa04, 0x3f, 0xf); + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0xa08, 0x3f, 0xf); + + setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 6); + setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 1); + + mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x840), 0xc, 0xc); + if (readl(SUNXI_DRAM_PHY0_BASE + 0x840) & 3) + result = false; + + if (config->bus_full_width) { + mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0xa40), 0xc, 0xc); + if (readl(SUNXI_DRAM_PHY0_BASE + 0xa40) & 3) + result = false; + } + + ptr1 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x898); + ptr2 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x850); + for (i = 0; i < 9; i++) { + val1 = readl(&ptr1[i]); + val2 = readl(&ptr2[i]); + if (val1 - val2 <= 6) + result = false; + } + ptr1 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x8bc); + ptr2 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x874); + for (i = 0; i < 9; i++) { + val1 = readl(&ptr1[i]); + val2 = readl(&ptr2[i]); + if (val1 - val2 <= 6) + result = false; + } + + if (config->bus_full_width) { + ptr1 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xa98); + ptr2 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xa50); + for (i = 0; i < 9; i++) { + val1 = readl(&ptr1[i]); + val2 = readl(&ptr2[i]); + if (val1 - val2 <= 6) + result = false; + } + + ptr1 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xabc); + ptr2 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xa74); + for (i = 0; i < 9; i++) { + val1 = readl(&ptr1[i]); + val2 = readl(&ptr2[i]); + if (val1 - val2 <= 6) + result = false; + } + } + + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 3); + + if (config->ranks == 2) { + /* maybe last parameter should be 1? */ + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x198, 3, 2); + + setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 6); + setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 1); + + mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x840), 0xc, 0xc); + if (readl(SUNXI_DRAM_PHY0_BASE + 0x840) & 3) + result = false; + + if (config->bus_full_width) { + mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0xa40), 0xc, 0xc); + if (readl(SUNXI_DRAM_PHY0_BASE + 0xa40) & 3) + result = false; + } + + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 3); + } + + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x198, 3); + + return result; +} + +static bool mctl_phy_write_training(const struct dram_config *config) +{ + u32 val1, val2, *ptr1, *ptr2; + bool result = true; + int i; + + writel(0, SUNXI_DRAM_PHY0_BASE + 0x134); + writel(0, SUNXI_DRAM_PHY0_BASE + 0x138); + writel(0, SUNXI_DRAM_PHY0_BASE + 0x19c); + writel(0, SUNXI_DRAM_PHY0_BASE + 0x1a0); + + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x198, 0xc, 8); + + setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 0x10); + setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 0x20); + + mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x8e0), 3, 3); + if (readl(SUNXI_DRAM_PHY0_BASE + 0x8e0) & 0xc) + result = false; + + if (config->bus_full_width) { + mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0xae0), 3, 3); + if (readl(SUNXI_DRAM_PHY0_BASE + 0xae0) & 0xc) + result = false; + } + + ptr1 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x938); + ptr2 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x8f0); + for (i = 0; i < 9; i++) { + val1 = readl(&ptr1[i]); + val2 = readl(&ptr2[i]); + if (val1 - val2 <= 6) + result = false; + } + ptr1 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x95c); + ptr2 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x914); + for (i = 0; i < 9; i++) { + val1 = readl(&ptr1[i]); + val2 = readl(&ptr2[i]); + if (val1 - val2 <= 6) + result = false; + } + + if (config->bus_full_width) { + ptr1 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xb38); + ptr2 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xaf0); + for (i = 0; i < 9; i++) { + val1 = readl(&ptr1[i]); + val2 = readl(&ptr2[i]); + if (val1 - val2 <= 6) + result = false; + } + ptr1 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xb5c); + ptr2 = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xb14); + for (i = 0; i < 9; i++) { + val1 = readl(&ptr1[i]); + val2 = readl(&ptr2[i]); + if (val1 - val2 <= 6) + result = false; + } + } + + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 0x60); + + if (config->ranks == 2) { + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x198, 0xc, 4); + + setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 0x10); + setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 0x20); + + mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x8e0), 3, 3); + if (readl(SUNXI_DRAM_PHY0_BASE + 0x8e0) & 0xc) + result = false; + + if (config->bus_full_width) { + mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0xae0), 3, 3); + if (readl(SUNXI_DRAM_PHY0_BASE + 0xae0) & 0xc) + result = false; + } + + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, 0x60); + } + + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x198, 0xc); + + return result; +} + +static void mctl_phy_bit_delay_compensation(const struct dram_para *para, + const struct dram_config *config) +{ + u8 array0[32], array1[32]; + u32 tmp; + int i; + + for (i = 0; i < 32; i++) { + array0[i] = (config->tpr11 >> (i & 0xf8)) & 0xff; + array1[i] = (config->tpr12 >> (i & 0xf8)) & 0x7f; + } + + if (para->tpr10 & TPR10_DX_BIT_DELAY1) { + setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x84, 0x40000); + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0xa0, 3); + setbits_le32(SUNXI_DRAM_PHY0_BASE + 4, 0x80); + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x44, BIT(28)); + + writel(array0[0], SUNXI_DRAM_PHY0_BASE + 0x320); + writel((array0[0] << 24) | (array0[1] << 16) | + (array0[2] << 8) | + array0[3], SUNXI_DRAM_PHY0_BASE + 0x324); + writel((array0[4] << 24) | (array0[5] << 16) | + (array0[6] << 8) | + array0[7], SUNXI_DRAM_PHY0_BASE + 0x328); + + writel(array0[0], SUNXI_DRAM_PHY0_BASE + 0x340); + writel((array0[0] << 24) | (array0[1] << 16) | + (array0[2] << 8) | + array0[3], SUNXI_DRAM_PHY0_BASE + 0x344); + writel((array0[4] << 24) | (array0[5] << 16) | + (array0[6] << 8) | + array0[7], SUNXI_DRAM_PHY0_BASE + 0x348); + + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x40c, 0xff00, + array0[0] << 8); + writel((array0[0] << 24) | (array0[1] << 16) | + (array0[2] << 8) | array0[3], + SUNXI_DRAM_PHY0_BASE + 0x400); + writel((array0[4] << 24) | (array0[5] << 16) | + (array0[6] << 8) | array0[7], + SUNXI_DRAM_PHY0_BASE + 0x404); + + writel(array0[0], SUNXI_DRAM_PHY0_BASE + 0x41c); + writel((array0[0] << 24) | (array0[1] << 16) | + (array0[2] << 8) | array0[3], + SUNXI_DRAM_PHY0_BASE + 0x420); + writel((array0[4] << 24) | (array0[5] << 16) | + (array0[6] << 8) | array0[7], + SUNXI_DRAM_PHY0_BASE + 0x424); + + tmp = config->odt_en & 0xff; + tmp = (tmp << 24) | (tmp << 8); + writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x32c); + writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x34c); + writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x408); + writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x428); + + writel(array0[8], SUNXI_DRAM_PHY0_BASE + 0x4a0); + writel((array0[8] << 24) | (array0[9] << 16) | + (array0[10] << 8) | array0[11], + SUNXI_DRAM_PHY0_BASE + 0x4a4); + writel((array0[12] << 24) | (array0[13] << 16) | + (array0[14] << 8) | array0[15], + SUNXI_DRAM_PHY0_BASE + 0x4a8); + + writel(array0[8], SUNXI_DRAM_PHY0_BASE + 0x4c0); + writel((array0[8] << 24) | (array0[9] << 16) | + (array0[10] << 8) | array0[11], + SUNXI_DRAM_PHY0_BASE + 0x4c4); + writel((array0[12] << 24) | (array0[13] << 16) | + (array0[14] << 8) | array0[15], + SUNXI_DRAM_PHY0_BASE + 0x4c8); + + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x58c, 0xff00, + array0[8] << 8); + writel((array0[8] << 24) | (array0[9] << 16) | + (array0[10] << 8) | array0[11], + SUNXI_DRAM_PHY0_BASE + 0x580); + writel((array0[12] << 24) | (array0[13] << 16) | + (array0[14] << 8) | array0[15], + SUNXI_DRAM_PHY0_BASE + 0x584); + + writel(array0[8], SUNXI_DRAM_PHY0_BASE + 0x59c); + writel((array0[8] << 24) | (array0[9] << 16) | + (array0[10] << 8) | array0[11], + SUNXI_DRAM_PHY0_BASE + 0x5a0); + writel((array0[12] << 24) | (array0[13] << 16) | + (array0[14] << 8) | array0[15], + SUNXI_DRAM_PHY0_BASE + 0x5a4); + + tmp = (config->odt_en >> 8) & 0xff; + tmp = (tmp << 24) | (tmp << 8); + writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x4ac); + writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x4cc); + writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x588); + writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x5a8); + + writel(array0[16], SUNXI_DRAM_PHY0_BASE + 0x620); + writel((array0[16] << 24) | (array0[17] << 16) | + (array0[18] << 8) | array0[19], + SUNXI_DRAM_PHY0_BASE + 0x624); + writel((array0[20] << 24) | (array0[21] << 16) | + (array0[22] << 8) | array0[23], + SUNXI_DRAM_PHY0_BASE + 0x628); + + writel(array0[16], SUNXI_DRAM_PHY0_BASE + 0x640); + writel((array0[16] << 24) | (array0[17] << 16) | + (array0[18] << 8) | array0[19], + SUNXI_DRAM_PHY0_BASE + 0x644); + writel((array0[20] << 24) | (array0[21] << 16) | + (array0[22] << 8) | array0[23], + SUNXI_DRAM_PHY0_BASE + 0x648); + + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x70c, + 0xff00, array0[16] << 8); + writel((array0[16] << 24) | (array0[17] << 16) | + (array0[18] << 8) | array0[19], + SUNXI_DRAM_PHY0_BASE + 0x700); + writel((array0[20] << 24) | (array0[21] << 16) | + (array0[22] << 8) | array0[23], + SUNXI_DRAM_PHY0_BASE + 0x704); + + writel(array0[16], SUNXI_DRAM_PHY0_BASE + 0x71c); + writel((array0[16] << 24) | (array0[17] << 16) | + (array0[18] << 8) | array0[19], + SUNXI_DRAM_PHY0_BASE + 0x720); + writel((array0[20] << 24) | (array0[21] << 16) | + (array0[22] << 8) | array0[23], SUNXI_DRAM_PHY0_BASE + 0x724); + + tmp = (config->odt_en >> 16) & 0xff; + tmp = (tmp << 24) | (tmp << 8); + writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x62c); + writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x64c); + writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x708); + writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x728); + + writel(array0[24], SUNXI_DRAM_PHY0_BASE + 0x7a0); + writel((array0[24] << 24) | (array0[25] << 16) | + (array0[26] << 8) | array0[27], + SUNXI_DRAM_PHY0_BASE + 0x7a4); + writel((array0[28] << 24) | (array0[29] << 16) | + (array0[30] << 8) | array0[31], + SUNXI_DRAM_PHY0_BASE + 0x7a8); + + writel(array0[24], SUNXI_DRAM_PHY0_BASE + 0x7c0); + writel((array0[24] << 24) | (array0[25] << 16) | + (array0[26] << 8) | array0[27], + SUNXI_DRAM_PHY0_BASE + 0x7c4); + writel((array0[28] << 24) | (array0[29] << 16) | + (array0[30] << 8) | array0[31], + SUNXI_DRAM_PHY0_BASE + 0x7c8); + + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x88c, 0xff00, + array0[24] << 8); + writel((array0[24] << 24) | (array0[25] << 16) | + (array0[26] << 8) | array0[27], + SUNXI_DRAM_PHY0_BASE + 0x880); + writel((array0[28] << 24) | (array0[29] << 16) | + (array0[30] << 8) | array0[31], + SUNXI_DRAM_PHY0_BASE + 0x884); + + writel(array0[24], SUNXI_DRAM_PHY0_BASE + 0x89c); + writel((array0[24] << 24) | (array0[25] << 16) | + (array0[26] << 8) | array0[27], + SUNXI_DRAM_PHY0_BASE + 0x8a0); + writel((array0[28] << 24) | (array0[29] << 16) | + (array0[30] << 8) | array0[31], + SUNXI_DRAM_PHY0_BASE + 0x8a4); + + tmp = (config->odt_en >> 24) & 0xff; + tmp = (tmp << 24) | (tmp << 8); + writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x7ac); + writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x7cc); + writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x888); + writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x8a8); + + setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x44, BIT(28)); + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x44, BIT(28)); + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x84, 0x40000); + } + + if (para->tpr10 & TPR10_DX_BIT_DELAY0) { + setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x84, 0x40000); + + writel(array1[0] << 8, SUNXI_DRAM_PHY0_BASE + 0x330); + writel((array1[0] << 24) | (array1[1] << 16) | + (array1[2] << 8) | array1[3], + SUNXI_DRAM_PHY0_BASE + 0x334); + writel((array1[4] << 24) | (array1[5] << 16) | + (array1[6] << 8) | array1[7], + SUNXI_DRAM_PHY0_BASE + 0x338); + + writel(array1[0] << 8, SUNXI_DRAM_PHY0_BASE + 0x350); + writel((array1[0] << 24) | (array1[1] << 16) | + (array1[2] << 8) | array1[3], + SUNXI_DRAM_PHY0_BASE + 0x354); + writel((array1[4] << 24) | (array1[5] << 16) | + (array1[6] << 8) | array1[7], + SUNXI_DRAM_PHY0_BASE + 0x358); + + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x40c, 0xff, array1[0]); + writel((array1[0] << 24) | (array1[1] << 16) | + (array1[2] << 8) | array1[3], + SUNXI_DRAM_PHY0_BASE + 0x410); + writel((array1[4] << 24) | (array1[5] << 16) | + (array1[6] << 8) | array1[7], + SUNXI_DRAM_PHY0_BASE + 0x414); + + writel(array1[0] << 8, SUNXI_DRAM_PHY0_BASE + 0x42c); + writel((array1[0] << 24) | (array1[1] << 16) | + (array1[2] << 8) | array1[3], + SUNXI_DRAM_PHY0_BASE + 0x430); + writel((array1[4] << 24) | (array1[5] << 16) | + (array1[6] << 8) | array1[7], + SUNXI_DRAM_PHY0_BASE + 0x434); + + tmp = config->tpr14 & 0xff; + tmp = (tmp << 24) | (tmp << 8); + writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x33c); + writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x35c); + writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x418); + writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x438); + + writel(array1[8] << 8, SUNXI_DRAM_PHY0_BASE + 0x4b0); + writel((array1[8] << 24) | (array1[9] << 16) | + (array1[10] << 8) | array1[11], + SUNXI_DRAM_PHY0_BASE + 0x4b4); + writel((array1[12] << 24) | (array1[13] << 16) | + (array1[14] << 8) | array1[15], + SUNXI_DRAM_PHY0_BASE + 0x4b8); + + writel(array1[8] << 8, SUNXI_DRAM_PHY0_BASE + 0x4d0); + writel((array1[8] << 24) | (array1[9] << 16) | + (array1[10] << 8) | array1[11], + SUNXI_DRAM_PHY0_BASE + 0x4d4); + writel((array1[12] << 24) | (array1[13] << 16) | + (array1[14] << 8) | array1[15], + SUNXI_DRAM_PHY0_BASE + 0x4d8); + + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x58c, 0xff, array1[8]); + writel((array1[8] << 24) | (array1[9] << 16) | + (array1[10] << 8) | array1[11], + SUNXI_DRAM_PHY0_BASE + 0x590); + writel((array1[12] << 24) | (array1[13] << 16) | + (array1[14] << 8) | array1[15], + SUNXI_DRAM_PHY0_BASE + 0x594); + + writel(array1[8] << 8, SUNXI_DRAM_PHY0_BASE + 0x5ac); + writel((array1[8] << 24) | (array1[9] << 16) | + (array1[10] << 8) | array1[11], + SUNXI_DRAM_PHY0_BASE + 0x5b0); + writel((array1[12] << 24) | (array1[13] << 16) | + (array1[14] << 8) | array1[15], + SUNXI_DRAM_PHY0_BASE + 0x5b4); + + tmp = (config->tpr14 >> 8) & 0xff; + tmp = (tmp << 24) | (tmp << 8); + writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x4bc); + writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x4dc); + writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x598); + writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x5b8); + + writel(array1[16] << 8, SUNXI_DRAM_PHY0_BASE + 0x630); + writel((array1[16] << 24) | (array1[17] << 16) | + (array1[18] << 8) | array1[19], + SUNXI_DRAM_PHY0_BASE + 0x634); + writel((array1[20] << 24) | (array1[21] << 16) | + (array1[22] << 8) | array1[23], + SUNXI_DRAM_PHY0_BASE + 0x638); + + writel(array1[16] << 8, SUNXI_DRAM_PHY0_BASE + 0x650); + writel((array1[16] << 24) | (array1[17] << 16) | + (array1[18] << 8) | array1[19], + SUNXI_DRAM_PHY0_BASE + 0x654); + writel((array1[20] << 24) | (array1[21] << 16) | + (array1[22] << 8) | array1[23], + SUNXI_DRAM_PHY0_BASE + 0x658); + + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x70c, 0xff, array1[16]); + writel((array1[16] << 24) | (array1[17] << 16) | + (array1[18] << 8) | array1[19], + SUNXI_DRAM_PHY0_BASE + 0x710); + writel((array1[20] << 24) | (array1[21] << 16) | + (array1[22] << 8) | array1[23], + SUNXI_DRAM_PHY0_BASE + 0x714); + + writel(array1[16] << 8, SUNXI_DRAM_PHY0_BASE + 0x72c); + writel((array1[16] << 24) | (array1[17] << 16) | + (array1[18] << 8) | array1[19], + SUNXI_DRAM_PHY0_BASE + 0x730); + writel((array1[20] << 24) | (array1[21] << 16) | + (array1[22] << 8) | array1[23], + SUNXI_DRAM_PHY0_BASE + 0x734); + + tmp = (config->tpr14 >> 16) & 0xff; + tmp = (tmp << 24) | (tmp << 8); + writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x63c); + writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x65c); + writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x718); + writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x738); + + writel(array1[24] << 8, SUNXI_DRAM_PHY0_BASE + 0x7b0); + writel((array1[24] << 24) | (array1[25] << 16) | + (array1[26] << 8) | array1[27], + SUNXI_DRAM_PHY0_BASE + 0x7b4); + writel((array1[28] << 24) | (array1[29] << 16) | + (array1[30] << 8) | array1[31], + SUNXI_DRAM_PHY0_BASE + 0x7b8); + + writel(array1[24] << 8, SUNXI_DRAM_PHY0_BASE + 0x7d0); + writel((array1[24] << 24) | (array1[25] << 16) | + (array1[26] << 8) | array1[27], + SUNXI_DRAM_PHY0_BASE + 0x7d4); + writel((array1[28] << 24) | (array1[29] << 16) | + (array1[30] << 8) | array1[31], + SUNXI_DRAM_PHY0_BASE + 0x7d8); + + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x88c, 0xff, array1[24]); + writel((array1[24] << 24) | (array1[25] << 16) | + (array1[26] << 8) | array1[27], + SUNXI_DRAM_PHY0_BASE + 0x890); + writel((array1[28] << 24) | (array1[29] << 16) | + (array1[30] << 8) | array1[31], + SUNXI_DRAM_PHY0_BASE + 0x894); + + writel(array1[24] << 8, SUNXI_DRAM_PHY0_BASE + 0x8ac); + writel((array1[24] << 24) | (array1[25] << 16) | + (array1[26] << 8) | array1[27], + SUNXI_DRAM_PHY0_BASE + 0x8b0); + writel((array1[28] << 24) | (array1[29] << 16) | + (array1[30] << 8) | array1[31], + SUNXI_DRAM_PHY0_BASE + 0x8b4); + + tmp = (config->tpr14 >> 24) & 0xff; + tmp = (tmp << 24) | (tmp << 8); + writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x7bc); + writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x7dc); + writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x898); + writel(tmp, SUNXI_DRAM_PHY0_BASE + 0x8b8); + + setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x94, 4); + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x94, 4); + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x84, 0x40000); + } +} + +static void mctl_phy_ca_bit_delay_compensation(const struct dram_para *para, + const struct dram_config *config) +{ + u32 val, low, high; + + if (para->tpr10 & BIT(31)) { + val = para->tpr0; + } else { + val = ((para->tpr10 & 0xf0) << 5) | ((para->tpr10 & 0xf) << 1); + if (para->tpr10 >> 29) + val <<= 1; + } + + setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x84, 0x40000); + setbits_le32(SUNXI_DRAM_PHY0_BASE + 0xac, 0x1000); + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x48, 0xc0000000); + + switch (para->type) { + case SUNXI_DRAM_TYPE_LPDDR4: + low = val & 0xff; + high = (val >> 8) & 0xff; + + val = (high << 24) | (high << 16) | (high << 8) | high; + writel(val, SUNXI_DRAM_PHY0_BASE + 0x104); + writel(val, SUNXI_DRAM_PHY0_BASE + 0x108); + writel(val, SUNXI_DRAM_PHY0_BASE + 0x10c); + writel(val, SUNXI_DRAM_PHY0_BASE + 0x114); + writel(val, SUNXI_DRAM_PHY0_BASE + 0x118); + writel(val, SUNXI_DRAM_PHY0_BASE + 0x11c); + writel(val, SUNXI_DRAM_PHY0_BASE + 0x120); + + val = (high << 24) | (high << 16) | (low << 8) | low; + writel(val, SUNXI_DRAM_PHY0_BASE + 0x110); + + val = (low << 24) | (high << 16) | (low << 8) | high; + writel(val, SUNXI_DRAM_PHY0_BASE + 0x11c); + break; + default: + panic("This DRAM setup is currently not supported.\n"); + }; + + setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x38, 1); + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x38, 1); + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x84, 0x40000); +} + +static bool mctl_phy_init(const struct dram_para *para, + const struct dram_config *config) +{ + void * const mctl_com = (void *)SUNXI_DRAM_COM_BASE; + struct sunxi_mctl_ctl_reg * const mctl_ctl = + (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE; + void *const prcm = (void *)SUNXI_PRCM_BASE; + u32 val, val2, mr1, mr2; + int i; + + clrbits_le32(prcm + CCU_PRCM_SYS_PWROFF_GATING, 1); + udelay(1); + + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x84, 0x40000); + + if (config->bus_full_width) + val = 0xf00; + else + val = 0x300; + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x00, 0xf00, val); + + switch (para->type) { + case SUNXI_DRAM_TYPE_LPDDR4: + if (config->clk <= 936) { + val = 10; + val2 = 20; + } else if (config->clk <= 1200) { + val = 14; + val2 = 28; + } else { + val = 16; + val2 = 32; + } + break; + default: + panic("This DRAM setup is currently not supported.\n"); + }; + + writel((val << 24) | (val << 16) | (val << 8) | val, SUNXI_DRAM_PHY0_BASE + 0x10); + writel((val2 << 24) | (val2 << 16) | (val2 << 8) | val2, SUNXI_DRAM_PHY0_BASE + 0x0c); + writel(0, SUNXI_DRAM_PHY0_BASE + 0x08); + + switch (para->type) { + case SUNXI_DRAM_TYPE_LPDDR4: + writel(0x00010203, SUNXI_DRAM_PHY0_BASE + 0x54); + writel(0x04050607, SUNXI_DRAM_PHY0_BASE + 0x58); + writel(0x08090a0b, SUNXI_DRAM_PHY0_BASE + 0x5c); + writel(0x0c0d0e0f, SUNXI_DRAM_PHY0_BASE + 0x60); + writel(0x10111213, SUNXI_DRAM_PHY0_BASE + 0x64); + writel(0x14151617, SUNXI_DRAM_PHY0_BASE + 0x68); + writel(0x18191a1b, SUNXI_DRAM_PHY0_BASE + 0x6c); + writel(0x1c1d1e00, SUNXI_DRAM_PHY0_BASE + 0x70); + break; + default: + panic("This DRAM setup is currently not supported.\n"); + }; + + mctl_phy_configure_odt(para); + + if (para->tpr10 & TPR10_CA_BIT_DELAY) + mctl_phy_ca_bit_delay_compensation(para, config); + + switch (para->type) { + case SUNXI_DRAM_TYPE_LPDDR4: + val = 0x18fd6300; + break; + default: + panic("This DRAM setup is currently not supported.\n"); + }; + + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0xa8, 0xffffff00, val); + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x00, 0x70); + + switch (para->type) { + case SUNXI_DRAM_TYPE_LPDDR4: + val = 0x50; + break; + default: + panic("This DRAM setup is currently not supported.\n"); + }; + setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x00, val); + setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x00, 0x80); + + // TODO: fix intervals + if (config->clk - 251 < 250) { + val = 0x18000000; + val2 = 0x18181818; + } else if (config->clk - 126 < 125) { + val = 0x28000000; + val2 = 0x28282828; + } else if (config->clk < 126) { + val = 0x38000000; + val2 = 0x38383838; + } else { + val = 0x18000000; + val2 = 0; + } + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0xc0, 0x78000000, val); + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0xd0, 0x78787878, val2); + + clrbits_le32(mctl_com + MCTL_COM_UNK_008, BIT(9)); + udelay(10); + + switch (para->type) { + case SUNXI_DRAM_TYPE_LPDDR4: + val = para->tpr6 >> 24 & 0xff; + if (val) + val <<= 1; + else + val = 0x33; + break; + default: + panic("This DRAM setup is currently not supported.\n"); + }; + val <<= 23; + + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x300, 0xff800060, val | 0x40); + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x600, 0xff800060, val | 0x40); + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x480, 0xff800060, val | 0x40); + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x780, 0xff800060, val | 0x40); + setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x84, 0x8000000); + setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x94, 0x80); + udelay(10); + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x94, 0x80); + udelay(10); + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x84, 0x8000000); + + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x308, 0x200); + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x488, 0x200); + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x608, 0x200); + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x788, 0x200); + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x908, 0x200); + if (para->type == SUNXI_DRAM_TYPE_LPDDR4) { + setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x308, 0x200); + setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x488, 0x200); + setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x608, 0x200); + setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x788, 0x200); + setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x908, 0x200); + } + + if (config->clk < 936) + val = 0x1b000000; + else + val = 0xc000000; + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x14, 0x1f000000, val); + + setbits_le32(mctl_com + MCTL_COM_MAER0, BIT(8)); + + /* start DFI init */ + writel(0, &mctl_ctl->swctl); + setbits_le32(&mctl_ctl->dfimisc, 1); + setbits_le32(&mctl_ctl->dfimisc, 0x20); + writel(1, &mctl_ctl->swctl); + mctl_await_completion(&mctl_ctl->swstat, 1, 1); + mctl_await_completion(&mctl_ctl->dfistat, 1, 1); + + udelay(500); + setbits_le32(prcm + CCU_PRCM_SYS_PWROFF_GATING, 1); + udelay(1); + + writel(0, &mctl_ctl->swctl); + clrbits_le32(&mctl_ctl->dfimisc, 0x20); + writel(1, &mctl_ctl->swctl); + mctl_await_completion(&mctl_ctl->swstat, 1, 1); + + writel(0, &mctl_ctl->swctl); + clrbits_le32(&mctl_ctl->pwrctl, 0x20); + writel(1, &mctl_ctl->swctl); + mctl_await_completion(&mctl_ctl->swstat, 1, 1); + mctl_await_completion(&mctl_ctl->statr, 3, 1); + + udelay(500); + + writel(0, &mctl_ctl->swctl); + clrbits_le32(&mctl_ctl->dfimisc, 1); + writel(1, &mctl_ctl->swctl); + mctl_await_completion(&mctl_ctl->swstat, 1, 1); + + switch (para->type) { + case SUNXI_DRAM_TYPE_LPDDR4: + if (config->clk <= 936) { + mr1 = 0x34; + mr2 = 0x1b; + } else if (config->clk <= 1200) { + mr1 = 0x54; + mr2 = 0x2d; + } else { + mr1 = 0x64; + mr2 = 0x36; + } + + writel(0x0, &mctl_ctl->mrctrl1); + writel(0x800000f0, &mctl_ctl->mrctrl0); + mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0); + + writel(0x100 | mr1, &mctl_ctl->mrctrl1); + writel(0x800000f0, &mctl_ctl->mrctrl0); + mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0); + + writel(0x200 | mr2, &mctl_ctl->mrctrl1); + writel(0x800000f0, &mctl_ctl->mrctrl0); + mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0); + + writel(0x333, &mctl_ctl->mrctrl1); + writel(0x800000f0, &mctl_ctl->mrctrl0); + mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0); + + writel(0x403, &mctl_ctl->mrctrl1); + writel(0x800000f0, &mctl_ctl->mrctrl0); + mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0); + + writel(0xb04, &mctl_ctl->mrctrl1); + writel(0x800000f0, &mctl_ctl->mrctrl0); + mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0); + + writel(0xc72, &mctl_ctl->mrctrl1); + writel(0x800000f0, &mctl_ctl->mrctrl0); + mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0); + + writel(0xd00, &mctl_ctl->mrctrl1); + writel(0x800000f0, &mctl_ctl->mrctrl0); + mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0); + + writel(0xe08, &mctl_ctl->mrctrl1); + writel(0x800000f0, &mctl_ctl->mrctrl0); + mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0); + + writel(0x1626, &mctl_ctl->mrctrl1); + writel(0x800000f0, &mctl_ctl->mrctrl0); + mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0); + break; + default: + panic("This DRAM setup is currently not supported.\n"); + }; + + writel(0, &mctl_ctl->swctl); + clrbits_le32(&mctl_ctl->rfshctl3, 1); + writel(1, &mctl_ctl->swctl); + + if (para->tpr10 & TPR10_WRITE_LEVELING) { + for (i = 0; i < 5; i++) + if (mctl_phy_write_leveling(para, config)) + break; + if (i == 5) { + debug("write leveling failed!\n"); + return false; + } + } + + if (para->tpr10 & TPR10_READ_CALIBRATION) { + for (i = 0; i < 5; i++) + if (mctl_phy_read_calibration(para, config)) + break; + if (i == 5) { + debug("read calibration failed!\n"); + return false; + } + } + + if (para->tpr10 & TPR10_READ_TRAINING) { + for (i = 0; i < 5; i++) + if (mctl_phy_read_training(para, config)) + break; + if (i == 5) { + debug("read training failed!\n"); + return false; + } + } + + if (para->tpr10 & TPR10_WRITE_TRAINING) { + for (i = 0; i < 5; i++) + if (mctl_phy_write_training(config)) + break; + if (i == 5) { + debug("write training failed!\n"); + return false; + } + } + + mctl_phy_bit_delay_compensation(para, config); + + return true; +} + +static bool mctl_ctrl_init(const struct dram_para *para, + const struct dram_config *config) +{ + void * const mctl_com = (void *)SUNXI_DRAM_COM_BASE; + struct sunxi_mctl_ctl_reg * const mctl_ctl = + (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE; + u32 reg_val; + + clrsetbits_le32(mctl_com + MCTL_COM_UNK_008, BIT(24), BIT(25) | BIT(9)); + setbits_le32(mctl_com + MCTL_COM_MAER0, BIT(15) | BIT(9)); + + if (para->type == SUNXI_DRAM_TYPE_LPDDR4) { + setbits_le32(0x02023ea8, 1); // NSI + setbits_le32(0x02071008, 1); // NSI_CPU + } + + clrsetbits_le32(&mctl_ctl->sched[0], 0xff08, 0x3000); + clrsetbits_le32(&mctl_ctl->sched[1], 0x77000000, 0x33000000); + clrsetbits_le32(&mctl_ctl->unk_0x270, 0xffff, 0x808); + clrsetbits_le32(&mctl_ctl->unk_0x264, 0xff00ffff, 0x1f000030); + + writel(0, &mctl_ctl->hwlpctl); + + reg_val = MSTR_ACTIVE_RANKS(config->ranks); + switch (para->type) { + case SUNXI_DRAM_TYPE_LPDDR4: + reg_val |= MSTR_BURST_LENGTH(16) | MSTR_DEVICETYPE_LPDDR4; + break; + default: + panic("This DRAM setup is currently not supported.\n"); + }; + if (config->bus_full_width) + reg_val |= MSTR_BUSWIDTH_FULL; + else + reg_val |= MSTR_BUSWIDTH_HALF; + writel(BIT(31) | BIT(30) | reg_val, &mctl_ctl->mstr); + + if (config->ranks == 2) + writel(0x0303, &mctl_ctl->odtmap); + else + writel(0x0201, &mctl_ctl->odtmap); + + switch (para->type) { + case SUNXI_DRAM_TYPE_LPDDR4: + reg_val = 0x04000400; + break; + default: + panic("This DRAM setup is currently not supported.\n"); + }; + writel(reg_val, &mctl_ctl->odtcfg); + writel(reg_val, &mctl_ctl->unk_0x2240); + writel(reg_val, &mctl_ctl->unk_0x3240); + writel(reg_val, &mctl_ctl->unk_0x4240); + + mctl_set_addrmap(config); + + mctl_set_timing_params(config->clk); + + writel(0, &mctl_ctl->pwrctl); + + setbits_le32(&mctl_ctl->dfiupd[0], BIT(31) | BIT(30)); + setbits_le32(&mctl_ctl->zqctl[0], BIT(31) | BIT(30)); + setbits_le32(&mctl_ctl->unk_0x2180, BIT(31) | BIT(30)); + setbits_le32(&mctl_ctl->unk_0x3180, BIT(31) | BIT(30)); + setbits_le32(&mctl_ctl->unk_0x4180, BIT(31) | BIT(30)); + + if (para->type == SUNXI_DRAM_TYPE_LPDDR4) + setbits_le32(&mctl_ctl->dbictl, 0x1); + + setbits_le32(&mctl_ctl->rfshctl3, BIT(0)); + clrbits_le32(&mctl_ctl->dfimisc, BIT(0)); + + writel(0x20, &mctl_ctl->pwrctl); + setbits_le32(&mctl_ctl->clken, BIT(8)); + + clrsetbits_le32(mctl_com + MCTL_COM_UNK_008, BIT(24), BIT(9)); + udelay(1); + /* this write seems to enable PHY MMIO region */ + setbits_le32(mctl_com + MCTL_COM_UNK_008, BIT(24)); + + if (!mctl_phy_init(para, config)) + return false; + + writel(0, &mctl_ctl->swctl); + clrbits_le32(&mctl_ctl->rfshctl3, BIT(0)); + writel(1, &mctl_ctl->swctl); + mctl_await_completion(&mctl_ctl->swstat, 1, 1); + + return true; +} + +static bool mctl_core_init(const struct dram_para *para, + const struct dram_config *config) +{ + mctl_sys_init(config->clk); + + return mctl_ctrl_init(para, config); +} + +static void mctl_auto_detect_rank_width(const struct dram_para *para, + struct dram_config *config) +{ + /* this is minimum size that it's supported */ + config->cols = 8; + config->rows = 13; + + /* + * Strategy here is to test most demanding combination first and least + * demanding last, otherwise HW might not be fully utilized. For + * example, half bus width and rank = 1 combination would also work + * on HW with full bus width and rank = 2, but only 1/4 RAM would be + * visible. + */ + + debug("testing 32-bit width, rank = 2\n"); + config->bus_full_width = 1; + config->ranks = 2; + if (mctl_core_init(para, config)) + return; + + debug("testing 32-bit width, rank = 1\n"); + config->bus_full_width = 1; + config->ranks = 1; + if (mctl_core_init(para, config)) + return; + + debug("testing 16-bit width, rank = 2\n"); + config->bus_full_width = 0; + config->ranks = 2; + if (mctl_core_init(para, config)) + return; + + debug("testing 16-bit width, rank = 1\n"); + config->bus_full_width = 0; + config->ranks = 1; + if (mctl_core_init(para, config)) + return; + + panic("This DRAM setup is currently not supported.\n"); +} + +static void mctl_auto_detect_dram_size(const struct dram_para *para, + struct dram_config *config) +{ + /* detect row address bits */ + config->cols = 8; + config->rows = 16; + mctl_core_init(para, config); + + for (config->rows = 13; config->rows < 16; config->rows++) { + /* 8 banks, 8 bit per byte and 16/32 bit width */ + if (mctl_mem_matches((1 << (config->rows + config->cols + + 4 + config->bus_full_width)))) + break; + } + + /* detect column address bits */ + config->cols = 11; + mctl_core_init(para, config); + + for (config->cols = 8; config->cols < 11; config->cols++) { + /* 8 bits per byte and 16/32 bit width */ + if (mctl_mem_matches(1 << (config->cols + 1 + + config->bus_full_width))) + break; + } +} + +static unsigned long long mctl_calc_size(const struct dram_config *config) +{ + u8 width = config->bus_full_width ? 4 : 2; + + /* 8 banks */ + return (1ULL << (config->cols + config->rows + 3)) * width * config->ranks; +} + +static const struct dram_para para = { + .type = SUNXI_DRAM_TYPE_LPDDR4, + .dx_odt = CONFIG_DRAM_SUNXI_DX_ODT, + .dx_dri = CONFIG_DRAM_SUNXI_DX_DRI, + .ca_dri = CONFIG_DRAM_SUNXI_CA_DRI, + .tpr0 = CONFIG_DRAM_SUNXI_TPR0, + .tpr1 = CONFIG_DRAM_SUNXI_TPR1, + .tpr2 = CONFIG_DRAM_SUNXI_TPR2, + .tpr6 = CONFIG_DRAM_SUNXI_TPR6, + .tpr10 = CONFIG_DRAM_SUNXI_TPR10, +}; + +static void sunxi_nsi_init(void) +{ + /* IOMMU prio 3 */ + writel(0x1, 0x02021418); + writel(0xf, 0x02021414); + /* DE prio 2 */ + writel(0x1, 0x02021a18); + writel(0xa, 0x02021a14); + /* VE R prio 2 */ + writel(0x1, 0x02021618); + writel(0xa, 0x02021614); + /* VE RW prio 2 */ + writel(0x1, 0x02021818); + writel(0xa, 0x02021814); + /* ISP prio 2 */ + writel(0x1, 0x02020c18); + writel(0xa, 0x02020c14); + /* CSI prio 2 */ + writel(0x1, 0x02021c18); + writel(0xa, 0x02021c14); + /* NPU prio 2 */ + writel(0x1, 0x02020a18); + writel(0xa, 0x02020a14); + + /* close ra0 autogating */ + writel(0x0, 0x02023c00); + /* close ta autogating */ + writel(0x0, 0x02023e00); + /* close pcie autogating */ + writel(0x0, 0x02020600); +} + +static void init_something(void) + +{ + u32 *ptr = (u32 *)0x02000804; + + do { + *ptr++ = 0xffffffff; + } while (ptr != (u32 *)0x20008e4); + + writel(0, 0x07002400); + writel(0, 0x07002404); + writel(0, 0x07002408); + + writel(0xffffffff, 0x07002004); + writel(0xffffffff, 0x07002014); + writel(0xffffffff, 0x07002024); + setbits_le32(0x07010290, 7); + + writel(7, 0x02001f00); + writel(0xffff, 0x03002020); + writel(3, 0x020008e0); + writel(7, 0x07102008); +} + +unsigned long sunxi_dram_init(void) +{ + struct dram_config config; + unsigned long size; + + config.clk = 360; + switch (para.type) { + case SUNXI_DRAM_TYPE_LPDDR4: + config.odt_en = 0x84848484; + config.tpr11 = 0x9a9a9a9a; + config.tpr12 = 0x0e0f070a; + config.tpr14 = 0x48484848; + break; + default: + panic("This DRAM setup is currently not supported.\n"); + }; + + setbits_le32(0x03000160, BIT(8)); + clrbits_le32(0x03000168, 0x3f); + + mctl_auto_detect_rank_width(¶, &config); + mctl_auto_detect_dram_size(¶, &config); + + config.clk = CONFIG_DRAM_CLK; + config.odt_en = CONFIG_DRAM_SUNXI_ODT_EN; + config.tpr11 = CONFIG_DRAM_SUNXI_TPR11; + config.tpr12 = CONFIG_DRAM_SUNXI_TPR12; + config.tpr14 = CONFIG_DRAM_SUNXI_TPR14; + + mctl_core_init(¶, &config); + + size = mctl_calc_size(&config); + + sunxi_nsi_init(); + init_something(); + + return size; +}; diff --git a/arch/arm/mach-sunxi/dram_timings/Makefile b/arch/arm/mach-sunxi/dram_timings/Makefile index 4dc1f29fc08..41fee509d5d 100644 --- a/arch/arm/mach-sunxi/dram_timings/Makefile +++ b/arch/arm/mach-sunxi/dram_timings/Makefile @@ -8,3 +8,4 @@ obj-$(CONFIG_SUNXI_DRAM_H616_LPDDR3) += h616_lpddr3.o obj-$(CONFIG_SUNXI_DRAM_H616_LPDDR4) += h616_lpddr4_2133.o obj-$(CONFIG_SUNXI_DRAM_A133_DDR4) += a133_ddr4.o obj-$(CONFIG_SUNXI_DRAM_A133_LPDDR4) += a133_lpddr4.o +obj-$(CONFIG_SUNXI_DRAM_A523_LPDDR4) += a523_lpddr4.o diff --git a/arch/arm/mach-sunxi/dram_timings/a523_lpddr4.c b/arch/arm/mach-sunxi/dram_timings/a523_lpddr4.c new file mode 100644 index 00000000000..940a4d04d57 --- /dev/null +++ b/arch/arm/mach-sunxi/dram_timings/a523_lpddr4.c @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * sun55i A523 LPDDR4-2133 timings, as programmed by Allwinner's boot0 + * + * (C) Copyright 2024 Jernej Skrabec + * (C) Copyright 2023 Mikhail Kalashnikov + * + */ + +#include +#include + +void mctl_set_timing_params(u32 clk) +{ + struct sunxi_mctl_ctl_reg * const mctl_ctl = + (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE; + u8 tcl, tcwl, t_rdata_en, trtp, twr, tphy_wrlat; + unsigned int mr1, mr2; + + u8 tccd = 4; + u8 tfaw = ns_to_t(40, clk); + u8 trrd = max(ns_to_t(10, clk), 2); + u8 twtr = max(ns_to_t(10, clk), 4); + u8 trcd = max(ns_to_t(18, clk), 2); + u8 trc = ns_to_t(65, clk); + u8 txp = max(ns_to_t(8, clk), 2); + u8 trp = ns_to_t(21, clk); + u8 tras = ns_to_t(42, clk); + u16 trefi = ns_to_t(3904, clk) / 32; + u16 trfc = ns_to_t(280, clk); + u16 txsr = ns_to_t(290, clk); + + u8 tmrw = max(ns_to_t(14, clk), 5); + u8 tmod = 12; + u8 tcke = max(ns_to_t(15, clk), 2); + u8 tcksrx = max(ns_to_t(2, clk), 2); + u8 tcksre = max(ns_to_t(5, clk), 2); + u8 trasmax = (trefi * 9) / 32; + + if (clk <= 936) { + mr1 = 0x34; + mr2 = 0x1b; + tcl = 10; + tcwl = 5; + t_rdata_en = 17; + trtp = 4; + tphy_wrlat = 5; + twr = 10; + } else if (clk <= 1200) { + mr1 = 0x54; + mr2 = 0x2d; + tcl = 14; + tcwl = 7; + t_rdata_en = 25; + trtp = 6; + tphy_wrlat = 9; + twr = 15; + } else { + mr1 = 0x64; + mr2 = 0x36; + tcl = 16; + tcwl = 8; + t_rdata_en = 29; + trtp = 7; + tphy_wrlat = 11; + twr = 17; + } + + u8 tmrd = tmrw; + u8 tckesr = tcke; + u8 twtp = twr + 9 + tcwl; + u8 twr2rd = twtr + 9 + tcwl; + u8 trd2wr = ns_to_t(4, clk) + 7 - ns_to_t(1, clk) + tcl; + u8 txs = 4; + u8 txsdll = 16; + u8 txsabort = 4; + u8 txsfast = 4; + + /* set DRAM timing */ + writel((twtp << 24) | (tfaw << 16) | (trasmax << 8) | tras, + &mctl_ctl->dramtmg[0]); + writel((txp << 16) | (trtp << 8) | trc, &mctl_ctl->dramtmg[1]); + writel((tcwl << 24) | (tcl << 16) | (trd2wr << 8) | twr2rd, + &mctl_ctl->dramtmg[2]); + writel((tmrw << 20) | (tmrd << 12) | tmod, &mctl_ctl->dramtmg[3]); + writel((trcd << 24) | (tccd << 16) | (trrd << 8) | trp, + &mctl_ctl->dramtmg[4]); + writel((tcksrx << 24) | (tcksre << 16) | (tckesr << 8) | tcke, + &mctl_ctl->dramtmg[5]); + /* Value suggested by ZynqMP manual and used by libdram */ + writel((txp + 2) | 0x02020000, &mctl_ctl->dramtmg[6]); + writel((txsfast << 24) | (txsabort << 16) | (txsdll << 8) | txs, + &mctl_ctl->dramtmg[8]); + writel(0x00020208, &mctl_ctl->dramtmg[9]); + writel(0xE0C05, &mctl_ctl->dramtmg[10]); + writel(0x440C021C, &mctl_ctl->dramtmg[11]); + writel(8, &mctl_ctl->dramtmg[12]); + writel(0xA100002, &mctl_ctl->dramtmg[13]); + writel(txsr, &mctl_ctl->dramtmg[14]); + + clrsetbits_le32(&mctl_ctl->init[0], 0xC0000FFF, 0x558); + writel(0x01f20000, &mctl_ctl->init[1]); + writel(0x00001705, &mctl_ctl->init[2]); + writel(0, &mctl_ctl->dfimisc); + writel((mr1 << 16) | mr2, &mctl_ctl->init[3]); + writel(0x00330000, &mctl_ctl->init[4]); + writel(0x00040072, &mctl_ctl->init[6]); + writel(0x00260008, &mctl_ctl->init[7]); + + clrsetbits_le32(&mctl_ctl->rankctl, 0xff0, 0x660); + + /* Configure DFI timing */ + writel(tphy_wrlat | 0x2000000 | (t_rdata_en << 16) | 0x808000, + &mctl_ctl->dfitmg0); + writel(0x100202, &mctl_ctl->dfitmg1); + + /* set refresh timing */ + writel((trefi << 16) | trfc, &mctl_ctl->rfshtmg); +} From patchwork Thu Jul 17 23:54:50 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 1382 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id D177D2309BD for ; Thu, 17 Jul 2025 23:57:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752796634; cv=none; b=heyAzOsGkoi/RQ/WJzaoXpPEEwRce3sfciEcYQrXysV93WLoY304TAZVJcwUzWaS6daysn+7gj2T5UDlA0clJVgD8DAjeTqnbekpsekNwiLFM2trJdQLWXoxB9bvUhtgBD9I8hyDt1l09Y85eOasuZ95c5gone/EQARXxlXiqG4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752796634; c=relaxed/simple; bh=DyMQkUZzmDD76/50964nv3EZN2HsfN/I1V3yRpmTZwg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=bfbEaNLNYe9H6r4rUn89A1sVhIGjH70AssxFTL2I1zbWH1+uW0Lld72QhoZenrk+lkJOT1tAOXl6h5OOvtEimwDzMGnbqFzBhb/VusmsHaI8bcRN3PgfiZEHTAtTiOgfQ9qOMeDA3Ocz0JhIrFnpN3PqdI1vhY/OFUjHr5P2IdE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 8E6731BCA; Thu, 17 Jul 2025 16:57:04 -0700 (PDT) Received: from localhost.localdomain (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 04AD83F694; Thu, 17 Jul 2025 16:57:10 -0700 (PDT) From: Andre Przywara To: u-boot@lists.denx.de Cc: Jernej Skrabec , Mikhail Kalashnikov , Yixun Lan , Paul Kocialkowski , linux-sunxi@lists.linux.dev, Tom Rini Subject: [PATCH v2 15/20] sunxi: add basic A523 support Date: Fri, 18 Jul 2025 00:54:50 +0100 Message-ID: <20250717235455.32528-16-andre.przywara@arm.com> X-Mailer: git-send-email 2.46.3 In-Reply-To: <20250717235455.32528-1-andre.przywara@arm.com> References: <20250717235455.32528-1-andre.przywara@arm.com> Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Status: O Add the basic Kconfig options, addresses and other values for the existing Kconfig settings for the new Allwinner A523/T527/H728 SoC. Signed-off-by: Andre Przywara --- arch/arm/cpu/armv8/fel_utils.S | 5 +++-- arch/arm/mach-sunxi/Kconfig | 24 +++++++++++++++++++++--- arch/arm/mach-sunxi/board.c | 5 +++++ arch/arm/mach-sunxi/cpu_info.c | 2 ++ board/sunxi/board.c | 7 ++++++- common/spl/Kconfig | 4 +++- include/configs/sun55i.h | 11 +++++++++++ 7 files changed, 51 insertions(+), 7 deletions(-) create mode 100644 include/configs/sun55i.h diff --git a/arch/arm/cpu/armv8/fel_utils.S b/arch/arm/cpu/armv8/fel_utils.S index 6a7ec9a7ec1..ccddfaaf04c 100644 --- a/arch/arm/cpu/armv8/fel_utils.S +++ b/arch/arm/cpu/armv8/fel_utils.S @@ -41,10 +41,11 @@ ENTRY(return_to_fel) str w2, [x1] ldr w0, =0xfa50392f // CPU hotplug magic -#if defined(CONFIG_MACH_SUN50I_H616) || defined(CONFIG_MACH_SUN50I_A133) +#if defined(CONFIG_MACH_SUN50I_H616) || defined(CONFIG_MACH_SUN50I_A133) || \ + defined(CONFIG_MACH_SUN55I_A523) ldr w2, =(SUNXI_R_CPUCFG_BASE + 0x1c0) str w0, [x2], #0x4 -#elif CONFIG_MACH_SUN50I_H6 +#elif defined(CONFIG_MACH_SUN50I_H6) ldr w2, =(SUNXI_RTC_BASE + 0x1b8) // BOOT_CPU_HP_FLAG_REG str w0, [x2], #0x4 #else diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig index 8a19534c2ec..6a511c4fd39 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig @@ -214,6 +214,7 @@ config AXP_PMIC_BUS config SUNXI_SRAM_ADDRESS hex default 0x10000 if MACH_SUN9I || MACH_SUN50I || MACH_SUN50I_H5 + default 0x44000 if MACH_SUN55I_A523 default 0x20000 if SUN50I_GEN_H6 || SUNXI_GEN_NCAT2 default 0x0 ---help--- @@ -226,6 +227,7 @@ config SUNXI_RVBAR_ADDRESS hex depends on ARM64 default 0x08100040 if MACH_SUN50I_A133 + default 0x08000040 if MACH_SUN55I_A523 default 0x09010040 if SUN50I_GEN_H6 default 0x017000a0 ---help--- @@ -254,6 +256,7 @@ config SUNXI_BL31_BASE default 0x00044000 if MACH_SUN50I || MACH_SUN50I_H5 default 0x40000000 if MACH_SUN50I_H616 default 0x00104000 if SUN50I_GEN_H6 + default 0x00054000 if MACH_SUN55I_A523 default 0x0 help Address where BL31 (TF-A) is loaded, or zero if BL31 is not used. @@ -335,7 +338,7 @@ config MACH_SUNXI_H3_H5 # TODO: try out A80's 8GiB DRAM space config SUNXI_DRAM_MAX_SIZE hex - default 0x100000000 if MACH_SUN50I_H616 || MACH_SUN50I_A133 + default 0x100000000 if MACH_SUN50I_H616 || MACH_SUN50I_A133 || MACH_SUN55I_A523 default 0xC0000000 if MACH_SUN50I || MACH_SUN50I_H5 || MACH_SUN50I_H6 default 0x80000000 @@ -537,6 +540,16 @@ config MACH_SUN50I_A133 select SUN50I_GEN_H6 imply OF_UPSTREAM +config MACH_SUN55I_A523 + bool "sun55i (Allwinner A523/A527/T527/H728)" + select ARM64 + select SUNXI_GEN_NCAT2 + select SUNXI_NEW_PINCTRL + select DRAM_SUN55I_A523 + select FIT + select SPL_LOAD_FIT if SPL + imply OF_UPSTREAM + endchoice # The sun8i SoCs share a lot, this helps to avoid a lot of "if A23 || A33" @@ -728,7 +741,9 @@ endif config DRAM_ZQ int "sunxi dram zq value" - depends on !MACH_SUN50I_H616 && !MACH_SUN50I_A133 + depends on !MACH_SUN50I_H616 + depends on !MACH_SUN50I_A133 + depends on !MACH_SUN55I_A523 default 123 if MACH_SUN4I || MACH_SUN5I || MACH_SUN6I || \ MACH_SUN8I_A23 || MACH_SUN8I_A33 || MACH_SUN8I_A83T default 127 if MACH_SUN7I @@ -742,6 +757,7 @@ config DRAM_ZQ config DRAM_ODT_EN bool "sunxi dram odt enable" depends on !MACH_SUN50I_H616 + depends on !MACH_SUN55I_A523 default y if MACH_SUN8I_A23 default y if MACH_SUNXI_H3_H5 default y if MACH_SUN8I_R40 @@ -831,6 +847,7 @@ endif config SYS_CLK_FREQ default 408000000 if MACH_SUNIV + default 792000000 if MACH_SUN55I_A523 default 816000000 if MACH_SUN50I || MACH_SUN50I_H5 default 888000000 if MACH_SUN50I_H6 default 912000000 if MACH_SUN7I @@ -849,6 +866,7 @@ config SYS_CONFIG_NAME default "sun50i" if MACH_SUN50I_H6 default "sun50i" if MACH_SUN50I_H616 default "sun50i" if MACH_SUN50I_A133 + default "sun55i" if MACH_SUN55I_A523 config SYS_BOARD default "sunxi" @@ -915,7 +933,7 @@ config I2C1_ENABLE ---help--- See I2C0_ENABLE help text. -if SUNXI_GEN_SUN6I || SUN50I_GEN_H6 +if SUNXI_GEN_SUN6I || SUN50I_GEN_H6 || SUNXI_GEN_NCAT2 config R_I2C_ENABLE bool "Enable the PRCM I2C/TWI controller" # This is used for the pmic on H3 diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c index 13caefda884..fb4837c2082 100644 --- a/arch/arm/mach-sunxi/board.c +++ b/arch/arm/mach-sunxi/board.c @@ -141,6 +141,10 @@ static int gpio_init(void) sunxi_gpio_set_cfgpin(SUNXI_GPB(9), SUN50I_H616_GPH_UART0); sunxi_gpio_set_cfgpin(SUNXI_GPB(10), SUN50I_H616_GPH_UART0); sunxi_gpio_set_pull(SUNXI_GPB(10), SUNXI_GPIO_PULL_UP); +#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN55I_A523) + sunxi_gpio_set_cfgpin(SUNXI_GPB(9), 2); + sunxi_gpio_set_cfgpin(SUNXI_GPB(10), 2); + sunxi_gpio_set_pull(SUNXI_GPB(10), SUNXI_GPIO_PULL_UP); #elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN8I_A83T) sunxi_gpio_set_cfgpin(SUNXI_GPB(9), SUN8I_A83T_GPB_UART0); sunxi_gpio_set_cfgpin(SUNXI_GPB(10), SUN8I_A83T_GPB_UART0); @@ -197,6 +201,7 @@ static int gpio_init(void) if (IS_ENABLED(CONFIG_SUN50I_GEN_H6) || IS_ENABLED(CONFIG_SUN50I_GEN_NCAT2)) { val = readl(SUNXI_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_VAL); + /* TODO: A523: keep only the lower two bits? */ writel(val, SUNXI_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_SEL); } if (IS_ENABLED(CONFIG_SUN50I_GEN_H6)) { diff --git a/arch/arm/mach-sunxi/cpu_info.c b/arch/arm/mach-sunxi/cpu_info.c index 3f4735d4717..c3a51d9956e 100644 --- a/arch/arm/mach-sunxi/cpu_info.c +++ b/arch/arm/mach-sunxi/cpu_info.c @@ -106,6 +106,8 @@ int print_cpuinfo(void) puts("CPU: Allwinner H616 (SUN50I)\n"); #elif defined CONFIG_MACH_SUN50I_A133 puts("CPU: Allwinner A133 (SUN50I)\n"); +#elif defined CONFIG_MACH_SUN55I_A523 + puts("CPU: Allwinner A523 (SUN55I)\n"); #else #warning Please update cpu_info.c with correct CPU information puts("CPU: SUNXI Family\n"); diff --git a/board/sunxi/board.c b/board/sunxi/board.c index 943b6221b8a..2929bc17f08 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -118,6 +118,10 @@ void i2c_init_board(void) clock_twi_onoff(5, 1); sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN50I_H616_GPL_R_TWI); sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN50I_H616_GPL_R_TWI); +#elif CONFIG_MACH_SUN55I_A523 + clock_twi_onoff(5, 1); + sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN50I_GPL_R_TWI); + sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN50I_GPL_R_TWI); #else clock_twi_onoff(5, 1); sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN8I_H3_GPL_R_TWI); @@ -435,7 +439,8 @@ static void mmc_pinmux_setup(int sdc) sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); sunxi_gpio_set_drv(pin, 2); } -#elif defined(CONFIG_MACH_SUN50I_H616) || defined(CONFIG_MACH_SUN50I_A133) +#elif defined(CONFIG_MACH_SUN50I_H616) || defined(CONFIG_MACH_SUN50I_A133) || \ + defined(CONFIG_MACH_SUN55I_A523) /* SDC2: PC0-PC1, PC5-PC6, PC8-PC11, PC13-PC16 */ for (pin = SUNXI_GPC(0); pin <= SUNXI_GPC(16); pin++) { if (pin > SUNXI_GPC(1) && pin < SUNXI_GPC(5)) diff --git a/common/spl/Kconfig b/common/spl/Kconfig index f69eff21107..f89f20a598e 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -80,7 +80,7 @@ config SPL_MAX_SIZE default 0x1b000 if AM33XX && !TI_SECURE_DEVICE default 0xec00 if OMAP34XX default 0x10000 if ARCH_MX6 && !MX6_OCRAM_256KB - default 0xbfa0 if MACH_SUN50I_H616 || MACH_SUN50I_A133 + default 0xbfa0 if MACH_SUN50I_H616 || MACH_SUN50I_A133 || MACH_SUN55I_A523 default 0x7000 if RCAR_GEN3 default 0x5fa0 if SUNXI_SRAM_ADDRESS = 0x0 default 0x7fa0 if ARCH_SUNXI @@ -278,6 +278,7 @@ config SPL_TEXT_BASE default 0x00912000 if ARCH_MX7 default 0x40301350 if OMAP54XX default 0x10060 if MACH_SUN50I || MACH_SUN50I_H5 || MACH_SUN9I + default 0x44060 if MACH_SUN55I_A523 default 0x20060 if SUN50I_GEN_H6 || SUNXI_GEN_NCAT2 default 0x00060 if ARCH_SUNXI default 0xfffc0000 if ARCH_ZYNQMP @@ -425,6 +426,7 @@ config SPL_STACK default 0x118000 if MACH_SUN50I_H6 default 0x52a00 if MACH_SUN50I_H616 default 0x40000 if MACH_SUN8I_R528 || MACH_SUN50I_A133 + default 0x44000 if MACH_SUN55I_A523 default 0x54000 if MACH_SUN50I || MACH_SUN50I_H5 default 0x18000 if MACH_SUN9I default 0x8000 if ARCH_SUNXI diff --git a/include/configs/sun55i.h b/include/configs/sun55i.h new file mode 100644 index 00000000000..70649366c1c --- /dev/null +++ b/include/configs/sun55i.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Placeholder wrapper to allow addressing Allwinner devices with Cortex-A55 + * cores separately. Please do not add anything in here. + */ +#ifndef __CONFIG_H +#define __CONFIG_H + +#include + +#endif /* __CONFIG_H */ From patchwork Thu Jul 17 23:54:51 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 1381 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id BB7E549641 for ; Thu, 17 Jul 2025 23:57:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752796635; cv=none; b=X6/97Zz9QmZ8PlQRfhkf1hcl0pVlIH0EBNRaapsqX7ZjjPkvPwzClzYNGuveiRUTzO8MWFJHZnejkJ7IpLldhoRUiGWeUgT7xJt5IEicUjWnEUM7en++zIdNx+6c7n7fy7VUxd/8vTAosOEY4ktI91R0wcHCbSt1lxf0Kaai5yY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752796635; c=relaxed/simple; bh=RbxgaBWASICNxOYt3EiyIqlbNdNhB9e8DVlEH8GDVIA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mxSTuGYuc5uLJTYlG77GgHZe3FUhASIJEQqYHYcoymz/S97PRMOZiqWkZ8P1nBXf3tlnTdsgwu3CcZfkLRRW79ANX6TSaSxbIfuwCJE6LW4+Z3aghcb6HCDSOyM9AnPqc+ry0bSkiVL8E3Y6pOVKdQ4J8h1/9AjEnz3CmLR+5zQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id E7157168F; Thu, 17 Jul 2025 16:57:05 -0700 (PDT) Received: from localhost.localdomain (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 5D5F43F694; Thu, 17 Jul 2025 16:57:12 -0700 (PDT) From: Andre Przywara To: u-boot@lists.denx.de Cc: Jernej Skrabec , Mikhail Kalashnikov , Yixun Lan , Paul Kocialkowski , linux-sunxi@lists.linux.dev, Tom Rini Subject: [PATCH v2 16/20] arm64: dts: allwinner: Add Allwinner A523 .dtsi file Date: Fri, 18 Jul 2025 00:54:51 +0100 Message-ID: <20250717235455.32528-17-andre.przywara@arm.com> X-Mailer: git-send-email 2.46.3 In-Reply-To: <20250717235455.32528-1-andre.przywara@arm.com> References: <20250717235455.32528-1-andre.przywara@arm.com> Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Status: O The Allwinner A523, and its siblings A527 and T527, which share the same die, are a new family of SoCs introduced in 2023. They features eight Arm Cortex-A55 cores, and, among the other usual peripherals, a PCIe and USB 3.0 controller. Add the basic SoC devicetree .dtsi for the chip, describing the fundamental peripherals: the cores, GIC, timer, RTC, CCU and pinctrl. Also some other peripherals are fully compatible with previous IP, so add the USB and MMC nodes as well. The other peripherals will be added in the future, once we understand their compatibility and DT requirements. Signed-off-by: Andre Przywara Reviewed-by: Jernej Skrabec Link: https://patch.msgid.link/20250307005712.16828-9-andre.przywara@arm.com Signed-off-by: Chen-Yu Tsai [ upstream commit: 35ac96f796649346c9b0440413dc6c5138249b3e ] (cherry picked from commit 247a3572abcfd7a0d48e12f8f810f1cbae5ce4f4) --- .../src/arm64/allwinner/sun55i-a523.dtsi | 598 ++++++++++++++++++ 1 file changed, 598 insertions(+) create mode 100644 dts/upstream/src/arm64/allwinner/sun55i-a523.dtsi diff --git a/dts/upstream/src/arm64/allwinner/sun55i-a523.dtsi b/dts/upstream/src/arm64/allwinner/sun55i-a523.dtsi new file mode 100644 index 00000000000..ee485899ba0 --- /dev/null +++ b/dts/upstream/src/arm64/allwinner/sun55i-a523.dtsi @@ -0,0 +1,598 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR MIT) +// Copyright (C) 2023-2024 Arm Ltd. + +#include +#include +#include +#include +#include +#include + +/ { + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + compatible = "arm,cortex-a55"; + device_type = "cpu"; + reg = <0x000>; + enable-method = "psci"; + }; + + cpu1: cpu@100 { + compatible = "arm,cortex-a55"; + device_type = "cpu"; + reg = <0x100>; + enable-method = "psci"; + }; + + cpu2: cpu@200 { + compatible = "arm,cortex-a55"; + device_type = "cpu"; + reg = <0x200>; + enable-method = "psci"; + }; + + cpu3: cpu@300 { + compatible = "arm,cortex-a55"; + device_type = "cpu"; + reg = <0x300>; + enable-method = "psci"; + }; + + cpu4: cpu@400 { + compatible = "arm,cortex-a55"; + device_type = "cpu"; + reg = <0x400>; + enable-method = "psci"; + }; + + cpu5: cpu@500 { + compatible = "arm,cortex-a55"; + device_type = "cpu"; + reg = <0x500>; + enable-method = "psci"; + }; + + cpu6: cpu@600 { + compatible = "arm,cortex-a55"; + device_type = "cpu"; + reg = <0x600>; + enable-method = "psci"; + }; + + cpu7: cpu@700 { + compatible = "arm,cortex-a55"; + device_type = "cpu"; + reg = <0x700>; + enable-method = "psci"; + }; + }; + + osc24M: osc24M-clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <24000000>; + clock-output-names = "osc24M"; + }; + + pmu { + compatible = "arm,cortex-a55-pmu"; + interrupts = ; + }; + + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; + + timer { + compatible = "arm,armv8-timer"; + arm,no-tick-in-suspend; + interrupts = , + , + , + ; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x0 0x0 0x40000000>; + + pio: pinctrl@2000000 { + compatible = "allwinner,sun55i-a523-pinctrl"; + reg = <0x2000000 0x800>; + interrupts = , + , + , + , + , + , + , + , + , + ; + clocks = <&ccu CLK_APB1>, <&osc24M>, <&rtc CLK_OSC32K>; + clock-names = "apb", "hosc", "losc"; + gpio-controller; + #gpio-cells = <3>; + interrupt-controller; + #interrupt-cells = <3>; + + mmc0_pins: mmc0-pins { + pins = "PF0" ,"PF1", "PF2", "PF3", "PF4", "PF5"; + allwinner,pinmux = <2>; + function = "mmc0"; + drive-strength = <30>; + bias-pull-up; + }; + + /omit-if-no-ref/ + mmc1_pins: mmc1-pins { + pins = "PG0" ,"PG1", "PG2", "PG3", "PG4", "PG5"; + allwinner,pinmux = <2>; + function = "mmc1"; + drive-strength = <30>; + bias-pull-up; + }; + + mmc2_pins: mmc2-pins { + pins = "PC0", "PC1" ,"PC5", "PC6", "PC8", + "PC9", "PC10", "PC11", "PC13", "PC14", + "PC15", "PC16"; + allwinner,pinmux = <3>; + function = "mmc2"; + drive-strength = <30>; + bias-pull-up; + }; + + uart0_pb_pins: uart0-pb-pins { + pins = "PB9", "PB10"; + allwinner,pinmux = <2>; + function = "uart0"; + }; + }; + + ccu: clock-controller@2001000 { + compatible = "allwinner,sun55i-a523-ccu"; + reg = <0x02001000 0x1000>; + clocks = <&osc24M>, <&rtc CLK_OSC32K>, + <&rtc CLK_IOSC>, <&rtc CLK_OSC32K_FANOUT>; + clock-names = "hosc", "losc", + "iosc", "losc-fanout"; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + mmc0: mmc@4020000 { + compatible = "allwinner,sun55i-a523-mmc", + "allwinner,sun20i-d1-mmc"; + reg = <0x04020000 0x1000>; + clocks = <&ccu CLK_BUS_MMC0>, <&ccu CLK_MMC0>; + clock-names = "ahb", "mmc"; + resets = <&ccu RST_BUS_MMC0>; + reset-names = "ahb"; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins>; + status = "disabled"; + + max-frequency = <150000000>; + cap-sd-highspeed; + cap-mmc-highspeed; + cap-sdio-irq; + #address-cells = <1>; + #size-cells = <0>; + }; + + mmc1: mmc@4021000 { + compatible = "allwinner,sun55i-a523-mmc", + "allwinner,sun20i-d1-mmc"; + reg = <0x04021000 0x1000>; + clocks = <&ccu CLK_BUS_MMC1>, <&ccu CLK_MMC1>; + clock-names = "ahb", "mmc"; + resets = <&ccu RST_BUS_MMC1>; + reset-names = "ahb"; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&mmc1_pins>; + status = "disabled"; + + max-frequency = <150000000>; + cap-sd-highspeed; + cap-mmc-highspeed; + cap-sdio-irq; + #address-cells = <1>; + #size-cells = <0>; + }; + + mmc2: mmc@4022000 { + compatible = "allwinner,sun55i-a523-mmc", + "allwinner,sun20i-d1-mmc"; + reg = <0x04022000 0x1000>; + clocks = <&ccu CLK_BUS_MMC2>, <&ccu CLK_MMC2>; + clock-names = "ahb", "mmc"; + resets = <&ccu RST_BUS_MMC2>; + reset-names = "ahb"; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&mmc2_pins>; + status = "disabled"; + + max-frequency = <150000000>; + cap-sd-highspeed; + cap-mmc-highspeed; + cap-sdio-irq; + #address-cells = <1>; + #size-cells = <0>; + }; + + wdt: watchdog@2050000 { + compatible = "allwinner,sun55i-a523-wdt"; + reg = <0x2050000 0x20>; + interrupts = ; + clocks = <&osc24M>, <&rtc CLK_OSC32K>; + clock-names = "hosc", "losc"; + status = "okay"; + }; + + uart0: serial@2500000 { + compatible = "snps,dw-apb-uart"; + reg = <0x02500000 0x400>; + interrupts = ; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&ccu CLK_BUS_UART0>; + resets = <&ccu RST_BUS_UART0>; + status = "disabled"; + }; + + uart1: serial@2500400 { + compatible = "snps,dw-apb-uart"; + reg = <0x02500400 0x400>; + interrupts = ; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&ccu CLK_BUS_UART1>; + resets = <&ccu RST_BUS_UART1>; + status = "disabled"; + }; + + uart2: serial@2500800 { + compatible = "snps,dw-apb-uart"; + reg = <0x02500800 0x400>; + interrupts = ; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&ccu CLK_BUS_UART2>; + resets = <&ccu RST_BUS_UART2>; + status = "disabled"; + }; + + uart3: serial@2500c00 { + compatible = "snps,dw-apb-uart"; + reg = <0x02500c00 0x400>; + interrupts = ; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&ccu CLK_BUS_UART3>; + resets = <&ccu RST_BUS_UART3>; + status = "disabled"; + }; + + uart4: serial@2501000 { + compatible = "snps,dw-apb-uart"; + reg = <0x02501000 0x400>; + interrupts = ; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&ccu CLK_BUS_UART4>; + resets = <&ccu RST_BUS_UART4>; + status = "disabled"; + }; + + uart5: serial@2501400 { + compatible = "snps,dw-apb-uart"; + reg = <0x02501400 0x400>; + interrupts = ; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&ccu CLK_BUS_UART5>; + resets = <&ccu RST_BUS_UART5>; + status = "disabled"; + }; + + uart6: serial@2501800 { + compatible = "snps,dw-apb-uart"; + reg = <0x02501800 0x400>; + interrupts = ; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&ccu CLK_BUS_UART6>; + resets = <&ccu RST_BUS_UART6>; + status = "disabled"; + }; + + uart7: serial@2501c00 { + compatible = "snps,dw-apb-uart"; + reg = <0x02501c00 0x400>; + interrupts = ; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&ccu CLK_BUS_UART7>; + resets = <&ccu RST_BUS_UART7>; + status = "disabled"; + }; + + i2c0: i2c@2502000 { + compatible = "allwinner,sun55i-a523-i2c", + "allwinner,sun8i-v536-i2c", + "allwinner,sun6i-a31-i2c"; + reg = <0x2502000 0x400>; + interrupts = ; + clocks = <&ccu CLK_BUS_I2C0>; + resets = <&ccu RST_BUS_I2C0>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c1: i2c@2502400 { + compatible = "allwinner,sun55i-a523-i2c", + "allwinner,sun8i-v536-i2c", + "allwinner,sun6i-a31-i2c"; + reg = <0x2502400 0x400>; + interrupts = ; + clocks = <&ccu CLK_BUS_I2C1>; + resets = <&ccu RST_BUS_I2C1>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c2: i2c@2502800 { + compatible = "allwinner,sun55i-a523-i2c", + "allwinner,sun8i-v536-i2c", + "allwinner,sun6i-a31-i2c"; + reg = <0x2502800 0x400>; + interrupts = ; + clocks = <&ccu CLK_BUS_I2C2>; + resets = <&ccu RST_BUS_I2C2>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c3: i2c@2502c00 { + compatible = "allwinner,sun55i-a523-i2c", + "allwinner,sun8i-v536-i2c", + "allwinner,sun6i-a31-i2c"; + reg = <0x2502c00 0x400>; + interrupts = ; + clocks = <&ccu CLK_BUS_I2C3>; + resets = <&ccu RST_BUS_I2C3>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c4: i2c@2503000 { + compatible = "allwinner,sun55i-a523-i2c", + "allwinner,sun8i-v536-i2c", + "allwinner,sun6i-a31-i2c"; + reg = <0x2503000 0x400>; + interrupts = ; + clocks = <&ccu CLK_BUS_I2C4>; + resets = <&ccu RST_BUS_I2C4>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c5: i2c@2503400 { + compatible = "allwinner,sun55i-a523-i2c", + "allwinner,sun8i-v536-i2c", + "allwinner,sun6i-a31-i2c"; + reg = <0x2503400 0x400>; + interrupts = ; + clocks = <&ccu CLK_BUS_I2C5>; + resets = <&ccu RST_BUS_I2C5>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + gic: interrupt-controller@3400000 { + compatible = "arm,gic-v3"; + #address-cells = <1>; + #interrupt-cells = <3>; + #size-cells = <1>; + ranges; + interrupt-controller; + reg = <0x3400000 0x10000>, + <0x3460000 0x100000>; + interrupts = ; + dma-noncoherent; + + its: msi-controller@3440000 { + compatible = "arm,gic-v3-its"; + reg = <0x3440000 0x20000>; + msi-controller; + #msi-cells = <1>; + dma-noncoherent; + }; + }; + + usb_otg: usb@4100000 { + compatible = "allwinner,sun55i-a523-musb", + "allwinner,sun8i-a33-musb"; + reg = <0x4100000 0x400>; + interrupts = ; + interrupt-names = "mc"; + clocks = <&ccu CLK_BUS_OTG>; + resets = <&ccu RST_BUS_OTG>; + extcon = <&usbphy 0>; + phys = <&usbphy 0>; + phy-names = "usb"; + status = "disabled"; + }; + + usbphy: phy@4100400 { + compatible = "allwinner,sun55i-a523-usb-phy", + "allwinner,sun20i-d1-usb-phy"; + reg = <0x4100400 0x100>, + <0x4101800 0x100>, + <0x4200800 0x100>; + reg-names = "phy_ctrl", + "pmu0", + "pmu1"; + clocks = <&osc24M>, + <&osc24M>; + clock-names = "usb0_phy", + "usb1_phy"; + resets = <&ccu RST_USB_PHY0>, + <&ccu RST_USB_PHY1>; + reset-names = "usb0_reset", + "usb1_reset"; + status = "disabled"; + #phy-cells = <1>; + }; + + ehci0: usb@4101000 { + compatible = "allwinner,sun55i-a523-ehci", + "generic-ehci"; + reg = <0x4101000 0x100>; + interrupts = ; + clocks = <&ccu CLK_BUS_OHCI0>, + <&ccu CLK_BUS_EHCI0>, + <&ccu CLK_USB_OHCI0>; + resets = <&ccu RST_BUS_OHCI0>, + <&ccu RST_BUS_EHCI0>; + phys = <&usbphy 0>; + phy-names = "usb"; + status = "disabled"; + }; + + ohci0: usb@4101400 { + compatible = "allwinner,sun55i-a523-ohci", + "generic-ohci"; + reg = <0x4101400 0x100>; + interrupts = ; + clocks = <&ccu CLK_BUS_OHCI0>, + <&ccu CLK_USB_OHCI0>; + resets = <&ccu RST_BUS_OHCI0>; + phys = <&usbphy 0>; + phy-names = "usb"; + status = "disabled"; + }; + + ehci1: usb@4200000 { + compatible = "allwinner,sun55i-a523-ehci", + "generic-ehci"; + reg = <0x4200000 0x100>; + interrupts = ; + clocks = <&ccu CLK_BUS_OHCI1>, + <&ccu CLK_BUS_EHCI1>, + <&ccu CLK_USB_OHCI1>; + resets = <&ccu RST_BUS_OHCI1>, + <&ccu RST_BUS_EHCI1>; + phys = <&usbphy 1>; + phy-names = "usb"; + status = "disabled"; + }; + + ohci1: usb@4200400 { + compatible = "allwinner,sun55i-a523-ohci", + "generic-ohci"; + reg = <0x4200400 0x100>; + interrupts = ; + clocks = <&ccu CLK_BUS_OHCI1>, + <&ccu CLK_USB_OHCI1>; + resets = <&ccu RST_BUS_OHCI1>; + phys = <&usbphy 1>; + phy-names = "usb"; + status = "disabled"; + }; + + r_ccu: clock-controller@7010000 { + compatible = "allwinner,sun55i-a523-r-ccu"; + reg = <0x7010000 0x250>; + clocks = <&osc24M>, + <&rtc CLK_OSC32K>, + <&rtc CLK_IOSC>, + <&ccu CLK_PLL_PERIPH0_200M>, + <&ccu CLK_PLL_AUDIO0_4X>; + clock-names = "hosc", + "losc", + "iosc", + "pll-periph", + "pll-audio"; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + nmi_intc: interrupt-controller@7010320 { + compatible = "allwinner,sun55i-a523-nmi"; + reg = <0x07010320 0xc>; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = ; + }; + + r_pio: pinctrl@7022000 { + compatible = "allwinner,sun55i-a523-r-pinctrl"; + reg = <0x7022000 0x800>; + interrupts = , + ; + clocks = <&r_ccu CLK_R_APB0>, + <&osc24M>, + <&rtc CLK_OSC32K>; + clock-names = "apb", "hosc", "losc"; + gpio-controller; + #gpio-cells = <3>; + interrupt-controller; + #interrupt-cells = <3>; + + r_i2c_pins: r-i2c-pins { + pins = "PL0" ,"PL1"; + allwinner,pinmux = <2>; + function = "r_i2c0"; + }; + }; + + r_i2c0: i2c@7081400 { + compatible = "allwinner,sun55i-a523-i2c", + "allwinner,sun8i-v536-i2c", + "allwinner,sun6i-a31-i2c"; + reg = <0x07081400 0x400>; + interrupts = ; + clocks = <&r_ccu CLK_BUS_R_I2C0>; + resets = <&r_ccu RST_BUS_R_I2C0>; + pinctrl-names = "default"; + pinctrl-0 = <&r_i2c_pins>; + status = "disabled"; + + #address-cells = <1>; + #size-cells = <0>; + }; + + rtc: rtc@7090000 { + compatible = "allwinner,sun55i-a523-rtc", + "allwinner,sun50i-r329-rtc"; + reg = <0x7090000 0x400>; + interrupts = ; + clocks = <&r_ccu CLK_BUS_R_RTC>, + <&osc24M>, + <&r_ccu CLK_R_AHB>; + clock-names = "bus", "hosc", "ahb"; + #clock-cells = <1>; + }; + }; +}; From patchwork Thu Jul 17 23:54:52 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 1380 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 1E73F2309BD for ; Thu, 17 Jul 2025 23:57:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752796636; cv=none; b=ZmpFZedmpWxKvY126zV+qQvL2/IfF+OczhoIso081pvaKb7VDSbH8AWgX+JcGIFGVKIhNT38FLbQu3m9QZRiprxkvTakiTQdC+4/Ioo9vlHnU/n345L7g4ve/UEfkJQrpvTezQE58EIhKx5RXzKxscQpvFYtkLgh3zc6igpj1Jg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752796636; c=relaxed/simple; bh=Kaw06YD3rMLgH92sK5rsa7xZagw4/v02B3zy876gaME=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MNN4o0oR7Ht1pT8luAUFY5EWSAogKP2539EpQjjvyY2qSu3kbLbLHgIXa52vpK7s9XWdlf4QRMcEaag8iGxTJfpTgI7kTPka2+0QaDDZWB8pFgzV+ekndFMbl33QkM/5kdMYWjdid2coEu5nU+9AUaA1WZYGButWJa3Tne9p5Yc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 494A21762; Thu, 17 Jul 2025 16:57:07 -0700 (PDT) Received: from localhost.localdomain (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id B64863F694; Thu, 17 Jul 2025 16:57:13 -0700 (PDT) From: Andre Przywara To: u-boot@lists.denx.de Cc: Jernej Skrabec , Mikhail Kalashnikov , Yixun Lan , Paul Kocialkowski , linux-sunxi@lists.linux.dev, Tom Rini Subject: [PATCH v2 17/20] arm64: dts: allwinner: a523: add X96Q-Pro+ support Date: Fri, 18 Jul 2025 00:54:52 +0100 Message-ID: <20250717235455.32528-18-andre.przywara@arm.com> X-Mailer: git-send-email 2.46.3 In-Reply-To: <20250717235455.32528-1-andre.przywara@arm.com> References: <20250717235455.32528-1-andre.przywara@arm.com> Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Status: O The X96QPro+ is a TV box using the Allwinner H728 SoC. That SoC seems to be a package variant of the A523 family, at least it uses the same SoC ID and is compatible as far as we can assess. It comes with the following specs: - Allwinner H728 SoC: 8 Arm Cortex-A55 cores, Mali-G57 MC1 GPU - 2 or 4GiB DDR3L DRAM - 32, 64, or 128 GiB eMMC flash - AXP717 + AXP323 PMICs - Gigabit Ethernet (using MAXIO PHY) - HDMI port - 2 * USB 2.0 ports - 1 * USB 3.0 port - microSD card slot - TOSLINK digital audio output - 3.5mm A/V port - infrared sensor - 7-segment display - 5V barrel plug power supply - power button The PCB provides holes for soldering a UART header or cable, this is connected to the debug UART0. There is another set of UART pins available. The board also features a FEL button (accessible through the 3.5mm socket) and a reset button (only accessible when case is open). This .dts just describes the basic peripherals as far as we support them at the moment. The PMIC rail assignments are reverse engineered as far as possible, by dumping them from a running Android system, and correlating them to other boards using the same SoC. Signed-off-by: Andre Przywara Acked-by: Jernej Skrabec Link: https://patch.msgid.link/20250307005712.16828-13-andre.przywara@arm.com [wens@csie.org: Squash in SD card detect pull resistor fix] Link: https://patch.msgid.link/20250425003422.3465-1-andre.przywara@arm.com Signed-off-by: Chen-Yu Tsai [ upstream commit: 4ee87d875071390b4e24ce46dbdd792216d61651 ] (cherry picked from commit 693da0a03149b77a3e2bc11cfd314df8cc2fab40) --- .../arm64/allwinner/sun55i-h728-x96qpro+.dts | 287 ++++++++++++++++++ 1 file changed, 287 insertions(+) create mode 100644 dts/upstream/src/arm64/allwinner/sun55i-h728-x96qpro+.dts diff --git a/dts/upstream/src/arm64/allwinner/sun55i-h728-x96qpro+.dts b/dts/upstream/src/arm64/allwinner/sun55i-h728-x96qpro+.dts new file mode 100644 index 00000000000..59db103546f --- /dev/null +++ b/dts/upstream/src/arm64/allwinner/sun55i-h728-x96qpro+.dts @@ -0,0 +1,287 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR MIT) +// Copyright (C) 2024 Arm Ltd. + +/dts-v1/; + +#include "sun55i-a523.dtsi" + +#include + +/ { + model = "X96Q Pro+"; + compatible = "amediatech,x96q-pro-plus", "allwinner,sun55i-h728"; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + ext_osc32k: ext-osc32k-clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <32768>; + clock-output-names = "ext_osc32k"; + }; + + reg_vcc5v: vcc5v { + /* board wide 5V supply from the barrel plug */ + compatible = "regulator-fixed"; + regulator-name = "vcc-5v"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + }; + + reg_vcc3v3: vcc3v3 { + /* 3.3V dummy supply for the SD card */ + compatible = "regulator-fixed"; + regulator-name = "vcc-3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <®_vcc5v>; + regulator-always-on; + }; +}; + +&ehci0 { + status = "okay"; +}; + +&ehci1 { + status = "okay"; +}; + +&mmc0 { + vmmc-supply = <®_vcc3v3>; + cd-gpios = <&pio 5 6 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; /* PF6 */ + bus-width = <4>; + disable-wp; + status = "okay"; +}; + +&mmc2 { + vmmc-supply = <®_cldo3>; + vqmmc-supply = <®_cldo1>; + bus-width = <8>; + non-removable; + cap-mmc-hw-reset; + mmc-ddr-1_8v; + mmc-hs200-1_8v; + status = "okay"; +}; + +&ohci0 { + status = "okay"; +}; + +&ohci1 { + status = "okay"; +}; + +&pio { + vcc-pb-supply = <®_cldo3>; /* via VCC-IO */ + vcc-pc-supply = <®_cldo1>; + vcc-pd-supply = <®_dcdc4>; + vcc-pe-supply = <®_dcdc4>; + vcc-pf-supply = <®_cldo3>; /* actually switchable */ + vcc-pg-supply = <®_bldo1>; + vcc-ph-supply = <®_cldo3>; /* via VCC-IO */ + vcc-pi-supply = <®_dcdc4>; + vcc-pj-supply = <®_dcdc4>; + vcc-pk-supply = <®_bldo3>; +}; + +&r_i2c0 { + status = "okay"; + + axp717: pmic@34 { + compatible = "x-powers,axp717"; + reg = <0x34>; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&nmi_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + + vin1-supply = <®_vcc5v>; + vin2-supply = <®_vcc5v>; + vin3-supply = <®_vcc5v>; + vin4-supply = <®_vcc5v>; + aldoin-supply = <®_vcc5v>; + bldoin-supply = <®_vcc5v>; + cldoin-supply = <®_vcc5v>; + + regulators { + /* Supplies the "little" cluster (1.0(?) GHz cores) */ + reg_dcdc1: dcdc1 { + regulator-always-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1160000>; + regulator-name = "vdd-cpul"; + }; + + reg_dcdc2: dcdc2 { + regulator-always-on; + regulator-min-microvolt = <920000>; + regulator-max-microvolt = <920000>; + regulator-name = "vdd-gpu-sys"; + }; + + reg_dcdc3: dcdc3 { + regulator-always-on; + regulator-min-microvolt = <1360000>; + regulator-max-microvolt = <1360000>; + regulator-name = "vdd-dram"; + }; + + reg_dcdc4: dcdc4 { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-name = "vdd-dcdc4"; + }; + + reg_aldo1: aldo1 { + /* not connected */ + }; + + reg_aldo2: aldo2 { + /* not connected */ + }; + + reg_aldo3: aldo3 { + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-aldo3"; + }; + + reg_aldo4: aldo4 { + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc-pll-dxco-avcc"; + }; + + reg_bldo1: bldo1 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc-pg-wifi-lvds"; + }; + + reg_bldo2: bldo2 { + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc-dram-1v8"; + }; + + reg_bldo3: bldo3 { + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-name = "vcc-bldo3"; + }; + + reg_bldo4: bldo4 { + /* not connected */ + }; + + reg_cldo1: cldo1 { + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc-codec-sd"; + }; + + reg_cldo2: cldo2 { + }; + + reg_cldo3: cldo3 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-codec-eth-sd"; + }; + + reg_cldo4: cldo4 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-eth-phy"; + }; + + reg_cpusldo: cpusldo { + /* supplies the management core */ + regulator-always-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + regulator-name = "vdd-cpus"; + }; + }; + }; + + axp323: pmic@36 { + compatible = "x-powers,axp323"; + reg = <0x36>; + #interrupt-cells = <1>; + interrupt-controller; + interrupt-parent = <&nmi_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + status = "okay"; + + vin1-supply = <®_vcc5v>; + vin2-supply = <®_vcc5v>; + vin3-supply = <®_vcc5v>; + + regulators { + aldo1 { + /* not connected */ + }; + + dldo1 { + /* not connected */ + }; + + /* Supplies the "big" cluster (1.8 GHz cores) */ + reg_dcdc1_323: dcdc1 { + regulator-always-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1160000>; + regulator-name = "vdd-cpub"; + }; + + /* DCDC2 is polyphased with DCDC1 */ + + reg_dcdc3_323: dcdc3 { + regulator-always-on; + regulator-min-microvolt = <1050000>; + regulator-max-microvolt = <1050000>; + regulator-name = "vdd-dcdc3"; + }; + }; + }; +}; + +&r_pio { +/* + * Specifying the supply would create a circular dependency. + * + * vcc-pl-supply = <®_aldo3>; + */ + vcc-pm-supply = <®_aldo3>; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pb_pins>; + status = "okay"; +}; + +&usb_otg { + /* USB0 is a USB-A receptacle, always powered, so force host mode. */ + dr_mode = "host"; + status = "okay"; +}; + +&usbphy { + status = "okay"; +}; From patchwork Thu Jul 17 23:54:53 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 1379 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 76E2A49641 for ; Thu, 17 Jul 2025 23:57:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752796638; cv=none; b=Joev6CLdHmVJAHkhiMPoRbPfp0A41ECmBMEON13LPFJSa/mCnTldTt35YlJY3rDP7uk9yQJdgtlU6ndytsV79OiPozNvlShnHvMuBalMJr8j0ry7oz35t3y/3V3wNoCojTTQ/JG6eriXFcjuSoV/KpL71efKmtorkym6+2Z0RVA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752796638; c=relaxed/simple; bh=gYQvRANnLTAvNX+o0V2/U6MQBEaszVyQ4vL6kZ3KLtM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=I43jQ2wl07k56FRh1Kw8kxFrIfEn90E5aPcFt/bSkvTQgYL+VPmVnDiuI5yxUonT5khumJ2Ahw4Qjv+oogqLHAGyGHDn+PRz1DvU47y1kF2UWbrty/ybqkV734+RfdqLn+1ktYOh21nm9PO19+riXKarD5FAkDghtb/FvakYbRI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id A357F1BB2; Thu, 17 Jul 2025 16:57:08 -0700 (PDT) Received: from localhost.localdomain (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 1AD4A3F694; Thu, 17 Jul 2025 16:57:14 -0700 (PDT) From: Andre Przywara To: u-boot@lists.denx.de Cc: Jernej Skrabec , Mikhail Kalashnikov , Yixun Lan , Paul Kocialkowski , linux-sunxi@lists.linux.dev, Tom Rini Subject: [PATCH v2 18/20] arm64: dts: allwinner: a523: add Radxa A5E support Date: Fri, 18 Jul 2025 00:54:53 +0100 Message-ID: <20250717235455.32528-19-andre.przywara@arm.com> X-Mailer: git-send-email 2.46.3 In-Reply-To: <20250717235455.32528-1-andre.przywara@arm.com> References: <20250717235455.32528-1-andre.przywara@arm.com> Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Status: O The Radxa A5E is a development board using the Allwinner A527 SoC, which is using the same die as the A523 SoC, just exposing the pins of more peripherals (like HDMI or the 2nd MAC). The board features: - Allwinner A527/T527 SoC: 8 ARM Cortex-A55 cores, Mali-G57 MC1 GPU - 1GiB/2GiB/4GiB LPDDR4 DRAM - AXP717 + AXP323 PMICs - Raspberry-Pi-2 compatible 40pin GPIO header - 1 USB 2.0 type C port (OTG), also power supply - 1 USB 3.0 type A host port (multiplexed with M.2 slot) - 1 M.2 M-key 2230 slot, with 1 PCIe2.1 lane connected (multiplexed with USB 3.0 port) - MicroSD slot - optional eMMC, 8, 16 or 32GB available - optional on-board 16MiB bootable SPI NOR flash - two 1Gbps Ethernet ports (via MAXIO MAE0621A PHYs) - PoE header for optional supply circuit on one Ethernet port - WiFi 802.11 a/b/g/n/ac/ax (LB-Link BL-M8800DS2 module using AIC8800) - HDMI port - camera and LCD connectors - power supply via USB-C connector (but no PD) or GPIO header pins This .dts describes the devices as far as we support them at the moment. The PMIC rails have been assigned as per the schematics. Signed-off-by: Andre Przywara Acked-by: Jernej Skrabec Link: https://patch.msgid.link/20250307005712.16828-14-andre.przywara@arm.com [wens@csie.org: Squash in SD card detect pull resistor fix] Link: https://patch.msgid.link/20250425003422.3465-1-andre.przywara@arm.com [wens@csie.org: Rename dts file to sun55i-a527-cubie-a5e.dts] Signed-off-by: Chen-Yu Tsai [ upstream commit: c2520cd032ae8ca3fdaf77b3f3aa687c8cb7843f ] (cherry picked from commit 91ad117321c0901094c1d6467df90f5f6757569a) --- .../arm64/allwinner/sun55i-a527-cubie-a5e.dts | 299 ++++++++++++++++++ 1 file changed, 299 insertions(+) create mode 100644 dts/upstream/src/arm64/allwinner/sun55i-a527-cubie-a5e.dts diff --git a/dts/upstream/src/arm64/allwinner/sun55i-a527-cubie-a5e.dts b/dts/upstream/src/arm64/allwinner/sun55i-a527-cubie-a5e.dts new file mode 100644 index 00000000000..ad9bd6da424 --- /dev/null +++ b/dts/upstream/src/arm64/allwinner/sun55i-a527-cubie-a5e.dts @@ -0,0 +1,299 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR MIT) +// Copyright (C) 2025 Arm Ltd. + +/dts-v1/; + +#include "sun55i-a523.dtsi" + +#include + +/ { + model = "Radxa A5E"; + compatible = "radxa,cubie-a5e", "allwinner,sun55i-a527"; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + ext_osc32k: ext-osc32k-clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <32768>; + clock-output-names = "ext_osc32k"; + }; + + reg_vcc5v: vcc5v { + /* board wide 5V supply from the USB-C connector */ + compatible = "regulator-fixed"; + regulator-name = "vcc-5v"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + }; + + reg_usb_vbus: vbus { + compatible = "regulator-fixed"; + regulator-name = "usb-vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <®_vcc5v>; + gpio = <&r_pio 0 8 GPIO_ACTIVE_HIGH>; /* PL8 */ + enable-active-high; + }; +}; + +&ehci0 { + status = "okay"; +}; + +&ehci1 { + status = "okay"; +}; + +&mmc0 { + vmmc-supply = <®_cldo3>; + cd-gpios = <&pio 5 6 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; /* PF6 */ + bus-width = <4>; + status = "okay"; +}; + +&ohci0 { + status = "okay"; +}; + +&ohci1 { + status = "okay"; +}; + +&pio { + vcc-pb-supply = <®_cldo3>; /* via VCC-IO */ + vcc-pc-supply = <®_cldo1>; + vcc-pd-supply = <®_cldo3>; + vcc-pe-supply = <®_aldo2>; + vcc-pf-supply = <®_cldo3>; /* actually switchable */ + vcc-pg-supply = <®_bldo1>; + vcc-ph-supply = <®_cldo3>; /* via VCC-IO */ + vcc-pi-supply = <®_cldo3>; + vcc-pj-supply = <®_cldo4>; + vcc-pk-supply = <®_cldo1>; +}; + +&r_i2c0 { + status = "okay"; + + axp717: pmic@34 { + compatible = "x-powers,axp717"; + reg = <0x34>; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&nmi_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + + vin1-supply = <®_vcc5v>; + vin2-supply = <®_vcc5v>; + vin3-supply = <®_vcc5v>; + vin4-supply = <®_vcc5v>; + aldoin-supply = <®_vcc5v>; + bldoin-supply = <®_vcc5v>; + cldoin-supply = <®_vcc5v>; + + regulators { + /* Supplies the "little" cluster (1.4 GHz cores) */ + reg_dcdc1: dcdc1 { + regulator-always-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1160000>; + regulator-name = "vdd-cpul"; + }; + + reg_dcdc2: dcdc2 { + regulator-always-on; + regulator-min-microvolt = <920000>; + regulator-max-microvolt = <920000>; + regulator-name = "vdd-gpu-sys"; + }; + + reg_dcdc3: dcdc3 { + regulator-always-on; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-name = "vdd-dram"; + }; + + reg_aldo1: aldo1 { + /* not connected */ + }; + + reg_aldo2: aldo2 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc-pe"; + }; + + reg_aldo3: aldo3 { + /* supplies the I2C pins for this PMIC */ + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-pl-usb"; + }; + + reg_aldo4: aldo4 { + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc-pll-dxco-avcc"; + }; + + reg_bldo1: bldo1 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc-pg-iowifi"; + }; + + reg_bldo2: bldo2 { + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc-pm-lpddr4"; + }; + + reg_bldo3: bldo3 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-mipi-cam"; + }; + + reg_bldo4: bldo4 { + /* not connected */ + }; + + reg_cldo1: cldo1 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc-pc-and-their-dog"; + }; + + reg_cldo2: cldo2 { + /* not connected */ + }; + + reg_cldo3: cldo3 { + /* IO, USB-2, 3V3, card, NAND, sensor, PI */ + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-io-mmc-spi-ana"; + }; + + reg_cldo4: cldo4 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-pj-phy"; + }; + + reg_cpusldo: cpusldo { + /* supplies the management core */ + regulator-always-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + regulator-name = "vdd-cpus"; + }; + }; + }; + + axp323: pmic@36 { + compatible = "x-powers,axp323"; + reg = <0x36>; + #interrupt-cells = <1>; + interrupt-controller; + interrupt-parent = <&nmi_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + status = "okay"; + + vin1-supply = <®_vcc5v>; + vin2-supply = <®_vcc5v>; + vin3-supply = <®_vcc5v>; + + regulators { + aldo1 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc-mipi-dsi"; + }; + + dldo1 { + /* not connected */ + }; + + /* Supplies the "big" cluster (1.8 GHz cores) */ + reg_dcdc1_323: dcdc1 { + regulator-always-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1160000>; + regulator-name = "vdd-cpub"; + }; + + /* DCDC2 is polyphased with DCDC1 */ + + /* RISC-V management core supply */ + reg_dcdc3_323: dcdc3 { + regulator-always-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + regulator-name = "vdd-dnr"; + }; + }; + }; +}; + +&r_pio { +/* + * Specifying the supply would create a circular dependency. + * + * vcc-pl-supply = <®_aldo3>; + */ + vcc-pm-supply = <®_aldo3>; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pb_pins>; + status = "okay"; +}; + +&usb_otg { + /* + * The USB-C port is the primary power supply, so in this configuration + * relies on the other end of the USB cable to supply the VBUS power. + * So use this port in peripheral mode. + * It is possible to supply the board with the 5V pins on the GPIO + * header, and since the DCIN_5V line is hardwired to the USB-C VBUS + * pins, the port turns into a host port, unconditionally supplying + * power. The dr_mode property should be changed to "host" here, if + * users choose this setup. + */ + dr_mode = "peripheral"; + status = "okay"; +}; + +/* + * The schematic describes USB0_ID (PL10), measuring VBUS_5V, which looks to + * be always on. Also there is USB-VBUSDET (PL2), which is measuring the same + * VBUS_5V. There is also DCIN_DET, which measures DCIN_5V, so the power + * input rail. + * None of them seem to make any sense in relation to detecting USB devices + * or whether there is power provided via any USB pins: they would always + * report high, otherwise the system wouldn't be running. + * The AXP717C provides proper USB-C CC pin functionality, but the PMIC is + * not connected to those pins of the USB-C connector. + */ +&usbphy { + usb0_vbus-supply = <®_vcc5v>; + usb1_vbus-supply = <®_usb_vbus>; + status = "okay"; +}; From patchwork Thu Jul 17 23:54:54 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 1378 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id D40C522258E for ; Thu, 17 Jul 2025 23:57:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752796639; cv=none; b=NRLk/Tvrgys99Mr7h71jEOdPxdvumd0Ot34HaKWqiNCPX8hapGj6uiNeK4/4n461ImDiKE9x5+Av6ov0NnQVwdBEbTKhgpvM+Nu+wLk4CkNPlh6ClrjP8mEZPlUIiMXt4XjzpZs42qz8vhArGDEQrJu6sv1UI3o3Z7YytwpF7vA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752796639; c=relaxed/simple; bh=LjPL89s/6N01CwYGN/oWL2Hv9g11Yk+F717/Pg2gG70=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KCWQ0VNrr4uCUDrrW7oE4rVJ2UDNb+R/EOrC+TmTQFVl4pT/OoV5XXK7/YR5eRk6r725nzlz93/B/CKJ/7J0HiGKy6FRROvG7Ux6yoV80U7+8y6iFv5bfL/P5Njkj3Ox8DkXCaQeRuk1Eb6BrmjCUSZF9Nx9THZ5Kl8G/jFT+gA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 09DB4168F; Thu, 17 Jul 2025 16:57:10 -0700 (PDT) Received: from localhost.localdomain (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 739403F694; Thu, 17 Jul 2025 16:57:16 -0700 (PDT) From: Andre Przywara To: u-boot@lists.denx.de Cc: Jernej Skrabec , Mikhail Kalashnikov , Yixun Lan , Paul Kocialkowski , linux-sunxi@lists.linux.dev, Tom Rini Subject: [PATCH v2 19/20] arm64: dts: allwinner: a523: add Avaota-A1 router support Date: Fri, 18 Jul 2025 00:54:54 +0100 Message-ID: <20250717235455.32528-20-andre.przywara@arm.com> X-Mailer: git-send-email 2.46.3 In-Reply-To: <20250717235455.32528-1-andre.przywara@arm.com> References: <20250717235455.32528-1-andre.przywara@arm.com> Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Status: O The Avaota A1 router board is an Open Source hardware board, designed by YuzukiHD. Pine64 produces some boards and sells them. It uses the Allwinner A527 or T527 SoC, and comes with the following features: - Eight ARM Cortex-A55 cores, Mali-G57 MC1 GPU - 1GiB/2GiB/4GiB LPDDR4 DRAM - AXP717 + AXP323 PMIC - Raspberry-Pi-2 compatible GPIO header - 1 USB 2.0 type A host port, 1 USB 3.0 type A host post - 1 USB 2.0 type C port (OTG + serial debug) - MicroSD slot - eMMC between 16 and 128 GiB - on-board 16MiB bootable SPI NOR flash - two 1Gbps Ethernet ports (via RTL8211F PHYs) - HDMI port - DP port - camera and LCD connectors - 3.5mm headphone jack - (yet) unsupported WiFi/BT chip - 1.3" LC display, connected via SPI - 12 V barrel plug for power supply Add the devicetree file describing the currently supported features. Signed-off-by: Andre Przywara Acked-by: Jernej Skrabec Link: https://patch.msgid.link/20250307005712.16828-12-andre.przywara@arm.com [wens@csie.org: Squash in SD card detect pull resistor fix] Link: https://patch.msgid.link/20250425003422.3465-1-andre.przywara@arm.com Signed-off-by: Chen-Yu Tsai [ upstream commit: dbe54efa32afe5b82763c015cbe9e64c4d4e117a ] (cherry picked from commit ebcb8469ef4336c05c6b9f409714a23cfc891fff) --- .../arm64/allwinner/sun55i-t527-avaota-a1.dts | 308 ++++++++++++++++++ 1 file changed, 308 insertions(+) create mode 100644 dts/upstream/src/arm64/allwinner/sun55i-t527-avaota-a1.dts diff --git a/dts/upstream/src/arm64/allwinner/sun55i-t527-avaota-a1.dts b/dts/upstream/src/arm64/allwinner/sun55i-t527-avaota-a1.dts new file mode 100644 index 00000000000..dea2acc1849 --- /dev/null +++ b/dts/upstream/src/arm64/allwinner/sun55i-t527-avaota-a1.dts @@ -0,0 +1,308 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR MIT) +// Copyright (C) 2024 Arm Ltd. + +/dts-v1/; + +#include "sun55i-a523.dtsi" + +#include + +/ { + model = "Avaota A1"; + compatible = "yuzukihd,avaota-a1", "allwinner,sun55i-t527"; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + ext_osc32k: ext-osc32k-clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <32768>; + clock-output-names = "ext_osc32k"; + }; + + reg_vcc12v: vcc12v { + /* DC input jack */ + compatible = "regulator-fixed"; + regulator-name = "vcc-12v"; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + regulator-always-on; + }; + + reg_vcc5v: vcc5v { + /* board wide 5V supply from the 12V->5V regulator */ + compatible = "regulator-fixed"; + regulator-name = "vcc-5v"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <®_vcc12v>; + regulator-always-on; + }; + + reg_usb_vbus: vbus { + compatible = "regulator-fixed"; + regulator-name = "usb-vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <®_vcc5v>; + gpio = <&pio 8 12 GPIO_ACTIVE_HIGH>; /* PI12 */ + enable-active-high; + }; +}; + +&ehci0 { + status = "okay"; +}; + +&ehci1 { + status = "okay"; +}; + +&mmc0 { + vmmc-supply = <®_cldo3>; + cd-gpios = <&pio 5 6 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; /* PF6 */ + bus-width = <4>; + status = "okay"; +}; + +&mmc2 { + bus-width = <8>; + cap-mmc-hw-reset; + mmc-ddr-1_8v; + mmc-hs200-1_8v; + non-removable; + vmmc-supply = <®_cldo3>; + vqmmc-supply = <®_cldo1>; + status = "okay"; +}; + +&ohci0 { + status = "okay"; +}; + +&ohci1 { + status = "okay"; +}; + +&pio { + vcc-pb-supply = <®_cldo3>; /* via VCC-IO */ + vcc-pc-supply = <®_cldo1>; + vcc-pd-supply = <®_dcdc4>; + vcc-pe-supply = <®_dcdc4>; + vcc-pf-supply = <®_cldo3>; /* actually switchable */ + vcc-pg-supply = <®_bldo1>; + vcc-ph-supply = <®_cldo3>; /* via VCC-IO */ + vcc-pi-supply = <®_dcdc4>; + vcc-pj-supply = <®_dcdc4>; + vcc-pk-supply = <®_bldo3>; +}; + +&r_i2c0 { + status = "okay"; + + axp717: pmic@35 { + compatible = "x-powers,axp717"; + reg = <0x35>; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&nmi_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + + vin1-supply = <®_vcc5v>; + vin2-supply = <®_vcc5v>; + vin3-supply = <®_vcc5v>; + vin4-supply = <®_vcc5v>; + aldoin-supply = <®_vcc5v>; + bldoin-supply = <®_vcc5v>; + cldoin-supply = <®_vcc5v>; + + regulators { + /* Supplies the "little" cluster (1.4 GHz cores) */ + reg_dcdc1: dcdc1 { + regulator-always-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1160000>; + regulator-name = "vdd-cpul"; + }; + + reg_dcdc2: dcdc2 { + regulator-always-on; + regulator-min-microvolt = <920000>; + regulator-max-microvolt = <920000>; + regulator-name = "vdd-gpu-sys"; + }; + + reg_dcdc3: dcdc3 { + regulator-always-on; + regulator-min-microvolt = <1160000>; + regulator-max-microvolt = <1160000>; + regulator-name = "vdd-dram"; + }; + + reg_dcdc4: dcdc4 { + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vdd-io"; + }; + + reg_aldo1: aldo1 { + /* not connected */ + }; + + reg_aldo2: aldo2 { + /* not connected */ + }; + + reg_aldo3: aldo3 { + /* supplies the I2C pins for this PMIC */ + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-pl-pm"; + }; + + reg_aldo4: aldo4 { + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc-pll-dxco-avcc"; + }; + + reg_bldo1: bldo1 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc-pg-wifi-lvds"; + }; + + reg_bldo2: bldo2 { + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc-dram-1v8"; + }; + + reg_bldo3: bldo3 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc-cvp-pk-vid1v8"; + }; + + reg_bldo4: bldo4 { + /* not connected */ + }; + + reg_cldo1: cldo1 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc-pc"; + }; + + reg_cldo2: cldo2 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc-efuse"; + }; + + reg_cldo3: cldo3 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-io-mmc-spi-ana"; + }; + + reg_cldo4: cldo4 { + /* not connected */ + }; + + reg_cpusldo: cpusldo { + /* supplies the management core */ + regulator-always-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + regulator-name = "vdd-cpus"; + }; + }; + }; + + axp323: pmic@36 { + compatible = "x-powers,axp323"; + reg = <0x36>; + #interrupt-cells = <1>; + interrupt-controller; + interrupt-parent = <&nmi_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + status = "okay"; + + vin1-supply = <®_vcc5v>; + vin2-supply = <®_vcc5v>; + vin3-supply = <®_vcc5v>; + + regulators { + aldo1 { + /* not connected */ + }; + + dldo1 { + /* not connected */ + }; + + /* Supplies the "big" cluster (1.8 GHz cores) */ + reg_dcdc1_323: dcdc1 { + regulator-always-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1160000>; + regulator-name = "vdd-cpub"; + }; + + /* DCDC2 is polyphased with DCDC1 */ + + /* Some RISC-V management core related voltage */ + reg_dcdc3_323: dcdc3 { + regulator-always-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + regulator-name = "vdd-dnr"; + }; + }; + }; +}; + +&r_pio { +/* + * Specifying the supply would create a circular dependency. + * + * vcc-pl-supply = <®_aldo3>; + */ + vcc-pm-supply = <®_aldo3>; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pb_pins>; + status = "okay"; +}; + +&usb_otg { + /* + * The CC pins of the USB-C port have two pull-down resistors + * connected to GND, which fixes this port to a peripheral role. + * There is a regulator, controlled by a GPIO, to provide VBUS power + * to the port, and a VBUSDET GPIO, to detect externally provided + * power, but without the CC pins there is no real way to do a + * runtime role detection. + */ + dr_mode = "peripheral"; + status = "okay"; +}; + +&usbphy { + usb0_vbus-supply = <®_usb_vbus>; + usb0_vbus_det-gpios = <&pio 8 13 GPIO_ACTIVE_HIGH>; /* PI13 */ + status = "okay"; +}; From patchwork Thu Jul 17 23:54:55 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 1377 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 248E849641 for ; Thu, 17 Jul 2025 23:57:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752796640; cv=none; b=S7oRhhBYlrlACTor71WPdiqx3tv2AcPSM6y0yhEagSow2RGpoaFZQKVtgUBaO+mi7l+a1ycLhJ6pT8hA/oztK3s4vQ0sWirbJFvNbE6BUAp+0tQTzqYIsRNGBXXggohosUEYIIg8Oq78SCUlUHPGrlqeZfGYoVTP3I22kxwueAE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752796640; c=relaxed/simple; bh=/t2h+O3D9+cGR0/A6BRBZ68TCA59hhJkMDfH1aoQbS4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Ro9x9FW2PC4MmMDlScNCqZdzhhC+ciihkoP/O3ovo96J+M8N3kL46WjpGpr8yZdlTxD+zxaYBMfFCFQEhtPvMoik6ScwOg7ansG8vH6nhJE3bPw7U8e+Lkyka1slIX0kiyTPHpILk6miCedyEIgkNjrIuSi5Nj5hpcdZWjY3q6Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 5F8EE1762; Thu, 17 Jul 2025 16:57:11 -0700 (PDT) Received: from localhost.localdomain (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id CC9773F694; Thu, 17 Jul 2025 16:57:17 -0700 (PDT) From: Andre Przywara To: u-boot@lists.denx.de Cc: Jernej Skrabec , Mikhail Kalashnikov , Yixun Lan , Paul Kocialkowski , linux-sunxi@lists.linux.dev, Tom Rini Subject: [PATCH v2 20/20] sunxi: A523: add defconfigs for three boards Date: Fri, 18 Jul 2025 00:54:55 +0100 Message-ID: <20250717235455.32528-21-andre.przywara@arm.com> X-Mailer: git-send-email 2.46.3 In-Reply-To: <20250717235455.32528-1-andre.przywara@arm.com> References: <20250717235455.32528-1-andre.przywara@arm.com> Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Status: O So far developers seem to use three popular boards: - Avaota A1: dev board with USB 3.0, dual Ethernet, small display - X96QPro+: TV box with Gigabit Ethernet, USB 3.0, eMMC - Radxa A5E: small dev board with USB3/M.2 2230 (muxed), dual Ethernet Add the defconfig files for those boards, containing the DRAM parameters and the usual Kconfig options. Signed-off-by: Andre Przywara --- board/sunxi/MAINTAINERS | 15 +++++++++++++++ configs/avaota-a1_defconfig | 31 +++++++++++++++++++++++++++++++ configs/radxa-a5e_defconfig | 30 ++++++++++++++++++++++++++++++ configs/x96q_pro_plus_defconfig | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 108 insertions(+) create mode 100644 configs/avaota-a1_defconfig create mode 100644 configs/radxa-a5e_defconfig create mode 100644 configs/x96q_pro_plus_defconfig diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS index 1b4b7d87163..66e6a8ff962 100644 --- a/board/sunxi/MAINTAINERS +++ b/board/sunxi/MAINTAINERS @@ -137,6 +137,11 @@ M: Chris Morgan S: Maintained F: configs/anbernic_rg35xx_h700_defconfig +AVAOTA A1 BOARD +M: Andre Przywara +S: Maintained +F: configs/avaota-a1_defconfig + BANANAPI M1 PLUS M: Jagan Teki S: Maintained @@ -531,6 +536,11 @@ M: Quentin Schulz S: Maintained F: configs/parrot_r16_defconfig +RADXA CUBIE A5E BOARD +M: Andre Przywara +S: Maintained +F: configs/radxa-a5e_defconfig + SINLINX SINA31s BOARD M: Chen-Yu Tsai S: Maintained @@ -591,6 +601,11 @@ M: Andre Przywara S: Maintained F: configs/x96_mate_defconfig +X96Q PRO+ TV BOX +M: Andre Przywara +S: Maintained +F: configs/x96q_pro_plus_defconfig + YONES TOPTECH BD1078 BOARD M: Paul Kocialkowski S: Maintained diff --git a/configs/avaota-a1_defconfig b/configs/avaota-a1_defconfig new file mode 100644 index 00000000000..55457edd3b3 --- /dev/null +++ b/configs/avaota-a1_defconfig @@ -0,0 +1,31 @@ +CONFIG_ARM=y +CONFIG_ARCH_SUNXI=y +CONFIG_DEFAULT_DEVICE_TREE="allwinner/sun55i-t527-avaota-a1" +CONFIG_SPL=y +CONFIG_DRAM_SUNXI_DX_ODT=0x07070707 +CONFIG_DRAM_SUNXI_DX_DRI=0x0d0d0d0d +CONFIG_DRAM_SUNXI_CA_DRI=0x0e0e +CONFIG_DRAM_SUNXI_ODT_EN=0x84848484 +CONFIG_DRAM_SUNXI_TPR0=0x80808080 +CONFIG_DRAM_SUNXI_TPR1=0x06060606 +CONFIG_DRAM_SUNXI_TPR6=0x38000000 +CONFIG_DRAM_SUNXI_TPR10=0x802f3333 +CONFIG_DRAM_SUNXI_TPR11=0xc7c5c4c2 +CONFIG_DRAM_SUNXI_TPR12=0x3533302f +CONFIG_MACH_SUN55I_A523=y +CONFIG_MMC_SUNXI_SLOT_EXTRA=2 +CONFIG_R_I2C_ENABLE=y +# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +CONFIG_SPL_I2C=y +CONFIG_SPL_SYS_I2C_LEGACY=y +CONFIG_SYS_I2C_MVTWSI=y +CONFIG_SYS_I2C_SLAVE=0x7f +CONFIG_SYS_I2C_SPEED=400000 +CONFIG_SUPPORT_EMMC_BOOT=y +CONFIG_REGULATOR_AXP=y +CONFIG_AXP717_POWER=y +CONFIG_AXP_I2C_ADDRESS=0x35 +CONFIG_AXP_DCDC2_VOLT=920 +CONFIG_AXP_DCDC3_VOLT=1160 +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_OHCI_HCD=y diff --git a/configs/radxa-a5e_defconfig b/configs/radxa-a5e_defconfig new file mode 100644 index 00000000000..012e7b4eeaf --- /dev/null +++ b/configs/radxa-a5e_defconfig @@ -0,0 +1,30 @@ +CONFIG_ARM=y +CONFIG_ARCH_SUNXI=y +CONFIG_DEFAULT_DEVICE_TREE="allwinner/sun55i-a527-cubie-a5e" +CONFIG_SPL=y +CONFIG_DRAM_SUNXI_DX_ODT=0x07070707 +CONFIG_DRAM_SUNXI_DX_DRI=0x0d0d0d0d +CONFIG_DRAM_SUNXI_CA_DRI=0x0e0e +CONFIG_DRAM_SUNXI_ODT_EN=0x84848484 +CONFIG_DRAM_SUNXI_TPR0=0x80808080 +CONFIG_DRAM_SUNXI_TPR1=0x06060606 +CONFIG_DRAM_SUNXI_TPR6=0x38000000 +CONFIG_DRAM_SUNXI_TPR10=0x802f3333 +CONFIG_DRAM_SUNXI_TPR11=0xc7c5c4c2 +CONFIG_DRAM_SUNXI_TPR12=0x3533302f +# BSP value: CONFIG_DRAM_SUNXI_TPR11=0xc6c4c2c0 +# BSP value: CONFIG_DRAM_SUNXI_TPR12=0x3a373233 +CONFIG_MACH_SUN55I_A523=y +CONFIG_R_I2C_ENABLE=y +# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +CONFIG_SPL_I2C=y +CONFIG_SPL_SYS_I2C_LEGACY=y +CONFIG_SYS_I2C_MVTWSI=y +CONFIG_SYS_I2C_SLAVE=0x7f +CONFIG_SYS_I2C_SPEED=400000 +CONFIG_REGULATOR_AXP=y +CONFIG_AXP717_POWER=y +CONFIG_AXP_DCDC2_VOLT=920 +CONFIG_AXP_DCDC3_VOLT=1100 +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_OHCI_HCD=y diff --git a/configs/x96q_pro_plus_defconfig b/configs/x96q_pro_plus_defconfig new file mode 100644 index 00000000000..07d3b078bef --- /dev/null +++ b/configs/x96q_pro_plus_defconfig @@ -0,0 +1,32 @@ +CONFIG_ARM=y +CONFIG_ARCH_SUNXI=y +CONFIG_DEFAULT_DEVICE_TREE="allwinner/sun55i-h728-x96qpro+" +CONFIG_SPL=y +CONFIG_DRAM_SUNXI_DX_ODT=0x07070707 +CONFIG_DRAM_SUNXI_DX_DRI=0x0c0c0c0c +CONFIG_DRAM_SUNXI_CA_DRI=0x0e0e +CONFIG_DRAM_SUNXI_ODT_EN=0x90909090 +CONFIG_DRAM_SUNXI_TPR0=0x80808080 +CONFIG_DRAM_SUNXI_TPR1=0x06060606 +CONFIG_DRAM_SUNXI_TPR6=0x3380807e +CONFIG_DRAM_SUNXI_TPR10=0x802f7788 +CONFIG_DRAM_SUNXI_TPR11=0x8f919190 +CONFIG_DRAM_SUNXI_TPR12=0x22222723 +CONFIG_MACH_SUN55I_A523=y +CONFIG_SUNXI_DRAM_A523_DDR3=y +CONFIG_DRAM_CLK=792 +CONFIG_MMC_SUNXI_SLOT_EXTRA=2 +CONFIG_R_I2C_ENABLE=y +# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +CONFIG_SPL_I2C=y +CONFIG_SPL_SYS_I2C_LEGACY=y +CONFIG_SYS_I2C_MVTWSI=y +CONFIG_SYS_I2C_SLAVE=0x7f +CONFIG_SYS_I2C_SPEED=400000 +CONFIG_SUPPORT_EMMC_BOOT=y +CONFIG_REGULATOR_AXP=y +CONFIG_AXP717_POWER=y +CONFIG_AXP_DCDC2_VOLT=920 +CONFIG_AXP_DCDC3_VOLT=1360 +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_OHCI_HCD=y