diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c index fcf5177e0c77..9254002971b6 100644 --- a/drivers/gpu/drm/bridge/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/dw-hdmi.c @@ -1418,6 +1418,10 @@ static int hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi *hdmi, unsigned int depth = hdmi_bus_fmt_color_depth(hdmi->hdmi_data.enc_out_bus_format); + if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format) && + pdata->mpll_cfg_420) + mpll_config = pdata->mpll_cfg_420; + /* PLL/MPLL Cfg - always match on final entry */ for (; mpll_config->mpixelclock != ~0UL; mpll_config++) if (mpixelclock <= mpll_config->mpixelclock) @@ -1443,18 +1447,8 @@ static int hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi *hdmi, if (depth) depth--; - /* - * RK3399 mpll clock source is vpll, also is vop clock source. - * vpll rate is twice of mpixelclock in YCBCR420 mode, we need - * to enable mpll output divider. - */ - if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format) && - (hdmi->dev_type == RK3399_HDMI || hdmi->dev_type == RK3368_HDMI)) - dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[depth].cpce | 1, - HDMI_3D_TX_PHY_CPCE_CTRL); - else - dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[depth].cpce, - HDMI_3D_TX_PHY_CPCE_CTRL); + dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[depth].cpce, + HDMI_3D_TX_PHY_CPCE_CTRL); dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[depth].gmp, HDMI_3D_TX_PHY_GMPCTRL); dw_hdmi_phy_i2c_write(hdmi, curr_ctrl->curr[depth], @@ -1911,14 +1905,14 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi, vmode->previous_pixelclock = vmode->mpixelclock; vmode->mpixelclock = mode->crtc_clock * 1000; - if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format)) - vmode->mpixelclock /= 2; if ((mode->flags & DRM_MODE_FLAG_3D_MASK) == DRM_MODE_FLAG_3D_FRAME_PACKING) vmode->mpixelclock *= 2; dev_dbg(hdmi->dev, "final pixclk = %d\n", vmode->mpixelclock); vmode->previous_tmdsclock = vmode->mtmdsclock; vmode->mtmdsclock = hdmi_get_tmdsclock(hdmi, vmode->mpixelclock); + if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format)) + vmode->mtmdsclock /= 2; dev_dbg(hdmi->dev, "final tmdsclk = %d\n", vmode->mtmdsclock); /* Set up HDMI_FC_INVIDCONF diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c index cbacf4de0dea..6015e78ca05d 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c @@ -290,6 +290,46 @@ static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = { } }; +static const struct dw_hdmi_mpll_config rockchip_mpll_cfg_420[] = { + { + 30666000, { + { 0x00b7, 0x0000 }, + { 0x2157, 0x0000 }, + { 0x40f7, 0x0000 }, + }, + }, { + 92000000, { + { 0x00b7, 0x0000 }, + { 0x2143, 0x0001 }, + { 0x40a3, 0x0001 }, + }, + }, { + 184000000, { + { 0x0073, 0x0001 }, + { 0x2146, 0x0002 }, + { 0x4062, 0x0002 }, + }, + }, { + 340000000, { + { 0x0052, 0x0003 }, + { 0x214d, 0x0003 }, + { 0x4065, 0x0003 }, + }, + }, { + 600000000, { + { 0x0041, 0x0003 }, + { 0x3b4d, 0x0003 }, + { 0x5a65, 0x0003 }, + }, + }, { + ~0UL, { + { 0x0000, 0x0000 }, + { 0x0000, 0x0000 }, + { 0x0000, 0x0000 }, + }, + } +}; + static const struct dw_hdmi_curr_ctrl rockchip_cur_ctr[] = { /* pixelclk bpp8 bpp10 bpp12 */ { @@ -1052,6 +1092,7 @@ static const struct dw_hdmi_plat_data rk3366_hdmi_drv_data = { static const struct dw_hdmi_plat_data rk3368_hdmi_drv_data = { .mode_valid = dw_hdmi_rockchip_mode_valid, .mpll_cfg = rockchip_mpll_cfg, + .mpll_cfg_420 = rockchip_mpll_cfg_420, .cur_ctr = rockchip_cur_ctr, .phy_config = rockchip_phy_config, .dev_type = RK3368_HDMI, @@ -1060,6 +1101,7 @@ static const struct dw_hdmi_plat_data rk3368_hdmi_drv_data = { static const struct dw_hdmi_plat_data rk3399_hdmi_drv_data = { .mode_valid = dw_hdmi_rockchip_mode_valid, .mpll_cfg = rockchip_mpll_cfg, + .mpll_cfg_420 = rockchip_mpll_cfg_420, .cur_ctr = rockchip_cur_ctr, .phy_config = rockchip_phy_config, .dev_type = RK3399_HDMI, diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h index 1111ff39e39a..e6cf3da43aa8 100644 --- a/include/drm/bridge/dw_hdmi.h +++ b/include/drm/bridge/dw_hdmi.h @@ -170,6 +170,7 @@ struct dw_hdmi_plat_data { /* Synopsys PHY support */ const struct dw_hdmi_mpll_config *mpll_cfg; + const struct dw_hdmi_mpll_config *mpll_cfg_420; const struct dw_hdmi_curr_ctrl *cur_ctr; const struct dw_hdmi_phy_config *phy_config; int (*configure_phy)(struct dw_hdmi *hdmi,