1 /* 2 * Copyright 2024 Microchip Technology Inc. and its subsidiaries. 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 #ifndef _MEC_QSPI_API_H 7 #define _MEC_QSPI_API_H 8 9 #include <stdbool.h> 10 #include <stddef.h> 11 #include <stdint.h> 12 13 #include "device_mec5.h" 14 #include "mec_defs.h" 15 #include "mec_retval.h" 16 17 /* Interfaces to any C modules */ 18 #ifdef __cplusplus 19 extern "C" 20 { 21 #endif 22 23 #define MEC_QSPI_NUM_INSTANCES 1 24 25 #define MEC_QSPI_SHD_PORT 0u 26 #define MEC_QSPI_PVT_PORT 1u 27 #define MEC_QSPI_INTERNAL_PORT 2u 28 #define MEC_QSPI_MAX_PORT 3u 29 30 /* SPI Flash Command structure */ 31 struct mec_spi_flash_cmd { 32 uint8_t opcode; 33 uint8_t npc; /* number of pins for opcode xmit */ 34 uint8_t npa; /* number of pins for command parameter xmit */ 35 uint8_t npd; /* number of pins for data r/w */ 36 uint8_t addr_nb; /* byte length of address */ 37 uint8_t mode_byte; /* optional mode byte */ 38 uint8_t mode_nbits; /* num bits in mode byte. 0 = no mode byte */ 39 uint8_t dummy_clocks; /* num dummy clocks to xmit after mode byte */ 40 }; 41 42 /* QMSPI API */ 43 44 enum mec_qspi_signal_mode { /* clock idle state, TX clock edge, RX clock edge */ 45 MEC_SPI_SIGNAL_MODE_0 = 0, /* low falling rising */ 46 MEC_SPI_SIGNAL_MODE_1, /* low rising falling */ 47 MEC_SPI_SIGNAL_MODE_2, /* high rising falling */ 48 MEC_SPI_SIGNAL_MODE_3, /* high falling rising */ 49 MEC_SPI_SIGNAL_MODE_MAX, 50 }; 51 52 enum mec_qspi_cs { 53 MEC_QSPI_CS_0 = 0, 54 MEC_QSPI_CS_1, 55 MEC_QSPI_CS_MAX, 56 }; 57 58 enum mec_qspi_io { 59 MEC_QSPI_IO_FULL_DUPLEX = 0, 60 MEC_QSPI_IO_DUAL, 61 MEC_QSPI_IO_QUAD, 62 MEC_QSPI_IO_MAX, 63 }; 64 65 enum mec_qspi_cstm { 66 MEC_QSPI_CSTM_CSA2CLK = 0, 67 MEC_QSPI_CSTM_CLK2CSD, 68 MEC_QSPI_CSTM_LD2H, 69 MEC_QSPI_CSTM_CSD2CSA, 70 MEC_QSPI_CSTM_MAX, 71 }; 72 73 enum mec_qspi_status { 74 MEC_QSPI_STS_XFR_DONE = MEC_BIT(0), 75 MEC_QSPI_STS_DMA_DONE = MEC_BIT(1), 76 MEC_QSPI_STS_TXB_ERR = MEC_BIT(2), /* overflow TX FIFO or DMA buffer */ 77 MEC_QSPI_STS_RXB_ERR = MEC_BIT(3), /* underflow RX FIFO or DMA buffer */ 78 MEC_QSPI_STS_PROG_ERR = MEC_BIT(4), /* software misconfigured transfer */ 79 MEC_QSPI_STS_LDMA_RX_ERR = MEC_BIT(5), /* Local-DMA error on receive */ 80 MEC_QSPI_STS_LDMA_TX_ERR = MEC_BIT(6), /* Local-DMA error on transmit */ 81 MEC_QSPI_STS_TXB_FULL = MEC_BIT(8), /* TX FIFO full */ 82 MEC_QSPI_STS_TXB_EMPTY = MEC_BIT(9), /* TX FIFO empty */ 83 MEC_QSPI_STS_TXB_REQ = MEC_BIT(10), /* TX FIFO reached high water mark */ 84 MEC_QSPI_STS_TXB_STALL = MEC_BIT(11), /* TX FIFO empty when engine requests more data */ 85 MEC_QSPI_STS_RXB_FULL = MEC_BIT(12), /* RX FIFO full */ 86 MEC_QSPI_STS_RXB_EMPTY = MEC_BIT(13), /* RX FIFO empty */ 87 MEC_QSPI_STS_RXB_REQ = MEC_BIT(14), /* RX FIFO reached high water mark */ 88 MEC_QSPI_STS_RXB_STALL = MEC_BIT(15), /* No clocks generated due to full RX FIFO */ 89 MEC_QSPI_STS_ACTIVE = MEC_BIT(16), /* QSPI is asserting its chip select */ 90 }; 91 92 enum mec_qspi_intr_enables { 93 MEC_QSPI_IEN_XFR_DONE = MEC_BIT(0), 94 MEC_QSPI_IEN_DMA_DONE = MEC_BIT(1), 95 MEC_QSPI_IEN_TXB_ERR = MEC_BIT(2), 96 MEC_QSPI_IEN_RXB_ERR = MEC_BIT(3), 97 MEC_QSPI_IEN_PROG_ERR = MEC_BIT(4), 98 MEC_QSPI_IEN_LDMA_RX_ERR = MEC_BIT(5), 99 MEC_QSPI_IEN_LDMA_TX_ERR = MEC_BIT(6), 100 MEC_QSPI_IEN_TXB_FULL = MEC_BIT(8), 101 MEC_QSPI_IEN_TXB_EMPTY = MEC_BIT(9), 102 MEC_QSPI_IEN_TXB_REQ = MEC_BIT(10), 103 MEC_QSPI_IEN_RXB_FULL = MEC_BIT(12), 104 MEC_QSPI_IEN_RXB_EMPTY = MEC_BIT(13), 105 MEC_QSPI_IEN_RXB_REQ = MEC_BIT(14), 106 }; 107 108 enum mec_qspi_options { 109 MEC_QSPI_OPT_ACTV_EN_POS = 0, 110 MEC_QSPI_OPT_TAF_DMA_EN_POS, 111 MEC_QSPI_OPT_RX_LDMA_EN_POS, 112 MEC_QSPI_OPT_TX_LDMA_EN_POS, 113 }; 114 115 #define MEC_QSPI_STATE_CLOSED 0 116 #define MEC_QSPI_STATE_OPEN_TX 1 117 #define MEC_QSPI_STATE_OPEN_RX 2 118 #define MEC_QSPI_STATE_MAX 3 119 120 #define MEC_QSPI_FLAG_TX_OPCODE MEC_BIT(0) 121 #define MEC_QSPI_FLAG_TX_ADDR MEC_BIT(1) 122 #define MEC_QSPI_FLAG_TX_DUMCLK MEC_BIT(2) 123 #define MEC_QSPI_FLAG_TX_MODEB MEC_BIT(3) 124 125 #define MEC_QSPI_CTX_DIR_RD 0U 126 #define MEC_QSPI_CTX_DIR_WR 1U 127 128 #define MEC_QSPI_BUF_FLAG_IFM_POS 0 129 #define MEC_QSPI_BUF_FLAG_IFM_MSK 0x3u 130 #define MEC_QSPI_BUF_FLAG_IFM_FD 0u /* full-duplex */ 131 #define MEC_QSPI_BUF_FLAG_IFM_DUAL 1u /* half-duplex, dual I/O */ 132 #define MEC_QSPI_BUF_FLAG_IFM_QUAD 2u /* half-duplex, quad I/O */ 133 #define MEC_QSPI_BUF_FLAG_DIR_TX_POS 4 134 135 struct mec_qspi_buf { 136 void *buf; 137 uint32_t len; 138 uint8_t flags; 139 }; 140 141 struct mec_qspi_timing { 142 uint32_t freqhz; 143 uint8_t dly_csa_to_clk; 144 uint8_t dly_clk_to_csd; 145 uint8_t dly_csd_to_wph; 146 uint8_t dly_start_to_csa; 147 uint32_t taps; 148 }; 149 150 /* forward reference */ 151 struct mec_qspi_regs; 152 153 /* Return QSPI controller SPI clock source in Hz */ 154 uint32_t mec_hal_qspi_max_spi_clock(void); 155 156 bool mec_hal_qspi_is_enabled(struct mec_qspi_regs *regs); 157 158 /* Return current QSPI frequency in Hz */ 159 uint32_t mec_hal_qspi_get_freq(struct mec_qspi_regs *base); 160 uint32_t mec_hal_qspi_freq_div(struct mec_qspi_regs *base); 161 uint16_t mec_hal_qspi_freq_div_raw(struct mec_qspi_regs *base); 162 int mec_hal_qspi_set_freq(struct mec_qspi_regs *base, uint32_t freqhz); 163 int mec_hal_qspi_byte_time_ns(struct mec_qspi_regs *base, uint32_t *btime_ns); 164 165 /* Reset QSPI block and clear interrupt status. */ 166 int mec_hal_qspi_reset(struct mec_qspi_regs *base); 167 168 /* Reset QSPI block with save/restore of frequency, signalling mode, 169 * CS timing, and taps select. 170 */ 171 int mec_hal_qspi_reset_sr(struct mec_qspi_regs *base); 172 173 void mec_hal_qspi_girq_clr(struct mec_qspi_regs *base); 174 void mec_hal_qspi_girq_ctrl(struct mec_qspi_regs *base, uint8_t enable); 175 uint32_t mec_hal_qspi_girq_is_result(struct mec_qspi_regs *base); 176 177 /* 1 = enable clock input to QMSPI block 178 * 0 = disable clock input to QMSPI block 179 */ 180 int mec_hal_qspi_clk_gate(struct mec_qspi_regs *base, uint8_t gate_clocks_on); 181 182 int mec_hal_qspi_init(struct mec_qspi_regs *base, 183 uint32_t freq_hz, 184 enum mec_qspi_signal_mode spi_mode, 185 enum mec_qspi_io iom, 186 enum mec_qspi_cs cs); 187 188 int mec_hal_qspi_options(struct mec_qspi_regs *regs, uint8_t en, uint32_t options); 189 190 int mec_hal_qspi_cs_select(struct mec_qspi_regs *base, enum mec_qspi_cs cs); 191 192 int mec_hal_qspi_spi_signal_mode(struct mec_qspi_regs *base, enum mec_qspi_signal_mode spi_mode); 193 int mec_hal_qspi_sampling_phase_pol(struct mec_qspi_regs *base, uint8_t phpol); 194 195 int mec_hal_qspi_io(struct mec_qspi_regs *base, enum mec_qspi_io io); 196 197 int mec_hal_qspi_cs_timing_adjust(struct mec_qspi_regs *base, 198 enum mec_qspi_cstm field, uint8_t val); 199 200 int mec_hal_qspi_cs_timing(struct mec_qspi_regs *base, uint32_t cs_timing); 201 202 int mec_hal_qspi_tap_select(struct mec_qspi_regs *base, uint8_t sel_sck_tap, uint8_t sel_ctrl_tap); 203 204 int mec_hal_qspi_cs1_freq(struct mec_qspi_regs *base, uint32_t freq); 205 206 int mec_hal_qspi_force_stop(struct mec_qspi_regs *base); 207 208 int mec_hal_qspi_done(struct mec_qspi_regs *base); 209 210 uint32_t mec_hal_qspi_hw_status(struct mec_qspi_regs *base); 211 int mec_hal_qspi_hw_status_clr(struct mec_qspi_regs *base, uint32_t msk); 212 int mec_hal_qspi_intr_ctrl(struct mec_qspi_regs *base, int enable); 213 int mec_hal_qspi_intr_ctrl_msk(struct mec_qspi_regs *base, int enable, uint32_t msk); 214 215 int mec_hal_qspi_tx_fifo_is_empty(struct mec_qspi_regs *base); 216 int mec_hal_qspi_tx_fifo_is_full(struct mec_qspi_regs *base); 217 int mec_hal_qspi_rx_fifo_is_empty(struct mec_qspi_regs *base); 218 int mec_hal_qspi_rx_fifo_is_full(struct mec_qspi_regs *base); 219 220 /* Start previously configured QSPI transaction. 221 * ien_mask == 0 disabled interrupts. 222 * ien_mask != 0 should use one or more values from enum mec_qspi_intr_enables 223 */ 224 int mec_hal_qspi_start(struct mec_qspi_regs *base, uint32_t ien_mask); 225 226 /* Store data bytes into QSPI TX FIFO until full or bufsz reached. 227 * Store number of bytes written into nwr if not NULL. 228 */ 229 int mec_hal_qspi_wr_tx_fifo(struct mec_qspi_regs *regs, const uint8_t *buf, uint32_t bufsz, 230 uint32_t *nwr); 231 232 int mec_hal_qspi_rd_rx_fifo(struct mec_qspi_regs *regs, uint8_t *buf, uint32_t bufsz, 233 uint32_t *nrd); 234 235 #define MEC5_QSPI_BUILD_DESCR_TX_DATA MEC_BIT(0) 236 #define MEC5_QSPI_BUILD_DESCR_TX_ZEROS MEC_BIT(1) 237 #define MEC5_QSPI_BUILD_DESCR_TX_ONES MEC_BIT(2) 238 #define MEC5_QSPI_BUILD_DESCR_RX_DATA MEC_BIT(3) 239 240 /* Build a 32-bit QSPI descriptor based on inputs. 241 * ifm is type enum mec_qspi_io specifying the data bus: full-duplex, dual, or quad 242 * nunits is the number of units (bytes or bits) to transfer. 243 * flags contains bits indicating units are bytes or bits, enable transmit, enable 244 * receive, etc. 245 * remunits pointer to uint32_t containing the number of remaining units if the 246 * descriptor number of units was exceeded. 247 */ 248 uint32_t mec_hal_qspi_build_descr(enum mec_qspi_io ifm, uint32_t nunits, uint32_t *remunits, 249 uint32_t flags); 250 251 #define MEC_QSPI_XFR_FLAG_CLR_FIFOS_POS 0 252 #define MEC_QSPI_XFR_FLAG_IEN_POS 1 253 #define MEC_QSPI_XFR_FLAG_CLOSE_POS 2 254 #define MEC_QSPI_XFR_FLAG_START_POS 3 255 256 int mec_hal_qspi_ldma(struct mec_qspi_regs *base, const uint8_t *txb, 257 uint8_t* rxb, size_t lenb, uint32_t flags); 258 259 260 /* -------- new API's -------- */ 261 struct mec_qspi_context { 262 uint8_t ndescrs; 263 uint8_t ntxdma; 264 uint8_t nrxdma; 265 uint8_t xflags; 266 uint32_t descrs[MEC5_QSPI_NUM_DESCRS]; 267 }; 268 269 void mec_hal_qspi_context_init(struct mec_qspi_context *ctx); 270 271 uint8_t mec_hal_qspi_ctx_alloc_ldma_chan(struct mec_qspi_context *ctx, uint8_t is_tx); 272 273 #define MEC5_QSPI_DCFG1_FLAG_IFM_POS 0 274 #define MEC5_QSPI_DCFG1_FLAG_IFM_MSK 0x3u 275 #define MEC5_QSPI_DCFG1_FLAG_IFM_FD 0u 276 #define MEC5_QSPI_DCFG1_FLAG_IFM_DUAL 0x1 277 #define MEC5_QSPI_DCFG1_FLAG_IFM_QUAD 0x2u 278 #define MEC5_QSPI_DCFG1_FLAG_DIR_TX MEC_BIT(2) 279 #define MEC5_QSPI_DCFG1_FLAG_DIR_RX MEC_BIT(3) 280 #define MEC5_QSPI_DCFG1_FLAG_DMA_TX_POS 4 281 #define MEC5_QSPI_DCFG1_FLAG_DMA_TX_MSK 0x30u 282 #define MEC5_QSPI_DCFG1_FLAG_DMA_RX_POS 8 283 #define MEC5_QSPI_DCFG1_FLAG_DMA_RX_MSK 0x300u 284 #define MEC5_QSPI_DCFG1_FLAG_DMA_MSK0 0x3u 285 286 #define MEC5_QSPI_DCFG1_FLAG_IFM(ifm) \ 287 (((uint32_t)(ifm) & MEC5_QSPI_DCFG1_FLAG_IFM_MSK) << MEC5_QSPI_DCFG1_FLAG_IFM_POS) 288 289 /* chan = 0 (disabled), 1-3 is Local-DMA channel */ 290 #define MEC5_QSPI_DCFG1_FLAG_DMA_TX(chan) \ 291 (((uint32_t)(chan) & MEC5_QSPI_DCFG1_FLAG_DMA_MSK0) << MEC5_QSPI_DCFG1_FLAG_DMA_TX_POS) 292 293 #define MEC5_QSPI_DCFG1_FLAG_DMA_RX(chan) \ 294 (((uint32_t)(chan) & MEC5_QSPI_DCFG1_FLAG_DMA_MSK0) << MEC5_QSPI_DCFG1_FLAG_DMA_RX_POS) 295 296 uint32_t mec_hal_qspi_descrs_cfg1(struct mec_qspi_context *ctx, uint32_t nbytes, uint32_t flags); 297 298 /* Use same flags as mec_qspi_descrs_cfg1 except only set one of DIR_TX or DIR_RX 299 * and the corresponding DMA channel field 300 */ 301 int mec_hal_qspi_ldma_cfg1(struct mec_qspi_regs *regs, uintptr_t buf_addr, 302 uint32_t nbytes, uint32_t ldflags); 303 304 /* Configure next free descriptor to generate clocks with all I/O pins tri-stated. 305 * nclocks < 1000 306 * nio_pins = [1, 2, 4] 307 */ 308 int mec_hal_qspi_cfg_gen_ts_clocks(struct mec_qspi_context *ctx, uint32_t nclocks, 309 uint8_t nio_pins); 310 311 /* Load descriptors from context structure into QSPI descriptor registers 312 * NOTE: loads all descriptors. 313 */ 314 #define MEC5_QSPI_LD_FLAGS_LAST_POS 0 315 #define MEC5_QSPI_LD_FLAGS_CLOSE_ON_LAST_POS 1 316 317 int mec_hal_qspi_load_descrs(struct mec_qspi_regs *regs, struct mec_qspi_context *ctx, 318 uint32_t flags); 319 320 int mec_hal_qspi_load_descrs_at(struct mec_qspi_regs *regs, const uint32_t *descrs, uint8_t ndescr, 321 uint8_t start_descr_idx); 322 323 #ifdef __cplusplus 324 } 325 #endif 326 327 #endif /* #ifndef _MEC_QSPI_API_H */ 328