Hello Olof,
On Wed, 20 Jan 2010, Olof Johansson wrote:
> Don't assume that gpmc_l3_clk is on, enable it before touching
> configuration registers.
>
> Signed-off-by: Olof Johansson
>
>
> diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
> index e86f5ca..dea72f3 100644
> --- a/arch/arm/mach-omap2/gpmc.c
> +++ b/arch/arm/mach-omap2/gpmc.c
> @@ -534,6 +534,8 @@ void __init gpmc_init(void)
> BUG();
> }
>
> + clk_enable(gpmc_l3_clk);
> +
> l = gpmc_read_reg(GPMC_REVISION);
> printk(KERN_INFO "GPMC revision %d.%d\n", (l >> 4) & 0x0f, l & 0x0f);
> /* Set smart idle mode and automatic L3 clock gating */
Care to try an approach similar to the following? Compile-tested, but
otherwise untested.
- Paul
>From 93bef5c90eed5247cfeada601beacdc734891924 Mon Sep 17 00:00:00 2001
From: Paul Walmsley
Date: Wed, 20 Jan 2010 18:16:18 -0700
Subject: [PATCH] OMAP GPMC: add fine-grained clock control
OMAP4 GPMC has a software-controllable GPMC clock gate, so, take
advantage of it by only enabling the GPMC clock when needed. Since
OMAP2xxx/3 don't have a separate software-controllable GPMC clock,
this change should not affect these platforms, aside from slowing some
of the gpmc.c functions down slightly.
Also rename "gpmc_l3_clk" to the more generic "gpmc_clk".
Since the GPMC clock is now enabled and disabled on demand, the
ENABLE_ON_INIT clock flag can be removed from the GPMC clocks; do so.
While here, add some to-do items to the initial comment block.
Finally, add a gpmc_ocp_barrier() function, intended to ensure that
all register writes to the GPMC are complete before disabling the GPMC
clock. Barriers are added where they appear to be needed.
---
arch/arm/mach-omap2/clock2xxx_data.c |1 -
arch/arm/mach-omap2/clock34xx_data.c |1 -
arch/arm/mach-omap2/gpmc.c | 92 --
3 files changed, 76 insertions(+), 18 deletions(-)
diff --git a/arch/arm/mach-omap2/clock2xxx_data.c
b/arch/arm/mach-omap2/clock2xxx_data.c
index 97dc7cf..0997104 100644
--- a/arch/arm/mach-omap2/clock2xxx_data.c
+++ b/arch/arm/mach-omap2/clock2xxx_data.c
@@ -1804,7 +1804,6 @@ static struct clk gpmc_fck = {
.name = "gpmc_fck",
.ops= &clkops_null, /* RMK: missing? */
.parent = &core_l3_ck,
- .flags = ENABLE_ON_INIT,
.clkdm_name = "core_l3_clkdm",
.recalc = &followparent_recalc,
};
diff --git a/arch/arm/mach-omap2/clock34xx_data.c
b/arch/arm/mach-omap2/clock34xx_data.c
index c6031d7..fab9e5b 100644
--- a/arch/arm/mach-omap2/clock34xx_data.c
+++ b/arch/arm/mach-omap2/clock34xx_data.c
@@ -1654,7 +1654,6 @@ static struct clk gpmc_fck = {
.name = "gpmc_fck",
.ops= &clkops_null,
.parent = &core_l3_ick,
- .flags = ENABLE_ON_INIT, /* huh? */
.clkdm_name = "core_l3_clkdm",
.recalc = &followparent_recalc,
};
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 3f1334f..3ccd1d5 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -1,7 +1,7 @@
/*
* GPMC support functions
*
- * Copyright (C) 2005-2006 Nokia Corporation
+ * Copyright (C) 2005-2006, 2010 Nokia Corporation
*
* Author: Juha Yrjola
*
@@ -11,6 +11,20 @@
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
+ *
+ * XXX Convert this to an early platform driver or something similar
+ *
+ * XXX This code is missing support for some of the OMAP3 GPMC features,
+ * such as CYCLE2CYCLESAMECSEN, CYCLE2CYCLEDIFFCSEN, CYCLE2CYCLEDELAY,
+ * BUSTURNAROUND, etc.
+ *
+ * XXX It's insufficient for the GPMC timing setup code to only take
+ * into account the target chip timing parameters - it must also take
+ * into consideration board timing parameters. For example, bus level
+ * translators between the OMAP and the target chip can introduce
+ * latency that can affect timings. In some extreme cases, PCB
+ * transmission line effects (e.g., rise time, fall time) may also
+ * need to be taken into account.
*/
#undef DEBUG
@@ -96,7 +110,7 @@ static unsigned gpmc_cs_map;
static void __iomem *gpmc_base;
-static struct clk *gpmc_l3_clk;
+static struct clk *gpmc_clk;
static void gpmc_write_reg(int idx, u32 val)
{
@@ -108,6 +122,11 @@ static u32 gpmc_read_reg(int idx)
return __raw_readl(gpmc_base + idx);
}
+static void gpmc_ocp_barrier(void)
+{
+ gpmc_read_reg(GPMC_REVISION);
+}
+
void gpmc_cs_write_reg(int cs, int idx, u32 val)
{
void __iomem *reg_addr;
@@ -124,13 +143,12 @@ u32 gpmc_cs_read_reg(int cs, int idx)
return __raw_readl(reg_addr);
}
-/* TODO: Add support for gpmc_fck to clock framework and use it */
unsigned long gpmc_get_fclk_period(void)
{
-