1 /* SPDX-License-Identifier: BSD-3-Clause */ 2 /* 3 * Copyright (c) 2020-2021 Rockchip Electronics Co., Ltd. 4 */ 5 6 #include "hal_conf.h" 7 8 #ifdef HAL_PL330_MODULE_ENABLED 9 10 /** @addtogroup RK_HAL_Driver 11 * @{ 12 */ 13 14 /** @addtogroup PL330 15 * @{ 16 */ 17 18 #ifndef _HAL_PL330_H 19 #define _HAL_PL330_H 20 21 #include "hal_def.h" 22 23 /** @defgroup PL330_Exported_Definition_Group1 Basic Definition 24 * @{ 25 */ 26 27 /***************************** MACRO Definition ******************************/ 28 29 /** PL330 status */ 30 #define PL330_STATE_STOPPED HAL_BIT(0) 31 #define PL330_STATE_EXECUTING HAL_BIT(1) 32 #define PL330_STATE_WFE HAL_BIT(2) 33 #define PL330_STATE_FAULTING HAL_BIT(3) 34 #define PL330_STATE_COMPLETING HAL_BIT(4) 35 #define PL330_STATE_WFP HAL_BIT(5) 36 #define PL330_STATE_KILLING HAL_BIT(6) 37 #define PL330_STATE_FAULT_COMPLETE HAL_BIT(7) 38 #define PL330_STATE_CACHEMISS HAL_BIT(8) 39 #define PL330_STATE_UPDTPC HAL_BIT(9) 40 #define PL330_STATE_ATBARRIER HAL_BIT(10) 41 #define PL330_STATE_QUEUEBUSY HAL_BIT(11) 42 #define PL330_STATE_INVALID HAL_BIT(15) 43 44 #define PL330_STABLE_STATES \ 45 (PL330_STATE_STOPPED | PL330_STATE_EXECUTING | PL330_STATE_WFE | \ 46 PL330_STATE_FAULTING) 47 48 #define PL330_MAX_CHAN 8 49 #define PL330_MAX_IRQS 32 50 #define PL330_MAX_PERI 32 51 #define PL330_MAX_BURST 16 52 53 /* 54 * With 256 bytes, we can do more than 2.5MB and 5MB xfers per req 55 * at 1byte/burst for P<->M and M<->M respectively. 56 * For typical scenario, at 1word/burst, 10MB and 20MB xfers per req 57 * should be enough for P<->M and M<->M respectively. 58 */ 59 #define MCODE_BUFF_PER_REQ 256 60 #define PL330_MAX_CHAN_BUFS 2 61 #define PL330_CHAN_BUF_LEN 128 62 #define PL330_CHANNELS_PER_DEV 8 63 #define PL330_NR_IRQS 2 64 65 /***************************** Structure Definition **************************/ 66 67 /** enum PL330_CACHECTRL - pl330 cache control */ 68 typedef enum { 69 CCTRL0, /**< Noncacheable and nonbufferable */ 70 CCTRL1, /**< Bufferable only */ 71 CCTRL2, /**< Cacheable, but do not allocate */ 72 CCTRL3, /**< Cacheable and bufferable, but do not allocate */ 73 INVALID1, /**< AWCACHE = 0x1000 */ 74 INVALID2, 75 CCTRL6, /**< Cacheable write-through, allocate on writes only */ 76 CCTRL7, /**< Cacheable write-back, allocate on writes only */ 77 } ePL330_CACHECTRL; 78 79 /** enum PL330_BYTESWAP - pl330 byte swap control */ 80 typedef enum { 81 SWAP_NO, 82 SWAP_2, 83 SWAP_4, 84 SWAP_8, 85 SWAP_16, 86 } ePL330_BYTESWAP; 87 88 /** 89 * enum PL330_COND - dma transfer mode 90 */ 91 typedef enum { 92 SINGLE, 93 BURST, 94 ALWAYS, 95 } ePL330_COND; 96 97 /** PL330 soc configuration */ 98 struct PL330_CONFIG { 99 uint32_t periphId; 100 uint32_t mode; 101 uint32_t dataBusWidth; /**< In number of bits */ 102 uint32_t dataBufDep; 103 uint32_t numChan; 104 uint32_t numPeri; 105 uint32_t periNs; 106 uint32_t numEvents; 107 uint32_t irqNs; 108 }; 109 110 /** PL330 request config */ 111 struct PL330_REQCFG { 112 /* Address Incrementing */ 113 uint32_t dstInc; 114 uint32_t srcInc; 115 116 /* 117 * For now, the SRC & DST protection levels 118 * and burst size/length are assumed same. 119 */ 120 bool nonsecure; 121 bool privileged; 122 bool insnaccess; 123 uint32_t brstLen; 124 uint32_t brstSize; /**< bytes */ 125 126 ePL330_CACHECTRL dcctl; 127 ePL330_CACHECTRL scctl; 128 ePL330_BYTESWAP swap; 129 }; 130 131 /** DMA block descriptor struct. */ 132 struct PL330_XFER { 133 uint32_t srcAddr; /**< Source starting address */ 134 uint32_t dstAddr; /**< Destination starting address */ 135 uint32_t length; /**< Number of bytes for the xfer */ 136 }; 137 138 /** 139 * It's the done callback a user can set for a desc 140 */ 141 typedef void (*PL330_Callback)(void *cparam); 142 143 /** 144 * A DMA Desc consisits of a request config struct, a xfer descriptor, 145 * a pointer pointing to generated DMA program, and execution result. 146 */ 147 struct PL330_DESC { 148 struct PL330_REQCFG rqcfg; 149 struct PL330_XFER px; 150 uint8_t peri; 151 eDMA_TRANSFER_DIRECTION dir; 152 bool cyclic; 153 uint32_t numPeriods; 154 uint32_t bytesReq; 155 uint16_t srcInterlaceSize; 156 uint16_t dstInterlaceSize; 157 void *mcBuf; 158 PL330_Callback callback; 159 void *cparam; 160 }; 161 162 struct PL330_XFER_SPEC { 163 uint32_t ccr; 164 struct PL330_DESC *desc; 165 }; 166 167 struct HAL_PL330_DEV; 168 /** 169 * The PL330_CHAN Data is a struct to book keep individual channel of 170 * the DMAC. 171 */ 172 struct PL330_CHAN { 173 uint16_t periId; 174 uint16_t chanId; 175 uint32_t fifoAddr; 176 uint32_t brstSz; 177 uint32_t brstLen; 178 uint16_t srcInterlaceSize; 179 uint16_t dstInterlaceSize; 180 struct PL330_DESC desc; 181 struct HAL_PL330_DEV *pl330; 182 void *mcBuf; 183 bool used; 184 }; 185 186 /** 187 * The PL330 driver instance data structure. A pointer to an instance data 188 * structure is passed around by functions to refer to a specific driver 189 * instance. 190 */ 191 struct HAL_PL330_DEV { 192 struct DMA_REG *pReg; 193 struct PL330_CHAN chans[PL330_CHANNELS_PER_DEV]; 194 struct PL330_CONFIG pcfg; 195 ePL330_COND peripReqType; 196 IRQn_Type irq[PL330_NR_IRQS]; 197 ePD_Id pd; 198 199 void *priv; 200 }; 201 202 /** @} */ 203 204 /***************************** Function Declare ******************************/ 205 /** @defgroup PL330_Public_Function_Declare Public Function Declare 206 * @{ 207 */ 208 209 HAL_Status HAL_PL330_Init(struct HAL_PL330_DEV *pl330); 210 HAL_Status HAL_PL330_DeInit(struct HAL_PL330_DEV *pl330); 211 212 HAL_Status HAL_PL330_Start(struct PL330_CHAN *pchan); 213 HAL_Status HAL_PL330_Stop(struct PL330_CHAN *pchan); 214 215 struct PL330_CHAN *HAL_PL330_RequestChannel(struct HAL_PL330_DEV *pl330, DMA_REQ_Type id); 216 HAL_Status HAL_PL330_ReleaseChannel(struct PL330_CHAN *pchan); 217 218 HAL_Status HAL_PL330_Config(struct PL330_CHAN *pchan, struct DMA_SLAVE_CONFIG *config); 219 HAL_Status HAL_PL330_PrepDmaMemcpy(struct PL330_CHAN *pchan, uint32_t dst, 220 uint32_t src, uint32_t len, 221 PL330_Callback callback, void *cparam); 222 HAL_Status HAL_PL330_PrepDmaCyclic(struct PL330_CHAN *pchan, uint32_t dmaAddr, 223 uint32_t len, uint32_t periodLen, 224 eDMA_TRANSFER_DIRECTION direction, 225 PL330_Callback callback, void *cparam); 226 HAL_Status HAL_PL330_PrepDmaSingle(struct PL330_CHAN *pchan, uint32_t dmaAddr, 227 uint32_t len, 228 eDMA_TRANSFER_DIRECTION direction, 229 PL330_Callback callback, void *cparam); 230 int HAL_PL330_GetPosition(struct PL330_CHAN *pchan); 231 232 uint32_t HAL_PL330_IrqHandler(struct HAL_PL330_DEV *pl330); 233 uint32_t HAL_PL330_GetRawIrqStatus(struct HAL_PL330_DEV *pl330); 234 HAL_Status HAL_PL330_ClearIrq(struct HAL_PL330_DEV *pl330, uint32_t irq); 235 236 HAL_Status HAL_PL330_SetMcBuf(struct PL330_CHAN *pchan, void *buf); 237 void *HAL_PL330_GetMcBuf(struct PL330_CHAN *pchan); 238 const struct PL330_DESC *HAL_PL330_GetDesc(struct PL330_CHAN *pchan); 239 240 /** @} */ 241 242 #endif 243 244 /** @} */ 245 246 /** @} */ 247 248 #endif 249 /* HAL_PL330_MODULE_ENABLED */ 250