summaryrefslogtreecommitdiff
path: root/arch/arm/include
diff options
context:
space:
mode:
authorFerass El Hafidi <[email protected]>2025-11-26 12:17:07 +0000
committerNeil Armstrong <[email protected]>2025-12-11 11:44:41 +0100
commit17d80a3b326ea94cab687236cfeac5fc7c2bca2e (patch)
treea19b425040dace9e85be97d8852fac01ef0b5b1c /arch/arm/include
parentf39f6eeaa8c19053405788479b61a1e3b17ec150 (diff)
arm: meson: spl: add support for SPL DRAM init
Supports both GXBB and GXL SoCs. Reviewed-by: Neil Armstrong <[email protected]> Signed-off-by: Ferass El Hafidi <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Neil Armstrong <[email protected]>
Diffstat (limited to 'arch/arm/include')
-rw-r--r--arch/arm/include/asm/arch-meson/dram-gx.h341
-rw-r--r--arch/arm/include/asm/arch-meson/dram-gxbb.h168
-rw-r--r--arch/arm/include/asm/arch-meson/dram-gxl.h193
-rw-r--r--arch/arm/include/asm/arch-meson/dram-settings-gx.h296
-rw-r--r--arch/arm/include/asm/arch-meson/dram-timings-gx.h117
5 files changed, 1115 insertions, 0 deletions
diff --git a/arch/arm/include/asm/arch-meson/dram-gx.h b/arch/arm/include/asm/arch-meson/dram-gx.h
new file mode 100644
index 00000000000..177e0ac1a65
--- /dev/null
+++ b/arch/arm/include/asm/arch-meson/dram-gx.h
@@ -0,0 +1,341 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2015, Amlogic, Inc. All rights reserved.
+ * Copyright (C) 2023, Ferass El Hafidi <[email protected]>
+ */
+#ifndef DRAM_GX_H
+#define DRAM_GX_H
+
+/*
+ * Registers
+ */
+
+/* PCTL */
+#define DDR0_PCTL_BASE 0xc8839000
+/* DDR1_PCTL_BASE is DDR0_PCTL_BASE + 0x400 */
+
+/* DMC */
+#define DMC_REG_BASE 0xc8838000
+
+#define DMC_REQ_CTRL (DMC_REG_BASE + (0x00 << 2))
+#define DMC_SOFT_RST (DMC_REG_BASE + (0x01 << 2))
+#define DMC_SOFT_RST1 (DMC_REG_BASE + (0x02 << 2))
+#define DMC_RST_STS (DMC_REG_BASE + (0x03 << 2))
+#define DMC_VERSION (DMC_REG_BASE + (0x05 << 2))
+
+#define DMC_REFR_CTRL1 (DMC_REG_BASE + (0x23 << 2))
+#define DMC_REFR_CTRL2 (DMC_REG_BASE + (0x24 << 2))
+
+#define DMC_PCTL_LP_CTRL (DMC_REG_BASE + (0x46 << 2))
+
+#define DMC_AM0_QOS_INC (DMC_REG_BASE + (0x62 << 2))
+#define DMC_AM0_QOS_DEC (DMC_REG_BASE + (0x64 << 2))
+#define DMC_AM0_QOS_DIS (DMC_REG_BASE + (0x66 << 2))
+
+#define DMC_AM1_QOS_INC (DMC_REG_BASE + (0x6c << 2))
+#define DMC_AM1_QOS_DEC (DMC_REG_BASE + (0x6e << 2))
+#define DMC_AM1_QOS_DIS (DMC_REG_BASE + (0x70 << 2))
+
+#define DMC_AM2_QOS_INC (DMC_REG_BASE + (0x76 << 2))
+#define DMC_AM2_QOS_DEC (DMC_REG_BASE + (0x78 << 2))
+#define DMC_AM2_QOS_DIS (DMC_REG_BASE + (0x7a << 2))
+
+#define DMC_AM3_QOS_INC (DMC_REG_BASE + (0x80 << 2))
+#define DMC_AM3_QOS_DEC (DMC_REG_BASE + (0x82 << 2))
+#define DMC_AM3_QOS_DIS (DMC_REG_BASE + (0x84 << 2))
+
+#define DMC_AM4_QOS_INC (DMC_REG_BASE + (0x8a << 2))
+#define DMC_AM4_QOS_DEC (DMC_REG_BASE + (0x8c << 2))
+#define DMC_AM4_QOS_DIS (DMC_REG_BASE + (0x8e << 2))
+
+#define DMC_AM5_QOS_INC (DMC_REG_BASE + (0x94 << 2))
+#define DMC_AM5_QOS_DEC (DMC_REG_BASE + (0x96 << 2))
+#define DMC_AM5_QOS_DIS (DMC_REG_BASE + (0x98 << 2))
+
+#define DMC_AM6_QOS_INC (DMC_REG_BASE + (0x9e << 2))
+#define DMC_AM6_QOS_DEC (DMC_REG_BASE + (0xa0 << 2))
+#define DMC_AM6_QOS_DIS (DMC_REG_BASE + (0xa2 << 2))
+
+#define DMC_AM7_QOS_INC (DMC_REG_BASE + (0xa8 << 2))
+#define DMC_AM7_QOS_DEC (DMC_REG_BASE + (0xaa << 2))
+#define DMC_AM7_QOS_DIS (DMC_REG_BASE + (0xac << 2))
+
+#define DMC_AXI0_QOS_INC (DMC_REG_BASE + (0xb2 << 2))
+#define DMC_AXI0_QOS_DEC (DMC_REG_BASE + (0xb4 << 2))
+#define DMC_AXI0_QOS_DIS (DMC_REG_BASE + (0xb6 << 2))
+#define DMC_AXI0_QOS_CTRL1 (DMC_REG_BASE + (0xb9 << 2))
+
+#define DMC_AXI1_QOS_INC (DMC_REG_BASE + (0xbc << 2))
+#define DMC_AXI1_QOS_DEC (DMC_REG_BASE + (0xbe << 2))
+#define DMC_AXI1_QOS_DIS (DMC_REG_BASE + (0xc0 << 2))
+
+#define DMC_AXI2_QOS_INC (DMC_REG_BASE + (0xc6 << 2))
+#define DMC_AXI2_QOS_DEC (DMC_REG_BASE + (0xc8 << 2))
+#define DMC_AXI2_QOS_DIS (DMC_REG_BASE + (0xca << 2))
+
+#define DMC_AXI3_QOS_INC (DMC_REG_BASE + (0xd0 << 2))
+#define DMC_AXI3_QOS_DEC (DMC_REG_BASE + (0xd2 << 2))
+#define DMC_AXI3_QOS_DIS (DMC_REG_BASE + (0xd4 << 2))
+
+#define DMC_AXI4_QOS_INC (DMC_REG_BASE + (0xda << 2))
+#define DMC_AXI4_QOS_DEC (DMC_REG_BASE + (0xdc << 2))
+#define DMC_AXI4_QOS_DIS (DMC_REG_BASE + (0xde << 2))
+
+#define DMC_AXI5_QOS_INC (DMC_REG_BASE + (0xe4 << 2))
+#define DMC_AXI5_QOS_DEC (DMC_REG_BASE + (0xe6 << 2))
+#define DMC_AXI5_QOS_DIS (DMC_REG_BASE + (0xe8 << 2))
+
+#define DMC_AXI6_QOS_INC (DMC_REG_BASE + (0xee << 2))
+#define DMC_AXI6_QOS_DEC (DMC_REG_BASE + (0xf0 << 2))
+#define DMC_AXI6_QOS_DIS (DMC_REG_BASE + (0xf2 << 2))
+
+#define DMC_AXI7_QOS_INC (DMC_REG_BASE + (0xf8 << 2))
+#define DMC_AXI7_QOS_DEC (DMC_REG_BASE + (0xfa << 2))
+#define DMC_AXI7_QOS_DIS (DMC_REG_BASE + (0xfc << 2))
+
+/* DDR MMC */
+#define AM_DDR_PLL_CNTL0 (DDR_MMC_BASE + 0x00)
+#define AM_DDR_PLL_CNTL1 (DDR_MMC_BASE + 0x04)
+#define AM_DDR_PLL_CNTL2 (DDR_MMC_BASE + 0x08)
+#define AM_DDR_PLL_CNTL3 (DDR_MMC_BASE + 0x0c)
+#define AM_DDR_PLL_CNTL4 (DDR_MMC_BASE + 0x10)
+#if defined(CONFIG_MESON_GXBB)
+#define AM_DDR_PLL_STS (DDR_MMC_BASE + 0x14)
+#else
+#define AM_DDR_PLL_CNTL5 (DDR_MMC_BASE + 0x14)
+#endif
+
+#define DDR0_CLK_CTRL (DDR_MMC_BASE + 0x400)
+
+/* DMC SEC */
+#define DMC_SEC_REG_BASE 0xda838400
+
+#define DMC_SEC_CTRL (DMC_SEC_REG_BASE + (0x00 << 2))
+#define DMC_SEC_RANGE_CTRL (DMC_SEC_REG_BASE + (0x07 << 2))
+#define DMC_SEC_AXI_PORT_CTRL (DMC_SEC_REG_BASE + (0x0e << 2))
+
+#define DMC_VDEC_SEC_READ_CTRL (DMC_SEC_REG_BASE + (0x10 << 2))
+#define DMC_VDEC_SEC_WRITE_CTRL (DMC_SEC_REG_BASE + (0x11 << 2))
+#define DMC_VDEC_SEC_CFG (DMC_SEC_REG_BASE + (0x12 << 2))
+
+#define DMC_HCODEC_SEC_READ_CTRL (DMC_SEC_REG_BASE + (0x17 << 2))
+#define DMC_HCODEC_SEC_WRITE_CTRL (DMC_SEC_REG_BASE + (0x18 << 2))
+#define DMC_HCODEC_SEC_CFG (DMC_SEC_REG_BASE + (0x19 << 2))
+
+#define DMC_HEVC_SEC_READ_CTRL (DMC_SEC_REG_BASE + (0x1e << 2))
+#define DMC_HEVC_SEC_WRITE_CTRL (DMC_SEC_REG_BASE + (0x1f << 2))
+#define DMC_HEVC_SEC_CFG (DMC_SEC_REG_BASE + (0x20 << 2))
+
+#define DMC_VPU_SEC_READ_CTRL (DMC_SEC_REG_BASE + (0x32 << 2))
+#define DMC_VPU_SEC_WRITE_CTRL (DMC_SEC_REG_BASE + (0x33 << 2))
+#define DMC_VPU_SEC_CFG (DMC_SEC_REG_BASE + (0x25 << 2))
+
+#define DMC_GE2D_SEC_CTRL (DMC_SEC_REG_BASE + (0x34 << 2))
+#define DMC_PARSER_SEC_CTRL (DMC_SEC_REG_BASE + (0x35 << 2))
+#define DMC_DEV_SEC_READ_CTRL (DMC_SEC_REG_BASE + (0x36 << 2))
+#define DMC_DEV_SEC_WRITE_CTRL (DMC_SEC_REG_BASE + (0x37 << 2))
+
+#define DMC_WTCH0_CTRL (DMC_SEC_REG_BASE + (0xa9 << 2))
+#define DMC_WTCH1_CTRL (DMC_SEC_REG_BASE + (0xb0 << 2))
+
+#define DDR0_ADDRMAP_0 (DMC_SEC_REG_BASE + (0xd0 << 2))
+#define DDR0_ADDRMAP_1 (DMC_SEC_REG_BASE + (0xd1 << 2))
+#define DDR0_ADDRMAP_2 (DMC_SEC_REG_BASE + (0xd2 << 2))
+#define DDR0_ADDRMAP_3 (DMC_SEC_REG_BASE + (0xd3 << 2))
+#define DDR0_ADDRMAP_4 (DMC_SEC_REG_BASE + (0xd4 << 2))
+
+#define DDR1_ADDRMAP_0 (DMC_SEC_REG_BASE + (0xd5 << 2))
+#define DDR1_ADDRMAP_1 (DMC_SEC_REG_BASE + (0xd6 << 2))
+#define DDR1_ADDRMAP_2 (DMC_SEC_REG_BASE + (0xd7 << 2))
+#define DDR1_ADDRMAP_3 (DMC_SEC_REG_BASE + (0xd8 << 2))
+#define DDR1_ADDRMAP_4 (DMC_SEC_REG_BASE + (0xd9 << 2))
+
+#if defined(CONFIG_MESON_GXL)
+#define DMC_DES_KEY0_H (DMC_SEC_REG_BASE + (0x90 << 2))
+#define DMC_DES_KEY0_L (DMC_SEC_REG_BASE + (0x91 << 2))
+#define DMC_DES_KEY1_H (DMC_SEC_REG_BASE + (0x92 << 2))
+#define DMC_DES_KEY1_L (DMC_SEC_REG_BASE + (0x93 << 2))
+
+#define DMC_DES_CTRL (DMC_SEC_REG_BASE + (0x9d << 2))
+#endif
+
+#define DMC_DDR_CTRL (DMC_SEC_REG_BASE + (0xda << 2))
+
+#define AM_ANALOG_TOP_REG1 (0xc8834400 + (0x6f << 2))
+
+/* Macros */
+#define DQSCORR_DX(dx) \
+ if ((readl(dx) & ~(0xe00)) && ((readl(dx) >> 8) & ~(0xe00))) \
+ writel((((readl(dx) & ~(0xe00)) * 95) / 100) | \
+ (((((readl(dx) >> 8) & ~(0xe00)) * 88) / 100) << 8) | \
+ (((((readl(dx) >> 8) & ~(0xe00)) * 88) / 100) << 16), \
+ dx); \
+ else if (((readl(dx) >> 8) & ~(0xe00))) \
+ writel((95 / 100) | \
+ (((((readl(dx) >> 8) & ~(0xe00)) * 88) / 100) << 8) | \
+ (((((readl(dx) >> 8) & ~(0xe00)) * 88) / 100) << 16), \
+ dx); \
+ else if (((readl(dx)) & ~(0xe00))) \
+ writel((((readl(dx) & ~(0xe00)) * 95) / 100) | \
+ (((88) / 100) << 8) | (((88) / 100) << 16), \
+ dx); \
+ else \
+ writel((95 / 100) | \
+ ((88 / 100) << 8) | ((88 / 100) << 16), dx)
+
+#define DMC_ENABLE_REGION(REGION) \
+ writel(0xffffffff, REGION## _SEC_CFG); \
+ writel(0x55555555, REGION## _SEC_WRITE_CTRL); \
+ writel(0x55555555, REGION## _SEC_READ_CTRL)
+
+/* TODO: Timeout */
+#define WAIT_FOR(a) \
+ while (!(readl(a) & 1)) \
+ ; \
+ if (!(readl(a) & 1)) \
+ panic("%s: init failed, err=%d", __func__, -ETIMEDOUT)
+
+/**
+ * Register values
+ **/
+
+/*
+ * PLL
+ */
+#define DDR_CLK_CNTL_CLKGEN_SOFTRESET BIT(28)
+#define DDR_CLK_CNTL_PHY_CLK_ENABLE BIT(29)
+#define DDR_CLK_CNTL_DDRPLL_ENABLE BIT(31)
+
+/*
+ * PCTL
+ */
+
+/* PCTL_SCTL: state control register (S905X datasheet p.451) */
+#define PCTL_SCTL_CFG_STATE BIT(0)
+#define PCTL_SCTL_GO_STATE BIT(1)
+
+/* PCTL_STAT */
+#define PCTL_STAT_ACCESS (BIT(1) | BIT(0))
+
+/* PCTL_POWCTL: power control */
+#define PCTL_POWCTL_POWERON BIT(0)
+
+/*
+ * PUB
+ */
+
+/* PUB_PGSR0: PHY General Status Register 0 */
+#define PUB_PGSR0_IDONE BIT(0) /* Initialization Done */
+#define PUB_PGSR0_PLDONE BIT(1) /* PLL Lock Done */
+#define PUB_PGSR0_DCDONE BIT(2) /* DDL Calibration Done */
+#define PUB_PGSR0_ZCDONE BIT(3) /* Impedance Calibration Done */
+#define PUB_PGSR0_DIDONE BIT(4) /* DRAM Initialization Done */
+#define PUB_PGSR0_WLDONE BIT(5) /* Write Leveling Done */
+#define PUB_PGSR0_QSGDONE BIT(6) /* DQS Gate Training Done */
+#define PUB_PGSR0_WLADONE BIT(7) /* Write Leveling Adjust Done */
+#define PUB_PGSR0_RDDONE BIT(8) /* Read Bit Deskew Done */
+#define PUB_PGSR0_WDDONE BIT(9) /* Write Bit Deskew Done */
+#define PUB_PGSR0_REDONE BIT(10) /* Read Eye Training Done */
+#define PUB_PGSR0_WEDONE BIT(11) /* Write Eye Training Done */
+#define PUB_PGSR0_ZCERR BIT(20) /* Impedance Calib Error */
+#define PUB_PGSR0_WLERR BIT(21) /* Write Leveling Error */
+#define PUB_PGSR0_QSGERR BIT(22) /* DQS Gate Training Error */
+#define PUB_PGSR0_WLAERR BIT(23) /* Write Leveling Adj Error */
+#define PUB_PGSR0_RDERR BIT(24) /* Read Bit Deskew Error */
+#define PUB_PGSR0_WDERR BIT(25) /* Write Bit Deskew Error */
+#define PUB_PGSR0_REERR BIT(26) /* Read Eye Training Error */
+#define PUB_PGSR0_WEERR BIT(27) /* Write Eye Training Error */
+
+/* PUB_PIR: PHY init register */
+#define PUB_PIR_INIT BIT(0)
+#define PUB_PIR_ZCAL BIT(1)
+#define PUB_PIR_CA BIT(2)
+
+#define PUB_PIR_PLLINIT BIT(4)
+#define PUB_PIR_DCAL BIT(5)
+#define PUB_PIR_PHYRST BIT(6)
+#define PUB_PIR_DRAMRST BIT(7)
+#define PUB_PIR_DRAMINIT BIT(8)
+#define PUB_PIR_WL BIT(9)
+#define PUB_PIR_QSGATE BIT(10)
+#define PUB_PIR_WLADJ BIT(11)
+#define PUB_PIR_RDDSKW BIT(12)
+#define PUB_PIR_WRDSKW BIT(13)
+#define PUB_PIR_RDEYE BIT(14)
+#define PUB_PIR_WREYE BIT(15)
+#define PUB_PIR_ICPC BIT(16)
+#define PUB_PIR_PLLBYP BIT(17)
+#define PUB_PIR_CTLDINIT BIT(18)
+#define PUB_PIR_RDIMMINIT BIT(19)
+#define PUB_PIR_CLRSR BIT(27)
+#define PUB_PIR_LOCKBYP BIT(28)
+#define PUB_PIR_DCALBYP BIT(29)
+#define PUB_PIR_ZCALBYP BIT(30)
+#define PUB_PIR_INITBYP BIT(31)
+
+#define PUB_PIR_FINAL_STEP (PUB_PIR_INIT | PUB_PIR_ZCAL | \
+ PUB_PIR_PLLINIT | PUB_PIR_DCAL | PUB_PIR_PHYRST | PUB_PIR_DRAMRST | \
+ PUB_PIR_DRAMINIT | PUB_PIR_WL | PUB_PIR_QSGATE | PUB_PIR_WLADJ | \
+ PUB_PIR_RDDSKW | PUB_PIR_WRDSKW | PUB_PIR_RDEYE | PUB_PIR_WREYE)
+
+/* Struct which holds timings (see dram-settings-gx.h) */
+struct meson_gx_dram_timings {
+ u8 drv;
+ u8 odt;
+ u8 rtp;
+ u8 wtr;
+ u8 rp;
+ u8 rcd;
+ u8 ras;
+ u8 rrd;
+ u8 rc;
+ u8 mrd;
+ u8 mod;
+ u8 faw;
+ u8 wlmrd;
+ u8 wlo;
+ ushort rfc;
+ u8 xp;
+ ushort xs;
+ ushort dllk;
+ u8 cke;
+ u8 rtodt;
+ u8 rtw;
+ u8 refi;
+ u8 refi_mddr3;
+ u8 cl;
+ u8 wr;
+ u8 cwl;
+ u8 al;
+ u8 dqs;
+ u8 cksre;
+ u8 cksrx;
+ u8 zqcs;
+ u8 xpdll;
+ ushort exsr;
+ ushort zqcl;
+ ushort zqcsi;
+ u8 rpab;
+ u8 rppb;
+ u8 tccdl;
+ u8 tdqsck;
+ u8 tdqsckmax;
+ u8 tckesr;
+ u8 tdpd;
+ u8 taond_aofd;
+};
+
+#if defined(CONFIG_MESON_GXBB)
+# include <asm/arch/dram-gxbb.h>
+#elif defined(CONFIG_MESON_GXL)
+# include <asm/arch/dram-gxl.h>
+#endif
+
+/* Functions */
+int dram_init(void);
+void meson_dram_prepare_pctl(void);
+void meson_dram_phy_init(void);
+void meson_dram_phy_setup_ranks(void);
+void meson_dram_finalise_init(void);
+extern const struct meson_gx_dram_timings timings;
+#endif
diff --git a/arch/arm/include/asm/arch-meson/dram-gxbb.h b/arch/arm/include/asm/arch-meson/dram-gxbb.h
new file mode 100644
index 00000000000..b04f66d6336
--- /dev/null
+++ b/arch/arm/include/asm/arch-meson/dram-gxbb.h
@@ -0,0 +1,168 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2015, Amlogic, Inc. All rights reserved.
+ * Copyright (C) 2023-2025, Ferass El Hafidi <[email protected]>
+ */
+#ifndef DRAM_GXBB_H
+#define DRAM_GXBB_H
+
+/* PUB (not much documented) */
+#define DDR0_PUB_REG_BASE 0xc8836000
+
+#define DDR0_PUB_PIR (DDR0_PUB_REG_BASE + (0x01 << 2))
+
+#define DDR0_PUB_PGCR1 (DDR0_PUB_REG_BASE + (0x03 << 2))
+#define DDR0_PUB_PGCR2 (DDR0_PUB_REG_BASE + (0x04 << 2))
+#define DDR0_PUB_PGCR3 (DDR0_PUB_REG_BASE + (0x05 << 2))
+#define DDR0_PUB_PGSR0 (DDR0_PUB_REG_BASE + (0x06 << 2))
+
+#define DDR0_PUB_ACLCDLR (DDR0_PUB_REG_BASE + (0x0F << 2))
+#define DDR0_PUB_ACBDLR0 (DDR0_PUB_REG_BASE + (0x10 << 2))
+#define DDR0_PUB_ACIOCR1 (DDR0_PUB_REG_BASE + (0x1B << 2))
+#define DDR0_PUB_ACIOCR2 (DDR0_PUB_REG_BASE + (0x1C << 2))
+#define DDR0_PUB_ACIOCR3 (DDR0_PUB_REG_BASE + (0x1D << 2))
+#define DDR0_PUB_ACIOCR4 (DDR0_PUB_REG_BASE + (0x1E << 2))
+#define DDR0_PUB_ACIOCR5 (DDR0_PUB_REG_BASE + (0x1F << 2))
+
+#define DDR0_PUB_DXCCR (DDR0_PUB_REG_BASE + (0x20 << 2))
+#define DDR0_PUB_DSGCR (DDR0_PUB_REG_BASE + (0x21 << 2))
+#define DDR0_PUB_DCR (DDR0_PUB_REG_BASE + (0x22 << 2))
+
+#define DDR0_PUB_DTPR0 (DDR0_PUB_REG_BASE + (0x23 << 2))
+#define DDR0_PUB_DTPR1 (DDR0_PUB_REG_BASE + (0x24 << 2))
+#define DDR0_PUB_DTPR2 (DDR0_PUB_REG_BASE + (0x25 << 2))
+#define DDR0_PUB_DTPR3 (DDR0_PUB_REG_BASE + (0x26 << 2))
+
+#define DDR0_PUB_MR0 (DDR0_PUB_REG_BASE + (0x27 << 2))
+#define DDR0_PUB_MR1 (DDR0_PUB_REG_BASE + (0x28 << 2))
+#define DDR0_PUB_MR2 (DDR0_PUB_REG_BASE + (0x29 << 2))
+#define DDR0_PUB_MR3 (DDR0_PUB_REG_BASE + (0x2A << 2))
+
+#define DDR0_PUB_ODTCR (DDR0_PUB_REG_BASE + (0x2B << 2))
+
+#define DDR0_PUB_DTCR (DDR0_PUB_REG_BASE + (0x2C << 2))
+
+#define DDR0_PUB_DTAR0 (DDR0_PUB_REG_BASE + (0x2D << 2))
+#define DDR0_PUB_DTAR1 (DDR0_PUB_REG_BASE + (0x2E << 2))
+#define DDR0_PUB_DTAR2 (DDR0_PUB_REG_BASE + (0x2F << 2))
+#define DDR0_PUB_DTAR3 (DDR0_PUB_REG_BASE + (0x30 << 2))
+
+#define DDR0_PUB_IOVCR0 (DDR0_PUB_REG_BASE + (0x8E << 2))
+#define DDR0_PUB_IOVCR1 (DDR0_PUB_REG_BASE + (0x8F << 2))
+
+#define DDR0_PUB_ZQCR (DDR0_PUB_REG_BASE + (0x90 << 2))
+
+#define DDR0_PUB_ZQ0PR (DDR0_PUB_REG_BASE + (0x91 << 2))
+#define DDR0_PUB_ZQ1PR (DDR0_PUB_REG_BASE + (0x95 << 2))
+#define DDR0_PUB_ZQ2PR (DDR0_PUB_REG_BASE + (0x99 << 2))
+#define DDR0_PUB_ZQ3PR (DDR0_PUB_REG_BASE + (0x9D << 2))
+
+#define DDR0_PUB_DX0GCR1 (DDR0_PUB_REG_BASE + (0xA1 << 2))
+#define DDR0_PUB_DX0GCR2 (DDR0_PUB_REG_BASE + (0xA2 << 2))
+#define DDR0_PUB_DX0GCR3 (DDR0_PUB_REG_BASE + (0xA3 << 2))
+
+#define DDR0_PUB_DX0LCDLR0 (DDR0_PUB_REG_BASE + (0xAE << 2))
+#define DDR0_PUB_DX0LCDLR2 (DDR0_PUB_REG_BASE + (0xB0 << 2))
+
+#define DDR0_PUB_DX0GTR (DDR0_PUB_REG_BASE + (0xB2 << 2))
+#define DDR0_PUB_DX1GTR (DDR0_PUB_REG_BASE + (0xD2 << 2))
+#define DDR0_PUB_DX2GTR (DDR0_PUB_REG_BASE + (0xF2 << 2))
+#define DDR0_PUB_DX3GTR (DDR0_PUB_REG_BASE + (0x112 << 2))
+
+#define DDR0_PUB_DX1GCR1 (DDR0_PUB_REG_BASE + (0xC1 << 2))
+#define DDR0_PUB_DX1GCR2 (DDR0_PUB_REG_BASE + (0xC2 << 2))
+#define DDR0_PUB_DX1GCR3 (DDR0_PUB_REG_BASE + (0xC3 << 2))
+#define DDR0_PUB_DX1LCDLR0 (DDR0_PUB_REG_BASE + (0xCE << 2))
+#define DDR0_PUB_DX1LCDLR2 (DDR0_PUB_REG_BASE + (0xD0 << 2))
+
+#define DDR0_PUB_DX2GCR1 (DDR0_PUB_REG_BASE + (0xE1 << 2))
+#define DDR0_PUB_DX2GCR2 (DDR0_PUB_REG_BASE + (0xE2 << 2))
+#define DDR0_PUB_DX2GCR3 (DDR0_PUB_REG_BASE + (0xE3 << 2))
+#define DDR0_PUB_DX2LCDLR2 (DDR0_PUB_REG_BASE + (0xF0 << 2))
+
+#define DDR0_PUB_DX3GCR1 (DDR0_PUB_REG_BASE + (0x101 << 2))
+#define DDR0_PUB_DX3GCR2 (DDR0_PUB_REG_BASE + (0x102 << 2))
+#define DDR0_PUB_DX3GCR3 (DDR0_PUB_REG_BASE + (0x103 << 2))
+#define DDR0_PUB_DX3LCDLR0 (DDR0_PUB_REG_BASE + (0x10E << 2))
+#define DDR0_PUB_DX3LCDLR2 (DDR0_PUB_REG_BASE + (0x110 << 2))
+
+/* PCTL */
+#define DDR0_PCTL_BASE 0xc8839000
+/* DDR1_PCTL_BASE is DDR0_PCTL_BASE + 0x400 */
+
+#define PCTL_SCFG (DDR0_PCTL_BASE + 0x000)
+#define PCTL_SCTL (DDR0_PCTL_BASE + (0x1 << 2))
+#define PCTL_STAT (DDR0_PCTL_BASE + (0x2 << 2))
+
+#define PCTL_POWSTAT (DDR0_PCTL_BASE + (0x12 << 2))
+#define PCTL_POWCTL (DDR0_PCTL_BASE + (0x11 << 2))
+
+#define PCTL_CMDTSTAT (DDR0_PCTL_BASE + (0x13 << 2))
+#define PCTL_CMDTSTATEN (DDR0_PCTL_BASE + (0x14 << 2))
+
+#define PCTL_PPCFG (DDR0_PCTL_BASE + (0x21 << 2))
+
+#define PCTL_MCFG (DDR0_PCTL_BASE + (0x20 << 2))
+#define PCTL_MCFG1 (DDR0_PCTL_BASE + (0x1f << 2))
+
+#define PCTL_TCKSRE (DDR0_PCTL_BASE + (0x49 << 2))
+#define PCTL_TZQCSI (DDR0_PCTL_BASE + (0x47 << 2))
+#define PCTL_TINIT (DDR0_PCTL_BASE + (0x31 << 2))
+#define PCTL_TOGCNT1U (DDR0_PCTL_BASE + (0x30 << 2))
+#define PCTL_TCKE (DDR0_PCTL_BASE + (0x4b << 2))
+#define PCTL_TMOD (DDR0_PCTL_BASE + (0x4c << 2))
+#define PCTL_TEXSR (DDR0_PCTL_BASE + (0x43 << 2))
+#define PCTL_TAL (DDR0_PCTL_BASE + (0x39 << 2))
+#define PCTL_TRTP (DDR0_PCTL_BASE + (0x40 << 2))
+#define PCTL_TCKSRX (DDR0_PCTL_BASE + (0x4a << 2))
+#define PCTL_TRTW (DDR0_PCTL_BASE + (0x38 << 2))
+#define PCTL_TCWL (DDR0_PCTL_BASE + (0x3b << 2))
+#define PCTL_TWR (DDR0_PCTL_BASE + (0x41 << 2))
+#define PCTL_TCL (DDR0_PCTL_BASE + (0x3a << 2))
+#define PCTL_TDQS (DDR0_PCTL_BASE + (0x48 << 2))
+#define PCTL_TRSTH (DDR0_PCTL_BASE + (0x32 << 2))
+#define PCTL_TRCD (DDR0_PCTL_BASE + (0x3e << 2))
+#define PCTL_TXP (DDR0_PCTL_BASE + (0x44 << 2))
+#define PCTL_TOGCNT100N (DDR0_PCTL_BASE + (0x33 << 2))
+#define PCTL_TMRD (DDR0_PCTL_BASE + (0x35 << 2))
+#define PCTL_TREFI (DDR0_PCTL_BASE + (0x34 << 2))
+#define PCTL_TRAS (DDR0_PCTL_BASE + (0x3c << 2))
+#define PCTL_TREFI_MEM_DDR3 (DDR0_PCTL_BASE + (0x52 << 2))
+#define PCTL_TWTR (DDR0_PCTL_BASE + (0x42 << 2))
+#define PCTL_TRC (DDR0_PCTL_BASE + (0x3d << 2))
+#define PCTL_TRFC (DDR0_PCTL_BASE + (0x36 << 2))
+#define PCTL_TCKESR (DDR0_PCTL_BASE + (0x50 << 2))
+#define PCTL_TZQCL (DDR0_PCTL_BASE + (0x4e << 2))
+#define PCTL_TRRD (DDR0_PCTL_BASE + (0x3f << 2))
+#define PCTL_TRP (DDR0_PCTL_BASE + (0x37 << 2))
+#define PCTL_TZQCS (DDR0_PCTL_BASE + (0x46 << 2))
+#define PCTL_TXPDLL (DDR0_PCTL_BASE + (0x45 << 2))
+
+#define PCTL_DFIODTCFG (DDR0_PCTL_BASE + (0x91 << 2))
+#define PCTL_DFIODTCFG1 (DDR0_PCTL_BASE + (0x92 << 2))
+#define PCTL_DFITCTRLDELAY (DDR0_PCTL_BASE + (0x90 << 2))
+#define PCTL_DFITPHYWRLAT (DDR0_PCTL_BASE + (0x95 << 2))
+#define PCTL_DFITPHYWRDATA (DDR0_PCTL_BASE + (0x94 << 2))
+#define PCTL_DFITRDDATAEN (DDR0_PCTL_BASE + (0x98 << 2))
+#define PCTL_DFITPHYRDLAT (DDR0_PCTL_BASE + (0x99 << 2))
+#define PCTL_DFITPHYUPDTYPE1 (DDR0_PCTL_BASE + (0x9d << 2))
+#define PCTL_DFISTCFG0 (DDR0_PCTL_BASE + (0xb1 << 2))
+#define PCTL_DFISTCFG1 (DDR0_PCTL_BASE + (0xb2 << 2))
+#define PCTL_DFISTSTAT0 (DDR0_PCTL_BASE + (0xb0 << 2))
+#define PCTL_DFILPCFG0 (DDR0_PCTL_BASE + (0xbc << 2))
+#define PCTL_DFITCTRLUPDMIN (DDR0_PCTL_BASE + (0xa0 << 2))
+#define PCTL_DFITDRAMCLKEN (DDR0_PCTL_BASE + (0xb4 << 2))
+#define PCTL_DFITDRAMCLKDIS (DDR0_PCTL_BASE + (0xb5 << 2))
+
+/* DDR MMC (see dram-gx.h for more details) */
+#define DDR_MMC_BASE 0xc8836800
+
+#define DDR0_SOFT_RESET (DDR_MMC_BASE + 0x404)
+#define DDR_CLK_CNTL (DDR_MMC_BASE + 0x18)
+#define DDR0_APD_CTRL (DDR_MMC_BASE + 0x408)
+
+/* These will get optimized out by the compiler */
+#define AM_DDR_PLL_CNTL5 0
+#define PCTL_TCCD 0
+#define PCTL_TFAW 0
+#endif
diff --git a/arch/arm/include/asm/arch-meson/dram-gxl.h b/arch/arm/include/asm/arch-meson/dram-gxl.h
new file mode 100644
index 00000000000..c52ef37c1bf
--- /dev/null
+++ b/arch/arm/include/asm/arch-meson/dram-gxl.h
@@ -0,0 +1,193 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2015, Amlogic, Inc. All rights reserved.
+ * Copyright (C) 2023-2025, Ferass El Hafidi <[email protected]>
+ */
+#ifndef DRAM_GXL_H
+#define DRAM_GXL_H
+
+/* PUB (not much documented) */
+#define DDR0_PUB_REG_BASE 0xc8836000
+
+#define DDR0_PUB_PIR (DDR0_PUB_REG_BASE + (0x01 << 2))
+
+#define DDR0_PUB_PGCR1 (DDR0_PUB_REG_BASE + (0x05 << 2))
+#define DDR0_PUB_PGCR2 (DDR0_PUB_REG_BASE + (0x06 << 2))
+#define DDR0_PUB_PGCR3 (DDR0_PUB_REG_BASE + (0x07 << 2))
+#define DDR0_PUB_PGCR4 (DDR0_PUB_REG_BASE + (0x08 << 2))
+#define DDR0_PUB_PGCR5 (DDR0_PUB_REG_BASE + (0x09 << 2))
+#define DDR0_PUB_PGCR6 (DDR0_PUB_REG_BASE + (0x0a << 2))
+#define DDR0_PUB_PGSR0 (DDR0_PUB_REG_BASE + (0x0d << 2))
+
+#define DDR0_PUB_ACLCDLR (DDR0_PUB_REG_BASE + (0x160 << 2))
+#define DDR0_PUB_ACMDLR0 (DDR0_PUB_REG_BASE + (0x168 << 2))
+#define DDR0_PUB_ACBDLR0 (DDR0_PUB_REG_BASE + (0x150 << 2))
+#define DDR0_PUB_ACBDLR1 (DDR0_PUB_REG_BASE + (0x151 << 2))
+#define DDR0_PUB_ACBDLR2 (DDR0_PUB_REG_BASE + (0x152 << 2))
+#define DDR0_PUB_ACBDLR3 (DDR0_PUB_REG_BASE + (0x153 << 2))
+#define DDR0_PUB_ACBDLR6 (DDR0_PUB_REG_BASE + (0x156 << 2))
+#define DDR0_PUB_ACBDLR7 (DDR0_PUB_REG_BASE + (0x157 << 2))
+#define DDR0_PUB_ACBDLR8 (DDR0_PUB_REG_BASE + (0x158 << 2))
+#define DDR0_PUB_ACBDLR9 (DDR0_PUB_REG_BASE + (0x159 << 2))
+#define DDR0_PUB_ACIOCR1 (DDR0_PUB_REG_BASE + (0x141 << 2))
+#define DDR0_PUB_ACIOCR2 (DDR0_PUB_REG_BASE + (0x142 << 2))
+#define DDR0_PUB_ACIOCR3 (DDR0_PUB_REG_BASE + (0x143 << 2))
+#define DDR0_PUB_ACIOCR4 (DDR0_PUB_REG_BASE + (0x144 << 2))
+#define DDR0_PUB_ACIOCR5 (DDR0_PUB_REG_BASE + (0x145 << 2))
+
+#define DDR0_PUB_PTR3 (DDR0_PUB_REG_BASE + (0x13 << 2))
+#define DDR0_PUB_PTR4 (DDR0_PUB_REG_BASE + (0x14 << 2))
+
+#define DDR0_PUB_DXCCR (DDR0_PUB_REG_BASE + (0x22 << 2))
+#define DDR0_PUB_DSGCR (DDR0_PUB_REG_BASE + (0x24 << 2))
+#define DDR0_PUB_DCR (DDR0_PUB_REG_BASE + (0x40 << 2))
+
+#define DDR0_PUB_DTPR0 (DDR0_PUB_REG_BASE + (0x44 << 2))
+#define DDR0_PUB_DTPR1 (DDR0_PUB_REG_BASE + (0x45 << 2))
+#define DDR0_PUB_DTPR2 (DDR0_PUB_REG_BASE + (0x46 << 2))
+#define DDR0_PUB_DTPR3 (DDR0_PUB_REG_BASE + (0x47 << 2))
+#define DDR0_PUB_DTPR4 (DDR0_PUB_REG_BASE + (0x48 << 2))
+#define DDR0_PUB_DTPR5 (DDR0_PUB_REG_BASE + (0x49 << 2))
+
+#define DDR0_PUB_MR0 (DDR0_PUB_REG_BASE + (0x60 << 2))
+#define DDR0_PUB_MR1 (DDR0_PUB_REG_BASE + (0x61 << 2))
+#define DDR0_PUB_MR2 (DDR0_PUB_REG_BASE + (0x62 << 2))
+#define DDR0_PUB_MR3 (DDR0_PUB_REG_BASE + (0x63 << 2))
+#define DDR0_PUB_MR4 (DDR0_PUB_REG_BASE + (0x64 << 2))
+#define DDR0_PUB_MR5 (DDR0_PUB_REG_BASE + (0x65 << 2))
+#define DDR0_PUB_MR6 (DDR0_PUB_REG_BASE + (0x66 << 2))
+#define DDR0_PUB_MR11 (DDR0_PUB_REG_BASE + (0x6b << 2))
+
+#define DDR0_PUB_ODTCR (DDR0_PUB_REG_BASE + (0x26 << 2))
+
+#define DDR0_PUB_DTCR (DDR0_PUB_REG_BASE + (0x80 << 2))
+#define DDR0_PUB_DTCR1 (DDR0_PUB_REG_BASE + (0x81 << 2))
+
+#define DDR0_PUB_DTAR0 (DDR0_PUB_REG_BASE + (0x82 << 2))
+#define DDR0_PUB_DTAR1 (DDR0_PUB_REG_BASE + (0x83 << 2))
+#define DDR0_PUB_DTAR2 (DDR0_PUB_REG_BASE + (0x84 << 2))
+#define DDR0_PUB_DTAR3 (DDR0_PUB_REG_BASE + (0x85 << 2))
+
+#define DDR0_PUB_RANKIDR (DDR0_PUB_REG_BASE + (0x137 << 2))
+
+#define DDR0_PUB_IOVCR0 (DDR0_PUB_REG_BASE + (0x148 << 2))
+#define DDR0_PUB_IOVCR1 (DDR0_PUB_REG_BASE + (0x149 << 2))
+
+#define DDR0_PUB_VTCR0 (DDR0_PUB_REG_BASE + (0x14a << 2))
+#define DDR0_PUB_VTCR1 (DDR0_PUB_REG_BASE + (0x14b << 2))
+
+#define DDR0_PUB_ZQCR (DDR0_PUB_REG_BASE + (0x1a0 << 2))
+
+#define DDR0_PUB_ZQ0PR (DDR0_PUB_REG_BASE + (0x1a1 << 2))
+#define DDR0_PUB_ZQ1PR (DDR0_PUB_REG_BASE + (0x1a5 << 2))
+#define DDR0_PUB_ZQ2PR (DDR0_PUB_REG_BASE + (0x1a9 << 2))
+#define DDR0_PUB_ZQ3PR (DDR0_PUB_REG_BASE + (0x1ad << 2))
+
+#define DDR0_PUB_DX0GCR1 (DDR0_PUB_REG_BASE + (0x1c1 << 2))
+#define DDR0_PUB_DX0GCR2 (DDR0_PUB_REG_BASE + (0x1c2 << 2))
+#define DDR0_PUB_DX0GCR3 (DDR0_PUB_REG_BASE + (0x1c3 << 2))
+#define DDR0_PUB_DX0GCR4 (DDR0_PUB_REG_BASE + (0x1c4 << 2))
+#define DDR0_PUB_DX0LCDLR0 (DDR0_PUB_REG_BASE + (0x1e0 << 2))
+#define DDR0_PUB_DX0LCDLR2 (DDR0_PUB_REG_BASE + (0x1e2 << 2))
+
+#define DDR0_PUB_DX0GTR (DDR0_PUB_REG_BASE + (0x1f0 << 2))
+#define DDR0_PUB_DX1GTR (DDR0_PUB_REG_BASE + (0x230 << 2))
+#define DDR0_PUB_DX2GTR (DDR0_PUB_REG_BASE + (0x270 << 2))
+#define DDR0_PUB_DX3GTR (DDR0_PUB_REG_BASE + (0x2b0 << 2))
+
+#define DDR0_PUB_DX1GCR1 (DDR0_PUB_REG_BASE + (0x201 << 2))
+#define DDR0_PUB_DX1GCR2 (DDR0_PUB_REG_BASE + (0x202 << 2))
+#define DDR0_PUB_DX1GCR3 (DDR0_PUB_REG_BASE + (0x203 << 2))
+#define DDR0_PUB_DX1GCR4 (DDR0_PUB_REG_BASE + (0x204 << 2))
+#define DDR0_PUB_DX1LCDLR0 (DDR0_PUB_REG_BASE + (0x220 << 2))
+#define DDR0_PUB_DX1LCDLR2 (DDR0_PUB_REG_BASE + (0x222 << 2))
+
+#define DDR0_PUB_DX2GCR0 (DDR0_PUB_REG_BASE + (0x240 << 2))
+#define DDR0_PUB_DX2GCR1 (DDR0_PUB_REG_BASE + (0x241 << 2))
+#define DDR0_PUB_DX2GCR2 (DDR0_PUB_REG_BASE + (0x242 << 2))
+#define DDR0_PUB_DX2GCR3 (DDR0_PUB_REG_BASE + (0x243 << 2))
+#define DDR0_PUB_DX2GCR4 (DDR0_PUB_REG_BASE + (0x244 << 2))
+#define DDR0_PUB_DX2LCDLR0 (DDR0_PUB_REG_BASE + (0x260 << 2))
+#define DDR0_PUB_DX2LCDLR2 (DDR0_PUB_REG_BASE + (0x262 << 2))
+
+#define DDR0_PUB_DX3GCR0 (DDR0_PUB_REG_BASE + (0x280 << 2))
+#define DDR0_PUB_DX3GCR1 (DDR0_PUB_REG_BASE + (0x281 << 2))
+#define DDR0_PUB_DX3GCR2 (DDR0_PUB_REG_BASE + (0x282 << 2))
+#define DDR0_PUB_DX3GCR3 (DDR0_PUB_REG_BASE + (0x283 << 2))
+#define DDR0_PUB_DX3GCR4 (DDR0_PUB_REG_BASE + (0x284 << 2))
+#define DDR0_PUB_DX3LCDLR0 (DDR0_PUB_REG_BASE + (0x2a0 << 2))
+#define DDR0_PUB_DX3LCDLR2 (DDR0_PUB_REG_BASE + (0x2a2 << 2))
+
+/* PCTL */
+#define DMC_PCTL_BASE 0xc8839000
+
+#define PCTL_SCFG (DDR0_PCTL_BASE + 0x000)
+#define PCTL_SCTL (DDR0_PCTL_BASE + (0x1 << 2))
+#define PCTL_STAT (DDR0_PCTL_BASE + (0x48 << 2))
+
+#define PCTL_CMDTSTAT (DDR0_PCTL_BASE + (0x48 << 2))
+
+#define PCTL_PPCFG (DDR0_PCTL_BASE + (0x43 << 2))
+#define PCTL_ZQCFG (DDR0_PCTL_BASE + (0x44 << 2))
+
+#define PCTL_MCFG (DDR0_PCTL_BASE + (0x41 << 2))
+#define PCTL_MCFG1 (DDR0_PCTL_BASE + (0x42 << 2))
+
+#define PCTL_TCKSRE (DDR0_PCTL_BASE + (0x1a << 2))
+#define PCTL_TZQCSI (DDR0_PCTL_BASE + (0x19 << 2))
+#define PCTL_TCKE (DDR0_PCTL_BASE + (0x1c << 2))
+#define PCTL_TMOD (DDR0_PCTL_BASE + (0x1d << 2))
+#define PCTL_TEXSR (DDR0_PCTL_BASE + (0x15 << 2))
+#define PCTL_TAL (DDR0_PCTL_BASE + (0x50 << 2))
+#define PCTL_TCCD (DDR0_PCTL_BASE + (0x52 << 2))
+#define PCTL_TRTP (DDR0_PCTL_BASE + (0x12 << 2))
+#define PCTL_TFAW (DDR0_PCTL_BASE + (0x11 << 2))
+#define PCTL_TCKSRX (DDR0_PCTL_BASE + (0x1b << 2))
+#define PCTL_TRTW (DDR0_PCTL_BASE + (0x9 << 2))
+#define PCTL_TCWL (DDR0_PCTL_BASE + (0xc << 2))
+#define PCTL_TWR (DDR0_PCTL_BASE + (0x13 << 2))
+#define PCTL_TCL (DDR0_PCTL_BASE + (0xb << 2))
+#define PCTL_TDQS (DDR0_PCTL_BASE + (0x1e << 2))
+#define PCTL_TRCD (DDR0_PCTL_BASE + (0xf << 2))
+#define PCTL_TXP (DDR0_PCTL_BASE + (0x16 << 2))
+#define PCTL_TMRD (DDR0_PCTL_BASE + (0x6 << 2))
+#define PCTL_TRAS (DDR0_PCTL_BASE + (0xd << 2))
+#define PCTL_TREFI_MEM_DDR3 (DDR0_PCTL_BASE + (0x24 << 2)) // replaced by TREFI
+#define PCTL_TWTR (DDR0_PCTL_BASE + (0x14 << 2))
+#define PCTL_TRC (DDR0_PCTL_BASE + (0xe << 2))
+#define PCTL_TRFC (DDR0_PCTL_BASE + (0x7 << 2))
+#define PCTL_TCKESR (DDR0_PCTL_BASE + (0x22 << 2))
+#define PCTL_TZQCL (DDR0_PCTL_BASE + (0x20 << 2))
+#define PCTL_TRRD (DDR0_PCTL_BASE + (0x10 << 2))
+#define PCTL_TRP (DDR0_PCTL_BASE + (0x8 << 2))
+#define PCTL_TZQCS (DDR0_PCTL_BASE + (0x18 << 2))
+#define PCTL_TXPDLL (DDR0_PCTL_BASE + (0x17 << 2))
+
+#define PCTL_DFIODTCFG (DDR0_PCTL_BASE + (0x27 << 2))
+#define PCTL_DFIODTCFG1 (DDR0_PCTL_BASE + (0x28 << 2))
+#define PCTL_DFITCTRLDELAY (DDR0_PCTL_BASE + (0x26 << 2))
+#define PCTL_DFITPHYWRLAT (DDR0_PCTL_BASE + (0x2b << 2))
+#define PCTL_DFITPHYWRDATA (DDR0_PCTL_BASE + (0x2a << 2))
+#define PCTL_DFITRDDATAEN (DDR0_PCTL_BASE + (0x2c << 2))
+#define PCTL_DFITPHYRDLAT (DDR0_PCTL_BASE + (0x2d << 2))
+#define PCTL_DFITPHYUPDTYPE0 (DDR0_PCTL_BASE + (0x2e << 2))
+#define PCTL_DFITPHYUPDTYPE1 (DDR0_PCTL_BASE + (0x2f << 2))
+#define PCTL_DFIUPDCFG (DDR0_PCTL_BASE + (0x35 << 2))
+#define PCTL_DFISTCFG0 (DDR0_PCTL_BASE + (0x3c << 2))
+#define PCTL_DFISTCFG1 (DDR0_PCTL_BASE + (0x3d << 2))
+#define PCTL_DFISTSTAT0 (DDR0_PCTL_BASE + (0x46 << 2))
+#define PCTL_DFILPCFG0 (DDR0_PCTL_BASE + (0x40 << 2))
+#define PCTL_DFITCTRLUPDMIN (DDR0_PCTL_BASE + (0x32 << 2))
+#define PCTL_DFITCTRLUPDMAX (DDR0_PCTL_BASE + (0x33 << 2))
+#define PCTL_DFITDRAMCLKEN (DDR0_PCTL_BASE + (0x3e << 2))
+#define PCTL_DFITDRAMCLKDIS (DDR0_PCTL_BASE + (0x3f << 2))
+
+/* DDR MMC (see dram-gx.h for more details) */
+#define DDR_MMC_BASE 0xc8837000
+
+#define DDR0_SOFT_RESET (DDR_MMC_BASE + 0x20)
+
+#define AM_DDR_PLL_STS (DDR_MMC_BASE + 0x18)
+#define DDR_CLK_CNTL (DDR_MMC_BASE + 0x1c)
+#define DDR0_APD_CTRL (DDR_MMC_BASE + 0x24)
+#endif
diff --git a/arch/arm/include/asm/arch-meson/dram-settings-gx.h b/arch/arm/include/asm/arch-meson/dram-settings-gx.h
new file mode 100644
index 00000000000..b4ced2eda67
--- /dev/null
+++ b/arch/arm/include/asm/arch-meson/dram-settings-gx.h
@@ -0,0 +1,296 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2023-2024, Ferass El Hafidi <[email protected]>
+ */
+#ifndef DRAM_SETTINGS_GX_H
+#define DRAM_SETTINGS_GX_H
+#include <linux/bitops.h>
+#include <asm/arch/dram-gx.h>
+
+/*
+ * These registers are pretty similar to other DRAM registers found in
+ * Allwinner A31/sun6i. Some of these registers also exist in some Rockchip
+ * SoCs and the TI KeyStone3.
+ */
+/* DMC control register */
+#if defined(CONFIG_DRAM_TWO_IDENTICAL_RANKS) || defined(CONFIG_DRAM_ONE_RANK)
+#define DMC_DRAM_SIZE_SHIFT 6
+#else
+#define DMC_DRAM_SIZE_SHIFT 7
+#endif
+#define DMC_CTRL_CHANNEL BIT(6) /* Channel 0 only */
+#if defined(CONFIG_DRAM_DDR4)
+#define DMC_CTRL_DDR_TYPE BIT(22) | BIT(20) /* DDR4 */
+#else
+#define DMC_CTRL_DDR_TYPE 0
+#endif
+#if defined(CONFIG_DRAM_ONE_RANK) || defined(CONFIG_DRAM_TWO_DIFF_RANKS)
+#define DMC_CTRL_RANK BIT(21) /* Enable rank 1 */
+#elif defined(CONFIG_DRAM_TWO_IDENTICAL_RANKS)
+#define DMC_CTRL_RANK BIT(22) /* Rank 0 and 1 are identical */
+#elif defined(CONFIG_DRAM_16BIT_RANK)
+#define DMC_CTRL_RANK BIT(16) /* 16-bit Rank 0 */
+#endif
+#define DMC_CTRL DMC_CTRL_CHANNEL | DMC_CTRL_RANK | DMC_CTRL_DDR_TYPE
+
+/* Mode Register */
+#if defined(CONFIG_MESON_GXL) && defined(CONFIG_DRAM_DDR4)
+#define PUB_MR0 4 | (((((timings.cl - 9) >> 1) & 7) << 4)) | \
+ ((((timings.wr - 10) >> 1) & 7) << 9)
+#define PUB_MR1 (timings.odt << 8) | (timings.drv << 1) | 0x81
+#define PUB_MR2 (((timings.cwl - 6) >> 1) & 7) << 3 | 0xc0
+#define PUB_MR3 0
+#define PUB_MR4 8
+#else
+#define PUB_MR0 (((timings.cl - 4) & 8) >> 1) | \
+ (((timings.cl - 4) & 7) << 4) | \
+ (((timings.wr <= 8 ? (timings.wr - 4) : (timings.wr >> 1)) & 7) << 9) | 0x1c00
+#define PUB_MR1 (timings.drv << 1) | \
+ ((timings.odt & 1) << 2) | \
+ (((timings.odt >> 1) & 1) << 6) | \
+ (((timings.odt >> 2) & 1) << 9) | \
+ BIT(7) | \
+ ((timings.al ? ((timings.cl - timings.al) & 3) : 0) << 3)
+#define PUB_MR2 BIT(6) | (((timings.cwl - 5) & 7) << 3)
+#endif
+#define PUB_MR3 0
+#if defined(CONFIG_MESON_GXL)
+#if defined(CONFIG_DRAM_DDR3)
+#define PUB_MR4 0
+#define PUB_MR5 0x420
+#elif defined(CONFIG_DRAM_DDR4)
+#define PUB_MR5 0x400
+#endif
+#define PUB_MR6 0x800
+#endif
+
+/* ODT Configuration Register */
+#if defined(CONFIG_MESON_GXBB)
+#define PUB_ODTCR 0x210000
+#elif defined(CONFIG_MESON_GXL)
+#define PUB_ODTCR 0x30000
+#endif
+
+/* DDR Timing Parameter */
+#if defined(CONFIG_MESON_GXBB)
+#define PUB_DTPR0 timings.rtp | \
+ (timings.wtr << 4) | \
+ (timings.rp << 8) | \
+ (timings.ras << 16) | \
+ (timings.rrd << 22) | \
+ (timings.rcd << 26)
+#define PUB_DTPR1 (timings.mod << 2) | \
+ (timings.faw << 5) | \
+ (timings.rfc << 11) | \
+ (timings.wlmrd << 20) | \
+ (timings.wlo << 26)
+#define PUB_DTPR2 timings.xs | \
+ (timings.xp << 10) | \
+ (timings.dllk << 19)
+#define PUB_DTPR3 0 | \
+ (0 << 3) | \
+ (timings.rc << 6) | \
+ (timings.cke << 13) | \
+ (timings.mrd << 18) | \
+ (0 << 29)
+#elif defined(CONFIG_MESON_GXL)
+#define PUB_DTPR0 timings.rtp | \
+ (timings.rp << 8) | \
+ (timings.ras << 16) | \
+ (timings.rrd << 24)
+#define PUB_DTPR1 (timings.wlmrd << 24) | \
+ (timings.faw << 16) | \
+ timings.mrd
+#define PUB_DTPR2 timings.xs | \
+ (timings.cke << 16)
+#define PUB_DTPR3 (timings.dllk << 16) | (4 << 28)
+#define PUB_DTPR4 timings.xp | BIT(11) | (timings.rfc << 0x10)
+#define PUB_DTPR5 (timings.rc << 16) | (timings.rcd << 8) | \
+ timings.wtr
+#endif
+
+#if defined(CONFIG_MESON_GXBB)
+#define PUB_PGCR0 0x7D81E3F
+#define PUB_PGCR1 0x380C6A0
+#define PUB_PGCR2 (0x1F12480 & 0xefffffff)
+#define PUB_PGCR3 0xC0AAFE60
+#elif defined(CONFIG_MESON_GXL)
+#define PUB_PGCR0 0x7d81e3f
+#define PUB_PGCR1 0x2004620
+#define PUB_PGCR2 (0xf05f97 & 0xefffffff)
+#if defined(CONFIG_DRAM_DDR3)
+#define PUB_PGCR3 0xc0aae860
+#elif defined(CONFIG_DRAM_DDR4)
+#define PUB_PGCR3 0xc0aae860 | 0x4000000
+#endif
+#endif
+
+#if defined(CONFIG_MESON_GXBB)
+#define PUB_DXCCR 0x181884
+#define PUB_DTCR 0x4300308f
+#define PUB_DSGCR 0x20645A
+
+#define PUB_ZQ0PR 0x69
+#define PUB_ZQ1PR 0x69
+#define PUB_ZQ2PR 0x69
+#define PUB_ZQ3PR 0x69
+#elif defined(CONFIG_MESON_GXL)
+#define PUB_DXCCR 0x20c01204
+
+#if defined(CONFIG_DRAM_DDR4)
+#define PUB_DTCR 0x80003187 | 0x40
+#else
+#define PUB_DTCR 0x80003187
+#endif
+
+#define PUB_DTCR1 0x00010237 /* XXX: Needed? */
+#define PUB_DSGCR (0x20641b | 0x800004) /* Works on DDR4 too? */
+
+#if defined(CONFIG_DRAM_DDR3)
+#define PUB_ZQ0PR 0x5d95d
+#define PUB_ZQ1PR 0x5d95d
+#define PUB_ZQ2PR 0x5d95d
+#define PUB_ZQ3PR 0x1dd1d
+#elif defined(CONFIG_DRAM_DDR4)
+#define PUB_ZQ0PR 0x775d
+#define PUB_ZQ1PR 0x6fc5d
+#define PUB_ZQ2PR 0x6fc5d
+#define PUB_ZQ3PR 0x1dd1d
+#endif
+#endif
+
+#if defined(CONFIG_DRAM_DDR3)
+#define PUB_DCR 0xb
+#elif defined(CONFIG_DRAM_DDR4)
+#define PUB_DCR 0x1800040c
+#endif
+#define PUB_DTAR (0 | (0 << 12) | (0 << 28)) /* Uh? */
+
+#define PCTL0_1US_PCK 0x1C8
+#define PCTL0_100NS_PCK 0x2D
+#define PCTL0_INIT_US 0x2
+#define PCTL0_RSTH_US 0x2
+
+/* Mode Config(?) */
+#if defined(CONFIG_MESON_GXBB)
+#define PCTL0_MCFG ((((timings.faw + timings.rrd - 1) / timings.rrd) & 3) << 0x12) | \
+ (0xa2f21 & 0xfff3ffff)
+#define PCTL0_MCFG1 (((timings.rrd - ((timings.faw - (timings.faw / timings.rrd) * \
+ timings.rrd) & 0xff)) & 7) << 8) | \
+ (0x80200000 & 0xfffffcff)
+#elif defined(CONFIG_MESON_GXL)
+#if defined(CONFIG_DRAM_DDR3)
+#define PCTL0_MCFG_DDRTYPE 0
+#elif defined(CONFIG_DRAM_DDR4)
+#define PCTL0_MCFG_DDRTYPE BIT(4)
+#endif
+
+#define PCTL0_MCFG (0xa2f21 & 0xffffff8f) | PCTL0_MCFG_DDRTYPE
+/* XXX: What is this? ↓ ??? */
+#define PCTL0_MCFG1 0
+#endif
+
+#define PCTL0_SCFG 0xF01
+
+#if defined(CONFIG_MESON_GXL) && defined(CONFIG_DRAM_16BIT_RANK)
+#define PCTL0_PPCFG 0x1fd
+#else
+#define PCTL0_PPCFG 0x1e0
+#endif
+
+#define PCTL0_DFISTCFG0 0x4
+#define PCTL0_DFISTCFG1 0x1
+
+#define PCTL0_DFITCTRLDELAY 0x2
+
+#if defined(CONFIG_MESON_GXBB)
+#define PCTL0_DFITPHYWRDATA 0x1
+#else
+#define PCTL0_DFITPHYWRDATA 0x2
+#endif
+
+#if defined(CONFIG_MESON_GXBB)
+#define PCTL0_DFITPHYWRLTA (timings.cwl + timings.al - \
+ (((timings.cwl + timings.al) % 2) ? 3 : 4)) / 2
+#define PCTL0_DFITRDDATAEN (timings.cl + timings.al - \
+ (((timings.cl + timings.al) % 2) ? 3 : 4)) / 2
+#define PCTL0_DFITPHYRDLAT ((timings.cl + timings.al) % 2) ? 14 : 16
+#elif defined(CONFIG_MESON_GXL)
+#define PCTL0_DFITPHYWRLTA ((timings.cwl + timings.al) - 2)
+#define PCTL0_DFITRDDATAEN ((timings.cl + timings.al) - 4)
+#define PCTL0_DFITPHYRDLAT 0x16
+#endif
+
+#define PCTL0_DFITDRAMCLKDIS 1
+#define PCTL0_DFITDRAMCLKEN 1
+#if defined(CONFIG_MESON_GXBB)
+#define PCTL0_DFITPHYUPDTYPE1 0x200
+#else
+#define PCTL0_DFITPHYUPDTYPE0 16
+#define PCTL0_DFITPHYUPDTYPE1 16
+#define PCTL0_DFITCTRLUPDMAX 64
+#define PCTL0_DFIUPDCFG 3
+#endif
+#define PCTL0_DFITCTRLUPDMIN 16
+
+#define PCTL0_CMDTSTATEN 1
+
+#if defined(CONFIG_DRAM_ONE_RANK) || defined(CONFIG_DRAM_16BIT_RANK)
+#define PCTL0_DFIODTCFG 0x808
+#elif defined(CONFIG_DRAM_TWO_DIFF_RANKS)
+#define PCTL0_DFIODTCFG 0xc0c
+#elif defined(CONFIG_DRAM_TWO_IDENTICAL_RANKS)
+#define PCTL0_DFIODTCFG 0x8
+#endif
+
+#if defined(CONFIG_MESON_GXBB)
+#define PCTL0_DFIODTCFG1 (0 | (6 << 16))
+#elif defined(CONFIG_MESON_GXL)
+#if defined(CONFIG_DRAM_16BIT_RANK)
+#define PCTL0_DFIODTCFG1 ((6 << 16) | (8 << 16))
+#else
+#define PCTL0_DFIODTCFG1 ((6 << 16) | (3 << 25) | (8 << 16))
+#endif
+#endif
+#define PCTL0_DFILPCFG0 (1 | (3 << 4) | BIT(8) | (3 << 12) | \
+ (7 << 16) | BIT(24) | (3 << 28))
+
+#if defined(CONFIG_MESON_GXBB)
+#define PUB_ACBDLR0 0x10
+#elif defined(CONFIG_MESON_GXL)
+#if defined(CONFIG_DRAM_DDR3)
+#define PUB_ACBDLR0 0
+#define PUB_ACBDLR3 0
+#define PUB_ACLCDLR 48
+#elif defined(CONFIG_DRAM_DDR4)
+#define PUB_ACBDLR0 0x3f
+#define PUB_ACBDLR3 0x10
+#define PUB_ACLCDLR 0x28
+#else
+#define PUB_ACBDLR0 0
+#define PUB_ACBDLR3 0
+#define PUB_ACLCDLR 48
+#endif
+#endif
+
+#define LPDDR3_CA0 2
+#define LPDDR3_CA1 0
+#define LPDDR3_REMAP 3
+#define LPDDR3_WL 1
+
+/* PLL */
+#if defined(CONFIG_MESON_GXBB)
+#define DDR_PLL_CNTL1 0x69c80000
+#define DDR_PLL_CNTL2 0xca463823
+#define DDR_PLL_CNTL3 0xc00023
+#define DDR_PLL_CNTL4 0x303500
+#define DDR_PLL_CNTL5 0 /* Unused */
+#elif defined(CONFIG_MESON_GXL)
+#define DDR_PLL_CNTL1 0xaa203
+#define DDR_PLL_CNTL2 0x2919a288
+#define DDR_PLL_CNTL3 0x3e3b744
+#define DDR_PLL_CNTL4 0xc0101
+#define DDR_PLL_CNTL5 0xe600001e
+#endif
+
+#endif /* DRAM_SETTINGS_GX_H */
diff --git a/arch/arm/include/asm/arch-meson/dram-timings-gx.h b/arch/arm/include/asm/arch-meson/dram-timings-gx.h
new file mode 100644
index 00000000000..144b727e998
--- /dev/null
+++ b/arch/arm/include/asm/arch-meson/dram-timings-gx.h
@@ -0,0 +1,117 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2024, Ferass El Hafidi <[email protected]>
+ */
+#ifndef DRAM_TIMINGS_GX_H
+#define DRAM_TIMINGS_GX_H
+
+/*
+ * DRAM timings
+ * It looks like those are quite similar in regular boards based on reference
+ * designs and not using counterfeit RAM chips. Those are hacked around by lowbin
+ * TV box vendors to support lowbin RAM chips, however. Here, we are hardcoding
+ * timings, which *will* cause issues on lowbin boards, but should be fine on other
+ * boards derived from Amlogic reference designs.
+ */
+
+/*
+ * TODO:
+ * - Add timings for different DRAM clocks
+ * - Support overwriting those if board needs different timings (how?)
+ * - Other things
+ */
+
+#if defined(CONFIG_DRAM_DDR3)
+/* DDR3: 912 MHz */
+const struct meson_gx_dram_timings timings = {
+ .drv = 0,
+ .odt = 2,
+
+ /* Timings */
+ .rtp = 0x7,
+ .wtr = 0x7,
+ .rp = 0xd,
+ .rcd = 0xd,
+ .ras = 0x25,
+ .rrd = 0x7,
+ .rc = 0x34,
+ .mrd = 0x6, /* Should be < 8 */
+ .mod = 0x4,
+ .faw = 0x21,
+ .wlmrd = 0x28,
+ .wlo = 0x7,
+ .rfc = 0x118,
+ .xp = 0x7,
+ .xs = 0x200,
+ .dllk = 0x200,
+ .cke = 0x5,
+ .rtodt = 0x0,
+ .rtw = 0x7,
+ .refi = 0x4e,
+ .refi_mddr3 = 0x4,
+ .cl = 0xd,
+ .wr = 0x10,
+ .cwl = 0x9,
+ .al = 0x0,
+ .dqs = 0x17,
+ .cksre = 0xf,
+ .cksrx = 0xf,
+ .zqcs = 0x40,
+ .xpdll = 0x17,
+ .exsr = 0x200, /* Should be < 0x3ff */
+ .zqcl = 0x88,
+ .zqcsi = 0x3e8,
+ .rpab = 0x0,
+ .rppb = 0x0,
+ .tdqsck = 0x0,
+ .tdqsckmax = 0x0,
+ .tckesr = 0x0,
+ .tdpd = 0x0,
+ .taond_aofd = 0x0,
+ .tccdl = 0, /* Unused on GXBB */
+};
+
+#elif defined(CONFIG_DRAM_DDR4)
+/* DDR4: 1080 MHz */
+const struct meson_gx_dram_timings timings = {
+ .drv = 1,
+ .odt = 1,
+
+ /* Timings */
+ .rtp = 9,
+ .wtr = 9,
+ .rp = 0x10, // ddr_clk < 1200
+ .rcd = 0x10, // ddr_clk < 1200
+ .ras = 35 * 1.2,
+ .rrd = 6,
+ .rc = 0x3a,
+ .mrd = 8,
+ .mod = 24,
+ .faw = 35 * 1.2,
+ .rfc = 350 * 1.2,
+ .wlmrd = 40,
+ .wlo = 9.5 * 1.2,
+ .xs = 512,
+ .xp = 7,
+ .cke = 5,
+ .dllk = 1024,
+ .rtodt = 0,
+ .rtw = 8,
+ .refi = 76,
+ .refi_mddr3 = 4,
+ .cl = 0x10, // ddr_clk < 1200
+ .wr = 0x12,
+ .cwl = 12,
+ .al = 0,
+ .exsr = 1024,
+ .dqs = 9,
+ .cksre = 15,
+ .cksrx = 15,
+ .zqcs = 128,
+ .zqcl = 256,
+ .xpdll = 23,
+ .zqcsi = 1000,
+ .tccdl = 6, // ddr_clk < 1200
+};
+#endif
+#endif