[coreboot-gerrit] Patch set updated for coreboot: 29c95d5 tegra124: Allow "best" PLLD parameters for unmatched pixel clock.

Patrick Georgi (pgeorgi@google.com) gerrit at coreboot.org
Mon Dec 15 23:18:00 CET 2014


Patrick Georgi (pgeorgi at google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/7771

-gerrit

commit 29c95d5d24737d734a9050c034642be710c14d7b
Author: Hung-Te Lin <hungte at chromium.org>
Date:   Thu Apr 17 08:20:04 2014 +0800

    tegra124: Allow "best" PLLD parameters for unmatched pixel clock.
    
    The pixel clock for some panel (ex: CMN N116BGE-EA2: 76420000) cannot be matched
    by our PLLD params finding algorithm, after VCO/CF limitations are applied.
    
    To support these panels, we want to allow "best matched" params.
    
    BRANCH=nyan
    BUG=none
    TEST=emerge-nyan_big coreboot chromeos-bootimage;
         emerge-nyan coreboot chromeos-bootimage;
         # Successfully brings up display on Nyan_Big EVT2 and Nyan Norrin.
    
    Original-Change-Id: If8143c2062abd2f843c07698ea55cab47bf1e41a
    Original-Signed-off-by: Hung-Te Lin <hungte at chromium.org>
    Original-Reviewed-on: https://chromium-review.googlesource.com/195327
    Original-Reviewed-by: Julius Werner <jwerner at chromium.org>
    (cherry picked from commit 8aa66e659e3c60296f05e59b4343496a850ea019)
    Signed-off-by: Marc Jones <marc.jones at se-eng.com>
    
    Change-Id: I623db44de35fecee5539e4d72f93f28b5fa0b59c
---
 src/soc/nvidia/tegra124/clock.c | 68 ++++++++++++++++++++++++-----------------
 1 file changed, 40 insertions(+), 28 deletions(-)

diff --git a/src/soc/nvidia/tegra124/clock.c b/src/soc/nvidia/tegra124/clock.c
index 765e447..eed5116 100644
--- a/src/soc/nvidia/tegra124/clock.c
+++ b/src/soc/nvidia/tegra124/clock.c
@@ -304,18 +304,17 @@ clock_display(u32 frequency)
 	 *           = (cf * n) >> p, where 1MHz < cf < 6MHz
 	 *           = ((ref / m) * n) >> p
 	 *
-	 * Assume p = 0, find (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.
+	 * Assume p = 0, 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.
 	 *
 	 * Note values undershoot or overshoot target output frequency may not
-	 * work if the value is not in "safe" range in panel specification, so
-	 * we want exact match.
+	 * 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,
 		  min_cf = 1 * mhz, max_cf = 6 * mhz;
@@ -326,40 +325,53 @@ clock_display(u32 frequency)
 		return -1;
 	}
 
-	for (m = 1; m < max_m; m++) {
+	for (m = 1; m < max_m && best_diff; m++) {
 		cf = ref / m;
 		if (cf < min_cf)
 			break;
+		if (cf > max_cf)
+			continue;
 
 		n = vco / cf;
-		if (vco != cf * n || n >= max_n || cf > max_cf)
+		if (n >= max_n)
+			continue;
+
+		diff = vco - n * cf;
+		if (n + 1 < max_n && diff > cf / 2) {
+			n++;
+			diff = cf - diff;
+		}
+
+		if (diff >= best_diff)
 			continue;
 
+		best_diff = diff;
 		plld.m = m;
 		plld.n = n;
+	}
+
+	if (plld.n < 50)
+		plld.cpcon = 2;
+	else if (plld.n < 300)
+		plld.cpcon = 3;
+	else if (plld.n < 600)
+		plld.cpcon = 8;
+	else
+		plld.cpcon = 12;
 
-		if (n < 50)
-			plld.cpcon = 2;
-		else if (n < 300)
-			plld.cpcon = 3;
-		else if (n < 600)
-			plld.cpcon = 8;
-		else
-			plld.cpcon = 12;
-
-		printk(BIOS_DEBUG, "%s: PLLD=%u ref=%u, m/n/p/cpcon="
-		       "%u/%u/%u/%u\n", __func__,
-		       (ref / plld.m * plld.n) >> plld.p, ref,
-		       plld.m, plld.n, plld.p, plld.cpcon);
-
-		init_pll(&clk_rst->plld_base, &clk_rst->plld_misc, plld,
-			 (PLLUD_MISC_LOCK_ENABLE | PLLD_MISC_CLK_ENABLE));
-		return 0;
+	if (best_diff) {
+		printk(BIOS_ERR, "%s: Failed to match output frequency %u, "
+		       "best difference is %u.\n", __func__, frequency,
+		       best_diff);
 	}
 
-	printk(BIOS_ERR, "%s: Failed to match output frequency %u.\n",
-	       __func__, frequency);
-	return -1;
+	printk(BIOS_DEBUG, "%s: PLLD=%u ref=%u, m/n/p/cpcon=%u/%u/%u/%u\n",
+	       __func__, (ref / plld.m * plld.n) >> plld.p, ref, plld.m, plld.n,
+	       plld.p, plld.cpcon);
+
+	init_pll(&clk_rst->plld_base, &clk_rst->plld_misc, plld,
+		 (PLLUD_MISC_LOCK_ENABLE | PLLD_MISC_CLK_ENABLE));
+	return 0;
 }
 
 /* Initialize the UART and put it on CLK_M so we can use it during clock_init().



More information about the coreboot-gerrit mailing list