1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2021 Adrian Chadd <adrian@FreeBSD.org> 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 #ifndef __QCOM_SPI_VAR_H__ 29 #define __QCOM_SPI_VAR_H__ 30 31 typedef enum { 32 QCOM_SPI_HW_QPI_V1_1 = 1, 33 QCOM_SPI_HW_QPI_V2_1 = 2, 34 QCOM_SPI_HW_QPI_V2_2 = 3, 35 } qcom_spi_hw_version_t; 36 37 #define CS_MAX 4 38 39 struct qcom_spi_softc { 40 device_t sc_dev; 41 device_t spibus; 42 43 uint32_t sc_debug; 44 45 struct resource *sc_mem_res; 46 struct resource *sc_irq_res; 47 void *sc_irq_h; 48 49 struct mtx sc_mtx; 50 bool sc_busy; /* an SPI transfer (cmd+data) 51 * is active */ 52 53 qcom_spi_hw_version_t hw_version; 54 55 clk_t clk_core; /* QUP/SPI core */ 56 clk_t clk_iface; /* SPI interface */ 57 58 /* For GPIO chip selects .. */ 59 gpio_pin_t cs_pins[CS_MAX]; 60 61 struct { 62 /* 63 * FIFO size / block size in bytes. 64 * 65 * The FIFO slots are DWORD sized, not byte sized. 66 * So if the transfer size is set to 8 bits per 67 * word (which is what we'll support initially) 68 * the effective available FIFO is 69 * fifo_size / sizeof(uint32_t). 70 */ 71 uint32_t input_block_size; 72 uint32_t output_block_size; 73 uint32_t input_fifo_size; 74 uint32_t output_fifo_size; 75 76 uint32_t cs_select; 77 uint32_t num_cs; 78 uint32_t max_frequency; 79 } config; 80 81 struct { 82 uint32_t transfer_mode; /* QUP_IO_M_MODE_* */ 83 uint32_t transfer_word_size; /* how many bytes in a transfer word */ 84 uint32_t frequency; 85 bool cs_high; /* true if CS is high for active */ 86 } state; 87 88 struct { 89 bool tx_dma_done; 90 bool rx_dma_done; 91 bool done; 92 bool do_tx; 93 bool do_rx; 94 bool error; 95 } intr; 96 97 struct { 98 bool active; /* a (sub) transfer is active */ 99 uint32_t num_words; /* number of word_size words to transfer */ 100 const char *tx_buf; 101 int tx_len; 102 int tx_offset; 103 char *rx_buf; 104 int rx_len; 105 int rx_offset; 106 bool done; 107 } transfer; 108 }; 109 110 #define QCOM_SPI_QUP_VERSION_V1(sc) \ 111 ((sc)->hw_version == QCOM_SPI_HW_QPI_V1_1) 112 113 #define QCOM_SPI_LOCK(sc) mtx_lock(&(sc)->sc_mtx) 114 #define QCOM_SPI_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx) 115 #define QCOM_SPI_ASSERT_LOCKED(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED) 116 #define QCOM_SPI_READ_4(sc, reg) bus_read_4((sc)->sc_mem_res, (reg)) 117 #define QCOM_SPI_WRITE_4(sc, reg, val) bus_write_4((sc)->sc_mem_res, \ 118 (reg), (val)) 119 120 /* XXX TODO: the region size should be in the tag or softc */ 121 #define QCOM_SPI_BARRIER_WRITE(sc) bus_barrier((sc)->sc_mem_res, \ 122 0, 0x600, BUS_SPACE_BARRIER_WRITE) 123 #define QCOM_SPI_BARRIER_READ(sc) bus_barrier((sc)->sc_mem_res, \ 124 0, 0x600, BUS_SPACE_BARRIER_READ) 125 #define QCOM_SPI_BARRIER_RW(sc) bus_barrier((sc)->sc_mem_res, \ 126 0, 0x600, BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE) 127 128 extern int qcom_spi_hw_read_controller_transfer_sizes( 129 struct qcom_spi_softc *sc); 130 extern int qcom_spi_hw_qup_set_state_locked(struct qcom_spi_softc *sc, 131 uint32_t state); 132 extern int qcom_spi_hw_qup_init_locked(struct qcom_spi_softc *sc); 133 extern int qcom_spi_hw_spi_init_locked(struct qcom_spi_softc *sc); 134 extern int qcom_spi_hw_spi_cs_force(struct qcom_spi_softc *sc, int cs, 135 bool enable); 136 extern int qcom_spi_hw_interrupt_handle(struct qcom_spi_softc *sc); 137 extern int qcom_spi_hw_setup_transfer_selection(struct qcom_spi_softc *sc, 138 uint32_t len); 139 extern int qcom_spi_hw_complete_transfer(struct qcom_spi_softc *sc); 140 141 extern int qcom_spi_hw_setup_current_transfer(struct qcom_spi_softc *sc); 142 extern int qcom_spi_hw_setup_pio_transfer_cnt(struct qcom_spi_softc *sc); 143 extern int qcom_spi_hw_setup_block_transfer_cnt(struct qcom_spi_softc *sc); 144 extern int qcom_spi_hw_setup_io_modes(struct qcom_spi_softc *sc); 145 extern int qcom_spi_hw_setup_spi_io_clock_polarity( 146 struct qcom_spi_softc *sc, bool cpol); 147 extern int qcom_spi_hw_setup_spi_config(struct qcom_spi_softc *sc, 148 uint32_t clock_val, bool cpha); 149 extern int qcom_spi_hw_setup_qup_config(struct qcom_spi_softc *sc, 150 bool is_tx, bool is_rx); 151 extern int qcom_spi_hw_setup_operational_mask(struct qcom_spi_softc *sc); 152 extern int qcom_spi_hw_ack_write_pio_fifo(struct qcom_spi_softc *sc); 153 extern int qcom_spi_hw_ack_opmode(struct qcom_spi_softc *sc); 154 extern int qcom_spi_hw_write_pio_fifo(struct qcom_spi_softc *sc); 155 extern int qcom_spi_hw_write_pio_block(struct qcom_spi_softc *sc); 156 extern int qcom_spi_hw_read_pio_fifo(struct qcom_spi_softc *sc); 157 extern int qcom_spi_hw_read_pio_block(struct qcom_spi_softc *sc); 158 extern int qcom_spi_hw_do_full_reset(struct qcom_spi_softc *sc); 159 160 #endif /* __QCOM_SPI_VAR_H__ */ 161