2 * TI OMAP3 processors emulation.
4 * Copyright (C) 2008 yajin <yajin@vm-kernel.org>
5 * Copyright (C) 2009 Nokia Corporation
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 or
10 * (at your option) version 3 of the License.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
27 #include "qemu-timer.h"
28 #include "qemu-char.h"
31 #include "audio/audio.h"
34 //#define OMAP3_DEBUG_
37 #define TRACE(fmt, ...) fprintf(stderr, "%s " fmt "\n", __FUNCTION__, ##__VA_ARGS__)
43 /* 68000000-680003FF */ L3ID_L3RT = 0,
44 /* 68000400-680007FF */ L3ID_L3SI,
45 /* 68000800-680013FF */
46 /* 68001400-680017FF */ L3ID_MPUSS_IA,
47 /* 68001800-68001BFF */ L3ID_IVASS_IA,
48 /* 68001C00-68001FFF */ L3ID_SGXSS_IA,
49 /* 68002000-680023FF */ L3ID_SMS_TA,
50 /* 68002400-680027FF */ L3ID_GPMC_TA,
51 /* 68002800-68002BFF */ L3ID_OCM_RAM_TA,
52 /* 68002C00-68002FFF */ L3ID_OCM_ROM_TA,
53 /* 68003000-680033FF */ L3ID_D2D_IA,
54 /* 68003400-680037FF */ L3ID_D2D_TA,
55 /* 68003800-68003FFF */
56 /* 68004000-680043FF */ L3ID_HSUSB_HOST_IA,
57 /* 68004400-680047FF */ L3ID_HSUSB_OTG_IA,
58 /* 68004800-68004BFF */
59 /* 68004C00-68004FFF */ L3ID_SDMA_RD_IA,
60 /* 68005000-680053FF */ L3ID_SDMA_WR_IA,
61 /* 68005400-680057FF */ L3ID_DSS_IA,
62 /* 68005800-68005BFF */ L3ID_CAMISP_IA,
63 /* 68005C00-68005FFF */ L3ID_DAP_IA,
64 /* 68006000-680063FF */ L3ID_IVASS_TA,
65 /* 68006400-680067FF */ L3ID_SGXSS_TA,
66 /* 68006800-68006BFF */ L3ID_L4_CORE_TA,
67 /* 68006C00-68006FFF */ L3ID_L4_PER_TA,
68 /* 68007000-680073FF */ L3ID_L4_EMU_TA,
69 /* 68007400-6800FFFF */
70 /* 68010000-680103FF */ L3ID_RT_PM,
71 /* 68010400-680123FF */
72 /* 68012400-680127FF */ L3ID_GPMC_PM,
73 /* 68012800-68012BFF */ L3ID_OCM_RAM_PM,
74 /* 68012C00-68012FFF */ L3ID_OCM_ROM_PM,
75 /* 68013000-680133FF */ L3ID_D2D_PM,
76 /* 68013400-68013FFF */
77 /* 68014000-680143FF */ L3ID_IVA_PM,
78 /* 68014400-68FFFFFF */
79 } omap3_l3_region_id_t;
81 struct omap_l3_region_s {
82 target_phys_addr_t offset;
85 L3TYPE_GENERIC = 0, /* needs to be mapped separately */
86 L3TYPE_IA, /* initiator agent */
87 L3TYPE_TA, /* target agent */
88 L3TYPE_PM, /* protection mechanism */
89 L3TYPE_UNDEFINED, /* every access will emit an error message */
93 struct omap3_l3_initiator_agent_s {
94 target_phys_addr_t base;
101 struct omap3_l3pm_s {
102 target_phys_addr_t base;
106 uint16_t req_info_permission[8];
107 uint16_t read_permission[8];
108 uint16_t write_permission[8];
109 uint32_t addr_match[7];
112 union omap3_l3_port_s {
113 struct omap_target_agent_s ta;
114 struct omap3_l3_initiator_agent_s ia;
115 struct omap3_l3pm_s pm;
119 target_phys_addr_t base;
121 union omap3_l3_port_s region[0];
124 static struct omap_l3_region_s omap3_l3_region[] = {
125 [L3ID_L3RT ] = {0x00000000, 0x0400, L3TYPE_UNDEFINED},
126 [L3ID_L3SI ] = {0x00000400, 0x0400, L3TYPE_UNDEFINED},
127 [L3ID_MPUSS_IA ] = {0x00001400, 0x0400, L3TYPE_IA},
128 [L3ID_IVASS_IA ] = {0x00001800, 0x0400, L3TYPE_IA},
129 [L3ID_SGXSS_IA ] = {0x00001c00, 0x0400, L3TYPE_IA},
130 [L3ID_SMS_TA ] = {0x00002000, 0x0400, L3TYPE_TA},
131 [L3ID_GPMC_TA ] = {0x00002400, 0x0400, L3TYPE_TA},
132 [L3ID_OCM_RAM_TA ] = {0x00002800, 0x0400, L3TYPE_TA},
133 [L3ID_OCM_ROM_TA ] = {0x00002c00, 0x0400, L3TYPE_TA},
134 [L3ID_D2D_IA ] = {0x00003000, 0x0400, L3TYPE_IA},
135 [L3ID_D2D_TA ] = {0x00003400, 0x0400, L3TYPE_TA},
136 [L3ID_HSUSB_HOST_IA] = {0x00004000, 0x0400, L3TYPE_IA},
137 [L3ID_HSUSB_OTG_IA ] = {0x00004400, 0x0400, L3TYPE_IA},
138 [L3ID_SDMA_RD_IA ] = {0x00004c00, 0x0400, L3TYPE_IA},
139 [L3ID_SDMA_WR_IA ] = {0x00005000, 0x0400, L3TYPE_IA},
140 [L3ID_DSS_IA ] = {0x00005400, 0x0400, L3TYPE_IA},
141 [L3ID_CAMISP_IA ] = {0x00005800, 0x0400, L3TYPE_IA},
142 [L3ID_DAP_IA ] = {0x00005c00, 0x0400, L3TYPE_IA},
143 [L3ID_IVASS_TA ] = {0x00006000, 0x0400, L3TYPE_TA},
144 [L3ID_SGXSS_TA ] = {0x00006400, 0x0400, L3TYPE_TA},
145 [L3ID_L4_CORE_TA ] = {0x00006800, 0x0400, L3TYPE_TA},
146 [L3ID_L4_PER_TA ] = {0x00006c00, 0x0400, L3TYPE_TA},
147 [L3ID_L4_EMU_TA ] = {0x00007000, 0x0400, L3TYPE_TA},
148 [L3ID_RT_PM ] = {0x00010000, 0x0400, L3TYPE_PM},
149 [L3ID_GPMC_PM ] = {0x00012400, 0x0400, L3TYPE_PM},
150 [L3ID_OCM_RAM_PM ] = {0x00012800, 0x0400, L3TYPE_PM},
151 [L3ID_OCM_ROM_PM ] = {0x00012c00, 0x0400, L3TYPE_PM},
152 [L3ID_D2D_PM ] = {0x00013000, 0x0400, L3TYPE_PM},
153 [L3ID_IVA_PM ] = {0x00014000, 0x0400, L3TYPE_PM},
156 static uint32_t omap3_l3ia_read(void *opaque, target_phys_addr_t addr)
158 struct omap3_l3_initiator_agent_s *s = (struct omap3_l3_initiator_agent_s *)opaque;
161 case 0x00: /* COMPONENT_L */
163 case 0x04: /* COMPONENT_H */
165 case 0x18: /* CORE_L */
167 case 0x1c: /* CORE_H */
168 return (s->component >> 16);
169 case 0x20: /* AGENT_CONTROL_L */
171 case 0x24: /* AGENT_CONTROL_H */
173 case 0x28: /* AGENT_STATUS_L */
175 case 0x2c: /* AGENT_STATUS_H */
177 case 0x58: /* ERROR_LOG_L */
179 case 0x5c: /* ERROR_LOG_H */
181 case 0x60: /* ERROR_LOG_ADDR_L */
183 case 0x64: /* ERROR_LOG_ADDR_H */
189 OMAP_BAD_REG(s->base + addr);
193 static void omap3_l3ia_write(void *opaque, target_phys_addr_t addr,
196 struct omap3_l3_initiator_agent_s *s = (struct omap3_l3_initiator_agent_s *)opaque;
199 case 0x00: /* COMPONENT_L */
200 case 0x04: /* COMPONENT_H */
201 case 0x18: /* CORE_L */
202 case 0x1c: /* CORE_H */
203 case 0x60: /* ERROR_LOG_ADDR_L */
204 case 0x64: /* ERROR_LOG_ADDR_H */
205 OMAP_RO_REG(s->base + addr);
207 case 0x24: /* AGENT_CONTROL_H */
208 case 0x2c: /* AGENT_STATUS_H */
209 case 0x5c: /* ERROR_LOG_H */
210 /* RW register but all bits are reserved/read-only */
212 case 0x20: /* AGENT_CONTROL_L */
213 s->control = value & 0x3e070711;
214 /* TODO: some bits are reserved for some IA instances */
216 case 0x28: /* AGENT_STATUS_L */
217 s->status &= ~(value & 0x30000000);
219 case 0x58: /* ERROR_LOG_L */
220 /* error logging is not implemented, so ignore */
223 OMAP_BAD_REG(s->base + addr);
228 static void omap3_l3ia_init(struct omap3_l3_initiator_agent_s *s)
230 s->component = ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
231 s->control = 0x3e000000;
235 static CPUReadMemoryFunc *omap3_l3ia_readfn[] = {
236 omap_badwidth_read32,
237 omap_badwidth_read32,
241 static CPUWriteMemoryFunc *omap3_l3ia_writefn[] = {
242 omap_badwidth_write32,
243 omap_badwidth_write32,
247 static uint32_t omap3_l3ta_read(void *opaque, target_phys_addr_t addr)
249 struct omap_target_agent_s *s = (struct omap_target_agent_s *)opaque;
252 case 0x00: /* COMPONENT_L */
254 case 0x04: /* COMPONENT_H */
256 case 0x18: /* CORE_L */
258 case 0x1c: /* CORE_H */
259 return (s->component >> 16);
260 case 0x20: /* AGENT_CONTROL_L */
262 case 0x24: /* AGENT_CONTROL_H */
264 case 0x28: /* AGENT_STATUS_L */
266 case 0x2c: /* AGENT_STATUS_H */
268 case 0x58: /* ERROR_LOG_L */
270 case 0x5c: /* ERROR_LOG_H */
272 case 0x60: /* ERROR_LOG_ADDR_L */
274 case 0x64: /* ERROR_LOG_ADDR_H */
280 OMAP_BAD_REG(s->base + addr);
284 static void omap3_l3ta_write(void *opaque, target_phys_addr_t addr,
287 struct omap_target_agent_s *s = (struct omap_target_agent_s *)opaque;
290 case 0x00: /* COMPONENT_L */
291 case 0x04: /* COMPONENT_H */
292 case 0x18: /* CORE_L */
293 case 0x1c: /* CORE_H */
294 case 0x60: /* ERROR_LOG_ADDR_L */
295 case 0x64: /* ERROR_LOG_ADDR_H */
296 OMAP_RO_REG(s->base + addr);
298 case 0x24: /* AGENT_CONTROL_H */
299 case 0x5c: /* ERROR_LOG_H */
300 /* RW register but all bits are reserved/read-only */
302 case 0x20: /* AGENT_CONTROL_L */
303 s->control = value & 0x03000711;
305 case 0x28: /* AGENT_STATUS_L */
306 if (s->base == OMAP3_L3_BASE + omap3_l3_region[L3ID_L4_CORE_TA].offset
307 || s->base == OMAP3_L3_BASE + omap3_l3_region[L3ID_L4_PER_TA].offset
308 || s->base == OMAP3_L3_BASE + omap3_l3_region[L3ID_L4_EMU_TA].offset) {
309 s->status &= ~(value & (1 << 24));
311 OMAP_RO_REG(s->base + addr);
313 case 0x2c: /* AGENT_STATUS_H */
314 if (s->base != OMAP3_L3_BASE + omap3_l3_region[L3ID_L4_CORE_TA].offset
315 && s->base != OMAP3_L3_BASE + omap3_l3_region[L3ID_L4_PER_TA].offset
316 && s->base != OMAP3_L3_BASE + omap3_l3_region[L3ID_L4_EMU_TA].offset)
317 OMAP_RO_REG(s->base + addr);
318 /* for L4 core, per, emu TAs this is RW reg */
320 case 0x58: /* ERROR_LOG_L */
321 /* error logging is not implemented, so ignore */
324 OMAP_BAD_REG(s->base + addr);
329 static void omap3_l3ta_init(struct omap_target_agent_s *s)
331 s->component = ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
332 s->control = 0x03000000;
336 static CPUReadMemoryFunc *omap3_l3ta_readfn[] = {
337 omap_badwidth_read32,
338 omap_badwidth_read32,
342 static CPUWriteMemoryFunc *omap3_l3ta_writefn[] = {
343 omap_badwidth_write32,
344 omap_badwidth_write32,
348 static uint32_t omap3_l3pm_read8(void *opaque, target_phys_addr_t addr)
350 struct omap3_l3pm_s *s = (struct omap3_l3pm_s *)opaque;
356 OMAP_BAD_REG(s->base + addr);
359 case 0x20: return s->error_log & 0xff;
360 case 0x21: return (s->error_log >> 8) & 0xff;
361 case 0x22: return (s->error_log >> 16) & 0xff;
362 case 0x23: return (s->error_log >> 24) & 0xff;
363 case 0x24 ... 0x27: return 0;
365 case 0x28 ... 0x2a: return 0;
366 case 0x2b: return s->control;
367 case 0x2c ... 0x2f: return 0;
368 /* ERROR_CLEAR_SINGLE */
369 case 0x30: return 0; /* TODO: clear single error from log */
370 case 0x31 ... 0x37: return 0;
371 /* ERROR_CLEAR_MULTI */
372 case 0x38: return 0; /* TODO: clear multiple errors from log */
373 case 0x39 ... 0x3f: return 0;
378 i = (addr - 0x48) / 0x20;
380 if (i < 7 || (i < 8 && addr < 0x60))
382 /* REQ_INFO_PERMISSION_i */
383 case 0x48: return s->req_info_permission[i] & 0xff;
384 case 0x49: return (s->req_info_permission[i] >> 8) & 0xff;
385 case 0x4a ... 0x4f: return 0;
386 /* READ_PERMISSION_i */
387 case 0x50: return s->read_permission[i] & 0xff;
388 case 0x51: return (s->read_permission[i] >> 8) & 0xff;
389 case 0x52 ... 0x57: return 0;
390 /* WRITE_PERMISSION_i */
391 case 0x58: return s->write_permission[i] & 0xff;
392 case 0x59: return (s->write_permission[i] >> 8) & 0xff;
393 case 0x5a ... 0x5f: return 0;
395 case 0x60: return s->addr_match[i] & 0xff;
396 case 0x61: return (s->addr_match[i] >> 8) & 0xff;
397 case 0x62: return (s->addr_match[i] >> 16) & 0xff;
398 case 0x63 ... 0x67: return 0;
403 OMAP_BAD_REG(s->base + addr);
407 static uint32_t omap3_l3pm_read16(void *opaque, target_phys_addr_t addr)
409 return omap3_l3pm_read8(opaque, addr)
410 | (omap3_l3pm_read8(opaque, addr + 1) << 8);
413 static uint32_t omap3_l3pm_read32(void *opaque, target_phys_addr_t addr)
415 return omap3_l3pm_read16(opaque, addr)
416 | (omap3_l3pm_read16(opaque, addr + 2) << 16);
419 static void omap3_l3pm_write8(void *opaque, target_phys_addr_t addr,
422 struct omap3_l3pm_s *s = (struct omap3_l3pm_s *)opaque;
428 OMAP_BAD_REGV(s->base + addr, value);
432 s->error_log &= ~((value & 0xcf) << 24);
438 s->control = value & 3;
442 /* ERROR_CLEAR_SINGLE / ERROR_CLEAR_MULTI */
444 OMAP_RO_REGV(s->base + addr, value);
450 i = (addr - 0x48) / 0x20;
452 if (i < 7 || (i < 8 && addr < 0x60))
454 /* REQ_INFO_PERMISSION_i */
456 s->req_info_permission[i] =
457 (s->req_info_permission[i] & ~0xff) | (value & 0xff);
460 s->req_info_permission[i] =
461 (s->req_info_permission[i] & ~0xff00) | ((value & 0xff) << 8);
465 /* READ_PERMISSION_i */
467 s->read_permission[i] =
468 (s->read_permission[i] & ~0xff) | (value & 0x3e);
471 s->read_permission[i] =
472 (s->read_permission[i] & ~0xff00) | ((value & 0x5f) << 8);
476 /* WRITE_PERMISSION_i */
478 s->write_permission[i] =
479 (s->write_permission[i] & ~0xff) | (value & 0x3e);
482 s->write_permission[i] =
483 (s->write_permission[i] & ~0xff00) | ((value & 0x5f) << 8);
489 s->addr_match[i] = (s->addr_match[i] & ~0xff) | (value & 0xff);
493 (s->addr_match[i] & ~0xfe00) | ((value & 0xfe) << 8);
497 (s->addr_match[i] & ~0x0f0000) | ((value & 0x0f) << 16);
505 OMAP_BAD_REGV(s->base + addr, value);
508 static void omap3_l3pm_write16(void *opaque, target_phys_addr_t addr,
511 omap3_l3pm_write8(opaque, addr + 0, value & 0xff);
512 omap3_l3pm_write8(opaque, addr + 1, (value >> 8) & 0xff);
515 static void omap3_l3pm_write32(void *opaque, target_phys_addr_t addr,
518 omap3_l3pm_write16(opaque, addr + 0, value & 0xffff);
519 omap3_l3pm_write16(opaque, addr + 2, (value >> 16) & 0xffff);
522 static void omap3_l3pm_init(struct omap3_l3pm_s *s)
529 case 0x68010000: /* PM_RT */
530 s->req_info_permission[0] = 0xffff;
531 s->req_info_permission[1] = 0;
532 for (i = 0; i < 2; i++)
533 s->read_permission[i] = s->write_permission[i] = 0x1406;
534 s->addr_match[0] = 0x10230;
536 case 0x68012400: /* PM_GPMC */
537 s->req_info_permission[0] = 0;
538 for (i = 3; i < 8; i++)
539 s->req_info_permission[i] = 0xffff;
540 for (i = 0; i < 8; i++)
541 s->read_permission[i] = s->write_permission[i] = 0x563e;
542 s->addr_match[0] = 0x00098;
544 case 0x68012800: /* PM_OCM_RAM */
545 s->req_info_permission[0] = 0;
546 for (i = 1; i < 8; i++)
547 s->req_info_permission[i] = 0xffff;
548 for (i = 0; i < 8; i++)
549 s->read_permission[i] = s->write_permission[i] = 0x5f3e;
550 s->addr_match[1] = 0x0f810;
552 case 0x68012C00: /* PM_OCM_ROM */
553 s->req_info_permission[1] = 0xffff;
554 for (i = 0; i < 2; i++) {
555 s->read_permission[i] = 0x1002;
556 s->write_permission[i] = 0;
558 s->addr_match[0] = 0x14028;
560 case 0x68013000: /* PM_MAD2D */
561 s->req_info_permission[0] = 0;
562 for (i = 1; i < 8; i++)
563 s->req_info_permission[i] = 0xffff;
564 for (i = 0; i < 8; i++)
565 s->read_permission[i] = s->write_permission[i] = 0x5f1e;
567 case 0x68014000: /* PM_IVA2.2 */
568 s->req_info_permission[0] = 0;
569 for (i = 1; i < 4; i++)
570 s->req_info_permission[i] = 0xffff;
571 for (i = 0; i < 4; i++)
572 s->read_permission[i] = s->write_permission[i] = 0x140e;
575 fprintf(stderr, "%s: unknown PM region (0x%08x)\n",
576 __FUNCTION__, s->base);
582 static CPUReadMemoryFunc *omap3_l3pm_readfn[] = {
588 static CPUWriteMemoryFunc *omap3_l3pm_writefn[] = {
594 static uint32_t omap3_l3undef_read8(void *opaque, target_phys_addr_t addr)
596 fprintf(stderr, "%s: unsupported register at %08x\n",
601 static uint32_t omap3_l3undef_read16(void *opaque, target_phys_addr_t addr)
603 fprintf(stderr, "%s: unsupported register at %08x\n",
608 static uint32_t omap3_l3undef_read32(void *opaque, target_phys_addr_t addr)
610 fprintf(stderr, "%s: unsupported register at %08x\n",
615 static void omap3_l3undef_write8(void *opaque, target_phys_addr_t addr,
618 fprintf(stderr, "%s: unsupported register at %08x, value %02x\n",
619 __FUNCTION__, addr, value);
622 static void omap3_l3undef_write16(void *opaque, target_phys_addr_t addr,
625 fprintf(stderr, "%s: unsupported register at %08x, value %04x\n",
626 __FUNCTION__, addr, value);
629 static void omap3_l3undef_write32(void *opaque, target_phys_addr_t addr,
632 fprintf(stderr, "%s: unsupported register at %08x, value %08x\n",
633 __FUNCTION__, addr, value);
636 static CPUReadMemoryFunc *omap3_l3undef_readfn[] = {
638 omap3_l3undef_read16,
639 omap3_l3undef_read32,
642 static CPUWriteMemoryFunc *omap3_l3undef_writefn[] = {
643 omap3_l3undef_write8,
644 omap3_l3undef_write16,
645 omap3_l3undef_write32,
648 static struct omap_l3_s *omap3_l3_init(target_phys_addr_t base,
649 struct omap_l3_region_s *regions,
652 int i, iomemtype = 0;
654 struct omap_l3_s *bus = qemu_mallocz(sizeof(*bus) + n * sizeof(*bus->region));
655 bus->region_count = n;
658 for (i = 0; i < n; i++) {
659 switch (regions[i].type) {
661 /* not mapped for now, mapping will be done later by
665 iomemtype = cpu_register_io_memory(0, omap3_l3ia_readfn,
668 bus->region[i].ia.base = base + regions[i].offset;
669 omap3_l3ia_init(&bus->region[i].ia);
672 iomemtype = cpu_register_io_memory(0, omap3_l3ta_readfn,
675 bus->region[i].ta.base = base + regions[i].offset;
676 omap3_l3ta_init(&bus->region[i].ta);
679 iomemtype = cpu_register_io_memory(0, omap3_l3pm_readfn,
682 bus->region[i].pm.base = base + regions[i].offset;
683 omap3_l3pm_init(&bus->region[i].pm);
685 case L3TYPE_UNDEFINED:
686 iomemtype = cpu_register_io_memory(0, omap3_l3undef_readfn,
687 omap3_l3undef_writefn,
691 fprintf(stderr, "%s: unknown L3 region type: %d\n",
692 __FUNCTION__, regions[i].type);
696 cpu_register_physical_memory(base + regions[i].offset,
705 /* 48000000-48001FFF */
706 /* 48002000-48002FFF */ L4ID_SCM = 0,
707 /* 48003000-48003FFF */ L4ID_SCM_TA,
708 /* 48004000-48005FFF */ L4ID_CM_A,
709 /* 48006000-480067FF */ L4ID_CM_B,
710 /* 48006800-48006FFF */
711 /* 48007000-48007FFF */ L4ID_CM_TA,
712 /* 48008000-48023FFF */
713 /* 48024000-48024FFF */
714 /* 48025000-48025FFF */
715 /* 48026000-4803FFFF */
716 /* 48040000-480407FF */ L4ID_CORE_AP,
717 /* 48040800-48040FFF */ L4ID_CORE_IP,
718 /* 48041000-48041FFF */ L4ID_CORE_LA,
719 /* 48042000-4804FBFF */
720 /* 4804FC00-4804FFFF */ L4ID_DSI,
721 /* 48050000-480503FF */ L4ID_DSS,
722 /* 48050400-480507FF */ L4ID_DISPC,
723 /* 48050800-48050BFF */ L4ID_RFBI,
724 /* 48050C00-48050FFF */ L4ID_VENC,
725 /* 48051000-48051FFF */ L4ID_DSS_TA,
726 /* 48052000-48055FFF */
727 /* 48056000-48056FFF */ L4ID_SDMA,
728 /* 48057000-48057FFF */ L4ID_SDMA_TA,
729 /* 48058000-4805FFFF */
730 /* 48060000-48060FFF */ L4ID_I2C3,
731 /* 48061000-48061FFF */ L4ID_I2C3_TA,
732 /* 48062000-48062FFF */ L4ID_USBTLL,
733 /* 48063000-48063FFF */ L4ID_USBTLL_TA,
734 /* 48064000-48064FFF */ L4ID_HSUSBHOST,
735 /* 48065000-48065FFF */ L4ID_HSUSBHOST_TA,
736 /* 48066000-48069FFF */
737 /* 4806A000-4806AFFF */ L4ID_UART1,
738 /* 4806B000-4806BFFF */ L4ID_UART1_TA,
739 /* 4806C000-4806CFFF */ L4ID_UART2,
740 /* 4806D000-4806DFFF */ L4ID_UART2_TA,
741 /* 4806E000-4806FFFF */
742 /* 48070000-48070FFF */ L4ID_I2C1,
743 /* 48071000-48071FFF */ L4ID_I2C1_TA,
744 /* 48072000-48072FFF */ L4ID_I2C2,
745 /* 48073000-48073FFF */ L4ID_I2C2_TA,
746 /* 48074000-48074FFF */ L4ID_MCBSP1,
747 /* 48075000-48075FFF */ L4ID_MCBSP1_TA,
748 /* 48076000-48085FFF */
749 /* 48086000-48086FFF */ L4ID_GPTIMER10,
750 /* 48087000-48087FFF */ L4ID_GPTIMER10_TA,
751 /* 48088000-48088FFF */ L4ID_GPTIMER11,
752 /* 48089000-48089FFF */ L4ID_GPTIMER11_TA,
753 /* 4808A000-4808AFFF */
754 /* 4808B000-4808BFFF */
755 /* 4808C000-48093FFF */
756 /* 48094000-48094FFF */ L4ID_MAILBOX,
757 /* 48095000-48095FFF */ L4ID_MAILBOX_TA,
758 /* 48096000-48096FFF */ L4ID_MCBSP5,
759 /* 48097000-48097FFF */ L4ID_MCBSP5_TA,
760 /* 48098000-48098FFF */ L4ID_MCSPI1,
761 /* 48099000-48099FFF */ L4ID_MCSPI1_TA,
762 /* 4809A000-4809AFFF */ L4ID_MCSPI2,
763 /* 4809B000-4809BFFF */ L4ID_MCSPI2_TA,
764 /* 4809C000-4809CFFF */ L4ID_MMCSDIO1,
765 /* 4809D000-4809DFFF */ L4ID_MMCSDIO1_TA,
766 /* 4809E000-4809EFFF */ L4ID_MSPRO,
767 /* 4809F000-4809FFFF */ L4ID_MSPRO_TA,
768 /* 480A0000-480AAFFF */
769 /* 480AB000-480ABFFF */ L4ID_HSUSBOTG,
770 /* 480AC000-480ACFFF */ L4ID_HSUSBOTG_TA,
771 /* 480AD000-480ADFFF */ L4ID_MMCSDIO3,
772 /* 480AE000-480AEFFF */ L4ID_MMCSDIO3_TA,
773 /* 480AF000-480AFFFF */
774 /* 480B0000-480B0FFF */
775 /* 480B1000-480B1FFF */
776 /* 480B2000-480B2FFF */ L4ID_HDQ1WIRE,
777 /* 480B3000-480B2FFF */ L4ID_HDQ1WIRE_TA,
778 /* 480B4000-480B4FFF */ L4ID_MMCSDIO2,
779 /* 480B5000-480B5FFF */ L4ID_MMCSDIO2_TA,
780 /* 480B6000-480B6FFF */ L4ID_ICRMPU,
781 /* 480B7000-480B7FFF */ L4ID_ICRMPU_TA,
782 /* 480B8000-480B8FFF */ L4ID_MCSPI3,
783 /* 480B9000-480B9FFF */ L4ID_MCSPI3_TA,
784 /* 480BA000-480BAFFF */ L4ID_MCSPI4,
785 /* 480BB000-480BBFFF */ L4ID_MCSPI4_TA,
786 /* 480BC000-480BFFFF */ L4ID_CAMERAISP,
787 /* 480C0000-480C0FFF */ L4ID_CAMERAISP_TA,
788 /* 480C1000-480CCFFF */
789 /* 480CD000-480CDFFF */ L4ID_ICRMODEM,
790 /* 480CE000-480CEFFF */ L4ID_ICRMODEM_TA,
791 /* 480CF000-482FFFFF */
792 /* 48300000-48303FFF */
793 /* 48304000-48304FFF */ L4ID_GPTIMER12,
794 /* 48305000-48305FFF */ L4ID_GPTIMER12_TA,
795 /* 48306000-48307FFF */ L4ID_PRM_A,
796 /* 48308000-483087FF */ L4ID_PRM_B,
797 /* 48308800-48308FFF */
798 /* 48309000-48309FFF */ L4ID_PRM_TA,
799 /* 4830A000-4830AFFF */ L4ID_TAP,
800 /* 4830B000-4830BFFF */ L4ID_TAP_TA,
801 /* 4830C000-4830FFFF */
802 /* 48310000-48310FFF */ L4ID_GPIO1,
803 /* 48311000-48311FFF */ L4ID_GPIO1_TA,
804 /* 48312000-48313FFF */
805 /* 48314000-48314FFF */ L4ID_WDTIMER2,
806 /* 48315000-48315FFF */ L4ID_WDTIMER2_TA,
807 /* 48316000-48317FFF */
808 /* 48318000-48318FFF */ L4ID_GPTIMER1,
809 /* 48319000-48319FFF */ L4ID_GPTIMER1_TA,
810 /* 4831A000-4831FFFF */
811 /* 48320000-48320FFF */ L4ID_32KTIMER,
812 /* 48321000-48321FFF */ L4ID_32KTIMER_TA,
813 /* 48322000-48327FFF */
814 /* 48328000-483287FF */ L4ID_WAKEUP_AP,
815 /* 48328800-48328FFF */ L4ID_WAKEUP_C_IP,
816 /* 48329000-48329FFF */ L4ID_WAKEUP_LA,
817 /* 4832A000-4832A7FF */ L4ID_WAKEUP_E_IP,
818 /* 4832A800-4833FFFF */
819 /* 48340000-48340FFF */
820 /* 48341000-48FFFFFF */
821 /* 49000000-490007FF */ L4ID_PER_AP,
822 /* 49000800-49000FFF */ L4ID_PER_IP,
823 /* 49001000-49001FFF */ L4ID_PER_LA,
824 /* 49002000-4901FFFF */
825 /* 49020000-49020FFF */ L4ID_UART3,
826 /* 49021000-49021FFF */ L4ID_UART3_TA,
827 /* 49022000-49022FFF */ L4ID_MCBSP2,
828 /* 49023000-49023FFF */ L4ID_MCBSP2_TA,
829 /* 49024000-49024FFF */ L4ID_MCBSP3,
830 /* 49025000-49025FFF */ L4ID_MCBSP3_TA,
831 /* 49026000-49026FFF */ L4ID_MCBSP4,
832 /* 49027000-49027FFF */ L4ID_MCBSP4_TA,
833 /* 49028000-49028FFF */ L4ID_MCBSP2S,
834 /* 49029000-49029FFF */ L4ID_MCBSP2S_TA,
835 /* 4902A000-4902AFFF */ L4ID_MCBSP3S,
836 /* 4902B000-4902BFFF */ L4ID_MCBSP3S_TA,
837 /* 4902C000-4902FFFF */
838 /* 49030000-49030FFF */ L4ID_WDTIMER3,
839 /* 49031000-49031FFF */ L4ID_WDTIMER3_TA,
840 /* 49032000-49032FFF */ L4ID_GPTIMER2,
841 /* 49033000-49033FFF */ L4ID_GPTIMER2_TA,
842 /* 49034000-49034FFF */ L4ID_GPTIMER3,
843 /* 49035000-49035FFF */ L4ID_GPTIMER3_TA,
844 /* 49036000-49036FFF */ L4ID_GPTIMER4,
845 /* 49037000-49037FFF */ L4ID_GPTIMER4_TA,
846 /* 49038000-49038FFF */ L4ID_GPTIMER5,
847 /* 49039000-49039FFF */ L4ID_GPTIMER5_TA,
848 /* 4903A000-4903AFFF */ L4ID_GPTIMER6,
849 /* 4903B000-4903BFFF */ L4ID_GPTIMER6_TA,
850 /* 4903C000-4903CFFF */ L4ID_GPTIMER7,
851 /* 4903D000-4903DFFF */ L4ID_GPTIMER7_TA,
852 /* 4903E000-4903EFFF */ L4ID_GPTIMER8,
853 /* 4903F000-4903FFFF */ L4ID_GPTIMER8_TA,
854 /* 49040000-49040FFF */ L4ID_GPTIMER9,
855 /* 49041000-49041FFF */ L4ID_GPTIMER9_TA,
856 /* 49042000-4904FFFF */
857 /* 49050000-49050FFF */ L4ID_GPIO2,
858 /* 49051000-49051FFF */ L4ID_GPIO2_TA,
859 /* 49052000-49052FFF */ L4ID_GPIO3,
860 /* 49053000-49053FFF */ L4ID_GPIO3_TA,
861 /* 49054000-49054FFF */ L4ID_GPIO4,
862 /* 49055000-49055FFF */ L4ID_GPIO4_TA,
863 /* 49056000-49056FFF */ L4ID_GPIO5,
864 /* 49057000-49057FFF */ L4ID_GPIO5_TA,
865 /* 49058000-49058FFF */ L4ID_GPIO6,
866 /* 49059000-49059FFF */ L4ID_GPIO6_TA,
867 /* 4905A000-490FFFFF */
868 /* 54000000-54003FFF */
869 /* 54004000-54005FFF */
870 /* 54006000-540067FF */ L4ID_EMU_AP,
871 /* 54006800-54006FFF */ L4ID_EMU_IP_C,
872 /* 54007000-54007FFF */ L4ID_EMU_LA,
873 /* 54008000-540087FF */ L4ID_EMU_IP_DAP,
874 /* 54008800-5400FFFF */
875 /* 54010000-54017FFF */ L4ID_MPUEMU,
876 /* 54018000-54018FFF */ L4ID_MPUEMU_TA,
877 /* 54019000-54019FFF */ L4ID_TPIU,
878 /* 5401A000-5401AFFF */ L4ID_TPIU_TA,
879 /* 5401B000-5401BFFF */ L4ID_ETB,
880 /* 5401C000-5401CFFF */ L4ID_ETB_TA,
881 /* 5401D000-5401DFFF */ L4ID_DAPCTL,
882 /* 5401E000-5401EFFF */ L4ID_DAPCTL_TA,
883 /* 5401F000-5401FFFF */ L4ID_SDTI_TA,
884 /* 54020000-544FFFFF */
885 /* 54500000-5450FFFF */ L4ID_SDTI_CFG,
886 /* 54510000-545FFFFF */
887 /* 54600000-546FFFFF */ L4ID_SDTI,
888 /* 54700000-54705FFF */
889 /* 54706000-54707FFF */ L4ID_EMU_PRM_A,
890 /* 54708000-547087FF */ L4ID_EMU_PRM_B,
891 /* 54708800-54708FFF */
892 /* 54709000-54709FFF */ L4ID_EMU_PRM_TA,
893 /* 5470A000-5470FFFF */
894 /* 54710000-54710FFF */ L4ID_EMU_GPIO1,
895 /* 54711000-54711FFF */ L4ID_EMU_GPIO1_TA,
896 /* 54712000-54713FFF */
897 /* 54714000-54714FFF */ L4ID_EMU_WDTM2,
898 /* 54715000-54715FFF */ L4ID_EMU_WDTM2_TA,
899 /* 54716000-54717FFF */
900 /* 54718000-54718FFF */ L4ID_EMU_GPTM1,
901 /* 54719000-54719FFF */ L4ID_EMU_GPTM1_TA,
902 /* 5471A000-5471FFFF */
903 /* 54720000-54720FFF */ L4ID_EMU_32KTM,
904 /* 54721000-54721FFF */ L4ID_EMU_32KTM_TA,
905 /* 54722000-54727FFF */
906 /* 54728000-547287FF */ L4ID_EMU_WKUP_AP,
907 /* 54728800-54728FFF */ L4ID_EMU_WKUP_IPC,
908 /* 54729000-54729FFF */ L4ID_EMU_WKUP_LA,
909 /* 5472A000-5472A7FF */ L4ID_EMU_WKUP_IPE,
910 /* 5472A800-547FFFFF */
911 } omap3_l4_region_id_t;
914 L4TYPE_GENERIC = 0, /* not mapped by default, must be mapped separately */
915 L4TYPE_IA, /* initiator agent */
916 L4TYPE_TA, /* target agent */
917 L4TYPE_LA, /* link register agent */
918 L4TYPE_AP /* address protection */
919 } omap3_l4_region_type_t;
921 /* we reuse the "access" member for defining region type -- the original
922 omap_l4_region_s "access" member is not used anywhere else anyway! */
923 static struct omap_l4_region_s omap3_l4_region[] = {
925 [L4ID_SCM ] = {0x00002000, 0x1000, L4TYPE_GENERIC},
926 [L4ID_SCM_TA ] = {0x00003000, 0x1000, L4TYPE_TA},
927 [L4ID_CM_A ] = {0x00004000, 0x2000, L4TYPE_GENERIC},
928 [L4ID_CM_B ] = {0x00006000, 0x0800, L4TYPE_GENERIC},
929 [L4ID_CM_TA ] = {0x00007000, 0x1000, L4TYPE_TA},
930 [L4ID_CORE_AP ] = {0x00040000, 0x0800, L4TYPE_AP},
931 [L4ID_CORE_IP ] = {0x00040800, 0x0800, L4TYPE_IA},
932 [L4ID_CORE_LA ] = {0x00041000, 0x1000, L4TYPE_LA},
933 [L4ID_DSI ] = {0x0004fc00, 0x0400, L4TYPE_GENERIC},
934 [L4ID_DSS ] = {0x00050000, 0x0400, L4TYPE_GENERIC},
935 [L4ID_DISPC ] = {0x00050400, 0x0400, L4TYPE_GENERIC},
936 [L4ID_RFBI ] = {0x00050800, 0x0400, L4TYPE_GENERIC},
937 [L4ID_VENC ] = {0x00050c00, 0x0400, L4TYPE_GENERIC},
938 [L4ID_DSS_TA ] = {0x00051000, 0x1000, L4TYPE_TA},
939 [L4ID_SDMA ] = {0x00056000, 0x1000, L4TYPE_GENERIC},
940 [L4ID_SDMA_TA ] = {0x00057000, 0x1000, L4TYPE_TA},
941 [L4ID_I2C3 ] = {0x00060000, 0x1000, L4TYPE_GENERIC},
942 [L4ID_I2C3_TA ] = {0x00061000, 0x1000, L4TYPE_TA},
943 [L4ID_USBTLL ] = {0x00062000, 0x1000, L4TYPE_GENERIC},
944 [L4ID_USBTLL_TA ] = {0x00063000, 0x1000, L4TYPE_TA},
945 [L4ID_HSUSBHOST ] = {0x00064000, 0x1000, L4TYPE_GENERIC},
946 [L4ID_HSUSBHOST_TA] = {0x00065000, 0x1000, L4TYPE_TA},
947 [L4ID_UART1 ] = {0x0006a000, 0x1000, L4TYPE_GENERIC},
948 [L4ID_UART1_TA ] = {0x0006b000, 0x1000, L4TYPE_TA},
949 [L4ID_UART2 ] = {0x0006c000, 0x1000, L4TYPE_GENERIC},
950 [L4ID_UART2_TA ] = {0x0006d000, 0x1000, L4TYPE_TA},
951 [L4ID_I2C1 ] = {0x00070000, 0x1000, L4TYPE_GENERIC},
952 [L4ID_I2C1_TA ] = {0x00071000, 0x1000, L4TYPE_TA},
953 [L4ID_I2C2 ] = {0x00072000, 0x1000, L4TYPE_GENERIC},
954 [L4ID_I2C2_TA ] = {0x00073000, 0x1000, L4TYPE_TA},
955 [L4ID_MCBSP1 ] = {0x00074000, 0x1000, L4TYPE_GENERIC},
956 [L4ID_MCBSP1_TA ] = {0x00075000, 0x1000, L4TYPE_TA},
957 [L4ID_GPTIMER10 ] = {0x00086000, 0x1000, L4TYPE_GENERIC},
958 [L4ID_GPTIMER10_TA] = {0x00087000, 0x1000, L4TYPE_TA},
959 [L4ID_GPTIMER11 ] = {0x00088000, 0x1000, L4TYPE_GENERIC},
960 [L4ID_GPTIMER11_TA] = {0x00089000, 0x1000, L4TYPE_TA},
961 [L4ID_MAILBOX ] = {0x00094000, 0x1000, L4TYPE_GENERIC},
962 [L4ID_MAILBOX_TA ] = {0x00095000, 0x1000, L4TYPE_TA},
963 [L4ID_MCBSP5 ] = {0x00096000, 0x1000, L4TYPE_GENERIC},
964 [L4ID_MCBSP5_TA ] = {0x00097000, 0x1000, L4TYPE_TA},
965 [L4ID_MCSPI1 ] = {0x00098000, 0x1000, L4TYPE_GENERIC},
966 [L4ID_MCSPI1_TA ] = {0x00099000, 0x1000, L4TYPE_TA},
967 [L4ID_MCSPI2 ] = {0x0009a000, 0x1000, L4TYPE_GENERIC},
968 [L4ID_MCSPI2_TA ] = {0x0009b000, 0x1000, L4TYPE_TA},
969 [L4ID_MMCSDIO1 ] = {0x0009c000, 0x1000, L4TYPE_GENERIC},
970 [L4ID_MMCSDIO1_TA ] = {0x0009d000, 0x1000, L4TYPE_TA},
971 [L4ID_MSPRO ] = {0x0009e000, 0x1000, L4TYPE_GENERIC},
972 [L4ID_MSPRO_TA ] = {0x0009f000, 0x1000, L4TYPE_TA},
973 [L4ID_HSUSBOTG ] = {0x000ab000, 0x1000, L4TYPE_GENERIC},
974 [L4ID_HSUSBOTG_TA ] = {0x000ac000, 0x1000, L4TYPE_TA},
975 [L4ID_MMCSDIO3 ] = {0x000ad000, 0x1000, L4TYPE_GENERIC},
976 [L4ID_MMCSDIO3_TA ] = {0x000ae000, 0x1000, L4TYPE_TA},
977 [L4ID_HDQ1WIRE ] = {0x000b2000, 0x1000, L4TYPE_GENERIC},
978 [L4ID_HDQ1WIRE_TA ] = {0x000b3000, 0x1000, L4TYPE_TA},
979 [L4ID_MMCSDIO2 ] = {0x000b4000, 0x1000, L4TYPE_GENERIC},
980 [L4ID_MMCSDIO2_TA ] = {0x000b5000, 0x1000, L4TYPE_TA},
981 [L4ID_ICRMPU ] = {0x000b6000, 0x1000, L4TYPE_GENERIC},
982 [L4ID_ICRMPU_TA ] = {0x000b7000, 0x1000, L4TYPE_TA},
983 [L4ID_MCSPI3 ] = {0x000b8000, 0x1000, L4TYPE_GENERIC},
984 [L4ID_MCSPI3_TA ] = {0x000b9000, 0x1000, L4TYPE_TA},
985 [L4ID_MCSPI4 ] = {0x000ba000, 0x1000, L4TYPE_GENERIC},
986 [L4ID_MCSPI4_TA ] = {0x000bb000, 0x1000, L4TYPE_TA},
987 [L4ID_CAMERAISP ] = {0x000bc000, 0x4000, L4TYPE_GENERIC},
988 [L4ID_CAMERAISP_TA] = {0x000c0000, 0x1000, L4TYPE_TA},
989 [L4ID_ICRMODEM ] = {0x000cd000, 0x1000, L4TYPE_GENERIC},
990 [L4ID_ICRMODEM_TA ] = {0x000ce000, 0x1000, L4TYPE_TA},
991 /* L4-Wakeup interconnect region A */
992 [L4ID_GPTIMER12 ] = {0x00304000, 0x1000, L4TYPE_GENERIC},
993 [L4ID_GPTIMER12_TA] = {0x00305000, 0x1000, L4TYPE_TA},
994 [L4ID_PRM_A ] = {0x00306000, 0x2000, L4TYPE_GENERIC},
995 [L4ID_PRM_B ] = {0x00308000, 0x0800, L4TYPE_GENERIC},
996 [L4ID_PRM_TA ] = {0x00309000, 0x1000, L4TYPE_TA},
998 [L4ID_TAP ] = {0x0030a000, 0x1000, L4TYPE_GENERIC},
999 [L4ID_TAP_TA ] = {0x0030b000, 0x1000, L4TYPE_TA},
1000 /* L4-Wakeup interconnect region B */
1001 [L4ID_GPIO1 ] = {0x00310000, 0x1000, L4TYPE_GENERIC},
1002 [L4ID_GPIO1_TA ] = {0x00311000, 0x1000, L4TYPE_TA},
1003 [L4ID_WDTIMER2 ] = {0x00314000, 0x1000, L4TYPE_GENERIC},
1004 [L4ID_WDTIMER2_TA ] = {0x00315000, 0x1000, L4TYPE_TA},
1005 [L4ID_GPTIMER1 ] = {0x00318000, 0x1000, L4TYPE_GENERIC},
1006 [L4ID_GPTIMER1_TA ] = {0x00319000, 0x1000, L4TYPE_TA},
1007 [L4ID_32KTIMER ] = {0x00320000, 0x1000, L4TYPE_GENERIC},
1008 [L4ID_32KTIMER_TA ] = {0x00321000, 0x1000, L4TYPE_TA},
1009 [L4ID_WAKEUP_AP ] = {0x00328000, 0x0800, L4TYPE_AP},
1010 [L4ID_WAKEUP_C_IP ] = {0x00328800, 0x0800, L4TYPE_IA},
1011 [L4ID_WAKEUP_LA ] = {0x00329000, 0x1000, L4TYPE_LA},
1012 [L4ID_WAKEUP_E_IP ] = {0x0032a000, 0x0800, L4TYPE_IA},
1014 [L4ID_PER_AP ] = {0x01000000, 0x0800, L4TYPE_AP},
1015 [L4ID_PER_IP ] = {0x01000800, 0x0800, L4TYPE_IA},
1016 [L4ID_PER_LA ] = {0x01001000, 0x1000, L4TYPE_LA},
1017 [L4ID_UART3 ] = {0x01020000, 0x1000, L4TYPE_GENERIC},
1018 [L4ID_UART3_TA ] = {0x01021000, 0x1000, L4TYPE_TA},
1019 [L4ID_MCBSP2 ] = {0x01022000, 0x1000, L4TYPE_GENERIC},
1020 [L4ID_MCBSP2_TA ] = {0x01023000, 0x1000, L4TYPE_TA},
1021 [L4ID_MCBSP3 ] = {0x01024000, 0x1000, L4TYPE_GENERIC},
1022 [L4ID_MCBSP3_TA ] = {0x01025000, 0x1000, L4TYPE_TA},
1023 [L4ID_MCBSP4 ] = {0x01026000, 0x1000, L4TYPE_GENERIC},
1024 [L4ID_MCBSP4_TA ] = {0x01027000, 0x1000, L4TYPE_TA},
1025 [L4ID_MCBSP2S ] = {0x01028000, 0x1000, L4TYPE_GENERIC},
1026 [L4ID_MCBSP2S_TA ] = {0x01029000, 0x1000, L4TYPE_TA},
1027 [L4ID_MCBSP3S ] = {0x0102a000, 0x1000, L4TYPE_GENERIC},
1028 [L4ID_MCBSP3S_TA ] = {0x0102b000, 0x1000, L4TYPE_TA},
1029 [L4ID_WDTIMER3 ] = {0x01030000, 0x1000, L4TYPE_GENERIC},
1030 [L4ID_WDTIMER3_TA ] = {0x01031000, 0x1000, L4TYPE_TA},
1031 [L4ID_GPTIMER2 ] = {0x01032000, 0x1000, L4TYPE_GENERIC},
1032 [L4ID_GPTIMER2_TA ] = {0x01033000, 0x1000, L4TYPE_TA},
1033 [L4ID_GPTIMER3 ] = {0x01034000, 0x1000, L4TYPE_GENERIC},
1034 [L4ID_GPTIMER3_TA ] = {0x01035000, 0x1000, L4TYPE_TA},
1035 [L4ID_GPTIMER4 ] = {0x01036000, 0x1000, L4TYPE_GENERIC},
1036 [L4ID_GPTIMER4_TA ] = {0x01037000, 0x1000, L4TYPE_TA},
1037 [L4ID_GPTIMER5 ] = {0x01038000, 0x1000, L4TYPE_GENERIC},
1038 [L4ID_GPTIMER5_TA ] = {0x01039000, 0x1000, L4TYPE_TA},
1039 [L4ID_GPTIMER6 ] = {0x0103a000, 0x1000, L4TYPE_GENERIC},
1040 [L4ID_GPTIMER6_TA ] = {0x0103b000, 0x1000, L4TYPE_TA},
1041 [L4ID_GPTIMER7 ] = {0x0103c000, 0x1000, L4TYPE_GENERIC},
1042 [L4ID_GPTIMER7_TA ] = {0x0103d000, 0x1000, L4TYPE_TA},
1043 [L4ID_GPTIMER8 ] = {0x0103e000, 0x1000, L4TYPE_GENERIC},
1044 [L4ID_GPTIMER8_TA ] = {0x0103f000, 0x1000, L4TYPE_TA},
1045 [L4ID_GPTIMER9 ] = {0x01040000, 0x1000, L4TYPE_GENERIC},
1046 [L4ID_GPTIMER9_TA ] = {0x01041000, 0x1000, L4TYPE_TA},
1047 [L4ID_GPIO2 ] = {0x01050000, 0x1000, L4TYPE_GENERIC},
1048 [L4ID_GPIO2_TA ] = {0x01051000, 0x1000, L4TYPE_TA},
1049 [L4ID_GPIO3 ] = {0x01052000, 0x1000, L4TYPE_GENERIC},
1050 [L4ID_GPIO3_TA ] = {0x01053000, 0x1000, L4TYPE_TA},
1051 [L4ID_GPIO4 ] = {0x01054000, 0x1000, L4TYPE_GENERIC},
1052 [L4ID_GPIO4_TA ] = {0x01055000, 0x1000, L4TYPE_TA},
1053 [L4ID_GPIO5 ] = {0x01056000, 0x1000, L4TYPE_GENERIC},
1054 [L4ID_GPIO5_TA ] = {0x01057000, 0x1000, L4TYPE_TA},
1055 [L4ID_GPIO6 ] = {0x01058000, 0x1000, L4TYPE_GENERIC},
1056 [L4ID_GPIO6_TA ] = {0x01059000, 0x1000, L4TYPE_TA},
1058 [L4ID_EMU_AP ] = {0x0c006000, 0x0800, L4TYPE_AP},
1059 [L4ID_EMU_IP_C ] = {0x0c006800, 0x0800, L4TYPE_IA},
1060 [L4ID_EMU_LA ] = {0x0c007000, 0x1000, L4TYPE_LA},
1061 [L4ID_EMU_IP_DAP ] = {0x0c008000, 0x0800, L4TYPE_IA},
1062 [L4ID_MPUEMU ] = {0x0c010000, 0x8000, L4TYPE_GENERIC},
1063 [L4ID_MPUEMU_TA ] = {0x0c018000, 0x1000, L4TYPE_TA},
1064 [L4ID_TPIU ] = {0x0c019000, 0x1000, L4TYPE_GENERIC},
1065 [L4ID_TPIU_TA ] = {0x0c01a000, 0x1000, L4TYPE_TA},
1066 [L4ID_ETB ] = {0x0c01b000, 0x1000, L4TYPE_GENERIC},
1067 [L4ID_ETB_TA ] = {0x0c01c000, 0x1000, L4TYPE_TA},
1068 [L4ID_DAPCTL ] = {0x0c01d000, 0x1000, L4TYPE_GENERIC},
1069 [L4ID_DAPCTL_TA ] = {0x0c01e000, 0x1000, L4TYPE_TA},
1070 [L4ID_EMU_PRM_A ] = {0x0c706000, 0x2000, L4TYPE_GENERIC},
1071 [L4ID_EMU_PRM_B ] = {0x0c706800, 0x0800, L4TYPE_GENERIC},
1072 [L4ID_EMU_PRM_TA ] = {0x0c709000, 0x1000, L4TYPE_TA},
1073 [L4ID_EMU_GPIO1 ] = {0x0c710000, 0x1000, L4TYPE_GENERIC},
1074 [L4ID_EMU_GPIO1_TA] = {0x0c711000, 0x1000, L4TYPE_TA},
1075 [L4ID_EMU_WDTM2 ] = {0x0c714000, 0x1000, L4TYPE_GENERIC},
1076 [L4ID_EMU_WDTM2_TA] = {0x0c715000, 0x1000, L4TYPE_TA},
1077 [L4ID_EMU_GPTM1 ] = {0x0c718000, 0x1000, L4TYPE_GENERIC},
1078 [L4ID_EMU_GPTM1_TA] = {0x0c719000, 0x1000, L4TYPE_TA},
1079 [L4ID_EMU_32KTM ] = {0x0c720000, 0x1000, L4TYPE_GENERIC},
1080 [L4ID_EMU_32KTM_TA] = {0x0c721000, 0x1000, L4TYPE_TA},
1081 [L4ID_EMU_WKUP_AP ] = {0x0c728000, 0x0800, L4TYPE_AP},
1082 [L4ID_EMU_WKUP_IPC] = {0x0c728800, 0x0800, L4TYPE_IA},
1083 [L4ID_EMU_WKUP_LA ] = {0x0c729000, 0x1000, L4TYPE_LA},
1084 [L4ID_EMU_WKUP_IPE] = {0x0c72a000, 0x0800, L4TYPE_IA},
1122 } omap3_l4_agent_info_id_t;
1124 struct omap3_l4_agent_info_s {
1125 omap3_l4_agent_info_id_t agent_id;
1126 omap3_l4_region_id_t first_region_id;
1130 static const struct omap3_l4_agent_info_s omap3_l4_agent_info[] = {
1131 /* L4-Core Agents */
1132 {L4A_DSS, L4ID_DSI, 6},
1134 /* TODO: USBHS OTG */
1135 /* TODO: USBHS host */
1137 {L4A_UART1, L4ID_UART1, 2},
1138 {L4A_UART2, L4ID_UART2, 2},
1139 {L4A_I2C1, L4ID_I2C1, 2},
1140 {L4A_I2C2, L4ID_I2C2, 2},
1141 {L4A_I2C3, L4ID_I2C3, 2},
1144 {L4A_GPTIMER10, L4ID_GPTIMER10, 2},
1145 {L4A_GPTIMER11, L4ID_GPTIMER11, 2},
1148 {L4A_MMC1, L4ID_MMCSDIO1, 2},
1149 {L4A_MMC2, L4ID_MMCSDIO2, 2},
1150 {L4A_MMC3, L4ID_MMCSDIO3, 2},
1151 /* TODO: HDQ/1-Wire */
1156 {L4A_CM, L4ID_CM_A, 3},
1157 {L4A_SCM, L4ID_SCM, 2},
1158 {L4A_TAP, L4ID_TAP, 2},
1159 /* L4-Wakeup Agents */
1160 {L4A_GPTIMER12, L4ID_GPTIMER12, 2},
1161 {L4A_PRM, L4ID_PRM_A, 3},
1162 {L4A_GPIO1, L4ID_GPIO1, 2},
1163 {L4A_WDTIMER2, L4ID_WDTIMER2, 2},
1164 {L4A_GPTIMER1, L4ID_GPTIMER1, 2},
1165 {L4A_32KTIMER, L4ID_32KTIMER, 2},
1167 {L4A_UART3, L4ID_UART3, 2},
1170 {L4A_GPTIMER2, L4ID_GPTIMER2, 2},
1171 {L4A_GPTIMER3, L4ID_GPTIMER3, 2},
1172 {L4A_GPTIMER4, L4ID_GPTIMER4, 2},
1173 {L4A_GPTIMER5, L4ID_GPTIMER5, 2},
1174 {L4A_GPTIMER6, L4ID_GPTIMER6, 2},
1175 {L4A_GPTIMER7, L4ID_GPTIMER7, 2},
1176 {L4A_GPTIMER8, L4ID_GPTIMER8, 2},
1177 {L4A_GPTIMER9, L4ID_GPTIMER9, 2},
1178 {L4A_GPIO2, L4ID_GPIO2, 2},
1179 {L4A_GPIO3, L4ID_GPIO3, 2},
1180 {L4A_GPIO4, L4ID_GPIO4, 2},
1181 {L4A_GPIO5, L4ID_GPIO5, 2},
1182 {L4A_GPIO6, L4ID_GPIO6, 2},
1185 static uint32_t omap3_l4ta_read(void *opaque, target_phys_addr_t addr)
1187 struct omap_target_agent_s *s = (struct omap_target_agent_s *)opaque;
1190 case 0x00: /* COMPONENT_L */
1191 return s->component;
1192 case 0x04: /* COMPONENT_H */
1194 case 0x18: /* CORE_L */
1195 return s->component;
1196 case 0x1c: /* CORE_H */
1197 return (s->component >> 16);
1198 case 0x20: /* AGENT_CONTROL_L */
1200 case 0x24: /* AGENT_CONTROL_H */
1201 return s->control_h;
1202 case 0x28: /* AGENT_STATUS_L */
1204 case 0x2c: /* AGENT_STATUS_H */
1210 OMAP_BAD_REG(s->base + addr);
1214 static void omap3_l4ta_write(void *opaque, target_phys_addr_t addr,
1217 struct omap_target_agent_s *s = (struct omap_target_agent_s *)opaque;
1220 case 0x00: /* COMPONENT_L */
1221 case 0x04: /* COMPONENT_H */
1222 case 0x18: /* CORE_L */
1223 case 0x1c: /* CORE_H */
1224 OMAP_RO_REG(s->base + addr);
1226 case 0x20: /* AGENT_CONTROL_L */
1227 s->control = value & 0x00000701;
1229 case 0x24: /* AGENT_CONTROL_H */
1230 s->control_h = value & 0x100; /* TODO: shouldn't this be read-only? */
1232 case 0x28: /* AGENT_STATUS_L */
1234 s->status &= ~0x100; /* REQ_TIMEOUT */
1236 case 0x2c: /* AGENT_STATUS_H */
1237 /* no writable bits although the register is listed as RW */
1240 OMAP_BAD_REG(s->base + addr);
1245 static CPUReadMemoryFunc *omap3_l4ta_readfn[] = {
1246 omap_badwidth_read32,
1247 omap_badwidth_read32,
1251 static CPUWriteMemoryFunc *omap3_l4ta_writefn[] = {
1252 omap_badwidth_write32,
1253 omap_badwidth_write32,
1257 static struct omap_target_agent_s *omap3_l4ta_init(struct omap_l4_s *bus, int cs)
1260 struct omap_target_agent_s *ta = 0;
1261 const struct omap3_l4_agent_info_s *info = 0;
1263 for (i = 0; i < bus->ta_num; i++)
1264 if (omap3_l4_agent_info[i].agent_id == cs) {
1266 info = &omap3_l4_agent_info[i];
1270 fprintf(stderr, "%s: invalid agent id (%i)\n", __FUNCTION__, cs);
1274 fprintf(stderr, "%s: target agent (%d) already initialized\n",
1280 ta->start = &omap3_l4_region[info->first_region_id];
1281 ta->regions = info->region_count;
1283 ta->component = ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
1284 ta->status = 0x00000000;
1285 ta->control = 0x00000200;
1287 for (i = 0; i < info->region_count; i++)
1288 if (omap3_l4_region[info->first_region_id + i].access == L4TYPE_TA)
1290 if (i >= info->region_count) {
1291 fprintf(stderr, "%s: specified agent (%d) has no TA region\n",
1296 iomemtype = l4_register_io_memory(0, omap3_l4ta_readfn,
1297 omap3_l4ta_writefn, ta);
1298 ta->base = omap_l4_attach(ta, i, iomemtype);
1303 /* common PRM domain registers */
1304 struct omap3_prm_domain_s {
1305 uint32_t rm_rstctrl; /* 50 */
1306 uint32_t rm_rstst; /* 58 */
1307 uint32_t pm_wken; /* a0 */
1308 uint32_t pm_mpugrpsel; /* a4 */
1309 uint32_t pm_ivagrpsel; /* a8 */
1310 uint32_t pm_wkst; /* b0 */
1311 uint32_t pm_wkdep; /* c8 */
1312 uint32_t pm_pwstctrl; /* e0 */
1313 uint32_t pm_pwstst; /* e4 */
1314 uint32_t pm_prepwstst; /* e8 */
1317 struct omap3_prm_s {
1320 struct omap_mpu_state_s *omap;
1322 struct omap3_prm_domain_s iva2;
1323 struct omap3_prm_domain_s mpu;
1324 struct omap3_prm_domain_s core;
1325 struct omap3_prm_domain_s sgx;
1326 struct omap3_prm_domain_s wkup;
1327 struct omap3_prm_domain_s dss;
1328 struct omap3_prm_domain_s cam;
1329 struct omap3_prm_domain_s per;
1330 struct omap3_prm_domain_s emu;
1331 struct omap3_prm_domain_s neon;
1332 struct omap3_prm_domain_s usbhost;
1334 uint32_t iva2_prm_irqstatus;
1335 uint32_t iva2_prm_irqenable;
1337 uint32_t mpu_pm_evgenctrl;
1338 uint32_t mpu_pm_evgenontim;
1339 uint32_t mpu_pm_evgenofftim;
1341 uint32_t core_pm_wkst3;
1342 uint32_t core_pm_wken3;
1343 uint32_t core_pm_iva2grpsel3;
1344 uint32_t core_pm_mpugrpsel3;
1346 uint32_t prm_revision;
1347 uint32_t prm_sysconfig;
1348 uint32_t prm_irqstatus_mpu;
1349 uint32_t prm_irqenable_mpu;
1351 uint32_t prm_clksel;
1352 uint32_t prm_clkout_ctrl;
1354 uint32_t prm_vc_smps_sa;
1355 uint32_t prm_vc_smps_vol_ra;
1356 uint32_t prm_vc_smps_cmd_ra;
1357 uint32_t prm_vc_cmd_val_0;
1358 uint32_t prm_vc_cmd_val_1;
1359 uint32_t prm_vc_hc_conf;
1360 uint32_t prm_vc_i2c_cfg;
1361 uint32_t prm_vc_bypass_val;
1362 uint32_t prm_rstctrl;
1363 uint32_t prm_rsttimer;
1365 uint32_t prm_voltctrl;
1366 uint32_t prm_sram_pcharge;
1367 uint32_t prm_clksrc_ctrl;
1369 uint32_t prm_voltsetup1;
1370 uint32_t prm_voltoffset;
1371 uint32_t prm_clksetup;
1372 uint32_t prm_polctrl;
1373 uint32_t prm_voltsetup2;
1376 static void omap3_prm_int_update(struct omap3_prm_s *s)
1378 qemu_set_irq(s->mpu_irq, s->prm_irqstatus_mpu & s->prm_irqenable_mpu);
1379 qemu_set_irq(s->iva_irq, s->iva2_prm_irqstatus & s->iva2_prm_irqenable);
1382 static void omap3_prm_reset(struct omap3_prm_s *s)
1384 s->iva2.rm_rstctrl = 0x7;
1385 s->iva2.rm_rstst = 0x1;
1386 s->iva2.pm_wkdep = 0xb3;
1387 s->iva2.pm_pwstctrl = 0xff0f07;
1388 s->iva2.pm_pwstst = 0xff7;
1389 s->iva2.pm_prepwstst = 0x0;
1390 s->iva2_prm_irqstatus = 0x0;
1391 s->iva2_prm_irqenable = 0x0;
1393 s->prm_revision = 0x10;
1394 s->prm_sysconfig = 0x1;
1395 s->prm_irqstatus_mpu = 0x0;
1396 s->prm_irqenable_mpu = 0x0;
1398 s->mpu.rm_rstst = 0x1;
1399 s->mpu.pm_wkdep = 0xa5;
1400 s->mpu.pm_pwstctrl = 0x30107;
1401 s->mpu.pm_pwstst = 0xc7;
1402 s->mpu.pm_pwstst = 0x0;
1403 s->mpu_pm_evgenctrl = 0x12;
1404 s->mpu_pm_evgenontim = 0x0;
1405 s->mpu_pm_evgenofftim = 0x0;
1407 s->core.rm_rstst = 0x1;
1408 s->core.pm_wken = 0xc33ffe18;
1409 s->core.pm_mpugrpsel = 0xc33ffe18;
1410 s->core.pm_ivagrpsel = 0xc33ffe18;
1411 s->core.pm_wkst = 0x0;
1412 s->core.pm_pwstctrl = 0xf0307;
1413 s->core.pm_pwstst = 0xf7;
1414 s->core.pm_prepwstst = 0x0;
1415 s->core_pm_wkst3 = 0x0;
1416 s->core_pm_wken3 = 0x4;
1417 s->core_pm_iva2grpsel3 = 0x4;
1418 s->core_pm_mpugrpsel3 = 0x4;
1420 s->sgx.rm_rstst = 0x1;
1421 s->sgx.pm_wkdep = 0x16;
1422 s->sgx.pm_pwstctrl = 0x30107;
1423 s->sgx.pm_pwstst = 0x3;
1424 s->sgx.pm_prepwstst = 0x0;
1426 s->wkup.pm_wken = 0x3cb;
1427 s->wkup.pm_mpugrpsel = 0x3cb;
1428 s->wkup.pm_ivagrpsel = 0x0;
1429 s->wkup.pm_wkst = 0x0;
1430 s->wkup.pm_pwstst = 0x3; /* TODO: check on real hardware */
1432 s->prm_clksel = 0x4;
1433 s->prm_clkout_ctrl = 0x80;
1435 s->dss.rm_rstst = 0x1;
1436 s->dss.pm_wken = 0x1;
1437 s->dss.pm_wkdep = 0x16;
1438 s->dss.pm_pwstctrl = 0x30107;
1439 s->dss.pm_pwstst = 0x3;
1440 s->dss.pm_prepwstst = 0x0;
1442 s->cam.rm_rstst = 0x1;
1443 s->cam.pm_wkdep = 0x16;
1444 s->cam.pm_pwstctrl = 0x30107;
1445 s->cam.pm_pwstst = 0x3;
1446 s->cam.pm_prepwstst = 0x0;
1448 s->per.rm_rstst = 0x1;
1449 s->per.pm_wken = 0x3efff;
1450 s->per.pm_mpugrpsel = 0x3efff;
1451 s->per.pm_ivagrpsel = 0x3efff;
1452 s->per.pm_wkst = 0x0;
1453 s->per.pm_wkdep = 0x17;
1454 s->per.pm_pwstctrl = 0x30107;
1455 s->per.pm_pwstst = 0x7;
1456 s->per.pm_prepwstst = 0x0;
1458 s->emu.rm_rstst = 0x1;
1459 s->emu.pm_pwstst = 0x13;
1461 s->prm_vc_smps_sa = 0x0;
1462 s->prm_vc_smps_vol_ra = 0x0;
1463 s->prm_vc_smps_cmd_ra = 0x0;
1464 s->prm_vc_cmd_val_0 = 0x0;
1465 s->prm_vc_cmd_val_1 = 0x0;
1466 s->prm_vc_hc_conf = 0x0;
1467 s->prm_vc_i2c_cfg = 0x18;
1468 s->prm_vc_bypass_val = 0x0;
1469 s->prm_rstctrl = 0x0;
1470 s->prm_rsttimer = 0x1006;
1472 s->prm_voltctrl = 0x0;
1473 s->prm_sram_pcharge = 0x50;
1474 s->prm_clksrc_ctrl = 0x43;
1476 s->prm_voltsetup1 = 0x0;
1477 s->prm_voltoffset = 0x0;
1478 s->prm_clksetup = 0x0;
1479 s->prm_polctrl = 0xa;
1480 s->prm_voltsetup2 = 0x0;
1482 s->neon.rm_rstst = 0x1;
1483 s->neon.pm_wkdep = 0x2;
1484 s->neon.pm_pwstctrl = 0x7;
1485 s->neon.pm_pwstst = 0x3;
1486 s->neon.pm_prepwstst = 0x0;
1488 s->usbhost.rm_rstst = 0x1;
1489 s->usbhost.pm_wken = 0x1;
1490 s->usbhost.pm_mpugrpsel = 0x1;
1491 s->usbhost.pm_ivagrpsel = 0x1;
1492 s->usbhost.pm_wkst = 0x0;
1493 s->usbhost.pm_wkdep = 0x17;
1494 s->usbhost.pm_pwstctrl = 0x30107;
1495 s->usbhost.pm_pwstst = 0x3;
1496 s->usbhost.pm_prepwstst = 0x0;
1498 omap3_prm_int_update(s);
1501 static uint32_t omap3_prm_read(void *opaque, target_phys_addr_t addr)
1503 struct omap3_prm_s *s = (struct omap3_prm_s *)opaque;
1504 struct omap3_prm_domain_s *d = 0;
1506 TRACE("%04x", addr);
1508 /* handle common domain registers first - all domains may not
1509 have all common registers though but we're returning zeroes there */
1510 switch ((addr >> 8) & 0xff) {
1511 case 0x00: d = &s->iva2; break;
1512 case 0x09: d = &s->mpu; break;
1513 case 0x0a: d = &s->core; break;
1514 case 0x0b: d = &s->sgx; break;
1515 case 0x0c: d = &s->wkup; break;
1516 case 0x0e: d = &s->dss; break;
1517 case 0x0f: d = &s->cam; break;
1518 case 0x10: d = &s->per; break;
1519 case 0x11: d = &s->emu; break;
1520 case 0x13: d = &s->neon; break;
1521 case 0x14: d = &s->usbhost; break;
1525 switch (addr & 0xff) {
1526 case 0x50: return d->rm_rstctrl;
1527 case 0x58: return d->rm_rstst;
1528 case 0xa0: return d->pm_wken;
1529 case 0xa4: return d->pm_mpugrpsel;
1530 case 0xa8: return d->pm_ivagrpsel;
1531 case 0xb0: return d->pm_wkst;
1532 case 0xc8: return d->pm_wkdep;
1533 case 0xe0: return d->pm_pwstctrl;
1534 case 0xe4: return d->pm_pwstst;
1535 case 0xe8: return d->pm_prepwstst;
1539 /* okay, not a common domain register so let's take a closer look */
1541 case 0x00f8: return s->iva2_prm_irqstatus;
1542 case 0x00fc: return s->iva2_prm_irqenable;
1543 case 0x0804: return s->prm_revision;
1544 case 0x0814: return s->prm_sysconfig;
1545 case 0x0818: return s->prm_irqstatus_mpu;
1546 case 0x081c: return s->prm_irqenable_mpu;
1547 case 0x09d4: return s->mpu_pm_evgenctrl;
1548 case 0x09d8: return s->mpu_pm_evgenontim;
1549 case 0x09dc: return s->mpu_pm_evgenofftim;
1550 case 0x0ab8: return s->core_pm_wkst3;
1551 case 0x0af0: return s->core_pm_wken3;
1552 case 0x0af4: return s->core_pm_iva2grpsel3;
1553 case 0x0af8: return s->core_pm_mpugrpsel3;
1554 case 0x0d40: return s->prm_clksel;
1555 case 0x0d70: return s->prm_clkout_ctrl;
1556 case 0x0de4: return 0x3; /* TODO: check on real hardware */
1557 case 0x1220: return s->prm_vc_smps_sa;
1558 case 0x1224: return s->prm_vc_smps_vol_ra;
1559 case 0x1228: return s->prm_vc_smps_cmd_ra;
1560 case 0x122c: return s->prm_vc_cmd_val_0;
1561 case 0x1230: return s->prm_vc_cmd_val_1;
1562 case 0x1234: return s->prm_vc_hc_conf;
1563 case 0x1238: return s->prm_vc_i2c_cfg;
1564 case 0x123c: return s->prm_vc_bypass_val;
1565 case 0x1250: return s->prm_rstctrl;
1566 case 0x1254: return s->prm_rsttimer;
1567 case 0x1258: return s->prm_rstst;
1568 case 0x1260: return s->prm_voltctrl;
1569 case 0x1264: return s->prm_sram_pcharge;
1570 case 0x1270: return s->prm_clksrc_ctrl;
1571 case 0x1280: return s->prm_obs;
1572 case 0x1290: return s->prm_voltsetup1;
1573 case 0x1294: return s->prm_voltoffset;
1574 case 0x1298: return s->prm_clksetup;
1575 case 0x129c: return s->prm_polctrl;
1576 case 0x12a0: return s->prm_voltsetup2;
1584 static inline void omap3_prm_clksrc_ctrl_update(struct omap3_prm_s *s,
1587 if ((value & 0xd0) == 0x40)
1588 omap_clk_setrate(omap_findclk(s->omap, "omap3_sys_clk"), 1, 1);
1589 else if ((value & 0xd0) == 0x80)
1590 omap_clk_setrate(omap_findclk(s->omap, "omap3_sys_clk"), 2, 1);
1593 static void omap3_prm_write(void *opaque, target_phys_addr_t addr,
1596 struct omap3_prm_s *s = (struct omap3_prm_s *)opaque;
1598 TRACE("%04x = %08x", addr, value);
1601 case 0x0050: s->iva2.rm_rstctrl = value & 0x7; break;
1602 case 0x0058: s->iva2.rm_rstst &= ~(value & 0x3f0f); break;
1603 case 0x00c8: s->iva2.pm_wkdep = value & 0xb3; break;
1604 case 0x00e0: s->iva2.pm_pwstctrl = 0xcff000 | (value & 0x300f0f); break;
1605 case 0x00e4: OMAP_RO_REG(addr); break;
1606 case 0x00e8: s->iva2.pm_prepwstst = value & 0xff7;
1608 s->iva2_prm_irqstatus &= ~(value & 0x7);
1609 omap3_prm_int_update(s);
1612 s->iva2_prm_irqenable = value & 0x7;
1613 omap3_prm_int_update(s);
1615 /* OCP_System_Reg_PRM */
1616 case 0x0804: OMAP_RO_REG(addr); break;
1617 case 0x0814: s->prm_sysconfig = value & 0x1; break;
1619 s->prm_irqstatus_mpu &= ~(value & 0x03c003fd);
1620 omap3_prm_int_update(s);
1623 s->prm_irqenable_mpu = value & 0x03c003fd;
1624 omap3_prm_int_update(s);
1627 case 0x0958: s->mpu.rm_rstst &= ~(value & 0x080f); break;
1628 case 0x09c8: s->mpu.pm_wkdep = value & 0xa5; break;
1629 case 0x09d4: s->mpu_pm_evgenctrl = value & 0x1f; break;
1630 case 0x09d8: s->mpu_pm_evgenontim = value; break;
1631 case 0x09dc: s->mpu_pm_evgenofftim = value; break;
1632 case 0x09e0: s->mpu.pm_pwstctrl = value & 0x3010f; break;
1633 case 0x09e4: OMAP_RO_REG(addr); break;
1634 case 0x09e8: s->mpu.pm_prepwstst = value & 0xc7; break;
1636 case 0x0a50: s->core.rm_rstctrl = value & 0x3; break; /* TODO: check if available on real hw */
1637 case 0x0a58: s->core.rm_rstst &= ~(value & 0x7); break;
1638 case 0x0aa0: s->core.pm_wken = 0x80000008 | (value & 0x433ffe10); break;
1639 case 0x0aa4: s->core.pm_mpugrpsel = 0x80000008 | (value & 0x433ffe10); break;
1640 case 0x0aa8: s->core.pm_ivagrpsel = 0x80000008 | (value & 0x433ffe10); break;
1641 case 0x0ab0: s->core.pm_wkst = value & 0x433ffe10; break;
1642 case 0x0ab8: s->core_pm_wkst3 &= ~(value & 0x4); break;
1643 case 0x0ae0: s->core.pm_pwstctrl = (value & 0x0f031f); break;
1644 case 0x0ae4: OMAP_RO_REG(addr); break;
1645 case 0x0ae8: s->core.pm_prepwstst = value & 0xf7; break;
1646 case 0x0af0: s->core_pm_wken3 = value & 0x4; break;
1647 case 0x0af4: s->core_pm_iva2grpsel3 = value & 0x4; break;
1648 case 0x0af8: s->core_pm_mpugrpsel3 = value & 0x4; break;
1650 case 0x0b58: s->sgx.rm_rstst &= ~(value & 0xf); break;
1651 case 0x0bc8: s->sgx.pm_wkdep = value & 0x16; break;
1652 case 0x0be0: s->sgx.pm_pwstctrl = 0x030104 | (value & 0x3); break;
1653 case 0x0be4: OMAP_RO_REG(addr); break;
1654 case 0x0be8: s->sgx.pm_prepwstst = value & 0x3; break;
1656 case 0x0ca0: s->wkup.pm_wken = 0x2 | (value & 0x0103c9); break;
1657 case 0x0ca4: s->wkup.pm_mpugrpsel = 0x0102 | (value & 0x02c9); break;
1658 case 0x0ca8: s->wkup.pm_ivagrpsel = value & 0x03cb; break;
1659 case 0x0cb0: s->wkup.pm_wkst &= ~(value & 0x0103cb); break;
1660 /* Clock_Control_Reg_PRM */
1662 s->prm_clksel = value & 0x7;
1663 fprintf(stderr, "%s PRM_CLKSEL = 0x%x\n", __FUNCTION__,
1665 /* TODO: update clocks */
1668 s->prm_clkout_ctrl = value & 0x80;
1669 fprintf(stderr, "%s PRM_CLKOUT_CTRL = 0x%x\n", __FUNCTION__,
1670 s->prm_clkout_ctrl);
1671 /* TODO: update clocks */
1674 case 0x0e58: s->dss.rm_rstst &= ~(value & 0xf); break;
1675 case 0x0ea0: s->dss.pm_wken = value & 1; break;
1676 case 0x0ec8: s->dss.pm_wkdep = value & 0x16; break;
1677 case 0x0ee0: s->dss.pm_pwstctrl = 0x030104 | (value & 3); break;
1678 case 0x0ee4: OMAP_RO_REG(addr); break;
1679 case 0x0ee8: s->dss.pm_prepwstst = value & 3; break;
1681 case 0x0f58: s->cam.rm_rstst &= (value & 0xf); break;
1682 case 0x0fc8: s->cam.pm_wkdep = value & 0x16; break;
1683 case 0x0fe0: s->cam.pm_pwstctrl = 0x030104 | (value & 3); break;
1684 case 0x0fe4: OMAP_RO_REG(addr); break;
1685 case 0x0fe8: s->cam.pm_prepwstst = value & 0x3; break;
1687 case 0x1058: s->per.rm_rstst &= ~(value & 0xf); break;
1688 case 0x10a0: s->per.pm_wken = value & 0x03efff; break;
1689 case 0x10a4: s->per.pm_mpugrpsel = value & 0x03efff; break;
1690 case 0x10a8: s->per.pm_ivagrpsel = value & 0x03efff; break;
1691 case 0x10b0: s->per.pm_wkst &= ~(value & 0x03efff); break;
1692 case 0x10c8: s->per.pm_wkdep = value & 0x17; break;
1693 case 0x10e0: s->per.pm_pwstctrl = 0x030100 | (value & 7); break;
1694 case 0x10e4: OMAP_RO_REG(addr); break;
1695 case 0x10e8: s->per.pm_prepwstst = value & 0x7; break;
1697 case 0x1158: s->emu.rm_rstst &= ~(value & 7); break;
1698 case 0x11e4: OMAP_RO_REG(addr); break;
1699 /* Global_Reg_PRM */
1700 case 0x1220: s->prm_vc_smps_sa = value & 0x7f007f; break;
1701 case 0x1224: s->prm_vc_smps_vol_ra = value & 0xff00ff; break;
1702 case 0x1228: s->prm_vc_smps_cmd_ra = value & 0xff00ff; break;
1703 case 0x122c: s->prm_vc_cmd_val_0 = value; break;
1704 case 0x1230: s->prm_vc_cmd_val_1 = value; break;
1705 case 0x1234: s->prm_vc_hc_conf = value & 0x1f001f; break;
1706 case 0x1238: s->prm_vc_i2c_cfg = value & 0x3f; break;
1707 case 0x123c: s->prm_vc_bypass_val = value & 0x01ffff7f; break;
1708 case 0x1250: s->prm_rstctrl = 0; break; /* TODO: resets */
1709 case 0x1254: s->prm_rsttimer = value & 0x1fff; break;
1710 case 0x1258: s->prm_rstst &= ~(value & 0x7fb); break;
1711 case 0x1260: s->prm_voltctrl = value & 0x1f; break;
1712 case 0x1264: s->prm_sram_pcharge = value & 0xff; break;
1714 s->prm_clksrc_ctrl = value & (0xd8);
1715 omap3_prm_clksrc_ctrl_update(s, s->prm_clksrc_ctrl);
1716 /* TODO: update SYSCLKSEL bits */
1718 case 0x1280: OMAP_RO_REG(addr); break;
1719 case 0x1290: s->prm_voltsetup1 = value; break;
1720 case 0x1294: s->prm_voltoffset = value & 0xffff; break;
1721 case 0x1298: s->prm_clksetup = value & 0xffff; break;
1722 case 0x129c: s->prm_polctrl = value & 0xf; break;
1723 case 0x12a0: s->prm_voltsetup2 = value & 0xffff; break;
1725 case 0x1358: s->neon.rm_rstst &= ~(value & 0xf); break;
1726 case 0x13c8: s->neon.pm_wkdep = value & 0x2; break;
1727 case 0x13e0: s->neon.pm_pwstctrl = 0x4 | (value & 3); break;
1728 case 0x13e4: OMAP_RO_REG(addr); break;
1729 case 0x13e8: s->neon.pm_prepwstst = value & 3; break;
1731 case 0x1458: s->usbhost.rm_rstst &= ~(value & 0xf); break;
1732 case 0x14a0: s->usbhost.pm_wken = value & 1; break;
1733 case 0x14a4: s->usbhost.pm_mpugrpsel = value & 1; break;
1734 case 0x14a8: s->usbhost.pm_ivagrpsel = value & 1; break;
1735 case 0x14b0: s->usbhost.pm_wkst &= ~(value & 1); break;
1736 case 0x14c8: s->usbhost.pm_wkdep = value & 0x17; break;
1737 case 0x14e0: s->usbhost.pm_pwstctrl = 0x030104 | (value & 0x13); break;
1738 case 0x14e4: OMAP_RO_REG(addr); break;
1739 case 0x14e8: s->usbhost.pm_prepwstst = value & 3; break;
1741 OMAP_BAD_REGV(addr, value);
1746 static CPUReadMemoryFunc *omap3_prm_readfn[] = {
1747 omap_badwidth_read32,
1748 omap_badwidth_read32,
1752 static CPUWriteMemoryFunc *omap3_prm_writefn[] = {
1753 omap_badwidth_write32,
1754 omap_badwidth_write32,
1758 struct omap3_prm_s *omap3_prm_init(struct omap_target_agent_s *ta,
1759 qemu_irq mpu_int, qemu_irq iva_int,
1760 struct omap_mpu_state_s *mpu)
1763 struct omap3_prm_s *s = (struct omap3_prm_s *) qemu_mallocz(sizeof(*s));
1765 s->mpu_irq = mpu_int;
1766 s->iva_irq = iva_int;
1770 iomemtype = l4_register_io_memory(0, omap3_prm_readfn,
1771 omap3_prm_writefn, s);
1772 omap_l4_attach(ta, 0, iomemtype);
1773 omap_l4_attach(ta, 1, iomemtype);
1782 struct omap_mpu_state_s *mpu;
1784 /*IVA2_CM Register */
1785 uint32_t cm_fclken_iva2; /*0x4800 4000 */
1786 uint32_t cm_clken_pll_iva2; /*0x4800 4004 */
1787 uint32_t cm_idlest_iva2; /*0x4800 4020 */
1788 uint32_t cm_idlest_pll_iva2; /*0x4800 4024 */
1789 uint32_t cm_autoidle_pll_iva2; /*0x4800 4034 */
1790 uint32_t cm_clksel1_pll_iva2; /*0x4800 4040 */
1791 uint32_t cm_clksel2_pll_iva2; /*0x4800 4044 */
1792 uint32_t cm_clkstctrl_iva2; /*0x4800 4048 */
1793 uint32_t cm_clkstst_iva2; /*0x4800 404c */
1795 /*OCP_System_Reg_CM */
1796 uint32_t cm_revision; /*0x4800 4800 */
1797 uint32_t cm_sysconfig; /*0x4800 4810 */
1799 /*MPU_CM Register */
1800 uint32_t cm_clken_pll_mpu; /*0x4800 4904 */
1801 uint32_t cm_idlest_mpu; /*0x4800 4920 */
1802 uint32_t cm_idlest_pll_mpu; /*0x4800 4924 */
1803 uint32_t cm_autoidle_pll_mpu; /*0x4800 4934 */
1804 uint32_t cm_clksel1_pll_mpu; /*0x4800 4940 */
1805 uint32_t cm_clksel2_pll_mpu; /*0x4800 4944 */
1806 uint32_t cm_clkstctrl_mpu; /*0x4800 4948 */
1807 uint32_t cm_clkstst_mpu; /*0x4800 494c */
1809 /*CORE_CM Register */
1810 uint32_t cm_fclken1_core; /*0x4800 4a00 */
1811 uint32_t cm_fclken3_core; /*0x4800 4a08 */
1812 uint32_t cm_iclken1_core; /*0x4800 4a10 */
1813 uint32_t cm_iclken2_core; /*0x4800 4a14 */
1814 uint32_t cm_iclken3_core; /*0x4800 4a18 */
1815 uint32_t cm_idlest1_core; /*0x4800 4a20 */
1816 uint32_t cm_idlest2_core; /*0x4800 4a24 */
1817 uint32_t cm_idlest3_core; /*0x4800 4a28 */
1818 uint32_t cm_autoidle1_core; /*0x4800 4a30 */
1819 uint32_t cm_autoidle2_core; /*0x4800 4a34 */
1820 uint32_t cm_autoidle3_core; /*0x4800 4a38 */
1821 uint32_t cm_clksel_core; /*0x4800 4a40 */
1822 uint32_t cm_clkstctrl_core; /*0x4800 4a48 */
1823 uint32_t cm_clkstst_core; /*0x4800 4a4c */
1825 /*SGX_CM Register */
1826 uint32_t cm_fclken_sgx; /*0x4800 4b00 */
1827 uint32_t cm_iclken_sgx; /*0x4800 4b10 */
1828 uint32_t cm_idlest_sgx; /*0x4800 4b20 */
1829 uint32_t cm_clksel_sgx; /*0x4800 4b40 */
1830 uint32_t cm_sleepdep_sgx; /*0x4800 4b44 */
1831 uint32_t cm_clkstctrl_sgx; /*0x4800 4b48 */
1832 uint32_t cm_clkstst_sgx; /*0x4800 4b4c */
1834 /*WKUP_CM Register */
1835 uint32_t cm_fclken_wkup; /*0x4800 4c00 */
1836 uint32_t cm_iclken_wkup; /*0x4800 4c10 */
1837 uint32_t cm_idlest_wkup; /*0x4800 4c20 */
1838 uint32_t cm_autoidle_wkup; /*0x4800 4c30 */
1839 uint32_t cm_clksel_wkup; /*0x4800 4c40 */
1840 uint32_t cm_c48; /*0x4800 4c48 */
1842 /*Clock_Control_Reg_CM Register */
1843 uint32_t cm_clken_pll; /*0x4800 4d00 */
1844 uint32_t cm_clken2_pll; /*0x4800 4d04 */
1845 uint32_t cm_idlest_ckgen; /*0x4800 4d20 */
1846 uint32_t cm_idlest2_ckgen; /*0x4800 4d24 */
1847 uint32_t cm_autoidle_pll; /*0x4800 4d30 */
1848 uint32_t cm_autoidle2_pll; /*0x4800 4d34 */
1849 uint32_t cm_clksel1_pll; /*0x4800 4d40 */
1850 uint32_t cm_clksel2_pll; /*0x4800 4d44 */
1851 uint32_t cm_clksel3_pll; /*0x4800 4d48 */
1852 uint32_t cm_clksel4_pll; /*0x4800 4d4c */
1853 uint32_t cm_clksel5_pll; /*0x4800 4d50 */
1854 uint32_t cm_clkout_ctrl; /*0x4800 4d70 */
1856 /*DSS_CM Register */
1857 uint32_t cm_fclken_dss; /*0x4800 4e00 */
1858 uint32_t cm_iclken_dss; /*0x4800 4e10 */
1859 uint32_t cm_idlest_dss; /*0x4800 4e20 */
1860 uint32_t cm_autoidle_dss; /*0x4800 4e30 */
1861 uint32_t cm_clksel_dss; /*0x4800 4e40 */
1862 uint32_t cm_sleepdep_dss; /*0x4800 4e44 */
1863 uint32_t cm_clkstctrl_dss; /*0x4800 4e48 */
1864 uint32_t cm_clkstst_dss; /*0x4800 4e4c */
1867 /*CAM_CM Register */
1868 uint32_t cm_fclken_cam; /*0x4800 4f00 */
1869 uint32_t cm_iclken_cam; /*0x4800 4f10 */
1870 uint32_t cm_idlest_cam; /*0x4800 4f20 */
1871 uint32_t cm_autoidle_cam; /*0x4800 4f30 */
1872 uint32_t cm_clksel_cam; /*0x4800 4f40 */
1873 uint32_t cm_sleepdep_cam; /*0x4800 4f44 */
1874 uint32_t cm_clkstctrl_cam; /*0x4800 4f48 */
1875 uint32_t cm_clkstst_cam; /*0x4800 4f4c */
1877 /*PER_CM Register */
1878 uint32_t cm_fclken_per; /*0x4800 5000 */
1879 uint32_t cm_iclken_per; /*0x4800 5010 */
1880 uint32_t cm_idlest_per; /*0x4800 5020 */
1881 uint32_t cm_autoidle_per; /*0x4800 5030 */
1882 uint32_t cm_clksel_per; /*0x4800 5040 */
1883 uint32_t cm_sleepdep_per; /*0x4800 5044 */
1884 uint32_t cm_clkstctrl_per; /*0x4800 5048 */
1885 uint32_t cm_clkstst_per; /*0x4800 504c */
1887 /*EMU_CM Register */
1888 uint32_t cm_clksel1_emu; /*0x4800 5140 */
1889 uint32_t cm_clkstctrl_emu; /*0x4800 5148 */
1890 uint32_t cm_clkstst_emu; /*0x4800 514c */
1891 uint32_t cm_clksel2_emu; /*0x4800 5150 */
1892 uint32_t cm_clksel3_emu; /*0x4800 5154 */
1894 /*Global_Reg_CM Register */
1895 uint32_t cm_polctrl; /*0x4800 529c */
1897 /*NEON_CM Register */
1898 uint32_t cm_idlest_neon; /*0x4800 5320 */
1899 uint32_t cm_clkstctrl_neon; /*0x4800 5348 */
1901 /*USBHOST_CM Register */
1902 uint32_t cm_fclken_usbhost; /*0x4800 5400 */
1903 uint32_t cm_iclken_usbhost; /*0x4800 5410 */
1904 uint32_t cm_idlest_usbhost; /*0x4800 5420 */
1905 uint32_t cm_autoidle_usbhost; /*0x4800 5430 */
1906 uint32_t cm_sleepdep_usbhost; /*0x4800 5444 */
1907 uint32_t cm_clkstctrl_usbhost; /*0x4800 5448 */
1908 uint32_t cm_clkstst_usbhost; /*0x4800 544c */
1913 static inline void omap3_cm_fclken_wkup_update(struct omap3_cm_s *s,
1918 omap_clk_onoff(omap_findclk(s->mpu,"omap3_wkup_32k_fclk"), 1);
1920 omap_clk_onoff(omap_findclk(s->mpu,"omap3_wkup_32k_fclk"), 0);
1923 omap_clk_onoff(omap_findclk(s->mpu,"omap3_gp1_fclk"), 1);
1925 omap_clk_onoff(omap_findclk(s->mpu,"omap3_gp1_fclk"), 0);
1928 static inline void omap3_cm_iclken_wkup_update(struct omap3_cm_s *s,
1933 omap_clk_onoff(omap_findclk(s->mpu,"omap3_wkup_l4_iclk"), 1);
1935 omap_clk_onoff(omap_findclk(s->mpu,"omap3_wkup_l4_iclk"), 0);
1939 static inline void omap3_cm_clksel_wkup_update(struct omap3_cm_s *s,
1942 omap_clk gp1_fclk = omap_findclk(s->mpu, "omap3_gp1_fclk");
1945 omap_clk_reparent(gp1_fclk, omap_findclk(s->mpu, "omap3_sys_clk"));
1947 omap_clk_reparent(gp1_fclk, omap_findclk(s->mpu, "omap3_32k_fclk"));
1948 /*Tell GPTIMER to generate new clk rate */
1949 omap_gp_timer_change_clk(s->mpu->gptimer[0]);
1951 TRACE("omap3_gp1_fclk %lld",
1952 omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp1_fclk")));
1954 /*TODO:CM_USIM_CLK CLKSEL_RM */
1957 static inline void omap3_cm_mpu_update(struct omap3_cm_s *s)
1959 uint32_t m, n, divide, m2, cm_clken_pll_mpu;
1960 uint32_t bypass = 1;
1962 cm_clken_pll_mpu = s->cm_clken_pll_mpu;
1963 omap_clk mpu_clk = omap_findclk(s->mpu, "omap3_mpu_clk");
1965 if ((cm_clken_pll_mpu & 0x7) == 0x5)
1969 else if ((cm_clken_pll_mpu & 0x7) == 0x7)
1971 m = (s->cm_clksel1_pll_mpu & 0x7ff00) >> 8;
1972 if ((m == 0) || (m == 1))
1980 divide = (s->cm_clksel1_pll_mpu & 0x380000) >> 19;
1981 //OMAP3_DEBUG(("divide %d\n",divide));
1982 omap_clk_reparent(mpu_clk, omap_findclk(s->mpu, "omap3_core_clk"));
1983 omap_clk_setrate(mpu_clk, divide, 1);
1988 n = (s->cm_clksel1_pll_mpu & 0x7F);
1989 m2 = (s->cm_clksel2_pll_mpu & 0x1F);
1990 //OMAP3_DEBUG(("M %d N %d M2 %d \n",m,n,m2 ));
1991 omap_clk_reparent(mpu_clk, omap_findclk(s->mpu, "omap3_sys_clk"));
1992 omap_clk_setrate(mpu_clk, (n + 1) * m2, m);
1993 //OMAP3_DEBUG(("mpu %d \n",omap_clk_getrate(mpu_clk)));
1999 static inline void omap3_cm_iva2_update(struct omap3_cm_s *s)
2001 uint32_t m, n, divide, m2, cm_clken_pll_iva2;
2002 uint32_t bypass = 1;
2004 cm_clken_pll_iva2 = s->cm_clken_pll_iva2;
2005 omap_clk iva2_clk = omap_findclk(s->mpu, "omap3_iva2_clk");
2007 if (((cm_clken_pll_iva2 & 0x7) == 0x5)
2008 || ((cm_clken_pll_iva2 & 0x7) == 0x1))
2012 else if ((cm_clken_pll_iva2 & 0x7) == 0x7)
2014 m = (s->cm_clksel1_pll_iva2 & 0x7ff00) >> 8;
2015 if ((m == 0) || (m == 1))
2023 divide = (s->cm_clksel1_pll_iva2 & 0x380000) >> 19;
2024 //OMAP3_DEBUG(("divide %d\n",divide));
2025 omap_clk_reparent(iva2_clk, omap_findclk(s->mpu, "omap3_core_clk"));
2026 omap_clk_setrate(iva2_clk, divide, 1);
2031 n = (s->cm_clksel1_pll_iva2 & 0x7F);
2032 m2 = (s->cm_clksel2_pll_iva2 & 0x1F);
2033 //OMAP3_DEBUG(("M %d N %d M2 %d \n",m,n,m2 ));
2034 omap_clk_reparent(iva2_clk, omap_findclk(s->mpu, "omap3_sys_clk"));
2035 omap_clk_setrate(iva2_clk, (n + 1) * m2, m);
2036 //OMAP3_DEBUG(("iva2_clk %d \n",omap_clk_getrate(iva2_clk)));
2042 static inline void omap3_cm_dpll3_update(struct omap3_cm_s *s)
2044 uint32_t m, n, m2, m3, cm_clken_pll;
2045 uint32_t bypass = 1;
2047 cm_clken_pll = s->cm_clken_pll;
2049 /*dpll3 bypass mode. parent clock is always omap3_sys_clk */
2050 if (((cm_clken_pll & 0x7) == 0x5) || ((cm_clken_pll & 0x7) == 0x6))
2054 else if ((cm_clken_pll & 0x7) == 0x7)
2056 m = (s->cm_clksel1_pll & 0x7ff0000) >> 16;
2057 if ((m == 0) || (m == 1))
2064 omap_clk_setrate(omap_findclk(s->mpu, "omap3_core_clk"), 1, 1);
2065 omap_clk_setrate(omap_findclk(s->mpu, "omap3_core2_clk"), 1, 1);
2066 omap_clk_setrate(omap_findclk(s->mpu, "omap3_emu_core_alwon_clk"), 1,
2071 n = (s->cm_clksel1_pll & 0x3f00) >> 8;
2072 m2 = (s->cm_clksel1_pll & 0xf8000000) >> 27;
2073 m3 = (s->cm_clksel1_emu & 0x1f0000) >> 16;
2075 if (s->cm_clksel2_emu&0x80000)
2077 /*override control of DPLL3*/
2078 m = (s->cm_clksel2_emu&0x7ff)>>8;
2079 n = s->cm_clksel2_emu&0x7f;
2080 TRACE("DPLL3 override, m 0x%x n 0x%x",m,n);
2083 //OMAP3_DEBUG(("dpll3 cm_clksel1_pll %x m %d n %d m2 %d m3 %d\n",s->cm_clksel1_pll,m,n,m2,m3 ));
2084 omap_clk_setrate(omap_findclk(s->mpu, "omap3_core_clk"), (n + 1) * m2,
2086 omap_clk_setrate(omap_findclk(s->mpu, "omap3_core2_clk"), (n + 1) * m2,
2088 omap_clk_setrate(omap_findclk(s->mpu, "omap3_emu_core_alwon_clk"),
2089 (n + 1) * m3, m * 2);
2090 TRACE("coreclk %lld",
2091 omap_clk_getrate(omap_findclk(s->mpu, "omap3_core_clk")));
2097 static inline void omap3_cm_dpll4_update(struct omap3_cm_s *s)
2099 uint32_t m, n, m2, m3, m4, m5, m6, cm_clken_pll;
2100 cm_clken_pll = s->cm_clken_pll;
2101 uint32_t bypass = 1;
2103 /*dpll3 bypass mode. parent clock is always omap3_sys_clk */
2105 if ((cm_clken_pll & 0x70000) == 0x10000)
2109 else if ((cm_clken_pll & 0x70000) == 0x70000)
2111 m = (s->cm_clksel2_pll & 0x7ff00) >> 8;
2112 if ((m == 0) || (m == 1))
2119 omap_clk_setrate(omap_findclk(s->mpu, "omap3_96m_fclk"), 1, 1);
2120 omap_clk_setrate(omap_findclk(s->mpu, "omap3_54m_fclk"), 1, 1);
2121 omap_clk_setrate(omap_findclk(s->mpu, "omap3_dss1_alwon_fclk"), 1, 1);
2122 omap_clk_setrate(omap_findclk(s->mpu, "omap3_cam_mclk"), 1, 1);
2123 omap_clk_setrate(omap_findclk(s->mpu, "omap3_per_alwon_clk"), 1, 1);
2127 n = (s->cm_clksel2_pll & 0x7f);
2128 m2 = s->cm_clksel3_pll & 0x1f;
2129 m3 = (s->cm_clksel_dss & 0x1f00) >> 8;
2130 m4 = s->cm_clksel_dss & 0x1f;
2131 m5 = s->cm_clksel_cam & 0x1f;
2132 m6 = (s->cm_clksel1_emu & 0x1f000000) >> 24;
2134 if (s->cm_clksel3_emu&0x80000)
2136 /*override control of DPLL4*/
2137 m = (s->cm_clksel3_emu&0x7ff)>>8;
2138 n = s->cm_clksel3_emu&0x7f;
2139 TRACE("DPLL4 override, m 0x%x n 0x%x",m,n);
2143 //OMAP3_DEBUG(("dpll4 m %d n %d m2 %d m3 %d m4 %d m5 %d m6 %d \n",m,n,m2,m3,m4,m5,m6 ));
2144 omap_clk_setrate(omap_findclk(s->mpu, "omap3_96m_fclk"), (n + 1) * m2,
2146 omap_clk_setrate(omap_findclk(s->mpu, "omap3_54m_fclk"), (n + 1) * m3,
2148 omap_clk_setrate(omap_findclk(s->mpu, "omap3_dss1_alwon_fclk"),
2149 (n + 1) * m4, m * 2);
2150 omap_clk_setrate(omap_findclk(s->mpu, "omap3_cam_mclk"), (n + 1) * m5,
2152 omap_clk_setrate(omap_findclk(s->mpu, "omap3_per_alwon_clk"),
2153 (n + 1) * m6, m * 2);
2155 TRACE("omap3_96m_fclk %lld",
2156 omap_clk_getrate(omap_findclk(s->mpu, "omap3_96m_fclk")));
2157 TRACE("omap3_54m_fclk %lld",
2158 omap_clk_getrate(omap_findclk(s->mpu, "omap3_54m_fclk")));
2159 TRACE("omap3_dss1_alwon_fclk %lld",
2160 omap_clk_getrate(omap_findclk(s->mpu, "omap3_dss1_alwon_fclk")));
2161 TRACE("omap3_cam_mclk %lld",
2162 omap_clk_getrate(omap_findclk(s->mpu, "omap3_cam_mclk")));
2163 TRACE("omap3_per_alwon_clk %lld",
2164 omap_clk_getrate(omap_findclk(s->mpu, "omap3_per_alwon_clk")));
2165 TRACE("omap3_48m_fclk %lld",
2166 omap_clk_getrate(omap_findclk(s->mpu, "omap3_48m_fclk")));
2167 TRACE("omap3_12m_fclk %lld",
2168 omap_clk_getrate(omap_findclk(s->mpu, "omap3_12m_fclk")));
2172 static inline void omap3_cm_dpll5_update(struct omap3_cm_s *s)
2174 uint32_t m, n, m2, cm_idlest2_ckgen;
2175 uint32_t bypass = 1;
2177 cm_idlest2_ckgen = s->cm_idlest2_ckgen;;
2179 /*dpll5 bypass mode */
2180 if ((cm_idlest2_ckgen & 0x1) == 0x0)
2187 omap_clk_setrate(omap_findclk(s->mpu, "omap3_120m_fclk"), 1, 1);
2191 m = (s->cm_clksel4_pll & 0x7ff00)>>8;
2192 n = s->cm_clksel4_pll & 0x3f00;
2193 m2 = s->cm_clksel5_pll & 0x1f;
2195 TRACE("dpll5 m %d n %d m2 %d",m,n,m2);
2196 omap_clk_setrate(omap_findclk(s->mpu, "omap3_120m_fclk"), (n + 1) * m2,
2198 TRACE("omap3_120m_fclk %lld",
2199 omap_clk_getrate(omap_findclk(s->mpu, "omap3_120m_fclk")));
2203 static inline void omap3_cm_48m_update(struct omap3_cm_s *s)
2205 if (s->cm_clksel1_pll & 0x8)
2207 /*parent is sysaltclk */
2208 omap_clk_reparent(omap_findclk(s->mpu, "omap3_48m_fclk"),
2209 omap_findclk(s->mpu, "omap3_sys_altclk"));
2210 omap_clk_reparent(omap_findclk(s->mpu, "omap3_12m_fclk"),
2211 omap_findclk(s->mpu, "omap3_sys_altclk"));
2212 /*TODO:need to set rate ? */
2217 omap_clk_reparent(omap_findclk(s->mpu, "omap3_12m_fclk"),
2218 omap_findclk(s->mpu, "omap3_96m_fclk"));
2219 omap_clk_reparent(omap_findclk(s->mpu, "omap3_48m_fclk"),
2220 omap_findclk(s->mpu, "omap3_96m_fclk"));
2221 omap_clk_setrate(omap_findclk(s->mpu, "omap3_48m_fclk"), 2, 1);
2222 omap_clk_setrate(omap_findclk(s->mpu, "omap3_12m_fclk"), 8, 1);
2228 static inline void omap3_cm_gp10_update(struct omap3_cm_s *s)
2230 omap_clk gp10_fclk = omap_findclk(s->mpu, "omap3_gp10_fclk");
2232 if (s->cm_clksel_core & 0x40)
2233 omap_clk_reparent(gp10_fclk, omap_findclk(s->mpu, "omap3_sys_clk"));
2235 omap_clk_reparent(gp10_fclk, omap_findclk(s->mpu, "omap3_32k_fclk"));
2237 /*Tell GPTIMER10 to generate new clk rate */
2238 omap_gp_timer_change_clk(s->mpu->gptimer[9]);
2239 TRACE("omap3_gp10_fclk %lld",
2240 omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp10_fclk")));
2243 static inline void omap3_cm_gp11_update(struct omap3_cm_s *s)
2245 omap_clk gp11_fclk = omap_findclk(s->mpu, "omap3_gp11_fclk");
2247 if (s->cm_clksel_core & 0x80)
2248 omap_clk_reparent(gp11_fclk, omap_findclk(s->mpu, "omap3_sys_clk"));
2250 omap_clk_reparent(gp11_fclk, omap_findclk(s->mpu, "omap3_32k_fclk"));
2251 /*Tell GPTIMER11 to generate new clk rate */
2252 omap_gp_timer_change_clk(s->mpu->gptimer[10]);
2253 TRACE("omap3_gp11_fclk %lld",
2254 omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp11_fclk")));
2257 static inline void omap3_cm_l3clk_update(struct omap3_cm_s *s)
2259 omap_clk l3_iclk = omap_findclk(s->mpu, "omap3_l3_iclk");
2260 if ((s->cm_clksel_core & 0x3) == 0x1)
2261 omap_clk_setrate(l3_iclk, 1, 1);
2262 else if ((s->cm_clksel_core & 0x3) == 0x2)
2263 omap_clk_setrate(l3_iclk, 2, 1);
2266 static inline void omap3_cm_l4clk_update(struct omap3_cm_s *s)
2268 omap_clk l4_iclk = omap_findclk(s->mpu, "omap3_l4_iclk");
2269 if ((s->cm_clksel_core & 0xc) == 0x4)
2270 omap_clk_setrate(l4_iclk, 1, 1);
2271 else if ((s->cm_clksel_core & 0xc) == 0x8)
2272 omap_clk_setrate(l4_iclk, 2, 1);
2275 static inline void omap3_cm_per_gptimer_update(struct omap3_cm_s *s)
2277 uint32_t cm_clksel_per = s->cm_clksel_per;
2279 if (cm_clksel_per & 0x1)
2280 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp2_fclk"),
2281 omap_findclk(s->mpu, "omap3_sys_clk"));
2283 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp2_fclk"),
2284 omap_findclk(s->mpu, "omap3_32k_fclk"));
2285 omap_gp_timer_change_clk(s->mpu->gptimer[1]);
2287 if (cm_clksel_per & 0x2)
2288 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp3_fclk"),
2289 omap_findclk(s->mpu, "omap3_sys_clk"));
2291 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp3_fclk"),
2292 omap_findclk(s->mpu, "omap3_32k_fclk"));
2293 omap_gp_timer_change_clk(s->mpu->gptimer[2]);
2295 if (cm_clksel_per & 0x4)
2296 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp4_fclk"),
2297 omap_findclk(s->mpu, "omap3_sys_clk"));
2299 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp4_fclk"),
2300 omap_findclk(s->mpu, "omap3_32k_fclk"));
2301 omap_gp_timer_change_clk(s->mpu->gptimer[3]);
2303 if (cm_clksel_per & 0x8)
2304 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp5_fclk"),
2305 omap_findclk(s->mpu, "omap3_sys_clk"));
2307 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp5_fclk"),
2308 omap_findclk(s->mpu, "omap3_32k_fclk"));
2309 omap_gp_timer_change_clk(s->mpu->gptimer[4]);
2311 if (cm_clksel_per & 0x10)
2312 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp6_fclk"),
2313 omap_findclk(s->mpu, "omap3_sys_clk"));
2315 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp6_fclk"),
2316 omap_findclk(s->mpu, "omap3_32k_fclk"));
2317 omap_gp_timer_change_clk(s->mpu->gptimer[5]);
2319 if (cm_clksel_per & 0x20)
2320 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp7_fclk"),
2321 omap_findclk(s->mpu, "omap3_sys_clk"));
2323 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp7_fclk"),
2324 omap_findclk(s->mpu, "omap3_32k_fclk"));
2325 omap_gp_timer_change_clk(s->mpu->gptimer[6]);
2328 if (cm_clksel_per & 0x40)
2329 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp8_fclk"),
2330 omap_findclk(s->mpu, "omap3_sys_clk"));
2332 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp8_fclk"),
2333 omap_findclk(s->mpu, "omap3_32k_fclk"));
2334 omap_gp_timer_change_clk(s->mpu->gptimer[7]);
2336 if (cm_clksel_per & 0x80)
2337 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp9_fclk"),
2338 omap_findclk(s->mpu, "omap3_sys_clk"));
2340 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp9_fclk"),
2341 omap_findclk(s->mpu, "omap3_32k_fclk"));
2342 omap_gp_timer_change_clk(s->mpu->gptimer[8]);
2344 /*TODO:Tell GPTIMER to generate new clk rate */
2345 TRACE("omap3_gp2_fclk %lld",
2346 omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp2_fclk")));
2347 TRACE("omap3_gp3_fclk %lld",
2348 omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp3_fclk")));
2349 TRACE("omap3_gp4_fclk %lld",
2350 omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp4_fclk")));
2351 TRACE("omap3_gp5_fclk %lld",
2352 omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp5_fclk")));
2353 TRACE("omap3_gp6_fclk %lld",
2354 omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp6_fclk")));
2355 TRACE("omap3_gp7_fclk %lld",
2356 omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp7_fclk")));
2357 TRACE("omap3_gp8_fclk %lld",
2358 omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp8_fclk")));
2359 TRACE("omap3_gp9_fclk %lld",
2360 omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp9_fclk")));
2363 static inline void omap3_cm_clkout2_update(struct omap3_cm_s *s)
2367 if (!s->cm_clkout_ctrl&0x80)
2370 switch (s->cm_clkout_ctrl&0x3)
2373 omap_clk_reparent(omap_findclk(s->mpu, "omap3_sys_clkout2"),
2374 omap_findclk(s->mpu, "omap3_core_clk"));
2377 omap_clk_reparent(omap_findclk(s->mpu, "omap3_sys_clkout2"),
2378 omap_findclk(s->mpu, "omap3_sys_clk"));
2381 omap_clk_reparent(omap_findclk(s->mpu, "omap3_sys_clkout2"),
2382 omap_findclk(s->mpu, "omap3_96m_fclk"));
2385 omap_clk_reparent(omap_findclk(s->mpu, "omap3_sys_clkout2"),
2386 omap_findclk(s->mpu, "omap3_54m_fclk"));
2390 divor = (s->cm_clkout_ctrl&0x31)>>3;
2392 omap_clk_setrate(omap_findclk(s->mpu, "omap3_sys_clkout2"), divor, 1);
2396 static void omap3_cm_reset(struct omap3_cm_s *s)
2398 s->cm_fclken_iva2 = 0x0;
2399 s->cm_clken_pll_iva2 = 0x11;
2400 s->cm_idlest_iva2 = 0x1;
2401 s->cm_idlest_pll_iva2 = 0x0;
2402 s->cm_autoidle_pll_iva2 = 0x0;
2403 s->cm_clksel1_pll_iva2 = 0x80000;
2404 s->cm_clksel2_pll_iva2 = 0x1;
2405 s->cm_clkstctrl_iva2 = 0x0;
2406 s->cm_clkstst_iva2 = 0x0;
2408 s->cm_revision = 0x10;
2409 s->cm_sysconfig = 0x1;
2411 s->cm_clken_pll_mpu = 0x15;
2412 s->cm_idlest_mpu = 0x1;
2413 s->cm_idlest_pll_mpu = 0x0;
2414 s->cm_autoidle_pll_mpu = 0x0;
2415 s->cm_clksel1_pll_mpu = 0x80000;
2416 s->cm_clksel2_pll_mpu = 0x1;
2417 s->cm_clkstctrl_mpu = 0x0;
2418 s->cm_clkstst_mpu = 0x0;
2420 s->cm_fclken1_core = 0x0;
2421 s->cm_fclken3_core = 0x0;
2422 s->cm_iclken1_core = 0x42;
2423 s->cm_iclken2_core = 0x0;
2424 s->cm_iclken3_core = 0x0;
2425 /*allow access to devices*/
2426 s->cm_idlest1_core = 0x0;
2427 s->cm_idlest2_core = 0x0;
2429 s->cm_idlest3_core = 0xa;
2430 s->cm_autoidle1_core = 0x0;
2431 s->cm_autoidle2_core = 0x0;
2432 s->cm_autoidle3_core = 0x0;
2433 s->cm_clksel_core = 0x105;
2434 s->cm_clkstctrl_core = 0x0;
2435 s->cm_clkstst_core = 0x0;
2437 s->cm_fclken_sgx = 0x0;
2438 s->cm_iclken_sgx = 0x0;
2439 s->cm_idlest_sgx = 0x1;
2440 s->cm_clksel_sgx = 0x0;
2441 s->cm_sleepdep_sgx = 0x0;
2442 s->cm_clkstctrl_sgx = 0x0;
2443 s->cm_clkstst_sgx = 0x0;
2445 s->cm_fclken_wkup = 0x0;
2446 s->cm_iclken_wkup = 0x0;
2447 /*assume all clock can be accessed*/
2448 s->cm_idlest_wkup = 0x0;
2449 s->cm_autoidle_wkup = 0x0;
2450 s->cm_clksel_wkup = 0x12;
2452 s->cm_clken_pll = 0x110015;
2453 s->cm_clken2_pll = 0x11;
2454 s->cm_idlest_ckgen = 0x0;
2455 s->cm_idlest2_ckgen = 0x0;
2456 s->cm_autoidle_pll = 0x0;
2457 s->cm_autoidle2_pll = 0x0;
2458 s->cm_clksel1_pll = 0x8000040;
2459 s->cm_clksel2_pll = 0x0;
2460 s->cm_clksel3_pll = 0x1;
2461 s->cm_clksel4_pll = 0x0;
2462 s->cm_clksel5_pll = 0x1;
2463 s->cm_clkout_ctrl = 0x3;
2466 s->cm_fclken_dss = 0x0;
2467 s->cm_iclken_dss = 0x0;
2468 /*dss can be accessed*/
2469 s->cm_idlest_dss = 0x0;
2470 s->cm_autoidle_dss = 0x0;
2471 s->cm_clksel_dss = 0x1010;
2472 s->cm_sleepdep_dss = 0x0;
2473 s->cm_clkstctrl_dss = 0x0;
2474 s->cm_clkstst_dss = 0x0;
2476 s->cm_fclken_cam = 0x0;
2477 s->cm_iclken_cam = 0x0;
2478 s->cm_idlest_cam = 0x1;
2479 s->cm_autoidle_cam = 0x0;
2480 s->cm_clksel_cam = 0x10;
2481 s->cm_sleepdep_cam = 0x0;
2482 s->cm_clkstctrl_cam = 0x0;
2483 s->cm_clkstst_cam = 0x0;
2485 s->cm_fclken_per = 0x0;
2486 s->cm_iclken_per = 0x0;
2487 //s->cm_idlest_per = 0x3ffff;
2488 s->cm_idlest_per = 0x0; //enable GPIO access
2489 s->cm_autoidle_per = 0x0;
2490 s->cm_clksel_per = 0x0;
2491 s->cm_sleepdep_per = 0x0;
2492 s->cm_clkstctrl_per = 0x0;
2493 s->cm_clkstst_per = 0x0;
2495 s->cm_clksel1_emu = 0x10100a50;
2496 s->cm_clkstctrl_emu = 0x2;
2497 s->cm_clkstst_emu = 0x0;
2498 s->cm_clksel2_emu = 0x0;
2499 s->cm_clksel3_emu = 0x0;
2501 s->cm_polctrl = 0x0;
2503 s->cm_idlest_neon = 0x1;
2504 s->cm_clkstctrl_neon = 0x0;
2506 s->cm_fclken_usbhost = 0x0;
2507 s->cm_iclken_usbhost = 0x0;
2508 s->cm_idlest_usbhost = 0x3;
2509 s->cm_autoidle_usbhost = 0x0;
2510 s->cm_sleepdep_usbhost = 0x0;
2511 s->cm_clkstctrl_usbhost = 0x0;
2512 s->cm_clkstst_usbhost = 0x0;
2515 static uint32_t omap3_cm_read(void *opaque, target_phys_addr_t addr)
2517 struct omap3_cm_s *s = (struct omap3_cm_s *) opaque;
2519 uint32_t bypass = 0, m;
2521 TRACE("%04x", addr);
2525 return s->cm_fclken_iva2;
2527 return s->cm_clken_pll_iva2;
2529 return s->cm_idlest_iva2;
2531 if (((s->cm_clken_pll_iva2 & 0x7) == 0x5)
2532 || ((s->cm_clken_pll_iva2 & 0x7) == 0x1))
2536 else if ((s->cm_clken_pll_iva2 & 0x7) == 0x7)
2538 m = (s->cm_clksel1_pll_iva2 & 0x7ff00) >> 8;
2539 if ((m == 0) || (m == 1))
2549 return s->cm_autoidle_pll_iva2;
2551 return s->cm_clksel1_pll_iva2;
2553 return s->cm_clksel2_pll_iva2;
2555 return s->cm_clkstctrl_iva2;
2557 return s->cm_clkstst_iva2;
2560 return s->cm_revision;
2562 return s->cm_sysconfig;
2565 case 0x904: /*CM_CLKEN_PLL_MPU */
2566 return s->cm_clken_pll_mpu;
2568 return s->cm_idlest_mpu & 0x0; /*MPU is active*/
2570 if ((s->cm_clken_pll_mpu & 0x7) == 0x5)
2574 else if ((s->cm_clken_pll_mpu & 0x7) == 0x7)
2576 m = (s->cm_clksel1_pll_mpu & 0x7ff00) >> 8;
2577 if ((m == 0) || (m == 1))
2587 return s->cm_autoidle_pll_mpu;
2589 return s->cm_clksel1_pll_mpu;
2591 return s->cm_clksel2_pll_mpu;
2593 return s->cm_clkstctrl_mpu;
2595 return s->cm_clkstst_mpu;
2600 return s->cm_fclken1_core;
2602 return s->cm_fclken3_core;
2604 return s->cm_iclken1_core;
2606 return s->cm_iclken2_core;
2608 return s->cm_idlest1_core;
2610 return s->cm_idlest2_core;
2612 return s->cm_idlest3_core;
2614 return s->cm_autoidle1_core;
2616 return s->cm_autoidle2_core;
2618 return s->cm_autoidle3_core;
2619 case 0xa40: /*CM_CLKSEL_CORE */
2620 return s->cm_clksel_core;
2622 return s->cm_clkstctrl_core;
2624 return s->cm_clkstst_core;
2627 return s->cm_fclken_sgx;
2629 return s->cm_iclken_sgx;
2631 return s->cm_idlest_sgx&0x0;
2632 case 0xb40: /*CM_CLKSEL_SGX */
2633 return s->cm_clksel_sgx;
2635 return s->cm_clkstctrl_sgx;
2637 return s->cm_clkstst_sgx;
2640 case 0xc00: /*CM_FCLKEN_WKUP */
2641 return s->cm_fclken_wkup;
2642 case 0xc10: /*CM_ICLKEN_WKUP */
2643 return s->cm_iclken_wkup;
2644 case 0xc20: /*CM_IDLEST_WKUP */
2645 /*TODO: Check whether the timer can be accessed. */
2648 return s->cm_idlest_wkup;
2650 return s->cm_clksel_wkup;
2655 case 0xd00: /*CM_CLKEN_PLL */
2656 return s->cm_clken_pll;
2658 return s->cm_clken2_pll;
2660 /*FIXME: all clock is active. we do not care it. */
2665 if (((s->cm_clken_pll & 0x7) == 0x5) || ((s->cm_clken_pll & 0x7) == 0x6))
2667 else if ((s->cm_clken_pll & 0x7) == 0x7) {
2668 m = (s->cm_clksel1_pll & 0x7ff0000) >> 16;
2669 if ((m == 0) || (m == 1))
2679 if ((s->cm_clken_pll & 0x70000) == 0x10000)
2681 else if ((s->cm_clken_pll & 0x70000) == 0x70000) {
2682 m = (s->cm_clksel2_pll & 0x7ff00) >> 8;
2683 if ((m == 0) || (m == 1))
2693 return s->cm_idlest2_ckgen;
2695 return s->cm_autoidle_pll;
2697 return s->cm_autoidle2_pll;
2698 case 0xd40: /*CM_CLKSEL1_PLL */
2699 return s->cm_clksel1_pll;
2701 return s->cm_clksel2_pll;
2702 case 0xd48: /*CM_CLKSEL3_PLL */
2703 return s->cm_clksel3_pll;
2705 return s->cm_clksel4_pll;
2706 case 0xd50: /*CM_CLKSEL5_PLL */
2707 return s->cm_clksel5_pll;
2709 return s->cm_clkout_ctrl;
2713 return s->cm_fclken_dss;
2715 return s->cm_iclken_dss;
2717 return s->cm_idlest_dss;
2719 return s->cm_autoidle_dss;
2721 return s->cm_clksel_dss;
2723 return s->cm_sleepdep_dss;
2725 return s->cm_clkstctrl_dss;
2727 return s->cm_clkstst_dss;
2731 return s->cm_fclken_cam;
2733 return s->cm_iclken_cam;
2735 return s->cm_idlest_cam&0x0;
2737 return s->cm_autoidle_cam;
2739 return s->cm_clksel_cam;
2741 return s->cm_sleepdep_cam;
2743 return s->cm_clkstctrl_cam;
2745 return s->cm_clkstst_cam;
2749 return s->cm_fclken_per;
2751 return s->cm_iclken_per;
2753 return s->cm_idlest_per ;
2755 return s->cm_autoidle_per;
2757 return s->cm_clksel_per;
2759 return s->cm_sleepdep_per;
2761 return s->cm_clkstctrl_per;
2763 return s->cm_clkstst_per;
2766 case 0x1140: /*CM_CLKSEL1_EMU */
2767 return s->cm_clksel1_emu;
2769 return s->cm_clkstctrl_emu;
2771 return s->cm_clkstst_emu&0x0;
2773 return s->cm_clksel2_emu;
2775 return s->cm_clksel3_emu;
2778 return s->cm_polctrl;
2781 return s->cm_idlest_neon&0x0;
2783 return s->cm_clkstctrl_neon;
2786 return s->cm_fclken_usbhost;
2788 return s->cm_iclken_usbhost;
2790 return s->cm_idlest_usbhost&0x0;
2792 return s->cm_autoidle_usbhost;
2794 return s->cm_sleepdep_usbhost;
2796 return s->cm_clkstctrl_usbhost;
2798 return s->cm_clkstst_usbhost;
2801 printf("omap3_cm_read addr %x pc %x \n", addr, cpu_single_env->regs[15] );
2807 static void omap3_cm_write(void *opaque, target_phys_addr_t addr,
2810 struct omap3_cm_s *s = (struct omap3_cm_s *) opaque;
2812 TRACE("%04x = %08x", addr, value);
2828 case 0xc20: /*CM_IDLEST_WKUP */
2846 s->cm_fclken_iva2 = value & 0x1;
2848 case 0x4: /*CM_CLKEN_PLL_IVA2 */
2849 s->cm_clken_pll_iva2 = value & 0x7ff;
2850 omap3_cm_iva2_update(s);
2853 s->cm_autoidle_pll_iva2 = value & 0x7;
2856 s->cm_clksel1_pll_iva2 = value & 0x3fff7f;
2857 //printf("value %x s->cm_clksel1_pll_iva2 %x \n",value,s->cm_clksel1_pll_iva2);
2858 omap3_cm_iva2_update(s);
2861 s->cm_clksel2_pll_iva2 = value & 0x1f;
2862 omap3_cm_iva2_update(s);
2865 s->cm_clkstctrl_iva2 = value& 0x3;
2869 s->cm_sysconfig = value & 0x1;
2873 case 0x904: /*CM_CLKEN_PLL_MPU */
2874 s->cm_clken_pll_mpu = value & 0x7ff;
2875 omap3_cm_mpu_update(s);
2878 s->cm_autoidle_pll_mpu = value & 0x7;
2881 //printf("s->cm_clksel1_pll_mpu %x\n",s->cm_clksel1_pll_mpu );
2882 s->cm_clksel1_pll_mpu = value & 0x3fff7f;
2883 omap3_cm_mpu_update(s);
2886 s->cm_clksel2_pll_mpu = value & 0x1f;
2887 omap3_cm_mpu_update(s);
2890 s->cm_clkstctrl_mpu = value & 0x3;
2895 s->cm_fclken1_core = value & 0x43fffe00;
2898 s->cm_fclken3_core = value & 0x7;
2901 s->cm_iclken1_core = value & 0x637ffed2;
2902 s->cm_idlest1_core = ~s->cm_iclken1_core;
2903 /* TODO: replace code below with real implementation */
2904 s->cm_idlest1_core &= ~0x20; /* HS OTG USB idle */
2905 s->cm_idlest1_core |= 4; /* SDMA in standby */
2908 s->cm_iclken2_core = value & 0x1f;
2911 s->cm_iclken3_core = value & 0x4;
2912 s->cm_idlest3_core = 0xd & ~(s->cm_iclken3_core & 4);
2915 s->cm_autoidle1_core = value & 0x7ffffed0;
2918 s->cm_autoidle2_core = value & 0x1f;
2921 s->cm_autoidle3_core = value & 0x2;
2923 case 0xa40: /*CM_CLKSEL_CORE */
2924 s->cm_clksel_core = (value & 0xff);
2925 s->cm_clksel_core |= 0x100;
2926 omap3_cm_gp10_update(s);
2927 omap3_cm_gp11_update(s);
2928 omap3_cm_l3clk_update(s);
2929 omap3_cm_l4clk_update(s);
2932 s->cm_clkstctrl_core = value & 0xf;
2936 s->cm_fclken_sgx = value &0x2;
2939 s->cm_iclken_sgx = value & 0x1;
2941 case 0xb40: /*CM_CLKSEL_SGX */
2942 /*TODO: SGX Clock!! */
2943 s->cm_clksel_sgx = value;
2946 s->cm_sleepdep_sgx = value &0x2;
2949 s->cm_clkstctrl_sgx = value & 0x3;
2953 case 0xc00: /*CM_FCLKEN_WKUP */
2954 s->cm_fclken_wkup = value & 0x2e9;
2956 case 0xc10: /*CM_ICLKEN_WKUP */
2957 s->cm_iclken_wkup = value & 0x2ff;
2960 s->cm_autoidle_wkup = value & 0x23f;
2962 case 0xc40: /*CM_CLKSEL_WKUP */
2963 s->cm_clksel_wkup = value & 0x7f;
2964 omap3_cm_clksel_wkup_update(s, s->cm_clksel_wkup);
2968 case 0xd00: /*CM_CLKEN_PLL */
2969 s->cm_clken_pll = value & 0xffff17ff;
2970 omap3_cm_dpll3_update(s);
2971 omap3_cm_dpll4_update(s);
2974 s->cm_clken2_pll = value & 0x7ff;
2977 s->cm_autoidle_pll = value & 0x3f;
2980 s->cm_autoidle2_pll = value & 0x7;
2982 case 0xd40: /*CM_CLKSEL1_PLL */
2983 //OMAP3_DEBUG(("WD40 value %x \n",value));
2984 s->cm_clksel1_pll = value & 0xffffbffc;
2985 //OMAP3_DEBUG(("WD40 value %x \n",value));
2986 omap3_cm_dpll3_update(s);
2987 omap3_cm_48m_update(s);
2990 s->cm_clksel2_pll = value & 0x7ff7f;
2991 omap3_cm_dpll4_update(s);
2993 case 0xd48: /*CM_CLKSEL3_PLL */
2994 s->cm_clksel3_pll = value & 0x1f;
2995 omap3_cm_dpll4_update(s);
2997 case 0xd4c: /*CM_CLKSEL4_PLL */
2998 s->cm_clksel4_pll = value & 0x7ff7f;
2999 omap3_cm_dpll5_update(s);
3001 case 0xd50: /*CM_CLKSEL5_PLL */
3002 s->cm_clksel5_pll = value & 0x1f;
3003 omap3_cm_dpll5_update(s);
3006 s->cm_clkout_ctrl = value & 0xbb;
3007 omap3_cm_clkout2_update(s);
3011 s->cm_fclken_dss = value & 0x7;
3014 s->cm_iclken_dss = value & 0x1;
3017 s->cm_autoidle_dss = value & 0x1;
3020 s->cm_clksel_dss = value & 0x1f1f;
3021 omap3_cm_dpll4_update(s);
3024 s->cm_sleepdep_dss = value & 0x7;
3027 s->cm_clkstctrl_dss = value & 0x3;
3031 s->cm_fclken_cam = value & 0x3;
3034 s->cm_iclken_cam = value & 0x1;
3037 s->cm_autoidle_cam = value & 0x1;
3040 s->cm_clksel_cam = value & 0x1f;
3041 omap3_cm_dpll4_update(s);
3044 s->cm_sleepdep_cam = value & 0x2;
3047 s->cm_clkstctrl_cam = value & 0x3;
3051 s->cm_fclken_per = value & 0x3ffff;
3054 s->cm_iclken_per = value & 0x3ffff;
3058 s->cm_autoidle_per = value &0x3ffff;
3061 s->cm_clksel_per = value & 0xff;
3062 omap3_cm_per_gptimer_update(s);
3065 s->cm_sleepdep_per = value & 0x6;
3068 s->cm_clkstctrl_per = value &0x7;
3071 case 0x1140: /*CM_CLKSEL1_EMU */
3072 s->cm_clksel1_emu = value & 0x1f1f3fff;
3073 //printf("cm_clksel1_emu %x\n",s->cm_clksel1_emu);
3074 omap3_cm_dpll3_update(s);
3075 omap3_cm_dpll4_update(s);
3078 s->cm_clkstctrl_emu = value & 0x3;
3081 s->cm_clksel2_emu = value & 0xfff7f;
3082 omap3_cm_dpll3_update(s);
3085 s->cm_clksel3_emu = value & 0xfff7f;
3086 omap3_cm_dpll4_update(s);
3090 s->cm_polctrl = value & 0x1;
3094 s->cm_clkstctrl_neon = value & 0x3;
3098 s->cm_fclken_usbhost = value & 0x3;
3101 s->cm_iclken_usbhost = value & 0x1;
3104 s->cm_autoidle_usbhost = value & 0x1;
3107 s->cm_sleepdep_usbhost = value & 0x6;
3110 s->cm_clkstctrl_usbhost = value & 0x3;
3114 printf("omap3_cm_write addr %x value %x pc %x\n", addr, value,cpu_single_env->regs[15] );
3121 static CPUReadMemoryFunc *omap3_cm_readfn[] = {
3122 omap_badwidth_read32,
3123 omap_badwidth_read32,
3127 static CPUWriteMemoryFunc *omap3_cm_writefn[] = {
3128 omap_badwidth_write32,
3129 omap_badwidth_write32,
3133 struct omap3_cm_s *omap3_cm_init(struct omap_target_agent_s *ta,
3134 qemu_irq mpu_int, qemu_irq dsp_int,
3135 qemu_irq iva_int, struct omap_mpu_state_s *mpu)
3138 struct omap3_cm_s *s = (struct omap3_cm_s *) qemu_mallocz(sizeof(*s));
3140 s->irq[0] = mpu_int;
3141 s->irq[1] = dsp_int;
3142 s->irq[2] = iva_int;
3146 iomemtype = l4_register_io_memory(0, omap3_cm_readfn, omap3_cm_writefn, s);
3147 omap_l4_attach(ta, 0, iomemtype);
3148 omap_l4_attach(ta, 1, iomemtype);
3153 #define OMAP3_SEC_WDT 1
3154 #define OMAP3_MPU_WDT 2
3155 #define OMAP3_IVA2_WDT 3
3156 /*omap3 watchdog timer*/
3159 qemu_irq irq; /*IVA2 IRQ */
3160 struct omap_mpu_state_s *mpu;
3167 //int64_t ticks_per_sec;
3169 uint32_t wd_sysconfig;
3170 uint32_t wd_sysstatus;
3180 /*pre and ptv in wclr */
3185 uint16_t writeh; /* LSB */
3186 uint16_t readh; /* MSB */
3189 static inline void omap3_wdt_timer_update(struct omap3_wdt_s *wdt_timer)
3192 if (wdt_timer->active)
3194 expires = muldiv64(0xffffffffll - wdt_timer->wcrr,
3195 ticks_per_sec, wdt_timer->rate);
3196 qemu_mod_timer(wdt_timer->timer, wdt_timer->time + expires);
3199 qemu_del_timer(wdt_timer->timer);
3202 static void omap3_wdt_clk_setup(struct omap3_wdt_s *timer)
3204 /*TODO: Add irq as user to clk */
3207 static inline uint32_t omap3_wdt_timer_read(struct omap3_wdt_s *timer)
3213 distance = qemu_get_clock(vm_clock) - timer->time;
3214 distance = muldiv64(distance, timer->rate, ticks_per_sec);
3216 if (distance >= 0xffffffff - timer->wcrr)
3219 return timer->wcrr + distance;
3226 static inline void omap3_wdt_timer_sync(struct omap3_wdt_s *timer)
3228 if (timer->active) {
3229 timer->val = omap3_wdt_timer_read(timer);
3230 timer->time = qemu_get_clock(vm_clock);
3234 static void omap3_wdt_reset(struct omap3_wdt_s *s, int wdt_index)
3236 s->wd_sysconfig = 0x0;
3237 s->wd_sysstatus = 0x0;
3245 case OMAP3_IVA2_WDT:
3246 s->wldr = 0xfffb0000;
3249 s->wldr = 0xffa60000;
3262 case OMAP3_IVA2_WDT:
3266 s->pre = s->wclr & (1 << 5);
3267 s->ptv = (s->wclr & 0x1c) >> 2;
3268 s->rate = omap_clk_getrate(s->clk) >> (s->pre ? s->ptv : 0);
3271 s->time = qemu_get_clock(vm_clock);
3272 omap3_wdt_timer_update(s);
3275 static uint32_t omap3_wdt_read32(void *opaque, target_phys_addr_t addr,
3278 struct omap3_wdt_s *s = (struct omap3_wdt_s *) opaque;
3281 //printf("omap3_wdt_read32 addr %x \n",addr);
3284 case 0x10: /*WD_SYSCONFIG */
3285 return s->wd_sysconfig;
3286 case 0x14: /*WD_SYSSTATUS */
3287 return s->wd_sysstatus;
3289 /*WISR*/ return s->wisr & 0x1;
3291 /*WIER*/ return s->wier & 0x1;
3293 /*WCLR*/ return s->wclr & 0x3c;
3295 /*WCRR*/ s->wcrr = omap3_wdt_timer_read(s);
3296 s->time = qemu_get_clock(vm_clock);
3299 /*WLDR*/ return s->wldr;
3301 /*WTGR*/ return s->wtgr;
3303 /*WWPS*/ return s->wwps;
3305 /*WSPR*/ return s->wspr;
3307 printf("omap3_wdt_read32 addr %x \n", addr);
3312 static uint32_t omap3_mpu_wdt_read16(void *opaque, target_phys_addr_t addr)
3314 struct omap3_wdt_s *s = (struct omap3_wdt_s *) opaque;
3321 ret = omap3_wdt_read32(opaque, addr, OMAP3_MPU_WDT);
3322 s->readh = ret >> 16;
3323 return ret & 0xffff;
3327 static uint32_t omap3_mpu_wdt_read32(void *opaque, target_phys_addr_t addr)
3329 return omap3_wdt_read32(opaque, addr, OMAP3_MPU_WDT);
3332 static void omap3_wdt_write32(void *opaque, target_phys_addr_t addr,
3333 uint32_t value, int wdt_index)
3335 struct omap3_wdt_s *s = (struct omap3_wdt_s *) opaque;
3337 //printf("omap3_wdt_write32 addr %x value %x \n",addr,value);
3340 case 0x14: /*WD_SYSSTATUS */
3342 /*WWPS*/ OMAP_RO_REG(addr);
3345 case 0x10: /*WD_SYSCONFIG */
3346 s->wd_sysconfig = value & 0x33f;
3349 /*WISR*/ s->wisr = value & 0x1;
3352 /*WIER*/ s->wier = value & 0x1;
3355 /*WCLR*/ s->wclr = value & 0x3c;
3358 /*WCRR*/ s->wcrr = value;
3359 s->time = qemu_get_clock(vm_clock);
3360 omap3_wdt_timer_update(s);
3363 /*WLDR*/ s->wldr = value; /*It will take effect after next overflow */
3366 /*WTGR*/ if (value != s->wtgr)
3369 s->pre = s->wclr & (1 << 5);
3370 s->ptv = (s->wclr & 0x1c) >> 2;
3371 s->rate = omap_clk_getrate(s->clk) >> (s->pre ? s->ptv : 0);
3372 s->time = qemu_get_clock(vm_clock);
3373 omap3_wdt_timer_update(s);
3379 if (((value & 0xffff) == 0x5555) && ((s->wspr & 0xffff) == 0xaaaa))
3382 s->wcrr = omap3_wdt_timer_read(s);
3383 omap3_wdt_timer_update(s);
3385 if (((value & 0xffff) == 0x4444) && ((s->wspr & 0xffff) == 0xbbbb))
3388 s->time = qemu_get_clock(vm_clock);
3389 omap3_wdt_timer_update(s);
3394 printf("omap3_wdt_write32 addr %x \n", addr);
3399 static void omap3_mpu_wdt_write16(void *opaque, target_phys_addr_t addr,
3402 struct omap3_wdt_s *s = (struct omap3_wdt_s *) opaque;
3405 return omap3_wdt_write32(opaque, addr, (value << 16) | s->writeh,
3408 s->writeh = (uint16_t) value;
3411 static void omap3_mpu_wdt_write32(void *opaque, target_phys_addr_t addr,
3414 omap3_wdt_write32(opaque, addr, value, OMAP3_MPU_WDT);
3417 static CPUReadMemoryFunc *omap3_mpu_wdt_readfn[] = {
3418 omap_badwidth_read32,
3419 omap3_mpu_wdt_read16,
3420 omap3_mpu_wdt_read32,
3423 static CPUWriteMemoryFunc *omap3_mpu_wdt_writefn[] = {
3424 omap_badwidth_write32,
3425 omap3_mpu_wdt_write16,
3426 omap3_mpu_wdt_write32,
3429 static void omap3_mpu_wdt_timer_tick(void *opaque)
3431 struct omap3_wdt_s *wdt_timer = (struct omap3_wdt_s *) opaque;
3433 /*TODO:Sent reset pulse to PRCM */
3434 wdt_timer->wcrr = wdt_timer->wldr;
3436 /*after overflow, generate the new wdt_timer->rate */
3437 wdt_timer->pre = wdt_timer->wclr & (1 << 5);
3438 wdt_timer->ptv = (wdt_timer->wclr & 0x1c) >> 2;
3440 omap_clk_getrate(wdt_timer->clk) >> (wdt_timer->pre ? wdt_timer->
3443 wdt_timer->time = qemu_get_clock(vm_clock);
3444 omap3_wdt_timer_update(wdt_timer);
3447 static struct omap3_wdt_s *omap3_mpu_wdt_init(struct omap_target_agent_s *ta,
3448 qemu_irq irq, omap_clk fclk,
3450 struct omap_mpu_state_s *mpu)
3453 struct omap3_wdt_s *s = (struct omap3_wdt_s *) qemu_mallocz(sizeof(*s));
3457 s->timer = qemu_new_timer(vm_clock, omap3_mpu_wdt_timer_tick, s);
3459 omap3_wdt_reset(s, OMAP3_MPU_WDT);
3461 omap3_wdt_clk_setup(s);
3463 iomemtype = l4_register_io_memory(0, omap3_mpu_wdt_readfn,
3464 omap3_mpu_wdt_writefn, s);
3465 omap_l4_attach(ta, 0, iomemtype);
3471 /*dummy system control module*/
3474 struct omap_mpu_state_s *mpu;
3476 uint8 interface[48]; /*0x4800 2000*/
3477 uint8 padconfs[576]; /*0x4800 2030*/
3478 uint32 general[228]; /*0x4800 2270*/
3479 uint8 mem_wkup[1024]; /*0x4800 2600*/
3480 uint8 padconfs_wkup[84]; /*0x4800 2a00*/
3481 uint32 general_wkup[8]; /*0x4800 2a60*/
3484 #define PADCONFS_VALUE(wakeup0,wakeup1,offmode0,offmode1, \
3485 inputenable0,inputenable1,pupd0,pupd1,muxmode0,muxmode1,offset) \
3487 *(padconfs+offset/4) = (wakeup0 <<14)|(offmode0<<9)|(inputenable0<<8)|(pupd0<<3)|(muxmode0); \
3488 *(padconfs+offset/4) |= (wakeup1 <<30)|(offmode1<<25)|(inputenable1<<24)|(pupd1<<19)|(muxmode1<<16); \
3492 static void omap3_scm_reset(struct omap3_scm_s *s)
3495 padconfs = (uint32 *)(s->padconfs);
3496 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x0);
3497 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x4);
3498 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x8);
3499 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0xc);
3500 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x10);
3501 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x14);
3502 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x18);
3503 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x1c);
3504 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x20);
3505 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x24);
3506 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x28);
3507 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x2c);
3508 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x30);
3509 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x34);
3510 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x38);
3511 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x3c);
3512 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x40);
3513 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x44);
3514 PADCONFS_VALUE(0,0,0,0,1,1,0,1,0,7,0x48);
3515 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x4c);
3516 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x50);
3517 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x54);
3518 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x58);
3519 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,0,0x5c);
3520 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x60);
3521 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x64);
3522 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x68);
3523 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x6c);
3524 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x70);
3525 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x74);
3526 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x78);
3527 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x7c);
3528 PADCONFS_VALUE(0,0,0,0,1,1,0,3,0,7,0x80);
3529 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x84);
3530 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x88);
3531 PADCONFS_VALUE(0,0,0,0,1,1,3,0,7,0,0x8c);
3532 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x90);
3533 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x94);
3534 PADCONFS_VALUE(0,0,0,0,1,1,1,0,7,0,0x98);
3535 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,7,0x9c);
3536 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0xa0);
3537 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0xa4);
3538 PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0xa8);
3539 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xac);
3540 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xb0);
3541 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xb4);
3542 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xb8);
3543 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xbc);
3544 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xc0);
3545 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xc4);
3546 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xc8);
3547 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xcc);
3548 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xd0);
3549 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xd4);
3550 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xd8);
3551 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xdc);
3552 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xe0);
3553 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xe4);
3554 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xe8);
3555 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xec);
3556 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xf0);
3557 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xf4);
3558 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xf8);
3559 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xfc);
3560 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x100);
3561 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x104);
3562 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x108);
3563 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x10c);
3564 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x110);
3565 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x114);
3566 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x118);
3567 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x11c);
3568 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x120);
3569 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x124);
3570 PADCONFS_VALUE(0,0,0,0,1,1,1,3,7,7,0x128);
3571 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x12c);
3572 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x130);
3573 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x134);
3574 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x138);
3575 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x13c);
3576 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x140);
3577 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x144);
3578 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x148);
3579 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x14c);
3580 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x150);
3581 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x154);
3582 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x158);
3583 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x15c);
3584 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x160);
3585 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x164);
3586 PADCONFS_VALUE(0,0,0,0,1,1,1,3,7,7,0x168);
3587 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x16c);
3588 PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0x170);
3589 PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0x174);
3590 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x178);
3591 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x17c);
3592 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x180);
3593 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x184);
3594 PADCONFS_VALUE(0,0,0,0,1,1,1,3,7,7,0x188);
3595 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x18c);
3596 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x190);
3597 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x194);
3598 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x198);
3599 PADCONFS_VALUE(0,0,0,0,1,1,1,3,7,7,0x19c);
3600 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x1a0);
3601 PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0x1a4);
3602 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x1a8);
3603 PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0x1ac);
3604 PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0x1b0);
3605 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1b4);
3606 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1b8);
3607 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1bc);
3608 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1c0);
3609 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1c4);
3610 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1c8);
3611 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1cc);
3612 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1d0);
3613 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1d4);
3614 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1d8);
3615 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1dc);
3616 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1e0);
3617 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1e4);
3618 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1e8);
3619 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1ec);
3620 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1f0);
3621 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1f4);
3622 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1f8);
3623 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1fc);
3624 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x200);
3625 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x204);
3626 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x208);
3627 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x20c);
3628 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x210);
3629 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x214);
3630 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x218);
3631 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x21c);
3632 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x220);
3633 PADCONFS_VALUE(0,0,0,0,1,1,3,1,0,0,0x224);
3634 PADCONFS_VALUE(0,0,0,0,1,1,0,1,0,0,0x228);
3635 PADCONFS_VALUE(0,0,0,0,1,1,0,1,0,0,0x22c);
3636 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x230);
3637 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x234);
3640 padconfs = (uint32 *)(s->general);
3641 s->general[1] = 0x4000000; /*0x4800 2274*/
3642 s->general[0x1c] = 0x1; /*0x4800 22e0*/
3643 s->general[0x75] = 0x7fc0; /*0x4800 2444*/
3644 s->general[0x76] = 0xaa; /*0x4800 2448*/
3645 s->general[0x7c] = 0x2700; /*0x4800 2460*/
3646 s->general[0x7d] = 0x300000; /*0x4800 2464*/
3647 s->general[0x7e] = 0x300000; /*0x4800 2468*/
3648 s->general[0x81] = 0xffff; /*0x4800 2474*/
3649 s->general[0x82] = 0xffff; /*0x4800 2478*/
3650 s->general[0x83] = 0xffff; /*0x4800 247c*/
3651 s->general[0x84] = 0x6; /*0x4800 2480*/
3652 s->general[0x85] = 0xffffffff; /*0x4800 2484*/
3653 s->general[0x86] = 0xffff; /*0x4800 2488*/
3654 s->general[0x87] = 0xffff; /*0x4800 248c*/
3655 s->general[0x88] = 0x1; /*0x4800 2490*/
3656 s->general[0x8b] = 0xffffffff; /*0x4800 249c*/
3657 s->general[0x8c] = 0xffff; /*0x4800 24a0*/
3658 s->general[0x8e] = 0xffff; /*0x4800 24a8*/
3659 s->general[0x8f] = 0xffff; /*0x4800 24ac*/
3660 s->general[0x91] = 0xffff; /*0x4800 24b4*/
3661 s->general[0x92] = 0xffff; /*0x4800 24b8*/
3662 s->general[0xac] = 0x109; /*0x4800 2520*/
3663 s->general[0xb2] = 0xffff; /*0x4800 2538*/
3664 s->general[0xb3] = 0xffff; /*0x4800 253c*/
3665 s->general[0xb4] = 0xffff; /*0x4800 2540*/
3666 PADCONFS_VALUE(0,0,0,0,1,1,3,3,4,4,0x368);
3667 PADCONFS_VALUE(0,0,0,0,1,1,3,3,4,4,0x36c);
3668 PADCONFS_VALUE(0,0,0,0,1,1,3,3,4,4,0x370);
3669 PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x374);
3670 PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x378);
3671 PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x37c);
3672 PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x380);
3673 PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x384);
3674 PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x388);
3678 padconfs = (uint32 *)(s->padconfs_wkup);
3679 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x0);
3680 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x4);
3681 PADCONFS_VALUE(0,0,0,0,1,1,3,0,0,0,0x8);
3682 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0xc);
3683 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x10);
3684 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x14);
3685 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x18);
3686 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1c);
3687 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x20);
3688 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x24);
3689 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x2c);
3692 s->general_wkup[0] = 0x66ff; /*0x4800 2A60*/
3696 static uint32_t omap3_scm_read8(void *opaque, target_phys_addr_t addr)
3698 struct omap3_scm_s *s = (struct omap3_scm_s *) opaque;
3703 return s->interface[addr];
3704 case 0x30 ... 0x26f:
3705 return s->padconfs[addr-0x30];
3706 case 0x270 ... 0x5ff:
3707 temp = (uint8_t *)s->general;
3708 return temp[addr-0x270];
3709 case 0x600 ... 0x9ff:
3710 return s->mem_wkup[addr-0x600];
3711 case 0xa00 ... 0xa5f:
3712 return s->padconfs_wkup[addr-0xa00];
3713 case 0xa60 ... 0xa7f:
3714 temp = (uint8_t *)s->general_wkup;
3715 return temp[addr-0xa60];
3719 printf("omap3_scm_read8 addr %x pc %x \n", addr,cpu_single_env->regs[15] );
3723 static uint32_t omap3_scm_read16(void *opaque, target_phys_addr_t addr)
3726 v = omap3_scm_read8(opaque, addr);
3727 v |= omap3_scm_read8(opaque, addr + 1) << 8;
3731 static uint32_t omap3_scm_read32(void *opaque, target_phys_addr_t addr)
3734 v = omap3_scm_read8(opaque, addr);
3735 v |= omap3_scm_read8(opaque, addr + 1) << 8;
3736 v |= omap3_scm_read8(opaque, addr + 2) << 16;
3737 v |= omap3_scm_read8(opaque, addr + 3) << 24;
3741 static void omap3_scm_write8(void *opaque, target_phys_addr_t addr,
3744 struct omap3_scm_s *s = (struct omap3_scm_s *) opaque;
3750 s->interface[addr] = value;
3752 case 0x30 ... 0x26f:
3753 s->padconfs[addr-0x30] = value;
3755 case 0x270 ... 0x5ff:
3756 temp = (uint8_t *)s->general;
3757 temp[addr-0x270] = value;
3759 case 0x600 ... 0x9ff:
3760 s->mem_wkup[addr-0x600] = value;
3762 case 0xa00 ... 0xa5f:
3763 s->padconfs_wkup[addr-0xa00] = value;
3765 case 0xa60 ... 0xa7f:
3766 temp = (uint8_t *)s->general_wkup;
3767 temp[addr-0xa60] = value;
3770 /*we do not care scm write*/
3771 printf("omap3_scm_write8 addr %x pc %x \n \n", addr,
3772 cpu_single_env->regs[15] - 0x80008000 + 0x80e80000);
3778 static void omap3_scm_write16(void *opaque, target_phys_addr_t addr,
3781 omap3_scm_write8(opaque, addr + 0, (value) & 0xff);
3782 omap3_scm_write8(opaque, addr + 1, (value >> 8) & 0xff);
3785 static void omap3_scm_write32(void *opaque, target_phys_addr_t addr,
3788 omap3_scm_write8(opaque, addr + 0, (value) & 0xff);
3789 omap3_scm_write8(opaque, addr + 1, (value >> 8) & 0xff);
3790 omap3_scm_write8(opaque, addr + 2, (value >> 16) & 0xff);
3791 omap3_scm_write8(opaque, addr + 3, (value >> 24) & 0xff);
3794 static CPUReadMemoryFunc *omap3_scm_readfn[] = {
3800 static CPUWriteMemoryFunc *omap3_scm_writefn[] = {
3806 static struct omap3_scm_s *omap3_scm_init(struct omap_target_agent_s *ta,
3807 struct omap_mpu_state_s *mpu)
3810 struct omap3_scm_s *s = (struct omap3_scm_s *) qemu_mallocz(sizeof(*s));
3816 iomemtype = l4_register_io_memory(0, omap3_scm_readfn,
3817 omap3_scm_writefn, s);
3818 omap_l4_attach(ta, 0, iomemtype);
3823 /*dummy SDRAM Memory Scheduler emulation*/
3826 struct omap_mpu_state_s *mpu;
3828 uint32 sms_sysconfig;
3829 uint32 sms_sysstatus;
3830 uint32 sms_rg_att[8];
3831 uint32 sms_rg_rdperm[8];
3832 uint32 sms_rg_wrperm[8];
3833 uint32 sms_rg_start[7];
3834 uint32 sms_rg_end[7];
3835 uint32 sms_security_control;
3836 uint32 sms_class_arbiter0;
3837 uint32 sms_class_arbiter1;
3838 uint32 sms_class_arbiter2;
3839 uint32 sms_interclass_arbiter;
3840 uint32 sms_class_rotation[3];
3841 uint32 sms_err_addr;
3842 uint32 sms_err_type;
3843 uint32 sms_pow_ctrl;
3844 uint32 sms_rot_control[12];
3845 uint32 sms_rot_size[12];
3846 uint32 sms_rot_physical_ba[12];
3849 static uint32_t omap3_sms_read32(void *opaque, target_phys_addr_t addr)
3851 struct omap3_sms_s *s = (struct omap3_sms_s *) opaque;
3856 return s->sms_sysconfig;
3858 return s->sms_sysstatus;
3867 return s->sms_rg_att[(addr-0x48)/0x20];
3876 return s->sms_rg_rdperm[(addr-0x50)/0x20];
3884 return s->sms_rg_wrperm[(addr-0x58)/0x20];
3892 return s->sms_rg_start[(addr-0x60)/0x20];
3901 return s->sms_rg_end[(addr-0x64)/0x20];
3903 return s->sms_security_control;
3905 return s->sms_class_arbiter0;
3907 return s->sms_class_arbiter1;
3909 return s->sms_class_arbiter2;
3911 return s->sms_interclass_arbiter;
3915 return s->sms_class_rotation[(addr-0x164)/4];
3917 return s->sms_err_addr;
3919 return s->sms_err_type;
3921 return s->sms_pow_ctrl;
3934 return s->sms_rot_control[(addr-0x180)/0x10];
3947 return s->sms_rot_size[(addr-0x184)/0x10];
3961 return s->sms_rot_size[(addr-0x188)/0x10];
3964 printf("omap3_sms_read32 addr %x \n", addr);
3969 static void omap3_sms_write32(void *opaque, target_phys_addr_t addr,
3972 struct omap3_sms_s *s = (struct omap3_sms_s *) opaque;
3981 s->sms_sysconfig = value & 0x1f;
3992 s->sms_rg_att[(addr-0x48)/0x20] = value;
4002 s->sms_rg_rdperm[(addr-0x50)/0x20] = value&0xffff;
4011 s->sms_rg_wrperm[(addr-0x58)/0x20] = value&0xffff;
4020 s->sms_rg_start[(addr-0x60)/0x20] = value;
4029 s->sms_rg_end[(addr-0x64)/0x20] = value;
4032 s->sms_security_control = value &0xfffffff;
4035 s->sms_class_arbiter0 = value;
4038 s->sms_class_arbiter1 = value;
4041 s->sms_class_arbiter2 = value;
4044 s->sms_interclass_arbiter = value;
4049 s->sms_class_rotation[(addr-0x164)/4] = value;
4052 s->sms_err_addr = value;
4055 s->sms_err_type = value;
4058 s->sms_pow_ctrl = value;
4072 s->sms_rot_control[(addr-0x180)/0x10] = value;
4086 s->sms_rot_size[(addr-0x184)/0x10] = value;
4101 s->sms_rot_size[(addr-0x188)/0x10] = value;
4104 printf("omap3_sms_write32 addr %x\n", addr);
4109 static CPUReadMemoryFunc *omap3_sms_readfn[] = {
4110 omap_badwidth_read32,
4111 omap_badwidth_read32,
4115 static CPUWriteMemoryFunc *omap3_sms_writefn[] = {
4116 omap_badwidth_write32,
4117 omap_badwidth_write32,
4121 static void omap3_sms_reset(struct omap3_sms_s *s)
4123 s->sms_sysconfig = 0x1;
4124 s->sms_class_arbiter0 = 0x500000;
4125 s->sms_class_arbiter1 = 0x500;
4126 s->sms_class_arbiter2 = 0x55000;
4127 s->sms_interclass_arbiter = 0x400040;
4128 s->sms_class_rotation[0] = 0x1;
4129 s->sms_class_rotation[1] = 0x1;
4130 s->sms_class_rotation[2] = 0x1;
4131 s->sms_pow_ctrl = 0x80;
4134 static struct omap3_sms_s *omap3_sms_init(struct omap_mpu_state_s *mpu)
4137 struct omap3_sms_s *s = (struct omap3_sms_s *) qemu_mallocz(sizeof(*s));
4143 iomemtype = cpu_register_io_memory(0, omap3_sms_readfn,
4144 omap3_sms_writefn, s);
4145 cpu_register_physical_memory(0x6c000000, 0x10000, iomemtype);
4150 static const struct dma_irq_map omap3_dma_irq_map[] = {
4151 {0, OMAP_INT_35XX_SDMA_IRQ0},
4152 {0, OMAP_INT_35XX_SDMA_IRQ1},
4153 {0, OMAP_INT_35XX_SDMA_IRQ2},
4154 {0, OMAP_INT_35XX_SDMA_IRQ3},
4157 static int omap3_validate_addr(struct omap_mpu_state_s *s,
4158 target_phys_addr_t addr)
4164 set the kind of memory connected to GPMC that we are trying to boot form.
4165 Uses SYS BOOT settings.
4167 void omap3_set_mem_type(struct omap_mpu_state_s *s,int bootfrom)
4169 s->omap3_scm->general[32] &= ~0x3f;
4171 case 0x0: /*GPMC_NOR*/
4172 s->omap3_scm->general[32] |= 7;
4174 case 0x1: /*GPMC_NAND*/
4175 s->omap3_scm->general[32] |= 1;
4178 s->omap3_scm->general[32] |= 8;
4181 s->omap3_scm->general[32] |= 0;
4184 s->omap3_scm->general[32] |= 17;
4187 s->omap3_scm->general[32] |= 3;
4192 void omap3_set_device_type(struct omap_mpu_state_s *s,int device_type)
4194 s->omap3_scm->general[32] &= ~(0x7 << 8);
4195 s->omap3_scm->general[32] |= (device_type & 0x7) << 8;
4198 struct omap_mpu_state_s *omap3530_mpu_init(unsigned long sdram_size,
4201 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
4202 qemu_mallocz(sizeof(struct omap_mpu_state_s));
4203 ram_addr_t sram_base, q2_base;
4205 qemu_irq dma_irqs[4];
4208 //omap_clk gpio_clks[4];
4210 s->mpu_model = omap3530;
4211 s->env = cpu_init("cortex-a8-r2");
4213 fprintf(stderr, "Unable to find CPU definition\n");
4216 s->sdram_size = sdram_size;
4217 s->sram_size = OMAP3530_SRAM_SIZE;
4219 sdindex = drive_get_index(IF_SD, 0, 0);
4220 if (sdindex == -1) {
4221 fprintf(stderr, "qemu: missing SecureDigital device\n");
4228 /* Memory-mapped stuff */
4230 q2_base = qemu_ram_alloc(s->sdram_size);
4231 cpu_register_physical_memory(OMAP3_Q2_BASE, s->sdram_size,
4232 (q2_base | IO_MEM_RAM));
4233 sram_base = qemu_ram_alloc(s->sram_size);
4234 cpu_register_physical_memory(OMAP3_SRAM_BASE, s->sram_size,
4235 (sram_base | IO_MEM_RAM));
4237 s->l4 = omap_l4_init(OMAP3_L4_BASE,
4238 sizeof(omap3_l4_agent_info)
4239 / sizeof(struct omap3_l4_agent_info_s));
4241 cpu_irq = arm_pic_init_cpu(s->env);
4242 s->ih[0] = omap2_inth_init(s, 0x48200000, 0x1000, 3, &s->irq[0],
4243 cpu_irq[ARM_PIC_CPU_IRQ],
4244 cpu_irq[ARM_PIC_CPU_FIQ],
4245 omap_findclk(s, "omap3_mpu_intc_fclk"),
4246 omap_findclk(s, "omap3_mpu_intc_iclk"));
4248 for (i = 0; i < 4; i++)
4250 s->irq[omap3_dma_irq_map[i].ih][omap3_dma_irq_map[i].intr];
4251 s->dma = omap_dma4_init(0x48056000, dma_irqs, s, 256, 32,
4252 omap_findclk(s, "omap3_sdma_fclk"),
4253 omap_findclk(s, "omap3_sdma_iclk"));
4254 s->port->addr_valid = omap3_validate_addr;
4257 /* Register SDRAM and SRAM ports for fast DMA transfers. */
4258 soc_dma_port_add_mem_ram(s->dma, q2_base, OMAP2_Q2_BASE, s->sdram_size);
4259 soc_dma_port_add_mem_ram(s->dma, sram_base, OMAP2_SRAM_BASE, s->sram_size);
4262 s->omap3_cm = omap3_cm_init(omap3_l4ta_init(s->l4, L4A_CM), NULL, NULL, NULL, s);
4264 s->omap3_prm = omap3_prm_init(omap3_l4ta_init(s->l4, L4A_PRM),
4265 s->irq[0][OMAP_INT_35XX_PRCM_MPU_IRQ],
4268 s->omap3_mpu_wdt = omap3_mpu_wdt_init(omap3_l4ta_init(s->l4, L4A_WDTIMER2),
4270 omap_findclk(s, "omap3_wkup_32k_fclk"),
4271 omap_findclk(s, "omap3_wkup_l4_iclk"),
4274 s->omap3_l3 = omap3_l3_init(OMAP3_L3_BASE,
4276 sizeof(omap3_l3_region)
4277 / sizeof(struct omap_l3_region_s));
4278 s->omap3_scm = omap3_scm_init(omap3_l4ta_init(s->l4, L4A_SCM), s);
4280 s->omap3_sms = omap3_sms_init(s);
4282 s->gptimer[0] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER1),
4283 s->irq[0][OMAP_INT_35XX_GPTIMER1],
4284 omap_findclk(s, "omap3_gp1_fclk"),
4285 omap_findclk(s, "omap3_wkup_l4_iclk"));
4286 s->gptimer[1] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER2),
4287 s->irq[0][OMAP_INT_35XX_GPTIMER2],
4288 omap_findclk(s, "omap3_gp2_fclk"),
4289 omap_findclk(s, "omap3_per_l4_iclk"));
4290 s->gptimer[2] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER3),
4291 s->irq[0][OMAP_INT_35XX_GPTIMER3],
4292 omap_findclk(s, "omap3_gp3_fclk"),
4293 omap_findclk(s, "omap3_per_l4_iclk"));
4294 s->gptimer[3] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER4),
4295 s->irq[0][OMAP_INT_35XX_GPTIMER4],
4296 omap_findclk(s, "omap3_gp4_fclk"),
4297 omap_findclk(s, "omap3_per_l4_iclk"));
4298 s->gptimer[4] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER5),
4299 s->irq[0][OMAP_INT_35XX_GPTIMER5],
4300 omap_findclk(s, "omap3_gp5_fclk"),
4301 omap_findclk(s, "omap3_per_l4_iclk"));
4302 s->gptimer[5] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER6),
4303 s->irq[0][OMAP_INT_35XX_GPTIMER6],
4304 omap_findclk(s, "omap3_gp6_fclk"),
4305 omap_findclk(s, "omap3_per_l4_iclk"));
4306 s->gptimer[6] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER7),
4307 s->irq[0][OMAP_INT_35XX_GPTIMER7],
4308 omap_findclk(s, "omap3_gp7_fclk"),
4309 omap_findclk(s, "omap3_per_l4_iclk"));
4310 s->gptimer[7] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER8),
4311 s->irq[0][OMAP_INT_35XX_GPTIMER8],
4312 omap_findclk(s, "omap3_gp8_fclk"),
4313 omap_findclk(s, "omap3_per_l4_iclk"));
4314 s->gptimer[8] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER9),
4315 s->irq[0][OMAP_INT_35XX_GPTIMER9],
4316 omap_findclk(s, "omap3_gp9_fclk"),
4317 omap_findclk(s, "omap3_per_l4_iclk"));
4318 s->gptimer[9] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER10),
4319 s->irq[0][OMAP_INT_35XX_GPTIMER10],
4320 omap_findclk(s, "omap3_gp10_fclk"),
4321 omap_findclk(s, "omap3_core_l4_iclk"));
4322 s->gptimer[10] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER11),
4323 s->irq[0][OMAP_INT_35XX_GPTIMER11],
4324 omap_findclk(s, "omap3_gp12_fclk"),
4325 omap_findclk(s, "omap3_core_l4_iclk"));
4326 s->gptimer[11] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER12),
4327 s->irq[0][OMAP_INT_35XX_GPTIMER12],
4328 omap_findclk(s, "omap3_gp12_fclk"),
4329 omap_findclk(s, "omap3_wkup_l4_iclk"));
4332 omap_synctimer_init(omap3_l4ta_init(s->l4, L4A_32KTIMER), s,
4333 omap_findclk(s, "omap3_sys_32k"), NULL);
4335 s->sdrc = omap_sdrc_init(0x6d000000);
4337 s->gpmc = omap_gpmc_init(s, 0x6e000000, s->irq[0][OMAP_INT_35XX_GPMC_IRQ]);
4340 s->uart[0] = omap2_uart_init(omap3_l4ta_init(s->l4, L4A_UART1),
4341 s->irq[0][OMAP_INT_35XX_UART1_IRQ],
4342 omap_findclk(s, "omap3_uart1_fclk"),
4343 omap_findclk(s, "omap3_uart1_iclk"),
4344 s->drq[OMAP35XX_DMA_UART1_TX],
4345 s->drq[OMAP35XX_DMA_UART1_RX], serial_hds[0]);
4346 s->uart[1] = omap2_uart_init(omap3_l4ta_init(s->l4, L4A_UART2),
4347 s->irq[0][OMAP_INT_35XX_UART2_IRQ],
4348 omap_findclk(s, "omap3_uart2_fclk"),
4349 omap_findclk(s, "omap3_uart2_iclk"),
4350 s->drq[OMAP35XX_DMA_UART2_TX],
4351 s->drq[OMAP35XX_DMA_UART2_RX],
4352 serial_hds[0] ? serial_hds[1] : 0);
4353 s->uart[2] = omap2_uart_init(omap3_l4ta_init(s->l4, L4A_UART3),
4354 s->irq[0][OMAP_INT_35XX_UART3_IRQ],
4355 omap_findclk(s, "omap3_uart2_fclk"),
4356 omap_findclk(s, "omap3_uart3_iclk"),
4357 s->drq[OMAP35XX_DMA_UART3_TX],
4358 s->drq[OMAP35XX_DMA_UART3_RX],
4360 && serial_hds[1] ? serial_hds[2] : 0);
4362 /*attach serial[0] to uart 2 for beagle board */
4363 omap_uart_attach(s->uart[2], serial_hds[0]);
4365 s->dss = omap_dss_init(s, omap3_l4ta_init(s->l4, L4A_DSS),
4366 s->irq[0][OMAP_INT_35XX_DSS_IRQ], s->drq[OMAP24XX_DMA_DSS],
4367 NULL,NULL,NULL,NULL,NULL);
4369 //gpio_clks[0] = NULL;
4370 //gpio_clks[1] = NULL;
4371 //gpio_clks[2] = NULL;
4372 //gpio_clks[3] = NULL;
4374 s->gpif = omap3_gpif_init();
4375 omap3_gpio_init(s, s->gpif ,omap3_l4ta_init(s->l4, L4A_GPIO1),
4376 &s->irq[0][OMAP_INT_35XX_GPIO_BANK1],
4378 omap3_gpio_init(s, s->gpif ,omap3_l4ta_init(s->l4, L4A_GPIO2),
4379 &s->irq[0][OMAP_INT_35XX_GPIO_BANK2],
4381 omap3_gpio_init(s, s->gpif ,omap3_l4ta_init(s->l4, L4A_GPIO3),
4382 &s->irq[0][OMAP_INT_35XX_GPIO_BANK3],
4384 omap3_gpio_init(s, s->gpif ,omap3_l4ta_init(s->l4, L4A_GPIO4),
4385 &s->irq[0][OMAP_INT_35XX_GPIO_BANK4],
4387 omap3_gpio_init(s, s->gpif ,omap3_l4ta_init(s->l4, L4A_GPIO5),
4388 &s->irq[0][OMAP_INT_35XX_GPIO_BANK5],
4390 omap3_gpio_init(s, s->gpif ,omap3_l4ta_init(s->l4, L4A_GPIO6),
4391 &s->irq[0][OMAP_INT_35XX_GPIO_BANK6],
4394 omap_tap_init(omap3_l4ta_init(s->l4, L4A_TAP), s);
4396 s->omap3_mmc[0] = omap3_mmc_init(omap3_l4ta_init(s->l4, L4A_MMC1),
4397 drives_table[sdindex].bdrv,
4398 s->irq[0][OMAP_INT_35XX_MMC1_IRQ],
4399 &s->drq[OMAP35XX_DMA_MMC1_TX],
4400 omap_findclk(s, "omap3_mmc1_fclk"),
4401 omap_findclk(s, "omap3_mmc1_iclk"));
4403 s->omap3_mmc[1] = omap3_mmc_init(omap3_l4ta_init(s->l4, L4A_MMC2),
4405 s->irq[0][OMAP_INT_35XX_MMC2_IRQ],
4406 &s->drq[OMAP35XX_DMA_MMC2_TX],
4407 omap_findclk(s, "omap3_mmc2_fclk"),
4408 omap_findclk(s, "omap3_mmc2_iclk"));
4410 s->omap3_mmc[2] = omap3_mmc_init(omap3_l4ta_init(s->l4, L4A_MMC3),
4412 s->irq[0][OMAP_INT_35XX_MMC3_IRQ],
4413 &s->drq[OMAP35XX_DMA_MMC3_TX],
4414 omap_findclk(s, "omap3_mmc3_fclk"),
4415 omap_findclk(s, "omap3_mmc3_iclk"));
4417 s->i2c[0] = omap3_i2c_init(omap3_l4ta_init(s->l4, L4A_I2C1),
4418 s->irq[0][OMAP_INT_35XX_I2C1_IRQ],
4419 &s->drq[OMAP35XX_DMA_I2C1_TX],
4420 omap_findclk(s, "omap3_i2c1_fclk"),
4421 omap_findclk(s, "omap3_i2c1_iclk"),
4423 s->i2c[1] = omap3_i2c_init(omap3_l4ta_init(s->l4, L4A_I2C2),
4424 s->irq[0][OMAP_INT_35XX_I2C2_IRQ],
4425 &s->drq[OMAP35XX_DMA_I2C2_TX],
4426 omap_findclk(s, "omap3_i2c2_fclk"),
4427 omap_findclk(s, "omap3_i2c2_iclk"),
4429 s->i2c[2] = omap3_i2c_init(omap3_l4ta_init(s->l4, L4A_I2C3),
4430 s->irq[0][OMAP_INT_35XX_I2C3_IRQ],
4431 &s->drq[OMAP35XX_DMA_I2C3_TX],
4432 omap_findclk(s, "omap3_i2c3_fclk"),
4433 omap_findclk(s, "omap3_i2c3_iclk"),
4440 static inline uint32_t omap3_get_le32(const void *p)
4442 const uint8_t *q = (const uint8_t *)p;
4451 static inline uint32_t omap3_get_le16(const void *p)
4453 const uint8_t *q = (const uint8_t *)p;
4460 static inline void omap3_boot_setlsb(target_phys_addr_t addr, uint16_t lsb)
4464 cpu_physical_memory_read(addr, x, 4);
4466 x[1] = (lsb >> 8) & 0xff;
4467 cpu_physical_memory_write(addr, x, 4);
4470 struct omap3_boot_s {
4471 struct omap_mpu_state_s *mpu;
4480 target_phys_addr_t addr;
4484 static struct omap3_boot_s *omap3_boot_init(const uint8_t *data,
4486 struct omap_mpu_state_s *mpu)
4488 struct omap3_boot_s *s = qemu_mallocz(sizeof(struct omap3_boot_s));
4490 s->state = imagehdr;
4491 if (data_len >= 512) {
4492 if (!strncasecmp((char *)(data + 0x14), "chsettings", 10)
4493 || !strncasecmp((char *)(data + 0x14), "chram", 5)
4494 || !strncasecmp((char *)(data + 0x14), "chflash", 7)
4495 || !strncasecmp((char *)(data + 0x14), "chmmcsd", 7))
4496 s->state = confighdr;
4501 static void omap3_boot_chsettings(const uint8_t *chtoc)
4505 if (omap3_get_le32(chtoc) != 0xc0c0c0c1) {
4506 fprintf(stderr, "%s: invalid section verification key\n", __FUNCTION__);
4509 if (!chtoc[4]) { /* section disabled? */
4512 if (omap3_get_le16(chtoc + 5) != 0x0001) {
4513 fprintf(stderr, "%s: unsupported CH version (0x%04x)\n", __FUNCTION__,
4514 omap3_get_le16(chtoc));
4517 flags = omap3_get_le32(chtoc + 8);
4520 cpu_physical_memory_write(0x48307270, chtoc + 0x00, 4); /* PRM_CLKSRC_CTRL */
4521 cpu_physical_memory_write(0x48306d40, chtoc + 0x04, 4); /* PRM_CLKSEL */
4522 cpu_physical_memory_write(0x48005140, chtoc + 0x08, 4); /* CM_CLKSEL1_EMU */
4523 if (flags & (1 << 2)) { /* clock configuration */
4524 cpu_physical_memory_write(0x48004a40, chtoc + 0x0c, 4); /* CM_CLKSEL_CORE */
4525 cpu_physical_memory_write(0x48004c40, chtoc + 0x10, 4); /* CM_CLKSEL_WKUP */
4527 if (flags & (1 << 5)) { /* DPLL3 CORE */
4528 if (flags & (1 << 8)) { /* enable DPLL3 bypass */
4529 cpu_physical_memory_read(0x48004d00, (uint8_t *)&x, 4);
4530 x &= ~7; x |= 5; /* set DPLL3 bypass */
4531 cpu_physical_memory_write(0x48004d00, (uint8_t *)&x, 4);
4533 cpu_physical_memory_write(0x48004d00, chtoc + 0x14, 4); /* CM_CLKEN_PLL */
4534 cpu_physical_memory_write(0x48004d30, chtoc + 0x18, 4); /* CM_AUTOIDLE_PLL */
4535 cpu_physical_memory_write(0x48004d40, chtoc + 0x1c, 4); /* CM_CLKSEL1_PLL */
4537 if (flags & (1 << 3)) { /* DPLL4 PER */
4538 if (flags & (1 << 6)) { /* enable DPLL4 bypass */
4539 cpu_physical_memory_read(0x48004d00, (uint8_t *)&x, 4);
4540 x &= ~0x70000; x |= 0x10000; /* set DPLL4 in stop mode */
4541 cpu_physical_memory_write(0x48004d00, (uint8_t *)&x, 4);
4543 cpu_physical_memory_write(0x48004d00, chtoc + 0x20, 4); /* CM_CLKEN_PLL */
4544 cpu_physical_memory_write(0x48004d30, chtoc + 0x24, 4); /* CM_AUTOIDLE_PLL */
4545 cpu_physical_memory_write(0x48004d44, chtoc + 0x28, 4); /* CM_CLKSEL2_PLL */
4546 cpu_physical_memory_write(0x48004d48, chtoc + 0x2c, 4); /* CM_CLKSEL3_PLL */
4548 if (flags & (1 << 3)) { /* DPLL1 MPU */
4549 if (flags & (1 << 7)) { /* enable DPLL1 bypass */
4550 cpu_physical_memory_read(0x48004904, (uint8_t *)&x, 4);
4551 x &= ~7; x |= 5; /* set DPLL1 bypass */
4552 cpu_physical_memory_write(0x48004904, (uint8_t *)&x, 4);
4554 cpu_physical_memory_write(0x48004904, chtoc + 0x30, 4); /* CM_CLKEN_PLL_MPU */
4555 cpu_physical_memory_write(0x48004934, chtoc + 0x34, 4); /* CM_AUTOIDLE_PLL_MPU */
4556 cpu_physical_memory_write(0x48004940, chtoc + 0x38, 4); /* CM_CLKSEL1_PLL_MPU */
4557 cpu_physical_memory_write(0x48004944, chtoc + 0x3c, 4); /* CM_CLKSEL2_PLL_MPU */
4558 cpu_physical_memory_write(0x48004948, chtoc + 0x40, 4); /* CM_CLKSTCTRL_MPU */
4560 switch ((flags >> 24) & 0xff) {
4561 case 0x01: x = 0; break; /* 12MHz */
4562 case 0x02: x = 1; break; /* 13MHz */
4563 case 0x03: x = 5; break; /* 16.8MHz */
4564 case 0x04: x = 2; break; /* 19.2MHz */
4565 case 0x05: x = 3; break; /* 26MHz */
4566 case 0x06: x = 4; break; /* 38.4MHz */
4568 fprintf(stderr, "%s: unsupported SYS.CLK setting\n", __FUNCTION__);
4572 if (x != omap3_get_le32(chtoc + 0x04)) {
4573 fprintf(stderr, "%s: mismatch in SYS.CLK id and PRM_CLKSEL value\n", __FUNCTION__);
4578 static void omap3_boot_chram(const uint8_t *chtoc)
4580 if (omap3_get_le32(chtoc) != 0xc0c0c0c2) {
4581 fprintf(stderr, "%s: invalid section verification key\n", __FUNCTION__);
4584 if (!chtoc[4]) { /* section disabled? */
4587 omap3_boot_setlsb(0x6d000040, omap3_get_le16(chtoc + 0x0a)); /* SDRC_CS_CFG */
4588 omap3_boot_setlsb(0x6d000044, omap3_get_le16(chtoc + 0x0c)); /* SDRC_SHARING */
4589 cpu_physical_memory_write(0x6d000060, chtoc + 0x10, 4); /* SDRC_DLLA_CTRL */
4591 cpu_physical_memory_write(0x6d000080, chtoc + 0x20, 4); /* SDRC_MCFG_0 */
4592 omap3_boot_setlsb(0x6d000084, omap3_get_le16(chtoc + 0x24)); /* SDRC_MR_0 */
4593 omap3_boot_setlsb(0x6d000088, omap3_get_le16(chtoc + 0x26)); /* SDRC_EMR1_0? */
4594 omap3_boot_setlsb(0x6d00008c, omap3_get_le16(chtoc + 0x28)); /* SDRC_EMR2_0 */
4595 omap3_boot_setlsb(0x6d000090, omap3_get_le16(chtoc + 0x2a)); /* SDRC_EMR3_0? */
4596 cpu_physical_memory_write(0x6d00009c, chtoc + 0x2c, 4); /* SDRC_ACTIM_CTRLA_0 */
4597 cpu_physical_memory_write(0x6d0000a0, chtoc + 0x30, 4); /* SDRC_ACTIM_CTRLB_0 */
4598 cpu_physical_memory_write(0x6d0000a4, chtoc + 0x34, 4); /* SDRC_RFR_CTRL_0 */
4600 cpu_physical_memory_write(0x6d0000b0, chtoc + 0x20, 4); /* SDRC_MCFG_1 */
4601 omap3_boot_setlsb(0x6d0000b4, omap3_get_le16(chtoc + 0x24)); /* SDRC_MR_1 */
4602 omap3_boot_setlsb(0x6d0000b8, omap3_get_le16(chtoc + 0x26)); /* SDRC_EMR1_1? */
4603 omap3_boot_setlsb(0x6d0000bc, omap3_get_le16(chtoc + 0x28)); /* SDRC_EMR2_1 */
4604 omap3_boot_setlsb(0x6d0000c0, omap3_get_le16(chtoc + 0x2a)); /* SDRC_EMR3_1? */
4605 cpu_physical_memory_write(0x6d0000cc, chtoc + 0x2c, 4); /* SDRC_ACTIM_CTRLA_1 */
4606 cpu_physical_memory_write(0x6d0000d0, chtoc + 0x30, 4); /* SDRC_ACTIM_CTRLB_1 */
4607 cpu_physical_memory_write(0x6d0000d4, chtoc + 0x34, 4); /* SDRC_RFR_CTRL_1 */
4610 static void omap3_boot_chflash(const uint8_t *chtoc)
4612 if (omap3_get_le32(chtoc) != 0xc0c0c0c3) {
4613 fprintf(stderr, "%s: invalid section verification key\n", __FUNCTION__);
4616 if (!chtoc[4]) { /* section disabled? */
4619 omap3_boot_setlsb(0x6e000010, omap3_get_le16(chtoc + 0x08)); /* GPMC_SYSCONFIG */
4620 omap3_boot_setlsb(0x6e00001c, omap3_get_le16(chtoc + 0x0a)); /* GPMC_IRQENABLE */
4621 omap3_boot_setlsb(0x6e000040, omap3_get_le16(chtoc + 0x0c)); /* GPMC_TIMEOUT_CONTROL */
4622 omap3_boot_setlsb(0x6e000050, omap3_get_le16(chtoc + 0x0e)); /* GPMC_CONFIG */
4623 cpu_physical_memory_write(0x6e000060, chtoc + 0x10, 4); /* GPMC_CONFIG1_0 */
4624 cpu_physical_memory_write(0x6e000064, chtoc + 0x14, 4); /* GPMC_CONFIG2_0 */
4625 cpu_physical_memory_write(0x6e000068, chtoc + 0x18, 4); /* GPMC_CONFIG3_0 */
4626 cpu_physical_memory_write(0x6e00006c, chtoc + 0x1c, 4); /* GPMC_CONFIG4_0 */
4627 cpu_physical_memory_write(0x6e000070, chtoc + 0x20, 4); /* GPMC_CONFIG5_0 */
4628 cpu_physical_memory_write(0x6e000074, chtoc + 0x24, 4); /* GPMC_CONFIG6_0 */
4629 cpu_physical_memory_write(0x6e000078, chtoc + 0x28, 4); /* GPMC_CONFIG7_0 */
4630 cpu_physical_memory_write(0x6e0001e0, chtoc + 0x2c, 4); /* GPMC_PREFETCH_CONFIG1 */
4631 omap3_boot_setlsb(0x6e0001e4, omap3_get_le16(chtoc + 0x30)); /* GPMC_PREFETCH_CONFIG2 */
4632 omap3_boot_setlsb(0x6e0001ec, omap3_get_le16(chtoc + 0x32)); /* GPMC_PREFETCH_CONTROL */
4633 /* TODO: ECC config registers. The TRM spec is not clear on these */
4636 static void omap3_boot_chmmcsd(const uint8_t *chtoc)
4638 if (omap3_get_le32(chtoc) != 0xc0c0c0c4) {
4639 fprintf(stderr, "%s: invalid section verification key\n", __FUNCTION__);
4642 if (!chtoc[4]) { /* section disabled? */
4645 /* TODO: MMCHS registers */
4648 /* returns non-zero if more blocks are needed */
4649 static uint32_t omap3_boot_block(const uint8_t *data,
4651 struct omap3_boot_s *s)
4653 const uint8_t *p = 0;
4659 for (p = data; i >= 32 && omap3_get_le32(p) != 0xffffffff; p += 32, i -= 32) {
4660 if (!strcasecmp((char *)(p + 0x14), "chsettings"))
4661 omap3_boot_chsettings(p + omap3_get_le32(p));
4662 else if (!strcasecmp((char *)(p + 0x14), "chram"))
4663 omap3_boot_chram(p + omap3_get_le32(p));
4664 else if (!strcasecmp((char *)(p + 0x14), "chflash"))
4665 omap3_boot_chflash(p + omap3_get_le32(p));
4666 else if (!strcasecmp((char *)(p + 0x14), "chmmcsd"))
4667 omap3_boot_chmmcsd(p + omap3_get_le32(p));
4669 fprintf(stderr, "%s: unknown CHTOC item \"%s\"\n",
4670 __FUNCTION__, (char *)(p + 0x14));
4677 s->state = imagehdr;
4682 s->count = omap3_get_le32(data);
4683 s->addr = omap3_get_le32(data + 4);
4684 s->mpu->env->regs[15] = s->addr;
4690 i = (s->count >= data_len) ? data_len : s->count;
4691 cpu_physical_memory_write(s->addr, data, i);
4703 /* returns ptr to matching dir entry / zero entry or 0 if unsuccessful */
4704 static const uint8_t *omap3_scan_fat_dir_sector(const uint8_t *s)
4708 /* there are 0x10 items with 0x20 bytes per item */
4709 for (i = 0x10; i--; s += 0x20) {
4710 if (*s == 0xe5 || (s[0x0b] & 0x0f) == 0x0f) continue; /* erased/LFN */
4711 if (!*s || !strncasecmp((void *)s, "mlo ", 8+3)) return s;
4716 struct omap3_fat_drv_s {
4717 BlockDriverState *bs;
4718 uint8_t ptype; /* 12, 16, 32 */
4719 uint64_t c0; /* physical byte offset for data cluster 0 */
4720 uint64_t fat; /* physical byte offset for used FAT sector 0 */
4721 uint32_t spc; /* sectors per cluster */
4724 /* returns cluster data in the buffer and next cluster chain number
4725 or 0 if unsuccessful */
4726 static uint32_t omap3_read_fat_cluster(uint8_t *data,
4727 struct omap3_fat_drv_s *drv,
4731 uint32_t len = drv->spc * 0x200; /* number of bytes to read */
4733 switch (drv->ptype) { /* check for EOF */
4734 case 12: if (cl > 0xff0) return 0; break;
4735 case 16: if (cl > 0xfff0) return 0; break;
4736 case 32: if (cl > 0x0ffffff0) return 0; break;
4740 if (bdrv_pread(drv->bs,
4741 drv->c0 + ((drv->ptype == 32 ? cl - 2 : cl) * len),
4745 switch (drv->ptype) { /* determine next cluster # */
4747 fprintf(stderr, "%s: FAT12 parsing not implemented!\n",
4751 return (bdrv_pread(drv->bs, drv->fat + cl * 2, buf, 2) != 2)
4752 ? 0 : omap3_get_le16(buf);
4754 return (bdrv_pread(drv->bs, drv->fat + cl * 4, buf, 4) != 4)
4755 ? 0 : omap3_get_le32(buf) & 0x0fffffff;
4762 static int omap3_mmc_fat_boot(BlockDriverState *bs,
4765 struct omap_mpu_state_s *mpu)
4767 struct omap3_fat_drv_s drv;
4768 struct omap3_boot_s *boot;
4769 uint32_t i, j, cluster0, fatsize, bootsize, rootsize;
4770 const uint8_t *p, *q;
4774 /* determine FAT type */
4777 fatsize = omap3_get_le16(sector + 0x16);
4779 fatsize = omap3_get_le32(sector + 0x24);
4780 bootsize = omap3_get_le16(sector + 0x0e);
4781 cluster0 = bootsize + fatsize * sector[0x10];
4782 rootsize = omap3_get_le16(sector + 0x11);
4783 if (rootsize & 0x0f)
4786 drv.spc = sector[0x0d];
4787 i = omap3_get_le16(sector + 0x13);
4789 i = omap3_get_le32(sector + 0x20);
4790 i = (i - (cluster0 + rootsize)) / drv.spc;
4791 drv.ptype = (i < 4085) ? 12 : (i < 65525) ? 16 : 32;
4793 /* search for boot loader file */
4795 drv.fat = (bootsize + pstart) * 0x200;
4796 drv.c0 = (cluster0 + pstart) * 0x200;
4797 if (drv.ptype == 32) {
4798 i = omap3_get_le32(sector + 0x2c); /* first root cluster # */
4799 j = omap3_get_le16(sector + 0x28);
4801 drv.fat += (j & 0x0f) * fatsize * 0x200;
4802 cluster = qemu_mallocz(drv.spc * 0x200);
4803 for (p = 0; !p && (i = omap3_read_fat_cluster(cluster, &drv, i)); ) {
4804 for (j = drv.spc, q=cluster; j-- & !p; q += 0x200)
4805 p = omap3_scan_fat_dir_sector(q);
4807 memcpy(sector, q - 0x200, 0x200); /* save the sector */
4810 } else { /* FAT12/16 */
4811 for (i = rootsize, j = 0, p = 0; i-- && !p; j++) {
4812 if (bdrv_pread(drv.bs, drv.c0 + j * 0x200, sector, 0x200) != 0x200)
4814 p = omap3_scan_fat_dir_sector(sector);
4818 if (p && *p) { /* did we indeed find the file? */
4819 i = omap3_get_le16(p + 0x14);
4821 i |= omap3_get_le16(p + 0x1a);
4822 j = drv.spc * 0x200;
4823 uint8 *data = qemu_mallocz(j);
4824 if ((i = omap3_read_fat_cluster(data, &drv, i))) {
4825 boot = omap3_boot_init(data, j, mpu);
4826 boot->state = imagehdr; /* override CH detection */
4827 while (omap3_boot_block(data, j, boot))
4828 i = omap3_read_fat_cluster(data, &drv, i);
4832 fprintf(stderr, "%s: unable to read MLO file contents from SD card\n",
4836 fprintf(stderr, "%s: MLO file not found in the root directory\n",
4842 static int omap3_mmc_raw_boot(BlockDriverState *bs,
4844 struct omap_mpu_state_s *mpu)
4846 struct omap3_boot_s *boot;
4849 if (bdrv_pread(bs, 0, sector, 0x200) == 0x200) {
4850 boot = omap3_boot_init(sector, 0x200, mpu);
4851 if (boot->state == confighdr) { /* CH must be present for raw boot */
4852 while (omap3_boot_block(sector, 0x200, boot)) {
4853 if (bdrv_pread(bs, ++i, sector, 0x200) != 0x200) {
4854 fprintf(stderr, "%s: error trying to read sector %u on boot device\n",
4865 /* returns non-zero if successful, zero if unsuccessful */
4866 int omap3_mmc_boot(struct omap_mpu_state_s *s)
4868 BlockDriverState *bs;
4869 int sdindex = drive_get_index(IF_SD, 0, 0);
4870 uint8_t *sector, *p;
4874 /* very simple implementation for GP device boot,
4875 supports only two modes:
4876 1. MBR partition table with an active FAT partition
4877 and boot loader file (MLO) in its root directory, or
4878 2. CH sector located on first sector, followed by boot loader image */
4880 bs = drives_table[sdindex].bdrv;
4881 sector = qemu_mallocz(0x200);
4882 if (bdrv_pread(bs, 0, sector, 0x200) == 0x200) {
4883 for (i = 0, p = sector + 0x1be; i < 4; i++, p += 0x10)
4884 if (p[0] == 0x80) break;
4885 if (sector[0x1fe] == 0x55 && sector[0x1ff] == 0xaa /* signature */
4886 && i < 4 /* active partition exists */
4887 && (p[4] == 1 || p[4] == 4 || p[4] == 6 || p[4] == 11
4888 || p[4] == 12 || p[4] == 14 || p[4] == 15) /* FAT */
4889 && bdrv_pread(bs, (pstart = omap3_get_le32(p + 8)) * 0x200,
4890 sector, 0x200) == 0x200
4891 && sector[0x1fe] == 0x55 && sector[0x1ff] == 0xaa)
4892 result = omap3_mmc_fat_boot(bs, sector, pstart, s);
4894 result = omap3_mmc_raw_boot(bs, sector, s);