Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* ebus.c: EBUS DMA library code.
0003  *
0004  * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
0005  * Copyright (C) 1999  David S. Miller (davem@redhat.com)
0006  */
0007 
0008 #include <linux/export.h>
0009 #include <linux/kernel.h>
0010 #include <linux/types.h>
0011 #include <linux/interrupt.h>
0012 #include <linux/delay.h>
0013 
0014 #include <asm/ebus_dma.h>
0015 #include <asm/io.h>
0016 
0017 #define EBDMA_CSR   0x00UL  /* Control/Status */
0018 #define EBDMA_ADDR  0x04UL  /* DMA Address */
0019 #define EBDMA_COUNT 0x08UL  /* DMA Count */
0020 
0021 #define EBDMA_CSR_INT_PEND  0x00000001
0022 #define EBDMA_CSR_ERR_PEND  0x00000002
0023 #define EBDMA_CSR_DRAIN     0x00000004
0024 #define EBDMA_CSR_INT_EN    0x00000010
0025 #define EBDMA_CSR_RESET     0x00000080
0026 #define EBDMA_CSR_WRITE     0x00000100
0027 #define EBDMA_CSR_EN_DMA    0x00000200
0028 #define EBDMA_CSR_CYC_PEND  0x00000400
0029 #define EBDMA_CSR_DIAG_RD_DONE  0x00000800
0030 #define EBDMA_CSR_DIAG_WR_DONE  0x00001000
0031 #define EBDMA_CSR_EN_CNT    0x00002000
0032 #define EBDMA_CSR_TC        0x00004000
0033 #define EBDMA_CSR_DIS_CSR_DRN   0x00010000
0034 #define EBDMA_CSR_BURST_SZ_MASK 0x000c0000
0035 #define EBDMA_CSR_BURST_SZ_1    0x00080000
0036 #define EBDMA_CSR_BURST_SZ_4    0x00000000
0037 #define EBDMA_CSR_BURST_SZ_8    0x00040000
0038 #define EBDMA_CSR_BURST_SZ_16   0x000c0000
0039 #define EBDMA_CSR_DIAG_EN   0x00100000
0040 #define EBDMA_CSR_DIS_ERR_PEND  0x00400000
0041 #define EBDMA_CSR_TCI_DIS   0x00800000
0042 #define EBDMA_CSR_EN_NEXT   0x01000000
0043 #define EBDMA_CSR_DMA_ON    0x02000000
0044 #define EBDMA_CSR_A_LOADED  0x04000000
0045 #define EBDMA_CSR_NA_LOADED 0x08000000
0046 #define EBDMA_CSR_DEV_ID_MASK   0xf0000000
0047 
0048 #define EBUS_DMA_RESET_TIMEOUT  10000
0049 
0050 static void __ebus_dma_reset(struct ebus_dma_info *p, int no_drain)
0051 {
0052     int i;
0053     u32 val = 0;
0054 
0055     writel(EBDMA_CSR_RESET, p->regs + EBDMA_CSR);
0056     udelay(1);
0057 
0058     if (no_drain)
0059         return;
0060 
0061     for (i = EBUS_DMA_RESET_TIMEOUT; i > 0; i--) {
0062         val = readl(p->regs + EBDMA_CSR);
0063 
0064         if (!(val & (EBDMA_CSR_DRAIN | EBDMA_CSR_CYC_PEND)))
0065             break;
0066         udelay(10);
0067     }
0068 }
0069 
0070 static irqreturn_t ebus_dma_irq(int irq, void *dev_id)
0071 {
0072     struct ebus_dma_info *p = dev_id;
0073     unsigned long flags;
0074     u32 csr = 0;
0075 
0076     spin_lock_irqsave(&p->lock, flags);
0077     csr = readl(p->regs + EBDMA_CSR);
0078     writel(csr, p->regs + EBDMA_CSR);
0079     spin_unlock_irqrestore(&p->lock, flags);
0080 
0081     if (csr & EBDMA_CSR_ERR_PEND) {
0082         printk(KERN_CRIT "ebus_dma(%s): DMA error!\n", p->name);
0083         p->callback(p, EBUS_DMA_EVENT_ERROR, p->client_cookie);
0084         return IRQ_HANDLED;
0085     } else if (csr & EBDMA_CSR_INT_PEND) {
0086         p->callback(p,
0087                 (csr & EBDMA_CSR_TC) ?
0088                 EBUS_DMA_EVENT_DMA : EBUS_DMA_EVENT_DEVICE,
0089                 p->client_cookie);
0090         return IRQ_HANDLED;
0091     }
0092 
0093     return IRQ_NONE;
0094 
0095 }
0096 
0097 int ebus_dma_register(struct ebus_dma_info *p)
0098 {
0099     u32 csr;
0100 
0101     if (!p->regs)
0102         return -EINVAL;
0103     if (p->flags & ~(EBUS_DMA_FLAG_USE_EBDMA_HANDLER |
0104              EBUS_DMA_FLAG_TCI_DISABLE))
0105         return -EINVAL;
0106     if ((p->flags & EBUS_DMA_FLAG_USE_EBDMA_HANDLER) && !p->callback)
0107         return -EINVAL;
0108     if (!strlen(p->name))
0109         return -EINVAL;
0110 
0111     __ebus_dma_reset(p, 1);
0112 
0113     csr = EBDMA_CSR_BURST_SZ_16 | EBDMA_CSR_EN_CNT;
0114 
0115     if (p->flags & EBUS_DMA_FLAG_TCI_DISABLE)
0116         csr |= EBDMA_CSR_TCI_DIS;
0117 
0118     writel(csr, p->regs + EBDMA_CSR);
0119 
0120     return 0;
0121 }
0122 EXPORT_SYMBOL(ebus_dma_register);
0123 
0124 int ebus_dma_irq_enable(struct ebus_dma_info *p, int on)
0125 {
0126     unsigned long flags;
0127     u32 csr;
0128 
0129     if (on) {
0130         if (p->flags & EBUS_DMA_FLAG_USE_EBDMA_HANDLER) {
0131             if (request_irq(p->irq, ebus_dma_irq, IRQF_SHARED, p->name, p))
0132                 return -EBUSY;
0133         }
0134 
0135         spin_lock_irqsave(&p->lock, flags);
0136         csr = readl(p->regs + EBDMA_CSR);
0137         csr |= EBDMA_CSR_INT_EN;
0138         writel(csr, p->regs + EBDMA_CSR);
0139         spin_unlock_irqrestore(&p->lock, flags);
0140     } else {
0141         spin_lock_irqsave(&p->lock, flags);
0142         csr = readl(p->regs + EBDMA_CSR);
0143         csr &= ~EBDMA_CSR_INT_EN;
0144         writel(csr, p->regs + EBDMA_CSR);
0145         spin_unlock_irqrestore(&p->lock, flags);
0146 
0147         if (p->flags & EBUS_DMA_FLAG_USE_EBDMA_HANDLER) {
0148             free_irq(p->irq, p);
0149         }
0150     }
0151 
0152     return 0;
0153 }
0154 EXPORT_SYMBOL(ebus_dma_irq_enable);
0155 
0156 void ebus_dma_unregister(struct ebus_dma_info *p)
0157 {
0158     unsigned long flags;
0159     u32 csr;
0160     int irq_on = 0;
0161 
0162     spin_lock_irqsave(&p->lock, flags);
0163     csr = readl(p->regs + EBDMA_CSR);
0164     if (csr & EBDMA_CSR_INT_EN) {
0165         csr &= ~EBDMA_CSR_INT_EN;
0166         writel(csr, p->regs + EBDMA_CSR);
0167         irq_on = 1;
0168     }
0169     spin_unlock_irqrestore(&p->lock, flags);
0170 
0171     if (irq_on)
0172         free_irq(p->irq, p);
0173 }
0174 EXPORT_SYMBOL(ebus_dma_unregister);
0175 
0176 int ebus_dma_request(struct ebus_dma_info *p, dma_addr_t bus_addr, size_t len)
0177 {
0178     unsigned long flags;
0179     u32 csr;
0180     int err;
0181 
0182     if (len >= (1 << 24))
0183         return -EINVAL;
0184 
0185     spin_lock_irqsave(&p->lock, flags);
0186     csr = readl(p->regs + EBDMA_CSR);
0187     err = -EINVAL;
0188     if (!(csr & EBDMA_CSR_EN_DMA))
0189         goto out;
0190     err = -EBUSY;
0191     if (csr & EBDMA_CSR_NA_LOADED)
0192         goto out;
0193 
0194     writel(len,      p->regs + EBDMA_COUNT);
0195     writel(bus_addr, p->regs + EBDMA_ADDR);
0196     err = 0;
0197 
0198 out:
0199     spin_unlock_irqrestore(&p->lock, flags);
0200 
0201     return err;
0202 }
0203 EXPORT_SYMBOL(ebus_dma_request);
0204 
0205 void ebus_dma_prepare(struct ebus_dma_info *p, int write)
0206 {
0207     unsigned long flags;
0208     u32 csr;
0209 
0210     spin_lock_irqsave(&p->lock, flags);
0211     __ebus_dma_reset(p, 0);
0212 
0213     csr = (EBDMA_CSR_INT_EN |
0214            EBDMA_CSR_EN_CNT |
0215            EBDMA_CSR_BURST_SZ_16 |
0216            EBDMA_CSR_EN_NEXT);
0217 
0218     if (write)
0219         csr |= EBDMA_CSR_WRITE;
0220     if (p->flags & EBUS_DMA_FLAG_TCI_DISABLE)
0221         csr |= EBDMA_CSR_TCI_DIS;
0222 
0223     writel(csr, p->regs + EBDMA_CSR);
0224 
0225     spin_unlock_irqrestore(&p->lock, flags);
0226 }
0227 EXPORT_SYMBOL(ebus_dma_prepare);
0228 
0229 unsigned int ebus_dma_residue(struct ebus_dma_info *p)
0230 {
0231     return readl(p->regs + EBDMA_COUNT);
0232 }
0233 EXPORT_SYMBOL(ebus_dma_residue);
0234 
0235 unsigned int ebus_dma_addr(struct ebus_dma_info *p)
0236 {
0237     return readl(p->regs + EBDMA_ADDR);
0238 }
0239 EXPORT_SYMBOL(ebus_dma_addr);
0240 
0241 void ebus_dma_enable(struct ebus_dma_info *p, int on)
0242 {
0243     unsigned long flags;
0244     u32 orig_csr, csr;
0245 
0246     spin_lock_irqsave(&p->lock, flags);
0247     orig_csr = csr = readl(p->regs + EBDMA_CSR);
0248     if (on)
0249         csr |= EBDMA_CSR_EN_DMA;
0250     else
0251         csr &= ~EBDMA_CSR_EN_DMA;
0252     if ((orig_csr & EBDMA_CSR_EN_DMA) !=
0253         (csr & EBDMA_CSR_EN_DMA))
0254         writel(csr, p->regs + EBDMA_CSR);
0255     spin_unlock_irqrestore(&p->lock, flags);
0256 }
0257 EXPORT_SYMBOL(ebus_dma_enable);