summaryrefslogtreecommitdiff
path: root/arch/sh/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/drivers')
-rw-r--r--arch/sh/drivers/dma/Kconfig14
-rw-r--r--arch/sh/drivers/dma/dma-sh.c37
2 files changed, 32 insertions, 19 deletions
diff --git a/arch/sh/drivers/dma/Kconfig b/arch/sh/drivers/dma/Kconfig
index 7d54f284ce10..08d937a6d249 100644
--- a/arch/sh/drivers/dma/Kconfig
+++ b/arch/sh/drivers/dma/Kconfig
@@ -28,17 +28,19 @@ config SH_DMA_API
config NR_ONCHIP_DMA_CHANNELS
int
depends on SH_DMA
- default "4" if CPU_SUBTYPE_SH7750 || CPU_SUBTYPE_SH7751 || \
- CPU_SUBTYPE_SH7750S || CPU_SUBTYPE_SH7091
+ default "4" if CPU_SUBTYPE_SH7709 || CPU_SUBTYPE_SH7750 || \
+ CPU_SUBTYPE_SH7750S || CPU_SUBTYPE_SH7751 || \
+ CPU_SUBTYPE_SH7091
default "8" if CPU_SUBTYPE_SH7750R || CPU_SUBTYPE_SH7751R || \
CPU_SUBTYPE_SH7760
- default "12" if CPU_SUBTYPE_SH7723 || CPU_SUBTYPE_SH7780 || \
- CPU_SUBTYPE_SH7785 || CPU_SUBTYPE_SH7724
+ default "12" if CPU_SUBTYPE_SH7723 || CPU_SUBTYPE_SH7724 || \
+ CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785
default "6"
help
This allows you to specify the number of channels that the on-chip
- DMAC supports. This will be 4 for SH7750/SH7751/Sh7750S/SH7091 and 8 for the
- SH7750R/SH7751R/SH7760, 12 for the SH7723/SH7780/SH7785/SH7724, default is 6.
+ DMAC supports. This will be 4 for SH7709/SH7750/SH7750S/SH7751/SH7091,
+ 8 for SH7750R/SH7751R/SH7760, and 12 for SH7723/SH7724/SH7780/SH7785.
+ Default is 6.
config SH_DMABRG
bool "SH7760 DMABRG support"
diff --git a/arch/sh/drivers/dma/dma-sh.c b/arch/sh/drivers/dma/dma-sh.c
index 96c626c2cd0a..306fba1564e5 100644
--- a/arch/sh/drivers/dma/dma-sh.c
+++ b/arch/sh/drivers/dma/dma-sh.c
@@ -19,6 +19,18 @@
#include <cpu/dma.h>
/*
+ * Some of the SoCs feature two DMAC modules. In such a case, the channels are
+ * distributed equally among them.
+ */
+#ifdef SH_DMAC_BASE1
+#define SH_DMAC_NR_MD_CH (CONFIG_NR_ONCHIP_DMA_CHANNELS / 2)
+#else
+#define SH_DMAC_NR_MD_CH CONFIG_NR_ONCHIP_DMA_CHANNELS
+#endif
+
+#define SH_DMAC_CH_SZ 0x10
+
+/*
* Define the default configuration for dual address memory-memory transfer.
* The 0x400 value represents auto-request, external->external.
*/
@@ -29,7 +41,7 @@ static unsigned long dma_find_base(unsigned int chan)
unsigned long base = SH_DMAC_BASE0;
#ifdef SH_DMAC_BASE1
- if (chan >= 6)
+ if (chan >= SH_DMAC_NR_MD_CH)
base = SH_DMAC_BASE1;
#endif
@@ -40,13 +52,13 @@ static unsigned long dma_base_addr(unsigned int chan)
{
unsigned long base = dma_find_base(chan);
- /* Normalize offset calculation */
- if (chan >= 9)
- chan -= 6;
- if (chan >= 4)
- base += 0x10;
+ chan = (chan % SH_DMAC_NR_MD_CH) * SH_DMAC_CH_SZ;
+
+ /* DMAOR is placed inside the channel register space. Step over it. */
+ if (chan >= DMAOR)
+ base += SH_DMAC_CH_SZ;
- return base + (chan * 0x10);
+ return base + chan;
}
#ifdef CONFIG_SH_DMA_IRQ_MULTI
@@ -250,12 +262,11 @@ static int sh_dmac_get_dma_residue(struct dma_channel *chan)
#define NR_DMAOR 1
#endif
-/*
- * DMAOR bases are broken out amongst channel groups. DMAOR0 manages
- * channels 0 - 5, DMAOR1 6 - 11 (optional).
- */
-#define dmaor_read_reg(n) __raw_readw(dma_find_base((n)*6))
-#define dmaor_write_reg(n, data) __raw_writew(data, dma_find_base(n)*6)
+#define dmaor_read_reg(n) __raw_readw(dma_find_base((n) * \
+ SH_DMAC_NR_MD_CH) + DMAOR)
+#define dmaor_write_reg(n, data) __raw_writew(data, \
+ dma_find_base((n) * \
+ SH_DMAC_NR_MD_CH) + DMAOR)
static inline int dmaor_reset(int no)
{