qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

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 
     30 static 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 
     61 static 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 
     74 static 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 
     81 static 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 
     89 static 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 
    124 static uint8_t imx_spi_selected_channel(IMXSPIState *s)
    125 {
    126     return EXTRACT(s->regs[ECSPI_CONREG], ECSPI_CONREG_CHANNEL_SELECT);
    127 }
    128 
    129 static 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 
    141 static bool imx_spi_is_enabled(IMXSPIState *s)
    142 {
    143     return s->regs[ECSPI_CONREG] & ECSPI_CONREG_EN;
    144 }
    145 
    146 static 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 
    153 static 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 
    162 static 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 
    235 static 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 
    259 static 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 
    272 static 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 
    280 static 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 
    329 static 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 
    441 static 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 
    458 static 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 
    478 static 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 
    488 static 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 
    495 static void imx_spi_register_types(void)
    496 {
    497     type_register_static(&imx_spi_info);
    498 }
    499 
    500 type_init(imx_spi_register_types)