From 937265ceff17ca9720a2ae9c6164c8a96ded4914 Mon Sep 17 00:00:00 2001 From: Guochun Huang Date: Fri, 4 Mar 2022 09:35:52 +0800 Subject: [PATCH] phy: rockchip: mipi-dcphy: accurately set mipi channel rate to Kbps/Ksps level take 1280x720@60Hz which pclk is 74.25Mhz as an example, the dsi lane rate should set 445500 Kbps/lane(pclk x bpp = lane_rate x lanes) when mipi work in no video burst pulse/event, therefore the PLL should output the rate of Kbps/ksps level for normal display. Signed-off-by: Guochun Huang Change-Id: I63bf5717e2da521b7af18d88c906b86e30a71488 --- .../phy/rockchip/phy-rockchip-samsung-dcphy.c | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c b/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c index e7cc39f14e92..1d5db69eed44 100644 --- a/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c +++ b/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c @@ -147,8 +147,8 @@ #define S_CPHY_MODE HIWORD_UPDATE(1, 3, 3) #define M_CPHY_MODE HIWORD_UPDATE(1, 0, 0) -#define PSEC_PER_NSEC 1000L -#define PSECS_PER_SEC 1000000000000LL +#define MAX_DPHY_BW 4500000L +#define MAX_CPHY_BW 2000000L struct samsung_mipi_dphy_timing { unsigned int max_lane_mbps; @@ -1419,9 +1419,9 @@ samsung_mipi_dcphy_pll_round_rate(struct samsung_mipi_dcphy *samsung, unsigned long prate, unsigned long rate, u8 *prediv, u16 *fbdiv, int *dsm, u8 *scaler) { - unsigned int max_fout = samsung->c_option ? 2000 : 4500; - unsigned long best_freq = 0; - unsigned int fin, fvco, fout; + u64 max_fout = samsung->c_option ? MAX_CPHY_BW : MAX_DPHY_BW; + u64 best_freq = 0; + u64 fin, fvco, fout; u8 min_prediv, max_prediv; u8 _prediv, best_prediv = 1; u16 _fbdiv, best_fbdiv = 1; @@ -1434,10 +1434,10 @@ samsung_mipi_dcphy_pll_round_rate(struct samsung_mipi_dcphy *samsung, * Fvco = ((m+k/65536) x 2 x Fin) / p * Fout = ((m+k/65536) x 2 x Fin) / (p x 2^s) */ - fin = div64_ul(prate, USEC_PER_SEC); + fin = div64_ul(prate, MSEC_PER_SEC); while (!best_freq) { - fout = div64_ul(rate, USEC_PER_SEC); + fout = div64_ul(rate, MSEC_PER_SEC); if (fout > max_fout) fout = max_fout; @@ -1448,15 +1448,15 @@ samsung_mipi_dcphy_pll_round_rate(struct samsung_mipi_dcphy *samsung, /* * 2600MHz ≤ FVCO ≤ 6600MHz */ - if (fvco < 2600 || fvco > 6600) + if (fvco < 2600 * MSEC_PER_SEC || fvco > 6600 * MSEC_PER_SEC) continue; /* 6MHz ≤ Fref(Fin / p) ≤ 30MHz */ - min_prediv = DIV_ROUND_UP(fin, 30); - max_prediv = fin / 6; + min_prediv = DIV_ROUND_UP_ULL(fin, 30 * MSEC_PER_SEC); + max_prediv = DIV_ROUND_CLOSEST_ULL(fin, 6 * MSEC_PER_SEC); for (_prediv = min_prediv; _prediv <= max_prediv; _prediv++) { - u32 delta, tmp; + u64 delta, tmp; _fbdiv = DIV_ROUND_CLOSEST_ULL(fvco * _prediv, 2 * fin); @@ -1466,26 +1466,26 @@ samsung_mipi_dcphy_pll_round_rate(struct samsung_mipi_dcphy *samsung, /* -32767 ≤ K[15:0] ≤ 32767 */ _dsm = ((_prediv * fvco) - (2 * _fbdiv * fin)); - _dsm = DIV_ROUND_UP(_dsm << 15, fin); + _dsm = DIV_ROUND_UP_ULL(_dsm << 15, fin); if (abs(_dsm) > 32767) continue; tmp = DIV_ROUND_CLOSEST_ULL((_fbdiv * fin * 2 * 1000), _prediv); tmp += DIV_ROUND_CLOSEST_ULL((_dsm * fin * 1000), _prediv << 15); - delta = abs(fvco - tmp); + delta = abs(fvco * MSEC_PER_SEC - tmp); if (delta < min_delta) { best_prediv = _prediv; best_fbdiv = _fbdiv; best_dsm = _dsm; best_scaler = _scaler; min_delta = delta; - best_freq = DIV_ROUND_CLOSEST_ULL(tmp, 1000) * USEC_PER_SEC; + best_freq = DIV_ROUND_CLOSEST_ULL(tmp, 1000) * MSEC_PER_SEC; } } } - rate += USEC_PER_SEC; + rate += 100 * MSEC_PER_SEC; } *prediv = best_prediv;