From 704690d968a5f1cde04d15ad6c2b8410d7933461 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 2 May 2019 15:11:05 -0700 Subject: [PATCH] clk: bcm2835: Add support for setting leaf clock rates while running. As long as you wait for !BUSY, you can do glitch-free updates of clock rate while the clock is running. Signed-off-by: Eric Anholt --- drivers/clk/bcm/clk-bcm2835.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -1138,15 +1138,19 @@ static int bcm2835_clock_set_rate(struct spin_lock(&cprman->regs_lock); - /* - * Setting up frac support - * - * In principle it is recommended to stop/start the clock first, - * but as we set CLK_SET_RATE_GATE during registration of the - * clock this requirement should be take care of by the - * clk-framework. + ctl = cprman_read(cprman, data->ctl_reg); + + /* If the clock is running, we have to pause clock generation while + * updating the control and div regs. This is glitchless (no clock + * signals generated faster than the rate) but each reg access is two + * OSC cycles so the clock will slow down for a moment. */ - ctl = cprman_read(cprman, data->ctl_reg) & ~CM_FRAC; + if (ctl & CM_ENABLE) { + cprman_write(cprman, data->ctl_reg, ctl & ~CM_ENABLE); + bcm2835_clock_wait_busy(clock); + } + + ctl &= ~CM_FRAC; ctl |= (div & CM_DIV_FRAC_MASK) ? CM_FRAC : 0; cprman_write(cprman, data->ctl_reg, ctl); @@ -1522,7 +1526,7 @@ static struct clk_hw *bcm2835_register_c init.ops = &bcm2835_vpu_clock_clk_ops; } else { init.ops = &bcm2835_clock_clk_ops; - init.flags |= CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE; + init.flags |= CLK_SET_PARENT_GATE; /* If the clock wasn't actually enabled at boot, it's not * critical.