summaryrefslogtreecommitdiffstats
path: root/drivers/ddr/imx/helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ddr/imx/helper.c')
-rw-r--r--drivers/ddr/imx/helper.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/drivers/ddr/imx/helper.c b/drivers/ddr/imx/helper.c
new file mode 100644
index 0000000000..f9c25f7180
--- /dev/null
+++ b/drivers/ddr/imx/helper.c
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2018 NXP
+ */
+
+#define pr_fmt(fmt) "imx-ddr: " fmt
+
+#include <common.h>
+#include <io.h>
+#include <errno.h>
+#include <soc/imx8m/ddr.h>
+
+/*
+ * We deprecate ddrphy_trained_csr(_num) for board code, so we can set it
+ * ourselves here
+ */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+
+void ddrphy_trained_csr_save(struct dram_controller *dram, struct dram_cfg_param *ddrphy_csr,
+ unsigned int num)
+{
+ int i = 0;
+
+ /* enable the ddrphy apb */
+ dwc_ddrphy_apb_wr(dram, 0xd0000, 0x0);
+ dwc_ddrphy_apb_wr(dram, 0xc0080, 0x3);
+ for (i = 0; i < num; i++) {
+ ddrphy_csr->val = dwc_ddrphy_apb_rd(dram, ddrphy_csr->reg);
+ ddrphy_csr++;
+ }
+ /* disable the ddrphy apb */
+ dwc_ddrphy_apb_wr(dram, 0xc0080, 0x2);
+ dwc_ddrphy_apb_wr(dram, 0xd0000, 0x1);
+}
+
+void *dram_config_save(struct dram_controller *dram, 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++;
+ }
+
+ if (dram->imx8m_ddr_old_spreadsheet) {
+ cfg->reg = DDRC_ADDRMAP7(0);
+ cfg->val = 0xf0f;
+ 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++;
+ }
+
+ return cfg;
+}