]> git.proxmox.com Git - mirror_qemu.git/blob - hw/mainstone.c
Scale TSC2102 touchscreen pressure value more realistically (still could be better).
[mirror_qemu.git] / hw / mainstone.c
1 /*
2 * PXA270-based Intel Mainstone platforms.
3 *
4 * Copyright (c) 2007 by Armin Kuster <akuster@kama-aina.net> or
5 * <akuster@mvista.com>
6 *
7 * Code based on spitz platform by Andrzej Zaborowski <balrog@zabor.org>
8 *
9 * This code is licensed under the GNU GPL v2.
10 */
11 #include "hw.h"
12 #include "pxa.h"
13 #include "arm-misc.h"
14 #include "net.h"
15 #include "devices.h"
16 #include "boards.h"
17
18 #define MST_ETH_PHYS 0x10000300
19 #define MST_FPGA_PHYS 0x08000000
20
21 /* Mainstone FPGA for extern irqs */
22 #define FPGA_GPIO_PIN 0
23 #define MST_NUM_IRQS 16
24 #define MST_BASE MST_FPGA_PHYS
25 #define MST_LEDDAT1 0x10
26 #define MST_LEDDAT2 0x14
27 #define MST_LEDCTRL 0x40
28 #define MST_GPSWR 0x60
29 #define MST_MSCWR1 0x80
30 #define MST_MSCWR2 0x84
31 #define MST_MSCWR3 0x88
32 #define MST_MSCRD 0x90
33 #define MST_INTMSKENA 0xc0
34 #define MST_INTSETCLR 0xd0
35 #define MST_PCMCIA0 0xe0
36 #define MST_PCMCIA1 0xe4
37
38 /* IRQ definitions */
39 #define ETHERNET_IRQ 3
40
41 typedef struct mst_irq_state {
42 target_phys_addr_t target_base;
43 qemu_irq *parent;
44 qemu_irq *pins;
45
46 uint32_t prev_level;
47 uint32_t leddat1;
48 uint32_t leddat2;
49 uint32_t ledctrl;
50 uint32_t gpswr;
51 uint32_t mscwr1;
52 uint32_t mscwr2;
53 uint32_t mscwr3;
54 uint32_t mscrd;
55 uint32_t intmskena;
56 uint32_t intsetclr;
57 uint32_t pcmcia0;
58 uint32_t pcmcia1;
59 } mst_irq_state;
60
61 static void
62 mst_fpga_update_gpio(mst_irq_state *s)
63 {
64 uint32_t level, diff;
65 int bit;
66 level = s->prev_level ^ s->intsetclr;
67
68 for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) {
69 bit = ffs(diff) - 1;
70 qemu_set_irq(s->pins[bit], (level >> bit) & 1 );
71 }
72 s->prev_level = level;
73 }
74
75 static void
76 mst_fpga_set_irq(void *opaque, int irq, int level)
77 {
78 mst_irq_state *s = (mst_irq_state *)opaque;
79
80 if (level)
81 s->prev_level |= 1u << irq;
82 else
83 s->prev_level &= ~(1u << irq);
84
85 if(s->intmskena & (1u << irq)) {
86 s->intsetclr = 1u << irq;
87 qemu_set_irq(s->parent[0], level);
88 }
89 }
90
91 static uint32_t
92 mst_fpga_readb(void *opaque, target_phys_addr_t addr)
93 {
94 mst_irq_state *s = (mst_irq_state *) opaque;
95 addr -= s->target_base;
96
97 switch (addr) {
98 case MST_LEDDAT1:
99 return s->leddat1;
100 case MST_LEDDAT2:
101 return s->leddat2;
102 case MST_LEDCTRL:
103 return s->ledctrl;
104 case MST_GPSWR:
105 return s->gpswr;
106 case MST_MSCWR1:
107 return s->mscwr1;
108 case MST_MSCWR2:
109 return s->mscwr2;
110 case MST_MSCWR3:
111 return s->mscwr3;
112 case MST_MSCRD:
113 return s->mscrd;
114 case MST_INTMSKENA:
115 return s->intmskena;
116 case MST_INTSETCLR:
117 return s->intsetclr;
118 case MST_PCMCIA0:
119 return s->pcmcia0;
120 case MST_PCMCIA1:
121 return s->pcmcia1;
122 default:
123 printf("Mainstone - mst_fpga_readb: Bad register offset "
124 REG_FMT " \n", addr);
125 }
126 return 0;
127 }
128
129 static void
130 mst_fpga_writeb(void *opaque, target_phys_addr_t addr, uint32_t value)
131 {
132 mst_irq_state *s = (mst_irq_state *) opaque;
133 addr -= s->target_base;
134 value &= 0xffffffff;
135
136 switch (addr) {
137 case MST_LEDDAT1:
138 s->leddat1 = value;
139 break;
140 case MST_LEDDAT2:
141 s->leddat2 = value;
142 break;
143 case MST_LEDCTRL:
144 s->ledctrl = value;
145 break;
146 case MST_GPSWR:
147 s->gpswr = value;
148 break;
149 case MST_MSCWR1:
150 s->mscwr1 = value;
151 break;
152 case MST_MSCWR2:
153 s->mscwr2 = value;
154 break;
155 case MST_MSCWR3:
156 s->mscwr3 = value;
157 break;
158 case MST_MSCRD:
159 s->mscrd = value;
160 break;
161 case MST_INTMSKENA: /* Mask interupt */
162 s->intmskena = (value & 0xFEEFF);
163 mst_fpga_update_gpio(s);
164 break;
165 case MST_INTSETCLR: /* clear or set interrupt */
166 s->intsetclr = (value & 0xFEEFF);
167 break;
168 case MST_PCMCIA0:
169 s->pcmcia0 = value;
170 break;
171 case MST_PCMCIA1:
172 s->pcmcia1 = value;
173 break;
174 default:
175 printf("Mainstone - mst_fpga_writeb: Bad register offset "
176 REG_FMT " \n", addr);
177 }
178 }
179
180 CPUReadMemoryFunc *mst_fpga_readfn[] = {
181 mst_fpga_readb,
182 mst_fpga_readb,
183 mst_fpga_readb,
184 };
185 CPUWriteMemoryFunc *mst_fpga_writefn[] = {
186 mst_fpga_writeb,
187 mst_fpga_writeb,
188 mst_fpga_writeb,
189 };
190
191 static void
192 mst_fpga_save(QEMUFile *f, void *opaque)
193 {
194 struct mst_irq_state *s = (mst_irq_state *) opaque;
195
196 qemu_put_be32s(f, &s->prev_level);
197 qemu_put_be32s(f, &s->leddat1);
198 qemu_put_be32s(f, &s->leddat2);
199 qemu_put_be32s(f, &s->ledctrl);
200 qemu_put_be32s(f, &s->gpswr);
201 qemu_put_be32s(f, &s->mscwr1);
202 qemu_put_be32s(f, &s->mscwr2);
203 qemu_put_be32s(f, &s->mscwr3);
204 qemu_put_be32s(f, &s->mscrd);
205 qemu_put_be32s(f, &s->intmskena);
206 qemu_put_be32s(f, &s->intsetclr);
207 qemu_put_be32s(f, &s->pcmcia0);
208 qemu_put_be32s(f, &s->pcmcia1);
209 }
210
211 static int
212 mst_fpga_load(QEMUFile *f, void *opaque, int version_id)
213 {
214 mst_irq_state *s = (mst_irq_state *) opaque;
215
216 qemu_get_be32s(f, &s->prev_level);
217 qemu_get_be32s(f, &s->leddat1);
218 qemu_get_be32s(f, &s->leddat2);
219 qemu_get_be32s(f, &s->ledctrl);
220 qemu_get_be32s(f, &s->gpswr);
221 qemu_get_be32s(f, &s->mscwr1);
222 qemu_get_be32s(f, &s->mscwr2);
223 qemu_get_be32s(f, &s->mscwr3);
224 qemu_get_be32s(f, &s->mscrd);
225 qemu_get_be32s(f, &s->intmskena);
226 qemu_get_be32s(f, &s->intsetclr);
227 qemu_get_be32s(f, &s->pcmcia0);
228 qemu_get_be32s(f, &s->pcmcia1);
229 return 0;
230 }
231
232 static qemu_irq
233 *mst_irq_init(struct pxa2xx_state_s *cpu, uint32_t base, int irq)
234 {
235 mst_irq_state *s;
236 int iomemtype;
237 qemu_irq *qi;
238
239 s = (mst_irq_state *) qemu_mallocz(sizeof(mst_irq_state));
240
241 if (!s)
242 return NULL;
243 s->target_base = base;
244 s->parent = &cpu->pic[irq];
245
246 /* alloc the external 16 irqs */
247 qi = qemu_allocate_irqs(mst_fpga_set_irq, s, MST_NUM_IRQS);
248 s->pins = qi;
249
250 iomemtype = cpu_register_io_memory(0, mst_fpga_readfn,
251 mst_fpga_writefn, s);
252 cpu_register_physical_memory(MST_BASE, 0x00100000, iomemtype);
253 register_savevm("mainstone_fpga", 0, 0, mst_fpga_save, mst_fpga_load, s);
254 return qi;
255 }
256
257 enum mainstone_model_e { mainstone };
258
259 static void mainstone_common_init(int ram_size, int vga_ram_size,
260 DisplayState *ds, const char *kernel_filename,
261 const char *kernel_cmdline, const char *initrd_filename,
262 const char *cpu_model, enum mainstone_model_e model, int arm_id)
263 {
264 uint32_t mainstone_ram = 0x04000000;
265 uint32_t mainstone_rom = 0x00800000;
266 struct pxa2xx_state_s *cpu;
267 qemu_irq *mst_irq;
268
269 if (!cpu_model)
270 cpu_model = "pxa270-c5";
271
272 /* Setup CPU & memory */
273 if (ram_size < mainstone_ram + mainstone_rom + PXA2XX_INTERNAL_SIZE) {
274 fprintf(stderr, "This platform requires %i bytes of memory\n",
275 mainstone_ram + mainstone_rom + PXA2XX_INTERNAL_SIZE);
276 exit(1);
277 }
278
279 cpu = pxa270_init(mainstone_ram, ds, cpu_model);
280 cpu_register_physical_memory(0, mainstone_rom,
281 qemu_ram_alloc(mainstone_rom) | IO_MEM_ROM);
282
283 /* Setup initial (reset) machine state */
284 cpu->env->regs[15] = PXA2XX_SDRAM_BASE;
285
286 mst_irq = mst_irq_init(cpu, MST_BASE, PXA2XX_PIC_GPIO_0);
287 smc91c111_init(&nd_table[0], MST_ETH_PHYS, mst_irq[ETHERNET_IRQ]);
288
289 arm_load_kernel(cpu->env, mainstone_ram, kernel_filename, kernel_cmdline,
290 initrd_filename, arm_id, PXA2XX_SDRAM_BASE);
291 }
292
293 static void mainstone_init(int ram_size, int vga_ram_size,
294 const char *boot_device, DisplayState *ds,
295 const char *kernel_filename, const char *kernel_cmdline,
296 const char *initrd_filename, const char *cpu_model)
297 {
298 mainstone_common_init(ram_size, vga_ram_size, ds, kernel_filename,
299 kernel_cmdline, initrd_filename, cpu_model, mainstone, 0x196);
300 }
301
302 QEMUMachine mainstone2_machine = {
303 "mainstone",
304 "Mainstone II (PXA27x)",
305 mainstone_init,
306 };