imx_spi.c (13407B)
1/* 2 * IMX SPI Controller 3 * 4 * Copyright (c) 2016 Jean-Christophe Dubois <jcd@tribudubois.net> 5 * 6 * This work is licensed under the terms of the GNU GPL, version 2 or later. 7 * See the COPYING file in the top-level directory. 8 * 9 */ 10 11#include "qemu/osdep.h" 12#include "hw/irq.h" 13#include "hw/ssi/imx_spi.h" 14#include "migration/vmstate.h" 15#include "qemu/log.h" 16#include "qemu/module.h" 17 18#ifndef DEBUG_IMX_SPI 19#define DEBUG_IMX_SPI 0 20#endif 21 22#define DPRINTF(fmt, args...) \ 23 do { \ 24 if (DEBUG_IMX_SPI) { \ 25 fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX_SPI, \ 26 __func__, ##args); \ 27 } \ 28 } while (0) 29 30static const char *imx_spi_reg_name(uint32_t reg) 31{ 32 static char unknown[20]; 33 34 switch (reg) { 35 case ECSPI_RXDATA: 36 return "ECSPI_RXDATA"; 37 case ECSPI_TXDATA: 38 return "ECSPI_TXDATA"; 39 case ECSPI_CONREG: 40 return "ECSPI_CONREG"; 41 case ECSPI_CONFIGREG: 42 return "ECSPI_CONFIGREG"; 43 case ECSPI_INTREG: 44 return "ECSPI_INTREG"; 45 case ECSPI_DMAREG: 46 return "ECSPI_DMAREG"; 47 case ECSPI_STATREG: 48 return "ECSPI_STATREG"; 49 case ECSPI_PERIODREG: 50 return "ECSPI_PERIODREG"; 51 case ECSPI_TESTREG: 52 return "ECSPI_TESTREG"; 53 case ECSPI_MSGDATA: 54 return "ECSPI_MSGDATA"; 55 default: 56 sprintf(unknown, "%u ?", reg); 57 return unknown; 58 } 59} 60 61static const VMStateDescription vmstate_imx_spi = { 62 .name = TYPE_IMX_SPI, 63 .version_id = 1, 64 .minimum_version_id = 1, 65 .fields = (VMStateField[]) { 66 VMSTATE_FIFO32(tx_fifo, IMXSPIState), 67 VMSTATE_FIFO32(rx_fifo, IMXSPIState), 68 VMSTATE_INT16(burst_length, IMXSPIState), 69 VMSTATE_UINT32_ARRAY(regs, IMXSPIState, ECSPI_MAX), 70 VMSTATE_END_OF_LIST() 71 }, 72}; 73 74static void imx_spi_txfifo_reset(IMXSPIState *s) 75{ 76 fifo32_reset(&s->tx_fifo); 77 s->regs[ECSPI_STATREG] |= ECSPI_STATREG_TE; 78 s->regs[ECSPI_STATREG] &= ~ECSPI_STATREG_TF; 79} 80 81static void imx_spi_rxfifo_reset(IMXSPIState *s) 82{ 83 fifo32_reset(&s->rx_fifo); 84 s->regs[ECSPI_STATREG] &= ~ECSPI_STATREG_RR; 85 s->regs[ECSPI_STATREG] &= ~ECSPI_STATREG_RF; 86 s->regs[ECSPI_STATREG] &= ~ECSPI_STATREG_RO; 87} 88 89static void imx_spi_update_irq(IMXSPIState *s) 90{ 91 int level; 92 93 if (fifo32_is_empty(&s->rx_fifo)) { 94 s->regs[ECSPI_STATREG] &= ~ECSPI_STATREG_RR; 95 } else { 96 s->regs[ECSPI_STATREG] |= ECSPI_STATREG_RR; 97 } 98 99 if (fifo32_is_full(&s->rx_fifo)) { 100 s->regs[ECSPI_STATREG] |= ECSPI_STATREG_RF; 101 } else { 102 s->regs[ECSPI_STATREG] &= ~ECSPI_STATREG_RF; 103 } 104 105 if (fifo32_is_empty(&s->tx_fifo)) { 106 s->regs[ECSPI_STATREG] |= ECSPI_STATREG_TE; 107 } else { 108 s->regs[ECSPI_STATREG] &= ~ECSPI_STATREG_TE; 109 } 110 111 if (fifo32_is_full(&s->tx_fifo)) { 112 s->regs[ECSPI_STATREG] |= ECSPI_STATREG_TF; 113 } else { 114 s->regs[ECSPI_STATREG] &= ~ECSPI_STATREG_TF; 115 } 116 117 level = s->regs[ECSPI_STATREG] & s->regs[ECSPI_INTREG] ? 1 : 0; 118 119 qemu_set_irq(s->irq, level); 120 121 DPRINTF("IRQ level is %d\n", level); 122} 123 124static uint8_t imx_spi_selected_channel(IMXSPIState *s) 125{ 126 return EXTRACT(s->regs[ECSPI_CONREG], ECSPI_CONREG_CHANNEL_SELECT); 127} 128 129static uint32_t imx_spi_burst_length(IMXSPIState *s) 130{ 131 uint32_t burst; 132 133 burst = EXTRACT(s->regs[ECSPI_CONREG], ECSPI_CONREG_BURST_LENGTH) + 1; 134 if (burst % 8) { 135 burst = ROUND_UP(burst, 8); 136 } 137 138 return burst; 139} 140 141static bool imx_spi_is_enabled(IMXSPIState *s) 142{ 143 return s->regs[ECSPI_CONREG] & ECSPI_CONREG_EN; 144} 145 146static bool imx_spi_channel_is_master(IMXSPIState *s) 147{ 148 uint8_t mode = EXTRACT(s->regs[ECSPI_CONREG], ECSPI_CONREG_CHANNEL_MODE); 149 150 return (mode & (1 << imx_spi_selected_channel(s))) ? true : false; 151} 152 153static bool imx_spi_is_multiple_master_burst(IMXSPIState *s) 154{ 155 uint8_t wave = EXTRACT(s->regs[ECSPI_CONFIGREG], ECSPI_CONFIGREG_SS_CTL); 156 157 return imx_spi_channel_is_master(s) && 158 !(s->regs[ECSPI_CONREG] & ECSPI_CONREG_SMC) && 159 ((wave & (1 << imx_spi_selected_channel(s))) ? true : false); 160} 161 162static void imx_spi_flush_txfifo(IMXSPIState *s) 163{ 164 uint32_t tx; 165 uint32_t rx; 166 167 DPRINTF("Begin: TX Fifo Size = %d, RX Fifo Size = %d\n", 168 fifo32_num_used(&s->tx_fifo), fifo32_num_used(&s->rx_fifo)); 169 170 while (!fifo32_is_empty(&s->tx_fifo)) { 171 int tx_burst = 0; 172 173 if (s->burst_length <= 0) { 174 s->burst_length = imx_spi_burst_length(s); 175 176 DPRINTF("Burst length = %d\n", s->burst_length); 177 178 if (imx_spi_is_multiple_master_burst(s)) { 179 s->regs[ECSPI_CONREG] |= ECSPI_CONREG_XCH; 180 } 181 } 182 183 tx = fifo32_pop(&s->tx_fifo); 184 185 DPRINTF("data tx:0x%08x\n", tx); 186 187 tx_burst = (s->burst_length % 32) ? : 32; 188 189 rx = 0; 190 191 while (tx_burst > 0) { 192 uint8_t byte = tx >> (tx_burst - 8); 193 194 DPRINTF("writing 0x%02x\n", (uint32_t)byte); 195 196 /* We need to write one byte at a time */ 197 byte = ssi_transfer(s->bus, byte); 198 199 DPRINTF("0x%02x read\n", (uint32_t)byte); 200 201 rx = (rx << 8) | byte; 202 203 /* Remove 8 bits from the actual burst */ 204 tx_burst -= 8; 205 s->burst_length -= 8; 206 } 207 208 DPRINTF("data rx:0x%08x\n", rx); 209 210 if (fifo32_is_full(&s->rx_fifo)) { 211 s->regs[ECSPI_STATREG] |= ECSPI_STATREG_RO; 212 } else { 213 fifo32_push(&s->rx_fifo, rx); 214 } 215 216 if (s->burst_length <= 0) { 217 if (!imx_spi_is_multiple_master_burst(s)) { 218 s->regs[ECSPI_STATREG] |= ECSPI_STATREG_TC; 219 break; 220 } 221 } 222 } 223 224 if (fifo32_is_empty(&s->tx_fifo)) { 225 s->regs[ECSPI_STATREG] |= ECSPI_STATREG_TC; 226 s->regs[ECSPI_CONREG] &= ~ECSPI_CONREG_XCH; 227 } 228 229 /* TODO: We should also use TDR and RDR bits */ 230 231 DPRINTF("End: TX Fifo Size = %d, RX Fifo Size = %d\n", 232 fifo32_num_used(&s->tx_fifo), fifo32_num_used(&s->rx_fifo)); 233} 234 235static void imx_spi_common_reset(IMXSPIState *s) 236{ 237 int i; 238 239 for (i = 0; i < ARRAY_SIZE(s->regs); i++) { 240 switch (i) { 241 case ECSPI_CONREG: 242 /* CONREG is not updated on soft reset */ 243 break; 244 case ECSPI_STATREG: 245 s->regs[i] = 0x00000003; 246 break; 247 default: 248 s->regs[i] = 0; 249 break; 250 } 251 } 252 253 imx_spi_rxfifo_reset(s); 254 imx_spi_txfifo_reset(s); 255 256 s->burst_length = 0; 257} 258 259static void imx_spi_soft_reset(IMXSPIState *s) 260{ 261 int i; 262 263 imx_spi_common_reset(s); 264 265 imx_spi_update_irq(s); 266 267 for (i = 0; i < ECSPI_NUM_CS; i++) { 268 qemu_set_irq(s->cs_lines[i], 1); 269 } 270} 271 272static void imx_spi_reset(DeviceState *dev) 273{ 274 IMXSPIState *s = IMX_SPI(dev); 275 276 imx_spi_common_reset(s); 277 s->regs[ECSPI_CONREG] = 0; 278} 279 280static uint64_t imx_spi_read(void *opaque, hwaddr offset, unsigned size) 281{ 282 uint32_t value = 0; 283 IMXSPIState *s = opaque; 284 uint32_t index = offset >> 2; 285 286 if (index >= ECSPI_MAX) { 287 qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%" 288 HWADDR_PRIx "\n", TYPE_IMX_SPI, __func__, offset); 289 return 0; 290 } 291 292 value = s->regs[index]; 293 294 if (imx_spi_is_enabled(s)) { 295 switch (index) { 296 case ECSPI_RXDATA: 297 if (fifo32_is_empty(&s->rx_fifo)) { 298 /* value is undefined */ 299 value = 0xdeadbeef; 300 } else { 301 /* read from the RX FIFO */ 302 value = fifo32_pop(&s->rx_fifo); 303 } 304 break; 305 case ECSPI_TXDATA: 306 qemu_log_mask(LOG_GUEST_ERROR, 307 "[%s]%s: Trying to read from TX FIFO\n", 308 TYPE_IMX_SPI, __func__); 309 310 /* Reading from TXDATA gives 0 */ 311 break; 312 case ECSPI_MSGDATA: 313 qemu_log_mask(LOG_GUEST_ERROR, 314 "[%s]%s: Trying to read from MSG FIFO\n", 315 TYPE_IMX_SPI, __func__); 316 /* Reading from MSGDATA gives 0 */ 317 break; 318 default: 319 break; 320 } 321 322 imx_spi_update_irq(s); 323 } 324 DPRINTF("reg[%s] => 0x%" PRIx32 "\n", imx_spi_reg_name(index), value); 325 326 return (uint64_t)value; 327} 328 329static void imx_spi_write(void *opaque, hwaddr offset, uint64_t value, 330 unsigned size) 331{ 332 IMXSPIState *s = opaque; 333 uint32_t index = offset >> 2; 334 uint32_t change_mask; 335 uint32_t burst; 336 337 if (index >= ECSPI_MAX) { 338 qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%" 339 HWADDR_PRIx "\n", TYPE_IMX_SPI, __func__, offset); 340 return; 341 } 342 343 DPRINTF("reg[%s] <= 0x%" PRIx32 "\n", imx_spi_reg_name(index), 344 (uint32_t)value); 345 346 if (!imx_spi_is_enabled(s)) { 347 /* Block is disabled */ 348 if (index != ECSPI_CONREG) { 349 /* Ignore access */ 350 return; 351 } 352 } 353 354 change_mask = s->regs[index] ^ value; 355 356 switch (index) { 357 case ECSPI_RXDATA: 358 qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Trying to write to RX FIFO\n", 359 TYPE_IMX_SPI, __func__); 360 break; 361 case ECSPI_TXDATA: 362 if (fifo32_is_full(&s->tx_fifo)) { 363 /* Ignore writes if queue is full */ 364 break; 365 } 366 367 fifo32_push(&s->tx_fifo, (uint32_t)value); 368 369 if (imx_spi_channel_is_master(s) && 370 (s->regs[ECSPI_CONREG] & ECSPI_CONREG_SMC)) { 371 /* 372 * Start emitting if current channel is master and SMC bit is 373 * set. 374 */ 375 imx_spi_flush_txfifo(s); 376 } 377 378 break; 379 case ECSPI_STATREG: 380 /* the RO and TC bits are write-one-to-clear */ 381 value &= ECSPI_STATREG_RO | ECSPI_STATREG_TC; 382 s->regs[ECSPI_STATREG] &= ~value; 383 384 break; 385 case ECSPI_CONREG: 386 s->regs[ECSPI_CONREG] = value; 387 388 burst = EXTRACT(s->regs[ECSPI_CONREG], ECSPI_CONREG_BURST_LENGTH) + 1; 389 if (burst % 8) { 390 qemu_log_mask(LOG_UNIMP, 391 "[%s]%s: burst length %d not supported: rounding up to next multiple of 8\n", 392 TYPE_IMX_SPI, __func__, burst); 393 } 394 395 if (!imx_spi_is_enabled(s)) { 396 /* device is disabled, so this is a soft reset */ 397 imx_spi_soft_reset(s); 398 399 return; 400 } 401 402 if (imx_spi_channel_is_master(s)) { 403 int i; 404 405 /* We are in master mode */ 406 407 for (i = 0; i < ECSPI_NUM_CS; i++) { 408 qemu_set_irq(s->cs_lines[i], 409 i == imx_spi_selected_channel(s) ? 0 : 1); 410 } 411 412 if ((value & change_mask & ECSPI_CONREG_SMC) && 413 !fifo32_is_empty(&s->tx_fifo)) { 414 /* SMC bit is set and TX FIFO has some slots filled in */ 415 imx_spi_flush_txfifo(s); 416 } else if ((value & change_mask & ECSPI_CONREG_XCH) && 417 !(value & ECSPI_CONREG_SMC)) { 418 /* This is a request to start emitting */ 419 imx_spi_flush_txfifo(s); 420 } 421 } 422 423 break; 424 case ECSPI_MSGDATA: 425 /* it is not clear from the spec what MSGDATA is for */ 426 /* Anyway it is not used by Linux driver */ 427 /* So for now we just ignore it */ 428 qemu_log_mask(LOG_UNIMP, 429 "[%s]%s: Trying to write to MSGDATA, ignoring\n", 430 TYPE_IMX_SPI, __func__); 431 break; 432 default: 433 s->regs[index] = value; 434 435 break; 436 } 437 438 imx_spi_update_irq(s); 439} 440 441static const struct MemoryRegionOps imx_spi_ops = { 442 .read = imx_spi_read, 443 .write = imx_spi_write, 444 .endianness = DEVICE_NATIVE_ENDIAN, 445 .valid = { 446 /* 447 * Our device would not work correctly if the guest was doing 448 * unaligned access. This might not be a limitation on the real 449 * device but in practice there is no reason for a guest to access 450 * this device unaligned. 451 */ 452 .min_access_size = 4, 453 .max_access_size = 4, 454 .unaligned = false, 455 }, 456}; 457 458static void imx_spi_realize(DeviceState *dev, Error **errp) 459{ 460 IMXSPIState *s = IMX_SPI(dev); 461 int i; 462 463 s->bus = ssi_create_bus(dev, "spi"); 464 465 memory_region_init_io(&s->iomem, OBJECT(dev), &imx_spi_ops, s, 466 TYPE_IMX_SPI, 0x1000); 467 sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem); 468 sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq); 469 470 for (i = 0; i < ECSPI_NUM_CS; ++i) { 471 sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->cs_lines[i]); 472 } 473 474 fifo32_create(&s->tx_fifo, ECSPI_FIFO_SIZE); 475 fifo32_create(&s->rx_fifo, ECSPI_FIFO_SIZE); 476} 477 478static void imx_spi_class_init(ObjectClass *klass, void *data) 479{ 480 DeviceClass *dc = DEVICE_CLASS(klass); 481 482 dc->realize = imx_spi_realize; 483 dc->vmsd = &vmstate_imx_spi; 484 dc->reset = imx_spi_reset; 485 dc->desc = "i.MX SPI Controller"; 486} 487 488static const TypeInfo imx_spi_info = { 489 .name = TYPE_IMX_SPI, 490 .parent = TYPE_SYS_BUS_DEVICE, 491 .instance_size = sizeof(IMXSPIState), 492 .class_init = imx_spi_class_init, 493}; 494 495static void imx_spi_register_types(void) 496{ 497 type_register_static(&imx_spi_info); 498} 499 500type_init(imx_spi_register_types)