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