linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH/RFC v2 0/2] CPUFreq for kzm9g
@ 2013-02-25 17:16 Guennadi Liakhovetski
  2013-02-25 17:17 ` [PATCH/RFC v2 1/2] ARM: shmobile: sh73a0: add support for adjusting CPU frequency Guennadi Liakhovetski
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Guennadi Liakhovetski @ 2013-02-25 17:16 UTC (permalink / raw)
  To: linux-arm-kernel

In v2 of this patch-set I dropped patches 1 and 3, because #1 is a bug-fix 
and can go in separately, #3 is more of a debugging help, than a real 
patch for mainlining. Of the remaining 2 patches the main difference to v1 
is the omission of the PLL0 manipulation. More is explained in respective 
patches.

Guennadi Liakhovetski (2):
  ARM: shmobile: sh73a0: add support for adjusting CPU frequency
  ARM: shmobile: kzm9g-reference: add CPUFreq support

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH/RFC v2 1/2] ARM: shmobile: sh73a0: add support for adjusting CPU frequency
  2013-02-25 17:16 [PATCH/RFC v2 0/2] CPUFreq for kzm9g Guennadi Liakhovetski
@ 2013-02-25 17:17 ` Guennadi Liakhovetski
  2013-02-25 17:17 ` [PATCH/RFC v2 2/2] ARM: shmobile: kzm9g-reference: add CPUFreq support Guennadi Liakhovetski
  2013-02-26 12:08 ` [PATCH/RFC v2 0/2] CPUFreq for kzm9g Magnus Damm
  2 siblings, 0 replies; 5+ messages in thread
From: Guennadi Liakhovetski @ 2013-02-25 17:17 UTC (permalink / raw)
  To: linux-arm-kernel

On SH73A0 the output of PLL0 is supplied to two dividers, feeding clock to
the CPU core and SGX. Lower CPU frequencies allow the use of lower supply
voltages and thus reduce power consumption.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---

v2:
1. Don't touch PLL0 in this initial implementation. This means we cannot 
configure the CPU frequency exactly as in the datasheet - 806 and 403MHz 
for 1.175 and 1.065V OPPs respectively. Instead we can only set 598 and 
398.(6)MHz.
2. Add a comment to describe SGX ZG clock restrictions.

 arch/arm/mach-shmobile/clock-sh73a0.c |   93 ++++++++++++++++++++++++++++++++-
 1 files changed, 91 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c
index 71843dd..1a4edb9 100644
--- a/arch/arm/mach-shmobile/clock-sh73a0.c
+++ b/arch/arm/mach-shmobile/clock-sh73a0.c
@@ -21,6 +21,7 @@
 #include <linux/io.h>
 #include <linux/sh_clk.h>
 #include <linux/clkdev.h>
+#include <asm/processor.h>
 #include <mach/common.h>
 
 #define FRQCRA		IOMEM(0xe6150000)
@@ -265,6 +266,11 @@ enum { DIV4_I, DIV4_ZG, DIV4_M3, DIV4_B, DIV4_M1, DIV4_M2,
 
 static struct clk div4_clks[DIV4_NR] = {
 	[DIV4_I] = DIV4(FRQCRA, 20, 0xdff, CLK_ENABLE_ON_INIT),
+	/*
+	 * ZG clock is dividing PLL0 frequency to supply SGX. Make sure not to
+	 * exceed maximum frequencies of 201.5MHz for VDD_DVFS=1.175 and
+	 * 239.2MHz for VDD_DVFS=1.315V.
+	 */
 	[DIV4_ZG] = SH_CLK_DIV4(&pll0_clk, FRQCRA, 16, 0xd7f, CLK_ENABLE_ON_INIT),
 	[DIV4_M3] = DIV4(FRQCRA, 12, 0x1dff, CLK_ENABLE_ON_INIT),
 	[DIV4_B] = DIV4(FRQCRA, 8, 0xdff, CLK_ENABLE_ON_INIT),
@@ -277,6 +283,82 @@ static struct clk div4_clks[DIV4_NR] = {
 	[DIV4_HP] = DIV4(FRQCRB, 4, 0xdff, 0),
 };
 
+static int (*div4_set_rate)(struct clk *clk, unsigned long rate);
+static unsigned long (*div4_recalc)(struct clk *clk);
+static long (*div4_round_rate)(struct clk *clk, unsigned long rate);
+
+static int zclk_set_rate(struct clk *clk, unsigned long rate)
+{
+	int i, ret;
+
+	if (!clk->parent || !__clk_get(clk->parent))
+		return -ENODEV;
+
+	if (rate == clk_get_rate(clk->parent)) {
+		/* 1:1 - switch off divider */
+		__raw_writel(__raw_readl(FRQCRB) & ~(1 << 28), FRQCRB);
+		ret = 0;
+	} else {
+		/* set the divider - call the DIV4 method */
+		ret = div4_set_rate(clk, rate);
+		if (ret < 0)
+			goto esetrate;
+
+		/* Enable the divider */
+		__raw_writel(__raw_readl(FRQCRB) | (1 << 28), FRQCRB);
+	}
+
+	/*
+	 * Kick the clock - this is also done in sh_clk_div_set_rate(), but we
+	 * want to check success
+	 */
+	__raw_writel(__raw_readl(FRQCRB) | (1 << 31), FRQCRB);
+	for (i = 1000; i; i--)
+		if (__raw_readl(FRQCRB) & (1 << 31))
+			cpu_relax();
+		else
+			break;
+	if (!i)
+		ret = -ETIMEDOUT;
+
+esetrate:
+	__clk_put(clk->parent);
+	return ret;
+}
+
+static long zclk_round_rate(struct clk *clk, unsigned long rate)
+{
+	unsigned long div_freq = div4_round_rate(clk, rate),
+		parent_freq = clk_get_rate(clk->parent);
+
+	if (rate > div_freq && abs(parent_freq - rate) < rate - div_freq)
+		return parent_freq;
+
+	return div_freq;
+}
+
+static unsigned long zclk_recalc(struct clk *clk)
+{
+	/* Must recalculate frequencies, even if the divisor is unused ATM! */
+	unsigned long div_freq = div4_recalc(clk);
+
+	if (__raw_readl(FRQCRB) & (1 << 28))
+		return div_freq;
+
+	return clk_get_rate(clk->parent);
+}
+
+static void zclk_extend(void)
+{
+	/* We extend the DIV4 clock with a 1:1 pass-through case */
+	div4_set_rate = div4_clks[DIV4_Z].ops->set_rate;
+	div4_round_rate = div4_clks[DIV4_Z].ops->round_rate;
+	div4_recalc = div4_clks[DIV4_Z].ops->recalc;
+	div4_clks[DIV4_Z].ops->set_rate = zclk_set_rate;
+	div4_clks[DIV4_Z].ops->round_rate = zclk_round_rate;
+	div4_clks[DIV4_Z].ops->recalc = zclk_recalc;
+}
+
 enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_ZB1,
 	DIV6_FLCTL, DIV6_SDHI0, DIV6_SDHI1, DIV6_SDHI2,
 	DIV6_FSIA, DIV6_FSIB, DIV6_SUB,
@@ -474,7 +556,7 @@ static struct clk *late_main_clks[] = {
 };
 
 enum { MSTP001,
-	MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP116, MSTP100,
+	MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP116, MSTP112, MSTP100,
 	MSTP219, MSTP218, MSTP217,
 	MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
 	MSTP331, MSTP329, MSTP328, MSTP325, MSTP323, MSTP322,
@@ -495,6 +577,7 @@ static struct clk mstp_clks[MSTP_NR] = {
 	[MSTP125] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */
 	[MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX0 */
 	[MSTP116] = MSTP(&div4_clks[DIV4_HP], SMSTPCR1, 16, 0), /* IIC0 */
+	[MSTP112] = MSTP(&div4_clks[DIV4_ZG], SMSTPCR1, 12, 0), /* SGX */
 	[MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */
 	[MSTP219] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 19, 0), /* SCIFA7 */
 	[MSTP218] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* SY-DMAC */
@@ -536,6 +619,9 @@ static struct clk_lookup lookups[] = {
 	/* main clocks */
 	CLKDEV_CON_ID("r_clk", &r_clk),
 
+	/* DIV4 clocks */
+	CLKDEV_DEV_ID("cpu0", &div4_clks[DIV4_Z]), /* cpufreq-cpu0 */
+
 	/* DIV6 clocks */
 	CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),
 	CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]),
@@ -627,8 +713,11 @@ void __init sh73a0_clock_init(void)
 	for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
 		ret = clk_register(main_clks[k]);
 
-	if (!ret)
+	if (!ret) {
 		ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
+		if (!ret)
+			zclk_extend();
+	}
 
 	if (!ret)
 		ret = sh_clk_div6_reparent_register(div6_clks, DIV6_NR);
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH/RFC v2 2/2] ARM: shmobile: kzm9g-reference: add CPUFreq support
  2013-02-25 17:16 [PATCH/RFC v2 0/2] CPUFreq for kzm9g Guennadi Liakhovetski
  2013-02-25 17:17 ` [PATCH/RFC v2 1/2] ARM: shmobile: sh73a0: add support for adjusting CPU frequency Guennadi Liakhovetski
@ 2013-02-25 17:17 ` Guennadi Liakhovetski
  2013-02-26 12:08 ` [PATCH/RFC v2 0/2] CPUFreq for kzm9g Magnus Damm
  2 siblings, 0 replies; 5+ messages in thread
From: Guennadi Liakhovetski @ 2013-02-25 17:17 UTC (permalink / raw)
  To: linux-arm-kernel

This patch enables the use of the generic cpufreq-cpu0 driver on kzm9g.
Providing a regulator and a list of OPPs in DT, combined with a clock,
attached to the cpu0 device is everything, the cpufreq-cpu0 driver needs.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---

v2: adjust CPU frequencies in the OPP list according to v2 of patch 1/2.

 arch/arm/boot/dts/sh73a0-kzm9g-reference.dts |   19 ++++++++++++++++---
 arch/arm/mach-shmobile/Kconfig               |    2 ++
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/sh73a0-kzm9g-reference.dts b/arch/arm/boot/dts/sh73a0-kzm9g-reference.dts
index d9f6c18..d7f18fd 100644
--- a/arch/arm/boot/dts/sh73a0-kzm9g-reference.dts
+++ b/arch/arm/boot/dts/sh73a0-kzm9g-reference.dts
@@ -18,6 +18,19 @@
 	model = "KZM-A9-GT";
 	compatible = "renesas,kzm9g-reference", "renesas,sh73a0";
 
+	cpus {
+		cpu at 0 {
+			cpu0-supply = <&vdd_dvfs>;
+			operating-points = <
+				/* kHz  uV */
+				1196000 1315000
+				 598000 1175000
+				 398667 1065000
+			>;
+			voltage-tolerance = <1>; /* 1% */
+		};
+	};
+
 	chosen {
 		bootargs = "console=tty0 console=ttySC4,115200 root=/dev/nfs ip=dhcp ignore_loglevel earlyprintk=sh-sci.4,115200";
 	};
@@ -118,10 +131,10 @@
 		reg = <0x40>;
 
 		regulators {
-			sd1 {
+			vdd_dvfs: sd1 {
 				regulator-name = "1.315V CPU";
-				regulator-min-microvolt = <1315000>;
-				regulator-max-microvolt = <1335000>;
+				regulator-min-microvolt = <1050000>;
+				regulator-max-microvolt = <1350000>;
 				regulator-always-on;
 				regulator-boot-on;
 			};
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index 927eecc..6f621ac 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -141,6 +141,8 @@ config MACH_KZM9G
 config MACH_KZM9G_REFERENCE
 	bool "KZM-A9-GT board - Reference Device Tree Implementation"
 	depends on ARCH_SH73A0
+	select ARCH_HAS_CPUFREQ
+	select ARCH_HAS_OPP
 	select ARCH_REQUIRE_GPIOLIB
 	select REGULATOR_FIXED_VOLTAGE if REGULATOR
 	select SND_SOC_AK4642 if SND_SIMPLE_CARD
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH/RFC v2 0/2] CPUFreq for kzm9g
  2013-02-25 17:16 [PATCH/RFC v2 0/2] CPUFreq for kzm9g Guennadi Liakhovetski
  2013-02-25 17:17 ` [PATCH/RFC v2 1/2] ARM: shmobile: sh73a0: add support for adjusting CPU frequency Guennadi Liakhovetski
  2013-02-25 17:17 ` [PATCH/RFC v2 2/2] ARM: shmobile: kzm9g-reference: add CPUFreq support Guennadi Liakhovetski
@ 2013-02-26 12:08 ` Magnus Damm
  2013-03-01 21:11   ` Guennadi Liakhovetski
  2 siblings, 1 reply; 5+ messages in thread
From: Magnus Damm @ 2013-02-26 12:08 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Feb 26, 2013 at 2:16 AM, Guennadi Liakhovetski
<g.liakhovetski@gmx.de> wrote:
> In v2 of this patch-set I dropped patches 1 and 3, because #1 is a bug-fix
> and can go in separately, #3 is more of a debugging help, than a real
> patch for mainlining. Of the remaining 2 patches the main difference to v1
> is the omission of the PLL0 manipulation. More is explained in respective
> patches.
>
> Guennadi Liakhovetski (2):
>   ARM: shmobile: sh73a0: add support for adjusting CPU frequency
>   ARM: shmobile: kzm9g-reference: add CPUFreq support

Hi Guennadi,

Thanks for your work on this. In general I am quite happy about this series.

One rather significant question is however this: Would it be possible
for you to check if the TWD is operating as expected when you scale
the CPU Frequency? I suspect it is not, so please cook up a v3 of this
series that also includes updates for timers.

Cheers,

/ magnus

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH/RFC v2 0/2] CPUFreq for kzm9g
  2013-02-26 12:08 ` [PATCH/RFC v2 0/2] CPUFreq for kzm9g Magnus Damm
@ 2013-03-01 21:11   ` Guennadi Liakhovetski
  0 siblings, 0 replies; 5+ messages in thread
From: Guennadi Liakhovetski @ 2013-03-01 21:11 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 26 Feb 2013, Magnus Damm wrote:

> On Tue, Feb 26, 2013 at 2:16 AM, Guennadi Liakhovetski
> <g.liakhovetski@gmx.de> wrote:
> > In v2 of this patch-set I dropped patches 1 and 3, because #1 is a bug-fix
> > and can go in separately, #3 is more of a debugging help, than a real
> > patch for mainlining. Of the remaining 2 patches the main difference to v1
> > is the omission of the PLL0 manipulation. More is explained in respective
> > patches.
> >
> > Guennadi Liakhovetski (2):
> >   ARM: shmobile: sh73a0: add support for adjusting CPU frequency
> >   ARM: shmobile: kzm9g-reference: add CPUFreq support
> 
> Hi Guennadi,
> 
> Thanks for your work on this. In general I am quite happy about this series.
> 
> One rather significant question is however this: Would it be possible
> for you to check if the TWD is operating as expected when you scale
> the CPU Frequency? I suspect it is not, so please cook up a v3 of this
> series that also includes updates for timers.

At last I managed to get twd running with a recent (of 27.02) all+next 
snapshot on kzm9g with DT (reference) and actually I'm not really sure the 
problem is there. At least definitely not as bad as I saw it last time. To 
remind, the problem I observed was, that at lower CPU speeds a simple 
shell script, consisting of 20 20-second sleep calls was gaining multiple 
seconds, was taking more like 405 seconds, than 400. Now I only see it 
going to 401 seconds. This is still not good, but I need a more precise 
comparison to actually decide, whether this problem only appears at lower 
CPU speeds or it is always there. I'll look further into it next week.

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2013-03-01 21:11 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-02-25 17:16 [PATCH/RFC v2 0/2] CPUFreq for kzm9g Guennadi Liakhovetski
2013-02-25 17:17 ` [PATCH/RFC v2 1/2] ARM: shmobile: sh73a0: add support for adjusting CPU frequency Guennadi Liakhovetski
2013-02-25 17:17 ` [PATCH/RFC v2 2/2] ARM: shmobile: kzm9g-reference: add CPUFreq support Guennadi Liakhovetski
2013-02-26 12:08 ` [PATCH/RFC v2 0/2] CPUFreq for kzm9g Magnus Damm
2013-03-01 21:11   ` Guennadi Liakhovetski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).