From ee1d8aa5ecf77991d3bbcfea2d5b37d88bb19473 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Fri, 5 Apr 2024 10:21:56 +0200 Subject: [PATCH] spmi: msm: support controller version 7 Add the defines and support for SPMI arbiters version 7, which can handle up to 1024 peripherals, and can also drive a secondary bus which is not implemented yet. Signed-off-by: Neil Armstrong Acked-by: Caleb Connolly Signed-off-by: Caleb Connolly --- drivers/spmi/spmi-msm.c | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/drivers/spmi/spmi-msm.c b/drivers/spmi/spmi-msm.c index 46e2e09dc2..244de69b35 100644 --- a/drivers/spmi/spmi-msm.c +++ b/drivers/spmi/spmi-msm.c @@ -23,13 +23,17 @@ DECLARE_GLOBAL_DATA_PTR; #define PMIC_ARB_VERSION_V2_MIN 0x20010000 #define PMIC_ARB_VERSION_V3_MIN 0x30000000 #define PMIC_ARB_VERSION_V5_MIN 0x50000000 +#define PMIC_ARB_VERSION_V7_MIN 0x70000000 #define APID_MAP_OFFSET_V1_V2_V3 (0x800) #define APID_MAP_OFFSET_V5 (0x900) +#define APID_MAP_OFFSET_V7 (0x2000) #define ARB_CHANNEL_OFFSET(n) (0x4 * (n)) #define SPMI_CH_OFFSET(chnl) ((chnl) * 0x8000) #define SPMI_V5_OBS_CH_OFFSET(chnl) ((chnl) * 0x80) +#define SPMI_V7_OBS_CH_OFFSET(chnl) ((chnl) * 0x20) #define SPMI_V5_RW_CH_OFFSET(chnl) ((chnl) * 0x10000) +#define SPMI_V7_RW_CH_OFFSET(chnl) ((chnl) * 0x1000) #define SPMI_OWNERSHIP_PERIPH2OWNER(x) ((x) & 0x7) @@ -52,6 +56,7 @@ DECLARE_GLOBAL_DATA_PTR; #define SPMI_MAX_CHANNELS 128 #define SPMI_MAX_CHANNELS_V5 512 +#define SPMI_MAX_CHANNELS_V7 1024 #define SPMI_MAX_SLAVES 16 #define SPMI_MAX_PERIPH 256 @@ -62,7 +67,8 @@ enum arb_ver { V1 = 1, V2, V3, - V5 = 5 + V5 = 5, + V7 = 7 }; /* @@ -133,6 +139,12 @@ static int msm_spmi_write(struct udevice *dev, int usid, int pid, int off, case V5: ch_offset = SPMI_V5_RW_CH_OFFSET(channel); + reg = pmic_arb_fmt_cmd_v2(SPMI_CMD_EXT_REG_WRITE_LONG, off); + break; + + case V7: + ch_offset = SPMI_V7_RW_CH_OFFSET(channel); + reg = pmic_arb_fmt_cmd_v2(SPMI_CMD_EXT_REG_WRITE_LONG, off); break; } @@ -196,6 +208,13 @@ static int msm_spmi_read(struct udevice *dev, int usid, int pid, int off) case V5: ch_offset = SPMI_V5_OBS_CH_OFFSET(channel); + /* Prepare read command */ + reg = pmic_arb_fmt_cmd_v2(SPMI_CMD_EXT_REG_READ_LONG, off); + break; + + case V7: + ch_offset = SPMI_V7_OBS_CH_OFFSET(channel); + /* Prepare read command */ reg = pmic_arb_fmt_cmd_v2(SPMI_CMD_EXT_REG_READ_LONG, off); break; @@ -250,10 +269,16 @@ static int msm_spmi_probe(struct udevice *dev) priv->arb_ver = V3; priv->arb_chnl = core_addr + APID_MAP_OFFSET_V1_V2_V3; priv->max_channels = SPMI_MAX_CHANNELS; - } else { + } 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 = SPMI_MAX_CHANNELS; + 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->spmi_cnfg = dev_read_addr_name(dev, "cnfg"); } @@ -276,7 +301,7 @@ static int msm_spmi_probe(struct udevice *dev) priv->channel_map[slave_id][pid] = i; /* Mark channels read-only when from different owner */ - if (priv->arb_ver == V5) { + if (priv->arb_ver == V5 || priv->arb_ver == V7) { uint32_t cnfg = readl(priv->spmi_cnfg + ARB_CHANNEL_OFFSET(i)); uint8_t owner = SPMI_OWNERSHIP_PERIPH2OWNER(cnfg); -- 2.39.5