Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

spmi: pmic_arb: add support for hw version 2

Qualcomm PMIC Arbiter version-2 changes from version-1 are:

- Some different register offsets.
- New channel register space, one per PMIC peripheral (ppid).
All tx traffic uses these channels.
- New observer register space. All rx trafic uses this space.
- Different command format for spmi command registers.

Reviewed-by: Sagar Dharia <sdharia@codeaurora.org>
Signed-off-by: Gilad Avidov <gavidov@codeaurora.org>
Tested-by: Ivan T. Ivanov <iivanov@mm-sol.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Gilad Avidov and committed by
Greg Kroah-Hartman
d0c6ae41 0b9641f5

+267 -62
+5 -1
Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.txt
··· 1 1 Qualcomm SPMI Controller (PMIC Arbiter) 2 2 3 - The SPMI PMIC Arbiter is found on the Snapdragon 800 Series. It is an SPMI 3 + The SPMI PMIC Arbiter is found on Snapdragon chipsets. It is an SPMI 4 4 controller with wrapping arbitration logic to allow for multiple on-chip 5 5 devices to control a single SPMI master. 6 6 ··· 19 19 "core" - core registers 20 20 "intr" - interrupt controller registers 21 21 "cnfg" - configuration registers 22 + Registers used only for V2 PMIC Arbiter: 23 + "chnls" - tx-channel per virtual slave registers. 24 + "obsrvr" - rx-channel (called observer) per virtual slave registers. 25 + 22 26 - reg : address + size pairs describing the PMIC arb register sets; order must 23 27 correspond with the order of entries in reg-names 24 28 - #address-cells : must be set to 2
+262 -61
drivers/spmi/spmi-pmic-arb.c
··· 1 - /* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. 1 + /* 2 + * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. 2 3 * 3 4 * This program is free software; you can redistribute it and/or modify 4 5 * it under the terms of the GNU General Public License version 2 and ··· 26 25 27 26 /* PMIC Arbiter configuration registers */ 28 27 #define PMIC_ARB_VERSION 0x0000 28 + #define PMIC_ARB_VERSION_V2_MIN 0x20010000 29 29 #define PMIC_ARB_INT_EN 0x0004 30 30 31 - /* PMIC Arbiter channel registers */ 32 - #define PMIC_ARB_CMD(N) (0x0800 + (0x80 * (N))) 33 - #define PMIC_ARB_CONFIG(N) (0x0804 + (0x80 * (N))) 34 - #define PMIC_ARB_STATUS(N) (0x0808 + (0x80 * (N))) 35 - #define PMIC_ARB_WDATA0(N) (0x0810 + (0x80 * (N))) 36 - #define PMIC_ARB_WDATA1(N) (0x0814 + (0x80 * (N))) 37 - #define PMIC_ARB_RDATA0(N) (0x0818 + (0x80 * (N))) 38 - #define PMIC_ARB_RDATA1(N) (0x081C + (0x80 * (N))) 39 - 40 - /* Interrupt Controller */ 41 - #define SPMI_PIC_OWNER_ACC_STATUS(M, N) (0x0000 + ((32 * (M)) + (4 * (N)))) 42 - #define SPMI_PIC_ACC_ENABLE(N) (0x0200 + (4 * (N))) 43 - #define SPMI_PIC_IRQ_STATUS(N) (0x0600 + (4 * (N))) 44 - #define SPMI_PIC_IRQ_CLEAR(N) (0x0A00 + (4 * (N))) 31 + /* PMIC Arbiter channel registers offsets */ 32 + #define PMIC_ARB_CMD 0x00 33 + #define PMIC_ARB_CONFIG 0x04 34 + #define PMIC_ARB_STATUS 0x08 35 + #define PMIC_ARB_WDATA0 0x10 36 + #define PMIC_ARB_WDATA1 0x14 37 + #define PMIC_ARB_RDATA0 0x18 38 + #define PMIC_ARB_RDATA1 0x1C 39 + #define PMIC_ARB_REG_CHNL(N) (0x800 + 0x4 * (N)) 45 40 46 41 /* Mapping Table */ 47 42 #define SPMI_MAPPING_TABLE_REG(N) (0x0B00 + (4 * (N))) ··· 49 52 50 53 #define SPMI_MAPPING_TABLE_LEN 255 51 54 #define SPMI_MAPPING_TABLE_TREE_DEPTH 16 /* Maximum of 16-bits */ 55 + #define PPID_TO_CHAN_TABLE_SZ BIT(12) /* PPID is 12bit chan is 1byte*/ 52 56 53 57 /* Ownership Table */ 54 58 #define SPMI_OWNERSHIP_TABLE_REG(N) (0x0700 + (4 * (N))) ··· 86 88 87 89 /* Maximum number of support PMIC peripherals */ 88 90 #define PMIC_ARB_MAX_PERIPHS 256 91 + #define PMIC_ARB_MAX_CHNL 128 89 92 #define PMIC_ARB_PERIPH_ID_VALID (1 << 15) 90 93 #define PMIC_ARB_TIMEOUT_US 100 91 94 #define PMIC_ARB_MAX_TRANS_BYTES (8) ··· 97 98 /* interrupt enable bit */ 98 99 #define SPMI_PIC_ACC_ENABLE_BIT BIT(0) 99 100 101 + struct pmic_arb_ver_ops; 102 + 100 103 /** 101 104 * spmi_pmic_arb_dev - SPMI PMIC Arbiter object 102 105 * 103 - * @base: address of the PMIC Arbiter core registers. 106 + * @rd_base: on v1 "core", on v2 "observer" register base off DT. 107 + * @wr_base: on v1 "core", on v2 "chnls" register base off DT. 104 108 * @intr: address of the SPMI interrupt control registers. 105 109 * @cnfg: address of the PMIC Arbiter configuration registers. 106 110 * @lock: lock to synchronize accesses. 107 - * @channel: which channel to use for accesses. 111 + * @channel: execution environment channel to use for accesses. 108 112 * @irq: PMIC ARB interrupt. 109 113 * @ee: the current Execution Environment 110 114 * @min_apid: minimum APID (used for bounding IRQ search) ··· 115 113 * @mapping_table: in-memory copy of PPID -> APID mapping table. 116 114 * @domain: irq domain object for PMIC IRQ domain 117 115 * @spmic: SPMI controller object 118 - * @apid_to_ppid: cached mapping from APID to PPID 116 + * @apid_to_ppid: in-memory copy of APID -> PPID mapping table. 117 + * @ver_ops: version dependent operations. 118 + * @ppid_to_chan in-memory copy of PPID -> channel (APID) mapping table. 119 + * v2 only. 119 120 */ 120 121 struct spmi_pmic_arb_dev { 121 - void __iomem *base; 122 + void __iomem *rd_base; 123 + void __iomem *wr_base; 122 124 void __iomem *intr; 123 125 void __iomem *cnfg; 124 126 raw_spinlock_t lock; ··· 135 129 struct irq_domain *domain; 136 130 struct spmi_controller *spmic; 137 131 u16 apid_to_ppid[256]; 132 + const struct pmic_arb_ver_ops *ver_ops; 133 + u8 *ppid_to_chan; 134 + }; 135 + 136 + /** 137 + * pmic_arb_ver: version dependent functionality. 138 + * 139 + * @non_data_cmd: on v1 issues an spmi non-data command. 140 + * on v2 no HW support, returns -EOPNOTSUPP. 141 + * @offset: on v1 offset of per-ee channel. 142 + * on v2 offset of per-ee and per-ppid channel. 143 + * @fmt_cmd: formats a GENI/SPMI command. 144 + * @owner_acc_status: on v1 offset of PMIC_ARB_SPMI_PIC_OWNERm_ACC_STATUSn 145 + * on v2 offset of SPMI_PIC_OWNERm_ACC_STATUSn. 146 + * @acc_enable: on v1 offset of PMIC_ARB_SPMI_PIC_ACC_ENABLEn 147 + * on v2 offset of SPMI_PIC_ACC_ENABLEn. 148 + * @irq_status: on v1 offset of PMIC_ARB_SPMI_PIC_IRQ_STATUSn 149 + * on v2 offset of SPMI_PIC_IRQ_STATUSn. 150 + * @irq_clear: on v1 offset of PMIC_ARB_SPMI_PIC_IRQ_CLEARn 151 + * on v2 offset of SPMI_PIC_IRQ_CLEARn. 152 + */ 153 + struct pmic_arb_ver_ops { 154 + /* spmi commands (read_cmd, write_cmd, cmd) functionality */ 155 + u32 (*offset)(struct spmi_pmic_arb_dev *dev, u8 sid, u16 addr); 156 + u32 (*fmt_cmd)(u8 opc, u8 sid, u16 addr, u8 bc); 157 + int (*non_data_cmd)(struct spmi_controller *ctrl, u8 opc, u8 sid); 158 + /* Interrupts controller functionality (offset of PIC registers) */ 159 + u32 (*owner_acc_status)(u8 m, u8 n); 160 + u32 (*acc_enable)(u8 n); 161 + u32 (*irq_status)(u8 n); 162 + u32 (*irq_clear)(u8 n); 138 163 }; 139 164 140 165 static inline u32 pmic_arb_base_read(struct spmi_pmic_arb_dev *dev, u32 offset) 141 166 { 142 - return readl_relaxed(dev->base + offset); 167 + return readl_relaxed(dev->rd_base + offset); 143 168 } 144 169 145 170 static inline void pmic_arb_base_write(struct spmi_pmic_arb_dev *dev, 146 171 u32 offset, u32 val) 147 172 { 148 - writel_relaxed(val, dev->base + offset); 173 + writel_relaxed(val, dev->wr_base + offset); 174 + } 175 + 176 + static inline void pmic_arb_set_rd_cmd(struct spmi_pmic_arb_dev *dev, 177 + u32 offset, u32 val) 178 + { 179 + writel_relaxed(val, dev->rd_base + offset); 149 180 } 150 181 151 182 /** ··· 211 168 pmic_arb_base_write(dev, reg, data); 212 169 } 213 170 214 - static int pmic_arb_wait_for_done(struct spmi_controller *ctrl) 171 + static int pmic_arb_wait_for_done(struct spmi_controller *ctrl, 172 + void __iomem *base, u8 sid, u16 addr) 215 173 { 216 174 struct spmi_pmic_arb_dev *dev = spmi_controller_get_drvdata(ctrl); 217 175 u32 status = 0; 218 176 u32 timeout = PMIC_ARB_TIMEOUT_US; 219 - u32 offset = PMIC_ARB_STATUS(dev->channel); 177 + u32 offset = dev->ver_ops->offset(dev, sid, addr) + PMIC_ARB_STATUS; 220 178 221 179 while (timeout--) { 222 - status = pmic_arb_base_read(dev, offset); 180 + status = readl_relaxed(base + offset); 223 181 224 182 if (status & PMIC_ARB_STATUS_DONE) { 225 183 if (status & PMIC_ARB_STATUS_DENIED) { ··· 255 211 return -ETIMEDOUT; 256 212 } 257 213 258 - /* Non-data command */ 259 - static int pmic_arb_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid) 214 + static int 215 + pmic_arb_non_data_cmd_v1(struct spmi_controller *ctrl, u8 opc, u8 sid) 260 216 { 261 217 struct spmi_pmic_arb_dev *pmic_arb = spmi_controller_get_drvdata(ctrl); 262 218 unsigned long flags; 263 219 u32 cmd; 264 220 int rc; 221 + u32 offset = pmic_arb->ver_ops->offset(pmic_arb, sid, 0); 222 + 223 + cmd = ((opc | 0x40) << 27) | ((sid & 0xf) << 20); 224 + 225 + raw_spin_lock_irqsave(&pmic_arb->lock, flags); 226 + pmic_arb_base_write(pmic_arb, offset + PMIC_ARB_CMD, cmd); 227 + rc = pmic_arb_wait_for_done(ctrl, pmic_arb->wr_base, sid, 0); 228 + raw_spin_unlock_irqrestore(&pmic_arb->lock, flags); 229 + 230 + return rc; 231 + } 232 + 233 + static int 234 + pmic_arb_non_data_cmd_v2(struct spmi_controller *ctrl, u8 opc, u8 sid) 235 + { 236 + return -EOPNOTSUPP; 237 + } 238 + 239 + /* Non-data command */ 240 + static int pmic_arb_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid) 241 + { 242 + struct spmi_pmic_arb_dev *pmic_arb = spmi_controller_get_drvdata(ctrl); 243 + 244 + dev_dbg(&ctrl->dev, "cmd op:0x%x sid:%d\n", opc, sid); 265 245 266 246 /* Check for valid non-data command */ 267 247 if (opc < SPMI_CMD_RESET || opc > SPMI_CMD_WAKEUP) 268 248 return -EINVAL; 269 249 270 - cmd = ((opc | 0x40) << 27) | ((sid & 0xf) << 20); 271 - 272 - raw_spin_lock_irqsave(&pmic_arb->lock, flags); 273 - pmic_arb_base_write(pmic_arb, PMIC_ARB_CMD(pmic_arb->channel), cmd); 274 - rc = pmic_arb_wait_for_done(ctrl); 275 - raw_spin_unlock_irqrestore(&pmic_arb->lock, flags); 276 - 277 - return rc; 250 + return pmic_arb->ver_ops->non_data_cmd(ctrl, opc, sid); 278 251 } 279 252 280 253 static int pmic_arb_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, ··· 302 241 u8 bc = len - 1; 303 242 u32 cmd; 304 243 int rc; 244 + u32 offset = pmic_arb->ver_ops->offset(pmic_arb, sid, addr); 305 245 306 246 if (bc >= PMIC_ARB_MAX_TRANS_BYTES) { 307 247 dev_err(&ctrl->dev, 308 - "pmic-arb supports 1..%d bytes per trans, but %d requested", 248 + "pmic-arb supports 1..%d bytes per trans, but:%zu requested", 309 249 PMIC_ARB_MAX_TRANS_BYTES, len); 310 250 return -EINVAL; 311 251 } ··· 321 259 else 322 260 return -EINVAL; 323 261 324 - cmd = (opc << 27) | ((sid & 0xf) << 20) | (addr << 4) | (bc & 0x7); 262 + cmd = pmic_arb->ver_ops->fmt_cmd(opc, sid, addr, bc); 325 263 326 264 raw_spin_lock_irqsave(&pmic_arb->lock, flags); 327 - pmic_arb_base_write(pmic_arb, PMIC_ARB_CMD(pmic_arb->channel), cmd); 328 - rc = pmic_arb_wait_for_done(ctrl); 265 + pmic_arb_set_rd_cmd(pmic_arb, offset + PMIC_ARB_CMD, cmd); 266 + rc = pmic_arb_wait_for_done(ctrl, pmic_arb->rd_base, sid, addr); 329 267 if (rc) 330 268 goto done; 331 269 332 - pa_read_data(pmic_arb, buf, PMIC_ARB_RDATA0(pmic_arb->channel), 270 + pa_read_data(pmic_arb, buf, offset + PMIC_ARB_RDATA0, 333 271 min_t(u8, bc, 3)); 334 272 335 273 if (bc > 3) 336 274 pa_read_data(pmic_arb, buf + 4, 337 - PMIC_ARB_RDATA1(pmic_arb->channel), bc - 4); 275 + offset + PMIC_ARB_RDATA1, bc - 4); 338 276 339 277 done: 340 278 raw_spin_unlock_irqrestore(&pmic_arb->lock, flags); ··· 349 287 u8 bc = len - 1; 350 288 u32 cmd; 351 289 int rc; 290 + u32 offset = pmic_arb->ver_ops->offset(pmic_arb, sid, addr); 352 291 353 292 if (bc >= PMIC_ARB_MAX_TRANS_BYTES) { 354 293 dev_err(&ctrl->dev, 355 - "pmic-arb supports 1..%d bytes per trans, but:%d requested", 294 + "pmic-arb supports 1..%d bytes per trans, but:%zu requested", 356 295 PMIC_ARB_MAX_TRANS_BYTES, len); 357 296 return -EINVAL; 358 297 } ··· 370 307 else 371 308 return -EINVAL; 372 309 373 - cmd = (opc << 27) | ((sid & 0xf) << 20) | (addr << 4) | (bc & 0x7); 310 + cmd = pmic_arb->ver_ops->fmt_cmd(opc, sid, addr, bc); 374 311 375 312 /* Write data to FIFOs */ 376 313 raw_spin_lock_irqsave(&pmic_arb->lock, flags); 377 - pa_write_data(pmic_arb, buf, PMIC_ARB_WDATA0(pmic_arb->channel) 378 - , min_t(u8, bc, 3)); 314 + pa_write_data(pmic_arb, buf, offset + PMIC_ARB_WDATA0, 315 + min_t(u8, bc, 3)); 379 316 if (bc > 3) 380 317 pa_write_data(pmic_arb, buf + 4, 381 - PMIC_ARB_WDATA1(pmic_arb->channel), bc - 4); 318 + offset + PMIC_ARB_WDATA1, bc - 4); 382 319 383 320 /* Start the transaction */ 384 - pmic_arb_base_write(pmic_arb, PMIC_ARB_CMD(pmic_arb->channel), cmd); 385 - rc = pmic_arb_wait_for_done(ctrl); 321 + pmic_arb_base_write(pmic_arb, offset + PMIC_ARB_CMD, cmd); 322 + rc = pmic_arb_wait_for_done(ctrl, pmic_arb->wr_base, sid, addr); 386 323 raw_spin_unlock_irqrestore(&pmic_arb->lock, flags); 387 324 388 325 return rc; ··· 439 376 u32 status; 440 377 int id; 441 378 442 - status = readl_relaxed(pa->intr + SPMI_PIC_IRQ_STATUS(apid)); 379 + status = readl_relaxed(pa->intr + pa->ver_ops->irq_status(apid)); 443 380 while (status) { 444 381 id = ffs(status) - 1; 445 382 status &= ~(1 << id); ··· 465 402 466 403 for (i = first; i <= last; ++i) { 467 404 status = readl_relaxed(intr + 468 - SPMI_PIC_OWNER_ACC_STATUS(pa->ee, i)); 405 + pa->ver_ops->owner_acc_status(pa->ee, i)); 469 406 while (status) { 470 407 id = ffs(status) - 1; 471 408 status &= ~(1 << id); ··· 485 422 u8 data; 486 423 487 424 raw_spin_lock_irqsave(&pa->lock, flags); 488 - writel_relaxed(1 << irq, pa->intr + SPMI_PIC_IRQ_CLEAR(apid)); 425 + writel_relaxed(1 << irq, pa->intr + pa->ver_ops->irq_clear(apid)); 489 426 raw_spin_unlock_irqrestore(&pa->lock, flags); 490 427 491 428 data = 1 << irq; ··· 502 439 u8 data; 503 440 504 441 raw_spin_lock_irqsave(&pa->lock, flags); 505 - status = readl_relaxed(pa->intr + SPMI_PIC_ACC_ENABLE(apid)); 442 + status = readl_relaxed(pa->intr + pa->ver_ops->acc_enable(apid)); 506 443 if (status & SPMI_PIC_ACC_ENABLE_BIT) { 507 444 status = status & ~SPMI_PIC_ACC_ENABLE_BIT; 508 - writel_relaxed(status, pa->intr + SPMI_PIC_ACC_ENABLE(apid)); 445 + writel_relaxed(status, pa->intr + 446 + pa->ver_ops->acc_enable(apid)); 509 447 } 510 448 raw_spin_unlock_irqrestore(&pa->lock, flags); 511 449 ··· 524 460 u8 data; 525 461 526 462 raw_spin_lock_irqsave(&pa->lock, flags); 527 - status = readl_relaxed(pa->intr + SPMI_PIC_ACC_ENABLE(apid)); 463 + status = readl_relaxed(pa->intr + pa->ver_ops->acc_enable(apid)); 528 464 if (!(status & SPMI_PIC_ACC_ENABLE_BIT)) { 529 465 writel_relaxed(status | SPMI_PIC_ACC_ENABLE_BIT, 530 - pa->intr + SPMI_PIC_ACC_ENABLE(apid)); 466 + pa->intr + pa->ver_ops->acc_enable(apid)); 531 467 } 532 468 raw_spin_unlock_irqrestore(&pa->lock, flags); 533 469 ··· 688 624 return 0; 689 625 } 690 626 627 + /* v1 offset per ee */ 628 + static u32 pmic_arb_offset_v1(struct spmi_pmic_arb_dev *pa, u8 sid, u16 addr) 629 + { 630 + return 0x800 + 0x80 * pa->channel; 631 + } 632 + 633 + /* v2 offset per ppid (chan) and per ee */ 634 + static u32 pmic_arb_offset_v2(struct spmi_pmic_arb_dev *pa, u8 sid, u16 addr) 635 + { 636 + u16 ppid = (sid << 8) | (addr >> 8); 637 + u8 chan = pa->ppid_to_chan[ppid]; 638 + 639 + return 0x1000 * pa->ee + 0x8000 * chan; 640 + } 641 + 642 + static u32 pmic_arb_fmt_cmd_v1(u8 opc, u8 sid, u16 addr, u8 bc) 643 + { 644 + return (opc << 27) | ((sid & 0xf) << 20) | (addr << 4) | (bc & 0x7); 645 + } 646 + 647 + static u32 pmic_arb_fmt_cmd_v2(u8 opc, u8 sid, u16 addr, u8 bc) 648 + { 649 + return (opc << 27) | ((addr & 0xff) << 4) | (bc & 0x7); 650 + } 651 + 652 + static u32 pmic_arb_owner_acc_status_v1(u8 m, u8 n) 653 + { 654 + return 0x20 * m + 0x4 * n; 655 + } 656 + 657 + static u32 pmic_arb_owner_acc_status_v2(u8 m, u8 n) 658 + { 659 + return 0x100000 + 0x1000 * m + 0x4 * n; 660 + } 661 + 662 + static u32 pmic_arb_acc_enable_v1(u8 n) 663 + { 664 + return 0x200 + 0x4 * n; 665 + } 666 + 667 + static u32 pmic_arb_acc_enable_v2(u8 n) 668 + { 669 + return 0x1000 * n; 670 + } 671 + 672 + static u32 pmic_arb_irq_status_v1(u8 n) 673 + { 674 + return 0x600 + 0x4 * n; 675 + } 676 + 677 + static u32 pmic_arb_irq_status_v2(u8 n) 678 + { 679 + return 0x4 + 0x1000 * n; 680 + } 681 + 682 + static u32 pmic_arb_irq_clear_v1(u8 n) 683 + { 684 + return 0xA00 + 0x4 * n; 685 + } 686 + 687 + static u32 pmic_arb_irq_clear_v2(u8 n) 688 + { 689 + return 0x8 + 0x1000 * n; 690 + } 691 + 692 + static const struct pmic_arb_ver_ops pmic_arb_v1 = { 693 + .non_data_cmd = pmic_arb_non_data_cmd_v1, 694 + .offset = pmic_arb_offset_v1, 695 + .fmt_cmd = pmic_arb_fmt_cmd_v1, 696 + .owner_acc_status = pmic_arb_owner_acc_status_v1, 697 + .acc_enable = pmic_arb_acc_enable_v1, 698 + .irq_status = pmic_arb_irq_status_v1, 699 + .irq_clear = pmic_arb_irq_clear_v1, 700 + }; 701 + 702 + static const struct pmic_arb_ver_ops pmic_arb_v2 = { 703 + .non_data_cmd = pmic_arb_non_data_cmd_v2, 704 + .offset = pmic_arb_offset_v2, 705 + .fmt_cmd = pmic_arb_fmt_cmd_v2, 706 + .owner_acc_status = pmic_arb_owner_acc_status_v2, 707 + .acc_enable = pmic_arb_acc_enable_v2, 708 + .irq_status = pmic_arb_irq_status_v2, 709 + .irq_clear = pmic_arb_irq_clear_v2, 710 + }; 711 + 691 712 static const struct irq_domain_ops pmic_arb_irq_domain_ops = { 692 713 .map = qpnpint_irq_domain_map, 693 714 .xlate = qpnpint_irq_domain_dt_translate, ··· 783 634 struct spmi_pmic_arb_dev *pa; 784 635 struct spmi_controller *ctrl; 785 636 struct resource *res; 786 - u32 channel, ee; 637 + void __iomem *core; 638 + u32 channel, ee, hw_ver; 787 639 int err, i; 640 + bool is_v1; 788 641 789 642 ctrl = spmi_controller_alloc(&pdev->dev, sizeof(*pa)); 790 643 if (!ctrl) ··· 796 645 pa->spmic = ctrl; 797 646 798 647 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "core"); 799 - pa->base = devm_ioremap_resource(&ctrl->dev, res); 800 - if (IS_ERR(pa->base)) { 801 - err = PTR_ERR(pa->base); 648 + core = devm_ioremap_resource(&ctrl->dev, res); 649 + if (IS_ERR(core)) { 650 + err = PTR_ERR(core); 802 651 goto err_put_ctrl; 652 + } 653 + 654 + hw_ver = readl_relaxed(core + PMIC_ARB_VERSION); 655 + is_v1 = (hw_ver < PMIC_ARB_VERSION_V2_MIN); 656 + 657 + dev_info(&ctrl->dev, "PMIC Arb Version-%d (0x%x)\n", (is_v1 ? 1 : 2), 658 + hw_ver); 659 + 660 + if (is_v1) { 661 + pa->ver_ops = &pmic_arb_v1; 662 + pa->wr_base = core; 663 + pa->rd_base = core; 664 + } else { 665 + u8 chan; 666 + u16 ppid; 667 + u32 regval; 668 + 669 + pa->ver_ops = &pmic_arb_v2; 670 + 671 + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, 672 + "obsrvr"); 673 + pa->rd_base = devm_ioremap_resource(&ctrl->dev, res); 674 + if (IS_ERR(pa->rd_base)) { 675 + err = PTR_ERR(pa->rd_base); 676 + goto err_put_ctrl; 677 + } 678 + 679 + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, 680 + "chnls"); 681 + pa->wr_base = devm_ioremap_resource(&ctrl->dev, res); 682 + if (IS_ERR(pa->wr_base)) { 683 + err = PTR_ERR(pa->wr_base); 684 + goto err_put_ctrl; 685 + } 686 + 687 + pa->ppid_to_chan = devm_kzalloc(&ctrl->dev, 688 + PPID_TO_CHAN_TABLE_SZ, GFP_KERNEL); 689 + if (!pa->ppid_to_chan) { 690 + err = -ENOMEM; 691 + goto err_put_ctrl; 692 + } 693 + /* 694 + * PMIC_ARB_REG_CHNL is a table in HW mapping channel to ppid. 695 + * ppid_to_chan is an in-memory invert of that table. 696 + */ 697 + for (chan = 0; chan < PMIC_ARB_MAX_CHNL; ++chan) { 698 + regval = readl_relaxed(core + PMIC_ARB_REG_CHNL(chan)); 699 + if (!regval) 700 + continue; 701 + 702 + ppid = (regval >> 8) & 0xFFF; 703 + pa->ppid_to_chan[ppid] = chan; 704 + } 803 705 } 804 706 805 707 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "intr"); ··· 934 730 err = spmi_controller_add(ctrl); 935 731 if (err) 936 732 goto err_domain_remove; 937 - 938 - dev_dbg(&ctrl->dev, "PMIC Arb Version 0x%x\n", 939 - pmic_arb_base_read(pa, PMIC_ARB_VERSION)); 940 733 941 734 return 0; 942 735