diff options
author | Anson Huang <b20788@freescale.com> | 2014-06-24 09:59:22 +0800 |
---|---|---|
committer | Anson Huang <b20788@freescale.com> | 2014-06-26 16:20:11 +0800 |
commit | 93510bfa720670b2f80a7f35ffb327f69fcb0f21 (patch) | |
tree | b767d76acd13570ab32d7a797f7e3d0147c4a7cd /arch | |
parent | 5ca5fc373dc516d495104650b46d765f54d507e5 (diff) |
ENGR00316496 ARM: imx: fix random failure for ddr3 freq scaling on i.mx6sx
Improve DDR3 freq scaling procedure of i.MX6SX:
1. some code of condition check is incorrect;
2. better to keep MMDC command same as ddr script;
3. improve the clock tree change of mmdc path;
4. remove CON_REG req for MMDC.
Signed-off-by: Anson Huang <b20788@freescale.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-imx/busfreq_ddr3.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-imx/ddr3_freq_imx6sx.S | 140 |
2 files changed, 48 insertions, 95 deletions
diff --git a/arch/arm/mach-imx/busfreq_ddr3.c b/arch/arm/mach-imx/busfreq_ddr3.c index 6854f78d3f47..f959c3c1ae08 100644 --- a/arch/arm/mach-imx/busfreq_ddr3.c +++ b/arch/arm/mach-imx/busfreq_ddr3.c @@ -105,7 +105,8 @@ unsigned long ddr3_dll_mx6sx[][2] = { {0x10, 0x0}, {0x30, 0x0}, {0x1C, 0x04008032}, - {0x1C, 0x00068031}, + {0x1C, 0x00008033}, + {0x1C, 0x00048031}, {0x1C, 0x05208030}, {0x1C, 0x04008040}, {0x818, 0x0}, diff --git a/arch/arm/mach-imx/ddr3_freq_imx6sx.S b/arch/arm/mach-imx/ddr3_freq_imx6sx.S index c63bf570100d..f2e523f47a43 100644 --- a/arch/arm/mach-imx/ddr3_freq_imx6sx.S +++ b/arch/arm/mach-imx/ddr3_freq_imx6sx.S @@ -59,7 +59,8 @@ add r9, r9, #4 cmp r9, #16 bne 2b - subs r8, r8, #1 + sub r8, r8, #1 + cmp r8, #0 bgt 1b .endm @@ -78,33 +79,7 @@ /* check whether periph2_clk is already from top path */ ldr r8, [r5, #CCM_CBCDR] ands r8, #(1 << 26) - bne skip_periph2_clk2_switch_400m - - /* change periph2_clk2 to be sourced from pll3_clk. */ - ldr r8, [r5, #CCM_CBCMR] - bic r8, r8, #(1 << 20) - str r8, [r5, #CCM_CBCMR] - - /* make sure periph2_clk2 freq not exceed 400MHz */ - ldr r8, [r5, #CCM_CBCDR] - bic r8, r8, #0x7 - orr r8, r8, #0x1 - str r8, [r5, #CCM_CBCDR] - - /* now switch periph2_clk to pll3_main_clk. */ - ldr r8, [r5, #CCM_CBCDR] - orr r8, r8, #(1 << 26) - str r8, [r5, #CCM_CBCDR] - - wait_for_ccm_handshake - -skip_periph2_clk2_switch_400m: - - /* now switch pre_periph2_clk to PFD_400MHz. */ - ldr r8, [r5, #CCM_CBCMR] - bic r8, r8, #(0x3 << 21) - orr r8, r8, #(0x1 << 21) - str r8, [r5, #CCM_CBCMR] + beq skip_periph2_clk2_switch_400m /* now switch periph2_clk back. */ ldr r8, [r5, #CCM_CBCDR] @@ -113,6 +88,13 @@ skip_periph2_clk2_switch_400m: wait_for_ccm_handshake + /* + * on i.MX6SX, pre_periph2_clk will be always from + * pll2_pfd2, so no need to set pre_periph2_clk + * parent, just set the mmdc divider directly. + */ +skip_periph2_clk2_switch_400m: + /* fabric_mmdc_podf to 0 */ ldr r8, [r5, #CCM_CBCDR] bic r8, r8, #(0x7 << 3) @@ -127,32 +109,7 @@ skip_periph2_clk2_switch_400m: /* check whether periph2_clk is already from top path */ ldr r8, [r5, #CCM_CBCDR] ands r8, #(1 << 26) - bne skip_periph2_clk2_switch_50m - - /* change periph2_clk2 to be sourced from pll3_clk. */ - ldr r8, [r5, #CCM_CBCMR] - bic r8, r8, #(1 << 20) - str r8, [r5, #CCM_CBCMR] - - ldr r8, [r5, #CCM_CBCDR] - bic r8, r8, #0x7 - orr r8, r8, #0x1 - str r8, [r5, #CCM_CBCDR] - - /* now switch periph2_clk to pll3_main_clk. */ - ldr r8, [r5, #CCM_CBCDR] - orr r8, r8, #(1 << 26) - str r8, [r5, #CCM_CBCDR] - - wait_for_ccm_handshake - -skip_periph2_clk2_switch_50m: - - /* now switch pre_periph2_clk to PFD_400MHz. */ - ldr r8, [r5, #CCM_CBCMR] - bic r8, r8, #(0x3 << 21) - orr r8, r8, #(0x1 << 21) - str r8, [r5, #CCM_CBCMR] + beq skip_periph2_clk2_switch_50m /* now switch periph2_clk back. */ ldr r8, [r5, #CCM_CBCDR] @@ -161,6 +118,13 @@ skip_periph2_clk2_switch_50m: wait_for_ccm_handshake + /* + * on i.MX6SX, pre_periph2_clk will be always from + * pll2_pfd2, so no need to set pre_periph2_clk + * parent, just set the mmdc divider directly. + */ +skip_periph2_clk2_switch_50m: + /* fabric_mmdc_podf to 7 so that mmdc is 400 / 8 = 50MHz */ ldr r8, [r5, #CCM_CBCDR] orr r8, r8, #(0x7 << 3) @@ -227,22 +191,24 @@ imx6sx_ddr3_freq_change_start: * and 2-4G is translated by TTBR1. */ + ldr r6, =iram_tlb_phys_addr + ldr r7, [r6] + /* Disable Branch Prediction, Z bit in SCTLR. */ - mrc p15, 0, r7, c1, c0, 0 - bic r7, r7, #0x800 - mcr p15, 0, r7, c1, c0, 0 + mrc p15, 0, r6, c1, c0, 0 + bic r6, r6, #0x800 + mcr p15, 0, r6, c1, c0, 0 /* Flush the Branch Target Address Cache (BTAC) */ ldr r6, =0x0 mcr p15, 0, r6, c7, c1, 6 - ldr r6, =iram_tlb_phys_addr - ldr r6, [r6] dsb isb /* Store the IRAM table in TTBR1 */ - mcr p15, 0, r6, c2, c0, 1 + mcr p15, 0, r7, c2, c0, 1 + /* Read TTBCR and set PD0=1, N = 1 */ mrc p15, 0, r6, c2, c0, 2 orr r6, r6, #0x11 @@ -259,9 +225,9 @@ imx6sx_ddr3_freq_change_start: isb /* Disable L1 data cache. */ - mrc p15, 0, r7, c1, c0, 0 - bic r7, r7, #0x4 - mcr p15, 0, r7, c1, c0, 0 + mrc p15, 0, r6, c1, c0, 0 + bic r6, r6, #0x4 + mcr p15, 0, r6, c1, c0, 0 ldr r4, =IMX_IO_P2V(MX6Q_MMDC_P0_BASE_ADDR) ldr r5, =IMX_IO_P2V(MX6Q_CCM_BASE_ADDR) @@ -309,20 +275,6 @@ wait_for_l2_to_idle: ldr r8, =4 do_delay - /* set CON_REG */ - ldr r8, =0x8000 - str r8, [r4, #MMDC0_MDSCR] -poll_conreq_set_1: - ldr r8, [r4, #MMDC0_MDSCR] - and r8, r8, #(0x4 << 12) - cmp r8, #(0x4 << 12) - bne poll_conreq_set_1 - - ldr r8, =0x00008010 - str r8, [r4, #MMDC0_MDSCR] - ldr r8, =0x00008018 - str r8, [r4, #MMDC0_MDSCR] - /* * if requested frequency is greater than * 300MHz go to DLL on mode. @@ -400,10 +352,10 @@ poll_dvfs_clear_1: ldr r8, =0x00018039 str r8, [r4, #MMDC0_MDSCR] - ldr r8, =0x08208030 + ldr r8, =0x04208030 str r8, [r4, #MMDC0_MDSCR] - ldr r8, =0x08208038 + ldr r8, =0x04208038 str r8, [r4, #MMDC0_MDSCR] ldr r8, =0x00088032 @@ -441,7 +393,8 @@ update_iomux: orr r11, r11, #0x28 str r11, [r6, r10] add r3, r3, #8 - subs r8, r8, #1 + sub r8, r8, #1 + cmp r8, #0 bgt update_iomux /* ODT disabled. */ @@ -459,10 +412,10 @@ update_iomux: str r8, [r4, #MMDC0_MAPSR] /* frc_msr + mu bypass */ - ldr r8, =0x00000060 + ldr r8, =0x00000160 str r8, [r4, #MMDC0_MPMUR0] - ldr r8, =0x00000460 + ldr r8, =0x00000560 str r8, [r4, #MMDC0_MPMUR0] ldr r8, =0x00000c60 @@ -490,10 +443,6 @@ dll_on_mode: orr r8, r8, #(1 << 21) str r8, [r4, #MMDC0_MAPSR] - /* de-assert CON_REQ. */ - mov r8, #0x0 - str r8, [r4, #MMDC0_MDSCR] - /* poll DVFS ack. */ poll_dvfs_set_2: ldr r8, [r4, #MMDC0_MAPSR] @@ -546,7 +495,8 @@ update_iomux1: ldr r11, [r3, #0x4] str r11, [r6, r10] add r3, r3, #8 - subs r8, r8, #1 + sub r8, r8, #1 + cmp r8, #0 bgt update_iomux1 /* config MMDC timings to 400MHz. */ @@ -579,10 +529,10 @@ update_iomux1: do_delay /* reset dll. */ - ldr r8, =0x09208030 + ldr r8, =0x05208030 str r8, [r4, #MMDC0_MDSCR] - ldr r8, =0x09208038 + ldr r8, =0x05208038 str r8, [r4, #MMDC0_MDSCR] /* delay for while. */ @@ -660,7 +610,8 @@ update_calib: ldr r11, [r1, #0x4] str r11, [r4, r10] add r1, r1, #8 - subs r8, r8, #1 + sub r8, r8, #1 + cmp r8, #0 bgt update_calib /* perform a force measurement. */ @@ -681,10 +632,6 @@ poll_conreq_clear_2: beq poll_conreq_clear_2 done: - /* Enable L1 data cache. */ - mrc p15, 0, r7, c1, c0, 0 - orr r7, r7, #0x4 - mcr p15, 0, r7, c1, c0, 0 #ifdef CONFIG_CACHE_L2X0 /* Enable L2. */ @@ -693,6 +640,11 @@ done: str r7, [r8, #0x100] #endif + /* Enable L1 data cache. */ + mrc p15, 0, r7, c1, c0, 0 + orr r7, r7, #0x4 + mcr p15, 0, r7, c1, c0, 0 + /* Restore the TTBCR */ dsb isb |