static void pxa2xx_mmci_write(void *opaque, target_phys_addr_t offset, uint32_t value) { PXA2xxMMCIState *s = (PXA2xxMMCIState *) opaque; switch (offset) { case MMC_STRPCL: if (value & STRPCL_STRT_CLK) { s->status |= STAT_CLK_EN; s->intreq &= ~INT_CLK_OFF; if (s->cmdreq && !(s->cmdat & CMDAT_STOP_TRAN)) { s->status &= STAT_CLK_EN; pxa2xx_mmci_wakequeues(s); } } if (value & STRPCL_STOP_CLK) { s->status &= ~STAT_CLK_EN; s->intreq |= INT_CLK_OFF; s->active = 0; } pxa2xx_mmci_int_update(s); break; case MMC_CLKRT: s->clkrt = value & 7; break; case MMC_SPI: s->spi = value & 0xf; if (value & SPI_SPI_MODE) printf("%s: attempted to use card in SPI mode\n", __FUNCTION__); break; case MMC_CMDAT: s->cmdat = value & 0x3dff; s->active = 0; s->cmdreq = 1; if (!(value & CMDAT_STOP_TRAN)) { s->status &= STAT_CLK_EN; if (s->status & STAT_CLK_EN) pxa2xx_mmci_wakequeues(s); } pxa2xx_mmci_int_update(s); break; case MMC_RESTO: s->resp_tout = value & 0x7f; break; case MMC_RDTO: s->read_tout = value & 0xffff; break; case MMC_BLKLEN: s->blklen = value & 0xfff; break; case MMC_NUMBLK: s->numblk = value & 0xffff; break; case MMC_PRTBUF: if (value & PRTBUF_PRT_BUF) { s->tx_start ^= 32; s->tx_len = 0; } pxa2xx_mmci_fifo_update(s); break; case MMC_I_MASK: s->intmask = value & 0x1fff; pxa2xx_mmci_int_update(s); break; case MMC_CMD: s->cmd = value & 0x3f; break; case MMC_ARGH: s->arg &= 0x0000ffff; s->arg |= value << 16; break; case MMC_ARGL: s->arg &= 0xffff0000; s->arg |= value & 0x0000ffff; break; case MMC_TXFIFO: while (s->ac_width -- && s->tx_len < 0x20) s->tx_fifo[(s->tx_start + (s->tx_len ++)) & 0x1f] = (value >> (s->ac_width << 3)) & 0xff; s->intreq &= ~INT_TXFIFO_REQ; pxa2xx_mmci_fifo_update(s); break; case MMC_RDWAIT: case MMC_BLKS_REM: break; default: hw_error("%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset); } }
static void pxa2xx_mmci_write(void *opaque, hwaddr offset, uint64_t value, unsigned size) { PXA2xxMMCIState *s = (PXA2xxMMCIState *) opaque; trace_pxa2xx_mmci_write(size, offset, value); switch (offset) { case MMC_STRPCL: if (value & STRPCL_STRT_CLK) { s->status |= STAT_CLK_EN; s->intreq &= ~INT_CLK_OFF; if (s->cmdreq && !(s->cmdat & CMDAT_STOP_TRAN)) { s->status &= STAT_CLK_EN; pxa2xx_mmci_wakequeues(s); } } if (value & STRPCL_STOP_CLK) { s->status &= ~STAT_CLK_EN; s->intreq |= INT_CLK_OFF; s->active = 0; } pxa2xx_mmci_int_update(s); break; case MMC_CLKRT: s->clkrt = value & 7; break; case MMC_SPI: s->spi = value & 0xf; if (value & SPI_SPI_MODE) { qemu_log_mask(LOG_GUEST_ERROR, "%s: attempted to use card in SPI mode\n", __func__); } break; case MMC_CMDAT: s->cmdat = value & 0x3dff; s->active = 0; s->cmdreq = 1; if (!(value & CMDAT_STOP_TRAN)) { s->status &= STAT_CLK_EN; if (s->status & STAT_CLK_EN) pxa2xx_mmci_wakequeues(s); } pxa2xx_mmci_int_update(s); break; case MMC_RESTO: s->resp_tout = value & 0x7f; break; case MMC_RDTO: s->read_tout = value & 0xffff; break; case MMC_BLKLEN: s->blklen = value & 0xfff; break; case MMC_NUMBLK: s->numblk = value & 0xffff; break; case MMC_PRTBUF: if (value & PRTBUF_PRT_BUF) { s->tx_start ^= 32; s->tx_len = 0; } pxa2xx_mmci_fifo_update(s); break; case MMC_I_MASK: s->intmask = value & 0x1fff; pxa2xx_mmci_int_update(s); break; case MMC_CMD: s->cmd = value & 0x3f; break; case MMC_ARGH: s->arg &= 0x0000ffff; s->arg |= value << 16; break; case MMC_ARGL: s->arg &= 0xffff0000; s->arg |= value & 0x0000ffff; break; case MMC_TXFIFO: while (size-- && s->tx_len < 0x20) s->tx_fifo[(s->tx_start + (s->tx_len ++)) & 0x1f] = (value >> (size << 3)) & 0xff; s->intreq &= ~INT_TXFIFO_REQ; pxa2xx_mmci_fifo_update(s); break; case MMC_RDWAIT: case MMC_BLKS_REM: break; default: qemu_log_mask(LOG_GUEST_ERROR, "%s: incorrect reg 0x%02" HWADDR_PRIx " " "(value 0x%08" PRIx64 ")\n", __func__, offset, value); } }