1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#include "blockdev.h"
22#include "hw.h"
23#include "arm-misc.h"
24#include "omap.h"
25#include "sysemu.h"
26#include "qemu-timer.h"
27#include "qemu-char.h"
28#include "flash.h"
29#include "soc_dma.h"
30#include "audio/audio.h"
31
32
33struct omap_eac_s {
34 qemu_irq irq;
35
36 uint16_t sysconfig;
37 uint8_t config[4];
38 uint8_t control;
39 uint8_t address;
40 uint16_t data;
41 uint8_t vtol;
42 uint8_t vtsl;
43 uint16_t mixer;
44 uint16_t gain[4];
45 uint8_t att;
46 uint16_t max[7];
47
48 struct {
49 qemu_irq txdrq;
50 qemu_irq rxdrq;
51 uint32_t (*txrx)(void *opaque, uint32_t, int);
52 void *opaque;
53
54#define EAC_BUF_LEN 1024
55 uint32_t rxbuf[EAC_BUF_LEN];
56 int rxoff;
57 int rxlen;
58 int rxavail;
59 uint32_t txbuf[EAC_BUF_LEN];
60 int txlen;
61 int txavail;
62
63 int enable;
64 int rate;
65
66 uint16_t config[4];
67
68
69 QEMUSoundCard card;
70 SWVoiceIn *in_voice;
71 SWVoiceOut *out_voice;
72 int hw_enable;
73 } codec;
74
75 struct {
76 uint8_t control;
77 uint16_t config;
78 } modem, bt;
79};
80
81static inline void omap_eac_interrupt_update(struct omap_eac_s *s)
82{
83 qemu_set_irq(s->irq, (s->codec.config[1] >> 14) & 1);
84}
85
86static inline void omap_eac_in_dmarequest_update(struct omap_eac_s *s)
87{
88 qemu_set_irq(s->codec.rxdrq, (s->codec.rxavail || s->codec.rxlen) &&
89 ((s->codec.config[1] >> 12) & 1));
90}
91
92static inline void omap_eac_out_dmarequest_update(struct omap_eac_s *s)
93{
94 qemu_set_irq(s->codec.txdrq, s->codec.txlen < s->codec.txavail &&
95 ((s->codec.config[1] >> 11) & 1));
96}
97
98static inline void omap_eac_in_refill(struct omap_eac_s *s)
99{
100 int left = MIN(EAC_BUF_LEN - s->codec.rxlen, s->codec.rxavail) << 2;
101 int start = ((s->codec.rxoff + s->codec.rxlen) & (EAC_BUF_LEN - 1)) << 2;
102 int leftwrap = MIN(left, (EAC_BUF_LEN << 2) - start);
103 int recv = 1;
104 uint8_t *buf = (uint8_t *) s->codec.rxbuf + start;
105
106 left -= leftwrap;
107 start = 0;
108 while (leftwrap && (recv = AUD_read(s->codec.in_voice, buf + start,
109 leftwrap)) > 0) {
110 start += recv;
111 leftwrap -= recv;
112 }
113 if (recv <= 0)
114 s->codec.rxavail = 0;
115 else
116 s->codec.rxavail -= start >> 2;
117 s->codec.rxlen += start >> 2;
118
119 if (recv > 0 && left > 0) {
120 start = 0;
121 while (left && (recv = AUD_read(s->codec.in_voice,
122 (uint8_t *) s->codec.rxbuf + start,
123 left)) > 0) {
124 start += recv;
125 left -= recv;
126 }
127 if (recv <= 0)
128 s->codec.rxavail = 0;
129 else
130 s->codec.rxavail -= start >> 2;
131 s->codec.rxlen += start >> 2;
132 }
133}
134
135static inline void omap_eac_out_empty(struct omap_eac_s *s)
136{
137 int left = s->codec.txlen << 2;
138 int start = 0;
139 int sent = 1;
140
141 while (left && (sent = AUD_write(s->codec.out_voice,
142 (uint8_t *) s->codec.txbuf + start,
143 left)) > 0) {
144 start += sent;
145 left -= sent;
146 }
147
148 if (!sent) {
149 s->codec.txavail = 0;
150 omap_eac_out_dmarequest_update(s);
151 }
152
153 if (start)
154 s->codec.txlen = 0;
155}
156
157static void omap_eac_in_cb(void *opaque, int avail_b)
158{
159 struct omap_eac_s *s = (struct omap_eac_s *) opaque;
160
161 s->codec.rxavail = avail_b >> 2;
162 omap_eac_in_refill(s);
163
164 omap_eac_in_dmarequest_update(s);
165}
166
167static void omap_eac_out_cb(void *opaque, int free_b)
168{
169 struct omap_eac_s *s = (struct omap_eac_s *) opaque;
170
171 s->codec.txavail = free_b >> 2;
172 if (s->codec.txlen)
173 omap_eac_out_empty(s);
174 else
175 omap_eac_out_dmarequest_update(s);
176}
177
178static void omap_eac_enable_update(struct omap_eac_s *s)
179{
180 s->codec.enable = !(s->codec.config[1] & 1) &&
181 (s->codec.config[1] & 2) &&
182 s->codec.hw_enable;
183}
184
185static const int omap_eac_fsint[4] = {
186 8000,
187 11025,
188 22050,
189 44100,
190};
191
192static const int omap_eac_fsint2[8] = {
193 8000,
194 11025,
195 22050,
196 44100,
197 48000,
198 0, 0, 0,
199};
200
201static const int omap_eac_fsint3[16] = {
202 8000,
203 11025,
204 16000,
205 22050,
206 24000,
207 32000,
208 44100,
209 48000,
210 0, 0, 0, 0, 0, 0, 0, 0,
211};
212
213static void omap_eac_rate_update(struct omap_eac_s *s)
214{
215 int fsint[3];
216
217 fsint[2] = (s->codec.config[3] >> 9) & 0xf;
218 fsint[1] = (s->codec.config[2] >> 0) & 0x7;
219 fsint[0] = (s->codec.config[0] >> 6) & 0x3;
220 if (fsint[2] < 0xf)
221 s->codec.rate = omap_eac_fsint3[fsint[2]];
222 else if (fsint[1] < 0x7)
223 s->codec.rate = omap_eac_fsint2[fsint[1]];
224 else
225 s->codec.rate = omap_eac_fsint[fsint[0]];
226}
227
228static void omap_eac_volume_update(struct omap_eac_s *s)
229{
230
231}
232
233static void omap_eac_format_update(struct omap_eac_s *s)
234{
235 struct audsettings fmt;
236
237
238 if (s->codec.rxlen)
239 s->codec.rxlen = 1;
240
241 if (s->codec.in_voice) {
242 AUD_set_active_in(s->codec.in_voice, 0);
243 AUD_close_in(&s->codec.card, s->codec.in_voice);
244 s->codec.in_voice = NULL;
245 }
246 if (s->codec.out_voice) {
247 omap_eac_out_empty(s);
248 AUD_set_active_out(s->codec.out_voice, 0);
249 AUD_close_out(&s->codec.card, s->codec.out_voice);
250 s->codec.out_voice = NULL;
251 s->codec.txavail = 0;
252 }
253
254 s->codec.txlen = 0;
255
256 omap_eac_enable_update(s);
257 if (!s->codec.enable)
258 return;
259
260 omap_eac_rate_update(s);
261 fmt.endianness = ((s->codec.config[0] >> 8) & 1);
262 fmt.nchannels = ((s->codec.config[0] >> 10) & 1) ? 2 : 1;
263 fmt.freq = s->codec.rate;
264
265
266
267
268 fmt.fmt = AUD_FMT_U16;
269
270 s->codec.in_voice = AUD_open_in(&s->codec.card, s->codec.in_voice,
271 "eac.codec.in", s, omap_eac_in_cb, &fmt);
272 s->codec.out_voice = AUD_open_out(&s->codec.card, s->codec.out_voice,
273 "eac.codec.out", s, omap_eac_out_cb, &fmt);
274
275 omap_eac_volume_update(s);
276
277 AUD_set_active_in(s->codec.in_voice, 1);
278 AUD_set_active_out(s->codec.out_voice, 1);
279}
280
281static void omap_eac_reset(struct omap_eac_s *s)
282{
283 s->sysconfig = 0;
284 s->config[0] = 0x0c;
285 s->config[1] = 0x09;
286 s->config[2] = 0xab;
287 s->config[3] = 0x03;
288 s->control = 0x00;
289 s->address = 0x00;
290 s->data = 0x0000;
291 s->vtol = 0x00;
292 s->vtsl = 0x00;
293 s->mixer = 0x0000;
294 s->gain[0] = 0xe7e7;
295 s->gain[1] = 0x6767;
296 s->gain[2] = 0x6767;
297 s->gain[3] = 0x6767;
298 s->att = 0xce;
299 s->max[0] = 0;
300 s->max[1] = 0;
301 s->max[2] = 0;
302 s->max[3] = 0;
303 s->max[4] = 0;
304 s->max[5] = 0;
305 s->max[6] = 0;
306
307 s->modem.control = 0x00;
308 s->modem.config = 0x0000;
309 s->bt.control = 0x00;
310 s->bt.config = 0x0000;
311 s->codec.config[0] = 0x0649;
312 s->codec.config[1] = 0x0000;
313 s->codec.config[2] = 0x0007;
314 s->codec.config[3] = 0x1ffc;
315 s->codec.rxoff = 0;
316 s->codec.rxlen = 0;
317 s->codec.txlen = 0;
318 s->codec.rxavail = 0;
319 s->codec.txavail = 0;
320
321 omap_eac_format_update(s);
322 omap_eac_interrupt_update(s);
323}
324
325static uint32_t omap_eac_read(void *opaque, target_phys_addr_t addr)
326{
327 struct omap_eac_s *s = (struct omap_eac_s *) opaque;
328 uint32_t ret;
329
330 switch (addr) {
331 case 0x000:
332 return s->config[0];
333 case 0x004:
334 return s->config[1];
335 case 0x008:
336 return s->config[2];
337 case 0x00c:
338 return s->config[3];
339
340 case 0x010:
341 return s->control | ((s->codec.rxavail + s->codec.rxlen > 0) << 7) |
342 ((s->codec.txlen < s->codec.txavail) << 5);
343
344 case 0x014:
345 return s->address;
346 case 0x018:
347 return s->data & 0xff;
348 case 0x01c:
349 return s->data >> 8;
350 case 0x020:
351 return s->vtol;
352 case 0x024:
353 return s->vtsl | (3 << 5);
354 case 0x040:
355 return s->modem.control;
356 case 0x044:
357 return s->modem.config;
358 case 0x060:
359 return s->bt.control;
360 case 0x064:
361 return s->bt.config;
362 case 0x080:
363 return s->mixer;
364 case 0x084:
365 return s->gain[0];
366 case 0x088:
367 return s->gain[1];
368 case 0x08c:
369 return s->gain[2];
370 case 0x090:
371 return s->gain[3];
372 case 0x094:
373 return s->att;
374 case 0x098:
375 return s->max[0];
376 case 0x09c:
377 return s->max[1];
378 case 0x0a0:
379 return s->max[2];
380 case 0x0a4:
381 return s->max[3];
382 case 0x0a8:
383 return s->max[4];
384 case 0x0ac:
385 return s->max[5];
386 case 0x0b0:
387 return s->max[6];
388 case 0x0b4:
389
390 return 0x0000;
391 case 0x0b8:
392 if (likely(s->codec.rxlen > 1)) {
393 ret = s->codec.rxbuf[s->codec.rxoff ++];
394 s->codec.rxlen --;
395 s->codec.rxoff &= EAC_BUF_LEN - 1;
396 return ret;
397 } else if (s->codec.rxlen) {
398 ret = s->codec.rxbuf[s->codec.rxoff ++];
399 s->codec.rxlen --;
400 s->codec.rxoff &= EAC_BUF_LEN - 1;
401 if (s->codec.rxavail)
402 omap_eac_in_refill(s);
403 omap_eac_in_dmarequest_update(s);
404 return ret;
405 }
406 return 0x0000;
407 case 0x0bc:
408 return s->codec.config[0];
409 case 0x0c0:
410 return s->codec.config[1] | ((s->codec.config[1] & 2) << 14);
411 case 0x0c4:
412 return s->codec.config[2];
413 case 0x0c8:
414 return s->codec.config[3];
415 case 0x0cc:
416 case 0x0d0:
417 case 0x0d8:
418 case 0x0e4:
419 case 0x0ec:
420 return 0x0000;
421
422 case 0x100:
423 return 0x0010;
424
425 case 0x104:
426 return s->sysconfig;
427
428 case 0x108:
429 return 1 | 0xe;
430 }
431
432 OMAP_BAD_REG(addr);
433 return 0;
434}
435
436static void omap_eac_write(void *opaque, target_phys_addr_t addr,
437 uint32_t value)
438{
439 struct omap_eac_s *s = (struct omap_eac_s *) opaque;
440
441 switch (addr) {
442 case 0x098:
443 case 0x09c:
444 case 0x0a0:
445 case 0x0a4:
446 case 0x0a8:
447 case 0x0ac:
448 case 0x0b0:
449 case 0x0b8:
450 case 0x0d0:
451 case 0x0d8:
452 case 0x0e4:
453 case 0x0ec:
454 case 0x100:
455 case 0x108:
456 OMAP_RO_REG(addr);
457 return;
458
459 case 0x000:
460 s->config[0] = value & 0xff;
461 omap_eac_format_update(s);
462 break;
463 case 0x004:
464 s->config[1] = value & 0xff;
465 omap_eac_format_update(s);
466 break;
467 case 0x008:
468 s->config[2] = value & 0xff;
469 omap_eac_format_update(s);
470 break;
471 case 0x00c:
472 s->config[3] = value & 0xff;
473 omap_eac_format_update(s);
474 break;
475
476 case 0x010:
477
478 s->control = value & 0x5f;
479 omap_eac_interrupt_update(s);
480 break;
481
482 case 0x014:
483 s->address = value & 0xff;
484 break;
485 case 0x018:
486 s->data &= 0xff00;
487 s->data |= value & 0xff;
488 break;
489 case 0x01c:
490 s->data &= 0x00ff;
491 s->data |= value << 8;
492 break;
493 case 0x020:
494 s->vtol = value & 0xf8;
495 break;
496 case 0x024:
497 s->vtsl = value & 0x9f;
498 break;
499 case 0x040:
500 s->modem.control = value & 0x8f;
501 break;
502 case 0x044:
503 s->modem.config = value & 0x7fff;
504 break;
505 case 0x060:
506 s->bt.control = value & 0x8f;
507 break;
508 case 0x064:
509 s->bt.config = value & 0x7fff;
510 break;
511 case 0x080:
512 s->mixer = value & 0x0fff;
513 break;
514 case 0x084:
515 s->gain[0] = value & 0xffff;
516 break;
517 case 0x088:
518 s->gain[1] = value & 0xff7f;
519 break;
520 case 0x08c:
521 s->gain[2] = value & 0xff7f;
522 break;
523 case 0x090:
524 s->gain[3] = value & 0xff7f;
525 break;
526 case 0x094:
527 s->att = value & 0xff;
528 break;
529
530 case 0x0b4:
531 s->codec.txbuf[s->codec.txlen ++] = value;
532 if (unlikely(s->codec.txlen == EAC_BUF_LEN ||
533 s->codec.txlen == s->codec.txavail)) {
534 if (s->codec.txavail)
535 omap_eac_out_empty(s);
536
537 s->codec.txlen = 0;
538 }
539 break;
540
541 case 0x0bc:
542 s->codec.config[0] = value & 0x07ff;
543 omap_eac_format_update(s);
544 break;
545 case 0x0c0:
546 s->codec.config[1] = value & 0x780f;
547 omap_eac_format_update(s);
548 break;
549 case 0x0c4:
550 s->codec.config[2] = value & 0x003f;
551 omap_eac_format_update(s);
552 break;
553 case 0x0c8:
554 s->codec.config[3] = value & 0xffff;
555 omap_eac_format_update(s);
556 break;
557 case 0x0cc:
558 case 0x0d4:
559 case 0x0e0:
560 case 0x0e8:
561 case 0x0f0:
562 break;
563
564 case 0x104:
565 if (value & (1 << 1))
566 omap_eac_reset(s);
567 s->sysconfig = value & 0x31d;
568 break;
569
570 default:
571 OMAP_BAD_REG(addr);
572 return;
573 }
574}
575
576static CPUReadMemoryFunc * const omap_eac_readfn[] = {
577 omap_badwidth_read16,
578 omap_eac_read,
579 omap_badwidth_read16,
580};
581
582static CPUWriteMemoryFunc * const omap_eac_writefn[] = {
583 omap_badwidth_write16,
584 omap_eac_write,
585 omap_badwidth_write16,
586};
587
588static struct omap_eac_s *omap_eac_init(struct omap_target_agent_s *ta,
589 qemu_irq irq, qemu_irq *drq, omap_clk fclk, omap_clk iclk)
590{
591 int iomemtype;
592 struct omap_eac_s *s = (struct omap_eac_s *)
593 qemu_mallocz(sizeof(struct omap_eac_s));
594
595 s->irq = irq;
596 s->codec.rxdrq = *drq ++;
597 s->codec.txdrq = *drq;
598 omap_eac_reset(s);
599
600 AUD_register_card("OMAP EAC", &s->codec.card);
601
602 iomemtype = cpu_register_io_memory(omap_eac_readfn,
603 omap_eac_writefn, s, DEVICE_NATIVE_ENDIAN);
604 omap_l4_attach(ta, 0, iomemtype);
605
606 return s;
607}
608
609
610struct omap_sti_s {
611 qemu_irq irq;
612 CharDriverState *chr;
613
614 uint32_t sysconfig;
615 uint32_t systest;
616 uint32_t irqst;
617 uint32_t irqen;
618 uint32_t clkcontrol;
619 uint32_t serial_config;
620};
621
622#define STI_TRACE_CONSOLE_CHANNEL 239
623#define STI_TRACE_CONTROL_CHANNEL 253
624
625static inline void omap_sti_interrupt_update(struct omap_sti_s *s)
626{
627 qemu_set_irq(s->irq, s->irqst & s->irqen);
628}
629
630static void omap_sti_reset(struct omap_sti_s *s)
631{
632 s->sysconfig = 0;
633 s->irqst = 0;
634 s->irqen = 0;
635 s->clkcontrol = 0;
636 s->serial_config = 0;
637
638 omap_sti_interrupt_update(s);
639}
640
641static uint32_t omap_sti_read(void *opaque, target_phys_addr_t addr)
642{
643 struct omap_sti_s *s = (struct omap_sti_s *) opaque;
644
645 switch (addr) {
646 case 0x00:
647 return 0x10;
648
649 case 0x10:
650 return s->sysconfig;
651
652 case 0x14:
653 return 0x00;
654
655 case 0x18:
656 return s->irqst;
657
658 case 0x1c:
659 return s->irqen;
660
661 case 0x24:
662 case 0x28:
663
664 return 0;
665
666 case 0x2c:
667 return s->clkcontrol;
668
669 case 0x30:
670 return s->serial_config;
671 }
672
673 OMAP_BAD_REG(addr);
674 return 0;
675}
676
677static void omap_sti_write(void *opaque, target_phys_addr_t addr,
678 uint32_t value)
679{
680 struct omap_sti_s *s = (struct omap_sti_s *) opaque;
681
682 switch (addr) {
683 case 0x00:
684 case 0x14:
685 OMAP_RO_REG(addr);
686 return;
687
688 case 0x10:
689 if (value & (1 << 1))
690 omap_sti_reset(s);
691 s->sysconfig = value & 0xfe;
692 break;
693
694 case 0x18:
695 s->irqst &= ~value;
696 omap_sti_interrupt_update(s);
697 break;
698
699 case 0x1c:
700 s->irqen = value & 0xffff;
701 omap_sti_interrupt_update(s);
702 break;
703
704 case 0x2c:
705 s->clkcontrol = value & 0xff;
706 break;
707
708 case 0x30:
709 s->serial_config = value & 0xff;
710 break;
711
712 case 0x24:
713 case 0x28:
714
715 return;
716
717 default:
718 OMAP_BAD_REG(addr);
719 return;
720 }
721}
722
723static CPUReadMemoryFunc * const omap_sti_readfn[] = {
724 omap_badwidth_read32,
725 omap_badwidth_read32,
726 omap_sti_read,
727};
728
729static CPUWriteMemoryFunc * const omap_sti_writefn[] = {
730 omap_badwidth_write32,
731 omap_badwidth_write32,
732 omap_sti_write,
733};
734
735static uint32_t omap_sti_fifo_read(void *opaque, target_phys_addr_t addr)
736{
737 OMAP_BAD_REG(addr);
738 return 0;
739}
740
741static void omap_sti_fifo_write(void *opaque, target_phys_addr_t addr,
742 uint32_t value)
743{
744 struct omap_sti_s *s = (struct omap_sti_s *) opaque;
745 int ch = addr >> 6;
746 uint8_t byte = value;
747
748 if (ch == STI_TRACE_CONTROL_CHANNEL) {
749
750 qemu_chr_write(s->chr, (const uint8_t *) "\r", 1);
751 } else if (ch == STI_TRACE_CONSOLE_CHANNEL || 1) {
752 if (value == 0xc0 || value == 0xc3) {
753
754 } else if (value == 0x00)
755 qemu_chr_write(s->chr, (const uint8_t *) "\n", 1);
756 else
757 qemu_chr_write(s->chr, &byte, 1);
758 }
759}
760
761static CPUReadMemoryFunc * const omap_sti_fifo_readfn[] = {
762 omap_sti_fifo_read,
763 omap_badwidth_read8,
764 omap_badwidth_read8,
765};
766
767static CPUWriteMemoryFunc * const omap_sti_fifo_writefn[] = {
768 omap_sti_fifo_write,
769 omap_badwidth_write8,
770 omap_badwidth_write8,
771};
772
773static struct omap_sti_s *omap_sti_init(struct omap_target_agent_s *ta,
774 target_phys_addr_t channel_base, qemu_irq irq, omap_clk clk,
775 CharDriverState *chr)
776{
777 int iomemtype;
778 struct omap_sti_s *s = (struct omap_sti_s *)
779 qemu_mallocz(sizeof(struct omap_sti_s));
780
781 s->irq = irq;
782 omap_sti_reset(s);
783
784 s->chr = chr ?: qemu_chr_open("null", "null", NULL);
785
786 iomemtype = l4_register_io_memory(omap_sti_readfn,
787 omap_sti_writefn, s);
788 omap_l4_attach(ta, 0, iomemtype);
789
790 iomemtype = cpu_register_io_memory(omap_sti_fifo_readfn,
791 omap_sti_fifo_writefn, s, DEVICE_NATIVE_ENDIAN);
792 cpu_register_physical_memory(channel_base, 0x10000, iomemtype);
793
794 return s;
795}
796
797
798#define L4TA(n) (n)
799#define L4TAO(n) ((n) + 39)
800
801static const struct omap_l4_region_s omap_l4_region[125] = {
802 [ 1] = { 0x40800, 0x800, 32 },
803 [ 2] = { 0x41000, 0x1000, 32 },
804 [ 0] = { 0x40000, 0x800, 32 },
805 [ 3] = { 0x00000, 0x1000, 32 | 16 | 8 },
806 [ 4] = { 0x01000, 0x1000, 32 | 16 | 8 },
807 [ 5] = { 0x04000, 0x1000, 32 | 16 },
808 [ 6] = { 0x05000, 0x1000, 32 | 16 | 8 },
809 [ 7] = { 0x08000, 0x800, 32 },
810 [ 8] = { 0x08800, 0x800, 32 },
811 [ 9] = { 0x09000, 0x1000, 32 | 16 | 8 },
812 [ 10] = { 0x12000, 0x1000, 32 | 16 | 8 },
813 [ 11] = { 0x13000, 0x1000, 32 | 16 | 8 },
814 [ 12] = { 0x14000, 0x1000, 32 },
815 [ 13] = { 0x15000, 0x1000, 32 | 16 | 8 },
816 [ 14] = { 0x18000, 0x1000, 32 | 16 | 8 },
817 [ 16] = { 0x1a000, 0x1000, 32 | 16 | 8 },
818 [ 18] = { 0x1c000, 0x1000, 32 | 16 | 8 },
819 [ 19] = { 0x1e000, 0x1000, 32 | 16 | 8 },
820 [ 15] = { 0x19000, 0x1000, 32 | 16 | 8 },
821 [ 17] = { 0x1b000, 0x1000, 32 | 16 | 8 },
822 [ 20] = { 0x20000, 0x1000, 32 | 16 | 8 },
823 [ 22] = { 0x22000, 0x1000, 32 | 16 | 8 },
824 [ 21] = { 0x21000, 0x1000, 32 | 16 | 8 },
825 [ 23] = { 0x23000, 0x1000, 32 | 16 | 8 },
826 [ 24] = { 0x28000, 0x1000, 32 | 16 | 8 },
827 [ 25] = { 0x29000, 0x1000, 32 | 16 | 8 },
828 [ 26] = { 0x48000, 0x2000, 32 | 16 | 8 },
829 [ 27] = { 0x4a000, 0x1000, 32 | 16 | 8 },
830 [ 28] = { 0x50000, 0x400, 32 | 16 | 8 },
831 [ 29] = { 0x50400, 0x400, 32 | 16 | 8 },
832 [ 30] = { 0x50800, 0x400, 32 | 16 | 8 },
833 [ 31] = { 0x50c00, 0x400, 32 | 16 | 8 },
834 [ 32] = { 0x51000, 0x1000, 32 | 16 | 8 },
835 [ 33] = { 0x52000, 0x400, 32 | 16 | 8 },
836 [ 34] = { 0x52400, 0x400, 32 | 16 | 8 },
837 [ 35] = { 0x52800, 0x400, 32 | 16 | 8 },
838 [ 36] = { 0x52c00, 0x400, 32 | 16 | 8 },
839 [ 37] = { 0x53000, 0x1000, 32 | 16 | 8 },
840 [ 38] = { 0x56000, 0x1000, 32 | 16 | 8 },
841 [ 39] = { 0x57000, 0x1000, 32 | 16 | 8 },
842 [ 40] = { 0x58000, 0x1000, 32 | 16 | 8 },
843 [ 41] = { 0x59000, 0x1000, 32 | 16 | 8 },
844 [ 42] = { 0x5a000, 0x1000, 32 | 16 | 8 },
845 [ 43] = { 0x5b000, 0x1000, 32 | 16 | 8 },
846 [ 44] = { 0x5c000, 0x1000, 32 | 16 | 8 },
847 [ 45] = { 0x5e000, 0x1000, 32 | 16 | 8 },
848 [ 46] = { 0x5f000, 0x1000, 32 | 16 | 8 },
849 [ 47] = { 0x60000, 0x1000, 32 | 16 | 8 },
850 [ 48] = { 0x61000, 0x1000, 32 | 16 | 8 },
851 [ 49] = { 0x62000, 0x1000, 32 | 16 | 8 },
852 [ 50] = { 0x63000, 0x1000, 32 | 16 | 8 },
853 [ 51] = { 0x64000, 0x1000, 32 | 16 | 8 },
854 [ 52] = { 0x65000, 0x1000, 32 | 16 | 8 },
855 [ 53] = { 0x66000, 0x300, 32 | 16 | 8 },
856 [ 54] = { 0x67000, 0x1000, 32 | 16 | 8 },
857 [ 55] = { 0x68000, 0x1000, 32 | 16 | 8 },
858 [ 56] = { 0x69000, 0x1000, 32 | 16 | 8 },
859 [ 57] = { 0x6a000, 0x1000, 16 | 8 },
860 [ 58] = { 0x6b000, 0x1000, 32 | 16 | 8 },
861 [ 59] = { 0x6c000, 0x1000, 16 | 8 },
862 [ 60] = { 0x6d000, 0x1000, 32 | 16 | 8 },
863 [ 61] = { 0x6e000, 0x1000, 16 | 8 },
864 [ 62] = { 0x6f000, 0x1000, 32 | 16 | 8 },
865 [ 63] = { 0x70000, 0x1000, 16 },
866 [ 64] = { 0x71000, 0x1000, 32 | 16 | 8 },
867 [ 65] = { 0x72000, 0x1000, 16 },
868 [ 66] = { 0x73000, 0x1000, 32 | 16 | 8 },
869 [ 67] = { 0x74000, 0x1000, 16 },
870 [ 68] = { 0x75000, 0x1000, 32 | 16 | 8 },
871 [ 69] = { 0x76000, 0x1000, 16 },
872 [ 70] = { 0x77000, 0x1000, 32 | 16 | 8 },
873 [ 71] = { 0x24000, 0x1000, 32 | 16 | 8 },
874 [ 72] = { 0x25000, 0x1000, 32 | 16 | 8 },
875 [ 73] = { 0x26000, 0x1000, 32 | 16 | 8 },
876 [ 74] = { 0x27000, 0x1000, 32 | 16 | 8 },
877 [ 75] = { 0x2a000, 0x1000, 32 | 16 | 8 },
878 [ 76] = { 0x2b000, 0x1000, 32 | 16 | 8 },
879 [ 77] = { 0x78000, 0x1000, 32 | 16 | 8 },
880 [ 78] = { 0x79000, 0x1000, 32 | 16 | 8 },
881 [ 79] = { 0x7a000, 0x1000, 32 | 16 | 8 },
882 [ 80] = { 0x7b000, 0x1000, 32 | 16 | 8 },
883 [ 81] = { 0x7c000, 0x1000, 32 | 16 | 8 },
884 [ 82] = { 0x7d000, 0x1000, 32 | 16 | 8 },
885 [ 83] = { 0x7e000, 0x1000, 32 | 16 | 8 },
886 [ 84] = { 0x7f000, 0x1000, 32 | 16 | 8 },
887 [ 85] = { 0x80000, 0x1000, 32 | 16 | 8 },
888 [ 86] = { 0x81000, 0x1000, 32 | 16 | 8 },
889 [ 87] = { 0x82000, 0x1000, 32 | 16 | 8 },
890 [ 88] = { 0x83000, 0x1000, 32 | 16 | 8 },
891 [ 89] = { 0x84000, 0x1000, 32 | 16 | 8 },
892 [ 90] = { 0x85000, 0x1000, 32 | 16 | 8 },
893 [ 91] = { 0x86000, 0x1000, 32 | 16 | 8 },
894 [ 92] = { 0x87000, 0x1000, 32 | 16 | 8 },
895 [ 93] = { 0x88000, 0x1000, 32 | 16 | 8 },
896 [ 94] = { 0x89000, 0x1000, 32 | 16 | 8 },
897 [ 95] = { 0x8a000, 0x1000, 32 | 16 | 8 },
898 [ 96] = { 0x8b000, 0x1000, 32 | 16 | 8 },
899 [ 97] = { 0x90000, 0x1000, 16 },
900 [ 98] = { 0x91000, 0x1000, 32 | 16 | 8 },
901 [ 99] = { 0x92000, 0x1000, 16 },
902 [100] = { 0x93000, 0x1000, 32 | 16 | 8 },
903 [101] = { 0x94000, 0x1000, 32 | 16 | 8 },
904 [102] = { 0x95000, 0x1000, 32 | 16 | 8 },
905 [103] = { 0x98000, 0x1000, 32 | 16 | 8 },
906 [104] = { 0x99000, 0x1000, 32 | 16 | 8 },
907 [105] = { 0x9a000, 0x1000, 32 | 16 | 8 },
908 [106] = { 0x9b000, 0x1000, 32 | 16 | 8 },
909 [107] = { 0x9c000, 0x1000, 16 | 8 },
910 [108] = { 0x9d000, 0x1000, 32 | 16 | 8 },
911 [109] = { 0x9e000, 0x1000, 32 | 16 | 8 },
912 [110] = { 0x9f000, 0x1000, 32 | 16 | 8 },
913 [111] = { 0xa0000, 0x1000, 32 },
914 [112] = { 0xa1000, 0x1000, 32 | 16 | 8 },
915 [113] = { 0xa2000, 0x1000, 32 },
916 [114] = { 0xa3000, 0x1000, 32 | 16 | 8 },
917 [115] = { 0xa4000, 0x1000, 32 },
918 [116] = { 0xa5000, 0x1000, 32 | 16 | 8 },
919 [117] = { 0xa6000, 0x1000, 32 },
920 [118] = { 0xa7000, 0x1000, 32 | 16 | 8 },
921 [119] = { 0xa8000, 0x2000, 32 },
922 [120] = { 0xaa000, 0x1000, 32 | 16 | 8 },
923 [121] = { 0xb0000, 0x1000, 32 },
924 [122] = { 0xb1000, 0x1000, 32 | 16 | 8 },
925 [123] = { 0xb2000, 0x1000, 32 },
926 [124] = { 0xb3000, 0x1000, 32 | 16 | 8 },
927};
928
929static const struct omap_l4_agent_info_s omap_l4_agent_info[54] = {
930 { 0, 0, 3, 2 },
931 { L4TAO(1), 3, 2, 1 },
932 { L4TAO(2), 5, 2, 1 },
933 { L4TAO(3), 7, 3, 2 },
934 { L4TA(1), 10, 2, 1 },
935 { L4TA(2), 12, 2, 1 },
936 { L4TA(3), 14, 6, 3 },
937 { L4TA(4), 20, 4, 3 },
938 { L4TA(7), 24, 2, 1 },
939 { L4TA(9), 26, 2, 1 },
940 { L4TA(10), 28, 5, 4 },
941 { L4TA(11), 33, 5, 4 },
942 { L4TA(12), 38, 2, 1 },
943 { L4TA(13), 40, 5, 4 },
944 { L4TAO(4), 45, 2, 1 },
945 { L4TA(14), 47, 2, 1 },
946 { L4TA(15), 49, 2, 1 },
947 { L4TA(16), 51, 2, 1 },
948 { L4TA(17), 53, 2, 1 },
949 { L4TA(18), 55, 2, 1 },
950 { L4TA(19), 57, 2, 1 },
951 { L4TA(20), 59, 2, 1 },
952 { L4TA(21), 61, 2, 1 },
953 { L4TAO(5), 63, 2, 1 },
954 { L4TAO(6), 65, 2, 1 },
955 { L4TAO(7), 67, 2, 1 },
956 { L4TAO(8), 69, 2, 1 },
957 { L4TA(5), 71, 2, 1 },
958 { L4TA(6), 73, 2, 1 },
959 { L4TA(8), 75, 2, 1 },
960 { L4TA(22), 77, 2, 1 },
961 { L4TA(23), 79, 2, 1 },
962 { L4TA(24), 81, 2, 1 },
963 { L4TA(25), 83, 2, 1 },
964 { L4TA(26), 85, 2, 1 },
965 { L4TA(27), 87, 2, 1 },
966 { L4TA(28), 89, 2, 1 },
967 { L4TA(29), 91, 2, 1 },
968 { L4TA(30), 93, 2, 1 },
969 { L4TA(31), 95, 2, 1 },
970 { L4TA(32), 97, 2, 1 },
971 { L4TA(33), 99, 2, 1 },
972 { L4TA(34), 101, 2, 1 },
973 { L4TA(35), 103, 2, 1 },
974 { L4TA(36), 105, 2, 1 },
975 { L4TAO(9), 107, 2, 1 },
976 { L4TAO(10), 109, 2, 1 },
977 { L4TAO(11), 111, 2, 1 },
978 { L4TAO(12), 113, 2, 1 },
979 { L4TAO(13), 115, 2, 1 },
980 { L4TA(37), 117, 2, 1 },
981 { L4TA(38), 119, 2, 1 },
982 { -1, 121, 2, 1 },
983 { L4TA(39), 123, 2, 1 },
984};
985
986#define omap_l4ta(bus, cs) \
987 omap_l4ta_get(bus, omap_l4_region, omap_l4_agent_info, L4TA(cs))
988#define omap_l4tao(bus, cs) \
989 omap_l4ta_get(bus, omap_l4_region, omap_l4_agent_info, L4TAO(cs))
990
991
992struct omap_prcm_s {
993 qemu_irq irq[3];
994 struct omap_mpu_state_s *mpu;
995
996 uint32_t irqst[3];
997 uint32_t irqen[3];
998
999 uint32_t sysconfig;
1000 uint32_t voltctrl;
1001 uint32_t scratch[20];
1002
1003 uint32_t clksrc[1];
1004 uint32_t clkout[1];
1005 uint32_t clkemul[1];
1006 uint32_t clkpol[1];
1007 uint32_t clksel[8];
1008 uint32_t clken[12];
1009 uint32_t clkctrl[4];
1010 uint32_t clkidle[7];
1011 uint32_t setuptime[2];
1012
1013 uint32_t wkup[3];
1014 uint32_t wken[3];
1015 uint32_t wkst[3];
1016 uint32_t rst[4];
1017 uint32_t rstctrl[1];
1018 uint32_t power[4];
1019 uint32_t rsttime_wkup;
1020
1021 uint32_t ev;
1022 uint32_t evtime[2];
1023
1024 int dpll_lock, apll_lock[2];
1025};
1026
1027static void omap_prcm_int_update(struct omap_prcm_s *s, int dom)
1028{
1029 qemu_set_irq(s->irq[dom], s->irqst[dom] & s->irqen[dom]);
1030
1031}
1032
1033static uint32_t omap_prcm_read(void *opaque, target_phys_addr_t addr)
1034{
1035 struct omap_prcm_s *s = (struct omap_prcm_s *) opaque;
1036 uint32_t ret;
1037
1038 switch (addr) {
1039 case 0x000:
1040 return 0x10;
1041
1042 case 0x010:
1043 return s->sysconfig;
1044
1045 case 0x018:
1046 return s->irqst[0];
1047
1048 case 0x01c:
1049 return s->irqen[0];
1050
1051 case 0x050:
1052 return s->voltctrl;
1053 case 0x054:
1054 return s->voltctrl & 3;
1055
1056 case 0x060:
1057 return s->clksrc[0];
1058 case 0x070:
1059 return s->clkout[0];
1060 case 0x078:
1061 return s->clkemul[0];
1062 case 0x080:
1063 case 0x084:
1064 return 0;
1065
1066 case 0x090:
1067 return s->setuptime[0];
1068
1069 case 0x094:
1070 return s->setuptime[1];
1071
1072 case 0x098:
1073 return s->clkpol[0];
1074
1075 case 0x0b0:
1076 case 0x0b4:
1077 case 0x0b8:
1078 case 0x0bc:
1079 case 0x0c0:
1080 case 0x0c4:
1081 case 0x0c8:
1082 case 0x0cc:
1083 case 0x0d0:
1084 case 0x0d4:
1085 case 0x0d8:
1086 case 0x0dc:
1087 case 0x0e0:
1088 case 0x0e4:
1089 case 0x0e8:
1090 case 0x0ec:
1091 case 0x0f0:
1092 case 0x0f4:
1093 case 0x0f8:
1094 case 0x0fc:
1095 return s->scratch[(addr - 0xb0) >> 2];
1096
1097 case 0x140:
1098 return s->clksel[0];
1099 case 0x148:
1100 return s->clkctrl[0];
1101
1102 case 0x158:
1103 return s->rst[0];
1104 case 0x1c8:
1105 return s->wkup[0];
1106 case 0x1d4:
1107 return s->ev;
1108 case 0x1d8:
1109 return s->evtime[0];
1110 case 0x1dc:
1111 return s->evtime[1];
1112 case 0x1e0:
1113 return s->power[0];
1114 case 0x1e4:
1115 return 0;
1116
1117 case 0x200:
1118 return s->clken[0];
1119 case 0x204:
1120 return s->clken[1];
1121 case 0x210:
1122 return s->clken[2];
1123 case 0x214:
1124 return s->clken[3];
1125 case 0x21c:
1126 return s->clken[4];
1127
1128 case 0x220:
1129
1130 return 0x7ffffff9;
1131 case 0x224:
1132
1133 return 0x00000007;
1134 case 0x22c:
1135
1136 return 0x0000001f;
1137
1138 case 0x230:
1139 return s->clkidle[0];
1140 case 0x234:
1141 return s->clkidle[1];
1142 case 0x238:
1143 return s->clkidle[2];
1144 case 0x23c:
1145 return s->clkidle[3];
1146
1147 case 0x240:
1148 return s->clksel[1];
1149 case 0x244:
1150 return s->clksel[2];
1151
1152 case 0x248:
1153 return s->clkctrl[1];
1154
1155 case 0x2a0:
1156 return s->wken[0];
1157 case 0x2a4:
1158 return s->wken[1];
1159
1160 case 0x2b0:
1161 return s->wkst[0];
1162 case 0x2b4:
1163 return s->wkst[1];
1164 case 0x2c8:
1165 return 0x1e;
1166
1167 case 0x2e0:
1168 return s->power[1];
1169 case 0x2e4:
1170 return 0x000030 | (s->power[1] & 0xfc00);
1171
1172 case 0x300:
1173 return s->clken[5];
1174 case 0x310:
1175 return s->clken[6];
1176 case 0x320:
1177
1178 return 0x00000001;
1179 case 0x340:
1180 return s->clksel[3];
1181 case 0x348:
1182 return s->clkctrl[2];
1183 case 0x350:
1184 return s->rstctrl[0];
1185 case 0x358:
1186 return s->rst[1];
1187 case 0x3c8:
1188 return s->wkup[1];
1189
1190 case 0x3e0:
1191 return s->power[2];
1192 case 0x3e4:
1193 return s->power[2] & 3;
1194
1195 case 0x400:
1196 return s->clken[7];
1197 case 0x410:
1198 return s->clken[8];
1199 case 0x420:
1200
1201 return 0x0000003f;
1202 case 0x430:
1203 return s->clkidle[4];
1204 case 0x440:
1205 return s->clksel[4];
1206 case 0x450:
1207 return 0;
1208 case 0x454:
1209 return s->rsttime_wkup;
1210 case 0x458:
1211 return s->rst[2];
1212 case 0x4a0:
1213 return s->wken[2];
1214 case 0x4b0:
1215 return s->wkst[2];
1216
1217 case 0x500:
1218 return s->clken[9];
1219 case 0x520:
1220 ret = 0x0000070 | (s->apll_lock[0] << 9) | (s->apll_lock[1] << 8);
1221 if (!(s->clksel[6] & 3))
1222
1223 ret |= 3 << 0;
1224 else if (!s->dpll_lock)
1225
1226 ret |= 1 << 0;
1227 else
1228
1229 ret |= 2 << 0;
1230 return ret;
1231 case 0x530:
1232 return s->clkidle[5];
1233 case 0x540:
1234 return s->clksel[5];
1235 case 0x544:
1236 return s->clksel[6];
1237
1238 case 0x800:
1239 return s->clken[10];
1240 case 0x810:
1241 return s->clken[11];
1242 case 0x820:
1243
1244 return 0x00000103;
1245 case 0x830:
1246 return s->clkidle[6];
1247 case 0x840:
1248 return s->clksel[7];
1249 case 0x848:
1250 return s->clkctrl[3];
1251 case 0x850:
1252 return 0;
1253 case 0x858:
1254 return s->rst[3];
1255 case 0x8c8:
1256 return s->wkup[2];
1257 case 0x8e0:
1258 return s->power[3];
1259 case 0x8e4:
1260 return 0x008030 | (s->power[3] & 0x3003);
1261
1262 case 0x8f0:
1263 return s->irqst[1];
1264 case 0x8f4:
1265 return s->irqen[1];
1266
1267 case 0x8f8:
1268 return s->irqst[2];
1269 case 0x8fc:
1270 return s->irqen[2];
1271 }
1272
1273 OMAP_BAD_REG(addr);
1274 return 0;
1275}
1276
1277static void omap_prcm_apll_update(struct omap_prcm_s *s)
1278{
1279 int mode[2];
1280
1281 mode[0] = (s->clken[9] >> 6) & 3;
1282 s->apll_lock[0] = (mode[0] == 3);
1283 mode[1] = (s->clken[9] >> 2) & 3;
1284 s->apll_lock[1] = (mode[1] == 3);
1285
1286
1287 if (mode[0] == 1 || mode[0] == 2 || mode[1] == 1 || mode[1] == 2)
1288 fprintf(stderr, "%s: bad EN_54M_PLL or bad EN_96M_PLL\n",
1289 __FUNCTION__);
1290}
1291
1292static void omap_prcm_dpll_update(struct omap_prcm_s *s)
1293{
1294 omap_clk dpll = omap_findclk(s->mpu, "dpll");
1295 omap_clk dpll_x2 = omap_findclk(s->mpu, "dpll");
1296 omap_clk core = omap_findclk(s->mpu, "core_clk");
1297 int mode = (s->clken[9] >> 0) & 3;
1298 int mult, div;
1299
1300 mult = (s->clksel[5] >> 12) & 0x3ff;
1301 div = (s->clksel[5] >> 8) & 0xf;
1302 if (mult == 0 || mult == 1)
1303 mode = 1;
1304
1305 s->dpll_lock = 0;
1306 switch (mode) {
1307 case 0:
1308 fprintf(stderr, "%s: bad EN_DPLL\n", __FUNCTION__);
1309 break;
1310 case 1:
1311 case 2:
1312 omap_clk_setrate(dpll, 1, 1);
1313 omap_clk_setrate(dpll_x2, 1, 1);
1314 break;
1315 case 3:
1316 s->dpll_lock = 1;
1317
1318 omap_clk_setrate(dpll, div + 1, mult);
1319 omap_clk_setrate(dpll_x2, div + 1, mult * 2);
1320 break;
1321 }
1322
1323 switch ((s->clksel[6] >> 0) & 3) {
1324 case 0:
1325 omap_clk_reparent(core, omap_findclk(s->mpu, "clk32-kHz"));
1326 break;
1327 case 1:
1328 omap_clk_reparent(core, dpll);
1329 break;
1330 case 2:
1331
1332 omap_clk_reparent(core, dpll_x2);
1333 break;
1334 case 3:
1335 fprintf(stderr, "%s: bad CORE_CLK_SRC\n", __FUNCTION__);
1336 break;
1337 }
1338}
1339
1340static void omap_prcm_write(void *opaque, target_phys_addr_t addr,
1341 uint32_t value)
1342{
1343 struct omap_prcm_s *s = (struct omap_prcm_s *) opaque;
1344
1345 switch (addr) {
1346 case 0x000:
1347 case 0x054:
1348 case 0x084:
1349 case 0x1e4:
1350 case 0x220:
1351 case 0x224:
1352 case 0x22c:
1353 case 0x2c8:
1354 case 0x2e4:
1355 case 0x320:
1356 case 0x3e4:
1357 case 0x420:
1358 case 0x520:
1359 case 0x820:
1360 case 0x8e4:
1361 OMAP_RO_REG(addr);
1362 return;
1363
1364 case 0x010:
1365 s->sysconfig = value & 1;
1366 break;
1367
1368 case 0x018:
1369 s->irqst[0] &= ~value;
1370 omap_prcm_int_update(s, 0);
1371 break;
1372 case 0x01c:
1373 s->irqen[0] = value & 0x3f;
1374 omap_prcm_int_update(s, 0);
1375 break;
1376
1377 case 0x050:
1378 s->voltctrl = value & 0xf1c3;
1379 break;
1380
1381 case 0x060:
1382 s->clksrc[0] = value & 0xdb;
1383
1384 break;
1385
1386 case 0x070:
1387 s->clkout[0] = value & 0xbbbb;
1388
1389 break;
1390
1391 case 0x078:
1392 s->clkemul[0] = value & 1;
1393
1394 break;
1395
1396 case 0x080:
1397 break;
1398
1399 case 0x090:
1400 s->setuptime[0] = value & 0xffff;
1401 break;
1402 case 0x094:
1403 s->setuptime[1] = value & 0xffff;
1404 break;
1405
1406 case 0x098:
1407 s->clkpol[0] = value & 0x701;
1408 break;
1409
1410 case 0x0b0:
1411 case 0x0b4:
1412 case 0x0b8:
1413 case 0x0bc:
1414 case 0x0c0:
1415 case 0x0c4:
1416 case 0x0c8:
1417 case 0x0cc:
1418 case 0x0d0:
1419 case 0x0d4:
1420 case 0x0d8:
1421 case 0x0dc:
1422 case 0x0e0:
1423 case 0x0e4:
1424 case 0x0e8:
1425 case 0x0ec:
1426 case 0x0f0:
1427 case 0x0f4:
1428 case 0x0f8:
1429 case 0x0fc:
1430 s->scratch[(addr - 0xb0) >> 2] = value;
1431 break;
1432
1433 case 0x140:
1434 s->clksel[0] = value & 0x1f;
1435
1436 break;
1437 case 0x148:
1438 s->clkctrl[0] = value & 0x1f;
1439 break;
1440
1441 case 0x158:
1442 s->rst[0] &= ~value;
1443 break;
1444 case 0x1c8:
1445 s->wkup[0] = value & 0x15;
1446 break;
1447
1448 case 0x1d4:
1449 s->ev = value & 0x1f;
1450 break;
1451 case 0x1d8:
1452 s->evtime[0] = value;
1453 break;
1454 case 0x1dc:
1455 s->evtime[1] = value;
1456 break;
1457
1458 case 0x1e0:
1459 s->power[0] = value & 0xc0f;
1460 break;
1461
1462 case 0x200:
1463 s->clken[0] = value & 0xbfffffff;
1464
1465
1466 break;
1467 case 0x204:
1468 s->clken[1] = value & 0x00000007;
1469
1470 break;
1471 case 0x210:
1472 s->clken[2] = value & 0xfffffff9;
1473
1474
1475 break;
1476 case 0x214:
1477 s->clken[3] = value & 0x00000007;
1478
1479 break;
1480 case 0x21c:
1481 s->clken[4] = value & 0x0000001f;
1482
1483 break;
1484
1485 case 0x230:
1486 s->clkidle[0] = value & 0xfffffff9;
1487
1488 break;
1489 case 0x234:
1490 s->clkidle[1] = value & 0x00000007;
1491
1492 break;
1493 case 0x238:
1494 s->clkidle[2] = value & 0x00000007;
1495
1496 break;
1497 case 0x23c:
1498 s->clkidle[3] = value & 0x0000001f;
1499
1500 break;
1501
1502 case 0x240:
1503 s->clksel[1] = value & 0x0fffbf7f;
1504
1505 break;
1506
1507 case 0x244:
1508 s->clksel[2] = value & 0x00fffffc;
1509
1510 break;
1511
1512 case 0x248:
1513 s->clkctrl[1] = value & 0x7;
1514 break;
1515
1516 case 0x2a0:
1517 s->wken[0] = value & 0x04667ff8;
1518 break;
1519 case 0x2a4:
1520 s->wken[1] = value & 0x00000005;
1521 break;
1522
1523 case 0x2b0:
1524 s->wkst[0] &= ~value;
1525 break;
1526 case 0x2b4:
1527 s->wkst[1] &= ~value;
1528 break;
1529
1530 case 0x2e0:
1531 s->power[1] = (value & 0x00fc3f) | (1 << 2);
1532 break;
1533
1534 case 0x300:
1535 s->clken[5] = value & 6;
1536
1537 break;
1538 case 0x310:
1539 s->clken[6] = value & 1;
1540
1541 break;
1542 case 0x340:
1543 s->clksel[3] = value & 7;
1544
1545 break;
1546 case 0x348:
1547 s->clkctrl[2] = value & 1;
1548 break;
1549 case 0x350:
1550 s->rstctrl[0] = value & 1;
1551
1552 break;
1553 case 0x358:
1554 s->rst[1] &= ~value;
1555 break;
1556 case 0x3c8:
1557 s->wkup[1] = value & 0x13;
1558 break;
1559 case 0x3e0:
1560 s->power[2] = (value & 0x00c0f) | (3 << 2);
1561 break;
1562
1563 case 0x400:
1564 s->clken[7] = value & 0xd;
1565
1566 break;
1567 case 0x410:
1568 s->clken[8] = value & 0x3f;
1569
1570 break;
1571 case 0x430:
1572 s->clkidle[4] = value & 0x0000003f;
1573
1574 break;
1575 case 0x440:
1576 s->clksel[4] = value & 3;
1577
1578 break;
1579 case 0x450:
1580
1581 if (value & 2)
1582 qemu_system_reset_request();
1583 break;
1584 case 0x454:
1585 s->rsttime_wkup = value & 0x1fff;
1586 break;
1587 case 0x458:
1588 s->rst[2] &= ~value;
1589 break;
1590 case 0x4a0:
1591 s->wken[2] = value & 0x00000005;
1592 break;
1593 case 0x4b0:
1594 s->wkst[2] &= ~value;
1595 break;
1596
1597 case 0x500:
1598 if (value & 0xffffff30)
1599 fprintf(stderr, "%s: write 0s in CM_CLKEN_PLL for "
1600 "future compatiblity\n", __FUNCTION__);
1601 if ((s->clken[9] ^ value) & 0xcc) {
1602 s->clken[9] &= ~0xcc;
1603 s->clken[9] |= value & 0xcc;
1604 omap_prcm_apll_update(s);
1605 }
1606 if ((s->clken[9] ^ value) & 3) {
1607 s->clken[9] &= ~3;
1608 s->clken[9] |= value & 3;
1609 omap_prcm_dpll_update(s);
1610 }
1611 break;
1612 case 0x530:
1613 s->clkidle[5] = value & 0x000000cf;
1614
1615 break;
1616 case 0x540:
1617 if (value & 0xfc4000d7)
1618 fprintf(stderr, "%s: write 0s in CM_CLKSEL1_PLL for "
1619 "future compatiblity\n", __FUNCTION__);
1620 if ((s->clksel[5] ^ value) & 0x003fff00) {
1621 s->clksel[5] = value & 0x03bfff28;
1622 omap_prcm_dpll_update(s);
1623 }
1624
1625
1626 s->clksel[5] = value & 0x03bfff28;
1627 break;
1628 case 0x544:
1629 if (value & ~3)
1630 fprintf(stderr, "%s: write 0s in CM_CLKSEL2_PLL[31:2] for "
1631 "future compatiblity\n", __FUNCTION__);
1632 if (s->clksel[6] != (value & 3)) {
1633 s->clksel[6] = value & 3;
1634 omap_prcm_dpll_update(s);
1635 }
1636 break;
1637
1638 case 0x800:
1639 s->clken[10] = value & 0x501;
1640
1641 break;
1642 case 0x810:
1643 s->clken[11] = value & 0x2;
1644
1645 break;
1646 case 0x830:
1647 s->clkidle[6] = value & 0x2;
1648
1649 break;
1650 case 0x840:
1651 s->clksel[7] = value & 0x3fff;
1652
1653 break;
1654 case 0x848:
1655 s->clkctrl[3] = value & 0x101;
1656 break;
1657 case 0x850:
1658
1659 break;
1660 case 0x858:
1661 s->rst[3] &= ~value;
1662 break;
1663 case 0x8c8:
1664 s->wkup[2] = value & 0x13;
1665 break;
1666 case 0x8e0:
1667 s->power[3] = (value & 0x03017) | (3 << 2);
1668 break;
1669
1670 case 0x8f0:
1671 s->irqst[1] &= ~value;
1672 omap_prcm_int_update(s, 1);
1673 break;
1674 case 0x8f4:
1675 s->irqen[1] = value & 0x7;
1676 omap_prcm_int_update(s, 1);
1677 break;
1678
1679 case 0x8f8:
1680 s->irqst[2] &= ~value;
1681 omap_prcm_int_update(s, 2);
1682 break;
1683 case 0x8fc:
1684 s->irqen[2] = value & 0x7;
1685 omap_prcm_int_update(s, 2);
1686 break;
1687
1688 default:
1689 OMAP_BAD_REG(addr);
1690 return;
1691 }
1692}
1693
1694static CPUReadMemoryFunc * const omap_prcm_readfn[] = {
1695 omap_badwidth_read32,
1696 omap_badwidth_read32,
1697 omap_prcm_read,
1698};
1699
1700static CPUWriteMemoryFunc * const omap_prcm_writefn[] = {
1701 omap_badwidth_write32,
1702 omap_badwidth_write32,
1703 omap_prcm_write,
1704};
1705
1706static void omap_prcm_reset(struct omap_prcm_s *s)
1707{
1708 s->sysconfig = 0;
1709 s->irqst[0] = 0;
1710 s->irqst[1] = 0;
1711 s->irqst[2] = 0;
1712 s->irqen[0] = 0;
1713 s->irqen[1] = 0;
1714 s->irqen[2] = 0;
1715 s->voltctrl = 0x1040;
1716 s->ev = 0x14;
1717 s->evtime[0] = 0;
1718 s->evtime[1] = 0;
1719 s->clkctrl[0] = 0;
1720 s->clkctrl[1] = 0;
1721 s->clkctrl[2] = 0;
1722 s->clkctrl[3] = 0;
1723 s->clken[1] = 7;
1724 s->clken[3] = 7;
1725 s->clken[4] = 0;
1726 s->clken[5] = 0;
1727 s->clken[6] = 0;
1728 s->clken[7] = 0xc;
1729 s->clken[8] = 0x3e;
1730 s->clken[9] = 0x0d;
1731 s->clken[10] = 0;
1732 s->clken[11] = 0;
1733 s->clkidle[0] = 0;
1734 s->clkidle[2] = 7;
1735 s->clkidle[3] = 0;
1736 s->clkidle[4] = 0;
1737 s->clkidle[5] = 0x0c;
1738 s->clkidle[6] = 0;
1739 s->clksel[0] = 0x01;
1740 s->clksel[1] = 0x02100121;
1741 s->clksel[2] = 0x00000000;
1742 s->clksel[3] = 0x01;
1743 s->clksel[4] = 0;
1744 s->clksel[7] = 0x0121;
1745 s->wkup[0] = 0x15;
1746 s->wkup[1] = 0x13;
1747 s->wkup[2] = 0x13;
1748 s->wken[0] = 0x04667ff8;
1749 s->wken[1] = 0x00000005;
1750 s->wken[2] = 5;
1751 s->wkst[0] = 0;
1752 s->wkst[1] = 0;
1753 s->wkst[2] = 0;
1754 s->power[0] = 0x00c;
1755 s->power[1] = 4;
1756 s->power[2] = 0x0000c;
1757 s->power[3] = 0x14;
1758 s->rstctrl[0] = 1;
1759 s->rst[3] = 1;
1760 omap_prcm_apll_update(s);
1761 omap_prcm_dpll_update(s);
1762}
1763
1764static void omap_prcm_coldreset(struct omap_prcm_s *s)
1765{
1766 s->setuptime[0] = 0;
1767 s->setuptime[1] = 0;
1768 memset(&s->scratch, 0, sizeof(s->scratch));
1769 s->rst[0] = 0x01;
1770 s->rst[1] = 0x00;
1771 s->rst[2] = 0x01;
1772 s->clken[0] = 0;
1773 s->clken[2] = 0;
1774 s->clkidle[1] = 0;
1775 s->clksel[5] = 0;
1776 s->clksel[6] = 2;
1777 s->clksrc[0] = 0x43;
1778 s->clkout[0] = 0x0303;
1779 s->clkemul[0] = 0;
1780 s->clkpol[0] = 0x100;
1781 s->rsttime_wkup = 0x1002;
1782
1783 omap_prcm_reset(s);
1784}
1785
1786static struct omap_prcm_s *omap_prcm_init(struct omap_target_agent_s *ta,
1787 qemu_irq mpu_int, qemu_irq dsp_int, qemu_irq iva_int,
1788 struct omap_mpu_state_s *mpu)
1789{
1790 int iomemtype;
1791 struct omap_prcm_s *s = (struct omap_prcm_s *)
1792 qemu_mallocz(sizeof(struct omap_prcm_s));
1793
1794 s->irq[0] = mpu_int;
1795 s->irq[1] = dsp_int;
1796 s->irq[2] = iva_int;
1797 s->mpu = mpu;
1798 omap_prcm_coldreset(s);
1799
1800 iomemtype = l4_register_io_memory(omap_prcm_readfn,
1801 omap_prcm_writefn, s);
1802 omap_l4_attach(ta, 0, iomemtype);
1803 omap_l4_attach(ta, 1, iomemtype);
1804
1805 return s;
1806}
1807
1808
1809struct omap_sysctl_s {
1810 struct omap_mpu_state_s *mpu;
1811
1812 uint32_t sysconfig;
1813 uint32_t devconfig;
1814 uint32_t psaconfig;
1815 uint32_t padconf[0x45];
1816 uint8_t obs;
1817 uint32_t msuspendmux[5];
1818};
1819
1820static uint32_t omap_sysctl_read8(void *opaque, target_phys_addr_t addr)
1821{
1822
1823 struct omap_sysctl_s *s = (struct omap_sysctl_s *) opaque;
1824 int pad_offset, byte_offset;
1825 int value;
1826
1827 switch (addr) {
1828 case 0x030 ... 0x140:
1829 pad_offset = (addr - 0x30) >> 2;
1830 byte_offset = (addr - 0x30) & (4 - 1);
1831
1832 value = s->padconf[pad_offset];
1833 value = (value >> (byte_offset * 8)) & 0xff;
1834
1835 return value;
1836
1837 default:
1838 break;
1839 }
1840
1841 OMAP_BAD_REG(addr);
1842 return 0;
1843}
1844
1845static uint32_t omap_sysctl_read(void *opaque, target_phys_addr_t addr)
1846{
1847 struct omap_sysctl_s *s = (struct omap_sysctl_s *) opaque;
1848
1849 switch (addr) {
1850 case 0x000:
1851 return 0x20;
1852
1853 case 0x010:
1854 return s->sysconfig;
1855
1856 case 0x030 ... 0x140:
1857 return s->padconf[(addr - 0x30) >> 2];
1858
1859 case 0x270:
1860 return s->obs;
1861
1862 case 0x274:
1863 return s->devconfig;
1864
1865 case 0x28c:
1866 return 0;
1867
1868 case 0x290:
1869 return s->msuspendmux[0];
1870 case 0x294:
1871 return s->msuspendmux[1];
1872 case 0x298:
1873 return s->msuspendmux[2];
1874 case 0x29c:
1875 return s->msuspendmux[3];
1876 case 0x2a0:
1877 return s->msuspendmux[4];
1878 case 0x2a4:
1879 return 0;
1880
1881 case 0x2b8:
1882 return s->psaconfig;
1883 case 0x2bc:
1884 case 0x2c0:
1885 return 0;
1886
1887 case 0x2b0:
1888 return 0x800000f1;
1889 case 0x2d0:
1890 return 0x80000015;
1891 case 0x2d4:
1892 return 0x8000007f;
1893 case 0x2b4:
1894 case 0x2f0:
1895 case 0x2f4:
1896
1897
1898 return 0;
1899
1900 case 0x2d8:
1901 return 0xff;
1902 case 0x2dc:
1903 case 0x2e0:
1904 case 0x2e4:
1905
1906 return 0;
1907
1908 case 0x2f8:
1909
1910 return 0x0300;
1911 case 0x2fc:
1912
1913 case 0x300:
1914 case 0x304:
1915 case 0x308:
1916 case 0x30c:
1917 return 0xdecafbad;
1918
1919 case 0x310:
1920 case 0x314:
1921 case 0x318:
1922 case 0x31c:
1923 case 0x320:
1924 case 0x324:
1925 case 0x330:
1926 case 0x334:
1927 case 0x338:
1928 case 0x33c:
1929 case 0x340:
1930 case 0x344:
1931 case 0x348:
1932 case 0x34c:
1933 case 0x350:
1934 case 0x354:
1935
1936
1937
1938 return 0;
1939 }
1940
1941 OMAP_BAD_REG(addr);
1942 return 0;
1943}
1944
1945static void omap_sysctl_write8(void *opaque, target_phys_addr_t addr,
1946 uint32_t value)
1947{
1948 struct omap_sysctl_s *s = (struct omap_sysctl_s *) opaque;
1949 int pad_offset, byte_offset;
1950 int prev_value;
1951
1952 switch (addr) {
1953 case 0x030 ... 0x140:
1954 pad_offset = (addr - 0x30) >> 2;
1955 byte_offset = (addr - 0x30) & (4 - 1);
1956
1957 prev_value = s->padconf[pad_offset];
1958 prev_value &= ~(0xff << (byte_offset * 8));
1959 prev_value |= ((value & 0x1f1f1f1f) << (byte_offset * 8)) & 0x1f1f1f1f;
1960 s->padconf[pad_offset] = prev_value;
1961 break;
1962
1963 default:
1964 OMAP_BAD_REG(addr);
1965 break;
1966 }
1967}
1968
1969static void omap_sysctl_write(void *opaque, target_phys_addr_t addr,
1970 uint32_t value)
1971{
1972 struct omap_sysctl_s *s = (struct omap_sysctl_s *) opaque;
1973
1974 switch (addr) {
1975 case 0x000:
1976 case 0x2a4:
1977 case 0x2c0:
1978 case 0x2f8:
1979 case 0x2fc:
1980 case 0x300:
1981 case 0x304:
1982 case 0x308:
1983 case 0x30c:
1984 case 0x310:
1985 case 0x314:
1986 case 0x318:
1987 case 0x31c:
1988 case 0x320:
1989 case 0x324:
1990 case 0x330:
1991 case 0x334:
1992 case 0x338:
1993 case 0x33c:
1994 case 0x340:
1995 case 0x344:
1996 case 0x348:
1997 case 0x34c:
1998 case 0x350:
1999 case 0x354:
2000 OMAP_RO_REG(addr);
2001 return;
2002
2003 case 0x010:
2004 s->sysconfig = value & 0x1e;
2005 break;
2006
2007 case 0x030 ... 0x140:
2008
2009 s->padconf[(addr - 0x30) >> 2] = value & 0x1f1f1f1f;
2010 break;
2011
2012 case 0x270:
2013 s->obs = value & 0xff;
2014 break;
2015
2016 case 0x274:
2017 s->devconfig = value & 0xffffc7ff;
2018 break;
2019
2020 case 0x28c:
2021 break;
2022
2023 case 0x290:
2024 s->msuspendmux[0] = value & 0x3fffffff;
2025 break;
2026 case 0x294:
2027 s->msuspendmux[1] = value & 0x3fffffff;
2028 break;
2029 case 0x298:
2030 s->msuspendmux[2] = value & 0x3fffffff;
2031 break;
2032 case 0x29c:
2033 s->msuspendmux[3] = value & 0x3fffffff;
2034 break;
2035 case 0x2a0:
2036 s->msuspendmux[4] = value & 0x3fffffff;
2037 break;
2038
2039 case 0x2b8:
2040 s->psaconfig = value & 0x1c;
2041 s->psaconfig |= (value & 0x20) ? 2 : 1;
2042 break;
2043 case 0x2bc:
2044 break;
2045
2046 case 0x2b0:
2047 case 0x2b4:
2048 case 0x2d0:
2049 case 0x2d4:
2050 case 0x2d8:
2051 case 0x2dc:
2052 case 0x2e0:
2053 case 0x2e4:
2054 case 0x2f0:
2055 case 0x2f4:
2056 break;
2057
2058 default:
2059 OMAP_BAD_REG(addr);
2060 return;
2061 }
2062}
2063
2064static CPUReadMemoryFunc * const omap_sysctl_readfn[] = {
2065 omap_sysctl_read8,
2066 omap_badwidth_read32,
2067 omap_sysctl_read,
2068};
2069
2070static CPUWriteMemoryFunc * const omap_sysctl_writefn[] = {
2071 omap_sysctl_write8,
2072 omap_badwidth_write32,
2073 omap_sysctl_write,
2074};
2075
2076static void omap_sysctl_reset(struct omap_sysctl_s *s)
2077{
2078
2079 s->sysconfig = 0;
2080 s->obs = 0;
2081 s->devconfig = 0x0c000000;
2082 s->msuspendmux[0] = 0x00000000;
2083 s->msuspendmux[1] = 0x00000000;
2084 s->msuspendmux[2] = 0x00000000;
2085 s->msuspendmux[3] = 0x00000000;
2086 s->msuspendmux[4] = 0x00000000;
2087 s->psaconfig = 1;
2088
2089 s->padconf[0x00] = 0x000f0f0f;
2090 s->padconf[0x01] = 0x00000000;
2091 s->padconf[0x02] = 0x00000000;
2092 s->padconf[0x03] = 0x00000000;
2093 s->padconf[0x04] = 0x00000000;
2094 s->padconf[0x05] = 0x00000000;
2095 s->padconf[0x06] = 0x00000000;
2096 s->padconf[0x07] = 0x00000000;
2097 s->padconf[0x08] = 0x08080800;
2098 s->padconf[0x09] = 0x08080808;
2099 s->padconf[0x0a] = 0x08080808;
2100 s->padconf[0x0b] = 0x08080808;
2101 s->padconf[0x0c] = 0x08080808;
2102 s->padconf[0x0d] = 0x08080800;
2103 s->padconf[0x0e] = 0x08080808;
2104 s->padconf[0x0f] = 0x08080808;
2105 s->padconf[0x10] = 0x18181808;
2106 s->padconf[0x11] = 0x18181818;
2107 s->padconf[0x12] = 0x18181818;
2108 s->padconf[0x13] = 0x18181818;
2109 s->padconf[0x14] = 0x18181818;
2110 s->padconf[0x15] = 0x18181818;
2111 s->padconf[0x16] = 0x18181818;
2112 s->padconf[0x17] = 0x1f001f00;
2113 s->padconf[0x18] = 0x1f1f1f1f;
2114 s->padconf[0x19] = 0x00000000;
2115 s->padconf[0x1a] = 0x1f180000;
2116 s->padconf[0x1b] = 0x00001f1f;
2117 s->padconf[0x1c] = 0x1f001f00;
2118 s->padconf[0x1d] = 0x00000000;
2119 s->padconf[0x1e] = 0x00000000;
2120 s->padconf[0x1f] = 0x08000000;
2121 s->padconf[0x20] = 0x08080808;
2122 s->padconf[0x21] = 0x08080808;
2123 s->padconf[0x22] = 0x0f080808;
2124 s->padconf[0x23] = 0x0f0f0f0f;
2125 s->padconf[0x24] = 0x000f0f0f;
2126 s->padconf[0x25] = 0x1f1f1f0f;
2127 s->padconf[0x26] = 0x080f0f1f;
2128 s->padconf[0x27] = 0x070f1808;
2129 s->padconf[0x28] = 0x0f070707;
2130 s->padconf[0x29] = 0x000f0f1f;
2131 s->padconf[0x2a] = 0x0f0f0f1f;
2132 s->padconf[0x2b] = 0x08000000;
2133 s->padconf[0x2c] = 0x0000001f;
2134 s->padconf[0x2d] = 0x0f0f1f00;
2135 s->padconf[0x2e] = 0x1f1f0f0f;
2136 s->padconf[0x2f] = 0x0f1f1f1f;
2137 s->padconf[0x30] = 0x0f0f0f0f;
2138 s->padconf[0x31] = 0x0f1f0f1f;
2139 s->padconf[0x32] = 0x0f0f0f0f;
2140 s->padconf[0x33] = 0x0f1f0f1f;
2141 s->padconf[0x34] = 0x1f1f0f0f;
2142 s->padconf[0x35] = 0x0f0f1f1f;
2143 s->padconf[0x36] = 0x0f0f1f0f;
2144 s->padconf[0x37] = 0x0f0f0f0f;
2145 s->padconf[0x38] = 0x1f18180f;
2146 s->padconf[0x39] = 0x1f1f1f1f;
2147 s->padconf[0x3a] = 0x00001f1f;
2148 s->padconf[0x3b] = 0x00000000;
2149 s->padconf[0x3c] = 0x00000000;
2150 s->padconf[0x3d] = 0x0f0f0f0f;
2151 s->padconf[0x3e] = 0x18000f0f;
2152 s->padconf[0x3f] = 0x00070000;
2153 s->padconf[0x40] = 0x00000707;
2154 s->padconf[0x41] = 0x0f1f0700;
2155 s->padconf[0x42] = 0x1f1f070f;
2156 s->padconf[0x43] = 0x0008081f;
2157 s->padconf[0x44] = 0x00000800;
2158}
2159
2160static struct omap_sysctl_s *omap_sysctl_init(struct omap_target_agent_s *ta,
2161 omap_clk iclk, struct omap_mpu_state_s *mpu)
2162{
2163 int iomemtype;
2164 struct omap_sysctl_s *s = (struct omap_sysctl_s *)
2165 qemu_mallocz(sizeof(struct omap_sysctl_s));
2166
2167 s->mpu = mpu;
2168 omap_sysctl_reset(s);
2169
2170 iomemtype = l4_register_io_memory(omap_sysctl_readfn,
2171 omap_sysctl_writefn, s);
2172 omap_l4_attach(ta, 0, iomemtype);
2173
2174 return s;
2175}
2176
2177
2178static void omap2_mpu_reset(void *opaque)
2179{
2180 struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
2181
2182 omap_inth_reset(mpu->ih[0]);
2183 omap_dma_reset(mpu->dma);
2184 omap_prcm_reset(mpu->prcm);
2185 omap_sysctl_reset(mpu->sysc);
2186 omap_gp_timer_reset(mpu->gptimer[0]);
2187 omap_gp_timer_reset(mpu->gptimer[1]);
2188 omap_gp_timer_reset(mpu->gptimer[2]);
2189 omap_gp_timer_reset(mpu->gptimer[3]);
2190 omap_gp_timer_reset(mpu->gptimer[4]);
2191 omap_gp_timer_reset(mpu->gptimer[5]);
2192 omap_gp_timer_reset(mpu->gptimer[6]);
2193 omap_gp_timer_reset(mpu->gptimer[7]);
2194 omap_gp_timer_reset(mpu->gptimer[8]);
2195 omap_gp_timer_reset(mpu->gptimer[9]);
2196 omap_gp_timer_reset(mpu->gptimer[10]);
2197 omap_gp_timer_reset(mpu->gptimer[11]);
2198 omap_synctimer_reset(mpu->synctimer);
2199 omap_sdrc_reset(mpu->sdrc);
2200 omap_gpmc_reset(mpu->gpmc);
2201 omap_dss_reset(mpu->dss);
2202 omap_uart_reset(mpu->uart[0]);
2203 omap_uart_reset(mpu->uart[1]);
2204 omap_uart_reset(mpu->uart[2]);
2205 omap_mmc_reset(mpu->mmc);
2206 omap_gpif_reset(mpu->gpif);
2207 omap_mcspi_reset(mpu->mcspi[0]);
2208 omap_mcspi_reset(mpu->mcspi[1]);
2209 omap_i2c_reset(mpu->i2c[0]);
2210 omap_i2c_reset(mpu->i2c[1]);
2211 cpu_reset(mpu->env);
2212}
2213
2214static int omap2_validate_addr(struct omap_mpu_state_s *s,
2215 target_phys_addr_t addr)
2216{
2217 return 1;
2218}
2219
2220static const struct dma_irq_map omap2_dma_irq_map[] = {
2221 { 0, OMAP_INT_24XX_SDMA_IRQ0 },
2222 { 0, OMAP_INT_24XX_SDMA_IRQ1 },
2223 { 0, OMAP_INT_24XX_SDMA_IRQ2 },
2224 { 0, OMAP_INT_24XX_SDMA_IRQ3 },
2225};
2226
2227struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size,
2228 const char *core)
2229{
2230 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
2231 qemu_mallocz(sizeof(struct omap_mpu_state_s));
2232 ram_addr_t sram_base, q2_base;
2233 qemu_irq *cpu_irq;
2234 qemu_irq dma_irqs[4];
2235 omap_clk gpio_clks[4];
2236 DriveInfo *dinfo;
2237 int i;
2238
2239
2240 s->mpu_model = omap2420;
2241 s->env = cpu_init(core ?: "arm1136-r2");
2242 if (!s->env) {
2243 fprintf(stderr, "Unable to find CPU definition\n");
2244 exit(1);
2245 }
2246 s->sdram_size = sdram_size;
2247 s->sram_size = OMAP242X_SRAM_SIZE;
2248
2249 s->wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0];
2250
2251
2252 omap_clk_init(s);
2253
2254
2255 cpu_register_physical_memory(OMAP2_Q2_BASE, s->sdram_size,
2256 (q2_base = qemu_ram_alloc(NULL, "omap2.dram",
2257 s->sdram_size)) | IO_MEM_RAM);
2258 cpu_register_physical_memory(OMAP2_SRAM_BASE, s->sram_size,
2259 (sram_base = qemu_ram_alloc(NULL, "omap2.sram",
2260 s->sram_size)) | IO_MEM_RAM);
2261
2262 s->l4 = omap_l4_init(OMAP2_L4_BASE, 54);
2263
2264
2265 cpu_irq = arm_pic_init_cpu(s->env);
2266 s->ih[0] = omap2_inth_init(0x480fe000, 0x1000, 3, &s->irq[0],
2267 cpu_irq[ARM_PIC_CPU_IRQ], cpu_irq[ARM_PIC_CPU_FIQ],
2268 omap_findclk(s, "mpu_intc_fclk"),
2269 omap_findclk(s, "mpu_intc_iclk"));
2270
2271 s->prcm = omap_prcm_init(omap_l4tao(s->l4, 3),
2272 s->irq[0][OMAP_INT_24XX_PRCM_MPU_IRQ], NULL, NULL, s);
2273
2274 s->sysc = omap_sysctl_init(omap_l4tao(s->l4, 1),
2275 omap_findclk(s, "omapctrl_iclk"), s);
2276
2277 for (i = 0; i < 4; i ++)
2278 dma_irqs[i] =
2279 s->irq[omap2_dma_irq_map[i].ih][omap2_dma_irq_map[i].intr];
2280 s->dma = omap_dma4_init(0x48056000, dma_irqs, s, 256, 32,
2281 omap_findclk(s, "sdma_iclk"),
2282 omap_findclk(s, "sdma_fclk"));
2283 s->port->addr_valid = omap2_validate_addr;
2284
2285
2286 soc_dma_port_add_mem_ram(s->dma, q2_base, OMAP2_Q2_BASE, s->sdram_size);
2287 soc_dma_port_add_mem_ram(s->dma, sram_base, OMAP2_SRAM_BASE, s->sram_size);
2288
2289 s->uart[0] = omap2_uart_init(omap_l4ta(s->l4, 19),
2290 s->irq[0][OMAP_INT_24XX_UART1_IRQ],
2291 omap_findclk(s, "uart1_fclk"),
2292 omap_findclk(s, "uart1_iclk"),
2293 s->drq[OMAP24XX_DMA_UART1_TX],
2294 s->drq[OMAP24XX_DMA_UART1_RX],
2295 "uart1",
2296 serial_hds[0]);
2297 s->uart[1] = omap2_uart_init(omap_l4ta(s->l4, 20),
2298 s->irq[0][OMAP_INT_24XX_UART2_IRQ],
2299 omap_findclk(s, "uart2_fclk"),
2300 omap_findclk(s, "uart2_iclk"),
2301 s->drq[OMAP24XX_DMA_UART2_TX],
2302 s->drq[OMAP24XX_DMA_UART2_RX],
2303 "uart2",
2304 serial_hds[0] ? serial_hds[1] : NULL);
2305 s->uart[2] = omap2_uart_init(omap_l4ta(s->l4, 21),
2306 s->irq[0][OMAP_INT_24XX_UART3_IRQ],
2307 omap_findclk(s, "uart3_fclk"),
2308 omap_findclk(s, "uart3_iclk"),
2309 s->drq[OMAP24XX_DMA_UART3_TX],
2310 s->drq[OMAP24XX_DMA_UART3_RX],
2311 "uart3",
2312 serial_hds[0] && serial_hds[1] ? serial_hds[2] : NULL);
2313
2314 s->gptimer[0] = omap_gp_timer_init(omap_l4ta(s->l4, 7),
2315 s->irq[0][OMAP_INT_24XX_GPTIMER1],
2316 omap_findclk(s, "wu_gpt1_clk"),
2317 omap_findclk(s, "wu_l4_iclk"));
2318 s->gptimer[1] = omap_gp_timer_init(omap_l4ta(s->l4, 8),
2319 s->irq[0][OMAP_INT_24XX_GPTIMER2],
2320 omap_findclk(s, "core_gpt2_clk"),
2321 omap_findclk(s, "core_l4_iclk"));
2322 s->gptimer[2] = omap_gp_timer_init(omap_l4ta(s->l4, 22),
2323 s->irq[0][OMAP_INT_24XX_GPTIMER3],
2324 omap_findclk(s, "core_gpt3_clk"),
2325 omap_findclk(s, "core_l4_iclk"));
2326 s->gptimer[3] = omap_gp_timer_init(omap_l4ta(s->l4, 23),
2327 s->irq[0][OMAP_INT_24XX_GPTIMER4],
2328 omap_findclk(s, "core_gpt4_clk"),
2329 omap_findclk(s, "core_l4_iclk"));
2330 s->gptimer[4] = omap_gp_timer_init(omap_l4ta(s->l4, 24),
2331 s->irq[0][OMAP_INT_24XX_GPTIMER5],
2332 omap_findclk(s, "core_gpt5_clk"),
2333 omap_findclk(s, "core_l4_iclk"));
2334 s->gptimer[5] = omap_gp_timer_init(omap_l4ta(s->l4, 25),
2335 s->irq[0][OMAP_INT_24XX_GPTIMER6],
2336 omap_findclk(s, "core_gpt6_clk"),
2337 omap_findclk(s, "core_l4_iclk"));
2338 s->gptimer[6] = omap_gp_timer_init(omap_l4ta(s->l4, 26),
2339 s->irq[0][OMAP_INT_24XX_GPTIMER7],
2340 omap_findclk(s, "core_gpt7_clk"),
2341 omap_findclk(s, "core_l4_iclk"));
2342 s->gptimer[7] = omap_gp_timer_init(omap_l4ta(s->l4, 27),
2343 s->irq[0][OMAP_INT_24XX_GPTIMER8],
2344 omap_findclk(s, "core_gpt8_clk"),
2345 omap_findclk(s, "core_l4_iclk"));
2346 s->gptimer[8] = omap_gp_timer_init(omap_l4ta(s->l4, 28),
2347 s->irq[0][OMAP_INT_24XX_GPTIMER9],
2348 omap_findclk(s, "core_gpt9_clk"),
2349 omap_findclk(s, "core_l4_iclk"));
2350 s->gptimer[9] = omap_gp_timer_init(omap_l4ta(s->l4, 29),
2351 s->irq[0][OMAP_INT_24XX_GPTIMER10],
2352 omap_findclk(s, "core_gpt10_clk"),
2353 omap_findclk(s, "core_l4_iclk"));
2354 s->gptimer[10] = omap_gp_timer_init(omap_l4ta(s->l4, 30),
2355 s->irq[0][OMAP_INT_24XX_GPTIMER11],
2356 omap_findclk(s, "core_gpt11_clk"),
2357 omap_findclk(s, "core_l4_iclk"));
2358 s->gptimer[11] = omap_gp_timer_init(omap_l4ta(s->l4, 31),
2359 s->irq[0][OMAP_INT_24XX_GPTIMER12],
2360 omap_findclk(s, "core_gpt12_clk"),
2361 omap_findclk(s, "core_l4_iclk"));
2362
2363 omap_tap_init(omap_l4ta(s->l4, 2), s);
2364
2365 s->synctimer = omap_synctimer_init(omap_l4tao(s->l4, 2), s,
2366 omap_findclk(s, "clk32-kHz"),
2367 omap_findclk(s, "core_l4_iclk"));
2368
2369 s->i2c[0] = omap2_i2c_init(omap_l4tao(s->l4, 5),
2370 s->irq[0][OMAP_INT_24XX_I2C1_IRQ],
2371 &s->drq[OMAP24XX_DMA_I2C1_TX],
2372 omap_findclk(s, "i2c1.fclk"),
2373 omap_findclk(s, "i2c1.iclk"));
2374 s->i2c[1] = omap2_i2c_init(omap_l4tao(s->l4, 6),
2375 s->irq[0][OMAP_INT_24XX_I2C2_IRQ],
2376 &s->drq[OMAP24XX_DMA_I2C2_TX],
2377 omap_findclk(s, "i2c2.fclk"),
2378 omap_findclk(s, "i2c2.iclk"));
2379
2380 gpio_clks[0] = omap_findclk(s, "gpio1_dbclk");
2381 gpio_clks[1] = omap_findclk(s, "gpio2_dbclk");
2382 gpio_clks[2] = omap_findclk(s, "gpio3_dbclk");
2383 gpio_clks[3] = omap_findclk(s, "gpio4_dbclk");
2384 s->gpif = omap2_gpio_init(omap_l4ta(s->l4, 3),
2385 &s->irq[0][OMAP_INT_24XX_GPIO_BANK1],
2386 gpio_clks, omap_findclk(s, "gpio_iclk"), 4);
2387
2388 s->sdrc = omap_sdrc_init(0x68009000);
2389 s->gpmc = omap_gpmc_init(0x6800a000, s->irq[0][OMAP_INT_24XX_GPMC_IRQ]);
2390
2391 dinfo = drive_get(IF_SD, 0, 0);
2392 if (!dinfo) {
2393 fprintf(stderr, "qemu: missing SecureDigital device\n");
2394 exit(1);
2395 }
2396 s->mmc = omap2_mmc_init(omap_l4tao(s->l4, 9), dinfo->bdrv,
2397 s->irq[0][OMAP_INT_24XX_MMC_IRQ],
2398 &s->drq[OMAP24XX_DMA_MMC1_TX],
2399 omap_findclk(s, "mmc_fclk"), omap_findclk(s, "mmc_iclk"));
2400
2401 s->mcspi[0] = omap_mcspi_init(omap_l4ta(s->l4, 35), 4,
2402 s->irq[0][OMAP_INT_24XX_MCSPI1_IRQ],
2403 &s->drq[OMAP24XX_DMA_SPI1_TX0],
2404 omap_findclk(s, "spi1_fclk"),
2405 omap_findclk(s, "spi1_iclk"));
2406 s->mcspi[1] = omap_mcspi_init(omap_l4ta(s->l4, 36), 2,
2407 s->irq[0][OMAP_INT_24XX_MCSPI2_IRQ],
2408 &s->drq[OMAP24XX_DMA_SPI2_TX0],
2409 omap_findclk(s, "spi2_fclk"),
2410 omap_findclk(s, "spi2_iclk"));
2411
2412 s->dss = omap_dss_init(omap_l4ta(s->l4, 10), 0x68000800,
2413
2414 s->irq[0][OMAP_INT_24XX_DSS_IRQ], s->drq[OMAP24XX_DMA_DSS],
2415 omap_findclk(s, "dss_clk1"), omap_findclk(s, "dss_clk2"),
2416 omap_findclk(s, "dss_54m_clk"),
2417 omap_findclk(s, "dss_l3_iclk"),
2418 omap_findclk(s, "dss_l4_iclk"));
2419
2420 omap_sti_init(omap_l4ta(s->l4, 18), 0x54000000,
2421 s->irq[0][OMAP_INT_24XX_STI], omap_findclk(s, "emul_ck"),
2422 serial_hds[0] && serial_hds[1] && serial_hds[2] ?
2423 serial_hds[3] : NULL);
2424
2425 s->eac = omap_eac_init(omap_l4ta(s->l4, 32),
2426 s->irq[0][OMAP_INT_24XX_EAC_IRQ],
2427
2428 &s->drq[OMAP24XX_DMA_EAC_AC_RD],
2429 omap_findclk(s, "func_96m_clk"),
2430 omap_findclk(s, "core_l4_iclk"));
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613 qemu_register_reset(omap2_mpu_reset, s);
2614
2615 return s;
2616}
2617