summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRanjani Vaidyanathan <Ranjani.Vaidyanathan@freescale.com>2014-09-23 15:18:49 -0500
committerPeng Fushi <fushi.peng@freescale.com>2014-09-24 14:50:33 +0800
commita89e0a0b52e0b31627c126c2c76df6a6b0c7256c (patch)
treed733e5fcce0839609751d91a664a295ad6214449
parentb538a88579a43fec06e7ab7c34c7eb4526b6e54a (diff)
ENGR00331050 [imx6qdl] Fix the workaround for ERR005778
The DDR freq code had an incorrect workaround for ERR005778. ERR005778 MMDC: DDR Controller’s measure unit may return an incorrect value when operating below 100 MHz Workarounds: To workaround this issue, following steps should be performed by software: 1. Prior to reducing the DDR frequency (528 MHz), read the measure unit count bits (MU_UNIT_DEL_NUM). 2. Bypass the automatic measure unit when below 100 MHz, by setting the measure unit bypass enable bit (MU_BYP_EN). 3. Double the measure unit count value read in step 1 and program it in the measure unit bypass bit (MU_BYP_VAL) of the MMDC PHY Measure Unit Register, for the reduced frequency operation below 100 MHz. Software should re-enable the measure unit when operating at the higher frequencies, by clearing the measure unit bypass enable bit (MU_BYP_EN). This code should be executed out of Internal RAM or a non-DDR based external memory. This patch fixes the code to follow the workaround specified in the errata document. Signed-off-by: Ranjani Vaidyanathan <Ranjani.Vaidyanathan@freescale.com>
-rw-r--r--arch/arm/mach-mx6/mx6_ddr_freq.S82
1 files changed, 55 insertions, 27 deletions
diff --git a/arch/arm/mach-mx6/mx6_ddr_freq.S b/arch/arm/mach-mx6/mx6_ddr_freq.S
index c97a082fd83f..716a67b4bd7a 100644
--- a/arch/arm/mach-mx6/mx6_ddr_freq.S
+++ b/arch/arm/mach-mx6/mx6_ddr_freq.S
@@ -384,7 +384,7 @@ skip_gpt_workaround4:
ENTRY(mx6_ddr_freq_change)
mx6_ddr3_iram_start:
- stmfd sp!, {r4 - r11} @ Save registers
+ stmfd sp!, {r4 - r12} @ Save registers
mov r4, r0 @save new freq requested
mov r8, r1 @save the ddr settings for the new rate
@@ -467,6 +467,12 @@ wait_for_l2_to_idle:
ldr r7, =MX6Q_IOMUXC_BASE_ADDR
add r7, r7, #PERIPBASE_VIRT
+ /* Read the original MU delay value */
+ ldr r0, [r5, #0x8b8]
+ mov r12, r0, lsr #16
+ ldr r0, =0x3ff
+ and r12, r12, r0
+
/* Disable automatic power saving. */
ldr r0, [r5, #0x404]
orr r0, r0, #0x01
@@ -692,19 +698,33 @@ update_iomux:
orr r0, r0, #0x20000000
str r0, [r5, r2]
- /* frc_msr + mu bypass*/
- ldr r0, =0x00000060
- str r0, [r5, #0x8b8]
- ldr r2, =0x48b8
- str r0, [r5, r2]
- ldr r0, =0x00000460
- str r0, [r5, #0x8b8]
- ldr r2, =0x48b8
- str r0, [r5, r2]
- ldr r0, =0x00000c60
- str r0, [r5, #0x8b8]
- ldr r2, =0x48b8
- str r0, [r5, r2]
+ /* Add workaround for ERR005778 */
+ /* double the original MU_UNIT_DEL_NUM */
+ lsl r12, r12, #1
+
+ /* Bypass the automatic MU by setting mu_byp_en. */
+ ldr r2, [r5, #0x8b8]
+ orr r2, r2, #0x400
+ orr r2, r2, r12
+ str r2, [r5, #0x8b8]
+ ldr r0, =0x48b8
+ str r2, [r5, r0]
+
+ /* Now perform a force measure */
+ ldr r0, [r5, #0x8b8]
+ orr r0, r0, #0x800
+ str r0, [r5, #0x8b8]
+ ldr r2, =0x48b8
+ str r0, [r5, r2]
+ /* Wait for FRC_MSR to clear. */
+1:
+ ldr r0, [r5, #0x8b8]
+ and r0, r0, #0x800
+ ldr r1, [r5, r2]
+ and r1, r1, #0x800
+ orr r0, r0, r1
+ cmp r0, #0x0
+ bne 1b
continue_dll_off_3:
@@ -795,18 +815,16 @@ poll_dvfs_clear_2:
ldr r2, =0x48b8
str r0, [r5, r2]
- /* delay for while */
- ldr r1, =4
-delay5:
- ldr r2, =0
-cont5:
- ldr r0, [r5, r2]
- add r2, r2, #4
- cmp r2, #16
- bne cont5
- sub r1, r1, #1
- cmp r1, #0
- bgt delay5
+ /* Wait for FRC_MSR to clear. */
+1:
+ ldr r0, [r5, #0x8b8]
+ and r0, r0, #0x800
+ ldr r1, [r5, r2]
+ and r1, r1, #0x800
+ orr r0, r0, r1
+ cmp r0, #0x0
+ bne 1b
+
/* Disable dqs pull down in the IOMUX. */
/*
setmem /32 0x020e05a8 = 0x00000030 // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS0 - DSE=110
@@ -1003,6 +1021,16 @@ update_calib:
ldr r2, =0x48B8
str r0, [r5, r2]
+ /* Wait for FRC_MSR to clear. */
+1:
+ ldr r0, [r5, #0x8b8]
+ and r0, r0, #0x800
+ ldr r1, [r5, r2]
+ and r1, r1, #0x800
+ orr r0, r0, r1
+ cmp r0, #0x0
+ bne 1b
+
/* clear SBS - unblock DDR accesses */
ldr r0, [r5, #0x410]
bic r0, r0, #0x100
@@ -1063,7 +1091,7 @@ done:
mcr p15, 0, r6, c7, c1, 6
/* Restore registers */
- ldmfd sp!, {r4 - r11}
+ ldmfd sp!, {r4 - r12}
mov pc, lr
/*