diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c --- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c @@ -302,6 +302,26 @@ u8 lpfctrl; }; +#define UC_DSI_MAX_LANE_MBPS 307 +#define UC_DSI_DPHY_MARGIN_NUMERATOR 11 +#define UC_DSI_DPHY_MARGIN_DENOMINATOR 10 + +static unsigned int uc_dsi_dphy_margin(unsigned int value) +{ + return DIV_ROUND_UP(value * UC_DSI_DPHY_MARGIN_NUMERATOR, + UC_DSI_DPHY_MARGIN_DENOMINATOR); +} + +static void +uc_dsi_apply_dphy_margin(struct phy_configure_opts_mipi_dphy *cfg) +{ + cfg->clk_prepare = uc_dsi_dphy_margin(cfg->clk_prepare); + cfg->clk_zero = uc_dsi_dphy_margin(cfg->clk_zero); + cfg->hs_zero = uc_dsi_dphy_margin(cfg->hs_zero); + cfg->clk_pre = uc_dsi_dphy_margin(cfg->clk_pre); + cfg->clk_post = uc_dsi_dphy_margin(cfg->clk_post); +} + /* The table is based on 27MHz DPHY pll reference clock. */ static const struct dphy_pll_parameter_map dppa_map[] = { { 89, 0x00, CP_CURRENT_3UA, LPF_RESISTORS_13KOHM }, @@ -574,11 +594,21 @@ "DPHY clock frequency is out of range\n"); } + if (target_mbps > UC_DSI_MAX_LANE_MBPS) { + dev_dbg(dsi->dev, + "uc rockchip dsi lane_mbps limited: calculated=%u limit=%u mode=%ux%u clock=%d lanes=%u format=0x%x\n", + target_mbps, UC_DSI_MAX_LANE_MBPS, mode->hdisplay, + mode->vdisplay, mode->clock, lanes, format); + target_mbps = UC_DSI_MAX_LANE_MBPS; + } + /* for external phy only a the mipi_dphy_config is necessary */ if (dsi->phy) { - phy_mipi_dphy_get_default_config(mode->clock * 1000 * 10 / 8, - bpp, lanes, - &dsi->phy_opts.mipi_dphy); + phy_mipi_dphy_get_default_config_for_hsclk( + (u64)target_mbps * USEC_PER_SEC, + lanes, + &dsi->phy_opts.mipi_dphy); + uc_dsi_apply_dphy_margin(&dsi->phy_opts.mipi_dphy); dsi->lane_mbps = target_mbps; *lane_mbps = dsi->lane_mbps;