aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2013-07-10 06:09:47 -0400
committerVinod Koul <vinod.koul@intel.com>2013-08-27 04:54:07 -0400
commitca8b387803072a16baf6d8090591b10bfdf4e253 (patch)
tree369a7e9cc93d4ff6d7e9445d57ef933a107eb75f
parent115357e9774ff8d70a84d3c31f271209913637b0 (diff)
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>
-rw-r--r--drivers/dma/sh/shdma.c14
-rw-r--r--include/linux/sh_dma.h34
2 files changed, 45 insertions, 3 deletions
diff --git a/drivers/dma/sh/shdma.c b/drivers/dma/sh/shdma.c
index 9ee1272604b4..53bd6308fc2f 100644
--- a/drivers/dma/sh/shdma.c
+++ b/drivers/dma/sh/shdma.c
@@ -49,12 +49,22 @@
49static DEFINE_SPINLOCK(sh_dmae_lock); 49static DEFINE_SPINLOCK(sh_dmae_lock);
50static LIST_HEAD(sh_dmae_devices); 50static LIST_HEAD(sh_dmae_devices);
51 51
52/*
53 * Different DMAC implementations provide different ways to clear DMA channels:
54 * (1) none - no CHCLR registers are available
55 * (2) one CHCLR register per channel - 0 has to be written to it to clear
56 * channel buffers
57 * (3) one CHCLR per several channels - 1 has to be written to the bit,
58 * corresponding to the specific channel to reset it
59 */
52static void channel_clear(struct sh_dmae_chan *sh_dc) 60static void channel_clear(struct sh_dmae_chan *sh_dc)
53{ 61{
54 struct sh_dmae_device *shdev = to_sh_dev(sh_dc); 62 struct sh_dmae_device *shdev = to_sh_dev(sh_dc);
63 const struct sh_dmae_channel *chan_pdata = shdev->pdata->channel +
64 sh_dc->shdma_chan.id;
65 u32 val = shdev->pdata->chclr_bitwise ? 1 << chan_pdata->chclr_bit : 0;
55 66
56 __raw_writel(0, shdev->chan_reg + 67 __raw_writel(val, shdev->chan_reg + chan_pdata->chclr_offset);
57 shdev->pdata->channel[sh_dc->shdma_chan.id].chclr_offset);
58} 68}
59 69
60static void sh_dmae_writel(struct sh_dmae_chan *sh_dc, u32 data, u32 reg) 70static void sh_dmae_writel(struct sh_dmae_chan *sh_dc, u32 data, u32 reg)
diff --git a/include/linux/sh_dma.h b/include/linux/sh_dma.h
index 4e83f3e034f3..776ed9d682f4 100644
--- a/include/linux/sh_dma.h
+++ b/include/linux/sh_dma.h
@@ -33,13 +33,44 @@ struct sh_dmae_slave_config {
33 char mid_rid; 33 char mid_rid;
34}; 34};
35 35
36/**
37 * struct sh_dmae_channel - DMAC channel platform data
38 * @offset: register offset within the main IOMEM resource
39 * @dmars: channel DMARS register offset
40 * @chclr_offset: channel CHCLR register offset
41 * @dmars_bit: channel DMARS field offset within the register
42 * @chclr_bit: bit position, to be set to reset the channel
43 */
36struct sh_dmae_channel { 44struct sh_dmae_channel {
37 unsigned int offset; 45 unsigned int offset;
38 unsigned int dmars; 46 unsigned int dmars;
39 unsigned int dmars_bit;
40 unsigned int chclr_offset; 47 unsigned int chclr_offset;
48 unsigned char dmars_bit;
49 unsigned char chclr_bit;
41}; 50};
42 51
52/**
53 * struct sh_dmae_pdata - DMAC platform data
54 * @slave: array of slaves
55 * @slave_num: number of slaves in the above array
56 * @channel: array of DMA channels
57 * @channel_num: number of channels in the above array
58 * @ts_low_shift: shift of the low part of the TS field
59 * @ts_low_mask: low TS field mask
60 * @ts_high_shift: additional shift of the high part of the TS field
61 * @ts_high_mask: high TS field mask
62 * @ts_shift: array of Transfer Size shifts, indexed by TS value
63 * @ts_shift_num: number of shifts in the above array
64 * @dmaor_init: DMAOR initialisation value
65 * @chcr_offset: CHCR address offset
66 * @chcr_ie_bit: CHCR Interrupt Enable bit
67 * @dmaor_is_32bit: DMAOR is a 32-bit register
68 * @needs_tend_set: the TEND register has to be set
69 * @no_dmars: DMAC has no DMARS registers
70 * @chclr_present: DMAC has one or several CHCLR registers
71 * @chclr_bitwise: channel CHCLR registers are bitwise
72 * @slave_only: DMAC cannot be used for MEMCPY
73 */
43struct sh_dmae_pdata { 74struct sh_dmae_pdata {
44 const struct sh_dmae_slave_config *slave; 75 const struct sh_dmae_slave_config *slave;
45 int slave_num; 76 int slave_num;
@@ -59,6 +90,7 @@ struct sh_dmae_pdata {
59 unsigned int needs_tend_set:1; 90 unsigned int needs_tend_set:1;
60 unsigned int no_dmars:1; 91 unsigned int no_dmars:1;
61 unsigned int chclr_present:1; 92 unsigned int chclr_present:1;
93 unsigned int chclr_bitwise:1;
62 unsigned int slave_only:1; 94 unsigned int slave_only:1;
63}; 95};
64 96