4
4
* SPDX-License-Identifier: Apache-2.0
5
5
*/
6
6
7
+ #include "drivers/dma.h"
7
8
#define DT_DRV_COMPAT intel_cavs_gpdma
8
9
9
- #define GPDMA_CTL_OFFSET 0x004
10
+ #define GPDMA_CTL_OFFSET 0x0004
10
11
#define GPDMA_CTL_FDCGB BIT(0)
11
12
13
+ #define GPDMA_CHLLPC_OFFSET (channel ) (0x0010 + (channel) * 0x10)
14
+ #define GPDMA_CHLLPC_EN BIT(7)
15
+ #define GPDMA_CHLLPC_DHRS (x ) SET_BITS(6, 0, x)
16
+
17
+ #define GPDMA_CHLLPL (channel ) (0x0018 + (channel) * 0x10)
18
+ #define GPDMA_CHLLPU (channel ) (0x001c + (channel) * 0x10)
19
+
12
20
#include "dma_dw_common.h"
13
21
14
22
#define LOG_LEVEL CONFIG_DMA_LOG_LEVEL
@@ -36,6 +44,137 @@ static void cavs_gpdma_clock_enable(const struct device *dev)
36
44
sys_write32 (GPDMA_CTL_FDCGB , reg );
37
45
}
38
46
47
+ static void cavs_gpdma_llp_config (const struct device * dev , uint32_t channel ,
48
+ uint32_t addr )
49
+ {
50
+ #ifdef CONFIG_DMA_CAVS_GPDMA_HAS_LLP
51
+ const struct cavs_gpdma_cfg * const dev_cfg = dev -> config ;
52
+
53
+ dw_write (dev_cfg -> shim , GPDMA_CHLLPC_OFFSET (channel ), GPDMA_CHLLPC_DHRS (addr ));
54
+ #endif
55
+ }
56
+
57
+ static inline void cavs_gpdma_llp_enable (const struct device * dev ,
58
+ uint32_t channel )
59
+ {
60
+ #ifdef CONFIG_DMA_CAVS_GPDMA_HAS_LLP
61
+ const struct cavs_gpdma_cfg * const dev_cfg = dev -> config ;
62
+ uint32_t val ;
63
+
64
+ val = dw_read (dev_cfg -> shim , GPDMA_CHLLPC_OFFSET (channel ));
65
+ if (!(val & GPDMA_CHLLPC_EN )) {
66
+ dw_write (dev_cfg -> shim , GPDMA_CHLLPC_OFFSET (channel ), val | GPDMA_CHLLPC_EN );
67
+ }
68
+ #endif
69
+ }
70
+
71
+ static inline void cavs_gpdma_llp_disable (const struct device * dev ,
72
+ uint32_t channel )
73
+ {
74
+ #ifdef CONFIG_DMA_CAVS_GPDMA_HAS_LLP
75
+ const struct cavs_gpdma_cfg * const dev_cfg = dev -> config ;
76
+ uint32_t val ;
77
+
78
+ val = dw_read (dev_cfg -> shim , GPDMA_CHLLPC_OFFSET (channel ));
79
+ dw_write (dev_cfg -> shim , GPDMA_CHLLPC_OFFSET (channel ), val | GPDMA_CHLLPC_EN );
80
+ #endif
81
+ }
82
+
83
+ static inline void cavs_gpdma_llp_read (const struct device * dev ,
84
+ uint32_t channel ,
85
+ uint32_t * llp_l ,
86
+ uint32_t * llp_u )
87
+ {
88
+ #ifdef CONFIG_DMA_CAVS_GPDMA_HAS_LLP
89
+ const struct cavs_gpdma_cfg * const dev_cfg = dev -> config ;
90
+
91
+ * llp_l = dw_read (dev_cfg -> shim , GPDMA_CHLLPL (channel ));
92
+ * llp_u = dw_read (dev_cfg -> shim , GPDMA_CHLLPU (channel ));
93
+ #endif
94
+ }
95
+
96
+
97
+ static int cavs_gpdma_config (const struct device * dev , uint32_t channel ,
98
+ struct dma_config * cfg )
99
+ {
100
+ int res = dw_dma_config (dev , channel , cfg );
101
+
102
+ if (res != 0 ) {
103
+ return res ;
104
+ }
105
+
106
+ struct dma_block_config * block_cfg = cfg -> head_block ;
107
+
108
+ /* Assume all scatter/gathers are for the same device? */
109
+ switch (cfg -> channel_direction ) {
110
+ case MEMORY_TO_PERIPHERAL :
111
+ LOG_DBG ("%s: dma %s configuring llp for destination %x" ,
112
+ __func__ , dev -> name , block_cfg -> dest_address );
113
+ cavs_gpdma_llp_config (dev , channel , block_cfg -> dest_address );
114
+ break ;
115
+ case PERIPHERAL_TO_MEMORY :
116
+ LOG_DBG ("%s: dma %s configuring llp for source %x" ,
117
+ __func__ , dev -> name , block_cfg -> source_address );
118
+ cavs_gpdma_llp_config (dev , channel , block_cfg -> source_address );
119
+ break ;
120
+ default :
121
+ break ;
122
+ }
123
+
124
+ return res ;
125
+ }
126
+
127
+ static int cavs_gpdma_start (const struct device * dev , uint32_t channel )
128
+ {
129
+ int ret ;
130
+
131
+ cavs_gpdma_llp_enable (dev , channel );
132
+ ret = dw_dma_start (dev , channel );
133
+ if (ret != 0 ) {
134
+ cavs_gpdma_llp_disable (dev , channel );
135
+ }
136
+ return ret ;
137
+ }
138
+
139
+ static int cavs_gpdma_stop (const struct device * dev , uint32_t channel )
140
+ {
141
+ int ret ;
142
+
143
+ ret = dw_dma_stop (dev , channel );
144
+ if (ret == 0 ) {
145
+ cavs_gpdma_llp_disable (dev , channel );
146
+ }
147
+ return ret ;
148
+ }
149
+
150
+ int cavs_gpdma_copy (const struct device * dev , uint32_t channel ,
151
+ uint32_t src , uint32_t dst , size_t size )
152
+ {
153
+ struct dw_dma_dev_data * const dev_data = dev -> data ;
154
+ struct dw_dma_chan_data * chan_data ;
155
+ int i = 0 ;
156
+
157
+ if (channel >= DW_MAX_CHAN ) {
158
+ return - EINVAL ;
159
+ }
160
+
161
+ chan_data = & dev_data -> chan [channel ];
162
+
163
+ /* default action is to clear the DONE bit for all LLI making
164
+ * sure the cache is coherent between DSP and DMAC.
165
+ */
166
+ for (i = 0 ; i < chan_data -> lli_count ; i ++ ) {
167
+ chan_data -> lli [i ].ctrl_hi &= ~DW_CTLH_DONE (1 );
168
+ }
169
+
170
+ chan_data -> ptr_data .current_ptr += size ;
171
+ if (chan_data -> ptr_data .current_ptr >= chan_data -> ptr_data .end_ptr ) {
172
+ chan_data -> ptr_data .current_ptr = chan_data -> ptr_data .start_ptr +
173
+ (chan_data -> ptr_data .current_ptr - chan_data -> ptr_data .end_ptr );
174
+ }
175
+
176
+ return 0 ;
177
+ }
39
178
40
179
int cavs_gpdma_init (const struct device * dev )
41
180
{
@@ -45,22 +184,31 @@ int cavs_gpdma_init(const struct device *dev)
45
184
cavs_gpdma_clock_enable (dev );
46
185
47
186
/* Disable all channels and Channel interrupts */
48
- dw_dma_setup (dev );
187
+ int ret = dw_dma_setup (dev );
188
+
189
+ if (ret != 0 ) {
190
+ LOG_ERR ("%s: dma %s failed to initialize" , __func__ , dev -> name );
191
+ goto out ;
192
+ }
49
193
50
194
/* Configure interrupts */
51
195
dev_cfg -> dw_cfg .irq_config ();
52
196
53
- LOG_INF ("Device %s initialized" , dev -> name );
197
+ LOG_INF ("%s: dma %s initialized" , __func__ , dev -> name );
54
198
199
+ out :
55
200
return 0 ;
56
201
}
57
202
58
203
59
204
static const struct dma_driver_api cavs_gpdma_driver_api = {
60
- .config = dw_dma_config ,
61
- .reload = dw_dma_reload ,
62
- .start = dw_dma_transfer_start ,
63
- .stop = dw_dma_transfer_stop ,
205
+ .config = cavs_gpdma_config ,
206
+ .reload = cavs_gpdma_copy ,
207
+ .start = cavs_gpdma_start ,
208
+ .stop = cavs_gpdma_stop ,
209
+ .suspend = dw_dma_suspend ,
210
+ .resume = dw_dma_resume ,
211
+ .get_status = dw_dma_get_status ,
64
212
};
65
213
66
214
0 commit comments