From 0d831770b154a057562236e8cf50905c8f1ae1b0 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 16 Jan 2006 22:14:09 -0800 Subject: [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 Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-sh/bus-sh.h | 1 + include/asm-sh/cpu-sh3/dma.h | 31 +++++++++++++++++++++++++- include/asm-sh/cpu-sh4/dma.h | 52 +++++++++++++++++++++++++++++++++++--------- include/asm-sh/dma-mapping.h | 25 +++++++++++---------- include/asm-sh/dma.h | 14 +++++++++--- 5 files changed, 97 insertions(+), 26 deletions(-) (limited to 'include') diff --git a/include/asm-sh/bus-sh.h b/include/asm-sh/bus-sh.h index 83c5d2f..e42d63b 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 b972e71..954801b 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 e2b91ad..0dfe61f 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 d3fa5c2..48f1f42 100644 --- a/include/asm-sh/dma-mapping.h +++ b/include/asm-sh/dma-mapping.h @@ -4,6 +4,7 @@ #include #include #include +#include #include 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 8e94360..a118a0d4 100644 --- a/include/asm-sh/dma.h +++ b/include/asm-sh/dma.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -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 -- cgit v1.1