dri-devel.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/7] Convert mtk-dsi to drm_bridge API and get EDID for ps8640 bridge
@ 2020-04-16 15:57 Enric Balletbo i Serra
  2020-04-16 15:57 ` [PATCH v2 1/7] drm/bridge: ps8640: Get the EDID from eDP control Enric Balletbo i Serra
                   ` (6 more replies)
  0 siblings, 7 replies; 19+ messages in thread
From: Enric Balletbo i Serra @ 2020-04-16 15:57 UTC (permalink / raw)
  To: linux-kernel
  Cc: Chun-Kuang Hu, Jernej Skrabec, drinkcat, Jonas Karlman,
	David Airlie, Thomas Zimmermann, dri-devel, Neil Armstrong,
	Andrzej Hajda, linux-mediatek, Laurent Pinchart, hsinyi,
	matthias.bgg, Collabora Kernel ML, linux-arm-kernel


The PS8640 dsi-to-eDP bridge driver is using the panel bridge API,
however, not all the components in the chain have been ported to the
drm_bridge API. Actually, when a panel is attached the default panel's mode
is used, but in some cases we can't get display up if mode getting from
eDP control EDID is not chosen.

This series address that problem, first implements the .get_edid()
callback in the PS8640 driver (which is not used until the conversion is
done) and then, converts the Mediatek DSI driver to use the drm_bridge
API.

As far as I know, we're the only users of the mediatek dsi driver in
mainline, so should be safe to switch to the new chain of drm_bridge API
unconditionally.

The patches has been tested on a Acer Chromebook R13 (Elm) running a
Chrome OS userspace and checking that the valid EDID mode reported by
the bridge is selected.

[1] https://lore.kernel.org/lkml/20200210063523.133333-1-hsinyi@chromium.org/

Changes in v2:
- Do not set connector_type for panel here. (Sam Ravnborg)

Enric Balletbo i Serra (7):
  drm/bridge: ps8640: Get the EDID from eDP control
  drm/bridge_connector: Set default status connected for eDP connectors
  drm/mediatek: mtk_dsi: Rename bridge to next_bridge
  drm/mediatek: mtk_dsi: Convert to bridge driver
  drm/mediatek: mtk_dsi: Use simple encoder
  drm/mediatek: mtk_dsi: Use the drm_panel_bridge API
  drm/mediatek: mtk_dsi: Create connector for bridges

 drivers/gpu/drm/bridge/parade-ps8640.c |  12 ++
 drivers/gpu/drm/drm_bridge_connector.c |   1 +
 drivers/gpu/drm/mediatek/mtk_dsi.c     | 280 ++++++++-----------------
 3 files changed, 101 insertions(+), 192 deletions(-)

-- 
2.25.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH v2 1/7] drm/bridge: ps8640: Get the EDID from eDP control
  2020-04-16 15:57 [PATCH v2 0/7] Convert mtk-dsi to drm_bridge API and get EDID for ps8640 bridge Enric Balletbo i Serra
@ 2020-04-16 15:57 ` Enric Balletbo i Serra
  2020-04-16 17:22   ` Laurent Pinchart
  2020-04-16 15:57 ` [PATCH v2 2/7] drm/bridge_connector: Set default status connected for eDP connectors Enric Balletbo i Serra
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 19+ messages in thread
From: Enric Balletbo i Serra @ 2020-04-16 15:57 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jernej Skrabec, drinkcat, Jonas Karlman, David Airlie,
	Neil Armstrong, dri-devel, Andrzej Hajda, Laurent Pinchart,
	hsinyi, matthias.bgg, Collabora Kernel ML

The PS8640 DSI-to-eDP bridge can retrieve the EDID, so implement the
.get_edid callback and set the flag to indicate the core to use it.

Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
---

Changes in v2: None

 drivers/gpu/drm/bridge/parade-ps8640.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/bridge/parade-ps8640.c b/drivers/gpu/drm/bridge/parade-ps8640.c
index d3a53442d449..956b76e0a44d 100644
--- a/drivers/gpu/drm/bridge/parade-ps8640.c
+++ b/drivers/gpu/drm/bridge/parade-ps8640.c
@@ -242,8 +242,18 @@ static int ps8640_bridge_attach(struct drm_bridge *bridge,
 	return ret;
 }
 
+static struct edid *ps8640_bridge_get_edid(struct drm_bridge *bridge,
+					   struct drm_connector *connector)
+{
+	struct ps8640 *ps_bridge = bridge_to_ps8640(bridge);
+
+	return drm_get_edid(connector,
+			    ps_bridge->page[PAGE0_DP_CNTL]->adapter);
+}
+
 static const struct drm_bridge_funcs ps8640_bridge_funcs = {
 	.attach = ps8640_bridge_attach,
+	.get_edid = ps8640_bridge_get_edid,
 	.post_disable = ps8640_post_disable,
 	.pre_enable = ps8640_pre_enable,
 };
@@ -296,6 +306,8 @@ static int ps8640_probe(struct i2c_client *client)
 
 	ps_bridge->bridge.funcs = &ps8640_bridge_funcs;
 	ps_bridge->bridge.of_node = dev->of_node;
+	ps_bridge->bridge.ops = DRM_BRIDGE_OP_EDID;
+	ps_bridge->bridge.type = DRM_MODE_CONNECTOR_eDP;
 
 	ps_bridge->page[PAGE0_DP_CNTL] = client;
 
-- 
2.25.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH v2 2/7] drm/bridge_connector: Set default status connected for eDP connectors
  2020-04-16 15:57 [PATCH v2 0/7] Convert mtk-dsi to drm_bridge API and get EDID for ps8640 bridge Enric Balletbo i Serra
  2020-04-16 15:57 ` [PATCH v2 1/7] drm/bridge: ps8640: Get the EDID from eDP control Enric Balletbo i Serra
@ 2020-04-16 15:57 ` Enric Balletbo i Serra
  2020-04-16 17:22   ` Laurent Pinchart
  2020-04-16 15:57 ` [PATCH v2 3/7] drm/mediatek: mtk_dsi: Rename bridge to next_bridge Enric Balletbo i Serra
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 19+ messages in thread
From: Enric Balletbo i Serra @ 2020-04-16 15:57 UTC (permalink / raw)
  To: linux-kernel
  Cc: drinkcat, Thomas Zimmermann, David Airlie, dri-devel,
	laurent.pinchart, hsinyi, matthias.bgg, Collabora Kernel ML

In an eDP application, HPD is not required and on most bridge chips
useless. If HPD is not used, we need to set initial status as connected,
otherwise the connector created by the drm_bridge_connector API remains
in an unknown state.

Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
---

Changes in v2: None

 drivers/gpu/drm/drm_bridge_connector.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/drm_bridge_connector.c b/drivers/gpu/drm/drm_bridge_connector.c
index c6994fe673f3..a58cbde59c34 100644
--- a/drivers/gpu/drm/drm_bridge_connector.c
+++ b/drivers/gpu/drm/drm_bridge_connector.c
@@ -187,6 +187,7 @@ drm_bridge_connector_detect(struct drm_connector *connector, bool force)
 		case DRM_MODE_CONNECTOR_DPI:
 		case DRM_MODE_CONNECTOR_LVDS:
 		case DRM_MODE_CONNECTOR_DSI:
+		case DRM_MODE_CONNECTOR_eDP:
 			status = connector_status_connected;
 			break;
 		default:
-- 
2.25.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH v2 3/7] drm/mediatek: mtk_dsi: Rename bridge to next_bridge
  2020-04-16 15:57 [PATCH v2 0/7] Convert mtk-dsi to drm_bridge API and get EDID for ps8640 bridge Enric Balletbo i Serra
  2020-04-16 15:57 ` [PATCH v2 1/7] drm/bridge: ps8640: Get the EDID from eDP control Enric Balletbo i Serra
  2020-04-16 15:57 ` [PATCH v2 2/7] drm/bridge_connector: Set default status connected for eDP connectors Enric Balletbo i Serra
@ 2020-04-16 15:57 ` Enric Balletbo i Serra
  2020-04-16 17:24   ` Laurent Pinchart
  2020-04-16 15:57 ` [PATCH v2 4/7] drm/mediatek: mtk_dsi: Convert to bridge driver Enric Balletbo i Serra
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 19+ messages in thread
From: Enric Balletbo i Serra @ 2020-04-16 15:57 UTC (permalink / raw)
  To: linux-kernel
  Cc: Chun-Kuang Hu, drinkcat, David Airlie, dri-devel, linux-mediatek,
	laurent.pinchart, hsinyi, matthias.bgg, Collabora Kernel ML,
	linux-arm-kernel

This is really a cosmetic change just to make a bit more readable the
code after convert the driver to drm_bridge. The bridge variable name
will be used by the encoder drm_bridge, and the chained bridge will be
named next_bridge.

Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
---

Changes in v2: None

 drivers/gpu/drm/mediatek/mtk_dsi.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index cfa45d6abd74..44ee884cc31c 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -182,7 +182,7 @@ struct mtk_dsi {
 	struct drm_encoder encoder;
 	struct drm_connector conn;
 	struct drm_panel *panel;
-	struct drm_bridge *bridge;
+	struct drm_bridge *next_bridge;
 	struct phy *phy;
 
 	void __iomem *regs;
@@ -903,8 +903,9 @@ static int mtk_dsi_create_conn_enc(struct drm_device *drm, struct mtk_dsi *dsi)
 	dsi->encoder.possible_crtcs = 1;
 
 	/* If there's a bridge, attach to it and let it create the connector */
-	if (dsi->bridge) {
-		ret = drm_bridge_attach(&dsi->encoder, dsi->bridge, NULL, 0);
+	if (dsi->next_bridge) {
+		ret = drm_bridge_attach(&dsi->encoder, dsi->next_bridge, NULL,
+					0);
 		if (ret) {
 			DRM_ERROR("Failed to attach bridge to drm\n");
 			goto err_encoder_cleanup;
@@ -1185,7 +1186,7 @@ static int mtk_dsi_probe(struct platform_device *pdev)
 	}
 
 	ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0,
-					  &dsi->panel, &dsi->bridge);
+					  &dsi->panel, &dsi->next_bridge);
 	if (ret)
 		goto err_unregister_host;
 
-- 
2.25.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH v2 4/7] drm/mediatek: mtk_dsi: Convert to bridge driver
  2020-04-16 15:57 [PATCH v2 0/7] Convert mtk-dsi to drm_bridge API and get EDID for ps8640 bridge Enric Balletbo i Serra
                   ` (2 preceding siblings ...)
  2020-04-16 15:57 ` [PATCH v2 3/7] drm/mediatek: mtk_dsi: Rename bridge to next_bridge Enric Balletbo i Serra
@ 2020-04-16 15:57 ` Enric Balletbo i Serra
  2020-04-16 15:57 ` [PATCH v2 5/7] drm/mediatek: mtk_dsi: Use simple encoder Enric Balletbo i Serra
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 19+ messages in thread
From: Enric Balletbo i Serra @ 2020-04-16 15:57 UTC (permalink / raw)
  To: linux-kernel
  Cc: Chun-Kuang Hu, drinkcat, David Airlie, dri-devel, linux-mediatek,
	laurent.pinchart, hsinyi, matthias.bgg, Collabora Kernel ML,
	linux-arm-kernel

Convert mtk_dsi to a bridge driver with built-in encoder support for
compatibility with existing component drivers.

Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
---

Changes in v2: None

 drivers/gpu/drm/mediatek/mtk_dsi.c | 106 ++++++++++++++++++-----------
 1 file changed, 68 insertions(+), 38 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 44ee884cc31c..3400d6686c85 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -180,6 +180,7 @@ struct mtk_dsi {
 	struct device *dev;
 	struct mipi_dsi_host host;
 	struct drm_encoder encoder;
+	struct drm_bridge bridge;
 	struct drm_connector conn;
 	struct drm_panel *panel;
 	struct drm_bridge *next_bridge;
@@ -205,9 +206,9 @@ struct mtk_dsi {
 	const struct mtk_dsi_driver_data *driver_data;
 };
 
-static inline struct mtk_dsi *encoder_to_dsi(struct drm_encoder *e)
+static inline struct mtk_dsi *bridge_to_dsi(struct drm_bridge *b)
 {
-	return container_of(e, struct mtk_dsi, encoder);
+	return container_of(b, struct mtk_dsi, bridge);
 }
 
 static inline struct mtk_dsi *connector_to_dsi(struct drm_connector *c)
@@ -796,32 +797,43 @@ static const struct drm_encoder_funcs mtk_dsi_encoder_funcs = {
 	.destroy = mtk_dsi_encoder_destroy,
 };
 
-static bool mtk_dsi_encoder_mode_fixup(struct drm_encoder *encoder,
-				       const struct drm_display_mode *mode,
-				       struct drm_display_mode *adjusted_mode)
+static int mtk_dsi_create_conn_enc(struct drm_device *drm, struct mtk_dsi *dsi);
+static void mtk_dsi_destroy_conn_enc(struct mtk_dsi *dsi);
+
+static int mtk_dsi_bridge_attach(struct drm_bridge *bridge,
+				 enum drm_bridge_attach_flags flags)
 {
-	return true;
+	struct mtk_dsi *dsi = bridge_to_dsi(bridge);
+
+	return mtk_dsi_create_conn_enc(bridge->dev, dsi);
+}
+
+static void mtk_dsi_bridge_detach(struct drm_bridge *bridge)
+{
+	struct mtk_dsi *dsi = bridge_to_dsi(bridge);
+
+	mtk_dsi_destroy_conn_enc(dsi);
 }
 
-static void mtk_dsi_encoder_mode_set(struct drm_encoder *encoder,
-				     struct drm_display_mode *mode,
-				     struct drm_display_mode *adjusted)
+static void mtk_dsi_bridge_mode_set(struct drm_bridge *bridge,
+				    const struct drm_display_mode *mode,
+				    const struct drm_display_mode *adjusted)
 {
-	struct mtk_dsi *dsi = encoder_to_dsi(encoder);
+	struct mtk_dsi *dsi = bridge_to_dsi(bridge);
 
 	drm_display_mode_to_videomode(adjusted, &dsi->vm);
 }
 
-static void mtk_dsi_encoder_disable(struct drm_encoder *encoder)
+static void mtk_dsi_bridge_disable(struct drm_bridge *bridge)
 {
-	struct mtk_dsi *dsi = encoder_to_dsi(encoder);
+	struct mtk_dsi *dsi = bridge_to_dsi(bridge);
 
 	mtk_output_dsi_disable(dsi);
 }
 
-static void mtk_dsi_encoder_enable(struct drm_encoder *encoder)
+static void mtk_dsi_bridge_enable(struct drm_bridge *bridge)
 {
-	struct mtk_dsi *dsi = encoder_to_dsi(encoder);
+	struct mtk_dsi *dsi = bridge_to_dsi(bridge);
 
 	mtk_output_dsi_enable(dsi);
 }
@@ -833,11 +845,12 @@ static int mtk_dsi_connector_get_modes(struct drm_connector *connector)
 	return drm_panel_get_modes(dsi->panel, connector);
 }
 
-static const struct drm_encoder_helper_funcs mtk_dsi_encoder_helper_funcs = {
-	.mode_fixup = mtk_dsi_encoder_mode_fixup,
-	.mode_set = mtk_dsi_encoder_mode_set,
-	.disable = mtk_dsi_encoder_disable,
-	.enable = mtk_dsi_encoder_enable,
+static const struct drm_bridge_funcs mtk_dsi_bridge_funcs = {
+	.attach = mtk_dsi_bridge_attach,
+	.detach = mtk_dsi_bridge_detach,
+	.disable = mtk_dsi_bridge_disable,
+	.enable = mtk_dsi_bridge_enable,
+	.mode_set = mtk_dsi_bridge_mode_set,
 };
 
 static const struct drm_connector_funcs mtk_dsi_connector_funcs = {
@@ -888,20 +901,6 @@ static int mtk_dsi_create_conn_enc(struct drm_device *drm, struct mtk_dsi *dsi)
 {
 	int ret;
 
-	ret = drm_encoder_init(drm, &dsi->encoder, &mtk_dsi_encoder_funcs,
-			       DRM_MODE_ENCODER_DSI, NULL);
-	if (ret) {
-		DRM_ERROR("Failed to encoder init to drm\n");
-		return ret;
-	}
-	drm_encoder_helper_add(&dsi->encoder, &mtk_dsi_encoder_helper_funcs);
-
-	/*
-	 * Currently display data paths are statically assigned to a crtc each.
-	 * crtc 0 is OVL0 -> COLOR0 -> AAL -> OD -> RDMA0 -> UFOE -> DSI0
-	 */
-	dsi->encoder.possible_crtcs = 1;
-
 	/* If there's a bridge, attach to it and let it create the connector */
 	if (dsi->next_bridge) {
 		ret = drm_bridge_attach(&dsi->encoder, dsi->next_bridge, NULL,
@@ -1123,6 +1122,34 @@ static const struct mipi_dsi_host_ops mtk_dsi_ops = {
 	.transfer = mtk_dsi_host_transfer,
 };
 
+static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi)
+{
+	int ret;
+
+	ret = drm_encoder_init(drm, &dsi->encoder, &mtk_dsi_encoder_funcs,
+			       DRM_MODE_ENCODER_DSI, NULL);
+	if (ret) {
+		DRM_ERROR("Failed to encoder init to drm\n");
+		return ret;
+	}
+
+	/*
+	 * Currently display data paths are statically assigned to a crtc each.
+	 * crtc 0 is OVL0 -> COLOR0 -> AAL -> OD -> RDMA0 -> UFOE -> DSI0
+	 */
+	dsi->encoder.possible_crtcs = 1;
+
+	ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL, 0);
+	if (ret)
+		goto err_cleanup_encoder;
+
+	return 0;
+
+err_cleanup_encoder:
+	drm_encoder_cleanup(&dsi->encoder);
+	return ret;
+}
+
 static int mtk_dsi_bind(struct device *dev, struct device *master, void *data)
 {
 	int ret;
@@ -1136,11 +1163,9 @@ static int mtk_dsi_bind(struct device *dev, struct device *master, void *data)
 		return ret;
 	}
 
-	ret = mtk_dsi_create_conn_enc(drm, dsi);
-	if (ret) {
-		DRM_ERROR("Encoder create failed with %d\n", ret);
+	ret = mtk_dsi_encoder_init(drm, dsi);
+	if (ret)
 		goto err_unregister;
-	}
 
 	return 0;
 
@@ -1155,7 +1180,6 @@ static void mtk_dsi_unbind(struct device *dev, struct device *master,
 	struct drm_device *drm = data;
 	struct mtk_dsi *dsi = dev_get_drvdata(dev);
 
-	mtk_dsi_destroy_conn_enc(dsi);
 	mtk_ddp_comp_unregister(drm, &dsi->ddp_comp);
 }
 
@@ -1265,6 +1289,11 @@ static int mtk_dsi_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, dsi);
 
+	dsi->bridge.funcs = &mtk_dsi_bridge_funcs;
+	dsi->bridge.of_node = dev->of_node;
+
+	drm_bridge_add(&dsi->bridge);
+
 	ret = component_add(&pdev->dev, &mtk_dsi_component_ops);
 	if (ret) {
 		dev_err(&pdev->dev, "failed to add component: %d\n", ret);
@@ -1283,6 +1312,7 @@ static int mtk_dsi_remove(struct platform_device *pdev)
 	struct mtk_dsi *dsi = platform_get_drvdata(pdev);
 
 	mtk_output_dsi_disable(dsi);
+	drm_bridge_remove(&dsi->bridge);
 	component_del(&pdev->dev, &mtk_dsi_component_ops);
 	mipi_dsi_host_unregister(&dsi->host);
 
-- 
2.25.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH v2 5/7] drm/mediatek: mtk_dsi: Use simple encoder
  2020-04-16 15:57 [PATCH v2 0/7] Convert mtk-dsi to drm_bridge API and get EDID for ps8640 bridge Enric Balletbo i Serra
                   ` (3 preceding siblings ...)
  2020-04-16 15:57 ` [PATCH v2 4/7] drm/mediatek: mtk_dsi: Convert to bridge driver Enric Balletbo i Serra
@ 2020-04-16 15:57 ` Enric Balletbo i Serra
  2020-04-16 17:28   ` Laurent Pinchart
  2020-04-16 15:57 ` [PATCH v2 6/7] drm/mediatek: mtk_dsi: Use the drm_panel_bridge API Enric Balletbo i Serra
  2020-04-16 15:57 ` [PATCH v2 7/7] drm/mediatek: mtk_dsi: Create connector for bridges Enric Balletbo i Serra
  6 siblings, 1 reply; 19+ messages in thread
From: Enric Balletbo i Serra @ 2020-04-16 15:57 UTC (permalink / raw)
  To: linux-kernel
  Cc: Chun-Kuang Hu, drinkcat, David Airlie, dri-devel, linux-mediatek,
	laurent.pinchart, hsinyi, matthias.bgg, Collabora Kernel ML,
	linux-arm-kernel

The mtk_dsi driver uses an empty implementation for its encoder. Replace
the code with the generic simple encoder.

Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
---

Changes in v2: None

 drivers/gpu/drm/mediatek/mtk_dsi.c | 14 +++-----------
 1 file changed, 3 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 3400d6686c85..48361c1e9f34 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -22,6 +22,7 @@
 #include <drm/drm_panel.h>
 #include <drm/drm_print.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
 
 #include "mtk_drm_ddp_comp.h"
 
@@ -788,15 +789,6 @@ static void mtk_output_dsi_disable(struct mtk_dsi *dsi)
 	dsi->enabled = false;
 }
 
-static void mtk_dsi_encoder_destroy(struct drm_encoder *encoder)
-{
-	drm_encoder_cleanup(encoder);
-}
-
-static const struct drm_encoder_funcs mtk_dsi_encoder_funcs = {
-	.destroy = mtk_dsi_encoder_destroy,
-};
-
 static int mtk_dsi_create_conn_enc(struct drm_device *drm, struct mtk_dsi *dsi);
 static void mtk_dsi_destroy_conn_enc(struct mtk_dsi *dsi);
 
@@ -1126,8 +1118,8 @@ static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi)
 {
 	int ret;
 
-	ret = drm_encoder_init(drm, &dsi->encoder, &mtk_dsi_encoder_funcs,
-			       DRM_MODE_ENCODER_DSI, NULL);
+	ret = drm_simple_encoder_init(drm, &dsi->encoder,
+				      DRM_MODE_ENCODER_DSI);
 	if (ret) {
 		DRM_ERROR("Failed to encoder init to drm\n");
 		return ret;
-- 
2.25.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH v2 6/7] drm/mediatek: mtk_dsi: Use the drm_panel_bridge API
  2020-04-16 15:57 [PATCH v2 0/7] Convert mtk-dsi to drm_bridge API and get EDID for ps8640 bridge Enric Balletbo i Serra
                   ` (4 preceding siblings ...)
  2020-04-16 15:57 ` [PATCH v2 5/7] drm/mediatek: mtk_dsi: Use simple encoder Enric Balletbo i Serra
@ 2020-04-16 15:57 ` Enric Balletbo i Serra
  2020-04-16 17:33   ` Laurent Pinchart
  2020-04-16 15:57 ` [PATCH v2 7/7] drm/mediatek: mtk_dsi: Create connector for bridges Enric Balletbo i Serra
  6 siblings, 1 reply; 19+ messages in thread
From: Enric Balletbo i Serra @ 2020-04-16 15:57 UTC (permalink / raw)
  To: linux-kernel
  Cc: Chun-Kuang Hu, drinkcat, David Airlie, dri-devel, linux-mediatek,
	laurent.pinchart, hsinyi, matthias.bgg, Collabora Kernel ML,
	linux-arm-kernel

Replace the manual panel handling code by a drm_panel_bridge. This
simplifies the driver and allows all components in the display pipeline
to be treated as bridges, paving the way to generic connector handling.

Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
---

Changes in v2:
- Do not set connector_type for panel here. (Sam Ravnborg)

 drivers/gpu/drm/mediatek/mtk_dsi.c | 177 ++++-------------------------
 1 file changed, 19 insertions(+), 158 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 48361c1e9f34..44718fa3d1ca 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -182,8 +182,7 @@ struct mtk_dsi {
 	struct mipi_dsi_host host;
 	struct drm_encoder encoder;
 	struct drm_bridge bridge;
-	struct drm_connector conn;
-	struct drm_panel *panel;
+	struct drm_bridge *panel_bridge;
 	struct drm_bridge *next_bridge;
 	struct phy *phy;
 
@@ -212,11 +211,6 @@ static inline struct mtk_dsi *bridge_to_dsi(struct drm_bridge *b)
 	return container_of(b, struct mtk_dsi, bridge);
 }
 
-static inline struct mtk_dsi *connector_to_dsi(struct drm_connector *c)
-{
-	return container_of(c, struct mtk_dsi, conn);
-}
-
 static inline struct mtk_dsi *host_to_dsi(struct mipi_dsi_host *h)
 {
 	return container_of(h, struct mtk_dsi, host);
@@ -682,16 +676,7 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
 	mtk_dsi_lane0_ulp_mode_leave(dsi);
 	mtk_dsi_clk_hs_mode(dsi, 0);
 
-	if (dsi->panel) {
-		if (drm_panel_prepare(dsi->panel)) {
-			DRM_ERROR("failed to prepare the panel\n");
-			goto err_disable_digital_clk;
-		}
-	}
-
 	return 0;
-err_disable_digital_clk:
-	clk_disable_unprepare(dsi->digital_clk);
 err_disable_engine_clk:
 	clk_disable_unprepare(dsi->engine_clk);
 err_phy_power_off:
@@ -718,15 +703,7 @@ static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
 	 */
 	mtk_dsi_stop(dsi);
 
-	if (!mtk_dsi_switch_to_cmd_mode(dsi, VM_DONE_INT_FLAG, 500)) {
-		if (dsi->panel) {
-			if (drm_panel_unprepare(dsi->panel)) {
-				DRM_ERROR("failed to unprepare the panel\n");
-				return;
-			}
-		}
-	}
-
+	mtk_dsi_switch_to_cmd_mode(dsi, VM_DONE_INT_FLAG, 500);
 	mtk_dsi_reset_engine(dsi);
 	mtk_dsi_lane0_ulp_mode_enter(dsi);
 	mtk_dsi_clk_ulp_mode_enter(dsi);
@@ -757,19 +734,7 @@ static void mtk_output_dsi_enable(struct mtk_dsi *dsi)
 
 	mtk_dsi_start(dsi);
 
-	if (dsi->panel) {
-		if (drm_panel_enable(dsi->panel)) {
-			DRM_ERROR("failed to enable the panel\n");
-			goto err_dsi_power_off;
-		}
-	}
-
 	dsi->enabled = true;
-
-	return;
-err_dsi_power_off:
-	mtk_dsi_stop(dsi);
-	mtk_dsi_poweroff(dsi);
 }
 
 static void mtk_output_dsi_disable(struct mtk_dsi *dsi)
@@ -777,34 +742,24 @@ static void mtk_output_dsi_disable(struct mtk_dsi *dsi)
 	if (!dsi->enabled)
 		return;
 
-	if (dsi->panel) {
-		if (drm_panel_disable(dsi->panel)) {
-			DRM_ERROR("failed to disable the panel\n");
-			return;
-		}
-	}
-
 	mtk_dsi_poweroff(dsi);
 
 	dsi->enabled = false;
 }
 
-static int mtk_dsi_create_conn_enc(struct drm_device *drm, struct mtk_dsi *dsi);
-static void mtk_dsi_destroy_conn_enc(struct mtk_dsi *dsi);
-
 static int mtk_dsi_bridge_attach(struct drm_bridge *bridge,
 				 enum drm_bridge_attach_flags flags)
 {
 	struct mtk_dsi *dsi = bridge_to_dsi(bridge);
+	struct drm_bridge *next;
 
-	return mtk_dsi_create_conn_enc(bridge->dev, dsi);
-}
-
-static void mtk_dsi_bridge_detach(struct drm_bridge *bridge)
-{
-	struct mtk_dsi *dsi = bridge_to_dsi(bridge);
+	if (dsi->next_bridge)
+		next = dsi->next_bridge;
+	else
+		next = dsi->panel_bridge;
 
-	mtk_dsi_destroy_conn_enc(dsi);
+	/* Attach the panel or bridge to the dsi bridge */
+	return drm_bridge_attach(bridge->encoder, next, &dsi->bridge, flags);
 }
 
 static void mtk_dsi_bridge_mode_set(struct drm_bridge *bridge,
@@ -830,101 +785,13 @@ static void mtk_dsi_bridge_enable(struct drm_bridge *bridge)
 	mtk_output_dsi_enable(dsi);
 }
 
-static int mtk_dsi_connector_get_modes(struct drm_connector *connector)
-{
-	struct mtk_dsi *dsi = connector_to_dsi(connector);
-
-	return drm_panel_get_modes(dsi->panel, connector);
-}
-
 static const struct drm_bridge_funcs mtk_dsi_bridge_funcs = {
 	.attach = mtk_dsi_bridge_attach,
-	.detach = mtk_dsi_bridge_detach,
 	.disable = mtk_dsi_bridge_disable,
 	.enable = mtk_dsi_bridge_enable,
 	.mode_set = mtk_dsi_bridge_mode_set,
 };
 
-static const struct drm_connector_funcs mtk_dsi_connector_funcs = {
-	.fill_modes = drm_helper_probe_single_connector_modes,
-	.destroy = drm_connector_cleanup,
-	.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 const struct drm_connector_helper_funcs
-	mtk_dsi_connector_helper_funcs = {
-	.get_modes = mtk_dsi_connector_get_modes,
-};
-
-static int mtk_dsi_create_connector(struct drm_device *drm, struct mtk_dsi *dsi)
-{
-	int ret;
-
-	ret = drm_connector_init(drm, &dsi->conn, &mtk_dsi_connector_funcs,
-				 DRM_MODE_CONNECTOR_DSI);
-	if (ret) {
-		DRM_ERROR("Failed to connector init to drm\n");
-		return ret;
-	}
-
-	drm_connector_helper_add(&dsi->conn, &mtk_dsi_connector_helper_funcs);
-
-	dsi->conn.dpms = DRM_MODE_DPMS_OFF;
-	drm_connector_attach_encoder(&dsi->conn, &dsi->encoder);
-
-	if (dsi->panel) {
-		ret = drm_panel_attach(dsi->panel, &dsi->conn);
-		if (ret) {
-			DRM_ERROR("Failed to attach panel to drm\n");
-			goto err_connector_cleanup;
-		}
-	}
-
-	return 0;
-
-err_connector_cleanup:
-	drm_connector_cleanup(&dsi->conn);
-	return ret;
-}
-
-static int mtk_dsi_create_conn_enc(struct drm_device *drm, struct mtk_dsi *dsi)
-{
-	int ret;
-
-	/* If there's a bridge, attach to it and let it create the connector */
-	if (dsi->next_bridge) {
-		ret = drm_bridge_attach(&dsi->encoder, dsi->next_bridge, NULL,
-					0);
-		if (ret) {
-			DRM_ERROR("Failed to attach bridge to drm\n");
-			goto err_encoder_cleanup;
-		}
-	} else {
-		/* Otherwise create our own connector and attach to a panel */
-		ret = mtk_dsi_create_connector(drm, dsi);
-		if (ret)
-			goto err_encoder_cleanup;
-	}
-
-	return 0;
-
-err_encoder_cleanup:
-	drm_encoder_cleanup(&dsi->encoder);
-	return ret;
-}
-
-static void mtk_dsi_destroy_conn_enc(struct mtk_dsi *dsi)
-{
-	drm_encoder_cleanup(&dsi->encoder);
-	/* Skip connector cleanup if creation was delegated to the bridge */
-	if (dsi->conn.dev)
-		drm_connector_cleanup(&dsi->conn);
-	if (dsi->panel)
-		drm_panel_detach(dsi->panel);
-}
-
 static void mtk_dsi_ddp_start(struct mtk_ddp_comp *comp)
 {
 	struct mtk_dsi *dsi = container_of(comp, struct mtk_dsi, ddp_comp);
@@ -953,20 +820,6 @@ static int mtk_dsi_host_attach(struct mipi_dsi_host *host,
 	dsi->format = device->format;
 	dsi->mode_flags = device->mode_flags;
 
-	if (dsi->conn.dev)
-		drm_helper_hpd_irq_event(dsi->conn.dev);
-
-	return 0;
-}
-
-static int mtk_dsi_host_detach(struct mipi_dsi_host *host,
-			       struct mipi_dsi_device *device)
-{
-	struct mtk_dsi *dsi = host_to_dsi(host);
-
-	if (dsi->conn.dev)
-		drm_helper_hpd_irq_event(dsi->conn.dev);
-
 	return 0;
 }
 
@@ -1110,7 +963,6 @@ static ssize_t mtk_dsi_host_transfer(struct mipi_dsi_host *host,
 
 static const struct mipi_dsi_host_ops mtk_dsi_ops = {
 	.attach = mtk_dsi_host_attach,
-	.detach = mtk_dsi_host_detach,
 	.transfer = mtk_dsi_host_transfer,
 };
 
@@ -1184,6 +1036,7 @@ static int mtk_dsi_probe(struct platform_device *pdev)
 {
 	struct mtk_dsi *dsi;
 	struct device *dev = &pdev->dev;
+	struct drm_panel *panel;
 	struct resource *regs;
 	int irq_num;
 	int comp_id;
@@ -1202,10 +1055,18 @@ static int mtk_dsi_probe(struct platform_device *pdev)
 	}
 
 	ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0,
-					  &dsi->panel, &dsi->next_bridge);
+					  &panel, &dsi->next_bridge);
 	if (ret)
 		goto err_unregister_host;
 
+	if (panel) {
+		dsi->panel_bridge = devm_drm_panel_bridge_add(dev, panel);
+		if (IS_ERR(dsi->panel_bridge)) {
+			ret = PTR_ERR(dsi->panel_bridge);
+			goto err_unregister_host;
+		}
+	}
+
 	dsi->driver_data = of_device_get_match_data(dev);
 
 	dsi->engine_clk = devm_clk_get(dev, "engine");
-- 
2.25.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH v2 7/7] drm/mediatek: mtk_dsi: Create connector for bridges
  2020-04-16 15:57 [PATCH v2 0/7] Convert mtk-dsi to drm_bridge API and get EDID for ps8640 bridge Enric Balletbo i Serra
                   ` (5 preceding siblings ...)
  2020-04-16 15:57 ` [PATCH v2 6/7] drm/mediatek: mtk_dsi: Use the drm_panel_bridge API Enric Balletbo i Serra
@ 2020-04-16 15:57 ` Enric Balletbo i Serra
  2020-04-16 17:35   ` Laurent Pinchart
  6 siblings, 1 reply; 19+ messages in thread
From: Enric Balletbo i Serra @ 2020-04-16 15:57 UTC (permalink / raw)
  To: linux-kernel
  Cc: Chun-Kuang Hu, drinkcat, David Airlie, dri-devel, linux-mediatek,
	laurent.pinchart, hsinyi, matthias.bgg, Collabora Kernel ML,
	linux-arm-kernel

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: Enric Balletbo i Serra <enric.balletbo@collabora.com>
---

Changes in v2: None

 drivers/gpu/drm/mediatek/mtk_dsi.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 44718fa3d1ca..2f8876c32864 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -17,6 +17,7 @@
 
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_bridge.h>
+#include <drm/drm_bridge_connector.h>
 #include <drm/drm_mipi_dsi.h>
 #include <drm/drm_of.h>
 #include <drm/drm_panel.h>
@@ -184,6 +185,7 @@ struct mtk_dsi {
 	struct drm_bridge bridge;
 	struct drm_bridge *panel_bridge;
 	struct drm_bridge *next_bridge;
+	struct drm_connector *connector;
 	struct phy *phy;
 
 	void __iomem *regs;
@@ -983,10 +985,19 @@ static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi)
 	 */
 	dsi->encoder.possible_crtcs = 1;
 
-	ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL, 0);
+	ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL,
+				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
 	if (ret)
 		goto err_cleanup_encoder;
 
+	dsi->connector = drm_bridge_connector_init(drm, &dsi->encoder);
+	if (IS_ERR(dsi->connector)) {
+		DRM_ERROR("Unable to create bridge connector\n");
+		ret = PTR_ERR(dsi->connector);
+		goto err_cleanup_encoder;
+	}
+	drm_connector_attach_encoder(dsi->connector, &dsi->encoder);
+
 	return 0;
 
 err_cleanup_encoder:
@@ -1144,6 +1155,7 @@ static int mtk_dsi_probe(struct platform_device *pdev)
 
 	dsi->bridge.funcs = &mtk_dsi_bridge_funcs;
 	dsi->bridge.of_node = dev->of_node;
+	dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
 
 	drm_bridge_add(&dsi->bridge);
 
-- 
2.25.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v2 1/7] drm/bridge: ps8640: Get the EDID from eDP control
  2020-04-16 15:57 ` [PATCH v2 1/7] drm/bridge: ps8640: Get the EDID from eDP control Enric Balletbo i Serra
@ 2020-04-16 17:22   ` Laurent Pinchart
  2020-04-17 14:51     ` Enric Balletbo i Serra
  0 siblings, 1 reply; 19+ messages in thread
From: Laurent Pinchart @ 2020-04-16 17:22 UTC (permalink / raw)
  To: Enric Balletbo i Serra
  Cc: Jernej Skrabec, drinkcat, Jonas Karlman, David Airlie,
	Neil Armstrong, linux-kernel, dri-devel, Andrzej Hajda, hsinyi,
	matthias.bgg, Collabora Kernel ML

Hi Enric,

Thank you for the patch.

On Thu, Apr 16, 2020 at 05:57:13PM +0200, Enric Balletbo i Serra wrote:
> The PS8640 DSI-to-eDP bridge can retrieve the EDID, so implement the
> .get_edid callback and set the flag to indicate the core to use it.
> 
> Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
> ---
> 
> Changes in v2: None
> 
>  drivers/gpu/drm/bridge/parade-ps8640.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/drivers/gpu/drm/bridge/parade-ps8640.c b/drivers/gpu/drm/bridge/parade-ps8640.c
> index d3a53442d449..956b76e0a44d 100644
> --- a/drivers/gpu/drm/bridge/parade-ps8640.c
> +++ b/drivers/gpu/drm/bridge/parade-ps8640.c
> @@ -242,8 +242,18 @@ static int ps8640_bridge_attach(struct drm_bridge *bridge,
>  	return ret;
>  }
>  
> +static struct edid *ps8640_bridge_get_edid(struct drm_bridge *bridge,
> +					   struct drm_connector *connector)
> +{
> +	struct ps8640 *ps_bridge = bridge_to_ps8640(bridge);
> +
> +	return drm_get_edid(connector,
> +			    ps_bridge->page[PAGE0_DP_CNTL]->adapter);

This will only work if the DDC signals are connected to the PS8640
(quite obviously). Is that guaranteed, or could some systems connect
them directory to an SoC I2C controller ? In the latter case we would
have to report this in the DT bindings of the PS8640. That's not
blocking for this patch, I am just wondering, as I would have expected
the driver to already expose EDID one way or another if this was
available and used.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> +}
> +
>  static const struct drm_bridge_funcs ps8640_bridge_funcs = {
>  	.attach = ps8640_bridge_attach,
> +	.get_edid = ps8640_bridge_get_edid,
>  	.post_disable = ps8640_post_disable,
>  	.pre_enable = ps8640_pre_enable,
>  };
> @@ -296,6 +306,8 @@ static int ps8640_probe(struct i2c_client *client)
>  
>  	ps_bridge->bridge.funcs = &ps8640_bridge_funcs;
>  	ps_bridge->bridge.of_node = dev->of_node;
> +	ps_bridge->bridge.ops = DRM_BRIDGE_OP_EDID;
> +	ps_bridge->bridge.type = DRM_MODE_CONNECTOR_eDP;
>  
>  	ps_bridge->page[PAGE0_DP_CNTL] = client;
>  

-- 
Regards,

Laurent Pinchart
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v2 2/7] drm/bridge_connector: Set default status connected for eDP connectors
  2020-04-16 15:57 ` [PATCH v2 2/7] drm/bridge_connector: Set default status connected for eDP connectors Enric Balletbo i Serra
@ 2020-04-16 17:22   ` Laurent Pinchart
  0 siblings, 0 replies; 19+ messages in thread
From: Laurent Pinchart @ 2020-04-16 17:22 UTC (permalink / raw)
  To: Enric Balletbo i Serra
  Cc: drinkcat, Thomas Zimmermann, David Airlie, linux-kernel,
	dri-devel, hsinyi, matthias.bgg, Collabora Kernel ML

Hi Enric,

Thank you for the patch.

On Thu, Apr 16, 2020 at 05:57:14PM +0200, Enric Balletbo i Serra wrote:
> In an eDP application, HPD is not required and on most bridge chips
> useless. If HPD is not used, we need to set initial status as connected,
> otherwise the connector created by the drm_bridge_connector API remains
> in an unknown state.
> 
> Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> ---
> 
> Changes in v2: None
> 
>  drivers/gpu/drm/drm_bridge_connector.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/gpu/drm/drm_bridge_connector.c b/drivers/gpu/drm/drm_bridge_connector.c
> index c6994fe673f3..a58cbde59c34 100644
> --- a/drivers/gpu/drm/drm_bridge_connector.c
> +++ b/drivers/gpu/drm/drm_bridge_connector.c
> @@ -187,6 +187,7 @@ drm_bridge_connector_detect(struct drm_connector *connector, bool force)
>  		case DRM_MODE_CONNECTOR_DPI:
>  		case DRM_MODE_CONNECTOR_LVDS:
>  		case DRM_MODE_CONNECTOR_DSI:
> +		case DRM_MODE_CONNECTOR_eDP:
>  			status = connector_status_connected;
>  			break;
>  		default:

-- 
Regards,

Laurent Pinchart
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v2 3/7] drm/mediatek: mtk_dsi: Rename bridge to next_bridge
  2020-04-16 15:57 ` [PATCH v2 3/7] drm/mediatek: mtk_dsi: Rename bridge to next_bridge Enric Balletbo i Serra
@ 2020-04-16 17:24   ` Laurent Pinchart
  2020-04-17 14:53     ` Enric Balletbo i Serra
  0 siblings, 1 reply; 19+ messages in thread
From: Laurent Pinchart @ 2020-04-16 17:24 UTC (permalink / raw)
  To: Enric Balletbo i Serra
  Cc: Chun-Kuang Hu, drinkcat, David Airlie, linux-kernel, dri-devel,
	linux-mediatek, hsinyi, matthias.bgg, Collabora Kernel ML,
	linux-arm-kernel

Hi Enric,

Thank you for the patch.

On Thu, Apr 16, 2020 at 05:57:15PM +0200, Enric Balletbo i Serra wrote:
> This is really a cosmetic change just to make a bit more readable the
> code after convert the driver to drm_bridge. The bridge variable name
> will be used by the encoder drm_bridge, and the chained bridge will be
> named next_bridge.
> 
> Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
> ---
> 
> Changes in v2: None
> 
>  drivers/gpu/drm/mediatek/mtk_dsi.c | 9 +++++----
>  1 file changed, 5 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index cfa45d6abd74..44ee884cc31c 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -182,7 +182,7 @@ struct mtk_dsi {
>  	struct drm_encoder encoder;
>  	struct drm_connector conn;
>  	struct drm_panel *panel;
> -	struct drm_bridge *bridge;
> +	struct drm_bridge *next_bridge;
>  	struct phy *phy;
>  
>  	void __iomem *regs;
> @@ -903,8 +903,9 @@ static int mtk_dsi_create_conn_enc(struct drm_device *drm, struct mtk_dsi *dsi)
>  	dsi->encoder.possible_crtcs = 1;
>  
>  	/* If there's a bridge, attach to it and let it create the connector */

Maybe s/bridge/next bridge/ here ? I expect this comment to go away
though, as there will always be a next bridge when the driver switches
to the DRM panel bridge helper.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> -	if (dsi->bridge) {
> -		ret = drm_bridge_attach(&dsi->encoder, dsi->bridge, NULL, 0);
> +	if (dsi->next_bridge) {
> +		ret = drm_bridge_attach(&dsi->encoder, dsi->next_bridge, NULL,
> +					0);
>  		if (ret) {
>  			DRM_ERROR("Failed to attach bridge to drm\n");
>  			goto err_encoder_cleanup;
> @@ -1185,7 +1186,7 @@ static int mtk_dsi_probe(struct platform_device *pdev)
>  	}
>  
>  	ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0,
> -					  &dsi->panel, &dsi->bridge);
> +					  &dsi->panel, &dsi->next_bridge);
>  	if (ret)
>  		goto err_unregister_host;
>  

-- 
Regards,

Laurent Pinchart
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v2 5/7] drm/mediatek: mtk_dsi: Use simple encoder
  2020-04-16 15:57 ` [PATCH v2 5/7] drm/mediatek: mtk_dsi: Use simple encoder Enric Balletbo i Serra
@ 2020-04-16 17:28   ` Laurent Pinchart
  0 siblings, 0 replies; 19+ messages in thread
From: Laurent Pinchart @ 2020-04-16 17:28 UTC (permalink / raw)
  To: Enric Balletbo i Serra
  Cc: Chun-Kuang Hu, drinkcat, David Airlie, linux-kernel, dri-devel,
	linux-mediatek, hsinyi, matthias.bgg, Collabora Kernel ML,
	linux-arm-kernel

Hi Enric,

Thank you for the patch.

On Thu, Apr 16, 2020 at 05:57:17PM +0200, Enric Balletbo i Serra wrote:
> The mtk_dsi driver uses an empty implementation for its encoder. Replace
> the code with the generic simple encoder.
> 
> Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> ---
> 
> Changes in v2: None
> 
>  drivers/gpu/drm/mediatek/mtk_dsi.c | 14 +++-----------
>  1 file changed, 3 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index 3400d6686c85..48361c1e9f34 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -22,6 +22,7 @@
>  #include <drm/drm_panel.h>
>  #include <drm/drm_print.h>
>  #include <drm/drm_probe_helper.h>
> +#include <drm/drm_simple_kms_helper.h>
>  
>  #include "mtk_drm_ddp_comp.h"
>  
> @@ -788,15 +789,6 @@ static void mtk_output_dsi_disable(struct mtk_dsi *dsi)
>  	dsi->enabled = false;
>  }
>  
> -static void mtk_dsi_encoder_destroy(struct drm_encoder *encoder)
> -{
> -	drm_encoder_cleanup(encoder);
> -}
> -
> -static const struct drm_encoder_funcs mtk_dsi_encoder_funcs = {
> -	.destroy = mtk_dsi_encoder_destroy,
> -};
> -
>  static int mtk_dsi_create_conn_enc(struct drm_device *drm, struct mtk_dsi *dsi);
>  static void mtk_dsi_destroy_conn_enc(struct mtk_dsi *dsi);
>  
> @@ -1126,8 +1118,8 @@ static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi)
>  {
>  	int ret;
>  
> -	ret = drm_encoder_init(drm, &dsi->encoder, &mtk_dsi_encoder_funcs,
> -			       DRM_MODE_ENCODER_DSI, NULL);
> +	ret = drm_simple_encoder_init(drm, &dsi->encoder,
> +				      DRM_MODE_ENCODER_DSI);
>  	if (ret) {
>  		DRM_ERROR("Failed to encoder init to drm\n");
>  		return ret;

-- 
Regards,

Laurent Pinchart
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v2 6/7] drm/mediatek: mtk_dsi: Use the drm_panel_bridge API
  2020-04-16 15:57 ` [PATCH v2 6/7] drm/mediatek: mtk_dsi: Use the drm_panel_bridge API Enric Balletbo i Serra
@ 2020-04-16 17:33   ` Laurent Pinchart
  0 siblings, 0 replies; 19+ messages in thread
From: Laurent Pinchart @ 2020-04-16 17:33 UTC (permalink / raw)
  To: Enric Balletbo i Serra
  Cc: Chun-Kuang Hu, drinkcat, David Airlie, linux-kernel, dri-devel,
	linux-mediatek, hsinyi, matthias.bgg, Collabora Kernel ML,
	linux-arm-kernel

Hi Enric,

Thank you for the patch.

On Thu, Apr 16, 2020 at 05:57:18PM +0200, Enric Balletbo i Serra wrote:
> Replace the manual panel handling code by a drm_panel_bridge. This
> simplifies the driver and allows all components in the display pipeline
> to be treated as bridges, paving the way to generic connector handling.
> 
> Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
> ---
> 
> Changes in v2:
> - Do not set connector_type for panel here. (Sam Ravnborg)
> 
>  drivers/gpu/drm/mediatek/mtk_dsi.c | 177 ++++-------------------------
>  1 file changed, 19 insertions(+), 158 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index 48361c1e9f34..44718fa3d1ca 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -182,8 +182,7 @@ struct mtk_dsi {
>  	struct mipi_dsi_host host;
>  	struct drm_encoder encoder;
>  	struct drm_bridge bridge;
> -	struct drm_connector conn;
> -	struct drm_panel *panel;
> +	struct drm_bridge *panel_bridge;

I think you can use the next_bridge field to store the panel bridge, it
will simplify the code a bit in mtk_dsi_bridge_attach().

>  	struct drm_bridge *next_bridge;
>  	struct phy *phy;
>  
> @@ -212,11 +211,6 @@ static inline struct mtk_dsi *bridge_to_dsi(struct drm_bridge *b)
>  	return container_of(b, struct mtk_dsi, bridge);
>  }
>  
> -static inline struct mtk_dsi *connector_to_dsi(struct drm_connector *c)
> -{
> -	return container_of(c, struct mtk_dsi, conn);
> -}
> -
>  static inline struct mtk_dsi *host_to_dsi(struct mipi_dsi_host *h)
>  {
>  	return container_of(h, struct mtk_dsi, host);
> @@ -682,16 +676,7 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
>  	mtk_dsi_lane0_ulp_mode_leave(dsi);
>  	mtk_dsi_clk_hs_mode(dsi, 0);
>  
> -	if (dsi->panel) {
> -		if (drm_panel_prepare(dsi->panel)) {
> -			DRM_ERROR("failed to prepare the panel\n");
> -			goto err_disable_digital_clk;
> -		}
> -	}
> -
>  	return 0;
> -err_disable_digital_clk:
> -	clk_disable_unprepare(dsi->digital_clk);
>  err_disable_engine_clk:
>  	clk_disable_unprepare(dsi->engine_clk);
>  err_phy_power_off:
> @@ -718,15 +703,7 @@ static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
>  	 */
>  	mtk_dsi_stop(dsi);
>  
> -	if (!mtk_dsi_switch_to_cmd_mode(dsi, VM_DONE_INT_FLAG, 500)) {
> -		if (dsi->panel) {
> -			if (drm_panel_unprepare(dsi->panel)) {
> -				DRM_ERROR("failed to unprepare the panel\n");
> -				return;
> -			}
> -		}
> -	}
> -
> +	mtk_dsi_switch_to_cmd_mode(dsi, VM_DONE_INT_FLAG, 500);
>  	mtk_dsi_reset_engine(dsi);
>  	mtk_dsi_lane0_ulp_mode_enter(dsi);
>  	mtk_dsi_clk_ulp_mode_enter(dsi);
> @@ -757,19 +734,7 @@ static void mtk_output_dsi_enable(struct mtk_dsi *dsi)
>  
>  	mtk_dsi_start(dsi);
>  
> -	if (dsi->panel) {
> -		if (drm_panel_enable(dsi->panel)) {
> -			DRM_ERROR("failed to enable the panel\n");
> -			goto err_dsi_power_off;
> -		}
> -	}
> -
>  	dsi->enabled = true;
> -
> -	return;
> -err_dsi_power_off:
> -	mtk_dsi_stop(dsi);
> -	mtk_dsi_poweroff(dsi);
>  }
>  
>  static void mtk_output_dsi_disable(struct mtk_dsi *dsi)
> @@ -777,34 +742,24 @@ static void mtk_output_dsi_disable(struct mtk_dsi *dsi)
>  	if (!dsi->enabled)
>  		return;
>  
> -	if (dsi->panel) {
> -		if (drm_panel_disable(dsi->panel)) {
> -			DRM_ERROR("failed to disable the panel\n");
> -			return;
> -		}
> -	}
> -
>  	mtk_dsi_poweroff(dsi);
>  
>  	dsi->enabled = false;
>  }
>  
> -static int mtk_dsi_create_conn_enc(struct drm_device *drm, struct mtk_dsi *dsi);
> -static void mtk_dsi_destroy_conn_enc(struct mtk_dsi *dsi);
> -
>  static int mtk_dsi_bridge_attach(struct drm_bridge *bridge,
>  				 enum drm_bridge_attach_flags flags)
>  {
>  	struct mtk_dsi *dsi = bridge_to_dsi(bridge);
> +	struct drm_bridge *next;
>  
> -	return mtk_dsi_create_conn_enc(bridge->dev, dsi);
> -}
> -
> -static void mtk_dsi_bridge_detach(struct drm_bridge *bridge)
> -{
> -	struct mtk_dsi *dsi = bridge_to_dsi(bridge);
> +	if (dsi->next_bridge)
> +		next = dsi->next_bridge;
> +	else
> +		next = dsi->panel_bridge;
>  
> -	mtk_dsi_destroy_conn_enc(dsi);
> +	/* Attach the panel or bridge to the dsi bridge */
> +	return drm_bridge_attach(bridge->encoder, next, &dsi->bridge, flags);
>  }
>  
>  static void mtk_dsi_bridge_mode_set(struct drm_bridge *bridge,
> @@ -830,101 +785,13 @@ static void mtk_dsi_bridge_enable(struct drm_bridge *bridge)
>  	mtk_output_dsi_enable(dsi);
>  }
>  
> -static int mtk_dsi_connector_get_modes(struct drm_connector *connector)
> -{
> -	struct mtk_dsi *dsi = connector_to_dsi(connector);
> -
> -	return drm_panel_get_modes(dsi->panel, connector);
> -}
> -
>  static const struct drm_bridge_funcs mtk_dsi_bridge_funcs = {
>  	.attach = mtk_dsi_bridge_attach,
> -	.detach = mtk_dsi_bridge_detach,
>  	.disable = mtk_dsi_bridge_disable,
>  	.enable = mtk_dsi_bridge_enable,
>  	.mode_set = mtk_dsi_bridge_mode_set,
>  };
>  
> -static const struct drm_connector_funcs mtk_dsi_connector_funcs = {
> -	.fill_modes = drm_helper_probe_single_connector_modes,
> -	.destroy = drm_connector_cleanup,
> -	.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 const struct drm_connector_helper_funcs
> -	mtk_dsi_connector_helper_funcs = {
> -	.get_modes = mtk_dsi_connector_get_modes,
> -};
> -
> -static int mtk_dsi_create_connector(struct drm_device *drm, struct mtk_dsi *dsi)
> -{
> -	int ret;
> -
> -	ret = drm_connector_init(drm, &dsi->conn, &mtk_dsi_connector_funcs,
> -				 DRM_MODE_CONNECTOR_DSI);
> -	if (ret) {
> -		DRM_ERROR("Failed to connector init to drm\n");
> -		return ret;
> -	}
> -
> -	drm_connector_helper_add(&dsi->conn, &mtk_dsi_connector_helper_funcs);
> -
> -	dsi->conn.dpms = DRM_MODE_DPMS_OFF;
> -	drm_connector_attach_encoder(&dsi->conn, &dsi->encoder);
> -
> -	if (dsi->panel) {
> -		ret = drm_panel_attach(dsi->panel, &dsi->conn);
> -		if (ret) {
> -			DRM_ERROR("Failed to attach panel to drm\n");
> -			goto err_connector_cleanup;
> -		}
> -	}
> -
> -	return 0;
> -
> -err_connector_cleanup:
> -	drm_connector_cleanup(&dsi->conn);
> -	return ret;
> -}
> -
> -static int mtk_dsi_create_conn_enc(struct drm_device *drm, struct mtk_dsi *dsi)
> -{
> -	int ret;
> -
> -	/* If there's a bridge, attach to it and let it create the connector */
> -	if (dsi->next_bridge) {
> -		ret = drm_bridge_attach(&dsi->encoder, dsi->next_bridge, NULL,
> -					0);
> -		if (ret) {
> -			DRM_ERROR("Failed to attach bridge to drm\n");
> -			goto err_encoder_cleanup;
> -		}
> -	} else {
> -		/* Otherwise create our own connector and attach to a panel */
> -		ret = mtk_dsi_create_connector(drm, dsi);
> -		if (ret)
> -			goto err_encoder_cleanup;
> -	}
> -
> -	return 0;
> -
> -err_encoder_cleanup:
> -	drm_encoder_cleanup(&dsi->encoder);
> -	return ret;
> -}
> -
> -static void mtk_dsi_destroy_conn_enc(struct mtk_dsi *dsi)
> -{
> -	drm_encoder_cleanup(&dsi->encoder);
> -	/* Skip connector cleanup if creation was delegated to the bridge */
> -	if (dsi->conn.dev)
> -		drm_connector_cleanup(&dsi->conn);
> -	if (dsi->panel)
> -		drm_panel_detach(dsi->panel);
> -}
> -
>  static void mtk_dsi_ddp_start(struct mtk_ddp_comp *comp)
>  {
>  	struct mtk_dsi *dsi = container_of(comp, struct mtk_dsi, ddp_comp);
> @@ -953,20 +820,6 @@ static int mtk_dsi_host_attach(struct mipi_dsi_host *host,
>  	dsi->format = device->format;
>  	dsi->mode_flags = device->mode_flags;
>  
> -	if (dsi->conn.dev)
> -		drm_helper_hpd_irq_event(dsi->conn.dev);
> -
> -	return 0;
> -}
> -
> -static int mtk_dsi_host_detach(struct mipi_dsi_host *host,
> -			       struct mipi_dsi_device *device)
> -{
> -	struct mtk_dsi *dsi = host_to_dsi(host);
> -
> -	if (dsi->conn.dev)
> -		drm_helper_hpd_irq_event(dsi->conn.dev);
> -
>  	return 0;
>  }
>  
> @@ -1110,7 +963,6 @@ static ssize_t mtk_dsi_host_transfer(struct mipi_dsi_host *host,
>  
>  static const struct mipi_dsi_host_ops mtk_dsi_ops = {
>  	.attach = mtk_dsi_host_attach,
> -	.detach = mtk_dsi_host_detach,
>  	.transfer = mtk_dsi_host_transfer,
>  };
>  
> @@ -1184,6 +1036,7 @@ static int mtk_dsi_probe(struct platform_device *pdev)
>  {
>  	struct mtk_dsi *dsi;
>  	struct device *dev = &pdev->dev;
> +	struct drm_panel *panel;
>  	struct resource *regs;
>  	int irq_num;
>  	int comp_id;
> @@ -1202,10 +1055,18 @@ static int mtk_dsi_probe(struct platform_device *pdev)
>  	}
>  
>  	ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0,
> -					  &dsi->panel, &dsi->next_bridge);
> +					  &panel, &dsi->next_bridge);
>  	if (ret)
>  		goto err_unregister_host;
>  
> +	if (panel) {
> +		dsi->panel_bridge = devm_drm_panel_bridge_add(dev, panel);

devm_drm_panel_bridge_add() can also return NULL on errors, so you need
IS_ERR_OR_NULL() below (and a special case to give ret a negative value
when the result is NULL). Or maybe it would be best to fix
devm_drm_panel_bridge_add() to always return an error pointer.

With this fixed,

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> +		if (IS_ERR(dsi->panel_bridge)) {
> +			ret = PTR_ERR(dsi->panel_bridge);
> +			goto err_unregister_host;
> +		}
> +	}
> +
>  	dsi->driver_data = of_device_get_match_data(dev);
>  
>  	dsi->engine_clk = devm_clk_get(dev, "engine");

-- 
Regards,

Laurent Pinchart
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v2 7/7] drm/mediatek: mtk_dsi: Create connector for bridges
  2020-04-16 15:57 ` [PATCH v2 7/7] drm/mediatek: mtk_dsi: Create connector for bridges Enric Balletbo i Serra
@ 2020-04-16 17:35   ` Laurent Pinchart
  2020-04-16 17:36     ` Laurent Pinchart
  0 siblings, 1 reply; 19+ messages in thread
From: Laurent Pinchart @ 2020-04-16 17:35 UTC (permalink / raw)
  To: Enric Balletbo i Serra
  Cc: Chun-Kuang Hu, drinkcat, David Airlie, linux-kernel, dri-devel,
	linux-mediatek, hsinyi, matthias.bgg, Collabora Kernel ML,
	linux-arm-kernel

Hi Enric,

Thank you for the patch.

On Thu, Apr 16, 2020 at 05:57:19PM +0200, Enric Balletbo i Serra 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.

That's the right direction, but this should be done in the mtk display
controller driver core, not in here. I'm OK with the code being here as
an interim measure if needed to move forward, but that should then be
temporary only.

> Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
> ---
> 
> Changes in v2: None
> 
>  drivers/gpu/drm/mediatek/mtk_dsi.c | 14 +++++++++++++-
>  1 file changed, 13 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index 44718fa3d1ca..2f8876c32864 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -17,6 +17,7 @@
>  
>  #include <drm/drm_atomic_helper.h>
>  #include <drm/drm_bridge.h>
> +#include <drm/drm_bridge_connector.h>
>  #include <drm/drm_mipi_dsi.h>
>  #include <drm/drm_of.h>
>  #include <drm/drm_panel.h>
> @@ -184,6 +185,7 @@ struct mtk_dsi {
>  	struct drm_bridge bridge;
>  	struct drm_bridge *panel_bridge;
>  	struct drm_bridge *next_bridge;
> +	struct drm_connector *connector;
>  	struct phy *phy;
>  
>  	void __iomem *regs;
> @@ -983,10 +985,19 @@ static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi)
>  	 */
>  	dsi->encoder.possible_crtcs = 1;
>  
> -	ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL, 0);
> +	ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL,
> +				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>  	if (ret)
>  		goto err_cleanup_encoder;
>  
> +	dsi->connector = drm_bridge_connector_init(drm, &dsi->encoder);
> +	if (IS_ERR(dsi->connector)) {
> +		DRM_ERROR("Unable to create bridge connector\n");
> +		ret = PTR_ERR(dsi->connector);
> +		goto err_cleanup_encoder;
> +	}
> +	drm_connector_attach_encoder(dsi->connector, &dsi->encoder);
> +
>  	return 0;
>  
>  err_cleanup_encoder:
> @@ -1144,6 +1155,7 @@ static int mtk_dsi_probe(struct platform_device *pdev)
>  
>  	dsi->bridge.funcs = &mtk_dsi_bridge_funcs;
>  	dsi->bridge.of_node = dev->of_node;
> +	dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;

I think this line belongs to the patch that adds drm_bridge support to
this driver.

>  
>  	drm_bridge_add(&dsi->bridge);
>  

-- 
Regards,

Laurent Pinchart
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v2 7/7] drm/mediatek: mtk_dsi: Create connector for bridges
  2020-04-16 17:35   ` Laurent Pinchart
@ 2020-04-16 17:36     ` Laurent Pinchart
  2020-04-16 21:33       ` Enric Balletbo i Serra
  0 siblings, 1 reply; 19+ messages in thread
From: Laurent Pinchart @ 2020-04-16 17:36 UTC (permalink / raw)
  To: Enric Balletbo i Serra
  Cc: Chun-Kuang Hu, drinkcat, David Airlie, linux-kernel, dri-devel,
	linux-mediatek, hsinyi, matthias.bgg, Collabora Kernel ML,
	linux-arm-kernel

Hi Enric,

On Thu, Apr 16, 2020 at 08:35:26PM +0300, Laurent Pinchart wrote:
> On Thu, Apr 16, 2020 at 05:57:19PM +0200, Enric Balletbo i Serra 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.
> 
> That's the right direction, but this should be done in the mtk display
> controller driver core, not in here. I'm OK with the code being here as
> an interim measure if needed to move forward, but that should then be
> temporary only.

I forgot to mention that the drm_encoder should also move out of the
bridge driver to the display controller driver.

> > Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
> > ---
> > 
> > Changes in v2: None
> > 
> >  drivers/gpu/drm/mediatek/mtk_dsi.c | 14 +++++++++++++-
> >  1 file changed, 13 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
> > index 44718fa3d1ca..2f8876c32864 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> > @@ -17,6 +17,7 @@
> >  
> >  #include <drm/drm_atomic_helper.h>
> >  #include <drm/drm_bridge.h>
> > +#include <drm/drm_bridge_connector.h>
> >  #include <drm/drm_mipi_dsi.h>
> >  #include <drm/drm_of.h>
> >  #include <drm/drm_panel.h>
> > @@ -184,6 +185,7 @@ struct mtk_dsi {
> >  	struct drm_bridge bridge;
> >  	struct drm_bridge *panel_bridge;
> >  	struct drm_bridge *next_bridge;
> > +	struct drm_connector *connector;
> >  	struct phy *phy;
> >  
> >  	void __iomem *regs;
> > @@ -983,10 +985,19 @@ static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi)
> >  	 */
> >  	dsi->encoder.possible_crtcs = 1;
> >  
> > -	ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL, 0);
> > +	ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL,
> > +				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> >  	if (ret)
> >  		goto err_cleanup_encoder;
> >  
> > +	dsi->connector = drm_bridge_connector_init(drm, &dsi->encoder);
> > +	if (IS_ERR(dsi->connector)) {
> > +		DRM_ERROR("Unable to create bridge connector\n");
> > +		ret = PTR_ERR(dsi->connector);
> > +		goto err_cleanup_encoder;
> > +	}
> > +	drm_connector_attach_encoder(dsi->connector, &dsi->encoder);
> > +
> >  	return 0;
> >  
> >  err_cleanup_encoder:
> > @@ -1144,6 +1155,7 @@ static int mtk_dsi_probe(struct platform_device *pdev)
> >  
> >  	dsi->bridge.funcs = &mtk_dsi_bridge_funcs;
> >  	dsi->bridge.of_node = dev->of_node;
> > +	dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
> 
> I think this line belongs to the patch that adds drm_bridge support to
> this driver.
> 
> >  
> >  	drm_bridge_add(&dsi->bridge);
> >  

-- 
Regards,

Laurent Pinchart
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v2 7/7] drm/mediatek: mtk_dsi: Create connector for bridges
  2020-04-16 17:36     ` Laurent Pinchart
@ 2020-04-16 21:33       ` Enric Balletbo i Serra
  2020-04-16 21:45         ` Laurent Pinchart
  0 siblings, 1 reply; 19+ messages in thread
From: Enric Balletbo i Serra @ 2020-04-16 21:33 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Chun-Kuang Hu, drinkcat, David Airlie, linux-kernel, dri-devel,
	linux-mediatek, hsinyi, matthias.bgg, Collabora Kernel ML,
	linux-arm-kernel

Hi Laurent,

On 16/4/20 19:36, Laurent Pinchart wrote:
> Hi Enric,
> 
> On Thu, Apr 16, 2020 at 08:35:26PM +0300, Laurent Pinchart wrote:
>> On Thu, Apr 16, 2020 at 05:57:19PM +0200, Enric Balletbo i Serra 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.
>>
>> That's the right direction, but this should be done in the mtk display
>> controller driver core, not in here. I'm OK with the code being here as
>> an interim measure if needed to move forward, but that should then be
>> temporary only.

It'd be nice if we can do this as an interim measure for now, so at least we
have the embedded display working. IIUC to move that to the display controller
driver core I should also convert/rework the mtk_dpi and mtk_hdmi drivers. This
is used for the external display on my device but to fully support this I'll
also need to rework the bridge chain logic to handle the multi-sink/multi-source
use case. This is something I plan to work on but I suspect won't be easy and
will trigger lots of discussions, and, of course, some time.

So, if is fine I won't move this for now.

Thanks,
 Enric


> 
> I forgot to mention that the drm_encoder should also move out of the
> bridge driver to the display controller driver.
> 
>>> Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
>>> ---
>>>
>>> Changes in v2: None
>>>
>>>  drivers/gpu/drm/mediatek/mtk_dsi.c | 14 +++++++++++++-
>>>  1 file changed, 13 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
>>> index 44718fa3d1ca..2f8876c32864 100644
>>> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
>>> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
>>> @@ -17,6 +17,7 @@
>>>  
>>>  #include <drm/drm_atomic_helper.h>
>>>  #include <drm/drm_bridge.h>
>>> +#include <drm/drm_bridge_connector.h>
>>>  #include <drm/drm_mipi_dsi.h>
>>>  #include <drm/drm_of.h>
>>>  #include <drm/drm_panel.h>
>>> @@ -184,6 +185,7 @@ struct mtk_dsi {
>>>  	struct drm_bridge bridge;
>>>  	struct drm_bridge *panel_bridge;
>>>  	struct drm_bridge *next_bridge;
>>> +	struct drm_connector *connector;
>>>  	struct phy *phy;
>>>  
>>>  	void __iomem *regs;
>>> @@ -983,10 +985,19 @@ static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi)
>>>  	 */
>>>  	dsi->encoder.possible_crtcs = 1;
>>>  
>>> -	ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL, 0);
>>> +	ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL,
>>> +				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>>>  	if (ret)
>>>  		goto err_cleanup_encoder;
>>>  
>>> +	dsi->connector = drm_bridge_connector_init(drm, &dsi->encoder);
>>> +	if (IS_ERR(dsi->connector)) {
>>> +		DRM_ERROR("Unable to create bridge connector\n");
>>> +		ret = PTR_ERR(dsi->connector);
>>> +		goto err_cleanup_encoder;
>>> +	}
>>> +	drm_connector_attach_encoder(dsi->connector, &dsi->encoder);
>>> +
>>>  	return 0;
>>>  
>>>  err_cleanup_encoder:
>>> @@ -1144,6 +1155,7 @@ static int mtk_dsi_probe(struct platform_device *pdev)
>>>  
>>>  	dsi->bridge.funcs = &mtk_dsi_bridge_funcs;
>>>  	dsi->bridge.of_node = dev->of_node;
>>> +	dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
>>
>> I think this line belongs to the patch that adds drm_bridge support to
>> this driver.
>>
>>>  
>>>  	drm_bridge_add(&dsi->bridge);
>>>  
> 
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v2 7/7] drm/mediatek: mtk_dsi: Create connector for bridges
  2020-04-16 21:33       ` Enric Balletbo i Serra
@ 2020-04-16 21:45         ` Laurent Pinchart
  0 siblings, 0 replies; 19+ messages in thread
From: Laurent Pinchart @ 2020-04-16 21:45 UTC (permalink / raw)
  To: Enric Balletbo i Serra
  Cc: Chun-Kuang Hu, drinkcat, David Airlie, linux-kernel, dri-devel,
	linux-mediatek, hsinyi, matthias.bgg, Collabora Kernel ML,
	linux-arm-kernel

Hi Enric,

On Thu, Apr 16, 2020 at 11:33:24PM +0200, Enric Balletbo i Serra wrote:
> On 16/4/20 19:36, Laurent Pinchart wrote:
> > On Thu, Apr 16, 2020 at 08:35:26PM +0300, Laurent Pinchart wrote:
> >> On Thu, Apr 16, 2020 at 05:57:19PM +0200, Enric Balletbo i Serra 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.
> >>
> >> That's the right direction, but this should be done in the mtk display
> >> controller driver core, not in here. I'm OK with the code being here as
> >> an interim measure if needed to move forward, but that should then be
> >> temporary only.
> 
> It'd be nice if we can do this as an interim measure for now, so at least we
> have the embedded display working. IIUC to move that to the display controller
> driver core I should also convert/rework the mtk_dpi and mtk_hdmi drivers. This
> is used for the external display on my device but to fully support this I'll
> also need to rework the bridge chain logic to handle the multi-sink/multi-source
> use case. This is something I plan to work on but I suspect won't be easy and
> will trigger lots of discussions, and, of course, some time.
> 
> So, if is fine I won't move this for now.

That's totally fine with me, I just wanted to make sure you were aware
that more work was needed :-)

Thanks for all your efforts !

> > I forgot to mention that the drm_encoder should also move out of the
> > bridge driver to the display controller driver.
> > 
> >>> Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
> >>> ---
> >>>
> >>> Changes in v2: None
> >>>
> >>>  drivers/gpu/drm/mediatek/mtk_dsi.c | 14 +++++++++++++-
> >>>  1 file changed, 13 insertions(+), 1 deletion(-)
> >>>
> >>> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
> >>> index 44718fa3d1ca..2f8876c32864 100644
> >>> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> >>> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> >>> @@ -17,6 +17,7 @@
> >>>  
> >>>  #include <drm/drm_atomic_helper.h>
> >>>  #include <drm/drm_bridge.h>
> >>> +#include <drm/drm_bridge_connector.h>
> >>>  #include <drm/drm_mipi_dsi.h>
> >>>  #include <drm/drm_of.h>
> >>>  #include <drm/drm_panel.h>
> >>> @@ -184,6 +185,7 @@ struct mtk_dsi {
> >>>  	struct drm_bridge bridge;
> >>>  	struct drm_bridge *panel_bridge;
> >>>  	struct drm_bridge *next_bridge;
> >>> +	struct drm_connector *connector;
> >>>  	struct phy *phy;
> >>>  
> >>>  	void __iomem *regs;
> >>> @@ -983,10 +985,19 @@ static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi)
> >>>  	 */
> >>>  	dsi->encoder.possible_crtcs = 1;
> >>>  
> >>> -	ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL, 0);
> >>> +	ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL,
> >>> +				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> >>>  	if (ret)
> >>>  		goto err_cleanup_encoder;
> >>>  
> >>> +	dsi->connector = drm_bridge_connector_init(drm, &dsi->encoder);
> >>> +	if (IS_ERR(dsi->connector)) {
> >>> +		DRM_ERROR("Unable to create bridge connector\n");
> >>> +		ret = PTR_ERR(dsi->connector);
> >>> +		goto err_cleanup_encoder;
> >>> +	}
> >>> +	drm_connector_attach_encoder(dsi->connector, &dsi->encoder);
> >>> +
> >>>  	return 0;
> >>>  
> >>>  err_cleanup_encoder:
> >>> @@ -1144,6 +1155,7 @@ static int mtk_dsi_probe(struct platform_device *pdev)
> >>>  
> >>>  	dsi->bridge.funcs = &mtk_dsi_bridge_funcs;
> >>>  	dsi->bridge.of_node = dev->of_node;
> >>> +	dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
> >>
> >> I think this line belongs to the patch that adds drm_bridge support to
> >> this driver.
> >>
> >>>  
> >>>  	drm_bridge_add(&dsi->bridge);
> >>>  

-- 
Regards,

Laurent Pinchart
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v2 1/7] drm/bridge: ps8640: Get the EDID from eDP control
  2020-04-16 17:22   ` Laurent Pinchart
@ 2020-04-17 14:51     ` Enric Balletbo i Serra
  0 siblings, 0 replies; 19+ messages in thread
From: Enric Balletbo i Serra @ 2020-04-17 14:51 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Jernej Skrabec, drinkcat, Jonas Karlman, David Airlie,
	Neil Armstrong, linux-kernel, dri-devel, Andrzej Hajda, hsinyi,
	matthias.bgg, Collabora Kernel ML

Hi Laurent,

On 16/4/20 19:22, Laurent Pinchart wrote:
> Hi Enric,
> 
> Thank you for the patch.
> 
> On Thu, Apr 16, 2020 at 05:57:13PM +0200, Enric Balletbo i Serra wrote:
>> The PS8640 DSI-to-eDP bridge can retrieve the EDID, so implement the
>> .get_edid callback and set the flag to indicate the core to use it.
>>
>> Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
>> ---
>>
>> Changes in v2: None
>>
>>  drivers/gpu/drm/bridge/parade-ps8640.c | 12 ++++++++++++
>>  1 file changed, 12 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/bridge/parade-ps8640.c b/drivers/gpu/drm/bridge/parade-ps8640.c
>> index d3a53442d449..956b76e0a44d 100644
>> --- a/drivers/gpu/drm/bridge/parade-ps8640.c
>> +++ b/drivers/gpu/drm/bridge/parade-ps8640.c
>> @@ -242,8 +242,18 @@ static int ps8640_bridge_attach(struct drm_bridge *bridge,
>>  	return ret;
>>  }
>>  
>> +static struct edid *ps8640_bridge_get_edid(struct drm_bridge *bridge,
>> +					   struct drm_connector *connector)
>> +{
>> +	struct ps8640 *ps_bridge = bridge_to_ps8640(bridge);
>> +
>> +	return drm_get_edid(connector,
>> +			    ps_bridge->page[PAGE0_DP_CNTL]->adapter);
> 
> This will only work if the DDC signals are connected to the PS8640
> (quite obviously). Is that guaranteed, or could some systems connect
> them directory to an SoC I2C controller ?

It is possible but IMHO opinion this is hardware tricky, I mean, ps8640 outputs
eDP interface and the panel is an eDP interface, so I'd expect hardware
engineers do a pin to pin design, not routing the DDC signals to the SoC
directly ignoring the eDP interface.

> In the latter case we would
> have to report this in the DT bindings of the PS8640. That's not
> blocking for this patch, I am just wondering, as I would have expected
> the driver to already expose EDID one way or another if this was
> available and used.
> 
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> 
>> +}
>> +
>>  static const struct drm_bridge_funcs ps8640_bridge_funcs = {
>>  	.attach = ps8640_bridge_attach,
>> +	.get_edid = ps8640_bridge_get_edid,
>>  	.post_disable = ps8640_post_disable,
>>  	.pre_enable = ps8640_pre_enable,
>>  };
>> @@ -296,6 +306,8 @@ static int ps8640_probe(struct i2c_client *client)
>>  
>>  	ps_bridge->bridge.funcs = &ps8640_bridge_funcs;
>>  	ps_bridge->bridge.of_node = dev->of_node;
>> +	ps_bridge->bridge.ops = DRM_BRIDGE_OP_EDID;
>> +	ps_bridge->bridge.type = DRM_MODE_CONNECTOR_eDP;
>>  
>>  	ps_bridge->page[PAGE0_DP_CNTL] = client;
>>  
> 
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v2 3/7] drm/mediatek: mtk_dsi: Rename bridge to next_bridge
  2020-04-16 17:24   ` Laurent Pinchart
@ 2020-04-17 14:53     ` Enric Balletbo i Serra
  0 siblings, 0 replies; 19+ messages in thread
From: Enric Balletbo i Serra @ 2020-04-17 14:53 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Chun-Kuang Hu, drinkcat, David Airlie, linux-kernel, dri-devel,
	linux-mediatek, hsinyi, matthias.bgg, Collabora Kernel ML,
	linux-arm-kernel

Hi Laurent,

On 16/4/20 19:24, Laurent Pinchart wrote:
> Hi Enric,
> 
> Thank you for the patch.
> 
> On Thu, Apr 16, 2020 at 05:57:15PM +0200, Enric Balletbo i Serra wrote:
>> This is really a cosmetic change just to make a bit more readable the
>> code after convert the driver to drm_bridge. The bridge variable name
>> will be used by the encoder drm_bridge, and the chained bridge will be
>> named next_bridge.
>>
>> Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
>> ---
>>
>> Changes in v2: None
>>
>>  drivers/gpu/drm/mediatek/mtk_dsi.c | 9 +++++----
>>  1 file changed, 5 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
>> index cfa45d6abd74..44ee884cc31c 100644
>> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
>> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
>> @@ -182,7 +182,7 @@ struct mtk_dsi {
>>  	struct drm_encoder encoder;
>>  	struct drm_connector conn;
>>  	struct drm_panel *panel;
>> -	struct drm_bridge *bridge;
>> +	struct drm_bridge *next_bridge;
>>  	struct phy *phy;
>>  
>>  	void __iomem *regs;
>> @@ -903,8 +903,9 @@ static int mtk_dsi_create_conn_enc(struct drm_device *drm, struct mtk_dsi *dsi)
>>  	dsi->encoder.possible_crtcs = 1;
>>  
>>  	/* If there's a bridge, attach to it and let it create the connector */
> 
> Maybe s/bridge/next bridge/ here ? I expect this comment to go away
> though, as there will always be a next bridge when the driver switches
> to the DRM panel bridge helper.
> 

I'll rename it to next bridge for coherency, however, as you point this message
is removed later.

> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> 
>> -	if (dsi->bridge) {
>> -		ret = drm_bridge_attach(&dsi->encoder, dsi->bridge, NULL, 0);
>> +	if (dsi->next_bridge) {
>> +		ret = drm_bridge_attach(&dsi->encoder, dsi->next_bridge, NULL,
>> +					0);
>>  		if (ret) {
>>  			DRM_ERROR("Failed to attach bridge to drm\n");
>>  			goto err_encoder_cleanup;
>> @@ -1185,7 +1186,7 @@ static int mtk_dsi_probe(struct platform_device *pdev)
>>  	}
>>  
>>  	ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0,
>> -					  &dsi->panel, &dsi->bridge);
>> +					  &dsi->panel, &dsi->next_bridge);
>>  	if (ret)
>>  		goto err_unregister_host;
>>  
> 
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

end of thread, other threads:[~2020-04-18  9:27 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-16 15:57 [PATCH v2 0/7] Convert mtk-dsi to drm_bridge API and get EDID for ps8640 bridge Enric Balletbo i Serra
2020-04-16 15:57 ` [PATCH v2 1/7] drm/bridge: ps8640: Get the EDID from eDP control Enric Balletbo i Serra
2020-04-16 17:22   ` Laurent Pinchart
2020-04-17 14:51     ` Enric Balletbo i Serra
2020-04-16 15:57 ` [PATCH v2 2/7] drm/bridge_connector: Set default status connected for eDP connectors Enric Balletbo i Serra
2020-04-16 17:22   ` Laurent Pinchart
2020-04-16 15:57 ` [PATCH v2 3/7] drm/mediatek: mtk_dsi: Rename bridge to next_bridge Enric Balletbo i Serra
2020-04-16 17:24   ` Laurent Pinchart
2020-04-17 14:53     ` Enric Balletbo i Serra
2020-04-16 15:57 ` [PATCH v2 4/7] drm/mediatek: mtk_dsi: Convert to bridge driver Enric Balletbo i Serra
2020-04-16 15:57 ` [PATCH v2 5/7] drm/mediatek: mtk_dsi: Use simple encoder Enric Balletbo i Serra
2020-04-16 17:28   ` Laurent Pinchart
2020-04-16 15:57 ` [PATCH v2 6/7] drm/mediatek: mtk_dsi: Use the drm_panel_bridge API Enric Balletbo i Serra
2020-04-16 17:33   ` Laurent Pinchart
2020-04-16 15:57 ` [PATCH v2 7/7] drm/mediatek: mtk_dsi: Create connector for bridges Enric Balletbo i Serra
2020-04-16 17:35   ` Laurent Pinchart
2020-04-16 17:36     ` Laurent Pinchart
2020-04-16 21:33       ` Enric Balletbo i Serra
2020-04-16 21:45         ` Laurent Pinchart

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).