<p>Lin Huang has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/22468">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">rockchip/rk3399: mipi: correct Feedback divider setting<br><br>This patch correct Feedback divider setting:<br>1. Set Feedback divider [8:5] when HIGH_PROGRAM_EN<br>2. Due to the use of a "by 2 pre-scaler," the range of the<br>   feedback multiplication Feedback divider is limited to even<br>   division numbers, and Feedback divider must be greater than<br>   12, less than 1000.<br>3. Make the previously configured Feedback divider(LSB)<br>   factors effective<br><br>Change-Id: Ic7c5c59be1d00c65c3b17cb3c4bfba8d7459e960<br>Signed-off-by: Lin Huang <hl@rock-chips.com><br>---<br>M src/soc/rockchip/rk3399/include/soc/mipi.h<br>M src/soc/rockchip/rk3399/mipi.c<br>2 files changed, 68 insertions(+), 23 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/68/22468/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/src/soc/rockchip/rk3399/include/soc/mipi.h b/src/soc/rockchip/rk3399/include/soc/mipi.h<br>index 7dc6b14..d716717 100644<br>--- a/src/soc/rockchip/rk3399/include/soc/mipi.h<br>+++ b/src/soc/rockchip/rk3399/include/soc/mipi.h<br>@@ -209,7 +209,7 @@<br> #define LOW_PROGRAM_EN             0<br> #define HIGH_PROGRAM_EN             BIT(7)<br> #define LOOP_DIV_LOW_SEL(val)  ((val - 1) & 0x1f)<br>-#define LOOP_DIV_HIGH_SEL(val) (((val - 1) >> 5) & 0x1f)<br>+#define LOOP_DIV_HIGH_SEL(val)    (((val - 1) >> 5) & 0xf)<br> #define PLL_LOOP_DIV_EN            BIT(5)<br> #define PLL_INPUT_DIV_EN       BIT(4)<br> <br>diff --git a/src/soc/rockchip/rk3399/mipi.c b/src/soc/rockchip/rk3399/mipi.c<br>index 1f07491..12e6608 100644<br>--- a/src/soc/rockchip/rk3399/mipi.c<br>+++ b/src/soc/rockchip/rk3399/mipi.c<br>@@ -162,6 +162,15 @@<br>      rk_mipi_dsi_phy_write(dsi, PLL_LOOP_DIVIDER_RATIO,<br>                          LOOP_DIV_LOW_SEL(dsi->feedback_div) |<br>                              LOW_PROGRAM_EN);<br>+<br>+    /*<br>+    * we need set divider control register immediately to make<br>+   * the configrued LSB effective according to IP simulation<br>+    * and lab test results. Only in this way can we get correct<br>+  * mipi phy pll frequency.<br>+    */<br>+  rk_mipi_dsi_phy_write(dsi, PLL_INPUT_AND_LOOP_DIVIDER_RATIOS_CONTROL,<br>+                              PLL_LOOP_DIV_EN | PLL_INPUT_DIV_EN);<br>    rk_mipi_dsi_phy_write(dsi, PLL_LOOP_DIVIDER_RATIO,<br>                          LOOP_DIV_HIGH_SEL(dsi->feedback_div) |<br>                             HIGH_PROGRAM_EN);<br>@@ -209,11 +218,15 @@<br> static int rk_mipi_dsi_get_lane_bps(struct rk_mipi_dsi *dsi,<br>                                     const struct edid *edid)<br> {<br>-     u32 i, pre;<br>-  u64 pclk, pllref, tmp, target_bps;<br>-   u32 m = 1, n = 1;<br>+    u64 pclk, target_bps;<br>         u32 max_bps = dppa_map[ARRAY_SIZE(dppa_map) - 1].max_mbps * MHz;<br>      int bpp;<br>+     u64 best_freq = 0;<br>+   u64 fvco_min, fvco_max, fref;<br>+        u32 min_prediv, max_prediv;<br>+  u32 prediv, best_prediv;<br>+     u64 fbdiv, best_fbdiv;<br>+       u32 min_delta;<br> <br>     bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);<br>   if (bpp < 0) {<br>@@ -222,32 +235,64 @@<br>              return bpp;<br>   }<br>     pclk = edid->mode.pixel_clock * MSECS_PER_SEC;<br>+<br>  /* take 1 / 0.8, since mbps must bigger than bandwidth of RGB */<br>      target_bps = pclk / dsi->lanes * bpp / 8 * 10;<br>     if (target_bps >= max_bps) {<br>               printk(BIOS_DEBUG, "DPHY clock frequency is out of range\n");<br>               return -1;<br>    }<br>-    pllref = OSC_HZ;<br>-     tmp = pllref;<br>-        /*<br>-    * The limits on the PLL divisor are:<br>-         *<br>-    *      5MHz <= (pllref / n) <= 40MHz<br>-   */<br>-  for (i = pllref / (5 * MHz); i > div_round_up(pllref, 40 * MHz); i--) {<br>-           pre = pllref / i;<br>-            if ((tmp > (target_bps % pre)) && (target_bps / pre < 512)) {<br>-                  tmp = target_bps % pre;<br>-                      n = i;<br>-                       m = target_bps / pre;<br>-                }<br>-            if (tmp == 0)<br>-                        break;<br>+<br>+    fref = OSC_HZ;<br>+<br>+    /* constraint: 5Mhz <= Fref / N <= 40MHz */<br>+    min_prediv = div_round_up(fref, 40 * MHz);<br>+   max_prediv = fref / (5 * MHz);<br>+<br>+    /* constraint: 80MHz <= Fvco <= 1500Mhz */<br>+     fvco_min = 80 * MHz;<br>+ fvco_max = 1500 * MHz;<br>+       min_delta = 1500 * MHz;<br>+<br>+   for (prediv = min_prediv; prediv <= max_prediv; prediv++) {<br>+               u64 freq;<br>+            int delta;<br>+<br>+                /* Fvco = Fref * M / N */<br>+            fbdiv = target_bps * prediv / fref;<br>+<br>+               /*<br>+            * Due to the use of a "by 2 pre-scaler", the range of the<br>+          * feedback multiplication value M is limited to even division<br>+                * numbers, and m must be greater than 12, less than 1000.<br>+            */<br>+          fbdiv += fbdiv % 2;<br>+          if (fbdiv <= 12 || fbdiv >= 1000)<br>+                      continue;<br>+<br>+         freq = (u64)fbdiv * fref / prediv;<br>+           if (freq < fvco_min || freq > fvco_max)<br>+                        continue;<br>+<br>+         delta = target_bps - freq;<br>+           delta = ABS(delta);<br>+          if (delta >= min_delta)<br>+                   continue;<br>+<br>+         best_prediv = prediv;<br>+                best_fbdiv = fbdiv;<br>+          min_delta = delta;<br>+           best_freq = freq;<br>     }<br>-    dsi->lane_bps = pllref / n * m;<br>-   dsi->input_div = n;<br>-       dsi->feedback_div = m;<br>+<br>+ if (best_freq) {<br>+             dsi->lane_bps = best_freq;<br>+                dsi->input_div = best_prediv;<br>+             dsi->feedback_div = best_fbdiv;<br>+   } else {<br>+             printk(BIOS_ERR, "Can not find best_freq for DPHY\n");<br>+             return -1;<br>+   }<br> <br>  return 0;<br> }<br></pre><p>To view, visit <a href="https://review.coreboot.org/22468">change 22468</a>. To unsubscribe, visit <a href="https://review.coreboot.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://review.coreboot.org/22468"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: Ic7c5c59be1d00c65c3b17cb3c4bfba8d7459e960 </div>
<div style="display:none"> Gerrit-Change-Number: 22468 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Lin Huang <hl@rock-chips.com> </div>