|
|
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_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
30:
31: typedef struct mst_irq_state{
32: target_phys_addr_t target_base;
33: qemu_irq *parent;
34: qemu_irq *pins;
35:
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;
50:
51: static void
52: mst_fpga_update_gpio(mst_irq_state *s)
53: {
54: uint32_t level, diff;
55: int bit;
56: level = s->prev_level ^ s->intsetclr;
57:
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 );
61: }
62: s->prev_level = level;
63: }
64:
65: static void
66: mst_fpga_set_irq(void *opaque, int irq, int level)
67: {
68: mst_irq_state *s = (mst_irq_state *)opaque;
69:
70: if (level)
71: s->prev_level |= 1u << irq;
72: else
73: s->prev_level &= ~(1u << irq);
74:
75: if(s->intmskena & (1u << irq)) {
76: s->intsetclr = 1u << irq;
77: qemu_set_irq(s->parent[0], level);
78: }
79: }
80:
81:
82: static uint32_t
83: mst_fpga_readb(void *opaque, target_phys_addr_t addr)
84: {
85: mst_irq_state *s = (mst_irq_state *) opaque;
86: addr -= s->target_base;
87:
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);
116: }
117: return 0;
118: }
119:
120: static void
121: mst_fpga_writeb(void *opaque, target_phys_addr_t addr, uint32_t value)
122: {
123: mst_irq_state *s = (mst_irq_state *) opaque;
124: addr -= s->target_base;
125: value &= 0xffffffff;
126:
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);
168: }
169: }
170:
171: CPUReadMemoryFunc *mst_fpga_readfn[] = {
172: mst_fpga_readb,
173: mst_fpga_readb,
174: mst_fpga_readb,
175: };
176: CPUWriteMemoryFunc *mst_fpga_writefn[] = {
177: mst_fpga_writeb,
178: mst_fpga_writeb,
179: mst_fpga_writeb,
180: };
181:
182: static void
183: mst_fpga_save(QEMUFile *f, void *opaque)
184: {
185: struct mst_irq_state *s = (mst_irq_state *) opaque;
186:
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);
200: }
201:
202: static int
203: mst_fpga_load(QEMUFile *f, void *opaque, int version_id)
204: {
205: mst_irq_state *s = (mst_irq_state *) opaque;
206:
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;
221: }
222:
223: qemu_irq *mst_irq_init(struct pxa2xx_state_s *cpu, uint32_t base, int irq)
224: {
225: mst_irq_state *s;
226: int iomemtype;
227: qemu_irq *qi;
228:
229: s = (mst_irq_state *)
230: qemu_mallocz(sizeof(mst_irq_state));
231:
232: if (!s)
233: return NULL;
234: s->target_base = base;
235: s->parent = &cpu->pic[irq];
236:
237: /* alloc the external 16 irqs */
238: qi = qemu_allocate_irqs(mst_fpga_set_irq, s, MST_NUM_IRQS);
239: s->pins = qi;
240:
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;
246: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.