[coreboot-gerrit] New patch to review for coreboot: eaa6a04 tegra124: change PLLD VCO calculation algorithm

Marc Jones (marc.jones@se-eng.com) gerrit at coreboot.org
Wed Dec 10 04:20:31 CET 2014


Marc Jones (marc.jones at se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/7773

-gerrit

commit eaa6a04ca35b420a2a4dd187e5d955b093f81698
Author: Ken Chang <kenc at nvidia.com>
Date:   Fri Apr 18 13:52:48 2014 +0800

    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 at nvidia.com>
    Original-Reviewed-on: https://chromium-review.googlesource.com/195534
    Original-Reviewed-by: Hung-Te Lin <hungte at chromium.org>
    (cherry picked from commit 1b56566786aa86c14f691fa3858b878f27b6b4de)
    Signed-off-by: Marc Jones <marc.jones at se-eng.com>
    
    Change-Id: Ia9de93420e60323f143a42db842febdd3706fe44
---
 src/soc/nvidia/tegra124/clock.c   | 23 +++++++++++++++--------
 src/soc/nvidia/tegra124/display.c |  4 ++--
 2 files changed, 17 insertions(+), 10 deletions(-)

diff --git a/src/soc/nvidia/tegra124/clock.c b/src/soc/nvidia/tegra124/clock.c
index eed5116..c5b06f4 100644
--- a/src/soc/nvidia/tegra124/clock.c
+++ b/src/soc/nvidia/tegra124/clock.c
@@ -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)
diff --git a/src/soc/nvidia/tegra124/display.c b/src/soc/nvidia/tegra124/display.c
index 33769ba..87472ef 100644
--- a/src/soc/nvidia/tegra124/display.c
+++ b/src/soc/nvidia/tegra124/display.c
@@ -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);



More information about the coreboot-gerrit mailing list