• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
4  */
5 
6 #include <linux/err.h>
7 #include <linux/init.h>
8 #include <linux/interrupt.h>
9 #include <linux/irq.h>
10 #include <linux/irqchip.h>
11 #include <linux/irqdomain.h>
12 #include <linux/io.h>
13 #include <linux/kernel.h>
14 #include <linux/module.h>
15 #include <linux/of.h>
16 #include <linux/of_irq.h>
17 #include <linux/of_address.h>
18 #include <linux/of_device.h>
19 #include <linux/soc/qcom/irq.h>
20 #include <linux/spinlock.h>
21 #include <linux/slab.h>
22 #include <linux/types.h>
23 
24 #include <linux/qcom_scm.h>
25 
26 #define PDC_MAX_IRQS		168
27 #define PDC_MAX_GPIO_IRQS	256
28 
29 #define CLEAR_INTR(reg, intr)	(reg & ~(1 << intr))
30 #define ENABLE_INTR(reg, intr)	(reg | (1 << intr))
31 
32 #define IRQ_ENABLE_BANK		0x10
33 #define IRQ_i_CFG		0x110
34 
35 #define PDC_NO_PARENT_IRQ	~0UL
36 
37 struct pdc_pin_region {
38 	u32 pin_base;
39 	u32 parent_base;
40 	u32 cnt;
41 };
42 
43 struct spi_cfg_regs {
44 	union {
45 		u64 start;
46 		void __iomem *base;
47 	};
48 	resource_size_t size;
49 	bool scm_io;
50 };
51 
52 static DEFINE_RAW_SPINLOCK(pdc_lock);
53 static void __iomem *pdc_base;
54 static struct pdc_pin_region *pdc_region;
55 static int pdc_region_cnt;
56 static struct spi_cfg_regs *spi_cfg;
57 
pdc_reg_write(int reg,u32 i,u32 val)58 static void pdc_reg_write(int reg, u32 i, u32 val)
59 {
60 	writel_relaxed(val, pdc_base + reg + i * sizeof(u32));
61 }
62 
pdc_reg_read(int reg,u32 i)63 static u32 pdc_reg_read(int reg, u32 i)
64 {
65 	return readl_relaxed(pdc_base + reg + i * sizeof(u32));
66 }
67 
pdc_enable_intr(struct irq_data * d,bool on)68 static void pdc_enable_intr(struct irq_data *d, bool on)
69 {
70 	int pin_out = d->hwirq;
71 	unsigned long flags;
72 	u32 index, mask;
73 	u32 enable;
74 
75 	index = pin_out / 32;
76 	mask = pin_out % 32;
77 
78 	raw_spin_lock_irqsave(&pdc_lock, flags);
79 	enable = pdc_reg_read(IRQ_ENABLE_BANK, index);
80 	enable = on ? ENABLE_INTR(enable, mask) : CLEAR_INTR(enable, mask);
81 	pdc_reg_write(IRQ_ENABLE_BANK, index, enable);
82 	raw_spin_unlock_irqrestore(&pdc_lock, flags);
83 }
84 
qcom_pdc_gic_disable(struct irq_data * d)85 static void qcom_pdc_gic_disable(struct irq_data *d)
86 {
87 	if (d->hwirq == GPIO_NO_WAKE_IRQ)
88 		return;
89 
90 	pdc_enable_intr(d, false);
91 	irq_chip_disable_parent(d);
92 }
93 
qcom_pdc_gic_get_irqchip_state(struct irq_data * d,enum irqchip_irq_state which,bool * state)94 static int qcom_pdc_gic_get_irqchip_state(struct irq_data *d,
95 		enum irqchip_irq_state which, bool *state)
96 {
97 	if (d->hwirq == GPIO_NO_WAKE_IRQ)
98 		return 0;
99 
100 	return irq_chip_get_parent_state(d, which, state);
101 }
102 
qcom_pdc_gic_set_irqchip_state(struct irq_data * d,enum irqchip_irq_state which,bool value)103 static int qcom_pdc_gic_set_irqchip_state(struct irq_data *d,
104 		enum irqchip_irq_state which, bool value)
105 {
106 	if (d->hwirq == GPIO_NO_WAKE_IRQ)
107 		return 0;
108 
109 	return irq_chip_set_parent_state(d, which, value);
110 }
111 
qcom_pdc_gic_enable(struct irq_data * d)112 static void qcom_pdc_gic_enable(struct irq_data *d)
113 {
114 	if (d->hwirq == GPIO_NO_WAKE_IRQ)
115 		return;
116 
117 	pdc_enable_intr(d, true);
118 	irq_chip_enable_parent(d);
119 }
120 
qcom_pdc_gic_mask(struct irq_data * d)121 static void qcom_pdc_gic_mask(struct irq_data *d)
122 {
123 	if (d->hwirq == GPIO_NO_WAKE_IRQ)
124 		return;
125 
126 	irq_chip_mask_parent(d);
127 }
128 
qcom_pdc_gic_unmask(struct irq_data * d)129 static void qcom_pdc_gic_unmask(struct irq_data *d)
130 {
131 	if (d->hwirq == GPIO_NO_WAKE_IRQ)
132 		return;
133 
134 	irq_chip_unmask_parent(d);
135 }
136 
__spi_pin_read(unsigned int pin)137 static u32 __spi_pin_read(unsigned int pin)
138 {
139 	void __iomem *cfg_reg = spi_cfg->base + pin * 4;
140 	u64 scm_cfg_reg = spi_cfg->start + pin * 4;
141 
142 	if (spi_cfg->scm_io) {
143 		unsigned int val;
144 
145 		qcom_scm_io_readl(scm_cfg_reg, &val);
146 		return val;
147 	} else {
148 		return readl(cfg_reg);
149 	}
150 }
151 
__spi_pin_write(unsigned int pin,unsigned int val)152 static void __spi_pin_write(unsigned int pin, unsigned int val)
153 {
154 	void __iomem *cfg_reg = spi_cfg->base + pin * 4;
155 	u64 scm_cfg_reg = spi_cfg->start + pin * 4;
156 
157 	if (spi_cfg->scm_io)
158 		qcom_scm_io_writel(scm_cfg_reg, val);
159 	else
160 		writel(val, cfg_reg);
161 }
162 
spi_configure_type(irq_hw_number_t hwirq,unsigned int type)163 static int spi_configure_type(irq_hw_number_t hwirq, unsigned int type)
164 {
165 	int spi = hwirq - 32;
166 	u32 pin = spi / 32;
167 	u32 mask = BIT(spi % 32);
168 	u32 val;
169 	unsigned long flags;
170 
171 	if (!spi_cfg)
172 		return 0;
173 
174 	if (pin * 4 > spi_cfg->size)
175 		return -EFAULT;
176 
177 	raw_spin_lock_irqsave(&pdc_lock, flags);
178 	val = __spi_pin_read(pin);
179 	val &= ~mask;
180 	if (type & IRQ_TYPE_LEVEL_MASK)
181 		val |= mask;
182 	__spi_pin_write(pin, val);
183 	raw_spin_unlock_irqrestore(&pdc_lock, flags);
184 
185 	return 0;
186 }
187 
188 /*
189  * GIC does not handle falling edge or active low. To allow falling edge and
190  * active low interrupts to be handled at GIC, PDC has an inverter that inverts
191  * falling edge into a rising edge and active low into an active high.
192  * For the inverter to work, the polarity bit in the IRQ_CONFIG register has to
193  * set as per the table below.
194  * Level sensitive active low    LOW
195  * Rising edge sensitive         NOT USED
196  * Falling edge sensitive        LOW
197  * Dual Edge sensitive           NOT USED
198  * Level sensitive active High   HIGH
199  * Falling Edge sensitive        NOT USED
200  * Rising edge sensitive         HIGH
201  * Dual Edge sensitive           HIGH
202  */
203 enum pdc_irq_config_bits {
204 	PDC_LEVEL_LOW		= 0b000,
205 	PDC_EDGE_FALLING	= 0b010,
206 	PDC_LEVEL_HIGH		= 0b100,
207 	PDC_EDGE_RISING		= 0b110,
208 	PDC_EDGE_DUAL		= 0b111,
209 };
210 
211 /**
212  * qcom_pdc_gic_set_type: Configure PDC for the interrupt
213  *
214  * @d: the interrupt data
215  * @type: the interrupt type
216  *
217  * If @type is edge triggered, forward that as Rising edge as PDC
218  * takes care of converting falling edge to rising edge signal
219  * If @type is level, then forward that as level high as PDC
220  * takes care of converting falling edge to rising edge signal
221  */
qcom_pdc_gic_set_type(struct irq_data * d,unsigned int type)222 static int qcom_pdc_gic_set_type(struct irq_data *d, unsigned int type)
223 {
224 	int pin_out = d->hwirq;
225 	int parent_hwirq = d->parent_data->hwirq;
226 	enum pdc_irq_config_bits pdc_type;
227 	int ret;
228 
229 	if (pin_out == GPIO_NO_WAKE_IRQ)
230 		return 0;
231 
232 	switch (type) {
233 	case IRQ_TYPE_EDGE_RISING:
234 		pdc_type = PDC_EDGE_RISING;
235 		break;
236 	case IRQ_TYPE_EDGE_FALLING:
237 		pdc_type = PDC_EDGE_FALLING;
238 		type = IRQ_TYPE_EDGE_RISING;
239 		break;
240 	case IRQ_TYPE_EDGE_BOTH:
241 		pdc_type = PDC_EDGE_DUAL;
242 		type = IRQ_TYPE_EDGE_RISING;
243 		break;
244 	case IRQ_TYPE_LEVEL_HIGH:
245 		pdc_type = PDC_LEVEL_HIGH;
246 		break;
247 	case IRQ_TYPE_LEVEL_LOW:
248 		pdc_type = PDC_LEVEL_LOW;
249 		type = IRQ_TYPE_LEVEL_HIGH;
250 		break;
251 	default:
252 		WARN_ON(1);
253 		return -EINVAL;
254 	}
255 
256 	pdc_reg_write(IRQ_i_CFG, pin_out, pdc_type);
257 
258 	/* Additionally, configure (only) the GPIO in the f/w */
259 	ret = spi_configure_type(parent_hwirq, type);
260 	if (ret)
261 		return ret;
262 
263 	return irq_chip_set_type_parent(d, type);
264 }
265 
266 static struct irq_chip qcom_pdc_gic_chip = {
267 	.name			= "PDC",
268 	.irq_eoi		= irq_chip_eoi_parent,
269 	.irq_mask		= qcom_pdc_gic_mask,
270 	.irq_unmask		= qcom_pdc_gic_unmask,
271 	.irq_disable		= qcom_pdc_gic_disable,
272 	.irq_enable		= qcom_pdc_gic_enable,
273 	.irq_get_irqchip_state	= qcom_pdc_gic_get_irqchip_state,
274 	.irq_set_irqchip_state	= qcom_pdc_gic_set_irqchip_state,
275 	.irq_retrigger		= irq_chip_retrigger_hierarchy,
276 	.irq_set_type		= qcom_pdc_gic_set_type,
277 	.flags			= IRQCHIP_MASK_ON_SUSPEND |
278 				  IRQCHIP_SET_TYPE_MASKED |
279 				  IRQCHIP_SKIP_SET_WAKE,
280 	.irq_set_vcpu_affinity	= irq_chip_set_vcpu_affinity_parent,
281 	.irq_set_affinity	= irq_chip_set_affinity_parent,
282 };
283 
get_parent_hwirq(int pin)284 static irq_hw_number_t get_parent_hwirq(int pin)
285 {
286 	int i;
287 	struct pdc_pin_region *region;
288 
289 	for (i = 0; i < pdc_region_cnt; i++) {
290 		region = &pdc_region[i];
291 		if (pin >= region->pin_base &&
292 		    pin < region->pin_base + region->cnt)
293 			return (region->parent_base + pin - region->pin_base);
294 	}
295 
296 	return PDC_NO_PARENT_IRQ;
297 }
298 
qcom_pdc_translate(struct irq_domain * d,struct irq_fwspec * fwspec,unsigned long * hwirq,unsigned int * type)299 static int qcom_pdc_translate(struct irq_domain *d, struct irq_fwspec *fwspec,
300 			      unsigned long *hwirq, unsigned int *type)
301 {
302 	if (is_of_node(fwspec->fwnode)) {
303 		if (fwspec->param_count != 2)
304 			return -EINVAL;
305 
306 		*hwirq = fwspec->param[0];
307 		*type = fwspec->param[1] & IRQ_TYPE_SENSE_MASK;
308 		return 0;
309 	}
310 
311 	return -EINVAL;
312 }
313 
qcom_pdc_alloc(struct irq_domain * domain,unsigned int virq,unsigned int nr_irqs,void * data)314 static int qcom_pdc_alloc(struct irq_domain *domain, unsigned int virq,
315 			  unsigned int nr_irqs, void *data)
316 {
317 	struct irq_fwspec *fwspec = data;
318 	struct irq_fwspec parent_fwspec;
319 	irq_hw_number_t hwirq, parent_hwirq;
320 	unsigned int type;
321 	int ret;
322 
323 	ret = qcom_pdc_translate(domain, fwspec, &hwirq, &type);
324 	if (ret)
325 		return ret;
326 
327 	ret  = irq_domain_set_hwirq_and_chip(domain, virq, hwirq,
328 					     &qcom_pdc_gic_chip, NULL);
329 	if (ret)
330 		return ret;
331 
332 	parent_hwirq = get_parent_hwirq(hwirq);
333 	if (parent_hwirq == PDC_NO_PARENT_IRQ)
334 		return 0;
335 
336 	if (type & IRQ_TYPE_EDGE_BOTH)
337 		type = IRQ_TYPE_EDGE_RISING;
338 
339 	if (type & IRQ_TYPE_LEVEL_MASK)
340 		type = IRQ_TYPE_LEVEL_HIGH;
341 
342 	parent_fwspec.fwnode      = domain->parent->fwnode;
343 	parent_fwspec.param_count = 3;
344 	parent_fwspec.param[0]    = 0;
345 	parent_fwspec.param[1]    = parent_hwirq;
346 	parent_fwspec.param[2]    = type;
347 
348 	return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs,
349 					    &parent_fwspec);
350 }
351 
352 static const struct irq_domain_ops qcom_pdc_ops = {
353 	.translate	= qcom_pdc_translate,
354 	.alloc		= qcom_pdc_alloc,
355 	.free		= irq_domain_free_irqs_common,
356 };
357 
qcom_pdc_gpio_alloc(struct irq_domain * domain,unsigned int virq,unsigned int nr_irqs,void * data)358 static int qcom_pdc_gpio_alloc(struct irq_domain *domain, unsigned int virq,
359 			       unsigned int nr_irqs, void *data)
360 {
361 	struct irq_fwspec *fwspec = data;
362 	struct irq_fwspec parent_fwspec;
363 	irq_hw_number_t hwirq, parent_hwirq;
364 	unsigned int type;
365 	int ret;
366 
367 	ret = qcom_pdc_translate(domain, fwspec, &hwirq, &type);
368 	if (ret)
369 		return ret;
370 
371 	ret = irq_domain_set_hwirq_and_chip(domain, virq, hwirq,
372 					    &qcom_pdc_gic_chip, NULL);
373 	if (ret)
374 		return ret;
375 
376 	if (hwirq == GPIO_NO_WAKE_IRQ)
377 		return 0;
378 
379 	parent_hwirq = get_parent_hwirq(hwirq);
380 	if (parent_hwirq == PDC_NO_PARENT_IRQ)
381 		return 0;
382 
383 	if (type & IRQ_TYPE_EDGE_BOTH)
384 		type = IRQ_TYPE_EDGE_RISING;
385 
386 	if (type & IRQ_TYPE_LEVEL_MASK)
387 		type = IRQ_TYPE_LEVEL_HIGH;
388 
389 	parent_fwspec.fwnode      = domain->parent->fwnode;
390 	parent_fwspec.param_count = 3;
391 	parent_fwspec.param[0]    = 0;
392 	parent_fwspec.param[1]    = parent_hwirq;
393 	parent_fwspec.param[2]    = type;
394 
395 	return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs,
396 					    &parent_fwspec);
397 }
398 
qcom_pdc_gpio_domain_select(struct irq_domain * d,struct irq_fwspec * fwspec,enum irq_domain_bus_token bus_token)399 static int qcom_pdc_gpio_domain_select(struct irq_domain *d,
400 				       struct irq_fwspec *fwspec,
401 				       enum irq_domain_bus_token bus_token)
402 {
403 	return bus_token == DOMAIN_BUS_WAKEUP;
404 }
405 
406 static const struct irq_domain_ops qcom_pdc_gpio_ops = {
407 	.select		= qcom_pdc_gpio_domain_select,
408 	.alloc		= qcom_pdc_gpio_alloc,
409 	.free		= irq_domain_free_irqs_common,
410 };
411 
pdc_setup_pin_mapping(struct device_node * np)412 static int pdc_setup_pin_mapping(struct device_node *np)
413 {
414 	int ret, n;
415 
416 	n = of_property_count_elems_of_size(np, "qcom,pdc-ranges", sizeof(u32));
417 	if (n <= 0 || n % 3)
418 		return -EINVAL;
419 
420 	pdc_region_cnt = n / 3;
421 	pdc_region = kcalloc(pdc_region_cnt, sizeof(*pdc_region), GFP_KERNEL);
422 	if (!pdc_region) {
423 		pdc_region_cnt = 0;
424 		return -ENOMEM;
425 	}
426 
427 	for (n = 0; n < pdc_region_cnt; n++) {
428 		ret = of_property_read_u32_index(np, "qcom,pdc-ranges",
429 						 n * 3 + 0,
430 						 &pdc_region[n].pin_base);
431 		if (ret)
432 			return ret;
433 		ret = of_property_read_u32_index(np, "qcom,pdc-ranges",
434 						 n * 3 + 1,
435 						 &pdc_region[n].parent_base);
436 		if (ret)
437 			return ret;
438 		ret = of_property_read_u32_index(np, "qcom,pdc-ranges",
439 						 n * 3 + 2,
440 						 &pdc_region[n].cnt);
441 		if (ret)
442 			return ret;
443 	}
444 
445 	return 0;
446 }
447 
qcom_pdc_init(struct device_node * node,struct device_node * parent)448 static int qcom_pdc_init(struct device_node *node, struct device_node *parent)
449 {
450 	struct irq_domain *parent_domain, *pdc_domain, *pdc_gpio_domain;
451 	struct resource res;
452 	int ret;
453 
454 	pdc_base = of_iomap(node, 0);
455 	if (!pdc_base) {
456 		pr_err("%pOF: unable to map PDC registers\n", node);
457 		return -ENXIO;
458 	}
459 
460 	parent_domain = irq_find_host(parent);
461 	if (!parent_domain) {
462 		pr_err("%pOF: unable to find PDC's parent domain\n", node);
463 		ret = -ENXIO;
464 		goto fail;
465 	}
466 
467 	ret = pdc_setup_pin_mapping(node);
468 	if (ret) {
469 		pr_err("%pOF: failed to init PDC pin-hwirq mapping\n", node);
470 		goto fail;
471 	}
472 
473 	pdc_domain = irq_domain_create_hierarchy(parent_domain, 0, PDC_MAX_IRQS,
474 						 of_fwnode_handle(node),
475 						 &qcom_pdc_ops, NULL);
476 	if (!pdc_domain) {
477 		pr_err("%pOF: GIC domain add failed\n", node);
478 		ret = -ENOMEM;
479 		goto fail;
480 	}
481 
482 	ret = of_address_to_resource(node, 1, &res);
483 	if (!ret) {
484 		spi_cfg = kcalloc(1, sizeof(*spi_cfg), GFP_KERNEL);
485 		if (!spi_cfg) {
486 			ret = -ENOMEM;
487 			goto remove;
488 		}
489 		spi_cfg->scm_io = of_find_property(node,
490 						   "qcom,scm-spi-cfg", NULL);
491 		spi_cfg->size = resource_size(&res);
492 		if (spi_cfg->scm_io) {
493 			spi_cfg->start = res.start;
494 		} else {
495 			spi_cfg->base = ioremap(res.start, spi_cfg->size);
496 			if (!spi_cfg->base) {
497 				ret = -ENOMEM;
498 				goto remove;
499 			}
500 		}
501 	}
502 
503 	pdc_gpio_domain = irq_domain_create_hierarchy(parent_domain,
504 						      IRQ_DOMAIN_FLAG_QCOM_PDC_WAKEUP,
505 						      PDC_MAX_GPIO_IRQS,
506 						      of_fwnode_handle(node),
507 						      &qcom_pdc_gpio_ops, NULL);
508 	if (!pdc_gpio_domain) {
509 		pr_err("%pOF: PDC domain add failed for GPIO domain\n", node);
510 		ret = -ENOMEM;
511 		goto remove;
512 	}
513 
514 	irq_domain_update_bus_token(pdc_gpio_domain, DOMAIN_BUS_WAKEUP);
515 
516 	return 0;
517 
518 remove:
519 	irq_domain_remove(pdc_domain);
520 	kfree(spi_cfg);
521 fail:
522 	kfree(pdc_region);
523 	iounmap(pdc_base);
524 	return ret;
525 }
526 
527 
528 #ifdef MODULE
qcom_pdc_probe(struct platform_device * pdev)529 static int qcom_pdc_probe(struct platform_device *pdev)
530 {
531 	struct device_node *np = pdev->dev.of_node;
532 	struct device_node *parent = of_irq_find_parent(np);
533 	return qcom_pdc_init(np, parent);
534 }
535 
536 static const struct of_device_id qcom_pdc_match_table[] = {
537 	{ .compatible = "qcom,sdm845-pdc" },
538 	{}
539 };
540 MODULE_DEVICE_TABLE(of, qcom_pdc_match_table);
541 
542 static struct platform_driver qcom_pdc_driver = {
543 	.probe = qcom_pdc_probe,
544 	.driver = {
545 		.name = "qcom-pdc",
546 		.of_match_table = qcom_pdc_match_table,
547 	},
548 };
549 module_platform_driver(qcom_pdc_driver);
550 #else
551 IRQCHIP_DECLARE(pdc_sdm845, "qcom,sdm845-pdc", qcom_pdc_init);
552 #endif
553 
554 MODULE_DESCRIPTION("Qualcomm Technologies, Inc. Power Domain Controller");
555 MODULE_LICENSE("GPL v2");
556