[PATCH 18/18] drm/vc4: hdmi: Force YUV422 if the rate is too high

Maxime Ripard maxime at cerno.tech
Wed Mar 17 15:43:52 UTC 2021


When using the modes that need the highest pixel rate we support (such
as 4k at 60Hz), using a 10 or 12 bpc output will put us over the limit
of what we can achieve.

In such a case, let's force our output to be YUV422 so that we can go
back down under the required clock rate.

Signed-off-by: Maxime Ripard <maxime at cerno.tech>
---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 37 +++++++++++++++++++++++++++++++++-
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index c4f91d39d91c..12eda1e76338 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -1029,6 +1029,41 @@ static unsigned long vc4_hdmi_calc_pixel_rate(struct drm_bridge *bridge,
 	return pixel_rate;
 }
 
+static u32 *vc4_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
+						       struct drm_bridge_state *bridge_state,
+						       struct drm_crtc_state *crtc_state,
+						       struct drm_connector_state *conn_state,
+						       unsigned int *num_output_fmts)
+{
+	struct vc4_hdmi *vc4_hdmi = bridge_to_vc4_hdmi(bridge);
+	unsigned long long pixel_rate = vc4_hdmi_calc_pixel_rate(bridge,
+								 bridge_state,
+								 crtc_state,
+								 conn_state);
+
+	/*
+	 * If our pixel rate is too fast, force YUV422 and hope it works
+	 */
+	if (pixel_rate > vc4_hdmi->variant->max_pixel_clock) {
+		u32 *output_fmts;
+
+		output_fmts = kzalloc(sizeof(*output_fmts), GFP_KERNEL);
+		if (!output_fmts)
+			return NULL;
+
+		*output_fmts = MEDIA_BUS_FMT_UYVY8_1X16;
+		*num_output_fmts = 1;
+
+		return output_fmts;
+	}
+
+	return drm_atomic_helper_bridge_hdmi_get_output_bus_fmts(bridge,
+								 bridge_state,
+								 crtc_state,
+								 conn_state,
+								 num_output_fmts);
+}
+
 static int vc4_hdmi_bridge_atomic_check(struct drm_bridge *bridge,
 					struct drm_bridge_state *bridge_state,
 					struct drm_crtc_state *crtc_state,
@@ -1088,7 +1123,7 @@ static const struct drm_bridge_funcs vc4_hdmi_bridge_funcs = {
 	.atomic_check =	vc4_hdmi_bridge_atomic_check,
 	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
 	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
-	.atomic_get_output_bus_fmts = drm_atomic_helper_bridge_hdmi_get_output_bus_fmts,
+	.atomic_get_output_bus_fmts = vc4_hdmi_bridge_atomic_get_output_bus_fmts,
 	.atomic_reset = drm_atomic_helper_bridge_reset,
 	.mode_valid =	vc4_hdmi_bridge_mode_valid,
 };
-- 
2.30.2



More information about the dri-devel mailing list