<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>