diff --git a/drivers/clk/clk-eyeq.c b/drivers/clk/clk-eyeq.c index 5166b65382a9..11df9f167b59 100644 --- a/drivers/clk/clk-eyeq.c +++ b/drivers/clk/clk-eyeq.c @@ -163,7 +163,7 @@ static void eqc_pll_downshift_factors(unsigned long *mult, unsigned long *div) static int eqc_pll_parse_registers(u32 r0, u32 r1, unsigned long *mult, unsigned long *div, unsigned long *acc) { - u32 spread; + unsigned long spread; if (r0 & PCSR0_BYPASS) { *mult = 1; @@ -195,23 +195,23 @@ static int eqc_pll_parse_registers(u32 r0, u32 r1, unsigned long *mult, /* * Spread spectrum. * - * Spread is 1/1000 parts of frequency, accuracy is half of - * that. To get accuracy, convert to ppb (parts per billion). + * Spread is in 1/1024 parts of frequency. Clock accuracy + * is half the spread value expressed in parts per billion. * - * acc = spread * 1e6 / 2 - * with acc in parts per billion and, - * spread in parts per thousand. + * accuracy = (spread * 1e9) / (1024 * 2) + * + * Care is taken to avoid overflowing or losing precision. */ spread = FIELD_GET(PCSR1_SPREAD, r1); - *acc = spread * 500000; + *acc = DIV_ROUND_CLOSEST(spread * 1000000000, 1024 * 2); if (r1 & PCSR1_DOWN_SPREAD) { /* * Downspreading: the central frequency is half a * spread lower. */ - *mult *= 2000 - spread; - *div *= 2000; + *mult *= 2048 - spread; + *div *= 2048; /* * Previous operation might overflow 32 bits. If it