]>
Commit | Line | Data |
---|---|---|
ef509b90 VA |
1 | /* |
2 | * Keystone2: DDR3 initialization | |
3 | * | |
4 | * (C) Copyright 2012-2014 | |
5 | * Texas Instruments Incorporated, <www.ti.com> | |
6 | * | |
7 | * SPDX-License-Identifier: GPL-2.0+ | |
8 | */ | |
9 | ||
ef509b90 | 10 | #include <asm/io.h> |
101eec50 | 11 | #include <common.h> |
89f44bb0 | 12 | #include <asm/arch/msmc.h> |
0b868589 | 13 | #include <asm/arch/ddr3.h> |
6c343825 | 14 | #include <asm/arch/psc_defs.h> |
ef509b90 | 15 | |
89f44bb0 VA |
16 | #include <asm/ti-common/ti-edma3.h> |
17 | ||
18 | #define DDR3_EDMA_BLK_SIZE_SHIFT 10 | |
19 | #define DDR3_EDMA_BLK_SIZE (1 << DDR3_EDMA_BLK_SIZE_SHIFT) | |
20 | #define DDR3_EDMA_BCNT 0x8000 | |
21 | #define DDR3_EDMA_CCNT 1 | |
22 | #define DDR3_EDMA_XF_SIZE (DDR3_EDMA_BLK_SIZE * DDR3_EDMA_BCNT) | |
23 | #define DDR3_EDMA_SLOT_NUM 1 | |
24 | ||
0b868589 | 25 | void ddr3_init_ddrphy(u32 base, struct ddr3_phy_config *phy_cfg) |
ef509b90 VA |
26 | { |
27 | unsigned int tmp; | |
28 | ||
29 | while ((__raw_readl(base + KS2_DDRPHY_PGSR0_OFFSET) | |
30 | & 0x00000001) != 0x00000001) | |
31 | ; | |
32 | ||
33 | __raw_writel(phy_cfg->pllcr, base + KS2_DDRPHY_PLLCR_OFFSET); | |
34 | ||
35 | tmp = __raw_readl(base + KS2_DDRPHY_PGCR1_OFFSET); | |
36 | tmp &= ~(phy_cfg->pgcr1_mask); | |
37 | tmp |= phy_cfg->pgcr1_val; | |
38 | __raw_writel(tmp, base + KS2_DDRPHY_PGCR1_OFFSET); | |
39 | ||
40 | __raw_writel(phy_cfg->ptr0, base + KS2_DDRPHY_PTR0_OFFSET); | |
41 | __raw_writel(phy_cfg->ptr1, base + KS2_DDRPHY_PTR1_OFFSET); | |
42 | __raw_writel(phy_cfg->ptr3, base + KS2_DDRPHY_PTR3_OFFSET); | |
43 | __raw_writel(phy_cfg->ptr4, base + KS2_DDRPHY_PTR4_OFFSET); | |
44 | ||
45 | tmp = __raw_readl(base + KS2_DDRPHY_DCR_OFFSET); | |
46 | tmp &= ~(phy_cfg->dcr_mask); | |
47 | tmp |= phy_cfg->dcr_val; | |
48 | __raw_writel(tmp, base + KS2_DDRPHY_DCR_OFFSET); | |
49 | ||
50 | __raw_writel(phy_cfg->dtpr0, base + KS2_DDRPHY_DTPR0_OFFSET); | |
51 | __raw_writel(phy_cfg->dtpr1, base + KS2_DDRPHY_DTPR1_OFFSET); | |
52 | __raw_writel(phy_cfg->dtpr2, base + KS2_DDRPHY_DTPR2_OFFSET); | |
53 | __raw_writel(phy_cfg->mr0, base + KS2_DDRPHY_MR0_OFFSET); | |
54 | __raw_writel(phy_cfg->mr1, base + KS2_DDRPHY_MR1_OFFSET); | |
55 | __raw_writel(phy_cfg->mr2, base + KS2_DDRPHY_MR2_OFFSET); | |
56 | __raw_writel(phy_cfg->dtcr, base + KS2_DDRPHY_DTCR_OFFSET); | |
57 | __raw_writel(phy_cfg->pgcr2, base + KS2_DDRPHY_PGCR2_OFFSET); | |
58 | ||
59 | __raw_writel(phy_cfg->zq0cr1, base + KS2_DDRPHY_ZQ0CR1_OFFSET); | |
60 | __raw_writel(phy_cfg->zq1cr1, base + KS2_DDRPHY_ZQ1CR1_OFFSET); | |
61 | __raw_writel(phy_cfg->zq2cr1, base + KS2_DDRPHY_ZQ2CR1_OFFSET); | |
62 | ||
63 | __raw_writel(phy_cfg->pir_v1, base + KS2_DDRPHY_PIR_OFFSET); | |
64 | while ((__raw_readl(base + KS2_DDRPHY_PGSR0_OFFSET) & 0x1) != 0x1) | |
65 | ; | |
66 | ||
67 | __raw_writel(phy_cfg->pir_v2, base + KS2_DDRPHY_PIR_OFFSET); | |
68 | while ((__raw_readl(base + KS2_DDRPHY_PGSR0_OFFSET) & 0x1) != 0x1) | |
69 | ; | |
70 | } | |
71 | ||
0b868589 | 72 | void ddr3_init_ddremif(u32 base, struct ddr3_emif_config *emif_cfg) |
ef509b90 VA |
73 | { |
74 | __raw_writel(emif_cfg->sdcfg, base + KS2_DDR3_SDCFG_OFFSET); | |
75 | __raw_writel(emif_cfg->sdtim1, base + KS2_DDR3_SDTIM1_OFFSET); | |
76 | __raw_writel(emif_cfg->sdtim2, base + KS2_DDR3_SDTIM2_OFFSET); | |
77 | __raw_writel(emif_cfg->sdtim3, base + KS2_DDR3_SDTIM3_OFFSET); | |
78 | __raw_writel(emif_cfg->sdtim4, base + KS2_DDR3_SDTIM4_OFFSET); | |
79 | __raw_writel(emif_cfg->zqcfg, base + KS2_DDR3_ZQCFG_OFFSET); | |
80 | __raw_writel(emif_cfg->sdrfc, base + KS2_DDR3_SDRFC_OFFSET); | |
81 | } | |
101eec50 | 82 | |
89f44bb0 VA |
83 | int ddr3_ecc_support_rmw(u32 base) |
84 | { | |
85 | u32 value = __raw_readl(base + KS2_DDR3_MIDR_OFFSET); | |
86 | ||
87 | /* Check the DDR3 controller ID reg if the controllers | |
88 | supports ECC RMW or not */ | |
89 | if (value == 0x40461C02) | |
90 | return 1; | |
91 | ||
92 | return 0; | |
93 | } | |
94 | ||
95 | static void ddr3_ecc_config(u32 base, u32 value) | |
96 | { | |
97 | u32 data; | |
98 | ||
99 | __raw_writel(value, base + KS2_DDR3_ECC_CTRL_OFFSET); | |
100 | udelay(100000); /* delay required to synchronize across clock domains */ | |
101 | ||
102 | if (value & KS2_DDR3_ECC_EN) { | |
103 | /* Clear the 1-bit error count */ | |
104 | data = __raw_readl(base + KS2_DDR3_ONE_BIT_ECC_ERR_CNT_OFFSET); | |
105 | __raw_writel(data, base + KS2_DDR3_ONE_BIT_ECC_ERR_CNT_OFFSET); | |
106 | ||
107 | /* enable the ECC interrupt */ | |
108 | __raw_writel(KS2_DDR3_1B_ECC_ERR_SYS | KS2_DDR3_2B_ECC_ERR_SYS | | |
109 | KS2_DDR3_WR_ECC_ERR_SYS, | |
110 | base + KS2_DDR3_ECC_INT_ENABLE_SET_SYS_OFFSET); | |
111 | ||
112 | /* Clear the ECC error interrupt status */ | |
113 | __raw_writel(KS2_DDR3_1B_ECC_ERR_SYS | KS2_DDR3_2B_ECC_ERR_SYS | | |
114 | KS2_DDR3_WR_ECC_ERR_SYS, | |
115 | base + KS2_DDR3_ECC_INT_STATUS_OFFSET); | |
116 | } | |
117 | } | |
118 | ||
119 | static void ddr3_reset_data(u32 base, u32 ddr3_size) | |
120 | { | |
121 | u32 mpax[2]; | |
122 | u32 seg_num; | |
123 | u32 seg, blks, dst, edma_blks; | |
124 | struct edma3_slot_config slot; | |
125 | struct edma3_channel_config edma_channel; | |
126 | u32 edma_src[DDR3_EDMA_BLK_SIZE/4] __aligned(16) = {0, }; | |
127 | ||
128 | /* Setup an edma to copy the 1k block to the entire DDR */ | |
129 | puts("\nClear entire DDR3 memory to enable ECC\n"); | |
130 | ||
131 | /* save the SES MPAX regs */ | |
132 | msmc_get_ses_mpax(8, 0, mpax); | |
133 | ||
134 | /* setup edma slot 1 configuration */ | |
135 | slot.opt = EDMA3_SLOPT_TRANS_COMP_INT_ENB | | |
136 | EDMA3_SLOPT_COMP_CODE(0) | | |
137 | EDMA3_SLOPT_STATIC | EDMA3_SLOPT_AB_SYNC; | |
138 | slot.bcnt = DDR3_EDMA_BCNT; | |
139 | slot.acnt = DDR3_EDMA_BLK_SIZE; | |
140 | slot.ccnt = DDR3_EDMA_CCNT; | |
141 | slot.src_bidx = 0; | |
142 | slot.dst_bidx = DDR3_EDMA_BLK_SIZE; | |
143 | slot.src_cidx = 0; | |
144 | slot.dst_cidx = 0; | |
145 | slot.link = EDMA3_PARSET_NULL_LINK; | |
146 | slot.bcntrld = 0; | |
147 | edma3_slot_configure(KS2_EDMA0_BASE, DDR3_EDMA_SLOT_NUM, &slot); | |
148 | ||
149 | /* configure quik edma channel */ | |
150 | edma_channel.slot = DDR3_EDMA_SLOT_NUM; | |
151 | edma_channel.chnum = 0; | |
152 | edma_channel.complete_code = 0; | |
153 | /* event trigger after dst update */ | |
154 | edma_channel.trigger_slot_word = EDMA3_TWORD(dst); | |
155 | qedma3_start(KS2_EDMA0_BASE, &edma_channel); | |
156 | ||
157 | /* DDR3 size in segments (4KB seg size) */ | |
158 | seg_num = ddr3_size << (30 - KS2_MSMC_SEG_SIZE_SHIFT); | |
159 | ||
160 | for (seg = 0; seg < seg_num; seg += KS2_MSMC_MAP_SEG_NUM) { | |
161 | /* map 2GB 36-bit DDR address to 32-bit DDR address in EMIF | |
162 | access slave interface so that edma driver can access */ | |
163 | msmc_map_ses_segment(8, 0, base >> KS2_MSMC_SEG_SIZE_SHIFT, | |
164 | KS2_MSMC_DST_SEG_BASE + seg, MPAX_SEG_2G); | |
165 | ||
166 | if ((seg_num - seg) > KS2_MSMC_MAP_SEG_NUM) | |
167 | edma_blks = KS2_MSMC_MAP_SEG_NUM << | |
168 | (KS2_MSMC_SEG_SIZE_SHIFT | |
169 | - DDR3_EDMA_BLK_SIZE_SHIFT); | |
170 | else | |
171 | edma_blks = (seg_num - seg) << (KS2_MSMC_SEG_SIZE_SHIFT | |
172 | - DDR3_EDMA_BLK_SIZE_SHIFT); | |
173 | ||
174 | /* Use edma driver to scrub 2GB DDR memory */ | |
175 | for (dst = base, blks = 0; blks < edma_blks; | |
176 | blks += DDR3_EDMA_BCNT, dst += DDR3_EDMA_XF_SIZE) { | |
177 | edma3_set_src_addr(KS2_EDMA0_BASE, | |
178 | edma_channel.slot, (u32)edma_src); | |
179 | edma3_set_dest_addr(KS2_EDMA0_BASE, | |
180 | edma_channel.slot, (u32)dst); | |
181 | ||
182 | while (edma3_check_for_transfer(KS2_EDMA0_BASE, | |
183 | &edma_channel)) | |
184 | udelay(10); | |
185 | } | |
186 | } | |
187 | ||
188 | qedma3_stop(KS2_EDMA0_BASE, &edma_channel); | |
189 | ||
190 | /* restore the SES MPAX regs */ | |
191 | msmc_set_ses_mpax(8, 0, mpax); | |
192 | } | |
193 | ||
194 | static void ddr3_ecc_init_range(u32 base) | |
195 | { | |
196 | u32 ecc_val = KS2_DDR3_ECC_EN; | |
197 | u32 rmw = ddr3_ecc_support_rmw(base); | |
198 | ||
199 | if (rmw) | |
200 | ecc_val |= KS2_DDR3_ECC_RMW_EN; | |
201 | ||
202 | __raw_writel(0, base + KS2_DDR3_ECC_ADDR_RANGE1_OFFSET); | |
203 | ||
204 | ddr3_ecc_config(base, ecc_val); | |
205 | } | |
206 | ||
207 | void ddr3_enable_ecc(u32 base, int test) | |
208 | { | |
209 | u32 ecc_val = KS2_DDR3_ECC_ENABLE; | |
210 | u32 rmw = ddr3_ecc_support_rmw(base); | |
211 | ||
212 | if (test) | |
213 | ecc_val |= KS2_DDR3_ECC_ADDR_RNG_1_EN; | |
214 | ||
215 | if (!rmw) { | |
216 | if (!test) | |
217 | /* by default, disable ecc when rmw = 0 and no | |
218 | ecc test */ | |
219 | ecc_val = 0; | |
220 | } else { | |
221 | ecc_val |= KS2_DDR3_ECC_RMW_EN; | |
222 | } | |
223 | ||
224 | ddr3_ecc_config(base, ecc_val); | |
225 | } | |
226 | ||
227 | void ddr3_disable_ecc(u32 base) | |
228 | { | |
229 | ddr3_ecc_config(base, 0); | |
230 | } | |
231 | ||
232 | #if defined(CONFIG_SOC_K2HK) || defined(CONFIG_SOC_K2L) | |
233 | static void cic_init(u32 base) | |
234 | { | |
235 | /* Disable CIC global interrupts */ | |
236 | __raw_writel(0, base + KS2_CIC_GLOBAL_ENABLE); | |
237 | ||
238 | /* Set to normal mode, no nesting, no priority hold */ | |
239 | __raw_writel(0, base + KS2_CIC_CTRL); | |
240 | __raw_writel(0, base + KS2_CIC_HOST_CTRL); | |
241 | ||
242 | /* Enable CIC global interrupts */ | |
243 | __raw_writel(1, base + KS2_CIC_GLOBAL_ENABLE); | |
244 | } | |
245 | ||
246 | static void cic_map_cic_to_gic(u32 base, u32 chan_num, u32 irq_num) | |
247 | { | |
248 | /* Map the system interrupt to a CIC channel */ | |
249 | __raw_writeb(chan_num, base + KS2_CIC_CHAN_MAP(0) + irq_num); | |
250 | ||
251 | /* Enable CIC system interrupt */ | |
252 | __raw_writel(irq_num, base + KS2_CIC_SYS_ENABLE_IDX_SET); | |
253 | ||
254 | /* Enable CIC Host interrupt */ | |
255 | __raw_writel(chan_num, base + KS2_CIC_HOST_ENABLE_IDX_SET); | |
256 | } | |
257 | ||
258 | static void ddr3_map_ecc_cic2_irq(u32 base) | |
259 | { | |
260 | cic_init(base); | |
261 | cic_map_cic_to_gic(base, KS2_CIC2_DDR3_ECC_CHAN_NUM, | |
262 | KS2_CIC2_DDR3_ECC_IRQ_NUM); | |
263 | } | |
264 | #endif | |
265 | ||
66c98a0c | 266 | void ddr3_init_ecc(u32 base, u32 ddr3_size) |
89f44bb0 | 267 | { |
89f44bb0 VA |
268 | if (!ddr3_ecc_support_rmw(base)) { |
269 | ddr3_disable_ecc(base); | |
270 | return; | |
271 | } | |
272 | ||
273 | ddr3_ecc_init_range(base); | |
89f44bb0 VA |
274 | ddr3_reset_data(CONFIG_SYS_SDRAM_BASE, ddr3_size); |
275 | ||
276 | /* mapping DDR3 ECC system interrupt from CIC2 to GIC */ | |
277 | #if defined(CONFIG_SOC_K2HK) || defined(CONFIG_SOC_K2L) | |
278 | ddr3_map_ecc_cic2_irq(KS2_CIC2_BASE); | |
279 | #endif | |
280 | ddr3_enable_ecc(base, 0); | |
281 | } | |
282 | ||
283 | void ddr3_check_ecc_int(u32 base) | |
284 | { | |
285 | char *env; | |
286 | int ecc_test = 0; | |
287 | u32 value = __raw_readl(base + KS2_DDR3_ECC_INT_STATUS_OFFSET); | |
288 | ||
289 | env = getenv("ecc_test"); | |
290 | if (env) | |
291 | ecc_test = simple_strtol(env, NULL, 0); | |
292 | ||
293 | if (value & KS2_DDR3_WR_ECC_ERR_SYS) | |
294 | puts("DDR3 ECC write error interrupted\n"); | |
295 | ||
296 | if (value & KS2_DDR3_2B_ECC_ERR_SYS) { | |
297 | puts("DDR3 ECC 2-bit error interrupted\n"); | |
298 | ||
299 | if (!ecc_test) { | |
300 | puts("Reseting the device ...\n"); | |
301 | reset_cpu(0); | |
302 | } | |
303 | } | |
304 | ||
305 | value = __raw_readl(base + KS2_DDR3_ONE_BIT_ECC_ERR_CNT_OFFSET); | |
306 | if (value) { | |
307 | printf("1-bit ECC err count: 0x%x\n", value); | |
308 | value = __raw_readl(base + | |
309 | KS2_DDR3_ONE_BIT_ECC_ERR_ADDR_LOG_OFFSET); | |
310 | printf("1-bit ECC err address log: 0x%x\n", value); | |
311 | } | |
312 | } | |
313 | ||
101eec50 HZ |
314 | void ddr3_reset_ddrphy(void) |
315 | { | |
316 | u32 tmp; | |
317 | ||
318 | /* Assert DDR3A PHY reset */ | |
3d315386 | 319 | tmp = readl(KS2_DDR3APLLCTL1); |
101eec50 | 320 | tmp |= KS2_DDR3_PLLCTRL_PHY_RESET; |
3d315386 | 321 | writel(tmp, KS2_DDR3APLLCTL1); |
101eec50 HZ |
322 | |
323 | /* wait 10us to catch the reset */ | |
324 | udelay(10); | |
325 | ||
326 | /* Release DDR3A PHY reset */ | |
3d315386 | 327 | tmp = readl(KS2_DDR3APLLCTL1); |
101eec50 | 328 | tmp &= ~KS2_DDR3_PLLCTRL_PHY_RESET; |
3d315386 | 329 | __raw_writel(tmp, KS2_DDR3APLLCTL1); |
101eec50 | 330 | } |
6c343825 MK |
331 | |
332 | #ifdef CONFIG_SOC_K2HK | |
333 | /** | |
334 | * ddr3_reset_workaround - reset workaround in case if leveling error | |
335 | * detected for PG 1.0 and 1.1 k2hk SoCs | |
336 | */ | |
337 | void ddr3_err_reset_workaround(void) | |
338 | { | |
339 | unsigned int tmp; | |
340 | unsigned int tmp_a; | |
341 | unsigned int tmp_b; | |
342 | ||
343 | /* | |
344 | * Check for PGSR0 error bits of DDR3 PHY. | |
345 | * Check for WLERR, QSGERR, WLAERR, | |
346 | * RDERR, WDERR, REERR, WEERR error to see if they are set or not | |
347 | */ | |
348 | tmp_a = __raw_readl(KS2_DDR3A_DDRPHYC + KS2_DDRPHY_PGSR0_OFFSET); | |
349 | tmp_b = __raw_readl(KS2_DDR3B_DDRPHYC + KS2_DDRPHY_PGSR0_OFFSET); | |
350 | ||
351 | if (((tmp_a & 0x0FE00000) != 0) || ((tmp_b & 0x0FE00000) != 0)) { | |
352 | printf("DDR Leveling Error Detected!\n"); | |
353 | printf("DDR3A PGSR0 = 0x%x\n", tmp_a); | |
354 | printf("DDR3B PGSR0 = 0x%x\n", tmp_b); | |
355 | ||
356 | /* | |
357 | * Write Keys to KICK registers to enable writes to registers | |
358 | * in boot config space | |
359 | */ | |
360 | __raw_writel(KS2_KICK0_MAGIC, KS2_KICK0); | |
361 | __raw_writel(KS2_KICK1_MAGIC, KS2_KICK1); | |
362 | ||
363 | /* | |
364 | * Move DDR3A Module out of reset isolation by setting | |
365 | * MDCTL23[12] = 0 | |
366 | */ | |
367 | tmp_a = __raw_readl(KS2_PSC_BASE + | |
368 | PSC_REG_MDCTL(KS2_LPSC_EMIF4F_DDR3A)); | |
369 | ||
370 | tmp_a = PSC_REG_MDCTL_SET_RESET_ISO(tmp_a, 0); | |
371 | __raw_writel(tmp_a, KS2_PSC_BASE + | |
372 | PSC_REG_MDCTL(KS2_LPSC_EMIF4F_DDR3A)); | |
373 | ||
374 | /* | |
375 | * Move DDR3B Module out of reset isolation by setting | |
376 | * MDCTL24[12] = 0 | |
377 | */ | |
378 | tmp_b = __raw_readl(KS2_PSC_BASE + | |
379 | PSC_REG_MDCTL(KS2_LPSC_EMIF4F_DDR3B)); | |
380 | tmp_b = PSC_REG_MDCTL_SET_RESET_ISO(tmp_b, 0); | |
381 | __raw_writel(tmp_b, KS2_PSC_BASE + | |
382 | PSC_REG_MDCTL(KS2_LPSC_EMIF4F_DDR3B)); | |
383 | ||
384 | /* | |
385 | * Write 0x5A69 Key to RSTCTRL[15:0] to unlock writes | |
386 | * to RSTCTRL and RSTCFG | |
387 | */ | |
388 | tmp = __raw_readl(KS2_RSTCTRL); | |
389 | tmp &= KS2_RSTCTRL_MASK; | |
390 | tmp |= KS2_RSTCTRL_KEY; | |
391 | __raw_writel(tmp, KS2_RSTCTRL); | |
392 | ||
393 | /* | |
394 | * Set PLL Controller to drive hard reset on SW trigger by | |
395 | * setting RSTCFG[13] = 0 | |
396 | */ | |
397 | tmp = __raw_readl(KS2_RSTCTRL_RSCFG); | |
398 | tmp &= ~KS2_RSTYPE_PLL_SOFT; | |
399 | __raw_writel(tmp, KS2_RSTCTRL_RSCFG); | |
400 | ||
401 | reset_cpu(0); | |
402 | } | |
403 | } | |
404 | #endif |