Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/rockchip: dw_hdmi_qp: Switch to phy_configure()

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 <daniels@collabora.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Link: https://lore.kernel.org/r/20251021-rk3588-10bpc-v3-3-3d3eed00a6db@collabora.com

authored by

Cristian Ciocaltea and committed by
Heiko Stuebner
ba9c2fe1 1ff27c59

+19 -18
+19 -18
drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
··· 14 14 #include <linux/module.h> 15 15 #include <linux/platform_device.h> 16 16 #include <linux/phy/phy.h> 17 + #include <linux/phy/phy-hdmi.h> 17 18 #include <linux/regmap.h> 18 19 #include <linux/workqueue.h> 19 20 ··· 97 96 struct delayed_work hpd_work; 98 97 int port_id; 99 98 const struct rockchip_hdmi_qp_ctrl_ops *ctrl_ops; 99 + unsigned long long tmds_char_rate; 100 100 }; 101 101 102 102 struct rockchip_hdmi_qp_ctrl_ops { ··· 116 114 static void dw_hdmi_qp_rockchip_encoder_enable(struct drm_encoder *encoder) 117 115 { 118 116 struct rockchip_hdmi_qp *hdmi = to_rockchip_hdmi_qp(encoder); 119 - struct drm_crtc *crtc = encoder->crtc; 120 - unsigned long long rate; 121 117 122 118 /* Unconditionally switch to TMDS as FRL is not yet supported */ 123 119 gpiod_set_value(hdmi->frl_enable_gpio, 0); 124 - 125 - if (crtc && crtc->state) { 126 - rate = drm_hdmi_compute_mode_clock(&crtc->state->adjusted_mode, 127 - 8, HDMI_COLORSPACE_RGB); 128 - /* 129 - * FIXME: Temporary workaround to pass pixel clock rate 130 - * to the PHY driver until phy_configure_opts_hdmi 131 - * becomes available in the PHY API. See also the related 132 - * comment in rk_hdptx_phy_power_on() from 133 - * drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c 134 - */ 135 - phy_set_bus_width(hdmi->phy, div_u64(rate, 100)); 136 - } 137 120 } 138 121 139 122 static int ··· 126 139 struct drm_crtc_state *crtc_state, 127 140 struct drm_connector_state *conn_state) 128 141 { 142 + struct rockchip_hdmi_qp *hdmi = to_rockchip_hdmi_qp(encoder); 129 143 struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state); 144 + union phy_configure_opts phy_cfg = {}; 145 + int ret; 130 146 131 - s->output_mode = ROCKCHIP_OUT_MODE_AAAA; 132 - s->output_type = DRM_MODE_CONNECTOR_HDMIA; 147 + if (hdmi->tmds_char_rate == conn_state->hdmi.tmds_char_rate) 148 + return 0; 133 149 134 - return 0; 150 + phy_cfg.hdmi.tmds_char_rate = conn_state->hdmi.tmds_char_rate; 151 + 152 + ret = phy_configure(hdmi->phy, &phy_cfg); 153 + if (!ret) { 154 + hdmi->tmds_char_rate = conn_state->hdmi.tmds_char_rate; 155 + s->output_mode = ROCKCHIP_OUT_MODE_AAAA; 156 + s->output_type = DRM_MODE_CONNECTOR_HDMIA; 157 + } else { 158 + dev_err(hdmi->dev, "Failed to configure phy: %d\n", ret); 159 + } 160 + 161 + return ret; 135 162 } 136 163 137 164 static const struct