Lines Matching +full:primary +full:- +full:pmic
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2012-2015, 2017, 2021, The Linux Foundation. All rights reserved.
22 /* PMIC Arbiter configuration registers */
35 /* PMIC Arbiter channel registers offsets */
52 #define SPMI_MAPPING_TABLE_TREE_DEPTH 16 /* Maximum of 16-bits */
91 * PMIC arbiter version 5 uses different register offsets for read/write vs
101 /* Maximum number of support PMIC peripherals */
135 * struct spmi_pmic_arb_bus - SPMI PMIC Arbiter Bus object
137 * @pmic_arb: the SPMI PMIC Arbiter the bus belongs to.
138 * @domain: irq domain object for PMIC IRQ domain
140 * @cnfg: address of the PMIC Arbiter configuration registers.
147 * @mapping_table: in-memory copy of PPID -> APID mapping table.
148 * @mapping_table_valid:bitmap containing valid-only periphs
149 * @ppid_to_apid: in-memory copy of PPID -> APID mapping table.
154 * @irq: PMIC ARB interrupt.
178 * struct spmi_pmic_arb - SPMI PMIC Arbiter object
205 * struct pmic_arb_ver_ops - version dependent functionality.
211 * @non_data_cmd: on v1 issues an spmi non-data command.
212 * on v2 no HW support, returns -EOPNOTSUPP.
213 * @offset: on v1 offset of per-ee channel.
214 * on v2 offset of per-ee and per-ppid channel.
250 writel_relaxed(val, pmic_arb->wr_base + offset); in pmic_arb_base_write()
256 writel_relaxed(val, pmic_arb->rd_base + offset); in pmic_arb_set_rd_cmd()
260 * pmic_arb_read_data: reads pmic-arb's register and copy 1..4 bytes to buf
261 * @pmic_arb: the SPMI PMIC arbiter
262 * @bc: byte count -1. range: 0..3
269 u32 data = __raw_readl(pmic_arb->rd_base + reg); in pmic_arb_read_data()
275 * pmic_arb_write_data: write 1..4 bytes from buf to pmic-arb's register
276 * @pmic_arb: the SPMI PMIC arbiter
277 * @bc: byte-count -1. range: 0..3.
287 __raw_writel(data, pmic_arb->wr_base + reg); in pmic_arb_write_data()
295 struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; in pmic_arb_wait_for_done()
301 rc = pmic_arb->ver_ops->offset(bus, sid, addr, ch_type); in pmic_arb_wait_for_done()
308 while (timeout--) { in pmic_arb_wait_for_done()
313 dev_err(&ctrl->dev, "%s: %#x %#x: transaction denied (%#x)\n", in pmic_arb_wait_for_done()
315 return -EPERM; in pmic_arb_wait_for_done()
319 dev_err(&ctrl->dev, "%s: %#x %#x: transaction failed (%#x) reg: 0x%x\n", in pmic_arb_wait_for_done()
322 return -EIO; in pmic_arb_wait_for_done()
326 dev_err(&ctrl->dev, "%s: %#x %#x: transaction dropped (%#x)\n", in pmic_arb_wait_for_done()
328 return -EIO; in pmic_arb_wait_for_done()
336 dev_err(&ctrl->dev, "%s: %#x %#x %#x: timeout, status %#x\n", in pmic_arb_wait_for_done()
337 __func__, bus->id, sid, addr, status); in pmic_arb_wait_for_done()
338 return -ETIMEDOUT; in pmic_arb_wait_for_done()
345 struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; in pmic_arb_non_data_cmd_v1()
351 rc = pmic_arb->ver_ops->offset(bus, sid, 0, PMIC_ARB_CHANNEL_RW); in pmic_arb_non_data_cmd_v1()
358 raw_spin_lock_irqsave(&bus->lock, flags); in pmic_arb_non_data_cmd_v1()
360 rc = pmic_arb_wait_for_done(ctrl, pmic_arb->wr_base, sid, 0, in pmic_arb_non_data_cmd_v1()
362 raw_spin_unlock_irqrestore(&bus->lock, flags); in pmic_arb_non_data_cmd_v1()
370 return -EOPNOTSUPP; in pmic_arb_non_data_cmd_v2()
373 /* Non-data command */
378 dev_dbg(&ctrl->dev, "cmd op:0x%x sid:%d\n", opc, sid); in pmic_arb_cmd()
380 /* Check for valid non-data command */ in pmic_arb_cmd()
382 return -EINVAL; in pmic_arb_cmd()
384 return pmic_arb->ver_ops->non_data_cmd(ctrl, opc, sid); in pmic_arb_cmd()
390 struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; in pmic_arb_fmt_read_cmd()
391 u8 bc = len - 1; in pmic_arb_fmt_read_cmd()
394 rc = pmic_arb->ver_ops->offset(bus, sid, addr, in pmic_arb_fmt_read_cmd()
401 dev_err(&bus->spmic->dev, "pmic-arb supports 1..%d bytes per trans, but:%zu requested\n", in pmic_arb_fmt_read_cmd()
403 return -EINVAL; in pmic_arb_fmt_read_cmd()
414 return -EINVAL; in pmic_arb_fmt_read_cmd()
416 *cmd = pmic_arb->ver_ops->fmt_cmd(opc, sid, addr, bc); in pmic_arb_fmt_read_cmd()
426 struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; in pmic_arb_read_cmd_unlocked()
427 u8 bc = len - 1; in pmic_arb_read_cmd_unlocked()
431 rc = pmic_arb_wait_for_done(ctrl, pmic_arb->rd_base, sid, addr, in pmic_arb_read_cmd_unlocked()
441 bc - 4); in pmic_arb_read_cmd_unlocked()
458 raw_spin_lock_irqsave(&bus->lock, flags); in pmic_arb_read_cmd()
460 raw_spin_unlock_irqrestore(&bus->lock, flags); in pmic_arb_read_cmd()
469 struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; in pmic_arb_fmt_write_cmd()
470 u8 bc = len - 1; in pmic_arb_fmt_write_cmd()
473 rc = pmic_arb->ver_ops->offset(bus, sid, addr, in pmic_arb_fmt_write_cmd()
480 dev_err(&bus->spmic->dev, "pmic-arb supports 1..%d bytes per trans, but:%zu requested\n", in pmic_arb_fmt_write_cmd()
482 return -EINVAL; in pmic_arb_fmt_write_cmd()
495 return -EINVAL; in pmic_arb_fmt_write_cmd()
497 *cmd = pmic_arb->ver_ops->fmt_cmd(opc, sid, addr, bc); in pmic_arb_fmt_write_cmd()
507 struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; in pmic_arb_write_cmd_unlocked()
508 u8 bc = len - 1; in pmic_arb_write_cmd_unlocked()
515 bc - 4); in pmic_arb_write_cmd_unlocked()
519 return pmic_arb_wait_for_done(ctrl, pmic_arb->wr_base, sid, addr, in pmic_arb_write_cmd_unlocked()
536 raw_spin_lock_irqsave(&bus->lock, flags); in pmic_arb_write_cmd()
539 raw_spin_unlock_irqrestore(&bus->lock, flags); in pmic_arb_write_cmd()
563 raw_spin_lock_irqsave(&bus->lock, flags); in pmic_arb_masked_write()
575 raw_spin_unlock_irqrestore(&bus->lock, flags); in pmic_arb_masked_write()
592 u8 type; /* 1 -> edge */
602 u8 sid = hwirq_to_sid(d->hwirq); in qpnpint_spmi_write()
603 u8 per = hwirq_to_per(d->hwirq); in qpnpint_spmi_write()
605 if (pmic_arb_write_cmd(bus->spmic, SPMI_CMD_EXT_WRITEL, sid, in qpnpint_spmi_write()
607 dev_err_ratelimited(&bus->spmic->dev, "failed irqchip transaction on %x\n", in qpnpint_spmi_write()
608 d->irq); in qpnpint_spmi_write()
614 u8 sid = hwirq_to_sid(d->hwirq); in qpnpint_spmi_read()
615 u8 per = hwirq_to_per(d->hwirq); in qpnpint_spmi_read()
617 if (pmic_arb_read_cmd(bus->spmic, SPMI_CMD_EXT_READL, sid, in qpnpint_spmi_read()
619 dev_err_ratelimited(&bus->spmic->dev, "failed irqchip transaction on %x\n", in qpnpint_spmi_read()
620 d->irq); in qpnpint_spmi_read()
628 u8 sid = hwirq_to_sid(d->hwirq); in qpnpint_spmi_masked_write()
629 u8 per = hwirq_to_per(d->hwirq); in qpnpint_spmi_masked_write()
632 rc = pmic_arb_masked_write(bus->spmic, sid, (per << 8) + reg, buf, in qpnpint_spmi_masked_write()
635 dev_err_ratelimited(&bus->spmic->dev, "failed irqchip transaction on %x rc=%d\n", in qpnpint_spmi_masked_write()
636 d->irq, rc); in qpnpint_spmi_masked_write()
642 struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; in cleanup_irq()
643 u16 ppid = bus->apid_data[apid].ppid; in cleanup_irq()
648 dev_err_ratelimited(&bus->spmic->dev, "%s apid=%d sid=0x%x per=0x%x irq=%d\n", in cleanup_irq()
650 writel_relaxed(irq_mask, pmic_arb->ver_ops->irq_clear(bus, apid)); in cleanup_irq()
655 struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; in periph_interrupt()
659 u8 sid = (bus->apid_data[apid].ppid >> 8) & 0xF; in periph_interrupt()
660 u8 per = bus->apid_data[apid].ppid & 0xFF; in periph_interrupt()
662 status = readl_relaxed(pmic_arb->ver_ops->irq_status(bus, apid)); in periph_interrupt()
664 id = ffs(status) - 1; in periph_interrupt()
666 irq = irq_find_mapping(bus->domain, in periph_interrupt()
682 struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; in pmic_arb_chained_irq()
683 const struct pmic_arb_ver_ops *ver_ops = pmic_arb->ver_ops; in pmic_arb_chained_irq()
685 int first = bus->min_apid; in pmic_arb_chained_irq()
686 int last = bus->max_apid; in pmic_arb_chained_irq()
688 * acc_offset will be non-zero for the secondary SPMI bus instance on in pmic_arb_chained_irq()
691 int acc_offset = bus->base_apid >> 5; in pmic_arb_chained_irq()
692 u8 ee = pmic_arb->ee; in pmic_arb_chained_irq()
702 status = readl_relaxed(ver_ops->owner_acc_status(bus, ee, i - acc_offset)); in pmic_arb_chained_irq()
707 id = ffs(status) - 1; in pmic_arb_chained_irq()
716 ver_ops->acc_enable(bus, apid)); in pmic_arb_chained_irq()
727 if (bus->apid_data[i].irq_ee != pmic_arb->ee) in pmic_arb_chained_irq()
731 ver_ops->irq_status(bus, i)); in pmic_arb_chained_irq()
734 ver_ops->acc_enable(bus, i)); in pmic_arb_chained_irq()
736 dev_dbg(&bus->spmic->dev, in pmic_arb_chained_irq()
755 struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; in qpnpint_irq_ack()
756 u8 irq = hwirq_to_irq(d->hwirq); in qpnpint_irq_ack()
757 u16 apid = hwirq_to_apid(d->hwirq); in qpnpint_irq_ack()
760 writel_relaxed(BIT(irq), pmic_arb->ver_ops->irq_clear(bus, apid)); in qpnpint_irq_ack()
768 u8 irq = hwirq_to_irq(d->hwirq); in qpnpint_irq_mask()
777 struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; in qpnpint_irq_unmask()
778 const struct pmic_arb_ver_ops *ver_ops = pmic_arb->ver_ops; in qpnpint_irq_unmask()
779 u8 irq = hwirq_to_irq(d->hwirq); in qpnpint_irq_unmask()
780 u16 apid = hwirq_to_apid(d->hwirq); in qpnpint_irq_unmask()
784 ver_ops->acc_enable(bus, apid)); in qpnpint_irq_unmask()
804 u8 irq_bit = BIT(hwirq_to_irq(d->hwirq)); in qpnpint_irq_set_type()
818 return -EINVAL; in qpnpint_irq_set_type()
843 return irq_set_irq_wake(bus->irq, on); in qpnpint_irq_set_wake()
850 u8 irq = hwirq_to_irq(d->hwirq); in qpnpint_get_irqchip_state()
854 return -EINVAL; in qpnpint_get_irqchip_state()
866 struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; in qpnpint_irq_domain_activate()
867 u16 periph = hwirq_to_per(d->hwirq); in qpnpint_irq_domain_activate()
868 u16 apid = hwirq_to_apid(d->hwirq); in qpnpint_irq_domain_activate()
869 u16 sid = hwirq_to_sid(d->hwirq); in qpnpint_irq_domain_activate()
870 u16 irq = hwirq_to_irq(d->hwirq); in qpnpint_irq_domain_activate()
873 if (bus->apid_data[apid].irq_ee != pmic_arb->ee) { in qpnpint_irq_domain_activate()
874 …dev_err(&bus->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u: ee=%u but owner=%u\n… in qpnpint_irq_domain_activate()
875 sid, periph, irq, pmic_arb->ee, in qpnpint_irq_domain_activate()
876 bus->apid_data[apid].irq_ee); in qpnpint_irq_domain_activate()
877 return -ENODEV; in qpnpint_irq_domain_activate()
903 struct spmi_pmic_arb_bus *bus = d->host_data; in qpnpint_irq_domain_translate()
904 struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; in qpnpint_irq_domain_translate()
905 u32 *intspec = fwspec->param; in qpnpint_irq_domain_translate()
909 dev_dbg(&bus->spmic->dev, "intspec[0] 0x%1x intspec[1] 0x%02x intspec[2] 0x%02x\n", in qpnpint_irq_domain_translate()
912 if (irq_domain_get_of_node(d) != bus->spmic->dev.of_node) in qpnpint_irq_domain_translate()
913 return -EINVAL; in qpnpint_irq_domain_translate()
914 if (fwspec->param_count != 4) in qpnpint_irq_domain_translate()
915 return -EINVAL; in qpnpint_irq_domain_translate()
917 return -EINVAL; in qpnpint_irq_domain_translate()
920 rc = pmic_arb->ver_ops->ppid_to_apid(bus, ppid); in qpnpint_irq_domain_translate()
922 dev_err(&bus->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u rc = %d\n", in qpnpint_irq_domain_translate()
929 if (apid > bus->max_apid) in qpnpint_irq_domain_translate()
930 bus->max_apid = apid; in qpnpint_irq_domain_translate()
931 if (apid < bus->min_apid) in qpnpint_irq_domain_translate()
932 bus->min_apid = apid; in qpnpint_irq_domain_translate()
937 dev_dbg(&bus->spmic->dev, "out_hwirq = %lu\n", *out_hwirq); in qpnpint_irq_domain_translate()
950 dev_dbg(&bus->spmic->dev, "virq = %u, hwirq = %lu, type = %u\n", in qpnpint_irq_domain_map()
969 struct spmi_pmic_arb_bus *bus = domain->host_data; in qpnpint_irq_domain_alloc()
988 struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; in pmic_arb_init_apid_min_max()
994 bus->max_apid = 0; in pmic_arb_init_apid_min_max()
995 bus->min_apid = pmic_arb->max_periphs - 1; in pmic_arb_init_apid_min_max()
1005 pmic_arb->wr_base = core; in pmic_arb_get_core_resources_v1()
1006 pmic_arb->rd_base = core; in pmic_arb_get_core_resources_v1()
1008 pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS; in pmic_arb_get_core_resources_v1()
1015 struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; in pmic_arb_init_apid_v1()
1019 dev_err(&bus->spmic->dev, "Unsupported buses count %d detected\n", in pmic_arb_init_apid_v1()
1021 return -EINVAL; in pmic_arb_init_apid_v1()
1024 mapping_table = devm_kcalloc(&bus->spmic->dev, pmic_arb->max_periphs, in pmic_arb_init_apid_v1()
1027 return -ENOMEM; in pmic_arb_init_apid_v1()
1029 bus->mapping_table = mapping_table; in pmic_arb_init_apid_v1()
1036 u32 *mapping_table = bus->mapping_table; in pmic_arb_ppid_to_apid_v1()
1042 apid_valid = bus->ppid_to_apid[ppid]; in pmic_arb_ppid_to_apid_v1()
1049 if (!test_and_set_bit(index, bus->mapping_table_valid)) in pmic_arb_ppid_to_apid_v1()
1050 mapping_table[index] = readl_relaxed(bus->cnfg + in pmic_arb_ppid_to_apid_v1()
1060 bus->ppid_to_apid[ppid] in pmic_arb_ppid_to_apid_v1()
1062 bus->apid_data[apid].ppid = ppid; in pmic_arb_ppid_to_apid_v1()
1070 bus->ppid_to_apid[ppid] in pmic_arb_ppid_to_apid_v1()
1072 bus->apid_data[apid].ppid = ppid; in pmic_arb_ppid_to_apid_v1()
1078 return -ENODEV; in pmic_arb_ppid_to_apid_v1()
1085 struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; in pmic_arb_offset_v1()
1086 return 0x800 + 0x80 * pmic_arb->channel; in pmic_arb_offset_v1()
1091 struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; in pmic_arb_find_apid()
1092 struct apid_data *apidd = &bus->apid_data[bus->last_apid]; in pmic_arb_find_apid()
1096 for (apid = bus->last_apid; ; apid++, apidd++) { in pmic_arb_find_apid()
1097 offset = pmic_arb->ver_ops->apid_map_offset(apid); in pmic_arb_find_apid()
1098 if (offset >= pmic_arb->core_size) in pmic_arb_find_apid()
1101 regval = readl_relaxed(pmic_arb->ver_ops->apid_owner(bus, in pmic_arb_find_apid()
1103 apidd->irq_ee = SPMI_OWNERSHIP_PERIPH2OWNER(regval); in pmic_arb_find_apid()
1104 apidd->write_ee = apidd->irq_ee; in pmic_arb_find_apid()
1106 regval = readl_relaxed(pmic_arb->core + offset); in pmic_arb_find_apid()
1111 bus->ppid_to_apid[id] = apid | PMIC_ARB_APID_VALID; in pmic_arb_find_apid()
1112 apidd->ppid = id; in pmic_arb_find_apid()
1118 bus->last_apid = apid & ~PMIC_ARB_APID_VALID; in pmic_arb_find_apid()
1127 pmic_arb->rd_base = devm_platform_ioremap_resource_byname(pdev, "obsrvr"); in pmic_arb_get_obsrvr_chnls_v2()
1128 if (IS_ERR(pmic_arb->rd_base)) in pmic_arb_get_obsrvr_chnls_v2()
1129 return PTR_ERR(pmic_arb->rd_base); in pmic_arb_get_obsrvr_chnls_v2()
1131 pmic_arb->wr_base = devm_platform_ioremap_resource_byname(pdev, "chnls"); in pmic_arb_get_obsrvr_chnls_v2()
1132 if (IS_ERR(pmic_arb->wr_base)) in pmic_arb_get_obsrvr_chnls_v2()
1133 return PTR_ERR(pmic_arb->wr_base); in pmic_arb_get_obsrvr_chnls_v2()
1143 pmic_arb->core = core; in pmic_arb_get_core_resources_v2()
1145 pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS; in pmic_arb_get_core_resources_v2()
1154 apid_valid = bus->ppid_to_apid[ppid]; in pmic_arb_ppid_to_apid_v2()
1158 return -ENODEV; in pmic_arb_ppid_to_apid_v2()
1165 struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; in pmic_arb_read_apid_map_v5()
1181 * the primary bus (0) and secondary bus (1) such that: in pmic_arb_read_apid_map_v5()
1182 * APID = 0 to N-1 are assigned to the primary bus in pmic_arb_read_apid_map_v5()
1183 * APID = N to N+M-1 are assigned to the secondary bus in pmic_arb_read_apid_map_v5()
1184 * where N = number of APIDs supported by the primary bus and in pmic_arb_read_apid_map_v5()
1187 apidd = &bus->apid_data[bus->base_apid]; in pmic_arb_read_apid_map_v5()
1188 apid_max = bus->base_apid + bus->apid_count; in pmic_arb_read_apid_map_v5()
1189 for (i = bus->base_apid; i < apid_max; i++, apidd++) { in pmic_arb_read_apid_map_v5()
1190 offset = pmic_arb->ver_ops->apid_map_offset(i); in pmic_arb_read_apid_map_v5()
1191 if (offset >= pmic_arb->core_size) in pmic_arb_read_apid_map_v5()
1194 regval = readl_relaxed(pmic_arb->core + offset); in pmic_arb_read_apid_map_v5()
1200 regval = readl_relaxed(pmic_arb->ver_ops->apid_owner(bus, i)); in pmic_arb_read_apid_map_v5()
1201 apidd->write_ee = SPMI_OWNERSHIP_PERIPH2OWNER(regval); in pmic_arb_read_apid_map_v5()
1203 apidd->irq_ee = is_irq_ee ? apidd->write_ee : INVALID_EE; in pmic_arb_read_apid_map_v5()
1205 valid = bus->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID; in pmic_arb_read_apid_map_v5()
1206 apid = bus->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID; in pmic_arb_read_apid_map_v5()
1207 prev_apidd = &bus->apid_data[apid]; in pmic_arb_read_apid_map_v5()
1209 if (!valid || apidd->write_ee == pmic_arb->ee) { in pmic_arb_read_apid_map_v5()
1211 bus->ppid_to_apid[ppid] = i | PMIC_ARB_APID_VALID; in pmic_arb_read_apid_map_v5()
1213 prev_apidd->write_ee == pmic_arb->ee) { in pmic_arb_read_apid_map_v5()
1218 prev_apidd->irq_ee = apidd->irq_ee; in pmic_arb_read_apid_map_v5()
1221 apidd->ppid = ppid; in pmic_arb_read_apid_map_v5()
1222 bus->last_apid = i; in pmic_arb_read_apid_map_v5()
1226 dev_dbg(&bus->spmic->dev, "PPID APID Write-EE IRQ-EE\n"); in pmic_arb_read_apid_map_v5()
1228 apid = bus->ppid_to_apid[ppid]; in pmic_arb_read_apid_map_v5()
1231 apidd = &bus->apid_data[apid]; in pmic_arb_read_apid_map_v5()
1232 dev_dbg(&bus->spmic->dev, "%#03X %3u %2u %2u\n", in pmic_arb_read_apid_map_v5()
1233 ppid, apid, apidd->write_ee, apidd->irq_ee); in pmic_arb_read_apid_map_v5()
1242 if (!(bus->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID)) in pmic_arb_ppid_to_apid_v5()
1243 return -ENODEV; in pmic_arb_ppid_to_apid_v5()
1245 return bus->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID; in pmic_arb_ppid_to_apid_v5()
1252 struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; in pmic_arb_offset_v2()
1263 return 0x1000 * pmic_arb->ee + 0x8000 * apid; in pmic_arb_offset_v2()
1268 struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; in pmic_arb_init_apid_v5()
1272 dev_err(&bus->spmic->dev, "Unsupported buses count %d detected\n", in pmic_arb_init_apid_v5()
1274 return -EINVAL; in pmic_arb_init_apid_v5()
1277 bus->base_apid = 0; in pmic_arb_init_apid_v5()
1278 bus->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) & in pmic_arb_init_apid_v5()
1281 if (bus->base_apid + bus->apid_count > pmic_arb->max_periphs) { in pmic_arb_init_apid_v5()
1282 dev_err(&bus->spmic->dev, "Unsupported APID count %d detected\n", in pmic_arb_init_apid_v5()
1283 bus->base_apid + bus->apid_count); in pmic_arb_init_apid_v5()
1284 return -EINVAL; in pmic_arb_init_apid_v5()
1293 dev_err(&bus->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n", in pmic_arb_init_apid_v5()
1308 struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; in pmic_arb_offset_v5()
1321 offset = 0x10000 * pmic_arb->ee + 0x80 * apid; in pmic_arb_offset_v5()
1324 if (bus->apid_data[apid].write_ee != pmic_arb->ee) { in pmic_arb_offset_v5()
1325 dev_err(&bus->spmic->dev, "disallowed SPMI write to sid=%u, addr=0x%04X\n", in pmic_arb_offset_v5()
1327 return -EPERM; in pmic_arb_offset_v5()
1341 pmic_arb->core = core; in pmic_arb_get_core_resources_v7()
1343 pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS_V7; in pmic_arb_get_core_resources_v7()
1354 struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; in pmic_arb_init_apid_v7()
1358 bus->base_apid = 0; in pmic_arb_init_apid_v7()
1359 bus->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) & in pmic_arb_init_apid_v7()
1362 bus->base_apid = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) & in pmic_arb_init_apid_v7()
1364 bus->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES1) & in pmic_arb_init_apid_v7()
1367 dev_err(&bus->spmic->dev, "Unsupported buses count %d detected\n", in pmic_arb_init_apid_v7()
1368 bus->id); in pmic_arb_init_apid_v7()
1369 return -EINVAL; in pmic_arb_init_apid_v7()
1372 if (bus->base_apid + bus->apid_count > pmic_arb->max_periphs) { in pmic_arb_init_apid_v7()
1373 dev_err(&bus->spmic->dev, "Unsupported APID count %d detected\n", in pmic_arb_init_apid_v7()
1374 bus->base_apid + bus->apid_count); in pmic_arb_init_apid_v7()
1375 return -EINVAL; in pmic_arb_init_apid_v7()
1384 dev_err(&bus->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n", in pmic_arb_init_apid_v7()
1399 struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; in pmic_arb_offset_v7()
1405 rc = pmic_arb->ver_ops->ppid_to_apid(bus, ppid); in pmic_arb_offset_v7()
1412 offset = 0x8000 * pmic_arb->ee + 0x20 * apid; in pmic_arb_offset_v7()
1415 if (bus->apid_data[apid].write_ee != pmic_arb->ee) { in pmic_arb_offset_v7()
1416 dev_err(&bus->spmic->dev, "disallowed SPMI write to sid=%u, addr=0x%04X\n", in pmic_arb_offset_v7()
1418 return -EPERM; in pmic_arb_offset_v7()
1440 return bus->intr + 0x20 * m + 0x4 * n; in pmic_arb_owner_acc_status_v1()
1446 return bus->intr + 0x100000 + 0x1000 * m + 0x4 * n; in pmic_arb_owner_acc_status_v2()
1452 return bus->intr + 0x200000 + 0x1000 * m + 0x4 * n; in pmic_arb_owner_acc_status_v3()
1458 return bus->intr + 0x10000 * m + 0x4 * n; in pmic_arb_owner_acc_status_v5()
1464 return bus->intr + 0x1000 * m + 0x4 * n; in pmic_arb_owner_acc_status_v7()
1470 return bus->intr + 0x200 + 0x4 * n; in pmic_arb_acc_enable_v1()
1476 return bus->intr + 0x1000 * n; in pmic_arb_acc_enable_v2()
1482 struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; in pmic_arb_acc_enable_v5()
1483 return pmic_arb->wr_base + 0x100 + 0x10000 * n; in pmic_arb_acc_enable_v5()
1489 struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; in pmic_arb_acc_enable_v7()
1490 return pmic_arb->wr_base + 0x100 + 0x1000 * n; in pmic_arb_acc_enable_v7()
1496 return bus->intr + 0x600 + 0x4 * n; in pmic_arb_irq_status_v1()
1502 return bus->intr + 0x4 + 0x1000 * n; in pmic_arb_irq_status_v2()
1508 struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; in pmic_arb_irq_status_v5()
1509 return pmic_arb->wr_base + 0x104 + 0x10000 * n; in pmic_arb_irq_status_v5()
1515 struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; in pmic_arb_irq_status_v7()
1516 return pmic_arb->wr_base + 0x104 + 0x1000 * n; in pmic_arb_irq_status_v7()
1522 return bus->intr + 0xA00 + 0x4 * n; in pmic_arb_irq_clear_v1()
1528 return bus->intr + 0x8 + 0x1000 * n; in pmic_arb_irq_clear_v2()
1534 struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; in pmic_arb_irq_clear_v5()
1535 return pmic_arb->wr_base + 0x108 + 0x10000 * n; in pmic_arb_irq_clear_v5()
1541 struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; in pmic_arb_irq_clear_v7()
1542 return pmic_arb->wr_base + 0x108 + 0x1000 * n; in pmic_arb_irq_clear_v7()
1563 return bus->cnfg + 0x700 + 0x4 * n; in pmic_arb_apid_owner_v2()
1574 return bus->cnfg + 0x4 * (n - bus->base_apid); in pmic_arb_apid_owner_v7()
1668 int bus_index = pmic_arb->buses_available; in spmi_pmic_arb_bus_init()
1670 struct device *dev = &pdev->dev; in spmi_pmic_arb_bus_init()
1681 ctrl->cmd = pmic_arb_cmd; in spmi_pmic_arb_bus_init()
1682 ctrl->read_cmd = pmic_arb_read_cmd; in spmi_pmic_arb_bus_init()
1683 ctrl->write_cmd = pmic_arb_write_cmd; in spmi_pmic_arb_bus_init()
1687 pmic_arb->buses[bus_index] = bus; in spmi_pmic_arb_bus_init()
1689 raw_spin_lock_init(&bus->lock); in spmi_pmic_arb_bus_init()
1691 bus->ppid_to_apid = devm_kcalloc(dev, PMIC_ARB_MAX_PPID, in spmi_pmic_arb_bus_init()
1692 sizeof(*bus->ppid_to_apid), in spmi_pmic_arb_bus_init()
1694 if (!bus->ppid_to_apid) in spmi_pmic_arb_bus_init()
1695 return -ENOMEM; in spmi_pmic_arb_bus_init()
1697 bus->apid_data = devm_kcalloc(dev, pmic_arb->max_periphs, in spmi_pmic_arb_bus_init()
1698 sizeof(*bus->apid_data), in spmi_pmic_arb_bus_init()
1700 if (!bus->apid_data) in spmi_pmic_arb_bus_init()
1701 return -ENOMEM; in spmi_pmic_arb_bus_init()
1703 index = of_property_match_string(node, "reg-names", "cnfg"); in spmi_pmic_arb_bus_init()
1706 return -EINVAL; in spmi_pmic_arb_bus_init()
1713 index = of_property_match_string(node, "reg-names", "intr"); in spmi_pmic_arb_bus_init()
1716 return -EINVAL; in spmi_pmic_arb_bus_init()
1725 return irq ?: -ENXIO; in spmi_pmic_arb_bus_init()
1727 bus->pmic_arb = pmic_arb; in spmi_pmic_arb_bus_init()
1728 bus->intr = intr; in spmi_pmic_arb_bus_init()
1729 bus->cnfg = cnfg; in spmi_pmic_arb_bus_init()
1730 bus->irq = irq; in spmi_pmic_arb_bus_init()
1731 bus->spmic = ctrl; in spmi_pmic_arb_bus_init()
1732 bus->id = bus_index; in spmi_pmic_arb_bus_init()
1734 ret = pmic_arb->ver_ops->init_apid(bus, bus_index); in spmi_pmic_arb_bus_init()
1738 dev_dbg(&pdev->dev, "adding irq domain for bus %d\n", bus_index); in spmi_pmic_arb_bus_init()
1740 bus->domain = irq_domain_add_tree(node, &pmic_arb_irq_domain_ops, bus); in spmi_pmic_arb_bus_init()
1741 if (!bus->domain) { in spmi_pmic_arb_bus_init()
1742 dev_err(&pdev->dev, "unable to create irq_domain\n"); in spmi_pmic_arb_bus_init()
1743 return -ENOMEM; in spmi_pmic_arb_bus_init()
1746 irq_set_chained_handler_and_data(bus->irq, in spmi_pmic_arb_bus_init()
1749 ctrl->dev.of_node = node; in spmi_pmic_arb_bus_init()
1750 dev_set_name(&ctrl->dev, "spmi-%d", bus_index); in spmi_pmic_arb_bus_init()
1756 pmic_arb->buses_available++; in spmi_pmic_arb_bus_init()
1764 struct device *dev = &pdev->dev; in spmi_pmic_arb_register_buses()
1765 struct device_node *node = dev->of_node; in spmi_pmic_arb_register_buses()
1770 if (of_device_is_compatible(node, "qcom,spmi-pmic-arb")) in spmi_pmic_arb_register_buses()
1788 for (i = 0; i < pmic_arb->buses_available; i++) { in spmi_pmic_arb_deregister_buses()
1789 struct spmi_pmic_arb_bus *bus = pmic_arb->buses[i]; in spmi_pmic_arb_deregister_buses()
1791 irq_set_chained_handler_and_data(bus->irq, in spmi_pmic_arb_deregister_buses()
1793 irq_domain_remove(bus->domain); in spmi_pmic_arb_deregister_buses()
1800 struct device *dev = &pdev->dev; in spmi_pmic_arb_probe()
1808 return -ENOMEM; in spmi_pmic_arb_probe()
1811 core = devm_ioremap(dev, res->start, resource_size(res)); in spmi_pmic_arb_probe()
1813 return -ENOMEM; in spmi_pmic_arb_probe()
1815 pmic_arb->core_size = resource_size(res); in spmi_pmic_arb_probe()
1822 pmic_arb->ver_ops = &pmic_arb_v1; in spmi_pmic_arb_probe()
1824 pmic_arb->ver_ops = &pmic_arb_v2; in spmi_pmic_arb_probe()
1826 pmic_arb->ver_ops = &pmic_arb_v3; in spmi_pmic_arb_probe()
1828 pmic_arb->ver_ops = &pmic_arb_v5; in spmi_pmic_arb_probe()
1830 pmic_arb->ver_ops = &pmic_arb_v7; in spmi_pmic_arb_probe()
1832 err = pmic_arb->ver_ops->get_core_resources(pdev, core); in spmi_pmic_arb_probe()
1836 dev_info(dev, "PMIC arbiter version %s (0x%x)\n", in spmi_pmic_arb_probe()
1837 pmic_arb->ver_ops->ver_str, hw_ver); in spmi_pmic_arb_probe()
1839 err = of_property_read_u32(pdev->dev.of_node, "qcom,channel", &channel); in spmi_pmic_arb_probe()
1841 dev_err(&pdev->dev, "channel unspecified.\n"); in spmi_pmic_arb_probe()
1846 dev_err(&pdev->dev, "invalid channel (%u) specified.\n", in spmi_pmic_arb_probe()
1848 return -EINVAL; in spmi_pmic_arb_probe()
1851 pmic_arb->channel = channel; in spmi_pmic_arb_probe()
1853 err = of_property_read_u32(pdev->dev.of_node, "qcom,ee", &ee); in spmi_pmic_arb_probe()
1855 dev_err(&pdev->dev, "EE unspecified.\n"); in spmi_pmic_arb_probe()
1860 dev_err(&pdev->dev, "invalid EE (%u) specified\n", ee); in spmi_pmic_arb_probe()
1861 return -EINVAL; in spmi_pmic_arb_probe()
1864 pmic_arb->ee = ee; in spmi_pmic_arb_probe()
1877 { .compatible = "qcom,spmi-pmic-arb", },
1878 { .compatible = "qcom,x1e80100-spmi-pmic-arb", },
1893 MODULE_DESCRIPTION("Qualcomm MSM SPMI Controller (PMIC Arbiter) driver");