linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFT PATCH 1/2] drm/bridge: tc358762: Set pre_enable_prev_first
@ 2023-01-13 23:56 Douglas Anderson
  2023-01-13 23:56 ` [RFT PATCH 2/2] drm/msm/dsi: Stop unconditionally powering up DSI hosts at modeset Douglas Anderson
  0 siblings, 1 reply; 9+ messages in thread
From: Douglas Anderson @ 2023-01-13 23:56 UTC (permalink / raw)
  To: dri-devel, Rob Clark, Abhinav Kumar, Dmitry Baryshkov
  Cc: Daniel Vetter, Andrzej Hajda, Dave Stevenson, Robert Foss,
	Sean Paul, Jonas Karlman, Laurent Pinchart, Neil Armstrong,
	David Airlie, linux-arm-msm, Stephen Boyd, Jernej Skrabec,
	Vinod Koul, Douglas Anderson, linux-kernel

Set the "pre_enable_prev_first" as provided by commit 4fb912e5e190
("drm/bridge: Introduce pre_enable_prev_first to alter bridge init
order"). This should allow us to revert commit ec7981e6c614
("drm/msm/dsi: don't powerup at modeset time for parade-ps8640") and
commit 7d8e9a90509f ("drm/msm/dsi: move DSI host powerup to modeset
time").

Cc: Dave Stevenson <dave.stevenson@raspberrypi.com>
Cc: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Cc: Abhinav Kumar <quic_abhinavk@quicinc.com>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
---

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

diff --git a/drivers/gpu/drm/bridge/tc358762.c b/drivers/gpu/drm/bridge/tc358762.c
index 0b6a28436885..77f7f7f54757 100644
--- a/drivers/gpu/drm/bridge/tc358762.c
+++ b/drivers/gpu/drm/bridge/tc358762.c
@@ -229,6 +229,7 @@ static int tc358762_probe(struct mipi_dsi_device *dsi)
 	ctx->bridge.funcs = &tc358762_bridge_funcs;
 	ctx->bridge.type = DRM_MODE_CONNECTOR_DPI;
 	ctx->bridge.of_node = dev->of_node;
+	ctx->bridge.pre_enable_prev_first = true;
 
 	drm_bridge_add(&ctx->bridge);
 
-- 
2.39.0.314.g84b9a713c41-goog


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

* [RFT PATCH 2/2] drm/msm/dsi: Stop unconditionally powering up DSI hosts at modeset
  2023-01-13 23:56 [RFT PATCH 1/2] drm/bridge: tc358762: Set pre_enable_prev_first Douglas Anderson
@ 2023-01-13 23:56 ` Douglas Anderson
  2023-01-27  1:13   ` Doug Anderson
                     ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Douglas Anderson @ 2023-01-13 23:56 UTC (permalink / raw)
  To: dri-devel, Rob Clark, Abhinav Kumar, Dmitry Baryshkov
  Cc: Daniel Vetter, Andrzej Hajda, Dave Stevenson, Robert Foss,
	Sean Paul, Jonas Karlman, Laurent Pinchart, Neil Armstrong,
	David Airlie, linux-arm-msm, Stephen Boyd, Jernej Skrabec,
	Vinod Koul, Douglas Anderson, freedreno, linux-kernel,
	ye xingchen

In commit 7d8e9a90509f ("drm/msm/dsi: move DSI host powerup to modeset
time"), we moved powering up DSI hosts to modeset time. This wasn't
because it was an elegant design, but there were no better options.

That commit actually ended up breaking ps8640, and thus was born
commit ec7981e6c614 ("drm/msm/dsi: don't powerup at modeset time for
parade-ps8640") as a temporary hack to un-break ps8640 by moving it to
the old way of doing things. It turns out that ps8640 _really_ doesn't
like its pre_enable() function to be called after
dsi_mgr_bridge_power_on(). Specifically (from experimentation, not
because I have any inside knowledge), it looks like the assertion of
"RST#" in the ps8640 runtime resume handler seems like it's not
allowed to happen after dsi_mgr_bridge_power_on()

Recently, Dave Stevenson's series landed allowing bridges some control
over pre_enable ordering. The meaty commit for our purposes is commit
4fb912e5e190 ("drm/bridge: Introduce pre_enable_prev_first to alter
bridge init order"). As documented by that series, if a bridge doesn't
set "pre_enable_prev_first" then we should use the old ordering.

Now that we have the commit ("drm/bridge: tc358762: Set
pre_enable_prev_first") we can go back to the old ordering, which also
allows us to remove the ps8640 special case.

One last note is that even without reverting commit 7d8e9a90509f
("drm/msm/dsi: move DSI host powerup to modeset time"), if you _just_
revert the ps8640 special case and try it out then it doesn't seem to
fail anymore. I spent time bisecting / debugging this and it turns out
to be mostly luck, so we still want this patch to make sure it's
solid. Specifically the reason it sorta works these days is because
we implemented wait_hpd_asserted() in ps8640 now, plus the magic of
"pm_runtime" autosuspend. The fact that we have wait_hpd_asserted()
implemented means that we actually power the bridge chip up just a wee
bit earlier and then the bridge happens to stay on because of
autosuspend and thus ends up powered before dsi_mgr_bridge_power_on().

Cc: Dave Stevenson <dave.stevenson@raspberrypi.com>
Cc: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Cc: Abhinav Kumar <quic_abhinavk@quicinc.com>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
---

 drivers/gpu/drm/msm/dsi/dsi_manager.c | 68 +++++----------------------
 1 file changed, 11 insertions(+), 57 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c
index 3a1417397283..5e6b8d423b96 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_manager.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c
@@ -34,32 +34,6 @@ static struct msm_dsi_manager msm_dsim_glb;
 #define IS_SYNC_NEEDED()	(msm_dsim_glb.is_sync_needed)
 #define IS_MASTER_DSI_LINK(id)	(msm_dsim_glb.master_dsi_link_id == id)
 
-#ifdef CONFIG_OF
-static bool dsi_mgr_power_on_early(struct drm_bridge *bridge)
-{
-	struct drm_bridge *next_bridge = drm_bridge_get_next_bridge(bridge);
-
-	/*
-	 * If the next bridge in the chain is the Parade ps8640 bridge chip
-	 * then don't power on early since it seems to violate the expectations
-	 * of the firmware that the bridge chip is running.
-	 *
-	 * NOTE: this is expected to be a temporary special case. It's expected
-	 * that we'll eventually have a framework that allows the next level
-	 * bridge to indicate whether it needs us to power on before it or
-	 * after it. When that framework is in place then we'll use it and
-	 * remove this special case.
-	 */
-	return !(next_bridge && next_bridge->of_node &&
-		 of_device_is_compatible(next_bridge->of_node, "parade,ps8640"));
-}
-#else
-static inline bool dsi_mgr_power_on_early(struct drm_bridge *bridge)
-{
-	return true;
-}
-#endif
-
 static inline struct msm_dsi *dsi_mgr_get_dsi(int id)
 {
 	return msm_dsim_glb.dsi[id];
@@ -254,7 +228,7 @@ static void msm_dsi_manager_set_split_display(u8 id)
 	}
 }
 
-static void dsi_mgr_bridge_power_on(struct drm_bridge *bridge)
+static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge)
 {
 	int id = dsi_mgr_bridge_get_id(bridge);
 	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
@@ -300,36 +274,10 @@ static void dsi_mgr_bridge_power_on(struct drm_bridge *bridge)
 	if (is_bonded_dsi && msm_dsi1)
 		msm_dsi_host_enable_irq(msm_dsi1->host);
 
-	return;
-
-host1_on_fail:
-	msm_dsi_host_power_off(host);
-host_on_fail:
-	dsi_mgr_phy_disable(id);
-phy_en_fail:
-	return;
-}
-
-static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge)
-{
-	int id = dsi_mgr_bridge_get_id(bridge);
-	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
-	struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1);
-	struct mipi_dsi_host *host = msm_dsi->host;
-	bool is_bonded_dsi = IS_BONDED_DSI();
-	int ret;
-
-	DBG("id=%d", id);
-	if (!msm_dsi_device_connected(msm_dsi))
-		return;
-
 	/* Do nothing with the host if it is slave-DSI in case of bonded DSI */
 	if (is_bonded_dsi && !IS_MASTER_DSI_LINK(id))
 		return;
 
-	if (!dsi_mgr_power_on_early(bridge))
-		dsi_mgr_bridge_power_on(bridge);
-
 	ret = msm_dsi_host_enable(host);
 	if (ret) {
 		pr_err("%s: enable host %d failed, %d\n", __func__, id, ret);
@@ -349,7 +297,16 @@ static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge)
 host1_en_fail:
 	msm_dsi_host_disable(host);
 host_en_fail:
-
+	msm_dsi_host_disable_irq(host);
+	if (is_bonded_dsi && msm_dsi1) {
+		msm_dsi_host_disable_irq(msm_dsi1->host);
+		msm_dsi_host_power_off(msm_dsi1->host);
+	}
+host1_on_fail:
+	msm_dsi_host_power_off(host);
+host_on_fail:
+	dsi_mgr_phy_disable(id);
+phy_en_fail:
 	return;
 }
 
@@ -438,9 +395,6 @@ static void dsi_mgr_bridge_mode_set(struct drm_bridge *bridge,
 	msm_dsi_host_set_display_mode(host, adjusted_mode);
 	if (is_bonded_dsi && other_dsi)
 		msm_dsi_host_set_display_mode(other_dsi->host, adjusted_mode);
-
-	if (dsi_mgr_power_on_early(bridge))
-		dsi_mgr_bridge_power_on(bridge);
 }
 
 static enum drm_mode_status dsi_mgr_bridge_mode_valid(struct drm_bridge *bridge,
-- 
2.39.0.314.g84b9a713c41-goog


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

* Re: [RFT PATCH 2/2] drm/msm/dsi: Stop unconditionally powering up DSI hosts at modeset
  2023-01-13 23:56 ` [RFT PATCH 2/2] drm/msm/dsi: Stop unconditionally powering up DSI hosts at modeset Douglas Anderson
@ 2023-01-27  1:13   ` Doug Anderson
  2023-01-27  5:48   ` Dmitry Baryshkov
  2023-01-27 18:53   ` [Freedreno] " Abhinav Kumar
  2 siblings, 0 replies; 9+ messages in thread
From: Doug Anderson @ 2023-01-27  1:13 UTC (permalink / raw)
  To: dri-devel, Rob Clark, Abhinav Kumar, Dmitry Baryshkov
  Cc: Daniel Vetter, Andrzej Hajda, Dave Stevenson, Robert Foss,
	Sean Paul, Jonas Karlman, Laurent Pinchart, Neil Armstrong,
	David Airlie, linux-arm-msm, Stephen Boyd, Jernej Skrabec,
	Vinod Koul, freedreno, linux-kernel, ye xingchen

Hi,

On Fri, Jan 13, 2023 at 3:56 PM Douglas Anderson <dianders@chromium.org> wrote:
>
> In commit 7d8e9a90509f ("drm/msm/dsi: move DSI host powerup to modeset
> time"), we moved powering up DSI hosts to modeset time. This wasn't
> because it was an elegant design, but there were no better options.
>
> That commit actually ended up breaking ps8640, and thus was born
> commit ec7981e6c614 ("drm/msm/dsi: don't powerup at modeset time for
> parade-ps8640") as a temporary hack to un-break ps8640 by moving it to
> the old way of doing things. It turns out that ps8640 _really_ doesn't
> like its pre_enable() function to be called after
> dsi_mgr_bridge_power_on(). Specifically (from experimentation, not
> because I have any inside knowledge), it looks like the assertion of
> "RST#" in the ps8640 runtime resume handler seems like it's not
> allowed to happen after dsi_mgr_bridge_power_on()
>
> Recently, Dave Stevenson's series landed allowing bridges some control
> over pre_enable ordering. The meaty commit for our purposes is commit
> 4fb912e5e190 ("drm/bridge: Introduce pre_enable_prev_first to alter
> bridge init order"). As documented by that series, if a bridge doesn't
> set "pre_enable_prev_first" then we should use the old ordering.
>
> Now that we have the commit ("drm/bridge: tc358762: Set
> pre_enable_prev_first") we can go back to the old ordering, which also
> allows us to remove the ps8640 special case.
>
> One last note is that even without reverting commit 7d8e9a90509f
> ("drm/msm/dsi: move DSI host powerup to modeset time"), if you _just_
> revert the ps8640 special case and try it out then it doesn't seem to
> fail anymore. I spent time bisecting / debugging this and it turns out
> to be mostly luck, so we still want this patch to make sure it's
> solid. Specifically the reason it sorta works these days is because
> we implemented wait_hpd_asserted() in ps8640 now, plus the magic of
> "pm_runtime" autosuspend. The fact that we have wait_hpd_asserted()
> implemented means that we actually power the bridge chip up just a wee
> bit earlier and then the bridge happens to stay on because of
> autosuspend and thus ends up powered before dsi_mgr_bridge_power_on().
>
> Cc: Dave Stevenson <dave.stevenson@raspberrypi.com>
> Cc: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> Cc: Abhinav Kumar <quic_abhinavk@quicinc.com>
> Signed-off-by: Douglas Anderson <dianders@chromium.org>
> ---
>
>  drivers/gpu/drm/msm/dsi/dsi_manager.c | 68 +++++----------------------
>  1 file changed, 11 insertions(+), 57 deletions(-)

Does anyone have any comments on this patch series? It would probably
make sense to wait to land until early in a kernel's release cycle, so
perhaps there is no hurry. That being said, it would still be good to
know what the plan is.

Abhinav: I think you're the one that was most concerned with removing
the special case for ps8640. Does that mean you'd be willing to review
this patch?

For whether or not the "tc358762" panel works with the MSM display
driver after this series, are the correct people on this thread?

Thanks!

-Doug

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

* Re: [RFT PATCH 2/2] drm/msm/dsi: Stop unconditionally powering up DSI hosts at modeset
  2023-01-13 23:56 ` [RFT PATCH 2/2] drm/msm/dsi: Stop unconditionally powering up DSI hosts at modeset Douglas Anderson
  2023-01-27  1:13   ` Doug Anderson
@ 2023-01-27  5:48   ` Dmitry Baryshkov
  2023-01-27 16:32     ` Doug Anderson
  2023-01-27 18:53   ` [Freedreno] " Abhinav Kumar
  2 siblings, 1 reply; 9+ messages in thread
From: Dmitry Baryshkov @ 2023-01-27  5:48 UTC (permalink / raw)
  To: Douglas Anderson
  Cc: dri-devel, Rob Clark, Abhinav Kumar, Daniel Vetter,
	Andrzej Hajda, Dave Stevenson, Robert Foss, Sean Paul,
	Jonas Karlman, Laurent Pinchart, Neil Armstrong, David Airlie,
	linux-arm-msm, Stephen Boyd, Jernej Skrabec, Vinod Koul,
	freedreno, linux-kernel, ye xingchen

Hi,

On Sat, 14 Jan 2023 at 01:56, Douglas Anderson <dianders@chromium.org> wrote:
>
> In commit 7d8e9a90509f ("drm/msm/dsi: move DSI host powerup to modeset
> time"), we moved powering up DSI hosts to modeset time. This wasn't
> because it was an elegant design, but there were no better options.
>
> That commit actually ended up breaking ps8640, and thus was born
> commit ec7981e6c614 ("drm/msm/dsi: don't powerup at modeset time for
> parade-ps8640") as a temporary hack to un-break ps8640 by moving it to
> the old way of doing things. It turns out that ps8640 _really_ doesn't
> like its pre_enable() function to be called after
> dsi_mgr_bridge_power_on(). Specifically (from experimentation, not
> because I have any inside knowledge), it looks like the assertion of
> "RST#" in the ps8640 runtime resume handler seems like it's not
> allowed to happen after dsi_mgr_bridge_power_on()
>
> Recently, Dave Stevenson's series landed allowing bridges some control
> over pre_enable ordering. The meaty commit for our purposes is commit
> 4fb912e5e190 ("drm/bridge: Introduce pre_enable_prev_first to alter
> bridge init order"). As documented by that series, if a bridge doesn't
> set "pre_enable_prev_first" then we should use the old ordering.
>
> Now that we have the commit ("drm/bridge: tc358762: Set
> pre_enable_prev_first") we can go back to the old ordering, which also
> allows us to remove the ps8640 special case.
>
> One last note is that even without reverting commit 7d8e9a90509f
> ("drm/msm/dsi: move DSI host powerup to modeset time"), if you _just_
> revert the ps8640 special case and try it out then it doesn't seem to
> fail anymore. I spent time bisecting / debugging this and it turns out
> to be mostly luck, so we still want this patch to make sure it's
> solid. Specifically the reason it sorta works these days is because
> we implemented wait_hpd_asserted() in ps8640 now, plus the magic of
> "pm_runtime" autosuspend. The fact that we have wait_hpd_asserted()
> implemented means that we actually power the bridge chip up just a wee
> bit earlier and then the bridge happens to stay on because of
> autosuspend and thus ends up powered before dsi_mgr_bridge_power_on().

I had a small comment on your patch, but then I was distracted and
forgot to send it. See below.

>
> Cc: Dave Stevenson <dave.stevenson@raspberrypi.com>
> Cc: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> Cc: Abhinav Kumar <quic_abhinavk@quicinc.com>
> Signed-off-by: Douglas Anderson <dianders@chromium.org>
> ---
>
>  drivers/gpu/drm/msm/dsi/dsi_manager.c | 68 +++++----------------------
>  1 file changed, 11 insertions(+), 57 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c
> index 3a1417397283..5e6b8d423b96 100644
> --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c
> +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c
> @@ -34,32 +34,6 @@ static struct msm_dsi_manager msm_dsim_glb;
>  #define IS_SYNC_NEEDED()       (msm_dsim_glb.is_sync_needed)
>  #define IS_MASTER_DSI_LINK(id) (msm_dsim_glb.master_dsi_link_id == id)
>
> -#ifdef CONFIG_OF
> -static bool dsi_mgr_power_on_early(struct drm_bridge *bridge)
> -{
> -       struct drm_bridge *next_bridge = drm_bridge_get_next_bridge(bridge);
> -
> -       /*
> -        * If the next bridge in the chain is the Parade ps8640 bridge chip
> -        * then don't power on early since it seems to violate the expectations
> -        * of the firmware that the bridge chip is running.
> -        *
> -        * NOTE: this is expected to be a temporary special case. It's expected
> -        * that we'll eventually have a framework that allows the next level
> -        * bridge to indicate whether it needs us to power on before it or
> -        * after it. When that framework is in place then we'll use it and
> -        * remove this special case.
> -        */
> -       return !(next_bridge && next_bridge->of_node &&
> -                of_device_is_compatible(next_bridge->of_node, "parade,ps8640"));
> -}
> -#else
> -static inline bool dsi_mgr_power_on_early(struct drm_bridge *bridge)
> -{
> -       return true;
> -}
> -#endif
> -
>  static inline struct msm_dsi *dsi_mgr_get_dsi(int id)
>  {
>         return msm_dsim_glb.dsi[id];
> @@ -254,7 +228,7 @@ static void msm_dsi_manager_set_split_display(u8 id)
>         }
>  }
>
> -static void dsi_mgr_bridge_power_on(struct drm_bridge *bridge)
> +static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge)

Can you please keep the dsi_mgr_bridge_power_on() as is and just
remove the now-legacy dsi_mgr_power_on_early().

>  {
>         int id = dsi_mgr_bridge_get_id(bridge);
>         struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
> @@ -300,36 +274,10 @@ static void dsi_mgr_bridge_power_on(struct drm_bridge *bridge)
>         if (is_bonded_dsi && msm_dsi1)
>                 msm_dsi_host_enable_irq(msm_dsi1->host);
>
> -       return;
> -
> -host1_on_fail:
> -       msm_dsi_host_power_off(host);
> -host_on_fail:
> -       dsi_mgr_phy_disable(id);
> -phy_en_fail:
> -       return;
> -}
> -
> -static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge)
> -{
> -       int id = dsi_mgr_bridge_get_id(bridge);
> -       struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
> -       struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1);
> -       struct mipi_dsi_host *host = msm_dsi->host;
> -       bool is_bonded_dsi = IS_BONDED_DSI();
> -       int ret;
> -
> -       DBG("id=%d", id);
> -       if (!msm_dsi_device_connected(msm_dsi))
> -               return;
> -
>         /* Do nothing with the host if it is slave-DSI in case of bonded DSI */
>         if (is_bonded_dsi && !IS_MASTER_DSI_LINK(id))
>                 return;
>
> -       if (!dsi_mgr_power_on_early(bridge))
> -               dsi_mgr_bridge_power_on(bridge);
> -
>         ret = msm_dsi_host_enable(host);
>         if (ret) {
>                 pr_err("%s: enable host %d failed, %d\n", __func__, id, ret);
> @@ -349,7 +297,16 @@ static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge)
>  host1_en_fail:
>         msm_dsi_host_disable(host);
>  host_en_fail:
> -
> +       msm_dsi_host_disable_irq(host);
> +       if (is_bonded_dsi && msm_dsi1) {
> +               msm_dsi_host_disable_irq(msm_dsi1->host);
> +               msm_dsi_host_power_off(msm_dsi1->host);
> +       }
> +host1_on_fail:
> +       msm_dsi_host_power_off(host);
> +host_on_fail:
> +       dsi_mgr_phy_disable(id);
> +phy_en_fail:
>         return;
>  }
>
> @@ -438,9 +395,6 @@ static void dsi_mgr_bridge_mode_set(struct drm_bridge *bridge,
>         msm_dsi_host_set_display_mode(host, adjusted_mode);
>         if (is_bonded_dsi && other_dsi)
>                 msm_dsi_host_set_display_mode(other_dsi->host, adjusted_mode);
> -
> -       if (dsi_mgr_power_on_early(bridge))
> -               dsi_mgr_bridge_power_on(bridge);
>  }
>
>  static enum drm_mode_status dsi_mgr_bridge_mode_valid(struct drm_bridge *bridge,
> --
> 2.39.0.314.g84b9a713c41-goog
>


-- 
With best wishes
Dmitry

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

* Re: [RFT PATCH 2/2] drm/msm/dsi: Stop unconditionally powering up DSI hosts at modeset
  2023-01-27  5:48   ` Dmitry Baryshkov
@ 2023-01-27 16:32     ` Doug Anderson
  2023-01-27 17:34       ` Dmitry Baryshkov
  0 siblings, 1 reply; 9+ messages in thread
From: Doug Anderson @ 2023-01-27 16:32 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: dri-devel, Rob Clark, Abhinav Kumar, Daniel Vetter,
	Andrzej Hajda, Dave Stevenson, Robert Foss, Sean Paul,
	Jonas Karlman, Laurent Pinchart, Neil Armstrong, David Airlie,
	linux-arm-msm, Stephen Boyd, Jernej Skrabec, Vinod Koul,
	freedreno, linux-kernel, ye xingchen

Hi,

On Thu, Jan 26, 2023 at 9:49 PM Dmitry Baryshkov
<dmitry.baryshkov@linaro.org> wrote:
>
> Hi,
>
> On Sat, 14 Jan 2023 at 01:56, Douglas Anderson <dianders@chromium.org> wrote:
> >
> > In commit 7d8e9a90509f ("drm/msm/dsi: move DSI host powerup to modeset
> > time"), we moved powering up DSI hosts to modeset time. This wasn't
> > because it was an elegant design, but there were no better options.
> >
> > That commit actually ended up breaking ps8640, and thus was born
> > commit ec7981e6c614 ("drm/msm/dsi: don't powerup at modeset time for
> > parade-ps8640") as a temporary hack to un-break ps8640 by moving it to
> > the old way of doing things. It turns out that ps8640 _really_ doesn't
> > like its pre_enable() function to be called after
> > dsi_mgr_bridge_power_on(). Specifically (from experimentation, not
> > because I have any inside knowledge), it looks like the assertion of
> > "RST#" in the ps8640 runtime resume handler seems like it's not
> > allowed to happen after dsi_mgr_bridge_power_on()
> >
> > Recently, Dave Stevenson's series landed allowing bridges some control
> > over pre_enable ordering. The meaty commit for our purposes is commit
> > 4fb912e5e190 ("drm/bridge: Introduce pre_enable_prev_first to alter
> > bridge init order"). As documented by that series, if a bridge doesn't
> > set "pre_enable_prev_first" then we should use the old ordering.
> >
> > Now that we have the commit ("drm/bridge: tc358762: Set
> > pre_enable_prev_first") we can go back to the old ordering, which also
> > allows us to remove the ps8640 special case.
> >
> > One last note is that even without reverting commit 7d8e9a90509f
> > ("drm/msm/dsi: move DSI host powerup to modeset time"), if you _just_
> > revert the ps8640 special case and try it out then it doesn't seem to
> > fail anymore. I spent time bisecting / debugging this and it turns out
> > to be mostly luck, so we still want this patch to make sure it's
> > solid. Specifically the reason it sorta works these days is because
> > we implemented wait_hpd_asserted() in ps8640 now, plus the magic of
> > "pm_runtime" autosuspend. The fact that we have wait_hpd_asserted()
> > implemented means that we actually power the bridge chip up just a wee
> > bit earlier and then the bridge happens to stay on because of
> > autosuspend and thus ends up powered before dsi_mgr_bridge_power_on().
>
> I had a small comment on your patch, but then I was distracted and
> forgot to send it. See below.
>
> >
> > Cc: Dave Stevenson <dave.stevenson@raspberrypi.com>
> > Cc: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> > Cc: Abhinav Kumar <quic_abhinavk@quicinc.com>
> > Signed-off-by: Douglas Anderson <dianders@chromium.org>
> > ---
> >
> >  drivers/gpu/drm/msm/dsi/dsi_manager.c | 68 +++++----------------------
> >  1 file changed, 11 insertions(+), 57 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c
> > index 3a1417397283..5e6b8d423b96 100644
> > --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c
> > +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c
> > @@ -34,32 +34,6 @@ static struct msm_dsi_manager msm_dsim_glb;
> >  #define IS_SYNC_NEEDED()       (msm_dsim_glb.is_sync_needed)
> >  #define IS_MASTER_DSI_LINK(id) (msm_dsim_glb.master_dsi_link_id == id)
> >
> > -#ifdef CONFIG_OF
> > -static bool dsi_mgr_power_on_early(struct drm_bridge *bridge)
> > -{
> > -       struct drm_bridge *next_bridge = drm_bridge_get_next_bridge(bridge);
> > -
> > -       /*
> > -        * If the next bridge in the chain is the Parade ps8640 bridge chip
> > -        * then don't power on early since it seems to violate the expectations
> > -        * of the firmware that the bridge chip is running.
> > -        *
> > -        * NOTE: this is expected to be a temporary special case. It's expected
> > -        * that we'll eventually have a framework that allows the next level
> > -        * bridge to indicate whether it needs us to power on before it or
> > -        * after it. When that framework is in place then we'll use it and
> > -        * remove this special case.
> > -        */
> > -       return !(next_bridge && next_bridge->of_node &&
> > -                of_device_is_compatible(next_bridge->of_node, "parade,ps8640"));
> > -}
> > -#else
> > -static inline bool dsi_mgr_power_on_early(struct drm_bridge *bridge)
> > -{
> > -       return true;
> > -}
> > -#endif
> > -
> >  static inline struct msm_dsi *dsi_mgr_get_dsi(int id)
> >  {
> >         return msm_dsim_glb.dsi[id];
> > @@ -254,7 +228,7 @@ static void msm_dsi_manager_set_split_display(u8 id)
> >         }
> >  }
> >
> > -static void dsi_mgr_bridge_power_on(struct drm_bridge *bridge)
> > +static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge)
>
> Can you please keep the dsi_mgr_bridge_power_on() as is and just
> remove the now-legacy dsi_mgr_power_on_early().

By this, I assume you mean keep the function separate but still remove
the call to it from "modeset" and unconditionally call it from
dsi_mgr_bridge_pre_enable(), right?


> >  {
> >         int id = dsi_mgr_bridge_get_id(bridge);
> >         struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
> > @@ -300,36 +274,10 @@ static void dsi_mgr_bridge_power_on(struct drm_bridge *bridge)
> >         if (is_bonded_dsi && msm_dsi1)
> >                 msm_dsi_host_enable_irq(msm_dsi1->host);
> >
> > -       return;
> > -
> > -host1_on_fail:
> > -       msm_dsi_host_power_off(host);
> > -host_on_fail:
> > -       dsi_mgr_phy_disable(id);
> > -phy_en_fail:
> > -       return;
> > -}
> > -
> > -static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge)
> > -{
> > -       int id = dsi_mgr_bridge_get_id(bridge);
> > -       struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
> > -       struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1);
> > -       struct mipi_dsi_host *host = msm_dsi->host;
> > -       bool is_bonded_dsi = IS_BONDED_DSI();
> > -       int ret;
> > -
> > -       DBG("id=%d", id);
> > -       if (!msm_dsi_device_connected(msm_dsi))
> > -               return;
> > -
> >         /* Do nothing with the host if it is slave-DSI in case of bonded DSI */
> >         if (is_bonded_dsi && !IS_MASTER_DSI_LINK(id))
> >                 return;
> >
> > -       if (!dsi_mgr_power_on_early(bridge))
> > -               dsi_mgr_bridge_power_on(bridge);
> > -
> >         ret = msm_dsi_host_enable(host);
> >         if (ret) {
> >                 pr_err("%s: enable host %d failed, %d\n", __func__, id, ret);
> > @@ -349,7 +297,16 @@ static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge)
> >  host1_en_fail:
> >         msm_dsi_host_disable(host);
> >  host_en_fail:
> > -
> > +       msm_dsi_host_disable_irq(host);
> > +       if (is_bonded_dsi && msm_dsi1) {
> > +               msm_dsi_host_disable_irq(msm_dsi1->host);
> > +               msm_dsi_host_power_off(msm_dsi1->host);
> > +       }
> > +host1_on_fail:
> > +       msm_dsi_host_power_off(host);
> > +host_on_fail:
> > +       dsi_mgr_phy_disable(id);
> > +phy_en_fail:
> >         return;
> >  }
> >
> > @@ -438,9 +395,6 @@ static void dsi_mgr_bridge_mode_set(struct drm_bridge *bridge,
> >         msm_dsi_host_set_display_mode(host, adjusted_mode);
> >         if (is_bonded_dsi && other_dsi)
> >                 msm_dsi_host_set_display_mode(other_dsi->host, adjusted_mode);
> > -
> > -       if (dsi_mgr_power_on_early(bridge))
> > -               dsi_mgr_bridge_power_on(bridge);
> >  }
> >
> >  static enum drm_mode_status dsi_mgr_bridge_mode_valid(struct drm_bridge *bridge,
> > --
> > 2.39.0.314.g84b9a713c41-goog
> >
>
>
> --
> With best wishes
> Dmitry

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

* Re: [RFT PATCH 2/2] drm/msm/dsi: Stop unconditionally powering up DSI hosts at modeset
  2023-01-27 16:32     ` Doug Anderson
@ 2023-01-27 17:34       ` Dmitry Baryshkov
  0 siblings, 0 replies; 9+ messages in thread
From: Dmitry Baryshkov @ 2023-01-27 17:34 UTC (permalink / raw)
  To: Doug Anderson
  Cc: dri-devel, Rob Clark, Abhinav Kumar, Daniel Vetter,
	Andrzej Hajda, Dave Stevenson, Robert Foss, Sean Paul,
	Jonas Karlman, Laurent Pinchart, Neil Armstrong, David Airlie,
	linux-arm-msm, Stephen Boyd, Jernej Skrabec, Vinod Koul,
	freedreno, linux-kernel, ye xingchen

On 27/01/2023 18:32, Doug Anderson wrote:
> Hi,
> 
> On Thu, Jan 26, 2023 at 9:49 PM Dmitry Baryshkov
> <dmitry.baryshkov@linaro.org> wrote:
>>
>> Hi,
>>
>> On Sat, 14 Jan 2023 at 01:56, Douglas Anderson <dianders@chromium.org> wrote:
>>>
>>> In commit 7d8e9a90509f ("drm/msm/dsi: move DSI host powerup to modeset
>>> time"), we moved powering up DSI hosts to modeset time. This wasn't
>>> because it was an elegant design, but there were no better options.
>>>
>>> That commit actually ended up breaking ps8640, and thus was born
>>> commit ec7981e6c614 ("drm/msm/dsi: don't powerup at modeset time for
>>> parade-ps8640") as a temporary hack to un-break ps8640 by moving it to
>>> the old way of doing things. It turns out that ps8640 _really_ doesn't
>>> like its pre_enable() function to be called after
>>> dsi_mgr_bridge_power_on(). Specifically (from experimentation, not
>>> because I have any inside knowledge), it looks like the assertion of
>>> "RST#" in the ps8640 runtime resume handler seems like it's not
>>> allowed to happen after dsi_mgr_bridge_power_on()
>>>
>>> Recently, Dave Stevenson's series landed allowing bridges some control
>>> over pre_enable ordering. The meaty commit for our purposes is commit
>>> 4fb912e5e190 ("drm/bridge: Introduce pre_enable_prev_first to alter
>>> bridge init order"). As documented by that series, if a bridge doesn't
>>> set "pre_enable_prev_first" then we should use the old ordering.
>>>
>>> Now that we have the commit ("drm/bridge: tc358762: Set
>>> pre_enable_prev_first") we can go back to the old ordering, which also
>>> allows us to remove the ps8640 special case.
>>>
>>> One last note is that even without reverting commit 7d8e9a90509f
>>> ("drm/msm/dsi: move DSI host powerup to modeset time"), if you _just_
>>> revert the ps8640 special case and try it out then it doesn't seem to
>>> fail anymore. I spent time bisecting / debugging this and it turns out
>>> to be mostly luck, so we still want this patch to make sure it's
>>> solid. Specifically the reason it sorta works these days is because
>>> we implemented wait_hpd_asserted() in ps8640 now, plus the magic of
>>> "pm_runtime" autosuspend. The fact that we have wait_hpd_asserted()
>>> implemented means that we actually power the bridge chip up just a wee
>>> bit earlier and then the bridge happens to stay on because of
>>> autosuspend and thus ends up powered before dsi_mgr_bridge_power_on().
>>
>> I had a small comment on your patch, but then I was distracted and
>> forgot to send it. See below.
>>
>>>
>>> Cc: Dave Stevenson <dave.stevenson@raspberrypi.com>
>>> Cc: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>> Cc: Abhinav Kumar <quic_abhinavk@quicinc.com>
>>> Signed-off-by: Douglas Anderson <dianders@chromium.org>
>>> ---
>>>
>>>   drivers/gpu/drm/msm/dsi/dsi_manager.c | 68 +++++----------------------
>>>   1 file changed, 11 insertions(+), 57 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c
>>> index 3a1417397283..5e6b8d423b96 100644
>>> --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c
>>> +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c
>>> @@ -34,32 +34,6 @@ static struct msm_dsi_manager msm_dsim_glb;
>>>   #define IS_SYNC_NEEDED()       (msm_dsim_glb.is_sync_needed)
>>>   #define IS_MASTER_DSI_LINK(id) (msm_dsim_glb.master_dsi_link_id == id)
>>>
>>> -#ifdef CONFIG_OF
>>> -static bool dsi_mgr_power_on_early(struct drm_bridge *bridge)
>>> -{
>>> -       struct drm_bridge *next_bridge = drm_bridge_get_next_bridge(bridge);
>>> -
>>> -       /*
>>> -        * If the next bridge in the chain is the Parade ps8640 bridge chip
>>> -        * then don't power on early since it seems to violate the expectations
>>> -        * of the firmware that the bridge chip is running.
>>> -        *
>>> -        * NOTE: this is expected to be a temporary special case. It's expected
>>> -        * that we'll eventually have a framework that allows the next level
>>> -        * bridge to indicate whether it needs us to power on before it or
>>> -        * after it. When that framework is in place then we'll use it and
>>> -        * remove this special case.
>>> -        */
>>> -       return !(next_bridge && next_bridge->of_node &&
>>> -                of_device_is_compatible(next_bridge->of_node, "parade,ps8640"));
>>> -}
>>> -#else
>>> -static inline bool dsi_mgr_power_on_early(struct drm_bridge *bridge)
>>> -{
>>> -       return true;
>>> -}
>>> -#endif
>>> -
>>>   static inline struct msm_dsi *dsi_mgr_get_dsi(int id)
>>>   {
>>>          return msm_dsim_glb.dsi[id];
>>> @@ -254,7 +228,7 @@ static void msm_dsi_manager_set_split_display(u8 id)
>>>          }
>>>   }
>>>
>>> -static void dsi_mgr_bridge_power_on(struct drm_bridge *bridge)
>>> +static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge)
>>
>> Can you please keep the dsi_mgr_bridge_power_on() as is and just
>> remove the now-legacy dsi_mgr_power_on_early().
> 
> By this, I assume you mean keep the function separate but still remove
> the call to it from "modeset" and unconditionally call it from
> dsi_mgr_bridge_pre_enable(), right?

Yes, of course.

> 
> 
>>>   {
>>>          int id = dsi_mgr_bridge_get_id(bridge);
>>>          struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
>>> @@ -300,36 +274,10 @@ static void dsi_mgr_bridge_power_on(struct drm_bridge *bridge)
>>>          if (is_bonded_dsi && msm_dsi1)
>>>                  msm_dsi_host_enable_irq(msm_dsi1->host);
>>>
>>> -       return;
>>> -
>>> -host1_on_fail:
>>> -       msm_dsi_host_power_off(host);
>>> -host_on_fail:
>>> -       dsi_mgr_phy_disable(id);
>>> -phy_en_fail:
>>> -       return;
>>> -}
>>> -
>>> -static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge)
>>> -{
>>> -       int id = dsi_mgr_bridge_get_id(bridge);
>>> -       struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
>>> -       struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1);
>>> -       struct mipi_dsi_host *host = msm_dsi->host;
>>> -       bool is_bonded_dsi = IS_BONDED_DSI();
>>> -       int ret;
>>> -
>>> -       DBG("id=%d", id);
>>> -       if (!msm_dsi_device_connected(msm_dsi))
>>> -               return;
>>> -
>>>          /* Do nothing with the host if it is slave-DSI in case of bonded DSI */
>>>          if (is_bonded_dsi && !IS_MASTER_DSI_LINK(id))
>>>                  return;
>>>
>>> -       if (!dsi_mgr_power_on_early(bridge))
>>> -               dsi_mgr_bridge_power_on(bridge);
>>> -
>>>          ret = msm_dsi_host_enable(host);
>>>          if (ret) {
>>>                  pr_err("%s: enable host %d failed, %d\n", __func__, id, ret);
>>> @@ -349,7 +297,16 @@ static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge)
>>>   host1_en_fail:
>>>          msm_dsi_host_disable(host);
>>>   host_en_fail:
>>> -
>>> +       msm_dsi_host_disable_irq(host);
>>> +       if (is_bonded_dsi && msm_dsi1) {
>>> +               msm_dsi_host_disable_irq(msm_dsi1->host);
>>> +               msm_dsi_host_power_off(msm_dsi1->host);
>>> +       }
>>> +host1_on_fail:
>>> +       msm_dsi_host_power_off(host);
>>> +host_on_fail:
>>> +       dsi_mgr_phy_disable(id);
>>> +phy_en_fail:
>>>          return;
>>>   }
>>>
>>> @@ -438,9 +395,6 @@ static void dsi_mgr_bridge_mode_set(struct drm_bridge *bridge,
>>>          msm_dsi_host_set_display_mode(host, adjusted_mode);
>>>          if (is_bonded_dsi && other_dsi)
>>>                  msm_dsi_host_set_display_mode(other_dsi->host, adjusted_mode);
>>> -
>>> -       if (dsi_mgr_power_on_early(bridge))
>>> -               dsi_mgr_bridge_power_on(bridge);
>>>   }
>>>
>>>   static enum drm_mode_status dsi_mgr_bridge_mode_valid(struct drm_bridge *bridge,
>>> --
>>> 2.39.0.314.g84b9a713c41-goog
>>>
>>
>>
>> --
>> With best wishes
>> Dmitry

-- 
With best wishes
Dmitry


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

* Re: [Freedreno] [RFT PATCH 2/2] drm/msm/dsi: Stop unconditionally powering up DSI hosts at modeset
  2023-01-13 23:56 ` [RFT PATCH 2/2] drm/msm/dsi: Stop unconditionally powering up DSI hosts at modeset Douglas Anderson
  2023-01-27  1:13   ` Doug Anderson
  2023-01-27  5:48   ` Dmitry Baryshkov
@ 2023-01-27 18:53   ` Abhinav Kumar
  2023-01-27 22:33     ` Doug Anderson
  2 siblings, 1 reply; 9+ messages in thread
From: Abhinav Kumar @ 2023-01-27 18:53 UTC (permalink / raw)
  To: Douglas Anderson, dri-devel, Rob Clark, Dmitry Baryshkov
  Cc: ye xingchen, Neil Armstrong, Jernej Skrabec, Daniel Vetter,
	Jonas Karlman, David Airlie, Dave Stevenson, Robert Foss,
	Stephen Boyd, Vinod Koul, Laurent Pinchart, Andrzej Hajda,
	linux-arm-msm, freedreno, Sean Paul, linux-kernel



On 1/13/2023 3:56 PM, Douglas Anderson wrote:
> In commit 7d8e9a90509f ("drm/msm/dsi: move DSI host powerup to modeset
> time"), we moved powering up DSI hosts to modeset time. This wasn't
> because it was an elegant design, but there were no better options.
> 
> That commit actually ended up breaking ps8640, and thus was born
> commit ec7981e6c614 ("drm/msm/dsi: don't powerup at modeset time for
> parade-ps8640") as a temporary hack to un-break ps8640 by moving it to
> the old way of doing things. It turns out that ps8640 _really_ doesn't
> like its pre_enable() function to be called after
> dsi_mgr_bridge_power_on(). Specifically (from experimentation, not
> because I have any inside knowledge), it looks like the assertion of
> "RST#" in the ps8640 runtime resume handler seems like it's not
> allowed to happen after dsi_mgr_bridge_power_on()
> 
> Recently, Dave Stevenson's series landed allowing bridges some control
> over pre_enable ordering. The meaty commit for our purposes is commit
> 4fb912e5e190 ("drm/bridge: Introduce pre_enable_prev_first to alter
> bridge init order"). As documented by that series, if a bridge doesn't
> set "pre_enable_prev_first" then we should use the old ordering.
> 
> Now that we have the commit ("drm/bridge: tc358762: Set
> pre_enable_prev_first") we can go back to the old ordering, which also
> allows us to remove the ps8640 special case.
> 
> One last note is that even without reverting commit 7d8e9a90509f
> ("drm/msm/dsi: move DSI host powerup to modeset time"), if you _just_
> revert the ps8640 special case and try it out then it doesn't seem to
> fail anymore. I spent time bisecting / debugging this and it turns out
> to be mostly luck, so we still want this patch to make sure it's
> solid. Specifically the reason it sorta works these days is because
> we implemented wait_hpd_asserted() in ps8640 now, plus the magic of
> "pm_runtime" autosuspend. The fact that we have wait_hpd_asserted()
> implemented means that we actually power the bridge chip up just a wee
> bit earlier and then the bridge happens to stay on because of
> autosuspend and thus ends up powered before dsi_mgr_bridge_power_on().
> 
> Cc: Dave Stevenson <dave.stevenson@raspberrypi.com>
> Cc: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> Cc: Abhinav Kumar <quic_abhinavk@quicinc.com>
> Signed-off-by: Douglas Anderson <dianders@chromium.org>

Why is the patch title showing 2/2? I am not seeing any 1/2 here.

> ---
> 
>   drivers/gpu/drm/msm/dsi/dsi_manager.c | 68 +++++----------------------
>   1 file changed, 11 insertions(+), 57 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c
> index 3a1417397283..5e6b8d423b96 100644
> --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c
> +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c
> @@ -34,32 +34,6 @@ static struct msm_dsi_manager msm_dsim_glb;
>   #define IS_SYNC_NEEDED()	(msm_dsim_glb.is_sync_needed)
>   #define IS_MASTER_DSI_LINK(id)	(msm_dsim_glb.master_dsi_link_id == id)
>   
> -#ifdef CONFIG_OF
> -static bool dsi_mgr_power_on_early(struct drm_bridge *bridge)
> -{
> -	struct drm_bridge *next_bridge = drm_bridge_get_next_bridge(bridge);
> -
> -	/*
> -	 * If the next bridge in the chain is the Parade ps8640 bridge chip
> -	 * then don't power on early since it seems to violate the expectations
> -	 * of the firmware that the bridge chip is running.
> -	 *
> -	 * NOTE: this is expected to be a temporary special case. It's expected
> -	 * that we'll eventually have a framework that allows the next level
> -	 * bridge to indicate whether it needs us to power on before it or
> -	 * after it. When that framework is in place then we'll use it and
> -	 * remove this special case.
> -	 */
> -	return !(next_bridge && next_bridge->of_node &&
> -		 of_device_is_compatible(next_bridge->of_node, "parade,ps8640"));
> -}
> -#else
> -static inline bool dsi_mgr_power_on_early(struct drm_bridge *bridge)
> -{
> -	return true;
> -}
> -#endif
> -
>   static inline struct msm_dsi *dsi_mgr_get_dsi(int id)
>   {
>   	return msm_dsim_glb.dsi[id];
> @@ -254,7 +228,7 @@ static void msm_dsi_manager_set_split_display(u8 id)
>   	}
>   }
>   
> -static void dsi_mgr_bridge_power_on(struct drm_bridge *bridge)
> +static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge)
>   {
>   	int id = dsi_mgr_bridge_get_id(bridge);
>   	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
> @@ -300,36 +274,10 @@ static void dsi_mgr_bridge_power_on(struct drm_bridge *bridge)
>   	if (is_bonded_dsi && msm_dsi1)
>   		msm_dsi_host_enable_irq(msm_dsi1->host);
>   
> -	return;
> -
> -host1_on_fail:
> -	msm_dsi_host_power_off(host);
> -host_on_fail:
> -	dsi_mgr_phy_disable(id);
> -phy_en_fail:
> -	return;
> -}
> -
> -static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge)
> -{
> -	int id = dsi_mgr_bridge_get_id(bridge);
> -	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
> -	struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1);
> -	struct mipi_dsi_host *host = msm_dsi->host;
> -	bool is_bonded_dsi = IS_BONDED_DSI();
> -	int ret;
> -
> -	DBG("id=%d", id);
> -	if (!msm_dsi_device_connected(msm_dsi))
> -		return;
> -
>   	/* Do nothing with the host if it is slave-DSI in case of bonded DSI */
>   	if (is_bonded_dsi && !IS_MASTER_DSI_LINK(id))
>   		return;
>   
> -	if (!dsi_mgr_power_on_early(bridge))
> -		dsi_mgr_bridge_power_on(bridge);
> -
>   	ret = msm_dsi_host_enable(host);
>   	if (ret) {
>   		pr_err("%s: enable host %d failed, %d\n", __func__, id, ret);
> @@ -349,7 +297,16 @@ static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge)
>   host1_en_fail:
>   	msm_dsi_host_disable(host);
>   host_en_fail:
> -
> +	msm_dsi_host_disable_irq(host);
> +	if (is_bonded_dsi && msm_dsi1) {
> +		msm_dsi_host_disable_irq(msm_dsi1->host);
> +		msm_dsi_host_power_off(msm_dsi1->host);
> +	}

In addition to Dmitry's comment of keeping the bridge_power_on() name,

this part of the change seems independent of the patch. This was missing 
cleanup for DSI1 (esp the disable_irq part).

So can we break it up into two parts.

1) Add missing cleanup for DSI1
2) Just get rid of dsi_mgr_power_on_early() and keep the call 
dsi_mgr_bridge_power_on() in dsi_mgr_bridge_pre_enable() unconditionally.

> +host1_on_fail:
> +	msm_dsi_host_power_off(host);
> +host_on_fail:
> +	dsi_mgr_phy_disable(id);
> +phy_en_fail:
>   	return;
>   }
>   
> @@ -438,9 +395,6 @@ static void dsi_mgr_bridge_mode_set(struct drm_bridge *bridge,
>   	msm_dsi_host_set_display_mode(host, adjusted_mode);
>   	if (is_bonded_dsi && other_dsi)
>   		msm_dsi_host_set_display_mode(other_dsi->host, adjusted_mode);
> -
> -	if (dsi_mgr_power_on_early(bridge))
> -		dsi_mgr_bridge_power_on(bridge);
>   }
>   
>   static enum drm_mode_status dsi_mgr_bridge_mode_valid(struct drm_bridge *bridge,

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

* Re: [Freedreno] [RFT PATCH 2/2] drm/msm/dsi: Stop unconditionally powering up DSI hosts at modeset
  2023-01-27 18:53   ` [Freedreno] " Abhinav Kumar
@ 2023-01-27 22:33     ` Doug Anderson
  2023-01-27 22:51       ` Abhinav Kumar
  0 siblings, 1 reply; 9+ messages in thread
From: Doug Anderson @ 2023-01-27 22:33 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: dri-devel, Rob Clark, Dmitry Baryshkov, ye xingchen,
	Neil Armstrong, Jernej Skrabec, Daniel Vetter, Jonas Karlman,
	David Airlie, Dave Stevenson, Robert Foss, Stephen Boyd,
	Vinod Koul, Laurent Pinchart, Andrzej Hajda, linux-arm-msm,
	freedreno, Sean Paul, linux-kernel

Hi,

On Fri, Jan 27, 2023 at 10:54 AM Abhinav Kumar
<quic_abhinavk@quicinc.com> wrote:
>
> On 1/13/2023 3:56 PM, Douglas Anderson wrote:
> > In commit 7d8e9a90509f ("drm/msm/dsi: move DSI host powerup to modeset
> > time"), we moved powering up DSI hosts to modeset time. This wasn't
> > because it was an elegant design, but there were no better options.
> >
> > That commit actually ended up breaking ps8640, and thus was born
> > commit ec7981e6c614 ("drm/msm/dsi: don't powerup at modeset time for
> > parade-ps8640") as a temporary hack to un-break ps8640 by moving it to
> > the old way of doing things. It turns out that ps8640 _really_ doesn't
> > like its pre_enable() function to be called after
> > dsi_mgr_bridge_power_on(). Specifically (from experimentation, not
> > because I have any inside knowledge), it looks like the assertion of
> > "RST#" in the ps8640 runtime resume handler seems like it's not
> > allowed to happen after dsi_mgr_bridge_power_on()
> >
> > Recently, Dave Stevenson's series landed allowing bridges some control
> > over pre_enable ordering. The meaty commit for our purposes is commit
> > 4fb912e5e190 ("drm/bridge: Introduce pre_enable_prev_first to alter
> > bridge init order"). As documented by that series, if a bridge doesn't
> > set "pre_enable_prev_first" then we should use the old ordering.
> >
> > Now that we have the commit ("drm/bridge: tc358762: Set
> > pre_enable_prev_first") we can go back to the old ordering, which also
> > allows us to remove the ps8640 special case.
> >
> > One last note is that even without reverting commit 7d8e9a90509f
> > ("drm/msm/dsi: move DSI host powerup to modeset time"), if you _just_
> > revert the ps8640 special case and try it out then it doesn't seem to
> > fail anymore. I spent time bisecting / debugging this and it turns out
> > to be mostly luck, so we still want this patch to make sure it's
> > solid. Specifically the reason it sorta works these days is because
> > we implemented wait_hpd_asserted() in ps8640 now, plus the magic of
> > "pm_runtime" autosuspend. The fact that we have wait_hpd_asserted()
> > implemented means that we actually power the bridge chip up just a wee
> > bit earlier and then the bridge happens to stay on because of
> > autosuspend and thus ends up powered before dsi_mgr_bridge_power_on().
> >
> > Cc: Dave Stevenson <dave.stevenson@raspberrypi.com>
> > Cc: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> > Cc: Abhinav Kumar <quic_abhinavk@quicinc.com>
> > Signed-off-by: Douglas Anderson <dianders@chromium.org>
>
> Why is the patch title showing 2/2? I am not seeing any 1/2 here.

Is it a problem with your mail filters? You can see it at:

https://lore.kernel.org/r/20230113155547.RFT.1.I723a3761d57ea60c5dd754c144aed6c3b2ea6f5a@changeid/

You are listed on the "To:" line. ;-)


> > @@ -349,7 +297,16 @@ static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge)
> >   host1_en_fail:
> >       msm_dsi_host_disable(host);
> >   host_en_fail:
> > -
> > +     msm_dsi_host_disable_irq(host);
> > +     if (is_bonded_dsi && msm_dsi1) {
> > +             msm_dsi_host_disable_irq(msm_dsi1->host);
> > +             msm_dsi_host_power_off(msm_dsi1->host);
> > +     }
>
> In addition to Dmitry's comment of keeping the bridge_power_on() name,
>
> this part of the change seems independent of the patch. This was missing
> cleanup for DSI1 (esp the disable_irq part).
>
> So can we break it up into two parts.
>
> 1) Add missing cleanup for DSI1
> 2) Just get rid of dsi_mgr_power_on_early() and keep the call
> dsi_mgr_bridge_power_on() in dsi_mgr_bridge_pre_enable() unconditionally.

I didn't intentionally fix any bug in my patch--I just reverted it all
back to how it was before. ;-)

So looking more closely, it looks like overall the current code (AKA
what's landed today and without ${SUBJECT} patch) doesn't really
handle errors with dsi_mgr_bridge_power_on() very well. The normal
case of calling dsi_mgr_bridge_power_on() from modeset is totally
ignored because modeset returns no error. Then the special workaround
for ps8640 just followed the same pattern and assumed that
dsi_mgr_bridge_power_on() succeeded. It also assumed that if the rest
of dsi_mgr_bridge_pre_enable() failed that it didn't need to undo
dsi_mgr_bridge_power_on() because it wouldn't have undone it in the
modeset case.

While the current code isn't the best, it's not like the pre_enable()
call could have returned errors anyway. It probably wasn't truly the
end of the world to behave the way it did.

With all that, I guess my plan would be to do as Dmitry says and just
always call dsi_mgr_bridge_power_on() from
dsi_mgr_bridge_pre_enable(). In the first patch I'll just do that and
remove the ps8640 workaround. Then I can add a 2nd patch that improves
the error handling by having dsi_mgr_bridge_power_on() return an error
code and then adding a matching dsi_mgr_bridge_power_off() that will
undo it and include the extra cleanup.

-Doug

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

* Re: [Freedreno] [RFT PATCH 2/2] drm/msm/dsi: Stop unconditionally powering up DSI hosts at modeset
  2023-01-27 22:33     ` Doug Anderson
@ 2023-01-27 22:51       ` Abhinav Kumar
  0 siblings, 0 replies; 9+ messages in thread
From: Abhinav Kumar @ 2023-01-27 22:51 UTC (permalink / raw)
  To: Doug Anderson
  Cc: Sean Paul, Neil Armstrong, linux-kernel, Andrzej Hajda,
	Jonas Karlman, ye xingchen, Dave Stevenson, Vinod Koul,
	Jernej Skrabec, Stephen Boyd, Rob Clark, dri-devel,
	Daniel Vetter, linux-arm-msm, Dmitry Baryshkov, freedreno,
	David Airlie, Robert Foss, Laurent Pinchart



On 1/27/2023 2:33 PM, Doug Anderson wrote:
> Hi,
> 
> On Fri, Jan 27, 2023 at 10:54 AM Abhinav Kumar
> <quic_abhinavk@quicinc.com> wrote:
>>
>> On 1/13/2023 3:56 PM, Douglas Anderson wrote:
>>> In commit 7d8e9a90509f ("drm/msm/dsi: move DSI host powerup to modeset
>>> time"), we moved powering up DSI hosts to modeset time. This wasn't
>>> because it was an elegant design, but there were no better options.
>>>
>>> That commit actually ended up breaking ps8640, and thus was born
>>> commit ec7981e6c614 ("drm/msm/dsi: don't powerup at modeset time for
>>> parade-ps8640") as a temporary hack to un-break ps8640 by moving it to
>>> the old way of doing things. It turns out that ps8640 _really_ doesn't
>>> like its pre_enable() function to be called after
>>> dsi_mgr_bridge_power_on(). Specifically (from experimentation, not
>>> because I have any inside knowledge), it looks like the assertion of
>>> "RST#" in the ps8640 runtime resume handler seems like it's not
>>> allowed to happen after dsi_mgr_bridge_power_on()
>>>
>>> Recently, Dave Stevenson's series landed allowing bridges some control
>>> over pre_enable ordering. The meaty commit for our purposes is commit
>>> 4fb912e5e190 ("drm/bridge: Introduce pre_enable_prev_first to alter
>>> bridge init order"). As documented by that series, if a bridge doesn't
>>> set "pre_enable_prev_first" then we should use the old ordering.
>>>
>>> Now that we have the commit ("drm/bridge: tc358762: Set
>>> pre_enable_prev_first") we can go back to the old ordering, which also
>>> allows us to remove the ps8640 special case.
>>>
>>> One last note is that even without reverting commit 7d8e9a90509f
>>> ("drm/msm/dsi: move DSI host powerup to modeset time"), if you _just_
>>> revert the ps8640 special case and try it out then it doesn't seem to
>>> fail anymore. I spent time bisecting / debugging this and it turns out
>>> to be mostly luck, so we still want this patch to make sure it's
>>> solid. Specifically the reason it sorta works these days is because
>>> we implemented wait_hpd_asserted() in ps8640 now, plus the magic of
>>> "pm_runtime" autosuspend. The fact that we have wait_hpd_asserted()
>>> implemented means that we actually power the bridge chip up just a wee
>>> bit earlier and then the bridge happens to stay on because of
>>> autosuspend and thus ends up powered before dsi_mgr_bridge_power_on().
>>>
>>> Cc: Dave Stevenson <dave.stevenson@raspberrypi.com>
>>> Cc: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>> Cc: Abhinav Kumar <quic_abhinavk@quicinc.com>
>>> Signed-off-by: Douglas Anderson <dianders@chromium.org>
>>
>> Why is the patch title showing 2/2? I am not seeing any 1/2 here.
> 
> Is it a problem with your mail filters? You can see it at:
> 
> https://lore.kernel.org/r/20230113155547.RFT.1.I723a3761d57ea60c5dd754c144aed6c3b2ea6f5a@changeid/
> 
> You are listed on the "To:" line. ;-)

Ah, I see what happened. The first patch did not have freedreno CCed but 
the second one did.

So freedreno PW got confused thinking , hey where is the first patch? :)

https://patchwork.freedesktop.org/series/112824/

And so did I :)

Perhaps freedreno should be CCed on both patches because its a series.

> 
> 
>>> @@ -349,7 +297,16 @@ static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge)
>>>    host1_en_fail:
>>>        msm_dsi_host_disable(host);
>>>    host_en_fail:
>>> -
>>> +     msm_dsi_host_disable_irq(host);
>>> +     if (is_bonded_dsi && msm_dsi1) {
>>> +             msm_dsi_host_disable_irq(msm_dsi1->host);
>>> +             msm_dsi_host_power_off(msm_dsi1->host);
>>> +     }
>>
>> In addition to Dmitry's comment of keeping the bridge_power_on() name,
>>
>> this part of the change seems independent of the patch. This was missing
>> cleanup for DSI1 (esp the disable_irq part).
>>
>> So can we break it up into two parts.
>>
>> 1) Add missing cleanup for DSI1
>> 2) Just get rid of dsi_mgr_power_on_early() and keep the call
>> dsi_mgr_bridge_power_on() in dsi_mgr_bridge_pre_enable() unconditionally.
> 
> I didn't intentionally fix any bug in my patch--I just reverted it all
> back to how it was before. ;-)
> 
No sure what I am missing here but I certainly dont see 
msm_dsi_host_disable_irq() being part of any error handling labels which 
made me think you fixed that.

> So looking more closely, it looks like overall the current code (AKA
> what's landed today and without ${SUBJECT} patch) doesn't really
> handle errors with dsi_mgr_bridge_power_on() very well. The normal
> case of calling dsi_mgr_bridge_power_on() from modeset is totally
> ignored because modeset returns no error. Then the special workaround
> for ps8640 just followed the same pattern and assumed that
> dsi_mgr_bridge_power_on() succeeded. It also assumed that if the rest
> of dsi_mgr_bridge_pre_enable() failed that it didn't need to undo
> dsi_mgr_bridge_power_on() because it wouldn't have undone it in the
> modeset case.
> 

Yes thats right.

> While the current code isn't the best, it's not like the pre_enable()
> call could have returned errors anyway. It probably wasn't truly the
> end of the world to behave the way it did.
> 
> With all that, I guess my plan would be to do as Dmitry says and just
> always call dsi_mgr_bridge_power_on() from
> dsi_mgr_bridge_pre_enable(). In the first patch I'll just do that and
> remove the ps8640 workaround. Then I can add a 2nd patch that improves
> the error handling by having dsi_mgr_bridge_power_on() return an error
> code and then adding a matching dsi_mgr_bridge_power_off() that will
> undo it and include the extra cleanup.
> 

Sounds good to me.

> -Doug

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

end of thread, other threads:[~2023-01-27 22:52 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-13 23:56 [RFT PATCH 1/2] drm/bridge: tc358762: Set pre_enable_prev_first Douglas Anderson
2023-01-13 23:56 ` [RFT PATCH 2/2] drm/msm/dsi: Stop unconditionally powering up DSI hosts at modeset Douglas Anderson
2023-01-27  1:13   ` Doug Anderson
2023-01-27  5:48   ` Dmitry Baryshkov
2023-01-27 16:32     ` Doug Anderson
2023-01-27 17:34       ` Dmitry Baryshkov
2023-01-27 18:53   ` [Freedreno] " Abhinav Kumar
2023-01-27 22:33     ` Doug Anderson
2023-01-27 22:51       ` Abhinav Kumar

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