cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

txx9dmac.h (7750B)


      1/* SPDX-License-Identifier: GPL-2.0-only */
      2/*
      3 * Driver for the TXx9 SoC DMA Controller
      4 *
      5 * Copyright (C) 2009 Atsushi Nemoto
      6 */
      7#ifndef TXX9DMAC_H
      8#define TXX9DMAC_H
      9
     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 can
     17 * be configured for memory-memory or device-memory transfer, but only
     18 * one channel can do alignment-free memory-memory transfer at a time
     19 * while the channel should occupy the FIFO buffer for effective
     20 * transfers.
     21 *
     22 * Instead of dynamically assign the FIFO buffer to channels, I chose
     23 * make one dedicated channel for memory-memory transfer.  The
     24 * dedicated channel is public.  Other channels are private and used
     25 * for slave transfer.  Some devices in the SoC are wired to certain
     26 * DMA channel.
     27 */
     28
     29#ifdef CONFIG_MACH_TX49XX
     30static inline bool txx9_dma_have_SMPCHN(void)
     31{
     32	return true;
     33}
     34#define TXX9_DMA_USE_SIMPLE_CHAIN
     35#else
     36static inline bool txx9_dma_have_SMPCHN(void)
     37{
     38	return false;
     39}
     40#endif
     41
     42#ifdef __LITTLE_ENDIAN
     43#ifdef CONFIG_MACH_TX49XX
     44#define CCR_LE	TXX9_DMA_CCR_LE
     45#define MCR_LE	0
     46#else
     47#define CCR_LE	0
     48#define MCR_LE	TXX9_DMA_MCR_LE
     49#endif
     50#else
     51#define CCR_LE	0
     52#define MCR_LE	0
     53#endif
     54
     55/*
     56 * Redefine this macro to handle differences between 32- and 64-bit
     57 * addressing, big vs. little endian, etc.
     58 */
     59#ifdef __BIG_ENDIAN
     60#define TXX9_DMA_REG32(name)		u32 __pad_##name; u32 name
     61#else
     62#define TXX9_DMA_REG32(name)		u32 name; u32 __pad_##name
     63#endif
     64
     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#else
     70	u64 CHAR;		/* Chain Address Register */
     71#endif
     72	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	0x00000080
    109#define TXX9_DMA_MCR_FIFUM(ch)	(0x00000008<<(ch))
    110#define TXX9_DMA_MCR_LE		0x00000004
    111#define TXX9_DMA_MCR_RPRT	0x00000002
    112#define TXX9_DMA_MCR_MSTEN	0x00000001
    113
    114/* bits for CCRn */
    115#define TXX9_DMA_CCR_IMMCHN	0x20000000
    116#define TXX9_DMA_CCR_USEXFSZ	0x10000000
    117#define TXX9_DMA_CCR_LE		0x08000000
    118#define TXX9_DMA_CCR_DBINH	0x04000000
    119#define TXX9_DMA_CCR_SBINH	0x02000000
    120#define TXX9_DMA_CCR_CHRST	0x01000000
    121#define TXX9_DMA_CCR_RVBYTE	0x00800000
    122#define TXX9_DMA_CCR_ACKPOL	0x00400000
    123#define TXX9_DMA_CCR_REQPL	0x00200000
    124#define TXX9_DMA_CCR_EGREQ	0x00100000
    125#define TXX9_DMA_CCR_CHDN	0x00080000
    126#define TXX9_DMA_CCR_DNCTL	0x00060000
    127#define TXX9_DMA_CCR_EXTRQ	0x00010000
    128#define TXX9_DMA_CCR_INTRQD	0x0000e000
    129#define TXX9_DMA_CCR_INTENE	0x00001000
    130#define TXX9_DMA_CCR_INTENC	0x00000800
    131#define TXX9_DMA_CCR_INTENT	0x00000400
    132#define TXX9_DMA_CCR_CHNEN	0x00000200
    133#define TXX9_DMA_CCR_XFACT	0x00000100
    134#define TXX9_DMA_CCR_SMPCHN	0x00000020
    135#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	0x00000002
    145#define TXX9_DMA_CCR_SNGAD	0x00000001
    146
    147/* bits for CSRn */
    148#define TXX9_DMA_CSR_CHNEN	0x00000400
    149#define TXX9_DMA_CSR_STLXFER	0x00000200
    150#define TXX9_DMA_CSR_XFACT	0x00000100
    151#define TXX9_DMA_CSR_ABCHC	0x00000080
    152#define TXX9_DMA_CSR_NCHNC	0x00000040
    153#define TXX9_DMA_CSR_NTRNFC	0x00000020
    154#define TXX9_DMA_CSR_EXTDN	0x00000010
    155#define TXX9_DMA_CSR_CFERR	0x00000008
    156#define TXX9_DMA_CSR_CHERR	0x00000004
    157#define TXX9_DMA_CSR_DESERR	0x00000002
    158#define TXX9_DMA_CSR_SORERR	0x00000001
    159
    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_CHAIN
    199/* 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#else
    204	u64 CHAR;
    205#endif
    206	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#else
    217#define txx9dmac_hwdesc txx9dmac_cregs
    218#define txx9dmac_hwdesc32 txx9dmac_cregs32
    219#endif
    220
    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_CHAIN
    236
    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	else
    280		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 */