Commit f40f4e45 authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Tomi Valkeinen
Browse files

drm/omap: Create connector for bridges



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: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: default avatarTomi Valkeinen <tomi.valkeinen@ti.com>
Tested-by: default avatarSebastian Reichel <sebastian.reichel@collabora.com>
Reviewed-by: default avatarSebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: default avatarTomi Valkeinen <tomi.valkeinen@ti.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200226112514.12455-39-laurent.pinchart@ideasonboard.com
parent 2f004792
Loading
Loading
Loading
Loading
+62 −12
Original line number Diff line number Diff line
@@ -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,10 +293,15 @@ 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);
		pipe->alias_id = id >= 0 ? id : i;
@@ -329,8 +336,23 @@ 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);

		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 +391,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 +417,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 +438,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 +669,7 @@ err_cleanup_helpers:

	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 +694,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);