blob: 1b6cb77659eeada48de832be1601b5191728d3d4 [file] [log] [blame]
ths7233b352007-12-02 02:20:03 +00001/*
2 * PXA270-based Intel Mainstone platforms.
3 * FPGA driver
4 *
5 * Copyright (c) 2007 by Armin Kuster <akuster@kama-aina.net> or
6 * <akuster@mvista.com>
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
ths7233b352007-12-02 02:20:03 +000017#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
30typedef struct mst_irq_state{
ths7233b352007-12-02 02:20:03 +000031 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
49static void
50mst_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
63static void
64mst_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
80static uint32_t
81mst_fpga_readb(void *opaque, target_phys_addr_t addr)
82{
83 mst_irq_state *s = (mst_irq_state *) opaque;
ths7233b352007-12-02 02:20:03 +000084
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
117static void
118mst_fpga_writeb(void *opaque, target_phys_addr_t addr, uint32_t value)
119{
120 mst_irq_state *s = (mst_irq_state *) opaque;
ths7233b352007-12-02 02:20:03 +0000121 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
Blue Swirld60efc62009-08-25 18:29:31 +0000167static CPUReadMemoryFunc * const mst_fpga_readfn[] = {
ths7233b352007-12-02 02:20:03 +0000168 mst_fpga_readb,
169 mst_fpga_readb,
170 mst_fpga_readb,
171};
Blue Swirld60efc62009-08-25 18:29:31 +0000172static CPUWriteMemoryFunc * const mst_fpga_writefn[] = {
ths7233b352007-12-02 02:20:03 +0000173 mst_fpga_writeb,
174 mst_fpga_writeb,
175 mst_fpga_writeb,
176};
177
178static void
179mst_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
198static int
199mst_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
Paul Brookbc24a222009-05-10 01:44:56 +0100219qemu_irq *mst_irq_init(PXA2xxState *cpu, uint32_t base, int irq)
ths7233b352007-12-02 02:20:03 +0000220{
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
ths7233b352007-12-02 02:20:03 +0000228 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
Avi Kivity1eed09c2009-06-14 11:38:51 +0300234 iomemtype = cpu_register_io_memory(mst_fpga_readfn,
ths7233b352007-12-02 02:20:03 +0000235 mst_fpga_writefn, s);
pbrook8da3ff12008-12-01 18:59:50 +0000236 cpu_register_physical_memory(base, 0x00100000, iomemtype);
ths7233b352007-12-02 02:20:03 +0000237 register_savevm("mainstone_fpga", 0, 0, mst_fpga_save, mst_fpga_load, s);
238 return qi;
239}