26b17393d9917fceabfb9693954c4c9ba5e21a6a
[openwrt/staging/thess.git] /
1 From cfe0832e8306cd9955f682b7314a5a6fc3b9d514 Mon Sep 17 00:00:00 2001
2 From: Eric Anholt <eric@anholt.net>
3 Date: Thu, 2 May 2019 15:11:05 -0700
4 Subject: [PATCH] clk: bcm2835: Add support for setting leaf clock
5 rates while running.
6
7 As long as you wait for !BUSY, you can do glitch-free updates of clock
8 rate while the clock is running.
9
10 Signed-off-by: Eric Anholt <eric@anholt.net>
11 ---
12 drivers/clk/bcm/clk-bcm2835.c | 22 +++++++++++++---------
13 1 file changed, 13 insertions(+), 9 deletions(-)
14
15 --- a/drivers/clk/bcm/clk-bcm2835.c
16 +++ b/drivers/clk/bcm/clk-bcm2835.c
17 @@ -1114,15 +1114,19 @@ static int bcm2835_clock_set_rate(struct
18
19 spin_lock(&cprman->regs_lock);
20
21 - /*
22 - * Setting up frac support
23 - *
24 - * In principle it is recommended to stop/start the clock first,
25 - * but as we set CLK_SET_RATE_GATE during registration of the
26 - * clock this requirement should be take care of by the
27 - * clk-framework.
28 + ctl = cprman_read(cprman, data->ctl_reg);
29 +
30 + /* If the clock is running, we have to pause clock generation while
31 + * updating the control and div regs. This is glitchless (no clock
32 + * signals generated faster than the rate) but each reg access is two
33 + * OSC cycles so the clock will slow down for a moment.
34 */
35 - ctl = cprman_read(cprman, data->ctl_reg) & ~CM_FRAC;
36 + if (ctl & CM_ENABLE) {
37 + cprman_write(cprman, data->ctl_reg, ctl & ~CM_ENABLE);
38 + bcm2835_clock_wait_busy(clock);
39 + }
40 +
41 + ctl &= ~CM_FRAC;
42 ctl |= (div & CM_DIV_FRAC_MASK) ? CM_FRAC : 0;
43 cprman_write(cprman, data->ctl_reg, ctl);
44
45 @@ -1492,7 +1496,7 @@ static struct clk_hw *bcm2835_register_c
46 init.ops = &bcm2835_vpu_clock_clk_ops;
47 } else {
48 init.ops = &bcm2835_clock_clk_ops;
49 - init.flags |= CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE;
50 + init.flags |= CLK_SET_PARENT_GATE;
51
52 /* If the clock wasn't actually enabled at boot, it's not
53 * critical.