|
|
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"
1.1.1.7 root 11: #include "sysbus.h"
1.1 root 12:
13: /* Mainstone FPGA for extern irqs */
14: #define FPGA_GPIO_PIN 0
15: #define MST_NUM_IRQS 16
16: #define MST_LEDDAT1 0x10
17: #define MST_LEDDAT2 0x14
18: #define MST_LEDCTRL 0x40
19: #define MST_GPSWR 0x60
20: #define MST_MSCWR1 0x80
21: #define MST_MSCWR2 0x84
22: #define MST_MSCWR3 0x88
23: #define MST_MSCRD 0x90
24: #define MST_INTMSKENA 0xc0
25: #define MST_INTSETCLR 0xd0
26: #define MST_PCMCIA0 0xe0
27: #define MST_PCMCIA1 0xe4
28:
1.1.1.7 root 29: #define MST_PCMCIAx_READY (1 << 10)
30: #define MST_PCMCIAx_nCD (1 << 5)
31:
32: #define MST_PCMCIA_CD0_IRQ 9
33: #define MST_PCMCIA_CD1_IRQ 13
34:
1.1 root 35: typedef struct mst_irq_state{
1.1.1.7 root 36: SysBusDevice busdev;
37:
38: qemu_irq parent;
1.1 root 39:
40: uint32_t prev_level;
41: uint32_t leddat1;
42: uint32_t leddat2;
43: uint32_t ledctrl;
44: uint32_t gpswr;
45: uint32_t mscwr1;
46: uint32_t mscwr2;
47: uint32_t mscwr3;
48: uint32_t mscrd;
49: uint32_t intmskena;
50: uint32_t intsetclr;
51: uint32_t pcmcia0;
52: uint32_t pcmcia1;
53: }mst_irq_state;
54:
55: static void
56: mst_fpga_set_irq(void *opaque, int irq, int level)
57: {
58: mst_irq_state *s = (mst_irq_state *)opaque;
1.1.1.7 root 59: uint32_t oldint = s->intsetclr & s->intmskena;
1.1 root 60:
61: if (level)
62: s->prev_level |= 1u << irq;
63: else
64: s->prev_level &= ~(1u << irq);
65:
1.1.1.7 root 66: switch(irq) {
67: case MST_PCMCIA_CD0_IRQ:
68: if (level)
69: s->pcmcia0 &= ~MST_PCMCIAx_nCD;
70: else
71: s->pcmcia0 |= MST_PCMCIAx_nCD;
72: break;
73: case MST_PCMCIA_CD1_IRQ:
74: if (level)
75: s->pcmcia1 &= ~MST_PCMCIAx_nCD;
76: else
77: s->pcmcia1 |= MST_PCMCIAx_nCD;
78: break;
1.1 root 79: }
1.1.1.7 root 80:
81: if ((s->intmskena & (1u << irq)) && level)
82: s->intsetclr |= 1u << irq;
83:
84: if (oldint != (s->intsetclr & s->intmskena))
85: qemu_set_irq(s->parent, s->intsetclr & s->intmskena);
1.1 root 86: }
87:
88:
89: static uint32_t
90: mst_fpga_readb(void *opaque, target_phys_addr_t addr)
91: {
92: mst_irq_state *s = (mst_irq_state *) opaque;
93:
94: switch (addr) {
95: case MST_LEDDAT1:
96: return s->leddat1;
97: case MST_LEDDAT2:
98: return s->leddat2;
99: case MST_LEDCTRL:
100: return s->ledctrl;
101: case MST_GPSWR:
102: return s->gpswr;
103: case MST_MSCWR1:
104: return s->mscwr1;
105: case MST_MSCWR2:
106: return s->mscwr2;
107: case MST_MSCWR3:
108: return s->mscwr3;
109: case MST_MSCRD:
110: return s->mscrd;
111: case MST_INTMSKENA:
112: return s->intmskena;
113: case MST_INTSETCLR:
114: return s->intsetclr;
115: case MST_PCMCIA0:
116: return s->pcmcia0;
117: case MST_PCMCIA1:
118: return s->pcmcia1;
119: default:
120: printf("Mainstone - mst_fpga_readb: Bad register offset "
1.1.1.8 ! root 121: "0x" TARGET_FMT_plx "\n", addr);
1.1 root 122: }
123: return 0;
124: }
125:
126: static void
127: mst_fpga_writeb(void *opaque, target_phys_addr_t addr, uint32_t value)
128: {
129: mst_irq_state *s = (mst_irq_state *) opaque;
130: value &= 0xffffffff;
131:
132: switch (addr) {
133: case MST_LEDDAT1:
134: s->leddat1 = value;
135: break;
136: case MST_LEDDAT2:
137: s->leddat2 = value;
138: break;
139: case MST_LEDCTRL:
140: s->ledctrl = value;
141: break;
142: case MST_GPSWR:
143: s->gpswr = value;
144: break;
145: case MST_MSCWR1:
146: s->mscwr1 = value;
147: break;
148: case MST_MSCWR2:
149: s->mscwr2 = value;
150: break;
151: case MST_MSCWR3:
152: s->mscwr3 = value;
153: break;
154: case MST_MSCRD:
155: s->mscrd = value;
156: break;
1.1.1.7 root 157: case MST_INTMSKENA: /* Mask interrupt */
1.1 root 158: s->intmskena = (value & 0xFEEFF);
1.1.1.7 root 159: qemu_set_irq(s->parent, s->intsetclr & s->intmskena);
1.1 root 160: break;
161: case MST_INTSETCLR: /* clear or set interrupt */
162: s->intsetclr = (value & 0xFEEFF);
1.1.1.7 root 163: qemu_set_irq(s->parent, s->intsetclr & s->intmskena);
1.1 root 164: break;
1.1.1.7 root 165: /* For PCMCIAx allow the to change only power and reset */
1.1 root 166: case MST_PCMCIA0:
1.1.1.7 root 167: s->pcmcia0 = (value & 0x1f) | (s->pcmcia0 & ~0x1f);
1.1 root 168: break;
169: case MST_PCMCIA1:
1.1.1.7 root 170: s->pcmcia1 = (value & 0x1f) | (s->pcmcia1 & ~0x1f);
1.1 root 171: break;
172: default:
173: printf("Mainstone - mst_fpga_writeb: Bad register offset "
1.1.1.8 ! root 174: "0x" TARGET_FMT_plx "\n", addr);
1.1 root 175: }
176: }
177:
1.1.1.4 root 178: static CPUReadMemoryFunc * const mst_fpga_readfn[] = {
1.1 root 179: mst_fpga_readb,
180: mst_fpga_readb,
181: mst_fpga_readb,
182: };
1.1.1.4 root 183: static CPUWriteMemoryFunc * const mst_fpga_writefn[] = {
1.1 root 184: mst_fpga_writeb,
185: mst_fpga_writeb,
186: mst_fpga_writeb,
187: };
188:
189:
1.1.1.7 root 190: static int mst_fpga_post_load(void *opaque, int version_id)
1.1 root 191: {
192: mst_irq_state *s = (mst_irq_state *) opaque;
193:
1.1.1.7 root 194: qemu_set_irq(s->parent, s->intsetclr & s->intmskena);
1.1 root 195: return 0;
196: }
197:
1.1.1.7 root 198: static int mst_fpga_init(SysBusDevice *dev)
1.1 root 199: {
200: mst_irq_state *s;
201: int iomemtype;
202:
1.1.1.7 root 203: s = FROM_SYSBUS(mst_irq_state, dev);
1.1 root 204:
1.1.1.7 root 205: s->pcmcia0 = MST_PCMCIAx_READY | MST_PCMCIAx_nCD;
206: s->pcmcia1 = MST_PCMCIAx_READY | MST_PCMCIAx_nCD;
207:
208: sysbus_init_irq(dev, &s->parent);
1.1 root 209:
210: /* alloc the external 16 irqs */
1.1.1.7 root 211: qdev_init_gpio_in(&dev->qdev, mst_fpga_set_irq, MST_NUM_IRQS);
1.1 root 212:
1.1.1.3 root 213: iomemtype = cpu_register_io_memory(mst_fpga_readfn,
1.1.1.6 root 214: mst_fpga_writefn, s, DEVICE_NATIVE_ENDIAN);
1.1.1.7 root 215: sysbus_init_mmio(dev, 0x00100000, iomemtype);
216: return 0;
217: }
218:
219: static VMStateDescription vmstate_mst_fpga_regs = {
220: .name = "mainstone_fpga",
221: .version_id = 0,
222: .minimum_version_id = 0,
223: .minimum_version_id_old = 0,
224: .post_load = mst_fpga_post_load,
225: .fields = (VMStateField []) {
226: VMSTATE_UINT32(prev_level, mst_irq_state),
227: VMSTATE_UINT32(leddat1, mst_irq_state),
228: VMSTATE_UINT32(leddat2, mst_irq_state),
229: VMSTATE_UINT32(ledctrl, mst_irq_state),
230: VMSTATE_UINT32(gpswr, mst_irq_state),
231: VMSTATE_UINT32(mscwr1, mst_irq_state),
232: VMSTATE_UINT32(mscwr2, mst_irq_state),
233: VMSTATE_UINT32(mscwr3, mst_irq_state),
234: VMSTATE_UINT32(mscrd, mst_irq_state),
235: VMSTATE_UINT32(intmskena, mst_irq_state),
236: VMSTATE_UINT32(intsetclr, mst_irq_state),
237: VMSTATE_UINT32(pcmcia0, mst_irq_state),
238: VMSTATE_UINT32(pcmcia1, mst_irq_state),
239: VMSTATE_END_OF_LIST(),
240: },
241: };
242:
243: static SysBusDeviceInfo mst_fpga_info = {
244: .init = mst_fpga_init,
245: .qdev.name = "mainstone-fpga",
246: .qdev.desc = "Mainstone II FPGA",
247: .qdev.size = sizeof(mst_irq_state),
248: .qdev.vmsd = &vmstate_mst_fpga_regs,
249: };
250:
251: static void mst_fpga_register(void)
252: {
253: sysbus_register_withprop(&mst_fpga_info);
1.1 root 254: }
1.1.1.7 root 255: device_init(mst_fpga_register);
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.