Merge branch 'qemu-cvs'
[kvm-userspace.git] / qemu / hw / mst_fpga.c
blob2d5ac5ae8d1e83d7d7d734be77bb55ab4ed6cb00
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 "pxa.h"
12 #include "mainstone.h"
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
31 typedef struct mst_irq_state{
32 target_phys_addr_t target_base;
33 qemu_irq *parent;
34 qemu_irq *pins;
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;
51 static void
52 mst_fpga_update_gpio(mst_irq_state *s)
54 uint32_t level, diff;
55 int bit;
56 level = s->prev_level ^ s->intsetclr;
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 );
62 s->prev_level = level;
65 static void
66 mst_fpga_set_irq(void *opaque, int irq, int level)
68 mst_irq_state *s = (mst_irq_state *)opaque;
70 if (level)
71 s->prev_level |= 1u << irq;
72 else
73 s->prev_level &= ~(1u << irq);
75 if(s->intmskena & (1u << irq)) {
76 s->intsetclr = 1u << irq;
77 qemu_set_irq(s->parent[0], level);
82 static uint32_t
83 mst_fpga_readb(void *opaque, target_phys_addr_t addr)
85 mst_irq_state *s = (mst_irq_state *) opaque;
86 addr -= s->target_base;
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);
117 return 0;
120 static void
121 mst_fpga_writeb(void *opaque, target_phys_addr_t addr, uint32_t value)
123 mst_irq_state *s = (mst_irq_state *) opaque;
124 addr -= s->target_base;
125 value &= 0xffffffff;
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);
171 static CPUReadMemoryFunc *mst_fpga_readfn[] = {
172 mst_fpga_readb,
173 mst_fpga_readb,
174 mst_fpga_readb,
176 static CPUWriteMemoryFunc *mst_fpga_writefn[] = {
177 mst_fpga_writeb,
178 mst_fpga_writeb,
179 mst_fpga_writeb,
182 static void
183 mst_fpga_save(QEMUFile *f, void *opaque)
185 struct mst_irq_state *s = (mst_irq_state *) opaque;
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);
202 static int
203 mst_fpga_load(QEMUFile *f, void *opaque, int version_id)
205 mst_irq_state *s = (mst_irq_state *) opaque;
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;
223 qemu_irq *mst_irq_init(struct pxa2xx_state_s *cpu, uint32_t base, int irq)
225 mst_irq_state *s;
226 int iomemtype;
227 qemu_irq *qi;
229 s = (mst_irq_state *)
230 qemu_mallocz(sizeof(mst_irq_state));
232 if (!s)
233 return NULL;
234 s->target_base = base;
235 s->parent = &cpu->pic[irq];
237 /* alloc the external 16 irqs */
238 qi = qemu_allocate_irqs(mst_fpga_set_irq, s, MST_NUM_IRQS);
239 s->pins = qi;
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;