aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/shdma.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/dma/shdma.c')
-rw-r--r--drivers/dma/shdma.c79
1 files changed, 49 insertions, 30 deletions
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c
index ab12fa5a1296..b419afaa2389 100644
--- a/drivers/dma/shdma.c
+++ b/drivers/dma/shdma.c
@@ -24,8 +24,7 @@
24#include <linux/delay.h> 24#include <linux/delay.h>
25#include <linux/dma-mapping.h> 25#include <linux/dma-mapping.h>
26#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <cpu/dma.h> 27#include <asm/dmaengine.h>
28#include <asm/dma-sh.h>
29#include "shdma.h" 28#include "shdma.h"
30 29
31/* DMA descriptor control */ 30/* DMA descriptor control */
@@ -38,15 +37,8 @@ enum sh_dmae_desc_status {
38}; 37};
39 38
40#define NR_DESCS_PER_CHANNEL 32 39#define NR_DESCS_PER_CHANNEL 32
41/* 40/* Default MEMCPY transfer size = 2^2 = 4 bytes */
42 * Define the default configuration for dual address memory-memory transfer. 41#define LOG2_DEFAULT_XFER_SIZE 2
43 * The 0x400 value represents auto-request, external->external.
44 *
45 * And this driver set 4byte burst mode.
46 * If you want to change mode, you need to change RS_DEFAULT of value.
47 * (ex 1byte burst mode -> (RS_DUAL & ~TS_32)
48 */
49#define RS_DEFAULT (RS_DUAL)
50 42
51/* A bitmask with bits enough for enum sh_dmae_slave_chan_id */ 43/* A bitmask with bits enough for enum sh_dmae_slave_chan_id */
52static unsigned long sh_dmae_slave_used[BITS_TO_LONGS(SHDMA_SLAVE_NUMBER)]; 44static unsigned long sh_dmae_slave_used[BITS_TO_LONGS(SHDMA_SLAVE_NUMBER)];
@@ -90,7 +82,7 @@ static int sh_dmae_rst(struct sh_dmae_device *shdev)
90 unsigned short dmaor; 82 unsigned short dmaor;
91 83
92 sh_dmae_ctl_stop(shdev); 84 sh_dmae_ctl_stop(shdev);
93 dmaor = dmaor_read(shdev) | DMAOR_INIT; 85 dmaor = dmaor_read(shdev) | shdev->pdata->dmaor_init;
94 86
95 dmaor_write(shdev, dmaor); 87 dmaor_write(shdev, dmaor);
96 if (dmaor_read(shdev) & (DMAOR_AE | DMAOR_NMIF)) { 88 if (dmaor_read(shdev) & (DMAOR_AE | DMAOR_NMIF)) {
@@ -110,13 +102,36 @@ static bool dmae_is_busy(struct sh_dmae_chan *sh_chan)
110 return false; /* waiting */ 102 return false; /* waiting */
111} 103}
112 104
113static unsigned int ts_shift[] = TS_SHIFT; 105static unsigned int calc_xmit_shift(struct sh_dmae_chan *sh_chan, u32 chcr)
114static inline unsigned int calc_xmit_shift(u32 chcr)
115{ 106{
116 int cnt = ((chcr & CHCR_TS_LOW_MASK) >> CHCR_TS_LOW_SHIFT) | 107 struct sh_dmae_device *shdev = container_of(sh_chan->common.device,
117 ((chcr & CHCR_TS_HIGH_MASK) >> CHCR_TS_HIGH_SHIFT); 108 struct sh_dmae_device, common);
109 struct sh_dmae_pdata *pdata = shdev->pdata;
110 int cnt = ((chcr & pdata->ts_low_mask) >> pdata->ts_low_shift) |
111 ((chcr & pdata->ts_high_mask) >> pdata->ts_high_shift);
112
113 if (cnt >= pdata->ts_shift_num)
114 cnt = 0;
118 115
119 return ts_shift[cnt]; 116 return pdata->ts_shift[cnt];
117}
118
119static u32 log2size_to_chcr(struct sh_dmae_chan *sh_chan, int l2size)
120{
121 struct sh_dmae_device *shdev = container_of(sh_chan->common.device,
122 struct sh_dmae_device, common);
123 struct sh_dmae_pdata *pdata = shdev->pdata;
124 int i;
125
126 for (i = 0; i < pdata->ts_shift_num; i++)
127 if (pdata->ts_shift[i] == l2size)
128 break;
129
130 if (i == pdata->ts_shift_num)
131 i = 0;
132
133 return ((i << pdata->ts_low_shift) & pdata->ts_low_mask) |
134 ((i << pdata->ts_high_shift) & pdata->ts_high_mask);
120} 135}
121 136
122static void dmae_set_reg(struct sh_dmae_chan *sh_chan, struct sh_dmae_regs *hw) 137static void dmae_set_reg(struct sh_dmae_chan *sh_chan, struct sh_dmae_regs *hw)
@@ -144,8 +159,13 @@ static void dmae_halt(struct sh_dmae_chan *sh_chan)
144 159
145static void dmae_init(struct sh_dmae_chan *sh_chan) 160static void dmae_init(struct sh_dmae_chan *sh_chan)
146{ 161{
147 u32 chcr = RS_DEFAULT; /* default is DUAL mode */ 162 /*
148 sh_chan->xmit_shift = calc_xmit_shift(chcr); 163 * Default configuration for dual address memory-memory transfer.
164 * 0x400 represents auto-request.
165 */
166 u32 chcr = DM_INC | SM_INC | 0x400 | log2size_to_chcr(sh_chan,
167 LOG2_DEFAULT_XFER_SIZE);
168 sh_chan->xmit_shift = calc_xmit_shift(sh_chan, chcr);
149 sh_dmae_writel(sh_chan, chcr, CHCR); 169 sh_dmae_writel(sh_chan, chcr, CHCR);
150} 170}
151 171
@@ -155,7 +175,7 @@ static int dmae_set_chcr(struct sh_dmae_chan *sh_chan, u32 val)
155 if (dmae_is_busy(sh_chan)) 175 if (dmae_is_busy(sh_chan))
156 return -EBUSY; 176 return -EBUSY;
157 177
158 sh_chan->xmit_shift = calc_xmit_shift(val); 178 sh_chan->xmit_shift = calc_xmit_shift(sh_chan, val);
159 sh_dmae_writel(sh_chan, val, CHCR); 179 sh_dmae_writel(sh_chan, val, CHCR);
160 180
161 return 0; 181 return 0;
@@ -285,9 +305,8 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan)
285 305
286 dmae_set_dmars(sh_chan, cfg->mid_rid); 306 dmae_set_dmars(sh_chan, cfg->mid_rid);
287 dmae_set_chcr(sh_chan, cfg->chcr); 307 dmae_set_chcr(sh_chan, cfg->chcr);
288 } else { 308 } else if ((sh_dmae_readl(sh_chan, CHCR) & 0xf00) != 0x400) {
289 if ((sh_dmae_readl(sh_chan, CHCR) & 0x700) != 0x400) 309 dmae_init(sh_chan);
290 dmae_set_chcr(sh_chan, RS_DEFAULT);
291 } 310 }
292 311
293 spin_lock_bh(&sh_chan->desc_lock); 312 spin_lock_bh(&sh_chan->desc_lock);
@@ -757,7 +776,7 @@ static irqreturn_t sh_dmae_err(int irq, void *data)
757 sh_dmae_ctl_stop(shdev); 776 sh_dmae_ctl_stop(shdev);
758 777
759 /* We cannot detect, which channel caused the error, have to reset all */ 778 /* We cannot detect, which channel caused the error, have to reset all */
760 for (i = 0; i < MAX_DMA_CHANNELS; i++) { 779 for (i = 0; i < SH_DMAC_MAX_CHANNELS; i++) {
761 struct sh_dmae_chan *sh_chan = shdev->chan[i]; 780 struct sh_dmae_chan *sh_chan = shdev->chan[i];
762 if (sh_chan) { 781 if (sh_chan) {
763 struct sh_desc *desc; 782 struct sh_desc *desc;
@@ -822,6 +841,9 @@ static int __devinit sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id,
822 return -ENOMEM; 841 return -ENOMEM;
823 } 842 }
824 843
844 /* copy struct dma_device */
845 new_sh_chan->common.device = &shdev->common;
846
825 new_sh_chan->dev = shdev->common.dev; 847 new_sh_chan->dev = shdev->common.dev;
826 new_sh_chan->id = id; 848 new_sh_chan->id = id;
827 new_sh_chan->irq = irq; 849 new_sh_chan->irq = irq;
@@ -840,9 +862,6 @@ static int __devinit sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id,
840 INIT_LIST_HEAD(&new_sh_chan->ld_queue); 862 INIT_LIST_HEAD(&new_sh_chan->ld_queue);
841 INIT_LIST_HEAD(&new_sh_chan->ld_free); 863 INIT_LIST_HEAD(&new_sh_chan->ld_free);
842 864
843 /* copy struct dma_device */
844 new_sh_chan->common.device = &shdev->common;
845
846 /* Add the channel to DMA device channel list */ 865 /* Add the channel to DMA device channel list */
847 list_add_tail(&new_sh_chan->common.device_node, 866 list_add_tail(&new_sh_chan->common.device_node,
848 &shdev->common.channels); 867 &shdev->common.channels);
@@ -896,8 +915,8 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
896{ 915{
897 struct sh_dmae_pdata *pdata = pdev->dev.platform_data; 916 struct sh_dmae_pdata *pdata = pdev->dev.platform_data;
898 unsigned long irqflags = IRQF_DISABLED, 917 unsigned long irqflags = IRQF_DISABLED,
899 chan_flag[MAX_DMA_CHANNELS] = {}; 918 chan_flag[SH_DMAC_MAX_CHANNELS] = {};
900 int errirq, chan_irq[MAX_DMA_CHANNELS]; 919 int errirq, chan_irq[SH_DMAC_MAX_CHANNELS];
901 int err, i, irq_cnt = 0, irqres = 0; 920 int err, i, irq_cnt = 0, irqres = 0;
902 struct sh_dmae_device *shdev; 921 struct sh_dmae_device *shdev;
903 struct resource *chan, *dmars, *errirq_res, *chanirq_res; 922 struct resource *chan, *dmars, *errirq_res, *chanirq_res;
@@ -983,7 +1002,7 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
983 1002
984 shdev->common.dev = &pdev->dev; 1003 shdev->common.dev = &pdev->dev;
985 /* Default transfer size of 32 bytes requires 32-byte alignment */ 1004 /* Default transfer size of 32 bytes requires 32-byte alignment */
986 shdev->common.copy_align = 5; 1005 shdev->common.copy_align = LOG2_DEFAULT_XFER_SIZE;
987 1006
988#if defined(CONFIG_CPU_SH4) 1007#if defined(CONFIG_CPU_SH4)
989 chanirq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 1); 1008 chanirq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 1);