summaryrefslogtreecommitdiffstats
path: root/include/asm-sh
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2006-01-16 22:14:09 -0800
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-16 23:15:27 -0800
commit0d831770b154a057562236e8cf50905c8f1ae1b0 (patch)
treedc25902b29b09838f2fe32e47be53c951a2fa67e /include/asm-sh
parent0025835cf20e07056b8521b8c1d7d0bfe07e81f1 (diff)
downloadlinux-0d831770b154a057562236e8cf50905c8f1ae1b0.tar.gz
linux-0d831770b154a057562236e8cf50905c8f1ae1b0.tar.bz2
linux-0d831770b154a057562236e8cf50905c8f1ae1b0.zip
[PATCH] sh: DMA updates
This extends the current SH DMA API somewhat to support a proper virtual channel abstraction, and also works to represent this through the driver model by giving each DMAC its own platform device. There's also a few other minor changes to support a few new CPU subtypes, and make TEI generation for the SH DMAC configurable. Signed-off-by: Paul Mundt <lethal@linux-sh.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include/asm-sh')
-rw-r--r--include/asm-sh/bus-sh.h1
-rw-r--r--include/asm-sh/cpu-sh3/dma.h31
-rw-r--r--include/asm-sh/cpu-sh4/dma.h52
-rw-r--r--include/asm-sh/dma-mapping.h25
-rw-r--r--include/asm-sh/dma.h14
5 files changed, 97 insertions, 26 deletions
diff --git a/include/asm-sh/bus-sh.h b/include/asm-sh/bus-sh.h
index 83c5d2fd057f..e42d63b65cb5 100644
--- a/include/asm-sh/bus-sh.h
+++ b/include/asm-sh/bus-sh.h
@@ -21,6 +21,7 @@ struct sh_dev {
void *mapbase;
unsigned int irq[6];
u64 *dma_mask;
+ u64 coherent_dma_mask;
};
#define to_sh_dev(d) container_of((d), struct sh_dev, dev)
diff --git a/include/asm-sh/cpu-sh3/dma.h b/include/asm-sh/cpu-sh3/dma.h
index b972e715f9ee..954801b46022 100644
--- a/include/asm-sh/cpu-sh3/dma.h
+++ b/include/asm-sh/cpu-sh3/dma.h
@@ -3,5 +3,34 @@
#define SH_DMAC_BASE 0xa4000020
-#endif /* __ASM_CPU_SH3_DMA_H */
+/* Definitions for the SuperH DMAC */
+#define TM_BURST 0x00000020
+#define TS_8 0x00000000
+#define TS_16 0x00000008
+#define TS_32 0x00000010
+#define TS_128 0x00000018
+
+#define CHCR_TS_MASK 0x18
+#define CHCR_TS_SHIFT 3
+
+#define DMAOR_INIT DMAOR_DME
+/*
+ * The SuperH DMAC supports a number of transmit sizes, we list them here,
+ * with their respective values as they appear in the CHCR registers.
+ */
+enum {
+ XMIT_SZ_8BIT,
+ XMIT_SZ_16BIT,
+ XMIT_SZ_32BIT,
+ XMIT_SZ_128BIT,
+};
+
+static unsigned int ts_shift[] __attribute__ ((used)) = {
+ [XMIT_SZ_8BIT] = 0,
+ [XMIT_SZ_16BIT] = 1,
+ [XMIT_SZ_32BIT] = 2,
+ [XMIT_SZ_128BIT] = 4,
+};
+
+#endif /* __ASM_CPU_SH3_DMA_H */
diff --git a/include/asm-sh/cpu-sh4/dma.h b/include/asm-sh/cpu-sh4/dma.h
index e2b91adf821a..0dfe61f14802 100644
--- a/include/asm-sh/cpu-sh4/dma.h
+++ b/include/asm-sh/cpu-sh4/dma.h
@@ -1,17 +1,49 @@
#ifndef __ASM_CPU_SH4_DMA_H
#define __ASM_CPU_SH4_DMA_H
+#ifdef CONFIG_CPU_SH4A
+#define SH_DMAC_BASE 0xfc808020
+#else
#define SH_DMAC_BASE 0xffa00000
+#endif
-#define SAR ((unsigned long[]){SH_DMAC_BASE + 0x00, SH_DMAC_BASE + 0x10, \
- SH_DMAC_BASE + 0x20, SH_DMAC_BASE + 0x30})
-#define DAR ((unsigned long[]){SH_DMAC_BASE + 0x04, SH_DMAC_BASE + 0x14, \
- SH_DMAC_BASE + 0x24, SH_DMAC_BASE + 0x34})
-#define DMATCR ((unsigned long[]){SH_DMAC_BASE + 0x08, SH_DMAC_BASE + 0x18, \
- SH_DMAC_BASE + 0x28, SH_DMAC_BASE + 0x38})
-#define CHCR ((unsigned long[]){SH_DMAC_BASE + 0x0c, SH_DMAC_BASE + 0x1c, \
- SH_DMAC_BASE + 0x2c, SH_DMAC_BASE + 0x3c})
-#define DMAOR (SH_DMAC_BASE + 0x40)
+/* Definitions for the SuperH DMAC */
+#define TM_BURST 0x0000080
+#define TS_8 0x00000010
+#define TS_16 0x00000020
+#define TS_32 0x00000030
+#define TS_64 0x00000000
-#endif /* __ASM_CPU_SH4_DMA_H */
+#define CHCR_TS_MASK 0x30
+#define CHCR_TS_SHIFT 4
+
+#define DMAOR_COD 0x00000008
+
+#define DMAOR_INIT ( 0x8000 | DMAOR_DME )
+/*
+ * The SuperH DMAC supports a number of transmit sizes, we list them here,
+ * with their respective values as they appear in the CHCR registers.
+ *
+ * Defaults to a 64-bit transfer size.
+ */
+enum {
+ XMIT_SZ_64BIT,
+ XMIT_SZ_8BIT,
+ XMIT_SZ_16BIT,
+ XMIT_SZ_32BIT,
+ XMIT_SZ_256BIT,
+};
+
+/*
+ * The DMA count is defined as the number of bytes to transfer.
+ */
+static unsigned int ts_shift[] __attribute__ ((used)) = {
+ [XMIT_SZ_64BIT] = 3,
+ [XMIT_SZ_8BIT] = 0,
+ [XMIT_SZ_16BIT] = 1,
+ [XMIT_SZ_32BIT] = 2,
+ [XMIT_SZ_256BIT] = 5,
+};
+
+#endif /* __ASM_CPU_SH4_DMA_H */
diff --git a/include/asm-sh/dma-mapping.h b/include/asm-sh/dma-mapping.h
index d3fa5c2b889d..48f1f42c5d14 100644
--- a/include/asm-sh/dma-mapping.h
+++ b/include/asm-sh/dma-mapping.h
@@ -4,6 +4,7 @@
#include <linux/config.h>
#include <linux/mm.h>
#include <asm/scatterlist.h>
+#include <asm/cacheflush.h>
#include <asm/io.h>
extern struct bus_type pci_bus_type;
@@ -141,24 +142,24 @@ static inline void dma_sync_sg(struct device *dev, struct scatterlist *sg,
}
}
-static inline void dma_sync_single_for_cpu(struct device *dev,
- dma_addr_t dma_handle, size_t size,
- enum dma_data_direction dir)
+static void dma_sync_single_for_cpu(struct device *dev,
+ dma_addr_t dma_handle, size_t size,
+ enum dma_data_direction dir)
__attribute__ ((alias("dma_sync_single")));
-static inline void dma_sync_single_for_device(struct device *dev,
- dma_addr_t dma_handle, size_t size,
- enum dma_data_direction dir)
+static void dma_sync_single_for_device(struct device *dev,
+ dma_addr_t dma_handle, size_t size,
+ enum dma_data_direction dir)
__attribute__ ((alias("dma_sync_single")));
-static inline void dma_sync_sg_for_cpu(struct device *dev,
- struct scatterlist *sg, int nelems,
- enum dma_data_direction dir)
+static void dma_sync_sg_for_cpu(struct device *dev,
+ struct scatterlist *sg, int nelems,
+ enum dma_data_direction dir)
__attribute__ ((alias("dma_sync_sg")));
-static inline void dma_sync_sg_for_device(struct device *dev,
- struct scatterlist *sg, int nelems,
- enum dma_data_direction dir)
+static void dma_sync_sg_for_device(struct device *dev,
+ struct scatterlist *sg, int nelems,
+ enum dma_data_direction dir)
__attribute__ ((alias("dma_sync_sg")));
static inline int dma_get_cache_alignment(void)
diff --git a/include/asm-sh/dma.h b/include/asm-sh/dma.h
index 8e9436093ca8..a118a0d43053 100644
--- a/include/asm-sh/dma.h
+++ b/include/asm-sh/dma.h
@@ -15,6 +15,7 @@
#include <linux/spinlock.h>
#include <linux/wait.h>
#include <linux/sysdev.h>
+#include <linux/device.h>
#include <asm/cpu/dma.h>
#include <asm/semaphore.h>
@@ -54,8 +55,8 @@ enum {
* DMA channel capabilities / flags
*/
enum {
- DMA_CONFIGURED = 0x00,
DMA_TEI_CAPABLE = 0x01,
+ DMA_CONFIGURED = 0x02,
};
extern spinlock_t dma_spin_lock;
@@ -74,7 +75,8 @@ struct dma_ops {
struct dma_channel {
char dev_id[16];
- unsigned int chan;
+ unsigned int chan; /* Physical channel number */
+ unsigned int vchan; /* Virtual channel number */
unsigned int mode;
unsigned int count;
@@ -91,6 +93,8 @@ struct dma_channel {
};
struct dma_info {
+ struct platform_device *pdev;
+
const char *name;
unsigned int nr_channels;
unsigned long flags;
@@ -130,7 +134,11 @@ extern void unregister_dmac(struct dma_info *info);
#ifdef CONFIG_SYSFS
/* arch/sh/drivers/dma/dma-sysfs.c */
-extern int dma_create_sysfs_files(struct dma_channel *);
+extern int dma_create_sysfs_files(struct dma_channel *, struct dma_info *);
+extern void dma_remove_sysfs_files(struct dma_channel *, struct dma_info *);
+#else
+#define dma_create_sysfs_file(channel, info) do { } while (0)
+#define dma_remove_sysfs_file(channel, info) do { } while (0)
#endif
#ifdef CONFIG_PCI