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)
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;
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;
};