summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeil Armstrong <neil.armstrong@linaro.org>2025-03-28 09:53:21 +0100
committerCaleb Connolly <caleb.connolly@linaro.org>2025-04-10 15:43:10 +0200
commit1a02b7aa58ae1558e2fd5c29e85c20bdf1becaae (patch)
treefad48af0c13390728e4822314d0996b43e6eafdd
parent2c1462e38b771c547a1f3ee8bbea5aa9d3719885 (diff)
spmi: msm: use real number of channels for v5 & v7
The SPMI_MAX_CHANNELS_Vx are only the maximum channels supported by the controller, but the real number of channels mapped on this system can be read from a register, so take this info. This allows no to overlap on the second controller present on the V7 SPMI arbiter, otherwise we would also parse the mapping of the second SPMI bus and we would bet the wrong IDs. Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> Tested-by: caleb.connolly@linaro.org # sdm845 Link: https://lore.kernel.org/r/20250328-topic-sm8x50-spmi-fix-v1-1-a7548d3aef0d@linaro.org Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
-rw-r--r--drivers/spmi/spmi-msm.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/drivers/spmi/spmi-msm.c b/drivers/spmi/spmi-msm.c
index 5cc5a9e654c..08be4517df1 100644
--- a/drivers/spmi/spmi-msm.c
+++ b/drivers/spmi/spmi-msm.c
@@ -24,6 +24,9 @@ DECLARE_GLOBAL_DATA_PTR;
#define PMIC_ARB_VERSION_V5_MIN 0x50000000
#define PMIC_ARB_VERSION_V7_MIN 0x70000000
+#define PMIC_ARB_FEATURES 0x0004
+#define PMIC_ARB_FEATURES_PERIPH_MASK GENMASK(10, 0)
+
#define APID_MAP_OFFSET_V1_V2_V3 (0x800)
#define APID_MAP_OFFSET_V5 (0x900)
#define APID_MAP_OFFSET_V7 (0x2000)
@@ -271,13 +274,17 @@ static int msm_spmi_probe(struct udevice *dev)
} else if (hw_ver < PMIC_ARB_VERSION_V7_MIN) {
priv->arb_ver = V5;
priv->arb_chnl = core_addr + APID_MAP_OFFSET_V5;
- priv->max_channels = SPMI_MAX_CHANNELS_V5;
+ priv->max_channels = min_t(u32, readl(core_addr + PMIC_ARB_FEATURES) &
+ PMIC_ARB_FEATURES_PERIPH_MASK,
+ SPMI_MAX_CHANNELS_V5);
priv->spmi_cnfg = dev_read_addr_name(dev, "cnfg");
} else {
/* TOFIX: handle second bus */
priv->arb_ver = V7;
priv->arb_chnl = core_addr + APID_MAP_OFFSET_V7;
- priv->max_channels = SPMI_MAX_CHANNELS_V7;
+ priv->max_channels = min_t(u32, readl(core_addr + PMIC_ARB_FEATURES) &
+ PMIC_ARB_FEATURES_PERIPH_MASK,
+ SPMI_MAX_CHANNELS_V7);
priv->spmi_cnfg = dev_read_addr_name(dev, "cnfg");
}