1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 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 * $FreeBSD$ 28 */ 29 30 #ifndef __QCOM_SPI_VAR_H__ 31 #define __QCOM_SPI_VAR_H__ 32 33 typedef enum { 34 QCOM_SPI_HW_QPI_V1_1 = 1, 35 QCOM_SPI_HW_QPI_V2_1 = 2, 36 QCOM_SPI_HW_QPI_V2_2 = 3, 37 } qcom_spi_hw_version_t; 38 39 #define CS_MAX 4 40 41 struct qcom_spi_softc { 42 device_t sc_dev; 43 device_t spibus; 44 45 uint32_t sc_debug; 46 47 struct resource *sc_mem_res; 48 struct resource *sc_irq_res; 49 void *sc_irq_h; 50 51 struct mtx sc_mtx; 52 bool sc_busy; /* an SPI transfer (cmd+data) 53 * is active */ 54 55 qcom_spi_hw_version_t hw_version; 56 57 clk_t clk_core; /* QUP/SPI core */ 58 clk_t clk_iface; /* SPI interface */ 59 60 /* For GPIO chip selects .. */ 61 gpio_pin_t cs_pins[CS_MAX]; 62 63 struct { 64 /* 65 * FIFO size / block size in bytes. 66 * 67 * The FIFO slots are DWORD sized, not byte sized. 68 * So if the transfer size is set to 8 bits per 69 * word (which is what we'll support initially) 70 * the effective available FIFO is 71 * fifo_size / sizeof(uint32_t). 72 */ 73 uint32_t input_block_size; 74 uint32_t output_block_size; 75 uint32_t input_fifo_size; 76 uint32_t output_fifo_size; 77 78 uint32_t cs_select; 79 uint32_t num_cs; 80 uint32_t max_frequency; 81 } config; 82 83 struct { 84 uint32_t transfer_mode; /* QUP_IO_M_MODE_* */ 85 uint32_t transfer_word_size; /* how many bytes in a transfer word */ 86 uint32_t frequency; 87 bool cs_high; /* true if CS is high for active */ 88 } state; 89 90 struct { 91 bool tx_dma_done; 92 bool rx_dma_done; 93 bool done; 94 bool do_tx; 95 bool do_rx; 96 bool error; 97 } intr; 98 99 struct { 100 bool active; /* a (sub) transfer is active */ 101 uint32_t num_words; /* number of word_size words to transfer */ 102 const char *tx_buf; 103 int tx_len; 104 int tx_offset; 105 char *rx_buf; 106 int rx_len; 107 int rx_offset; 108 bool done; 109 } transfer; 110 }; 111 112 #define QCOM_SPI_QUP_VERSION_V1(sc) \ 113 ((sc)->hw_version == QCOM_SPI_HW_QPI_V1_1) 114 115 #define QCOM_SPI_LOCK(sc) mtx_lock(&(sc)->sc_mtx) 116 #define QCOM_SPI_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx) 117 #define QCOM_SPI_ASSERT_LOCKED(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED) 118 #define QCOM_SPI_READ_4(sc, reg) bus_read_4((sc)->sc_mem_res, (reg)) 119 #define QCOM_SPI_WRITE_4(sc, reg, val) bus_write_4((sc)->sc_mem_res, \ 120 (reg), (val)) 121 122 /* XXX TODO: the region size should be in the tag or softc */ 123 #define QCOM_SPI_BARRIER_WRITE(sc) bus_barrier((sc)->sc_mem_res, \ 124 0, 0x600, BUS_SPACE_BARRIER_WRITE) 125 #define QCOM_SPI_BARRIER_READ(sc) bus_barrier((sc)->sc_mem_res, \ 126 0, 0x600, BUS_SPACE_BARRIER_READ) 127 #define QCOM_SPI_BARRIER_RW(sc) bus_barrier((sc)->sc_mem_res, \ 128 0, 0x600, BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE) 129 130 extern int qcom_spi_hw_read_controller_transfer_sizes( 131 struct qcom_spi_softc *sc); 132 extern int qcom_spi_hw_qup_set_state_locked(struct qcom_spi_softc *sc, 133 uint32_t state); 134 extern int qcom_spi_hw_qup_init_locked(struct qcom_spi_softc *sc); 135 extern int qcom_spi_hw_spi_init_locked(struct qcom_spi_softc *sc); 136 extern int qcom_spi_hw_spi_cs_force(struct qcom_spi_softc *sc, int cs, 137 bool enable); 138 extern int qcom_spi_hw_interrupt_handle(struct qcom_spi_softc *sc); 139 extern int qcom_spi_hw_setup_transfer_selection(struct qcom_spi_softc *sc, 140 uint32_t len); 141 extern int qcom_spi_hw_complete_transfer(struct qcom_spi_softc *sc); 142 143 extern int qcom_spi_hw_setup_current_transfer(struct qcom_spi_softc *sc); 144 extern int qcom_spi_hw_setup_pio_transfer_cnt(struct qcom_spi_softc *sc); 145 extern int qcom_spi_hw_setup_block_transfer_cnt(struct qcom_spi_softc *sc); 146 extern int qcom_spi_hw_setup_io_modes(struct qcom_spi_softc *sc); 147 extern int qcom_spi_hw_setup_spi_io_clock_polarity( 148 struct qcom_spi_softc *sc, bool cpol); 149 extern int qcom_spi_hw_setup_spi_config(struct qcom_spi_softc *sc, 150 uint32_t clock_val, bool cpha); 151 extern int qcom_spi_hw_setup_qup_config(struct qcom_spi_softc *sc, 152 bool is_tx, bool is_rx); 153 extern int qcom_spi_hw_setup_operational_mask(struct qcom_spi_softc *sc); 154 extern int qcom_spi_hw_ack_write_pio_fifo(struct qcom_spi_softc *sc); 155 extern int qcom_spi_hw_ack_opmode(struct qcom_spi_softc *sc); 156 extern int qcom_spi_hw_write_pio_fifo(struct qcom_spi_softc *sc); 157 extern int qcom_spi_hw_write_pio_block(struct qcom_spi_softc *sc); 158 extern int qcom_spi_hw_read_pio_fifo(struct qcom_spi_softc *sc); 159 extern int qcom_spi_hw_read_pio_block(struct qcom_spi_softc *sc); 160 extern int qcom_spi_hw_do_full_reset(struct qcom_spi_softc *sc); 161 162 #endif /* __QCOM_SPI_VAR_H__ */ 163