1 /* SPDX-License-Identifier: GPL-2.0+ */ 2 /* 3 * Copyright (C) 2018 Exceet Electronics GmbH 4 * Copyright (C) 2018 Bootlin 5 * 6 * Author: 7 * Peter Pan <peterpandong@micron.com> 8 * Boris Brezillon <boris.brezillon@bootlin.com> 9 */ 10 11 #ifndef __UBOOT_SPI_MEM_H 12 #define __UBOOT_SPI_MEM_H 13 14 #include <common.h> 15 #include <dm.h> 16 #include <errno.h> 17 #include <spi.h> 18 19 #define SPI_MEM_OP_CMD(__opcode, __buswidth) \ 20 { \ 21 .buswidth = __buswidth, \ 22 .opcode = __opcode, \ 23 } 24 25 #define SPI_MEM_OP_ADDR(__nbytes, __val, __buswidth) \ 26 { \ 27 .nbytes = __nbytes, \ 28 .val = __val, \ 29 .buswidth = __buswidth, \ 30 } 31 32 #define SPI_MEM_OP_NO_ADDR { } 33 34 #define SPI_MEM_OP_DUMMY(__nbytes, __buswidth) \ 35 { \ 36 .nbytes = __nbytes, \ 37 .buswidth = __buswidth, \ 38 } 39 40 #define SPI_MEM_OP_NO_DUMMY { } 41 42 #define SPI_MEM_OP_DATA_IN(__nbytes, __buf, __buswidth) \ 43 { \ 44 .dir = SPI_MEM_DATA_IN, \ 45 .nbytes = __nbytes, \ 46 .buf.in = __buf, \ 47 .buswidth = __buswidth, \ 48 } 49 50 #define SPI_MEM_OP_DATA_OUT(__nbytes, __buf, __buswidth) \ 51 { \ 52 .dir = SPI_MEM_DATA_OUT, \ 53 .nbytes = __nbytes, \ 54 .buf.out = __buf, \ 55 .buswidth = __buswidth, \ 56 } 57 58 #define SPI_MEM_OP_NO_DATA { } 59 60 /** 61 * enum spi_mem_data_dir - describes the direction of a SPI memory data 62 * transfer from the controller perspective 63 * @SPI_MEM_DATA_IN: data coming from the SPI memory 64 * @SPI_MEM_DATA_OUT: data sent the SPI memory 65 */ 66 enum spi_mem_data_dir { 67 SPI_MEM_DATA_IN, 68 SPI_MEM_DATA_OUT, 69 }; 70 71 /** 72 * struct spi_mem_op - describes a SPI memory operation 73 * @cmd.buswidth: number of IO lines used to transmit the command 74 * @cmd.opcode: operation opcode 75 * @addr.nbytes: number of address bytes to send. Can be zero if the operation 76 * does not need to send an address 77 * @addr.buswidth: number of IO lines used to transmit the address cycles 78 * @addr.val: address value. This value is always sent MSB first on the bus. 79 * Note that only @addr.nbytes are taken into account in this 80 * address value, so users should make sure the value fits in the 81 * assigned number of bytes. 82 * @dummy.nbytes: number of dummy bytes to send after an opcode or address. Can 83 * be zero if the operation does not require dummy bytes 84 * @dummy.buswidth: number of IO lanes used to transmit the dummy bytes 85 * @data.buswidth: number of IO lanes used to send/receive the data 86 * @data.dir: direction of the transfer 87 * @data.buf.in: input buffer 88 * @data.buf.out: output buffer 89 */ 90 struct spi_mem_op { 91 struct { 92 u8 buswidth; 93 u8 opcode; 94 } cmd; 95 96 struct { 97 u8 nbytes; 98 u8 buswidth; 99 u64 val; 100 } addr; 101 102 struct { 103 u8 nbytes; 104 u8 buswidth; 105 } dummy; 106 107 struct { 108 u8 buswidth; 109 enum spi_mem_data_dir dir; 110 unsigned int nbytes; 111 /* buf.{in,out} must be DMA-able. */ 112 union { 113 void *in; 114 const void *out; 115 } buf; 116 } data; 117 }; 118 119 #define SPI_MEM_OP(__cmd, __addr, __dummy, __data) \ 120 { \ 121 .cmd = __cmd, \ 122 .addr = __addr, \ 123 .dummy = __dummy, \ 124 .data = __data, \ 125 } 126 127 #ifndef __UBOOT__ 128 /** 129 * struct spi_mem - describes a SPI memory device 130 * @spi: the underlying SPI device 131 * @drvpriv: spi_mem_driver private data 132 * 133 * Extra information that describe the SPI memory device and may be needed by 134 * the controller to properly handle this device should be placed here. 135 * 136 * One example would be the device size since some controller expose their SPI 137 * mem devices through a io-mapped region. 138 */ 139 struct spi_mem { 140 struct udevice *dev; 141 void *drvpriv; 142 }; 143 144 /** 145 * struct spi_mem_set_drvdata() - attach driver private data to a SPI mem 146 * device 147 * @mem: memory device 148 * @data: data to attach to the memory device 149 */ 150 static inline void spi_mem_set_drvdata(struct spi_mem *mem, void *data) 151 { 152 mem->drvpriv = data; 153 } 154 155 /** 156 * struct spi_mem_get_drvdata() - get driver private data attached to a SPI mem 157 * device 158 * @mem: memory device 159 * 160 * Return: the data attached to the mem device. 161 */ 162 static inline void *spi_mem_get_drvdata(struct spi_mem *mem) 163 { 164 return mem->drvpriv; 165 } 166 #endif /* __UBOOT__ */ 167 168 /** 169 * struct spi_controller_mem_ops - SPI memory operations 170 * @adjust_op_size: shrink the data xfer of an operation to match controller's 171 * limitations (can be alignment of max RX/TX size 172 * limitations) 173 * @supports_op: check if an operation is supported by the controller 174 * @exec_op: execute a SPI memory operation 175 * 176 * This interface should be implemented by SPI controllers providing an 177 * high-level interface to execute SPI memory operation, which is usually the 178 * case for QSPI controllers. 179 */ 180 struct spi_controller_mem_ops { 181 int (*adjust_op_size)(struct spi_slave *slave, struct spi_mem_op *op); 182 bool (*supports_op)(struct spi_slave *slave, 183 const struct spi_mem_op *op); 184 int (*exec_op)(struct spi_slave *slave, 185 const struct spi_mem_op *op); 186 }; 187 188 #ifndef __UBOOT__ 189 /** 190 * struct spi_mem_driver - SPI memory driver 191 * @spidrv: inherit from a SPI driver 192 * @probe: probe a SPI memory. Usually where detection/initialization takes 193 * place 194 * @remove: remove a SPI memory 195 * @shutdown: take appropriate action when the system is shutdown 196 * 197 * This is just a thin wrapper around a spi_driver. The core takes care of 198 * allocating the spi_mem object and forwarding the probe/remove/shutdown 199 * request to the spi_mem_driver. The reason we use this wrapper is because 200 * we might have to stuff more information into the spi_mem struct to let 201 * SPI controllers know more about the SPI memory they interact with, and 202 * having this intermediate layer allows us to do that without adding more 203 * useless fields to the spi_device object. 204 */ 205 struct spi_mem_driver { 206 struct spi_driver spidrv; 207 int (*probe)(struct spi_mem *mem); 208 int (*remove)(struct spi_mem *mem); 209 void (*shutdown)(struct spi_mem *mem); 210 }; 211 212 #if IS_ENABLED(CONFIG_SPI_MEM) 213 int spi_controller_dma_map_mem_op_data(struct spi_controller *ctlr, 214 const struct spi_mem_op *op, 215 struct sg_table *sg); 216 217 void spi_controller_dma_unmap_mem_op_data(struct spi_controller *ctlr, 218 const struct spi_mem_op *op, 219 struct sg_table *sg); 220 #else 221 static inline int 222 spi_controller_dma_map_mem_op_data(struct spi_controller *ctlr, 223 const struct spi_mem_op *op, 224 struct sg_table *sg) 225 { 226 return -ENOTSUPP; 227 } 228 229 static inline void 230 spi_controller_dma_unmap_mem_op_data(struct spi_controller *ctlr, 231 const struct spi_mem_op *op, 232 struct sg_table *sg) 233 { 234 } 235 #endif /* CONFIG_SPI_MEM */ 236 #endif /* __UBOOT__ */ 237 238 int spi_mem_adjust_op_size(struct spi_slave *slave, struct spi_mem_op *op); 239 240 bool spi_mem_supports_op(struct spi_slave *slave, const struct spi_mem_op *op); 241 242 int spi_mem_exec_op(struct spi_slave *slave, const struct spi_mem_op *op); 243 244 #ifndef __UBOOT__ 245 int spi_mem_driver_register_with_owner(struct spi_mem_driver *drv, 246 struct module *owner); 247 248 void spi_mem_driver_unregister(struct spi_mem_driver *drv); 249 250 #define spi_mem_driver_register(__drv) \ 251 spi_mem_driver_register_with_owner(__drv, THIS_MODULE) 252 253 #define module_spi_mem_driver(__drv) \ 254 module_driver(__drv, spi_mem_driver_register, \ 255 spi_mem_driver_unregister) 256 #endif 257 258 #endif /* __LINUX_SPI_MEM_H */ 259