DMA: shdma: support the new CHCLR register layout
On newer r-car SoCs the CHCLR register only contains one bit per channel, to which a 1 has to be written to reset the channel. Older SoC versions had one CHCLR register per channel, to which a 0 must be written to reset the channel and clear its buffers. This patch adds support for the newer layout. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski+renesas@gmail.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
This commit is contained in:
parent
115357e977
commit
ca8b387803
|
@ -49,12 +49,22 @@
|
|||
static DEFINE_SPINLOCK(sh_dmae_lock);
|
||||
static LIST_HEAD(sh_dmae_devices);
|
||||
|
||||
/*
|
||||
* Different DMAC implementations provide different ways to clear DMA channels:
|
||||
* (1) none - no CHCLR registers are available
|
||||
* (2) one CHCLR register per channel - 0 has to be written to it to clear
|
||||
* channel buffers
|
||||
* (3) one CHCLR per several channels - 1 has to be written to the bit,
|
||||
* corresponding to the specific channel to reset it
|
||||
*/
|
||||
static void channel_clear(struct sh_dmae_chan *sh_dc)
|
||||
{
|
||||
struct sh_dmae_device *shdev = to_sh_dev(sh_dc);
|
||||
const struct sh_dmae_channel *chan_pdata = shdev->pdata->channel +
|
||||
sh_dc->shdma_chan.id;
|
||||
u32 val = shdev->pdata->chclr_bitwise ? 1 << chan_pdata->chclr_bit : 0;
|
||||
|
||||
__raw_writel(0, shdev->chan_reg +
|
||||
shdev->pdata->channel[sh_dc->shdma_chan.id].chclr_offset);
|
||||
__raw_writel(val, shdev->chan_reg + chan_pdata->chclr_offset);
|
||||
}
|
||||
|
||||
static void sh_dmae_writel(struct sh_dmae_chan *sh_dc, u32 data, u32 reg)
|
||||
|
|
|
@ -33,13 +33,44 @@ struct sh_dmae_slave_config {
|
|||
char mid_rid;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct sh_dmae_channel - DMAC channel platform data
|
||||
* @offset: register offset within the main IOMEM resource
|
||||
* @dmars: channel DMARS register offset
|
||||
* @chclr_offset: channel CHCLR register offset
|
||||
* @dmars_bit: channel DMARS field offset within the register
|
||||
* @chclr_bit: bit position, to be set to reset the channel
|
||||
*/
|
||||
struct sh_dmae_channel {
|
||||
unsigned int offset;
|
||||
unsigned int dmars;
|
||||
unsigned int dmars_bit;
|
||||
unsigned int chclr_offset;
|
||||
unsigned char dmars_bit;
|
||||
unsigned char chclr_bit;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct sh_dmae_pdata - DMAC platform data
|
||||
* @slave: array of slaves
|
||||
* @slave_num: number of slaves in the above array
|
||||
* @channel: array of DMA channels
|
||||
* @channel_num: number of channels in the above array
|
||||
* @ts_low_shift: shift of the low part of the TS field
|
||||
* @ts_low_mask: low TS field mask
|
||||
* @ts_high_shift: additional shift of the high part of the TS field
|
||||
* @ts_high_mask: high TS field mask
|
||||
* @ts_shift: array of Transfer Size shifts, indexed by TS value
|
||||
* @ts_shift_num: number of shifts in the above array
|
||||
* @dmaor_init: DMAOR initialisation value
|
||||
* @chcr_offset: CHCR address offset
|
||||
* @chcr_ie_bit: CHCR Interrupt Enable bit
|
||||
* @dmaor_is_32bit: DMAOR is a 32-bit register
|
||||
* @needs_tend_set: the TEND register has to be set
|
||||
* @no_dmars: DMAC has no DMARS registers
|
||||
* @chclr_present: DMAC has one or several CHCLR registers
|
||||
* @chclr_bitwise: channel CHCLR registers are bitwise
|
||||
* @slave_only: DMAC cannot be used for MEMCPY
|
||||
*/
|
||||
struct sh_dmae_pdata {
|
||||
const struct sh_dmae_slave_config *slave;
|
||||
int slave_num;
|
||||
|
@ -59,6 +90,7 @@ struct sh_dmae_pdata {
|
|||
unsigned int needs_tend_set:1;
|
||||
unsigned int no_dmars:1;
|
||||
unsigned int chclr_present:1;
|
||||
unsigned int chclr_bitwise:1;
|
||||
unsigned int slave_only:1;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue