1 /* 2 * Block model of SPI controller present in 3 * Microsemi's SmartFusion2 and SmartFusion SoCs. 4 * 5 * Copyright (C) 2017 Subbaraya Sundeep <sundeep.lkml@gmail.com> 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a copy 8 * of this software and associated documentation files (the "Software"), to deal 9 * in the Software without restriction, including without limitation the rights 10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 * copies of the Software, and to permit persons to whom the Software is 12 * furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included in 15 * all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 * THE SOFTWARE. 24 */ 25 26 #include "qemu/osdep.h" 27 #include "hw/ssi/mss-spi.h" 28 #include "qemu/log.h" 29 30 #ifndef MSS_SPI_ERR_DEBUG 31 #define MSS_SPI_ERR_DEBUG 0 32 #endif 33 34 #define DB_PRINT_L(lvl, fmt, args...) do { \ 35 if (MSS_SPI_ERR_DEBUG >= lvl) { \ 36 qemu_log("%s: " fmt "\n", __func__, ## args); \ 37 } \ 38 } while (0) 39 40 #define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args) 41 42 #define FIFO_CAPACITY 32 43 44 #define R_SPI_CONTROL 0 45 #define R_SPI_DFSIZE 1 46 #define R_SPI_STATUS 2 47 #define R_SPI_INTCLR 3 48 #define R_SPI_RX 4 49 #define R_SPI_TX 5 50 #define R_SPI_CLKGEN 6 51 #define R_SPI_SS 7 52 #define R_SPI_MIS 8 53 #define R_SPI_RIS 9 54 55 #define S_TXDONE (1 << 0) 56 #define S_RXRDY (1 << 1) 57 #define S_RXCHOVRF (1 << 2) 58 #define S_RXFIFOFUL (1 << 4) 59 #define S_RXFIFOFULNXT (1 << 5) 60 #define S_RXFIFOEMP (1 << 6) 61 #define S_RXFIFOEMPNXT (1 << 7) 62 #define S_TXFIFOFUL (1 << 8) 63 #define S_TXFIFOFULNXT (1 << 9) 64 #define S_TXFIFOEMP (1 << 10) 65 #define S_TXFIFOEMPNXT (1 << 11) 66 #define S_FRAMESTART (1 << 12) 67 #define S_SSEL (1 << 13) 68 #define S_ACTIVE (1 << 14) 69 70 #define C_ENABLE (1 << 0) 71 #define C_MODE (1 << 1) 72 #define C_INTRXDATA (1 << 4) 73 #define C_INTTXDATA (1 << 5) 74 #define C_INTRXOVRFLO (1 << 6) 75 #define C_SPS (1 << 26) 76 #define C_BIGFIFO (1 << 29) 77 #define C_RESET (1 << 31) 78 79 #define FRAMESZ_MASK 0x3F 80 #define FMCOUNT_MASK 0x00FFFF00 81 #define FMCOUNT_SHIFT 8 82 #define FRAMESZ_MAX 32 83 84 static void txfifo_reset(MSSSpiState *s) 85 { 86 fifo32_reset(&s->tx_fifo); 87 88 s->regs[R_SPI_STATUS] &= ~S_TXFIFOFUL; 89 s->regs[R_SPI_STATUS] |= S_TXFIFOEMP; 90 } 91 92 static void rxfifo_reset(MSSSpiState *s) 93 { 94 fifo32_reset(&s->rx_fifo); 95 96 s->regs[R_SPI_STATUS] &= ~S_RXFIFOFUL; 97 s->regs[R_SPI_STATUS] |= S_RXFIFOEMP; 98 } 99 100 static void set_fifodepth(MSSSpiState *s) 101 { 102 unsigned int size = s->regs[R_SPI_DFSIZE] & FRAMESZ_MASK; 103 104 if (size <= 8) { 105 s->fifo_depth = 32; 106 } else if (size <= 16) { 107 s->fifo_depth = 16; 108 } else { 109 s->fifo_depth = 8; 110 } 111 } 112 113 static void update_mis(MSSSpiState *s) 114 { 115 uint32_t reg = s->regs[R_SPI_CONTROL]; 116 uint32_t tmp; 117 118 /* 119 * form the Control register interrupt enable bits 120 * same as RIS, MIS and Interrupt clear registers for simplicity 121 */ 122 tmp = ((reg & C_INTRXOVRFLO) >> 4) | ((reg & C_INTRXDATA) >> 3) | 123 ((reg & C_INTTXDATA) >> 5); 124 s->regs[R_SPI_MIS] |= tmp & s->regs[R_SPI_RIS]; 125 } 126 127 static void spi_update_irq(MSSSpiState *s) 128 { 129 int irq; 130 131 update_mis(s); 132 irq = !!(s->regs[R_SPI_MIS]); 133 134 qemu_set_irq(s->irq, irq); 135 } 136 137 static void mss_spi_reset(DeviceState *d) 138 { 139 MSSSpiState *s = MSS_SPI(d); 140 141 memset(s->regs, 0, sizeof s->regs); 142 s->regs[R_SPI_CONTROL] = 0x80000102; 143 s->regs[R_SPI_DFSIZE] = 0x4; 144 s->regs[R_SPI_STATUS] = S_SSEL | S_TXFIFOEMP | S_RXFIFOEMP; 145 s->regs[R_SPI_CLKGEN] = 0x7; 146 s->regs[R_SPI_RIS] = 0x0; 147 148 s->fifo_depth = 4; 149 s->frame_count = 1; 150 s->enabled = false; 151 152 rxfifo_reset(s); 153 txfifo_reset(s); 154 } 155 156 static uint64_t 157 spi_read(void *opaque, hwaddr addr, unsigned int size) 158 { 159 MSSSpiState *s = opaque; 160 uint32_t ret = 0; 161 162 addr >>= 2; 163 switch (addr) { 164 case R_SPI_RX: 165 s->regs[R_SPI_STATUS] &= ~S_RXFIFOFUL; 166 s->regs[R_SPI_STATUS] &= ~S_RXCHOVRF; 167 ret = fifo32_pop(&s->rx_fifo); 168 if (fifo32_is_empty(&s->rx_fifo)) { 169 s->regs[R_SPI_STATUS] |= S_RXFIFOEMP; 170 } 171 break; 172 173 case R_SPI_MIS: 174 update_mis(s); 175 ret = s->regs[R_SPI_MIS]; 176 break; 177 178 default: 179 if (addr < ARRAY_SIZE(s->regs)) { 180 ret = s->regs[addr]; 181 } else { 182 qemu_log_mask(LOG_GUEST_ERROR, 183 "%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, 184 addr * 4); 185 return ret; 186 } 187 break; 188 } 189 190 DB_PRINT("addr=0x%" HWADDR_PRIx " = 0x%" PRIx32, addr * 4, ret); 191 spi_update_irq(s); 192 return ret; 193 } 194 195 static void assert_cs(MSSSpiState *s) 196 { 197 qemu_set_irq(s->cs_line, 0); 198 } 199 200 static void deassert_cs(MSSSpiState *s) 201 { 202 qemu_set_irq(s->cs_line, 1); 203 } 204 205 static void spi_flush_txfifo(MSSSpiState *s) 206 { 207 uint32_t tx; 208 uint32_t rx; 209 bool sps = !!(s->regs[R_SPI_CONTROL] & C_SPS); 210 211 /* 212 * Chip Select(CS) is automatically controlled by this controller. 213 * If SPS bit is set in Control register then CS is asserted 214 * until all the frames set in frame count of Control register are 215 * transferred. If SPS is not set then CS pulses between frames. 216 * Note that Slave Select register specifies which of the CS line 217 * has to be controlled automatically by controller. Bits SS[7:1] are for 218 * masters in FPGA fabric since we model only Microcontroller subsystem 219 * of Smartfusion2 we control only one CS(SS[0]) line. 220 */ 221 while (!fifo32_is_empty(&s->tx_fifo) && s->frame_count) { 222 assert_cs(s); 223 224 s->regs[R_SPI_STATUS] &= ~(S_TXDONE | S_RXRDY); 225 226 tx = fifo32_pop(&s->tx_fifo); 227 DB_PRINT("data tx:0x%" PRIx32, tx); 228 rx = ssi_transfer(s->spi, tx); 229 DB_PRINT("data rx:0x%" PRIx32, rx); 230 231 if (fifo32_num_used(&s->rx_fifo) == s->fifo_depth) { 232 s->regs[R_SPI_STATUS] |= S_RXCHOVRF; 233 s->regs[R_SPI_RIS] |= S_RXCHOVRF; 234 } else { 235 fifo32_push(&s->rx_fifo, rx); 236 s->regs[R_SPI_STATUS] &= ~S_RXFIFOEMP; 237 if (fifo32_num_used(&s->rx_fifo) == (s->fifo_depth - 1)) { 238 s->regs[R_SPI_STATUS] |= S_RXFIFOFULNXT; 239 } else if (fifo32_num_used(&s->rx_fifo) == s->fifo_depth) { 240 s->regs[R_SPI_STATUS] |= S_RXFIFOFUL; 241 } 242 } 243 s->frame_count--; 244 if (!sps) { 245 deassert_cs(s); 246 } 247 } 248 249 if (!s->frame_count) { 250 s->frame_count = (s->regs[R_SPI_CONTROL] & FMCOUNT_MASK) >> 251 FMCOUNT_SHIFT; 252 deassert_cs(s); 253 s->regs[R_SPI_RIS] |= S_TXDONE | S_RXRDY; 254 s->regs[R_SPI_STATUS] |= S_TXDONE | S_RXRDY; 255 } 256 } 257 258 static void spi_write(void *opaque, hwaddr addr, 259 uint64_t val64, unsigned int size) 260 { 261 MSSSpiState *s = opaque; 262 uint32_t value = val64; 263 264 DB_PRINT("addr=0x%" HWADDR_PRIx " =0x%" PRIx32, addr, value); 265 addr >>= 2; 266 267 switch (addr) { 268 case R_SPI_TX: 269 /* adding to already full FIFO */ 270 if (fifo32_num_used(&s->tx_fifo) == s->fifo_depth) { 271 break; 272 } 273 s->regs[R_SPI_STATUS] &= ~S_TXFIFOEMP; 274 fifo32_push(&s->tx_fifo, value); 275 if (fifo32_num_used(&s->tx_fifo) == (s->fifo_depth - 1)) { 276 s->regs[R_SPI_STATUS] |= S_TXFIFOFULNXT; 277 } else if (fifo32_num_used(&s->tx_fifo) == s->fifo_depth) { 278 s->regs[R_SPI_STATUS] |= S_TXFIFOFUL; 279 } 280 if (s->enabled) { 281 spi_flush_txfifo(s); 282 } 283 break; 284 285 case R_SPI_CONTROL: 286 s->regs[R_SPI_CONTROL] = value; 287 if (value & C_BIGFIFO) { 288 set_fifodepth(s); 289 } else { 290 s->fifo_depth = 4; 291 } 292 s->enabled = value & C_ENABLE; 293 s->frame_count = (value & FMCOUNT_MASK) >> FMCOUNT_SHIFT; 294 if (value & C_RESET) { 295 mss_spi_reset(DEVICE(s)); 296 } 297 break; 298 299 case R_SPI_DFSIZE: 300 if (s->enabled) { 301 break; 302 } 303 /* 304 * [31:6] bits are reserved bits and for future use. 305 * [5:0] are for frame size. Only [5:0] bits are validated 306 * during write, [31:6] bits are untouched. 307 */ 308 if ((value & FRAMESZ_MASK) > FRAMESZ_MAX) { 309 qemu_log_mask(LOG_GUEST_ERROR, "%s: Incorrect size %u provided." 310 "Maximum frame size is %u\n", 311 __func__, value & FRAMESZ_MASK, FRAMESZ_MAX); 312 break; 313 } 314 s->regs[R_SPI_DFSIZE] = value; 315 break; 316 317 case R_SPI_INTCLR: 318 s->regs[R_SPI_INTCLR] = value; 319 if (value & S_TXDONE) { 320 s->regs[R_SPI_RIS] &= ~S_TXDONE; 321 } 322 if (value & S_RXRDY) { 323 s->regs[R_SPI_RIS] &= ~S_RXRDY; 324 } 325 if (value & S_RXCHOVRF) { 326 s->regs[R_SPI_RIS] &= ~S_RXCHOVRF; 327 } 328 break; 329 330 case R_SPI_MIS: 331 case R_SPI_STATUS: 332 case R_SPI_RIS: 333 qemu_log_mask(LOG_GUEST_ERROR, 334 "%s: Write to read only register 0x%" HWADDR_PRIx "\n", 335 __func__, addr * 4); 336 break; 337 338 default: 339 if (addr < ARRAY_SIZE(s->regs)) { 340 s->regs[addr] = value; 341 } else { 342 qemu_log_mask(LOG_GUEST_ERROR, 343 "%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, 344 addr * 4); 345 } 346 break; 347 } 348 349 spi_update_irq(s); 350 } 351 352 static const MemoryRegionOps spi_ops = { 353 .read = spi_read, 354 .write = spi_write, 355 .endianness = DEVICE_NATIVE_ENDIAN, 356 .valid = { 357 .min_access_size = 1, 358 .max_access_size = 4 359 } 360 }; 361 362 static void mss_spi_realize(DeviceState *dev, Error **errp) 363 { 364 MSSSpiState *s = MSS_SPI(dev); 365 SysBusDevice *sbd = SYS_BUS_DEVICE(dev); 366 367 s->spi = ssi_create_bus(dev, "spi"); 368 369 sysbus_init_irq(sbd, &s->irq); 370 ssi_auto_connect_slaves(dev, &s->cs_line, s->spi); 371 sysbus_init_irq(sbd, &s->cs_line); 372 373 memory_region_init_io(&s->mmio, OBJECT(s), &spi_ops, s, 374 TYPE_MSS_SPI, R_SPI_MAX * 4); 375 sysbus_init_mmio(sbd, &s->mmio); 376 377 fifo32_create(&s->tx_fifo, FIFO_CAPACITY); 378 fifo32_create(&s->rx_fifo, FIFO_CAPACITY); 379 } 380 381 static const VMStateDescription vmstate_mss_spi = { 382 .name = TYPE_MSS_SPI, 383 .version_id = 1, 384 .minimum_version_id = 1, 385 .fields = (VMStateField[]) { 386 VMSTATE_FIFO32(tx_fifo, MSSSpiState), 387 VMSTATE_FIFO32(rx_fifo, MSSSpiState), 388 VMSTATE_UINT32_ARRAY(regs, MSSSpiState, R_SPI_MAX), 389 VMSTATE_END_OF_LIST() 390 } 391 }; 392 393 static void mss_spi_class_init(ObjectClass *klass, void *data) 394 { 395 DeviceClass *dc = DEVICE_CLASS(klass); 396 397 dc->realize = mss_spi_realize; 398 dc->reset = mss_spi_reset; 399 dc->vmsd = &vmstate_mss_spi; 400 } 401 402 static const TypeInfo mss_spi_info = { 403 .name = TYPE_MSS_SPI, 404 .parent = TYPE_SYS_BUS_DEVICE, 405 .instance_size = sizeof(MSSSpiState), 406 .class_init = mss_spi_class_init, 407 }; 408 409 static void mss_spi_register_types(void) 410 { 411 type_register_static(&mss_spi_info); 412 } 413 414 type_init(mss_spi_register_types) 415