Merge commit 'gnu/master' into test
[qemu] / hw / omap3_mmc.c
1 /*
2  * OMAP3 Multimedia Card/Secure Digital/Secure Digital I/O (MMC/SD/SDIO) Card Interface emulation
3  *
4  * Copyright (C) 2008 yajin  <yajin@vm-kernel.org>
5  * Copyright (C) 2009 Nokia Corporation
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2 or
10  * (at your option) version 3 of the License.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20  * MA 02111-1307 USA
21  */
22 #include "hw.h"
23 #include "omap.h"
24 #include "sd.h"
25
26 /* debug levels:
27    0 - no debug
28    1 - print out all commands in processing order
29    2 - dump all register accesses and buffer management */
30 #define MMC_DEBUG_LEVEL 0
31
32 #if MMC_DEBUG_LEVEL>0
33 #define TRACE(fmt,...) fprintf(stderr, "%s: " fmt "\n", __FUNCTION__, ##__VA_ARGS__)
34 #if MMC_DEBUG_LEVEL>1
35 #define TRACE2(...) TRACE(__VA_ARGS__)
36 #else
37 #define TRACE2(...)
38 #endif
39 #else
40 #define TRACE(...)
41 #define TRACE2(...)
42 #endif
43
44 struct omap3_mmc_s
45 {
46     qemu_irq irq;
47     qemu_irq *dma;
48     qemu_irq coverswitch;
49     omap_clk clk;
50     SDState *card;
51
52     uint32_t sysconfig;
53     uint32_t sysstatus;
54     uint32_t csre;
55     uint32_t systest;
56     uint32_t con;
57     uint32_t pwcnt;
58     uint32_t blk;
59     uint32_t arg;
60     uint32_t cmd;
61     uint32_t rsp10;
62     uint32_t rsp32;
63     uint32_t rsp54;
64     uint32_t rsp76;
65     uint32_t data;
66     uint32_t pstate;
67     uint32_t hctl;
68     uint32_t sysctl;
69     uint32_t stat;
70     uint32_t ie;
71     uint32_t ise;
72     uint32_t ac12;
73     uint32_t capa;
74     uint32_t cur_capa;
75     uint32_t rev;
76
77     uint16_t blen_counter;
78     uint16_t nblk_counter;
79
80     uint32_t fifo[256];
81     int fifo_start;
82     int fifo_len;
83
84     int ddir;
85     int transfer;
86     int stop;
87     
88     uint32_t stat_pending;
89 };
90
91
92 typedef enum
93 {
94     sd_nore = 0,     /* no response */
95     sd_136_bits = 1, /* response length 136 bits */
96     sd_48_bits = 2,  /* response length 48 bits */
97     sd_48b_bits = 3, /* response length 48 bits with busy after response */
98 } omap3_sd_rsp_type_t;
99
100 static void omap3_mmc_command(struct omap3_mmc_s *host);
101
102 static void omap3_mmc_interrupts_update(struct omap3_mmc_s *s)
103 {
104     qemu_set_irq(s->irq, !!((s->stat | s->stat_pending) & s->ie & s->ise));
105 }
106
107 static void omap3_mmc_fifolevel_update(struct omap3_mmc_s *host)
108 {
109     enum { ongoing, ready, aborted } state = ongoing;
110     
111     if ((host->cmd & (1 << 21))) { /* DP */
112         if (host->ddir) {
113             TRACE2("receive, dma=%d, fifo_len=%d bytes",
114                    host->cmd & 1, host->fifo_len * 4);
115             
116             /* omap3_mmc_transfer ensures we always have data in FIFO
117                during receive as long as all data has not been transferred -
118                NOTE that the actual transfer may be finished already (i.e.
119                host->transfer is cleared) but not all data has been read out
120                from FIFO yet */
121             if (host->fifo_len) {
122                 if (host->cmd & 1) { /* DE */
123                     if (host->fifo_len * 4 == (host->blk & 0x7ff)) { /* BLEN */
124                         if (host->stop)
125                             state = aborted;
126                         else
127                             qemu_irq_raise(host->dma[1]);
128                     } else
129                         qemu_irq_lower(host->dma[1]);
130                 } else {
131                     if (host->stop 
132                         && host->fifo_len * 4 == (host->blk & 0x7ff))
133                         state = aborted;
134                     else {
135                         host->pstate |= 0x0800;      /* BRE */
136                         host->stat_pending |= 0x20;  /* BRR */
137                     }
138                 }
139             }
140             else
141                 state = host->stop ? aborted : ready;
142         } else {
143             /* omap3_mmc_transfer keeps FIFO empty during transmit so
144                we just check all blocks have been transferred or not */
145             if (host->transfer) {
146                 if (host->cmd & 1) { /* DE */
147                     if (host->blen_counter == (host->blk & 0x7ff)) { /* BLEN */
148                         if (host->stop)
149                             state = aborted;
150                         else
151                             qemu_irq_raise(host->dma[0]);
152                     } else
153                         qemu_irq_lower(host->dma[0]);
154                 } else {
155                     if (host->stop
156                         && host->blen_counter == (host->blk & 0x7ff))
157                         state = aborted;
158                     else {
159                         host->pstate |= 0x0400;      /* BWE */
160                         host->stat_pending |= 0x10;  /* BWR */
161                     }
162                 }
163             } else
164                 state = host->stop ? aborted : ready;
165         }
166
167         if ((host->cmd & 1) || state != ongoing) { /* DE */
168             host->pstate &= ~0x0c00;               /* BRE | BWE */
169             host->stat_pending &= ~0x30;           /* BRR | BWR */
170             host->stat &= ~0x30;                   /* BRR | BWR */
171             if (state != ongoing) {
172                 TRACE2("transfer %s", 
173                        state == ready
174                        ? "complete"
175                        : "aborted --> complete");
176                 host->stat_pending |= 0x2;         /* TC */
177                 if (host->cmd & 0x04) {            /* ACEN */
178                     host->stop = 0x0cc30000;
179                     state = aborted;
180                 }
181                 if (state == aborted) {
182                     host->cmd = host->stop;
183                     host->stop = 0;
184                     omap3_mmc_command(host);
185                 }
186             }
187         }
188     }
189 }
190
191 static void omap3_mmc_transfer(struct omap3_mmc_s *host)
192 {
193     int i;
194     uint32_t x;
195 #if MMC_DEBUG_LEVEL>1
196     int j;
197     uint8_t c, sym[17];
198 #endif
199
200     /* IF data transfer is inactive
201        OR block count enabled with zero block count
202        OR in receive mode and we have unread data in FIFO
203        OR in transmit mode and we have no data in FIFO,
204        THEN don't do anything */
205     if (!host->transfer
206         || ((host->cmd & 2) && !host->nblk_counter)
207         || (host->ddir && host->fifo_len)
208         || (!host->ddir && !host->fifo_len))
209         return;
210     
211     if (host->ddir) {
212         TRACE2("begin, %d blocks (%d bytes/block) left to receive, %d bytes in FIFO",
213                (host->cmd & 2) ? host->nblk_counter : 1,
214                host->blk & 0x7ff, 
215                host->fifo_len * 4);
216         while (host->blen_counter && host->fifo_len < 255) {
217             for (i = 0, x = 0; i < 32 && host->blen_counter; i += 8, host->blen_counter--)
218                 x |= sd_read_data(host->card) << i;
219             host->fifo[(host->fifo_start + host->fifo_len) & 0xff] = x;
220             host->fifo_len++;
221         }
222         TRACE2("end, %d bytes in FIFO:", host->fifo_len * 4);
223 #if MMC_DEBUG_LEVEL>1
224         for (i = 0; i < host->fifo_len; ) {
225             fprintf(stderr, "%s: [0x%03x] ", __FUNCTION__, i * 4);
226             do {
227                 x = host->fifo[(host->fifo_start + i) & 0xff];
228                 for (j = 0; j < 4; j++) {
229                     c = (x >> (j * 8)) & 0xff;
230                     fprintf(stderr, "%02x ", c);
231                     sym[(i & 3) * 4 + j] = (c < 32 || c > 126) ? '.' : c;
232                 }
233             } while (((++i) & 3));
234             sym[16] = 0;
235             fprintf(stderr, "%s\n", sym);
236         }
237 #endif
238     } else {
239         TRACE2("%d bytes left to transmit in current block", host->blen_counter);
240         while (host->blen_counter && host->fifo_len) {
241             for (i = 0; i < 32 && host->blen_counter; i += 8, host->blen_counter--)
242                 sd_write_data(host->card, (host->fifo[host->fifo_start] >> i) & 0xff);
243             host->fifo_start++;
244             host->fifo_len--;
245             host->fifo_start &= 0xff;
246         }
247     }
248
249     if (!host->blen_counter) {
250         if (host->cmd & 2) /* BCE */
251             host->nblk_counter--;
252         TRACE2("block done, %d blocks left",
253                (host->cmd & (1 << 5)) ? host->nblk_counter : 0);
254         host->blen_counter = host->blk & 0x7ff;
255         if (!(host->cmd & (1 << 5)) /* MSBS */
256             || !host->nblk_counter) {
257             host->nblk_counter = (host->blk >> 16) & 0xffff;
258             host->transfer = 0;
259             host->pstate &= ~0x0306; /* RTA | WTA | DLA | DATI */
260         }
261     }
262 }
263
264 static void omap3_mmc_command(struct omap3_mmc_s *host)
265 {
266     uint32_t rspstatus, mask;
267     int rsplen, timeout;
268     SDRequest request;
269     uint8_t response[16];
270     int cmd = (host->cmd >> 24) & 0x3f; /* INDX */
271     
272     TRACE("%d type=%d arg=0x%08x blk=0x%08x, fifo=%d/%d",
273           cmd, (host->cmd >> 22) & 3, host->arg, host->blk,
274           host->fifo_start, host->fifo_len);
275
276     if ((host->con & 2) && !cmd) { /* INIT and CMD0 */
277         host->stat_pending |= 0x1;
278         host->pstate &= 0xfffffffe;
279         return;
280     }
281     
282     if (host->cmd & (1 << 21)) { /* DP */
283         host->fifo_start = 0;
284         host->fifo_len = 0;
285         host->transfer = 1;
286         host->ddir = (host->cmd >> 4) & 1;
287         /* DLA | DATI | (RTA/WTA) */
288         host->pstate |= 0x6 | (host->ddir ? 0x200 : 0x100);
289     } else {
290         host->transfer = 0;
291         host->pstate &= ~0x306; /* RTA | WTA | DLA | DATI */
292     }
293     
294     timeout = 0;
295     mask = 0;
296     rspstatus = 0;
297     
298     request.cmd = cmd;
299     request.arg = host->arg;
300     request.crc = 0; /* FIXME */
301     
302     rsplen = sd_do_command(host->card, &request, response);
303     
304     switch ((host->cmd >> 16) & 3) { /* RSP_TYPE */
305         case sd_nore:
306             rsplen = 0;
307             break;
308         case sd_136_bits:
309             if (rsplen < 16) {
310                 timeout = 1;
311                 break;
312             }
313             rsplen = 16;
314             host->rsp76 = (response[0] << 24) | (response[1] << 16) |
315             (response[2] << 8) | (response[3] << 0);
316             host->rsp54 = (response[4] << 24) | (response[5] << 16) |
317             (response[6] << 8) | (response[7] << 0);
318             host->rsp32 = (response[8] << 24) | (response[9] << 16) |
319             (response[10] << 8) | (response[11] << 0);
320             host->rsp10 = (response[12] << 24) | (response[13] << 16) |
321             (response[14] << 8) | (response[15] << 0);
322             break;
323             case sd_48_bits:
324             case sd_48b_bits:
325             if (rsplen < 4) {
326                 timeout = 1;
327                 break;
328             }
329             rsplen = 4;
330             host->rsp10 = (response[0] << 24) | (response[1] << 16) |
331             (response[2] << 8) | (response[3] << 0);
332             switch (cmd) {
333                 case 41: /* r3 */
334                 case 8:  /* r7 */
335                     break;
336                 case 3:  /* r6 */
337                     mask = 0xe00;
338                     rspstatus = (response[2] << 8) | response[3];
339                     break;
340                 default:
341                     mask = OUT_OF_RANGE | ADDRESS_ERROR | BLOCK_LEN_ERROR |
342                     ERASE_SEQ_ERROR | ERASE_PARAM | WP_VIOLATION |
343                     LOCK_UNLOCK_FAILED | COM_CRC_ERROR | ILLEGAL_COMMAND |
344                     CARD_ECC_FAILED | CC_ERROR | SD_ERROR |
345                     CID_CSD_OVERWRITE | WP_ERASE_SKIP;
346                     rspstatus = (response[0] << 24) | (response[1] << 16) |
347                     (response[2] << 8) | (response[3] << 0);
348                     break;
349             }
350             default:
351             break;
352     }
353     
354     if (cmd == 12 || cmd == 52) { /* stop transfer commands */
355         /*host->fifo_start = 0;*/
356         /*host->fifo_len = 0;*/
357         host->transfer = 0;
358         host->pstate &= ~0x0f06;     /* BRE | BWE | RTA | WTA | DLA | DATI */
359         host->stat_pending &= ~0x30; /* BRR | BWR */
360         host->stat &= ~0x30;         /* BRR | BWR */
361         host->stat_pending |= 0x2;   /* TC */
362         qemu_irq_lower(host->dma[0]);
363         qemu_irq_lower(host->dma[1]);
364     }
365     
366     if (rspstatus & mask & host->csre) {
367         host->stat_pending |= 1 << 28;    /* CERR */
368         host->pstate &= ~0x306;           /* RTA | WTA | DLA | DATI */
369         host->transfer = 0;
370     } else {
371         host->stat &= ~(1 << 28);         /* CERR */
372         host->stat_pending &= ~(1 << 28); /* CERR */
373     }
374     host->stat_pending |= timeout ? (1 << 16) : 0x1; /* CTO : CC */
375 }
376
377 static void omap3_mmc_reset(struct omap3_mmc_s *s)
378 {
379     s->sysconfig = 0x00000015;
380     s->con       = 0x00000500;
381     s->pstate    = 0x00040000;
382     s->capa      = 0x00e10080;
383     s->rev       = 0x26000000;
384
385     s->fifo_start = 0;
386     s->fifo_len   = 0;
387     s->stop       = 0;
388 }
389
390 static uint32_t omap3_mmc_read(void *opaque, target_phys_addr_t addr)
391 {
392     struct omap3_mmc_s *s = (struct omap3_mmc_s *) opaque;
393     uint32_t i ;
394
395     switch (addr) {
396         case 0x10:
397             TRACE2("SYSCONFIG = %08x", s->sysconfig);
398             return s->sysconfig;
399         case 0x14:
400             TRACE2("SYSSTATUS = %08x", s->sysstatus | 0x1);
401             return s->sysstatus | 0x1; /*reset completed */
402         case 0x24:
403             TRACE2("CSRE = %08x", s->csre);
404             return s->csre;
405         case 0x28:
406             TRACE2("SYSTEST = %08x", s->systest);
407             return s->systest;
408         case 0x2c: /* MMCHS_CON */
409             TRACE2("CON = %08x", s->con);
410             return s->con;
411         case 0x30:
412             TRACE2("PWCNT = %08x", s->pwcnt);
413             return s->pwcnt;
414         case 0x104: /* MMCHS_BLK */
415             TRACE2("BLK = %08x", s->blk);
416             return s->blk;
417         case 0x108: /* MMCHS_ARG */
418             TRACE2("ARG = %08x", s->arg);
419             return s->arg;
420         case 0x10c:
421             TRACE2("CMD = %08x", s->cmd);
422             return s->cmd;
423         case 0x110:
424             TRACE2("RSP10 = %08x", s->rsp10);
425             return s->rsp10;
426         case 0x114:
427             TRACE2("RSP32 = %08x", s->rsp32);
428             return s->rsp32;
429         case 0x118:
430             TRACE2("RSP54 = %08x", s->rsp54);
431             return s->rsp54;
432         case 0x11c:
433             TRACE2("RSP76 = %08x", s->rsp76);
434             return s->rsp76;
435         case 0x120:
436             /* in PIO mode, access allowed only when BRE is set */
437             if (!(s->cmd & 1) && !(s->pstate & 0x0800)) {
438                 s->stat_pending |= 1 << 29; /* BADA */
439                 i = 0;
440             } else {
441                 i = s->fifo[s->fifo_start];
442                 s->fifo[s->fifo_start] = 0;
443                 if (s->fifo_len == 0) {
444                     fprintf(stderr, "%s: FIFO underrun\n", __FUNCTION__);
445                     return i;
446                 }
447                 s->fifo_start++;
448                 s->fifo_len--;
449                 s->fifo_start &= 255;
450                 omap3_mmc_transfer(s);
451                 omap3_mmc_fifolevel_update(s);
452             }
453             omap3_mmc_interrupts_update(s);
454             return i;
455         case 0x124: /* MMCHS_PSTATE */
456             TRACE2("PSTATE = %08x", s->pstate);
457             return s->pstate;
458         case 0x128:
459             TRACE2("HCTL = %08x", s->hctl);
460             return s->hctl;
461         case 0x12c: /* MMCHS_SYSCTL */
462             TRACE2("SYSCTL = %08x", s->sysctl);
463             return s->sysctl;
464         case 0x130: /* MMCHS_STAT */
465             s->stat |= s->stat_pending;
466             if (s->stat & 0xffff0000)
467                    s->stat |= 1 << 15;    /* ERRI */
468             else
469                    s->stat &= ~(1 << 15); /* ERRI */
470             s->stat_pending = 0;
471             TRACE2("STAT = %08x", s->stat);
472             return s->stat;
473         case 0x134:
474             TRACE2("IE = %08x", s->ie);
475             return s->ie;
476         case 0x138:
477             TRACE2("ISE = %08x", s->ise);
478             return s->ise;
479         case 0x13c:
480             TRACE2("AC12 = %08x", s->ac12);
481             return s->ac12;
482         case 0x140: /* MMCHS_CAPA */
483             TRACE2("CAPA = %08x", s->capa);
484             return s->capa;
485         case 0x148:
486             TRACE2("CUR_CAPA = %08x", s->cur_capa);
487             return s->cur_capa;
488         case 0x1fc:
489             TRACE2("REV = %08x", s->rev);
490             return s->rev;
491         default:
492             OMAP_BAD_REG(addr);
493             exit(-1);
494             return 0;
495     }
496 }
497
498 static void omap3_mmc_write(void *opaque, target_phys_addr_t addr,
499                             uint32_t value)
500 {
501     struct omap3_mmc_s *s = (struct omap3_mmc_s *) opaque;
502     
503     switch (addr) {
504         case 0x014:
505         case 0x110:
506         case 0x114:
507         case 0x118:
508         case 0x11c:
509         case 0x124:
510         case 0x13c:
511         case 0x1fc:
512             OMAP_RO_REG(addr);
513             break;
514         case 0x010:
515             TRACE2("SYSCONFIG = %08x", value);
516             if (value & 2)
517                 omap3_mmc_reset(s);
518             s->sysconfig = value & 0x31d;
519             break;
520         case 0x024:
521             TRACE2("CSRE = %08x", value);
522             s->csre = value;
523             break;
524         case 0x028:
525             TRACE2("SYSTEST = %08x", value);
526             s->systest = value;
527             break;
528         case 0x02c: /* MMCHS_CON */
529             TRACE2("CON = %08x", value);
530             if (value & 0x10)   /* MODE */
531                 fprintf(stderr, "%s: SYSTEST mode is not supported\n",
532                         __FUNCTION__);
533             if (value & 0x20)   /* DW8 */
534                 fprintf(stderr, "%s: 8-bit data width is not supported\n",
535                         __FUNCTION__);
536             if (value & 0x1000) /* CEATA */
537                 fprintf(stderr, "%s: CE-ATA control mode not supported\n",
538                         __FUNCTION__);
539             s->con = value & 0x1ffff;
540             break;
541         case 0x030:
542             TRACE2("PWCNT = %08x", value);
543             s->pwcnt = value;
544             break;
545         case 0x104: /* MMCHS_BLK */
546             TRACE2("BLK = %08x", value);
547             s->blk = value & 0xffff07ff;
548             s->blen_counter = value & 0x7ff;
549             s->nblk_counter = (value >> 16) & 0xffff;
550             break;
551         case 0x108: /* MMCHS_ARG */
552             TRACE2("ARG = %08x", value);
553             s->arg = value;
554             break;
555         case 0x10c: /* MMCHS_CMD */
556             TRACE2("CMD = %08x", value);
557             if (!s->card) {
558                 s->stat_pending |= (1 << 16); /* CTO */
559             } else {
560                 /* TODO: writing to bits 0-15 should have no effect during
561                    an active data transfer */
562                 if (!s->stop
563                     && (((value >> 24) & 0x3f) == 12
564                         || ((value >> 24) & 0x3f) == 52)) {
565                     s->stop = value & 0x3ffb0037;
566                 } else {
567                     s->cmd = value & 0x3ffb0037;
568                     omap3_mmc_command(s);
569                 }
570                 omap3_mmc_transfer(s);
571                 omap3_mmc_fifolevel_update(s);
572             }
573             omap3_mmc_interrupts_update(s);
574             break;
575         case 0x120:
576             /* in PIO mode, access allowed only when BWE is set */
577             if (!(s->cmd & 1) && !(s->pstate & 0x0400)) {
578                 s->stat_pending |= 1 << 29; /* BADA */
579             } else {
580                 if (s->fifo_len == 256) {
581                     fprintf(stderr, "%s: FIFO overrun\n", __FUNCTION__);
582                     break;
583                 }
584                 s->fifo[(s->fifo_start + s->fifo_len) & 255] = value;
585                 s->fifo_len++;
586                 omap3_mmc_transfer(s);
587                 omap3_mmc_fifolevel_update(s);
588             }
589             omap3_mmc_interrupts_update(s);
590             break;
591         case 0x128: /* MMCHS_HCTL */
592             TRACE2("HCTL = %08x", value);
593             s->hctl = value & 0xf0f0f02;
594             if (s->hctl & (1 << 16)) /* SBGR */
595                 fprintf(stderr, "%s: Stop at block gap feature not implemented!\n", __FUNCTION__);
596             break;
597         case 0x12c: /* MMCHS_SYSCTL */
598             TRACE2("SYSCTL = %08x", value);
599             if (value & 0x04000000) { /* SRD */
600                 s->data    = 0;
601                 s->pstate &= ~0x00000f06; /* BRE, BWE, RTA, WTA, DLA, DATI */
602                 s->hctl   &= ~0x00030000; /* SGBR, CR */
603                 s->stat   &= ~0x00000034; /* BRR, BWR, BGE */
604                 s->stat_pending &= ~0x00000034;
605                 s->fifo_start = 0;
606                 s->fifo_len = 0;
607             }
608             if (value & 0x02000000) { /* SRC */
609                 s->pstate &= ~0x00000001; /* CMDI */
610             }
611             if (value & 0x01000000) { /* SRA */
612                 uint32_t capa = s->capa;
613                 uint32_t cur_capa = s->cur_capa;
614                 omap3_mmc_reset(s);
615                 s->capa = capa;
616                 s->cur_capa = cur_capa;
617             }
618             value = (value & ~2) | ((value & 1) << 1); /* copy ICE directly to ICS */
619             s->sysctl = value & 0x000fffc7;
620             break;
621         case 0x130:
622             TRACE2("STAT = %08x", value);
623             value = value & 0x317f0237;
624             s->stat &= ~value;
625             /* stat_pending is NOT cleared */
626             omap3_mmc_interrupts_update(s);
627             break;
628         case 0x134: /* MMCHS_IE */
629             TRACE2("IE = %08x", value);
630             if (!(s->con & 0x4000)) /* if CON:OBIE is clear, ignore write to OBI_ENABLE */
631                 value = (value & ~0x200) | (s->ie & 0x200);
632             s->ie = value & 0x317f0337;
633             if (!(s->ie & 0x100)) {
634                 s->stat &= ~0x100;
635                 s->stat_pending &= ~0x100;
636             }
637             omap3_mmc_interrupts_update(s);
638             break;
639         case 0x138:
640             TRACE2("ISE = %08x", value);
641             s->ise = value & 0x317f0337;
642             omap3_mmc_interrupts_update(s);
643             break;
644         case 0x140: /* MMCHS_CAPA */
645             TRACE2("CAPA = %08x", value);
646             s->capa &= ~0x07000000;
647             s->capa |= value & 0x07000000;
648             break;
649         case 0x148:
650             TRACE2("CUR_CAPA = %08x", value);
651             s->cur_capa = value & 0xffffff;
652             break;
653         default:
654             OMAP_BAD_REG(addr);
655             exit(-1);
656     }
657 }
658
659 static CPUReadMemoryFunc *omap3_mmc_readfn[] = {
660     omap_badwidth_read32,
661     omap_badwidth_read32,
662     omap3_mmc_read,
663 };
664
665 static CPUWriteMemoryFunc *omap3_mmc_writefn[] = {
666     omap_badwidth_write32,
667     omap_badwidth_write32,
668     omap3_mmc_write,
669 };
670
671 static void omap3_mmc_save_state(QEMUFile *f, void *opaque)
672 {
673     struct omap3_mmc_s *s = (struct omap3_mmc_s *)opaque;
674     int i;
675     
676     qemu_put_be32(f, s->sysconfig);
677     qemu_put_be32(f, s->sysstatus);
678     qemu_put_be32(f, s->csre);
679     qemu_put_be32(f, s->systest);
680     qemu_put_be32(f, s->con);
681     qemu_put_be32(f, s->pwcnt);
682     qemu_put_be32(f, s->blk);
683     qemu_put_be32(f, s->arg);
684     qemu_put_be32(f, s->cmd);
685     qemu_put_be32(f, s->rsp10);
686     qemu_put_be32(f, s->rsp32);
687     qemu_put_be32(f, s->rsp54);
688     qemu_put_be32(f, s->rsp76);
689     qemu_put_be32(f, s->data);
690     qemu_put_be32(f, s->pstate);
691     qemu_put_be32(f, s->hctl);
692     qemu_put_be32(f, s->sysctl);
693     qemu_put_be32(f, s->stat);
694     qemu_put_be32(f, s->ie);
695     qemu_put_be32(f, s->ise);
696     qemu_put_be32(f, s->ac12);
697     qemu_put_be32(f, s->capa);
698     qemu_put_be32(f, s->cur_capa);
699     qemu_put_be32(f, s->rev);
700     qemu_put_be16(f, s->blen_counter);
701     qemu_put_be16(f, s->nblk_counter);
702     for (i = 0; i < sizeof(s->fifo)/sizeof(uint32_t); i++)
703         qemu_put_be32(f, s->fifo[i]);
704     qemu_put_sbe32(f, s->fifo_start);
705     qemu_put_sbe32(f, s->fifo_len);
706     qemu_put_sbe32(f, s->ddir);
707     qemu_put_sbe32(f, s->transfer);
708     qemu_put_sbe32(f, s->stop);
709     qemu_put_be32(f, s->stat_pending);
710 }
711
712 static int omap3_mmc_load_state(QEMUFile *f, void *opaque, int version_id)
713 {
714     struct omap3_mmc_s *s = (struct omap3_mmc_s *)opaque;
715     int i;
716     
717     if (version_id)
718         return -EINVAL;
719     
720     s->sysconfig = qemu_get_be32(f);
721     s->sysstatus = qemu_get_be32(f);
722     s->csre = qemu_get_be32(f);
723     s->systest = qemu_get_be32(f);
724     s->con = qemu_get_be32(f);
725     s->pwcnt = qemu_get_be32(f);
726     s->blk = qemu_get_be32(f);
727     s->arg = qemu_get_be32(f);
728     s->cmd = qemu_get_be32(f);
729     s->rsp10 = qemu_get_be32(f);
730     s->rsp32 = qemu_get_be32(f);
731     s->rsp54 = qemu_get_be32(f);
732     s->rsp76 = qemu_get_be32(f);
733     s->data = qemu_get_be32(f);
734     s->pstate = qemu_get_be32(f);
735     s->hctl = qemu_get_be32(f);
736     s->sysctl = qemu_get_be32(f);
737     s->stat = qemu_get_be32(f);
738     s->ie = qemu_get_be32(f);
739     s->ise = qemu_get_be32(f);
740     s->ac12 = qemu_get_be32(f);
741     s->capa = qemu_get_be32(f);
742     s->cur_capa = qemu_get_be32(f);
743     s->rev = qemu_get_be32(f);
744     s->blen_counter = qemu_get_be16(f);
745     s->nblk_counter = qemu_get_be16(f);
746     for (i = 0; i < sizeof(s->fifo)/sizeof(uint32_t); i++)
747         s->fifo[i] = qemu_get_be32(f);
748     s->fifo_start = qemu_get_sbe32(f);
749     s->fifo_len = qemu_get_sbe32(f);
750     s->ddir = qemu_get_sbe32(f);
751     s->transfer = qemu_get_sbe32(f);
752     s->stop = qemu_get_sbe32(f);
753     s->stat_pending = qemu_get_be32(f);
754     
755     omap3_mmc_fifolevel_update(s);
756     omap3_mmc_interrupts_update(s);
757     
758     return 0;
759 }
760
761 struct omap3_mmc_s *omap3_mmc_init(struct omap_target_agent_s *ta,
762                                    qemu_irq irq, qemu_irq dma[],
763                                    omap_clk fclk, omap_clk iclk)
764 {
765     int iomemtype;
766     struct omap3_mmc_s *s = (struct omap3_mmc_s *)
767         qemu_mallocz(sizeof(struct omap3_mmc_s));
768
769     s->irq = irq;
770     s->dma = dma;
771     s->clk = fclk;
772
773     omap3_mmc_reset(s);
774
775     iomemtype = l4_register_io_memory(0, omap3_mmc_readfn,
776                                       omap3_mmc_writefn, s);
777     omap_l4_attach(ta, 0, iomemtype);
778
779     register_savevm("omap3_mmc", (ta->base >> 12) & 0xff, 0,
780                     omap3_mmc_save_state, omap3_mmc_load_state, s);
781     return s;
782 }
783
784 void omap3_mmc_attach(struct omap3_mmc_s *s,
785                       BlockDriverState *bd)
786 {
787     if (s->card) {
788         fprintf(stderr, "%s: SD card already attached!\n", __FUNCTION__);
789         exit(-1);
790     }
791     s->card = sd_init(bd, 0);
792     sd_enable(s->card, 1);
793 }