pxa2xx_mmci.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553
  1. /*
  2. * Intel XScale PXA255/270 MultiMediaCard/SD/SDIO Controller emulation.
  3. *
  4. * Copyright (c) 2006 Openedhand Ltd.
  5. * Written by Andrzej Zaborowski <balrog@zabor.org>
  6. *
  7. * This code is licensed under the GPLv2.
  8. *
  9. * Contributions after 2012-01-13 are licensed under the terms of the
  10. * GNU GPL, version 2 or (at your option) any later version.
  11. */
  12. #include "hw.h"
  13. #include "pxa.h"
  14. #include "sd.h"
  15. #include "qdev.h"
  16. struct PXA2xxMMCIState {
  17. MemoryRegion iomem;
  18. qemu_irq irq;
  19. qemu_irq rx_dma;
  20. qemu_irq tx_dma;
  21. SDState *card;
  22. uint32_t status;
  23. uint32_t clkrt;
  24. uint32_t spi;
  25. uint32_t cmdat;
  26. uint32_t resp_tout;
  27. uint32_t read_tout;
  28. int blklen;
  29. int numblk;
  30. uint32_t intmask;
  31. uint32_t intreq;
  32. int cmd;
  33. uint32_t arg;
  34. int active;
  35. int bytesleft;
  36. uint8_t tx_fifo[64];
  37. int tx_start;
  38. int tx_len;
  39. uint8_t rx_fifo[32];
  40. int rx_start;
  41. int rx_len;
  42. uint16_t resp_fifo[9];
  43. int resp_len;
  44. int cmdreq;
  45. int ac_width;
  46. };
  47. #define MMC_STRPCL 0x00 /* MMC Clock Start/Stop register */
  48. #define MMC_STAT 0x04 /* MMC Status register */
  49. #define MMC_CLKRT 0x08 /* MMC Clock Rate register */
  50. #define MMC_SPI 0x0c /* MMC SPI Mode register */
  51. #define MMC_CMDAT 0x10 /* MMC Command/Data register */
  52. #define MMC_RESTO 0x14 /* MMC Response Time-Out register */
  53. #define MMC_RDTO 0x18 /* MMC Read Time-Out register */
  54. #define MMC_BLKLEN 0x1c /* MMC Block Length register */
  55. #define MMC_NUMBLK 0x20 /* MMC Number of Blocks register */
  56. #define MMC_PRTBUF 0x24 /* MMC Buffer Partly Full register */
  57. #define MMC_I_MASK 0x28 /* MMC Interrupt Mask register */
  58. #define MMC_I_REG 0x2c /* MMC Interrupt Request register */
  59. #define MMC_CMD 0x30 /* MMC Command register */
  60. #define MMC_ARGH 0x34 /* MMC Argument High register */
  61. #define MMC_ARGL 0x38 /* MMC Argument Low register */
  62. #define MMC_RES 0x3c /* MMC Response FIFO */
  63. #define MMC_RXFIFO 0x40 /* MMC Receive FIFO */
  64. #define MMC_TXFIFO 0x44 /* MMC Transmit FIFO */
  65. #define MMC_RDWAIT 0x48 /* MMC RD_WAIT register */
  66. #define MMC_BLKS_REM 0x4c /* MMC Blocks Remaining register */
  67. /* Bitfield masks */
  68. #define STRPCL_STOP_CLK (1 << 0)
  69. #define STRPCL_STRT_CLK (1 << 1)
  70. #define STAT_TOUT_RES (1 << 1)
  71. #define STAT_CLK_EN (1 << 8)
  72. #define STAT_DATA_DONE (1 << 11)
  73. #define STAT_PRG_DONE (1 << 12)
  74. #define STAT_END_CMDRES (1 << 13)
  75. #define SPI_SPI_MODE (1 << 0)
  76. #define CMDAT_RES_TYPE (3 << 0)
  77. #define CMDAT_DATA_EN (1 << 2)
  78. #define CMDAT_WR_RD (1 << 3)
  79. #define CMDAT_DMA_EN (1 << 7)
  80. #define CMDAT_STOP_TRAN (1 << 10)
  81. #define INT_DATA_DONE (1 << 0)
  82. #define INT_PRG_DONE (1 << 1)
  83. #define INT_END_CMD (1 << 2)
  84. #define INT_STOP_CMD (1 << 3)
  85. #define INT_CLK_OFF (1 << 4)
  86. #define INT_RXFIFO_REQ (1 << 5)
  87. #define INT_TXFIFO_REQ (1 << 6)
  88. #define INT_TINT (1 << 7)
  89. #define INT_DAT_ERR (1 << 8)
  90. #define INT_RES_ERR (1 << 9)
  91. #define INT_RD_STALLED (1 << 10)
  92. #define INT_SDIO_INT (1 << 11)
  93. #define INT_SDIO_SACK (1 << 12)
  94. #define PRTBUF_PRT_BUF (1 << 0)
  95. /* Route internal interrupt lines to the global IC and DMA */
  96. static void pxa2xx_mmci_int_update(PXA2xxMMCIState *s)
  97. {
  98. uint32_t mask = s->intmask;
  99. if (s->cmdat & CMDAT_DMA_EN) {
  100. mask |= INT_RXFIFO_REQ | INT_TXFIFO_REQ;
  101. qemu_set_irq(s->rx_dma, !!(s->intreq & INT_RXFIFO_REQ));
  102. qemu_set_irq(s->tx_dma, !!(s->intreq & INT_TXFIFO_REQ));
  103. }
  104. qemu_set_irq(s->irq, !!(s->intreq & ~mask));
  105. }
  106. static void pxa2xx_mmci_fifo_update(PXA2xxMMCIState *s)
  107. {
  108. if (!s->active)
  109. return;
  110. if (s->cmdat & CMDAT_WR_RD) {
  111. while (s->bytesleft && s->tx_len) {
  112. sd_write_data(s->card, s->tx_fifo[s->tx_start ++]);
  113. s->tx_start &= 0x1f;
  114. s->tx_len --;
  115. s->bytesleft --;
  116. }
  117. if (s->bytesleft)
  118. s->intreq |= INT_TXFIFO_REQ;
  119. } else
  120. while (s->bytesleft && s->rx_len < 32) {
  121. s->rx_fifo[(s->rx_start + (s->rx_len ++)) & 0x1f] =
  122. sd_read_data(s->card);
  123. s->bytesleft --;
  124. s->intreq |= INT_RXFIFO_REQ;
  125. }
  126. if (!s->bytesleft) {
  127. s->active = 0;
  128. s->intreq |= INT_DATA_DONE;
  129. s->status |= STAT_DATA_DONE;
  130. if (s->cmdat & CMDAT_WR_RD) {
  131. s->intreq |= INT_PRG_DONE;
  132. s->status |= STAT_PRG_DONE;
  133. }
  134. }
  135. pxa2xx_mmci_int_update(s);
  136. }
  137. static void pxa2xx_mmci_wakequeues(PXA2xxMMCIState *s)
  138. {
  139. int rsplen, i;
  140. SDRequest request;
  141. uint8_t response[16];
  142. s->active = 1;
  143. s->rx_len = 0;
  144. s->tx_len = 0;
  145. s->cmdreq = 0;
  146. request.cmd = s->cmd;
  147. request.arg = s->arg;
  148. request.crc = 0; /* FIXME */
  149. rsplen = sd_do_command(s->card, &request, response);
  150. s->intreq |= INT_END_CMD;
  151. memset(s->resp_fifo, 0, sizeof(s->resp_fifo));
  152. switch (s->cmdat & CMDAT_RES_TYPE) {
  153. #define PXAMMCI_RESP(wd, value0, value1) \
  154. s->resp_fifo[(wd) + 0] |= (value0); \
  155. s->resp_fifo[(wd) + 1] |= (value1) << 8;
  156. case 0: /* No response */
  157. goto complete;
  158. case 1: /* R1, R4, R5 or R6 */
  159. if (rsplen < 4)
  160. goto timeout;
  161. goto complete;
  162. case 2: /* R2 */
  163. if (rsplen < 16)
  164. goto timeout;
  165. goto complete;
  166. case 3: /* R3 */
  167. if (rsplen < 4)
  168. goto timeout;
  169. goto complete;
  170. complete:
  171. for (i = 0; rsplen > 0; i ++, rsplen -= 2) {
  172. PXAMMCI_RESP(i, response[i * 2], response[i * 2 + 1]);
  173. }
  174. s->status |= STAT_END_CMDRES;
  175. if (!(s->cmdat & CMDAT_DATA_EN))
  176. s->active = 0;
  177. else
  178. s->bytesleft = s->numblk * s->blklen;
  179. s->resp_len = 0;
  180. break;
  181. timeout:
  182. s->active = 0;
  183. s->status |= STAT_TOUT_RES;
  184. break;
  185. }
  186. pxa2xx_mmci_fifo_update(s);
  187. }
  188. static uint32_t pxa2xx_mmci_read(void *opaque, hwaddr offset)
  189. {
  190. PXA2xxMMCIState *s = (PXA2xxMMCIState *) opaque;
  191. uint32_t ret;
  192. switch (offset) {
  193. case MMC_STRPCL:
  194. return 0;
  195. case MMC_STAT:
  196. return s->status;
  197. case MMC_CLKRT:
  198. return s->clkrt;
  199. case MMC_SPI:
  200. return s->spi;
  201. case MMC_CMDAT:
  202. return s->cmdat;
  203. case MMC_RESTO:
  204. return s->resp_tout;
  205. case MMC_RDTO:
  206. return s->read_tout;
  207. case MMC_BLKLEN:
  208. return s->blklen;
  209. case MMC_NUMBLK:
  210. return s->numblk;
  211. case MMC_PRTBUF:
  212. return 0;
  213. case MMC_I_MASK:
  214. return s->intmask;
  215. case MMC_I_REG:
  216. return s->intreq;
  217. case MMC_CMD:
  218. return s->cmd | 0x40;
  219. case MMC_ARGH:
  220. return s->arg >> 16;
  221. case MMC_ARGL:
  222. return s->arg & 0xffff;
  223. case MMC_RES:
  224. if (s->resp_len < 9)
  225. return s->resp_fifo[s->resp_len ++];
  226. return 0;
  227. case MMC_RXFIFO:
  228. ret = 0;
  229. while (s->ac_width -- && s->rx_len) {
  230. ret |= s->rx_fifo[s->rx_start ++] << (s->ac_width << 3);
  231. s->rx_start &= 0x1f;
  232. s->rx_len --;
  233. }
  234. s->intreq &= ~INT_RXFIFO_REQ;
  235. pxa2xx_mmci_fifo_update(s);
  236. return ret;
  237. case MMC_RDWAIT:
  238. return 0;
  239. case MMC_BLKS_REM:
  240. return s->numblk;
  241. default:
  242. hw_error("%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);
  243. }
  244. return 0;
  245. }
  246. static void pxa2xx_mmci_write(void *opaque,
  247. hwaddr offset, uint32_t value)
  248. {
  249. PXA2xxMMCIState *s = (PXA2xxMMCIState *) opaque;
  250. switch (offset) {
  251. case MMC_STRPCL:
  252. if (value & STRPCL_STRT_CLK) {
  253. s->status |= STAT_CLK_EN;
  254. s->intreq &= ~INT_CLK_OFF;
  255. if (s->cmdreq && !(s->cmdat & CMDAT_STOP_TRAN)) {
  256. s->status &= STAT_CLK_EN;
  257. pxa2xx_mmci_wakequeues(s);
  258. }
  259. }
  260. if (value & STRPCL_STOP_CLK) {
  261. s->status &= ~STAT_CLK_EN;
  262. s->intreq |= INT_CLK_OFF;
  263. s->active = 0;
  264. }
  265. pxa2xx_mmci_int_update(s);
  266. break;
  267. case MMC_CLKRT:
  268. s->clkrt = value & 7;
  269. break;
  270. case MMC_SPI:
  271. s->spi = value & 0xf;
  272. if (value & SPI_SPI_MODE)
  273. printf("%s: attempted to use card in SPI mode\n", __FUNCTION__);
  274. break;
  275. case MMC_CMDAT:
  276. s->cmdat = value & 0x3dff;
  277. s->active = 0;
  278. s->cmdreq = 1;
  279. if (!(value & CMDAT_STOP_TRAN)) {
  280. s->status &= STAT_CLK_EN;
  281. if (s->status & STAT_CLK_EN)
  282. pxa2xx_mmci_wakequeues(s);
  283. }
  284. pxa2xx_mmci_int_update(s);
  285. break;
  286. case MMC_RESTO:
  287. s->resp_tout = value & 0x7f;
  288. break;
  289. case MMC_RDTO:
  290. s->read_tout = value & 0xffff;
  291. break;
  292. case MMC_BLKLEN:
  293. s->blklen = value & 0xfff;
  294. break;
  295. case MMC_NUMBLK:
  296. s->numblk = value & 0xffff;
  297. break;
  298. case MMC_PRTBUF:
  299. if (value & PRTBUF_PRT_BUF) {
  300. s->tx_start ^= 32;
  301. s->tx_len = 0;
  302. }
  303. pxa2xx_mmci_fifo_update(s);
  304. break;
  305. case MMC_I_MASK:
  306. s->intmask = value & 0x1fff;
  307. pxa2xx_mmci_int_update(s);
  308. break;
  309. case MMC_CMD:
  310. s->cmd = value & 0x3f;
  311. break;
  312. case MMC_ARGH:
  313. s->arg &= 0x0000ffff;
  314. s->arg |= value << 16;
  315. break;
  316. case MMC_ARGL:
  317. s->arg &= 0xffff0000;
  318. s->arg |= value & 0x0000ffff;
  319. break;
  320. case MMC_TXFIFO:
  321. while (s->ac_width -- && s->tx_len < 0x20)
  322. s->tx_fifo[(s->tx_start + (s->tx_len ++)) & 0x1f] =
  323. (value >> (s->ac_width << 3)) & 0xff;
  324. s->intreq &= ~INT_TXFIFO_REQ;
  325. pxa2xx_mmci_fifo_update(s);
  326. break;
  327. case MMC_RDWAIT:
  328. case MMC_BLKS_REM:
  329. break;
  330. default:
  331. hw_error("%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);
  332. }
  333. }
  334. static uint32_t pxa2xx_mmci_readb(void *opaque, hwaddr offset)
  335. {
  336. PXA2xxMMCIState *s = (PXA2xxMMCIState *) opaque;
  337. s->ac_width = 1;
  338. return pxa2xx_mmci_read(opaque, offset);
  339. }
  340. static uint32_t pxa2xx_mmci_readh(void *opaque, hwaddr offset)
  341. {
  342. PXA2xxMMCIState *s = (PXA2xxMMCIState *) opaque;
  343. s->ac_width = 2;
  344. return pxa2xx_mmci_read(opaque, offset);
  345. }
  346. static uint32_t pxa2xx_mmci_readw(void *opaque, hwaddr offset)
  347. {
  348. PXA2xxMMCIState *s = (PXA2xxMMCIState *) opaque;
  349. s->ac_width = 4;
  350. return pxa2xx_mmci_read(opaque, offset);
  351. }
  352. static void pxa2xx_mmci_writeb(void *opaque,
  353. hwaddr offset, uint32_t value)
  354. {
  355. PXA2xxMMCIState *s = (PXA2xxMMCIState *) opaque;
  356. s->ac_width = 1;
  357. pxa2xx_mmci_write(opaque, offset, value);
  358. }
  359. static void pxa2xx_mmci_writeh(void *opaque,
  360. hwaddr offset, uint32_t value)
  361. {
  362. PXA2xxMMCIState *s = (PXA2xxMMCIState *) opaque;
  363. s->ac_width = 2;
  364. pxa2xx_mmci_write(opaque, offset, value);
  365. }
  366. static void pxa2xx_mmci_writew(void *opaque,
  367. hwaddr offset, uint32_t value)
  368. {
  369. PXA2xxMMCIState *s = (PXA2xxMMCIState *) opaque;
  370. s->ac_width = 4;
  371. pxa2xx_mmci_write(opaque, offset, value);
  372. }
  373. static const MemoryRegionOps pxa2xx_mmci_ops = {
  374. .old_mmio = {
  375. .read = { pxa2xx_mmci_readb,
  376. pxa2xx_mmci_readh,
  377. pxa2xx_mmci_readw, },
  378. .write = { pxa2xx_mmci_writeb,
  379. pxa2xx_mmci_writeh,
  380. pxa2xx_mmci_writew, },
  381. },
  382. .endianness = DEVICE_NATIVE_ENDIAN,
  383. };
  384. static void pxa2xx_mmci_save(QEMUFile *f, void *opaque)
  385. {
  386. PXA2xxMMCIState *s = (PXA2xxMMCIState *) opaque;
  387. int i;
  388. qemu_put_be32s(f, &s->status);
  389. qemu_put_be32s(f, &s->clkrt);
  390. qemu_put_be32s(f, &s->spi);
  391. qemu_put_be32s(f, &s->cmdat);
  392. qemu_put_be32s(f, &s->resp_tout);
  393. qemu_put_be32s(f, &s->read_tout);
  394. qemu_put_be32(f, s->blklen);
  395. qemu_put_be32(f, s->numblk);
  396. qemu_put_be32s(f, &s->intmask);
  397. qemu_put_be32s(f, &s->intreq);
  398. qemu_put_be32(f, s->cmd);
  399. qemu_put_be32s(f, &s->arg);
  400. qemu_put_be32(f, s->cmdreq);
  401. qemu_put_be32(f, s->active);
  402. qemu_put_be32(f, s->bytesleft);
  403. qemu_put_byte(f, s->tx_len);
  404. for (i = 0; i < s->tx_len; i ++)
  405. qemu_put_byte(f, s->tx_fifo[(s->tx_start + i) & 63]);
  406. qemu_put_byte(f, s->rx_len);
  407. for (i = 0; i < s->rx_len; i ++)
  408. qemu_put_byte(f, s->rx_fifo[(s->rx_start + i) & 31]);
  409. qemu_put_byte(f, s->resp_len);
  410. for (i = s->resp_len; i < 9; i ++)
  411. qemu_put_be16s(f, &s->resp_fifo[i]);
  412. }
  413. static int pxa2xx_mmci_load(QEMUFile *f, void *opaque, int version_id)
  414. {
  415. PXA2xxMMCIState *s = (PXA2xxMMCIState *) opaque;
  416. int i;
  417. qemu_get_be32s(f, &s->status);
  418. qemu_get_be32s(f, &s->clkrt);
  419. qemu_get_be32s(f, &s->spi);
  420. qemu_get_be32s(f, &s->cmdat);
  421. qemu_get_be32s(f, &s->resp_tout);
  422. qemu_get_be32s(f, &s->read_tout);
  423. s->blklen = qemu_get_be32(f);
  424. s->numblk = qemu_get_be32(f);
  425. qemu_get_be32s(f, &s->intmask);
  426. qemu_get_be32s(f, &s->intreq);
  427. s->cmd = qemu_get_be32(f);
  428. qemu_get_be32s(f, &s->arg);
  429. s->cmdreq = qemu_get_be32(f);
  430. s->active = qemu_get_be32(f);
  431. s->bytesleft = qemu_get_be32(f);
  432. s->tx_len = qemu_get_byte(f);
  433. s->tx_start = 0;
  434. if (s->tx_len >= sizeof(s->tx_fifo) || s->tx_len < 0)
  435. return -EINVAL;
  436. for (i = 0; i < s->tx_len; i ++)
  437. s->tx_fifo[i] = qemu_get_byte(f);
  438. s->rx_len = qemu_get_byte(f);
  439. s->rx_start = 0;
  440. if (s->rx_len >= sizeof(s->rx_fifo) || s->rx_len < 0)
  441. return -EINVAL;
  442. for (i = 0; i < s->rx_len; i ++)
  443. s->rx_fifo[i] = qemu_get_byte(f);
  444. s->resp_len = qemu_get_byte(f);
  445. if (s->resp_len > 9 || s->resp_len < 0)
  446. return -EINVAL;
  447. for (i = s->resp_len; i < 9; i ++)
  448. qemu_get_be16s(f, &s->resp_fifo[i]);
  449. return 0;
  450. }
  451. PXA2xxMMCIState *pxa2xx_mmci_init(MemoryRegion *sysmem,
  452. hwaddr base,
  453. BlockDriverState *bd, qemu_irq irq,
  454. qemu_irq rx_dma, qemu_irq tx_dma)
  455. {
  456. PXA2xxMMCIState *s;
  457. s = (PXA2xxMMCIState *) g_malloc0(sizeof(PXA2xxMMCIState));
  458. s->irq = irq;
  459. s->rx_dma = rx_dma;
  460. s->tx_dma = tx_dma;
  461. memory_region_init_io(&s->iomem, &pxa2xx_mmci_ops, s,
  462. "pxa2xx-mmci", 0x00100000);
  463. memory_region_add_subregion(sysmem, base, &s->iomem);
  464. /* Instantiate the actual storage */
  465. s->card = sd_init(bd, 0);
  466. register_savevm(NULL, "pxa2xx_mmci", 0, 0,
  467. pxa2xx_mmci_save, pxa2xx_mmci_load, s);
  468. return s;
  469. }
  470. void pxa2xx_mmci_handlers(PXA2xxMMCIState *s, qemu_irq readonly,
  471. qemu_irq coverswitch)
  472. {
  473. sd_set_cb(s->card, readonly, coverswitch);
  474. }