aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGilad Avidov <gavidov@codeaurora.org>2015-03-25 13:37:32 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-03-26 18:51:36 -0400
commitd0c6ae41d12ad7b2ba271f279936327320b6671c (patch)
treeadd5d2166f09fa4b00c0e9309810841275a124f9
parent0b9641f5722a9c08cacb534d633ff469ab02a288 (diff)
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>
-rw-r--r--Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.txt6
-rw-r--r--drivers/spmi/spmi-pmic-arb.c319
2 files changed, 265 insertions, 60 deletions
diff --git a/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.txt b/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.txt
index 715d0998af8e..e16b9b5afc70 100644
--- a/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.txt
+++ b/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.txt
@@ -1,6 +1,6 @@
1Qualcomm SPMI Controller (PMIC Arbiter) 1Qualcomm SPMI Controller (PMIC Arbiter)
2 2
3The SPMI PMIC Arbiter is found on the Snapdragon 800 Series. It is an SPMI 3The SPMI PMIC Arbiter is found on Snapdragon chipsets. It is an SPMI
4controller with wrapping arbitration logic to allow for multiple on-chip 4controller with wrapping arbitration logic to allow for multiple on-chip
5devices to control a single SPMI master. 5devices to control a single SPMI master.
6 6
@@ -19,6 +19,10 @@ Required properties:
19 "core" - core registers 19 "core" - core registers
20 "intr" - interrupt controller registers 20 "intr" - interrupt controller registers
21 "cnfg" - configuration registers 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- reg : address + size pairs describing the PMIC arb register sets; order must 26- reg : address + size pairs describing the PMIC arb register sets; order must
23 correspond with the order of entries in reg-names 27 correspond with the order of entries in reg-names
24- #address-cells : must be set to 2 28- #address-cells : must be set to 2
diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index 20559ab3466d..d7119db49cfe 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -1,4 +1,5 @@
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 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and 5 * it under the terms of the GNU General Public License version 2 and
@@ -25,22 +26,18 @@
25 26
26/* PMIC Arbiter configuration registers */ 27/* PMIC Arbiter configuration registers */
27#define PMIC_ARB_VERSION 0x0000 28#define PMIC_ARB_VERSION 0x0000
29#define PMIC_ARB_VERSION_V2_MIN 0x20010000
28#define PMIC_ARB_INT_EN 0x0004 30#define PMIC_ARB_INT_EN 0x0004
29 31
30/* PMIC Arbiter channel registers */ 32/* PMIC Arbiter channel registers offsets */
31#define PMIC_ARB_CMD(N) (0x0800 + (0x80 * (N))) 33#define PMIC_ARB_CMD 0x00
32#define PMIC_ARB_CONFIG(N) (0x0804 + (0x80 * (N))) 34#define PMIC_ARB_CONFIG 0x04
33#define PMIC_ARB_STATUS(N) (0x0808 + (0x80 * (N))) 35#define PMIC_ARB_STATUS 0x08
34#define PMIC_ARB_WDATA0(N) (0x0810 + (0x80 * (N))) 36#define PMIC_ARB_WDATA0 0x10
35#define PMIC_ARB_WDATA1(N) (0x0814 + (0x80 * (N))) 37#define PMIC_ARB_WDATA1 0x14
36#define PMIC_ARB_RDATA0(N) (0x0818 + (0x80 * (N))) 38#define PMIC_ARB_RDATA0 0x18
37#define PMIC_ARB_RDATA1(N) (0x081C + (0x80 * (N))) 39#define PMIC_ARB_RDATA1 0x1C
38 40#define PMIC_ARB_REG_CHNL(N) (0x800 + 0x4 * (N))
39/* Interrupt Controller */
40#define SPMI_PIC_OWNER_ACC_STATUS(M, N) (0x0000 + ((32 * (M)) + (4 * (N))))
41#define SPMI_PIC_ACC_ENABLE(N) (0x0200 + (4 * (N)))
42#define SPMI_PIC_IRQ_STATUS(N) (0x0600 + (4 * (N)))
43#define SPMI_PIC_IRQ_CLEAR(N) (0x0A00 + (4 * (N)))
44 41
45/* Mapping Table */ 42/* Mapping Table */
46#define SPMI_MAPPING_TABLE_REG(N) (0x0B00 + (4 * (N))) 43#define SPMI_MAPPING_TABLE_REG(N) (0x0B00 + (4 * (N)))
@@ -52,6 +49,7 @@
52 49
53#define SPMI_MAPPING_TABLE_LEN 255 50#define SPMI_MAPPING_TABLE_LEN 255
54#define SPMI_MAPPING_TABLE_TREE_DEPTH 16 /* Maximum of 16-bits */ 51#define SPMI_MAPPING_TABLE_TREE_DEPTH 16 /* Maximum of 16-bits */
52#define PPID_TO_CHAN_TABLE_SZ BIT(12) /* PPID is 12bit chan is 1byte*/
55 53
56/* Ownership Table */ 54/* Ownership Table */
57#define SPMI_OWNERSHIP_TABLE_REG(N) (0x0700 + (4 * (N))) 55#define SPMI_OWNERSHIP_TABLE_REG(N) (0x0700 + (4 * (N)))
@@ -88,6 +86,7 @@ enum pmic_arb_cmd_op_code {
88 86
89/* Maximum number of support PMIC peripherals */ 87/* Maximum number of support PMIC peripherals */
90#define PMIC_ARB_MAX_PERIPHS 256 88#define PMIC_ARB_MAX_PERIPHS 256
89#define PMIC_ARB_MAX_CHNL 128
91#define PMIC_ARB_PERIPH_ID_VALID (1 << 15) 90#define PMIC_ARB_PERIPH_ID_VALID (1 << 15)
92#define PMIC_ARB_TIMEOUT_US 100 91#define PMIC_ARB_TIMEOUT_US 100
93#define PMIC_ARB_MAX_TRANS_BYTES (8) 92#define PMIC_ARB_MAX_TRANS_BYTES (8)
@@ -98,14 +97,17 @@ enum pmic_arb_cmd_op_code {
98/* interrupt enable bit */ 97/* interrupt enable bit */
99#define SPMI_PIC_ACC_ENABLE_BIT BIT(0) 98#define SPMI_PIC_ACC_ENABLE_BIT BIT(0)
100 99
100struct pmic_arb_ver_ops;
101
101/** 102/**
102 * spmi_pmic_arb_dev - SPMI PMIC Arbiter object 103 * spmi_pmic_arb_dev - SPMI PMIC Arbiter object
103 * 104 *
104 * @base: address of the PMIC Arbiter core registers. 105 * @rd_base: on v1 "core", on v2 "observer" register base off DT.
106 * @wr_base: on v1 "core", on v2 "chnls" register base off DT.
105 * @intr: address of the SPMI interrupt control registers. 107 * @intr: address of the SPMI interrupt control registers.
106 * @cnfg: address of the PMIC Arbiter configuration registers. 108 * @cnfg: address of the PMIC Arbiter configuration registers.
107 * @lock: lock to synchronize accesses. 109 * @lock: lock to synchronize accesses.
108 * @channel: which channel to use for accesses. 110 * @channel: execution environment channel to use for accesses.
109 * @irq: PMIC ARB interrupt. 111 * @irq: PMIC ARB interrupt.
110 * @ee: the current Execution Environment 112 * @ee: the current Execution Environment
111 * @min_apid: minimum APID (used for bounding IRQ search) 113 * @min_apid: minimum APID (used for bounding IRQ search)
@@ -113,10 +115,14 @@ enum pmic_arb_cmd_op_code {
113 * @mapping_table: in-memory copy of PPID -> APID mapping table. 115 * @mapping_table: in-memory copy of PPID -> APID mapping table.
114 * @domain: irq domain object for PMIC IRQ domain 116 * @domain: irq domain object for PMIC IRQ domain
115 * @spmic: SPMI controller object 117 * @spmic: SPMI controller object
116 * @apid_to_ppid: cached mapping from APID to PPID 118 * @apid_to_ppid: in-memory copy of APID -> PPID mapping table.
119 * @ver_ops: version dependent operations.
120 * @ppid_to_chan in-memory copy of PPID -> channel (APID) mapping table.
121 * v2 only.
117 */ 122 */
118struct spmi_pmic_arb_dev { 123struct spmi_pmic_arb_dev {
119 void __iomem *base; 124 void __iomem *rd_base;
125 void __iomem *wr_base;
120 void __iomem *intr; 126 void __iomem *intr;
121 void __iomem *cnfg; 127 void __iomem *cnfg;
122 raw_spinlock_t lock; 128 raw_spinlock_t lock;
@@ -129,17 +135,54 @@ struct spmi_pmic_arb_dev {
129 struct irq_domain *domain; 135 struct irq_domain *domain;
130 struct spmi_controller *spmic; 136 struct spmi_controller *spmic;
131 u16 apid_to_ppid[256]; 137 u16 apid_to_ppid[256];
138 const struct pmic_arb_ver_ops *ver_ops;
139 u8 *ppid_to_chan;
140};
141
142/**
143 * pmic_arb_ver: version dependent functionality.
144 *
145 * @non_data_cmd: on v1 issues an spmi non-data command.
146 * on v2 no HW support, returns -EOPNOTSUPP.
147 * @offset: on v1 offset of per-ee channel.
148 * on v2 offset of per-ee and per-ppid channel.
149 * @fmt_cmd: formats a GENI/SPMI command.
150 * @owner_acc_status: on v1 offset of PMIC_ARB_SPMI_PIC_OWNERm_ACC_STATUSn
151 * on v2 offset of SPMI_PIC_OWNERm_ACC_STATUSn.
152 * @acc_enable: on v1 offset of PMIC_ARB_SPMI_PIC_ACC_ENABLEn
153 * on v2 offset of SPMI_PIC_ACC_ENABLEn.
154 * @irq_status: on v1 offset of PMIC_ARB_SPMI_PIC_IRQ_STATUSn
155 * on v2 offset of SPMI_PIC_IRQ_STATUSn.
156 * @irq_clear: on v1 offset of PMIC_ARB_SPMI_PIC_IRQ_CLEARn
157 * on v2 offset of SPMI_PIC_IRQ_CLEARn.
158 */
159struct pmic_arb_ver_ops {
160 /* spmi commands (read_cmd, write_cmd, cmd) functionality */
161 u32 (*offset)(struct spmi_pmic_arb_dev *dev, u8 sid, u16 addr);
162 u32 (*fmt_cmd)(u8 opc, u8 sid, u16 addr, u8 bc);
163 int (*non_data_cmd)(struct spmi_controller *ctrl, u8 opc, u8 sid);
164 /* Interrupts controller functionality (offset of PIC registers) */
165 u32 (*owner_acc_status)(u8 m, u8 n);
166 u32 (*acc_enable)(u8 n);
167 u32 (*irq_status)(u8 n);
168 u32 (*irq_clear)(u8 n);
132}; 169};
133 170
134static inline u32 pmic_arb_base_read(struct spmi_pmic_arb_dev *dev, u32 offset) 171static inline u32 pmic_arb_base_read(struct spmi_pmic_arb_dev *dev, u32 offset)
135{ 172{
136 return readl_relaxed(dev->base + offset); 173 return readl_relaxed(dev->rd_base + offset);
137} 174}
138 175
139static inline void pmic_arb_base_write(struct spmi_pmic_arb_dev *dev, 176static inline void pmic_arb_base_write(struct spmi_pmic_arb_dev *dev,
140 u32 offset, u32 val) 177 u32 offset, u32 val)
141{ 178{
142 writel_relaxed(val, dev->base + offset); 179 writel_relaxed(val, dev->wr_base + offset);
180}
181
182static inline void pmic_arb_set_rd_cmd(struct spmi_pmic_arb_dev *dev,
183 u32 offset, u32 val)
184{
185 writel_relaxed(val, dev->rd_base + offset);
143} 186}
144 187
145/** 188/**
@@ -168,15 +211,16 @@ pa_write_data(struct spmi_pmic_arb_dev *dev, const u8 *buf, u32 reg, u8 bc)
168 pmic_arb_base_write(dev, reg, data); 211 pmic_arb_base_write(dev, reg, data);
169} 212}
170 213
171static int pmic_arb_wait_for_done(struct spmi_controller *ctrl) 214static int pmic_arb_wait_for_done(struct spmi_controller *ctrl,
215 void __iomem *base, u8 sid, u16 addr)
172{ 216{
173 struct spmi_pmic_arb_dev *dev = spmi_controller_get_drvdata(ctrl); 217 struct spmi_pmic_arb_dev *dev = spmi_controller_get_drvdata(ctrl);
174 u32 status = 0; 218 u32 status = 0;
175 u32 timeout = PMIC_ARB_TIMEOUT_US; 219 u32 timeout = PMIC_ARB_TIMEOUT_US;
176 u32 offset = PMIC_ARB_STATUS(dev->channel); 220 u32 offset = dev->ver_ops->offset(dev, sid, addr) + PMIC_ARB_STATUS;
177 221
178 while (timeout--) { 222 while (timeout--) {
179 status = pmic_arb_base_read(dev, offset); 223 status = readl_relaxed(base + offset);
180 224
181 if (status & PMIC_ARB_STATUS_DONE) { 225 if (status & PMIC_ARB_STATUS_DONE) {
182 if (status & PMIC_ARB_STATUS_DENIED) { 226 if (status & PMIC_ARB_STATUS_DENIED) {
@@ -211,28 +255,45 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl)
211 return -ETIMEDOUT; 255 return -ETIMEDOUT;
212} 256}
213 257
214/* Non-data command */ 258static int
215static int pmic_arb_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid) 259pmic_arb_non_data_cmd_v1(struct spmi_controller *ctrl, u8 opc, u8 sid)
216{ 260{
217 struct spmi_pmic_arb_dev *pmic_arb = spmi_controller_get_drvdata(ctrl); 261 struct spmi_pmic_arb_dev *pmic_arb = spmi_controller_get_drvdata(ctrl);
218 unsigned long flags; 262 unsigned long flags;
219 u32 cmd; 263 u32 cmd;
220 int rc; 264 int rc;
221 265 u32 offset = pmic_arb->ver_ops->offset(pmic_arb, sid, 0);
222 /* Check for valid non-data command */
223 if (opc < SPMI_CMD_RESET || opc > SPMI_CMD_WAKEUP)
224 return -EINVAL;
225 266
226 cmd = ((opc | 0x40) << 27) | ((sid & 0xf) << 20); 267 cmd = ((opc | 0x40) << 27) | ((sid & 0xf) << 20);
227 268
228 raw_spin_lock_irqsave(&pmic_arb->lock, flags); 269 raw_spin_lock_irqsave(&pmic_arb->lock, flags);
229 pmic_arb_base_write(pmic_arb, PMIC_ARB_CMD(pmic_arb->channel), cmd); 270 pmic_arb_base_write(pmic_arb, offset + PMIC_ARB_CMD, cmd);
230 rc = pmic_arb_wait_for_done(ctrl); 271 rc = pmic_arb_wait_for_done(ctrl, pmic_arb->wr_base, sid, 0);
231 raw_spin_unlock_irqrestore(&pmic_arb->lock, flags); 272 raw_spin_unlock_irqrestore(&pmic_arb->lock, flags);
232 273
233 return rc; 274 return rc;
234} 275}
235 276
277static int
278pmic_arb_non_data_cmd_v2(struct spmi_controller *ctrl, u8 opc, u8 sid)
279{
280 return -EOPNOTSUPP;
281}
282
283/* Non-data command */
284static int pmic_arb_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid)
285{
286 struct spmi_pmic_arb_dev *pmic_arb = spmi_controller_get_drvdata(ctrl);
287
288 dev_dbg(&ctrl->dev, "cmd op:0x%x sid:%d\n", opc, sid);
289
290 /* Check for valid non-data command */
291 if (opc < SPMI_CMD_RESET || opc > SPMI_CMD_WAKEUP)
292 return -EINVAL;
293
294 return pmic_arb->ver_ops->non_data_cmd(ctrl, opc, sid);
295}
296
236static int pmic_arb_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, 297static int pmic_arb_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
237 u16 addr, u8 *buf, size_t len) 298 u16 addr, u8 *buf, size_t len)
238{ 299{
@@ -241,10 +302,11 @@ static int pmic_arb_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
241 u8 bc = len - 1; 302 u8 bc = len - 1;
242 u32 cmd; 303 u32 cmd;
243 int rc; 304 int rc;
305 u32 offset = pmic_arb->ver_ops->offset(pmic_arb, sid, addr);
244 306
245 if (bc >= PMIC_ARB_MAX_TRANS_BYTES) { 307 if (bc >= PMIC_ARB_MAX_TRANS_BYTES) {
246 dev_err(&ctrl->dev, 308 dev_err(&ctrl->dev,
247 "pmic-arb supports 1..%d bytes per trans, but %d requested", 309 "pmic-arb supports 1..%d bytes per trans, but:%zu requested",
248 PMIC_ARB_MAX_TRANS_BYTES, len); 310 PMIC_ARB_MAX_TRANS_BYTES, len);
249 return -EINVAL; 311 return -EINVAL;
250 } 312 }
@@ -259,20 +321,20 @@ static int pmic_arb_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
259 else 321 else
260 return -EINVAL; 322 return -EINVAL;
261 323
262 cmd = (opc << 27) | ((sid & 0xf) << 20) | (addr << 4) | (bc & 0x7); 324 cmd = pmic_arb->ver_ops->fmt_cmd(opc, sid, addr, bc);
263 325
264 raw_spin_lock_irqsave(&pmic_arb->lock, flags); 326 raw_spin_lock_irqsave(&pmic_arb->lock, flags);
265 pmic_arb_base_write(pmic_arb, PMIC_ARB_CMD(pmic_arb->channel), cmd); 327 pmic_arb_set_rd_cmd(pmic_arb, offset + PMIC_ARB_CMD, cmd);
266 rc = pmic_arb_wait_for_done(ctrl); 328 rc = pmic_arb_wait_for_done(ctrl, pmic_arb->rd_base, sid, addr);
267 if (rc) 329 if (rc)
268 goto done; 330 goto done;
269 331
270 pa_read_data(pmic_arb, buf, PMIC_ARB_RDATA0(pmic_arb->channel), 332 pa_read_data(pmic_arb, buf, offset + PMIC_ARB_RDATA0,
271 min_t(u8, bc, 3)); 333 min_t(u8, bc, 3));
272 334
273 if (bc > 3) 335 if (bc > 3)
274 pa_read_data(pmic_arb, buf + 4, 336 pa_read_data(pmic_arb, buf + 4,
275 PMIC_ARB_RDATA1(pmic_arb->channel), bc - 4); 337 offset + PMIC_ARB_RDATA1, bc - 4);
276 338
277done: 339done:
278 raw_spin_unlock_irqrestore(&pmic_arb->lock, flags); 340 raw_spin_unlock_irqrestore(&pmic_arb->lock, flags);
@@ -287,10 +349,11 @@ static int pmic_arb_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
287 u8 bc = len - 1; 349 u8 bc = len - 1;
288 u32 cmd; 350 u32 cmd;
289 int rc; 351 int rc;
352 u32 offset = pmic_arb->ver_ops->offset(pmic_arb, sid, addr);
290 353
291 if (bc >= PMIC_ARB_MAX_TRANS_BYTES) { 354 if (bc >= PMIC_ARB_MAX_TRANS_BYTES) {
292 dev_err(&ctrl->dev, 355 dev_err(&ctrl->dev,
293 "pmic-arb supports 1..%d bytes per trans, but:%d requested", 356 "pmic-arb supports 1..%d bytes per trans, but:%zu requested",
294 PMIC_ARB_MAX_TRANS_BYTES, len); 357 PMIC_ARB_MAX_TRANS_BYTES, len);
295 return -EINVAL; 358 return -EINVAL;
296 } 359 }
@@ -307,19 +370,19 @@ static int pmic_arb_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
307 else 370 else
308 return -EINVAL; 371 return -EINVAL;
309 372
310 cmd = (opc << 27) | ((sid & 0xf) << 20) | (addr << 4) | (bc & 0x7); 373 cmd = pmic_arb->ver_ops->fmt_cmd(opc, sid, addr, bc);
311 374
312 /* Write data to FIFOs */ 375 /* Write data to FIFOs */
313 raw_spin_lock_irqsave(&pmic_arb->lock, flags); 376 raw_spin_lock_irqsave(&pmic_arb->lock, flags);
314 pa_write_data(pmic_arb, buf, PMIC_ARB_WDATA0(pmic_arb->channel) 377 pa_write_data(pmic_arb, buf, offset + PMIC_ARB_WDATA0,
315 , min_t(u8, bc, 3)); 378 min_t(u8, bc, 3));
316 if (bc > 3) 379 if (bc > 3)
317 pa_write_data(pmic_arb, buf + 4, 380 pa_write_data(pmic_arb, buf + 4,
318 PMIC_ARB_WDATA1(pmic_arb->channel), bc - 4); 381 offset + PMIC_ARB_WDATA1, bc - 4);
319 382
320 /* Start the transaction */ 383 /* Start the transaction */
321 pmic_arb_base_write(pmic_arb, PMIC_ARB_CMD(pmic_arb->channel), cmd); 384 pmic_arb_base_write(pmic_arb, offset + PMIC_ARB_CMD, cmd);
322 rc = pmic_arb_wait_for_done(ctrl); 385 rc = pmic_arb_wait_for_done(ctrl, pmic_arb->wr_base, sid, addr);
323 raw_spin_unlock_irqrestore(&pmic_arb->lock, flags); 386 raw_spin_unlock_irqrestore(&pmic_arb->lock, flags);
324 387
325 return rc; 388 return rc;
@@ -376,7 +439,7 @@ static void periph_interrupt(struct spmi_pmic_arb_dev *pa, u8 apid)
376 u32 status; 439 u32 status;
377 int id; 440 int id;
378 441
379 status = readl_relaxed(pa->intr + SPMI_PIC_IRQ_STATUS(apid)); 442 status = readl_relaxed(pa->intr + pa->ver_ops->irq_status(apid));
380 while (status) { 443 while (status) {
381 id = ffs(status) - 1; 444 id = ffs(status) - 1;
382 status &= ~(1 << id); 445 status &= ~(1 << id);
@@ -402,7 +465,7 @@ static void pmic_arb_chained_irq(unsigned int irq, struct irq_desc *desc)
402 465
403 for (i = first; i <= last; ++i) { 466 for (i = first; i <= last; ++i) {
404 status = readl_relaxed(intr + 467 status = readl_relaxed(intr +
405 SPMI_PIC_OWNER_ACC_STATUS(pa->ee, i)); 468 pa->ver_ops->owner_acc_status(pa->ee, i));
406 while (status) { 469 while (status) {
407 id = ffs(status) - 1; 470 id = ffs(status) - 1;
408 status &= ~(1 << id); 471 status &= ~(1 << id);
@@ -422,7 +485,7 @@ static void qpnpint_irq_ack(struct irq_data *d)
422 u8 data; 485 u8 data;
423 486
424 raw_spin_lock_irqsave(&pa->lock, flags); 487 raw_spin_lock_irqsave(&pa->lock, flags);
425 writel_relaxed(1 << irq, pa->intr + SPMI_PIC_IRQ_CLEAR(apid)); 488 writel_relaxed(1 << irq, pa->intr + pa->ver_ops->irq_clear(apid));
426 raw_spin_unlock_irqrestore(&pa->lock, flags); 489 raw_spin_unlock_irqrestore(&pa->lock, flags);
427 490
428 data = 1 << irq; 491 data = 1 << irq;
@@ -439,10 +502,11 @@ static void qpnpint_irq_mask(struct irq_data *d)
439 u8 data; 502 u8 data;
440 503
441 raw_spin_lock_irqsave(&pa->lock, flags); 504 raw_spin_lock_irqsave(&pa->lock, flags);
442 status = readl_relaxed(pa->intr + SPMI_PIC_ACC_ENABLE(apid)); 505 status = readl_relaxed(pa->intr + pa->ver_ops->acc_enable(apid));
443 if (status & SPMI_PIC_ACC_ENABLE_BIT) { 506 if (status & SPMI_PIC_ACC_ENABLE_BIT) {
444 status = status & ~SPMI_PIC_ACC_ENABLE_BIT; 507 status = status & ~SPMI_PIC_ACC_ENABLE_BIT;
445 writel_relaxed(status, pa->intr + SPMI_PIC_ACC_ENABLE(apid)); 508 writel_relaxed(status, pa->intr +
509 pa->ver_ops->acc_enable(apid));
446 } 510 }
447 raw_spin_unlock_irqrestore(&pa->lock, flags); 511 raw_spin_unlock_irqrestore(&pa->lock, flags);
448 512
@@ -460,10 +524,10 @@ static void qpnpint_irq_unmask(struct irq_data *d)
460 u8 data; 524 u8 data;
461 525
462 raw_spin_lock_irqsave(&pa->lock, flags); 526 raw_spin_lock_irqsave(&pa->lock, flags);
463 status = readl_relaxed(pa->intr + SPMI_PIC_ACC_ENABLE(apid)); 527 status = readl_relaxed(pa->intr + pa->ver_ops->acc_enable(apid));
464 if (!(status & SPMI_PIC_ACC_ENABLE_BIT)) { 528 if (!(status & SPMI_PIC_ACC_ENABLE_BIT)) {
465 writel_relaxed(status | SPMI_PIC_ACC_ENABLE_BIT, 529 writel_relaxed(status | SPMI_PIC_ACC_ENABLE_BIT,
466 pa->intr + SPMI_PIC_ACC_ENABLE(apid)); 530 pa->intr + pa->ver_ops->acc_enable(apid));
467 } 531 }
468 raw_spin_unlock_irqrestore(&pa->lock, flags); 532 raw_spin_unlock_irqrestore(&pa->lock, flags);
469 533
@@ -624,6 +688,91 @@ static int qpnpint_irq_domain_map(struct irq_domain *d,
624 return 0; 688 return 0;
625} 689}
626 690
691/* v1 offset per ee */
692static u32 pmic_arb_offset_v1(struct spmi_pmic_arb_dev *pa, u8 sid, u16 addr)
693{
694 return 0x800 + 0x80 * pa->channel;
695}
696
697/* v2 offset per ppid (chan) and per ee */
698static u32 pmic_arb_offset_v2(struct spmi_pmic_arb_dev *pa, u8 sid, u16 addr)
699{
700 u16 ppid = (sid << 8) | (addr >> 8);
701 u8 chan = pa->ppid_to_chan[ppid];
702
703 return 0x1000 * pa->ee + 0x8000 * chan;
704}
705
706static u32 pmic_arb_fmt_cmd_v1(u8 opc, u8 sid, u16 addr, u8 bc)
707{
708 return (opc << 27) | ((sid & 0xf) << 20) | (addr << 4) | (bc & 0x7);
709}
710
711static u32 pmic_arb_fmt_cmd_v2(u8 opc, u8 sid, u16 addr, u8 bc)
712{
713 return (opc << 27) | ((addr & 0xff) << 4) | (bc & 0x7);
714}
715
716static u32 pmic_arb_owner_acc_status_v1(u8 m, u8 n)
717{
718 return 0x20 * m + 0x4 * n;
719}
720
721static u32 pmic_arb_owner_acc_status_v2(u8 m, u8 n)
722{
723 return 0x100000 + 0x1000 * m + 0x4 * n;
724}
725
726static u32 pmic_arb_acc_enable_v1(u8 n)
727{
728 return 0x200 + 0x4 * n;
729}
730
731static u32 pmic_arb_acc_enable_v2(u8 n)
732{
733 return 0x1000 * n;
734}
735
736static u32 pmic_arb_irq_status_v1(u8 n)
737{
738 return 0x600 + 0x4 * n;
739}
740
741static u32 pmic_arb_irq_status_v2(u8 n)
742{
743 return 0x4 + 0x1000 * n;
744}
745
746static u32 pmic_arb_irq_clear_v1(u8 n)
747{
748 return 0xA00 + 0x4 * n;
749}
750
751static u32 pmic_arb_irq_clear_v2(u8 n)
752{
753 return 0x8 + 0x1000 * n;
754}
755
756static const struct pmic_arb_ver_ops pmic_arb_v1 = {
757 .non_data_cmd = pmic_arb_non_data_cmd_v1,
758 .offset = pmic_arb_offset_v1,
759 .fmt_cmd = pmic_arb_fmt_cmd_v1,
760 .owner_acc_status = pmic_arb_owner_acc_status_v1,
761 .acc_enable = pmic_arb_acc_enable_v1,
762 .irq_status = pmic_arb_irq_status_v1,
763 .irq_clear = pmic_arb_irq_clear_v1,
764};
765
766static const struct pmic_arb_ver_ops pmic_arb_v2 = {
767 .non_data_cmd = pmic_arb_non_data_cmd_v2,
768 .offset = pmic_arb_offset_v2,
769 .fmt_cmd = pmic_arb_fmt_cmd_v2,
770 .owner_acc_status = pmic_arb_owner_acc_status_v2,
771 .acc_enable = pmic_arb_acc_enable_v2,
772 .irq_status = pmic_arb_irq_status_v2,
773 .irq_clear = pmic_arb_irq_clear_v2,
774};
775
627static const struct irq_domain_ops pmic_arb_irq_domain_ops = { 776static const struct irq_domain_ops pmic_arb_irq_domain_ops = {
628 .map = qpnpint_irq_domain_map, 777 .map = qpnpint_irq_domain_map,
629 .xlate = qpnpint_irq_domain_dt_translate, 778 .xlate = qpnpint_irq_domain_dt_translate,
@@ -634,8 +783,10 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
634 struct spmi_pmic_arb_dev *pa; 783 struct spmi_pmic_arb_dev *pa;
635 struct spmi_controller *ctrl; 784 struct spmi_controller *ctrl;
636 struct resource *res; 785 struct resource *res;
637 u32 channel, ee; 786 void __iomem *core;
787 u32 channel, ee, hw_ver;
638 int err, i; 788 int err, i;
789 bool is_v1;
639 790
640 ctrl = spmi_controller_alloc(&pdev->dev, sizeof(*pa)); 791 ctrl = spmi_controller_alloc(&pdev->dev, sizeof(*pa));
641 if (!ctrl) 792 if (!ctrl)
@@ -645,12 +796,65 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
645 pa->spmic = ctrl; 796 pa->spmic = ctrl;
646 797
647 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "core"); 798 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "core");
648 pa->base = devm_ioremap_resource(&ctrl->dev, res); 799 core = devm_ioremap_resource(&ctrl->dev, res);
649 if (IS_ERR(pa->base)) { 800 if (IS_ERR(core)) {
650 err = PTR_ERR(pa->base); 801 err = PTR_ERR(core);
651 goto err_put_ctrl; 802 goto err_put_ctrl;
652 } 803 }
653 804
805 hw_ver = readl_relaxed(core + PMIC_ARB_VERSION);
806 is_v1 = (hw_ver < PMIC_ARB_VERSION_V2_MIN);
807
808 dev_info(&ctrl->dev, "PMIC Arb Version-%d (0x%x)\n", (is_v1 ? 1 : 2),
809 hw_ver);
810
811 if (is_v1) {
812 pa->ver_ops = &pmic_arb_v1;
813 pa->wr_base = core;
814 pa->rd_base = core;
815 } else {
816 u8 chan;
817 u16 ppid;
818 u32 regval;
819
820 pa->ver_ops = &pmic_arb_v2;
821
822 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
823 "obsrvr");
824 pa->rd_base = devm_ioremap_resource(&ctrl->dev, res);
825 if (IS_ERR(pa->rd_base)) {
826 err = PTR_ERR(pa->rd_base);
827 goto err_put_ctrl;
828 }
829
830 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
831 "chnls");
832 pa->wr_base = devm_ioremap_resource(&ctrl->dev, res);
833 if (IS_ERR(pa->wr_base)) {
834 err = PTR_ERR(pa->wr_base);
835 goto err_put_ctrl;
836 }
837
838 pa->ppid_to_chan = devm_kzalloc(&ctrl->dev,
839 PPID_TO_CHAN_TABLE_SZ, GFP_KERNEL);
840 if (!pa->ppid_to_chan) {
841 err = -ENOMEM;
842 goto err_put_ctrl;
843 }
844 /*
845 * PMIC_ARB_REG_CHNL is a table in HW mapping channel to ppid.
846 * ppid_to_chan is an in-memory invert of that table.
847 */
848 for (chan = 0; chan < PMIC_ARB_MAX_CHNL; ++chan) {
849 regval = readl_relaxed(core + PMIC_ARB_REG_CHNL(chan));
850 if (!regval)
851 continue;
852
853 ppid = (regval >> 8) & 0xFFF;
854 pa->ppid_to_chan[ppid] = chan;
855 }
856 }
857
654 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "intr"); 858 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "intr");
655 pa->intr = devm_ioremap_resource(&ctrl->dev, res); 859 pa->intr = devm_ioremap_resource(&ctrl->dev, res);
656 if (IS_ERR(pa->intr)) { 860 if (IS_ERR(pa->intr)) {
@@ -731,9 +935,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
731 if (err) 935 if (err)
732 goto err_domain_remove; 936 goto err_domain_remove;
733 937
734 dev_dbg(&ctrl->dev, "PMIC Arb Version 0x%x\n",
735 pmic_arb_base_read(pa, PMIC_ARB_VERSION));
736
737 return 0; 938 return 0;
738 939
739err_domain_remove: 940err_domain_remove: