On Thu, 18 Jul 2024 22:42:52 +0200 Michael Walle <mwa...@kernel.org> wrote:
Hi, > The CDR2 divider calculation always yield a frequency greater than the > requested one. Use DIV_ROUND_UP() to keep the frequency equal or below > the requested one. This way, we can also drop the "if div > 0" check > because we know for a fact that div cannot be zero. > > FWIW, this aligns the CDR2 calculation with the linux driver. Thanks, that looks alright now. I tested some corner cases, and it seems to do the right thing (TM) now. > Suggested-by: Andre Przywara <andre.przyw...@arm.com> > Signed-off-by: Michael Walle <mwa...@kernel.org> Reviewed-by: Andre Przywara <andre.przyw...@arm.com> Applied to sunxi/master. Cheers, Andre. > --- > drivers/spi/spi-sunxi.c | 11 ++++------- > 1 file changed, 4 insertions(+), 7 deletions(-) > > diff --git a/drivers/spi/spi-sunxi.c b/drivers/spi/spi-sunxi.c > index bfb402902b8..f110a8b7658 100644 > --- a/drivers/spi/spi-sunxi.c > +++ b/drivers/spi/spi-sunxi.c > @@ -233,7 +233,7 @@ err_ahb: > static void sun4i_spi_set_speed_mode(struct udevice *dev) > { > struct sun4i_spi_priv *priv = dev_get_priv(dev); > - unsigned int div; > + unsigned int div, div_cdr2; > u32 reg; > > /* > @@ -259,15 +259,12 @@ static void sun4i_spi_set_speed_mode(struct udevice > *dev) > */ > > div = DIV_ROUND_UP(SUNXI_INPUT_CLOCK, priv->freq); > + div_cdr2 = DIV_ROUND_UP(div, 2); > reg = readl(SPI_REG(priv, SPI_CCR)); > > - if ((div / 2) <= (SUN4I_CLK_CTL_CDR2_MASK + 1)) { > - div /= 2; > - if (div > 0) > - div--; > - > + if (div_cdr2 <= (SUN4I_CLK_CTL_CDR2_MASK + 1)) { > reg &= ~(SUN4I_CLK_CTL_CDR2_MASK | SUN4I_CLK_CTL_DRS); > - reg |= SUN4I_CLK_CTL_CDR2(div) | SUN4I_CLK_CTL_DRS; > + reg |= SUN4I_CLK_CTL_CDR2(div_cdr2 - 1) | SUN4I_CLK_CTL_DRS; > } else { > div = fls(div - 1); > /* The F1C100s encodes the divider as 2^(n+1) */