diff options
author | Jon Hunter <jon-hunter@ti.com> | 2010-09-27 16:02:59 -0400 |
---|---|---|
committer | Paul Walmsley <paul@pwsan.com> | 2010-09-27 16:02:59 -0400 |
commit | a3fed9bc181666df6ecfe9ce34a29d48803f2310 (patch) | |
tree | c9adc2fc9b5d84c88d5ebe2f33865d1a859ffbda /arch | |
parent | dcf5ef3f42fbc0c62043b4c466d679fca32f1b9f (diff) |
omap3: Prevent SDRC deadlock when L3 is changing frequency
When changing the L3 clock frequency, the CPU is executing from internal RAM
and the SDRC clock is disabled. During this time accesses made to external
DDR are stalled. If the ARM subsystem attempts to access the DDR while the
SDRC clock is disabled this will stall the CPU until the access to the SDRC
timeouts. A timeout on the SDRC should never occur. Once a timeout occurs all
the following accesses will be aborted and the DDR is no longer accessible.
Although the code being executed in the internal RAM does not directly access
the DDR, it was found that the branch prediction logic in the CPU may cause
the CPU to prefetch code from a DDR location while the SDRC clock is disabled.
This was causing an SDRC timeout which resulted in a system hang.
This patch fixes this problem by ensuring the branch prediction logic is
disabled while changing the L3 clock frequency. The branch prediction logic
is disabled by clearing the Z-bit in the ARM CTRL register.
Disabling the branch prediction logic does not have any noticable impact
on the execution time of this code section. The hardware observability
signals were used to monitor the sdrc idle time with and without this
patch when operating at different CPU frequencies (150MHz, 500MHz and
600MHz) and the total sdrc idle time when changing frequenct was in
the range of 9-11us. This was measured on an omap3430 SDP running the
omapzoom p-android-omap-2.6.29 branch.
Signed-off-by: Jon Hunter <jon-hunter@ti.com>
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Richard Woodruff <r-woodruff2@ti.com>
Cc: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-omap2/sram34xx.S | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/arch/arm/mach-omap2/sram34xx.S b/arch/arm/mach-omap2/sram34xx.S index de99ba2a57ab..3637274af5be 100644 --- a/arch/arm/mach-omap2/sram34xx.S +++ b/arch/arm/mach-omap2/sram34xx.S | |||
@@ -129,8 +129,11 @@ ENTRY(omap3_sram_configure_core_dpll) | |||
129 | ldr r4, [sp, #80] | 129 | ldr r4, [sp, #80] |
130 | str r4, omap_sdrc_mr_1_val | 130 | str r4, omap_sdrc_mr_1_val |
131 | skip_cs1_params: | 131 | skip_cs1_params: |
132 | mrc p15, 0, r8, c1, c0, 0 @ read ctrl register | ||
133 | bic r10, r8, #0x800 @ clear Z-bit, disable branch prediction | ||
134 | mcr p15, 0, r10, c1, c0, 0 @ write ctrl register | ||
132 | dsb @ flush buffered writes to interconnect | 135 | dsb @ flush buffered writes to interconnect |
133 | 136 | isb @ prevent speculative exec past here | |
134 | cmp r3, #1 @ if increasing SDRC clk rate, | 137 | cmp r3, #1 @ if increasing SDRC clk rate, |
135 | bleq configure_sdrc @ program the SDRC regs early (for RFR) | 138 | bleq configure_sdrc @ program the SDRC regs early (for RFR) |
136 | cmp r1, #SDRC_UNLOCK_DLL @ set the intended DLL state | 139 | cmp r1, #SDRC_UNLOCK_DLL @ set the intended DLL state |
@@ -148,6 +151,7 @@ skip_cs1_params: | |||
148 | beq return_to_sdram @ return to SDRAM code, otherwise, | 151 | beq return_to_sdram @ return to SDRAM code, otherwise, |
149 | bl configure_sdrc @ reprogram SDRC regs now | 152 | bl configure_sdrc @ reprogram SDRC regs now |
150 | return_to_sdram: | 153 | return_to_sdram: |
154 | mcr p15, 0, r8, c1, c0, 0 @ restore ctrl register | ||
151 | isb @ prevent speculative exec past here | 155 | isb @ prevent speculative exec past here |
152 | mov r0, #0 @ return value | 156 | mov r0, #0 @ return value |
153 | ldmfd sp!, {r1-r12, pc} @ restore regs and return | 157 | ldmfd sp!, {r1-r12, pc} @ restore regs and return |