(linenum→info "unix/slp.c:2238")

qemu/0.9.1/hw/mst_fpga.c

    1: /*
    2:  * PXA270-based Intel Mainstone platforms.
    3:  * FPGA driver
    4:  *
    5:  * Copyright (c) 2007 by Armin Kuster <akuster@kama-aina.net> or
    6:  *                                    <akuster@mvista.com>
    7:  *
    8:  * This code is licensed under the GNU GPL v2.
    9:  */
   10: #include "hw.h"
   11: #include "pxa.h"
   12: #include "mainstone.h"
   13: 
   14: /* Mainstone FPGA for extern irqs */
   15: #define FPGA_GPIO_PIN   0
   16: #define MST_NUM_IRQS    16
   17: #define MST_BASE                MST_FPGA_PHYS
   18: #define MST_LEDDAT1             0x10
   19: #define MST_LEDDAT2             0x14
   20: #define MST_LEDCTRL             0x40
   21: #define MST_GPSWR               0x60
   22: #define MST_MSCWR1              0x80
   23: #define MST_MSCWR2              0x84
   24: #define MST_MSCWR3              0x88
   25: #define MST_MSCRD               0x90
   26: #define MST_INTMSKENA   0xc0
   27: #define MST_INTSETCLR   0xd0
   28: #define MST_PCMCIA0             0xe0
   29: #define MST_PCMCIA1             0xe4
   30: 
   31: typedef struct mst_irq_state{
   32:         target_phys_addr_t target_base;
   33:         qemu_irq *parent;
   34:         qemu_irq *pins;
   35: 
   36:         uint32_t prev_level;
   37:         uint32_t leddat1;
   38:         uint32_t leddat2;
   39:         uint32_t ledctrl;
   40:         uint32_t gpswr;
   41:         uint32_t mscwr1;
   42:         uint32_t mscwr2;
   43:         uint32_t mscwr3;
   44:         uint32_t mscrd;
   45:         uint32_t intmskena;
   46:         uint32_t intsetclr;
   47:         uint32_t pcmcia0;
   48:         uint32_t pcmcia1;
   49: }mst_irq_state;
   50: 
   51: static void
   52: mst_fpga_update_gpio(mst_irq_state *s)
   53: {
   54:         uint32_t level, diff;
   55:         int bit;
   56:         level = s->prev_level ^ s->intsetclr;
   57: 
   58:         for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) {
   59:                 bit = ffs(diff) - 1;
   60:                 qemu_set_irq(s->pins[bit], (level >> bit) & 1 );
   61:         }
   62:         s->prev_level = level;
   63: }
   64: 
   65: static void
   66: mst_fpga_set_irq(void *opaque, int irq, int level)
   67: {
   68:         mst_irq_state *s = (mst_irq_state *)opaque;
   69: 
   70:         if (level)
   71:                 s->prev_level |= 1u << irq;
   72:         else
   73:                 s->prev_level &= ~(1u << irq);
   74: 
   75:         if(s->intmskena & (1u << irq)) {
   76:                 s->intsetclr = 1u << irq;
   77:                 qemu_set_irq(s->parent[0], level);
   78:         }
   79: }
   80: 
   81: 
   82: static uint32_t
   83: mst_fpga_readb(void *opaque, target_phys_addr_t addr)
   84: {
   85:         mst_irq_state *s = (mst_irq_state *) opaque;
   86:         addr -= s->target_base;
   87: 
   88:         switch (addr) {
   89:         case MST_LEDDAT1:
   90:                 return s->leddat1;
   91:         case MST_LEDDAT2:
   92:                 return s->leddat2;
   93:         case MST_LEDCTRL:
   94:                 return s->ledctrl;
   95:         case MST_GPSWR:
   96:                 return s->gpswr;
   97:         case MST_MSCWR1:
   98:                 return s->mscwr1;
   99:         case MST_MSCWR2:
  100:                 return s->mscwr2;
  101:         case MST_MSCWR3:
  102:                 return s->mscwr3;
  103:         case MST_MSCRD:
  104:                 return s->mscrd;
  105:         case MST_INTMSKENA:
  106:                 return s->intmskena;
  107:         case MST_INTSETCLR:
  108:                 return s->intsetclr;
  109:         case MST_PCMCIA0:
  110:                 return s->pcmcia0;
  111:         case MST_PCMCIA1:
  112:                 return s->pcmcia1;
  113:         default:
  114:                 printf("Mainstone - mst_fpga_readb: Bad register offset "
  115:                         REG_FMT " \n", addr);
  116:         }
  117:         return 0;
  118: }
  119: 
  120: static void
  121: mst_fpga_writeb(void *opaque, target_phys_addr_t addr, uint32_t value)
  122: {
  123:         mst_irq_state *s = (mst_irq_state *) opaque;
  124:         addr -= s->target_base;
  125:         value &= 0xffffffff;
  126: 
  127:         switch (addr) {
  128:         case MST_LEDDAT1:
  129:                 s->leddat1 = value;
  130:                 break;
  131:         case MST_LEDDAT2:
  132:                 s->leddat2 = value;
  133:                 break;
  134:         case MST_LEDCTRL:
  135:                 s->ledctrl = value;
  136:                 break;
  137:         case MST_GPSWR:
  138:                 s->gpswr = value;
  139:                 break;
  140:         case MST_MSCWR1:
  141:                 s->mscwr1 = value;
  142:                 break;
  143:         case MST_MSCWR2:
  144:                 s->mscwr2 = value;
  145:                 break;
  146:         case MST_MSCWR3:
  147:                 s->mscwr3 = value;
  148:                 break;
  149:         case MST_MSCRD:
  150:                 s->mscrd =  value;
  151:                 break;
  152:         case MST_INTMSKENA:    /* Mask interupt */
  153:                 s->intmskena = (value & 0xFEEFF);
  154:                 mst_fpga_update_gpio(s);
  155:                 break;
  156:         case MST_INTSETCLR:    /* clear or set interrupt */
  157:                 s->intsetclr = (value & 0xFEEFF);
  158:                 break;
  159:         case MST_PCMCIA0:
  160:                 s->pcmcia0 = value;
  161:                 break;
  162:         case MST_PCMCIA1:
  163:                 s->pcmcia1 = value;
  164:                 break;
  165:         default:
  166:                 printf("Mainstone - mst_fpga_writeb: Bad register offset "
  167:                         REG_FMT " \n", addr);
  168:         }
  169: }
  170: 
  171: CPUReadMemoryFunc *mst_fpga_readfn[] = {
  172:         mst_fpga_readb,
  173:         mst_fpga_readb,
  174:         mst_fpga_readb,
  175: };
  176: CPUWriteMemoryFunc *mst_fpga_writefn[] = {
  177:         mst_fpga_writeb,
  178:         mst_fpga_writeb,
  179:         mst_fpga_writeb,
  180: };
  181: 
  182: static void
  183: mst_fpga_save(QEMUFile *f, void *opaque)
  184: {
  185:         struct mst_irq_state *s = (mst_irq_state *) opaque;
  186: 
  187:         qemu_put_be32s(f, &s->prev_level);
  188:         qemu_put_be32s(f, &s->leddat1);
  189:         qemu_put_be32s(f, &s->leddat2);
  190:         qemu_put_be32s(f, &s->ledctrl);
  191:         qemu_put_be32s(f, &s->gpswr);
  192:         qemu_put_be32s(f, &s->mscwr1);
  193:         qemu_put_be32s(f, &s->mscwr2);
  194:         qemu_put_be32s(f, &s->mscwr3);
  195:         qemu_put_be32s(f, &s->mscrd);
  196:         qemu_put_be32s(f, &s->intmskena);
  197:         qemu_put_be32s(f, &s->intsetclr);
  198:         qemu_put_be32s(f, &s->pcmcia0);
  199:         qemu_put_be32s(f, &s->pcmcia1);
  200: }
  201: 
  202: static int
  203: mst_fpga_load(QEMUFile *f, void *opaque, int version_id)
  204: {
  205:         mst_irq_state *s = (mst_irq_state *) opaque;
  206: 
  207:         qemu_get_be32s(f, &s->prev_level);
  208:         qemu_get_be32s(f, &s->leddat1);
  209:         qemu_get_be32s(f, &s->leddat2);
  210:         qemu_get_be32s(f, &s->ledctrl);
  211:         qemu_get_be32s(f, &s->gpswr);
  212:         qemu_get_be32s(f, &s->mscwr1);
  213:         qemu_get_be32s(f, &s->mscwr2);
  214:         qemu_get_be32s(f, &s->mscwr3);
  215:         qemu_get_be32s(f, &s->mscrd);
  216:         qemu_get_be32s(f, &s->intmskena);
  217:         qemu_get_be32s(f, &s->intsetclr);
  218:         qemu_get_be32s(f, &s->pcmcia0);
  219:         qemu_get_be32s(f, &s->pcmcia1);
  220:         return 0;
  221: }
  222: 
  223: qemu_irq *mst_irq_init(struct pxa2xx_state_s *cpu, uint32_t base, int irq)
  224: {
  225:         mst_irq_state *s;
  226:         int iomemtype;
  227:         qemu_irq *qi;
  228: 
  229:         s = (mst_irq_state  *)
  230:                 qemu_mallocz(sizeof(mst_irq_state));
  231: 
  232:         if (!s)
  233:                 return NULL;
  234:         s->target_base = base;
  235:         s->parent = &cpu->pic[irq];
  236: 
  237:         /* alloc the external 16 irqs */
  238:         qi  = qemu_allocate_irqs(mst_fpga_set_irq, s, MST_NUM_IRQS);
  239:         s->pins = qi;
  240: 
  241:         iomemtype = cpu_register_io_memory(0, mst_fpga_readfn,
  242:                 mst_fpga_writefn, s);
  243:         cpu_register_physical_memory(MST_BASE, 0x00100000, iomemtype);
  244:         register_savevm("mainstone_fpga", 0, 0, mst_fpga_save, mst_fpga_load, s);
  245:         return qi;
  246: }
Syntax (Markdown)