2 * DDR controller configuration for the i.MX7 architecture
4 * (C) Copyright 2017 CompuLab, Ltd. http://www.compulab.com
6 * Author: Uri Mashiach <uri.mashiach@compulab.co.il>
8 * SPDX-License-Identifier: GPL-2.0+
11 #include <linux/types.h>
13 #include <asm/arch/imx-regs.h>
14 #include <asm/arch/crm_regs.h>
15 #include <asm/arch/mx7-ddr.h>
19 * Routine: mx7_dram_cfg
20 * Description: DDR controller configuration
22 * @ddrc_regs_val: DDRC registers value
23 * @ddrc_mp_val: DDRC_MP registers value
24 * @ddr_phy_regs_val: DDR_PHY registers value
25 * @calib_param: calibration parameters
28 void mx7_dram_cfg(struct ddrc
*ddrc_regs_val
, struct ddrc_mp
*ddrc_mp_val
,
29 struct ddr_phy
*ddr_phy_regs_val
,
30 struct mx7_calibration
*calib_param
)
32 struct src
*const src_regs
= (struct src
*)SRC_BASE_ADDR
;
33 struct ddrc
*const ddrc_regs
= (struct ddrc
*)DDRC_IPS_BASE_ADDR
;
34 struct ddrc_mp
*const ddrc_mp_reg
= (struct ddrc_mp
*)DDRC_MP_BASE_ADDR
;
35 struct ddr_phy
*const ddr_phy_regs
=
36 (struct ddr_phy
*)DDRPHY_IPS_BASE_ADDR
;
37 struct iomuxc_gpr_base_regs
*const iomuxc_gpr_regs
=
38 (struct iomuxc_gpr_base_regs
*)IOMUXC_GPR_BASE_ADDR
;
41 /* Assert DDR Controller preset and DDR PHY reset */
42 writel(SRC_DDRC_RCR_DDRC_CORE_RST_MASK
, &src_regs
->ddrc_rcr
);
44 /* DDR controller configuration */
45 writel(ddrc_regs_val
->mstr
, &ddrc_regs
->mstr
);
46 writel(ddrc_regs_val
->rfshtmg
, &ddrc_regs
->rfshtmg
);
47 writel(ddrc_mp_val
->pctrl_0
, &ddrc_mp_reg
->pctrl_0
);
48 writel(ddrc_regs_val
->init1
, &ddrc_regs
->init1
);
49 writel(ddrc_regs_val
->init0
, &ddrc_regs
->init0
);
50 writel(ddrc_regs_val
->init3
, &ddrc_regs
->init3
);
51 writel(ddrc_regs_val
->init4
, &ddrc_regs
->init4
);
52 writel(ddrc_regs_val
->init5
, &ddrc_regs
->init5
);
53 writel(ddrc_regs_val
->rankctl
, &ddrc_regs
->rankctl
);
54 writel(ddrc_regs_val
->dramtmg0
, &ddrc_regs
->dramtmg0
);
55 writel(ddrc_regs_val
->dramtmg1
, &ddrc_regs
->dramtmg1
);
56 writel(ddrc_regs_val
->dramtmg2
, &ddrc_regs
->dramtmg2
);
57 writel(ddrc_regs_val
->dramtmg3
, &ddrc_regs
->dramtmg3
);
58 writel(ddrc_regs_val
->dramtmg4
, &ddrc_regs
->dramtmg4
);
59 writel(ddrc_regs_val
->dramtmg5
, &ddrc_regs
->dramtmg5
);
60 writel(ddrc_regs_val
->dramtmg8
, &ddrc_regs
->dramtmg8
);
61 writel(ddrc_regs_val
->zqctl0
, &ddrc_regs
->zqctl0
);
62 writel(ddrc_regs_val
->dfitmg0
, &ddrc_regs
->dfitmg0
);
63 writel(ddrc_regs_val
->dfitmg1
, &ddrc_regs
->dfitmg1
);
64 writel(ddrc_regs_val
->dfiupd0
, &ddrc_regs
->dfiupd0
);
65 writel(ddrc_regs_val
->dfiupd1
, &ddrc_regs
->dfiupd1
);
66 writel(ddrc_regs_val
->dfiupd2
, &ddrc_regs
->dfiupd2
);
67 writel(ddrc_regs_val
->addrmap0
, &ddrc_regs
->addrmap0
);
68 writel(ddrc_regs_val
->addrmap1
, &ddrc_regs
->addrmap1
);
69 writel(ddrc_regs_val
->addrmap4
, &ddrc_regs
->addrmap4
);
70 writel(ddrc_regs_val
->addrmap5
, &ddrc_regs
->addrmap5
);
71 writel(ddrc_regs_val
->addrmap6
, &ddrc_regs
->addrmap6
);
72 writel(ddrc_regs_val
->odtcfg
, &ddrc_regs
->odtcfg
);
73 writel(ddrc_regs_val
->odtmap
, &ddrc_regs
->odtmap
);
75 /* De-assert DDR Controller preset and DDR PHY reset */
76 clrbits_le32(&src_regs
->ddrc_rcr
, SRC_DDRC_RCR_DDRC_CORE_RST_MASK
);
78 /* PHY configuration */
79 writel(ddr_phy_regs_val
->phy_con0
, &ddr_phy_regs
->phy_con0
);
80 writel(ddr_phy_regs_val
->phy_con1
, &ddr_phy_regs
->phy_con1
);
81 writel(ddr_phy_regs_val
->phy_con4
, &ddr_phy_regs
->phy_con4
);
82 writel(ddr_phy_regs_val
->mdll_con0
, &ddr_phy_regs
->mdll_con0
);
83 writel(ddr_phy_regs_val
->drvds_con0
, &ddr_phy_regs
->drvds_con0
);
84 writel(ddr_phy_regs_val
->offset_wr_con0
, &ddr_phy_regs
->offset_wr_con0
);
85 writel(ddr_phy_regs_val
->offset_rd_con0
, &ddr_phy_regs
->offset_rd_con0
);
86 writel(ddr_phy_regs_val
->cmd_sdll_con0
|
87 DDR_PHY_CMD_SDLL_CON0_CTRL_RESYNC_MASK
,
88 &ddr_phy_regs
->cmd_sdll_con0
);
89 writel(ddr_phy_regs_val
->cmd_sdll_con0
&
90 ~DDR_PHY_CMD_SDLL_CON0_CTRL_RESYNC_MASK
,
91 &ddr_phy_regs
->cmd_sdll_con0
);
92 writel(ddr_phy_regs_val
->offset_lp_con0
, &ddr_phy_regs
->offset_lp_con0
);
95 for (i
= 0; i
< calib_param
->num_val
; i
++)
96 writel(calib_param
->values
[i
], &ddr_phy_regs
->zq_con0
);
99 HW_CCM_CCGR_WR(CCGR_IDX_DDR
, CCM_CLK_ON_N_N
);
100 writel(IOMUXC_GPR_GPR8_ddr_phy_ctrl_wake_up(0xf) |
101 IOMUXC_GPR_GPR8_ddr_phy_dfi_init_start_MASK
,
102 &iomuxc_gpr_regs
->gpr
[8]);
103 HW_CCM_CCGR_WR(CCGR_IDX_DDR
, CCM_CLK_ON_R_W
);
107 * Routine: imx_ddr_size
108 * Description: extract the current DRAM size from the DDRC registers
112 unsigned int imx_ddr_size(void)
114 struct ddrc
*const ddrc_regs
= (struct ddrc
*)DDRC_IPS_BASE_ADDR
;
115 u32 reg_val
, field_val
;
116 int bits
= 0;/* Number of address bits */
118 /* Count data bus width bits */
119 reg_val
= readl(&ddrc_regs
->mstr
);
120 field_val
= (reg_val
& MSTR_DATA_BUS_WIDTH_MASK
) >> MSTR_DATA_BUS_WIDTH_SHIFT
;
121 bits
+= 2 - field_val
;
122 /* Count rank address bits */
123 field_val
= (reg_val
& MSTR_DATA_ACTIVE_RANKS_MASK
) >> MSTR_DATA_ACTIVE_RANKS_SHIFT
;
125 bits
+= field_val
- 1;
126 /* Count column address bits */
127 bits
+= 2;/* Column address 0 and 1 are fixed mapped */
128 reg_val
= readl(&ddrc_regs
->addrmap2
);
129 field_val
= (reg_val
& ADDRMAP2_COL_B2_MASK
) >> ADDRMAP2_COL_B2_SHIFT
;
132 field_val
= (reg_val
& ADDRMAP2_COL_B3_MASK
) >> ADDRMAP2_COL_B3_SHIFT
;
135 field_val
= (reg_val
& ADDRMAP2_COL_B4_MASK
) >> ADDRMAP2_COL_B4_SHIFT
;
138 field_val
= (reg_val
& ADDRMAP2_COL_B5_MASK
) >> ADDRMAP2_COL_B5_SHIFT
;
141 reg_val
= readl(&ddrc_regs
->addrmap3
);
142 field_val
= (reg_val
& ADDRMAP3_COL_B6_MASK
) >> ADDRMAP3_COL_B6_SHIFT
;
145 field_val
= (reg_val
& ADDRMAP3_COL_B7_MASK
) >> ADDRMAP3_COL_B7_SHIFT
;
148 field_val
= (reg_val
& ADDRMAP3_COL_B8_MASK
) >> ADDRMAP3_COL_B8_SHIFT
;
151 field_val
= (reg_val
& ADDRMAP3_COL_B9_MASK
) >> ADDRMAP3_COL_B9_SHIFT
;
154 reg_val
= readl(&ddrc_regs
->addrmap4
);
155 field_val
= (reg_val
& ADDRMAP4_COL_B10_MASK
) >> ADDRMAP4_COL_B10_SHIFT
;
158 field_val
= (reg_val
& ADDRMAP4_COL_B11_MASK
) >> ADDRMAP4_COL_B11_SHIFT
;
161 /* Count row address bits */
162 reg_val
= readl(&ddrc_regs
->addrmap5
);
163 field_val
= (reg_val
& ADDRMAP5_ROW_B0_MASK
) >> ADDRMAP5_ROW_B0_SHIFT
;
166 field_val
= (reg_val
& ADDRMAP5_ROW_B1_MASK
) >> ADDRMAP5_ROW_B1_SHIFT
;
169 field_val
= (reg_val
& ADDRMAP5_ROW_B2_10_MASK
) >> ADDRMAP5_ROW_B2_10_SHIFT
;
172 field_val
= (reg_val
& ADDRMAP5_ROW_B11_MASK
) >> ADDRMAP5_ROW_B11_SHIFT
;
175 reg_val
= readl(&ddrc_regs
->addrmap6
);
176 field_val
= (reg_val
& ADDRMAP6_ROW_B12_MASK
) >> ADDRMAP6_ROW_B12_SHIFT
;
179 field_val
= (reg_val
& ADDRMAP6_ROW_B13_MASK
) >> ADDRMAP6_ROW_B13_SHIFT
;
182 field_val
= (reg_val
& ADDRMAP6_ROW_B14_MASK
) >> ADDRMAP6_ROW_B14_SHIFT
;
185 field_val
= (reg_val
& ADDRMAP6_ROW_B15_MASK
) >> ADDRMAP6_ROW_B15_SHIFT
;
188 /* Count bank bits */
189 reg_val
= readl(&ddrc_regs
->addrmap1
);
190 field_val
= (reg_val
& ADDRMAP1_BANK_B0_MASK
) >> ADDRMAP1_BANK_B0_SHIFT
;
193 field_val
= (reg_val
& ADDRMAP1_BANK_B1_MASK
) >> ADDRMAP1_BANK_B1_SHIFT
;
196 field_val
= (reg_val
& ADDRMAP1_BANK_B2_MASK
) >> ADDRMAP1_BANK_B2_SHIFT
;