@@ -14,6 +14,9 @@ LOG_MODULE_REGISTER(spi_litex_litespi);
14
14
#include "spi_litex_common.h"
15
15
16
16
#define SPI_LITEX_ANY_HAS_IRQ DT_ANY_INST_HAS_PROP_STATUS_OKAY(interrupts)
17
+ #define SPI_LITEX_ALL_HAS_IRQ DT_ALL_INST_HAS_PROP_STATUS_OKAY(interrupts)
18
+
19
+ #define SPI_LITEX_HAS_IRQ (SPI_LITEX_ALL_HAS_IRQ || dev_config->has_irq)
17
20
18
21
#define SPIFLASH_CORE_MASTER_PHYCONFIG_LEN_OFFSET 0x0
19
22
#define SPIFLASH_CORE_MASTER_PHYCONFIG_WIDTH_OFFSET 0x1
@@ -25,6 +28,9 @@ LOG_MODULE_REGISTER(spi_litex_litespi);
25
28
#define SPI_MAX_WORD_SIZE 32
26
29
#define SPI_MAX_CS_SIZE 4
27
30
31
+ #define SPI_LITEX_WIDTH BIT(0)
32
+ #define SPI_LITEX_MASK BIT(0)
33
+
28
34
struct spi_litex_dev_config {
29
35
uint32_t core_master_cs_addr ;
30
36
uint32_t core_master_phyconfig_addr ;
@@ -43,9 +49,7 @@ struct spi_litex_dev_config {
43
49
struct spi_litex_data {
44
50
struct spi_context ctx ;
45
51
uint8_t dfs ; /* dfs in bytes: 1,2 or 4 */
46
- #if SPI_LITEX_ANY_HAS_IRQ
47
- struct k_sem sem_rx_ready ;
48
- #endif /* SPI_LITEX_ANY_HAS_IRQ */
52
+ uint8_t len ; /* length of the last transfer in bytes */
49
53
};
50
54
51
55
@@ -93,11 +97,6 @@ static int spi_config(const struct device *dev, const struct spi_config *config)
93
97
return - ENOTSUP ;
94
98
}
95
99
96
- if (config -> operation & SPI_LOCK_ON ) {
97
- LOG_ERR ("Lock On not supported" );
98
- return - ENOTSUP ;
99
- }
100
-
101
100
if (IS_ENABLED (CONFIG_SPI_EXTENDED_MODES ) &&
102
101
(config -> operation & SPI_LINES_MASK ) != SPI_LINES_SINGLE ) {
103
102
LOG_ERR ("Only supports single mode" );
@@ -144,40 +143,63 @@ static void spiflash_len_mask_width_write(uint32_t len, uint32_t width, uint32_t
144
143
litex_write32 (word , addr );
145
144
}
146
145
147
- static void spi_litex_wait_for_rx_ready (const struct device * dev )
146
+ static void spi_litex_spi_do_tx (const struct device * dev )
148
147
{
149
148
const struct spi_litex_dev_config * dev_config = dev -> config ;
150
-
151
- #if SPI_LITEX_ANY_HAS_IRQ
152
149
struct spi_litex_data * data = dev -> data ;
150
+ struct spi_context * ctx = & data -> ctx ;
151
+ uint8_t len ;
152
+ uint32_t txd = 0U ;
153
+
154
+ len = MIN (spi_context_max_continuous_chunk (ctx ), dev_config -> core_master_rxtx_size );
155
+ if (len != data -> len ) {
156
+ spiflash_len_mask_width_write (len * 8 , SPI_LITEX_WIDTH , SPI_LITEX_MASK ,
157
+ dev_config -> core_master_phyconfig_addr );
158
+ data -> len = len ;
159
+ }
153
160
154
- if (dev_config -> has_irq ) {
155
- /* Wait for the RX ready event */
156
- k_sem_take (& data -> sem_rx_ready , K_FOREVER );
157
- return ;
161
+ if (spi_context_tx_buf_on (ctx )) {
162
+ litex_spi_tx_put (len , & txd , ctx -> tx_buf );
158
163
}
159
- #endif /* SPI_LITEX_ANY_HAS_IRQ */
160
164
161
- while (!(litex_read8 (dev_config -> core_master_status_addr ) &
162
- BIT (SPIFLASH_CORE_MASTER_STATUS_RX_READY_OFFSET ))) {
163
- ;
165
+ LOG_DBG ("txd: 0x%x" , txd );
166
+ litex_write32 (txd , dev_config -> core_master_rxtx_addr );
167
+
168
+ spi_context_update_tx (ctx , data -> dfs , len / data -> dfs );
169
+ }
170
+
171
+ static void spi_litex_spi_do_rx (const struct device * dev )
172
+ {
173
+ const struct spi_litex_dev_config * dev_config = dev -> config ;
174
+ struct spi_litex_data * data = dev -> data ;
175
+ struct spi_context * ctx = & data -> ctx ;
176
+ uint32_t rxd ;
177
+
178
+ rxd = litex_read32 (dev_config -> core_master_rxtx_addr );
179
+ LOG_DBG ("rxd: 0x%x" , rxd );
180
+
181
+ if (spi_context_rx_buf_on (ctx )) {
182
+ litex_spi_rx_put (data -> len , & rxd , ctx -> rx_buf );
164
183
}
184
+
185
+ spi_context_update_rx (ctx , data -> dfs , data -> len / data -> dfs );
165
186
}
166
187
167
188
static int spi_litex_xfer (const struct device * dev , const struct spi_config * config )
168
189
{
169
190
const struct spi_litex_dev_config * dev_config = dev -> config ;
170
191
struct spi_litex_data * data = dev -> data ;
171
192
struct spi_context * ctx = & data -> ctx ;
172
- uint32_t txd , rxd ;
193
+ uint32_t rxd ;
173
194
int ret = 0 ;
174
195
175
- uint8_t len = data -> dfs ; /* SPI Xfer length*/
176
- uint8_t old_len = len ; /* old SPI Xfer length*/
177
196
uint8_t width = BIT (0 ); /* SPI Xfer width*/
178
197
uint8_t mask = BIT (0 ); /* SPI Xfer mask*/
179
198
180
- spiflash_len_mask_width_write (len * 8 , width , mask , dev_config -> core_master_phyconfig_addr );
199
+ data -> len = MIN (spi_context_max_continuous_chunk (ctx ), dev_config -> core_master_rxtx_size );
200
+
201
+ spiflash_len_mask_width_write (data -> len * 8 , SPI_LITEX_WIDTH , SPI_LITEX_MASK ,
202
+ dev_config -> core_master_phyconfig_addr );
181
203
182
204
litex_write32 (BIT (config -> slave ), dev_config -> core_master_cs_addr );
183
205
@@ -188,79 +210,71 @@ static int spi_litex_xfer(const struct device *dev, const struct spi_config *con
188
210
LOG_DBG ("flushed rxd: 0x%x" , rxd );
189
211
}
190
212
213
+ while (!(litex_read8 (dev_config -> core_master_status_addr ) &
214
+ BIT (SPIFLASH_CORE_MASTER_STATUS_TX_READY_OFFSET ))) {
215
+ ;
216
+ }
217
+
191
218
#if SPI_LITEX_ANY_HAS_IRQ
192
- if (dev_config -> has_irq ) {
219
+ if (SPI_LITEX_HAS_IRQ ) {
193
220
litex_write8 (BIT (0 ), dev_config -> core_master_ev_enable_addr );
194
221
litex_write8 (BIT (0 ), dev_config -> core_master_ev_pending_addr );
195
- k_sem_reset (& data -> sem_rx_ready );
222
+
223
+ spi_litex_spi_do_tx (dev );
224
+
225
+ ret = spi_context_wait_for_completion (ctx );
226
+
227
+ spi_context_release (ctx , ret );
228
+
229
+ return ret ;
196
230
}
197
231
#endif /* SPI_LITEX_ANY_HAS_IRQ */
198
232
199
233
do {
200
- len = MIN (spi_context_max_continuous_chunk (ctx ), dev_config -> core_master_rxtx_size );
201
- if (len != old_len ) {
202
- spiflash_len_mask_width_write (len * 8 , width , mask ,
203
- dev_config -> core_master_phyconfig_addr );
204
- old_len = len ;
205
- }
206
-
207
- if (spi_context_tx_buf_on (ctx )) {
208
- litex_spi_tx_put (len , & txd , ctx -> tx_buf );
209
- } else {
210
- txd = 0U ;
211
- }
234
+ spi_litex_spi_do_tx (dev );
212
235
213
236
while (!(litex_read8 (dev_config -> core_master_status_addr ) &
214
- BIT (SPIFLASH_CORE_MASTER_STATUS_TX_READY_OFFSET ))) {
237
+ BIT (SPIFLASH_CORE_MASTER_STATUS_RX_READY_OFFSET ))) {
215
238
;
216
239
}
217
240
218
- LOG_DBG ("txd: 0x%x" , txd );
219
- litex_write32 (txd , dev_config -> core_master_rxtx_addr );
220
-
221
- spi_context_update_tx (ctx , data -> dfs , len / data -> dfs );
222
-
223
- spi_litex_wait_for_rx_ready (dev );
224
-
225
- rxd = litex_read32 (dev_config -> core_master_rxtx_addr );
226
- LOG_DBG ("rxd: 0x%x" , rxd );
227
-
228
- if (spi_context_rx_buf_on (ctx )) {
229
- litex_spi_rx_put (len , & rxd , ctx -> rx_buf );
230
- }
231
-
232
- spi_context_update_rx (ctx , data -> dfs , len / data -> dfs );
233
-
241
+ spi_litex_spi_do_rx (dev );
234
242
} while (spi_context_tx_on (ctx ) || spi_context_rx_on (ctx ));
235
243
236
244
litex_write32 (0 , dev_config -> core_master_cs_addr );
237
245
238
- #if SPI_LITEX_ANY_HAS_IRQ
239
- if (dev_config -> has_irq ) {
240
- /* Wait for the RX ready event */
241
- litex_write8 (0 , dev_config -> core_master_ev_enable_addr );
242
- }
243
- #endif /* SPI_LITEX_ANY_HAS_IRQ */
244
246
spi_context_complete (ctx , dev , 0 );
245
247
246
248
return ret ;
247
249
}
248
250
249
- static int spi_litex_transceive (const struct device * dev , const struct spi_config * config ,
250
- const struct spi_buf_set * tx_bufs ,
251
- const struct spi_buf_set * rx_bufs )
251
+ static int transceive (const struct device * dev ,
252
+ const struct spi_config * config ,
253
+ const struct spi_buf_set * tx_bufs ,
254
+ const struct spi_buf_set * rx_bufs ,
255
+ bool asynchronous ,
256
+ spi_callback_t cb ,
257
+ void * userdata )
252
258
{
253
259
struct spi_litex_data * data = dev -> data ;
254
-
255
- int ret = spi_config (dev , config );
256
-
257
- if (ret ) {
258
- return ret ;
259
- }
260
+ int ret ;
260
261
261
262
if (!tx_bufs && !rx_bufs ) {
262
263
return 0 ;
263
264
}
265
+ #if SPI_LITEX_ANY_HAS_IRQ
266
+ if (!SPI_LITEX_HAS_IRQ && asynchronous ) {
267
+ return - ENOTSUP ;
268
+ }
269
+ #endif /* SPI_LITEX_ANY_HAS_IRQ */
270
+
271
+ spi_context_lock (& data -> ctx , asynchronous , cb , userdata , config );
272
+
273
+ ret = spi_config (dev , config );
274
+
275
+ if (ret < 0 ) {
276
+ return ret ;
277
+ }
264
278
265
279
spi_context_buffers_setup (& data -> ctx , tx_bufs , rx_bufs , data -> dfs );
266
280
@@ -269,19 +283,31 @@ static int spi_litex_transceive(const struct device *dev, const struct spi_confi
269
283
return ret ;
270
284
}
271
285
286
+ static int spi_litex_transceive (const struct device * dev ,
287
+ const struct spi_config * config ,
288
+ const struct spi_buf_set * tx_bufs ,
289
+ const struct spi_buf_set * rx_bufs )
290
+ {
291
+ return transceive (dev , config , tx_bufs , rx_bufs , false, NULL , NULL );
292
+ }
293
+
272
294
#ifdef CONFIG_SPI_ASYNC
273
- static int spi_litex_transceive_async (const struct device * dev , const struct spi_config * config ,
295
+ static int spi_litex_transceive_async (const struct device * dev ,
296
+ const struct spi_config * config ,
274
297
const struct spi_buf_set * tx_bufs ,
275
298
const struct spi_buf_set * rx_bufs ,
276
- struct k_poll_signal * async )
299
+ spi_callback_t cb ,
300
+ void * userdata )
277
301
{
278
- return - ENOTSUP ;
302
+ return transceive ( dev , config , tx_bufs , rx_bufs , true, cb , userdata ) ;
279
303
}
280
304
#endif /* CONFIG_SPI_ASYNC */
281
305
282
306
static int spi_litex_release (const struct device * dev , const struct spi_config * config )
283
307
{
308
+ struct spi_litex_data * data = dev -> data ;
284
309
310
+ spi_context_unlock_unconditionally (& data -> ctx );
285
311
return 0 ;
286
312
}
287
313
@@ -290,12 +316,26 @@ static void spi_litex_irq_handler(const struct device *dev)
290
316
{
291
317
struct spi_litex_data * data = dev -> data ;
292
318
const struct spi_litex_dev_config * dev_config = dev -> config ;
319
+ struct spi_context * ctx = & data -> ctx ;
320
+ uint32_t txd , rxd ;
321
+ uint8_t len ;
322
+ uint8_t old_len ;
293
323
294
324
if (litex_read8 (dev_config -> core_master_ev_pending_addr ) & BIT (0 )) {
295
- k_sem_give ( & data -> sem_rx_ready );
325
+ spi_litex_spi_do_rx ( dev );
296
326
297
327
/* ack reader irq */
298
328
litex_write8 (BIT (0 ), dev_config -> core_master_ev_pending_addr );
329
+
330
+ if (spi_context_tx_on (ctx ) || spi_context_rx_on (ctx )) {
331
+ spi_litex_spi_do_tx (dev );
332
+ } else {
333
+ litex_write8 (0 , dev_config -> core_master_ev_enable_addr );
334
+
335
+ litex_write32 (0 , dev_config -> core_master_cs_addr );
336
+
337
+ spi_context_complete (ctx , dev , 0 );
338
+ }
299
339
}
300
340
}
301
341
#endif /* SPI_LITEX_ANY_HAS_IRQ */
@@ -326,9 +366,6 @@ static DEVICE_API(spi, spi_litex_api) = {
326
366
return 0; \
327
367
};
328
368
329
- #define SPI_LITEX_IRQ_DATA (n ) \
330
- .sem_rx_ready = Z_SEM_INITIALIZER(spi_litex_data_##n.sem_rx_ready, 0, 1),
331
-
332
369
#define SPI_LITEX_IRQ_CONFIG (n ) \
333
370
.has_irq = DT_INST_IRQ_HAS_IDX(n, 0), \
334
371
.core_master_ev_pending_addr = DT_INST_REG_ADDR_BY_NAME_OR(n, core_master_ev_pending, 0), \
@@ -340,7 +377,6 @@ static DEVICE_API(spi, spi_litex_api) = {
340
377
static struct spi_litex_data spi_litex_data_##n = { \
341
378
SPI_CONTEXT_INIT_LOCK(spi_litex_data_##n, ctx), \
342
379
SPI_CONTEXT_INIT_SYNC(spi_litex_data_##n, ctx), \
343
- IF_ENABLED(SPI_LITEX_ANY_HAS_IRQ, (SPI_LITEX_IRQ_DATA(n))) \
344
380
}; \
345
381
\
346
382
static struct spi_litex_dev_config spi_litex_cfg_##n = { \
0 commit comments