brintos

brintos / linux-shallow public Read only

0
0
Text · 7.6 KiB · aa53eaf Raw
305 lines · c
1/* SPDX-License-Identifier: GPL-2.0-only */2/*3 * Driver for the TXx9 SoC DMA Controller4 *5 * Copyright (C) 2009 Atsushi Nemoto6 */7#ifndef TXX9DMAC_H8#define TXX9DMAC_H9 10#include <linux/dmaengine.h>11#include <asm/txx9/dmac.h>12 13/*14 * Design Notes:15 *16 * This DMAC have four channels and one FIFO buffer.  Each channel can17 * be configured for memory-memory or device-memory transfer, but only18 * one channel can do alignment-free memory-memory transfer at a time19 * while the channel should occupy the FIFO buffer for effective20 * transfers.21 *22 * Instead of dynamically assign the FIFO buffer to channels, I chose23 * make one dedicated channel for memory-memory transfer.  The24 * dedicated channel is public.  Other channels are private and used25 * for slave transfer.  Some devices in the SoC are wired to certain26 * DMA channel.27 */28 29#ifdef CONFIG_MACH_TX49XX30static inline bool txx9_dma_have_SMPCHN(void)31{32	return true;33}34#define TXX9_DMA_USE_SIMPLE_CHAIN35#else36static inline bool txx9_dma_have_SMPCHN(void)37{38	return false;39}40#endif41 42#ifdef __LITTLE_ENDIAN43#ifdef CONFIG_MACH_TX49XX44#define CCR_LE	TXX9_DMA_CCR_LE45#define MCR_LE	046#else47#define CCR_LE	048#define MCR_LE	TXX9_DMA_MCR_LE49#endif50#else51#define CCR_LE	052#define MCR_LE	053#endif54 55/*56 * Redefine this macro to handle differences between 32- and 64-bit57 * addressing, big vs. little endian, etc.58 */59#ifdef __BIG_ENDIAN60#define TXX9_DMA_REG32(name)		u32 __pad_##name; u32 name61#else62#define TXX9_DMA_REG32(name)		u32 name; u32 __pad_##name63#endif64 65/* Hardware register definitions. */66struct txx9dmac_cregs {67#if defined(CONFIG_32BIT) && !defined(CONFIG_PHYS_ADDR_T_64BIT)68	TXX9_DMA_REG32(CHAR);	/* Chain Address Register */69#else70	u64 CHAR;		/* Chain Address Register */71#endif72	u64 SAR;		/* Source Address Register */73	u64 DAR;		/* Destination Address Register */74	TXX9_DMA_REG32(CNTR);	/* Count Register */75	TXX9_DMA_REG32(SAIR);	/* Source Address Increment Register */76	TXX9_DMA_REG32(DAIR);	/* Destination Address Increment Register */77	TXX9_DMA_REG32(CCR);	/* Channel Control Register */78	TXX9_DMA_REG32(CSR);	/* Channel Status Register */79};80struct txx9dmac_cregs32 {81	u32 CHAR;82	u32 SAR;83	u32 DAR;84	u32 CNTR;85	u32 SAIR;86	u32 DAIR;87	u32 CCR;88	u32 CSR;89};90 91struct txx9dmac_regs {92	/* per-channel registers */93	struct txx9dmac_cregs	CHAN[TXX9_DMA_MAX_NR_CHANNELS];94	u64	__pad[9];95	u64	MFDR;		/* Memory Fill Data Register */96	TXX9_DMA_REG32(MCR);	/* Master Control Register */97};98struct txx9dmac_regs32 {99	struct txx9dmac_cregs32	CHAN[TXX9_DMA_MAX_NR_CHANNELS];100	u32	__pad[9];101	u32	MFDR;102	u32	MCR;103};104 105/* bits for MCR */106#define TXX9_DMA_MCR_EIS(ch)	(0x10000000<<(ch))107#define TXX9_DMA_MCR_DIS(ch)	(0x01000000<<(ch))108#define TXX9_DMA_MCR_RSFIF	0x00000080109#define TXX9_DMA_MCR_FIFUM(ch)	(0x00000008<<(ch))110#define TXX9_DMA_MCR_LE		0x00000004111#define TXX9_DMA_MCR_RPRT	0x00000002112#define TXX9_DMA_MCR_MSTEN	0x00000001113 114/* bits for CCRn */115#define TXX9_DMA_CCR_IMMCHN	0x20000000116#define TXX9_DMA_CCR_USEXFSZ	0x10000000117#define TXX9_DMA_CCR_LE		0x08000000118#define TXX9_DMA_CCR_DBINH	0x04000000119#define TXX9_DMA_CCR_SBINH	0x02000000120#define TXX9_DMA_CCR_CHRST	0x01000000121#define TXX9_DMA_CCR_RVBYTE	0x00800000122#define TXX9_DMA_CCR_ACKPOL	0x00400000123#define TXX9_DMA_CCR_REQPL	0x00200000124#define TXX9_DMA_CCR_EGREQ	0x00100000125#define TXX9_DMA_CCR_CHDN	0x00080000126#define TXX9_DMA_CCR_DNCTL	0x00060000127#define TXX9_DMA_CCR_EXTRQ	0x00010000128#define TXX9_DMA_CCR_INTRQD	0x0000e000129#define TXX9_DMA_CCR_INTENE	0x00001000130#define TXX9_DMA_CCR_INTENC	0x00000800131#define TXX9_DMA_CCR_INTENT	0x00000400132#define TXX9_DMA_CCR_CHNEN	0x00000200133#define TXX9_DMA_CCR_XFACT	0x00000100134#define TXX9_DMA_CCR_SMPCHN	0x00000020135#define TXX9_DMA_CCR_XFSZ(order)	(((order) << 2) & 0x0000001c)136#define TXX9_DMA_CCR_XFSZ_1	TXX9_DMA_CCR_XFSZ(0)137#define TXX9_DMA_CCR_XFSZ_2	TXX9_DMA_CCR_XFSZ(1)138#define TXX9_DMA_CCR_XFSZ_4	TXX9_DMA_CCR_XFSZ(2)139#define TXX9_DMA_CCR_XFSZ_8	TXX9_DMA_CCR_XFSZ(3)140#define TXX9_DMA_CCR_XFSZ_X4	TXX9_DMA_CCR_XFSZ(4)141#define TXX9_DMA_CCR_XFSZ_X8	TXX9_DMA_CCR_XFSZ(5)142#define TXX9_DMA_CCR_XFSZ_X16	TXX9_DMA_CCR_XFSZ(6)143#define TXX9_DMA_CCR_XFSZ_X32	TXX9_DMA_CCR_XFSZ(7)144#define TXX9_DMA_CCR_MEMIO	0x00000002145#define TXX9_DMA_CCR_SNGAD	0x00000001146 147/* bits for CSRn */148#define TXX9_DMA_CSR_CHNEN	0x00000400149#define TXX9_DMA_CSR_STLXFER	0x00000200150#define TXX9_DMA_CSR_XFACT	0x00000100151#define TXX9_DMA_CSR_ABCHC	0x00000080152#define TXX9_DMA_CSR_NCHNC	0x00000040153#define TXX9_DMA_CSR_NTRNFC	0x00000020154#define TXX9_DMA_CSR_EXTDN	0x00000010155#define TXX9_DMA_CSR_CFERR	0x00000008156#define TXX9_DMA_CSR_CHERR	0x00000004157#define TXX9_DMA_CSR_DESERR	0x00000002158#define TXX9_DMA_CSR_SORERR	0x00000001159 160struct txx9dmac_chan {161	struct dma_chan		chan;162	struct dma_device	dma;163	struct txx9dmac_dev	*ddev;164	void __iomem		*ch_regs;165	struct tasklet_struct	tasklet;166	int			irq;167	u32			ccr;168 169	spinlock_t		lock;170 171	/* these other elements are all protected by lock */172	struct list_head	active_list;173	struct list_head	queue;174	struct list_head	free_list;175 176	unsigned int		descs_allocated;177};178 179struct txx9dmac_dev {180	void __iomem		*regs;181	struct tasklet_struct	tasklet;182	int			irq;183	struct txx9dmac_chan	*chan[TXX9_DMA_MAX_NR_CHANNELS];184	bool			have_64bit_regs;185	unsigned int		descsize;186};187 188static inline bool __is_dmac64(const struct txx9dmac_dev *ddev)189{190	return ddev->have_64bit_regs;191}192 193static inline bool is_dmac64(const struct txx9dmac_chan *dc)194{195	return __is_dmac64(dc->ddev);196}197 198#ifdef TXX9_DMA_USE_SIMPLE_CHAIN199/* Hardware descriptor definition. (for simple-chain) */200struct txx9dmac_hwdesc {201#if defined(CONFIG_32BIT) && !defined(CONFIG_PHYS_ADDR_T_64BIT)202	TXX9_DMA_REG32(CHAR);203#else204	u64 CHAR;205#endif206	u64 SAR;207	u64 DAR;208	TXX9_DMA_REG32(CNTR);209};210struct txx9dmac_hwdesc32 {211	u32 CHAR;212	u32 SAR;213	u32 DAR;214	u32 CNTR;215};216#else217#define txx9dmac_hwdesc txx9dmac_cregs218#define txx9dmac_hwdesc32 txx9dmac_cregs32219#endif220 221struct txx9dmac_desc {222	/* FIRST values the hardware uses */223	union {224		struct txx9dmac_hwdesc hwdesc;225		struct txx9dmac_hwdesc32 hwdesc32;226	};227 228	/* THEN values for driver housekeeping */229	struct list_head		desc_node ____cacheline_aligned;230	struct list_head		tx_list;231	struct dma_async_tx_descriptor	txd;232	size_t				len;233};234 235#ifdef TXX9_DMA_USE_SIMPLE_CHAIN236 237static inline bool txx9dmac_chan_INTENT(struct txx9dmac_chan *dc)238{239	return (dc->ccr & TXX9_DMA_CCR_INTENT) != 0;240}241 242static inline void txx9dmac_chan_set_INTENT(struct txx9dmac_chan *dc)243{244	dc->ccr |= TXX9_DMA_CCR_INTENT;245}246 247static inline void txx9dmac_desc_set_INTENT(struct txx9dmac_dev *ddev,248					    struct txx9dmac_desc *desc)249{250}251 252static inline void txx9dmac_chan_set_SMPCHN(struct txx9dmac_chan *dc)253{254	dc->ccr |= TXX9_DMA_CCR_SMPCHN;255}256 257static inline void txx9dmac_desc_set_nosimple(struct txx9dmac_dev *ddev,258					      struct txx9dmac_desc *desc,259					      u32 sair, u32 dair, u32 ccr)260{261}262 263#else /* TXX9_DMA_USE_SIMPLE_CHAIN */264 265static inline bool txx9dmac_chan_INTENT(struct txx9dmac_chan *dc)266{267	return true;268}269 270static void txx9dmac_chan_set_INTENT(struct txx9dmac_chan *dc)271{272}273 274static inline void txx9dmac_desc_set_INTENT(struct txx9dmac_dev *ddev,275					    struct txx9dmac_desc *desc)276{277	if (__is_dmac64(ddev))278		desc->hwdesc.CCR |= TXX9_DMA_CCR_INTENT;279	else280		desc->hwdesc32.CCR |= TXX9_DMA_CCR_INTENT;281}282 283static inline void txx9dmac_chan_set_SMPCHN(struct txx9dmac_chan *dc)284{285}286 287static inline void txx9dmac_desc_set_nosimple(struct txx9dmac_dev *ddev,288					      struct txx9dmac_desc *desc,289					      u32 sai, u32 dai, u32 ccr)290{291	if (__is_dmac64(ddev)) {292		desc->hwdesc.SAIR = sai;293		desc->hwdesc.DAIR = dai;294		desc->hwdesc.CCR = ccr;295	} else {296		desc->hwdesc32.SAIR = sai;297		desc->hwdesc32.DAIR = dai;298		desc->hwdesc32.CCR = ccr;299	}300}301 302#endif /* TXX9_DMA_USE_SIMPLE_CHAIN */303 304#endif /* TXX9DMAC_H */305