All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/4] drm: exynos: dsi: Convert drm bridge
@ 2021-12-10 19:19 Jagan Teki
  2021-12-10 19:19 ` [PATCH v2 1/4] drm: exynos: dsi: Check panel for panel helpers Jagan Teki
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Jagan Teki @ 2021-12-10 19:19 UTC (permalink / raw)
  To: Marek Szyprowski, Andrzej Hajda, Neil Armstrong, Robert Foss,
	Laurent Pinchart, Sam Ravnborg, Michael Nazzareno Trimarchi,
	Inki Dae
  Cc: linux-amarula, Jagan Teki, dri-devel

Updated series about drm bridge conversion of exynos dsi.

Patch 1: panel checker

Patch 2: panel_bridge API

Patch 3: Bridge conversion

Patch 4: Atomic functions

[1] https://patchwork.kernel.org/project/dri-devel/cover/20211122070633.89219-1-jagan@amarulasolutions.com/

Any inputs?
Jagan.

Jagan Teki (4):
  drm: exynos: dsi: Check panel for panel helpers
  drm: exynos: dsi: Use drm panel_bridge API
  drm: exynos: dsi: Convert to bridge driver
  drm: exynos: dsi: Switch to atomic funcs

 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 208 ++++++------------------
 1 file changed, 51 insertions(+), 157 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v2 1/4] drm: exynos: dsi: Check panel for panel helpers
  2021-12-10 19:19 [PATCH v2 0/4] drm: exynos: dsi: Convert drm bridge Jagan Teki
@ 2021-12-10 19:19 ` Jagan Teki
  2021-12-13  8:14   ` Andrzej Hajda
  2021-12-10 19:19 ` [PATCH v2 2/4] drm: exynos: dsi: Use drm panel_bridge API Jagan Teki
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 7+ messages in thread
From: Jagan Teki @ 2021-12-10 19:19 UTC (permalink / raw)
  To: Marek Szyprowski, Andrzej Hajda, Neil Armstrong, Robert Foss,
	Laurent Pinchart, Sam Ravnborg, Michael Nazzareno Trimarchi,
	Inki Dae
  Cc: linux-amarula, Jagan Teki, dri-devel

Trigger the panel operation helpers only if host found the panel.

Add check.

Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
---
Changes for v2:
- new patch 

 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 8d137857818c..0bb44e476633 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -1439,7 +1439,8 @@ static void exynos_dsi_disable(struct drm_encoder *encoder)
 
 	dsi->state &= ~DSIM_STATE_VIDOUT_AVAILABLE;
 
-	drm_panel_disable(dsi->panel);
+	if (dsi->panel)
+		drm_panel_disable(dsi->panel);
 
 	list_for_each_entry_reverse(iter, &dsi->bridge_chain, chain_node) {
 		if (iter->funcs->disable)
@@ -1447,7 +1448,8 @@ static void exynos_dsi_disable(struct drm_encoder *encoder)
 	}
 
 	exynos_dsi_set_display_enable(dsi, false);
-	drm_panel_unprepare(dsi->panel);
+	if (dsi->panel)
+		drm_panel_unprepare(dsi->panel);
 
 	list_for_each_entry(iter, &dsi->bridge_chain, chain_node) {
 		if (iter->funcs->post_disable)
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 2/4] drm: exynos: dsi: Use drm panel_bridge API
  2021-12-10 19:19 [PATCH v2 0/4] drm: exynos: dsi: Convert drm bridge Jagan Teki
  2021-12-10 19:19 ` [PATCH v2 1/4] drm: exynos: dsi: Check panel for panel helpers Jagan Teki
@ 2021-12-10 19:19 ` Jagan Teki
  2021-12-10 19:19 ` [PATCH v2 3/4] drm: exynos: dsi: Convert to bridge driver Jagan Teki
  2021-12-10 19:19 ` [PATCH v2 4/4] drm: exynos: dsi: Switch to atomic funcs Jagan Teki
  3 siblings, 0 replies; 7+ messages in thread
From: Jagan Teki @ 2021-12-10 19:19 UTC (permalink / raw)
  To: Marek Szyprowski, Andrzej Hajda, Neil Armstrong, Robert Foss,
	Laurent Pinchart, Sam Ravnborg, Michael Nazzareno Trimarchi,
	Inki Dae
  Cc: linux-amarula, Jagan Teki, dri-devel

Replace the manual panel handling code by a drm panel_bridge via
devm_drm_of_get_bridge().

Adding panel_bridge handling,

- Drops drm_connector and related operations as drm_bridge_attach
  creates connector during attachment.

- Drops panel pointer and iterate the bridge, so-that it can operate
  the normal bridge and panel_bridge in constitutive callbacks.

This simplifies the driver and allows all components in the display
pipeline to be treated as bridges.

Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
---
Changes for v2:
- new patch

 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 147 +++---------------------
 1 file changed, 14 insertions(+), 133 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 0bb44e476633..8c6f7ac82822 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -254,8 +254,6 @@ struct exynos_dsi_driver_data {
 struct exynos_dsi {
 	struct drm_encoder encoder;
 	struct mipi_dsi_host dsi_host;
-	struct drm_connector connector;
-	struct drm_panel *panel;
 	struct list_head bridge_chain;
 	struct drm_bridge *out_bridge;
 	struct device *dev;
@@ -285,7 +283,6 @@ struct exynos_dsi {
 };
 
 #define host_to_dsi(host) container_of(host, struct exynos_dsi, dsi_host)
-#define connector_to_dsi(c) container_of(c, struct exynos_dsi, connector)
 
 static inline struct exynos_dsi *encoder_to_dsi(struct drm_encoder *e)
 {
@@ -1391,42 +1388,21 @@ static void exynos_dsi_enable(struct drm_encoder *encoder)
 
 	dsi->state |= DSIM_STATE_ENABLED;
 
-	if (dsi->panel) {
-		ret = drm_panel_prepare(dsi->panel);
-		if (ret < 0)
-			goto err_put_sync;
-	} else {
-		list_for_each_entry_reverse(iter, &dsi->bridge_chain,
-					    chain_node) {
-			if (iter->funcs->pre_enable)
-				iter->funcs->pre_enable(iter);
-		}
+	list_for_each_entry_reverse(iter, &dsi->bridge_chain, chain_node) {
+		if (iter->funcs->pre_enable)
+			iter->funcs->pre_enable(iter);
 	}
 
 	exynos_dsi_set_display_mode(dsi);
 	exynos_dsi_set_display_enable(dsi, true);
 
-	if (dsi->panel) {
-		ret = drm_panel_enable(dsi->panel);
-		if (ret < 0)
-			goto err_display_disable;
-	} else {
-		list_for_each_entry(iter, &dsi->bridge_chain, chain_node) {
-			if (iter->funcs->enable)
-				iter->funcs->enable(iter);
-		}
+	list_for_each_entry(iter, &dsi->bridge_chain, chain_node) {
+		if (iter->funcs->enable)
+			iter->funcs->enable(iter);
 	}
 
 	dsi->state |= DSIM_STATE_VIDOUT_AVAILABLE;
 	return;
-
-err_display_disable:
-	exynos_dsi_set_display_enable(dsi, false);
-	drm_panel_unprepare(dsi->panel);
-
-err_put_sync:
-	dsi->state &= ~DSIM_STATE_ENABLED;
-	pm_runtime_put(dsi->dev);
 }
 
 static void exynos_dsi_disable(struct drm_encoder *encoder)
@@ -1439,17 +1415,12 @@ static void exynos_dsi_disable(struct drm_encoder *encoder)
 
 	dsi->state &= ~DSIM_STATE_VIDOUT_AVAILABLE;
 
-	if (dsi->panel)
-		drm_panel_disable(dsi->panel);
-
 	list_for_each_entry_reverse(iter, &dsi->bridge_chain, chain_node) {
 		if (iter->funcs->disable)
 			iter->funcs->disable(iter);
 	}
 
 	exynos_dsi_set_display_enable(dsi, false);
-	if (dsi->panel)
-		drm_panel_unprepare(dsi->panel);
 
 	list_for_each_entry(iter, &dsi->bridge_chain, chain_node) {
 		if (iter->funcs->post_disable)
@@ -1460,70 +1431,6 @@ static void exynos_dsi_disable(struct drm_encoder *encoder)
 	pm_runtime_put_sync(dsi->dev);
 }
 
-static enum drm_connector_status
-exynos_dsi_detect(struct drm_connector *connector, bool force)
-{
-	return connector->status;
-}
-
-static void exynos_dsi_connector_destroy(struct drm_connector *connector)
-{
-	drm_connector_unregister(connector);
-	drm_connector_cleanup(connector);
-	connector->dev = NULL;
-}
-
-static const struct drm_connector_funcs exynos_dsi_connector_funcs = {
-	.detect = exynos_dsi_detect,
-	.fill_modes = drm_helper_probe_single_connector_modes,
-	.destroy = exynos_dsi_connector_destroy,
-	.reset = drm_atomic_helper_connector_reset,
-	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
-	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
-};
-
-static int exynos_dsi_get_modes(struct drm_connector *connector)
-{
-	struct exynos_dsi *dsi = connector_to_dsi(connector);
-
-	if (dsi->panel)
-		return drm_panel_get_modes(dsi->panel, connector);
-
-	return 0;
-}
-
-static const struct drm_connector_helper_funcs exynos_dsi_connector_helper_funcs = {
-	.get_modes = exynos_dsi_get_modes,
-};
-
-static int exynos_dsi_create_connector(struct drm_encoder *encoder)
-{
-	struct exynos_dsi *dsi = encoder_to_dsi(encoder);
-	struct drm_connector *connector = &dsi->connector;
-	struct drm_device *drm = encoder->dev;
-	int ret;
-
-	connector->polled = DRM_CONNECTOR_POLL_HPD;
-
-	ret = drm_connector_init(drm, connector, &exynos_dsi_connector_funcs,
-				 DRM_MODE_CONNECTOR_DSI);
-	if (ret) {
-		DRM_DEV_ERROR(dsi->dev,
-			      "Failed to initialize connector with drm\n");
-		return ret;
-	}
-
-	connector->status = connector_status_disconnected;
-	drm_connector_helper_add(connector, &exynos_dsi_connector_helper_funcs);
-	drm_connector_attach_encoder(connector, encoder);
-	if (!drm->registered)
-		return 0;
-
-	connector->funcs->reset(connector);
-	drm_connector_register(connector);
-	return 0;
-}
-
 static const struct drm_encoder_helper_funcs exynos_dsi_encoder_helper_funcs = {
 	.enable = exynos_dsi_enable,
 	.disable = exynos_dsi_disable,
@@ -1537,30 +1444,13 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
 	struct exynos_dsi *dsi = host_to_dsi(host);
 	struct drm_encoder *encoder = &dsi->encoder;
 	struct drm_device *drm = encoder->dev;
-	struct drm_bridge *out_bridge;
 
-	out_bridge  = of_drm_find_bridge(device->dev.of_node);
-	if (out_bridge) {
-		drm_bridge_attach(encoder, out_bridge, NULL, 0);
-		dsi->out_bridge = out_bridge;
-		list_splice_init(&encoder->bridge_chain, &dsi->bridge_chain);
-	} else {
-		int ret = exynos_dsi_create_connector(encoder);
-
-		if (ret) {
-			DRM_DEV_ERROR(dsi->dev,
-				      "failed to create connector ret = %d\n",
-				      ret);
-			drm_encoder_cleanup(encoder);
-			return ret;
-		}
+	dsi->out_bridge = devm_drm_of_get_bridge(dsi->dev, dsi->dev->of_node, 0, 0);
+	if (IS_ERR(dsi->out_bridge))
+		return PTR_ERR(dsi->out_bridge);
 
-		dsi->panel = of_drm_find_panel(device->dev.of_node);
-		if (IS_ERR(dsi->panel))
-			dsi->panel = NULL;
-		else
-			dsi->connector.status = connector_status_connected;
-	}
+	drm_bridge_attach(encoder, dsi->out_bridge, NULL, 0);
+	list_splice_init(&encoder->bridge_chain, &dsi->bridge_chain);
 
 	/*
 	 * This is a temporary solution and should be made by more generic way.
@@ -1596,18 +1486,9 @@ static int exynos_dsi_host_detach(struct mipi_dsi_host *host,
 	struct exynos_dsi *dsi = host_to_dsi(host);
 	struct drm_device *drm = dsi->encoder.dev;
 
-	if (dsi->panel) {
-		mutex_lock(&drm->mode_config.mutex);
-		exynos_dsi_disable(&dsi->encoder);
-		dsi->panel = NULL;
-		dsi->connector.status = connector_status_disconnected;
-		mutex_unlock(&drm->mode_config.mutex);
-	} else {
-		if (dsi->out_bridge->funcs->detach)
-			dsi->out_bridge->funcs->detach(dsi->out_bridge);
-		dsi->out_bridge = NULL;
-		INIT_LIST_HEAD(&dsi->bridge_chain);
-	}
+	if (dsi->out_bridge->funcs->detach)
+		dsi->out_bridge->funcs->detach(dsi->out_bridge);
+	INIT_LIST_HEAD(&dsi->bridge_chain);
 
 	if (drm->mode_config.poll_enabled)
 		drm_kms_helper_hotplug_event(drm);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 3/4] drm: exynos: dsi: Convert to bridge driver
  2021-12-10 19:19 [PATCH v2 0/4] drm: exynos: dsi: Convert drm bridge Jagan Teki
  2021-12-10 19:19 ` [PATCH v2 1/4] drm: exynos: dsi: Check panel for panel helpers Jagan Teki
  2021-12-10 19:19 ` [PATCH v2 2/4] drm: exynos: dsi: Use drm panel_bridge API Jagan Teki
@ 2021-12-10 19:19 ` Jagan Teki
  2021-12-10 19:19 ` [PATCH v2 4/4] drm: exynos: dsi: Switch to atomic funcs Jagan Teki
  3 siblings, 0 replies; 7+ messages in thread
From: Jagan Teki @ 2021-12-10 19:19 UTC (permalink / raw)
  To: Marek Szyprowski, Andrzej Hajda, Neil Armstrong, Robert Foss,
	Laurent Pinchart, Sam Ravnborg, Michael Nazzareno Trimarchi,
	Inki Dae
  Cc: linux-amarula, Jagan Teki, dri-devel

Convert the encoders to bridge drivers in order to standardize on
a single API with built-in dumb encoder support for compatibility
with existing component drivers.

Driver bridge conversion will help to reuse the same bridge on
different platforms as exynos dsi driver can be used as a Samsung
DSIM and use it for i.MX8MM platform.

Bridge conversion,

- Drops drm_encoder_helper_funcs, bridge_chain.

- Adds drm_bridge_funcs and register a drm bridge.

Convert it.

Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
---
Changes for v2:
- drop bridge_chain

 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 84 +++++++++++++------------
 1 file changed, 45 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 8c6f7ac82822..37ad94b563c4 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -254,7 +254,7 @@ struct exynos_dsi_driver_data {
 struct exynos_dsi {
 	struct drm_encoder encoder;
 	struct mipi_dsi_host dsi_host;
-	struct list_head bridge_chain;
+	struct drm_bridge bridge;
 	struct drm_bridge *out_bridge;
 	struct device *dev;
 
@@ -284,9 +284,9 @@ struct exynos_dsi {
 
 #define host_to_dsi(host) container_of(host, struct exynos_dsi, dsi_host)
 
-static inline struct exynos_dsi *encoder_to_dsi(struct drm_encoder *e)
+static inline struct exynos_dsi *bridge_to_dsi(struct drm_bridge *b)
 {
-	return container_of(e, struct exynos_dsi, encoder);
+	return container_of(b, struct exynos_dsi, bridge);
 }
 
 enum reg_idx {
@@ -877,9 +877,10 @@ static int exynos_dsi_init_link(struct exynos_dsi *dsi)
 	return 0;
 }
 
-static void exynos_dsi_set_display_mode(struct exynos_dsi *dsi)
+static void exynos_dsi_set_display_mode(struct drm_bridge *bridge)
 {
-	struct drm_display_mode *m = &dsi->encoder.crtc->state->adjusted_mode;
+	struct exynos_dsi *dsi = bridge_to_dsi(bridge);
+	struct drm_display_mode *m = &bridge->encoder->crtc->state->adjusted_mode;
 	unsigned int num_bits_resol = dsi->driver_data->num_bits_resol;
 	u32 reg;
 
@@ -1371,10 +1372,10 @@ static void exynos_dsi_unregister_te_irq(struct exynos_dsi *dsi)
 	}
 }
 
-static void exynos_dsi_enable(struct drm_encoder *encoder)
+static void exynos_dsi_enable(struct drm_bridge *bridge)
 {
-	struct exynos_dsi *dsi = encoder_to_dsi(encoder);
-	struct drm_bridge *iter;
+	struct exynos_dsi *dsi = bridge_to_dsi(bridge);
+	const struct drm_bridge_funcs *funcs = dsi->out_bridge->funcs;
 	int ret;
 
 	if (dsi->state & DSIM_STATE_ENABLED)
@@ -1388,52 +1389,53 @@ static void exynos_dsi_enable(struct drm_encoder *encoder)
 
 	dsi->state |= DSIM_STATE_ENABLED;
 
-	list_for_each_entry_reverse(iter, &dsi->bridge_chain, chain_node) {
-		if (iter->funcs->pre_enable)
-			iter->funcs->pre_enable(iter);
-	}
+	if (dsi->out_bridge)
+		funcs->pre_enable(dsi->out_bridge);
 
-	exynos_dsi_set_display_mode(dsi);
+	exynos_dsi_set_display_mode(bridge);
 	exynos_dsi_set_display_enable(dsi, true);
 
-	list_for_each_entry(iter, &dsi->bridge_chain, chain_node) {
-		if (iter->funcs->enable)
-			iter->funcs->enable(iter);
-	}
+	if (dsi->out_bridge)
+		funcs->enable(dsi->out_bridge);
 
 	dsi->state |= DSIM_STATE_VIDOUT_AVAILABLE;
 	return;
 }
 
-static void exynos_dsi_disable(struct drm_encoder *encoder)
+static void exynos_dsi_disable(struct drm_bridge *bridge)
 {
-	struct exynos_dsi *dsi = encoder_to_dsi(encoder);
-	struct drm_bridge *iter;
+	struct exynos_dsi *dsi = bridge_to_dsi(bridge);
+	const struct drm_bridge_funcs *funcs = dsi->out_bridge->funcs;
 
 	if (!(dsi->state & DSIM_STATE_ENABLED))
 		return;
 
 	dsi->state &= ~DSIM_STATE_VIDOUT_AVAILABLE;
 
-	list_for_each_entry_reverse(iter, &dsi->bridge_chain, chain_node) {
-		if (iter->funcs->disable)
-			iter->funcs->disable(iter);
-	}
+	if (dsi->out_bridge)
+		funcs->disable(dsi->out_bridge);
 
 	exynos_dsi_set_display_enable(dsi, false);
 
-	list_for_each_entry(iter, &dsi->bridge_chain, chain_node) {
-		if (iter->funcs->post_disable)
-			iter->funcs->post_disable(iter);
-	}
+	if (dsi->out_bridge)
+		funcs->post_disable(dsi->out_bridge);
 
 	dsi->state &= ~DSIM_STATE_ENABLED;
 	pm_runtime_put_sync(dsi->dev);
 }
 
-static const struct drm_encoder_helper_funcs exynos_dsi_encoder_helper_funcs = {
-	.enable = exynos_dsi_enable,
-	.disable = exynos_dsi_disable,
+static int exynos_dsi_attach(struct drm_bridge *bridge,
+			     enum drm_bridge_attach_flags flags)
+{
+	struct exynos_dsi *dsi = bridge_to_dsi(bridge);
+
+	return drm_bridge_attach(bridge->encoder, dsi->out_bridge, NULL, 0);
+}
+
+static const struct drm_bridge_funcs exynos_dsi_bridge_funcs = {
+	.enable			= exynos_dsi_enable,
+	.disable		= exynos_dsi_disable,
+	.attach			= exynos_dsi_attach,
 };
 
 MODULE_DEVICE_TABLE(of, exynos_dsi_of_match);
@@ -1449,8 +1451,7 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
 	if (IS_ERR(dsi->out_bridge))
 		return PTR_ERR(dsi->out_bridge);
 
-	drm_bridge_attach(encoder, dsi->out_bridge, NULL, 0);
-	list_splice_init(&encoder->bridge_chain, &dsi->bridge_chain);
+	drm_bridge_attach(encoder, &dsi->bridge, NULL, 0);
 
 	/*
 	 * This is a temporary solution and should be made by more generic way.
@@ -1488,7 +1489,6 @@ static int exynos_dsi_host_detach(struct mipi_dsi_host *host,
 
 	if (dsi->out_bridge->funcs->detach)
 		dsi->out_bridge->funcs->detach(dsi->out_bridge);
-	INIT_LIST_HEAD(&dsi->bridge_chain);
 
 	if (drm->mode_config.poll_enabled)
 		drm_kms_helper_hotplug_event(drm);
@@ -1585,8 +1585,6 @@ static int exynos_dsi_bind(struct device *dev, struct device *master,
 
 	drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_TMDS);
 
-	drm_encoder_helper_add(encoder, &exynos_dsi_encoder_helper_funcs);
-
 	ret = exynos_drm_set_possible_crtcs(encoder, EXYNOS_DISPLAY_TYPE_LCD);
 	if (ret < 0)
 		return ret;
@@ -1606,9 +1604,8 @@ static void exynos_dsi_unbind(struct device *dev, struct device *master,
 				void *data)
 {
 	struct exynos_dsi *dsi = dev_get_drvdata(dev);
-	struct drm_encoder *encoder = &dsi->encoder;
 
-	exynos_dsi_disable(encoder);
+	exynos_dsi_disable(&dsi->bridge);
 
 	mipi_dsi_host_unregister(&dsi->dsi_host);
 }
@@ -1634,7 +1631,6 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 	init_completion(&dsi->completed);
 	spin_lock_init(&dsi->transfer_lock);
 	INIT_LIST_HEAD(&dsi->transfer_list);
-	INIT_LIST_HEAD(&dsi->bridge_chain);
 
 	dsi->dsi_host.ops = &exynos_dsi_ops;
 	dsi->dsi_host.dev = dev;
@@ -1702,6 +1698,12 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 
 	pm_runtime_enable(dev);
 
+	dsi->bridge.funcs = &exynos_dsi_bridge_funcs;
+	dsi->bridge.of_node = dev->of_node;
+	dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
+
+	drm_bridge_add(&dsi->bridge);
+
 	ret = component_add(dev, &exynos_dsi_component_ops);
 	if (ret)
 		goto err_disable_runtime;
@@ -1716,6 +1718,10 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 
 static int exynos_dsi_remove(struct platform_device *pdev)
 {
+	struct exynos_dsi *dsi = platform_get_drvdata(pdev);
+
+	drm_bridge_remove(&dsi->bridge);
+
 	pm_runtime_disable(&pdev->dev);
 
 	component_del(&pdev->dev, &exynos_dsi_component_ops);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 4/4] drm: exynos: dsi: Switch to atomic funcs
  2021-12-10 19:19 [PATCH v2 0/4] drm: exynos: dsi: Convert drm bridge Jagan Teki
                   ` (2 preceding siblings ...)
  2021-12-10 19:19 ` [PATCH v2 3/4] drm: exynos: dsi: Convert to bridge driver Jagan Teki
@ 2021-12-10 19:19 ` Jagan Teki
  3 siblings, 0 replies; 7+ messages in thread
From: Jagan Teki @ 2021-12-10 19:19 UTC (permalink / raw)
  To: Marek Szyprowski, Andrzej Hajda, Neil Armstrong, Robert Foss,
	Laurent Pinchart, Sam Ravnborg, Michael Nazzareno Trimarchi,
	Inki Dae
  Cc: linux-amarula, Jagan Teki, dri-devel

The new support drm bridges are moving towards atomic functions.

Replace atomic version of functions to continue the transition
to the atomic API.

Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
---
Changes for v2:
- new patch 

 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 23 ++++++++++++++---------
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 37ad94b563c4..f2c12a356952 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -1372,7 +1372,8 @@ static void exynos_dsi_unregister_te_irq(struct exynos_dsi *dsi)
 	}
 }
 
-static void exynos_dsi_enable(struct drm_bridge *bridge)
+static void exynos_dsi_atomic_enable(struct drm_bridge *bridge,
+				     struct drm_bridge_state *old_bridge_state)
 {
 	struct exynos_dsi *dsi = bridge_to_dsi(bridge);
 	const struct drm_bridge_funcs *funcs = dsi->out_bridge->funcs;
@@ -1390,19 +1391,20 @@ static void exynos_dsi_enable(struct drm_bridge *bridge)
 	dsi->state |= DSIM_STATE_ENABLED;
 
 	if (dsi->out_bridge)
-		funcs->pre_enable(dsi->out_bridge);
+		funcs->atomic_pre_enable(dsi->out_bridge, old_bridge_state);
 
 	exynos_dsi_set_display_mode(bridge);
 	exynos_dsi_set_display_enable(dsi, true);
 
 	if (dsi->out_bridge)
-		funcs->enable(dsi->out_bridge);
+		funcs->atomic_enable(dsi->out_bridge, old_bridge_state);
 
 	dsi->state |= DSIM_STATE_VIDOUT_AVAILABLE;
 	return;
 }
 
-static void exynos_dsi_disable(struct drm_bridge *bridge)
+static void exynos_dsi_atomic_disable(struct drm_bridge *bridge,
+				      struct drm_bridge_state *old_bridge_state)
 {
 	struct exynos_dsi *dsi = bridge_to_dsi(bridge);
 	const struct drm_bridge_funcs *funcs = dsi->out_bridge->funcs;
@@ -1413,12 +1415,12 @@ static void exynos_dsi_disable(struct drm_bridge *bridge)
 	dsi->state &= ~DSIM_STATE_VIDOUT_AVAILABLE;
 
 	if (dsi->out_bridge)
-		funcs->disable(dsi->out_bridge);
+		funcs->atomic_disable(dsi->out_bridge, old_bridge_state);
 
 	exynos_dsi_set_display_enable(dsi, false);
 
 	if (dsi->out_bridge)
-		funcs->post_disable(dsi->out_bridge);
+		funcs->atomic_post_disable(dsi->out_bridge, old_bridge_state);
 
 	dsi->state &= ~DSIM_STATE_ENABLED;
 	pm_runtime_put_sync(dsi->dev);
@@ -1433,8 +1435,11 @@ static int exynos_dsi_attach(struct drm_bridge *bridge,
 }
 
 static const struct drm_bridge_funcs exynos_dsi_bridge_funcs = {
-	.enable			= exynos_dsi_enable,
-	.disable		= exynos_dsi_disable,
+	.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		= exynos_dsi_atomic_enable,
+	.atomic_disable		= exynos_dsi_atomic_disable,
 	.attach			= exynos_dsi_attach,
 };
 
@@ -1605,7 +1610,7 @@ static void exynos_dsi_unbind(struct device *dev, struct device *master,
 {
 	struct exynos_dsi *dsi = dev_get_drvdata(dev);
 
-	exynos_dsi_disable(&dsi->bridge);
+	exynos_dsi_atomic_disable(&dsi->bridge, NULL);
 
 	mipi_dsi_host_unregister(&dsi->dsi_host);
 }
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 1/4] drm: exynos: dsi: Check panel for panel helpers
  2021-12-10 19:19 ` [PATCH v2 1/4] drm: exynos: dsi: Check panel for panel helpers Jagan Teki
@ 2021-12-13  8:14   ` Andrzej Hajda
  2021-12-13  8:27     ` Jagan Teki
  0 siblings, 1 reply; 7+ messages in thread
From: Andrzej Hajda @ 2021-12-13  8:14 UTC (permalink / raw)
  To: Jagan Teki, Marek Szyprowski, Neil Armstrong, Robert Foss,
	Laurent Pinchart, Sam Ravnborg, Michael Nazzareno Trimarchi,
	Inki Dae
  Cc: linux-amarula, dri-devel


On 10.12.2021 20:19, Jagan Teki wrote:
> Trigger the panel operation helpers only if host found the panel.
>
> Add check.
>
> Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>


Both helpers handle already "NULL panels", so these checks are redundant.


Regards

Andrzej

> ---
> Changes for v2:
> - new patch
>
>   drivers/gpu/drm/exynos/exynos_drm_dsi.c | 6 ++++--
>   1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
> index 8d137857818c..0bb44e476633 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
> @@ -1439,7 +1439,8 @@ static void exynos_dsi_disable(struct drm_encoder *encoder)
>   
>   	dsi->state &= ~DSIM_STATE_VIDOUT_AVAILABLE;
>   
> -	drm_panel_disable(dsi->panel);
> +	if (dsi->panel)
> +		drm_panel_disable(dsi->panel);
>   
>   	list_for_each_entry_reverse(iter, &dsi->bridge_chain, chain_node) {
>   		if (iter->funcs->disable)
> @@ -1447,7 +1448,8 @@ static void exynos_dsi_disable(struct drm_encoder *encoder)
>   	}
>   
>   	exynos_dsi_set_display_enable(dsi, false);
> -	drm_panel_unprepare(dsi->panel);
> +	if (dsi->panel)
> +		drm_panel_unprepare(dsi->panel);
>   
>   	list_for_each_entry(iter, &dsi->bridge_chain, chain_node) {
>   		if (iter->funcs->post_disable)

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 1/4] drm: exynos: dsi: Check panel for panel helpers
  2021-12-13  8:14   ` Andrzej Hajda
@ 2021-12-13  8:27     ` Jagan Teki
  0 siblings, 0 replies; 7+ messages in thread
From: Jagan Teki @ 2021-12-13  8:27 UTC (permalink / raw)
  To: Andrzej Hajda
  Cc: Neil Armstrong, linux-amarula, dri-devel, Robert Foss,
	Laurent Pinchart, Michael Nazzareno Trimarchi, Sam Ravnborg,
	Marek Szyprowski

Hi Andrzej,

On Mon, Dec 13, 2021 at 1:44 PM Andrzej Hajda <andrzej.hajda@intel.com> wrote:
>
>
> On 10.12.2021 20:19, Jagan Teki wrote:
> > Trigger the panel operation helpers only if host found the panel.
> >
> > Add check.
> >
> > Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
>
>
> Both helpers handle already "NULL panels", so these checks are redundant.

Got it. Please look at v3 if you have time.

Thanks,
Jagan.

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2021-12-13  8:28 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-10 19:19 [PATCH v2 0/4] drm: exynos: dsi: Convert drm bridge Jagan Teki
2021-12-10 19:19 ` [PATCH v2 1/4] drm: exynos: dsi: Check panel for panel helpers Jagan Teki
2021-12-13  8:14   ` Andrzej Hajda
2021-12-13  8:27     ` Jagan Teki
2021-12-10 19:19 ` [PATCH v2 2/4] drm: exynos: dsi: Use drm panel_bridge API Jagan Teki
2021-12-10 19:19 ` [PATCH v2 3/4] drm: exynos: dsi: Convert to bridge driver Jagan Teki
2021-12-10 19:19 ` [PATCH v2 4/4] drm: exynos: dsi: Switch to atomic funcs Jagan Teki

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.