[U-Boot] PATCH: mpc8xx PLPRCR (init_pll_866)

Signed-off-by: Spencer Putt Raytheon Company
The current init_pll_866 makes a bad assumption for the oscillator. A board with a slower oscillator may lead to PLPRCR fields overflowing their bounds and making the board not boot. This patch should more accurately set the PLPRCR regardless of the oscillator, and will increase the probability a board will boot by doing some bounds checking.
--- cpu_mpc8xx_speed.c 2008-10-16 15:37:10.000000000 -0400 +++ speed.c 2008-10-16 15:35:44.000000000 -0400 @@ -313,56 +313,60 @@ } /* Configure PLL for MPC866/859/885 CPU series - * PLL multiplication factor is set to the value nearest to the desired clk, - * assuming a oscclk of 10 MHz. + * PLL multiplication factor is set to the value nearest to the desired clk + * If the clk is unattainable, it is set to the highest possible, OSCLK*16 */ static long init_pll_866 (long clk) { extern void plprcr_write_866 (long); volatile immap_t *immr = (immap_t *) CFG_IMMR; - long n, plprcr; - char mfi, mfn, mfd, s, pdf; - long step_mfi, step_mfn; - - if (clk < 20000000) { - clk *= 2; - pdf = 1; - } else { - pdf = 0; - } + long n, plprcr, mfi; + char mfn, mfd, s; + long pdf = -1; + long step_mfi, step_mfn; + +/* The goal is to make (mfi / pdf) * (OSCLK >> s) = clk + * + * Generally having s as high as possible is desired. + * This is because the final resolution depends on the + * the OSCLK freq >> s. So let's see how we can manipulate + * the predivision factor (pdf) to allow s to be as large + * as possible. + */ + s = 2; + mfi = clk / (CONFIG_8xx_OSCLK / 4); - if (clk < 40000000) { - s = 2; - step_mfi = CONFIG_8xx_OSCLK / 4; - mfd = 7; - step_mfn = CONFIG_8xx_OSCLK / 30; - } else if (clk < 80000000) { + if (mfi > 16 * 2) { + s = 0; + } else if (mfi > 16) { s = 1; - step_mfi = CONFIG_8xx_OSCLK / 2; - mfd = 14; - step_mfn = CONFIG_8xx_OSCLK / 30; + } + + /* Modify pdf until mfi is in range (5 to 15) */ + do { + step_mfi = (CONFIG_8xx_OSCLK >> s) / (++pdf + 1); + mfi = clk / step_mfi; + } while (mfi < 5 && pdf < 16); + + /* Set the denominator to 32 */ + mfd = 31; + step_mfn = step_mfi / (mfd + 1); + + /* Check mfi's range (the frequency may be unattainable) */ + if (mfi > 15) { + /* FIXME: possibly warn the user */ + mfi = 15; + mfn = 31; } else { - s = 0; - step_mfi = CONFIG_8xx_OSCLK; - mfd = 29; - step_mfn = CONFIG_8xx_OSCLK / 30; + /* Find the numerator (n/32) */ + mfn = (clk - (mfi * step_mfi)) / step_mfn; } - /* Calculate integer part of multiplication factor - */ - n = clk / step_mfi; - mfi = (char)n; - - /* Calculate numerator of fractional part of multiplication factor - */ - n = clk - (n * step_mfi); - mfn = (char)(n / step_mfn); - - /* Calculate effective clk - */ - n = ((mfi * step_mfi) + (mfn * step_mfn)) / (pdf + 1); + /* Calculate effective clock */ + n = (mfi * step_mfi) + (mfn * step_mfn); + /* Unlock the PLPRCR */ immr->im_clkrstk.cark_plprcrk = KAPWR_KEY; plprcr = (immr->im_clkrst.car_plprcr & ~(PLPRCR_MFN_MSK @@ -379,6 +383,7 @@ plprcr |= PLPRCR_DBRMO; plprcr_write_866 (plprcr); /* set value using SIU4/9 workaround */ + immr->im_clkrstk.cark_plprcrk = 0x00000000; return (n);

Dear Spencer Putt,
In message OF804207B5.958BB343-ON86257506.0064304D-86257506.00643054@mck.us.ray.com you wrote:
Signed-off-by: Spencer Putt Raytheon Company
The current init_pll_866 makes a bad assumption for the oscillator. A board with a slower oscillator may lead to PLPRCR fields overflowing their bounds and making the board not boot. This patch should more accurately set the PLPRCR regardless of the oscillator, and will increase the probability a board will boot by doing some bounds checking.
--- cpu_mpc8xx_speed.c 2008-10-16 15:37:10.000000000 -0400 +++ speed.c 2008-10-16 15:35:44.000000000 -0400 @@ -313,56 +313,60 @@ } /* Configure PLL for MPC866/859/885 CPU series
- PLL multiplication factor is set to the value nearest to the desired
clk,
- assuming a oscclk of 10 MHz.
- PLL multiplication factor is set to the value nearest to the desired
clk
- If the clk is unattainable, it is set to the highest possible, OSCLK*16
*/ static long init_pll_866 (long clk) { extern void plprcr_write_866 (long); volatile immap_t *immr = (immap_t *) CFG_IMMR;
- long n, plprcr;
- char mfi, mfn, mfd, s, pdf;
- long step_mfi, step_mfn;
- if (clk < 20000000) {
- clk *= 2;
- pdf = 1;
- } else {
- pdf = 0;
- }
Your patch is completely white-space corrupted, probably by your Lotus mailer.
Please retry sending after fixing your mail configuration. It is best when you use git-format-patch to create the patch and git-send-email to send it.
Best regards,
Wolfgang Denk
participants (2)
-
Spencer Putt
-
Wolfgang Denk