dri-devel.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v5] drm/bridge: ti-sn65dsi86: Add HPD for DisplayPort connector type
@ 2025-06-16  9:32 Jayesh Choudhary
  2025-06-16 16:24 ` Doug Anderson
  2025-06-23 16:50 ` Ernest Van Hoecke
  0 siblings, 2 replies; 5+ messages in thread
From: Jayesh Choudhary @ 2025-06-16  9:32 UTC (permalink / raw)
  To: dianders, andrzej.hajda, neil.armstrong, rfoss, Laurent.pinchart,
	dri-devel, tomi.valkeinen, max.krummenacher, ernestvanhoecke
  Cc: jonas, jernej.skrabec, maarten.lankhorst, mripard, tzimmermann,
	airlied, simona, kieran.bingham+renesas, linux-kernel, max.oss.09,
	devarsht, j-choudhary, geert

By default, HPD was disabled on SN65DSI86 bridge. When the driver was
added (commit "a095f15c00e27"), the HPD_DISABLE bit was set in pre-enable
call which was moved to other function calls subsequently.
Later on, commit "c312b0df3b13" added detect utility for DP mode. But with
HPD_DISABLE bit set, all the HPD events are disabled[0] and the debounced
state always return 1 (always connected state).

Set HPD_DISABLE bit conditionally based on display sink's connector type.
Since the HPD_STATE is reflected correctly only after waiting for debounce
time (~100-400ms) and adding this delay in detect() is not feasible
owing to the performace impact (glitches and frame drop), remove runtime
calls in detect() and add hpd_enable()/disable() bridge hooks with runtime
calls, to detect hpd properly without any delay.

[0]: <https://www.ti.com/lit/gpn/SN65DSI86> (Pg. 32)

Fixes: c312b0df3b13 ("drm/bridge: ti-sn65dsi86: Implement bridge connector operations for DP")
Cc: Max Krummenacher <max.krummenacher@toradex.com>
Signed-off-by: Jayesh Choudhary <j-choudhary@ti.com>
---

Changelog v4->v5:
- Make suspend asynchronous in hpd_disable()
- Update HPD_DISABLE in probe function to address the case for when
  comms are already enabled. Comments taken verbatim from [2]
- Update comments

v4 patch:
<https://lore.kernel.org/all/20250611052947.5776-1-j-choudhary@ti.com/>

Changelog v3->v4:
- Remove "no-hpd" support due to backward compatibility issues
- Change the conditional from "no-hpd" back to connector type
  but still address [1]

v3 patch link:
<https://lore.kernel.org/all/20250529110418.481756-1-j-choudhary@ti.com/>

Changelog v2->v3:
- Change conditional based on no-hpd property to address [1]
- Remove runtime calls in detect() with appropriate comments
- Add hpd_enable() and hpd_disable() in drm_bridge_funcs

v2 patch link:
<https://lore.kernel.org/all/20250508115433.449102-1-j-choudhary@ti.com/>

Changelog v1->v2:
- Drop additional property in bindings and use conditional.
- Instead of register read for HPD state, use dpcd read which returns 0
  for success and error codes for no connection
- Add relevant history for the required change in commit message
- Drop RFC subject-prefix in v2
- Add "Cc:" tag

v1 patch link:
<https://lore.kernel.org/all/20250424105432.255309-1-j-choudhary@ti.com/>

[1]: <https://lore.kernel.org/all/mwh35anw57d6nvre3sguetzq3miu4kd43rokegvul7fk266lys@5h2euthpk7vq/>
[2]: <https://lore.kernel.org/all/CAD=FV=WvH73d78De3PrbiG7b6OaS_BysGtxQ=mJTj4z-h0LYWA@mail.gmail.com/>

 drivers/gpu/drm/bridge/ti-sn65dsi86.c | 70 +++++++++++++++++++++++----
 1 file changed, 61 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
index 60224f476e1d..c6a826e8091e 100644
--- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c
+++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
@@ -348,12 +348,18 @@ static void ti_sn65dsi86_enable_comms(struct ti_sn65dsi86 *pdata,
 	 * 200 ms.  We'll assume that the panel driver will have the hardcoded
 	 * delay in its prepare and always disable HPD.
 	 *
-	 * If HPD somehow makes sense on some future panel we'll have to
-	 * change this to be conditional on someone specifying that HPD should
-	 * be used.
+	 * For DisplayPort bridge type, we need HPD. So we use the bridge type
+	 * to conditionally disable HPD.
+	 * NOTE: The bridge type is set in ti_sn_bridge_probe() but enable_comms()
+	 * can be called before. So for DisplayPort, HPD will be enabled once
+	 * bridge type is set. We are using bridge type instead of "no-hpd"
+	 * property because it is not used properly in devicetree description
+	 * and hence is unreliable.
 	 */
-	regmap_update_bits(pdata->regmap, SN_HPD_DISABLE_REG, HPD_DISABLE,
-			   HPD_DISABLE);
+
+	if (pdata->bridge.type != DRM_MODE_CONNECTOR_DisplayPort)
+		regmap_update_bits(pdata->regmap, SN_HPD_DISABLE_REG, HPD_DISABLE,
+				   HPD_DISABLE);
 
 	pdata->comms_enabled = true;
 
@@ -1195,9 +1201,14 @@ static enum drm_connector_status ti_sn_bridge_detect(struct drm_bridge *bridge)
 	struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge);
 	int val = 0;
 
-	pm_runtime_get_sync(pdata->dev);
+	/*
+	 * Runtime reference is grabbed in ti_sn_bridge_hpd_enable()
+	 * as the chip won't report HPD just after being powered on.
+	 * HPD_DEBOUNCED_STATE reflects correct state only after the
+	 * debounce time (~100-400 ms).
+	 */
+
 	regmap_read(pdata->regmap, SN_HPD_DISABLE_REG, &val);
-	pm_runtime_put_autosuspend(pdata->dev);
 
 	return val & HPD_DEBOUNCED_STATE ? connector_status_connected
 					 : connector_status_disconnected;
@@ -1220,6 +1231,27 @@ static void ti_sn65dsi86_debugfs_init(struct drm_bridge *bridge, struct dentry *
 	debugfs_create_file("status", 0600, debugfs, pdata, &status_fops);
 }
 
+static void ti_sn_bridge_hpd_enable(struct drm_bridge *bridge)
+{
+	struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge);
+
+	/*
+	 * Device needs to be powered on before reading the HPD state
+	 * for reliable hpd detection in ti_sn_bridge_detect() due to
+	 * the high debounce time.
+	 */
+
+	pm_runtime_get_sync(pdata->dev);
+}
+
+static void ti_sn_bridge_hpd_disable(struct drm_bridge *bridge)
+{
+	struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge);
+
+	pm_runtime_mark_last_busy(pdata->dev);
+	pm_runtime_put_autosuspend(pdata->dev);
+}
+
 static const struct drm_bridge_funcs ti_sn_bridge_funcs = {
 	.attach = ti_sn_bridge_attach,
 	.detach = ti_sn_bridge_detach,
@@ -1234,6 +1266,8 @@ static const struct drm_bridge_funcs ti_sn_bridge_funcs = {
 	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
 	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
 	.debugfs_init = ti_sn65dsi86_debugfs_init,
+	.hpd_enable = ti_sn_bridge_hpd_enable,
+	.hpd_disable = ti_sn_bridge_hpd_disable,
 };
 
 static void ti_sn_bridge_parse_lanes(struct ti_sn65dsi86 *pdata,
@@ -1321,8 +1355,26 @@ static int ti_sn_bridge_probe(struct auxiliary_device *adev,
 	pdata->bridge.type = pdata->next_bridge->type == DRM_MODE_CONNECTOR_DisplayPort
 			   ? DRM_MODE_CONNECTOR_DisplayPort : DRM_MODE_CONNECTOR_eDP;
 
-	if (pdata->bridge.type == DRM_MODE_CONNECTOR_DisplayPort)
-		pdata->bridge.ops = DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_DETECT;
+	if (pdata->bridge.type == DRM_MODE_CONNECTOR_DisplayPort) {
+		pdata->bridge.ops = DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_DETECT |
+				    DRM_BRIDGE_OP_HPD;
+		/*
+		 * If comms were already enabled they would have been enabled
+		 * with the wrong value of HPD_DISABLE. Update it now. Comms
+		 * could be enabled if anyone is holding a pm_runtime reference
+		 * (like if a GPIO is in use). Note that in most cases nobody
+		 * is doing AUX channel xfers before the bridge is added so
+		 * HPD doesn't _really_ matter then. The only exception is in
+		 * the eDP case where the panel wants to read the EDID before
+		 * the bridge is added. We always consistently have HPD disabled
+		 * for eDP.
+		 */
+		mutex_lock(&pdata->comms_mutex);
+		if (pdata->comms_enabled)
+			regmap_update_bits(pdata->regmap, SN_HPD_DISABLE_REG,
+					   HPD_DISABLE, 0);
+		mutex_unlock(&pdata->comms_mutex);
+	};
 
 	drm_bridge_add(&pdata->bridge);
 
-- 
2.34.1


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

* Re: [PATCH v5] drm/bridge: ti-sn65dsi86: Add HPD for DisplayPort connector type
  2025-06-16  9:32 [PATCH v5] drm/bridge: ti-sn65dsi86: Add HPD for DisplayPort connector type Jayesh Choudhary
@ 2025-06-16 16:24 ` Doug Anderson
  2025-06-23 15:30   ` Doug Anderson
  2025-06-23 16:50 ` Ernest Van Hoecke
  1 sibling, 1 reply; 5+ messages in thread
From: Doug Anderson @ 2025-06-16 16:24 UTC (permalink / raw)
  To: Jayesh Choudhary
  Cc: andrzej.hajda, neil.armstrong, rfoss, Laurent.pinchart, dri-devel,
	tomi.valkeinen, max.krummenacher, ernestvanhoecke, jonas,
	jernej.skrabec, maarten.lankhorst, mripard, tzimmermann, airlied,
	simona, kieran.bingham+renesas, linux-kernel, max.oss.09,
	devarsht, geert

Hi,

On Mon, Jun 16, 2025 at 2:32 AM Jayesh Choudhary <j-choudhary@ti.com> wrote:
>
> @@ -1220,6 +1231,27 @@ static void ti_sn65dsi86_debugfs_init(struct drm_bridge *bridge, struct dentry *
>         debugfs_create_file("status", 0600, debugfs, pdata, &status_fops);
>  }
>
> +static void ti_sn_bridge_hpd_enable(struct drm_bridge *bridge)
> +{
> +       struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge);
> +
> +       /*
> +        * Device needs to be powered on before reading the HPD state
> +        * for reliable hpd detection in ti_sn_bridge_detect() due to
> +        * the high debounce time.
> +        */
> +
> +       pm_runtime_get_sync(pdata->dev);
> +}
> +
> +static void ti_sn_bridge_hpd_disable(struct drm_bridge *bridge)
> +{
> +       struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge);
> +
> +       pm_runtime_mark_last_busy(pdata->dev);
> +       pm_runtime_put_autosuspend(pdata->dev);

nit: you don't need the pm_runtime_mark_last_busy() here, do you? Just
call pm_runtime_put_autosuspend().

Aside from the nit, this looks reasonable to me now.

Reviewed-by: Douglas Anderson <dianders@chromium.org>

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

* Re: [PATCH v5] drm/bridge: ti-sn65dsi86: Add HPD for DisplayPort connector type
  2025-06-16 16:24 ` Doug Anderson
@ 2025-06-23 15:30   ` Doug Anderson
  2025-06-24  4:52     ` Jayesh Choudhary
  0 siblings, 1 reply; 5+ messages in thread
From: Doug Anderson @ 2025-06-23 15:30 UTC (permalink / raw)
  To: Jayesh Choudhary
  Cc: andrzej.hajda, neil.armstrong, rfoss, Laurent.pinchart, dri-devel,
	tomi.valkeinen, max.krummenacher, ernestvanhoecke, jonas,
	jernej.skrabec, maarten.lankhorst, mripard, tzimmermann, airlied,
	simona, kieran.bingham+renesas, linux-kernel, max.oss.09,
	devarsht, geert

Hi,

On Mon, Jun 16, 2025 at 9:24 AM Doug Anderson <dianders@chromium.org> wrote:
>
> Hi,
>
> On Mon, Jun 16, 2025 at 2:32 AM Jayesh Choudhary <j-choudhary@ti.com> wrote:
> >
> > @@ -1220,6 +1231,27 @@ static void ti_sn65dsi86_debugfs_init(struct drm_bridge *bridge, struct dentry *
> >         debugfs_create_file("status", 0600, debugfs, pdata, &status_fops);
> >  }
> >
> > +static void ti_sn_bridge_hpd_enable(struct drm_bridge *bridge)
> > +{
> > +       struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge);
> > +
> > +       /*
> > +        * Device needs to be powered on before reading the HPD state
> > +        * for reliable hpd detection in ti_sn_bridge_detect() due to
> > +        * the high debounce time.
> > +        */
> > +
> > +       pm_runtime_get_sync(pdata->dev);
> > +}
> > +
> > +static void ti_sn_bridge_hpd_disable(struct drm_bridge *bridge)
> > +{
> > +       struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge);
> > +
> > +       pm_runtime_mark_last_busy(pdata->dev);
> > +       pm_runtime_put_autosuspend(pdata->dev);
>
> nit: you don't need the pm_runtime_mark_last_busy() here, do you? Just
> call pm_runtime_put_autosuspend().
>
> Aside from the nit, this looks reasonable to me now.
>
> Reviewed-by: Douglas Anderson <dianders@chromium.org>

What's the plan here? I can just remove the
`pm_runtime_mark_last_busy()` and land it if people are on board with
that (and if it works fine for Jayesh). If Jayesh wants to post a v6
to make it more legit, I can land that. I probably won't land anything
myself past Wednesday (California time) since I'm about to go offline
for 2 weeks and wouldn't want to land and bolt.

-Doug

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

* Re: [PATCH v5] drm/bridge: ti-sn65dsi86: Add HPD for DisplayPort connector type
  2025-06-16  9:32 [PATCH v5] drm/bridge: ti-sn65dsi86: Add HPD for DisplayPort connector type Jayesh Choudhary
  2025-06-16 16:24 ` Doug Anderson
@ 2025-06-23 16:50 ` Ernest Van Hoecke
  1 sibling, 0 replies; 5+ messages in thread
From: Ernest Van Hoecke @ 2025-06-23 16:50 UTC (permalink / raw)
  To: Jayesh Choudhary
  Cc: dianders, andrzej.hajda, neil.armstrong, rfoss, Laurent.pinchart,
	dri-devel, tomi.valkeinen, max.krummenacher, jonas,
	jernej.skrabec, maarten.lankhorst, mripard, tzimmermann, airlied,
	simona, kieran.bingham+renesas, linux-kernel, max.oss.09,
	devarsht, geert

Hi Jayesh,

Thanks a lot for all your work on this patch. I tested this version on a
board with the broken HPD signal and can confirm that eDP works as
expected anyways.

Tested-by: Ernest Van Hoecke <ernest.vanhoecke@toradex.com>

Kind regards,
Ernest


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

* Re: [PATCH v5] drm/bridge: ti-sn65dsi86: Add HPD for DisplayPort connector type
  2025-06-23 15:30   ` Doug Anderson
@ 2025-06-24  4:52     ` Jayesh Choudhary
  0 siblings, 0 replies; 5+ messages in thread
From: Jayesh Choudhary @ 2025-06-24  4:52 UTC (permalink / raw)
  To: Doug Anderson
  Cc: andrzej.hajda, neil.armstrong, rfoss, Laurent.pinchart, dri-devel,
	tomi.valkeinen, max.krummenacher, ernestvanhoecke, jonas,
	jernej.skrabec, maarten.lankhorst, mripard, tzimmermann, airlied,
	simona, kieran.bingham+renesas, linux-kernel, max.oss.09,
	devarsht, geert

Hello Doug,

On 23/06/25 21:00, Doug Anderson wrote:
> Hi,
> 
> On Mon, Jun 16, 2025 at 9:24 AM Doug Anderson <dianders@chromium.org> wrote:
>>
>> Hi,
>>
>> On Mon, Jun 16, 2025 at 2:32 AM Jayesh Choudhary <j-choudhary@ti.com> wrote:
>>>
>>> @@ -1220,6 +1231,27 @@ static void ti_sn65dsi86_debugfs_init(struct drm_bridge *bridge, struct dentry *
>>>          debugfs_create_file("status", 0600, debugfs, pdata, &status_fops);
>>>   }
>>>
>>> +static void ti_sn_bridge_hpd_enable(struct drm_bridge *bridge)
>>> +{
>>> +       struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge);
>>> +
>>> +       /*
>>> +        * Device needs to be powered on before reading the HPD state
>>> +        * for reliable hpd detection in ti_sn_bridge_detect() due to
>>> +        * the high debounce time.
>>> +        */
>>> +
>>> +       pm_runtime_get_sync(pdata->dev);
>>> +}
>>> +
>>> +static void ti_sn_bridge_hpd_disable(struct drm_bridge *bridge)
>>> +{
>>> +       struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge);
>>> +
>>> +       pm_runtime_mark_last_busy(pdata->dev);
>>> +       pm_runtime_put_autosuspend(pdata->dev);
>>
>> nit: you don't need the pm_runtime_mark_last_busy() here, do you? Just
>> call pm_runtime_put_autosuspend().
>>
>> Aside from the nit, this looks reasonable to me now.
>>
>> Reviewed-by: Douglas Anderson <dianders@chromium.org>
> 
> What's the plan here? I can just remove the
> `pm_runtime_mark_last_busy()` and land it if people are on board with
> that (and if it works fine for Jayesh). If Jayesh wants to post a v6
> to make it more legit, I can land that. I probably won't land anything
> myself past Wednesday (California time) since I'm about to go offline
> for 2 weeks and wouldn't want to land and bolt.
> 

Posted v6 with this dropped and the tags picked up:
https://lore.kernel.org/all/20250624044835.165708-1-j-choudhary@ti.com/

Thanks and Warm Regards,
Jayesh


> -Doug

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

end of thread, other threads:[~2025-06-24  4:53 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-16  9:32 [PATCH v5] drm/bridge: ti-sn65dsi86: Add HPD for DisplayPort connector type Jayesh Choudhary
2025-06-16 16:24 ` Doug Anderson
2025-06-23 15:30   ` Doug Anderson
2025-06-24  4:52     ` Jayesh Choudhary
2025-06-23 16:50 ` Ernest Van Hoecke

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).