brcm2708: update linux 4.4 patches to latest version
[openwrt/staging/lynxis/omap.git] / target / linux / brcm2708 / patches-4.4 / 0256-clk-bcm2835-correctly-enable-fractional-clock-suppor.patch
1 From 7182f4321e85d4911762f7dd2b38e6e1a7919073 Mon Sep 17 00:00:00 2001
2 From: Martin Sperl <kernel@martin.sperl.org>
3 Date: Mon, 29 Feb 2016 11:39:21 +0000
4 Subject: [PATCH 256/423] clk: bcm2835: correctly enable fractional clock
5 support
6
7 The current driver calculates the clock divider with
8 fractional support enabled.
9
10 But it does not enable fractional support in the
11 control register itself resulting in an integer only divider,
12 but in clk_set_rate responds back the fractionally divided
13 clock frequency.
14
15 This patch enables fractional support in the control register
16 whenever there is a fractional bit set in the requested clock divider.
17
18 Mash clock limits are are also handled for the PWM clock
19 applying the correct divider limits (2 and max_int) applicable to
20 basic fractional divider support (mash order of 1).
21
22 It also adds locking to protect the read/modify/write cycle of
23 the register modification.
24
25 Fixes: 41691b8862e2 ("clk: bcm2835: Add support for programming the
26 audio domain clocks")
27
28 Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
29 Signed-off-by: Eric Anholt <eric@anholt.net>
30 Reviewed-by: Eric Anholt <eric@anholt.net>
31 (cherry picked from commit 959ca92a3235fc4b17c1e18483fc390b3d612254)
32 ---
33 drivers/clk/bcm/clk-bcm2835.c | 45 +++++++++++++++++++++++++++++++++++++------
34 1 file changed, 39 insertions(+), 6 deletions(-)
35
36 --- a/drivers/clk/bcm/clk-bcm2835.c
37 +++ b/drivers/clk/bcm/clk-bcm2835.c
38 @@ -51,6 +51,7 @@
39 #define CM_GNRICCTL 0x000
40 #define CM_GNRICDIV 0x004
41 # define CM_DIV_FRAC_BITS 12
42 +# define CM_DIV_FRAC_MASK GENMASK(CM_DIV_FRAC_BITS - 1, 0)
43
44 #define CM_VPUCTL 0x008
45 #define CM_VPUDIV 0x00c
46 @@ -128,6 +129,7 @@
47 # define CM_GATE BIT(CM_GATE_BIT)
48 # define CM_BUSY BIT(7)
49 # define CM_BUSYD BIT(8)
50 +# define CM_FRAC BIT(9)
51 # define CM_SRC_SHIFT 0
52 # define CM_SRC_BITS 4
53 # define CM_SRC_MASK 0xf
54 @@ -647,6 +649,7 @@ struct bcm2835_clock_data {
55 u32 frac_bits;
56
57 bool is_vpu_clock;
58 + bool is_mash_clock;
59 };
60
61 static const char *const bcm2835_clock_per_parents[] = {
62 @@ -828,6 +831,7 @@ static const struct bcm2835_clock_data b
63 .div_reg = CM_PWMDIV,
64 .int_bits = 12,
65 .frac_bits = 12,
66 + .is_mash_clock = true,
67 };
68
69 struct bcm2835_pll {
70 @@ -1196,7 +1200,7 @@ static u32 bcm2835_clock_choose_div(stru
71 GENMASK(CM_DIV_FRAC_BITS - data->frac_bits, 0) >> 1;
72 u64 temp = (u64)parent_rate << CM_DIV_FRAC_BITS;
73 u64 rem;
74 - u32 div;
75 + u32 div, mindiv, maxdiv;
76
77 rem = do_div(temp, rate);
78 div = temp;
79 @@ -1206,11 +1210,23 @@ static u32 bcm2835_clock_choose_div(stru
80 div += unused_frac_mask + 1;
81 div &= ~unused_frac_mask;
82
83 - /* clamp to min divider of 1 */
84 - div = max_t(u32, div, 1 << CM_DIV_FRAC_BITS);
85 - /* clamp to the highest possible fractional divider */
86 - div = min_t(u32, div, GENMASK(data->int_bits + CM_DIV_FRAC_BITS - 1,
87 - CM_DIV_FRAC_BITS - data->frac_bits));
88 + /* different clamping limits apply for a mash clock */
89 + if (data->is_mash_clock) {
90 + /* clamp to min divider of 2 */
91 + mindiv = 2 << CM_DIV_FRAC_BITS;
92 + /* clamp to the highest possible integer divider */
93 + maxdiv = (BIT(data->int_bits) - 1) << CM_DIV_FRAC_BITS;
94 + } else {
95 + /* clamp to min divider of 1 */
96 + mindiv = 1 << CM_DIV_FRAC_BITS;
97 + /* clamp to the highest possible fractional divider */
98 + maxdiv = GENMASK(data->int_bits + CM_DIV_FRAC_BITS - 1,
99 + CM_DIV_FRAC_BITS - data->frac_bits);
100 + }
101 +
102 + /* apply the clamping limits */
103 + div = max_t(u32, div, mindiv);
104 + div = min_t(u32, div, maxdiv);
105
106 return div;
107 }
108 @@ -1304,9 +1320,26 @@ static int bcm2835_clock_set_rate(struct
109 struct bcm2835_cprman *cprman = clock->cprman;
110 const struct bcm2835_clock_data *data = clock->data;
111 u32 div = bcm2835_clock_choose_div(hw, rate, parent_rate, false);
112 + u32 ctl;
113 +
114 + spin_lock(&cprman->regs_lock);
115 +
116 + /*
117 + * Setting up frac support
118 + *
119 + * In principle it is recommended to stop/start the clock first,
120 + * but as we set CLK_SET_RATE_GATE during registration of the
121 + * clock this requirement should be take care of by the
122 + * clk-framework.
123 + */
124 + ctl = cprman_read(cprman, data->ctl_reg) & ~CM_FRAC;
125 + ctl |= (div & CM_DIV_FRAC_MASK) ? CM_FRAC : 0;
126 + cprman_write(cprman, data->ctl_reg, ctl);
127
128 cprman_write(cprman, data->div_reg, div);
129
130 + spin_unlock(&cprman->regs_lock);
131 +
132 return 0;
133 }
134