diff options
Diffstat (limited to 'drivers/ddr/imx8m')
-rw-r--r-- | drivers/ddr/imx8m/Kconfig | 7 | ||||
-rw-r--r-- | drivers/ddr/imx8m/Makefile | 7 | ||||
-rw-r--r-- | drivers/ddr/imx8m/ddr_init.c | 214 | ||||
-rw-r--r-- | drivers/ddr/imx8m/ddrphy_csr.c | 734 | ||||
-rw-r--r-- | drivers/ddr/imx8m/ddrphy_train.c | 131 | ||||
-rw-r--r-- | drivers/ddr/imx8m/ddrphy_utils.c | 529 | ||||
-rw-r--r-- | drivers/ddr/imx8m/helper.c | 88 |
7 files changed, 0 insertions, 1710 deletions
diff --git a/drivers/ddr/imx8m/Kconfig b/drivers/ddr/imx8m/Kconfig deleted file mode 100644 index efc50c21d4..0000000000 --- a/drivers/ddr/imx8m/Kconfig +++ /dev/null @@ -1,7 +0,0 @@ -menu "i.MX8M DDR controllers" - depends on ARCH_IMX8MQ || ARCH_IMX8MM || ARCH_IMX8MN || ARCH_IMX8MP - -config IMX8M_DRAM - bool "imx8m dram controller support" - -endmenu diff --git a/drivers/ddr/imx8m/Makefile b/drivers/ddr/imx8m/Makefile deleted file mode 100644 index 2be313900f..0000000000 --- a/drivers/ddr/imx8m/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# -# Copyright 2018 NXP -# -# SPDX-License-Identifier: GPL-2.0+ -# - -pbl-$(CONFIG_IMX8M_DRAM) += helper.o ddrphy_utils.o ddrphy_train.o ddrphy_csr.o ddr_init.o diff --git a/drivers/ddr/imx8m/ddr_init.c b/drivers/ddr/imx8m/ddr_init.c deleted file mode 100644 index 95ac76efcd..0000000000 --- a/drivers/ddr/imx8m/ddr_init.c +++ /dev/null @@ -1,214 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright 2018-2019 NXP - */ - -#define pr_fmt(fmt) "imx8m-ddr: " fmt - -#include <common.h> -#include <errno.h> -#include <io.h> -#include <soc/imx8m/ddr.h> -#include <mach/generic.h> -#include <mach/imx8m-regs.h> -#include <mach/imx8m-ccm-regs.h> - -static void ddr_cfg_umctl2(struct dram_cfg_param *ddrc_cfg, int num) -{ - int i = 0; - - for (i = 0; i < num; i++) { - reg32_write((unsigned long)ddrc_cfg->reg, ddrc_cfg->val); - ddrc_cfg++; - } -} - -/* - * We store the timing parameters here. the TF-A will pick these up. - * Note that the timing used we leave the driver with is a PLL bypass 25MHz - * mode. So if your board runs horribly slow you'll likely have to provide a - * TF-A binary. - */ -#define IMX8M_SAVED_DRAM_TIMING_BASE 0x180000 - -static int imx8m_ddr_init(struct dram_timing_info *dram_timing, - enum ddrc_type type) -{ - unsigned long src_ddrc_rcr = MX8M_SRC_DDRC_RCR_ADDR; - unsigned int tmp, initial_drate, target_freq; - int ret; - - pr_debug("start DRAM init\n"); - - /* Step1: Follow the power up procedure */ - switch (type) { - case DDRC_TYPE_MQ: - reg32_write(src_ddrc_rcr + 0x04, 0x8f00000f); - reg32_write(src_ddrc_rcr, 0x8f00000f); - reg32_write(src_ddrc_rcr + 0x04, 0x8f000000); - break; - case DDRC_TYPE_MM: - case DDRC_TYPE_MN: - case DDRC_TYPE_MP: - reg32_write(src_ddrc_rcr, 0x8f00001f); - reg32_write(src_ddrc_rcr, 0x8f00000f); - break; - } - - pr_debug("cfg clk\n"); - - /* disable iso */ - reg32_write(0x303A00EC, 0x0000ffff); /* PGC_CPU_MAPPING */ - reg32setbit(0x303A00F8, 5); /* PU_PGC_SW_PUP_REQ */ - - initial_drate = dram_timing->fsp_msg[0].drate; - /* default to the frequency point 0 clock */ - ddrphy_init_set_dfi_clk(initial_drate, type); - - /* D-aasert the presetn */ - reg32_write(src_ddrc_rcr, 0x8F000006); - - /* Step2: Program the dwc_ddr_umctl2 registers */ - pr_debug("ddrc config start\n"); - ddr_cfg_umctl2(dram_timing->ddrc_cfg, dram_timing->ddrc_cfg_num); - pr_debug("ddrc config done\n"); - - /* Step3: De-assert reset signal(core_ddrc_rstn & aresetn_n) */ - reg32_write(src_ddrc_rcr, 0x8F000004); - reg32_write(src_ddrc_rcr, 0x8F000000); - - /* - * Step4: Disable auto-refreshes, self-refresh, powerdown, and - * assertion of dfi_dram_clk_disable by setting RFSHCTL3.dis_auto_refresh = 1, - * PWRCTL.powerdown_en = 0, and PWRCTL.selfref_en = 0, - * PWRCTL.en_dfi_dram_clk_disable = 0 - */ - reg32_write(DDRC_DBG1(0), 0x00000000); - reg32_write(DDRC_RFSHCTL3(0), 0x0000001); - reg32_write(DDRC_PWRCTL(0), 0xa0); - - /* if ddr type is LPDDR4, do it */ - tmp = reg32_read(DDRC_MSTR(0)); - if (tmp & (0x1 << 5) && type != DDRC_TYPE_MN) - reg32_write(DDRC_DDR_SS_GPR0, 0x01); /* LPDDR4 mode */ - - /* determine the initial boot frequency */ - target_freq = reg32_read(DDRC_MSTR2(0)) & 0x3; - target_freq = (tmp & (0x1 << 29)) ? target_freq : 0x0; - - /* Step5: Set SWCT.sw_done to 0 */ - reg32_write(DDRC_SWCTL(0), 0x00000000); - - /* Set the default boot frequency point */ - clrsetbits_le32(DDRC_DFIMISC(0), (0x1f << 8), target_freq << 8); - /* Step6: Set DFIMISC.dfi_init_complete_en to 0 */ - clrbits_le32(DDRC_DFIMISC(0), 0x1); - - /* Step7: Set SWCTL.sw_done to 1; need to polling SWSTAT.sw_done_ack */ - reg32_write(DDRC_SWCTL(0), 0x00000001); - do { - tmp = reg32_read(DDRC_SWSTAT(0)); - } while ((tmp & 0x1) == 0x0); - - /* - * Step8 ~ Step13: Start PHY initialization and training by - * accessing relevant PUB registers - */ - pr_debug("ddrphy config start\n"); - - ret = ddr_cfg_phy(dram_timing, type); - if (ret) - return ret; - - pr_debug("ddrphy config done\n"); - - /* - * step14 CalBusy.0 =1, indicates the calibrator is actively - * calibrating. Wait Calibrating done. - */ - do { - tmp = reg32_read(DDRPHY_CalBusy(0)); - } while ((tmp & 0x1)); - - pr_debug("ddrphy calibration done\n"); - - /* Step15: Set SWCTL.sw_done to 0 */ - reg32_write(DDRC_SWCTL(0), 0x00000000); - - /* Apply rank-to-rank workaround */ - update_umctl2_rank_space_setting(dram_timing->fsp_msg_num - 1, type); - - /* Step16: Set DFIMISC.dfi_init_start to 1 */ - setbits_le32(DDRC_DFIMISC(0), (0x1 << 5)); - - /* Step17: Set SWCTL.sw_done to 1; need to polling SWSTAT.sw_done_ack */ - reg32_write(DDRC_SWCTL(0), 0x00000001); - do { - tmp = reg32_read(DDRC_SWSTAT(0)); - } while ((tmp & 0x1) == 0x0); - - /* Step18: Polling DFISTAT.dfi_init_complete = 1 */ - do { - tmp = reg32_read(DDRC_DFISTAT(0)); - } while ((tmp & 0x1) == 0x0); - - /* Step19: Set SWCTL.sw_done to 0 */ - reg32_write(DDRC_SWCTL(0), 0x00000000); - - /* Step20: Set DFIMISC.dfi_init_start to 0 */ - clrbits_le32(DDRC_DFIMISC(0), (0x1 << 5)); - - /* Step21: optional */ - - /* Step22: Set DFIMISC.dfi_init_complete_en to 1 */ - setbits_le32(DDRC_DFIMISC(0), 0x1); - - /* Step23: Set PWRCTL.selfref_sw to 0 */ - clrbits_le32(DDRC_PWRCTL(0), (0x1 << 5)); - - /* Step24: Set SWCTL.sw_done to 1; need polling SWSTAT.sw_done_ack */ - reg32_write(DDRC_SWCTL(0), 0x00000001); - do { - tmp = reg32_read(DDRC_SWSTAT(0)); - } while ((tmp & 0x1) == 0x0); - - /* Step25: Wait for dwc_ddr_umctl2 to move to normal operating mode by monitoring - * STAT.operating_mode signal */ - do { - tmp = reg32_read(DDRC_STAT(0)); - } while ((tmp & 0x3) != 0x1); - - /* Step26: Set back register in Step4 to the original values if desired */ - reg32_write(DDRC_RFSHCTL3(0), 0x0000000); - /* enable selfref_en by default */ - setbits_le32(DDRC_PWRCTL(0), 0x1); - - /* enable port 0 */ - reg32_write(DDRC_PCTRL_0(0), 0x00000001); - pr_debug(" ddrmix config done\n"); - - /* save the dram timing config into memory */ - dram_config_save(dram_timing, IMX8M_SAVED_DRAM_TIMING_BASE); - - return 0; -} - -int imx8mm_ddr_init(struct dram_timing_info *dram_timing) -{ - return imx8m_ddr_init(dram_timing, DDRC_TYPE_MM); -} - -int imx8mn_ddr_init(struct dram_timing_info *dram_timing) -{ - return imx8m_ddr_init(dram_timing, DDRC_TYPE_MN); -} - -int imx8mq_ddr_init(struct dram_timing_info *dram_timing) -{ - return imx8m_ddr_init(dram_timing, DDRC_TYPE_MQ); -} - -int imx8mp_ddr_init(struct dram_timing_info *dram_timing) -{ - return imx8m_ddr_init(dram_timing, DDRC_TYPE_MP); -} diff --git a/drivers/ddr/imx8m/ddrphy_csr.c b/drivers/ddr/imx8m/ddrphy_csr.c deleted file mode 100644 index 2e08d111be..0000000000 --- a/drivers/ddr/imx8m/ddrphy_csr.c +++ /dev/null @@ -1,734 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright 2018 NXP - */ - -#define pr_fmt(fmt) "imx8m-ddr: " fmt - -#include <linux/kernel.h> -#include <soc/imx8m/ddr.h> - -/* ddr phy trained csr */ -struct dram_cfg_param ddrphy_trained_csr[] = { - { 0x200b2, 0x0 }, - { 0x1200b2, 0x0 }, - { 0x2200b2, 0x0 }, - { 0x200cb, 0x0 }, - { 0x10043, 0x0 }, - { 0x110043, 0x0 }, - { 0x210043, 0x0 }, - { 0x10143, 0x0 }, - { 0x110143, 0x0 }, - { 0x210143, 0x0 }, - { 0x11043, 0x0 }, - { 0x111043, 0x0 }, - { 0x211043, 0x0 }, - { 0x11143, 0x0 }, - { 0x111143, 0x0 }, - { 0x211143, 0x0 }, - { 0x12043, 0x0 }, - { 0x112043, 0x0 }, - { 0x212043, 0x0 }, - { 0x12143, 0x0 }, - { 0x112143, 0x0 }, - { 0x212143, 0x0 }, - { 0x13043, 0x0 }, - { 0x113043, 0x0 }, - { 0x213043, 0x0 }, - { 0x13143, 0x0 }, - { 0x113143, 0x0 }, - { 0x213143, 0x0 }, - { 0x80, 0x0 }, - { 0x100080, 0x0 }, - { 0x200080, 0x0 }, - { 0x1080, 0x0 }, - { 0x101080, 0x0 }, - { 0x201080, 0x0 }, - { 0x2080, 0x0 }, - { 0x102080, 0x0 }, - { 0x202080, 0x0 }, - { 0x3080, 0x0 }, - { 0x103080, 0x0 }, - { 0x203080, 0x0 }, - { 0x4080, 0x0 }, - { 0x104080, 0x0 }, - { 0x204080, 0x0 }, - { 0x5080, 0x0 }, - { 0x105080, 0x0 }, - { 0x205080, 0x0 }, - { 0x6080, 0x0 }, - { 0x106080, 0x0 }, - { 0x206080, 0x0 }, - { 0x7080, 0x0 }, - { 0x107080, 0x0 }, - { 0x207080, 0x0 }, - { 0x8080, 0x0 }, - { 0x108080, 0x0 }, - { 0x208080, 0x0 }, - { 0x9080, 0x0 }, - { 0x109080, 0x0 }, - { 0x209080, 0x0 }, - { 0x10080, 0x0 }, - { 0x110080, 0x0 }, - { 0x210080, 0x0 }, - { 0x10180, 0x0 }, - { 0x110180, 0x0 }, - { 0x210180, 0x0 }, - { 0x11080, 0x0 }, - { 0x111080, 0x0 }, - { 0x211080, 0x0 }, - { 0x11180, 0x0 }, - { 0x111180, 0x0 }, - { 0x211180, 0x0 }, - { 0x12080, 0x0 }, - { 0x112080, 0x0 }, - { 0x212080, 0x0 }, - { 0x12180, 0x0 }, - { 0x112180, 0x0 }, - { 0x212180, 0x0 }, - { 0x13080, 0x0 }, - { 0x113080, 0x0 }, - { 0x213080, 0x0 }, - { 0x13180, 0x0 }, - { 0x113180, 0x0 }, - { 0x213180, 0x0 }, - { 0x10081, 0x0 }, - { 0x110081, 0x0 }, - { 0x210081, 0x0 }, - { 0x10181, 0x0 }, - { 0x110181, 0x0 }, - { 0x210181, 0x0 }, - { 0x11081, 0x0 }, - { 0x111081, 0x0 }, - { 0x211081, 0x0 }, - { 0x11181, 0x0 }, - { 0x111181, 0x0 }, - { 0x211181, 0x0 }, - { 0x12081, 0x0 }, - { 0x112081, 0x0 }, - { 0x212081, 0x0 }, - { 0x12181, 0x0 }, - { 0x112181, 0x0 }, - { 0x212181, 0x0 }, - { 0x13081, 0x0 }, - { 0x113081, 0x0 }, - { 0x213081, 0x0 }, - { 0x13181, 0x0 }, - { 0x113181, 0x0 }, - { 0x213181, 0x0 }, - { 0x100d0, 0x0 }, - { 0x1100d0, 0x0 }, - { 0x2100d0, 0x0 }, - { 0x101d0, 0x0 }, - { 0x1101d0, 0x0 }, - { 0x2101d0, 0x0 }, - { 0x110d0, 0x0 }, - { 0x1110d0, 0x0 }, - { 0x2110d0, 0x0 }, - { 0x111d0, 0x0 }, - { 0x1111d0, 0x0 }, - { 0x2111d0, 0x0 }, - { 0x120d0, 0x0 }, - { 0x1120d0, 0x0 }, - { 0x2120d0, 0x0 }, - { 0x121d0, 0x0 }, - { 0x1121d0, 0x0 }, - { 0x2121d0, 0x0 }, - { 0x130d0, 0x0 }, - { 0x1130d0, 0x0 }, - { 0x2130d0, 0x0 }, - { 0x131d0, 0x0 }, - { 0x1131d0, 0x0 }, - { 0x2131d0, 0x0 }, - { 0x100d1, 0x0 }, - { 0x1100d1, 0x0 }, - { 0x2100d1, 0x0 }, - { 0x101d1, 0x0 }, - { 0x1101d1, 0x0 }, - { 0x2101d1, 0x0 }, - { 0x110d1, 0x0 }, - { 0x1110d1, 0x0 }, - { 0x2110d1, 0x0 }, - { 0x111d1, 0x0 }, - { 0x1111d1, 0x0 }, - { 0x2111d1, 0x0 }, - { 0x120d1, 0x0 }, - { 0x1120d1, 0x0 }, - { 0x2120d1, 0x0 }, - { 0x121d1, 0x0 }, - { 0x1121d1, 0x0 }, - { 0x2121d1, 0x0 }, - { 0x130d1, 0x0 }, - { 0x1130d1, 0x0 }, - { 0x2130d1, 0x0 }, - { 0x131d1, 0x0 }, - { 0x1131d1, 0x0 }, - { 0x2131d1, 0x0 }, - { 0x10068, 0x0 }, - { 0x10168, 0x0 }, - { 0x10268, 0x0 }, - { 0x10368, 0x0 }, - { 0x10468, 0x0 }, - { 0x10568, 0x0 }, - { 0x10668, 0x0 }, - { 0x10768, 0x0 }, - { 0x10868, 0x0 }, - { 0x11068, 0x0 }, - { 0x11168, 0x0 }, - { 0x11268, 0x0 }, - { 0x11368, 0x0 }, - { 0x11468, 0x0 }, - { 0x11568, 0x0 }, - { 0x11668, 0x0 }, - { 0x11768, 0x0 }, - { 0x11868, 0x0 }, - { 0x12068, 0x0 }, - { 0x12168, 0x0 }, - { 0x12268, 0x0 }, - { 0x12368, 0x0 }, - { 0x12468, 0x0 }, - { 0x12568, 0x0 }, - { 0x12668, 0x0 }, - { 0x12768, 0x0 }, - { 0x12868, 0x0 }, - { 0x13068, 0x0 }, - { 0x13168, 0x0 }, - { 0x13268, 0x0 }, - { 0x13368, 0x0 }, - { 0x13468, 0x0 }, - { 0x13568, 0x0 }, - { 0x13668, 0x0 }, - { 0x13768, 0x0 }, - { 0x13868, 0x0 }, - { 0x10069, 0x0 }, - { 0x10169, 0x0 }, - { 0x10269, 0x0 }, - { 0x10369, 0x0 }, - { 0x10469, 0x0 }, - { 0x10569, 0x0 }, - { 0x10669, 0x0 }, - { 0x10769, 0x0 }, - { 0x10869, 0x0 }, - { 0x11069, 0x0 }, - { 0x11169, 0x0 }, - { 0x11269, 0x0 }, - { 0x11369, 0x0 }, - { 0x11469, 0x0 }, - { 0x11569, 0x0 }, - { 0x11669, 0x0 }, - { 0x11769, 0x0 }, - { 0x11869, 0x0 }, - { 0x12069, 0x0 }, - { 0x12169, 0x0 }, - { 0x12269, 0x0 }, - { 0x12369, 0x0 }, - { 0x12469, 0x0 }, - { 0x12569, 0x0 }, - { 0x12669, 0x0 }, - { 0x12769, 0x0 }, - { 0x12869, 0x0 }, - { 0x13069, 0x0 }, - { 0x13169, 0x0 }, - { 0x13269, 0x0 }, - { 0x13369, 0x0 }, - { 0x13469, 0x0 }, - { 0x13569, 0x0 }, - { 0x13669, 0x0 }, - { 0x13769, 0x0 }, - { 0x13869, 0x0 }, - { 0x1008c, 0x0 }, - { 0x11008c, 0x0 }, - { 0x21008c, 0x0 }, - { 0x1018c, 0x0 }, - { 0x11018c, 0x0 }, - { 0x21018c, 0x0 }, - { 0x1108c, 0x0 }, - { 0x11108c, 0x0 }, - { 0x21108c, 0x0 }, - { 0x1118c, 0x0 }, - { 0x11118c, 0x0 }, - { 0x21118c, 0x0 }, - { 0x1208c, 0x0 }, - { 0x11208c, 0x0 }, - { 0x21208c, 0x0 }, - { 0x1218c, 0x0 }, - { 0x11218c, 0x0 }, - { 0x21218c, 0x0 }, - { 0x1308c, 0x0 }, - { 0x11308c, 0x0 }, - { 0x21308c, 0x0 }, - { 0x1318c, 0x0 }, - { 0x11318c, 0x0 }, - { 0x21318c, 0x0 }, - { 0x1008d, 0x0 }, - { 0x11008d, 0x0 }, - { 0x21008d, 0x0 }, - { 0x1018d, 0x0 }, - { 0x11018d, 0x0 }, - { 0x21018d, 0x0 }, - { 0x1108d, 0x0 }, - { 0x11108d, 0x0 }, - { 0x21108d, 0x0 }, - { 0x1118d, 0x0 }, - { 0x11118d, 0x0 }, - { 0x21118d, 0x0 }, - { 0x1208d, 0x0 }, - { 0x11208d, 0x0 }, - { 0x21208d, 0x0 }, - { 0x1218d, 0x0 }, - { 0x11218d, 0x0 }, - { 0x21218d, 0x0 }, - { 0x1308d, 0x0 }, - { 0x11308d, 0x0 }, - { 0x21308d, 0x0 }, - { 0x1318d, 0x0 }, - { 0x11318d, 0x0 }, - { 0x21318d, 0x0 }, - { 0x100c0, 0x0 }, - { 0x1100c0, 0x0 }, - { 0x2100c0, 0x0 }, - { 0x101c0, 0x0 }, - { 0x1101c0, 0x0 }, - { 0x2101c0, 0x0 }, - { 0x102c0, 0x0 }, - { 0x1102c0, 0x0 }, - { 0x2102c0, 0x0 }, - { 0x103c0, 0x0 }, - { 0x1103c0, 0x0 }, - { 0x2103c0, 0x0 }, - { 0x104c0, 0x0 }, - { 0x1104c0, 0x0 }, - { 0x2104c0, 0x0 }, - { 0x105c0, 0x0 }, - { 0x1105c0, 0x0 }, - { 0x2105c0, 0x0 }, - { 0x106c0, 0x0 }, - { 0x1106c0, 0x0 }, - { 0x2106c0, 0x0 }, - { 0x107c0, 0x0 }, - { 0x1107c0, 0x0 }, - { 0x2107c0, 0x0 }, - { 0x108c0, 0x0 }, - { 0x1108c0, 0x0 }, - { 0x2108c0, 0x0 }, - { 0x110c0, 0x0 }, - { 0x1110c0, 0x0 }, - { 0x2110c0, 0x0 }, - { 0x111c0, 0x0 }, - { 0x1111c0, 0x0 }, - { 0x2111c0, 0x0 }, - { 0x112c0, 0x0 }, - { 0x1112c0, 0x0 }, - { 0x2112c0, 0x0 }, - { 0x113c0, 0x0 }, - { 0x1113c0, 0x0 }, - { 0x2113c0, 0x0 }, - { 0x114c0, 0x0 }, - { 0x1114c0, 0x0 }, - { 0x2114c0, 0x0 }, - { 0x115c0, 0x0 }, - { 0x1115c0, 0x0 }, - { 0x2115c0, 0x0 }, - { 0x116c0, 0x0 }, - { 0x1116c0, 0x0 }, - { 0x2116c0, 0x0 }, - { 0x117c0, 0x0 }, - { 0x1117c0, 0x0 }, - { 0x2117c0, 0x0 }, - { 0x118c0, 0x0 }, - { 0x1118c0, 0x0 }, - { 0x2118c0, 0x0 }, - { 0x120c0, 0x0 }, - { 0x1120c0, 0x0 }, - { 0x2120c0, 0x0 }, - { 0x121c0, 0x0 }, - { 0x1121c0, 0x0 }, - { 0x2121c0, 0x0 }, - { 0x122c0, 0x0 }, - { 0x1122c0, 0x0 }, - { 0x2122c0, 0x0 }, - { 0x123c0, 0x0 }, - { 0x1123c0, 0x0 }, - { 0x2123c0, 0x0 }, - { 0x124c0, 0x0 }, - { 0x1124c0, 0x0 }, - { 0x2124c0, 0x0 }, - { 0x125c0, 0x0 }, - { 0x1125c0, 0x0 }, - { 0x2125c0, 0x0 }, - { 0x126c0, 0x0 }, - { 0x1126c0, 0x0 }, - { 0x2126c0, 0x0 }, - { 0x127c0, 0x0 }, - { 0x1127c0, 0x0 }, - { 0x2127c0, 0x0 }, - { 0x128c0, 0x0 }, - { 0x1128c0, 0x0 }, - { 0x2128c0, 0x0 }, - { 0x130c0, 0x0 }, - { 0x1130c0, 0x0 }, - { 0x2130c0, 0x0 }, - { 0x131c0, 0x0 }, - { 0x1131c0, 0x0 }, - { 0x2131c0, 0x0 }, - { 0x132c0, 0x0 }, - { 0x1132c0, 0x0 }, - { 0x2132c0, 0x0 }, - { 0x133c0, 0x0 }, - { 0x1133c0, 0x0 }, - { 0x2133c0, 0x0 }, - { 0x134c0, 0x0 }, - { 0x1134c0, 0x0 }, - { 0x2134c0, 0x0 }, - { 0x135c0, 0x0 }, - { 0x1135c0, 0x0 }, - { 0x2135c0, 0x0 }, - { 0x136c0, 0x0 }, - { 0x1136c0, 0x0 }, - { 0x2136c0, 0x0 }, - { 0x137c0, 0x0 }, - { 0x1137c0, 0x0 }, - { 0x2137c0, 0x0 }, - { 0x138c0, 0x0 }, - { 0x1138c0, 0x0 }, - { 0x2138c0, 0x0 }, - { 0x100c1, 0x0 }, - { 0x1100c1, 0x0 }, - { 0x2100c1, 0x0 }, - { 0x101c1, 0x0 }, - { 0x1101c1, 0x0 }, - { 0x2101c1, 0x0 }, - { 0x102c1, 0x0 }, - { 0x1102c1, 0x0 }, - { 0x2102c1, 0x0 }, - { 0x103c1, 0x0 }, - { 0x1103c1, 0x0 }, - { 0x2103c1, 0x0 }, - { 0x104c1, 0x0 }, - { 0x1104c1, 0x0 }, - { 0x2104c1, 0x0 }, - { 0x105c1, 0x0 }, - { 0x1105c1, 0x0 }, - { 0x2105c1, 0x0 }, - { 0x106c1, 0x0 }, - { 0x1106c1, 0x0 }, - { 0x2106c1, 0x0 }, - { 0x107c1, 0x0 }, - { 0x1107c1, 0x0 }, - { 0x2107c1, 0x0 }, - { 0x108c1, 0x0 }, - { 0x1108c1, 0x0 }, - { 0x2108c1, 0x0 }, - { 0x110c1, 0x0 }, - { 0x1110c1, 0x0 }, - { 0x2110c1, 0x0 }, - { 0x111c1, 0x0 }, - { 0x1111c1, 0x0 }, - { 0x2111c1, 0x0 }, - { 0x112c1, 0x0 }, - { 0x1112c1, 0x0 }, - { 0x2112c1, 0x0 }, - { 0x113c1, 0x0 }, - { 0x1113c1, 0x0 }, - { 0x2113c1, 0x0 }, - { 0x114c1, 0x0 }, - { 0x1114c1, 0x0 }, - { 0x2114c1, 0x0 }, - { 0x115c1, 0x0 }, - { 0x1115c1, 0x0 }, - { 0x2115c1, 0x0 }, - { 0x116c1, 0x0 }, - { 0x1116c1, 0x0 }, - { 0x2116c1, 0x0 }, - { 0x117c1, 0x0 }, - { 0x1117c1, 0x0 }, - { 0x2117c1, 0x0 }, - { 0x118c1, 0x0 }, - { 0x1118c1, 0x0 }, - { 0x2118c1, 0x0 }, - { 0x120c1, 0x0 }, - { 0x1120c1, 0x0 }, - { 0x2120c1, 0x0 }, - { 0x121c1, 0x0 }, - { 0x1121c1, 0x0 }, - { 0x2121c1, 0x0 }, - { 0x122c1, 0x0 }, - { 0x1122c1, 0x0 }, - { 0x2122c1, 0x0 }, - { 0x123c1, 0x0 }, - { 0x1123c1, 0x0 }, - { 0x2123c1, 0x0 }, - { 0x124c1, 0x0 }, - { 0x1124c1, 0x0 }, - { 0x2124c1, 0x0 }, - { 0x125c1, 0x0 }, - { 0x1125c1, 0x0 }, - { 0x2125c1, 0x0 }, - { 0x126c1, 0x0 }, - { 0x1126c1, 0x0 }, - { 0x2126c1, 0x0 }, - { 0x127c1, 0x0 }, - { 0x1127c1, 0x0 }, - { 0x2127c1, 0x0 }, - { 0x128c1, 0x0 }, - { 0x1128c1, 0x0 }, - { 0x2128c1, 0x0 }, - { 0x130c1, 0x0 }, - { 0x1130c1, 0x0 }, - { 0x2130c1, 0x0 }, - { 0x131c1, 0x0 }, - { 0x1131c1, 0x0 }, - { 0x2131c1, 0x0 }, - { 0x132c1, 0x0 }, - { 0x1132c1, 0x0 }, - { 0x2132c1, 0x0 }, - { 0x133c1, 0x0 }, - { 0x1133c1, 0x0 }, - { 0x2133c1, 0x0 }, - { 0x134c1, 0x0 }, - { 0x1134c1, 0x0 }, - { 0x2134c1, 0x0 }, - { 0x135c1, 0x0 }, - { 0x1135c1, 0x0 }, - { 0x2135c1, 0x0 }, - { 0x136c1, 0x0 }, - { 0x1136c1, 0x0 }, - { 0x2136c1, 0x0 }, - { 0x137c1, 0x0 }, - { 0x1137c1, 0x0 }, - { 0x2137c1, 0x0 }, - { 0x138c1, 0x0 }, - { 0x1138c1, 0x0 }, - { 0x2138c1, 0x0 }, - { 0x10020, 0x0 }, - { 0x110020, 0x0 }, - { 0x210020, 0x0 }, - { 0x11020, 0x0 }, - { 0x111020, 0x0 }, - { 0x211020, 0x0 }, - { 0x12020, 0x0 }, - { 0x112020, 0x0 }, - { 0x212020, 0x0 }, - { 0x13020, 0x0 }, - { 0x113020, 0x0 }, - { 0x213020, 0x0 }, - { 0x20072, 0x0 }, - { 0x20073, 0x0 }, - { 0x20074, 0x0 }, - { 0x100aa, 0x0 }, - { 0x110aa, 0x0 }, - { 0x120aa, 0x0 }, - { 0x130aa, 0x0 }, - { 0x20010, 0x0 }, - { 0x120010, 0x0 }, - { 0x220010, 0x0 }, - { 0x20011, 0x0 }, - { 0x120011, 0x0 }, - { 0x220011, 0x0 }, - { 0x100ae, 0x0 }, - { 0x1100ae, 0x0 }, - { 0x2100ae, 0x0 }, - { 0x100af, 0x0 }, - { 0x1100af, 0x0 }, - { 0x2100af, 0x0 }, - { 0x110ae, 0x0 }, - { 0x1110ae, 0x0 }, - { 0x2110ae, 0x0 }, - { 0x110af, 0x0 }, - { 0x1110af, 0x0 }, - { 0x2110af, 0x0 }, - { 0x120ae, 0x0 }, - { 0x1120ae, 0x0 }, - { 0x2120ae, 0x0 }, - { 0x120af, 0x0 }, - { 0x1120af, 0x0 }, - { 0x2120af, 0x0 }, - { 0x130ae, 0x0 }, - { 0x1130ae, 0x0 }, - { 0x2130ae, 0x0 }, - { 0x130af, 0x0 }, - { 0x1130af, 0x0 }, - { 0x2130af, 0x0 }, - { 0x20020, 0x0 }, - { 0x120020, 0x0 }, - { 0x220020, 0x0 }, - { 0x100a0, 0x0 }, - { 0x100a1, 0x0 }, - { 0x100a2, 0x0 }, - { 0x100a3, 0x0 }, - { 0x100a4, 0x0 }, - { 0x100a5, 0x0 }, - { 0x100a6, 0x0 }, - { 0x100a7, 0x0 }, - { 0x110a0, 0x0 }, - { 0x110a1, 0x0 }, - { 0x110a2, 0x0 }, - { 0x110a3, 0x0 }, - { 0x110a4, 0x0 }, - { 0x110a5, 0x0 }, - { 0x110a6, 0x0 }, - { 0x110a7, 0x0 }, - { 0x120a0, 0x0 }, - { 0x120a1, 0x0 }, - { 0x120a2, 0x0 }, - { 0x120a3, 0x0 }, - { 0x120a4, 0x0 }, - { 0x120a5, 0x0 }, - { 0x120a6, 0x0 }, - { 0x120a7, 0x0 }, - { 0x130a0, 0x0 }, - { 0x130a1, 0x0 }, - { 0x130a2, 0x0 }, - { 0x130a3, 0x0 }, - { 0x130a4, 0x0 }, - { 0x130a5, 0x0 }, - { 0x130a6, 0x0 }, - { 0x130a7, 0x0 }, - { 0x2007c, 0x0 }, - { 0x12007c, 0x0 }, - { 0x22007c, 0x0 }, - { 0x2007d, 0x0 }, - { 0x12007d, 0x0 }, - { 0x22007d, 0x0 }, - { 0x400fd, 0x0 }, - { 0x400c0, 0x0 }, - { 0x90201, 0x0 }, - { 0x190201, 0x0 }, - { 0x290201, 0x0 }, - { 0x90202, 0x0 }, - { 0x190202, 0x0 }, - { 0x290202, 0x0 }, - { 0x90203, 0x0 }, - { 0x190203, 0x0 }, - { 0x290203, 0x0 }, - { 0x90204, 0x0 }, - { 0x190204, 0x0 }, - { 0x290204, 0x0 }, - { 0x90205, 0x0 }, - { 0x190205, 0x0 }, - { 0x290205, 0x0 }, - { 0x90206, 0x0 }, - { 0x190206, 0x0 }, - { 0x290206, 0x0 }, - { 0x90207, 0x0 }, - { 0x190207, 0x0 }, - { 0x290207, 0x0 }, - { 0x90208, 0x0 }, - { 0x190208, 0x0 }, - { 0x290208, 0x0 }, - { 0x10062, 0x0 }, - { 0x10162, 0x0 }, - { 0x10262, 0x0 }, - { 0x10362, 0x0 }, - { 0x10462, 0x0 }, - { 0x10562, 0x0 }, - { 0x10662, 0x0 }, - { 0x10762, 0x0 }, - { 0x10862, 0x0 }, - { 0x11062, 0x0 }, - { 0x11162, 0x0 }, - { 0x11262, 0x0 }, - { 0x11362, 0x0 }, - { 0x11462, 0x0 }, - { 0x11562, 0x0 }, - { 0x11662, 0x0 }, - { 0x11762, 0x0 }, - { 0x11862, 0x0 }, - { 0x12062, 0x0 }, - { 0x12162, 0x0 }, - { 0x12262, 0x0 }, - { 0x12362, 0x0 }, - { 0x12462, 0x0 }, - { 0x12562, 0x0 }, - { 0x12662, 0x0 }, - { 0x12762, 0x0 }, - { 0x12862, 0x0 }, - { 0x13062, 0x0 }, - { 0x13162, 0x0 }, - { 0x13262, 0x0 }, - { 0x13362, 0x0 }, - { 0x13462, 0x0 }, - { 0x13562, 0x0 }, - { 0x13662, 0x0 }, - { 0x13762, 0x0 }, - { 0x13862, 0x0 }, - { 0x20077, 0x0 }, - { 0x10001, 0x0 }, - { 0x11001, 0x0 }, - { 0x12001, 0x0 }, - { 0x13001, 0x0 }, - { 0x10040, 0x0 }, - { 0x10140, 0x0 }, - { 0x10240, 0x0 }, - { 0x10340, 0x0 }, - { 0x10440, 0x0 }, - { 0x10540, 0x0 }, - { 0x10640, 0x0 }, - { 0x10740, 0x0 }, - { 0x10840, 0x0 }, - { 0x10030, 0x0 }, - { 0x10130, 0x0 }, - { 0x10230, 0x0 }, - { 0x10330, 0x0 }, - { 0x10430, 0x0 }, - { 0x10530, 0x0 }, - { 0x10630, 0x0 }, - { 0x10730, 0x0 }, - { 0x10830, 0x0 }, - { 0x11040, 0x0 }, - { 0x11140, 0x0 }, - { 0x11240, 0x0 }, - { 0x11340, 0x0 }, - { 0x11440, 0x0 }, - { 0x11540, 0x0 }, - { 0x11640, 0x0 }, - { 0x11740, 0x0 }, - { 0x11840, 0x0 }, - { 0x11030, 0x0 }, - { 0x11130, 0x0 }, - { 0x11230, 0x0 }, - { 0x11330, 0x0 }, - { 0x11430, 0x0 }, - { 0x11530, 0x0 }, - { 0x11630, 0x0 }, - { 0x11730, 0x0 }, - { 0x11830, 0x0 }, - { 0x12040, 0x0 }, - { 0x12140, 0x0 }, - { 0x12240, 0x0 }, - { 0x12340, 0x0 }, - { 0x12440, 0x0 }, - { 0x12540, 0x0 }, - { 0x12640, 0x0 }, - { 0x12740, 0x0 }, - { 0x12840, 0x0 }, - { 0x12030, 0x0 }, - { 0x12130, 0x0 }, - { 0x12230, 0x0 }, - { 0x12330, 0x0 }, - { 0x12430, 0x0 }, - { 0x12530, 0x0 }, - { 0x12630, 0x0 }, - { 0x12730, 0x0 }, - { 0x12830, 0x0 }, - { 0x13040, 0x0 }, - { 0x13140, 0x0 }, - { 0x13240, 0x0 }, - { 0x13340, 0x0 }, - { 0x13440, 0x0 }, - { 0x13540, 0x0 }, - { 0x13640, 0x0 }, - { 0x13740, 0x0 }, - { 0x13840, 0x0 }, - { 0x13030, 0x0 }, - { 0x13130, 0x0 }, - { 0x13230, 0x0 }, - { 0x13330, 0x0 }, - { 0x13430, 0x0 }, - { 0x13530, 0x0 }, - { 0x13630, 0x0 }, - { 0x13730, 0x0 }, - { 0x13830, 0x0 }, -}; - -uint32_t ddrphy_trained_csr_num = ARRAY_SIZE(ddrphy_trained_csr); diff --git a/drivers/ddr/imx8m/ddrphy_train.c b/drivers/ddr/imx8m/ddrphy_train.c deleted file mode 100644 index d930a2fffe..0000000000 --- a/drivers/ddr/imx8m/ddrphy_train.c +++ /dev/null @@ -1,131 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright 2018 NXP - */ - -#define pr_fmt(fmt) "imx8m-ddr: " fmt - -#include <common.h> -#include <linux/kernel.h> -#include <soc/imx8m/ddr.h> -#include <firmware.h> -#include <mach/imx8m-regs.h> - -void ddr_load_train_code(enum dram_type dram_type, enum fw_type fw_type) -{ - const u16 *imem, *dmem; - size_t isize, dsize; - - if (dram_is_lpddr4(dram_type)) { - if (fw_type == FW_1D_IMAGE) { - get_builtin_firmware(lpddr4_pmu_train_1d_imem_bin, &imem, &isize); - get_builtin_firmware(lpddr4_pmu_train_1d_dmem_bin, &dmem, &dsize); - } else { - get_builtin_firmware(lpddr4_pmu_train_2d_imem_bin, &imem, &isize); - get_builtin_firmware(lpddr4_pmu_train_2d_dmem_bin, &dmem, &dsize); - } - } else if (dram_is_ddr4(dram_type)) { - if (fw_type == FW_1D_IMAGE) { - get_builtin_firmware(ddr4_imem_1d_bin, &imem, &isize); - get_builtin_firmware(ddr4_dmem_1d_bin, &dmem, &dsize); - } else { - get_builtin_firmware(ddr4_imem_2d_bin, &imem, &isize); - get_builtin_firmware(ddr4_dmem_2d_bin, &dmem, &dsize); - } - } else { - panic("No matching DDR PHY firmware found"); - } - - ddrc_phy_load_firmware(IOMEM(MX8M_DDRC_PHY_BASE_ADDR), - DDRC_PHY_IMEM, imem, isize); - - ddrc_phy_load_firmware(IOMEM(MX8M_DDRC_PHY_BASE_ADDR), - DDRC_PHY_DMEM, dmem, dsize); -} - -int ddr_cfg_phy(struct dram_timing_info *dram_timing, enum ddrc_type type) -{ - struct dram_cfg_param *dram_cfg; - struct dram_fsp_msg *fsp_msg; - unsigned int num; - int i = 0; - int j = 0; - int ret; - - /* initialize PHY configuration */ - dram_cfg = dram_timing->ddrphy_cfg; - num = dram_timing->ddrphy_cfg_num; - for (i = 0; i < num; i++) { - /* config phy reg */ - dwc_ddrphy_apb_wr(dram_cfg->reg, dram_cfg->val); - dram_cfg++; - } - - /* load the frequency setpoint message block config */ - fsp_msg = dram_timing->fsp_msg; - for (i = 0; i < dram_timing->fsp_msg_num; i++) { - pr_debug("DRAM PHY training for %dMTS\n", fsp_msg->drate); - /* set dram PHY input clocks to desired frequency */ - ddrphy_init_set_dfi_clk(fsp_msg->drate, type); - - /* load the dram training firmware image */ - dwc_ddrphy_apb_wr(0xd0000, 0x0); - ddr_load_train_code(dram_timing->dram_type, fsp_msg->fw_type); - - /* load the frequency set point message block parameter */ - dram_cfg = fsp_msg->fsp_cfg; - num = fsp_msg->fsp_cfg_num; - for (j = 0; j < num; j++) { - dwc_ddrphy_apb_wr(dram_cfg->reg, dram_cfg->val); - dram_cfg++; - } - - /* - * -------------------- excute the firmware -------------------- - * Running the firmware is a simply process to taking the - * PMU out of reset and stall, then the firwmare will be run - * 1. reset the PMU; - * 2. begin the excution; - * 3. wait for the training done; - * 4. read the message block result. - * ------------------------------------------------------------- - */ - dwc_ddrphy_apb_wr(0xd0000, 0x1); - dwc_ddrphy_apb_wr(0xd0099, 0x9); - dwc_ddrphy_apb_wr(0xd0099, 0x1); - dwc_ddrphy_apb_wr(0xd0099, 0x0); - - /* Wait for the training firmware to complete */ - ret = wait_ddrphy_training_complete(); - if (ret) - return ret; - - /* Halt the microcontroller. */ - dwc_ddrphy_apb_wr(0xd0099, 0x1); - - /* Read the Message Block results */ - dwc_ddrphy_apb_wr(0xd0000, 0x0); - - ddrphy_init_read_msg_block(fsp_msg->fw_type); - - if (fsp_msg->fw_type != FW_2D_IMAGE) - get_trained_CDD(i); - - dwc_ddrphy_apb_wr(0xd0000, 0x1); - - fsp_msg++; - } - - /* Load PHY Init Engine Image */ - dram_cfg = dram_timing->ddrphy_pie; - num = dram_timing->ddrphy_pie_num; - for (i = 0; i < num; i++) { - dwc_ddrphy_apb_wr(dram_cfg->reg, dram_cfg->val); - dram_cfg++; - } - - /* save the ddr PHY trained CSR in memory for low power use */ - ddrphy_trained_csr_save(ddrphy_trained_csr, ddrphy_trained_csr_num); - - return 0; -} diff --git a/drivers/ddr/imx8m/ddrphy_utils.c b/drivers/ddr/imx8m/ddrphy_utils.c deleted file mode 100644 index 79bb76c35a..0000000000 --- a/drivers/ddr/imx8m/ddrphy_utils.c +++ /dev/null @@ -1,529 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* -* Copyright 2018 NXP -*/ - -#define pr_fmt(fmt) "imx8m-ddr: " fmt - -#include <common.h> -#include <errno.h> -#include <io.h> -#include <linux/iopoll.h> -#include <soc/imx8m/ddr.h> -#include <mach/imx8m-regs.h> -#include <mach/imx8m-ccm-regs.h> - -/* DDR Transfer rate, bus clock is transfer rate / 2, and the DDRC runs at bus - * clock / 2, which is therefor transfer rate / 4. */ -enum ddr_rate { - DDR_4000, - DDR_3200, - DDR_3000, - DDR_2600, /* Unused */ - DDR_2400, - DDR_2376, /* Unused */ - DDR_1600, - DDR_1000, /* Unused */ - DDR_1066, - DDR_667, - DDR_400, - DDR_250, /* Unused */ - DDR_100, - DDR_NUM_RATES -}; - -/* PLL config for IMX8MM type DRAM PLL. This PLL type isn't documented, but - * it looks like it is a basically a fractional PLL: - * Frequency = Ref (24 MHz) / P * M / 2^S - * Note: Divider is equal to register value - */ -#define MDIV(x) ((x) << 12) -#define PDIV(x) ((x) << 4) -#define SDIV(x) ((x) << 0) - -#define LOCK_STATUS BIT(31) -#define LOCK_SEL_MASK BIT(29) -#define CLKE_MASK BIT(11) -#define RST_MASK BIT(9) -#define BYPASS_MASK BIT(4) - -static const struct imx8mm_fracpll_config { - uint32_t r1, r2; - bool valid; -} imx8mm_fracpll_table[DDR_NUM_RATES] = { - [DDR_4000] = { .valid = true, .r1 = MDIV(250) | PDIV(3) | SDIV(1), .r2 = 0 }, - [DDR_3200] = { .valid = true, .r1 = MDIV(300) | PDIV(9) | SDIV(0), .r2 = 0 }, - [DDR_3000] = { .valid = true, .r1 = MDIV(250) | PDIV(8) | SDIV(0), .r2 = 0 }, - [DDR_2600] = { .valid = true, .r1 = MDIV(325) | PDIV(3) | SDIV(2), .r2 = 0 }, - [DDR_2400] = { .valid = true, .r1 = MDIV(300) | PDIV(3) | SDIV(2), .r2 = 0 }, - [DDR_2376] = { .valid = true, .r1 = MDIV( 99) | PDIV(1) | SDIV(2), .r2 = 0 }, - [DDR_1600] = { .valid = true, .r1 = MDIV(300) | PDIV(9) | SDIV(1), .r2 = 0 }, - [DDR_1066] = { .valid = true, .r1 = MDIV(400) | PDIV(9) | SDIV(2), .r2 = 0 }, - [DDR_667] = { .valid = true, .r1 = MDIV(334) | PDIV(3) | SDIV(4), .r2 = 0 }, - [DDR_400] = { .valid = true, .r1 = MDIV(300) | PDIV(9) | SDIV(3), .r2 = 0 }, -}; - -/* PLL config for IMX8MQ type DRAM PLL. This is SSCG_PLL: - * Frequency = Ref (25 MHz) / divr1 * (2*divf1) / divr2 * divf2 / divq - * Note: IMX8MQ RM, §5.1.5.4.4 Fig. 5-8 shows ÷2 on divf2, but this is not true. - * Note: divider is register value + 1 - */ -#define SSCG_PLL_LOCK BIT(31) -#define SSCG_PLL_DRAM_PLL_CLKE BIT(9) -#define SSCG_PLL_PD BIT(7) -#define SSCG_PLL_BYPASS1 BIT(5) -#define SSCG_PLL_BYPASS2 BIT(4) - -#define SSCG_PLL_REF_DIVR2_MASK (0x3f << 19) -#define SSCG_PLL_REF_DIVR2_VAL(n) (((n) << 19) & SSCG_PLL_REF_DIVR2_MASK) -#define SSCG_PLL_FEEDBACK_DIV_F1_MASK (0x3f << 13) -#define SSCG_PLL_FEEDBACK_DIV_F1_VAL(n) (((n) << 13) & SSCG_PLL_FEEDBACK_DIV_F1_MASK) -#define SSCG_PLL_FEEDBACK_DIV_F2_MASK (0x3f << 7) -#define SSCG_PLL_FEEDBACK_DIV_F2_VAL(n) (((n) << 7) & SSCG_PLL_FEEDBACK_DIV_F2_MASK) -#define SSCG_PLL_OUTPUT_DIV_VAL_MASK (0x3f << 1) -#define SSCG_PLL_OUTPUT_DIV_VAL(n) (((n) << 1) & SSCG_PLL_OUTPUT_DIV_VAL_MASK) - -#define SSCG_PLL_CFG2(divf1, divr2, divf2, divq) \ - (SSCG_PLL_FEEDBACK_DIV_F1_VAL(divf1) | SSCG_PLL_FEEDBACK_DIV_F2_VAL(divf2) | \ - SSCG_PLL_REF_DIVR2_VAL(divr2) | SSCG_PLL_OUTPUT_DIV_VAL(divq)) - -static const struct imx8mq_ssgcpll_config { - uint32_t val; - bool valid; -} imx8mq_ssgcpll_table[DDR_NUM_RATES] = { - [DDR_3200] = { .valid = true, .val = SSCG_PLL_CFG2(39, 29, 11, 0) }, - [DDR_2400] = { .valid = true, .val = SSCG_PLL_CFG2(39, 29, 17, 1) }, - [DDR_1600] = { .valid = true, .val = SSCG_PLL_CFG2(39, 29, 11, 1) }, - [DDR_667] = { .valid = true, .val = SSCG_PLL_CFG2(45, 30, 8, 3) }, /* ~166.935 MHz = 667.74 */ -}; - -/* IMX8M Bypass clock config. These configure dram_alt1_clk and the dram apb - * clock. For the bypass config, clock rate = DRAM tranfer rate, rather than - * clock = dram / 4 - */ - -/* prediv is actual divider, register will be set to divider - 1 */ -#define CCM_ROOT_CFG(mux, prediv) (IMX8M_CCM_TARGET_ROOTn_ENABLE | \ - IMX8M_CCM_TARGET_ROOTn_MUX(mux) | IMX8M_CCM_TARGET_ROOTn_PRE_DIV(prediv-1)) - -static const struct imx8m_bypass_config { - uint32_t alt_clk; - uint32_t apb_clk; - bool valid; -} imx8m_bypass_table[DDR_NUM_RATES] = { - [DDR_400] = { .valid = true, .alt_clk = CCM_ROOT_CFG(1, 2), .apb_clk = CCM_ROOT_CFG(3, 2) }, - [DDR_250] = { .valid = true, .alt_clk = CCM_ROOT_CFG(3, 2), .apb_clk = CCM_ROOT_CFG(2, 2) }, - [DDR_100] = { .valid = true, .alt_clk = CCM_ROOT_CFG(2, 1), .apb_clk = CCM_ROOT_CFG(2, 2) }, -}; - -void ddrc_phy_load_firmware(void __iomem *phy, - enum ddrc_phy_firmware_offset offset, - const u16 *blob, size_t size) -{ - while (size) { - writew(*blob++, phy + DDRC_PHY_REG(offset)); - offset++; - size -= sizeof(*blob); - } -} - -enum pmc_constants { - PMC_MESSAGE_ID, - PMC_MESSAGE_STREAM, - - PMC_TRAIN_SUCCESS = 0x07, - PMC_TRAIN_STREAM_START = 0x08, - PMC_TRAIN_FAIL = 0xff, -}; - -static u32 ddrc_phy_get_message(void __iomem *phy, int type) -{ - u32 r, message; - - /* - * When BIT0 set to 0, the PMU has a message for the user - * Wait for it indefinitely. - */ - readl_poll_timeout(phy + DDRC_PHY_REG(0xd0004), - r, !(r & BIT(0)), 0); - - switch (type) { - case PMC_MESSAGE_ID: - /* - * Get the major message ID - */ - message = readl(phy + DDRC_PHY_REG(0xd0032)); - break; - case PMC_MESSAGE_STREAM: - message = readl(phy + DDRC_PHY_REG(0xd0034)); - message <<= 16; - message |= readl(phy + DDRC_PHY_REG(0xd0032)); - break; - } - - /* - * By setting this register to 0, the user acknowledges the - * receipt of the message. - */ - writel(0x00000000, phy + DDRC_PHY_REG(0xd0031)); - /* - * When BIT0 set to 0, the PMU has a message for the user - */ - readl_poll_timeout(phy + DDRC_PHY_REG(0xd0004), - r, r & BIT(0), 0); - - writel(0x00000001, phy + DDRC_PHY_REG(0xd0031)); - - return message; -} - -static void ddrc_phy_fetch_streaming_message(void __iomem *phy) -{ - const u16 index = ddrc_phy_get_message(phy, PMC_MESSAGE_STREAM); - u16 i; - - for (i = 0; i < index; i++) - ddrc_phy_get_message(phy, PMC_MESSAGE_STREAM); -} - -int wait_ddrphy_training_complete(void) -{ - void __iomem *phy = IOMEM(MX8M_DDRC_PHY_BASE_ADDR); - - for (;;) { - const u32 m = ddrc_phy_get_message(phy, PMC_MESSAGE_ID); - - switch (m) { - case PMC_TRAIN_STREAM_START: - ddrc_phy_fetch_streaming_message(phy); - break; - case PMC_TRAIN_SUCCESS: - return 0; - case PMC_TRAIN_FAIL: - hang(); - } - } -} - -static void dram_enable_bypass(enum ddr_rate drate) -{ - const struct imx8m_bypass_config *config = &imx8m_bypass_table[drate]; - - if (!config->valid) { - printf("No matched freq table entry %u\n", drate); - return; - } - - imx8m_clock_set_target_val(IMX8M_DRAM_ALT_CLK_ROOT, config->alt_clk); - imx8m_clock_set_target_val(IMX8M_DRAM_APB_CLK_ROOT, config->apb_clk); - imx8m_clock_set_target_val(IMX8M_DRAM_SEL_CFG, IMX8M_CCM_TARGET_ROOTn_ENABLE | - IMX8M_CCM_TARGET_ROOTn_MUX(1)); -} - -static void dram_disable_bypass(void) -{ - imx8m_clock_set_target_val(IMX8M_DRAM_SEL_CFG, - IMX8M_CCM_TARGET_ROOTn_ENABLE | - IMX8M_CCM_TARGET_ROOTn_MUX(0)); - imx8m_clock_set_target_val(IMX8M_DRAM_APB_CLK_ROOT, - IMX8M_CCM_TARGET_ROOTn_ENABLE | - IMX8M_CCM_TARGET_ROOTn_MUX(4) | - IMX8M_CCM_TARGET_ROOTn_PRE_DIV(5 - 1)); -} - -static int dram_frac_pll_init(enum ddr_rate drate) -{ - volatile int i; - u32 tmp; - void *pll_base; - const struct imx8mm_fracpll_config *config = &imx8mm_fracpll_table[drate]; - - if (!config->valid) { - printf("No matched freq table entry %u\n", drate); - return -EINVAL; - } - - setbits_le32(MX8M_GPC_BASE_ADDR + 0xec, 1 << 7); - setbits_le32(MX8M_GPC_BASE_ADDR + 0xf8, 1 << 5); - writel(0x8F000000UL, MX8M_SRC_BASE_ADDR + 0x1004); - - pll_base = IOMEM(MX8M_ANATOP_BASE_ADDR) + 0x50; - - /* Bypass clock and set lock to pll output lock */ - tmp = readl(pll_base); - tmp |= BYPASS_MASK; - writel(tmp, pll_base); - - /* Enable RST */ - tmp &= ~RST_MASK; - writel(tmp, pll_base); - - writel(config->r1, pll_base + 4); - writel(config->r2, pll_base + 8); - - for (i = 0; i < 1000; i++); - - /* Disable RST */ - tmp |= RST_MASK; - writel(tmp, pll_base); - - /* Wait Lock*/ - while (!(readl(pll_base) & LOCK_STATUS)); - - /* Bypass */ - tmp &= ~BYPASS_MASK; - writel(tmp, pll_base); - - return 0; -} - -static int dram_sscg_pll_init(enum ddr_rate drate) -{ - u32 val; - void __iomem *pll_base = IOMEM(MX8M_ANATOP_BASE_ADDR) + 0x60; - const struct imx8mq_ssgcpll_config *config = &imx8mq_ssgcpll_table[drate]; - - if (!config->valid) { - printf("No matched freq table entry %u\n", drate); - return -EINVAL; - } - - /* Bypass */ - setbits_le32(pll_base, SSCG_PLL_BYPASS1 | SSCG_PLL_BYPASS2); - - val = readl(pll_base + 0x8); - val &= ~(SSCG_PLL_OUTPUT_DIV_VAL_MASK | - SSCG_PLL_FEEDBACK_DIV_F2_MASK | - SSCG_PLL_FEEDBACK_DIV_F1_MASK | - SSCG_PLL_REF_DIVR2_MASK); - val |= config->val; - writel(val, pll_base + 0x8); - - /* Clear power down bit */ - clrbits_le32(pll_base, SSCG_PLL_PD); - /* Enable PLL */ - setbits_le32(pll_base, SSCG_PLL_DRAM_PLL_CLKE); - - /* Clear bypass */ - clrbits_le32(pll_base, SSCG_PLL_BYPASS1); - udelay(100); - clrbits_le32(pll_base, SSCG_PLL_BYPASS2); - /* Wait lock */ - while (!(readl(pll_base) & SSCG_PLL_LOCK)) - ; - - return 0; -} - -static int dram_pll_init(enum ddr_rate drate, enum ddrc_type type) -{ - switch (type) { - case DDRC_TYPE_MQ: - return dram_sscg_pll_init(drate); - case DDRC_TYPE_MM: - case DDRC_TYPE_MN: - case DDRC_TYPE_MP: - return dram_frac_pll_init(drate); - default: - return -ENODEV; - } -} - -void ddrphy_init_set_dfi_clk(unsigned int drate_mhz, enum ddrc_type type) -{ - enum ddr_rate drate; - - switch (drate_mhz) { - case 4000: drate = DDR_4000; break; - case 3200: drate = DDR_3200; break; - case 3000: drate = DDR_3000; break; - case 2400: drate = DDR_2400; break; - case 1600: drate = DDR_1600; break; - case 1066: drate = DDR_1066; break; - case 667: drate = DDR_667; break; - case 400: drate = DDR_400; break; - case 100: drate = DDR_100; break; - default: - return; - } - - if (drate_mhz > 400) { - dram_pll_init(drate, type); - dram_disable_bypass(); - } else { - dram_enable_bypass(drate); - } -} - -void ddrphy_init_read_msg_block(enum fw_type type) -{ -} - -static unsigned int g_cdd_rr_max[4]; -static unsigned int g_cdd_rw_max[4]; -static unsigned int g_cdd_wr_max[4]; -static unsigned int g_cdd_ww_max[4]; - -static unsigned int look_for_max(unsigned int data[], unsigned int addr_start, - unsigned int addr_end) -{ - unsigned int i, imax = 0; - - for (i = addr_start; i <= addr_end; i++) { - if (((data[i] >> 7) == 0) && (data[i] > imax)) - imax = data[i]; - } - - return imax; -} - -void get_trained_CDD(u32 fsp) -{ - unsigned int i, ddr_type, tmp; - unsigned int cdd_cha[12], cdd_chb[12]; - unsigned int cdd_cha_rr_max, cdd_cha_rw_max, cdd_cha_wr_max, cdd_cha_ww_max; - unsigned int cdd_chb_rr_max, cdd_chb_rw_max, cdd_chb_wr_max, cdd_chb_ww_max; - - ddr_type = reg32_read(DDRC_MSTR(0)) & 0x3f; - if (ddr_type == 0x20) { - for (i = 0; i < 6; i++) { - tmp = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + - (0x54013UL + i) * 4); - cdd_cha[i * 2] = tmp & 0xff; - cdd_cha[i * 2 + 1] = (tmp >> 8) & 0xff; - } - - for (i = 0; i < 7; i++) { - tmp = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + - (0x5402cUL + i) * 4); - if (i == 0) { - cdd_cha[0] = (tmp >> 8) & 0xff; - } else if (i == 6) { - cdd_cha[11] = tmp & 0xff; - } else { - cdd_chb[ i * 2 - 1] = tmp & 0xff; - cdd_chb[i * 2] = (tmp >> 8) & 0xff; - } - } - - cdd_cha_rr_max = look_for_max(cdd_cha, 0, 1); - cdd_cha_rw_max = look_for_max(cdd_cha, 2, 5); - cdd_cha_wr_max = look_for_max(cdd_cha, 6, 9); - cdd_cha_ww_max = look_for_max(cdd_cha, 10, 11); - cdd_chb_rr_max = look_for_max(cdd_chb, 0, 1); - cdd_chb_rw_max = look_for_max(cdd_chb, 2, 5); - cdd_chb_wr_max = look_for_max(cdd_chb, 6, 9); - cdd_chb_ww_max = look_for_max(cdd_chb, 10, 11); - g_cdd_rr_max[fsp] = cdd_cha_rr_max > cdd_chb_rr_max ? cdd_cha_rr_max : cdd_chb_rr_max; - g_cdd_rw_max[fsp] = cdd_cha_rw_max > cdd_chb_rw_max ? cdd_cha_rw_max : cdd_chb_rw_max; - g_cdd_wr_max[fsp] = cdd_cha_wr_max > cdd_chb_wr_max ? cdd_cha_wr_max : cdd_chb_wr_max; - g_cdd_ww_max[fsp] = cdd_cha_ww_max > cdd_chb_ww_max ? cdd_cha_ww_max : cdd_chb_ww_max; - } else { - unsigned int ddr4_cdd[64]; - - for( i = 0; i < 29; i++) { - tmp = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + - (0x54012UL + i) * 4); - ddr4_cdd[i * 2] = tmp & 0xff; - ddr4_cdd[i * 2 + 1] = (tmp >> 8) & 0xff; - } - - g_cdd_rr_max[fsp] = look_for_max(ddr4_cdd, 1, 12); - g_cdd_ww_max[fsp] = look_for_max(ddr4_cdd, 13, 24); - g_cdd_rw_max[fsp] = look_for_max(ddr4_cdd, 25, 40); - g_cdd_wr_max[fsp] = look_for_max(ddr4_cdd, 41, 56); - } -} - -void update_umctl2_rank_space_setting(unsigned int pstat_num, - enum ddrc_type type) -{ - unsigned int i,ddr_type; - unsigned int rdata, tmp, tmp_t; - unsigned int ddrc_w2r,ddrc_r2w,ddrc_wr_gap,ddrc_rd_gap; - unsigned long addr_slot; - - ddr_type = reg32_read(DDRC_MSTR(0)) & 0x3f; - for (i = 0; i < pstat_num; i++) { - addr_slot = i ? (i + 1) * 0x1000 : 0; - if (ddr_type == 0x20) { - /* update r2w:[13:8], w2r:[5:0] */ - rdata = reg32_read(DDRC_DRAMTMG2(0) + addr_slot); - ddrc_w2r = rdata & 0x3f; - if (type == DDRC_TYPE_MP) - tmp = ddrc_w2r + (g_cdd_wr_max[i] >> 1); - else - tmp = ddrc_w2r + (g_cdd_wr_max[i] >> 1) + 1; - ddrc_w2r = (tmp > 0x3f) ? 0x3f : tmp; - - ddrc_r2w = (rdata >> 8) & 0x3f; - if (type == DDRC_TYPE_MP) - tmp = ddrc_r2w + (g_cdd_rw_max[i] >> 1); - else - tmp = ddrc_r2w + (g_cdd_rw_max[i] >> 1) + 1; - ddrc_r2w = (tmp > 0x3f) ? 0x3f : tmp; - - tmp_t = (rdata & 0xffffc0c0) | (ddrc_r2w << 8) | ddrc_w2r; - reg32_write((DDRC_DRAMTMG2(0) + addr_slot), tmp_t); - } else { - /* update w2r:[5:0] */ - rdata = reg32_read(DDRC_DRAMTMG9(0) + addr_slot); - ddrc_w2r = rdata & 0x3f; - if (type == DDRC_TYPE_MP) - tmp = ddrc_w2r + (g_cdd_wr_max[i] >> 1); - else - tmp = ddrc_w2r + (g_cdd_wr_max[i] >> 1) + 1; - ddrc_w2r = (tmp > 0x3f) ? 0x3f : tmp; - tmp_t = (rdata & 0xffffffc0) | ddrc_w2r; - reg32_write((DDRC_DRAMTMG9(0) + addr_slot), tmp_t); - - /* update r2w:[13:8] */ - rdata = reg32_read(DDRC_DRAMTMG2(0) + addr_slot); - ddrc_r2w = (rdata >> 8) & 0x3f; - if (type == DDRC_TYPE_MP) - tmp = ddrc_r2w + (g_cdd_rw_max[i] >> 1); - else - tmp = ddrc_r2w + (g_cdd_rw_max[i] >> 1) + 1; - ddrc_r2w = (tmp > 0x3f) ? 0x3f : tmp; - - tmp_t = (rdata & 0xffffc0ff) | (ddrc_r2w << 8); - reg32_write((DDRC_DRAMTMG2(0) + addr_slot), tmp_t); - } - - if (type != DDRC_TYPE_MQ) { - /* update rankctl: wr_gap:11:8; rd:gap:7:4; quasi-dymic, doc wrong(static) */ - rdata = reg32_read(DDRC_RANKCTL(0) + addr_slot); - ddrc_wr_gap = (rdata >> 8) & 0xf; - if (type == DDRC_TYPE_MP) - tmp = ddrc_wr_gap + (g_cdd_ww_max[i] >> 1); - else - tmp = ddrc_wr_gap + (g_cdd_ww_max[i] >> 1) + 1; - ddrc_wr_gap = (tmp > 0xf) ? 0xf : tmp; - - ddrc_rd_gap = (rdata >> 4) & 0xf; - if (type == DDRC_TYPE_MP) - tmp = ddrc_rd_gap + (g_cdd_rr_max[i] >> 1); - else - tmp = ddrc_rd_gap + (g_cdd_rr_max[i] >> 1) + 1; - ddrc_rd_gap = (tmp > 0xf) ? 0xf : tmp; - - tmp_t = (rdata & 0xfffff00f) | (ddrc_wr_gap << 8) | (ddrc_rd_gap << 4); - reg32_write((DDRC_RANKCTL(0) + addr_slot), tmp_t); - } - } - - if (type == DDRC_TYPE_MQ) { - /* update rankctl: wr_gap:11:8; rd:gap:7:4; quasi-dymic, doc wrong(static) */ - rdata = reg32_read(DDRC_RANKCTL(0)); - ddrc_wr_gap = (rdata >> 8) & 0xf; - tmp = ddrc_wr_gap + (g_cdd_ww_max[0] >> 1) + 1; - ddrc_wr_gap = (tmp > 0xf) ? 0xf : tmp; - - ddrc_rd_gap = (rdata >> 4) & 0xf; - tmp = ddrc_rd_gap + (g_cdd_rr_max[0] >> 1) + 1; - ddrc_rd_gap = (tmp > 0xf) ? 0xf : tmp; - - tmp_t = (rdata & 0xfffff00f) | (ddrc_wr_gap << 8) | (ddrc_rd_gap << 4); - reg32_write(DDRC_RANKCTL(0), tmp_t); - } -} diff --git a/drivers/ddr/imx8m/helper.c b/drivers/ddr/imx8m/helper.c deleted file mode 100644 index 209c55f552..0000000000 --- a/drivers/ddr/imx8m/helper.c +++ /dev/null @@ -1,88 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright 2018 NXP - */ - -#define pr_fmt(fmt) "imx8m-ddr: " fmt - -#include <common.h> -#include <io.h> -#include <errno.h> -#include <soc/imx8m/ddr.h> - -#define IMEM_LEN 32768 /* byte */ -#define DMEM_LEN 16384 /* byte */ -#define IMEM_2D_OFFSET 49152 - -#define IMEM_OFFSET_ADDR 0x00050000 -#define DMEM_OFFSET_ADDR 0x00054000 -#define DDR_TRAIN_CODE_BASE_ADDR IP2APB_DDRPHY_IPS_BASE_ADDR(0) - -void ddrphy_trained_csr_save(struct dram_cfg_param *ddrphy_csr, - unsigned int num) -{ - int i = 0; - - /* enable the ddrphy apb */ - dwc_ddrphy_apb_wr(0xd0000, 0x0); - dwc_ddrphy_apb_wr(0xc0080, 0x3); - for (i = 0; i < num; i++) { - ddrphy_csr->val = dwc_ddrphy_apb_rd(ddrphy_csr->reg); - ddrphy_csr++; - } - /* disable the ddrphy apb */ - dwc_ddrphy_apb_wr(0xc0080, 0x2); - dwc_ddrphy_apb_wr(0xd0000, 0x1); -} - -void dram_config_save(struct dram_timing_info *timing_info, - unsigned long saved_timing_base) -{ - int i = 0; - struct dram_timing_info *saved_timing = (void *)saved_timing_base; - struct dram_cfg_param *cfg; - - saved_timing->ddrc_cfg_num = timing_info->ddrc_cfg_num; - saved_timing->ddrphy_cfg_num = timing_info->ddrphy_cfg_num; - saved_timing->ddrphy_trained_csr_num = ddrphy_trained_csr_num; - saved_timing->ddrphy_pie_num = timing_info->ddrphy_pie_num; - - /* save the fsp table */ - for (i = 0; i < 4; i++) - saved_timing->fsp_table[i] = timing_info->fsp_table[i]; - - cfg = (struct dram_cfg_param *)(saved_timing_base + - sizeof(*timing_info)); - - /* save ddrc config */ - saved_timing->ddrc_cfg = cfg; - for (i = 0; i < timing_info->ddrc_cfg_num; i++) { - cfg->reg = timing_info->ddrc_cfg[i].reg; - cfg->val = timing_info->ddrc_cfg[i].val; - cfg++; - } - - /* save ddrphy config */ - saved_timing->ddrphy_cfg = cfg; - for (i = 0; i < timing_info->ddrphy_cfg_num; i++) { - cfg->reg = timing_info->ddrphy_cfg[i].reg; - cfg->val = timing_info->ddrphy_cfg[i].val; - cfg++; - } - - /* save the ddrphy csr */ - saved_timing->ddrphy_trained_csr = cfg; - for (i = 0; i < ddrphy_trained_csr_num; i++) { - cfg->reg = ddrphy_trained_csr[i].reg; - cfg->val = ddrphy_trained_csr[i].val; - cfg++; - } - - /* save the ddrphy pie */ - saved_timing->ddrphy_pie = cfg; - for (i = 0; i < timing_info->ddrphy_pie_num; i++) { - cfg->reg = timing_info->ddrphy_pie[i].reg; - cfg->val = timing_info->ddrphy_pie[i].val; - cfg++; - } -} |