Commit 7c352cd38d0ad7a25f98592182704667dfde37a8
Committed by
Tom Rini
1 parent
37be54fd13
Exists in
v2017.01-smarct4x
and in
34 other branches
am33xx: Re-enable SW levelling for DDR2
The recent changes for hw leveling on am33xx were not intended for DDR2 boards, only DDR3. Update emif_sdram_type to take a sdram_config value to check against. This lets us pass in the value we would use to configure, when we have not yet configured the board yet. In other cases update the call to be as functional as before and check an already programmed value in. Tested-by: Yan Liu <yan-liu@ti.com> Signed-off-by: Tom Rini <trini@ti.com> Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
Showing 7 changed files with 124 additions and 40 deletions Side-by-side Diff
arch/arm/cpu/armv7/am33xx/ddr.c
... | ... | @@ -123,30 +123,33 @@ |
123 | 123 | writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl); |
124 | 124 | writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl_shdw); |
125 | 125 | |
126 | - /* Perform hardware leveling. */ | |
127 | - udelay(1000); | |
128 | - writel(readl(&emif_reg[nr]->emif_ddr_ext_phy_ctrl_36) | | |
129 | - 0x100, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_36); | |
130 | - writel(readl(&emif_reg[nr]->emif_ddr_ext_phy_ctrl_36_shdw) | | |
131 | - 0x100, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_36_shdw); | |
126 | + /* Perform hardware leveling for DDR3 */ | |
127 | + if (emif_sdram_type(regs->sdram_config) == EMIF_SDRAM_TYPE_DDR3) { | |
128 | + udelay(1000); | |
129 | + writel(readl(&emif_reg[nr]->emif_ddr_ext_phy_ctrl_36) | | |
130 | + 0x100, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_36); | |
131 | + writel(readl(&emif_reg[nr]->emif_ddr_ext_phy_ctrl_36_shdw) | | |
132 | + 0x100, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_36_shdw); | |
132 | 133 | |
133 | - writel(0x80000000, &emif_reg[nr]->emif_rd_wr_lvl_rmp_ctl); | |
134 | + writel(0x80000000, &emif_reg[nr]->emif_rd_wr_lvl_rmp_ctl); | |
134 | 135 | |
135 | - /* Enable read leveling */ | |
136 | - writel(0x80000000, &emif_reg[nr]->emif_rd_wr_lvl_ctl); | |
136 | + /* Enable read leveling */ | |
137 | + writel(0x80000000, &emif_reg[nr]->emif_rd_wr_lvl_ctl); | |
137 | 138 | |
138 | - /* | |
139 | - * Enable full read and write leveling. Wait for read and write | |
140 | - * leveling bit to clear RDWRLVLFULL_START bit 31 | |
141 | - */ | |
142 | - while((readl(&emif_reg[nr]->emif_rd_wr_lvl_ctl) & 0x80000000) != 0) | |
143 | - ; | |
139 | + /* | |
140 | + * Enable full read and write leveling. Wait for read and write | |
141 | + * leveling bit to clear RDWRLVLFULL_START bit 31 | |
142 | + */ | |
143 | + while ((readl(&emif_reg[nr]->emif_rd_wr_lvl_ctl) & 0x80000000) | |
144 | + != 0) | |
145 | + ; | |
144 | 146 | |
145 | - /* Check the timeout register to see if leveling is complete */ | |
146 | - if((readl(&emif_reg[nr]->emif_status) & 0x70) != 0) | |
147 | - puts("DDR3 H/W leveling incomplete with errors\n"); | |
147 | + /* Check the timeout register to see if leveling is complete */ | |
148 | + if ((readl(&emif_reg[nr]->emif_status) & 0x70) != 0) | |
149 | + puts("DDR3 H/W leveling incomplete with errors\n"); | |
148 | 150 | |
149 | - if (emif_sdram_type() == EMIF_SDRAM_TYPE_LPDDR2) { | |
151 | + } else { | |
152 | + /* DDR2 */ | |
150 | 153 | configure_mr(nr, 0); |
151 | 154 | configure_mr(nr, 1); |
152 | 155 | } |
153 | 156 | |
... | ... | @@ -183,9 +186,49 @@ |
183 | 186 | } |
184 | 187 | |
185 | 188 | /* |
189 | + * Configure EXT PHY registers for software leveling | |
190 | + */ | |
191 | +static void ext_phy_settings_swlvl(const struct emif_regs *regs, int nr) | |
192 | +{ | |
193 | + u32 *ext_phy_ctrl_base = 0; | |
194 | + u32 *emif_ext_phy_ctrl_base = 0; | |
195 | + __maybe_unused const u32 *ext_phy_ctrl_const_regs; | |
196 | + u32 i = 0; | |
197 | + __maybe_unused u32 size; | |
198 | + | |
199 | + ext_phy_ctrl_base = (u32 *)&(regs->emif_ddr_ext_phy_ctrl_1); | |
200 | + emif_ext_phy_ctrl_base = | |
201 | + (u32 *)&(emif_reg[nr]->emif_ddr_ext_phy_ctrl_1); | |
202 | + | |
203 | + /* Configure external phy control timing registers */ | |
204 | + for (i = 0; i < EMIF_EXT_PHY_CTRL_TIMING_REG; i++) { | |
205 | + writel(*ext_phy_ctrl_base, emif_ext_phy_ctrl_base++); | |
206 | + /* Update shadow registers */ | |
207 | + writel(*ext_phy_ctrl_base++, emif_ext_phy_ctrl_base++); | |
208 | + } | |
209 | + | |
210 | +#ifdef CONFIG_AM43XX | |
211 | + /* | |
212 | + * External phy 6-24 registers do not change with ddr frequency. | |
213 | + * These only need to be set on DDR2 on AM43xx. | |
214 | + */ | |
215 | + emif_get_ext_phy_ctrl_const_regs(&ext_phy_ctrl_const_regs, &size); | |
216 | + | |
217 | + if (!size) | |
218 | + return; | |
219 | + | |
220 | + for (i = 0; i < size; i++) { | |
221 | + writel(ext_phy_ctrl_const_regs[i], emif_ext_phy_ctrl_base++); | |
222 | + /* Update shadow registers */ | |
223 | + writel(ext_phy_ctrl_const_regs[i], emif_ext_phy_ctrl_base++); | |
224 | + } | |
225 | +#endif | |
226 | +} | |
227 | + | |
228 | +/* | |
186 | 229 | * Configure EXT PHY registers for hardware leveling |
187 | 230 | */ |
188 | -static void ext_phy_settings(const struct emif_regs *regs, int nr) | |
231 | +static void ext_phy_settings_hwlvl(const struct emif_regs *regs, int nr) | |
189 | 232 | { |
190 | 233 | /* |
191 | 234 | * Enable hardware leveling on the EMIF. For details about these |
... | ... | @@ -256,8 +299,12 @@ |
256 | 299 | writel(regs->emif_ddr_phy_ctlr_1, |
257 | 300 | &emif_reg[nr]->emif_ddr_phy_ctrl_1_shdw); |
258 | 301 | |
259 | - if (get_emif_rev((u32)emif_reg[nr]) == EMIF_4D5) | |
260 | - ext_phy_settings(regs, nr); | |
302 | + if (get_emif_rev((u32)emif_reg[nr]) == EMIF_4D5) { | |
303 | + if (emif_sdram_type(regs->sdram_config) == EMIF_SDRAM_TYPE_DDR3) | |
304 | + ext_phy_settings_hwlvl(regs, nr); | |
305 | + else | |
306 | + ext_phy_settings_swlvl(regs, nr); | |
307 | + } | |
261 | 308 | } |
262 | 309 | |
263 | 310 | /** |
arch/arm/cpu/armv7/am33xx/emif4.c
... | ... | @@ -124,8 +124,9 @@ |
124 | 124 | /* Set CKE to be controlled by EMIF/DDR PHY */ |
125 | 125 | writel(DDR_CKE_CTRL_NORMAL, &ddrctrl->ddrckectrl); |
126 | 126 | |
127 | - /* Allow EMIF to control DDR_RESET */ | |
128 | - writel(0x00000000, &ddrctrl->ddrioctrl); | |
127 | + if (emif_sdram_type(regs->sdram_config) == EMIF_SDRAM_TYPE_DDR3) | |
128 | + /* Allow EMIF to control DDR_RESET */ | |
129 | + writel(0x00000000, &ddrctrl->ddrioctrl); | |
129 | 130 | #endif |
130 | 131 | |
131 | 132 | /* Program EMIF instance */ |
arch/arm/cpu/armv7/omap-common/clocks-common.c
... | ... | @@ -372,6 +372,7 @@ |
372 | 372 | { |
373 | 373 | u32 temp; |
374 | 374 | const struct dpll_params *params; |
375 | + struct emif_reg_struct *emif = (struct emif_reg_struct *)EMIF1_BASE; | |
375 | 376 | |
376 | 377 | debug("setup_dplls\n"); |
377 | 378 | |
... | ... | @@ -382,7 +383,8 @@ |
382 | 383 | * Core DPLL will be locked after setting up EMIF |
383 | 384 | * using the FREQ_UPDATE method(freq_update_core()) |
384 | 385 | */ |
385 | - if (emif_sdram_type() == EMIF_SDRAM_TYPE_LPDDR2) | |
386 | + if (emif_sdram_type(readl(&emif->emif_sdram_config)) == | |
387 | + EMIF_SDRAM_TYPE_LPDDR2) | |
386 | 388 | do_setup_dpll((*prcm)->cm_clkmode_dpll_core, params, |
387 | 389 | DPLL_NO_LOCK, "core"); |
388 | 390 | else |
arch/arm/cpu/armv7/omap-common/emif-common.c
... | ... | @@ -1171,12 +1171,14 @@ |
1171 | 1171 | * OPP to another) |
1172 | 1172 | */ |
1173 | 1173 | if (!(in_sdram || warm_reset())) { |
1174 | - if (emif_sdram_type() == EMIF_SDRAM_TYPE_LPDDR2) | |
1174 | + if (emif_sdram_type(regs->sdram_config) == | |
1175 | + EMIF_SDRAM_TYPE_LPDDR2) | |
1175 | 1176 | lpddr2_init(base, regs); |
1176 | 1177 | else |
1177 | 1178 | ddr3_init(base, regs); |
1178 | 1179 | } |
1179 | - if (warm_reset() && (emif_sdram_type() == EMIF_SDRAM_TYPE_DDR3)) { | |
1180 | + if (warm_reset() && (emif_sdram_type(regs->sdram_config) == | |
1181 | + EMIF_SDRAM_TYPE_DDR3)) { | |
1180 | 1182 | set_lpmode_selfrefresh(base); |
1181 | 1183 | emif_reset_phy(base); |
1182 | 1184 | omap5_ddr3_leveling(base, regs); |
... | ... | @@ -1398,7 +1400,8 @@ |
1398 | 1400 | void sdram_init(void) |
1399 | 1401 | { |
1400 | 1402 | u32 in_sdram, size_prog, size_detect; |
1401 | - u32 sdram_type = emif_sdram_type(); | |
1403 | + struct emif_reg_struct *emif = (struct emif_reg_struct *)EMIF1_BASE; | |
1404 | + u32 sdram_type = emif_sdram_type(emif->emif_sdram_config); | |
1402 | 1405 | |
1403 | 1406 | debug(">>sdram_init()\n"); |
1404 | 1407 |
arch/arm/cpu/armv7/omap5/hwinit.c
... | ... | @@ -122,6 +122,7 @@ |
122 | 122 | void do_io_settings(void) |
123 | 123 | { |
124 | 124 | u32 io_settings = 0, mask = 0; |
125 | + struct emif_reg_struct *emif = (struct emif_reg_struct *)EMIF1_BASE; | |
125 | 126 | |
126 | 127 | /* Impedance settings EMMC, C2C 1,2, hsi2 */ |
127 | 128 | mask = (ds_mask << 2) | (ds_mask << 8) | |
... | ... | @@ -177,7 +178,7 @@ |
177 | 178 | (sc_fast << 17) | (sc_fast << 14); |
178 | 179 | writel(io_settings, (*ctrl)->control_smart3io_padconf_1); |
179 | 180 | |
180 | - if (emif_sdram_type() == EMIF_SDRAM_TYPE_LPDDR2) | |
181 | + if (emif_sdram_type(emif->emif_sdram_config) == EMIF_SDRAM_TYPE_LPDDR2) | |
181 | 182 | io_settings_lpddr2(); |
182 | 183 | else |
183 | 184 | io_settings_ddr3(); |
arch/arm/include/asm/emif.h
... | ... | @@ -1209,12 +1209,10 @@ |
1209 | 1209 | * which is typically the case. So it is sufficient to get |
1210 | 1210 | * SDRAM type from EMIF1. |
1211 | 1211 | */ |
1212 | -static inline u32 emif_sdram_type(void) | |
1212 | +static inline u32 emif_sdram_type(u32 sdram_config) | |
1213 | 1213 | { |
1214 | - struct emif_reg_struct *emif = (struct emif_reg_struct *)EMIF1_BASE; | |
1215 | - | |
1216 | - return (readl(&emif->emif_sdram_config) & | |
1217 | - EMIF_REG_SDRAM_TYPE_MASK) >> EMIF_REG_SDRAM_TYPE_SHIFT; | |
1214 | + return (sdram_config & EMIF_REG_SDRAM_TYPE_MASK) | |
1215 | + >> EMIF_REG_SDRAM_TYPE_SHIFT; | |
1218 | 1216 | } |
1219 | 1217 | |
1220 | 1218 | /* assert macros */ |
... | ... | @@ -1244,7 +1242,6 @@ |
1244 | 1242 | #endif |
1245 | 1243 | |
1246 | 1244 | void config_data_eye_leveling_samples(u32 emif_base); |
1247 | -u32 emif_sdram_type(void); | |
1248 | 1245 | const struct read_write_regs *get_bug_regs(u32 *iterations); |
1249 | 1246 | #endif |
board/ti/am43xx/board.c
... | ... | @@ -148,6 +148,29 @@ |
148 | 148 | 400, 23, 1, -1, 2, -1, -1 |
149 | 149 | }; |
150 | 150 | |
151 | +static const u32 ext_phy_ctrl_const_base_lpddr2[] = { | |
152 | + 0x00500050, | |
153 | + 0x00350035, | |
154 | + 0x00350035, | |
155 | + 0x00350035, | |
156 | + 0x00350035, | |
157 | + 0x00350035, | |
158 | + 0x00000000, | |
159 | + 0x00000000, | |
160 | + 0x00000000, | |
161 | + 0x00000000, | |
162 | + 0x00000000, | |
163 | + 0x00000000, | |
164 | + 0x00000000, | |
165 | + 0x00000000, | |
166 | + 0x00000000, | |
167 | + 0x00000000, | |
168 | + 0x00000000, | |
169 | + 0x00000000, | |
170 | + 0x40001000, | |
171 | + 0x08102040 | |
172 | +}; | |
173 | + | |
151 | 174 | const struct ctrl_ioregs ioregs_lpddr2 = { |
152 | 175 | .cm0ioctl = LPDDR2_ADDRCTRL_IOCTRL_VALUE, |
153 | 176 | .cm1ioctl = LPDDR2_ADDRCTRL_WD0_IOCTRL_VALUE, |
... | ... | @@ -317,6 +340,16 @@ |
317 | 340 | .emif_connect_id_serv_2_map = 0x00000000, |
318 | 341 | .emif_cos_config = 0x00ffffff |
319 | 342 | }; |
343 | + | |
344 | +void emif_get_ext_phy_ctrl_const_regs(const u32 **regs, u32 *size) | |
345 | +{ | |
346 | + if (board_is_eposevm()) { | |
347 | + *regs = ext_phy_ctrl_const_base_lpddr2; | |
348 | + *size = ARRAY_SIZE(ext_phy_ctrl_const_base_lpddr2); | |
349 | + } | |
350 | + | |
351 | + return; | |
352 | +} | |
320 | 353 | |
321 | 354 | /* |
322 | 355 | * get_sys_clk_index : returns the index of the sys_clk read from |