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 <[email protected]>
---
 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

Reply via email to