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},
1125 } omap3_l4_agent_info_id_t;
1127 struct omap3_l4_agent_info_s {
1128 omap3_l4_agent_info_id_t agent_id;
1129 omap3_l4_region_id_t first_region_id;
1133 static const struct omap3_l4_agent_info_s omap3_l4_agent_info[] = {
1134 /* L4-Core Agents */
1135 {L4A_DSS, L4ID_DSI, 6},
1137 {L4A_USBHS_OTG, L4ID_HSUSBOTG, 2},
1138 {L4A_USBHS_HOST, L4ID_HSUSBHOST, 2},
1139 {L4A_USBHS_TLL, L4ID_USBTLL, 2},
1140 {L4A_UART1, L4ID_UART1, 2},
1141 {L4A_UART2, L4ID_UART2, 2},
1142 {L4A_I2C1, L4ID_I2C1, 2},
1143 {L4A_I2C2, L4ID_I2C2, 2},
1144 {L4A_I2C3, L4ID_I2C3, 2},
1147 {L4A_GPTIMER10, L4ID_GPTIMER10, 2},
1148 {L4A_GPTIMER11, L4ID_GPTIMER11, 2},
1151 {L4A_MMC1, L4ID_MMCSDIO1, 2},
1152 {L4A_MMC2, L4ID_MMCSDIO2, 2},
1153 {L4A_MMC3, L4ID_MMCSDIO3, 2},
1154 /* TODO: HDQ/1-Wire */
1159 {L4A_CM, L4ID_CM_A, 3},
1160 {L4A_SCM, L4ID_SCM, 2},
1161 {L4A_TAP, L4ID_TAP, 2},
1162 /* L4-Wakeup Agents */
1163 {L4A_GPTIMER12, L4ID_GPTIMER12, 2},
1164 {L4A_PRM, L4ID_PRM_A, 3},
1165 {L4A_GPIO1, L4ID_GPIO1, 2},
1166 {L4A_WDTIMER2, L4ID_WDTIMER2, 2},
1167 {L4A_GPTIMER1, L4ID_GPTIMER1, 2},
1168 {L4A_32KTIMER, L4ID_32KTIMER, 2},
1170 {L4A_UART3, L4ID_UART3, 2},
1173 {L4A_GPTIMER2, L4ID_GPTIMER2, 2},
1174 {L4A_GPTIMER3, L4ID_GPTIMER3, 2},
1175 {L4A_GPTIMER4, L4ID_GPTIMER4, 2},
1176 {L4A_GPTIMER5, L4ID_GPTIMER5, 2},
1177 {L4A_GPTIMER6, L4ID_GPTIMER6, 2},
1178 {L4A_GPTIMER7, L4ID_GPTIMER7, 2},
1179 {L4A_GPTIMER8, L4ID_GPTIMER8, 2},
1180 {L4A_GPTIMER9, L4ID_GPTIMER9, 2},
1181 {L4A_GPIO2, L4ID_GPIO2, 2},
1182 {L4A_GPIO3, L4ID_GPIO3, 2},
1183 {L4A_GPIO4, L4ID_GPIO4, 2},
1184 {L4A_GPIO5, L4ID_GPIO5, 2},
1185 {L4A_GPIO6, L4ID_GPIO6, 2},
1188 static uint32_t omap3_l4ta_read(void *opaque, target_phys_addr_t addr)
1190 struct omap_target_agent_s *s = (struct omap_target_agent_s *)opaque;
1193 case 0x00: /* COMPONENT_L */
1194 return s->component;
1195 case 0x04: /* COMPONENT_H */
1197 case 0x18: /* CORE_L */
1198 return s->component;
1199 case 0x1c: /* CORE_H */
1200 return (s->component >> 16);
1201 case 0x20: /* AGENT_CONTROL_L */
1203 case 0x24: /* AGENT_CONTROL_H */
1204 return s->control_h;
1205 case 0x28: /* AGENT_STATUS_L */
1207 case 0x2c: /* AGENT_STATUS_H */
1213 OMAP_BAD_REG(s->base + addr);
1217 static void omap3_l4ta_write(void *opaque, target_phys_addr_t addr,
1220 struct omap_target_agent_s *s = (struct omap_target_agent_s *)opaque;
1223 case 0x00: /* COMPONENT_L */
1224 case 0x04: /* COMPONENT_H */
1225 case 0x18: /* CORE_L */
1226 case 0x1c: /* CORE_H */
1227 OMAP_RO_REG(s->base + addr);
1229 case 0x20: /* AGENT_CONTROL_L */
1230 s->control = value & 0x00000701;
1232 case 0x24: /* AGENT_CONTROL_H */
1233 s->control_h = value & 0x100; /* TODO: shouldn't this be read-only? */
1235 case 0x28: /* AGENT_STATUS_L */
1237 s->status &= ~0x100; /* REQ_TIMEOUT */
1239 case 0x2c: /* AGENT_STATUS_H */
1240 /* no writable bits although the register is listed as RW */
1243 OMAP_BAD_REG(s->base + addr);
1248 static CPUReadMemoryFunc *omap3_l4ta_readfn[] = {
1249 omap_badwidth_read32,
1250 omap_badwidth_read32,
1254 static CPUWriteMemoryFunc *omap3_l4ta_writefn[] = {
1255 omap_badwidth_write32,
1256 omap_badwidth_write32,
1260 static struct omap_target_agent_s *omap3_l4ta_init(struct omap_l4_s *bus, int cs)
1263 struct omap_target_agent_s *ta = 0;
1264 const struct omap3_l4_agent_info_s *info = 0;
1266 for (i = 0; i < bus->ta_num; i++)
1267 if (omap3_l4_agent_info[i].agent_id == cs) {
1269 info = &omap3_l4_agent_info[i];
1273 fprintf(stderr, "%s: invalid agent id (%i)\n", __FUNCTION__, cs);
1277 fprintf(stderr, "%s: target agent (%d) already initialized\n",
1283 ta->start = &omap3_l4_region[info->first_region_id];
1284 ta->regions = info->region_count;
1286 ta->component = ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
1287 ta->status = 0x00000000;
1288 ta->control = 0x00000200;
1290 for (i = 0; i < info->region_count; i++)
1291 if (omap3_l4_region[info->first_region_id + i].access == L4TYPE_TA)
1293 if (i >= info->region_count) {
1294 fprintf(stderr, "%s: specified agent (%d) has no TA region\n",
1299 iomemtype = l4_register_io_memory(0, omap3_l4ta_readfn,
1300 omap3_l4ta_writefn, ta);
1301 ta->base = omap_l4_attach(ta, i, iomemtype);
1306 /* common PRM domain registers */
1307 struct omap3_prm_domain_s {
1308 uint32_t rm_rstctrl; /* 50 */
1309 uint32_t rm_rstst; /* 58 */
1310 uint32_t pm_wken; /* a0 */
1311 uint32_t pm_mpugrpsel; /* a4 */
1312 uint32_t pm_ivagrpsel; /* a8 */
1313 uint32_t pm_wkst; /* b0 */
1314 uint32_t pm_wkdep; /* c8 */
1315 uint32_t pm_pwstctrl; /* e0 */
1316 uint32_t pm_pwstst; /* e4 */
1317 uint32_t pm_prepwstst; /* e8 */
1320 struct omap3_prm_s {
1323 struct omap_mpu_state_s *omap;
1325 struct omap3_prm_domain_s iva2;
1326 struct omap3_prm_domain_s mpu;
1327 struct omap3_prm_domain_s core;
1328 struct omap3_prm_domain_s sgx;
1329 struct omap3_prm_domain_s wkup;
1330 struct omap3_prm_domain_s dss;
1331 struct omap3_prm_domain_s cam;
1332 struct omap3_prm_domain_s per;
1333 struct omap3_prm_domain_s emu;
1334 struct omap3_prm_domain_s neon;
1335 struct omap3_prm_domain_s usbhost;
1337 uint32_t iva2_prm_irqstatus;
1338 uint32_t iva2_prm_irqenable;
1340 uint32_t mpu_pm_evgenctrl;
1341 uint32_t mpu_pm_evgenontim;
1342 uint32_t mpu_pm_evgenofftim;
1344 uint32_t core_pm_wkst3;
1345 uint32_t core_pm_wken3;
1346 uint32_t core_pm_iva2grpsel3;
1347 uint32_t core_pm_mpugrpsel3;
1349 uint32_t prm_revision;
1350 uint32_t prm_sysconfig;
1351 uint32_t prm_irqstatus_mpu;
1352 uint32_t prm_irqenable_mpu;
1354 uint32_t prm_clksel;
1355 uint32_t prm_clkout_ctrl;
1357 uint32_t prm_vc_smps_sa;
1358 uint32_t prm_vc_smps_vol_ra;
1359 uint32_t prm_vc_smps_cmd_ra;
1360 uint32_t prm_vc_cmd_val_0;
1361 uint32_t prm_vc_cmd_val_1;
1362 uint32_t prm_vc_hc_conf;
1363 uint32_t prm_vc_i2c_cfg;
1364 uint32_t prm_vc_bypass_val;
1365 uint32_t prm_rstctrl;
1366 uint32_t prm_rsttimer;
1368 uint32_t prm_voltctrl;
1369 uint32_t prm_sram_pcharge;
1370 uint32_t prm_clksrc_ctrl;
1372 uint32_t prm_voltsetup1;
1373 uint32_t prm_voltoffset;
1374 uint32_t prm_clksetup;
1375 uint32_t prm_polctrl;
1376 uint32_t prm_voltsetup2;
1379 static void omap3_prm_int_update(struct omap3_prm_s *s)
1381 qemu_set_irq(s->mpu_irq, s->prm_irqstatus_mpu & s->prm_irqenable_mpu);
1382 qemu_set_irq(s->iva_irq, s->iva2_prm_irqstatus & s->iva2_prm_irqenable);
1385 static void omap3_prm_reset(struct omap3_prm_s *s)
1387 s->iva2.rm_rstctrl = 0x7;
1388 s->iva2.rm_rstst = 0x1;
1389 s->iva2.pm_wkdep = 0xb3;
1390 s->iva2.pm_pwstctrl = 0xff0f07;
1391 s->iva2.pm_pwstst = 0xff7;
1392 s->iva2.pm_prepwstst = 0x0;
1393 s->iva2_prm_irqstatus = 0x0;
1394 s->iva2_prm_irqenable = 0x0;
1396 s->prm_revision = 0x10;
1397 s->prm_sysconfig = 0x1;
1398 s->prm_irqstatus_mpu = 0x0;
1399 s->prm_irqenable_mpu = 0x0;
1401 s->mpu.rm_rstst = 0x1;
1402 s->mpu.pm_wkdep = 0xa5;
1403 s->mpu.pm_pwstctrl = 0x30107;
1404 s->mpu.pm_pwstst = 0xc7;
1405 s->mpu.pm_pwstst = 0x0;
1406 s->mpu_pm_evgenctrl = 0x12;
1407 s->mpu_pm_evgenontim = 0x0;
1408 s->mpu_pm_evgenofftim = 0x0;
1410 s->core.rm_rstst = 0x1;
1411 s->core.pm_wken = 0xc33ffe18;
1412 s->core.pm_mpugrpsel = 0xc33ffe18;
1413 s->core.pm_ivagrpsel = 0xc33ffe18;
1414 s->core.pm_wkst = 0x0;
1415 s->core.pm_pwstctrl = 0xf0307;
1416 s->core.pm_pwstst = 0xf7;
1417 s->core.pm_prepwstst = 0x0;
1418 s->core_pm_wkst3 = 0x0;
1419 s->core_pm_wken3 = 0x4;
1420 s->core_pm_iva2grpsel3 = 0x4;
1421 s->core_pm_mpugrpsel3 = 0x4;
1423 s->sgx.rm_rstst = 0x1;
1424 s->sgx.pm_wkdep = 0x16;
1425 s->sgx.pm_pwstctrl = 0x30107;
1426 s->sgx.pm_pwstst = 0x3;
1427 s->sgx.pm_prepwstst = 0x0;
1429 s->wkup.pm_wken = 0x3cb;
1430 s->wkup.pm_mpugrpsel = 0x3cb;
1431 s->wkup.pm_ivagrpsel = 0x0;
1432 s->wkup.pm_wkst = 0x0;
1433 s->wkup.pm_pwstst = 0x3; /* TODO: check on real hardware */
1435 s->prm_clksel = 0x4;
1436 s->prm_clkout_ctrl = 0x80;
1438 s->dss.rm_rstst = 0x1;
1439 s->dss.pm_wken = 0x1;
1440 s->dss.pm_wkdep = 0x16;
1441 s->dss.pm_pwstctrl = 0x30107;
1442 s->dss.pm_pwstst = 0x3;
1443 s->dss.pm_prepwstst = 0x0;
1445 s->cam.rm_rstst = 0x1;
1446 s->cam.pm_wkdep = 0x16;
1447 s->cam.pm_pwstctrl = 0x30107;
1448 s->cam.pm_pwstst = 0x3;
1449 s->cam.pm_prepwstst = 0x0;
1451 s->per.rm_rstst = 0x1;
1452 s->per.pm_wken = 0x3efff;
1453 s->per.pm_mpugrpsel = 0x3efff;
1454 s->per.pm_ivagrpsel = 0x3efff;
1455 s->per.pm_wkst = 0x0;
1456 s->per.pm_wkdep = 0x17;
1457 s->per.pm_pwstctrl = 0x30107;
1458 s->per.pm_pwstst = 0x7;
1459 s->per.pm_prepwstst = 0x0;
1461 s->emu.rm_rstst = 0x1;
1462 s->emu.pm_pwstst = 0x13;
1464 s->prm_vc_smps_sa = 0x0;
1465 s->prm_vc_smps_vol_ra = 0x0;
1466 s->prm_vc_smps_cmd_ra = 0x0;
1467 s->prm_vc_cmd_val_0 = 0x0;
1468 s->prm_vc_cmd_val_1 = 0x0;
1469 s->prm_vc_hc_conf = 0x0;
1470 s->prm_vc_i2c_cfg = 0x18;
1471 s->prm_vc_bypass_val = 0x0;
1472 s->prm_rstctrl = 0x0;
1473 s->prm_rsttimer = 0x1006;
1475 s->prm_voltctrl = 0x0;
1476 s->prm_sram_pcharge = 0x50;
1477 s->prm_clksrc_ctrl = 0x43;
1479 s->prm_voltsetup1 = 0x0;
1480 s->prm_voltoffset = 0x0;
1481 s->prm_clksetup = 0x0;
1482 s->prm_polctrl = 0xa;
1483 s->prm_voltsetup2 = 0x0;
1485 s->neon.rm_rstst = 0x1;
1486 s->neon.pm_wkdep = 0x2;
1487 s->neon.pm_pwstctrl = 0x7;
1488 s->neon.pm_pwstst = 0x3;
1489 s->neon.pm_prepwstst = 0x0;
1491 s->usbhost.rm_rstst = 0x1;
1492 s->usbhost.pm_wken = 0x1;
1493 s->usbhost.pm_mpugrpsel = 0x1;
1494 s->usbhost.pm_ivagrpsel = 0x1;
1495 s->usbhost.pm_wkst = 0x0;
1496 s->usbhost.pm_wkdep = 0x17;
1497 s->usbhost.pm_pwstctrl = 0x30107;
1498 s->usbhost.pm_pwstst = 0x3;
1499 s->usbhost.pm_prepwstst = 0x0;
1501 omap3_prm_int_update(s);
1504 static uint32_t omap3_prm_read(void *opaque, target_phys_addr_t addr)
1506 struct omap3_prm_s *s = (struct omap3_prm_s *)opaque;
1507 struct omap3_prm_domain_s *d = 0;
1509 TRACE("%04x", addr);
1511 /* handle common domain registers first - all domains may not
1512 have all common registers though but we're returning zeroes there */
1513 switch ((addr >> 8) & 0xff) {
1514 case 0x00: d = &s->iva2; break;
1515 case 0x09: d = &s->mpu; break;
1516 case 0x0a: d = &s->core; break;
1517 case 0x0b: d = &s->sgx; break;
1518 case 0x0c: d = &s->wkup; break;
1519 case 0x0e: d = &s->dss; break;
1520 case 0x0f: d = &s->cam; break;
1521 case 0x10: d = &s->per; break;
1522 case 0x11: d = &s->emu; break;
1523 case 0x13: d = &s->neon; break;
1524 case 0x14: d = &s->usbhost; break;
1528 switch (addr & 0xff) {
1529 case 0x50: return d->rm_rstctrl;
1530 case 0x58: return d->rm_rstst;
1531 case 0xa0: return d->pm_wken;
1532 case 0xa4: return d->pm_mpugrpsel;
1533 case 0xa8: return d->pm_ivagrpsel;
1534 case 0xb0: return d->pm_wkst;
1535 case 0xc8: return d->pm_wkdep;
1536 case 0xe0: return d->pm_pwstctrl;
1537 case 0xe4: return d->pm_pwstst;
1538 case 0xe8: return d->pm_prepwstst;
1542 /* okay, not a common domain register so let's take a closer look */
1544 case 0x00f8: return s->iva2_prm_irqstatus;
1545 case 0x00fc: return s->iva2_prm_irqenable;
1546 case 0x0804: return s->prm_revision;
1547 case 0x0814: return s->prm_sysconfig;
1548 case 0x0818: return s->prm_irqstatus_mpu;
1549 case 0x081c: return s->prm_irqenable_mpu;
1550 case 0x09d4: return s->mpu_pm_evgenctrl;
1551 case 0x09d8: return s->mpu_pm_evgenontim;
1552 case 0x09dc: return s->mpu_pm_evgenofftim;
1553 case 0x0ab8: return s->core_pm_wkst3;
1554 case 0x0af0: return s->core_pm_wken3;
1555 case 0x0af4: return s->core_pm_iva2grpsel3;
1556 case 0x0af8: return s->core_pm_mpugrpsel3;
1557 case 0x0d40: return s->prm_clksel;
1558 case 0x0d70: return s->prm_clkout_ctrl;
1559 case 0x0de4: return 0x3; /* TODO: check on real hardware */
1560 case 0x1220: return s->prm_vc_smps_sa;
1561 case 0x1224: return s->prm_vc_smps_vol_ra;
1562 case 0x1228: return s->prm_vc_smps_cmd_ra;
1563 case 0x122c: return s->prm_vc_cmd_val_0;
1564 case 0x1230: return s->prm_vc_cmd_val_1;
1565 case 0x1234: return s->prm_vc_hc_conf;
1566 case 0x1238: return s->prm_vc_i2c_cfg;
1567 case 0x123c: return s->prm_vc_bypass_val;
1568 case 0x1250: return s->prm_rstctrl;
1569 case 0x1254: return s->prm_rsttimer;
1570 case 0x1258: return s->prm_rstst;
1571 case 0x1260: return s->prm_voltctrl;
1572 case 0x1264: return s->prm_sram_pcharge;
1573 case 0x1270: return s->prm_clksrc_ctrl;
1574 case 0x1280: return s->prm_obs;
1575 case 0x1290: return s->prm_voltsetup1;
1576 case 0x1294: return s->prm_voltoffset;
1577 case 0x1298: return s->prm_clksetup;
1578 case 0x129c: return s->prm_polctrl;
1579 case 0x12a0: return s->prm_voltsetup2;
1587 static inline void omap3_prm_clksrc_ctrl_update(struct omap3_prm_s *s,
1590 if ((value & 0xd0) == 0x40)
1591 omap_clk_setrate(omap_findclk(s->omap, "omap3_sys_clk"), 1, 1);
1592 else if ((value & 0xd0) == 0x80)
1593 omap_clk_setrate(omap_findclk(s->omap, "omap3_sys_clk"), 2, 1);
1596 static void omap3_prm_write(void *opaque, target_phys_addr_t addr,
1599 struct omap3_prm_s *s = (struct omap3_prm_s *)opaque;
1601 TRACE("%04x = %08x", addr, value);
1604 case 0x0050: s->iva2.rm_rstctrl = value & 0x7; break;
1605 case 0x0058: s->iva2.rm_rstst &= ~(value & 0x3f0f); break;
1606 case 0x00c8: s->iva2.pm_wkdep = value & 0xb3; break;
1607 case 0x00e0: s->iva2.pm_pwstctrl = 0xcff000 | (value & 0x300f0f); break;
1608 case 0x00e4: OMAP_RO_REG(addr); break;
1609 case 0x00e8: s->iva2.pm_prepwstst = value & 0xff7;
1611 s->iva2_prm_irqstatus &= ~(value & 0x7);
1612 omap3_prm_int_update(s);
1615 s->iva2_prm_irqenable = value & 0x7;
1616 omap3_prm_int_update(s);
1618 /* OCP_System_Reg_PRM */
1619 case 0x0804: OMAP_RO_REG(addr); break;
1620 case 0x0814: s->prm_sysconfig = value & 0x1; break;
1622 s->prm_irqstatus_mpu &= ~(value & 0x03c003fd);
1623 omap3_prm_int_update(s);
1626 s->prm_irqenable_mpu = value & 0x03c003fd;
1627 omap3_prm_int_update(s);
1630 case 0x0958: s->mpu.rm_rstst &= ~(value & 0x080f); break;
1631 case 0x09c8: s->mpu.pm_wkdep = value & 0xa5; break;
1632 case 0x09d4: s->mpu_pm_evgenctrl = value & 0x1f; break;
1633 case 0x09d8: s->mpu_pm_evgenontim = value; break;
1634 case 0x09dc: s->mpu_pm_evgenofftim = value; break;
1635 case 0x09e0: s->mpu.pm_pwstctrl = value & 0x3010f; break;
1636 case 0x09e4: OMAP_RO_REG(addr); break;
1637 case 0x09e8: s->mpu.pm_prepwstst = value & 0xc7; break;
1639 case 0x0a50: s->core.rm_rstctrl = value & 0x3; break; /* TODO: check if available on real hw */
1640 case 0x0a58: s->core.rm_rstst &= ~(value & 0x7); break;
1641 case 0x0aa0: s->core.pm_wken = 0x80000008 | (value & 0x433ffe10); break;
1642 case 0x0aa4: s->core.pm_mpugrpsel = 0x80000008 | (value & 0x433ffe10); break;
1643 case 0x0aa8: s->core.pm_ivagrpsel = 0x80000008 | (value & 0x433ffe10); break;
1644 case 0x0ab0: s->core.pm_wkst = value & 0x433ffe10; break;
1645 case 0x0ab8: s->core_pm_wkst3 &= ~(value & 0x4); break;
1646 case 0x0ae0: s->core.pm_pwstctrl = (value & 0x0f031f); break;
1647 case 0x0ae4: OMAP_RO_REG(addr); break;
1648 case 0x0ae8: s->core.pm_prepwstst = value & 0xf7; break;
1649 case 0x0af0: s->core_pm_wken3 = value & 0x4; break;
1650 case 0x0af4: s->core_pm_iva2grpsel3 = value & 0x4; break;
1651 case 0x0af8: s->core_pm_mpugrpsel3 = value & 0x4; break;
1653 case 0x0b58: s->sgx.rm_rstst &= ~(value & 0xf); break;
1654 case 0x0bc8: s->sgx.pm_wkdep = value & 0x16; break;
1655 case 0x0be0: s->sgx.pm_pwstctrl = 0x030104 | (value & 0x3); break;
1656 case 0x0be4: OMAP_RO_REG(addr); break;
1657 case 0x0be8: s->sgx.pm_prepwstst = value & 0x3; break;
1659 case 0x0ca0: s->wkup.pm_wken = 0x2 | (value & 0x0103c9); break;
1660 case 0x0ca4: s->wkup.pm_mpugrpsel = 0x0102 | (value & 0x02c9); break;
1661 case 0x0ca8: s->wkup.pm_ivagrpsel = value & 0x03cb; break;
1662 case 0x0cb0: s->wkup.pm_wkst &= ~(value & 0x0103cb); break;
1663 /* Clock_Control_Reg_PRM */
1665 s->prm_clksel = value & 0x7;
1666 fprintf(stderr, "%s PRM_CLKSEL = 0x%x\n", __FUNCTION__,
1668 /* TODO: update clocks */
1671 s->prm_clkout_ctrl = value & 0x80;
1672 fprintf(stderr, "%s PRM_CLKOUT_CTRL = 0x%x\n", __FUNCTION__,
1673 s->prm_clkout_ctrl);
1674 /* TODO: update clocks */
1677 case 0x0e58: s->dss.rm_rstst &= ~(value & 0xf); break;
1678 case 0x0ea0: s->dss.pm_wken = value & 1; break;
1679 case 0x0ec8: s->dss.pm_wkdep = value & 0x16; break;
1680 case 0x0ee0: s->dss.pm_pwstctrl = 0x030104 | (value & 3); break;
1681 case 0x0ee4: OMAP_RO_REG(addr); break;
1682 case 0x0ee8: s->dss.pm_prepwstst = value & 3; break;
1684 case 0x0f58: s->cam.rm_rstst &= (value & 0xf); break;
1685 case 0x0fc8: s->cam.pm_wkdep = value & 0x16; break;
1686 case 0x0fe0: s->cam.pm_pwstctrl = 0x030104 | (value & 3); break;
1687 case 0x0fe4: OMAP_RO_REG(addr); break;
1688 case 0x0fe8: s->cam.pm_prepwstst = value & 0x3; break;
1690 case 0x1058: s->per.rm_rstst &= ~(value & 0xf); break;
1691 case 0x10a0: s->per.pm_wken = value & 0x03efff; break;
1692 case 0x10a4: s->per.pm_mpugrpsel = value & 0x03efff; break;
1693 case 0x10a8: s->per.pm_ivagrpsel = value & 0x03efff; break;
1694 case 0x10b0: s->per.pm_wkst &= ~(value & 0x03efff); break;
1695 case 0x10c8: s->per.pm_wkdep = value & 0x17; break;
1696 case 0x10e0: s->per.pm_pwstctrl = 0x030100 | (value & 7); break;
1697 case 0x10e4: OMAP_RO_REG(addr); break;
1698 case 0x10e8: s->per.pm_prepwstst = value & 0x7; break;
1700 case 0x1158: s->emu.rm_rstst &= ~(value & 7); break;
1701 case 0x11e4: OMAP_RO_REG(addr); break;
1702 /* Global_Reg_PRM */
1703 case 0x1220: s->prm_vc_smps_sa = value & 0x7f007f; break;
1704 case 0x1224: s->prm_vc_smps_vol_ra = value & 0xff00ff; break;
1705 case 0x1228: s->prm_vc_smps_cmd_ra = value & 0xff00ff; break;
1706 case 0x122c: s->prm_vc_cmd_val_0 = value; break;
1707 case 0x1230: s->prm_vc_cmd_val_1 = value; break;
1708 case 0x1234: s->prm_vc_hc_conf = value & 0x1f001f; break;
1709 case 0x1238: s->prm_vc_i2c_cfg = value & 0x3f; break;
1710 case 0x123c: s->prm_vc_bypass_val = value & 0x01ffff7f; break;
1711 case 0x1250: s->prm_rstctrl = 0; break; /* TODO: resets */
1712 case 0x1254: s->prm_rsttimer = value & 0x1fff; break;
1713 case 0x1258: s->prm_rstst &= ~(value & 0x7fb); break;
1714 case 0x1260: s->prm_voltctrl = value & 0x1f; break;
1715 case 0x1264: s->prm_sram_pcharge = value & 0xff; break;
1717 s->prm_clksrc_ctrl = value & (0xd8);
1718 omap3_prm_clksrc_ctrl_update(s, s->prm_clksrc_ctrl);
1719 /* TODO: update SYSCLKSEL bits */
1721 case 0x1280: OMAP_RO_REG(addr); break;
1722 case 0x1290: s->prm_voltsetup1 = value; break;
1723 case 0x1294: s->prm_voltoffset = value & 0xffff; break;
1724 case 0x1298: s->prm_clksetup = value & 0xffff; break;
1725 case 0x129c: s->prm_polctrl = value & 0xf; break;
1726 case 0x12a0: s->prm_voltsetup2 = value & 0xffff; break;
1728 case 0x1358: s->neon.rm_rstst &= ~(value & 0xf); break;
1729 case 0x13c8: s->neon.pm_wkdep = value & 0x2; break;
1730 case 0x13e0: s->neon.pm_pwstctrl = 0x4 | (value & 3); break;
1731 case 0x13e4: OMAP_RO_REG(addr); break;
1732 case 0x13e8: s->neon.pm_prepwstst = value & 3; break;
1734 case 0x1458: s->usbhost.rm_rstst &= ~(value & 0xf); break;
1735 case 0x14a0: s->usbhost.pm_wken = value & 1; break;
1736 case 0x14a4: s->usbhost.pm_mpugrpsel = value & 1; break;
1737 case 0x14a8: s->usbhost.pm_ivagrpsel = value & 1; break;
1738 case 0x14b0: s->usbhost.pm_wkst &= ~(value & 1); break;
1739 case 0x14c8: s->usbhost.pm_wkdep = value & 0x17; break;
1740 case 0x14e0: s->usbhost.pm_pwstctrl = 0x030104 | (value & 0x13); break;
1741 case 0x14e4: OMAP_RO_REG(addr); break;
1742 case 0x14e8: s->usbhost.pm_prepwstst = value & 3; break;
1744 OMAP_BAD_REGV(addr, value);
1749 static CPUReadMemoryFunc *omap3_prm_readfn[] = {
1750 omap_badwidth_read32,
1751 omap_badwidth_read32,
1755 static CPUWriteMemoryFunc *omap3_prm_writefn[] = {
1756 omap_badwidth_write32,
1757 omap_badwidth_write32,
1761 struct omap3_prm_s *omap3_prm_init(struct omap_target_agent_s *ta,
1762 qemu_irq mpu_int, qemu_irq iva_int,
1763 struct omap_mpu_state_s *mpu)
1766 struct omap3_prm_s *s = (struct omap3_prm_s *) qemu_mallocz(sizeof(*s));
1768 s->mpu_irq = mpu_int;
1769 s->iva_irq = iva_int;
1773 iomemtype = l4_register_io_memory(0, omap3_prm_readfn,
1774 omap3_prm_writefn, s);
1775 omap_l4_attach(ta, 0, iomemtype);
1776 omap_l4_attach(ta, 1, iomemtype);
1785 struct omap_mpu_state_s *mpu;
1787 /*IVA2_CM Register */
1788 uint32_t cm_fclken_iva2; /*0x4800 4000 */
1789 uint32_t cm_clken_pll_iva2; /*0x4800 4004 */
1790 uint32_t cm_idlest_iva2; /*0x4800 4020 */
1791 uint32_t cm_idlest_pll_iva2; /*0x4800 4024 */
1792 uint32_t cm_autoidle_pll_iva2; /*0x4800 4034 */
1793 uint32_t cm_clksel1_pll_iva2; /*0x4800 4040 */
1794 uint32_t cm_clksel2_pll_iva2; /*0x4800 4044 */
1795 uint32_t cm_clkstctrl_iva2; /*0x4800 4048 */
1796 uint32_t cm_clkstst_iva2; /*0x4800 404c */
1798 /*OCP_System_Reg_CM */
1799 uint32_t cm_revision; /*0x4800 4800 */
1800 uint32_t cm_sysconfig; /*0x4800 4810 */
1802 /*MPU_CM Register */
1803 uint32_t cm_clken_pll_mpu; /*0x4800 4904 */
1804 uint32_t cm_idlest_mpu; /*0x4800 4920 */
1805 uint32_t cm_idlest_pll_mpu; /*0x4800 4924 */
1806 uint32_t cm_autoidle_pll_mpu; /*0x4800 4934 */
1807 uint32_t cm_clksel1_pll_mpu; /*0x4800 4940 */
1808 uint32_t cm_clksel2_pll_mpu; /*0x4800 4944 */
1809 uint32_t cm_clkstctrl_mpu; /*0x4800 4948 */
1810 uint32_t cm_clkstst_mpu; /*0x4800 494c */
1812 /*CORE_CM Register */
1813 uint32_t cm_fclken1_core; /*0x4800 4a00 */
1814 uint32_t cm_fclken3_core; /*0x4800 4a08 */
1815 uint32_t cm_iclken1_core; /*0x4800 4a10 */
1816 uint32_t cm_iclken2_core; /*0x4800 4a14 */
1817 uint32_t cm_iclken3_core; /*0x4800 4a18 */
1818 uint32_t cm_idlest1_core; /*0x4800 4a20 */
1819 uint32_t cm_idlest2_core; /*0x4800 4a24 */
1820 uint32_t cm_idlest3_core; /*0x4800 4a28 */
1821 uint32_t cm_autoidle1_core; /*0x4800 4a30 */
1822 uint32_t cm_autoidle2_core; /*0x4800 4a34 */
1823 uint32_t cm_autoidle3_core; /*0x4800 4a38 */
1824 uint32_t cm_clksel_core; /*0x4800 4a40 */
1825 uint32_t cm_clkstctrl_core; /*0x4800 4a48 */
1826 uint32_t cm_clkstst_core; /*0x4800 4a4c */
1828 /*SGX_CM Register */
1829 uint32_t cm_fclken_sgx; /*0x4800 4b00 */
1830 uint32_t cm_iclken_sgx; /*0x4800 4b10 */
1831 uint32_t cm_idlest_sgx; /*0x4800 4b20 */
1832 uint32_t cm_clksel_sgx; /*0x4800 4b40 */
1833 uint32_t cm_sleepdep_sgx; /*0x4800 4b44 */
1834 uint32_t cm_clkstctrl_sgx; /*0x4800 4b48 */
1835 uint32_t cm_clkstst_sgx; /*0x4800 4b4c */
1837 /*WKUP_CM Register */
1838 uint32_t cm_fclken_wkup; /*0x4800 4c00 */
1839 uint32_t cm_iclken_wkup; /*0x4800 4c10 */
1840 uint32_t cm_idlest_wkup; /*0x4800 4c20 */
1841 uint32_t cm_autoidle_wkup; /*0x4800 4c30 */
1842 uint32_t cm_clksel_wkup; /*0x4800 4c40 */
1843 uint32_t cm_c48; /*0x4800 4c48 */
1845 /*Clock_Control_Reg_CM Register */
1846 uint32_t cm_clken_pll; /*0x4800 4d00 */
1847 uint32_t cm_clken2_pll; /*0x4800 4d04 */
1848 uint32_t cm_idlest_ckgen; /*0x4800 4d20 */
1849 uint32_t cm_idlest2_ckgen; /*0x4800 4d24 */
1850 uint32_t cm_autoidle_pll; /*0x4800 4d30 */
1851 uint32_t cm_autoidle2_pll; /*0x4800 4d34 */
1852 uint32_t cm_clksel1_pll; /*0x4800 4d40 */
1853 uint32_t cm_clksel2_pll; /*0x4800 4d44 */
1854 uint32_t cm_clksel3_pll; /*0x4800 4d48 */
1855 uint32_t cm_clksel4_pll; /*0x4800 4d4c */
1856 uint32_t cm_clksel5_pll; /*0x4800 4d50 */
1857 uint32_t cm_clkout_ctrl; /*0x4800 4d70 */
1859 /*DSS_CM Register */
1860 uint32_t cm_fclken_dss; /*0x4800 4e00 */
1861 uint32_t cm_iclken_dss; /*0x4800 4e10 */
1862 uint32_t cm_idlest_dss; /*0x4800 4e20 */
1863 uint32_t cm_autoidle_dss; /*0x4800 4e30 */
1864 uint32_t cm_clksel_dss; /*0x4800 4e40 */
1865 uint32_t cm_sleepdep_dss; /*0x4800 4e44 */
1866 uint32_t cm_clkstctrl_dss; /*0x4800 4e48 */
1867 uint32_t cm_clkstst_dss; /*0x4800 4e4c */
1870 /*CAM_CM Register */
1871 uint32_t cm_fclken_cam; /*0x4800 4f00 */
1872 uint32_t cm_iclken_cam; /*0x4800 4f10 */
1873 uint32_t cm_idlest_cam; /*0x4800 4f20 */
1874 uint32_t cm_autoidle_cam; /*0x4800 4f30 */
1875 uint32_t cm_clksel_cam; /*0x4800 4f40 */
1876 uint32_t cm_sleepdep_cam; /*0x4800 4f44 */
1877 uint32_t cm_clkstctrl_cam; /*0x4800 4f48 */
1878 uint32_t cm_clkstst_cam; /*0x4800 4f4c */
1880 /*PER_CM Register */
1881 uint32_t cm_fclken_per; /*0x4800 5000 */
1882 uint32_t cm_iclken_per; /*0x4800 5010 */
1883 uint32_t cm_idlest_per; /*0x4800 5020 */
1884 uint32_t cm_autoidle_per; /*0x4800 5030 */
1885 uint32_t cm_clksel_per; /*0x4800 5040 */
1886 uint32_t cm_sleepdep_per; /*0x4800 5044 */
1887 uint32_t cm_clkstctrl_per; /*0x4800 5048 */
1888 uint32_t cm_clkstst_per; /*0x4800 504c */
1890 /*EMU_CM Register */
1891 uint32_t cm_clksel1_emu; /*0x4800 5140 */
1892 uint32_t cm_clkstctrl_emu; /*0x4800 5148 */
1893 uint32_t cm_clkstst_emu; /*0x4800 514c */
1894 uint32_t cm_clksel2_emu; /*0x4800 5150 */
1895 uint32_t cm_clksel3_emu; /*0x4800 5154 */
1897 /*Global_Reg_CM Register */
1898 uint32_t cm_polctrl; /*0x4800 529c */
1900 /*NEON_CM Register */
1901 uint32_t cm_idlest_neon; /*0x4800 5320 */
1902 uint32_t cm_clkstctrl_neon; /*0x4800 5348 */
1904 /*USBHOST_CM Register */
1905 uint32_t cm_fclken_usbhost; /*0x4800 5400 */
1906 uint32_t cm_iclken_usbhost; /*0x4800 5410 */
1907 uint32_t cm_idlest_usbhost; /*0x4800 5420 */
1908 uint32_t cm_autoidle_usbhost; /*0x4800 5430 */
1909 uint32_t cm_sleepdep_usbhost; /*0x4800 5444 */
1910 uint32_t cm_clkstctrl_usbhost; /*0x4800 5448 */
1911 uint32_t cm_clkstst_usbhost; /*0x4800 544c */
1916 static inline void omap3_cm_fclken_wkup_update(struct omap3_cm_s *s,
1921 omap_clk_onoff(omap_findclk(s->mpu,"omap3_wkup_32k_fclk"), 1);
1923 omap_clk_onoff(omap_findclk(s->mpu,"omap3_wkup_32k_fclk"), 0);
1926 omap_clk_onoff(omap_findclk(s->mpu,"omap3_gp1_fclk"), 1);
1928 omap_clk_onoff(omap_findclk(s->mpu,"omap3_gp1_fclk"), 0);
1931 static inline void omap3_cm_iclken_wkup_update(struct omap3_cm_s *s,
1936 omap_clk_onoff(omap_findclk(s->mpu,"omap3_wkup_l4_iclk"), 1);
1938 omap_clk_onoff(omap_findclk(s->mpu,"omap3_wkup_l4_iclk"), 0);
1942 static inline void omap3_cm_clksel_wkup_update(struct omap3_cm_s *s,
1945 omap_clk gp1_fclk = omap_findclk(s->mpu, "omap3_gp1_fclk");
1948 omap_clk_reparent(gp1_fclk, omap_findclk(s->mpu, "omap3_sys_clk"));
1950 omap_clk_reparent(gp1_fclk, omap_findclk(s->mpu, "omap3_32k_fclk"));
1951 /*Tell GPTIMER to generate new clk rate */
1952 omap_gp_timer_change_clk(s->mpu->gptimer[0]);
1954 TRACE("omap3_gp1_fclk %lld",
1955 omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp1_fclk")));
1957 /*TODO:CM_USIM_CLK CLKSEL_RM */
1960 static inline void omap3_cm_mpu_update(struct omap3_cm_s *s)
1962 uint32_t m, n, divide, m2, cm_clken_pll_mpu;
1963 uint32_t bypass = 1;
1965 cm_clken_pll_mpu = s->cm_clken_pll_mpu;
1966 omap_clk mpu_clk = omap_findclk(s->mpu, "omap3_mpu_clk");
1968 if ((cm_clken_pll_mpu & 0x7) == 0x5)
1972 else if ((cm_clken_pll_mpu & 0x7) == 0x7)
1974 m = (s->cm_clksel1_pll_mpu & 0x7ff00) >> 8;
1975 if ((m == 0) || (m == 1))
1983 divide = (s->cm_clksel1_pll_mpu & 0x380000) >> 19;
1984 //OMAP3_DEBUG(("divide %d\n",divide));
1985 omap_clk_reparent(mpu_clk, omap_findclk(s->mpu, "omap3_core_clk"));
1986 omap_clk_setrate(mpu_clk, divide, 1);
1991 n = (s->cm_clksel1_pll_mpu & 0x7F);
1992 m2 = (s->cm_clksel2_pll_mpu & 0x1F);
1993 //OMAP3_DEBUG(("M %d N %d M2 %d \n",m,n,m2 ));
1994 omap_clk_reparent(mpu_clk, omap_findclk(s->mpu, "omap3_sys_clk"));
1995 omap_clk_setrate(mpu_clk, (n + 1) * m2, m);
1996 //OMAP3_DEBUG(("mpu %d \n",omap_clk_getrate(mpu_clk)));
2002 static inline void omap3_cm_iva2_update(struct omap3_cm_s *s)
2004 uint32_t m, n, divide, m2, cm_clken_pll_iva2;
2005 uint32_t bypass = 1;
2007 cm_clken_pll_iva2 = s->cm_clken_pll_iva2;
2008 omap_clk iva2_clk = omap_findclk(s->mpu, "omap3_iva2_clk");
2010 if (((cm_clken_pll_iva2 & 0x7) == 0x5)
2011 || ((cm_clken_pll_iva2 & 0x7) == 0x1))
2015 else if ((cm_clken_pll_iva2 & 0x7) == 0x7)
2017 m = (s->cm_clksel1_pll_iva2 & 0x7ff00) >> 8;
2018 if ((m == 0) || (m == 1))
2026 divide = (s->cm_clksel1_pll_iva2 & 0x380000) >> 19;
2027 //OMAP3_DEBUG(("divide %d\n",divide));
2028 omap_clk_reparent(iva2_clk, omap_findclk(s->mpu, "omap3_core_clk"));
2029 omap_clk_setrate(iva2_clk, divide, 1);
2034 n = (s->cm_clksel1_pll_iva2 & 0x7F);
2035 m2 = (s->cm_clksel2_pll_iva2 & 0x1F);
2036 //OMAP3_DEBUG(("M %d N %d M2 %d \n",m,n,m2 ));
2037 omap_clk_reparent(iva2_clk, omap_findclk(s->mpu, "omap3_sys_clk"));
2038 omap_clk_setrate(iva2_clk, (n + 1) * m2, m);
2039 //OMAP3_DEBUG(("iva2_clk %d \n",omap_clk_getrate(iva2_clk)));
2045 static inline void omap3_cm_dpll3_update(struct omap3_cm_s *s)
2047 uint32_t m, n, m2, m3, cm_clken_pll;
2048 uint32_t bypass = 1;
2050 cm_clken_pll = s->cm_clken_pll;
2052 /*dpll3 bypass mode. parent clock is always omap3_sys_clk */
2053 if (((cm_clken_pll & 0x7) == 0x5) || ((cm_clken_pll & 0x7) == 0x6))
2057 else if ((cm_clken_pll & 0x7) == 0x7)
2059 m = (s->cm_clksel1_pll & 0x7ff0000) >> 16;
2060 if ((m == 0) || (m == 1))
2067 omap_clk_setrate(omap_findclk(s->mpu, "omap3_core_clk"), 1, 1);
2068 omap_clk_setrate(omap_findclk(s->mpu, "omap3_core2_clk"), 1, 1);
2069 omap_clk_setrate(omap_findclk(s->mpu, "omap3_emu_core_alwon_clk"), 1,
2074 n = (s->cm_clksel1_pll & 0x3f00) >> 8;
2075 m2 = (s->cm_clksel1_pll & 0xf8000000) >> 27;
2076 m3 = (s->cm_clksel1_emu & 0x1f0000) >> 16;
2078 if (s->cm_clksel2_emu&0x80000)
2080 /*override control of DPLL3*/
2081 m = (s->cm_clksel2_emu&0x7ff)>>8;
2082 n = s->cm_clksel2_emu&0x7f;
2083 TRACE("DPLL3 override, m 0x%x n 0x%x",m,n);
2086 //OMAP3_DEBUG(("dpll3 cm_clksel1_pll %x m %d n %d m2 %d m3 %d\n",s->cm_clksel1_pll,m,n,m2,m3 ));
2087 omap_clk_setrate(omap_findclk(s->mpu, "omap3_core_clk"), (n + 1) * m2,
2089 omap_clk_setrate(omap_findclk(s->mpu, "omap3_core2_clk"), (n + 1) * m2,
2091 omap_clk_setrate(omap_findclk(s->mpu, "omap3_emu_core_alwon_clk"),
2092 (n + 1) * m3, m * 2);
2093 TRACE("coreclk %lld",
2094 omap_clk_getrate(omap_findclk(s->mpu, "omap3_core_clk")));
2100 static inline void omap3_cm_dpll4_update(struct omap3_cm_s *s)
2102 uint32_t m, n, m2, m3, m4, m5, m6, cm_clken_pll;
2103 cm_clken_pll = s->cm_clken_pll;
2104 uint32_t bypass = 1;
2106 /*dpll3 bypass mode. parent clock is always omap3_sys_clk */
2108 if ((cm_clken_pll & 0x70000) == 0x10000)
2112 else if ((cm_clken_pll & 0x70000) == 0x70000)
2114 m = (s->cm_clksel2_pll & 0x7ff00) >> 8;
2115 if ((m == 0) || (m == 1))
2122 omap_clk_setrate(omap_findclk(s->mpu, "omap3_96m_fclk"), 1, 1);
2123 omap_clk_setrate(omap_findclk(s->mpu, "omap3_54m_fclk"), 1, 1);
2124 omap_clk_setrate(omap_findclk(s->mpu, "omap3_dss1_alwon_fclk"), 1, 1);
2125 omap_clk_setrate(omap_findclk(s->mpu, "omap3_cam_mclk"), 1, 1);
2126 omap_clk_setrate(omap_findclk(s->mpu, "omap3_per_alwon_clk"), 1, 1);
2130 n = (s->cm_clksel2_pll & 0x7f);
2131 m2 = s->cm_clksel3_pll & 0x1f;
2132 m3 = (s->cm_clksel_dss & 0x1f00) >> 8;
2133 m4 = s->cm_clksel_dss & 0x1f;
2134 m5 = s->cm_clksel_cam & 0x1f;
2135 m6 = (s->cm_clksel1_emu & 0x1f000000) >> 24;
2137 if (s->cm_clksel3_emu&0x80000)
2139 /*override control of DPLL4*/
2140 m = (s->cm_clksel3_emu&0x7ff)>>8;
2141 n = s->cm_clksel3_emu&0x7f;
2142 TRACE("DPLL4 override, m 0x%x n 0x%x",m,n);
2146 //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 ));
2147 omap_clk_setrate(omap_findclk(s->mpu, "omap3_96m_fclk"), (n + 1) * m2,
2149 omap_clk_setrate(omap_findclk(s->mpu, "omap3_54m_fclk"), (n + 1) * m3,
2151 omap_clk_setrate(omap_findclk(s->mpu, "omap3_dss1_alwon_fclk"),
2152 (n + 1) * m4, m * 2);
2153 omap_clk_setrate(omap_findclk(s->mpu, "omap3_cam_mclk"), (n + 1) * m5,
2155 omap_clk_setrate(omap_findclk(s->mpu, "omap3_per_alwon_clk"),
2156 (n + 1) * m6, m * 2);
2158 TRACE("omap3_96m_fclk %lld",
2159 omap_clk_getrate(omap_findclk(s->mpu, "omap3_96m_fclk")));
2160 TRACE("omap3_54m_fclk %lld",
2161 omap_clk_getrate(omap_findclk(s->mpu, "omap3_54m_fclk")));
2162 TRACE("omap3_dss1_alwon_fclk %lld",
2163 omap_clk_getrate(omap_findclk(s->mpu, "omap3_dss1_alwon_fclk")));
2164 TRACE("omap3_cam_mclk %lld",
2165 omap_clk_getrate(omap_findclk(s->mpu, "omap3_cam_mclk")));
2166 TRACE("omap3_per_alwon_clk %lld",
2167 omap_clk_getrate(omap_findclk(s->mpu, "omap3_per_alwon_clk")));
2168 TRACE("omap3_48m_fclk %lld",
2169 omap_clk_getrate(omap_findclk(s->mpu, "omap3_48m_fclk")));
2170 TRACE("omap3_12m_fclk %lld",
2171 omap_clk_getrate(omap_findclk(s->mpu, "omap3_12m_fclk")));
2175 static inline void omap3_cm_dpll5_update(struct omap3_cm_s *s)
2177 uint32_t m, n, m2, cm_idlest2_ckgen;
2178 uint32_t bypass = 1;
2180 cm_idlest2_ckgen = s->cm_idlest2_ckgen;;
2182 /*dpll5 bypass mode */
2183 if ((cm_idlest2_ckgen & 0x1) == 0x0)
2190 omap_clk_setrate(omap_findclk(s->mpu, "omap3_120m_fclk"), 1, 1);
2194 m = (s->cm_clksel4_pll & 0x7ff00)>>8;
2195 n = s->cm_clksel4_pll & 0x3f00;
2196 m2 = s->cm_clksel5_pll & 0x1f;
2198 TRACE("dpll5 m %d n %d m2 %d",m,n,m2);
2199 omap_clk_setrate(omap_findclk(s->mpu, "omap3_120m_fclk"), (n + 1) * m2,
2201 TRACE("omap3_120m_fclk %lld",
2202 omap_clk_getrate(omap_findclk(s->mpu, "omap3_120m_fclk")));
2206 static inline void omap3_cm_48m_update(struct omap3_cm_s *s)
2208 if (s->cm_clksel1_pll & 0x8)
2210 /*parent is sysaltclk */
2211 omap_clk_reparent(omap_findclk(s->mpu, "omap3_48m_fclk"),
2212 omap_findclk(s->mpu, "omap3_sys_altclk"));
2213 omap_clk_reparent(omap_findclk(s->mpu, "omap3_12m_fclk"),
2214 omap_findclk(s->mpu, "omap3_sys_altclk"));
2215 /*TODO:need to set rate ? */
2220 omap_clk_reparent(omap_findclk(s->mpu, "omap3_12m_fclk"),
2221 omap_findclk(s->mpu, "omap3_96m_fclk"));
2222 omap_clk_reparent(omap_findclk(s->mpu, "omap3_48m_fclk"),
2223 omap_findclk(s->mpu, "omap3_96m_fclk"));
2224 omap_clk_setrate(omap_findclk(s->mpu, "omap3_48m_fclk"), 2, 1);
2225 omap_clk_setrate(omap_findclk(s->mpu, "omap3_12m_fclk"), 8, 1);
2231 static inline void omap3_cm_gp10_update(struct omap3_cm_s *s)
2233 omap_clk gp10_fclk = omap_findclk(s->mpu, "omap3_gp10_fclk");
2235 if (s->cm_clksel_core & 0x40)
2236 omap_clk_reparent(gp10_fclk, omap_findclk(s->mpu, "omap3_sys_clk"));
2238 omap_clk_reparent(gp10_fclk, omap_findclk(s->mpu, "omap3_32k_fclk"));
2240 /*Tell GPTIMER10 to generate new clk rate */
2241 omap_gp_timer_change_clk(s->mpu->gptimer[9]);
2242 TRACE("omap3_gp10_fclk %lld",
2243 omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp10_fclk")));
2246 static inline void omap3_cm_gp11_update(struct omap3_cm_s *s)
2248 omap_clk gp11_fclk = omap_findclk(s->mpu, "omap3_gp11_fclk");
2250 if (s->cm_clksel_core & 0x80)
2251 omap_clk_reparent(gp11_fclk, omap_findclk(s->mpu, "omap3_sys_clk"));
2253 omap_clk_reparent(gp11_fclk, omap_findclk(s->mpu, "omap3_32k_fclk"));
2254 /*Tell GPTIMER11 to generate new clk rate */
2255 omap_gp_timer_change_clk(s->mpu->gptimer[10]);
2256 TRACE("omap3_gp11_fclk %lld",
2257 omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp11_fclk")));
2260 static inline void omap3_cm_l3clk_update(struct omap3_cm_s *s)
2262 omap_clk l3_iclk = omap_findclk(s->mpu, "omap3_l3_iclk");
2263 if ((s->cm_clksel_core & 0x3) == 0x1)
2264 omap_clk_setrate(l3_iclk, 1, 1);
2265 else if ((s->cm_clksel_core & 0x3) == 0x2)
2266 omap_clk_setrate(l3_iclk, 2, 1);
2269 static inline void omap3_cm_l4clk_update(struct omap3_cm_s *s)
2271 omap_clk l4_iclk = omap_findclk(s->mpu, "omap3_l4_iclk");
2272 if ((s->cm_clksel_core & 0xc) == 0x4)
2273 omap_clk_setrate(l4_iclk, 1, 1);
2274 else if ((s->cm_clksel_core & 0xc) == 0x8)
2275 omap_clk_setrate(l4_iclk, 2, 1);
2278 static inline void omap3_cm_per_gptimer_update(struct omap3_cm_s *s)
2280 uint32_t cm_clksel_per = s->cm_clksel_per;
2282 if (cm_clksel_per & 0x1)
2283 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp2_fclk"),
2284 omap_findclk(s->mpu, "omap3_sys_clk"));
2286 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp2_fclk"),
2287 omap_findclk(s->mpu, "omap3_32k_fclk"));
2288 omap_gp_timer_change_clk(s->mpu->gptimer[1]);
2290 if (cm_clksel_per & 0x2)
2291 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp3_fclk"),
2292 omap_findclk(s->mpu, "omap3_sys_clk"));
2294 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp3_fclk"),
2295 omap_findclk(s->mpu, "omap3_32k_fclk"));
2296 omap_gp_timer_change_clk(s->mpu->gptimer[2]);
2298 if (cm_clksel_per & 0x4)
2299 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp4_fclk"),
2300 omap_findclk(s->mpu, "omap3_sys_clk"));
2302 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp4_fclk"),
2303 omap_findclk(s->mpu, "omap3_32k_fclk"));
2304 omap_gp_timer_change_clk(s->mpu->gptimer[3]);
2306 if (cm_clksel_per & 0x8)
2307 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp5_fclk"),
2308 omap_findclk(s->mpu, "omap3_sys_clk"));
2310 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp5_fclk"),
2311 omap_findclk(s->mpu, "omap3_32k_fclk"));
2312 omap_gp_timer_change_clk(s->mpu->gptimer[4]);
2314 if (cm_clksel_per & 0x10)
2315 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp6_fclk"),
2316 omap_findclk(s->mpu, "omap3_sys_clk"));
2318 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp6_fclk"),
2319 omap_findclk(s->mpu, "omap3_32k_fclk"));
2320 omap_gp_timer_change_clk(s->mpu->gptimer[5]);
2322 if (cm_clksel_per & 0x20)
2323 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp7_fclk"),
2324 omap_findclk(s->mpu, "omap3_sys_clk"));
2326 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp7_fclk"),
2327 omap_findclk(s->mpu, "omap3_32k_fclk"));
2328 omap_gp_timer_change_clk(s->mpu->gptimer[6]);
2331 if (cm_clksel_per & 0x40)
2332 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp8_fclk"),
2333 omap_findclk(s->mpu, "omap3_sys_clk"));
2335 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp8_fclk"),
2336 omap_findclk(s->mpu, "omap3_32k_fclk"));
2337 omap_gp_timer_change_clk(s->mpu->gptimer[7]);
2339 if (cm_clksel_per & 0x80)
2340 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp9_fclk"),
2341 omap_findclk(s->mpu, "omap3_sys_clk"));
2343 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp9_fclk"),
2344 omap_findclk(s->mpu, "omap3_32k_fclk"));
2345 omap_gp_timer_change_clk(s->mpu->gptimer[8]);
2347 /*TODO:Tell GPTIMER to generate new clk rate */
2348 TRACE("omap3_gp2_fclk %lld",
2349 omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp2_fclk")));
2350 TRACE("omap3_gp3_fclk %lld",
2351 omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp3_fclk")));
2352 TRACE("omap3_gp4_fclk %lld",
2353 omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp4_fclk")));
2354 TRACE("omap3_gp5_fclk %lld",
2355 omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp5_fclk")));
2356 TRACE("omap3_gp6_fclk %lld",
2357 omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp6_fclk")));
2358 TRACE("omap3_gp7_fclk %lld",
2359 omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp7_fclk")));
2360 TRACE("omap3_gp8_fclk %lld",
2361 omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp8_fclk")));
2362 TRACE("omap3_gp9_fclk %lld",
2363 omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp9_fclk")));
2366 static inline void omap3_cm_clkout2_update(struct omap3_cm_s *s)
2370 if (!s->cm_clkout_ctrl&0x80)
2373 switch (s->cm_clkout_ctrl&0x3)
2376 omap_clk_reparent(omap_findclk(s->mpu, "omap3_sys_clkout2"),
2377 omap_findclk(s->mpu, "omap3_core_clk"));
2380 omap_clk_reparent(omap_findclk(s->mpu, "omap3_sys_clkout2"),
2381 omap_findclk(s->mpu, "omap3_sys_clk"));
2384 omap_clk_reparent(omap_findclk(s->mpu, "omap3_sys_clkout2"),
2385 omap_findclk(s->mpu, "omap3_96m_fclk"));
2388 omap_clk_reparent(omap_findclk(s->mpu, "omap3_sys_clkout2"),
2389 omap_findclk(s->mpu, "omap3_54m_fclk"));
2393 divor = (s->cm_clkout_ctrl&0x31)>>3;
2395 omap_clk_setrate(omap_findclk(s->mpu, "omap3_sys_clkout2"), divor, 1);
2399 static void omap3_cm_reset(struct omap3_cm_s *s)
2401 s->cm_fclken_iva2 = 0x0;
2402 s->cm_clken_pll_iva2 = 0x11;
2403 s->cm_idlest_iva2 = 0x1;
2404 s->cm_idlest_pll_iva2 = 0x0;
2405 s->cm_autoidle_pll_iva2 = 0x0;
2406 s->cm_clksel1_pll_iva2 = 0x80000;
2407 s->cm_clksel2_pll_iva2 = 0x1;
2408 s->cm_clkstctrl_iva2 = 0x0;
2409 s->cm_clkstst_iva2 = 0x0;
2411 s->cm_revision = 0x10;
2412 s->cm_sysconfig = 0x1;
2414 s->cm_clken_pll_mpu = 0x15;
2415 s->cm_idlest_mpu = 0x1;
2416 s->cm_idlest_pll_mpu = 0x0;
2417 s->cm_autoidle_pll_mpu = 0x0;
2418 s->cm_clksel1_pll_mpu = 0x80000;
2419 s->cm_clksel2_pll_mpu = 0x1;
2420 s->cm_clkstctrl_mpu = 0x0;
2421 s->cm_clkstst_mpu = 0x0;
2423 s->cm_fclken1_core = 0x0;
2424 s->cm_fclken3_core = 0x0;
2425 s->cm_iclken1_core = 0x42;
2426 s->cm_iclken2_core = 0x0;
2427 s->cm_iclken3_core = 0x0;
2428 /*allow access to devices*/
2429 s->cm_idlest1_core = 0x0;
2430 s->cm_idlest2_core = 0x0;
2432 s->cm_idlest3_core = 0xa;
2433 s->cm_autoidle1_core = 0x0;
2434 s->cm_autoidle2_core = 0x0;
2435 s->cm_autoidle3_core = 0x0;
2436 s->cm_clksel_core = 0x105;
2437 s->cm_clkstctrl_core = 0x0;
2438 s->cm_clkstst_core = 0x0;
2440 s->cm_fclken_sgx = 0x0;
2441 s->cm_iclken_sgx = 0x0;
2442 s->cm_idlest_sgx = 0x1;
2443 s->cm_clksel_sgx = 0x0;
2444 s->cm_sleepdep_sgx = 0x0;
2445 s->cm_clkstctrl_sgx = 0x0;
2446 s->cm_clkstst_sgx = 0x0;
2448 s->cm_fclken_wkup = 0x0;
2449 s->cm_iclken_wkup = 0x0;
2450 /*assume all clock can be accessed*/
2451 s->cm_idlest_wkup = 0x0;
2452 s->cm_autoidle_wkup = 0x0;
2453 s->cm_clksel_wkup = 0x12;
2455 s->cm_clken_pll = 0x110015;
2456 s->cm_clken2_pll = 0x11;
2457 s->cm_idlest_ckgen = 0x0;
2458 s->cm_idlest2_ckgen = 0x0;
2459 s->cm_autoidle_pll = 0x0;
2460 s->cm_autoidle2_pll = 0x0;
2461 s->cm_clksel1_pll = 0x8000040;
2462 s->cm_clksel2_pll = 0x0;
2463 s->cm_clksel3_pll = 0x1;
2464 s->cm_clksel4_pll = 0x0;
2465 s->cm_clksel5_pll = 0x1;
2466 s->cm_clkout_ctrl = 0x3;
2469 s->cm_fclken_dss = 0x0;
2470 s->cm_iclken_dss = 0x0;
2471 /*dss can be accessed*/
2472 s->cm_idlest_dss = 0x0;
2473 s->cm_autoidle_dss = 0x0;
2474 s->cm_clksel_dss = 0x1010;
2475 s->cm_sleepdep_dss = 0x0;
2476 s->cm_clkstctrl_dss = 0x0;
2477 s->cm_clkstst_dss = 0x0;
2479 s->cm_fclken_cam = 0x0;
2480 s->cm_iclken_cam = 0x0;
2481 s->cm_idlest_cam = 0x1;
2482 s->cm_autoidle_cam = 0x0;
2483 s->cm_clksel_cam = 0x10;
2484 s->cm_sleepdep_cam = 0x0;
2485 s->cm_clkstctrl_cam = 0x0;
2486 s->cm_clkstst_cam = 0x0;
2488 s->cm_fclken_per = 0x0;
2489 s->cm_iclken_per = 0x0;
2490 //s->cm_idlest_per = 0x3ffff;
2491 s->cm_idlest_per = 0x0; //enable GPIO access
2492 s->cm_autoidle_per = 0x0;
2493 s->cm_clksel_per = 0x0;
2494 s->cm_sleepdep_per = 0x0;
2495 s->cm_clkstctrl_per = 0x0;
2496 s->cm_clkstst_per = 0x0;
2498 s->cm_clksel1_emu = 0x10100a50;
2499 s->cm_clkstctrl_emu = 0x2;
2500 s->cm_clkstst_emu = 0x0;
2501 s->cm_clksel2_emu = 0x0;
2502 s->cm_clksel3_emu = 0x0;
2504 s->cm_polctrl = 0x0;
2506 s->cm_idlest_neon = 0x1;
2507 s->cm_clkstctrl_neon = 0x0;
2509 s->cm_fclken_usbhost = 0x0;
2510 s->cm_iclken_usbhost = 0x0;
2511 s->cm_idlest_usbhost = 0x3;
2512 s->cm_autoidle_usbhost = 0x0;
2513 s->cm_sleepdep_usbhost = 0x0;
2514 s->cm_clkstctrl_usbhost = 0x0;
2515 s->cm_clkstst_usbhost = 0x0;
2518 static uint32_t omap3_cm_read(void *opaque, target_phys_addr_t addr)
2520 struct omap3_cm_s *s = (struct omap3_cm_s *) opaque;
2522 uint32_t bypass = 0, m;
2524 TRACE("%04x", addr);
2528 return s->cm_fclken_iva2;
2530 return s->cm_clken_pll_iva2;
2532 return s->cm_idlest_iva2;
2534 if (((s->cm_clken_pll_iva2 & 0x7) == 0x5)
2535 || ((s->cm_clken_pll_iva2 & 0x7) == 0x1))
2539 else if ((s->cm_clken_pll_iva2 & 0x7) == 0x7)
2541 m = (s->cm_clksel1_pll_iva2 & 0x7ff00) >> 8;
2542 if ((m == 0) || (m == 1))
2552 return s->cm_autoidle_pll_iva2;
2554 return s->cm_clksel1_pll_iva2;
2556 return s->cm_clksel2_pll_iva2;
2558 return s->cm_clkstctrl_iva2;
2560 return s->cm_clkstst_iva2;
2563 return s->cm_revision;
2565 return s->cm_sysconfig;
2568 case 0x904: /*CM_CLKEN_PLL_MPU */
2569 return s->cm_clken_pll_mpu;
2571 return s->cm_idlest_mpu & 0x0; /*MPU is active*/
2573 if ((s->cm_clken_pll_mpu & 0x7) == 0x5)
2577 else if ((s->cm_clken_pll_mpu & 0x7) == 0x7)
2579 m = (s->cm_clksel1_pll_mpu & 0x7ff00) >> 8;
2580 if ((m == 0) || (m == 1))
2590 return s->cm_autoidle_pll_mpu;
2592 return s->cm_clksel1_pll_mpu;
2594 return s->cm_clksel2_pll_mpu;
2596 return s->cm_clkstctrl_mpu;
2598 return s->cm_clkstst_mpu;
2603 return s->cm_fclken1_core;
2605 return s->cm_fclken3_core;
2607 return s->cm_iclken1_core;
2609 return s->cm_iclken2_core;
2611 return s->cm_idlest1_core;
2613 return s->cm_idlest2_core;
2615 return s->cm_idlest3_core;
2617 return s->cm_autoidle1_core;
2619 return s->cm_autoidle2_core;
2621 return s->cm_autoidle3_core;
2622 case 0xa40: /*CM_CLKSEL_CORE */
2623 return s->cm_clksel_core;
2625 return s->cm_clkstctrl_core;
2627 return s->cm_clkstst_core;
2630 return s->cm_fclken_sgx;
2632 return s->cm_iclken_sgx;
2634 return s->cm_idlest_sgx&0x0;
2635 case 0xb40: /*CM_CLKSEL_SGX */
2636 return s->cm_clksel_sgx;
2638 return s->cm_clkstctrl_sgx;
2640 return s->cm_clkstst_sgx;
2643 case 0xc00: /*CM_FCLKEN_WKUP */
2644 return s->cm_fclken_wkup;
2645 case 0xc10: /*CM_ICLKEN_WKUP */
2646 return s->cm_iclken_wkup;
2647 case 0xc20: /*CM_IDLEST_WKUP */
2648 /*TODO: Check whether the timer can be accessed. */
2651 return s->cm_idlest_wkup;
2653 return s->cm_clksel_wkup;
2658 case 0xd00: /*CM_CLKEN_PLL */
2659 return s->cm_clken_pll;
2661 return s->cm_clken2_pll;
2663 /*FIXME: all clock is active. we do not care it. */
2668 if (((s->cm_clken_pll & 0x7) == 0x5) || ((s->cm_clken_pll & 0x7) == 0x6))
2670 else if ((s->cm_clken_pll & 0x7) == 0x7) {
2671 m = (s->cm_clksel1_pll & 0x7ff0000) >> 16;
2672 if ((m == 0) || (m == 1))
2682 if ((s->cm_clken_pll & 0x70000) == 0x10000)
2684 else if ((s->cm_clken_pll & 0x70000) == 0x70000) {
2685 m = (s->cm_clksel2_pll & 0x7ff00) >> 8;
2686 if ((m == 0) || (m == 1))
2696 return s->cm_idlest2_ckgen;
2698 return s->cm_autoidle_pll;
2700 return s->cm_autoidle2_pll;
2701 case 0xd40: /*CM_CLKSEL1_PLL */
2702 return s->cm_clksel1_pll;
2704 return s->cm_clksel2_pll;
2705 case 0xd48: /*CM_CLKSEL3_PLL */
2706 return s->cm_clksel3_pll;
2708 return s->cm_clksel4_pll;
2709 case 0xd50: /*CM_CLKSEL5_PLL */
2710 return s->cm_clksel5_pll;
2712 return s->cm_clkout_ctrl;
2716 return s->cm_fclken_dss;
2718 return s->cm_iclken_dss;
2720 return s->cm_idlest_dss;
2722 return s->cm_autoidle_dss;
2724 return s->cm_clksel_dss;
2726 return s->cm_sleepdep_dss;
2728 return s->cm_clkstctrl_dss;
2730 return s->cm_clkstst_dss;
2734 return s->cm_fclken_cam;
2736 return s->cm_iclken_cam;
2738 return s->cm_idlest_cam&0x0;
2740 return s->cm_autoidle_cam;
2742 return s->cm_clksel_cam;
2744 return s->cm_sleepdep_cam;
2746 return s->cm_clkstctrl_cam;
2748 return s->cm_clkstst_cam;
2752 return s->cm_fclken_per;
2754 return s->cm_iclken_per;
2756 return s->cm_idlest_per ;
2758 return s->cm_autoidle_per;
2760 return s->cm_clksel_per;
2762 return s->cm_sleepdep_per;
2764 return s->cm_clkstctrl_per;
2766 return s->cm_clkstst_per;
2769 case 0x1140: /*CM_CLKSEL1_EMU */
2770 return s->cm_clksel1_emu;
2772 return s->cm_clkstctrl_emu;
2774 return s->cm_clkstst_emu&0x0;
2776 return s->cm_clksel2_emu;
2778 return s->cm_clksel3_emu;
2781 return s->cm_polctrl;
2784 return s->cm_idlest_neon&0x0;
2786 return s->cm_clkstctrl_neon;
2789 return s->cm_fclken_usbhost;
2791 return s->cm_iclken_usbhost;
2793 return s->cm_idlest_usbhost&0x0;
2795 return s->cm_autoidle_usbhost;
2797 return s->cm_sleepdep_usbhost;
2799 return s->cm_clkstctrl_usbhost;
2801 return s->cm_clkstst_usbhost;
2804 printf("omap3_cm_read addr %x pc %x \n", addr, cpu_single_env->regs[15] );
2810 static void omap3_cm_write(void *opaque, target_phys_addr_t addr,
2813 struct omap3_cm_s *s = (struct omap3_cm_s *) opaque;
2815 TRACE("%04x = %08x", addr, value);
2831 case 0xc20: /*CM_IDLEST_WKUP */
2849 s->cm_fclken_iva2 = value & 0x1;
2851 case 0x4: /*CM_CLKEN_PLL_IVA2 */
2852 s->cm_clken_pll_iva2 = value & 0x7ff;
2853 omap3_cm_iva2_update(s);
2856 s->cm_autoidle_pll_iva2 = value & 0x7;
2859 s->cm_clksel1_pll_iva2 = value & 0x3fff7f;
2860 //printf("value %x s->cm_clksel1_pll_iva2 %x \n",value,s->cm_clksel1_pll_iva2);
2861 omap3_cm_iva2_update(s);
2864 s->cm_clksel2_pll_iva2 = value & 0x1f;
2865 omap3_cm_iva2_update(s);
2868 s->cm_clkstctrl_iva2 = value& 0x3;
2872 s->cm_sysconfig = value & 0x1;
2876 case 0x904: /*CM_CLKEN_PLL_MPU */
2877 s->cm_clken_pll_mpu = value & 0x7ff;
2878 omap3_cm_mpu_update(s);
2881 s->cm_autoidle_pll_mpu = value & 0x7;
2884 //printf("s->cm_clksel1_pll_mpu %x\n",s->cm_clksel1_pll_mpu );
2885 s->cm_clksel1_pll_mpu = value & 0x3fff7f;
2886 omap3_cm_mpu_update(s);
2889 s->cm_clksel2_pll_mpu = value & 0x1f;
2890 omap3_cm_mpu_update(s);
2893 s->cm_clkstctrl_mpu = value & 0x3;
2898 s->cm_fclken1_core = value & 0x43fffe00;
2901 s->cm_fclken3_core = value & 0x7;
2904 s->cm_iclken1_core = value & 0x637ffed2;
2905 s->cm_idlest1_core = ~s->cm_iclken1_core;
2906 /* TODO: replace code below with real implementation */
2907 s->cm_idlest1_core &= ~0x20; /* HS OTG USB idle */
2908 s->cm_idlest1_core |= 4; /* SDMA in standby */
2911 s->cm_iclken2_core = value & 0x1f;
2914 s->cm_iclken3_core = value & 0x4;
2915 s->cm_idlest3_core = 0xd & ~(s->cm_iclken3_core & 4);
2918 s->cm_autoidle1_core = value & 0x7ffffed0;
2921 s->cm_autoidle2_core = value & 0x1f;
2924 s->cm_autoidle3_core = value & 0x2;
2926 case 0xa40: /*CM_CLKSEL_CORE */
2927 s->cm_clksel_core = (value & 0xff);
2928 s->cm_clksel_core |= 0x100;
2929 omap3_cm_gp10_update(s);
2930 omap3_cm_gp11_update(s);
2931 omap3_cm_l3clk_update(s);
2932 omap3_cm_l4clk_update(s);
2935 s->cm_clkstctrl_core = value & 0xf;
2939 s->cm_fclken_sgx = value &0x2;
2942 s->cm_iclken_sgx = value & 0x1;
2944 case 0xb40: /*CM_CLKSEL_SGX */
2945 /*TODO: SGX Clock!! */
2946 s->cm_clksel_sgx = value;
2949 s->cm_sleepdep_sgx = value &0x2;
2952 s->cm_clkstctrl_sgx = value & 0x3;
2956 case 0xc00: /*CM_FCLKEN_WKUP */
2957 s->cm_fclken_wkup = value & 0x2e9;
2959 case 0xc10: /*CM_ICLKEN_WKUP */
2960 s->cm_iclken_wkup = value & 0x2ff;
2963 s->cm_autoidle_wkup = value & 0x23f;
2965 case 0xc40: /*CM_CLKSEL_WKUP */
2966 s->cm_clksel_wkup = value & 0x7f;
2967 omap3_cm_clksel_wkup_update(s, s->cm_clksel_wkup);
2971 case 0xd00: /*CM_CLKEN_PLL */
2972 s->cm_clken_pll = value & 0xffff17ff;
2973 omap3_cm_dpll3_update(s);
2974 omap3_cm_dpll4_update(s);
2977 s->cm_clken2_pll = value & 0x7ff;
2980 s->cm_autoidle_pll = value & 0x3f;
2983 s->cm_autoidle2_pll = value & 0x7;
2985 case 0xd40: /*CM_CLKSEL1_PLL */
2986 //OMAP3_DEBUG(("WD40 value %x \n",value));
2987 s->cm_clksel1_pll = value & 0xffffbffc;
2988 //OMAP3_DEBUG(("WD40 value %x \n",value));
2989 omap3_cm_dpll3_update(s);
2990 omap3_cm_48m_update(s);
2993 s->cm_clksel2_pll = value & 0x7ff7f;
2994 omap3_cm_dpll4_update(s);
2996 case 0xd48: /*CM_CLKSEL3_PLL */
2997 s->cm_clksel3_pll = value & 0x1f;
2998 omap3_cm_dpll4_update(s);
3000 case 0xd4c: /*CM_CLKSEL4_PLL */
3001 s->cm_clksel4_pll = value & 0x7ff7f;
3002 omap3_cm_dpll5_update(s);
3004 case 0xd50: /*CM_CLKSEL5_PLL */
3005 s->cm_clksel5_pll = value & 0x1f;
3006 omap3_cm_dpll5_update(s);
3009 s->cm_clkout_ctrl = value & 0xbb;
3010 omap3_cm_clkout2_update(s);
3014 s->cm_fclken_dss = value & 0x7;
3017 s->cm_iclken_dss = value & 0x1;
3020 s->cm_autoidle_dss = value & 0x1;
3023 s->cm_clksel_dss = value & 0x1f1f;
3024 omap3_cm_dpll4_update(s);
3027 s->cm_sleepdep_dss = value & 0x7;
3030 s->cm_clkstctrl_dss = value & 0x3;
3034 s->cm_fclken_cam = value & 0x3;
3037 s->cm_iclken_cam = value & 0x1;
3040 s->cm_autoidle_cam = value & 0x1;
3043 s->cm_clksel_cam = value & 0x1f;
3044 omap3_cm_dpll4_update(s);
3047 s->cm_sleepdep_cam = value & 0x2;
3050 s->cm_clkstctrl_cam = value & 0x3;
3054 s->cm_fclken_per = value & 0x3ffff;
3057 s->cm_iclken_per = value & 0x3ffff;
3061 s->cm_autoidle_per = value &0x3ffff;
3064 s->cm_clksel_per = value & 0xff;
3065 omap3_cm_per_gptimer_update(s);
3068 s->cm_sleepdep_per = value & 0x6;
3071 s->cm_clkstctrl_per = value &0x7;
3074 case 0x1140: /*CM_CLKSEL1_EMU */
3075 s->cm_clksel1_emu = value & 0x1f1f3fff;
3076 //printf("cm_clksel1_emu %x\n",s->cm_clksel1_emu);
3077 omap3_cm_dpll3_update(s);
3078 omap3_cm_dpll4_update(s);
3081 s->cm_clkstctrl_emu = value & 0x3;
3084 s->cm_clksel2_emu = value & 0xfff7f;
3085 omap3_cm_dpll3_update(s);
3088 s->cm_clksel3_emu = value & 0xfff7f;
3089 omap3_cm_dpll4_update(s);
3093 s->cm_polctrl = value & 0x1;
3097 s->cm_clkstctrl_neon = value & 0x3;
3101 s->cm_fclken_usbhost = value & 0x3;
3104 s->cm_iclken_usbhost = value & 0x1;
3107 s->cm_autoidle_usbhost = value & 0x1;
3110 s->cm_sleepdep_usbhost = value & 0x6;
3113 s->cm_clkstctrl_usbhost = value & 0x3;
3117 printf("omap3_cm_write addr %x value %x pc %x\n", addr, value,cpu_single_env->regs[15] );
3124 static CPUReadMemoryFunc *omap3_cm_readfn[] = {
3125 omap_badwidth_read32,
3126 omap_badwidth_read32,
3130 static CPUWriteMemoryFunc *omap3_cm_writefn[] = {
3131 omap_badwidth_write32,
3132 omap_badwidth_write32,
3136 struct omap3_cm_s *omap3_cm_init(struct omap_target_agent_s *ta,
3137 qemu_irq mpu_int, qemu_irq dsp_int,
3138 qemu_irq iva_int, struct omap_mpu_state_s *mpu)
3141 struct omap3_cm_s *s = (struct omap3_cm_s *) qemu_mallocz(sizeof(*s));
3143 s->irq[0] = mpu_int;
3144 s->irq[1] = dsp_int;
3145 s->irq[2] = iva_int;
3149 iomemtype = l4_register_io_memory(0, omap3_cm_readfn, omap3_cm_writefn, s);
3150 omap_l4_attach(ta, 0, iomemtype);
3151 omap_l4_attach(ta, 1, iomemtype);
3156 #define OMAP3_SEC_WDT 1
3157 #define OMAP3_MPU_WDT 2
3158 #define OMAP3_IVA2_WDT 3
3159 /*omap3 watchdog timer*/
3162 qemu_irq irq; /*IVA2 IRQ */
3163 struct omap_mpu_state_s *mpu;
3170 //int64_t ticks_per_sec;
3172 uint32_t wd_sysconfig;
3173 uint32_t wd_sysstatus;
3183 /*pre and ptv in wclr */
3188 uint16_t writeh; /* LSB */
3189 uint16_t readh; /* MSB */
3192 static inline void omap3_wdt_timer_update(struct omap3_wdt_s *wdt_timer)
3195 if (wdt_timer->active)
3197 expires = muldiv64(0xffffffffll - wdt_timer->wcrr,
3198 ticks_per_sec, wdt_timer->rate);
3199 qemu_mod_timer(wdt_timer->timer, wdt_timer->time + expires);
3202 qemu_del_timer(wdt_timer->timer);
3205 static void omap3_wdt_clk_setup(struct omap3_wdt_s *timer)
3207 /*TODO: Add irq as user to clk */
3210 static inline uint32_t omap3_wdt_timer_read(struct omap3_wdt_s *timer)
3216 distance = qemu_get_clock(vm_clock) - timer->time;
3217 distance = muldiv64(distance, timer->rate, ticks_per_sec);
3219 if (distance >= 0xffffffff - timer->wcrr)
3222 return timer->wcrr + distance;
3229 static inline void omap3_wdt_timer_sync(struct omap3_wdt_s *timer)
3231 if (timer->active) {
3232 timer->val = omap3_wdt_timer_read(timer);
3233 timer->time = qemu_get_clock(vm_clock);
3237 static void omap3_wdt_reset(struct omap3_wdt_s *s, int wdt_index)
3239 s->wd_sysconfig = 0x0;
3240 s->wd_sysstatus = 0x0;
3248 case OMAP3_IVA2_WDT:
3249 s->wldr = 0xfffb0000;
3252 s->wldr = 0xffa60000;
3265 case OMAP3_IVA2_WDT:
3269 s->pre = s->wclr & (1 << 5);
3270 s->ptv = (s->wclr & 0x1c) >> 2;
3271 s->rate = omap_clk_getrate(s->clk) >> (s->pre ? s->ptv : 0);
3274 s->time = qemu_get_clock(vm_clock);
3275 omap3_wdt_timer_update(s);
3278 static uint32_t omap3_wdt_read32(void *opaque, target_phys_addr_t addr,
3281 struct omap3_wdt_s *s = (struct omap3_wdt_s *) opaque;
3284 //printf("omap3_wdt_read32 addr %x \n",addr);
3287 case 0x10: /*WD_SYSCONFIG */
3288 return s->wd_sysconfig;
3289 case 0x14: /*WD_SYSSTATUS */
3290 return s->wd_sysstatus;
3292 /*WISR*/ return s->wisr & 0x1;
3294 /*WIER*/ return s->wier & 0x1;
3296 /*WCLR*/ return s->wclr & 0x3c;
3298 /*WCRR*/ s->wcrr = omap3_wdt_timer_read(s);
3299 s->time = qemu_get_clock(vm_clock);
3302 /*WLDR*/ return s->wldr;
3304 /*WTGR*/ return s->wtgr;
3306 /*WWPS*/ return s->wwps;
3308 /*WSPR*/ return s->wspr;
3310 printf("omap3_wdt_read32 addr %x \n", addr);
3315 static uint32_t omap3_mpu_wdt_read16(void *opaque, target_phys_addr_t addr)
3317 struct omap3_wdt_s *s = (struct omap3_wdt_s *) opaque;
3324 ret = omap3_wdt_read32(opaque, addr, OMAP3_MPU_WDT);
3325 s->readh = ret >> 16;
3326 return ret & 0xffff;
3330 static uint32_t omap3_mpu_wdt_read32(void *opaque, target_phys_addr_t addr)
3332 return omap3_wdt_read32(opaque, addr, OMAP3_MPU_WDT);
3335 static void omap3_wdt_write32(void *opaque, target_phys_addr_t addr,
3336 uint32_t value, int wdt_index)
3338 struct omap3_wdt_s *s = (struct omap3_wdt_s *) opaque;
3340 //printf("omap3_wdt_write32 addr %x value %x \n",addr,value);
3343 case 0x14: /*WD_SYSSTATUS */
3345 /*WWPS*/ OMAP_RO_REG(addr);
3348 case 0x10: /*WD_SYSCONFIG */
3349 s->wd_sysconfig = value & 0x33f;
3352 /*WISR*/ s->wisr = value & 0x1;
3355 /*WIER*/ s->wier = value & 0x1;
3358 /*WCLR*/ s->wclr = value & 0x3c;
3361 /*WCRR*/ s->wcrr = value;
3362 s->time = qemu_get_clock(vm_clock);
3363 omap3_wdt_timer_update(s);
3366 /*WLDR*/ s->wldr = value; /*It will take effect after next overflow */
3369 /*WTGR*/ if (value != s->wtgr)
3372 s->pre = s->wclr & (1 << 5);
3373 s->ptv = (s->wclr & 0x1c) >> 2;
3374 s->rate = omap_clk_getrate(s->clk) >> (s->pre ? s->ptv : 0);
3375 s->time = qemu_get_clock(vm_clock);
3376 omap3_wdt_timer_update(s);
3382 if (((value & 0xffff) == 0x5555) && ((s->wspr & 0xffff) == 0xaaaa))
3385 s->wcrr = omap3_wdt_timer_read(s);
3386 omap3_wdt_timer_update(s);
3388 if (((value & 0xffff) == 0x4444) && ((s->wspr & 0xffff) == 0xbbbb))
3391 s->time = qemu_get_clock(vm_clock);
3392 omap3_wdt_timer_update(s);
3397 printf("omap3_wdt_write32 addr %x \n", addr);
3402 static void omap3_mpu_wdt_write16(void *opaque, target_phys_addr_t addr,
3405 struct omap3_wdt_s *s = (struct omap3_wdt_s *) opaque;
3408 return omap3_wdt_write32(opaque, addr, (value << 16) | s->writeh,
3411 s->writeh = (uint16_t) value;
3414 static void omap3_mpu_wdt_write32(void *opaque, target_phys_addr_t addr,
3417 omap3_wdt_write32(opaque, addr, value, OMAP3_MPU_WDT);
3420 static CPUReadMemoryFunc *omap3_mpu_wdt_readfn[] = {
3421 omap_badwidth_read32,
3422 omap3_mpu_wdt_read16,
3423 omap3_mpu_wdt_read32,
3426 static CPUWriteMemoryFunc *omap3_mpu_wdt_writefn[] = {
3427 omap_badwidth_write32,
3428 omap3_mpu_wdt_write16,
3429 omap3_mpu_wdt_write32,
3432 static void omap3_mpu_wdt_timer_tick(void *opaque)
3434 struct omap3_wdt_s *wdt_timer = (struct omap3_wdt_s *) opaque;
3436 /*TODO:Sent reset pulse to PRCM */
3437 wdt_timer->wcrr = wdt_timer->wldr;
3439 /*after overflow, generate the new wdt_timer->rate */
3440 wdt_timer->pre = wdt_timer->wclr & (1 << 5);
3441 wdt_timer->ptv = (wdt_timer->wclr & 0x1c) >> 2;
3443 omap_clk_getrate(wdt_timer->clk) >> (wdt_timer->pre ? wdt_timer->
3446 wdt_timer->time = qemu_get_clock(vm_clock);
3447 omap3_wdt_timer_update(wdt_timer);
3450 static struct omap3_wdt_s *omap3_mpu_wdt_init(struct omap_target_agent_s *ta,
3451 qemu_irq irq, omap_clk fclk,
3453 struct omap_mpu_state_s *mpu)
3456 struct omap3_wdt_s *s = (struct omap3_wdt_s *) qemu_mallocz(sizeof(*s));
3460 s->timer = qemu_new_timer(vm_clock, omap3_mpu_wdt_timer_tick, s);
3462 omap3_wdt_reset(s, OMAP3_MPU_WDT);
3464 omap3_wdt_clk_setup(s);
3466 iomemtype = l4_register_io_memory(0, omap3_mpu_wdt_readfn,
3467 omap3_mpu_wdt_writefn, s);
3468 omap_l4_attach(ta, 0, iomemtype);
3474 /*dummy system control module*/
3477 struct omap_mpu_state_s *mpu;
3479 uint8 interface[48]; /*0x4800 2000*/
3480 uint8 padconfs[576]; /*0x4800 2030*/
3481 uint32 general[228]; /*0x4800 2270*/
3482 uint8 mem_wkup[1024]; /*0x4800 2600*/
3483 uint8 padconfs_wkup[84]; /*0x4800 2a00*/
3484 uint32 general_wkup[8]; /*0x4800 2a60*/
3487 #define PADCONFS_VALUE(wakeup0,wakeup1,offmode0,offmode1, \
3488 inputenable0,inputenable1,pupd0,pupd1,muxmode0,muxmode1,offset) \
3490 *(padconfs+offset/4) = (wakeup0 <<14)|(offmode0<<9)|(inputenable0<<8)|(pupd0<<3)|(muxmode0); \
3491 *(padconfs+offset/4) |= (wakeup1 <<30)|(offmode1<<25)|(inputenable1<<24)|(pupd1<<19)|(muxmode1<<16); \
3495 static void omap3_scm_reset(struct omap3_scm_s *s)
3498 padconfs = (uint32 *)(s->padconfs);
3499 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x0);
3500 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x4);
3501 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x8);
3502 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0xc);
3503 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x10);
3504 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x14);
3505 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x18);
3506 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x1c);
3507 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x20);
3508 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x24);
3509 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x28);
3510 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x2c);
3511 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x30);
3512 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x34);
3513 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x38);
3514 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x3c);
3515 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x40);
3516 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x44);
3517 PADCONFS_VALUE(0,0,0,0,1,1,0,1,0,7,0x48);
3518 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x4c);
3519 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x50);
3520 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x54);
3521 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x58);
3522 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,0,0x5c);
3523 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x60);
3524 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x64);
3525 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x68);
3526 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x6c);
3527 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x70);
3528 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x74);
3529 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x78);
3530 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x7c);
3531 PADCONFS_VALUE(0,0,0,0,1,1,0,3,0,7,0x80);
3532 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x84);
3533 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x88);
3534 PADCONFS_VALUE(0,0,0,0,1,1,3,0,7,0,0x8c);
3535 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x90);
3536 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x94);
3537 PADCONFS_VALUE(0,0,0,0,1,1,1,0,7,0,0x98);
3538 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,7,0x9c);
3539 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0xa0);
3540 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0xa4);
3541 PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0xa8);
3542 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xac);
3543 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xb0);
3544 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xb4);
3545 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xb8);
3546 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xbc);
3547 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xc0);
3548 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xc4);
3549 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xc8);
3550 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xcc);
3551 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xd0);
3552 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xd4);
3553 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xd8);
3554 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xdc);
3555 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xe0);
3556 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xe4);
3557 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xe8);
3558 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xec);
3559 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xf0);
3560 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xf4);
3561 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xf8);
3562 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xfc);
3563 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x100);
3564 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x104);
3565 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x108);
3566 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x10c);
3567 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x110);
3568 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x114);
3569 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x118);
3570 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x11c);
3571 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x120);
3572 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x124);
3573 PADCONFS_VALUE(0,0,0,0,1,1,1,3,7,7,0x128);
3574 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x12c);
3575 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x130);
3576 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x134);
3577 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x138);
3578 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x13c);
3579 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x140);
3580 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x144);
3581 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x148);
3582 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x14c);
3583 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x150);
3584 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x154);
3585 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x158);
3586 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x15c);
3587 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x160);
3588 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x164);
3589 PADCONFS_VALUE(0,0,0,0,1,1,1,3,7,7,0x168);
3590 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x16c);
3591 PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0x170);
3592 PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0x174);
3593 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x178);
3594 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x17c);
3595 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x180);
3596 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x184);
3597 PADCONFS_VALUE(0,0,0,0,1,1,1,3,7,7,0x188);
3598 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x18c);
3599 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x190);
3600 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x194);
3601 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x198);
3602 PADCONFS_VALUE(0,0,0,0,1,1,1,3,7,7,0x19c);
3603 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x1a0);
3604 PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0x1a4);
3605 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x1a8);
3606 PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0x1ac);
3607 PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0x1b0);
3608 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1b4);
3609 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1b8);
3610 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1bc);
3611 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1c0);
3612 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1c4);
3613 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1c8);
3614 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1cc);
3615 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1d0);
3616 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1d4);
3617 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1d8);
3618 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1dc);
3619 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1e0);
3620 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1e4);
3621 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1e8);
3622 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1ec);
3623 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1f0);
3624 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1f4);
3625 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1f8);
3626 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1fc);
3627 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x200);
3628 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x204);
3629 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x208);
3630 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x20c);
3631 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x210);
3632 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x214);
3633 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x218);
3634 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x21c);
3635 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x220);
3636 PADCONFS_VALUE(0,0,0,0,1,1,3,1,0,0,0x224);
3637 PADCONFS_VALUE(0,0,0,0,1,1,0,1,0,0,0x228);
3638 PADCONFS_VALUE(0,0,0,0,1,1,0,1,0,0,0x22c);
3639 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x230);
3640 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x234);
3643 padconfs = (uint32 *)(s->general);
3644 s->general[1] = 0x4000000; /*0x4800 2274*/
3645 s->general[0x1c] = 0x1; /*0x4800 22e0*/
3646 s->general[0x75] = 0x7fc0; /*0x4800 2444*/
3647 s->general[0x76] = 0xaa; /*0x4800 2448*/
3648 s->general[0x7c] = 0x2700; /*0x4800 2460*/
3649 s->general[0x7d] = 0x300000; /*0x4800 2464*/
3650 s->general[0x7e] = 0x300000; /*0x4800 2468*/
3651 s->general[0x81] = 0xffff; /*0x4800 2474*/
3652 s->general[0x82] = 0xffff; /*0x4800 2478*/
3653 s->general[0x83] = 0xffff; /*0x4800 247c*/
3654 s->general[0x84] = 0x6; /*0x4800 2480*/
3655 s->general[0x85] = 0xffffffff; /*0x4800 2484*/
3656 s->general[0x86] = 0xffff; /*0x4800 2488*/
3657 s->general[0x87] = 0xffff; /*0x4800 248c*/
3658 s->general[0x88] = 0x1; /*0x4800 2490*/
3659 s->general[0x8b] = 0xffffffff; /*0x4800 249c*/
3660 s->general[0x8c] = 0xffff; /*0x4800 24a0*/
3661 s->general[0x8e] = 0xffff; /*0x4800 24a8*/
3662 s->general[0x8f] = 0xffff; /*0x4800 24ac*/
3663 s->general[0x91] = 0xffff; /*0x4800 24b4*/
3664 s->general[0x92] = 0xffff; /*0x4800 24b8*/
3665 s->general[0xac] = 0x109; /*0x4800 2520*/
3666 s->general[0xb2] = 0xffff; /*0x4800 2538*/
3667 s->general[0xb3] = 0xffff; /*0x4800 253c*/
3668 s->general[0xb4] = 0xffff; /*0x4800 2540*/
3669 PADCONFS_VALUE(0,0,0,0,1,1,3,3,4,4,0x368);
3670 PADCONFS_VALUE(0,0,0,0,1,1,3,3,4,4,0x36c);
3671 PADCONFS_VALUE(0,0,0,0,1,1,3,3,4,4,0x370);
3672 PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x374);
3673 PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x378);
3674 PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x37c);
3675 PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x380);
3676 PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x384);
3677 PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x388);
3681 padconfs = (uint32 *)(s->padconfs_wkup);
3682 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x0);
3683 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x4);
3684 PADCONFS_VALUE(0,0,0,0,1,1,3,0,0,0,0x8);
3685 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0xc);
3686 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x10);
3687 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x14);
3688 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x18);
3689 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1c);
3690 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x20);
3691 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x24);
3692 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x2c);
3695 s->general_wkup[0] = 0x66ff; /*0x4800 2A60*/
3699 static uint32_t omap3_scm_read8(void *opaque, target_phys_addr_t addr)
3701 struct omap3_scm_s *s = (struct omap3_scm_s *) opaque;
3706 return s->interface[addr];
3707 case 0x30 ... 0x26f:
3708 return s->padconfs[addr-0x30];
3709 case 0x270 ... 0x5ff:
3710 temp = (uint8_t *)s->general;
3711 return temp[addr-0x270];
3712 case 0x600 ... 0x9ff:
3713 return s->mem_wkup[addr-0x600];
3714 case 0xa00 ... 0xa5f:
3715 return s->padconfs_wkup[addr-0xa00];
3716 case 0xa60 ... 0xa7f:
3717 temp = (uint8_t *)s->general_wkup;
3718 return temp[addr-0xa60];
3722 printf("omap3_scm_read8 addr %x pc %x \n", addr,cpu_single_env->regs[15] );
3726 static uint32_t omap3_scm_read16(void *opaque, target_phys_addr_t addr)
3729 v = omap3_scm_read8(opaque, addr);
3730 v |= omap3_scm_read8(opaque, addr + 1) << 8;
3734 static uint32_t omap3_scm_read32(void *opaque, target_phys_addr_t addr)
3737 v = omap3_scm_read8(opaque, addr);
3738 v |= omap3_scm_read8(opaque, addr + 1) << 8;
3739 v |= omap3_scm_read8(opaque, addr + 2) << 16;
3740 v |= omap3_scm_read8(opaque, addr + 3) << 24;
3744 static void omap3_scm_write8(void *opaque, target_phys_addr_t addr,
3747 struct omap3_scm_s *s = (struct omap3_scm_s *) opaque;
3753 s->interface[addr] = value;
3755 case 0x30 ... 0x26f:
3756 s->padconfs[addr-0x30] = value;
3758 case 0x270 ... 0x5ff:
3759 temp = (uint8_t *)s->general;
3760 temp[addr-0x270] = value;
3762 case 0x600 ... 0x9ff:
3763 s->mem_wkup[addr-0x600] = value;
3765 case 0xa00 ... 0xa5f:
3766 s->padconfs_wkup[addr-0xa00] = value;
3768 case 0xa60 ... 0xa7f:
3769 temp = (uint8_t *)s->general_wkup;
3770 temp[addr-0xa60] = value;
3773 /*we do not care scm write*/
3774 printf("omap3_scm_write8 addr %x pc %x \n \n", addr,
3775 cpu_single_env->regs[15] - 0x80008000 + 0x80e80000);
3781 static void omap3_scm_write16(void *opaque, target_phys_addr_t addr,
3784 omap3_scm_write8(opaque, addr + 0, (value) & 0xff);
3785 omap3_scm_write8(opaque, addr + 1, (value >> 8) & 0xff);
3788 static void omap3_scm_write32(void *opaque, target_phys_addr_t addr,
3791 omap3_scm_write8(opaque, addr + 0, (value) & 0xff);
3792 omap3_scm_write8(opaque, addr + 1, (value >> 8) & 0xff);
3793 omap3_scm_write8(opaque, addr + 2, (value >> 16) & 0xff);
3794 omap3_scm_write8(opaque, addr + 3, (value >> 24) & 0xff);
3797 static CPUReadMemoryFunc *omap3_scm_readfn[] = {
3803 static CPUWriteMemoryFunc *omap3_scm_writefn[] = {
3809 static struct omap3_scm_s *omap3_scm_init(struct omap_target_agent_s *ta,
3810 struct omap_mpu_state_s *mpu)
3813 struct omap3_scm_s *s = (struct omap3_scm_s *) qemu_mallocz(sizeof(*s));
3819 iomemtype = l4_register_io_memory(0, omap3_scm_readfn,
3820 omap3_scm_writefn, s);
3821 omap_l4_attach(ta, 0, iomemtype);
3826 /*dummy SDRAM Memory Scheduler emulation*/
3829 struct omap_mpu_state_s *mpu;
3831 uint32 sms_sysconfig;
3832 uint32 sms_sysstatus;
3833 uint32 sms_rg_att[8];
3834 uint32 sms_rg_rdperm[8];
3835 uint32 sms_rg_wrperm[8];
3836 uint32 sms_rg_start[7];
3837 uint32 sms_rg_end[7];
3838 uint32 sms_security_control;
3839 uint32 sms_class_arbiter0;
3840 uint32 sms_class_arbiter1;
3841 uint32 sms_class_arbiter2;
3842 uint32 sms_interclass_arbiter;
3843 uint32 sms_class_rotation[3];
3844 uint32 sms_err_addr;
3845 uint32 sms_err_type;
3846 uint32 sms_pow_ctrl;
3847 uint32 sms_rot_control[12];
3848 uint32 sms_rot_size[12];
3849 uint32 sms_rot_physical_ba[12];
3852 static uint32_t omap3_sms_read32(void *opaque, target_phys_addr_t addr)
3854 struct omap3_sms_s *s = (struct omap3_sms_s *) opaque;
3859 return s->sms_sysconfig;
3861 return s->sms_sysstatus;
3870 return s->sms_rg_att[(addr-0x48)/0x20];
3879 return s->sms_rg_rdperm[(addr-0x50)/0x20];
3887 return s->sms_rg_wrperm[(addr-0x58)/0x20];
3895 return s->sms_rg_start[(addr-0x60)/0x20];
3904 return s->sms_rg_end[(addr-0x64)/0x20];
3906 return s->sms_security_control;
3908 return s->sms_class_arbiter0;
3910 return s->sms_class_arbiter1;
3912 return s->sms_class_arbiter2;
3914 return s->sms_interclass_arbiter;
3918 return s->sms_class_rotation[(addr-0x164)/4];
3920 return s->sms_err_addr;
3922 return s->sms_err_type;
3924 return s->sms_pow_ctrl;
3937 return s->sms_rot_control[(addr-0x180)/0x10];
3950 return s->sms_rot_size[(addr-0x184)/0x10];
3964 return s->sms_rot_size[(addr-0x188)/0x10];
3967 printf("omap3_sms_read32 addr %x \n", addr);
3972 static void omap3_sms_write32(void *opaque, target_phys_addr_t addr,
3975 struct omap3_sms_s *s = (struct omap3_sms_s *) opaque;
3984 s->sms_sysconfig = value & 0x1f;
3995 s->sms_rg_att[(addr-0x48)/0x20] = value;
4005 s->sms_rg_rdperm[(addr-0x50)/0x20] = value&0xffff;
4014 s->sms_rg_wrperm[(addr-0x58)/0x20] = value&0xffff;
4023 s->sms_rg_start[(addr-0x60)/0x20] = value;
4032 s->sms_rg_end[(addr-0x64)/0x20] = value;
4035 s->sms_security_control = value &0xfffffff;
4038 s->sms_class_arbiter0 = value;
4041 s->sms_class_arbiter1 = value;
4044 s->sms_class_arbiter2 = value;
4047 s->sms_interclass_arbiter = value;
4052 s->sms_class_rotation[(addr-0x164)/4] = value;
4055 s->sms_err_addr = value;
4058 s->sms_err_type = value;
4061 s->sms_pow_ctrl = value;
4075 s->sms_rot_control[(addr-0x180)/0x10] = value;
4089 s->sms_rot_size[(addr-0x184)/0x10] = value;
4104 s->sms_rot_size[(addr-0x188)/0x10] = value;
4107 printf("omap3_sms_write32 addr %x\n", addr);
4112 static CPUReadMemoryFunc *omap3_sms_readfn[] = {
4113 omap_badwidth_read32,
4114 omap_badwidth_read32,
4118 static CPUWriteMemoryFunc *omap3_sms_writefn[] = {
4119 omap_badwidth_write32,
4120 omap_badwidth_write32,
4124 static void omap3_sms_reset(struct omap3_sms_s *s)
4126 s->sms_sysconfig = 0x1;
4127 s->sms_class_arbiter0 = 0x500000;
4128 s->sms_class_arbiter1 = 0x500;
4129 s->sms_class_arbiter2 = 0x55000;
4130 s->sms_interclass_arbiter = 0x400040;
4131 s->sms_class_rotation[0] = 0x1;
4132 s->sms_class_rotation[1] = 0x1;
4133 s->sms_class_rotation[2] = 0x1;
4134 s->sms_pow_ctrl = 0x80;
4137 static struct omap3_sms_s *omap3_sms_init(struct omap_mpu_state_s *mpu)
4140 struct omap3_sms_s *s = (struct omap3_sms_s *) qemu_mallocz(sizeof(*s));
4146 iomemtype = cpu_register_io_memory(0, omap3_sms_readfn,
4147 omap3_sms_writefn, s);
4148 cpu_register_physical_memory(0x6c000000, 0x10000, iomemtype);
4153 static const struct dma_irq_map omap3_dma_irq_map[] = {
4154 {0, OMAP_INT_35XX_SDMA_IRQ0},
4155 {0, OMAP_INT_35XX_SDMA_IRQ1},
4156 {0, OMAP_INT_35XX_SDMA_IRQ2},
4157 {0, OMAP_INT_35XX_SDMA_IRQ3},
4160 static int omap3_validate_addr(struct omap_mpu_state_s *s,
4161 target_phys_addr_t addr)
4167 set the kind of memory connected to GPMC that we are trying to boot form.
4168 Uses SYS BOOT settings.
4170 void omap3_set_mem_type(struct omap_mpu_state_s *s,int bootfrom)
4172 s->omap3_scm->general[32] &= ~0x3f;
4174 case 0x0: /*GPMC_NOR*/
4175 s->omap3_scm->general[32] |= 7;
4177 case 0x1: /*GPMC_NAND*/
4178 s->omap3_scm->general[32] |= 1;
4181 s->omap3_scm->general[32] |= 8;
4184 s->omap3_scm->general[32] |= 0;
4187 s->omap3_scm->general[32] |= 17;
4190 s->omap3_scm->general[32] |= 3;
4195 void omap3_set_device_type(struct omap_mpu_state_s *s,int device_type)
4197 s->omap3_scm->general[32] &= ~(0x7 << 8);
4198 s->omap3_scm->general[32] |= (device_type & 0x7) << 8;
4201 struct omap_mpu_state_s *omap3530_mpu_init(unsigned long sdram_size,
4204 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
4205 qemu_mallocz(sizeof(struct omap_mpu_state_s));
4206 ram_addr_t sram_base, q2_base;
4208 qemu_irq dma_irqs[4];
4211 s->mpu_model = omap3530;
4212 s->env = cpu_init("cortex-a8-r2");
4214 fprintf(stderr, "Unable to find CPU definition\n");
4217 s->sdram_size = sdram_size;
4218 s->sram_size = OMAP3530_SRAM_SIZE;
4223 /* Memory-mapped stuff */
4225 q2_base = qemu_ram_alloc(s->sdram_size);
4226 cpu_register_physical_memory(OMAP3_Q2_BASE, s->sdram_size,
4227 (q2_base | IO_MEM_RAM));
4228 sram_base = qemu_ram_alloc(s->sram_size);
4229 cpu_register_physical_memory(OMAP3_SRAM_BASE, s->sram_size,
4230 (sram_base | IO_MEM_RAM));
4232 s->l4 = omap_l4_init(OMAP3_L4_BASE,
4233 sizeof(omap3_l4_agent_info)
4234 / sizeof(struct omap3_l4_agent_info_s));
4236 cpu_irq = arm_pic_init_cpu(s->env);
4237 s->ih[0] = omap2_inth_init(s, 0x48200000, 0x1000, 3, &s->irq[0],
4238 cpu_irq[ARM_PIC_CPU_IRQ],
4239 cpu_irq[ARM_PIC_CPU_FIQ],
4240 omap_findclk(s, "omap3_mpu_intc_fclk"),
4241 omap_findclk(s, "omap3_mpu_intc_iclk"));
4243 for (i = 0; i < 4; i++)
4245 s->irq[omap3_dma_irq_map[i].ih][omap3_dma_irq_map[i].intr];
4246 s->dma = omap_dma4_init(0x48056000, dma_irqs, s, 256, 32,
4247 omap_findclk(s, "omap3_sdma_fclk"),
4248 omap_findclk(s, "omap3_sdma_iclk"));
4249 s->port->addr_valid = omap3_validate_addr;
4251 /* Register SDRAM and SRAM ports for fast DMA transfers. */
4252 soc_dma_port_add_mem_ram(s->dma, q2_base, OMAP2_Q2_BASE, s->sdram_size);
4253 soc_dma_port_add_mem_ram(s->dma, sram_base, OMAP2_SRAM_BASE, s->sram_size);
4256 s->omap3_cm = omap3_cm_init(omap3_l4ta_init(s->l4, L4A_CM), NULL, NULL, NULL, s);
4258 s->omap3_prm = omap3_prm_init(omap3_l4ta_init(s->l4, L4A_PRM),
4259 s->irq[0][OMAP_INT_35XX_PRCM_MPU_IRQ],
4262 s->omap3_mpu_wdt = omap3_mpu_wdt_init(omap3_l4ta_init(s->l4, L4A_WDTIMER2),
4264 omap_findclk(s, "omap3_wkup_32k_fclk"),
4265 omap_findclk(s, "omap3_wkup_l4_iclk"),
4268 s->omap3_l3 = omap3_l3_init(OMAP3_L3_BASE,
4270 sizeof(omap3_l3_region)
4271 / sizeof(struct omap_l3_region_s));
4272 s->omap3_scm = omap3_scm_init(omap3_l4ta_init(s->l4, L4A_SCM), s);
4274 s->omap3_sms = omap3_sms_init(s);
4276 s->gptimer[0] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER1),
4277 s->irq[0][OMAP_INT_35XX_GPT1_IRQ],
4278 omap_findclk(s, "omap3_gp1_fclk"),
4279 omap_findclk(s, "omap3_wkup_l4_iclk"));
4280 s->gptimer[1] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER2),
4281 s->irq[0][OMAP_INT_35XX_GPT2_IRQ],
4282 omap_findclk(s, "omap3_gp2_fclk"),
4283 omap_findclk(s, "omap3_per_l4_iclk"));
4284 s->gptimer[2] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER3),
4285 s->irq[0][OMAP_INT_35XX_GPT3_IRQ],
4286 omap_findclk(s, "omap3_gp3_fclk"),
4287 omap_findclk(s, "omap3_per_l4_iclk"));
4288 s->gptimer[3] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER4),
4289 s->irq[0][OMAP_INT_35XX_GPT4_IRQ],
4290 omap_findclk(s, "omap3_gp4_fclk"),
4291 omap_findclk(s, "omap3_per_l4_iclk"));
4292 s->gptimer[4] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER5),
4293 s->irq[0][OMAP_INT_35XX_GPT5_IRQ],
4294 omap_findclk(s, "omap3_gp5_fclk"),
4295 omap_findclk(s, "omap3_per_l4_iclk"));
4296 s->gptimer[5] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER6),
4297 s->irq[0][OMAP_INT_35XX_GPT6_IRQ],
4298 omap_findclk(s, "omap3_gp6_fclk"),
4299 omap_findclk(s, "omap3_per_l4_iclk"));
4300 s->gptimer[6] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER7),
4301 s->irq[0][OMAP_INT_35XX_GPT7_IRQ],
4302 omap_findclk(s, "omap3_gp7_fclk"),
4303 omap_findclk(s, "omap3_per_l4_iclk"));
4304 s->gptimer[7] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER8),
4305 s->irq[0][OMAP_INT_35XX_GPT8_IRQ],
4306 omap_findclk(s, "omap3_gp8_fclk"),
4307 omap_findclk(s, "omap3_per_l4_iclk"));
4308 s->gptimer[8] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER9),
4309 s->irq[0][OMAP_INT_35XX_GPT9_IRQ],
4310 omap_findclk(s, "omap3_gp9_fclk"),
4311 omap_findclk(s, "omap3_per_l4_iclk"));
4312 s->gptimer[9] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER10),
4313 s->irq[0][OMAP_INT_35XX_GPT10_IRQ],
4314 omap_findclk(s, "omap3_gp10_fclk"),
4315 omap_findclk(s, "omap3_core_l4_iclk"));
4316 s->gptimer[10] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER11),
4317 s->irq[0][OMAP_INT_35XX_GPT11_IRQ],
4318 omap_findclk(s, "omap3_gp12_fclk"),
4319 omap_findclk(s, "omap3_core_l4_iclk"));
4320 s->gptimer[11] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER12),
4321 s->irq[0][OMAP_INT_35XX_GPT12_IRQ],
4322 omap_findclk(s, "omap3_gp12_fclk"),
4323 omap_findclk(s, "omap3_wkup_l4_iclk"));
4326 omap_synctimer_init(omap3_l4ta_init(s->l4, L4A_32KTIMER), s,
4327 omap_findclk(s, "omap3_sys_32k"), NULL);
4329 s->sdrc = omap_sdrc_init(0x6d000000);
4331 s->gpmc = omap_gpmc_init(s, 0x6e000000, s->irq[0][OMAP_INT_35XX_GPMC_IRQ]);
4334 s->uart[0] = omap2_uart_init(omap3_l4ta_init(s->l4, L4A_UART1),
4335 s->irq[0][OMAP_INT_35XX_UART1_IRQ],
4336 omap_findclk(s, "omap3_uart1_fclk"),
4337 omap_findclk(s, "omap3_uart1_iclk"),
4338 s->drq[OMAP35XX_DMA_UART1_TX],
4339 s->drq[OMAP35XX_DMA_UART1_RX], 0);
4340 s->uart[1] = omap2_uart_init(omap3_l4ta_init(s->l4, L4A_UART2),
4341 s->irq[0][OMAP_INT_35XX_UART2_IRQ],
4342 omap_findclk(s, "omap3_uart2_fclk"),
4343 omap_findclk(s, "omap3_uart2_iclk"),
4344 s->drq[OMAP35XX_DMA_UART2_TX],
4345 s->drq[OMAP35XX_DMA_UART2_RX], 0);
4346 s->uart[2] = omap2_uart_init(omap3_l4ta_init(s->l4, L4A_UART3),
4347 s->irq[0][OMAP_INT_35XX_UART3_IRQ],
4348 omap_findclk(s, "omap3_uart2_fclk"),
4349 omap_findclk(s, "omap3_uart3_iclk"),
4350 s->drq[OMAP35XX_DMA_UART3_TX],
4351 s->drq[OMAP35XX_DMA_UART3_RX], 0);
4353 s->dss = omap_dss_init(s, omap3_l4ta_init(s->l4, L4A_DSS),
4354 s->irq[0][OMAP_INT_35XX_DSS_IRQ], s->drq[OMAP24XX_DMA_DSS],
4355 NULL,NULL,NULL,NULL,NULL);
4357 s->gpif = omap3_gpif_init();
4358 omap3_gpio_init(s, s->gpif ,omap3_l4ta_init(s->l4, L4A_GPIO1),
4359 &s->irq[0][OMAP_INT_35XX_GPIO1_MPU_IRQ],
4361 omap3_gpio_init(s, s->gpif ,omap3_l4ta_init(s->l4, L4A_GPIO2),
4362 &s->irq[0][OMAP_INT_35XX_GPIO2_MPU_IRQ],
4364 omap3_gpio_init(s, s->gpif ,omap3_l4ta_init(s->l4, L4A_GPIO3),
4365 &s->irq[0][OMAP_INT_35XX_GPIO3_MPU_IRQ],
4367 omap3_gpio_init(s, s->gpif ,omap3_l4ta_init(s->l4, L4A_GPIO4),
4368 &s->irq[0][OMAP_INT_35XX_GPIO4_MPU_IRQ],
4370 omap3_gpio_init(s, s->gpif ,omap3_l4ta_init(s->l4, L4A_GPIO5),
4371 &s->irq[0][OMAP_INT_35XX_GPIO5_MPU_IRQ],
4373 omap3_gpio_init(s, s->gpif ,omap3_l4ta_init(s->l4, L4A_GPIO6),
4374 &s->irq[0][OMAP_INT_35XX_GPIO6_MPU_IRQ],
4377 omap_tap_init(omap3_l4ta_init(s->l4, L4A_TAP), s);
4379 s->omap3_mmc[0] = omap3_mmc_init(omap3_l4ta_init(s->l4, L4A_MMC1),
4380 s->irq[0][OMAP_INT_35XX_MMC1_IRQ],
4381 &s->drq[OMAP35XX_DMA_MMC1_TX],
4382 omap_findclk(s, "omap3_mmc1_fclk"),
4383 omap_findclk(s, "omap3_mmc1_iclk"));
4385 s->omap3_mmc[1] = omap3_mmc_init(omap3_l4ta_init(s->l4, L4A_MMC2),
4386 s->irq[0][OMAP_INT_35XX_MMC2_IRQ],
4387 &s->drq[OMAP35XX_DMA_MMC2_TX],
4388 omap_findclk(s, "omap3_mmc2_fclk"),
4389 omap_findclk(s, "omap3_mmc2_iclk"));
4391 s->omap3_mmc[2] = omap3_mmc_init(omap3_l4ta_init(s->l4, L4A_MMC3),
4392 s->irq[0][OMAP_INT_35XX_MMC3_IRQ],
4393 &s->drq[OMAP35XX_DMA_MMC3_TX],
4394 omap_findclk(s, "omap3_mmc3_fclk"),
4395 omap_findclk(s, "omap3_mmc3_iclk"));
4397 s->i2c[0] = omap3_i2c_init(omap3_l4ta_init(s->l4, L4A_I2C1),
4398 s->irq[0][OMAP_INT_35XX_I2C1_IRQ],
4399 &s->drq[OMAP35XX_DMA_I2C1_TX],
4400 omap_findclk(s, "omap3_i2c1_fclk"),
4401 omap_findclk(s, "omap3_i2c1_iclk"),
4403 s->i2c[1] = omap3_i2c_init(omap3_l4ta_init(s->l4, L4A_I2C2),
4404 s->irq[0][OMAP_INT_35XX_I2C2_IRQ],
4405 &s->drq[OMAP35XX_DMA_I2C2_TX],
4406 omap_findclk(s, "omap3_i2c2_fclk"),
4407 omap_findclk(s, "omap3_i2c2_iclk"),
4409 s->i2c[2] = omap3_i2c_init(omap3_l4ta_init(s->l4, L4A_I2C3),
4410 s->irq[0][OMAP_INT_35XX_I2C3_IRQ],
4411 &s->drq[OMAP35XX_DMA_I2C3_TX],
4412 omap_findclk(s, "omap3_i2c3_fclk"),
4413 omap_findclk(s, "omap3_i2c3_iclk"),
4416 s->omap3_usb = omap3_hsusb_init(omap3_l4ta_init(s->l4, L4A_USBHS_OTG),
4417 omap3_l4ta_init(s->l4, L4A_USBHS_HOST),
4418 omap3_l4ta_init(s->l4, L4A_USBHS_TLL),
4419 s->irq[0][OMAP_INT_35XX_HSUSB_MC],
4420 s->irq[0][OMAP_INT_35XX_HSUSB_DMA],
4421 s->irq[0][OMAP_INT_35XX_OHCI_IRQ],
4422 s->irq[0][OMAP_INT_35XX_EHCI_IRQ],
4423 s->irq[0][OMAP_INT_35XX_TLL_IRQ]);
4428 static inline uint32_t omap3_get_le32(const void *p)
4430 const uint8_t *q = (const uint8_t *)p;
4439 static inline uint32_t omap3_get_le16(const void *p)
4441 const uint8_t *q = (const uint8_t *)p;
4448 static inline void omap3_boot_setlsb(target_phys_addr_t addr, uint16_t lsb)
4452 cpu_physical_memory_read(addr, x, 4);
4454 x[1] = (lsb >> 8) & 0xff;
4455 cpu_physical_memory_write(addr, x, 4);
4458 struct omap3_boot_s {
4459 struct omap_mpu_state_s *mpu;
4468 target_phys_addr_t addr;
4472 static struct omap3_boot_s *omap3_boot_init(const uint8_t *data,
4474 struct omap_mpu_state_s *mpu)
4476 struct omap3_boot_s *s = qemu_mallocz(sizeof(struct omap3_boot_s));
4478 s->state = imagehdr;
4479 if (data_len >= 512) {
4480 if (!strncasecmp((char *)(data + 0x14), "chsettings", 10)
4481 || !strncasecmp((char *)(data + 0x14), "chram", 5)
4482 || !strncasecmp((char *)(data + 0x14), "chflash", 7)
4483 || !strncasecmp((char *)(data + 0x14), "chmmcsd", 7))
4484 s->state = confighdr;
4489 static void omap3_boot_chsettings(const uint8_t *chtoc)
4493 if (omap3_get_le32(chtoc) != 0xc0c0c0c1) {
4494 fprintf(stderr, "%s: invalid section verification key\n", __FUNCTION__);
4497 if (!chtoc[4]) { /* section disabled? */
4500 if (omap3_get_le16(chtoc + 5) != 0x0001) {
4501 fprintf(stderr, "%s: unsupported CH version (0x%04x)\n", __FUNCTION__,
4502 omap3_get_le16(chtoc));
4505 flags = omap3_get_le32(chtoc + 8);
4508 cpu_physical_memory_write(0x48307270, chtoc + 0x00, 4); /* PRM_CLKSRC_CTRL */
4509 cpu_physical_memory_write(0x48306d40, chtoc + 0x04, 4); /* PRM_CLKSEL */
4510 cpu_physical_memory_write(0x48005140, chtoc + 0x08, 4); /* CM_CLKSEL1_EMU */
4511 if (flags & (1 << 2)) { /* clock configuration */
4512 cpu_physical_memory_write(0x48004a40, chtoc + 0x0c, 4); /* CM_CLKSEL_CORE */
4513 cpu_physical_memory_write(0x48004c40, chtoc + 0x10, 4); /* CM_CLKSEL_WKUP */
4515 if (flags & (1 << 5)) { /* DPLL3 CORE */
4516 if (flags & (1 << 8)) { /* enable DPLL3 bypass */
4517 cpu_physical_memory_read(0x48004d00, (uint8_t *)&x, 4);
4518 x &= ~7; x |= 5; /* set DPLL3 bypass */
4519 cpu_physical_memory_write(0x48004d00, (uint8_t *)&x, 4);
4521 cpu_physical_memory_write(0x48004d00, chtoc + 0x14, 4); /* CM_CLKEN_PLL */
4522 cpu_physical_memory_write(0x48004d30, chtoc + 0x18, 4); /* CM_AUTOIDLE_PLL */
4523 cpu_physical_memory_write(0x48004d40, chtoc + 0x1c, 4); /* CM_CLKSEL1_PLL */
4525 if (flags & (1 << 3)) { /* DPLL4 PER */
4526 if (flags & (1 << 6)) { /* enable DPLL4 bypass */
4527 cpu_physical_memory_read(0x48004d00, (uint8_t *)&x, 4);
4528 x &= ~0x70000; x |= 0x10000; /* set DPLL4 in stop mode */
4529 cpu_physical_memory_write(0x48004d00, (uint8_t *)&x, 4);
4531 cpu_physical_memory_write(0x48004d00, chtoc + 0x20, 4); /* CM_CLKEN_PLL */
4532 cpu_physical_memory_write(0x48004d30, chtoc + 0x24, 4); /* CM_AUTOIDLE_PLL */
4533 cpu_physical_memory_write(0x48004d44, chtoc + 0x28, 4); /* CM_CLKSEL2_PLL */
4534 cpu_physical_memory_write(0x48004d48, chtoc + 0x2c, 4); /* CM_CLKSEL3_PLL */
4536 if (flags & (1 << 3)) { /* DPLL1 MPU */
4537 if (flags & (1 << 7)) { /* enable DPLL1 bypass */
4538 cpu_physical_memory_read(0x48004904, (uint8_t *)&x, 4);
4539 x &= ~7; x |= 5; /* set DPLL1 bypass */
4540 cpu_physical_memory_write(0x48004904, (uint8_t *)&x, 4);
4542 cpu_physical_memory_write(0x48004904, chtoc + 0x30, 4); /* CM_CLKEN_PLL_MPU */
4543 cpu_physical_memory_write(0x48004934, chtoc + 0x34, 4); /* CM_AUTOIDLE_PLL_MPU */
4544 cpu_physical_memory_write(0x48004940, chtoc + 0x38, 4); /* CM_CLKSEL1_PLL_MPU */
4545 cpu_physical_memory_write(0x48004944, chtoc + 0x3c, 4); /* CM_CLKSEL2_PLL_MPU */
4546 cpu_physical_memory_write(0x48004948, chtoc + 0x40, 4); /* CM_CLKSTCTRL_MPU */
4548 switch ((flags >> 24) & 0xff) {
4549 case 0x01: x = 0; break; /* 12MHz */
4550 case 0x02: x = 1; break; /* 13MHz */
4551 case 0x03: x = 5; break; /* 16.8MHz */
4552 case 0x04: x = 2; break; /* 19.2MHz */
4553 case 0x05: x = 3; break; /* 26MHz */
4554 case 0x06: x = 4; break; /* 38.4MHz */
4556 fprintf(stderr, "%s: unsupported SYS.CLK setting\n", __FUNCTION__);
4560 if (x != omap3_get_le32(chtoc + 0x04)) {
4561 fprintf(stderr, "%s: mismatch in SYS.CLK id and PRM_CLKSEL value\n", __FUNCTION__);
4566 static void omap3_boot_chram(const uint8_t *chtoc)
4568 if (omap3_get_le32(chtoc) != 0xc0c0c0c2) {
4569 fprintf(stderr, "%s: invalid section verification key\n", __FUNCTION__);
4572 if (!chtoc[4]) { /* section disabled? */
4575 omap3_boot_setlsb(0x6d000040, omap3_get_le16(chtoc + 0x0a)); /* SDRC_CS_CFG */
4576 omap3_boot_setlsb(0x6d000044, omap3_get_le16(chtoc + 0x0c)); /* SDRC_SHARING */
4577 cpu_physical_memory_write(0x6d000060, chtoc + 0x10, 4); /* SDRC_DLLA_CTRL */
4579 cpu_physical_memory_write(0x6d000080, chtoc + 0x20, 4); /* SDRC_MCFG_0 */
4580 omap3_boot_setlsb(0x6d000084, omap3_get_le16(chtoc + 0x24)); /* SDRC_MR_0 */
4581 omap3_boot_setlsb(0x6d000088, omap3_get_le16(chtoc + 0x26)); /* SDRC_EMR1_0? */
4582 omap3_boot_setlsb(0x6d00008c, omap3_get_le16(chtoc + 0x28)); /* SDRC_EMR2_0 */
4583 omap3_boot_setlsb(0x6d000090, omap3_get_le16(chtoc + 0x2a)); /* SDRC_EMR3_0? */
4584 cpu_physical_memory_write(0x6d00009c, chtoc + 0x2c, 4); /* SDRC_ACTIM_CTRLA_0 */
4585 cpu_physical_memory_write(0x6d0000a0, chtoc + 0x30, 4); /* SDRC_ACTIM_CTRLB_0 */
4586 cpu_physical_memory_write(0x6d0000a4, chtoc + 0x34, 4); /* SDRC_RFR_CTRL_0 */
4588 cpu_physical_memory_write(0x6d0000b0, chtoc + 0x20, 4); /* SDRC_MCFG_1 */
4589 omap3_boot_setlsb(0x6d0000b4, omap3_get_le16(chtoc + 0x24)); /* SDRC_MR_1 */
4590 omap3_boot_setlsb(0x6d0000b8, omap3_get_le16(chtoc + 0x26)); /* SDRC_EMR1_1? */
4591 omap3_boot_setlsb(0x6d0000bc, omap3_get_le16(chtoc + 0x28)); /* SDRC_EMR2_1 */
4592 omap3_boot_setlsb(0x6d0000c0, omap3_get_le16(chtoc + 0x2a)); /* SDRC_EMR3_1? */
4593 cpu_physical_memory_write(0x6d0000cc, chtoc + 0x2c, 4); /* SDRC_ACTIM_CTRLA_1 */
4594 cpu_physical_memory_write(0x6d0000d0, chtoc + 0x30, 4); /* SDRC_ACTIM_CTRLB_1 */
4595 cpu_physical_memory_write(0x6d0000d4, chtoc + 0x34, 4); /* SDRC_RFR_CTRL_1 */
4598 static void omap3_boot_chflash(const uint8_t *chtoc)
4600 if (omap3_get_le32(chtoc) != 0xc0c0c0c3) {
4601 fprintf(stderr, "%s: invalid section verification key\n", __FUNCTION__);
4604 if (!chtoc[4]) { /* section disabled? */
4607 omap3_boot_setlsb(0x6e000010, omap3_get_le16(chtoc + 0x08)); /* GPMC_SYSCONFIG */
4608 omap3_boot_setlsb(0x6e00001c, omap3_get_le16(chtoc + 0x0a)); /* GPMC_IRQENABLE */
4609 omap3_boot_setlsb(0x6e000040, omap3_get_le16(chtoc + 0x0c)); /* GPMC_TIMEOUT_CONTROL */
4610 omap3_boot_setlsb(0x6e000050, omap3_get_le16(chtoc + 0x0e)); /* GPMC_CONFIG */
4611 cpu_physical_memory_write(0x6e000060, chtoc + 0x10, 4); /* GPMC_CONFIG1_0 */
4612 cpu_physical_memory_write(0x6e000064, chtoc + 0x14, 4); /* GPMC_CONFIG2_0 */
4613 cpu_physical_memory_write(0x6e000068, chtoc + 0x18, 4); /* GPMC_CONFIG3_0 */
4614 cpu_physical_memory_write(0x6e00006c, chtoc + 0x1c, 4); /* GPMC_CONFIG4_0 */
4615 cpu_physical_memory_write(0x6e000070, chtoc + 0x20, 4); /* GPMC_CONFIG5_0 */
4616 cpu_physical_memory_write(0x6e000074, chtoc + 0x24, 4); /* GPMC_CONFIG6_0 */
4617 cpu_physical_memory_write(0x6e000078, chtoc + 0x28, 4); /* GPMC_CONFIG7_0 */
4618 cpu_physical_memory_write(0x6e0001e0, chtoc + 0x2c, 4); /* GPMC_PREFETCH_CONFIG1 */
4619 omap3_boot_setlsb(0x6e0001e4, omap3_get_le16(chtoc + 0x30)); /* GPMC_PREFETCH_CONFIG2 */
4620 omap3_boot_setlsb(0x6e0001ec, omap3_get_le16(chtoc + 0x32)); /* GPMC_PREFETCH_CONTROL */
4621 /* TODO: ECC config registers. The TRM spec is not clear on these */
4624 static void omap3_boot_chmmcsd(const uint8_t *chtoc)
4626 if (omap3_get_le32(chtoc) != 0xc0c0c0c4) {
4627 fprintf(stderr, "%s: invalid section verification key\n", __FUNCTION__);
4630 if (!chtoc[4]) { /* section disabled? */
4633 /* TODO: MMCHS registers */
4636 /* returns non-zero if more blocks are needed */
4637 static uint32_t omap3_boot_block(const uint8_t *data,
4639 struct omap3_boot_s *s)
4641 const uint8_t *p = 0;
4647 for (p = data; i >= 32 && omap3_get_le32(p) != 0xffffffff; p += 32, i -= 32) {
4648 if (!strcasecmp((char *)(p + 0x14), "chsettings"))
4649 omap3_boot_chsettings(p + omap3_get_le32(p));
4650 else if (!strcasecmp((char *)(p + 0x14), "chram"))
4651 omap3_boot_chram(p + omap3_get_le32(p));
4652 else if (!strcasecmp((char *)(p + 0x14), "chflash"))
4653 omap3_boot_chflash(p + omap3_get_le32(p));
4654 else if (!strcasecmp((char *)(p + 0x14), "chmmcsd"))
4655 omap3_boot_chmmcsd(p + omap3_get_le32(p));
4657 fprintf(stderr, "%s: unknown CHTOC item \"%s\"\n",
4658 __FUNCTION__, (char *)(p + 0x14));
4665 s->state = imagehdr;
4672 s->count = omap3_get_le32(data);
4673 s->addr = omap3_get_le32(data + 4);
4674 if (!s->count || !s->addr || s->addr == 0xffffffff)
4676 s->mpu->env->regs[15] = s->addr;
4682 i = (s->count >= data_len) ? data_len : s->count;
4683 cpu_physical_memory_write(s->addr, data, i);
4695 /* returns ptr to matching dir entry / zero entry or 0 if unsuccessful */
4696 static const uint8_t *omap3_scan_fat_dir_sector(const uint8_t *s)
4700 /* there are 0x10 items with 0x20 bytes per item */
4701 for (i = 0x10; i--; s += 0x20) {
4702 if (*s == 0xe5 || (s[0x0b] & 0x0f) == 0x0f) continue; /* erased/LFN */
4703 if (!*s || !strncasecmp((void *)s, "mlo ", 8+3)) return s;
4708 struct omap3_fat_drv_s {
4709 BlockDriverState *bs;
4710 uint8_t ptype; /* 12, 16, 32 */
4711 uint64_t c0; /* physical byte offset for data cluster 0 */
4712 uint64_t fat; /* physical byte offset for used FAT sector 0 */
4713 uint32_t spc; /* sectors per cluster */
4716 /* returns cluster data in the buffer and next cluster chain number
4717 or 0 if unsuccessful */
4718 static uint32_t omap3_read_fat_cluster(uint8_t *data,
4719 struct omap3_fat_drv_s *drv,
4723 uint32_t len = drv->spc * 0x200; /* number of bytes to read */
4725 switch (drv->ptype) { /* check for EOF */
4726 case 12: if (cl > 0xff0) return 0; break;
4727 case 16: if (cl > 0xfff0) return 0; break;
4728 case 32: if (cl > 0x0ffffff0) return 0; break;
4732 if (bdrv_pread(drv->bs,
4733 drv->c0 + ((drv->ptype == 32 ? cl - 2 : cl) * len),
4737 switch (drv->ptype) { /* determine next cluster # */
4739 fprintf(stderr, "%s: FAT12 parsing not implemented!\n",
4743 return (bdrv_pread(drv->bs, drv->fat + cl * 2, buf, 2) != 2)
4744 ? 0 : omap3_get_le16(buf);
4746 return (bdrv_pread(drv->bs, drv->fat + cl * 4, buf, 4) != 4)
4747 ? 0 : omap3_get_le32(buf) & 0x0fffffff;
4754 static int omap3_mmc_fat_boot(BlockDriverState *bs,
4757 struct omap_mpu_state_s *mpu)
4759 struct omap3_fat_drv_s drv;
4760 struct omap3_boot_s *boot;
4761 uint32_t i, j, cluster0, fatsize, bootsize, rootsize;
4762 const uint8_t *p, *q;
4766 /* determine FAT type */
4769 fatsize = omap3_get_le16(sector + 0x16);
4771 fatsize = omap3_get_le32(sector + 0x24);
4772 bootsize = omap3_get_le16(sector + 0x0e);
4773 cluster0 = bootsize + fatsize * sector[0x10];
4774 rootsize = omap3_get_le16(sector + 0x11);
4775 if (rootsize & 0x0f)
4778 drv.spc = sector[0x0d];
4779 i = omap3_get_le16(sector + 0x13);
4781 i = omap3_get_le32(sector + 0x20);
4782 i = (i - (cluster0 + rootsize)) / drv.spc;
4783 drv.ptype = (i < 4085) ? 12 : (i < 65525) ? 16 : 32;
4785 /* search for boot loader file */
4787 drv.fat = (bootsize + pstart) * 0x200;
4788 drv.c0 = (cluster0 + pstart) * 0x200;
4789 if (drv.ptype == 32) {
4790 i = omap3_get_le32(sector + 0x2c); /* first root cluster # */
4791 j = omap3_get_le16(sector + 0x28);
4793 drv.fat += (j & 0x0f) * fatsize * 0x200;
4794 cluster = qemu_mallocz(drv.spc * 0x200);
4795 for (p = 0; !p && (i = omap3_read_fat_cluster(cluster, &drv, i)); ) {
4796 for (j = drv.spc, q=cluster; j-- & !p; q += 0x200)
4797 p = omap3_scan_fat_dir_sector(q);
4799 memcpy(sector, q - 0x200, 0x200); /* save the sector */
4802 } else { /* FAT12/16 */
4803 for (i = rootsize, j = 0, p = 0; i-- && !p; j++) {
4804 if (bdrv_pread(drv.bs, drv.c0 + j * 0x200, sector, 0x200) != 0x200)
4806 p = omap3_scan_fat_dir_sector(sector);
4810 if (p && *p) { /* did we indeed find the file? */
4811 i = omap3_get_le16(p + 0x14);
4813 i |= omap3_get_le16(p + 0x1a);
4814 j = drv.spc * 0x200;
4815 uint8 *data = qemu_mallocz(j);
4816 if ((i = omap3_read_fat_cluster(data, &drv, i))) {
4817 boot = omap3_boot_init(data, j, mpu);
4818 boot->state = imagehdr; /* override CH detection */
4819 while (omap3_boot_block(data, j, boot))
4820 i = omap3_read_fat_cluster(data, &drv, i);
4821 result = (boot->state == done);
4824 fprintf(stderr, "%s: unable to read MLO file contents from SD card\n",
4828 fprintf(stderr, "%s: MLO file not found in the root directory\n",
4834 static int omap3_mmc_raw_boot(BlockDriverState *bs,
4836 struct omap_mpu_state_s *mpu)
4838 struct omap3_boot_s *boot;
4842 if (bdrv_pread(bs, 0, sector, 0x200) == 0x200) {
4843 boot = omap3_boot_init(sector, 0x200, mpu);
4844 if (boot->state == confighdr) { /* CH must be present for raw boot */
4845 while (omap3_boot_block(sector, 0x200, boot)) {
4846 if (bdrv_pread(bs, ++i, sector, 0x200) != 0x200) {
4847 fprintf(stderr, "%s: error trying to read sector %u on boot device\n",
4853 result = (boot->state == done);
4859 /* returns non-zero if successful, zero if unsuccessful */
4860 int omap3_mmc_boot(struct omap_mpu_state_s *s)
4862 BlockDriverState *bs;
4863 int sdindex = drive_get_index(IF_SD, 0, 0);
4864 uint8_t *sector, *p;
4868 /* very simple implementation for GP device boot,
4869 supports only two modes:
4870 1. MBR partition table with an active FAT partition
4871 and boot loader file (MLO) in its root directory, or
4872 2. CH sector located on first sector, followed by boot loader image */
4874 bs = drives_table[sdindex].bdrv;
4875 sector = qemu_mallocz(0x200);
4876 if (bdrv_pread(bs, 0, sector, 0x200) == 0x200) {
4877 for (i = 0, p = sector + 0x1be; i < 4; i++, p += 0x10)
4878 if (p[0] == 0x80) break;
4879 if (sector[0x1fe] == 0x55 && sector[0x1ff] == 0xaa /* signature */
4880 && i < 4 /* active partition exists */
4881 && (p[4] == 1 || p[4] == 4 || p[4] == 6 || p[4] == 11
4882 || p[4] == 12 || p[4] == 14 || p[4] == 15) /* FAT */
4883 && bdrv_pread(bs, (pstart = omap3_get_le32(p + 8)) * 0x200,
4884 sector, 0x200) == 0x200
4885 && sector[0x1fe] == 0x55 && sector[0x1ff] == 0xaa)
4886 result = omap3_mmc_fat_boot(bs, sector, pstart, s);
4888 result = omap3_mmc_raw_boot(bs, sector, s);
4895 /* returns non-zero if successful, zero if unsuccessful */
4896 int omap3_nand_boot(struct omap_mpu_state_s *mpu,
4897 struct nand_flash_s *nand,
4898 void (*nand_pread_f)(struct nand_flash_s *nand,
4903 struct omap3_boot_s *boot;
4908 data = qemu_mallocz(0x1000);
4909 nand_pread_f(nand, 0, data, 0x1000);
4910 boot = omap3_boot_init(data, 0x1000, mpu);
4911 while (omap3_boot_block(data, 0x1000, boot)) {
4913 nand_pread_f(nand, addr, data, 0x1000);
4915 result = (boot->state == done);