summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorFrank.Li <Frank.Li@freescale.com>2009-11-11 16:27:43 -0600
committerAlejandro Gonzalez <alex.gonzalez@digi.com>2010-02-12 17:19:34 +0100
commite38dee10a3b832a5b5189f943b360f9370aa47f3 (patch)
treed47484de0eb875bc142ed8260ea7e6f6656877a1 /arch
parentab14ca996c24992108d6658c5b89d1c70a48ca9d (diff)
ENGR00116050 iMX233 correct EMI clock change
The BSP uses the deprecated DCC_RESYNC logic for changing clocks. This was ok for 37xx, but it is not recommended for 378x Use DLL_RESET and DLL_SHIFT_RESET for changing clocks Signed-off-by: Frank.Li <Frank.Li@freescale.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-stmp378x/emi.S91
-rw-r--r--arch/arm/mach-stmp378x/emi.inc25
2 files changed, 96 insertions, 20 deletions
diff --git a/arch/arm/mach-stmp378x/emi.S b/arch/arm/mach-stmp378x/emi.S
index f4072ff33b24..3b2aac31167f 100644
--- a/arch/arm/mach-stmp378x/emi.S
+++ b/arch/arm/mach-stmp378x/emi.S
@@ -23,6 +23,8 @@
#include <mach/platform.h>
#include <mach/regs-power.h>
#include <mach/regs-clkctrl.h>
+#include <mach/regs-emi.h>
+#include <mach/regs-dram.h>
/* TODO should be move to clock.h */
#define SCALING_DATA_EMI_DIV_OFFSET 0
@@ -107,6 +109,23 @@ ENTRY(stmp3xxx_ram_freq_scale)
tst r1, #BM_CLKCTRL_EMI_BUSY_REF_XTAL
bne 101b
+ @When are using the DLL, reset the DRAM controller and DLL
+ @start point logic (via DLL_SHIFT_RESET and DLL_RESET).
+ @After changing clock dividers and loading
+ @the new HW_DRAM_CTL* parameters, we will wait for a new DLL_LOCK
+
+ @todo - for DRAM's that will use DLL bypass (non DDR1)
+ @ we should not use DLL_RESET and DLL_SHIFT_RESET.
+
+ mov r0, #(HW_EMI_CTRL_ADDR & 0x000000FF)
+ orr r0, r0, #(HW_EMI_CTRL_ADDR & 0x0000FF00)
+ orr r0, r0, #(HW_EMI_CTRL_ADDR & 0x00FF0000)
+ orr r0, r0, #(HW_EMI_CTRL_ADDR & 0xFF000000)
+ ldr r1, [r0] @read values of HW_EMI_CTRL into R1
+ orr r1, r1, #BM_EMI_CTRL_DLL_SHIFT_RESET @Set these 2 fields.
+ orr r1, r1, #BM_EMI_CTRL_DLL_RESET
+ str r1, [r0] @write back values to HW_EMI_CTRL register.
+
bl __stmp_emi_set_values
@ EMI back to PLL
@@ -117,6 +136,8 @@ ENTRY(stmp3xxx_ram_freq_scale)
mov r1, #(1<<6)
str r1, [r0, #8]
+ @ Wait for BUSY_REF_EMI, to assure new clock dividers
+ @ are done transferring
mov r0, #(HW_CLKCTRL_EMI_ADDR & 0x000000FF)
orr r0, r0, #(HW_CLKCTRL_EMI_ADDR & 0x0000FF00)
orr r0, r0, #(HW_CLKCTRL_EMI_ADDR & 0x00FF0000)
@@ -124,21 +145,65 @@ ENTRY(stmp3xxx_ram_freq_scale)
1: ldr r1, [r0]
tst r1, #BM_CLKCTRL_EMI_BUSY_REF_EMI
bne 1b
- bic r1, #BM_CLKCTRL_EMI_DCC_RESYNC_ENABLE
str r1, [r0]
- @ restore normal DRAM mode
- ldr r0, __stmp_dram_ctl00
- ldr r1, [r0, #0x20]
- bic r1, r1, #(1 << 8)
- str r1, [r0, #0x20]
- @ wait for it to actually happen
- ldr r0, __stmp_dram_emi00
-102: ldr r1, [r0, #0x10]
- tst r1, #(1 << 1)
- bne 102b
-
- @ restore regs and return
+@todo - for DRAM's that will use DLL bypass (non DDR1)
+@we should not use DLL_RESET and DLL_SHIFT_RESET.
+@ if(HW_DRAM_CTL04.B.DLL_BYPASS_MODE==0)
+@ {
+@
+@ Clear the DLL_RESET and DLL_SHIFT_RESET bitfields
+@ (\todo - is that necessary?
+@ they were already set previously to reset
+@ the controller/DLL start point,
+@ so clearing should have no effect..)
+@
+@ BF_CS2(EMI_CTRL, DLL_RESET, 0, DLL_SHIFT_RESET, 0);
+
+ mov r0, #(HW_EMI_CTRL_ADDR & 0x000000FF)
+ orr r0, r0, #(HW_EMI_CTRL_ADDR & 0x0000FF00)
+ orr r0, r0, #(HW_EMI_CTRL_ADDR & 0x00FF0000)
+ orr r0, r0, #(HW_EMI_CTRL_ADDR & 0xFF000000)
+ ldr r1, [r0]
+ bic r1, #BM_EMI_CTRL_DLL_SHIFT_RESET
+ bic r1, #BM_EMI_CTRL_DLL_RESET
+ str r1, [r0]
+
+@Wait for BUSY_REF_EMI, to assure new clock dividers are done transferring.
+@(\todo is that necessary. we already did this above.
+ mov r0, #(HW_CLKCTRL_EMI_ADDR & 0x000000FF)
+ orr r0, r0, #(HW_CLKCTRL_EMI_ADDR & 0x0000FF00)
+ orr r0, r0, #(HW_CLKCTRL_EMI_ADDR & 0x00FF0000)
+ orr r0, r0, #(HW_CLKCTRL_EMI_ADDR & 0xFF000000)
+66: ldr r1, [r0]
+ tst r1, #BM_CLKCTRL_EMI_BUSY_REF_EMI
+ bne 66b
+
+@ Wait for DLL locking.
+@ while(HW_DRAM_CTL04.B.DLLLOCKREG==0);
+
+ mov r0, #(HW_DRAM_CTL04_ADDR & 0x000000FF)
+ orr r0, r0, #(HW_DRAM_CTL04_ADDR & 0x0000FF00)
+ orr r0, r0, #(HW_DRAM_CTL04_ADDR & 0x00FF0000)
+ orr r0, r0, #(HW_DRAM_CTL04_ADDR & 0xFF000000)
+77: ldr r1, [r0]
+ tst r1, #BM_DRAM_CTL04_DLLLOCKREG
+ beq 77b
+
+
+ @ resttore normal DRAM mode
+ ldr r0, __stmp_dram_ctl00
+ ldr r1, [r0, #0x20]
+ bic r1, r1, #(1 << 8)
+ str r1, [r0, #0x20]
+
+ @ wait for it to actually happen
+ ldr r0, __stmp_dram_emi00
+102: ldr r1, [r0, #0x10]
+ tst r1, #(1 << 1)
+ bne 102b
+
+@ restore regs and return
ldmfd sp!, {r1 - r9, lr}
mov pc, lr
diff --git a/arch/arm/mach-stmp378x/emi.inc b/arch/arm/mach-stmp378x/emi.inc
index 3fc5f89543e9..4cd3206a223e 100644
--- a/arch/arm/mach-stmp378x/emi.inc
+++ b/arch/arm/mach-stmp378x/emi.inc
@@ -22,7 +22,8 @@ __stmp_emi_set_values:
orr r1, r1, #(HW_CLKCTRL_EMI_ADDR & 0x00FF0000)
orr r1, r1, #(HW_CLKCTRL_EMI_ADDR & 0xFF000000)
- mov r3, #BM_CLKCTRL_EMI_DCC_RESYNC_ENABLE
+@ DDC_RESNCY is deprecated at mx23
+@ mov r3, #BM_CLKCTRL_EMI_DCC_RESYNC_ENABLE
mov r0, #(HW_CLKCTRL_FRAC_ADDR & 0x000000FF)
orr r0, r0, #(HW_CLKCTRL_FRAC_ADDR & 0x0000FF00)
@@ -42,6 +43,15 @@ __stmp_emi_set_values:
nop
nop
+@ Change integer/fractional dividers.
+
+@ The fractional divider and integer divider must be written in such
+@ an order to guarantee that when going from a lower frequency to a
+@ higher frequency that any intermediate frequencies do not exceed
+@ the final frequency. For this reason, we must make sure to check
+@ the current divider values with the new divider values and write
+@ them in the correct order.
+
1: ldr r4, [r1]
and r4, r4, #BM_CLKCTRL_EMI_DIV_EMI
/* new emi div > cur emi div? */
@@ -49,15 +59,16 @@ __stmp_emi_set_values:
bgt 2f
mov r4, r7
orr r4, r4, #0x100
- orr r4, r4, r3
+
+@ This was for DCC_RESYNC_ENABLE, which is deprecated in mx23
+@ orr r4, r4, r3
+
str r4, [r1]
11: ldr r4, [r1]
tst r4, #BM_CLKCTRL_EMI_BUSY_REF_EMI
bne 11b
tst r4, #BM_CLKCTRL_EMI_BUSY_REF_XTAL
bne 11b
- tst r4, #BM_CLKCTRL_EMI_BUSY_DCC_RESYNC
- bne 11b
2: ldr r2, [r0]
@@ -80,15 +91,15 @@ __stmp_emi_set_values:
beq 4f
mov r4, r7
orr r4, r4, #0x100
- orr r4, r4, r3
+
+@ This was for DCC_RESYNC_ENABLE, which is deprecated in mx23
+@ orr r4, r4, r3
str r4, [r1]
31: ldr r4, [r1]
tst r4, #BM_CLKCTRL_EMI_BUSY_REF_EMI
bne 31b
tst r4, #BM_CLKCTRL_EMI_BUSY_REF_XTAL
bne 31b
- tst r4, #BM_CLKCTRL_EMI_BUSY_DCC_RESYNC
- bne 31b
4: ldmfd r9!, {r0 - r4, lr}
mov pc, lr