|
|
1.1 ! root 1: /* ! 2: * PXA270-based Intel Mainstone platforms. ! 3: * FPGA driver ! 4: * ! 5: * Copyright (c) 2007 by Armin Kuster <[email protected]> or ! 6: * <[email protected]> ! 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.