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 DEFINE_SPINLOCK(sh_dmae_lock);
|
||||||
static LIST_HEAD(sh_dmae_devices);
|
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)
|
static void channel_clear(struct sh_dmae_chan *sh_dc)
|
||||||
{
|
{
|
||||||
struct sh_dmae_device *shdev = to_sh_dev(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 +
|
__raw_writel(val, shdev->chan_reg + chan_pdata->chclr_offset);
|
||||||
shdev->pdata->channel[sh_dc->shdma_chan.id].chclr_offset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sh_dmae_writel(struct sh_dmae_chan *sh_dc, u32 data, u32 reg)
|
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;
|
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 {
|
struct sh_dmae_channel {
|
||||||
unsigned int offset;
|
unsigned int offset;
|
||||||
unsigned int dmars;
|
unsigned int dmars;
|
||||||
unsigned int dmars_bit;
|
|
||||||
unsigned int chclr_offset;
|
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 {
|
struct sh_dmae_pdata {
|
||||||
const struct sh_dmae_slave_config *slave;
|
const struct sh_dmae_slave_config *slave;
|
||||||
int slave_num;
|
int slave_num;
|
||||||
|
@ -59,6 +90,7 @@ struct sh_dmae_pdata {
|
||||||
unsigned int needs_tend_set:1;
|
unsigned int needs_tend_set:1;
|
||||||
unsigned int no_dmars:1;
|
unsigned int no_dmars:1;
|
||||||
unsigned int chclr_present:1;
|
unsigned int chclr_present:1;
|
||||||
|
unsigned int chclr_bitwise:1;
|
||||||
unsigned int slave_only:1;
|
unsigned int slave_only:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue