mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-05 00:20:32 +00:00
dmaengine: mv_xor_v2: implement proper interrupt coalescing
Until now, the driver was not using interrupt coalescing: one interrupt was generated for each descriptor processed by the XOR engine. This commit changes that by using the interrupt coalescing features of the hardware, by setting both a number of descriptors processed before an interrupt is generated and a timeout before an interrupt is generated. Signed-off-by: Hanna Hawa <hannah@marvell.com> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
This commit is contained in:
parent
b2d3c270f9
commit
d793327fac
1 changed files with 36 additions and 0 deletions
|
@ -42,6 +42,7 @@
|
||||||
#define MV_XOR_V2_DMA_IMSG_THRD_OFF 0x018
|
#define MV_XOR_V2_DMA_IMSG_THRD_OFF 0x018
|
||||||
#define MV_XOR_V2_DMA_IMSG_THRD_MASK 0x7FFF
|
#define MV_XOR_V2_DMA_IMSG_THRD_MASK 0x7FFF
|
||||||
#define MV_XOR_V2_DMA_IMSG_THRD_SHIFT 0x0
|
#define MV_XOR_V2_DMA_IMSG_THRD_SHIFT 0x0
|
||||||
|
#define MV_XOR_V2_DMA_IMSG_TIMER_EN BIT(18)
|
||||||
#define MV_XOR_V2_DMA_DESQ_AWATTR_OFF 0x01C
|
#define MV_XOR_V2_DMA_DESQ_AWATTR_OFF 0x01C
|
||||||
/* Same flags as MV_XOR_V2_DMA_DESQ_ARATTR_OFF */
|
/* Same flags as MV_XOR_V2_DMA_DESQ_ARATTR_OFF */
|
||||||
#define MV_XOR_V2_DMA_DESQ_ALLOC_OFF 0x04C
|
#define MV_XOR_V2_DMA_DESQ_ALLOC_OFF 0x04C
|
||||||
|
@ -55,6 +56,9 @@
|
||||||
#define MV_XOR_V2_DMA_DESQ_STOP_OFF 0x800
|
#define MV_XOR_V2_DMA_DESQ_STOP_OFF 0x800
|
||||||
#define MV_XOR_V2_DMA_DESQ_DEALLOC_OFF 0x804
|
#define MV_XOR_V2_DMA_DESQ_DEALLOC_OFF 0x804
|
||||||
#define MV_XOR_V2_DMA_DESQ_ADD_OFF 0x808
|
#define MV_XOR_V2_DMA_DESQ_ADD_OFF 0x808
|
||||||
|
#define MV_XOR_V2_DMA_IMSG_TMOT 0x810
|
||||||
|
#define MV_XOR_V2_DMA_IMSG_TIMER_THRD_MASK 0x1FFF
|
||||||
|
#define MV_XOR_V2_DMA_IMSG_TIMER_THRD_SHIFT 0
|
||||||
|
|
||||||
/* XOR Global registers */
|
/* XOR Global registers */
|
||||||
#define MV_XOR_V2_GLOB_BW_CTRL 0x4
|
#define MV_XOR_V2_GLOB_BW_CTRL 0x4
|
||||||
|
@ -90,6 +94,13 @@
|
||||||
*/
|
*/
|
||||||
#define MV_XOR_V2_DESC_NUM 1024
|
#define MV_XOR_V2_DESC_NUM 1024
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Threshold values for descriptors and timeout, determined by
|
||||||
|
* experimentation as giving a good level of performance.
|
||||||
|
*/
|
||||||
|
#define MV_XOR_V2_DONE_IMSG_THRD 0x14
|
||||||
|
#define MV_XOR_V2_TIMER_THRD 0xB0
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct mv_xor_v2_descriptor - DMA HW descriptor
|
* struct mv_xor_v2_descriptor - DMA HW descriptor
|
||||||
* @desc_id: used by S/W and is not affected by H/W.
|
* @desc_id: used by S/W and is not affected by H/W.
|
||||||
|
@ -246,6 +257,29 @@ static int mv_xor_v2_set_desc_size(struct mv_xor_v2_device *xor_dev)
|
||||||
return MV_XOR_V2_EXT_DESC_SIZE;
|
return MV_XOR_V2_EXT_DESC_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the IMSG threshold
|
||||||
|
*/
|
||||||
|
static inline
|
||||||
|
void mv_xor_v2_enable_imsg_thrd(struct mv_xor_v2_device *xor_dev)
|
||||||
|
{
|
||||||
|
u32 reg;
|
||||||
|
|
||||||
|
/* Configure threshold of number of descriptors, and enable timer */
|
||||||
|
reg = readl(xor_dev->dma_base + MV_XOR_V2_DMA_IMSG_THRD_OFF);
|
||||||
|
reg &= (~MV_XOR_V2_DMA_IMSG_THRD_MASK << MV_XOR_V2_DMA_IMSG_THRD_SHIFT);
|
||||||
|
reg |= (MV_XOR_V2_DONE_IMSG_THRD << MV_XOR_V2_DMA_IMSG_THRD_SHIFT);
|
||||||
|
reg |= MV_XOR_V2_DMA_IMSG_TIMER_EN;
|
||||||
|
writel(reg, xor_dev->dma_base + MV_XOR_V2_DMA_IMSG_THRD_OFF);
|
||||||
|
|
||||||
|
/* Configure Timer Threshold */
|
||||||
|
reg = readl(xor_dev->dma_base + MV_XOR_V2_DMA_IMSG_TMOT);
|
||||||
|
reg &= (~MV_XOR_V2_DMA_IMSG_TIMER_THRD_MASK <<
|
||||||
|
MV_XOR_V2_DMA_IMSG_TIMER_THRD_SHIFT);
|
||||||
|
reg |= (MV_XOR_V2_TIMER_THRD << MV_XOR_V2_DMA_IMSG_TIMER_THRD_SHIFT);
|
||||||
|
writel(reg, xor_dev->dma_base + MV_XOR_V2_DMA_IMSG_TMOT);
|
||||||
|
}
|
||||||
|
|
||||||
static irqreturn_t mv_xor_v2_interrupt_handler(int irq, void *data)
|
static irqreturn_t mv_xor_v2_interrupt_handler(int irq, void *data)
|
||||||
{
|
{
|
||||||
struct mv_xor_v2_device *xor_dev = data;
|
struct mv_xor_v2_device *xor_dev = data;
|
||||||
|
@ -795,6 +829,8 @@ static int mv_xor_v2_probe(struct platform_device *pdev)
|
||||||
list_add_tail(&xor_dev->dmachan.device_node,
|
list_add_tail(&xor_dev->dmachan.device_node,
|
||||||
&dma_dev->channels);
|
&dma_dev->channels);
|
||||||
|
|
||||||
|
mv_xor_v2_enable_imsg_thrd(xor_dev);
|
||||||
|
|
||||||
mv_xor_v2_descq_init(xor_dev);
|
mv_xor_v2_descq_init(xor_dev);
|
||||||
|
|
||||||
ret = dma_async_device_register(dma_dev);
|
ret = dma_async_device_register(dma_dev);
|
||||||
|
|
Loading…
Reference in a new issue