[PATCH 0/9] Add Anbernic RG35XX-2024

From: Chris Morgan macromorgan@hotmail.com
Add support for the Anbernic RG35XX-2024.
This device is a handheld gaming console (series) based around the Anbernic H700 SoC. It comes with 1GB of RAM and multiple face buttons for input.
Add support for the simplest model for now, and then iterate later to add board detection logic, support the entire device lineup, and move to using the mainline device tree.
Chris Morgan (2): sunxi: dts: arm/arm64: update sun50i-h616.dtsi from Linux-v6.11-rc1 sunxi: Add support for Anbernic RG35XX-2024
Jernej Skrabec (7): sunxi: H616: dram: DDR3: adjust settings sunxi: H616: dram: LPDDR3: adjust settings sunxi: H616: dram: LPDDR4: adjust settings sunxi: H616: DRAM: Add alternative pin mapping sunxi: H616: DRAM: Adjust configuration procedure sunxi: H616: DRAM: Adjust size scan procedure sunxi: H616: dram: Update mbus priorities
arch/arm/dts/Makefile | 3 +- arch/arm/dts/sun50i-h616.dtsi | 98 +++++- .../dts/sun50i-h700-anbernic-rg35xx-2024.dts | 320 ++++++++++++++++++ arch/arm/mach-sunxi/dram_sun50i_h616.c | 178 ++++++---- .../mach-sunxi/dram_timings/h616_ddr3_1333.c | 5 +- .../arm/mach-sunxi/dram_timings/h616_lpddr3.c | 2 +- .../dram_timings/h616_lpddr4_2133.c | 2 +- board/sunxi/MAINTAINERS | 5 + configs/anbernic_rg35xx_h700_defconfig | 50 +++ include/dt-bindings/clock/sun50i-h616-ccu.h | 1 + include/dt-bindings/reset/sun50i-h616-ccu.h | 1 + 11 files changed, 600 insertions(+), 65 deletions(-) create mode 100644 arch/arm/dts/sun50i-h700-anbernic-rg35xx-2024.dts create mode 100644 configs/anbernic_rg35xx_h700_defconfig

From: Jernej Skrabec jernej.skrabec@gmail.com
Adjust H616 DDR3 DRAM settings to be in line with vendor driver.
Signed-off-by: Jernej Skrabec jernej.skrabec@gmail.com Tested-by: Chris Morgan macromorgan@hotmail.com --- arch/arm/mach-sunxi/dram_timings/h616_ddr3_1333.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-sunxi/dram_timings/h616_ddr3_1333.c b/arch/arm/mach-sunxi/dram_timings/h616_ddr3_1333.c index 3faf8d5bd9..26b7eac342 100644 --- a/arch/arm/mach-sunxi/dram_timings/h616_ddr3_1333.c +++ b/arch/arm/mach-sunxi/dram_timings/h616_ddr3_1333.c @@ -24,8 +24,8 @@ void mctl_set_timing_params(const struct dram_para *para) u8 trrd = max(ns_to_t(6), 4); /* JEDEC: max(6 ns, 4nCK) */ u8 trcd = ns_to_t(15); /* JEDEC: 13.5 ns */ u8 trc = ns_to_t(53); /* JEDEC: 49.5 ns */ - u8 txp = max(ns_to_t(6), 3); /* JEDEC: max(6 ns, 3nCK) */ u8 trtp = max(ns_to_t(8), 2); /* JEDEC: max(7.5 ns, 4nCK) */ + u8 txp = trtp; /* JEDEC: max(6 ns, 3nCK) */ u8 trp = ns_to_t(15); /* JEDEC: >= 13.75 ns */ u8 tras = ns_to_t(38); /* JEDEC >= 36 ns, <= 9*trefi */ u16 trefi = ns_to_t(7800) / 32; /* JEDEC: 7.8us@Tcase <= 85C */ @@ -64,6 +64,9 @@ void mctl_set_timing_params(const struct dram_para *para) twr2rd = trtp + 2 + tcwl; trd2wr = tcl + 3 - tcwl;
+ if (trtp + trp < tcl + 2) + trtp = tcl + 2 - trp; + /* set DRAM timing */ writel((twtp << 24) | (tfaw << 16) | (trasmax << 8) | tras, &mctl_ctl->dramtmg[0]);

On Thu, 1 Aug 2024 17:55:11 -0500 Chris Morgan macroalpha82@gmail.com wrote:
From: Jernej Skrabec jernej.skrabec@gmail.com
Adjust H616 DDR3 DRAM settings to be in line with vendor driver.
Signed-off-by: Jernej Skrabec jernej.skrabec@gmail.com Tested-by: Chris Morgan macromorgan@hotmail.com
arch/arm/mach-sunxi/dram_timings/h616_ddr3_1333.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-sunxi/dram_timings/h616_ddr3_1333.c b/arch/arm/mach-sunxi/dram_timings/h616_ddr3_1333.c index 3faf8d5bd9..26b7eac342 100644 --- a/arch/arm/mach-sunxi/dram_timings/h616_ddr3_1333.c +++ b/arch/arm/mach-sunxi/dram_timings/h616_ddr3_1333.c @@ -24,8 +24,8 @@ void mctl_set_timing_params(const struct dram_para *para) u8 trrd = max(ns_to_t(6), 4); /* JEDEC: max(6 ns, 4nCK) */ u8 trcd = ns_to_t(15); /* JEDEC: 13.5 ns */ u8 trc = ns_to_t(53); /* JEDEC: 49.5 ns */
- u8 txp = max(ns_to_t(6), 3); /* JEDEC: max(6 ns, 3nCK) */ u8 trtp = max(ns_to_t(8), 2); /* JEDEC: max(7.5 ns, 4nCK) */
- u8 txp = trtp; /* JEDEC: max(6 ns, 3nCK) */
I am not too sure this change makes sense: assuming that it really should read: u8 txp = max(ns_to_t(8), 2); (as txp and trtp are quite different delays), it wouldn't really change anything unless we drop below 500 MHz for the DRAM clock. 8ns are rounded up to 3 clock cycles (nCK), for both 648 and 720 MHz. We would only get below 3nCK for frequencies under 500 MHz. 6ns would be 3nCK at 720 MHz as well, but 2nCK at 648 MHz. But changing the minimum to 3nCK at the same time prevents any change. So since the current code matches JEDEC, I'd rather keep it.
Cheers, Andre
u8 trp = ns_to_t(15); /* JEDEC: >= 13.75 ns */ u8 tras = ns_to_t(38); /* JEDEC >= 36 ns, <= 9*trefi */ u16 trefi = ns_to_t(7800) / 32; /* JEDEC: 7.8us@Tcase <= 85C */ @@ -64,6 +64,9 @@ void mctl_set_timing_params(const struct dram_para *para) twr2rd = trtp + 2 + tcwl; trd2wr = tcl + 3 - tcwl;
- if (trtp + trp < tcl + 2)
trtp = tcl + 2 - trp;
- /* set DRAM timing */ writel((twtp << 24) | (tfaw << 16) | (trasmax << 8) | tras, &mctl_ctl->dramtmg[0]);

From: Jernej Skrabec jernej.skrabec@gmail.com
Adjust H616 LPDDR3 DRAM settings to be in line with vendor driver.
Signed-off-by: Jernej Skrabec jernej.skrabec@gmail.com Tested-by: Chris Morgan macromorgan@hotmail.com --- arch/arm/mach-sunxi/dram_sun50i_h616.c | 2 +- arch/arm/mach-sunxi/dram_timings/h616_lpddr3.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c b/arch/arm/mach-sunxi/dram_sun50i_h616.c index 37c139e0ee..a20264d8b4 100644 --- a/arch/arm/mach-sunxi/dram_sun50i_h616.c +++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c @@ -945,7 +945,7 @@ static bool mctl_phy_init(const struct dram_para *para, val = para->tpr6 & 0xff; break; case SUNXI_DRAM_TYPE_LPDDR3: - val = para->tpr6 >> 8 & 0xff; + val = para->tpr6 >> 16 & 0xff; break; case SUNXI_DRAM_TYPE_LPDDR4: val = para->tpr6 >> 24 & 0xff; diff --git a/arch/arm/mach-sunxi/dram_timings/h616_lpddr3.c b/arch/arm/mach-sunxi/dram_timings/h616_lpddr3.c index ce2ffa7a02..82b86084a6 100644 --- a/arch/arm/mach-sunxi/dram_timings/h616_lpddr3.c +++ b/arch/arm/mach-sunxi/dram_timings/h616_lpddr3.c @@ -24,8 +24,8 @@ void mctl_set_timing_params(const struct dram_para *para) u8 trrd = max(ns_to_t(6), 4); u8 trcd = ns_to_t(24); u8 trc = ns_to_t(70); - u8 txp = max(ns_to_t(8), 3); u8 trtp = max(ns_to_t(8), 2); + u8 txp = trtp; u8 trp = ns_to_t(27); u8 tras = ns_to_t(41); u16 trefi = ns_to_t(7800) / 64;

On 02.08.2024 01:55, Chris Morgan wrote:
From: Jernej Skrabec jernej.skrabec@gmail.com
Adjust H616 LPDDR3 DRAM settings to be in line with vendor driver.
Signed-off-by: Jernej Skrabec jernej.skrabec@gmail.com Tested-by: Chris Morgan macromorgan@hotmail.com
arch/arm/mach-sunxi/dram_sun50i_h616.c | 2 +- arch/arm/mach-sunxi/dram_timings/h616_lpddr3.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c b/arch/arm/mach-sunxi/dram_sun50i_h616.c index 37c139e0ee..a20264d8b4 100644 --- a/arch/arm/mach-sunxi/dram_sun50i_h616.c +++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c @@ -945,7 +945,7 @@ static bool mctl_phy_init(const struct dram_para *para, val = para->tpr6 & 0xff; break; case SUNXI_DRAM_TYPE_LPDDR3:
val = para->tpr6 >> 8 & 0xff;
val = para->tpr6 >> 16 & 0xff;
This is the correct change to match the factory tpr6 parameters.
I think, we also need to change the default value in arch/arm/mach-sunxi/Kconfig:
from: config DRAM_SUN50I_H616_TPR6 hex "H616 DRAM TPR6 parameter" default 0x3300c080 to default 0x33c00080
break;
case SUNXI_DRAM_TYPE_LPDDR4: val = para->tpr6 >> 24 & 0xff; diff --git a/arch/arm/mach-sunxi/dram_timings/h616_lpddr3.c b/arch/arm/mach-sunxi/dram_timings/h616_lpddr3.c index ce2ffa7a02..82b86084a6 100644 --- a/arch/arm/mach-sunxi/dram_timings/h616_lpddr3.c +++ b/arch/arm/mach-sunxi/dram_timings/h616_lpddr3.c @@ -24,8 +24,8 @@ void mctl_set_timing_params(const struct dram_para *para) u8 trrd = max(ns_to_t(6), 4); u8 trcd = ns_to_t(24); u8 trc = ns_to_t(70);
- u8 txp = max(ns_to_t(8), 3); u8 trtp = max(ns_to_t(8), 2);
- u8 txp = trtp;
I think Jernejchanged this value using RE. I checked the 047fb104 register (dramtmg[1])
on my t98-h2b-lp3 tvbox, it has not changed and is the same as the factory value.
=> md.l 0x47fb100 047fb100: 10141811 0004041c 04070d0d 0050500c .............PP.

On Sat, 3 Aug 2024 16:17:26 +0300 Mikhail Kalashnikov iuncuim@gmail.com wrote:
Hi Mikhail,
On 02.08.2024 01:55, Chris Morgan wrote:
From: Jernej Skrabec jernej.skrabec@gmail.com
Adjust H616 LPDDR3 DRAM settings to be in line with vendor driver.
Signed-off-by: Jernej Skrabec jernej.skrabec@gmail.com Tested-by: Chris Morgan macromorgan@hotmail.com
arch/arm/mach-sunxi/dram_sun50i_h616.c | 2 +- arch/arm/mach-sunxi/dram_timings/h616_lpddr3.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c b/arch/arm/mach-sunxi/dram_sun50i_h616.c index 37c139e0ee..a20264d8b4 100644 --- a/arch/arm/mach-sunxi/dram_sun50i_h616.c +++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c @@ -945,7 +945,7 @@ static bool mctl_phy_init(const struct dram_para *para, val = para->tpr6 & 0xff; break; case SUNXI_DRAM_TYPE_LPDDR3:
val = para->tpr6 >> 8 & 0xff;
val = para->tpr6 >> 16 & 0xff;
This is the correct change to match the factory tpr6 parameters.
I think, we also need to change the default value in arch/arm/mach-sunxi/Kconfig:
from: config DRAM_SUN50I_H616_TPR6 hex "H616 DRAM TPR6 parameter" default 0x3300c080 to default 0x33c00080
Can you please confirm what the vendor code does here? Does it use a value of 0xc0 for "val" above, so we need to change *both* the shift and the default value? Or does the vendor code write 0 (the original bits[23:16]) into val? I am a bit puzzled because I think we copied the TPR values verbatim from the vendor firmware, so changing DRAM_SUN50I_H616_TPR6 looks a bit odd.
break;
case SUNXI_DRAM_TYPE_LPDDR4: val = para->tpr6 >> 24 & 0xff; diff --git a/arch/arm/mach-sunxi/dram_timings/h616_lpddr3.c b/arch/arm/mach-sunxi/dram_timings/h616_lpddr3.c index ce2ffa7a02..82b86084a6 100644 --- a/arch/arm/mach-sunxi/dram_timings/h616_lpddr3.c +++ b/arch/arm/mach-sunxi/dram_timings/h616_lpddr3.c @@ -24,8 +24,8 @@ void mctl_set_timing_params(const struct dram_para *para) u8 trrd = max(ns_to_t(6), 4); u8 trcd = ns_to_t(24); u8 trc = ns_to_t(70);
- u8 txp = max(ns_to_t(8), 3); u8 trtp = max(ns_to_t(8), 2);
- u8 txp = trtp;
I think Jernejchanged this value using RE. I checked the 047fb104 register (dramtmg[1])
on my t98-h2b-lp3 tvbox, it has not changed and is the same as the factory value.
So my educated guess (if that change originates from REing of binary driver code): - tXP and tRTP do not seem related, judging by JEDEC documentation. If the txp value is assigned the value of trtp, that's probably some compiler optimisation, because both variables were assigned to the same expression, in the original vendor code. - The LPDDR3 spec describes tXP as "max(7.5ns,3nCK)", that would be the original setting. Down to 500 MHz DRAM clock ns_to_t(8) results in a value of 3 or higher, so this change would only be relevant for DRAM clock speeds below 500 MHz. I doubt we have a board with LPDDR3 DRAM that slow?
So I am happy to change that code, if that's closer to what the vendor driver does, but I doubt that this will impact any actual hardware. Also I would like to change the assignment to copy the *formula* that trtp is using, instead of copying the value of it. So this effectively just lowers the minimum clock cycles to 2 (instead of 3).
Does that make sense?
Cheers, Andre
=> md.l 0x47fb100 047fb100: 10141811 0004041c 04070d0d 0050500c .............PP.

From: Jernej Skrabec jernej.skrabec@gmail.com
Adjust H616 LPDDR4 DRAM settings to be in line with vendor driver.
Signed-off-by: Jernej Skrabec jernej.skrabec@gmail.com Tested-by: Chris Morgan macromorgan@hotmail.com --- arch/arm/mach-sunxi/dram_sun50i_h616.c | 35 +++++++++++++------ .../dram_timings/h616_lpddr4_2133.c | 2 +- 2 files changed, 26 insertions(+), 11 deletions(-)
diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c b/arch/arm/mach-sunxi/dram_sun50i_h616.c index a20264d8b4..b6638c519e 100644 --- a/arch/arm/mach-sunxi/dram_sun50i_h616.c +++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c @@ -293,14 +293,22 @@ static void mctl_phy_configure_odt(const struct dram_para *para) dmb(); }
-static bool mctl_phy_write_leveling(const struct dram_config *config) +static bool mctl_phy_write_leveling(const struct dram_para *para, + const struct dram_config *config) { bool result = true; u32 val;
clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 0xc0, 0x80); - writel(4, SUNXI_DRAM_PHY0_BASE + 0xc); - writel(0x40, SUNXI_DRAM_PHY0_BASE + 0x10); + + if (para->type == SUNXI_DRAM_TYPE_LPDDR4) { + /* MR2 value */ + writel(0x1b, SUNXI_DRAM_PHY0_BASE + 0xc); + writel(0, SUNXI_DRAM_PHY0_BASE + 0x10); + } else { + writel(4, SUNXI_DRAM_PHY0_BASE + 0xc); + writel(0x40, SUNXI_DRAM_PHY0_BASE + 0x10); + }
setbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 4);
@@ -859,9 +867,9 @@ static void mctl_phy_ca_bit_delay_compensation(const struct dram_para *para, } break; case SUNXI_DRAM_TYPE_LPDDR4: - if (para->tpr2 & 1) { - writel(val, SUNXI_DRAM_PHY0_BASE + 0x788); - } else { + writel(val, SUNXI_DRAM_PHY0_BASE + 0x788); + if (config->ranks == 2) { + val = (para->tpr10 >> 11) & 0x1e; writel(val, SUNXI_DRAM_PHY0_BASE + 0x794); }; break; @@ -949,6 +957,8 @@ static bool mctl_phy_init(const struct dram_para *para, break; case SUNXI_DRAM_TYPE_LPDDR4: val = para->tpr6 >> 24 & 0xff; + if (!val) + val = 0x33; break; case SUNXI_DRAM_TYPE_DDR4: default: @@ -1080,19 +1090,27 @@ static bool mctl_phy_init(const struct dram_para *para, mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0);
writel(0xb04, &mctl_ctl->mrctrl1); + udelay(10); writel(0x80000030, &mctl_ctl->mrctrl0); + udelay(10); mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0);
writel(0xc72, &mctl_ctl->mrctrl1); + udelay(10); writel(0x80000030, &mctl_ctl->mrctrl0); + udelay(10); mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0);
writel(0xe09, &mctl_ctl->mrctrl1); + udelay(10); writel(0x80000030, &mctl_ctl->mrctrl0); + udelay(10); mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0);
writel(0x1624, &mctl_ctl->mrctrl1); + udelay(10); writel(0x80000030, &mctl_ctl->mrctrl0); + udelay(10); mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0); break; case SUNXI_DRAM_TYPE_DDR4: @@ -1108,7 +1126,7 @@ static bool mctl_phy_init(const struct dram_para *para,
if (para->tpr10 & TPR10_WRITE_LEVELING) { for (i = 0; i < 5; i++) - if (mctl_phy_write_leveling(config)) + if (mctl_phy_write_leveling(para, config)) break; if (i == 5) { debug("write leveling failed!\n"); @@ -1234,9 +1252,6 @@ static bool mctl_ctrl_init(const struct dram_para *para, 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));
diff --git a/arch/arm/mach-sunxi/dram_timings/h616_lpddr4_2133.c b/arch/arm/mach-sunxi/dram_timings/h616_lpddr4_2133.c index e6446b9180..6f5c4acbd6 100644 --- a/arch/arm/mach-sunxi/dram_timings/h616_lpddr4_2133.c +++ b/arch/arm/mach-sunxi/dram_timings/h616_lpddr4_2133.c @@ -23,7 +23,7 @@ void mctl_set_timing_params(const struct dram_para *para) u8 trcd = max(ns_to_t(18), 2); u8 trc = ns_to_t(65); u8 txp = max(ns_to_t(8), 2); - u8 trtp = max(ns_to_t(8), 4); + u8 trtp = 4; u8 trp = ns_to_t(21); u8 tras = ns_to_t(42); u16 trefi = ns_to_t(3904) / 32;

On 02.08.2024 01:55, Chris Morgan wrote:
From: Jernej Skrabec jernej.skrabec@gmail.com
Adjust H616 LPDDR4 DRAM settings to be in line with vendor driver.
Signed-off-by: Jernej Skrabec jernej.skrabec@gmail.com Tested-by: Chris Morgan macromorgan@hotmail.com
arch/arm/mach-sunxi/dram_sun50i_h616.c | 35 +++++++++++++------ .../dram_timings/h616_lpddr4_2133.c | 2 +- 2 files changed, 26 insertions(+), 11 deletions(-)
diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c b/arch/arm/mach-sunxi/dram_sun50i_h616.c index a20264d8b4..b6638c519e 100644 --- a/arch/arm/mach-sunxi/dram_sun50i_h616.c +++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c @@ -293,14 +293,22 @@ static void mctl_phy_configure_odt(const struct dram_para *para) dmb(); }
-static bool mctl_phy_write_leveling(const struct dram_config *config) +static bool mctl_phy_write_leveling(const struct dram_para *para,
const struct dram_config *config)
{ bool result = true; u32 val;
clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 0xc0, 0x80);
- writel(4, SUNXI_DRAM_PHY0_BASE + 0xc);
- writel(0x40, SUNXI_DRAM_PHY0_BASE + 0x10);
if (para->type == SUNXI_DRAM_TYPE_LPDDR4) {
/* MR2 value */
writel(0x1b, SUNXI_DRAM_PHY0_BASE + 0xc);
writel(0, SUNXI_DRAM_PHY0_BASE + 0x10);
} else {
writel(4, SUNXI_DRAM_PHY0_BASE + 0xc);
writel(0x40, SUNXI_DRAM_PHY0_BASE + 0x10);
}
setbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 4);
@@ -859,9 +867,9 @@ static void mctl_phy_ca_bit_delay_compensation(const struct dram_para *para, } break; case SUNXI_DRAM_TYPE_LPDDR4:
if (para->tpr2 & 1) {
writel(val, SUNXI_DRAM_PHY0_BASE + 0x788);
} else {
writel(val, SUNXI_DRAM_PHY0_BASE + 0x788);
if (config->ranks == 2) {
}; break;val = (para->tpr10 >> 11) & 0x1e; writel(val, SUNXI_DRAM_PHY0_BASE + 0x794);
@@ -949,6 +957,8 @@ static bool mctl_phy_init(const struct dram_para *para, break; case SUNXI_DRAM_TYPE_LPDDR4: val = para->tpr6 >> 24 & 0xff;
if (!val)
val = 0x33;
We don't need this as the default value from arch/arm/mach-sunxi/Kconfigcovers this case:
config DRAM_SUN50I_H616_TPR6 hex "H616 DRAM TPR6 parameter" default 0x3300c080
break;
case SUNXI_DRAM_TYPE_DDR4: default: @@ -1080,19 +1090,27 @@ static bool mctl_phy_init(const struct dram_para *para, mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0);
writel(0xb04, &mctl_ctl->mrctrl1);
udelay(10);
writel(0x80000030, &mctl_ctl->mrctrl0);
udelay(10);
mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0);
writel(0xc72, &mctl_ctl->mrctrl1);
udelay(10);
writel(0x80000030, &mctl_ctl->mrctrl0);
udelay(10);
mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0);
writel(0xe09, &mctl_ctl->mrctrl1);
udelay(10);
writel(0x80000030, &mctl_ctl->mrctrl0);
udelay(10);
mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0);
writel(0x1624, &mctl_ctl->mrctrl1);
udelay(10);
writel(0x80000030, &mctl_ctl->mrctrl0);
udelay(10);
Looks like something experimental.
mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0); break;
case SUNXI_DRAM_TYPE_DDR4: @@ -1108,7 +1126,7 @@ static bool mctl_phy_init(const struct dram_para *para,
if (para->tpr10 & TPR10_WRITE_LEVELING) { for (i = 0; i < 5; i++)
if (mctl_phy_write_leveling(config))
if (i == 5) { debug("write leveling failed!\n");if (mctl_phy_write_leveling(para, config)) break;
@@ -1234,9 +1252,6 @@ static bool mctl_ctrl_init(const struct dram_para *para, 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);
I have this piece of code in the opizero3 mtd dump. This condition depends on tpr13. Judging by the dram_para parameters, it should be performed for lpddr4 (and maybe ddr4) memory. According to the opizero3 dump it should clear all values and set BIT(2). Don't know, why I only set BIT(0) here. This may be a bug or another spl from t507 and the first version of the driver.
setbits_le32(&mctl_ctl->rfshctl3, BIT(0)); clrbits_le32(&mctl_ctl->dfimisc, BIT(0));
diff --git a/arch/arm/mach-sunxi/dram_timings/h616_lpddr4_2133.c b/arch/arm/mach-sunxi/dram_timings/h616_lpddr4_2133.c index e6446b9180..6f5c4acbd6 100644 --- a/arch/arm/mach-sunxi/dram_timings/h616_lpddr4_2133.c +++ b/arch/arm/mach-sunxi/dram_timings/h616_lpddr4_2133.c @@ -23,7 +23,7 @@ void mctl_set_timing_params(const struct dram_para *para) u8 trcd = max(ns_to_t(18), 2); u8 trc = ns_to_t(65); u8 txp = max(ns_to_t(8), 2);
- u8 trtp = max(ns_to_t(8), 4);
- u8 trtp = 4; u8 trp = ns_to_t(21); u8 tras = ns_to_t(42); u16 trefi = ns_to_t(3904) / 32;

On Sat, Aug 03, 2024 at 03:29:17PM +0300, Mikhail Kalashnikov wrote:
On 02.08.2024 01:55, Chris Morgan wrote:
From: Jernej Skrabec jernej.skrabec@gmail.com
Adjust H616 LPDDR4 DRAM settings to be in line with vendor driver.
Signed-off-by: Jernej Skrabec jernej.skrabec@gmail.com Tested-by: Chris Morgan macromorgan@hotmail.com
arch/arm/mach-sunxi/dram_sun50i_h616.c | 35 +++++++++++++------ .../dram_timings/h616_lpddr4_2133.c | 2 +- 2 files changed, 26 insertions(+), 11 deletions(-)
diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c b/arch/arm/mach-sunxi/dram_sun50i_h616.c index a20264d8b4..b6638c519e 100644 --- a/arch/arm/mach-sunxi/dram_sun50i_h616.c +++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c @@ -293,14 +293,22 @@ static void mctl_phy_configure_odt(const struct dram_para *para) dmb(); } -static bool mctl_phy_write_leveling(const struct dram_config *config) +static bool mctl_phy_write_leveling(const struct dram_para *para,
{ bool result = true; u32 val; clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 0xc0, 0x80);const struct dram_config *config)
- writel(4, SUNXI_DRAM_PHY0_BASE + 0xc);
- writel(0x40, SUNXI_DRAM_PHY0_BASE + 0x10);
- if (para->type == SUNXI_DRAM_TYPE_LPDDR4) {
/* MR2 value */
writel(0x1b, SUNXI_DRAM_PHY0_BASE + 0xc);
writel(0, SUNXI_DRAM_PHY0_BASE + 0x10);
- } else {
writel(4, SUNXI_DRAM_PHY0_BASE + 0xc);
writel(0x40, SUNXI_DRAM_PHY0_BASE + 0x10);
- } setbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 4);
@@ -859,9 +867,9 @@ static void mctl_phy_ca_bit_delay_compensation(const struct dram_para *para, } break; case SUNXI_DRAM_TYPE_LPDDR4:
if (para->tpr2 & 1) {
writel(val, SUNXI_DRAM_PHY0_BASE + 0x788);
} else {
writel(val, SUNXI_DRAM_PHY0_BASE + 0x788);
if (config->ranks == 2) {
}; break;val = (para->tpr10 >> 11) & 0x1e; writel(val, SUNXI_DRAM_PHY0_BASE + 0x794);
@@ -949,6 +957,8 @@ static bool mctl_phy_init(const struct dram_para *para, break; case SUNXI_DRAM_TYPE_LPDDR4: val = para->tpr6 >> 24 & 0xff;
if (!val)
val = 0x33;
We don't need this as the default value from arch/arm/mach-sunxi/Kconfigcovers this case:
config DRAM_SUN50I_H616_TPR6 hex "H616 DRAM TPR6 parameter" default 0x3300c080
break;
case SUNXI_DRAM_TYPE_DDR4: default: @@ -1080,19 +1090,27 @@ static bool mctl_phy_init(const struct dram_para *para, mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0); writel(0xb04, &mctl_ctl->mrctrl1);
writel(0x80000030, &mctl_ctl->mrctrl0);udelay(10);
mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0); writel(0xc72, &mctl_ctl->mrctrl1);udelay(10);
writel(0x80000030, &mctl_ctl->mrctrl0);udelay(10);
mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0); writel(0xe09, &mctl_ctl->mrctrl1);udelay(10);
writel(0x80000030, &mctl_ctl->mrctrl0);udelay(10);
mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0); writel(0x1624, &mctl_ctl->mrctrl1);udelay(10);
writel(0x80000030, &mctl_ctl->mrctrl0);udelay(10);
udelay(10);
Looks like something experimental.
Should I remove it? Sorry but I'm not super familiar with this specific code.
mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0); break;
case SUNXI_DRAM_TYPE_DDR4: @@ -1108,7 +1126,7 @@ static bool mctl_phy_init(const struct dram_para *para, if (para->tpr10 & TPR10_WRITE_LEVELING) { for (i = 0; i < 5; i++)
if (mctl_phy_write_leveling(config))
if (i == 5) { debug("write leveling failed!\n");if (mctl_phy_write_leveling(para, config)) break;
@@ -1234,9 +1252,6 @@ static bool mctl_ctrl_init(const struct dram_para *para, 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);
I have this piece of code in the opizero3 mtd dump. This condition depends on tpr13. Judging by the dram_para parameters, it should be performed for lpddr4 (and maybe ddr4) memory. According to the opizero3 dump it should clear all values and set BIT(2). Don't know, why I only set BIT(0) here. This may be a bug or another spl from t507 and the first version of the driver.
What would be correct here then?
setbits_le32(&mctl_ctl->rfshctl3, BIT(0)); clrbits_le32(&mctl_ctl->dfimisc, BIT(0)); diff --git a/arch/arm/mach-sunxi/dram_timings/h616_lpddr4_2133.c b/arch/arm/mach-sunxi/dram_timings/h616_lpddr4_2133.c index e6446b9180..6f5c4acbd6 100644 --- a/arch/arm/mach-sunxi/dram_timings/h616_lpddr4_2133.c +++ b/arch/arm/mach-sunxi/dram_timings/h616_lpddr4_2133.c @@ -23,7 +23,7 @@ void mctl_set_timing_params(const struct dram_para *para) u8 trcd = max(ns_to_t(18), 2); u8 trc = ns_to_t(65); u8 txp = max(ns_to_t(8), 2);
- u8 trtp = max(ns_to_t(8), 4);
- u8 trtp = 4; u8 trp = ns_to_t(21); u8 tras = ns_to_t(42); u16 trefi = ns_to_t(3904) / 32;
Thank you, Chris

On Wed, Aug 14, 2024 at 04:06:23PM -0500, Chris Morgan wrote:
On Sat, Aug 03, 2024 at 03:29:17PM +0300, Mikhail Kalashnikov wrote:
On 02.08.2024 01:55, Chris Morgan wrote:
From: Jernej Skrabec jernej.skrabec@gmail.com
Adjust H616 LPDDR4 DRAM settings to be in line with vendor driver.
Signed-off-by: Jernej Skrabec jernej.skrabec@gmail.com Tested-by: Chris Morgan macromorgan@hotmail.com
arch/arm/mach-sunxi/dram_sun50i_h616.c | 35 +++++++++++++------ .../dram_timings/h616_lpddr4_2133.c | 2 +- 2 files changed, 26 insertions(+), 11 deletions(-)
diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c b/arch/arm/mach-sunxi/dram_sun50i_h616.c index a20264d8b4..b6638c519e 100644 --- a/arch/arm/mach-sunxi/dram_sun50i_h616.c +++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c @@ -293,14 +293,22 @@ static void mctl_phy_configure_odt(const struct dram_para *para) dmb(); } -static bool mctl_phy_write_leveling(const struct dram_config *config) +static bool mctl_phy_write_leveling(const struct dram_para *para,
{ bool result = true; u32 val; clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 0xc0, 0x80);const struct dram_config *config)
- writel(4, SUNXI_DRAM_PHY0_BASE + 0xc);
- writel(0x40, SUNXI_DRAM_PHY0_BASE + 0x10);
- if (para->type == SUNXI_DRAM_TYPE_LPDDR4) {
/* MR2 value */
writel(0x1b, SUNXI_DRAM_PHY0_BASE + 0xc);
writel(0, SUNXI_DRAM_PHY0_BASE + 0x10);
- } else {
writel(4, SUNXI_DRAM_PHY0_BASE + 0xc);
writel(0x40, SUNXI_DRAM_PHY0_BASE + 0x10);
- } setbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 4);
@@ -859,9 +867,9 @@ static void mctl_phy_ca_bit_delay_compensation(const struct dram_para *para, } break; case SUNXI_DRAM_TYPE_LPDDR4:
if (para->tpr2 & 1) {
writel(val, SUNXI_DRAM_PHY0_BASE + 0x788);
} else {
writel(val, SUNXI_DRAM_PHY0_BASE + 0x788);
if (config->ranks == 2) {
}; break;val = (para->tpr10 >> 11) & 0x1e; writel(val, SUNXI_DRAM_PHY0_BASE + 0x794);
@@ -949,6 +957,8 @@ static bool mctl_phy_init(const struct dram_para *para, break; case SUNXI_DRAM_TYPE_LPDDR4: val = para->tpr6 >> 24 & 0xff;
if (!val)
val = 0x33;
We don't need this as the default value from arch/arm/mach-sunxi/Kconfigcovers this case:
config DRAM_SUN50I_H616_TPR6 hex "H616 DRAM TPR6 parameter" default 0x3300c080
break;
case SUNXI_DRAM_TYPE_DDR4: default: @@ -1080,19 +1090,27 @@ static bool mctl_phy_init(const struct dram_para *para, mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0); writel(0xb04, &mctl_ctl->mrctrl1);
writel(0x80000030, &mctl_ctl->mrctrl0);udelay(10);
mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0); writel(0xc72, &mctl_ctl->mrctrl1);udelay(10);
writel(0x80000030, &mctl_ctl->mrctrl0);udelay(10);
mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0); writel(0xe09, &mctl_ctl->mrctrl1);udelay(10);
writel(0x80000030, &mctl_ctl->mrctrl0);udelay(10);
mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0); writel(0x1624, &mctl_ctl->mrctrl1);udelay(10);
writel(0x80000030, &mctl_ctl->mrctrl0);udelay(10);
udelay(10);
Looks like something experimental.
Should I remove it? Sorry but I'm not super familiar with this specific code.
mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0); break;
case SUNXI_DRAM_TYPE_DDR4: @@ -1108,7 +1126,7 @@ static bool mctl_phy_init(const struct dram_para *para, if (para->tpr10 & TPR10_WRITE_LEVELING) { for (i = 0; i < 5; i++)
if (mctl_phy_write_leveling(config))
if (i == 5) { debug("write leveling failed!\n");if (mctl_phy_write_leveling(para, config)) break;
@@ -1234,9 +1252,6 @@ static bool mctl_ctrl_init(const struct dram_para *para, 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);
I have this piece of code in the opizero3 mtd dump. This condition depends on tpr13. Judging by the dram_para parameters, it should be performed for lpddr4 (and maybe ddr4) memory. According to the opizero3 dump it should clear all values and set BIT(2). Don't know, why I only set BIT(0) here. This may be a bug or another spl from t507 and the first version of the driver.
What would be correct here then?
I've tested removing and/or changing this to writel(BIT(2), &mctl_ctl->dbictl); and it failed to work. Leaving this as it is things do seem to work though.
Let me know what you want me to test here and I will.
Thank you, Chris
setbits_le32(&mctl_ctl->rfshctl3, BIT(0)); clrbits_le32(&mctl_ctl->dfimisc, BIT(0)); diff --git a/arch/arm/mach-sunxi/dram_timings/h616_lpddr4_2133.c b/arch/arm/mach-sunxi/dram_timings/h616_lpddr4_2133.c index e6446b9180..6f5c4acbd6 100644 --- a/arch/arm/mach-sunxi/dram_timings/h616_lpddr4_2133.c +++ b/arch/arm/mach-sunxi/dram_timings/h616_lpddr4_2133.c @@ -23,7 +23,7 @@ void mctl_set_timing_params(const struct dram_para *para) u8 trcd = max(ns_to_t(18), 2); u8 trc = ns_to_t(65); u8 txp = max(ns_to_t(8), 2);
- u8 trtp = max(ns_to_t(8), 4);
- u8 trtp = 4; u8 trp = ns_to_t(21); u8 tras = ns_to_t(42); u16 trefi = ns_to_t(3904) / 32;
Thank you, Chris

On 16.08.2024 4:03 AM, Chris Morgan wrote:
On Wed, Aug 14, 2024 at 04:06:23PM -0500, Chris Morgan wrote:
On Sat, Aug 03, 2024 at 03:29:17PM +0300, Mikhail Kalashnikov wrote:
On 02.08.2024 01:55, Chris Morgan wrote:
From: Jernej Skrabec jernej.skrabec@gmail.com
Adjust H616 LPDDR4 DRAM settings to be in line with vendor driver.
Signed-off-by: Jernej Skrabec jernej.skrabec@gmail.com Tested-by: Chris Morgan macromorgan@hotmail.com
arch/arm/mach-sunxi/dram_sun50i_h616.c | 35 +++++++++++++------ .../dram_timings/h616_lpddr4_2133.c | 2 +- 2 files changed, 26 insertions(+), 11 deletions(-)
diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c b/arch/arm/mach-sunxi/dram_sun50i_h616.c index a20264d8b4..b6638c519e 100644 --- a/arch/arm/mach-sunxi/dram_sun50i_h616.c +++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c @@ -293,14 +293,22 @@ static void mctl_phy_configure_odt(const struct dram_para *para) dmb(); } -static bool mctl_phy_write_leveling(const struct dram_config *config) +static bool mctl_phy_write_leveling(const struct dram_para *para,
{ bool result = true; u32 val; clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 0xc0, 0x80);const struct dram_config *config)
- writel(4, SUNXI_DRAM_PHY0_BASE + 0xc);
- writel(0x40, SUNXI_DRAM_PHY0_BASE + 0x10);
- if (para->type == SUNXI_DRAM_TYPE_LPDDR4) {
/* MR2 value */
writel(0x1b, SUNXI_DRAM_PHY0_BASE + 0xc);
writel(0, SUNXI_DRAM_PHY0_BASE + 0x10);
- } else {
writel(4, SUNXI_DRAM_PHY0_BASE + 0xc);
writel(0x40, SUNXI_DRAM_PHY0_BASE + 0x10);
- } setbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 4);
@@ -859,9 +867,9 @@ static void mctl_phy_ca_bit_delay_compensation(const struct dram_para *para, } break; case SUNXI_DRAM_TYPE_LPDDR4:
if (para->tpr2 & 1) {
writel(val, SUNXI_DRAM_PHY0_BASE + 0x788);
} else {
writel(val, SUNXI_DRAM_PHY0_BASE + 0x788);
if (config->ranks == 2) {
val = (para->tpr10 >> 11) & 0x1e; writel(val, SUNXI_DRAM_PHY0_BASE + 0x794); }; break;
@@ -949,6 +957,8 @@ static bool mctl_phy_init(const struct dram_para *para, break; case SUNXI_DRAM_TYPE_LPDDR4: val = para->tpr6 >> 24 & 0xff;
if (!val)
val = 0x33;
We don't need this as the default value from arch/arm/mach-sunxi/Kconfigcovers this case:
config DRAM_SUN50I_H616_TPR6 hex "H616 DRAM TPR6 parameter" default 0x3300c080
break; case SUNXI_DRAM_TYPE_DDR4: default:
@@ -1080,19 +1090,27 @@ static bool mctl_phy_init(const struct dram_para *para, mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0); writel(0xb04, &mctl_ctl->mrctrl1);
udelay(10); writel(0x80000030, &mctl_ctl->mrctrl0);
udelay(10); mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0); writel(0xc72, &mctl_ctl->mrctrl1);
udelay(10); writel(0x80000030, &mctl_ctl->mrctrl0);
udelay(10); mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0); writel(0xe09, &mctl_ctl->mrctrl1);
udelay(10); writel(0x80000030, &mctl_ctl->mrctrl0);
udelay(10); mctl_await_completion(&mctl_ctl->mrctrl0, BIT(31), 0); writel(0x1624, &mctl_ctl->mrctrl1);
udelay(10); writel(0x80000030, &mctl_ctl->mrctrl0);
udelay(10);
Looks like something experimental.
Should I remove it? Sorry but I'm not super familiar with this specific code.
Unfortunately, I don't know what exactly these changes should change. I think it would be right to add only the necessary changes for adding a new device. Some devices that use this driver have not been tested yet. I think the rest of the changes can be prepared by Jernej when he has time

From: Jernej Skrabec jernej.skrabec@gmail.com
It seems that different dies need different PHY pin mapping. Select alternatives based on "bond ID".
Signed-off-by: Jernej Skrabec jernej.skrabec@gmail.com Tested-by: Chris Morgan macromorgan@hotmail.com --- arch/arm/mach-sunxi/dram_sun50i_h616.c | 59 +++++++++++++++++++------- 1 file changed, 44 insertions(+), 15 deletions(-)
diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c b/arch/arm/mach-sunxi/dram_sun50i_h616.c index b6638c519e..abb8ee760b 100644 --- a/arch/arm/mach-sunxi/dram_sun50i_h616.c +++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c @@ -225,22 +225,43 @@ static void mctl_set_addrmap(const struct dram_config *config) mctl_ctl->addrmap[8] = 0x3F3F; }
-static const u8 phy_init[] = { +static const u8 phy_addr_maps[2][27] = { #ifdef CONFIG_SUNXI_DRAM_H616_DDR3_1333 - 0x07, 0x0b, 0x02, 0x16, 0x0d, 0x0e, 0x14, 0x19, - 0x0a, 0x15, 0x03, 0x13, 0x04, 0x0c, 0x10, 0x06, - 0x0f, 0x11, 0x1a, 0x01, 0x12, 0x17, 0x00, 0x08, - 0x09, 0x05, 0x18 + { + 0x07, 0x0b, 0x02, 0x16, 0x0d, 0x0e, 0x14, 0x19, + 0x0a, 0x15, 0x03, 0x13, 0x04, 0x0c, 0x10, 0x06, + 0x0f, 0x11, 0x1a, 0x01, 0x12, 0x17, 0x00, 0x08, + 0x09, 0x05, 0x18 + }, { + 0x08, 0x02, 0x12, 0x05, 0x15, 0x17, 0x18, 0x0b, + 0x14, 0x07, 0x04, 0x13, 0x0c, 0x00, 0x16, 0x1a, + 0x0a, 0x11, 0x03, 0x10, 0x0e, 0x01, 0x0d, 0x19, + 0x06, 0x09, 0x0f + } #elif defined(CONFIG_SUNXI_DRAM_H616_LPDDR3) - 0x18, 0x06, 0x00, 0x05, 0x04, 0x03, 0x09, 0x02, - 0x08, 0x01, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x07, - 0x17, 0x19, 0x1a + { + 0x18, 0x06, 0x00, 0x05, 0x04, 0x03, 0x09, 0x02, + 0x08, 0x01, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x07, + 0x17, 0x19, 0x1a + }, { + 0x18, 0x00, 0x04, 0x09, 0x06, 0x05, 0x02, 0x19, + 0x17, 0x03, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x07, + 0x08, 0x01, 0x1a + } #elif defined(CONFIG_SUNXI_DRAM_H616_LPDDR4) - 0x02, 0x00, 0x17, 0x05, 0x04, 0x19, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x01, - 0x18, 0x03, 0x1a + { + 0x02, 0x00, 0x17, 0x05, 0x04, 0x19, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x01, + 0x18, 0x03, 0x1a + }, { + 0x03, 0x00, 0x17, 0x05, 0x02, 0x19, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x01, + 0x18, 0x04, 0x1a + } #endif };
@@ -887,6 +908,7 @@ static bool mctl_phy_init(const struct dram_para *para, struct sunxi_mctl_ctl_reg * const mctl_ctl = (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE; u32 val, val2, *ptr, mr0, mr2; + const u8 *map; int i;
if (para->type == SUNXI_DRAM_TYPE_LPDDR4) @@ -942,8 +964,15 @@ static bool mctl_phy_init(const struct dram_para *para, writel(val2, SUNXI_DRAM_PHY0_BASE + 0x37c);
ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xc0); - for (i = 0; i < ARRAY_SIZE(phy_init); i++) - writel(phy_init[i], &ptr[i]); + val = readl(SUNXI_SID_BASE); + if (((val & 0xfbff) == 0x5000) || + ((val & 0xfeff) == 0x5c00) || + ((val & 0xf7ff) == 0x2000)) + map = phy_addr_maps[0]; + else + map = phy_addr_maps[1]; + for (i = 0; i < ARRAY_SIZE(phy_addr_maps[0]); i++) + writel(map[i], &ptr[i]);
if (para->tpr10 & TPR10_CA_BIT_DELAY) mctl_phy_ca_bit_delay_compensation(para, config);

From: Jernej Skrabec jernej.skrabec@gmail.com
When comparing configuration procedure to vendor driver, I noticed that one command was out of order and that some delays were missing.
Fix that.
Signed-off-by: Jernej Skrabec jernej.skrabec@gmail.com Tested-by: Chris Morgan macromorgan@hotmail.com --- arch/arm/mach-sunxi/dram_sun50i_h616.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c b/arch/arm/mach-sunxi/dram_sun50i_h616.c index abb8ee760b..aec561cc94 100644 --- a/arch/arm/mach-sunxi/dram_sun50i_h616.c +++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c @@ -1025,12 +1025,16 @@ static bool mctl_phy_init(const struct dram_para *para, clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x14c, 0xe0, 0x20); }
+ clrbits_le32(&mctl_com->unk_0x500, 0x200); + udelay(1); + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x14c, 8);
mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x180), 4, 4);
+ udelay(1000); + writel(0x37, SUNXI_DRAM_PHY0_BASE + 0x58); - clrbits_le32(&mctl_com->unk_0x500, 0x200);
writel(0, &mctl_ctl->swctl); setbits_le32(&mctl_ctl->dfimisc, 1); @@ -1049,6 +1053,8 @@ static bool mctl_phy_init(const struct dram_para *para, mctl_await_completion(&mctl_ctl->swstat, 1, 1); mctl_await_completion(&mctl_ctl->statr, 3, 1);
+ udelay(200); + writel(0, &mctl_ctl->swctl); clrbits_le32(&mctl_ctl->dfimisc, 1);
@@ -1292,8 +1298,10 @@ static bool mctl_ctrl_init(const struct dram_para *para, setbits_le32(&mctl_ctl->clken, BIT(8));
clrsetbits_le32(&mctl_com->unk_0x500, BIT(24), 0x300); + udelay(1); /* this write seems to enable PHY MMIO region */ setbits_le32(&mctl_com->unk_0x500, BIT(24)); + udelay(1);
if (!mctl_phy_init(para, config)) return false;

From: Jernej Skrabec jernej.skrabec@gmail.com
It's safer to start scanning for columns first and then rows. Columns reside on LSB address pins, which means that second configuration will already have all needed row pins active.
This is also preparation for introducing DDR4 support, which need scan for banks and bank groups too.
Signed-off-by: Jernej Skrabec jernej.skrabec@gmail.com Tested-by: Chris Morgan macromorgan@hotmail.com --- arch/arm/mach-sunxi/dram_sun50i_h616.c | 31 +++++++++++++++----------- 1 file changed, 18 insertions(+), 13 deletions(-)
diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c b/arch/arm/mach-sunxi/dram_sun50i_h616.c index aec561cc94..3075d9c80d 100644 --- a/arch/arm/mach-sunxi/dram_sun50i_h616.c +++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c @@ -1373,28 +1373,33 @@ static void mctl_auto_detect_rank_width(const struct dram_para *para, 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 = 18; + unsigned int shift; + + /* max. config for columns, but not rows */ + config->cols = 11; + config->rows = 13; mctl_core_init(para, config);
- for (config->rows = 13; config->rows < 18; 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)))) + shift = config->bus_full_width + 1; + + /* detect column address bits */ + for (config->cols = 8; config->cols < 11; config->cols++) { + if (mctl_mem_matches(1ULL << (config->cols + shift))) break; } + debug("detected %u columns\n", config->cols);
- /* detect column address bits */ - config->cols = 11; + /* reconfigure to make sure that all active rows are accessible */ + config->rows = 18; 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))) + /* detect row address bits */ + shift = config->bus_full_width + 4 + config->cols; + for (config->rows = 13; config->rows < 18; config->rows++) { + if (mctl_mem_matches(1ULL << (config->rows + shift))) break; } + debug("detected %u rows\n", config->rows); }
static unsigned long mctl_calc_size(const struct dram_config *config)

From: Jernej Skrabec jernej.skrabec@gmail.com
CSI1 channel (22) is missing and IOMMU (25) has priority flag set in vendor bootloader. Fix that.
While at it, replace bandwidth flag with priority since original flag has always value "true".
Signed-off-by: Jernej Skrabec jernej.skrabec@gmail.com Tested-by: Chris Morgan macromorgan@hotmail.com --- arch/arm/mach-sunxi/dram_sun50i_h616.c | 41 +++++++++++++------------- 1 file changed, 21 insertions(+), 20 deletions(-)
diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c b/arch/arm/mach-sunxi/dram_sun50i_h616.c index 3075d9c80d..d2380a3531 100644 --- a/arch/arm/mach-sunxi/dram_sun50i_h616.c +++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c @@ -55,8 +55,8 @@ static void mbus_configure_port(u8 port, writel_relaxed(cfg1, &mctl_com->master[port].cfg1); }
-#define MBUS_CONF(port, bwlimit, qos, acs, bwl0, bwl1, bwl2) \ - mbus_configure_port(port, bwlimit, false, \ +#define MBUS_CONF(port, priority, qos, acs, bwl0, bwl1, bwl2) \ + mbus_configure_port(port, true, priority, \ MBUS_QOS_ ## qos, 0, acs, bwl0, bwl1, bwl2)
static void mctl_set_master_priority(void) @@ -68,24 +68,25 @@ static void mctl_set_master_priority(void) writel(399, &mctl_com->tmr); writel(BIT(16), &mctl_com->bwcr);
- MBUS_CONF( 0, true, HIGHEST, 0, 256, 128, 100); - MBUS_CONF( 1, true, HIGH, 0, 1536, 1400, 256); - MBUS_CONF( 2, true, HIGHEST, 0, 512, 256, 96); - MBUS_CONF( 3, true, HIGH, 0, 256, 100, 80); - MBUS_CONF( 4, true, HIGH, 2, 8192, 5500, 5000); - MBUS_CONF( 5, true, HIGH, 2, 100, 64, 32); - MBUS_CONF( 6, true, HIGH, 2, 100, 64, 32); - MBUS_CONF( 8, true, HIGH, 0, 256, 128, 64); - MBUS_CONF(11, true, HIGH, 0, 256, 128, 100); - MBUS_CONF(14, true, HIGH, 0, 1024, 256, 64); - MBUS_CONF(16, true, HIGHEST, 6, 8192, 2800, 2400); - MBUS_CONF(21, true, HIGHEST, 6, 2048, 768, 512); - MBUS_CONF(25, true, HIGHEST, 0, 100, 64, 32); - MBUS_CONF(26, true, HIGH, 2, 8192, 5500, 5000); - MBUS_CONF(37, true, HIGH, 0, 256, 128, 64); - MBUS_CONF(38, true, HIGH, 2, 100, 64, 32); - MBUS_CONF(39, true, HIGH, 2, 8192, 5500, 5000); - MBUS_CONF(40, true, HIGH, 2, 100, 64, 32); + MBUS_CONF(0, false, HIGHEST, 0, 256, 128, 100); + MBUS_CONF(1, false, HIGH, 0, 1536, 1400, 256); + MBUS_CONF(2, false, HIGHEST, 0, 512, 256, 96); + MBUS_CONF(3, false, HIGH, 0, 256, 100, 80); + MBUS_CONF(4, false, HIGH, 2, 8192, 5500, 5000); + MBUS_CONF(5, false, HIGH, 2, 100, 64, 32); + MBUS_CONF(6, false, HIGH, 2, 100, 64, 32); + MBUS_CONF(8, false, HIGH, 0, 256, 128, 64); + MBUS_CONF(11, false, HIGH, 0, 256, 128, 100); + MBUS_CONF(14, false, HIGH, 0, 1024, 256, 64); + MBUS_CONF(16, false, HIGHEST, 6, 8192, 2800, 2400); + MBUS_CONF(21, false, HIGHEST, 6, 2048, 768, 512); + MBUS_CONF(22, false, HIGH, 0, 256, 128, 100); + MBUS_CONF(25, true, HIGHEST, 0, 100, 64, 32); + MBUS_CONF(26, false, HIGH, 2, 8192, 5500, 5000); + MBUS_CONF(37, false, HIGH, 0, 256, 128, 64); + MBUS_CONF(38, false, HIGH, 2, 100, 64, 32); + MBUS_CONF(39, false, HIGH, 2, 8192, 5500, 5000); + MBUS_CONF(40, false, HIGH, 2, 100, 64, 32);
dmb(); }

From: Chris Morgan macromorgan@hotmail.com
Update the sun50i-h616.dtsi file from upstream linux, and include the fix for selecting the pinctrl for the r_i2c bus from mainline:
7c9ea4ab7617 ("arm64: dts: allwinner: h616: Add r_i2c pinctrl nodes")
Signed-off-by: Chris Morgan macromorgan@hotmail.com --- arch/arm/dts/sun50i-h616.dtsi | 98 ++++++++++++++++++++- include/dt-bindings/clock/sun50i-h616-ccu.h | 1 + include/dt-bindings/reset/sun50i-h616-ccu.h | 1 + 3 files changed, 99 insertions(+), 1 deletion(-)
diff --git a/arch/arm/dts/sun50i-h616.dtsi b/arch/arm/dts/sun50i-h616.dtsi index b2e85e52d1..e88c1fbac6 100644 --- a/arch/arm/dts/sun50i-h616.dtsi +++ b/arch/arm/dts/sun50i-h616.dtsi @@ -26,6 +26,14 @@ reg = <0>; enable-method = "psci"; clocks = <&ccu CLK_CPUX>; + #cooling-cells = <2>; + i-cache-size = <0x8000>; + i-cache-line-size = <64>; + i-cache-sets = <256>; + d-cache-size = <0x8000>; + d-cache-line-size = <64>; + d-cache-sets = <128>; + next-level-cache = <&l2_cache>; };
cpu1: cpu@1 { @@ -34,6 +42,14 @@ reg = <1>; enable-method = "psci"; clocks = <&ccu CLK_CPUX>; + #cooling-cells = <2>; + i-cache-size = <0x8000>; + i-cache-line-size = <64>; + i-cache-sets = <256>; + d-cache-size = <0x8000>; + d-cache-line-size = <64>; + d-cache-sets = <128>; + next-level-cache = <&l2_cache>; };
cpu2: cpu@2 { @@ -42,6 +58,14 @@ reg = <2>; enable-method = "psci"; clocks = <&ccu CLK_CPUX>; + #cooling-cells = <2>; + i-cache-size = <0x8000>; + i-cache-line-size = <64>; + i-cache-sets = <256>; + d-cache-size = <0x8000>; + d-cache-line-size = <64>; + d-cache-sets = <128>; + next-level-cache = <&l2_cache>; };
cpu3: cpu@3 { @@ -50,6 +74,23 @@ reg = <3>; enable-method = "psci"; clocks = <&ccu CLK_CPUX>; + #cooling-cells = <2>; + i-cache-size = <0x8000>; + i-cache-line-size = <64>; + i-cache-sets = <256>; + d-cache-size = <0x8000>; + d-cache-line-size = <64>; + d-cache-sets = <128>; + next-level-cache = <&l2_cache>; + }; + + l2_cache: l2-cache { + compatible = "cache"; + cache-level = <2>; + cache-unified; + cache-size = <0x40000>; + cache-line-size = <64>; + cache-sets = <256>; }; };
@@ -109,6 +150,16 @@ #size-cells = <1>; ranges = <0x0 0x0 0x0 0x40000000>;
+ crypto: crypto@1904000 { + compatible = "allwinner,sun50i-h616-crypto"; + reg = <0x01904000 0x800>; + interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_CE>, <&ccu CLK_CE>, + <&ccu CLK_MBUS_CE>, <&rtc CLK_IOSC>; + clock-names = "bus", "mod", "ram", "trng"; + resets = <&ccu RST_BUS_CE>; + }; + syscon: syscon@3000000 { compatible = "allwinner,sun50i-h616-system-control"; reg = <0x03000000 0x1000>; @@ -156,6 +207,10 @@ ths_calibration: thermal-sensor-calibration@14 { reg = <0x14 0x8>; }; + + cpu_speed_grade: cpu-speed-grade@0 { + reg = <0x0 2>; + }; };
watchdog: watchdog@30090a0 { @@ -194,7 +249,7 @@ };
i2c0_pins: i2c0-pins { - pins = "PI6", "PI7"; + pins = "PI5", "PI6"; function = "i2c0"; };
@@ -298,6 +353,15 @@ #interrupt-cells = <3>; };
+ iommu: iommu@30f0000 { + compatible = "allwinner,sun50i-h616-iommu"; + reg = <0x030f0000 0x10000>; + interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_IOMMU>; + resets = <&ccu RST_BUS_IOMMU>; + #iommu-cells = <1>; + }; + mmc0: mmc@4020000 { compatible = "allwinner,sun50i-h616-mmc", "allwinner,sun50i-a100-mmc"; @@ -581,6 +645,17 @@ status = "disabled"; };
+ gpadc: adc@5070000 { + compatible = "allwinner,sun50i-h616-gpadc", + "allwinner,sun20i-d1-gpadc"; + reg = <0x05070000 0x400>; + clocks = <&ccu CLK_BUS_GPADC>; + resets = <&ccu RST_BUS_GPADC>; + interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + #io-channel-cells = <1>; + }; + ths: thermal-sensor@5070400 { compatible = "allwinner,sun50i-h616-ths"; reg = <0x05070400 0x400>; @@ -594,6 +669,16 @@ #thermal-sensor-cells = <1>; };
+ lradc: lradc@5070800 { + compatible = "allwinner,sun50i-h616-lradc", + "allwinner,sun50i-r329-lradc"; + reg = <0x05070800 0x400>; + interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_KEYADC>; + resets = <&ccu RST_BUS_KEYADC>; + status = "disabled"; + }; + usbotg: usb@5100000 { compatible = "allwinner,sun50i-h616-musb", "allwinner,sun8i-h3-musb"; @@ -775,6 +860,15 @@ #reset-cells = <1>; };
+ nmi_intc: interrupt-controller@7010320 { + compatible = "allwinner,sun50i-h616-nmi", + "allwinner,sun9i-a80-nmi"; + reg = <0x07010320 0xc>; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>; + }; + r_pio: pinctrl@7022000 { compatible = "allwinner,sun50i-h616-r-pinctrl"; reg = <0x07022000 0x400>; @@ -820,6 +914,8 @@ dmas = <&dma 48>, <&dma 48>; dma-names = "rx", "tx"; resets = <&r_ccu RST_R_APB2_I2C>; + pinctrl-names = "default"; + pinctrl-0 = <&r_i2c_pins>; status = "disabled"; #address-cells = <1>; #size-cells = <0>; diff --git a/include/dt-bindings/clock/sun50i-h616-ccu.h b/include/dt-bindings/clock/sun50i-h616-ccu.h index 6f8f01e676..ebb146ab7f 100644 --- a/include/dt-bindings/clock/sun50i-h616-ccu.h +++ b/include/dt-bindings/clock/sun50i-h616-ccu.h @@ -112,5 +112,6 @@ #define CLK_HDCP 126 #define CLK_BUS_HDCP 127 #define CLK_PLL_SYSTEM_32K 128 +#define CLK_BUS_GPADC 129
#endif /* _DT_BINDINGS_CLK_SUN50I_H616_H_ */ diff --git a/include/dt-bindings/reset/sun50i-h616-ccu.h b/include/dt-bindings/reset/sun50i-h616-ccu.h index 1bd8bb0a11..ed177c04af 100644 --- a/include/dt-bindings/reset/sun50i-h616-ccu.h +++ b/include/dt-bindings/reset/sun50i-h616-ccu.h @@ -66,5 +66,6 @@ #define RST_BUS_TVE0 57 #define RST_BUS_HDCP 58 #define RST_BUS_KEYADC 59 +#define RST_BUS_GPADC 60
#endif /* _DT_BINDINGS_RESET_SUN50I_H616_H_ */

From: Chris Morgan macromorgan@hotmail.com
The Anbernic RG35XX series of devices are based around an Allwinner H700 SoC with 1GB of RAM, 2 SD cards, and multiple input buttons.
This bootloader has been tested on the Anbernic RG35XX-2024 and RG35XX-H, but should be suitable for the entire lineup of H700 based devices.
A future series of updates will add board selection logic to identify and load the correct device tree automatically, and will switch to utilizing a mainline device tree.
Signed-off-by: Chris Morgan macromorgan@hotmail.com --- arch/arm/dts/Makefile | 3 +- .../dts/sun50i-h700-anbernic-rg35xx-2024.dts | 320 ++++++++++++++++++ board/sunxi/MAINTAINERS | 5 + configs/anbernic_rg35xx_h700_defconfig | 50 +++ 4 files changed, 377 insertions(+), 1 deletion(-) create mode 100644 arch/arm/dts/sun50i-h700-anbernic-rg35xx-2024.dts create mode 100644 configs/anbernic_rg35xx_h700_defconfig
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 3ae4110d60..886ab0312a 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -679,10 +679,11 @@ dtb-$(CONFIG_MACH_SUN50I_H6) += \ sun50i-h6-tanix-tx6-mini.dtb dtb-$(CONFIG_MACH_SUN50I_H616) += \ sun50i-h616-orangepi-zero2.dtb \ + sun50i-h616-x96-mate.dtb \ sun50i-h618-orangepi-zero2w.dtb \ sun50i-h618-orangepi-zero3.dtb \ sun50i-h618-transpeed-8k618-t.dtb \ - sun50i-h616-x96-mate.dtb + sun50i-h700-anbernic-rg35xx-2024.dtb dtb-$(CONFIG_MACH_SUN50I) += \ sun50i-a64-amarula-relic.dtb \ sun50i-a64-bananapi-m64.dtb \ diff --git a/arch/arm/dts/sun50i-h700-anbernic-rg35xx-2024.dts b/arch/arm/dts/sun50i-h700-anbernic-rg35xx-2024.dts new file mode 100644 index 0000000000..75206af164 --- /dev/null +++ b/arch/arm/dts/sun50i-h700-anbernic-rg35xx-2024.dts @@ -0,0 +1,320 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Copyright (C) 2024 Ryan Walklin ryan@testtoast.com. + */ + +/dts-v1/; + +#include "sun50i-h616.dtsi" +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/linux-event-codes.h> +#include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/leds/common.h> + +/ { + model = "Anbernic RG35XX 2024"; + chassis-type = "handset"; + compatible = "anbernic,rg35xx-2024", "allwinner,sun50i-h700"; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + gpio_keys_gamepad: gpio-keys-gamepad { + compatible = "gpio-keys"; + + button-a { + label = "Action-Pad A"; + gpios = <&pio 0 0 GPIO_ACTIVE_LOW>; /* PA0 */ + linux,input-type = <EV_KEY>; + linux,code = <BTN_EAST>; + }; + + button-b { + label = "Action-Pad B"; + gpios = <&pio 0 1 GPIO_ACTIVE_LOW>; /* PA1 */ + linux,input-type = <EV_KEY>; + linux,code = <BTN_SOUTH>; + }; + + button-down { + label = "D-Pad Down"; + gpios = <&pio 4 0 GPIO_ACTIVE_LOW>; /* PE0 */ + linux,input-type = <EV_KEY>; + linux,code = <BTN_DPAD_DOWN>; + }; + + button-l1 { + label = "Key L1"; + gpios = <&pio 0 10 GPIO_ACTIVE_LOW>; /* PA10 */ + linux,input-type = <EV_KEY>; + linux,code = <BTN_TL>; + }; + + button-l2 { + label = "Key L2"; + gpios = <&pio 0 11 GPIO_ACTIVE_LOW>; /* PA11 */ + linux,input-type = <EV_KEY>; + linux,code = <BTN_TL2>; + }; + + button-left { + label = "D-Pad left"; + gpios = <&pio 0 8 GPIO_ACTIVE_LOW>; /* PA8 */ + linux,input-type = <EV_KEY>; + linux,code = <BTN_DPAD_LEFT>; + }; + + button-menu { + label = "Key Menu"; + gpios = <&pio 4 3 GPIO_ACTIVE_LOW>; /* PE3 */ + linux,input-type = <EV_KEY>; + linux,code = <BTN_MODE>; + }; + + button-r1 { + label = "Key R1"; + gpios = <&pio 0 12 GPIO_ACTIVE_LOW>; /* PA12 */ + linux,input-type = <EV_KEY>; + linux,code = <BTN_TR>; + }; + + button-r2 { + label = "Key R2"; + gpios = <&pio 0 7 GPIO_ACTIVE_LOW>; /* PA7 */ + linux,input-type = <EV_KEY>; + linux,code = <BTN_TR2>; + }; + + button-right { + label = "D-Pad Right"; + gpios = <&pio 0 9 GPIO_ACTIVE_LOW>; /* PA9 */ + linux,input-type = <EV_KEY>; + linux,code = <BTN_DPAD_RIGHT>; + }; + + button-select { + label = "Key Select"; + gpios = <&pio 0 5 GPIO_ACTIVE_LOW>; /* PA5 */ + linux,input-type = <EV_KEY>; + linux,code = <BTN_SELECT>; + }; + button-start { + label = "Key Start"; + gpios = <&pio 0 4 GPIO_ACTIVE_LOW>; /* PA4 */ + linux,input-type = <EV_KEY>; + linux,code = <BTN_START>; + }; + + button-up { + label = "D-Pad Up"; + gpios = <&pio 0 6 GPIO_ACTIVE_LOW>; /* PA6 */ + linux,input-type = <EV_KEY>; + linux,code = <BTN_DPAD_UP>; + }; + + button-x { + label = "Action-Pad X"; + gpios = <&pio 0 3 GPIO_ACTIVE_LOW>; /* PA3 */ + linux,input-type = <EV_KEY>; + linux,code = <BTN_NORTH>; + }; + + button-y { + label = "Action Pad Y"; + gpios = <&pio 0 2 GPIO_ACTIVE_LOW>; /* PA2 */ + linux,input-type = <EV_KEY>; + linux,code = <BTN_WEST>; + }; + }; + + gpio-keys-volume { + compatible = "gpio-keys"; + autorepeat; + + button-vol-up { + label = "Key Volume Up"; + gpios = <&pio 4 1 GPIO_ACTIVE_LOW>; /* PE1 */ + linux,input-type = <EV_KEY>; + linux,code = <KEY_VOLUMEUP>; + }; + + button-vol-down { + label = "Key Volume Down"; + gpios = <&pio 4 2 GPIO_ACTIVE_LOW>; /* PE2 */ + linux,input-type = <EV_KEY>; + linux,code = <KEY_VOLUMEDOWN>; + }; + }; + + leds { + compatible = "gpio-leds"; + + led-0 { + function = LED_FUNCTION_POWER; + color = <LED_COLOR_ID_GREEN>; + gpios = <&pio 8 12 GPIO_ACTIVE_HIGH>; /* PI12 */ + default-state = "on"; + }; + }; + + reg_vcc5v: regulator-vcc5v { /* USB-C power input */ + compatible = "regulator-fixed"; + regulator-name = "vcc-5v"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; +}; + +&cpu0 { + cpu-supply = <®_dcdc1>; +}; + +&mmc0 { + vmmc-supply = <®_cldo3>; + disable-wp; + cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */ + bus-width = <4>; + status = "okay"; +}; + +&pio { + vcc-pa-supply = <®_cldo3>; + vcc-pc-supply = <®_cldo3>; + vcc-pe-supply = <®_cldo3>; + vcc-pf-supply = <®_cldo3>; + vcc-pg-supply = <®_aldo4>; + vcc-ph-supply = <®_cldo3>; + vcc-pi-supply = <®_cldo3>; +}; + +&r_i2c { + 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>; + + regulators { + reg_dcdc1: dcdc1 { + regulator-always-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1160000>; + regulator-name = "vdd-cpu"; + }; + + reg_dcdc2: dcdc2 { + regulator-always-on; + regulator-min-microvolt = <940000>; + regulator-max-microvolt = <940000>; + 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 { + /* 1.8v - unused */ + }; + + reg_aldo2: aldo2 { + /* 1.8v - unused */ + }; + + reg_aldo3: aldo3 { + /* 1.8v - unused */ + }; + + reg_aldo4: aldo4 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc-pg"; + }; + + reg_bldo1: bldo1 { + /* 1.8v - unused */ + }; + + reg_bldo2: bldo2 { + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc-pll"; + }; + + reg_bldo3: bldo3 { + /* 2.8v - unused */ + }; + + reg_bldo4: bldo4 { + /* 1.2v - unused */ + }; + + reg_cldo1: cldo1 { + /* 3.3v - audio codec - not yet implemented */ + }; + + reg_cldo2: cldo2 { + /* 3.3v - unused */ + }; + + reg_cldo3: cldo3 { + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-io"; + }; + + reg_cldo4: cldo4 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-wifi"; + }; + + reg_boost: boost { + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5200000>; + regulator-name = "boost"; + }; + + reg_cpusldo: cpusldo { + regulator-always-on; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1400000>; + regulator-name = "cpusldo"; + }; + }; + }; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_ph_pins>; + status = "okay"; +}; + +&usbotg { + dr_mode = "peripheral"; + status = "okay"; +}; + +&usbphy { + status = "okay"; +}; diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS index 4bcd9b9af7..e31c1b3a83 100644 --- a/board/sunxi/MAINTAINERS +++ b/board/sunxi/MAINTAINERS @@ -121,6 +121,11 @@ M: Paul Kocialkowski contact@paulk.fr S: Maintained F: configs/Ainol_AW1_defconfig
+ANBERNIC RG35XX-2024 +M: Chris Morgan macromorgan@hotmail.com +S: Maintained +F: configs/anbernic_rg35xx_h700_defconfig + AMARULA A64-RELIC M: Jagan Teki jagan@amarulasolutions.com S: Maintained diff --git a/configs/anbernic_rg35xx_h700_defconfig b/configs/anbernic_rg35xx_h700_defconfig new file mode 100644 index 0000000000..e8958aaf57 --- /dev/null +++ b/configs/anbernic_rg35xx_h700_defconfig @@ -0,0 +1,50 @@ +CONFIG_ARM=y +CONFIG_ARCH_SUNXI=y +CONFIG_DEFAULT_DEVICE_TREE="sun50i-h700-anbernic-rg35xx-2024" +CONFIG_SPL=y +CONFIG_DRAM_SUN50I_H616_DX_ODT=0x08080808 +CONFIG_DRAM_SUN50I_H616_DX_DRI=0x0e0e0e0e +CONFIG_DRAM_SUN50I_H616_CA_DRI=0x0e0e +CONFIG_DRAM_SUN50I_H616_ODT_EN=0x7887bbbb +CONFIG_DRAM_SUN50I_H616_TPR2=0x1 +CONFIG_DRAM_SUN50I_H616_TPR6=0x40808080 +CONFIG_DRAM_SUN50I_H616_TPR10=0x402f6633 +CONFIG_DRAM_SUN50I_H616_TPR11=0x1a1e1e1b +CONFIG_MACH_SUN50I_H616=y +CONFIG_RESERVE_ALLWINNER_BOOT0_HEADER=y +CONFIG_SUNXI_DRAM_H616_LPDDR4=y +CONFIG_DRAM_CLK=672 +CONFIG_R_I2C_ENABLE=y +CONFIG_DEFAULT_FDT_FILE="sun50i-h700-anbernic-rg35xx-2024.dtb" +CONFIG_LAST_STAGE_INIT=y +CONFIG_SPL_I2C=y +CONFIG_CMD_BDINFO_EXTRA=y +CONFIG_CMD_BOOTDEV=y +CONFIG_CMD_BOOTMETH=y +CONFIG_CMD_BOOTZ=y +CONFIG_BOOTM_OPENRTOS=y +CONFIG_BOOTM_OSE=y +CONFIG_CMD_ADTIMG=y +CONFIG_CMD_ADC=y +CONFIG_CMD_CLK=y +# CONFIG_CMD_LOADB is not set +# CONFIG_CMD_LOADS is not set +CONFIG_CMD_BKOPS_ENABLE=y +CONFIG_CMD_MMC_REG=y +CONFIG_CMD_MMC_SWRITE=y +CONFIG_CMD_SDRAM=y +CONFIG_CMD_PMIC=y +CONFIG_CMD_REGULATOR=y +# CONFIG_NET is not set +CONFIG_BUTTON=y +CONFIG_BUTTON_GPIO=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=940 +CONFIG_AXP_DCDC3_VOLT=1100 +CONFIG_REGEX=y +# CONFIG_EFI_LOADER is not set

Hi Chris,
On Fri, 2 Aug 2024 at 04:29, Chris Morgan macroalpha82@gmail.com wrote:
From: Chris Morgan macromorgan@hotmail.com
The Anbernic RG35XX series of devices are based around an Allwinner H700 SoC with 1GB of RAM, 2 SD cards, and multiple input buttons.
This bootloader has been tested on the Anbernic RG35XX-2024 and RG35XX-H, but should be suitable for the entire lineup of H700 based devices.
A future series of updates will add board selection logic to identify and load the correct device tree automatically, and will switch to utilizing a mainline device tree.
I can already see the upstream DT subtree containing DTS for this board as:
./dts/upstream/src/arm64/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts
Are there any major differences that won't allow you to switch to OF_UPSTREAM for this board?
-Sumit
Signed-off-by: Chris Morgan macromorgan@hotmail.com
arch/arm/dts/Makefile | 3 +- .../dts/sun50i-h700-anbernic-rg35xx-2024.dts | 320 ++++++++++++++++++ board/sunxi/MAINTAINERS | 5 + configs/anbernic_rg35xx_h700_defconfig | 50 +++ 4 files changed, 377 insertions(+), 1 deletion(-) create mode 100644 arch/arm/dts/sun50i-h700-anbernic-rg35xx-2024.dts create mode 100644 configs/anbernic_rg35xx_h700_defconfig
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 3ae4110d60..886ab0312a 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -679,10 +679,11 @@ dtb-$(CONFIG_MACH_SUN50I_H6) += \ sun50i-h6-tanix-tx6-mini.dtb dtb-$(CONFIG_MACH_SUN50I_H616) += \ sun50i-h616-orangepi-zero2.dtb \
sun50i-h616-x96-mate.dtb \ sun50i-h618-orangepi-zero2w.dtb \ sun50i-h618-orangepi-zero3.dtb \ sun50i-h618-transpeed-8k618-t.dtb \
sun50i-h616-x96-mate.dtb
sun50i-h700-anbernic-rg35xx-2024.dtb
dtb-$(CONFIG_MACH_SUN50I) += \ sun50i-a64-amarula-relic.dtb \ sun50i-a64-bananapi-m64.dtb \ diff --git a/arch/arm/dts/sun50i-h700-anbernic-rg35xx-2024.dts b/arch/arm/dts/sun50i-h700-anbernic-rg35xx-2024.dts new file mode 100644 index 0000000000..75206af164 --- /dev/null +++ b/arch/arm/dts/sun50i-h700-anbernic-rg35xx-2024.dts @@ -0,0 +1,320 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/*
- Copyright (C) 2024 Ryan Walklin ryan@testtoast.com.
- */
+/dts-v1/;
+#include "sun50i-h616.dtsi" +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/linux-event-codes.h> +#include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/leds/common.h>
+/ {
model = "Anbernic RG35XX 2024";
chassis-type = "handset";
compatible = "anbernic,rg35xx-2024", "allwinner,sun50i-h700";
aliases {
serial0 = &uart0;
};
chosen {
stdout-path = "serial0:115200n8";
};
gpio_keys_gamepad: gpio-keys-gamepad {
compatible = "gpio-keys";
button-a {
label = "Action-Pad A";
gpios = <&pio 0 0 GPIO_ACTIVE_LOW>; /* PA0 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_EAST>;
};
button-b {
label = "Action-Pad B";
gpios = <&pio 0 1 GPIO_ACTIVE_LOW>; /* PA1 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_SOUTH>;
};
button-down {
label = "D-Pad Down";
gpios = <&pio 4 0 GPIO_ACTIVE_LOW>; /* PE0 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_DPAD_DOWN>;
};
button-l1 {
label = "Key L1";
gpios = <&pio 0 10 GPIO_ACTIVE_LOW>; /* PA10 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_TL>;
};
button-l2 {
label = "Key L2";
gpios = <&pio 0 11 GPIO_ACTIVE_LOW>; /* PA11 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_TL2>;
};
button-left {
label = "D-Pad left";
gpios = <&pio 0 8 GPIO_ACTIVE_LOW>; /* PA8 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_DPAD_LEFT>;
};
button-menu {
label = "Key Menu";
gpios = <&pio 4 3 GPIO_ACTIVE_LOW>; /* PE3 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_MODE>;
};
button-r1 {
label = "Key R1";
gpios = <&pio 0 12 GPIO_ACTIVE_LOW>; /* PA12 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_TR>;
};
button-r2 {
label = "Key R2";
gpios = <&pio 0 7 GPIO_ACTIVE_LOW>; /* PA7 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_TR2>;
};
button-right {
label = "D-Pad Right";
gpios = <&pio 0 9 GPIO_ACTIVE_LOW>; /* PA9 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_DPAD_RIGHT>;
};
button-select {
label = "Key Select";
gpios = <&pio 0 5 GPIO_ACTIVE_LOW>; /* PA5 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_SELECT>;
};
button-start {
label = "Key Start";
gpios = <&pio 0 4 GPIO_ACTIVE_LOW>; /* PA4 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_START>;
};
button-up {
label = "D-Pad Up";
gpios = <&pio 0 6 GPIO_ACTIVE_LOW>; /* PA6 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_DPAD_UP>;
};
button-x {
label = "Action-Pad X";
gpios = <&pio 0 3 GPIO_ACTIVE_LOW>; /* PA3 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_NORTH>;
};
button-y {
label = "Action Pad Y";
gpios = <&pio 0 2 GPIO_ACTIVE_LOW>; /* PA2 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_WEST>;
};
};
gpio-keys-volume {
compatible = "gpio-keys";
autorepeat;
button-vol-up {
label = "Key Volume Up";
gpios = <&pio 4 1 GPIO_ACTIVE_LOW>; /* PE1 */
linux,input-type = <EV_KEY>;
linux,code = <KEY_VOLUMEUP>;
};
button-vol-down {
label = "Key Volume Down";
gpios = <&pio 4 2 GPIO_ACTIVE_LOW>; /* PE2 */
linux,input-type = <EV_KEY>;
linux,code = <KEY_VOLUMEDOWN>;
};
};
leds {
compatible = "gpio-leds";
led-0 {
function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_GREEN>;
gpios = <&pio 8 12 GPIO_ACTIVE_HIGH>; /* PI12 */
default-state = "on";
};
};
reg_vcc5v: regulator-vcc5v { /* USB-C power input */
compatible = "regulator-fixed";
regulator-name = "vcc-5v";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
};
+};
+&cpu0 {
cpu-supply = <®_dcdc1>;
+};
+&mmc0 {
vmmc-supply = <®_cldo3>;
disable-wp;
cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
bus-width = <4>;
status = "okay";
+};
+&pio {
vcc-pa-supply = <®_cldo3>;
vcc-pc-supply = <®_cldo3>;
vcc-pe-supply = <®_cldo3>;
vcc-pf-supply = <®_cldo3>;
vcc-pg-supply = <®_aldo4>;
vcc-ph-supply = <®_cldo3>;
vcc-pi-supply = <®_cldo3>;
+};
+&r_i2c {
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>;
regulators {
reg_dcdc1: dcdc1 {
regulator-always-on;
regulator-min-microvolt = <900000>;
regulator-max-microvolt = <1160000>;
regulator-name = "vdd-cpu";
};
reg_dcdc2: dcdc2 {
regulator-always-on;
regulator-min-microvolt = <940000>;
regulator-max-microvolt = <940000>;
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 {
/* 1.8v - unused */
};
reg_aldo2: aldo2 {
/* 1.8v - unused */
};
reg_aldo3: aldo3 {
/* 1.8v - unused */
};
reg_aldo4: aldo4 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-name = "vcc-pg";
};
reg_bldo1: bldo1 {
/* 1.8v - unused */
};
reg_bldo2: bldo2 {
regulator-always-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-name = "vcc-pll";
};
reg_bldo3: bldo3 {
/* 2.8v - unused */
};
reg_bldo4: bldo4 {
/* 1.2v - unused */
};
reg_cldo1: cldo1 {
/* 3.3v - audio codec - not yet implemented */
};
reg_cldo2: cldo2 {
/* 3.3v - unused */
};
reg_cldo3: cldo3 {
regulator-always-on;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-name = "vcc-io";
};
reg_cldo4: cldo4 {
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-name = "vcc-wifi";
};
reg_boost: boost {
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5200000>;
regulator-name = "boost";
};
reg_cpusldo: cpusldo {
regulator-always-on;
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <1400000>;
regulator-name = "cpusldo";
};
};
};
+};
+&uart0 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_ph_pins>;
status = "okay";
+};
+&usbotg {
dr_mode = "peripheral";
status = "okay";
+};
+&usbphy {
status = "okay";
+}; diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS index 4bcd9b9af7..e31c1b3a83 100644 --- a/board/sunxi/MAINTAINERS +++ b/board/sunxi/MAINTAINERS @@ -121,6 +121,11 @@ M: Paul Kocialkowski contact@paulk.fr S: Maintained F: configs/Ainol_AW1_defconfig
+ANBERNIC RG35XX-2024 +M: Chris Morgan macromorgan@hotmail.com +S: Maintained +F: configs/anbernic_rg35xx_h700_defconfig
AMARULA A64-RELIC M: Jagan Teki jagan@amarulasolutions.com S: Maintained diff --git a/configs/anbernic_rg35xx_h700_defconfig b/configs/anbernic_rg35xx_h700_defconfig new file mode 100644 index 0000000000..e8958aaf57 --- /dev/null +++ b/configs/anbernic_rg35xx_h700_defconfig @@ -0,0 +1,50 @@ +CONFIG_ARM=y +CONFIG_ARCH_SUNXI=y +CONFIG_DEFAULT_DEVICE_TREE="sun50i-h700-anbernic-rg35xx-2024" +CONFIG_SPL=y +CONFIG_DRAM_SUN50I_H616_DX_ODT=0x08080808 +CONFIG_DRAM_SUN50I_H616_DX_DRI=0x0e0e0e0e +CONFIG_DRAM_SUN50I_H616_CA_DRI=0x0e0e +CONFIG_DRAM_SUN50I_H616_ODT_EN=0x7887bbbb +CONFIG_DRAM_SUN50I_H616_TPR2=0x1 +CONFIG_DRAM_SUN50I_H616_TPR6=0x40808080 +CONFIG_DRAM_SUN50I_H616_TPR10=0x402f6633 +CONFIG_DRAM_SUN50I_H616_TPR11=0x1a1e1e1b +CONFIG_MACH_SUN50I_H616=y +CONFIG_RESERVE_ALLWINNER_BOOT0_HEADER=y +CONFIG_SUNXI_DRAM_H616_LPDDR4=y +CONFIG_DRAM_CLK=672 +CONFIG_R_I2C_ENABLE=y +CONFIG_DEFAULT_FDT_FILE="sun50i-h700-anbernic-rg35xx-2024.dtb" +CONFIG_LAST_STAGE_INIT=y +CONFIG_SPL_I2C=y +CONFIG_CMD_BDINFO_EXTRA=y +CONFIG_CMD_BOOTDEV=y +CONFIG_CMD_BOOTMETH=y +CONFIG_CMD_BOOTZ=y +CONFIG_BOOTM_OPENRTOS=y +CONFIG_BOOTM_OSE=y +CONFIG_CMD_ADTIMG=y +CONFIG_CMD_ADC=y +CONFIG_CMD_CLK=y +# CONFIG_CMD_LOADB is not set +# CONFIG_CMD_LOADS is not set +CONFIG_CMD_BKOPS_ENABLE=y +CONFIG_CMD_MMC_REG=y +CONFIG_CMD_MMC_SWRITE=y +CONFIG_CMD_SDRAM=y +CONFIG_CMD_PMIC=y +CONFIG_CMD_REGULATOR=y +# CONFIG_NET is not set +CONFIG_BUTTON=y +CONFIG_BUTTON_GPIO=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=940 +CONFIG_AXP_DCDC3_VOLT=1100 +CONFIG_REGEX=y
+# CONFIG_EFI_LOADER is not set
2.34.1

On Fri, 2 Aug 2024 12:24:56 +0530 Sumit Garg sumit.garg@linaro.org wrote:
Hi Sumit,
Hi Chris,
On Fri, 2 Aug 2024 at 04:29, Chris Morgan macroalpha82@gmail.com wrote:
From: Chris Morgan macromorgan@hotmail.com
The Anbernic RG35XX series of devices are based around an Allwinner H700 SoC with 1GB of RAM, 2 SD cards, and multiple input buttons.
This bootloader has been tested on the Anbernic RG35XX-2024 and RG35XX-H, but should be suitable for the entire lineup of H700 based devices.
A future series of updates will add board selection logic to identify and load the correct device tree automatically, and will switch to utilizing a mainline device tree.
I can already see the upstream DT subtree containing DTS for this board as:
./dts/upstream/src/arm64/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts
Are there any major differences that won't allow you to switch to OF_UPSTREAM for this board?
In this case there are no differences between the DT in the kernel repo and what we put in U-Boot. The main reason for me holding back the switch to OF_UPSTREAM for the H616 was indeed the rather slow update cadence, which somewhat slows down upstreaming of new boards like this. Doing this separately gives us a bit more control and freedom to take DT patches early, for instance when they appear in some Linux -rc1, or even before that (linux-next). I explained my position in more detail here: https://lore.kernel.org/u-boot/191A0F66-E2AE-4D1B-ACBE-E411E135BB61@arm.com/
I think Tom partly convinced me that regular updates together with cherry-picking should solve most of those problems, so I will probably do the switch for the next cycle.
Cheers, Andre
Signed-off-by: Chris Morgan macromorgan@hotmail.com
arch/arm/dts/Makefile | 3 +- .../dts/sun50i-h700-anbernic-rg35xx-2024.dts | 320 ++++++++++++++++++ board/sunxi/MAINTAINERS | 5 + configs/anbernic_rg35xx_h700_defconfig | 50 +++ 4 files changed, 377 insertions(+), 1 deletion(-) create mode 100644 arch/arm/dts/sun50i-h700-anbernic-rg35xx-2024.dts create mode 100644 configs/anbernic_rg35xx_h700_defconfig
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 3ae4110d60..886ab0312a 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -679,10 +679,11 @@ dtb-$(CONFIG_MACH_SUN50I_H6) += \ sun50i-h6-tanix-tx6-mini.dtb dtb-$(CONFIG_MACH_SUN50I_H616) += \ sun50i-h616-orangepi-zero2.dtb \
sun50i-h616-x96-mate.dtb \ sun50i-h618-orangepi-zero2w.dtb \ sun50i-h618-orangepi-zero3.dtb \ sun50i-h618-transpeed-8k618-t.dtb \
sun50i-h616-x96-mate.dtb
sun50i-h700-anbernic-rg35xx-2024.dtb
dtb-$(CONFIG_MACH_SUN50I) += \ sun50i-a64-amarula-relic.dtb \ sun50i-a64-bananapi-m64.dtb \ diff --git a/arch/arm/dts/sun50i-h700-anbernic-rg35xx-2024.dts b/arch/arm/dts/sun50i-h700-anbernic-rg35xx-2024.dts new file mode 100644 index 0000000000..75206af164 --- /dev/null +++ b/arch/arm/dts/sun50i-h700-anbernic-rg35xx-2024.dts @@ -0,0 +1,320 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/*
- Copyright (C) 2024 Ryan Walklin ryan@testtoast.com.
- */
+/dts-v1/;
+#include "sun50i-h616.dtsi" +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/linux-event-codes.h> +#include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/leds/common.h>
+/ {
model = "Anbernic RG35XX 2024";
chassis-type = "handset";
compatible = "anbernic,rg35xx-2024", "allwinner,sun50i-h700";
aliases {
serial0 = &uart0;
};
chosen {
stdout-path = "serial0:115200n8";
};
gpio_keys_gamepad: gpio-keys-gamepad {
compatible = "gpio-keys";
button-a {
label = "Action-Pad A";
gpios = <&pio 0 0 GPIO_ACTIVE_LOW>; /* PA0 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_EAST>;
};
button-b {
label = "Action-Pad B";
gpios = <&pio 0 1 GPIO_ACTIVE_LOW>; /* PA1 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_SOUTH>;
};
button-down {
label = "D-Pad Down";
gpios = <&pio 4 0 GPIO_ACTIVE_LOW>; /* PE0 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_DPAD_DOWN>;
};
button-l1 {
label = "Key L1";
gpios = <&pio 0 10 GPIO_ACTIVE_LOW>; /* PA10 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_TL>;
};
button-l2 {
label = "Key L2";
gpios = <&pio 0 11 GPIO_ACTIVE_LOW>; /* PA11 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_TL2>;
};
button-left {
label = "D-Pad left";
gpios = <&pio 0 8 GPIO_ACTIVE_LOW>; /* PA8 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_DPAD_LEFT>;
};
button-menu {
label = "Key Menu";
gpios = <&pio 4 3 GPIO_ACTIVE_LOW>; /* PE3 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_MODE>;
};
button-r1 {
label = "Key R1";
gpios = <&pio 0 12 GPIO_ACTIVE_LOW>; /* PA12 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_TR>;
};
button-r2 {
label = "Key R2";
gpios = <&pio 0 7 GPIO_ACTIVE_LOW>; /* PA7 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_TR2>;
};
button-right {
label = "D-Pad Right";
gpios = <&pio 0 9 GPIO_ACTIVE_LOW>; /* PA9 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_DPAD_RIGHT>;
};
button-select {
label = "Key Select";
gpios = <&pio 0 5 GPIO_ACTIVE_LOW>; /* PA5 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_SELECT>;
};
button-start {
label = "Key Start";
gpios = <&pio 0 4 GPIO_ACTIVE_LOW>; /* PA4 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_START>;
};
button-up {
label = "D-Pad Up";
gpios = <&pio 0 6 GPIO_ACTIVE_LOW>; /* PA6 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_DPAD_UP>;
};
button-x {
label = "Action-Pad X";
gpios = <&pio 0 3 GPIO_ACTIVE_LOW>; /* PA3 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_NORTH>;
};
button-y {
label = "Action Pad Y";
gpios = <&pio 0 2 GPIO_ACTIVE_LOW>; /* PA2 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_WEST>;
};
};
gpio-keys-volume {
compatible = "gpio-keys";
autorepeat;
button-vol-up {
label = "Key Volume Up";
gpios = <&pio 4 1 GPIO_ACTIVE_LOW>; /* PE1 */
linux,input-type = <EV_KEY>;
linux,code = <KEY_VOLUMEUP>;
};
button-vol-down {
label = "Key Volume Down";
gpios = <&pio 4 2 GPIO_ACTIVE_LOW>; /* PE2 */
linux,input-type = <EV_KEY>;
linux,code = <KEY_VOLUMEDOWN>;
};
};
leds {
compatible = "gpio-leds";
led-0 {
function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_GREEN>;
gpios = <&pio 8 12 GPIO_ACTIVE_HIGH>; /* PI12 */
default-state = "on";
};
};
reg_vcc5v: regulator-vcc5v { /* USB-C power input */
compatible = "regulator-fixed";
regulator-name = "vcc-5v";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
};
+};
+&cpu0 {
cpu-supply = <®_dcdc1>;
+};
+&mmc0 {
vmmc-supply = <®_cldo3>;
disable-wp;
cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
bus-width = <4>;
status = "okay";
+};
+&pio {
vcc-pa-supply = <®_cldo3>;
vcc-pc-supply = <®_cldo3>;
vcc-pe-supply = <®_cldo3>;
vcc-pf-supply = <®_cldo3>;
vcc-pg-supply = <®_aldo4>;
vcc-ph-supply = <®_cldo3>;
vcc-pi-supply = <®_cldo3>;
+};
+&r_i2c {
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>;
regulators {
reg_dcdc1: dcdc1 {
regulator-always-on;
regulator-min-microvolt = <900000>;
regulator-max-microvolt = <1160000>;
regulator-name = "vdd-cpu";
};
reg_dcdc2: dcdc2 {
regulator-always-on;
regulator-min-microvolt = <940000>;
regulator-max-microvolt = <940000>;
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 {
/* 1.8v - unused */
};
reg_aldo2: aldo2 {
/* 1.8v - unused */
};
reg_aldo3: aldo3 {
/* 1.8v - unused */
};
reg_aldo4: aldo4 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-name = "vcc-pg";
};
reg_bldo1: bldo1 {
/* 1.8v - unused */
};
reg_bldo2: bldo2 {
regulator-always-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-name = "vcc-pll";
};
reg_bldo3: bldo3 {
/* 2.8v - unused */
};
reg_bldo4: bldo4 {
/* 1.2v - unused */
};
reg_cldo1: cldo1 {
/* 3.3v - audio codec - not yet implemented */
};
reg_cldo2: cldo2 {
/* 3.3v - unused */
};
reg_cldo3: cldo3 {
regulator-always-on;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-name = "vcc-io";
};
reg_cldo4: cldo4 {
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-name = "vcc-wifi";
};
reg_boost: boost {
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5200000>;
regulator-name = "boost";
};
reg_cpusldo: cpusldo {
regulator-always-on;
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <1400000>;
regulator-name = "cpusldo";
};
};
};
+};
+&uart0 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_ph_pins>;
status = "okay";
+};
+&usbotg {
dr_mode = "peripheral";
status = "okay";
+};
+&usbphy {
status = "okay";
+}; diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS index 4bcd9b9af7..e31c1b3a83 100644 --- a/board/sunxi/MAINTAINERS +++ b/board/sunxi/MAINTAINERS @@ -121,6 +121,11 @@ M: Paul Kocialkowski contact@paulk.fr S: Maintained F: configs/Ainol_AW1_defconfig
+ANBERNIC RG35XX-2024 +M: Chris Morgan macromorgan@hotmail.com +S: Maintained +F: configs/anbernic_rg35xx_h700_defconfig
AMARULA A64-RELIC M: Jagan Teki jagan@amarulasolutions.com S: Maintained diff --git a/configs/anbernic_rg35xx_h700_defconfig b/configs/anbernic_rg35xx_h700_defconfig new file mode 100644 index 0000000000..e8958aaf57 --- /dev/null +++ b/configs/anbernic_rg35xx_h700_defconfig @@ -0,0 +1,50 @@ +CONFIG_ARM=y +CONFIG_ARCH_SUNXI=y +CONFIG_DEFAULT_DEVICE_TREE="sun50i-h700-anbernic-rg35xx-2024" +CONFIG_SPL=y +CONFIG_DRAM_SUN50I_H616_DX_ODT=0x08080808 +CONFIG_DRAM_SUN50I_H616_DX_DRI=0x0e0e0e0e +CONFIG_DRAM_SUN50I_H616_CA_DRI=0x0e0e +CONFIG_DRAM_SUN50I_H616_ODT_EN=0x7887bbbb +CONFIG_DRAM_SUN50I_H616_TPR2=0x1 +CONFIG_DRAM_SUN50I_H616_TPR6=0x40808080 +CONFIG_DRAM_SUN50I_H616_TPR10=0x402f6633 +CONFIG_DRAM_SUN50I_H616_TPR11=0x1a1e1e1b +CONFIG_MACH_SUN50I_H616=y +CONFIG_RESERVE_ALLWINNER_BOOT0_HEADER=y +CONFIG_SUNXI_DRAM_H616_LPDDR4=y +CONFIG_DRAM_CLK=672 +CONFIG_R_I2C_ENABLE=y +CONFIG_DEFAULT_FDT_FILE="sun50i-h700-anbernic-rg35xx-2024.dtb" +CONFIG_LAST_STAGE_INIT=y +CONFIG_SPL_I2C=y +CONFIG_CMD_BDINFO_EXTRA=y +CONFIG_CMD_BOOTDEV=y +CONFIG_CMD_BOOTMETH=y +CONFIG_CMD_BOOTZ=y +CONFIG_BOOTM_OPENRTOS=y +CONFIG_BOOTM_OSE=y +CONFIG_CMD_ADTIMG=y +CONFIG_CMD_ADC=y +CONFIG_CMD_CLK=y +# CONFIG_CMD_LOADB is not set +# CONFIG_CMD_LOADS is not set +CONFIG_CMD_BKOPS_ENABLE=y +CONFIG_CMD_MMC_REG=y +CONFIG_CMD_MMC_SWRITE=y +CONFIG_CMD_SDRAM=y +CONFIG_CMD_PMIC=y +CONFIG_CMD_REGULATOR=y +# CONFIG_NET is not set +CONFIG_BUTTON=y +CONFIG_BUTTON_GPIO=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=940 +CONFIG_AXP_DCDC3_VOLT=1100 +CONFIG_REGEX=y
+# CONFIG_EFI_LOADER is not set
2.34.1

Hi Andre,
On Fri, 2 Aug 2024 at 15:27, Andre Przywara andre.przywara@arm.com wrote:
On Fri, 2 Aug 2024 12:24:56 +0530 Sumit Garg sumit.garg@linaro.org wrote:
Hi Sumit,
Hi Chris,
On Fri, 2 Aug 2024 at 04:29, Chris Morgan macroalpha82@gmail.com wrote:
From: Chris Morgan macromorgan@hotmail.com
The Anbernic RG35XX series of devices are based around an Allwinner H700 SoC with 1GB of RAM, 2 SD cards, and multiple input buttons.
This bootloader has been tested on the Anbernic RG35XX-2024 and RG35XX-H, but should be suitable for the entire lineup of H700 based devices.
A future series of updates will add board selection logic to identify and load the correct device tree automatically, and will switch to utilizing a mainline device tree.
I can already see the upstream DT subtree containing DTS for this board as:
./dts/upstream/src/arm64/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts
Are there any major differences that won't allow you to switch to OF_UPSTREAM for this board?
In this case there are no differences between the DT in the kernel repo and what we put in U-Boot. The main reason for me holding back the switch to OF_UPSTREAM for the H616 was indeed the rather slow update cadence, which somewhat slows down upstreaming of new boards like this. Doing this separately gives us a bit more control and freedom to take DT patches early, for instance when they appear in some Linux -rc1, or even before that (linux-next). I explained my position in more detail here: https://lore.kernel.org/u-boot/191A0F66-E2AE-4D1B-ACBE-E411E135BB61@arm.com/
I can see the reasoning, thanks.
I think Tom partly convinced me that regular updates together with cherry-picking should solve most of those problems, so I will probably do the switch for the next cycle.
Glad to hear that. Cherry-picking has been working really well for Rockchip platforms [1] [2] [3] as the changes appear in Linux -rc1. Also, it pretty much avoids maintainers to review the DT changes unless there are some bits added via *-u-boot.dtsi.
[1] https://patchwork.ozlabs.org/project/uboot/list/?series=417233 [2] https://patchwork.ozlabs.org/project/uboot/list/?series=417377 [3] https://patchwork.ozlabs.org/project/uboot/list/?series=417353
-Sumit

On Fri, Aug 02, 2024 at 04:08:39PM +0530, Sumit Garg wrote:
Hi Andre,
On Fri, 2 Aug 2024 at 15:27, Andre Przywara andre.przywara@arm.com wrote:
On Fri, 2 Aug 2024 12:24:56 +0530 Sumit Garg sumit.garg@linaro.org wrote:
Hi Sumit,
Hi Chris,
On Fri, 2 Aug 2024 at 04:29, Chris Morgan macroalpha82@gmail.com wrote:
From: Chris Morgan macromorgan@hotmail.com
The Anbernic RG35XX series of devices are based around an Allwinner H700 SoC with 1GB of RAM, 2 SD cards, and multiple input buttons.
This bootloader has been tested on the Anbernic RG35XX-2024 and RG35XX-H, but should be suitable for the entire lineup of H700 based devices.
A future series of updates will add board selection logic to identify and load the correct device tree automatically, and will switch to utilizing a mainline device tree.
I can already see the upstream DT subtree containing DTS for this board as:
./dts/upstream/src/arm64/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts
Are there any major differences that won't allow you to switch to OF_UPSTREAM for this board?
In this case there are no differences between the DT in the kernel repo and what we put in U-Boot. The main reason for me holding back the switch to OF_UPSTREAM for the H616 was indeed the rather slow update cadence, which somewhat slows down upstreaming of new boards like this. Doing this separately gives us a bit more control and freedom to take DT patches early, for instance when they appear in some Linux -rc1, or even before that (linux-next). I explained my position in more detail here: https://lore.kernel.org/u-boot/191A0F66-E2AE-4D1B-ACBE-E411E135BB61@arm.com/
I can see the reasoning, thanks.
I think Tom partly convinced me that regular updates together with cherry-picking should solve most of those problems, so I will probably do the switch for the next cycle.
Glad to hear that. Cherry-picking has been working really well for Rockchip platforms [1] [2] [3] as the changes appear in Linux -rc1. Also, it pretty much avoids maintainers to review the DT changes unless there are some bits added via *-u-boot.dtsi.
[1] https://patchwork.ozlabs.org/project/uboot/list/?series=417233 [2] https://patchwork.ozlabs.org/project/uboot/list/?series=417377 [3] https://patchwork.ozlabs.org/project/uboot/list/?series=417353
-Sumit
The specific differences between this and the upstream tree is that the upstream tree is missing the switch from rsb to i2c for the PMIC. That said, if we can cherry pick the change (it was just accepted and should end up in 6.12) that would work and I can start from the get-go with an upstream tree. There may be other differences, but they are ultimately superficial for U-Boot. I'll still make this for the RK35XX-2024 only for now, because I need to finish some stuff in the detection logic.
Thank you. Chris

On 02.08.2024 01:55, Chris Morgan wrote:
From: Chris Morgan macromorgan@hotmail.com
The Anbernic RG35XX series of devices are based around an Allwinner H700 SoC with 1GB of RAM, 2 SD cards, and multiple input buttons.
This bootloader has been tested on the Anbernic RG35XX-2024 and RG35XX-H, but should be suitable for the entire lineup of H700 based devices.
A future series of updates will add board selection logic to identify and load the correct device tree automatically, and will switch to utilizing a mainline device tree.
Signed-off-by: Chris Morgan macromorgan@hotmail.com
arch/arm/dts/Makefile | 3 +- .../dts/sun50i-h700-anbernic-rg35xx-2024.dts | 320 ++++++++++++++++++ board/sunxi/MAINTAINERS | 5 + configs/anbernic_rg35xx_h700_defconfig | 50 +++ 4 files changed, 377 insertions(+), 1 deletion(-) create mode 100644 arch/arm/dts/sun50i-h700-anbernic-rg35xx-2024.dts create mode 100644 configs/anbernic_rg35xx_h700_defconfig
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 3ae4110d60..886ab0312a 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -679,10 +679,11 @@ dtb-$(CONFIG_MACH_SUN50I_H6) += \ sun50i-h6-tanix-tx6-mini.dtb dtb-$(CONFIG_MACH_SUN50I_H616) += \ sun50i-h616-orangepi-zero2.dtb \
- sun50i-h616-x96-mate.dtb \ sun50i-h618-orangepi-zero2w.dtb \ sun50i-h618-orangepi-zero3.dtb \ sun50i-h618-transpeed-8k618-t.dtb \
- sun50i-h616-x96-mate.dtb
- sun50i-h700-anbernic-rg35xx-2024.dtb dtb-$(CONFIG_MACH_SUN50I) += \ sun50i-a64-amarula-relic.dtb \ sun50i-a64-bananapi-m64.dtb \
diff --git a/arch/arm/dts/sun50i-h700-anbernic-rg35xx-2024.dts b/arch/arm/dts/sun50i-h700-anbernic-rg35xx-2024.dts new file mode 100644 index 0000000000..75206af164 --- /dev/null +++ b/arch/arm/dts/sun50i-h700-anbernic-rg35xx-2024.dts @@ -0,0 +1,320 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/*
- Copyright (C) 2024 Ryan Walklin ryan@testtoast.com.
- */
+/dts-v1/;
+#include "sun50i-h616.dtsi" +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/linux-event-codes.h> +#include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/leds/common.h>
+/ {
- model = "Anbernic RG35XX 2024";
- chassis-type = "handset";
- compatible = "anbernic,rg35xx-2024", "allwinner,sun50i-h700";
- aliases {
serial0 = &uart0;
- };
- chosen {
stdout-path = "serial0:115200n8";
- };
- gpio_keys_gamepad: gpio-keys-gamepad {
compatible = "gpio-keys";
button-a {
label = "Action-Pad A";
gpios = <&pio 0 0 GPIO_ACTIVE_LOW>; /* PA0 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_EAST>;
};
button-b {
label = "Action-Pad B";
gpios = <&pio 0 1 GPIO_ACTIVE_LOW>; /* PA1 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_SOUTH>;
};
button-down {
label = "D-Pad Down";
gpios = <&pio 4 0 GPIO_ACTIVE_LOW>; /* PE0 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_DPAD_DOWN>;
};
button-l1 {
label = "Key L1";
gpios = <&pio 0 10 GPIO_ACTIVE_LOW>; /* PA10 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_TL>;
};
button-l2 {
label = "Key L2";
gpios = <&pio 0 11 GPIO_ACTIVE_LOW>; /* PA11 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_TL2>;
};
button-left {
label = "D-Pad left";
gpios = <&pio 0 8 GPIO_ACTIVE_LOW>; /* PA8 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_DPAD_LEFT>;
};
button-menu {
label = "Key Menu";
gpios = <&pio 4 3 GPIO_ACTIVE_LOW>; /* PE3 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_MODE>;
};
button-r1 {
label = "Key R1";
gpios = <&pio 0 12 GPIO_ACTIVE_LOW>; /* PA12 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_TR>;
};
button-r2 {
label = "Key R2";
gpios = <&pio 0 7 GPIO_ACTIVE_LOW>; /* PA7 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_TR2>;
};
button-right {
label = "D-Pad Right";
gpios = <&pio 0 9 GPIO_ACTIVE_LOW>; /* PA9 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_DPAD_RIGHT>;
};
button-select {
label = "Key Select";
gpios = <&pio 0 5 GPIO_ACTIVE_LOW>; /* PA5 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_SELECT>;
};
button-start {
label = "Key Start";
gpios = <&pio 0 4 GPIO_ACTIVE_LOW>; /* PA4 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_START>;
};
button-up {
label = "D-Pad Up";
gpios = <&pio 0 6 GPIO_ACTIVE_LOW>; /* PA6 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_DPAD_UP>;
};
button-x {
label = "Action-Pad X";
gpios = <&pio 0 3 GPIO_ACTIVE_LOW>; /* PA3 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_NORTH>;
};
button-y {
label = "Action Pad Y";
gpios = <&pio 0 2 GPIO_ACTIVE_LOW>; /* PA2 */
linux,input-type = <EV_KEY>;
linux,code = <BTN_WEST>;
};
- };
- gpio-keys-volume {
compatible = "gpio-keys";
autorepeat;
button-vol-up {
label = "Key Volume Up";
gpios = <&pio 4 1 GPIO_ACTIVE_LOW>; /* PE1 */
linux,input-type = <EV_KEY>;
linux,code = <KEY_VOLUMEUP>;
};
button-vol-down {
label = "Key Volume Down";
gpios = <&pio 4 2 GPIO_ACTIVE_LOW>; /* PE2 */
linux,input-type = <EV_KEY>;
linux,code = <KEY_VOLUMEDOWN>;
};
- };
- leds {
compatible = "gpio-leds";
led-0 {
function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_GREEN>;
gpios = <&pio 8 12 GPIO_ACTIVE_HIGH>; /* PI12 */
default-state = "on";
};
- };
- reg_vcc5v: regulator-vcc5v { /* USB-C power input */
compatible = "regulator-fixed";
regulator-name = "vcc-5v";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
- };
+};
+&cpu0 {
- cpu-supply = <®_dcdc1>;
+};
+&mmc0 {
- vmmc-supply = <®_cldo3>;
- disable-wp;
- cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
- bus-width = <4>;
- status = "okay";
+};
+&pio {
- vcc-pa-supply = <®_cldo3>;
- vcc-pc-supply = <®_cldo3>;
- vcc-pe-supply = <®_cldo3>;
- vcc-pf-supply = <®_cldo3>;
- vcc-pg-supply = <®_aldo4>;
- vcc-ph-supply = <®_cldo3>;
- vcc-pi-supply = <®_cldo3>;
+};
+&r_i2c {
- 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>;
regulators {
reg_dcdc1: dcdc1 {
regulator-always-on;
regulator-min-microvolt = <900000>;
regulator-max-microvolt = <1160000>;
regulator-name = "vdd-cpu";
};
reg_dcdc2: dcdc2 {
regulator-always-on;
regulator-min-microvolt = <940000>;
regulator-max-microvolt = <940000>;
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 {
/* 1.8v - unused */
};
reg_aldo2: aldo2 {
/* 1.8v - unused */
};
reg_aldo3: aldo3 {
/* 1.8v - unused */
};
reg_aldo4: aldo4 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-name = "vcc-pg";
};
reg_bldo1: bldo1 {
/* 1.8v - unused */
};
reg_bldo2: bldo2 {
regulator-always-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-name = "vcc-pll";
};
reg_bldo3: bldo3 {
/* 2.8v - unused */
};
reg_bldo4: bldo4 {
/* 1.2v - unused */
};
reg_cldo1: cldo1 {
/* 3.3v - audio codec - not yet implemented */
};
reg_cldo2: cldo2 {
/* 3.3v - unused */
};
reg_cldo3: cldo3 {
regulator-always-on;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-name = "vcc-io";
};
reg_cldo4: cldo4 {
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-name = "vcc-wifi";
};
reg_boost: boost {
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5200000>;
regulator-name = "boost";
};
reg_cpusldo: cpusldo {
regulator-always-on;
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <1400000>;
regulator-name = "cpusldo";
};
};
- };
+};
+&uart0 {
- pinctrl-names = "default";
- pinctrl-0 = <&uart0_ph_pins>;
- status = "okay";
+};
+&usbotg {
- dr_mode = "peripheral";
- status = "okay";
+};
+&usbphy {
- status = "okay";
+}; diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS index 4bcd9b9af7..e31c1b3a83 100644 --- a/board/sunxi/MAINTAINERS +++ b/board/sunxi/MAINTAINERS @@ -121,6 +121,11 @@ M: Paul Kocialkowski contact@paulk.fr S: Maintained F: configs/Ainol_AW1_defconfig
+ANBERNIC RG35XX-2024 +M: Chris Morgan macromorgan@hotmail.com +S: Maintained +F: configs/anbernic_rg35xx_h700_defconfig
- AMARULA A64-RELIC M: Jagan Teki jagan@amarulasolutions.com S: Maintained
diff --git a/configs/anbernic_rg35xx_h700_defconfig b/configs/anbernic_rg35xx_h700_defconfig new file mode 100644 index 0000000000..e8958aaf57 --- /dev/null +++ b/configs/anbernic_rg35xx_h700_defconfig @@ -0,0 +1,50 @@ +CONFIG_ARM=y +CONFIG_ARCH_SUNXI=y +CONFIG_DEFAULT_DEVICE_TREE="sun50i-h700-anbernic-rg35xx-2024" +CONFIG_SPL=y +CONFIG_DRAM_SUN50I_H616_DX_ODT=0x08080808 +CONFIG_DRAM_SUN50I_H616_DX_DRI=0x0e0e0e0e +CONFIG_DRAM_SUN50I_H616_CA_DRI=0x0e0e +CONFIG_DRAM_SUN50I_H616_ODT_EN=0x7887bbbb +CONFIG_DRAM_SUN50I_H616_TPR2=0x1 +CONFIG_DRAM_SUN50I_H616_TPR6=0x40808080 +CONFIG_DRAM_SUN50I_H616_TPR10=0x402f6633 +CONFIG_DRAM_SUN50I_H616_TPR11=0x1a1e1e1b
If your "Memory Dumps from Factory 35XXH (Allwinner H700) " from gist correct,
TPR12 parameter should be here.
+CONFIG_MACH_SUN50I_H616=y +CONFIG_RESERVE_ALLWINNER_BOOT0_HEADER=y +CONFIG_SUNXI_DRAM_H616_LPDDR4=y +CONFIG_DRAM_CLK=672 +CONFIG_R_I2C_ENABLE=y +CONFIG_DEFAULT_FDT_FILE="sun50i-h700-anbernic-rg35xx-2024.dtb" +CONFIG_LAST_STAGE_INIT=y +CONFIG_SPL_I2C=y +CONFIG_CMD_BDINFO_EXTRA=y +CONFIG_CMD_BOOTDEV=y +CONFIG_CMD_BOOTMETH=y +CONFIG_CMD_BOOTZ=y +CONFIG_BOOTM_OPENRTOS=y +CONFIG_BOOTM_OSE=y +CONFIG_CMD_ADTIMG=y +CONFIG_CMD_ADC=y +CONFIG_CMD_CLK=y +# CONFIG_CMD_LOADB is not set +# CONFIG_CMD_LOADS is not set +CONFIG_CMD_BKOPS_ENABLE=y +CONFIG_CMD_MMC_REG=y +CONFIG_CMD_MMC_SWRITE=y +CONFIG_CMD_SDRAM=y +CONFIG_CMD_PMIC=y +CONFIG_CMD_REGULATOR=y +# CONFIG_NET is not set +CONFIG_BUTTON=y +CONFIG_BUTTON_GPIO=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=940 +CONFIG_AXP_DCDC3_VOLT=1100 +CONFIG_REGEX=y +# CONFIG_EFI_LOADER is not set
participants (5)
-
Andre Przywara
-
Chris Morgan
-
Chris Morgan
-
Mikhail Kalashnikov
-
Sumit Garg