diff mbox series

[v3,35/50] drm/omap: Create connector for bridges

Message ID 20191210225750.15709-36-laurent.pinchart@ideasonboard.com (mailing list archive)
State New, archived
Headers show
Series drm/omap: Replace custom display drivers with drm_bridge and drm_panel | expand

Commit Message

Laurent Pinchart Dec. 10, 2019, 10:57 p.m. UTC
Use the drm_bridge_connector helper to create a connector for pipelines
that use drm_bridge. This allows splitting connector operations across
multiple bridges when necessary, instead of having the last bridge in
the chain creating the connector and handling all connector operations
internally.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
Changes since v1:

- Squash with patch "drm/omap: Detach from panels at remove time"
---
 drivers/gpu/drm/omapdrm/omap_drv.c | 79 +++++++++++++++++++++++++-----
 1 file changed, 67 insertions(+), 12 deletions(-)

Comments

Sam Ravnborg Dec. 15, 2019, 10 a.m. UTC | #1
Hi Laurent.

On Wed, Dec 11, 2019 at 12:57:35AM +0200, Laurent Pinchart wrote:
> Use the drm_bridge_connector helper to create a connector for pipelines
> that use drm_bridge. This allows splitting connector operations across
> multiple bridges when necessary, instead of having the last bridge in
> the chain creating the connector and handling all connector operations
> internally.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
> Changes since v1:
> 
> - Squash with patch "drm/omap: Detach from panels at remove time"
> ---
>  drivers/gpu/drm/omapdrm/omap_drv.c | 79 +++++++++++++++++++++++++-----
>  1 file changed, 67 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
> index 1df509342b5d..097fbbaa5df0 100644
> --- a/drivers/gpu/drm/omapdrm/omap_drv.c
> +++ b/drivers/gpu/drm/omapdrm/omap_drv.c
> @@ -12,10 +12,12 @@
>  #include <drm/drm_atomic.h>
>  #include <drm/drm_atomic_helper.h>
>  #include <drm/drm_bridge.h>
> +#include <drm/drm_bridge_connector.h>
>  #include <drm/drm_drv.h>
>  #include <drm/drm_fb_helper.h>
>  #include <drm/drm_file.h>
>  #include <drm/drm_ioctl.h>
> +#include <drm/drm_panel.h>
>  #include <drm/drm_prime.h>
>  #include <drm/drm_probe_helper.h>
>  #include <drm/drm_vblank.h>
> @@ -291,9 +293,14 @@ static int omap_modeset_init(struct drm_device *dev)
>  
>  		if (pipe->output->bridge) {
>  			ret = drm_bridge_attach(pipe->encoder,
> -						pipe->output->bridge, NULL, 0);
> -			if (ret < 0)
> +						pipe->output->bridge, NULL,
> +						DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> +			if (ret < 0) {
> +				dev_err(priv->dev,
> +					"unable to attach bridge %pOF\n",
> +					pipe->output->bridge->of_node);
>  				return ret;
> +			}
>  		}
>  
>  		id = omap_display_id(pipe->output);
> @@ -329,8 +336,28 @@ static int omap_modeset_init(struct drm_device *dev)
>  							      encoder);
>  			if (!pipe->connector)
>  				return -ENOMEM;
> +		} else {
> +			pipe->connector = drm_bridge_connector_init(dev, encoder);
> +			if (IS_ERR(pipe->connector)) {
> +				dev_err(priv->dev,
> +					"unable to create bridge connector for %s\n",
> +					pipe->output->name);
> +				return PTR_ERR(pipe->connector);
> +			}
> +		}
>  
> -			drm_connector_attach_encoder(pipe->connector, encoder);
> +		drm_connector_attach_encoder(pipe->connector, encoder);
> +
> +		/*
> +		 * FIXME: drm_panel should not store the drm_connector pointer
> +		 * internally but should receive it in its .get_modes()
> +		 * operation.
> +		 */
This FIXME is not fully up-to-date.
drm_panel_attach ignores the connector argumant, and we could also pass
NULL here.

I am not convinced we need the drm_panel_(attach|detach) anymore, but
this is not the thread to take that discussion.

	Sam
Laurent Pinchart Dec. 18, 2019, 1:56 a.m. UTC | #2
Hi Sam,

Thank you for the review.

On Sun, Dec 15, 2019 at 11:00:18AM +0100, Sam Ravnborg wrote:
> On Wed, Dec 11, 2019 at 12:57:35AM +0200, Laurent Pinchart wrote:
> > Use the drm_bridge_connector helper to create a connector for pipelines
> > that use drm_bridge. This allows splitting connector operations across
> > multiple bridges when necessary, instead of having the last bridge in
> > the chain creating the connector and handling all connector operations
> > internally.
> > 
> > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > ---
> > Changes since v1:
> > 
> > - Squash with patch "drm/omap: Detach from panels at remove time"
> > ---
> >  drivers/gpu/drm/omapdrm/omap_drv.c | 79 +++++++++++++++++++++++++-----
> >  1 file changed, 67 insertions(+), 12 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
> > index 1df509342b5d..097fbbaa5df0 100644
> > --- a/drivers/gpu/drm/omapdrm/omap_drv.c
> > +++ b/drivers/gpu/drm/omapdrm/omap_drv.c
> > @@ -12,10 +12,12 @@
> >  #include <drm/drm_atomic.h>
> >  #include <drm/drm_atomic_helper.h>
> >  #include <drm/drm_bridge.h>
> > +#include <drm/drm_bridge_connector.h>
> >  #include <drm/drm_drv.h>
> >  #include <drm/drm_fb_helper.h>
> >  #include <drm/drm_file.h>
> >  #include <drm/drm_ioctl.h>
> > +#include <drm/drm_panel.h>
> >  #include <drm/drm_prime.h>
> >  #include <drm/drm_probe_helper.h>
> >  #include <drm/drm_vblank.h>
> > @@ -291,9 +293,14 @@ static int omap_modeset_init(struct drm_device *dev)
> >  
> >  		if (pipe->output->bridge) {
> >  			ret = drm_bridge_attach(pipe->encoder,
> > -						pipe->output->bridge, NULL, 0);
> > -			if (ret < 0)
> > +						pipe->output->bridge, NULL,
> > +						DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> > +			if (ret < 0) {
> > +				dev_err(priv->dev,
> > +					"unable to attach bridge %pOF\n",
> > +					pipe->output->bridge->of_node);
> >  				return ret;
> > +			}
> >  		}
> >  
> >  		id = omap_display_id(pipe->output);
> > @@ -329,8 +336,28 @@ static int omap_modeset_init(struct drm_device *dev)
> >  							      encoder);
> >  			if (!pipe->connector)
> >  				return -ENOMEM;
> > +		} else {
> > +			pipe->connector = drm_bridge_connector_init(dev, encoder);
> > +			if (IS_ERR(pipe->connector)) {
> > +				dev_err(priv->dev,
> > +					"unable to create bridge connector for %s\n",
> > +					pipe->output->name);
> > +				return PTR_ERR(pipe->connector);
> > +			}
> > +		}
> >  
> > -			drm_connector_attach_encoder(pipe->connector, encoder);
> > +		drm_connector_attach_encoder(pipe->connector, encoder);
> > +
> > +		/*
> > +		 * FIXME: drm_panel should not store the drm_connector pointer
> > +		 * internally but should receive it in its .get_modes()
> > +		 * operation.
> > +		 */
>
> This FIXME is not fully up-to-date.
> drm_panel_attach ignores the connector argumant, and we could also pass
> NULL here.

You're right, I'll remove the comment.

> I am not convinced we need the drm_panel_(attach|detach) anymore, but
> this is not the thread to take that discussion.

Indeed :-) I think we should replace all direct panel usage with the DRM
panel bridge, then we'll be able to refactor the panel API freely.
Tomi Valkeinen Dec. 18, 2019, 12:55 p.m. UTC | #3
On 11/12/2019 00:57, Laurent Pinchart wrote:
> Use the drm_bridge_connector helper to create a connector for pipelines
> that use drm_bridge. This allows splitting connector operations across
> multiple bridges when necessary, instead of having the last bridge in
> the chain creating the connector and handling all connector operations
> internally.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
> Changes since v1:
> 
> - Squash with patch "drm/omap: Detach from panels at remove time"
> ---
>   drivers/gpu/drm/omapdrm/omap_drv.c | 79 +++++++++++++++++++++++++-----
>   1 file changed, 67 insertions(+), 12 deletions(-)

Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ti.com>

  Tomi
diff mbox series

Patch

diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index 1df509342b5d..097fbbaa5df0 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -12,10 +12,12 @@ 
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_bridge.h>
+#include <drm/drm_bridge_connector.h>
 #include <drm/drm_drv.h>
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_file.h>
 #include <drm/drm_ioctl.h>
+#include <drm/drm_panel.h>
 #include <drm/drm_prime.h>
 #include <drm/drm_probe_helper.h>
 #include <drm/drm_vblank.h>
@@ -291,9 +293,14 @@  static int omap_modeset_init(struct drm_device *dev)
 
 		if (pipe->output->bridge) {
 			ret = drm_bridge_attach(pipe->encoder,
-						pipe->output->bridge, NULL, 0);
-			if (ret < 0)
+						pipe->output->bridge, NULL,
+						DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+			if (ret < 0) {
+				dev_err(priv->dev,
+					"unable to attach bridge %pOF\n",
+					pipe->output->bridge->of_node);
 				return ret;
+			}
 		}
 
 		id = omap_display_id(pipe->output);
@@ -329,8 +336,28 @@  static int omap_modeset_init(struct drm_device *dev)
 							      encoder);
 			if (!pipe->connector)
 				return -ENOMEM;
+		} else {
+			pipe->connector = drm_bridge_connector_init(dev, encoder);
+			if (IS_ERR(pipe->connector)) {
+				dev_err(priv->dev,
+					"unable to create bridge connector for %s\n",
+					pipe->output->name);
+				return PTR_ERR(pipe->connector);
+			}
+		}
 
-			drm_connector_attach_encoder(pipe->connector, encoder);
+		drm_connector_attach_encoder(pipe->connector, encoder);
+
+		/*
+		 * FIXME: drm_panel should not store the drm_connector pointer
+		 * internally but should receive it in its .get_modes()
+		 * operation.
+		 */
+		if (pipe->output->panel) {
+			ret = drm_panel_attach(pipe->output->panel,
+					       pipe->connector);
+			if (ret < 0)
+				return ret;
 		}
 
 		crtc = omap_crtc_init(dev, pipe, priv->planes[i]);
@@ -369,6 +396,23 @@  static int omap_modeset_init(struct drm_device *dev)
 	return 0;
 }
 
+static void omap_modeset_fini(struct drm_device *ddev)
+{
+	struct omap_drm_private *priv = ddev->dev_private;
+	unsigned int i;
+
+	omap_drm_irq_uninstall(ddev);
+
+	for (i = 0; i < priv->num_pipes; i++) {
+		struct omap_drm_pipeline *pipe = &priv->pipes[i];
+
+		if (pipe->output->panel)
+			drm_panel_detach(pipe->output->panel);
+	}
+
+	drm_mode_config_cleanup(ddev);
+}
+
 /*
  * Enable the HPD in external components if supported
  */
@@ -378,8 +422,15 @@  static void omap_modeset_enable_external_hpd(struct drm_device *ddev)
 	unsigned int i;
 
 	for (i = 0; i < priv->num_pipes; i++) {
-		if (priv->pipes[i].connector)
-			omap_connector_enable_hpd(priv->pipes[i].connector);
+		struct drm_connector *connector = priv->pipes[i].connector;
+
+		if (!connector)
+			continue;
+
+		if (priv->pipes[i].output->next)
+			omap_connector_enable_hpd(connector);
+		else
+			drm_bridge_connector_enable_hpd(connector);
 	}
 }
 
@@ -392,8 +443,15 @@  static void omap_modeset_disable_external_hpd(struct drm_device *ddev)
 	unsigned int i;
 
 	for (i = 0; i < priv->num_pipes; i++) {
-		if (priv->pipes[i].connector)
-			omap_connector_disable_hpd(priv->pipes[i].connector);
+		struct drm_connector *connector = priv->pipes[i].connector;
+
+		if (!connector)
+			continue;
+
+		if (priv->pipes[i].output->next)
+			omap_connector_disable_hpd(connector);
+		else
+			drm_bridge_connector_disable_hpd(connector);
 	}
 }
 
@@ -616,8 +674,7 @@  static int omapdrm_init(struct omap_drm_private *priv, struct device *dev)
 
 	omap_fbdev_fini(ddev);
 err_cleanup_modeset:
-	drm_mode_config_cleanup(ddev);
-	omap_drm_irq_uninstall(ddev);
+	omap_modeset_fini(ddev);
 err_gem_deinit:
 	omap_gem_deinit(ddev);
 	destroy_workqueue(priv->wq);
@@ -642,9 +699,7 @@  static void omapdrm_cleanup(struct omap_drm_private *priv)
 
 	drm_atomic_helper_shutdown(ddev);
 
-	drm_mode_config_cleanup(ddev);
-
-	omap_drm_irq_uninstall(ddev);
+	omap_modeset_fini(ddev);
 	omap_gem_deinit(ddev);
 
 	destroy_workqueue(priv->wq);