Stop relying on phy_set_bus_width() based workaround to setup the TMDS character rate and, instead, use the recently introduced HDMI PHY configuration API. This is also a prerequisite to enable high color depth and FRL support.
Additionally, move the logic to ->atomic_check() callback where the current mode rate is already provided by the connector state. As a matter of fact this is actually necessary to ensure the link rate is configured before VOP2 attempts to use the PHY PLL as a DCLK source in vop2_crtc_atomic_enable(). The rationale is to restrict any changes of the PHY rate via CCF and, instead, prefer the PHY configuration API for this purpose. Acked-by: Daniel Stone <[email protected]> Signed-off-by: Cristian Ciocaltea <[email protected]> --- drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 37 +++++++++++++------------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c index 931343b072ad..04e18dd9102a 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c @@ -14,6 +14,7 @@ #include <linux/module.h> #include <linux/platform_device.h> #include <linux/phy/phy.h> +#include <linux/phy/phy-hdmi.h> #include <linux/regmap.h> #include <linux/workqueue.h> @@ -96,6 +97,7 @@ struct rockchip_hdmi_qp { struct delayed_work hpd_work; int port_id; const struct rockchip_hdmi_qp_ctrl_ops *ctrl_ops; + unsigned long long tmds_char_rate; }; struct rockchip_hdmi_qp_ctrl_ops { @@ -114,24 +116,9 @@ static struct rockchip_hdmi_qp *to_rockchip_hdmi_qp(struct drm_encoder *encoder) static void dw_hdmi_qp_rockchip_encoder_enable(struct drm_encoder *encoder) { struct rockchip_hdmi_qp *hdmi = to_rockchip_hdmi_qp(encoder); - struct drm_crtc *crtc = encoder->crtc; - unsigned long long rate; /* Unconditionally switch to TMDS as FRL is not yet supported */ gpiod_set_value(hdmi->enable_gpio, 1); - - if (crtc && crtc->state) { - rate = drm_hdmi_compute_mode_clock(&crtc->state->adjusted_mode, - 8, HDMI_COLORSPACE_RGB); - /* - * FIXME: Temporary workaround to pass pixel clock rate - * to the PHY driver until phy_configure_opts_hdmi - * becomes available in the PHY API. See also the related - * comment in rk_hdptx_phy_power_on() from - * drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c - */ - phy_set_bus_width(hdmi->phy, div_u64(rate, 100)); - } } static int @@ -139,12 +126,26 @@ dw_hdmi_qp_rockchip_encoder_atomic_check(struct drm_encoder *encoder, struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state) { + struct rockchip_hdmi_qp *hdmi = to_rockchip_hdmi_qp(encoder); struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state); + union phy_configure_opts phy_cfg = {}; + int ret; - s->output_mode = ROCKCHIP_OUT_MODE_AAAA; - s->output_type = DRM_MODE_CONNECTOR_HDMIA; + if (hdmi->tmds_char_rate == conn_state->hdmi.tmds_char_rate) + return 0; - return 0; + phy_cfg.hdmi.tmds_char_rate = conn_state->hdmi.tmds_char_rate; + + ret = phy_configure(hdmi->phy, &phy_cfg); + if (!ret) { + hdmi->tmds_char_rate = conn_state->hdmi.tmds_char_rate; + s->output_mode = ROCKCHIP_OUT_MODE_AAAA; + s->output_type = DRM_MODE_CONNECTOR_HDMIA; + } else { + dev_err(hdmi->dev, "Failed to configure phy: %d\n", ret); + } + + return ret; } static const struct -- 2.51.0
