summaryrefslogtreecommitdiffstats
path: root/drivers/ddr/imx8m/helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ddr/imx8m/helper.c')
-rw-r--r--drivers/ddr/imx8m/helper.c86
1 files changed, 86 insertions, 0 deletions
diff --git a/drivers/ddr/imx8m/helper.c b/drivers/ddr/imx8m/helper.c
new file mode 100644
index 0000000000..9e32ef9376
--- /dev/null
+++ b/drivers/ddr/imx8m/helper.c
@@ -0,0 +1,86 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2018 NXP
+ */
+
+#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++;
+ }
+}