[coreboot-gerrit] Change in coreboot[master]: rockchip/rk3399: mipi: correct Feedback divider setting
Lin Huang (Code Review)
gerrit at coreboot.org
Wed Nov 15 04:28:16 CET 2017
Lin Huang has uploaded this change for review. ( https://review.coreboot.org/22468
Change subject: rockchip/rk3399: mipi: correct Feedback divider setting
......................................................................
rockchip/rk3399: mipi: correct Feedback divider setting
This patch correct Feedback divider setting:
1. Set Feedback divider [8:5] when HIGH_PROGRAM_EN
2. Due to the use of a "by 2 pre-scaler," the range of the
feedback multiplication Feedback divider is limited to even
division numbers, and Feedback divider must be greater than
12, less than 1000.
3. Make the previously configured Feedback divider(LSB)
factors effective
Change-Id: Ic7c5c59be1d00c65c3b17cb3c4bfba8d7459e960
Signed-off-by: Lin Huang <hl at rock-chips.com>
---
M src/soc/rockchip/rk3399/include/soc/mipi.h
M src/soc/rockchip/rk3399/mipi.c
2 files changed, 68 insertions(+), 23 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/68/22468/1
diff --git a/src/soc/rockchip/rk3399/include/soc/mipi.h b/src/soc/rockchip/rk3399/include/soc/mipi.h
index 7dc6b14..d716717 100644
--- a/src/soc/rockchip/rk3399/include/soc/mipi.h
+++ b/src/soc/rockchip/rk3399/include/soc/mipi.h
@@ -209,7 +209,7 @@
#define LOW_PROGRAM_EN 0
#define HIGH_PROGRAM_EN BIT(7)
#define LOOP_DIV_LOW_SEL(val) ((val - 1) & 0x1f)
-#define LOOP_DIV_HIGH_SEL(val) (((val - 1) >> 5) & 0x1f)
+#define LOOP_DIV_HIGH_SEL(val) (((val - 1) >> 5) & 0xf)
#define PLL_LOOP_DIV_EN BIT(5)
#define PLL_INPUT_DIV_EN BIT(4)
diff --git a/src/soc/rockchip/rk3399/mipi.c b/src/soc/rockchip/rk3399/mipi.c
index 1f07491..12e6608 100644
--- a/src/soc/rockchip/rk3399/mipi.c
+++ b/src/soc/rockchip/rk3399/mipi.c
@@ -162,6 +162,15 @@
rk_mipi_dsi_phy_write(dsi, PLL_LOOP_DIVIDER_RATIO,
LOOP_DIV_LOW_SEL(dsi->feedback_div) |
LOW_PROGRAM_EN);
+
+ /*
+ * we need set divider control register immediately to make
+ * the configrued LSB effective according to IP simulation
+ * and lab test results. Only in this way can we get correct
+ * mipi phy pll frequency.
+ */
+ rk_mipi_dsi_phy_write(dsi, PLL_INPUT_AND_LOOP_DIVIDER_RATIOS_CONTROL,
+ PLL_LOOP_DIV_EN | PLL_INPUT_DIV_EN);
rk_mipi_dsi_phy_write(dsi, PLL_LOOP_DIVIDER_RATIO,
LOOP_DIV_HIGH_SEL(dsi->feedback_div) |
HIGH_PROGRAM_EN);
@@ -209,11 +218,15 @@
static int rk_mipi_dsi_get_lane_bps(struct rk_mipi_dsi *dsi,
const struct edid *edid)
{
- u32 i, pre;
- u64 pclk, pllref, tmp, target_bps;
- u32 m = 1, n = 1;
+ u64 pclk, target_bps;
u32 max_bps = dppa_map[ARRAY_SIZE(dppa_map) - 1].max_mbps * MHz;
int bpp;
+ u64 best_freq = 0;
+ u64 fvco_min, fvco_max, fref;
+ u32 min_prediv, max_prediv;
+ u32 prediv, best_prediv;
+ u64 fbdiv, best_fbdiv;
+ u32 min_delta;
bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
if (bpp < 0) {
@@ -222,32 +235,64 @@
return bpp;
}
pclk = edid->mode.pixel_clock * MSECS_PER_SEC;
+
/* take 1 / 0.8, since mbps must bigger than bandwidth of RGB */
target_bps = pclk / dsi->lanes * bpp / 8 * 10;
if (target_bps >= max_bps) {
printk(BIOS_DEBUG, "DPHY clock frequency is out of range\n");
return -1;
}
- pllref = OSC_HZ;
- tmp = pllref;
- /*
- * The limits on the PLL divisor are:
- *
- * 5MHz <= (pllref / n) <= 40MHz
- */
- for (i = pllref / (5 * MHz); i > div_round_up(pllref, 40 * MHz); i--) {
- pre = pllref / i;
- if ((tmp > (target_bps % pre)) && (target_bps / pre < 512)) {
- tmp = target_bps % pre;
- n = i;
- m = target_bps / pre;
- }
- if (tmp == 0)
- break;
+
+ fref = OSC_HZ;
+
+ /* constraint: 5Mhz <= Fref / N <= 40MHz */
+ min_prediv = div_round_up(fref, 40 * MHz);
+ max_prediv = fref / (5 * MHz);
+
+ /* constraint: 80MHz <= Fvco <= 1500Mhz */
+ fvco_min = 80 * MHz;
+ fvco_max = 1500 * MHz;
+ min_delta = 1500 * MHz;
+
+ for (prediv = min_prediv; prediv <= max_prediv; prediv++) {
+ u64 freq;
+ int delta;
+
+ /* Fvco = Fref * M / N */
+ fbdiv = target_bps * prediv / fref;
+
+ /*
+ * Due to the use of a "by 2 pre-scaler", the range of the
+ * feedback multiplication value M is limited to even division
+ * numbers, and m must be greater than 12, less than 1000.
+ */
+ fbdiv += fbdiv % 2;
+ if (fbdiv <= 12 || fbdiv >= 1000)
+ continue;
+
+ freq = (u64)fbdiv * fref / prediv;
+ if (freq < fvco_min || freq > fvco_max)
+ continue;
+
+ delta = target_bps - freq;
+ delta = ABS(delta);
+ if (delta >= min_delta)
+ continue;
+
+ best_prediv = prediv;
+ best_fbdiv = fbdiv;
+ min_delta = delta;
+ best_freq = freq;
}
- dsi->lane_bps = pllref / n * m;
- dsi->input_div = n;
- dsi->feedback_div = m;
+
+ if (best_freq) {
+ dsi->lane_bps = best_freq;
+ dsi->input_div = best_prediv;
+ dsi->feedback_div = best_fbdiv;
+ } else {
+ printk(BIOS_ERR, "Can not find best_freq for DPHY\n");
+ return -1;
+ }
return 0;
}
--
To view, visit https://review.coreboot.org/22468
To unsubscribe, visit https://review.coreboot.org/settings
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ic7c5c59be1d00c65c3b17cb3c4bfba8d7459e960
Gerrit-Change-Number: 22468
Gerrit-PatchSet: 1
Gerrit-Owner: Lin Huang <hl at rock-chips.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.coreboot.org/pipermail/coreboot-gerrit/attachments/20171115/0c076628/attachment-0001.html>
More information about the coreboot-gerrit
mailing list