diff options
| author | Nicholas Troast <ntroast@codeaurora.org> | 2016-03-28 10:16:31 -0700 |
|---|---|---|
| committer | Kyle Yan <kyan@codeaurora.org> | 2016-04-27 19:04:54 -0700 |
| commit | fd495fefdd3065582c5672253ddf5ba9018aa5e2 (patch) | |
| tree | 29793b5df335b3a1f7af15913e0c7aa0ccd3ceb3 /drivers/spmi | |
| parent | 8feb0d7d2f9f0abde70b417951311e67588ff8ec (diff) | |
spmi: pmic_arb: add support for PMIC bus arbiter v3
PMIC bus arbiter v3 supports 512 SPMI peripherals. Add the v3 operators to
support this new arbiter version.
CRs-Fixed: 1001770
Change-Id: Ic36b8e3c01af2fde1827a53c8c52baed240c238e
Signed-off-by: Nicholas Troast <ntroast@codeaurora.org>
Diffstat (limited to 'drivers/spmi')
| -rw-r--r-- | drivers/spmi/spmi-pmic-arb.c | 44 |
1 files changed, 35 insertions, 9 deletions
diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c index 2d9bc712a677..6e11f9ca5ce2 100644 --- a/drivers/spmi/spmi-pmic-arb.c +++ b/drivers/spmi/spmi-pmic-arb.c @@ -28,6 +28,7 @@ /* PMIC Arbiter configuration registers */ #define PMIC_ARB_VERSION 0x0000 #define PMIC_ARB_VERSION_V2_MIN 0x20010000 +#define PMIC_ARB_VERSION_V3_MIN 0x30000000 #define PMIC_ARB_INT_EN 0x0004 /* PMIC Arbiter channel registers offsets */ @@ -151,7 +152,9 @@ struct spmi_pmic_arb { /** * pmic_arb_ver: version dependent functionality. * - * @mode: access rights to specified pmic peripheral. + * @ver_str: version string. + * @ppid_to_apid: finds the apid for a given ppid. + * @mode: access rights to specified pmic peripheral. * @non_data_cmd: on v1 issues an spmi non-data command. * on v2 no HW support, returns -EOPNOTSUPP. * @offset: on v1 offset of per-ee channel. @@ -167,6 +170,7 @@ struct spmi_pmic_arb { * on v2 offset of SPMI_PIC_IRQ_CLEARn. */ struct pmic_arb_ver_ops { + const char *ver_str; int (*ppid_to_apid)(struct spmi_pmic_arb *pa, u8 sid, u16 addr, u8 *apid); int (*mode)(struct spmi_pmic_arb *dev, u8 sid, u16 addr, @@ -886,6 +890,11 @@ static u32 pmic_arb_owner_acc_status_v2(u8 m, u8 n) return 0x100000 + 0x1000 * m + 0x4 * n; } +static u32 pmic_arb_owner_acc_status_v3(u8 m, u8 n) +{ + return 0x200000 + 0x1000 * m + 0x4 * n; +} + static u32 pmic_arb_acc_enable_v1(u8 n) { return 0x200 + 0x4 * n; @@ -917,6 +926,7 @@ static u32 pmic_arb_irq_clear_v2(u8 n) } static const struct pmic_arb_ver_ops pmic_arb_v1 = { + .ver_str = "v1", .ppid_to_apid = pmic_arb_ppid_to_apid_v1, .mode = pmic_arb_mode_v1, .non_data_cmd = pmic_arb_non_data_cmd_v1, @@ -929,6 +939,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v1 = { }; static const struct pmic_arb_ver_ops pmic_arb_v2 = { + .ver_str = "v2", .ppid_to_apid = pmic_arb_ppid_to_apid_v2, .mode = pmic_arb_mode_v2, .non_data_cmd = pmic_arb_non_data_cmd_v2, @@ -940,6 +951,19 @@ static const struct pmic_arb_ver_ops pmic_arb_v2 = { .irq_clear = pmic_arb_irq_clear_v2, }; +static const struct pmic_arb_ver_ops pmic_arb_v3 = { + .ver_str = "v3", + .ppid_to_apid = pmic_arb_ppid_to_apid_v2, + .mode = pmic_arb_mode_v2, + .non_data_cmd = pmic_arb_non_data_cmd_v2, + .offset = pmic_arb_offset_v2, + .fmt_cmd = pmic_arb_fmt_cmd_v2, + .owner_acc_status = pmic_arb_owner_acc_status_v3, + .acc_enable = pmic_arb_acc_enable_v2, + .irq_status = pmic_arb_irq_status_v2, + .irq_clear = pmic_arb_irq_clear_v2, +}; + static const struct irq_domain_ops pmic_arb_irq_domain_ops = { .map = qpnpint_irq_domain_map, .xlate = qpnpint_irq_domain_dt_translate, @@ -953,7 +977,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev) void __iomem *core; u32 channel, ee, hw_ver; int err; - bool is_v1; ctrl = spmi_controller_alloc(&pdev->dev, sizeof(*pa)); if (!ctrl) @@ -977,21 +1000,21 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev) } hw_ver = readl_relaxed(core + PMIC_ARB_VERSION); - is_v1 = (hw_ver < PMIC_ARB_VERSION_V2_MIN); - dev_info(&ctrl->dev, "PMIC Arb Version-%d (0x%x)\n", (is_v1 ? 1 : 2), - hw_ver); - - if (is_v1) { + if (hw_ver < PMIC_ARB_VERSION_V2_MIN) { pa->ver_ops = &pmic_arb_v1; pa->wr_base = core; pa->rd_base = core; } else { pa->core = core; - pa->ver_ops = &pmic_arb_v2; + + if (hw_ver < PMIC_ARB_VERSION_V3_MIN) + pa->ver_ops = &pmic_arb_v2; + else + pa->ver_ops = &pmic_arb_v3; /* the apid to ppid table starts at PMIC_ARB_REG_CHNL(0) */ - pa->max_periph = (pa->core_size - PMIC_ARB_REG_CHNL(0)) / 4; + pa->max_periph = (pa->core_size - PMIC_ARB_REG_CHNL(0)) / 4; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "obsrvr"); @@ -1019,6 +1042,9 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev) } } + dev_info(&ctrl->dev, "PMIC arbiter version %s (0x%x)\n", + pa->ver_ops->ver_str, hw_ver); + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "intr"); pa->intr = devm_ioremap_resource(&ctrl->dev, res); if (IS_ERR(pa->intr)) { |
