From: Eric Anholt Date: Thu, 2 May 2019 22:11:05 +0000 (-0700) Subject: clk: bcm2835: Add support for setting leaf clock rates while running. X-Git-Tag: accepted/tizen/unified/20210330.111217~720 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c4d5ef6f698c35fa3b95862de11dd6018b74626a;p=platform%2Fkernel%2Flinux-rpi.git 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 --- diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index 38f97f1..4cf4f5e 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -1115,15 +1115,19 @@ static int bcm2835_clock_set_rate(struct clk_hw *hw, 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); @@ -1499,7 +1503,7 @@ static struct clk_hw *bcm2835_register_clock(struct bcm2835_cprman *cprman, 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.