[PATCH RFC 15/19] drm/imx: pd: Use bus format/flags provided by the bridge when available

Boris Brezillon boris.brezillon at collabora.com
Thu Aug 8 15:11:46 UTC 2019


Now that bridges can expose the bus format/flags they expect, we can
use those instead of the relying on the display_info provided by the
connector (which is only valid if the encoder is directly connected
to bridge element driving the panel/display).

We also explicitly expose the bus formats supported by our encoder by
filling encoder->output_bus_caps with proper info.

Signed-off-by: Boris Brezillon <boris.brezillon at collabora.com>
---
 drivers/gpu/drm/imx/parallel-display.c | 28 +++++++++++++++++++++++++-
 1 file changed, 27 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c
index 35f20edab9fd..57fee48d6bb6 100644
--- a/drivers/gpu/drm/imx/parallel-display.c
+++ b/drivers/gpu/drm/imx/parallel-display.c
@@ -115,8 +115,18 @@ static int imx_pd_encoder_atomic_check(struct drm_encoder *encoder,
 	struct imx_crtc_state *imx_crtc_state = to_imx_crtc_state(crtc_state);
 	struct drm_display_info *di = &conn_state->connector->display_info;
 	struct imx_parallel_display *imxpd = enc_to_imxpd(encoder);
+	struct drm_bridge_state *bridge_state = NULL;
+	struct drm_bridge *bridge;
 
-	if (!imxpd->bus_format && di->num_bus_formats) {
+	bridge = drm_bridge_chain_get_first_bridge(encoder);
+	if (bridge)
+		bridge_state = drm_atomic_get_new_bridge_state(crtc_state->state,
+							       bridge);
+
+	if (bridge_state && bridge_state->input_bus_cfg.fmt) {
+		imx_crtc_state->bus_format = bridge_state->input_bus_cfg.fmt;
+		imx_crtc_state->bus_flags = bridge_state->input_bus_cfg.flags;
+	} else if (!imxpd->bus_format && di->num_bus_formats) {
 		imx_crtc_state->bus_flags = di->bus_flags;
 		imx_crtc_state->bus_format = di->bus_formats[0];
 	} else {
@@ -152,10 +162,18 @@ static const struct drm_encoder_helper_funcs imx_pd_encoder_helper_funcs = {
 	.atomic_check = imx_pd_encoder_atomic_check,
 };
 
+static const u32 imx_pd_bus_fmts[] = {
+	MEDIA_BUS_FMT_RGB888_1X24,
+	MEDIA_BUS_FMT_RGB565_1X16,
+	MEDIA_BUS_FMT_RGB666_1X18,
+	MEDIA_BUS_FMT_RGB666_1X24_CPADHI,
+};
+
 static int imx_pd_register(struct drm_device *drm,
 	struct imx_parallel_display *imxpd)
 {
 	struct drm_encoder *encoder = &imxpd->encoder;
+	struct drm_bus_caps *bus_caps = &encoder->output_bus_caps;
 	int ret;
 
 	ret = imx_drm_encoder_parse_of(drm, encoder, imxpd->dev->of_node);
@@ -173,6 +191,14 @@ static int imx_pd_register(struct drm_device *drm,
 	drm_encoder_init(drm, encoder, &imx_pd_encoder_funcs,
 			 DRM_MODE_ENCODER_NONE, NULL);
 
+	if (imxpd->bus_format) {
+		bus_caps->supported_fmts = &imxpd->bus_format;
+		bus_caps->num_supported_fmts = 1;
+	} else {
+		bus_caps->supported_fmts = imx_pd_bus_fmts;
+		bus_caps->num_supported_fmts = ARRAY_SIZE(imx_pd_bus_fmts);
+	}
+
 	if (!imxpd->bridge) {
 		drm_connector_helper_add(&imxpd->connector,
 				&imx_pd_connector_helper_funcs);
-- 
2.21.0



More information about the dri-devel mailing list