[PATCH 4/5] drm/msm/dsi: take bonded DSI master cfg from per-SoC config
From: Qianhui Xu
Date: Sat Oct 31 2026 - 11:07:00 EST
Take the bonded master link id from the per-SoC config instead of
deriving it from probe order: the master is a property of the SoC's
DSI generation, not of which host happens to probe first. Behaviour
is unchanged: on sm8750 the cfg entry resolves to the same master the
hardcoded value named.
Signed-off-by: Qianhui Xu <xiaqinghuan@xxxxxxxxxxxxxxxx>
---
drivers/gpu/drm/msm/dsi/dsi.h | 1 +
drivers/gpu/drm/msm/dsi/dsi_host.c | 11 ++++++
drivers/gpu/drm/msm/dsi/dsi_manager.c | 49 ++++++++++++++++++++-------
3 files changed, 48 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h
index 667d233f7b..811895123b 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.h
+++ b/drivers/gpu/drm/msm/dsi/dsi.h
@@ -62,6 +62,7 @@ void msm_dsi_manager_tpg_enable(void);
struct msm_dsi_host;
struct msm_dsi_host_cfg_ops;
const struct msm_dsi_host_cfg_ops *msm_dsi_host_get_cfg_ops(struct mipi_dsi_host *host);
+const struct msm_dsi_bonded_cfg *msm_dsi_host_get_bonded_cfg(struct mipi_dsi_host *host);
int msm_dsi_host_xfer_prepare(struct mipi_dsi_host *host,
const struct mipi_dsi_msg *msg);
void msm_dsi_host_xfer_restore(struct mipi_dsi_host *host,
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 5df0e775b1..df37e91170 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -2357,6 +2357,17 @@ dsi_bonded_cfg(struct msm_dsi_host *msm_host)
return msm_host->cfg_hnd->cfg->bonded;
}
+/*
+ * The bonded master/slave roles are a property of the SoC's DSI generation,
+ * not of the order in which the two DSI hosts happen to probe. Expose the
+ * per-SoC table so the manager can take the master from there.
+ */
+const struct msm_dsi_bonded_cfg *
+msm_dsi_host_get_bonded_cfg(struct mipi_dsi_host *host)
+{
+ return dsi_bonded_cfg(to_msm_dsi_host(host));
+}
+
static void dsi_cmd_error_prepare(struct msm_dsi_host *msm_host)
{
const struct msm_dsi_bonded_cfg *bonded = dsi_bonded_cfg(msm_host);
diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c
index 917e51a73f..ddf4d2a159 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_manager.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c
@@ -46,7 +46,6 @@ static DEFINE_MUTEX(dsi_bonded_cmd_lock);
#define IS_BONDED_DSI() (msm_dsim_glb.is_bonded_dsi)
#define IS_SYNC_NEEDED() (msm_dsim_glb.is_sync_needed)
-#define IS_MASTER_DSI_LINK(id) (msm_dsim_glb.master_dsi_link_id == id)
static bool dsi_mgr_uses_bonded_cmd(void)
{
@@ -74,6 +73,30 @@ static inline struct msm_dsi *dsi_mgr_get_other_dsi(int id)
return msm_dsim_glb.dsi[(id + 1) % DSI_MAX];
}
+/*
+ * The master link comes from the per-SoC bonded config when the SoC provides
+ * one; falling back to the DT-declared value (which the probe order fills in)
+ * keeps SoCs without a bonded table working exactly as before.
+ */
+static int dsi_mgr_bonded_master_link_id(int id)
+{
+ struct msm_dsi *dsi = dsi_mgr_get_dsi(id);
+ const struct msm_dsi_bonded_cfg *bonded;
+
+ if (dsi && dsi->host) {
+ bonded = msm_dsi_host_get_bonded_cfg(dsi->host);
+ if (bonded)
+ return bonded->master_link_id;
+ }
+
+ return msm_dsim_glb.master_dsi_link_id;
+}
+
+static bool dsi_mgr_is_master_dsi_link(int id)
+{
+ return dsi_mgr_bonded_master_link_id(id) == id;
+}
+
static int dsi_mgr_parse_of(struct device_node *np, int id)
{
struct msm_dsi_manager *msm_dsim = &msm_dsim_glb;
@@ -117,9 +140,9 @@ static int dsi_mgr_setup_components(int id)
if (ret)
return ret;
} else if (other_dsi) {
- struct msm_dsi *master_link_dsi = IS_MASTER_DSI_LINK(id) ?
+ struct msm_dsi *master_link_dsi = dsi_mgr_is_master_dsi_link(id) ?
msm_dsi : other_dsi;
- struct msm_dsi *slave_link_dsi = IS_MASTER_DSI_LINK(id) ?
+ struct msm_dsi *slave_link_dsi = dsi_mgr_is_master_dsi_link(id) ?
other_dsi : msm_dsi;
/*
@@ -327,7 +350,7 @@ static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge,
DBG("id=%d", id);
/* Do nothing with the host if it is slave-DSI in case of bonded DSI */
- if (is_bonded_dsi && !IS_MASTER_DSI_LINK(id))
+ if (is_bonded_dsi && !dsi_mgr_is_master_dsi_link(id))
return;
ret = dsi_mgr_bridge_power_on(bridge);
@@ -375,7 +398,7 @@ static void dsi_mgr_bridge_enable(struct drm_bridge *bridge,
if (!msm_dsim_glb.is_sm8750 ||
!to_dsi_bridge(bridge)->powered ||
msm_dsi_manager_cmd_failed() ||
- (IS_BONDED_DSI() && !IS_MASTER_DSI_LINK(id)))
+ (IS_BONDED_DSI() && !dsi_mgr_is_master_dsi_link(id)))
return;
panel = of_drm_find_panel(msm_dsi->next_bridge->of_node);
@@ -404,7 +427,7 @@ static void dsi_mgr_bridge_disable(struct drm_bridge *bridge,
if (!msm_dsim_glb.is_sm8750 ||
!to_dsi_bridge(bridge)->powered ||
msm_dsi_manager_cmd_failed() ||
- (IS_BONDED_DSI() && !IS_MASTER_DSI_LINK(id)))
+ (IS_BONDED_DSI() && !dsi_mgr_is_master_dsi_link(id)))
return;
/* Make off commands possible before panel unprepare in post-disable. */
@@ -446,7 +469,7 @@ static void dsi_mgr_bridge_post_disable(struct drm_bridge *bridge,
* It is safe to call dsi_mgr_phy_disable() here because a single PHY
* won't be diabled until both PHYs request disable.
*/
- if (is_bonded_dsi && !IS_MASTER_DSI_LINK(id))
+ if (is_bonded_dsi && !dsi_mgr_is_master_dsi_link(id))
goto disable_phy;
if (msm_dsim_glb.is_sm8750)
@@ -498,7 +521,7 @@ static void dsi_mgr_bridge_mode_set(struct drm_bridge *bridge,
DBG("set mode: " DRM_MODE_FMT, DRM_MODE_ARG(mode));
- if (is_bonded_dsi && !IS_MASTER_DSI_LINK(id))
+ if (is_bonded_dsi && !dsi_mgr_is_master_dsi_link(id))
return;
msm_dsi_host_set_display_mode(host, adjusted_mode);
@@ -608,13 +631,13 @@ static int dsi_mgr_bonded_cmd_xfer(const struct mipi_dsi_msg *msg)
{
struct msm_dsi *master_dsi, *slave_dsi;
const struct msm_dsi_host_cfg_ops *ops;
+ int master_id = dsi_mgr_bonded_master_link_id(DSI_0);
- if (msm_dsim_glb.master_dsi_link_id < 0 ||
- msm_dsim_glb.master_dsi_link_id >= DSI_MAX)
+ if (master_id < 0 || master_id >= DSI_MAX)
return -EINVAL;
- master_dsi = dsi_mgr_get_dsi(msm_dsim_glb.master_dsi_link_id);
- slave_dsi = dsi_mgr_get_other_dsi(msm_dsim_glb.master_dsi_link_id);
+ master_dsi = dsi_mgr_get_dsi(master_id);
+ slave_dsi = dsi_mgr_get_other_dsi(master_id);
if (!master_dsi || !slave_dsi || !master_dsi->host || !slave_dsi->host)
return -ENODEV;
@@ -771,7 +794,7 @@ bool msm_dsi_is_bonded_dsi(struct msm_dsi *msm_dsi)
bool msm_dsi_is_master_dsi(struct msm_dsi *msm_dsi)
{
- return IS_MASTER_DSI_LINK(msm_dsi->id);
+ return dsi_mgr_is_master_dsi_link(msm_dsi->id);
}
const char *msm_dsi_get_te_source(struct msm_dsi *msm_dsi)
--
2.53.0