All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH v2 0/5] Simplify and correct msm/dp bridge implementation
@ 2022-02-11 22:40 ` Dmitry Baryshkov
  0 siblings, 0 replies; 84+ messages in thread
From: Dmitry Baryshkov @ 2022-02-11 22:40 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar, Kuogee Hsieh
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

I noticed that commit 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
enable and disable") conflicts with the panel-edp (panel bridge)
support. Both bridges will try to attach directly to the drm encoder
itself without forming a proper bridge chain.

Initially I started writing lengthy letter describing what is broken and
how it should be fixed. Then at some point I stopped and quickly coded
this RFC (which is compile-tested only).

Comments and tests (on both DP and eDP setups) are more than welcome.

Changes since RFC v1:
 - Expanded commit messages to reference possible setups
   Added details about possible bridges, usage, etc
 - Changed handling of errors for devm_drm_of_get_bridge(). Made the
   -ENODEV fatal for the eDP connectors only, all other errors should be
   fatal for both eDP and DP.

Dmitry Baryshkov (5):
  drm/msm/dp: fix panel bridge attachment
  drm/msm/dp: support attaching bridges to the DP encoder
  drm/msm/dp: support finding next bridge even for DP interfaces
  drm/msm/dp: replace dp_connector with drm_bridge_connector
  drm/msm/dp: remove extra wrappers and public functions

 drivers/gpu/drm/msm/dp/dp_display.c |  76 +++++++-----
 drivers/gpu/drm/msm/dp/dp_display.h |   3 +-
 drivers/gpu/drm/msm/dp/dp_drm.c     | 186 +++++++---------------------
 drivers/gpu/drm/msm/dp/dp_drm.h     |  22 +++-
 drivers/gpu/drm/msm/dp/dp_parser.c  |  38 +++---
 drivers/gpu/drm/msm/dp/dp_parser.h  |   2 +-
 drivers/gpu/drm/msm/msm_drv.h       |  31 -----
 7 files changed, 137 insertions(+), 221 deletions(-)


base-commit: 6aa89ae1fb049614b7e03e24485bbfb96754a02b
prerequisite-patch-id: 89e012b5b7da1a90cc243cc4c305400a4fafdf0b
prerequisite-patch-id: 0de618d54d5fea5b48c2b540c8731a1a7e2f4c15
prerequisite-patch-id: a9b1a27e9800626cc0ebc73291d65c2790670583
prerequisite-patch-id: 2067135baa2995fbcbfd6793b61e39027e6b7516
prerequisite-patch-id: 0591114f3c59f9376ba25e77e7a48daf90cf7aa6
prerequisite-patch-id: 684cf6c7a177cb7c6c9d83a859eec0acef5c132c
prerequisite-patch-id: 083313bc9b19fcf7fed78f63a3cb0752f54cec4f
prerequisite-patch-id: 6e46e24cd7471ba38679b3d6f99a1132fa1154b3
-- 
2.34.1


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

* [RFC PATCH v2 0/5] Simplify and correct msm/dp bridge implementation
@ 2022-02-11 22:40 ` Dmitry Baryshkov
  0 siblings, 0 replies; 84+ messages in thread
From: Dmitry Baryshkov @ 2022-02-11 22:40 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar, Kuogee Hsieh
  Cc: David Airlie, linux-arm-msm, dri-devel, Stephen Boyd, freedreno

I noticed that commit 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
enable and disable") conflicts with the panel-edp (panel bridge)
support. Both bridges will try to attach directly to the drm encoder
itself without forming a proper bridge chain.

Initially I started writing lengthy letter describing what is broken and
how it should be fixed. Then at some point I stopped and quickly coded
this RFC (which is compile-tested only).

Comments and tests (on both DP and eDP setups) are more than welcome.

Changes since RFC v1:
 - Expanded commit messages to reference possible setups
   Added details about possible bridges, usage, etc
 - Changed handling of errors for devm_drm_of_get_bridge(). Made the
   -ENODEV fatal for the eDP connectors only, all other errors should be
   fatal for both eDP and DP.

Dmitry Baryshkov (5):
  drm/msm/dp: fix panel bridge attachment
  drm/msm/dp: support attaching bridges to the DP encoder
  drm/msm/dp: support finding next bridge even for DP interfaces
  drm/msm/dp: replace dp_connector with drm_bridge_connector
  drm/msm/dp: remove extra wrappers and public functions

 drivers/gpu/drm/msm/dp/dp_display.c |  76 +++++++-----
 drivers/gpu/drm/msm/dp/dp_display.h |   3 +-
 drivers/gpu/drm/msm/dp/dp_drm.c     | 186 +++++++---------------------
 drivers/gpu/drm/msm/dp/dp_drm.h     |  22 +++-
 drivers/gpu/drm/msm/dp/dp_parser.c  |  38 +++---
 drivers/gpu/drm/msm/dp/dp_parser.h  |   2 +-
 drivers/gpu/drm/msm/msm_drv.h       |  31 -----
 7 files changed, 137 insertions(+), 221 deletions(-)


base-commit: 6aa89ae1fb049614b7e03e24485bbfb96754a02b
prerequisite-patch-id: 89e012b5b7da1a90cc243cc4c305400a4fafdf0b
prerequisite-patch-id: 0de618d54d5fea5b48c2b540c8731a1a7e2f4c15
prerequisite-patch-id: a9b1a27e9800626cc0ebc73291d65c2790670583
prerequisite-patch-id: 2067135baa2995fbcbfd6793b61e39027e6b7516
prerequisite-patch-id: 0591114f3c59f9376ba25e77e7a48daf90cf7aa6
prerequisite-patch-id: 684cf6c7a177cb7c6c9d83a859eec0acef5c132c
prerequisite-patch-id: 083313bc9b19fcf7fed78f63a3cb0752f54cec4f
prerequisite-patch-id: 6e46e24cd7471ba38679b3d6f99a1132fa1154b3
-- 
2.34.1


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

* [RFC PATCH v2 1/5] drm/msm/dp: fix panel bridge attachment
  2022-02-11 22:40 ` Dmitry Baryshkov
@ 2022-02-11 22:40   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 84+ messages in thread
From: Dmitry Baryshkov @ 2022-02-11 22:40 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar, Kuogee Hsieh
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

In commit 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
enable and disable") the DP driver received a drm_bridge instance, which
is always attached to the encoder as a root bridge. However it conflicts
with the panel_bridge support for eDP panels. The panel bridge attaches
to the encoder before the "dp" bridge has a chace to do so. Change
panel_bridge attachment to come after dp_bridge attachment.

Fixes: 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display enable and disable")
Cc: Kuogee Hsieh <quic_khsieh@quicinc.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/dp/dp_drm.c | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
index d4d360d19eba..26ef41a4c1b6 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.c
+++ b/drivers/gpu/drm/msm/dp/dp_drm.c
@@ -169,16 +169,6 @@ struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display)
 
 	drm_connector_attach_encoder(connector, dp_display->encoder);
 
-	if (dp_display->panel_bridge) {
-		ret = drm_bridge_attach(dp_display->encoder,
-					dp_display->panel_bridge, NULL,
-					DRM_BRIDGE_ATTACH_NO_CONNECTOR);
-		if (ret < 0) {
-			DRM_ERROR("failed to attach panel bridge: %d\n", ret);
-			return ERR_PTR(ret);
-		}
-	}
-
 	return connector;
 }
 
@@ -246,5 +236,16 @@ struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display, struct drm_devi
 		return ERR_PTR(rc);
 	}
 
+	if (dp_display->panel_bridge) {
+		rc = drm_bridge_attach(dp_display->encoder,
+					dp_display->panel_bridge, bridge,
+					DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+		if (rc < 0) {
+			DRM_ERROR("failed to attach panel bridge: %d\n", rc);
+			drm_bridge_remove(bridge);
+			return ERR_PTR(rc);
+		}
+	}
+
 	return bridge;
 }
-- 
2.34.1


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

* [RFC PATCH v2 1/5] drm/msm/dp: fix panel bridge attachment
@ 2022-02-11 22:40   ` Dmitry Baryshkov
  0 siblings, 0 replies; 84+ messages in thread
From: Dmitry Baryshkov @ 2022-02-11 22:40 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar, Kuogee Hsieh
  Cc: David Airlie, linux-arm-msm, dri-devel, Stephen Boyd, freedreno

In commit 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
enable and disable") the DP driver received a drm_bridge instance, which
is always attached to the encoder as a root bridge. However it conflicts
with the panel_bridge support for eDP panels. The panel bridge attaches
to the encoder before the "dp" bridge has a chace to do so. Change
panel_bridge attachment to come after dp_bridge attachment.

Fixes: 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display enable and disable")
Cc: Kuogee Hsieh <quic_khsieh@quicinc.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/dp/dp_drm.c | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
index d4d360d19eba..26ef41a4c1b6 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.c
+++ b/drivers/gpu/drm/msm/dp/dp_drm.c
@@ -169,16 +169,6 @@ struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display)
 
 	drm_connector_attach_encoder(connector, dp_display->encoder);
 
-	if (dp_display->panel_bridge) {
-		ret = drm_bridge_attach(dp_display->encoder,
-					dp_display->panel_bridge, NULL,
-					DRM_BRIDGE_ATTACH_NO_CONNECTOR);
-		if (ret < 0) {
-			DRM_ERROR("failed to attach panel bridge: %d\n", ret);
-			return ERR_PTR(ret);
-		}
-	}
-
 	return connector;
 }
 
@@ -246,5 +236,16 @@ struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display, struct drm_devi
 		return ERR_PTR(rc);
 	}
 
+	if (dp_display->panel_bridge) {
+		rc = drm_bridge_attach(dp_display->encoder,
+					dp_display->panel_bridge, bridge,
+					DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+		if (rc < 0) {
+			DRM_ERROR("failed to attach panel bridge: %d\n", rc);
+			drm_bridge_remove(bridge);
+			return ERR_PTR(rc);
+		}
+	}
+
 	return bridge;
 }
-- 
2.34.1


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

* [RFC PATCH v2 2/5] drm/msm/dp: support attaching bridges to the DP encoder
  2022-02-11 22:40 ` Dmitry Baryshkov
@ 2022-02-11 22:40   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 84+ messages in thread
From: Dmitry Baryshkov @ 2022-02-11 22:40 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar, Kuogee Hsieh
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

Currently DP driver will allocate panel bridge for eDP panels. This
supports only the following topology:

- eDP encoder ⇒ eDP panel (wrapped using panel-bridge)

Simplify this code to just check if there is any next bridge in the
chain (be it a panel bridge or regular bridge). Rename panel_bridge
field to next_bridge accordingly.

This allows one to use e.g. one of the following display topologies:

- eDP encoder ⇒ ptn3460 ⇒ fixed LVDS panel
- eDP encoder ⇒ ptn3460 ⇒ LVDS connector with EDID lines for panel autodetect
- eDP encoder ⇒ ptn3460 ⇒ THC63LVD1024 ⇒ DPI panel.
- eDP encoder ⇒ LT8912 ⇒ DSI panel

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/dp/dp_display.c |  2 +-
 drivers/gpu/drm/msm/dp/dp_display.h |  2 +-
 drivers/gpu/drm/msm/dp/dp_drm.c     |  4 ++--
 drivers/gpu/drm/msm/dp/dp_parser.c  | 31 +++++++++++++++--------------
 drivers/gpu/drm/msm/dp/dp_parser.h  |  2 +-
 5 files changed, 21 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index 44d42c76c2a3..45f9a912ecc5 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -266,7 +266,7 @@ static int dp_display_bind(struct device *dev, struct device *master,
 		goto end;
 	}
 
-	dp->dp_display.panel_bridge = dp->parser->panel_bridge;
+	dp->dp_display.next_bridge = dp->parser->next_bridge;
 
 	dp->aux->drm_dev = drm;
 	rc = dp_aux_register(dp->aux);
diff --git a/drivers/gpu/drm/msm/dp/dp_display.h b/drivers/gpu/drm/msm/dp/dp_display.h
index e3adcd578a90..7af2b186d2d9 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.h
+++ b/drivers/gpu/drm/msm/dp/dp_display.h
@@ -16,7 +16,7 @@ struct msm_dp {
 	struct drm_bridge *bridge;
 	struct drm_connector *connector;
 	struct drm_encoder *encoder;
-	struct drm_bridge *panel_bridge;
+	struct drm_bridge *next_bridge;
 	bool is_connected;
 	bool audio_enabled;
 	bool power_on;
diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
index 26ef41a4c1b6..80f59cf99089 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.c
+++ b/drivers/gpu/drm/msm/dp/dp_drm.c
@@ -236,9 +236,9 @@ struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display, struct drm_devi
 		return ERR_PTR(rc);
 	}
 
-	if (dp_display->panel_bridge) {
+	if (dp_display->next_bridge) {
 		rc = drm_bridge_attach(dp_display->encoder,
-					dp_display->panel_bridge, bridge,
+					dp_display->next_bridge, bridge,
 					DRM_BRIDGE_ATTACH_NO_CONNECTOR);
 		if (rc < 0) {
 			DRM_ERROR("failed to attach panel bridge: %d\n", rc);
diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c b/drivers/gpu/drm/msm/dp/dp_parser.c
index a7acc23f742b..901d7967370f 100644
--- a/drivers/gpu/drm/msm/dp/dp_parser.c
+++ b/drivers/gpu/drm/msm/dp/dp_parser.c
@@ -265,23 +265,16 @@ static int dp_parser_clock(struct dp_parser *parser)
 	return 0;
 }
 
-static int dp_parser_find_panel(struct dp_parser *parser)
+static int dp_parser_find_next_bridge(struct dp_parser *parser)
 {
 	struct device *dev = &parser->pdev->dev;
-	struct drm_panel *panel;
-	int rc;
+	struct drm_bridge *bridge;
 
-	rc = drm_of_find_panel_or_bridge(dev->of_node, 1, 0, &panel, NULL);
-	if (rc) {
-		DRM_ERROR("failed to acquire DRM panel: %d\n", rc);
-		return rc;
-	}
+	bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0);
+	if (IS_ERR(bridge))
+		return PTR_ERR(bridge);
 
-	parser->panel_bridge = devm_drm_panel_bridge_add(dev, panel);
-	if (IS_ERR(parser->panel_bridge)) {
-		DRM_ERROR("failed to create panel bridge\n");
-		return PTR_ERR(parser->panel_bridge);
-	}
+	parser->next_bridge = bridge;
 
 	return 0;
 }
@@ -307,10 +300,18 @@ static int dp_parser_parse(struct dp_parser *parser, int connector_type)
 	if (rc)
 		return rc;
 
+	/*
+	 * Currently we support external bridges only for eDP connectors.
+	 *
+	 * No external bridges are expected for the DisplayPort connector,
+	 * it is physically present in a form of a DP or USB-C connector.
+	 */
 	if (connector_type == DRM_MODE_CONNECTOR_eDP) {
-		rc = dp_parser_find_panel(parser);
-		if (rc)
+		rc = dp_parser_find_next_bridge(parser);
+		if (rc) {
+			DRM_ERROR("DP: failed to find next bridge\n");
 			return rc;
+		}
 	}
 
 	/* Map the corresponding regulator information according to
diff --git a/drivers/gpu/drm/msm/dp/dp_parser.h b/drivers/gpu/drm/msm/dp/dp_parser.h
index 3172da089421..4cec851e38d9 100644
--- a/drivers/gpu/drm/msm/dp/dp_parser.h
+++ b/drivers/gpu/drm/msm/dp/dp_parser.h
@@ -123,7 +123,7 @@ struct dp_parser {
 	struct dp_display_data disp_data;
 	const struct dp_regulator_cfg *regulator_cfg;
 	u32 max_dp_lanes;
-	struct drm_bridge *panel_bridge;
+	struct drm_bridge *next_bridge;
 
 	int (*parse)(struct dp_parser *parser, int connector_type);
 };
-- 
2.34.1


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

* [RFC PATCH v2 2/5] drm/msm/dp: support attaching bridges to the DP encoder
@ 2022-02-11 22:40   ` Dmitry Baryshkov
  0 siblings, 0 replies; 84+ messages in thread
From: Dmitry Baryshkov @ 2022-02-11 22:40 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar, Kuogee Hsieh
  Cc: David Airlie, linux-arm-msm, dri-devel, Stephen Boyd, freedreno

Currently DP driver will allocate panel bridge for eDP panels. This
supports only the following topology:

- eDP encoder ⇒ eDP panel (wrapped using panel-bridge)

Simplify this code to just check if there is any next bridge in the
chain (be it a panel bridge or regular bridge). Rename panel_bridge
field to next_bridge accordingly.

This allows one to use e.g. one of the following display topologies:

- eDP encoder ⇒ ptn3460 ⇒ fixed LVDS panel
- eDP encoder ⇒ ptn3460 ⇒ LVDS connector with EDID lines for panel autodetect
- eDP encoder ⇒ ptn3460 ⇒ THC63LVD1024 ⇒ DPI panel.
- eDP encoder ⇒ LT8912 ⇒ DSI panel

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/dp/dp_display.c |  2 +-
 drivers/gpu/drm/msm/dp/dp_display.h |  2 +-
 drivers/gpu/drm/msm/dp/dp_drm.c     |  4 ++--
 drivers/gpu/drm/msm/dp/dp_parser.c  | 31 +++++++++++++++--------------
 drivers/gpu/drm/msm/dp/dp_parser.h  |  2 +-
 5 files changed, 21 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index 44d42c76c2a3..45f9a912ecc5 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -266,7 +266,7 @@ static int dp_display_bind(struct device *dev, struct device *master,
 		goto end;
 	}
 
-	dp->dp_display.panel_bridge = dp->parser->panel_bridge;
+	dp->dp_display.next_bridge = dp->parser->next_bridge;
 
 	dp->aux->drm_dev = drm;
 	rc = dp_aux_register(dp->aux);
diff --git a/drivers/gpu/drm/msm/dp/dp_display.h b/drivers/gpu/drm/msm/dp/dp_display.h
index e3adcd578a90..7af2b186d2d9 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.h
+++ b/drivers/gpu/drm/msm/dp/dp_display.h
@@ -16,7 +16,7 @@ struct msm_dp {
 	struct drm_bridge *bridge;
 	struct drm_connector *connector;
 	struct drm_encoder *encoder;
-	struct drm_bridge *panel_bridge;
+	struct drm_bridge *next_bridge;
 	bool is_connected;
 	bool audio_enabled;
 	bool power_on;
diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
index 26ef41a4c1b6..80f59cf99089 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.c
+++ b/drivers/gpu/drm/msm/dp/dp_drm.c
@@ -236,9 +236,9 @@ struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display, struct drm_devi
 		return ERR_PTR(rc);
 	}
 
-	if (dp_display->panel_bridge) {
+	if (dp_display->next_bridge) {
 		rc = drm_bridge_attach(dp_display->encoder,
-					dp_display->panel_bridge, bridge,
+					dp_display->next_bridge, bridge,
 					DRM_BRIDGE_ATTACH_NO_CONNECTOR);
 		if (rc < 0) {
 			DRM_ERROR("failed to attach panel bridge: %d\n", rc);
diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c b/drivers/gpu/drm/msm/dp/dp_parser.c
index a7acc23f742b..901d7967370f 100644
--- a/drivers/gpu/drm/msm/dp/dp_parser.c
+++ b/drivers/gpu/drm/msm/dp/dp_parser.c
@@ -265,23 +265,16 @@ static int dp_parser_clock(struct dp_parser *parser)
 	return 0;
 }
 
-static int dp_parser_find_panel(struct dp_parser *parser)
+static int dp_parser_find_next_bridge(struct dp_parser *parser)
 {
 	struct device *dev = &parser->pdev->dev;
-	struct drm_panel *panel;
-	int rc;
+	struct drm_bridge *bridge;
 
-	rc = drm_of_find_panel_or_bridge(dev->of_node, 1, 0, &panel, NULL);
-	if (rc) {
-		DRM_ERROR("failed to acquire DRM panel: %d\n", rc);
-		return rc;
-	}
+	bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0);
+	if (IS_ERR(bridge))
+		return PTR_ERR(bridge);
 
-	parser->panel_bridge = devm_drm_panel_bridge_add(dev, panel);
-	if (IS_ERR(parser->panel_bridge)) {
-		DRM_ERROR("failed to create panel bridge\n");
-		return PTR_ERR(parser->panel_bridge);
-	}
+	parser->next_bridge = bridge;
 
 	return 0;
 }
@@ -307,10 +300,18 @@ static int dp_parser_parse(struct dp_parser *parser, int connector_type)
 	if (rc)
 		return rc;
 
+	/*
+	 * Currently we support external bridges only for eDP connectors.
+	 *
+	 * No external bridges are expected for the DisplayPort connector,
+	 * it is physically present in a form of a DP or USB-C connector.
+	 */
 	if (connector_type == DRM_MODE_CONNECTOR_eDP) {
-		rc = dp_parser_find_panel(parser);
-		if (rc)
+		rc = dp_parser_find_next_bridge(parser);
+		if (rc) {
+			DRM_ERROR("DP: failed to find next bridge\n");
 			return rc;
+		}
 	}
 
 	/* Map the corresponding regulator information according to
diff --git a/drivers/gpu/drm/msm/dp/dp_parser.h b/drivers/gpu/drm/msm/dp/dp_parser.h
index 3172da089421..4cec851e38d9 100644
--- a/drivers/gpu/drm/msm/dp/dp_parser.h
+++ b/drivers/gpu/drm/msm/dp/dp_parser.h
@@ -123,7 +123,7 @@ struct dp_parser {
 	struct dp_display_data disp_data;
 	const struct dp_regulator_cfg *regulator_cfg;
 	u32 max_dp_lanes;
-	struct drm_bridge *panel_bridge;
+	struct drm_bridge *next_bridge;
 
 	int (*parse)(struct dp_parser *parser, int connector_type);
 };
-- 
2.34.1


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

* [RFC PATCH v2 3/5] drm/msm/dp: support finding next bridge even for DP interfaces
  2022-02-11 22:40 ` Dmitry Baryshkov
@ 2022-02-11 22:40   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 84+ messages in thread
From: Dmitry Baryshkov @ 2022-02-11 22:40 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar, Kuogee Hsieh
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

It is possible to supply display-connector (bridge) to the DP interface,
add support for parsing it too.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/dp/dp_parser.c | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c b/drivers/gpu/drm/msm/dp/dp_parser.c
index 901d7967370f..1056b8d5755b 100644
--- a/drivers/gpu/drm/msm/dp/dp_parser.c
+++ b/drivers/gpu/drm/msm/dp/dp_parser.c
@@ -301,17 +301,22 @@ static int dp_parser_parse(struct dp_parser *parser, int connector_type)
 		return rc;
 
 	/*
-	 * Currently we support external bridges only for eDP connectors.
+	 * External bridges are mandatory for eDP interfaces: one has to
+	 * provide at least an eDP panel (which gets wrapped into panel-bridge).
 	 *
-	 * No external bridges are expected for the DisplayPort connector,
-	 * it is physically present in a form of a DP or USB-C connector.
+	 * For DisplayPort interfaces external bridges are optional, so
+	 * silently ignore an error if one is not present (-ENODEV).
 	 */
-	if (connector_type == DRM_MODE_CONNECTOR_eDP) {
-		rc = dp_parser_find_next_bridge(parser);
-		if (rc) {
-			DRM_ERROR("DP: failed to find next bridge\n");
+	rc = dp_parser_find_next_bridge(parser);
+	if (rc == -ENODEV) {
+		if (connector_type == DRM_MODE_CONNECTOR_eDP) {
+			DRM_ERROR("eDP: next bridge is not present\n");
 			return rc;
 		}
+	} else if (rc) {
+		if (rc != -EPROBE_DEFER)
+			DRM_ERROR("DP: error parsing next bridge: %d\n", rc);
+		return rc;
 	}
 
 	/* Map the corresponding regulator information according to
-- 
2.34.1


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

* [RFC PATCH v2 3/5] drm/msm/dp: support finding next bridge even for DP interfaces
@ 2022-02-11 22:40   ` Dmitry Baryshkov
  0 siblings, 0 replies; 84+ messages in thread
From: Dmitry Baryshkov @ 2022-02-11 22:40 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar, Kuogee Hsieh
  Cc: David Airlie, linux-arm-msm, dri-devel, Stephen Boyd, freedreno

It is possible to supply display-connector (bridge) to the DP interface,
add support for parsing it too.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/dp/dp_parser.c | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c b/drivers/gpu/drm/msm/dp/dp_parser.c
index 901d7967370f..1056b8d5755b 100644
--- a/drivers/gpu/drm/msm/dp/dp_parser.c
+++ b/drivers/gpu/drm/msm/dp/dp_parser.c
@@ -301,17 +301,22 @@ static int dp_parser_parse(struct dp_parser *parser, int connector_type)
 		return rc;
 
 	/*
-	 * Currently we support external bridges only for eDP connectors.
+	 * External bridges are mandatory for eDP interfaces: one has to
+	 * provide at least an eDP panel (which gets wrapped into panel-bridge).
 	 *
-	 * No external bridges are expected for the DisplayPort connector,
-	 * it is physically present in a form of a DP or USB-C connector.
+	 * For DisplayPort interfaces external bridges are optional, so
+	 * silently ignore an error if one is not present (-ENODEV).
 	 */
-	if (connector_type == DRM_MODE_CONNECTOR_eDP) {
-		rc = dp_parser_find_next_bridge(parser);
-		if (rc) {
-			DRM_ERROR("DP: failed to find next bridge\n");
+	rc = dp_parser_find_next_bridge(parser);
+	if (rc == -ENODEV) {
+		if (connector_type == DRM_MODE_CONNECTOR_eDP) {
+			DRM_ERROR("eDP: next bridge is not present\n");
 			return rc;
 		}
+	} else if (rc) {
+		if (rc != -EPROBE_DEFER)
+			DRM_ERROR("DP: error parsing next bridge: %d\n", rc);
+		return rc;
 	}
 
 	/* Map the corresponding regulator information according to
-- 
2.34.1


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

* [RFC PATCH v2 4/5] drm/msm/dp: replace dp_connector with drm_bridge_connector
  2022-02-11 22:40 ` Dmitry Baryshkov
@ 2022-02-11 22:40   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 84+ messages in thread
From: Dmitry Baryshkov @ 2022-02-11 22:40 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar, Kuogee Hsieh
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

There is little point in having both connector and root bridge
implementation in the same driver. Move connector's functionality to the
bridge to let next bridge in chain to override it.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/dp/dp_display.c |  22 +++---
 drivers/gpu/drm/msm/dp/dp_drm.c     | 113 ++++++++++------------------
 2 files changed, 52 insertions(+), 83 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index 45f9a912ecc5..59e5e5b8e5b4 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -1501,6 +1501,17 @@ int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev,
 
 	dp_display->encoder = encoder;
 
+	dp_display->bridge = msm_dp_bridge_init(dp_display, dev, encoder);
+	if (IS_ERR(dp_display->bridge)) {
+		ret = PTR_ERR(dp_display->bridge);
+		DRM_DEV_ERROR(dev->dev,
+			"failed to create dp bridge: %d\n", ret);
+		dp_display->bridge = NULL;
+		return ret;
+	}
+
+	priv->bridges[priv->num_bridges++] = dp_display->bridge;
+
 	dp_display->connector = dp_drm_connector_init(dp_display);
 	if (IS_ERR(dp_display->connector)) {
 		ret = PTR_ERR(dp_display->connector);
@@ -1514,17 +1525,6 @@ int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev,
 
 	priv->connectors[priv->num_connectors++] = dp_display->connector;
 
-	dp_display->bridge = msm_dp_bridge_init(dp_display, dev, encoder);
-	if (IS_ERR(dp_display->bridge)) {
-		ret = PTR_ERR(dp_display->bridge);
-		DRM_DEV_ERROR(dev->dev,
-			"failed to create dp bridge: %d\n", ret);
-		dp_display->bridge = NULL;
-		return ret;
-	}
-
-	priv->bridges[priv->num_bridges++] = dp_display->bridge;
-
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
index 80f59cf99089..57800b865fe6 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.c
+++ b/drivers/gpu/drm/msm/dp/dp_drm.c
@@ -6,6 +6,7 @@
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_atomic.h>
 #include <drm/drm_bridge.h>
+#include <drm/drm_bridge_connector.h>
 #include <drm/drm_crtc.h>
 
 #include "msm_drv.h"
@@ -20,24 +21,16 @@ struct msm_dp_bridge {
 
 #define to_dp_display(x)     container_of((x), struct msm_dp_bridge, bridge)
 
-struct dp_connector {
-	struct drm_connector base;
-	struct msm_dp *dp_display;
-};
-#define to_dp_connector(x) container_of(x, struct dp_connector, base)
-
 /**
- * dp_connector_detect - callback to determine if connector is connected
- * @conn: Pointer to drm connector structure
- * @force: Force detect setting from drm framework
- * Returns: Connector 'is connected' status
+ * dp_bridge_detect - callback to determine if connector is connected
+ * @bridge: Pointer to drm bridge structure
+ * Returns: Bridge's 'is connected' status
  */
-static enum drm_connector_status dp_connector_detect(struct drm_connector *conn,
-		bool force)
+static enum drm_connector_status dp_bridge_detect(struct drm_bridge *bridge)
 {
 	struct msm_dp *dp;
 
-	dp = to_dp_connector(conn)->dp_display;
+	dp = to_dp_display(bridge)->dp_display;
 
 	DRM_DEBUG_DP("is_connected = %s\n",
 		(dp->is_connected) ? "true" : "false");
@@ -47,11 +40,12 @@ static enum drm_connector_status dp_connector_detect(struct drm_connector *conn,
 }
 
 /**
- * dp_connector_get_modes - callback to add drm modes via drm_mode_probed_add()
+ * dp_bridge_get_modes - callback to add drm modes via drm_mode_probed_add()
+ * @bridge: Poiner to drm bridge
  * @connector: Pointer to drm connector structure
  * Returns: Number of modes added
  */
-static int dp_connector_get_modes(struct drm_connector *connector)
+static int dp_bridge_get_modes(struct drm_bridge *bridge, struct drm_connector *connector)
 {
 	int rc = 0;
 	struct msm_dp *dp;
@@ -61,7 +55,7 @@ static int dp_connector_get_modes(struct drm_connector *connector)
 	if (!connector)
 		return 0;
 
-	dp = to_dp_connector(connector)->dp_display;
+	dp = to_dp_display(bridge)->dp_display;
 
 	dp_mode = kzalloc(sizeof(*dp_mode),  GFP_KERNEL);
 	if (!dp_mode)
@@ -102,18 +96,20 @@ static int dp_connector_get_modes(struct drm_connector *connector)
 }
 
 /**
- * dp_connector_mode_valid - callback to determine if specified mode is valid
- * @connector: Pointer to drm connector structure
+ * dp_bridge_mode_valid - callback to determine if specified mode is valid
+ * @bridge: Pointer to drm bridge structure
+ * @info: display info
  * @mode: Pointer to drm mode structure
  * Returns: Validity status for specified mode
  */
-static enum drm_mode_status dp_connector_mode_valid(
-		struct drm_connector *connector,
-		struct drm_display_mode *mode)
+static enum drm_mode_status dp_bridge_mode_valid(
+		struct drm_bridge *bridge,
+		const struct drm_display_info *info,
+		const struct drm_display_mode *mode)
 {
 	struct msm_dp *dp_disp;
 
-	dp_disp = to_dp_connector(connector)->dp_display;
+	dp_disp = to_dp_display(bridge)->dp_display;
 
 	if ((dp_disp->max_pclk_khz <= 0) ||
 			(dp_disp->max_pclk_khz > DP_MAX_PIXEL_CLK_KHZ) ||
@@ -123,55 +119,6 @@ static enum drm_mode_status dp_connector_mode_valid(
 	return dp_display_validate_mode(dp_disp, mode->clock);
 }
 
-static const struct drm_connector_funcs dp_connector_funcs = {
-	.detect = dp_connector_detect,
-	.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 dp_connector_helper_funcs = {
-	.get_modes = dp_connector_get_modes,
-	.mode_valid = dp_connector_mode_valid,
-};
-
-/* connector initialization */
-struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display)
-{
-	struct drm_connector *connector = NULL;
-	struct dp_connector *dp_connector;
-	int ret;
-
-	dp_connector = devm_kzalloc(dp_display->drm_dev->dev,
-					sizeof(*dp_connector),
-					GFP_KERNEL);
-	if (!dp_connector)
-		return ERR_PTR(-ENOMEM);
-
-	dp_connector->dp_display = dp_display;
-
-	connector = &dp_connector->base;
-
-	ret = drm_connector_init(dp_display->drm_dev, connector,
-			&dp_connector_funcs,
-			dp_display->connector_type);
-	if (ret)
-		return ERR_PTR(ret);
-
-	drm_connector_helper_add(connector, &dp_connector_helper_funcs);
-
-	/*
-	 * Enable HPD to let hpd event is handled when cable is connected.
-	 */
-	connector->polled = DRM_CONNECTOR_POLL_HPD;
-
-	drm_connector_attach_encoder(connector, dp_display->encoder);
-
-	return connector;
-}
-
 static void dp_bridge_mode_set(struct drm_bridge *drm_bridge,
 				const struct drm_display_mode *mode,
 				const struct drm_display_mode *adjusted_mode)
@@ -211,6 +158,9 @@ static const struct drm_bridge_funcs dp_bridge_ops = {
 	.disable      = dp_bridge_disable,
 	.post_disable = dp_bridge_post_disable,
 	.mode_set     = dp_bridge_mode_set,
+	.mode_valid   = dp_bridge_mode_valid,
+	.get_modes    = dp_bridge_get_modes,
+	.detect       = dp_bridge_detect,
 };
 
 struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display, struct drm_device *dev,
@@ -228,7 +178,12 @@ struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display, struct drm_devi
 
 	bridge = &dp_bridge->bridge;
 	bridge->funcs = &dp_bridge_ops;
-	bridge->encoder = encoder;
+	bridge->type = dp_display->connector_type;
+
+	bridge->ops =
+		DRM_BRIDGE_OP_DETECT |
+		DRM_BRIDGE_OP_HPD |
+		DRM_BRIDGE_OP_MODES;
 
 	rc = drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
 	if (rc) {
@@ -249,3 +204,17 @@ struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display, struct drm_devi
 
 	return bridge;
 }
+
+/* connector initialization */
+struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display)
+{
+	struct drm_connector *connector = NULL;
+
+	connector = drm_bridge_connector_init(dp_display->drm_dev, dp_display->encoder);
+	if (IS_ERR(connector))
+		return connector;
+
+	drm_connector_attach_encoder(connector, dp_display->encoder);
+
+	return connector;
+}
-- 
2.34.1


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

* [RFC PATCH v2 4/5] drm/msm/dp: replace dp_connector with drm_bridge_connector
@ 2022-02-11 22:40   ` Dmitry Baryshkov
  0 siblings, 0 replies; 84+ messages in thread
From: Dmitry Baryshkov @ 2022-02-11 22:40 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar, Kuogee Hsieh
  Cc: David Airlie, linux-arm-msm, dri-devel, Stephen Boyd, freedreno

There is little point in having both connector and root bridge
implementation in the same driver. Move connector's functionality to the
bridge to let next bridge in chain to override it.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/dp/dp_display.c |  22 +++---
 drivers/gpu/drm/msm/dp/dp_drm.c     | 113 ++++++++++------------------
 2 files changed, 52 insertions(+), 83 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index 45f9a912ecc5..59e5e5b8e5b4 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -1501,6 +1501,17 @@ int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev,
 
 	dp_display->encoder = encoder;
 
+	dp_display->bridge = msm_dp_bridge_init(dp_display, dev, encoder);
+	if (IS_ERR(dp_display->bridge)) {
+		ret = PTR_ERR(dp_display->bridge);
+		DRM_DEV_ERROR(dev->dev,
+			"failed to create dp bridge: %d\n", ret);
+		dp_display->bridge = NULL;
+		return ret;
+	}
+
+	priv->bridges[priv->num_bridges++] = dp_display->bridge;
+
 	dp_display->connector = dp_drm_connector_init(dp_display);
 	if (IS_ERR(dp_display->connector)) {
 		ret = PTR_ERR(dp_display->connector);
@@ -1514,17 +1525,6 @@ int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev,
 
 	priv->connectors[priv->num_connectors++] = dp_display->connector;
 
-	dp_display->bridge = msm_dp_bridge_init(dp_display, dev, encoder);
-	if (IS_ERR(dp_display->bridge)) {
-		ret = PTR_ERR(dp_display->bridge);
-		DRM_DEV_ERROR(dev->dev,
-			"failed to create dp bridge: %d\n", ret);
-		dp_display->bridge = NULL;
-		return ret;
-	}
-
-	priv->bridges[priv->num_bridges++] = dp_display->bridge;
-
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
index 80f59cf99089..57800b865fe6 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.c
+++ b/drivers/gpu/drm/msm/dp/dp_drm.c
@@ -6,6 +6,7 @@
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_atomic.h>
 #include <drm/drm_bridge.h>
+#include <drm/drm_bridge_connector.h>
 #include <drm/drm_crtc.h>
 
 #include "msm_drv.h"
@@ -20,24 +21,16 @@ struct msm_dp_bridge {
 
 #define to_dp_display(x)     container_of((x), struct msm_dp_bridge, bridge)
 
-struct dp_connector {
-	struct drm_connector base;
-	struct msm_dp *dp_display;
-};
-#define to_dp_connector(x) container_of(x, struct dp_connector, base)
-
 /**
- * dp_connector_detect - callback to determine if connector is connected
- * @conn: Pointer to drm connector structure
- * @force: Force detect setting from drm framework
- * Returns: Connector 'is connected' status
+ * dp_bridge_detect - callback to determine if connector is connected
+ * @bridge: Pointer to drm bridge structure
+ * Returns: Bridge's 'is connected' status
  */
-static enum drm_connector_status dp_connector_detect(struct drm_connector *conn,
-		bool force)
+static enum drm_connector_status dp_bridge_detect(struct drm_bridge *bridge)
 {
 	struct msm_dp *dp;
 
-	dp = to_dp_connector(conn)->dp_display;
+	dp = to_dp_display(bridge)->dp_display;
 
 	DRM_DEBUG_DP("is_connected = %s\n",
 		(dp->is_connected) ? "true" : "false");
@@ -47,11 +40,12 @@ static enum drm_connector_status dp_connector_detect(struct drm_connector *conn,
 }
 
 /**
- * dp_connector_get_modes - callback to add drm modes via drm_mode_probed_add()
+ * dp_bridge_get_modes - callback to add drm modes via drm_mode_probed_add()
+ * @bridge: Poiner to drm bridge
  * @connector: Pointer to drm connector structure
  * Returns: Number of modes added
  */
-static int dp_connector_get_modes(struct drm_connector *connector)
+static int dp_bridge_get_modes(struct drm_bridge *bridge, struct drm_connector *connector)
 {
 	int rc = 0;
 	struct msm_dp *dp;
@@ -61,7 +55,7 @@ static int dp_connector_get_modes(struct drm_connector *connector)
 	if (!connector)
 		return 0;
 
-	dp = to_dp_connector(connector)->dp_display;
+	dp = to_dp_display(bridge)->dp_display;
 
 	dp_mode = kzalloc(sizeof(*dp_mode),  GFP_KERNEL);
 	if (!dp_mode)
@@ -102,18 +96,20 @@ static int dp_connector_get_modes(struct drm_connector *connector)
 }
 
 /**
- * dp_connector_mode_valid - callback to determine if specified mode is valid
- * @connector: Pointer to drm connector structure
+ * dp_bridge_mode_valid - callback to determine if specified mode is valid
+ * @bridge: Pointer to drm bridge structure
+ * @info: display info
  * @mode: Pointer to drm mode structure
  * Returns: Validity status for specified mode
  */
-static enum drm_mode_status dp_connector_mode_valid(
-		struct drm_connector *connector,
-		struct drm_display_mode *mode)
+static enum drm_mode_status dp_bridge_mode_valid(
+		struct drm_bridge *bridge,
+		const struct drm_display_info *info,
+		const struct drm_display_mode *mode)
 {
 	struct msm_dp *dp_disp;
 
-	dp_disp = to_dp_connector(connector)->dp_display;
+	dp_disp = to_dp_display(bridge)->dp_display;
 
 	if ((dp_disp->max_pclk_khz <= 0) ||
 			(dp_disp->max_pclk_khz > DP_MAX_PIXEL_CLK_KHZ) ||
@@ -123,55 +119,6 @@ static enum drm_mode_status dp_connector_mode_valid(
 	return dp_display_validate_mode(dp_disp, mode->clock);
 }
 
-static const struct drm_connector_funcs dp_connector_funcs = {
-	.detect = dp_connector_detect,
-	.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 dp_connector_helper_funcs = {
-	.get_modes = dp_connector_get_modes,
-	.mode_valid = dp_connector_mode_valid,
-};
-
-/* connector initialization */
-struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display)
-{
-	struct drm_connector *connector = NULL;
-	struct dp_connector *dp_connector;
-	int ret;
-
-	dp_connector = devm_kzalloc(dp_display->drm_dev->dev,
-					sizeof(*dp_connector),
-					GFP_KERNEL);
-	if (!dp_connector)
-		return ERR_PTR(-ENOMEM);
-
-	dp_connector->dp_display = dp_display;
-
-	connector = &dp_connector->base;
-
-	ret = drm_connector_init(dp_display->drm_dev, connector,
-			&dp_connector_funcs,
-			dp_display->connector_type);
-	if (ret)
-		return ERR_PTR(ret);
-
-	drm_connector_helper_add(connector, &dp_connector_helper_funcs);
-
-	/*
-	 * Enable HPD to let hpd event is handled when cable is connected.
-	 */
-	connector->polled = DRM_CONNECTOR_POLL_HPD;
-
-	drm_connector_attach_encoder(connector, dp_display->encoder);
-
-	return connector;
-}
-
 static void dp_bridge_mode_set(struct drm_bridge *drm_bridge,
 				const struct drm_display_mode *mode,
 				const struct drm_display_mode *adjusted_mode)
@@ -211,6 +158,9 @@ static const struct drm_bridge_funcs dp_bridge_ops = {
 	.disable      = dp_bridge_disable,
 	.post_disable = dp_bridge_post_disable,
 	.mode_set     = dp_bridge_mode_set,
+	.mode_valid   = dp_bridge_mode_valid,
+	.get_modes    = dp_bridge_get_modes,
+	.detect       = dp_bridge_detect,
 };
 
 struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display, struct drm_device *dev,
@@ -228,7 +178,12 @@ struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display, struct drm_devi
 
 	bridge = &dp_bridge->bridge;
 	bridge->funcs = &dp_bridge_ops;
-	bridge->encoder = encoder;
+	bridge->type = dp_display->connector_type;
+
+	bridge->ops =
+		DRM_BRIDGE_OP_DETECT |
+		DRM_BRIDGE_OP_HPD |
+		DRM_BRIDGE_OP_MODES;
 
 	rc = drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
 	if (rc) {
@@ -249,3 +204,17 @@ struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display, struct drm_devi
 
 	return bridge;
 }
+
+/* connector initialization */
+struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display)
+{
+	struct drm_connector *connector = NULL;
+
+	connector = drm_bridge_connector_init(dp_display->drm_dev, dp_display->encoder);
+	if (IS_ERR(connector))
+		return connector;
+
+	drm_connector_attach_encoder(connector, dp_display->encoder);
+
+	return connector;
+}
-- 
2.34.1


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

* [RFC PATCH v2 5/5] drm/msm/dp: remove extra wrappers and public functions
  2022-02-11 22:40 ` Dmitry Baryshkov
@ 2022-02-11 22:40   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 84+ messages in thread
From: Dmitry Baryshkov @ 2022-02-11 22:40 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar, Kuogee Hsieh
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

dp_bridge's functions are thin wrappers around the msm_dp_display_*
family. Squash dp_bridge callbacks into respective msm_dp_display
functions, removing the latter functions from public space.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/dp/dp_display.c | 54 +++++++++++++++-------
 drivers/gpu/drm/msm/dp/dp_display.h |  1 -
 drivers/gpu/drm/msm/dp/dp_drm.c     | 72 ++---------------------------
 drivers/gpu/drm/msm/dp/dp_drm.h     | 22 ++++++++-
 drivers/gpu/drm/msm/msm_drv.h       | 31 -------------
 5 files changed, 60 insertions(+), 120 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index 59e5e5b8e5b4..a9b641a68bff 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -10,7 +10,6 @@
 #include <linux/component.h>
 #include <linux/of_irq.h>
 #include <linux/delay.h>
-#include <drm/drm_panel.h>
 
 #include "msm_drv.h"
 #include "msm_kms.h"
@@ -945,18 +944,36 @@ int dp_display_set_plugged_cb(struct msm_dp *dp_display,
 	return 0;
 }
 
-int dp_display_validate_mode(struct msm_dp *dp, u32 mode_pclk_khz)
+/**
+ * dp_bridge_mode_valid - callback to determine if specified mode is valid
+ * @bridge: Pointer to drm bridge structure
+ * @info: display info
+ * @mode: Pointer to drm mode structure
+ * Returns: Validity status for specified mode
+ */
+enum drm_mode_status dp_bridge_mode_valid(struct drm_bridge *bridge,
+					  const struct drm_display_info *info,
+					  const struct drm_display_mode *mode)
 {
 	const u32 num_components = 3, default_bpp = 24;
 	struct dp_display_private *dp_display;
 	struct dp_link_info *link_info;
 	u32 mode_rate_khz = 0, supported_rate_khz = 0, mode_bpp = 0;
+	struct msm_dp *dp;
+	int mode_pclk_khz = mode->clock;
+
+	dp = to_dp_bridge(bridge)->dp_display;
 
 	if (!dp || !mode_pclk_khz || !dp->connector) {
 		DRM_ERROR("invalid params\n");
 		return -EINVAL;
 	}
 
+	if ((dp->max_pclk_khz <= 0) ||
+			(dp->max_pclk_khz > DP_MAX_PIXEL_CLK_KHZ) ||
+			(mode->clock > dp->max_pclk_khz))
+		return MODE_BAD;
+
 	dp_display = container_of(dp, struct dp_display_private, dp_display);
 	link_info = &dp_display->panel->link_info;
 
@@ -1501,7 +1518,7 @@ int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev,
 
 	dp_display->encoder = encoder;
 
-	dp_display->bridge = msm_dp_bridge_init(dp_display, dev, encoder);
+	dp_display->bridge = dp_bridge_init(dp_display, dev, encoder);
 	if (IS_ERR(dp_display->bridge)) {
 		ret = PTR_ERR(dp_display->bridge);
 		DRM_DEV_ERROR(dev->dev,
@@ -1528,8 +1545,10 @@ int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev,
 	return 0;
 }
 
-int msm_dp_display_enable(struct msm_dp *dp, struct drm_encoder *encoder)
+void dp_bridge_enable(struct drm_bridge *drm_bridge)
 {
+	struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
+	struct msm_dp *dp = dp_bridge->dp_display;
 	int rc = 0;
 	struct dp_display_private *dp_display;
 	u32 state;
@@ -1537,7 +1556,7 @@ int msm_dp_display_enable(struct msm_dp *dp, struct drm_encoder *encoder)
 	dp_display = container_of(dp, struct dp_display_private, dp_display);
 	if (!dp_display->dp_mode.drm_mode.clock) {
 		DRM_ERROR("invalid params\n");
-		return -EINVAL;
+		return;
 	}
 
 	mutex_lock(&dp_display->event_mutex);
@@ -1549,14 +1568,14 @@ int msm_dp_display_enable(struct msm_dp *dp, struct drm_encoder *encoder)
 	if (rc) {
 		DRM_ERROR("Failed to perform a mode set, rc=%d\n", rc);
 		mutex_unlock(&dp_display->event_mutex);
-		return rc;
+		return;
 	}
 
 	rc = dp_display_prepare(dp);
 	if (rc) {
 		DRM_ERROR("DP display prepare failed, rc=%d\n", rc);
 		mutex_unlock(&dp_display->event_mutex);
-		return rc;
+		return;
 	}
 
 	state =  dp_display->hpd_state;
@@ -1581,23 +1600,23 @@ int msm_dp_display_enable(struct msm_dp *dp, struct drm_encoder *encoder)
 	dp_display->hpd_state = ST_CONNECTED;
 
 	mutex_unlock(&dp_display->event_mutex);
-
-	return rc;
 }
 
-int msm_dp_display_pre_disable(struct msm_dp *dp, struct drm_encoder *encoder)
+void dp_bridge_disable(struct drm_bridge *drm_bridge)
 {
+	struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
+	struct msm_dp *dp = dp_bridge->dp_display;
 	struct dp_display_private *dp_display;
 
 	dp_display = container_of(dp, struct dp_display_private, dp_display);
 
 	dp_ctrl_push_idle(dp_display->ctrl);
-
-	return 0;
 }
 
-int msm_dp_display_disable(struct msm_dp *dp, struct drm_encoder *encoder)
+void dp_bridge_post_disable(struct drm_bridge *drm_bridge)
 {
+	struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
+	struct msm_dp *dp = dp_bridge->dp_display;
 	int rc = 0;
 	u32 state;
 	struct dp_display_private *dp_display;
@@ -1624,13 +1643,14 @@ int msm_dp_display_disable(struct msm_dp *dp, struct drm_encoder *encoder)
 	}
 
 	mutex_unlock(&dp_display->event_mutex);
-	return rc;
 }
 
-void msm_dp_display_mode_set(struct msm_dp *dp, struct drm_encoder *encoder,
-				const struct drm_display_mode *mode,
-				const struct drm_display_mode *adjusted_mode)
+void dp_bridge_mode_set(struct drm_bridge *drm_bridge,
+			const struct drm_display_mode *mode,
+			const struct drm_display_mode *adjusted_mode)
 {
+	struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
+	struct msm_dp *dp = dp_bridge->dp_display;
 	struct dp_display_private *dp_display;
 
 	dp_display = container_of(dp, struct dp_display_private, dp_display);
diff --git a/drivers/gpu/drm/msm/dp/dp_display.h b/drivers/gpu/drm/msm/dp/dp_display.h
index 7af2b186d2d9..49a1d89681ac 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.h
+++ b/drivers/gpu/drm/msm/dp/dp_display.h
@@ -32,7 +32,6 @@ struct msm_dp {
 
 int dp_display_set_plugged_cb(struct msm_dp *dp_display,
 		hdmi_codec_plugged_cb fn, struct device *codec_dev);
-int dp_display_validate_mode(struct msm_dp *dp_display, u32 mode_pclk_khz);
 int dp_display_get_modes(struct msm_dp *dp_display,
 		struct dp_display_mode *dp_mode);
 int dp_display_request_irq(struct msm_dp *dp_display);
diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
index 57800b865fe6..7ce1aca48687 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.c
+++ b/drivers/gpu/drm/msm/dp/dp_drm.c
@@ -13,14 +13,6 @@
 #include "msm_kms.h"
 #include "dp_drm.h"
 
-
-struct msm_dp_bridge {
-	struct drm_bridge bridge;
-	struct msm_dp *dp_display;
-};
-
-#define to_dp_display(x)     container_of((x), struct msm_dp_bridge, bridge)
-
 /**
  * dp_bridge_detect - callback to determine if connector is connected
  * @bridge: Pointer to drm bridge structure
@@ -30,7 +22,7 @@ static enum drm_connector_status dp_bridge_detect(struct drm_bridge *bridge)
 {
 	struct msm_dp *dp;
 
-	dp = to_dp_display(bridge)->dp_display;
+	dp = to_dp_bridge(bridge)->dp_display;
 
 	DRM_DEBUG_DP("is_connected = %s\n",
 		(dp->is_connected) ? "true" : "false");
@@ -55,7 +47,7 @@ static int dp_bridge_get_modes(struct drm_bridge *bridge, struct drm_connector *
 	if (!connector)
 		return 0;
 
-	dp = to_dp_display(bridge)->dp_display;
+	dp = to_dp_bridge(bridge)->dp_display;
 
 	dp_mode = kzalloc(sizeof(*dp_mode),  GFP_KERNEL);
 	if (!dp_mode)
@@ -95,64 +87,6 @@ static int dp_bridge_get_modes(struct drm_bridge *bridge, struct drm_connector *
 	return rc;
 }
 
-/**
- * dp_bridge_mode_valid - callback to determine if specified mode is valid
- * @bridge: Pointer to drm bridge structure
- * @info: display info
- * @mode: Pointer to drm mode structure
- * Returns: Validity status for specified mode
- */
-static enum drm_mode_status dp_bridge_mode_valid(
-		struct drm_bridge *bridge,
-		const struct drm_display_info *info,
-		const struct drm_display_mode *mode)
-{
-	struct msm_dp *dp_disp;
-
-	dp_disp = to_dp_display(bridge)->dp_display;
-
-	if ((dp_disp->max_pclk_khz <= 0) ||
-			(dp_disp->max_pclk_khz > DP_MAX_PIXEL_CLK_KHZ) ||
-			(mode->clock > dp_disp->max_pclk_khz))
-		return MODE_BAD;
-
-	return dp_display_validate_mode(dp_disp, mode->clock);
-}
-
-static void dp_bridge_mode_set(struct drm_bridge *drm_bridge,
-				const struct drm_display_mode *mode,
-				const struct drm_display_mode *adjusted_mode)
-{
-	struct msm_dp_bridge *dp_bridge = to_dp_display(drm_bridge);
-	struct msm_dp *dp_display = dp_bridge->dp_display;
-
-	msm_dp_display_mode_set(dp_display, drm_bridge->encoder, mode, adjusted_mode);
-}
-
-static void dp_bridge_enable(struct drm_bridge *drm_bridge)
-{
-	struct msm_dp_bridge *dp_bridge = to_dp_display(drm_bridge);
-	struct msm_dp *dp_display = dp_bridge->dp_display;
-
-	msm_dp_display_enable(dp_display, drm_bridge->encoder);
-}
-
-static void dp_bridge_disable(struct drm_bridge *drm_bridge)
-{
-	struct msm_dp_bridge *dp_bridge = to_dp_display(drm_bridge);
-	struct msm_dp *dp_display = dp_bridge->dp_display;
-
-	msm_dp_display_pre_disable(dp_display, drm_bridge->encoder);
-}
-
-static void dp_bridge_post_disable(struct drm_bridge *drm_bridge)
-{
-	struct msm_dp_bridge *dp_bridge = to_dp_display(drm_bridge);
-	struct msm_dp *dp_display = dp_bridge->dp_display;
-
-	msm_dp_display_disable(dp_display, drm_bridge->encoder);
-}
-
 static const struct drm_bridge_funcs dp_bridge_ops = {
 	.enable       = dp_bridge_enable,
 	.disable      = dp_bridge_disable,
@@ -163,7 +97,7 @@ static const struct drm_bridge_funcs dp_bridge_ops = {
 	.detect       = dp_bridge_detect,
 };
 
-struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display, struct drm_device *dev,
+struct drm_bridge *dp_bridge_init(struct msm_dp *dp_display, struct drm_device *dev,
 			struct drm_encoder *encoder)
 {
 	int rc;
diff --git a/drivers/gpu/drm/msm/dp/dp_drm.h b/drivers/gpu/drm/msm/dp/dp_drm.h
index c27bfceefdf0..f4b1ed1e24f7 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.h
+++ b/drivers/gpu/drm/msm/dp/dp_drm.h
@@ -7,12 +7,30 @@
 #define _DP_DRM_H_
 
 #include <linux/types.h>
-#include <drm/drm_crtc.h>
-#include <drm/drm_crtc_helper.h>
+#include <drm/drm_bridge.h>
 
 #include "msm_drv.h"
 #include "dp_display.h"
 
+struct msm_dp_bridge {
+	struct drm_bridge bridge;
+	struct msm_dp *dp_display;
+};
+
+#define to_dp_bridge(x)     container_of((x), struct msm_dp_bridge, bridge)
+
 struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display);
+struct drm_bridge *dp_bridge_init(struct msm_dp *dp_display, struct drm_device *dev,
+			struct drm_encoder *encoder);
+
+void dp_bridge_enable(struct drm_bridge *drm_bridge);
+void dp_bridge_disable(struct drm_bridge *drm_bridge);
+void dp_bridge_post_disable(struct drm_bridge *drm_bridge);
+enum drm_mode_status dp_bridge_mode_valid(struct drm_bridge *bridge,
+					  const struct drm_display_info *info,
+					  const struct drm_display_mode *mode);
+void dp_bridge_mode_set(struct drm_bridge *drm_bridge,
+			const struct drm_display_mode *mode,
+			const struct drm_display_mode *adjusted_mode);
 
 #endif /* _DP_DRM_H_ */
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index d7574e6bd4e4..b698a3be6072 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -385,16 +385,6 @@ int __init msm_dp_register(void);
 void __exit msm_dp_unregister(void);
 int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev,
 			 struct drm_encoder *encoder);
-int msm_dp_display_enable(struct msm_dp *dp, struct drm_encoder *encoder);
-int msm_dp_display_disable(struct msm_dp *dp, struct drm_encoder *encoder);
-int msm_dp_display_pre_disable(struct msm_dp *dp, struct drm_encoder *encoder);
-void msm_dp_display_mode_set(struct msm_dp *dp, struct drm_encoder *encoder,
-				const struct drm_display_mode *mode,
-				const struct drm_display_mode *adjusted_mode);
-
-struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display,
-					struct drm_device *dev,
-					struct drm_encoder *encoder);
 void msm_dp_irq_postinstall(struct msm_dp *dp_display);
 void msm_dp_snapshot(struct msm_disp_state *disp_state, struct msm_dp *dp_display);
 
@@ -414,27 +404,6 @@ static inline int msm_dp_modeset_init(struct msm_dp *dp_display,
 {
 	return -EINVAL;
 }
-static inline int msm_dp_display_enable(struct msm_dp *dp,
-					struct drm_encoder *encoder)
-{
-	return -EINVAL;
-}
-static inline int msm_dp_display_disable(struct msm_dp *dp,
-					struct drm_encoder *encoder)
-{
-	return -EINVAL;
-}
-static inline int msm_dp_display_pre_disable(struct msm_dp *dp,
-					struct drm_encoder *encoder)
-{
-	return -EINVAL;
-}
-static inline void msm_dp_display_mode_set(struct msm_dp *dp,
-				struct drm_encoder *encoder,
-				const struct drm_display_mode *mode,
-				const struct drm_display_mode *adjusted_mode)
-{
-}
 
 static inline void msm_dp_irq_postinstall(struct msm_dp *dp_display)
 {
-- 
2.34.1


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

* [RFC PATCH v2 5/5] drm/msm/dp: remove extra wrappers and public functions
@ 2022-02-11 22:40   ` Dmitry Baryshkov
  0 siblings, 0 replies; 84+ messages in thread
From: Dmitry Baryshkov @ 2022-02-11 22:40 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar, Kuogee Hsieh
  Cc: David Airlie, linux-arm-msm, dri-devel, Stephen Boyd, freedreno

dp_bridge's functions are thin wrappers around the msm_dp_display_*
family. Squash dp_bridge callbacks into respective msm_dp_display
functions, removing the latter functions from public space.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/dp/dp_display.c | 54 +++++++++++++++-------
 drivers/gpu/drm/msm/dp/dp_display.h |  1 -
 drivers/gpu/drm/msm/dp/dp_drm.c     | 72 ++---------------------------
 drivers/gpu/drm/msm/dp/dp_drm.h     | 22 ++++++++-
 drivers/gpu/drm/msm/msm_drv.h       | 31 -------------
 5 files changed, 60 insertions(+), 120 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index 59e5e5b8e5b4..a9b641a68bff 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -10,7 +10,6 @@
 #include <linux/component.h>
 #include <linux/of_irq.h>
 #include <linux/delay.h>
-#include <drm/drm_panel.h>
 
 #include "msm_drv.h"
 #include "msm_kms.h"
@@ -945,18 +944,36 @@ int dp_display_set_plugged_cb(struct msm_dp *dp_display,
 	return 0;
 }
 
-int dp_display_validate_mode(struct msm_dp *dp, u32 mode_pclk_khz)
+/**
+ * dp_bridge_mode_valid - callback to determine if specified mode is valid
+ * @bridge: Pointer to drm bridge structure
+ * @info: display info
+ * @mode: Pointer to drm mode structure
+ * Returns: Validity status for specified mode
+ */
+enum drm_mode_status dp_bridge_mode_valid(struct drm_bridge *bridge,
+					  const struct drm_display_info *info,
+					  const struct drm_display_mode *mode)
 {
 	const u32 num_components = 3, default_bpp = 24;
 	struct dp_display_private *dp_display;
 	struct dp_link_info *link_info;
 	u32 mode_rate_khz = 0, supported_rate_khz = 0, mode_bpp = 0;
+	struct msm_dp *dp;
+	int mode_pclk_khz = mode->clock;
+
+	dp = to_dp_bridge(bridge)->dp_display;
 
 	if (!dp || !mode_pclk_khz || !dp->connector) {
 		DRM_ERROR("invalid params\n");
 		return -EINVAL;
 	}
 
+	if ((dp->max_pclk_khz <= 0) ||
+			(dp->max_pclk_khz > DP_MAX_PIXEL_CLK_KHZ) ||
+			(mode->clock > dp->max_pclk_khz))
+		return MODE_BAD;
+
 	dp_display = container_of(dp, struct dp_display_private, dp_display);
 	link_info = &dp_display->panel->link_info;
 
@@ -1501,7 +1518,7 @@ int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev,
 
 	dp_display->encoder = encoder;
 
-	dp_display->bridge = msm_dp_bridge_init(dp_display, dev, encoder);
+	dp_display->bridge = dp_bridge_init(dp_display, dev, encoder);
 	if (IS_ERR(dp_display->bridge)) {
 		ret = PTR_ERR(dp_display->bridge);
 		DRM_DEV_ERROR(dev->dev,
@@ -1528,8 +1545,10 @@ int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev,
 	return 0;
 }
 
-int msm_dp_display_enable(struct msm_dp *dp, struct drm_encoder *encoder)
+void dp_bridge_enable(struct drm_bridge *drm_bridge)
 {
+	struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
+	struct msm_dp *dp = dp_bridge->dp_display;
 	int rc = 0;
 	struct dp_display_private *dp_display;
 	u32 state;
@@ -1537,7 +1556,7 @@ int msm_dp_display_enable(struct msm_dp *dp, struct drm_encoder *encoder)
 	dp_display = container_of(dp, struct dp_display_private, dp_display);
 	if (!dp_display->dp_mode.drm_mode.clock) {
 		DRM_ERROR("invalid params\n");
-		return -EINVAL;
+		return;
 	}
 
 	mutex_lock(&dp_display->event_mutex);
@@ -1549,14 +1568,14 @@ int msm_dp_display_enable(struct msm_dp *dp, struct drm_encoder *encoder)
 	if (rc) {
 		DRM_ERROR("Failed to perform a mode set, rc=%d\n", rc);
 		mutex_unlock(&dp_display->event_mutex);
-		return rc;
+		return;
 	}
 
 	rc = dp_display_prepare(dp);
 	if (rc) {
 		DRM_ERROR("DP display prepare failed, rc=%d\n", rc);
 		mutex_unlock(&dp_display->event_mutex);
-		return rc;
+		return;
 	}
 
 	state =  dp_display->hpd_state;
@@ -1581,23 +1600,23 @@ int msm_dp_display_enable(struct msm_dp *dp, struct drm_encoder *encoder)
 	dp_display->hpd_state = ST_CONNECTED;
 
 	mutex_unlock(&dp_display->event_mutex);
-
-	return rc;
 }
 
-int msm_dp_display_pre_disable(struct msm_dp *dp, struct drm_encoder *encoder)
+void dp_bridge_disable(struct drm_bridge *drm_bridge)
 {
+	struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
+	struct msm_dp *dp = dp_bridge->dp_display;
 	struct dp_display_private *dp_display;
 
 	dp_display = container_of(dp, struct dp_display_private, dp_display);
 
 	dp_ctrl_push_idle(dp_display->ctrl);
-
-	return 0;
 }
 
-int msm_dp_display_disable(struct msm_dp *dp, struct drm_encoder *encoder)
+void dp_bridge_post_disable(struct drm_bridge *drm_bridge)
 {
+	struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
+	struct msm_dp *dp = dp_bridge->dp_display;
 	int rc = 0;
 	u32 state;
 	struct dp_display_private *dp_display;
@@ -1624,13 +1643,14 @@ int msm_dp_display_disable(struct msm_dp *dp, struct drm_encoder *encoder)
 	}
 
 	mutex_unlock(&dp_display->event_mutex);
-	return rc;
 }
 
-void msm_dp_display_mode_set(struct msm_dp *dp, struct drm_encoder *encoder,
-				const struct drm_display_mode *mode,
-				const struct drm_display_mode *adjusted_mode)
+void dp_bridge_mode_set(struct drm_bridge *drm_bridge,
+			const struct drm_display_mode *mode,
+			const struct drm_display_mode *adjusted_mode)
 {
+	struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
+	struct msm_dp *dp = dp_bridge->dp_display;
 	struct dp_display_private *dp_display;
 
 	dp_display = container_of(dp, struct dp_display_private, dp_display);
diff --git a/drivers/gpu/drm/msm/dp/dp_display.h b/drivers/gpu/drm/msm/dp/dp_display.h
index 7af2b186d2d9..49a1d89681ac 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.h
+++ b/drivers/gpu/drm/msm/dp/dp_display.h
@@ -32,7 +32,6 @@ struct msm_dp {
 
 int dp_display_set_plugged_cb(struct msm_dp *dp_display,
 		hdmi_codec_plugged_cb fn, struct device *codec_dev);
-int dp_display_validate_mode(struct msm_dp *dp_display, u32 mode_pclk_khz);
 int dp_display_get_modes(struct msm_dp *dp_display,
 		struct dp_display_mode *dp_mode);
 int dp_display_request_irq(struct msm_dp *dp_display);
diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
index 57800b865fe6..7ce1aca48687 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.c
+++ b/drivers/gpu/drm/msm/dp/dp_drm.c
@@ -13,14 +13,6 @@
 #include "msm_kms.h"
 #include "dp_drm.h"
 
-
-struct msm_dp_bridge {
-	struct drm_bridge bridge;
-	struct msm_dp *dp_display;
-};
-
-#define to_dp_display(x)     container_of((x), struct msm_dp_bridge, bridge)
-
 /**
  * dp_bridge_detect - callback to determine if connector is connected
  * @bridge: Pointer to drm bridge structure
@@ -30,7 +22,7 @@ static enum drm_connector_status dp_bridge_detect(struct drm_bridge *bridge)
 {
 	struct msm_dp *dp;
 
-	dp = to_dp_display(bridge)->dp_display;
+	dp = to_dp_bridge(bridge)->dp_display;
 
 	DRM_DEBUG_DP("is_connected = %s\n",
 		(dp->is_connected) ? "true" : "false");
@@ -55,7 +47,7 @@ static int dp_bridge_get_modes(struct drm_bridge *bridge, struct drm_connector *
 	if (!connector)
 		return 0;
 
-	dp = to_dp_display(bridge)->dp_display;
+	dp = to_dp_bridge(bridge)->dp_display;
 
 	dp_mode = kzalloc(sizeof(*dp_mode),  GFP_KERNEL);
 	if (!dp_mode)
@@ -95,64 +87,6 @@ static int dp_bridge_get_modes(struct drm_bridge *bridge, struct drm_connector *
 	return rc;
 }
 
-/**
- * dp_bridge_mode_valid - callback to determine if specified mode is valid
- * @bridge: Pointer to drm bridge structure
- * @info: display info
- * @mode: Pointer to drm mode structure
- * Returns: Validity status for specified mode
- */
-static enum drm_mode_status dp_bridge_mode_valid(
-		struct drm_bridge *bridge,
-		const struct drm_display_info *info,
-		const struct drm_display_mode *mode)
-{
-	struct msm_dp *dp_disp;
-
-	dp_disp = to_dp_display(bridge)->dp_display;
-
-	if ((dp_disp->max_pclk_khz <= 0) ||
-			(dp_disp->max_pclk_khz > DP_MAX_PIXEL_CLK_KHZ) ||
-			(mode->clock > dp_disp->max_pclk_khz))
-		return MODE_BAD;
-
-	return dp_display_validate_mode(dp_disp, mode->clock);
-}
-
-static void dp_bridge_mode_set(struct drm_bridge *drm_bridge,
-				const struct drm_display_mode *mode,
-				const struct drm_display_mode *adjusted_mode)
-{
-	struct msm_dp_bridge *dp_bridge = to_dp_display(drm_bridge);
-	struct msm_dp *dp_display = dp_bridge->dp_display;
-
-	msm_dp_display_mode_set(dp_display, drm_bridge->encoder, mode, adjusted_mode);
-}
-
-static void dp_bridge_enable(struct drm_bridge *drm_bridge)
-{
-	struct msm_dp_bridge *dp_bridge = to_dp_display(drm_bridge);
-	struct msm_dp *dp_display = dp_bridge->dp_display;
-
-	msm_dp_display_enable(dp_display, drm_bridge->encoder);
-}
-
-static void dp_bridge_disable(struct drm_bridge *drm_bridge)
-{
-	struct msm_dp_bridge *dp_bridge = to_dp_display(drm_bridge);
-	struct msm_dp *dp_display = dp_bridge->dp_display;
-
-	msm_dp_display_pre_disable(dp_display, drm_bridge->encoder);
-}
-
-static void dp_bridge_post_disable(struct drm_bridge *drm_bridge)
-{
-	struct msm_dp_bridge *dp_bridge = to_dp_display(drm_bridge);
-	struct msm_dp *dp_display = dp_bridge->dp_display;
-
-	msm_dp_display_disable(dp_display, drm_bridge->encoder);
-}
-
 static const struct drm_bridge_funcs dp_bridge_ops = {
 	.enable       = dp_bridge_enable,
 	.disable      = dp_bridge_disable,
@@ -163,7 +97,7 @@ static const struct drm_bridge_funcs dp_bridge_ops = {
 	.detect       = dp_bridge_detect,
 };
 
-struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display, struct drm_device *dev,
+struct drm_bridge *dp_bridge_init(struct msm_dp *dp_display, struct drm_device *dev,
 			struct drm_encoder *encoder)
 {
 	int rc;
diff --git a/drivers/gpu/drm/msm/dp/dp_drm.h b/drivers/gpu/drm/msm/dp/dp_drm.h
index c27bfceefdf0..f4b1ed1e24f7 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.h
+++ b/drivers/gpu/drm/msm/dp/dp_drm.h
@@ -7,12 +7,30 @@
 #define _DP_DRM_H_
 
 #include <linux/types.h>
-#include <drm/drm_crtc.h>
-#include <drm/drm_crtc_helper.h>
+#include <drm/drm_bridge.h>
 
 #include "msm_drv.h"
 #include "dp_display.h"
 
+struct msm_dp_bridge {
+	struct drm_bridge bridge;
+	struct msm_dp *dp_display;
+};
+
+#define to_dp_bridge(x)     container_of((x), struct msm_dp_bridge, bridge)
+
 struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display);
+struct drm_bridge *dp_bridge_init(struct msm_dp *dp_display, struct drm_device *dev,
+			struct drm_encoder *encoder);
+
+void dp_bridge_enable(struct drm_bridge *drm_bridge);
+void dp_bridge_disable(struct drm_bridge *drm_bridge);
+void dp_bridge_post_disable(struct drm_bridge *drm_bridge);
+enum drm_mode_status dp_bridge_mode_valid(struct drm_bridge *bridge,
+					  const struct drm_display_info *info,
+					  const struct drm_display_mode *mode);
+void dp_bridge_mode_set(struct drm_bridge *drm_bridge,
+			const struct drm_display_mode *mode,
+			const struct drm_display_mode *adjusted_mode);
 
 #endif /* _DP_DRM_H_ */
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index d7574e6bd4e4..b698a3be6072 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -385,16 +385,6 @@ int __init msm_dp_register(void);
 void __exit msm_dp_unregister(void);
 int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev,
 			 struct drm_encoder *encoder);
-int msm_dp_display_enable(struct msm_dp *dp, struct drm_encoder *encoder);
-int msm_dp_display_disable(struct msm_dp *dp, struct drm_encoder *encoder);
-int msm_dp_display_pre_disable(struct msm_dp *dp, struct drm_encoder *encoder);
-void msm_dp_display_mode_set(struct msm_dp *dp, struct drm_encoder *encoder,
-				const struct drm_display_mode *mode,
-				const struct drm_display_mode *adjusted_mode);
-
-struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display,
-					struct drm_device *dev,
-					struct drm_encoder *encoder);
 void msm_dp_irq_postinstall(struct msm_dp *dp_display);
 void msm_dp_snapshot(struct msm_disp_state *disp_state, struct msm_dp *dp_display);
 
@@ -414,27 +404,6 @@ static inline int msm_dp_modeset_init(struct msm_dp *dp_display,
 {
 	return -EINVAL;
 }
-static inline int msm_dp_display_enable(struct msm_dp *dp,
-					struct drm_encoder *encoder)
-{
-	return -EINVAL;
-}
-static inline int msm_dp_display_disable(struct msm_dp *dp,
-					struct drm_encoder *encoder)
-{
-	return -EINVAL;
-}
-static inline int msm_dp_display_pre_disable(struct msm_dp *dp,
-					struct drm_encoder *encoder)
-{
-	return -EINVAL;
-}
-static inline void msm_dp_display_mode_set(struct msm_dp *dp,
-				struct drm_encoder *encoder,
-				const struct drm_display_mode *mode,
-				const struct drm_display_mode *adjusted_mode)
-{
-}
 
 static inline void msm_dp_irq_postinstall(struct msm_dp *dp_display)
 {
-- 
2.34.1


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

* Re: [RFC PATCH v2 1/5] drm/msm/dp: fix panel bridge attachment
  2022-02-11 22:40   ` Dmitry Baryshkov
@ 2022-02-18 21:14     ` Kuogee Hsieh
  -1 siblings, 0 replies; 84+ messages in thread
From: Kuogee Hsieh @ 2022-02-18 21:14 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno


On 2/11/2022 2:40 PM, Dmitry Baryshkov wrote:
> In commit 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
> enable and disable") the DP driver received a drm_bridge instance, which
> is always attached to the encoder as a root bridge. However it conflicts
> with the panel_bridge support for eDP panels. The panel bridge attaches
> to the encoder before the "dp" bridge has a chace to do so. Change
> panel_bridge attachment to come after dp_bridge attachment.
>
> Fixes: 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display enable and disable")
> Cc: Kuogee Hsieh <quic_khsieh@quicinc.com>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Tested-by: Kuogee Hsieh <quic_khsieh@quicinc.com>
> ---
>   drivers/gpu/drm/msm/dp/dp_drm.c | 21 +++++++++++----------
>   1 file changed, 11 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
> index d4d360d19eba..26ef41a4c1b6 100644
> --- a/drivers/gpu/drm/msm/dp/dp_drm.c
> +++ b/drivers/gpu/drm/msm/dp/dp_drm.c
> @@ -169,16 +169,6 @@ struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display)
>   
>   	drm_connector_attach_encoder(connector, dp_display->encoder);
>   
> -	if (dp_display->panel_bridge) {
> -		ret = drm_bridge_attach(dp_display->encoder,
> -					dp_display->panel_bridge, NULL,
> -					DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> -		if (ret < 0) {
> -			DRM_ERROR("failed to attach panel bridge: %d\n", ret);
> -			return ERR_PTR(ret);
> -		}
> -	}
> -
>   	return connector;
>   }
>   
> @@ -246,5 +236,16 @@ struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display, struct drm_devi
>   		return ERR_PTR(rc);
>   	}
>   
> +	if (dp_display->panel_bridge) {
> +		rc = drm_bridge_attach(dp_display->encoder,
> +					dp_display->panel_bridge, bridge,
> +					DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> +		if (rc < 0) {
> +			DRM_ERROR("failed to attach panel bridge: %d\n", rc);
> +			drm_bridge_remove(bridge);
> +			return ERR_PTR(rc);
> +		}
> +	}
> +
>   	return bridge;
>   }

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

* Re: [RFC PATCH v2 1/5] drm/msm/dp: fix panel bridge attachment
@ 2022-02-18 21:14     ` Kuogee Hsieh
  0 siblings, 0 replies; 84+ messages in thread
From: Kuogee Hsieh @ 2022-02-18 21:14 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: David Airlie, linux-arm-msm, dri-devel, Stephen Boyd, freedreno


On 2/11/2022 2:40 PM, Dmitry Baryshkov wrote:
> In commit 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
> enable and disable") the DP driver received a drm_bridge instance, which
> is always attached to the encoder as a root bridge. However it conflicts
> with the panel_bridge support for eDP panels. The panel bridge attaches
> to the encoder before the "dp" bridge has a chace to do so. Change
> panel_bridge attachment to come after dp_bridge attachment.
>
> Fixes: 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display enable and disable")
> Cc: Kuogee Hsieh <quic_khsieh@quicinc.com>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Tested-by: Kuogee Hsieh <quic_khsieh@quicinc.com>
> ---
>   drivers/gpu/drm/msm/dp/dp_drm.c | 21 +++++++++++----------
>   1 file changed, 11 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
> index d4d360d19eba..26ef41a4c1b6 100644
> --- a/drivers/gpu/drm/msm/dp/dp_drm.c
> +++ b/drivers/gpu/drm/msm/dp/dp_drm.c
> @@ -169,16 +169,6 @@ struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display)
>   
>   	drm_connector_attach_encoder(connector, dp_display->encoder);
>   
> -	if (dp_display->panel_bridge) {
> -		ret = drm_bridge_attach(dp_display->encoder,
> -					dp_display->panel_bridge, NULL,
> -					DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> -		if (ret < 0) {
> -			DRM_ERROR("failed to attach panel bridge: %d\n", ret);
> -			return ERR_PTR(ret);
> -		}
> -	}
> -
>   	return connector;
>   }
>   
> @@ -246,5 +236,16 @@ struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display, struct drm_devi
>   		return ERR_PTR(rc);
>   	}
>   
> +	if (dp_display->panel_bridge) {
> +		rc = drm_bridge_attach(dp_display->encoder,
> +					dp_display->panel_bridge, bridge,
> +					DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> +		if (rc < 0) {
> +			DRM_ERROR("failed to attach panel bridge: %d\n", rc);
> +			drm_bridge_remove(bridge);
> +			return ERR_PTR(rc);
> +		}
> +	}
> +
>   	return bridge;
>   }

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

* Re: [RFC PATCH v2 2/5] drm/msm/dp: support attaching bridges to the DP encoder
  2022-02-11 22:40   ` Dmitry Baryshkov
@ 2022-02-18 21:28     ` Kuogee Hsieh
  -1 siblings, 0 replies; 84+ messages in thread
From: Kuogee Hsieh @ 2022-02-18 21:28 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno


On 2/11/2022 2:40 PM, Dmitry Baryshkov wrote:
> Currently DP driver will allocate panel bridge for eDP panels. This
> supports only the following topology:
>
> - eDP encoder ⇒ eDP panel (wrapped using panel-bridge)
>
> Simplify this code to just check if there is any next bridge in the
> chain (be it a panel bridge or regular bridge). Rename panel_bridge
> field to next_bridge accordingly.
>
> This allows one to use e.g. one of the following display topologies:
>
> - eDP encoder ⇒ ptn3460 ⇒ fixed LVDS panel
> - eDP encoder ⇒ ptn3460 ⇒ LVDS connector with EDID lines for panel autodetect
> - eDP encoder ⇒ ptn3460 ⇒ THC63LVD1024 ⇒ DPI panel.
> - eDP encoder ⇒ LT8912 ⇒ DSI panel
>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

> Tested-by: Kuogee Hsieh <quic_khsieh@quicinc.com>

> ---
>   drivers/gpu/drm/msm/dp/dp_display.c |  2 +-
>   drivers/gpu/drm/msm/dp/dp_display.h |  2 +-
>   drivers/gpu/drm/msm/dp/dp_drm.c     |  4 ++--
>   drivers/gpu/drm/msm/dp/dp_parser.c  | 31 +++++++++++++++--------------
>   drivers/gpu/drm/msm/dp/dp_parser.h  |  2 +-
>   5 files changed, 21 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
> index 44d42c76c2a3..45f9a912ecc5 100644
> --- a/drivers/gpu/drm/msm/dp/dp_display.c
> +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> @@ -266,7 +266,7 @@ static int dp_display_bind(struct device *dev, struct device *master,
>   		goto end;
>   	}
>   
> -	dp->dp_display.panel_bridge = dp->parser->panel_bridge;
> +	dp->dp_display.next_bridge = dp->parser->next_bridge;
>   
>   	dp->aux->drm_dev = drm;
>   	rc = dp_aux_register(dp->aux);
> diff --git a/drivers/gpu/drm/msm/dp/dp_display.h b/drivers/gpu/drm/msm/dp/dp_display.h
> index e3adcd578a90..7af2b186d2d9 100644
> --- a/drivers/gpu/drm/msm/dp/dp_display.h
> +++ b/drivers/gpu/drm/msm/dp/dp_display.h
> @@ -16,7 +16,7 @@ struct msm_dp {
>   	struct drm_bridge *bridge;
>   	struct drm_connector *connector;
>   	struct drm_encoder *encoder;
> -	struct drm_bridge *panel_bridge;
> +	struct drm_bridge *next_bridge;
>   	bool is_connected;
>   	bool audio_enabled;
>   	bool power_on;
> diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
> index 26ef41a4c1b6..80f59cf99089 100644
> --- a/drivers/gpu/drm/msm/dp/dp_drm.c
> +++ b/drivers/gpu/drm/msm/dp/dp_drm.c
> @@ -236,9 +236,9 @@ struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display, struct drm_devi
>   		return ERR_PTR(rc);
>   	}
>   
> -	if (dp_display->panel_bridge) {
> +	if (dp_display->next_bridge) {
>   		rc = drm_bridge_attach(dp_display->encoder,
> -					dp_display->panel_bridge, bridge,
> +					dp_display->next_bridge, bridge,
>   					DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>   		if (rc < 0) {
>   			DRM_ERROR("failed to attach panel bridge: %d\n", rc);
> diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c b/drivers/gpu/drm/msm/dp/dp_parser.c
> index a7acc23f742b..901d7967370f 100644
> --- a/drivers/gpu/drm/msm/dp/dp_parser.c
> +++ b/drivers/gpu/drm/msm/dp/dp_parser.c
> @@ -265,23 +265,16 @@ static int dp_parser_clock(struct dp_parser *parser)
>   	return 0;
>   }
>   
> -static int dp_parser_find_panel(struct dp_parser *parser)
> +static int dp_parser_find_next_bridge(struct dp_parser *parser)
>   {
>   	struct device *dev = &parser->pdev->dev;
> -	struct drm_panel *panel;
> -	int rc;
> +	struct drm_bridge *bridge;
>   
> -	rc = drm_of_find_panel_or_bridge(dev->of_node, 1, 0, &panel, NULL);
> -	if (rc) {
> -		DRM_ERROR("failed to acquire DRM panel: %d\n", rc);
> -		return rc;
> -	}
> +	bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0);
> +	if (IS_ERR(bridge))
> +		return PTR_ERR(bridge);
>   
> -	parser->panel_bridge = devm_drm_panel_bridge_add(dev, panel);
> -	if (IS_ERR(parser->panel_bridge)) {
> -		DRM_ERROR("failed to create panel bridge\n");
> -		return PTR_ERR(parser->panel_bridge);
> -	}
> +	parser->next_bridge = bridge;
>   
>   	return 0;
>   }
> @@ -307,10 +300,18 @@ static int dp_parser_parse(struct dp_parser *parser, int connector_type)
>   	if (rc)
>   		return rc;
>   
> +	/*
> +	 * Currently we support external bridges only for eDP connectors.
> +	 *
> +	 * No external bridges are expected for the DisplayPort connector,
> +	 * it is physically present in a form of a DP or USB-C connector.
> +	 */
>   	if (connector_type == DRM_MODE_CONNECTOR_eDP) {
> -		rc = dp_parser_find_panel(parser);
> -		if (rc)
> +		rc = dp_parser_find_next_bridge(parser);
> +		if (rc) {
> +			DRM_ERROR("DP: failed to find next bridge\n");
>   			return rc;
> +		}
>   	}
>   
>   	/* Map the corresponding regulator information according to
> diff --git a/drivers/gpu/drm/msm/dp/dp_parser.h b/drivers/gpu/drm/msm/dp/dp_parser.h
> index 3172da089421..4cec851e38d9 100644
> --- a/drivers/gpu/drm/msm/dp/dp_parser.h
> +++ b/drivers/gpu/drm/msm/dp/dp_parser.h
> @@ -123,7 +123,7 @@ struct dp_parser {
>   	struct dp_display_data disp_data;
>   	const struct dp_regulator_cfg *regulator_cfg;
>   	u32 max_dp_lanes;
> -	struct drm_bridge *panel_bridge;
> +	struct drm_bridge *next_bridge;
>   
>   	int (*parse)(struct dp_parser *parser, int connector_type);
>   };

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

* Re: [RFC PATCH v2 2/5] drm/msm/dp: support attaching bridges to the DP encoder
@ 2022-02-18 21:28     ` Kuogee Hsieh
  0 siblings, 0 replies; 84+ messages in thread
From: Kuogee Hsieh @ 2022-02-18 21:28 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: David Airlie, linux-arm-msm, dri-devel, Stephen Boyd, freedreno


On 2/11/2022 2:40 PM, Dmitry Baryshkov wrote:
> Currently DP driver will allocate panel bridge for eDP panels. This
> supports only the following topology:
>
> - eDP encoder ⇒ eDP panel (wrapped using panel-bridge)
>
> Simplify this code to just check if there is any next bridge in the
> chain (be it a panel bridge or regular bridge). Rename panel_bridge
> field to next_bridge accordingly.
>
> This allows one to use e.g. one of the following display topologies:
>
> - eDP encoder ⇒ ptn3460 ⇒ fixed LVDS panel
> - eDP encoder ⇒ ptn3460 ⇒ LVDS connector with EDID lines for panel autodetect
> - eDP encoder ⇒ ptn3460 ⇒ THC63LVD1024 ⇒ DPI panel.
> - eDP encoder ⇒ LT8912 ⇒ DSI panel
>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

> Tested-by: Kuogee Hsieh <quic_khsieh@quicinc.com>

> ---
>   drivers/gpu/drm/msm/dp/dp_display.c |  2 +-
>   drivers/gpu/drm/msm/dp/dp_display.h |  2 +-
>   drivers/gpu/drm/msm/dp/dp_drm.c     |  4 ++--
>   drivers/gpu/drm/msm/dp/dp_parser.c  | 31 +++++++++++++++--------------
>   drivers/gpu/drm/msm/dp/dp_parser.h  |  2 +-
>   5 files changed, 21 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
> index 44d42c76c2a3..45f9a912ecc5 100644
> --- a/drivers/gpu/drm/msm/dp/dp_display.c
> +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> @@ -266,7 +266,7 @@ static int dp_display_bind(struct device *dev, struct device *master,
>   		goto end;
>   	}
>   
> -	dp->dp_display.panel_bridge = dp->parser->panel_bridge;
> +	dp->dp_display.next_bridge = dp->parser->next_bridge;
>   
>   	dp->aux->drm_dev = drm;
>   	rc = dp_aux_register(dp->aux);
> diff --git a/drivers/gpu/drm/msm/dp/dp_display.h b/drivers/gpu/drm/msm/dp/dp_display.h
> index e3adcd578a90..7af2b186d2d9 100644
> --- a/drivers/gpu/drm/msm/dp/dp_display.h
> +++ b/drivers/gpu/drm/msm/dp/dp_display.h
> @@ -16,7 +16,7 @@ struct msm_dp {
>   	struct drm_bridge *bridge;
>   	struct drm_connector *connector;
>   	struct drm_encoder *encoder;
> -	struct drm_bridge *panel_bridge;
> +	struct drm_bridge *next_bridge;
>   	bool is_connected;
>   	bool audio_enabled;
>   	bool power_on;
> diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
> index 26ef41a4c1b6..80f59cf99089 100644
> --- a/drivers/gpu/drm/msm/dp/dp_drm.c
> +++ b/drivers/gpu/drm/msm/dp/dp_drm.c
> @@ -236,9 +236,9 @@ struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display, struct drm_devi
>   		return ERR_PTR(rc);
>   	}
>   
> -	if (dp_display->panel_bridge) {
> +	if (dp_display->next_bridge) {
>   		rc = drm_bridge_attach(dp_display->encoder,
> -					dp_display->panel_bridge, bridge,
> +					dp_display->next_bridge, bridge,
>   					DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>   		if (rc < 0) {
>   			DRM_ERROR("failed to attach panel bridge: %d\n", rc);
> diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c b/drivers/gpu/drm/msm/dp/dp_parser.c
> index a7acc23f742b..901d7967370f 100644
> --- a/drivers/gpu/drm/msm/dp/dp_parser.c
> +++ b/drivers/gpu/drm/msm/dp/dp_parser.c
> @@ -265,23 +265,16 @@ static int dp_parser_clock(struct dp_parser *parser)
>   	return 0;
>   }
>   
> -static int dp_parser_find_panel(struct dp_parser *parser)
> +static int dp_parser_find_next_bridge(struct dp_parser *parser)
>   {
>   	struct device *dev = &parser->pdev->dev;
> -	struct drm_panel *panel;
> -	int rc;
> +	struct drm_bridge *bridge;
>   
> -	rc = drm_of_find_panel_or_bridge(dev->of_node, 1, 0, &panel, NULL);
> -	if (rc) {
> -		DRM_ERROR("failed to acquire DRM panel: %d\n", rc);
> -		return rc;
> -	}
> +	bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0);
> +	if (IS_ERR(bridge))
> +		return PTR_ERR(bridge);
>   
> -	parser->panel_bridge = devm_drm_panel_bridge_add(dev, panel);
> -	if (IS_ERR(parser->panel_bridge)) {
> -		DRM_ERROR("failed to create panel bridge\n");
> -		return PTR_ERR(parser->panel_bridge);
> -	}
> +	parser->next_bridge = bridge;
>   
>   	return 0;
>   }
> @@ -307,10 +300,18 @@ static int dp_parser_parse(struct dp_parser *parser, int connector_type)
>   	if (rc)
>   		return rc;
>   
> +	/*
> +	 * Currently we support external bridges only for eDP connectors.
> +	 *
> +	 * No external bridges are expected for the DisplayPort connector,
> +	 * it is physically present in a form of a DP or USB-C connector.
> +	 */
>   	if (connector_type == DRM_MODE_CONNECTOR_eDP) {
> -		rc = dp_parser_find_panel(parser);
> -		if (rc)
> +		rc = dp_parser_find_next_bridge(parser);
> +		if (rc) {
> +			DRM_ERROR("DP: failed to find next bridge\n");
>   			return rc;
> +		}
>   	}
>   
>   	/* Map the corresponding regulator information according to
> diff --git a/drivers/gpu/drm/msm/dp/dp_parser.h b/drivers/gpu/drm/msm/dp/dp_parser.h
> index 3172da089421..4cec851e38d9 100644
> --- a/drivers/gpu/drm/msm/dp/dp_parser.h
> +++ b/drivers/gpu/drm/msm/dp/dp_parser.h
> @@ -123,7 +123,7 @@ struct dp_parser {
>   	struct dp_display_data disp_data;
>   	const struct dp_regulator_cfg *regulator_cfg;
>   	u32 max_dp_lanes;
> -	struct drm_bridge *panel_bridge;
> +	struct drm_bridge *next_bridge;
>   
>   	int (*parse)(struct dp_parser *parser, int connector_type);
>   };

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

* Re: [RFC PATCH v2 3/5] drm/msm/dp: support finding next bridge even for DP interfaces
  2022-02-11 22:40   ` Dmitry Baryshkov
@ 2022-02-18 21:29     ` Kuogee Hsieh
  -1 siblings, 0 replies; 84+ messages in thread
From: Kuogee Hsieh @ 2022-02-18 21:29 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno


On 2/11/2022 2:40 PM, Dmitry Baryshkov wrote:
> It is possible to supply display-connector (bridge) to the DP interface,
> add support for parsing it too.
>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Tested-by: Kuogee Hsieh <quic_khsieh@quicinc.com>
> ---
>   drivers/gpu/drm/msm/dp/dp_parser.c | 19 ++++++++++++-------
>   1 file changed, 12 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c b/drivers/gpu/drm/msm/dp/dp_parser.c
> index 901d7967370f..1056b8d5755b 100644
> --- a/drivers/gpu/drm/msm/dp/dp_parser.c
> +++ b/drivers/gpu/drm/msm/dp/dp_parser.c
> @@ -301,17 +301,22 @@ static int dp_parser_parse(struct dp_parser *parser, int connector_type)
>   		return rc;
>   
>   	/*
> -	 * Currently we support external bridges only for eDP connectors.
> +	 * External bridges are mandatory for eDP interfaces: one has to
> +	 * provide at least an eDP panel (which gets wrapped into panel-bridge).
>   	 *
> -	 * No external bridges are expected for the DisplayPort connector,
> -	 * it is physically present in a form of a DP or USB-C connector.
> +	 * For DisplayPort interfaces external bridges are optional, so
> +	 * silently ignore an error if one is not present (-ENODEV).
>   	 */
> -	if (connector_type == DRM_MODE_CONNECTOR_eDP) {
> -		rc = dp_parser_find_next_bridge(parser);
> -		if (rc) {
> -			DRM_ERROR("DP: failed to find next bridge\n");
> +	rc = dp_parser_find_next_bridge(parser);
> +	if (rc == -ENODEV) {
> +		if (connector_type == DRM_MODE_CONNECTOR_eDP) {
> +			DRM_ERROR("eDP: next bridge is not present\n");
>   			return rc;
>   		}
> +	} else if (rc) {
> +		if (rc != -EPROBE_DEFER)
> +			DRM_ERROR("DP: error parsing next bridge: %d\n", rc);
> +		return rc;
>   	}
>   
>   	/* Map the corresponding regulator information according to

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

* Re: [RFC PATCH v2 3/5] drm/msm/dp: support finding next bridge even for DP interfaces
@ 2022-02-18 21:29     ` Kuogee Hsieh
  0 siblings, 0 replies; 84+ messages in thread
From: Kuogee Hsieh @ 2022-02-18 21:29 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: David Airlie, linux-arm-msm, dri-devel, Stephen Boyd, freedreno


On 2/11/2022 2:40 PM, Dmitry Baryshkov wrote:
> It is possible to supply display-connector (bridge) to the DP interface,
> add support for parsing it too.
>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Tested-by: Kuogee Hsieh <quic_khsieh@quicinc.com>
> ---
>   drivers/gpu/drm/msm/dp/dp_parser.c | 19 ++++++++++++-------
>   1 file changed, 12 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c b/drivers/gpu/drm/msm/dp/dp_parser.c
> index 901d7967370f..1056b8d5755b 100644
> --- a/drivers/gpu/drm/msm/dp/dp_parser.c
> +++ b/drivers/gpu/drm/msm/dp/dp_parser.c
> @@ -301,17 +301,22 @@ static int dp_parser_parse(struct dp_parser *parser, int connector_type)
>   		return rc;
>   
>   	/*
> -	 * Currently we support external bridges only for eDP connectors.
> +	 * External bridges are mandatory for eDP interfaces: one has to
> +	 * provide at least an eDP panel (which gets wrapped into panel-bridge).
>   	 *
> -	 * No external bridges are expected for the DisplayPort connector,
> -	 * it is physically present in a form of a DP or USB-C connector.
> +	 * For DisplayPort interfaces external bridges are optional, so
> +	 * silently ignore an error if one is not present (-ENODEV).
>   	 */
> -	if (connector_type == DRM_MODE_CONNECTOR_eDP) {
> -		rc = dp_parser_find_next_bridge(parser);
> -		if (rc) {
> -			DRM_ERROR("DP: failed to find next bridge\n");
> +	rc = dp_parser_find_next_bridge(parser);
> +	if (rc == -ENODEV) {
> +		if (connector_type == DRM_MODE_CONNECTOR_eDP) {
> +			DRM_ERROR("eDP: next bridge is not present\n");
>   			return rc;
>   		}
> +	} else if (rc) {
> +		if (rc != -EPROBE_DEFER)
> +			DRM_ERROR("DP: error parsing next bridge: %d\n", rc);
> +		return rc;
>   	}
>   
>   	/* Map the corresponding regulator information according to

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

* Re: [RFC PATCH v2 2/5] drm/msm/dp: support attaching bridges to the DP encoder
  2022-02-18 21:28     ` Kuogee Hsieh
@ 2022-02-18 21:31       ` Dmitry Baryshkov
  -1 siblings, 0 replies; 84+ messages in thread
From: Dmitry Baryshkov @ 2022-02-18 21:31 UTC (permalink / raw)
  To: Kuogee Hsieh, Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

On 19/02/2022 00:28, Kuogee Hsieh wrote:
> 
> On 2/11/2022 2:40 PM, Dmitry Baryshkov wrote:
>> Currently DP driver will allocate panel bridge for eDP panels. This
>> supports only the following topology:
>>
>> - eDP encoder ⇒ eDP panel (wrapped using panel-bridge)
>>
>> Simplify this code to just check if there is any next bridge in the
>> chain (be it a panel bridge or regular bridge). Rename panel_bridge
>> field to next_bridge accordingly.
>>
>> This allows one to use e.g. one of the following display topologies:
>>
>> - eDP encoder ⇒ ptn3460 ⇒ fixed LVDS panel
>> - eDP encoder ⇒ ptn3460 ⇒ LVDS connector with EDID lines for panel 
>> autodetect
>> - eDP encoder ⇒ ptn3460 ⇒ THC63LVD1024 ⇒ DPI panel.
>> - eDP encoder ⇒ LT8912 ⇒ DSI panel
>>
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> 
>> Tested-by: Kuogee Hsieh <quic_khsieh@quicinc.com>

The Tested-by got hidden by the quotation symbols. Could you please send 
another one?

> 
>> ---
>>   drivers/gpu/drm/msm/dp/dp_display.c |  2 +-
>>   drivers/gpu/drm/msm/dp/dp_display.h |  2 +-
>>   drivers/gpu/drm/msm/dp/dp_drm.c     |  4 ++--
>>   drivers/gpu/drm/msm/dp/dp_parser.c  | 31 +++++++++++++++--------------
>>   drivers/gpu/drm/msm/dp/dp_parser.h  |  2 +-
>>   5 files changed, 21 insertions(+), 20 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
>> b/drivers/gpu/drm/msm/dp/dp_display.c
>> index 44d42c76c2a3..45f9a912ecc5 100644
>> --- a/drivers/gpu/drm/msm/dp/dp_display.c
>> +++ b/drivers/gpu/drm/msm/dp/dp_display.c
>> @@ -266,7 +266,7 @@ static int dp_display_bind(struct device *dev, 
>> struct device *master,
>>           goto end;
>>       }
>> -    dp->dp_display.panel_bridge = dp->parser->panel_bridge;
>> +    dp->dp_display.next_bridge = dp->parser->next_bridge;
>>       dp->aux->drm_dev = drm;
>>       rc = dp_aux_register(dp->aux);
>> diff --git a/drivers/gpu/drm/msm/dp/dp_display.h 
>> b/drivers/gpu/drm/msm/dp/dp_display.h
>> index e3adcd578a90..7af2b186d2d9 100644
>> --- a/drivers/gpu/drm/msm/dp/dp_display.h
>> +++ b/drivers/gpu/drm/msm/dp/dp_display.h
>> @@ -16,7 +16,7 @@ struct msm_dp {
>>       struct drm_bridge *bridge;
>>       struct drm_connector *connector;
>>       struct drm_encoder *encoder;
>> -    struct drm_bridge *panel_bridge;
>> +    struct drm_bridge *next_bridge;
>>       bool is_connected;
>>       bool audio_enabled;
>>       bool power_on;
>> diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c 
>> b/drivers/gpu/drm/msm/dp/dp_drm.c
>> index 26ef41a4c1b6..80f59cf99089 100644
>> --- a/drivers/gpu/drm/msm/dp/dp_drm.c
>> +++ b/drivers/gpu/drm/msm/dp/dp_drm.c
>> @@ -236,9 +236,9 @@ struct drm_bridge *msm_dp_bridge_init(struct 
>> msm_dp *dp_display, struct drm_devi
>>           return ERR_PTR(rc);
>>       }
>> -    if (dp_display->panel_bridge) {
>> +    if (dp_display->next_bridge) {
>>           rc = drm_bridge_attach(dp_display->encoder,
>> -                    dp_display->panel_bridge, bridge,
>> +                    dp_display->next_bridge, bridge,
>>                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>>           if (rc < 0) {
>>               DRM_ERROR("failed to attach panel bridge: %d\n", rc);
>> diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c 
>> b/drivers/gpu/drm/msm/dp/dp_parser.c
>> index a7acc23f742b..901d7967370f 100644
>> --- a/drivers/gpu/drm/msm/dp/dp_parser.c
>> +++ b/drivers/gpu/drm/msm/dp/dp_parser.c
>> @@ -265,23 +265,16 @@ static int dp_parser_clock(struct dp_parser 
>> *parser)
>>       return 0;
>>   }
>> -static int dp_parser_find_panel(struct dp_parser *parser)
>> +static int dp_parser_find_next_bridge(struct dp_parser *parser)
>>   {
>>       struct device *dev = &parser->pdev->dev;
>> -    struct drm_panel *panel;
>> -    int rc;
>> +    struct drm_bridge *bridge;
>> -    rc = drm_of_find_panel_or_bridge(dev->of_node, 1, 0, &panel, NULL);
>> -    if (rc) {
>> -        DRM_ERROR("failed to acquire DRM panel: %d\n", rc);
>> -        return rc;
>> -    }
>> +    bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0);
>> +    if (IS_ERR(bridge))
>> +        return PTR_ERR(bridge);
>> -    parser->panel_bridge = devm_drm_panel_bridge_add(dev, panel);
>> -    if (IS_ERR(parser->panel_bridge)) {
>> -        DRM_ERROR("failed to create panel bridge\n");
>> -        return PTR_ERR(parser->panel_bridge);
>> -    }
>> +    parser->next_bridge = bridge;
>>       return 0;
>>   }
>> @@ -307,10 +300,18 @@ static int dp_parser_parse(struct dp_parser 
>> *parser, int connector_type)
>>       if (rc)
>>           return rc;
>> +    /*
>> +     * Currently we support external bridges only for eDP connectors.
>> +     *
>> +     * No external bridges are expected for the DisplayPort connector,
>> +     * it is physically present in a form of a DP or USB-C connector.
>> +     */
>>       if (connector_type == DRM_MODE_CONNECTOR_eDP) {
>> -        rc = dp_parser_find_panel(parser);
>> -        if (rc)
>> +        rc = dp_parser_find_next_bridge(parser);
>> +        if (rc) {
>> +            DRM_ERROR("DP: failed to find next bridge\n");
>>               return rc;
>> +        }
>>       }
>>       /* Map the corresponding regulator information according to
>> diff --git a/drivers/gpu/drm/msm/dp/dp_parser.h 
>> b/drivers/gpu/drm/msm/dp/dp_parser.h
>> index 3172da089421..4cec851e38d9 100644
>> --- a/drivers/gpu/drm/msm/dp/dp_parser.h
>> +++ b/drivers/gpu/drm/msm/dp/dp_parser.h
>> @@ -123,7 +123,7 @@ struct dp_parser {
>>       struct dp_display_data disp_data;
>>       const struct dp_regulator_cfg *regulator_cfg;
>>       u32 max_dp_lanes;
>> -    struct drm_bridge *panel_bridge;
>> +    struct drm_bridge *next_bridge;
>>       int (*parse)(struct dp_parser *parser, int connector_type);
>>   };


-- 
With best wishes
Dmitry

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

* Re: [RFC PATCH v2 2/5] drm/msm/dp: support attaching bridges to the DP encoder
@ 2022-02-18 21:31       ` Dmitry Baryshkov
  0 siblings, 0 replies; 84+ messages in thread
From: Dmitry Baryshkov @ 2022-02-18 21:31 UTC (permalink / raw)
  To: Kuogee Hsieh, Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: David Airlie, linux-arm-msm, dri-devel, Stephen Boyd, freedreno

On 19/02/2022 00:28, Kuogee Hsieh wrote:
> 
> On 2/11/2022 2:40 PM, Dmitry Baryshkov wrote:
>> Currently DP driver will allocate panel bridge for eDP panels. This
>> supports only the following topology:
>>
>> - eDP encoder ⇒ eDP panel (wrapped using panel-bridge)
>>
>> Simplify this code to just check if there is any next bridge in the
>> chain (be it a panel bridge or regular bridge). Rename panel_bridge
>> field to next_bridge accordingly.
>>
>> This allows one to use e.g. one of the following display topologies:
>>
>> - eDP encoder ⇒ ptn3460 ⇒ fixed LVDS panel
>> - eDP encoder ⇒ ptn3460 ⇒ LVDS connector with EDID lines for panel 
>> autodetect
>> - eDP encoder ⇒ ptn3460 ⇒ THC63LVD1024 ⇒ DPI panel.
>> - eDP encoder ⇒ LT8912 ⇒ DSI panel
>>
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> 
>> Tested-by: Kuogee Hsieh <quic_khsieh@quicinc.com>

The Tested-by got hidden by the quotation symbols. Could you please send 
another one?

> 
>> ---
>>   drivers/gpu/drm/msm/dp/dp_display.c |  2 +-
>>   drivers/gpu/drm/msm/dp/dp_display.h |  2 +-
>>   drivers/gpu/drm/msm/dp/dp_drm.c     |  4 ++--
>>   drivers/gpu/drm/msm/dp/dp_parser.c  | 31 +++++++++++++++--------------
>>   drivers/gpu/drm/msm/dp/dp_parser.h  |  2 +-
>>   5 files changed, 21 insertions(+), 20 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
>> b/drivers/gpu/drm/msm/dp/dp_display.c
>> index 44d42c76c2a3..45f9a912ecc5 100644
>> --- a/drivers/gpu/drm/msm/dp/dp_display.c
>> +++ b/drivers/gpu/drm/msm/dp/dp_display.c
>> @@ -266,7 +266,7 @@ static int dp_display_bind(struct device *dev, 
>> struct device *master,
>>           goto end;
>>       }
>> -    dp->dp_display.panel_bridge = dp->parser->panel_bridge;
>> +    dp->dp_display.next_bridge = dp->parser->next_bridge;
>>       dp->aux->drm_dev = drm;
>>       rc = dp_aux_register(dp->aux);
>> diff --git a/drivers/gpu/drm/msm/dp/dp_display.h 
>> b/drivers/gpu/drm/msm/dp/dp_display.h
>> index e3adcd578a90..7af2b186d2d9 100644
>> --- a/drivers/gpu/drm/msm/dp/dp_display.h
>> +++ b/drivers/gpu/drm/msm/dp/dp_display.h
>> @@ -16,7 +16,7 @@ struct msm_dp {
>>       struct drm_bridge *bridge;
>>       struct drm_connector *connector;
>>       struct drm_encoder *encoder;
>> -    struct drm_bridge *panel_bridge;
>> +    struct drm_bridge *next_bridge;
>>       bool is_connected;
>>       bool audio_enabled;
>>       bool power_on;
>> diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c 
>> b/drivers/gpu/drm/msm/dp/dp_drm.c
>> index 26ef41a4c1b6..80f59cf99089 100644
>> --- a/drivers/gpu/drm/msm/dp/dp_drm.c
>> +++ b/drivers/gpu/drm/msm/dp/dp_drm.c
>> @@ -236,9 +236,9 @@ struct drm_bridge *msm_dp_bridge_init(struct 
>> msm_dp *dp_display, struct drm_devi
>>           return ERR_PTR(rc);
>>       }
>> -    if (dp_display->panel_bridge) {
>> +    if (dp_display->next_bridge) {
>>           rc = drm_bridge_attach(dp_display->encoder,
>> -                    dp_display->panel_bridge, bridge,
>> +                    dp_display->next_bridge, bridge,
>>                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>>           if (rc < 0) {
>>               DRM_ERROR("failed to attach panel bridge: %d\n", rc);
>> diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c 
>> b/drivers/gpu/drm/msm/dp/dp_parser.c
>> index a7acc23f742b..901d7967370f 100644
>> --- a/drivers/gpu/drm/msm/dp/dp_parser.c
>> +++ b/drivers/gpu/drm/msm/dp/dp_parser.c
>> @@ -265,23 +265,16 @@ static int dp_parser_clock(struct dp_parser 
>> *parser)
>>       return 0;
>>   }
>> -static int dp_parser_find_panel(struct dp_parser *parser)
>> +static int dp_parser_find_next_bridge(struct dp_parser *parser)
>>   {
>>       struct device *dev = &parser->pdev->dev;
>> -    struct drm_panel *panel;
>> -    int rc;
>> +    struct drm_bridge *bridge;
>> -    rc = drm_of_find_panel_or_bridge(dev->of_node, 1, 0, &panel, NULL);
>> -    if (rc) {
>> -        DRM_ERROR("failed to acquire DRM panel: %d\n", rc);
>> -        return rc;
>> -    }
>> +    bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0);
>> +    if (IS_ERR(bridge))
>> +        return PTR_ERR(bridge);
>> -    parser->panel_bridge = devm_drm_panel_bridge_add(dev, panel);
>> -    if (IS_ERR(parser->panel_bridge)) {
>> -        DRM_ERROR("failed to create panel bridge\n");
>> -        return PTR_ERR(parser->panel_bridge);
>> -    }
>> +    parser->next_bridge = bridge;
>>       return 0;
>>   }
>> @@ -307,10 +300,18 @@ static int dp_parser_parse(struct dp_parser 
>> *parser, int connector_type)
>>       if (rc)
>>           return rc;
>> +    /*
>> +     * Currently we support external bridges only for eDP connectors.
>> +     *
>> +     * No external bridges are expected for the DisplayPort connector,
>> +     * it is physically present in a form of a DP or USB-C connector.
>> +     */
>>       if (connector_type == DRM_MODE_CONNECTOR_eDP) {
>> -        rc = dp_parser_find_panel(parser);
>> -        if (rc)
>> +        rc = dp_parser_find_next_bridge(parser);
>> +        if (rc) {
>> +            DRM_ERROR("DP: failed to find next bridge\n");
>>               return rc;
>> +        }
>>       }
>>       /* Map the corresponding regulator information according to
>> diff --git a/drivers/gpu/drm/msm/dp/dp_parser.h 
>> b/drivers/gpu/drm/msm/dp/dp_parser.h
>> index 3172da089421..4cec851e38d9 100644
>> --- a/drivers/gpu/drm/msm/dp/dp_parser.h
>> +++ b/drivers/gpu/drm/msm/dp/dp_parser.h
>> @@ -123,7 +123,7 @@ struct dp_parser {
>>       struct dp_display_data disp_data;
>>       const struct dp_regulator_cfg *regulator_cfg;
>>       u32 max_dp_lanes;
>> -    struct drm_bridge *panel_bridge;
>> +    struct drm_bridge *next_bridge;
>>       int (*parse)(struct dp_parser *parser, int connector_type);
>>   };


-- 
With best wishes
Dmitry

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

* Re: [RFC PATCH v2 4/5] drm/msm/dp: replace dp_connector with drm_bridge_connector
  2022-02-11 22:40   ` Dmitry Baryshkov
@ 2022-02-18 21:31     ` Kuogee Hsieh
  -1 siblings, 0 replies; 84+ messages in thread
From: Kuogee Hsieh @ 2022-02-18 21:31 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno


On 2/11/2022 2:40 PM, Dmitry Baryshkov wrote:
> There is little point in having both connector and root bridge
> implementation in the same driver. Move connector's functionality to the
> bridge to let next bridge in chain to override it.
>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

This patch break primary (edp) display

-- right half of screen garbled

-- screen shift vertically

below are error messages seen --

[   36.679216] panel-edp soc@0:edp_panel: No display modes
[   36.687272] panel-edp soc@0:edp_panel: No display modes
[   40.593709] panel-edp soc@0:edp_panel: No display modes
[   40.600285] panel-edp soc@0:edp_panel: No display modes

> ---
>   drivers/gpu/drm/msm/dp/dp_display.c |  22 +++---
>   drivers/gpu/drm/msm/dp/dp_drm.c     | 113 ++++++++++------------------
>   2 files changed, 52 insertions(+), 83 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
> index 45f9a912ecc5..59e5e5b8e5b4 100644
> --- a/drivers/gpu/drm/msm/dp/dp_display.c
> +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> @@ -1501,6 +1501,17 @@ int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev,
>   
>   	dp_display->encoder = encoder;
>   
> +	dp_display->bridge = msm_dp_bridge_init(dp_display, dev, encoder);
> +	if (IS_ERR(dp_display->bridge)) {
> +		ret = PTR_ERR(dp_display->bridge);
> +		DRM_DEV_ERROR(dev->dev,
> +			"failed to create dp bridge: %d\n", ret);
> +		dp_display->bridge = NULL;
> +		return ret;
> +	}
> +
> +	priv->bridges[priv->num_bridges++] = dp_display->bridge;
> +
>   	dp_display->connector = dp_drm_connector_init(dp_display);
>   	if (IS_ERR(dp_display->connector)) {
>   		ret = PTR_ERR(dp_display->connector);
> @@ -1514,17 +1525,6 @@ int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev,
>   
>   	priv->connectors[priv->num_connectors++] = dp_display->connector;
>   
> -	dp_display->bridge = msm_dp_bridge_init(dp_display, dev, encoder);
> -	if (IS_ERR(dp_display->bridge)) {
> -		ret = PTR_ERR(dp_display->bridge);
> -		DRM_DEV_ERROR(dev->dev,
> -			"failed to create dp bridge: %d\n", ret);
> -		dp_display->bridge = NULL;
> -		return ret;
> -	}
> -
> -	priv->bridges[priv->num_bridges++] = dp_display->bridge;
> -
>   	return 0;
>   }
>   
> diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
> index 80f59cf99089..57800b865fe6 100644
> --- a/drivers/gpu/drm/msm/dp/dp_drm.c
> +++ b/drivers/gpu/drm/msm/dp/dp_drm.c
> @@ -6,6 +6,7 @@
>   #include <drm/drm_atomic_helper.h>
>   #include <drm/drm_atomic.h>
>   #include <drm/drm_bridge.h>
> +#include <drm/drm_bridge_connector.h>
>   #include <drm/drm_crtc.h>
>   
>   #include "msm_drv.h"
> @@ -20,24 +21,16 @@ struct msm_dp_bridge {
>   
>   #define to_dp_display(x)     container_of((x), struct msm_dp_bridge, bridge)
>   
> -struct dp_connector {
> -	struct drm_connector base;
> -	struct msm_dp *dp_display;
> -};
> -#define to_dp_connector(x) container_of(x, struct dp_connector, base)
> -
>   /**
> - * dp_connector_detect - callback to determine if connector is connected
> - * @conn: Pointer to drm connector structure
> - * @force: Force detect setting from drm framework
> - * Returns: Connector 'is connected' status
> + * dp_bridge_detect - callback to determine if connector is connected
> + * @bridge: Pointer to drm bridge structure
> + * Returns: Bridge's 'is connected' status
>    */
> -static enum drm_connector_status dp_connector_detect(struct drm_connector *conn,
> -		bool force)
> +static enum drm_connector_status dp_bridge_detect(struct drm_bridge *bridge)
>   {
>   	struct msm_dp *dp;
>   
> -	dp = to_dp_connector(conn)->dp_display;
> +	dp = to_dp_display(bridge)->dp_display;
>   
>   	DRM_DEBUG_DP("is_connected = %s\n",
>   		(dp->is_connected) ? "true" : "false");
> @@ -47,11 +40,12 @@ static enum drm_connector_status dp_connector_detect(struct drm_connector *conn,
>   }
>   
>   /**
> - * dp_connector_get_modes - callback to add drm modes via drm_mode_probed_add()
> + * dp_bridge_get_modes - callback to add drm modes via drm_mode_probed_add()
> + * @bridge: Poiner to drm bridge
>    * @connector: Pointer to drm connector structure
>    * Returns: Number of modes added
>    */
> -static int dp_connector_get_modes(struct drm_connector *connector)
> +static int dp_bridge_get_modes(struct drm_bridge *bridge, struct drm_connector *connector)
>   {
>   	int rc = 0;
>   	struct msm_dp *dp;
> @@ -61,7 +55,7 @@ static int dp_connector_get_modes(struct drm_connector *connector)
>   	if (!connector)
>   		return 0;
>   
> -	dp = to_dp_connector(connector)->dp_display;
> +	dp = to_dp_display(bridge)->dp_display;
>   
>   	dp_mode = kzalloc(sizeof(*dp_mode),  GFP_KERNEL);
>   	if (!dp_mode)
> @@ -102,18 +96,20 @@ static int dp_connector_get_modes(struct drm_connector *connector)
>   }
>   
>   /**
> - * dp_connector_mode_valid - callback to determine if specified mode is valid
> - * @connector: Pointer to drm connector structure
> + * dp_bridge_mode_valid - callback to determine if specified mode is valid
> + * @bridge: Pointer to drm bridge structure
> + * @info: display info
>    * @mode: Pointer to drm mode structure
>    * Returns: Validity status for specified mode
>    */
> -static enum drm_mode_status dp_connector_mode_valid(
> -		struct drm_connector *connector,
> -		struct drm_display_mode *mode)
> +static enum drm_mode_status dp_bridge_mode_valid(
> +		struct drm_bridge *bridge,
> +		const struct drm_display_info *info,
> +		const struct drm_display_mode *mode)
>   {
>   	struct msm_dp *dp_disp;
>   
> -	dp_disp = to_dp_connector(connector)->dp_display;
> +	dp_disp = to_dp_display(bridge)->dp_display;
>   
>   	if ((dp_disp->max_pclk_khz <= 0) ||
>   			(dp_disp->max_pclk_khz > DP_MAX_PIXEL_CLK_KHZ) ||
> @@ -123,55 +119,6 @@ static enum drm_mode_status dp_connector_mode_valid(
>   	return dp_display_validate_mode(dp_disp, mode->clock);
>   }
>   
> -static const struct drm_connector_funcs dp_connector_funcs = {
> -	.detect = dp_connector_detect,
> -	.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 dp_connector_helper_funcs = {
> -	.get_modes = dp_connector_get_modes,
> -	.mode_valid = dp_connector_mode_valid,
> -};
> -
> -/* connector initialization */
> -struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display)
> -{
> -	struct drm_connector *connector = NULL;
> -	struct dp_connector *dp_connector;
> -	int ret;
> -
> -	dp_connector = devm_kzalloc(dp_display->drm_dev->dev,
> -					sizeof(*dp_connector),
> -					GFP_KERNEL);
> -	if (!dp_connector)
> -		return ERR_PTR(-ENOMEM);
> -
> -	dp_connector->dp_display = dp_display;
> -
> -	connector = &dp_connector->base;
> -
> -	ret = drm_connector_init(dp_display->drm_dev, connector,
> -			&dp_connector_funcs,
> -			dp_display->connector_type);
> -	if (ret)
> -		return ERR_PTR(ret);
> -
> -	drm_connector_helper_add(connector, &dp_connector_helper_funcs);
> -
> -	/*
> -	 * Enable HPD to let hpd event is handled when cable is connected.
> -	 */
> -	connector->polled = DRM_CONNECTOR_POLL_HPD;
> -
> -	drm_connector_attach_encoder(connector, dp_display->encoder);
> -
> -	return connector;
> -}
> -
>   static void dp_bridge_mode_set(struct drm_bridge *drm_bridge,
>   				const struct drm_display_mode *mode,
>   				const struct drm_display_mode *adjusted_mode)
> @@ -211,6 +158,9 @@ static const struct drm_bridge_funcs dp_bridge_ops = {
>   	.disable      = dp_bridge_disable,
>   	.post_disable = dp_bridge_post_disable,
>   	.mode_set     = dp_bridge_mode_set,
> +	.mode_valid   = dp_bridge_mode_valid,
> +	.get_modes    = dp_bridge_get_modes,
> +	.detect       = dp_bridge_detect,
>   };
>   
>   struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display, struct drm_device *dev,
> @@ -228,7 +178,12 @@ struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display, struct drm_devi
>   
>   	bridge = &dp_bridge->bridge;
>   	bridge->funcs = &dp_bridge_ops;
> -	bridge->encoder = encoder;
> +	bridge->type = dp_display->connector_type;
> +
> +	bridge->ops =
> +		DRM_BRIDGE_OP_DETECT |
> +		DRM_BRIDGE_OP_HPD |
> +		DRM_BRIDGE_OP_MODES;
>   
>   	rc = drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>   	if (rc) {
> @@ -249,3 +204,17 @@ struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display, struct drm_devi
>   
>   	return bridge;
>   }
> +
> +/* connector initialization */
> +struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display)
> +{
> +	struct drm_connector *connector = NULL;
> +
> +	connector = drm_bridge_connector_init(dp_display->drm_dev, dp_display->encoder);
> +	if (IS_ERR(connector))
> +		return connector;
> +
> +	drm_connector_attach_encoder(connector, dp_display->encoder);
> +
> +	return connector;
> +}

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

* Re: [RFC PATCH v2 4/5] drm/msm/dp: replace dp_connector with drm_bridge_connector
@ 2022-02-18 21:31     ` Kuogee Hsieh
  0 siblings, 0 replies; 84+ messages in thread
From: Kuogee Hsieh @ 2022-02-18 21:31 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: David Airlie, linux-arm-msm, dri-devel, Stephen Boyd, freedreno


On 2/11/2022 2:40 PM, Dmitry Baryshkov wrote:
> There is little point in having both connector and root bridge
> implementation in the same driver. Move connector's functionality to the
> bridge to let next bridge in chain to override it.
>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

This patch break primary (edp) display

-- right half of screen garbled

-- screen shift vertically

below are error messages seen --

[   36.679216] panel-edp soc@0:edp_panel: No display modes
[   36.687272] panel-edp soc@0:edp_panel: No display modes
[   40.593709] panel-edp soc@0:edp_panel: No display modes
[   40.600285] panel-edp soc@0:edp_panel: No display modes

> ---
>   drivers/gpu/drm/msm/dp/dp_display.c |  22 +++---
>   drivers/gpu/drm/msm/dp/dp_drm.c     | 113 ++++++++++------------------
>   2 files changed, 52 insertions(+), 83 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
> index 45f9a912ecc5..59e5e5b8e5b4 100644
> --- a/drivers/gpu/drm/msm/dp/dp_display.c
> +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> @@ -1501,6 +1501,17 @@ int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev,
>   
>   	dp_display->encoder = encoder;
>   
> +	dp_display->bridge = msm_dp_bridge_init(dp_display, dev, encoder);
> +	if (IS_ERR(dp_display->bridge)) {
> +		ret = PTR_ERR(dp_display->bridge);
> +		DRM_DEV_ERROR(dev->dev,
> +			"failed to create dp bridge: %d\n", ret);
> +		dp_display->bridge = NULL;
> +		return ret;
> +	}
> +
> +	priv->bridges[priv->num_bridges++] = dp_display->bridge;
> +
>   	dp_display->connector = dp_drm_connector_init(dp_display);
>   	if (IS_ERR(dp_display->connector)) {
>   		ret = PTR_ERR(dp_display->connector);
> @@ -1514,17 +1525,6 @@ int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev,
>   
>   	priv->connectors[priv->num_connectors++] = dp_display->connector;
>   
> -	dp_display->bridge = msm_dp_bridge_init(dp_display, dev, encoder);
> -	if (IS_ERR(dp_display->bridge)) {
> -		ret = PTR_ERR(dp_display->bridge);
> -		DRM_DEV_ERROR(dev->dev,
> -			"failed to create dp bridge: %d\n", ret);
> -		dp_display->bridge = NULL;
> -		return ret;
> -	}
> -
> -	priv->bridges[priv->num_bridges++] = dp_display->bridge;
> -
>   	return 0;
>   }
>   
> diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
> index 80f59cf99089..57800b865fe6 100644
> --- a/drivers/gpu/drm/msm/dp/dp_drm.c
> +++ b/drivers/gpu/drm/msm/dp/dp_drm.c
> @@ -6,6 +6,7 @@
>   #include <drm/drm_atomic_helper.h>
>   #include <drm/drm_atomic.h>
>   #include <drm/drm_bridge.h>
> +#include <drm/drm_bridge_connector.h>
>   #include <drm/drm_crtc.h>
>   
>   #include "msm_drv.h"
> @@ -20,24 +21,16 @@ struct msm_dp_bridge {
>   
>   #define to_dp_display(x)     container_of((x), struct msm_dp_bridge, bridge)
>   
> -struct dp_connector {
> -	struct drm_connector base;
> -	struct msm_dp *dp_display;
> -};
> -#define to_dp_connector(x) container_of(x, struct dp_connector, base)
> -
>   /**
> - * dp_connector_detect - callback to determine if connector is connected
> - * @conn: Pointer to drm connector structure
> - * @force: Force detect setting from drm framework
> - * Returns: Connector 'is connected' status
> + * dp_bridge_detect - callback to determine if connector is connected
> + * @bridge: Pointer to drm bridge structure
> + * Returns: Bridge's 'is connected' status
>    */
> -static enum drm_connector_status dp_connector_detect(struct drm_connector *conn,
> -		bool force)
> +static enum drm_connector_status dp_bridge_detect(struct drm_bridge *bridge)
>   {
>   	struct msm_dp *dp;
>   
> -	dp = to_dp_connector(conn)->dp_display;
> +	dp = to_dp_display(bridge)->dp_display;
>   
>   	DRM_DEBUG_DP("is_connected = %s\n",
>   		(dp->is_connected) ? "true" : "false");
> @@ -47,11 +40,12 @@ static enum drm_connector_status dp_connector_detect(struct drm_connector *conn,
>   }
>   
>   /**
> - * dp_connector_get_modes - callback to add drm modes via drm_mode_probed_add()
> + * dp_bridge_get_modes - callback to add drm modes via drm_mode_probed_add()
> + * @bridge: Poiner to drm bridge
>    * @connector: Pointer to drm connector structure
>    * Returns: Number of modes added
>    */
> -static int dp_connector_get_modes(struct drm_connector *connector)
> +static int dp_bridge_get_modes(struct drm_bridge *bridge, struct drm_connector *connector)
>   {
>   	int rc = 0;
>   	struct msm_dp *dp;
> @@ -61,7 +55,7 @@ static int dp_connector_get_modes(struct drm_connector *connector)
>   	if (!connector)
>   		return 0;
>   
> -	dp = to_dp_connector(connector)->dp_display;
> +	dp = to_dp_display(bridge)->dp_display;
>   
>   	dp_mode = kzalloc(sizeof(*dp_mode),  GFP_KERNEL);
>   	if (!dp_mode)
> @@ -102,18 +96,20 @@ static int dp_connector_get_modes(struct drm_connector *connector)
>   }
>   
>   /**
> - * dp_connector_mode_valid - callback to determine if specified mode is valid
> - * @connector: Pointer to drm connector structure
> + * dp_bridge_mode_valid - callback to determine if specified mode is valid
> + * @bridge: Pointer to drm bridge structure
> + * @info: display info
>    * @mode: Pointer to drm mode structure
>    * Returns: Validity status for specified mode
>    */
> -static enum drm_mode_status dp_connector_mode_valid(
> -		struct drm_connector *connector,
> -		struct drm_display_mode *mode)
> +static enum drm_mode_status dp_bridge_mode_valid(
> +		struct drm_bridge *bridge,
> +		const struct drm_display_info *info,
> +		const struct drm_display_mode *mode)
>   {
>   	struct msm_dp *dp_disp;
>   
> -	dp_disp = to_dp_connector(connector)->dp_display;
> +	dp_disp = to_dp_display(bridge)->dp_display;
>   
>   	if ((dp_disp->max_pclk_khz <= 0) ||
>   			(dp_disp->max_pclk_khz > DP_MAX_PIXEL_CLK_KHZ) ||
> @@ -123,55 +119,6 @@ static enum drm_mode_status dp_connector_mode_valid(
>   	return dp_display_validate_mode(dp_disp, mode->clock);
>   }
>   
> -static const struct drm_connector_funcs dp_connector_funcs = {
> -	.detect = dp_connector_detect,
> -	.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 dp_connector_helper_funcs = {
> -	.get_modes = dp_connector_get_modes,
> -	.mode_valid = dp_connector_mode_valid,
> -};
> -
> -/* connector initialization */
> -struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display)
> -{
> -	struct drm_connector *connector = NULL;
> -	struct dp_connector *dp_connector;
> -	int ret;
> -
> -	dp_connector = devm_kzalloc(dp_display->drm_dev->dev,
> -					sizeof(*dp_connector),
> -					GFP_KERNEL);
> -	if (!dp_connector)
> -		return ERR_PTR(-ENOMEM);
> -
> -	dp_connector->dp_display = dp_display;
> -
> -	connector = &dp_connector->base;
> -
> -	ret = drm_connector_init(dp_display->drm_dev, connector,
> -			&dp_connector_funcs,
> -			dp_display->connector_type);
> -	if (ret)
> -		return ERR_PTR(ret);
> -
> -	drm_connector_helper_add(connector, &dp_connector_helper_funcs);
> -
> -	/*
> -	 * Enable HPD to let hpd event is handled when cable is connected.
> -	 */
> -	connector->polled = DRM_CONNECTOR_POLL_HPD;
> -
> -	drm_connector_attach_encoder(connector, dp_display->encoder);
> -
> -	return connector;
> -}
> -
>   static void dp_bridge_mode_set(struct drm_bridge *drm_bridge,
>   				const struct drm_display_mode *mode,
>   				const struct drm_display_mode *adjusted_mode)
> @@ -211,6 +158,9 @@ static const struct drm_bridge_funcs dp_bridge_ops = {
>   	.disable      = dp_bridge_disable,
>   	.post_disable = dp_bridge_post_disable,
>   	.mode_set     = dp_bridge_mode_set,
> +	.mode_valid   = dp_bridge_mode_valid,
> +	.get_modes    = dp_bridge_get_modes,
> +	.detect       = dp_bridge_detect,
>   };
>   
>   struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display, struct drm_device *dev,
> @@ -228,7 +178,12 @@ struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display, struct drm_devi
>   
>   	bridge = &dp_bridge->bridge;
>   	bridge->funcs = &dp_bridge_ops;
> -	bridge->encoder = encoder;
> +	bridge->type = dp_display->connector_type;
> +
> +	bridge->ops =
> +		DRM_BRIDGE_OP_DETECT |
> +		DRM_BRIDGE_OP_HPD |
> +		DRM_BRIDGE_OP_MODES;
>   
>   	rc = drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>   	if (rc) {
> @@ -249,3 +204,17 @@ struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display, struct drm_devi
>   
>   	return bridge;
>   }
> +
> +/* connector initialization */
> +struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display)
> +{
> +	struct drm_connector *connector = NULL;
> +
> +	connector = drm_bridge_connector_init(dp_display->drm_dev, dp_display->encoder);
> +	if (IS_ERR(connector))
> +		return connector;
> +
> +	drm_connector_attach_encoder(connector, dp_display->encoder);
> +
> +	return connector;
> +}

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

* Re: [RFC PATCH v2 4/5] drm/msm/dp: replace dp_connector with drm_bridge_connector
  2022-02-18 21:31     ` Kuogee Hsieh
@ 2022-02-18 21:52       ` Dmitry Baryshkov
  -1 siblings, 0 replies; 84+ messages in thread
From: Dmitry Baryshkov @ 2022-02-18 21:52 UTC (permalink / raw)
  To: Kuogee Hsieh, Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

On 19/02/2022 00:31, Kuogee Hsieh wrote:
> 
> On 2/11/2022 2:40 PM, Dmitry Baryshkov wrote:
>> There is little point in having both connector and root bridge
>> implementation in the same driver. Move connector's functionality to the
>> bridge to let next bridge in chain to override it.
>>
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> 
> This patch break primary (edp) display
> 
> -- right half of screen garbled
> 
> -- screen shift vertically
> 
> below are error messages seen --
> 
> [   36.679216] panel-edp soc@0:edp_panel: No display modes
> [   36.687272] panel-edp soc@0:edp_panel: No display modes
> [   40.593709] panel-edp soc@0:edp_panel: No display modes
> [   40.600285] panel-edp soc@0:edp_panel: No display modes

Thanks for testing this series!

Could you please post the result of `modetest -c` after this patch?


> 
>> ---
>>   drivers/gpu/drm/msm/dp/dp_display.c |  22 +++---
>>   drivers/gpu/drm/msm/dp/dp_drm.c     | 113 ++++++++++------------------
>>   2 files changed, 52 insertions(+), 83 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
>> b/drivers/gpu/drm/msm/dp/dp_display.c
>> index 45f9a912ecc5..59e5e5b8e5b4 100644
>> --- a/drivers/gpu/drm/msm/dp/dp_display.c
>> +++ b/drivers/gpu/drm/msm/dp/dp_display.c
>> @@ -1501,6 +1501,17 @@ int msm_dp_modeset_init(struct msm_dp 
>> *dp_display, struct drm_device *dev,
>>       dp_display->encoder = encoder;
>> +    dp_display->bridge = msm_dp_bridge_init(dp_display, dev, encoder);
>> +    if (IS_ERR(dp_display->bridge)) {
>> +        ret = PTR_ERR(dp_display->bridge);
>> +        DRM_DEV_ERROR(dev->dev,
>> +            "failed to create dp bridge: %d\n", ret);
>> +        dp_display->bridge = NULL;
>> +        return ret;
>> +    }
>> +
>> +    priv->bridges[priv->num_bridges++] = dp_display->bridge;
>> +
>>       dp_display->connector = dp_drm_connector_init(dp_display);
>>       if (IS_ERR(dp_display->connector)) {
>>           ret = PTR_ERR(dp_display->connector);
>> @@ -1514,17 +1525,6 @@ int msm_dp_modeset_init(struct msm_dp 
>> *dp_display, struct drm_device *dev,
>>       priv->connectors[priv->num_connectors++] = dp_display->connector;
>> -    dp_display->bridge = msm_dp_bridge_init(dp_display, dev, encoder);
>> -    if (IS_ERR(dp_display->bridge)) {
>> -        ret = PTR_ERR(dp_display->bridge);
>> -        DRM_DEV_ERROR(dev->dev,
>> -            "failed to create dp bridge: %d\n", ret);
>> -        dp_display->bridge = NULL;
>> -        return ret;
>> -    }
>> -
>> -    priv->bridges[priv->num_bridges++] = dp_display->bridge;
>> -
>>       return 0;
>>   }
>> diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c 
>> b/drivers/gpu/drm/msm/dp/dp_drm.c
>> index 80f59cf99089..57800b865fe6 100644
>> --- a/drivers/gpu/drm/msm/dp/dp_drm.c
>> +++ b/drivers/gpu/drm/msm/dp/dp_drm.c
>> @@ -6,6 +6,7 @@
>>   #include <drm/drm_atomic_helper.h>
>>   #include <drm/drm_atomic.h>
>>   #include <drm/drm_bridge.h>
>> +#include <drm/drm_bridge_connector.h>
>>   #include <drm/drm_crtc.h>
>>   #include "msm_drv.h"
>> @@ -20,24 +21,16 @@ struct msm_dp_bridge {
>>   #define to_dp_display(x)     container_of((x), struct msm_dp_bridge, 
>> bridge)
>> -struct dp_connector {
>> -    struct drm_connector base;
>> -    struct msm_dp *dp_display;
>> -};
>> -#define to_dp_connector(x) container_of(x, struct dp_connector, base)
>> -
>>   /**
>> - * dp_connector_detect - callback to determine if connector is connected
>> - * @conn: Pointer to drm connector structure
>> - * @force: Force detect setting from drm framework
>> - * Returns: Connector 'is connected' status
>> + * dp_bridge_detect - callback to determine if connector is connected
>> + * @bridge: Pointer to drm bridge structure
>> + * Returns: Bridge's 'is connected' status
>>    */
>> -static enum drm_connector_status dp_connector_detect(struct 
>> drm_connector *conn,
>> -        bool force)
>> +static enum drm_connector_status dp_bridge_detect(struct drm_bridge 
>> *bridge)
>>   {
>>       struct msm_dp *dp;
>> -    dp = to_dp_connector(conn)->dp_display;
>> +    dp = to_dp_display(bridge)->dp_display;
>>       DRM_DEBUG_DP("is_connected = %s\n",
>>           (dp->is_connected) ? "true" : "false");
>> @@ -47,11 +40,12 @@ static enum drm_connector_status 
>> dp_connector_detect(struct drm_connector *conn,
>>   }
>>   /**
>> - * dp_connector_get_modes - callback to add drm modes via 
>> drm_mode_probed_add()
>> + * dp_bridge_get_modes - callback to add drm modes via 
>> drm_mode_probed_add()
>> + * @bridge: Poiner to drm bridge
>>    * @connector: Pointer to drm connector structure
>>    * Returns: Number of modes added
>>    */
>> -static int dp_connector_get_modes(struct drm_connector *connector)
>> +static int dp_bridge_get_modes(struct drm_bridge *bridge, struct 
>> drm_connector *connector)
>>   {
>>       int rc = 0;
>>       struct msm_dp *dp;
>> @@ -61,7 +55,7 @@ static int dp_connector_get_modes(struct 
>> drm_connector *connector)
>>       if (!connector)
>>           return 0;
>> -    dp = to_dp_connector(connector)->dp_display;
>> +    dp = to_dp_display(bridge)->dp_display;
>>       dp_mode = kzalloc(sizeof(*dp_mode),  GFP_KERNEL);
>>       if (!dp_mode)
>> @@ -102,18 +96,20 @@ static int dp_connector_get_modes(struct 
>> drm_connector *connector)
>>   }
>>   /**
>> - * dp_connector_mode_valid - callback to determine if specified mode 
>> is valid
>> - * @connector: Pointer to drm connector structure
>> + * dp_bridge_mode_valid - callback to determine if specified mode is 
>> valid
>> + * @bridge: Pointer to drm bridge structure
>> + * @info: display info
>>    * @mode: Pointer to drm mode structure
>>    * Returns: Validity status for specified mode
>>    */
>> -static enum drm_mode_status dp_connector_mode_valid(
>> -        struct drm_connector *connector,
>> -        struct drm_display_mode *mode)
>> +static enum drm_mode_status dp_bridge_mode_valid(
>> +        struct drm_bridge *bridge,
>> +        const struct drm_display_info *info,
>> +        const struct drm_display_mode *mode)
>>   {
>>       struct msm_dp *dp_disp;
>> -    dp_disp = to_dp_connector(connector)->dp_display;
>> +    dp_disp = to_dp_display(bridge)->dp_display;
>>       if ((dp_disp->max_pclk_khz <= 0) ||
>>               (dp_disp->max_pclk_khz > DP_MAX_PIXEL_CLK_KHZ) ||
>> @@ -123,55 +119,6 @@ static enum drm_mode_status dp_connector_mode_valid(
>>       return dp_display_validate_mode(dp_disp, mode->clock);
>>   }
>> -static const struct drm_connector_funcs dp_connector_funcs = {
>> -    .detect = dp_connector_detect,
>> -    .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 
>> dp_connector_helper_funcs = {
>> -    .get_modes = dp_connector_get_modes,
>> -    .mode_valid = dp_connector_mode_valid,
>> -};
>> -
>> -/* connector initialization */
>> -struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display)
>> -{
>> -    struct drm_connector *connector = NULL;
>> -    struct dp_connector *dp_connector;
>> -    int ret;
>> -
>> -    dp_connector = devm_kzalloc(dp_display->drm_dev->dev,
>> -                    sizeof(*dp_connector),
>> -                    GFP_KERNEL);
>> -    if (!dp_connector)
>> -        return ERR_PTR(-ENOMEM);
>> -
>> -    dp_connector->dp_display = dp_display;
>> -
>> -    connector = &dp_connector->base;
>> -
>> -    ret = drm_connector_init(dp_display->drm_dev, connector,
>> -            &dp_connector_funcs,
>> -            dp_display->connector_type);
>> -    if (ret)
>> -        return ERR_PTR(ret);
>> -
>> -    drm_connector_helper_add(connector, &dp_connector_helper_funcs);
>> -
>> -    /*
>> -     * Enable HPD to let hpd event is handled when cable is connected.
>> -     */
>> -    connector->polled = DRM_CONNECTOR_POLL_HPD;
>> -
>> -    drm_connector_attach_encoder(connector, dp_display->encoder);
>> -
>> -    return connector;
>> -}
>> -
>>   static void dp_bridge_mode_set(struct drm_bridge *drm_bridge,
>>                   const struct drm_display_mode *mode,
>>                   const struct drm_display_mode *adjusted_mode)
>> @@ -211,6 +158,9 @@ static const struct drm_bridge_funcs dp_bridge_ops 
>> = {
>>       .disable      = dp_bridge_disable,
>>       .post_disable = dp_bridge_post_disable,
>>       .mode_set     = dp_bridge_mode_set,
>> +    .mode_valid   = dp_bridge_mode_valid,
>> +    .get_modes    = dp_bridge_get_modes,
>> +    .detect       = dp_bridge_detect,
>>   };
>>   struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display, 
>> struct drm_device *dev,
>> @@ -228,7 +178,12 @@ struct drm_bridge *msm_dp_bridge_init(struct 
>> msm_dp *dp_display, struct drm_devi
>>       bridge = &dp_bridge->bridge;
>>       bridge->funcs = &dp_bridge_ops;
>> -    bridge->encoder = encoder;
>> +    bridge->type = dp_display->connector_type;
>> +
>> +    bridge->ops =
>> +        DRM_BRIDGE_OP_DETECT |
>> +        DRM_BRIDGE_OP_HPD |
>> +        DRM_BRIDGE_OP_MODES;
>>       rc = drm_bridge_attach(encoder, bridge, NULL, 
>> DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>>       if (rc) {
>> @@ -249,3 +204,17 @@ struct drm_bridge *msm_dp_bridge_init(struct 
>> msm_dp *dp_display, struct drm_devi
>>       return bridge;
>>   }
>> +
>> +/* connector initialization */
>> +struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display)
>> +{
>> +    struct drm_connector *connector = NULL;
>> +
>> +    connector = drm_bridge_connector_init(dp_display->drm_dev, 
>> dp_display->encoder);
>> +    if (IS_ERR(connector))
>> +        return connector;
>> +
>> +    drm_connector_attach_encoder(connector, dp_display->encoder);
>> +
>> +    return connector;
>> +}


-- 
With best wishes
Dmitry

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

* Re: [RFC PATCH v2 4/5] drm/msm/dp: replace dp_connector with drm_bridge_connector
@ 2022-02-18 21:52       ` Dmitry Baryshkov
  0 siblings, 0 replies; 84+ messages in thread
From: Dmitry Baryshkov @ 2022-02-18 21:52 UTC (permalink / raw)
  To: Kuogee Hsieh, Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: David Airlie, linux-arm-msm, dri-devel, Stephen Boyd, freedreno

On 19/02/2022 00:31, Kuogee Hsieh wrote:
> 
> On 2/11/2022 2:40 PM, Dmitry Baryshkov wrote:
>> There is little point in having both connector and root bridge
>> implementation in the same driver. Move connector's functionality to the
>> bridge to let next bridge in chain to override it.
>>
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> 
> This patch break primary (edp) display
> 
> -- right half of screen garbled
> 
> -- screen shift vertically
> 
> below are error messages seen --
> 
> [   36.679216] panel-edp soc@0:edp_panel: No display modes
> [   36.687272] panel-edp soc@0:edp_panel: No display modes
> [   40.593709] panel-edp soc@0:edp_panel: No display modes
> [   40.600285] panel-edp soc@0:edp_panel: No display modes

Thanks for testing this series!

Could you please post the result of `modetest -c` after this patch?


> 
>> ---
>>   drivers/gpu/drm/msm/dp/dp_display.c |  22 +++---
>>   drivers/gpu/drm/msm/dp/dp_drm.c     | 113 ++++++++++------------------
>>   2 files changed, 52 insertions(+), 83 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
>> b/drivers/gpu/drm/msm/dp/dp_display.c
>> index 45f9a912ecc5..59e5e5b8e5b4 100644
>> --- a/drivers/gpu/drm/msm/dp/dp_display.c
>> +++ b/drivers/gpu/drm/msm/dp/dp_display.c
>> @@ -1501,6 +1501,17 @@ int msm_dp_modeset_init(struct msm_dp 
>> *dp_display, struct drm_device *dev,
>>       dp_display->encoder = encoder;
>> +    dp_display->bridge = msm_dp_bridge_init(dp_display, dev, encoder);
>> +    if (IS_ERR(dp_display->bridge)) {
>> +        ret = PTR_ERR(dp_display->bridge);
>> +        DRM_DEV_ERROR(dev->dev,
>> +            "failed to create dp bridge: %d\n", ret);
>> +        dp_display->bridge = NULL;
>> +        return ret;
>> +    }
>> +
>> +    priv->bridges[priv->num_bridges++] = dp_display->bridge;
>> +
>>       dp_display->connector = dp_drm_connector_init(dp_display);
>>       if (IS_ERR(dp_display->connector)) {
>>           ret = PTR_ERR(dp_display->connector);
>> @@ -1514,17 +1525,6 @@ int msm_dp_modeset_init(struct msm_dp 
>> *dp_display, struct drm_device *dev,
>>       priv->connectors[priv->num_connectors++] = dp_display->connector;
>> -    dp_display->bridge = msm_dp_bridge_init(dp_display, dev, encoder);
>> -    if (IS_ERR(dp_display->bridge)) {
>> -        ret = PTR_ERR(dp_display->bridge);
>> -        DRM_DEV_ERROR(dev->dev,
>> -            "failed to create dp bridge: %d\n", ret);
>> -        dp_display->bridge = NULL;
>> -        return ret;
>> -    }
>> -
>> -    priv->bridges[priv->num_bridges++] = dp_display->bridge;
>> -
>>       return 0;
>>   }
>> diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c 
>> b/drivers/gpu/drm/msm/dp/dp_drm.c
>> index 80f59cf99089..57800b865fe6 100644
>> --- a/drivers/gpu/drm/msm/dp/dp_drm.c
>> +++ b/drivers/gpu/drm/msm/dp/dp_drm.c
>> @@ -6,6 +6,7 @@
>>   #include <drm/drm_atomic_helper.h>
>>   #include <drm/drm_atomic.h>
>>   #include <drm/drm_bridge.h>
>> +#include <drm/drm_bridge_connector.h>
>>   #include <drm/drm_crtc.h>
>>   #include "msm_drv.h"
>> @@ -20,24 +21,16 @@ struct msm_dp_bridge {
>>   #define to_dp_display(x)     container_of((x), struct msm_dp_bridge, 
>> bridge)
>> -struct dp_connector {
>> -    struct drm_connector base;
>> -    struct msm_dp *dp_display;
>> -};
>> -#define to_dp_connector(x) container_of(x, struct dp_connector, base)
>> -
>>   /**
>> - * dp_connector_detect - callback to determine if connector is connected
>> - * @conn: Pointer to drm connector structure
>> - * @force: Force detect setting from drm framework
>> - * Returns: Connector 'is connected' status
>> + * dp_bridge_detect - callback to determine if connector is connected
>> + * @bridge: Pointer to drm bridge structure
>> + * Returns: Bridge's 'is connected' status
>>    */
>> -static enum drm_connector_status dp_connector_detect(struct 
>> drm_connector *conn,
>> -        bool force)
>> +static enum drm_connector_status dp_bridge_detect(struct drm_bridge 
>> *bridge)
>>   {
>>       struct msm_dp *dp;
>> -    dp = to_dp_connector(conn)->dp_display;
>> +    dp = to_dp_display(bridge)->dp_display;
>>       DRM_DEBUG_DP("is_connected = %s\n",
>>           (dp->is_connected) ? "true" : "false");
>> @@ -47,11 +40,12 @@ static enum drm_connector_status 
>> dp_connector_detect(struct drm_connector *conn,
>>   }
>>   /**
>> - * dp_connector_get_modes - callback to add drm modes via 
>> drm_mode_probed_add()
>> + * dp_bridge_get_modes - callback to add drm modes via 
>> drm_mode_probed_add()
>> + * @bridge: Poiner to drm bridge
>>    * @connector: Pointer to drm connector structure
>>    * Returns: Number of modes added
>>    */
>> -static int dp_connector_get_modes(struct drm_connector *connector)
>> +static int dp_bridge_get_modes(struct drm_bridge *bridge, struct 
>> drm_connector *connector)
>>   {
>>       int rc = 0;
>>       struct msm_dp *dp;
>> @@ -61,7 +55,7 @@ static int dp_connector_get_modes(struct 
>> drm_connector *connector)
>>       if (!connector)
>>           return 0;
>> -    dp = to_dp_connector(connector)->dp_display;
>> +    dp = to_dp_display(bridge)->dp_display;
>>       dp_mode = kzalloc(sizeof(*dp_mode),  GFP_KERNEL);
>>       if (!dp_mode)
>> @@ -102,18 +96,20 @@ static int dp_connector_get_modes(struct 
>> drm_connector *connector)
>>   }
>>   /**
>> - * dp_connector_mode_valid - callback to determine if specified mode 
>> is valid
>> - * @connector: Pointer to drm connector structure
>> + * dp_bridge_mode_valid - callback to determine if specified mode is 
>> valid
>> + * @bridge: Pointer to drm bridge structure
>> + * @info: display info
>>    * @mode: Pointer to drm mode structure
>>    * Returns: Validity status for specified mode
>>    */
>> -static enum drm_mode_status dp_connector_mode_valid(
>> -        struct drm_connector *connector,
>> -        struct drm_display_mode *mode)
>> +static enum drm_mode_status dp_bridge_mode_valid(
>> +        struct drm_bridge *bridge,
>> +        const struct drm_display_info *info,
>> +        const struct drm_display_mode *mode)
>>   {
>>       struct msm_dp *dp_disp;
>> -    dp_disp = to_dp_connector(connector)->dp_display;
>> +    dp_disp = to_dp_display(bridge)->dp_display;
>>       if ((dp_disp->max_pclk_khz <= 0) ||
>>               (dp_disp->max_pclk_khz > DP_MAX_PIXEL_CLK_KHZ) ||
>> @@ -123,55 +119,6 @@ static enum drm_mode_status dp_connector_mode_valid(
>>       return dp_display_validate_mode(dp_disp, mode->clock);
>>   }
>> -static const struct drm_connector_funcs dp_connector_funcs = {
>> -    .detect = dp_connector_detect,
>> -    .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 
>> dp_connector_helper_funcs = {
>> -    .get_modes = dp_connector_get_modes,
>> -    .mode_valid = dp_connector_mode_valid,
>> -};
>> -
>> -/* connector initialization */
>> -struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display)
>> -{
>> -    struct drm_connector *connector = NULL;
>> -    struct dp_connector *dp_connector;
>> -    int ret;
>> -
>> -    dp_connector = devm_kzalloc(dp_display->drm_dev->dev,
>> -                    sizeof(*dp_connector),
>> -                    GFP_KERNEL);
>> -    if (!dp_connector)
>> -        return ERR_PTR(-ENOMEM);
>> -
>> -    dp_connector->dp_display = dp_display;
>> -
>> -    connector = &dp_connector->base;
>> -
>> -    ret = drm_connector_init(dp_display->drm_dev, connector,
>> -            &dp_connector_funcs,
>> -            dp_display->connector_type);
>> -    if (ret)
>> -        return ERR_PTR(ret);
>> -
>> -    drm_connector_helper_add(connector, &dp_connector_helper_funcs);
>> -
>> -    /*
>> -     * Enable HPD to let hpd event is handled when cable is connected.
>> -     */
>> -    connector->polled = DRM_CONNECTOR_POLL_HPD;
>> -
>> -    drm_connector_attach_encoder(connector, dp_display->encoder);
>> -
>> -    return connector;
>> -}
>> -
>>   static void dp_bridge_mode_set(struct drm_bridge *drm_bridge,
>>                   const struct drm_display_mode *mode,
>>                   const struct drm_display_mode *adjusted_mode)
>> @@ -211,6 +158,9 @@ static const struct drm_bridge_funcs dp_bridge_ops 
>> = {
>>       .disable      = dp_bridge_disable,
>>       .post_disable = dp_bridge_post_disable,
>>       .mode_set     = dp_bridge_mode_set,
>> +    .mode_valid   = dp_bridge_mode_valid,
>> +    .get_modes    = dp_bridge_get_modes,
>> +    .detect       = dp_bridge_detect,
>>   };
>>   struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display, 
>> struct drm_device *dev,
>> @@ -228,7 +178,12 @@ struct drm_bridge *msm_dp_bridge_init(struct 
>> msm_dp *dp_display, struct drm_devi
>>       bridge = &dp_bridge->bridge;
>>       bridge->funcs = &dp_bridge_ops;
>> -    bridge->encoder = encoder;
>> +    bridge->type = dp_display->connector_type;
>> +
>> +    bridge->ops =
>> +        DRM_BRIDGE_OP_DETECT |
>> +        DRM_BRIDGE_OP_HPD |
>> +        DRM_BRIDGE_OP_MODES;
>>       rc = drm_bridge_attach(encoder, bridge, NULL, 
>> DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>>       if (rc) {
>> @@ -249,3 +204,17 @@ struct drm_bridge *msm_dp_bridge_init(struct 
>> msm_dp *dp_display, struct drm_devi
>>       return bridge;
>>   }
>> +
>> +/* connector initialization */
>> +struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display)
>> +{
>> +    struct drm_connector *connector = NULL;
>> +
>> +    connector = drm_bridge_connector_init(dp_display->drm_dev, 
>> dp_display->encoder);
>> +    if (IS_ERR(connector))
>> +        return connector;
>> +
>> +    drm_connector_attach_encoder(connector, dp_display->encoder);
>> +
>> +    return connector;
>> +}


-- 
With best wishes
Dmitry

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

* Re: [RFC PATCH v2 4/5] drm/msm/dp: replace dp_connector with drm_bridge_connector
  2022-02-18 21:31     ` Kuogee Hsieh
@ 2022-02-18 22:32       ` Dmitry Baryshkov
  -1 siblings, 0 replies; 84+ messages in thread
From: Dmitry Baryshkov @ 2022-02-18 22:32 UTC (permalink / raw)
  To: Kuogee Hsieh, Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

On 19/02/2022 00:31, Kuogee Hsieh wrote:
> 
> On 2/11/2022 2:40 PM, Dmitry Baryshkov wrote:
>> There is little point in having both connector and root bridge
>> implementation in the same driver. Move connector's functionality to the
>> bridge to let next bridge in chain to override it.
>>
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> 
> This patch break primary (edp) display
> 
> -- right half of screen garbled
> 
> -- screen shift vertically
> 
> below are error messages seen --
> 
> [   36.679216] panel-edp soc@0:edp_panel: No display modes
> [   36.687272] panel-edp soc@0:edp_panel: No display modes
> [   40.593709] panel-edp soc@0:edp_panel: No display modes
> [   40.600285] panel-edp soc@0:edp_panel: No display modes

So, before the patch the drm core was getting modes from the 
drm_connector (which means, modes from drm driver itself). With this 
patch the panel-edp tries to get modes.

Could you please check, why panel_edp_get_modes() fails? Assuming that 
you use platform panel-edp binding (rather than 'edp-panel') could you 
please check you have either of the following:
- ddc bus for EDID?
- either num_timing or num_modes in your panel desc.


> 
>> ---
>>   drivers/gpu/drm/msm/dp/dp_display.c |  22 +++---
>>   drivers/gpu/drm/msm/dp/dp_drm.c     | 113 ++++++++++------------------
>>   2 files changed, 52 insertions(+), 83 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
>> b/drivers/gpu/drm/msm/dp/dp_display.c
>> index 45f9a912ecc5..59e5e5b8e5b4 100644
>> --- a/drivers/gpu/drm/msm/dp/dp_display.c
>> +++ b/drivers/gpu/drm/msm/dp/dp_display.c
>> @@ -1501,6 +1501,17 @@ int msm_dp_modeset_init(struct msm_dp 
>> *dp_display, struct drm_device *dev,
>>       dp_display->encoder = encoder;
>> +    dp_display->bridge = msm_dp_bridge_init(dp_display, dev, encoder);
>> +    if (IS_ERR(dp_display->bridge)) {
>> +        ret = PTR_ERR(dp_display->bridge);
>> +        DRM_DEV_ERROR(dev->dev,
>> +            "failed to create dp bridge: %d\n", ret);
>> +        dp_display->bridge = NULL;
>> +        return ret;
>> +    }
>> +
>> +    priv->bridges[priv->num_bridges++] = dp_display->bridge;
>> +
>>       dp_display->connector = dp_drm_connector_init(dp_display);
>>       if (IS_ERR(dp_display->connector)) {
>>           ret = PTR_ERR(dp_display->connector);
>> @@ -1514,17 +1525,6 @@ int msm_dp_modeset_init(struct msm_dp 
>> *dp_display, struct drm_device *dev,
>>       priv->connectors[priv->num_connectors++] = dp_display->connector;
>> -    dp_display->bridge = msm_dp_bridge_init(dp_display, dev, encoder);
>> -    if (IS_ERR(dp_display->bridge)) {
>> -        ret = PTR_ERR(dp_display->bridge);
>> -        DRM_DEV_ERROR(dev->dev,
>> -            "failed to create dp bridge: %d\n", ret);
>> -        dp_display->bridge = NULL;
>> -        return ret;
>> -    }
>> -
>> -    priv->bridges[priv->num_bridges++] = dp_display->bridge;
>> -
>>       return 0;
>>   }
>> diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c 
>> b/drivers/gpu/drm/msm/dp/dp_drm.c
>> index 80f59cf99089..57800b865fe6 100644
>> --- a/drivers/gpu/drm/msm/dp/dp_drm.c
>> +++ b/drivers/gpu/drm/msm/dp/dp_drm.c
>> @@ -6,6 +6,7 @@
>>   #include <drm/drm_atomic_helper.h>
>>   #include <drm/drm_atomic.h>
>>   #include <drm/drm_bridge.h>
>> +#include <drm/drm_bridge_connector.h>
>>   #include <drm/drm_crtc.h>
>>   #include "msm_drv.h"
>> @@ -20,24 +21,16 @@ struct msm_dp_bridge {
>>   #define to_dp_display(x)     container_of((x), struct msm_dp_bridge, 
>> bridge)
>> -struct dp_connector {
>> -    struct drm_connector base;
>> -    struct msm_dp *dp_display;
>> -};
>> -#define to_dp_connector(x) container_of(x, struct dp_connector, base)
>> -
>>   /**
>> - * dp_connector_detect - callback to determine if connector is connected
>> - * @conn: Pointer to drm connector structure
>> - * @force: Force detect setting from drm framework
>> - * Returns: Connector 'is connected' status
>> + * dp_bridge_detect - callback to determine if connector is connected
>> + * @bridge: Pointer to drm bridge structure
>> + * Returns: Bridge's 'is connected' status
>>    */
>> -static enum drm_connector_status dp_connector_detect(struct 
>> drm_connector *conn,
>> -        bool force)
>> +static enum drm_connector_status dp_bridge_detect(struct drm_bridge 
>> *bridge)
>>   {
>>       struct msm_dp *dp;
>> -    dp = to_dp_connector(conn)->dp_display;
>> +    dp = to_dp_display(bridge)->dp_display;
>>       DRM_DEBUG_DP("is_connected = %s\n",
>>           (dp->is_connected) ? "true" : "false");
>> @@ -47,11 +40,12 @@ static enum drm_connector_status 
>> dp_connector_detect(struct drm_connector *conn,
>>   }
>>   /**
>> - * dp_connector_get_modes - callback to add drm modes via 
>> drm_mode_probed_add()
>> + * dp_bridge_get_modes - callback to add drm modes via 
>> drm_mode_probed_add()
>> + * @bridge: Poiner to drm bridge
>>    * @connector: Pointer to drm connector structure
>>    * Returns: Number of modes added
>>    */
>> -static int dp_connector_get_modes(struct drm_connector *connector)
>> +static int dp_bridge_get_modes(struct drm_bridge *bridge, struct 
>> drm_connector *connector)
>>   {
>>       int rc = 0;
>>       struct msm_dp *dp;
>> @@ -61,7 +55,7 @@ static int dp_connector_get_modes(struct 
>> drm_connector *connector)
>>       if (!connector)
>>           return 0;
>> -    dp = to_dp_connector(connector)->dp_display;
>> +    dp = to_dp_display(bridge)->dp_display;
>>       dp_mode = kzalloc(sizeof(*dp_mode),  GFP_KERNEL);
>>       if (!dp_mode)
>> @@ -102,18 +96,20 @@ static int dp_connector_get_modes(struct 
>> drm_connector *connector)
>>   }
>>   /**
>> - * dp_connector_mode_valid - callback to determine if specified mode 
>> is valid
>> - * @connector: Pointer to drm connector structure
>> + * dp_bridge_mode_valid - callback to determine if specified mode is 
>> valid
>> + * @bridge: Pointer to drm bridge structure
>> + * @info: display info
>>    * @mode: Pointer to drm mode structure
>>    * Returns: Validity status for specified mode
>>    */
>> -static enum drm_mode_status dp_connector_mode_valid(
>> -        struct drm_connector *connector,
>> -        struct drm_display_mode *mode)
>> +static enum drm_mode_status dp_bridge_mode_valid(
>> +        struct drm_bridge *bridge,
>> +        const struct drm_display_info *info,
>> +        const struct drm_display_mode *mode)
>>   {
>>       struct msm_dp *dp_disp;
>> -    dp_disp = to_dp_connector(connector)->dp_display;
>> +    dp_disp = to_dp_display(bridge)->dp_display;
>>       if ((dp_disp->max_pclk_khz <= 0) ||
>>               (dp_disp->max_pclk_khz > DP_MAX_PIXEL_CLK_KHZ) ||
>> @@ -123,55 +119,6 @@ static enum drm_mode_status dp_connector_mode_valid(
>>       return dp_display_validate_mode(dp_disp, mode->clock);
>>   }
>> -static const struct drm_connector_funcs dp_connector_funcs = {
>> -    .detect = dp_connector_detect,
>> -    .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 
>> dp_connector_helper_funcs = {
>> -    .get_modes = dp_connector_get_modes,
>> -    .mode_valid = dp_connector_mode_valid,
>> -};
>> -
>> -/* connector initialization */
>> -struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display)
>> -{
>> -    struct drm_connector *connector = NULL;
>> -    struct dp_connector *dp_connector;
>> -    int ret;
>> -
>> -    dp_connector = devm_kzalloc(dp_display->drm_dev->dev,
>> -                    sizeof(*dp_connector),
>> -                    GFP_KERNEL);
>> -    if (!dp_connector)
>> -        return ERR_PTR(-ENOMEM);
>> -
>> -    dp_connector->dp_display = dp_display;
>> -
>> -    connector = &dp_connector->base;
>> -
>> -    ret = drm_connector_init(dp_display->drm_dev, connector,
>> -            &dp_connector_funcs,
>> -            dp_display->connector_type);
>> -    if (ret)
>> -        return ERR_PTR(ret);
>> -
>> -    drm_connector_helper_add(connector, &dp_connector_helper_funcs);
>> -
>> -    /*
>> -     * Enable HPD to let hpd event is handled when cable is connected.
>> -     */
>> -    connector->polled = DRM_CONNECTOR_POLL_HPD;
>> -
>> -    drm_connector_attach_encoder(connector, dp_display->encoder);
>> -
>> -    return connector;
>> -}
>> -
>>   static void dp_bridge_mode_set(struct drm_bridge *drm_bridge,
>>                   const struct drm_display_mode *mode,
>>                   const struct drm_display_mode *adjusted_mode)
>> @@ -211,6 +158,9 @@ static const struct drm_bridge_funcs dp_bridge_ops 
>> = {
>>       .disable      = dp_bridge_disable,
>>       .post_disable = dp_bridge_post_disable,
>>       .mode_set     = dp_bridge_mode_set,
>> +    .mode_valid   = dp_bridge_mode_valid,
>> +    .get_modes    = dp_bridge_get_modes,
>> +    .detect       = dp_bridge_detect,
>>   };
>>   struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display, 
>> struct drm_device *dev,
>> @@ -228,7 +178,12 @@ struct drm_bridge *msm_dp_bridge_init(struct 
>> msm_dp *dp_display, struct drm_devi
>>       bridge = &dp_bridge->bridge;
>>       bridge->funcs = &dp_bridge_ops;
>> -    bridge->encoder = encoder;
>> +    bridge->type = dp_display->connector_type;
>> +
>> +    bridge->ops =
>> +        DRM_BRIDGE_OP_DETECT |
>> +        DRM_BRIDGE_OP_HPD |
>> +        DRM_BRIDGE_OP_MODES;
>>       rc = drm_bridge_attach(encoder, bridge, NULL, 
>> DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>>       if (rc) {
>> @@ -249,3 +204,17 @@ struct drm_bridge *msm_dp_bridge_init(struct 
>> msm_dp *dp_display, struct drm_devi
>>       return bridge;
>>   }
>> +
>> +/* connector initialization */
>> +struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display)
>> +{
>> +    struct drm_connector *connector = NULL;
>> +
>> +    connector = drm_bridge_connector_init(dp_display->drm_dev, 
>> dp_display->encoder);
>> +    if (IS_ERR(connector))
>> +        return connector;
>> +
>> +    drm_connector_attach_encoder(connector, dp_display->encoder);
>> +
>> +    return connector;
>> +}


-- 
With best wishes
Dmitry

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

* Re: [RFC PATCH v2 4/5] drm/msm/dp: replace dp_connector with drm_bridge_connector
@ 2022-02-18 22:32       ` Dmitry Baryshkov
  0 siblings, 0 replies; 84+ messages in thread
From: Dmitry Baryshkov @ 2022-02-18 22:32 UTC (permalink / raw)
  To: Kuogee Hsieh, Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: David Airlie, linux-arm-msm, dri-devel, Stephen Boyd, freedreno

On 19/02/2022 00:31, Kuogee Hsieh wrote:
> 
> On 2/11/2022 2:40 PM, Dmitry Baryshkov wrote:
>> There is little point in having both connector and root bridge
>> implementation in the same driver. Move connector's functionality to the
>> bridge to let next bridge in chain to override it.
>>
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> 
> This patch break primary (edp) display
> 
> -- right half of screen garbled
> 
> -- screen shift vertically
> 
> below are error messages seen --
> 
> [   36.679216] panel-edp soc@0:edp_panel: No display modes
> [   36.687272] panel-edp soc@0:edp_panel: No display modes
> [   40.593709] panel-edp soc@0:edp_panel: No display modes
> [   40.600285] panel-edp soc@0:edp_panel: No display modes

So, before the patch the drm core was getting modes from the 
drm_connector (which means, modes from drm driver itself). With this 
patch the panel-edp tries to get modes.

Could you please check, why panel_edp_get_modes() fails? Assuming that 
you use platform panel-edp binding (rather than 'edp-panel') could you 
please check you have either of the following:
- ddc bus for EDID?
- either num_timing or num_modes in your panel desc.


> 
>> ---
>>   drivers/gpu/drm/msm/dp/dp_display.c |  22 +++---
>>   drivers/gpu/drm/msm/dp/dp_drm.c     | 113 ++++++++++------------------
>>   2 files changed, 52 insertions(+), 83 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
>> b/drivers/gpu/drm/msm/dp/dp_display.c
>> index 45f9a912ecc5..59e5e5b8e5b4 100644
>> --- a/drivers/gpu/drm/msm/dp/dp_display.c
>> +++ b/drivers/gpu/drm/msm/dp/dp_display.c
>> @@ -1501,6 +1501,17 @@ int msm_dp_modeset_init(struct msm_dp 
>> *dp_display, struct drm_device *dev,
>>       dp_display->encoder = encoder;
>> +    dp_display->bridge = msm_dp_bridge_init(dp_display, dev, encoder);
>> +    if (IS_ERR(dp_display->bridge)) {
>> +        ret = PTR_ERR(dp_display->bridge);
>> +        DRM_DEV_ERROR(dev->dev,
>> +            "failed to create dp bridge: %d\n", ret);
>> +        dp_display->bridge = NULL;
>> +        return ret;
>> +    }
>> +
>> +    priv->bridges[priv->num_bridges++] = dp_display->bridge;
>> +
>>       dp_display->connector = dp_drm_connector_init(dp_display);
>>       if (IS_ERR(dp_display->connector)) {
>>           ret = PTR_ERR(dp_display->connector);
>> @@ -1514,17 +1525,6 @@ int msm_dp_modeset_init(struct msm_dp 
>> *dp_display, struct drm_device *dev,
>>       priv->connectors[priv->num_connectors++] = dp_display->connector;
>> -    dp_display->bridge = msm_dp_bridge_init(dp_display, dev, encoder);
>> -    if (IS_ERR(dp_display->bridge)) {
>> -        ret = PTR_ERR(dp_display->bridge);
>> -        DRM_DEV_ERROR(dev->dev,
>> -            "failed to create dp bridge: %d\n", ret);
>> -        dp_display->bridge = NULL;
>> -        return ret;
>> -    }
>> -
>> -    priv->bridges[priv->num_bridges++] = dp_display->bridge;
>> -
>>       return 0;
>>   }
>> diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c 
>> b/drivers/gpu/drm/msm/dp/dp_drm.c
>> index 80f59cf99089..57800b865fe6 100644
>> --- a/drivers/gpu/drm/msm/dp/dp_drm.c
>> +++ b/drivers/gpu/drm/msm/dp/dp_drm.c
>> @@ -6,6 +6,7 @@
>>   #include <drm/drm_atomic_helper.h>
>>   #include <drm/drm_atomic.h>
>>   #include <drm/drm_bridge.h>
>> +#include <drm/drm_bridge_connector.h>
>>   #include <drm/drm_crtc.h>
>>   #include "msm_drv.h"
>> @@ -20,24 +21,16 @@ struct msm_dp_bridge {
>>   #define to_dp_display(x)     container_of((x), struct msm_dp_bridge, 
>> bridge)
>> -struct dp_connector {
>> -    struct drm_connector base;
>> -    struct msm_dp *dp_display;
>> -};
>> -#define to_dp_connector(x) container_of(x, struct dp_connector, base)
>> -
>>   /**
>> - * dp_connector_detect - callback to determine if connector is connected
>> - * @conn: Pointer to drm connector structure
>> - * @force: Force detect setting from drm framework
>> - * Returns: Connector 'is connected' status
>> + * dp_bridge_detect - callback to determine if connector is connected
>> + * @bridge: Pointer to drm bridge structure
>> + * Returns: Bridge's 'is connected' status
>>    */
>> -static enum drm_connector_status dp_connector_detect(struct 
>> drm_connector *conn,
>> -        bool force)
>> +static enum drm_connector_status dp_bridge_detect(struct drm_bridge 
>> *bridge)
>>   {
>>       struct msm_dp *dp;
>> -    dp = to_dp_connector(conn)->dp_display;
>> +    dp = to_dp_display(bridge)->dp_display;
>>       DRM_DEBUG_DP("is_connected = %s\n",
>>           (dp->is_connected) ? "true" : "false");
>> @@ -47,11 +40,12 @@ static enum drm_connector_status 
>> dp_connector_detect(struct drm_connector *conn,
>>   }
>>   /**
>> - * dp_connector_get_modes - callback to add drm modes via 
>> drm_mode_probed_add()
>> + * dp_bridge_get_modes - callback to add drm modes via 
>> drm_mode_probed_add()
>> + * @bridge: Poiner to drm bridge
>>    * @connector: Pointer to drm connector structure
>>    * Returns: Number of modes added
>>    */
>> -static int dp_connector_get_modes(struct drm_connector *connector)
>> +static int dp_bridge_get_modes(struct drm_bridge *bridge, struct 
>> drm_connector *connector)
>>   {
>>       int rc = 0;
>>       struct msm_dp *dp;
>> @@ -61,7 +55,7 @@ static int dp_connector_get_modes(struct 
>> drm_connector *connector)
>>       if (!connector)
>>           return 0;
>> -    dp = to_dp_connector(connector)->dp_display;
>> +    dp = to_dp_display(bridge)->dp_display;
>>       dp_mode = kzalloc(sizeof(*dp_mode),  GFP_KERNEL);
>>       if (!dp_mode)
>> @@ -102,18 +96,20 @@ static int dp_connector_get_modes(struct 
>> drm_connector *connector)
>>   }
>>   /**
>> - * dp_connector_mode_valid - callback to determine if specified mode 
>> is valid
>> - * @connector: Pointer to drm connector structure
>> + * dp_bridge_mode_valid - callback to determine if specified mode is 
>> valid
>> + * @bridge: Pointer to drm bridge structure
>> + * @info: display info
>>    * @mode: Pointer to drm mode structure
>>    * Returns: Validity status for specified mode
>>    */
>> -static enum drm_mode_status dp_connector_mode_valid(
>> -        struct drm_connector *connector,
>> -        struct drm_display_mode *mode)
>> +static enum drm_mode_status dp_bridge_mode_valid(
>> +        struct drm_bridge *bridge,
>> +        const struct drm_display_info *info,
>> +        const struct drm_display_mode *mode)
>>   {
>>       struct msm_dp *dp_disp;
>> -    dp_disp = to_dp_connector(connector)->dp_display;
>> +    dp_disp = to_dp_display(bridge)->dp_display;
>>       if ((dp_disp->max_pclk_khz <= 0) ||
>>               (dp_disp->max_pclk_khz > DP_MAX_PIXEL_CLK_KHZ) ||
>> @@ -123,55 +119,6 @@ static enum drm_mode_status dp_connector_mode_valid(
>>       return dp_display_validate_mode(dp_disp, mode->clock);
>>   }
>> -static const struct drm_connector_funcs dp_connector_funcs = {
>> -    .detect = dp_connector_detect,
>> -    .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 
>> dp_connector_helper_funcs = {
>> -    .get_modes = dp_connector_get_modes,
>> -    .mode_valid = dp_connector_mode_valid,
>> -};
>> -
>> -/* connector initialization */
>> -struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display)
>> -{
>> -    struct drm_connector *connector = NULL;
>> -    struct dp_connector *dp_connector;
>> -    int ret;
>> -
>> -    dp_connector = devm_kzalloc(dp_display->drm_dev->dev,
>> -                    sizeof(*dp_connector),
>> -                    GFP_KERNEL);
>> -    if (!dp_connector)
>> -        return ERR_PTR(-ENOMEM);
>> -
>> -    dp_connector->dp_display = dp_display;
>> -
>> -    connector = &dp_connector->base;
>> -
>> -    ret = drm_connector_init(dp_display->drm_dev, connector,
>> -            &dp_connector_funcs,
>> -            dp_display->connector_type);
>> -    if (ret)
>> -        return ERR_PTR(ret);
>> -
>> -    drm_connector_helper_add(connector, &dp_connector_helper_funcs);
>> -
>> -    /*
>> -     * Enable HPD to let hpd event is handled when cable is connected.
>> -     */
>> -    connector->polled = DRM_CONNECTOR_POLL_HPD;
>> -
>> -    drm_connector_attach_encoder(connector, dp_display->encoder);
>> -
>> -    return connector;
>> -}
>> -
>>   static void dp_bridge_mode_set(struct drm_bridge *drm_bridge,
>>                   const struct drm_display_mode *mode,
>>                   const struct drm_display_mode *adjusted_mode)
>> @@ -211,6 +158,9 @@ static const struct drm_bridge_funcs dp_bridge_ops 
>> = {
>>       .disable      = dp_bridge_disable,
>>       .post_disable = dp_bridge_post_disable,
>>       .mode_set     = dp_bridge_mode_set,
>> +    .mode_valid   = dp_bridge_mode_valid,
>> +    .get_modes    = dp_bridge_get_modes,
>> +    .detect       = dp_bridge_detect,
>>   };
>>   struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display, 
>> struct drm_device *dev,
>> @@ -228,7 +178,12 @@ struct drm_bridge *msm_dp_bridge_init(struct 
>> msm_dp *dp_display, struct drm_devi
>>       bridge = &dp_bridge->bridge;
>>       bridge->funcs = &dp_bridge_ops;
>> -    bridge->encoder = encoder;
>> +    bridge->type = dp_display->connector_type;
>> +
>> +    bridge->ops =
>> +        DRM_BRIDGE_OP_DETECT |
>> +        DRM_BRIDGE_OP_HPD |
>> +        DRM_BRIDGE_OP_MODES;
>>       rc = drm_bridge_attach(encoder, bridge, NULL, 
>> DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>>       if (rc) {
>> @@ -249,3 +204,17 @@ struct drm_bridge *msm_dp_bridge_init(struct 
>> msm_dp *dp_display, struct drm_devi
>>       return bridge;
>>   }
>> +
>> +/* connector initialization */
>> +struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display)
>> +{
>> +    struct drm_connector *connector = NULL;
>> +
>> +    connector = drm_bridge_connector_init(dp_display->drm_dev, 
>> dp_display->encoder);
>> +    if (IS_ERR(connector))
>> +        return connector;
>> +
>> +    drm_connector_attach_encoder(connector, dp_display->encoder);
>> +
>> +    return connector;
>> +}


-- 
With best wishes
Dmitry

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

* Re: [RFC PATCH v2 2/5] drm/msm/dp: support attaching bridges to the DP encoder
  2022-02-11 22:40   ` Dmitry Baryshkov
@ 2022-02-18 23:38     ` Stephen Boyd
  -1 siblings, 0 replies; 84+ messages in thread
From: Stephen Boyd @ 2022-02-18 23:38 UTC (permalink / raw)
  To: Abhinav Kumar, Bjorn Andersson, Dmitry Baryshkov, Kuogee Hsieh,
	Rob Clark, Sean Paul
  Cc: David Airlie, Daniel Vetter, linux-arm-msm, dri-devel, freedreno

Quoting Dmitry Baryshkov (2022-02-11 14:40:03)
> Currently DP driver will allocate panel bridge for eDP panels. This
> supports only the following topology:
>
> - eDP encoder ⇒ eDP panel (wrapped using panel-bridge)
>
> Simplify this code to just check if there is any next bridge in the
> chain (be it a panel bridge or regular bridge). Rename panel_bridge
> field to next_bridge accordingly.
>
> This allows one to use e.g. one of the following display topologies:
>
> - eDP encoder ⇒ ptn3460 ⇒ fixed LVDS panel
> - eDP encoder ⇒ ptn3460 ⇒ LVDS connector with EDID lines for panel autodetect
> - eDP encoder ⇒ ptn3460 ⇒ THC63LVD1024 ⇒ DPI panel.
> - eDP encoder ⇒ LT8912 ⇒ DSI panel
>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---

Reviewed-by: Stephen Boyd <swboyd@chromium.org>

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

* Re: [RFC PATCH v2 2/5] drm/msm/dp: support attaching bridges to the DP encoder
@ 2022-02-18 23:38     ` Stephen Boyd
  0 siblings, 0 replies; 84+ messages in thread
From: Stephen Boyd @ 2022-02-18 23:38 UTC (permalink / raw)
  To: Abhinav Kumar, Bjorn Andersson, Dmitry Baryshkov, Kuogee Hsieh,
	Rob Clark, Sean Paul
  Cc: David Airlie, linux-arm-msm, freedreno, dri-devel

Quoting Dmitry Baryshkov (2022-02-11 14:40:03)
> Currently DP driver will allocate panel bridge for eDP panels. This
> supports only the following topology:
>
> - eDP encoder ⇒ eDP panel (wrapped using panel-bridge)
>
> Simplify this code to just check if there is any next bridge in the
> chain (be it a panel bridge or regular bridge). Rename panel_bridge
> field to next_bridge accordingly.
>
> This allows one to use e.g. one of the following display topologies:
>
> - eDP encoder ⇒ ptn3460 ⇒ fixed LVDS panel
> - eDP encoder ⇒ ptn3460 ⇒ LVDS connector with EDID lines for panel autodetect
> - eDP encoder ⇒ ptn3460 ⇒ THC63LVD1024 ⇒ DPI panel.
> - eDP encoder ⇒ LT8912 ⇒ DSI panel
>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---

Reviewed-by: Stephen Boyd <swboyd@chromium.org>

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

* Re: [RFC PATCH v2 1/5] drm/msm/dp: fix panel bridge attachment
  2022-02-11 22:40   ` Dmitry Baryshkov
@ 2022-02-18 23:56     ` Stephen Boyd
  -1 siblings, 0 replies; 84+ messages in thread
From: Stephen Boyd @ 2022-02-18 23:56 UTC (permalink / raw)
  To: Abhinav Kumar, Bjorn Andersson, Dmitry Baryshkov, Kuogee Hsieh,
	Rob Clark, Sean Paul
  Cc: David Airlie, Daniel Vetter, linux-arm-msm, dri-devel, freedreno

Quoting Dmitry Baryshkov (2022-02-11 14:40:02)
> In commit 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
> enable and disable") the DP driver received a drm_bridge instance, which
> is always attached to the encoder as a root bridge. However it conflicts
> with the panel_bridge support for eDP panels. The panel bridge attaches
> to the encoder before the "dp" bridge has a chace to do so. Change

s/chace/chance/

> panel_bridge attachment to come after dp_bridge attachment.

s/panel_bridge/panel bridge/ possibly? And maybe clarify that dp_bridge
is the "DP driver's drm_bridge instance created in
msm_dp_bridge_init()"?

My understanding is that we want to pass the bridge created in
msm_dp_bridge_init() as the 'previous' bridge so that it attaches the
panel bridge to the output of the DP bridge that's attached to the
encoder.

>
> Fixes: 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display enable and disable")
> Cc: Kuogee Hsieh <quic_khsieh@quicinc.com>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---

Reviewed-by: Stephen Boyd <swboyd@chromium.org>

>  drivers/gpu/drm/msm/dp/dp_drm.c | 21 +++++++++++----------
>  1 file changed, 11 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
> index d4d360d19eba..26ef41a4c1b6 100644
> --- a/drivers/gpu/drm/msm/dp/dp_drm.c
> +++ b/drivers/gpu/drm/msm/dp/dp_drm.c
> @@ -169,16 +169,6 @@ struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display)
>
>         drm_connector_attach_encoder(connector, dp_display->encoder);
>
> -       if (dp_display->panel_bridge) {
> -               ret = drm_bridge_attach(dp_display->encoder,
> -                                       dp_display->panel_bridge, NULL,
> -                                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> -               if (ret < 0) {
> -                       DRM_ERROR("failed to attach panel bridge: %d\n", ret);
> -                       return ERR_PTR(ret);
> -               }
> -       }
> -
>         return connector;
>  }
>
> @@ -246,5 +236,16 @@ struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display, struct drm_devi
>                 return ERR_PTR(rc);
>         }
>
> +       if (dp_display->panel_bridge) {
> +               rc = drm_bridge_attach(dp_display->encoder,
> +                                       dp_display->panel_bridge, bridge,
> +                                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> +               if (rc < 0) {
> +                       DRM_ERROR("failed to attach panel bridge: %d\n", rc);
> +                       drm_bridge_remove(bridge);
> +                       return ERR_PTR(rc);
> +               }
> +       }
> +
>         return bridge;

Not a problem with this patch, but what is this pointer used for? I see
it's assigned to priv->bridges and num_bridges is incremented but nobody
seems to look at that.

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

* Re: [RFC PATCH v2 1/5] drm/msm/dp: fix panel bridge attachment
@ 2022-02-18 23:56     ` Stephen Boyd
  0 siblings, 0 replies; 84+ messages in thread
From: Stephen Boyd @ 2022-02-18 23:56 UTC (permalink / raw)
  To: Abhinav Kumar, Bjorn Andersson, Dmitry Baryshkov, Kuogee Hsieh,
	Rob Clark, Sean Paul
  Cc: David Airlie, linux-arm-msm, freedreno, dri-devel

Quoting Dmitry Baryshkov (2022-02-11 14:40:02)
> In commit 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
> enable and disable") the DP driver received a drm_bridge instance, which
> is always attached to the encoder as a root bridge. However it conflicts
> with the panel_bridge support for eDP panels. The panel bridge attaches
> to the encoder before the "dp" bridge has a chace to do so. Change

s/chace/chance/

> panel_bridge attachment to come after dp_bridge attachment.

s/panel_bridge/panel bridge/ possibly? And maybe clarify that dp_bridge
is the "DP driver's drm_bridge instance created in
msm_dp_bridge_init()"?

My understanding is that we want to pass the bridge created in
msm_dp_bridge_init() as the 'previous' bridge so that it attaches the
panel bridge to the output of the DP bridge that's attached to the
encoder.

>
> Fixes: 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display enable and disable")
> Cc: Kuogee Hsieh <quic_khsieh@quicinc.com>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---

Reviewed-by: Stephen Boyd <swboyd@chromium.org>

>  drivers/gpu/drm/msm/dp/dp_drm.c | 21 +++++++++++----------
>  1 file changed, 11 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
> index d4d360d19eba..26ef41a4c1b6 100644
> --- a/drivers/gpu/drm/msm/dp/dp_drm.c
> +++ b/drivers/gpu/drm/msm/dp/dp_drm.c
> @@ -169,16 +169,6 @@ struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display)
>
>         drm_connector_attach_encoder(connector, dp_display->encoder);
>
> -       if (dp_display->panel_bridge) {
> -               ret = drm_bridge_attach(dp_display->encoder,
> -                                       dp_display->panel_bridge, NULL,
> -                                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> -               if (ret < 0) {
> -                       DRM_ERROR("failed to attach panel bridge: %d\n", ret);
> -                       return ERR_PTR(ret);
> -               }
> -       }
> -
>         return connector;
>  }
>
> @@ -246,5 +236,16 @@ struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display, struct drm_devi
>                 return ERR_PTR(rc);
>         }
>
> +       if (dp_display->panel_bridge) {
> +               rc = drm_bridge_attach(dp_display->encoder,
> +                                       dp_display->panel_bridge, bridge,
> +                                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> +               if (rc < 0) {
> +                       DRM_ERROR("failed to attach panel bridge: %d\n", rc);
> +                       drm_bridge_remove(bridge);
> +                       return ERR_PTR(rc);
> +               }
> +       }
> +
>         return bridge;

Not a problem with this patch, but what is this pointer used for? I see
it's assigned to priv->bridges and num_bridges is incremented but nobody
seems to look at that.

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

* Re: [RFC PATCH v2 3/5] drm/msm/dp: support finding next bridge even for DP interfaces
  2022-02-11 22:40   ` Dmitry Baryshkov
@ 2022-02-19  0:34     ` Stephen Boyd
  -1 siblings, 0 replies; 84+ messages in thread
From: Stephen Boyd @ 2022-02-19  0:34 UTC (permalink / raw)
  To: Abhinav Kumar, Bjorn Andersson, Dmitry Baryshkov, Kuogee Hsieh,
	Rob Clark, Sean Paul
  Cc: David Airlie, Daniel Vetter, linux-arm-msm, dri-devel, freedreno

Quoting Dmitry Baryshkov (2022-02-11 14:40:04)
> It is possible to supply display-connector (bridge) to the DP interface,
> add support for parsing it too.
>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---

Reviewed-by: Stephen Boyd <swboyd@chromium.org>

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

* Re: [RFC PATCH v2 3/5] drm/msm/dp: support finding next bridge even for DP interfaces
@ 2022-02-19  0:34     ` Stephen Boyd
  0 siblings, 0 replies; 84+ messages in thread
From: Stephen Boyd @ 2022-02-19  0:34 UTC (permalink / raw)
  To: Abhinav Kumar, Bjorn Andersson, Dmitry Baryshkov, Kuogee Hsieh,
	Rob Clark, Sean Paul
  Cc: David Airlie, linux-arm-msm, freedreno, dri-devel

Quoting Dmitry Baryshkov (2022-02-11 14:40:04)
> It is possible to supply display-connector (bridge) to the DP interface,
> add support for parsing it too.
>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---

Reviewed-by: Stephen Boyd <swboyd@chromium.org>

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

* Re: [RFC PATCH v2 4/5] drm/msm/dp: replace dp_connector with drm_bridge_connector
  2022-02-18 22:32       ` Dmitry Baryshkov
@ 2022-02-19  0:55         ` Stephen Boyd
  -1 siblings, 0 replies; 84+ messages in thread
From: Stephen Boyd @ 2022-02-19  0:55 UTC (permalink / raw)
  To: Abhinav Kumar, Bjorn Andersson, Dmitry Baryshkov, Kuogee Hsieh,
	Rob Clark, Sean Paul
  Cc: David Airlie, Daniel Vetter, linux-arm-msm, dri-devel, freedreno

Quoting Dmitry Baryshkov (2022-02-18 14:32:53)
> On 19/02/2022 00:31, Kuogee Hsieh wrote:
> >
> > On 2/11/2022 2:40 PM, Dmitry Baryshkov wrote:
> >> There is little point in having both connector and root bridge
> >> implementation in the same driver. Move connector's functionality to the
> >> bridge to let next bridge in chain to override it.
> >>
> >> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> >
> > This patch break primary (edp) display
> >
> > -- right half of screen garbled
> >
> > -- screen shift vertically
> >
> > below are error messages seen --
> >
> > [   36.679216] panel-edp soc@0:edp_panel: No display modes
> > [   36.687272] panel-edp soc@0:edp_panel: No display modes
> > [   40.593709] panel-edp soc@0:edp_panel: No display modes
> > [   40.600285] panel-edp soc@0:edp_panel: No display modes
>
> So, before the patch the drm core was getting modes from the
> drm_connector (which means, modes from drm driver itself). With this
> patch the panel-edp tries to get modes.
>
> Could you please check, why panel_edp_get_modes() fails? Assuming that
> you use platform panel-edp binding (rather than 'edp-panel') could you
> please check you have either of the following:
> - ddc bus for EDID?

I don't see anywhere where the ddc pointer is set for the dp bridge in
msm_dp_bridge_init(). Is that required though? I'd think simple panel is
still being used here so reading EDID isn't required.

> - either num_timing or num_modes in your panel desc.
>

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

* Re: [RFC PATCH v2 4/5] drm/msm/dp: replace dp_connector with drm_bridge_connector
@ 2022-02-19  0:55         ` Stephen Boyd
  0 siblings, 0 replies; 84+ messages in thread
From: Stephen Boyd @ 2022-02-19  0:55 UTC (permalink / raw)
  To: Abhinav Kumar, Bjorn Andersson, Dmitry Baryshkov, Kuogee Hsieh,
	Rob Clark, Sean Paul
  Cc: David Airlie, linux-arm-msm, freedreno, dri-devel

Quoting Dmitry Baryshkov (2022-02-18 14:32:53)
> On 19/02/2022 00:31, Kuogee Hsieh wrote:
> >
> > On 2/11/2022 2:40 PM, Dmitry Baryshkov wrote:
> >> There is little point in having both connector and root bridge
> >> implementation in the same driver. Move connector's functionality to the
> >> bridge to let next bridge in chain to override it.
> >>
> >> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> >
> > This patch break primary (edp) display
> >
> > -- right half of screen garbled
> >
> > -- screen shift vertically
> >
> > below are error messages seen --
> >
> > [   36.679216] panel-edp soc@0:edp_panel: No display modes
> > [   36.687272] panel-edp soc@0:edp_panel: No display modes
> > [   40.593709] panel-edp soc@0:edp_panel: No display modes
> > [   40.600285] panel-edp soc@0:edp_panel: No display modes
>
> So, before the patch the drm core was getting modes from the
> drm_connector (which means, modes from drm driver itself). With this
> patch the panel-edp tries to get modes.
>
> Could you please check, why panel_edp_get_modes() fails? Assuming that
> you use platform panel-edp binding (rather than 'edp-panel') could you
> please check you have either of the following:
> - ddc bus for EDID?

I don't see anywhere where the ddc pointer is set for the dp bridge in
msm_dp_bridge_init(). Is that required though? I'd think simple panel is
still being used here so reading EDID isn't required.

> - either num_timing or num_modes in your panel desc.
>

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

* Re: [RFC PATCH v2 4/5] drm/msm/dp: replace dp_connector with drm_bridge_connector
  2022-02-19  0:55         ` Stephen Boyd
@ 2022-02-19  2:22           ` Dmitry Baryshkov
  -1 siblings, 0 replies; 84+ messages in thread
From: Dmitry Baryshkov @ 2022-02-19  2:22 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Abhinav Kumar, Bjorn Andersson, Kuogee Hsieh, Rob Clark,
	Sean Paul, David Airlie, Daniel Vetter, linux-arm-msm, dri-devel,
	freedreno

On Sat, 19 Feb 2022 at 03:55, Stephen Boyd <swboyd@chromium.org> wrote:
>
> Quoting Dmitry Baryshkov (2022-02-18 14:32:53)
> > On 19/02/2022 00:31, Kuogee Hsieh wrote:
> > >
> > > On 2/11/2022 2:40 PM, Dmitry Baryshkov wrote:
> > >> There is little point in having both connector and root bridge
> > >> implementation in the same driver. Move connector's functionality to the
> > >> bridge to let next bridge in chain to override it.
> > >>
> > >> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> > >
> > > This patch break primary (edp) display
> > >
> > > -- right half of screen garbled
> > >
> > > -- screen shift vertically
> > >
> > > below are error messages seen --
> > >
> > > [   36.679216] panel-edp soc@0:edp_panel: No display modes
> > > [   36.687272] panel-edp soc@0:edp_panel: No display modes
> > > [   40.593709] panel-edp soc@0:edp_panel: No display modes
> > > [   40.600285] panel-edp soc@0:edp_panel: No display modes
> >
> > So, before the patch the drm core was getting modes from the
> > drm_connector (which means, modes from drm driver itself). With this
> > patch the panel-edp tries to get modes.
> >
> > Could you please check, why panel_edp_get_modes() fails? Assuming that
> > you use platform panel-edp binding (rather than 'edp-panel') could you
> > please check you have either of the following:
> > - ddc bus for EDID?
>
> I don't see anywhere where the ddc pointer is set for the dp bridge in
> msm_dp_bridge_init(). Is that required though? I'd think simple panel is
> still being used here so reading EDID isn't required.

I meant the 'ddc-i2c-bus' property for the corresponding eDP panel.

> > - either num_timing or num_modes in your panel desc.

After reading the panel-edp's code I don't have another cause for
panel_edp_get_modes(). It should either have a DDC bus specified using
the mentioned device tree property, or it should have specified the
timings.

Kuogee, which platform were you using when testing this patch? Could
you please share the dts fragment?

-- 
With best wishes
Dmitry

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

* Re: [RFC PATCH v2 4/5] drm/msm/dp: replace dp_connector with drm_bridge_connector
@ 2022-02-19  2:22           ` Dmitry Baryshkov
  0 siblings, 0 replies; 84+ messages in thread
From: Dmitry Baryshkov @ 2022-02-19  2:22 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: freedreno, David Airlie, linux-arm-msm, Abhinav Kumar, dri-devel,
	Kuogee Hsieh, Bjorn Andersson, Sean Paul

On Sat, 19 Feb 2022 at 03:55, Stephen Boyd <swboyd@chromium.org> wrote:
>
> Quoting Dmitry Baryshkov (2022-02-18 14:32:53)
> > On 19/02/2022 00:31, Kuogee Hsieh wrote:
> > >
> > > On 2/11/2022 2:40 PM, Dmitry Baryshkov wrote:
> > >> There is little point in having both connector and root bridge
> > >> implementation in the same driver. Move connector's functionality to the
> > >> bridge to let next bridge in chain to override it.
> > >>
> > >> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> > >
> > > This patch break primary (edp) display
> > >
> > > -- right half of screen garbled
> > >
> > > -- screen shift vertically
> > >
> > > below are error messages seen --
> > >
> > > [   36.679216] panel-edp soc@0:edp_panel: No display modes
> > > [   36.687272] panel-edp soc@0:edp_panel: No display modes
> > > [   40.593709] panel-edp soc@0:edp_panel: No display modes
> > > [   40.600285] panel-edp soc@0:edp_panel: No display modes
> >
> > So, before the patch the drm core was getting modes from the
> > drm_connector (which means, modes from drm driver itself). With this
> > patch the panel-edp tries to get modes.
> >
> > Could you please check, why panel_edp_get_modes() fails? Assuming that
> > you use platform panel-edp binding (rather than 'edp-panel') could you
> > please check you have either of the following:
> > - ddc bus for EDID?
>
> I don't see anywhere where the ddc pointer is set for the dp bridge in
> msm_dp_bridge_init(). Is that required though? I'd think simple panel is
> still being used here so reading EDID isn't required.

I meant the 'ddc-i2c-bus' property for the corresponding eDP panel.

> > - either num_timing or num_modes in your panel desc.

After reading the panel-edp's code I don't have another cause for
panel_edp_get_modes(). It should either have a DDC bus specified using
the mentioned device tree property, or it should have specified the
timings.

Kuogee, which platform were you using when testing this patch? Could
you please share the dts fragment?

-- 
With best wishes
Dmitry

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

* Re: [RFC PATCH v2 1/5] drm/msm/dp: fix panel bridge attachment
  2022-02-18 23:56     ` Stephen Boyd
@ 2022-02-19  2:26       ` Dmitry Baryshkov
  -1 siblings, 0 replies; 84+ messages in thread
From: Dmitry Baryshkov @ 2022-02-19  2:26 UTC (permalink / raw)
  To: Stephen Boyd, Abhinav Kumar, Bjorn Andersson, Kuogee Hsieh,
	Rob Clark, Sean Paul
  Cc: David Airlie, Daniel Vetter, linux-arm-msm, dri-devel, freedreno

On 19/02/2022 02:56, Stephen Boyd wrote:
> Quoting Dmitry Baryshkov (2022-02-11 14:40:02)
>> In commit 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
>> enable and disable") the DP driver received a drm_bridge instance, which
>> is always attached to the encoder as a root bridge. However it conflicts
>> with the panel_bridge support for eDP panels. The panel bridge attaches
>> to the encoder before the "dp" bridge has a chace to do so. Change
> 
> s/chace/chance/
> 
>> panel_bridge attachment to come after dp_bridge attachment.
> 
> s/panel_bridge/panel bridge/ possibly? And maybe clarify that dp_bridge
> is the "DP driver's drm_bridge instance created in
> msm_dp_bridge_init()"?
> 
> My understanding is that we want to pass the bridge created in
> msm_dp_bridge_init() as the 'previous' bridge so that it attaches the
> panel bridge to the output of the DP bridge that's attached to the
> encoder.

Thanks! I'll update the commit log when pushing the patches.

> 
>>
>> Fixes: 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display enable and disable")
>> Cc: Kuogee Hsieh <quic_khsieh@quicinc.com>
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>> ---
> 
> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
> 
>>   drivers/gpu/drm/msm/dp/dp_drm.c | 21 +++++++++++----------
>>   1 file changed, 11 insertions(+), 10 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
>> index d4d360d19eba..26ef41a4c1b6 100644
>> --- a/drivers/gpu/drm/msm/dp/dp_drm.c
>> +++ b/drivers/gpu/drm/msm/dp/dp_drm.c
>> @@ -169,16 +169,6 @@ struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display)
>>
>>          drm_connector_attach_encoder(connector, dp_display->encoder);
>>
>> -       if (dp_display->panel_bridge) {
>> -               ret = drm_bridge_attach(dp_display->encoder,
>> -                                       dp_display->panel_bridge, NULL,
>> -                                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>> -               if (ret < 0) {
>> -                       DRM_ERROR("failed to attach panel bridge: %d\n", ret);
>> -                       return ERR_PTR(ret);
>> -               }
>> -       }
>> -
>>          return connector;
>>   }
>>
>> @@ -246,5 +236,16 @@ struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display, struct drm_devi
>>                  return ERR_PTR(rc);
>>          }
>>
>> +       if (dp_display->panel_bridge) {
>> +               rc = drm_bridge_attach(dp_display->encoder,
>> +                                       dp_display->panel_bridge, bridge,
>> +                                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>> +               if (rc < 0) {
>> +                       DRM_ERROR("failed to attach panel bridge: %d\n", rc);
>> +                       drm_bridge_remove(bridge);
>> +                       return ERR_PTR(rc);
>> +               }
>> +       }
>> +
>>          return bridge;
> 
> Not a problem with this patch, but what is this pointer used for? I see
> it's assigned to priv->bridges and num_bridges is incremented but nobody
> seems to look at that.


That's on my todo list. to remove connectors array and to destroy 
created bridges during drm device destruction.

-- 
With best wishes
Dmitry

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

* Re: [RFC PATCH v2 1/5] drm/msm/dp: fix panel bridge attachment
@ 2022-02-19  2:26       ` Dmitry Baryshkov
  0 siblings, 0 replies; 84+ messages in thread
From: Dmitry Baryshkov @ 2022-02-19  2:26 UTC (permalink / raw)
  To: Stephen Boyd, Abhinav Kumar, Bjorn Andersson, Kuogee Hsieh,
	Rob Clark, Sean Paul
  Cc: David Airlie, linux-arm-msm, freedreno, dri-devel

On 19/02/2022 02:56, Stephen Boyd wrote:
> Quoting Dmitry Baryshkov (2022-02-11 14:40:02)
>> In commit 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
>> enable and disable") the DP driver received a drm_bridge instance, which
>> is always attached to the encoder as a root bridge. However it conflicts
>> with the panel_bridge support for eDP panels. The panel bridge attaches
>> to the encoder before the "dp" bridge has a chace to do so. Change
> 
> s/chace/chance/
> 
>> panel_bridge attachment to come after dp_bridge attachment.
> 
> s/panel_bridge/panel bridge/ possibly? And maybe clarify that dp_bridge
> is the "DP driver's drm_bridge instance created in
> msm_dp_bridge_init()"?
> 
> My understanding is that we want to pass the bridge created in
> msm_dp_bridge_init() as the 'previous' bridge so that it attaches the
> panel bridge to the output of the DP bridge that's attached to the
> encoder.

Thanks! I'll update the commit log when pushing the patches.

> 
>>
>> Fixes: 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display enable and disable")
>> Cc: Kuogee Hsieh <quic_khsieh@quicinc.com>
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>> ---
> 
> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
> 
>>   drivers/gpu/drm/msm/dp/dp_drm.c | 21 +++++++++++----------
>>   1 file changed, 11 insertions(+), 10 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
>> index d4d360d19eba..26ef41a4c1b6 100644
>> --- a/drivers/gpu/drm/msm/dp/dp_drm.c
>> +++ b/drivers/gpu/drm/msm/dp/dp_drm.c
>> @@ -169,16 +169,6 @@ struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display)
>>
>>          drm_connector_attach_encoder(connector, dp_display->encoder);
>>
>> -       if (dp_display->panel_bridge) {
>> -               ret = drm_bridge_attach(dp_display->encoder,
>> -                                       dp_display->panel_bridge, NULL,
>> -                                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>> -               if (ret < 0) {
>> -                       DRM_ERROR("failed to attach panel bridge: %d\n", ret);
>> -                       return ERR_PTR(ret);
>> -               }
>> -       }
>> -
>>          return connector;
>>   }
>>
>> @@ -246,5 +236,16 @@ struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display, struct drm_devi
>>                  return ERR_PTR(rc);
>>          }
>>
>> +       if (dp_display->panel_bridge) {
>> +               rc = drm_bridge_attach(dp_display->encoder,
>> +                                       dp_display->panel_bridge, bridge,
>> +                                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>> +               if (rc < 0) {
>> +                       DRM_ERROR("failed to attach panel bridge: %d\n", rc);
>> +                       drm_bridge_remove(bridge);
>> +                       return ERR_PTR(rc);
>> +               }
>> +       }
>> +
>>          return bridge;
> 
> Not a problem with this patch, but what is this pointer used for? I see
> it's assigned to priv->bridges and num_bridges is incremented but nobody
> seems to look at that.


That's on my todo list. to remove connectors array and to destroy 
created bridges during drm device destruction.

-- 
With best wishes
Dmitry

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

* Re: [RFC PATCH v2 4/5] drm/msm/dp: replace dp_connector with drm_bridge_connector
  2022-02-19  2:22           ` Dmitry Baryshkov
@ 2022-02-23 17:21             ` Kuogee Hsieh
  -1 siblings, 0 replies; 84+ messages in thread
From: Kuogee Hsieh @ 2022-02-23 17:21 UTC (permalink / raw)
  To: Dmitry Baryshkov, Stephen Boyd
  Cc: Abhinav Kumar, Bjorn Andersson, Rob Clark, Sean Paul,
	David Airlie, Daniel Vetter, linux-arm-msm, dri-devel, freedreno


On 2/18/2022 6:22 PM, Dmitry Baryshkov wrote:
> On Sat, 19 Feb 2022 at 03:55, Stephen Boyd <swboyd@chromium.org> wrote:
>> Quoting Dmitry Baryshkov (2022-02-18 14:32:53)
>>> On 19/02/2022 00:31, Kuogee Hsieh wrote:
>>>> On 2/11/2022 2:40 PM, Dmitry Baryshkov wrote:
>>>>> There is little point in having both connector and root bridge
>>>>> implementation in the same driver. Move connector's functionality to the
>>>>> bridge to let next bridge in chain to override it.
>>>>>
>>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>>> This patch break primary (edp) display
>>>>
>>>> -- right half of screen garbled
>>>>
>>>> -- screen shift vertically
>>>>
>>>> below are error messages seen --
>>>>
>>>> [   36.679216] panel-edp soc@0:edp_panel: No display modes
>>>> [   36.687272] panel-edp soc@0:edp_panel: No display modes
>>>> [   40.593709] panel-edp soc@0:edp_panel: No display modes
>>>> [   40.600285] panel-edp soc@0:edp_panel: No display modes
>>> So, before the patch the drm core was getting modes from the
>>> drm_connector (which means, modes from drm driver itself). With this
>>> patch the panel-edp tries to get modes.
>>>
>>> Could you please check, why panel_edp_get_modes() fails? Assuming that
>>> you use platform panel-edp binding (rather than 'edp-panel') could you
>>> please check you have either of the following:
>>> - ddc bus for EDID?
>> I don't see anywhere where the ddc pointer is set for the dp bridge in
>> msm_dp_bridge_init(). Is that required though? I'd think simple panel is
>> still being used here so reading EDID isn't required.
> I meant the 'ddc-i2c-bus' property for the corresponding eDP panel.
>
>>> - either num_timing or num_modes in your panel desc.
> After reading the panel-edp's code I don't have another cause for
> panel_edp_get_modes(). It should either have a DDC bus specified using
> the mentioned device tree property, or it should have specified the
> timings.
>
> Kuogee, which platform were you using when testing this patch? Could
> you please share the dts fragment?

I cherry-picked your patches on top of our internal release which is 
usually have some (or many) patches behind msm-next.

where is "ddc-i2c-bus" located?

                         msm_edp: edp@aea0000 {
                                 compatible = "qcom,sc7280-edp";

                                 reg = <0 0xaea0000 0 0x200>,
                                       <0 0xaea0200 0 0x200>,
                                       <0 0xaea0400 0 0xc00>,
                                       <0 0xaea1000 0 0x400>;

                                 interrupt-parent = <&mdss>;
                                 interrupts = <14>;

                                 clocks = <&rpmhcc RPMH_CXO_CLK>,
                                          <&gcc GCC_EDP_CLKREF_EN>,
                                          <&dispcc DISP_CC_MDSS_AHB_CLK>,
                                          <&dispcc 
DISP_CC_MDSS_EDP_AUX_CLK>,
                                          <&dispcc 
DISP_CC_MDSS_EDP_LINK_CLK>,
                                          <&dispcc 
DISP_CC_MDSS_EDP_LINK_INTF_CLK>,
                                          <&dispcc 
DISP_CC_MDSS_EDP_PIXEL_CLK>;
                                 clock-names = "core_xo",
                                               "core_ref",
                                               "core_iface",
                                               "core_aux",
                                               "ctrl_link",
                                               "ctrl_link_iface",
                                               "stream_pixel";
                                 #clock-cells = <1>;
                                 assigned-clocks = <&dispcc 
DISP_CC_MDSS_EDP_LINK_CLK_SRC>,
                                                   <&dispcc 
DISP_CC_MDSS_EDP_PIXEL_CLK_SRC>;
                                 assigned-clock-parents = <&edp_phy 0>, 
<&edp_phy 1>;

                                 phys = <&edp_phy>;
                                 phy-names = "dp";

                                 operating-points-v2 = <&edp_opp_table>;
                                 power-domains = <&rpmhpd SC7280_CX>;

                                 #address-cells = <1>;
                                 #size-cells = <0>;

                                 status = "disabled";

                                 ports {
                                         #address-cells = <1>;
                                         #size-cells = <0>;
                                         port@0 {
                                                 reg = <0>;
                                                 edp_in: endpoint {
remote-endpoint = <&dpu_intf5_out>;
                                                 };
                                         };
                                 };

                             edp_opp_table: opp-table {
                                         compatible = "operating-points-v2";

                                         opp-160000000 {
                                                 opp-hz = /bits/ 64 
<160000000>;
                                                 required-opps = 
<&rpmhpd_opp_low_svs>;
                                         };

                                         opp-270000000 {
                                                 opp-hz = /bits/ 64 
<270000000>;
                                                 required-opps = 
<&rpmhpd_opp_svs>;
                                         };

                                         opp-540000000 {
                                                 opp-hz = /bits/ 64 
<540000000>;
                                                 required-opps = 
<&rpmhpd_opp_nom>;
                                         };

                                         opp-810000000 {
                                                 opp-hz = /bits/ 64 
<810000000>;
                                                 required-opps = 
<&rpmhpd_opp_nom>;
                                         };
                                 };
                         };


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

* Re: [RFC PATCH v2 4/5] drm/msm/dp: replace dp_connector with drm_bridge_connector
@ 2022-02-23 17:21             ` Kuogee Hsieh
  0 siblings, 0 replies; 84+ messages in thread
From: Kuogee Hsieh @ 2022-02-23 17:21 UTC (permalink / raw)
  To: Dmitry Baryshkov, Stephen Boyd
  Cc: freedreno, David Airlie, linux-arm-msm, Abhinav Kumar, dri-devel,
	Bjorn Andersson, Sean Paul


On 2/18/2022 6:22 PM, Dmitry Baryshkov wrote:
> On Sat, 19 Feb 2022 at 03:55, Stephen Boyd <swboyd@chromium.org> wrote:
>> Quoting Dmitry Baryshkov (2022-02-18 14:32:53)
>>> On 19/02/2022 00:31, Kuogee Hsieh wrote:
>>>> On 2/11/2022 2:40 PM, Dmitry Baryshkov wrote:
>>>>> There is little point in having both connector and root bridge
>>>>> implementation in the same driver. Move connector's functionality to the
>>>>> bridge to let next bridge in chain to override it.
>>>>>
>>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>>> This patch break primary (edp) display
>>>>
>>>> -- right half of screen garbled
>>>>
>>>> -- screen shift vertically
>>>>
>>>> below are error messages seen --
>>>>
>>>> [   36.679216] panel-edp soc@0:edp_panel: No display modes
>>>> [   36.687272] panel-edp soc@0:edp_panel: No display modes
>>>> [   40.593709] panel-edp soc@0:edp_panel: No display modes
>>>> [   40.600285] panel-edp soc@0:edp_panel: No display modes
>>> So, before the patch the drm core was getting modes from the
>>> drm_connector (which means, modes from drm driver itself). With this
>>> patch the panel-edp tries to get modes.
>>>
>>> Could you please check, why panel_edp_get_modes() fails? Assuming that
>>> you use platform panel-edp binding (rather than 'edp-panel') could you
>>> please check you have either of the following:
>>> - ddc bus for EDID?
>> I don't see anywhere where the ddc pointer is set for the dp bridge in
>> msm_dp_bridge_init(). Is that required though? I'd think simple panel is
>> still being used here so reading EDID isn't required.
> I meant the 'ddc-i2c-bus' property for the corresponding eDP panel.
>
>>> - either num_timing or num_modes in your panel desc.
> After reading the panel-edp's code I don't have another cause for
> panel_edp_get_modes(). It should either have a DDC bus specified using
> the mentioned device tree property, or it should have specified the
> timings.
>
> Kuogee, which platform were you using when testing this patch? Could
> you please share the dts fragment?

I cherry-picked your patches on top of our internal release which is 
usually have some (or many) patches behind msm-next.

where is "ddc-i2c-bus" located?

                         msm_edp: edp@aea0000 {
                                 compatible = "qcom,sc7280-edp";

                                 reg = <0 0xaea0000 0 0x200>,
                                       <0 0xaea0200 0 0x200>,
                                       <0 0xaea0400 0 0xc00>,
                                       <0 0xaea1000 0 0x400>;

                                 interrupt-parent = <&mdss>;
                                 interrupts = <14>;

                                 clocks = <&rpmhcc RPMH_CXO_CLK>,
                                          <&gcc GCC_EDP_CLKREF_EN>,
                                          <&dispcc DISP_CC_MDSS_AHB_CLK>,
                                          <&dispcc 
DISP_CC_MDSS_EDP_AUX_CLK>,
                                          <&dispcc 
DISP_CC_MDSS_EDP_LINK_CLK>,
                                          <&dispcc 
DISP_CC_MDSS_EDP_LINK_INTF_CLK>,
                                          <&dispcc 
DISP_CC_MDSS_EDP_PIXEL_CLK>;
                                 clock-names = "core_xo",
                                               "core_ref",
                                               "core_iface",
                                               "core_aux",
                                               "ctrl_link",
                                               "ctrl_link_iface",
                                               "stream_pixel";
                                 #clock-cells = <1>;
                                 assigned-clocks = <&dispcc 
DISP_CC_MDSS_EDP_LINK_CLK_SRC>,
                                                   <&dispcc 
DISP_CC_MDSS_EDP_PIXEL_CLK_SRC>;
                                 assigned-clock-parents = <&edp_phy 0>, 
<&edp_phy 1>;

                                 phys = <&edp_phy>;
                                 phy-names = "dp";

                                 operating-points-v2 = <&edp_opp_table>;
                                 power-domains = <&rpmhpd SC7280_CX>;

                                 #address-cells = <1>;
                                 #size-cells = <0>;

                                 status = "disabled";

                                 ports {
                                         #address-cells = <1>;
                                         #size-cells = <0>;
                                         port@0 {
                                                 reg = <0>;
                                                 edp_in: endpoint {
remote-endpoint = <&dpu_intf5_out>;
                                                 };
                                         };
                                 };

                             edp_opp_table: opp-table {
                                         compatible = "operating-points-v2";

                                         opp-160000000 {
                                                 opp-hz = /bits/ 64 
<160000000>;
                                                 required-opps = 
<&rpmhpd_opp_low_svs>;
                                         };

                                         opp-270000000 {
                                                 opp-hz = /bits/ 64 
<270000000>;
                                                 required-opps = 
<&rpmhpd_opp_svs>;
                                         };

                                         opp-540000000 {
                                                 opp-hz = /bits/ 64 
<540000000>;
                                                 required-opps = 
<&rpmhpd_opp_nom>;
                                         };

                                         opp-810000000 {
                                                 opp-hz = /bits/ 64 
<810000000>;
                                                 required-opps = 
<&rpmhpd_opp_nom>;
                                         };
                                 };
                         };


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

* Re: [RFC PATCH v2 2/5] drm/msm/dp: support attaching bridges to the DP encoder
  2022-02-11 22:40   ` Dmitry Baryshkov
@ 2022-02-23 17:47     ` Kuogee Hsieh
  -1 siblings, 0 replies; 84+ messages in thread
From: Kuogee Hsieh @ 2022-02-23 17:47 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno


On 2/11/2022 2:40 PM, Dmitry Baryshkov wrote:
> Currently DP driver will allocate panel bridge for eDP panels. This
> supports only the following topology:
>
> - eDP encoder ⇒ eDP panel (wrapped using panel-bridge)
>
> Simplify this code to just check if there is any next bridge in the
> chain (be it a panel bridge or regular bridge). Rename panel_bridge
> field to next_bridge accordingly.
>
> This allows one to use e.g. one of the following display topologies:
>
> - eDP encoder ⇒ ptn3460 ⇒ fixed LVDS panel
> - eDP encoder ⇒ ptn3460 ⇒ LVDS connector with EDID lines for panel autodetect
> - eDP encoder ⇒ ptn3460 ⇒ THC63LVD1024 ⇒ DPI panel.
> - eDP encoder ⇒ LT8912 ⇒ DSI panel
>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---

Tested-by: Kuogee Hsieh <quic_khsieh@quicinc.com>


>   drivers/gpu/drm/msm/dp/dp_display.c |  2 +-
>   drivers/gpu/drm/msm/dp/dp_display.h |  2 +-
>   drivers/gpu/drm/msm/dp/dp_drm.c     |  4 ++--
>   drivers/gpu/drm/msm/dp/dp_parser.c  | 31 +++++++++++++++--------------
>   drivers/gpu/drm/msm/dp/dp_parser.h  |  2 +-
>   5 files changed, 21 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
> index 44d42c76c2a3..45f9a912ecc5 100644
> --- a/drivers/gpu/drm/msm/dp/dp_display.c
> +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> @@ -266,7 +266,7 @@ static int dp_display_bind(struct device *dev, struct device *master,
>   		goto end;
>   	}
>   
> -	dp->dp_display.panel_bridge = dp->parser->panel_bridge;
> +	dp->dp_display.next_bridge = dp->parser->next_bridge;
>   
>   	dp->aux->drm_dev = drm;
>   	rc = dp_aux_register(dp->aux);
> diff --git a/drivers/gpu/drm/msm/dp/dp_display.h b/drivers/gpu/drm/msm/dp/dp_display.h
> index e3adcd578a90..7af2b186d2d9 100644
> --- a/drivers/gpu/drm/msm/dp/dp_display.h
> +++ b/drivers/gpu/drm/msm/dp/dp_display.h
> @@ -16,7 +16,7 @@ struct msm_dp {
>   	struct drm_bridge *bridge;
>   	struct drm_connector *connector;
>   	struct drm_encoder *encoder;
> -	struct drm_bridge *panel_bridge;
> +	struct drm_bridge *next_bridge;
>   	bool is_connected;
>   	bool audio_enabled;
>   	bool power_on;
> diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
> index 26ef41a4c1b6..80f59cf99089 100644
> --- a/drivers/gpu/drm/msm/dp/dp_drm.c
> +++ b/drivers/gpu/drm/msm/dp/dp_drm.c
> @@ -236,9 +236,9 @@ struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display, struct drm_devi
>   		return ERR_PTR(rc);
>   	}
>   
> -	if (dp_display->panel_bridge) {
> +	if (dp_display->next_bridge) {
>   		rc = drm_bridge_attach(dp_display->encoder,
> -					dp_display->panel_bridge, bridge,
> +					dp_display->next_bridge, bridge,
>   					DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>   		if (rc < 0) {
>   			DRM_ERROR("failed to attach panel bridge: %d\n", rc);
> diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c b/drivers/gpu/drm/msm/dp/dp_parser.c
> index a7acc23f742b..901d7967370f 100644
> --- a/drivers/gpu/drm/msm/dp/dp_parser.c
> +++ b/drivers/gpu/drm/msm/dp/dp_parser.c
> @@ -265,23 +265,16 @@ static int dp_parser_clock(struct dp_parser *parser)
>   	return 0;
>   }
>   
> -static int dp_parser_find_panel(struct dp_parser *parser)
> +static int dp_parser_find_next_bridge(struct dp_parser *parser)
>   {
>   	struct device *dev = &parser->pdev->dev;
> -	struct drm_panel *panel;
> -	int rc;
> +	struct drm_bridge *bridge;
>   
> -	rc = drm_of_find_panel_or_bridge(dev->of_node, 1, 0, &panel, NULL);
> -	if (rc) {
> -		DRM_ERROR("failed to acquire DRM panel: %d\n", rc);
> -		return rc;
> -	}
> +	bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0);
> +	if (IS_ERR(bridge))
> +		return PTR_ERR(bridge);
>   
> -	parser->panel_bridge = devm_drm_panel_bridge_add(dev, panel);
> -	if (IS_ERR(parser->panel_bridge)) {
> -		DRM_ERROR("failed to create panel bridge\n");
> -		return PTR_ERR(parser->panel_bridge);
> -	}
> +	parser->next_bridge = bridge;
>   
>   	return 0;
>   }
> @@ -307,10 +300,18 @@ static int dp_parser_parse(struct dp_parser *parser, int connector_type)
>   	if (rc)
>   		return rc;
>   
> +	/*
> +	 * Currently we support external bridges only for eDP connectors.
> +	 *
> +	 * No external bridges are expected for the DisplayPort connector,
> +	 * it is physically present in a form of a DP or USB-C connector.
> +	 */
>   	if (connector_type == DRM_MODE_CONNECTOR_eDP) {
> -		rc = dp_parser_find_panel(parser);
> -		if (rc)
> +		rc = dp_parser_find_next_bridge(parser);
> +		if (rc) {
> +			DRM_ERROR("DP: failed to find next bridge\n");
>   			return rc;
> +		}
>   	}
>   
>   	/* Map the corresponding regulator information according to
> diff --git a/drivers/gpu/drm/msm/dp/dp_parser.h b/drivers/gpu/drm/msm/dp/dp_parser.h
> index 3172da089421..4cec851e38d9 100644
> --- a/drivers/gpu/drm/msm/dp/dp_parser.h
> +++ b/drivers/gpu/drm/msm/dp/dp_parser.h
> @@ -123,7 +123,7 @@ struct dp_parser {
>   	struct dp_display_data disp_data;
>   	const struct dp_regulator_cfg *regulator_cfg;
>   	u32 max_dp_lanes;
> -	struct drm_bridge *panel_bridge;
> +	struct drm_bridge *next_bridge;
>   
>   	int (*parse)(struct dp_parser *parser, int connector_type);
>   };

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

* Re: [RFC PATCH v2 2/5] drm/msm/dp: support attaching bridges to the DP encoder
@ 2022-02-23 17:47     ` Kuogee Hsieh
  0 siblings, 0 replies; 84+ messages in thread
From: Kuogee Hsieh @ 2022-02-23 17:47 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: David Airlie, linux-arm-msm, dri-devel, Stephen Boyd, freedreno


On 2/11/2022 2:40 PM, Dmitry Baryshkov wrote:
> Currently DP driver will allocate panel bridge for eDP panels. This
> supports only the following topology:
>
> - eDP encoder ⇒ eDP panel (wrapped using panel-bridge)
>
> Simplify this code to just check if there is any next bridge in the
> chain (be it a panel bridge or regular bridge). Rename panel_bridge
> field to next_bridge accordingly.
>
> This allows one to use e.g. one of the following display topologies:
>
> - eDP encoder ⇒ ptn3460 ⇒ fixed LVDS panel
> - eDP encoder ⇒ ptn3460 ⇒ LVDS connector with EDID lines for panel autodetect
> - eDP encoder ⇒ ptn3460 ⇒ THC63LVD1024 ⇒ DPI panel.
> - eDP encoder ⇒ LT8912 ⇒ DSI panel
>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---

Tested-by: Kuogee Hsieh <quic_khsieh@quicinc.com>


>   drivers/gpu/drm/msm/dp/dp_display.c |  2 +-
>   drivers/gpu/drm/msm/dp/dp_display.h |  2 +-
>   drivers/gpu/drm/msm/dp/dp_drm.c     |  4 ++--
>   drivers/gpu/drm/msm/dp/dp_parser.c  | 31 +++++++++++++++--------------
>   drivers/gpu/drm/msm/dp/dp_parser.h  |  2 +-
>   5 files changed, 21 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
> index 44d42c76c2a3..45f9a912ecc5 100644
> --- a/drivers/gpu/drm/msm/dp/dp_display.c
> +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> @@ -266,7 +266,7 @@ static int dp_display_bind(struct device *dev, struct device *master,
>   		goto end;
>   	}
>   
> -	dp->dp_display.panel_bridge = dp->parser->panel_bridge;
> +	dp->dp_display.next_bridge = dp->parser->next_bridge;
>   
>   	dp->aux->drm_dev = drm;
>   	rc = dp_aux_register(dp->aux);
> diff --git a/drivers/gpu/drm/msm/dp/dp_display.h b/drivers/gpu/drm/msm/dp/dp_display.h
> index e3adcd578a90..7af2b186d2d9 100644
> --- a/drivers/gpu/drm/msm/dp/dp_display.h
> +++ b/drivers/gpu/drm/msm/dp/dp_display.h
> @@ -16,7 +16,7 @@ struct msm_dp {
>   	struct drm_bridge *bridge;
>   	struct drm_connector *connector;
>   	struct drm_encoder *encoder;
> -	struct drm_bridge *panel_bridge;
> +	struct drm_bridge *next_bridge;
>   	bool is_connected;
>   	bool audio_enabled;
>   	bool power_on;
> diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
> index 26ef41a4c1b6..80f59cf99089 100644
> --- a/drivers/gpu/drm/msm/dp/dp_drm.c
> +++ b/drivers/gpu/drm/msm/dp/dp_drm.c
> @@ -236,9 +236,9 @@ struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display, struct drm_devi
>   		return ERR_PTR(rc);
>   	}
>   
> -	if (dp_display->panel_bridge) {
> +	if (dp_display->next_bridge) {
>   		rc = drm_bridge_attach(dp_display->encoder,
> -					dp_display->panel_bridge, bridge,
> +					dp_display->next_bridge, bridge,
>   					DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>   		if (rc < 0) {
>   			DRM_ERROR("failed to attach panel bridge: %d\n", rc);
> diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c b/drivers/gpu/drm/msm/dp/dp_parser.c
> index a7acc23f742b..901d7967370f 100644
> --- a/drivers/gpu/drm/msm/dp/dp_parser.c
> +++ b/drivers/gpu/drm/msm/dp/dp_parser.c
> @@ -265,23 +265,16 @@ static int dp_parser_clock(struct dp_parser *parser)
>   	return 0;
>   }
>   
> -static int dp_parser_find_panel(struct dp_parser *parser)
> +static int dp_parser_find_next_bridge(struct dp_parser *parser)
>   {
>   	struct device *dev = &parser->pdev->dev;
> -	struct drm_panel *panel;
> -	int rc;
> +	struct drm_bridge *bridge;
>   
> -	rc = drm_of_find_panel_or_bridge(dev->of_node, 1, 0, &panel, NULL);
> -	if (rc) {
> -		DRM_ERROR("failed to acquire DRM panel: %d\n", rc);
> -		return rc;
> -	}
> +	bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0);
> +	if (IS_ERR(bridge))
> +		return PTR_ERR(bridge);
>   
> -	parser->panel_bridge = devm_drm_panel_bridge_add(dev, panel);
> -	if (IS_ERR(parser->panel_bridge)) {
> -		DRM_ERROR("failed to create panel bridge\n");
> -		return PTR_ERR(parser->panel_bridge);
> -	}
> +	parser->next_bridge = bridge;
>   
>   	return 0;
>   }
> @@ -307,10 +300,18 @@ static int dp_parser_parse(struct dp_parser *parser, int connector_type)
>   	if (rc)
>   		return rc;
>   
> +	/*
> +	 * Currently we support external bridges only for eDP connectors.
> +	 *
> +	 * No external bridges are expected for the DisplayPort connector,
> +	 * it is physically present in a form of a DP or USB-C connector.
> +	 */
>   	if (connector_type == DRM_MODE_CONNECTOR_eDP) {
> -		rc = dp_parser_find_panel(parser);
> -		if (rc)
> +		rc = dp_parser_find_next_bridge(parser);
> +		if (rc) {
> +			DRM_ERROR("DP: failed to find next bridge\n");
>   			return rc;
> +		}
>   	}
>   
>   	/* Map the corresponding regulator information according to
> diff --git a/drivers/gpu/drm/msm/dp/dp_parser.h b/drivers/gpu/drm/msm/dp/dp_parser.h
> index 3172da089421..4cec851e38d9 100644
> --- a/drivers/gpu/drm/msm/dp/dp_parser.h
> +++ b/drivers/gpu/drm/msm/dp/dp_parser.h
> @@ -123,7 +123,7 @@ struct dp_parser {
>   	struct dp_display_data disp_data;
>   	const struct dp_regulator_cfg *regulator_cfg;
>   	u32 max_dp_lanes;
> -	struct drm_bridge *panel_bridge;
> +	struct drm_bridge *next_bridge;
>   
>   	int (*parse)(struct dp_parser *parser, int connector_type);
>   };

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

* Re: [RFC PATCH v2 4/5] drm/msm/dp: replace dp_connector with drm_bridge_connector
  2022-02-23 17:21             ` Kuogee Hsieh
@ 2022-02-23 18:22               ` Dmitry Baryshkov
  -1 siblings, 0 replies; 84+ messages in thread
From: Dmitry Baryshkov @ 2022-02-23 18:22 UTC (permalink / raw)
  To: Kuogee Hsieh, Stephen Boyd
  Cc: Abhinav Kumar, Bjorn Andersson, Rob Clark, Sean Paul,
	David Airlie, Daniel Vetter, linux-arm-msm, dri-devel, freedreno

On 23/02/2022 20:21, Kuogee Hsieh wrote:
> 
> On 2/18/2022 6:22 PM, Dmitry Baryshkov wrote:
>> On Sat, 19 Feb 2022 at 03:55, Stephen Boyd <swboyd@chromium.org> wrote:
>>> Quoting Dmitry Baryshkov (2022-02-18 14:32:53)
>>>> On 19/02/2022 00:31, Kuogee Hsieh wrote:
>>>>> On 2/11/2022 2:40 PM, Dmitry Baryshkov wrote:
>>>>>> There is little point in having both connector and root bridge
>>>>>> implementation in the same driver. Move connector's functionality 
>>>>>> to the
>>>>>> bridge to let next bridge in chain to override it.
>>>>>>
>>>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>>>> This patch break primary (edp) display
>>>>>
>>>>> -- right half of screen garbled
>>>>>
>>>>> -- screen shift vertically
>>>>>
>>>>> below are error messages seen --
>>>>>
>>>>> [   36.679216] panel-edp soc@0:edp_panel: No display modes
>>>>> [   36.687272] panel-edp soc@0:edp_panel: No display modes
>>>>> [   40.593709] panel-edp soc@0:edp_panel: No display modes
>>>>> [   40.600285] panel-edp soc@0:edp_panel: No display modes
>>>> So, before the patch the drm core was getting modes from the
>>>> drm_connector (which means, modes from drm driver itself). With this
>>>> patch the panel-edp tries to get modes.
>>>>
>>>> Could you please check, why panel_edp_get_modes() fails? Assuming that
>>>> you use platform panel-edp binding (rather than 'edp-panel') could you
>>>> please check you have either of the following:
>>>> - ddc bus for EDID?
>>> I don't see anywhere where the ddc pointer is set for the dp bridge in
>>> msm_dp_bridge_init(). Is that required though? I'd think simple panel is
>>> still being used here so reading EDID isn't required.
>> I meant the 'ddc-i2c-bus' property for the corresponding eDP panel.
>>
>>>> - either num_timing or num_modes in your panel desc.
>> After reading the panel-edp's code I don't have another cause for
>> panel_edp_get_modes(). It should either have a DDC bus specified using
>> the mentioned device tree property, or it should have specified the
>> timings.
>>
>> Kuogee, which platform were you using when testing this patch? Could
>> you please share the dts fragment?
> 
> I cherry-picked your patches on top of our internal release which is 
> usually have some (or many) patches behind msm-next.
> 
> where is "ddc-i2c-bus" located?

In the panel device node.

Can you please share it too?

> 
>                          msm_edp: edp@aea0000 {
>                                  compatible = "qcom,sc7280-edp";
> 
>                                  reg = <0 0xaea0000 0 0x200>,
>                                        <0 0xaea0200 0 0x200>,
>                                        <0 0xaea0400 0 0xc00>,
>                                        <0 0xaea1000 0 0x400>;
> 
>                                  interrupt-parent = <&mdss>;
>                                  interrupts = <14>;
> 
>                                  clocks = <&rpmhcc RPMH_CXO_CLK>,
>                                           <&gcc GCC_EDP_CLKREF_EN>,
>                                           <&dispcc DISP_CC_MDSS_AHB_CLK>,
>                                           <&dispcc 
> DISP_CC_MDSS_EDP_AUX_CLK>,
>                                           <&dispcc 
> DISP_CC_MDSS_EDP_LINK_CLK>,
>                                           <&dispcc 
> DISP_CC_MDSS_EDP_LINK_INTF_CLK>,
>                                           <&dispcc 
> DISP_CC_MDSS_EDP_PIXEL_CLK>;
>                                  clock-names = "core_xo",
>                                                "core_ref",
>                                                "core_iface",
>                                                "core_aux",
>                                                "ctrl_link",
>                                                "ctrl_link_iface",
>                                                "stream_pixel";
>                                  #clock-cells = <1>;
>                                  assigned-clocks = <&dispcc 
> DISP_CC_MDSS_EDP_LINK_CLK_SRC>,
>                                                    <&dispcc 
> DISP_CC_MDSS_EDP_PIXEL_CLK_SRC>;
>                                  assigned-clock-parents = <&edp_phy 0>, 
> <&edp_phy 1>;
> 
>                                  phys = <&edp_phy>;
>                                  phy-names = "dp";
> 
>                                  operating-points-v2 = <&edp_opp_table>;
>                                  power-domains = <&rpmhpd SC7280_CX>;
> 
>                                  #address-cells = <1>;
>                                  #size-cells = <0>;
> 
>                                  status = "disabled";
> 
>                                  ports {
>                                          #address-cells = <1>;
>                                          #size-cells = <0>;
>                                          port@0 {
>                                                  reg = <0>;
>                                                  edp_in: endpoint {
> remote-endpoint = <&dpu_intf5_out>;
>                                                  };
>                                          };
>                                  };
> 
>                              edp_opp_table: opp-table {
>                                          compatible = 
> "operating-points-v2";
> 
>                                          opp-160000000 {
>                                                  opp-hz = /bits/ 64 
> <160000000>;
>                                                  required-opps = 
> <&rpmhpd_opp_low_svs>;
>                                          };
> 
>                                          opp-270000000 {
>                                                  opp-hz = /bits/ 64 
> <270000000>;
>                                                  required-opps = 
> <&rpmhpd_opp_svs>;
>                                          };
> 
>                                          opp-540000000 {
>                                                  opp-hz = /bits/ 64 
> <540000000>;
>                                                  required-opps = 
> <&rpmhpd_opp_nom>;
>                                          };
> 
>                                          opp-810000000 {
>                                                  opp-hz = /bits/ 64 
> <810000000>;
>                                                  required-opps = 
> <&rpmhpd_opp_nom>;
>                                          };
>                                  };
>                          };
> 


-- 
With best wishes
Dmitry

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

* Re: [RFC PATCH v2 4/5] drm/msm/dp: replace dp_connector with drm_bridge_connector
@ 2022-02-23 18:22               ` Dmitry Baryshkov
  0 siblings, 0 replies; 84+ messages in thread
From: Dmitry Baryshkov @ 2022-02-23 18:22 UTC (permalink / raw)
  To: Kuogee Hsieh, Stephen Boyd
  Cc: freedreno, David Airlie, linux-arm-msm, Abhinav Kumar, dri-devel,
	Bjorn Andersson, Sean Paul

On 23/02/2022 20:21, Kuogee Hsieh wrote:
> 
> On 2/18/2022 6:22 PM, Dmitry Baryshkov wrote:
>> On Sat, 19 Feb 2022 at 03:55, Stephen Boyd <swboyd@chromium.org> wrote:
>>> Quoting Dmitry Baryshkov (2022-02-18 14:32:53)
>>>> On 19/02/2022 00:31, Kuogee Hsieh wrote:
>>>>> On 2/11/2022 2:40 PM, Dmitry Baryshkov wrote:
>>>>>> There is little point in having both connector and root bridge
>>>>>> implementation in the same driver. Move connector's functionality 
>>>>>> to the
>>>>>> bridge to let next bridge in chain to override it.
>>>>>>
>>>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>>>> This patch break primary (edp) display
>>>>>
>>>>> -- right half of screen garbled
>>>>>
>>>>> -- screen shift vertically
>>>>>
>>>>> below are error messages seen --
>>>>>
>>>>> [   36.679216] panel-edp soc@0:edp_panel: No display modes
>>>>> [   36.687272] panel-edp soc@0:edp_panel: No display modes
>>>>> [   40.593709] panel-edp soc@0:edp_panel: No display modes
>>>>> [   40.600285] panel-edp soc@0:edp_panel: No display modes
>>>> So, before the patch the drm core was getting modes from the
>>>> drm_connector (which means, modes from drm driver itself). With this
>>>> patch the panel-edp tries to get modes.
>>>>
>>>> Could you please check, why panel_edp_get_modes() fails? Assuming that
>>>> you use platform panel-edp binding (rather than 'edp-panel') could you
>>>> please check you have either of the following:
>>>> - ddc bus for EDID?
>>> I don't see anywhere where the ddc pointer is set for the dp bridge in
>>> msm_dp_bridge_init(). Is that required though? I'd think simple panel is
>>> still being used here so reading EDID isn't required.
>> I meant the 'ddc-i2c-bus' property for the corresponding eDP panel.
>>
>>>> - either num_timing or num_modes in your panel desc.
>> After reading the panel-edp's code I don't have another cause for
>> panel_edp_get_modes(). It should either have a DDC bus specified using
>> the mentioned device tree property, or it should have specified the
>> timings.
>>
>> Kuogee, which platform were you using when testing this patch? Could
>> you please share the dts fragment?
> 
> I cherry-picked your patches on top of our internal release which is 
> usually have some (or many) patches behind msm-next.
> 
> where is "ddc-i2c-bus" located?

In the panel device node.

Can you please share it too?

> 
>                          msm_edp: edp@aea0000 {
>                                  compatible = "qcom,sc7280-edp";
> 
>                                  reg = <0 0xaea0000 0 0x200>,
>                                        <0 0xaea0200 0 0x200>,
>                                        <0 0xaea0400 0 0xc00>,
>                                        <0 0xaea1000 0 0x400>;
> 
>                                  interrupt-parent = <&mdss>;
>                                  interrupts = <14>;
> 
>                                  clocks = <&rpmhcc RPMH_CXO_CLK>,
>                                           <&gcc GCC_EDP_CLKREF_EN>,
>                                           <&dispcc DISP_CC_MDSS_AHB_CLK>,
>                                           <&dispcc 
> DISP_CC_MDSS_EDP_AUX_CLK>,
>                                           <&dispcc 
> DISP_CC_MDSS_EDP_LINK_CLK>,
>                                           <&dispcc 
> DISP_CC_MDSS_EDP_LINK_INTF_CLK>,
>                                           <&dispcc 
> DISP_CC_MDSS_EDP_PIXEL_CLK>;
>                                  clock-names = "core_xo",
>                                                "core_ref",
>                                                "core_iface",
>                                                "core_aux",
>                                                "ctrl_link",
>                                                "ctrl_link_iface",
>                                                "stream_pixel";
>                                  #clock-cells = <1>;
>                                  assigned-clocks = <&dispcc 
> DISP_CC_MDSS_EDP_LINK_CLK_SRC>,
>                                                    <&dispcc 
> DISP_CC_MDSS_EDP_PIXEL_CLK_SRC>;
>                                  assigned-clock-parents = <&edp_phy 0>, 
> <&edp_phy 1>;
> 
>                                  phys = <&edp_phy>;
>                                  phy-names = "dp";
> 
>                                  operating-points-v2 = <&edp_opp_table>;
>                                  power-domains = <&rpmhpd SC7280_CX>;
> 
>                                  #address-cells = <1>;
>                                  #size-cells = <0>;
> 
>                                  status = "disabled";
> 
>                                  ports {
>                                          #address-cells = <1>;
>                                          #size-cells = <0>;
>                                          port@0 {
>                                                  reg = <0>;
>                                                  edp_in: endpoint {
> remote-endpoint = <&dpu_intf5_out>;
>                                                  };
>                                          };
>                                  };
> 
>                              edp_opp_table: opp-table {
>                                          compatible = 
> "operating-points-v2";
> 
>                                          opp-160000000 {
>                                                  opp-hz = /bits/ 64 
> <160000000>;
>                                                  required-opps = 
> <&rpmhpd_opp_low_svs>;
>                                          };
> 
>                                          opp-270000000 {
>                                                  opp-hz = /bits/ 64 
> <270000000>;
>                                                  required-opps = 
> <&rpmhpd_opp_svs>;
>                                          };
> 
>                                          opp-540000000 {
>                                                  opp-hz = /bits/ 64 
> <540000000>;
>                                                  required-opps = 
> <&rpmhpd_opp_nom>;
>                                          };
> 
>                                          opp-810000000 {
>                                                  opp-hz = /bits/ 64 
> <810000000>;
>                                                  required-opps = 
> <&rpmhpd_opp_nom>;
>                                          };
>                                  };
>                          };
> 


-- 
With best wishes
Dmitry

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

* Re: [RFC PATCH v2 4/5] drm/msm/dp: replace dp_connector with drm_bridge_connector
  2022-02-23 18:22               ` Dmitry Baryshkov
@ 2022-02-23 18:27                 ` Kuogee Hsieh
  -1 siblings, 0 replies; 84+ messages in thread
From: Kuogee Hsieh @ 2022-02-23 18:27 UTC (permalink / raw)
  To: Dmitry Baryshkov, Stephen Boyd
  Cc: Abhinav Kumar, Bjorn Andersson, Rob Clark, Sean Paul,
	David Airlie, Daniel Vetter, linux-arm-msm, dri-devel, freedreno


On 2/23/2022 10:22 AM, Dmitry Baryshkov wrote:
> On 23/02/2022 20:21, Kuogee Hsieh wrote:
>>
>> On 2/18/2022 6:22 PM, Dmitry Baryshkov wrote:
>>> On Sat, 19 Feb 2022 at 03:55, Stephen Boyd <swboyd@chromium.org> wrote:
>>>> Quoting Dmitry Baryshkov (2022-02-18 14:32:53)
>>>>> On 19/02/2022 00:31, Kuogee Hsieh wrote:
>>>>>> On 2/11/2022 2:40 PM, Dmitry Baryshkov wrote:
>>>>>>> There is little point in having both connector and root bridge
>>>>>>> implementation in the same driver. Move connector's 
>>>>>>> functionality to the
>>>>>>> bridge to let next bridge in chain to override it.
>>>>>>>
>>>>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>>>>> This patch break primary (edp) display
>>>>>>
>>>>>> -- right half of screen garbled
>>>>>>
>>>>>> -- screen shift vertically
>>>>>>
>>>>>> below are error messages seen --
>>>>>>
>>>>>> [   36.679216] panel-edp soc@0:edp_panel: No display modes
>>>>>> [   36.687272] panel-edp soc@0:edp_panel: No display modes
>>>>>> [   40.593709] panel-edp soc@0:edp_panel: No display modes
>>>>>> [   40.600285] panel-edp soc@0:edp_panel: No display modes
>>>>> So, before the patch the drm core was getting modes from the
>>>>> drm_connector (which means, modes from drm driver itself). With this
>>>>> patch the panel-edp tries to get modes.
>>>>>
>>>>> Could you please check, why panel_edp_get_modes() fails? Assuming 
>>>>> that
>>>>> you use platform panel-edp binding (rather than 'edp-panel') could 
>>>>> you
>>>>> please check you have either of the following:
>>>>> - ddc bus for EDID?
>>>> I don't see anywhere where the ddc pointer is set for the dp bridge in
>>>> msm_dp_bridge_init(). Is that required though? I'd think simple 
>>>> panel is
>>>> still being used here so reading EDID isn't required.
>>> I meant the 'ddc-i2c-bus' property for the corresponding eDP panel.
>>>
>>>>> - either num_timing or num_modes in your panel desc.
>>> After reading the panel-edp's code I don't have another cause for
>>> panel_edp_get_modes(). It should either have a DDC bus specified using
>>> the mentioned device tree property, or it should have specified the
>>> timings.
>>>
>>> Kuogee, which platform were you using when testing this patch? Could
>>> you please share the dts fragment?
>>
>> I cherry-picked your patches on top of our internal release which is 
>> usually have some (or many) patches behind msm-next.
>>
>> where is "ddc-i2c-bus" located?
>
> In the panel device node.
>
> Can you please share it too?


&soc {
         edp_power_supply: edp_power {
                 compatible = "regulator-fixed";
                 regulator-name = "edp_backlight_power";

                 regulator-always-on;
                 regulator-boot-on;
         };

         edp_backlight: edp_backlight {
                 compatible = "pwm-backlight";

                 pwms = <&pm8350c_pwm 3 65535>;
                 power-supply = <&edp_power_supply>;
                 enable-gpio = <&pm8350c_gpios 7 GPIO_ACTIVE_HIGH>;

                 pinctrl-names = "default";
                 pinctrl-0 = <&backlight_pwm_default>;
         };

         edp_panel: edp_panel {
                 compatible = "sharp_lq140m1jw46";

                 pinctrl-names = "default";
                 pinctrl-0 = <&edp_hot_plug_det>, 
<&edp_panel_power_default>;

                 power-supply = <&edp_power_supply>;
                 backlight = <&edp_backlight>;

                 ports {
                         #address-cells = <1>;
                         #size-cells = <0>;
                         port@0 {
                                 reg = <0>;
                                 edp_panel_in: endpoint {
                                         remote-endpoint = <&edp_out>;
                                 };
                         };
                 };
         };
};


>
>>
>>                          msm_edp: edp@aea0000 {
>>                                  compatible = "qcom,sc7280-edp";
>>
>>                                  reg = <0 0xaea0000 0 0x200>,
>>                                        <0 0xaea0200 0 0x200>,
>>                                        <0 0xaea0400 0 0xc00>,
>>                                        <0 0xaea1000 0 0x400>;
>>
>>                                  interrupt-parent = <&mdss>;
>>                                  interrupts = <14>;
>>
>>                                  clocks = <&rpmhcc RPMH_CXO_CLK>,
>>                                           <&gcc GCC_EDP_CLKREF_EN>,
>>                                           <&dispcc 
>> DISP_CC_MDSS_AHB_CLK>,
>>                                           <&dispcc 
>> DISP_CC_MDSS_EDP_AUX_CLK>,
>>                                           <&dispcc 
>> DISP_CC_MDSS_EDP_LINK_CLK>,
>>                                           <&dispcc 
>> DISP_CC_MDSS_EDP_LINK_INTF_CLK>,
>>                                           <&dispcc 
>> DISP_CC_MDSS_EDP_PIXEL_CLK>;
>>                                  clock-names = "core_xo",
>>                                                "core_ref",
>>                                                "core_iface",
>>                                                "core_aux",
>>                                                "ctrl_link",
>> "ctrl_link_iface",
>>                                                "stream_pixel";
>>                                  #clock-cells = <1>;
>>                                  assigned-clocks = <&dispcc 
>> DISP_CC_MDSS_EDP_LINK_CLK_SRC>,
>> <&dispcc DISP_CC_MDSS_EDP_PIXEL_CLK_SRC>;
>>                                  assigned-clock-parents = <&edp_phy 
>> 0>, <&edp_phy 1>;
>>
>>                                  phys = <&edp_phy>;
>>                                  phy-names = "dp";
>>
>>                                  operating-points-v2 = <&edp_opp_table>;
>>                                  power-domains = <&rpmhpd SC7280_CX>;
>>
>>                                  #address-cells = <1>;
>>                                  #size-cells = <0>;
>>
>>                                  status = "disabled";
>>
>>                                  ports {
>>                                          #address-cells = <1>;
>>                                          #size-cells = <0>;
>>                                          port@0 {
>>                                                  reg = <0>;
>>                                                  edp_in: endpoint {
>> remote-endpoint = <&dpu_intf5_out>;
>>                                                  };
>>                                          };
>>                                  };
>>
>>                              edp_opp_table: opp-table {
>>                                          compatible = 
>> "operating-points-v2";
>>
>>                                          opp-160000000 {
>>                                                  opp-hz = /bits/ 64 
>> <160000000>;
>>                                                  required-opps = 
>> <&rpmhpd_opp_low_svs>;
>>                                          };
>>
>>                                          opp-270000000 {
>>                                                  opp-hz = /bits/ 64 
>> <270000000>;
>>                                                  required-opps = 
>> <&rpmhpd_opp_svs>;
>>                                          };
>>
>>                                          opp-540000000 {
>>                                                  opp-hz = /bits/ 64 
>> <540000000>;
>>                                                  required-opps = 
>> <&rpmhpd_opp_nom>;
>>                                          };
>>
>>                                          opp-810000000 {
>>                                                  opp-hz = /bits/ 64 
>> <810000000>;
>>                                                  required-opps = 
>> <&rpmhpd_opp_nom>;
>>                                          };
>>                                  };
>>                          };
>>
>
>

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

* Re: [RFC PATCH v2 4/5] drm/msm/dp: replace dp_connector with drm_bridge_connector
@ 2022-02-23 18:27                 ` Kuogee Hsieh
  0 siblings, 0 replies; 84+ messages in thread
From: Kuogee Hsieh @ 2022-02-23 18:27 UTC (permalink / raw)
  To: Dmitry Baryshkov, Stephen Boyd
  Cc: freedreno, David Airlie, linux-arm-msm, Abhinav Kumar, dri-devel,
	Bjorn Andersson, Sean Paul


On 2/23/2022 10:22 AM, Dmitry Baryshkov wrote:
> On 23/02/2022 20:21, Kuogee Hsieh wrote:
>>
>> On 2/18/2022 6:22 PM, Dmitry Baryshkov wrote:
>>> On Sat, 19 Feb 2022 at 03:55, Stephen Boyd <swboyd@chromium.org> wrote:
>>>> Quoting Dmitry Baryshkov (2022-02-18 14:32:53)
>>>>> On 19/02/2022 00:31, Kuogee Hsieh wrote:
>>>>>> On 2/11/2022 2:40 PM, Dmitry Baryshkov wrote:
>>>>>>> There is little point in having both connector and root bridge
>>>>>>> implementation in the same driver. Move connector's 
>>>>>>> functionality to the
>>>>>>> bridge to let next bridge in chain to override it.
>>>>>>>
>>>>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>>>>> This patch break primary (edp) display
>>>>>>
>>>>>> -- right half of screen garbled
>>>>>>
>>>>>> -- screen shift vertically
>>>>>>
>>>>>> below are error messages seen --
>>>>>>
>>>>>> [   36.679216] panel-edp soc@0:edp_panel: No display modes
>>>>>> [   36.687272] panel-edp soc@0:edp_panel: No display modes
>>>>>> [   40.593709] panel-edp soc@0:edp_panel: No display modes
>>>>>> [   40.600285] panel-edp soc@0:edp_panel: No display modes
>>>>> So, before the patch the drm core was getting modes from the
>>>>> drm_connector (which means, modes from drm driver itself). With this
>>>>> patch the panel-edp tries to get modes.
>>>>>
>>>>> Could you please check, why panel_edp_get_modes() fails? Assuming 
>>>>> that
>>>>> you use platform panel-edp binding (rather than 'edp-panel') could 
>>>>> you
>>>>> please check you have either of the following:
>>>>> - ddc bus for EDID?
>>>> I don't see anywhere where the ddc pointer is set for the dp bridge in
>>>> msm_dp_bridge_init(). Is that required though? I'd think simple 
>>>> panel is
>>>> still being used here so reading EDID isn't required.
>>> I meant the 'ddc-i2c-bus' property for the corresponding eDP panel.
>>>
>>>>> - either num_timing or num_modes in your panel desc.
>>> After reading the panel-edp's code I don't have another cause for
>>> panel_edp_get_modes(). It should either have a DDC bus specified using
>>> the mentioned device tree property, or it should have specified the
>>> timings.
>>>
>>> Kuogee, which platform were you using when testing this patch? Could
>>> you please share the dts fragment?
>>
>> I cherry-picked your patches on top of our internal release which is 
>> usually have some (or many) patches behind msm-next.
>>
>> where is "ddc-i2c-bus" located?
>
> In the panel device node.
>
> Can you please share it too?


&soc {
         edp_power_supply: edp_power {
                 compatible = "regulator-fixed";
                 regulator-name = "edp_backlight_power";

                 regulator-always-on;
                 regulator-boot-on;
         };

         edp_backlight: edp_backlight {
                 compatible = "pwm-backlight";

                 pwms = <&pm8350c_pwm 3 65535>;
                 power-supply = <&edp_power_supply>;
                 enable-gpio = <&pm8350c_gpios 7 GPIO_ACTIVE_HIGH>;

                 pinctrl-names = "default";
                 pinctrl-0 = <&backlight_pwm_default>;
         };

         edp_panel: edp_panel {
                 compatible = "sharp_lq140m1jw46";

                 pinctrl-names = "default";
                 pinctrl-0 = <&edp_hot_plug_det>, 
<&edp_panel_power_default>;

                 power-supply = <&edp_power_supply>;
                 backlight = <&edp_backlight>;

                 ports {
                         #address-cells = <1>;
                         #size-cells = <0>;
                         port@0 {
                                 reg = <0>;
                                 edp_panel_in: endpoint {
                                         remote-endpoint = <&edp_out>;
                                 };
                         };
                 };
         };
};


>
>>
>>                          msm_edp: edp@aea0000 {
>>                                  compatible = "qcom,sc7280-edp";
>>
>>                                  reg = <0 0xaea0000 0 0x200>,
>>                                        <0 0xaea0200 0 0x200>,
>>                                        <0 0xaea0400 0 0xc00>,
>>                                        <0 0xaea1000 0 0x400>;
>>
>>                                  interrupt-parent = <&mdss>;
>>                                  interrupts = <14>;
>>
>>                                  clocks = <&rpmhcc RPMH_CXO_CLK>,
>>                                           <&gcc GCC_EDP_CLKREF_EN>,
>>                                           <&dispcc 
>> DISP_CC_MDSS_AHB_CLK>,
>>                                           <&dispcc 
>> DISP_CC_MDSS_EDP_AUX_CLK>,
>>                                           <&dispcc 
>> DISP_CC_MDSS_EDP_LINK_CLK>,
>>                                           <&dispcc 
>> DISP_CC_MDSS_EDP_LINK_INTF_CLK>,
>>                                           <&dispcc 
>> DISP_CC_MDSS_EDP_PIXEL_CLK>;
>>                                  clock-names = "core_xo",
>>                                                "core_ref",
>>                                                "core_iface",
>>                                                "core_aux",
>>                                                "ctrl_link",
>> "ctrl_link_iface",
>>                                                "stream_pixel";
>>                                  #clock-cells = <1>;
>>                                  assigned-clocks = <&dispcc 
>> DISP_CC_MDSS_EDP_LINK_CLK_SRC>,
>> <&dispcc DISP_CC_MDSS_EDP_PIXEL_CLK_SRC>;
>>                                  assigned-clock-parents = <&edp_phy 
>> 0>, <&edp_phy 1>;
>>
>>                                  phys = <&edp_phy>;
>>                                  phy-names = "dp";
>>
>>                                  operating-points-v2 = <&edp_opp_table>;
>>                                  power-domains = <&rpmhpd SC7280_CX>;
>>
>>                                  #address-cells = <1>;
>>                                  #size-cells = <0>;
>>
>>                                  status = "disabled";
>>
>>                                  ports {
>>                                          #address-cells = <1>;
>>                                          #size-cells = <0>;
>>                                          port@0 {
>>                                                  reg = <0>;
>>                                                  edp_in: endpoint {
>> remote-endpoint = <&dpu_intf5_out>;
>>                                                  };
>>                                          };
>>                                  };
>>
>>                              edp_opp_table: opp-table {
>>                                          compatible = 
>> "operating-points-v2";
>>
>>                                          opp-160000000 {
>>                                                  opp-hz = /bits/ 64 
>> <160000000>;
>>                                                  required-opps = 
>> <&rpmhpd_opp_low_svs>;
>>                                          };
>>
>>                                          opp-270000000 {
>>                                                  opp-hz = /bits/ 64 
>> <270000000>;
>>                                                  required-opps = 
>> <&rpmhpd_opp_svs>;
>>                                          };
>>
>>                                          opp-540000000 {
>>                                                  opp-hz = /bits/ 64 
>> <540000000>;
>>                                                  required-opps = 
>> <&rpmhpd_opp_nom>;
>>                                          };
>>
>>                                          opp-810000000 {
>>                                                  opp-hz = /bits/ 64 
>> <810000000>;
>>                                                  required-opps = 
>> <&rpmhpd_opp_nom>;
>>                                          };
>>                                  };
>>                          };
>>
>
>

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

* Re: [RFC PATCH v2 4/5] drm/msm/dp: replace dp_connector with drm_bridge_connector
  2022-02-23 18:27                 ` Kuogee Hsieh
@ 2022-02-23 18:45                   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 84+ messages in thread
From: Dmitry Baryshkov @ 2022-02-23 18:45 UTC (permalink / raw)
  To: Kuogee Hsieh
  Cc: Stephen Boyd, Abhinav Kumar, Bjorn Andersson, Rob Clark,
	Sean Paul, David Airlie, Daniel Vetter, linux-arm-msm, dri-devel,
	freedreno

On Wed, 23 Feb 2022 at 21:27, Kuogee Hsieh <quic_khsieh@quicinc.com> wrote:
>
>
> On 2/23/2022 10:22 AM, Dmitry Baryshkov wrote:
> > On 23/02/2022 20:21, Kuogee Hsieh wrote:
> >>
> >> On 2/18/2022 6:22 PM, Dmitry Baryshkov wrote:
> >>> On Sat, 19 Feb 2022 at 03:55, Stephen Boyd <swboyd@chromium.org> wrote:
> >>>> Quoting Dmitry Baryshkov (2022-02-18 14:32:53)
> >>>>> On 19/02/2022 00:31, Kuogee Hsieh wrote:
> >>>>>> On 2/11/2022 2:40 PM, Dmitry Baryshkov wrote:
> >>>>>>> There is little point in having both connector and root bridge
> >>>>>>> implementation in the same driver. Move connector's
> >>>>>>> functionality to the
> >>>>>>> bridge to let next bridge in chain to override it.
> >>>>>>>
> >>>>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> >>>>>> This patch break primary (edp) display
> >>>>>>
> >>>>>> -- right half of screen garbled
> >>>>>>
> >>>>>> -- screen shift vertically
> >>>>>>
> >>>>>> below are error messages seen --
> >>>>>>
> >>>>>> [   36.679216] panel-edp soc@0:edp_panel: No display modes
> >>>>>> [   36.687272] panel-edp soc@0:edp_panel: No display modes
> >>>>>> [   40.593709] panel-edp soc@0:edp_panel: No display modes
> >>>>>> [   40.600285] panel-edp soc@0:edp_panel: No display modes
> >>>>> So, before the patch the drm core was getting modes from the
> >>>>> drm_connector (which means, modes from drm driver itself). With this
> >>>>> patch the panel-edp tries to get modes.
> >>>>>
> >>>>> Could you please check, why panel_edp_get_modes() fails? Assuming
> >>>>> that
> >>>>> you use platform panel-edp binding (rather than 'edp-panel') could
> >>>>> you
> >>>>> please check you have either of the following:
> >>>>> - ddc bus for EDID?
> >>>> I don't see anywhere where the ddc pointer is set for the dp bridge in
> >>>> msm_dp_bridge_init(). Is that required though? I'd think simple
> >>>> panel is
> >>>> still being used here so reading EDID isn't required.
> >>> I meant the 'ddc-i2c-bus' property for the corresponding eDP panel.
> >>>
> >>>>> - either num_timing or num_modes in your panel desc.
> >>> After reading the panel-edp's code I don't have another cause for
> >>> panel_edp_get_modes(). It should either have a DDC bus specified using
> >>> the mentioned device tree property, or it should have specified the
> >>> timings.
> >>>
> >>> Kuogee, which platform were you using when testing this patch? Could
> >>> you please share the dts fragment?
> >>
> >> I cherry-picked your patches on top of our internal release which is
> >> usually have some (or many) patches behind msm-next.
> >>
> >> where is "ddc-i2c-bus" located?
> >
> > In the panel device node.
> >
> > Can you please share it too?
>
>
> &soc {
>          edp_power_supply: edp_power {
>                  compatible = "regulator-fixed";
>                  regulator-name = "edp_backlight_power";
>
>                  regulator-always-on;
>                  regulator-boot-on;
>          };
>
>          edp_backlight: edp_backlight {
>                  compatible = "pwm-backlight";
>
>                  pwms = <&pm8350c_pwm 3 65535>;
>                  power-supply = <&edp_power_supply>;
>                  enable-gpio = <&pm8350c_gpios 7 GPIO_ACTIVE_HIGH>;
>
>                  pinctrl-names = "default";
>                  pinctrl-0 = <&backlight_pwm_default>;
>          };
>
>          edp_panel: edp_panel {
>                  compatible = "sharp_lq140m1jw46";

I'd assume that the panel is supported by the patch
https://patchwork.kernel.org/project/linux-arm-msm/patch/1644494255-6632-5-git-send-email-quic_sbillaka@quicinc.com/
and the compatible value is just an old value.
Provided that the panel description defines modes, I'd ask for some
debug from the panel_edp_get_modes(). At least let's see why
panel_edp_get_non_edid_modes() / panel_edp_get_display_modes() returns
no modes.

Regarding the ddc bus, if you have separate i2c bus connected to this
panel, the ddc-i2c-bus = <&i2c_N>; property should go to this device
node.

>                  pinctrl-names = "default";
>                  pinctrl-0 = <&edp_hot_plug_det>,
> <&edp_panel_power_default>;
>
>                  power-supply = <&edp_power_supply>;
>                  backlight = <&edp_backlight>;
>
>                  ports {
>                          #address-cells = <1>;
>                          #size-cells = <0>;
>                          port@0 {
>                                  reg = <0>;
>                                  edp_panel_in: endpoint {
>                                          remote-endpoint = <&edp_out>;
>                                  };
>                          };
>                  };
>          };
> };
>
>
> >
> >>
> >>                          msm_edp: edp@aea0000 {
> >>                                  compatible = "qcom,sc7280-edp";
> >>
> >>                                  reg = <0 0xaea0000 0 0x200>,
> >>                                        <0 0xaea0200 0 0x200>,
> >>                                        <0 0xaea0400 0 0xc00>,
> >>                                        <0 0xaea1000 0 0x400>;
> >>
> >>                                  interrupt-parent = <&mdss>;
> >>                                  interrupts = <14>;
> >>
> >>                                  clocks = <&rpmhcc RPMH_CXO_CLK>,
> >>                                           <&gcc GCC_EDP_CLKREF_EN>,
> >>                                           <&dispcc
> >> DISP_CC_MDSS_AHB_CLK>,
> >>                                           <&dispcc
> >> DISP_CC_MDSS_EDP_AUX_CLK>,
> >>                                           <&dispcc
> >> DISP_CC_MDSS_EDP_LINK_CLK>,
> >>                                           <&dispcc
> >> DISP_CC_MDSS_EDP_LINK_INTF_CLK>,
> >>                                           <&dispcc
> >> DISP_CC_MDSS_EDP_PIXEL_CLK>;
> >>                                  clock-names = "core_xo",
> >>                                                "core_ref",
> >>                                                "core_iface",
> >>                                                "core_aux",
> >>                                                "ctrl_link",
> >> "ctrl_link_iface",
> >>                                                "stream_pixel";
> >>                                  #clock-cells = <1>;
> >>                                  assigned-clocks = <&dispcc
> >> DISP_CC_MDSS_EDP_LINK_CLK_SRC>,
> >> <&dispcc DISP_CC_MDSS_EDP_PIXEL_CLK_SRC>;
> >>                                  assigned-clock-parents = <&edp_phy
> >> 0>, <&edp_phy 1>;
> >>
> >>                                  phys = <&edp_phy>;
> >>                                  phy-names = "dp";
> >>
> >>                                  operating-points-v2 = <&edp_opp_table>;
> >>                                  power-domains = <&rpmhpd SC7280_CX>;
> >>
> >>                                  #address-cells = <1>;
> >>                                  #size-cells = <0>;
> >>
> >>                                  status = "disabled";
> >>
> >>                                  ports {
> >>                                          #address-cells = <1>;
> >>                                          #size-cells = <0>;
> >>                                          port@0 {
> >>                                                  reg = <0>;
> >>                                                  edp_in: endpoint {
> >> remote-endpoint = <&dpu_intf5_out>;
> >>                                                  };
> >>                                          };
> >>                                  };
> >>
> >>                              edp_opp_table: opp-table {
> >>                                          compatible =
> >> "operating-points-v2";
> >>
> >>                                          opp-160000000 {
> >>                                                  opp-hz = /bits/ 64
> >> <160000000>;
> >>                                                  required-opps =
> >> <&rpmhpd_opp_low_svs>;
> >>                                          };
> >>
> >>                                          opp-270000000 {
> >>                                                  opp-hz = /bits/ 64
> >> <270000000>;
> >>                                                  required-opps =
> >> <&rpmhpd_opp_svs>;
> >>                                          };
> >>
> >>                                          opp-540000000 {
> >>                                                  opp-hz = /bits/ 64
> >> <540000000>;
> >>                                                  required-opps =
> >> <&rpmhpd_opp_nom>;
> >>                                          };
> >>
> >>                                          opp-810000000 {
> >>                                                  opp-hz = /bits/ 64
> >> <810000000>;
> >>                                                  required-opps =
> >> <&rpmhpd_opp_nom>;
> >>                                          };
> >>                                  };
> >>                          };
> >>
> >
> >



-- 
With best wishes
Dmitry

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

* Re: [RFC PATCH v2 4/5] drm/msm/dp: replace dp_connector with drm_bridge_connector
@ 2022-02-23 18:45                   ` Dmitry Baryshkov
  0 siblings, 0 replies; 84+ messages in thread
From: Dmitry Baryshkov @ 2022-02-23 18:45 UTC (permalink / raw)
  To: Kuogee Hsieh
  Cc: freedreno, David Airlie, linux-arm-msm, Abhinav Kumar, dri-devel,
	Bjorn Andersson, Stephen Boyd, Sean Paul

On Wed, 23 Feb 2022 at 21:27, Kuogee Hsieh <quic_khsieh@quicinc.com> wrote:
>
>
> On 2/23/2022 10:22 AM, Dmitry Baryshkov wrote:
> > On 23/02/2022 20:21, Kuogee Hsieh wrote:
> >>
> >> On 2/18/2022 6:22 PM, Dmitry Baryshkov wrote:
> >>> On Sat, 19 Feb 2022 at 03:55, Stephen Boyd <swboyd@chromium.org> wrote:
> >>>> Quoting Dmitry Baryshkov (2022-02-18 14:32:53)
> >>>>> On 19/02/2022 00:31, Kuogee Hsieh wrote:
> >>>>>> On 2/11/2022 2:40 PM, Dmitry Baryshkov wrote:
> >>>>>>> There is little point in having both connector and root bridge
> >>>>>>> implementation in the same driver. Move connector's
> >>>>>>> functionality to the
> >>>>>>> bridge to let next bridge in chain to override it.
> >>>>>>>
> >>>>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> >>>>>> This patch break primary (edp) display
> >>>>>>
> >>>>>> -- right half of screen garbled
> >>>>>>
> >>>>>> -- screen shift vertically
> >>>>>>
> >>>>>> below are error messages seen --
> >>>>>>
> >>>>>> [   36.679216] panel-edp soc@0:edp_panel: No display modes
> >>>>>> [   36.687272] panel-edp soc@0:edp_panel: No display modes
> >>>>>> [   40.593709] panel-edp soc@0:edp_panel: No display modes
> >>>>>> [   40.600285] panel-edp soc@0:edp_panel: No display modes
> >>>>> So, before the patch the drm core was getting modes from the
> >>>>> drm_connector (which means, modes from drm driver itself). With this
> >>>>> patch the panel-edp tries to get modes.
> >>>>>
> >>>>> Could you please check, why panel_edp_get_modes() fails? Assuming
> >>>>> that
> >>>>> you use platform panel-edp binding (rather than 'edp-panel') could
> >>>>> you
> >>>>> please check you have either of the following:
> >>>>> - ddc bus for EDID?
> >>>> I don't see anywhere where the ddc pointer is set for the dp bridge in
> >>>> msm_dp_bridge_init(). Is that required though? I'd think simple
> >>>> panel is
> >>>> still being used here so reading EDID isn't required.
> >>> I meant the 'ddc-i2c-bus' property for the corresponding eDP panel.
> >>>
> >>>>> - either num_timing or num_modes in your panel desc.
> >>> After reading the panel-edp's code I don't have another cause for
> >>> panel_edp_get_modes(). It should either have a DDC bus specified using
> >>> the mentioned device tree property, or it should have specified the
> >>> timings.
> >>>
> >>> Kuogee, which platform were you using when testing this patch? Could
> >>> you please share the dts fragment?
> >>
> >> I cherry-picked your patches on top of our internal release which is
> >> usually have some (or many) patches behind msm-next.
> >>
> >> where is "ddc-i2c-bus" located?
> >
> > In the panel device node.
> >
> > Can you please share it too?
>
>
> &soc {
>          edp_power_supply: edp_power {
>                  compatible = "regulator-fixed";
>                  regulator-name = "edp_backlight_power";
>
>                  regulator-always-on;
>                  regulator-boot-on;
>          };
>
>          edp_backlight: edp_backlight {
>                  compatible = "pwm-backlight";
>
>                  pwms = <&pm8350c_pwm 3 65535>;
>                  power-supply = <&edp_power_supply>;
>                  enable-gpio = <&pm8350c_gpios 7 GPIO_ACTIVE_HIGH>;
>
>                  pinctrl-names = "default";
>                  pinctrl-0 = <&backlight_pwm_default>;
>          };
>
>          edp_panel: edp_panel {
>                  compatible = "sharp_lq140m1jw46";

I'd assume that the panel is supported by the patch
https://patchwork.kernel.org/project/linux-arm-msm/patch/1644494255-6632-5-git-send-email-quic_sbillaka@quicinc.com/
and the compatible value is just an old value.
Provided that the panel description defines modes, I'd ask for some
debug from the panel_edp_get_modes(). At least let's see why
panel_edp_get_non_edid_modes() / panel_edp_get_display_modes() returns
no modes.

Regarding the ddc bus, if you have separate i2c bus connected to this
panel, the ddc-i2c-bus = <&i2c_N>; property should go to this device
node.

>                  pinctrl-names = "default";
>                  pinctrl-0 = <&edp_hot_plug_det>,
> <&edp_panel_power_default>;
>
>                  power-supply = <&edp_power_supply>;
>                  backlight = <&edp_backlight>;
>
>                  ports {
>                          #address-cells = <1>;
>                          #size-cells = <0>;
>                          port@0 {
>                                  reg = <0>;
>                                  edp_panel_in: endpoint {
>                                          remote-endpoint = <&edp_out>;
>                                  };
>                          };
>                  };
>          };
> };
>
>
> >
> >>
> >>                          msm_edp: edp@aea0000 {
> >>                                  compatible = "qcom,sc7280-edp";
> >>
> >>                                  reg = <0 0xaea0000 0 0x200>,
> >>                                        <0 0xaea0200 0 0x200>,
> >>                                        <0 0xaea0400 0 0xc00>,
> >>                                        <0 0xaea1000 0 0x400>;
> >>
> >>                                  interrupt-parent = <&mdss>;
> >>                                  interrupts = <14>;
> >>
> >>                                  clocks = <&rpmhcc RPMH_CXO_CLK>,
> >>                                           <&gcc GCC_EDP_CLKREF_EN>,
> >>                                           <&dispcc
> >> DISP_CC_MDSS_AHB_CLK>,
> >>                                           <&dispcc
> >> DISP_CC_MDSS_EDP_AUX_CLK>,
> >>                                           <&dispcc
> >> DISP_CC_MDSS_EDP_LINK_CLK>,
> >>                                           <&dispcc
> >> DISP_CC_MDSS_EDP_LINK_INTF_CLK>,
> >>                                           <&dispcc
> >> DISP_CC_MDSS_EDP_PIXEL_CLK>;
> >>                                  clock-names = "core_xo",
> >>                                                "core_ref",
> >>                                                "core_iface",
> >>                                                "core_aux",
> >>                                                "ctrl_link",
> >> "ctrl_link_iface",
> >>                                                "stream_pixel";
> >>                                  #clock-cells = <1>;
> >>                                  assigned-clocks = <&dispcc
> >> DISP_CC_MDSS_EDP_LINK_CLK_SRC>,
> >> <&dispcc DISP_CC_MDSS_EDP_PIXEL_CLK_SRC>;
> >>                                  assigned-clock-parents = <&edp_phy
> >> 0>, <&edp_phy 1>;
> >>
> >>                                  phys = <&edp_phy>;
> >>                                  phy-names = "dp";
> >>
> >>                                  operating-points-v2 = <&edp_opp_table>;
> >>                                  power-domains = <&rpmhpd SC7280_CX>;
> >>
> >>                                  #address-cells = <1>;
> >>                                  #size-cells = <0>;
> >>
> >>                                  status = "disabled";
> >>
> >>                                  ports {
> >>                                          #address-cells = <1>;
> >>                                          #size-cells = <0>;
> >>                                          port@0 {
> >>                                                  reg = <0>;
> >>                                                  edp_in: endpoint {
> >> remote-endpoint = <&dpu_intf5_out>;
> >>                                                  };
> >>                                          };
> >>                                  };
> >>
> >>                              edp_opp_table: opp-table {
> >>                                          compatible =
> >> "operating-points-v2";
> >>
> >>                                          opp-160000000 {
> >>                                                  opp-hz = /bits/ 64
> >> <160000000>;
> >>                                                  required-opps =
> >> <&rpmhpd_opp_low_svs>;
> >>                                          };
> >>
> >>                                          opp-270000000 {
> >>                                                  opp-hz = /bits/ 64
> >> <270000000>;
> >>                                                  required-opps =
> >> <&rpmhpd_opp_svs>;
> >>                                          };
> >>
> >>                                          opp-540000000 {
> >>                                                  opp-hz = /bits/ 64
> >> <540000000>;
> >>                                                  required-opps =
> >> <&rpmhpd_opp_nom>;
> >>                                          };
> >>
> >>                                          opp-810000000 {
> >>                                                  opp-hz = /bits/ 64
> >> <810000000>;
> >>                                                  required-opps =
> >> <&rpmhpd_opp_nom>;
> >>                                          };
> >>                                  };
> >>                          };
> >>
> >
> >



-- 
With best wishes
Dmitry

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

* Re: [RFC PATCH v2 4/5] drm/msm/dp: replace dp_connector with drm_bridge_connector
  2022-02-23 18:27                 ` Kuogee Hsieh
@ 2022-02-23 21:33                   ` Stephen Boyd
  -1 siblings, 0 replies; 84+ messages in thread
From: Stephen Boyd @ 2022-02-23 21:33 UTC (permalink / raw)
  To: Dmitry Baryshkov, Kuogee Hsieh
  Cc: Abhinav Kumar, Bjorn Andersson, Rob Clark, Sean Paul,
	David Airlie, Daniel Vetter, linux-arm-msm, dri-devel, freedreno

Quoting Kuogee Hsieh (2022-02-23 10:27:26)
>
> On 2/23/2022 10:22 AM, Dmitry Baryshkov wrote:
> > On 23/02/2022 20:21, Kuogee Hsieh wrote:
> >
> > In the panel device node.
> >
> > Can you please share it too?
>
>
> &soc {
>          edp_power_supply: edp_power {
>                  compatible = "regulator-fixed";
>                  regulator-name = "edp_backlight_power";
>
>                  regulator-always-on;
>                  regulator-boot-on;
>          };
>
>          edp_backlight: edp_backlight {
>                  compatible = "pwm-backlight";
>
>                  pwms = <&pm8350c_pwm 3 65535>;
>                  power-supply = <&edp_power_supply>;
>                  enable-gpio = <&pm8350c_gpios 7 GPIO_ACTIVE_HIGH>;
>
>                  pinctrl-names = "default";
>                  pinctrl-0 = <&backlight_pwm_default>;
>          };
>
>          edp_panel: edp_panel {
>                  compatible = "sharp_lq140m1jw46";

Is that supposed to be sharp,lq140m1jw46 with a comma instead of an
underscore?

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

* Re: [RFC PATCH v2 4/5] drm/msm/dp: replace dp_connector with drm_bridge_connector
@ 2022-02-23 21:33                   ` Stephen Boyd
  0 siblings, 0 replies; 84+ messages in thread
From: Stephen Boyd @ 2022-02-23 21:33 UTC (permalink / raw)
  To: Dmitry Baryshkov, Kuogee Hsieh
  Cc: freedreno, David Airlie, linux-arm-msm, Abhinav Kumar, dri-devel,
	Bjorn Andersson, Sean Paul

Quoting Kuogee Hsieh (2022-02-23 10:27:26)
>
> On 2/23/2022 10:22 AM, Dmitry Baryshkov wrote:
> > On 23/02/2022 20:21, Kuogee Hsieh wrote:
> >
> > In the panel device node.
> >
> > Can you please share it too?
>
>
> &soc {
>          edp_power_supply: edp_power {
>                  compatible = "regulator-fixed";
>                  regulator-name = "edp_backlight_power";
>
>                  regulator-always-on;
>                  regulator-boot-on;
>          };
>
>          edp_backlight: edp_backlight {
>                  compatible = "pwm-backlight";
>
>                  pwms = <&pm8350c_pwm 3 65535>;
>                  power-supply = <&edp_power_supply>;
>                  enable-gpio = <&pm8350c_gpios 7 GPIO_ACTIVE_HIGH>;
>
>                  pinctrl-names = "default";
>                  pinctrl-0 = <&backlight_pwm_default>;
>          };
>
>          edp_panel: edp_panel {
>                  compatible = "sharp_lq140m1jw46";

Is that supposed to be sharp,lq140m1jw46 with a comma instead of an
underscore?

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

* Re: [RFC PATCH v2 4/5] drm/msm/dp: replace dp_connector with drm_bridge_connector
  2022-02-23 21:33                   ` Stephen Boyd
@ 2022-02-24  0:40                     ` Kuogee Hsieh
  -1 siblings, 0 replies; 84+ messages in thread
From: Kuogee Hsieh @ 2022-02-24  0:40 UTC (permalink / raw)
  To: Stephen Boyd, Dmitry Baryshkov
  Cc: Abhinav Kumar, Bjorn Andersson, Rob Clark, Sean Paul,
	David Airlie, Daniel Vetter, linux-arm-msm, dri-devel, freedreno


On 2/23/2022 1:33 PM, Stephen Boyd wrote:
> Quoting Kuogee Hsieh (2022-02-23 10:27:26)
>> On 2/23/2022 10:22 AM, Dmitry Baryshkov wrote:
>>> On 23/02/2022 20:21, Kuogee Hsieh wrote:
>>>
>>> In the panel device node.
>>>
>>> Can you please share it too?
>>
>> &soc {
>>           edp_power_supply: edp_power {
>>                   compatible = "regulator-fixed";
>>                   regulator-name = "edp_backlight_power";
>>
>>                   regulator-always-on;
>>                   regulator-boot-on;
>>           };
>>
>>           edp_backlight: edp_backlight {
>>                   compatible = "pwm-backlight";
>>
>>                   pwms = <&pm8350c_pwm 3 65535>;
>>                   power-supply = <&edp_power_supply>;
>>                   enable-gpio = <&pm8350c_gpios 7 GPIO_ACTIVE_HIGH>;
>>
>>                   pinctrl-names = "default";
>>                   pinctrl-0 = <&backlight_pwm_default>;
>>           };
>>
>>           edp_panel: edp_panel {
>>                   compatible = "sharp_lq140m1jw46";
> Is that supposed to be sharp,lq140m1jw46 with a comma instead of an
> underscore?

Stephen,

This is our internal branch which does not have patches up to date yet.

I will cherry-pick newer edp related patches which are under review now 
to re test it.


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

* Re: [RFC PATCH v2 4/5] drm/msm/dp: replace dp_connector with drm_bridge_connector
@ 2022-02-24  0:40                     ` Kuogee Hsieh
  0 siblings, 0 replies; 84+ messages in thread
From: Kuogee Hsieh @ 2022-02-24  0:40 UTC (permalink / raw)
  To: Stephen Boyd, Dmitry Baryshkov
  Cc: freedreno, David Airlie, linux-arm-msm, Abhinav Kumar, dri-devel,
	Bjorn Andersson, Sean Paul


On 2/23/2022 1:33 PM, Stephen Boyd wrote:
> Quoting Kuogee Hsieh (2022-02-23 10:27:26)
>> On 2/23/2022 10:22 AM, Dmitry Baryshkov wrote:
>>> On 23/02/2022 20:21, Kuogee Hsieh wrote:
>>>
>>> In the panel device node.
>>>
>>> Can you please share it too?
>>
>> &soc {
>>           edp_power_supply: edp_power {
>>                   compatible = "regulator-fixed";
>>                   regulator-name = "edp_backlight_power";
>>
>>                   regulator-always-on;
>>                   regulator-boot-on;
>>           };
>>
>>           edp_backlight: edp_backlight {
>>                   compatible = "pwm-backlight";
>>
>>                   pwms = <&pm8350c_pwm 3 65535>;
>>                   power-supply = <&edp_power_supply>;
>>                   enable-gpio = <&pm8350c_gpios 7 GPIO_ACTIVE_HIGH>;
>>
>>                   pinctrl-names = "default";
>>                   pinctrl-0 = <&backlight_pwm_default>;
>>           };
>>
>>           edp_panel: edp_panel {
>>                   compatible = "sharp_lq140m1jw46";
> Is that supposed to be sharp,lq140m1jw46 with a comma instead of an
> underscore?

Stephen,

This is our internal branch which does not have patches up to date yet.

I will cherry-pick newer edp related patches which are under review now 
to re test it.


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

* Re: [Freedreno] [RFC PATCH v2 1/5] drm/msm/dp: fix panel bridge attachment
  2022-02-19  2:26       ` Dmitry Baryshkov
@ 2022-02-24 18:25         ` Abhinav Kumar
  -1 siblings, 0 replies; 84+ messages in thread
From: Abhinav Kumar @ 2022-02-24 18:25 UTC (permalink / raw)
  To: Dmitry Baryshkov, Stephen Boyd, Bjorn Andersson, Kuogee Hsieh,
	Rob Clark, Sean Paul
  Cc: David Airlie, linux-arm-msm, freedreno, dri-devel, Daniel Vetter



On 2/18/2022 6:26 PM, Dmitry Baryshkov wrote:
> On 19/02/2022 02:56, Stephen Boyd wrote:
>> Quoting Dmitry Baryshkov (2022-02-11 14:40:02)
>>> In commit 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
>>> enable and disable") the DP driver received a drm_bridge instance, which
>>> is always attached to the encoder as a root bridge. However it conflicts
>>> with the panel_bridge support for eDP panels. The panel bridge attaches
>>> to the encoder before the "dp" bridge has a chace to do so. Change
>>
>> s/chace/chance/
>>
>>> panel_bridge attachment to come after dp_bridge attachment.
>>
>> s/panel_bridge/panel bridge/ possibly? And maybe clarify that dp_bridge
>> is the "DP driver's drm_bridge instance created in
>> msm_dp_bridge_init()"?
>>
>> My understanding is that we want to pass the bridge created in
>> msm_dp_bridge_init() as the 'previous' bridge so that it attaches the
>> panel bridge to the output of the DP bridge that's attached to the
>> encoder.
> 
> Thanks! I'll update the commit log when pushing the patches.

Please correct if i am missing something here.

You are right that the eDP panel's panel bridge attaches to the encoder 
in dp_drm_connector_init() which happens before msm_dp_bridge_init() and 
hence it will attach directly to the encoder.

But we are talking about different encoders here. DP's dp_display has a 
different encoder compared to the EDP's dp_display.

So DP's bridge will still be attached to its encoder's root.

So what are we achieving with this change?

> 
>>
>>>
>>> Fixes: 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display 
>>> enable and disable")
>>> Cc: Kuogee Hsieh <quic_khsieh@quicinc.com>
>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>> ---
>>
>> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
>>
>>>   drivers/gpu/drm/msm/dp/dp_drm.c | 21 +++++++++++----------
>>>   1 file changed, 11 insertions(+), 10 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c 
>>> b/drivers/gpu/drm/msm/dp/dp_drm.c
>>> index d4d360d19eba..26ef41a4c1b6 100644
>>> --- a/drivers/gpu/drm/msm/dp/dp_drm.c
>>> +++ b/drivers/gpu/drm/msm/dp/dp_drm.c
>>> @@ -169,16 +169,6 @@ struct drm_connector 
>>> *dp_drm_connector_init(struct msm_dp *dp_display)
>>>
>>>          drm_connector_attach_encoder(connector, dp_display->encoder);
>>>
>>> -       if (dp_display->panel_bridge) {
>>> -               ret = drm_bridge_attach(dp_display->encoder,
>>> -                                       dp_display->panel_bridge, NULL,
>>> -                                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>>> -               if (ret < 0) {
>>> -                       DRM_ERROR("failed to attach panel bridge: 
>>> %d\n", ret);
>>> -                       return ERR_PTR(ret);
>>> -               }
>>> -       }
>>> -
>>>          return connector;
>>>   }
>>>
>>> @@ -246,5 +236,16 @@ struct drm_bridge *msm_dp_bridge_init(struct 
>>> msm_dp *dp_display, struct drm_devi
>>>                  return ERR_PTR(rc);
>>>          }
>>>
>>> +       if (dp_display->panel_bridge) {
>>> +               rc = drm_bridge_attach(dp_display->encoder,
>>> +                                       dp_display->panel_bridge, 
>>> bridge,
>>> +                                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>>> +               if (rc < 0) {
>>> +                       DRM_ERROR("failed to attach panel bridge: 
>>> %d\n", rc);
>>> +                       drm_bridge_remove(bridge);
>>> +                       return ERR_PTR(rc);
>>> +               }
>>> +       }
>>> +
>>>          return bridge;
>>
>> Not a problem with this patch, but what is this pointer used for? I see
>> it's assigned to priv->bridges and num_bridges is incremented but nobody
>> seems to look at that.
> 
> 
> That's on my todo list. to remove connectors array and to destroy 
> created bridges during drm device destruction.
> 

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

* Re: [Freedreno] [RFC PATCH v2 1/5] drm/msm/dp: fix panel bridge attachment
@ 2022-02-24 18:25         ` Abhinav Kumar
  0 siblings, 0 replies; 84+ messages in thread
From: Abhinav Kumar @ 2022-02-24 18:25 UTC (permalink / raw)
  To: Dmitry Baryshkov, Stephen Boyd, Bjorn Andersson, Kuogee Hsieh,
	Rob Clark, Sean Paul
  Cc: David Airlie, linux-arm-msm, freedreno, dri-devel



On 2/18/2022 6:26 PM, Dmitry Baryshkov wrote:
> On 19/02/2022 02:56, Stephen Boyd wrote:
>> Quoting Dmitry Baryshkov (2022-02-11 14:40:02)
>>> In commit 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
>>> enable and disable") the DP driver received a drm_bridge instance, which
>>> is always attached to the encoder as a root bridge. However it conflicts
>>> with the panel_bridge support for eDP panels. The panel bridge attaches
>>> to the encoder before the "dp" bridge has a chace to do so. Change
>>
>> s/chace/chance/
>>
>>> panel_bridge attachment to come after dp_bridge attachment.
>>
>> s/panel_bridge/panel bridge/ possibly? And maybe clarify that dp_bridge
>> is the "DP driver's drm_bridge instance created in
>> msm_dp_bridge_init()"?
>>
>> My understanding is that we want to pass the bridge created in
>> msm_dp_bridge_init() as the 'previous' bridge so that it attaches the
>> panel bridge to the output of the DP bridge that's attached to the
>> encoder.
> 
> Thanks! I'll update the commit log when pushing the patches.

Please correct if i am missing something here.

You are right that the eDP panel's panel bridge attaches to the encoder 
in dp_drm_connector_init() which happens before msm_dp_bridge_init() and 
hence it will attach directly to the encoder.

But we are talking about different encoders here. DP's dp_display has a 
different encoder compared to the EDP's dp_display.

So DP's bridge will still be attached to its encoder's root.

So what are we achieving with this change?

> 
>>
>>>
>>> Fixes: 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display 
>>> enable and disable")
>>> Cc: Kuogee Hsieh <quic_khsieh@quicinc.com>
>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>> ---
>>
>> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
>>
>>>   drivers/gpu/drm/msm/dp/dp_drm.c | 21 +++++++++++----------
>>>   1 file changed, 11 insertions(+), 10 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c 
>>> b/drivers/gpu/drm/msm/dp/dp_drm.c
>>> index d4d360d19eba..26ef41a4c1b6 100644
>>> --- a/drivers/gpu/drm/msm/dp/dp_drm.c
>>> +++ b/drivers/gpu/drm/msm/dp/dp_drm.c
>>> @@ -169,16 +169,6 @@ struct drm_connector 
>>> *dp_drm_connector_init(struct msm_dp *dp_display)
>>>
>>>          drm_connector_attach_encoder(connector, dp_display->encoder);
>>>
>>> -       if (dp_display->panel_bridge) {
>>> -               ret = drm_bridge_attach(dp_display->encoder,
>>> -                                       dp_display->panel_bridge, NULL,
>>> -                                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>>> -               if (ret < 0) {
>>> -                       DRM_ERROR("failed to attach panel bridge: 
>>> %d\n", ret);
>>> -                       return ERR_PTR(ret);
>>> -               }
>>> -       }
>>> -
>>>          return connector;
>>>   }
>>>
>>> @@ -246,5 +236,16 @@ struct drm_bridge *msm_dp_bridge_init(struct 
>>> msm_dp *dp_display, struct drm_devi
>>>                  return ERR_PTR(rc);
>>>          }
>>>
>>> +       if (dp_display->panel_bridge) {
>>> +               rc = drm_bridge_attach(dp_display->encoder,
>>> +                                       dp_display->panel_bridge, 
>>> bridge,
>>> +                                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>>> +               if (rc < 0) {
>>> +                       DRM_ERROR("failed to attach panel bridge: 
>>> %d\n", rc);
>>> +                       drm_bridge_remove(bridge);
>>> +                       return ERR_PTR(rc);
>>> +               }
>>> +       }
>>> +
>>>          return bridge;
>>
>> Not a problem with this patch, but what is this pointer used for? I see
>> it's assigned to priv->bridges and num_bridges is incremented but nobody
>> seems to look at that.
> 
> 
> That's on my todo list. to remove connectors array and to destroy 
> created bridges during drm device destruction.
> 

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

* Re: [RFC PATCH v2 2/5] drm/msm/dp: support attaching bridges to the DP encoder
  2022-02-11 22:40   ` Dmitry Baryshkov
@ 2022-02-24 19:56     ` Abhinav Kumar
  -1 siblings, 0 replies; 84+ messages in thread
From: Abhinav Kumar @ 2022-02-24 19:56 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Clark, Sean Paul, Kuogee Hsieh
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno



On 2/11/2022 2:40 PM, Dmitry Baryshkov wrote:
> Currently DP driver will allocate panel bridge for eDP panels. This
> supports only the following topology:
> 
> - eDP encoder ⇒ eDP panel (wrapped using panel-bridge)
> 
> Simplify this code to just check if there is any next bridge in the
> chain (be it a panel bridge or regular bridge). Rename panel_bridge
> field to next_bridge accordingly.
> 
> This allows one to use e.g. one of the following display topologies:
> 
> - eDP encoder ⇒ ptn3460 ⇒ fixed LVDS panel
> - eDP encoder ⇒ ptn3460 ⇒ LVDS connector with EDID lines for panel autodetect
> - eDP encoder ⇒ ptn3460 ⇒ THC63LVD1024 ⇒ DPI panel.
> - eDP encoder ⇒ LT8912 ⇒ DSI panel
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>

> ---
>   drivers/gpu/drm/msm/dp/dp_display.c |  2 +-
>   drivers/gpu/drm/msm/dp/dp_display.h |  2 +-
>   drivers/gpu/drm/msm/dp/dp_drm.c     |  4 ++--
>   drivers/gpu/drm/msm/dp/dp_parser.c  | 31 +++++++++++++++--------------
>   drivers/gpu/drm/msm/dp/dp_parser.h  |  2 +-
>   5 files changed, 21 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
> index 44d42c76c2a3..45f9a912ecc5 100644
> --- a/drivers/gpu/drm/msm/dp/dp_display.c
> +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> @@ -266,7 +266,7 @@ static int dp_display_bind(struct device *dev, struct device *master,
>   		goto end;
>   	}
>   
> -	dp->dp_display.panel_bridge = dp->parser->panel_bridge;
> +	dp->dp_display.next_bridge = dp->parser->next_bridge;
>   
>   	dp->aux->drm_dev = drm;
>   	rc = dp_aux_register(dp->aux);
> diff --git a/drivers/gpu/drm/msm/dp/dp_display.h b/drivers/gpu/drm/msm/dp/dp_display.h
> index e3adcd578a90..7af2b186d2d9 100644
> --- a/drivers/gpu/drm/msm/dp/dp_display.h
> +++ b/drivers/gpu/drm/msm/dp/dp_display.h
> @@ -16,7 +16,7 @@ struct msm_dp {
>   	struct drm_bridge *bridge;
>   	struct drm_connector *connector;
>   	struct drm_encoder *encoder;
> -	struct drm_bridge *panel_bridge;
> +	struct drm_bridge *next_bridge;
>   	bool is_connected;
>   	bool audio_enabled;
>   	bool power_on;
> diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
> index 26ef41a4c1b6..80f59cf99089 100644
> --- a/drivers/gpu/drm/msm/dp/dp_drm.c
> +++ b/drivers/gpu/drm/msm/dp/dp_drm.c
> @@ -236,9 +236,9 @@ struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display, struct drm_devi
>   		return ERR_PTR(rc);
>   	}
>   
> -	if (dp_display->panel_bridge) {
> +	if (dp_display->next_bridge) {
>   		rc = drm_bridge_attach(dp_display->encoder,
> -					dp_display->panel_bridge, bridge,
> +					dp_display->next_bridge, bridge,
>   					DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>   		if (rc < 0) {
>   			DRM_ERROR("failed to attach panel bridge: %d\n", rc);
> diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c b/drivers/gpu/drm/msm/dp/dp_parser.c
> index a7acc23f742b..901d7967370f 100644
> --- a/drivers/gpu/drm/msm/dp/dp_parser.c
> +++ b/drivers/gpu/drm/msm/dp/dp_parser.c
> @@ -265,23 +265,16 @@ static int dp_parser_clock(struct dp_parser *parser)
>   	return 0;
>   }
>   
> -static int dp_parser_find_panel(struct dp_parser *parser)
> +static int dp_parser_find_next_bridge(struct dp_parser *parser)
>   {
>   	struct device *dev = &parser->pdev->dev;
> -	struct drm_panel *panel;
> -	int rc;
> +	struct drm_bridge *bridge;
>   
> -	rc = drm_of_find_panel_or_bridge(dev->of_node, 1, 0, &panel, NULL);
> -	if (rc) {
> -		DRM_ERROR("failed to acquire DRM panel: %d\n", rc);
> -		return rc;
> -	}
> +	bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0);
> +	if (IS_ERR(bridge))
> +		return PTR_ERR(bridge);
>   
> -	parser->panel_bridge = devm_drm_panel_bridge_add(dev, panel);
> -	if (IS_ERR(parser->panel_bridge)) {
> -		DRM_ERROR("failed to create panel bridge\n");
> -		return PTR_ERR(parser->panel_bridge);
> -	}
> +	parser->next_bridge = bridge;
>   
>   	return 0;
>   }
> @@ -307,10 +300,18 @@ static int dp_parser_parse(struct dp_parser *parser, int connector_type)
>   	if (rc)
>   		return rc;
>   
> +	/*
> +	 * Currently we support external bridges only for eDP connectors.
> +	 *
> +	 * No external bridges are expected for the DisplayPort connector,
> +	 * it is physically present in a form of a DP or USB-C connector.
> +	 */
>   	if (connector_type == DRM_MODE_CONNECTOR_eDP) {
> -		rc = dp_parser_find_panel(parser);
> -		if (rc)
> +		rc = dp_parser_find_next_bridge(parser);
> +		if (rc) {
> +			DRM_ERROR("DP: failed to find next bridge\n");
>   			return rc;
> +		}
>   	}
>   
>   	/* Map the corresponding regulator information according to
> diff --git a/drivers/gpu/drm/msm/dp/dp_parser.h b/drivers/gpu/drm/msm/dp/dp_parser.h
> index 3172da089421..4cec851e38d9 100644
> --- a/drivers/gpu/drm/msm/dp/dp_parser.h
> +++ b/drivers/gpu/drm/msm/dp/dp_parser.h
> @@ -123,7 +123,7 @@ struct dp_parser {
>   	struct dp_display_data disp_data;
>   	const struct dp_regulator_cfg *regulator_cfg;
>   	u32 max_dp_lanes;
> -	struct drm_bridge *panel_bridge;
> +	struct drm_bridge *next_bridge;
>   
>   	int (*parse)(struct dp_parser *parser, int connector_type);
>   };

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

* Re: [RFC PATCH v2 2/5] drm/msm/dp: support attaching bridges to the DP encoder
@ 2022-02-24 19:56     ` Abhinav Kumar
  0 siblings, 0 replies; 84+ messages in thread
From: Abhinav Kumar @ 2022-02-24 19:56 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Clark, Sean Paul, Kuogee Hsieh
  Cc: David Airlie, linux-arm-msm, dri-devel, Stephen Boyd, freedreno



On 2/11/2022 2:40 PM, Dmitry Baryshkov wrote:
> Currently DP driver will allocate panel bridge for eDP panels. This
> supports only the following topology:
> 
> - eDP encoder ⇒ eDP panel (wrapped using panel-bridge)
> 
> Simplify this code to just check if there is any next bridge in the
> chain (be it a panel bridge or regular bridge). Rename panel_bridge
> field to next_bridge accordingly.
> 
> This allows one to use e.g. one of the following display topologies:
> 
> - eDP encoder ⇒ ptn3460 ⇒ fixed LVDS panel
> - eDP encoder ⇒ ptn3460 ⇒ LVDS connector with EDID lines for panel autodetect
> - eDP encoder ⇒ ptn3460 ⇒ THC63LVD1024 ⇒ DPI panel.
> - eDP encoder ⇒ LT8912 ⇒ DSI panel
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>

> ---
>   drivers/gpu/drm/msm/dp/dp_display.c |  2 +-
>   drivers/gpu/drm/msm/dp/dp_display.h |  2 +-
>   drivers/gpu/drm/msm/dp/dp_drm.c     |  4 ++--
>   drivers/gpu/drm/msm/dp/dp_parser.c  | 31 +++++++++++++++--------------
>   drivers/gpu/drm/msm/dp/dp_parser.h  |  2 +-
>   5 files changed, 21 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
> index 44d42c76c2a3..45f9a912ecc5 100644
> --- a/drivers/gpu/drm/msm/dp/dp_display.c
> +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> @@ -266,7 +266,7 @@ static int dp_display_bind(struct device *dev, struct device *master,
>   		goto end;
>   	}
>   
> -	dp->dp_display.panel_bridge = dp->parser->panel_bridge;
> +	dp->dp_display.next_bridge = dp->parser->next_bridge;
>   
>   	dp->aux->drm_dev = drm;
>   	rc = dp_aux_register(dp->aux);
> diff --git a/drivers/gpu/drm/msm/dp/dp_display.h b/drivers/gpu/drm/msm/dp/dp_display.h
> index e3adcd578a90..7af2b186d2d9 100644
> --- a/drivers/gpu/drm/msm/dp/dp_display.h
> +++ b/drivers/gpu/drm/msm/dp/dp_display.h
> @@ -16,7 +16,7 @@ struct msm_dp {
>   	struct drm_bridge *bridge;
>   	struct drm_connector *connector;
>   	struct drm_encoder *encoder;
> -	struct drm_bridge *panel_bridge;
> +	struct drm_bridge *next_bridge;
>   	bool is_connected;
>   	bool audio_enabled;
>   	bool power_on;
> diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
> index 26ef41a4c1b6..80f59cf99089 100644
> --- a/drivers/gpu/drm/msm/dp/dp_drm.c
> +++ b/drivers/gpu/drm/msm/dp/dp_drm.c
> @@ -236,9 +236,9 @@ struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display, struct drm_devi
>   		return ERR_PTR(rc);
>   	}
>   
> -	if (dp_display->panel_bridge) {
> +	if (dp_display->next_bridge) {
>   		rc = drm_bridge_attach(dp_display->encoder,
> -					dp_display->panel_bridge, bridge,
> +					dp_display->next_bridge, bridge,
>   					DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>   		if (rc < 0) {
>   			DRM_ERROR("failed to attach panel bridge: %d\n", rc);
> diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c b/drivers/gpu/drm/msm/dp/dp_parser.c
> index a7acc23f742b..901d7967370f 100644
> --- a/drivers/gpu/drm/msm/dp/dp_parser.c
> +++ b/drivers/gpu/drm/msm/dp/dp_parser.c
> @@ -265,23 +265,16 @@ static int dp_parser_clock(struct dp_parser *parser)
>   	return 0;
>   }
>   
> -static int dp_parser_find_panel(struct dp_parser *parser)
> +static int dp_parser_find_next_bridge(struct dp_parser *parser)
>   {
>   	struct device *dev = &parser->pdev->dev;
> -	struct drm_panel *panel;
> -	int rc;
> +	struct drm_bridge *bridge;
>   
> -	rc = drm_of_find_panel_or_bridge(dev->of_node, 1, 0, &panel, NULL);
> -	if (rc) {
> -		DRM_ERROR("failed to acquire DRM panel: %d\n", rc);
> -		return rc;
> -	}
> +	bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0);
> +	if (IS_ERR(bridge))
> +		return PTR_ERR(bridge);
>   
> -	parser->panel_bridge = devm_drm_panel_bridge_add(dev, panel);
> -	if (IS_ERR(parser->panel_bridge)) {
> -		DRM_ERROR("failed to create panel bridge\n");
> -		return PTR_ERR(parser->panel_bridge);
> -	}
> +	parser->next_bridge = bridge;
>   
>   	return 0;
>   }
> @@ -307,10 +300,18 @@ static int dp_parser_parse(struct dp_parser *parser, int connector_type)
>   	if (rc)
>   		return rc;
>   
> +	/*
> +	 * Currently we support external bridges only for eDP connectors.
> +	 *
> +	 * No external bridges are expected for the DisplayPort connector,
> +	 * it is physically present in a form of a DP or USB-C connector.
> +	 */
>   	if (connector_type == DRM_MODE_CONNECTOR_eDP) {
> -		rc = dp_parser_find_panel(parser);
> -		if (rc)
> +		rc = dp_parser_find_next_bridge(parser);
> +		if (rc) {
> +			DRM_ERROR("DP: failed to find next bridge\n");
>   			return rc;
> +		}
>   	}
>   
>   	/* Map the corresponding regulator information according to
> diff --git a/drivers/gpu/drm/msm/dp/dp_parser.h b/drivers/gpu/drm/msm/dp/dp_parser.h
> index 3172da089421..4cec851e38d9 100644
> --- a/drivers/gpu/drm/msm/dp/dp_parser.h
> +++ b/drivers/gpu/drm/msm/dp/dp_parser.h
> @@ -123,7 +123,7 @@ struct dp_parser {
>   	struct dp_display_data disp_data;
>   	const struct dp_regulator_cfg *regulator_cfg;
>   	u32 max_dp_lanes;
> -	struct drm_bridge *panel_bridge;
> +	struct drm_bridge *next_bridge;
>   
>   	int (*parse)(struct dp_parser *parser, int connector_type);
>   };

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

* Re: [RFC PATCH v2 3/5] drm/msm/dp: support finding next bridge even for DP interfaces
  2022-02-11 22:40   ` Dmitry Baryshkov
@ 2022-02-24 20:13     ` Abhinav Kumar
  -1 siblings, 0 replies; 84+ messages in thread
From: Abhinav Kumar @ 2022-02-24 20:13 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Clark, Sean Paul, Kuogee Hsieh
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno



On 2/11/2022 2:40 PM, Dmitry Baryshkov wrote:
> It is possible to supply display-connector (bridge) to the DP interface,
> add support for parsing it too.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>   drivers/gpu/drm/msm/dp/dp_parser.c | 19 ++++++++++++-------
>   1 file changed, 12 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c b/drivers/gpu/drm/msm/dp/dp_parser.c
> index 901d7967370f..1056b8d5755b 100644
> --- a/drivers/gpu/drm/msm/dp/dp_parser.c
> +++ b/drivers/gpu/drm/msm/dp/dp_parser.c
> @@ -301,17 +301,22 @@ static int dp_parser_parse(struct dp_parser *parser, int connector_type)
>   		return rc;
>   
>   	/*
> -	 * Currently we support external bridges only for eDP connectors.
> +	 * External bridges are mandatory for eDP interfaces: one has to
> +	 * provide at least an eDP panel (which gets wrapped into panel-bridge).
>   	 *
> -	 * No external bridges are expected for the DisplayPort connector,
> -	 * it is physically present in a form of a DP or USB-C connector.
> +	 * For DisplayPort interfaces external bridges are optional, so
> +	 * silently ignore an error if one is not present (-ENODEV).
>   	 */
> -	if (connector_type == DRM_MODE_CONNECTOR_eDP) {
> -		rc = dp_parser_find_next_bridge(parser);
> -		if (rc) {
> -			DRM_ERROR("DP: failed to find next bridge\n");
> +	rc = dp_parser_find_next_bridge(parser);
> +	if (rc == -ENODEV) {
> +		if (connector_type == DRM_MODE_CONNECTOR_eDP) {
> +			DRM_ERROR("eDP: next bridge is not present\n");
>   			return rc;
>   		}
> +	} else if (rc) {
> +		if (rc != -EPROBE_DEFER)
> +			DRM_ERROR("DP: error parsing next bridge: %d\n", rc);
> +		return rc;
>   	}

How is this silently ignoring?

static int dp_display_bind(struct device *dev, struct device *master,
                void *data)
{
     int rc = 0;
     struct dp_display_private *dp = dev_get_dp_display_private(dev);
     struct msm_drm_private *priv = dev_get_drvdata(master);
     struct drm_device *drm = priv->dev;

     dp->dp_display.drm_dev = drm;
     priv->dp[dp->id] = &dp->dp_display;

     rc = dp->parser->parse(dp->parser, dp->dp_display.connector_type);
     if (rc) {
         DRM_ERROR("device tree parsing failed\n");
         goto end;
     }

dp_display_bind will still fail if a bridge is not found.

If supplying a bridge is optional even this should succeed right?

>   
>   	/* Map the corresponding regulator information according to

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

* Re: [RFC PATCH v2 3/5] drm/msm/dp: support finding next bridge even for DP interfaces
@ 2022-02-24 20:13     ` Abhinav Kumar
  0 siblings, 0 replies; 84+ messages in thread
From: Abhinav Kumar @ 2022-02-24 20:13 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Clark, Sean Paul, Kuogee Hsieh
  Cc: David Airlie, linux-arm-msm, dri-devel, Stephen Boyd, freedreno



On 2/11/2022 2:40 PM, Dmitry Baryshkov wrote:
> It is possible to supply display-connector (bridge) to the DP interface,
> add support for parsing it too.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>   drivers/gpu/drm/msm/dp/dp_parser.c | 19 ++++++++++++-------
>   1 file changed, 12 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c b/drivers/gpu/drm/msm/dp/dp_parser.c
> index 901d7967370f..1056b8d5755b 100644
> --- a/drivers/gpu/drm/msm/dp/dp_parser.c
> +++ b/drivers/gpu/drm/msm/dp/dp_parser.c
> @@ -301,17 +301,22 @@ static int dp_parser_parse(struct dp_parser *parser, int connector_type)
>   		return rc;
>   
>   	/*
> -	 * Currently we support external bridges only for eDP connectors.
> +	 * External bridges are mandatory for eDP interfaces: one has to
> +	 * provide at least an eDP panel (which gets wrapped into panel-bridge).
>   	 *
> -	 * No external bridges are expected for the DisplayPort connector,
> -	 * it is physically present in a form of a DP or USB-C connector.
> +	 * For DisplayPort interfaces external bridges are optional, so
> +	 * silently ignore an error if one is not present (-ENODEV).
>   	 */
> -	if (connector_type == DRM_MODE_CONNECTOR_eDP) {
> -		rc = dp_parser_find_next_bridge(parser);
> -		if (rc) {
> -			DRM_ERROR("DP: failed to find next bridge\n");
> +	rc = dp_parser_find_next_bridge(parser);
> +	if (rc == -ENODEV) {
> +		if (connector_type == DRM_MODE_CONNECTOR_eDP) {
> +			DRM_ERROR("eDP: next bridge is not present\n");
>   			return rc;
>   		}
> +	} else if (rc) {
> +		if (rc != -EPROBE_DEFER)
> +			DRM_ERROR("DP: error parsing next bridge: %d\n", rc);
> +		return rc;
>   	}

How is this silently ignoring?

static int dp_display_bind(struct device *dev, struct device *master,
                void *data)
{
     int rc = 0;
     struct dp_display_private *dp = dev_get_dp_display_private(dev);
     struct msm_drm_private *priv = dev_get_drvdata(master);
     struct drm_device *drm = priv->dev;

     dp->dp_display.drm_dev = drm;
     priv->dp[dp->id] = &dp->dp_display;

     rc = dp->parser->parse(dp->parser, dp->dp_display.connector_type);
     if (rc) {
         DRM_ERROR("device tree parsing failed\n");
         goto end;
     }

dp_display_bind will still fail if a bridge is not found.

If supplying a bridge is optional even this should succeed right?

>   
>   	/* Map the corresponding regulator information according to

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

* Re: [Freedreno] [RFC PATCH v2 1/5] drm/msm/dp: fix panel bridge attachment
  2022-02-24 18:25         ` Abhinav Kumar
@ 2022-02-24 20:41           ` Dmitry Baryshkov
  -1 siblings, 0 replies; 84+ messages in thread
From: Dmitry Baryshkov @ 2022-02-24 20:41 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: Stephen Boyd, Bjorn Andersson, Kuogee Hsieh, Rob Clark,
	Sean Paul, David Airlie, linux-arm-msm, freedreno, dri-devel,
	Daniel Vetter

On Thu, 24 Feb 2022 at 21:25, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>
>
>
> On 2/18/2022 6:26 PM, Dmitry Baryshkov wrote:
> > On 19/02/2022 02:56, Stephen Boyd wrote:
> >> Quoting Dmitry Baryshkov (2022-02-11 14:40:02)
> >>> In commit 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
> >>> enable and disable") the DP driver received a drm_bridge instance, which
> >>> is always attached to the encoder as a root bridge. However it conflicts
> >>> with the panel_bridge support for eDP panels. The panel bridge attaches
> >>> to the encoder before the "dp" bridge has a chace to do so. Change
> >>
> >> s/chace/chance/
> >>
> >>> panel_bridge attachment to come after dp_bridge attachment.
> >>
> >> s/panel_bridge/panel bridge/ possibly? And maybe clarify that dp_bridge
> >> is the "DP driver's drm_bridge instance created in
> >> msm_dp_bridge_init()"?
> >>
> >> My understanding is that we want to pass the bridge created in
> >> msm_dp_bridge_init() as the 'previous' bridge so that it attaches the
> >> panel bridge to the output of the DP bridge that's attached to the
> >> encoder.
> >
> > Thanks! I'll update the commit log when pushing the patches.
>
> Please correct if i am missing something here.
>
> You are right that the eDP panel's panel bridge attaches to the encoder
> in dp_drm_connector_init() which happens before msm_dp_bridge_init() and
> hence it will attach directly to the encoder.
>
> But we are talking about different encoders here. DP's dp_display has a
> different encoder compared to the EDP's dp_display.

The encoders are different. However both encoders use the same
codepath, which includes dp_bridge. It controls dp_display by calling
msm_dp_display_foo() functions.

> So DP's bridge will still be attached to its encoder's root.

There is one dp_bridge per each encoder. Consider sc8180x which has 3
DP controllers (and thus 3 dp_bridges).

>
> So what are we achieving with this change?
>
> >
> >>
> >>>
> >>> Fixes: 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
> >>> enable and disable")
> >>> Cc: Kuogee Hsieh <quic_khsieh@quicinc.com>
> >>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> >>> ---
> >>
> >> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
> >>
> >>>   drivers/gpu/drm/msm/dp/dp_drm.c | 21 +++++++++++----------
> >>>   1 file changed, 11 insertions(+), 10 deletions(-)
> >>>
> >>> diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c
> >>> b/drivers/gpu/drm/msm/dp/dp_drm.c
> >>> index d4d360d19eba..26ef41a4c1b6 100644
> >>> --- a/drivers/gpu/drm/msm/dp/dp_drm.c
> >>> +++ b/drivers/gpu/drm/msm/dp/dp_drm.c
> >>> @@ -169,16 +169,6 @@ struct drm_connector
> >>> *dp_drm_connector_init(struct msm_dp *dp_display)
> >>>
> >>>          drm_connector_attach_encoder(connector, dp_display->encoder);
> >>>
> >>> -       if (dp_display->panel_bridge) {
> >>> -               ret = drm_bridge_attach(dp_display->encoder,
> >>> -                                       dp_display->panel_bridge, NULL,
> >>> -                                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> >>> -               if (ret < 0) {
> >>> -                       DRM_ERROR("failed to attach panel bridge:
> >>> %d\n", ret);
> >>> -                       return ERR_PTR(ret);
> >>> -               }
> >>> -       }
> >>> -
> >>>          return connector;
> >>>   }
> >>>
> >>> @@ -246,5 +236,16 @@ struct drm_bridge *msm_dp_bridge_init(struct
> >>> msm_dp *dp_display, struct drm_devi
> >>>                  return ERR_PTR(rc);
> >>>          }
> >>>
> >>> +       if (dp_display->panel_bridge) {
> >>> +               rc = drm_bridge_attach(dp_display->encoder,
> >>> +                                       dp_display->panel_bridge,
> >>> bridge,
> >>> +                                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> >>> +               if (rc < 0) {
> >>> +                       DRM_ERROR("failed to attach panel bridge:
> >>> %d\n", rc);
> >>> +                       drm_bridge_remove(bridge);
> >>> +                       return ERR_PTR(rc);
> >>> +               }
> >>> +       }
> >>> +
> >>>          return bridge;
> >>
> >> Not a problem with this patch, but what is this pointer used for? I see
> >> it's assigned to priv->bridges and num_bridges is incremented but nobody
> >> seems to look at that.
> >
> >
> > That's on my todo list. to remove connectors array and to destroy
> > created bridges during drm device destruction.
> >



-- 
With best wishes
Dmitry

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

* Re: [Freedreno] [RFC PATCH v2 1/5] drm/msm/dp: fix panel bridge attachment
@ 2022-02-24 20:41           ` Dmitry Baryshkov
  0 siblings, 0 replies; 84+ messages in thread
From: Dmitry Baryshkov @ 2022-02-24 20:41 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: freedreno, David Airlie, linux-arm-msm, Stephen Boyd, dri-devel,
	Kuogee Hsieh, Bjorn Andersson, Sean Paul

On Thu, 24 Feb 2022 at 21:25, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>
>
>
> On 2/18/2022 6:26 PM, Dmitry Baryshkov wrote:
> > On 19/02/2022 02:56, Stephen Boyd wrote:
> >> Quoting Dmitry Baryshkov (2022-02-11 14:40:02)
> >>> In commit 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
> >>> enable and disable") the DP driver received a drm_bridge instance, which
> >>> is always attached to the encoder as a root bridge. However it conflicts
> >>> with the panel_bridge support for eDP panels. The panel bridge attaches
> >>> to the encoder before the "dp" bridge has a chace to do so. Change
> >>
> >> s/chace/chance/
> >>
> >>> panel_bridge attachment to come after dp_bridge attachment.
> >>
> >> s/panel_bridge/panel bridge/ possibly? And maybe clarify that dp_bridge
> >> is the "DP driver's drm_bridge instance created in
> >> msm_dp_bridge_init()"?
> >>
> >> My understanding is that we want to pass the bridge created in
> >> msm_dp_bridge_init() as the 'previous' bridge so that it attaches the
> >> panel bridge to the output of the DP bridge that's attached to the
> >> encoder.
> >
> > Thanks! I'll update the commit log when pushing the patches.
>
> Please correct if i am missing something here.
>
> You are right that the eDP panel's panel bridge attaches to the encoder
> in dp_drm_connector_init() which happens before msm_dp_bridge_init() and
> hence it will attach directly to the encoder.
>
> But we are talking about different encoders here. DP's dp_display has a
> different encoder compared to the EDP's dp_display.

The encoders are different. However both encoders use the same
codepath, which includes dp_bridge. It controls dp_display by calling
msm_dp_display_foo() functions.

> So DP's bridge will still be attached to its encoder's root.

There is one dp_bridge per each encoder. Consider sc8180x which has 3
DP controllers (and thus 3 dp_bridges).

>
> So what are we achieving with this change?
>
> >
> >>
> >>>
> >>> Fixes: 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
> >>> enable and disable")
> >>> Cc: Kuogee Hsieh <quic_khsieh@quicinc.com>
> >>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> >>> ---
> >>
> >> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
> >>
> >>>   drivers/gpu/drm/msm/dp/dp_drm.c | 21 +++++++++++----------
> >>>   1 file changed, 11 insertions(+), 10 deletions(-)
> >>>
> >>> diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c
> >>> b/drivers/gpu/drm/msm/dp/dp_drm.c
> >>> index d4d360d19eba..26ef41a4c1b6 100644
> >>> --- a/drivers/gpu/drm/msm/dp/dp_drm.c
> >>> +++ b/drivers/gpu/drm/msm/dp/dp_drm.c
> >>> @@ -169,16 +169,6 @@ struct drm_connector
> >>> *dp_drm_connector_init(struct msm_dp *dp_display)
> >>>
> >>>          drm_connector_attach_encoder(connector, dp_display->encoder);
> >>>
> >>> -       if (dp_display->panel_bridge) {
> >>> -               ret = drm_bridge_attach(dp_display->encoder,
> >>> -                                       dp_display->panel_bridge, NULL,
> >>> -                                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> >>> -               if (ret < 0) {
> >>> -                       DRM_ERROR("failed to attach panel bridge:
> >>> %d\n", ret);
> >>> -                       return ERR_PTR(ret);
> >>> -               }
> >>> -       }
> >>> -
> >>>          return connector;
> >>>   }
> >>>
> >>> @@ -246,5 +236,16 @@ struct drm_bridge *msm_dp_bridge_init(struct
> >>> msm_dp *dp_display, struct drm_devi
> >>>                  return ERR_PTR(rc);
> >>>          }
> >>>
> >>> +       if (dp_display->panel_bridge) {
> >>> +               rc = drm_bridge_attach(dp_display->encoder,
> >>> +                                       dp_display->panel_bridge,
> >>> bridge,
> >>> +                                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> >>> +               if (rc < 0) {
> >>> +                       DRM_ERROR("failed to attach panel bridge:
> >>> %d\n", rc);
> >>> +                       drm_bridge_remove(bridge);
> >>> +                       return ERR_PTR(rc);
> >>> +               }
> >>> +       }
> >>> +
> >>>          return bridge;
> >>
> >> Not a problem with this patch, but what is this pointer used for? I see
> >> it's assigned to priv->bridges and num_bridges is incremented but nobody
> >> seems to look at that.
> >
> >
> > That's on my todo list. to remove connectors array and to destroy
> > created bridges during drm device destruction.
> >



-- 
With best wishes
Dmitry

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

* Re: [RFC PATCH v2 3/5] drm/msm/dp: support finding next bridge even for DP interfaces
  2022-02-24 20:13     ` Abhinav Kumar
@ 2022-02-24 20:49       ` Dmitry Baryshkov
  -1 siblings, 0 replies; 84+ messages in thread
From: Dmitry Baryshkov @ 2022-02-24 20:49 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: Bjorn Andersson, Rob Clark, Sean Paul, Kuogee Hsieh,
	Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

On Thu, 24 Feb 2022 at 23:13, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>
>
>
> On 2/11/2022 2:40 PM, Dmitry Baryshkov wrote:
> > It is possible to supply display-connector (bridge) to the DP interface,
> > add support for parsing it too.
> >
> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> > ---
> >   drivers/gpu/drm/msm/dp/dp_parser.c | 19 ++++++++++++-------
> >   1 file changed, 12 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c b/drivers/gpu/drm/msm/dp/dp_parser.c
> > index 901d7967370f..1056b8d5755b 100644
> > --- a/drivers/gpu/drm/msm/dp/dp_parser.c
> > +++ b/drivers/gpu/drm/msm/dp/dp_parser.c
> > @@ -301,17 +301,22 @@ static int dp_parser_parse(struct dp_parser *parser, int connector_type)
> >               return rc;
> >
> >       /*
> > -      * Currently we support external bridges only for eDP connectors.
> > +      * External bridges are mandatory for eDP interfaces: one has to
> > +      * provide at least an eDP panel (which gets wrapped into panel-bridge).
> >        *
> > -      * No external bridges are expected for the DisplayPort connector,
> > -      * it is physically present in a form of a DP or USB-C connector.
> > +      * For DisplayPort interfaces external bridges are optional, so
> > +      * silently ignore an error if one is not present (-ENODEV).
> >        */
> > -     if (connector_type == DRM_MODE_CONNECTOR_eDP) {
> > -             rc = dp_parser_find_next_bridge(parser);
> > -             if (rc) {
> > -                     DRM_ERROR("DP: failed to find next bridge\n");
> > +     rc = dp_parser_find_next_bridge(parser);
> > +     if (rc == -ENODEV) {
> > +             if (connector_type == DRM_MODE_CONNECTOR_eDP) {
> > +                     DRM_ERROR("eDP: next bridge is not present\n");
> >                       return rc;
> >               }
> > +     } else if (rc) {
> > +             if (rc != -EPROBE_DEFER)
> > +                     DRM_ERROR("DP: error parsing next bridge: %d\n", rc);
> > +             return rc;
> >       }
>
> How is this silently ignoring?
>
> static int dp_display_bind(struct device *dev, struct device *master,
>                 void *data)
> {
>      int rc = 0;
>      struct dp_display_private *dp = dev_get_dp_display_private(dev);
>      struct msm_drm_private *priv = dev_get_drvdata(master);
>      struct drm_device *drm = priv->dev;
>
>      dp->dp_display.drm_dev = drm;
>      priv->dp[dp->id] = &dp->dp_display;
>
>      rc = dp->parser->parse(dp->parser, dp->dp_display.connector_type);
>      if (rc) {
>          DRM_ERROR("device tree parsing failed\n");
>          goto end;
>      }
>
> dp_display_bind will still fail if a bridge is not found.
>
> If supplying a bridge is optional even this should succeed right?

It will succeed as dp_parser_parse() will not return -ENODEV if the
connector is not eDP.
To rephrase the comment:
For the dp_parser_find_next_bridge() result:
- for eDP the driver passes all errors to the calling function.
- for DP the driver ignores -ENODEV (no external bridge is supplied),
but passes all other errors (which can mean e.g. that the bridge is
not properly declared or that it did hasn't been probed yet).

-- 
With best wishes
Dmitry

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

* Re: [RFC PATCH v2 3/5] drm/msm/dp: support finding next bridge even for DP interfaces
@ 2022-02-24 20:49       ` Dmitry Baryshkov
  0 siblings, 0 replies; 84+ messages in thread
From: Dmitry Baryshkov @ 2022-02-24 20:49 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: freedreno, David Airlie, linux-arm-msm, dri-devel, Kuogee Hsieh,
	Bjorn Andersson, Stephen Boyd, Sean Paul

On Thu, 24 Feb 2022 at 23:13, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>
>
>
> On 2/11/2022 2:40 PM, Dmitry Baryshkov wrote:
> > It is possible to supply display-connector (bridge) to the DP interface,
> > add support for parsing it too.
> >
> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> > ---
> >   drivers/gpu/drm/msm/dp/dp_parser.c | 19 ++++++++++++-------
> >   1 file changed, 12 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c b/drivers/gpu/drm/msm/dp/dp_parser.c
> > index 901d7967370f..1056b8d5755b 100644
> > --- a/drivers/gpu/drm/msm/dp/dp_parser.c
> > +++ b/drivers/gpu/drm/msm/dp/dp_parser.c
> > @@ -301,17 +301,22 @@ static int dp_parser_parse(struct dp_parser *parser, int connector_type)
> >               return rc;
> >
> >       /*
> > -      * Currently we support external bridges only for eDP connectors.
> > +      * External bridges are mandatory for eDP interfaces: one has to
> > +      * provide at least an eDP panel (which gets wrapped into panel-bridge).
> >        *
> > -      * No external bridges are expected for the DisplayPort connector,
> > -      * it is physically present in a form of a DP or USB-C connector.
> > +      * For DisplayPort interfaces external bridges are optional, so
> > +      * silently ignore an error if one is not present (-ENODEV).
> >        */
> > -     if (connector_type == DRM_MODE_CONNECTOR_eDP) {
> > -             rc = dp_parser_find_next_bridge(parser);
> > -             if (rc) {
> > -                     DRM_ERROR("DP: failed to find next bridge\n");
> > +     rc = dp_parser_find_next_bridge(parser);
> > +     if (rc == -ENODEV) {
> > +             if (connector_type == DRM_MODE_CONNECTOR_eDP) {
> > +                     DRM_ERROR("eDP: next bridge is not present\n");
> >                       return rc;
> >               }
> > +     } else if (rc) {
> > +             if (rc != -EPROBE_DEFER)
> > +                     DRM_ERROR("DP: error parsing next bridge: %d\n", rc);
> > +             return rc;
> >       }
>
> How is this silently ignoring?
>
> static int dp_display_bind(struct device *dev, struct device *master,
>                 void *data)
> {
>      int rc = 0;
>      struct dp_display_private *dp = dev_get_dp_display_private(dev);
>      struct msm_drm_private *priv = dev_get_drvdata(master);
>      struct drm_device *drm = priv->dev;
>
>      dp->dp_display.drm_dev = drm;
>      priv->dp[dp->id] = &dp->dp_display;
>
>      rc = dp->parser->parse(dp->parser, dp->dp_display.connector_type);
>      if (rc) {
>          DRM_ERROR("device tree parsing failed\n");
>          goto end;
>      }
>
> dp_display_bind will still fail if a bridge is not found.
>
> If supplying a bridge is optional even this should succeed right?

It will succeed as dp_parser_parse() will not return -ENODEV if the
connector is not eDP.
To rephrase the comment:
For the dp_parser_find_next_bridge() result:
- for eDP the driver passes all errors to the calling function.
- for DP the driver ignores -ENODEV (no external bridge is supplied),
but passes all other errors (which can mean e.g. that the bridge is
not properly declared or that it did hasn't been probed yet).

-- 
With best wishes
Dmitry

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

* Re: [RFC PATCH v2 3/5] drm/msm/dp: support finding next bridge even for DP interfaces
  2022-02-24 20:49       ` Dmitry Baryshkov
@ 2022-02-24 21:09         ` Abhinav Kumar
  -1 siblings, 0 replies; 84+ messages in thread
From: Abhinav Kumar @ 2022-02-24 21:09 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: freedreno, David Airlie, linux-arm-msm, dri-devel, Kuogee Hsieh,
	Bjorn Andersson, Stephen Boyd, Sean Paul



On 2/24/2022 12:49 PM, Dmitry Baryshkov wrote:
> On Thu, 24 Feb 2022 at 23:13, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>>
>>
>>
>> On 2/11/2022 2:40 PM, Dmitry Baryshkov wrote:
>>> It is possible to supply display-connector (bridge) to the DP interface,
>>> add support for parsing it too.
>>>
>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>> ---
>>>    drivers/gpu/drm/msm/dp/dp_parser.c | 19 ++++++++++++-------
>>>    1 file changed, 12 insertions(+), 7 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c b/drivers/gpu/drm/msm/dp/dp_parser.c
>>> index 901d7967370f..1056b8d5755b 100644
>>> --- a/drivers/gpu/drm/msm/dp/dp_parser.c
>>> +++ b/drivers/gpu/drm/msm/dp/dp_parser.c
>>> @@ -301,17 +301,22 @@ static int dp_parser_parse(struct dp_parser *parser, int connector_type)
>>>                return rc;
>>>
>>>        /*
>>> -      * Currently we support external bridges only for eDP connectors.
>>> +      * External bridges are mandatory for eDP interfaces: one has to
>>> +      * provide at least an eDP panel (which gets wrapped into panel-bridge).
>>>         *
>>> -      * No external bridges are expected for the DisplayPort connector,
>>> -      * it is physically present in a form of a DP or USB-C connector.
>>> +      * For DisplayPort interfaces external bridges are optional, so
>>> +      * silently ignore an error if one is not present (-ENODEV).
>>>         */
>>> -     if (connector_type == DRM_MODE_CONNECTOR_eDP) {
>>> -             rc = dp_parser_find_next_bridge(parser);
>>> -             if (rc) {
>>> -                     DRM_ERROR("DP: failed to find next bridge\n");
>>> +     rc = dp_parser_find_next_bridge(parser);
>>> +     if (rc == -ENODEV) {
>>> +             if (connector_type == DRM_MODE_CONNECTOR_eDP) {
>>> +                     DRM_ERROR("eDP: next bridge is not present\n");
>>>                        return rc;
>>>                }
>>> +     } else if (rc) {
>>> +             if (rc != -EPROBE_DEFER)
>>> +                     DRM_ERROR("DP: error parsing next bridge: %d\n", rc);
>>> +             return rc;
>>>        }
>>
>> How is this silently ignoring?
>>
>> static int dp_display_bind(struct device *dev, struct device *master,
>>                  void *data)
>> {
>>       int rc = 0;
>>       struct dp_display_private *dp = dev_get_dp_display_private(dev);
>>       struct msm_drm_private *priv = dev_get_drvdata(master);
>>       struct drm_device *drm = priv->dev;
>>
>>       dp->dp_display.drm_dev = drm;
>>       priv->dp[dp->id] = &dp->dp_display;
>>
>>       rc = dp->parser->parse(dp->parser, dp->dp_display.connector_type);
>>       if (rc) {
>>           DRM_ERROR("device tree parsing failed\n");
>>           goto end;
>>       }
>>
>> dp_display_bind will still fail if a bridge is not found.
>>
>> If supplying a bridge is optional even this should succeed right?
> 
> It will succeed as dp_parser_parse() will not return -ENODEV if the
> connector is not eDP.
> To rephrase the comment:
> For the dp_parser_find_next_bridge() result:
> - for eDP the driver passes all errors to the calling function.
> - for DP the driver ignores -ENODEV (no external bridge is supplied),
> but passes all other errors (which can mean e.g. that the bridge is
> not properly declared or that it did hasn't been probed yet).
> 

Ah okay, I just noticed that dp_parser_parse() returns 0 by default and 
not rc.

So in this case it will still return 0.

Hence this change LGTM,

Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>

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

* Re: [RFC PATCH v2 3/5] drm/msm/dp: support finding next bridge even for DP interfaces
@ 2022-02-24 21:09         ` Abhinav Kumar
  0 siblings, 0 replies; 84+ messages in thread
From: Abhinav Kumar @ 2022-02-24 21:09 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Sean Paul, David Airlie, linux-arm-msm, Stephen Boyd, dri-devel,
	Bjorn Andersson, Kuogee Hsieh, freedreno



On 2/24/2022 12:49 PM, Dmitry Baryshkov wrote:
> On Thu, 24 Feb 2022 at 23:13, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>>
>>
>>
>> On 2/11/2022 2:40 PM, Dmitry Baryshkov wrote:
>>> It is possible to supply display-connector (bridge) to the DP interface,
>>> add support for parsing it too.
>>>
>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>> ---
>>>    drivers/gpu/drm/msm/dp/dp_parser.c | 19 ++++++++++++-------
>>>    1 file changed, 12 insertions(+), 7 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c b/drivers/gpu/drm/msm/dp/dp_parser.c
>>> index 901d7967370f..1056b8d5755b 100644
>>> --- a/drivers/gpu/drm/msm/dp/dp_parser.c
>>> +++ b/drivers/gpu/drm/msm/dp/dp_parser.c
>>> @@ -301,17 +301,22 @@ static int dp_parser_parse(struct dp_parser *parser, int connector_type)
>>>                return rc;
>>>
>>>        /*
>>> -      * Currently we support external bridges only for eDP connectors.
>>> +      * External bridges are mandatory for eDP interfaces: one has to
>>> +      * provide at least an eDP panel (which gets wrapped into panel-bridge).
>>>         *
>>> -      * No external bridges are expected for the DisplayPort connector,
>>> -      * it is physically present in a form of a DP or USB-C connector.
>>> +      * For DisplayPort interfaces external bridges are optional, so
>>> +      * silently ignore an error if one is not present (-ENODEV).
>>>         */
>>> -     if (connector_type == DRM_MODE_CONNECTOR_eDP) {
>>> -             rc = dp_parser_find_next_bridge(parser);
>>> -             if (rc) {
>>> -                     DRM_ERROR("DP: failed to find next bridge\n");
>>> +     rc = dp_parser_find_next_bridge(parser);
>>> +     if (rc == -ENODEV) {
>>> +             if (connector_type == DRM_MODE_CONNECTOR_eDP) {
>>> +                     DRM_ERROR("eDP: next bridge is not present\n");
>>>                        return rc;
>>>                }
>>> +     } else if (rc) {
>>> +             if (rc != -EPROBE_DEFER)
>>> +                     DRM_ERROR("DP: error parsing next bridge: %d\n", rc);
>>> +             return rc;
>>>        }
>>
>> How is this silently ignoring?
>>
>> static int dp_display_bind(struct device *dev, struct device *master,
>>                  void *data)
>> {
>>       int rc = 0;
>>       struct dp_display_private *dp = dev_get_dp_display_private(dev);
>>       struct msm_drm_private *priv = dev_get_drvdata(master);
>>       struct drm_device *drm = priv->dev;
>>
>>       dp->dp_display.drm_dev = drm;
>>       priv->dp[dp->id] = &dp->dp_display;
>>
>>       rc = dp->parser->parse(dp->parser, dp->dp_display.connector_type);
>>       if (rc) {
>>           DRM_ERROR("device tree parsing failed\n");
>>           goto end;
>>       }
>>
>> dp_display_bind will still fail if a bridge is not found.
>>
>> If supplying a bridge is optional even this should succeed right?
> 
> It will succeed as dp_parser_parse() will not return -ENODEV if the
> connector is not eDP.
> To rephrase the comment:
> For the dp_parser_find_next_bridge() result:
> - for eDP the driver passes all errors to the calling function.
> - for DP the driver ignores -ENODEV (no external bridge is supplied),
> but passes all other errors (which can mean e.g. that the bridge is
> not properly declared or that it did hasn't been probed yet).
> 

Ah okay, I just noticed that dp_parser_parse() returns 0 by default and 
not rc.

So in this case it will still return 0.

Hence this change LGTM,

Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>

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

* Re: [Freedreno] [RFC PATCH v2 1/5] drm/msm/dp: fix panel bridge attachment
  2022-02-24 20:41           ` Dmitry Baryshkov
@ 2022-02-25  2:01             ` Abhinav Kumar
  -1 siblings, 0 replies; 84+ messages in thread
From: Abhinav Kumar @ 2022-02-25  2:01 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: freedreno, David Airlie, linux-arm-msm, Stephen Boyd, dri-devel,
	Kuogee Hsieh, Bjorn Andersson, Sean Paul



On 2/24/2022 12:41 PM, Dmitry Baryshkov wrote:
> On Thu, 24 Feb 2022 at 21:25, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>>
>>
>>
>> On 2/18/2022 6:26 PM, Dmitry Baryshkov wrote:
>>> On 19/02/2022 02:56, Stephen Boyd wrote:
>>>> Quoting Dmitry Baryshkov (2022-02-11 14:40:02)
>>>>> In commit 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
>>>>> enable and disable") the DP driver received a drm_bridge instance, which
>>>>> is always attached to the encoder as a root bridge. However it conflicts
>>>>> with the panel_bridge support for eDP panels. The panel bridge attaches
>>>>> to the encoder before the "dp" bridge has a chace to do so. Change
>>>>
>>>> s/chace/chance/
>>>>
>>>>> panel_bridge attachment to come after dp_bridge attachment.
>>>>
>>>> s/panel_bridge/panel bridge/ possibly? And maybe clarify that dp_bridge
>>>> is the "DP driver's drm_bridge instance created in
>>>> msm_dp_bridge_init()"?
>>>>
>>>> My understanding is that we want to pass the bridge created in
>>>> msm_dp_bridge_init() as the 'previous' bridge so that it attaches the
>>>> panel bridge to the output of the DP bridge that's attached to the
>>>> encoder.
>>>
>>> Thanks! I'll update the commit log when pushing the patches.
>>
>> Please correct if i am missing something here.
>>
>> You are right that the eDP panel's panel bridge attaches to the encoder
>> in dp_drm_connector_init() which happens before msm_dp_bridge_init() and
>> hence it will attach directly to the encoder.
>>
>> But we are talking about different encoders here. DP's dp_display has a
>> different encoder compared to the EDP's dp_display.
> 
> The encoders are different. However both encoders use the same
> codepath, which includes dp_bridge. It controls dp_display by calling
> msm_dp_display_foo() functions.
> 
>> So DP's bridge will still be attached to its encoder's root.
> 
> There is one dp_bridge per each encoder. Consider sc8180x which has 3
> DP controllers (and thus 3 dp_bridges).
> 

Sorry, but I still didnt follow this.

So for eDP, dp_drm_connector_init() will attach the panel_bridge
and then msm_dp_bridge_init() will add a drm_bridge.

And yes in that case, the drm_bridge will be after the panel_bridge

But since panel_bridge is at the root for eDP it should be okay.

Your commit text was mentioning about DP.

For DP, for each controller in the catalog, we will call modeset_init() 
which should skip this part for DP

   if (dp_display->panel_bridge) {
         ret = drm_bridge_attach(dp_display->encoder,
                     dp_display->panel_bridge, NULL,
                     DRM_BRIDGE_ATTACH_NO_CONNECTOR);
         if (ret < 0) {
             DRM_ERROR("failed to attach panel bridge: %d\n", ret);
             return ERR_PTR(ret);
         }
     }

Followed by calling msm_dp_bridge_init() which will actually attach the 
bridge:

drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);

Now, even for 3 DP controllers, this shall be true as there will be 3 
separate encoders and 3 dp_displays and hence 3 drm_bridges.

What am i missing here?

>>
>> So what are we achieving with this change?
>>
>>>
>>>>
>>>>>
>>>>> Fixes: 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
>>>>> enable and disable")
>>>>> Cc: Kuogee Hsieh <quic_khsieh@quicinc.com>
>>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>>>> ---
>>>>
>>>> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
>>>>
>>>>>    drivers/gpu/drm/msm/dp/dp_drm.c | 21 +++++++++++----------
>>>>>    1 file changed, 11 insertions(+), 10 deletions(-)
>>>>>
>>>>> diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c
>>>>> b/drivers/gpu/drm/msm/dp/dp_drm.c
>>>>> index d4d360d19eba..26ef41a4c1b6 100644
>>>>> --- a/drivers/gpu/drm/msm/dp/dp_drm.c
>>>>> +++ b/drivers/gpu/drm/msm/dp/dp_drm.c
>>>>> @@ -169,16 +169,6 @@ struct drm_connector
>>>>> *dp_drm_connector_init(struct msm_dp *dp_display)
>>>>>
>>>>>           drm_connector_attach_encoder(connector, dp_display->encoder);
>>>>>
>>>>> -       if (dp_display->panel_bridge) {
>>>>> -               ret = drm_bridge_attach(dp_display->encoder,
>>>>> -                                       dp_display->panel_bridge, NULL,
>>>>> -                                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>>>>> -               if (ret < 0) {
>>>>> -                       DRM_ERROR("failed to attach panel bridge:
>>>>> %d\n", ret);
>>>>> -                       return ERR_PTR(ret);
>>>>> -               }
>>>>> -       }
>>>>> -
>>>>>           return connector;
>>>>>    }
>>>>>
>>>>> @@ -246,5 +236,16 @@ struct drm_bridge *msm_dp_bridge_init(struct
>>>>> msm_dp *dp_display, struct drm_devi
>>>>>                   return ERR_PTR(rc);
>>>>>           }
>>>>>
>>>>> +       if (dp_display->panel_bridge) {
>>>>> +               rc = drm_bridge_attach(dp_display->encoder,
>>>>> +                                       dp_display->panel_bridge,
>>>>> bridge,
>>>>> +                                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>>>>> +               if (rc < 0) {
>>>>> +                       DRM_ERROR("failed to attach panel bridge:
>>>>> %d\n", rc);
>>>>> +                       drm_bridge_remove(bridge);
>>>>> +                       return ERR_PTR(rc);
>>>>> +               }
>>>>> +       }
>>>>> +
>>>>>           return bridge;
>>>>
>>>> Not a problem with this patch, but what is this pointer used for? I see
>>>> it's assigned to priv->bridges and num_bridges is incremented but nobody
>>>> seems to look at that.
>>>
>>>
>>> That's on my todo list. to remove connectors array and to destroy
>>> created bridges during drm device destruction.
>>>
> 
> 
> 

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

* Re: [Freedreno] [RFC PATCH v2 1/5] drm/msm/dp: fix panel bridge attachment
@ 2022-02-25  2:01             ` Abhinav Kumar
  0 siblings, 0 replies; 84+ messages in thread
From: Abhinav Kumar @ 2022-02-25  2:01 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Stephen Boyd, Bjorn Andersson, Kuogee Hsieh, Rob Clark,
	Sean Paul, David Airlie, linux-arm-msm, freedreno, dri-devel,
	Daniel Vetter



On 2/24/2022 12:41 PM, Dmitry Baryshkov wrote:
> On Thu, 24 Feb 2022 at 21:25, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>>
>>
>>
>> On 2/18/2022 6:26 PM, Dmitry Baryshkov wrote:
>>> On 19/02/2022 02:56, Stephen Boyd wrote:
>>>> Quoting Dmitry Baryshkov (2022-02-11 14:40:02)
>>>>> In commit 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
>>>>> enable and disable") the DP driver received a drm_bridge instance, which
>>>>> is always attached to the encoder as a root bridge. However it conflicts
>>>>> with the panel_bridge support for eDP panels. The panel bridge attaches
>>>>> to the encoder before the "dp" bridge has a chace to do so. Change
>>>>
>>>> s/chace/chance/
>>>>
>>>>> panel_bridge attachment to come after dp_bridge attachment.
>>>>
>>>> s/panel_bridge/panel bridge/ possibly? And maybe clarify that dp_bridge
>>>> is the "DP driver's drm_bridge instance created in
>>>> msm_dp_bridge_init()"?
>>>>
>>>> My understanding is that we want to pass the bridge created in
>>>> msm_dp_bridge_init() as the 'previous' bridge so that it attaches the
>>>> panel bridge to the output of the DP bridge that's attached to the
>>>> encoder.
>>>
>>> Thanks! I'll update the commit log when pushing the patches.
>>
>> Please correct if i am missing something here.
>>
>> You are right that the eDP panel's panel bridge attaches to the encoder
>> in dp_drm_connector_init() which happens before msm_dp_bridge_init() and
>> hence it will attach directly to the encoder.
>>
>> But we are talking about different encoders here. DP's dp_display has a
>> different encoder compared to the EDP's dp_display.
> 
> The encoders are different. However both encoders use the same
> codepath, which includes dp_bridge. It controls dp_display by calling
> msm_dp_display_foo() functions.
> 
>> So DP's bridge will still be attached to its encoder's root.
> 
> There is one dp_bridge per each encoder. Consider sc8180x which has 3
> DP controllers (and thus 3 dp_bridges).
> 

Sorry, but I still didnt follow this.

So for eDP, dp_drm_connector_init() will attach the panel_bridge
and then msm_dp_bridge_init() will add a drm_bridge.

And yes in that case, the drm_bridge will be after the panel_bridge

But since panel_bridge is at the root for eDP it should be okay.

Your commit text was mentioning about DP.

For DP, for each controller in the catalog, we will call modeset_init() 
which should skip this part for DP

   if (dp_display->panel_bridge) {
         ret = drm_bridge_attach(dp_display->encoder,
                     dp_display->panel_bridge, NULL,
                     DRM_BRIDGE_ATTACH_NO_CONNECTOR);
         if (ret < 0) {
             DRM_ERROR("failed to attach panel bridge: %d\n", ret);
             return ERR_PTR(ret);
         }
     }

Followed by calling msm_dp_bridge_init() which will actually attach the 
bridge:

drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);

Now, even for 3 DP controllers, this shall be true as there will be 3 
separate encoders and 3 dp_displays and hence 3 drm_bridges.

What am i missing here?

>>
>> So what are we achieving with this change?
>>
>>>
>>>>
>>>>>
>>>>> Fixes: 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
>>>>> enable and disable")
>>>>> Cc: Kuogee Hsieh <quic_khsieh@quicinc.com>
>>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>>>> ---
>>>>
>>>> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
>>>>
>>>>>    drivers/gpu/drm/msm/dp/dp_drm.c | 21 +++++++++++----------
>>>>>    1 file changed, 11 insertions(+), 10 deletions(-)
>>>>>
>>>>> diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c
>>>>> b/drivers/gpu/drm/msm/dp/dp_drm.c
>>>>> index d4d360d19eba..26ef41a4c1b6 100644
>>>>> --- a/drivers/gpu/drm/msm/dp/dp_drm.c
>>>>> +++ b/drivers/gpu/drm/msm/dp/dp_drm.c
>>>>> @@ -169,16 +169,6 @@ struct drm_connector
>>>>> *dp_drm_connector_init(struct msm_dp *dp_display)
>>>>>
>>>>>           drm_connector_attach_encoder(connector, dp_display->encoder);
>>>>>
>>>>> -       if (dp_display->panel_bridge) {
>>>>> -               ret = drm_bridge_attach(dp_display->encoder,
>>>>> -                                       dp_display->panel_bridge, NULL,
>>>>> -                                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>>>>> -               if (ret < 0) {
>>>>> -                       DRM_ERROR("failed to attach panel bridge:
>>>>> %d\n", ret);
>>>>> -                       return ERR_PTR(ret);
>>>>> -               }
>>>>> -       }
>>>>> -
>>>>>           return connector;
>>>>>    }
>>>>>
>>>>> @@ -246,5 +236,16 @@ struct drm_bridge *msm_dp_bridge_init(struct
>>>>> msm_dp *dp_display, struct drm_devi
>>>>>                   return ERR_PTR(rc);
>>>>>           }
>>>>>
>>>>> +       if (dp_display->panel_bridge) {
>>>>> +               rc = drm_bridge_attach(dp_display->encoder,
>>>>> +                                       dp_display->panel_bridge,
>>>>> bridge,
>>>>> +                                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>>>>> +               if (rc < 0) {
>>>>> +                       DRM_ERROR("failed to attach panel bridge:
>>>>> %d\n", rc);
>>>>> +                       drm_bridge_remove(bridge);
>>>>> +                       return ERR_PTR(rc);
>>>>> +               }
>>>>> +       }
>>>>> +
>>>>>           return bridge;
>>>>
>>>> Not a problem with this patch, but what is this pointer used for? I see
>>>> it's assigned to priv->bridges and num_bridges is incremented but nobody
>>>> seems to look at that.
>>>
>>>
>>> That's on my todo list. to remove connectors array and to destroy
>>> created bridges during drm device destruction.
>>>
> 
> 
> 

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

* Re: [Freedreno] [RFC PATCH v2 1/5] drm/msm/dp: fix panel bridge attachment
  2022-02-25  2:01             ` Abhinav Kumar
@ 2022-02-25  4:22               ` Dmitry Baryshkov
  -1 siblings, 0 replies; 84+ messages in thread
From: Dmitry Baryshkov @ 2022-02-25  4:22 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: Stephen Boyd, Bjorn Andersson, Kuogee Hsieh, Rob Clark,
	Sean Paul, David Airlie, linux-arm-msm, freedreno, dri-devel,
	Daniel Vetter

On Fri, 25 Feb 2022 at 05:01, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>
>
>
> On 2/24/2022 12:41 PM, Dmitry Baryshkov wrote:
> > On Thu, 24 Feb 2022 at 21:25, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
> >>
> >>
> >>
> >> On 2/18/2022 6:26 PM, Dmitry Baryshkov wrote:
> >>> On 19/02/2022 02:56, Stephen Boyd wrote:
> >>>> Quoting Dmitry Baryshkov (2022-02-11 14:40:02)
> >>>>> In commit 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
> >>>>> enable and disable") the DP driver received a drm_bridge instance, which
> >>>>> is always attached to the encoder as a root bridge. However it conflicts
> >>>>> with the panel_bridge support for eDP panels. The panel bridge attaches
> >>>>> to the encoder before the "dp" bridge has a chace to do so. Change
> >>>>
> >>>> s/chace/chance/
> >>>>
> >>>>> panel_bridge attachment to come after dp_bridge attachment.
> >>>>
> >>>> s/panel_bridge/panel bridge/ possibly? And maybe clarify that dp_bridge
> >>>> is the "DP driver's drm_bridge instance created in
> >>>> msm_dp_bridge_init()"?
> >>>>
> >>>> My understanding is that we want to pass the bridge created in
> >>>> msm_dp_bridge_init() as the 'previous' bridge so that it attaches the
> >>>> panel bridge to the output of the DP bridge that's attached to the
> >>>> encoder.
> >>>
> >>> Thanks! I'll update the commit log when pushing the patches.
> >>
> >> Please correct if i am missing something here.
> >>
> >> You are right that the eDP panel's panel bridge attaches to the encoder
> >> in dp_drm_connector_init() which happens before msm_dp_bridge_init() and
> >> hence it will attach directly to the encoder.
> >>
> >> But we are talking about different encoders here. DP's dp_display has a
> >> different encoder compared to the EDP's dp_display.
> >
> > The encoders are different. However both encoders use the same
> > codepath, which includes dp_bridge. It controls dp_display by calling
> > msm_dp_display_foo() functions.
> >

> >> So DP's bridge will still be attached to its encoder's root.
> >
> > There is one dp_bridge per each encoder. Consider sc8180x which has 3
> > DP controllers (and thus 3 dp_bridges).
> >
>
> Sorry, but I still didnt follow this.
>
> So for eDP, dp_drm_connector_init() will attach the panel_bridge
> and then msm_dp_bridge_init() will add a drm_bridge.
>
> And yes in that case, the drm_bridge will be after the panel_bridge
>
> But since panel_bridge is at the root for eDP it should be okay.

No. It is not.
For both DP and eDP the chain should be:
dpu_encoder -> dp_bridge -> external (panel) bridge, optional for DP
-> [other bridges] -> connector

Otherwise drm_bridge_chain_foo() functions would be called in the
incorrect order.

Thus the dp_bridge should be attached directly to the encoder
(drm_encoder) and panel_bridge should use dp_bridge as the 'previous'
bridge.

For example, for the DP port one can use a display-connector (which
actually implements drm_bridge) as an external bridge to provide hpd
or dp power GPIOs.

Note, that the current dp_connector breaks layering. It makes calls
directly into dp_display, not allowing external bridge (and other
bridges) to override get_modes/mode_valid and other callbacks.
Thus one of the next patches in series (the one that Kuogee had issues
with) tries to replace the chain with the following one:
dpu_encoder -> dp_bridge -> external (panel) bridge -> [other bridges]
-> drm_bridge_connector.

>
> Your commit text was mentioning about DP.
>
> For DP, for each controller in the catalog, we will call modeset_init()
> which should skip this part for DP
>
>    if (dp_display->panel_bridge) {
>          ret = drm_bridge_attach(dp_display->encoder,
>                      dp_display->panel_bridge, NULL,

as you see, NULL is incorrect. It should be a pointer to dp_bridge instead

>                      DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>          if (ret < 0) {
>              DRM_ERROR("failed to attach panel bridge: %d\n", ret);
>              return ERR_PTR(ret);
>          }
>      }
>
> Followed by calling msm_dp_bridge_init() which will actually attach the
> bridge:
>
> drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);

And this bridge should be attached before the external bridge.

>
> Now, even for 3 DP controllers, this shall be true as there will be 3
> separate encoders and 3 dp_displays and hence 3 drm_bridges.
>
> What am i missing here?
>
> >>
> >> So what are we achieving with this change?
> >>
> >>>
> >>>>
> >>>>>
> >>>>> Fixes: 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
> >>>>> enable and disable")
> >>>>> Cc: Kuogee Hsieh <quic_khsieh@quicinc.com>
> >>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> >>>>> ---
> >>>>
> >>>> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
> >>>>
> >>>>>    drivers/gpu/drm/msm/dp/dp_drm.c | 21 +++++++++++----------
> >>>>>    1 file changed, 11 insertions(+), 10 deletions(-)
> >>>>>
> >>>>> diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c
> >>>>> b/drivers/gpu/drm/msm/dp/dp_drm.c
> >>>>> index d4d360d19eba..26ef41a4c1b6 100644
> >>>>> --- a/drivers/gpu/drm/msm/dp/dp_drm.c
> >>>>> +++ b/drivers/gpu/drm/msm/dp/dp_drm.c
> >>>>> @@ -169,16 +169,6 @@ struct drm_connector
> >>>>> *dp_drm_connector_init(struct msm_dp *dp_display)
> >>>>>
> >>>>>           drm_connector_attach_encoder(connector, dp_display->encoder);
> >>>>>
> >>>>> -       if (dp_display->panel_bridge) {
> >>>>> -               ret = drm_bridge_attach(dp_display->encoder,
> >>>>> -                                       dp_display->panel_bridge, NULL,
> >>>>> -                                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> >>>>> -               if (ret < 0) {
> >>>>> -                       DRM_ERROR("failed to attach panel bridge:
> >>>>> %d\n", ret);
> >>>>> -                       return ERR_PTR(ret);
> >>>>> -               }
> >>>>> -       }
> >>>>> -
> >>>>>           return connector;
> >>>>>    }
> >>>>>
> >>>>> @@ -246,5 +236,16 @@ struct drm_bridge *msm_dp_bridge_init(struct
> >>>>> msm_dp *dp_display, struct drm_devi
> >>>>>                   return ERR_PTR(rc);
> >>>>>           }
> >>>>>
> >>>>> +       if (dp_display->panel_bridge) {
> >>>>> +               rc = drm_bridge_attach(dp_display->encoder,
> >>>>> +                                       dp_display->panel_bridge,
> >>>>> bridge,
> >>>>> +                                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> >>>>> +               if (rc < 0) {
> >>>>> +                       DRM_ERROR("failed to attach panel bridge:
> >>>>> %d\n", rc);
> >>>>> +                       drm_bridge_remove(bridge);
> >>>>> +                       return ERR_PTR(rc);
> >>>>> +               }
> >>>>> +       }
> >>>>> +
> >>>>>           return bridge;
> >>>>
> >>>> Not a problem with this patch, but what is this pointer used for? I see
> >>>> it's assigned to priv->bridges and num_bridges is incremented but nobody
> >>>> seems to look at that.
> >>>
> >>>
> >>> That's on my todo list. to remove connectors array and to destroy
> >>> created bridges during drm device destruction.
> >>>
> >
> >
> >



-- 
With best wishes
Dmitry

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

* Re: [Freedreno] [RFC PATCH v2 1/5] drm/msm/dp: fix panel bridge attachment
@ 2022-02-25  4:22               ` Dmitry Baryshkov
  0 siblings, 0 replies; 84+ messages in thread
From: Dmitry Baryshkov @ 2022-02-25  4:22 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: freedreno, David Airlie, linux-arm-msm, Stephen Boyd, dri-devel,
	Kuogee Hsieh, Bjorn Andersson, Sean Paul

On Fri, 25 Feb 2022 at 05:01, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>
>
>
> On 2/24/2022 12:41 PM, Dmitry Baryshkov wrote:
> > On Thu, 24 Feb 2022 at 21:25, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
> >>
> >>
> >>
> >> On 2/18/2022 6:26 PM, Dmitry Baryshkov wrote:
> >>> On 19/02/2022 02:56, Stephen Boyd wrote:
> >>>> Quoting Dmitry Baryshkov (2022-02-11 14:40:02)
> >>>>> In commit 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
> >>>>> enable and disable") the DP driver received a drm_bridge instance, which
> >>>>> is always attached to the encoder as a root bridge. However it conflicts
> >>>>> with the panel_bridge support for eDP panels. The panel bridge attaches
> >>>>> to the encoder before the "dp" bridge has a chace to do so. Change
> >>>>
> >>>> s/chace/chance/
> >>>>
> >>>>> panel_bridge attachment to come after dp_bridge attachment.
> >>>>
> >>>> s/panel_bridge/panel bridge/ possibly? And maybe clarify that dp_bridge
> >>>> is the "DP driver's drm_bridge instance created in
> >>>> msm_dp_bridge_init()"?
> >>>>
> >>>> My understanding is that we want to pass the bridge created in
> >>>> msm_dp_bridge_init() as the 'previous' bridge so that it attaches the
> >>>> panel bridge to the output of the DP bridge that's attached to the
> >>>> encoder.
> >>>
> >>> Thanks! I'll update the commit log when pushing the patches.
> >>
> >> Please correct if i am missing something here.
> >>
> >> You are right that the eDP panel's panel bridge attaches to the encoder
> >> in dp_drm_connector_init() which happens before msm_dp_bridge_init() and
> >> hence it will attach directly to the encoder.
> >>
> >> But we are talking about different encoders here. DP's dp_display has a
> >> different encoder compared to the EDP's dp_display.
> >
> > The encoders are different. However both encoders use the same
> > codepath, which includes dp_bridge. It controls dp_display by calling
> > msm_dp_display_foo() functions.
> >

> >> So DP's bridge will still be attached to its encoder's root.
> >
> > There is one dp_bridge per each encoder. Consider sc8180x which has 3
> > DP controllers (and thus 3 dp_bridges).
> >
>
> Sorry, but I still didnt follow this.
>
> So for eDP, dp_drm_connector_init() will attach the panel_bridge
> and then msm_dp_bridge_init() will add a drm_bridge.
>
> And yes in that case, the drm_bridge will be after the panel_bridge
>
> But since panel_bridge is at the root for eDP it should be okay.

No. It is not.
For both DP and eDP the chain should be:
dpu_encoder -> dp_bridge -> external (panel) bridge, optional for DP
-> [other bridges] -> connector

Otherwise drm_bridge_chain_foo() functions would be called in the
incorrect order.

Thus the dp_bridge should be attached directly to the encoder
(drm_encoder) and panel_bridge should use dp_bridge as the 'previous'
bridge.

For example, for the DP port one can use a display-connector (which
actually implements drm_bridge) as an external bridge to provide hpd
or dp power GPIOs.

Note, that the current dp_connector breaks layering. It makes calls
directly into dp_display, not allowing external bridge (and other
bridges) to override get_modes/mode_valid and other callbacks.
Thus one of the next patches in series (the one that Kuogee had issues
with) tries to replace the chain with the following one:
dpu_encoder -> dp_bridge -> external (panel) bridge -> [other bridges]
-> drm_bridge_connector.

>
> Your commit text was mentioning about DP.
>
> For DP, for each controller in the catalog, we will call modeset_init()
> which should skip this part for DP
>
>    if (dp_display->panel_bridge) {
>          ret = drm_bridge_attach(dp_display->encoder,
>                      dp_display->panel_bridge, NULL,

as you see, NULL is incorrect. It should be a pointer to dp_bridge instead

>                      DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>          if (ret < 0) {
>              DRM_ERROR("failed to attach panel bridge: %d\n", ret);
>              return ERR_PTR(ret);
>          }
>      }
>
> Followed by calling msm_dp_bridge_init() which will actually attach the
> bridge:
>
> drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);

And this bridge should be attached before the external bridge.

>
> Now, even for 3 DP controllers, this shall be true as there will be 3
> separate encoders and 3 dp_displays and hence 3 drm_bridges.
>
> What am i missing here?
>
> >>
> >> So what are we achieving with this change?
> >>
> >>>
> >>>>
> >>>>>
> >>>>> Fixes: 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
> >>>>> enable and disable")
> >>>>> Cc: Kuogee Hsieh <quic_khsieh@quicinc.com>
> >>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> >>>>> ---
> >>>>
> >>>> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
> >>>>
> >>>>>    drivers/gpu/drm/msm/dp/dp_drm.c | 21 +++++++++++----------
> >>>>>    1 file changed, 11 insertions(+), 10 deletions(-)
> >>>>>
> >>>>> diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c
> >>>>> b/drivers/gpu/drm/msm/dp/dp_drm.c
> >>>>> index d4d360d19eba..26ef41a4c1b6 100644
> >>>>> --- a/drivers/gpu/drm/msm/dp/dp_drm.c
> >>>>> +++ b/drivers/gpu/drm/msm/dp/dp_drm.c
> >>>>> @@ -169,16 +169,6 @@ struct drm_connector
> >>>>> *dp_drm_connector_init(struct msm_dp *dp_display)
> >>>>>
> >>>>>           drm_connector_attach_encoder(connector, dp_display->encoder);
> >>>>>
> >>>>> -       if (dp_display->panel_bridge) {
> >>>>> -               ret = drm_bridge_attach(dp_display->encoder,
> >>>>> -                                       dp_display->panel_bridge, NULL,
> >>>>> -                                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> >>>>> -               if (ret < 0) {
> >>>>> -                       DRM_ERROR("failed to attach panel bridge:
> >>>>> %d\n", ret);
> >>>>> -                       return ERR_PTR(ret);
> >>>>> -               }
> >>>>> -       }
> >>>>> -
> >>>>>           return connector;
> >>>>>    }
> >>>>>
> >>>>> @@ -246,5 +236,16 @@ struct drm_bridge *msm_dp_bridge_init(struct
> >>>>> msm_dp *dp_display, struct drm_devi
> >>>>>                   return ERR_PTR(rc);
> >>>>>           }
> >>>>>
> >>>>> +       if (dp_display->panel_bridge) {
> >>>>> +               rc = drm_bridge_attach(dp_display->encoder,
> >>>>> +                                       dp_display->panel_bridge,
> >>>>> bridge,
> >>>>> +                                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> >>>>> +               if (rc < 0) {
> >>>>> +                       DRM_ERROR("failed to attach panel bridge:
> >>>>> %d\n", rc);
> >>>>> +                       drm_bridge_remove(bridge);
> >>>>> +                       return ERR_PTR(rc);
> >>>>> +               }
> >>>>> +       }
> >>>>> +
> >>>>>           return bridge;
> >>>>
> >>>> Not a problem with this patch, but what is this pointer used for? I see
> >>>> it's assigned to priv->bridges and num_bridges is incremented but nobody
> >>>> seems to look at that.
> >>>
> >>>
> >>> That's on my todo list. to remove connectors array and to destroy
> >>> created bridges during drm device destruction.
> >>>
> >
> >
> >



-- 
With best wishes
Dmitry

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

* Re: [Freedreno] [RFC PATCH v2 1/5] drm/msm/dp: fix panel bridge attachment
  2022-02-25  4:22               ` Dmitry Baryshkov
@ 2022-02-25  4:45                 ` Abhinav Kumar
  -1 siblings, 0 replies; 84+ messages in thread
From: Abhinav Kumar @ 2022-02-25  4:45 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Stephen Boyd, Bjorn Andersson, Kuogee Hsieh, Rob Clark,
	Sean Paul, David Airlie, linux-arm-msm, freedreno, dri-devel,
	Daniel Vetter



On 2/24/2022 8:22 PM, Dmitry Baryshkov wrote:
> On Fri, 25 Feb 2022 at 05:01, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>>
>>
>>
>> On 2/24/2022 12:41 PM, Dmitry Baryshkov wrote:
>>> On Thu, 24 Feb 2022 at 21:25, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>>>>
>>>>
>>>>
>>>> On 2/18/2022 6:26 PM, Dmitry Baryshkov wrote:
>>>>> On 19/02/2022 02:56, Stephen Boyd wrote:
>>>>>> Quoting Dmitry Baryshkov (2022-02-11 14:40:02)
>>>>>>> In commit 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
>>>>>>> enable and disable") the DP driver received a drm_bridge instance, which
>>>>>>> is always attached to the encoder as a root bridge. However it conflicts
>>>>>>> with the panel_bridge support for eDP panels. The panel bridge attaches
>>>>>>> to the encoder before the "dp" bridge has a chace to do so. Change
>>>>>>
>>>>>> s/chace/chance/
>>>>>>
>>>>>>> panel_bridge attachment to come after dp_bridge attachment.
>>>>>>
>>>>>> s/panel_bridge/panel bridge/ possibly? And maybe clarify that dp_bridge
>>>>>> is the "DP driver's drm_bridge instance created in
>>>>>> msm_dp_bridge_init()"?
>>>>>>
>>>>>> My understanding is that we want to pass the bridge created in
>>>>>> msm_dp_bridge_init() as the 'previous' bridge so that it attaches the
>>>>>> panel bridge to the output of the DP bridge that's attached to the
>>>>>> encoder.
>>>>>
>>>>> Thanks! I'll update the commit log when pushing the patches.
>>>>
>>>> Please correct if i am missing something here.
>>>>
>>>> You are right that the eDP panel's panel bridge attaches to the encoder
>>>> in dp_drm_connector_init() which happens before msm_dp_bridge_init() and
>>>> hence it will attach directly to the encoder.
>>>>
>>>> But we are talking about different encoders here. DP's dp_display has a
>>>> different encoder compared to the EDP's dp_display.
>>>
>>> The encoders are different. However both encoders use the same
>>> codepath, which includes dp_bridge. It controls dp_display by calling
>>> msm_dp_display_foo() functions.
>>>
> 
>>>> So DP's bridge will still be attached to its encoder's root.
>>>
>>> There is one dp_bridge per each encoder. Consider sc8180x which has 3
>>> DP controllers (and thus 3 dp_bridges).
>>>
>>
>> Sorry, but I still didnt follow this.
>>
>> So for eDP, dp_drm_connector_init() will attach the panel_bridge
>> and then msm_dp_bridge_init() will add a drm_bridge.
>>
>> And yes in that case, the drm_bridge will be after the panel_bridge
>>
>> But since panel_bridge is at the root for eDP it should be okay.
> 
> No. It is not.
> For both DP and eDP the chain should be:
> dpu_encoder -> dp_bridge -> external (panel) bridge, optional for DP
> -> [other bridges] -> connector
> 
> Otherwise drm_bridge_chain_foo() functions would be called in the
> incorrect order.

Agreed. For drm_bridge_chain_foo() ordering to be correct, for eDP chain 
the order should be what you mentioned and panel_bridge should be at the 
end ( should be the last one ).

For the above reason,

Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>

I still didnt understand what gets affected by this for the 
msm_dp_display_foo() functions you mentioned earlier and wanted to get 
some clarity on that.
> 
> Thus the dp_bridge should be attached directly to the encoder
> (drm_encoder) and panel_bridge should use dp_bridge as the 'previous'
> bridge.
> 

Agreed.

> For example, for the DP port one can use a display-connector (which
> actually implements drm_bridge) as an external bridge to provide hpd
> or dp power GPIOs.
> 
> Note, that the current dp_connector breaks layering. It makes calls
> directly into dp_display, not allowing external bridge (and other
> bridges) to override get_modes/mode_valid and other callbacks.
> Thus one of the next patches in series (the one that Kuogee had issues
> with) tries to replace the chain with the following one:
> dpu_encoder -> dp_bridge -> external (panel) bridge -> [other bridges]
> -> drm_bridge_connector.
> 
>>

So originally the plan was always that the DP connector layer intercepts 
the call because panel-eDP file did not support reading of the EDID ( we 
have not provided the aux bus ). So it was intended that we did not want 
to goto the eDP panel to get the modes. Not an error but something which 
we wanted to cleanup later when we moved to panel-eDP completely.

Till then we wanted the dp_connector to read the EDID and get the modes.

So this was actually intended to happen till the point where we moved to 
panel-eDP to get the modes.

Hence what you have mentioned in your cover letter is right that the 
chain was broken but there was no loss of functionality due to that today.

Now that these changes are made, we can still goto panel-eDP file for 
the modes because of the below change from Sankeerth where the mode is 
hard-coded:

https://patchwork.freedesktop.org/patch/473431/

With this change cherry-picked it should work for kuogee. We will 
re-test that with this change.


>> Your commit text was mentioning about DP.
>>
>> For DP, for each controller in the catalog, we will call modeset_init()
>> which should skip this part for DP
>>
>>     if (dp_display->panel_bridge) {
>>           ret = drm_bridge_attach(dp_display->encoder,
>>                       dp_display->panel_bridge, NULL,
> 
> as you see, NULL is incorrect. It should be a pointer to dp_bridge instead
> 
>>                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>>           if (ret < 0) {
>>               DRM_ERROR("failed to attach panel bridge: %d\n", ret);
>>               return ERR_PTR(ret);
>>           }
>>       }
>>
>> Followed by calling msm_dp_bridge_init() which will actually attach the
>> bridge:
>>
>> drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> 
> And this bridge should be attached before the external bridge.
> 
>>
>> Now, even for 3 DP controllers, this shall be true as there will be 3
>> separate encoders and 3 dp_displays and hence 3 drm_bridges.
>>
>> What am i missing here?
>>
>>>>
>>>> So what are we achieving with this change?
>>>>
>>>>>
>>>>>>
>>>>>>>
>>>>>>> Fixes: 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
>>>>>>> enable and disable")
>>>>>>> Cc: Kuogee Hsieh <quic_khsieh@quicinc.com>
>>>>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>>>>>> ---
>>>>>>
>>>>>> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
>>>>>>
>>>>>>>     drivers/gpu/drm/msm/dp/dp_drm.c | 21 +++++++++++----------
>>>>>>>     1 file changed, 11 insertions(+), 10 deletions(-)
>>>>>>>
>>>>>>> diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c
>>>>>>> b/drivers/gpu/drm/msm/dp/dp_drm.c
>>>>>>> index d4d360d19eba..26ef41a4c1b6 100644
>>>>>>> --- a/drivers/gpu/drm/msm/dp/dp_drm.c
>>>>>>> +++ b/drivers/gpu/drm/msm/dp/dp_drm.c
>>>>>>> @@ -169,16 +169,6 @@ struct drm_connector
>>>>>>> *dp_drm_connector_init(struct msm_dp *dp_display)
>>>>>>>
>>>>>>>            drm_connector_attach_encoder(connector, dp_display->encoder);
>>>>>>>
>>>>>>> -       if (dp_display->panel_bridge) {
>>>>>>> -               ret = drm_bridge_attach(dp_display->encoder,
>>>>>>> -                                       dp_display->panel_bridge, NULL,
>>>>>>> -                                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>>>>>>> -               if (ret < 0) {
>>>>>>> -                       DRM_ERROR("failed to attach panel bridge:
>>>>>>> %d\n", ret);
>>>>>>> -                       return ERR_PTR(ret);
>>>>>>> -               }
>>>>>>> -       }
>>>>>>> -
>>>>>>>            return connector;
>>>>>>>     }
>>>>>>>
>>>>>>> @@ -246,5 +236,16 @@ struct drm_bridge *msm_dp_bridge_init(struct
>>>>>>> msm_dp *dp_display, struct drm_devi
>>>>>>>                    return ERR_PTR(rc);
>>>>>>>            }
>>>>>>>
>>>>>>> +       if (dp_display->panel_bridge) {
>>>>>>> +               rc = drm_bridge_attach(dp_display->encoder,
>>>>>>> +                                       dp_display->panel_bridge,
>>>>>>> bridge,
>>>>>>> +                                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>>>>>>> +               if (rc < 0) {
>>>>>>> +                       DRM_ERROR("failed to attach panel bridge:
>>>>>>> %d\n", rc);
>>>>>>> +                       drm_bridge_remove(bridge);
>>>>>>> +                       return ERR_PTR(rc);
>>>>>>> +               }
>>>>>>> +       }
>>>>>>> +
>>>>>>>            return bridge;
>>>>>>
>>>>>> Not a problem with this patch, but what is this pointer used for? I see
>>>>>> it's assigned to priv->bridges and num_bridges is incremented but nobody
>>>>>> seems to look at that.
>>>>>
>>>>>
>>>>> That's on my todo list. to remove connectors array and to destroy
>>>>> created bridges during drm device destruction.
>>>>>
>>>
>>>
>>>
> 
> 
> 

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

* Re: [Freedreno] [RFC PATCH v2 1/5] drm/msm/dp: fix panel bridge attachment
@ 2022-02-25  4:45                 ` Abhinav Kumar
  0 siblings, 0 replies; 84+ messages in thread
From: Abhinav Kumar @ 2022-02-25  4:45 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: freedreno, David Airlie, linux-arm-msm, Stephen Boyd, dri-devel,
	Kuogee Hsieh, Bjorn Andersson, Sean Paul



On 2/24/2022 8:22 PM, Dmitry Baryshkov wrote:
> On Fri, 25 Feb 2022 at 05:01, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>>
>>
>>
>> On 2/24/2022 12:41 PM, Dmitry Baryshkov wrote:
>>> On Thu, 24 Feb 2022 at 21:25, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>>>>
>>>>
>>>>
>>>> On 2/18/2022 6:26 PM, Dmitry Baryshkov wrote:
>>>>> On 19/02/2022 02:56, Stephen Boyd wrote:
>>>>>> Quoting Dmitry Baryshkov (2022-02-11 14:40:02)
>>>>>>> In commit 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
>>>>>>> enable and disable") the DP driver received a drm_bridge instance, which
>>>>>>> is always attached to the encoder as a root bridge. However it conflicts
>>>>>>> with the panel_bridge support for eDP panels. The panel bridge attaches
>>>>>>> to the encoder before the "dp" bridge has a chace to do so. Change
>>>>>>
>>>>>> s/chace/chance/
>>>>>>
>>>>>>> panel_bridge attachment to come after dp_bridge attachment.
>>>>>>
>>>>>> s/panel_bridge/panel bridge/ possibly? And maybe clarify that dp_bridge
>>>>>> is the "DP driver's drm_bridge instance created in
>>>>>> msm_dp_bridge_init()"?
>>>>>>
>>>>>> My understanding is that we want to pass the bridge created in
>>>>>> msm_dp_bridge_init() as the 'previous' bridge so that it attaches the
>>>>>> panel bridge to the output of the DP bridge that's attached to the
>>>>>> encoder.
>>>>>
>>>>> Thanks! I'll update the commit log when pushing the patches.
>>>>
>>>> Please correct if i am missing something here.
>>>>
>>>> You are right that the eDP panel's panel bridge attaches to the encoder
>>>> in dp_drm_connector_init() which happens before msm_dp_bridge_init() and
>>>> hence it will attach directly to the encoder.
>>>>
>>>> But we are talking about different encoders here. DP's dp_display has a
>>>> different encoder compared to the EDP's dp_display.
>>>
>>> The encoders are different. However both encoders use the same
>>> codepath, which includes dp_bridge. It controls dp_display by calling
>>> msm_dp_display_foo() functions.
>>>
> 
>>>> So DP's bridge will still be attached to its encoder's root.
>>>
>>> There is one dp_bridge per each encoder. Consider sc8180x which has 3
>>> DP controllers (and thus 3 dp_bridges).
>>>
>>
>> Sorry, but I still didnt follow this.
>>
>> So for eDP, dp_drm_connector_init() will attach the panel_bridge
>> and then msm_dp_bridge_init() will add a drm_bridge.
>>
>> And yes in that case, the drm_bridge will be after the panel_bridge
>>
>> But since panel_bridge is at the root for eDP it should be okay.
> 
> No. It is not.
> For both DP and eDP the chain should be:
> dpu_encoder -> dp_bridge -> external (panel) bridge, optional for DP
> -> [other bridges] -> connector
> 
> Otherwise drm_bridge_chain_foo() functions would be called in the
> incorrect order.

Agreed. For drm_bridge_chain_foo() ordering to be correct, for eDP chain 
the order should be what you mentioned and panel_bridge should be at the 
end ( should be the last one ).

For the above reason,

Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>

I still didnt understand what gets affected by this for the 
msm_dp_display_foo() functions you mentioned earlier and wanted to get 
some clarity on that.
> 
> Thus the dp_bridge should be attached directly to the encoder
> (drm_encoder) and panel_bridge should use dp_bridge as the 'previous'
> bridge.
> 

Agreed.

> For example, for the DP port one can use a display-connector (which
> actually implements drm_bridge) as an external bridge to provide hpd
> or dp power GPIOs.
> 
> Note, that the current dp_connector breaks layering. It makes calls
> directly into dp_display, not allowing external bridge (and other
> bridges) to override get_modes/mode_valid and other callbacks.
> Thus one of the next patches in series (the one that Kuogee had issues
> with) tries to replace the chain with the following one:
> dpu_encoder -> dp_bridge -> external (panel) bridge -> [other bridges]
> -> drm_bridge_connector.
> 
>>

So originally the plan was always that the DP connector layer intercepts 
the call because panel-eDP file did not support reading of the EDID ( we 
have not provided the aux bus ). So it was intended that we did not want 
to goto the eDP panel to get the modes. Not an error but something which 
we wanted to cleanup later when we moved to panel-eDP completely.

Till then we wanted the dp_connector to read the EDID and get the modes.

So this was actually intended to happen till the point where we moved to 
panel-eDP to get the modes.

Hence what you have mentioned in your cover letter is right that the 
chain was broken but there was no loss of functionality due to that today.

Now that these changes are made, we can still goto panel-eDP file for 
the modes because of the below change from Sankeerth where the mode is 
hard-coded:

https://patchwork.freedesktop.org/patch/473431/

With this change cherry-picked it should work for kuogee. We will 
re-test that with this change.


>> Your commit text was mentioning about DP.
>>
>> For DP, for each controller in the catalog, we will call modeset_init()
>> which should skip this part for DP
>>
>>     if (dp_display->panel_bridge) {
>>           ret = drm_bridge_attach(dp_display->encoder,
>>                       dp_display->panel_bridge, NULL,
> 
> as you see, NULL is incorrect. It should be a pointer to dp_bridge instead
> 
>>                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>>           if (ret < 0) {
>>               DRM_ERROR("failed to attach panel bridge: %d\n", ret);
>>               return ERR_PTR(ret);
>>           }
>>       }
>>
>> Followed by calling msm_dp_bridge_init() which will actually attach the
>> bridge:
>>
>> drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> 
> And this bridge should be attached before the external bridge.
> 
>>
>> Now, even for 3 DP controllers, this shall be true as there will be 3
>> separate encoders and 3 dp_displays and hence 3 drm_bridges.
>>
>> What am i missing here?
>>
>>>>
>>>> So what are we achieving with this change?
>>>>
>>>>>
>>>>>>
>>>>>>>
>>>>>>> Fixes: 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
>>>>>>> enable and disable")
>>>>>>> Cc: Kuogee Hsieh <quic_khsieh@quicinc.com>
>>>>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>>>>>> ---
>>>>>>
>>>>>> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
>>>>>>
>>>>>>>     drivers/gpu/drm/msm/dp/dp_drm.c | 21 +++++++++++----------
>>>>>>>     1 file changed, 11 insertions(+), 10 deletions(-)
>>>>>>>
>>>>>>> diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c
>>>>>>> b/drivers/gpu/drm/msm/dp/dp_drm.c
>>>>>>> index d4d360d19eba..26ef41a4c1b6 100644
>>>>>>> --- a/drivers/gpu/drm/msm/dp/dp_drm.c
>>>>>>> +++ b/drivers/gpu/drm/msm/dp/dp_drm.c
>>>>>>> @@ -169,16 +169,6 @@ struct drm_connector
>>>>>>> *dp_drm_connector_init(struct msm_dp *dp_display)
>>>>>>>
>>>>>>>            drm_connector_attach_encoder(connector, dp_display->encoder);
>>>>>>>
>>>>>>> -       if (dp_display->panel_bridge) {
>>>>>>> -               ret = drm_bridge_attach(dp_display->encoder,
>>>>>>> -                                       dp_display->panel_bridge, NULL,
>>>>>>> -                                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>>>>>>> -               if (ret < 0) {
>>>>>>> -                       DRM_ERROR("failed to attach panel bridge:
>>>>>>> %d\n", ret);
>>>>>>> -                       return ERR_PTR(ret);
>>>>>>> -               }
>>>>>>> -       }
>>>>>>> -
>>>>>>>            return connector;
>>>>>>>     }
>>>>>>>
>>>>>>> @@ -246,5 +236,16 @@ struct drm_bridge *msm_dp_bridge_init(struct
>>>>>>> msm_dp *dp_display, struct drm_devi
>>>>>>>                    return ERR_PTR(rc);
>>>>>>>            }
>>>>>>>
>>>>>>> +       if (dp_display->panel_bridge) {
>>>>>>> +               rc = drm_bridge_attach(dp_display->encoder,
>>>>>>> +                                       dp_display->panel_bridge,
>>>>>>> bridge,
>>>>>>> +                                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>>>>>>> +               if (rc < 0) {
>>>>>>> +                       DRM_ERROR("failed to attach panel bridge:
>>>>>>> %d\n", rc);
>>>>>>> +                       drm_bridge_remove(bridge);
>>>>>>> +                       return ERR_PTR(rc);
>>>>>>> +               }
>>>>>>> +       }
>>>>>>> +
>>>>>>>            return bridge;
>>>>>>
>>>>>> Not a problem with this patch, but what is this pointer used for? I see
>>>>>> it's assigned to priv->bridges and num_bridges is incremented but nobody
>>>>>> seems to look at that.
>>>>>
>>>>>
>>>>> That's on my todo list. to remove connectors array and to destroy
>>>>> created bridges during drm device destruction.
>>>>>
>>>
>>>
>>>
> 
> 
> 

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

* Re: [Freedreno] [RFC PATCH v2 1/5] drm/msm/dp: fix panel bridge attachment
  2022-02-25  4:45                 ` Abhinav Kumar
@ 2022-02-25  9:04                   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 84+ messages in thread
From: Dmitry Baryshkov @ 2022-02-25  9:04 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: Stephen Boyd, Bjorn Andersson, Kuogee Hsieh, Rob Clark,
	Sean Paul, David Airlie, linux-arm-msm, freedreno, dri-devel,
	Daniel Vetter

On Fri, 25 Feb 2022 at 07:45, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>
>
>
> On 2/24/2022 8:22 PM, Dmitry Baryshkov wrote:
> > On Fri, 25 Feb 2022 at 05:01, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
> >>
> >>
> >>
> >> On 2/24/2022 12:41 PM, Dmitry Baryshkov wrote:
> >>> On Thu, 24 Feb 2022 at 21:25, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
> >>>>
> >>>>
> >>>>
> >>>> On 2/18/2022 6:26 PM, Dmitry Baryshkov wrote:
> >>>>> On 19/02/2022 02:56, Stephen Boyd wrote:
> >>>>>> Quoting Dmitry Baryshkov (2022-02-11 14:40:02)
> >>>>>>> In commit 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
> >>>>>>> enable and disable") the DP driver received a drm_bridge instance, which
> >>>>>>> is always attached to the encoder as a root bridge. However it conflicts
> >>>>>>> with the panel_bridge support for eDP panels. The panel bridge attaches
> >>>>>>> to the encoder before the "dp" bridge has a chace to do so. Change
> >>>>>>
> >>>>>> s/chace/chance/
> >>>>>>
> >>>>>>> panel_bridge attachment to come after dp_bridge attachment.
> >>>>>>
> >>>>>> s/panel_bridge/panel bridge/ possibly? And maybe clarify that dp_bridge
> >>>>>> is the "DP driver's drm_bridge instance created in
> >>>>>> msm_dp_bridge_init()"?
> >>>>>>
> >>>>>> My understanding is that we want to pass the bridge created in
> >>>>>> msm_dp_bridge_init() as the 'previous' bridge so that it attaches the
> >>>>>> panel bridge to the output of the DP bridge that's attached to the
> >>>>>> encoder.
> >>>>>
> >>>>> Thanks! I'll update the commit log when pushing the patches.
> >>>>
> >>>> Please correct if i am missing something here.
> >>>>
> >>>> You are right that the eDP panel's panel bridge attaches to the encoder
> >>>> in dp_drm_connector_init() which happens before msm_dp_bridge_init() and
> >>>> hence it will attach directly to the encoder.
> >>>>
> >>>> But we are talking about different encoders here. DP's dp_display has a
> >>>> different encoder compared to the EDP's dp_display.
> >>>
> >>> The encoders are different. However both encoders use the same
> >>> codepath, which includes dp_bridge. It controls dp_display by calling
> >>> msm_dp_display_foo() functions.
> >>>
> >
> >>>> So DP's bridge will still be attached to its encoder's root.
> >>>
> >>> There is one dp_bridge per each encoder. Consider sc8180x which has 3
> >>> DP controllers (and thus 3 dp_bridges).
> >>>
> >>
> >> Sorry, but I still didnt follow this.
> >>
> >> So for eDP, dp_drm_connector_init() will attach the panel_bridge
> >> and then msm_dp_bridge_init() will add a drm_bridge.
> >>
> >> And yes in that case, the drm_bridge will be after the panel_bridge
> >>
> >> But since panel_bridge is at the root for eDP it should be okay.
> >
> > No. It is not.
> > For both DP and eDP the chain should be:
> > dpu_encoder -> dp_bridge -> external (panel) bridge, optional for DP
> > -> [other bridges] -> connector
> >
> > Otherwise drm_bridge_chain_foo() functions would be called in the
> > incorrect order.
>
> Agreed. For drm_bridge_chain_foo() ordering to be correct, for eDP chain
> the order should be what you mentioned and panel_bridge should be at the
> end ( should be the last one ).
>
> For the above reason,
>
> Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
>
> I still didnt understand what gets affected by this for the
> msm_dp_display_foo() functions you mentioned earlier and wanted to get
> some clarity on that.

They should be called at the correct time.

> >
> > Thus the dp_bridge should be attached directly to the encoder
> > (drm_encoder) and panel_bridge should use dp_bridge as the 'previous'
> > bridge.
> >
>
> Agreed.
>
> > For example, for the DP port one can use a display-connector (which
> > actually implements drm_bridge) as an external bridge to provide hpd
> > or dp power GPIOs.
> >
> > Note, that the current dp_connector breaks layering. It makes calls
> > directly into dp_display, not allowing external bridge (and other
> > bridges) to override get_modes/mode_valid and other callbacks.
> > Thus one of the next patches in series (the one that Kuogee had issues
> > with) tries to replace the chain with the following one:
> > dpu_encoder -> dp_bridge -> external (panel) bridge -> [other bridges]
> > -> drm_bridge_connector.
> >
> >>
>
> So originally the plan was always that the DP connector layer intercepts
> the call because panel-eDP file did not support reading of the EDID ( we
> have not provided the aux bus ). So it was intended that we did not want
> to goto the eDP panel to get the modes. Not an error but something which
> we wanted to cleanup later when we moved to panel-eDP completely.

panel_edp_get_modes() correctly handles this case and returns modes
specified in the panel description. So the code should work even with
panel-eDP and w/o the AUX bus.

>
> Till then we wanted the dp_connector to read the EDID and get the modes.
>
> So this was actually intended to happen till the point where we moved to
> panel-eDP to get the modes.
>
> Hence what you have mentioned in your cover letter is right that the
> chain was broken but there was no loss of functionality due to that today.
>
> Now that these changes are made, we can still goto panel-eDP file for
> the modes because of the below change from Sankeerth where the mode is
> hard-coded:
>
> https://patchwork.freedesktop.org/patch/473431/
>
> With this change cherry-picked it should work for kuogee. We will
> re-test that with this change.

I suppose he had both of the changes in the tree. Otherwise the
panel_edp_get_modes() wouldn't be called.

> >> Your commit text was mentioning about DP.
> >>
> >> For DP, for each controller in the catalog, we will call modeset_init()
> >> which should skip this part for DP
> >>
> >>     if (dp_display->panel_bridge) {
> >>           ret = drm_bridge_attach(dp_display->encoder,
> >>                       dp_display->panel_bridge, NULL,
> >
> > as you see, NULL is incorrect. It should be a pointer to dp_bridge instead
> >
> >>                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> >>           if (ret < 0) {
> >>               DRM_ERROR("failed to attach panel bridge: %d\n", ret);
> >>               return ERR_PTR(ret);
> >>           }
> >>       }
> >>
> >> Followed by calling msm_dp_bridge_init() which will actually attach the
> >> bridge:
> >>
> >> drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> >
> > And this bridge should be attached before the external bridge.
> >
> >>
> >> Now, even for 3 DP controllers, this shall be true as there will be 3
> >> separate encoders and 3 dp_displays and hence 3 drm_bridges.
> >>
> >> What am i missing here?
> >>
> >>>>
> >>>> So what are we achieving with this change?
> >>>>
> >>>>>
> >>>>>>
> >>>>>>>
> >>>>>>> Fixes: 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
> >>>>>>> enable and disable")
> >>>>>>> Cc: Kuogee Hsieh <quic_khsieh@quicinc.com>
> >>>>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> >>>>>>> ---
> >>>>>>
> >>>>>> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
> >>>>>>
> >>>>>>>     drivers/gpu/drm/msm/dp/dp_drm.c | 21 +++++++++++----------
> >>>>>>>     1 file changed, 11 insertions(+), 10 deletions(-)
> >>>>>>>
> >>>>>>> diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c
> >>>>>>> b/drivers/gpu/drm/msm/dp/dp_drm.c
> >>>>>>> index d4d360d19eba..26ef41a4c1b6 100644
> >>>>>>> --- a/drivers/gpu/drm/msm/dp/dp_drm.c
> >>>>>>> +++ b/drivers/gpu/drm/msm/dp/dp_drm.c
> >>>>>>> @@ -169,16 +169,6 @@ struct drm_connector
> >>>>>>> *dp_drm_connector_init(struct msm_dp *dp_display)
> >>>>>>>
> >>>>>>>            drm_connector_attach_encoder(connector, dp_display->encoder);
> >>>>>>>
> >>>>>>> -       if (dp_display->panel_bridge) {
> >>>>>>> -               ret = drm_bridge_attach(dp_display->encoder,
> >>>>>>> -                                       dp_display->panel_bridge, NULL,
> >>>>>>> -                                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> >>>>>>> -               if (ret < 0) {
> >>>>>>> -                       DRM_ERROR("failed to attach panel bridge:
> >>>>>>> %d\n", ret);
> >>>>>>> -                       return ERR_PTR(ret);
> >>>>>>> -               }
> >>>>>>> -       }
> >>>>>>> -
> >>>>>>>            return connector;
> >>>>>>>     }
> >>>>>>>
> >>>>>>> @@ -246,5 +236,16 @@ struct drm_bridge *msm_dp_bridge_init(struct
> >>>>>>> msm_dp *dp_display, struct drm_devi
> >>>>>>>                    return ERR_PTR(rc);
> >>>>>>>            }
> >>>>>>>
> >>>>>>> +       if (dp_display->panel_bridge) {
> >>>>>>> +               rc = drm_bridge_attach(dp_display->encoder,
> >>>>>>> +                                       dp_display->panel_bridge,
> >>>>>>> bridge,
> >>>>>>> +                                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> >>>>>>> +               if (rc < 0) {
> >>>>>>> +                       DRM_ERROR("failed to attach panel bridge:
> >>>>>>> %d\n", rc);
> >>>>>>> +                       drm_bridge_remove(bridge);
> >>>>>>> +                       return ERR_PTR(rc);
> >>>>>>> +               }
> >>>>>>> +       }
> >>>>>>> +
> >>>>>>>            return bridge;
> >>>>>>
> >>>>>> Not a problem with this patch, but what is this pointer used for? I see
> >>>>>> it's assigned to priv->bridges and num_bridges is incremented but nobody
> >>>>>> seems to look at that.
> >>>>>
> >>>>>
> >>>>> That's on my todo list. to remove connectors array and to destroy
> >>>>> created bridges during drm device destruction.
> >>>>>
> >>>
> >>>
> >>>
> >
> >
> >



-- 
With best wishes
Dmitry

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

* Re: [Freedreno] [RFC PATCH v2 1/5] drm/msm/dp: fix panel bridge attachment
@ 2022-02-25  9:04                   ` Dmitry Baryshkov
  0 siblings, 0 replies; 84+ messages in thread
From: Dmitry Baryshkov @ 2022-02-25  9:04 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: freedreno, David Airlie, linux-arm-msm, Stephen Boyd, dri-devel,
	Kuogee Hsieh, Bjorn Andersson, Sean Paul

On Fri, 25 Feb 2022 at 07:45, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>
>
>
> On 2/24/2022 8:22 PM, Dmitry Baryshkov wrote:
> > On Fri, 25 Feb 2022 at 05:01, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
> >>
> >>
> >>
> >> On 2/24/2022 12:41 PM, Dmitry Baryshkov wrote:
> >>> On Thu, 24 Feb 2022 at 21:25, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
> >>>>
> >>>>
> >>>>
> >>>> On 2/18/2022 6:26 PM, Dmitry Baryshkov wrote:
> >>>>> On 19/02/2022 02:56, Stephen Boyd wrote:
> >>>>>> Quoting Dmitry Baryshkov (2022-02-11 14:40:02)
> >>>>>>> In commit 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
> >>>>>>> enable and disable") the DP driver received a drm_bridge instance, which
> >>>>>>> is always attached to the encoder as a root bridge. However it conflicts
> >>>>>>> with the panel_bridge support for eDP panels. The panel bridge attaches
> >>>>>>> to the encoder before the "dp" bridge has a chace to do so. Change
> >>>>>>
> >>>>>> s/chace/chance/
> >>>>>>
> >>>>>>> panel_bridge attachment to come after dp_bridge attachment.
> >>>>>>
> >>>>>> s/panel_bridge/panel bridge/ possibly? And maybe clarify that dp_bridge
> >>>>>> is the "DP driver's drm_bridge instance created in
> >>>>>> msm_dp_bridge_init()"?
> >>>>>>
> >>>>>> My understanding is that we want to pass the bridge created in
> >>>>>> msm_dp_bridge_init() as the 'previous' bridge so that it attaches the
> >>>>>> panel bridge to the output of the DP bridge that's attached to the
> >>>>>> encoder.
> >>>>>
> >>>>> Thanks! I'll update the commit log when pushing the patches.
> >>>>
> >>>> Please correct if i am missing something here.
> >>>>
> >>>> You are right that the eDP panel's panel bridge attaches to the encoder
> >>>> in dp_drm_connector_init() which happens before msm_dp_bridge_init() and
> >>>> hence it will attach directly to the encoder.
> >>>>
> >>>> But we are talking about different encoders here. DP's dp_display has a
> >>>> different encoder compared to the EDP's dp_display.
> >>>
> >>> The encoders are different. However both encoders use the same
> >>> codepath, which includes dp_bridge. It controls dp_display by calling
> >>> msm_dp_display_foo() functions.
> >>>
> >
> >>>> So DP's bridge will still be attached to its encoder's root.
> >>>
> >>> There is one dp_bridge per each encoder. Consider sc8180x which has 3
> >>> DP controllers (and thus 3 dp_bridges).
> >>>
> >>
> >> Sorry, but I still didnt follow this.
> >>
> >> So for eDP, dp_drm_connector_init() will attach the panel_bridge
> >> and then msm_dp_bridge_init() will add a drm_bridge.
> >>
> >> And yes in that case, the drm_bridge will be after the panel_bridge
> >>
> >> But since panel_bridge is at the root for eDP it should be okay.
> >
> > No. It is not.
> > For both DP and eDP the chain should be:
> > dpu_encoder -> dp_bridge -> external (panel) bridge, optional for DP
> > -> [other bridges] -> connector
> >
> > Otherwise drm_bridge_chain_foo() functions would be called in the
> > incorrect order.
>
> Agreed. For drm_bridge_chain_foo() ordering to be correct, for eDP chain
> the order should be what you mentioned and panel_bridge should be at the
> end ( should be the last one ).
>
> For the above reason,
>
> Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
>
> I still didnt understand what gets affected by this for the
> msm_dp_display_foo() functions you mentioned earlier and wanted to get
> some clarity on that.

They should be called at the correct time.

> >
> > Thus the dp_bridge should be attached directly to the encoder
> > (drm_encoder) and panel_bridge should use dp_bridge as the 'previous'
> > bridge.
> >
>
> Agreed.
>
> > For example, for the DP port one can use a display-connector (which
> > actually implements drm_bridge) as an external bridge to provide hpd
> > or dp power GPIOs.
> >
> > Note, that the current dp_connector breaks layering. It makes calls
> > directly into dp_display, not allowing external bridge (and other
> > bridges) to override get_modes/mode_valid and other callbacks.
> > Thus one of the next patches in series (the one that Kuogee had issues
> > with) tries to replace the chain with the following one:
> > dpu_encoder -> dp_bridge -> external (panel) bridge -> [other bridges]
> > -> drm_bridge_connector.
> >
> >>
>
> So originally the plan was always that the DP connector layer intercepts
> the call because panel-eDP file did not support reading of the EDID ( we
> have not provided the aux bus ). So it was intended that we did not want
> to goto the eDP panel to get the modes. Not an error but something which
> we wanted to cleanup later when we moved to panel-eDP completely.

panel_edp_get_modes() correctly handles this case and returns modes
specified in the panel description. So the code should work even with
panel-eDP and w/o the AUX bus.

>
> Till then we wanted the dp_connector to read the EDID and get the modes.
>
> So this was actually intended to happen till the point where we moved to
> panel-eDP to get the modes.
>
> Hence what you have mentioned in your cover letter is right that the
> chain was broken but there was no loss of functionality due to that today.
>
> Now that these changes are made, we can still goto panel-eDP file for
> the modes because of the below change from Sankeerth where the mode is
> hard-coded:
>
> https://patchwork.freedesktop.org/patch/473431/
>
> With this change cherry-picked it should work for kuogee. We will
> re-test that with this change.

I suppose he had both of the changes in the tree. Otherwise the
panel_edp_get_modes() wouldn't be called.

> >> Your commit text was mentioning about DP.
> >>
> >> For DP, for each controller in the catalog, we will call modeset_init()
> >> which should skip this part for DP
> >>
> >>     if (dp_display->panel_bridge) {
> >>           ret = drm_bridge_attach(dp_display->encoder,
> >>                       dp_display->panel_bridge, NULL,
> >
> > as you see, NULL is incorrect. It should be a pointer to dp_bridge instead
> >
> >>                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> >>           if (ret < 0) {
> >>               DRM_ERROR("failed to attach panel bridge: %d\n", ret);
> >>               return ERR_PTR(ret);
> >>           }
> >>       }
> >>
> >> Followed by calling msm_dp_bridge_init() which will actually attach the
> >> bridge:
> >>
> >> drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> >
> > And this bridge should be attached before the external bridge.
> >
> >>
> >> Now, even for 3 DP controllers, this shall be true as there will be 3
> >> separate encoders and 3 dp_displays and hence 3 drm_bridges.
> >>
> >> What am i missing here?
> >>
> >>>>
> >>>> So what are we achieving with this change?
> >>>>
> >>>>>
> >>>>>>
> >>>>>>>
> >>>>>>> Fixes: 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
> >>>>>>> enable and disable")
> >>>>>>> Cc: Kuogee Hsieh <quic_khsieh@quicinc.com>
> >>>>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> >>>>>>> ---
> >>>>>>
> >>>>>> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
> >>>>>>
> >>>>>>>     drivers/gpu/drm/msm/dp/dp_drm.c | 21 +++++++++++----------
> >>>>>>>     1 file changed, 11 insertions(+), 10 deletions(-)
> >>>>>>>
> >>>>>>> diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c
> >>>>>>> b/drivers/gpu/drm/msm/dp/dp_drm.c
> >>>>>>> index d4d360d19eba..26ef41a4c1b6 100644
> >>>>>>> --- a/drivers/gpu/drm/msm/dp/dp_drm.c
> >>>>>>> +++ b/drivers/gpu/drm/msm/dp/dp_drm.c
> >>>>>>> @@ -169,16 +169,6 @@ struct drm_connector
> >>>>>>> *dp_drm_connector_init(struct msm_dp *dp_display)
> >>>>>>>
> >>>>>>>            drm_connector_attach_encoder(connector, dp_display->encoder);
> >>>>>>>
> >>>>>>> -       if (dp_display->panel_bridge) {
> >>>>>>> -               ret = drm_bridge_attach(dp_display->encoder,
> >>>>>>> -                                       dp_display->panel_bridge, NULL,
> >>>>>>> -                                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> >>>>>>> -               if (ret < 0) {
> >>>>>>> -                       DRM_ERROR("failed to attach panel bridge:
> >>>>>>> %d\n", ret);
> >>>>>>> -                       return ERR_PTR(ret);
> >>>>>>> -               }
> >>>>>>> -       }
> >>>>>>> -
> >>>>>>>            return connector;
> >>>>>>>     }
> >>>>>>>
> >>>>>>> @@ -246,5 +236,16 @@ struct drm_bridge *msm_dp_bridge_init(struct
> >>>>>>> msm_dp *dp_display, struct drm_devi
> >>>>>>>                    return ERR_PTR(rc);
> >>>>>>>            }
> >>>>>>>
> >>>>>>> +       if (dp_display->panel_bridge) {
> >>>>>>> +               rc = drm_bridge_attach(dp_display->encoder,
> >>>>>>> +                                       dp_display->panel_bridge,
> >>>>>>> bridge,
> >>>>>>> +                                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> >>>>>>> +               if (rc < 0) {
> >>>>>>> +                       DRM_ERROR("failed to attach panel bridge:
> >>>>>>> %d\n", rc);
> >>>>>>> +                       drm_bridge_remove(bridge);
> >>>>>>> +                       return ERR_PTR(rc);
> >>>>>>> +               }
> >>>>>>> +       }
> >>>>>>> +
> >>>>>>>            return bridge;
> >>>>>>
> >>>>>> Not a problem with this patch, but what is this pointer used for? I see
> >>>>>> it's assigned to priv->bridges and num_bridges is incremented but nobody
> >>>>>> seems to look at that.
> >>>>>
> >>>>>
> >>>>> That's on my todo list. to remove connectors array and to destroy
> >>>>> created bridges during drm device destruction.
> >>>>>
> >>>
> >>>
> >>>
> >
> >
> >



-- 
With best wishes
Dmitry

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

* Re: [Freedreno] [RFC PATCH v2 1/5] drm/msm/dp: fix panel bridge attachment
  2022-02-25  9:04                   ` Dmitry Baryshkov
@ 2022-02-25 17:11                     ` Abhinav Kumar
  -1 siblings, 0 replies; 84+ messages in thread
From: Abhinav Kumar @ 2022-02-25 17:11 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Stephen Boyd, Bjorn Andersson, Kuogee Hsieh, Rob Clark,
	Sean Paul, David Airlie, linux-arm-msm, freedreno, dri-devel,
	Daniel Vetter



On 2/25/2022 1:04 AM, Dmitry Baryshkov wrote:
> On Fri, 25 Feb 2022 at 07:45, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>>
>>
>>
>> On 2/24/2022 8:22 PM, Dmitry Baryshkov wrote:
>>> On Fri, 25 Feb 2022 at 05:01, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>>>>
>>>>
>>>>
>>>> On 2/24/2022 12:41 PM, Dmitry Baryshkov wrote:
>>>>> On Thu, 24 Feb 2022 at 21:25, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>> On 2/18/2022 6:26 PM, Dmitry Baryshkov wrote:
>>>>>>> On 19/02/2022 02:56, Stephen Boyd wrote:
>>>>>>>> Quoting Dmitry Baryshkov (2022-02-11 14:40:02)
>>>>>>>>> In commit 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
>>>>>>>>> enable and disable") the DP driver received a drm_bridge instance, which
>>>>>>>>> is always attached to the encoder as a root bridge. However it conflicts
>>>>>>>>> with the panel_bridge support for eDP panels. The panel bridge attaches
>>>>>>>>> to the encoder before the "dp" bridge has a chace to do so. Change
>>>>>>>>
>>>>>>>> s/chace/chance/
>>>>>>>>
>>>>>>>>> panel_bridge attachment to come after dp_bridge attachment.
>>>>>>>>
>>>>>>>> s/panel_bridge/panel bridge/ possibly? And maybe clarify that dp_bridge
>>>>>>>> is the "DP driver's drm_bridge instance created in
>>>>>>>> msm_dp_bridge_init()"?
>>>>>>>>
>>>>>>>> My understanding is that we want to pass the bridge created in
>>>>>>>> msm_dp_bridge_init() as the 'previous' bridge so that it attaches the
>>>>>>>> panel bridge to the output of the DP bridge that's attached to the
>>>>>>>> encoder.
>>>>>>>
>>>>>>> Thanks! I'll update the commit log when pushing the patches.
>>>>>>
>>>>>> Please correct if i am missing something here.
>>>>>>
>>>>>> You are right that the eDP panel's panel bridge attaches to the encoder
>>>>>> in dp_drm_connector_init() which happens before msm_dp_bridge_init() and
>>>>>> hence it will attach directly to the encoder.
>>>>>>
>>>>>> But we are talking about different encoders here. DP's dp_display has a
>>>>>> different encoder compared to the EDP's dp_display.
>>>>>
>>>>> The encoders are different. However both encoders use the same
>>>>> codepath, which includes dp_bridge. It controls dp_display by calling
>>>>> msm_dp_display_foo() functions.
>>>>>
>>>
>>>>>> So DP's bridge will still be attached to its encoder's root.
>>>>>
>>>>> There is one dp_bridge per each encoder. Consider sc8180x which has 3
>>>>> DP controllers (and thus 3 dp_bridges).
>>>>>
>>>>
>>>> Sorry, but I still didnt follow this.
>>>>
>>>> So for eDP, dp_drm_connector_init() will attach the panel_bridge
>>>> and then msm_dp_bridge_init() will add a drm_bridge.
>>>>
>>>> And yes in that case, the drm_bridge will be after the panel_bridge
>>>>
>>>> But since panel_bridge is at the root for eDP it should be okay.
>>>
>>> No. It is not.
>>> For both DP and eDP the chain should be:
>>> dpu_encoder -> dp_bridge -> external (panel) bridge, optional for DP
>>> -> [other bridges] -> connector
>>>
>>> Otherwise drm_bridge_chain_foo() functions would be called in the
>>> incorrect order.
>>
>> Agreed. For drm_bridge_chain_foo() ordering to be correct, for eDP chain
>> the order should be what you mentioned and panel_bridge should be at the
>> end ( should be the last one ).
>>
>> For the above reason,
>>
>> Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
>>
>> I still didnt understand what gets affected by this for the
>> msm_dp_display_foo() functions you mentioned earlier and wanted to get
>> some clarity on that.
> 
> They should be called at the correct time.
> 
>>>
>>> Thus the dp_bridge should be attached directly to the encoder
>>> (drm_encoder) and panel_bridge should use dp_bridge as the 'previous'
>>> bridge.
>>>
>>
>> Agreed.
>>
>>> For example, for the DP port one can use a display-connector (which
>>> actually implements drm_bridge) as an external bridge to provide hpd
>>> or dp power GPIOs.
>>>
>>> Note, that the current dp_connector breaks layering. It makes calls
>>> directly into dp_display, not allowing external bridge (and other
>>> bridges) to override get_modes/mode_valid and other callbacks.
>>> Thus one of the next patches in series (the one that Kuogee had issues
>>> with) tries to replace the chain with the following one:
>>> dpu_encoder -> dp_bridge -> external (panel) bridge -> [other bridges]
>>> -> drm_bridge_connector.
>>>
>>>>
>>
>> So originally the plan was always that the DP connector layer intercepts
>> the call because panel-eDP file did not support reading of the EDID ( we
>> have not provided the aux bus ). So it was intended that we did not want
>> to goto the eDP panel to get the modes. Not an error but something which
>> we wanted to cleanup later when we moved to panel-eDP completely.
> 
> panel_edp_get_modes() correctly handles this case and returns modes
> specified in the panel description. So the code should work even with
> panel-eDP and w/o the AUX bus.
> 

If hard-coded modes are not present, it will fail in below case:

     /*
      * Add hard-coded panel modes. Don't call this if there are no timings
      * and no modes (the generic edp-panel case) because it will clobber
      * the display_info that was already set by drm_add_edid_modes().
      */
     if (p->desc->num_timings || p->desc->num_modes)
         num += panel_edp_get_non_edid_modes(p, connector);
     else if (!num)
         dev_warn(p->base.dev, "No display modes\n");

Thats exactly the error he was seeing.

>>
>> Till then we wanted the dp_connector to read the EDID and get the modes.
>>
>> So this was actually intended to happen till the point where we moved to
>> panel-eDP to get the modes.
>>
>> Hence what you have mentioned in your cover letter is right that the
>> chain was broken but there was no loss of functionality due to that today.
>>
>> Now that these changes are made, we can still goto panel-eDP file for
>> the modes because of the below change from Sankeerth where the mode is
>> hard-coded:
>>
>> https://patchwork.freedesktop.org/patch/473431/
>>
>> With this change cherry-picked it should work for kuogee. We will
>> re-test that with this change.
> 
> I suppose he had both of the changes in the tree. Otherwise the
> panel_edp_get_modes() wouldn't be called.

No he did not.

That brings up another point.

Even Bjorn was relying on the DP connector's get_modes() for his eDP 
panel if I am not mistaken.

Unless he makes an equivalent change for his panel OR supports reading 
EDID in panel-edp, then he will hit the same error.

Given that your changes were only compile tested, lets wait for both 
Kuogee and Bjorn to validate their resp setups.

> 
>>>> Your commit text was mentioning about DP.
>>>>
>>>> For DP, for each controller in the catalog, we will call modeset_init()
>>>> which should skip this part for DP
>>>>
>>>>      if (dp_display->panel_bridge) {
>>>>            ret = drm_bridge_attach(dp_display->encoder,
>>>>                        dp_display->panel_bridge, NULL,
>>>
>>> as you see, NULL is incorrect. It should be a pointer to dp_bridge instead
>>>
>>>>                        DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>>>>            if (ret < 0) {
>>>>                DRM_ERROR("failed to attach panel bridge: %d\n", ret);
>>>>                return ERR_PTR(ret);
>>>>            }
>>>>        }
>>>>
>>>> Followed by calling msm_dp_bridge_init() which will actually attach the
>>>> bridge:
>>>>
>>>> drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>>>
>>> And this bridge should be attached before the external bridge.
>>>
>>>>
>>>> Now, even for 3 DP controllers, this shall be true as there will be 3
>>>> separate encoders and 3 dp_displays and hence 3 drm_bridges.
>>>>
>>>> What am i missing here?
>>>>
>>>>>>
>>>>>> So what are we achieving with this change?
>>>>>>
>>>>>>>
>>>>>>>>
>>>>>>>>>
>>>>>>>>> Fixes: 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
>>>>>>>>> enable and disable")
>>>>>>>>> Cc: Kuogee Hsieh <quic_khsieh@quicinc.com>
>>>>>>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>>>>>>>> ---
>>>>>>>>
>>>>>>>> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
>>>>>>>>
>>>>>>>>>      drivers/gpu/drm/msm/dp/dp_drm.c | 21 +++++++++++----------
>>>>>>>>>      1 file changed, 11 insertions(+), 10 deletions(-)
>>>>>>>>>
>>>>>>>>> diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c
>>>>>>>>> b/drivers/gpu/drm/msm/dp/dp_drm.c
>>>>>>>>> index d4d360d19eba..26ef41a4c1b6 100644
>>>>>>>>> --- a/drivers/gpu/drm/msm/dp/dp_drm.c
>>>>>>>>> +++ b/drivers/gpu/drm/msm/dp/dp_drm.c
>>>>>>>>> @@ -169,16 +169,6 @@ struct drm_connector
>>>>>>>>> *dp_drm_connector_init(struct msm_dp *dp_display)
>>>>>>>>>
>>>>>>>>>             drm_connector_attach_encoder(connector, dp_display->encoder);
>>>>>>>>>
>>>>>>>>> -       if (dp_display->panel_bridge) {
>>>>>>>>> -               ret = drm_bridge_attach(dp_display->encoder,
>>>>>>>>> -                                       dp_display->panel_bridge, NULL,
>>>>>>>>> -                                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>>>>>>>>> -               if (ret < 0) {
>>>>>>>>> -                       DRM_ERROR("failed to attach panel bridge:
>>>>>>>>> %d\n", ret);
>>>>>>>>> -                       return ERR_PTR(ret);
>>>>>>>>> -               }
>>>>>>>>> -       }
>>>>>>>>> -
>>>>>>>>>             return connector;
>>>>>>>>>      }
>>>>>>>>>
>>>>>>>>> @@ -246,5 +236,16 @@ struct drm_bridge *msm_dp_bridge_init(struct
>>>>>>>>> msm_dp *dp_display, struct drm_devi
>>>>>>>>>                     return ERR_PTR(rc);
>>>>>>>>>             }
>>>>>>>>>
>>>>>>>>> +       if (dp_display->panel_bridge) {
>>>>>>>>> +               rc = drm_bridge_attach(dp_display->encoder,
>>>>>>>>> +                                       dp_display->panel_bridge,
>>>>>>>>> bridge,
>>>>>>>>> +                                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>>>>>>>>> +               if (rc < 0) {
>>>>>>>>> +                       DRM_ERROR("failed to attach panel bridge:
>>>>>>>>> %d\n", rc);
>>>>>>>>> +                       drm_bridge_remove(bridge);
>>>>>>>>> +                       return ERR_PTR(rc);
>>>>>>>>> +               }
>>>>>>>>> +       }
>>>>>>>>> +
>>>>>>>>>             return bridge;
>>>>>>>>
>>>>>>>> Not a problem with this patch, but what is this pointer used for? I see
>>>>>>>> it's assigned to priv->bridges and num_bridges is incremented but nobody
>>>>>>>> seems to look at that.
>>>>>>>
>>>>>>>
>>>>>>> That's on my todo list. to remove connectors array and to destroy
>>>>>>> created bridges during drm device destruction.
>>>>>>>
>>>>>
>>>>>
>>>>>
>>>
>>>
>>>
> 
> 
> 

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

* Re: [Freedreno] [RFC PATCH v2 1/5] drm/msm/dp: fix panel bridge attachment
@ 2022-02-25 17:11                     ` Abhinav Kumar
  0 siblings, 0 replies; 84+ messages in thread
From: Abhinav Kumar @ 2022-02-25 17:11 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: freedreno, David Airlie, linux-arm-msm, Stephen Boyd, dri-devel,
	Kuogee Hsieh, Bjorn Andersson, Sean Paul



On 2/25/2022 1:04 AM, Dmitry Baryshkov wrote:
> On Fri, 25 Feb 2022 at 07:45, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>>
>>
>>
>> On 2/24/2022 8:22 PM, Dmitry Baryshkov wrote:
>>> On Fri, 25 Feb 2022 at 05:01, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>>>>
>>>>
>>>>
>>>> On 2/24/2022 12:41 PM, Dmitry Baryshkov wrote:
>>>>> On Thu, 24 Feb 2022 at 21:25, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>> On 2/18/2022 6:26 PM, Dmitry Baryshkov wrote:
>>>>>>> On 19/02/2022 02:56, Stephen Boyd wrote:
>>>>>>>> Quoting Dmitry Baryshkov (2022-02-11 14:40:02)
>>>>>>>>> In commit 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
>>>>>>>>> enable and disable") the DP driver received a drm_bridge instance, which
>>>>>>>>> is always attached to the encoder as a root bridge. However it conflicts
>>>>>>>>> with the panel_bridge support for eDP panels. The panel bridge attaches
>>>>>>>>> to the encoder before the "dp" bridge has a chace to do so. Change
>>>>>>>>
>>>>>>>> s/chace/chance/
>>>>>>>>
>>>>>>>>> panel_bridge attachment to come after dp_bridge attachment.
>>>>>>>>
>>>>>>>> s/panel_bridge/panel bridge/ possibly? And maybe clarify that dp_bridge
>>>>>>>> is the "DP driver's drm_bridge instance created in
>>>>>>>> msm_dp_bridge_init()"?
>>>>>>>>
>>>>>>>> My understanding is that we want to pass the bridge created in
>>>>>>>> msm_dp_bridge_init() as the 'previous' bridge so that it attaches the
>>>>>>>> panel bridge to the output of the DP bridge that's attached to the
>>>>>>>> encoder.
>>>>>>>
>>>>>>> Thanks! I'll update the commit log when pushing the patches.
>>>>>>
>>>>>> Please correct if i am missing something here.
>>>>>>
>>>>>> You are right that the eDP panel's panel bridge attaches to the encoder
>>>>>> in dp_drm_connector_init() which happens before msm_dp_bridge_init() and
>>>>>> hence it will attach directly to the encoder.
>>>>>>
>>>>>> But we are talking about different encoders here. DP's dp_display has a
>>>>>> different encoder compared to the EDP's dp_display.
>>>>>
>>>>> The encoders are different. However both encoders use the same
>>>>> codepath, which includes dp_bridge. It controls dp_display by calling
>>>>> msm_dp_display_foo() functions.
>>>>>
>>>
>>>>>> So DP's bridge will still be attached to its encoder's root.
>>>>>
>>>>> There is one dp_bridge per each encoder. Consider sc8180x which has 3
>>>>> DP controllers (and thus 3 dp_bridges).
>>>>>
>>>>
>>>> Sorry, but I still didnt follow this.
>>>>
>>>> So for eDP, dp_drm_connector_init() will attach the panel_bridge
>>>> and then msm_dp_bridge_init() will add a drm_bridge.
>>>>
>>>> And yes in that case, the drm_bridge will be after the panel_bridge
>>>>
>>>> But since panel_bridge is at the root for eDP it should be okay.
>>>
>>> No. It is not.
>>> For both DP and eDP the chain should be:
>>> dpu_encoder -> dp_bridge -> external (panel) bridge, optional for DP
>>> -> [other bridges] -> connector
>>>
>>> Otherwise drm_bridge_chain_foo() functions would be called in the
>>> incorrect order.
>>
>> Agreed. For drm_bridge_chain_foo() ordering to be correct, for eDP chain
>> the order should be what you mentioned and panel_bridge should be at the
>> end ( should be the last one ).
>>
>> For the above reason,
>>
>> Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
>>
>> I still didnt understand what gets affected by this for the
>> msm_dp_display_foo() functions you mentioned earlier and wanted to get
>> some clarity on that.
> 
> They should be called at the correct time.
> 
>>>
>>> Thus the dp_bridge should be attached directly to the encoder
>>> (drm_encoder) and panel_bridge should use dp_bridge as the 'previous'
>>> bridge.
>>>
>>
>> Agreed.
>>
>>> For example, for the DP port one can use a display-connector (which
>>> actually implements drm_bridge) as an external bridge to provide hpd
>>> or dp power GPIOs.
>>>
>>> Note, that the current dp_connector breaks layering. It makes calls
>>> directly into dp_display, not allowing external bridge (and other
>>> bridges) to override get_modes/mode_valid and other callbacks.
>>> Thus one of the next patches in series (the one that Kuogee had issues
>>> with) tries to replace the chain with the following one:
>>> dpu_encoder -> dp_bridge -> external (panel) bridge -> [other bridges]
>>> -> drm_bridge_connector.
>>>
>>>>
>>
>> So originally the plan was always that the DP connector layer intercepts
>> the call because panel-eDP file did not support reading of the EDID ( we
>> have not provided the aux bus ). So it was intended that we did not want
>> to goto the eDP panel to get the modes. Not an error but something which
>> we wanted to cleanup later when we moved to panel-eDP completely.
> 
> panel_edp_get_modes() correctly handles this case and returns modes
> specified in the panel description. So the code should work even with
> panel-eDP and w/o the AUX bus.
> 

If hard-coded modes are not present, it will fail in below case:

     /*
      * Add hard-coded panel modes. Don't call this if there are no timings
      * and no modes (the generic edp-panel case) because it will clobber
      * the display_info that was already set by drm_add_edid_modes().
      */
     if (p->desc->num_timings || p->desc->num_modes)
         num += panel_edp_get_non_edid_modes(p, connector);
     else if (!num)
         dev_warn(p->base.dev, "No display modes\n");

Thats exactly the error he was seeing.

>>
>> Till then we wanted the dp_connector to read the EDID and get the modes.
>>
>> So this was actually intended to happen till the point where we moved to
>> panel-eDP to get the modes.
>>
>> Hence what you have mentioned in your cover letter is right that the
>> chain was broken but there was no loss of functionality due to that today.
>>
>> Now that these changes are made, we can still goto panel-eDP file for
>> the modes because of the below change from Sankeerth where the mode is
>> hard-coded:
>>
>> https://patchwork.freedesktop.org/patch/473431/
>>
>> With this change cherry-picked it should work for kuogee. We will
>> re-test that with this change.
> 
> I suppose he had both of the changes in the tree. Otherwise the
> panel_edp_get_modes() wouldn't be called.

No he did not.

That brings up another point.

Even Bjorn was relying on the DP connector's get_modes() for his eDP 
panel if I am not mistaken.

Unless he makes an equivalent change for his panel OR supports reading 
EDID in panel-edp, then he will hit the same error.

Given that your changes were only compile tested, lets wait for both 
Kuogee and Bjorn to validate their resp setups.

> 
>>>> Your commit text was mentioning about DP.
>>>>
>>>> For DP, for each controller in the catalog, we will call modeset_init()
>>>> which should skip this part for DP
>>>>
>>>>      if (dp_display->panel_bridge) {
>>>>            ret = drm_bridge_attach(dp_display->encoder,
>>>>                        dp_display->panel_bridge, NULL,
>>>
>>> as you see, NULL is incorrect. It should be a pointer to dp_bridge instead
>>>
>>>>                        DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>>>>            if (ret < 0) {
>>>>                DRM_ERROR("failed to attach panel bridge: %d\n", ret);
>>>>                return ERR_PTR(ret);
>>>>            }
>>>>        }
>>>>
>>>> Followed by calling msm_dp_bridge_init() which will actually attach the
>>>> bridge:
>>>>
>>>> drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>>>
>>> And this bridge should be attached before the external bridge.
>>>
>>>>
>>>> Now, even for 3 DP controllers, this shall be true as there will be 3
>>>> separate encoders and 3 dp_displays and hence 3 drm_bridges.
>>>>
>>>> What am i missing here?
>>>>
>>>>>>
>>>>>> So what are we achieving with this change?
>>>>>>
>>>>>>>
>>>>>>>>
>>>>>>>>>
>>>>>>>>> Fixes: 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
>>>>>>>>> enable and disable")
>>>>>>>>> Cc: Kuogee Hsieh <quic_khsieh@quicinc.com>
>>>>>>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>>>>>>>> ---
>>>>>>>>
>>>>>>>> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
>>>>>>>>
>>>>>>>>>      drivers/gpu/drm/msm/dp/dp_drm.c | 21 +++++++++++----------
>>>>>>>>>      1 file changed, 11 insertions(+), 10 deletions(-)
>>>>>>>>>
>>>>>>>>> diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c
>>>>>>>>> b/drivers/gpu/drm/msm/dp/dp_drm.c
>>>>>>>>> index d4d360d19eba..26ef41a4c1b6 100644
>>>>>>>>> --- a/drivers/gpu/drm/msm/dp/dp_drm.c
>>>>>>>>> +++ b/drivers/gpu/drm/msm/dp/dp_drm.c
>>>>>>>>> @@ -169,16 +169,6 @@ struct drm_connector
>>>>>>>>> *dp_drm_connector_init(struct msm_dp *dp_display)
>>>>>>>>>
>>>>>>>>>             drm_connector_attach_encoder(connector, dp_display->encoder);
>>>>>>>>>
>>>>>>>>> -       if (dp_display->panel_bridge) {
>>>>>>>>> -               ret = drm_bridge_attach(dp_display->encoder,
>>>>>>>>> -                                       dp_display->panel_bridge, NULL,
>>>>>>>>> -                                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>>>>>>>>> -               if (ret < 0) {
>>>>>>>>> -                       DRM_ERROR("failed to attach panel bridge:
>>>>>>>>> %d\n", ret);
>>>>>>>>> -                       return ERR_PTR(ret);
>>>>>>>>> -               }
>>>>>>>>> -       }
>>>>>>>>> -
>>>>>>>>>             return connector;
>>>>>>>>>      }
>>>>>>>>>
>>>>>>>>> @@ -246,5 +236,16 @@ struct drm_bridge *msm_dp_bridge_init(struct
>>>>>>>>> msm_dp *dp_display, struct drm_devi
>>>>>>>>>                     return ERR_PTR(rc);
>>>>>>>>>             }
>>>>>>>>>
>>>>>>>>> +       if (dp_display->panel_bridge) {
>>>>>>>>> +               rc = drm_bridge_attach(dp_display->encoder,
>>>>>>>>> +                                       dp_display->panel_bridge,
>>>>>>>>> bridge,
>>>>>>>>> +                                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>>>>>>>>> +               if (rc < 0) {
>>>>>>>>> +                       DRM_ERROR("failed to attach panel bridge:
>>>>>>>>> %d\n", rc);
>>>>>>>>> +                       drm_bridge_remove(bridge);
>>>>>>>>> +                       return ERR_PTR(rc);
>>>>>>>>> +               }
>>>>>>>>> +       }
>>>>>>>>> +
>>>>>>>>>             return bridge;
>>>>>>>>
>>>>>>>> Not a problem with this patch, but what is this pointer used for? I see
>>>>>>>> it's assigned to priv->bridges and num_bridges is incremented but nobody
>>>>>>>> seems to look at that.
>>>>>>>
>>>>>>>
>>>>>>> That's on my todo list. to remove connectors array and to destroy
>>>>>>> created bridges during drm device destruction.
>>>>>>>
>>>>>
>>>>>
>>>>>
>>>
>>>
>>>
> 
> 
> 

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

* Re: [Freedreno] [RFC PATCH v2 1/5] drm/msm/dp: fix panel bridge attachment
  2022-02-25 17:11                     ` Abhinav Kumar
@ 2022-02-25 17:25                       ` Dmitry Baryshkov
  -1 siblings, 0 replies; 84+ messages in thread
From: Dmitry Baryshkov @ 2022-02-25 17:25 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: Stephen Boyd, Bjorn Andersson, Kuogee Hsieh, Rob Clark,
	Sean Paul, David Airlie, linux-arm-msm, freedreno, dri-devel,
	Daniel Vetter

On Fri, 25 Feb 2022 at 20:11, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>
>
>
> On 2/25/2022 1:04 AM, Dmitry Baryshkov wrote:
> > On Fri, 25 Feb 2022 at 07:45, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
> >>
> >>
> >>
> >> On 2/24/2022 8:22 PM, Dmitry Baryshkov wrote:
> >>> On Fri, 25 Feb 2022 at 05:01, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
> >>>>
> >>>>
> >>>>
> >>>> On 2/24/2022 12:41 PM, Dmitry Baryshkov wrote:
> >>>>> On Thu, 24 Feb 2022 at 21:25, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>> On 2/18/2022 6:26 PM, Dmitry Baryshkov wrote:
> >>>>>>> On 19/02/2022 02:56, Stephen Boyd wrote:
> >>>>>>>> Quoting Dmitry Baryshkov (2022-02-11 14:40:02)
> >>>>>>>>> In commit 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
> >>>>>>>>> enable and disable") the DP driver received a drm_bridge instance, which
> >>>>>>>>> is always attached to the encoder as a root bridge. However it conflicts
> >>>>>>>>> with the panel_bridge support for eDP panels. The panel bridge attaches
> >>>>>>>>> to the encoder before the "dp" bridge has a chace to do so. Change
> >>>>>>>>
> >>>>>>>> s/chace/chance/
> >>>>>>>>
> >>>>>>>>> panel_bridge attachment to come after dp_bridge attachment.
> >>>>>>>>
> >>>>>>>> s/panel_bridge/panel bridge/ possibly? And maybe clarify that dp_bridge
> >>>>>>>> is the "DP driver's drm_bridge instance created in
> >>>>>>>> msm_dp_bridge_init()"?
> >>>>>>>>
> >>>>>>>> My understanding is that we want to pass the bridge created in
> >>>>>>>> msm_dp_bridge_init() as the 'previous' bridge so that it attaches the
> >>>>>>>> panel bridge to the output of the DP bridge that's attached to the
> >>>>>>>> encoder.
> >>>>>>>
> >>>>>>> Thanks! I'll update the commit log when pushing the patches.
> >>>>>>
> >>>>>> Please correct if i am missing something here.
> >>>>>>
> >>>>>> You are right that the eDP panel's panel bridge attaches to the encoder
> >>>>>> in dp_drm_connector_init() which happens before msm_dp_bridge_init() and
> >>>>>> hence it will attach directly to the encoder.
> >>>>>>
> >>>>>> But we are talking about different encoders here. DP's dp_display has a
> >>>>>> different encoder compared to the EDP's dp_display.
> >>>>>
> >>>>> The encoders are different. However both encoders use the same
> >>>>> codepath, which includes dp_bridge. It controls dp_display by calling
> >>>>> msm_dp_display_foo() functions.
> >>>>>
> >>>
> >>>>>> So DP's bridge will still be attached to its encoder's root.
> >>>>>
> >>>>> There is one dp_bridge per each encoder. Consider sc8180x which has 3
> >>>>> DP controllers (and thus 3 dp_bridges).
> >>>>>
> >>>>
> >>>> Sorry, but I still didnt follow this.
> >>>>
> >>>> So for eDP, dp_drm_connector_init() will attach the panel_bridge
> >>>> and then msm_dp_bridge_init() will add a drm_bridge.
> >>>>
> >>>> And yes in that case, the drm_bridge will be after the panel_bridge
> >>>>
> >>>> But since panel_bridge is at the root for eDP it should be okay.
> >>>
> >>> No. It is not.
> >>> For both DP and eDP the chain should be:
> >>> dpu_encoder -> dp_bridge -> external (panel) bridge, optional for DP
> >>> -> [other bridges] -> connector
> >>>
> >>> Otherwise drm_bridge_chain_foo() functions would be called in the
> >>> incorrect order.
> >>
> >> Agreed. For drm_bridge_chain_foo() ordering to be correct, for eDP chain
> >> the order should be what you mentioned and panel_bridge should be at the
> >> end ( should be the last one ).
> >>
> >> For the above reason,
> >>
> >> Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
> >>
> >> I still didnt understand what gets affected by this for the
> >> msm_dp_display_foo() functions you mentioned earlier and wanted to get
> >> some clarity on that.
> >
> > They should be called at the correct time.
> >
> >>>
> >>> Thus the dp_bridge should be attached directly to the encoder
> >>> (drm_encoder) and panel_bridge should use dp_bridge as the 'previous'
> >>> bridge.
> >>>
> >>
> >> Agreed.
> >>
> >>> For example, for the DP port one can use a display-connector (which
> >>> actually implements drm_bridge) as an external bridge to provide hpd
> >>> or dp power GPIOs.
> >>>
> >>> Note, that the current dp_connector breaks layering. It makes calls
> >>> directly into dp_display, not allowing external bridge (and other
> >>> bridges) to override get_modes/mode_valid and other callbacks.
> >>> Thus one of the next patches in series (the one that Kuogee had issues
> >>> with) tries to replace the chain with the following one:
> >>> dpu_encoder -> dp_bridge -> external (panel) bridge -> [other bridges]
> >>> -> drm_bridge_connector.
> >>>
> >>>>
> >>
> >> So originally the plan was always that the DP connector layer intercepts
> >> the call because panel-eDP file did not support reading of the EDID ( we
> >> have not provided the aux bus ). So it was intended that we did not want
> >> to goto the eDP panel to get the modes. Not an error but something which
> >> we wanted to cleanup later when we moved to panel-eDP completely.
> >
> > panel_edp_get_modes() correctly handles this case and returns modes
> > specified in the panel description. So the code should work even with
> > panel-eDP and w/o the AUX bus.
> >
>
> If hard-coded modes are not present, it will fail in below case:
>
>      /*
>       * Add hard-coded panel modes. Don't call this if there are no timings
>       * and no modes (the generic edp-panel case) because it will clobber
>       * the display_info that was already set by drm_add_edid_modes().
>       */
>      if (p->desc->num_timings || p->desc->num_modes)
>          num += panel_edp_get_non_edid_modes(p, connector);
>      else if (!num)
>          dev_warn(p->base.dev, "No display modes\n");
>
> Thats exactly the error he was seeing.

Ah, so he had neither timings nor modes. The rest of the panels does.

>
> >>
> >> Till then we wanted the dp_connector to read the EDID and get the modes.
> >>
> >> So this was actually intended to happen till the point where we moved to
> >> panel-eDP to get the modes.
> >>
> >> Hence what you have mentioned in your cover letter is right that the
> >> chain was broken but there was no loss of functionality due to that today.
> >>
> >> Now that these changes are made, we can still goto panel-eDP file for
> >> the modes because of the below change from Sankeerth where the mode is
> >> hard-coded:
> >>
> >> https://patchwork.freedesktop.org/patch/473431/
> >>
> >> With this change cherry-picked it should work for kuogee. We will
> >> re-test that with this change.
> >
> > I suppose he had both of the changes in the tree. Otherwise the
> > panel_edp_get_modes() wouldn't be called.
>
> No he did not.
>
> That brings up another point.
>
> Even Bjorn was relying on the DP connector's get_modes() for his eDP
> panel if I am not mistaken.
>
> Unless he makes an equivalent change for his panel OR supports reading
> EDID in panel-edp, then he will hit the same error.
>
> Given that your changes were only compile tested, lets wait for both
> Kuogee and Bjorn to validate their resp setups.

Sure, anyway I think it's too late to bring in this patch during this cycle.

>
> >
> >>>> Your commit text was mentioning about DP.
> >>>>
> >>>> For DP, for each controller in the catalog, we will call modeset_init()
> >>>> which should skip this part for DP
> >>>>
> >>>>      if (dp_display->panel_bridge) {
> >>>>            ret = drm_bridge_attach(dp_display->encoder,
> >>>>                        dp_display->panel_bridge, NULL,
> >>>
> >>> as you see, NULL is incorrect. It should be a pointer to dp_bridge instead
> >>>
> >>>>                        DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> >>>>            if (ret < 0) {
> >>>>                DRM_ERROR("failed to attach panel bridge: %d\n", ret);
> >>>>                return ERR_PTR(ret);
> >>>>            }
> >>>>        }
> >>>>
> >>>> Followed by calling msm_dp_bridge_init() which will actually attach the
> >>>> bridge:
> >>>>
> >>>> drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> >>>
> >>> And this bridge should be attached before the external bridge.
> >>>
> >>>>
> >>>> Now, even for 3 DP controllers, this shall be true as there will be 3
> >>>> separate encoders and 3 dp_displays and hence 3 drm_bridges.
> >>>>
> >>>> What am i missing here?
> >>>>
> >>>>>>
> >>>>>> So what are we achieving with this change?
> >>>>>>
> >>>>>>>
> >>>>>>>>
> >>>>>>>>>
> >>>>>>>>> Fixes: 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
> >>>>>>>>> enable and disable")
> >>>>>>>>> Cc: Kuogee Hsieh <quic_khsieh@quicinc.com>
> >>>>>>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> >>>>>>>>> ---
> >>>>>>>>
> >>>>>>>> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
> >>>>>>>>
> >>>>>>>>>      drivers/gpu/drm/msm/dp/dp_drm.c | 21 +++++++++++----------
> >>>>>>>>>      1 file changed, 11 insertions(+), 10 deletions(-)
> >>>>>>>>>
> >>>>>>>>> diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c
> >>>>>>>>> b/drivers/gpu/drm/msm/dp/dp_drm.c
> >>>>>>>>> index d4d360d19eba..26ef41a4c1b6 100644
> >>>>>>>>> --- a/drivers/gpu/drm/msm/dp/dp_drm.c
> >>>>>>>>> +++ b/drivers/gpu/drm/msm/dp/dp_drm.c
> >>>>>>>>> @@ -169,16 +169,6 @@ struct drm_connector
> >>>>>>>>> *dp_drm_connector_init(struct msm_dp *dp_display)
> >>>>>>>>>
> >>>>>>>>>             drm_connector_attach_encoder(connector, dp_display->encoder);
> >>>>>>>>>
> >>>>>>>>> -       if (dp_display->panel_bridge) {
> >>>>>>>>> -               ret = drm_bridge_attach(dp_display->encoder,
> >>>>>>>>> -                                       dp_display->panel_bridge, NULL,
> >>>>>>>>> -                                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> >>>>>>>>> -               if (ret < 0) {
> >>>>>>>>> -                       DRM_ERROR("failed to attach panel bridge:
> >>>>>>>>> %d\n", ret);
> >>>>>>>>> -                       return ERR_PTR(ret);
> >>>>>>>>> -               }
> >>>>>>>>> -       }
> >>>>>>>>> -
> >>>>>>>>>             return connector;
> >>>>>>>>>      }
> >>>>>>>>>
> >>>>>>>>> @@ -246,5 +236,16 @@ struct drm_bridge *msm_dp_bridge_init(struct
> >>>>>>>>> msm_dp *dp_display, struct drm_devi
> >>>>>>>>>                     return ERR_PTR(rc);
> >>>>>>>>>             }
> >>>>>>>>>
> >>>>>>>>> +       if (dp_display->panel_bridge) {
> >>>>>>>>> +               rc = drm_bridge_attach(dp_display->encoder,
> >>>>>>>>> +                                       dp_display->panel_bridge,
> >>>>>>>>> bridge,
> >>>>>>>>> +                                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> >>>>>>>>> +               if (rc < 0) {
> >>>>>>>>> +                       DRM_ERROR("failed to attach panel bridge:
> >>>>>>>>> %d\n", rc);
> >>>>>>>>> +                       drm_bridge_remove(bridge);
> >>>>>>>>> +                       return ERR_PTR(rc);
> >>>>>>>>> +               }
> >>>>>>>>> +       }
> >>>>>>>>> +
> >>>>>>>>>             return bridge;
> >>>>>>>>
> >>>>>>>> Not a problem with this patch, but what is this pointer used for? I see
> >>>>>>>> it's assigned to priv->bridges and num_bridges is incremented but nobody
> >>>>>>>> seems to look at that.
> >>>>>>>
> >>>>>>>
> >>>>>>> That's on my todo list. to remove connectors array and to destroy
> >>>>>>> created bridges during drm device destruction.
> >>>>>>>
> >>>>>
> >>>>>
> >>>>>
> >>>
> >>>
> >>>
> >
> >
> >



-- 
With best wishes
Dmitry

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

* Re: [Freedreno] [RFC PATCH v2 1/5] drm/msm/dp: fix panel bridge attachment
@ 2022-02-25 17:25                       ` Dmitry Baryshkov
  0 siblings, 0 replies; 84+ messages in thread
From: Dmitry Baryshkov @ 2022-02-25 17:25 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: freedreno, David Airlie, linux-arm-msm, Stephen Boyd, dri-devel,
	Kuogee Hsieh, Bjorn Andersson, Sean Paul

On Fri, 25 Feb 2022 at 20:11, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>
>
>
> On 2/25/2022 1:04 AM, Dmitry Baryshkov wrote:
> > On Fri, 25 Feb 2022 at 07:45, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
> >>
> >>
> >>
> >> On 2/24/2022 8:22 PM, Dmitry Baryshkov wrote:
> >>> On Fri, 25 Feb 2022 at 05:01, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
> >>>>
> >>>>
> >>>>
> >>>> On 2/24/2022 12:41 PM, Dmitry Baryshkov wrote:
> >>>>> On Thu, 24 Feb 2022 at 21:25, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>> On 2/18/2022 6:26 PM, Dmitry Baryshkov wrote:
> >>>>>>> On 19/02/2022 02:56, Stephen Boyd wrote:
> >>>>>>>> Quoting Dmitry Baryshkov (2022-02-11 14:40:02)
> >>>>>>>>> In commit 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
> >>>>>>>>> enable and disable") the DP driver received a drm_bridge instance, which
> >>>>>>>>> is always attached to the encoder as a root bridge. However it conflicts
> >>>>>>>>> with the panel_bridge support for eDP panels. The panel bridge attaches
> >>>>>>>>> to the encoder before the "dp" bridge has a chace to do so. Change
> >>>>>>>>
> >>>>>>>> s/chace/chance/
> >>>>>>>>
> >>>>>>>>> panel_bridge attachment to come after dp_bridge attachment.
> >>>>>>>>
> >>>>>>>> s/panel_bridge/panel bridge/ possibly? And maybe clarify that dp_bridge
> >>>>>>>> is the "DP driver's drm_bridge instance created in
> >>>>>>>> msm_dp_bridge_init()"?
> >>>>>>>>
> >>>>>>>> My understanding is that we want to pass the bridge created in
> >>>>>>>> msm_dp_bridge_init() as the 'previous' bridge so that it attaches the
> >>>>>>>> panel bridge to the output of the DP bridge that's attached to the
> >>>>>>>> encoder.
> >>>>>>>
> >>>>>>> Thanks! I'll update the commit log when pushing the patches.
> >>>>>>
> >>>>>> Please correct if i am missing something here.
> >>>>>>
> >>>>>> You are right that the eDP panel's panel bridge attaches to the encoder
> >>>>>> in dp_drm_connector_init() which happens before msm_dp_bridge_init() and
> >>>>>> hence it will attach directly to the encoder.
> >>>>>>
> >>>>>> But we are talking about different encoders here. DP's dp_display has a
> >>>>>> different encoder compared to the EDP's dp_display.
> >>>>>
> >>>>> The encoders are different. However both encoders use the same
> >>>>> codepath, which includes dp_bridge. It controls dp_display by calling
> >>>>> msm_dp_display_foo() functions.
> >>>>>
> >>>
> >>>>>> So DP's bridge will still be attached to its encoder's root.
> >>>>>
> >>>>> There is one dp_bridge per each encoder. Consider sc8180x which has 3
> >>>>> DP controllers (and thus 3 dp_bridges).
> >>>>>
> >>>>
> >>>> Sorry, but I still didnt follow this.
> >>>>
> >>>> So for eDP, dp_drm_connector_init() will attach the panel_bridge
> >>>> and then msm_dp_bridge_init() will add a drm_bridge.
> >>>>
> >>>> And yes in that case, the drm_bridge will be after the panel_bridge
> >>>>
> >>>> But since panel_bridge is at the root for eDP it should be okay.
> >>>
> >>> No. It is not.
> >>> For both DP and eDP the chain should be:
> >>> dpu_encoder -> dp_bridge -> external (panel) bridge, optional for DP
> >>> -> [other bridges] -> connector
> >>>
> >>> Otherwise drm_bridge_chain_foo() functions would be called in the
> >>> incorrect order.
> >>
> >> Agreed. For drm_bridge_chain_foo() ordering to be correct, for eDP chain
> >> the order should be what you mentioned and panel_bridge should be at the
> >> end ( should be the last one ).
> >>
> >> For the above reason,
> >>
> >> Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
> >>
> >> I still didnt understand what gets affected by this for the
> >> msm_dp_display_foo() functions you mentioned earlier and wanted to get
> >> some clarity on that.
> >
> > They should be called at the correct time.
> >
> >>>
> >>> Thus the dp_bridge should be attached directly to the encoder
> >>> (drm_encoder) and panel_bridge should use dp_bridge as the 'previous'
> >>> bridge.
> >>>
> >>
> >> Agreed.
> >>
> >>> For example, for the DP port one can use a display-connector (which
> >>> actually implements drm_bridge) as an external bridge to provide hpd
> >>> or dp power GPIOs.
> >>>
> >>> Note, that the current dp_connector breaks layering. It makes calls
> >>> directly into dp_display, not allowing external bridge (and other
> >>> bridges) to override get_modes/mode_valid and other callbacks.
> >>> Thus one of the next patches in series (the one that Kuogee had issues
> >>> with) tries to replace the chain with the following one:
> >>> dpu_encoder -> dp_bridge -> external (panel) bridge -> [other bridges]
> >>> -> drm_bridge_connector.
> >>>
> >>>>
> >>
> >> So originally the plan was always that the DP connector layer intercepts
> >> the call because panel-eDP file did not support reading of the EDID ( we
> >> have not provided the aux bus ). So it was intended that we did not want
> >> to goto the eDP panel to get the modes. Not an error but something which
> >> we wanted to cleanup later when we moved to panel-eDP completely.
> >
> > panel_edp_get_modes() correctly handles this case and returns modes
> > specified in the panel description. So the code should work even with
> > panel-eDP and w/o the AUX bus.
> >
>
> If hard-coded modes are not present, it will fail in below case:
>
>      /*
>       * Add hard-coded panel modes. Don't call this if there are no timings
>       * and no modes (the generic edp-panel case) because it will clobber
>       * the display_info that was already set by drm_add_edid_modes().
>       */
>      if (p->desc->num_timings || p->desc->num_modes)
>          num += panel_edp_get_non_edid_modes(p, connector);
>      else if (!num)
>          dev_warn(p->base.dev, "No display modes\n");
>
> Thats exactly the error he was seeing.

Ah, so he had neither timings nor modes. The rest of the panels does.

>
> >>
> >> Till then we wanted the dp_connector to read the EDID and get the modes.
> >>
> >> So this was actually intended to happen till the point where we moved to
> >> panel-eDP to get the modes.
> >>
> >> Hence what you have mentioned in your cover letter is right that the
> >> chain was broken but there was no loss of functionality due to that today.
> >>
> >> Now that these changes are made, we can still goto panel-eDP file for
> >> the modes because of the below change from Sankeerth where the mode is
> >> hard-coded:
> >>
> >> https://patchwork.freedesktop.org/patch/473431/
> >>
> >> With this change cherry-picked it should work for kuogee. We will
> >> re-test that with this change.
> >
> > I suppose he had both of the changes in the tree. Otherwise the
> > panel_edp_get_modes() wouldn't be called.
>
> No he did not.
>
> That brings up another point.
>
> Even Bjorn was relying on the DP connector's get_modes() for his eDP
> panel if I am not mistaken.
>
> Unless he makes an equivalent change for his panel OR supports reading
> EDID in panel-edp, then he will hit the same error.
>
> Given that your changes were only compile tested, lets wait for both
> Kuogee and Bjorn to validate their resp setups.

Sure, anyway I think it's too late to bring in this patch during this cycle.

>
> >
> >>>> Your commit text was mentioning about DP.
> >>>>
> >>>> For DP, for each controller in the catalog, we will call modeset_init()
> >>>> which should skip this part for DP
> >>>>
> >>>>      if (dp_display->panel_bridge) {
> >>>>            ret = drm_bridge_attach(dp_display->encoder,
> >>>>                        dp_display->panel_bridge, NULL,
> >>>
> >>> as you see, NULL is incorrect. It should be a pointer to dp_bridge instead
> >>>
> >>>>                        DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> >>>>            if (ret < 0) {
> >>>>                DRM_ERROR("failed to attach panel bridge: %d\n", ret);
> >>>>                return ERR_PTR(ret);
> >>>>            }
> >>>>        }
> >>>>
> >>>> Followed by calling msm_dp_bridge_init() which will actually attach the
> >>>> bridge:
> >>>>
> >>>> drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> >>>
> >>> And this bridge should be attached before the external bridge.
> >>>
> >>>>
> >>>> Now, even for 3 DP controllers, this shall be true as there will be 3
> >>>> separate encoders and 3 dp_displays and hence 3 drm_bridges.
> >>>>
> >>>> What am i missing here?
> >>>>
> >>>>>>
> >>>>>> So what are we achieving with this change?
> >>>>>>
> >>>>>>>
> >>>>>>>>
> >>>>>>>>>
> >>>>>>>>> Fixes: 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
> >>>>>>>>> enable and disable")
> >>>>>>>>> Cc: Kuogee Hsieh <quic_khsieh@quicinc.com>
> >>>>>>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> >>>>>>>>> ---
> >>>>>>>>
> >>>>>>>> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
> >>>>>>>>
> >>>>>>>>>      drivers/gpu/drm/msm/dp/dp_drm.c | 21 +++++++++++----------
> >>>>>>>>>      1 file changed, 11 insertions(+), 10 deletions(-)
> >>>>>>>>>
> >>>>>>>>> diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c
> >>>>>>>>> b/drivers/gpu/drm/msm/dp/dp_drm.c
> >>>>>>>>> index d4d360d19eba..26ef41a4c1b6 100644
> >>>>>>>>> --- a/drivers/gpu/drm/msm/dp/dp_drm.c
> >>>>>>>>> +++ b/drivers/gpu/drm/msm/dp/dp_drm.c
> >>>>>>>>> @@ -169,16 +169,6 @@ struct drm_connector
> >>>>>>>>> *dp_drm_connector_init(struct msm_dp *dp_display)
> >>>>>>>>>
> >>>>>>>>>             drm_connector_attach_encoder(connector, dp_display->encoder);
> >>>>>>>>>
> >>>>>>>>> -       if (dp_display->panel_bridge) {
> >>>>>>>>> -               ret = drm_bridge_attach(dp_display->encoder,
> >>>>>>>>> -                                       dp_display->panel_bridge, NULL,
> >>>>>>>>> -                                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> >>>>>>>>> -               if (ret < 0) {
> >>>>>>>>> -                       DRM_ERROR("failed to attach panel bridge:
> >>>>>>>>> %d\n", ret);
> >>>>>>>>> -                       return ERR_PTR(ret);
> >>>>>>>>> -               }
> >>>>>>>>> -       }
> >>>>>>>>> -
> >>>>>>>>>             return connector;
> >>>>>>>>>      }
> >>>>>>>>>
> >>>>>>>>> @@ -246,5 +236,16 @@ struct drm_bridge *msm_dp_bridge_init(struct
> >>>>>>>>> msm_dp *dp_display, struct drm_devi
> >>>>>>>>>                     return ERR_PTR(rc);
> >>>>>>>>>             }
> >>>>>>>>>
> >>>>>>>>> +       if (dp_display->panel_bridge) {
> >>>>>>>>> +               rc = drm_bridge_attach(dp_display->encoder,
> >>>>>>>>> +                                       dp_display->panel_bridge,
> >>>>>>>>> bridge,
> >>>>>>>>> +                                       DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> >>>>>>>>> +               if (rc < 0) {
> >>>>>>>>> +                       DRM_ERROR("failed to attach panel bridge:
> >>>>>>>>> %d\n", rc);
> >>>>>>>>> +                       drm_bridge_remove(bridge);
> >>>>>>>>> +                       return ERR_PTR(rc);
> >>>>>>>>> +               }
> >>>>>>>>> +       }
> >>>>>>>>> +
> >>>>>>>>>             return bridge;
> >>>>>>>>
> >>>>>>>> Not a problem with this patch, but what is this pointer used for? I see
> >>>>>>>> it's assigned to priv->bridges and num_bridges is incremented but nobody
> >>>>>>>> seems to look at that.
> >>>>>>>
> >>>>>>>
> >>>>>>> That's on my todo list. to remove connectors array and to destroy
> >>>>>>> created bridges during drm device destruction.
> >>>>>>>
> >>>>>
> >>>>>
> >>>>>
> >>>
> >>>
> >>>
> >
> >
> >



-- 
With best wishes
Dmitry

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

* RE: [RFC PATCH v2 5/5] drm/msm/dp: remove extra wrappers and public functions
       [not found]   ` <26549f55-6195-a7ec-5896-de5f986ad716@quicinc.com>
@ 2022-03-16 16:31       ` Sankeerth Billakanti (QUIC)
  0 siblings, 0 replies; 84+ messages in thread
From: Sankeerth Billakanti (QUIC) @ 2022-03-16 16:31 UTC (permalink / raw)
  To: bjorn.andersson, robdclark, sean, Abhinav Kumar (QUIC),
	Kuogee Hsieh (QUIC)
  Cc: swboyd, airlied, daniel, linux-arm-msm, dri-devel, freedreno

> Subject: [RFC PATCH v2 5/5] drm/msm/dp: remove extra wrappers and
> public functions
> Date: Sat, 12 Feb 2022 01:40:06 +0300
> From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> To: Bjorn Andersson <bjorn.andersson@linaro.org>, Rob Clark
> <robdclark@gmail.com>, Sean Paul <sean@poorly.run>, Abhinav Kumar
> <quic_abhinavk@quicinc.com>, Kuogee Hsieh <quic_khsieh@quicinc.com>
> CC: Stephen Boyd <swboyd@chromium.org>, David Airlie <airlied@linux.ie>,
> Daniel Vetter <daniel@ffwll.ch>, linux-arm-msm@vger.kernel.org, dri-
> devel@lists.freedesktop.org, freedreno@lists.freedesktop.org
> 
> dp_bridge's functions are thin wrappers around the msm_dp_display_*
> family. Squash dp_bridge callbacks into respective msm_dp_display
> functions, removing the latter functions from public space.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>


Tested-by: Sankeerth Billakanti <quic_sbillaka@quicinc.com>


> ---
>   drivers/gpu/drm/msm/dp/dp_display.c | 54 +++++++++++++++-------
>   drivers/gpu/drm/msm/dp/dp_display.h |  1 -
>   drivers/gpu/drm/msm/dp/dp_drm.c     | 72 ++---------------------------
>   drivers/gpu/drm/msm/dp/dp_drm.h     | 22 ++++++++-
>   drivers/gpu/drm/msm/msm_drv.h       | 31 -------------
>   5 files changed, 60 insertions(+), 120 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/dp/dp_display.c
> b/drivers/gpu/drm/msm/dp/dp_display.c
> index 59e5e5b8e5b4..a9b641a68bff 100644
> --- a/drivers/gpu/drm/msm/dp/dp_display.c
> +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> @@ -10,7 +10,6 @@
>   #include <linux/component.h>
>   #include <linux/of_irq.h>
>   #include <linux/delay.h>
> -#include <drm/drm_panel.h>
>    #include "msm_drv.h"
>   #include "msm_kms.h"
> @@ -945,18 +944,36 @@ int dp_display_set_plugged_cb(struct msm_dp
> *dp_display,
>   	return 0;
>   }
>   -int dp_display_validate_mode(struct msm_dp *dp, u32 mode_pclk_khz)
> +/**
> + * dp_bridge_mode_valid - callback to determine if specified mode is
> +valid
> + * @bridge: Pointer to drm bridge structure
> + * @info: display info
> + * @mode: Pointer to drm mode structure
> + * Returns: Validity status for specified mode  */ enum drm_mode_status
> +dp_bridge_mode_valid(struct drm_bridge *bridge,
> +					  const struct drm_display_info *info,
> +					  const struct drm_display_mode
> *mode)
>   {
>   	const u32 num_components = 3, default_bpp = 24;
>   	struct dp_display_private *dp_display;
>   	struct dp_link_info *link_info;
>   	u32 mode_rate_khz = 0, supported_rate_khz = 0, mode_bpp = 0;
> +	struct msm_dp *dp;
> +	int mode_pclk_khz = mode->clock;
> +
> +	dp = to_dp_bridge(bridge)->dp_display;
>    	if (!dp || !mode_pclk_khz || !dp->connector) {
>   		DRM_ERROR("invalid params\n");
>   		return -EINVAL;
>   	}
>   +	if ((dp->max_pclk_khz <= 0) ||
> +			(dp->max_pclk_khz > DP_MAX_PIXEL_CLK_KHZ) ||
> +			(mode->clock > dp->max_pclk_khz))
> +		return MODE_BAD;
> +
>   	dp_display = container_of(dp, struct dp_display_private,
> dp_display);
>   	link_info = &dp_display->panel->link_info;
>   @@ -1501,7 +1518,7 @@ int msm_dp_modeset_init(struct msm_dp
> *dp_display, struct drm_device *dev,
>    	dp_display->encoder = encoder;
>   -	dp_display->bridge = msm_dp_bridge_init(dp_display, dev,
> encoder);
> +	dp_display->bridge = dp_bridge_init(dp_display, dev, encoder);
>   	if (IS_ERR(dp_display->bridge)) {
>   		ret = PTR_ERR(dp_display->bridge);
>   		DRM_DEV_ERROR(dev->dev,
> @@ -1528,8 +1545,10 @@ int msm_dp_modeset_init(struct msm_dp
> *dp_display, struct drm_device *dev,
>   	return 0;
>   }
>   -int msm_dp_display_enable(struct msm_dp *dp, struct drm_encoder
> *encoder)
> +void dp_bridge_enable(struct drm_bridge *drm_bridge)
>   {
> +	struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
> +	struct msm_dp *dp = dp_bridge->dp_display;
>   	int rc = 0;
>   	struct dp_display_private *dp_display;
>   	u32 state;
> @@ -1537,7 +1556,7 @@ int msm_dp_display_enable(struct msm_dp *dp,
> struct drm_encoder *encoder)
>   	dp_display = container_of(dp, struct dp_display_private,
> dp_display);
>   	if (!dp_display->dp_mode.drm_mode.clock) {
>   		DRM_ERROR("invalid params\n");
> -		return -EINVAL;
> +		return;
>   	}
>    	mutex_lock(&dp_display->event_mutex);
> @@ -1549,14 +1568,14 @@ int msm_dp_display_enable(struct msm_dp *dp,
> struct drm_encoder *encoder)
>   	if (rc) {
>   		DRM_ERROR("Failed to perform a mode set, rc=%d\n", rc);
>   		mutex_unlock(&dp_display->event_mutex);
> -		return rc;
> +		return;
>   	}
>    	rc = dp_display_prepare(dp);
>   	if (rc) {
>   		DRM_ERROR("DP display prepare failed, rc=%d\n", rc);
>   		mutex_unlock(&dp_display->event_mutex);
> -		return rc;
> +		return;
>   	}
>    	state =  dp_display->hpd_state;
> @@ -1581,23 +1600,23 @@ int msm_dp_display_enable(struct msm_dp *dp,
> struct drm_encoder *encoder)
>   	dp_display->hpd_state = ST_CONNECTED;
>    	mutex_unlock(&dp_display->event_mutex);
> -
> -	return rc;
>   }
>   -int msm_dp_display_pre_disable(struct msm_dp *dp, struct drm_encoder
> *encoder)
> +void dp_bridge_disable(struct drm_bridge *drm_bridge)
>   {
> +	struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
> +	struct msm_dp *dp = dp_bridge->dp_display;
>   	struct dp_display_private *dp_display;
>    	dp_display = container_of(dp, struct dp_display_private,
> dp_display);
>    	dp_ctrl_push_idle(dp_display->ctrl);
> -
> -	return 0;
>   }
>   -int msm_dp_display_disable(struct msm_dp *dp, struct drm_encoder
> *encoder)
> +void dp_bridge_post_disable(struct drm_bridge *drm_bridge)
>   {
> +	struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
> +	struct msm_dp *dp = dp_bridge->dp_display;
>   	int rc = 0;
>   	u32 state;
>   	struct dp_display_private *dp_display; @@ -1624,13 +1643,14 @@
> int msm_dp_display_disable(struct msm_dp *dp, struct drm_encoder
> *encoder)
>   	}
>    	mutex_unlock(&dp_display->event_mutex);
> -	return rc;
>   }
>   -void msm_dp_display_mode_set(struct msm_dp *dp, struct drm_encoder
> *encoder,
> -				const struct drm_display_mode *mode,
> -				const struct drm_display_mode
> *adjusted_mode)
> +void dp_bridge_mode_set(struct drm_bridge *drm_bridge,
> +			const struct drm_display_mode *mode,
> +			const struct drm_display_mode *adjusted_mode)
>   {
> +	struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
> +	struct msm_dp *dp = dp_bridge->dp_display;
>   	struct dp_display_private *dp_display;
>    	dp_display = container_of(dp, struct dp_display_private,
> dp_display); diff --git a/drivers/gpu/drm/msm/dp/dp_display.h
> b/drivers/gpu/drm/msm/dp/dp_display.h
> index 7af2b186d2d9..49a1d89681ac 100644
> --- a/drivers/gpu/drm/msm/dp/dp_display.h
> +++ b/drivers/gpu/drm/msm/dp/dp_display.h
> @@ -32,7 +32,6 @@ struct msm_dp {
>    int dp_display_set_plugged_cb(struct msm_dp *dp_display,
>   		hdmi_codec_plugged_cb fn, struct device *codec_dev); -int
> dp_display_validate_mode(struct msm_dp *dp_display, u32
> mode_pclk_khz);
>   int dp_display_get_modes(struct msm_dp *dp_display,
>   		struct dp_display_mode *dp_mode);
>   int dp_display_request_irq(struct msm_dp *dp_display); diff --git
> a/drivers/gpu/drm/msm/dp/dp_drm.c
> b/drivers/gpu/drm/msm/dp/dp_drm.c index 57800b865fe6..7ce1aca48687
> 100644
> --- a/drivers/gpu/drm/msm/dp/dp_drm.c
> +++ b/drivers/gpu/drm/msm/dp/dp_drm.c
> @@ -13,14 +13,6 @@
>   #include "msm_kms.h"
>   #include "dp_drm.h"
>   -
> -struct msm_dp_bridge {
> -	struct drm_bridge bridge;
> -	struct msm_dp *dp_display;
> -};
> -
> -#define to_dp_display(x)     container_of((x), struct msm_dp_bridge,
> bridge)
> -
>   /**
>    * dp_bridge_detect - callback to determine if connector is connected
>    * @bridge: Pointer to drm bridge structure @@ -30,7 +22,7 @@ static enum
> drm_connector_status dp_bridge_detect(struct drm_bridge *bridge)
>   {
>   	struct msm_dp *dp;
>   -	dp = to_dp_display(bridge)->dp_display;
> +	dp = to_dp_bridge(bridge)->dp_display;
>    	DRM_DEBUG_DP("is_connected = %s\n",
>   		(dp->is_connected) ? "true" : "false"); @@ -55,7 +47,7 @@
> static int dp_bridge_get_modes(struct drm_bridge *bridge, struct
> drm_connector *
>   	if (!connector)
>   		return 0;
>   -	dp = to_dp_display(bridge)->dp_display;
> +	dp = to_dp_bridge(bridge)->dp_display;
>    	dp_mode = kzalloc(sizeof(*dp_mode),  GFP_KERNEL);
>   	if (!dp_mode)
> @@ -95,64 +87,6 @@ static int dp_bridge_get_modes(struct drm_bridge
> *bridge, struct drm_connector *
>   	return rc;
>   }
>   -/**
> - * dp_bridge_mode_valid - callback to determine if specified mode is valid
> - * @bridge: Pointer to drm bridge structure
> - * @info: display info
> - * @mode: Pointer to drm mode structure
> - * Returns: Validity status for specified mode
> - */
> -static enum drm_mode_status dp_bridge_mode_valid(
> -		struct drm_bridge *bridge,
> -		const struct drm_display_info *info,
> -		const struct drm_display_mode *mode)
> -{
> -	struct msm_dp *dp_disp;
> -
> -	dp_disp = to_dp_display(bridge)->dp_display;
> -
> -	if ((dp_disp->max_pclk_khz <= 0) ||
> -			(dp_disp->max_pclk_khz >
> DP_MAX_PIXEL_CLK_KHZ) ||
> -			(mode->clock > dp_disp->max_pclk_khz))
> -		return MODE_BAD;
> -
> -	return dp_display_validate_mode(dp_disp, mode->clock);
> -}
> -
> -static void dp_bridge_mode_set(struct drm_bridge *drm_bridge,
> -				const struct drm_display_mode *mode,
> -				const struct drm_display_mode
> *adjusted_mode)
> -{
> -	struct msm_dp_bridge *dp_bridge = to_dp_display(drm_bridge);
> -	struct msm_dp *dp_display = dp_bridge->dp_display;
> -
> -	msm_dp_display_mode_set(dp_display, drm_bridge->encoder,
> mode,
> adjusted_mode);
> -}
> -
> -static void dp_bridge_enable(struct drm_bridge *drm_bridge) -{
> -	struct msm_dp_bridge *dp_bridge = to_dp_display(drm_bridge);
> -	struct msm_dp *dp_display = dp_bridge->dp_display;
> -
> -	msm_dp_display_enable(dp_display, drm_bridge->encoder);
> -}
> -
> -static void dp_bridge_disable(struct drm_bridge *drm_bridge) -{
> -	struct msm_dp_bridge *dp_bridge = to_dp_display(drm_bridge);
> -	struct msm_dp *dp_display = dp_bridge->dp_display;
> -
> -	msm_dp_display_pre_disable(dp_display, drm_bridge->encoder);
> -}
> -
> -static void dp_bridge_post_disable(struct drm_bridge *drm_bridge) -{
> -	struct msm_dp_bridge *dp_bridge = to_dp_display(drm_bridge);
> -	struct msm_dp *dp_display = dp_bridge->dp_display;
> -
> -	msm_dp_display_disable(dp_display, drm_bridge->encoder);
> -}
> -
>   static const struct drm_bridge_funcs dp_bridge_ops = {
>   	.enable       = dp_bridge_enable,
>   	.disable      = dp_bridge_disable,
> @@ -163,7 +97,7 @@ static const struct drm_bridge_funcs dp_bridge_ops =
> {
>   	.detect       = dp_bridge_detect,
>   };
>   -struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display,
> struct drm_device *dev,
> +struct drm_bridge *dp_bridge_init(struct msm_dp *dp_display, struct
> drm_device *dev,
>   			struct drm_encoder *encoder)
>   {
>   	int rc;
> diff --git a/drivers/gpu/drm/msm/dp/dp_drm.h
> b/drivers/gpu/drm/msm/dp/dp_drm.h index c27bfceefdf0..f4b1ed1e24f7
> 100644
> --- a/drivers/gpu/drm/msm/dp/dp_drm.h
> +++ b/drivers/gpu/drm/msm/dp/dp_drm.h
> @@ -7,12 +7,30 @@
>   #define _DP_DRM_H_
>    #include <linux/types.h>
> -#include <drm/drm_crtc.h>
> -#include <drm/drm_crtc_helper.h>
> +#include <drm/drm_bridge.h>
>    #include "msm_drv.h"
>   #include "dp_display.h"
>   +struct msm_dp_bridge {
> +	struct drm_bridge bridge;
> +	struct msm_dp *dp_display;
> +};
> +
> +#define to_dp_bridge(x)     container_of((x), struct msm_dp_bridge,
> bridge)
> +
>   struct drm_connector *dp_drm_connector_init(struct msm_dp
> *dp_display);
> +struct drm_bridge *dp_bridge_init(struct msm_dp *dp_display, struct
> drm_device *dev,
> +			struct drm_encoder *encoder);
> +
> +void dp_bridge_enable(struct drm_bridge *drm_bridge); void
> +dp_bridge_disable(struct drm_bridge *drm_bridge); void
> +dp_bridge_post_disable(struct drm_bridge *drm_bridge); enum
> +drm_mode_status dp_bridge_mode_valid(struct drm_bridge *bridge,
> +					  const struct drm_display_info *info,
> +					  const struct drm_display_mode
> *mode); void
> +dp_bridge_mode_set(struct drm_bridge *drm_bridge,
> +			const struct drm_display_mode *mode,
> +			const struct drm_display_mode *adjusted_mode);
>    #endif /* _DP_DRM_H_ */
> diff --git a/drivers/gpu/drm/msm/msm_drv.h
> b/drivers/gpu/drm/msm/msm_drv.h index d7574e6bd4e4..b698a3be6072
> 100644
> --- a/drivers/gpu/drm/msm/msm_drv.h
> +++ b/drivers/gpu/drm/msm/msm_drv.h
> @@ -385,16 +385,6 @@ int __init msm_dp_register(void);
>   void __exit msm_dp_unregister(void);
>   int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device
> *dev,
>   			 struct drm_encoder *encoder);
> -int msm_dp_display_enable(struct msm_dp *dp, struct drm_encoder
> *encoder); -int msm_dp_display_disable(struct msm_dp *dp, struct
> drm_encoder *encoder); -int msm_dp_display_pre_disable(struct msm_dp
> *dp, struct drm_encoder *encoder); -void
> msm_dp_display_mode_set(struct msm_dp *dp, struct drm_encoder
> *encoder,
> -				const struct drm_display_mode *mode,
> -				const struct drm_display_mode
> *adjusted_mode);
> -
> -struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display,
> -					struct drm_device *dev,
> -					struct drm_encoder *encoder);
>   void msm_dp_irq_postinstall(struct msm_dp *dp_display);
>   void msm_dp_snapshot(struct msm_disp_state *disp_state, struct
> msm_dp *dp_display);
>   @@ -414,27 +404,6 @@ static inline int msm_dp_modeset_init(struct
> msm_dp *dp_display,
>   {
>   	return -EINVAL;
>   }
> -static inline int msm_dp_display_enable(struct msm_dp *dp,
> -					struct drm_encoder *encoder)
> -{
> -	return -EINVAL;
> -}
> -static inline int msm_dp_display_disable(struct msm_dp *dp,
> -					struct drm_encoder *encoder)
> -{
> -	return -EINVAL;
> -}
> -static inline int msm_dp_display_pre_disable(struct msm_dp *dp,
> -					struct drm_encoder *encoder)
> -{
> -	return -EINVAL;
> -}
> -static inline void msm_dp_display_mode_set(struct msm_dp *dp,
> -				struct drm_encoder *encoder,
> -				const struct drm_display_mode *mode,
> -				const struct drm_display_mode
> *adjusted_mode)
> -{
> -}
>    static inline void msm_dp_irq_postinstall(struct msm_dp *dp_display)
>   {
> --
> 2.34.1


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

* RE: [RFC PATCH v2 5/5] drm/msm/dp: remove extra wrappers and public functions
@ 2022-03-16 16:31       ` Sankeerth Billakanti (QUIC)
  0 siblings, 0 replies; 84+ messages in thread
From: Sankeerth Billakanti (QUIC) @ 2022-03-16 16:31 UTC (permalink / raw)
  To: bjorn.andersson, robdclark, sean, Abhinav Kumar (QUIC),
	Kuogee Hsieh (QUIC)
  Cc: airlied, linux-arm-msm, dri-devel, swboyd, freedreno

> Subject: [RFC PATCH v2 5/5] drm/msm/dp: remove extra wrappers and
> public functions
> Date: Sat, 12 Feb 2022 01:40:06 +0300
> From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> To: Bjorn Andersson <bjorn.andersson@linaro.org>, Rob Clark
> <robdclark@gmail.com>, Sean Paul <sean@poorly.run>, Abhinav Kumar
> <quic_abhinavk@quicinc.com>, Kuogee Hsieh <quic_khsieh@quicinc.com>
> CC: Stephen Boyd <swboyd@chromium.org>, David Airlie <airlied@linux.ie>,
> Daniel Vetter <daniel@ffwll.ch>, linux-arm-msm@vger.kernel.org, dri-
> devel@lists.freedesktop.org, freedreno@lists.freedesktop.org
> 
> dp_bridge's functions are thin wrappers around the msm_dp_display_*
> family. Squash dp_bridge callbacks into respective msm_dp_display
> functions, removing the latter functions from public space.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>


Tested-by: Sankeerth Billakanti <quic_sbillaka@quicinc.com>


> ---
>   drivers/gpu/drm/msm/dp/dp_display.c | 54 +++++++++++++++-------
>   drivers/gpu/drm/msm/dp/dp_display.h |  1 -
>   drivers/gpu/drm/msm/dp/dp_drm.c     | 72 ++---------------------------
>   drivers/gpu/drm/msm/dp/dp_drm.h     | 22 ++++++++-
>   drivers/gpu/drm/msm/msm_drv.h       | 31 -------------
>   5 files changed, 60 insertions(+), 120 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/dp/dp_display.c
> b/drivers/gpu/drm/msm/dp/dp_display.c
> index 59e5e5b8e5b4..a9b641a68bff 100644
> --- a/drivers/gpu/drm/msm/dp/dp_display.c
> +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> @@ -10,7 +10,6 @@
>   #include <linux/component.h>
>   #include <linux/of_irq.h>
>   #include <linux/delay.h>
> -#include <drm/drm_panel.h>
>    #include "msm_drv.h"
>   #include "msm_kms.h"
> @@ -945,18 +944,36 @@ int dp_display_set_plugged_cb(struct msm_dp
> *dp_display,
>   	return 0;
>   }
>   -int dp_display_validate_mode(struct msm_dp *dp, u32 mode_pclk_khz)
> +/**
> + * dp_bridge_mode_valid - callback to determine if specified mode is
> +valid
> + * @bridge: Pointer to drm bridge structure
> + * @info: display info
> + * @mode: Pointer to drm mode structure
> + * Returns: Validity status for specified mode  */ enum drm_mode_status
> +dp_bridge_mode_valid(struct drm_bridge *bridge,
> +					  const struct drm_display_info *info,
> +					  const struct drm_display_mode
> *mode)
>   {
>   	const u32 num_components = 3, default_bpp = 24;
>   	struct dp_display_private *dp_display;
>   	struct dp_link_info *link_info;
>   	u32 mode_rate_khz = 0, supported_rate_khz = 0, mode_bpp = 0;
> +	struct msm_dp *dp;
> +	int mode_pclk_khz = mode->clock;
> +
> +	dp = to_dp_bridge(bridge)->dp_display;
>    	if (!dp || !mode_pclk_khz || !dp->connector) {
>   		DRM_ERROR("invalid params\n");
>   		return -EINVAL;
>   	}
>   +	if ((dp->max_pclk_khz <= 0) ||
> +			(dp->max_pclk_khz > DP_MAX_PIXEL_CLK_KHZ) ||
> +			(mode->clock > dp->max_pclk_khz))
> +		return MODE_BAD;
> +
>   	dp_display = container_of(dp, struct dp_display_private,
> dp_display);
>   	link_info = &dp_display->panel->link_info;
>   @@ -1501,7 +1518,7 @@ int msm_dp_modeset_init(struct msm_dp
> *dp_display, struct drm_device *dev,
>    	dp_display->encoder = encoder;
>   -	dp_display->bridge = msm_dp_bridge_init(dp_display, dev,
> encoder);
> +	dp_display->bridge = dp_bridge_init(dp_display, dev, encoder);
>   	if (IS_ERR(dp_display->bridge)) {
>   		ret = PTR_ERR(dp_display->bridge);
>   		DRM_DEV_ERROR(dev->dev,
> @@ -1528,8 +1545,10 @@ int msm_dp_modeset_init(struct msm_dp
> *dp_display, struct drm_device *dev,
>   	return 0;
>   }
>   -int msm_dp_display_enable(struct msm_dp *dp, struct drm_encoder
> *encoder)
> +void dp_bridge_enable(struct drm_bridge *drm_bridge)
>   {
> +	struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
> +	struct msm_dp *dp = dp_bridge->dp_display;
>   	int rc = 0;
>   	struct dp_display_private *dp_display;
>   	u32 state;
> @@ -1537,7 +1556,7 @@ int msm_dp_display_enable(struct msm_dp *dp,
> struct drm_encoder *encoder)
>   	dp_display = container_of(dp, struct dp_display_private,
> dp_display);
>   	if (!dp_display->dp_mode.drm_mode.clock) {
>   		DRM_ERROR("invalid params\n");
> -		return -EINVAL;
> +		return;
>   	}
>    	mutex_lock(&dp_display->event_mutex);
> @@ -1549,14 +1568,14 @@ int msm_dp_display_enable(struct msm_dp *dp,
> struct drm_encoder *encoder)
>   	if (rc) {
>   		DRM_ERROR("Failed to perform a mode set, rc=%d\n", rc);
>   		mutex_unlock(&dp_display->event_mutex);
> -		return rc;
> +		return;
>   	}
>    	rc = dp_display_prepare(dp);
>   	if (rc) {
>   		DRM_ERROR("DP display prepare failed, rc=%d\n", rc);
>   		mutex_unlock(&dp_display->event_mutex);
> -		return rc;
> +		return;
>   	}
>    	state =  dp_display->hpd_state;
> @@ -1581,23 +1600,23 @@ int msm_dp_display_enable(struct msm_dp *dp,
> struct drm_encoder *encoder)
>   	dp_display->hpd_state = ST_CONNECTED;
>    	mutex_unlock(&dp_display->event_mutex);
> -
> -	return rc;
>   }
>   -int msm_dp_display_pre_disable(struct msm_dp *dp, struct drm_encoder
> *encoder)
> +void dp_bridge_disable(struct drm_bridge *drm_bridge)
>   {
> +	struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
> +	struct msm_dp *dp = dp_bridge->dp_display;
>   	struct dp_display_private *dp_display;
>    	dp_display = container_of(dp, struct dp_display_private,
> dp_display);
>    	dp_ctrl_push_idle(dp_display->ctrl);
> -
> -	return 0;
>   }
>   -int msm_dp_display_disable(struct msm_dp *dp, struct drm_encoder
> *encoder)
> +void dp_bridge_post_disable(struct drm_bridge *drm_bridge)
>   {
> +	struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
> +	struct msm_dp *dp = dp_bridge->dp_display;
>   	int rc = 0;
>   	u32 state;
>   	struct dp_display_private *dp_display; @@ -1624,13 +1643,14 @@
> int msm_dp_display_disable(struct msm_dp *dp, struct drm_encoder
> *encoder)
>   	}
>    	mutex_unlock(&dp_display->event_mutex);
> -	return rc;
>   }
>   -void msm_dp_display_mode_set(struct msm_dp *dp, struct drm_encoder
> *encoder,
> -				const struct drm_display_mode *mode,
> -				const struct drm_display_mode
> *adjusted_mode)
> +void dp_bridge_mode_set(struct drm_bridge *drm_bridge,
> +			const struct drm_display_mode *mode,
> +			const struct drm_display_mode *adjusted_mode)
>   {
> +	struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
> +	struct msm_dp *dp = dp_bridge->dp_display;
>   	struct dp_display_private *dp_display;
>    	dp_display = container_of(dp, struct dp_display_private,
> dp_display); diff --git a/drivers/gpu/drm/msm/dp/dp_display.h
> b/drivers/gpu/drm/msm/dp/dp_display.h
> index 7af2b186d2d9..49a1d89681ac 100644
> --- a/drivers/gpu/drm/msm/dp/dp_display.h
> +++ b/drivers/gpu/drm/msm/dp/dp_display.h
> @@ -32,7 +32,6 @@ struct msm_dp {
>    int dp_display_set_plugged_cb(struct msm_dp *dp_display,
>   		hdmi_codec_plugged_cb fn, struct device *codec_dev); -int
> dp_display_validate_mode(struct msm_dp *dp_display, u32
> mode_pclk_khz);
>   int dp_display_get_modes(struct msm_dp *dp_display,
>   		struct dp_display_mode *dp_mode);
>   int dp_display_request_irq(struct msm_dp *dp_display); diff --git
> a/drivers/gpu/drm/msm/dp/dp_drm.c
> b/drivers/gpu/drm/msm/dp/dp_drm.c index 57800b865fe6..7ce1aca48687
> 100644
> --- a/drivers/gpu/drm/msm/dp/dp_drm.c
> +++ b/drivers/gpu/drm/msm/dp/dp_drm.c
> @@ -13,14 +13,6 @@
>   #include "msm_kms.h"
>   #include "dp_drm.h"
>   -
> -struct msm_dp_bridge {
> -	struct drm_bridge bridge;
> -	struct msm_dp *dp_display;
> -};
> -
> -#define to_dp_display(x)     container_of((x), struct msm_dp_bridge,
> bridge)
> -
>   /**
>    * dp_bridge_detect - callback to determine if connector is connected
>    * @bridge: Pointer to drm bridge structure @@ -30,7 +22,7 @@ static enum
> drm_connector_status dp_bridge_detect(struct drm_bridge *bridge)
>   {
>   	struct msm_dp *dp;
>   -	dp = to_dp_display(bridge)->dp_display;
> +	dp = to_dp_bridge(bridge)->dp_display;
>    	DRM_DEBUG_DP("is_connected = %s\n",
>   		(dp->is_connected) ? "true" : "false"); @@ -55,7 +47,7 @@
> static int dp_bridge_get_modes(struct drm_bridge *bridge, struct
> drm_connector *
>   	if (!connector)
>   		return 0;
>   -	dp = to_dp_display(bridge)->dp_display;
> +	dp = to_dp_bridge(bridge)->dp_display;
>    	dp_mode = kzalloc(sizeof(*dp_mode),  GFP_KERNEL);
>   	if (!dp_mode)
> @@ -95,64 +87,6 @@ static int dp_bridge_get_modes(struct drm_bridge
> *bridge, struct drm_connector *
>   	return rc;
>   }
>   -/**
> - * dp_bridge_mode_valid - callback to determine if specified mode is valid
> - * @bridge: Pointer to drm bridge structure
> - * @info: display info
> - * @mode: Pointer to drm mode structure
> - * Returns: Validity status for specified mode
> - */
> -static enum drm_mode_status dp_bridge_mode_valid(
> -		struct drm_bridge *bridge,
> -		const struct drm_display_info *info,
> -		const struct drm_display_mode *mode)
> -{
> -	struct msm_dp *dp_disp;
> -
> -	dp_disp = to_dp_display(bridge)->dp_display;
> -
> -	if ((dp_disp->max_pclk_khz <= 0) ||
> -			(dp_disp->max_pclk_khz >
> DP_MAX_PIXEL_CLK_KHZ) ||
> -			(mode->clock > dp_disp->max_pclk_khz))
> -		return MODE_BAD;
> -
> -	return dp_display_validate_mode(dp_disp, mode->clock);
> -}
> -
> -static void dp_bridge_mode_set(struct drm_bridge *drm_bridge,
> -				const struct drm_display_mode *mode,
> -				const struct drm_display_mode
> *adjusted_mode)
> -{
> -	struct msm_dp_bridge *dp_bridge = to_dp_display(drm_bridge);
> -	struct msm_dp *dp_display = dp_bridge->dp_display;
> -
> -	msm_dp_display_mode_set(dp_display, drm_bridge->encoder,
> mode,
> adjusted_mode);
> -}
> -
> -static void dp_bridge_enable(struct drm_bridge *drm_bridge) -{
> -	struct msm_dp_bridge *dp_bridge = to_dp_display(drm_bridge);
> -	struct msm_dp *dp_display = dp_bridge->dp_display;
> -
> -	msm_dp_display_enable(dp_display, drm_bridge->encoder);
> -}
> -
> -static void dp_bridge_disable(struct drm_bridge *drm_bridge) -{
> -	struct msm_dp_bridge *dp_bridge = to_dp_display(drm_bridge);
> -	struct msm_dp *dp_display = dp_bridge->dp_display;
> -
> -	msm_dp_display_pre_disable(dp_display, drm_bridge->encoder);
> -}
> -
> -static void dp_bridge_post_disable(struct drm_bridge *drm_bridge) -{
> -	struct msm_dp_bridge *dp_bridge = to_dp_display(drm_bridge);
> -	struct msm_dp *dp_display = dp_bridge->dp_display;
> -
> -	msm_dp_display_disable(dp_display, drm_bridge->encoder);
> -}
> -
>   static const struct drm_bridge_funcs dp_bridge_ops = {
>   	.enable       = dp_bridge_enable,
>   	.disable      = dp_bridge_disable,
> @@ -163,7 +97,7 @@ static const struct drm_bridge_funcs dp_bridge_ops =
> {
>   	.detect       = dp_bridge_detect,
>   };
>   -struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display,
> struct drm_device *dev,
> +struct drm_bridge *dp_bridge_init(struct msm_dp *dp_display, struct
> drm_device *dev,
>   			struct drm_encoder *encoder)
>   {
>   	int rc;
> diff --git a/drivers/gpu/drm/msm/dp/dp_drm.h
> b/drivers/gpu/drm/msm/dp/dp_drm.h index c27bfceefdf0..f4b1ed1e24f7
> 100644
> --- a/drivers/gpu/drm/msm/dp/dp_drm.h
> +++ b/drivers/gpu/drm/msm/dp/dp_drm.h
> @@ -7,12 +7,30 @@
>   #define _DP_DRM_H_
>    #include <linux/types.h>
> -#include <drm/drm_crtc.h>
> -#include <drm/drm_crtc_helper.h>
> +#include <drm/drm_bridge.h>
>    #include "msm_drv.h"
>   #include "dp_display.h"
>   +struct msm_dp_bridge {
> +	struct drm_bridge bridge;
> +	struct msm_dp *dp_display;
> +};
> +
> +#define to_dp_bridge(x)     container_of((x), struct msm_dp_bridge,
> bridge)
> +
>   struct drm_connector *dp_drm_connector_init(struct msm_dp
> *dp_display);
> +struct drm_bridge *dp_bridge_init(struct msm_dp *dp_display, struct
> drm_device *dev,
> +			struct drm_encoder *encoder);
> +
> +void dp_bridge_enable(struct drm_bridge *drm_bridge); void
> +dp_bridge_disable(struct drm_bridge *drm_bridge); void
> +dp_bridge_post_disable(struct drm_bridge *drm_bridge); enum
> +drm_mode_status dp_bridge_mode_valid(struct drm_bridge *bridge,
> +					  const struct drm_display_info *info,
> +					  const struct drm_display_mode
> *mode); void
> +dp_bridge_mode_set(struct drm_bridge *drm_bridge,
> +			const struct drm_display_mode *mode,
> +			const struct drm_display_mode *adjusted_mode);
>    #endif /* _DP_DRM_H_ */
> diff --git a/drivers/gpu/drm/msm/msm_drv.h
> b/drivers/gpu/drm/msm/msm_drv.h index d7574e6bd4e4..b698a3be6072
> 100644
> --- a/drivers/gpu/drm/msm/msm_drv.h
> +++ b/drivers/gpu/drm/msm/msm_drv.h
> @@ -385,16 +385,6 @@ int __init msm_dp_register(void);
>   void __exit msm_dp_unregister(void);
>   int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device
> *dev,
>   			 struct drm_encoder *encoder);
> -int msm_dp_display_enable(struct msm_dp *dp, struct drm_encoder
> *encoder); -int msm_dp_display_disable(struct msm_dp *dp, struct
> drm_encoder *encoder); -int msm_dp_display_pre_disable(struct msm_dp
> *dp, struct drm_encoder *encoder); -void
> msm_dp_display_mode_set(struct msm_dp *dp, struct drm_encoder
> *encoder,
> -				const struct drm_display_mode *mode,
> -				const struct drm_display_mode
> *adjusted_mode);
> -
> -struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display,
> -					struct drm_device *dev,
> -					struct drm_encoder *encoder);
>   void msm_dp_irq_postinstall(struct msm_dp *dp_display);
>   void msm_dp_snapshot(struct msm_disp_state *disp_state, struct
> msm_dp *dp_display);
>   @@ -414,27 +404,6 @@ static inline int msm_dp_modeset_init(struct
> msm_dp *dp_display,
>   {
>   	return -EINVAL;
>   }
> -static inline int msm_dp_display_enable(struct msm_dp *dp,
> -					struct drm_encoder *encoder)
> -{
> -	return -EINVAL;
> -}
> -static inline int msm_dp_display_disable(struct msm_dp *dp,
> -					struct drm_encoder *encoder)
> -{
> -	return -EINVAL;
> -}
> -static inline int msm_dp_display_pre_disable(struct msm_dp *dp,
> -					struct drm_encoder *encoder)
> -{
> -	return -EINVAL;
> -}
> -static inline void msm_dp_display_mode_set(struct msm_dp *dp,
> -				struct drm_encoder *encoder,
> -				const struct drm_display_mode *mode,
> -				const struct drm_display_mode
> *adjusted_mode)
> -{
> -}
>    static inline void msm_dp_irq_postinstall(struct msm_dp *dp_display)
>   {
> --
> 2.34.1


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

* RE: [RFC PATCH v2 4/5] drm/msm/dp: replace dp_connector with drm_bridge_connector
       [not found]                     ` <64a5ae1a-df65-b0a5-5d0d-cfb1d4da3bf7@quicinc.com>
@ 2022-03-16 16:45                         ` Sankeerth Billakanti (QUIC)
  0 siblings, 0 replies; 84+ messages in thread
From: Sankeerth Billakanti (QUIC) @ 2022-03-16 16:45 UTC (permalink / raw)
  To: swboyd, dmitry.baryshkov
  Cc: Abhinav Kumar (QUIC), Sankeerth Billakanti (QUIC),
	bjorn.andersson, robdclark, sean, airlied, daniel, linux-arm-msm,
	dri-devel, freedreno

> Subject: Re: [RFC PATCH v2 4/5] drm/msm/dp: replace dp_connector with
> drm_bridge_connector
> Date: Wed, 23 Feb 2022 16:40:56 -0800
> From: Kuogee Hsieh <quic_khsieh@quicinc.com>
> To: Stephen Boyd <swboyd@chromium.org>, Dmitry Baryshkov
> <dmitry.baryshkov@linaro.org>
> CC: Abhinav Kumar <quic_abhinavk@quicinc.com>, Bjorn Andersson
> <bjorn.andersson@linaro.org>, Rob Clark <robdclark@gmail.com>, Sean Paul
> <sean@poorly.run>, David Airlie <airlied@linux.ie>, Daniel Vetter
> <daniel@ffwll.ch>, linux-arm-msm@vger.kernel.org, dri-
> devel@lists.freedesktop.org, freedreno@lists.freedesktop.org
> 
> 
> On 2/23/2022 1:33 PM, Stephen Boyd wrote:
> > Quoting Kuogee Hsieh (2022-02-23 10:27:26)
> >> On 2/23/2022 10:22 AM, Dmitry Baryshkov wrote:
> >>> On 23/02/2022 20:21, Kuogee Hsieh wrote:
> >>>
> >>> In the panel device node.
> >>>
> >>> Can you please share it too?
> >>
> >> &soc {
> >>           edp_power_supply: edp_power {
> >>                   compatible = "regulator-fixed";
> >>                   regulator-name = "edp_backlight_power";
> >>
> >>                   regulator-always-on;
> >>                   regulator-boot-on;
> >>           };
> >>
> >>           edp_backlight: edp_backlight {
> >>                   compatible = "pwm-backlight";
> >>
> >>                   pwms = <&pm8350c_pwm 3 65535>;
> >>                   power-supply = <&edp_power_supply>;
> >>                   enable-gpio = <&pm8350c_gpios 7 GPIO_ACTIVE_HIGH>;
> >>
> >>                   pinctrl-names = "default";
> >>                   pinctrl-0 = <&backlight_pwm_default>;
> >>           };
> >>
> >>           edp_panel: edp_panel {
> >>                   compatible = "sharp_lq140m1jw46";
> > Is that supposed to be sharp,lq140m1jw46 with a comma instead of an
> > underscore?
> 
> Stephen,
> 
> This is our internal branch which does not have patches up to date yet.
> 
> I will cherry-pick newer edp related patches which are under review now to
> re test it.

Tested-by: Sankeerth Billakanti <quic_sbillaka@quicinc.com>

Detect returned eDP not connected because the panel power was not on and mode_valid was failing because the DP mode_valid is different from eDP

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

* RE: [RFC PATCH v2 4/5] drm/msm/dp: replace dp_connector with drm_bridge_connector
@ 2022-03-16 16:45                         ` Sankeerth Billakanti (QUIC)
  0 siblings, 0 replies; 84+ messages in thread
From: Sankeerth Billakanti (QUIC) @ 2022-03-16 16:45 UTC (permalink / raw)
  To: swboyd, dmitry.baryshkov
  Cc: freedreno, Sankeerth Billakanti (QUIC),
	airlied, linux-arm-msm, Abhinav Kumar (QUIC),
	dri-devel, bjorn.andersson, sean

> Subject: Re: [RFC PATCH v2 4/5] drm/msm/dp: replace dp_connector with
> drm_bridge_connector
> Date: Wed, 23 Feb 2022 16:40:56 -0800
> From: Kuogee Hsieh <quic_khsieh@quicinc.com>
> To: Stephen Boyd <swboyd@chromium.org>, Dmitry Baryshkov
> <dmitry.baryshkov@linaro.org>
> CC: Abhinav Kumar <quic_abhinavk@quicinc.com>, Bjorn Andersson
> <bjorn.andersson@linaro.org>, Rob Clark <robdclark@gmail.com>, Sean Paul
> <sean@poorly.run>, David Airlie <airlied@linux.ie>, Daniel Vetter
> <daniel@ffwll.ch>, linux-arm-msm@vger.kernel.org, dri-
> devel@lists.freedesktop.org, freedreno@lists.freedesktop.org
> 
> 
> On 2/23/2022 1:33 PM, Stephen Boyd wrote:
> > Quoting Kuogee Hsieh (2022-02-23 10:27:26)
> >> On 2/23/2022 10:22 AM, Dmitry Baryshkov wrote:
> >>> On 23/02/2022 20:21, Kuogee Hsieh wrote:
> >>>
> >>> In the panel device node.
> >>>
> >>> Can you please share it too?
> >>
> >> &soc {
> >>           edp_power_supply: edp_power {
> >>                   compatible = "regulator-fixed";
> >>                   regulator-name = "edp_backlight_power";
> >>
> >>                   regulator-always-on;
> >>                   regulator-boot-on;
> >>           };
> >>
> >>           edp_backlight: edp_backlight {
> >>                   compatible = "pwm-backlight";
> >>
> >>                   pwms = <&pm8350c_pwm 3 65535>;
> >>                   power-supply = <&edp_power_supply>;
> >>                   enable-gpio = <&pm8350c_gpios 7 GPIO_ACTIVE_HIGH>;
> >>
> >>                   pinctrl-names = "default";
> >>                   pinctrl-0 = <&backlight_pwm_default>;
> >>           };
> >>
> >>           edp_panel: edp_panel {
> >>                   compatible = "sharp_lq140m1jw46";
> > Is that supposed to be sharp,lq140m1jw46 with a comma instead of an
> > underscore?
> 
> Stephen,
> 
> This is our internal branch which does not have patches up to date yet.
> 
> I will cherry-pick newer edp related patches which are under review now to
> re test it.

Tested-by: Sankeerth Billakanti <quic_sbillaka@quicinc.com>

Detect returned eDP not connected because the panel power was not on and mode_valid was failing because the DP mode_valid is different from eDP

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

* Re: [RFC PATCH v2 5/5] drm/msm/dp: remove extra wrappers and public functions
  2022-03-16 16:31       ` Sankeerth Billakanti (QUIC)
@ 2022-04-14 20:17         ` Abhinav Kumar
  -1 siblings, 0 replies; 84+ messages in thread
From: Abhinav Kumar @ 2022-04-14 20:17 UTC (permalink / raw)
  To: Sankeerth Billakanti (QUIC),
	bjorn.andersson, robdclark, sean, Kuogee Hsieh (QUIC)
  Cc: swboyd, airlied, daniel, linux-arm-msm, dri-devel, freedreno



On 3/16/2022 9:31 AM, Sankeerth Billakanti (QUIC) wrote:
>> Subject: [RFC PATCH v2 5/5] drm/msm/dp: remove extra wrappers and
>> public functions
>> Date: Sat, 12 Feb 2022 01:40:06 +0300
>> From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>> To: Bjorn Andersson <bjorn.andersson@linaro.org>, Rob Clark
>> <robdclark@gmail.com>, Sean Paul <sean@poorly.run>, Abhinav Kumar
>> <quic_abhinavk@quicinc.com>, Kuogee Hsieh <quic_khsieh@quicinc.com>
>> CC: Stephen Boyd <swboyd@chromium.org>, David Airlie <airlied@linux.ie>,
>> Daniel Vetter <daniel@ffwll.ch>, linux-arm-msm@vger.kernel.org, dri-
>> devel@lists.freedesktop.org, freedreno@lists.freedesktop.org
>>
>> dp_bridge's functions are thin wrappers around the msm_dp_display_*
>> family. Squash dp_bridge callbacks into respective msm_dp_display
>> functions, removing the latter functions from public space.
>>
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> 
> 
> Tested-by: Sankeerth Billakanti <quic_sbillaka@quicinc.com>
Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>

> 
> 
>> ---
>>    drivers/gpu/drm/msm/dp/dp_display.c | 54 +++++++++++++++-------
>>    drivers/gpu/drm/msm/dp/dp_display.h |  1 -
>>    drivers/gpu/drm/msm/dp/dp_drm.c     | 72 ++---------------------------
>>    drivers/gpu/drm/msm/dp/dp_drm.h     | 22 ++++++++-
>>    drivers/gpu/drm/msm/msm_drv.h       | 31 -------------
>>    5 files changed, 60 insertions(+), 120 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/dp/dp_display.c
>> b/drivers/gpu/drm/msm/dp/dp_display.c
>> index 59e5e5b8e5b4..a9b641a68bff 100644
>> --- a/drivers/gpu/drm/msm/dp/dp_display.c
>> +++ b/drivers/gpu/drm/msm/dp/dp_display.c
>> @@ -10,7 +10,6 @@
>>    #include <linux/component.h>
>>    #include <linux/of_irq.h>
>>    #include <linux/delay.h>
>> -#include <drm/drm_panel.h>
>>     #include "msm_drv.h"
>>    #include "msm_kms.h"
>> @@ -945,18 +944,36 @@ int dp_display_set_plugged_cb(struct msm_dp
>> *dp_display,
>>        return 0;
>>    }
>>    -int dp_display_validate_mode(struct msm_dp *dp, u32 mode_pclk_khz)
>> +/**
>> + * dp_bridge_mode_valid - callback to determine if specified mode is
>> +valid
>> + * @bridge: Pointer to drm bridge structure
>> + * @info: display info
>> + * @mode: Pointer to drm mode structure
>> + * Returns: Validity status for specified mode  */ enum drm_mode_status
>> +dp_bridge_mode_valid(struct drm_bridge *bridge,
>> +                                       const struct drm_display_info *info,
>> +                                       const struct drm_display_mode
>> *mode)
>>    {
>>        const u32 num_components = 3, default_bpp = 24;
>>        struct dp_display_private *dp_display;
>>        struct dp_link_info *link_info;
>>        u32 mode_rate_khz = 0, supported_rate_khz = 0, mode_bpp = 0;
>> +     struct msm_dp *dp;
>> +     int mode_pclk_khz = mode->clock;
>> +
>> +     dp = to_dp_bridge(bridge)->dp_display;
>>        if (!dp || !mode_pclk_khz || !dp->connector) {
>>                DRM_ERROR("invalid params\n");
>>                return -EINVAL;
>>        }
>>    +   if ((dp->max_pclk_khz <= 0) ||
>> +                     (dp->max_pclk_khz > DP_MAX_PIXEL_CLK_KHZ) ||
>> +                     (mode->clock > dp->max_pclk_khz))
>> +             return MODE_BAD;
>> +
>>        dp_display = container_of(dp, struct dp_display_private,
>> dp_display);
>>        link_info = &dp_display->panel->link_info;
>>    @@ -1501,7 +1518,7 @@ int msm_dp_modeset_init(struct msm_dp
>> *dp_display, struct drm_device *dev,
>>        dp_display->encoder = encoder;
>>    -   dp_display->bridge = msm_dp_bridge_init(dp_display, dev,
>> encoder);
>> +     dp_display->bridge = dp_bridge_init(dp_display, dev, encoder);
>>        if (IS_ERR(dp_display->bridge)) {
>>                ret = PTR_ERR(dp_display->bridge);
>>                DRM_DEV_ERROR(dev->dev,
>> @@ -1528,8 +1545,10 @@ int msm_dp_modeset_init(struct msm_dp
>> *dp_display, struct drm_device *dev,
>>        return 0;
>>    }
>>    -int msm_dp_display_enable(struct msm_dp *dp, struct drm_encoder
>> *encoder)
>> +void dp_bridge_enable(struct drm_bridge *drm_bridge)
>>    {
>> +     struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
>> +     struct msm_dp *dp = dp_bridge->dp_display;
>>        int rc = 0;
>>        struct dp_display_private *dp_display;
>>        u32 state;
>> @@ -1537,7 +1556,7 @@ int msm_dp_display_enable(struct msm_dp *dp,
>> struct drm_encoder *encoder)
>>        dp_display = container_of(dp, struct dp_display_private,
>> dp_display);
>>        if (!dp_display->dp_mode.drm_mode.clock) {
>>                DRM_ERROR("invalid params\n");
>> -             return -EINVAL;
>> +             return;
>>        }
>>        mutex_lock(&dp_display->event_mutex);
>> @@ -1549,14 +1568,14 @@ int msm_dp_display_enable(struct msm_dp *dp,
>> struct drm_encoder *encoder)
>>        if (rc) {
>>                DRM_ERROR("Failed to perform a mode set, rc=%d\n", rc);
>>                mutex_unlock(&dp_display->event_mutex);
>> -             return rc;
>> +             return;
>>        }
>>        rc = dp_display_prepare(dp);
>>        if (rc) {
>>                DRM_ERROR("DP display prepare failed, rc=%d\n", rc);
>>                mutex_unlock(&dp_display->event_mutex);
>> -             return rc;
>> +             return;
>>        }
>>        state =  dp_display->hpd_state;
>> @@ -1581,23 +1600,23 @@ int msm_dp_display_enable(struct msm_dp *dp,
>> struct drm_encoder *encoder)
>>        dp_display->hpd_state = ST_CONNECTED;
>>        mutex_unlock(&dp_display->event_mutex);
>> -
>> -     return rc;
>>    }
>>    -int msm_dp_display_pre_disable(struct msm_dp *dp, struct drm_encoder
>> *encoder)
>> +void dp_bridge_disable(struct drm_bridge *drm_bridge)
>>    {
>> +     struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
>> +     struct msm_dp *dp = dp_bridge->dp_display;
>>        struct dp_display_private *dp_display;
>>        dp_display = container_of(dp, struct dp_display_private,
>> dp_display);
>>        dp_ctrl_push_idle(dp_display->ctrl);
>> -
>> -     return 0;
>>    }
>>    -int msm_dp_display_disable(struct msm_dp *dp, struct drm_encoder
>> *encoder)
>> +void dp_bridge_post_disable(struct drm_bridge *drm_bridge)
>>    {
>> +     struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
>> +     struct msm_dp *dp = dp_bridge->dp_display;
>>        int rc = 0;
>>        u32 state;
>>        struct dp_display_private *dp_display; @@ -1624,13 +1643,14 @@
>> int msm_dp_display_disable(struct msm_dp *dp, struct drm_encoder
>> *encoder)
>>        }
>>        mutex_unlock(&dp_display->event_mutex);
>> -     return rc;
>>    }
>>    -void msm_dp_display_mode_set(struct msm_dp *dp, struct drm_encoder
>> *encoder,
>> -                             const struct drm_display_mode *mode,
>> -                             const struct drm_display_mode
>> *adjusted_mode)
>> +void dp_bridge_mode_set(struct drm_bridge *drm_bridge,
>> +                     const struct drm_display_mode *mode,
>> +                     const struct drm_display_mode *adjusted_mode)
>>    {
>> +     struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
>> +     struct msm_dp *dp = dp_bridge->dp_display;
>>        struct dp_display_private *dp_display;
>>        dp_display = container_of(dp, struct dp_display_private,
>> dp_display); diff --git a/drivers/gpu/drm/msm/dp/dp_display.h
>> b/drivers/gpu/drm/msm/dp/dp_display.h
>> index 7af2b186d2d9..49a1d89681ac 100644
>> --- a/drivers/gpu/drm/msm/dp/dp_display.h
>> +++ b/drivers/gpu/drm/msm/dp/dp_display.h
>> @@ -32,7 +32,6 @@ struct msm_dp {
>>     int dp_display_set_plugged_cb(struct msm_dp *dp_display,
>>                hdmi_codec_plugged_cb fn, struct device *codec_dev); -int
>> dp_display_validate_mode(struct msm_dp *dp_display, u32
>> mode_pclk_khz);
>>    int dp_display_get_modes(struct msm_dp *dp_display,
>>                struct dp_display_mode *dp_mode);
>>    int dp_display_request_irq(struct msm_dp *dp_display); diff --git
>> a/drivers/gpu/drm/msm/dp/dp_drm.c
>> b/drivers/gpu/drm/msm/dp/dp_drm.c index 57800b865fe6..7ce1aca48687
>> 100644
>> --- a/drivers/gpu/drm/msm/dp/dp_drm.c
>> +++ b/drivers/gpu/drm/msm/dp/dp_drm.c
>> @@ -13,14 +13,6 @@
>>    #include "msm_kms.h"
>>    #include "dp_drm.h"
>>    -
>> -struct msm_dp_bridge {
>> -     struct drm_bridge bridge;
>> -     struct msm_dp *dp_display;
>> -};
>> -
>> -#define to_dp_display(x)     container_of((x), struct msm_dp_bridge,
>> bridge)
>> -
>>    /**
>>     * dp_bridge_detect - callback to determine if connector is connected
>>     * @bridge: Pointer to drm bridge structure @@ -30,7 +22,7 @@ static enum
>> drm_connector_status dp_bridge_detect(struct drm_bridge *bridge)
>>    {
>>        struct msm_dp *dp;
>>    -   dp = to_dp_display(bridge)->dp_display;
>> +     dp = to_dp_bridge(bridge)->dp_display;
>>        DRM_DEBUG_DP("is_connected = %s\n",
>>                (dp->is_connected) ? "true" : "false"); @@ -55,7 +47,7 @@
>> static int dp_bridge_get_modes(struct drm_bridge *bridge, struct
>> drm_connector *
>>        if (!connector)
>>                return 0;
>>    -   dp = to_dp_display(bridge)->dp_display;
>> +     dp = to_dp_bridge(bridge)->dp_display;
>>        dp_mode = kzalloc(sizeof(*dp_mode),  GFP_KERNEL);
>>        if (!dp_mode)
>> @@ -95,64 +87,6 @@ static int dp_bridge_get_modes(struct drm_bridge
>> *bridge, struct drm_connector *
>>        return rc;
>>    }
>>    -/**
>> - * dp_bridge_mode_valid - callback to determine if specified mode is valid
>> - * @bridge: Pointer to drm bridge structure
>> - * @info: display info
>> - * @mode: Pointer to drm mode structure
>> - * Returns: Validity status for specified mode
>> - */
>> -static enum drm_mode_status dp_bridge_mode_valid(
>> -             struct drm_bridge *bridge,
>> -             const struct drm_display_info *info,
>> -             const struct drm_display_mode *mode)
>> -{
>> -     struct msm_dp *dp_disp;
>> -
>> -     dp_disp = to_dp_display(bridge)->dp_display;
>> -
>> -     if ((dp_disp->max_pclk_khz <= 0) ||
>> -                     (dp_disp->max_pclk_khz >
>> DP_MAX_PIXEL_CLK_KHZ) ||
>> -                     (mode->clock > dp_disp->max_pclk_khz))
>> -             return MODE_BAD;
>> -
>> -     return dp_display_validate_mode(dp_disp, mode->clock);
>> -}
>> -
>> -static void dp_bridge_mode_set(struct drm_bridge *drm_bridge,
>> -                             const struct drm_display_mode *mode,
>> -                             const struct drm_display_mode
>> *adjusted_mode)
>> -{
>> -     struct msm_dp_bridge *dp_bridge = to_dp_display(drm_bridge);
>> -     struct msm_dp *dp_display = dp_bridge->dp_display;
>> -
>> -     msm_dp_display_mode_set(dp_display, drm_bridge->encoder,
>> mode,
>> adjusted_mode);
>> -}
>> -
>> -static void dp_bridge_enable(struct drm_bridge *drm_bridge) -{
>> -     struct msm_dp_bridge *dp_bridge = to_dp_display(drm_bridge);
>> -     struct msm_dp *dp_display = dp_bridge->dp_display;
>> -
>> -     msm_dp_display_enable(dp_display, drm_bridge->encoder);
>> -}
>> -
>> -static void dp_bridge_disable(struct drm_bridge *drm_bridge) -{
>> -     struct msm_dp_bridge *dp_bridge = to_dp_display(drm_bridge);
>> -     struct msm_dp *dp_display = dp_bridge->dp_display;
>> -
>> -     msm_dp_display_pre_disable(dp_display, drm_bridge->encoder);
>> -}
>> -
>> -static void dp_bridge_post_disable(struct drm_bridge *drm_bridge) -{
>> -     struct msm_dp_bridge *dp_bridge = to_dp_display(drm_bridge);
>> -     struct msm_dp *dp_display = dp_bridge->dp_display;
>> -
>> -     msm_dp_display_disable(dp_display, drm_bridge->encoder);
>> -}
>> -
>>    static const struct drm_bridge_funcs dp_bridge_ops = {
>>        .enable       = dp_bridge_enable,
>>        .disable      = dp_bridge_disable,
>> @@ -163,7 +97,7 @@ static const struct drm_bridge_funcs dp_bridge_ops =
>> {
>>        .detect       = dp_bridge_detect,
>>    };
>>    -struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display,
>> struct drm_device *dev,
>> +struct drm_bridge *dp_bridge_init(struct msm_dp *dp_display, struct
>> drm_device *dev,
>>                        struct drm_encoder *encoder)
>>    {
>>        int rc;
>> diff --git a/drivers/gpu/drm/msm/dp/dp_drm.h
>> b/drivers/gpu/drm/msm/dp/dp_drm.h index c27bfceefdf0..f4b1ed1e24f7
>> 100644
>> --- a/drivers/gpu/drm/msm/dp/dp_drm.h
>> +++ b/drivers/gpu/drm/msm/dp/dp_drm.h
>> @@ -7,12 +7,30 @@
>>    #define _DP_DRM_H_
>>     #include <linux/types.h>
>> -#include <drm/drm_crtc.h>
>> -#include <drm/drm_crtc_helper.h>
>> +#include <drm/drm_bridge.h>
>>     #include "msm_drv.h"
>>    #include "dp_display.h"
>>    +struct msm_dp_bridge {
>> +     struct drm_bridge bridge;
>> +     struct msm_dp *dp_display;
>> +};
>> +
>> +#define to_dp_bridge(x)     container_of((x), struct msm_dp_bridge,
>> bridge)
>> +
>>    struct drm_connector *dp_drm_connector_init(struct msm_dp
>> *dp_display);
>> +struct drm_bridge *dp_bridge_init(struct msm_dp *dp_display, struct
>> drm_device *dev,
>> +                     struct drm_encoder *encoder);
>> +
>> +void dp_bridge_enable(struct drm_bridge *drm_bridge); void
>> +dp_bridge_disable(struct drm_bridge *drm_bridge); void
>> +dp_bridge_post_disable(struct drm_bridge *drm_bridge); enum
>> +drm_mode_status dp_bridge_mode_valid(struct drm_bridge *bridge,
>> +                                       const struct drm_display_info *info,
>> +                                       const struct drm_display_mode
>> *mode); void
>> +dp_bridge_mode_set(struct drm_bridge *drm_bridge,
>> +                     const struct drm_display_mode *mode,
>> +                     const struct drm_display_mode *adjusted_mode);
>>     #endif /* _DP_DRM_H_ */
>> diff --git a/drivers/gpu/drm/msm/msm_drv.h
>> b/drivers/gpu/drm/msm/msm_drv.h index d7574e6bd4e4..b698a3be6072
>> 100644
>> --- a/drivers/gpu/drm/msm/msm_drv.h
>> +++ b/drivers/gpu/drm/msm/msm_drv.h
>> @@ -385,16 +385,6 @@ int __init msm_dp_register(void);
>>    void __exit msm_dp_unregister(void);
>>    int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device
>> *dev,
>>                         struct drm_encoder *encoder);
>> -int msm_dp_display_enable(struct msm_dp *dp, struct drm_encoder
>> *encoder); -int msm_dp_display_disable(struct msm_dp *dp, struct
>> drm_encoder *encoder); -int msm_dp_display_pre_disable(struct msm_dp
>> *dp, struct drm_encoder *encoder); -void
>> msm_dp_display_mode_set(struct msm_dp *dp, struct drm_encoder
>> *encoder,
>> -                             const struct drm_display_mode *mode,
>> -                             const struct drm_display_mode
>> *adjusted_mode);
>> -
>> -struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display,
>> -                                     struct drm_device *dev,
>> -                                     struct drm_encoder *encoder);
>>    void msm_dp_irq_postinstall(struct msm_dp *dp_display);
>>    void msm_dp_snapshot(struct msm_disp_state *disp_state, struct
>> msm_dp *dp_display);
>>    @@ -414,27 +404,6 @@ static inline int msm_dp_modeset_init(struct
>> msm_dp *dp_display,
>>    {
>>        return -EINVAL;
>>    }
>> -static inline int msm_dp_display_enable(struct msm_dp *dp,
>> -                                     struct drm_encoder *encoder)
>> -{
>> -     return -EINVAL;
>> -}
>> -static inline int msm_dp_display_disable(struct msm_dp *dp,
>> -                                     struct drm_encoder *encoder)
>> -{
>> -     return -EINVAL;
>> -}
>> -static inline int msm_dp_display_pre_disable(struct msm_dp *dp,
>> -                                     struct drm_encoder *encoder)
>> -{
>> -     return -EINVAL;
>> -}
>> -static inline void msm_dp_display_mode_set(struct msm_dp *dp,
>> -                             struct drm_encoder *encoder,
>> -                             const struct drm_display_mode *mode,
>> -                             const struct drm_display_mode
>> *adjusted_mode)
>> -{
>> -}
>>     static inline void msm_dp_irq_postinstall(struct msm_dp *dp_display)
>>    {
>> --
>> 2.34.1
> 

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

* Re: [RFC PATCH v2 5/5] drm/msm/dp: remove extra wrappers and public functions
@ 2022-04-14 20:17         ` Abhinav Kumar
  0 siblings, 0 replies; 84+ messages in thread
From: Abhinav Kumar @ 2022-04-14 20:17 UTC (permalink / raw)
  To: Sankeerth Billakanti (QUIC),
	bjorn.andersson, robdclark, sean, Kuogee Hsieh (QUIC)
  Cc: airlied, linux-arm-msm, dri-devel, swboyd, freedreno



On 3/16/2022 9:31 AM, Sankeerth Billakanti (QUIC) wrote:
>> Subject: [RFC PATCH v2 5/5] drm/msm/dp: remove extra wrappers and
>> public functions
>> Date: Sat, 12 Feb 2022 01:40:06 +0300
>> From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>> To: Bjorn Andersson <bjorn.andersson@linaro.org>, Rob Clark
>> <robdclark@gmail.com>, Sean Paul <sean@poorly.run>, Abhinav Kumar
>> <quic_abhinavk@quicinc.com>, Kuogee Hsieh <quic_khsieh@quicinc.com>
>> CC: Stephen Boyd <swboyd@chromium.org>, David Airlie <airlied@linux.ie>,
>> Daniel Vetter <daniel@ffwll.ch>, linux-arm-msm@vger.kernel.org, dri-
>> devel@lists.freedesktop.org, freedreno@lists.freedesktop.org
>>
>> dp_bridge's functions are thin wrappers around the msm_dp_display_*
>> family. Squash dp_bridge callbacks into respective msm_dp_display
>> functions, removing the latter functions from public space.
>>
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> 
> 
> Tested-by: Sankeerth Billakanti <quic_sbillaka@quicinc.com>
Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>

> 
> 
>> ---
>>    drivers/gpu/drm/msm/dp/dp_display.c | 54 +++++++++++++++-------
>>    drivers/gpu/drm/msm/dp/dp_display.h |  1 -
>>    drivers/gpu/drm/msm/dp/dp_drm.c     | 72 ++---------------------------
>>    drivers/gpu/drm/msm/dp/dp_drm.h     | 22 ++++++++-
>>    drivers/gpu/drm/msm/msm_drv.h       | 31 -------------
>>    5 files changed, 60 insertions(+), 120 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/dp/dp_display.c
>> b/drivers/gpu/drm/msm/dp/dp_display.c
>> index 59e5e5b8e5b4..a9b641a68bff 100644
>> --- a/drivers/gpu/drm/msm/dp/dp_display.c
>> +++ b/drivers/gpu/drm/msm/dp/dp_display.c
>> @@ -10,7 +10,6 @@
>>    #include <linux/component.h>
>>    #include <linux/of_irq.h>
>>    #include <linux/delay.h>
>> -#include <drm/drm_panel.h>
>>     #include "msm_drv.h"
>>    #include "msm_kms.h"
>> @@ -945,18 +944,36 @@ int dp_display_set_plugged_cb(struct msm_dp
>> *dp_display,
>>        return 0;
>>    }
>>    -int dp_display_validate_mode(struct msm_dp *dp, u32 mode_pclk_khz)
>> +/**
>> + * dp_bridge_mode_valid - callback to determine if specified mode is
>> +valid
>> + * @bridge: Pointer to drm bridge structure
>> + * @info: display info
>> + * @mode: Pointer to drm mode structure
>> + * Returns: Validity status for specified mode  */ enum drm_mode_status
>> +dp_bridge_mode_valid(struct drm_bridge *bridge,
>> +                                       const struct drm_display_info *info,
>> +                                       const struct drm_display_mode
>> *mode)
>>    {
>>        const u32 num_components = 3, default_bpp = 24;
>>        struct dp_display_private *dp_display;
>>        struct dp_link_info *link_info;
>>        u32 mode_rate_khz = 0, supported_rate_khz = 0, mode_bpp = 0;
>> +     struct msm_dp *dp;
>> +     int mode_pclk_khz = mode->clock;
>> +
>> +     dp = to_dp_bridge(bridge)->dp_display;
>>        if (!dp || !mode_pclk_khz || !dp->connector) {
>>                DRM_ERROR("invalid params\n");
>>                return -EINVAL;
>>        }
>>    +   if ((dp->max_pclk_khz <= 0) ||
>> +                     (dp->max_pclk_khz > DP_MAX_PIXEL_CLK_KHZ) ||
>> +                     (mode->clock > dp->max_pclk_khz))
>> +             return MODE_BAD;
>> +
>>        dp_display = container_of(dp, struct dp_display_private,
>> dp_display);
>>        link_info = &dp_display->panel->link_info;
>>    @@ -1501,7 +1518,7 @@ int msm_dp_modeset_init(struct msm_dp
>> *dp_display, struct drm_device *dev,
>>        dp_display->encoder = encoder;
>>    -   dp_display->bridge = msm_dp_bridge_init(dp_display, dev,
>> encoder);
>> +     dp_display->bridge = dp_bridge_init(dp_display, dev, encoder);
>>        if (IS_ERR(dp_display->bridge)) {
>>                ret = PTR_ERR(dp_display->bridge);
>>                DRM_DEV_ERROR(dev->dev,
>> @@ -1528,8 +1545,10 @@ int msm_dp_modeset_init(struct msm_dp
>> *dp_display, struct drm_device *dev,
>>        return 0;
>>    }
>>    -int msm_dp_display_enable(struct msm_dp *dp, struct drm_encoder
>> *encoder)
>> +void dp_bridge_enable(struct drm_bridge *drm_bridge)
>>    {
>> +     struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
>> +     struct msm_dp *dp = dp_bridge->dp_display;
>>        int rc = 0;
>>        struct dp_display_private *dp_display;
>>        u32 state;
>> @@ -1537,7 +1556,7 @@ int msm_dp_display_enable(struct msm_dp *dp,
>> struct drm_encoder *encoder)
>>        dp_display = container_of(dp, struct dp_display_private,
>> dp_display);
>>        if (!dp_display->dp_mode.drm_mode.clock) {
>>                DRM_ERROR("invalid params\n");
>> -             return -EINVAL;
>> +             return;
>>        }
>>        mutex_lock(&dp_display->event_mutex);
>> @@ -1549,14 +1568,14 @@ int msm_dp_display_enable(struct msm_dp *dp,
>> struct drm_encoder *encoder)
>>        if (rc) {
>>                DRM_ERROR("Failed to perform a mode set, rc=%d\n", rc);
>>                mutex_unlock(&dp_display->event_mutex);
>> -             return rc;
>> +             return;
>>        }
>>        rc = dp_display_prepare(dp);
>>        if (rc) {
>>                DRM_ERROR("DP display prepare failed, rc=%d\n", rc);
>>                mutex_unlock(&dp_display->event_mutex);
>> -             return rc;
>> +             return;
>>        }
>>        state =  dp_display->hpd_state;
>> @@ -1581,23 +1600,23 @@ int msm_dp_display_enable(struct msm_dp *dp,
>> struct drm_encoder *encoder)
>>        dp_display->hpd_state = ST_CONNECTED;
>>        mutex_unlock(&dp_display->event_mutex);
>> -
>> -     return rc;
>>    }
>>    -int msm_dp_display_pre_disable(struct msm_dp *dp, struct drm_encoder
>> *encoder)
>> +void dp_bridge_disable(struct drm_bridge *drm_bridge)
>>    {
>> +     struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
>> +     struct msm_dp *dp = dp_bridge->dp_display;
>>        struct dp_display_private *dp_display;
>>        dp_display = container_of(dp, struct dp_display_private,
>> dp_display);
>>        dp_ctrl_push_idle(dp_display->ctrl);
>> -
>> -     return 0;
>>    }
>>    -int msm_dp_display_disable(struct msm_dp *dp, struct drm_encoder
>> *encoder)
>> +void dp_bridge_post_disable(struct drm_bridge *drm_bridge)
>>    {
>> +     struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
>> +     struct msm_dp *dp = dp_bridge->dp_display;
>>        int rc = 0;
>>        u32 state;
>>        struct dp_display_private *dp_display; @@ -1624,13 +1643,14 @@
>> int msm_dp_display_disable(struct msm_dp *dp, struct drm_encoder
>> *encoder)
>>        }
>>        mutex_unlock(&dp_display->event_mutex);
>> -     return rc;
>>    }
>>    -void msm_dp_display_mode_set(struct msm_dp *dp, struct drm_encoder
>> *encoder,
>> -                             const struct drm_display_mode *mode,
>> -                             const struct drm_display_mode
>> *adjusted_mode)
>> +void dp_bridge_mode_set(struct drm_bridge *drm_bridge,
>> +                     const struct drm_display_mode *mode,
>> +                     const struct drm_display_mode *adjusted_mode)
>>    {
>> +     struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
>> +     struct msm_dp *dp = dp_bridge->dp_display;
>>        struct dp_display_private *dp_display;
>>        dp_display = container_of(dp, struct dp_display_private,
>> dp_display); diff --git a/drivers/gpu/drm/msm/dp/dp_display.h
>> b/drivers/gpu/drm/msm/dp/dp_display.h
>> index 7af2b186d2d9..49a1d89681ac 100644
>> --- a/drivers/gpu/drm/msm/dp/dp_display.h
>> +++ b/drivers/gpu/drm/msm/dp/dp_display.h
>> @@ -32,7 +32,6 @@ struct msm_dp {
>>     int dp_display_set_plugged_cb(struct msm_dp *dp_display,
>>                hdmi_codec_plugged_cb fn, struct device *codec_dev); -int
>> dp_display_validate_mode(struct msm_dp *dp_display, u32
>> mode_pclk_khz);
>>    int dp_display_get_modes(struct msm_dp *dp_display,
>>                struct dp_display_mode *dp_mode);
>>    int dp_display_request_irq(struct msm_dp *dp_display); diff --git
>> a/drivers/gpu/drm/msm/dp/dp_drm.c
>> b/drivers/gpu/drm/msm/dp/dp_drm.c index 57800b865fe6..7ce1aca48687
>> 100644
>> --- a/drivers/gpu/drm/msm/dp/dp_drm.c
>> +++ b/drivers/gpu/drm/msm/dp/dp_drm.c
>> @@ -13,14 +13,6 @@
>>    #include "msm_kms.h"
>>    #include "dp_drm.h"
>>    -
>> -struct msm_dp_bridge {
>> -     struct drm_bridge bridge;
>> -     struct msm_dp *dp_display;
>> -};
>> -
>> -#define to_dp_display(x)     container_of((x), struct msm_dp_bridge,
>> bridge)
>> -
>>    /**
>>     * dp_bridge_detect - callback to determine if connector is connected
>>     * @bridge: Pointer to drm bridge structure @@ -30,7 +22,7 @@ static enum
>> drm_connector_status dp_bridge_detect(struct drm_bridge *bridge)
>>    {
>>        struct msm_dp *dp;
>>    -   dp = to_dp_display(bridge)->dp_display;
>> +     dp = to_dp_bridge(bridge)->dp_display;
>>        DRM_DEBUG_DP("is_connected = %s\n",
>>                (dp->is_connected) ? "true" : "false"); @@ -55,7 +47,7 @@
>> static int dp_bridge_get_modes(struct drm_bridge *bridge, struct
>> drm_connector *
>>        if (!connector)
>>                return 0;
>>    -   dp = to_dp_display(bridge)->dp_display;
>> +     dp = to_dp_bridge(bridge)->dp_display;
>>        dp_mode = kzalloc(sizeof(*dp_mode),  GFP_KERNEL);
>>        if (!dp_mode)
>> @@ -95,64 +87,6 @@ static int dp_bridge_get_modes(struct drm_bridge
>> *bridge, struct drm_connector *
>>        return rc;
>>    }
>>    -/**
>> - * dp_bridge_mode_valid - callback to determine if specified mode is valid
>> - * @bridge: Pointer to drm bridge structure
>> - * @info: display info
>> - * @mode: Pointer to drm mode structure
>> - * Returns: Validity status for specified mode
>> - */
>> -static enum drm_mode_status dp_bridge_mode_valid(
>> -             struct drm_bridge *bridge,
>> -             const struct drm_display_info *info,
>> -             const struct drm_display_mode *mode)
>> -{
>> -     struct msm_dp *dp_disp;
>> -
>> -     dp_disp = to_dp_display(bridge)->dp_display;
>> -
>> -     if ((dp_disp->max_pclk_khz <= 0) ||
>> -                     (dp_disp->max_pclk_khz >
>> DP_MAX_PIXEL_CLK_KHZ) ||
>> -                     (mode->clock > dp_disp->max_pclk_khz))
>> -             return MODE_BAD;
>> -
>> -     return dp_display_validate_mode(dp_disp, mode->clock);
>> -}
>> -
>> -static void dp_bridge_mode_set(struct drm_bridge *drm_bridge,
>> -                             const struct drm_display_mode *mode,
>> -                             const struct drm_display_mode
>> *adjusted_mode)
>> -{
>> -     struct msm_dp_bridge *dp_bridge = to_dp_display(drm_bridge);
>> -     struct msm_dp *dp_display = dp_bridge->dp_display;
>> -
>> -     msm_dp_display_mode_set(dp_display, drm_bridge->encoder,
>> mode,
>> adjusted_mode);
>> -}
>> -
>> -static void dp_bridge_enable(struct drm_bridge *drm_bridge) -{
>> -     struct msm_dp_bridge *dp_bridge = to_dp_display(drm_bridge);
>> -     struct msm_dp *dp_display = dp_bridge->dp_display;
>> -
>> -     msm_dp_display_enable(dp_display, drm_bridge->encoder);
>> -}
>> -
>> -static void dp_bridge_disable(struct drm_bridge *drm_bridge) -{
>> -     struct msm_dp_bridge *dp_bridge = to_dp_display(drm_bridge);
>> -     struct msm_dp *dp_display = dp_bridge->dp_display;
>> -
>> -     msm_dp_display_pre_disable(dp_display, drm_bridge->encoder);
>> -}
>> -
>> -static void dp_bridge_post_disable(struct drm_bridge *drm_bridge) -{
>> -     struct msm_dp_bridge *dp_bridge = to_dp_display(drm_bridge);
>> -     struct msm_dp *dp_display = dp_bridge->dp_display;
>> -
>> -     msm_dp_display_disable(dp_display, drm_bridge->encoder);
>> -}
>> -
>>    static const struct drm_bridge_funcs dp_bridge_ops = {
>>        .enable       = dp_bridge_enable,
>>        .disable      = dp_bridge_disable,
>> @@ -163,7 +97,7 @@ static const struct drm_bridge_funcs dp_bridge_ops =
>> {
>>        .detect       = dp_bridge_detect,
>>    };
>>    -struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display,
>> struct drm_device *dev,
>> +struct drm_bridge *dp_bridge_init(struct msm_dp *dp_display, struct
>> drm_device *dev,
>>                        struct drm_encoder *encoder)
>>    {
>>        int rc;
>> diff --git a/drivers/gpu/drm/msm/dp/dp_drm.h
>> b/drivers/gpu/drm/msm/dp/dp_drm.h index c27bfceefdf0..f4b1ed1e24f7
>> 100644
>> --- a/drivers/gpu/drm/msm/dp/dp_drm.h
>> +++ b/drivers/gpu/drm/msm/dp/dp_drm.h
>> @@ -7,12 +7,30 @@
>>    #define _DP_DRM_H_
>>     #include <linux/types.h>
>> -#include <drm/drm_crtc.h>
>> -#include <drm/drm_crtc_helper.h>
>> +#include <drm/drm_bridge.h>
>>     #include "msm_drv.h"
>>    #include "dp_display.h"
>>    +struct msm_dp_bridge {
>> +     struct drm_bridge bridge;
>> +     struct msm_dp *dp_display;
>> +};
>> +
>> +#define to_dp_bridge(x)     container_of((x), struct msm_dp_bridge,
>> bridge)
>> +
>>    struct drm_connector *dp_drm_connector_init(struct msm_dp
>> *dp_display);
>> +struct drm_bridge *dp_bridge_init(struct msm_dp *dp_display, struct
>> drm_device *dev,
>> +                     struct drm_encoder *encoder);
>> +
>> +void dp_bridge_enable(struct drm_bridge *drm_bridge); void
>> +dp_bridge_disable(struct drm_bridge *drm_bridge); void
>> +dp_bridge_post_disable(struct drm_bridge *drm_bridge); enum
>> +drm_mode_status dp_bridge_mode_valid(struct drm_bridge *bridge,
>> +                                       const struct drm_display_info *info,
>> +                                       const struct drm_display_mode
>> *mode); void
>> +dp_bridge_mode_set(struct drm_bridge *drm_bridge,
>> +                     const struct drm_display_mode *mode,
>> +                     const struct drm_display_mode *adjusted_mode);
>>     #endif /* _DP_DRM_H_ */
>> diff --git a/drivers/gpu/drm/msm/msm_drv.h
>> b/drivers/gpu/drm/msm/msm_drv.h index d7574e6bd4e4..b698a3be6072
>> 100644
>> --- a/drivers/gpu/drm/msm/msm_drv.h
>> +++ b/drivers/gpu/drm/msm/msm_drv.h
>> @@ -385,16 +385,6 @@ int __init msm_dp_register(void);
>>    void __exit msm_dp_unregister(void);
>>    int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device
>> *dev,
>>                         struct drm_encoder *encoder);
>> -int msm_dp_display_enable(struct msm_dp *dp, struct drm_encoder
>> *encoder); -int msm_dp_display_disable(struct msm_dp *dp, struct
>> drm_encoder *encoder); -int msm_dp_display_pre_disable(struct msm_dp
>> *dp, struct drm_encoder *encoder); -void
>> msm_dp_display_mode_set(struct msm_dp *dp, struct drm_encoder
>> *encoder,
>> -                             const struct drm_display_mode *mode,
>> -                             const struct drm_display_mode
>> *adjusted_mode);
>> -
>> -struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display,
>> -                                     struct drm_device *dev,
>> -                                     struct drm_encoder *encoder);
>>    void msm_dp_irq_postinstall(struct msm_dp *dp_display);
>>    void msm_dp_snapshot(struct msm_disp_state *disp_state, struct
>> msm_dp *dp_display);
>>    @@ -414,27 +404,6 @@ static inline int msm_dp_modeset_init(struct
>> msm_dp *dp_display,
>>    {
>>        return -EINVAL;
>>    }
>> -static inline int msm_dp_display_enable(struct msm_dp *dp,
>> -                                     struct drm_encoder *encoder)
>> -{
>> -     return -EINVAL;
>> -}
>> -static inline int msm_dp_display_disable(struct msm_dp *dp,
>> -                                     struct drm_encoder *encoder)
>> -{
>> -     return -EINVAL;
>> -}
>> -static inline int msm_dp_display_pre_disable(struct msm_dp *dp,
>> -                                     struct drm_encoder *encoder)
>> -{
>> -     return -EINVAL;
>> -}
>> -static inline void msm_dp_display_mode_set(struct msm_dp *dp,
>> -                             struct drm_encoder *encoder,
>> -                             const struct drm_display_mode *mode,
>> -                             const struct drm_display_mode
>> *adjusted_mode)
>> -{
>> -}
>>     static inline void msm_dp_irq_postinstall(struct msm_dp *dp_display)
>>    {
>> --
>> 2.34.1
> 

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

* Re: [RFC PATCH v2 4/5] drm/msm/dp: replace dp_connector with drm_bridge_connector
  2022-03-16 16:45                         ` Sankeerth Billakanti (QUIC)
@ 2022-04-14 20:17                           ` Abhinav Kumar
  -1 siblings, 0 replies; 84+ messages in thread
From: Abhinav Kumar @ 2022-04-14 20:17 UTC (permalink / raw)
  To: Sankeerth Billakanti (QUIC), swboyd, dmitry.baryshkov
  Cc: bjorn.andersson, robdclark, sean, airlied, daniel, linux-arm-msm,
	dri-devel, freedreno



On 3/16/2022 9:45 AM, Sankeerth Billakanti (QUIC) wrote:
>> Subject: Re: [RFC PATCH v2 4/5] drm/msm/dp: replace dp_connector with
>> drm_bridge_connector
>> Date: Wed, 23 Feb 2022 16:40:56 -0800
>> From: Kuogee Hsieh <quic_khsieh@quicinc.com>
>> To: Stephen Boyd <swboyd@chromium.org>, Dmitry Baryshkov
>> <dmitry.baryshkov@linaro.org>
>> CC: Abhinav Kumar <quic_abhinavk@quicinc.com>, Bjorn Andersson
>> <bjorn.andersson@linaro.org>, Rob Clark <robdclark@gmail.com>, Sean Paul
>> <sean@poorly.run>, David Airlie <airlied@linux.ie>, Daniel Vetter
>> <daniel@ffwll.ch>, linux-arm-msm@vger.kernel.org, dri-
>> devel@lists.freedesktop.org, freedreno@lists.freedesktop.org
>>
>>
>> On 2/23/2022 1:33 PM, Stephen Boyd wrote:
>>> Quoting Kuogee Hsieh (2022-02-23 10:27:26)
>>>> On 2/23/2022 10:22 AM, Dmitry Baryshkov wrote:
>>>>> On 23/02/2022 20:21, Kuogee Hsieh wrote:
>>>>>
>>>>> In the panel device node.
>>>>>
>>>>> Can you please share it too?
>>>>
>>>> &soc {
>>>>            edp_power_supply: edp_power {
>>>>                    compatible = "regulator-fixed";
>>>>                    regulator-name = "edp_backlight_power";
>>>>
>>>>                    regulator-always-on;
>>>>                    regulator-boot-on;
>>>>            };
>>>>
>>>>            edp_backlight: edp_backlight {
>>>>                    compatible = "pwm-backlight";
>>>>
>>>>                    pwms = <&pm8350c_pwm 3 65535>;
>>>>                    power-supply = <&edp_power_supply>;
>>>>                    enable-gpio = <&pm8350c_gpios 7 GPIO_ACTIVE_HIGH>;
>>>>
>>>>                    pinctrl-names = "default";
>>>>                    pinctrl-0 = <&backlight_pwm_default>;
>>>>            };
>>>>
>>>>            edp_panel: edp_panel {
>>>>                    compatible = "sharp_lq140m1jw46";
>>> Is that supposed to be sharp,lq140m1jw46 with a comma instead of an
>>> underscore?
>>
>> Stephen,
>>
>> This is our internal branch which does not have patches up to date yet.
>>
>> I will cherry-pick newer edp related patches which are under review now to
>> re test it.
> 
> Tested-by: Sankeerth Billakanti <quic_sbillaka@quicinc.com>
Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
> 
> Detect returned eDP not connected because the panel power was not on and mode_valid was failing because the DP mode_valid is different from eDP

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

* Re: [RFC PATCH v2 4/5] drm/msm/dp: replace dp_connector with drm_bridge_connector
@ 2022-04-14 20:17                           ` Abhinav Kumar
  0 siblings, 0 replies; 84+ messages in thread
From: Abhinav Kumar @ 2022-04-14 20:17 UTC (permalink / raw)
  To: Sankeerth Billakanti (QUIC), swboyd, dmitry.baryshkov
  Cc: freedreno, airlied, linux-arm-msm, dri-devel, bjorn.andersson, sean



On 3/16/2022 9:45 AM, Sankeerth Billakanti (QUIC) wrote:
>> Subject: Re: [RFC PATCH v2 4/5] drm/msm/dp: replace dp_connector with
>> drm_bridge_connector
>> Date: Wed, 23 Feb 2022 16:40:56 -0800
>> From: Kuogee Hsieh <quic_khsieh@quicinc.com>
>> To: Stephen Boyd <swboyd@chromium.org>, Dmitry Baryshkov
>> <dmitry.baryshkov@linaro.org>
>> CC: Abhinav Kumar <quic_abhinavk@quicinc.com>, Bjorn Andersson
>> <bjorn.andersson@linaro.org>, Rob Clark <robdclark@gmail.com>, Sean Paul
>> <sean@poorly.run>, David Airlie <airlied@linux.ie>, Daniel Vetter
>> <daniel@ffwll.ch>, linux-arm-msm@vger.kernel.org, dri-
>> devel@lists.freedesktop.org, freedreno@lists.freedesktop.org
>>
>>
>> On 2/23/2022 1:33 PM, Stephen Boyd wrote:
>>> Quoting Kuogee Hsieh (2022-02-23 10:27:26)
>>>> On 2/23/2022 10:22 AM, Dmitry Baryshkov wrote:
>>>>> On 23/02/2022 20:21, Kuogee Hsieh wrote:
>>>>>
>>>>> In the panel device node.
>>>>>
>>>>> Can you please share it too?
>>>>
>>>> &soc {
>>>>            edp_power_supply: edp_power {
>>>>                    compatible = "regulator-fixed";
>>>>                    regulator-name = "edp_backlight_power";
>>>>
>>>>                    regulator-always-on;
>>>>                    regulator-boot-on;
>>>>            };
>>>>
>>>>            edp_backlight: edp_backlight {
>>>>                    compatible = "pwm-backlight";
>>>>
>>>>                    pwms = <&pm8350c_pwm 3 65535>;
>>>>                    power-supply = <&edp_power_supply>;
>>>>                    enable-gpio = <&pm8350c_gpios 7 GPIO_ACTIVE_HIGH>;
>>>>
>>>>                    pinctrl-names = "default";
>>>>                    pinctrl-0 = <&backlight_pwm_default>;
>>>>            };
>>>>
>>>>            edp_panel: edp_panel {
>>>>                    compatible = "sharp_lq140m1jw46";
>>> Is that supposed to be sharp,lq140m1jw46 with a comma instead of an
>>> underscore?
>>
>> Stephen,
>>
>> This is our internal branch which does not have patches up to date yet.
>>
>> I will cherry-pick newer edp related patches which are under review now to
>> re test it.
> 
> Tested-by: Sankeerth Billakanti <quic_sbillaka@quicinc.com>
Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
> 
> Detect returned eDP not connected because the panel power was not on and mode_valid was failing because the DP mode_valid is different from eDP

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

end of thread, other threads:[~2022-04-14 20:18 UTC | newest]

Thread overview: 84+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-11 22:40 [RFC PATCH v2 0/5] Simplify and correct msm/dp bridge implementation Dmitry Baryshkov
2022-02-11 22:40 ` Dmitry Baryshkov
2022-02-11 22:40 ` [RFC PATCH v2 1/5] drm/msm/dp: fix panel bridge attachment Dmitry Baryshkov
2022-02-11 22:40   ` Dmitry Baryshkov
2022-02-18 21:14   ` Kuogee Hsieh
2022-02-18 21:14     ` Kuogee Hsieh
2022-02-18 23:56   ` Stephen Boyd
2022-02-18 23:56     ` Stephen Boyd
2022-02-19  2:26     ` Dmitry Baryshkov
2022-02-19  2:26       ` Dmitry Baryshkov
2022-02-24 18:25       ` [Freedreno] " Abhinav Kumar
2022-02-24 18:25         ` Abhinav Kumar
2022-02-24 20:41         ` Dmitry Baryshkov
2022-02-24 20:41           ` Dmitry Baryshkov
2022-02-25  2:01           ` Abhinav Kumar
2022-02-25  2:01             ` Abhinav Kumar
2022-02-25  4:22             ` Dmitry Baryshkov
2022-02-25  4:22               ` Dmitry Baryshkov
2022-02-25  4:45               ` Abhinav Kumar
2022-02-25  4:45                 ` Abhinav Kumar
2022-02-25  9:04                 ` Dmitry Baryshkov
2022-02-25  9:04                   ` Dmitry Baryshkov
2022-02-25 17:11                   ` Abhinav Kumar
2022-02-25 17:11                     ` Abhinav Kumar
2022-02-25 17:25                     ` Dmitry Baryshkov
2022-02-25 17:25                       ` Dmitry Baryshkov
2022-02-11 22:40 ` [RFC PATCH v2 2/5] drm/msm/dp: support attaching bridges to the DP encoder Dmitry Baryshkov
2022-02-11 22:40   ` Dmitry Baryshkov
2022-02-18 21:28   ` Kuogee Hsieh
2022-02-18 21:28     ` Kuogee Hsieh
2022-02-18 21:31     ` Dmitry Baryshkov
2022-02-18 21:31       ` Dmitry Baryshkov
2022-02-18 23:38   ` Stephen Boyd
2022-02-18 23:38     ` Stephen Boyd
2022-02-23 17:47   ` Kuogee Hsieh
2022-02-23 17:47     ` Kuogee Hsieh
2022-02-24 19:56   ` Abhinav Kumar
2022-02-24 19:56     ` Abhinav Kumar
2022-02-11 22:40 ` [RFC PATCH v2 3/5] drm/msm/dp: support finding next bridge even for DP interfaces Dmitry Baryshkov
2022-02-11 22:40   ` Dmitry Baryshkov
2022-02-18 21:29   ` Kuogee Hsieh
2022-02-18 21:29     ` Kuogee Hsieh
2022-02-19  0:34   ` Stephen Boyd
2022-02-19  0:34     ` Stephen Boyd
2022-02-24 20:13   ` Abhinav Kumar
2022-02-24 20:13     ` Abhinav Kumar
2022-02-24 20:49     ` Dmitry Baryshkov
2022-02-24 20:49       ` Dmitry Baryshkov
2022-02-24 21:09       ` Abhinav Kumar
2022-02-24 21:09         ` Abhinav Kumar
2022-02-11 22:40 ` [RFC PATCH v2 4/5] drm/msm/dp: replace dp_connector with drm_bridge_connector Dmitry Baryshkov
2022-02-11 22:40   ` Dmitry Baryshkov
2022-02-18 21:31   ` Kuogee Hsieh
2022-02-18 21:31     ` Kuogee Hsieh
2022-02-18 21:52     ` Dmitry Baryshkov
2022-02-18 21:52       ` Dmitry Baryshkov
2022-02-18 22:32     ` Dmitry Baryshkov
2022-02-18 22:32       ` Dmitry Baryshkov
2022-02-19  0:55       ` Stephen Boyd
2022-02-19  0:55         ` Stephen Boyd
2022-02-19  2:22         ` Dmitry Baryshkov
2022-02-19  2:22           ` Dmitry Baryshkov
2022-02-23 17:21           ` Kuogee Hsieh
2022-02-23 17:21             ` Kuogee Hsieh
2022-02-23 18:22             ` Dmitry Baryshkov
2022-02-23 18:22               ` Dmitry Baryshkov
2022-02-23 18:27               ` Kuogee Hsieh
2022-02-23 18:27                 ` Kuogee Hsieh
2022-02-23 18:45                 ` Dmitry Baryshkov
2022-02-23 18:45                   ` Dmitry Baryshkov
2022-02-23 21:33                 ` Stephen Boyd
2022-02-23 21:33                   ` Stephen Boyd
2022-02-24  0:40                   ` Kuogee Hsieh
2022-02-24  0:40                     ` Kuogee Hsieh
     [not found]                     ` <64a5ae1a-df65-b0a5-5d0d-cfb1d4da3bf7@quicinc.com>
2022-03-16 16:45                       ` Sankeerth Billakanti (QUIC)
2022-03-16 16:45                         ` Sankeerth Billakanti (QUIC)
2022-04-14 20:17                         ` Abhinav Kumar
2022-04-14 20:17                           ` Abhinav Kumar
2022-02-11 22:40 ` [RFC PATCH v2 5/5] drm/msm/dp: remove extra wrappers and public functions Dmitry Baryshkov
2022-02-11 22:40   ` Dmitry Baryshkov
     [not found]   ` <26549f55-6195-a7ec-5896-de5f986ad716@quicinc.com>
2022-03-16 16:31     ` Sankeerth Billakanti (QUIC)
2022-03-16 16:31       ` Sankeerth Billakanti (QUIC)
2022-04-14 20:17       ` Abhinav Kumar
2022-04-14 20:17         ` Abhinav Kumar

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.