388 lines
11 KiB
C
388 lines
11 KiB
C
#ifndef _DW_DMAC_H_
|
|
#define _DW_DMAC_H_
|
|
|
|
#include "hal/dma.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/*! max dmac hardware channel
|
|
*/
|
|
#define DW_DMAC_MAX_DMAC_CHN 4
|
|
/*! max dmac hardware channel mask
|
|
*/
|
|
#define DW_DMAC_MAX_DMAC_CHN_MASK 0xF
|
|
|
|
/**
|
|
* @brief DMAC controller (IP)
|
|
*/
|
|
struct dw_dmac_hw_ch {
|
|
__IO uint32 SARL;
|
|
__IO uint32 SARH;
|
|
__IO uint32 DARL;
|
|
__IO uint32 DARH;
|
|
__IO uint32 FIFO0[2]; //LLPL,LLPH, NO USE
|
|
__IO uint32 CTLL;
|
|
__IO uint32 CTLH;
|
|
__IO uint32 FIFO1[8]; //SSTATL,SSTATH,DSTATL,DSTATH,SSTATARL,SSTATARH,DSTATARL,DSTATARH
|
|
__IO uint32 CFGL;
|
|
__IO uint32 CFGH;
|
|
__IO uint32 SGRL;
|
|
__IO uint32 SGRH;
|
|
__IO uint32 DSRL;
|
|
__IO uint32 DSRH;
|
|
};
|
|
|
|
/**
|
|
* @brief DMAC
|
|
*/
|
|
struct hgdma_dw_hw {
|
|
struct dw_dmac_hw_ch CH[4];
|
|
__IO uint32 FIFO0[22*4];
|
|
__IO uint32 RawTfrL;
|
|
__IO uint32 RawTfrH;
|
|
__IO uint32 RawBlockL;
|
|
__IO uint32 RawBlockH;
|
|
__IO uint32 RawSrcTranL;
|
|
__IO uint32 RawSrcTranH;
|
|
__IO uint32 RawDstTranL;
|
|
__IO uint32 RawDstTranH;
|
|
__IO uint32 RawErrL;
|
|
__IO uint32 RawErrH;
|
|
__IO uint32 FIFO1[5*2];
|
|
__IO uint32 MaskTfrL;
|
|
__IO uint32 MaskTfrH;
|
|
__IO uint32 MaskBlockL;
|
|
__IO uint32 MaskBlockH;
|
|
__IO uint32 MaskSrcTranL;
|
|
__IO uint32 MaskSrcTranH;
|
|
__IO uint32 MaskDstTranL;
|
|
__IO uint32 MaskDstTranH;
|
|
__IO uint32 MaskErrL;
|
|
__IO uint32 MaskErrH;
|
|
__IO uint32 ClearTfrL;
|
|
__IO uint32 ClearTfrH;
|
|
__IO uint32 ClearBlockL;
|
|
__IO uint32 ClearBlockH;
|
|
__IO uint32 ClearSrcTranL;
|
|
__IO uint32 ClearSrcTranH;
|
|
__IO uint32 ClearDstTranL;
|
|
__IO uint32 ClearDstTranH;
|
|
__IO uint32 ClearErrL;
|
|
__IO uint32 ClearErrH;
|
|
__IO uint32 FIFO2[2];
|
|
__IO uint32 ReqSrcRegL;
|
|
__IO uint32 ReqSrcRegH;
|
|
__IO uint32 ReqDstRegL;
|
|
__IO uint32 ReqDstRegH;
|
|
__IO uint32 SglReqSrcRegL;
|
|
__IO uint32 SglReqSrcRegH;
|
|
__IO uint32 SglReqDstRegL;
|
|
__IO uint32 SglReqDstRegH;
|
|
__IO uint32 LstSrcRegL;
|
|
__IO uint32 LstSrcRegH;
|
|
__IO uint32 LstDstRegL;
|
|
__IO uint32 LstDstRegH;
|
|
__IO uint32 DmaCfgRegL;
|
|
__IO uint32 DmaCfgRegH;
|
|
__IO uint32 ChEnRegL;
|
|
__IO uint32 ChEnRegH;
|
|
__IO uint32 FIFO3[2];
|
|
__IO uint32 DmaTestRegL;
|
|
__IO uint32 DmaTestRegH;
|
|
};
|
|
|
|
struct hgdma_dw {
|
|
struct dma_device dev;
|
|
struct hgdma_dw_hw *hw;
|
|
uint32 irq_num;
|
|
uint32 opened;
|
|
os_semaphore_t mem_chn;
|
|
os_semaphore_t dev_chn;
|
|
os_mutex_t dev_mutex;
|
|
dma_irq_hdl irq_hdl[DW_DMAC_MAX_DMAC_CHN];
|
|
uint32 irq_data[DW_DMAC_MAX_DMAC_CHN];
|
|
uint32 state[DW_DMAC_MAX_DMAC_CHN];
|
|
uint32 chn_used_flag;
|
|
};
|
|
|
|
/** @brief DW DMAC register constant table definition
|
|
* @{
|
|
*/
|
|
|
|
/***** DW_PARAMS Register *****/
|
|
/*! number of channels
|
|
*/
|
|
#define DW_DMAC_PARAMS_NR_CHAN 4
|
|
/*! number of AHB masters
|
|
*/
|
|
#define DW_DMAC_PARAMS_NR_MASTER 2
|
|
|
|
|
|
/***** DWC_PARAMS Register *****/
|
|
/*! multi block transfer
|
|
*/
|
|
#define DW_DMACC_PARAMS_MBLK_EN 11
|
|
|
|
|
|
/***** CTLx Register *****/
|
|
/*! irqs enabled
|
|
*/
|
|
#define DW_DMAC_CTLL_INT_EN (1UL << 0)
|
|
/*! The size of each element of destination transmission.
|
|
*/
|
|
#define DW_DMAC_CTLL_DST_WIDTH(n) (((n)&0x7) << 1)
|
|
/*! The size of each element of source transmission.
|
|
*/
|
|
#define DW_DMAC_CTLL_SRC_WIDTH(n) (((n)&0x7) << 4)
|
|
/*! Indicates destination address how to change on every source transfer.
|
|
*/
|
|
#define DW_DMAC_CTLL_DST_DIR(n) (((n)&0x3) << 7)
|
|
/*! Indicates source address how to change on every source transfer.
|
|
*/
|
|
#define DW_DMAC_CTLL_SRC_DIR(n) (((n)&0x3) << 9)
|
|
/*! Number of data items to be written to de destination every time.
|
|
*/
|
|
#define DW_DMAC_CTLL_DST_MSIZE(n) (((n)&0x7) << 11)
|
|
/*! Number of data items to be read from the source every time.
|
|
*/
|
|
#define DW_DMAC_CTLL_SRC_MSIZE(n) (((n)&0x7) << 14)
|
|
/*! src gather
|
|
*/
|
|
#define DW_DMAC_CTLL_S_GATH_EN (1UL << 17)
|
|
/* dst scatter
|
|
*/
|
|
//#define DW_DMAC_CTLL_D_SCAT_EN (1UL << 18)
|
|
/*! Transfer type and flow control.
|
|
*/
|
|
#define DW_DMAC_CTLL_FC(n) (((n)&0x7) << 20)
|
|
/*! dst master select : 1 for memory, 0 for peripherals
|
|
*/
|
|
#define DW_DMAC_CTLL_DMS(n) (((n)&0x3) << 23)
|
|
/*! src master select : 1 for memory, 0 for peripherals
|
|
*/
|
|
#define DW_DMAC_CTLL_SMS(n) (((n)&0x3) << 25)
|
|
/* dest block chain
|
|
*/
|
|
//#define DW_DMAC_CTLL_LLP_D_EN (1UL << 27)
|
|
/* src block chain
|
|
*/
|
|
//#define DW_DMAC_CTLL_LLP_S_EN (1UL << 28)
|
|
|
|
|
|
/***** CTL_HI Register *****/
|
|
/*! Block transfer done
|
|
*/
|
|
#define DW_DMAC_CTLH_DONE (0x00001000)
|
|
/*! Block transfer size. The max block size is 4095.
|
|
*/
|
|
#define DW_DMAC_CTLH_BLOCK_TS_MASK (0x00000FFF)
|
|
|
|
|
|
/***** CFG_LO Register *****/
|
|
/*! Channel priority mask
|
|
*/
|
|
#define DW_DMAC_CFGL_CH_PRIOR_MASK (0x7UL << 5)
|
|
/*! Channel priority
|
|
*/
|
|
#define DW_DMAC_CFGL_CH_PRIOR(n) (((n)&0x7) << 5)
|
|
/*! Channle Suspend. Suspends all DMA data transfers from the source until this
|
|
* bit is cleared.
|
|
*/
|
|
#define DW_DMAC_CFGL_CH_SUSP (1UL << 8)
|
|
/*! Indicates if there is data left in the channel FIFO.
|
|
*/
|
|
#define DW_DMAC_CFGL_FIFO_EMPTY (1UL << 9)
|
|
/*! Destination software or hardware handshaking select.
|
|
*/
|
|
#define DW_DMAC_CFGL_HS_DST (1UL << 10)
|
|
/*! Source software or hardware handshaking select.
|
|
*/
|
|
#define DW_DMAC_CFGL_HS_SRC (1UL << 11)
|
|
//#define DW_DMAC_CFGL_LOCK_CH_LEVEL(n) (((n)&0x3) << 12)
|
|
//#define DW_DMAC_CFGL_LOCK_BUS_LEVEL(n) (((n)&0x3) << 14)
|
|
//#define DW_DMAC_CFGL_LOCK_CH (1UL << 16)
|
|
//#define DW_DMAC_CFGL_LOCK_BUS (1UL << 17)
|
|
/*! Destination handshaking interface polarity.
|
|
*/
|
|
#define DW_DMAC_CFGL_HS_DST_POL (1UL << 18)
|
|
/*! Source handshaking interface polarity.
|
|
*/
|
|
#define DW_DMAC_CFGL_HS_SRC_POL (1UL << 19)
|
|
/*! Maximum AMBA burst length that is used for DMA transfers on this channel.
|
|
*/
|
|
#define DW_DMAC_CFGL_MAX_BURST(n) (((n)&0x2FF) << 20)
|
|
/*! Automatic source reload.
|
|
*/
|
|
#define DW_DMAC_CFGL_RELOAD_SAR (1UL << 30)
|
|
/*! Automatic desination reload.
|
|
*/
|
|
#define DW_DMAC_CFGL_RELOAD_DAR (1UL << 31)
|
|
|
|
|
|
/***** CFG_HI Register *****/
|
|
/*! Flow control mode.
|
|
*/
|
|
#define DW_DMAC_CFGH_FCMODE (1UL << 0)
|
|
/*! FIFO mode select.
|
|
*/
|
|
#define DW_DMAC_CFGH_FIFO_MODE (1UL << 1)
|
|
/*! Protection control.
|
|
*/
|
|
#define DW_DMAC_CFGH_PROTCTL(n) (((n)&0x7) << 2)
|
|
//#define DW_DMAC_CFGH_DS_UPD_EN (1UL << 5)
|
|
//#define DW_DMAC_CFGH_SS_UPD_EN (1UL << 6)
|
|
/*! Assigns a hardware handshaking interface to the source of channel.
|
|
*/
|
|
#define DW_DMAC_CFGH_SRC_PER(n) (((n)&0xF) << 7)
|
|
/*! Assigns a hardware handshaking interface to the destination of channel.
|
|
*/
|
|
#define DW_DMAC_CFGH_DST_PER(n) (((n)&0xF) << 11)
|
|
|
|
|
|
/***** SGR Register *****/
|
|
/*! Source gather interval.
|
|
*/
|
|
#define DW_DMAC_SGR_SGI(n) (((n)&0xFFFFF) << 0)
|
|
/*! Source gather count.
|
|
*/
|
|
#define DW_DMAC_SGR_SGC(n) (((n)&0xF) << 20)
|
|
|
|
|
|
/***** DSR Register *****/
|
|
//#define DW_DMAC_DSR_DSI(x) (((n)&0xFFFFF) << 0)
|
|
//#define DW_DMAC_DSR_DSC(x) (((n)&0xF) << 20)
|
|
|
|
|
|
/***** DmaCfgReg Register *****/
|
|
/*! dmac enable.
|
|
*/
|
|
#define DW_DMAC_CFG_DMA_EN (1UL << 0)
|
|
|
|
/***** ChEnRegL/MaskTfrL/MaskErrL/MaskDstTranL/MaskSrcTranL/MaskBlockL/ Register *****/
|
|
/*! Source gather count.
|
|
*/
|
|
#define DW_DMAC_WRITE_EN(n) ((1 << (n+8)) | (1 << n))
|
|
/*! Source gather count.
|
|
*/
|
|
#define DW_DMAC_WRITE_DIS(n) (1 << (n+8))
|
|
|
|
#define DW_DMAC_XFER_DONE(n) (1 << (n))
|
|
#define DW_DMAC_XFER_ERR(n) (1 << (n+8))
|
|
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
/** @brief DW DMAC external constant definition
|
|
* @{
|
|
*/
|
|
|
|
/**
|
|
* @breif Number of data items to be transferred(of width TR_WIDTH)
|
|
*/
|
|
enum dw_dmac_msize {
|
|
/*! damc data width : 1 TR_WIDTH
|
|
*/
|
|
DW_DMAC_MSIZE_1,
|
|
/*! damc data width : 4 TR_WIDTH
|
|
*/
|
|
|
|
DW_DMAC_MSIZE_4,
|
|
/*! damc data width : 8 TR_WIDTH
|
|
*/
|
|
DW_DMAC_MSIZE_8,
|
|
// The following MSIZE is not supported.
|
|
// DW_DMAC_MSIZE_16,
|
|
// DW_DMAC_MSIZE_32,
|
|
// DW_DMAC_MSIZE_64,
|
|
// DW_DMAC_MSIZE_128,
|
|
// DW_DMAC_MSIZE_256,
|
|
};
|
|
|
|
/**
|
|
* @brief The size of each element of destination transmission. The unit is bit.
|
|
*/
|
|
enum dw_dmac_tr_width {
|
|
/*! damc xfer width : 8 bit
|
|
*/
|
|
DW_DMAC_TR_8,
|
|
/*! damc xfer width : 16bit
|
|
*/
|
|
DW_DMAC_TR_16,
|
|
/*! damc xfer width : 32bit
|
|
*/
|
|
DW_DMAC_TR_32,
|
|
// The following TR_WIDTH is not supported.0
|
|
// DW_DMAC_TR_64,
|
|
// DW_DMAC_TR_128,
|
|
// DW_DMAC_TR_256,
|
|
};
|
|
|
|
/**
|
|
* @brief Indicates destination address how to change on every source transfer.
|
|
*/
|
|
enum dw_dmac_addr_dir {
|
|
/*! Increment
|
|
*/
|
|
DW_DMAC_ADDR_INC,
|
|
/*! Decrement
|
|
*/
|
|
DW_DMAC_ADDR_DEC,
|
|
/*! No change
|
|
*/
|
|
DW_DMAC_ADDR_NO_CHANGE,
|
|
};
|
|
|
|
/**
|
|
* @breif flow controller
|
|
@verbatim
|
|
-------------------------------------------------------------------------------
|
|
CTLL.TT_FC Field Transfer Type Flow Controller
|
|
-------------------------------------------------------------------------------
|
|
000 Memory to Memory DW_anb_dmac
|
|
001 Memory to Peripheral DW_anb_dmac
|
|
010 Peripheral to Memory DW_anb_dmac
|
|
011 Peripheral to Peripheral DW_anb_dmac
|
|
100 Peripheral to Memory Peripheral
|
|
101 Peripheral to Peripheral Source Peripheral
|
|
110 Memory to Peripheral Peripheral
|
|
111 Peripheral to Peripheral Destination Peripheral
|
|
@endverbatim
|
|
*/
|
|
enum dw_dmac_fc {
|
|
/*! Memory to Memory
|
|
*/
|
|
DW_DMAC_FC_D_M2M,
|
|
/*! Memory to Peripheral
|
|
*/
|
|
DW_DMAC_FC_D_M2P,
|
|
/*! Peripheral to Memory
|
|
*/
|
|
DW_DMAC_FC_D_P2M,
|
|
/*! Peripheral to Peripheral
|
|
*/
|
|
DW_DMAC_FC_D_P2P,
|
|
// The following flow control is not supported.
|
|
// DW_DMAC_FC_P_P2M,
|
|
// DW_DMAC_FC_SP_P2P,
|
|
// DW_DMAC_FC_P_M2P,
|
|
// DW_DMAC_FC_DP_P2P,
|
|
};
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
int32 dw_dmac_search_src_id(uint32 addr);
|
|
int32 dw_dmac_search_dest_id(uint32 addr);
|
|
int32 dw_dmac_attach(uint32 dev_id, struct hgdma_dw *dmac);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|