Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * IMG PowerDown Controller (PDC)
0004  *
0005  * Copyright 2010-2013 Imagination Technologies Ltd.
0006  *
0007  * Exposes the syswake and PDC peripheral wake interrupts to the system.
0008  *
0009  */
0010 
0011 #include <linux/bitops.h>
0012 #include <linux/interrupt.h>
0013 #include <linux/irqdomain.h>
0014 #include <linux/io.h>
0015 #include <linux/kernel.h>
0016 #include <linux/of.h>
0017 #include <linux/platform_device.h>
0018 #include <linux/spinlock.h>
0019 
0020 /* PDC interrupt register numbers */
0021 
0022 #define PDC_IRQ_STATUS          0x310
0023 #define PDC_IRQ_ENABLE          0x314
0024 #define PDC_IRQ_CLEAR           0x318
0025 #define PDC_IRQ_ROUTE           0x31c
0026 #define PDC_SYS_WAKE_BASE       0x330
0027 #define PDC_SYS_WAKE_STRIDE     0x8
0028 #define PDC_SYS_WAKE_CONFIG_BASE    0x334
0029 #define PDC_SYS_WAKE_CONFIG_STRIDE  0x8
0030 
0031 /* PDC interrupt register field masks */
0032 
0033 #define PDC_IRQ_SYS3            0x08
0034 #define PDC_IRQ_SYS2            0x04
0035 #define PDC_IRQ_SYS1            0x02
0036 #define PDC_IRQ_SYS0            0x01
0037 #define PDC_IRQ_ROUTE_WU_EN_SYS3    0x08000000
0038 #define PDC_IRQ_ROUTE_WU_EN_SYS2    0x04000000
0039 #define PDC_IRQ_ROUTE_WU_EN_SYS1    0x02000000
0040 #define PDC_IRQ_ROUTE_WU_EN_SYS0    0x01000000
0041 #define PDC_IRQ_ROUTE_WU_EN_WD      0x00040000
0042 #define PDC_IRQ_ROUTE_WU_EN_IR      0x00020000
0043 #define PDC_IRQ_ROUTE_WU_EN_RTC     0x00010000
0044 #define PDC_IRQ_ROUTE_EXT_EN_SYS3   0x00000800
0045 #define PDC_IRQ_ROUTE_EXT_EN_SYS2   0x00000400
0046 #define PDC_IRQ_ROUTE_EXT_EN_SYS1   0x00000200
0047 #define PDC_IRQ_ROUTE_EXT_EN_SYS0   0x00000100
0048 #define PDC_IRQ_ROUTE_EXT_EN_WD     0x00000004
0049 #define PDC_IRQ_ROUTE_EXT_EN_IR     0x00000002
0050 #define PDC_IRQ_ROUTE_EXT_EN_RTC    0x00000001
0051 #define PDC_SYS_WAKE_RESET      0x00000010
0052 #define PDC_SYS_WAKE_INT_MODE       0x0000000e
0053 #define PDC_SYS_WAKE_INT_MODE_SHIFT 1
0054 #define PDC_SYS_WAKE_PIN_VAL        0x00000001
0055 
0056 /* PDC interrupt constants */
0057 
0058 #define PDC_SYS_WAKE_INT_LOW        0x0
0059 #define PDC_SYS_WAKE_INT_HIGH       0x1
0060 #define PDC_SYS_WAKE_INT_DOWN       0x2
0061 #define PDC_SYS_WAKE_INT_UP     0x3
0062 #define PDC_SYS_WAKE_INT_CHANGE     0x6
0063 #define PDC_SYS_WAKE_INT_NONE       0x4
0064 
0065 /**
0066  * struct pdc_intc_priv - private pdc interrupt data.
0067  * @nr_perips:      Number of peripheral interrupt signals.
0068  * @nr_syswakes:    Number of syswake signals.
0069  * @perip_irqs:     List of peripheral IRQ numbers handled.
0070  * @syswake_irq:    Shared PDC syswake IRQ number.
0071  * @domain:     IRQ domain for PDC peripheral and syswake IRQs.
0072  * @pdc_base:       Base of PDC registers.
0073  * @irq_route:      Cached version of PDC_IRQ_ROUTE register.
0074  * @lock:       Lock to protect the PDC syswake registers and the cached
0075  *          values of those registers in this struct.
0076  */
0077 struct pdc_intc_priv {
0078     unsigned int        nr_perips;
0079     unsigned int        nr_syswakes;
0080     unsigned int        *perip_irqs;
0081     unsigned int        syswake_irq;
0082     struct irq_domain   *domain;
0083     void __iomem        *pdc_base;
0084 
0085     u32         irq_route;
0086     raw_spinlock_t      lock;
0087 };
0088 
0089 static void pdc_write(struct pdc_intc_priv *priv, unsigned int reg_offs,
0090               unsigned int data)
0091 {
0092     iowrite32(data, priv->pdc_base + reg_offs);
0093 }
0094 
0095 static unsigned int pdc_read(struct pdc_intc_priv *priv,
0096                  unsigned int reg_offs)
0097 {
0098     return ioread32(priv->pdc_base + reg_offs);
0099 }
0100 
0101 /* Generic IRQ callbacks */
0102 
0103 #define SYS0_HWIRQ  8
0104 
0105 static unsigned int hwirq_is_syswake(irq_hw_number_t hw)
0106 {
0107     return hw >= SYS0_HWIRQ;
0108 }
0109 
0110 static unsigned int hwirq_to_syswake(irq_hw_number_t hw)
0111 {
0112     return hw - SYS0_HWIRQ;
0113 }
0114 
0115 static irq_hw_number_t syswake_to_hwirq(unsigned int syswake)
0116 {
0117     return SYS0_HWIRQ + syswake;
0118 }
0119 
0120 static struct pdc_intc_priv *irqd_to_priv(struct irq_data *data)
0121 {
0122     return (struct pdc_intc_priv *)data->domain->host_data;
0123 }
0124 
0125 /*
0126  * perip_irq_mask() and perip_irq_unmask() use IRQ_ROUTE which also contains
0127  * wake bits, therefore we cannot use the generic irqchip mask callbacks as they
0128  * cache the mask.
0129  */
0130 
0131 static void perip_irq_mask(struct irq_data *data)
0132 {
0133     struct pdc_intc_priv *priv = irqd_to_priv(data);
0134 
0135     raw_spin_lock(&priv->lock);
0136     priv->irq_route &= ~data->mask;
0137     pdc_write(priv, PDC_IRQ_ROUTE, priv->irq_route);
0138     raw_spin_unlock(&priv->lock);
0139 }
0140 
0141 static void perip_irq_unmask(struct irq_data *data)
0142 {
0143     struct pdc_intc_priv *priv = irqd_to_priv(data);
0144 
0145     raw_spin_lock(&priv->lock);
0146     priv->irq_route |= data->mask;
0147     pdc_write(priv, PDC_IRQ_ROUTE, priv->irq_route);
0148     raw_spin_unlock(&priv->lock);
0149 }
0150 
0151 static int syswake_irq_set_type(struct irq_data *data, unsigned int flow_type)
0152 {
0153     struct pdc_intc_priv *priv = irqd_to_priv(data);
0154     unsigned int syswake = hwirq_to_syswake(data->hwirq);
0155     unsigned int irq_mode;
0156     unsigned int soc_sys_wake_regoff, soc_sys_wake;
0157 
0158     /* translate to syswake IRQ mode */
0159     switch (flow_type) {
0160     case IRQ_TYPE_EDGE_BOTH:
0161         irq_mode = PDC_SYS_WAKE_INT_CHANGE;
0162         break;
0163     case IRQ_TYPE_EDGE_RISING:
0164         irq_mode = PDC_SYS_WAKE_INT_UP;
0165         break;
0166     case IRQ_TYPE_EDGE_FALLING:
0167         irq_mode = PDC_SYS_WAKE_INT_DOWN;
0168         break;
0169     case IRQ_TYPE_LEVEL_HIGH:
0170         irq_mode = PDC_SYS_WAKE_INT_HIGH;
0171         break;
0172     case IRQ_TYPE_LEVEL_LOW:
0173         irq_mode = PDC_SYS_WAKE_INT_LOW;
0174         break;
0175     default:
0176         return -EINVAL;
0177     }
0178 
0179     raw_spin_lock(&priv->lock);
0180 
0181     /* set the IRQ mode */
0182     soc_sys_wake_regoff = PDC_SYS_WAKE_BASE + syswake*PDC_SYS_WAKE_STRIDE;
0183     soc_sys_wake = pdc_read(priv, soc_sys_wake_regoff);
0184     soc_sys_wake &= ~PDC_SYS_WAKE_INT_MODE;
0185     soc_sys_wake |= irq_mode << PDC_SYS_WAKE_INT_MODE_SHIFT;
0186     pdc_write(priv, soc_sys_wake_regoff, soc_sys_wake);
0187 
0188     /* and update the handler */
0189     irq_setup_alt_chip(data, flow_type);
0190 
0191     raw_spin_unlock(&priv->lock);
0192 
0193     return 0;
0194 }
0195 
0196 /* applies to both peripheral and syswake interrupts */
0197 static int pdc_irq_set_wake(struct irq_data *data, unsigned int on)
0198 {
0199     struct pdc_intc_priv *priv = irqd_to_priv(data);
0200     irq_hw_number_t hw = data->hwirq;
0201     unsigned int mask = (1 << 16) << hw;
0202     unsigned int dst_irq;
0203 
0204     raw_spin_lock(&priv->lock);
0205     if (on)
0206         priv->irq_route |= mask;
0207     else
0208         priv->irq_route &= ~mask;
0209     pdc_write(priv, PDC_IRQ_ROUTE, priv->irq_route);
0210     raw_spin_unlock(&priv->lock);
0211 
0212     /* control the destination IRQ wakeup too for standby mode */
0213     if (hwirq_is_syswake(hw))
0214         dst_irq = priv->syswake_irq;
0215     else
0216         dst_irq = priv->perip_irqs[hw];
0217     irq_set_irq_wake(dst_irq, on);
0218 
0219     return 0;
0220 }
0221 
0222 static void pdc_intc_perip_isr(struct irq_desc *desc)
0223 {
0224     unsigned int irq = irq_desc_get_irq(desc);
0225     struct pdc_intc_priv *priv;
0226     unsigned int i;
0227 
0228     priv = (struct pdc_intc_priv *)irq_desc_get_handler_data(desc);
0229 
0230     /* find the peripheral number */
0231     for (i = 0; i < priv->nr_perips; ++i)
0232         if (irq == priv->perip_irqs[i])
0233             goto found;
0234 
0235     /* should never get here */
0236     return;
0237 found:
0238 
0239     /* pass on the interrupt */
0240     generic_handle_domain_irq(priv->domain, i);
0241 }
0242 
0243 static void pdc_intc_syswake_isr(struct irq_desc *desc)
0244 {
0245     struct pdc_intc_priv *priv;
0246     unsigned int syswake;
0247     unsigned int status;
0248 
0249     priv = (struct pdc_intc_priv *)irq_desc_get_handler_data(desc);
0250 
0251     status = pdc_read(priv, PDC_IRQ_STATUS) &
0252          pdc_read(priv, PDC_IRQ_ENABLE);
0253     status &= (1 << priv->nr_syswakes) - 1;
0254 
0255     for (syswake = 0; status; status >>= 1, ++syswake) {
0256         /* Has this sys_wake triggered? */
0257         if (!(status & 1))
0258             continue;
0259 
0260         generic_handle_domain_irq(priv->domain, syswake_to_hwirq(syswake));
0261     }
0262 }
0263 
0264 static void pdc_intc_setup(struct pdc_intc_priv *priv)
0265 {
0266     int i;
0267     unsigned int soc_sys_wake_regoff;
0268     unsigned int soc_sys_wake;
0269 
0270     /*
0271      * Mask all syswake interrupts before routing, or we could receive an
0272      * interrupt before we're ready to handle it.
0273      */
0274     pdc_write(priv, PDC_IRQ_ENABLE, 0);
0275 
0276     /*
0277      * Enable routing of all syswakes
0278      * Disable all wake sources
0279      */
0280     priv->irq_route = ((PDC_IRQ_ROUTE_EXT_EN_SYS0 << priv->nr_syswakes) -
0281                 PDC_IRQ_ROUTE_EXT_EN_SYS0);
0282     pdc_write(priv, PDC_IRQ_ROUTE, priv->irq_route);
0283 
0284     /* Initialise syswake IRQ */
0285     for (i = 0; i < priv->nr_syswakes; ++i) {
0286         /* set the IRQ mode to none */
0287         soc_sys_wake_regoff = PDC_SYS_WAKE_BASE + i*PDC_SYS_WAKE_STRIDE;
0288         soc_sys_wake = PDC_SYS_WAKE_INT_NONE
0289                 << PDC_SYS_WAKE_INT_MODE_SHIFT;
0290         pdc_write(priv, soc_sys_wake_regoff, soc_sys_wake);
0291     }
0292 }
0293 
0294 static int pdc_intc_probe(struct platform_device *pdev)
0295 {
0296     struct pdc_intc_priv *priv;
0297     struct device_node *node = pdev->dev.of_node;
0298     struct resource *res_regs;
0299     struct irq_chip_generic *gc;
0300     unsigned int i;
0301     int irq, ret;
0302     u32 val;
0303 
0304     if (!node)
0305         return -ENOENT;
0306 
0307     /* Get registers */
0308     res_regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0309     if (res_regs == NULL) {
0310         dev_err(&pdev->dev, "cannot find registers resource\n");
0311         return -ENOENT;
0312     }
0313 
0314     /* Allocate driver data */
0315     priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
0316     if (!priv)
0317         return -ENOMEM;
0318     raw_spin_lock_init(&priv->lock);
0319     platform_set_drvdata(pdev, priv);
0320 
0321     /* Ioremap the registers */
0322     priv->pdc_base = devm_ioremap(&pdev->dev, res_regs->start,
0323                       resource_size(res_regs));
0324     if (!priv->pdc_base)
0325         return -EIO;
0326 
0327     /* Get number of peripherals */
0328     ret = of_property_read_u32(node, "num-perips", &val);
0329     if (ret) {
0330         dev_err(&pdev->dev, "No num-perips node property found\n");
0331         return -EINVAL;
0332     }
0333     if (val > SYS0_HWIRQ) {
0334         dev_err(&pdev->dev, "num-perips (%u) out of range\n", val);
0335         return -EINVAL;
0336     }
0337     priv->nr_perips = val;
0338 
0339     /* Get number of syswakes */
0340     ret = of_property_read_u32(node, "num-syswakes", &val);
0341     if (ret) {
0342         dev_err(&pdev->dev, "No num-syswakes node property found\n");
0343         return -EINVAL;
0344     }
0345     if (val > SYS0_HWIRQ) {
0346         dev_err(&pdev->dev, "num-syswakes (%u) out of range\n", val);
0347         return -EINVAL;
0348     }
0349     priv->nr_syswakes = val;
0350 
0351     /* Get peripheral IRQ numbers */
0352     priv->perip_irqs = devm_kcalloc(&pdev->dev, 4, priv->nr_perips,
0353                     GFP_KERNEL);
0354     if (!priv->perip_irqs)
0355         return -ENOMEM;
0356     for (i = 0; i < priv->nr_perips; ++i) {
0357         irq = platform_get_irq(pdev, 1 + i);
0358         if (irq < 0)
0359             return irq;
0360         priv->perip_irqs[i] = irq;
0361     }
0362     /* check if too many were provided */
0363     if (platform_get_irq(pdev, 1 + i) >= 0) {
0364         dev_err(&pdev->dev, "surplus perip IRQs detected\n");
0365         return -EINVAL;
0366     }
0367 
0368     /* Get syswake IRQ number */
0369     irq = platform_get_irq(pdev, 0);
0370     if (irq < 0)
0371         return irq;
0372     priv->syswake_irq = irq;
0373 
0374     /* Set up an IRQ domain */
0375     priv->domain = irq_domain_add_linear(node, 16, &irq_generic_chip_ops,
0376                          priv);
0377     if (unlikely(!priv->domain)) {
0378         dev_err(&pdev->dev, "cannot add IRQ domain\n");
0379         return -ENOMEM;
0380     }
0381 
0382     /*
0383      * Set up 2 generic irq chips with 2 chip types.
0384      * The first one for peripheral irqs (only 1 chip type used)
0385      * The second one for syswake irqs (edge and level chip types)
0386      */
0387     ret = irq_alloc_domain_generic_chips(priv->domain, 8, 2, "pdc",
0388                          handle_level_irq, 0, 0,
0389                          IRQ_GC_INIT_NESTED_LOCK);
0390     if (ret)
0391         goto err_generic;
0392 
0393     /* peripheral interrupt chip */
0394 
0395     gc = irq_get_domain_generic_chip(priv->domain, 0);
0396     gc->unused  = ~(BIT(priv->nr_perips) - 1);
0397     gc->reg_base    = priv->pdc_base;
0398     /*
0399      * IRQ_ROUTE contains wake bits, so we can't use the generic versions as
0400      * they cache the mask
0401      */
0402     gc->chip_types[0].regs.mask     = PDC_IRQ_ROUTE;
0403     gc->chip_types[0].chip.irq_mask     = perip_irq_mask;
0404     gc->chip_types[0].chip.irq_unmask   = perip_irq_unmask;
0405     gc->chip_types[0].chip.irq_set_wake = pdc_irq_set_wake;
0406 
0407     /* syswake interrupt chip */
0408 
0409     gc = irq_get_domain_generic_chip(priv->domain, 8);
0410     gc->unused  = ~(BIT(priv->nr_syswakes) - 1);
0411     gc->reg_base    = priv->pdc_base;
0412 
0413     /* edge interrupts */
0414     gc->chip_types[0].type          = IRQ_TYPE_EDGE_BOTH;
0415     gc->chip_types[0].handler       = handle_edge_irq;
0416     gc->chip_types[0].regs.ack      = PDC_IRQ_CLEAR;
0417     gc->chip_types[0].regs.mask     = PDC_IRQ_ENABLE;
0418     gc->chip_types[0].chip.irq_ack      = irq_gc_ack_set_bit;
0419     gc->chip_types[0].chip.irq_mask     = irq_gc_mask_clr_bit;
0420     gc->chip_types[0].chip.irq_unmask   = irq_gc_mask_set_bit;
0421     gc->chip_types[0].chip.irq_set_type = syswake_irq_set_type;
0422     gc->chip_types[0].chip.irq_set_wake = pdc_irq_set_wake;
0423     /* for standby we pass on to the shared syswake IRQ */
0424     gc->chip_types[0].chip.flags        = IRQCHIP_MASK_ON_SUSPEND;
0425 
0426     /* level interrupts */
0427     gc->chip_types[1].type          = IRQ_TYPE_LEVEL_MASK;
0428     gc->chip_types[1].handler       = handle_level_irq;
0429     gc->chip_types[1].regs.ack      = PDC_IRQ_CLEAR;
0430     gc->chip_types[1].regs.mask     = PDC_IRQ_ENABLE;
0431     gc->chip_types[1].chip.irq_ack      = irq_gc_ack_set_bit;
0432     gc->chip_types[1].chip.irq_mask     = irq_gc_mask_clr_bit;
0433     gc->chip_types[1].chip.irq_unmask   = irq_gc_mask_set_bit;
0434     gc->chip_types[1].chip.irq_set_type = syswake_irq_set_type;
0435     gc->chip_types[1].chip.irq_set_wake = pdc_irq_set_wake;
0436     /* for standby we pass on to the shared syswake IRQ */
0437     gc->chip_types[1].chip.flags        = IRQCHIP_MASK_ON_SUSPEND;
0438 
0439     /* Set up the hardware to enable interrupt routing */
0440     pdc_intc_setup(priv);
0441 
0442     /* Setup chained handlers for the peripheral IRQs */
0443     for (i = 0; i < priv->nr_perips; ++i) {
0444         irq = priv->perip_irqs[i];
0445         irq_set_chained_handler_and_data(irq, pdc_intc_perip_isr,
0446                          priv);
0447     }
0448 
0449     /* Setup chained handler for the syswake IRQ */
0450     irq_set_chained_handler_and_data(priv->syswake_irq,
0451                      pdc_intc_syswake_isr, priv);
0452 
0453     dev_info(&pdev->dev,
0454          "PDC IRQ controller initialised (%u perip IRQs, %u syswake IRQs)\n",
0455          priv->nr_perips,
0456          priv->nr_syswakes);
0457 
0458     return 0;
0459 err_generic:
0460     irq_domain_remove(priv->domain);
0461     return ret;
0462 }
0463 
0464 static int pdc_intc_remove(struct platform_device *pdev)
0465 {
0466     struct pdc_intc_priv *priv = platform_get_drvdata(pdev);
0467 
0468     irq_domain_remove(priv->domain);
0469     return 0;
0470 }
0471 
0472 static const struct of_device_id pdc_intc_match[] = {
0473     { .compatible = "img,pdc-intc" },
0474     {}
0475 };
0476 
0477 static struct platform_driver pdc_intc_driver = {
0478     .driver = {
0479         .name       = "pdc-intc",
0480         .of_match_table = pdc_intc_match,
0481     },
0482     .probe = pdc_intc_probe,
0483     .remove = pdc_intc_remove,
0484 };
0485 
0486 static int __init pdc_intc_init(void)
0487 {
0488     return platform_driver_register(&pdc_intc_driver);
0489 }
0490 core_initcall(pdc_intc_init);