Lines Matching +full:pic +full:- +full:base +full:- +full:vec
1 // SPDX-License-Identifier: GPL-2.0
4 * Loongson PCH PIC support
7 #define pr_fmt(fmt) "pch-pic: " fmt
20 #include "irq-loongson.h"
43 void __iomem *base; member
62 return priv->table[hirq]; in hwirq_to_bit()
68 void __iomem *addr = priv->base + offset + PIC_REG_IDX(bit) * 4; in pch_pic_bitset()
70 raw_spin_lock(&priv->pic_lock); in pch_pic_bitset()
74 raw_spin_unlock(&priv->pic_lock); in pch_pic_bitset()
80 void __iomem *addr = priv->base + offset + PIC_REG_IDX(bit) * 4; in pch_pic_bitclr()
82 raw_spin_lock(&priv->pic_lock); in pch_pic_bitclr()
86 raw_spin_unlock(&priv->pic_lock); in pch_pic_bitclr()
93 pch_pic_bitset(priv, PCH_PIC_MASK, hwirq_to_bit(priv, d->hwirq)); in pch_pic_mask_irq()
100 int bit = hwirq_to_bit(priv, d->hwirq); in pch_pic_unmask_irq()
103 priv->base + PCH_PIC_CLR + PIC_REG_IDX(bit) * 4); in pch_pic_unmask_irq()
112 int bit = hwirq_to_bit(priv, d->hwirq); in pch_pic_set_type()
137 ret = -EINVAL; in pch_pic_set_type()
148 int bit = hwirq_to_bit(priv, d->hwirq); in pch_pic_ack_irq()
150 reg = readl(priv->base + PCH_PIC_EDGE + PIC_REG_IDX(bit) * 4); in pch_pic_ack_irq()
153 priv->base + PCH_PIC_CLR + PIC_REG_IDX(bit) * 4); in pch_pic_ack_irq()
159 .name = "PCH PIC",
173 struct pch_pic *priv = d->host_data; in pch_pic_domain_translate()
174 struct device_node *of_node = to_of_node(fwspec->fwnode); in pch_pic_domain_translate()
179 if (fwspec->param_count < 2) in pch_pic_domain_translate()
180 return -EINVAL; in pch_pic_domain_translate()
182 *hwirq = fwspec->param[0]; in pch_pic_domain_translate()
183 *type = fwspec->param[1] & IRQ_TYPE_SENSE_MASK; in pch_pic_domain_translate()
185 if (fwspec->param_count < 1) in pch_pic_domain_translate()
186 return -EINVAL; in pch_pic_domain_translate()
188 *hwirq = fwspec->param[0] - priv->gsi_base; in pch_pic_domain_translate()
190 if (fwspec->param_count > 1) in pch_pic_domain_translate()
191 *type = fwspec->param[1] & IRQ_TYPE_SENSE_MASK; in pch_pic_domain_translate()
196 raw_spin_lock_irqsave(&priv->pic_lock, flags); in pch_pic_domain_translate()
197 /* Check pic-table to confirm if the hwirq has been assigned */ in pch_pic_domain_translate()
198 for (i = 0; i < priv->inuse; i++) { in pch_pic_domain_translate()
199 if (priv->table[i] == *hwirq) { in pch_pic_domain_translate()
204 if (i == priv->inuse) { in pch_pic_domain_translate()
205 /* Assign a new hwirq in pic-table */ in pch_pic_domain_translate()
206 if (priv->inuse >= PIC_COUNT) { in pch_pic_domain_translate()
207 pr_err("pch-pic domain has no free vectors\n"); in pch_pic_domain_translate()
208 raw_spin_unlock_irqrestore(&priv->pic_lock, flags); in pch_pic_domain_translate()
209 return -EINVAL; in pch_pic_domain_translate()
211 priv->table[priv->inuse] = *hwirq; in pch_pic_domain_translate()
212 *hwirq = priv->inuse++; in pch_pic_domain_translate()
214 raw_spin_unlock_irqrestore(&priv->pic_lock, flags); in pch_pic_domain_translate()
227 struct pch_pic *priv = domain->host_data; in pch_pic_alloc()
234 writeb(priv->ht_vec_base + hwirq, priv->base + PCH_INT_HTVEC(hwirq_to_bit(priv, hwirq))); in pch_pic_alloc()
236 parent_fwspec.fwnode = domain->parent->fwnode; in pch_pic_alloc()
238 parent_fwspec.param[0] = hwirq + priv->ht_vec_base; in pch_pic_alloc()
264 writeb(priv->ht_vec_base + i, priv->base + PCH_INT_HTVEC(hwirq_to_bit(priv, i))); in pch_pic_reset()
266 writeb(1, priv->base + PCH_INT_ROUTE(i)); in pch_pic_reset()
271 writel_relaxed(0xFFFFFFFF, priv->base + PCH_PIC_MASK + 4 * i); in pch_pic_reset()
272 writel_relaxed(0xFFFFFFFF, priv->base + PCH_PIC_CLR + 4 * i); in pch_pic_reset()
274 writel_relaxed(0, priv->base + PCH_PIC_AUTO0 + 4 * i); in pch_pic_reset()
275 writel_relaxed(0, priv->base + PCH_PIC_AUTO1 + 4 * i); in pch_pic_reset()
277 writel_relaxed(0xFFFFFFFF, priv->base + PCH_PIC_HTMSI_EN + 4 * i); in pch_pic_reset()
287 pch_pic_priv[i]->saved_vec_pol[j] = in pch_pic_suspend()
288 readl(pch_pic_priv[i]->base + PCH_PIC_POL + 4 * j); in pch_pic_suspend()
289 pch_pic_priv[i]->saved_vec_edge[j] = in pch_pic_suspend()
290 readl(pch_pic_priv[i]->base + PCH_PIC_EDGE + 4 * j); in pch_pic_suspend()
291 pch_pic_priv[i]->saved_vec_en[j] = in pch_pic_suspend()
292 readl(pch_pic_priv[i]->base + PCH_PIC_MASK + 4 * j); in pch_pic_suspend()
306 writel(pch_pic_priv[i]->saved_vec_pol[j], in pch_pic_resume()
307 pch_pic_priv[i]->base + PCH_PIC_POL + 4 * j); in pch_pic_resume()
308 writel(pch_pic_priv[i]->saved_vec_edge[j], in pch_pic_resume()
309 pch_pic_priv[i]->base + PCH_PIC_EDGE + 4 * j); in pch_pic_resume()
310 writel(pch_pic_priv[i]->saved_vec_en[j], in pch_pic_resume()
311 pch_pic_priv[i]->base + PCH_PIC_MASK + 4 * j); in pch_pic_resume()
330 return -ENOMEM; in pch_pic_init()
332 raw_spin_lock_init(&priv->pic_lock); in pch_pic_init()
333 priv->base = ioremap(addr, size); in pch_pic_init()
334 if (!priv->base) in pch_pic_init()
337 priv->inuse = 0; in pch_pic_init()
339 priv->table[i] = PIC_UNDEF_VECTOR; in pch_pic_init()
341 priv->ht_vec_base = vec_base; in pch_pic_init()
342 priv->vec_count = ((readq(priv->base) >> 48) & 0xff) + 1; in pch_pic_init()
343 priv->gsi_base = gsi_base; in pch_pic_init()
345 priv->pic_domain = irq_domain_create_hierarchy(parent_domain, 0, in pch_pic_init()
346 priv->vec_count, domain_handle, in pch_pic_init()
349 if (!priv->pic_domain) { in pch_pic_init()
364 iounmap(priv->base); in pch_pic_init()
368 return -EINVAL; in pch_pic_init()
381 return -EINVAL; in pch_pic_of_init()
386 return -ENXIO; in pch_pic_of_init()
389 if (of_property_read_u32(node, "loongson,pic-base-vec", &vec_base)) { in pch_pic_of_init()
390 pr_err("Failed to determine pic-base-vec\n"); in pch_pic_of_init()
391 return -EINVAL; in pch_pic_of_init()
402 IRQCHIP_DECLARE(pch_pic, "loongson,pch-pic-1.0", pch_pic_of_init);
416 return -1; in find_pch_pic()
418 if (gsi >= priv->gsi_base && gsi < (priv->gsi_base + priv->vec_count)) in find_pch_pic()
423 return -1; in find_pch_pic()
431 return pch_lpc_acpi_init(pch_pic_priv[0]->pic_domain, pchlpc_entry); in pch_lpc_parse_madt()
451 if (find_pch_pic(acpi_pchpic->gsi_base) >= 0) in pch_pic_acpi_init()
454 domain_handle = irq_domain_alloc_fwnode(&acpi_pchpic->address); in pch_pic_acpi_init()
457 return -ENOMEM; in pch_pic_acpi_init()
460 ret = pch_pic_init(acpi_pchpic->address, acpi_pchpic->size, in pch_pic_acpi_init()
461 0, parent, domain_handle, acpi_pchpic->gsi_base); in pch_pic_acpi_init()
468 if (acpi_pchpic->id == 0) in pch_pic_acpi_init()