linux-renesas-soc.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/27] Converter R-Car DU to the DRM bridge connector helper
@ 2020-05-26  1:14 Laurent Pinchart
  2020-05-26  1:14 ` [PATCH 01/27] drm: bridge: adv7511: Split EDID read to a separate function Laurent Pinchart
                   ` (27 more replies)
  0 siblings, 28 replies; 69+ messages in thread
From: Laurent Pinchart @ 2020-05-26  1:14 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-renesas-soc, Andrzej Hajda, Jernej Skrabec, Jonas Karlman,
	Neil Armstrong, Sam Ravnborg, Kieran Bingham

Hello,

This patch series converts the R-Car DU driver to use the DRM bridge
connector helper drm_bridge_connector_init().

The bulk of the series is conversion of the adv7511, simple-bridge,
rcar-lbds and dw-hdmi drivers to make connector creation optional
(through the DRM_BRIDGE_ATTACH_NO_CONNECTOR flag).

The series starts with the adv7511 driver, previously posted as "[PATCH
0/4] drm: bridge: adv7511: Enable usage with DRM bridge connector
helper" ([1]). Patches 01/27 to 04/27 incorporate all the received
review comments.

The next three patches address the simple-bridge driver, previously
posted as "[PATCH 0/2] drm: bridge: simple-bridge: Enable usage with DRM
bridge connector helper". Patch 05/27 is an additional fix that stems
from the review, and patches 06/27 and 07/27 incorporate all the
received review comments.

Patch 08/27 is a new patch that addresses the rcar-lvds driver. Instead
of implementing direct support for DRM_BRIDGE_ATTACH_NO_CONNECTOR, it
simply removes code that shouldn't have been in the driver in the first
place by switching to the panel bridge helper.

Patches 09/27 to 22/27 then address the dw-hdmi driver. That's a more
sizeable rework, due to the fact that the driver implements a mid-layer
for platform-specific glue, with the internal drm_connector being used
throughout the whole code. There's no rocket science there, but patch
10/27 should be noted for adding a new argument to the
drm_bridge_funcs.mode_valid() function. Please see individual patches
for details.

Patch 23/27 adds support to the dw-hdmi driver to attach to a downstream
bridge if one is specified in DT. As the DT port number corresponding to
the video output differs between platforms that integrate the dw-hdmi
(some of them even don't have a video output port, which should probably
be fixed, but that's out of scope for this series), the port number has
to be specified by the platform glue layer. Patch 24/27 does so for the
R-Car dw-hdmi driver.

Patch 25/27 is a drive-by fix for an error path issue in the rcar-du
driver. Patch 26/27 finally makes use of the drm_bridge_connector_init()
helper.

Unfortunately, this breaks the VGA output on R-Car Gen3 platforms. On
those platforms, the VGA DDC lines are not connected, and there is no
mean for software to detect the VGA output connection status. When the
simple-bridge driver creates a connector, it automatically adds default
modes when no DDC is available. This behavious is also present int the
DRM probe helper drm_helper_probe_single_connector_modes(), but only
when the connector status is connector_status_connected. As the driver
(rightfully) reports connector_status_unconnected, no modes are added.
Patch 27/27 fixes this issue by extending addition of default modes in
drm_helper_probe_single_connector_modes() when the output status is
unknown. An alternative approach would be to implement this behaviour in
the bridge connector helper (drm_bridge_connector.c).

All the modified drivers have been compile-tested, and the series has
been tested on a Renesas R-Car Salvator-XS board with the VGA, HDMI and
LVDS outputs.

[1] https://lore.kernel.org/dri-devel/20200409004610.12346-1-laurent.pinchart+renesas@ideasonboard.com/
[2] https://lore.kernel.org/dri-devel/20200409003636.11792-1-laurent.pinchart+renesas@ideasonboard.com/

Laurent Pinchart (27):
  drm: bridge: adv7511: Split EDID read to a separate function
  drm: bridge: adv7511: Split connector creation to a separate function
  drm: bridge: adv7511: Implement bridge connector operations
  drm: bridge: adv7511: Make connector creation optional
  drm: bridge: Return NULL on error from drm_bridge_get_edid()
  drm: bridge: simple-bridge: Delegate operations to next bridge
  drm: bridge: simple-bridge: Make connector creation optional
  drm: rcar-du: lvds: Convert to DRM panel bridge helper
  drm: edid: Constify connector argument to infoframe functions
  drm: bridge: Pass drm_display_info to drm_bridge_funcs .mode_valid()
  drm: bridge: dw-hdmi: Pass private data pointer to .mode_valid()
  drm: bridge: dw-hdmi: Pass private data pointer to .configure_phy()
  drm: bridge: dw-hdmi: Remove unused field from dw_hdmi_plat_data
  drm: meson: dw-hdmi: Use dw_hdmi context to replace hack
  drm: bridge: dw-hdmi: Pass drm_display_info to .mode_valid()
  drm: bridge: dw-hdmi: Constify mode argument to dw_hdmi_phy_ops
    .init()
  drm: bridge: dw-hdmi: Constify mode argument to internal functions
  drm: bridge: dw-hdmi: Pass drm_display_info to dw_hdmi_support_scdc()
  drm: bridge: dw-hdmi: Split connector creation to a separate function
  drm: bridge: dw-hdmi: Store current connector in struct dw_hdmi
  drm: bridge: dw-hdmi: Pass drm_connector to internal functions as
    needed
  drm: bridge: dw-hdmi: Make connector creation optional
  drm: bridge: dw-hdmi: Attach to next bridge if available
  drm: rcar-du: dw-hdmi: Set output port number
  drm: rcar-du: Fix error handling in rcar_du_encoder_init()
  drm: rcar-du: Use drm_bridge_connector_init() helper
  drm: Add default modes for connectors in unknown state

 drivers/gpu/drm/bridge/adv7511/adv7511_drv.c  | 159 +++++---
 .../drm/bridge/analogix/analogix-anx6345.c    |   1 +
 .../drm/bridge/analogix/analogix-anx78xx.c    |   1 +
 drivers/gpu/drm/bridge/cdns-dsi.c             |   1 +
 drivers/gpu/drm/bridge/chrontel-ch7033.c      |   1 +
 drivers/gpu/drm/bridge/nwl-dsi.c              |   1 +
 drivers/gpu/drm/bridge/sii9234.c              |   1 +
 drivers/gpu/drm/bridge/sil-sii8620.c          |   1 +
 drivers/gpu/drm/bridge/simple-bridge.c        | 113 +++---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c     | 357 ++++++++++++------
 drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c |   1 +
 drivers/gpu/drm/bridge/tc358767.c             |   1 +
 drivers/gpu/drm/bridge/tc358768.c             |   1 +
 drivers/gpu/drm/bridge/thc63lvd1024.c         |   1 +
 drivers/gpu/drm/bridge/ti-tfp410.c            |  11 +-
 drivers/gpu/drm/drm_atomic_helper.c           |   3 +-
 drivers/gpu/drm/drm_bridge.c                  |  10 +-
 drivers/gpu/drm/drm_edid.c                    |  12 +-
 drivers/gpu/drm/drm_probe_helper.c            |   7 +-
 drivers/gpu/drm/i2c/tda998x_drv.c             |   1 +
 drivers/gpu/drm/imx/dw_hdmi-imx.c             |   6 +-
 drivers/gpu/drm/meson/meson_dw_hdmi.c         |  34 +-
 drivers/gpu/drm/omapdrm/dss/dpi.c             |   1 +
 drivers/gpu/drm/omapdrm/dss/sdi.c             |   1 +
 drivers/gpu/drm/omapdrm/dss/venc.c            |   1 +
 drivers/gpu/drm/rcar-du/rcar_du_encoder.c     |  26 +-
 drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c        |   7 +-
 drivers/gpu/drm/rcar-du/rcar_lvds.c           | 124 +-----
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c   |   6 +-
 drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c         |   6 +-
 drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h         |   3 +-
 drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c        |   3 +-
 include/drm/bridge/dw_hdmi.h                  |  28 +-
 include/drm/drm_bridge.h                      |   3 +
 include/drm/drm_edid.h                        |   6 +-
 include/drm/drm_modeset_helper_vtables.h      |   8 +-
 36 files changed, 541 insertions(+), 406 deletions(-)

-- 
Regards,

Laurent Pinchart


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

* [PATCH 01/27] drm: bridge: adv7511: Split EDID read to a separate function
  2020-05-26  1:14 [PATCH 00/27] Converter R-Car DU to the DRM bridge connector helper Laurent Pinchart
@ 2020-05-26  1:14 ` Laurent Pinchart
  2020-05-26  1:14 ` [PATCH 02/27] drm: bridge: adv7511: Split connector creation " Laurent Pinchart
                   ` (26 subsequent siblings)
  27 siblings, 0 replies; 69+ messages in thread
From: Laurent Pinchart @ 2020-05-26  1:14 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-renesas-soc, Andrzej Hajda, Jernej Skrabec, Jonas Karlman,
	Neil Armstrong, Sam Ravnborg, Kieran Bingham

To prepare for the implementation of the DRM bridge connector
operations, move EDID read out of adv7511_get_modes() to a separate
function.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Acked-by: Sam Ravnborg <sam@ravnborg.org>
---
 drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 23 ++++++++++++++------
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index 87b58c1acff4..58d02e92b6b9 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -589,11 +589,10 @@ static int adv7511_get_edid_block(void *data, u8 *buf, unsigned int block,
  * ADV75xx helpers
  */
 
-static int adv7511_get_modes(struct adv7511 *adv7511,
-			     struct drm_connector *connector)
+static struct edid *adv7511_get_edid(struct adv7511 *adv7511,
+				     struct drm_connector *connector)
 {
 	struct edid *edid;
-	unsigned int count;
 
 	/* Reading the EDID only works if the device is powered */
 	if (!adv7511->powered) {
@@ -612,15 +611,25 @@ static int adv7511_get_modes(struct adv7511 *adv7511,
 	if (!adv7511->powered)
 		__adv7511_power_off(adv7511);
 
-
-	drm_connector_update_edid_property(connector, edid);
-	count = drm_add_edid_modes(connector, edid);
-
 	adv7511_set_config_csc(adv7511, connector, adv7511->rgb,
 			       drm_detect_hdmi_monitor(edid));
 
 	cec_s_phys_addr_from_edid(adv7511->cec_adap, edid);
 
+	return edid;
+}
+
+static int adv7511_get_modes(struct adv7511 *adv7511,
+			     struct drm_connector *connector)
+{
+	struct edid *edid;
+	unsigned int count;
+
+	edid = adv7511_get_edid(adv7511, connector);
+
+	drm_connector_update_edid_property(connector, edid);
+	count = drm_add_edid_modes(connector, edid);
+
 	kfree(edid);
 
 	return count;
-- 
Regards,

Laurent Pinchart


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

* [PATCH 02/27] drm: bridge: adv7511: Split connector creation to a separate function
  2020-05-26  1:14 [PATCH 00/27] Converter R-Car DU to the DRM bridge connector helper Laurent Pinchart
  2020-05-26  1:14 ` [PATCH 01/27] drm: bridge: adv7511: Split EDID read to a separate function Laurent Pinchart
@ 2020-05-26  1:14 ` Laurent Pinchart
  2020-05-26  1:14 ` [PATCH 03/27] drm: bridge: adv7511: Implement bridge connector operations Laurent Pinchart
                   ` (25 subsequent siblings)
  27 siblings, 0 replies; 69+ messages in thread
From: Laurent Pinchart @ 2020-05-26  1:14 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-renesas-soc, Andrzej Hajda, Jernej Skrabec, Jonas Karlman,
	Neil Armstrong, Sam Ravnborg, Kieran Bingham

To prepare for making the connector creation optional, move the related
code out of adv7511_bridge_attach() to a separate function.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Acked-by: Sam Ravnborg <sam@ravnborg.org>
---
Changes since v1:

- Test for (ret < 0) instead of (ret)
---
 drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 62 +++++++++++++-------
 1 file changed, 40 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index 58d02e92b6b9..f0992b6d654f 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -783,7 +783,10 @@ static void adv7511_mode_set(struct adv7511 *adv7511,
 	adv7511->f_tmds = mode->clock;
 }
 
-/* Connector funcs */
+/* -----------------------------------------------------------------------------
+ * DRM Connector Operations
+ */
+
 static struct adv7511 *connector_to_adv7511(struct drm_connector *connector)
 {
 	return container_of(connector, struct adv7511, connector);
@@ -827,7 +830,40 @@ static const struct drm_connector_funcs adv7511_connector_funcs = {
 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 };
 
-/* Bridge funcs */
+static int adv7511_connector_init(struct adv7511 *adv)
+{
+	struct drm_bridge *bridge = &adv->bridge;
+	int ret;
+
+	if (!bridge->encoder) {
+		DRM_ERROR("Parent encoder object not found");
+		return -ENODEV;
+	}
+
+	if (adv->i2c_main->irq)
+		adv->connector.polled = DRM_CONNECTOR_POLL_HPD;
+	else
+		adv->connector.polled = DRM_CONNECTOR_POLL_CONNECT |
+				DRM_CONNECTOR_POLL_DISCONNECT;
+
+	ret = drm_connector_init(bridge->dev, &adv->connector,
+				 &adv7511_connector_funcs,
+				 DRM_MODE_CONNECTOR_HDMIA);
+	if (ret < 0) {
+		DRM_ERROR("Failed to initialize connector with drm\n");
+		return ret;
+	}
+	drm_connector_helper_add(&adv->connector,
+				 &adv7511_connector_helper_funcs);
+	drm_connector_attach_encoder(&adv->connector, bridge->encoder);
+
+	return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * DRM Bridge Operations
+ */
+
 static struct adv7511 *bridge_to_adv7511(struct drm_bridge *bridge)
 {
 	return container_of(bridge, struct adv7511, bridge);
@@ -867,27 +903,9 @@ static int adv7511_bridge_attach(struct drm_bridge *bridge,
 		return -EINVAL;
 	}
 
-	if (!bridge->encoder) {
-		DRM_ERROR("Parent encoder object not found");
-		return -ENODEV;
-	}
-
-	if (adv->i2c_main->irq)
-		adv->connector.polled = DRM_CONNECTOR_POLL_HPD;
-	else
-		adv->connector.polled = DRM_CONNECTOR_POLL_CONNECT |
-				DRM_CONNECTOR_POLL_DISCONNECT;
-
-	ret = drm_connector_init(bridge->dev, &adv->connector,
-				 &adv7511_connector_funcs,
-				 DRM_MODE_CONNECTOR_HDMIA);
-	if (ret) {
-		DRM_ERROR("Failed to initialize connector with drm\n");
+	ret = adv7511_connector_init(adv);
+	if (ret < 0)
 		return ret;
-	}
-	drm_connector_helper_add(&adv->connector,
-				 &adv7511_connector_helper_funcs);
-	drm_connector_attach_encoder(&adv->connector, bridge->encoder);
 
 	if (adv->type == ADV7533 || adv->type == ADV7535)
 		ret = adv7533_attach_dsi(adv);
-- 
Regards,

Laurent Pinchart


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

* [PATCH 03/27] drm: bridge: adv7511: Implement bridge connector operations
  2020-05-26  1:14 [PATCH 00/27] Converter R-Car DU to the DRM bridge connector helper Laurent Pinchart
  2020-05-26  1:14 ` [PATCH 01/27] drm: bridge: adv7511: Split EDID read to a separate function Laurent Pinchart
  2020-05-26  1:14 ` [PATCH 02/27] drm: bridge: adv7511: Split connector creation " Laurent Pinchart
@ 2020-05-26  1:14 ` Laurent Pinchart
  2020-06-21  8:25   ` Sam Ravnborg
  2020-05-26  1:14 ` [PATCH 04/27] drm: bridge: adv7511: Make connector creation optional Laurent Pinchart
                   ` (24 subsequent siblings)
  27 siblings, 1 reply; 69+ messages in thread
From: Laurent Pinchart @ 2020-05-26  1:14 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-renesas-soc, Andrzej Hajda, Jernej Skrabec, Jonas Karlman,
	Neil Armstrong, Sam Ravnborg, Kieran Bingham

Implement the bridge connector-related .get_edid(), .detect() and
.hpd_notify() operations, and report the related bridge capabilities.

Output status detection is implemented using the same backend as for the
DRM connector, but requires making mode retrieval at detection time
optional as no pointer to the connector is available to the bridge
.detect() operation. The reason for the need to retrieve modes at
detection time is unclear to me, and this may benefit from further
refactoring of hot plug handling code.

Hot plug detection is notified through the bridge HPD notification
framework when the bridge is used without creating a connector, and
falls back to the existing implementation otherwise. CEC handling of
disconnection is handled in the new .hpd_notify() operation in the new
code path.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 43 ++++++++++++++++++--
 1 file changed, 39 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index f0992b6d654f..2662f28f8007 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -443,9 +443,14 @@ static void adv7511_hpd_work(struct work_struct *work)
 
 	if (adv7511->connector.status != status) {
 		adv7511->connector.status = status;
-		if (status == connector_status_disconnected)
-			cec_phys_addr_invalidate(adv7511->cec_adap);
-		drm_kms_helper_hotplug_event(adv7511->connector.dev);
+
+		if (adv7511->connector.dev) {
+			if (status == connector_status_disconnected)
+				cec_phys_addr_invalidate(adv7511->cec_adap);
+			drm_kms_helper_hotplug_event(adv7511->connector.dev);
+		} else {
+			drm_bridge_hpd_notify(&adv7511->bridge, status);
+		}
 	}
 }
 
@@ -661,7 +666,8 @@ adv7511_detect(struct adv7511 *adv7511, struct drm_connector *connector)
 	if (status == connector_status_connected && hpd && adv7511->powered) {
 		regcache_mark_dirty(adv7511->regmap);
 		adv7511_power_on(adv7511);
-		adv7511_get_modes(adv7511, connector);
+		if (connector)
+			adv7511_get_modes(adv7511, connector);
 		if (adv7511->status == connector_status_connected)
 			status = connector_status_disconnected;
 	} else {
@@ -917,11 +923,38 @@ static int adv7511_bridge_attach(struct drm_bridge *bridge,
 	return ret;
 }
 
+static enum drm_connector_status adv7511_bridge_detect(struct drm_bridge *bridge)
+{
+	struct adv7511 *adv = bridge_to_adv7511(bridge);
+
+	return adv7511_detect(adv, NULL);
+}
+
+static struct edid *adv7511_bridge_get_edid(struct drm_bridge *bridge,
+					    struct drm_connector *connector)
+{
+	struct adv7511 *adv = bridge_to_adv7511(bridge);
+
+	return adv7511_get_edid(adv, connector);
+}
+
+static void adv7511_bridge_hpd_notify(struct drm_bridge *bridge,
+				      enum drm_connector_status status)
+{
+	struct adv7511 *adv = bridge_to_adv7511(bridge);
+
+	if (status == connector_status_disconnected)
+		cec_phys_addr_invalidate(adv->cec_adap);
+}
+
 static const struct drm_bridge_funcs adv7511_bridge_funcs = {
 	.enable = adv7511_bridge_enable,
 	.disable = adv7511_bridge_disable,
 	.mode_set = adv7511_bridge_mode_set,
 	.attach = adv7511_bridge_attach,
+	.detect = adv7511_bridge_detect,
+	.get_edid = adv7511_bridge_get_edid,
+	.hpd_notify = adv7511_bridge_hpd_notify,
 };
 
 /* -----------------------------------------------------------------------------
@@ -1250,6 +1283,8 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
 		goto err_unregister_cec;
 
 	adv7511->bridge.funcs = &adv7511_bridge_funcs;
+	adv7511->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID
+			    | DRM_BRIDGE_OP_HPD;
 	adv7511->bridge.of_node = dev->of_node;
 
 	drm_bridge_add(&adv7511->bridge);
-- 
Regards,

Laurent Pinchart


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

* [PATCH 04/27] drm: bridge: adv7511: Make connector creation optional
  2020-05-26  1:14 [PATCH 00/27] Converter R-Car DU to the DRM bridge connector helper Laurent Pinchart
                   ` (2 preceding siblings ...)
  2020-05-26  1:14 ` [PATCH 03/27] drm: bridge: adv7511: Implement bridge connector operations Laurent Pinchart
@ 2020-05-26  1:14 ` Laurent Pinchart
  2020-05-26  1:14 ` [PATCH 05/27] drm: bridge: Return NULL on error from drm_bridge_get_edid() Laurent Pinchart
                   ` (23 subsequent siblings)
  27 siblings, 0 replies; 69+ messages in thread
From: Laurent Pinchart @ 2020-05-26  1:14 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-renesas-soc, Andrzej Hajda, Jernej Skrabec, Jonas Karlman,
	Neil Armstrong, Sam Ravnborg, Kieran Bingham

Now that the driver supports all the connector-related bridge
operations, make the connector creation optional. This enables usage of
the adv7511 with the DRM bridge connector helper.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Acked-by: Sam Ravnborg <sam@ravnborg.org>
---
 drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index 2662f28f8007..f45cdca9cce5 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -902,17 +902,14 @@ static int adv7511_bridge_attach(struct drm_bridge *bridge,
 				 enum drm_bridge_attach_flags flags)
 {
 	struct adv7511 *adv = bridge_to_adv7511(bridge);
-	int ret;
+	int ret = 0;
 
-	if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {
-		DRM_ERROR("Fix bridge driver to make connector optional!");
-		return -EINVAL;
+	if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
+		ret = adv7511_connector_init(adv);
+		if (ret < 0)
+			return ret;
 	}
 
-	ret = adv7511_connector_init(adv);
-	if (ret < 0)
-		return ret;
-
 	if (adv->type == ADV7533 || adv->type == ADV7535)
 		ret = adv7533_attach_dsi(adv);
 
-- 
Regards,

Laurent Pinchart


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

* [PATCH 05/27] drm: bridge: Return NULL on error from drm_bridge_get_edid()
  2020-05-26  1:14 [PATCH 00/27] Converter R-Car DU to the DRM bridge connector helper Laurent Pinchart
                   ` (3 preceding siblings ...)
  2020-05-26  1:14 ` [PATCH 04/27] drm: bridge: adv7511: Make connector creation optional Laurent Pinchart
@ 2020-05-26  1:14 ` Laurent Pinchart
  2020-06-21  8:26   ` Sam Ravnborg
  2020-05-26  1:14 ` [PATCH 06/27] drm: bridge: simple-bridge: Delegate operations to next bridge Laurent Pinchart
                   ` (22 subsequent siblings)
  27 siblings, 1 reply; 69+ messages in thread
From: Laurent Pinchart @ 2020-05-26  1:14 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-renesas-soc, Andrzej Hajda, Jernej Skrabec, Jonas Karlman,
	Neil Armstrong, Sam Ravnborg, Kieran Bingham

The drm_bridge_get_edid() function is documented to return an error
pointer on error. The underlying .get_edid() operation, however, returns
NULL on error, and so do the drm_get_edid() and drm_do_get_edid()
functions upon which .get_edid() is usually implemented. Make
drm_bridge_get_edid() return NULL on error to be consistent.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/gpu/drm/bridge/ti-tfp410.c | 10 +++++++---
 drivers/gpu/drm/drm_bridge.c       |  6 +++---
 2 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/bridge/ti-tfp410.c b/drivers/gpu/drm/bridge/ti-tfp410.c
index e3eb6364c0f7..f065a96a0917 100644
--- a/drivers/gpu/drm/bridge/ti-tfp410.c
+++ b/drivers/gpu/drm/bridge/ti-tfp410.c
@@ -51,11 +51,15 @@ static int tfp410_get_modes(struct drm_connector *connector)
 	struct edid *edid;
 	int ret;
 
-	edid = drm_bridge_get_edid(dvi->next_bridge, connector);
-	if (IS_ERR_OR_NULL(edid)) {
-		if (edid != ERR_PTR(-ENOTSUPP))
+	if (dvi->next_bridge->ops & DRM_BRIDGE_OP_EDID) {
+		edid = drm_bridge_get_edid(dvi->next_bridge, connector);
+		if (!edid)
 			DRM_INFO("EDID read failed. Fallback to standard modes\n");
+	} else {
+		edid = NULL;
+	}
 
+	if (!edid) {
 		/*
 		 * No EDID, fallback on the XGA standard modes and prefer a mode
 		 * pretty much anything can handle.
diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index afdec8e5fc68..fe1e3460b486 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -1086,16 +1086,16 @@ EXPORT_SYMBOL_GPL(drm_bridge_get_modes);
  *
  * If the bridge supports output EDID retrieval, as reported by the
  * DRM_BRIDGE_OP_EDID bridge ops flag, call &drm_bridge_funcs.get_edid to
- * get the EDID and return it. Otherwise return ERR_PTR(-ENOTSUPP).
+ * get the EDID and return it. Otherwise return NULL.
  *
  * RETURNS:
- * The retrieved EDID on success, or an error pointer otherwise.
+ * The retrieved EDID on success, or NULL otherwise.
  */
 struct edid *drm_bridge_get_edid(struct drm_bridge *bridge,
 				 struct drm_connector *connector)
 {
 	if (!(bridge->ops & DRM_BRIDGE_OP_EDID))
-		return ERR_PTR(-ENOTSUPP);
+		return NULL;
 
 	return bridge->funcs->get_edid(bridge, connector);
 }
-- 
Regards,

Laurent Pinchart


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

* [PATCH 06/27] drm: bridge: simple-bridge: Delegate operations to next bridge
  2020-05-26  1:14 [PATCH 00/27] Converter R-Car DU to the DRM bridge connector helper Laurent Pinchart
                   ` (4 preceding siblings ...)
  2020-05-26  1:14 ` [PATCH 05/27] drm: bridge: Return NULL on error from drm_bridge_get_edid() Laurent Pinchart
@ 2020-05-26  1:14 ` Laurent Pinchart
  2020-05-26  1:14 ` [PATCH 07/27] drm: bridge: simple-bridge: Make connector creation optional Laurent Pinchart
                   ` (21 subsequent siblings)
  27 siblings, 0 replies; 69+ messages in thread
From: Laurent Pinchart @ 2020-05-26  1:14 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-renesas-soc, Andrzej Hajda, Jernej Skrabec, Jonas Karlman,
	Neil Armstrong, Sam Ravnborg, Kieran Bingham

Instead of poking into the DT node of the next bridge for its DDC bus
and implementing the .get_modes() and .detect() connector operations
manually, retrieve the next bridge in the chain and delegate these
operations to it.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Acked-by: Sam Ravnborg <sam@ravnborg.org>
---
Changes since v1:

- Adapt to drm_bridge_get_edid() returning NULL on error
- Acquire next bridge earlier in probe()
---
 drivers/gpu/drm/bridge/simple-bridge.c | 104 ++++++++++---------------
 1 file changed, 39 insertions(+), 65 deletions(-)

diff --git a/drivers/gpu/drm/bridge/simple-bridge.c b/drivers/gpu/drm/bridge/simple-bridge.c
index a2dca7a3ef03..a1be269d833a 100644
--- a/drivers/gpu/drm/bridge/simple-bridge.c
+++ b/drivers/gpu/drm/bridge/simple-bridge.c
@@ -29,7 +29,7 @@ struct simple_bridge {
 
 	const struct simple_bridge_info *info;
 
-	struct i2c_adapter	*ddc;
+	struct drm_bridge	*next_bridge;
 	struct regulator	*vdd;
 	struct gpio_desc	*enable;
 };
@@ -52,29 +52,28 @@ static int simple_bridge_get_modes(struct drm_connector *connector)
 	struct edid *edid;
 	int ret;
 
-	if (!sbridge->ddc)
-		goto fallback;
+	if (sbridge->next_bridge->ops & DRM_BRIDGE_OP_EDID) {
+		edid = drm_bridge_get_edid(sbridge->next_bridge, connector);
+		if (!edid)
+			DRM_INFO("EDID read failed. Fallback to standard modes\n");
+	} else {
+		edid = NULL;
+	}
 
-	edid = drm_get_edid(connector, sbridge->ddc);
 	if (!edid) {
-		DRM_INFO("EDID readout failed, falling back to standard modes\n");
-		goto fallback;
+		/*
+		 * In case we cannot retrieve the EDIDs (missing or broken DDC
+		 * bus from the next bridge), fallback on the XGA standards and
+		 * prefer a mode pretty much anyone can handle.
+		 */
+		ret = drm_add_modes_noedid(connector, 1920, 1200);
+		drm_set_preferred_mode(connector, 1024, 768);
+		return ret;
 	}
 
 	drm_connector_update_edid_property(connector, edid);
 	ret = drm_add_edid_modes(connector, edid);
 	kfree(edid);
-	return ret;
-
-fallback:
-	/*
-	 * In case we cannot retrieve the EDIDs (broken or missing i2c
-	 * bus), fallback on the XGA standards
-	 */
-	ret = drm_add_modes_noedid(connector, 1920, 1200);
-
-	/* And prefer a mode pretty much anyone can handle */
-	drm_set_preferred_mode(connector, 1024, 768);
 
 	return ret;
 }
@@ -88,16 +87,7 @@ simple_bridge_connector_detect(struct drm_connector *connector, bool force)
 {
 	struct simple_bridge *sbridge = drm_connector_to_simple_bridge(connector);
 
-	/*
-	 * Even if we have an I2C bus, we can't assume that the cable
-	 * is disconnected if drm_probe_ddc fails. Some cables don't
-	 * wire the DDC pins, or the I2C bus might not be working at
-	 * all.
-	 */
-	if (sbridge->ddc && drm_probe_ddc(sbridge->ddc))
-		return connector_status_connected;
-
-	return connector_status_unknown;
+	return drm_bridge_detect(sbridge->next_bridge);
 }
 
 static const struct drm_connector_funcs simple_bridge_con_funcs = {
@@ -120,6 +110,11 @@ static int simple_bridge_attach(struct drm_bridge *bridge,
 		return -EINVAL;
 	}
 
+	ret = drm_bridge_attach(bridge->encoder, sbridge->next_bridge, bridge,
+				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+	if (ret < 0)
+		return ret;
+
 	if (!bridge->encoder) {
 		DRM_ERROR("Missing encoder\n");
 		return -ENODEV;
@@ -130,7 +125,7 @@ static int simple_bridge_attach(struct drm_bridge *bridge,
 	ret = drm_connector_init_with_ddc(bridge->dev, &sbridge->connector,
 					  &simple_bridge_con_funcs,
 					  sbridge->info->connector_type,
-					  sbridge->ddc);
+					  sbridge->next_bridge->ddc);
 	if (ret) {
 		DRM_ERROR("Failed to initialize connector\n");
 		return ret;
@@ -172,31 +167,10 @@ static const struct drm_bridge_funcs simple_bridge_bridge_funcs = {
 	.disable	= simple_bridge_disable,
 };
 
-static struct i2c_adapter *simple_bridge_retrieve_ddc(struct device *dev)
-{
-	struct device_node *phandle, *remote;
-	struct i2c_adapter *ddc;
-
-	remote = of_graph_get_remote_node(dev->of_node, 1, -1);
-	if (!remote)
-		return ERR_PTR(-EINVAL);
-
-	phandle = of_parse_phandle(remote, "ddc-i2c-bus", 0);
-	of_node_put(remote);
-	if (!phandle)
-		return ERR_PTR(-ENODEV);
-
-	ddc = of_get_i2c_adapter_by_node(phandle);
-	of_node_put(phandle);
-	if (!ddc)
-		return ERR_PTR(-EPROBE_DEFER);
-
-	return ddc;
-}
-
 static int simple_bridge_probe(struct platform_device *pdev)
 {
 	struct simple_bridge *sbridge;
+	struct device_node *remote;
 
 	sbridge = devm_kzalloc(&pdev->dev, sizeof(*sbridge), GFP_KERNEL);
 	if (!sbridge)
@@ -205,6 +179,20 @@ static int simple_bridge_probe(struct platform_device *pdev)
 
 	sbridge->info = of_device_get_match_data(&pdev->dev);
 
+	/* Get the next bridge in the pipeline. */
+	remote = of_graph_get_remote_node(pdev->dev.of_node, 1, -1);
+	if (!remote)
+		return -EINVAL;
+
+	sbridge->next_bridge = of_drm_find_bridge(remote);
+	of_node_put(remote);
+
+	if (!sbridge->next_bridge) {
+		dev_dbg(&pdev->dev, "Next bridge not found, deferring probe\n");
+		return -EPROBE_DEFER;
+	}
+
+	/* Get the regulator and GPIO resources. */
 	sbridge->vdd = devm_regulator_get_optional(&pdev->dev, "vdd");
 	if (IS_ERR(sbridge->vdd)) {
 		int ret = PTR_ERR(sbridge->vdd);
@@ -222,18 +210,7 @@ static int simple_bridge_probe(struct platform_device *pdev)
 		return PTR_ERR(sbridge->enable);
 	}
 
-	sbridge->ddc = simple_bridge_retrieve_ddc(&pdev->dev);
-	if (IS_ERR(sbridge->ddc)) {
-		if (PTR_ERR(sbridge->ddc) == -ENODEV) {
-			dev_dbg(&pdev->dev,
-				"No i2c bus specified. Disabling EDID readout\n");
-			sbridge->ddc = NULL;
-		} else {
-			dev_err(&pdev->dev, "Couldn't retrieve i2c bus\n");
-			return PTR_ERR(sbridge->ddc);
-		}
-	}
-
+	/* Register the bridge. */
 	sbridge->bridge.funcs = &simple_bridge_bridge_funcs;
 	sbridge->bridge.of_node = pdev->dev.of_node;
 	sbridge->bridge.timings = sbridge->info->timings;
@@ -249,9 +226,6 @@ static int simple_bridge_remove(struct platform_device *pdev)
 
 	drm_bridge_remove(&sbridge->bridge);
 
-	if (sbridge->ddc)
-		i2c_put_adapter(sbridge->ddc);
-
 	return 0;
 }
 
-- 
Regards,

Laurent Pinchart


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

* [PATCH 07/27] drm: bridge: simple-bridge: Make connector creation optional
  2020-05-26  1:14 [PATCH 00/27] Converter R-Car DU to the DRM bridge connector helper Laurent Pinchart
                   ` (5 preceding siblings ...)
  2020-05-26  1:14 ` [PATCH 06/27] drm: bridge: simple-bridge: Delegate operations to next bridge Laurent Pinchart
@ 2020-05-26  1:14 ` Laurent Pinchart
  2020-05-26  1:14 ` [PATCH 08/27] drm: rcar-du: lvds: Convert to DRM panel bridge helper Laurent Pinchart
                   ` (20 subsequent siblings)
  27 siblings, 0 replies; 69+ messages in thread
From: Laurent Pinchart @ 2020-05-26  1:14 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-renesas-soc, Andrzej Hajda, Jernej Skrabec, Jonas Karlman,
	Neil Armstrong, Sam Ravnborg, Kieran Bingham

Make the connector creation optional to enable usage of the
simple-bridge with the DRM bridge connector helper.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Acked-by: Sam Ravnborg <sam@ravnborg.org>
---
 drivers/gpu/drm/bridge/simple-bridge.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/bridge/simple-bridge.c b/drivers/gpu/drm/bridge/simple-bridge.c
index a1be269d833a..d974282c12b2 100644
--- a/drivers/gpu/drm/bridge/simple-bridge.c
+++ b/drivers/gpu/drm/bridge/simple-bridge.c
@@ -105,16 +105,14 @@ static int simple_bridge_attach(struct drm_bridge *bridge,
 	struct simple_bridge *sbridge = drm_bridge_to_simple_bridge(bridge);
 	int ret;
 
-	if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {
-		DRM_ERROR("Fix bridge driver to make connector optional!");
-		return -EINVAL;
-	}
-
 	ret = drm_bridge_attach(bridge->encoder, sbridge->next_bridge, bridge,
 				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
 	if (ret < 0)
 		return ret;
 
+	if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
+		return 0;
+
 	if (!bridge->encoder) {
 		DRM_ERROR("Missing encoder\n");
 		return -ENODEV;
@@ -131,8 +129,7 @@ static int simple_bridge_attach(struct drm_bridge *bridge,
 		return ret;
 	}
 
-	drm_connector_attach_encoder(&sbridge->connector,
-					  bridge->encoder);
+	drm_connector_attach_encoder(&sbridge->connector, bridge->encoder);
 
 	return 0;
 }
-- 
Regards,

Laurent Pinchart


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

* [PATCH 08/27] drm: rcar-du: lvds: Convert to DRM panel bridge helper
  2020-05-26  1:14 [PATCH 00/27] Converter R-Car DU to the DRM bridge connector helper Laurent Pinchart
                   ` (6 preceding siblings ...)
  2020-05-26  1:14 ` [PATCH 07/27] drm: bridge: simple-bridge: Make connector creation optional Laurent Pinchart
@ 2020-05-26  1:14 ` Laurent Pinchart
  2020-05-26  1:14 ` [PATCH 09/27] drm: edid: Constify connector argument to infoframe functions Laurent Pinchart
                   ` (19 subsequent siblings)
  27 siblings, 0 replies; 69+ messages in thread
From: Laurent Pinchart @ 2020-05-26  1:14 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-renesas-soc, Andrzej Hajda, Jernej Skrabec, Jonas Karlman,
	Neil Armstrong, Sam Ravnborg, Kieran Bingham

Replace the manual panel handling with usage of the DRM panel bridge
helper. This simplifies the driver, and brings support for
DRM_BRIDGE_ATTACH_NO_CONNECTOR as an added bonus.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/gpu/drm/rcar-du/rcar_lvds.c | 124 +++-------------------------
 1 file changed, 12 insertions(+), 112 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.c b/drivers/gpu/drm/rcar-du/rcar_lvds.c
index ab0d49618cf9..9404f12813d1 100644
--- a/drivers/gpu/drm/rcar-du/rcar_lvds.c
+++ b/drivers/gpu/drm/rcar-du/rcar_lvds.c
@@ -63,7 +63,6 @@ struct rcar_lvds {
 	struct drm_bridge bridge;
 
 	struct drm_bridge *next_bridge;
-	struct drm_connector connector;
 	struct drm_panel *panel;
 
 	void __iomem *mmio;
@@ -80,73 +79,11 @@ struct rcar_lvds {
 #define bridge_to_rcar_lvds(b) \
 	container_of(b, struct rcar_lvds, bridge)
 
-#define connector_to_rcar_lvds(c) \
-	container_of(c, struct rcar_lvds, connector)
-
 static void rcar_lvds_write(struct rcar_lvds *lvds, u32 reg, u32 data)
 {
 	iowrite32(data, lvds->mmio + reg);
 }
 
-/* -----------------------------------------------------------------------------
- * Connector & Panel
- */
-
-static int rcar_lvds_connector_get_modes(struct drm_connector *connector)
-{
-	struct rcar_lvds *lvds = connector_to_rcar_lvds(connector);
-
-	return drm_panel_get_modes(lvds->panel, connector);
-}
-
-static int rcar_lvds_connector_atomic_check(struct drm_connector *connector,
-					    struct drm_atomic_state *state)
-{
-	struct rcar_lvds *lvds = connector_to_rcar_lvds(connector);
-	const struct drm_display_mode *panel_mode;
-	struct drm_connector_state *conn_state;
-	struct drm_crtc_state *crtc_state;
-
-	conn_state = drm_atomic_get_new_connector_state(state, connector);
-	if (!conn_state->crtc)
-		return 0;
-
-	if (list_empty(&connector->modes)) {
-		dev_dbg(lvds->dev, "connector: empty modes list\n");
-		return -EINVAL;
-	}
-
-	panel_mode = list_first_entry(&connector->modes,
-				      struct drm_display_mode, head);
-
-	/* We're not allowed to modify the resolution. */
-	crtc_state = drm_atomic_get_crtc_state(state, conn_state->crtc);
-	if (IS_ERR(crtc_state))
-		return PTR_ERR(crtc_state);
-
-	if (crtc_state->mode.hdisplay != panel_mode->hdisplay ||
-	    crtc_state->mode.vdisplay != panel_mode->vdisplay)
-		return -EINVAL;
-
-	/* The flat panel mode is fixed, just copy it to the adjusted mode. */
-	drm_mode_copy(&crtc_state->adjusted_mode, panel_mode);
-
-	return 0;
-}
-
-static const struct drm_connector_helper_funcs rcar_lvds_conn_helper_funcs = {
-	.get_modes = rcar_lvds_connector_get_modes,
-	.atomic_check = rcar_lvds_connector_atomic_check,
-};
-
-static const struct drm_connector_funcs rcar_lvds_conn_funcs = {
-	.reset = drm_atomic_helper_connector_reset,
-	.fill_modes = drm_helper_probe_single_connector_modes,
-	.destroy = drm_connector_cleanup,
-	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
-	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
-};
-
 /* -----------------------------------------------------------------------------
  * PLL Setup
  */
@@ -583,11 +520,6 @@ static void __rcar_lvds_atomic_enable(struct drm_bridge *bridge,
 	/* Turn the output on. */
 	lvdcr0 |= LVDCR0_LVRES;
 	rcar_lvds_write(lvds, LVDCR0, lvdcr0);
-
-	if (lvds->panel) {
-		drm_panel_prepare(lvds->panel);
-		drm_panel_enable(lvds->panel);
-	}
 }
 
 static void rcar_lvds_atomic_enable(struct drm_bridge *bridge,
@@ -609,11 +541,6 @@ static void rcar_lvds_atomic_disable(struct drm_bridge *bridge,
 {
 	struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
 
-	if (lvds->panel) {
-		drm_panel_disable(lvds->panel);
-		drm_panel_unprepare(lvds->panel);
-	}
-
 	rcar_lvds_write(lvds, LVDCR0, 0);
 	rcar_lvds_write(lvds, LVDCR1, 0);
 	rcar_lvds_write(lvds, LVDPLLCR, 0);
@@ -648,49 +575,13 @@ static int rcar_lvds_attach(struct drm_bridge *bridge,
 			    enum drm_bridge_attach_flags flags)
 {
 	struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
-	struct drm_connector *connector = &lvds->connector;
-	struct drm_encoder *encoder = bridge->encoder;
-	int ret;
 
-	/* If we have a next bridge just attach it. */
-	if (lvds->next_bridge)
-		return drm_bridge_attach(bridge->encoder, lvds->next_bridge,
-					 bridge, flags);
-
-	if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {
-		DRM_ERROR("Fix bridge driver to make connector optional!");
-		return -EINVAL;
-	}
-
-	/* Otherwise if we have a panel, create a connector. */
-	if (!lvds->panel)
-		return 0;
-
-	ret = drm_connector_init(bridge->dev, connector, &rcar_lvds_conn_funcs,
-				 DRM_MODE_CONNECTOR_LVDS);
-	if (ret < 0)
-		return ret;
-
-	drm_connector_helper_add(connector, &rcar_lvds_conn_helper_funcs);
-
-	ret = drm_connector_attach_encoder(connector, encoder);
-	if (ret < 0)
-		return ret;
-
-	return drm_panel_attach(lvds->panel, connector);
-}
-
-static void rcar_lvds_detach(struct drm_bridge *bridge)
-{
-	struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
-
-	if (lvds->panel)
-		drm_panel_detach(lvds->panel);
+	return drm_bridge_attach(bridge->encoder, lvds->next_bridge, bridge,
+				 flags);
 }
 
 static const struct drm_bridge_funcs rcar_lvds_bridge_ops = {
 	.attach = rcar_lvds_attach,
-	.detach = rcar_lvds_detach,
 	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
 	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
 	.atomic_reset = drm_atomic_helper_bridge_reset,
@@ -763,7 +654,7 @@ static int rcar_lvds_parse_dt_companion(struct rcar_lvds *lvds)
 		 * that we are expected to generate even pixels from the primary
 		 * encoder, and odd pixels from the companion encoder.
 		 */
-		if (lvds->next_bridge && lvds->next_bridge->timings &&
+		if (lvds->next_bridge->timings &&
 		    lvds->next_bridge->timings->dual_link)
 			lvds->link_type = RCAR_LVDS_DUAL_LINK_EVEN_ODD_PIXELS;
 		else
@@ -815,6 +706,15 @@ static int rcar_lvds_parse_dt(struct rcar_lvds *lvds)
 	if (ret)
 		goto done;
 
+	if (lvds->panel) {
+		lvds->next_bridge = devm_drm_panel_bridge_add(lvds->dev,
+							      lvds->panel);
+		if (IS_ERR_OR_NULL(lvds->next_bridge)) {
+			ret = -EINVAL;
+			goto done;
+		}
+	}
+
 	if (lvds->info->quirks & RCAR_LVDS_QUIRK_DUAL_LINK)
 		ret = rcar_lvds_parse_dt_companion(lvds);
 
-- 
Regards,

Laurent Pinchart


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

* [PATCH 09/27] drm: edid: Constify connector argument to infoframe functions
  2020-05-26  1:14 [PATCH 00/27] Converter R-Car DU to the DRM bridge connector helper Laurent Pinchart
                   ` (7 preceding siblings ...)
  2020-05-26  1:14 ` [PATCH 08/27] drm: rcar-du: lvds: Convert to DRM panel bridge helper Laurent Pinchart
@ 2020-05-26  1:14 ` Laurent Pinchart
  2020-06-21  8:27   ` Sam Ravnborg
  2020-05-26  1:14 ` [PATCH 10/27] drm: bridge: Pass drm_display_info to drm_bridge_funcs .mode_valid() Laurent Pinchart
                   ` (18 subsequent siblings)
  27 siblings, 1 reply; 69+ messages in thread
From: Laurent Pinchart @ 2020-05-26  1:14 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-renesas-soc, Andrzej Hajda, Jernej Skrabec, Jonas Karlman,
	Neil Armstrong, Sam Ravnborg, Kieran Bingham, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann

The drm_hdmi_avi_infoframe_from_display_mode(),
drm_hdmi_vendor_infoframe_from_display_mode() and
drm_hdmi_avi_infoframe_quant_range() functions take a drm_connector that
they don't modify. Mark it as const.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/gpu/drm/drm_edid.c | 12 ++++++------
 include/drm/drm_edid.h     |  6 +++---
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 3bd95c4b02eb..e6b26f16c21f 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -5365,7 +5365,7 @@ void drm_set_preferred_mode(struct drm_connector *connector,
 }
 EXPORT_SYMBOL(drm_set_preferred_mode);
 
-static bool is_hdmi2_sink(struct drm_connector *connector)
+static bool is_hdmi2_sink(const struct drm_connector *connector)
 {
 	/*
 	 * FIXME: sil-sii8620 doesn't have a connector around when
@@ -5450,7 +5450,7 @@ drm_hdmi_infoframe_set_hdr_metadata(struct hdmi_drm_infoframe *frame,
 }
 EXPORT_SYMBOL(drm_hdmi_infoframe_set_hdr_metadata);
 
-static u8 drm_mode_hdmi_vic(struct drm_connector *connector,
+static u8 drm_mode_hdmi_vic(const struct drm_connector *connector,
 			    const struct drm_display_mode *mode)
 {
 	bool has_hdmi_infoframe = connector ?
@@ -5466,7 +5466,7 @@ static u8 drm_mode_hdmi_vic(struct drm_connector *connector,
 	return drm_match_hdmi_mode(mode);
 }
 
-static u8 drm_mode_cea_vic(struct drm_connector *connector,
+static u8 drm_mode_cea_vic(const struct drm_connector *connector,
 			   const struct drm_display_mode *mode)
 {
 	u8 vic;
@@ -5504,7 +5504,7 @@ static u8 drm_mode_cea_vic(struct drm_connector *connector,
  */
 int
 drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
-					 struct drm_connector *connector,
+					 const struct drm_connector *connector,
 					 const struct drm_display_mode *mode)
 {
 	enum hdmi_picture_aspect picture_aspect;
@@ -5651,7 +5651,7 @@ EXPORT_SYMBOL(drm_hdmi_avi_infoframe_colorspace);
  */
 void
 drm_hdmi_avi_infoframe_quant_range(struct hdmi_avi_infoframe *frame,
-				   struct drm_connector *connector,
+				   const struct drm_connector *connector,
 				   const struct drm_display_mode *mode,
 				   enum hdmi_quantization_range rgb_quant_range)
 {
@@ -5755,7 +5755,7 @@ s3d_structure_from_display_mode(const struct drm_display_mode *mode)
  */
 int
 drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame,
-					    struct drm_connector *connector,
+					    const struct drm_connector *connector,
 					    const struct drm_display_mode *mode)
 {
 	/*
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 34b15e3d070c..43254319ab19 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -361,11 +361,11 @@ drm_load_edid_firmware(struct drm_connector *connector)
 
 int
 drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
-					 struct drm_connector *connector,
+					 const struct drm_connector *connector,
 					 const struct drm_display_mode *mode);
 int
 drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame,
-					    struct drm_connector *connector,
+					    const struct drm_connector *connector,
 					    const struct drm_display_mode *mode);
 
 void
@@ -378,7 +378,7 @@ drm_hdmi_avi_infoframe_bars(struct hdmi_avi_infoframe *frame,
 
 void
 drm_hdmi_avi_infoframe_quant_range(struct hdmi_avi_infoframe *frame,
-				   struct drm_connector *connector,
+				   const struct drm_connector *connector,
 				   const struct drm_display_mode *mode,
 				   enum hdmi_quantization_range rgb_quant_range);
 
-- 
Regards,

Laurent Pinchart


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

* [PATCH 10/27] drm: bridge: Pass drm_display_info to drm_bridge_funcs .mode_valid()
  2020-05-26  1:14 [PATCH 00/27] Converter R-Car DU to the DRM bridge connector helper Laurent Pinchart
                   ` (8 preceding siblings ...)
  2020-05-26  1:14 ` [PATCH 09/27] drm: edid: Constify connector argument to infoframe functions Laurent Pinchart
@ 2020-05-26  1:14 ` Laurent Pinchart
  2020-05-26 12:51   ` Neil Armstrong
                     ` (2 more replies)
  2020-05-26  1:14 ` [PATCH 11/27] drm: bridge: dw-hdmi: Pass private data pointer to .mode_valid() Laurent Pinchart
                   ` (17 subsequent siblings)
  27 siblings, 3 replies; 69+ messages in thread
From: Laurent Pinchart @ 2020-05-26  1:14 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-renesas-soc, Andrzej Hajda, Jernej Skrabec, Jonas Karlman,
	Neil Armstrong, Sam Ravnborg, Kieran Bingham, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Andrey Gusakov,
	Boris Brezillon, Chris Zhong, Enric Balletbo i Serra,
	Guido Günther, Icenowy Zheng, Jacopo Mondi, Jyri Sarha,
	Lubomir Rintel, Maciej Purski, Peter Ujfalusi, Philippe Cornu,
	Russell King, Tomasz Stanislawski, Tomi Valkeinen

When validating a mode, bridges may need to do so in the context of a
display, as specified by drm_display_info. An example is the meson
dw-hdmi bridge that needs to consider the YUV 4:2:0 output format to
perform clock calculations.

Bridges that need the display info currently retrieve it from the
drm_connector created by the bridge. This gets in the way of moving
connector creation out of bridge drivers. To make this possible, pass
the drm_display_info to drm_bridge_funcs .mode_valid().

Changes to the bridge drivers have been performed with the following
coccinelle semantic patch and have been compile-tested.

@ rule1 @
identifier funcs;
identifier fn;
@@
 struct drm_bridge_funcs funcs = {
 	...,
 	.mode_valid = fn
 };

@ depends on rule1 @
identifier rule1.fn;
identifier bridge;
identifier mode;
@@
 enum drm_mode_status fn(
 	struct drm_bridge *bridge,
+	const struct drm_display_info *info,
 	const struct drm_display_mode *mode
 )
 {
 	...
 }

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/gpu/drm/bridge/analogix/analogix-anx6345.c | 1 +
 drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c | 1 +
 drivers/gpu/drm/bridge/cdns-dsi.c                  | 1 +
 drivers/gpu/drm/bridge/chrontel-ch7033.c           | 1 +
 drivers/gpu/drm/bridge/nwl-dsi.c                   | 1 +
 drivers/gpu/drm/bridge/sii9234.c                   | 1 +
 drivers/gpu/drm/bridge/sil-sii8620.c               | 1 +
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c          | 1 +
 drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c      | 1 +
 drivers/gpu/drm/bridge/tc358767.c                  | 1 +
 drivers/gpu/drm/bridge/tc358768.c                  | 1 +
 drivers/gpu/drm/bridge/thc63lvd1024.c              | 1 +
 drivers/gpu/drm/bridge/ti-tfp410.c                 | 1 +
 drivers/gpu/drm/drm_atomic_helper.c                | 3 ++-
 drivers/gpu/drm/drm_bridge.c                       | 4 +++-
 drivers/gpu/drm/drm_probe_helper.c                 | 4 +++-
 drivers/gpu/drm/i2c/tda998x_drv.c                  | 1 +
 drivers/gpu/drm/omapdrm/dss/dpi.c                  | 1 +
 drivers/gpu/drm/omapdrm/dss/sdi.c                  | 1 +
 drivers/gpu/drm/omapdrm/dss/venc.c                 | 1 +
 include/drm/drm_bridge.h                           | 3 +++
 21 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c b/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c
index 2bc6e4f85171..371f4a9f866d 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c
@@ -585,6 +585,7 @@ static int anx6345_bridge_attach(struct drm_bridge *bridge,
 
 static enum drm_mode_status
 anx6345_bridge_mode_valid(struct drm_bridge *bridge,
+			  const struct drm_display_info *info,
 			  const struct drm_display_mode *mode)
 {
 	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
diff --git a/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c b/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c
index 0d5a5ad0c9ee..81debd02c169 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c
@@ -944,6 +944,7 @@ static int anx78xx_bridge_attach(struct drm_bridge *bridge,
 
 static enum drm_mode_status
 anx78xx_bridge_mode_valid(struct drm_bridge *bridge,
+			  const struct drm_display_info *info,
 			  const struct drm_display_mode *mode)
 {
 	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
diff --git a/drivers/gpu/drm/bridge/cdns-dsi.c b/drivers/gpu/drm/bridge/cdns-dsi.c
index 69c3892caee5..76373e31df92 100644
--- a/drivers/gpu/drm/bridge/cdns-dsi.c
+++ b/drivers/gpu/drm/bridge/cdns-dsi.c
@@ -663,6 +663,7 @@ static int cdns_dsi_bridge_attach(struct drm_bridge *bridge,
 
 static enum drm_mode_status
 cdns_dsi_bridge_mode_valid(struct drm_bridge *bridge,
+			   const struct drm_display_info *info,
 			   const struct drm_display_mode *mode)
 {
 	struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge);
diff --git a/drivers/gpu/drm/bridge/chrontel-ch7033.c b/drivers/gpu/drm/bridge/chrontel-ch7033.c
index f8675d82974b..486f405c2e16 100644
--- a/drivers/gpu/drm/bridge/chrontel-ch7033.c
+++ b/drivers/gpu/drm/bridge/chrontel-ch7033.c
@@ -317,6 +317,7 @@ static void ch7033_bridge_detach(struct drm_bridge *bridge)
 }
 
 static enum drm_mode_status ch7033_bridge_mode_valid(struct drm_bridge *bridge,
+				     const struct drm_display_info *info,
 				     const struct drm_display_mode *mode)
 {
 	if (mode->clock > 165000)
diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
index b14d725bf609..77a79af70914 100644
--- a/drivers/gpu/drm/bridge/nwl-dsi.c
+++ b/drivers/gpu/drm/bridge/nwl-dsi.c
@@ -818,6 +818,7 @@ static bool nwl_dsi_bridge_mode_fixup(struct drm_bridge *bridge,
 
 static enum drm_mode_status
 nwl_dsi_bridge_mode_valid(struct drm_bridge *bridge,
+			  const struct drm_display_info *info,
 			  const struct drm_display_mode *mode)
 {
 	struct nwl_dsi *dsi = bridge_to_dsi(bridge);
diff --git a/drivers/gpu/drm/bridge/sii9234.c b/drivers/gpu/drm/bridge/sii9234.c
index b1258f0ed205..15c98a7bd81c 100644
--- a/drivers/gpu/drm/bridge/sii9234.c
+++ b/drivers/gpu/drm/bridge/sii9234.c
@@ -873,6 +873,7 @@ static inline struct sii9234 *bridge_to_sii9234(struct drm_bridge *bridge)
 }
 
 static enum drm_mode_status sii9234_mode_valid(struct drm_bridge *bridge,
+					 const struct drm_display_info *info,
 					 const struct drm_display_mode *mode)
 {
 	if (mode->clock > MHL1_MAX_CLK)
diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
index 92acd336aa89..7c0c93c7e61f 100644
--- a/drivers/gpu/drm/bridge/sil-sii8620.c
+++ b/drivers/gpu/drm/bridge/sil-sii8620.c
@@ -2244,6 +2244,7 @@ static int sii8620_is_packing_required(struct sii8620 *ctx,
 }
 
 static enum drm_mode_status sii8620_mode_valid(struct drm_bridge *bridge,
+					 const struct drm_display_info *info,
 					 const struct drm_display_mode *mode)
 {
 	struct sii8620 *ctx = bridge_to_sii8620(bridge);
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 30681398cfb0..b535354150db 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -2767,6 +2767,7 @@ static void dw_hdmi_bridge_detach(struct drm_bridge *bridge)
 
 static enum drm_mode_status
 dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
+			  const struct drm_display_info *info,
 			  const struct drm_display_mode *mode)
 {
 	struct dw_hdmi *hdmi = bridge->driver_private;
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index 5ef0f154aa7b..c223fb9a04cb 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -924,6 +924,7 @@ static void dw_mipi_dsi_bridge_enable(struct drm_bridge *bridge)
 
 static enum drm_mode_status
 dw_mipi_dsi_bridge_mode_valid(struct drm_bridge *bridge,
+			      const struct drm_display_info *info,
 			      const struct drm_display_mode *mode)
 {
 	struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge);
diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c
index e4c0ea03ae3a..c2777b226c75 100644
--- a/drivers/gpu/drm/bridge/tc358767.c
+++ b/drivers/gpu/drm/bridge/tc358767.c
@@ -1306,6 +1306,7 @@ static bool tc_bridge_mode_fixup(struct drm_bridge *bridge,
 }
 
 static enum drm_mode_status tc_mode_valid(struct drm_bridge *bridge,
+					  const struct drm_display_info *info,
 					  const struct drm_display_mode *mode)
 {
 	struct tc_data *tc = bridge_to_tc(bridge);
diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c
index 6650fe4cfc20..4a463fadf743 100644
--- a/drivers/gpu/drm/bridge/tc358768.c
+++ b/drivers/gpu/drm/bridge/tc358768.c
@@ -529,6 +529,7 @@ static int tc358768_bridge_attach(struct drm_bridge *bridge,
 
 static enum drm_mode_status
 tc358768_bridge_mode_valid(struct drm_bridge *bridge,
+			   const struct drm_display_info *info,
 			   const struct drm_display_mode *mode)
 {
 	struct tc358768_priv *priv = bridge_to_tc358768(bridge);
diff --git a/drivers/gpu/drm/bridge/thc63lvd1024.c b/drivers/gpu/drm/bridge/thc63lvd1024.c
index 97d8129760e9..86b06975bfdd 100644
--- a/drivers/gpu/drm/bridge/thc63lvd1024.c
+++ b/drivers/gpu/drm/bridge/thc63lvd1024.c
@@ -51,6 +51,7 @@ static int thc63_attach(struct drm_bridge *bridge,
 }
 
 static enum drm_mode_status thc63_mode_valid(struct drm_bridge *bridge,
+					const struct drm_display_info *info,
 					const struct drm_display_mode *mode)
 {
 	struct thc63_dev *thc63 = to_thc63(bridge);
diff --git a/drivers/gpu/drm/bridge/ti-tfp410.c b/drivers/gpu/drm/bridge/ti-tfp410.c
index f065a96a0917..1f49aca06a9f 100644
--- a/drivers/gpu/drm/bridge/ti-tfp410.c
+++ b/drivers/gpu/drm/bridge/ti-tfp410.c
@@ -192,6 +192,7 @@ static void tfp410_disable(struct drm_bridge *bridge)
 }
 
 static enum drm_mode_status tfp410_mode_valid(struct drm_bridge *bridge,
+					      const struct drm_display_info *info,
 					      const struct drm_display_mode *mode)
 {
 	if (mode->clock < 25000)
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 85d163f16801..c1178518dc7a 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -506,7 +506,8 @@ static enum drm_mode_status mode_valid_path(struct drm_connector *connector,
 	}
 
 	bridge = drm_bridge_chain_get_first_bridge(encoder);
-	ret = drm_bridge_chain_mode_valid(bridge, mode);
+	ret = drm_bridge_chain_mode_valid(bridge, &connector->display_info,
+					  mode);
 	if (ret != MODE_OK) {
 		DRM_DEBUG_ATOMIC("[BRIDGE] mode_valid() failed\n");
 		return ret;
diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index fe1e3460b486..64f0effb52ac 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -377,6 +377,7 @@ EXPORT_SYMBOL(drm_bridge_chain_mode_fixup);
  * drm_bridge_chain_mode_valid - validate the mode against all bridges in the
  *				 encoder chain.
  * @bridge: bridge control structure
+ * @info: display info against which the mode shall be validated
  * @mode: desired mode to be validated
  *
  * Calls &drm_bridge_funcs.mode_valid for all the bridges in the encoder
@@ -390,6 +391,7 @@ EXPORT_SYMBOL(drm_bridge_chain_mode_fixup);
  */
 enum drm_mode_status
 drm_bridge_chain_mode_valid(struct drm_bridge *bridge,
+			    const struct drm_display_info *info,
 			    const struct drm_display_mode *mode)
 {
 	struct drm_encoder *encoder;
@@ -404,7 +406,7 @@ drm_bridge_chain_mode_valid(struct drm_bridge *bridge,
 		if (!bridge->funcs->mode_valid)
 			continue;
 
-		ret = bridge->funcs->mode_valid(bridge, mode);
+		ret = bridge->funcs->mode_valid(bridge, info, mode);
 		if (ret != MODE_OK)
 			return ret;
 	}
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
index 576b4b7dcd89..f5d141e0400f 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -114,7 +114,9 @@ drm_mode_validate_pipeline(struct drm_display_mode *mode,
 		}
 
 		bridge = drm_bridge_chain_get_first_bridge(encoder);
-		ret = drm_bridge_chain_mode_valid(bridge, mode);
+		ret = drm_bridge_chain_mode_valid(bridge,
+						  &connector->display_info,
+						  mode);
 		if (ret != MODE_OK) {
 			/* There is also no point in continuing for crtc check
 			 * here. */
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
index 9517f522dcb9..50fd119a5276 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -1379,6 +1379,7 @@ static void tda998x_bridge_detach(struct drm_bridge *bridge)
 }
 
 static enum drm_mode_status tda998x_bridge_mode_valid(struct drm_bridge *bridge,
+				     const struct drm_display_info *info,
 				     const struct drm_display_mode *mode)
 {
 	/* TDA19988 dotclock can go up to 165MHz */
diff --git a/drivers/gpu/drm/omapdrm/dss/dpi.c b/drivers/gpu/drm/omapdrm/dss/dpi.c
index 5110acb0c6c1..1d2992daef40 100644
--- a/drivers/gpu/drm/omapdrm/dss/dpi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dpi.c
@@ -434,6 +434,7 @@ static int dpi_bridge_attach(struct drm_bridge *bridge,
 
 static enum drm_mode_status
 dpi_bridge_mode_valid(struct drm_bridge *bridge,
+		       const struct drm_display_info *info,
 		       const struct drm_display_mode *mode)
 {
 	struct dpi_data *dpi = drm_bridge_to_dpi(bridge);
diff --git a/drivers/gpu/drm/omapdrm/dss/sdi.c b/drivers/gpu/drm/omapdrm/dss/sdi.c
index 417a8740ad0a..033fd30074b0 100644
--- a/drivers/gpu/drm/omapdrm/dss/sdi.c
+++ b/drivers/gpu/drm/omapdrm/dss/sdi.c
@@ -140,6 +140,7 @@ static int sdi_bridge_attach(struct drm_bridge *bridge,
 
 static enum drm_mode_status
 sdi_bridge_mode_valid(struct drm_bridge *bridge,
+		      const struct drm_display_info *info,
 		      const struct drm_display_mode *mode)
 {
 	struct sdi_device *sdi = drm_bridge_to_sdi(bridge);
diff --git a/drivers/gpu/drm/omapdrm/dss/venc.c b/drivers/gpu/drm/omapdrm/dss/venc.c
index 9701843ccf09..4406ce2a08b4 100644
--- a/drivers/gpu/drm/omapdrm/dss/venc.c
+++ b/drivers/gpu/drm/omapdrm/dss/venc.c
@@ -548,6 +548,7 @@ static int venc_bridge_attach(struct drm_bridge *bridge,
 
 static enum drm_mode_status
 venc_bridge_mode_valid(struct drm_bridge *bridge,
+		       const struct drm_display_info *info,
 		       const struct drm_display_mode *mode)
 {
 	switch (venc_get_videomode(mode)) {
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index ea2aa5ebae34..e3d7f36d8c39 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -35,6 +35,7 @@
 struct drm_bridge;
 struct drm_bridge_timings;
 struct drm_connector;
+struct drm_display_info;
 struct drm_panel;
 struct edid;
 struct i2c_adapter;
@@ -112,6 +113,7 @@ struct drm_bridge_funcs {
 	 * drm_mode_status Enum
 	 */
 	enum drm_mode_status (*mode_valid)(struct drm_bridge *bridge,
+					   const struct drm_display_info *info,
 					   const struct drm_display_mode *mode);
 
 	/**
@@ -836,6 +838,7 @@ bool drm_bridge_chain_mode_fixup(struct drm_bridge *bridge,
 				 struct drm_display_mode *adjusted_mode);
 enum drm_mode_status
 drm_bridge_chain_mode_valid(struct drm_bridge *bridge,
+			    const struct drm_display_info *info,
 			    const struct drm_display_mode *mode);
 void drm_bridge_chain_disable(struct drm_bridge *bridge);
 void drm_bridge_chain_post_disable(struct drm_bridge *bridge);
-- 
Regards,

Laurent Pinchart


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

* [PATCH 11/27] drm: bridge: dw-hdmi: Pass private data pointer to .mode_valid()
  2020-05-26  1:14 [PATCH 00/27] Converter R-Car DU to the DRM bridge connector helper Laurent Pinchart
                   ` (9 preceding siblings ...)
  2020-05-26  1:14 ` [PATCH 10/27] drm: bridge: Pass drm_display_info to drm_bridge_funcs .mode_valid() Laurent Pinchart
@ 2020-05-26  1:14 ` Laurent Pinchart
  2020-05-26  9:44   ` Neil Armstrong
  2020-05-26  1:14 ` [PATCH 12/27] drm: bridge: dw-hdmi: Pass private data pointer to .configure_phy() Laurent Pinchart
                   ` (16 subsequent siblings)
  27 siblings, 1 reply; 69+ messages in thread
From: Laurent Pinchart @ 2020-05-26  1:14 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-renesas-soc, Andrzej Hajda, Jernej Skrabec, Jonas Karlman,
	Neil Armstrong, Sam Ravnborg, Kieran Bingham, Philipp Zabel,
	Sandy Huang, Heiko Stübner, Maxime Ripard, Chen-Yu Tsai,
	linux-amlogic

Platform glue drivers for dw_hdmi may need to access device-specific
data from their .mode_valid() implementation. They currently have no
clean way to do so, and one driver hacks around it by accessing the
dev_private data of the drm_device retrieved from the connector.

Add a priv_data void pointer to the dw_hdmi_plat_data structure, and
pass it to the .mode_valid() function.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c   |  6 ++++--
 drivers/gpu/drm/imx/dw_hdmi-imx.c           |  6 ++++--
 drivers/gpu/drm/meson/meson_dw_hdmi.c       |  3 ++-
 drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c      |  3 ++-
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c |  3 ++-
 drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c       |  6 ++++--
 drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h       |  3 ++-
 include/drm/bridge/dw_hdmi.h                | 14 ++++++++++++--
 8 files changed, 32 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index b535354150db..2b3f203cf467 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -2771,6 +2771,7 @@ dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
 			  const struct drm_display_mode *mode)
 {
 	struct dw_hdmi *hdmi = bridge->driver_private;
+	const struct dw_hdmi_plat_data *pdata = hdmi->plat_data;
 	struct drm_connector *connector = &hdmi->connector;
 	enum drm_mode_status mode_status = MODE_OK;
 
@@ -2778,8 +2779,9 @@ dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
 	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
 		return MODE_BAD;
 
-	if (hdmi->plat_data->mode_valid)
-		mode_status = hdmi->plat_data->mode_valid(connector, mode);
+	if (pdata->mode_valid)
+		mode_status = pdata->mode_valid(hdmi, pdata->priv_data,
+						connector, mode);
 
 	return mode_status;
 }
diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c b/drivers/gpu/drm/imx/dw_hdmi-imx.c
index ba4ca17fd4d8..95aed4666c95 100644
--- a/drivers/gpu/drm/imx/dw_hdmi-imx.c
+++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c
@@ -145,7 +145,8 @@ static const struct drm_encoder_helper_funcs dw_hdmi_imx_encoder_helper_funcs =
 };
 
 static enum drm_mode_status
-imx6q_hdmi_mode_valid(struct drm_connector *con,
+imx6q_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data,
+		      struct drm_connector *con,
 		      const struct drm_display_mode *mode)
 {
 	if (mode->clock < 13500)
@@ -158,7 +159,8 @@ imx6q_hdmi_mode_valid(struct drm_connector *con,
 }
 
 static enum drm_mode_status
-imx6dl_hdmi_mode_valid(struct drm_connector *con,
+imx6dl_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data,
+		       struct drm_connector *con,
 		       const struct drm_display_mode *mode)
 {
 	if (mode->clock < 13500)
diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c
index 5be963e9db05..5cc311c1b8e0 100644
--- a/drivers/gpu/drm/meson/meson_dw_hdmi.c
+++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c
@@ -630,7 +630,8 @@ static irqreturn_t dw_hdmi_top_thread_irq(int irq, void *dev_id)
 }
 
 static enum drm_mode_status
-dw_hdmi_mode_valid(struct drm_connector *connector,
+dw_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data,
+		   struct drm_connector *connector,
 		   const struct drm_display_mode *mode)
 {
 	struct meson_drm *priv = connector->dev->dev_private;
diff --git a/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c b/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c
index 452461dc96f2..4d837a4d302d 100644
--- a/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c
+++ b/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c
@@ -38,7 +38,8 @@ static const struct rcar_hdmi_phy_params rcar_hdmi_phy_params[] = {
 };
 
 static enum drm_mode_status
-rcar_hdmi_mode_valid(struct drm_connector *connector,
+rcar_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data,
+		     struct drm_connector *connector,
 		     const struct drm_display_mode *mode)
 {
 	/*
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index 121aa8a63a76..d08f86783a28 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -220,7 +220,8 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
 }
 
 static enum drm_mode_status
-dw_hdmi_rockchip_mode_valid(struct drm_connector *connector,
+dw_hdmi_rockchip_mode_valid(struct dw_hdmi *hdmi, void *data,
+			    struct drm_connector *connector,
 			    const struct drm_display_mode *mode)
 {
 	const struct dw_hdmi_mpll_config *mpll_cfg = rockchip_mpll_cfg;
diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
index 972682bb8000..0a3637442ba6 100644
--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
+++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
@@ -31,7 +31,8 @@ sun8i_dw_hdmi_encoder_helper_funcs = {
 };
 
 static enum drm_mode_status
-sun8i_dw_hdmi_mode_valid_a83t(struct drm_connector *connector,
+sun8i_dw_hdmi_mode_valid_a83t(struct dw_hdmi *hdmi, void *data,
+			      struct drm_connector *connector,
 			      const struct drm_display_mode *mode)
 {
 	if (mode->clock > 297000)
@@ -41,7 +42,8 @@ sun8i_dw_hdmi_mode_valid_a83t(struct drm_connector *connector,
 }
 
 static enum drm_mode_status
-sun8i_dw_hdmi_mode_valid_h6(struct drm_connector *connector,
+sun8i_dw_hdmi_mode_valid_h6(struct dw_hdmi *hdmi, void *data,
+			    struct drm_connector *connector,
 			    const struct drm_display_mode *mode)
 {
 	/*
diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
index 8e64945167e9..8587b8d2590e 100644
--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
+++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
@@ -176,7 +176,8 @@ struct sun8i_hdmi_phy {
 };
 
 struct sun8i_dw_hdmi_quirks {
-	enum drm_mode_status (*mode_valid)(struct drm_connector *connector,
+	enum drm_mode_status (*mode_valid)(struct dw_hdmi *hdmi, void *data,
+					   struct drm_connector *connector,
 					   const struct drm_display_mode *mode);
 	unsigned int set_rate : 1;
 	unsigned int use_drm_infoframe : 1;
diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
index 0b34a12c4a1c..66a811f75b91 100644
--- a/include/drm/bridge/dw_hdmi.h
+++ b/include/drm/bridge/dw_hdmi.h
@@ -124,13 +124,23 @@ struct dw_hdmi_phy_ops {
 
 struct dw_hdmi_plat_data {
 	struct regmap *regm;
-	enum drm_mode_status (*mode_valid)(struct drm_connector *connector,
-					   const struct drm_display_mode *mode);
+
 	unsigned long input_bus_format;
 	unsigned long input_bus_encoding;
 	bool use_drm_infoframe;
 	bool ycbcr_420_allowed;
 
+	/*
+	 * Private data passed to all the .mode_valid() and .configure_phy()
+	 * callback functions.
+	 */
+	void *priv_data;
+
+	/* Platform-specific mode validation (optional). */
+	enum drm_mode_status (*mode_valid)(struct dw_hdmi *hdmi, void *data,
+					   struct drm_connector *connector,
+					   const struct drm_display_mode *mode);
+
 	/* Vendor PHY support */
 	const struct dw_hdmi_phy_ops *phy_ops;
 	const char *phy_name;
-- 
Regards,

Laurent Pinchart


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

* [PATCH 12/27] drm: bridge: dw-hdmi: Pass private data pointer to .configure_phy()
  2020-05-26  1:14 [PATCH 00/27] Converter R-Car DU to the DRM bridge connector helper Laurent Pinchart
                   ` (10 preceding siblings ...)
  2020-05-26  1:14 ` [PATCH 11/27] drm: bridge: dw-hdmi: Pass private data pointer to .mode_valid() Laurent Pinchart
@ 2020-05-26  1:14 ` Laurent Pinchart
  2020-05-26  9:45   ` Neil Armstrong
  2020-05-26  1:14 ` [PATCH 13/27] drm: bridge: dw-hdmi: Remove unused field from dw_hdmi_plat_data Laurent Pinchart
                   ` (15 subsequent siblings)
  27 siblings, 1 reply; 69+ messages in thread
From: Laurent Pinchart @ 2020-05-26  1:14 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-renesas-soc, Andrzej Hajda, Jernej Skrabec, Jonas Karlman,
	Neil Armstrong, Sam Ravnborg, Kieran Bingham

The .configure_phy() operation takes a dw_hdmi_plat_data pointer as a
context argument. This differs from .mode_valid() that takes a custom
private context pointer, causing possible confusion. Make the
dw_hdmi_plat_data operations more consistent by passing the private
context pointer to .configure_phy() as well.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 2 +-
 drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c    | 3 +--
 include/drm/bridge/dw_hdmi.h              | 3 +--
 3 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 2b3f203cf467..6edb60e6c784 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -1514,7 +1514,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi)
 
 	/* Write to the PHY as configured by the platform */
 	if (pdata->configure_phy)
-		ret = pdata->configure_phy(hdmi, pdata, mpixelclock);
+		ret = pdata->configure_phy(hdmi, pdata->priv_data, mpixelclock);
 	else
 		ret = phy->configure(hdmi, pdata, mpixelclock);
 	if (ret) {
diff --git a/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c b/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c
index 4d837a4d302d..d0dffe55a7cb 100644
--- a/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c
+++ b/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c
@@ -52,8 +52,7 @@ rcar_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data,
 	return MODE_OK;
 }
 
-static int rcar_hdmi_phy_configure(struct dw_hdmi *hdmi,
-				   const struct dw_hdmi_plat_data *pdata,
+static int rcar_hdmi_phy_configure(struct dw_hdmi *hdmi, void *data,
 				   unsigned long mpixelclock)
 {
 	const struct rcar_hdmi_phy_params *params = rcar_hdmi_phy_params;
diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
index 66a811f75b91..09348c9cbd11 100644
--- a/include/drm/bridge/dw_hdmi.h
+++ b/include/drm/bridge/dw_hdmi.h
@@ -151,8 +151,7 @@ struct dw_hdmi_plat_data {
 	const struct dw_hdmi_mpll_config *mpll_cfg;
 	const struct dw_hdmi_curr_ctrl *cur_ctr;
 	const struct dw_hdmi_phy_config *phy_config;
-	int (*configure_phy)(struct dw_hdmi *hdmi,
-			     const struct dw_hdmi_plat_data *pdata,
+	int (*configure_phy)(struct dw_hdmi *hdmi, void *data,
 			     unsigned long mpixelclock);
 };
 
-- 
Regards,

Laurent Pinchart


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

* [PATCH 13/27] drm: bridge: dw-hdmi: Remove unused field from dw_hdmi_plat_data
  2020-05-26  1:14 [PATCH 00/27] Converter R-Car DU to the DRM bridge connector helper Laurent Pinchart
                   ` (11 preceding siblings ...)
  2020-05-26  1:14 ` [PATCH 12/27] drm: bridge: dw-hdmi: Pass private data pointer to .configure_phy() Laurent Pinchart
@ 2020-05-26  1:14 ` Laurent Pinchart
  2020-05-26  9:45   ` Neil Armstrong
  2020-05-26  1:14 ` [PATCH 14/27] drm: meson: dw-hdmi: Use dw_hdmi context to replace hack Laurent Pinchart
                   ` (14 subsequent siblings)
  27 siblings, 1 reply; 69+ messages in thread
From: Laurent Pinchart @ 2020-05-26  1:14 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-renesas-soc, Andrzej Hajda, Jernej Skrabec, Jonas Karlman,
	Neil Armstrong, Sam Ravnborg, Kieran Bingham

The input_bus_format field of struct dw_hdmi_plat_data is unused. Remove
it.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 5 +----
 include/drm/bridge/dw_hdmi.h              | 1 -
 2 files changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 6edb60e6c784..adc5a95a06e9 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -2137,10 +2137,7 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
 	hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 0;
 	hdmi->hdmi_data.video_mode.mpixelrepetitioninput = 0;
 
-	if (hdmi->plat_data->input_bus_format)
-		hdmi->hdmi_data.enc_in_bus_format =
-			hdmi->plat_data->input_bus_format;
-	else if (hdmi->hdmi_data.enc_in_bus_format == MEDIA_BUS_FMT_FIXED)
+	if (hdmi->hdmi_data.enc_in_bus_format == MEDIA_BUS_FMT_FIXED)
 		hdmi->hdmi_data.enc_in_bus_format = MEDIA_BUS_FMT_RGB888_1X24;
 
 	/* TOFIX: Get input encoding from plat data or fallback to none */
diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
index 09348c9cbd11..5dfa9d83e2d3 100644
--- a/include/drm/bridge/dw_hdmi.h
+++ b/include/drm/bridge/dw_hdmi.h
@@ -125,7 +125,6 @@ struct dw_hdmi_phy_ops {
 struct dw_hdmi_plat_data {
 	struct regmap *regm;
 
-	unsigned long input_bus_format;
 	unsigned long input_bus_encoding;
 	bool use_drm_infoframe;
 	bool ycbcr_420_allowed;
-- 
Regards,

Laurent Pinchart


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

* [PATCH 14/27] drm: meson: dw-hdmi: Use dw_hdmi context to replace hack
  2020-05-26  1:14 [PATCH 00/27] Converter R-Car DU to the DRM bridge connector helper Laurent Pinchart
                   ` (12 preceding siblings ...)
  2020-05-26  1:14 ` [PATCH 13/27] drm: bridge: dw-hdmi: Remove unused field from dw_hdmi_plat_data Laurent Pinchart
@ 2020-05-26  1:14 ` Laurent Pinchart
  2020-05-26 12:32   ` Neil Armstrong
  2020-05-26  1:14 ` [PATCH 15/27] drm: bridge: dw-hdmi: Pass drm_display_info to .mode_valid() Laurent Pinchart
                   ` (13 subsequent siblings)
  27 siblings, 1 reply; 69+ messages in thread
From: Laurent Pinchart @ 2020-05-26  1:14 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-renesas-soc, Andrzej Hajda, Jernej Skrabec, Jonas Karlman,
	Neil Armstrong, Sam Ravnborg, Kieran Bingham, linux-amlogic

The meson-dw-hdmi driver needs to access its own context from the
.mode_valid() operation. It currently gets it from the dev_private field
of the drm_device retrieved from the connector, which is a hack. Use the
private data passed to the .mode_valid() operation instead.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/gpu/drm/meson/meson_dw_hdmi.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c
index 5cc311c1b8e0..34ba94922605 100644
--- a/drivers/gpu/drm/meson/meson_dw_hdmi.c
+++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c
@@ -634,7 +634,8 @@ dw_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data,
 		   struct drm_connector *connector,
 		   const struct drm_display_mode *mode)
 {
-	struct meson_drm *priv = connector->dev->dev_private;
+	struct meson_dw_hdmi *dw_hdmi = data;
+	struct meson_drm *priv = dw_hdmi->priv;
 	bool is_hdmi2_sink = connector->display_info.hdmi.scdc.supported;
 	unsigned int phy_freq;
 	unsigned int vclk_freq;
@@ -693,7 +694,7 @@ dw_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data,
 	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
 		venc_freq /= 2;
 
-	dev_dbg(connector->dev->dev, "%s: vclk:%d phy=%d venc=%d hdmi=%d\n",
+	dev_dbg(dw_hdmi->dev, "%s: vclk:%d phy=%d venc=%d hdmi=%d\n",
 		__func__, phy_freq, vclk_freq, venc_freq, hdmi_freq);
 
 	return meson_vclk_vic_supported_freq(priv, phy_freq, vclk_freq);
@@ -1068,6 +1069,7 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master,
 
 	/* Bridge / Connector */
 
+	dw_plat_data->priv_data = meson_dw_hdmi;
 	dw_plat_data->mode_valid = dw_hdmi_mode_valid;
 	dw_plat_data->phy_ops = &meson_dw_hdmi_phy_ops;
 	dw_plat_data->phy_name = "meson_dw_hdmi_phy";
-- 
Regards,

Laurent Pinchart


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

* [PATCH 15/27] drm: bridge: dw-hdmi: Pass drm_display_info to .mode_valid()
  2020-05-26  1:14 [PATCH 00/27] Converter R-Car DU to the DRM bridge connector helper Laurent Pinchart
                   ` (13 preceding siblings ...)
  2020-05-26  1:14 ` [PATCH 14/27] drm: meson: dw-hdmi: Use dw_hdmi context to replace hack Laurent Pinchart
@ 2020-05-26  1:14 ` Laurent Pinchart
  2020-05-26  9:46   ` Neil Armstrong
  2020-05-26  1:14 ` [PATCH 16/27] drm: bridge: dw-hdmi: Constify mode argument to dw_hdmi_phy_ops .init() Laurent Pinchart
                   ` (12 subsequent siblings)
  27 siblings, 1 reply; 69+ messages in thread
From: Laurent Pinchart @ 2020-05-26  1:14 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-renesas-soc, Andrzej Hajda, Jernej Skrabec, Jonas Karlman,
	Neil Armstrong, Sam Ravnborg, Kieran Bingham, Philipp Zabel,
	Sandy Huang, Heiko Stübner, Maxime Ripard, Chen-Yu Tsai,
	linux-amlogic

Replace the drm_connector pointer passed to the .mode_valid() function
with a const drm_display_info pointer, as that's all the function should
need. Use the display info passed to the bridge .mode_valid() operation
instead of retrieving it from the connector, to prepare for make
connector creation optional.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c   |  5 ++---
 drivers/gpu/drm/imx/dw_hdmi-imx.c           |  4 ++--
 drivers/gpu/drm/meson/meson_dw_hdmi.c       | 20 ++++++++++----------
 drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c      |  2 +-
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c |  2 +-
 drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c       |  4 ++--
 drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h       |  2 +-
 include/drm/bridge/dw_hdmi.h                |  4 ++--
 8 files changed, 21 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index adc5a95a06e9..23650e69604c 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -2769,7 +2769,6 @@ dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
 {
 	struct dw_hdmi *hdmi = bridge->driver_private;
 	const struct dw_hdmi_plat_data *pdata = hdmi->plat_data;
-	struct drm_connector *connector = &hdmi->connector;
 	enum drm_mode_status mode_status = MODE_OK;
 
 	/* We don't support double-clocked modes */
@@ -2777,8 +2776,8 @@ dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
 		return MODE_BAD;
 
 	if (pdata->mode_valid)
-		mode_status = pdata->mode_valid(hdmi, pdata->priv_data,
-						connector, mode);
+		mode_status = pdata->mode_valid(hdmi, pdata->priv_data, info,
+						mode);
 
 	return mode_status;
 }
diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c b/drivers/gpu/drm/imx/dw_hdmi-imx.c
index 95aed4666c95..2dc93fa6ecb6 100644
--- a/drivers/gpu/drm/imx/dw_hdmi-imx.c
+++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c
@@ -146,7 +146,7 @@ static const struct drm_encoder_helper_funcs dw_hdmi_imx_encoder_helper_funcs =
 
 static enum drm_mode_status
 imx6q_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data,
-		      struct drm_connector *con,
+		      const struct drm_display_info *info,
 		      const struct drm_display_mode *mode)
 {
 	if (mode->clock < 13500)
@@ -160,7 +160,7 @@ imx6q_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data,
 
 static enum drm_mode_status
 imx6dl_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data,
-		       struct drm_connector *con,
+		       const struct drm_display_info *info,
 		       const struct drm_display_mode *mode)
 {
 	if (mode->clock < 13500)
diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c
index 34ba94922605..71d599970ec7 100644
--- a/drivers/gpu/drm/meson/meson_dw_hdmi.c
+++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c
@@ -631,12 +631,12 @@ static irqreturn_t dw_hdmi_top_thread_irq(int irq, void *dev_id)
 
 static enum drm_mode_status
 dw_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data,
-		   struct drm_connector *connector,
+		   const struct drm_display_info *display_info,
 		   const struct drm_display_mode *mode)
 {
 	struct meson_dw_hdmi *dw_hdmi = data;
 	struct meson_drm *priv = dw_hdmi->priv;
-	bool is_hdmi2_sink = connector->display_info.hdmi.scdc.supported;
+	bool is_hdmi2_sink = display_info->hdmi.scdc.supported;
 	unsigned int phy_freq;
 	unsigned int vclk_freq;
 	unsigned int venc_freq;
@@ -647,10 +647,10 @@ dw_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data,
 	DRM_DEBUG_DRIVER("Modeline " DRM_MODE_FMT "\n", DRM_MODE_ARG(mode));
 
 	/* If sink does not support 540MHz, reject the non-420 HDMI2 modes */
-	if (connector->display_info.max_tmds_clock &&
-	    mode->clock > connector->display_info.max_tmds_clock &&
-	    !drm_mode_is_420_only(&connector->display_info, mode) &&
-	    !drm_mode_is_420_also(&connector->display_info, mode))
+	if (display_info->max_tmds_clock &&
+	    mode->clock > display_info->max_tmds_clock &&
+	    !drm_mode_is_420_only(display_info, mode) &&
+	    !drm_mode_is_420_also(display_info, mode))
 		return MODE_BAD;
 
 	/* Check against non-VIC supported modes */
@@ -667,9 +667,9 @@ dw_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data,
 	vclk_freq = mode->clock;
 
 	/* For 420, pixel clock is half unlike venc clock */
-	if (drm_mode_is_420_only(&connector->display_info, mode) ||
+	if (drm_mode_is_420_only(display_info, mode) ||
 	    (!is_hdmi2_sink &&
-	     drm_mode_is_420_also(&connector->display_info, mode)))
+	     drm_mode_is_420_also(display_info, mode)))
 		vclk_freq /= 2;
 
 	/* TMDS clock is pixel_clock * 10 */
@@ -684,9 +684,9 @@ dw_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data,
 
 	/* VENC double pixels for 1080i, 720p and YUV420 modes */
 	if (meson_venc_hdmi_venc_repeat(vic) ||
-	    drm_mode_is_420_only(&connector->display_info, mode) ||
+	    drm_mode_is_420_only(display_info, mode) ||
 	    (!is_hdmi2_sink &&
-	     drm_mode_is_420_also(&connector->display_info, mode)))
+	     drm_mode_is_420_also(display_info, mode)))
 		venc_freq *= 2;
 
 	vclk_freq = max(venc_freq, hdmi_freq);
diff --git a/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c b/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c
index d0dffe55a7cb..7b8ec8310699 100644
--- a/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c
+++ b/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c
@@ -39,7 +39,7 @@ static const struct rcar_hdmi_phy_params rcar_hdmi_phy_params[] = {
 
 static enum drm_mode_status
 rcar_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data,
-		     struct drm_connector *connector,
+		     const struct drm_display_info *info,
 		     const struct drm_display_mode *mode)
 {
 	/*
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index d08f86783a28..d286751bb333 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -221,7 +221,7 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
 
 static enum drm_mode_status
 dw_hdmi_rockchip_mode_valid(struct dw_hdmi *hdmi, void *data,
-			    struct drm_connector *connector,
+			    const struct drm_display_info *info,
 			    const struct drm_display_mode *mode)
 {
 	const struct dw_hdmi_mpll_config *mpll_cfg = rockchip_mpll_cfg;
diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
index 0a3637442ba6..d4c08043dd81 100644
--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
+++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
@@ -32,7 +32,7 @@ sun8i_dw_hdmi_encoder_helper_funcs = {
 
 static enum drm_mode_status
 sun8i_dw_hdmi_mode_valid_a83t(struct dw_hdmi *hdmi, void *data,
-			      struct drm_connector *connector,
+			      const struct drm_display_info *info,
 			      const struct drm_display_mode *mode)
 {
 	if (mode->clock > 297000)
@@ -43,7 +43,7 @@ sun8i_dw_hdmi_mode_valid_a83t(struct dw_hdmi *hdmi, void *data,
 
 static enum drm_mode_status
 sun8i_dw_hdmi_mode_valid_h6(struct dw_hdmi *hdmi, void *data,
-			    struct drm_connector *connector,
+			    const struct drm_display_info *info,
 			    const struct drm_display_mode *mode)
 {
 	/*
diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
index 8587b8d2590e..d983746fa194 100644
--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
+++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
@@ -177,7 +177,7 @@ struct sun8i_hdmi_phy {
 
 struct sun8i_dw_hdmi_quirks {
 	enum drm_mode_status (*mode_valid)(struct dw_hdmi *hdmi, void *data,
-					   struct drm_connector *connector,
+					   const struct drm_display_info *info,
 					   const struct drm_display_mode *mode);
 	unsigned int set_rate : 1;
 	unsigned int use_drm_infoframe : 1;
diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
index 5dfa9d83e2d3..fec293b21c2e 100644
--- a/include/drm/bridge/dw_hdmi.h
+++ b/include/drm/bridge/dw_hdmi.h
@@ -8,7 +8,7 @@
 
 #include <sound/hdmi-codec.h>
 
-struct drm_connector;
+struct drm_display_info;
 struct drm_display_mode;
 struct drm_encoder;
 struct dw_hdmi;
@@ -137,7 +137,7 @@ struct dw_hdmi_plat_data {
 
 	/* Platform-specific mode validation (optional). */
 	enum drm_mode_status (*mode_valid)(struct dw_hdmi *hdmi, void *data,
-					   struct drm_connector *connector,
+					   const struct drm_display_info *info,
 					   const struct drm_display_mode *mode);
 
 	/* Vendor PHY support */
-- 
Regards,

Laurent Pinchart


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

* [PATCH 16/27] drm: bridge: dw-hdmi: Constify mode argument to dw_hdmi_phy_ops .init()
  2020-05-26  1:14 [PATCH 00/27] Converter R-Car DU to the DRM bridge connector helper Laurent Pinchart
                   ` (14 preceding siblings ...)
  2020-05-26  1:14 ` [PATCH 15/27] drm: bridge: dw-hdmi: Pass drm_display_info to .mode_valid() Laurent Pinchart
@ 2020-05-26  1:14 ` Laurent Pinchart
  2020-05-26  9:46   ` Neil Armstrong
  2020-05-26  1:14 ` [PATCH 17/27] drm: bridge: dw-hdmi: Constify mode argument to internal functions Laurent Pinchart
                   ` (11 subsequent siblings)
  27 siblings, 1 reply; 69+ messages in thread
From: Laurent Pinchart @ 2020-05-26  1:14 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-renesas-soc, Andrzej Hajda, Jernej Skrabec, Jonas Karlman,
	Neil Armstrong, Sam Ravnborg, Kieran Bingham, Sandy Huang,
	Heiko Stübner, Maxime Ripard, Chen-Yu Tsai, linux-amlogic

The PHY .init() must not modify the mode it receives. Make the pointer
const to enfore that.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c   | 2 +-
 drivers/gpu/drm/meson/meson_dw_hdmi.c       | 4 ++--
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 2 +-
 drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c      | 2 +-
 include/drm/bridge/dw_hdmi.h                | 2 +-
 5 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 23650e69604c..6e6a3d95e68e 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -1531,7 +1531,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi)
 }
 
 static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
-			    struct drm_display_mode *mode)
+			    const struct drm_display_mode *mode)
 {
 	int i, ret;
 
diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c
index 71d599970ec7..757c17fbb29f 100644
--- a/drivers/gpu/drm/meson/meson_dw_hdmi.c
+++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c
@@ -297,7 +297,7 @@ static inline void dw_hdmi_dwc_write_bits(struct meson_dw_hdmi *dw_hdmi,
 
 /* Setup PHY bandwidth modes */
 static void meson_hdmi_phy_setup_mode(struct meson_dw_hdmi *dw_hdmi,
-				      struct drm_display_mode *mode)
+				      const struct drm_display_mode *mode)
 {
 	struct meson_drm *priv = dw_hdmi->priv;
 	unsigned int pixel_clock = mode->clock;
@@ -427,7 +427,7 @@ static void dw_hdmi_set_vclk(struct meson_dw_hdmi *dw_hdmi,
 }
 
 static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
-			    struct drm_display_mode *mode)
+			    const struct drm_display_mode *mode)
 {
 	struct meson_dw_hdmi *dw_hdmi = (struct meson_dw_hdmi *)data;
 	struct meson_drm *priv = dw_hdmi->priv;
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index d286751bb333..10e210f6455d 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -312,7 +312,7 @@ static const struct drm_encoder_helper_funcs dw_hdmi_rockchip_encoder_helper_fun
 };
 
 static int dw_hdmi_rockchip_genphy_init(struct dw_hdmi *dw_hdmi, void *data,
-			     struct drm_display_mode *mode)
+					const struct drm_display_mode *mode)
 {
 	struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
 
diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
index 43643ad31730..8e078cacf063 100644
--- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
+++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
@@ -341,7 +341,7 @@ static int sun8i_hdmi_phy_config_h3(struct dw_hdmi *hdmi,
 }
 
 static int sun8i_hdmi_phy_config(struct dw_hdmi *hdmi, void *data,
-				 struct drm_display_mode *mode)
+				 const struct drm_display_mode *mode)
 {
 	struct sun8i_hdmi_phy *phy = (struct sun8i_hdmi_phy *)data;
 	u32 val = 0;
diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
index fec293b21c2e..f930d218cc6b 100644
--- a/include/drm/bridge/dw_hdmi.h
+++ b/include/drm/bridge/dw_hdmi.h
@@ -114,7 +114,7 @@ struct dw_hdmi_phy_config {
 
 struct dw_hdmi_phy_ops {
 	int (*init)(struct dw_hdmi *hdmi, void *data,
-		    struct drm_display_mode *mode);
+		    const struct drm_display_mode *mode);
 	void (*disable)(struct dw_hdmi *hdmi, void *data);
 	enum drm_connector_status (*read_hpd)(struct dw_hdmi *hdmi, void *data);
 	void (*update_hpd)(struct dw_hdmi *hdmi, void *data,
-- 
Regards,

Laurent Pinchart


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

* [PATCH 17/27] drm: bridge: dw-hdmi: Constify mode argument to internal functions
  2020-05-26  1:14 [PATCH 00/27] Converter R-Car DU to the DRM bridge connector helper Laurent Pinchart
                   ` (15 preceding siblings ...)
  2020-05-26  1:14 ` [PATCH 16/27] drm: bridge: dw-hdmi: Constify mode argument to dw_hdmi_phy_ops .init() Laurent Pinchart
@ 2020-05-26  1:14 ` Laurent Pinchart
  2020-05-26  9:46   ` Neil Armstrong
  2020-05-26  1:14 ` [PATCH 18/27] drm: bridge: dw-hdmi: Pass drm_display_info to dw_hdmi_support_scdc() Laurent Pinchart
                   ` (10 subsequent siblings)
  27 siblings, 1 reply; 69+ messages in thread
From: Laurent Pinchart @ 2020-05-26  1:14 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-renesas-soc, Andrzej Hajda, Jernej Skrabec, Jonas Karlman,
	Neil Armstrong, Sam Ravnborg, Kieran Bingham

Several internal functions take a drm_display_mode argument to configure
the HDMI encoder or the HDMI PHY. They must not modify the mode, make
the pointer const to enforce that.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 6e6a3d95e68e..5b5f07a23400 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -1628,7 +1628,8 @@ static void hdmi_tx_hdcp_config(struct dw_hdmi *hdmi)
 		  HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_MASK, HDMI_A_HDCPCFG1);
 }
 
-static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
+static void hdmi_config_AVI(struct dw_hdmi *hdmi,
+			    const struct drm_display_mode *mode)
 {
 	struct hdmi_avi_infoframe frame;
 	u8 val;
@@ -1756,7 +1757,7 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
 }
 
 static void hdmi_config_vendor_specific_infoframe(struct dw_hdmi *hdmi,
-						 struct drm_display_mode *mode)
+						  const struct drm_display_mode *mode)
 {
 	struct hdmi_vendor_infoframe frame;
 	u8 buffer[10];
@@ -2112,7 +2113,8 @@ static void hdmi_disable_overflow_interrupts(struct dw_hdmi *hdmi)
 		    HDMI_IH_MUTE_FC_STAT2);
 }
 
-static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
+static int dw_hdmi_setup(struct dw_hdmi *hdmi,
+			 const struct drm_display_mode *mode)
 {
 	int ret;
 
-- 
Regards,

Laurent Pinchart


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

* [PATCH 18/27] drm: bridge: dw-hdmi: Pass drm_display_info to dw_hdmi_support_scdc()
  2020-05-26  1:14 [PATCH 00/27] Converter R-Car DU to the DRM bridge connector helper Laurent Pinchart
                   ` (16 preceding siblings ...)
  2020-05-26  1:14 ` [PATCH 17/27] drm: bridge: dw-hdmi: Constify mode argument to internal functions Laurent Pinchart
@ 2020-05-26  1:14 ` Laurent Pinchart
  2020-05-26  9:48   ` Neil Armstrong
  2020-05-26  1:14 ` [PATCH 19/27] drm: bridge: dw-hdmi: Split connector creation to a separate function Laurent Pinchart
                   ` (9 subsequent siblings)
  27 siblings, 1 reply; 69+ messages in thread
From: Laurent Pinchart @ 2020-05-26  1:14 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-renesas-soc, Andrzej Hajda, Jernej Skrabec, Jonas Karlman,
	Neil Armstrong, Sam Ravnborg, Kieran Bingham, Sandy Huang,
	Heiko Stübner, Maxime Ripard, Chen-Yu Tsai, linux-amlogic

To prepare for making connector creation optional in the driver, pass
the drm_display_info explicitly to dw_hdmi_support_scdc(). The pointer
is passed to the callers where required, particularly to the
dw_hdmi_phy_ops .init() function.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c   | 32 ++++++++++++---------
 drivers/gpu/drm/meson/meson_dw_hdmi.c       |  3 +-
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c |  1 +
 drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c      |  1 +
 include/drm/bridge/dw_hdmi.h                |  4 ++-
 5 files changed, 26 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 5b5f07a23400..a18794cce0d8 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -1241,10 +1241,9 @@ void dw_hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data,
 EXPORT_SYMBOL_GPL(dw_hdmi_phy_i2c_write);
 
 /* Filter out invalid setups to avoid configuring SCDC and scrambling */
-static bool dw_hdmi_support_scdc(struct dw_hdmi *hdmi)
+static bool dw_hdmi_support_scdc(struct dw_hdmi *hdmi,
+				 const struct drm_display_info *display)
 {
-	struct drm_display_info *display = &hdmi->connector.display_info;
-
 	/* Completely disable SCDC support for older controllers */
 	if (hdmi->version < 0x200a)
 		return false;
@@ -1282,12 +1281,13 @@ static bool dw_hdmi_support_scdc(struct dw_hdmi *hdmi)
  * helper should called right before enabling the TMDS Clock and Data in
  * the PHY configuration callback.
  */
-void dw_hdmi_set_high_tmds_clock_ratio(struct dw_hdmi *hdmi)
+void dw_hdmi_set_high_tmds_clock_ratio(struct dw_hdmi *hdmi,
+				       const struct drm_display_info *display)
 {
 	unsigned long mtmdsclock = hdmi->hdmi_data.video_mode.mtmdsclock;
 
 	/* Control for TMDS Bit Period/TMDS Clock-Period Ratio */
-	if (dw_hdmi_support_scdc(hdmi)) {
+	if (dw_hdmi_support_scdc(hdmi, display)) {
 		if (mtmdsclock > HDMI14_MAX_TMDSCLK)
 			drm_scdc_set_high_tmds_clock_ratio(hdmi->ddc, 1);
 		else
@@ -1490,7 +1490,8 @@ static int hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi *hdmi,
 	return 0;
 }
 
-static int hdmi_phy_configure(struct dw_hdmi *hdmi)
+static int hdmi_phy_configure(struct dw_hdmi *hdmi,
+			      const struct drm_display_info *display)
 {
 	const struct dw_hdmi_phy_data *phy = hdmi->phy.data;
 	const struct dw_hdmi_plat_data *pdata = hdmi->plat_data;
@@ -1500,7 +1501,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi)
 
 	dw_hdmi_phy_power_off(hdmi);
 
-	dw_hdmi_set_high_tmds_clock_ratio(hdmi);
+	dw_hdmi_set_high_tmds_clock_ratio(hdmi, display);
 
 	/* Leave low power consumption mode by asserting SVSRET. */
 	if (phy->has_svsret)
@@ -1531,6 +1532,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi)
 }
 
 static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
+			    const struct drm_display_info *display,
 			    const struct drm_display_mode *mode)
 {
 	int i, ret;
@@ -1540,7 +1542,7 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
 		dw_hdmi_phy_sel_data_en_pol(hdmi, 1);
 		dw_hdmi_phy_sel_interface_control(hdmi, 0);
 
-		ret = hdmi_phy_configure(hdmi);
+		ret = hdmi_phy_configure(hdmi, display);
 		if (ret)
 			return ret;
 	}
@@ -1846,10 +1848,11 @@ static void hdmi_config_drm_infoframe(struct dw_hdmi *hdmi)
 }
 
 static void hdmi_av_composer(struct dw_hdmi *hdmi,
+			     const struct drm_display_info *display,
 			     const struct drm_display_mode *mode)
 {
 	u8 inv_val, bytes;
-	struct drm_hdmi_info *hdmi_info = &hdmi->connector.display_info.hdmi;
+	const struct drm_hdmi_info *hdmi_info = &display->hdmi;
 	struct hdmi_vmode *vmode = &hdmi->hdmi_data.video_mode;
 	int hblank, vblank, h_de_hs, v_de_vs, hsync_len, vsync_len;
 	unsigned int vdisplay, hdisplay;
@@ -1882,7 +1885,7 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
 
 	/* Set up HDMI_FC_INVIDCONF */
 	inv_val = (hdmi->hdmi_data.hdcp_enable ||
-		   (dw_hdmi_support_scdc(hdmi) &&
+		   (dw_hdmi_support_scdc(hdmi, display) &&
 		    (vmode->mtmdsclock > HDMI14_MAX_TMDSCLK ||
 		     hdmi_info->scdc.scrambling.low_rates)) ?
 		HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE :
@@ -1950,7 +1953,7 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
 	}
 
 	/* Scrambling Control */
-	if (dw_hdmi_support_scdc(hdmi)) {
+	if (dw_hdmi_support_scdc(hdmi, display)) {
 		if (vmode->mtmdsclock > HDMI14_MAX_TMDSCLK ||
 		    hdmi_info->scdc.scrambling.low_rates) {
 			/*
@@ -2116,6 +2119,7 @@ static void hdmi_disable_overflow_interrupts(struct dw_hdmi *hdmi)
 static int dw_hdmi_setup(struct dw_hdmi *hdmi,
 			 const struct drm_display_mode *mode)
 {
+	struct drm_connector *connector = &hdmi->connector;
 	int ret;
 
 	hdmi_disable_overflow_interrupts(hdmi);
@@ -2161,10 +2165,12 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi,
 	hdmi->hdmi_data.video_mode.mdataenablepolarity = true;
 
 	/* HDMI Initialization Step B.1 */
-	hdmi_av_composer(hdmi, mode);
+	hdmi_av_composer(hdmi, &connector->display_info, mode);
 
 	/* HDMI Initializateion Step B.2 */
-	ret = hdmi->phy.ops->init(hdmi, hdmi->phy.data, &hdmi->previous_mode);
+	ret = hdmi->phy.ops->init(hdmi, hdmi->phy.data,
+				  &connector->display_info,
+				  &hdmi->previous_mode);
 	if (ret)
 		return ret;
 	hdmi->phy.enabled = true;
diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c
index 757c17fbb29f..15e62f327894 100644
--- a/drivers/gpu/drm/meson/meson_dw_hdmi.c
+++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c
@@ -427,6 +427,7 @@ static void dw_hdmi_set_vclk(struct meson_dw_hdmi *dw_hdmi,
 }
 
 static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
+			    const struct drm_display_info *display,
 			    const struct drm_display_mode *mode)
 {
 	struct meson_dw_hdmi *dw_hdmi = (struct meson_dw_hdmi *)data;
@@ -496,7 +497,7 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
 	/* Disable clock, fifo, fifo_wr */
 	regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, 0xf, 0);
 
-	dw_hdmi_set_high_tmds_clock_ratio(hdmi);
+	dw_hdmi_set_high_tmds_clock_ratio(hdmi, display);
 
 	msleep(100);
 
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index 10e210f6455d..23de359a1dec 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -312,6 +312,7 @@ static const struct drm_encoder_helper_funcs dw_hdmi_rockchip_encoder_helper_fun
 };
 
 static int dw_hdmi_rockchip_genphy_init(struct dw_hdmi *dw_hdmi, void *data,
+					const struct drm_display_info *display,
 					const struct drm_display_mode *mode)
 {
 	struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
index 8e078cacf063..156d00e5165b 100644
--- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
+++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
@@ -341,6 +341,7 @@ static int sun8i_hdmi_phy_config_h3(struct dw_hdmi *hdmi,
 }
 
 static int sun8i_hdmi_phy_config(struct dw_hdmi *hdmi, void *data,
+				 const struct drm_display_info *display,
 				 const struct drm_display_mode *mode)
 {
 	struct sun8i_hdmi_phy *phy = (struct sun8i_hdmi_phy *)data;
diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
index f930d218cc6b..ea34ca146b82 100644
--- a/include/drm/bridge/dw_hdmi.h
+++ b/include/drm/bridge/dw_hdmi.h
@@ -114,6 +114,7 @@ struct dw_hdmi_phy_config {
 
 struct dw_hdmi_phy_ops {
 	int (*init)(struct dw_hdmi *hdmi, void *data,
+		    const struct drm_display_info *display,
 		    const struct drm_display_mode *mode);
 	void (*disable)(struct dw_hdmi *hdmi, void *data);
 	enum drm_connector_status (*read_hpd)(struct dw_hdmi *hdmi, void *data);
@@ -174,7 +175,8 @@ void dw_hdmi_set_channel_status(struct dw_hdmi *hdmi, u8 *channel_status);
 void dw_hdmi_set_channel_allocation(struct dw_hdmi *hdmi, unsigned int ca);
 void dw_hdmi_audio_enable(struct dw_hdmi *hdmi);
 void dw_hdmi_audio_disable(struct dw_hdmi *hdmi);
-void dw_hdmi_set_high_tmds_clock_ratio(struct dw_hdmi *hdmi);
+void dw_hdmi_set_high_tmds_clock_ratio(struct dw_hdmi *hdmi,
+				       const struct drm_display_info *display);
 
 /* PHY configuration */
 void dw_hdmi_phy_i2c_set_addr(struct dw_hdmi *hdmi, u8 address);
-- 
Regards,

Laurent Pinchart


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

* [PATCH 19/27] drm: bridge: dw-hdmi: Split connector creation to a separate function
  2020-05-26  1:14 [PATCH 00/27] Converter R-Car DU to the DRM bridge connector helper Laurent Pinchart
                   ` (17 preceding siblings ...)
  2020-05-26  1:14 ` [PATCH 18/27] drm: bridge: dw-hdmi: Pass drm_display_info to dw_hdmi_support_scdc() Laurent Pinchart
@ 2020-05-26  1:14 ` Laurent Pinchart
  2020-05-26  9:49   ` Neil Armstrong
  2020-05-26  1:14 ` [PATCH 20/27] drm: bridge: dw-hdmi: Store current connector in struct dw_hdmi Laurent Pinchart
                   ` (8 subsequent siblings)
  27 siblings, 1 reply; 69+ messages in thread
From: Laurent Pinchart @ 2020-05-26  1:14 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-renesas-soc, Andrzej Hajda, Jernej Skrabec, Jonas Karlman,
	Neil Armstrong, Sam Ravnborg, Kieran Bingham

Isolate all the code related to connector creation to a new
dw_hdmi_connector_create() function, to prepare for making connector
creation optional.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 107 +++++++++++++---------
 1 file changed, 62 insertions(+), 45 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index a18794cce0d8..35d38b644912 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -2317,6 +2317,10 @@ static void dw_hdmi_update_phy_mask(struct dw_hdmi *hdmi)
 					  hdmi->rxsense);
 }
 
+/* -----------------------------------------------------------------------------
+ * DRM Connector Operations
+ */
+
 static enum drm_connector_status
 dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
 {
@@ -2438,6 +2442,59 @@ static const struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs =
 	.atomic_check = dw_hdmi_connector_atomic_check,
 };
 
+static int dw_hdmi_connector_create(struct dw_hdmi *hdmi)
+{
+	struct drm_connector *connector = &hdmi->connector;
+	struct cec_connector_info conn_info;
+	struct cec_notifier *notifier;
+
+	if (hdmi->version >= 0x200a)
+		connector->ycbcr_420_allowed =
+			hdmi->plat_data->ycbcr_420_allowed;
+	else
+		connector->ycbcr_420_allowed = false;
+
+	connector->interlace_allowed = 1;
+	connector->polled = DRM_CONNECTOR_POLL_HPD;
+
+	drm_connector_helper_add(connector, &dw_hdmi_connector_helper_funcs);
+
+	drm_connector_init_with_ddc(hdmi->bridge.dev, connector,
+				    &dw_hdmi_connector_funcs,
+				    DRM_MODE_CONNECTOR_HDMIA,
+				    hdmi->ddc);
+
+	/*
+	 * drm_connector_attach_max_bpc_property() requires the
+	 * connector to have a state.
+	 */
+	drm_atomic_helper_connector_reset(connector);
+
+	drm_connector_attach_max_bpc_property(connector, 8, 16);
+
+	if (hdmi->version >= 0x200a && hdmi->plat_data->use_drm_infoframe)
+		drm_object_attach_property(&connector->base,
+			connector->dev->mode_config.hdr_output_metadata_property, 0);
+
+	drm_connector_attach_encoder(connector, hdmi->bridge.encoder);
+
+	cec_fill_conn_info_from_drm(&conn_info, connector);
+
+	notifier = cec_notifier_conn_register(hdmi->dev, NULL, &conn_info);
+	if (!notifier)
+		return -ENOMEM;
+
+	mutex_lock(&hdmi->cec_notifier_mutex);
+	hdmi->cec_notifier = notifier;
+	mutex_unlock(&hdmi->cec_notifier_mutex);
+
+	return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * DRM Bridge Operations
+ */
+
 /*
  * Possible output formats :
  * - MEDIA_BUS_FMT_UYYVYY16_0_5X48,
@@ -2713,51 +2770,13 @@ static int dw_hdmi_bridge_attach(struct drm_bridge *bridge,
 				 enum drm_bridge_attach_flags flags)
 {
 	struct dw_hdmi *hdmi = bridge->driver_private;
-	struct drm_encoder *encoder = bridge->encoder;
-	struct drm_connector *connector = &hdmi->connector;
-	struct cec_connector_info conn_info;
-	struct cec_notifier *notifier;
 
 	if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {
 		DRM_ERROR("Fix bridge driver to make connector optional!");
 		return -EINVAL;
 	}
 
-	connector->interlace_allowed = 1;
-	connector->polled = DRM_CONNECTOR_POLL_HPD;
-
-	drm_connector_helper_add(connector, &dw_hdmi_connector_helper_funcs);
-
-	drm_connector_init_with_ddc(bridge->dev, connector,
-				    &dw_hdmi_connector_funcs,
-				    DRM_MODE_CONNECTOR_HDMIA,
-				    hdmi->ddc);
-
-	/*
-	 * drm_connector_attach_max_bpc_property() requires the
-	 * connector to have a state.
-	 */
-	drm_atomic_helper_connector_reset(connector);
-
-	drm_connector_attach_max_bpc_property(connector, 8, 16);
-
-	if (hdmi->version >= 0x200a && hdmi->plat_data->use_drm_infoframe)
-		drm_object_attach_property(&connector->base,
-			connector->dev->mode_config.hdr_output_metadata_property, 0);
-
-	drm_connector_attach_encoder(connector, encoder);
-
-	cec_fill_conn_info_from_drm(&conn_info, connector);
-
-	notifier = cec_notifier_conn_register(hdmi->dev, NULL, &conn_info);
-	if (!notifier)
-		return -ENOMEM;
-
-	mutex_lock(&hdmi->cec_notifier_mutex);
-	hdmi->cec_notifier = notifier;
-	mutex_unlock(&hdmi->cec_notifier_mutex);
-
-	return 0;
+	return dw_hdmi_connector_create(hdmi);
 }
 
 static void dw_hdmi_bridge_detach(struct drm_bridge *bridge)
@@ -2841,6 +2860,10 @@ static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = {
 	.mode_valid = dw_hdmi_bridge_mode_valid,
 };
 
+/* -----------------------------------------------------------------------------
+ * IRQ Handling
+ */
+
 static irqreturn_t dw_hdmi_i2c_irq(struct dw_hdmi *hdmi)
 {
 	struct dw_hdmi_i2c *i2c = hdmi->i2c;
@@ -3303,12 +3326,6 @@ __dw_hdmi_probe(struct platform_device *pdev,
 	hdmi->bridge.of_node = pdev->dev.of_node;
 #endif
 
-	if (hdmi->version >= 0x200a)
-		hdmi->connector.ycbcr_420_allowed =
-			hdmi->plat_data->ycbcr_420_allowed;
-	else
-		hdmi->connector.ycbcr_420_allowed = false;
-
 	memset(&pdevinfo, 0, sizeof(pdevinfo));
 	pdevinfo.parent = dev;
 	pdevinfo.id = PLATFORM_DEVID_AUTO;
-- 
Regards,

Laurent Pinchart


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

* [PATCH 20/27] drm: bridge: dw-hdmi: Store current connector in struct dw_hdmi
  2020-05-26  1:14 [PATCH 00/27] Converter R-Car DU to the DRM bridge connector helper Laurent Pinchart
                   ` (18 preceding siblings ...)
  2020-05-26  1:14 ` [PATCH 19/27] drm: bridge: dw-hdmi: Split connector creation to a separate function Laurent Pinchart
@ 2020-05-26  1:14 ` Laurent Pinchart
  2020-05-26 12:29   ` Neil Armstrong
  2020-05-26  1:14 ` [PATCH 21/27] drm: bridge: dw-hdmi: Pass drm_connector to internal functions as needed Laurent Pinchart
                   ` (7 subsequent siblings)
  27 siblings, 1 reply; 69+ messages in thread
From: Laurent Pinchart @ 2020-05-26  1:14 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-renesas-soc, Andrzej Hajda, Jernej Skrabec, Jonas Karlman,
	Neil Armstrong, Sam Ravnborg, Kieran Bingham

Store the connector that the bridge is currently wired to in the dw_hdmi
structure. This is currently identical to the connector field, but will
differ once the driver supports disabling connector creation.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 35d38b644912..16bffedb4715 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -181,6 +181,7 @@ struct dw_hdmi {
 
 	struct mutex mutex;		/* for state below and previous_mode */
 	enum drm_connector_force force;	/* mutex-protected force state */
+	struct drm_connector *curr_conn;/* current connector (only valid when !disabled) */
 	bool disabled;			/* DRM has disabled our bridge */
 	bool bridge_is_on;		/* indicates the bridge is on */
 	bool rxsense;			/* rxsense state */
@@ -2823,23 +2824,32 @@ static void dw_hdmi_bridge_mode_set(struct drm_bridge *bridge,
 	mutex_unlock(&hdmi->mutex);
 }
 
-static void dw_hdmi_bridge_disable(struct drm_bridge *bridge)
+static void dw_hdmi_bridge_atomic_disable(struct drm_bridge *bridge,
+					  struct drm_bridge_state *old_state)
 {
 	struct dw_hdmi *hdmi = bridge->driver_private;
 
 	mutex_lock(&hdmi->mutex);
 	hdmi->disabled = true;
+	hdmi->curr_conn = NULL;
 	dw_hdmi_update_power(hdmi);
 	dw_hdmi_update_phy_mask(hdmi);
 	mutex_unlock(&hdmi->mutex);
 }
 
-static void dw_hdmi_bridge_enable(struct drm_bridge *bridge)
+static void dw_hdmi_bridge_atomic_enable(struct drm_bridge *bridge,
+					 struct drm_bridge_state *old_state)
 {
 	struct dw_hdmi *hdmi = bridge->driver_private;
+	struct drm_atomic_state *state = old_state->base.state;
+	struct drm_connector *connector;
+
+	connector = drm_atomic_get_new_connector_for_encoder(state,
+							     bridge->encoder);
 
 	mutex_lock(&hdmi->mutex);
 	hdmi->disabled = false;
+	hdmi->curr_conn = connector;
 	dw_hdmi_update_power(hdmi);
 	dw_hdmi_update_phy_mask(hdmi);
 	mutex_unlock(&hdmi->mutex);
@@ -2854,8 +2864,8 @@ static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = {
 	.atomic_check = dw_hdmi_bridge_atomic_check,
 	.atomic_get_output_bus_fmts = dw_hdmi_bridge_atomic_get_output_bus_fmts,
 	.atomic_get_input_bus_fmts = dw_hdmi_bridge_atomic_get_input_bus_fmts,
-	.enable = dw_hdmi_bridge_enable,
-	.disable = dw_hdmi_bridge_disable,
+	.atomic_enable = dw_hdmi_bridge_atomic_enable,
+	.atomic_disable = dw_hdmi_bridge_atomic_disable,
 	.mode_set = dw_hdmi_bridge_mode_set,
 	.mode_valid = dw_hdmi_bridge_mode_valid,
 };
-- 
Regards,

Laurent Pinchart


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

* [PATCH 21/27] drm: bridge: dw-hdmi: Pass drm_connector to internal functions as needed
  2020-05-26  1:14 [PATCH 00/27] Converter R-Car DU to the DRM bridge connector helper Laurent Pinchart
                   ` (19 preceding siblings ...)
  2020-05-26  1:14 ` [PATCH 20/27] drm: bridge: dw-hdmi: Store current connector in struct dw_hdmi Laurent Pinchart
@ 2020-05-26  1:14 ` Laurent Pinchart
  2020-05-26 12:29   ` Neil Armstrong
  2020-05-26  1:15 ` [PATCH 22/27] drm: bridge: dw-hdmi: Make connector creation optional Laurent Pinchart
                   ` (6 subsequent siblings)
  27 siblings, 1 reply; 69+ messages in thread
From: Laurent Pinchart @ 2020-05-26  1:14 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-renesas-soc, Andrzej Hajda, Jernej Skrabec, Jonas Karlman,
	Neil Armstrong, Sam Ravnborg, Kieran Bingham

To prepare for making connector creation optional in the driver, pass
the drm_connector explicitly to the internal functions that require it.
The functions that still access the connector from the dw_hdmi structure
are dw_hdmi_connector_create() and __dw_hdmi_probe(). The former access
is expected, as that's where the internal connector is created. The
latter will be addressed separately.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 31 +++++++++++++----------
 1 file changed, 18 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 16bffedb4715..b69c14b9de62 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -1632,18 +1632,17 @@ static void hdmi_tx_hdcp_config(struct dw_hdmi *hdmi)
 }
 
 static void hdmi_config_AVI(struct dw_hdmi *hdmi,
+			    const struct drm_connector *connector,
 			    const struct drm_display_mode *mode)
 {
 	struct hdmi_avi_infoframe frame;
 	u8 val;
 
 	/* Initialise info frame from DRM mode */
-	drm_hdmi_avi_infoframe_from_display_mode(&frame,
-						 &hdmi->connector, mode);
+	drm_hdmi_avi_infoframe_from_display_mode(&frame, connector, mode);
 
 	if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format)) {
-		drm_hdmi_avi_infoframe_quant_range(&frame, &hdmi->connector,
-						   mode,
+		drm_hdmi_avi_infoframe_quant_range(&frame, connector, mode,
 						   hdmi->hdmi_data.rgb_limited_range ?
 						   HDMI_QUANTIZATION_RANGE_LIMITED :
 						   HDMI_QUANTIZATION_RANGE_FULL);
@@ -1760,14 +1759,14 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi,
 }
 
 static void hdmi_config_vendor_specific_infoframe(struct dw_hdmi *hdmi,
+						  const struct drm_connector *connector,
 						  const struct drm_display_mode *mode)
 {
 	struct hdmi_vendor_infoframe frame;
 	u8 buffer[10];
 	ssize_t err;
 
-	err = drm_hdmi_vendor_infoframe_from_display_mode(&frame,
-							  &hdmi->connector,
+	err = drm_hdmi_vendor_infoframe_from_display_mode(&frame, connector,
 							  mode);
 	if (err < 0)
 		/*
@@ -1813,9 +1812,10 @@ static void hdmi_config_vendor_specific_infoframe(struct dw_hdmi *hdmi,
 			HDMI_FC_DATAUTO0_VSD_MASK);
 }
 
-static void hdmi_config_drm_infoframe(struct dw_hdmi *hdmi)
+static void hdmi_config_drm_infoframe(struct dw_hdmi *hdmi,
+				      const struct drm_connector *connector)
 {
-	const struct drm_connector_state *conn_state = hdmi->connector.state;
+	const struct drm_connector_state *conn_state = connector->state;
 	struct hdmi_drm_infoframe frame;
 	u8 buffer[30];
 	ssize_t err;
@@ -2118,9 +2118,9 @@ static void hdmi_disable_overflow_interrupts(struct dw_hdmi *hdmi)
 }
 
 static int dw_hdmi_setup(struct dw_hdmi *hdmi,
+			 const struct drm_connector *connector,
 			 const struct drm_display_mode *mode)
 {
-	struct drm_connector *connector = &hdmi->connector;
 	int ret;
 
 	hdmi_disable_overflow_interrupts(hdmi);
@@ -2192,9 +2192,9 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi,
 		dev_dbg(hdmi->dev, "%s HDMI mode\n", __func__);
 
 		/* HDMI Initialization Step F - Configure AVI InfoFrame */
-		hdmi_config_AVI(hdmi, mode);
-		hdmi_config_vendor_specific_infoframe(hdmi, mode);
-		hdmi_config_drm_infoframe(hdmi);
+		hdmi_config_AVI(hdmi, connector, mode);
+		hdmi_config_vendor_specific_infoframe(hdmi, connector, mode);
+		hdmi_config_drm_infoframe(hdmi, connector);
 	} else {
 		dev_dbg(hdmi->dev, "%s DVI mode\n", __func__);
 	}
@@ -2263,7 +2263,12 @@ static void initialize_hdmi_ih_mutes(struct dw_hdmi *hdmi)
 static void dw_hdmi_poweron(struct dw_hdmi *hdmi)
 {
 	hdmi->bridge_is_on = true;
-	dw_hdmi_setup(hdmi, &hdmi->previous_mode);
+
+	/*
+	 * The curr_conn field is guaranteed to be valid here, as this function
+	 * is only be called when !hdmi->disabled.
+	 */
+	dw_hdmi_setup(hdmi, hdmi->curr_conn, &hdmi->previous_mode);
 }
 
 static void dw_hdmi_poweroff(struct dw_hdmi *hdmi)
-- 
Regards,

Laurent Pinchart


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

* [PATCH 22/27] drm: bridge: dw-hdmi: Make connector creation optional
  2020-05-26  1:14 [PATCH 00/27] Converter R-Car DU to the DRM bridge connector helper Laurent Pinchart
                   ` (20 preceding siblings ...)
  2020-05-26  1:14 ` [PATCH 21/27] drm: bridge: dw-hdmi: Pass drm_connector to internal functions as needed Laurent Pinchart
@ 2020-05-26  1:15 ` Laurent Pinchart
  2020-05-26 12:35   ` Neil Armstrong
  2020-05-26  1:15 ` [PATCH 23/27] drm: bridge: dw-hdmi: Attach to next bridge if available Laurent Pinchart
                   ` (5 subsequent siblings)
  27 siblings, 1 reply; 69+ messages in thread
From: Laurent Pinchart @ 2020-05-26  1:15 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-renesas-soc, Andrzej Hajda, Jernej Skrabec, Jonas Karlman,
	Neil Armstrong, Sam Ravnborg, Kieran Bingham

Implement the drm_bridge_funcs .detect() and .get_edid() operations, and
call drm_bridge_hpd_notify() notify to report HPD. This provides the
necessary API to support disabling connector creation, do so by
accepting DRM_BRIDGE_ATTACH_NO_CONNECTOR in dw_hdmi_bridge_attach().

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 104 +++++++++++++++-------
 1 file changed, 74 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index b69c14b9de62..6148a022569a 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -2323,15 +2323,8 @@ static void dw_hdmi_update_phy_mask(struct dw_hdmi *hdmi)
 					  hdmi->rxsense);
 }
 
-/* -----------------------------------------------------------------------------
- * DRM Connector Operations
- */
-
-static enum drm_connector_status
-dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
+static enum drm_connector_status dw_hdmi_detect(struct dw_hdmi *hdmi)
 {
-	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
-					     connector);
 	enum drm_connector_status result;
 
 	mutex_lock(&hdmi->mutex);
@@ -2354,31 +2347,57 @@ dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
 	return result;
 }
 
-static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
+static struct edid *dw_hdmi_get_edid(struct dw_hdmi *hdmi,
+				     struct drm_connector *connector)
 {
-	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
-					     connector);
 	struct edid *edid;
-	int ret = 0;
 
 	if (!hdmi->ddc)
-		return 0;
+		return NULL;
 
 	edid = drm_get_edid(connector, hdmi->ddc);
-	if (edid) {
-		dev_dbg(hdmi->dev, "got edid: width[%d] x height[%d]\n",
-			edid->width_cm, edid->height_cm);
-
-		hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid);
-		hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
-		drm_connector_update_edid_property(connector, edid);
-		cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid);
-		ret = drm_add_edid_modes(connector, edid);
-		kfree(edid);
-	} else {
+	if (!edid) {
 		dev_dbg(hdmi->dev, "failed to get edid\n");
+		return NULL;
 	}
 
+	dev_dbg(hdmi->dev, "got edid: width[%d] x height[%d]\n",
+		edid->width_cm, edid->height_cm);
+
+	hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid);
+	hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
+
+	return edid;
+}
+
+/* -----------------------------------------------------------------------------
+ * DRM Connector Operations
+ */
+
+static enum drm_connector_status
+dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
+{
+	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
+					     connector);
+	return dw_hdmi_detect(hdmi);
+}
+
+static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
+{
+	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
+					     connector);
+	struct edid *edid;
+	int ret;
+
+	edid = dw_hdmi_get_edid(hdmi, connector);
+	if (!edid)
+		return 0;
+
+	drm_connector_update_edid_property(connector, edid);
+	cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid);
+	ret = drm_add_edid_modes(connector, edid);
+	kfree(edid);
+
 	return ret;
 }
 
@@ -2777,10 +2796,8 @@ static int dw_hdmi_bridge_attach(struct drm_bridge *bridge,
 {
 	struct dw_hdmi *hdmi = bridge->driver_private;
 
-	if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {
-		DRM_ERROR("Fix bridge driver to make connector optional!");
-		return -EINVAL;
-	}
+	if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
+		return 0;
 
 	return dw_hdmi_connector_create(hdmi);
 }
@@ -2860,6 +2877,21 @@ static void dw_hdmi_bridge_atomic_enable(struct drm_bridge *bridge,
 	mutex_unlock(&hdmi->mutex);
 }
 
+static enum drm_connector_status dw_hdmi_bridge_detect(struct drm_bridge *bridge)
+{
+	struct dw_hdmi *hdmi = bridge->driver_private;
+
+	return dw_hdmi_detect(hdmi);
+}
+
+static struct edid *dw_hdmi_bridge_get_edid(struct drm_bridge *bridge,
+					    struct drm_connector *connector)
+{
+	struct dw_hdmi *hdmi = bridge->driver_private;
+
+	return dw_hdmi_get_edid(hdmi, connector);
+}
+
 static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = {
 	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
 	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
@@ -2873,6 +2905,8 @@ static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = {
 	.atomic_disable = dw_hdmi_bridge_atomic_disable,
 	.mode_set = dw_hdmi_bridge_mode_set,
 	.mode_valid = dw_hdmi_bridge_mode_valid,
+	.detect = dw_hdmi_bridge_detect,
+	.get_edid = dw_hdmi_bridge_get_edid,
 };
 
 /* -----------------------------------------------------------------------------
@@ -2988,10 +3022,18 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
 	}
 
 	if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
+		enum drm_connector_status status = phy_int_pol & HDMI_PHY_HPD
+						 ? connector_status_connected
+						 : connector_status_disconnected;
+
 		dev_dbg(hdmi->dev, "EVENT=%s\n",
-			phy_int_pol & HDMI_PHY_HPD ? "plugin" : "plugout");
-		if (hdmi->bridge.dev)
+			status == connector_status_connected ?
+			"plugin" : "plugout");
+
+		if (hdmi->bridge.dev) {
 			drm_helper_hpd_irq_event(hdmi->bridge.dev);
+			drm_bridge_hpd_notify(&hdmi->bridge, status);
+		}
 	}
 
 	hdmi_writeb(hdmi, intr_stat, HDMI_IH_PHY_STAT0);
@@ -3337,6 +3379,8 @@ __dw_hdmi_probe(struct platform_device *pdev,
 
 	hdmi->bridge.driver_private = hdmi;
 	hdmi->bridge.funcs = &dw_hdmi_bridge_funcs;
+	hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID
+			 | DRM_BRIDGE_OP_HPD;
 #ifdef CONFIG_OF
 	hdmi->bridge.of_node = pdev->dev.of_node;
 #endif
-- 
Regards,

Laurent Pinchart


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

* [PATCH 23/27] drm: bridge: dw-hdmi: Attach to next bridge if available
  2020-05-26  1:14 [PATCH 00/27] Converter R-Car DU to the DRM bridge connector helper Laurent Pinchart
                   ` (21 preceding siblings ...)
  2020-05-26  1:15 ` [PATCH 22/27] drm: bridge: dw-hdmi: Make connector creation optional Laurent Pinchart
@ 2020-05-26  1:15 ` Laurent Pinchart
  2020-05-26 12:50   ` Neil Armstrong
  2020-05-26  1:15 ` [PATCH 24/27] drm: rcar-du: dw-hdmi: Set output port number Laurent Pinchart
                   ` (4 subsequent siblings)
  27 siblings, 1 reply; 69+ messages in thread
From: Laurent Pinchart @ 2020-05-26  1:15 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-renesas-soc, Andrzej Hajda, Jernej Skrabec, Jonas Karlman,
	Neil Armstrong, Sam Ravnborg, Kieran Bingham

On all platforms except i.MX and Rockchip, the dw-hdmi DT bindings
require a video output port connected to an HDMI sink (most likely an
HDMI connector, in rare cases another bridges converting HDMI to another
protocol). For those platforms, retrieve the next bridge and attach it
from the dw-hdmi bridge attach handler.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 52 ++++++++++++++++++++++-
 include/drm/bridge/dw_hdmi.h              |  2 +
 2 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 6148a022569a..512e67bb1c32 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -143,6 +143,7 @@ struct dw_hdmi_phy_data {
 struct dw_hdmi {
 	struct drm_connector connector;
 	struct drm_bridge bridge;
+	struct drm_bridge *next_bridge;
 
 	unsigned int version;
 
@@ -2797,7 +2798,8 @@ static int dw_hdmi_bridge_attach(struct drm_bridge *bridge,
 	struct dw_hdmi *hdmi = bridge->driver_private;
 
 	if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
-		return 0;
+		return drm_bridge_attach(bridge->encoder, hdmi->next_bridge,
+					 bridge, flags);
 
 	return dw_hdmi_connector_create(hdmi);
 }
@@ -3179,6 +3181,50 @@ static void dw_hdmi_init_hw(struct dw_hdmi *hdmi)
 		hdmi->phy.ops->setup_hpd(hdmi, hdmi->phy.data);
 }
 
+static int dw_hdmi_parse_dt(struct dw_hdmi *hdmi)
+{
+	struct device_node *endpoint;
+	struct device_node *remote;
+
+	if (!hdmi->plat_data->output_port)
+		return 0;
+
+	endpoint = of_graph_get_endpoint_by_regs(hdmi->dev->of_node,
+						 hdmi->plat_data->output_port,
+						 -1);
+	if (!endpoint) {
+		/*
+		 * Don't treat this as a fatal error as the Rockchip DW-HDMI
+		 * binding doesn't make the output port mandatory.
+		 */
+		dev_dbg(hdmi->dev, "Missing endpoint in port@%u\n",
+			hdmi->plat_data->output_port);
+		return 0;
+	}
+
+	remote = of_graph_get_remote_port_parent(endpoint);
+	of_node_put(endpoint);
+	if (!remote) {
+		dev_err(hdmi->dev, "Endpoint in port@%u unconnected\n",
+			hdmi->plat_data->output_port);
+		return -ENODEV;
+	}
+
+	if (!of_device_is_available(remote)) {
+		dev_err(hdmi->dev, "port@%u remote device is disabled\n",
+			hdmi->plat_data->output_port);
+		of_node_put(remote);
+		return -ENODEV;
+	}
+
+	hdmi->next_bridge = of_drm_find_bridge(remote);
+	of_node_put(remote);
+	if (!hdmi->next_bridge)
+		return -EPROBE_DEFER;
+
+	return 0;
+}
+
 static struct dw_hdmi *
 __dw_hdmi_probe(struct platform_device *pdev,
 		const struct dw_hdmi_plat_data *plat_data)
@@ -3216,6 +3262,10 @@ __dw_hdmi_probe(struct platform_device *pdev,
 	mutex_init(&hdmi->cec_notifier_mutex);
 	spin_lock_init(&hdmi->audio_lock);
 
+	ret = dw_hdmi_parse_dt(hdmi);
+	if (ret < 0)
+		return ERR_PTR(ret);
+
 	ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0);
 	if (ddc_node) {
 		hdmi->ddc = of_get_i2c_adapter_by_node(ddc_node);
diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
index ea34ca146b82..8ebeb65d6371 100644
--- a/include/drm/bridge/dw_hdmi.h
+++ b/include/drm/bridge/dw_hdmi.h
@@ -126,6 +126,8 @@ struct dw_hdmi_phy_ops {
 struct dw_hdmi_plat_data {
 	struct regmap *regm;
 
+	unsigned int output_port;
+
 	unsigned long input_bus_encoding;
 	bool use_drm_infoframe;
 	bool ycbcr_420_allowed;
-- 
Regards,

Laurent Pinchart


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

* [PATCH 24/27] drm: rcar-du: dw-hdmi: Set output port number
  2020-05-26  1:14 [PATCH 00/27] Converter R-Car DU to the DRM bridge connector helper Laurent Pinchart
                   ` (22 preceding siblings ...)
  2020-05-26  1:15 ` [PATCH 23/27] drm: bridge: dw-hdmi: Attach to next bridge if available Laurent Pinchart
@ 2020-05-26  1:15 ` Laurent Pinchart
  2020-05-26  1:15 ` [PATCH 25/27] drm: rcar-du: Fix error handling in rcar_du_encoder_init() Laurent Pinchart
                   ` (3 subsequent siblings)
  27 siblings, 0 replies; 69+ messages in thread
From: Laurent Pinchart @ 2020-05-26  1:15 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-renesas-soc, Andrzej Hajda, Jernej Skrabec, Jonas Karlman,
	Neil Armstrong, Sam Ravnborg, Kieran Bingham

Report the DT output port number in dw_hdmi_plat_data to connect to the
next bridge in the dw-hdmi driver.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c b/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c
index 7b8ec8310699..18ed14911b98 100644
--- a/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c
+++ b/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c
@@ -75,6 +75,7 @@ static int rcar_hdmi_phy_configure(struct dw_hdmi *hdmi, void *data,
 }
 
 static const struct dw_hdmi_plat_data rcar_dw_hdmi_plat_data = {
+	.output_port = 1,
 	.mode_valid = rcar_hdmi_mode_valid,
 	.configure_phy	= rcar_hdmi_phy_configure,
 };
-- 
Regards,

Laurent Pinchart


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

* [PATCH 25/27] drm: rcar-du: Fix error handling in rcar_du_encoder_init()
  2020-05-26  1:14 [PATCH 00/27] Converter R-Car DU to the DRM bridge connector helper Laurent Pinchart
                   ` (23 preceding siblings ...)
  2020-05-26  1:15 ` [PATCH 24/27] drm: rcar-du: dw-hdmi: Set output port number Laurent Pinchart
@ 2020-05-26  1:15 ` Laurent Pinchart
  2020-05-26  1:15 ` [PATCH 26/27] drm: rcar-du: Use drm_bridge_connector_init() helper Laurent Pinchart
                   ` (2 subsequent siblings)
  27 siblings, 0 replies; 69+ messages in thread
From: Laurent Pinchart @ 2020-05-26  1:15 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-renesas-soc, Andrzej Hajda, Jernej Skrabec, Jonas Karlman,
	Neil Armstrong, Sam Ravnborg, Kieran Bingham

When attaching the bridge returns an error, the rcar_du_encoder_init()
function calls drm_encoder_cleanup() manually instead of jumping to the
error handling path that frees memory. Fix it.

Fixes: c6a27fa41fab ("drm: rcar-du: Convert LVDS encoder code to bridge driver")
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/gpu/drm/rcar-du/rcar_du_encoder.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
index b0335da0c161..72bf6e2c7933 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
@@ -115,8 +115,9 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu,
 	 */
 	ret = drm_bridge_attach(encoder, bridge, NULL, 0);
 	if (ret) {
-		drm_encoder_cleanup(encoder);
-		return ret;
+		dev_err(rcdu->dev, "failed to attach bridge for output %u\n",
+			output);
+		goto done;
 	}
 
 done:
-- 
Regards,

Laurent Pinchart


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

* [PATCH 26/27] drm: rcar-du: Use drm_bridge_connector_init() helper
  2020-05-26  1:14 [PATCH 00/27] Converter R-Car DU to the DRM bridge connector helper Laurent Pinchart
                   ` (24 preceding siblings ...)
  2020-05-26  1:15 ` [PATCH 25/27] drm: rcar-du: Fix error handling in rcar_du_encoder_init() Laurent Pinchart
@ 2020-05-26  1:15 ` Laurent Pinchart
  2020-05-26  1:15 ` [PATCH 27/27] drm: Add default modes for connectors in unknown state Laurent Pinchart
  2020-06-23 18:55 ` [PATCH 00/27] Converter R-Car DU to the DRM bridge connector helper Sam Ravnborg
  27 siblings, 0 replies; 69+ messages in thread
From: Laurent Pinchart @ 2020-05-26  1:15 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-renesas-soc, Andrzej Hajda, Jernej Skrabec, Jonas Karlman,
	Neil Armstrong, Sam Ravnborg, Kieran Bingham

Use the drm_bridge_connector_init() helper to create a drm_connector for
each output, instead of relying on the bridge drivers doing so. Attach
the bridges with the DRM_BRIDGE_ATTACH_NO_CONNECTOR flag to instruct
them not to create a connector.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/gpu/drm/rcar-du/rcar_du_encoder.c | 21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
index 72bf6e2c7933..f6981e6444bc 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
@@ -10,6 +10,7 @@
 #include <linux/export.h>
 
 #include <drm/drm_bridge.h>
+#include <drm/drm_bridge_connector.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_modeset_helper_vtables.h>
 #include <drm/drm_panel.h>
@@ -49,6 +50,7 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu,
 			 struct device_node *enc_node)
 {
 	struct rcar_du_encoder *renc;
+	struct drm_connector *connector;
 	struct drm_encoder *encoder;
 	struct drm_bridge *bridge;
 	int ret;
@@ -109,17 +111,26 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu,
 	if (ret < 0)
 		goto done;
 
-	/*
-	 * Attach the bridge to the encoder. The bridge will create the
-	 * connector.
-	 */
-	ret = drm_bridge_attach(encoder, bridge, NULL, 0);
+	/* Attach the bridge to the encoder. */
+	ret = drm_bridge_attach(encoder, bridge, NULL,
+				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
 	if (ret) {
 		dev_err(rcdu->dev, "failed to attach bridge for output %u\n",
 			output);
 		goto done;
 	}
 
+	/* Create the connector for the chain of bridges. */
+	connector = drm_bridge_connector_init(rcdu->ddev, encoder);
+	if (IS_ERR(connector)) {
+		dev_err(rcdu->dev,
+			"failed to created connector for output %u\n", output);
+		ret = PTR_ERR(connector);
+		goto done;
+	}
+
+	ret = drm_connector_attach_encoder(connector, encoder);
+
 done:
 	if (ret < 0) {
 		if (encoder->name)
-- 
Regards,

Laurent Pinchart


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

* [PATCH 27/27] drm: Add default modes for connectors in unknown state
  2020-05-26  1:14 [PATCH 00/27] Converter R-Car DU to the DRM bridge connector helper Laurent Pinchart
                   ` (25 preceding siblings ...)
  2020-05-26  1:15 ` [PATCH 26/27] drm: rcar-du: Use drm_bridge_connector_init() helper Laurent Pinchart
@ 2020-05-26  1:15 ` Laurent Pinchart
  2020-06-21  8:40   ` Sam Ravnborg
  2020-06-23 18:55 ` [PATCH 00/27] Converter R-Car DU to the DRM bridge connector helper Sam Ravnborg
  27 siblings, 1 reply; 69+ messages in thread
From: Laurent Pinchart @ 2020-05-26  1:15 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-renesas-soc, Andrzej Hajda, Jernej Skrabec, Jonas Karlman,
	Neil Armstrong, Sam Ravnborg, Kieran Bingham, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Daniel Vetter

The DRM CRTC helpers add default modes to connectors in the connected
state if no mode can be retrieved from the connector. This behaviour is
useful for VGA or DVI outputs that have no connected DDC bus. However,
in such cases, the status of the output usually can't be retrieved and
is reported as connector_status_unknown.

Extend the addition of default modes to connectors in an unknown state
to support outputs that can retrieve neither the modes nor the
connection status.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/gpu/drm/drm_probe_helper.c       | 3 ++-
 include/drm/drm_modeset_helper_vtables.h | 8 +++++++-
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
index f5d141e0400f..9055d9573c90 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -491,7 +491,8 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
 	if (count == 0 && connector->status == connector_status_connected)
 		count = drm_add_override_edid_modes(connector);
 
-	if (count == 0 && connector->status == connector_status_connected)
+	if (count == 0 && (connector->status == connector_status_connected ||
+			   connector->status == connector_status_unknown))
 		count = drm_add_modes_noedid(connector, 1024, 768);
 	count += drm_helper_probe_add_cmdline_mode(connector);
 	if (count == 0)
diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
index 421a30f08463..afe55e2e93d2 100644
--- a/include/drm/drm_modeset_helper_vtables.h
+++ b/include/drm/drm_modeset_helper_vtables.h
@@ -876,13 +876,19 @@ struct drm_connector_helper_funcs {
 	 * The usual way to implement this is to cache the EDID retrieved in the
 	 * probe callback somewhere in the driver-private connector structure.
 	 * In this function drivers then parse the modes in the EDID and add
-	 * them by calling drm_add_edid_modes(). But connectors that driver a
+	 * them by calling drm_add_edid_modes(). But connectors that drive a
 	 * fixed panel can also manually add specific modes using
 	 * drm_mode_probed_add(). Drivers which manually add modes should also
 	 * make sure that the &drm_connector.display_info,
 	 * &drm_connector.width_mm and &drm_connector.height_mm fields are
 	 * filled in.
 	 *
+	 * Note that the caller function will automatically add standard VESA
+	 * DMT modes up to 1024x768 if the .get_modes() helper operation returns
+	 * no mode and if the connector status is connector_status_connected or
+	 * connector_status_unknown. There is no need to call
+	 * drm_add_edid_modes() manually in that case.
+	 *
 	 * Virtual drivers that just want some standard VESA mode with a given
 	 * resolution can call drm_add_modes_noedid(), and mark the preferred
 	 * one using drm_set_preferred_mode().
-- 
Regards,

Laurent Pinchart


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

* Re: [PATCH 11/27] drm: bridge: dw-hdmi: Pass private data pointer to .mode_valid()
  2020-05-26  1:14 ` [PATCH 11/27] drm: bridge: dw-hdmi: Pass private data pointer to .mode_valid() Laurent Pinchart
@ 2020-05-26  9:44   ` Neil Armstrong
  0 siblings, 0 replies; 69+ messages in thread
From: Neil Armstrong @ 2020-05-26  9:44 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: linux-renesas-soc, Andrzej Hajda, Jernej Skrabec, Jonas Karlman,
	Sam Ravnborg, Kieran Bingham, Philipp Zabel, Sandy Huang,
	Heiko Stübner, Maxime Ripard, Chen-Yu Tsai, linux-amlogic

On 26/05/2020 03:14, Laurent Pinchart wrote:
> Platform glue drivers for dw_hdmi may need to access device-specific
> data from their .mode_valid() implementation. They currently have no
> clean way to do so, and one driver hacks around it by accessing the
> dev_private data of the drm_device retrieved from the connector.
> 
> Add a priv_data void pointer to the dw_hdmi_plat_data structure, and
> pass it to the .mode_valid() function.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c   |  6 ++++--
>  drivers/gpu/drm/imx/dw_hdmi-imx.c           |  6 ++++--
>  drivers/gpu/drm/meson/meson_dw_hdmi.c       |  3 ++-
>  drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c      |  3 ++-
>  drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c |  3 ++-
>  drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c       |  6 ++++--
>  drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h       |  3 ++-
>  include/drm/bridge/dw_hdmi.h                | 14 ++++++++++++--
>  8 files changed, 32 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index b535354150db..2b3f203cf467 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -2771,6 +2771,7 @@ dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
>  			  const struct drm_display_mode *mode)
>  {
>  	struct dw_hdmi *hdmi = bridge->driver_private;
> +	const struct dw_hdmi_plat_data *pdata = hdmi->plat_data;
>  	struct drm_connector *connector = &hdmi->connector;
>  	enum drm_mode_status mode_status = MODE_OK;
>  
> @@ -2778,8 +2779,9 @@ dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
>  	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
>  		return MODE_BAD;
>  
> -	if (hdmi->plat_data->mode_valid)
> -		mode_status = hdmi->plat_data->mode_valid(connector, mode);
> +	if (pdata->mode_valid)
> +		mode_status = pdata->mode_valid(hdmi, pdata->priv_data,
> +						connector, mode);
>  
>  	return mode_status;
>  }
> diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c b/drivers/gpu/drm/imx/dw_hdmi-imx.c
> index ba4ca17fd4d8..95aed4666c95 100644
> --- a/drivers/gpu/drm/imx/dw_hdmi-imx.c
> +++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c
> @@ -145,7 +145,8 @@ static const struct drm_encoder_helper_funcs dw_hdmi_imx_encoder_helper_funcs =
>  };
>  
>  static enum drm_mode_status
> -imx6q_hdmi_mode_valid(struct drm_connector *con,
> +imx6q_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data,
> +		      struct drm_connector *con,
>  		      const struct drm_display_mode *mode)
>  {
>  	if (mode->clock < 13500)
> @@ -158,7 +159,8 @@ imx6q_hdmi_mode_valid(struct drm_connector *con,
>  }
>  
>  static enum drm_mode_status
> -imx6dl_hdmi_mode_valid(struct drm_connector *con,
> +imx6dl_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data,
> +		       struct drm_connector *con,
>  		       const struct drm_display_mode *mode)
>  {
>  	if (mode->clock < 13500)
> diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c
> index 5be963e9db05..5cc311c1b8e0 100644
> --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c
> +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c
> @@ -630,7 +630,8 @@ static irqreturn_t dw_hdmi_top_thread_irq(int irq, void *dev_id)
>  }
>  
>  static enum drm_mode_status
> -dw_hdmi_mode_valid(struct drm_connector *connector,
> +dw_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data,
> +		   struct drm_connector *connector,
>  		   const struct drm_display_mode *mode)
>  {
>  	struct meson_drm *priv = connector->dev->dev_private;
> diff --git a/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c b/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c
> index 452461dc96f2..4d837a4d302d 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c
> @@ -38,7 +38,8 @@ static const struct rcar_hdmi_phy_params rcar_hdmi_phy_params[] = {
>  };
>  
>  static enum drm_mode_status
> -rcar_hdmi_mode_valid(struct drm_connector *connector,
> +rcar_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data,
> +		     struct drm_connector *connector,
>  		     const struct drm_display_mode *mode)
>  {
>  	/*
> diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> index 121aa8a63a76..d08f86783a28 100644
> --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> @@ -220,7 +220,8 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
>  }
>  
>  static enum drm_mode_status
> -dw_hdmi_rockchip_mode_valid(struct drm_connector *connector,
> +dw_hdmi_rockchip_mode_valid(struct dw_hdmi *hdmi, void *data,
> +			    struct drm_connector *connector,
>  			    const struct drm_display_mode *mode)
>  {
>  	const struct dw_hdmi_mpll_config *mpll_cfg = rockchip_mpll_cfg;
> diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
> index 972682bb8000..0a3637442ba6 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
> +++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
> @@ -31,7 +31,8 @@ sun8i_dw_hdmi_encoder_helper_funcs = {
>  };
>  
>  static enum drm_mode_status
> -sun8i_dw_hdmi_mode_valid_a83t(struct drm_connector *connector,
> +sun8i_dw_hdmi_mode_valid_a83t(struct dw_hdmi *hdmi, void *data,
> +			      struct drm_connector *connector,
>  			      const struct drm_display_mode *mode)
>  {
>  	if (mode->clock > 297000)
> @@ -41,7 +42,8 @@ sun8i_dw_hdmi_mode_valid_a83t(struct drm_connector *connector,
>  }
>  
>  static enum drm_mode_status
> -sun8i_dw_hdmi_mode_valid_h6(struct drm_connector *connector,
> +sun8i_dw_hdmi_mode_valid_h6(struct dw_hdmi *hdmi, void *data,
> +			    struct drm_connector *connector,
>  			    const struct drm_display_mode *mode)
>  {
>  	/*
> diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
> index 8e64945167e9..8587b8d2590e 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
> +++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
> @@ -176,7 +176,8 @@ struct sun8i_hdmi_phy {
>  };
>  
>  struct sun8i_dw_hdmi_quirks {
> -	enum drm_mode_status (*mode_valid)(struct drm_connector *connector,
> +	enum drm_mode_status (*mode_valid)(struct dw_hdmi *hdmi, void *data,
> +					   struct drm_connector *connector,
>  					   const struct drm_display_mode *mode);
>  	unsigned int set_rate : 1;
>  	unsigned int use_drm_infoframe : 1;
> diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
> index 0b34a12c4a1c..66a811f75b91 100644
> --- a/include/drm/bridge/dw_hdmi.h
> +++ b/include/drm/bridge/dw_hdmi.h
> @@ -124,13 +124,23 @@ struct dw_hdmi_phy_ops {
>  
>  struct dw_hdmi_plat_data {
>  	struct regmap *regm;
> -	enum drm_mode_status (*mode_valid)(struct drm_connector *connector,
> -					   const struct drm_display_mode *mode);
> +
>  	unsigned long input_bus_format;
>  	unsigned long input_bus_encoding;
>  	bool use_drm_infoframe;
>  	bool ycbcr_420_allowed;
>  
> +	/*
> +	 * Private data passed to all the .mode_valid() and .configure_phy()
> +	 * callback functions.
> +	 */
> +	void *priv_data;
> +
> +	/* Platform-specific mode validation (optional). */
> +	enum drm_mode_status (*mode_valid)(struct dw_hdmi *hdmi, void *data,
> +					   struct drm_connector *connector,
> +					   const struct drm_display_mode *mode);
> +
>  	/* Vendor PHY support */
>  	const struct dw_hdmi_phy_ops *phy_ops;
>  	const char *phy_name;
> 

Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>

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

* Re: [PATCH 12/27] drm: bridge: dw-hdmi: Pass private data pointer to .configure_phy()
  2020-05-26  1:14 ` [PATCH 12/27] drm: bridge: dw-hdmi: Pass private data pointer to .configure_phy() Laurent Pinchart
@ 2020-05-26  9:45   ` Neil Armstrong
  0 siblings, 0 replies; 69+ messages in thread
From: Neil Armstrong @ 2020-05-26  9:45 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: linux-renesas-soc, Andrzej Hajda, Jernej Skrabec, Jonas Karlman,
	Sam Ravnborg, Kieran Bingham

On 26/05/2020 03:14, Laurent Pinchart wrote:
> The .configure_phy() operation takes a dw_hdmi_plat_data pointer as a
> context argument. This differs from .mode_valid() that takes a custom
> private context pointer, causing possible confusion. Make the
> dw_hdmi_plat_data operations more consistent by passing the private
> context pointer to .configure_phy() as well.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 2 +-
>  drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c    | 3 +--
>  include/drm/bridge/dw_hdmi.h              | 3 +--
>  3 files changed, 3 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 2b3f203cf467..6edb60e6c784 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -1514,7 +1514,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi)
>  
>  	/* Write to the PHY as configured by the platform */
>  	if (pdata->configure_phy)
> -		ret = pdata->configure_phy(hdmi, pdata, mpixelclock);
> +		ret = pdata->configure_phy(hdmi, pdata->priv_data, mpixelclock);
>  	else
>  		ret = phy->configure(hdmi, pdata, mpixelclock);
>  	if (ret) {
> diff --git a/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c b/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c
> index 4d837a4d302d..d0dffe55a7cb 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c
> @@ -52,8 +52,7 @@ rcar_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data,
>  	return MODE_OK;
>  }
>  
> -static int rcar_hdmi_phy_configure(struct dw_hdmi *hdmi,
> -				   const struct dw_hdmi_plat_data *pdata,
> +static int rcar_hdmi_phy_configure(struct dw_hdmi *hdmi, void *data,
>  				   unsigned long mpixelclock)
>  {
>  	const struct rcar_hdmi_phy_params *params = rcar_hdmi_phy_params;
> diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
> index 66a811f75b91..09348c9cbd11 100644
> --- a/include/drm/bridge/dw_hdmi.h
> +++ b/include/drm/bridge/dw_hdmi.h
> @@ -151,8 +151,7 @@ struct dw_hdmi_plat_data {
>  	const struct dw_hdmi_mpll_config *mpll_cfg;
>  	const struct dw_hdmi_curr_ctrl *cur_ctr;
>  	const struct dw_hdmi_phy_config *phy_config;
> -	int (*configure_phy)(struct dw_hdmi *hdmi,
> -			     const struct dw_hdmi_plat_data *pdata,
> +	int (*configure_phy)(struct dw_hdmi *hdmi, void *data,
>  			     unsigned long mpixelclock);
>  };
>  
> 

Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>

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

* Re: [PATCH 13/27] drm: bridge: dw-hdmi: Remove unused field from dw_hdmi_plat_data
  2020-05-26  1:14 ` [PATCH 13/27] drm: bridge: dw-hdmi: Remove unused field from dw_hdmi_plat_data Laurent Pinchart
@ 2020-05-26  9:45   ` Neil Armstrong
  0 siblings, 0 replies; 69+ messages in thread
From: Neil Armstrong @ 2020-05-26  9:45 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: linux-renesas-soc, Andrzej Hajda, Jernej Skrabec, Jonas Karlman,
	Sam Ravnborg, Kieran Bingham

On 26/05/2020 03:14, Laurent Pinchart wrote:
> The input_bus_format field of struct dw_hdmi_plat_data is unused. Remove
> it.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 5 +----
>  include/drm/bridge/dw_hdmi.h              | 1 -
>  2 files changed, 1 insertion(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 6edb60e6c784..adc5a95a06e9 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -2137,10 +2137,7 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
>  	hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 0;
>  	hdmi->hdmi_data.video_mode.mpixelrepetitioninput = 0;
>  
> -	if (hdmi->plat_data->input_bus_format)
> -		hdmi->hdmi_data.enc_in_bus_format =
> -			hdmi->plat_data->input_bus_format;
> -	else if (hdmi->hdmi_data.enc_in_bus_format == MEDIA_BUS_FMT_FIXED)
> +	if (hdmi->hdmi_data.enc_in_bus_format == MEDIA_BUS_FMT_FIXED)
>  		hdmi->hdmi_data.enc_in_bus_format = MEDIA_BUS_FMT_RGB888_1X24;
>  
>  	/* TOFIX: Get input encoding from plat data or fallback to none */
> diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
> index 09348c9cbd11..5dfa9d83e2d3 100644
> --- a/include/drm/bridge/dw_hdmi.h
> +++ b/include/drm/bridge/dw_hdmi.h
> @@ -125,7 +125,6 @@ struct dw_hdmi_phy_ops {
>  struct dw_hdmi_plat_data {
>  	struct regmap *regm;
>  
> -	unsigned long input_bus_format;
>  	unsigned long input_bus_encoding;
>  	bool use_drm_infoframe;
>  	bool ycbcr_420_allowed;
> 

Obviously, now meta-meson doesn't need it anymore, thanks for fixing this.

Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>

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

* Re: [PATCH 15/27] drm: bridge: dw-hdmi: Pass drm_display_info to .mode_valid()
  2020-05-26  1:14 ` [PATCH 15/27] drm: bridge: dw-hdmi: Pass drm_display_info to .mode_valid() Laurent Pinchart
@ 2020-05-26  9:46   ` Neil Armstrong
  0 siblings, 0 replies; 69+ messages in thread
From: Neil Armstrong @ 2020-05-26  9:46 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: linux-renesas-soc, Andrzej Hajda, Jernej Skrabec, Jonas Karlman,
	Sam Ravnborg, Kieran Bingham, Philipp Zabel, Sandy Huang,
	Heiko Stübner, Maxime Ripard, Chen-Yu Tsai, linux-amlogic

On 26/05/2020 03:14, Laurent Pinchart wrote:
> Replace the drm_connector pointer passed to the .mode_valid() function
> with a const drm_display_info pointer, as that's all the function should
> need. Use the display info passed to the bridge .mode_valid() operation
> instead of retrieving it from the connector, to prepare for make
> connector creation optional.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c   |  5 ++---
>  drivers/gpu/drm/imx/dw_hdmi-imx.c           |  4 ++--
>  drivers/gpu/drm/meson/meson_dw_hdmi.c       | 20 ++++++++++----------
>  drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c      |  2 +-
>  drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c |  2 +-
>  drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c       |  4 ++--
>  drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h       |  2 +-
>  include/drm/bridge/dw_hdmi.h                |  4 ++--
>  8 files changed, 21 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index adc5a95a06e9..23650e69604c 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -2769,7 +2769,6 @@ dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
>  {
>  	struct dw_hdmi *hdmi = bridge->driver_private;
>  	const struct dw_hdmi_plat_data *pdata = hdmi->plat_data;
> -	struct drm_connector *connector = &hdmi->connector;
>  	enum drm_mode_status mode_status = MODE_OK;
>  
>  	/* We don't support double-clocked modes */
> @@ -2777,8 +2776,8 @@ dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
>  		return MODE_BAD;
>  
>  	if (pdata->mode_valid)
> -		mode_status = pdata->mode_valid(hdmi, pdata->priv_data,
> -						connector, mode);
> +		mode_status = pdata->mode_valid(hdmi, pdata->priv_data, info,
> +						mode);
>  
>  	return mode_status;
>  }
> diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c b/drivers/gpu/drm/imx/dw_hdmi-imx.c
> index 95aed4666c95..2dc93fa6ecb6 100644
> --- a/drivers/gpu/drm/imx/dw_hdmi-imx.c
> +++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c
> @@ -146,7 +146,7 @@ static const struct drm_encoder_helper_funcs dw_hdmi_imx_encoder_helper_funcs =
>  
>  static enum drm_mode_status
>  imx6q_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data,
> -		      struct drm_connector *con,
> +		      const struct drm_display_info *info,
>  		      const struct drm_display_mode *mode)
>  {
>  	if (mode->clock < 13500)
> @@ -160,7 +160,7 @@ imx6q_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data,
>  
>  static enum drm_mode_status
>  imx6dl_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data,
> -		       struct drm_connector *con,
> +		       const struct drm_display_info *info,
>  		       const struct drm_display_mode *mode)
>  {
>  	if (mode->clock < 13500)
> diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c
> index 34ba94922605..71d599970ec7 100644
> --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c
> +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c
> @@ -631,12 +631,12 @@ static irqreturn_t dw_hdmi_top_thread_irq(int irq, void *dev_id)
>  
>  static enum drm_mode_status
>  dw_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data,
> -		   struct drm_connector *connector,
> +		   const struct drm_display_info *display_info,
>  		   const struct drm_display_mode *mode)
>  {
>  	struct meson_dw_hdmi *dw_hdmi = data;
>  	struct meson_drm *priv = dw_hdmi->priv;
> -	bool is_hdmi2_sink = connector->display_info.hdmi.scdc.supported;
> +	bool is_hdmi2_sink = display_info->hdmi.scdc.supported;
>  	unsigned int phy_freq;
>  	unsigned int vclk_freq;
>  	unsigned int venc_freq;
> @@ -647,10 +647,10 @@ dw_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data,
>  	DRM_DEBUG_DRIVER("Modeline " DRM_MODE_FMT "\n", DRM_MODE_ARG(mode));
>  
>  	/* If sink does not support 540MHz, reject the non-420 HDMI2 modes */
> -	if (connector->display_info.max_tmds_clock &&
> -	    mode->clock > connector->display_info.max_tmds_clock &&
> -	    !drm_mode_is_420_only(&connector->display_info, mode) &&
> -	    !drm_mode_is_420_also(&connector->display_info, mode))
> +	if (display_info->max_tmds_clock &&
> +	    mode->clock > display_info->max_tmds_clock &&
> +	    !drm_mode_is_420_only(display_info, mode) &&
> +	    !drm_mode_is_420_also(display_info, mode))
>  		return MODE_BAD;
>  
>  	/* Check against non-VIC supported modes */
> @@ -667,9 +667,9 @@ dw_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data,
>  	vclk_freq = mode->clock;
>  
>  	/* For 420, pixel clock is half unlike venc clock */
> -	if (drm_mode_is_420_only(&connector->display_info, mode) ||
> +	if (drm_mode_is_420_only(display_info, mode) ||
>  	    (!is_hdmi2_sink &&
> -	     drm_mode_is_420_also(&connector->display_info, mode)))
> +	     drm_mode_is_420_also(display_info, mode)))
>  		vclk_freq /= 2;
>  
>  	/* TMDS clock is pixel_clock * 10 */
> @@ -684,9 +684,9 @@ dw_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data,
>  
>  	/* VENC double pixels for 1080i, 720p and YUV420 modes */
>  	if (meson_venc_hdmi_venc_repeat(vic) ||
> -	    drm_mode_is_420_only(&connector->display_info, mode) ||
> +	    drm_mode_is_420_only(display_info, mode) ||
>  	    (!is_hdmi2_sink &&
> -	     drm_mode_is_420_also(&connector->display_info, mode)))
> +	     drm_mode_is_420_also(display_info, mode)))
>  		venc_freq *= 2;
>  
>  	vclk_freq = max(venc_freq, hdmi_freq);
> diff --git a/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c b/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c
> index d0dffe55a7cb..7b8ec8310699 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c
> @@ -39,7 +39,7 @@ static const struct rcar_hdmi_phy_params rcar_hdmi_phy_params[] = {
>  
>  static enum drm_mode_status
>  rcar_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data,
> -		     struct drm_connector *connector,
> +		     const struct drm_display_info *info,
>  		     const struct drm_display_mode *mode)
>  {
>  	/*
> diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> index d08f86783a28..d286751bb333 100644
> --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> @@ -221,7 +221,7 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
>  
>  static enum drm_mode_status
>  dw_hdmi_rockchip_mode_valid(struct dw_hdmi *hdmi, void *data,
> -			    struct drm_connector *connector,
> +			    const struct drm_display_info *info,
>  			    const struct drm_display_mode *mode)
>  {
>  	const struct dw_hdmi_mpll_config *mpll_cfg = rockchip_mpll_cfg;
> diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
> index 0a3637442ba6..d4c08043dd81 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
> +++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
> @@ -32,7 +32,7 @@ sun8i_dw_hdmi_encoder_helper_funcs = {
>  
>  static enum drm_mode_status
>  sun8i_dw_hdmi_mode_valid_a83t(struct dw_hdmi *hdmi, void *data,
> -			      struct drm_connector *connector,
> +			      const struct drm_display_info *info,
>  			      const struct drm_display_mode *mode)
>  {
>  	if (mode->clock > 297000)
> @@ -43,7 +43,7 @@ sun8i_dw_hdmi_mode_valid_a83t(struct dw_hdmi *hdmi, void *data,
>  
>  static enum drm_mode_status
>  sun8i_dw_hdmi_mode_valid_h6(struct dw_hdmi *hdmi, void *data,
> -			    struct drm_connector *connector,
> +			    const struct drm_display_info *info,
>  			    const struct drm_display_mode *mode)
>  {
>  	/*
> diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
> index 8587b8d2590e..d983746fa194 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
> +++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
> @@ -177,7 +177,7 @@ struct sun8i_hdmi_phy {
>  
>  struct sun8i_dw_hdmi_quirks {
>  	enum drm_mode_status (*mode_valid)(struct dw_hdmi *hdmi, void *data,
> -					   struct drm_connector *connector,
> +					   const struct drm_display_info *info,
>  					   const struct drm_display_mode *mode);
>  	unsigned int set_rate : 1;
>  	unsigned int use_drm_infoframe : 1;
> diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
> index 5dfa9d83e2d3..fec293b21c2e 100644
> --- a/include/drm/bridge/dw_hdmi.h
> +++ b/include/drm/bridge/dw_hdmi.h
> @@ -8,7 +8,7 @@
>  
>  #include <sound/hdmi-codec.h>
>  
> -struct drm_connector;
> +struct drm_display_info;
>  struct drm_display_mode;
>  struct drm_encoder;
>  struct dw_hdmi;
> @@ -137,7 +137,7 @@ struct dw_hdmi_plat_data {
>  
>  	/* Platform-specific mode validation (optional). */
>  	enum drm_mode_status (*mode_valid)(struct dw_hdmi *hdmi, void *data,
> -					   struct drm_connector *connector,
> +					   const struct drm_display_info *info,
>  					   const struct drm_display_mode *mode);
>  
>  	/* Vendor PHY support */
> 

Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>

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

* Re: [PATCH 16/27] drm: bridge: dw-hdmi: Constify mode argument to dw_hdmi_phy_ops .init()
  2020-05-26  1:14 ` [PATCH 16/27] drm: bridge: dw-hdmi: Constify mode argument to dw_hdmi_phy_ops .init() Laurent Pinchart
@ 2020-05-26  9:46   ` Neil Armstrong
  0 siblings, 0 replies; 69+ messages in thread
From: Neil Armstrong @ 2020-05-26  9:46 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: linux-renesas-soc, Andrzej Hajda, Jernej Skrabec, Jonas Karlman,
	Sam Ravnborg, Kieran Bingham, Sandy Huang, Heiko Stübner,
	Maxime Ripard, Chen-Yu Tsai, linux-amlogic

On 26/05/2020 03:14, Laurent Pinchart wrote:
> The PHY .init() must not modify the mode it receives. Make the pointer
> const to enfore that.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c   | 2 +-
>  drivers/gpu/drm/meson/meson_dw_hdmi.c       | 4 ++--
>  drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 2 +-
>  drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c      | 2 +-
>  include/drm/bridge/dw_hdmi.h                | 2 +-
>  5 files changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 23650e69604c..6e6a3d95e68e 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -1531,7 +1531,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi)
>  }
>  
>  static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
> -			    struct drm_display_mode *mode)
> +			    const struct drm_display_mode *mode)
>  {
>  	int i, ret;
>  
> diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c
> index 71d599970ec7..757c17fbb29f 100644
> --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c
> +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c
> @@ -297,7 +297,7 @@ static inline void dw_hdmi_dwc_write_bits(struct meson_dw_hdmi *dw_hdmi,
>  
>  /* Setup PHY bandwidth modes */
>  static void meson_hdmi_phy_setup_mode(struct meson_dw_hdmi *dw_hdmi,
> -				      struct drm_display_mode *mode)
> +				      const struct drm_display_mode *mode)
>  {
>  	struct meson_drm *priv = dw_hdmi->priv;
>  	unsigned int pixel_clock = mode->clock;
> @@ -427,7 +427,7 @@ static void dw_hdmi_set_vclk(struct meson_dw_hdmi *dw_hdmi,
>  }
>  
>  static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
> -			    struct drm_display_mode *mode)
> +			    const struct drm_display_mode *mode)
>  {
>  	struct meson_dw_hdmi *dw_hdmi = (struct meson_dw_hdmi *)data;
>  	struct meson_drm *priv = dw_hdmi->priv;
> diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> index d286751bb333..10e210f6455d 100644
> --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> @@ -312,7 +312,7 @@ static const struct drm_encoder_helper_funcs dw_hdmi_rockchip_encoder_helper_fun
>  };
>  
>  static int dw_hdmi_rockchip_genphy_init(struct dw_hdmi *dw_hdmi, void *data,
> -			     struct drm_display_mode *mode)
> +					const struct drm_display_mode *mode)
>  {
>  	struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
>  
> diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
> index 43643ad31730..8e078cacf063 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
> +++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
> @@ -341,7 +341,7 @@ static int sun8i_hdmi_phy_config_h3(struct dw_hdmi *hdmi,
>  }
>  
>  static int sun8i_hdmi_phy_config(struct dw_hdmi *hdmi, void *data,
> -				 struct drm_display_mode *mode)
> +				 const struct drm_display_mode *mode)
>  {
>  	struct sun8i_hdmi_phy *phy = (struct sun8i_hdmi_phy *)data;
>  	u32 val = 0;
> diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
> index fec293b21c2e..f930d218cc6b 100644
> --- a/include/drm/bridge/dw_hdmi.h
> +++ b/include/drm/bridge/dw_hdmi.h
> @@ -114,7 +114,7 @@ struct dw_hdmi_phy_config {
>  
>  struct dw_hdmi_phy_ops {
>  	int (*init)(struct dw_hdmi *hdmi, void *data,
> -		    struct drm_display_mode *mode);
> +		    const struct drm_display_mode *mode);
>  	void (*disable)(struct dw_hdmi *hdmi, void *data);
>  	enum drm_connector_status (*read_hpd)(struct dw_hdmi *hdmi, void *data);
>  	void (*update_hpd)(struct dw_hdmi *hdmi, void *data,
> 

Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>

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

* Re: [PATCH 17/27] drm: bridge: dw-hdmi: Constify mode argument to internal functions
  2020-05-26  1:14 ` [PATCH 17/27] drm: bridge: dw-hdmi: Constify mode argument to internal functions Laurent Pinchart
@ 2020-05-26  9:46   ` Neil Armstrong
  0 siblings, 0 replies; 69+ messages in thread
From: Neil Armstrong @ 2020-05-26  9:46 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: linux-renesas-soc, Andrzej Hajda, Jernej Skrabec, Jonas Karlman,
	Sam Ravnborg, Kieran Bingham

On 26/05/2020 03:14, Laurent Pinchart wrote:
> Several internal functions take a drm_display_mode argument to configure
> the HDMI encoder or the HDMI PHY. They must not modify the mode, make
> the pointer const to enforce that.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 6e6a3d95e68e..5b5f07a23400 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -1628,7 +1628,8 @@ static void hdmi_tx_hdcp_config(struct dw_hdmi *hdmi)
>  		  HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_MASK, HDMI_A_HDCPCFG1);
>  }
>  
> -static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
> +static void hdmi_config_AVI(struct dw_hdmi *hdmi,
> +			    const struct drm_display_mode *mode)
>  {
>  	struct hdmi_avi_infoframe frame;
>  	u8 val;
> @@ -1756,7 +1757,7 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
>  }
>  
>  static void hdmi_config_vendor_specific_infoframe(struct dw_hdmi *hdmi,
> -						 struct drm_display_mode *mode)
> +						  const struct drm_display_mode *mode)
>  {
>  	struct hdmi_vendor_infoframe frame;
>  	u8 buffer[10];
> @@ -2112,7 +2113,8 @@ static void hdmi_disable_overflow_interrupts(struct dw_hdmi *hdmi)
>  		    HDMI_IH_MUTE_FC_STAT2);
>  }
>  
> -static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
> +static int dw_hdmi_setup(struct dw_hdmi *hdmi,
> +			 const struct drm_display_mode *mode)
>  {
>  	int ret;
>  
> 

Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>

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

* Re: [PATCH 18/27] drm: bridge: dw-hdmi: Pass drm_display_info to dw_hdmi_support_scdc()
  2020-05-26  1:14 ` [PATCH 18/27] drm: bridge: dw-hdmi: Pass drm_display_info to dw_hdmi_support_scdc() Laurent Pinchart
@ 2020-05-26  9:48   ` Neil Armstrong
  0 siblings, 0 replies; 69+ messages in thread
From: Neil Armstrong @ 2020-05-26  9:48 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: linux-renesas-soc, Andrzej Hajda, Jernej Skrabec, Jonas Karlman,
	Sam Ravnborg, Kieran Bingham, Sandy Huang, Heiko Stübner,
	Maxime Ripard, Chen-Yu Tsai, linux-amlogic

On 26/05/2020 03:14, Laurent Pinchart wrote:
> To prepare for making connector creation optional in the driver, pass
> the drm_display_info explicitly to dw_hdmi_support_scdc(). The pointer
> is passed to the callers where required, particularly to the
> dw_hdmi_phy_ops .init() function.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c   | 32 ++++++++++++---------
>  drivers/gpu/drm/meson/meson_dw_hdmi.c       |  3 +-
>  drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c |  1 +
>  drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c      |  1 +
>  include/drm/bridge/dw_hdmi.h                |  4 ++-
>  5 files changed, 26 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 5b5f07a23400..a18794cce0d8 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -1241,10 +1241,9 @@ void dw_hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data,
>  EXPORT_SYMBOL_GPL(dw_hdmi_phy_i2c_write);
>  
>  /* Filter out invalid setups to avoid configuring SCDC and scrambling */
> -static bool dw_hdmi_support_scdc(struct dw_hdmi *hdmi)
> +static bool dw_hdmi_support_scdc(struct dw_hdmi *hdmi,
> +				 const struct drm_display_info *display)
>  {
> -	struct drm_display_info *display = &hdmi->connector.display_info;
> -
>  	/* Completely disable SCDC support for older controllers */
>  	if (hdmi->version < 0x200a)
>  		return false;
> @@ -1282,12 +1281,13 @@ static bool dw_hdmi_support_scdc(struct dw_hdmi *hdmi)
>   * helper should called right before enabling the TMDS Clock and Data in
>   * the PHY configuration callback.
>   */
> -void dw_hdmi_set_high_tmds_clock_ratio(struct dw_hdmi *hdmi)
> +void dw_hdmi_set_high_tmds_clock_ratio(struct dw_hdmi *hdmi,
> +				       const struct drm_display_info *display)
>  {
>  	unsigned long mtmdsclock = hdmi->hdmi_data.video_mode.mtmdsclock;
>  
>  	/* Control for TMDS Bit Period/TMDS Clock-Period Ratio */
> -	if (dw_hdmi_support_scdc(hdmi)) {
> +	if (dw_hdmi_support_scdc(hdmi, display)) {
>  		if (mtmdsclock > HDMI14_MAX_TMDSCLK)
>  			drm_scdc_set_high_tmds_clock_ratio(hdmi->ddc, 1);
>  		else
> @@ -1490,7 +1490,8 @@ static int hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi *hdmi,
>  	return 0;
>  }
>  
> -static int hdmi_phy_configure(struct dw_hdmi *hdmi)
> +static int hdmi_phy_configure(struct dw_hdmi *hdmi,
> +			      const struct drm_display_info *display)
>  {
>  	const struct dw_hdmi_phy_data *phy = hdmi->phy.data;
>  	const struct dw_hdmi_plat_data *pdata = hdmi->plat_data;
> @@ -1500,7 +1501,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi)
>  
>  	dw_hdmi_phy_power_off(hdmi);
>  
> -	dw_hdmi_set_high_tmds_clock_ratio(hdmi);
> +	dw_hdmi_set_high_tmds_clock_ratio(hdmi, display);
>  
>  	/* Leave low power consumption mode by asserting SVSRET. */
>  	if (phy->has_svsret)
> @@ -1531,6 +1532,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi)
>  }
>  
>  static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
> +			    const struct drm_display_info *display,
>  			    const struct drm_display_mode *mode)
>  {
>  	int i, ret;
> @@ -1540,7 +1542,7 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
>  		dw_hdmi_phy_sel_data_en_pol(hdmi, 1);
>  		dw_hdmi_phy_sel_interface_control(hdmi, 0);
>  
> -		ret = hdmi_phy_configure(hdmi);
> +		ret = hdmi_phy_configure(hdmi, display);
>  		if (ret)
>  			return ret;
>  	}
> @@ -1846,10 +1848,11 @@ static void hdmi_config_drm_infoframe(struct dw_hdmi *hdmi)
>  }
>  
>  static void hdmi_av_composer(struct dw_hdmi *hdmi,
> +			     const struct drm_display_info *display,
>  			     const struct drm_display_mode *mode)
>  {
>  	u8 inv_val, bytes;
> -	struct drm_hdmi_info *hdmi_info = &hdmi->connector.display_info.hdmi;
> +	const struct drm_hdmi_info *hdmi_info = &display->hdmi;
>  	struct hdmi_vmode *vmode = &hdmi->hdmi_data.video_mode;
>  	int hblank, vblank, h_de_hs, v_de_vs, hsync_len, vsync_len;
>  	unsigned int vdisplay, hdisplay;
> @@ -1882,7 +1885,7 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
>  
>  	/* Set up HDMI_FC_INVIDCONF */
>  	inv_val = (hdmi->hdmi_data.hdcp_enable ||
> -		   (dw_hdmi_support_scdc(hdmi) &&
> +		   (dw_hdmi_support_scdc(hdmi, display) &&
>  		    (vmode->mtmdsclock > HDMI14_MAX_TMDSCLK ||
>  		     hdmi_info->scdc.scrambling.low_rates)) ?
>  		HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE :
> @@ -1950,7 +1953,7 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
>  	}
>  
>  	/* Scrambling Control */
> -	if (dw_hdmi_support_scdc(hdmi)) {
> +	if (dw_hdmi_support_scdc(hdmi, display)) {
>  		if (vmode->mtmdsclock > HDMI14_MAX_TMDSCLK ||
>  		    hdmi_info->scdc.scrambling.low_rates) {
>  			/*
> @@ -2116,6 +2119,7 @@ static void hdmi_disable_overflow_interrupts(struct dw_hdmi *hdmi)
>  static int dw_hdmi_setup(struct dw_hdmi *hdmi,
>  			 const struct drm_display_mode *mode)
>  {
> +	struct drm_connector *connector = &hdmi->connector;
>  	int ret;
>  
>  	hdmi_disable_overflow_interrupts(hdmi);
> @@ -2161,10 +2165,12 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi,
>  	hdmi->hdmi_data.video_mode.mdataenablepolarity = true;
>  
>  	/* HDMI Initialization Step B.1 */
> -	hdmi_av_composer(hdmi, mode);
> +	hdmi_av_composer(hdmi, &connector->display_info, mode);
>  
>  	/* HDMI Initializateion Step B.2 */
> -	ret = hdmi->phy.ops->init(hdmi, hdmi->phy.data, &hdmi->previous_mode);
> +	ret = hdmi->phy.ops->init(hdmi, hdmi->phy.data,
> +				  &connector->display_info,
> +				  &hdmi->previous_mode);
>  	if (ret)
>  		return ret;
>  	hdmi->phy.enabled = true;
> diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c
> index 757c17fbb29f..15e62f327894 100644
> --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c
> +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c
> @@ -427,6 +427,7 @@ static void dw_hdmi_set_vclk(struct meson_dw_hdmi *dw_hdmi,
>  }
>  
>  static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
> +			    const struct drm_display_info *display,
>  			    const struct drm_display_mode *mode)
>  {
>  	struct meson_dw_hdmi *dw_hdmi = (struct meson_dw_hdmi *)data;
> @@ -496,7 +497,7 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
>  	/* Disable clock, fifo, fifo_wr */
>  	regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, 0xf, 0);
>  
> -	dw_hdmi_set_high_tmds_clock_ratio(hdmi);
> +	dw_hdmi_set_high_tmds_clock_ratio(hdmi, display);
>  
>  	msleep(100);
>  
> diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> index 10e210f6455d..23de359a1dec 100644
> --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> @@ -312,6 +312,7 @@ static const struct drm_encoder_helper_funcs dw_hdmi_rockchip_encoder_helper_fun
>  };
>  
>  static int dw_hdmi_rockchip_genphy_init(struct dw_hdmi *dw_hdmi, void *data,
> +					const struct drm_display_info *display,
>  					const struct drm_display_mode *mode)
>  {
>  	struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
> diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
> index 8e078cacf063..156d00e5165b 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
> +++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
> @@ -341,6 +341,7 @@ static int sun8i_hdmi_phy_config_h3(struct dw_hdmi *hdmi,
>  }
>  
>  static int sun8i_hdmi_phy_config(struct dw_hdmi *hdmi, void *data,
> +				 const struct drm_display_info *display,
>  				 const struct drm_display_mode *mode)
>  {
>  	struct sun8i_hdmi_phy *phy = (struct sun8i_hdmi_phy *)data;
> diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
> index f930d218cc6b..ea34ca146b82 100644
> --- a/include/drm/bridge/dw_hdmi.h
> +++ b/include/drm/bridge/dw_hdmi.h
> @@ -114,6 +114,7 @@ struct dw_hdmi_phy_config {
>  
>  struct dw_hdmi_phy_ops {
>  	int (*init)(struct dw_hdmi *hdmi, void *data,
> +		    const struct drm_display_info *display,
>  		    const struct drm_display_mode *mode);
>  	void (*disable)(struct dw_hdmi *hdmi, void *data);
>  	enum drm_connector_status (*read_hpd)(struct dw_hdmi *hdmi, void *data);
> @@ -174,7 +175,8 @@ void dw_hdmi_set_channel_status(struct dw_hdmi *hdmi, u8 *channel_status);
>  void dw_hdmi_set_channel_allocation(struct dw_hdmi *hdmi, unsigned int ca);
>  void dw_hdmi_audio_enable(struct dw_hdmi *hdmi);
>  void dw_hdmi_audio_disable(struct dw_hdmi *hdmi);
> -void dw_hdmi_set_high_tmds_clock_ratio(struct dw_hdmi *hdmi);
> +void dw_hdmi_set_high_tmds_clock_ratio(struct dw_hdmi *hdmi,
> +				       const struct drm_display_info *display);
>  
>  /* PHY configuration */
>  void dw_hdmi_phy_i2c_set_addr(struct dw_hdmi *hdmi, u8 address);
> 

Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>

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

* Re: [PATCH 19/27] drm: bridge: dw-hdmi: Split connector creation to a separate function
  2020-05-26  1:14 ` [PATCH 19/27] drm: bridge: dw-hdmi: Split connector creation to a separate function Laurent Pinchart
@ 2020-05-26  9:49   ` Neil Armstrong
  0 siblings, 0 replies; 69+ messages in thread
From: Neil Armstrong @ 2020-05-26  9:49 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: linux-renesas-soc, Andrzej Hajda, Jernej Skrabec, Jonas Karlman,
	Sam Ravnborg, Kieran Bingham

On 26/05/2020 03:14, Laurent Pinchart wrote:
> Isolate all the code related to connector creation to a new
> dw_hdmi_connector_create() function, to prepare for making connector
> creation optional.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 107 +++++++++++++---------
>  1 file changed, 62 insertions(+), 45 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index a18794cce0d8..35d38b644912 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -2317,6 +2317,10 @@ static void dw_hdmi_update_phy_mask(struct dw_hdmi *hdmi)
>  					  hdmi->rxsense);
>  }
>  
> +/* -----------------------------------------------------------------------------
> + * DRM Connector Operations
> + */
> +
>  static enum drm_connector_status
>  dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
>  {
> @@ -2438,6 +2442,59 @@ static const struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs =
>  	.atomic_check = dw_hdmi_connector_atomic_check,
>  };
>  
> +static int dw_hdmi_connector_create(struct dw_hdmi *hdmi)
> +{
> +	struct drm_connector *connector = &hdmi->connector;
> +	struct cec_connector_info conn_info;
> +	struct cec_notifier *notifier;
> +
> +	if (hdmi->version >= 0x200a)
> +		connector->ycbcr_420_allowed =
> +			hdmi->plat_data->ycbcr_420_allowed;
> +	else
> +		connector->ycbcr_420_allowed = false;
> +
> +	connector->interlace_allowed = 1;
> +	connector->polled = DRM_CONNECTOR_POLL_HPD;
> +
> +	drm_connector_helper_add(connector, &dw_hdmi_connector_helper_funcs);
> +
> +	drm_connector_init_with_ddc(hdmi->bridge.dev, connector,
> +				    &dw_hdmi_connector_funcs,
> +				    DRM_MODE_CONNECTOR_HDMIA,
> +				    hdmi->ddc);
> +
> +	/*
> +	 * drm_connector_attach_max_bpc_property() requires the
> +	 * connector to have a state.
> +	 */
> +	drm_atomic_helper_connector_reset(connector);
> +
> +	drm_connector_attach_max_bpc_property(connector, 8, 16);
> +
> +	if (hdmi->version >= 0x200a && hdmi->plat_data->use_drm_infoframe)
> +		drm_object_attach_property(&connector->base,
> +			connector->dev->mode_config.hdr_output_metadata_property, 0);
> +
> +	drm_connector_attach_encoder(connector, hdmi->bridge.encoder);
> +
> +	cec_fill_conn_info_from_drm(&conn_info, connector);
> +
> +	notifier = cec_notifier_conn_register(hdmi->dev, NULL, &conn_info);
> +	if (!notifier)
> +		return -ENOMEM;
> +
> +	mutex_lock(&hdmi->cec_notifier_mutex);
> +	hdmi->cec_notifier = notifier;
> +	mutex_unlock(&hdmi->cec_notifier_mutex);
> +
> +	return 0;
> +}
> +
> +/* -----------------------------------------------------------------------------
> + * DRM Bridge Operations
> + */
> +
>  /*
>   * Possible output formats :
>   * - MEDIA_BUS_FMT_UYYVYY16_0_5X48,
> @@ -2713,51 +2770,13 @@ static int dw_hdmi_bridge_attach(struct drm_bridge *bridge,
>  				 enum drm_bridge_attach_flags flags)
>  {
>  	struct dw_hdmi *hdmi = bridge->driver_private;
> -	struct drm_encoder *encoder = bridge->encoder;
> -	struct drm_connector *connector = &hdmi->connector;
> -	struct cec_connector_info conn_info;
> -	struct cec_notifier *notifier;
>  
>  	if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {
>  		DRM_ERROR("Fix bridge driver to make connector optional!");
>  		return -EINVAL;
>  	}
>  
> -	connector->interlace_allowed = 1;
> -	connector->polled = DRM_CONNECTOR_POLL_HPD;
> -
> -	drm_connector_helper_add(connector, &dw_hdmi_connector_helper_funcs);
> -
> -	drm_connector_init_with_ddc(bridge->dev, connector,
> -				    &dw_hdmi_connector_funcs,
> -				    DRM_MODE_CONNECTOR_HDMIA,
> -				    hdmi->ddc);
> -
> -	/*
> -	 * drm_connector_attach_max_bpc_property() requires the
> -	 * connector to have a state.
> -	 */
> -	drm_atomic_helper_connector_reset(connector);
> -
> -	drm_connector_attach_max_bpc_property(connector, 8, 16);
> -
> -	if (hdmi->version >= 0x200a && hdmi->plat_data->use_drm_infoframe)
> -		drm_object_attach_property(&connector->base,
> -			connector->dev->mode_config.hdr_output_metadata_property, 0);
> -
> -	drm_connector_attach_encoder(connector, encoder);
> -
> -	cec_fill_conn_info_from_drm(&conn_info, connector);
> -
> -	notifier = cec_notifier_conn_register(hdmi->dev, NULL, &conn_info);
> -	if (!notifier)
> -		return -ENOMEM;
> -
> -	mutex_lock(&hdmi->cec_notifier_mutex);
> -	hdmi->cec_notifier = notifier;
> -	mutex_unlock(&hdmi->cec_notifier_mutex);
> -
> -	return 0;
> +	return dw_hdmi_connector_create(hdmi);
>  }
>  
>  static void dw_hdmi_bridge_detach(struct drm_bridge *bridge)
> @@ -2841,6 +2860,10 @@ static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = {
>  	.mode_valid = dw_hdmi_bridge_mode_valid,
>  };
>  
> +/* -----------------------------------------------------------------------------
> + * IRQ Handling
> + */
> +
>  static irqreturn_t dw_hdmi_i2c_irq(struct dw_hdmi *hdmi)
>  {
>  	struct dw_hdmi_i2c *i2c = hdmi->i2c;
> @@ -3303,12 +3326,6 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  	hdmi->bridge.of_node = pdev->dev.of_node;
>  #endif
>  
> -	if (hdmi->version >= 0x200a)
> -		hdmi->connector.ycbcr_420_allowed =
> -			hdmi->plat_data->ycbcr_420_allowed;
> -	else
> -		hdmi->connector.ycbcr_420_allowed = false;
> -
>  	memset(&pdevinfo, 0, sizeof(pdevinfo));
>  	pdevinfo.parent = dev;
>  	pdevinfo.id = PLATFORM_DEVID_AUTO;
> 

Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>

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

* Re: [PATCH 20/27] drm: bridge: dw-hdmi: Store current connector in struct dw_hdmi
  2020-05-26  1:14 ` [PATCH 20/27] drm: bridge: dw-hdmi: Store current connector in struct dw_hdmi Laurent Pinchart
@ 2020-05-26 12:29   ` Neil Armstrong
  0 siblings, 0 replies; 69+ messages in thread
From: Neil Armstrong @ 2020-05-26 12:29 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: linux-renesas-soc, Andrzej Hajda, Jernej Skrabec, Jonas Karlman,
	Sam Ravnborg, Kieran Bingham

On 26/05/2020 03:14, Laurent Pinchart wrote:
> Store the connector that the bridge is currently wired to in the dw_hdmi
> structure. This is currently identical to the connector field, but will
> differ once the driver supports disabling connector creation.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 18 ++++++++++++++----
>  1 file changed, 14 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 35d38b644912..16bffedb4715 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -181,6 +181,7 @@ struct dw_hdmi {
>  
>  	struct mutex mutex;		/* for state below and previous_mode */
>  	enum drm_connector_force force;	/* mutex-protected force state */
> +	struct drm_connector *curr_conn;/* current connector (only valid when !disabled) */

Nit: The comment position is not great, but I don't see other ways except adding a tab and removing "(only valid when !disabled)"

>  	bool disabled;			/* DRM has disabled our bridge */
>  	bool bridge_is_on;		/* indicates the bridge is on */
>  	bool rxsense;			/* rxsense state */
> @@ -2823,23 +2824,32 @@ static void dw_hdmi_bridge_mode_set(struct drm_bridge *bridge,
>  	mutex_unlock(&hdmi->mutex);
>  }
>  
> -static void dw_hdmi_bridge_disable(struct drm_bridge *bridge)
> +static void dw_hdmi_bridge_atomic_disable(struct drm_bridge *bridge,
> +					  struct drm_bridge_state *old_state)
>  {
>  	struct dw_hdmi *hdmi = bridge->driver_private;
>  
>  	mutex_lock(&hdmi->mutex);
>  	hdmi->disabled = true;
> +	hdmi->curr_conn = NULL;
>  	dw_hdmi_update_power(hdmi);
>  	dw_hdmi_update_phy_mask(hdmi);
>  	mutex_unlock(&hdmi->mutex);
>  }
>  
> -static void dw_hdmi_bridge_enable(struct drm_bridge *bridge)
> +static void dw_hdmi_bridge_atomic_enable(struct drm_bridge *bridge,
> +					 struct drm_bridge_state *old_state)
>  {
>  	struct dw_hdmi *hdmi = bridge->driver_private;
> +	struct drm_atomic_state *state = old_state->base.state;
> +	struct drm_connector *connector;
> +
> +	connector = drm_atomic_get_new_connector_for_encoder(state,
> +							     bridge->encoder);
>  
>  	mutex_lock(&hdmi->mutex);
>  	hdmi->disabled = false;
> +	hdmi->curr_conn = connector;
>  	dw_hdmi_update_power(hdmi);
>  	dw_hdmi_update_phy_mask(hdmi);
>  	mutex_unlock(&hdmi->mutex);
> @@ -2854,8 +2864,8 @@ static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = {
>  	.atomic_check = dw_hdmi_bridge_atomic_check,
>  	.atomic_get_output_bus_fmts = dw_hdmi_bridge_atomic_get_output_bus_fmts,
>  	.atomic_get_input_bus_fmts = dw_hdmi_bridge_atomic_get_input_bus_fmts,
> -	.enable = dw_hdmi_bridge_enable,
> -	.disable = dw_hdmi_bridge_disable,
> +	.atomic_enable = dw_hdmi_bridge_atomic_enable,
> +	.atomic_disable = dw_hdmi_bridge_atomic_disable,
>  	.mode_set = dw_hdmi_bridge_mode_set,
>  	.mode_valid = dw_hdmi_bridge_mode_valid,
>  };
> 

Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>

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

* Re: [PATCH 21/27] drm: bridge: dw-hdmi: Pass drm_connector to internal functions as needed
  2020-05-26  1:14 ` [PATCH 21/27] drm: bridge: dw-hdmi: Pass drm_connector to internal functions as needed Laurent Pinchart
@ 2020-05-26 12:29   ` Neil Armstrong
  0 siblings, 0 replies; 69+ messages in thread
From: Neil Armstrong @ 2020-05-26 12:29 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: linux-renesas-soc, Andrzej Hajda, Jernej Skrabec, Jonas Karlman,
	Sam Ravnborg, Kieran Bingham

On 26/05/2020 03:14, Laurent Pinchart wrote:
> To prepare for making connector creation optional in the driver, pass
> the drm_connector explicitly to the internal functions that require it.
> The functions that still access the connector from the dw_hdmi structure
> are dw_hdmi_connector_create() and __dw_hdmi_probe(). The former access
> is expected, as that's where the internal connector is created. The
> latter will be addressed separately.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 31 +++++++++++++----------
>  1 file changed, 18 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 16bffedb4715..b69c14b9de62 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -1632,18 +1632,17 @@ static void hdmi_tx_hdcp_config(struct dw_hdmi *hdmi)
>  }
>  
>  static void hdmi_config_AVI(struct dw_hdmi *hdmi,
> +			    const struct drm_connector *connector,
>  			    const struct drm_display_mode *mode)
>  {
>  	struct hdmi_avi_infoframe frame;
>  	u8 val;
>  
>  	/* Initialise info frame from DRM mode */
> -	drm_hdmi_avi_infoframe_from_display_mode(&frame,
> -						 &hdmi->connector, mode);
> +	drm_hdmi_avi_infoframe_from_display_mode(&frame, connector, mode);
>  
>  	if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format)) {
> -		drm_hdmi_avi_infoframe_quant_range(&frame, &hdmi->connector,
> -						   mode,
> +		drm_hdmi_avi_infoframe_quant_range(&frame, connector, mode,
>  						   hdmi->hdmi_data.rgb_limited_range ?
>  						   HDMI_QUANTIZATION_RANGE_LIMITED :
>  						   HDMI_QUANTIZATION_RANGE_FULL);
> @@ -1760,14 +1759,14 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi,
>  }
>  
>  static void hdmi_config_vendor_specific_infoframe(struct dw_hdmi *hdmi,
> +						  const struct drm_connector *connector,
>  						  const struct drm_display_mode *mode)
>  {
>  	struct hdmi_vendor_infoframe frame;
>  	u8 buffer[10];
>  	ssize_t err;
>  
> -	err = drm_hdmi_vendor_infoframe_from_display_mode(&frame,
> -							  &hdmi->connector,
> +	err = drm_hdmi_vendor_infoframe_from_display_mode(&frame, connector,
>  							  mode);
>  	if (err < 0)
>  		/*
> @@ -1813,9 +1812,10 @@ static void hdmi_config_vendor_specific_infoframe(struct dw_hdmi *hdmi,
>  			HDMI_FC_DATAUTO0_VSD_MASK);
>  }
>  
> -static void hdmi_config_drm_infoframe(struct dw_hdmi *hdmi)
> +static void hdmi_config_drm_infoframe(struct dw_hdmi *hdmi,
> +				      const struct drm_connector *connector)
>  {
> -	const struct drm_connector_state *conn_state = hdmi->connector.state;
> +	const struct drm_connector_state *conn_state = connector->state;
>  	struct hdmi_drm_infoframe frame;
>  	u8 buffer[30];
>  	ssize_t err;
> @@ -2118,9 +2118,9 @@ static void hdmi_disable_overflow_interrupts(struct dw_hdmi *hdmi)
>  }
>  
>  static int dw_hdmi_setup(struct dw_hdmi *hdmi,
> +			 const struct drm_connector *connector,
>  			 const struct drm_display_mode *mode)
>  {
> -	struct drm_connector *connector = &hdmi->connector;
>  	int ret;
>  
>  	hdmi_disable_overflow_interrupts(hdmi);
> @@ -2192,9 +2192,9 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi,
>  		dev_dbg(hdmi->dev, "%s HDMI mode\n", __func__);
>  
>  		/* HDMI Initialization Step F - Configure AVI InfoFrame */
> -		hdmi_config_AVI(hdmi, mode);
> -		hdmi_config_vendor_specific_infoframe(hdmi, mode);
> -		hdmi_config_drm_infoframe(hdmi);
> +		hdmi_config_AVI(hdmi, connector, mode);
> +		hdmi_config_vendor_specific_infoframe(hdmi, connector, mode);
> +		hdmi_config_drm_infoframe(hdmi, connector);
>  	} else {
>  		dev_dbg(hdmi->dev, "%s DVI mode\n", __func__);
>  	}
> @@ -2263,7 +2263,12 @@ static void initialize_hdmi_ih_mutes(struct dw_hdmi *hdmi)
>  static void dw_hdmi_poweron(struct dw_hdmi *hdmi)
>  {
>  	hdmi->bridge_is_on = true;
> -	dw_hdmi_setup(hdmi, &hdmi->previous_mode);
> +
> +	/*
> +	 * The curr_conn field is guaranteed to be valid here, as this function
> +	 * is only be called when !hdmi->disabled.
> +	 */
> +	dw_hdmi_setup(hdmi, hdmi->curr_conn, &hdmi->previous_mode);
>  }
>  
>  static void dw_hdmi_poweroff(struct dw_hdmi *hdmi)
> 

Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>

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

* Re: [PATCH 14/27] drm: meson: dw-hdmi: Use dw_hdmi context to replace hack
  2020-05-26  1:14 ` [PATCH 14/27] drm: meson: dw-hdmi: Use dw_hdmi context to replace hack Laurent Pinchart
@ 2020-05-26 12:32   ` Neil Armstrong
  0 siblings, 0 replies; 69+ messages in thread
From: Neil Armstrong @ 2020-05-26 12:32 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: linux-renesas-soc, Andrzej Hajda, Jernej Skrabec, Jonas Karlman,
	Sam Ravnborg, Kieran Bingham, linux-amlogic

On 26/05/2020 03:14, Laurent Pinchart wrote:
> The meson-dw-hdmi driver needs to access its own context from the
> .mode_valid() operation. It currently gets it from the dev_private field
> of the drm_device retrieved from the connector, which is a hack. Use the
> private data passed to the .mode_valid() operation instead.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  drivers/gpu/drm/meson/meson_dw_hdmi.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c
> index 5cc311c1b8e0..34ba94922605 100644
> --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c
> +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c
> @@ -634,7 +634,8 @@ dw_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data,
>  		   struct drm_connector *connector,
>  		   const struct drm_display_mode *mode)
>  {
> -	struct meson_drm *priv = connector->dev->dev_private;
> +	struct meson_dw_hdmi *dw_hdmi = data;
> +	struct meson_drm *priv = dw_hdmi->priv;
>  	bool is_hdmi2_sink = connector->display_info.hdmi.scdc.supported;
>  	unsigned int phy_freq;
>  	unsigned int vclk_freq;
> @@ -693,7 +694,7 @@ dw_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data,
>  	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
>  		venc_freq /= 2;
>  
> -	dev_dbg(connector->dev->dev, "%s: vclk:%d phy=%d venc=%d hdmi=%d\n",
> +	dev_dbg(dw_hdmi->dev, "%s: vclk:%d phy=%d venc=%d hdmi=%d\n",
>  		__func__, phy_freq, vclk_freq, venc_freq, hdmi_freq);
>  
>  	return meson_vclk_vic_supported_freq(priv, phy_freq, vclk_freq);
> @@ -1068,6 +1069,7 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master,
>  
>  	/* Bridge / Connector */
>  
> +	dw_plat_data->priv_data = meson_dw_hdmi;
>  	dw_plat_data->mode_valid = dw_hdmi_mode_valid;
>  	dw_plat_data->phy_ops = &meson_dw_hdmi_phy_ops;
>  	dw_plat_data->phy_name = "meson_dw_hdmi_phy";
> 

Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>

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

* Re: [PATCH 22/27] drm: bridge: dw-hdmi: Make connector creation optional
  2020-05-26  1:15 ` [PATCH 22/27] drm: bridge: dw-hdmi: Make connector creation optional Laurent Pinchart
@ 2020-05-26 12:35   ` Neil Armstrong
  2020-06-07  1:19     ` Laurent Pinchart
  0 siblings, 1 reply; 69+ messages in thread
From: Neil Armstrong @ 2020-05-26 12:35 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: linux-renesas-soc, Andrzej Hajda, Jernej Skrabec, Jonas Karlman,
	Sam Ravnborg, Kieran Bingham

On 26/05/2020 03:15, Laurent Pinchart wrote:
> Implement the drm_bridge_funcs .detect() and .get_edid() operations, and
> call drm_bridge_hpd_notify() notify to report HPD. This provides the
> necessary API to support disabling connector creation, do so by
> accepting DRM_BRIDGE_ATTACH_NO_CONNECTOR in dw_hdmi_bridge_attach().
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 104 +++++++++++++++-------
>  1 file changed, 74 insertions(+), 30 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index b69c14b9de62..6148a022569a 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -2323,15 +2323,8 @@ static void dw_hdmi_update_phy_mask(struct dw_hdmi *hdmi)
>  					  hdmi->rxsense);
>  }
>  
> -/* -----------------------------------------------------------------------------
> - * DRM Connector Operations
> - */
> -
> -static enum drm_connector_status
> -dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
> +static enum drm_connector_status dw_hdmi_detect(struct dw_hdmi *hdmi)
>  {
> -	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
> -					     connector);
>  	enum drm_connector_status result;
>  
>  	mutex_lock(&hdmi->mutex);
> @@ -2354,31 +2347,57 @@ dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
>  	return result;
>  }
>  
> -static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
> +static struct edid *dw_hdmi_get_edid(struct dw_hdmi *hdmi,
> +				     struct drm_connector *connector)
>  {
> -	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
> -					     connector);
>  	struct edid *edid;
> -	int ret = 0;
>  
>  	if (!hdmi->ddc)
> -		return 0;
> +		return NULL;
>  
>  	edid = drm_get_edid(connector, hdmi->ddc);
> -	if (edid) {
> -		dev_dbg(hdmi->dev, "got edid: width[%d] x height[%d]\n",
> -			edid->width_cm, edid->height_cm);
> -
> -		hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid);
> -		hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
> -		drm_connector_update_edid_property(connector, edid);
> -		cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid);
> -		ret = drm_add_edid_modes(connector, edid);
> -		kfree(edid);
> -	} else {
> +	if (!edid) {
>  		dev_dbg(hdmi->dev, "failed to get edid\n");
> +		return NULL;
>  	}
>  
> +	dev_dbg(hdmi->dev, "got edid: width[%d] x height[%d]\n",
> +		edid->width_cm, edid->height_cm);
> +
> +	hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid);
> +	hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
> +
> +	return edid;
> +}
> +
> +/* -----------------------------------------------------------------------------
> + * DRM Connector Operations
> + */
> +
> +static enum drm_connector_status
> +dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
> +{
> +	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
> +					     connector);
> +	return dw_hdmi_detect(hdmi);
> +}
> +
> +static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
> +{
> +	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
> +					     connector);
> +	struct edid *edid;
> +	int ret;
> +
> +	edid = dw_hdmi_get_edid(hdmi, connector);
> +	if (!edid)
> +		return 0;
> +
> +	drm_connector_update_edid_property(connector, edid);
> +	cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid);
> +	ret = drm_add_edid_modes(connector, edid);
> +	kfree(edid);
> +
>  	return ret;
>  }
>  
> @@ -2777,10 +2796,8 @@ static int dw_hdmi_bridge_attach(struct drm_bridge *bridge,
>  {
>  	struct dw_hdmi *hdmi = bridge->driver_private;
>  
> -	if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {
> -		DRM_ERROR("Fix bridge driver to make connector optional!");
> -		return -EINVAL;
> -	}
> +	if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
> +		return 0;
>  
>  	return dw_hdmi_connector_create(hdmi);
>  }
> @@ -2860,6 +2877,21 @@ static void dw_hdmi_bridge_atomic_enable(struct drm_bridge *bridge,
>  	mutex_unlock(&hdmi->mutex);
>  }
>  
> +static enum drm_connector_status dw_hdmi_bridge_detect(struct drm_bridge *bridge)
> +{
> +	struct dw_hdmi *hdmi = bridge->driver_private;
> +
> +	return dw_hdmi_detect(hdmi);
> +}
> +
> +static struct edid *dw_hdmi_bridge_get_edid(struct drm_bridge *bridge,
> +					    struct drm_connector *connector)
> +{
> +	struct dw_hdmi *hdmi = bridge->driver_private;
> +
> +	return dw_hdmi_get_edid(hdmi, connector);
> +}
> +
>  static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = {
>  	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
>  	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
> @@ -2873,6 +2905,8 @@ static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = {
>  	.atomic_disable = dw_hdmi_bridge_atomic_disable,
>  	.mode_set = dw_hdmi_bridge_mode_set,
>  	.mode_valid = dw_hdmi_bridge_mode_valid,
> +	.detect = dw_hdmi_bridge_detect,
> +	.get_edid = dw_hdmi_bridge_get_edid,
>  };
>  
>  /* -----------------------------------------------------------------------------
> @@ -2988,10 +3022,18 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
>  	}
>  
>  	if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
> +		enum drm_connector_status status = phy_int_pol & HDMI_PHY_HPD
> +						 ? connector_status_connected
> +						 : connector_status_disconnected;
> +
>  		dev_dbg(hdmi->dev, "EVENT=%s\n",
> -			phy_int_pol & HDMI_PHY_HPD ? "plugin" : "plugout");
> -		if (hdmi->bridge.dev)
> +			status == connector_status_connected ?
> +			"plugin" : "plugout");
> +
> +		if (hdmi->bridge.dev) {
>  			drm_helper_hpd_irq_event(hdmi->bridge.dev);
> +			drm_bridge_hpd_notify(&hdmi->bridge, status);

I suspect I will also need to add drm_bridge_hpd_notify() in meson_dw_hdmi.c in dw_hdmi_top_thread_irq() for HPD event, right ?

> +		}
>  	}
>  
>  	hdmi_writeb(hdmi, intr_stat, HDMI_IH_PHY_STAT0);
> @@ -3337,6 +3379,8 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  
>  	hdmi->bridge.driver_private = hdmi;
>  	hdmi->bridge.funcs = &dw_hdmi_bridge_funcs;
> +	hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID
> +			 | DRM_BRIDGE_OP_HPD;

same here for meson_dw_hdmi ?
could I also assume we could disable the dw_hdmi bridge & hpd ops when using with meson_dw_hdmi and
implement these in meson_dw_hdmi ?

>  #ifdef CONFIG_OF
>  	hdmi->bridge.of_node = pdev->dev.of_node;
>  #endif
> 

Anyway

Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>

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

* Re: [PATCH 23/27] drm: bridge: dw-hdmi: Attach to next bridge if available
  2020-05-26  1:15 ` [PATCH 23/27] drm: bridge: dw-hdmi: Attach to next bridge if available Laurent Pinchart
@ 2020-05-26 12:50   ` Neil Armstrong
  2020-05-26 14:23     ` Jonas Karlman
  2020-06-07  1:22     ` Laurent Pinchart
  0 siblings, 2 replies; 69+ messages in thread
From: Neil Armstrong @ 2020-05-26 12:50 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: Jernej Skrabec, Jonas Karlman, Kieran Bingham, linux-renesas-soc,
	Andrzej Hajda, Sam Ravnborg

On 26/05/2020 03:15, Laurent Pinchart wrote:
> On all platforms except i.MX and Rockchip, the dw-hdmi DT bindings
> require a video output port connected to an HDMI sink (most likely an
> HDMI connector, in rare cases another bridges converting HDMI to another
> protocol). For those platforms, retrieve the next bridge and attach it
> from the dw-hdmi bridge attach handler.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 52 ++++++++++++++++++++++-
>  include/drm/bridge/dw_hdmi.h              |  2 +
>  2 files changed, 53 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 6148a022569a..512e67bb1c32 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -143,6 +143,7 @@ struct dw_hdmi_phy_data {
>  struct dw_hdmi {
>  	struct drm_connector connector;
>  	struct drm_bridge bridge;
> +	struct drm_bridge *next_bridge;
>  
>  	unsigned int version;
>  
> @@ -2797,7 +2798,8 @@ static int dw_hdmi_bridge_attach(struct drm_bridge *bridge,
>  	struct dw_hdmi *hdmi = bridge->driver_private;
>  
>  	if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
> -		return 0;
> +		return drm_bridge_attach(bridge->encoder, hdmi->next_bridge,
> +					 bridge, flags);
>  
>  	return dw_hdmi_connector_create(hdmi);
>  }
> @@ -3179,6 +3181,50 @@ static void dw_hdmi_init_hw(struct dw_hdmi *hdmi)
>  		hdmi->phy.ops->setup_hpd(hdmi, hdmi->phy.data);
>  }
>  
> +static int dw_hdmi_parse_dt(struct dw_hdmi *hdmi)
> +{
> +	struct device_node *endpoint;
> +	struct device_node *remote;
> +
> +	if (!hdmi->plat_data->output_port)
> +		return 0;
> +
> +	endpoint = of_graph_get_endpoint_by_regs(hdmi->dev->of_node,
> +						 hdmi->plat_data->output_port,
> +						 -1);
> +	if (!endpoint) {
> +		/*
> +		 * Don't treat this as a fatal error as the Rockchip DW-HDMI
> +		 * binding doesn't make the output port mandatory.
> +		 */
> +		dev_dbg(hdmi->dev, "Missing endpoint in port@%u\n",
> +			hdmi->plat_data->output_port);
> +		return 0;
> +	}
> +
> +	remote = of_graph_get_remote_port_parent(endpoint);
> +	of_node_put(endpoint);
> +	if (!remote) {
> +		dev_err(hdmi->dev, "Endpoint in port@%u unconnected\n",
> +			hdmi->plat_data->output_port);
> +		return -ENODEV;
> +	}
> +
> +	if (!of_device_is_available(remote)) {
> +		dev_err(hdmi->dev, "port@%u remote device is disabled\n",
> +			hdmi->plat_data->output_port);
> +		of_node_put(remote);
> +		return -ENODEV;
> +	}
> +
> +	hdmi->next_bridge = of_drm_find_bridge(remote);
> +	of_node_put(remote);
> +	if (!hdmi->next_bridge)
> +		return -EPROBE_DEFER;

I'll be safer to print a warn for now until all platforms has been tested.

> +
> +	return 0;
> +}
> +
>  static struct dw_hdmi *
>  __dw_hdmi_probe(struct platform_device *pdev,
>  		const struct dw_hdmi_plat_data *plat_data)
> @@ -3216,6 +3262,10 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  	mutex_init(&hdmi->cec_notifier_mutex);
>  	spin_lock_init(&hdmi->audio_lock);
>  
> +	ret = dw_hdmi_parse_dt(hdmi);
> +	if (ret < 0)
> +		return ERR_PTR(ret);
> +
>  	ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0);
>  	if (ddc_node) {
>  		hdmi->ddc = of_get_i2c_adapter_by_node(ddc_node);
> diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
> index ea34ca146b82..8ebeb65d6371 100644
> --- a/include/drm/bridge/dw_hdmi.h
> +++ b/include/drm/bridge/dw_hdmi.h
> @@ -126,6 +126,8 @@ struct dw_hdmi_phy_ops {
>  struct dw_hdmi_plat_data {
>  	struct regmap *regm;
>  
> +	unsigned int output_port;
> +
>  	unsigned long input_bus_encoding;
>  	bool use_drm_infoframe;
>  	bool ycbcr_420_allowed;
> 

I must check on meson, since I'm not sure for now if the connector probes.

Anyway, this looks fine.

Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>

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

* Re: [PATCH 10/27] drm: bridge: Pass drm_display_info to drm_bridge_funcs .mode_valid()
  2020-05-26  1:14 ` [PATCH 10/27] drm: bridge: Pass drm_display_info to drm_bridge_funcs .mode_valid() Laurent Pinchart
@ 2020-05-26 12:51   ` Neil Armstrong
  2020-05-26 12:59   ` Boris Brezillon
  2020-05-26 14:05   ` Guido Günther
  2 siblings, 0 replies; 69+ messages in thread
From: Neil Armstrong @ 2020-05-26 12:51 UTC (permalink / raw)
  To: Laurent Pinchart, dri-devel
  Cc: linux-renesas-soc, Andrzej Hajda, Jernej Skrabec, Jonas Karlman,
	Sam Ravnborg, Kieran Bingham, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Andrey Gusakov, Boris Brezillon, Chris Zhong,
	Enric Balletbo i Serra, Guido Günther, Icenowy Zheng,
	Jacopo Mondi, Jyri Sarha, Lubomir Rintel, Maciej Purski,
	Peter Ujfalusi, Philippe Cornu, Russell King,
	Tomasz Stanislawski, Tomi Valkeinen

On 26/05/2020 03:14, Laurent Pinchart wrote:
> When validating a mode, bridges may need to do so in the context of a
> display, as specified by drm_display_info. An example is the meson
> dw-hdmi bridge that needs to consider the YUV 4:2:0 output format to
> perform clock calculations.
> 
> Bridges that need the display info currently retrieve it from the
> drm_connector created by the bridge. This gets in the way of moving
> connector creation out of bridge drivers. To make this possible, pass
> the drm_display_info to drm_bridge_funcs .mode_valid().
> 
> Changes to the bridge drivers have been performed with the following
> coccinelle semantic patch and have been compile-tested.
> 
> @ rule1 @
> identifier funcs;
> identifier fn;
> @@
>  struct drm_bridge_funcs funcs = {
>  	...,
>  	.mode_valid = fn
>  };
> 
> @ depends on rule1 @
> identifier rule1.fn;
> identifier bridge;
> identifier mode;
> @@
>  enum drm_mode_status fn(
>  	struct drm_bridge *bridge,
> +	const struct drm_display_info *info,
>  	const struct drm_display_mode *mode
>  )
>  {
>  	...
>  }
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  drivers/gpu/drm/bridge/analogix/analogix-anx6345.c | 1 +
>  drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c | 1 +
>  drivers/gpu/drm/bridge/cdns-dsi.c                  | 1 +
>  drivers/gpu/drm/bridge/chrontel-ch7033.c           | 1 +
>  drivers/gpu/drm/bridge/nwl-dsi.c                   | 1 +
>  drivers/gpu/drm/bridge/sii9234.c                   | 1 +
>  drivers/gpu/drm/bridge/sil-sii8620.c               | 1 +
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c          | 1 +
>  drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c      | 1 +
>  drivers/gpu/drm/bridge/tc358767.c                  | 1 +
>  drivers/gpu/drm/bridge/tc358768.c                  | 1 +
>  drivers/gpu/drm/bridge/thc63lvd1024.c              | 1 +
>  drivers/gpu/drm/bridge/ti-tfp410.c                 | 1 +
>  drivers/gpu/drm/drm_atomic_helper.c                | 3 ++-
>  drivers/gpu/drm/drm_bridge.c                       | 4 +++-
>  drivers/gpu/drm/drm_probe_helper.c                 | 4 +++-
>  drivers/gpu/drm/i2c/tda998x_drv.c                  | 1 +
>  drivers/gpu/drm/omapdrm/dss/dpi.c                  | 1 +
>  drivers/gpu/drm/omapdrm/dss/sdi.c                  | 1 +
>  drivers/gpu/drm/omapdrm/dss/venc.c                 | 1 +
>  include/drm/drm_bridge.h                           | 3 +++
>  21 files changed, 28 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c b/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c
> index 2bc6e4f85171..371f4a9f866d 100644
> --- a/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c
> +++ b/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c
> @@ -585,6 +585,7 @@ static int anx6345_bridge_attach(struct drm_bridge *bridge,
>  
>  static enum drm_mode_status
>  anx6345_bridge_mode_valid(struct drm_bridge *bridge,
> +			  const struct drm_display_info *info,
>  			  const struct drm_display_mode *mode)
>  {
>  	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
> diff --git a/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c b/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c
> index 0d5a5ad0c9ee..81debd02c169 100644
> --- a/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c
> +++ b/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c
> @@ -944,6 +944,7 @@ static int anx78xx_bridge_attach(struct drm_bridge *bridge,
>  
>  static enum drm_mode_status
>  anx78xx_bridge_mode_valid(struct drm_bridge *bridge,
> +			  const struct drm_display_info *info,
>  			  const struct drm_display_mode *mode)
>  {
>  	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
> diff --git a/drivers/gpu/drm/bridge/cdns-dsi.c b/drivers/gpu/drm/bridge/cdns-dsi.c
> index 69c3892caee5..76373e31df92 100644
> --- a/drivers/gpu/drm/bridge/cdns-dsi.c
> +++ b/drivers/gpu/drm/bridge/cdns-dsi.c
> @@ -663,6 +663,7 @@ static int cdns_dsi_bridge_attach(struct drm_bridge *bridge,
>  
>  static enum drm_mode_status
>  cdns_dsi_bridge_mode_valid(struct drm_bridge *bridge,
> +			   const struct drm_display_info *info,
>  			   const struct drm_display_mode *mode)
>  {
>  	struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge);
> diff --git a/drivers/gpu/drm/bridge/chrontel-ch7033.c b/drivers/gpu/drm/bridge/chrontel-ch7033.c
> index f8675d82974b..486f405c2e16 100644
> --- a/drivers/gpu/drm/bridge/chrontel-ch7033.c
> +++ b/drivers/gpu/drm/bridge/chrontel-ch7033.c
> @@ -317,6 +317,7 @@ static void ch7033_bridge_detach(struct drm_bridge *bridge)
>  }
>  
>  static enum drm_mode_status ch7033_bridge_mode_valid(struct drm_bridge *bridge,
> +				     const struct drm_display_info *info,
>  				     const struct drm_display_mode *mode)
>  {
>  	if (mode->clock > 165000)
> diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
> index b14d725bf609..77a79af70914 100644
> --- a/drivers/gpu/drm/bridge/nwl-dsi.c
> +++ b/drivers/gpu/drm/bridge/nwl-dsi.c
> @@ -818,6 +818,7 @@ static bool nwl_dsi_bridge_mode_fixup(struct drm_bridge *bridge,
>  
>  static enum drm_mode_status
>  nwl_dsi_bridge_mode_valid(struct drm_bridge *bridge,
> +			  const struct drm_display_info *info,
>  			  const struct drm_display_mode *mode)
>  {
>  	struct nwl_dsi *dsi = bridge_to_dsi(bridge);
> diff --git a/drivers/gpu/drm/bridge/sii9234.c b/drivers/gpu/drm/bridge/sii9234.c
> index b1258f0ed205..15c98a7bd81c 100644
> --- a/drivers/gpu/drm/bridge/sii9234.c
> +++ b/drivers/gpu/drm/bridge/sii9234.c
> @@ -873,6 +873,7 @@ static inline struct sii9234 *bridge_to_sii9234(struct drm_bridge *bridge)
>  }
>  
>  static enum drm_mode_status sii9234_mode_valid(struct drm_bridge *bridge,
> +					 const struct drm_display_info *info,
>  					 const struct drm_display_mode *mode)
>  {
>  	if (mode->clock > MHL1_MAX_CLK)
> diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
> index 92acd336aa89..7c0c93c7e61f 100644
> --- a/drivers/gpu/drm/bridge/sil-sii8620.c
> +++ b/drivers/gpu/drm/bridge/sil-sii8620.c
> @@ -2244,6 +2244,7 @@ static int sii8620_is_packing_required(struct sii8620 *ctx,
>  }
>  
>  static enum drm_mode_status sii8620_mode_valid(struct drm_bridge *bridge,
> +					 const struct drm_display_info *info,
>  					 const struct drm_display_mode *mode)
>  {
>  	struct sii8620 *ctx = bridge_to_sii8620(bridge);
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 30681398cfb0..b535354150db 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -2767,6 +2767,7 @@ static void dw_hdmi_bridge_detach(struct drm_bridge *bridge)
>  
>  static enum drm_mode_status
>  dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
> +			  const struct drm_display_info *info,
>  			  const struct drm_display_mode *mode)
>  {
>  	struct dw_hdmi *hdmi = bridge->driver_private;
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> index 5ef0f154aa7b..c223fb9a04cb 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> @@ -924,6 +924,7 @@ static void dw_mipi_dsi_bridge_enable(struct drm_bridge *bridge)
>  
>  static enum drm_mode_status
>  dw_mipi_dsi_bridge_mode_valid(struct drm_bridge *bridge,
> +			      const struct drm_display_info *info,
>  			      const struct drm_display_mode *mode)
>  {
>  	struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge);
> diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c
> index e4c0ea03ae3a..c2777b226c75 100644
> --- a/drivers/gpu/drm/bridge/tc358767.c
> +++ b/drivers/gpu/drm/bridge/tc358767.c
> @@ -1306,6 +1306,7 @@ static bool tc_bridge_mode_fixup(struct drm_bridge *bridge,
>  }
>  
>  static enum drm_mode_status tc_mode_valid(struct drm_bridge *bridge,
> +					  const struct drm_display_info *info,
>  					  const struct drm_display_mode *mode)
>  {
>  	struct tc_data *tc = bridge_to_tc(bridge);
> diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c
> index 6650fe4cfc20..4a463fadf743 100644
> --- a/drivers/gpu/drm/bridge/tc358768.c
> +++ b/drivers/gpu/drm/bridge/tc358768.c
> @@ -529,6 +529,7 @@ static int tc358768_bridge_attach(struct drm_bridge *bridge,
>  
>  static enum drm_mode_status
>  tc358768_bridge_mode_valid(struct drm_bridge *bridge,
> +			   const struct drm_display_info *info,
>  			   const struct drm_display_mode *mode)
>  {
>  	struct tc358768_priv *priv = bridge_to_tc358768(bridge);
> diff --git a/drivers/gpu/drm/bridge/thc63lvd1024.c b/drivers/gpu/drm/bridge/thc63lvd1024.c
> index 97d8129760e9..86b06975bfdd 100644
> --- a/drivers/gpu/drm/bridge/thc63lvd1024.c
> +++ b/drivers/gpu/drm/bridge/thc63lvd1024.c
> @@ -51,6 +51,7 @@ static int thc63_attach(struct drm_bridge *bridge,
>  }
>  
>  static enum drm_mode_status thc63_mode_valid(struct drm_bridge *bridge,
> +					const struct drm_display_info *info,
>  					const struct drm_display_mode *mode)
>  {
>  	struct thc63_dev *thc63 = to_thc63(bridge);
> diff --git a/drivers/gpu/drm/bridge/ti-tfp410.c b/drivers/gpu/drm/bridge/ti-tfp410.c
> index f065a96a0917..1f49aca06a9f 100644
> --- a/drivers/gpu/drm/bridge/ti-tfp410.c
> +++ b/drivers/gpu/drm/bridge/ti-tfp410.c
> @@ -192,6 +192,7 @@ static void tfp410_disable(struct drm_bridge *bridge)
>  }
>  
>  static enum drm_mode_status tfp410_mode_valid(struct drm_bridge *bridge,
> +					      const struct drm_display_info *info,
>  					      const struct drm_display_mode *mode)
>  {
>  	if (mode->clock < 25000)
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> index 85d163f16801..c1178518dc7a 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -506,7 +506,8 @@ static enum drm_mode_status mode_valid_path(struct drm_connector *connector,
>  	}
>  
>  	bridge = drm_bridge_chain_get_first_bridge(encoder);
> -	ret = drm_bridge_chain_mode_valid(bridge, mode);
> +	ret = drm_bridge_chain_mode_valid(bridge, &connector->display_info,
> +					  mode);
>  	if (ret != MODE_OK) {
>  		DRM_DEBUG_ATOMIC("[BRIDGE] mode_valid() failed\n");
>  		return ret;
> diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
> index fe1e3460b486..64f0effb52ac 100644
> --- a/drivers/gpu/drm/drm_bridge.c
> +++ b/drivers/gpu/drm/drm_bridge.c
> @@ -377,6 +377,7 @@ EXPORT_SYMBOL(drm_bridge_chain_mode_fixup);
>   * drm_bridge_chain_mode_valid - validate the mode against all bridges in the
>   *				 encoder chain.
>   * @bridge: bridge control structure
> + * @info: display info against which the mode shall be validated
>   * @mode: desired mode to be validated
>   *
>   * Calls &drm_bridge_funcs.mode_valid for all the bridges in the encoder
> @@ -390,6 +391,7 @@ EXPORT_SYMBOL(drm_bridge_chain_mode_fixup);
>   */
>  enum drm_mode_status
>  drm_bridge_chain_mode_valid(struct drm_bridge *bridge,
> +			    const struct drm_display_info *info,
>  			    const struct drm_display_mode *mode)
>  {
>  	struct drm_encoder *encoder;
> @@ -404,7 +406,7 @@ drm_bridge_chain_mode_valid(struct drm_bridge *bridge,
>  		if (!bridge->funcs->mode_valid)
>  			continue;
>  
> -		ret = bridge->funcs->mode_valid(bridge, mode);
> +		ret = bridge->funcs->mode_valid(bridge, info, mode);
>  		if (ret != MODE_OK)
>  			return ret;
>  	}
> diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
> index 576b4b7dcd89..f5d141e0400f 100644
> --- a/drivers/gpu/drm/drm_probe_helper.c
> +++ b/drivers/gpu/drm/drm_probe_helper.c
> @@ -114,7 +114,9 @@ drm_mode_validate_pipeline(struct drm_display_mode *mode,
>  		}
>  
>  		bridge = drm_bridge_chain_get_first_bridge(encoder);
> -		ret = drm_bridge_chain_mode_valid(bridge, mode);
> +		ret = drm_bridge_chain_mode_valid(bridge,
> +						  &connector->display_info,
> +						  mode);
>  		if (ret != MODE_OK) {
>  			/* There is also no point in continuing for crtc check
>  			 * here. */
> diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
> index 9517f522dcb9..50fd119a5276 100644
> --- a/drivers/gpu/drm/i2c/tda998x_drv.c
> +++ b/drivers/gpu/drm/i2c/tda998x_drv.c
> @@ -1379,6 +1379,7 @@ static void tda998x_bridge_detach(struct drm_bridge *bridge)
>  }
>  
>  static enum drm_mode_status tda998x_bridge_mode_valid(struct drm_bridge *bridge,
> +				     const struct drm_display_info *info,
>  				     const struct drm_display_mode *mode)
>  {
>  	/* TDA19988 dotclock can go up to 165MHz */
> diff --git a/drivers/gpu/drm/omapdrm/dss/dpi.c b/drivers/gpu/drm/omapdrm/dss/dpi.c
> index 5110acb0c6c1..1d2992daef40 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dpi.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dpi.c
> @@ -434,6 +434,7 @@ static int dpi_bridge_attach(struct drm_bridge *bridge,
>  
>  static enum drm_mode_status
>  dpi_bridge_mode_valid(struct drm_bridge *bridge,
> +		       const struct drm_display_info *info,
>  		       const struct drm_display_mode *mode)
>  {
>  	struct dpi_data *dpi = drm_bridge_to_dpi(bridge);
> diff --git a/drivers/gpu/drm/omapdrm/dss/sdi.c b/drivers/gpu/drm/omapdrm/dss/sdi.c
> index 417a8740ad0a..033fd30074b0 100644
> --- a/drivers/gpu/drm/omapdrm/dss/sdi.c
> +++ b/drivers/gpu/drm/omapdrm/dss/sdi.c
> @@ -140,6 +140,7 @@ static int sdi_bridge_attach(struct drm_bridge *bridge,
>  
>  static enum drm_mode_status
>  sdi_bridge_mode_valid(struct drm_bridge *bridge,
> +		      const struct drm_display_info *info,
>  		      const struct drm_display_mode *mode)
>  {
>  	struct sdi_device *sdi = drm_bridge_to_sdi(bridge);
> diff --git a/drivers/gpu/drm/omapdrm/dss/venc.c b/drivers/gpu/drm/omapdrm/dss/venc.c
> index 9701843ccf09..4406ce2a08b4 100644
> --- a/drivers/gpu/drm/omapdrm/dss/venc.c
> +++ b/drivers/gpu/drm/omapdrm/dss/venc.c
> @@ -548,6 +548,7 @@ static int venc_bridge_attach(struct drm_bridge *bridge,
>  
>  static enum drm_mode_status
>  venc_bridge_mode_valid(struct drm_bridge *bridge,
> +		       const struct drm_display_info *info,
>  		       const struct drm_display_mode *mode)
>  {
>  	switch (venc_get_videomode(mode)) {
> diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
> index ea2aa5ebae34..e3d7f36d8c39 100644
> --- a/include/drm/drm_bridge.h
> +++ b/include/drm/drm_bridge.h
> @@ -35,6 +35,7 @@
>  struct drm_bridge;
>  struct drm_bridge_timings;
>  struct drm_connector;
> +struct drm_display_info;
>  struct drm_panel;
>  struct edid;
>  struct i2c_adapter;
> @@ -112,6 +113,7 @@ struct drm_bridge_funcs {
>  	 * drm_mode_status Enum
>  	 */
>  	enum drm_mode_status (*mode_valid)(struct drm_bridge *bridge,
> +					   const struct drm_display_info *info,
>  					   const struct drm_display_mode *mode);
>  
>  	/**
> @@ -836,6 +838,7 @@ bool drm_bridge_chain_mode_fixup(struct drm_bridge *bridge,
>  				 struct drm_display_mode *adjusted_mode);
>  enum drm_mode_status
>  drm_bridge_chain_mode_valid(struct drm_bridge *bridge,
> +			    const struct drm_display_info *info,
>  			    const struct drm_display_mode *mode);
>  void drm_bridge_chain_disable(struct drm_bridge *bridge);
>  void drm_bridge_chain_post_disable(struct drm_bridge *bridge);
> 

Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>

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

* Re: [PATCH 10/27] drm: bridge: Pass drm_display_info to drm_bridge_funcs .mode_valid()
  2020-05-26  1:14 ` [PATCH 10/27] drm: bridge: Pass drm_display_info to drm_bridge_funcs .mode_valid() Laurent Pinchart
  2020-05-26 12:51   ` Neil Armstrong
@ 2020-05-26 12:59   ` Boris Brezillon
  2020-05-26 14:05   ` Guido Günther
  2 siblings, 0 replies; 69+ messages in thread
From: Boris Brezillon @ 2020-05-26 12:59 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: dri-devel, linux-renesas-soc, Andrzej Hajda, Jernej Skrabec,
	Jonas Karlman, Neil Armstrong, Sam Ravnborg, Kieran Bingham,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Andrey Gusakov, Chris Zhong, Enric Balletbo i Serra,
	Guido Günther, Icenowy Zheng, Jacopo Mondi, Jyri Sarha,
	Lubomir Rintel, Maciej Purski, Peter Ujfalusi, Philippe Cornu,
	Russell King, Tomasz Stanislawski, Tomi Valkeinen

On Tue, 26 May 2020 04:14:48 +0300
Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> wrote:

> When validating a mode, bridges may need to do so in the context of a
> display, as specified by drm_display_info. An example is the meson
> dw-hdmi bridge that needs to consider the YUV 4:2:0 output format to
> perform clock calculations.
> 
> Bridges that need the display info currently retrieve it from the
> drm_connector created by the bridge. This gets in the way of moving
> connector creation out of bridge drivers. To make this possible, pass
> the drm_display_info to drm_bridge_funcs .mode_valid().
> 
> Changes to the bridge drivers have been performed with the following
> coccinelle semantic patch and have been compile-tested.
> 
> @ rule1 @
> identifier funcs;
> identifier fn;
> @@
>  struct drm_bridge_funcs funcs = {
>  	...,
>  	.mode_valid = fn
>  };
> 
> @ depends on rule1 @
> identifier rule1.fn;
> identifier bridge;
> identifier mode;
> @@
>  enum drm_mode_status fn(
>  	struct drm_bridge *bridge,
> +	const struct drm_display_info *info,
>  	const struct drm_display_mode *mode
>  )
>  {
>  	...
>  }
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>

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

* Re: [PATCH 10/27] drm: bridge: Pass drm_display_info to drm_bridge_funcs .mode_valid()
  2020-05-26  1:14 ` [PATCH 10/27] drm: bridge: Pass drm_display_info to drm_bridge_funcs .mode_valid() Laurent Pinchart
  2020-05-26 12:51   ` Neil Armstrong
  2020-05-26 12:59   ` Boris Brezillon
@ 2020-05-26 14:05   ` Guido Günther
  2 siblings, 0 replies; 69+ messages in thread
From: Guido Günther @ 2020-05-26 14:05 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: dri-devel, linux-renesas-soc, Andrzej Hajda, Jernej Skrabec,
	Jonas Karlman, Neil Armstrong, Sam Ravnborg, Kieran Bingham,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Andrey Gusakov, Boris Brezillon, Chris Zhong,
	Enric Balletbo i Serra, Icenowy Zheng, Jacopo Mondi, Jyri Sarha,
	Lubomir Rintel, Maciej Purski, Peter Ujfalusi, Philippe Cornu,
	Russell King, Tomasz Stanislawski, Tomi Valkeinen

Hi,
On Tue, May 26, 2020 at 04:14:48AM +0300, Laurent Pinchart wrote:
> When validating a mode, bridges may need to do so in the context of a
> display, as specified by drm_display_info. An example is the meson
> dw-hdmi bridge that needs to consider the YUV 4:2:0 output format to
> perform clock calculations.
> 
> Bridges that need the display info currently retrieve it from the
> drm_connector created by the bridge. This gets in the way of moving
> connector creation out of bridge drivers. To make this possible, pass
> the drm_display_info to drm_bridge_funcs .mode_valid().
> 
> Changes to the bridge drivers have been performed with the following
> coccinelle semantic patch and have been compile-tested.
> 
> @ rule1 @
> identifier funcs;
> identifier fn;
> @@
>  struct drm_bridge_funcs funcs = {
>  	...,
>  	.mode_valid = fn
>  };
> 
> @ depends on rule1 @
> identifier rule1.fn;
> identifier bridge;
> identifier mode;
> @@
>  enum drm_mode_status fn(
>  	struct drm_bridge *bridge,
> +	const struct drm_display_info *info,
>  	const struct drm_display_mode *mode
>  )
>  {
>  	...
>  }
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  drivers/gpu/drm/bridge/analogix/analogix-anx6345.c | 1 +
>  drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c | 1 +
>  drivers/gpu/drm/bridge/cdns-dsi.c                  | 1 +
>  drivers/gpu/drm/bridge/chrontel-ch7033.c           | 1 +
>  drivers/gpu/drm/bridge/nwl-dsi.c                   | 1 +
>  drivers/gpu/drm/bridge/sii9234.c                   | 1 +
>  drivers/gpu/drm/bridge/sil-sii8620.c               | 1 +
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c          | 1 +
>  drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c      | 1 +
>  drivers/gpu/drm/bridge/tc358767.c                  | 1 +
>  drivers/gpu/drm/bridge/tc358768.c                  | 1 +
>  drivers/gpu/drm/bridge/thc63lvd1024.c              | 1 +
>  drivers/gpu/drm/bridge/ti-tfp410.c                 | 1 +
>  drivers/gpu/drm/drm_atomic_helper.c                | 3 ++-
>  drivers/gpu/drm/drm_bridge.c                       | 4 +++-
>  drivers/gpu/drm/drm_probe_helper.c                 | 4 +++-
>  drivers/gpu/drm/i2c/tda998x_drv.c                  | 1 +
>  drivers/gpu/drm/omapdrm/dss/dpi.c                  | 1 +
>  drivers/gpu/drm/omapdrm/dss/sdi.c                  | 1 +
>  drivers/gpu/drm/omapdrm/dss/venc.c                 | 1 +
>  include/drm/drm_bridge.h                           | 3 +++
>  21 files changed, 28 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c b/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c
> index 2bc6e4f85171..371f4a9f866d 100644
> --- a/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c
> +++ b/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c
> @@ -585,6 +585,7 @@ static int anx6345_bridge_attach(struct drm_bridge *bridge,
>  
>  static enum drm_mode_status
>  anx6345_bridge_mode_valid(struct drm_bridge *bridge,
> +			  const struct drm_display_info *info,
>  			  const struct drm_display_mode *mode)
>  {
>  	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
> diff --git a/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c b/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c
> index 0d5a5ad0c9ee..81debd02c169 100644
> --- a/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c
> +++ b/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c
> @@ -944,6 +944,7 @@ static int anx78xx_bridge_attach(struct drm_bridge *bridge,
>  
>  static enum drm_mode_status
>  anx78xx_bridge_mode_valid(struct drm_bridge *bridge,
> +			  const struct drm_display_info *info,
>  			  const struct drm_display_mode *mode)
>  {
>  	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
> diff --git a/drivers/gpu/drm/bridge/cdns-dsi.c b/drivers/gpu/drm/bridge/cdns-dsi.c
> index 69c3892caee5..76373e31df92 100644
> --- a/drivers/gpu/drm/bridge/cdns-dsi.c
> +++ b/drivers/gpu/drm/bridge/cdns-dsi.c
> @@ -663,6 +663,7 @@ static int cdns_dsi_bridge_attach(struct drm_bridge *bridge,
>  
>  static enum drm_mode_status
>  cdns_dsi_bridge_mode_valid(struct drm_bridge *bridge,
> +			   const struct drm_display_info *info,
>  			   const struct drm_display_mode *mode)
>  {
>  	struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge);
> diff --git a/drivers/gpu/drm/bridge/chrontel-ch7033.c b/drivers/gpu/drm/bridge/chrontel-ch7033.c
> index f8675d82974b..486f405c2e16 100644
> --- a/drivers/gpu/drm/bridge/chrontel-ch7033.c
> +++ b/drivers/gpu/drm/bridge/chrontel-ch7033.c
> @@ -317,6 +317,7 @@ static void ch7033_bridge_detach(struct drm_bridge *bridge)
>  }
>  
>  static enum drm_mode_status ch7033_bridge_mode_valid(struct drm_bridge *bridge,
> +				     const struct drm_display_info *info,
>  				     const struct drm_display_mode *mode)
>  {
>  	if (mode->clock > 165000)
> diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
> index b14d725bf609..77a79af70914 100644
> --- a/drivers/gpu/drm/bridge/nwl-dsi.c
> +++ b/drivers/gpu/drm/bridge/nwl-dsi.c
> @@ -818,6 +818,7 @@ static bool nwl_dsi_bridge_mode_fixup(struct drm_bridge *bridge,
>  
>  static enum drm_mode_status
>  nwl_dsi_bridge_mode_valid(struct drm_bridge *bridge,
> +			  const struct drm_display_info *info,
>  			  const struct drm_display_mode *mode)
>  {
>  	struct nwl_dsi *dsi = bridge_to_dsi(bridge);
> diff --git a/drivers/gpu/drm/bridge/sii9234.c b/drivers/gpu/drm/bridge/sii9234.c
> index b1258f0ed205..15c98a7bd81c 100644
> --- a/drivers/gpu/drm/bridge/sii9234.c
> +++ b/drivers/gpu/drm/bridge/sii9234.c
> @@ -873,6 +873,7 @@ static inline struct sii9234 *bridge_to_sii9234(struct drm_bridge *bridge)
>  }
>  
>  static enum drm_mode_status sii9234_mode_valid(struct drm_bridge *bridge,
> +					 const struct drm_display_info *info,
>  					 const struct drm_display_mode *mode)
>  {
>  	if (mode->clock > MHL1_MAX_CLK)
> diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
> index 92acd336aa89..7c0c93c7e61f 100644
> --- a/drivers/gpu/drm/bridge/sil-sii8620.c
> +++ b/drivers/gpu/drm/bridge/sil-sii8620.c
> @@ -2244,6 +2244,7 @@ static int sii8620_is_packing_required(struct sii8620 *ctx,
>  }
>  
>  static enum drm_mode_status sii8620_mode_valid(struct drm_bridge *bridge,
> +					 const struct drm_display_info *info,
>  					 const struct drm_display_mode *mode)
>  {
>  	struct sii8620 *ctx = bridge_to_sii8620(bridge);
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 30681398cfb0..b535354150db 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -2767,6 +2767,7 @@ static void dw_hdmi_bridge_detach(struct drm_bridge *bridge)
>  
>  static enum drm_mode_status
>  dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
> +			  const struct drm_display_info *info,
>  			  const struct drm_display_mode *mode)
>  {
>  	struct dw_hdmi *hdmi = bridge->driver_private;
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> index 5ef0f154aa7b..c223fb9a04cb 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> @@ -924,6 +924,7 @@ static void dw_mipi_dsi_bridge_enable(struct drm_bridge *bridge)
>  
>  static enum drm_mode_status
>  dw_mipi_dsi_bridge_mode_valid(struct drm_bridge *bridge,
> +			      const struct drm_display_info *info,
>  			      const struct drm_display_mode *mode)
>  {
>  	struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge);
> diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c
> index e4c0ea03ae3a..c2777b226c75 100644
> --- a/drivers/gpu/drm/bridge/tc358767.c
> +++ b/drivers/gpu/drm/bridge/tc358767.c
> @@ -1306,6 +1306,7 @@ static bool tc_bridge_mode_fixup(struct drm_bridge *bridge,
>  }
>  
>  static enum drm_mode_status tc_mode_valid(struct drm_bridge *bridge,
> +					  const struct drm_display_info *info,
>  					  const struct drm_display_mode *mode)
>  {
>  	struct tc_data *tc = bridge_to_tc(bridge);
> diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c
> index 6650fe4cfc20..4a463fadf743 100644
> --- a/drivers/gpu/drm/bridge/tc358768.c
> +++ b/drivers/gpu/drm/bridge/tc358768.c
> @@ -529,6 +529,7 @@ static int tc358768_bridge_attach(struct drm_bridge *bridge,
>  
>  static enum drm_mode_status
>  tc358768_bridge_mode_valid(struct drm_bridge *bridge,
> +			   const struct drm_display_info *info,
>  			   const struct drm_display_mode *mode)
>  {
>  	struct tc358768_priv *priv = bridge_to_tc358768(bridge);
> diff --git a/drivers/gpu/drm/bridge/thc63lvd1024.c b/drivers/gpu/drm/bridge/thc63lvd1024.c
> index 97d8129760e9..86b06975bfdd 100644
> --- a/drivers/gpu/drm/bridge/thc63lvd1024.c
> +++ b/drivers/gpu/drm/bridge/thc63lvd1024.c
> @@ -51,6 +51,7 @@ static int thc63_attach(struct drm_bridge *bridge,
>  }
>  
>  static enum drm_mode_status thc63_mode_valid(struct drm_bridge *bridge,
> +					const struct drm_display_info *info,
>  					const struct drm_display_mode *mode)
>  {
>  	struct thc63_dev *thc63 = to_thc63(bridge);
> diff --git a/drivers/gpu/drm/bridge/ti-tfp410.c b/drivers/gpu/drm/bridge/ti-tfp410.c
> index f065a96a0917..1f49aca06a9f 100644
> --- a/drivers/gpu/drm/bridge/ti-tfp410.c
> +++ b/drivers/gpu/drm/bridge/ti-tfp410.c
> @@ -192,6 +192,7 @@ static void tfp410_disable(struct drm_bridge *bridge)
>  }
>  
>  static enum drm_mode_status tfp410_mode_valid(struct drm_bridge *bridge,
> +					      const struct drm_display_info *info,
>  					      const struct drm_display_mode *mode)
>  {
>  	if (mode->clock < 25000)
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> index 85d163f16801..c1178518dc7a 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -506,7 +506,8 @@ static enum drm_mode_status mode_valid_path(struct drm_connector *connector,
>  	}
>  
>  	bridge = drm_bridge_chain_get_first_bridge(encoder);
> -	ret = drm_bridge_chain_mode_valid(bridge, mode);
> +	ret = drm_bridge_chain_mode_valid(bridge, &connector->display_info,
> +					  mode);
>  	if (ret != MODE_OK) {
>  		DRM_DEBUG_ATOMIC("[BRIDGE] mode_valid() failed\n");
>  		return ret;
> diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
> index fe1e3460b486..64f0effb52ac 100644
> --- a/drivers/gpu/drm/drm_bridge.c
> +++ b/drivers/gpu/drm/drm_bridge.c
> @@ -377,6 +377,7 @@ EXPORT_SYMBOL(drm_bridge_chain_mode_fixup);
>   * drm_bridge_chain_mode_valid - validate the mode against all bridges in the
>   *				 encoder chain.
>   * @bridge: bridge control structure
> + * @info: display info against which the mode shall be validated
>   * @mode: desired mode to be validated
>   *
>   * Calls &drm_bridge_funcs.mode_valid for all the bridges in the encoder
> @@ -390,6 +391,7 @@ EXPORT_SYMBOL(drm_bridge_chain_mode_fixup);
>   */
>  enum drm_mode_status
>  drm_bridge_chain_mode_valid(struct drm_bridge *bridge,
> +			    const struct drm_display_info *info,
>  			    const struct drm_display_mode *mode)
>  {
>  	struct drm_encoder *encoder;
> @@ -404,7 +406,7 @@ drm_bridge_chain_mode_valid(struct drm_bridge *bridge,
>  		if (!bridge->funcs->mode_valid)
>  			continue;
>  
> -		ret = bridge->funcs->mode_valid(bridge, mode);
> +		ret = bridge->funcs->mode_valid(bridge, info, mode);
>  		if (ret != MODE_OK)
>  			return ret;
>  	}
> diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
> index 576b4b7dcd89..f5d141e0400f 100644
> --- a/drivers/gpu/drm/drm_probe_helper.c
> +++ b/drivers/gpu/drm/drm_probe_helper.c
> @@ -114,7 +114,9 @@ drm_mode_validate_pipeline(struct drm_display_mode *mode,
>  		}
>  
>  		bridge = drm_bridge_chain_get_first_bridge(encoder);
> -		ret = drm_bridge_chain_mode_valid(bridge, mode);
> +		ret = drm_bridge_chain_mode_valid(bridge,
> +						  &connector->display_info,
> +						  mode);
>  		if (ret != MODE_OK) {
>  			/* There is also no point in continuing for crtc check
>  			 * here. */
> diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
> index 9517f522dcb9..50fd119a5276 100644
> --- a/drivers/gpu/drm/i2c/tda998x_drv.c
> +++ b/drivers/gpu/drm/i2c/tda998x_drv.c
> @@ -1379,6 +1379,7 @@ static void tda998x_bridge_detach(struct drm_bridge *bridge)
>  }
>  
>  static enum drm_mode_status tda998x_bridge_mode_valid(struct drm_bridge *bridge,
> +				     const struct drm_display_info *info,
>  				     const struct drm_display_mode *mode)
>  {
>  	/* TDA19988 dotclock can go up to 165MHz */
> diff --git a/drivers/gpu/drm/omapdrm/dss/dpi.c b/drivers/gpu/drm/omapdrm/dss/dpi.c
> index 5110acb0c6c1..1d2992daef40 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dpi.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dpi.c
> @@ -434,6 +434,7 @@ static int dpi_bridge_attach(struct drm_bridge *bridge,
>  
>  static enum drm_mode_status
>  dpi_bridge_mode_valid(struct drm_bridge *bridge,
> +		       const struct drm_display_info *info,
>  		       const struct drm_display_mode *mode)
>  {
>  	struct dpi_data *dpi = drm_bridge_to_dpi(bridge);
> diff --git a/drivers/gpu/drm/omapdrm/dss/sdi.c b/drivers/gpu/drm/omapdrm/dss/sdi.c
> index 417a8740ad0a..033fd30074b0 100644
> --- a/drivers/gpu/drm/omapdrm/dss/sdi.c
> +++ b/drivers/gpu/drm/omapdrm/dss/sdi.c
> @@ -140,6 +140,7 @@ static int sdi_bridge_attach(struct drm_bridge *bridge,
>  
>  static enum drm_mode_status
>  sdi_bridge_mode_valid(struct drm_bridge *bridge,
> +		      const struct drm_display_info *info,
>  		      const struct drm_display_mode *mode)
>  {
>  	struct sdi_device *sdi = drm_bridge_to_sdi(bridge);
> diff --git a/drivers/gpu/drm/omapdrm/dss/venc.c b/drivers/gpu/drm/omapdrm/dss/venc.c
> index 9701843ccf09..4406ce2a08b4 100644
> --- a/drivers/gpu/drm/omapdrm/dss/venc.c
> +++ b/drivers/gpu/drm/omapdrm/dss/venc.c
> @@ -548,6 +548,7 @@ static int venc_bridge_attach(struct drm_bridge *bridge,
>  
>  static enum drm_mode_status
>  venc_bridge_mode_valid(struct drm_bridge *bridge,
> +		       const struct drm_display_info *info,
>  		       const struct drm_display_mode *mode)
>  {
>  	switch (venc_get_videomode(mode)) {
> diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
> index ea2aa5ebae34..e3d7f36d8c39 100644
> --- a/include/drm/drm_bridge.h
> +++ b/include/drm/drm_bridge.h
> @@ -35,6 +35,7 @@
>  struct drm_bridge;
>  struct drm_bridge_timings;
>  struct drm_connector;
> +struct drm_display_info;
>  struct drm_panel;
>  struct edid;
>  struct i2c_adapter;
> @@ -112,6 +113,7 @@ struct drm_bridge_funcs {
>  	 * drm_mode_status Enum
>  	 */
>  	enum drm_mode_status (*mode_valid)(struct drm_bridge *bridge,
> +					   const struct drm_display_info *info,
>  					   const struct drm_display_mode *mode);
>  
>  	/**
> @@ -836,6 +838,7 @@ bool drm_bridge_chain_mode_fixup(struct drm_bridge *bridge,
>  				 struct drm_display_mode *adjusted_mode);
>  enum drm_mode_status
>  drm_bridge_chain_mode_valid(struct drm_bridge *bridge,
> +			    const struct drm_display_info *info,
>  			    const struct drm_display_mode *mode);
>  void drm_bridge_chain_disable(struct drm_bridge *bridge);
>  void drm_bridge_chain_post_disable(struct drm_bridge *bridge);
> -- 
> Regards,
> 
> Laurent Pinchart
> 

for the nwl-dsi part:

Reviewed-by: Guido Günther <agx@sigxcpu.org> 

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

* Re: [PATCH 23/27] drm: bridge: dw-hdmi: Attach to next bridge if available
  2020-05-26 12:50   ` Neil Armstrong
@ 2020-05-26 14:23     ` Jonas Karlman
  2020-06-07  1:24       ` Laurent Pinchart
  2020-06-07  1:22     ` Laurent Pinchart
  1 sibling, 1 reply; 69+ messages in thread
From: Jonas Karlman @ 2020-05-26 14:23 UTC (permalink / raw)
  To: Neil Armstrong, Laurent Pinchart, dri-devel
  Cc: Jernej Skrabec, Kieran Bingham, linux-renesas-soc, Andrzej Hajda,
	Sam Ravnborg

On 2020-05-26 14:50, Neil Armstrong wrote:
> On 26/05/2020 03:15, Laurent Pinchart wrote:
>> On all platforms except i.MX and Rockchip, the dw-hdmi DT bindings
>> require a video output port connected to an HDMI sink (most likely an
>> HDMI connector, in rare cases another bridges converting HDMI to another
>> protocol). For those platforms, retrieve the next bridge and attach it
>> from the dw-hdmi bridge attach handler.
>>
>> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
>> ---
>>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 52 ++++++++++++++++++++++-
>>  include/drm/bridge/dw_hdmi.h              |  2 +
>>  2 files changed, 53 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>> index 6148a022569a..512e67bb1c32 100644
>> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>> @@ -143,6 +143,7 @@ struct dw_hdmi_phy_data {
>>  struct dw_hdmi {
>>  	struct drm_connector connector;
>>  	struct drm_bridge bridge;
>> +	struct drm_bridge *next_bridge;
>>  
>>  	unsigned int version;
>>  
>> @@ -2797,7 +2798,8 @@ static int dw_hdmi_bridge_attach(struct drm_bridge *bridge,
>>  	struct dw_hdmi *hdmi = bridge->driver_private;
>>  
>>  	if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
>> -		return 0;
>> +		return drm_bridge_attach(bridge->encoder, hdmi->next_bridge,
>> +					 bridge, flags);
>>  
>>  	return dw_hdmi_connector_create(hdmi);
>>  }
>> @@ -3179,6 +3181,50 @@ static void dw_hdmi_init_hw(struct dw_hdmi *hdmi)
>>  		hdmi->phy.ops->setup_hpd(hdmi, hdmi->phy.data);
>>  }
>>  
>> +static int dw_hdmi_parse_dt(struct dw_hdmi *hdmi)
>> +{
>> +	struct device_node *endpoint;
>> +	struct device_node *remote;
>> +
>> +	if (!hdmi->plat_data->output_port)
>> +		return 0;
>> +
>> +	endpoint = of_graph_get_endpoint_by_regs(hdmi->dev->of_node,
>> +						 hdmi->plat_data->output_port,
>> +						 -1);
>> +	if (!endpoint) {
>> +		/*
>> +		 * Don't treat this as a fatal error as the Rockchip DW-HDMI
>> +		 * binding doesn't make the output port mandatory.
>> +		 */
>> +		dev_dbg(hdmi->dev, "Missing endpoint in port@%u\n",
>> +			hdmi->plat_data->output_port);
>> +		return 0;

After this series only rcar-du set output_port so this block should only
run for rcar-du, for platforms without output_port the if-statement
for !hdmi->plat_data->output_port already return success so you can
probably return fatal error here.

The comment is a little bit misleading because of the if-statement above
or am I missing something?

Regards,
Jonas

>> +	}
>> +
>> +	remote = of_graph_get_remote_port_parent(endpoint);
>> +	of_node_put(endpoint);
>> +	if (!remote) {
>> +		dev_err(hdmi->dev, "Endpoint in port@%u unconnected\n",
>> +			hdmi->plat_data->output_port);
>> +		return -ENODEV;
>> +	}
>> +
>> +	if (!of_device_is_available(remote)) {
>> +		dev_err(hdmi->dev, "port@%u remote device is disabled\n",
>> +			hdmi->plat_data->output_port);
>> +		of_node_put(remote);
>> +		return -ENODEV;
>> +	}
>> +
>> +	hdmi->next_bridge = of_drm_find_bridge(remote);
>> +	of_node_put(remote);
>> +	if (!hdmi->next_bridge)
>> +		return -EPROBE_DEFER;
> 
> I'll be safer to print a warn for now until all platforms has been tested.
> 
>> +
>> +	return 0;
>> +}
>> +
>>  static struct dw_hdmi *
>>  __dw_hdmi_probe(struct platform_device *pdev,
>>  		const struct dw_hdmi_plat_data *plat_data)
>> @@ -3216,6 +3262,10 @@ __dw_hdmi_probe(struct platform_device *pdev,
>>  	mutex_init(&hdmi->cec_notifier_mutex);
>>  	spin_lock_init(&hdmi->audio_lock);
>>  
>> +	ret = dw_hdmi_parse_dt(hdmi);
>> +	if (ret < 0)
>> +		return ERR_PTR(ret);
>> +
>>  	ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0);
>>  	if (ddc_node) {
>>  		hdmi->ddc = of_get_i2c_adapter_by_node(ddc_node);
>> diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
>> index ea34ca146b82..8ebeb65d6371 100644
>> --- a/include/drm/bridge/dw_hdmi.h
>> +++ b/include/drm/bridge/dw_hdmi.h
>> @@ -126,6 +126,8 @@ struct dw_hdmi_phy_ops {
>>  struct dw_hdmi_plat_data {
>>  	struct regmap *regm;
>>  
>> +	unsigned int output_port;
>> +
>>  	unsigned long input_bus_encoding;
>>  	bool use_drm_infoframe;
>>  	bool ycbcr_420_allowed;
>>
> 
> I must check on meson, since I'm not sure for now if the connector probes.
> 
> Anyway, this looks fine.
> 
> Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
> 

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

* Re: [PATCH 22/27] drm: bridge: dw-hdmi: Make connector creation optional
  2020-05-26 12:35   ` Neil Armstrong
@ 2020-06-07  1:19     ` Laurent Pinchart
  0 siblings, 0 replies; 69+ messages in thread
From: Laurent Pinchart @ 2020-06-07  1:19 UTC (permalink / raw)
  To: Neil Armstrong
  Cc: Laurent Pinchart, dri-devel, linux-renesas-soc, Andrzej Hajda,
	Jernej Skrabec, Jonas Karlman, Sam Ravnborg, Kieran Bingham

Hi Neil,

On Tue, May 26, 2020 at 02:35:19PM +0200, Neil Armstrong wrote:
> On 26/05/2020 03:15, Laurent Pinchart wrote:
> > Implement the drm_bridge_funcs .detect() and .get_edid() operations, and
> > call drm_bridge_hpd_notify() notify to report HPD. This provides the
> > necessary API to support disabling connector creation, do so by
> > accepting DRM_BRIDGE_ATTACH_NO_CONNECTOR in dw_hdmi_bridge_attach().
> > 
> > Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> > ---
> >  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 104 +++++++++++++++-------
> >  1 file changed, 74 insertions(+), 30 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> > index b69c14b9de62..6148a022569a 100644
> > --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> > +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> > @@ -2323,15 +2323,8 @@ static void dw_hdmi_update_phy_mask(struct dw_hdmi *hdmi)
> >  					  hdmi->rxsense);
> >  }
> >  
> > -/* -----------------------------------------------------------------------------
> > - * DRM Connector Operations
> > - */
> > -
> > -static enum drm_connector_status
> > -dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
> > +static enum drm_connector_status dw_hdmi_detect(struct dw_hdmi *hdmi)
> >  {
> > -	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
> > -					     connector);
> >  	enum drm_connector_status result;
> >  
> >  	mutex_lock(&hdmi->mutex);
> > @@ -2354,31 +2347,57 @@ dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
> >  	return result;
> >  }
> >  
> > -static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
> > +static struct edid *dw_hdmi_get_edid(struct dw_hdmi *hdmi,
> > +				     struct drm_connector *connector)
> >  {
> > -	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
> > -					     connector);
> >  	struct edid *edid;
> > -	int ret = 0;
> >  
> >  	if (!hdmi->ddc)
> > -		return 0;
> > +		return NULL;
> >  
> >  	edid = drm_get_edid(connector, hdmi->ddc);
> > -	if (edid) {
> > -		dev_dbg(hdmi->dev, "got edid: width[%d] x height[%d]\n",
> > -			edid->width_cm, edid->height_cm);
> > -
> > -		hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid);
> > -		hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
> > -		drm_connector_update_edid_property(connector, edid);
> > -		cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid);
> > -		ret = drm_add_edid_modes(connector, edid);
> > -		kfree(edid);
> > -	} else {
> > +	if (!edid) {
> >  		dev_dbg(hdmi->dev, "failed to get edid\n");
> > +		return NULL;
> >  	}
> >  
> > +	dev_dbg(hdmi->dev, "got edid: width[%d] x height[%d]\n",
> > +		edid->width_cm, edid->height_cm);
> > +
> > +	hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid);
> > +	hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
> > +
> > +	return edid;
> > +}
> > +
> > +/* -----------------------------------------------------------------------------
> > + * DRM Connector Operations
> > + */
> > +
> > +static enum drm_connector_status
> > +dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
> > +{
> > +	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
> > +					     connector);
> > +	return dw_hdmi_detect(hdmi);
> > +}
> > +
> > +static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
> > +{
> > +	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
> > +					     connector);
> > +	struct edid *edid;
> > +	int ret;
> > +
> > +	edid = dw_hdmi_get_edid(hdmi, connector);
> > +	if (!edid)
> > +		return 0;
> > +
> > +	drm_connector_update_edid_property(connector, edid);
> > +	cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid);
> > +	ret = drm_add_edid_modes(connector, edid);
> > +	kfree(edid);
> > +
> >  	return ret;
> >  }
> >  
> > @@ -2777,10 +2796,8 @@ static int dw_hdmi_bridge_attach(struct drm_bridge *bridge,
> >  {
> >  	struct dw_hdmi *hdmi = bridge->driver_private;
> >  
> > -	if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {
> > -		DRM_ERROR("Fix bridge driver to make connector optional!");
> > -		return -EINVAL;
> > -	}
> > +	if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
> > +		return 0;
> >  
> >  	return dw_hdmi_connector_create(hdmi);
> >  }
> > @@ -2860,6 +2877,21 @@ static void dw_hdmi_bridge_atomic_enable(struct drm_bridge *bridge,
> >  	mutex_unlock(&hdmi->mutex);
> >  }
> >  
> > +static enum drm_connector_status dw_hdmi_bridge_detect(struct drm_bridge *bridge)
> > +{
> > +	struct dw_hdmi *hdmi = bridge->driver_private;
> > +
> > +	return dw_hdmi_detect(hdmi);
> > +}
> > +
> > +static struct edid *dw_hdmi_bridge_get_edid(struct drm_bridge *bridge,
> > +					    struct drm_connector *connector)
> > +{
> > +	struct dw_hdmi *hdmi = bridge->driver_private;
> > +
> > +	return dw_hdmi_get_edid(hdmi, connector);
> > +}
> > +
> >  static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = {
> >  	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
> >  	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
> > @@ -2873,6 +2905,8 @@ static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = {
> >  	.atomic_disable = dw_hdmi_bridge_atomic_disable,
> >  	.mode_set = dw_hdmi_bridge_mode_set,
> >  	.mode_valid = dw_hdmi_bridge_mode_valid,
> > +	.detect = dw_hdmi_bridge_detect,
> > +	.get_edid = dw_hdmi_bridge_get_edid,
> >  };
> >  
> >  /* -----------------------------------------------------------------------------
> > @@ -2988,10 +3022,18 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
> >  	}
> >  
> >  	if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
> > +		enum drm_connector_status status = phy_int_pol & HDMI_PHY_HPD
> > +						 ? connector_status_connected
> > +						 : connector_status_disconnected;
> > +
> >  		dev_dbg(hdmi->dev, "EVENT=%s\n",
> > -			phy_int_pol & HDMI_PHY_HPD ? "plugin" : "plugout");
> > -		if (hdmi->bridge.dev)
> > +			status == connector_status_connected ?
> > +			"plugin" : "plugout");
> > +
> > +		if (hdmi->bridge.dev) {
> >  			drm_helper_hpd_irq_event(hdmi->bridge.dev);
> > +			drm_bridge_hpd_notify(&hdmi->bridge, status);
> 
> I suspect I will also need to add drm_bridge_hpd_notify() in
> meson_dw_hdmi.c in dw_hdmi_top_thread_irq() for HPD event, right ?

If you want to support DRM_BRIDGE_ATTACH_NO_CONNECTOR (and I think you
should :-)), yes.

> > +		}
> >  	}
> >  
> >  	hdmi_writeb(hdmi, intr_stat, HDMI_IH_PHY_STAT0);
> > @@ -3337,6 +3379,8 @@ __dw_hdmi_probe(struct platform_device *pdev,
> >  
> >  	hdmi->bridge.driver_private = hdmi;
> >  	hdmi->bridge.funcs = &dw_hdmi_bridge_funcs;
> > +	hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID
> > +			 | DRM_BRIDGE_OP_HPD;
> 
> same here for meson_dw_hdmi ?
> could I also assume we could disable the dw_hdmi bridge & hpd ops when
> using with meson_dw_hdmi and implement these in meson_dw_hdmi ?

I've only noticed now that meson_dw_hdmi has its own bridge. Could you
briefly explain how all that works ?

> >  #ifdef CONFIG_OF
> >  	hdmi->bridge.of_node = pdev->dev.of_node;
> >  #endif
> 
> Anyway
> 
> Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 23/27] drm: bridge: dw-hdmi: Attach to next bridge if available
  2020-05-26 12:50   ` Neil Armstrong
  2020-05-26 14:23     ` Jonas Karlman
@ 2020-06-07  1:22     ` Laurent Pinchart
  1 sibling, 0 replies; 69+ messages in thread
From: Laurent Pinchart @ 2020-06-07  1:22 UTC (permalink / raw)
  To: Neil Armstrong
  Cc: Laurent Pinchart, dri-devel, Jernej Skrabec, Jonas Karlman,
	Kieran Bingham, linux-renesas-soc, Andrzej Hajda, Sam Ravnborg

Hi Neil,

On Tue, May 26, 2020 at 02:50:21PM +0200, Neil Armstrong wrote:
> On 26/05/2020 03:15, Laurent Pinchart wrote:
> > On all platforms except i.MX and Rockchip, the dw-hdmi DT bindings
> > require a video output port connected to an HDMI sink (most likely an
> > HDMI connector, in rare cases another bridges converting HDMI to another
> > protocol). For those platforms, retrieve the next bridge and attach it
> > from the dw-hdmi bridge attach handler.
> > 
> > Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> > ---
> >  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 52 ++++++++++++++++++++++-
> >  include/drm/bridge/dw_hdmi.h              |  2 +
> >  2 files changed, 53 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> > index 6148a022569a..512e67bb1c32 100644
> > --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> > +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> > @@ -143,6 +143,7 @@ struct dw_hdmi_phy_data {
> >  struct dw_hdmi {
> >  	struct drm_connector connector;
> >  	struct drm_bridge bridge;
> > +	struct drm_bridge *next_bridge;
> >  
> >  	unsigned int version;
> >  
> > @@ -2797,7 +2798,8 @@ static int dw_hdmi_bridge_attach(struct drm_bridge *bridge,
> >  	struct dw_hdmi *hdmi = bridge->driver_private;
> >  
> >  	if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
> > -		return 0;
> > +		return drm_bridge_attach(bridge->encoder, hdmi->next_bridge,
> > +					 bridge, flags);
> >  
> >  	return dw_hdmi_connector_create(hdmi);
> >  }
> > @@ -3179,6 +3181,50 @@ static void dw_hdmi_init_hw(struct dw_hdmi *hdmi)
> >  		hdmi->phy.ops->setup_hpd(hdmi, hdmi->phy.data);
> >  }
> >  
> > +static int dw_hdmi_parse_dt(struct dw_hdmi *hdmi)
> > +{
> > +	struct device_node *endpoint;
> > +	struct device_node *remote;
> > +
> > +	if (!hdmi->plat_data->output_port)
> > +		return 0;
> > +
> > +	endpoint = of_graph_get_endpoint_by_regs(hdmi->dev->of_node,
> > +						 hdmi->plat_data->output_port,
> > +						 -1);
> > +	if (!endpoint) {
> > +		/*
> > +		 * Don't treat this as a fatal error as the Rockchip DW-HDMI
> > +		 * binding doesn't make the output port mandatory.
> > +		 */
> > +		dev_dbg(hdmi->dev, "Missing endpoint in port@%u\n",
> > +			hdmi->plat_data->output_port);
> > +		return 0;
> > +	}
> > +
> > +	remote = of_graph_get_remote_port_parent(endpoint);
> > +	of_node_put(endpoint);
> > +	if (!remote) {
> > +		dev_err(hdmi->dev, "Endpoint in port@%u unconnected\n",
> > +			hdmi->plat_data->output_port);
> > +		return -ENODEV;
> > +	}
> > +
> > +	if (!of_device_is_available(remote)) {
> > +		dev_err(hdmi->dev, "port@%u remote device is disabled\n",
> > +			hdmi->plat_data->output_port);
> > +		of_node_put(remote);
> > +		return -ENODEV;
> > +	}
> > +
> > +	hdmi->next_bridge = of_drm_find_bridge(remote);
> > +	of_node_put(remote);
> > +	if (!hdmi->next_bridge)
> > +		return -EPROBE_DEFER;
> 
> I'll be safer to print a warn for now until all platforms has been tested.

Probe deferral isn't an error though, it can happen in normal
conditions, if the next bridge hasn't been probed yet. A WARN_ON() would
be pretty bad in that case, and even a dev_warn() may generate
unnecessary worry.

Given that this code only runs if hdmi->plat_data->output_port != 0, and
only the rcar-du driver sets the output_port field, I think it's safe to
not print any message.

> > +
> > +	return 0;
> > +}
> > +
> >  static struct dw_hdmi *
> >  __dw_hdmi_probe(struct platform_device *pdev,
> >  		const struct dw_hdmi_plat_data *plat_data)
> > @@ -3216,6 +3262,10 @@ __dw_hdmi_probe(struct platform_device *pdev,
> >  	mutex_init(&hdmi->cec_notifier_mutex);
> >  	spin_lock_init(&hdmi->audio_lock);
> >  
> > +	ret = dw_hdmi_parse_dt(hdmi);
> > +	if (ret < 0)
> > +		return ERR_PTR(ret);
> > +
> >  	ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0);
> >  	if (ddc_node) {
> >  		hdmi->ddc = of_get_i2c_adapter_by_node(ddc_node);
> > diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
> > index ea34ca146b82..8ebeb65d6371 100644
> > --- a/include/drm/bridge/dw_hdmi.h
> > +++ b/include/drm/bridge/dw_hdmi.h
> > @@ -126,6 +126,8 @@ struct dw_hdmi_phy_ops {
> >  struct dw_hdmi_plat_data {
> >  	struct regmap *regm;
> >  
> > +	unsigned int output_port;
> > +
> >  	unsigned long input_bus_encoding;
> >  	bool use_drm_infoframe;
> >  	bool ycbcr_420_allowed;
> > 
> 
> I must check on meson, since I'm not sure for now if the connector probes.
> 
> Anyway, this looks fine.
> 
> Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 23/27] drm: bridge: dw-hdmi: Attach to next bridge if available
  2020-05-26 14:23     ` Jonas Karlman
@ 2020-06-07  1:24       ` Laurent Pinchart
  0 siblings, 0 replies; 69+ messages in thread
From: Laurent Pinchart @ 2020-06-07  1:24 UTC (permalink / raw)
  To: Jonas Karlman
  Cc: Neil Armstrong, Laurent Pinchart, dri-devel, Jernej Skrabec,
	Kieran Bingham, linux-renesas-soc, Andrzej Hajda, Sam Ravnborg

Hi Jonas,

On Tue, May 26, 2020 at 02:23:33PM +0000, Jonas Karlman wrote:
> On 2020-05-26 14:50, Neil Armstrong wrote:
> > On 26/05/2020 03:15, Laurent Pinchart wrote:
> >> On all platforms except i.MX and Rockchip, the dw-hdmi DT bindings
> >> require a video output port connected to an HDMI sink (most likely an
> >> HDMI connector, in rare cases another bridges converting HDMI to another
> >> protocol). For those platforms, retrieve the next bridge and attach it
> >> from the dw-hdmi bridge attach handler.
> >>
> >> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> >> ---
> >>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 52 ++++++++++++++++++++++-
> >>  include/drm/bridge/dw_hdmi.h              |  2 +
> >>  2 files changed, 53 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> >> index 6148a022569a..512e67bb1c32 100644
> >> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> >> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> >> @@ -143,6 +143,7 @@ struct dw_hdmi_phy_data {
> >>  struct dw_hdmi {
> >>  	struct drm_connector connector;
> >>  	struct drm_bridge bridge;
> >> +	struct drm_bridge *next_bridge;
> >>  
> >>  	unsigned int version;
> >>  
> >> @@ -2797,7 +2798,8 @@ static int dw_hdmi_bridge_attach(struct drm_bridge *bridge,
> >>  	struct dw_hdmi *hdmi = bridge->driver_private;
> >>  
> >>  	if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
> >> -		return 0;
> >> +		return drm_bridge_attach(bridge->encoder, hdmi->next_bridge,
> >> +					 bridge, flags);
> >>  
> >>  	return dw_hdmi_connector_create(hdmi);
> >>  }
> >> @@ -3179,6 +3181,50 @@ static void dw_hdmi_init_hw(struct dw_hdmi *hdmi)
> >>  		hdmi->phy.ops->setup_hpd(hdmi, hdmi->phy.data);
> >>  }
> >>  
> >> +static int dw_hdmi_parse_dt(struct dw_hdmi *hdmi)
> >> +{
> >> +	struct device_node *endpoint;
> >> +	struct device_node *remote;
> >> +
> >> +	if (!hdmi->plat_data->output_port)
> >> +		return 0;
> >> +
> >> +	endpoint = of_graph_get_endpoint_by_regs(hdmi->dev->of_node,
> >> +						 hdmi->plat_data->output_port,
> >> +						 -1);
> >> +	if (!endpoint) {
> >> +		/*
> >> +		 * Don't treat this as a fatal error as the Rockchip DW-HDMI
> >> +		 * binding doesn't make the output port mandatory.
> >> +		 */
> >> +		dev_dbg(hdmi->dev, "Missing endpoint in port@%u\n",
> >> +			hdmi->plat_data->output_port);
> >> +		return 0;
> 
> After this series only rcar-du set output_port so this block should only
> run for rcar-du, for platforms without output_port the if-statement
> for !hdmi->plat_data->output_port already return success so you can
> probably return fatal error here.
> 
> The comment is a little bit misleading because of the if-statement above
> or am I missing something?

You're right, I'll turn this into an error.

> >> +	}
> >> +
> >> +	remote = of_graph_get_remote_port_parent(endpoint);
> >> +	of_node_put(endpoint);
> >> +	if (!remote) {
> >> +		dev_err(hdmi->dev, "Endpoint in port@%u unconnected\n",
> >> +			hdmi->plat_data->output_port);
> >> +		return -ENODEV;
> >> +	}
> >> +
> >> +	if (!of_device_is_available(remote)) {
> >> +		dev_err(hdmi->dev, "port@%u remote device is disabled\n",
> >> +			hdmi->plat_data->output_port);
> >> +		of_node_put(remote);
> >> +		return -ENODEV;
> >> +	}
> >> +
> >> +	hdmi->next_bridge = of_drm_find_bridge(remote);
> >> +	of_node_put(remote);
> >> +	if (!hdmi->next_bridge)
> >> +		return -EPROBE_DEFER;
> > 
> > I'll be safer to print a warn for now until all platforms has been tested.
> > 
> >> +
> >> +	return 0;
> >> +}
> >> +
> >>  static struct dw_hdmi *
> >>  __dw_hdmi_probe(struct platform_device *pdev,
> >>  		const struct dw_hdmi_plat_data *plat_data)
> >> @@ -3216,6 +3262,10 @@ __dw_hdmi_probe(struct platform_device *pdev,
> >>  	mutex_init(&hdmi->cec_notifier_mutex);
> >>  	spin_lock_init(&hdmi->audio_lock);
> >>  
> >> +	ret = dw_hdmi_parse_dt(hdmi);
> >> +	if (ret < 0)
> >> +		return ERR_PTR(ret);
> >> +
> >>  	ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0);
> >>  	if (ddc_node) {
> >>  		hdmi->ddc = of_get_i2c_adapter_by_node(ddc_node);
> >> diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
> >> index ea34ca146b82..8ebeb65d6371 100644
> >> --- a/include/drm/bridge/dw_hdmi.h
> >> +++ b/include/drm/bridge/dw_hdmi.h
> >> @@ -126,6 +126,8 @@ struct dw_hdmi_phy_ops {
> >>  struct dw_hdmi_plat_data {
> >>  	struct regmap *regm;
> >>  
> >> +	unsigned int output_port;
> >> +
> >>  	unsigned long input_bus_encoding;
> >>  	bool use_drm_infoframe;
> >>  	bool ycbcr_420_allowed;
> >>
> > 
> > I must check on meson, since I'm not sure for now if the connector probes.
> > 
> > Anyway, this looks fine.
> > 
> > Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
> > 

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 03/27] drm: bridge: adv7511: Implement bridge connector operations
  2020-05-26  1:14 ` [PATCH 03/27] drm: bridge: adv7511: Implement bridge connector operations Laurent Pinchart
@ 2020-06-21  8:25   ` Sam Ravnborg
  0 siblings, 0 replies; 69+ messages in thread
From: Sam Ravnborg @ 2020-06-21  8:25 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: dri-devel, Jernej Skrabec, Neil Armstrong, Jonas Karlman,
	Kieran Bingham, linux-renesas-soc, Andrzej Hajda

On Tue, May 26, 2020 at 04:14:41AM +0300, Laurent Pinchart wrote:
> Implement the bridge connector-related .get_edid(), .detect() and
> .hpd_notify() operations, and report the related bridge capabilities.
> 
> Output status detection is implemented using the same backend as for the
> DRM connector, but requires making mode retrieval at detection time
> optional as no pointer to the connector is available to the bridge
> .detect() operation. The reason for the need to retrieve modes at
> detection time is unclear to me, and this may benefit from further
> refactoring of hot plug handling code.
As discussed before the get_modes is likely not needed.
But this patch should not remove it - so fine
> 
> Hot plug detection is notified through the bridge HPD notification
> framework when the bridge is used without creating a connector, and
> falls back to the existing implementation otherwise. CEC handling of
> disconnection is handled in the new .hpd_notify() operation in the new
> code path.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Acked-by: Sam Ravnborg <sam@ravnborg.org>
> ---
>  drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 43 ++++++++++++++++++--
>  1 file changed, 39 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> index f0992b6d654f..2662f28f8007 100644
> --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> @@ -443,9 +443,14 @@ static void adv7511_hpd_work(struct work_struct *work)
>  
>  	if (adv7511->connector.status != status) {
>  		adv7511->connector.status = status;
> -		if (status == connector_status_disconnected)
> -			cec_phys_addr_invalidate(adv7511->cec_adap);
> -		drm_kms_helper_hotplug_event(adv7511->connector.dev);
> +
> +		if (adv7511->connector.dev) {
> +			if (status == connector_status_disconnected)
> +				cec_phys_addr_invalidate(adv7511->cec_adap);
> +			drm_kms_helper_hotplug_event(adv7511->connector.dev);
> +		} else {
> +			drm_bridge_hpd_notify(&adv7511->bridge, status);
> +		}
>  	}
>  }
>  
> @@ -661,7 +666,8 @@ adv7511_detect(struct adv7511 *adv7511, struct drm_connector *connector)
>  	if (status == connector_status_connected && hpd && adv7511->powered) {
>  		regcache_mark_dirty(adv7511->regmap);
>  		adv7511_power_on(adv7511);
> -		adv7511_get_modes(adv7511, connector);
> +		if (connector)
> +			adv7511_get_modes(adv7511, connector);
>  		if (adv7511->status == connector_status_connected)
>  			status = connector_status_disconnected;
>  	} else {
> @@ -917,11 +923,38 @@ static int adv7511_bridge_attach(struct drm_bridge *bridge,
>  	return ret;
>  }
>  
> +static enum drm_connector_status adv7511_bridge_detect(struct drm_bridge *bridge)
> +{
> +	struct adv7511 *adv = bridge_to_adv7511(bridge);
> +
> +	return adv7511_detect(adv, NULL);
> +}
> +
> +static struct edid *adv7511_bridge_get_edid(struct drm_bridge *bridge,
> +					    struct drm_connector *connector)
> +{
> +	struct adv7511 *adv = bridge_to_adv7511(bridge);
> +
> +	return adv7511_get_edid(adv, connector);
> +}
> +
> +static void adv7511_bridge_hpd_notify(struct drm_bridge *bridge,
> +				      enum drm_connector_status status)
> +{
> +	struct adv7511 *adv = bridge_to_adv7511(bridge);
> +
> +	if (status == connector_status_disconnected)
> +		cec_phys_addr_invalidate(adv->cec_adap);
> +}
> +
>  static const struct drm_bridge_funcs adv7511_bridge_funcs = {
>  	.enable = adv7511_bridge_enable,
>  	.disable = adv7511_bridge_disable,
>  	.mode_set = adv7511_bridge_mode_set,
>  	.attach = adv7511_bridge_attach,
> +	.detect = adv7511_bridge_detect,
> +	.get_edid = adv7511_bridge_get_edid,
> +	.hpd_notify = adv7511_bridge_hpd_notify,
>  };
>  
>  /* -----------------------------------------------------------------------------
> @@ -1250,6 +1283,8 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
>  		goto err_unregister_cec;
>  
>  	adv7511->bridge.funcs = &adv7511_bridge_funcs;
> +	adv7511->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID
> +			    | DRM_BRIDGE_OP_HPD;
>  	adv7511->bridge.of_node = dev->of_node;
>  
>  	drm_bridge_add(&adv7511->bridge);
> -- 
> Regards,
> 
> Laurent Pinchart
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 05/27] drm: bridge: Return NULL on error from drm_bridge_get_edid()
  2020-05-26  1:14 ` [PATCH 05/27] drm: bridge: Return NULL on error from drm_bridge_get_edid() Laurent Pinchart
@ 2020-06-21  8:26   ` Sam Ravnborg
  0 siblings, 0 replies; 69+ messages in thread
From: Sam Ravnborg @ 2020-06-21  8:26 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: dri-devel, Jernej Skrabec, Neil Armstrong, Jonas Karlman,
	Kieran Bingham, linux-renesas-soc, Andrzej Hajda

On Tue, May 26, 2020 at 04:14:43AM +0300, Laurent Pinchart wrote:
> The drm_bridge_get_edid() function is documented to return an error
> pointer on error. The underlying .get_edid() operation, however, returns
> NULL on error, and so do the drm_get_edid() and drm_do_get_edid()
> functions upon which .get_edid() is usually implemented. Make
> drm_bridge_get_edid() return NULL on error to be consistent.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Acked-by: Sam Ravnborg <sam@ravnborg.org>
> ---
>  drivers/gpu/drm/bridge/ti-tfp410.c | 10 +++++++---
>  drivers/gpu/drm/drm_bridge.c       |  6 +++---
>  2 files changed, 10 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/ti-tfp410.c b/drivers/gpu/drm/bridge/ti-tfp410.c
> index e3eb6364c0f7..f065a96a0917 100644
> --- a/drivers/gpu/drm/bridge/ti-tfp410.c
> +++ b/drivers/gpu/drm/bridge/ti-tfp410.c
> @@ -51,11 +51,15 @@ static int tfp410_get_modes(struct drm_connector *connector)
>  	struct edid *edid;
>  	int ret;
>  
> -	edid = drm_bridge_get_edid(dvi->next_bridge, connector);
> -	if (IS_ERR_OR_NULL(edid)) {
> -		if (edid != ERR_PTR(-ENOTSUPP))
> +	if (dvi->next_bridge->ops & DRM_BRIDGE_OP_EDID) {
> +		edid = drm_bridge_get_edid(dvi->next_bridge, connector);
> +		if (!edid)
>  			DRM_INFO("EDID read failed. Fallback to standard modes\n");
> +	} else {
> +		edid = NULL;
> +	}
>  
> +	if (!edid) {
>  		/*
>  		 * No EDID, fallback on the XGA standard modes and prefer a mode
>  		 * pretty much anything can handle.
> diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
> index afdec8e5fc68..fe1e3460b486 100644
> --- a/drivers/gpu/drm/drm_bridge.c
> +++ b/drivers/gpu/drm/drm_bridge.c
> @@ -1086,16 +1086,16 @@ EXPORT_SYMBOL_GPL(drm_bridge_get_modes);
>   *
>   * If the bridge supports output EDID retrieval, as reported by the
>   * DRM_BRIDGE_OP_EDID bridge ops flag, call &drm_bridge_funcs.get_edid to
> - * get the EDID and return it. Otherwise return ERR_PTR(-ENOTSUPP).
> + * get the EDID and return it. Otherwise return NULL.
>   *
>   * RETURNS:
> - * The retrieved EDID on success, or an error pointer otherwise.
> + * The retrieved EDID on success, or NULL otherwise.
>   */
>  struct edid *drm_bridge_get_edid(struct drm_bridge *bridge,
>  				 struct drm_connector *connector)
>  {
>  	if (!(bridge->ops & DRM_BRIDGE_OP_EDID))
> -		return ERR_PTR(-ENOTSUPP);
> +		return NULL;
>  
>  	return bridge->funcs->get_edid(bridge, connector);
>  }
> -- 
> Regards,
> 
> Laurent Pinchart
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 09/27] drm: edid: Constify connector argument to infoframe functions
  2020-05-26  1:14 ` [PATCH 09/27] drm: edid: Constify connector argument to infoframe functions Laurent Pinchart
@ 2020-06-21  8:27   ` Sam Ravnborg
  0 siblings, 0 replies; 69+ messages in thread
From: Sam Ravnborg @ 2020-06-21  8:27 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: dri-devel, Jernej Skrabec, Neil Armstrong, Jonas Karlman,
	Kieran Bingham, linux-renesas-soc, Andrzej Hajda,
	Thomas Zimmermann

On Tue, May 26, 2020 at 04:14:47AM +0300, Laurent Pinchart wrote:
> The drm_hdmi_avi_infoframe_from_display_mode(),
> drm_hdmi_vendor_infoframe_from_display_mode() and
> drm_hdmi_avi_infoframe_quant_range() functions take a drm_connector that
> they don't modify. Mark it as const.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Acked-by: Sam Ravnborg <sam@ravnborg.org>
> ---
>  drivers/gpu/drm/drm_edid.c | 12 ++++++------
>  include/drm/drm_edid.h     |  6 +++---
>  2 files changed, 9 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 3bd95c4b02eb..e6b26f16c21f 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -5365,7 +5365,7 @@ void drm_set_preferred_mode(struct drm_connector *connector,
>  }
>  EXPORT_SYMBOL(drm_set_preferred_mode);
>  
> -static bool is_hdmi2_sink(struct drm_connector *connector)
> +static bool is_hdmi2_sink(const struct drm_connector *connector)
>  {
>  	/*
>  	 * FIXME: sil-sii8620 doesn't have a connector around when
> @@ -5450,7 +5450,7 @@ drm_hdmi_infoframe_set_hdr_metadata(struct hdmi_drm_infoframe *frame,
>  }
>  EXPORT_SYMBOL(drm_hdmi_infoframe_set_hdr_metadata);
>  
> -static u8 drm_mode_hdmi_vic(struct drm_connector *connector,
> +static u8 drm_mode_hdmi_vic(const struct drm_connector *connector,
>  			    const struct drm_display_mode *mode)
>  {
>  	bool has_hdmi_infoframe = connector ?
> @@ -5466,7 +5466,7 @@ static u8 drm_mode_hdmi_vic(struct drm_connector *connector,
>  	return drm_match_hdmi_mode(mode);
>  }
>  
> -static u8 drm_mode_cea_vic(struct drm_connector *connector,
> +static u8 drm_mode_cea_vic(const struct drm_connector *connector,
>  			   const struct drm_display_mode *mode)
>  {
>  	u8 vic;
> @@ -5504,7 +5504,7 @@ static u8 drm_mode_cea_vic(struct drm_connector *connector,
>   */
>  int
>  drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
> -					 struct drm_connector *connector,
> +					 const struct drm_connector *connector,
>  					 const struct drm_display_mode *mode)
>  {
>  	enum hdmi_picture_aspect picture_aspect;
> @@ -5651,7 +5651,7 @@ EXPORT_SYMBOL(drm_hdmi_avi_infoframe_colorspace);
>   */
>  void
>  drm_hdmi_avi_infoframe_quant_range(struct hdmi_avi_infoframe *frame,
> -				   struct drm_connector *connector,
> +				   const struct drm_connector *connector,
>  				   const struct drm_display_mode *mode,
>  				   enum hdmi_quantization_range rgb_quant_range)
>  {
> @@ -5755,7 +5755,7 @@ s3d_structure_from_display_mode(const struct drm_display_mode *mode)
>   */
>  int
>  drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame,
> -					    struct drm_connector *connector,
> +					    const struct drm_connector *connector,
>  					    const struct drm_display_mode *mode)
>  {
>  	/*
> diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> index 34b15e3d070c..43254319ab19 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -361,11 +361,11 @@ drm_load_edid_firmware(struct drm_connector *connector)
>  
>  int
>  drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
> -					 struct drm_connector *connector,
> +					 const struct drm_connector *connector,
>  					 const struct drm_display_mode *mode);
>  int
>  drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame,
> -					    struct drm_connector *connector,
> +					    const struct drm_connector *connector,
>  					    const struct drm_display_mode *mode);
>  
>  void
> @@ -378,7 +378,7 @@ drm_hdmi_avi_infoframe_bars(struct hdmi_avi_infoframe *frame,
>  
>  void
>  drm_hdmi_avi_infoframe_quant_range(struct hdmi_avi_infoframe *frame,
> -				   struct drm_connector *connector,
> +				   const struct drm_connector *connector,
>  				   const struct drm_display_mode *mode,
>  				   enum hdmi_quantization_range rgb_quant_range);
>  
> -- 
> Regards,
> 
> Laurent Pinchart
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 27/27] drm: Add default modes for connectors in unknown state
  2020-05-26  1:15 ` [PATCH 27/27] drm: Add default modes for connectors in unknown state Laurent Pinchart
@ 2020-06-21  8:40   ` Sam Ravnborg
  2020-06-24  1:12     ` Laurent Pinchart
  0 siblings, 1 reply; 69+ messages in thread
From: Sam Ravnborg @ 2020-06-21  8:40 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: dri-devel, Jernej Skrabec, Neil Armstrong, Jonas Karlman,
	Kieran Bingham, linux-renesas-soc, Andrzej Hajda,
	Thomas Zimmermann

On Tue, May 26, 2020 at 04:15:05AM +0300, Laurent Pinchart wrote:
> The DRM CRTC helpers add default modes to connectors in the connected
> state if no mode can be retrieved from the connector. This behaviour is
> useful for VGA or DVI outputs that have no connected DDC bus. However,
> in such cases, the status of the output usually can't be retrieved and
> is reported as connector_status_unknown.
> 
> Extend the addition of default modes to connectors in an unknown state
> to support outputs that can retrieve neither the modes nor the
> connection status.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

From your description sounds like an OK approach.
But this is not something I feel too familiar with.
Acked-by: Sam Ravnborg <sam@ravnborg.org>

> ---
>  drivers/gpu/drm/drm_probe_helper.c       | 3 ++-
>  include/drm/drm_modeset_helper_vtables.h | 8 +++++++-
>  2 files changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
> index f5d141e0400f..9055d9573c90 100644
> --- a/drivers/gpu/drm/drm_probe_helper.c
> +++ b/drivers/gpu/drm/drm_probe_helper.c
> @@ -491,7 +491,8 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
>  	if (count == 0 && connector->status == connector_status_connected)
>  		count = drm_add_override_edid_modes(connector);
>  
> -	if (count == 0 && connector->status == connector_status_connected)
> +	if (count == 0 && (connector->status == connector_status_connected ||
> +			   connector->status == connector_status_unknown))
>  		count = drm_add_modes_noedid(connector, 1024, 768);
>  	count += drm_helper_probe_add_cmdline_mode(connector);
>  	if (count == 0)
> diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
> index 421a30f08463..afe55e2e93d2 100644
> --- a/include/drm/drm_modeset_helper_vtables.h
> +++ b/include/drm/drm_modeset_helper_vtables.h
> @@ -876,13 +876,19 @@ struct drm_connector_helper_funcs {
>  	 * The usual way to implement this is to cache the EDID retrieved in the
>  	 * probe callback somewhere in the driver-private connector structure.
>  	 * In this function drivers then parse the modes in the EDID and add
> -	 * them by calling drm_add_edid_modes(). But connectors that driver a
> +	 * them by calling drm_add_edid_modes(). But connectors that drive a
>  	 * fixed panel can also manually add specific modes using
>  	 * drm_mode_probed_add(). Drivers which manually add modes should also
>  	 * make sure that the &drm_connector.display_info,
>  	 * &drm_connector.width_mm and &drm_connector.height_mm fields are
>  	 * filled in.
>  	 *
> +	 * Note that the caller function will automatically add standard VESA
> +	 * DMT modes up to 1024x768 if the .get_modes() helper operation returns
> +	 * no mode and if the connector status is connector_status_connected or
> +	 * connector_status_unknown. There is no need to call
> +	 * drm_add_edid_modes() manually in that case.
> +	 *
>  	 * Virtual drivers that just want some standard VESA mode with a given
>  	 * resolution can call drm_add_modes_noedid(), and mark the preferred
>  	 * one using drm_set_preferred_mode().
> -- 
> Regards,
> 
> Laurent Pinchart
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 00/27] Converter R-Car DU to the DRM bridge connector helper
  2020-05-26  1:14 [PATCH 00/27] Converter R-Car DU to the DRM bridge connector helper Laurent Pinchart
                   ` (26 preceding siblings ...)
  2020-05-26  1:15 ` [PATCH 27/27] drm: Add default modes for connectors in unknown state Laurent Pinchart
@ 2020-06-23 18:55 ` Sam Ravnborg
  2020-06-25  8:48   ` Liu Ying
  27 siblings, 1 reply; 69+ messages in thread
From: Sam Ravnborg @ 2020-06-23 18:55 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: dri-devel, Jernej Skrabec, Neil Armstrong, Jonas Karlman,
	Kieran Bingham, linux-renesas-soc, Andrzej Hajda

Hi Laurent.

On Tue, May 26, 2020 at 04:14:38AM +0300, Laurent Pinchart wrote:
> Hello,
> 
> This patch series converts the R-Car DU driver to use the DRM bridge
> connector helper drm_bridge_connector_init().
> 
> The bulk of the series is conversion of the adv7511, simple-bridge,
> rcar-lbds and dw-hdmi drivers to make connector creation optional
> (through the DRM_BRIDGE_ATTACH_NO_CONNECTOR flag).
> 
> The series starts with the adv7511 driver, previously posted as "[PATCH
> 0/4] drm: bridge: adv7511: Enable usage with DRM bridge connector
> helper" ([1]). Patches 01/27 to 04/27 incorporate all the received
> review comments.
> 
> The next three patches address the simple-bridge driver, previously
> posted as "[PATCH 0/2] drm: bridge: simple-bridge: Enable usage with DRM
> bridge connector helper". Patch 05/27 is an additional fix that stems
> from the review, and patches 06/27 and 07/27 incorporate all the
> received review comments.
> 
> Patch 08/27 is a new patch that addresses the rcar-lvds driver. Instead
> of implementing direct support for DRM_BRIDGE_ATTACH_NO_CONNECTOR, it
> simply removes code that shouldn't have been in the driver in the first
> place by switching to the panel bridge helper.
> 
> Patches 09/27 to 22/27 then address the dw-hdmi driver. That's a more
> sizeable rework, due to the fact that the driver implements a mid-layer
> for platform-specific glue, with the internal drm_connector being used
> throughout the whole code. There's no rocket science there, but patch
> 10/27 should be noted for adding a new argument to the
> drm_bridge_funcs.mode_valid() function. Please see individual patches
> for details.
> 
> Patch 23/27 adds support to the dw-hdmi driver to attach to a downstream
> bridge if one is specified in DT. As the DT port number corresponding to
> the video output differs between platforms that integrate the dw-hdmi
> (some of them even don't have a video output port, which should probably
> be fixed, but that's out of scope for this series), the port number has
> to be specified by the platform glue layer. Patch 24/27 does so for the
> R-Car dw-hdmi driver.
> 
> Patch 25/27 is a drive-by fix for an error path issue in the rcar-du
> driver. Patch 26/27 finally makes use of the drm_bridge_connector_init()
> helper.
> 
> Unfortunately, this breaks the VGA output on R-Car Gen3 platforms. On
> those platforms, the VGA DDC lines are not connected, and there is no
> mean for software to detect the VGA output connection status. When the
> simple-bridge driver creates a connector, it automatically adds default
> modes when no DDC is available. This behavious is also present int the
> DRM probe helper drm_helper_probe_single_connector_modes(), but only
> when the connector status is connector_status_connected. As the driver
> (rightfully) reports connector_status_unconnected, no modes are added.
> Patch 27/27 fixes this issue by extending addition of default modes in
> drm_helper_probe_single_connector_modes() when the output status is
> unknown. An alternative approach would be to implement this behaviour in
> the bridge connector helper (drm_bridge_connector.c).
> 
> All the modified drivers have been compile-tested, and the series has
> been tested on a Renesas R-Car Salvator-XS board with the VGA, HDMI and
> LVDS outputs.
> 
> [1] https://lore.kernel.org/dri-devel/20200409004610.12346-1-laurent.pinchart+renesas@ideasonboard.com/
> [2] https://lore.kernel.org/dri-devel/20200409003636.11792-1-laurent.pinchart+renesas@ideasonboard.com/

As we briefly discussed on IRC the first 21 patches are now applied to
drm-misc-next.
The rcar-du specific patches was left out and the last patch was
likewise not applied in this round- mostly because it was the coming
after several rcar-du patches and I was not sure if there was some
dependencies to consider.

With this set in we have more examples in the tree how to do proper
bridges which is good.

While applying the new r-bs was ofc added.

	Sam

> 
> Laurent Pinchart (27):
>   drm: bridge: adv7511: Split EDID read to a separate function
>   drm: bridge: adv7511: Split connector creation to a separate function
>   drm: bridge: adv7511: Implement bridge connector operations
>   drm: bridge: adv7511: Make connector creation optional
>   drm: bridge: Return NULL on error from drm_bridge_get_edid()
>   drm: bridge: simple-bridge: Delegate operations to next bridge
>   drm: bridge: simple-bridge: Make connector creation optional
>   drm: rcar-du: lvds: Convert to DRM panel bridge helper
>   drm: edid: Constify connector argument to infoframe functions
>   drm: bridge: Pass drm_display_info to drm_bridge_funcs .mode_valid()
>   drm: bridge: dw-hdmi: Pass private data pointer to .mode_valid()
>   drm: bridge: dw-hdmi: Pass private data pointer to .configure_phy()
>   drm: bridge: dw-hdmi: Remove unused field from dw_hdmi_plat_data
>   drm: meson: dw-hdmi: Use dw_hdmi context to replace hack
>   drm: bridge: dw-hdmi: Pass drm_display_info to .mode_valid()
>   drm: bridge: dw-hdmi: Constify mode argument to dw_hdmi_phy_ops
>     .init()
>   drm: bridge: dw-hdmi: Constify mode argument to internal functions
>   drm: bridge: dw-hdmi: Pass drm_display_info to dw_hdmi_support_scdc()
>   drm: bridge: dw-hdmi: Split connector creation to a separate function
>   drm: bridge: dw-hdmi: Store current connector in struct dw_hdmi
>   drm: bridge: dw-hdmi: Pass drm_connector to internal functions as
>     needed
>   drm: bridge: dw-hdmi: Make connector creation optional
>   drm: bridge: dw-hdmi: Attach to next bridge if available
>   drm: rcar-du: dw-hdmi: Set output port number
>   drm: rcar-du: Fix error handling in rcar_du_encoder_init()
>   drm: rcar-du: Use drm_bridge_connector_init() helper
>   drm: Add default modes for connectors in unknown state
> 
>  drivers/gpu/drm/bridge/adv7511/adv7511_drv.c  | 159 +++++---
>  .../drm/bridge/analogix/analogix-anx6345.c    |   1 +
>  .../drm/bridge/analogix/analogix-anx78xx.c    |   1 +
>  drivers/gpu/drm/bridge/cdns-dsi.c             |   1 +
>  drivers/gpu/drm/bridge/chrontel-ch7033.c      |   1 +
>  drivers/gpu/drm/bridge/nwl-dsi.c              |   1 +
>  drivers/gpu/drm/bridge/sii9234.c              |   1 +
>  drivers/gpu/drm/bridge/sil-sii8620.c          |   1 +
>  drivers/gpu/drm/bridge/simple-bridge.c        | 113 +++---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c     | 357 ++++++++++++------
>  drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c |   1 +
>  drivers/gpu/drm/bridge/tc358767.c             |   1 +
>  drivers/gpu/drm/bridge/tc358768.c             |   1 +
>  drivers/gpu/drm/bridge/thc63lvd1024.c         |   1 +
>  drivers/gpu/drm/bridge/ti-tfp410.c            |  11 +-
>  drivers/gpu/drm/drm_atomic_helper.c           |   3 +-
>  drivers/gpu/drm/drm_bridge.c                  |  10 +-
>  drivers/gpu/drm/drm_edid.c                    |  12 +-
>  drivers/gpu/drm/drm_probe_helper.c            |   7 +-
>  drivers/gpu/drm/i2c/tda998x_drv.c             |   1 +
>  drivers/gpu/drm/imx/dw_hdmi-imx.c             |   6 +-
>  drivers/gpu/drm/meson/meson_dw_hdmi.c         |  34 +-
>  drivers/gpu/drm/omapdrm/dss/dpi.c             |   1 +
>  drivers/gpu/drm/omapdrm/dss/sdi.c             |   1 +
>  drivers/gpu/drm/omapdrm/dss/venc.c            |   1 +
>  drivers/gpu/drm/rcar-du/rcar_du_encoder.c     |  26 +-
>  drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c        |   7 +-
>  drivers/gpu/drm/rcar-du/rcar_lvds.c           | 124 +-----
>  drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c   |   6 +-
>  drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c         |   6 +-
>  drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h         |   3 +-
>  drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c        |   3 +-
>  include/drm/bridge/dw_hdmi.h                  |  28 +-
>  include/drm/drm_bridge.h                      |   3 +
>  include/drm/drm_edid.h                        |   6 +-
>  include/drm/drm_modeset_helper_vtables.h      |   8 +-
>  36 files changed, 541 insertions(+), 406 deletions(-)
> 
> -- 
> Regards,
> 
> Laurent Pinchart
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 27/27] drm: Add default modes for connectors in unknown state
  2020-06-21  8:40   ` Sam Ravnborg
@ 2020-06-24  1:12     ` Laurent Pinchart
  2020-06-24  7:23       ` Daniel Vetter
  0 siblings, 1 reply; 69+ messages in thread
From: Laurent Pinchart @ 2020-06-24  1:12 UTC (permalink / raw)
  To: Sam Ravnborg
  Cc: Laurent Pinchart, dri-devel, Jernej Skrabec, Neil Armstrong,
	Jonas Karlman, Kieran Bingham, linux-renesas-soc, Andrzej Hajda,
	Thomas Zimmermann, Daniel Vetter

Hi Sam,

On Sun, Jun 21, 2020 at 10:40:00AM +0200, Sam Ravnborg wrote:
> On Tue, May 26, 2020 at 04:15:05AM +0300, Laurent Pinchart wrote:
> > The DRM CRTC helpers add default modes to connectors in the connected
> > state if no mode can be retrieved from the connector. This behaviour is
> > useful for VGA or DVI outputs that have no connected DDC bus. However,
> > in such cases, the status of the output usually can't be retrieved and
> > is reported as connector_status_unknown.
> > 
> > Extend the addition of default modes to connectors in an unknown state
> > to support outputs that can retrieve neither the modes nor the
> > connection status.
> > 
> > Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> 
> From your description sounds like an OK approach.
> But this is not something I feel too familiar with.
> Acked-by: Sam Ravnborg <sam@ravnborg.org>

Thanks for the ack. I'd like to have Daniel's (CC'ed) feedback on this
too.

> > ---
> >  drivers/gpu/drm/drm_probe_helper.c       | 3 ++-
> >  include/drm/drm_modeset_helper_vtables.h | 8 +++++++-
> >  2 files changed, 9 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
> > index f5d141e0400f..9055d9573c90 100644
> > --- a/drivers/gpu/drm/drm_probe_helper.c
> > +++ b/drivers/gpu/drm/drm_probe_helper.c
> > @@ -491,7 +491,8 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
> >  	if (count == 0 && connector->status == connector_status_connected)
> >  		count = drm_add_override_edid_modes(connector);
> >  
> > -	if (count == 0 && connector->status == connector_status_connected)
> > +	if (count == 0 && (connector->status == connector_status_connected ||
> > +			   connector->status == connector_status_unknown))
> >  		count = drm_add_modes_noedid(connector, 1024, 768);
> >  	count += drm_helper_probe_add_cmdline_mode(connector);
> >  	if (count == 0)
> > diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
> > index 421a30f08463..afe55e2e93d2 100644
> > --- a/include/drm/drm_modeset_helper_vtables.h
> > +++ b/include/drm/drm_modeset_helper_vtables.h
> > @@ -876,13 +876,19 @@ struct drm_connector_helper_funcs {
> >  	 * The usual way to implement this is to cache the EDID retrieved in the
> >  	 * probe callback somewhere in the driver-private connector structure.
> >  	 * In this function drivers then parse the modes in the EDID and add
> > -	 * them by calling drm_add_edid_modes(). But connectors that driver a
> > +	 * them by calling drm_add_edid_modes(). But connectors that drive a
> >  	 * fixed panel can also manually add specific modes using
> >  	 * drm_mode_probed_add(). Drivers which manually add modes should also
> >  	 * make sure that the &drm_connector.display_info,
> >  	 * &drm_connector.width_mm and &drm_connector.height_mm fields are
> >  	 * filled in.
> >  	 *
> > +	 * Note that the caller function will automatically add standard VESA
> > +	 * DMT modes up to 1024x768 if the .get_modes() helper operation returns
> > +	 * no mode and if the connector status is connector_status_connected or
> > +	 * connector_status_unknown. There is no need to call
> > +	 * drm_add_edid_modes() manually in that case.
> > +	 *
> >  	 * Virtual drivers that just want some standard VESA mode with a given
> >  	 * resolution can call drm_add_modes_noedid(), and mark the preferred
> >  	 * one using drm_set_preferred_mode().

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 27/27] drm: Add default modes for connectors in unknown state
  2020-06-24  1:12     ` Laurent Pinchart
@ 2020-06-24  7:23       ` Daniel Vetter
  2020-06-24 15:24         ` Alex Deucher
  2020-06-24 22:47         ` Laurent Pinchart
  0 siblings, 2 replies; 69+ messages in thread
From: Daniel Vetter @ 2020-06-24  7:23 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Sam Ravnborg, Laurent Pinchart, dri-devel, Jernej Skrabec,
	Neil Armstrong, Jonas Karlman, Kieran Bingham, linux-renesas-soc,
	Andrzej Hajda, Thomas Zimmermann, Daniel Vetter

On Wed, Jun 24, 2020 at 04:12:09AM +0300, Laurent Pinchart wrote:
> Hi Sam,
> 
> On Sun, Jun 21, 2020 at 10:40:00AM +0200, Sam Ravnborg wrote:
> > On Tue, May 26, 2020 at 04:15:05AM +0300, Laurent Pinchart wrote:
> > > The DRM CRTC helpers add default modes to connectors in the connected
> > > state if no mode can be retrieved from the connector. This behaviour is
> > > useful for VGA or DVI outputs that have no connected DDC bus. However,
> > > in such cases, the status of the output usually can't be retrieved and
> > > is reported as connector_status_unknown.
> > > 
> > > Extend the addition of default modes to connectors in an unknown state
> > > to support outputs that can retrieve neither the modes nor the
> > > connection status.
> > > 
> > > Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> > 
> > From your description sounds like an OK approach.
> > But this is not something I feel too familiar with.
> > Acked-by: Sam Ravnborg <sam@ravnborg.org>
> 
> Thanks for the ack. I'd like to have Daniel's (CC'ed) feedback on this
> too.

Makes sense, and at least pre-coffee me can't immediately think of a
scenario where we're going to regret this. _unknown status is pretty much
limited to old VGA and similar things where load detect somehow isn't well
supported by the hw.

Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>

> 
> > > ---
> > >  drivers/gpu/drm/drm_probe_helper.c       | 3 ++-
> > >  include/drm/drm_modeset_helper_vtables.h | 8 +++++++-
> > >  2 files changed, 9 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
> > > index f5d141e0400f..9055d9573c90 100644
> > > --- a/drivers/gpu/drm/drm_probe_helper.c
> > > +++ b/drivers/gpu/drm/drm_probe_helper.c
> > > @@ -491,7 +491,8 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
> > >  	if (count == 0 && connector->status == connector_status_connected)
> > >  		count = drm_add_override_edid_modes(connector);
> > >  
> > > -	if (count == 0 && connector->status == connector_status_connected)
> > > +	if (count == 0 && (connector->status == connector_status_connected ||
> > > +			   connector->status == connector_status_unknown))
> > >  		count = drm_add_modes_noedid(connector, 1024, 768);
> > >  	count += drm_helper_probe_add_cmdline_mode(connector);
> > >  	if (count == 0)
> > > diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
> > > index 421a30f08463..afe55e2e93d2 100644
> > > --- a/include/drm/drm_modeset_helper_vtables.h
> > > +++ b/include/drm/drm_modeset_helper_vtables.h
> > > @@ -876,13 +876,19 @@ struct drm_connector_helper_funcs {
> > >  	 * The usual way to implement this is to cache the EDID retrieved in the
> > >  	 * probe callback somewhere in the driver-private connector structure.
> > >  	 * In this function drivers then parse the modes in the EDID and add
> > > -	 * them by calling drm_add_edid_modes(). But connectors that driver a
> > > +	 * them by calling drm_add_edid_modes(). But connectors that drive a
> > >  	 * fixed panel can also manually add specific modes using
> > >  	 * drm_mode_probed_add(). Drivers which manually add modes should also
> > >  	 * make sure that the &drm_connector.display_info,
> > >  	 * &drm_connector.width_mm and &drm_connector.height_mm fields are
> > >  	 * filled in.
> > >  	 *
> > > +	 * Note that the caller function will automatically add standard VESA
> > > +	 * DMT modes up to 1024x768 if the .get_modes() helper operation returns
> > > +	 * no mode and if the connector status is connector_status_connected or
> > > +	 * connector_status_unknown. There is no need to call
> > > +	 * drm_add_edid_modes() manually in that case.

Hm calling drm_add_edid_modes if you have no edid is a bit a funny idea
... Personally I'd just leave out the last sentence, I think that only
confuses readers. Or I'm not grasphing what you're trying to tell here.

r-b with or without this change since imo super tiny nit.

Cheers, Daniel

> > > +	 *
> > >  	 * Virtual drivers that just want some standard VESA mode with a given
> > >  	 * resolution can call drm_add_modes_noedid(), and mark the preferred
> > >  	 * one using drm_set_preferred_mode().
> 
> -- 
> Regards,
> 
> Laurent Pinchart

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

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

* Re: [PATCH 27/27] drm: Add default modes for connectors in unknown state
  2020-06-24  7:23       ` Daniel Vetter
@ 2020-06-24 15:24         ` Alex Deucher
  2020-06-24 19:31           ` Daniel Vetter
  2020-06-24 22:47         ` Laurent Pinchart
  1 sibling, 1 reply; 69+ messages in thread
From: Alex Deucher @ 2020-06-24 15:24 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Laurent Pinchart, Jernej Skrabec, Laurent Pinchart,
	Jonas Karlman, Neil Armstrong, Kieran Bingham,
	Maling list - DRI developers, linux-renesas-soc, Andrzej Hajda,
	Thomas Zimmermann, Sam Ravnborg

On Wed, Jun 24, 2020 at 3:23 AM Daniel Vetter <daniel@ffwll.ch> wrote:
>
> On Wed, Jun 24, 2020 at 04:12:09AM +0300, Laurent Pinchart wrote:
> > Hi Sam,
> >
> > On Sun, Jun 21, 2020 at 10:40:00AM +0200, Sam Ravnborg wrote:
> > > On Tue, May 26, 2020 at 04:15:05AM +0300, Laurent Pinchart wrote:
> > > > The DRM CRTC helpers add default modes to connectors in the connected
> > > > state if no mode can be retrieved from the connector. This behaviour is
> > > > useful for VGA or DVI outputs that have no connected DDC bus. However,
> > > > in such cases, the status of the output usually can't be retrieved and
> > > > is reported as connector_status_unknown.
> > > >
> > > > Extend the addition of default modes to connectors in an unknown state
> > > > to support outputs that can retrieve neither the modes nor the
> > > > connection status.
> > > >
> > > > Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> > >
> > > From your description sounds like an OK approach.
> > > But this is not something I feel too familiar with.
> > > Acked-by: Sam Ravnborg <sam@ravnborg.org>
> >
> > Thanks for the ack. I'd like to have Daniel's (CC'ed) feedback on this
> > too.
>
> Makes sense, and at least pre-coffee me can't immediately think of a
> scenario where we're going to regret this. _unknown status is pretty much
> limited to old VGA and similar things where load detect somehow isn't well
> supported by the hw.
>
> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
>
> >
> > > > ---
> > > >  drivers/gpu/drm/drm_probe_helper.c       | 3 ++-
> > > >  include/drm/drm_modeset_helper_vtables.h | 8 +++++++-
> > > >  2 files changed, 9 insertions(+), 2 deletions(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
> > > > index f5d141e0400f..9055d9573c90 100644
> > > > --- a/drivers/gpu/drm/drm_probe_helper.c
> > > > +++ b/drivers/gpu/drm/drm_probe_helper.c
> > > > @@ -491,7 +491,8 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
> > > >   if (count == 0 && connector->status == connector_status_connected)
> > > >           count = drm_add_override_edid_modes(connector);
> > > >
> > > > - if (count == 0 && connector->status == connector_status_connected)
> > > > + if (count == 0 && (connector->status == connector_status_connected ||
> > > > +                    connector->status == connector_status_unknown))
> > > >           count = drm_add_modes_noedid(connector, 1024, 768);
> > > >   count += drm_helper_probe_add_cmdline_mode(connector);
> > > >   if (count == 0)
> > > > diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
> > > > index 421a30f08463..afe55e2e93d2 100644
> > > > --- a/include/drm/drm_modeset_helper_vtables.h
> > > > +++ b/include/drm/drm_modeset_helper_vtables.h
> > > > @@ -876,13 +876,19 @@ struct drm_connector_helper_funcs {
> > > >    * The usual way to implement this is to cache the EDID retrieved in the
> > > >    * probe callback somewhere in the driver-private connector structure.
> > > >    * In this function drivers then parse the modes in the EDID and add
> > > > -  * them by calling drm_add_edid_modes(). But connectors that driver a
> > > > +  * them by calling drm_add_edid_modes(). But connectors that drive a
> > > >    * fixed panel can also manually add specific modes using
> > > >    * drm_mode_probed_add(). Drivers which manually add modes should also
> > > >    * make sure that the &drm_connector.display_info,
> > > >    * &drm_connector.width_mm and &drm_connector.height_mm fields are
> > > >    * filled in.
> > > >    *
> > > > +  * Note that the caller function will automatically add standard VESA
> > > > +  * DMT modes up to 1024x768 if the .get_modes() helper operation returns
> > > > +  * no mode and if the connector status is connector_status_connected or
> > > > +  * connector_status_unknown. There is no need to call
> > > > +  * drm_add_edid_modes() manually in that case.
>
> Hm calling drm_add_edid_modes if you have no edid is a bit a funny idea
> ... Personally I'd just leave out the last sentence, I think that only
> confuses readers. Or I'm not grasphing what you're trying to tell here.

IIRC, some drivers used and desktop environments expected unknown
rather than off for LVDS/eDP panels when the lid was shut or if the
mux was switched to another device in the case of hybrid laptops.

Alex


>
> r-b with or without this change since imo super tiny nit.
>
> Cheers, Daniel
>
> > > > +  *
> > > >    * Virtual drivers that just want some standard VESA mode with a given
> > > >    * resolution can call drm_add_modes_noedid(), and mark the preferred
> > > >    * one using drm_set_preferred_mode().
> >
> > --
> > Regards,
> >
> > Laurent Pinchart
>
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 27/27] drm: Add default modes for connectors in unknown state
  2020-06-24 15:24         ` Alex Deucher
@ 2020-06-24 19:31           ` Daniel Vetter
  2020-06-24 19:40             ` Alex Deucher
  0 siblings, 1 reply; 69+ messages in thread
From: Daniel Vetter @ 2020-06-24 19:31 UTC (permalink / raw)
  To: Alex Deucher
  Cc: Laurent Pinchart, Jernej Skrabec, Laurent Pinchart,
	Jonas Karlman, Neil Armstrong, Kieran Bingham,
	Maling list - DRI developers, open list:DRM DRIVERS FOR RENESAS,
	Andrzej Hajda, Thomas Zimmermann, Sam Ravnborg

On Wed, Jun 24, 2020 at 5:24 PM Alex Deucher <alexdeucher@gmail.com> wrote:
>
> On Wed, Jun 24, 2020 at 3:23 AM Daniel Vetter <daniel@ffwll.ch> wrote:
> >
> > On Wed, Jun 24, 2020 at 04:12:09AM +0300, Laurent Pinchart wrote:
> > > Hi Sam,
> > >
> > > On Sun, Jun 21, 2020 at 10:40:00AM +0200, Sam Ravnborg wrote:
> > > > On Tue, May 26, 2020 at 04:15:05AM +0300, Laurent Pinchart wrote:
> > > > > The DRM CRTC helpers add default modes to connectors in the connected
> > > > > state if no mode can be retrieved from the connector. This behaviour is
> > > > > useful for VGA or DVI outputs that have no connected DDC bus. However,
> > > > > in such cases, the status of the output usually can't be retrieved and
> > > > > is reported as connector_status_unknown.
> > > > >
> > > > > Extend the addition of default modes to connectors in an unknown state
> > > > > to support outputs that can retrieve neither the modes nor the
> > > > > connection status.
> > > > >
> > > > > Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> > > >
> > > > From your description sounds like an OK approach.
> > > > But this is not something I feel too familiar with.
> > > > Acked-by: Sam Ravnborg <sam@ravnborg.org>
> > >
> > > Thanks for the ack. I'd like to have Daniel's (CC'ed) feedback on this
> > > too.
> >
> > Makes sense, and at least pre-coffee me can't immediately think of a
> > scenario where we're going to regret this. _unknown status is pretty much
> > limited to old VGA and similar things where load detect somehow isn't well
> > supported by the hw.
> >
> > Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> >
> > >
> > > > > ---
> > > > >  drivers/gpu/drm/drm_probe_helper.c       | 3 ++-
> > > > >  include/drm/drm_modeset_helper_vtables.h | 8 +++++++-
> > > > >  2 files changed, 9 insertions(+), 2 deletions(-)
> > > > >
> > > > > diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
> > > > > index f5d141e0400f..9055d9573c90 100644
> > > > > --- a/drivers/gpu/drm/drm_probe_helper.c
> > > > > +++ b/drivers/gpu/drm/drm_probe_helper.c
> > > > > @@ -491,7 +491,8 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
> > > > >   if (count == 0 && connector->status == connector_status_connected)
> > > > >           count = drm_add_override_edid_modes(connector);
> > > > >
> > > > > - if (count == 0 && connector->status == connector_status_connected)
> > > > > + if (count == 0 && (connector->status == connector_status_connected ||
> > > > > +                    connector->status == connector_status_unknown))
> > > > >           count = drm_add_modes_noedid(connector, 1024, 768);
> > > > >   count += drm_helper_probe_add_cmdline_mode(connector);
> > > > >   if (count == 0)
> > > > > diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
> > > > > index 421a30f08463..afe55e2e93d2 100644
> > > > > --- a/include/drm/drm_modeset_helper_vtables.h
> > > > > +++ b/include/drm/drm_modeset_helper_vtables.h
> > > > > @@ -876,13 +876,19 @@ struct drm_connector_helper_funcs {
> > > > >    * The usual way to implement this is to cache the EDID retrieved in the
> > > > >    * probe callback somewhere in the driver-private connector structure.
> > > > >    * In this function drivers then parse the modes in the EDID and add
> > > > > -  * them by calling drm_add_edid_modes(). But connectors that driver a
> > > > > +  * them by calling drm_add_edid_modes(). But connectors that drive a
> > > > >    * fixed panel can also manually add specific modes using
> > > > >    * drm_mode_probed_add(). Drivers which manually add modes should also
> > > > >    * make sure that the &drm_connector.display_info,
> > > > >    * &drm_connector.width_mm and &drm_connector.height_mm fields are
> > > > >    * filled in.
> > > > >    *
> > > > > +  * Note that the caller function will automatically add standard VESA
> > > > > +  * DMT modes up to 1024x768 if the .get_modes() helper operation returns
> > > > > +  * no mode and if the connector status is connector_status_connected or
> > > > > +  * connector_status_unknown. There is no need to call
> > > > > +  * drm_add_edid_modes() manually in that case.
> >
> > Hm calling drm_add_edid_modes if you have no edid is a bit a funny idea
> > ... Personally I'd just leave out the last sentence, I think that only
> > confuses readers. Or I'm not grasphing what you're trying to tell here.
>
> IIRC, some drivers used and desktop environments expected unknown
> rather than off for LVDS/eDP panels when the lid was shut or if the
> mux was switched to another device in the case of hybrid laptops.

We seem to have totally ditched that in

commit 05c72e77ccda89ff624108b1b59a0fc43843f343
Author: Ville Syrjälä <ville.syrjala@linux.intel.com>
Date:   Tue Jul 17 20:42:14 2018 +0300

    drm/i915: Nuke the LVDS lid notifier

No screaming yet.

But I'm also a bit confused, for a panel there's generally an edid
around, or a fixed (list of) modes. That's enough to stop this
fallback from running, so should be all fine.
-Daniell

>
> Alex
>
>
> >
> > r-b with or without this change since imo super tiny nit.
> >
> > Cheers, Daniel
> >
> > > > > +  *
> > > > >    * Virtual drivers that just want some standard VESA mode with a given
> > > > >    * resolution can call drm_add_modes_noedid(), and mark the preferred
> > > > >    * one using drm_set_preferred_mode().
> > >
> > > --
> > > Regards,
> > >
> > > Laurent Pinchart
> >
> > --
> > Daniel Vetter
> > Software Engineer, Intel Corporation
> > http://blog.ffwll.ch
> > _______________________________________________
> > dri-devel mailing list
> > dri-devel@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/dri-devel



-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

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

* Re: [PATCH 27/27] drm: Add default modes for connectors in unknown state
  2020-06-24 19:31           ` Daniel Vetter
@ 2020-06-24 19:40             ` Alex Deucher
  2020-06-25  7:56               ` Daniel Vetter
  0 siblings, 1 reply; 69+ messages in thread
From: Alex Deucher @ 2020-06-24 19:40 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Laurent Pinchart, Jernej Skrabec, Laurent Pinchart,
	Jonas Karlman, Neil Armstrong, Kieran Bingham,
	Maling list - DRI developers, open list:DRM DRIVERS FOR RENESAS,
	Andrzej Hajda, Thomas Zimmermann, Sam Ravnborg

On Wed, Jun 24, 2020 at 3:31 PM Daniel Vetter <daniel@ffwll.ch> wrote:
>
> On Wed, Jun 24, 2020 at 5:24 PM Alex Deucher <alexdeucher@gmail.com> wrote:
> >
> > On Wed, Jun 24, 2020 at 3:23 AM Daniel Vetter <daniel@ffwll.ch> wrote:
> > >
> > > On Wed, Jun 24, 2020 at 04:12:09AM +0300, Laurent Pinchart wrote:
> > > > Hi Sam,
> > > >
> > > > On Sun, Jun 21, 2020 at 10:40:00AM +0200, Sam Ravnborg wrote:
> > > > > On Tue, May 26, 2020 at 04:15:05AM +0300, Laurent Pinchart wrote:
> > > > > > The DRM CRTC helpers add default modes to connectors in the connected
> > > > > > state if no mode can be retrieved from the connector. This behaviour is
> > > > > > useful for VGA or DVI outputs that have no connected DDC bus. However,
> > > > > > in such cases, the status of the output usually can't be retrieved and
> > > > > > is reported as connector_status_unknown.
> > > > > >
> > > > > > Extend the addition of default modes to connectors in an unknown state
> > > > > > to support outputs that can retrieve neither the modes nor the
> > > > > > connection status.
> > > > > >
> > > > > > Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> > > > >
> > > > > From your description sounds like an OK approach.
> > > > > But this is not something I feel too familiar with.
> > > > > Acked-by: Sam Ravnborg <sam@ravnborg.org>
> > > >
> > > > Thanks for the ack. I'd like to have Daniel's (CC'ed) feedback on this
> > > > too.
> > >
> > > Makes sense, and at least pre-coffee me can't immediately think of a
> > > scenario where we're going to regret this. _unknown status is pretty much
> > > limited to old VGA and similar things where load detect somehow isn't well
> > > supported by the hw.
> > >
> > > Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > >
> > > >
> > > > > > ---
> > > > > >  drivers/gpu/drm/drm_probe_helper.c       | 3 ++-
> > > > > >  include/drm/drm_modeset_helper_vtables.h | 8 +++++++-
> > > > > >  2 files changed, 9 insertions(+), 2 deletions(-)
> > > > > >
> > > > > > diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
> > > > > > index f5d141e0400f..9055d9573c90 100644
> > > > > > --- a/drivers/gpu/drm/drm_probe_helper.c
> > > > > > +++ b/drivers/gpu/drm/drm_probe_helper.c
> > > > > > @@ -491,7 +491,8 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
> > > > > >   if (count == 0 && connector->status == connector_status_connected)
> > > > > >           count = drm_add_override_edid_modes(connector);
> > > > > >
> > > > > > - if (count == 0 && connector->status == connector_status_connected)
> > > > > > + if (count == 0 && (connector->status == connector_status_connected ||
> > > > > > +                    connector->status == connector_status_unknown))
> > > > > >           count = drm_add_modes_noedid(connector, 1024, 768);
> > > > > >   count += drm_helper_probe_add_cmdline_mode(connector);
> > > > > >   if (count == 0)
> > > > > > diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
> > > > > > index 421a30f08463..afe55e2e93d2 100644
> > > > > > --- a/include/drm/drm_modeset_helper_vtables.h
> > > > > > +++ b/include/drm/drm_modeset_helper_vtables.h
> > > > > > @@ -876,13 +876,19 @@ struct drm_connector_helper_funcs {
> > > > > >    * The usual way to implement this is to cache the EDID retrieved in the
> > > > > >    * probe callback somewhere in the driver-private connector structure.
> > > > > >    * In this function drivers then parse the modes in the EDID and add
> > > > > > -  * them by calling drm_add_edid_modes(). But connectors that driver a
> > > > > > +  * them by calling drm_add_edid_modes(). But connectors that drive a
> > > > > >    * fixed panel can also manually add specific modes using
> > > > > >    * drm_mode_probed_add(). Drivers which manually add modes should also
> > > > > >    * make sure that the &drm_connector.display_info,
> > > > > >    * &drm_connector.width_mm and &drm_connector.height_mm fields are
> > > > > >    * filled in.
> > > > > >    *
> > > > > > +  * Note that the caller function will automatically add standard VESA
> > > > > > +  * DMT modes up to 1024x768 if the .get_modes() helper operation returns
> > > > > > +  * no mode and if the connector status is connector_status_connected or
> > > > > > +  * connector_status_unknown. There is no need to call
> > > > > > +  * drm_add_edid_modes() manually in that case.
> > >
> > > Hm calling drm_add_edid_modes if you have no edid is a bit a funny idea
> > > ... Personally I'd just leave out the last sentence, I think that only
> > > confuses readers. Or I'm not grasphing what you're trying to tell here.
> >
> > IIRC, some drivers used and desktop environments expected unknown
> > rather than off for LVDS/eDP panels when the lid was shut or if the
> > mux was switched to another device in the case of hybrid laptops.
>
> We seem to have totally ditched that in
>
> commit 05c72e77ccda89ff624108b1b59a0fc43843f343
> Author: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Date:   Tue Jul 17 20:42:14 2018 +0300
>
>     drm/i915: Nuke the LVDS lid notifier
>
> No screaming yet.
>
> But I'm also a bit confused, for a panel there's generally an edid
> around, or a fixed (list of) modes. That's enough to stop this
> fallback from running, so should be all fine.

No, you are right; you will have the EDID so this shouldn't be an
issue.  I was mis-remembering the original issue.  We originally
always reported connected for LVDS in radeon if the panel was present,
but then we got flack because some userspace expected unknown in
certain cases (e.g., lid or muxed displays).  Either way the EDID info
is still there.

Alex


> -Daniell
>
> >
> > Alex
> >
> >
> > >
> > > r-b with or without this change since imo super tiny nit.
> > >
> > > Cheers, Daniel
> > >
> > > > > > +  *
> > > > > >    * Virtual drivers that just want some standard VESA mode with a given
> > > > > >    * resolution can call drm_add_modes_noedid(), and mark the preferred
> > > > > >    * one using drm_set_preferred_mode().
> > > >
> > > > --
> > > > Regards,
> > > >
> > > > Laurent Pinchart
> > >
> > > --
> > > Daniel Vetter
> > > Software Engineer, Intel Corporation
> > > http://blog.ffwll.ch
> > > _______________________________________________
> > > dri-devel mailing list
> > > dri-devel@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/dri-devel
>
>
>
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch

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

* Re: [PATCH 27/27] drm: Add default modes for connectors in unknown state
  2020-06-24  7:23       ` Daniel Vetter
  2020-06-24 15:24         ` Alex Deucher
@ 2020-06-24 22:47         ` Laurent Pinchart
  1 sibling, 0 replies; 69+ messages in thread
From: Laurent Pinchart @ 2020-06-24 22:47 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Sam Ravnborg, Laurent Pinchart, dri-devel, Jernej Skrabec,
	Neil Armstrong, Jonas Karlman, Kieran Bingham, linux-renesas-soc,
	Andrzej Hajda, Thomas Zimmermann

Hi Daniel,

On Wed, Jun 24, 2020 at 09:23:04AM +0200, Daniel Vetter wrote:
> On Wed, Jun 24, 2020 at 04:12:09AM +0300, Laurent Pinchart wrote:
> > On Sun, Jun 21, 2020 at 10:40:00AM +0200, Sam Ravnborg wrote:
> > > On Tue, May 26, 2020 at 04:15:05AM +0300, Laurent Pinchart wrote:
> > > > The DRM CRTC helpers add default modes to connectors in the connected
> > > > state if no mode can be retrieved from the connector. This behaviour is
> > > > useful for VGA or DVI outputs that have no connected DDC bus. However,
> > > > in such cases, the status of the output usually can't be retrieved and
> > > > is reported as connector_status_unknown.
> > > > 
> > > > Extend the addition of default modes to connectors in an unknown state
> > > > to support outputs that can retrieve neither the modes nor the
> > > > connection status.
> > > > 
> > > > Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> > > 
> > > From your description sounds like an OK approach.
> > > But this is not something I feel too familiar with.
> > > Acked-by: Sam Ravnborg <sam@ravnborg.org>
> > 
> > Thanks for the ack. I'd like to have Daniel's (CC'ed) feedback on this
> > too.
> 
> Makes sense, and at least pre-coffee me can't immediately think of a
> scenario where we're going to regret this. _unknown status is pretty much
> limited to old VGA and similar things where load detect somehow isn't well
> supported by the hw.
> 
> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> 
> > > > ---
> > > >  drivers/gpu/drm/drm_probe_helper.c       | 3 ++-
> > > >  include/drm/drm_modeset_helper_vtables.h | 8 +++++++-
> > > >  2 files changed, 9 insertions(+), 2 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
> > > > index f5d141e0400f..9055d9573c90 100644
> > > > --- a/drivers/gpu/drm/drm_probe_helper.c
> > > > +++ b/drivers/gpu/drm/drm_probe_helper.c
> > > > @@ -491,7 +491,8 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
> > > >  	if (count == 0 && connector->status == connector_status_connected)
> > > >  		count = drm_add_override_edid_modes(connector);
> > > >  
> > > > -	if (count == 0 && connector->status == connector_status_connected)
> > > > +	if (count == 0 && (connector->status == connector_status_connected ||
> > > > +			   connector->status == connector_status_unknown))
> > > >  		count = drm_add_modes_noedid(connector, 1024, 768);
> > > >  	count += drm_helper_probe_add_cmdline_mode(connector);
> > > >  	if (count == 0)
> > > > diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
> > > > index 421a30f08463..afe55e2e93d2 100644
> > > > --- a/include/drm/drm_modeset_helper_vtables.h
> > > > +++ b/include/drm/drm_modeset_helper_vtables.h
> > > > @@ -876,13 +876,19 @@ struct drm_connector_helper_funcs {
> > > >  	 * The usual way to implement this is to cache the EDID retrieved in the
> > > >  	 * probe callback somewhere in the driver-private connector structure.
> > > >  	 * In this function drivers then parse the modes in the EDID and add
> > > > -	 * them by calling drm_add_edid_modes(). But connectors that driver a
> > > > +	 * them by calling drm_add_edid_modes(). But connectors that drive a
> > > >  	 * fixed panel can also manually add specific modes using
> > > >  	 * drm_mode_probed_add(). Drivers which manually add modes should also
> > > >  	 * make sure that the &drm_connector.display_info,
> > > >  	 * &drm_connector.width_mm and &drm_connector.height_mm fields are
> > > >  	 * filled in.
> > > >  	 *
> > > > +	 * Note that the caller function will automatically add standard VESA
> > > > +	 * DMT modes up to 1024x768 if the .get_modes() helper operation returns
> > > > +	 * no mode and if the connector status is connector_status_connected or
> > > > +	 * connector_status_unknown. There is no need to call
> > > > +	 * drm_add_edid_modes() manually in that case.
> 
> Hm calling drm_add_edid_modes if you have no edid is a bit a funny idea
> ... Personally I'd just leave out the last sentence, I think that only
> confuses readers. Or I'm not grasphing what you're trying to tell here.

Sorry, I meant drm_add_modes_noedid(). Is that clearer ?

> r-b with or without this change since imo super tiny nit.
> 
> > > > +	 *
> > > >  	 * Virtual drivers that just want some standard VESA mode with a given
> > > >  	 * resolution can call drm_add_modes_noedid(), and mark the preferred
> > > >  	 * one using drm_set_preferred_mode().

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 27/27] drm: Add default modes for connectors in unknown state
  2020-06-24 19:40             ` Alex Deucher
@ 2020-06-25  7:56               ` Daniel Vetter
  2020-06-25  7:57                 ` Daniel Vetter
  0 siblings, 1 reply; 69+ messages in thread
From: Daniel Vetter @ 2020-06-25  7:56 UTC (permalink / raw)
  To: Alex Deucher
  Cc: Daniel Vetter, Laurent Pinchart, Jernej Skrabec,
	Laurent Pinchart, Jonas Karlman, Neil Armstrong, Kieran Bingham,
	Maling list - DRI developers, open list:DRM DRIVERS FOR RENESAS,
	Andrzej Hajda, Thomas Zimmermann, Sam Ravnborg

On Wed, Jun 24, 2020 at 03:40:42PM -0400, Alex Deucher wrote:
> On Wed, Jun 24, 2020 at 3:31 PM Daniel Vetter <daniel@ffwll.ch> wrote:
> >
> > On Wed, Jun 24, 2020 at 5:24 PM Alex Deucher <alexdeucher@gmail.com> wrote:
> > >
> > > On Wed, Jun 24, 2020 at 3:23 AM Daniel Vetter <daniel@ffwll.ch> wrote:
> > > >
> > > > On Wed, Jun 24, 2020 at 04:12:09AM +0300, Laurent Pinchart wrote:
> > > > > Hi Sam,
> > > > >
> > > > > On Sun, Jun 21, 2020 at 10:40:00AM +0200, Sam Ravnborg wrote:
> > > > > > On Tue, May 26, 2020 at 04:15:05AM +0300, Laurent Pinchart wrote:
> > > > > > > The DRM CRTC helpers add default modes to connectors in the connected
> > > > > > > state if no mode can be retrieved from the connector. This behaviour is
> > > > > > > useful for VGA or DVI outputs that have no connected DDC bus. However,
> > > > > > > in such cases, the status of the output usually can't be retrieved and
> > > > > > > is reported as connector_status_unknown.
> > > > > > >
> > > > > > > Extend the addition of default modes to connectors in an unknown state
> > > > > > > to support outputs that can retrieve neither the modes nor the
> > > > > > > connection status.
> > > > > > >
> > > > > > > Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> > > > > >
> > > > > > From your description sounds like an OK approach.
> > > > > > But this is not something I feel too familiar with.
> > > > > > Acked-by: Sam Ravnborg <sam@ravnborg.org>
> > > > >
> > > > > Thanks for the ack. I'd like to have Daniel's (CC'ed) feedback on this
> > > > > too.
> > > >
> > > > Makes sense, and at least pre-coffee me can't immediately think of a
> > > > scenario where we're going to regret this. _unknown status is pretty much
> > > > limited to old VGA and similar things where load detect somehow isn't well
> > > > supported by the hw.
> > > >
> > > > Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > > >
> > > > >
> > > > > > > ---
> > > > > > >  drivers/gpu/drm/drm_probe_helper.c       | 3 ++-
> > > > > > >  include/drm/drm_modeset_helper_vtables.h | 8 +++++++-
> > > > > > >  2 files changed, 9 insertions(+), 2 deletions(-)
> > > > > > >
> > > > > > > diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
> > > > > > > index f5d141e0400f..9055d9573c90 100644
> > > > > > > --- a/drivers/gpu/drm/drm_probe_helper.c
> > > > > > > +++ b/drivers/gpu/drm/drm_probe_helper.c
> > > > > > > @@ -491,7 +491,8 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
> > > > > > >   if (count == 0 && connector->status == connector_status_connected)
> > > > > > >           count = drm_add_override_edid_modes(connector);
> > > > > > >
> > > > > > > - if (count == 0 && connector->status == connector_status_connected)
> > > > > > > + if (count == 0 && (connector->status == connector_status_connected ||
> > > > > > > +                    connector->status == connector_status_unknown))
> > > > > > >           count = drm_add_modes_noedid(connector, 1024, 768);
> > > > > > >   count += drm_helper_probe_add_cmdline_mode(connector);
> > > > > > >   if (count == 0)
> > > > > > > diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
> > > > > > > index 421a30f08463..afe55e2e93d2 100644
> > > > > > > --- a/include/drm/drm_modeset_helper_vtables.h
> > > > > > > +++ b/include/drm/drm_modeset_helper_vtables.h
> > > > > > > @@ -876,13 +876,19 @@ struct drm_connector_helper_funcs {
> > > > > > >    * The usual way to implement this is to cache the EDID retrieved in the
> > > > > > >    * probe callback somewhere in the driver-private connector structure.
> > > > > > >    * In this function drivers then parse the modes in the EDID and add
> > > > > > > -  * them by calling drm_add_edid_modes(). But connectors that driver a
> > > > > > > +  * them by calling drm_add_edid_modes(). But connectors that drive a
> > > > > > >    * fixed panel can also manually add specific modes using
> > > > > > >    * drm_mode_probed_add(). Drivers which manually add modes should also
> > > > > > >    * make sure that the &drm_connector.display_info,
> > > > > > >    * &drm_connector.width_mm and &drm_connector.height_mm fields are
> > > > > > >    * filled in.
> > > > > > >    *
> > > > > > > +  * Note that the caller function will automatically add standard VESA
> > > > > > > +  * DMT modes up to 1024x768 if the .get_modes() helper operation returns
> > > > > > > +  * no mode and if the connector status is connector_status_connected or
> > > > > > > +  * connector_status_unknown. There is no need to call
> > > > > > > +  * drm_add_edid_modes() manually in that case.
> > > >
> > > > Hm calling drm_add_edid_modes if you have no edid is a bit a funny idea
> > > > ... Personally I'd just leave out the last sentence, I think that only
> > > > confuses readers. Or I'm not grasphing what you're trying to tell here.
> > >
> > > IIRC, some drivers used and desktop environments expected unknown
> > > rather than off for LVDS/eDP panels when the lid was shut or if the
> > > mux was switched to another device in the case of hybrid laptops.
> >
> > We seem to have totally ditched that in
> >
> > commit 05c72e77ccda89ff624108b1b59a0fc43843f343
> > Author: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > Date:   Tue Jul 17 20:42:14 2018 +0300
> >
> >     drm/i915: Nuke the LVDS lid notifier
> >
> > No screaming yet.
> >
> > But I'm also a bit confused, for a panel there's generally an edid
> > around, or a fixed (list of) modes. That's enough to stop this
> > fallback from running, so should be all fine.
> 
> No, you are right; you will have the EDID so this shouldn't be an
> issue.  I was mis-remembering the original issue.  We originally
> always reported connected for LVDS in radeon if the panel was present,
> but then we got flack because some userspace expected unknown in
> certain cases (e.g., lid or muxed displays).  Either way the EDID info
> is still there.

Yeah I think i915 started that habit, but I guess people realized it's
unreliable enough that they should have their own lid handler in the
desktop enviromnent doing whatever they want to do on lid close.

Should we perhaps document that somewhere, that panels are always marked
as connected? Not even sure where to put that in the docs ...

Maybe adding a few of the usual suspects from the compositor side, Simon,
Pekka?
-Daniel

> 
> Alex
> 
> 
> > -Daniell
> >
> > >
> > > Alex
> > >
> > >
> > > >
> > > > r-b with or without this change since imo super tiny nit.
> > > >
> > > > Cheers, Daniel
> > > >
> > > > > > > +  *
> > > > > > >    * Virtual drivers that just want some standard VESA mode with a given
> > > > > > >    * resolution can call drm_add_modes_noedid(), and mark the preferred
> > > > > > >    * one using drm_set_preferred_mode().
> > > > >
> > > > > --
> > > > > Regards,
> > > > >
> > > > > Laurent Pinchart
> > > >
> > > > --
> > > > Daniel Vetter
> > > > Software Engineer, Intel Corporation
> > > > http://blog.ffwll.ch
> > > > _______________________________________________
> > > > dri-devel mailing list
> > > > dri-devel@lists.freedesktop.org
> > > > https://lists.freedesktop.org/mailman/listinfo/dri-devel
> >
> >
> >
> > --
> > Daniel Vetter
> > Software Engineer, Intel Corporation
> > http://blog.ffwll.ch

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

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

* Re: [PATCH 27/27] drm: Add default modes for connectors in unknown state
  2020-06-25  7:56               ` Daniel Vetter
@ 2020-06-25  7:57                 ` Daniel Vetter
  2020-06-25 10:31                   ` Pekka Paalanen
  0 siblings, 1 reply; 69+ messages in thread
From: Daniel Vetter @ 2020-06-25  7:57 UTC (permalink / raw)
  To: Alex Deucher, Simon Ser, Pekka Paalanen
  Cc: Laurent Pinchart, Jernej Skrabec, Laurent Pinchart,
	Jonas Karlman, Neil Armstrong, Kieran Bingham,
	Maling list - DRI developers, open list:DRM DRIVERS FOR RENESAS,
	Andrzej Hajda, Thomas Zimmermann, Sam Ravnborg

On Thu, Jun 25, 2020 at 9:56 AM Daniel Vetter <daniel@ffwll.ch> wrote:
>
> On Wed, Jun 24, 2020 at 03:40:42PM -0400, Alex Deucher wrote:
> > On Wed, Jun 24, 2020 at 3:31 PM Daniel Vetter <daniel@ffwll.ch> wrote:
> > >
> > > On Wed, Jun 24, 2020 at 5:24 PM Alex Deucher <alexdeucher@gmail.com> wrote:
> > > >
> > > > On Wed, Jun 24, 2020 at 3:23 AM Daniel Vetter <daniel@ffwll.ch> wrote:
> > > > >
> > > > > On Wed, Jun 24, 2020 at 04:12:09AM +0300, Laurent Pinchart wrote:
> > > > > > Hi Sam,
> > > > > >
> > > > > > On Sun, Jun 21, 2020 at 10:40:00AM +0200, Sam Ravnborg wrote:
> > > > > > > On Tue, May 26, 2020 at 04:15:05AM +0300, Laurent Pinchart wrote:
> > > > > > > > The DRM CRTC helpers add default modes to connectors in the connected
> > > > > > > > state if no mode can be retrieved from the connector. This behaviour is
> > > > > > > > useful for VGA or DVI outputs that have no connected DDC bus. However,
> > > > > > > > in such cases, the status of the output usually can't be retrieved and
> > > > > > > > is reported as connector_status_unknown.
> > > > > > > >
> > > > > > > > Extend the addition of default modes to connectors in an unknown state
> > > > > > > > to support outputs that can retrieve neither the modes nor the
> > > > > > > > connection status.
> > > > > > > >
> > > > > > > > Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> > > > > > >
> > > > > > > From your description sounds like an OK approach.
> > > > > > > But this is not something I feel too familiar with.
> > > > > > > Acked-by: Sam Ravnborg <sam@ravnborg.org>
> > > > > >
> > > > > > Thanks for the ack. I'd like to have Daniel's (CC'ed) feedback on this
> > > > > > too.
> > > > >
> > > > > Makes sense, and at least pre-coffee me can't immediately think of a
> > > > > scenario where we're going to regret this. _unknown status is pretty much
> > > > > limited to old VGA and similar things where load detect somehow isn't well
> > > > > supported by the hw.
> > > > >
> > > > > Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > > > >
> > > > > >
> > > > > > > > ---
> > > > > > > >  drivers/gpu/drm/drm_probe_helper.c       | 3 ++-
> > > > > > > >  include/drm/drm_modeset_helper_vtables.h | 8 +++++++-
> > > > > > > >  2 files changed, 9 insertions(+), 2 deletions(-)
> > > > > > > >
> > > > > > > > diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
> > > > > > > > index f5d141e0400f..9055d9573c90 100644
> > > > > > > > --- a/drivers/gpu/drm/drm_probe_helper.c
> > > > > > > > +++ b/drivers/gpu/drm/drm_probe_helper.c
> > > > > > > > @@ -491,7 +491,8 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
> > > > > > > >   if (count == 0 && connector->status == connector_status_connected)
> > > > > > > >           count = drm_add_override_edid_modes(connector);
> > > > > > > >
> > > > > > > > - if (count == 0 && connector->status == connector_status_connected)
> > > > > > > > + if (count == 0 && (connector->status == connector_status_connected ||
> > > > > > > > +                    connector->status == connector_status_unknown))
> > > > > > > >           count = drm_add_modes_noedid(connector, 1024, 768);
> > > > > > > >   count += drm_helper_probe_add_cmdline_mode(connector);
> > > > > > > >   if (count == 0)
> > > > > > > > diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
> > > > > > > > index 421a30f08463..afe55e2e93d2 100644
> > > > > > > > --- a/include/drm/drm_modeset_helper_vtables.h
> > > > > > > > +++ b/include/drm/drm_modeset_helper_vtables.h
> > > > > > > > @@ -876,13 +876,19 @@ struct drm_connector_helper_funcs {
> > > > > > > >    * The usual way to implement this is to cache the EDID retrieved in the
> > > > > > > >    * probe callback somewhere in the driver-private connector structure.
> > > > > > > >    * In this function drivers then parse the modes in the EDID and add
> > > > > > > > -  * them by calling drm_add_edid_modes(). But connectors that driver a
> > > > > > > > +  * them by calling drm_add_edid_modes(). But connectors that drive a
> > > > > > > >    * fixed panel can also manually add specific modes using
> > > > > > > >    * drm_mode_probed_add(). Drivers which manually add modes should also
> > > > > > > >    * make sure that the &drm_connector.display_info,
> > > > > > > >    * &drm_connector.width_mm and &drm_connector.height_mm fields are
> > > > > > > >    * filled in.
> > > > > > > >    *
> > > > > > > > +  * Note that the caller function will automatically add standard VESA
> > > > > > > > +  * DMT modes up to 1024x768 if the .get_modes() helper operation returns
> > > > > > > > +  * no mode and if the connector status is connector_status_connected or
> > > > > > > > +  * connector_status_unknown. There is no need to call
> > > > > > > > +  * drm_add_edid_modes() manually in that case.
> > > > >
> > > > > Hm calling drm_add_edid_modes if you have no edid is a bit a funny idea
> > > > > ... Personally I'd just leave out the last sentence, I think that only
> > > > > confuses readers. Or I'm not grasphing what you're trying to tell here.
> > > >
> > > > IIRC, some drivers used and desktop environments expected unknown
> > > > rather than off for LVDS/eDP panels when the lid was shut or if the
> > > > mux was switched to another device in the case of hybrid laptops.
> > >
> > > We seem to have totally ditched that in
> > >
> > > commit 05c72e77ccda89ff624108b1b59a0fc43843f343
> > > Author: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > Date:   Tue Jul 17 20:42:14 2018 +0300
> > >
> > >     drm/i915: Nuke the LVDS lid notifier
> > >
> > > No screaming yet.
> > >
> > > But I'm also a bit confused, for a panel there's generally an edid
> > > around, or a fixed (list of) modes. That's enough to stop this
> > > fallback from running, so should be all fine.
> >
> > No, you are right; you will have the EDID so this shouldn't be an
> > issue.  I was mis-remembering the original issue.  We originally
> > always reported connected for LVDS in radeon if the panel was present,
> > but then we got flack because some userspace expected unknown in
> > certain cases (e.g., lid or muxed displays).  Either way the EDID info
> > is still there.
>
> Yeah I think i915 started that habit, but I guess people realized it's
> unreliable enough that they should have their own lid handler in the
> desktop enviromnent doing whatever they want to do on lid close.
>
> Should we perhaps document that somewhere, that panels are always marked
> as connected? Not even sure where to put that in the docs ...
>
> Maybe adding a few of the usual suspects from the compositor side, Simon,
> Pekka?

Actually adding Simon and Pekka this time around ...

> -Daniel
>
> >
> > Alex
> >
> >
> > > -Daniell
> > >
> > > >
> > > > Alex
> > > >
> > > >
> > > > >
> > > > > r-b with or without this change since imo super tiny nit.
> > > > >
> > > > > Cheers, Daniel
> > > > >
> > > > > > > > +  *
> > > > > > > >    * Virtual drivers that just want some standard VESA mode with a given
> > > > > > > >    * resolution can call drm_add_modes_noedid(), and mark the preferred
> > > > > > > >    * one using drm_set_preferred_mode().
> > > > > >
> > > > > > --
> > > > > > Regards,
> > > > > >
> > > > > > Laurent Pinchart
> > > > >
> > > > > --
> > > > > Daniel Vetter
> > > > > Software Engineer, Intel Corporation
> > > > > http://blog.ffwll.ch
> > > > > _______________________________________________
> > > > > dri-devel mailing list
> > > > > dri-devel@lists.freedesktop.org
> > > > > https://lists.freedesktop.org/mailman/listinfo/dri-devel
> > >
> > >
> > >
> > > --
> > > Daniel Vetter
> > > Software Engineer, Intel Corporation
> > > http://blog.ffwll.ch
>
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch



-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

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

* Re: [PATCH 00/27] Converter R-Car DU to the DRM bridge connector helper
  2020-06-23 18:55 ` [PATCH 00/27] Converter R-Car DU to the DRM bridge connector helper Sam Ravnborg
@ 2020-06-25  8:48   ` Liu Ying
  2020-06-27 19:55     ` Sam Ravnborg
  0 siblings, 1 reply; 69+ messages in thread
From: Liu Ying @ 2020-06-25  8:48 UTC (permalink / raw)
  To: Sam Ravnborg, Laurent Pinchart
  Cc: Jernej Skrabec, Jonas Karlman, Neil Armstrong, Kieran Bingham,
	dri-devel, linux-renesas-soc, Andrzej Hajda

Hi Sam,

On Tue, 2020-06-23 at 20:55 +0200, Sam Ravnborg wrote:
> Hi Laurent.
> 
> On Tue, May 26, 2020 at 04:14:38AM +0300, Laurent Pinchart wrote:
> > Hello,
> > 
> > This patch series converts the R-Car DU driver to use the DRM
> > bridge
> > connector helper drm_bridge_connector_init().
> > 
> > The bulk of the series is conversion of the adv7511, simple-bridge,
> > rcar-lbds and dw-hdmi drivers to make connector creation optional
> > (through the DRM_BRIDGE_ATTACH_NO_CONNECTOR flag).
> > 
> > The series starts with the adv7511 driver, previously posted as
> > "[PATCH
> > 0/4] drm: bridge: adv7511: Enable usage with DRM bridge connector
> > helper" ([1]). Patches 01/27 to 04/27 incorporate all the received
> > review comments.
> > 
> > The next three patches address the simple-bridge driver, previously
> > posted as "[PATCH 0/2] drm: bridge: simple-bridge: Enable usage
> > with DRM
> > bridge connector helper". Patch 05/27 is an additional fix that
> > stems
> > from the review, and patches 06/27 and 07/27 incorporate all the
> > received review comments.
> > 
> > Patch 08/27 is a new patch that addresses the rcar-lvds driver.
> > Instead
> > of implementing direct support for DRM_BRIDGE_ATTACH_NO_CONNECTOR,
> > it
> > simply removes code that shouldn't have been in the driver in the
> > first
> > place by switching to the panel bridge helper.
> > 
> > Patches 09/27 to 22/27 then address the dw-hdmi driver. That's a
> > more
> > sizeable rework, due to the fact that the driver implements a mid-
> > layer
> > for platform-specific glue, with the internal drm_connector being
> > used
> > throughout the whole code. There's no rocket science there, but
> > patch
> > 10/27 should be noted for adding a new argument to the
> > drm_bridge_funcs.mode_valid() function. Please see individual
> > patches
> > for details.
> > 
> > Patch 23/27 adds support to the dw-hdmi driver to attach to a
> > downstream
> > bridge if one is specified in DT. As the DT port number
> > corresponding to
> > the video output differs between platforms that integrate the dw-
> > hdmi
> > (some of them even don't have a video output port, which should
> > probably
> > be fixed, but that's out of scope for this series), the port number
> > has
> > to be specified by the platform glue layer. Patch 24/27 does so for
> > the
> > R-Car dw-hdmi driver.
> > 
> > Patch 25/27 is a drive-by fix for an error path issue in the rcar-
> > du
> > driver. Patch 26/27 finally makes use of the
> > drm_bridge_connector_init()
> > helper.
> > 
> > Unfortunately, this breaks the VGA output on R-Car Gen3 platforms.
> > On
> > those platforms, the VGA DDC lines are not connected, and there is
> > no
> > mean for software to detect the VGA output connection status. When
> > the
> > simple-bridge driver creates a connector, it automatically adds
> > default
> > modes when no DDC is available. This behavious is also present int
> > the
> > DRM probe helper drm_helper_probe_single_connector_modes(), but
> > only
> > when the connector status is connector_status_connected. As the
> > driver
> > (rightfully) reports connector_status_unconnected, no modes are
> > added.
> > Patch 27/27 fixes this issue by extending addition of default modes
> > in
> > drm_helper_probe_single_connector_modes() when the output status is
> > unknown. An alternative approach would be to implement this
> > behaviour in
> > the bridge connector helper (drm_bridge_connector.c).
> > 
> > All the modified drivers have been compile-tested, and the series
> > has
> > been tested on a Renesas R-Car Salvator-XS board with the VGA, HDMI
> > and
> > LVDS outputs.
> > 
> > [1] 
> > https://lore.kernel.org/dri-devel/20200409004610.12346-1-laurent.pinchart+renesas@ideasonboard.com/
> > [2] 
> > https://lore.kernel.org/dri-devel/20200409003636.11792-1-laurent.pinchart+renesas@ideasonboard.com/
> 
> As we briefly discussed on IRC the first 21 patches are now applied
> to
> drm-misc-next.

I see patch '[22/27] drm: bridge: dw-hdmi: Make connector creation
optional' is applied to drm-misc-next.
That patch would introduce an uninitialized mutex accessing issue as I
mentioned in the patch[1]. And, the patch intends to fix the issue in
the first place.

[1] https://patchwork.freedesktop.org/patch/370560/


Regards,
Liu Ying

> The rcar-du specific patches was left out and the last patch was
> likewise not applied in this round- mostly because it was the coming
> after several rcar-du patches and I was not sure if there was some
> dependencies to consider.
> 
> With this set in we have more examples in the tree how to do proper
> bridges which is good.
> 
> While applying the new r-bs was ofc added.
> 
> 	Sam
> 
> > 
> > Laurent Pinchart (27):
> >   drm: bridge: adv7511: Split EDID read to a separate function
> >   drm: bridge: adv7511: Split connector creation to a separate
> > function
> >   drm: bridge: adv7511: Implement bridge connector operations
> >   drm: bridge: adv7511: Make connector creation optional
> >   drm: bridge: Return NULL on error from drm_bridge_get_edid()
> >   drm: bridge: simple-bridge: Delegate operations to next bridge
> >   drm: bridge: simple-bridge: Make connector creation optional
> >   drm: rcar-du: lvds: Convert to DRM panel bridge helper
> >   drm: edid: Constify connector argument to infoframe functions
> >   drm: bridge: Pass drm_display_info to drm_bridge_funcs
> > .mode_valid()
> >   drm: bridge: dw-hdmi: Pass private data pointer to .mode_valid()
> >   drm: bridge: dw-hdmi: Pass private data pointer to
> > .configure_phy()
> >   drm: bridge: dw-hdmi: Remove unused field from dw_hdmi_plat_data
> >   drm: meson: dw-hdmi: Use dw_hdmi context to replace hack
> >   drm: bridge: dw-hdmi: Pass drm_display_info to .mode_valid()
> >   drm: bridge: dw-hdmi: Constify mode argument to dw_hdmi_phy_ops
> >     .init()
> >   drm: bridge: dw-hdmi: Constify mode argument to internal
> > functions
> >   drm: bridge: dw-hdmi: Pass drm_display_info to
> > dw_hdmi_support_scdc()
> >   drm: bridge: dw-hdmi: Split connector creation to a separate
> > function
> >   drm: bridge: dw-hdmi: Store current connector in struct dw_hdmi
> >   drm: bridge: dw-hdmi: Pass drm_connector to internal functions as
> >     needed
> >   drm: bridge: dw-hdmi: Make connector creation optional
> >   drm: bridge: dw-hdmi: Attach to next bridge if available
> >   drm: rcar-du: dw-hdmi: Set output port number
> >   drm: rcar-du: Fix error handling in rcar_du_encoder_init()
> >   drm: rcar-du: Use drm_bridge_connector_init() helper
> >   drm: Add default modes for connectors in unknown state
> > 
> >  drivers/gpu/drm/bridge/adv7511/adv7511_drv.c  | 159 +++++---
> >  .../drm/bridge/analogix/analogix-anx6345.c    |   1 +
> >  .../drm/bridge/analogix/analogix-anx78xx.c    |   1 +
> >  drivers/gpu/drm/bridge/cdns-dsi.c             |   1 +
> >  drivers/gpu/drm/bridge/chrontel-ch7033.c      |   1 +
> >  drivers/gpu/drm/bridge/nwl-dsi.c              |   1 +
> >  drivers/gpu/drm/bridge/sii9234.c              |   1 +
> >  drivers/gpu/drm/bridge/sil-sii8620.c          |   1 +
> >  drivers/gpu/drm/bridge/simple-bridge.c        | 113 +++---
> >  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c     | 357 ++++++++++++
> > ------
> >  drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c |   1 +
> >  drivers/gpu/drm/bridge/tc358767.c             |   1 +
> >  drivers/gpu/drm/bridge/tc358768.c             |   1 +
> >  drivers/gpu/drm/bridge/thc63lvd1024.c         |   1 +
> >  drivers/gpu/drm/bridge/ti-tfp410.c            |  11 +-
> >  drivers/gpu/drm/drm_atomic_helper.c           |   3 +-
> >  drivers/gpu/drm/drm_bridge.c                  |  10 +-
> >  drivers/gpu/drm/drm_edid.c                    |  12 +-
> >  drivers/gpu/drm/drm_probe_helper.c            |   7 +-
> >  drivers/gpu/drm/i2c/tda998x_drv.c             |   1 +
> >  drivers/gpu/drm/imx/dw_hdmi-imx.c             |   6 +-
> >  drivers/gpu/drm/meson/meson_dw_hdmi.c         |  34 +-
> >  drivers/gpu/drm/omapdrm/dss/dpi.c             |   1 +
> >  drivers/gpu/drm/omapdrm/dss/sdi.c             |   1 +
> >  drivers/gpu/drm/omapdrm/dss/venc.c            |   1 +
> >  drivers/gpu/drm/rcar-du/rcar_du_encoder.c     |  26 +-
> >  drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c        |   7 +-
> >  drivers/gpu/drm/rcar-du/rcar_lvds.c           | 124 +-----
> >  drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c   |   6 +-
> >  drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c         |   6 +-
> >  drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h         |   3 +-
> >  drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c        |   3 +-
> >  include/drm/bridge/dw_hdmi.h                  |  28 +-
> >  include/drm/drm_bridge.h                      |   3 +
> >  include/drm/drm_edid.h                        |   6 +-
> >  include/drm/drm_modeset_helper_vtables.h      |   8 +-
> >  36 files changed, 541 insertions(+), 406 deletions(-)
> > 
> > -- 
> > Regards,
> > 
> > Laurent Pinchart
> > 
> > _______________________________________________
> > dri-devel mailing list
> > dri-devel@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/dri-devel
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel


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

* Re: [PATCH 27/27] drm: Add default modes for connectors in unknown state
  2020-06-25  7:57                 ` Daniel Vetter
@ 2020-06-25 10:31                   ` Pekka Paalanen
  2020-06-25 10:44                     ` Daniel Vetter
  0 siblings, 1 reply; 69+ messages in thread
From: Pekka Paalanen @ 2020-06-25 10:31 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Alex Deucher, Simon Ser, Laurent Pinchart, Jernej Skrabec,
	Laurent Pinchart, Jonas Karlman, Neil Armstrong, Kieran Bingham,
	Maling list - DRI developers, open list:DRM DRIVERS FOR RENESAS,
	Andrzej Hajda, Thomas Zimmermann, Sam Ravnborg

[-- Attachment #1: Type: text/plain, Size: 7981 bytes --]

On Thu, 25 Jun 2020 09:57:44 +0200
Daniel Vetter <daniel@ffwll.ch> wrote:

> On Thu, Jun 25, 2020 at 9:56 AM Daniel Vetter <daniel@ffwll.ch> wrote:
> >
> > On Wed, Jun 24, 2020 at 03:40:42PM -0400, Alex Deucher wrote:  
> > > On Wed, Jun 24, 2020 at 3:31 PM Daniel Vetter <daniel@ffwll.ch> wrote:  
> > > >
> > > > On Wed, Jun 24, 2020 at 5:24 PM Alex Deucher <alexdeucher@gmail.com> wrote:  
> > > > >
> > > > > On Wed, Jun 24, 2020 at 3:23 AM Daniel Vetter <daniel@ffwll.ch> wrote:  
> > > > > >
> > > > > > On Wed, Jun 24, 2020 at 04:12:09AM +0300, Laurent Pinchart wrote:  
> > > > > > > Hi Sam,
> > > > > > >
> > > > > > > On Sun, Jun 21, 2020 at 10:40:00AM +0200, Sam Ravnborg wrote:  
> > > > > > > > On Tue, May 26, 2020 at 04:15:05AM +0300, Laurent Pinchart wrote:  
> > > > > > > > > The DRM CRTC helpers add default modes to connectors in the connected
> > > > > > > > > state if no mode can be retrieved from the connector. This behaviour is
> > > > > > > > > useful for VGA or DVI outputs that have no connected DDC bus. However,
> > > > > > > > > in such cases, the status of the output usually can't be retrieved and
> > > > > > > > > is reported as connector_status_unknown.
> > > > > > > > >
> > > > > > > > > Extend the addition of default modes to connectors in an unknown state
> > > > > > > > > to support outputs that can retrieve neither the modes nor the
> > > > > > > > > connection status.
> > > > > > > > >
> > > > > > > > > Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>  
> > > > > > > >
> > > > > > > > From your description sounds like an OK approach.
> > > > > > > > But this is not something I feel too familiar with.
> > > > > > > > Acked-by: Sam Ravnborg <sam@ravnborg.org>  
> > > > > > >
> > > > > > > Thanks for the ack. I'd like to have Daniel's (CC'ed) feedback on this
> > > > > > > too.  
> > > > > >
> > > > > > Makes sense, and at least pre-coffee me can't immediately think of a
> > > > > > scenario where we're going to regret this. _unknown status is pretty much
> > > > > > limited to old VGA and similar things where load detect somehow isn't well
> > > > > > supported by the hw.
> > > > > >
> > > > > > Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > > > > >  
> > > > > > >  
> > > > > > > > > ---
> > > > > > > > >  drivers/gpu/drm/drm_probe_helper.c       | 3 ++-
> > > > > > > > >  include/drm/drm_modeset_helper_vtables.h | 8 +++++++-
> > > > > > > > >  2 files changed, 9 insertions(+), 2 deletions(-)
> > > > > > > > >
> > > > > > > > > diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
> > > > > > > > > index f5d141e0400f..9055d9573c90 100644
> > > > > > > > > --- a/drivers/gpu/drm/drm_probe_helper.c
> > > > > > > > > +++ b/drivers/gpu/drm/drm_probe_helper.c
> > > > > > > > > @@ -491,7 +491,8 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
> > > > > > > > >   if (count == 0 && connector->status == connector_status_connected)
> > > > > > > > >           count = drm_add_override_edid_modes(connector);
> > > > > > > > >
> > > > > > > > > - if (count == 0 && connector->status == connector_status_connected)
> > > > > > > > > + if (count == 0 && (connector->status == connector_status_connected ||
> > > > > > > > > +                    connector->status == connector_status_unknown))
> > > > > > > > >           count = drm_add_modes_noedid(connector, 1024, 768);
> > > > > > > > >   count += drm_helper_probe_add_cmdline_mode(connector);
> > > > > > > > >   if (count == 0)
> > > > > > > > > diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
> > > > > > > > > index 421a30f08463..afe55e2e93d2 100644
> > > > > > > > > --- a/include/drm/drm_modeset_helper_vtables.h
> > > > > > > > > +++ b/include/drm/drm_modeset_helper_vtables.h
> > > > > > > > > @@ -876,13 +876,19 @@ struct drm_connector_helper_funcs {
> > > > > > > > >    * The usual way to implement this is to cache the EDID retrieved in the
> > > > > > > > >    * probe callback somewhere in the driver-private connector structure.
> > > > > > > > >    * In this function drivers then parse the modes in the EDID and add
> > > > > > > > > -  * them by calling drm_add_edid_modes(). But connectors that driver a
> > > > > > > > > +  * them by calling drm_add_edid_modes(). But connectors that drive a
> > > > > > > > >    * fixed panel can also manually add specific modes using
> > > > > > > > >    * drm_mode_probed_add(). Drivers which manually add modes should also
> > > > > > > > >    * make sure that the &drm_connector.display_info,
> > > > > > > > >    * &drm_connector.width_mm and &drm_connector.height_mm fields are
> > > > > > > > >    * filled in.
> > > > > > > > >    *
> > > > > > > > > +  * Note that the caller function will automatically add standard VESA
> > > > > > > > > +  * DMT modes up to 1024x768 if the .get_modes() helper operation returns
> > > > > > > > > +  * no mode and if the connector status is connector_status_connected or
> > > > > > > > > +  * connector_status_unknown. There is no need to call
> > > > > > > > > +  * drm_add_edid_modes() manually in that case.  
> > > > > >
> > > > > > Hm calling drm_add_edid_modes if you have no edid is a bit a funny idea
> > > > > > ... Personally I'd just leave out the last sentence, I think that only
> > > > > > confuses readers. Or I'm not grasphing what you're trying to tell here.  
> > > > >
> > > > > IIRC, some drivers used and desktop environments expected unknown
> > > > > rather than off for LVDS/eDP panels when the lid was shut or if the
> > > > > mux was switched to another device in the case of hybrid laptops.  
> > > >
> > > > We seem to have totally ditched that in
> > > >
> > > > commit 05c72e77ccda89ff624108b1b59a0fc43843f343
> > > > Author: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > > Date:   Tue Jul 17 20:42:14 2018 +0300
> > > >
> > > >     drm/i915: Nuke the LVDS lid notifier
> > > >
> > > > No screaming yet.
> > > >
> > > > But I'm also a bit confused, for a panel there's generally an edid
> > > > around, or a fixed (list of) modes. That's enough to stop this
> > > > fallback from running, so should be all fine.  
> > >
> > > No, you are right; you will have the EDID so this shouldn't be an
> > > issue.  I was mis-remembering the original issue.  We originally
> > > always reported connected for LVDS in radeon if the panel was present,
> > > but then we got flack because some userspace expected unknown in
> > > certain cases (e.g., lid or muxed displays).  Either way the EDID info
> > > is still there.  
> >
> > Yeah I think i915 started that habit, but I guess people realized it's
> > unreliable enough that they should have their own lid handler in the
> > desktop enviromnent doing whatever they want to do on lid close.
> >
> > Should we perhaps document that somewhere, that panels are always marked
> > as connected? Not even sure where to put that in the docs ...
> >
> > Maybe adding a few of the usual suspects from the compositor side, Simon,
> > Pekka?  
> 
> Actually adding Simon and Pekka this time around ...

I don't know what anyone else does, but Weston (is not a DE) does not
look at any lid switch, and assumes that if connector status is not
DRM_MODE_CONNECTED, then it is disconnected. So, if a driver switched
to "Unknown" status, it would be taken as disconnected.

I never knew what "Unknown" was relevant for. In weston.ini you can
also force a connector on, so users could drive it regardless.

However, I would also say that Weston is not supposed to react to any
lid action exactly because it does not watch the lid switch. Personally
I would expect a built-in screen to stay on even if lid closed.

Panels that are always connected showing up as always connected, sounds
good to me.


Thanks,
pq

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH 27/27] drm: Add default modes for connectors in unknown state
  2020-06-25 10:31                   ` Pekka Paalanen
@ 2020-06-25 10:44                     ` Daniel Vetter
  2020-06-26  8:59                       ` Pekka Paalanen
  0 siblings, 1 reply; 69+ messages in thread
From: Daniel Vetter @ 2020-06-25 10:44 UTC (permalink / raw)
  To: Pekka Paalanen
  Cc: Alex Deucher, Simon Ser, Laurent Pinchart, Jernej Skrabec,
	Laurent Pinchart, Jonas Karlman, Neil Armstrong, Kieran Bingham,
	Maling list - DRI developers, open list:DRM DRIVERS FOR RENESAS,
	Andrzej Hajda, Thomas Zimmermann, Sam Ravnborg

On Thu, Jun 25, 2020 at 12:32 PM Pekka Paalanen <ppaalanen@gmail.com> wrote:
>
> On Thu, 25 Jun 2020 09:57:44 +0200
> Daniel Vetter <daniel@ffwll.ch> wrote:
>
> > On Thu, Jun 25, 2020 at 9:56 AM Daniel Vetter <daniel@ffwll.ch> wrote:
> > >
> > > On Wed, Jun 24, 2020 at 03:40:42PM -0400, Alex Deucher wrote:
> > > > On Wed, Jun 24, 2020 at 3:31 PM Daniel Vetter <daniel@ffwll.ch> wrote:
> > > > >
> > > > > On Wed, Jun 24, 2020 at 5:24 PM Alex Deucher <alexdeucher@gmail.com> wrote:
> > > > > >
> > > > > > On Wed, Jun 24, 2020 at 3:23 AM Daniel Vetter <daniel@ffwll.ch> wrote:
> > > > > > >
> > > > > > > On Wed, Jun 24, 2020 at 04:12:09AM +0300, Laurent Pinchart wrote:
> > > > > > > > Hi Sam,
> > > > > > > >
> > > > > > > > On Sun, Jun 21, 2020 at 10:40:00AM +0200, Sam Ravnborg wrote:
> > > > > > > > > On Tue, May 26, 2020 at 04:15:05AM +0300, Laurent Pinchart wrote:
> > > > > > > > > > The DRM CRTC helpers add default modes to connectors in the connected
> > > > > > > > > > state if no mode can be retrieved from the connector. This behaviour is
> > > > > > > > > > useful for VGA or DVI outputs that have no connected DDC bus. However,
> > > > > > > > > > in such cases, the status of the output usually can't be retrieved and
> > > > > > > > > > is reported as connector_status_unknown.
> > > > > > > > > >
> > > > > > > > > > Extend the addition of default modes to connectors in an unknown state
> > > > > > > > > > to support outputs that can retrieve neither the modes nor the
> > > > > > > > > > connection status.
> > > > > > > > > >
> > > > > > > > > > Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> > > > > > > > >
> > > > > > > > > From your description sounds like an OK approach.
> > > > > > > > > But this is not something I feel too familiar with.
> > > > > > > > > Acked-by: Sam Ravnborg <sam@ravnborg.org>
> > > > > > > >
> > > > > > > > Thanks for the ack. I'd like to have Daniel's (CC'ed) feedback on this
> > > > > > > > too.
> > > > > > >
> > > > > > > Makes sense, and at least pre-coffee me can't immediately think of a
> > > > > > > scenario where we're going to regret this. _unknown status is pretty much
> > > > > > > limited to old VGA and similar things where load detect somehow isn't well
> > > > > > > supported by the hw.
> > > > > > >
> > > > > > > Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > > > > > >
> > > > > > > >
> > > > > > > > > > ---
> > > > > > > > > >  drivers/gpu/drm/drm_probe_helper.c       | 3 ++-
> > > > > > > > > >  include/drm/drm_modeset_helper_vtables.h | 8 +++++++-
> > > > > > > > > >  2 files changed, 9 insertions(+), 2 deletions(-)
> > > > > > > > > >
> > > > > > > > > > diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
> > > > > > > > > > index f5d141e0400f..9055d9573c90 100644
> > > > > > > > > > --- a/drivers/gpu/drm/drm_probe_helper.c
> > > > > > > > > > +++ b/drivers/gpu/drm/drm_probe_helper.c
> > > > > > > > > > @@ -491,7 +491,8 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
> > > > > > > > > >   if (count == 0 && connector->status == connector_status_connected)
> > > > > > > > > >           count = drm_add_override_edid_modes(connector);
> > > > > > > > > >
> > > > > > > > > > - if (count == 0 && connector->status == connector_status_connected)
> > > > > > > > > > + if (count == 0 && (connector->status == connector_status_connected ||
> > > > > > > > > > +                    connector->status == connector_status_unknown))
> > > > > > > > > >           count = drm_add_modes_noedid(connector, 1024, 768);
> > > > > > > > > >   count += drm_helper_probe_add_cmdline_mode(connector);
> > > > > > > > > >   if (count == 0)
> > > > > > > > > > diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
> > > > > > > > > > index 421a30f08463..afe55e2e93d2 100644
> > > > > > > > > > --- a/include/drm/drm_modeset_helper_vtables.h
> > > > > > > > > > +++ b/include/drm/drm_modeset_helper_vtables.h
> > > > > > > > > > @@ -876,13 +876,19 @@ struct drm_connector_helper_funcs {
> > > > > > > > > >    * The usual way to implement this is to cache the EDID retrieved in the
> > > > > > > > > >    * probe callback somewhere in the driver-private connector structure.
> > > > > > > > > >    * In this function drivers then parse the modes in the EDID and add
> > > > > > > > > > -  * them by calling drm_add_edid_modes(). But connectors that driver a
> > > > > > > > > > +  * them by calling drm_add_edid_modes(). But connectors that drive a
> > > > > > > > > >    * fixed panel can also manually add specific modes using
> > > > > > > > > >    * drm_mode_probed_add(). Drivers which manually add modes should also
> > > > > > > > > >    * make sure that the &drm_connector.display_info,
> > > > > > > > > >    * &drm_connector.width_mm and &drm_connector.height_mm fields are
> > > > > > > > > >    * filled in.
> > > > > > > > > >    *
> > > > > > > > > > +  * Note that the caller function will automatically add standard VESA
> > > > > > > > > > +  * DMT modes up to 1024x768 if the .get_modes() helper operation returns
> > > > > > > > > > +  * no mode and if the connector status is connector_status_connected or
> > > > > > > > > > +  * connector_status_unknown. There is no need to call
> > > > > > > > > > +  * drm_add_edid_modes() manually in that case.
> > > > > > >
> > > > > > > Hm calling drm_add_edid_modes if you have no edid is a bit a funny idea
> > > > > > > ... Personally I'd just leave out the last sentence, I think that only
> > > > > > > confuses readers. Or I'm not grasphing what you're trying to tell here.
> > > > > >
> > > > > > IIRC, some drivers used and desktop environments expected unknown
> > > > > > rather than off for LVDS/eDP panels when the lid was shut or if the
> > > > > > mux was switched to another device in the case of hybrid laptops.
> > > > >
> > > > > We seem to have totally ditched that in
> > > > >
> > > > > commit 05c72e77ccda89ff624108b1b59a0fc43843f343
> > > > > Author: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > > > Date:   Tue Jul 17 20:42:14 2018 +0300
> > > > >
> > > > >     drm/i915: Nuke the LVDS lid notifier
> > > > >
> > > > > No screaming yet.
> > > > >
> > > > > But I'm also a bit confused, for a panel there's generally an edid
> > > > > around, or a fixed (list of) modes. That's enough to stop this
> > > > > fallback from running, so should be all fine.
> > > >
> > > > No, you are right; you will have the EDID so this shouldn't be an
> > > > issue.  I was mis-remembering the original issue.  We originally
> > > > always reported connected for LVDS in radeon if the panel was present,
> > > > but then we got flack because some userspace expected unknown in
> > > > certain cases (e.g., lid or muxed displays).  Either way the EDID info
> > > > is still there.
> > >
> > > Yeah I think i915 started that habit, but I guess people realized it's
> > > unreliable enough that they should have their own lid handler in the
> > > desktop enviromnent doing whatever they want to do on lid close.
> > >
> > > Should we perhaps document that somewhere, that panels are always marked
> > > as connected? Not even sure where to put that in the docs ...
> > >
> > > Maybe adding a few of the usual suspects from the compositor side, Simon,
> > > Pekka?
> >
> > Actually adding Simon and Pekka this time around ...
>
> I don't know what anyone else does, but Weston (is not a DE) does not
> look at any lid switch, and assumes that if connector status is not
> DRM_MODE_CONNECTED, then it is disconnected. So, if a driver switched
> to "Unknown" status, it would be taken as disconnected.

Maybe an aside, but the guideline is for autoconfiguration:
- Light up everything that has connector status connected.
- If nothing has that status, try to light up the connectors with
status "unknown".

This is only really relevant on older platforms, mostly for VGA and
somewhat for dvi outputs.

Maybe another thing we should put down somewhere in the uapi docs ...
-Daniel


>
> I never knew what "Unknown" was relevant for. In weston.ini you can
> also force a connector on, so users could drive it regardless.
>
> However, I would also say that Weston is not supposed to react to any
> lid action exactly because it does not watch the lid switch. Personally
> I would expect a built-in screen to stay on even if lid closed.
>
> Panels that are always connected showing up as always connected, sounds
> good to me.
>
>
> Thanks,
> pq



-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

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

* Re: [PATCH 27/27] drm: Add default modes for connectors in unknown state
  2020-06-25 10:44                     ` Daniel Vetter
@ 2020-06-26  8:59                       ` Pekka Paalanen
  2020-06-26  9:25                         ` Daniel Stone
  0 siblings, 1 reply; 69+ messages in thread
From: Pekka Paalanen @ 2020-06-26  8:59 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Alex Deucher, Simon Ser, Laurent Pinchart, Jernej Skrabec,
	Laurent Pinchart, Jonas Karlman, Neil Armstrong, Kieran Bingham,
	Maling list - DRI developers, open list:DRM DRIVERS FOR RENESAS,
	Andrzej Hajda, Thomas Zimmermann, Sam Ravnborg

[-- Attachment #1: Type: text/plain, Size: 2900 bytes --]

On Thu, 25 Jun 2020 12:44:36 +0200
Daniel Vetter <daniel@ffwll.ch> wrote:

> On Thu, Jun 25, 2020 at 12:32 PM Pekka Paalanen <ppaalanen@gmail.com> wrote:
> >
> > On Thu, 25 Jun 2020 09:57:44 +0200
> > Daniel Vetter <daniel@ffwll.ch> wrote:
> >  
> > > On Thu, Jun 25, 2020 at 9:56 AM Daniel Vetter <daniel@ffwll.ch> wrote:  
> > > >
> > > > On Wed, Jun 24, 2020 at 03:40:42PM -0400, Alex Deucher wrote:  

...

> > > > > No, you are right; you will have the EDID so this shouldn't be an
> > > > > issue.  I was mis-remembering the original issue.  We originally
> > > > > always reported connected for LVDS in radeon if the panel was present,
> > > > > but then we got flack because some userspace expected unknown in
> > > > > certain cases (e.g., lid or muxed displays).  Either way the EDID info
> > > > > is still there.  
> > > >
> > > > Yeah I think i915 started that habit, but I guess people realized it's
> > > > unreliable enough that they should have their own lid handler in the
> > > > desktop enviromnent doing whatever they want to do on lid close.
> > > >
> > > > Should we perhaps document that somewhere, that panels are always marked
> > > > as connected? Not even sure where to put that in the docs ...
> > > >
> > > > Maybe adding a few of the usual suspects from the compositor side, Simon,
> > > > Pekka?  
> > >
> > > Actually adding Simon and Pekka this time around ...  
> >
> > I don't know what anyone else does, but Weston (is not a DE) does not
> > look at any lid switch, and assumes that if connector status is not
> > DRM_MODE_CONNECTED, then it is disconnected. So, if a driver switched
> > to "Unknown" status, it would be taken as disconnected.  
> 
> Maybe an aside, but the guideline is for autoconfiguration:
> - Light up everything that has connector status connected.
> - If nothing has that status, try to light up the connectors with
> status "unknown".
> 
> This is only really relevant on older platforms, mostly for VGA and
> somewhat for dvi outputs.
> 
> Maybe another thing we should put down somewhere in the uapi docs ...

As I had no idea what "unknown" means or when it can happen, I assumed
that it must mean "the hardware cannot know". If the hardware cannot
know, then I certainly will not be trying to enable that, unless
explicitly configured to do so. Having a phantom output is worse than
having a real output that does not light up, because it's not obvious at
first with phantom output that anything is wrong. You may just be
wondering where your windows disappear, or where did you mouse cursor
go, or why you see a wallpaper but no login dialog, etc.

I certainly do hope no-one uses this quirk of Weston to get their lid
do what they want... it's possible, OTOH the desktop user base of
Weston according to what I've heard is around one person. It's not me.


Thanks,
pq

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH 27/27] drm: Add default modes for connectors in unknown state
  2020-06-26  8:59                       ` Pekka Paalanen
@ 2020-06-26  9:25                         ` Daniel Stone
  2020-06-26 13:35                           ` Daniel Vetter
  0 siblings, 1 reply; 69+ messages in thread
From: Daniel Stone @ 2020-06-26  9:25 UTC (permalink / raw)
  To: Pekka Paalanen
  Cc: Daniel Vetter, Jernej Skrabec, Laurent Pinchart, Jonas Karlman,
	Neil Armstrong, Kieran Bingham, Maling list - DRI developers,
	open list:DRM DRIVERS FOR RENESAS, Andrzej Hajda,
	Laurent Pinchart, Thomas Zimmermann, Sam Ravnborg

Hi,

On Fri, 26 Jun 2020 at 10:00, Pekka Paalanen <ppaalanen@gmail.com> wrote:
> On Thu, 25 Jun 2020 12:44:36 +0200 Daniel Vetter <daniel@ffwll.ch> wrote:
> > Maybe an aside, but the guideline is for autoconfiguration:
> > - Light up everything that has connector status connected.
> > - If nothing has that status, try to light up the connectors with
> > status "unknown".
> >
> > This is only really relevant on older platforms, mostly for VGA and
> > somewhat for dvi outputs.
> >
> > Maybe another thing we should put down somewhere in the uapi docs ...
>
> As I had no idea what "unknown" means or when it can happen, I assumed
> that it must mean "the hardware cannot know". If the hardware cannot
> know, then I certainly will not be trying to enable that, unless
> explicitly configured to do so. Having a phantom output is worse than
> having a real output that does not light up, because it's not obvious at
> first with phantom output that anything is wrong. You may just be
> wondering where your windows disappear, or where did you mouse cursor
> go, or why you see a wallpaper but no login dialog, etc.

How about a refinement of Dan's suggestion, proceeding down this
logical order and breaking if true:
- ignore all disconnected outputs
- if any outputs are connected, ignore all unknown outputs
- if only one output is unknown, use only that output (with default
mode if need be)
- if any outputs are unknown but have EDID present, use only those outputs
- at this point, we have multiple unknown outputs with no EDID - break
and demand explicit user configuration

Cheers,
Daniel

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

* Re: [PATCH 27/27] drm: Add default modes for connectors in unknown state
  2020-06-26  9:25                         ` Daniel Stone
@ 2020-06-26 13:35                           ` Daniel Vetter
  0 siblings, 0 replies; 69+ messages in thread
From: Daniel Vetter @ 2020-06-26 13:35 UTC (permalink / raw)
  To: Daniel Stone
  Cc: Pekka Paalanen, Daniel Vetter, Jernej Skrabec, Laurent Pinchart,
	Jonas Karlman, Neil Armstrong, Kieran Bingham,
	Maling list - DRI developers, open list:DRM DRIVERS FOR RENESAS,
	Andrzej Hajda, Laurent Pinchart, Thomas Zimmermann, Sam Ravnborg

On Fri, Jun 26, 2020 at 10:25:45AM +0100, Daniel Stone wrote:
> Hi,
> 
> On Fri, 26 Jun 2020 at 10:00, Pekka Paalanen <ppaalanen@gmail.com> wrote:
> > On Thu, 25 Jun 2020 12:44:36 +0200 Daniel Vetter <daniel@ffwll.ch> wrote:
> > > Maybe an aside, but the guideline is for autoconfiguration:
> > > - Light up everything that has connector status connected.
> > > - If nothing has that status, try to light up the connectors with
> > > status "unknown".
> > >
> > > This is only really relevant on older platforms, mostly for VGA and
> > > somewhat for dvi outputs.
> > >
> > > Maybe another thing we should put down somewhere in the uapi docs ...
> >
> > As I had no idea what "unknown" means or when it can happen, I assumed
> > that it must mean "the hardware cannot know". If the hardware cannot
> > know, then I certainly will not be trying to enable that, unless
> > explicitly configured to do so. Having a phantom output is worse than
> > having a real output that does not light up, because it's not obvious at
> > first with phantom output that anything is wrong. You may just be
> > wondering where your windows disappear, or where did you mouse cursor
> > go, or why you see a wallpaper but no login dialog, etc.
> 
> How about a refinement of Dan's suggestion, proceeding down this
> logical order and breaking if true:
> - ignore all disconnected outputs
> - if any outputs are connected, ignore all unknown outputs
> - if only one output is unknown, use only that output (with default
> mode if need be)
> - if any outputs are unknown but have EDID present, use only those outputs
> - at this point, we have multiple unknown outputs with no EDID - break
> and demand explicit user configuration

EDID present generally means the status will be "connected". So not much
of a refined.

I'd say if you have multiple unknown, use a cloned config to avoid the
"windows are disappearing" problem. Which is also what fbcon does, and
iirc also -modesetting by default.

But the most important part is to not light up "unknown" outputs if
there's another output with a solid "connected". That avoids the problems
Pekka points out, phantom outputs are bad. Really no need to refine beyond
that, since imo that's a kernel bug.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

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

* Re: [PATCH 00/27] Converter R-Car DU to the DRM bridge connector helper
  2020-06-25  8:48   ` Liu Ying
@ 2020-06-27 19:55     ` Sam Ravnborg
  2020-06-28  8:28       ` Laurent Pinchart
  0 siblings, 1 reply; 69+ messages in thread
From: Sam Ravnborg @ 2020-06-27 19:55 UTC (permalink / raw)
  To: Liu Ying, Laurent Pinchart
  Cc: Laurent Pinchart, Jernej Skrabec, Jonas Karlman, Neil Armstrong,
	Kieran Bingham, dri-devel, linux-renesas-soc, Andrzej Hajda

Hi Liu,

thanks for the notice.

Laurent, I trust you will take a look and resolve this.

	Sam

On Thu, Jun 25, 2020 at 04:48:01PM +0800, Liu Ying wrote:
> Hi Sam,
> 
> On Tue, 2020-06-23 at 20:55 +0200, Sam Ravnborg wrote:
> > Hi Laurent.
> > 
> > On Tue, May 26, 2020 at 04:14:38AM +0300, Laurent Pinchart wrote:
> > > Hello,
> > > 
> > > This patch series converts the R-Car DU driver to use the DRM
> > > bridge
> > > connector helper drm_bridge_connector_init().
> > > 
> > > The bulk of the series is conversion of the adv7511, simple-bridge,
> > > rcar-lbds and dw-hdmi drivers to make connector creation optional
> > > (through the DRM_BRIDGE_ATTACH_NO_CONNECTOR flag).
> > > 
> > > The series starts with the adv7511 driver, previously posted as
> > > "[PATCH
> > > 0/4] drm: bridge: adv7511: Enable usage with DRM bridge connector
> > > helper" ([1]). Patches 01/27 to 04/27 incorporate all the received
> > > review comments.
> > > 
> > > The next three patches address the simple-bridge driver, previously
> > > posted as "[PATCH 0/2] drm: bridge: simple-bridge: Enable usage
> > > with DRM
> > > bridge connector helper". Patch 05/27 is an additional fix that
> > > stems
> > > from the review, and patches 06/27 and 07/27 incorporate all the
> > > received review comments.
> > > 
> > > Patch 08/27 is a new patch that addresses the rcar-lvds driver.
> > > Instead
> > > of implementing direct support for DRM_BRIDGE_ATTACH_NO_CONNECTOR,
> > > it
> > > simply removes code that shouldn't have been in the driver in the
> > > first
> > > place by switching to the panel bridge helper.
> > > 
> > > Patches 09/27 to 22/27 then address the dw-hdmi driver. That's a
> > > more
> > > sizeable rework, due to the fact that the driver implements a mid-
> > > layer
> > > for platform-specific glue, with the internal drm_connector being
> > > used
> > > throughout the whole code. There's no rocket science there, but
> > > patch
> > > 10/27 should be noted for adding a new argument to the
> > > drm_bridge_funcs.mode_valid() function. Please see individual
> > > patches
> > > for details.
> > > 
> > > Patch 23/27 adds support to the dw-hdmi driver to attach to a
> > > downstream
> > > bridge if one is specified in DT. As the DT port number
> > > corresponding to
> > > the video output differs between platforms that integrate the dw-
> > > hdmi
> > > (some of them even don't have a video output port, which should
> > > probably
> > > be fixed, but that's out of scope for this series), the port number
> > > has
> > > to be specified by the platform glue layer. Patch 24/27 does so for
> > > the
> > > R-Car dw-hdmi driver.
> > > 
> > > Patch 25/27 is a drive-by fix for an error path issue in the rcar-
> > > du
> > > driver. Patch 26/27 finally makes use of the
> > > drm_bridge_connector_init()
> > > helper.
> > > 
> > > Unfortunately, this breaks the VGA output on R-Car Gen3 platforms.
> > > On
> > > those platforms, the VGA DDC lines are not connected, and there is
> > > no
> > > mean for software to detect the VGA output connection status. When
> > > the
> > > simple-bridge driver creates a connector, it automatically adds
> > > default
> > > modes when no DDC is available. This behavious is also present int
> > > the
> > > DRM probe helper drm_helper_probe_single_connector_modes(), but
> > > only
> > > when the connector status is connector_status_connected. As the
> > > driver
> > > (rightfully) reports connector_status_unconnected, no modes are
> > > added.
> > > Patch 27/27 fixes this issue by extending addition of default modes
> > > in
> > > drm_helper_probe_single_connector_modes() when the output status is
> > > unknown. An alternative approach would be to implement this
> > > behaviour in
> > > the bridge connector helper (drm_bridge_connector.c).
> > > 
> > > All the modified drivers have been compile-tested, and the series
> > > has
> > > been tested on a Renesas R-Car Salvator-XS board with the VGA, HDMI
> > > and
> > > LVDS outputs.
> > > 
> > > [1] 
> > > https://lore.kernel.org/dri-devel/20200409004610.12346-1-laurent.pinchart+renesas@ideasonboard.com/
> > > [2] 
> > > https://lore.kernel.org/dri-devel/20200409003636.11792-1-laurent.pinchart+renesas@ideasonboard.com/
> > 
> > As we briefly discussed on IRC the first 21 patches are now applied
> > to
> > drm-misc-next.
> 
> I see patch '[22/27] drm: bridge: dw-hdmi: Make connector creation
> optional' is applied to drm-misc-next.
> That patch would introduce an uninitialized mutex accessing issue as I
> mentioned in the patch[1]. And, the patch intends to fix the issue in
> the first place.
> 
> [1] https://patchwork.freedesktop.org/patch/370560/
> 
> 
> Regards,
> Liu Ying
> 
> > The rcar-du specific patches was left out and the last patch was
> > likewise not applied in this round- mostly because it was the coming
> > after several rcar-du patches and I was not sure if there was some
> > dependencies to consider.
> > 
> > With this set in we have more examples in the tree how to do proper
> > bridges which is good.
> > 
> > While applying the new r-bs was ofc added.
> > 
> > 	Sam
> > 
> > > 
> > > Laurent Pinchart (27):
> > >   drm: bridge: adv7511: Split EDID read to a separate function
> > >   drm: bridge: adv7511: Split connector creation to a separate
> > > function
> > >   drm: bridge: adv7511: Implement bridge connector operations
> > >   drm: bridge: adv7511: Make connector creation optional
> > >   drm: bridge: Return NULL on error from drm_bridge_get_edid()
> > >   drm: bridge: simple-bridge: Delegate operations to next bridge
> > >   drm: bridge: simple-bridge: Make connector creation optional
> > >   drm: rcar-du: lvds: Convert to DRM panel bridge helper
> > >   drm: edid: Constify connector argument to infoframe functions
> > >   drm: bridge: Pass drm_display_info to drm_bridge_funcs
> > > .mode_valid()
> > >   drm: bridge: dw-hdmi: Pass private data pointer to .mode_valid()
> > >   drm: bridge: dw-hdmi: Pass private data pointer to
> > > .configure_phy()
> > >   drm: bridge: dw-hdmi: Remove unused field from dw_hdmi_plat_data
> > >   drm: meson: dw-hdmi: Use dw_hdmi context to replace hack
> > >   drm: bridge: dw-hdmi: Pass drm_display_info to .mode_valid()
> > >   drm: bridge: dw-hdmi: Constify mode argument to dw_hdmi_phy_ops
> > >     .init()
> > >   drm: bridge: dw-hdmi: Constify mode argument to internal
> > > functions
> > >   drm: bridge: dw-hdmi: Pass drm_display_info to
> > > dw_hdmi_support_scdc()
> > >   drm: bridge: dw-hdmi: Split connector creation to a separate
> > > function
> > >   drm: bridge: dw-hdmi: Store current connector in struct dw_hdmi
> > >   drm: bridge: dw-hdmi: Pass drm_connector to internal functions as
> > >     needed
> > >   drm: bridge: dw-hdmi: Make connector creation optional
> > >   drm: bridge: dw-hdmi: Attach to next bridge if available
> > >   drm: rcar-du: dw-hdmi: Set output port number
> > >   drm: rcar-du: Fix error handling in rcar_du_encoder_init()
> > >   drm: rcar-du: Use drm_bridge_connector_init() helper
> > >   drm: Add default modes for connectors in unknown state
> > > 
> > >  drivers/gpu/drm/bridge/adv7511/adv7511_drv.c  | 159 +++++---
> > >  .../drm/bridge/analogix/analogix-anx6345.c    |   1 +
> > >  .../drm/bridge/analogix/analogix-anx78xx.c    |   1 +
> > >  drivers/gpu/drm/bridge/cdns-dsi.c             |   1 +
> > >  drivers/gpu/drm/bridge/chrontel-ch7033.c      |   1 +
> > >  drivers/gpu/drm/bridge/nwl-dsi.c              |   1 +
> > >  drivers/gpu/drm/bridge/sii9234.c              |   1 +
> > >  drivers/gpu/drm/bridge/sil-sii8620.c          |   1 +
> > >  drivers/gpu/drm/bridge/simple-bridge.c        | 113 +++---
> > >  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c     | 357 ++++++++++++
> > > ------
> > >  drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c |   1 +
> > >  drivers/gpu/drm/bridge/tc358767.c             |   1 +
> > >  drivers/gpu/drm/bridge/tc358768.c             |   1 +
> > >  drivers/gpu/drm/bridge/thc63lvd1024.c         |   1 +
> > >  drivers/gpu/drm/bridge/ti-tfp410.c            |  11 +-
> > >  drivers/gpu/drm/drm_atomic_helper.c           |   3 +-
> > >  drivers/gpu/drm/drm_bridge.c                  |  10 +-
> > >  drivers/gpu/drm/drm_edid.c                    |  12 +-
> > >  drivers/gpu/drm/drm_probe_helper.c            |   7 +-
> > >  drivers/gpu/drm/i2c/tda998x_drv.c             |   1 +
> > >  drivers/gpu/drm/imx/dw_hdmi-imx.c             |   6 +-
> > >  drivers/gpu/drm/meson/meson_dw_hdmi.c         |  34 +-
> > >  drivers/gpu/drm/omapdrm/dss/dpi.c             |   1 +
> > >  drivers/gpu/drm/omapdrm/dss/sdi.c             |   1 +
> > >  drivers/gpu/drm/omapdrm/dss/venc.c            |   1 +
> > >  drivers/gpu/drm/rcar-du/rcar_du_encoder.c     |  26 +-
> > >  drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c        |   7 +-
> > >  drivers/gpu/drm/rcar-du/rcar_lvds.c           | 124 +-----
> > >  drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c   |   6 +-
> > >  drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c         |   6 +-
> > >  drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h         |   3 +-
> > >  drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c        |   3 +-
> > >  include/drm/bridge/dw_hdmi.h                  |  28 +-
> > >  include/drm/drm_bridge.h                      |   3 +
> > >  include/drm/drm_edid.h                        |   6 +-
> > >  include/drm/drm_modeset_helper_vtables.h      |   8 +-
> > >  36 files changed, 541 insertions(+), 406 deletions(-)
> > > 
> > > -- 
> > > Regards,
> > > 
> > > Laurent Pinchart
> > > 
> > > _______________________________________________
> > > dri-devel mailing list
> > > dri-devel@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/dri-devel
> > 
> > _______________________________________________
> > dri-devel mailing list
> > dri-devel@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 00/27] Converter R-Car DU to the DRM bridge connector helper
  2020-06-27 19:55     ` Sam Ravnborg
@ 2020-06-28  8:28       ` Laurent Pinchart
  0 siblings, 0 replies; 69+ messages in thread
From: Laurent Pinchart @ 2020-06-28  8:28 UTC (permalink / raw)
  To: Sam Ravnborg
  Cc: Liu Ying, Laurent Pinchart, Jernej Skrabec, Jonas Karlman,
	Neil Armstrong, Kieran Bingham, dri-devel, linux-renesas-soc,
	Andrzej Hajda

Hi Sam,

On Sat, Jun 27, 2020 at 09:55:39PM +0200, Sam Ravnborg wrote:
> Hi Liu,
> 
> thanks for the notice.
> 
> Laurent, I trust you will take a look and resolve this.

I've just reviewed Liu's patches (and CC'ed you on 2/2).

> On Thu, Jun 25, 2020 at 04:48:01PM +0800, Liu Ying wrote:
> > On Tue, 2020-06-23 at 20:55 +0200, Sam Ravnborg wrote:
> >> On Tue, May 26, 2020 at 04:14:38AM +0300, Laurent Pinchart wrote:
> >>> Hello,
> >>> 
> >>> This patch series converts the R-Car DU driver to use the DRM bridge
> >>> connector helper drm_bridge_connector_init().
> >>> 
> >>> The bulk of the series is conversion of the adv7511, simple-bridge,
> >>> rcar-lbds and dw-hdmi drivers to make connector creation optional
> >>> (through the DRM_BRIDGE_ATTACH_NO_CONNECTOR flag).
> >>> 
> >>> The series starts with the adv7511 driver, previously posted as "[PATCH
> >>> 0/4] drm: bridge: adv7511: Enable usage with DRM bridge connector
> >>> helper" ([1]). Patches 01/27 to 04/27 incorporate all the received
> >>> review comments.
> >>> 
> >>> The next three patches address the simple-bridge driver, previously
> >>> posted as "[PATCH 0/2] drm: bridge: simple-bridge: Enable usage with DRM
> >>> bridge connector helper". Patch 05/27 is an additional fix that stems
> >>> from the review, and patches 06/27 and 07/27 incorporate all the
> >>> received review comments.
> >>> 
> >>> Patch 08/27 is a new patch that addresses the rcar-lvds driver. Instead
> >>> of implementing direct support for DRM_BRIDGE_ATTACH_NO_CONNECTOR, it
> >>> simply removes code that shouldn't have been in the driver in the first
> >>> place by switching to the panel bridge helper.
> >>> 
> >>> Patches 09/27 to 22/27 then address the dw-hdmi driver. That's a more
> >>> sizeable rework, due to the fact that the driver implements a mid- layer
> >>> for platform-specific glue, with the internal drm_connector being used
> >>> throughout the whole code. There's no rocket science there, but patch
> >>> 10/27 should be noted for adding a new argument to the
> >>> drm_bridge_funcs.mode_valid() function. Please see individual patches
> >>> for details.
> >>> 
> >>> Patch 23/27 adds support to the dw-hdmi driver to attach to a downstream
> >>> bridge if one is specified in DT. As the DT port number corresponding to
> >>> the video output differs between platforms that integrate the dw- hdmi
> >>> (some of them even don't have a video output port, which should probably
> >>> be fixed, but that's out of scope for this series), the port number has
> >>> to be specified by the platform glue layer. Patch 24/27 does so for the
> >>> R-Car dw-hdmi driver.
> >>> 
> >>> Patch 25/27 is a drive-by fix for an error path issue in the rcar- du
> >>> driver. Patch 26/27 finally makes use of the drm_bridge_connector_init()
> >>> helper.
> >>> 
> >>> Unfortunately, this breaks the VGA output on R-Car Gen3 platforms. On
> >>> those platforms, the VGA DDC lines are not connected, and there is no
> >>> mean for software to detect the VGA output connection status. When the
> >>> simple-bridge driver creates a connector, it automatically adds default
> >>> modes when no DDC is available. This behavious is also present int the
> >>> DRM probe helper drm_helper_probe_single_connector_modes(), but only
> >>> when the connector status is connector_status_connected. As the driver
> >>> (rightfully) reports connector_status_unconnected, no modes are added.
> >>> Patch 27/27 fixes this issue by extending addition of default modes in
> >>> drm_helper_probe_single_connector_modes() when the output status is
> >>> unknown. An alternative approach would be to implement this behaviour in
> >>> the bridge connector helper (drm_bridge_connector.c).
> >>> 
> >>> All the modified drivers have been compile-tested, and the series has
> >>> been tested on a Renesas R-Car Salvator-XS board with the VGA, HDMI and
> >>> LVDS outputs.
> >>> 
> >>> [1] 
> >>> https://lore.kernel.org/dri-devel/20200409004610.12346-1-laurent.pinchart+renesas@ideasonboard.com/
> >>> [2] 
> >>> https://lore.kernel.org/dri-devel/20200409003636.11792-1-laurent.pinchart+renesas@ideasonboard.com/
> >> 
> >> As we briefly discussed on IRC the first 21 patches are now applied to
> >> drm-misc-next.
> > 
> > I see patch '[22/27] drm: bridge: dw-hdmi: Make connector creation
> > optional' is applied to drm-misc-next.
> > That patch would introduce an uninitialized mutex accessing issue as I
> > mentioned in the patch[1]. And, the patch intends to fix the issue in
> > the first place.
> > 
> > [1] https://patchwork.freedesktop.org/patch/370560/
> > 
> >> The rcar-du specific patches was left out and the last patch was
> >> likewise not applied in this round- mostly because it was the coming
> >> after several rcar-du patches and I was not sure if there was some
> >> dependencies to consider.
> >> 
> >> With this set in we have more examples in the tree how to do proper
> >> bridges which is good.
> >> 
> >> While applying the new r-bs was ofc added.
> >> 
> >>> Laurent Pinchart (27):
> >>>   drm: bridge: adv7511: Split EDID read to a separate function
> >>>   drm: bridge: adv7511: Split connector creation to a separate function
> >>>   drm: bridge: adv7511: Implement bridge connector operations
> >>>   drm: bridge: adv7511: Make connector creation optional
> >>>   drm: bridge: Return NULL on error from drm_bridge_get_edid()
> >>>   drm: bridge: simple-bridge: Delegate operations to next bridge
> >>>   drm: bridge: simple-bridge: Make connector creation optional
> >>>   drm: rcar-du: lvds: Convert to DRM panel bridge helper
> >>>   drm: edid: Constify connector argument to infoframe functions
> >>>   drm: bridge: Pass drm_display_info to drm_bridge_funcs .mode_valid()
> >>>   drm: bridge: dw-hdmi: Pass private data pointer to .mode_valid()
> >>>   drm: bridge: dw-hdmi: Pass private data pointer to .configure_phy()
> >>>   drm: bridge: dw-hdmi: Remove unused field from dw_hdmi_plat_data
> >>>   drm: meson: dw-hdmi: Use dw_hdmi context to replace hack
> >>>   drm: bridge: dw-hdmi: Pass drm_display_info to .mode_valid()
> >>>   drm: bridge: dw-hdmi: Constify mode argument to dw_hdmi_phy_ops
> >>>     .init()
> >>>   drm: bridge: dw-hdmi: Constify mode argument to internal functions
> >>>   drm: bridge: dw-hdmi: Pass drm_display_info to dw_hdmi_support_scdc()
> >>>   drm: bridge: dw-hdmi: Split connector creation to a separate function
> >>>   drm: bridge: dw-hdmi: Store current connector in struct dw_hdmi
> >>>   drm: bridge: dw-hdmi: Pass drm_connector to internal functions as
> >>>     needed
> >>>   drm: bridge: dw-hdmi: Make connector creation optional
> >>>   drm: bridge: dw-hdmi: Attach to next bridge if available
> >>>   drm: rcar-du: dw-hdmi: Set output port number
> >>>   drm: rcar-du: Fix error handling in rcar_du_encoder_init()
> >>>   drm: rcar-du: Use drm_bridge_connector_init() helper
> >>>   drm: Add default modes for connectors in unknown state
> >>> 
> >>>  drivers/gpu/drm/bridge/adv7511/adv7511_drv.c  | 159 +++++---
> >>>  .../drm/bridge/analogix/analogix-anx6345.c    |   1 +
> >>>  .../drm/bridge/analogix/analogix-anx78xx.c    |   1 +
> >>>  drivers/gpu/drm/bridge/cdns-dsi.c             |   1 +
> >>>  drivers/gpu/drm/bridge/chrontel-ch7033.c      |   1 +
> >>>  drivers/gpu/drm/bridge/nwl-dsi.c              |   1 +
> >>>  drivers/gpu/drm/bridge/sii9234.c              |   1 +
> >>>  drivers/gpu/drm/bridge/sil-sii8620.c          |   1 +
> >>>  drivers/gpu/drm/bridge/simple-bridge.c        | 113 +++---
> >>>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c     | 357 ++++++++++++------
> >>>  drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c |   1 +
> >>>  drivers/gpu/drm/bridge/tc358767.c             |   1 +
> >>>  drivers/gpu/drm/bridge/tc358768.c             |   1 +
> >>>  drivers/gpu/drm/bridge/thc63lvd1024.c         |   1 +
> >>>  drivers/gpu/drm/bridge/ti-tfp410.c            |  11 +-
> >>>  drivers/gpu/drm/drm_atomic_helper.c           |   3 +-
> >>>  drivers/gpu/drm/drm_bridge.c                  |  10 +-
> >>>  drivers/gpu/drm/drm_edid.c                    |  12 +-
> >>>  drivers/gpu/drm/drm_probe_helper.c            |   7 +-
> >>>  drivers/gpu/drm/i2c/tda998x_drv.c             |   1 +
> >>>  drivers/gpu/drm/imx/dw_hdmi-imx.c             |   6 +-
> >>>  drivers/gpu/drm/meson/meson_dw_hdmi.c         |  34 +-
> >>>  drivers/gpu/drm/omapdrm/dss/dpi.c             |   1 +
> >>>  drivers/gpu/drm/omapdrm/dss/sdi.c             |   1 +
> >>>  drivers/gpu/drm/omapdrm/dss/venc.c            |   1 +
> >>>  drivers/gpu/drm/rcar-du/rcar_du_encoder.c     |  26 +-
> >>>  drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c        |   7 +-
> >>>  drivers/gpu/drm/rcar-du/rcar_lvds.c           | 124 +-----
> >>>  drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c   |   6 +-
> >>>  drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c         |   6 +-
> >>>  drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h         |   3 +-
> >>>  drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c        |   3 +-
> >>>  include/drm/bridge/dw_hdmi.h                  |  28 +-
> >>>  include/drm/drm_bridge.h                      |   3 +
> >>>  include/drm/drm_edid.h                        |   6 +-
> >>>  include/drm/drm_modeset_helper_vtables.h      |   8 +-
> >>>  36 files changed, 541 insertions(+), 406 deletions(-)

-- 
Regards,

Laurent Pinchart

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

end of thread, other threads:[~2020-06-28  8:28 UTC | newest]

Thread overview: 69+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-26  1:14 [PATCH 00/27] Converter R-Car DU to the DRM bridge connector helper Laurent Pinchart
2020-05-26  1:14 ` [PATCH 01/27] drm: bridge: adv7511: Split EDID read to a separate function Laurent Pinchart
2020-05-26  1:14 ` [PATCH 02/27] drm: bridge: adv7511: Split connector creation " Laurent Pinchart
2020-05-26  1:14 ` [PATCH 03/27] drm: bridge: adv7511: Implement bridge connector operations Laurent Pinchart
2020-06-21  8:25   ` Sam Ravnborg
2020-05-26  1:14 ` [PATCH 04/27] drm: bridge: adv7511: Make connector creation optional Laurent Pinchart
2020-05-26  1:14 ` [PATCH 05/27] drm: bridge: Return NULL on error from drm_bridge_get_edid() Laurent Pinchart
2020-06-21  8:26   ` Sam Ravnborg
2020-05-26  1:14 ` [PATCH 06/27] drm: bridge: simple-bridge: Delegate operations to next bridge Laurent Pinchart
2020-05-26  1:14 ` [PATCH 07/27] drm: bridge: simple-bridge: Make connector creation optional Laurent Pinchart
2020-05-26  1:14 ` [PATCH 08/27] drm: rcar-du: lvds: Convert to DRM panel bridge helper Laurent Pinchart
2020-05-26  1:14 ` [PATCH 09/27] drm: edid: Constify connector argument to infoframe functions Laurent Pinchart
2020-06-21  8:27   ` Sam Ravnborg
2020-05-26  1:14 ` [PATCH 10/27] drm: bridge: Pass drm_display_info to drm_bridge_funcs .mode_valid() Laurent Pinchart
2020-05-26 12:51   ` Neil Armstrong
2020-05-26 12:59   ` Boris Brezillon
2020-05-26 14:05   ` Guido Günther
2020-05-26  1:14 ` [PATCH 11/27] drm: bridge: dw-hdmi: Pass private data pointer to .mode_valid() Laurent Pinchart
2020-05-26  9:44   ` Neil Armstrong
2020-05-26  1:14 ` [PATCH 12/27] drm: bridge: dw-hdmi: Pass private data pointer to .configure_phy() Laurent Pinchart
2020-05-26  9:45   ` Neil Armstrong
2020-05-26  1:14 ` [PATCH 13/27] drm: bridge: dw-hdmi: Remove unused field from dw_hdmi_plat_data Laurent Pinchart
2020-05-26  9:45   ` Neil Armstrong
2020-05-26  1:14 ` [PATCH 14/27] drm: meson: dw-hdmi: Use dw_hdmi context to replace hack Laurent Pinchart
2020-05-26 12:32   ` Neil Armstrong
2020-05-26  1:14 ` [PATCH 15/27] drm: bridge: dw-hdmi: Pass drm_display_info to .mode_valid() Laurent Pinchart
2020-05-26  9:46   ` Neil Armstrong
2020-05-26  1:14 ` [PATCH 16/27] drm: bridge: dw-hdmi: Constify mode argument to dw_hdmi_phy_ops .init() Laurent Pinchart
2020-05-26  9:46   ` Neil Armstrong
2020-05-26  1:14 ` [PATCH 17/27] drm: bridge: dw-hdmi: Constify mode argument to internal functions Laurent Pinchart
2020-05-26  9:46   ` Neil Armstrong
2020-05-26  1:14 ` [PATCH 18/27] drm: bridge: dw-hdmi: Pass drm_display_info to dw_hdmi_support_scdc() Laurent Pinchart
2020-05-26  9:48   ` Neil Armstrong
2020-05-26  1:14 ` [PATCH 19/27] drm: bridge: dw-hdmi: Split connector creation to a separate function Laurent Pinchart
2020-05-26  9:49   ` Neil Armstrong
2020-05-26  1:14 ` [PATCH 20/27] drm: bridge: dw-hdmi: Store current connector in struct dw_hdmi Laurent Pinchart
2020-05-26 12:29   ` Neil Armstrong
2020-05-26  1:14 ` [PATCH 21/27] drm: bridge: dw-hdmi: Pass drm_connector to internal functions as needed Laurent Pinchart
2020-05-26 12:29   ` Neil Armstrong
2020-05-26  1:15 ` [PATCH 22/27] drm: bridge: dw-hdmi: Make connector creation optional Laurent Pinchart
2020-05-26 12:35   ` Neil Armstrong
2020-06-07  1:19     ` Laurent Pinchart
2020-05-26  1:15 ` [PATCH 23/27] drm: bridge: dw-hdmi: Attach to next bridge if available Laurent Pinchart
2020-05-26 12:50   ` Neil Armstrong
2020-05-26 14:23     ` Jonas Karlman
2020-06-07  1:24       ` Laurent Pinchart
2020-06-07  1:22     ` Laurent Pinchart
2020-05-26  1:15 ` [PATCH 24/27] drm: rcar-du: dw-hdmi: Set output port number Laurent Pinchart
2020-05-26  1:15 ` [PATCH 25/27] drm: rcar-du: Fix error handling in rcar_du_encoder_init() Laurent Pinchart
2020-05-26  1:15 ` [PATCH 26/27] drm: rcar-du: Use drm_bridge_connector_init() helper Laurent Pinchart
2020-05-26  1:15 ` [PATCH 27/27] drm: Add default modes for connectors in unknown state Laurent Pinchart
2020-06-21  8:40   ` Sam Ravnborg
2020-06-24  1:12     ` Laurent Pinchart
2020-06-24  7:23       ` Daniel Vetter
2020-06-24 15:24         ` Alex Deucher
2020-06-24 19:31           ` Daniel Vetter
2020-06-24 19:40             ` Alex Deucher
2020-06-25  7:56               ` Daniel Vetter
2020-06-25  7:57                 ` Daniel Vetter
2020-06-25 10:31                   ` Pekka Paalanen
2020-06-25 10:44                     ` Daniel Vetter
2020-06-26  8:59                       ` Pekka Paalanen
2020-06-26  9:25                         ` Daniel Stone
2020-06-26 13:35                           ` Daniel Vetter
2020-06-24 22:47         ` Laurent Pinchart
2020-06-23 18:55 ` [PATCH 00/27] Converter R-Car DU to the DRM bridge connector helper Sam Ravnborg
2020-06-25  8:48   ` Liu Ying
2020-06-27 19:55     ` Sam Ravnborg
2020-06-28  8:28       ` Laurent Pinchart

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