From: Viorel Suman <viorel.su...@nxp.com> Collect errata registers values after the training and restore errata registers values before starting quick boot firmware.
Signed-off-by: Viorel Suman <viorel.su...@nxp.com> Reviewed-by: Tom Zheng <haidong.zh...@nxp.com> Reviewed-by: Ye Li <ye...@nxp.com> Tested-by: Florin Pavelescu <florin.pavele...@nxp.com> Signed-off-by: Peng Fan <peng....@nxp.com> --- arch/arm/include/asm/arch-imx9/ddr.h | 5 ++++- drivers/ddr/imx/phy/Makefile | 4 ++-- drivers/ddr/imx/phy/ddrphy_qb.c | 4 ++++ drivers/ddr/imx/phy/ddrphy_qb_errata.c | 39 ++++++++++++++++++++++++++++++++++ drivers/ddr/imx/phy/ddrphy_qb_gen.c | 3 +++ 5 files changed, 52 insertions(+), 3 deletions(-) diff --git a/arch/arm/include/asm/arch-imx9/ddr.h b/arch/arm/include/asm/arch-imx9/ddr.h index 6e5a3e3b6793d0171c2fbe6415821968ac1d3ba4..e30274035ca620fbcee46932b33374055aba3378 100644 --- a/arch/arm/include/asm/arch-imx9/ddr.h +++ b/arch/arm/include/asm/arch-imx9/ddr.h @@ -103,6 +103,7 @@ extern struct dram_timing_info dram_timing; #if (defined(CONFIG_IMX_SNPS_DDR_PHY_QB_GEN) || defined(CONFIG_IMX_SNPS_DDR_PHY_QB)) #define DDRPHY_QB_FSP_SIZE 3 +#define DDRPHY_QB_ERR_SIZE 6 #define DDRPHY_QB_CSR_SIZE 1792 #define DDRPHY_QB_FLAG_2D BIT(0) /* =1 if First boot used 2D training, =0 otherwise */ @@ -110,13 +111,15 @@ struct ddrphy_qb_state { u32 crc; u32 flags; u32 fsp[DDRPHY_QB_FSP_SIZE]; + u32 err[DDRPHY_QB_ERR_SIZE]; u32 csr[DDRPHY_QB_CSR_SIZE]; }; #define DDRPHY_QB_STATE_SIZE \ - (sizeof(u32) * (1 + DDRPHY_QB_FSP_SIZE + DDRPHY_QB_CSR_SIZE)) + (sizeof(u32) * (1 + DDRPHY_QB_FSP_SIZE + DDRPHY_QB_ERR_SIZE + DDRPHY_QB_CSR_SIZE)) extern struct ddrphy_qb_state qb_state; +extern const u32 ddrphy_err_cfg[DDRPHY_QB_ERR_SIZE]; #if defined(CONFIG_IMX_SNPS_DDR_PHY_QB_GEN) int ddrphy_qb_save(void); diff --git a/drivers/ddr/imx/phy/Makefile b/drivers/ddr/imx/phy/Makefile index 2310e69ab5c3036a2903465f4c4e95a79bf0b2c5..75c11625e8a23152e81700b747b216338af1406b 100644 --- a/drivers/ddr/imx/phy/Makefile +++ b/drivers/ddr/imx/phy/Makefile @@ -6,6 +6,6 @@ ifdef CONFIG_XPL_BUILD obj-$(CONFIG_IMX_SNPS_DDR_PHY) += helper.o ddrphy_utils.o ddrphy_train.o -obj-$(CONFIG_IMX_SNPS_DDR_PHY_QB_GEN) += ddrphy_qb_gen.o -obj-$(CONFIG_IMX_SNPS_DDR_PHY_QB) += ddrphy_qb.o +obj-$(CONFIG_IMX_SNPS_DDR_PHY_QB_GEN) += ddrphy_qb_gen.o ddrphy_qb_errata.o +obj-$(CONFIG_IMX_SNPS_DDR_PHY_QB) += ddrphy_qb.o ddrphy_qb_errata.o endif diff --git a/drivers/ddr/imx/phy/ddrphy_qb.c b/drivers/ddr/imx/phy/ddrphy_qb.c index 04a6520be5464ac26e30a516265b1b6993eec38c..2bd34bf91fad46e41b3581d79db3523b5442654e 100644 --- a/drivers/ddr/imx/phy/ddrphy_qb.c +++ b/drivers/ddr/imx/phy/ddrphy_qb.c @@ -47,6 +47,10 @@ static int ddrphy_qb_restore(struct dram_timing_info *info, int fsp_id) ddrphy_w(0x5403c, 0x78, qb_state.fsp[2] >> 8); /* TrainedVREFDQ_B1 -> MR14_B1 */ } + /* restore errata registers */ + for (i = 0; i < DDRPHY_QB_ERR_SIZE; i++) + dwc_ddrphy_apb_wr(ddrphy_err_cfg[i], qb_state.err[i]); + /* save CSRs to address starting with 0x54800 */ for (i = 0, to_addr = 0x54800; i < DDRPHY_QB_CSR_SIZE; i++, to_addr++) dwc_ddrphy_apb_wr(to_addr, qb_state.csr[i]); diff --git a/drivers/ddr/imx/phy/ddrphy_qb_errata.c b/drivers/ddr/imx/phy/ddrphy_qb_errata.c new file mode 100644 index 0000000000000000000000000000000000000000..91843ab2d939fc973af35ce07a63b1b375463b92 --- /dev/null +++ b/drivers/ddr/imx/phy/ddrphy_qb_errata.c @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2025 NXP + */ + +#include <asm/arch/ddr.h> +#include <linux/types.h> + +/** Errata CSRs + * STAR_3141216 0x020021 -> in ddrphy_csr_cfg + * STAR_3256585 0x02000b -> in ddrphy_csr_cfg + * 0x12000b -> in ddrphy_csr_cfg + * 0x22000b -> in ddrphy_csr_cfg + * STAR_3975199 0x0200c7 + * 0x0200ca + * 0x1200c7 + * 0x1200ca + * 0x2200c7 + * 0x2200ca + * STAR_4101789 0x0200c7 -> covered by STAR_3975199 + * 0x0200c5 -> in ddrphy_csr_cfg + * 0x1200c7 -> covered by STAR_3975199 + * 0x1200c5 -> in ddrphy_csr_cfg + * 0x2200c7 -> covered by STAR_3975199 + * 0x2200c5 -> in ddrphy_csr_cfg + */ + +/** + * All from STAR_3975199, the remaining errata registers + * are covered by either ddrphy_csr_cfg or STAR_3975199 + */ +const u32 ddrphy_err_cfg[DDRPHY_QB_ERR_SIZE] = { + 0x000200c7, + 0x000200ca, + 0x001200c7, + 0x001200ca, + 0x002200c7, + 0x002200ca, +}; diff --git a/drivers/ddr/imx/phy/ddrphy_qb_gen.c b/drivers/ddr/imx/phy/ddrphy_qb_gen.c index d77bb8480d85770d29e4408c2a723b20377833f0..981bfa88dc59c69905d14ffc6cfad4a92da35843 100644 --- a/drivers/ddr/imx/phy/ddrphy_qb_gen.c +++ b/drivers/ddr/imx/phy/ddrphy_qb_gen.c @@ -1819,6 +1819,9 @@ int ddrphy_qb_save(void) /* enable the ddrphy apb */ dwc_ddrphy_apb_wr(0xd0000, 0x0); + for (i = 0; i < DDRPHY_QB_ERR_SIZE; i++) + qb_state.err[i] = dwc_ddrphy_apb_rd(ddrphy_err_cfg[i]); + for (i = 0; i < DDRPHY_QB_CSR_SIZE; i++) qb_state.csr[i] = dwc_ddrphy_apb_rd(ddrphy_csr_cfg[i]); -- 2.35.3