Commit | Line | Data |
---|---|---|
b2441318 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
8d073287 | 2 | /* |
51533b61 MS |
3 | * DMA C definitions and help macros |
4 | * | |
5 | */ | |
6 | ||
7 | #ifndef dma_h | |
8 | #define dma_h | |
9 | ||
10 | /* registers */ /* Really needed, since both are listed in sw.list? */ | |
a1ce3928 | 11 | #include <arch/hwregs/dma_defs.h> |
51533b61 MS |
12 | |
13 | ||
14 | /* descriptors */ | |
15 | ||
16 | // ------------------------------------------------------------ dma_descr_group | |
17 | typedef struct dma_descr_group { | |
18 | struct dma_descr_group *next; | |
19 | unsigned eol : 1; | |
20 | unsigned tol : 1; | |
21 | unsigned bol : 1; | |
22 | unsigned : 1; | |
23 | unsigned intr : 1; | |
24 | unsigned : 2; | |
25 | unsigned en : 1; | |
26 | unsigned : 7; | |
27 | unsigned dis : 1; | |
28 | unsigned md : 16; | |
29 | struct dma_descr_group *up; | |
30 | union { | |
31 | struct dma_descr_context *context; | |
32 | struct dma_descr_group *group; | |
33 | } down; | |
34 | } dma_descr_group; | |
35 | ||
36 | // ---------------------------------------------------------- dma_descr_context | |
37 | typedef struct dma_descr_context { | |
38 | struct dma_descr_context *next; | |
39 | unsigned eol : 1; | |
40 | unsigned : 3; | |
41 | unsigned intr : 1; | |
42 | unsigned : 1; | |
43 | unsigned store_mode : 1; | |
44 | unsigned en : 1; | |
45 | unsigned : 7; | |
46 | unsigned dis : 1; | |
47 | unsigned md0 : 16; | |
48 | unsigned md1; | |
49 | unsigned md2; | |
50 | unsigned md3; | |
51 | unsigned md4; | |
52 | struct dma_descr_data *saved_data; | |
53 | char *saved_data_buf; | |
54 | } dma_descr_context; | |
55 | ||
56 | // ------------------------------------------------------------- dma_descr_data | |
57 | typedef struct dma_descr_data { | |
58 | struct dma_descr_data *next; | |
59 | char *buf; | |
60 | unsigned eol : 1; | |
61 | unsigned : 2; | |
62 | unsigned out_eop : 1; | |
63 | unsigned intr : 1; | |
64 | unsigned wait : 1; | |
65 | unsigned : 2; | |
66 | unsigned : 3; | |
67 | unsigned in_eop : 1; | |
68 | unsigned : 4; | |
69 | unsigned md : 16; | |
70 | char *after; | |
71 | } dma_descr_data; | |
72 | ||
73 | // --------------------------------------------------------------------- macros | |
74 | ||
75 | // enable DMA channel | |
76 | #define DMA_ENABLE( inst ) \ | |
77 | do { reg_dma_rw_cfg e = REG_RD( dma, inst, rw_cfg );\ | |
78 | e.en = regk_dma_yes; \ | |
79 | REG_WR( dma, inst, rw_cfg, e); } while( 0 ) | |
80 | ||
81 | // reset DMA channel | |
82 | #define DMA_RESET( inst ) \ | |
83 | do { reg_dma_rw_cfg r = REG_RD( dma, inst, rw_cfg );\ | |
84 | r.en = regk_dma_no; \ | |
85 | REG_WR( dma, inst, rw_cfg, r); } while( 0 ) | |
86 | ||
87 | // stop DMA channel | |
88 | #define DMA_STOP( inst ) \ | |
89 | do { reg_dma_rw_cfg s = REG_RD( dma, inst, rw_cfg );\ | |
90 | s.stop = regk_dma_yes; \ | |
91 | REG_WR( dma, inst, rw_cfg, s); } while( 0 ) | |
92 | ||
93 | // continue DMA channel operation | |
94 | #define DMA_CONTINUE( inst ) \ | |
95 | do { reg_dma_rw_cfg c = REG_RD( dma, inst, rw_cfg );\ | |
96 | c.stop = regk_dma_no; \ | |
97 | REG_WR( dma, inst, rw_cfg, c); } while( 0 ) | |
98 | ||
99 | // give stream command | |
100 | #define DMA_WR_CMD( inst, cmd_par ) \ | |
8d073287 JN |
101 | do { reg_dma_rw_stream_cmd __x = {0}; \ |
102 | do { __x = REG_RD(dma, inst, rw_stream_cmd); } while (__x.busy); \ | |
103 | __x.cmd = (cmd_par); \ | |
104 | REG_WR(dma, inst, rw_stream_cmd, __x); \ | |
105 | } while (0) | |
51533b61 MS |
106 | |
107 | // load: g,c,d:burst | |
108 | #define DMA_START_GROUP( inst, group_descr ) \ | |
109 | do { REG_WR_INT( dma, inst, rw_group, (int) group_descr ); \ | |
110 | DMA_WR_CMD( inst, regk_dma_load_g ); \ | |
111 | DMA_WR_CMD( inst, regk_dma_load_c ); \ | |
112 | DMA_WR_CMD( inst, regk_dma_load_d | regk_dma_burst ); \ | |
113 | } while( 0 ) | |
114 | ||
115 | // load: c,d:burst | |
116 | #define DMA_START_CONTEXT( inst, ctx_descr ) \ | |
117 | do { REG_WR_INT( dma, inst, rw_group_down, (int) ctx_descr ); \ | |
118 | DMA_WR_CMD( inst, regk_dma_load_c ); \ | |
119 | DMA_WR_CMD( inst, regk_dma_load_d | regk_dma_burst ); \ | |
120 | } while( 0 ) | |
121 | ||
122 | // if the DMA is at the end of the data list, the last data descr is reloaded | |
123 | #define DMA_CONTINUE_DATA( inst ) \ | |
124 | do { reg_dma_rw_cmd c = {0}; \ | |
125 | c.cont_data = regk_dma_yes;\ | |
126 | REG_WR( dma, inst, rw_cmd, c ); } while( 0 ) | |
127 | ||
128 | #endif |