diff mbox

[1/5] arm: sa1100: add cpu clock

Message ID 1384227132-10501-1-git-send-email-dbaryshkov@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Dmitry Baryshkov Nov. 12, 2013, 3:32 a.m. UTC
Both SA1100 framebuffer and PCMCIA drivers require knowledge of cpu
frequency to correctly program timings.  Currently they receive timing
information by calling cpufreq_get(0).  However if cpu frequency driver
is not enabled (e.g. due to unsupported DRAM chip/board on sa1110)
cpufreq_get(0) returns 0, causing incorrect timings to be programmed.

Add cpu clock returning cpu frequency, to be used by sa11x0 fb and
pcmcia drivers.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 arch/arm/mach-sa1100/clock.c | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

Comments

Russell King - ARM Linux Nov. 12, 2013, 9:57 a.m. UTC | #1
On Tue, Nov 12, 2013 at 07:32:08AM +0400, Dmitry Eremin-Solenikov wrote:
> Both SA1100 framebuffer and PCMCIA drivers require knowledge of cpu
> frequency to correctly program timings.  Currently they receive timing
> information by calling cpufreq_get(0).  However if cpu frequency driver
> is not enabled (e.g. due to unsupported DRAM chip/board on sa1110)
> cpufreq_get(0) returns 0, causing incorrect timings to be programmed.

I added a select statement back in 1937f5b91833e2e8e53bcc821fc7a5fbe6ccb9b5
which avoids this problem.  Does this not work?
--
To unsubscribe from this list: send the line "unsubscribe linux-fbdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Dmitry Baryshkov Nov. 12, 2013, 10:37 a.m. UTC | #2
On 11/12/2013 01:57 PM, Russell King - ARM Linux wrote:
> On Tue, Nov 12, 2013 at 07:32:08AM +0400, Dmitry Eremin-Solenikov wrote:
>> Both SA1100 framebuffer and PCMCIA drivers require knowledge of cpu
>> frequency to correctly program timings.  Currently they receive timing
>> information by calling cpufreq_get(0).  However if cpu frequency driver
>> is not enabled (e.g. due to unsupported DRAM chip/board on sa1110)
>> cpufreq_get(0) returns 0, causing incorrect timings to be programmed.
>
> I added a select statement back in 1937f5b91833e2e8e53bcc821fc7a5fbe6ccb9b5
> which avoids this problem.  Does this not work?

No, it does not.

1) For collie (sa1110) we don't have dram chip timings in table, so the 
cpufreq driver is not registered and cpufreq_get() returns 0

2) What if I want to build a kernel w/o cpu freq? We have clocks exactly 
for this reasons - to let drivers get frequency information.

3) And last but not least - PXA uses clocks in this place.
diff mbox

Patch

diff --git a/arch/arm/mach-sa1100/clock.c b/arch/arm/mach-sa1100/clock.c
index 172ebd0..abf1dc1 100644
--- a/arch/arm/mach-sa1100/clock.c
+++ b/arch/arm/mach-sa1100/clock.c
@@ -15,10 +15,12 @@ 
 #include <linux/clkdev.h>
 
 #include <mach/hardware.h>
+#include <mach/generic.h>
 
 struct clkops {
 	void			(*enable)(struct clk *);
 	void			(*disable)(struct clk *);
+	unsigned long		(*get_rate)(struct clk *);
 };
 
 struct clk {
@@ -51,6 +53,19 @@  static void clk_gpio27_disable(struct clk *clk)
 	GAFR &= ~GPIO_32_768kHz;
 }
 
+static void clk_cpu_enable(struct clk *clk)
+{
+}
+
+static void clk_cpu_disable(struct clk *clk)
+{
+}
+
+static unsigned long clk_cpu_get_rate(struct clk *clk)
+{
+	return sa11x0_getspeed(0) * 1000;
+}
+
 int clk_enable(struct clk *clk)
 {
 	unsigned long flags;
@@ -80,16 +95,35 @@  void clk_disable(struct clk *clk)
 }
 EXPORT_SYMBOL(clk_disable);
 
+unsigned long clk_get_rate(struct clk *clk)
+{
+	if (clk && clk->ops && clk->ops->get_rate)
+		return clk->ops->get_rate(clk);
+	else
+		return 0;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
 const struct clkops clk_gpio27_ops = {
 	.enable		= clk_gpio27_enable,
 	.disable	= clk_gpio27_disable,
 };
 
+const struct clkops clk_cpu_ops = {
+	.enable		= clk_cpu_enable,
+	.disable	= clk_cpu_disable,
+	.get_rate	= clk_cpu_get_rate,
+};
+
 static DEFINE_CLK(gpio27, &clk_gpio27_ops);
 
+static DEFINE_CLK(cpu, &clk_cpu_ops);
+
 static struct clk_lookup sa11xx_clkregs[] = {
 	CLKDEV_INIT("sa1111.0", NULL, &clk_gpio27),
 	CLKDEV_INIT("sa1100-rtc", NULL, NULL),
+	CLKDEV_INIT("sa11x0-fb", NULL, &clk_cpu),
+	CLKDEV_INIT("sa11x0-pcmcia", NULL, &clk_cpu),
 };
 
 static int __init sa11xx_clk_init(void)