Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * linux/arch/arm/plat-omap/dma.c
0004  *
0005  * Copyright (C) 2003 - 2008 Nokia Corporation
0006  * Author: Juha Yrjölä <juha.yrjola@nokia.com>
0007  * DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com>
0008  * Graphics DMA and LCD DMA graphics tranformations
0009  * by Imre Deak <imre.deak@nokia.com>
0010  * OMAP2/3 support Copyright (C) 2004-2007 Texas Instruments, Inc.
0011  * Merged to support both OMAP1 and OMAP2 by Tony Lindgren <tony@atomide.com>
0012  * Some functions based on earlier dma-omap.c Copyright (C) 2001 RidgeRun, Inc.
0013  *
0014  * Copyright (C) 2009 Texas Instruments
0015  * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
0016  *
0017  * Support functions for the OMAP internal DMA channels.
0018  *
0019  * Copyright (C) 2010 Texas Instruments Incorporated - https://www.ti.com/
0020  * Converted DMA library into DMA platform driver.
0021  *  - G, Manjunath Kondaiah <manjugk@ti.com>
0022  */
0023 
0024 #include <linux/module.h>
0025 #include <linux/init.h>
0026 #include <linux/sched.h>
0027 #include <linux/spinlock.h>
0028 #include <linux/errno.h>
0029 #include <linux/interrupt.h>
0030 #include <linux/irq.h>
0031 #include <linux/io.h>
0032 #include <linux/slab.h>
0033 #include <linux/delay.h>
0034 
0035 #include <linux/omap-dma.h>
0036 
0037 #include <linux/soc/ti/omap1-io.h>
0038 #include <linux/soc/ti/omap1-soc.h>
0039 
0040 #include "tc.h"
0041 
0042 /*
0043  * MAX_LOGICAL_DMA_CH_COUNT: the maximum number of logical DMA
0044  * channels that an instance of the SDMA IP block can support.  Used
0045  * to size arrays.  (The actual maximum on a particular SoC may be less
0046  * than this -- for example, OMAP1 SDMA instances only support 17 logical
0047  * DMA channels.)
0048  */
0049 #define MAX_LOGICAL_DMA_CH_COUNT        32
0050 
0051 #undef DEBUG
0052 
0053 #define OMAP_DMA_ACTIVE         0x01
0054 
0055 #define OMAP_FUNC_MUX_ARM_BASE      (0xfffe1000 + 0xec)
0056 
0057 static struct omap_system_dma_plat_info *p;
0058 static struct omap_dma_dev_attr *d;
0059 static int enable_1510_mode;
0060 static u32 errata;
0061 
0062 struct dma_link_info {
0063     int *linked_dmach_q;
0064     int no_of_lchs_linked;
0065 
0066     int q_count;
0067     int q_tail;
0068     int q_head;
0069 
0070     int chain_state;
0071     int chain_mode;
0072 
0073 };
0074 
0075 static int dma_lch_count;
0076 static int dma_chan_count;
0077 static int omap_dma_reserve_channels;
0078 
0079 static DEFINE_SPINLOCK(dma_chan_lock);
0080 static struct omap_dma_lch *dma_chan;
0081 
0082 static inline void omap_disable_channel_irq(int lch)
0083 {
0084     /* disable channel interrupts */
0085     p->dma_write(0, CICR, lch);
0086     /* Clear CSR */
0087     p->dma_read(CSR, lch);
0088 }
0089 
0090 static inline void set_gdma_dev(int req, int dev)
0091 {
0092     u32 reg = OMAP_FUNC_MUX_ARM_BASE + ((req - 1) / 5) * 4;
0093     int shift = ((req - 1) % 5) * 6;
0094     u32 l;
0095 
0096     l = omap_readl(reg);
0097     l &= ~(0x3f << shift);
0098     l |= (dev - 1) << shift;
0099     omap_writel(l, reg);
0100 }
0101 
0102 #if IS_ENABLED(CONFIG_FB_OMAP)
0103 void omap_set_dma_priority(int lch, int dst_port, int priority)
0104 {
0105     unsigned long reg;
0106     u32 l;
0107 
0108     if (dma_omap1()) {
0109         switch (dst_port) {
0110         case OMAP_DMA_PORT_OCP_T1:  /* FFFECC00 */
0111             reg = OMAP_TC_OCPT1_PRIOR;
0112             break;
0113         case OMAP_DMA_PORT_OCP_T2:  /* FFFECCD0 */
0114             reg = OMAP_TC_OCPT2_PRIOR;
0115             break;
0116         case OMAP_DMA_PORT_EMIFF:   /* FFFECC08 */
0117             reg = OMAP_TC_EMIFF_PRIOR;
0118             break;
0119         case OMAP_DMA_PORT_EMIFS:   /* FFFECC04 */
0120             reg = OMAP_TC_EMIFS_PRIOR;
0121             break;
0122         default:
0123             BUG();
0124             return;
0125         }
0126         l = omap_readl(reg);
0127         l &= ~(0xf << 8);
0128         l |= (priority & 0xf) << 8;
0129         omap_writel(l, reg);
0130     }
0131 }
0132 EXPORT_SYMBOL(omap_set_dma_priority);
0133 #endif
0134 
0135 #if IS_ENABLED(CONFIG_USB_OMAP)
0136 #ifdef CONFIG_ARCH_OMAP15XX
0137 /* Returns 1 if the DMA module is in OMAP1510-compatible mode, 0 otherwise */
0138 static int omap_dma_in_1510_mode(void)
0139 {
0140     return enable_1510_mode;
0141 }
0142 #else
0143 #define omap_dma_in_1510_mode()     0
0144 #endif
0145 
0146 void omap_set_dma_transfer_params(int lch, int data_type, int elem_count,
0147                   int frame_count, int sync_mode,
0148                   int dma_trigger, int src_or_dst_synch)
0149 {
0150     u32 l;
0151     u16 ccr;
0152 
0153     l = p->dma_read(CSDP, lch);
0154     l &= ~0x03;
0155     l |= data_type;
0156     p->dma_write(l, CSDP, lch);
0157 
0158     ccr = p->dma_read(CCR, lch);
0159     ccr &= ~(1 << 5);
0160     if (sync_mode == OMAP_DMA_SYNC_FRAME)
0161         ccr |= 1 << 5;
0162     p->dma_write(ccr, CCR, lch);
0163 
0164     ccr = p->dma_read(CCR2, lch);
0165     ccr &= ~(1 << 2);
0166     if (sync_mode == OMAP_DMA_SYNC_BLOCK)
0167         ccr |= 1 << 2;
0168     p->dma_write(ccr, CCR2, lch);
0169     p->dma_write(elem_count, CEN, lch);
0170     p->dma_write(frame_count, CFN, lch);
0171 }
0172 EXPORT_SYMBOL(omap_set_dma_transfer_params);
0173 
0174 void omap_set_dma_channel_mode(int lch, enum omap_dma_channel_mode mode)
0175 {
0176     if (!dma_omap15xx()) {
0177         u32 l;
0178 
0179         l = p->dma_read(LCH_CTRL, lch);
0180         l &= ~0x7;
0181         l |= mode;
0182         p->dma_write(l, LCH_CTRL, lch);
0183     }
0184 }
0185 EXPORT_SYMBOL(omap_set_dma_channel_mode);
0186 
0187 /* Note that src_port is only for omap1 */
0188 void omap_set_dma_src_params(int lch, int src_port, int src_amode,
0189                  unsigned long src_start,
0190                  int src_ei, int src_fi)
0191 {
0192     u32 l;
0193     u16 w;
0194 
0195     w = p->dma_read(CSDP, lch);
0196     w &= ~(0x1f << 2);
0197     w |= src_port << 2;
0198     p->dma_write(w, CSDP, lch);
0199 
0200     l = p->dma_read(CCR, lch);
0201     l &= ~(0x03 << 12);
0202     l |= src_amode << 12;
0203     p->dma_write(l, CCR, lch);
0204 
0205     p->dma_write(src_start, CSSA, lch);
0206 
0207     p->dma_write(src_ei, CSEI, lch);
0208     p->dma_write(src_fi, CSFI, lch);
0209 }
0210 EXPORT_SYMBOL(omap_set_dma_src_params);
0211 
0212 void omap_set_dma_src_data_pack(int lch, int enable)
0213 {
0214     u32 l;
0215 
0216     l = p->dma_read(CSDP, lch);
0217     l &= ~(1 << 6);
0218     if (enable)
0219         l |= (1 << 6);
0220     p->dma_write(l, CSDP, lch);
0221 }
0222 EXPORT_SYMBOL(omap_set_dma_src_data_pack);
0223 
0224 void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
0225 {
0226     unsigned int burst = 0;
0227     u32 l;
0228 
0229     l = p->dma_read(CSDP, lch);
0230     l &= ~(0x03 << 7);
0231 
0232     switch (burst_mode) {
0233     case OMAP_DMA_DATA_BURST_DIS:
0234         break;
0235     case OMAP_DMA_DATA_BURST_4:
0236         burst = 0x2;
0237         break;
0238     case OMAP_DMA_DATA_BURST_8:
0239         /*
0240          * not supported by current hardware on OMAP1
0241          * w |= (0x03 << 7);
0242          */
0243         fallthrough;
0244     case OMAP_DMA_DATA_BURST_16:
0245         /* OMAP1 don't support burst 16 */
0246         fallthrough;
0247     default:
0248         BUG();
0249     }
0250 
0251     l |= (burst << 7);
0252     p->dma_write(l, CSDP, lch);
0253 }
0254 EXPORT_SYMBOL(omap_set_dma_src_burst_mode);
0255 
0256 /* Note that dest_port is only for OMAP1 */
0257 void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode,
0258                   unsigned long dest_start,
0259                   int dst_ei, int dst_fi)
0260 {
0261     u32 l;
0262 
0263     l = p->dma_read(CSDP, lch);
0264     l &= ~(0x1f << 9);
0265     l |= dest_port << 9;
0266     p->dma_write(l, CSDP, lch);
0267 
0268     l = p->dma_read(CCR, lch);
0269     l &= ~(0x03 << 14);
0270     l |= dest_amode << 14;
0271     p->dma_write(l, CCR, lch);
0272 
0273     p->dma_write(dest_start, CDSA, lch);
0274 
0275     p->dma_write(dst_ei, CDEI, lch);
0276     p->dma_write(dst_fi, CDFI, lch);
0277 }
0278 EXPORT_SYMBOL(omap_set_dma_dest_params);
0279 
0280 void omap_set_dma_dest_data_pack(int lch, int enable)
0281 {
0282     u32 l;
0283 
0284     l = p->dma_read(CSDP, lch);
0285     l &= ~(1 << 13);
0286     if (enable)
0287         l |= 1 << 13;
0288     p->dma_write(l, CSDP, lch);
0289 }
0290 EXPORT_SYMBOL(omap_set_dma_dest_data_pack);
0291 
0292 void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
0293 {
0294     unsigned int burst = 0;
0295     u32 l;
0296 
0297     l = p->dma_read(CSDP, lch);
0298     l &= ~(0x03 << 14);
0299 
0300     switch (burst_mode) {
0301     case OMAP_DMA_DATA_BURST_DIS:
0302         break;
0303     case OMAP_DMA_DATA_BURST_4:
0304         burst = 0x2;
0305         break;
0306     case OMAP_DMA_DATA_BURST_8:
0307         burst = 0x3;
0308         break;
0309     case OMAP_DMA_DATA_BURST_16:
0310         /* OMAP1 don't support burst 16 */
0311         fallthrough;
0312     default:
0313         printk(KERN_ERR "Invalid DMA burst mode\n");
0314         BUG();
0315         return;
0316     }
0317     l |= (burst << 14);
0318     p->dma_write(l, CSDP, lch);
0319 }
0320 EXPORT_SYMBOL(omap_set_dma_dest_burst_mode);
0321 
0322 static inline void omap_enable_channel_irq(int lch)
0323 {
0324     /* Clear CSR */
0325     p->dma_read(CSR, lch);
0326 
0327     /* Enable some nice interrupts. */
0328     p->dma_write(dma_chan[lch].enabled_irqs, CICR, lch);
0329 }
0330 
0331 void omap_disable_dma_irq(int lch, u16 bits)
0332 {
0333     dma_chan[lch].enabled_irqs &= ~bits;
0334 }
0335 EXPORT_SYMBOL(omap_disable_dma_irq);
0336 
0337 static inline void enable_lnk(int lch)
0338 {
0339     u32 l;
0340 
0341     l = p->dma_read(CLNK_CTRL, lch);
0342 
0343     l &= ~(1 << 14);
0344 
0345     /* Set the ENABLE_LNK bits */
0346     if (dma_chan[lch].next_lch != -1)
0347         l = dma_chan[lch].next_lch | (1 << 15);
0348 
0349     p->dma_write(l, CLNK_CTRL, lch);
0350 }
0351 
0352 static inline void disable_lnk(int lch)
0353 {
0354     u32 l;
0355 
0356     l = p->dma_read(CLNK_CTRL, lch);
0357 
0358     /* Disable interrupts */
0359     omap_disable_channel_irq(lch);
0360 
0361     /* Set the STOP_LNK bit */
0362     l |= 1 << 14;
0363 
0364     p->dma_write(l, CLNK_CTRL, lch);
0365     dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
0366 }
0367 #endif
0368 
0369 int omap_request_dma(int dev_id, const char *dev_name,
0370              void (*callback)(int lch, u16 ch_status, void *data),
0371              void *data, int *dma_ch_out)
0372 {
0373     int ch, free_ch = -1;
0374     unsigned long flags;
0375     struct omap_dma_lch *chan;
0376 
0377     WARN(strcmp(dev_name, "DMA engine"), "Using deprecated platform DMA API - please update to DMA engine");
0378 
0379     spin_lock_irqsave(&dma_chan_lock, flags);
0380     for (ch = 0; ch < dma_chan_count; ch++) {
0381         if (free_ch == -1 && dma_chan[ch].dev_id == -1) {
0382             free_ch = ch;
0383             /* Exit after first free channel found */
0384             break;
0385         }
0386     }
0387     if (free_ch == -1) {
0388         spin_unlock_irqrestore(&dma_chan_lock, flags);
0389         return -EBUSY;
0390     }
0391     chan = dma_chan + free_ch;
0392     chan->dev_id = dev_id;
0393 
0394     if (p->clear_lch_regs)
0395         p->clear_lch_regs(free_ch);
0396 
0397     spin_unlock_irqrestore(&dma_chan_lock, flags);
0398 
0399     chan->dev_name = dev_name;
0400     chan->callback = callback;
0401     chan->data = data;
0402     chan->flags = 0;
0403 
0404     chan->enabled_irqs = OMAP_DMA_DROP_IRQ | OMAP_DMA_BLOCK_IRQ;
0405 
0406     chan->enabled_irqs |= OMAP1_DMA_TOUT_IRQ;
0407 
0408     if (dma_omap16xx()) {
0409         /* If the sync device is set, configure it dynamically. */
0410         if (dev_id != 0) {
0411             set_gdma_dev(free_ch + 1, dev_id);
0412             dev_id = free_ch + 1;
0413         }
0414         /*
0415          * Disable the 1510 compatibility mode and set the sync device
0416          * id.
0417          */
0418         p->dma_write(dev_id | (1 << 10), CCR, free_ch);
0419     } else {
0420         p->dma_write(dev_id, CCR, free_ch);
0421     }
0422 
0423     *dma_ch_out = free_ch;
0424 
0425     return 0;
0426 }
0427 EXPORT_SYMBOL(omap_request_dma);
0428 
0429 void omap_free_dma(int lch)
0430 {
0431     unsigned long flags;
0432 
0433     if (dma_chan[lch].dev_id == -1) {
0434         pr_err("omap_dma: trying to free unallocated DMA channel %d\n",
0435                lch);
0436         return;
0437     }
0438 
0439     /* Disable all DMA interrupts for the channel. */
0440     omap_disable_channel_irq(lch);
0441 
0442     /* Make sure the DMA transfer is stopped. */
0443     p->dma_write(0, CCR, lch);
0444 
0445     spin_lock_irqsave(&dma_chan_lock, flags);
0446     dma_chan[lch].dev_id = -1;
0447     dma_chan[lch].next_lch = -1;
0448     dma_chan[lch].callback = NULL;
0449     spin_unlock_irqrestore(&dma_chan_lock, flags);
0450 }
0451 EXPORT_SYMBOL(omap_free_dma);
0452 
0453 /*
0454  * Clears any DMA state so the DMA engine is ready to restart with new buffers
0455  * through omap_start_dma(). Any buffers in flight are discarded.
0456  */
0457 static void omap_clear_dma(int lch)
0458 {
0459     unsigned long flags;
0460 
0461     local_irq_save(flags);
0462     p->clear_dma(lch);
0463     local_irq_restore(flags);
0464 }
0465 
0466 #if IS_ENABLED(CONFIG_USB_OMAP)
0467 void omap_start_dma(int lch)
0468 {
0469     u32 l;
0470 
0471     /*
0472      * The CPC/CDAC register needs to be initialized to zero
0473      * before starting dma transfer.
0474      */
0475     if (dma_omap15xx())
0476         p->dma_write(0, CPC, lch);
0477     else
0478         p->dma_write(0, CDAC, lch);
0479 
0480     if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
0481         int next_lch, cur_lch;
0482         char dma_chan_link_map[MAX_LOGICAL_DMA_CH_COUNT];
0483 
0484         /* Set the link register of the first channel */
0485         enable_lnk(lch);
0486 
0487         memset(dma_chan_link_map, 0, sizeof(dma_chan_link_map));
0488         dma_chan_link_map[lch] = 1;
0489 
0490         cur_lch = dma_chan[lch].next_lch;
0491         do {
0492             next_lch = dma_chan[cur_lch].next_lch;
0493 
0494             /* The loop case: we've been here already */
0495             if (dma_chan_link_map[cur_lch])
0496                 break;
0497             /* Mark the current channel */
0498             dma_chan_link_map[cur_lch] = 1;
0499 
0500             enable_lnk(cur_lch);
0501             omap_enable_channel_irq(cur_lch);
0502 
0503             cur_lch = next_lch;
0504         } while (next_lch != -1);
0505     } else if (IS_DMA_ERRATA(DMA_ERRATA_PARALLEL_CHANNELS))
0506         p->dma_write(lch, CLNK_CTRL, lch);
0507 
0508     omap_enable_channel_irq(lch);
0509 
0510     l = p->dma_read(CCR, lch);
0511 
0512     if (IS_DMA_ERRATA(DMA_ERRATA_IFRAME_BUFFERING))
0513             l |= OMAP_DMA_CCR_BUFFERING_DISABLE;
0514     l |= OMAP_DMA_CCR_EN;
0515 
0516     /*
0517      * As dma_write() uses IO accessors which are weakly ordered, there
0518      * is no guarantee that data in coherent DMA memory will be visible
0519      * to the DMA device.  Add a memory barrier here to ensure that any
0520      * such data is visible prior to enabling DMA.
0521      */
0522     mb();
0523     p->dma_write(l, CCR, lch);
0524 
0525     dma_chan[lch].flags |= OMAP_DMA_ACTIVE;
0526 }
0527 EXPORT_SYMBOL(omap_start_dma);
0528 
0529 void omap_stop_dma(int lch)
0530 {
0531     u32 l;
0532 
0533     /* Disable all interrupts on the channel */
0534     omap_disable_channel_irq(lch);
0535 
0536     l = p->dma_read(CCR, lch);
0537     if (IS_DMA_ERRATA(DMA_ERRATA_i541) &&
0538             (l & OMAP_DMA_CCR_SEL_SRC_DST_SYNC)) {
0539         int i = 0;
0540         u32 sys_cf;
0541 
0542         /* Configure No-Standby */
0543         l = p->dma_read(OCP_SYSCONFIG, lch);
0544         sys_cf = l;
0545         l &= ~DMA_SYSCONFIG_MIDLEMODE_MASK;
0546         l |= DMA_SYSCONFIG_MIDLEMODE(DMA_IDLEMODE_NO_IDLE);
0547         p->dma_write(l , OCP_SYSCONFIG, 0);
0548 
0549         l = p->dma_read(CCR, lch);
0550         l &= ~OMAP_DMA_CCR_EN;
0551         p->dma_write(l, CCR, lch);
0552 
0553         /* Wait for sDMA FIFO drain */
0554         l = p->dma_read(CCR, lch);
0555         while (i < 100 && (l & (OMAP_DMA_CCR_RD_ACTIVE |
0556                     OMAP_DMA_CCR_WR_ACTIVE))) {
0557             udelay(5);
0558             i++;
0559             l = p->dma_read(CCR, lch);
0560         }
0561         if (i >= 100)
0562             pr_err("DMA drain did not complete on lch %d\n", lch);
0563         /* Restore OCP_SYSCONFIG */
0564         p->dma_write(sys_cf, OCP_SYSCONFIG, lch);
0565     } else {
0566         l &= ~OMAP_DMA_CCR_EN;
0567         p->dma_write(l, CCR, lch);
0568     }
0569 
0570     /*
0571      * Ensure that data transferred by DMA is visible to any access
0572      * after DMA has been disabled.  This is important for coherent
0573      * DMA regions.
0574      */
0575     mb();
0576 
0577     if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
0578         int next_lch, cur_lch = lch;
0579         char dma_chan_link_map[MAX_LOGICAL_DMA_CH_COUNT];
0580 
0581         memset(dma_chan_link_map, 0, sizeof(dma_chan_link_map));
0582         do {
0583             /* The loop case: we've been here already */
0584             if (dma_chan_link_map[cur_lch])
0585                 break;
0586             /* Mark the current channel */
0587             dma_chan_link_map[cur_lch] = 1;
0588 
0589             disable_lnk(cur_lch);
0590 
0591             next_lch = dma_chan[cur_lch].next_lch;
0592             cur_lch = next_lch;
0593         } while (next_lch != -1);
0594     }
0595 
0596     dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
0597 }
0598 EXPORT_SYMBOL(omap_stop_dma);
0599 
0600 /*
0601  * Allows changing the DMA callback function or data. This may be needed if
0602  * the driver shares a single DMA channel for multiple dma triggers.
0603  */
0604 /*
0605  * Returns current physical source address for the given DMA channel.
0606  * If the channel is running the caller must disable interrupts prior calling
0607  * this function and process the returned value before re-enabling interrupt to
0608  * prevent races with the interrupt handler. Note that in continuous mode there
0609  * is a chance for CSSA_L register overflow between the two reads resulting
0610  * in incorrect return value.
0611  */
0612 dma_addr_t omap_get_dma_src_pos(int lch)
0613 {
0614     dma_addr_t offset = 0;
0615 
0616     if (dma_omap15xx())
0617         offset = p->dma_read(CPC, lch);
0618     else
0619         offset = p->dma_read(CSAC, lch);
0620 
0621     if (IS_DMA_ERRATA(DMA_ERRATA_3_3) && offset == 0)
0622         offset = p->dma_read(CSAC, lch);
0623 
0624     if (!dma_omap15xx()) {
0625         /*
0626          * CDAC == 0 indicates that the DMA transfer on the channel has
0627          * not been started (no data has been transferred so far).
0628          * Return the programmed source start address in this case.
0629          */
0630         if (likely(p->dma_read(CDAC, lch)))
0631             offset = p->dma_read(CSAC, lch);
0632         else
0633             offset = p->dma_read(CSSA, lch);
0634     }
0635 
0636     offset |= (p->dma_read(CSSA, lch) & 0xFFFF0000);
0637 
0638     return offset;
0639 }
0640 EXPORT_SYMBOL(omap_get_dma_src_pos);
0641 
0642 /*
0643  * Returns current physical destination address for the given DMA channel.
0644  * If the channel is running the caller must disable interrupts prior calling
0645  * this function and process the returned value before re-enabling interrupt to
0646  * prevent races with the interrupt handler. Note that in continuous mode there
0647  * is a chance for CDSA_L register overflow between the two reads resulting
0648  * in incorrect return value.
0649  */
0650 dma_addr_t omap_get_dma_dst_pos(int lch)
0651 {
0652     dma_addr_t offset = 0;
0653 
0654     if (dma_omap15xx())
0655         offset = p->dma_read(CPC, lch);
0656     else
0657         offset = p->dma_read(CDAC, lch);
0658 
0659     /*
0660      * omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is
0661      * read before the DMA controller finished disabling the channel.
0662      */
0663     if (!dma_omap15xx() && offset == 0) {
0664         offset = p->dma_read(CDAC, lch);
0665         /*
0666          * CDAC == 0 indicates that the DMA transfer on the channel has
0667          * not been started (no data has been transferred so far).
0668          * Return the programmed destination start address in this case.
0669          */
0670         if (unlikely(!offset))
0671             offset = p->dma_read(CDSA, lch);
0672     }
0673 
0674     offset |= (p->dma_read(CDSA, lch) & 0xFFFF0000);
0675 
0676     return offset;
0677 }
0678 EXPORT_SYMBOL(omap_get_dma_dst_pos);
0679 
0680 int omap_get_dma_active_status(int lch)
0681 {
0682     return (p->dma_read(CCR, lch) & OMAP_DMA_CCR_EN) != 0;
0683 }
0684 EXPORT_SYMBOL(omap_get_dma_active_status);
0685 #endif
0686 
0687 int omap_dma_running(void)
0688 {
0689     int lch;
0690 
0691     if (omap_lcd_dma_running())
0692         return 1;
0693 
0694     for (lch = 0; lch < dma_chan_count; lch++)
0695         if (p->dma_read(CCR, lch) & OMAP_DMA_CCR_EN)
0696             return 1;
0697 
0698     return 0;
0699 }
0700 
0701 /*----------------------------------------------------------------------------*/
0702 
0703 static int omap1_dma_handle_ch(int ch)
0704 {
0705     u32 csr;
0706 
0707     if (enable_1510_mode && ch >= 6) {
0708         csr = dma_chan[ch].saved_csr;
0709         dma_chan[ch].saved_csr = 0;
0710     } else
0711         csr = p->dma_read(CSR, ch);
0712     if (enable_1510_mode && ch <= 2 && (csr >> 7) != 0) {
0713         dma_chan[ch + 6].saved_csr = csr >> 7;
0714         csr &= 0x7f;
0715     }
0716     if ((csr & 0x3f) == 0)
0717         return 0;
0718     if (unlikely(dma_chan[ch].dev_id == -1)) {
0719         pr_warn("Spurious interrupt from DMA channel %d (CSR %04x)\n",
0720             ch, csr);
0721         return 0;
0722     }
0723     if (unlikely(csr & OMAP1_DMA_TOUT_IRQ))
0724         pr_warn("DMA timeout with device %d\n", dma_chan[ch].dev_id);
0725     if (unlikely(csr & OMAP_DMA_DROP_IRQ))
0726         pr_warn("DMA synchronization event drop occurred with device %d\n",
0727             dma_chan[ch].dev_id);
0728     if (likely(csr & OMAP_DMA_BLOCK_IRQ))
0729         dma_chan[ch].flags &= ~OMAP_DMA_ACTIVE;
0730     if (likely(dma_chan[ch].callback != NULL))
0731         dma_chan[ch].callback(ch, csr, dma_chan[ch].data);
0732 
0733     return 1;
0734 }
0735 
0736 static irqreturn_t omap1_dma_irq_handler(int irq, void *dev_id)
0737 {
0738     int ch = ((int) dev_id) - 1;
0739     int handled = 0;
0740 
0741     for (;;) {
0742         int handled_now = 0;
0743 
0744         handled_now += omap1_dma_handle_ch(ch);
0745         if (enable_1510_mode && dma_chan[ch + 6].saved_csr)
0746             handled_now += omap1_dma_handle_ch(ch + 6);
0747         if (!handled_now)
0748             break;
0749         handled += handled_now;
0750     }
0751 
0752     return handled ? IRQ_HANDLED : IRQ_NONE;
0753 }
0754 
0755 struct omap_system_dma_plat_info *omap_get_plat_info(void)
0756 {
0757     return p;
0758 }
0759 EXPORT_SYMBOL_GPL(omap_get_plat_info);
0760 
0761 static int omap_system_dma_probe(struct platform_device *pdev)
0762 {
0763     int ch, ret = 0;
0764     int dma_irq;
0765     char irq_name[4];
0766 
0767     p = pdev->dev.platform_data;
0768     if (!p) {
0769         dev_err(&pdev->dev,
0770             "%s: System DMA initialized without platform data\n",
0771             __func__);
0772         return -EINVAL;
0773     }
0774 
0775     d           = p->dma_attr;
0776     errata          = p->errata;
0777 
0778     if ((d->dev_caps & RESERVE_CHANNEL) && omap_dma_reserve_channels
0779             && (omap_dma_reserve_channels < d->lch_count))
0780         d->lch_count    = omap_dma_reserve_channels;
0781 
0782     dma_lch_count       = d->lch_count;
0783     dma_chan_count      = dma_lch_count;
0784     enable_1510_mode    = d->dev_caps & ENABLE_1510_MODE;
0785 
0786     dma_chan = devm_kcalloc(&pdev->dev, dma_lch_count,
0787                 sizeof(*dma_chan), GFP_KERNEL);
0788     if (!dma_chan)
0789         return -ENOMEM;
0790 
0791     for (ch = 0; ch < dma_chan_count; ch++) {
0792         omap_clear_dma(ch);
0793 
0794         dma_chan[ch].dev_id = -1;
0795         dma_chan[ch].next_lch = -1;
0796 
0797         if (ch >= 6 && enable_1510_mode)
0798             continue;
0799 
0800         /*
0801          * request_irq() doesn't like dev_id (ie. ch) being
0802          * zero, so we have to kludge around this.
0803          */
0804         sprintf(&irq_name[0], "%d", ch);
0805         dma_irq = platform_get_irq_byname(pdev, irq_name);
0806 
0807         if (dma_irq < 0) {
0808             ret = dma_irq;
0809             goto exit_dma_irq_fail;
0810         }
0811 
0812         /* INT_DMA_LCD is handled in lcd_dma.c */
0813         if (dma_irq == INT_DMA_LCD)
0814             continue;
0815 
0816         ret = request_irq(dma_irq,
0817                 omap1_dma_irq_handler, 0, "DMA",
0818                 (void *) (ch + 1));
0819         if (ret != 0)
0820             goto exit_dma_irq_fail;
0821     }
0822 
0823     /* reserve dma channels 0 and 1 in high security devices on 34xx */
0824     if (d->dev_caps & HS_CHANNELS_RESERVED) {
0825         pr_info("Reserving DMA channels 0 and 1 for HS ROM code\n");
0826         dma_chan[0].dev_id = 0;
0827         dma_chan[1].dev_id = 1;
0828     }
0829     p->show_dma_caps();
0830     return 0;
0831 
0832 exit_dma_irq_fail:
0833     return ret;
0834 }
0835 
0836 static int omap_system_dma_remove(struct platform_device *pdev)
0837 {
0838     int dma_irq, irq_rel = 0;
0839 
0840     for ( ; irq_rel < dma_chan_count; irq_rel++) {
0841         dma_irq = platform_get_irq(pdev, irq_rel);
0842         free_irq(dma_irq, (void *)(irq_rel + 1));
0843     }
0844 
0845     return 0;
0846 }
0847 
0848 static struct platform_driver omap_system_dma_driver = {
0849     .probe      = omap_system_dma_probe,
0850     .remove     = omap_system_dma_remove,
0851     .driver     = {
0852         .name   = "omap_dma_system"
0853     },
0854 };
0855 
0856 static int __init omap_system_dma_init(void)
0857 {
0858     return platform_driver_register(&omap_system_dma_driver);
0859 }
0860 arch_initcall(omap_system_dma_init);
0861 
0862 static void __exit omap_system_dma_exit(void)
0863 {
0864     platform_driver_unregister(&omap_system_dma_driver);
0865 }
0866 
0867 MODULE_DESCRIPTION("OMAP SYSTEM DMA DRIVER");
0868 MODULE_LICENSE("GPL");
0869 MODULE_AUTHOR("Texas Instruments Inc");
0870 
0871 /*
0872  * Reserve the omap SDMA channels using cmdline bootarg
0873  * "omap_dma_reserve_ch=". The valid range is 1 to 32
0874  */
0875 static int __init omap_dma_cmdline_reserve_ch(char *str)
0876 {
0877     if (get_option(&str, &omap_dma_reserve_channels) != 1)
0878         omap_dma_reserve_channels = 0;
0879     return 1;
0880 }
0881 
0882 __setup("omap_dma_reserve_ch=", omap_dma_cmdline_reserve_ch);
0883 
0884