1 /******************************************************************************
2 *                                                                             *
3 * License Agreement                                                           *
4 *                                                                             *
5 * Copyright (c) 2014 Altera Corporation, San Jose, California, USA.           *
6 * All rights reserved.                                                        *
7 *                                                                             *
8 * Permission is hereby granted, free of charge, to any person obtaining a     *
9 * copy of this software and associated documentation files (the "Software"),  *
10 * to deal in the Software without restriction, including without limitation   *
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,    *
12 * and/or sell copies of the Software, and to permit persons to whom the       *
13 * Software is furnished to do so, subject to the following conditions:        *
14 *                                                                             *
15 * The above copyright notice and this permission notice shall be included in  *
16 * all copies or substantial portions of the Software.                         *
17 *                                                                             *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  *
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,    *
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER      *
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING     *
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER         *
24 * DEALINGS IN THE SOFTWARE.                                                   *
25 *                                                                             *
26 *                                                                             *
27 ******************************************************************************/
28 
29 #ifndef __ALTERA_MSGDMA_H__
30 #define __ALTERA_MSGDMA_H__
31 
32 #include <stddef.h>
33 #include <errno.h>
34 
35 #include "sys/alt_dev.h"
36 #include "alt_types.h"
37 #include "altera_msgdma_csr_regs.h"
38 #include "altera_msgdma_descriptor_regs.h"
39 #include "altera_msgdma_response_regs.h"
40 #include "altera_msgdma_prefetcher_regs.h"
41 #include "os/alt_sem.h"
42 #include "os/alt_flag.h"
43 
44 #ifdef __cplusplus
45 extern "C"
46 {
47 #endif /* __cplusplus */
48 
49 /*
50  * Helper struct to have easy access to hi/low values from a 64 bit value.
51  * Useful when having to write prefetcher/descriptor 64 bit addresses.
52  */
53 typedef union {
54   alt_u64 u64;
55   alt_u32 u32[2];
56 } msgdma_addr64;
57 
58 /*
59  * To ensure that a descriptor is created without spaces between the structure
60  * members, we call upon GCC's ability to pack to a byte-aligned boundary.
61  * Additionally, msgdma requires the descriptors to be aligned to a 16 byte
62  * boundary.
63  */
64 #define alt_msgdma_standard_descriptor_packed \
65 	__attribute__ ((packed, aligned(16)))
66 #define alt_msgdma_extended_descriptor_packed \
67 	__attribute__ ((packed, aligned(32)))
68 #define alt_msgdma_prefetcher_standard_descriptor_packed \
69 	__attribute__ ((packed, aligned(32)))
70 #define alt_msgdma_prefetcher_extended_descriptor_packed \
71 	__attribute__ ((packed, aligned(64)))
72 #define alt_msgdma_response_packed __attribute__ ((packed, aligned(4)))
73 
74 /*
75  * The function alt_find_dev() is used to search the device list "list" to
76  * locate a device named "name". If a match is found, then a pointer to the
77  * device is returned, otherwise NULL is returned.
78  */
79 extern alt_dev* alt_find_dev (const char* name, alt_llist* list);
80 
81 /* Callback routine type definition */
82 typedef void (*alt_msgdma_callback)(void *context);
83 
84 /* use this structure if you haven't enabled the enhanced features */
85 typedef struct {
86   alt_u32 *read_address;
87   alt_u32 *write_address;
88   alt_u32 transfer_length;
89   alt_u32 control;
90 } alt_msgdma_standard_descriptor_packed alt_msgdma_standard_descriptor;
91 
92 /* use this structure if you have enabled the enhanced features (only the
93  * elements enabled in hardware will be used)
94  */
95 typedef struct {
96   alt_u32 *read_address_low;
97   alt_u32 *write_address_low;
98   alt_u32 transfer_length;
99   alt_u16 sequence_number;
100   alt_u8  read_burst_count;
101   alt_u8  write_burst_count;
102   alt_u16 read_stride;
103   alt_u16 write_stride;
104   alt_u32 *read_address_high;
105   alt_u32 *write_address_high;
106   alt_u32 control;
107 } alt_msgdma_extended_descriptor_packed alt_msgdma_extended_descriptor;
108 
109 
110 /* Prefetcher Descriptors need to be different than standard dispatcher
111  * descriptors use this structure if you haven't enabled the enhanced
112  * features
113  */
114 typedef struct {
115   alt_u32 read_address;
116   alt_u32 write_address;
117   alt_u32 transfer_length;
118   alt_u32 next_desc_ptr;
119   alt_u32 bytes_transfered;
120   alt_u16 status;
121   alt_u16 _pad1_rsvd;
122   alt_u32 _pad2_rsvd;
123   alt_u32 control;
124 } alt_msgdma_prefetcher_standard_descriptor_packed alt_msgdma_prefetcher_standard_descriptor;
125 
126 /* use this structure if you have enabled the enhanced features (only the elements
127 enabled in hardware will be used) */
128 typedef struct {
129   alt_u32  read_address_low;
130   alt_u32  write_address_low;
131   alt_u32 transfer_length;
132   alt_u32  next_desc_ptr_low;
133   alt_u32 bytes_transfered;
134   alt_u16 status;
135   alt_u16 _pad1_rsvd;
136   alt_u32 _pad2_rsvd;
137   alt_u16 sequence_number;
138   alt_u8  read_burst_count;
139   alt_u8  write_burst_count;
140   alt_u16 read_stride;
141   alt_u16 write_stride;
142   alt_u32  read_address_high;
143   alt_u32  write_address_high;
144   alt_u32  next_desc_ptr_high;
145   alt_u32 _pad3_rsvd[3];
146   alt_u32 control;
147 } alt_msgdma_prefetcher_extended_descriptor_packed alt_msgdma_prefetcher_extended_descriptor;
148 
149 
150 /* msgdma device structure */
151 typedef struct alt_msgdma_dev
152 {
153 	/* Device linked-list entry */
154     alt_llist                            llist;
155 	/* Name of msgdma in Qsys system */
156     const char                           *name;
157 	/* Base address of control and status register */
158     alt_u32                              *csr_base;
159 	/* Base address of the descriptor slave port */
160     alt_u32                              *descriptor_base;
161 	/* Base address of the response register */
162     alt_u32                              *response_base;
163     /* Base address of the prefetcher register */
164     alt_u32                              *prefetcher_base;
165 	/* device IRQ controller ID */
166 	alt_u32                    	         irq_controller_ID;
167 	/* device IRQ ID */
168 	alt_u32                    	         irq_ID;
169 	/* FIFO size to store descriptor count,
170 	{ 8, 16, 32, 64,default:128, 256, 512, 1024 } */
171     alt_u32                              descriptor_fifo_depth;
172 	/* FIFO size to store response count */
173     alt_u32                              response_fifo_depth;
174 	/* Callback routine pointer */
175     alt_msgdma_callback                  callback;
176 	/* Callback context pointer */
177     void                                 *callback_context;
178 	/* user define control setting during interrupt registering*/
179     alt_u32                              control;
180 	/* Enable burst transfer */
181     alt_u8				burst_enable;
182 	/* Enable burst wrapping */
183     alt_u8				burst_wrapping_support;
184         /* Depth of the internal data path FIFO*/
185     alt_u32				data_fifo_depth;
186 	/* Data path Width. This parameter affect both read
187            master and write master data width */
188     alt_u32			        data_width;
189 	/* Maximum burst count*/
190     alt_u32                             max_burst_count;
191 	/* Maximum transfer length*/
192     alt_u32                             max_byte;
193 	/* Maximum stride count */
194     alt_u64				max_stride;
195 	/* Enable dynamic burst programming*/
196     alt_u8			     programmable_burst_enable;
197 	/* Enable stride addressing */
198     alt_u8				stride_enable;
199 	/* Supported transaction type */
200     const char                          *transfer_type;
201        /* Extended feature support enable "1"-enable  "0"-disable */
202     alt_u8				enhanced_features;
203       /* Enable response port "0"-memory-mapped, "1"-streaming, "2"-disable */
204     alt_u8				response_port;
205     /* Prefetcher enabled "0"-disabled, "1"-enabled*/
206     alt_u8				prefetcher_enable;
207 	/* Semaphore used to control access registers
208 	in multi-threaded mode */
209     ALT_SEM                              (regs_lock)
210 } alt_msgdma_dev;
211 
212 
213 
214 /*******************************************************************************
215  *  Public API
216  ******************************************************************************/
217 alt_msgdma_dev* alt_msgdma_open (const char* name);
218 
219 void alt_msgdma_register_callback(
220 	alt_msgdma_dev *dev,
221 	alt_msgdma_callback callback,
222 	alt_u32 control,
223 	void *context);
224 
225 int alt_msgdma_standard_descriptor_async_transfer(
226 	alt_msgdma_dev *dev,
227 	alt_msgdma_standard_descriptor *desc);
228 
229 int alt_msgdma_extended_descriptor_async_transfer(
230 	alt_msgdma_dev *dev,
231 	alt_msgdma_extended_descriptor *desc);
232 
233 int alt_msgdma_construct_standard_mm_to_mm_descriptor (
234 	alt_msgdma_dev *dev,
235 	alt_msgdma_standard_descriptor *descriptor,
236 	alt_u32 *read_address,
237 	alt_u32 *write_address,
238 	alt_u32 length,
239 	alt_u32 control);
240 
241 int alt_msgdma_construct_standard_st_to_mm_descriptor (
242 	alt_msgdma_dev *dev,
243 	alt_msgdma_standard_descriptor *descriptor,
244 	alt_u32 *write_address,
245 	alt_u32 length,
246 	alt_u32 control);
247 
248 int alt_msgdma_construct_standard_mm_to_st_descriptor (
249 	alt_msgdma_dev *dev,
250 	alt_msgdma_standard_descriptor *descriptor,
251 	alt_u32 *read_address,
252 	alt_u32 length,
253 	alt_u32 control);
254 
255 int alt_msgdma_construct_extended_st_to_mm_descriptor (
256 	alt_msgdma_dev *dev,
257 	alt_msgdma_extended_descriptor *descriptor,
258 	alt_u32 *write_address,
259 	alt_u32 length,
260 	alt_u32 control,
261 	alt_u16 sequence_number,
262 	alt_u8 write_burst_count,
263 	alt_u16 write_stride);
264 
265 int alt_msgdma_construct_extended_mm_to_st_descriptor (
266 	alt_msgdma_dev *dev,
267 	alt_msgdma_extended_descriptor *descriptor,
268 	alt_u32 *read_address,
269 	alt_u32 length,
270 	alt_u32 control,
271 	alt_u16 sequence_number,
272 	alt_u8 read_burst_count,
273 	alt_u16 read_stride);
274 
275 int alt_msgdma_construct_extended_mm_to_mm_descriptor (
276 	alt_msgdma_dev *dev,
277 	alt_msgdma_extended_descriptor *descriptor,
278 	alt_u32 *read_address,
279 	alt_u32 *write_address,
280 	alt_u32 length,
281 	alt_u32 control,
282 	alt_u16 sequence_number,
283 	alt_u8 read_burst_count,
284 	alt_u8 write_burst_count,
285 	alt_u16 read_stride,
286 	alt_u16 write_stride);
287 
288 int alt_msgdma_standard_descriptor_sync_transfer(
289 	alt_msgdma_dev *dev,
290 	alt_msgdma_standard_descriptor *desc);
291 
292 int alt_msgdma_extended_descriptor_sync_transfer(
293 	alt_msgdma_dev *dev,
294 	alt_msgdma_extended_descriptor *desc);
295 
296 int alt_msgdma_standard_descriptor_sync_transfer(
297 	alt_msgdma_dev *dev,
298 	alt_msgdma_standard_descriptor *desc);
299 
300 /***************** MSGDMA PREFETCHER PUBLIC APIs ******************/
301 int alt_msgdma_construct_prefetcher_standard_mm_to_mm_descriptor (
302 	alt_msgdma_dev *dev,
303 	alt_msgdma_prefetcher_standard_descriptor *descriptor,
304 	alt_u32 read_address,
305 	alt_u32 write_address,
306 	alt_u32 length,
307 	alt_u32 control);
308 
309 int alt_msgdma_construct_prefetcher_standard_st_to_mm_descriptor (
310 	alt_msgdma_dev *dev,
311 	alt_msgdma_prefetcher_standard_descriptor *descriptor,
312 	alt_u32 write_address,
313 	alt_u32 length,
314 	alt_u32 control);
315 
316 int alt_msgdma_construct_prefetcher_standard_mm_to_st_descriptor (
317 	alt_msgdma_dev *dev,
318 	alt_msgdma_prefetcher_standard_descriptor *descriptor,
319 	alt_u32 read_address,
320 	alt_u32 length,
321 	alt_u32 control);
322 
323 int alt_msgdma_construct_prefetcher_extended_st_to_mm_descriptor (
324 	alt_msgdma_dev *dev,
325 	alt_msgdma_prefetcher_extended_descriptor *descriptor,
326 	alt_u32 write_address_high,
327 	alt_u32 write_address_low,
328 	alt_u32 length,
329 	alt_u32 control,
330 	alt_u16 sequence_number,
331 	alt_u8 write_burst_count,
332 	alt_u16 write_stride);
333 
334 int alt_msgdma_construct_prefetcher_extended_mm_to_st_descriptor (
335 	alt_msgdma_dev *dev,
336 	alt_msgdma_prefetcher_extended_descriptor *descriptor,
337 	alt_u32 read_address_high,
338 	alt_u32 read_address_low,
339 	alt_u32 length,
340 	alt_u32 control,
341 	alt_u16 sequence_number,
342 	alt_u8 read_burst_count,
343 	alt_u16 read_stride);
344 
345 int alt_msgdma_construct_prefetcher_extended_mm_to_mm_descriptor (
346 	alt_msgdma_dev *dev,
347 	alt_msgdma_prefetcher_extended_descriptor *descriptor,
348 	alt_u32 read_address_high,
349 	alt_u32 read_address_low,
350 	alt_u32 write_address_high,
351 	alt_u32 write_address_low,
352 	alt_u32 length,
353 	alt_u32 control,
354 	alt_u16 sequence_number,
355 	alt_u8 read_burst_count,
356 	alt_u8 write_burst_count,
357 	alt_u16 read_stride,
358 	alt_u16 write_stride);
359 
360 int alt_msgdma_prefetcher_add_standard_desc_to_list (
361 	alt_msgdma_prefetcher_standard_descriptor** list,
362 	alt_msgdma_prefetcher_standard_descriptor* descriptor);
363 
364 int alt_msgdma_prefetcher_add_extended_desc_to_list (
365 	alt_msgdma_prefetcher_extended_descriptor** list,
366 	alt_msgdma_prefetcher_extended_descriptor* descriptor);
367 
368 int alt_msgdma_start_prefetcher_with_std_desc_list (
369 	alt_msgdma_dev *dev,
370 	alt_msgdma_prefetcher_standard_descriptor *list,
371 	alt_u8 park_mode_en,
372 	alt_u8 poll_en);
373 
374 int alt_msgdma_start_prefetcher_with_extd_desc_list (
375 	alt_msgdma_dev *dev,
376 	alt_msgdma_prefetcher_extended_descriptor *list,
377 	alt_u8 park_mode_en,
378 	alt_u8 poll_en);
379 
380 int alt_msgdma_prefetcher_set_std_list_own_by_hw_bits (
381 	alt_msgdma_prefetcher_standard_descriptor *list);
382 int alt_msgdma_prefetcher_set_extd_list_own_by_hw_bits (
383 	alt_msgdma_prefetcher_extended_descriptor *list);
384 
385 void alt_msgdma_init (alt_msgdma_dev *dev, alt_u32 ic_id, alt_u32 irq);
386 
387 /* HAL initialization macros */
388 
389 /*Depth of internal data path FIFO.STRIDE_ENABLE
390  * ALTERA_MSGDMA_INSTANCE is the macro used by alt_sys_init() to
391  * allocate any per device memory that may be required.
392  */
393 #define ALTERA_MSGDMA_CSR_DESCRIPTOR_SLAVE_RESPONSE_INSTANCE(name, csr_if, desc_if, resp_if, dev) \
394 static alt_msgdma_dev dev =                                                                       \
395 {                                                                                                 \
396   ALT_LLIST_ENTRY,                                                                                \
397   name##_CSR_NAME,                                                                                \
398   ((alt_u32 *)(csr_if##_BASE)),                                                                   \
399   ((alt_u32 *)(desc_if##_BASE)),                                                                  \
400   ((alt_u32 *)(resp_if##_BASE)),                                                                  \
401   ((alt_u32 *)(0)),                                                                               \
402   ((alt_u32  )name##_CSR_IRQ_INTERRUPT_CONTROLLER_ID),                                            \
403   ((alt_u32  )name##_CSR_IRQ),                                                                    \
404   ((alt_u32  )desc_if##_DESCRIPTOR_FIFO_DEPTH),                                                   \
405   ((alt_u32  )resp_if##_DESCRIPTOR_FIFO_DEPTH * 2),                                               \
406   ((void *) 0x0),                                                                                 \
407   ((void *) 0x0),                                                                                 \
408   ((alt_u32) 0x0),                                                                                \
409   ((alt_u8) csr_if##_BURST_ENABLE),                                                               \
410   ((alt_u8) csr_if##_BURST_WRAPPING_SUPPORT),                                                     \
411   ((alt_u32) csr_if##_DATA_FIFO_DEPTH),                                                           \
412   ((alt_u32) csr_if##_DATA_WIDTH),                                                                \
413   ((alt_u32) csr_if##_MAX_BURST_COUNT),                                                           \
414   ((alt_u32) csr_if##_MAX_BYTE),                                                                  \
415   ((alt_u64) csr_if##_MAX_STRIDE),                                                                \
416   ((alt_u8) csr_if##_PROGRAMMABLE_BURST_ENABLE),                                                  \
417   ((alt_u8) csr_if##_STRIDE_ENABLE),                                                              \
418   csr_if##_TRANSFER_TYPE,                                                                         \
419   ((alt_u8) csr_if##_ENHANCED_FEATURES),                                                          \
420   ((alt_u8) csr_if##_RESPONSE_PORT),                                                              \
421   ((alt_u8) csr_if##_PREFETCHER_ENABLE)                                                           \
422 };
423 
424 #define ALTERA_MSGDMA_CSR_DESCRIPTOR_SLAVE_INSTANCE(name, csr_if, desc_if, dev) \
425 static alt_msgdma_dev dev =                                                     \
426 {                                                                               \
427   ALT_LLIST_ENTRY,                                                              \
428   name##_CSR_NAME,                                                              \
429   ((alt_u32 *)(csr_if##_BASE)),                                                 \
430   ((alt_u32 *)(desc_if##_BASE)),                                                \
431   ((alt_u32 *)(0)),                                                             \
432   ((alt_u32 *)(0)),                                                             \
433   ((alt_u32  )name##_CSR_IRQ_INTERRUPT_CONTROLLER_ID),                          \
434   ((alt_u32  )name##_CSR_IRQ),                                                  \
435   ((alt_u32  )desc_if##_DESCRIPTOR_FIFO_DEPTH),                                 \
436   ((alt_u32) 0x0),                                                              \
437   ((void *) 0x0),                                                               \
438   ((void *) 0x0),                                                               \
439   ((alt_u32) 0x0),                                                              \
440   ((alt_u8) csr_if##_BURST_ENABLE),                                             \
441   ((alt_u8) csr_if##_BURST_WRAPPING_SUPPORT),                                   \
442   ((alt_u32) csr_if##_DATA_FIFO_DEPTH),                                         \
443   ((alt_u32) csr_if##_DATA_WIDTH),                                              \
444   ((alt_u32) csr_if##_MAX_BURST_COUNT),                                         \
445   ((alt_u32) csr_if##_MAX_BYTE),                                                \
446   ((alt_u64) csr_if##_MAX_STRIDE),                                              \
447   ((alt_u8) csr_if##_PROGRAMMABLE_BURST_ENABLE),                                \
448   ((alt_u8) csr_if##_STRIDE_ENABLE),                                            \
449   csr_if##_TRANSFER_TYPE,                                                       \
450   ((alt_u8) csr_if##_ENHANCED_FEATURES),                                        \
451   ((alt_u8) csr_if##_RESPONSE_PORT),                                            \
452   ((alt_u8) csr_if##_PREFETCHER_ENABLE)                                         \
453 };
454 
455 /*
456  * New Interface for Prefetcher 15/6/2015.
457  */
458 #define ALTERA_MSGDMA_CSR_PREFETCHER_CSR_INSTANCE(name, csr_if, pref_if, dev)   \
459 static alt_msgdma_dev dev =                                                     \
460 {                                                                               \
461   ALT_LLIST_ENTRY,                                                              \
462   name##_CSR_NAME,                                                              \
463   ((alt_u32 *)(csr_if##_BASE)),                                                 \
464   ((alt_u32 *)(0)),                                                             \
465   ((alt_u32 *)(0)),                                                             \
466   ((alt_u32 *)(pref_if##_BASE)),                                                \
467   ((alt_u32  )name##_PREFETCHER_CSR_IRQ_INTERRUPT_CONTROLLER_ID),               \
468   ((alt_u32  )name##_PREFETCHER_CSR_IRQ),                                       \
469   ((alt_u32  )(0)),                                                             \
470   ((alt_u32) 0x0),                                                              \
471   ((void *) 0x0),                                                               \
472   ((void *) 0x0),                                                               \
473   ((alt_u32) 0x0),                                                              \
474   ((alt_u8) csr_if##_BURST_ENABLE),                                             \
475   ((alt_u8) csr_if##_BURST_WRAPPING_SUPPORT),                                   \
476   ((alt_u32) csr_if##_DATA_FIFO_DEPTH),                                         \
477   ((alt_u32) csr_if##_DATA_WIDTH),                                              \
478   ((alt_u32) csr_if##_MAX_BURST_COUNT),                                         \
479   ((alt_u32) csr_if##_MAX_BYTE),                                                \
480   ((alt_u64) csr_if##_MAX_STRIDE),                                              \
481   ((alt_u8) csr_if##_PROGRAMMABLE_BURST_ENABLE),                                \
482   ((alt_u8) csr_if##_STRIDE_ENABLE),                                            \
483   csr_if##_TRANSFER_TYPE,                                                       \
484   ((alt_u8) csr_if##_ENHANCED_FEATURES),                                        \
485   ((alt_u8) csr_if##_RESPONSE_PORT),                                            \
486   ((alt_u8) csr_if##_PREFETCHER_ENABLE)                                         \
487 };
488 
489 
490 /*
491  * The macro ALTERA_MSGDMA_INIT is called by the auto-generated function
492  * alt_sys_init() to initialize a given device instance.
493  */
494 #define ALTERA_MSGDMA_INIT(name, dev)                                              \
495     alt_msgdma_init(&dev, dev.irq_controller_ID, dev.irq_ID);
496 
497 #ifdef __cplusplus
498 }
499 #endif /* __cplusplus */
500 
501 #endif /* __ALTERA_MSGDMA_H__ */
502