summaryrefslogtreecommitdiff
path: root/arch/arm/mach-omap2
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2009-05-26 14:41:35 -0700
committerTony Lindgren <tony@atomide.com>2009-05-26 14:41:35 -0700
commit88b6f7eb9b4a06fbfe27f2d98e249577f4cfdaef (patch)
tree9ef0d7ecd3e0551ca4d13ac0134aeb3ecd8558c7 /arch/arm/mach-omap2
parent8f9ccfeeb2cecb54dd093119291ab271ab0fd94a (diff)
parent7971687094ef48695aa56a0c03416b609bd4d1fd (diff)
Merge branch 'omap-clock-upstream' of git://git.pwsan.com/linux-2.6 into for-next
Diffstat (limited to 'arch/arm/mach-omap2')
-rw-r--r--arch/arm/mach-omap2/clock.c14
-rw-r--r--arch/arm/mach-omap2/clock24xx.c2
-rw-r--r--arch/arm/mach-omap2/clock34xx.c20
-rw-r--r--arch/arm/mach-omap2/sdrc.c19
-rw-r--r--arch/arm/mach-omap2/sram34xx.S129
5 files changed, 107 insertions, 77 deletions
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index dd37483f3d18..ba528f85749c 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -547,8 +547,8 @@ u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
const struct clksel_rate *clkr;
u32 last_div = 0;
- printk(KERN_INFO "clock: clksel_round_rate_div: %s target_rate %ld\n",
- clk->name, target_rate);
+ pr_debug("clock: clksel_round_rate_div: %s target_rate %ld\n",
+ clk->name, target_rate);
*new_div = 1;
@@ -562,7 +562,7 @@ u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
/* Sanity check */
if (clkr->div <= last_div)
- printk(KERN_ERR "clock: clksel_rate table not sorted "
+ pr_err("clock: clksel_rate table not sorted "
"for clock %s", clk->name);
last_div = clkr->div;
@@ -574,7 +574,7 @@ u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
}
if (!clkr->div) {
- printk(KERN_ERR "clock: Could not find divisor for target "
+ pr_err("clock: Could not find divisor for target "
"rate %ld for clock %s parent %s\n", target_rate,
clk->name, clk->parent->name);
return ~0;
@@ -582,8 +582,8 @@ u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
*new_div = clkr->div;
- printk(KERN_INFO "clock: new_div = %d, new_rate = %ld\n", *new_div,
- (clk->parent->rate / clkr->div));
+ pr_debug("clock: new_div = %d, new_rate = %ld\n", *new_div,
+ (clk->parent->rate / clkr->div));
return (clk->parent->rate / clkr->div);
}
@@ -1035,7 +1035,7 @@ void omap2_clk_disable_unused(struct clk *clk)
if ((regval32 & (1 << clk->enable_bit)) == v)
return;
- printk(KERN_INFO "Disabling unused clock \"%s\"\n", clk->name);
+ printk(KERN_DEBUG "Disabling unused clock \"%s\"\n", clk->name);
if (cpu_is_omap34xx()) {
omap2_clk_enable(clk);
omap2_clk_disable(clk);
diff --git a/arch/arm/mach-omap2/clock24xx.c b/arch/arm/mach-omap2/clock24xx.c
index c442fe9f998a..44de0271fc2f 100644
--- a/arch/arm/mach-omap2/clock24xx.c
+++ b/arch/arm/mach-omap2/clock24xx.c
@@ -725,7 +725,7 @@ int __init omap2_clk_init(void)
clk_init(&omap2_clk_functions);
for (c = omap24xx_clks; c < omap24xx_clks + ARRAY_SIZE(omap24xx_clks); c++)
- clk_init_one(c->lk.clk);
+ clk_preinit(c->lk.clk);
osc_ck.rate = omap2_osc_clk_recalc(&osc_ck);
propagate_rate(&osc_ck);
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index ba05aa42bd8e..62021397e5f9 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -281,6 +281,8 @@ static struct omap_clk omap34xx_clks[] = {
#define MAX_DPLL_WAIT_TRIES 1000000
+#define MIN_SDRC_DLL_LOCK_FREQ 83000000
+
/**
* omap3_dpll_recalc - recalculate DPLL rate
* @clk: DPLL struct clk
@@ -703,6 +705,7 @@ static int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate)
static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
{
u32 new_div = 0;
+ u32 unlock_dll = 0;
unsigned long validrate, sdrcrate;
struct omap_sdrc_params *sp;
@@ -729,17 +732,22 @@ static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
if (!sp)
return -EINVAL;
- pr_info("clock: changing CORE DPLL rate from %lu to %lu\n", clk->rate,
- validrate);
- pr_info("clock: SDRC timing params used: %08x %08x %08x\n",
- sp->rfr_ctrl, sp->actim_ctrla, sp->actim_ctrlb);
+ if (sdrcrate < MIN_SDRC_DLL_LOCK_FREQ) {
+ pr_debug("clock: will unlock SDRC DLL\n");
+ unlock_dll = 1;
+ }
+
+ pr_debug("clock: changing CORE DPLL rate from %lu to %lu\n", clk->rate,
+ validrate);
+ pr_debug("clock: SDRC timing params used: %08x %08x %08x\n",
+ sp->rfr_ctrl, sp->actim_ctrla, sp->actim_ctrlb);
/* REVISIT: SRAM code doesn't support other M2 divisors yet */
WARN_ON(new_div != 1 && new_div != 2);
/* REVISIT: Add SDRC_MR changing to this code also */
omap3_configure_core_dpll(sp->rfr_ctrl, sp->actim_ctrla,
- sp->actim_ctrlb, new_div);
+ sp->actim_ctrlb, new_div, unlock_dll);
return 0;
}
@@ -956,7 +964,7 @@ int __init omap2_clk_init(void)
clk_init(&omap2_clk_functions);
for (c = omap34xx_clks; c < omap34xx_clks + ARRAY_SIZE(omap34xx_clks); c++)
- clk_init_one(c->lk.clk);
+ clk_preinit(c->lk.clk);
for (c = omap34xx_clks; c < omap34xx_clks + ARRAY_SIZE(omap34xx_clks); c++)
if (c->cpu & cpu_clkflg) {
diff --git a/arch/arm/mach-omap2/sdrc.c b/arch/arm/mach-omap2/sdrc.c
index 2a30060cb4b7..d62e4e10d4b0 100644
--- a/arch/arm/mach-omap2/sdrc.c
+++ b/arch/arm/mach-omap2/sdrc.c
@@ -37,6 +37,10 @@ static struct omap_sdrc_params *sdrc_init_params;
void __iomem *omap2_sdrc_base;
void __iomem *omap2_sms_base;
+/* SDRC_POWER register bits */
+#define SDRC_POWER_EXTCLKDIS_SHIFT 3
+#define SDRC_POWER_PWDENA_SHIFT 2
+#define SDRC_POWER_PAGEPOLICY_SHIFT 0
/**
* omap2_sdrc_get_params - return SDRC register values for a given clock rate
@@ -74,7 +78,14 @@ void __init omap2_set_globals_sdrc(struct omap_globals *omap2_globals)
omap2_sms_base = omap2_globals->sms;
}
-/* turn on smart idle modes for SDRAM scheduler and controller */
+/**
+ * omap2_sdrc_init - initialize SMS, SDRC devices on boot
+ * @sp: pointer to a null-terminated list of struct omap_sdrc_params
+ *
+ * Turn on smart idle modes for SDRAM scheduler and controller.
+ * Program a known-good configuration for the SDRC to deal with buggy
+ * bootloaders.
+ */
void __init omap2_sdrc_init(struct omap_sdrc_params *sp)
{
u32 l;
@@ -90,4 +101,10 @@ void __init omap2_sdrc_init(struct omap_sdrc_params *sp)
sdrc_write_reg(l, SDRC_SYSCONFIG);
sdrc_init_params = sp;
+
+ /* XXX Enable SRFRONIDLEREQ here also? */
+ l = (1 << SDRC_POWER_EXTCLKDIS_SHIFT) |
+ (1 << SDRC_POWER_PWDENA_SHIFT) |
+ (1 << SDRC_POWER_PAGEPOLICY_SHIFT);
+ sdrc_write_reg(l, SDRC_POWER);
}
diff --git a/arch/arm/mach-omap2/sram34xx.S b/arch/arm/mach-omap2/sram34xx.S
index 2c7146136342..c080c82521e1 100644
--- a/arch/arm/mach-omap2/sram34xx.S
+++ b/arch/arm/mach-omap2/sram34xx.S
@@ -40,69 +40,74 @@
/*
* Change frequency of core dpll
* r0 = sdrc_rfr_ctrl r1 = sdrc_actim_ctrla r2 = sdrc_actim_ctrlb r3 = M2
+ * r4 = Unlock SDRC DLL? (1 = yes, 0 = no) -- only unlock DLL for
+ * SDRC rates < 83MHz
*/
ENTRY(omap3_sram_configure_core_dpll)
stmfd sp!, {r1-r12, lr} @ store regs to stack
+ ldr r4, [sp, #52] @ pull extra args off the stack
+ dsb @ flush buffered writes to interconnect
cmp r3, #0x2
blne configure_sdrc
- cmp r3, #0x2
+ cmp r4, #0x1
+ bleq unlock_dll
blne lock_dll
- cmp r3, #0x1
- blne unlock_dll
bl sdram_in_selfrefresh @ put the SDRAM in self refresh
bl configure_core_dpll
bl enable_sdrc
- cmp r3, #0x1
- blne wait_dll_unlock
- cmp r3, #0x2
+ cmp r4, #0x1
+ bleq wait_dll_unlock
blne wait_dll_lock
cmp r3, #0x1
blne configure_sdrc
+ isb @ prevent speculative exec past here
mov r0, #0 @ return value
ldmfd sp!, {r1-r12, pc} @ restore regs and return
unlock_dll:
- ldr r4, omap3_sdrc_dlla_ctrl
- ldr r5, [r4]
- orr r5, r5, #0x4
- str r5, [r4]
+ ldr r11, omap3_sdrc_dlla_ctrl
+ ldr r12, [r11]
+ orr r12, r12, #0x4
+ str r12, [r11] @ (no OCP barrier needed)
bx lr
lock_dll:
- ldr r4, omap3_sdrc_dlla_ctrl
- ldr r5, [r4]
- bic r5, r5, #0x4
- str r5, [r4]
+ ldr r11, omap3_sdrc_dlla_ctrl
+ ldr r12, [r11]
+ bic r12, r12, #0x4
+ str r12, [r11] @ (no OCP barrier needed)
bx lr
sdram_in_selfrefresh:
- mov r5, #0x0 @ Move 0 to R5
- mcr p15, 0, r5, c7, c10, 5 @ memory barrier
- ldr r4, omap3_sdrc_power @ read the SDRC_POWER register
- ldr r5, [r4] @ read the contents of SDRC_POWER
- orr r5, r5, #0x40 @ enable self refresh on idle req
- str r5, [r4] @ write back to SDRC_POWER register
- ldr r4, omap3_cm_iclken1_core @ read the CM_ICLKEN1_CORE reg
- ldr r5, [r4]
- bic r5, r5, #0x2 @ disable iclk bit for SRDC
- str r5, [r4]
+ ldr r11, omap3_sdrc_power @ read the SDRC_POWER register
+ ldr r12, [r11] @ read the contents of SDRC_POWER
+ mov r9, r12 @ keep a copy of SDRC_POWER bits
+ orr r12, r12, #0x40 @ enable self refresh on idle req
+ bic r12, r12, #0x4 @ clear PWDENA
+ str r12, [r11] @ write back to SDRC_POWER register
+ ldr r12, [r11] @ posted-write barrier for SDRC
+ ldr r11, omap3_cm_iclken1_core @ read the CM_ICLKEN1_CORE reg
+ ldr r12, [r11]
+ bic r12, r12, #0x2 @ disable iclk bit for SDRC
+ str r12, [r11]
wait_sdrc_idle:
- ldr r4, omap3_cm_idlest1_core
- ldr r5, [r4]
- and r5, r5, #0x2 @ check for SDRC idle
- cmp r5, #2
+ ldr r11, omap3_cm_idlest1_core
+ ldr r12, [r11]
+ and r12, r12, #0x2 @ check for SDRC idle
+ cmp r12, #2
bne wait_sdrc_idle
bx lr
configure_core_dpll:
- ldr r4, omap3_cm_clksel1_pll
- ldr r5, [r4]
- ldr r6, core_m2_mask_val @ modify m2 for core dpll
- and r5, r5, r6
- orr r5, r5, r3, lsl #0x1B @ r3 contains the M2 val
- str r5, [r4]
- mov r5, #0x800 @ wait for the clock to stabilise
+ ldr r11, omap3_cm_clksel1_pll
+ ldr r12, [r11]
+ ldr r10, core_m2_mask_val @ modify m2 for core dpll
+ and r12, r12, r10
+ orr r12, r12, r3, lsl #0x1B @ r3 contains the M2 val
+ str r12, [r11]
+ ldr r12, [r11] @ posted-write barrier for CM
+ mov r12, #0x800 @ wait for the clock to stabilise
cmp r3, #2
bne wait_clk_stable
bx lr
wait_clk_stable:
- subs r5, r5, #1
+ subs r12, r12, #1
bne wait_clk_stable
nop
nop
@@ -116,42 +121,42 @@ wait_clk_stable:
nop
bx lr
enable_sdrc:
- ldr r4, omap3_cm_iclken1_core
- ldr r5, [r4]
- orr r5, r5, #0x2 @ enable iclk bit for SDRC
- str r5, [r4]
+ ldr r11, omap3_cm_iclken1_core
+ ldr r12, [r11]
+ orr r12, r12, #0x2 @ enable iclk bit for SDRC
+ str r12, [r11]
wait_sdrc_idle1:
- ldr r4, omap3_cm_idlest1_core
- ldr r5, [r4]
- and r5, r5, #0x2
- cmp r5, #0
+ ldr r11, omap3_cm_idlest1_core
+ ldr r12, [r11]
+ and r12, r12, #0x2
+ cmp r12, #0
bne wait_sdrc_idle1
- ldr r4, omap3_sdrc_power
- ldr r5, [r4]
- bic r5, r5, #0x40
- str r5, [r4]
+restore_sdrc_power_val:
+ ldr r11, omap3_sdrc_power
+ str r9, [r11] @ restore SDRC_POWER, no barrier needed
bx lr
wait_dll_lock:
- ldr r4, omap3_sdrc_dlla_status
- ldr r5, [r4]
- and r5, r5, #0x4
- cmp r5, #0x4
+ ldr r11, omap3_sdrc_dlla_status
+ ldr r12, [r11]
+ and r12, r12, #0x4
+ cmp r12, #0x4
bne wait_dll_lock
bx lr
wait_dll_unlock:
- ldr r4, omap3_sdrc_dlla_status
- ldr r5, [r4]
- and r5, r5, #0x4
- cmp r5, #0x0
+ ldr r11, omap3_sdrc_dlla_status
+ ldr r12, [r11]
+ and r12, r12, #0x4
+ cmp r12, #0x0
bne wait_dll_unlock
bx lr
configure_sdrc:
- ldr r4, omap3_sdrc_rfr_ctrl
- str r0, [r4]
- ldr r4, omap3_sdrc_actim_ctrla
- str r1, [r4]
- ldr r4, omap3_sdrc_actim_ctrlb
- str r2, [r4]
+ ldr r11, omap3_sdrc_rfr_ctrl
+ str r0, [r11]
+ ldr r11, omap3_sdrc_actim_ctrla
+ str r1, [r11]
+ ldr r11, omap3_sdrc_actim_ctrlb
+ str r2, [r11]
+ ldr r2, [r11] @ posted-write barrier for SDRC
bx lr
omap3_sdrc_power: