qemu/hw/ssi/imx_spi.c
<<
>>
Prefs
   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)
 501