aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorAnson Huang <b20788@freescale.com>2014-06-30 02:25:08 -0400
committerAnson Huang <b20788@freescale.com>2014-07-03 22:23:51 -0400
commit8f87c4e16fb82eea770769da543b8831118f205e (patch)
treec0cc2e928c0692c6cd9a566cfc965702560c2491 /arch
parent9010f234160a387acc5477f054f89656fcdc1c7d (diff)
ENGR00320383-1 ARM: imx: correct ddr3 busfreq change flow of i.mx6sx
Now that we have found the root cause of ddr3 freq scaling of i.MX6SX, we can remove the previous workaround and add correct fix. Revert "ENGR00316496 ARM: imx: fix random failure for ddr3 freq scaling on i.mx6sx" This reverts commit 93510bfa720670b2f80a7f35ffb327f69fcb0f21. Signed-off-by: Anson Huang <b20788@freescale.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-imx/busfreq_ddr3.c3
-rw-r--r--arch/arm/mach-imx/ddr3_freq_imx6sx.S140
2 files changed, 95 insertions, 48 deletions
diff --git a/arch/arm/mach-imx/busfreq_ddr3.c b/arch/arm/mach-imx/busfreq_ddr3.c
index f959c3c1ae08..6854f78d3f47 100644
--- a/arch/arm/mach-imx/busfreq_ddr3.c
+++ b/arch/arm/mach-imx/busfreq_ddr3.c
@@ -105,8 +105,7 @@ unsigned long ddr3_dll_mx6sx[][2] = {
105 {0x10, 0x0}, 105 {0x10, 0x0},
106 {0x30, 0x0}, 106 {0x30, 0x0},
107 {0x1C, 0x04008032}, 107 {0x1C, 0x04008032},
108 {0x1C, 0x00008033}, 108 {0x1C, 0x00068031},
109 {0x1C, 0x00048031},
110 {0x1C, 0x05208030}, 109 {0x1C, 0x05208030},
111 {0x1C, 0x04008040}, 110 {0x1C, 0x04008040},
112 {0x818, 0x0}, 111 {0x818, 0x0},
diff --git a/arch/arm/mach-imx/ddr3_freq_imx6sx.S b/arch/arm/mach-imx/ddr3_freq_imx6sx.S
index d0f692c39e64..23a34d43c1ce 100644
--- a/arch/arm/mach-imx/ddr3_freq_imx6sx.S
+++ b/arch/arm/mach-imx/ddr3_freq_imx6sx.S
@@ -59,8 +59,7 @@
59 add r9, r9, #4 59 add r9, r9, #4
60 cmp r9, #16 60 cmp r9, #16
61 bne 2b 61 bne 2b
62 sub r8, r8, #1 62 subs r8, r8, #1
63 cmp r8, #0
64 bgt 1b 63 bgt 1b
65 64
66 .endm 65 .endm
@@ -79,22 +78,41 @@
79 /* check whether periph2_clk is already from top path */ 78 /* check whether periph2_clk is already from top path */
80 ldr r8, [r5, #CCM_CBCDR] 79 ldr r8, [r5, #CCM_CBCDR]
81 ands r8, #(1 << 26) 80 ands r8, #(1 << 26)
82 beq skip_periph2_clk2_switch_400m 81 bne skip_periph2_clk2_switch_400m
83 82
84 /* now switch periph2_clk back. */ 83 /* change periph2_clk2 to be sourced from pll3_clk. */
84 ldr r8, [r5, #CCM_CBCMR]
85 bic r8, r8, #(1 << 20)
86 str r8, [r5, #CCM_CBCMR]
87
88 /* make sure periph2_clk2 freq not exceed 400MHz */
85 ldr r8, [r5, #CCM_CBCDR] 89 ldr r8, [r5, #CCM_CBCDR]
86 bic r8, r8, #(1 << 26) 90 bic r8, r8, #0x7
91 orr r8, r8, #0x1
92 str r8, [r5, #CCM_CBCDR]
93
94 /* now switch periph2_clk to pll3_main_clk. */
95 ldr r8, [r5, #CCM_CBCDR]
96 orr r8, r8, #(1 << 26)
87 str r8, [r5, #CCM_CBCDR] 97 str r8, [r5, #CCM_CBCDR]
88 98
89 wait_for_ccm_handshake 99 wait_for_ccm_handshake
90 100
91 /*
92 * on i.MX6SX, pre_periph2_clk will be always from
93 * pll2_pfd2, so no need to set pre_periph2_clk
94 * parent, just set the mmdc divider directly.
95 */
96skip_periph2_clk2_switch_400m: 101skip_periph2_clk2_switch_400m:
97 102
103 /* now switch pre_periph2_clk to PFD_400MHz. */
104 ldr r8, [r5, #CCM_CBCMR]
105 bic r8, r8, #(0x3 << 21)
106 orr r8, r8, #(0x1 << 21)
107 str r8, [r5, #CCM_CBCMR]
108
109 /* now switch periph2_clk back. */
110 ldr r8, [r5, #CCM_CBCDR]
111 bic r8, r8, #(1 << 26)
112 str r8, [r5, #CCM_CBCDR]
113
114 wait_for_ccm_handshake
115
98 /* fabric_mmdc_podf to 0 */ 116 /* fabric_mmdc_podf to 0 */
99 ldr r8, [r5, #CCM_CBCDR] 117 ldr r8, [r5, #CCM_CBCDR]
100 bic r8, r8, #(0x7 << 3) 118 bic r8, r8, #(0x7 << 3)
@@ -109,22 +127,40 @@ skip_periph2_clk2_switch_400m:
109 /* check whether periph2_clk is already from top path */ 127 /* check whether periph2_clk is already from top path */
110 ldr r8, [r5, #CCM_CBCDR] 128 ldr r8, [r5, #CCM_CBCDR]
111 ands r8, #(1 << 26) 129 ands r8, #(1 << 26)
112 beq skip_periph2_clk2_switch_50m 130 bne skip_periph2_clk2_switch_50m
131
132 /* change periph2_clk2 to be sourced from pll3_clk. */
133 ldr r8, [r5, #CCM_CBCMR]
134 bic r8, r8, #(1 << 20)
135 str r8, [r5, #CCM_CBCMR]
113 136
114 /* now switch periph2_clk back. */
115 ldr r8, [r5, #CCM_CBCDR] 137 ldr r8, [r5, #CCM_CBCDR]
116 bic r8, r8, #(1 << 26) 138 bic r8, r8, #0x7
139 orr r8, r8, #0x1
140 str r8, [r5, #CCM_CBCDR]
141
142 /* now switch periph2_clk to pll3_main_clk. */
143 ldr r8, [r5, #CCM_CBCDR]
144 orr r8, r8, #(1 << 26)
117 str r8, [r5, #CCM_CBCDR] 145 str r8, [r5, #CCM_CBCDR]
118 146
119 wait_for_ccm_handshake 147 wait_for_ccm_handshake
120 148
121 /*
122 * on i.MX6SX, pre_periph2_clk will be always from
123 * pll2_pfd2, so no need to set pre_periph2_clk
124 * parent, just set the mmdc divider directly.
125 */
126skip_periph2_clk2_switch_50m: 149skip_periph2_clk2_switch_50m:
127 150
151 /* now switch pre_periph2_clk to PFD_400MHz. */
152 ldr r8, [r5, #CCM_CBCMR]
153 bic r8, r8, #(0x3 << 21)
154 orr r8, r8, #(0x1 << 21)
155 str r8, [r5, #CCM_CBCMR]
156
157 /* now switch periph2_clk back. */
158 ldr r8, [r5, #CCM_CBCDR]
159 bic r8, r8, #(1 << 26)
160 str r8, [r5, #CCM_CBCDR]
161
162 wait_for_ccm_handshake
163
128 /* fabric_mmdc_podf to 7 so that mmdc is 400 / 8 = 50MHz */ 164 /* fabric_mmdc_podf to 7 so that mmdc is 400 / 8 = 50MHz */
129 ldr r8, [r5, #CCM_CBCDR] 165 ldr r8, [r5, #CCM_CBCDR]
130 orr r8, r8, #(0x7 << 3) 166 orr r8, r8, #(0x7 << 3)
@@ -191,24 +227,22 @@ imx6sx_ddr3_freq_change_start:
191 * and 2-4G is translated by TTBR1. 227 * and 2-4G is translated by TTBR1.
192 */ 228 */
193 229
194 ldr r6, =iram_tlb_phys_addr
195 ldr r7, [r6]
196
197 /* Disable Branch Prediction, Z bit in SCTLR. */ 230 /* Disable Branch Prediction, Z bit in SCTLR. */
198 mrc p15, 0, r6, c1, c0, 0 231 mrc p15, 0, r7, c1, c0, 0
199 bic r6, r6, #0x800 232 bic r7, r7, #0x800
200 mcr p15, 0, r6, c1, c0, 0 233 mcr p15, 0, r7, c1, c0, 0
201 234
202 /* Flush the Branch Target Address Cache (BTAC) */ 235 /* Flush the Branch Target Address Cache (BTAC) */
203 ldr r6, =0x0 236 ldr r6, =0x0
204 mcr p15, 0, r6, c7, c1, 6 237 mcr p15, 0, r6, c7, c1, 6
238 ldr r6, =iram_tlb_phys_addr
239 ldr r6, [r6]
205 240
206 dsb 241 dsb
207 isb 242 isb
208 243
209 /* Store the IRAM table in TTBR1 */ 244 /* Store the IRAM table in TTBR1 */
210 mcr p15, 0, r7, c2, c0, 1 245 mcr p15, 0, r6, c2, c0, 1
211
212 /* Read TTBCR and set PD0=1, N = 1 */ 246 /* Read TTBCR and set PD0=1, N = 1 */
213 mrc p15, 0, r6, c2, c0, 2 247 mrc p15, 0, r6, c2, c0, 2
214 orr r6, r6, #0x11 248 orr r6, r6, #0x11
@@ -225,9 +259,9 @@ imx6sx_ddr3_freq_change_start:
225 isb 259 isb
226 260
227 /* Disable L1 data cache. */ 261 /* Disable L1 data cache. */
228 mrc p15, 0, r6, c1, c0, 0 262 mrc p15, 0, r7, c1, c0, 0
229 bic r6, r6, #0x4 263 bic r7, r7, #0x4
230 mcr p15, 0, r6, c1, c0, 0 264 mcr p15, 0, r7, c1, c0, 0
231 265
232 ldr r4, =IMX_IO_P2V(MX6Q_MMDC_P0_BASE_ADDR) 266 ldr r4, =IMX_IO_P2V(MX6Q_MMDC_P0_BASE_ADDR)
233 ldr r5, =IMX_IO_P2V(MX6Q_CCM_BASE_ADDR) 267 ldr r5, =IMX_IO_P2V(MX6Q_CCM_BASE_ADDR)
@@ -275,6 +309,20 @@ wait_for_l2_to_idle:
275 ldr r8, =4 309 ldr r8, =4
276 do_delay 310 do_delay
277 311
312 /* set CON_REG */
313 ldr r8, =0x8000
314 str r8, [r4, #MMDC0_MDSCR]
315poll_conreq_set_1:
316 ldr r8, [r4, #MMDC0_MDSCR]
317 and r8, r8, #(0x4 << 12)
318 cmp r8, #(0x4 << 12)
319 bne poll_conreq_set_1
320
321 ldr r8, =0x00008010
322 str r8, [r4, #MMDC0_MDSCR]
323 ldr r8, =0x00008018
324 str r8, [r4, #MMDC0_MDSCR]
325
278 /* 326 /*
279 * if requested frequency is greater than 327 * if requested frequency is greater than
280 * 300MHz go to DLL on mode. 328 * 300MHz go to DLL on mode.
@@ -352,10 +400,10 @@ poll_dvfs_clear_1:
352 ldr r8, =0x00018039 400 ldr r8, =0x00018039
353 str r8, [r4, #MMDC0_MDSCR] 401 str r8, [r4, #MMDC0_MDSCR]
354 402
355 ldr r8, =0x04208030 403 ldr r8, =0x08208030
356 str r8, [r4, #MMDC0_MDSCR] 404 str r8, [r4, #MMDC0_MDSCR]
357 405
358 ldr r8, =0x04208038 406 ldr r8, =0x08208038
359 str r8, [r4, #MMDC0_MDSCR] 407 str r8, [r4, #MMDC0_MDSCR]
360 408
361 ldr r8, =0x00088032 409 ldr r8, =0x00088032
@@ -393,8 +441,7 @@ update_iomux:
393 orr r11, r11, #0x28 441 orr r11, r11, #0x28
394 str r11, [r6, r10] 442 str r11, [r6, r10]
395 add r3, r3, #8 443 add r3, r3, #8
396 sub r8, r8, #1 444 subs r8, r8, #1
397 cmp r8, #0
398 bgt update_iomux 445 bgt update_iomux
399 446
400 /* ODT disabled. */ 447 /* ODT disabled. */
@@ -407,10 +454,10 @@ update_iomux:
407 str r8, [r4, #MMDC0_MPDGCTRL0] 454 str r8, [r4, #MMDC0_MPDGCTRL0]
408 455
409 /* frc_msr + mu bypass */ 456 /* frc_msr + mu bypass */
410 ldr r8, =0x00000160 457 ldr r8, =0x00000060
411 str r8, [r4, #MMDC0_MPMUR0] 458 str r8, [r4, #MMDC0_MPMUR0]
412 459
413 ldr r8, =0x00000560 460 ldr r8, =0x00000460
414 str r8, [r4, #MMDC0_MPMUR0] 461 str r8, [r4, #MMDC0_MPMUR0]
415 462
416 ldr r8, =0x00000c60 463 ldr r8, =0x00000c60
@@ -438,6 +485,10 @@ dll_on_mode:
438 orr r8, r8, #(1 << 21) 485 orr r8, r8, #(1 << 21)
439 str r8, [r4, #MMDC0_MAPSR] 486 str r8, [r4, #MMDC0_MAPSR]
440 487
488 /* de-assert CON_REQ. */
489 mov r8, #0x0
490 str r8, [r4, #MMDC0_MDSCR]
491
441 /* poll DVFS ack. */ 492 /* poll DVFS ack. */
442poll_dvfs_set_2: 493poll_dvfs_set_2:
443 ldr r8, [r4, #MMDC0_MAPSR] 494 ldr r8, [r4, #MMDC0_MAPSR]
@@ -490,8 +541,7 @@ update_iomux1:
490 ldr r11, [r3, #0x4] 541 ldr r11, [r3, #0x4]
491 str r11, [r6, r10] 542 str r11, [r6, r10]
492 add r3, r3, #8 543 add r3, r3, #8
493 sub r8, r8, #1 544 subs r8, r8, #1
494 cmp r8, #0
495 bgt update_iomux1 545 bgt update_iomux1
496 546
497 /* config MMDC timings to 400MHz. */ 547 /* config MMDC timings to 400MHz. */
@@ -524,10 +574,10 @@ update_iomux1:
524 do_delay 574 do_delay
525 575
526 /* reset dll. */ 576 /* reset dll. */
527 ldr r8, =0x05208030 577 ldr r8, =0x09208030
528 str r8, [r4, #MMDC0_MDSCR] 578 str r8, [r4, #MMDC0_MDSCR]
529 579
530 ldr r8, =0x05208038 580 ldr r8, =0x09208038
531 str r8, [r4, #MMDC0_MDSCR] 581 str r8, [r4, #MMDC0_MDSCR]
532 582
533 /* delay for while. */ 583 /* delay for while. */
@@ -600,8 +650,7 @@ update_calib:
600 ldr r11, [r1, #0x4] 650 ldr r11, [r1, #0x4]
601 str r11, [r4, r10] 651 str r11, [r4, r10]
602 add r1, r1, #8 652 add r1, r1, #8
603 sub r8, r8, #1 653 subs r8, r8, #1
604 cmp r8, #0
605 bgt update_calib 654 bgt update_calib
606 655
607 /* perform a force measurement. */ 656 /* perform a force measurement. */
@@ -622,6 +671,10 @@ poll_conreq_clear_2:
622 beq poll_conreq_clear_2 671 beq poll_conreq_clear_2
623 672
624done: 673done:
674 /* Enable L1 data cache. */
675 mrc p15, 0, r7, c1, c0, 0
676 orr r7, r7, #0x4
677 mcr p15, 0, r7, c1, c0, 0
625 678
626 /* MMDC0_MAPSR adopt power down enable. */ 679 /* MMDC0_MAPSR adopt power down enable. */
627 ldr r8, [r4, #MMDC0_MAPSR] 680 ldr r8, [r4, #MMDC0_MAPSR]
@@ -635,11 +688,6 @@ done:
635 str r7, [r8, #0x100] 688 str r7, [r8, #0x100]
636#endif 689#endif
637 690
638 /* Enable L1 data cache. */
639 mrc p15, 0, r7, c1, c0, 0
640 orr r7, r7, #0x4
641 mcr p15, 0, r7, c1, c0, 0
642
643 /* Restore the TTBCR */ 691 /* Restore the TTBCR */
644 dsb 692 dsb
645 isb 693 isb