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.

Signed-off-by: Cristian Ciocaltea <cristian.ciocal...@collabora.com>
---
 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 
5280383febe25cf579c306ec1642557600595e58..6f2006e7999b540f29841ec4ef679a3ab1e8f497
 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
@@ -13,6 +13,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>
 
@@ -95,6 +96,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 {
@@ -113,24 +115,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
@@ -138,12 +125,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.50.1

Reply via email to