Lines Matching +full:data +full:- +full:transfer
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
78 sc->config.input_block_size = 4; in qcom_spi_hw_read_controller_transfer_sizes()
80 sc->config.input_block_size = val * 16; in qcom_spi_hw_read_controller_transfer_sizes()
86 sc->config.output_block_size = 4; in qcom_spi_hw_read_controller_transfer_sizes()
88 sc->config.output_block_size = val * 16; in qcom_spi_hw_read_controller_transfer_sizes()
93 sc->config.input_fifo_size = in qcom_spi_hw_read_controller_transfer_sizes()
94 sc->config.input_block_size * (2 << val); in qcom_spi_hw_read_controller_transfer_sizes()
99 sc->config.output_fifo_size = in qcom_spi_hw_read_controller_transfer_sizes()
100 sc->config.output_block_size * (2 << val); in qcom_spi_hw_read_controller_transfer_sizes()
128 device_printf(sc->sc_dev, in qcom_spi_hw_qup_wait_state_valid_locked()
141 if (sc->state.transfer_mode == QUP_IO_M_MODE_DMOV) in qcom_spi_hw_is_opmode_dma_locked()
143 if (sc->state.transfer_mode == QUP_IO_M_MODE_BAM) in qcom_spi_hw_is_opmode_dma_locked()
218 device_printf(sc->sc_dev, "ERROR: %s: couldn't reset\n", in qcom_spi_hw_qup_init_locked()
261 /* Initial CS/tri-state io control config */ in qcom_spi_hw_spi_init_locked()
264 | SPI_IO_C_CS_SELECT(sc->config.cs_select)); in qcom_spi_hw_spi_init_locked()
275 * the SPI transfer machine do its thing. If you want to be able
279 * NOR/NAND devices tend to stop a block transfer.)
333 device_printf(sc->sc_dev, "ERROR: (QUP) mask=0x%08x\n", in qcom_spi_hw_interrupt_handle()
335 sc->intr.error = true; in qcom_spi_hw_interrupt_handle()
338 device_printf(sc->sc_dev, "ERROR: (SPI) mask=0x%08x\n", in qcom_spi_hw_interrupt_handle()
340 sc->intr.error = true; in qcom_spi_hw_interrupt_handle()
349 sc->intr.rx_dma_done = true; in qcom_spi_hw_interrupt_handle()
352 sc->intr.tx_dma_done = true; in qcom_spi_hw_interrupt_handle()
356 sc->intr.do_rx = true; in qcom_spi_hw_interrupt_handle()
358 sc->intr.do_tx = true; in qcom_spi_hw_interrupt_handle()
363 sc->intr.done = true; in qcom_spi_hw_interrupt_handle()
364 if (sc->intr.error) in qcom_spi_hw_interrupt_handle()
365 sc->intr.done = true; in qcom_spi_hw_interrupt_handle()
371 * Make initial transfer selections based on the transfer sizes
384 * For now only support doing a single FIFO transfer. in qcom_spi_hw_setup_transfer_selection()
385 * The main PIO transfer routine loop will break it up for us. in qcom_spi_hw_setup_transfer_selection()
387 sc->state.transfer_mode = QUP_IO_M_MODE_FIFO; in qcom_spi_hw_setup_transfer_selection()
388 sc->transfer.tx_offset = 0; in qcom_spi_hw_setup_transfer_selection()
389 sc->transfer.rx_offset = 0; in qcom_spi_hw_setup_transfer_selection()
390 sc->transfer.tx_len = 0; in qcom_spi_hw_setup_transfer_selection()
391 sc->transfer.rx_len = 0; in qcom_spi_hw_setup_transfer_selection()
392 sc->transfer.tx_buf = NULL; in qcom_spi_hw_setup_transfer_selection()
393 sc->transfer.rx_buf = NULL; in qcom_spi_hw_setup_transfer_selection()
403 sc->state.transfer_word_size = 4; in qcom_spi_hw_setup_transfer_selection()
405 sc->state.transfer_word_size = 1; in qcom_spi_hw_setup_transfer_selection()
411 * Blank the transfer state after a full transfer is completed.
418 sc->state.transfer_mode = QUP_IO_M_MODE_FIFO; in qcom_spi_hw_complete_transfer()
419 sc->transfer.tx_offset = 0; in qcom_spi_hw_complete_transfer()
420 sc->transfer.rx_offset = 0; in qcom_spi_hw_complete_transfer()
421 sc->transfer.tx_len = 0; in qcom_spi_hw_complete_transfer()
422 sc->transfer.rx_len = 0; in qcom_spi_hw_complete_transfer()
423 sc->transfer.tx_buf = NULL; in qcom_spi_hw_complete_transfer()
424 sc->transfer.rx_buf = NULL; in qcom_spi_hw_complete_transfer()
425 sc->state.transfer_word_size = 0; in qcom_spi_hw_complete_transfer()
430 * Configure up the transfer selection for the current transfer.
432 * This calculates how many words we can transfer in the current
433 * transfer and what's left to transfer.
447 * if the transfer sizes are not symmetrical.) in qcom_spi_hw_setup_current_transfer()
449 bytes_left = sc->transfer.tx_len - sc->transfer.tx_offset; in qcom_spi_hw_setup_current_transfer()
451 if (sc->state.transfer_mode == QUP_IO_M_MODE_FIFO) { in qcom_spi_hw_setup_current_transfer()
458 sc->transfer.num_words = bytes_left / sc->state.transfer_word_size; in qcom_spi_hw_setup_current_transfer()
459 sc->transfer.num_words = MIN(sc->transfer.num_words, in qcom_spi_hw_setup_current_transfer()
460 sc->config.input_fifo_size / sizeof(uint32_t)); in qcom_spi_hw_setup_current_transfer()
461 } else if (sc->state.transfer_mode == QUP_IO_M_MODE_BLOCK) { in qcom_spi_hw_setup_current_transfer()
466 * our maximum transfer size will ACTUALLY be capped by in qcom_spi_hw_setup_current_transfer()
467 * SPI_MAX_XFER (65536-64 bytes.) Each transfer in qcom_spi_hw_setup_current_transfer()
469 * last transfer. in qcom_spi_hw_setup_current_transfer()
471 sc->transfer.num_words = bytes_left / sc->state.transfer_word_size; in qcom_spi_hw_setup_current_transfer()
472 sc->transfer.num_words = MIN(sc->transfer.num_words, in qcom_spi_hw_setup_current_transfer()
478 "%s: transfer.tx_len=%u," in qcom_spi_hw_setup_current_transfer()
479 "transfer.tx_offset=%u," in qcom_spi_hw_setup_current_transfer()
483 sc->transfer.tx_len, in qcom_spi_hw_setup_current_transfer()
484 sc->transfer.tx_offset, in qcom_spi_hw_setup_current_transfer()
485 sc->state.transfer_word_size, in qcom_spi_hw_setup_current_transfer()
487 sc->transfer.num_words, in qcom_spi_hw_setup_current_transfer()
488 sc->config.input_fifo_size / sizeof(uint32_t)); in qcom_spi_hw_setup_current_transfer()
494 * Setup the PIO FIFO transfer count.
505 QCOM_SPI_WRITE_4(sc, QUP_MX_READ_CNT, sc->transfer.num_words); in qcom_spi_hw_setup_pio_transfer_cnt()
506 QCOM_SPI_WRITE_4(sc, QUP_MX_WRITE_CNT, sc->transfer.num_words); in qcom_spi_hw_setup_pio_transfer_cnt()
512 sc->transfer.num_words); in qcom_spi_hw_setup_pio_transfer_cnt()
520 * Setup the PIO BLOCK transfer count.
522 * This sets up the total transfer size, in TX/RX FIFO block size
524 * chunk of data is avaliable or required.
534 QCOM_SPI_WRITE_4(sc, QUP_MX_INPUT_CNT, sc->transfer.num_words); in qcom_spi_hw_setup_block_transfer_cnt()
535 QCOM_SPI_WRITE_4(sc, QUP_MX_OUTPUT_CNT, sc->transfer.num_words); in qcom_spi_hw_setup_block_transfer_cnt()
559 * see the pio/block transfer routines. in qcom_spi_hw_setup_io_modes()
566 /* Transfer mode */ in qcom_spi_hw_setup_io_modes()
567 reg |= ((sc->state.transfer_mode & QUP_IO_M_INPUT_MODE_MASK) in qcom_spi_hw_setup_io_modes()
569 reg |= ((sc->state.transfer_mode & QUP_IO_M_OUTPUT_MODE_MASK) in qcom_spi_hw_setup_io_modes()
613 * or the clock/transfer phase. When we do then here's where we in qcom_spi_hw_setup_spi_config()
631 * Note - don't do this if SPI loopback is enabled! in qcom_spi_hw_setup_spi_config()
661 reg |= ((sc->state.transfer_word_size * 8) - 1) & QUP_CONFIG_N; in qcom_spi_hw_setup_qup_config()
665 * data in, out, and/or both. For PIO/block modes it must stay in qcom_spi_hw_setup_qup_config()
737 * pre-shifting it into the place requested.
748 if (sc->transfer.tx_buf == NULL) in qcom_spi_hw_write_from_tx_buf()
751 if (sc->transfer.tx_offset < sc->transfer.tx_len) { in qcom_spi_hw_write_from_tx_buf()
752 *val |= (sc->transfer.tx_buf[sc->transfer.tx_offset] & 0xff) in qcom_spi_hw_write_from_tx_buf()
754 sc->transfer.tx_offset++; in qcom_spi_hw_write_from_tx_buf()
773 * Loop over the transfer num_words, do complain if we are full. in qcom_spi_hw_write_pio_fifo()
775 for (i = 0; i < sc->transfer.num_words; i++) { in qcom_spi_hw_write_pio_fifo()
781 device_printf(sc->sc_dev, "%s: FIFO full\n", __func__); in qcom_spi_hw_write_pio_fifo()
786 * Handle 1, 2, 4 byte transfer packing rules. in qcom_spi_hw_write_pio_fifo()
791 * (and u-boot uses it!) but I'll stick with what Linux is in qcom_spi_hw_write_pio_fifo()
794 * The format is the same as 4 byte RX - 0xaabbccdd; in qcom_spi_hw_write_pio_fifo()
798 if (sc->state.transfer_word_size == 1) { in qcom_spi_hw_write_pio_fifo()
801 } else if (sc->state.transfer_word_size == 2) { in qcom_spi_hw_write_pio_fifo()
806 } else if (sc->state.transfer_word_size == 4) { in qcom_spi_hw_write_pio_fifo()
828 __func__, num_bytes, sc->transfer.num_words); in qcom_spi_hw_write_pio_fifo()
841 * Read data into the RX buffer and increment the RX offset.
851 if (sc->transfer.rx_buf == NULL) in qcom_spi_hw_read_into_rx_buf()
855 if (sc->transfer.rx_offset < sc->transfer.rx_len) { in qcom_spi_hw_read_into_rx_buf()
856 sc->transfer.rx_buf[sc->transfer.rx_offset] = val; in qcom_spi_hw_read_into_rx_buf()
857 sc->transfer.rx_offset++; in qcom_spi_hw_read_into_rx_buf()
880 for (i = 0; i < sc->transfer.num_words; i++) { in qcom_spi_hw_read_pio_fifo()
885 device_printf(sc->sc_dev, "%s: FIFO empty\n", __func__); in qcom_spi_hw_read_pio_fifo()
890 * Always read num_words up to FIFO being non-empty; that way in qcom_spi_hw_read_pio_fifo()
891 * if we have mis-matching TX/RX buffer sizes for some reason in qcom_spi_hw_read_pio_fifo()
898 * doing 1, 2, or 4 byte transfer words. in qcom_spi_hw_read_pio_fifo()
900 if (sc->state.transfer_word_size == 1) { in qcom_spi_hw_read_pio_fifo()
903 } else if (sc->state.transfer_word_size == 2) { in qcom_spi_hw_read_pio_fifo()
908 } else if (sc->state.transfer_word_size == 4) { in qcom_spi_hw_read_pio_fifo()
921 "%s: read %d bytes (%d transfer words)\n", in qcom_spi_hw_read_pio_fifo()
922 __func__, num_bytes, sc->transfer.num_words); in qcom_spi_hw_read_pio_fifo()
926 * This is a no-op for FIFO mode, it's only a thing for BLOCK in qcom_spi_hw_read_pio_fifo()
932 device_printf(sc->sc_dev, "%s: read complete (DONE)\n" , in qcom_spi_hw_read_pio_fifo()
934 sc->intr.done = true; in qcom_spi_hw_read_pio_fifo()
940 * And see if we've finished the transfer and won't be getting in qcom_spi_hw_read_pio_fifo()
944 * we get an interrupt when the FIFO has enough data present. in qcom_spi_hw_read_pio_fifo()
946 if ((sc->state.transfer_mode == QUP_IO_M_MODE_FIFO) in qcom_spi_hw_read_pio_fifo()
947 && (sc->transfer.rx_offset >= sc->transfer.rx_len)) { in qcom_spi_hw_read_pio_fifo()
948 device_printf(sc->sc_dev, "%s: read complete (rxlen)\n", in qcom_spi_hw_read_pio_fifo()
950 sc->intr.done = true; in qcom_spi_hw_read_pio_fifo()
956 * the FIFO transfer. We won't get any subsequent transfers; in qcom_spi_hw_read_pio_fifo()
957 * we'll need to schedule a new FIFO transfer. in qcom_spi_hw_read_pio_fifo()
959 sc->intr.done = true; in qcom_spi_hw_read_pio_fifo()