ca70b9ddbf0dd7de2f41a10f1021aa1c2fdad1ed
[oweals/openwrt.git] /
1 From bf85b92a97a95161d98874571c520fb1395c5aa2 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 @@ -1097,15 +1097,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 @@ -1475,7 +1479,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.