Annotation of qemu/hw/omap_gpmc.c, revision 1.1.1.4

1.1       root        1: /*
                      2:  * TI OMAP general purpose memory controller emulation.
                      3:  *
                      4:  * Copyright (C) 2007-2009 Nokia Corporation
                      5:  * Original code written by Andrzej Zaborowski <andrew@openedhand.com>
                      6:  * Enhancements for OMAP3 and NAND support written by Juha Riihimäki
                      7:  *
                      8:  * This program is free software; you can redistribute it and/or
                      9:  * modify it under the terms of the GNU General Public License as
                     10:  * published by the Free Software Foundation; either version 2 or
                     11:  * (at your option) any later version of the License.
                     12:  *
                     13:  * This program is distributed in the hope that it will be useful,
                     14:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
                     15:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     16:  * GNU General Public License for more details.
                     17:  *
                     18:  * You should have received a copy of the GNU General Public License along
                     19:  * with this program; if not, see <http://www.gnu.org/licenses/>.
                     20:  */
                     21: #include "hw.h"
                     22: #include "flash.h"
                     23: #include "omap.h"
1.1.1.3   root       24: #include "memory.h"
                     25: #include "exec-memory.h"
1.1       root       26: 
                     27: /* General-Purpose Memory Controller */
                     28: struct omap_gpmc_s {
                     29:     qemu_irq irq;
1.1.1.3   root       30:     qemu_irq drq;
                     31:     MemoryRegion iomem;
                     32:     int accept_256;
1.1       root       33: 
1.1.1.3   root       34:     uint8_t revision;
1.1       root       35:     uint8_t sysconfig;
                     36:     uint16_t irqst;
                     37:     uint16_t irqen;
1.1.1.3   root       38:     uint16_t lastirq;
1.1       root       39:     uint16_t timeout;
                     40:     uint16_t config;
                     41:     struct omap_gpmc_cs_file_s {
                     42:         uint32_t config[7];
1.1.1.3   root       43:         MemoryRegion *iomem;
                     44:         MemoryRegion container;
                     45:         MemoryRegion nandiomem;
                     46:         DeviceState *dev;
1.1       root       47:     } cs_file[8];
                     48:     int ecc_cs;
                     49:     int ecc_ptr;
                     50:     uint32_t ecc_cfg;
                     51:     ECCState ecc[9];
1.1.1.3   root       52:     struct prefetch {
                     53:         uint32_t config1; /* GPMC_PREFETCH_CONFIG1 */
                     54:         uint32_t transfercount; /* GPMC_PREFETCH_CONFIG2:TRANSFERCOUNT */
                     55:         int startengine; /* GPMC_PREFETCH_CONTROL:STARTENGINE */
                     56:         int fifopointer; /* GPMC_PREFETCH_STATUS:FIFOPOINTER */
                     57:         int count; /* GPMC_PREFETCH_STATUS:COUNTVALUE */
                     58:         MemoryRegion iomem;
                     59:         uint8_t fifo[64];
                     60:     } prefetch;
1.1       root       61: };
                     62: 
1.1.1.3   root       63: #define OMAP_GPMC_8BIT 0
                     64: #define OMAP_GPMC_16BIT 1
                     65: #define OMAP_GPMC_NOR 0
                     66: #define OMAP_GPMC_NAND 2
                     67: 
                     68: static int omap_gpmc_devtype(struct omap_gpmc_cs_file_s *f)
                     69: {
                     70:     return (f->config[0] >> 10) & 3;
                     71: }
                     72: 
                     73: static int omap_gpmc_devsize(struct omap_gpmc_cs_file_s *f)
                     74: {
                     75:     /* devsize field is really 2 bits but we ignore the high
                     76:      * bit to ensure consistent behaviour if the guest sets
                     77:      * it (values 2 and 3 are reserved in the TRM)
                     78:      */
                     79:     return (f->config[0] >> 12) & 1;
                     80: }
                     81: 
                     82: /* Extract the chip-select value from the prefetch config1 register */
                     83: static int prefetch_cs(uint32_t config1)
                     84: {
                     85:     return (config1 >> 24) & 7;
                     86: }
                     87: 
                     88: static int prefetch_threshold(uint32_t config1)
                     89: {
                     90:     return (config1 >> 8) & 0x7f;
                     91: }
                     92: 
1.1       root       93: static void omap_gpmc_int_update(struct omap_gpmc_s *s)
                     94: {
1.1.1.3   root       95:     /* The TRM is a bit unclear, but it seems to say that
                     96:      * the TERMINALCOUNTSTATUS bit is set only on the
                     97:      * transition when the prefetch engine goes from
                     98:      * active to inactive, whereas the FIFOEVENTSTATUS
                     99:      * bit is held high as long as the fifo has at
                    100:      * least THRESHOLD bytes available.
                    101:      * So we do the latter here, but TERMINALCOUNTSTATUS
                    102:      * is set elsewhere.
                    103:      */
                    104:     if (s->prefetch.fifopointer >= prefetch_threshold(s->prefetch.config1)) {
                    105:         s->irqst |= 1;
                    106:     }
                    107:     if ((s->irqen & s->irqst) != s->lastirq) {
                    108:         s->lastirq = s->irqen & s->irqst;
                    109:         qemu_set_irq(s->irq, s->lastirq);
                    110:     }
1.1       root      111: }
                    112: 
1.1.1.3   root      113: static void omap_gpmc_dma_update(struct omap_gpmc_s *s, int value)
1.1       root      114: {
1.1.1.3   root      115:     if (s->prefetch.config1 & 4) {
                    116:         qemu_set_irq(s->drq, value);
                    117:     }
                    118: }
                    119: 
                    120: /* Access functions for when a NAND-like device is mapped into memory:
                    121:  * all addresses in the region behave like accesses to the relevant
                    122:  * GPMC_NAND_DATA_i register (which is actually implemented to call these)
                    123:  */
                    124: static uint64_t omap_nand_read(void *opaque, target_phys_addr_t addr,
                    125:                                unsigned size)
                    126: {
                    127:     struct omap_gpmc_cs_file_s *f = (struct omap_gpmc_cs_file_s *)opaque;
                    128:     uint64_t v;
                    129:     nand_setpins(f->dev, 0, 0, 0, 1, 0);
                    130:     switch (omap_gpmc_devsize(f)) {
                    131:     case OMAP_GPMC_8BIT:
                    132:         v = nand_getio(f->dev);
                    133:         if (size == 1) {
                    134:             return v;
                    135:         }
                    136:         v |= (nand_getio(f->dev) << 8);
                    137:         if (size == 2) {
                    138:             return v;
                    139:         }
                    140:         v |= (nand_getio(f->dev) << 16);
                    141:         v |= (nand_getio(f->dev) << 24);
                    142:         return v;
                    143:     case OMAP_GPMC_16BIT:
                    144:         v = nand_getio(f->dev);
                    145:         if (size == 1) {
                    146:             /* 8 bit read from 16 bit device : probably a guest bug */
                    147:             return v & 0xff;
                    148:         }
                    149:         if (size == 2) {
                    150:             return v;
                    151:         }
                    152:         v |= (nand_getio(f->dev) << 16);
                    153:         return v;
                    154:     default:
                    155:         abort();
                    156:     }
                    157: }
                    158: 
                    159: static void omap_nand_setio(DeviceState *dev, uint64_t value,
                    160:                             int nandsize, int size)
                    161: {
                    162:     /* Write the specified value to the NAND device, respecting
                    163:      * both size of the NAND device and size of the write access.
                    164:      */
                    165:     switch (nandsize) {
                    166:     case OMAP_GPMC_8BIT:
                    167:         switch (size) {
                    168:         case 1:
                    169:             nand_setio(dev, value & 0xff);
                    170:             break;
                    171:         case 2:
                    172:             nand_setio(dev, value & 0xff);
                    173:             nand_setio(dev, (value >> 8) & 0xff);
                    174:             break;
                    175:         case 4:
                    176:         default:
                    177:             nand_setio(dev, value & 0xff);
                    178:             nand_setio(dev, (value >> 8) & 0xff);
                    179:             nand_setio(dev, (value >> 16) & 0xff);
                    180:             nand_setio(dev, (value >> 24) & 0xff);
                    181:             break;
                    182:         }
                    183:         break;
                    184:     case OMAP_GPMC_16BIT:
                    185:         switch (size) {
                    186:         case 1:
                    187:             /* writing to a 16bit device with 8bit access is probably a guest
                    188:              * bug; pass the value through anyway.
                    189:              */
                    190:         case 2:
                    191:             nand_setio(dev, value & 0xffff);
                    192:             break;
                    193:         case 4:
                    194:         default:
                    195:             nand_setio(dev, value & 0xffff);
                    196:             nand_setio(dev, (value >> 16) & 0xffff);
                    197:             break;
                    198:         }
                    199:         break;
                    200:     }
                    201: }
                    202: 
                    203: static void omap_nand_write(void *opaque, target_phys_addr_t addr,
                    204:                             uint64_t value, unsigned size)
                    205: {
                    206:     struct omap_gpmc_cs_file_s *f = (struct omap_gpmc_cs_file_s *)opaque;
                    207:     nand_setpins(f->dev, 0, 0, 0, 1, 0);
                    208:     omap_nand_setio(f->dev, value, omap_gpmc_devsize(f), size);
                    209: }
                    210: 
                    211: static const MemoryRegionOps omap_nand_ops = {
                    212:     .read = omap_nand_read,
                    213:     .write = omap_nand_write,
                    214:     .endianness = DEVICE_NATIVE_ENDIAN,
                    215: };
                    216: 
                    217: static void fill_prefetch_fifo(struct omap_gpmc_s *s)
                    218: {
                    219:     /* Fill the prefetch FIFO by reading data from NAND.
                    220:      * We do this synchronously, unlike the hardware which
                    221:      * will do this asynchronously. We refill when the
                    222:      * FIFO has THRESHOLD bytes free, and we always refill
                    223:      * as much data as possible starting at the top end
                    224:      * of the FIFO.
                    225:      * (We have to refill at THRESHOLD rather than waiting
                    226:      * for the FIFO to empty to allow for the case where
                    227:      * the FIFO size isn't an exact multiple of THRESHOLD
                    228:      * and we're doing DMA transfers.)
                    229:      * This means we never need to handle wrap-around in
                    230:      * the fifo-reading code, and the next byte of data
                    231:      * to read is always fifo[63 - fifopointer].
                    232:      */
                    233:     int fptr;
                    234:     int cs = prefetch_cs(s->prefetch.config1);
                    235:     int is16bit = (((s->cs_file[cs].config[0] >> 12) & 3) != 0);
                    236:     int bytes;
                    237:     /* Don't believe the bit of the OMAP TRM that says that COUNTVALUE
                    238:      * and TRANSFERCOUNT are in units of 16 bit words for 16 bit NAND.
                    239:      * Instead believe the bit that says it is always a byte count.
                    240:      */
                    241:     bytes = 64 - s->prefetch.fifopointer;
                    242:     if (bytes > s->prefetch.count) {
                    243:         bytes = s->prefetch.count;
                    244:     }
                    245:     s->prefetch.count -= bytes;
                    246:     s->prefetch.fifopointer += bytes;
                    247:     fptr = 64 - s->prefetch.fifopointer;
                    248:     /* Move the existing data in the FIFO so it sits just
                    249:      * before what we're about to read in
                    250:      */
                    251:     while (fptr < (64 - bytes)) {
                    252:         s->prefetch.fifo[fptr] = s->prefetch.fifo[fptr + bytes];
                    253:         fptr++;
                    254:     }
                    255:     while (fptr < 64) {
                    256:         if (is16bit) {
                    257:             uint32_t v = omap_nand_read(&s->cs_file[cs], 0, 2);
                    258:             s->prefetch.fifo[fptr++] = v & 0xff;
                    259:             s->prefetch.fifo[fptr++] = (v >> 8) & 0xff;
                    260:         } else {
                    261:             s->prefetch.fifo[fptr++] = omap_nand_read(&s->cs_file[cs], 0, 1);
                    262:         }
                    263:     }
                    264:     if (s->prefetch.startengine && (s->prefetch.count == 0)) {
                    265:         /* This was the final transfer: raise TERMINALCOUNTSTATUS */
                    266:         s->irqst |= 2;
                    267:         s->prefetch.startengine = 0;
                    268:     }
                    269:     /* If there are any bytes in the FIFO at this point then
                    270:      * we must raise a DMA request (either this is a final part
                    271:      * transfer, or we filled the FIFO in which case we certainly
                    272:      * have THRESHOLD bytes available)
                    273:      */
                    274:     if (s->prefetch.fifopointer != 0) {
                    275:         omap_gpmc_dma_update(s, 1);
                    276:     }
                    277:     omap_gpmc_int_update(s);
                    278: }
                    279: 
                    280: /* Access functions for a NAND-like device when the prefetch/postwrite
                    281:  * engine is enabled -- all addresses in the region behave alike:
                    282:  * data is read or written to the FIFO.
                    283:  */
                    284: static uint64_t omap_gpmc_prefetch_read(void *opaque, target_phys_addr_t addr,
                    285:                                         unsigned size)
                    286: {
                    287:     struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
                    288:     uint32_t data;
                    289:     if (s->prefetch.config1 & 1) {
                    290:         /* The TRM doesn't define the behaviour if you read from the
                    291:          * FIFO when the prefetch engine is in write mode. We choose
                    292:          * to always return zero.
                    293:          */
                    294:         return 0;
                    295:     }
                    296:     /* Note that trying to read an empty fifo repeats the last byte */
                    297:     if (s->prefetch.fifopointer) {
                    298:         s->prefetch.fifopointer--;
                    299:     }
                    300:     data = s->prefetch.fifo[63 - s->prefetch.fifopointer];
                    301:     if (s->prefetch.fifopointer ==
                    302:         (64 - prefetch_threshold(s->prefetch.config1))) {
                    303:         /* We've drained THRESHOLD bytes now. So deassert the
                    304:          * DMA request, then refill the FIFO (which will probably
                    305:          * assert it again.)
                    306:          */
                    307:         omap_gpmc_dma_update(s, 0);
                    308:         fill_prefetch_fifo(s);
                    309:     }
                    310:     omap_gpmc_int_update(s);
                    311:     return data;
                    312: }
                    313: 
                    314: static void omap_gpmc_prefetch_write(void *opaque, target_phys_addr_t addr,
                    315:                                      uint64_t value, unsigned size)
                    316: {
                    317:     struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
                    318:     int cs = prefetch_cs(s->prefetch.config1);
                    319:     if ((s->prefetch.config1 & 1) == 0) {
                    320:         /* The TRM doesn't define the behaviour of writing to the
                    321:          * FIFO when the prefetch engine is in read mode. We
                    322:          * choose to ignore the write.
                    323:          */
1.1       root      324:         return;
                    325:     }
1.1.1.3   root      326:     if (s->prefetch.count == 0) {
                    327:         /* The TRM doesn't define the behaviour of writing to the
                    328:          * FIFO if the transfer is complete. We choose to ignore.
                    329:          */
                    330:         return;
                    331:     }
                    332:     /* The only reason we do any data buffering in postwrite
                    333:      * mode is if we are talking to a 16 bit NAND device, in
                    334:      * which case we need to buffer the first byte of the
                    335:      * 16 bit word until the other byte arrives.
                    336:      */
                    337:     int is16bit = (((s->cs_file[cs].config[0] >> 12) & 3) != 0);
                    338:     if (is16bit) {
                    339:         /* fifopointer alternates between 64 (waiting for first
                    340:          * byte of word) and 63 (waiting for second byte)
                    341:          */
                    342:         if (s->prefetch.fifopointer == 64) {
                    343:             s->prefetch.fifo[0] = value;
                    344:             s->prefetch.fifopointer--;
                    345:         } else {
                    346:             value = (value << 8) | s->prefetch.fifo[0];
                    347:             omap_nand_write(&s->cs_file[cs], 0, value, 2);
                    348:             s->prefetch.count--;
                    349:             s->prefetch.fifopointer = 64;
                    350:         }
                    351:     } else {
                    352:         /* Just write the byte : fifopointer remains 64 at all times */
                    353:         omap_nand_write(&s->cs_file[cs], 0, value, 1);
                    354:         s->prefetch.count--;
                    355:     }
                    356:     if (s->prefetch.count == 0) {
                    357:         /* Final transfer: raise TERMINALCOUNTSTATUS */
                    358:         s->irqst |= 2;
                    359:         s->prefetch.startengine = 0;
                    360:     }
                    361:     omap_gpmc_int_update(s);
                    362: }
                    363: 
                    364: static const MemoryRegionOps omap_prefetch_ops = {
                    365:     .read = omap_gpmc_prefetch_read,
                    366:     .write = omap_gpmc_prefetch_write,
                    367:     .endianness = DEVICE_NATIVE_ENDIAN,
                    368:     .impl.min_access_size = 1,
                    369:     .impl.max_access_size = 1,
                    370: };
                    371: 
                    372: static MemoryRegion *omap_gpmc_cs_memregion(struct omap_gpmc_s *s, int cs)
                    373: {
                    374:     /* Return the MemoryRegion* to map/unmap for this chipselect */
                    375:     struct omap_gpmc_cs_file_s *f = &s->cs_file[cs];
                    376:     if (omap_gpmc_devtype(f) == OMAP_GPMC_NOR) {
                    377:         return f->iomem;
                    378:     }
                    379:     if ((s->prefetch.config1 & 0x80) &&
                    380:         (prefetch_cs(s->prefetch.config1) == cs)) {
                    381:         /* The prefetch engine is enabled for this CS: map the FIFO */
                    382:         return &s->prefetch.iomem;
                    383:     }
                    384:     return &f->nandiomem;
                    385: }
                    386: 
                    387: static void omap_gpmc_cs_map(struct omap_gpmc_s *s, int cs)
                    388: {
                    389:     struct omap_gpmc_cs_file_s *f = &s->cs_file[cs];
                    390:     uint32_t mask = (f->config[6] >> 8) & 0xf;
                    391:     uint32_t base = f->config[6] & 0x3f;
                    392:     uint32_t size;
1.1       root      393: 
1.1.1.3   root      394:     if (!f->iomem && !f->dev) {
1.1       root      395:         return;
1.1.1.3   root      396:     }
                    397: 
                    398:     if (!(f->config[6] & (1 << 6))) {
                    399:         /* Do nothing unless CSVALID */
                    400:         return;
                    401:     }
1.1       root      402: 
1.1.1.3   root      403:     /* TODO: check for overlapping regions and report access errors */
                    404:     if (mask != 0x8 && mask != 0xc && mask != 0xe && mask != 0xf
                    405:          && !(s->accept_256 && !mask)) {
                    406:         fprintf(stderr, "%s: invalid chip-select mask address (0x%x)\n",
                    407:                  __func__, mask);
                    408:     }
                    409: 
                    410:     base <<= 24;
                    411:     size = (0x0fffffff & ~(mask << 24)) + 1;
1.1       root      412:     /* TODO: rather than setting the size of the mapping (which should be
                    413:      * constant), the mask should cause wrapping of the address space, so
                    414:      * that the same memory becomes accessible at every <i>size</i> bytes
                    415:      * starting from <i>base</i>.  */
1.1.1.3   root      416:     memory_region_init(&f->container, "omap-gpmc-file", size);
                    417:     memory_region_add_subregion(&f->container, 0,
                    418:                                 omap_gpmc_cs_memregion(s, cs));
                    419:     memory_region_add_subregion(get_system_memory(), base,
                    420:                                 &f->container);
1.1       root      421: }
                    422: 
1.1.1.3   root      423: static void omap_gpmc_cs_unmap(struct omap_gpmc_s *s, int cs)
1.1       root      424: {
1.1.1.3   root      425:     struct omap_gpmc_cs_file_s *f = &s->cs_file[cs];
                    426:     if (!(f->config[6] & (1 << 6))) {
                    427:         /* Do nothing unless CSVALID */
                    428:         return;
                    429:     }
                    430:     if (!f->iomem && !f->dev) {
                    431:         return;
1.1       root      432:     }
1.1.1.3   root      433:     memory_region_del_subregion(get_system_memory(), &f->container);
                    434:     memory_region_del_subregion(&f->container, omap_gpmc_cs_memregion(s, cs));
                    435:     memory_region_destroy(&f->container);
1.1       root      436: }
                    437: 
                    438: void omap_gpmc_reset(struct omap_gpmc_s *s)
                    439: {
                    440:     int i;
                    441: 
                    442:     s->sysconfig = 0;
                    443:     s->irqst = 0;
                    444:     s->irqen = 0;
                    445:     omap_gpmc_int_update(s);
1.1.1.4 ! root      446:     for (i = 0; i < 8; i++) {
        !           447:         /* This has to happen before we change any of the config
        !           448:          * used to determine which memory regions are mapped or unmapped.
        !           449:          */
        !           450:         omap_gpmc_cs_unmap(s, i);
        !           451:     }
1.1       root      452:     s->timeout = 0;
                    453:     s->config = 0xa00;
1.1.1.3   root      454:     s->prefetch.config1 = 0x00004000;
                    455:     s->prefetch.transfercount = 0x00000000;
                    456:     s->prefetch.startengine = 0;
                    457:     s->prefetch.fifopointer = 0;
                    458:     s->prefetch.count = 0;
1.1       root      459:     for (i = 0; i < 8; i ++) {
                    460:         s->cs_file[i].config[1] = 0x101001;
                    461:         s->cs_file[i].config[2] = 0x020201;
                    462:         s->cs_file[i].config[3] = 0x10031003;
                    463:         s->cs_file[i].config[4] = 0x10f1111;
                    464:         s->cs_file[i].config[5] = 0;
                    465:         s->cs_file[i].config[6] = 0xf00 | (i ? 0 : 1 << 6);
1.1.1.3   root      466: 
                    467:         s->cs_file[i].config[6] = 0xf00;
                    468:         /* In theory we could probe attached devices for some CFG1
                    469:          * bits here, but we just retain them across resets as they
                    470:          * were set initially by omap_gpmc_attach().
                    471:          */
                    472:         if (i == 0) {
                    473:             s->cs_file[i].config[0] &= 0x00433e00;
                    474:             s->cs_file[i].config[6] |= 1 << 6; /* CSVALID */
                    475:             omap_gpmc_cs_map(s, i);
                    476:         } else {
                    477:             s->cs_file[i].config[0] &= 0x00403c00;
                    478:         }
1.1       root      479:     }
                    480:     s->ecc_cs = 0;
                    481:     s->ecc_ptr = 0;
                    482:     s->ecc_cfg = 0x3fcff000;
                    483:     for (i = 0; i < 9; i ++)
                    484:         ecc_reset(&s->ecc[i]);
                    485: }
                    486: 
1.1.1.3   root      487: static int gpmc_wordaccess_only(target_phys_addr_t addr)
                    488: {
                    489:     /* Return true if the register offset is to a register that
                    490:      * only permits word width accesses.
                    491:      * Non-word accesses are only OK for GPMC_NAND_DATA/ADDRESS/COMMAND
                    492:      * for any chipselect.
                    493:      */
                    494:     if (addr >= 0x60 && addr <= 0x1d4) {
                    495:         int cs = (addr - 0x60) / 0x30;
                    496:         addr -= cs * 0x30;
                    497:         if (addr >= 0x7c && addr < 0x88) {
                    498:             /* GPMC_NAND_COMMAND, GPMC_NAND_ADDRESS, GPMC_NAND_DATA */
                    499:             return 0;
                    500:         }
                    501:     }
                    502:     return 1;
                    503: }
                    504: 
                    505: static uint64_t omap_gpmc_read(void *opaque, target_phys_addr_t addr,
                    506:                                unsigned size)
1.1       root      507: {
                    508:     struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
                    509:     int cs;
                    510:     struct omap_gpmc_cs_file_s *f;
                    511: 
1.1.1.3   root      512:     if (size != 4 && gpmc_wordaccess_only(addr)) {
                    513:         return omap_badwidth_read32(opaque, addr);
                    514:     }
                    515: 
1.1       root      516:     switch (addr) {
                    517:     case 0x000:        /* GPMC_REVISION */
1.1.1.3   root      518:         return s->revision;
1.1       root      519: 
                    520:     case 0x010:        /* GPMC_SYSCONFIG */
                    521:         return s->sysconfig;
                    522: 
                    523:     case 0x014:        /* GPMC_SYSSTATUS */
                    524:         return 1;                                              /* RESETDONE */
                    525: 
                    526:     case 0x018:        /* GPMC_IRQSTATUS */
                    527:         return s->irqst;
                    528: 
                    529:     case 0x01c:        /* GPMC_IRQENABLE */
                    530:         return s->irqen;
                    531: 
                    532:     case 0x040:        /* GPMC_TIMEOUT_CONTROL */
                    533:         return s->timeout;
                    534: 
                    535:     case 0x044:        /* GPMC_ERR_ADDRESS */
                    536:     case 0x048:        /* GPMC_ERR_TYPE */
                    537:         return 0;
                    538: 
                    539:     case 0x050:        /* GPMC_CONFIG */
                    540:         return s->config;
                    541: 
                    542:     case 0x054:        /* GPMC_STATUS */
                    543:         return 0x001;
                    544: 
                    545:     case 0x060 ... 0x1d4:
                    546:         cs = (addr - 0x060) / 0x30;
                    547:         addr -= cs * 0x30;
                    548:         f = s->cs_file + cs;
                    549:         switch (addr) {
1.1.1.3   root      550:         case 0x60:      /* GPMC_CONFIG1 */
                    551:             return f->config[0];
                    552:         case 0x64:      /* GPMC_CONFIG2 */
                    553:             return f->config[1];
                    554:         case 0x68:      /* GPMC_CONFIG3 */
                    555:             return f->config[2];
                    556:         case 0x6c:      /* GPMC_CONFIG4 */
                    557:             return f->config[3];
                    558:         case 0x70:      /* GPMC_CONFIG5 */
                    559:             return f->config[4];
                    560:         case 0x74:      /* GPMC_CONFIG6 */
                    561:             return f->config[5];
                    562:         case 0x78:      /* GPMC_CONFIG7 */
                    563:             return f->config[6];
                    564:         case 0x84 ... 0x87: /* GPMC_NAND_DATA */
                    565:             if (omap_gpmc_devtype(f) == OMAP_GPMC_NAND) {
                    566:                 return omap_nand_read(f, 0, size);
                    567:             }
                    568:             return 0;
1.1       root      569:         }
                    570:         break;
                    571: 
                    572:     case 0x1e0:        /* GPMC_PREFETCH_CONFIG1 */
1.1.1.3   root      573:         return s->prefetch.config1;
1.1       root      574:     case 0x1e4:        /* GPMC_PREFETCH_CONFIG2 */
1.1.1.3   root      575:         return s->prefetch.transfercount;
1.1       root      576:     case 0x1ec:        /* GPMC_PREFETCH_CONTROL */
1.1.1.3   root      577:         return s->prefetch.startengine;
1.1       root      578:     case 0x1f0:        /* GPMC_PREFETCH_STATUS */
1.1.1.3   root      579:         /* NB: The OMAP3 TRM is inconsistent about whether the GPMC
                    580:          * FIFOTHRESHOLDSTATUS bit should be set when
                    581:          * FIFOPOINTER > FIFOTHRESHOLD or when it is >= FIFOTHRESHOLD.
                    582:          * Apparently the underlying functional spec from which the TRM was
                    583:          * created states that the behaviour is ">=", and this also
                    584:          * makes more conceptual sense.
                    585:          */
                    586:         return (s->prefetch.fifopointer << 24) |
                    587:                 ((s->prefetch.fifopointer >=
                    588:                   ((s->prefetch.config1 >> 8) & 0x7f) ? 1 : 0) << 16) |
                    589:                 s->prefetch.count;
1.1       root      590: 
                    591:     case 0x1f4:        /* GPMC_ECC_CONFIG */
                    592:         return s->ecc_cs;
                    593:     case 0x1f8:        /* GPMC_ECC_CONTROL */
                    594:         return s->ecc_ptr;
                    595:     case 0x1fc:        /* GPMC_ECC_SIZE_CONFIG */
                    596:         return s->ecc_cfg;
                    597:     case 0x200 ... 0x220:      /* GPMC_ECC_RESULT */
                    598:         cs = (addr & 0x1f) >> 2;
                    599:         /* TODO: check correctness */
                    600:         return
                    601:                 ((s->ecc[cs].cp    &  0x07) <<  0) |
                    602:                 ((s->ecc[cs].cp    &  0x38) << 13) |
                    603:                 ((s->ecc[cs].lp[0] & 0x1ff) <<  3) |
                    604:                 ((s->ecc[cs].lp[1] & 0x1ff) << 19);
                    605: 
                    606:     case 0x230:        /* GPMC_TESTMODE_CTRL */
                    607:         return 0;
                    608:     case 0x234:        /* GPMC_PSA_LSB */
                    609:     case 0x238:        /* GPMC_PSA_MSB */
                    610:         return 0x00000000;
                    611:     }
                    612: 
                    613:     OMAP_BAD_REG(addr);
                    614:     return 0;
                    615: }
                    616: 
                    617: static void omap_gpmc_write(void *opaque, target_phys_addr_t addr,
1.1.1.3   root      618:                             uint64_t value, unsigned size)
1.1       root      619: {
                    620:     struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
                    621:     int cs;
                    622:     struct omap_gpmc_cs_file_s *f;
                    623: 
1.1.1.3   root      624:     if (size != 4 && gpmc_wordaccess_only(addr)) {
                    625:         return omap_badwidth_write32(opaque, addr, value);
                    626:     }
                    627: 
1.1       root      628:     switch (addr) {
                    629:     case 0x000:        /* GPMC_REVISION */
                    630:     case 0x014:        /* GPMC_SYSSTATUS */
                    631:     case 0x054:        /* GPMC_STATUS */
                    632:     case 0x1f0:        /* GPMC_PREFETCH_STATUS */
                    633:     case 0x200 ... 0x220:      /* GPMC_ECC_RESULT */
                    634:     case 0x234:        /* GPMC_PSA_LSB */
                    635:     case 0x238:        /* GPMC_PSA_MSB */
                    636:         OMAP_RO_REG(addr);
                    637:         break;
                    638: 
                    639:     case 0x010:        /* GPMC_SYSCONFIG */
                    640:         if ((value >> 3) == 0x3)
1.1.1.3   root      641:             fprintf(stderr, "%s: bad SDRAM idle mode %"PRIi64"\n",
1.1       root      642:                             __FUNCTION__, value >> 3);
                    643:         if (value & 2)
                    644:             omap_gpmc_reset(s);
                    645:         s->sysconfig = value & 0x19;
                    646:         break;
                    647: 
                    648:     case 0x018:        /* GPMC_IRQSTATUS */
1.1.1.3   root      649:         s->irqst &= ~value;
1.1       root      650:         omap_gpmc_int_update(s);
                    651:         break;
                    652: 
                    653:     case 0x01c:        /* GPMC_IRQENABLE */
                    654:         s->irqen = value & 0xf03;
                    655:         omap_gpmc_int_update(s);
                    656:         break;
                    657: 
                    658:     case 0x040:        /* GPMC_TIMEOUT_CONTROL */
                    659:         s->timeout = value & 0x1ff1;
                    660:         break;
                    661: 
                    662:     case 0x044:        /* GPMC_ERR_ADDRESS */
                    663:     case 0x048:        /* GPMC_ERR_TYPE */
                    664:         break;
                    665: 
                    666:     case 0x050:        /* GPMC_CONFIG */
                    667:         s->config = value & 0xf13;
                    668:         break;
                    669: 
                    670:     case 0x060 ... 0x1d4:
                    671:         cs = (addr - 0x060) / 0x30;
                    672:         addr -= cs * 0x30;
                    673:         f = s->cs_file + cs;
                    674:         switch (addr) {
1.1.1.3   root      675:         case 0x60:      /* GPMC_CONFIG1 */
                    676:             f->config[0] = value & 0xffef3e13;
                    677:             break;
                    678:         case 0x64:      /* GPMC_CONFIG2 */
                    679:             f->config[1] = value & 0x001f1f8f;
                    680:             break;
                    681:         case 0x68:      /* GPMC_CONFIG3 */
                    682:             f->config[2] = value & 0x001f1f8f;
                    683:             break;
                    684:         case 0x6c:      /* GPMC_CONFIG4 */
                    685:             f->config[3] = value & 0x1f8f1f8f;
                    686:             break;
                    687:         case 0x70:      /* GPMC_CONFIG5 */
                    688:             f->config[4] = value & 0x0f1f1f1f;
                    689:             break;
                    690:         case 0x74:      /* GPMC_CONFIG6 */
                    691:             f->config[5] = value & 0x00000fcf;
                    692:             break;
                    693:         case 0x78:      /* GPMC_CONFIG7 */
                    694:             if ((f->config[6] ^ value) & 0xf7f) {
                    695:                 omap_gpmc_cs_unmap(s, cs);
1.1       root      696:                 f->config[6] = value & 0x00000f7f;
1.1.1.3   root      697:                 omap_gpmc_cs_map(s, cs);
                    698:             }
                    699:             break;
                    700:         case 0x7c ... 0x7f: /* GPMC_NAND_COMMAND */
                    701:             if (omap_gpmc_devtype(f) == OMAP_GPMC_NAND) {
                    702:                 nand_setpins(f->dev, 1, 0, 0, 1, 0); /* CLE */
                    703:                 omap_nand_setio(f->dev, value, omap_gpmc_devsize(f), size);
                    704:             }
                    705:             break;
                    706:         case 0x80 ... 0x83: /* GPMC_NAND_ADDRESS */
                    707:             if (omap_gpmc_devtype(f) == OMAP_GPMC_NAND) {
                    708:                 nand_setpins(f->dev, 0, 1, 0, 1, 0); /* ALE */
                    709:                 omap_nand_setio(f->dev, value, omap_gpmc_devsize(f), size);
                    710:             }
                    711:             break;
                    712:         case 0x84 ... 0x87: /* GPMC_NAND_DATA */
                    713:             if (omap_gpmc_devtype(f) == OMAP_GPMC_NAND) {
                    714:                 omap_nand_write(f, 0, value, size);
                    715:             }
                    716:             break;
                    717:         default:
                    718:             goto bad_reg;
1.1       root      719:         }
                    720:         break;
                    721: 
                    722:     case 0x1e0:        /* GPMC_PREFETCH_CONFIG1 */
1.1.1.3   root      723:         if (!s->prefetch.startengine) {
1.1.1.4 ! root      724:             uint32_t newconfig1 = value & 0x7f8f7fbf;
1.1.1.3   root      725:             uint32_t changed;
1.1.1.4 ! root      726:             changed = newconfig1 ^ s->prefetch.config1;
1.1.1.3   root      727:             if (changed & (0x80 | 0x7000000)) {
                    728:                 /* Turning the engine on or off, or mapping it somewhere else.
                    729:                  * cs_map() and cs_unmap() check the prefetch config and
                    730:                  * overall CSVALID bits, so it is sufficient to unmap-and-map
1.1.1.4 ! root      731:                  * both the old cs and the new one. Note that we adhere to
        !           732:                  * the "unmap/change config/map" order (and not unmap twice
        !           733:                  * if newcs == oldcs), otherwise we'll try to delete the wrong
        !           734:                  * memory region.
1.1.1.3   root      735:                  */
1.1.1.4 ! root      736:                 int oldcs = prefetch_cs(s->prefetch.config1);
        !           737:                 int newcs = prefetch_cs(newconfig1);
1.1.1.3   root      738:                 omap_gpmc_cs_unmap(s, oldcs);
1.1.1.4 ! root      739:                 if (oldcs != newcs) {
1.1.1.3   root      740:                     omap_gpmc_cs_unmap(s, newcs);
1.1.1.4 ! root      741:                 }
        !           742:                 s->prefetch.config1 = newconfig1;
        !           743:                 omap_gpmc_cs_map(s, oldcs);
        !           744:                 if (oldcs != newcs) {
1.1.1.3   root      745:                     omap_gpmc_cs_map(s, newcs);
                    746:                 }
1.1.1.4 ! root      747:             } else {
        !           748:                 s->prefetch.config1 = newconfig1;
1.1.1.3   root      749:             }
                    750:         }
1.1       root      751:         break;
                    752: 
                    753:     case 0x1e4:        /* GPMC_PREFETCH_CONFIG2 */
1.1.1.3   root      754:         if (!s->prefetch.startengine) {
                    755:             s->prefetch.transfercount = value & 0x3fff;
                    756:         }
1.1       root      757:         break;
                    758: 
                    759:     case 0x1ec:        /* GPMC_PREFETCH_CONTROL */
1.1.1.3   root      760:         if (s->prefetch.startengine != (value & 1)) {
                    761:             s->prefetch.startengine = value & 1;
                    762:             if (s->prefetch.startengine) {
                    763:                 /* Prefetch engine start */
                    764:                 s->prefetch.count = s->prefetch.transfercount;
                    765:                 if (s->prefetch.config1 & 1) {
                    766:                     /* Write */
                    767:                     s->prefetch.fifopointer = 64;
                    768:                 } else {
                    769:                     /* Read */
                    770:                     s->prefetch.fifopointer = 0;
                    771:                     fill_prefetch_fifo(s);
                    772:                 }
                    773:             } else {
                    774:                 /* Prefetch engine forcibly stopped. The TRM
                    775:                  * doesn't define the behaviour if you do this.
                    776:                  * We clear the prefetch count, which means that
                    777:                  * we permit no more writes, and don't read any
                    778:                  * more data from NAND. The CPU can still drain
                    779:                  * the FIFO of unread data.
                    780:                  */
                    781:                 s->prefetch.count = 0;
                    782:             }
                    783:             omap_gpmc_int_update(s);
1.1       root      784:         }
                    785:         break;
                    786: 
                    787:     case 0x1f4:        /* GPMC_ECC_CONFIG */
                    788:         s->ecc_cs = 0x8f;
                    789:         break;
                    790:     case 0x1f8:        /* GPMC_ECC_CONTROL */
                    791:         if (value & (1 << 8))
                    792:             for (cs = 0; cs < 9; cs ++)
                    793:                 ecc_reset(&s->ecc[cs]);
                    794:         s->ecc_ptr = value & 0xf;
                    795:         if (s->ecc_ptr == 0 || s->ecc_ptr > 9) {
                    796:             s->ecc_ptr = 0;
                    797:             s->ecc_cs &= ~1;
                    798:         }
                    799:         break;
                    800:     case 0x1fc:        /* GPMC_ECC_SIZE_CONFIG */
                    801:         s->ecc_cfg = value & 0x3fcff1ff;
                    802:         break;
                    803:     case 0x230:        /* GPMC_TESTMODE_CTRL */
                    804:         if (value & 7)
                    805:             fprintf(stderr, "%s: test mode enable attempt\n", __FUNCTION__);
                    806:         break;
                    807: 
                    808:     default:
                    809:     bad_reg:
                    810:         OMAP_BAD_REG(addr);
                    811:         return;
                    812:     }
                    813: }
                    814: 
1.1.1.3   root      815: static const MemoryRegionOps omap_gpmc_ops = {
                    816:     .read = omap_gpmc_read,
                    817:     .write = omap_gpmc_write,
                    818:     .endianness = DEVICE_NATIVE_ENDIAN,
1.1       root      819: };
                    820: 
1.1.1.3   root      821: struct omap_gpmc_s *omap_gpmc_init(struct omap_mpu_state_s *mpu,
                    822:                                    target_phys_addr_t base,
                    823:                                    qemu_irq irq, qemu_irq drq)
1.1       root      824: {
1.1.1.3   root      825:     int cs;
1.1       root      826:     struct omap_gpmc_s *s = (struct omap_gpmc_s *)
1.1.1.3   root      827:             g_malloc0(sizeof(struct omap_gpmc_s));
1.1       root      828: 
1.1.1.3   root      829:     memory_region_init_io(&s->iomem, &omap_gpmc_ops, s, "omap-gpmc", 0x1000);
                    830:     memory_region_add_subregion(get_system_memory(), base, &s->iomem);
                    831: 
                    832:     s->irq = irq;
                    833:     s->drq = drq;
                    834:     s->accept_256 = cpu_is_omap3630(mpu);
                    835:     s->revision = cpu_class_omap3(mpu) ? 0x50 : 0x20;
                    836:     s->lastirq = 0;
1.1       root      837:     omap_gpmc_reset(s);
                    838: 
1.1.1.3   root      839:     /* We have to register a different IO memory handler for each
                    840:      * chip select region in case a NAND device is mapped there. We
                    841:      * make the region the worst-case size of 256MB and rely on the
                    842:      * container memory region in cs_map to chop it down to the actual
                    843:      * guest-requested size.
                    844:      */
                    845:     for (cs = 0; cs < 8; cs++) {
                    846:         memory_region_init_io(&s->cs_file[cs].nandiomem,
                    847:                               &omap_nand_ops,
                    848:                               &s->cs_file[cs],
                    849:                               "omap-nand",
                    850:                               256 * 1024 * 1024);
                    851:     }
1.1       root      852: 
1.1.1.3   root      853:     memory_region_init_io(&s->prefetch.iomem, &omap_prefetch_ops, s,
                    854:                           "omap-gpmc-prefetch", 256 * 1024 * 1024);
1.1       root      855:     return s;
                    856: }
                    857: 
1.1.1.3   root      858: void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, MemoryRegion *iomem)
1.1       root      859: {
                    860:     struct omap_gpmc_cs_file_s *f;
1.1.1.3   root      861:     assert(iomem);
1.1       root      862: 
                    863:     if (cs < 0 || cs >= 8) {
                    864:         fprintf(stderr, "%s: bad chip-select %i\n", __FUNCTION__, cs);
                    865:         exit(-1);
                    866:     }
                    867:     f = &s->cs_file[cs];
                    868: 
1.1.1.3   root      869:     omap_gpmc_cs_unmap(s, cs);
                    870:     f->config[0] &= ~(0xf << 10);
                    871:     f->iomem = iomem;
                    872:     omap_gpmc_cs_map(s, cs);
                    873: }
                    874: 
                    875: void omap_gpmc_attach_nand(struct omap_gpmc_s *s, int cs, DeviceState *nand)
                    876: {
                    877:     struct omap_gpmc_cs_file_s *f;
                    878:     assert(nand);
                    879: 
                    880:     if (cs < 0 || cs >= 8) {
                    881:         fprintf(stderr, "%s: bad chip-select %i\n", __func__, cs);
                    882:         exit(-1);
                    883:     }
                    884:     f = &s->cs_file[cs];
                    885: 
                    886:     omap_gpmc_cs_unmap(s, cs);
                    887:     f->config[0] &= ~(0xf << 10);
                    888:     f->config[0] |= (OMAP_GPMC_NAND << 10);
                    889:     f->dev = nand;
                    890:     if (nand_getbuswidth(f->dev) == 16) {
                    891:         f->config[0] |= OMAP_GPMC_16BIT << 12;
                    892:     }
                    893:     omap_gpmc_cs_map(s, cs);
1.1       root      894: }

unix.superglobalmegacorp.com