[PATCH v6 23/51] drm/omap: Add infrastructure to support drm_bridge local to DSS outputs
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Sun Feb 16 21:02:40 UTC 2020
In order to support drm_bridge-based pipeline, the internal HDMI
encoders will need to expose the EDID read operation through the
drm_bridge API, and thus to expose a drm_bridge instance corresponding
to the encoder. The HDMI encoders are however handled as omap_dss_device
instances, which conflicts with this requirement.
In order to move forward with the drm_bridge transition, add support for
creating drm_bridge instances local to DSS outputs. If a local bridge is
passed to the omapdss_device_init_output() function, it is used as the
first bridge in the chain, and the omap_dss_device.next_bridge field is
set to the next bridge for the use of the internal encoders' bridges.
Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Reviewed-by: Tomi Valkeinen <tomi.valkeinen at ti.com>
---
drivers/gpu/drm/omapdrm/dss/dpi.c | 2 +-
drivers/gpu/drm/omapdrm/dss/dsi.c | 2 +-
drivers/gpu/drm/omapdrm/dss/hdmi4.c | 2 +-
drivers/gpu/drm/omapdrm/dss/hdmi5.c | 2 +-
drivers/gpu/drm/omapdrm/dss/omapdss.h | 4 +++-
drivers/gpu/drm/omapdrm/dss/output.c | 20 ++++++++++++++++----
drivers/gpu/drm/omapdrm/dss/sdi.c | 2 +-
drivers/gpu/drm/omapdrm/dss/venc.c | 2 +-
drivers/gpu/drm/omapdrm/omap_drv.c | 2 +-
9 files changed, 26 insertions(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/dss/dpi.c b/drivers/gpu/drm/omapdrm/dss/dpi.c
index 462ed6f3118a..2d0eb5fcbb5b 100644
--- a/drivers/gpu/drm/omapdrm/dss/dpi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dpi.c
@@ -629,7 +629,7 @@ static int dpi_init_output_port(struct dpi_data *dpi, struct device_node *port)
out->ops = &dpi_ops;
out->owner = THIS_MODULE;
- r = omapdss_device_init_output(out);
+ r = omapdss_device_init_output(out, NULL);
if (r < 0)
return r;
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 6379eea124d1..79ddfbfd1b58 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -5121,7 +5121,7 @@ static int dsi_init_output(struct dsi_data *dsi)
| DRM_BUS_FLAG_DE_HIGH
| DRM_BUS_FLAG_SYNC_DRIVE_NEGEDGE;
- r = omapdss_device_init_output(out);
+ r = omapdss_device_init_output(out, NULL);
if (r < 0)
return r;
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
index 44075718407b..dd4a14fe7e59 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
@@ -676,7 +676,7 @@ static int hdmi4_init_output(struct omap_hdmi *hdmi)
out->of_port = 0;
out->ops_flags = OMAP_DSS_DEVICE_OP_EDID;
- r = omapdss_device_init_output(out);
+ r = omapdss_device_init_output(out, NULL);
if (r < 0)
return r;
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
index 1b5bd44ee09d..8e3790dd8b98 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
@@ -660,7 +660,7 @@ static int hdmi5_init_output(struct omap_hdmi *hdmi)
out->of_port = 0;
out->ops_flags = OMAP_DSS_DEVICE_OP_EDID;
- r = omapdss_device_init_output(out);
+ r = omapdss_device_init_output(out, NULL);
if (r < 0)
return r;
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index b48a51d11310..82e9bfa5530a 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -400,6 +400,7 @@ struct omap_dss_device {
struct dss_device *dss;
struct omap_dss_device *next;
struct drm_bridge *bridge;
+ struct drm_bridge *next_bridge;
struct drm_panel *panel;
struct list_head list;
@@ -488,7 +489,8 @@ int omap_dss_get_num_overlays(void);
#define for_each_dss_output(d) \
while ((d = omapdss_device_next_output(d)) != NULL)
struct omap_dss_device *omapdss_device_next_output(struct omap_dss_device *from);
-int omapdss_device_init_output(struct omap_dss_device *out);
+int omapdss_device_init_output(struct omap_dss_device *out,
+ struct drm_bridge *local_bridge);
void omapdss_device_cleanup_output(struct omap_dss_device *out);
typedef void (*omap_dispc_isr_t) (void *arg, u32 mask);
diff --git a/drivers/gpu/drm/omapdrm/dss/output.c b/drivers/gpu/drm/omapdrm/dss/output.c
index c1ec9d343e53..9ba7cc8539a1 100644
--- a/drivers/gpu/drm/omapdrm/dss/output.c
+++ b/drivers/gpu/drm/omapdrm/dss/output.c
@@ -17,7 +17,8 @@
#include "dss.h"
#include "omapdss.h"
-int omapdss_device_init_output(struct omap_dss_device *out)
+int omapdss_device_init_output(struct omap_dss_device *out,
+ struct drm_bridge *local_bridge)
{
struct device_node *remote_node;
int ret;
@@ -58,10 +59,20 @@ int omapdss_device_init_output(struct omap_dss_device *out)
out->bridge = bridge;
}
- return out->next || out->bridge ? 0 : -EPROBE_DEFER;
+ if (local_bridge) {
+ out->next_bridge = out->bridge;
+ out->bridge = local_bridge;
+ }
+
+ if (!out->next && !out->bridge) {
+ ret = -EPROBE_DEFER;
+ goto error;
+ }
+
+ return 0;
error:
- omapdss_device_put(out->next);
+ omapdss_device_cleanup_output(out);
out->next = NULL;
return ret;
}
@@ -70,7 +81,8 @@ EXPORT_SYMBOL(omapdss_device_init_output);
void omapdss_device_cleanup_output(struct omap_dss_device *out)
{
if (out->bridge && out->panel)
- drm_panel_bridge_remove(out->bridge);
+ drm_panel_bridge_remove(out->next_bridge ?
+ out->next_bridge : out->bridge);
if (out->next)
omapdss_device_put(out->next);
diff --git a/drivers/gpu/drm/omapdrm/dss/sdi.c b/drivers/gpu/drm/omapdrm/dss/sdi.c
index 9092ed3d0ef1..11aa2f712ff4 100644
--- a/drivers/gpu/drm/omapdrm/dss/sdi.c
+++ b/drivers/gpu/drm/omapdrm/dss/sdi.c
@@ -271,7 +271,7 @@ static int sdi_init_output(struct sdi_device *sdi)
out->bus_flags = DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE /* 15.5.9.1.2 */
| DRM_BUS_FLAG_SYNC_DRIVE_POSEDGE;
- r = omapdss_device_init_output(out);
+ r = omapdss_device_init_output(out, NULL);
if (r < 0)
return r;
diff --git a/drivers/gpu/drm/omapdrm/dss/venc.c b/drivers/gpu/drm/omapdrm/dss/venc.c
index e2f480f689b8..977d8d525b43 100644
--- a/drivers/gpu/drm/omapdrm/dss/venc.c
+++ b/drivers/gpu/drm/omapdrm/dss/venc.c
@@ -757,7 +757,7 @@ static int venc_init_output(struct venc_device *venc)
out->of_port = 0;
out->ops_flags = OMAP_DSS_DEVICE_OP_MODES;
- r = omapdss_device_init_output(out);
+ r = omapdss_device_init_output(out, NULL);
if (r < 0)
return r;
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index aefcf86d4045..1df509342b5d 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -324,7 +324,7 @@ static int omap_modeset_init(struct drm_device *dev)
struct drm_encoder *encoder = pipe->encoder;
struct drm_crtc *crtc;
- if (!pipe->output->bridge) {
+ if (pipe->output->next) {
pipe->connector = omap_connector_init(dev, pipe->output,
encoder);
if (!pipe->connector)
--
Regards,
Laurent Pinchart
More information about the dri-devel
mailing list