Fix build from previous commit
[qemu.git] / hw / mst_fpga.c
blob93c65143db6d2e97fce4b39377894e414a983590
1 /*
2 * PXA270-based Intel Mainstone platforms.
3 * FPGA driver
5 * Copyright (c) 2007 by Armin Kuster <akuster@kama-aina.net> or
6 * <akuster@mvista.com>
8 * This code is licensed under the GNU GPL v2.
9 */
10 #include "hw.h"
11 #include "mainstone.h"
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
29 typedef struct mst_irq_state{
30 qemu_irq parent;
31 qemu_irq *pins;
33 uint32_t prev_level;
34 uint32_t leddat1;
35 uint32_t leddat2;
36 uint32_t ledctrl;
37 uint32_t gpswr;
38 uint32_t mscwr1;
39 uint32_t mscwr2;
40 uint32_t mscwr3;
41 uint32_t mscrd;
42 uint32_t intmskena;
43 uint32_t intsetclr;
44 uint32_t pcmcia0;
45 uint32_t pcmcia1;
46 }mst_irq_state;
48 static void
49 mst_fpga_update_gpio(mst_irq_state *s)
51 uint32_t level, diff;
52 int bit;
53 level = s->prev_level ^ s->intsetclr;
55 for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) {
56 bit = ffs(diff) - 1;
57 qemu_set_irq(s->pins[bit], (level >> bit) & 1 );
59 s->prev_level = level;
62 static void
63 mst_fpga_set_irq(void *opaque, int irq, int level)
65 mst_irq_state *s = (mst_irq_state *)opaque;
67 if (level)
68 s->prev_level |= 1u << irq;
69 else
70 s->prev_level &= ~(1u << irq);
72 if(s->intmskena & (1u << irq)) {
73 s->intsetclr = 1u << irq;
74 qemu_set_irq(s->parent, level);
79 static uint32_t
80 mst_fpga_readb(void *opaque, target_phys_addr_t addr)
82 mst_irq_state *s = (mst_irq_state *) opaque;
84 switch (addr) {
85 case MST_LEDDAT1:
86 return s->leddat1;
87 case MST_LEDDAT2:
88 return s->leddat2;
89 case MST_LEDCTRL:
90 return s->ledctrl;
91 case MST_GPSWR:
92 return s->gpswr;
93 case MST_MSCWR1:
94 return s->mscwr1;
95 case MST_MSCWR2:
96 return s->mscwr2;
97 case MST_MSCWR3:
98 return s->mscwr3;
99 case MST_MSCRD:
100 return s->mscrd;
101 case MST_INTMSKENA:
102 return s->intmskena;
103 case MST_INTSETCLR:
104 return s->intsetclr;
105 case MST_PCMCIA0:
106 return s->pcmcia0;
107 case MST_PCMCIA1:
108 return s->pcmcia1;
109 default:
110 printf("Mainstone - mst_fpga_readb: Bad register offset "
111 "0x" TARGET_FMT_plx " \n", addr);
113 return 0;
116 static void
117 mst_fpga_writeb(void *opaque, target_phys_addr_t addr, uint32_t value)
119 mst_irq_state *s = (mst_irq_state *) opaque;
120 value &= 0xffffffff;
122 switch (addr) {
123 case MST_LEDDAT1:
124 s->leddat1 = value;
125 break;
126 case MST_LEDDAT2:
127 s->leddat2 = value;
128 break;
129 case MST_LEDCTRL:
130 s->ledctrl = value;
131 break;
132 case MST_GPSWR:
133 s->gpswr = value;
134 break;
135 case MST_MSCWR1:
136 s->mscwr1 = value;
137 break;
138 case MST_MSCWR2:
139 s->mscwr2 = value;
140 break;
141 case MST_MSCWR3:
142 s->mscwr3 = value;
143 break;
144 case MST_MSCRD:
145 s->mscrd = value;
146 break;
147 case MST_INTMSKENA: /* Mask interupt */
148 s->intmskena = (value & 0xFEEFF);
149 mst_fpga_update_gpio(s);
150 break;
151 case MST_INTSETCLR: /* clear or set interrupt */
152 s->intsetclr = (value & 0xFEEFF);
153 break;
154 case MST_PCMCIA0:
155 s->pcmcia0 = value;
156 break;
157 case MST_PCMCIA1:
158 s->pcmcia1 = value;
159 break;
160 default:
161 printf("Mainstone - mst_fpga_writeb: Bad register offset "
162 "0x" TARGET_FMT_plx " \n", addr);
166 static CPUReadMemoryFunc * const mst_fpga_readfn[] = {
167 mst_fpga_readb,
168 mst_fpga_readb,
169 mst_fpga_readb,
171 static CPUWriteMemoryFunc * const mst_fpga_writefn[] = {
172 mst_fpga_writeb,
173 mst_fpga_writeb,
174 mst_fpga_writeb,
177 static void
178 mst_fpga_save(QEMUFile *f, void *opaque)
180 struct mst_irq_state *s = (mst_irq_state *) opaque;
182 qemu_put_be32s(f, &s->prev_level);
183 qemu_put_be32s(f, &s->leddat1);
184 qemu_put_be32s(f, &s->leddat2);
185 qemu_put_be32s(f, &s->ledctrl);
186 qemu_put_be32s(f, &s->gpswr);
187 qemu_put_be32s(f, &s->mscwr1);
188 qemu_put_be32s(f, &s->mscwr2);
189 qemu_put_be32s(f, &s->mscwr3);
190 qemu_put_be32s(f, &s->mscrd);
191 qemu_put_be32s(f, &s->intmskena);
192 qemu_put_be32s(f, &s->intsetclr);
193 qemu_put_be32s(f, &s->pcmcia0);
194 qemu_put_be32s(f, &s->pcmcia1);
197 static int
198 mst_fpga_load(QEMUFile *f, void *opaque, int version_id)
200 mst_irq_state *s = (mst_irq_state *) opaque;
202 qemu_get_be32s(f, &s->prev_level);
203 qemu_get_be32s(f, &s->leddat1);
204 qemu_get_be32s(f, &s->leddat2);
205 qemu_get_be32s(f, &s->ledctrl);
206 qemu_get_be32s(f, &s->gpswr);
207 qemu_get_be32s(f, &s->mscwr1);
208 qemu_get_be32s(f, &s->mscwr2);
209 qemu_get_be32s(f, &s->mscwr3);
210 qemu_get_be32s(f, &s->mscrd);
211 qemu_get_be32s(f, &s->intmskena);
212 qemu_get_be32s(f, &s->intsetclr);
213 qemu_get_be32s(f, &s->pcmcia0);
214 qemu_get_be32s(f, &s->pcmcia1);
215 return 0;
218 qemu_irq *mst_irq_init(uint32_t base, qemu_irq irq)
220 mst_irq_state *s;
221 int iomemtype;
222 qemu_irq *qi;
224 s = (mst_irq_state *)
225 qemu_mallocz(sizeof(mst_irq_state));
227 s->parent = irq;
229 /* alloc the external 16 irqs */
230 qi = qemu_allocate_irqs(mst_fpga_set_irq, s, MST_NUM_IRQS);
231 s->pins = qi;
233 iomemtype = cpu_register_io_memory(mst_fpga_readfn,
234 mst_fpga_writefn, s, DEVICE_NATIVE_ENDIAN);
235 cpu_register_physical_memory(base, 0x00100000, iomemtype);
236 register_savevm(NULL, "mainstone_fpga", 0, 0, mst_fpga_save,
237 mst_fpga_load, s);
238 return qi;