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