Commit 258db72309ec47b99cec89c06f6b4491f9951b27

Authored by Bai Ping
1 parent e2985a6e64

MLK-19777-01: imx8mm: rename the lpddr4_ddrphy_train file

For LPDDR4 or DDR4, the ddr phy train flow is the same.
So rename the 'lpddr4_ddrphy_train.c' to 'ddrphy_train.c'.
make it more common for reuse and move it to driver/ddr/imx8m/.

Signed-off-by: Bai Ping <ping.bai@nxp.com>

Showing 7 changed files with 276 additions and 283 deletions Side-by-side Diff

arch/arm/include/asm/arch-imx8m/imx8m_ddr.h
... ... @@ -52,7 +52,7 @@
52 52  
53 53 void ddr_load_train_firmware(enum fw_type type);
54 54 void ddr_init(struct dram_timing_info *timing_info);
55   -void lpddr4_cfg_phy(struct dram_timing_info *timing_info);
  55 +void ddr_cfg_phy(struct dram_timing_info *timing_info);
56 56 void load_lpddr4_phy_pie(void);
57 57 void ddrphy_trained_csr_save(struct dram_cfg_param *, unsigned int);
58 58 void dram_config_save(struct dram_timing_info *, unsigned long);
drivers/ddr/imx8m/Makefile
... ... @@ -5,7 +5,7 @@
5 5 #
6 6  
7 7 ifdef CONFIG_SPL_BUILD
8   -obj-$(CONFIG_IMX8M_DRAM) += helper.o ddrphy_utils.o
9   -obj-$(CONFIG_IMX8M_LPDDR4) += lpddr4/
  8 +obj-$(CONFIG_IMX8M_DRAM) += helper.o ddrphy_utils.o ddrphy_train.o
  9 +obj-$(CONFIG_IMX8M_LPDDR4) += lpddr4_init.o
10 10 endif
drivers/ddr/imx8m/ddrphy_train.c
  1 +/*
  2 + * Copyright 2018 NXP
  3 + *
  4 + * SPDX-License-Identifier: GPL-2.0+
  5 + */
  6 +#include <common.h>
  7 +#include <linux/kernel.h>
  8 +#include <asm/arch/imx8m_ddr.h>
  9 +#include <asm/arch/lpddr4_define.h>
  10 +
  11 +void ddr_cfg_phy(struct dram_timing_info *dram_timing)
  12 +{
  13 + struct dram_cfg_param *dram_cfg;
  14 + struct dram_fsp_msg *fsp_msg;
  15 + unsigned int num;
  16 + int i = 0;
  17 + int j = 0;
  18 +
  19 + /* initialize PHY configuration */
  20 + dram_cfg = dram_timing->ddrphy_cfg;
  21 + num = dram_timing->ddrphy_cfg_num;
  22 + for (i = 0; i < num; i++) {
  23 + /* config phy reg */
  24 + dwc_ddrphy_apb_wr(dram_cfg->reg, dram_cfg->val);
  25 + dram_cfg++;
  26 + }
  27 +
  28 + /* load the frequency setpoint message block config */
  29 + fsp_msg = dram_timing->fsp_msg;
  30 + for (i = 0; i < dram_timing->fsp_msg_num; i++) {
  31 + printf("DRAM PHY training for %dMTS\n", fsp_msg->drate);
  32 + /* set dram PHY input clocks to desired frequency */
  33 + ddrphy_init_set_dfi_clk(fsp_msg->drate);
  34 +
  35 + /* load the dram training firmware image */
  36 + dwc_ddrphy_apb_wr(0xd0000,0x0);
  37 + ddr_load_train_firmware(fsp_msg->fw_type);
  38 +
  39 + /* load the frequency set point message block parameter */
  40 + dram_cfg = fsp_msg->fsp_cfg;
  41 + num = fsp_msg->fsp_cfg_num;
  42 + for (j = 0; j < num; j++) {
  43 + dwc_ddrphy_apb_wr(dram_cfg->reg, dram_cfg->val);
  44 + dram_cfg++;
  45 + }
  46 +
  47 + /*
  48 + * -------------------- excute the firmware --------------------
  49 + * Running the firmware is a simply process to taking the
  50 + * PMU out of reset and stall, then the firwmare will be run
  51 + * 1. reset the PMU;
  52 + * 2. begin the excution;
  53 + * 3. wait for the training done;
  54 + * 4. read the message block result.
  55 + * -------------------------------------------------------------
  56 + */
  57 + dwc_ddrphy_apb_wr(0xd0000, 0x1);
  58 + dwc_ddrphy_apb_wr(0xd0099, 0x9);
  59 + dwc_ddrphy_apb_wr(0xd0099, 0x1);
  60 + dwc_ddrphy_apb_wr(0xd0099, 0x0);
  61 +
  62 + /* Wait for the training firmware to complete */
  63 + wait_ddrphy_training_complete();
  64 +
  65 + /* Halt the microcontroller. */
  66 + dwc_ddrphy_apb_wr(0xd0099, 0x1);
  67 +
  68 + /* Read the Message Block results */
  69 + dwc_ddrphy_apb_wr(0xd0000, 0x0);
  70 + ddrphy_init_read_msg_block(fsp_msg->fw_type);
  71 + dwc_ddrphy_apb_wr(0xd0000, 0x1);
  72 +
  73 + fsp_msg++;
  74 + }
  75 +
  76 + /* Load PHY Init Engine Image */
  77 + dram_cfg = dram_timing->ddrphy_pie;
  78 + num = dram_timing->ddrphy_pie_num;
  79 + for (i = 0; i < num; i++) {
  80 + dwc_ddrphy_apb_wr(dram_cfg->reg, dram_cfg->val);
  81 + dram_cfg++;
  82 + }
  83 +
  84 + /* save the ddr PHY trained CSR in memory for low power use */
  85 + ddrphy_trained_csr_save(dram_timing->ddrphy_trained_csr,
  86 + dram_timing->ddrphy_trained_csr_num);
  87 +}
drivers/ddr/imx8m/lpddr4/Makefile
1   -#
2   -# Copyright 2018 NXP
3   -#
4   -# SPDX-License-Identifier: GPL-2.0+
5   -#
6   -
7   -obj-$(CONFIG_SPL_BUILD) += lpddr4_init.o lpddr4_ddrphy_train.o
drivers/ddr/imx8m/lpddr4/lpddr4_ddrphy_train.c
1   -/*
2   - * Copyright 2018 NXP
3   - *
4   - * SPDX-License-Identifier: GPL-2.0+
5   - */
6   -#include <common.h>
7   -#include <linux/kernel.h>
8   -#include <asm/arch/imx8m_ddr.h>
9   -#include <asm/arch/lpddr4_define.h>
10   -
11   -void lpddr4_cfg_phy(struct dram_timing_info *dram_timing)
12   -{
13   - struct dram_cfg_param *dram_cfg;
14   - struct dram_fsp_msg *fsp_msg;
15   - unsigned int num;
16   - int i = 0;
17   - int j = 0;
18   -
19   - /* initialize PHY configuration */
20   - dram_cfg = dram_timing->ddrphy_cfg;
21   - num = dram_timing->ddrphy_cfg_num;
22   - for (i = 0; i < num; i++) {
23   - /* config phy reg */
24   - dwc_ddrphy_apb_wr(dram_cfg->reg, dram_cfg->val);
25   - dram_cfg++;
26   - }
27   -
28   - /* load the frequency setpoint message block config */
29   - fsp_msg = dram_timing->fsp_msg;
30   - for (i = 0; i < dram_timing->fsp_msg_num; i++) {
31   - printf("DRAM PHY training for %dMTS\n", fsp_msg->drate);
32   - /* set dram PHY input clocks to desired frequency */
33   - ddrphy_init_set_dfi_clk(fsp_msg->drate);
34   -
35   - /* load the dram training firmware image */
36   - dwc_ddrphy_apb_wr(0xd0000,0x0);
37   - ddr_load_train_firmware(fsp_msg->fw_type);
38   -
39   - /* load the frequency set point message block parameter */
40   - dram_cfg = fsp_msg->fsp_cfg;
41   - num = fsp_msg->fsp_cfg_num;
42   - for (j = 0; j < num; j++) {
43   - dwc_ddrphy_apb_wr(dram_cfg->reg, dram_cfg->val);
44   - dram_cfg++;
45   - }
46   -
47   - /*
48   - * -------------------- excute the firmware --------------------
49   - * Running the firmware is a simply process to taking the
50   - * PMU out of reset and stall, then the firwmare will be run
51   - * 1. reset the PMU;
52   - * 2. begin the excution;
53   - * 3. wait for the training done;
54   - * 4. read the message block result.
55   - * -------------------------------------------------------------
56   - */
57   - dwc_ddrphy_apb_wr(0xd0000, 0x1);
58   - dwc_ddrphy_apb_wr(0xd0099, 0x9);
59   - dwc_ddrphy_apb_wr(0xd0099, 0x1);
60   - dwc_ddrphy_apb_wr(0xd0099, 0x0);
61   -
62   - /* Wait for the training firmware to complete */
63   - wait_ddrphy_training_complete();
64   -
65   - /* Halt the microcontroller. */
66   - dwc_ddrphy_apb_wr(0xd0099, 0x1);
67   -
68   - /* Read the Message Block results */
69   - dwc_ddrphy_apb_wr(0xd0000, 0x0);
70   - ddrphy_init_read_msg_block(fsp_msg->fw_type);
71   - dwc_ddrphy_apb_wr(0xd0000, 0x1);
72   -
73   - fsp_msg++;
74   - }
75   -
76   - /* Load PHY Init Engine Image */
77   - dram_cfg = dram_timing->ddrphy_pie;
78   - num = dram_timing->ddrphy_pie_num;
79   - for (i = 0; i < num; i++) {
80   - dwc_ddrphy_apb_wr(dram_cfg->reg, dram_cfg->val);
81   - dram_cfg++;
82   - }
83   -
84   - /* save the ddr PHY trained CSR in memory for low power use */
85   - ddrphy_trained_csr_save(dram_timing->ddrphy_trained_csr,
86   - dram_timing->ddrphy_trained_csr_num);
87   -}
drivers/ddr/imx8m/lpddr4/lpddr4_init.c
1   -/*
2   -* Copyright 2018 NXP
3   -*
4   -* SPDX-License-Identifier: GPL-2.0+
5   -*/
6   -
7   -#include <common.h>
8   -#include <errno.h>
9   -#include <asm/io.h>
10   -#include <asm/arch/ddr.h>
11   -#include <asm/arch/clock.h>
12   -#include <asm/arch/imx8m_ddr.h>
13   -#include <asm/arch/lpddr4_define.h>
14   -#include <asm/arch/sys_proto.h>
15   -
16   -void lpddr4_cfg_umctl2(struct dram_cfg_param *ddrc_cfg, int num)
17   -{
18   - int i = 0;
19   -
20   - for (i = 0; i < num; i++) {
21   - reg32_write(ddrc_cfg->reg, ddrc_cfg->val);
22   - ddrc_cfg++;
23   - }
24   -}
25   -
26   -void ddr_init(struct dram_timing_info *dram_timing)
27   -{
28   - unsigned int tmp;
29   -
30   - printf("DDRINFO: start lpddr4 ddr init\n");
31   - /* step 1: reset */
32   - if (is_imx8mq()) {
33   - reg32_write(SRC_DDRC_RCR_ADDR + 0x04, 0x8F00000F);
34   - reg32_write(SRC_DDRC_RCR_ADDR, 0x8F00000F);
35   - reg32_write(SRC_DDRC_RCR_ADDR + 0x04, 0x8F000000);
36   - } else {
37   - reg32_write(SRC_DDRC_RCR_ADDR, 0x8F00001F);
38   - reg32_write(SRC_DDRC_RCR_ADDR, 0x8F00000F);
39   - }
40   -
41   - mdelay(100);
42   -
43   - debug("DDRINFO: reset done\n");
44   - /* change the clock source of dram_apb_clk_root: source 4 800MHz /4 = 200MHz */
45   - clock_set_target_val(DRAM_APB_CLK_ROOT, CLK_ROOT_ON | CLK_ROOT_SOURCE_SEL(4) |
46   - CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV4));
47   -
48   - /* disable iso */
49   - reg32_write(0x303A00EC, 0x0000ffff); /* PGC_CPU_MAPPING */
50   - reg32setbit(0x303A00F8, 5); /* PU_PGC_SW_PUP_REQ */
51   -
52   - debug("DDRINFO: cfg clk\n");
53   - dram_pll_init(DRAM_PLL_OUT_750M);
54   -
55   - /*
56   - * release [0]ddr1_preset_n, [1]ddr1_core_reset_n,
57   - * [2]ddr1_phy_reset, [3]ddr1_phy_pwrokin_n
58   - */
59   - reg32_write(SRC_DDRC_RCR_ADDR, 0x8F000006);
60   -
61   - /*step2 Configure uMCTL2's registers */
62   - debug("DDRINFO: ddrc config start\n");
63   - lpddr4_cfg_umctl2(dram_timing->ddrc_cfg, dram_timing->ddrc_cfg_num);
64   - debug("DDRINFO: ddrc config done\n");
65   -
66   - /*
67   - * step3 de-assert all reset
68   - * RESET: <core_ddrc_rstn> DEASSERTED
69   - * RESET: <aresetn> for Port 0 DEASSERT(0)ED
70   - */
71   - reg32_write(SRC_DDRC_RCR_ADDR, 0x8F000004);
72   - reg32_write(SRC_DDRC_RCR_ADDR, 0x8F000000);
73   -
74   - reg32_write(DDRC_DBG1(0), 0x00000000);
75   - /* step4 */
76   - /* [0]dis_auto_refresh=1 */
77   - reg32_write(DDRC_RFSHCTL3(0), 0x00000011);
78   -
79   - /* [8]--1: lpddr4_sr allowed; [5]--1: software entry to SR */
80   - reg32_write(DDRC_PWRCTL(0), 0x000000a8);
81   -
82   - do {
83   - tmp = reg32_read(DDRC_STAT(0));
84   - } while ((tmp & 0x33f) != 0x223);
85   -
86   - reg32_write(DDRC_DDR_SS_GPR0, 0x01); /* LPDDR4 mode */
87   -
88   - /* step5 */
89   - reg32_write(DDRC_SWCTL(0), 0x00000000);
90   -
91   - /* step6 */
92   - tmp = reg32_read(DDRC_MSTR2(0));
93   - if (tmp == 0x2) {
94   - reg32_write(DDRC_DFIMISC(0), 0x00000210);
95   - } else if (tmp == 0x1) {
96   - reg32_write(DDRC_DFIMISC(0), 0x00000110);
97   - } else {
98   - reg32_write(DDRC_DFIMISC(0), 0x00000010);
99   - }
100   -
101   - /* step7 [0]--1: disable quasi-dynamic programming */
102   - reg32_write(DDRC_SWCTL(0), 0x00000001);
103   -
104   - /* step8 Configure LPDDR4 PHY's registers */
105   - debug("DDRINFO:ddrphy config start\n");
106   - lpddr4_cfg_phy(dram_timing);
107   - debug("DDRINFO: ddrphy config done\n");
108   -
109   - /*
110   - * step14 CalBusy.0 =1, indicates the calibrator is actively
111   - * calibrating. Wait Calibrating done.
112   - */
113   - do {
114   - tmp = reg32_read(DDRPHY_CalBusy(0));
115   - } while ((tmp & 0x1));
116   -
117   - printf("DDRINFO:ddrphy calibration done\n");
118   -
119   - /* step15 [0]--0: to enable quasi-dynamic programming */
120   - reg32_write(DDRC_SWCTL(0), 0x00000000);
121   -
122   - /* step16 */
123   - tmp = reg32_read(DDRC_MSTR2(0));
124   - if (tmp == 0x2) {
125   - reg32_write(DDRC_DFIMISC(0), 0x00000230);
126   - } else if (tmp == 0x1) {
127   - reg32_write(DDRC_DFIMISC(0), 0x00000130);
128   - } else {
129   - reg32_write(DDRC_DFIMISC(0), 0x00000030);
130   - }
131   -
132   - /* step17 [0]--1: disable quasi-dynamic programming */
133   - reg32_write(DDRC_SWCTL(0), 0x00000001);
134   - /* step18 wait DFISTAT.dfi_init_complete to 1 */
135   - do {
136   - tmp = reg32_read(DDRC_DFISTAT(0));
137   - } while ((tmp & 0x1) == 0x0);
138   -
139   - /* step19 */
140   - reg32_write(DDRC_SWCTL(0), 0x00000000);
141   -
142   - /* step20~22 */
143   - tmp = reg32_read(DDRC_MSTR2(0));
144   - if (tmp == 0x2) {
145   - reg32_write(DDRC_DFIMISC(0), 0x00000210);
146   - /* set DFIMISC.dfi_init_complete_en again */
147   - reg32_write(DDRC_DFIMISC(0), 0x00000211);
148   - } else if (tmp == 0x1) {
149   - reg32_write(DDRC_DFIMISC(0), 0x00000110);
150   - /* set DFIMISC.dfi_init_complete_en again */
151   - reg32_write(DDRC_DFIMISC(0), 0x00000111);
152   - } else {
153   - /* clear DFIMISC.dfi_init_complete_en */
154   - reg32_write(DDRC_DFIMISC(0), 0x00000010);
155   - /* set DFIMISC.dfi_init_complete_en again */
156   - reg32_write(DDRC_DFIMISC(0), 0x00000011);
157   - }
158   -
159   - /* step23 [5]selfref_sw=0; */
160   - reg32_write(DDRC_PWRCTL(0), 0x00000008);
161   - /* step24 sw_done=1 */
162   - reg32_write(DDRC_SWCTL(0), 0x00000001);
163   -
164   - /* step25 wait SWSTAT.sw_done_ack to 1 */
165   - do {
166   - tmp = reg32_read(DDRC_SWSTAT(0));
167   - } while ((tmp & 0x1) == 0x0);
168   -
169   -#ifdef DFI_BUG_WR
170   - reg32_write(DDRC_DFIPHYMSTR(0), 0x00000001);
171   -#endif
172   - /* wait STAT.operating_mode([1:0] for ddr3) to normal state */
173   - do {
174   - tmp = reg32_read(DDRC_STAT(0));
175   - } while ((tmp & 0x3) != 0x1);
176   -
177   - /* step26 */
178   - reg32_write(DDRC_RFSHCTL3(0), 0x00000010);
179   -
180   - /* enable port 0 */
181   - reg32_write(DDRC_PCTRL_0(0), 0x00000001);
182   - printf("DDRINFO: ddrmix config done\n");
183   -
184   - /* save the dram timing config into memory */
185   - dram_config_save(dram_timing, CONFIG_SAVED_DRAM_TIMING_BASE);
186   -}
drivers/ddr/imx8m/lpddr4_init.c
  1 +/*
  2 +* Copyright 2018 NXP
  3 +*
  4 +* SPDX-License-Identifier: GPL-2.0+
  5 +*/
  6 +
  7 +#include <common.h>
  8 +#include <errno.h>
  9 +#include <asm/io.h>
  10 +#include <asm/arch/ddr.h>
  11 +#include <asm/arch/clock.h>
  12 +#include <asm/arch/imx8m_ddr.h>
  13 +#include <asm/arch/lpddr4_define.h>
  14 +#include <asm/arch/sys_proto.h>
  15 +
  16 +void lpddr4_cfg_umctl2(struct dram_cfg_param *ddrc_cfg, int num)
  17 +{
  18 + int i = 0;
  19 +
  20 + for (i = 0; i < num; i++) {
  21 + reg32_write(ddrc_cfg->reg, ddrc_cfg->val);
  22 + ddrc_cfg++;
  23 + }
  24 +}
  25 +
  26 +void ddr_init(struct dram_timing_info *dram_timing)
  27 +{
  28 + unsigned int tmp;
  29 +
  30 + printf("DDRINFO: start lpddr4 ddr init\n");
  31 + /* step 1: reset */
  32 + if (is_imx8mq()) {
  33 + reg32_write(SRC_DDRC_RCR_ADDR + 0x04, 0x8F00000F);
  34 + reg32_write(SRC_DDRC_RCR_ADDR, 0x8F00000F);
  35 + reg32_write(SRC_DDRC_RCR_ADDR + 0x04, 0x8F000000);
  36 + } else {
  37 + reg32_write(SRC_DDRC_RCR_ADDR, 0x8F00001F);
  38 + reg32_write(SRC_DDRC_RCR_ADDR, 0x8F00000F);
  39 + }
  40 +
  41 + mdelay(100);
  42 +
  43 + debug("DDRINFO: reset done\n");
  44 + /* change the clock source of dram_apb_clk_root: source 4 800MHz /4 = 200MHz */
  45 + clock_set_target_val(DRAM_APB_CLK_ROOT, CLK_ROOT_ON | CLK_ROOT_SOURCE_SEL(4) |
  46 + CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV4));
  47 +
  48 + /* disable iso */
  49 + reg32_write(0x303A00EC, 0x0000ffff); /* PGC_CPU_MAPPING */
  50 + reg32setbit(0x303A00F8, 5); /* PU_PGC_SW_PUP_REQ */
  51 +
  52 + debug("DDRINFO: cfg clk\n");
  53 + dram_pll_init(DRAM_PLL_OUT_750M);
  54 +
  55 + /*
  56 + * release [0]ddr1_preset_n, [1]ddr1_core_reset_n,
  57 + * [2]ddr1_phy_reset, [3]ddr1_phy_pwrokin_n
  58 + */
  59 + reg32_write(SRC_DDRC_RCR_ADDR, 0x8F000006);
  60 +
  61 + /*step2 Configure uMCTL2's registers */
  62 + debug("DDRINFO: ddrc config start\n");
  63 + lpddr4_cfg_umctl2(dram_timing->ddrc_cfg, dram_timing->ddrc_cfg_num);
  64 + debug("DDRINFO: ddrc config done\n");
  65 +
  66 + /*
  67 + * step3 de-assert all reset
  68 + * RESET: <core_ddrc_rstn> DEASSERTED
  69 + * RESET: <aresetn> for Port 0 DEASSERT(0)ED
  70 + */
  71 + reg32_write(SRC_DDRC_RCR_ADDR, 0x8F000004);
  72 + reg32_write(SRC_DDRC_RCR_ADDR, 0x8F000000);
  73 +
  74 + reg32_write(DDRC_DBG1(0), 0x00000000);
  75 + /* step4 */
  76 + /* [0]dis_auto_refresh=1 */
  77 + reg32_write(DDRC_RFSHCTL3(0), 0x00000011);
  78 +
  79 + /* [8]--1: lpddr4_sr allowed; [5]--1: software entry to SR */
  80 + reg32_write(DDRC_PWRCTL(0), 0x000000a8);
  81 +
  82 + do {
  83 + tmp = reg32_read(DDRC_STAT(0));
  84 + } while ((tmp & 0x33f) != 0x223);
  85 +
  86 + reg32_write(DDRC_DDR_SS_GPR0, 0x01); /* LPDDR4 mode */
  87 +
  88 + /* step5 */
  89 + reg32_write(DDRC_SWCTL(0), 0x00000000);
  90 +
  91 + /* step6 */
  92 + tmp = reg32_read(DDRC_MSTR2(0));
  93 + if (tmp == 0x2) {
  94 + reg32_write(DDRC_DFIMISC(0), 0x00000210);
  95 + } else if (tmp == 0x1) {
  96 + reg32_write(DDRC_DFIMISC(0), 0x00000110);
  97 + } else {
  98 + reg32_write(DDRC_DFIMISC(0), 0x00000010);
  99 + }
  100 +
  101 + /* step7 [0]--1: disable quasi-dynamic programming */
  102 + reg32_write(DDRC_SWCTL(0), 0x00000001);
  103 +
  104 + /* step8 Configure LPDDR4 PHY's registers */
  105 + debug("DDRINFO:ddrphy config start\n");
  106 + ddr_cfg_phy(dram_timing);
  107 + debug("DDRINFO: ddrphy config done\n");
  108 +
  109 + /*
  110 + * step14 CalBusy.0 =1, indicates the calibrator is actively
  111 + * calibrating. Wait Calibrating done.
  112 + */
  113 + do {
  114 + tmp = reg32_read(DDRPHY_CalBusy(0));
  115 + } while ((tmp & 0x1));
  116 +
  117 + printf("DDRINFO:ddrphy calibration done\n");
  118 +
  119 + /* step15 [0]--0: to enable quasi-dynamic programming */
  120 + reg32_write(DDRC_SWCTL(0), 0x00000000);
  121 +
  122 + /* step16 */
  123 + tmp = reg32_read(DDRC_MSTR2(0));
  124 + if (tmp == 0x2) {
  125 + reg32_write(DDRC_DFIMISC(0), 0x00000230);
  126 + } else if (tmp == 0x1) {
  127 + reg32_write(DDRC_DFIMISC(0), 0x00000130);
  128 + } else {
  129 + reg32_write(DDRC_DFIMISC(0), 0x00000030);
  130 + }
  131 +
  132 + /* step17 [0]--1: disable quasi-dynamic programming */
  133 + reg32_write(DDRC_SWCTL(0), 0x00000001);
  134 + /* step18 wait DFISTAT.dfi_init_complete to 1 */
  135 + do {
  136 + tmp = reg32_read(DDRC_DFISTAT(0));
  137 + } while ((tmp & 0x1) == 0x0);
  138 +
  139 + /* step19 */
  140 + reg32_write(DDRC_SWCTL(0), 0x00000000);
  141 +
  142 + /* step20~22 */
  143 + tmp = reg32_read(DDRC_MSTR2(0));
  144 + if (tmp == 0x2) {
  145 + reg32_write(DDRC_DFIMISC(0), 0x00000210);
  146 + /* set DFIMISC.dfi_init_complete_en again */
  147 + reg32_write(DDRC_DFIMISC(0), 0x00000211);
  148 + } else if (tmp == 0x1) {
  149 + reg32_write(DDRC_DFIMISC(0), 0x00000110);
  150 + /* set DFIMISC.dfi_init_complete_en again */
  151 + reg32_write(DDRC_DFIMISC(0), 0x00000111);
  152 + } else {
  153 + /* clear DFIMISC.dfi_init_complete_en */
  154 + reg32_write(DDRC_DFIMISC(0), 0x00000010);
  155 + /* set DFIMISC.dfi_init_complete_en again */
  156 + reg32_write(DDRC_DFIMISC(0), 0x00000011);
  157 + }
  158 +
  159 + /* step23 [5]selfref_sw=0; */
  160 + reg32_write(DDRC_PWRCTL(0), 0x00000008);
  161 + /* step24 sw_done=1 */
  162 + reg32_write(DDRC_SWCTL(0), 0x00000001);
  163 +
  164 + /* step25 wait SWSTAT.sw_done_ack to 1 */
  165 + do {
  166 + tmp = reg32_read(DDRC_SWSTAT(0));
  167 + } while ((tmp & 0x1) == 0x0);
  168 +
  169 +#ifdef DFI_BUG_WR
  170 + reg32_write(DDRC_DFIPHYMSTR(0), 0x00000001);
  171 +#endif
  172 + /* wait STAT.operating_mode([1:0] for ddr3) to normal state */
  173 + do {
  174 + tmp = reg32_read(DDRC_STAT(0));
  175 + } while ((tmp & 0x3) != 0x1);
  176 +
  177 + /* step26 */
  178 + reg32_write(DDRC_RFSHCTL3(0), 0x00000010);
  179 +
  180 + /* enable port 0 */
  181 + reg32_write(DDRC_PCTRL_0(0), 0x00000001);
  182 + printf("DDRINFO: ddrmix config done\n");
  183 +
  184 + /* save the dram timing config into memory */
  185 + dram_config_save(dram_timing, CONFIG_SAVED_DRAM_TIMING_BASE);
  186 +}