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

au1000_dma.h (11155B)


      1/*
      2 * BRIEF MODULE DESCRIPTION
      3 *	Defines for using and allocating DMA channels on the Alchemy
      4 *      Au1x00 MIPS processors.
      5 *
      6 * Copyright 2000, 2008 MontaVista Software Inc.
      7 * Author: MontaVista Software, Inc. <source@mvista.com>
      8 *
      9 *  This program is free software; you can redistribute  it and/or modify it
     10 *  under  the terms of  the GNU General  Public License as published by the
     11 *  Free Software Foundation;  either version 2 of the  License, or (at your
     12 *  option) any later version.
     13 *
     14 *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
     15 *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
     16 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
     17 *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
     18 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     19 *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
     20 *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
     21 *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
     22 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     23 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24 *
     25 *  You should have received a copy of the  GNU General Public License along
     26 *  with this program; if not, write  to the Free Software Foundation, Inc.,
     27 *  675 Mass Ave, Cambridge, MA 02139, USA.
     28 *
     29 */
     30#ifndef __ASM_AU1000_DMA_H
     31#define __ASM_AU1000_DMA_H
     32
     33#include <linux/io.h>		/* need byte IO */
     34#include <linux/spinlock.h>	/* And spinlocks */
     35#include <linux/delay.h>
     36
     37#define NUM_AU1000_DMA_CHANNELS 8
     38
     39/* DMA Channel Register Offsets */
     40#define DMA_MODE_SET		0x00000000
     41#define DMA_MODE_READ		DMA_MODE_SET
     42#define DMA_MODE_CLEAR		0x00000004
     43/* DMA Mode register bits follow */
     44#define DMA_DAH_MASK		(0x0f << 20)
     45#define DMA_DID_BIT		16
     46#define DMA_DID_MASK		(0x0f << DMA_DID_BIT)
     47#define DMA_DS			(1 << 15)
     48#define DMA_BE			(1 << 13)
     49#define DMA_DR			(1 << 12)
     50#define DMA_TS8			(1 << 11)
     51#define DMA_DW_BIT		9
     52#define DMA_DW_MASK		(0x03 << DMA_DW_BIT)
     53#define DMA_DW8			(0 << DMA_DW_BIT)
     54#define DMA_DW16		(1 << DMA_DW_BIT)
     55#define DMA_DW32		(2 << DMA_DW_BIT)
     56#define DMA_NC			(1 << 8)
     57#define DMA_IE			(1 << 7)
     58#define DMA_HALT		(1 << 6)
     59#define DMA_GO			(1 << 5)
     60#define DMA_AB			(1 << 4)
     61#define DMA_D1			(1 << 3)
     62#define DMA_BE1			(1 << 2)
     63#define DMA_D0			(1 << 1)
     64#define DMA_BE0			(1 << 0)
     65
     66#define DMA_PERIPHERAL_ADDR	0x00000008
     67#define DMA_BUFFER0_START	0x0000000C
     68#define DMA_BUFFER1_START	0x00000014
     69#define DMA_BUFFER0_COUNT	0x00000010
     70#define DMA_BUFFER1_COUNT	0x00000018
     71#define DMA_BAH_BIT	16
     72#define DMA_BAH_MASK	(0x0f << DMA_BAH_BIT)
     73#define DMA_COUNT_BIT	0
     74#define DMA_COUNT_MASK	(0xffff << DMA_COUNT_BIT)
     75
     76/* DMA Device IDs follow */
     77enum {
     78	DMA_ID_UART0_TX = 0,
     79	DMA_ID_UART0_RX,
     80	DMA_ID_GP04,
     81	DMA_ID_GP05,
     82	DMA_ID_AC97C_TX,
     83	DMA_ID_AC97C_RX,
     84	DMA_ID_UART3_TX,
     85	DMA_ID_UART3_RX,
     86	DMA_ID_USBDEV_EP0_RX,
     87	DMA_ID_USBDEV_EP0_TX,
     88	DMA_ID_USBDEV_EP2_TX,
     89	DMA_ID_USBDEV_EP3_TX,
     90	DMA_ID_USBDEV_EP4_RX,
     91	DMA_ID_USBDEV_EP5_RX,
     92	DMA_ID_I2S_TX,
     93	DMA_ID_I2S_RX,
     94	DMA_NUM_DEV
     95};
     96
     97/* DMA Device ID's for 2nd bank (AU1100) follow */
     98enum {
     99	DMA_ID_SD0_TX = 0,
    100	DMA_ID_SD0_RX,
    101	DMA_ID_SD1_TX,
    102	DMA_ID_SD1_RX,
    103	DMA_NUM_DEV_BANK2
    104};
    105
    106struct dma_chan {
    107	int dev_id;		/* this channel is allocated if >= 0, */
    108				/* free otherwise */
    109	void __iomem *io;
    110	const char *dev_str;
    111	int irq;
    112	void *irq_dev;
    113	unsigned int fifo_addr;
    114	unsigned int mode;
    115};
    116
    117/* These are in arch/mips/au1000/common/dma.c */
    118extern struct dma_chan au1000_dma_table[];
    119extern int request_au1000_dma(int dev_id,
    120			      const char *dev_str,
    121			      irq_handler_t irqhandler,
    122			      unsigned long irqflags,
    123			      void *irq_dev_id);
    124extern void free_au1000_dma(unsigned int dmanr);
    125extern int au1000_dma_read_proc(char *buf, char **start, off_t fpos,
    126				int length, int *eof, void *data);
    127extern void dump_au1000_dma_channel(unsigned int dmanr);
    128extern spinlock_t au1000_dma_spin_lock;
    129
    130static inline struct dma_chan *get_dma_chan(unsigned int dmanr)
    131{
    132	if (dmanr >= NUM_AU1000_DMA_CHANNELS ||
    133	    au1000_dma_table[dmanr].dev_id < 0)
    134		return NULL;
    135	return &au1000_dma_table[dmanr];
    136}
    137
    138static inline unsigned long claim_dma_lock(void)
    139{
    140	unsigned long flags;
    141
    142	spin_lock_irqsave(&au1000_dma_spin_lock, flags);
    143	return flags;
    144}
    145
    146static inline void release_dma_lock(unsigned long flags)
    147{
    148	spin_unlock_irqrestore(&au1000_dma_spin_lock, flags);
    149}
    150
    151/*
    152 * Set the DMA buffer enable bits in the mode register.
    153 */
    154static inline void enable_dma_buffer0(unsigned int dmanr)
    155{
    156	struct dma_chan *chan = get_dma_chan(dmanr);
    157
    158	if (!chan)
    159		return;
    160	__raw_writel(DMA_BE0, chan->io + DMA_MODE_SET);
    161}
    162
    163static inline void enable_dma_buffer1(unsigned int dmanr)
    164{
    165	struct dma_chan *chan = get_dma_chan(dmanr);
    166
    167	if (!chan)
    168		return;
    169	__raw_writel(DMA_BE1, chan->io + DMA_MODE_SET);
    170}
    171static inline void enable_dma_buffers(unsigned int dmanr)
    172{
    173	struct dma_chan *chan = get_dma_chan(dmanr);
    174
    175	if (!chan)
    176		return;
    177	__raw_writel(DMA_BE0 | DMA_BE1, chan->io + DMA_MODE_SET);
    178}
    179
    180static inline void start_dma(unsigned int dmanr)
    181{
    182	struct dma_chan *chan = get_dma_chan(dmanr);
    183
    184	if (!chan)
    185		return;
    186	__raw_writel(DMA_GO, chan->io + DMA_MODE_SET);
    187}
    188
    189#define DMA_HALT_POLL 0x5000
    190
    191static inline void halt_dma(unsigned int dmanr)
    192{
    193	struct dma_chan *chan = get_dma_chan(dmanr);
    194	int i;
    195
    196	if (!chan)
    197		return;
    198	__raw_writel(DMA_GO, chan->io + DMA_MODE_CLEAR);
    199
    200	/* Poll the halt bit */
    201	for (i = 0; i < DMA_HALT_POLL; i++)
    202		if (__raw_readl(chan->io + DMA_MODE_READ) & DMA_HALT)
    203			break;
    204	if (i == DMA_HALT_POLL)
    205		printk(KERN_INFO "halt_dma: HALT poll expired!\n");
    206}
    207
    208static inline void disable_dma(unsigned int dmanr)
    209{
    210	struct dma_chan *chan = get_dma_chan(dmanr);
    211
    212	if (!chan)
    213		return;
    214
    215	halt_dma(dmanr);
    216
    217	/* Now we can disable the buffers */
    218	__raw_writel(~DMA_GO, chan->io + DMA_MODE_CLEAR);
    219}
    220
    221static inline int dma_halted(unsigned int dmanr)
    222{
    223	struct dma_chan *chan = get_dma_chan(dmanr);
    224
    225	if (!chan)
    226		return 1;
    227	return (__raw_readl(chan->io + DMA_MODE_READ) & DMA_HALT) ? 1 : 0;
    228}
    229
    230/* Initialize a DMA channel. */
    231static inline void init_dma(unsigned int dmanr)
    232{
    233	struct dma_chan *chan = get_dma_chan(dmanr);
    234	u32 mode;
    235
    236	if (!chan)
    237		return;
    238
    239	disable_dma(dmanr);
    240
    241	/* Set device FIFO address */
    242	__raw_writel(CPHYSADDR(chan->fifo_addr), chan->io + DMA_PERIPHERAL_ADDR);
    243
    244	mode = chan->mode | (chan->dev_id << DMA_DID_BIT);
    245	if (chan->irq)
    246		mode |= DMA_IE;
    247
    248	__raw_writel(~mode, chan->io + DMA_MODE_CLEAR);
    249	__raw_writel(mode,	 chan->io + DMA_MODE_SET);
    250}
    251
    252/*
    253 * Set mode for a specific DMA channel
    254 */
    255static inline void set_dma_mode(unsigned int dmanr, unsigned int mode)
    256{
    257	struct dma_chan *chan = get_dma_chan(dmanr);
    258
    259	if (!chan)
    260		return;
    261	/*
    262	 * set_dma_mode is only allowed to change endianess, direction,
    263	 * transfer size, device FIFO width, and coherency settings.
    264	 * Make sure anything else is masked off.
    265	 */
    266	mode &= (DMA_BE | DMA_DR | DMA_TS8 | DMA_DW_MASK | DMA_NC);
    267	chan->mode &= ~(DMA_BE | DMA_DR | DMA_TS8 | DMA_DW_MASK | DMA_NC);
    268	chan->mode |= mode;
    269}
    270
    271static inline unsigned int get_dma_mode(unsigned int dmanr)
    272{
    273	struct dma_chan *chan = get_dma_chan(dmanr);
    274
    275	if (!chan)
    276		return 0;
    277	return chan->mode;
    278}
    279
    280static inline int get_dma_active_buffer(unsigned int dmanr)
    281{
    282	struct dma_chan *chan = get_dma_chan(dmanr);
    283
    284	if (!chan)
    285		return -1;
    286	return (__raw_readl(chan->io + DMA_MODE_READ) & DMA_AB) ? 1 : 0;
    287}
    288
    289/*
    290 * Set the device FIFO address for a specific DMA channel - only
    291 * applicable to GPO4 and GPO5. All the other devices have fixed
    292 * FIFO addresses.
    293 */
    294static inline void set_dma_fifo_addr(unsigned int dmanr, unsigned int a)
    295{
    296	struct dma_chan *chan = get_dma_chan(dmanr);
    297
    298	if (!chan)
    299		return;
    300
    301	if (chan->mode & DMA_DS)	/* second bank of device IDs */
    302		return;
    303
    304	if (chan->dev_id != DMA_ID_GP04 && chan->dev_id != DMA_ID_GP05)
    305		return;
    306
    307	__raw_writel(CPHYSADDR(a), chan->io + DMA_PERIPHERAL_ADDR);
    308}
    309
    310/*
    311 * Clear the DMA buffer done bits in the mode register.
    312 */
    313static inline void clear_dma_done0(unsigned int dmanr)
    314{
    315	struct dma_chan *chan = get_dma_chan(dmanr);
    316
    317	if (!chan)
    318		return;
    319	__raw_writel(DMA_D0, chan->io + DMA_MODE_CLEAR);
    320}
    321
    322static inline void clear_dma_done1(unsigned int dmanr)
    323{
    324	struct dma_chan *chan = get_dma_chan(dmanr);
    325
    326	if (!chan)
    327		return;
    328	__raw_writel(DMA_D1, chan->io + DMA_MODE_CLEAR);
    329}
    330
    331/*
    332 * This does nothing - not applicable to Au1000 DMA.
    333 */
    334static inline void set_dma_page(unsigned int dmanr, char pagenr)
    335{
    336}
    337
    338/*
    339 * Set Buffer 0 transfer address for specific DMA channel.
    340 */
    341static inline void set_dma_addr0(unsigned int dmanr, unsigned int a)
    342{
    343	struct dma_chan *chan = get_dma_chan(dmanr);
    344
    345	if (!chan)
    346		return;
    347	__raw_writel(a, chan->io + DMA_BUFFER0_START);
    348}
    349
    350/*
    351 * Set Buffer 1 transfer address for specific DMA channel.
    352 */
    353static inline void set_dma_addr1(unsigned int dmanr, unsigned int a)
    354{
    355	struct dma_chan *chan = get_dma_chan(dmanr);
    356
    357	if (!chan)
    358		return;
    359	__raw_writel(a, chan->io + DMA_BUFFER1_START);
    360}
    361
    362
    363/*
    364 * Set Buffer 0 transfer size (max 64k) for a specific DMA channel.
    365 */
    366static inline void set_dma_count0(unsigned int dmanr, unsigned int count)
    367{
    368	struct dma_chan *chan = get_dma_chan(dmanr);
    369
    370	if (!chan)
    371		return;
    372	count &= DMA_COUNT_MASK;
    373	__raw_writel(count, chan->io + DMA_BUFFER0_COUNT);
    374}
    375
    376/*
    377 * Set Buffer 1 transfer size (max 64k) for a specific DMA channel.
    378 */
    379static inline void set_dma_count1(unsigned int dmanr, unsigned int count)
    380{
    381	struct dma_chan *chan = get_dma_chan(dmanr);
    382
    383	if (!chan)
    384		return;
    385	count &= DMA_COUNT_MASK;
    386	__raw_writel(count, chan->io + DMA_BUFFER1_COUNT);
    387}
    388
    389/*
    390 * Set both buffer transfer sizes (max 64k) for a specific DMA channel.
    391 */
    392static inline void set_dma_count(unsigned int dmanr, unsigned int count)
    393{
    394	struct dma_chan *chan = get_dma_chan(dmanr);
    395
    396	if (!chan)
    397		return;
    398	count &= DMA_COUNT_MASK;
    399	__raw_writel(count, chan->io + DMA_BUFFER0_COUNT);
    400	__raw_writel(count, chan->io + DMA_BUFFER1_COUNT);
    401}
    402
    403/*
    404 * Returns which buffer has its done bit set in the mode register.
    405 * Returns -1 if neither or both done bits set.
    406 */
    407static inline unsigned int get_dma_buffer_done(unsigned int dmanr)
    408{
    409	struct dma_chan *chan = get_dma_chan(dmanr);
    410
    411	if (!chan)
    412		return 0;
    413	return __raw_readl(chan->io + DMA_MODE_READ) & (DMA_D0 | DMA_D1);
    414}
    415
    416
    417/*
    418 * Returns the DMA channel's Buffer Done IRQ number.
    419 */
    420static inline int get_dma_done_irq(unsigned int dmanr)
    421{
    422	struct dma_chan *chan = get_dma_chan(dmanr);
    423
    424	if (!chan)
    425		return -1;
    426	return chan->irq;
    427}
    428
    429/*
    430 * Get DMA residue count. Returns the number of _bytes_ left to transfer.
    431 */
    432static inline int get_dma_residue(unsigned int dmanr)
    433{
    434	int curBufCntReg, count;
    435	struct dma_chan *chan = get_dma_chan(dmanr);
    436
    437	if (!chan)
    438		return 0;
    439
    440	curBufCntReg = (__raw_readl(chan->io + DMA_MODE_READ) & DMA_AB) ?
    441	    DMA_BUFFER1_COUNT : DMA_BUFFER0_COUNT;
    442
    443	count = __raw_readl(chan->io + curBufCntReg) & DMA_COUNT_MASK;
    444
    445	if ((chan->mode & DMA_DW_MASK) == DMA_DW16)
    446		count <<= 1;
    447	else if ((chan->mode & DMA_DW_MASK) == DMA_DW32)
    448		count <<= 2;
    449
    450	return count;
    451}
    452
    453#endif /* __ASM_AU1000_DMA_H */