All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jagan Teki <jagan@amarulasolutions.com>
To: Maxime Ripard <mripard@kernel.org>, Chen-Yu Tsai <wens@csie.org>,
	Laurent Pinchart <Laurent.pinchart@ideasonboard.com>,
	Neil Armstrong <narmstrong@baylibre.com>,
	Robert Foss <robert.foss@linaro.org>,
	Sam Ravnborg <sam@ravnborg.org>
Cc: linux-sunxi@googlegroups.com, linux-amarula@amarulasolutions.com,
	linux-arm-kernel@lists.infradead.org,
	dri-devel@lists.freedesktop.org,
	Jagan Teki <jagan@amarulasolutions.com>
Subject: [PATCH v5 3/7] drm: sun4i: dsi: Convert to bridge driver
Date: Mon, 22 Nov 2021 12:22:19 +0530	[thread overview]
Message-ID: <20211122065223.88059-4-jagan@amarulasolutions.com> (raw)
In-Reply-To: <20211122065223.88059-1-jagan@amarulasolutions.com>

Some display panels would come up with a non-DSI output, those
can have an option to connect the DSI host by means of interface
bridge converter.

This DSI to non-DSI interface bridge converter would requires
DSI Host to handle drm bridge functionalities in order to DSI
Host to Interface bridge.

This patch convert the existing to a drm bridge driver with a
built-in encoder support for compatibility with existing
component drivers.

Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
---
Changes for v5:
- add atomic APIs
- find host and device variant DSI devices.
Changes for v4, v3:
- none

 drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 112 ++++++++++++++++++++-----
 drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h |   7 ++
 2 files changed, 96 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
index 43d9c9e5198d..a6a272b55f77 100644
--- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
+++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
@@ -21,6 +21,7 @@
 
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_mipi_dsi.h>
+#include <drm/drm_of.h>
 #include <drm/drm_panel.h>
 #include <drm/drm_print.h>
 #include <drm/drm_probe_helper.h>
@@ -713,10 +714,11 @@ static int sun6i_dsi_start(struct sun6i_dsi *dsi,
 	return 0;
 }
 
-static void sun6i_dsi_encoder_enable(struct drm_encoder *encoder)
+static void sun6i_dsi_bridge_atomic_enable(struct drm_bridge *bridge,
+					   struct drm_bridge_state *old_bridge_state)
 {
-	struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
-	struct sun6i_dsi *dsi = encoder_to_sun6i_dsi(encoder);
+	struct sun6i_dsi *dsi = bridge_to_sun6i_dsi(bridge);
+	struct drm_display_mode *mode = &bridge->encoder->crtc->state->adjusted_mode;
 	struct mipi_dsi_device *device = dsi->device;
 	union phy_configure_opts opts = { };
 	struct phy_configure_opts_mipi_dphy *cfg = &opts.mipi_dphy;
@@ -772,6 +774,9 @@ static void sun6i_dsi_encoder_enable(struct drm_encoder *encoder)
 	if (dsi->panel)
 		drm_panel_prepare(dsi->panel);
 
+	if (dsi->next_bridge)
+		dsi->next_bridge->funcs->atomic_pre_enable(dsi->next_bridge, old_bridge_state);
+
 	/*
 	 * FIXME: This should be moved after the switch to HS mode.
 	 *
@@ -787,6 +792,9 @@ static void sun6i_dsi_encoder_enable(struct drm_encoder *encoder)
 	if (dsi->panel)
 		drm_panel_enable(dsi->panel);
 
+	if (dsi->next_bridge)
+		dsi->next_bridge->funcs->atomic_enable(dsi->next_bridge, old_bridge_state);
+
 	sun6i_dsi_start(dsi, DSI_START_HSC);
 
 	udelay(1000);
@@ -794,15 +802,19 @@ static void sun6i_dsi_encoder_enable(struct drm_encoder *encoder)
 	sun6i_dsi_start(dsi, DSI_START_HSD);
 }
 
-static void sun6i_dsi_encoder_disable(struct drm_encoder *encoder)
+static void sun6i_dsi_bridge_atomic_disable(struct drm_bridge *bridge,
+					    struct drm_bridge_state *old_bridge_state)
 {
-	struct sun6i_dsi *dsi = encoder_to_sun6i_dsi(encoder);
+	struct sun6i_dsi *dsi = bridge_to_sun6i_dsi(bridge);
 
 	DRM_DEBUG_DRIVER("Disabling DSI output\n");
 
 	if (dsi->panel) {
 		drm_panel_disable(dsi->panel);
 		drm_panel_unprepare(dsi->panel);
+	} else if (dsi->next_bridge) {
+		dsi->next_bridge->funcs->atomic_disable(dsi->next_bridge, old_bridge_state);
+		dsi->next_bridge->funcs->atomic_post_disable(dsi->next_bridge, old_bridge_state);
 	}
 
 	phy_power_off(dsi->dphy);
@@ -842,9 +854,25 @@ static const struct drm_connector_funcs sun6i_dsi_connector_funcs = {
 	.atomic_destroy_state	= drm_atomic_helper_connector_destroy_state,
 };
 
-static const struct drm_encoder_helper_funcs sun6i_dsi_enc_helper_funcs = {
-	.disable	= sun6i_dsi_encoder_disable,
-	.enable		= sun6i_dsi_encoder_enable,
+static int sun6i_dsi_bridge_attach(struct drm_bridge *bridge,
+				   enum drm_bridge_attach_flags flags)
+{
+	struct sun6i_dsi *dsi = bridge_to_sun6i_dsi(bridge);
+
+	if (dsi->next_bridge)
+		return drm_bridge_attach(bridge->encoder, dsi->next_bridge,
+					 NULL, 0);
+
+	return 0;
+}
+
+static const struct drm_bridge_funcs sun6i_dsi_bridge_funcs = {
+	.atomic_duplicate_state	= drm_atomic_helper_bridge_duplicate_state,
+	.atomic_destroy_state	= drm_atomic_helper_bridge_destroy_state,
+	.atomic_reset		= drm_atomic_helper_bridge_reset,
+	.atomic_enable		= sun6i_dsi_bridge_atomic_enable,
+	.atomic_disable		= sun6i_dsi_bridge_atomic_disable,
+	.attach			= sun6i_dsi_bridge_attach,
 };
 
 static u32 sun6i_dsi_dcs_build_pkt_hdr(struct sun6i_dsi *dsi,
@@ -966,8 +994,6 @@ static int sun6i_dsi_bind(struct device *dev, struct device *master,
 	struct sun6i_dsi *dsi = dev_get_drvdata(dev);
 	int ret;
 
-	drm_encoder_helper_add(&dsi->encoder,
-			       &sun6i_dsi_enc_helper_funcs);
 	ret = drm_simple_encoder_init(drm, &dsi->encoder,
 				      DRM_MODE_ENCODER_DSI);
 	if (ret) {
@@ -976,18 +1002,26 @@ static int sun6i_dsi_bind(struct device *dev, struct device *master,
 	}
 	dsi->encoder.possible_crtcs = BIT(0);
 
-	drm_connector_helper_add(&dsi->connector,
-				 &sun6i_dsi_connector_helper_funcs);
-	ret = drm_connector_init(drm, &dsi->connector,
-				 &sun6i_dsi_connector_funcs,
-				 DRM_MODE_CONNECTOR_DSI);
+	ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL, 0);
 	if (ret) {
-		dev_err(dsi->dev,
-			"Couldn't initialise the DSI connector\n");
+		dev_err(dsi->dev, "Couldn't attach drm bridge\n");
 		goto err_cleanup_connector;
 	}
 
-	drm_connector_attach_encoder(&dsi->connector, &dsi->encoder);
+	if (dsi->panel) {
+		drm_connector_helper_add(&dsi->connector,
+					 &sun6i_dsi_connector_helper_funcs);
+		ret = drm_connector_init(drm, &dsi->connector,
+					 &sun6i_dsi_connector_funcs,
+					 DRM_MODE_CONNECTOR_DSI);
+		if (ret) {
+			dev_err(dsi->dev,
+				"Couldn't initialise the DSI connector\n");
+			goto err_cleanup_connector;
+		}
+
+		drm_connector_attach_encoder(&dsi->connector, &dsi->encoder);
+	}
 
 	return 0;
 
@@ -1013,16 +1047,46 @@ static int sun6i_dsi_attach(struct mipi_dsi_host *host,
 			    struct mipi_dsi_device *device)
 {
 	struct sun6i_dsi *dsi = host_to_sun6i_dsi(host);
-	struct drm_panel *panel = of_drm_find_panel(device->dev.of_node);
+	struct device_node *remote = device->dev.of_node;
 	int ret;
 
-	if (IS_ERR(panel))
-		return PTR_ERR(panel);
+	if (!of_device_is_available(remote)) {
+		/**
+		 * I2C interfaced DSI bridges will register DSI host on the
+		 * bridge drivers instead of conventional device.
+		 *
+		 * Those are probed via host of_node instead of device of_node.
+		 */
+		remote = of_graph_get_remote_node(host->dev->of_node, 0, 0);
+		if (!remote)
+			return -ENODEV;
+	}
+
+	dsi->panel = of_drm_find_panel(remote);
+	if (IS_ERR(dsi->panel)) {
+		dsi->panel = NULL;
+
+		dsi->next_bridge = of_drm_find_bridge(remote);
+		if (IS_ERR(dsi->next_bridge)) {
+			dev_err(dsi->dev, "failed to find bridge\n");
+			return PTR_ERR(dsi->next_bridge);
+		}
+	} else {
+		dsi->next_bridge = NULL;
+	}
+
+	of_node_put(remote);
 
-	dsi->panel = panel;
 	dsi->device = device;
 
-	dev_info(host->dev, "Attached device %s\n", device->name);
+	dev_info(host->dev, "Attached %s %s\n",
+		 device->name, dsi->panel ? "panel" : "bridge");
+
+	dsi->bridge.funcs = &sun6i_dsi_bridge_funcs;
+	dsi->bridge.of_node = dsi->dev->of_node;
+	dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
+
+	drm_bridge_add(&dsi->bridge);
 
 	ret = component_add(dsi->dev, &sun6i_dsi_ops);
 	if (ret) {
@@ -1040,9 +1104,11 @@ static int sun6i_dsi_detach(struct mipi_dsi_host *host,
 	struct sun6i_dsi *dsi = host_to_sun6i_dsi(host);
 
 	dsi->panel = NULL;
+	dsi->next_bridge = NULL;
 	dsi->device = NULL;
 
 	component_del(dsi->dev, &sun6i_dsi_ops);
+	drm_bridge_remove(&dsi->bridge);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
index 61e88ea6044d..d269304691c9 100644
--- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
+++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
@@ -16,6 +16,7 @@
 #define SUN6I_DSI_TCON_DIV	4
 
 struct sun6i_dsi {
+	struct drm_bridge	bridge;
 	struct drm_connector	connector;
 	struct drm_encoder	encoder;
 	struct mipi_dsi_host	host;
@@ -30,6 +31,7 @@ struct sun6i_dsi {
 	struct device		*dev;
 	struct mipi_dsi_device	*device;
 	struct drm_panel	*panel;
+	struct drm_bridge	*next_bridge;
 };
 
 static inline struct sun6i_dsi *host_to_sun6i_dsi(struct mipi_dsi_host *host)
@@ -37,6 +39,11 @@ static inline struct sun6i_dsi *host_to_sun6i_dsi(struct mipi_dsi_host *host)
 	return container_of(host, struct sun6i_dsi, host);
 };
 
+static inline struct sun6i_dsi *bridge_to_sun6i_dsi(struct drm_bridge *bridge)
+{
+	return container_of(bridge, struct sun6i_dsi, bridge);
+}
+
 static inline struct sun6i_dsi *connector_to_sun6i_dsi(struct drm_connector *connector)
 {
 	return container_of(connector, struct sun6i_dsi, connector);
-- 
2.25.1


WARNING: multiple messages have this Message-ID (diff)
From: Jagan Teki <jagan@amarulasolutions.com>
To: Maxime Ripard <mripard@kernel.org>, Chen-Yu Tsai <wens@csie.org>,
	Laurent Pinchart <Laurent.pinchart@ideasonboard.com>,
	Neil Armstrong <narmstrong@baylibre.com>,
	Robert Foss <robert.foss@linaro.org>,
	Sam Ravnborg <sam@ravnborg.org>
Cc: dri-devel@lists.freedesktop.org,
	linux-arm-kernel@lists.infradead.org,
	linux-sunxi@googlegroups.com, linux-amarula@amarulasolutions.com,
	Jagan Teki <jagan@amarulasolutions.com>
Subject: [PATCH v5 3/7] drm: sun4i: dsi: Convert to bridge driver
Date: Mon, 22 Nov 2021 12:22:19 +0530	[thread overview]
Message-ID: <20211122065223.88059-4-jagan@amarulasolutions.com> (raw)
In-Reply-To: <20211122065223.88059-1-jagan@amarulasolutions.com>

Some display panels would come up with a non-DSI output, those
can have an option to connect the DSI host by means of interface
bridge converter.

This DSI to non-DSI interface bridge converter would requires
DSI Host to handle drm bridge functionalities in order to DSI
Host to Interface bridge.

This patch convert the existing to a drm bridge driver with a
built-in encoder support for compatibility with existing
component drivers.

Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
---
Changes for v5:
- add atomic APIs
- find host and device variant DSI devices.
Changes for v4, v3:
- none

 drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 112 ++++++++++++++++++++-----
 drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h |   7 ++
 2 files changed, 96 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
index 43d9c9e5198d..a6a272b55f77 100644
--- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
+++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
@@ -21,6 +21,7 @@
 
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_mipi_dsi.h>
+#include <drm/drm_of.h>
 #include <drm/drm_panel.h>
 #include <drm/drm_print.h>
 #include <drm/drm_probe_helper.h>
@@ -713,10 +714,11 @@ static int sun6i_dsi_start(struct sun6i_dsi *dsi,
 	return 0;
 }
 
-static void sun6i_dsi_encoder_enable(struct drm_encoder *encoder)
+static void sun6i_dsi_bridge_atomic_enable(struct drm_bridge *bridge,
+					   struct drm_bridge_state *old_bridge_state)
 {
-	struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
-	struct sun6i_dsi *dsi = encoder_to_sun6i_dsi(encoder);
+	struct sun6i_dsi *dsi = bridge_to_sun6i_dsi(bridge);
+	struct drm_display_mode *mode = &bridge->encoder->crtc->state->adjusted_mode;
 	struct mipi_dsi_device *device = dsi->device;
 	union phy_configure_opts opts = { };
 	struct phy_configure_opts_mipi_dphy *cfg = &opts.mipi_dphy;
@@ -772,6 +774,9 @@ static void sun6i_dsi_encoder_enable(struct drm_encoder *encoder)
 	if (dsi->panel)
 		drm_panel_prepare(dsi->panel);
 
+	if (dsi->next_bridge)
+		dsi->next_bridge->funcs->atomic_pre_enable(dsi->next_bridge, old_bridge_state);
+
 	/*
 	 * FIXME: This should be moved after the switch to HS mode.
 	 *
@@ -787,6 +792,9 @@ static void sun6i_dsi_encoder_enable(struct drm_encoder *encoder)
 	if (dsi->panel)
 		drm_panel_enable(dsi->panel);
 
+	if (dsi->next_bridge)
+		dsi->next_bridge->funcs->atomic_enable(dsi->next_bridge, old_bridge_state);
+
 	sun6i_dsi_start(dsi, DSI_START_HSC);
 
 	udelay(1000);
@@ -794,15 +802,19 @@ static void sun6i_dsi_encoder_enable(struct drm_encoder *encoder)
 	sun6i_dsi_start(dsi, DSI_START_HSD);
 }
 
-static void sun6i_dsi_encoder_disable(struct drm_encoder *encoder)
+static void sun6i_dsi_bridge_atomic_disable(struct drm_bridge *bridge,
+					    struct drm_bridge_state *old_bridge_state)
 {
-	struct sun6i_dsi *dsi = encoder_to_sun6i_dsi(encoder);
+	struct sun6i_dsi *dsi = bridge_to_sun6i_dsi(bridge);
 
 	DRM_DEBUG_DRIVER("Disabling DSI output\n");
 
 	if (dsi->panel) {
 		drm_panel_disable(dsi->panel);
 		drm_panel_unprepare(dsi->panel);
+	} else if (dsi->next_bridge) {
+		dsi->next_bridge->funcs->atomic_disable(dsi->next_bridge, old_bridge_state);
+		dsi->next_bridge->funcs->atomic_post_disable(dsi->next_bridge, old_bridge_state);
 	}
 
 	phy_power_off(dsi->dphy);
@@ -842,9 +854,25 @@ static const struct drm_connector_funcs sun6i_dsi_connector_funcs = {
 	.atomic_destroy_state	= drm_atomic_helper_connector_destroy_state,
 };
 
-static const struct drm_encoder_helper_funcs sun6i_dsi_enc_helper_funcs = {
-	.disable	= sun6i_dsi_encoder_disable,
-	.enable		= sun6i_dsi_encoder_enable,
+static int sun6i_dsi_bridge_attach(struct drm_bridge *bridge,
+				   enum drm_bridge_attach_flags flags)
+{
+	struct sun6i_dsi *dsi = bridge_to_sun6i_dsi(bridge);
+
+	if (dsi->next_bridge)
+		return drm_bridge_attach(bridge->encoder, dsi->next_bridge,
+					 NULL, 0);
+
+	return 0;
+}
+
+static const struct drm_bridge_funcs sun6i_dsi_bridge_funcs = {
+	.atomic_duplicate_state	= drm_atomic_helper_bridge_duplicate_state,
+	.atomic_destroy_state	= drm_atomic_helper_bridge_destroy_state,
+	.atomic_reset		= drm_atomic_helper_bridge_reset,
+	.atomic_enable		= sun6i_dsi_bridge_atomic_enable,
+	.atomic_disable		= sun6i_dsi_bridge_atomic_disable,
+	.attach			= sun6i_dsi_bridge_attach,
 };
 
 static u32 sun6i_dsi_dcs_build_pkt_hdr(struct sun6i_dsi *dsi,
@@ -966,8 +994,6 @@ static int sun6i_dsi_bind(struct device *dev, struct device *master,
 	struct sun6i_dsi *dsi = dev_get_drvdata(dev);
 	int ret;
 
-	drm_encoder_helper_add(&dsi->encoder,
-			       &sun6i_dsi_enc_helper_funcs);
 	ret = drm_simple_encoder_init(drm, &dsi->encoder,
 				      DRM_MODE_ENCODER_DSI);
 	if (ret) {
@@ -976,18 +1002,26 @@ static int sun6i_dsi_bind(struct device *dev, struct device *master,
 	}
 	dsi->encoder.possible_crtcs = BIT(0);
 
-	drm_connector_helper_add(&dsi->connector,
-				 &sun6i_dsi_connector_helper_funcs);
-	ret = drm_connector_init(drm, &dsi->connector,
-				 &sun6i_dsi_connector_funcs,
-				 DRM_MODE_CONNECTOR_DSI);
+	ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL, 0);
 	if (ret) {
-		dev_err(dsi->dev,
-			"Couldn't initialise the DSI connector\n");
+		dev_err(dsi->dev, "Couldn't attach drm bridge\n");
 		goto err_cleanup_connector;
 	}
 
-	drm_connector_attach_encoder(&dsi->connector, &dsi->encoder);
+	if (dsi->panel) {
+		drm_connector_helper_add(&dsi->connector,
+					 &sun6i_dsi_connector_helper_funcs);
+		ret = drm_connector_init(drm, &dsi->connector,
+					 &sun6i_dsi_connector_funcs,
+					 DRM_MODE_CONNECTOR_DSI);
+		if (ret) {
+			dev_err(dsi->dev,
+				"Couldn't initialise the DSI connector\n");
+			goto err_cleanup_connector;
+		}
+
+		drm_connector_attach_encoder(&dsi->connector, &dsi->encoder);
+	}
 
 	return 0;
 
@@ -1013,16 +1047,46 @@ static int sun6i_dsi_attach(struct mipi_dsi_host *host,
 			    struct mipi_dsi_device *device)
 {
 	struct sun6i_dsi *dsi = host_to_sun6i_dsi(host);
-	struct drm_panel *panel = of_drm_find_panel(device->dev.of_node);
+	struct device_node *remote = device->dev.of_node;
 	int ret;
 
-	if (IS_ERR(panel))
-		return PTR_ERR(panel);
+	if (!of_device_is_available(remote)) {
+		/**
+		 * I2C interfaced DSI bridges will register DSI host on the
+		 * bridge drivers instead of conventional device.
+		 *
+		 * Those are probed via host of_node instead of device of_node.
+		 */
+		remote = of_graph_get_remote_node(host->dev->of_node, 0, 0);
+		if (!remote)
+			return -ENODEV;
+	}
+
+	dsi->panel = of_drm_find_panel(remote);
+	if (IS_ERR(dsi->panel)) {
+		dsi->panel = NULL;
+
+		dsi->next_bridge = of_drm_find_bridge(remote);
+		if (IS_ERR(dsi->next_bridge)) {
+			dev_err(dsi->dev, "failed to find bridge\n");
+			return PTR_ERR(dsi->next_bridge);
+		}
+	} else {
+		dsi->next_bridge = NULL;
+	}
+
+	of_node_put(remote);
 
-	dsi->panel = panel;
 	dsi->device = device;
 
-	dev_info(host->dev, "Attached device %s\n", device->name);
+	dev_info(host->dev, "Attached %s %s\n",
+		 device->name, dsi->panel ? "panel" : "bridge");
+
+	dsi->bridge.funcs = &sun6i_dsi_bridge_funcs;
+	dsi->bridge.of_node = dsi->dev->of_node;
+	dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
+
+	drm_bridge_add(&dsi->bridge);
 
 	ret = component_add(dsi->dev, &sun6i_dsi_ops);
 	if (ret) {
@@ -1040,9 +1104,11 @@ static int sun6i_dsi_detach(struct mipi_dsi_host *host,
 	struct sun6i_dsi *dsi = host_to_sun6i_dsi(host);
 
 	dsi->panel = NULL;
+	dsi->next_bridge = NULL;
 	dsi->device = NULL;
 
 	component_del(dsi->dev, &sun6i_dsi_ops);
+	drm_bridge_remove(&dsi->bridge);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
index 61e88ea6044d..d269304691c9 100644
--- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
+++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
@@ -16,6 +16,7 @@
 #define SUN6I_DSI_TCON_DIV	4
 
 struct sun6i_dsi {
+	struct drm_bridge	bridge;
 	struct drm_connector	connector;
 	struct drm_encoder	encoder;
 	struct mipi_dsi_host	host;
@@ -30,6 +31,7 @@ struct sun6i_dsi {
 	struct device		*dev;
 	struct mipi_dsi_device	*device;
 	struct drm_panel	*panel;
+	struct drm_bridge	*next_bridge;
 };
 
 static inline struct sun6i_dsi *host_to_sun6i_dsi(struct mipi_dsi_host *host)
@@ -37,6 +39,11 @@ static inline struct sun6i_dsi *host_to_sun6i_dsi(struct mipi_dsi_host *host)
 	return container_of(host, struct sun6i_dsi, host);
 };
 
+static inline struct sun6i_dsi *bridge_to_sun6i_dsi(struct drm_bridge *bridge)
+{
+	return container_of(bridge, struct sun6i_dsi, bridge);
+}
+
 static inline struct sun6i_dsi *connector_to_sun6i_dsi(struct drm_connector *connector)
 {
 	return container_of(connector, struct sun6i_dsi, connector);
-- 
2.25.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  parent reply	other threads:[~2021-11-22  6:53 UTC|newest]

Thread overview: 72+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-22  6:52 [PATCH v5 0/7] drm: sun4i: dsi: Convert drm bridge Jagan Teki
2021-11-22  6:52 ` Jagan Teki
2021-11-22  6:52 ` [PATCH v5 1/7] drm: sun4i: dsi: Drop DRM bind race with bridge attach Jagan Teki
2021-11-22  6:52   ` Jagan Teki
2021-11-22  6:52 ` [PATCH v5 2/7] drm: sun4i: dsi: Add component only once DSI device attached Jagan Teki
2021-11-22  6:52   ` Jagan Teki
2021-11-22  6:52 ` Jagan Teki [this message]
2021-11-22  6:52   ` [PATCH v5 3/7] drm: sun4i: dsi: Convert to bridge driver Jagan Teki
2021-11-22 10:07   ` Maxime Ripard
2021-11-22 10:07     ` Maxime Ripard
2021-11-22 12:45     ` Laurent Pinchart
2021-11-22 12:45       ` Laurent Pinchart
2021-11-22 13:48     ` Jagan Teki
2021-11-22 13:48       ` Jagan Teki
2021-11-22 14:04       ` Maxime Ripard
2021-11-22 14:04         ` Maxime Ripard
2021-11-22 14:19         ` Jagan Teki
2021-11-22 14:19           ` Jagan Teki
2021-11-22 15:04           ` Maxime Ripard
2021-11-22 15:04             ` Maxime Ripard
2021-11-25 16:17             ` Jagan Teki
2021-11-25 16:17               ` Jagan Teki
2021-11-23 18:32           ` Jagan Teki
2021-11-23 18:32             ` Jagan Teki
2021-11-25 14:15             ` Maxime Ripard
2021-11-25 14:15               ` Maxime Ripard
2021-11-25 14:25               ` Jagan Teki
2021-11-25 14:25                 ` Jagan Teki
2021-11-25 16:10                 ` Maxime Ripard
2021-11-25 16:10                   ` Maxime Ripard
2021-11-25 16:14                   ` Jagan Teki
2021-11-25 16:14                     ` Jagan Teki
2021-11-26 16:04                     ` Maxime Ripard
2021-11-26 16:04                       ` Maxime Ripard
2021-11-30  7:39                       ` Jagan Teki
2021-11-30  7:39                         ` Jagan Teki
2021-12-05 17:39                         ` Michael Nazzareno Trimarchi
2021-12-05 17:39                           ` Michael Nazzareno Trimarchi
2021-11-22 12:52   ` Neil Armstrong
2021-11-22 12:52     ` Neil Armstrong
2021-11-22 13:16     ` Jagan Teki
2021-11-22 13:16       ` Jagan Teki
2021-11-22 15:35       ` Neil Armstrong
2021-11-22 15:35         ` Neil Armstrong
2021-11-22 17:19         ` Dave Stevenson
2021-11-22 17:19           ` Dave Stevenson
2021-11-23  8:19           ` Neil Armstrong
2021-11-23  8:19             ` Neil Armstrong
2021-11-22  6:52 ` [PATCH v5 4/7] drm: sun4i: dsi: Add mode_set function Jagan Teki
2021-11-22  6:52   ` Jagan Teki
2021-11-22 10:07   ` Maxime Ripard
2021-11-22 10:07     ` Maxime Ripard
2021-11-22 13:05     ` Jagan Teki
2021-11-22 13:05       ` Jagan Teki
2021-11-22 13:28       ` Maxime Ripard
2021-11-22 13:28         ` Maxime Ripard
2021-11-22 13:51         ` Jagan Teki
2021-11-22 13:51           ` Jagan Teki
2021-11-22 14:09           ` Maxime Ripard
2021-11-22 14:09             ` Maxime Ripard
2021-11-22 14:31             ` Jagan Teki
2021-11-22 14:31               ` Jagan Teki
2021-11-22 15:06               ` Maxime Ripard
2021-11-22 15:06                 ` Maxime Ripard
2021-11-22 15:17                 ` Jagan Teki
2021-11-22 15:17                   ` Jagan Teki
2021-11-22  6:52 ` [DO NOT MERGE] [PATCH v5 5/7] ARM: dts: sun8i: bananapi-m2m: Enable S070WV20-CT16 Panel Jagan Teki
2021-11-22  6:52   ` Jagan Teki
2021-11-22  6:52 ` [DO NOT MERGE] [PATCH v5 6/7] ARM: dts: sun8i: bananapi-m2m: Enable ICN6211 DSI Bridge Jagan Teki
2021-11-22  6:52   ` Jagan Teki
2021-11-22  6:52 ` [DO NOT MERGE] [PATCH v5 7/7] ARM: dts: sun8i: Enable DLPC3433 Bridge (I2C) Jagan Teki
2021-11-22  6:52   ` Jagan Teki

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211122065223.88059-4-jagan@amarulasolutions.com \
    --to=jagan@amarulasolutions.com \
    --cc=Laurent.pinchart@ideasonboard.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=linux-amarula@amarulasolutions.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-sunxi@googlegroups.com \
    --cc=mripard@kernel.org \
    --cc=narmstrong@baylibre.com \
    --cc=robert.foss@linaro.org \
    --cc=sam@ravnborg.org \
    --cc=wens@csie.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.