tegra124: change PLLD VCO calculation algorithm
The current algo sets dc shift clock divider to 5 and PLLD DIVP to 0, this is causing VCO out of the characterized range for some panels. This CL changes the dc shift clock divider to 1 and calculates a proper DIVP to have the VCO inside the characterized range, i.e., 500MHz ~ 1000MHz. BRANCH=none BUG=none TEST=Verify on below panels the pixel clock frequencies are correct. 1. AUO B133XTN01.3 (69.5 MHz) pixelclk(MHz), pll_d(MHz), m/n/p without: 69.5 695 12/695/0 with: 69.5 139 3/139/2 2. AUO B140HTT01.0 (141 MHz) pixelclk(MHz), pll_d(MHz), m/n/p without: VCO (1410000000) out of range. Cannot support. with: 141 282 2/94/1 3. LG LP140WH8 (76.32 MHz) pixelclk(MHz), pll_d(MHz), m/n/p without: 76.32 763.2 5/381/0 with: 76.3125 152.625 8/407/2 4. N116BGE-EA2 (76.42 MHz) pixelclk(MHz), pll_d(MHz), m/n/p without: 76.40 764 3/191/0 with: 76.375 152.75 12/611/2 Original-Change-Id: Id4b3a4865acde37a97d7346ec88406f5237304eb Original-Signed-off-by: Ken Chang <kenc@nvidia.com> Original-Reviewed-on: https://chromium-review.googlesource.com/195534 Original-Reviewed-by: Hung-Te Lin <hungte@chromium.org> (cherry picked from commit 1b56566786aa86c14f691fa3858b878f27b6b4de) Signed-off-by: Marc Jones <marc.jones@se-eng.com> Change-Id: Ia9de93420e60323f143a42db842febdd3706fe44 Reviewed-on: http://review.coreboot.org/7773 Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org> Tested-by: build bot (Jenkins)
This commit is contained in:
@@ -304,7 +304,8 @@ clock_display(u32 frequency)
|
||||
* = (cf * n) >> p, where 1MHz < cf < 6MHz
|
||||
* = ((ref / m) * n) >> p
|
||||
*
|
||||
* Assume p = 0, find best (m, n). since m has only 5 bits, we can
|
||||
* Iterate the possible values of p (3 bits, 2^7) to find out a minimum
|
||||
* safe vco, then find best (m, n). since m has only 5 bits, we can
|
||||
* iterate all possible values. Note Tegra 124 supports 11 bits for n,
|
||||
* but our pll_fields has only 10 bits for n.
|
||||
*
|
||||
@@ -312,19 +313,25 @@ clock_display(u32 frequency)
|
||||
* work if the values are not in "safe" range by panel specification.
|
||||
*/
|
||||
struct pllpad_dividers plld = { 0 };
|
||||
u32 ref = clock_get_pll_input_khz() * 1000, m, n;
|
||||
u32 cf, vco = frequency;
|
||||
u32 diff, best_diff = vco;
|
||||
const u32 max_m = 1 << 5, max_n = 1 << 10, mhz = 1000 * 1000,
|
||||
min_vco = 500 * mhz, max_vco = 1000 * mhz,
|
||||
u32 ref = clock_get_pll_input_khz() * 1000, m, n, p = 0;
|
||||
u32 cf, vco;
|
||||
u32 diff, best_diff;
|
||||
const u32 max_m = 1 << 5, max_n = 1 << 10, max_p = 1 << 3,
|
||||
mhz = 1000 * 1000, min_vco = 500 * mhz, max_vco = 1000 * mhz,
|
||||
min_cf = 1 * mhz, max_cf = 6 * mhz;
|
||||
|
||||
for (vco = frequency; vco < min_vco && p < max_p; p++)
|
||||
vco <<= 1;
|
||||
|
||||
if (vco < min_vco || vco > max_vco) {
|
||||
printk(BIOS_ERR, "%s: VCO (%d) out of range. Cannot support.\n",
|
||||
__func__, vco);
|
||||
printk(BIOS_ERR, "%s: Cannot find out a supported VCO"
|
||||
" for Frequency (%u).\n", __func__, frequency);
|
||||
return -1;
|
||||
}
|
||||
|
||||
plld.p = p;
|
||||
best_diff = vco;
|
||||
|
||||
for (m = 1; m < max_m && best_diff; m++) {
|
||||
cf = ref / m;
|
||||
if (cf < min_cf)
|
||||
|
@@ -124,12 +124,12 @@ static int update_display_mode(struct display_controller *disp_ctrl,
|
||||
* Currently most panels work inside clock range 50MHz~100MHz, and PLLD
|
||||
* has some requirements to have VCO in range 500MHz~1000MHz (see
|
||||
* clock.c for more detail). To simplify calculation, we set
|
||||
* PixelClockDiv to 1 and ShiftClockDiv to 5. In future these values
|
||||
* PixelClockDiv to 1 and ShiftClockDiv to 1. In future these values
|
||||
* may be calculated by clock_display, to allow wider frequency range.
|
||||
*
|
||||
* Note ShiftClockDiv is a 7.1 format value.
|
||||
*/
|
||||
const u32 shift_clock_div = 5;
|
||||
const u32 shift_clock_div = 1;
|
||||
WRITEL((PIXEL_CLK_DIVIDER_PCD1 << PIXEL_CLK_DIVIDER_SHIFT) |
|
||||
((shift_clock_div - 1) * 2) << SHIFT_CLK_DIVIDER_SHIFT,
|
||||
&disp_ctrl->disp.disp_clk_ctrl);
|
||||
|
Reference in New Issue
Block a user