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