1*552a848eSStefano Babic /* 2*552a848eSStefano Babic * Freescale i.MX28 APBH DMA 3*552a848eSStefano Babic * 4*552a848eSStefano Babic * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com> 5*552a848eSStefano Babic * on behalf of DENX Software Engineering GmbH 6*552a848eSStefano Babic * 7*552a848eSStefano Babic * Based on code from LTIB: 8*552a848eSStefano Babic * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved. 9*552a848eSStefano Babic * 10*552a848eSStefano Babic * SPDX-License-Identifier: GPL-2.0+ 11*552a848eSStefano Babic */ 12*552a848eSStefano Babic 13*552a848eSStefano Babic #ifndef __DMA_H__ 14*552a848eSStefano Babic #define __DMA_H__ 15*552a848eSStefano Babic 16*552a848eSStefano Babic #include <linux/list.h> 17*552a848eSStefano Babic #include <linux/compiler.h> 18*552a848eSStefano Babic 19*552a848eSStefano Babic #define DMA_PIO_WORDS 15 20*552a848eSStefano Babic #define MXS_DMA_ALIGNMENT ARCH_DMA_MINALIGN 21*552a848eSStefano Babic 22*552a848eSStefano Babic /* 23*552a848eSStefano Babic * MXS DMA channels 24*552a848eSStefano Babic */ 25*552a848eSStefano Babic #if defined(CONFIG_MX23) 26*552a848eSStefano Babic enum { 27*552a848eSStefano Babic MXS_DMA_CHANNEL_AHB_APBH_LCDIF = 0, 28*552a848eSStefano Babic MXS_DMA_CHANNEL_AHB_APBH_SSP0, 29*552a848eSStefano Babic MXS_DMA_CHANNEL_AHB_APBH_SSP1, 30*552a848eSStefano Babic MXS_DMA_CHANNEL_AHB_APBH_RESERVED0, 31*552a848eSStefano Babic MXS_DMA_CHANNEL_AHB_APBH_GPMI0, 32*552a848eSStefano Babic MXS_DMA_CHANNEL_AHB_APBH_GPMI1, 33*552a848eSStefano Babic MXS_DMA_CHANNEL_AHB_APBH_GPMI2, 34*552a848eSStefano Babic MXS_DMA_CHANNEL_AHB_APBH_GPMI3, 35*552a848eSStefano Babic MXS_MAX_DMA_CHANNELS, 36*552a848eSStefano Babic }; 37*552a848eSStefano Babic #elif defined(CONFIG_MX28) 38*552a848eSStefano Babic enum { 39*552a848eSStefano Babic MXS_DMA_CHANNEL_AHB_APBH_SSP0 = 0, 40*552a848eSStefano Babic MXS_DMA_CHANNEL_AHB_APBH_SSP1, 41*552a848eSStefano Babic MXS_DMA_CHANNEL_AHB_APBH_SSP2, 42*552a848eSStefano Babic MXS_DMA_CHANNEL_AHB_APBH_SSP3, 43*552a848eSStefano Babic MXS_DMA_CHANNEL_AHB_APBH_GPMI0, 44*552a848eSStefano Babic MXS_DMA_CHANNEL_AHB_APBH_GPMI1, 45*552a848eSStefano Babic MXS_DMA_CHANNEL_AHB_APBH_GPMI2, 46*552a848eSStefano Babic MXS_DMA_CHANNEL_AHB_APBH_GPMI3, 47*552a848eSStefano Babic MXS_DMA_CHANNEL_AHB_APBH_GPMI4, 48*552a848eSStefano Babic MXS_DMA_CHANNEL_AHB_APBH_GPMI5, 49*552a848eSStefano Babic MXS_DMA_CHANNEL_AHB_APBH_GPMI6, 50*552a848eSStefano Babic MXS_DMA_CHANNEL_AHB_APBH_GPMI7, 51*552a848eSStefano Babic MXS_DMA_CHANNEL_AHB_APBH_HSADC, 52*552a848eSStefano Babic MXS_DMA_CHANNEL_AHB_APBH_LCDIF, 53*552a848eSStefano Babic MXS_DMA_CHANNEL_AHB_APBH_RESERVED0, 54*552a848eSStefano Babic MXS_DMA_CHANNEL_AHB_APBH_RESERVED1, 55*552a848eSStefano Babic MXS_MAX_DMA_CHANNELS, 56*552a848eSStefano Babic }; 57*552a848eSStefano Babic #elif defined(CONFIG_MX6) || defined(CONFIG_MX7) 58*552a848eSStefano Babic enum { 59*552a848eSStefano Babic MXS_DMA_CHANNEL_AHB_APBH_GPMI0 = 0, 60*552a848eSStefano Babic MXS_DMA_CHANNEL_AHB_APBH_GPMI1, 61*552a848eSStefano Babic MXS_DMA_CHANNEL_AHB_APBH_GPMI2, 62*552a848eSStefano Babic MXS_DMA_CHANNEL_AHB_APBH_GPMI3, 63*552a848eSStefano Babic MXS_DMA_CHANNEL_AHB_APBH_GPMI4, 64*552a848eSStefano Babic MXS_DMA_CHANNEL_AHB_APBH_GPMI5, 65*552a848eSStefano Babic MXS_DMA_CHANNEL_AHB_APBH_GPMI6, 66*552a848eSStefano Babic MXS_DMA_CHANNEL_AHB_APBH_GPMI7, 67*552a848eSStefano Babic MXS_MAX_DMA_CHANNELS, 68*552a848eSStefano Babic }; 69*552a848eSStefano Babic #endif 70*552a848eSStefano Babic 71*552a848eSStefano Babic /* 72*552a848eSStefano Babic * MXS DMA hardware command. 73*552a848eSStefano Babic * 74*552a848eSStefano Babic * This structure describes the in-memory layout of an entire DMA command, 75*552a848eSStefano Babic * including space for the maximum number of PIO accesses. See the appropriate 76*552a848eSStefano Babic * reference manual for a detailed description of what these fields mean to the 77*552a848eSStefano Babic * DMA hardware. 78*552a848eSStefano Babic */ 79*552a848eSStefano Babic #define MXS_DMA_DESC_COMMAND_MASK 0x3 80*552a848eSStefano Babic #define MXS_DMA_DESC_COMMAND_OFFSET 0 81*552a848eSStefano Babic #define MXS_DMA_DESC_COMMAND_NO_DMAXFER 0x0 82*552a848eSStefano Babic #define MXS_DMA_DESC_COMMAND_DMA_WRITE 0x1 83*552a848eSStefano Babic #define MXS_DMA_DESC_COMMAND_DMA_READ 0x2 84*552a848eSStefano Babic #define MXS_DMA_DESC_COMMAND_DMA_SENSE 0x3 85*552a848eSStefano Babic #define MXS_DMA_DESC_CHAIN (1 << 2) 86*552a848eSStefano Babic #define MXS_DMA_DESC_IRQ (1 << 3) 87*552a848eSStefano Babic #define MXS_DMA_DESC_NAND_LOCK (1 << 4) 88*552a848eSStefano Babic #define MXS_DMA_DESC_NAND_WAIT_4_READY (1 << 5) 89*552a848eSStefano Babic #define MXS_DMA_DESC_DEC_SEM (1 << 6) 90*552a848eSStefano Babic #define MXS_DMA_DESC_WAIT4END (1 << 7) 91*552a848eSStefano Babic #define MXS_DMA_DESC_HALT_ON_TERMINATE (1 << 8) 92*552a848eSStefano Babic #define MXS_DMA_DESC_TERMINATE_FLUSH (1 << 9) 93*552a848eSStefano Babic #define MXS_DMA_DESC_PIO_WORDS_MASK (0xf << 12) 94*552a848eSStefano Babic #define MXS_DMA_DESC_PIO_WORDS_OFFSET 12 95*552a848eSStefano Babic #define MXS_DMA_DESC_BYTES_MASK (0xffff << 16) 96*552a848eSStefano Babic #define MXS_DMA_DESC_BYTES_OFFSET 16 97*552a848eSStefano Babic 98*552a848eSStefano Babic struct mxs_dma_cmd { 99*552a848eSStefano Babic unsigned long next; 100*552a848eSStefano Babic unsigned long data; 101*552a848eSStefano Babic union { 102*552a848eSStefano Babic dma_addr_t address; 103*552a848eSStefano Babic unsigned long alternate; 104*552a848eSStefano Babic }; 105*552a848eSStefano Babic unsigned long pio_words[DMA_PIO_WORDS]; 106*552a848eSStefano Babic }; 107*552a848eSStefano Babic 108*552a848eSStefano Babic /* 109*552a848eSStefano Babic * MXS DMA command descriptor. 110*552a848eSStefano Babic * 111*552a848eSStefano Babic * This structure incorporates an MXS DMA hardware command structure, along 112*552a848eSStefano Babic * with metadata. 113*552a848eSStefano Babic */ 114*552a848eSStefano Babic #define MXS_DMA_DESC_FIRST (1 << 0) 115*552a848eSStefano Babic #define MXS_DMA_DESC_LAST (1 << 1) 116*552a848eSStefano Babic #define MXS_DMA_DESC_READY (1 << 31) 117*552a848eSStefano Babic 118*552a848eSStefano Babic struct mxs_dma_desc { 119*552a848eSStefano Babic struct mxs_dma_cmd cmd; 120*552a848eSStefano Babic unsigned int flags; 121*552a848eSStefano Babic dma_addr_t address; 122*552a848eSStefano Babic void *buffer; 123*552a848eSStefano Babic struct list_head node; 124*552a848eSStefano Babic } __aligned(MXS_DMA_ALIGNMENT); 125*552a848eSStefano Babic 126*552a848eSStefano Babic /** 127*552a848eSStefano Babic * MXS DMA channel 128*552a848eSStefano Babic * 129*552a848eSStefano Babic * This structure represents a single DMA channel. The MXS platform code 130*552a848eSStefano Babic * maintains an array of these structures to represent every DMA channel in the 131*552a848eSStefano Babic * system (see mxs_dma_channels). 132*552a848eSStefano Babic */ 133*552a848eSStefano Babic #define MXS_DMA_FLAGS_IDLE 0 134*552a848eSStefano Babic #define MXS_DMA_FLAGS_BUSY (1 << 0) 135*552a848eSStefano Babic #define MXS_DMA_FLAGS_FREE 0 136*552a848eSStefano Babic #define MXS_DMA_FLAGS_ALLOCATED (1 << 16) 137*552a848eSStefano Babic #define MXS_DMA_FLAGS_VALID (1 << 31) 138*552a848eSStefano Babic 139*552a848eSStefano Babic struct mxs_dma_chan { 140*552a848eSStefano Babic const char *name; 141*552a848eSStefano Babic unsigned long dev; 142*552a848eSStefano Babic struct mxs_dma_device *dma; 143*552a848eSStefano Babic unsigned int flags; 144*552a848eSStefano Babic unsigned int active_num; 145*552a848eSStefano Babic unsigned int pending_num; 146*552a848eSStefano Babic struct list_head active; 147*552a848eSStefano Babic struct list_head done; 148*552a848eSStefano Babic }; 149*552a848eSStefano Babic 150*552a848eSStefano Babic struct mxs_dma_desc *mxs_dma_desc_alloc(void); 151*552a848eSStefano Babic void mxs_dma_desc_free(struct mxs_dma_desc *); 152*552a848eSStefano Babic int mxs_dma_desc_append(int channel, struct mxs_dma_desc *pdesc); 153*552a848eSStefano Babic 154*552a848eSStefano Babic int mxs_dma_go(int chan); 155*552a848eSStefano Babic void mxs_dma_init(void); 156*552a848eSStefano Babic int mxs_dma_init_channel(int chan); 157*552a848eSStefano Babic int mxs_dma_release(int chan); 158*552a848eSStefano Babic 159*552a848eSStefano Babic void mxs_dma_circ_start(int chan, struct mxs_dma_desc *pdesc); 160*552a848eSStefano Babic 161*552a848eSStefano Babic #endif /* __DMA_H__ */ 162