Move the H616 PHY init tables into the per-DRAM-type timing files and expose helpers to select the timing and PHY initialisation data from the current DRAM parameters.
Also make ns_to_t() use dram_para->clk instead of CONFIG_DRAM_CLK so a future caller can select the backend at runtime. Keep the existing fixed-profile Kconfig selection and linkage unchanged by doing the dispatch in inline helpers, so current H616 boards still build with only their selected backend linked in. Signed-off-by: James Hilliard <[email protected]> --- .../include/asm/arch-sunxi/dram_sun50i_h616.h | 39 ++++++++++++-- arch/arm/mach-sunxi/dram_sun50i_h616.c | 42 +-------------- .../mach-sunxi/dram_timings/h616_ddr3_1333.c | 54 +++++++++++++------ .../arm/mach-sunxi/dram_timings/h616_lpddr3.c | 54 +++++++++++++------ .../dram_timings/h616_lpddr4_2133.c | 54 +++++++++++++------ 5 files changed, 152 insertions(+), 91 deletions(-) diff --git a/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h b/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h index a8fdda124a0..6dab3b4832b 100644 --- a/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h +++ b/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h @@ -168,13 +168,46 @@ struct dram_config { u8 bus_full_width; }; -static inline int ns_to_t(int nanoseconds) +#define H616_PHY_INIT_LEN 27 + +static inline int ns_to_t(const struct dram_para *para, int nanoseconds) { - const unsigned int ctrl_freq = CONFIG_DRAM_CLK / 2; + const unsigned int ctrl_freq = para->clk / 2; return DIV_ROUND_UP(ctrl_freq * nanoseconds, 1000); } -void mctl_set_timing_params(const struct dram_para *para); +void h616_ddr3_set_timing_params(const struct dram_para *para); +void h616_lpddr3_set_timing_params(const struct dram_para *para); +void h616_lpddr4_set_timing_params(const struct dram_para *para); + +const u8 *h616_ddr3_get_phy_init(void); +const u8 *h616_lpddr3_get_phy_init(void); +const u8 *h616_lpddr4_get_phy_init(void); + +static inline void mctl_set_timing_params(const struct dram_para *para) +{ +#ifdef CONFIG_SUNXI_DRAM_H616_DDR3_1333 + h616_ddr3_set_timing_params(para); +#elif defined(CONFIG_SUNXI_DRAM_H616_LPDDR3) + h616_lpddr3_set_timing_params(para); +#elif defined(CONFIG_SUNXI_DRAM_H616_LPDDR4) + h616_lpddr4_set_timing_params(para); +#endif +} + +static inline const u8 *h616_get_phy_init(const struct dram_para *para) +{ + (void)para; + +#ifdef CONFIG_SUNXI_DRAM_H616_DDR3_1333 + return h616_ddr3_get_phy_init(); +#elif defined(CONFIG_SUNXI_DRAM_H616_LPDDR3) + return h616_lpddr3_get_phy_init(); +#elif defined(CONFIG_SUNXI_DRAM_H616_LPDDR4) + return h616_lpddr4_get_phy_init(); +#endif + return NULL; +} #endif /* _SUNXI_DRAM_SUN50I_H616_H */ diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c b/arch/arm/mach-sunxi/dram_sun50i_h616.c index 3345c9b8e82..c3e1286fb35 100644 --- a/arch/arm/mach-sunxi/dram_sun50i_h616.c +++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c @@ -227,45 +227,6 @@ static void mctl_set_addrmap(const struct dram_config *config) mctl_ctl->addrmap[8] = 0x3F3F; } -#ifdef CONFIG_DRAM_SUNXI_PHY_ADDR_MAP_1 -static const u8 phy_init[] = { -#ifdef CONFIG_SUNXI_DRAM_H616_DDR3_1333 - 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, 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) - 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 -}; -#else /* CONFIG_DRAM_SUNXI_PHY_ADDR_MAP_0 */ -static const u8 phy_init[] = { -#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 -#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 -#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 -#endif -}; -#endif /* CONFIG_DRAM_SUNXI_PHY_ADDR_MAP_0 */ #define MASK_BYTE(reg, nr) (((reg) >> ((nr) * 8)) & 0x1f) static void mctl_phy_configure_odt(const struct dram_para *para) { @@ -908,6 +869,7 @@ static bool mctl_phy_init(const struct dram_para *para, (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE; struct sunxi_mctl_ctl_reg * const mctl_ctl = (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE; + const u8 *phy_init = h616_get_phy_init(para); u32 val, val2, *ptr, mr0, mr2; int i; @@ -964,7 +926,7 @@ 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++) + for (i = 0; i < H616_PHY_INIT_LEN; i++) writel(phy_init[i], &ptr[i]); if (para->tpr10 & TPR10_CA_BIT_DELAY) 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 3faf8d5bd97..20c90f20cb9 100644 --- a/arch/arm/mach-sunxi/dram_timings/h616_ddr3_1333.c +++ b/arch/arm/mach-sunxi/dram_timings/h616_ddr3_1333.c @@ -14,33 +14,55 @@ #include <asm/arch/dram.h> #include <asm/arch/cpu.h> -void mctl_set_timing_params(const struct dram_para *para) +static const u8 h616_ddr3_phy_init_default[H616_PHY_INIT_LEN] = { + 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 +}; + +static const u8 h616_ddr3_phy_init_addr_map_1[H616_PHY_INIT_LEN] = { + 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 +}; + +const u8 *h616_ddr3_get_phy_init(void) +{ + if (IS_ENABLED(CONFIG_DRAM_SUNXI_PHY_ADDR_MAP_1)) + return h616_ddr3_phy_init_addr_map_1; + + return h616_ddr3_phy_init_default; +} + +void h616_ddr3_set_timing_params(const struct dram_para *para) { struct sunxi_mctl_ctl_reg * const mctl_ctl = (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE; u8 tccd = 2; /* JEDEC: 4nCK */ - u8 tfaw = ns_to_t(50); /* JEDEC: 30 ns w/ 1K pages */ - 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 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 */ - u16 trfc = ns_to_t(350); /* JEDEC: 160 ns for 2Gb */ + u8 tfaw = ns_to_t(para, 50); /* JEDEC: 30 ns w/ 1K pages */ + u8 trrd = max(ns_to_t(para, 6), 4); /* JEDEC: max(6 ns, 4nCK) */ + u8 trcd = ns_to_t(para, 15); /* JEDEC: 13.5 ns */ + u8 trc = ns_to_t(para, 53); /* JEDEC: 49.5 ns */ + u8 txp = max(ns_to_t(para, 6), 3); /* JEDEC: max(6 ns, 3nCK) */ + u8 trtp = max(ns_to_t(para, 8), 2); /* JEDEC: max(7.5 ns, 4nCK) */ + u8 trp = ns_to_t(para, 15); /* JEDEC: >= 13.75 ns */ + u8 tras = ns_to_t(para, 38); /* JEDEC >= 36 ns, <= 9*trefi */ + u16 trefi = ns_to_t(para, 7800) / 32; /* JEDEC: 7.8us@Tcase <= 85C */ + u16 trfc = ns_to_t(para, 350); /* JEDEC: 160 ns for 2Gb */ u16 txsr = 4; /* ? */ u8 tmrw = 0; /* ? */ u8 tmrd = 4; /* JEDEC: 4nCK */ - u8 tmod = max(ns_to_t(15), 12); /* JEDEC: max(15 ns, 12nCK) */ - u8 tcke = max(ns_to_t(6), 3); /* JEDEC: max(5.625 ns, 3nCK) */ - u8 tcksrx = max(ns_to_t(10), 4); /* JEDEC: max(10 ns, 5nCK) */ - u8 tcksre = max(ns_to_t(10), 4); /* JEDEC: max(10 ns, 5nCK) */ + u8 tmod = max(ns_to_t(para, 15), 12); /* JEDEC: max(15 ns, 12nCK) */ + u8 tcke = max(ns_to_t(para, 6), 3); /* JEDEC: max(5.625 ns, 3nCK) */ + u8 tcksrx = max(ns_to_t(para, 10), 4); /* JEDEC: max(10 ns, 5nCK) */ + u8 tcksre = max(ns_to_t(para, 10), 4); /* JEDEC: max(10 ns, 5nCK) */ u8 tckesr = tcke + 1; /* JEDEC: tCKE(min) + 1nCK */ u8 trasmax = (para->clk / 2) / 15; /* JEDEC: tREFI * 9 */ - u8 txs = ns_to_t(360) / 32; /* JEDEC: max(5nCK,tRFC+10ns) */ + u8 txs = ns_to_t(para, 360) / 32; /* JEDEC: max(5nCK,tRFC+10ns) */ u8 txsdll = 16; /* JEDEC: 512 nCK */ u8 txsabort = 4; /* ? */ u8 txsfast = 4; /* ? */ diff --git a/arch/arm/mach-sunxi/dram_timings/h616_lpddr3.c b/arch/arm/mach-sunxi/dram_timings/h616_lpddr3.c index ce2ffa7a020..23b29cc973c 100644 --- a/arch/arm/mach-sunxi/dram_timings/h616_lpddr3.c +++ b/arch/arm/mach-sunxi/dram_timings/h616_lpddr3.c @@ -14,33 +14,55 @@ #include <asm/arch/dram.h> #include <asm/arch/cpu.h> -void mctl_set_timing_params(const struct dram_para *para) +static const u8 h616_lpddr3_phy_init_default[H616_PHY_INIT_LEN] = { + 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 +}; + +static const u8 h616_lpddr3_phy_init_addr_map_1[H616_PHY_INIT_LEN] = { + 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 +}; + +const u8 *h616_lpddr3_get_phy_init(void) +{ + if (IS_ENABLED(CONFIG_DRAM_SUNXI_PHY_ADDR_MAP_1)) + return h616_lpddr3_phy_init_addr_map_1; + + return h616_lpddr3_phy_init_default; +} + +void h616_lpddr3_set_timing_params(const struct dram_para *para) { struct sunxi_mctl_ctl_reg * const mctl_ctl = (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE; u8 tccd = 2; - u8 tfaw = ns_to_t(50); - 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 trp = ns_to_t(27); - u8 tras = ns_to_t(41); - u16 trefi = ns_to_t(7800) / 64; - u16 trfc = ns_to_t(210); + u8 tfaw = ns_to_t(para, 50); + u8 trrd = max(ns_to_t(para, 6), 4); + u8 trcd = ns_to_t(para, 24); + u8 trc = ns_to_t(para, 70); + u8 txp = max(ns_to_t(para, 8), 3); + u8 trtp = max(ns_to_t(para, 8), 2); + u8 trp = ns_to_t(para, 27); + u8 tras = ns_to_t(para, 41); + u16 trefi = ns_to_t(para, 7800) / 64; + u16 trfc = ns_to_t(para, 210); u16 txsr = 88; u8 tmrw = 5; u8 tmrd = 5; - u8 tmod = max(ns_to_t(15), 12); - u8 tcke = max(ns_to_t(6), 3); - u8 tcksrx = max(ns_to_t(12), 4); - u8 tcksre = max(ns_to_t(12), 4); + u8 tmod = max(ns_to_t(para, 15), 12); + u8 tcke = max(ns_to_t(para, 6), 3); + u8 tcksrx = max(ns_to_t(para, 12), 4); + u8 tcksre = max(ns_to_t(para, 12), 4); u8 tckesr = tcke + 2; u8 trasmax = (para->clk / 2) / 16; - u8 txs = ns_to_t(360) / 32; + u8 txs = ns_to_t(para, 360) / 32; u8 txsdll = 16; u8 txsabort = 4; u8 txsfast = 4; 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 6f5c4acbd62..c19ae025f75 100644 --- a/arch/arm/mach-sunxi/dram_timings/h616_lpddr4_2133.c +++ b/arch/arm/mach-sunxi/dram_timings/h616_lpddr4_2133.c @@ -12,30 +12,52 @@ #include <asm/arch/dram.h> #include <asm/arch/cpu.h> -void mctl_set_timing_params(const struct dram_para *para) +static const u8 h616_lpddr4_phy_init_default[H616_PHY_INIT_LEN] = { + 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 +}; + +static const u8 h616_lpddr4_phy_init_addr_map_1[H616_PHY_INIT_LEN] = { + 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 +}; + +const u8 *h616_lpddr4_get_phy_init(void) +{ + if (IS_ENABLED(CONFIG_DRAM_SUNXI_PHY_ADDR_MAP_1)) + return h616_lpddr4_phy_init_addr_map_1; + + return h616_lpddr4_phy_init_default; +} + +void h616_lpddr4_set_timing_params(const struct dram_para *para) { struct sunxi_mctl_ctl_reg * const mctl_ctl = (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE; u8 tccd = 4; - u8 tfaw = ns_to_t(40); - u8 trrd = max(ns_to_t(10), 2); - u8 trcd = max(ns_to_t(18), 2); - u8 trc = ns_to_t(65); - u8 txp = max(ns_to_t(8), 2); + u8 tfaw = ns_to_t(para, 40); + u8 trrd = max(ns_to_t(para, 10), 2); + u8 trcd = max(ns_to_t(para, 18), 2); + u8 trc = ns_to_t(para, 65); + u8 txp = max(ns_to_t(para, 8), 2); u8 trtp = 4; - u8 trp = ns_to_t(21); - u8 tras = ns_to_t(42); - u16 trefi = ns_to_t(3904) / 32; - u16 trfc = ns_to_t(280); - u16 txsr = ns_to_t(190); + u8 trp = ns_to_t(para, 21); + u8 tras = ns_to_t(para, 42); + u16 trefi = ns_to_t(para, 3904) / 32; + u16 trfc = ns_to_t(para, 280); + u16 txsr = ns_to_t(para, 190); - u8 tmrw = max(ns_to_t(14), 5); + u8 tmrw = max(ns_to_t(para, 14), 5); u8 tmrd = tmrw; u8 tmod = 12; - u8 tcke = max(ns_to_t(15), 2); - u8 tcksrx = max(ns_to_t(2), 2); - u8 tcksre = max(ns_to_t(5), 2); + u8 tcke = max(ns_to_t(para, 15), 2); + u8 tcksrx = max(ns_to_t(para, 2), 2); + u8 tcksre = max(ns_to_t(para, 5), 2); u8 tckesr = tcke; u8 trasmax = (trefi * 9) / 32; u8 txs = 4; @@ -49,7 +71,7 @@ void mctl_set_timing_params(const struct dram_para *para) u8 twtp = 24; u8 twr2rd = max(trrd, (u8)4) + 14; - u8 trd2wr = (ns_to_t(4) + 17) - ns_to_t(1); + u8 trd2wr = (ns_to_t(para, 4) + 17) - ns_to_t(para, 1); /* set DRAM timing */ writel((twtp << 24) | (tfaw << 16) | (trasmax << 8) | tras, -- 2.43.0

