1 /* 2 * Arm SCP/MCP Software 3 * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved. 4 * 5 * SPDX-License-Identifier: BSD-3-Clause 6 */ 7 8 #ifndef QSPI_API_H 9 #define QSPI_API_H 10 11 #include <fwk_id.h> 12 13 #include <stdbool.h> 14 #include <stdint.h> 15 16 /* 17 * \brief qspi command structure 18 */ 19 struct qspi_command { 20 uint8_t code; 21 struct len { 22 uint8_t code_byte; 23 uint8_t addr_byte; 24 uint8_t alt_byte; 25 uint8_t dummy_cycle; 26 uint8_t data_byte; 27 } len; 28 struct alt { 29 uint8_t data[4]; 30 bool is_nibble; 31 } alt; 32 struct io { 33 uint8_t code_bit; 34 uint8_t addr_bit; 35 uint8_t data_bit; 36 } io; 37 }; 38 39 /* 40 * \brief qspi command generator macro definitions 41 */ 42 #define QSPI_GEN_COMMAND( \ 43 CODE, \ 44 CODE_BYTE, \ 45 ADDR_BYTE, \ 46 ALT_BYTE, \ 47 DUMMY, \ 48 DATA_BYTE, \ 49 ALT_0, \ 50 ALT_1, \ 51 ALT_2, \ 52 ALT_3, \ 53 NIBBLE, \ 54 IO_CODE, \ 55 IO_ADDR, \ 56 IO_DATA) \ 57 { \ 58 .code = CODE, \ 59 .len = { \ 60 .code_byte = CODE_BYTE, \ 61 .addr_byte = ADDR_BYTE, \ 62 .alt_byte = ALT_BYTE, \ 63 .dummy_cycle = DUMMY, \ 64 .data_byte = DATA_BYTE, \ 65 }, \ 66 .alt = { \ 67 .data = { \ 68 ALT_0, \ 69 ALT_1, \ 70 ALT_2, \ 71 ALT_3 \ 72 }, \ 73 .is_nibble = NIBBLE, \ 74 }, \ 75 .io = { \ 76 .code_bit = IO_CODE, \ 77 .addr_bit = IO_ADDR, \ 78 .data_bit = IO_DATA, \ 79 }, \ 80 } 81 #define QSPI_COMMAND_EMPTY \ 82 ((struct qspi_command) \ 83 QSPI_GEN_COMMAND(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, false, 0, 0, 0)) 84 #define QSPI_COMMAND_TYPE_CODE(CODE) \ 85 ((struct qspi_command) \ 86 QSPI_GEN_COMMAND(CODE, 1, 0, 0, 0, 0, 0, 0, 0, 0, false, 1, 0, 1)) 87 #define QSPI_COMMAND_TYPE_CODE_DATA(CODE) \ 88 ((struct qspi_command) \ 89 QSPI_GEN_COMMAND(CODE, 1, 0, 0, 0, 1, 0, 0, 0, 0, false, 1, 0, 1)) 90 91 #define QSPI_COMMAND_TYPE_READ(CODE, ADDR, DUMMY, IO_CODE, IO_ADDR, IO_DATA) \ 92 ((struct qspi_command) QSPI_GEN_COMMAND( \ 93 CODE, \ 94 1, \ 95 ADDR, \ 96 0, \ 97 DUMMY, \ 98 1, \ 99 0, \ 100 0, \ 101 0, \ 102 0, \ 103 false, \ 104 IO_CODE, \ 105 IO_ADDR, \ 106 IO_DATA)) 107 #define QSPI_COMMAND_TYPE_WRITE(CODE, ADDR, IO_CODE, IO_ADDR, IO_DATA) \ 108 ((struct qspi_command) QSPI_GEN_COMMAND( \ 109 CODE, 1, ADDR, 0, 0, 1, 0, 0, 0, 0, false, IO_CODE, IO_ADDR, IO_DATA)) 110 #define QSPI_COMMAND_TYPE_WRITE_ADDR(CODE, ADDR, IO_CODE, IO_ADDR, IO_DATA) \ 111 ((struct qspi_command) QSPI_GEN_COMMAND( \ 112 CODE, 1, ADDR, 0, 0, 0, 0, 0, 0, 0, false, IO_CODE, IO_ADDR, IO_DATA)) 113 #define QSPI_COMMAND_TYPE_READ_WITH_ALT_00( \ 114 CODE, ADDR, ALT, DUMMY, IO_CODE, IO_ADDR, IO_DATA) \ 115 ((struct qspi_command) QSPI_GEN_COMMAND( \ 116 CODE, \ 117 1, \ 118 ADDR, \ 119 ALT, \ 120 DUMMY, \ 121 1, \ 122 0, \ 123 0, \ 124 0, \ 125 0, \ 126 false, \ 127 IO_CODE, \ 128 IO_ADDR, \ 129 IO_DATA)) 130 #define QSPI_COMMAND_TYPE_READ_WITH_ALT_FF( \ 131 CODE, ADDR, ALT, DUMMY, IO_CODE, IO_ADDR, IO_DATA) \ 132 ((struct qspi_command) QSPI_GEN_COMMAND( \ 133 CODE, \ 134 1, \ 135 ADDR, \ 136 ALT, \ 137 DUMMY, \ 138 1, \ 139 0xFF, \ 140 0xFF, \ 141 0xFF, \ 142 0xFF, \ 143 false, \ 144 IO_CODE, \ 145 IO_ADDR, \ 146 IO_DATA)) 147 148 #define IS_QSPI_COMMAND_EMPTY(cmd) \ 149 (cmd.code == 0 && cmd.len.code_byte == 0 && cmd.len.addr_byte == 0 && \ 150 cmd.len.alt_byte == 0 && cmd.len.dummy_cycle == 0 && \ 151 cmd.len.data_byte == 0) 152 153 /* 154 * \brief QSPI API indices 155 */ 156 enum qspi_api_type { 157 QSPI_API_TYPE_DEFAULT = 0, 158 QSPI_API_TYPE_COUNT, 159 }; 160 161 /*! 162 * \brief APIs to access the descriptors in the flash memory. 163 */ 164 struct qspi_api { 165 /*! 166 * \brief set read command to spi flash memory 167 * 168 * \param id The qspi device identifier. 169 * \param command Read command to send spi flash memofy. 170 * 171 * \retval ::FWK_SUCCESS The operation succeeded. 172 * \retval ::FWK_E_PARAM An invalid command was encountered. 173 * \retval ::FWK_E_STATE The qspi module isn't started yet. 174 * \return One of the other specific error codes. 175 */ 176 int (*set_read_command)(fwk_id_t id, struct qspi_command *command); 177 178 /*! 179 * \brief set write command to spi flash memory 180 * 181 * \param id The qspi device identifier. 182 * \param command Write command to send spi flash memofy. 183 * 184 * \retval ::FWK_SUCCESS The operation succeeded. 185 * \retval ::FWK_E_PARAM An invalid command was encountered. 186 * \retval ::FWK_E_STATE The qspi module isn't started yet. 187 * \return One of the other specific error codes. 188 */ 189 int (*set_write_command)(fwk_id_t id, struct qspi_command *command); 190 191 /*! 192 * \brief read data from spi flash memory 193 * 194 * \param id The qspi device identifier. 195 * \param offset Offset address of spi flash memory to read. 196 * \param buf The pointer address to store the data. 197 * \param len Number of data to read. 198 * 199 * \retval ::FWK_SUCCESS The operation succeeded. 200 * \retval ::FWK_E_PARAM An invalid parameter was encountered. 201 * \retval ::FWK_E_STATE The qspi module isn't started yet. 202 * \return One of the other specific error codes. 203 */ 204 int (*read)(fwk_id_t id, uint32_t offset, void *buf, uint32_t len); 205 206 /*! 207 * \brief write data to spi flash memory 208 * 209 * \param id The qspi device identifier. 210 * \param offset Offset address of spi flash memory to write. 211 * \param buf The pointer address to store the data. 212 * \param len Number of data to write. 213 * 214 * \retval ::FWK_SUCCESS The operation succeeded. 215 * \retval ::FWK_E_PARAM An invalid parameter was encountered. 216 * \retval ::FWK_E_STATE The qspi module isn't started yet. 217 * \return One of the other specific error codes. 218 */ 219 int (*write)(fwk_id_t id, uint32_t offset, void *buf, uint32_t len); 220 221 /*! 222 * \brief erase data on the spi flash memory 223 * 224 * \param id The qspi device identifier. 225 * \param offset Offset address of spi flash memory to write. 226 * 227 * \retval ::FWK_SUCCESS The operation succeeded. 228 * \retval ::FWK_E_STATE The qspi module isn't started yet. 229 * \return One of the other specific error codes. 230 */ 231 int (*erase)(fwk_id_t id, uint32_t offset); 232 233 /*! 234 * \brief reset the device and set hsspi controller to the command sequence 235 * mode 236 * 237 * \param id The qspi device identifier. 238 * 239 * \return never return. 240 */ 241 int (*init_csmode)(fwk_id_t id); 242 }; 243 244 /* 245 * \brief function pointer for command operation 246 */ 247 typedef int (*qspi_ope_func_t)(fwk_id_t, const struct qspi_api *, void *); 248 249 #endif /* QSPI_API_H */ 250