mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 12:17:12 +09:00
add dma irq mode
This commit is contained in:
@@ -51,6 +51,13 @@
|
||||
#define DMA_AUTOINIT 0x10
|
||||
|
||||
|
||||
/*
|
||||
* The DMA irq modes
|
||||
*/
|
||||
#define DMA_IRQ_DELAY_MODE 0x00 /*performan in software irq handleer*/
|
||||
#define DMA_IRQ_RIGHTNOW_MODE 0x01 /*performan in dwdma irq handleer*/
|
||||
|
||||
|
||||
/* Request a DMA channel
|
||||
*
|
||||
* Some architectures may need to do allocate an interrupt
|
||||
@@ -96,10 +103,8 @@ extern void set_dma_sg(unsigned int chan, struct scatterlist *sg, int nr_sg);
|
||||
* DMA address immediately, but defer it to the enable_dma().
|
||||
*/
|
||||
extern void __set_dma_addr(unsigned int chan, void *addr);
|
||||
#define set_dma_addr(chan, addr) \
|
||||
__set_dma_addr(chan, addr)
|
||||
//__set_dma_addr(chan, bus_to_virt(addr))
|
||||
|
||||
|
||||
#define set_dma_addr(chan, addr) __set_dma_addr(chan, addr)//__set_dma_addr(chan, bus_to_virt(addr))
|
||||
|
||||
/* Set the DMA byte count for this channel
|
||||
*
|
||||
@@ -132,7 +137,12 @@ extern int get_dma_residue(unsigned int chan);
|
||||
#endif
|
||||
/* Set dam irq callback that perform when dma transfer has completed
|
||||
*/
|
||||
extern void set_dma_handler (unsigned int chan, void (*irq_handler) (int, void *), void *data);
|
||||
extern void set_dma_handler (unsigned int chan, void (*irq_handler) (int, void *), void *data, unsigned int irq_mode);
|
||||
|
||||
|
||||
/*
|
||||
* get dma transfer position
|
||||
*/
|
||||
extern void get_dma_position(unsigned int chan, dma_addr_t *src_pos, dma_addr_t *dst_pos);
|
||||
|
||||
extern int dma_getposition(unsigned int channel, dma_addr_t *src, dma_addr_t *dst);
|
||||
#endif /* __ASM_ARM_DMA_H */
|
||||
|
||||
@@ -19,6 +19,7 @@ struct dma_ops {
|
||||
int (*free)(unsigned int, dma_t *); /* optional */
|
||||
int (*enable)(unsigned int, dma_t *); /* mandatory */
|
||||
int (*disable)(unsigned int, dma_t *); /* mandatory */
|
||||
void (*position)(unsigned int, dma_t *);
|
||||
#if 0
|
||||
int (*residue)(unsigned int, dma_t *); /* optional */
|
||||
int (*setspeed)(unsigned int, dma_t *, int); /* optional */
|
||||
@@ -42,8 +43,12 @@ struct dma_struct {
|
||||
unsigned int lock; /* Device is allocated */
|
||||
const char *device_id; /* Device name */
|
||||
|
||||
int (*irqHandle)(int irq, void *dev_id); /*irq callback*/
|
||||
void (*irqHandle)(int irq, void *dev_id); /*irq callback*/
|
||||
void *data;
|
||||
unsigned int irq_mode;
|
||||
|
||||
dma_addr_t src_pos;
|
||||
dma_addr_t dst_pos;
|
||||
|
||||
const struct dma_ops *d_ops;
|
||||
};
|
||||
|
||||
@@ -126,7 +126,7 @@ EXPORT_SYMBOL(free_dma);
|
||||
*
|
||||
* Copy irq handler to the structure
|
||||
*/
|
||||
void set_dma_handler (unsigned int chan, void (*irq_handler) (int, void *), void *data)
|
||||
void set_dma_handler (unsigned int chan, void (*irq_handler) (int, void *), void *data, unsigned int irq_mode)
|
||||
{
|
||||
dma_t *dma = dma_channel(chan);
|
||||
|
||||
@@ -136,6 +136,7 @@ EXPORT_SYMBOL(free_dma);
|
||||
|
||||
dma->irqHandle = irq_handler;
|
||||
dma->data = data;
|
||||
dma->irq_mode = irq_mode;
|
||||
}
|
||||
EXPORT_SYMBOL(set_dma_handler);
|
||||
|
||||
@@ -264,6 +265,26 @@ int dma_channel_active(unsigned int chan)
|
||||
dma_t *dma = dma_channel(chan);
|
||||
return dma->active;
|
||||
}
|
||||
|
||||
/*
|
||||
* get dma transfer position
|
||||
*/
|
||||
void get_dma_position(unsigned int chan, dma_addr_t *src_pos, dma_addr_t *dst_pos)
|
||||
{
|
||||
dma_t *dma = dma_channel(chan);
|
||||
|
||||
if (dma->d_ops->position)
|
||||
dma->d_ops->position(chan, dma);
|
||||
|
||||
if (src_pos) {
|
||||
*src_pos = dma->src_pos;
|
||||
}
|
||||
|
||||
if (dst_pos) {
|
||||
*dst_pos = dma->dst_pos;
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(dma_channel_active);
|
||||
#if 0
|
||||
void set_dma_page(unsigned int chan, char pagenr)
|
||||
|
||||
@@ -130,7 +130,7 @@ const static struct rk28_dma_dev rk28_dev_info[] = {
|
||||
* rk28_dma_ctl_for_write - set dma control register for writing mode
|
||||
*
|
||||
*/
|
||||
static inline unsigned int rk28_dma_ctl_for_write(unsigned int dma_ch, struct rk28_dma_dev *dev_info, dma_t *dma_t)
|
||||
static inline unsigned int rk28_dma_ctl_for_write(unsigned int dma_ch, const struct rk28_dma_dev *dev_info, dma_t *dma_t)
|
||||
{
|
||||
#ifdef test_dma
|
||||
unsigned int dev_mode = B_CTLL_MEM2MEM_DMAC;
|
||||
@@ -155,7 +155,7 @@ static inline unsigned int rk28_dma_ctl_for_write(unsigned int dma_ch, struct rk
|
||||
* rk28_dma_ctl_for_read - set dma control register for reading mode
|
||||
*
|
||||
*/
|
||||
static inline unsigned int rk28_dma_ctl_for_read(unsigned int dma_ch, struct rk28_dma_dev *dev_info, dma_t *dma_t)
|
||||
static inline unsigned int rk28_dma_ctl_for_read(unsigned int dma_ch, const struct rk28_dma_dev *dev_info, dma_t *dma_t)
|
||||
{
|
||||
#ifdef test_dma
|
||||
unsigned int dev_mode = B_CTLL_MEM2MEM_DMAC;
|
||||
@@ -246,7 +246,7 @@ static void rk28_dma_write_to_sg(unsigned int dma_ch, dma_t *dma_t)
|
||||
struct rk28_dma_llp * rk28llp_phy;
|
||||
struct rk28_dma_llp rk28dma_reg;
|
||||
struct scatterlist *sg;
|
||||
unsigned int wid_off;
|
||||
unsigned int wid_off, bk_count, bk_res, sgcount_tmp, bk_length;
|
||||
|
||||
rk28dma = &rk2818_dma[dma_ch];
|
||||
|
||||
@@ -258,16 +258,36 @@ static void rk28_dma_write_to_sg(unsigned int dma_ch, dma_t *dma_t)
|
||||
rk28llp_vir = rk28dma->dma_llp_vir;
|
||||
rk28llp_phy = (struct rk28_dma_llp *)rk28dma->dma_llp_phy;
|
||||
sg = dma_t->sg;
|
||||
#if 1
|
||||
bk_length = RK28_DMA_CH0A1_MAX_LEN << wid_off;
|
||||
|
||||
for (sgcount_tmp = 0; sgcount_tmp < dma_t->sgcount; sgcount_tmp++, sg++) {
|
||||
bk_count = (sg->length >> wid_off) / RK28_DMA_CH0A1_MAX_LEN;
|
||||
bk_res = (sg->length >> wid_off) % RK28_DMA_CH0A1_MAX_LEN;
|
||||
for (i = 0; i < bk_count; i++) {
|
||||
rk28_dma_set_llp(dev_addr_w,
|
||||
sg->dma_address + i * bk_length,
|
||||
rk28llp_vir++,
|
||||
++rk28llp_phy,
|
||||
ctll_r,
|
||||
RK28_DMA_CH0A1_MAX_LEN);
|
||||
}
|
||||
if (bk_res > 0) {
|
||||
rk28_dma_set_llp(dev_addr_w,
|
||||
sg->dma_address + bk_count * bk_length,
|
||||
rk28llp_vir++,
|
||||
++rk28llp_phy,
|
||||
ctll_r,
|
||||
bk_res);
|
||||
}
|
||||
}
|
||||
#else
|
||||
for (i = 0; i < dma_t->sgcount; i++, sg++) {
|
||||
rk28_dma_set_llp(dev_addr_w, sg->dma_address, rk28llp_vir++, ++rk28llp_phy, ctll_r, (sg->length >> wid_off));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
rk28_dma_end_of_llp(rk28llp_vir - 1);
|
||||
|
||||
rk28dma_reg.sar = 0;//dev_addr_w;
|
||||
rk28dma_reg.dar = 0;//dma_t->sg->dma_address;
|
||||
rk28dma_reg.ctll = ctll_r;
|
||||
rk28dma_reg.llp = (struct rk28_dma_llp *)rk28dma->dma_llp_phy;
|
||||
rk28dma_reg.size = 0;//dma_t->sg->length;
|
||||
} else { /*single transfer*/
|
||||
if (dma_t->buf.length > RK28_DMA_CH2_MAX_LEN) {
|
||||
rk28dma->length = RK28_DMA_CH2_MAX_LEN;
|
||||
@@ -276,12 +296,12 @@ static void rk28_dma_write_to_sg(unsigned int dma_ch, dma_t *dma_t)
|
||||
rk28dma->length = dma_t->buf.length;
|
||||
rk28dma->residue = 0;
|
||||
}
|
||||
rk28dma_reg.sar = dev_addr_w;
|
||||
rk28dma_reg.dar = dma_t->buf.dma_address;
|
||||
rk28dma_reg.ctll = ctll_r;
|
||||
rk28dma_reg.llp = NULL;
|
||||
rk28dma_reg.size = rk28dma->length;
|
||||
}
|
||||
rk28dma_reg.sar = dev_addr_w;
|
||||
rk28dma_reg.dar = dma_t->buf.dma_address;
|
||||
rk28dma_reg.ctll = ctll_r;
|
||||
rk28dma_reg.size = rk28dma->length;
|
||||
rk28_dma_set_reg(dma_ch, &rk28dma_reg, rk28dma->dev_info->hd_if_r);
|
||||
/*
|
||||
printk(KERN_INFO "dma_write_to_sg: ch = %d, sar = 0x%x, dar = 0x%x, ctll = 0x%x, llp = 0x%x, size = %d, \n",
|
||||
@@ -316,10 +336,10 @@ static void rk28_dma_read_from_sg(unsigned int dma_ch, dma_t *dma_t)
|
||||
struct rk28_dma_llp * rk28llp_phy;
|
||||
struct rk28_dma_llp rk28dma_reg;
|
||||
struct scatterlist *sg;
|
||||
unsigned int wid_off;
|
||||
unsigned int wid_off, bk_count, bk_res, sgcount_tmp, bk_length;
|
||||
|
||||
rk28dma = &rk2818_dma[dma_ch];
|
||||
|
||||
|
||||
/*setup linked list table end*/
|
||||
dev_addr_r = rk28dma->dev_info->dev_addr_r;
|
||||
ctll_w = rk28_dma_ctl_for_write(dma_ch, rk28dma->dev_info, dma_t);
|
||||
@@ -329,16 +349,36 @@ static void rk28_dma_read_from_sg(unsigned int dma_ch, dma_t *dma_t)
|
||||
rk28llp_vir = rk28dma->dma_llp_vir;
|
||||
rk28llp_phy = (struct rk28_dma_llp *)rk28dma->dma_llp_phy;
|
||||
sg = dma_t->sg;
|
||||
#if 1
|
||||
bk_length = RK28_DMA_CH0A1_MAX_LEN << wid_off;
|
||||
|
||||
for (sgcount_tmp = 0; sgcount_tmp < dma_t->sgcount; sgcount_tmp++, sg++) {
|
||||
bk_count = (sg->length >> wid_off) / RK28_DMA_CH0A1_MAX_LEN;
|
||||
bk_res = (sg->length >> wid_off) % RK28_DMA_CH0A1_MAX_LEN;
|
||||
for (i = 0; i < bk_count; i++) {
|
||||
rk28_dma_set_llp(sg->dma_address + i * bk_length,
|
||||
dev_addr_r,
|
||||
rk28llp_vir++,
|
||||
++rk28llp_phy,
|
||||
ctll_w,
|
||||
RK28_DMA_CH0A1_MAX_LEN);
|
||||
}
|
||||
if (bk_res > 0) {
|
||||
rk28_dma_set_llp(sg->dma_address + bk_count * bk_length,
|
||||
dev_addr_r,
|
||||
rk28llp_vir++,
|
||||
++rk28llp_phy,
|
||||
ctll_w,
|
||||
bk_res);
|
||||
}
|
||||
}
|
||||
#else
|
||||
for (i = 0; i < dma_t->sgcount; i++, sg++) {
|
||||
rk28_dma_set_llp(sg->dma_address, dev_addr_r, rk28llp_vir++, ++rk28llp_phy, ctll_w, (sg->length >> wid_off));
|
||||
}
|
||||
#endif
|
||||
rk28_dma_end_of_llp(rk28llp_vir - 1);
|
||||
|
||||
rk28dma_reg.sar = 0;//dma_t->sg->dma_address;
|
||||
rk28dma_reg.dar = 0;//dev_addr_r;
|
||||
rk28dma_reg.ctll = ctll_w;
|
||||
rk28dma_reg.llp = (struct rk28_dma_llp *)rk28dma->dma_llp_phy;
|
||||
rk28dma_reg.size = 0;//dma_t->sg->length;
|
||||
} else { /*single transfer*/
|
||||
if (dma_t->buf.length > RK28_DMA_CH2_MAX_LEN) {
|
||||
rk28dma->length = RK28_DMA_CH2_MAX_LEN;
|
||||
@@ -347,12 +387,12 @@ static void rk28_dma_read_from_sg(unsigned int dma_ch, dma_t *dma_t)
|
||||
rk28dma->length = dma_t->buf.length;
|
||||
rk28dma->residue = 0;
|
||||
}
|
||||
rk28dma_reg.sar = dma_t->buf.dma_address;
|
||||
rk28dma_reg.dar = dev_addr_r;
|
||||
rk28dma_reg.ctll = ctll_w;
|
||||
rk28dma_reg.llp = NULL;
|
||||
rk28dma_reg.size = rk28dma->length;
|
||||
}
|
||||
rk28dma_reg.sar = dma_t->buf.dma_address;
|
||||
rk28dma_reg.dar = dev_addr_r;
|
||||
rk28dma_reg.ctll = ctll_w;
|
||||
rk28dma_reg.size = rk28dma->length;
|
||||
rk28_dma_set_reg(dma_ch, &rk28dma_reg, rk28dma->dev_info->hd_if_w);
|
||||
|
||||
//printk(KERN_INFO "read_from_sg: ch = %d, sar = 0x%x, dar = 0x%x, ctll = 0x%x, llp = 0x%x, size = %d, \n",
|
||||
@@ -430,6 +470,8 @@ static int rk28_dma_disable(unsigned int dma_ch, dma_t *dma_t)
|
||||
while (GET_DWDMA_STATUS(dma_ch))
|
||||
cpu_relax();
|
||||
|
||||
rk28dma->tasklet_flag = 0;
|
||||
|
||||
spin_unlock(&rk28dma->lock);
|
||||
|
||||
return 0;
|
||||
@@ -471,13 +513,15 @@ static int rk28_dma_request(unsigned int dma_ch, dma_t *dma_t)
|
||||
}
|
||||
} else {
|
||||
rk28dma->dma_llp_vir = NULL;
|
||||
rk28dma->dma_llp_phy = NULL;
|
||||
rk28dma->dma_llp_phy = 0;
|
||||
}
|
||||
|
||||
rk28dma->dev_info = &rk28_dev_info[i];
|
||||
|
||||
/* clear interrupt */
|
||||
CLR_DWDMA_INTR(dma_ch);
|
||||
|
||||
UN_MASK_DWDMA_TRF_INTR(dma_ch);
|
||||
|
||||
spin_unlock(&rk28dma->lock);
|
||||
|
||||
@@ -500,6 +544,8 @@ static int rk28_dma_free(unsigned int dma_ch, dma_t *dma_t)
|
||||
|
||||
/* clear interrupt */
|
||||
CLR_DWDMA_INTR(dma_ch);
|
||||
|
||||
MASK_DWDMA_TRF_INTR(dma_ch);
|
||||
|
||||
if (dma_ch < RK28_DMA_CH2) {
|
||||
if (!rk28dma->dma_llp_vir) {
|
||||
@@ -515,7 +561,7 @@ static int rk28_dma_free(unsigned int dma_ch, dma_t *dma_t)
|
||||
rk28dma->dma_t.addr = NULL;
|
||||
rk28dma->dma_t.count = 0;
|
||||
rk28dma->dma_llp_vir = NULL;
|
||||
rk28dma->dma_llp_phy = NULL;
|
||||
rk28dma->dma_llp_phy = 0;
|
||||
rk28dma->residue = 0;
|
||||
rk28dma->length = 0;
|
||||
|
||||
@@ -580,6 +626,27 @@ static int rk28_dma_next(unsigned int dma_ch)
|
||||
*
|
||||
*/
|
||||
static void rk28_dma_tasklet(unsigned long data)
|
||||
{
|
||||
int i;
|
||||
struct rk2818_dma *rk28dma;
|
||||
|
||||
for (i = 0; i < MAX_DMA_CHANNELS; i++) {
|
||||
rk28dma = &rk2818_dma[i];
|
||||
if ((rk28dma->tasklet_flag) && (rk28dma->dma_t.irq_mode == DMA_IRQ_DELAY_MODE)) {
|
||||
rk28dma->dma_t.active = 0;
|
||||
rk28dma->tasklet_flag = 0;
|
||||
if (rk28dma->dma_t.irqHandle)
|
||||
rk28dma->dma_t.irqHandle(i, rk28dma->dma_t.data);
|
||||
UN_MASK_DWDMA_TRF_INTR(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* rk28_dma_irq_handler - irq callback function
|
||||
*
|
||||
*/
|
||||
static irqreturn_t rk28_dma_irq_handler(int irq, void *dev_id)
|
||||
{
|
||||
int i, raw_status;
|
||||
struct rk2818_dma *rk28dma;
|
||||
@@ -596,58 +663,42 @@ static void rk28_dma_tasklet(unsigned long data)
|
||||
//printk(KERN_WARNING "dma_irq: don't finish for channel %d\n", i);
|
||||
continue;
|
||||
}
|
||||
/* already complete transfer */
|
||||
rk28dma->dma_t.active = 0;
|
||||
|
||||
|
||||
if (rk28dma->dma_t.irqHandle) {
|
||||
void *data = rk28dma->dma_t.data;
|
||||
rk28dma->dma_t.irqHandle(i, data);
|
||||
if (rk28dma->dma_t.irq_mode != DMA_IRQ_DELAY_MODE) {
|
||||
/* already have completed transfer */
|
||||
rk28dma->dma_t.active = 0;
|
||||
rk28dma->dma_t.irqHandle(i, rk28dma->dma_t.data);
|
||||
} else {
|
||||
MASK_DWDMA_TRF_INTR(i);
|
||||
rk28dma->tasklet_flag = 1;
|
||||
tasklet_schedule(&rk2818_dma_tasklet);
|
||||
//printk(KERN_WARNING "dma_irq: no IRQ handler for DMA channel %d\n", i);
|
||||
}
|
||||
} else {
|
||||
printk(KERN_WARNING "dma_irq: no IRQ handler for DMA channel %d\n", i);
|
||||
}
|
||||
/* already have completed transfer */
|
||||
rk28dma->dma_t.active = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Re-enable interrupts
|
||||
*/
|
||||
UN_MASK_DWDMA_ALL_TRF_INTR;
|
||||
}
|
||||
|
||||
/**
|
||||
* rk28_dma_irq_handler - irq callback function
|
||||
*
|
||||
*/
|
||||
static irqreturn_t rk28_dma_irq_handler(int irq, void *dev_id)
|
||||
{
|
||||
/*
|
||||
* Just disable the interrupts. We'll turn them back on in the
|
||||
* softirq handler.
|
||||
*/
|
||||
MASK_DWDMA_ALL_TRF_INTR;
|
||||
|
||||
tasklet_schedule(&rk2818_dma_tasklet);
|
||||
//tasklet_schedule(&rk2818_dma_tasklet);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
||||
int dma_getposition(unsigned int channel, dma_addr_t *src, dma_addr_t *dst)
|
||||
static void rk28_dma_position(unsigned int dma_ch, dma_t *dma_t)
|
||||
{
|
||||
u32 phy_ch = channel;
|
||||
if (src != NULL)
|
||||
*src = read_dma_reg(DWDMA_SAR(phy_ch));
|
||||
if (dst != NULL)
|
||||
*dst = read_dma_reg(DWDMA_DAR(phy_ch));
|
||||
|
||||
return 0;
|
||||
dma_t->src_pos = read_dma_reg(DWDMA_SAR(dma_ch));
|
||||
dma_t->dst_pos = read_dma_reg(DWDMA_DAR(dma_ch));
|
||||
}
|
||||
EXPORT_SYMBOL(dma_getposition);
|
||||
|
||||
static struct dma_ops rk2818_dma_ops = {
|
||||
.request = rk28_dma_request,
|
||||
.free = rk28_dma_free,
|
||||
.enable = rk28_dma_enable,
|
||||
.disable = rk28_dma_disable,
|
||||
.position = rk28_dma_position,
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -671,9 +722,10 @@ static int __init rk28_dma_init(void)
|
||||
dma_add(i, &rk2818_dma[i].dma_t);
|
||||
|
||||
rk2818_dma[i].dma_llp_vir = NULL;
|
||||
rk2818_dma[i].dma_llp_phy = NULL;
|
||||
rk2818_dma[i].dma_llp_phy = 0;
|
||||
rk2818_dma[i].residue = 0;
|
||||
rk2818_dma[i].length = 0;
|
||||
rk2818_dma[i].tasklet_flag = 0;
|
||||
}
|
||||
|
||||
/* clear all interrupts */
|
||||
@@ -690,7 +742,8 @@ static int __init rk28_dma_init(void)
|
||||
write_dma_reg(DWDMA_MaskErr, 0x3f00);
|
||||
|
||||
/*unmask transfer completion interrupt*/
|
||||
UN_MASK_DWDMA_ALL_TRF_INTR;
|
||||
//UN_MASK_DWDMA_ALL_TRF_INTR;
|
||||
MASK_DWDMA_ALL_TRF_INTR;
|
||||
|
||||
ret = request_irq(RK28_DMA_IRQ_NUM, rk28_dma_irq_handler, 0, "DMA", NULL);
|
||||
if (ret < 0) {
|
||||
@@ -698,7 +751,7 @@ static int __init rk28_dma_init(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
tasklet_init(&rk2818_dma_tasklet, rk28_dma_tasklet, NULL);
|
||||
tasklet_init(&rk2818_dma_tasklet, rk28_dma_tasklet, 0);
|
||||
|
||||
/* enable DMA module */
|
||||
write_dma_reg(DWDMA_DmaCfgReg, 0x01);
|
||||
|
||||
@@ -151,9 +151,11 @@
|
||||
|
||||
/* Unmask interrupt */
|
||||
#define UN_MASK_DWDMA_ALL_TRF_INTR write_dma_reg(DWDMA_MaskTfr, 0x3f3f)//mask_dma_reg(DWDMA_MaskTfr, 0x101<<dma_ch, 0x101<<dma_ch)
|
||||
#define UN_MASK_DWDMA_TRF_INTR(dma_ch) mask_dma_reg(DWDMA_MaskTfr, 0x101<<dma_ch, 0x101<<dma_ch)
|
||||
|
||||
/* Mask interrupt */
|
||||
#define MASK_DWDMA_ALL_TRF_INTR write_dma_reg(DWDMA_MaskTfr, 0x3f00)//mask_dma_reg(DWDMA_MaskTfr, 0x101<<dma_ch, 0x100<<dma_ch)
|
||||
#define MASK_DWDMA_TRF_INTR(dma_ch) mask_dma_reg(DWDMA_MaskTfr, 0x101<<dma_ch, 0x100<<dma_ch)
|
||||
|
||||
/* Enable channel */
|
||||
#define ENABLE_DWDMA(dma_ch) mask_dma_reg(DWDMA_ChEnReg, 0x101<<dma_ch, 0x101<<dma_ch)
|
||||
@@ -197,11 +199,12 @@ struct rk28_dma_dev {
|
||||
|
||||
struct rk2818_dma {
|
||||
dma_t dma_t;
|
||||
struct rk28_dma_dev *dev_info;/* basic address of sg in memory */
|
||||
const struct rk28_dma_dev *dev_info;/* basic address of sg in memory */
|
||||
struct rk28_dma_llp *dma_llp_vir; /* virtual cpu addrress of linked list */
|
||||
unsigned int dma_llp_phy; /* physical bus address of linked list */
|
||||
unsigned int length; /* current transfer block */
|
||||
unsigned int residue; /* residue block of current dma transfer */
|
||||
unsigned int tasklet_flag;
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
|
||||
@@ -402,7 +402,7 @@ static int rk2818_sdmmc_submit_data_dma(struct rk2818_sdmmc_host *host, struct m
|
||||
set_dma_sg(host->dma_chn, data->sg, data->sg_len);
|
||||
set_dma_mode(host->dma_chn,
|
||||
(data->flags & MMC_DATA_READ)? DMA_MODE_READ : DMA_MODE_WRITE);
|
||||
set_dma_handler(host->dma_chn, rk2818_sdmmc_dma_complete, (void *)host);
|
||||
set_dma_handler(host->dma_chn, rk2818_sdmmc_dma_complete, (void *)host, DMA_IRQ_DELAY_MODE);
|
||||
writel(readl(host->regs + SDMMC_CTRL) | SDMMC_CTRL_DMA_ENABLE,
|
||||
host->regs +SDMMC_CTRL);
|
||||
enable_dma(host->dma_chn);
|
||||
|
||||
@@ -155,7 +155,7 @@ void audio_start_dma(struct snd_pcm_substream *substream, int mode)
|
||||
disable_dma(prtd->params->channel);
|
||||
//set_dma_sg(prtd->params->channel, &(sg_buf->sg), 1);
|
||||
set_dma_mode(prtd->params->channel, DMA_MODE_WRITE);
|
||||
set_dma_handler(prtd->params->channel, rockchip_pcm_dma_irq, substream);
|
||||
set_dma_handler(prtd->params->channel, rockchip_pcm_dma_irq, substream, DMA_IRQ_RIGHTNOW_MODE);
|
||||
__set_dma_addr(prtd->params->channel, (void *)(sg_buf->sg.dma_address));
|
||||
set_dma_count(prtd->params->channel, sg_buf->sg.length);
|
||||
enable_dma(prtd->params->channel);
|
||||
@@ -185,7 +185,7 @@ void audio_start_dma(struct snd_pcm_substream *substream, int mode)
|
||||
disable_dma(prtd->params->channel);
|
||||
//set_dma_sg(prtd->params->channel, &(sg_buf->sg), 1);
|
||||
set_dma_mode(prtd->params->channel, DMA_MODE_READ);
|
||||
set_dma_handler(prtd->params->channel, rockchip_pcm_dma_irq, substream);
|
||||
set_dma_handler(prtd->params->channel, rockchip_pcm_dma_irq, substream, DMA_IRQ_RIGHTNOW_MODE);
|
||||
__set_dma_addr(prtd->params->channel, (void *)(sg_buf->sg.dma_address));
|
||||
set_dma_count(prtd->params->channel, sg_buf->sg.length);
|
||||
enable_dma(prtd->params->channel);
|
||||
@@ -418,7 +418,9 @@ rockchip_pcm_pointer(struct snd_pcm_substream *substream)
|
||||
|
||||
DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
|
||||
spin_lock(&prtd->lock);
|
||||
dma_getposition(prtd->params->channel, &src, &dst);
|
||||
|
||||
get_dma_position(prtd->params->channel, &src, &dst);
|
||||
//dma_getposition(prtd->params->channel, &src, &dst);
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
|
||||
res = dst - prtd->dma_start;
|
||||
|
||||
Reference in New Issue
Block a user