1
0
Fork 0

dmaengine: dw: set LMS field in descriptors

The LMS field indicates from which master the descriptor is to be
read.  This patch assumes this is always the same as the memory
side in a peripheral transfer which is true for all known systems.

Signed-off-by: Mans Rullgard <mans@mansr.com>
Acked-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
hifive-unleashed-5.1
Mans Rullgard 2016-03-18 16:24:44 +02:00 committed by Vinod Koul
parent df1f3a2305
commit 2a0fae025e
2 changed files with 18 additions and 12 deletions

View File

@ -217,6 +217,7 @@ static inline void dwc_do_single_block(struct dw_dma_chan *dwc,
static void dwc_dostart(struct dw_dma_chan *dwc, struct dw_desc *first)
{
struct dw_dma *dw = to_dw_dma(dwc->chan.device);
u8 lms = DWC_LLP_LMS(dwc->m_master);
unsigned long was_soft_llp;
/* ASSERT: channel is idle */
@ -252,9 +253,8 @@ static void dwc_dostart(struct dw_dma_chan *dwc, struct dw_desc *first)
dwc_initialize(dwc);
channel_writel(dwc, LLP, first->txd.phys);
channel_writel(dwc, CTL_LO,
DWC_CTLL_LLP_D_EN | DWC_CTLL_LLP_S_EN);
channel_writel(dwc, LLP, first->txd.phys | lms);
channel_writel(dwc, CTL_LO, DWC_CTLL_LLP_D_EN | DWC_CTLL_LLP_S_EN);
channel_writel(dwc, CTL_HI, 0);
channel_set_bit(dw, CH_EN, dwc->mask);
}
@ -418,7 +418,7 @@ static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc)
dwc->residue = desc->total_len;
/* Check first descriptors addr */
if (desc->txd.phys == llp) {
if (desc->txd.phys == DWC_LLP_LOC(llp)) {
spin_unlock_irqrestore(&dwc->lock, flags);
return;
}
@ -705,6 +705,7 @@ dwc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
unsigned int dst_width;
unsigned int data_width;
u32 ctllo;
u8 lms = DWC_LLP_LMS(dwc->m_master);
dev_vdbg(chan2dev(chan),
"%s: d%pad s%pad l0x%zx f0x%lx\n", __func__,
@ -747,7 +748,7 @@ dwc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
if (!first) {
first = desc;
} else {
lli_write(prev, llp, desc->txd.phys);
lli_write(prev, llp, desc->txd.phys | lms);
list_add_tail(&desc->desc_node, &first->tx_list);
}
prev = desc;
@ -779,6 +780,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
struct dw_desc *prev;
struct dw_desc *first;
u32 ctllo;
u8 lms = DWC_LLP_LMS(dwc->m_master);
dma_addr_t reg;
unsigned int reg_width;
unsigned int mem_width;
@ -843,7 +845,7 @@ slave_sg_todev_fill_desc:
if (!first) {
first = desc;
} else {
lli_write(prev, llp, desc->txd.phys);
lli_write(prev, llp, desc->txd.phys | lms);
list_add_tail(&desc->desc_node, &first->tx_list);
}
prev = desc;
@ -898,7 +900,7 @@ slave_sg_fromdev_fill_desc:
if (!first) {
first = desc;
} else {
lli_write(prev, llp, desc->txd.phys);
lli_write(prev, llp, desc->txd.phys | lms);
list_add_tail(&desc->desc_node, &first->tx_list);
}
prev = desc;
@ -1330,6 +1332,7 @@ struct dw_cyclic_desc *dw_dma_cyclic_prep(struct dma_chan *chan,
struct dw_cyclic_desc *retval = NULL;
struct dw_desc *desc;
struct dw_desc *last = NULL;
u8 lms = DWC_LLP_LMS(dwc->m_master);
unsigned long was_cyclic;
unsigned int reg_width;
unsigned int periods;
@ -1438,13 +1441,13 @@ struct dw_cyclic_desc *dw_dma_cyclic_prep(struct dma_chan *chan,
cdesc->desc[i] = desc;
if (last)
lli_write(last, llp, desc->txd.phys);
lli_write(last, llp, desc->txd.phys | lms);
last = desc;
}
/* Let's make a cyclic list */
lli_write(last, llp, cdesc->desc[0]->txd.phys);
lli_write(last, llp, cdesc->desc[0]->txd.phys | lms);
dev_dbg(chan2dev(&dwc->chan),
"cyclic prepared buf %pad len %zu period %zu periods %d\n",
@ -1646,9 +1649,8 @@ int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata)
dwc->block_size = pdata->block_size;
/* Check if channel supports multi block transfer */
channel_writel(dwc, LLP, 0xfffffffc);
dwc->nollp =
(channel_readl(dwc, LLP) & 0xfffffffc) == 0;
channel_writel(dwc, LLP, DWC_LLP_LOC(0xffffffff));
dwc->nollp = DWC_LLP_LOC(channel_readl(dwc, LLP)) == 0;
channel_writel(dwc, LLP, 0);
}
}

View File

@ -143,6 +143,10 @@ enum dw_dma_msize {
DW_DMA_MSIZE_256,
};
/* Bitfields in LLP */
#define DWC_LLP_LMS(x) ((x) & 3) /* list master select */
#define DWC_LLP_LOC(x) ((x) & ~3) /* next lli */
/* Bitfields in CTL_LO */
#define DWC_CTLL_INT_EN (1 << 0) /* irqs enabled? */
#define DWC_CTLL_DST_WIDTH(n) ((n)<<1) /* bytes per element */