Skip to content

Commit

Permalink
drm/msm/dsi: don't powerup at modeset time for parade-ps8640
Browse files Browse the repository at this point in the history
Commit 7d8e9a9 ("drm/msm/dsi: move DSI host powerup to modeset
time") caused sc7180 Chromebooks that use the parade-ps8640 bridge
chip to fail to turn the display back on after it turns off.

Unfortunately, it doesn't look easy to fix the parade-ps8640 driver to
handle the new power sequence. The Linux driver has almost nothing in
it and most of the logic for this bridge chip is in black-box firmware
that the bridge chip uses.

Also unfortunately, reverting the patch will break "tc358762".

The long term solution here is probably Dave Stevenson's series [1]
that would give more flexibility. However, that is likely not a quick
fix.

For the short term, we'll look at the compatible of the next bridge in
the chain and go back to the old way for the Parade PS8640 bridge
chip. If it's found that other bridge chips also need this workaround
then we can add them to the list or consider inverting the
condition. However, the hope is that the framework will not take too
much longer to land and we won't have to add anything other than
ps8640 here.

[1] https://lore.kernel.org/r/cover.1646406653.git.dave.stevenson@raspberrypi.com

Fixes: 7d8e9a9 ("drm/msm/dsi: move DSI host powerup to modeset time")
Suggested-by: Rob Clark <robdclark@gmail.com>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
Link: https://lore.kernel.org/r/20220513131504.v5.1.Ia196e35ad985059e77b038a41662faae9e26f411@changeid
Signed-off-by: Rob Clark <robdclark@chromium.org>
  • Loading branch information
dianders authored and robclark committed May 18, 2022
1 parent 24df120 commit ec7981e
Showing 1 changed file with 31 additions and 1 deletion.
32 changes: 31 additions & 1 deletion drivers/gpu/drm/msm/dsi/dsi_manager.c
Expand Up @@ -34,6 +34,32 @@ 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];
Expand Down Expand Up @@ -389,6 +415,9 @@ static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge)
if (is_bonded_dsi && !IS_MASTER_DSI_LINK(id))
return;

if (!dsi_mgr_power_on_early(bridge))
dsi_mgr_bridge_power_on(bridge);

/* Always call panel functions once, because even for dual panels,
* there is only one drm_panel instance.
*/
Expand Down Expand Up @@ -570,7 +599,8 @@ static void dsi_mgr_bridge_mode_set(struct drm_bridge *bridge,
if (is_bonded_dsi && other_dsi)
msm_dsi_host_set_display_mode(other_dsi->host, adjusted_mode);

dsi_mgr_bridge_power_on(bridge);
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,
Expand Down

0 comments on commit ec7981e

Please sign in to comment.