2013-05-17 21:19:00

by Tony Prisk

[permalink] [raw]
Subject: [PATCH 0/4] VT8500 clock for 3.10/3.11

Hi Mike,

Patch #1 is a fix for 3.10 please - Due to an unbalanced spinlock in
vt8500_dclk_set_rate() we get kernel dumps on bootup.

Patch #2 adds support for the PLL clocks on WM8850 - originally it was thought
these were the same as WM8750, but with the release of vendor source it's now
confirmed to be different.

Patch #3 removes a check (which is also done in vt8500_dclk_round_rate) to
ensure the divisor is correct. Due to rounding errors, this usually results in
a lower than requested clock rate. Because round_rate is always called on all
our clocks, this test is actually redundant so I have dropped it.

Patch #4 is to add clk-vt8500.c to MAINTAINERS

Regards
Tony Prisk

Tony Prisk (4):
clk: vt8500: Fix unbalanced spinlock in vt8500_dclk_set_rate()
clk: vt8500: Add support for clocks on the WM8850 SoCs
clk: vt8500: Remove unnecessary divisor adjustment in
vtwm_dclk_set_rate()
MAINTAINERS: vt8500: Add clk-vt8500.c to MAINTAINERS file

Documentation/devicetree/bindings/clock/vt8500.txt | 2 +
MAINTAINERS | 1 +
drivers/clk/clk-vt8500.c | 77 ++++++++++++++++++--
3 files changed, 75 insertions(+), 5 deletions(-)

--
1.7.9.5


2013-05-17 21:18:59

by Tony Prisk

[permalink] [raw]
Subject: [PATCH 4/4] MAINTAINERS: vt8500: Add clk-vt8500.c to MAINTAINERS file

This file has missed being added under ARM/VT8500 ARM ARCHITECTURE,
and is maintained along with the rest of the vt8500 arch code.

Signed-off-by: Tony Prisk <[email protected]>
---
MAINTAINERS | 1 +
1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 3d7782b..5ab8ccb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1283,6 +1283,7 @@ M: Tony Prisk <[email protected]>
L: [email protected] (moderated for non-subscribers)
S: Maintained
F: arch/arm/mach-vt8500/
+F: drivers/clk/vt8500-vt8500.c
F: drivers/clocksource/vt8500_timer.c
F: drivers/gpio/gpio-vt8500.c
F: drivers/mmc/host/wmt-sdmmc.c
--
1.7.9.5

2013-05-17 21:18:58

by Tony Prisk

[permalink] [raw]
Subject: [PATCH 3/4] clk: vt8500: Remove unnecessary divisor adjustment in vtwm_dclk_set_rate()

The divisor adjustment code to ensure that a divisor is not rounded down,
thereby giving a rate higher than requested, is unnecessary and in some
instances results in the actual rate being much lower than requested due to
rounding errors.

The test is already performed in vtwm_dclk_round_rate(), which is always
called when clk_set_rate is called. Due to rounding errors in the line:
divisor = parent_rate / rate (clk-vt8500.c:160) we will sometimes end up
adjusting the divisor twice - first in round_rate and then again in set_rate.

This patch removes the test/adjustment in vtwm_dclk_set_rate.

Signed-off-by: Tony Prisk <[email protected]>
---
drivers/clk/clk-vt8500.c | 4 ----
1 file changed, 4 deletions(-)

diff --git a/drivers/clk/clk-vt8500.c b/drivers/clk/clk-vt8500.c
index ce401cf..82306f5 100644
--- a/drivers/clk/clk-vt8500.c
+++ b/drivers/clk/clk-vt8500.c
@@ -157,10 +157,6 @@ static int vt8500_dclk_set_rate(struct clk_hw *hw, unsigned long rate,

divisor = parent_rate / rate;

- /* If prate / rate would be decimal, incr the divisor */
- if (rate * divisor < parent_rate)
- divisor++;
-
if (divisor == cdev->div_mask + 1)
divisor = 0;

--
1.7.9.5

2013-05-17 21:18:57

by Tony Prisk

[permalink] [raw]
Subject: [PATCH 1/4] clk: vt8500: Fix unbalanced spinlock in vt8500_dclk_set_rate()

With the addition of a DVO clock, a bug is now evident in the vt8500
clock code:
[ 0.290000] WARNING: at init/main.c:698 do_one_initcall+0x158/0x18c()
[ 0.300000] initcall wm8505fb_driver_init+0x0/0xc returned with disabled int

This is caused by an unbalanced spinlock in vt8500_dclk_set_rate().
Replace the second call to spin_lock_irqsave() with spin_unlock_irqrestore().

Signed-off-by: Tony Prisk <[email protected]>
---
drivers/clk/clk-vt8500.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/clk-vt8500.c b/drivers/clk/clk-vt8500.c
index debf688..553ac35 100644
--- a/drivers/clk/clk-vt8500.c
+++ b/drivers/clk/clk-vt8500.c
@@ -183,7 +183,7 @@ static int vt8500_dclk_set_rate(struct clk_hw *hw, unsigned long rate,
writel(divisor, cdev->div_reg);
vt8500_pmc_wait_busy();

- spin_lock_irqsave(cdev->lock, flags);
+ spin_unlock_irqrestore(cdev->lock, flags);

return 0;
}
--
1.7.9.5

2013-05-17 21:20:41

by Tony Prisk

[permalink] [raw]
Subject: [PATCH 2/4] clk: vt8500: Add support for clocks on the WM8850 SoCs

The WM8850 has a different PLL clock to the previous versions. This
patch adds support for the WM8850-style PLL clocks.

Signed-off-by: Tony Prisk <[email protected]>
---
Documentation/devicetree/bindings/clock/vt8500.txt | 2 +
drivers/clk/clk-vt8500.c | 71 ++++++++++++++++++++
2 files changed, 73 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/vt8500.txt b/Documentation/devicetree/bindings/clock/vt8500.txt
index a880c70..91d71cc 100644
--- a/Documentation/devicetree/bindings/clock/vt8500.txt
+++ b/Documentation/devicetree/bindings/clock/vt8500.txt
@@ -8,6 +8,8 @@ Required properties:
- compatible : shall be one of the following:
"via,vt8500-pll-clock" - for a VT8500/WM8505 PLL clock
"wm,wm8650-pll-clock" - for a WM8650 PLL clock
+ "wm,wm8750-pll-clock" - for a WM8750 PLL clock
+ "wm,wm8850-pll-clock" - for a WM8850 PLL clock
"via,vt8500-device-clock" - for a VT/WM device clock

Required properties for PLL clocks:
diff --git a/drivers/clk/clk-vt8500.c b/drivers/clk/clk-vt8500.c
index 553ac35..ce401cf 100644
--- a/drivers/clk/clk-vt8500.c
+++ b/drivers/clk/clk-vt8500.c
@@ -42,6 +42,7 @@ struct clk_device {
#define PLL_TYPE_VT8500 0
#define PLL_TYPE_WM8650 1
#define PLL_TYPE_WM8750 2
+#define PLL_TYPE_WM8850 3

struct clk_pll {
struct clk_hw hw;
@@ -327,6 +328,15 @@ CLK_OF_DECLARE(vt8500_device, "via,vt8500-device-clock", vtwm_device_clk_init);
#define WM8750_BITS_TO_VAL(f, m, d1, d2) \
((f << 24) | ((m - 1) << 16) | ((d1 - 1) << 8) | d2)

+/* Helper macros for PLL_WM8850 */
+#define WM8850_PLL_MUL(x) ((((x >> 16) & 0x7F) + 1) * 2)
+#define WM8850_PLL_DIV(x) ((((x >> 8) & 1) + 1) * (1 << (x & 3)))
+
+#define WM8850_BITS_TO_FREQ(r, m, d1, d2) \
+ (r * ((m + 1) * 2) / ((d1+1) * (1 << d2)))
+
+#define WM8850_BITS_TO_VAL(m, d1, d2) \
+ ((((m / 2) - 1) << 16) | ((d1 - 1) << 8) | d2)

static void vt8500_find_pll_bits(unsigned long rate, unsigned long parent_rate,
u32 *multiplier, u32 *prediv)
@@ -466,6 +476,49 @@ static void wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate,
*divisor2 = best_div2;
}

+static void wm8850_find_pll_bits(unsigned long rate, unsigned long parent_rate,
+ u32 *multiplier, u32 *divisor1, u32 *divisor2)
+{
+ u32 mul, div1, div2;
+ u32 best_mul, best_div1, best_div2;
+ unsigned long tclk, rate_err, best_err;
+
+ best_err = (unsigned long)-1;
+
+ /* Find the closest match (lower or equal to requested) */
+ for (div1 = 1; div1 >= 0; div1--)
+ for (div2 = 3; div2 >= 0; div2--)
+ for (mul = 0; mul <= 127; mul++) {
+ tclk = parent_rate * ((mul + 1) * 2) /
+ ((div1 + 1) * (1 << div2));
+ if (tclk > rate)
+ continue;
+ /* error will always be +ve */
+ rate_err = rate - tclk;
+ if (rate_err == 0) {
+ *multiplier = mul;
+ *divisor1 = div1;
+ *divisor2 = div2;
+ return;
+ }
+
+ if (rate_err < best_err) {
+ best_err = rate_err;
+ best_mul = mul;
+ best_div1 = div1;
+ best_div2 = div2;
+ }
+ }
+
+ /* if we got here, it wasn't an exact match */
+ pr_warn("%s: requested rate %lu, found rate %lu\n", __func__, rate,
+ rate - best_err);
+
+ *multiplier = best_mul;
+ *divisor1 = best_div1;
+ *divisor2 = best_div2;
+}
+
static int vtwm_pll_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
@@ -489,6 +542,10 @@ static int vtwm_pll_set_rate(struct clk_hw *hw, unsigned long rate,
wm8750_find_pll_bits(rate, parent_rate, &filter, &mul, &div1, &div2);
pll_val = WM8750_BITS_TO_VAL(filter, mul, div1, div2);
break;
+ case PLL_TYPE_WM8850:
+ wm8850_find_pll_bits(rate, parent_rate, &mul, &div1, &div2);
+ pll_val = WM8850_BITS_TO_VAL(mul, div1, div2);
+ break;
default:
pr_err("%s: invalid pll type\n", __func__);
return 0;
@@ -525,6 +582,10 @@ static long vtwm_pll_round_rate(struct clk_hw *hw, unsigned long rate,
wm8750_find_pll_bits(rate, *prate, &filter, &mul, &div1, &div2);
round_rate = WM8750_BITS_TO_FREQ(*prate, mul, div1, div2);
break;
+ case PLL_TYPE_WM8850:
+ wm8850_find_pll_bits(rate, *prate, &mul, &div1, &div2);
+ round_rate = WM8850_BITS_TO_FREQ(*prate, mul, div1, div2);
+ break;
default:
round_rate = 0;
}
@@ -552,6 +613,10 @@ static unsigned long vtwm_pll_recalc_rate(struct clk_hw *hw,
pll_freq = parent_rate * WM8750_PLL_MUL(pll_val);
pll_freq /= WM8750_PLL_DIV(pll_val);
break;
+ case PLL_TYPE_WM8850:
+ pll_freq = parent_rate * WM8850_PLL_MUL(pll_val);
+ pll_freq /= WM8850_PLL_DIV(pll_val);
+ break;
default:
pll_freq = 0;
}
@@ -628,6 +693,12 @@ static void __init wm8750_pll_init(struct device_node *node)
}
CLK_OF_DECLARE(wm8750_pll, "wm,wm8750-pll-clock", wm8750_pll_init);

+static void __init wm8850_pll_init(struct device_node *node)
+{
+ vtwm_pll_clk_init(node, PLL_TYPE_WM8850);
+}
+CLK_OF_DECLARE(wm8850_pll, "wm,wm8850-pll-clock", wm8850_pll_init);
+
void __init vtwm_clk_init(void __iomem *base)
{
if (!base)
--
1.7.9.5

2013-05-18 08:30:23

by Tony Prisk

[permalink] [raw]
Subject: Re: [PATCH 4/4] MAINTAINERS: vt8500: Add clk-vt8500.c to MAINTAINERS file

On 18/05/13 18:40, Alexey Charkov wrote:
> On 18 May 2013 01:18, "Tony Prisk" <[email protected]> wrote:
>> This file has missed being added under ARM/VT8500 ARM ARCHITECTURE,
>> and is maintained along with the rest of the vt8500 arch code.
>>
>> Signed-off-by: Tony Prisk <[email protected]>
>> ---
>> MAINTAINERS | 1 +
>> 1 file changed, 1 insertion(+)
>>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index 3d7782b..5ab8ccb 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -1283,6 +1283,7 @@ M: Tony Prisk <[email protected]>
>> L: [email protected] (moderated for
> non-subscribers)
>> S: Maintained
>> F: arch/arm/mach-vt8500/
>> +F: drivers/clk/vt8500-vt8500.c
> This looks like a typo (clk vs. vt8500).
>
> Best,
> Alexey
>
eeek - oops.

Mike,

Disregard this patch - I will send a more complete one through arm-soc
as there are other files missing as well.

Regards
Tony P

2013-05-29 23:17:01

by Mike Turquette

[permalink] [raw]
Subject: Re: [PATCH 4/4] MAINTAINERS: vt8500: Add clk-vt8500.c to MAINTAINERS file

Quoting Tony Prisk (2013-05-18 01:30:21)
> On 18/05/13 18:40, Alexey Charkov wrote:
> > On 18 May 2013 01:18, "Tony Prisk" <[email protected]> wrote:
> >> This file has missed being added under ARM/VT8500 ARM ARCHITECTURE,
> >> and is maintained along with the rest of the vt8500 arch code.
> >>
> >> Signed-off-by: Tony Prisk <[email protected]>
> >> ---
> >> MAINTAINERS | 1 +
> >> 1 file changed, 1 insertion(+)
> >>
> >> diff --git a/MAINTAINERS b/MAINTAINERS
> >> index 3d7782b..5ab8ccb 100644
> >> --- a/MAINTAINERS
> >> +++ b/MAINTAINERS
> >> @@ -1283,6 +1283,7 @@ M: Tony Prisk <[email protected]>
> >> L: [email protected] (moderated for
> > non-subscribers)
> >> S: Maintained
> >> F: arch/arm/mach-vt8500/
> >> +F: drivers/clk/vt8500-vt8500.c
> > This looks like a typo (clk vs. vt8500).
> >
> > Best,
> > Alexey
> >
> eeek - oops.
>
> Mike,
>
> Disregard this patch - I will send a more complete one through arm-soc
> as there are other files missing as well.
>

Hi Tony,

I've taken patch #1 into clk-fixes. I took patches #2 & #3 into
clk-next from your previous series posted on May 13, which appear
identical to the ones in this series. In the future could you put a
"v2" in the patch subject since those patches were re-posted? It would
have helped me catch it.

I have not taken patch #4.

Does this all sound correct to you?

Thanks,
Mike

> Regards
> Tony P

2013-05-30 06:09:58

by Tony Prisk

[permalink] [raw]
Subject: Re: [PATCH 4/4] MAINTAINERS: vt8500: Add clk-vt8500.c to MAINTAINERS file

On 30/05/13 11:16, Mike Turquette wrote:
> Quoting Tony Prisk (2013-05-18 01:30:21)
>> On 18/05/13 18:40, Alexey Charkov wrote:
>>> On 18 May 2013 01:18, "Tony Prisk" <[email protected]> wrote:
>>>> This file has missed being added under ARM/VT8500 ARM ARCHITECTURE,
>>>> and is maintained along with the rest of the vt8500 arch code.
>>>>
>>>> Signed-off-by: Tony Prisk <[email protected]>
>>>> ---
>>>> MAINTAINERS | 1 +
>>>> 1 file changed, 1 insertion(+)
>>>>
>>>> diff --git a/MAINTAINERS b/MAINTAINERS
>>>> index 3d7782b..5ab8ccb 100644
>>>> --- a/MAINTAINERS
>>>> +++ b/MAINTAINERS
>>>> @@ -1283,6 +1283,7 @@ M: Tony Prisk <[email protected]>
>>>> L: [email protected] (moderated for
>>> non-subscribers)
>>>> S: Maintained
>>>> F: arch/arm/mach-vt8500/
>>>> +F: drivers/clk/vt8500-vt8500.c
>>> This looks like a typo (clk vs. vt8500).
>>>
>>> Best,
>>> Alexey
>>>
>> eeek - oops.
>>
>> Mike,
>>
>> Disregard this patch - I will send a more complete one through arm-soc
>> as there are other files missing as well.
>>
> Hi Tony,
>
> I've taken patch #1 into clk-fixes. I took patches #2 & #3 into
> clk-next from your previous series posted on May 13, which appear
> identical to the ones in this series. In the future could you put a
> "v2" in the patch subject since those patches were re-posted? It would
> have helped me catch it.
>
> I have not taken patch #4.
>
> Does this all sound correct to you?
>
> Thanks,
> Mike
>
>> Regards
>> Tony P
Perfect - Thanks Mike

Regards
Tony P