Lines Matching +full:dma +full:- +full:channel +full:- +full:mask
4 * SPDX-License-Identifier: Apache-2.0
18 #include <zephyr/drivers/dma.h>
19 #include <zephyr/drivers/dma/dma_gd32.h>
30 /* SPI error status mask. */
45 uint32_t channel; member
65 const struct spi_gd32_dma_config dma[NUM_OF_DIRECTION]; member
75 struct spi_gd32_dma_data dma[NUM_OF_DIRECTION]; member
86 const struct spi_gd32_config *cfg = dev->config; in spi_gd32_dma_enabled()
88 if (cfg->dma[TX].dev && cfg->dma[RX].dev) { in spi_gd32_dma_enabled()
104 uint32_t stat = SPI_STAT(cfg->reg); in spi_gd32_get_err()
108 cfg->reg, stat & (uint32_t)SPI_GD32_ERR_MASK); in spi_gd32_get_err()
110 return -EIO; in spi_gd32_get_err()
118 return spi_context_tx_on(&data->ctx) || in spi_gd32_transfer_ongoing()
119 spi_context_rx_on(&data->ctx); in spi_gd32_transfer_ongoing()
125 struct spi_gd32_data *data = dev->data; in spi_gd32_configure()
126 const struct spi_gd32_config *cfg = dev->config; in spi_gd32_configure()
129 if (spi_context_configured(&data->ctx, config)) { in spi_gd32_configure()
133 if (SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_SLAVE) { in spi_gd32_configure()
135 return -ENOTSUP; in spi_gd32_configure()
138 SPI_CTL0(cfg->reg) &= ~SPI_CTL0_SPIEN; in spi_gd32_configure()
140 SPI_CTL0(cfg->reg) |= SPI_MASTER; in spi_gd32_configure()
141 SPI_CTL0(cfg->reg) &= ~SPI_TRANSMODE_BDTRANSMIT; in spi_gd32_configure()
143 if (SPI_WORD_SIZE_GET(config->operation) == 8) { in spi_gd32_configure()
144 SPI_CTL0(cfg->reg) |= SPI_FRAMESIZE_8BIT; in spi_gd32_configure()
146 SPI_CTL0(cfg->reg) |= SPI_FRAMESIZE_16BIT; in spi_gd32_configure()
150 SPI_CTL0(cfg->reg) &= ~SPI_CTL0_SWNSSEN; in spi_gd32_configure()
152 SPI_CTL0(cfg->reg) |= SPI_CTL0_SWNSSEN; in spi_gd32_configure()
158 SPI_CTL1(cfg->reg) |= SPI_CTL1_NSSDRV; in spi_gd32_configure()
161 SPI_CTL0(cfg->reg) &= ~SPI_CTL0_LF; in spi_gd32_configure()
162 if (config->operation & SPI_TRANSFER_LSB) { in spi_gd32_configure()
163 SPI_CTL0(cfg->reg) |= SPI_CTL0_LF; in spi_gd32_configure()
166 SPI_CTL0(cfg->reg) &= ~SPI_CTL0_CKPL; in spi_gd32_configure()
167 if (config->operation & SPI_MODE_CPOL) { in spi_gd32_configure()
168 SPI_CTL0(cfg->reg) |= SPI_CTL0_CKPL; in spi_gd32_configure()
171 SPI_CTL0(cfg->reg) &= ~SPI_CTL0_CKPH; in spi_gd32_configure()
172 if (config->operation & SPI_MODE_CPHA) { in spi_gd32_configure()
173 SPI_CTL0(cfg->reg) |= SPI_CTL0_CKPH; in spi_gd32_configure()
177 (clock_control_subsys_t)&cfg->clkid, in spi_gd32_configure()
182 if (bus_freq <= config->frequency) { in spi_gd32_configure()
183 SPI_CTL0(cfg->reg) &= ~SPI_CTL0_PSC; in spi_gd32_configure()
184 SPI_CTL0(cfg->reg) |= CTL0_PSC(i); in spi_gd32_configure()
189 data->ctx.config = config; in spi_gd32_configure()
196 struct spi_gd32_data *data = dev->data; in spi_gd32_frame_exchange()
197 const struct spi_gd32_config *cfg = dev->config; in spi_gd32_frame_exchange()
198 struct spi_context *ctx = &data->ctx; in spi_gd32_frame_exchange()
201 while ((SPI_STAT(cfg->reg) & SPI_STAT_TBE) == 0) { in spi_gd32_frame_exchange()
205 if (SPI_WORD_SIZE_GET(ctx->config->operation) == 8) { in spi_gd32_frame_exchange()
207 tx_frame = UNALIGNED_GET((uint8_t *)(data->ctx.tx_buf)); in spi_gd32_frame_exchange()
210 SPI_DATA(cfg->reg) = tx_frame; in spi_gd32_frame_exchange()
215 tx_frame = UNALIGNED_GET((uint8_t *)(data->ctx.tx_buf)); in spi_gd32_frame_exchange()
217 SPI_DATA(cfg->reg) = tx_frame; in spi_gd32_frame_exchange()
222 while ((SPI_STAT(cfg->reg) & SPI_STAT_RBNE) == 0) { in spi_gd32_frame_exchange()
226 if (SPI_WORD_SIZE_GET(data->ctx.config->operation) == 8) { in spi_gd32_frame_exchange()
228 rx_frame = SPI_DATA(cfg->reg); in spi_gd32_frame_exchange()
230 UNALIGNED_PUT(rx_frame, (uint8_t *)data->ctx.rx_buf); in spi_gd32_frame_exchange()
235 rx_frame = SPI_DATA(cfg->reg); in spi_gd32_frame_exchange()
237 UNALIGNED_PUT(rx_frame, (uint16_t *)data->ctx.rx_buf); in spi_gd32_frame_exchange()
248 uint32_t channel, int status);
252 const struct spi_gd32_config *cfg = dev->config; in spi_gd32_dma_setup()
253 struct spi_gd32_data *data = dev->data; in spi_gd32_dma_setup()
254 struct dma_config *dma_cfg = &data->dma[dir].config; in spi_gd32_dma_setup()
255 struct dma_block_config *block_cfg = &data->dma[dir].block; in spi_gd32_dma_setup()
256 const struct spi_gd32_dma_config *dma = &cfg->dma[dir]; in spi_gd32_dma_setup() local
262 dma_cfg->source_burst_length = 1; in spi_gd32_dma_setup()
263 dma_cfg->dest_burst_length = 1; in spi_gd32_dma_setup()
264 dma_cfg->user_data = (void *)dev; in spi_gd32_dma_setup()
265 dma_cfg->dma_callback = spi_gd32_dma_callback; in spi_gd32_dma_setup()
266 dma_cfg->block_count = 1U; in spi_gd32_dma_setup()
267 dma_cfg->head_block = block_cfg; in spi_gd32_dma_setup()
268 dma_cfg->dma_slot = cfg->dma[dir].slot; in spi_gd32_dma_setup()
269 dma_cfg->channel_priority = in spi_gd32_dma_setup()
270 GD32_DMA_CONFIG_PRIORITY(cfg->dma[dir].config); in spi_gd32_dma_setup()
271 dma_cfg->channel_direction = in spi_gd32_dma_setup()
274 if (SPI_WORD_SIZE_GET(data->ctx.config->operation) == 8) { in spi_gd32_dma_setup()
275 dma_cfg->source_data_size = 1; in spi_gd32_dma_setup()
276 dma_cfg->dest_data_size = 1; in spi_gd32_dma_setup()
278 dma_cfg->source_data_size = 2; in spi_gd32_dma_setup()
279 dma_cfg->dest_data_size = 2; in spi_gd32_dma_setup()
282 block_cfg->block_size = spi_context_max_continuous_chunk(&data->ctx); in spi_gd32_dma_setup()
285 block_cfg->dest_address = (uint32_t)&SPI_DATA(cfg->reg); in spi_gd32_dma_setup()
286 block_cfg->dest_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; in spi_gd32_dma_setup()
287 if (spi_context_tx_buf_on(&data->ctx)) { in spi_gd32_dma_setup()
288 block_cfg->source_address = (uint32_t)data->ctx.tx_buf; in spi_gd32_dma_setup()
289 block_cfg->source_addr_adj = DMA_ADDR_ADJ_INCREMENT; in spi_gd32_dma_setup()
291 block_cfg->source_address = (uint32_t)&dummy_tx; in spi_gd32_dma_setup()
292 block_cfg->source_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; in spi_gd32_dma_setup()
297 block_cfg->source_address = (uint32_t)&SPI_DATA(cfg->reg); in spi_gd32_dma_setup()
298 block_cfg->source_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; in spi_gd32_dma_setup()
300 if (spi_context_rx_buf_on(&data->ctx)) { in spi_gd32_dma_setup()
301 block_cfg->dest_address = (uint32_t)data->ctx.rx_buf; in spi_gd32_dma_setup()
302 block_cfg->dest_addr_adj = DMA_ADDR_ADJ_INCREMENT; in spi_gd32_dma_setup()
304 block_cfg->dest_address = (uint32_t)&dummy_rx; in spi_gd32_dma_setup()
305 block_cfg->dest_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; in spi_gd32_dma_setup()
309 ret = dma_config(dma->dev, dma->channel, dma_cfg); in spi_gd32_dma_setup()
311 LOG_ERR("dma_config %p failed %d\n", dma->dev, ret); in spi_gd32_dma_setup()
315 ret = dma_start(dma->dev, dma->channel); in spi_gd32_dma_setup()
317 LOG_ERR("dma_start %p failed %d\n", dma->dev, ret); in spi_gd32_dma_setup()
326 const struct spi_gd32_config *cfg = dev->config; in spi_gd32_start_dma_transceive()
327 struct spi_gd32_data *data = dev->data; in spi_gd32_start_dma_transceive()
328 const size_t chunk_len = spi_context_max_continuous_chunk(&data->ctx); in spi_gd32_start_dma_transceive()
333 dma_get_status(cfg->dma[i].dev, cfg->dma[i].channel, &stat); in spi_gd32_start_dma_transceive()
334 if ((chunk_len != data->dma[i].count) && !stat.busy) { in spi_gd32_start_dma_transceive()
342 SPI_CTL1(cfg->reg) |= (SPI_CTL1_DMATEN | SPI_CTL1_DMAREN); in spi_gd32_start_dma_transceive()
347 dma_stop(cfg->dma[i].dev, cfg->dma[i].channel); in spi_gd32_start_dma_transceive()
361 struct spi_gd32_data *data = dev->data; in spi_gd32_transceive_impl()
362 const struct spi_gd32_config *cfg = dev->config; in spi_gd32_transceive_impl()
365 spi_context_lock(&data->ctx, (cb != NULL), cb, userdata, config); in spi_gd32_transceive_impl()
372 SPI_CTL0(cfg->reg) |= SPI_CTL0_SPIEN; in spi_gd32_transceive_impl()
374 spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, 1); in spi_gd32_transceive_impl()
376 spi_context_cs_control(&data->ctx, true); in spi_gd32_transceive_impl()
381 for (size_t i = 0; i < ARRAY_SIZE(data->dma); i++) { in spi_gd32_transceive_impl()
382 data->dma[i].count = 0; in spi_gd32_transceive_impl()
392 SPI_STAT(cfg->reg) &= in spi_gd32_transceive_impl()
394 SPI_CTL1(cfg->reg) |= in spi_gd32_transceive_impl()
397 ret = spi_context_wait_for_completion(&data->ctx); in spi_gd32_transceive_impl()
407 spi_context_complete(&data->ctx, dev, ret); in spi_gd32_transceive_impl()
411 while (!(SPI_STAT(cfg->reg) & SPI_STAT_TBE) || in spi_gd32_transceive_impl()
412 (SPI_STAT(cfg->reg) & SPI_STAT_TRANS)) { in spi_gd32_transceive_impl()
418 SPI_CTL1(cfg->reg) &= in spi_gd32_transceive_impl()
421 spi_context_cs_control(&data->ctx, false); in spi_gd32_transceive_impl()
423 SPI_CTL0(cfg->reg) &= in spi_gd32_transceive_impl()
427 spi_context_release(&data->ctx, ret); in spi_gd32_transceive_impl()
456 struct spi_gd32_data *data = dev->data; in spi_gd32_complete()
457 const struct spi_gd32_config *cfg = dev->config; in spi_gd32_complete()
459 SPI_CTL1(cfg->reg) &= in spi_gd32_complete()
464 dma_stop(cfg->dma[i].dev, cfg->dma[i].channel); in spi_gd32_complete()
468 spi_context_complete(&data->ctx, dev, status); in spi_gd32_complete()
473 const struct spi_gd32_config *cfg = dev->config; in spi_gd32_isr()
474 struct spi_gd32_data *data = dev->data; in spi_gd32_isr()
498 struct spi_gd32_data *data = dev->data; in spi_gd32_chunk_transfer_finished()
499 struct spi_gd32_dma_data *dma = data->dma; in spi_gd32_chunk_transfer_finished() local
500 const size_t chunk_len = spi_context_max_continuous_chunk(&data->ctx); in spi_gd32_chunk_transfer_finished()
502 return (MIN(dma[TX].count, dma[RX].count) >= chunk_len); in spi_gd32_chunk_transfer_finished()
506 uint32_t channel, int status) in spi_gd32_dma_callback() argument
509 const struct spi_gd32_config *cfg = dev->config; in spi_gd32_dma_callback()
510 struct spi_gd32_data *data = dev->data; in spi_gd32_dma_callback()
511 const size_t chunk_len = spi_context_max_continuous_chunk(&data->ctx); in spi_gd32_dma_callback()
515 LOG_ERR("dma:%p ch:%d callback gets error: %d", dma_dev, channel, in spi_gd32_dma_callback()
521 for (size_t i = 0; i < ARRAY_SIZE(cfg->dma); i++) { in spi_gd32_dma_callback()
522 if (dma_dev == cfg->dma[i].dev && in spi_gd32_dma_callback()
523 channel == cfg->dma[i].channel) { in spi_gd32_dma_callback()
524 data->dma[i].count += chunk_len; in spi_gd32_dma_callback()
529 * The transmission of this chunk is complete if both the dma[TX].count in spi_gd32_dma_callback()
530 * and the dma[RX].count reach greater than or equal to the chunk_len. in spi_gd32_dma_callback()
534 if (SPI_WORD_SIZE_GET(data->ctx.config->operation) == 8) { in spi_gd32_dma_callback()
535 spi_context_update_tx(&data->ctx, 1, chunk_len); in spi_gd32_dma_callback()
536 spi_context_update_rx(&data->ctx, 1, chunk_len); in spi_gd32_dma_callback()
538 spi_context_update_tx(&data->ctx, 2, chunk_len); in spi_gd32_dma_callback()
539 spi_context_update_rx(&data->ctx, 2, chunk_len); in spi_gd32_dma_callback()
546 data->dma[TX].count = 0; in spi_gd32_dma_callback()
547 data->dma[RX].count = 0; in spi_gd32_dma_callback()
550 spi_context_complete(&data->ctx, dev, 0); in spi_gd32_dma_callback()
561 #endif /* DMA */
566 struct spi_gd32_data *data = dev->data; in spi_gd32_release()
568 spi_context_unlock_unconditionally(&data->ctx); in spi_gd32_release()
586 struct spi_gd32_data *data = dev->data; in spi_gd32_init()
587 const struct spi_gd32_config *cfg = dev->config; in spi_gd32_init()
594 (clock_control_subsys_t)&cfg->clkid); in spi_gd32_init()
596 (void)reset_line_toggle_dt(&cfg->reset); in spi_gd32_init()
598 ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); in spi_gd32_init()
605 if ((cfg->dma[RX].dev && !cfg->dma[TX].dev) || in spi_gd32_init()
606 (cfg->dma[TX].dev && !cfg->dma[RX].dev)) { in spi_gd32_init()
607 LOG_ERR("DMA must be enabled for both TX and RX channels"); in spi_gd32_init()
608 return -ENODEV; in spi_gd32_init()
612 if (!device_is_ready(cfg->dma[i].dev)) { in spi_gd32_init()
613 LOG_ERR("DMA %s not ready", cfg->dma[i].dev->name); in spi_gd32_init()
614 return -ENODEV; in spi_gd32_init()
617 ch_filter = BIT(cfg->dma[i].channel); in spi_gd32_init()
618 ret = dma_request_channel(cfg->dma[i].dev, &ch_filter); in spi_gd32_init()
626 ret = spi_context_cs_configure_all(&data->ctx); in spi_gd32_init()
632 cfg->irq_configure(dev); in spi_gd32_init()
635 spi_context_unlock_unconditionally(&data->ctx); in spi_gd32_init()
643 .channel = DT_INST_DMAS_CELL_BY_NAME(idx, dir, channel), \
683 IF_ENABLED(CONFIG_SPI_GD32_DMA, (.dma = DMAS_DECL(idx),)) \