/*
* OMAP DMAengine support
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/delay.h>
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/omap-dma.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/of_dma.h>
#include <linux/of_device.h>
#include "virt-dma.h"
struct omap_dmadev {
struct dma_device ddev;
spinlock_t lock;
struct tasklet_struct task;
struct list_head pending;
void __iomem *base;
const struct omap_dma_reg *reg_map;
struct omap_system_dma_plat_info *plat;
bool legacy;
spinlock_t irq_lock;
uint32_t irq_enable_mask;
struct omap_chan *lch_map[32];
};
struct omap_chan {
struct virt_dma_chan vc;
struct list_head node;
void __iomem *channel_base;
const struct omap_dma_reg *reg_map;
uint32_t ccr;
struct dma_slave_config cfg;
unsigned dma_sig;
bool cyclic;
bool paused;
int dma_ch;
struct omap_desc *desc;
unsigned sgidx;
};
struct omap_sg {
dma_addr_t addr;
uint32_t en; /* number of elements (24-bit) */
uint32_t fn; /* number of frames (16-bit) */
};
struct omap_desc {
struct virt_dma_desc vd;
enum dma_transfer_direction dir;
dma_addr_t dev_addr;
int16_t fi; /* for OMAP_DMA_SYNC_PACKET */
uint8_t es; /* CSDP_DATA_TYPE_xxx */
uint32_t ccr; /* CCR value */
uint16_t clnk_ctrl; /* CLNK_CTRL value */
uint16_t cicr; /* CICR value */
uint32_t csdp; /* CSDP value */
unsigned sglen;
struct omap_sg sg[0];
};
enum {
CCR_FS = BIT(5),
CCR_READ_PRIORITY = BIT(6),
CCR_ENABLE = BIT(7),
CCR_AUTO_INIT = BIT(8), /* OMAP1 only */
CCR_REPEAT = BIT(9), /* OMAP1 only */
CCR_OMAP31_DISABLE = BIT(10), /* OMAP1 only */
CCR_SUSPEND_SENSITIVE = BIT(8), /* OMAP2+ only */
CCR_RD_ACTIVE = BIT(9), /* OMAP2+ only */
CCR_WR_ACTIVE = BIT(10), /* OMAP2+ only */
CCR_SRC_AMODE_CONSTANT = 0 << 12,
CCR_SRC_AMODE_POSTINC = 1 << 12,
CCR_SRC_AMODE_SGLIDX = 2 << 12,
CCR_SRC_AMODE_DBLIDX = 3 << 12,
CCR_DST_AMODE_CONSTANT = 0 << 14,
CCR_DST_AMODE_POSTINC = 1 << 14,
CCR_DST_AMODE_SGLIDX = 2 << 14,
CCR_DST_AMODE_DBLIDX = 3