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 struct omap3_scm_s {
3475 struct omap_mpu_state_s *mpu;
3477 uint8 interface[48]; /*0x4800 2000*/
3478 uint8 padconfs[576]; /*0x4800 2030*/
3479 uint32 general[228]; /*0x4800 2270*/
3480 uint8 mem_wkup[1024]; /*0x4800 2600*/
3481 uint8 padconfs_wkup[84]; /*0x4800 2a00*/
3482 uint32 general_wkup[8]; /*0x4800 2a60*/
3485 #define PADCONFS_VALUE(wakeup0,wakeup1,offmode0,offmode1, \
3486 inputenable0,inputenable1,pupd0,pupd1,muxmode0,muxmode1,offset) \
3488 *(padconfs+offset/4) = (wakeup0 <<14)|(offmode0<<9)|(inputenable0<<8)|(pupd0<<3)|(muxmode0); \
3489 *(padconfs+offset/4) |= (wakeup1 <<30)|(offmode1<<25)|(inputenable1<<24)|(pupd1<<19)|(muxmode1<<16); \
3493 static void omap3_scm_reset(struct omap3_scm_s *s)
3496 padconfs = (uint32 *)(s->padconfs);
3497 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x0);
3498 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x4);
3499 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x8);
3500 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0xc);
3501 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x10);
3502 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x14);
3503 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x18);
3504 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x1c);
3505 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x20);
3506 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x24);
3507 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x28);
3508 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x2c);
3509 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x30);
3510 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x34);
3511 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x38);
3512 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x3c);
3513 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x40);
3514 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x44);
3515 PADCONFS_VALUE(0,0,0,0,1,1,0,1,0,7,0x48);
3516 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x4c);
3517 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x50);
3518 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x54);
3519 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x58);
3520 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,0,0x5c);
3521 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x60);
3522 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x64);
3523 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x68);
3524 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x6c);
3525 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x70);
3526 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x74);
3527 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x78);
3528 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x7c);
3529 PADCONFS_VALUE(0,0,0,0,1,1,0,3,0,7,0x80);
3530 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x84);
3531 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x88);
3532 PADCONFS_VALUE(0,0,0,0,1,1,3,0,7,0,0x8c);
3533 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x90);
3534 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x94);
3535 PADCONFS_VALUE(0,0,0,0,1,1,1,0,7,0,0x98);
3536 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,7,0x9c);
3537 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0xa0);
3538 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0xa4);
3539 PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0xa8);
3540 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xac);
3541 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xb0);
3542 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xb4);
3543 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xb8);
3544 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xbc);
3545 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xc0);
3546 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xc4);
3547 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xc8);
3548 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xcc);
3549 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xd0);
3550 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xd4);
3551 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xd8);
3552 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xdc);
3553 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xe0);
3554 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xe4);
3555 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xe8);
3556 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xec);
3557 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xf0);
3558 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xf4);
3559 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xf8);
3560 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xfc);
3561 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x100);
3562 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x104);
3563 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x108);
3564 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x10c);
3565 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x110);
3566 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x114);
3567 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x118);
3568 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x11c);
3569 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x120);
3570 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x124);
3571 PADCONFS_VALUE(0,0,0,0,1,1,1,3,7,7,0x128);
3572 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x12c);
3573 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x130);
3574 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x134);
3575 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x138);
3576 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x13c);
3577 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x140);
3578 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x144);
3579 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x148);
3580 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x14c);
3581 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x150);
3582 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x154);
3583 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x158);
3584 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x15c);
3585 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x160);
3586 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x164);
3587 PADCONFS_VALUE(0,0,0,0,1,1,1,3,7,7,0x168);
3588 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x16c);
3589 PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0x170);
3590 PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0x174);
3591 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x178);
3592 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x17c);
3593 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x180);
3594 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x184);
3595 PADCONFS_VALUE(0,0,0,0,1,1,1,3,7,7,0x188);
3596 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x18c);
3597 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x190);
3598 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x194);
3599 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x198);
3600 PADCONFS_VALUE(0,0,0,0,1,1,1,3,7,7,0x19c);
3601 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x1a0);
3602 PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0x1a4);
3603 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x1a8);
3604 PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0x1ac);
3605 PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0x1b0);
3606 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1b4);
3607 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1b8);
3608 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1bc);
3609 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1c0);
3610 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1c4);
3611 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1c8);
3612 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1cc);
3613 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1d0);
3614 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1d4);
3615 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1d8);
3616 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1dc);
3617 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1e0);
3618 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1e4);
3619 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1e8);
3620 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1ec);
3621 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1f0);
3622 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1f4);
3623 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1f8);
3624 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1fc);
3625 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x200);
3626 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x204);
3627 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x208);
3628 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x20c);
3629 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x210);
3630 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x214);
3631 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x218);
3632 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x21c);
3633 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x220);
3634 PADCONFS_VALUE(0,0,0,0,1,1,3,1,0,0,0x224);
3635 PADCONFS_VALUE(0,0,0,0,1,1,0,1,0,0,0x228);
3636 PADCONFS_VALUE(0,0,0,0,1,1,0,1,0,0,0x22c);
3637 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x230);
3638 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x234);
3640 padconfs = (uint32 *)(s->general);
3641 memset(s->general, 0, sizeof(s->general));
3642 s->general[0x01] = 0x4000000; /* CONTROL_DEVCONF_0 */
3643 s->general[0x1c] = 0x1; /* 0x480022e0?? */
3644 s->general[0x20] = 0x30f; /* CONTROL_STATUS:
3645 * - device type = GP Device
3646 * - sys_boot = NAND, USB, UART3, MMC1 */
3647 s->general[0x75] = 0x7fc0; /* CONTROL_PROG_IO0 */
3648 s->general[0x76] = 0xaa; /* CONTROL_PROG_IO1 */
3649 s->general[0x7c] = 0x2700; /* CONTROL_SDRC_SHARING */
3650 s->general[0x7d] = 0x300000; /* CONTROL_SDRC_MCFG0 */
3651 s->general[0x7e] = 0x300000; /* CONTROL_SDRC_MCFG1 */
3652 s->general[0x81] = 0xffff; /* CONTROL_MODEM_GPMC_DT_FW_REQ_INFO */
3653 s->general[0x82] = 0xffff; /* CONTROL_MODEM_GPMC_DT_FW_RD */
3654 s->general[0x83] = 0xffff; /* CONTROL_MODEM_GPMC_DT_FW_WR */
3655 s->general[0x84] = 0x6; /* CONTROL_MODEM_GPMC_BOOT_CODE */
3656 s->general[0x85] = 0xffffffff; /* CONTROL_MODEM_SMS_RG_ATT1 */
3657 s->general[0x86] = 0xffff; /* CONTROL_MODEM_SMS_RG_RDPERM1 */
3658 s->general[0x87] = 0xffff; /* CONTROL_MODEM_SMS_RG_WRPERM1 */
3659 s->general[0x88] = 0x1; /* CONTROL_MODEM_D2D_FW_DEBUG_MODE */
3660 s->general[0x8b] = 0xffffffff; /* CONTROL_DPF_OCM_RAM_FW_REQINFO */
3661 s->general[0x8c] = 0xffff; /* CONTROL_DPF_OCM_RAM_FW_WR */
3662 s->general[0x8e] = 0xffff; /* CONTROL_DPF_REGION4_GPMC_FW_REQINFO */
3663 s->general[0x8f] = 0xffff; /* CONTROL_DPF_REGION4_GPMC_FW_WR */
3664 s->general[0x91] = 0xffff; /* CONTROL_DPF_REGION1_IVA2_FW_REQINFO */
3665 s->general[0x92] = 0xffff; /* CONTROL_DPF_REGION1_IVA2_FW_WR */
3666 s->general[0xac] = 0x109; /* CONTROL_PBIAS_LITE */
3667 s->general[0xb2] = 0xffff; /* CONTROL_DPF_MAD2D_FW_ADDR_MATCH */
3668 s->general[0xb3] = 0xffff; /* CONTROL_DPF_MAD2D_FW_REQINFO */
3669 s->general[0xb4] = 0xffff; /* CONTROL_DPF_MAD2D_FW_WR */
3670 PADCONFS_VALUE(0,0,0,0,1,1,3,3,4,4,0x368); /* PADCONF_ETK_CLK */
3671 PADCONFS_VALUE(0,0,0,0,1,1,3,3,4,4,0x36c); /* PADCONF_ETK_D0 */
3672 PADCONFS_VALUE(0,0,0,0,1,1,3,3,4,4,0x370); /* PADCONF_ETK_D2 */
3673 PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x374); /* PADCONF_ETK_D4 */
3674 PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x378); /* PADCONF_ETK_D6 */
3675 PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x37c); /* PADCONF_ETK_D8 */
3676 PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x380); /* PADCONF_ETK_D10 */
3677 PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x384); /* PADCONF_ETK_D12 */
3678 PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x388); /* PADCONF_ETK_D14 */
3680 padconfs = (uint32 *)(s->padconfs_wkup);
3681 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x0);
3682 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x4);
3683 PADCONFS_VALUE(0,0,0,0,1,1,3,0,0,0,0x8);
3684 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0xc);
3685 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x10);
3686 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x14);
3687 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x18);
3688 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1c);
3689 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x20);
3690 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x24);
3691 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x2c);
3693 s->general_wkup[0] = 0x66ff; /* 0x48002A60?? */
3696 static uint32_t omap3_scm_read8(void *opaque, target_phys_addr_t addr)
3698 struct omap3_scm_s *s = (struct omap3_scm_s *) opaque;
3703 return s->interface[addr];
3704 case 0x30 ... 0x26f:
3705 return s->padconfs[addr-0x30];
3706 case 0x270 ... 0x5ff:
3707 temp = (uint8_t *)s->general;
3708 return temp[addr-0x270];
3709 case 0x600 ... 0x9ff:
3710 return s->mem_wkup[addr-0x600];
3711 case 0xa00 ... 0xa5f:
3712 return s->padconfs_wkup[addr-0xa00];
3713 case 0xa60 ... 0xa7f:
3714 temp = (uint8_t *)s->general_wkup;
3715 return temp[addr-0xa60];
3719 printf("omap3_scm_read8 addr %x pc %x \n", addr,cpu_single_env->regs[15] );
3723 static uint32_t omap3_scm_read16(void *opaque, target_phys_addr_t addr)
3726 v = omap3_scm_read8(opaque, addr);
3727 v |= omap3_scm_read8(opaque, addr + 1) << 8;
3731 static uint32_t omap3_scm_read32(void *opaque, target_phys_addr_t addr)
3734 v = omap3_scm_read8(opaque, addr);
3735 v |= omap3_scm_read8(opaque, addr + 1) << 8;
3736 v |= omap3_scm_read8(opaque, addr + 2) << 16;
3737 v |= omap3_scm_read8(opaque, addr + 3) << 24;
3741 static void omap3_scm_write8(void *opaque, target_phys_addr_t addr,
3744 struct omap3_scm_s *s = (struct omap3_scm_s *) opaque;
3750 s->interface[addr] = value;
3752 case 0x30 ... 0x26f:
3753 s->padconfs[addr-0x30] = value;
3755 case 0x270 ... 0x5ff:
3756 temp = (uint8_t *)s->general;
3757 temp[addr-0x270] = value;
3759 case 0x600 ... 0x9ff:
3760 s->mem_wkup[addr-0x600] = value;
3762 case 0xa00 ... 0xa5f:
3763 s->padconfs_wkup[addr-0xa00] = value;
3765 case 0xa60 ... 0xa7f:
3766 temp = (uint8_t *)s->general_wkup;
3767 temp[addr-0xa60] = value;
3770 /*we do not care scm write*/
3771 printf("omap3_scm_write8 addr %x pc %x \n \n", addr,
3772 cpu_single_env->regs[15] - 0x80008000 + 0x80e80000);
3778 static void omap3_scm_write16(void *opaque, target_phys_addr_t addr,
3781 omap3_scm_write8(opaque, addr + 0, (value) & 0xff);
3782 omap3_scm_write8(opaque, addr + 1, (value >> 8) & 0xff);
3785 static void omap3_scm_write32(void *opaque, target_phys_addr_t addr,
3788 omap3_scm_write8(opaque, addr + 0, (value) & 0xff);
3789 omap3_scm_write8(opaque, addr + 1, (value >> 8) & 0xff);
3790 omap3_scm_write8(opaque, addr + 2, (value >> 16) & 0xff);
3791 omap3_scm_write8(opaque, addr + 3, (value >> 24) & 0xff);
3794 static CPUReadMemoryFunc *omap3_scm_readfn[] = {
3800 static CPUWriteMemoryFunc *omap3_scm_writefn[] = {
3806 static struct omap3_scm_s *omap3_scm_init(struct omap_target_agent_s *ta,
3807 struct omap_mpu_state_s *mpu)
3810 struct omap3_scm_s *s = (struct omap3_scm_s *) qemu_mallocz(sizeof(*s));
3816 iomemtype = l4_register_io_memory(0, omap3_scm_readfn,
3817 omap3_scm_writefn, s);
3818 omap_l4_attach(ta, 0, iomemtype);
3823 /*dummy SDRAM Memory Scheduler emulation*/
3826 struct omap_mpu_state_s *mpu;
3828 uint32 sms_sysconfig;
3829 uint32 sms_sysstatus;
3830 uint32 sms_rg_att[8];
3831 uint32 sms_rg_rdperm[8];
3832 uint32 sms_rg_wrperm[8];
3833 uint32 sms_rg_start[7];
3834 uint32 sms_rg_end[7];
3835 uint32 sms_security_control;
3836 uint32 sms_class_arbiter0;
3837 uint32 sms_class_arbiter1;
3838 uint32 sms_class_arbiter2;
3839 uint32 sms_interclass_arbiter;
3840 uint32 sms_class_rotation[3];
3841 uint32 sms_err_addr;
3842 uint32 sms_err_type;
3843 uint32 sms_pow_ctrl;
3844 uint32 sms_rot_control[12];
3845 uint32 sms_rot_size[12];
3846 uint32 sms_rot_physical_ba[12];
3849 static uint32_t omap3_sms_read32(void *opaque, target_phys_addr_t addr)
3851 struct omap3_sms_s *s = (struct omap3_sms_s *) opaque;
3856 return s->sms_sysconfig;
3858 return s->sms_sysstatus;
3867 return s->sms_rg_att[(addr-0x48)/0x20];
3876 return s->sms_rg_rdperm[(addr-0x50)/0x20];
3884 return s->sms_rg_wrperm[(addr-0x58)/0x20];
3892 return s->sms_rg_start[(addr-0x60)/0x20];
3901 return s->sms_rg_end[(addr-0x64)/0x20];
3903 return s->sms_security_control;
3905 return s->sms_class_arbiter0;
3907 return s->sms_class_arbiter1;
3909 return s->sms_class_arbiter2;
3911 return s->sms_interclass_arbiter;
3915 return s->sms_class_rotation[(addr-0x164)/4];
3917 return s->sms_err_addr;
3919 return s->sms_err_type;
3921 return s->sms_pow_ctrl;
3934 return s->sms_rot_control[(addr-0x180)/0x10];
3947 return s->sms_rot_size[(addr-0x184)/0x10];
3961 return s->sms_rot_size[(addr-0x188)/0x10];
3964 printf("omap3_sms_read32 addr %x \n", addr);
3969 static void omap3_sms_write32(void *opaque, target_phys_addr_t addr,
3972 struct omap3_sms_s *s = (struct omap3_sms_s *) opaque;
3981 s->sms_sysconfig = value & 0x1f;
3992 s->sms_rg_att[(addr-0x48)/0x20] = value;
4002 s->sms_rg_rdperm[(addr-0x50)/0x20] = value&0xffff;
4011 s->sms_rg_wrperm[(addr-0x58)/0x20] = value&0xffff;
4020 s->sms_rg_start[(addr-0x60)/0x20] = value;
4029 s->sms_rg_end[(addr-0x64)/0x20] = value;
4032 s->sms_security_control = value &0xfffffff;
4035 s->sms_class_arbiter0 = value;
4038 s->sms_class_arbiter1 = value;
4041 s->sms_class_arbiter2 = value;
4044 s->sms_interclass_arbiter = value;
4049 s->sms_class_rotation[(addr-0x164)/4] = value;
4052 s->sms_err_addr = value;
4055 s->sms_err_type = value;
4058 s->sms_pow_ctrl = value;
4072 s->sms_rot_control[(addr-0x180)/0x10] = value;
4086 s->sms_rot_size[(addr-0x184)/0x10] = value;
4101 s->sms_rot_size[(addr-0x188)/0x10] = value;
4104 printf("omap3_sms_write32 addr %x\n", addr);
4109 static CPUReadMemoryFunc *omap3_sms_readfn[] = {
4110 omap_badwidth_read32,
4111 omap_badwidth_read32,
4115 static CPUWriteMemoryFunc *omap3_sms_writefn[] = {
4116 omap_badwidth_write32,
4117 omap_badwidth_write32,
4121 static void omap3_sms_reset(struct omap3_sms_s *s)
4123 s->sms_sysconfig = 0x1;
4124 s->sms_class_arbiter0 = 0x500000;
4125 s->sms_class_arbiter1 = 0x500;
4126 s->sms_class_arbiter2 = 0x55000;
4127 s->sms_interclass_arbiter = 0x400040;
4128 s->sms_class_rotation[0] = 0x1;
4129 s->sms_class_rotation[1] = 0x1;
4130 s->sms_class_rotation[2] = 0x1;
4131 s->sms_pow_ctrl = 0x80;
4134 static struct omap3_sms_s *omap3_sms_init(struct omap_mpu_state_s *mpu)
4137 struct omap3_sms_s *s = (struct omap3_sms_s *) qemu_mallocz(sizeof(*s));
4143 iomemtype = cpu_register_io_memory(0, omap3_sms_readfn,
4144 omap3_sms_writefn, s);
4145 cpu_register_physical_memory(0x6c000000, 0x10000, iomemtype);
4150 static const struct dma_irq_map omap3_dma_irq_map[] = {
4151 {0, OMAP_INT_35XX_SDMA_IRQ0},
4152 {0, OMAP_INT_35XX_SDMA_IRQ1},
4153 {0, OMAP_INT_35XX_SDMA_IRQ2},
4154 {0, OMAP_INT_35XX_SDMA_IRQ3},
4157 static int omap3_validate_addr(struct omap_mpu_state_s *s,
4158 target_phys_addr_t addr)
4163 struct omap_mpu_state_s *omap3530_mpu_init(unsigned long sdram_size,
4166 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
4167 qemu_mallocz(sizeof(struct omap_mpu_state_s));
4168 ram_addr_t sram_base, q2_base;
4170 qemu_irq dma_irqs[4];
4173 s->mpu_model = omap3530;
4174 s->env = cpu_init("cortex-a8-r2");
4176 fprintf(stderr, "Unable to find CPU definition\n");
4179 s->sdram_size = sdram_size;
4180 s->sram_size = OMAP3530_SRAM_SIZE;
4185 /* Memory-mapped stuff */
4187 q2_base = qemu_ram_alloc(s->sdram_size);
4188 cpu_register_physical_memory(OMAP3_Q2_BASE, s->sdram_size,
4189 (q2_base | IO_MEM_RAM));
4190 sram_base = qemu_ram_alloc(s->sram_size);
4191 cpu_register_physical_memory(OMAP3_SRAM_BASE, s->sram_size,
4192 (sram_base | IO_MEM_RAM));
4194 s->l4 = omap_l4_init(OMAP3_L4_BASE,
4195 sizeof(omap3_l4_agent_info)
4196 / sizeof(struct omap3_l4_agent_info_s));
4198 cpu_irq = arm_pic_init_cpu(s->env);
4199 s->ih[0] = omap2_inth_init(s, 0x48200000, 0x1000, 3, &s->irq[0],
4200 cpu_irq[ARM_PIC_CPU_IRQ],
4201 cpu_irq[ARM_PIC_CPU_FIQ],
4202 omap_findclk(s, "omap3_mpu_intc_fclk"),
4203 omap_findclk(s, "omap3_mpu_intc_iclk"));
4205 for (i = 0; i < 4; i++)
4207 s->irq[omap3_dma_irq_map[i].ih][omap3_dma_irq_map[i].intr];
4208 s->dma = omap_dma4_init(0x48056000, dma_irqs, s, 256, 32,
4209 omap_findclk(s, "omap3_sdma_fclk"),
4210 omap_findclk(s, "omap3_sdma_iclk"));
4211 s->port->addr_valid = omap3_validate_addr;
4213 /* Register SDRAM and SRAM ports for fast DMA transfers. */
4214 soc_dma_port_add_mem_ram(s->dma, q2_base, OMAP2_Q2_BASE, s->sdram_size);
4215 soc_dma_port_add_mem_ram(s->dma, sram_base, OMAP2_SRAM_BASE, s->sram_size);
4218 s->omap3_cm = omap3_cm_init(omap3_l4ta_init(s->l4, L4A_CM), NULL, NULL, NULL, s);
4220 s->omap3_prm = omap3_prm_init(omap3_l4ta_init(s->l4, L4A_PRM),
4221 s->irq[0][OMAP_INT_35XX_PRCM_MPU_IRQ],
4224 s->omap3_mpu_wdt = omap3_mpu_wdt_init(omap3_l4ta_init(s->l4, L4A_WDTIMER2),
4226 omap_findclk(s, "omap3_wkup_32k_fclk"),
4227 omap_findclk(s, "omap3_wkup_l4_iclk"),
4230 s->omap3_l3 = omap3_l3_init(OMAP3_L3_BASE,
4232 sizeof(omap3_l3_region)
4233 / sizeof(struct omap_l3_region_s));
4234 s->omap3_scm = omap3_scm_init(omap3_l4ta_init(s->l4, L4A_SCM), s);
4236 s->omap3_sms = omap3_sms_init(s);
4238 s->gptimer[0] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER1),
4239 s->irq[0][OMAP_INT_35XX_GPT1_IRQ],
4240 omap_findclk(s, "omap3_gp1_fclk"),
4241 omap_findclk(s, "omap3_wkup_l4_iclk"));
4242 s->gptimer[1] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER2),
4243 s->irq[0][OMAP_INT_35XX_GPT2_IRQ],
4244 omap_findclk(s, "omap3_gp2_fclk"),
4245 omap_findclk(s, "omap3_per_l4_iclk"));
4246 s->gptimer[2] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER3),
4247 s->irq[0][OMAP_INT_35XX_GPT3_IRQ],
4248 omap_findclk(s, "omap3_gp3_fclk"),
4249 omap_findclk(s, "omap3_per_l4_iclk"));
4250 s->gptimer[3] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER4),
4251 s->irq[0][OMAP_INT_35XX_GPT4_IRQ],
4252 omap_findclk(s, "omap3_gp4_fclk"),
4253 omap_findclk(s, "omap3_per_l4_iclk"));
4254 s->gptimer[4] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER5),
4255 s->irq[0][OMAP_INT_35XX_GPT5_IRQ],
4256 omap_findclk(s, "omap3_gp5_fclk"),
4257 omap_findclk(s, "omap3_per_l4_iclk"));
4258 s->gptimer[5] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER6),
4259 s->irq[0][OMAP_INT_35XX_GPT6_IRQ],
4260 omap_findclk(s, "omap3_gp6_fclk"),
4261 omap_findclk(s, "omap3_per_l4_iclk"));
4262 s->gptimer[6] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER7),
4263 s->irq[0][OMAP_INT_35XX_GPT7_IRQ],
4264 omap_findclk(s, "omap3_gp7_fclk"),
4265 omap_findclk(s, "omap3_per_l4_iclk"));
4266 s->gptimer[7] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER8),
4267 s->irq[0][OMAP_INT_35XX_GPT8_IRQ],
4268 omap_findclk(s, "omap3_gp8_fclk"),
4269 omap_findclk(s, "omap3_per_l4_iclk"));
4270 s->gptimer[8] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER9),
4271 s->irq[0][OMAP_INT_35XX_GPT9_IRQ],
4272 omap_findclk(s, "omap3_gp9_fclk"),
4273 omap_findclk(s, "omap3_per_l4_iclk"));
4274 s->gptimer[9] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER10),
4275 s->irq[0][OMAP_INT_35XX_GPT10_IRQ],
4276 omap_findclk(s, "omap3_gp10_fclk"),
4277 omap_findclk(s, "omap3_core_l4_iclk"));
4278 s->gptimer[10] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER11),
4279 s->irq[0][OMAP_INT_35XX_GPT11_IRQ],
4280 omap_findclk(s, "omap3_gp12_fclk"),
4281 omap_findclk(s, "omap3_core_l4_iclk"));
4282 s->gptimer[11] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER12),
4283 s->irq[0][OMAP_INT_35XX_GPT12_IRQ],
4284 omap_findclk(s, "omap3_gp12_fclk"),
4285 omap_findclk(s, "omap3_wkup_l4_iclk"));
4288 omap_synctimer_init(omap3_l4ta_init(s->l4, L4A_32KTIMER), s,
4289 omap_findclk(s, "omap3_sys_32k"), NULL);
4291 s->sdrc = omap_sdrc_init(0x6d000000);
4293 s->gpmc = omap_gpmc_init(s, 0x6e000000, s->irq[0][OMAP_INT_35XX_GPMC_IRQ]);
4296 s->uart[0] = omap2_uart_init(omap3_l4ta_init(s->l4, L4A_UART1),
4297 s->irq[0][OMAP_INT_35XX_UART1_IRQ],
4298 omap_findclk(s, "omap3_uart1_fclk"),
4299 omap_findclk(s, "omap3_uart1_iclk"),
4300 s->drq[OMAP35XX_DMA_UART1_TX],
4301 s->drq[OMAP35XX_DMA_UART1_RX], 0);
4302 s->uart[1] = omap2_uart_init(omap3_l4ta_init(s->l4, L4A_UART2),
4303 s->irq[0][OMAP_INT_35XX_UART2_IRQ],
4304 omap_findclk(s, "omap3_uart2_fclk"),
4305 omap_findclk(s, "omap3_uart2_iclk"),
4306 s->drq[OMAP35XX_DMA_UART2_TX],
4307 s->drq[OMAP35XX_DMA_UART2_RX], 0);
4308 s->uart[2] = omap2_uart_init(omap3_l4ta_init(s->l4, L4A_UART3),
4309 s->irq[0][OMAP_INT_35XX_UART3_IRQ],
4310 omap_findclk(s, "omap3_uart2_fclk"),
4311 omap_findclk(s, "omap3_uart3_iclk"),
4312 s->drq[OMAP35XX_DMA_UART3_TX],
4313 s->drq[OMAP35XX_DMA_UART3_RX], 0);
4315 s->dss = omap_dss_init(s, omap3_l4ta_init(s->l4, L4A_DSS),
4316 s->irq[0][OMAP_INT_35XX_DSS_IRQ], s->drq[OMAP24XX_DMA_DSS],
4317 NULL,NULL,NULL,NULL,NULL);
4319 s->gpif = omap3_gpif_init();
4320 omap3_gpio_init(s, s->gpif ,omap3_l4ta_init(s->l4, L4A_GPIO1),
4321 &s->irq[0][OMAP_INT_35XX_GPIO1_MPU_IRQ],
4323 omap3_gpio_init(s, s->gpif ,omap3_l4ta_init(s->l4, L4A_GPIO2),
4324 &s->irq[0][OMAP_INT_35XX_GPIO2_MPU_IRQ],
4326 omap3_gpio_init(s, s->gpif ,omap3_l4ta_init(s->l4, L4A_GPIO3),
4327 &s->irq[0][OMAP_INT_35XX_GPIO3_MPU_IRQ],
4329 omap3_gpio_init(s, s->gpif ,omap3_l4ta_init(s->l4, L4A_GPIO4),
4330 &s->irq[0][OMAP_INT_35XX_GPIO4_MPU_IRQ],
4332 omap3_gpio_init(s, s->gpif ,omap3_l4ta_init(s->l4, L4A_GPIO5),
4333 &s->irq[0][OMAP_INT_35XX_GPIO5_MPU_IRQ],
4335 omap3_gpio_init(s, s->gpif ,omap3_l4ta_init(s->l4, L4A_GPIO6),
4336 &s->irq[0][OMAP_INT_35XX_GPIO6_MPU_IRQ],
4339 omap_tap_init(omap3_l4ta_init(s->l4, L4A_TAP), s);
4341 s->omap3_mmc[0] = omap3_mmc_init(omap3_l4ta_init(s->l4, L4A_MMC1),
4342 s->irq[0][OMAP_INT_35XX_MMC1_IRQ],
4343 &s->drq[OMAP35XX_DMA_MMC1_TX],
4344 omap_findclk(s, "omap3_mmc1_fclk"),
4345 omap_findclk(s, "omap3_mmc1_iclk"));
4347 s->omap3_mmc[1] = omap3_mmc_init(omap3_l4ta_init(s->l4, L4A_MMC2),
4348 s->irq[0][OMAP_INT_35XX_MMC2_IRQ],
4349 &s->drq[OMAP35XX_DMA_MMC2_TX],
4350 omap_findclk(s, "omap3_mmc2_fclk"),
4351 omap_findclk(s, "omap3_mmc2_iclk"));
4353 s->omap3_mmc[2] = omap3_mmc_init(omap3_l4ta_init(s->l4, L4A_MMC3),
4354 s->irq[0][OMAP_INT_35XX_MMC3_IRQ],
4355 &s->drq[OMAP35XX_DMA_MMC3_TX],
4356 omap_findclk(s, "omap3_mmc3_fclk"),
4357 omap_findclk(s, "omap3_mmc3_iclk"));
4359 s->i2c[0] = omap3_i2c_init(omap3_l4ta_init(s->l4, L4A_I2C1),
4360 s->irq[0][OMAP_INT_35XX_I2C1_IRQ],
4361 &s->drq[OMAP35XX_DMA_I2C1_TX],
4362 omap_findclk(s, "omap3_i2c1_fclk"),
4363 omap_findclk(s, "omap3_i2c1_iclk"),
4365 s->i2c[1] = omap3_i2c_init(omap3_l4ta_init(s->l4, L4A_I2C2),
4366 s->irq[0][OMAP_INT_35XX_I2C2_IRQ],
4367 &s->drq[OMAP35XX_DMA_I2C2_TX],
4368 omap_findclk(s, "omap3_i2c2_fclk"),
4369 omap_findclk(s, "omap3_i2c2_iclk"),
4371 s->i2c[2] = omap3_i2c_init(omap3_l4ta_init(s->l4, L4A_I2C3),
4372 s->irq[0][OMAP_INT_35XX_I2C3_IRQ],
4373 &s->drq[OMAP35XX_DMA_I2C3_TX],
4374 omap_findclk(s, "omap3_i2c3_fclk"),
4375 omap_findclk(s, "omap3_i2c3_iclk"),
4378 s->omap3_usb = omap3_hsusb_init(omap3_l4ta_init(s->l4, L4A_USBHS_OTG),
4379 omap3_l4ta_init(s->l4, L4A_USBHS_HOST),
4380 omap3_l4ta_init(s->l4, L4A_USBHS_TLL),
4381 s->irq[0][OMAP_INT_35XX_HSUSB_MC],
4382 s->irq[0][OMAP_INT_35XX_HSUSB_DMA],
4383 s->irq[0][OMAP_INT_35XX_OHCI_IRQ],
4384 s->irq[0][OMAP_INT_35XX_EHCI_IRQ],
4385 s->irq[0][OMAP_INT_35XX_TLL_IRQ]);
4390 static inline uint32_t omap3_get_le32(const void *p)
4392 const uint8_t *q = (const uint8_t *)p;
4401 static inline uint32_t omap3_get_le16(const void *p)
4403 const uint8_t *q = (const uint8_t *)p;
4410 static inline void omap3_boot_setlsb(target_phys_addr_t addr, uint16_t lsb)
4414 cpu_physical_memory_read(addr, x, 4);
4416 x[1] = (lsb >> 8) & 0xff;
4417 cpu_physical_memory_write(addr, x, 4);
4420 struct omap3_boot_s {
4421 struct omap_mpu_state_s *mpu;
4430 target_phys_addr_t addr;
4434 static struct omap3_boot_s *omap3_boot_init(const uint8_t *data,
4436 struct omap_mpu_state_s *mpu)
4438 struct omap3_boot_s *s = qemu_mallocz(sizeof(struct omap3_boot_s));
4440 s->state = imagehdr;
4441 if (data_len >= 512) {
4442 if (!strncasecmp((char *)(data + 0x14), "chsettings", 10)
4443 || !strncasecmp((char *)(data + 0x14), "chram", 5)
4444 || !strncasecmp((char *)(data + 0x14), "chflash", 7)
4445 || !strncasecmp((char *)(data + 0x14), "chmmcsd", 7))
4446 s->state = confighdr;
4451 static void omap3_boot_chsettings(const uint8_t *chtoc)
4455 if (omap3_get_le32(chtoc) != 0xc0c0c0c1) {
4456 fprintf(stderr, "%s: invalid section verification key\n", __FUNCTION__);
4459 if (!chtoc[4]) { /* section disabled? */
4462 if (omap3_get_le16(chtoc + 5) != 0x0001) {
4463 fprintf(stderr, "%s: unsupported CH version (0x%04x)\n", __FUNCTION__,
4464 omap3_get_le16(chtoc));
4467 flags = omap3_get_le32(chtoc + 8);
4470 cpu_physical_memory_write(0x48307270, chtoc + 0x00, 4); /* PRM_CLKSRC_CTRL */
4471 cpu_physical_memory_write(0x48306d40, chtoc + 0x04, 4); /* PRM_CLKSEL */
4472 cpu_physical_memory_write(0x48005140, chtoc + 0x08, 4); /* CM_CLKSEL1_EMU */
4473 if (flags & (1 << 2)) { /* clock configuration */
4474 cpu_physical_memory_write(0x48004a40, chtoc + 0x0c, 4); /* CM_CLKSEL_CORE */
4475 cpu_physical_memory_write(0x48004c40, chtoc + 0x10, 4); /* CM_CLKSEL_WKUP */
4477 if (flags & (1 << 5)) { /* DPLL3 CORE */
4478 if (flags & (1 << 8)) { /* enable DPLL3 bypass */
4479 cpu_physical_memory_read(0x48004d00, (uint8_t *)&x, 4);
4480 x &= ~7; x |= 5; /* set DPLL3 bypass */
4481 cpu_physical_memory_write(0x48004d00, (uint8_t *)&x, 4);
4483 cpu_physical_memory_write(0x48004d00, chtoc + 0x14, 4); /* CM_CLKEN_PLL */
4484 cpu_physical_memory_write(0x48004d30, chtoc + 0x18, 4); /* CM_AUTOIDLE_PLL */
4485 cpu_physical_memory_write(0x48004d40, chtoc + 0x1c, 4); /* CM_CLKSEL1_PLL */
4487 if (flags & (1 << 3)) { /* DPLL4 PER */
4488 if (flags & (1 << 6)) { /* enable DPLL4 bypass */
4489 cpu_physical_memory_read(0x48004d00, (uint8_t *)&x, 4);
4490 x &= ~0x70000; x |= 0x10000; /* set DPLL4 in stop mode */
4491 cpu_physical_memory_write(0x48004d00, (uint8_t *)&x, 4);
4493 cpu_physical_memory_write(0x48004d00, chtoc + 0x20, 4); /* CM_CLKEN_PLL */
4494 cpu_physical_memory_write(0x48004d30, chtoc + 0x24, 4); /* CM_AUTOIDLE_PLL */
4495 cpu_physical_memory_write(0x48004d44, chtoc + 0x28, 4); /* CM_CLKSEL2_PLL */
4496 cpu_physical_memory_write(0x48004d48, chtoc + 0x2c, 4); /* CM_CLKSEL3_PLL */
4498 if (flags & (1 << 3)) { /* DPLL1 MPU */
4499 if (flags & (1 << 7)) { /* enable DPLL1 bypass */
4500 cpu_physical_memory_read(0x48004904, (uint8_t *)&x, 4);
4501 x &= ~7; x |= 5; /* set DPLL1 bypass */
4502 cpu_physical_memory_write(0x48004904, (uint8_t *)&x, 4);
4504 cpu_physical_memory_write(0x48004904, chtoc + 0x30, 4); /* CM_CLKEN_PLL_MPU */
4505 cpu_physical_memory_write(0x48004934, chtoc + 0x34, 4); /* CM_AUTOIDLE_PLL_MPU */
4506 cpu_physical_memory_write(0x48004940, chtoc + 0x38, 4); /* CM_CLKSEL1_PLL_MPU */
4507 cpu_physical_memory_write(0x48004944, chtoc + 0x3c, 4); /* CM_CLKSEL2_PLL_MPU */
4508 cpu_physical_memory_write(0x48004948, chtoc + 0x40, 4); /* CM_CLKSTCTRL_MPU */
4510 switch ((flags >> 24) & 0xff) {
4511 case 0x01: x = 0; break; /* 12MHz */
4512 case 0x02: x = 1; break; /* 13MHz */
4513 case 0x03: x = 5; break; /* 16.8MHz */
4514 case 0x04: x = 2; break; /* 19.2MHz */
4515 case 0x05: x = 3; break; /* 26MHz */
4516 case 0x06: x = 4; break; /* 38.4MHz */
4518 fprintf(stderr, "%s: unsupported SYS.CLK setting\n", __FUNCTION__);
4522 if (x != omap3_get_le32(chtoc + 0x04)) {
4523 fprintf(stderr, "%s: mismatch in SYS.CLK id and PRM_CLKSEL value\n", __FUNCTION__);
4528 static void omap3_boot_chram(const uint8_t *chtoc)
4530 if (omap3_get_le32(chtoc) != 0xc0c0c0c2) {
4531 fprintf(stderr, "%s: invalid section verification key\n", __FUNCTION__);
4534 if (!chtoc[4]) { /* section disabled? */
4537 omap3_boot_setlsb(0x6d000040, omap3_get_le16(chtoc + 0x0a)); /* SDRC_CS_CFG */
4538 omap3_boot_setlsb(0x6d000044, omap3_get_le16(chtoc + 0x0c)); /* SDRC_SHARING */
4539 cpu_physical_memory_write(0x6d000060, chtoc + 0x10, 4); /* SDRC_DLLA_CTRL */
4541 cpu_physical_memory_write(0x6d000080, chtoc + 0x20, 4); /* SDRC_MCFG_0 */
4542 omap3_boot_setlsb(0x6d000084, omap3_get_le16(chtoc + 0x24)); /* SDRC_MR_0 */
4543 omap3_boot_setlsb(0x6d000088, omap3_get_le16(chtoc + 0x26)); /* SDRC_EMR1_0? */
4544 omap3_boot_setlsb(0x6d00008c, omap3_get_le16(chtoc + 0x28)); /* SDRC_EMR2_0 */
4545 omap3_boot_setlsb(0x6d000090, omap3_get_le16(chtoc + 0x2a)); /* SDRC_EMR3_0? */
4546 cpu_physical_memory_write(0x6d00009c, chtoc + 0x2c, 4); /* SDRC_ACTIM_CTRLA_0 */
4547 cpu_physical_memory_write(0x6d0000a0, chtoc + 0x30, 4); /* SDRC_ACTIM_CTRLB_0 */
4548 cpu_physical_memory_write(0x6d0000a4, chtoc + 0x34, 4); /* SDRC_RFR_CTRL_0 */
4550 cpu_physical_memory_write(0x6d0000b0, chtoc + 0x20, 4); /* SDRC_MCFG_1 */
4551 omap3_boot_setlsb(0x6d0000b4, omap3_get_le16(chtoc + 0x24)); /* SDRC_MR_1 */
4552 omap3_boot_setlsb(0x6d0000b8, omap3_get_le16(chtoc + 0x26)); /* SDRC_EMR1_1? */
4553 omap3_boot_setlsb(0x6d0000bc, omap3_get_le16(chtoc + 0x28)); /* SDRC_EMR2_1 */
4554 omap3_boot_setlsb(0x6d0000c0, omap3_get_le16(chtoc + 0x2a)); /* SDRC_EMR3_1? */
4555 cpu_physical_memory_write(0x6d0000cc, chtoc + 0x2c, 4); /* SDRC_ACTIM_CTRLA_1 */
4556 cpu_physical_memory_write(0x6d0000d0, chtoc + 0x30, 4); /* SDRC_ACTIM_CTRLB_1 */
4557 cpu_physical_memory_write(0x6d0000d4, chtoc + 0x34, 4); /* SDRC_RFR_CTRL_1 */
4560 static void omap3_boot_chflash(const uint8_t *chtoc)
4562 if (omap3_get_le32(chtoc) != 0xc0c0c0c3) {
4563 fprintf(stderr, "%s: invalid section verification key\n", __FUNCTION__);
4566 if (!chtoc[4]) { /* section disabled? */
4569 omap3_boot_setlsb(0x6e000010, omap3_get_le16(chtoc + 0x08)); /* GPMC_SYSCONFIG */
4570 omap3_boot_setlsb(0x6e00001c, omap3_get_le16(chtoc + 0x0a)); /* GPMC_IRQENABLE */
4571 omap3_boot_setlsb(0x6e000040, omap3_get_le16(chtoc + 0x0c)); /* GPMC_TIMEOUT_CONTROL */
4572 omap3_boot_setlsb(0x6e000050, omap3_get_le16(chtoc + 0x0e)); /* GPMC_CONFIG */
4573 cpu_physical_memory_write(0x6e000060, chtoc + 0x10, 4); /* GPMC_CONFIG1_0 */
4574 cpu_physical_memory_write(0x6e000064, chtoc + 0x14, 4); /* GPMC_CONFIG2_0 */
4575 cpu_physical_memory_write(0x6e000068, chtoc + 0x18, 4); /* GPMC_CONFIG3_0 */
4576 cpu_physical_memory_write(0x6e00006c, chtoc + 0x1c, 4); /* GPMC_CONFIG4_0 */
4577 cpu_physical_memory_write(0x6e000070, chtoc + 0x20, 4); /* GPMC_CONFIG5_0 */
4578 cpu_physical_memory_write(0x6e000074, chtoc + 0x24, 4); /* GPMC_CONFIG6_0 */
4579 cpu_physical_memory_write(0x6e000078, chtoc + 0x28, 4); /* GPMC_CONFIG7_0 */
4580 cpu_physical_memory_write(0x6e0001e0, chtoc + 0x2c, 4); /* GPMC_PREFETCH_CONFIG1 */
4581 omap3_boot_setlsb(0x6e0001e4, omap3_get_le16(chtoc + 0x30)); /* GPMC_PREFETCH_CONFIG2 */
4582 omap3_boot_setlsb(0x6e0001ec, omap3_get_le16(chtoc + 0x32)); /* GPMC_PREFETCH_CONTROL */
4583 /* TODO: ECC config registers. The TRM spec is not clear on these */
4586 static void omap3_boot_chmmcsd(const uint8_t *chtoc)
4588 if (omap3_get_le32(chtoc) != 0xc0c0c0c4) {
4589 fprintf(stderr, "%s: invalid section verification key\n", __FUNCTION__);
4592 if (!chtoc[4]) { /* section disabled? */
4595 /* TODO: MMCHS registers */
4598 /* returns non-zero if more blocks are needed */
4599 static uint32_t omap3_boot_block(const uint8_t *data,
4601 struct omap3_boot_s *s)
4603 const uint8_t *p = 0;
4609 for (p = data; i >= 32 && omap3_get_le32(p) != 0xffffffff; p += 32, i -= 32) {
4610 if (!strcasecmp((char *)(p + 0x14), "chsettings"))
4611 omap3_boot_chsettings(p + omap3_get_le32(p));
4612 else if (!strcasecmp((char *)(p + 0x14), "chram"))
4613 omap3_boot_chram(p + omap3_get_le32(p));
4614 else if (!strcasecmp((char *)(p + 0x14), "chflash"))
4615 omap3_boot_chflash(p + omap3_get_le32(p));
4616 else if (!strcasecmp((char *)(p + 0x14), "chmmcsd"))
4617 omap3_boot_chmmcsd(p + omap3_get_le32(p));
4619 fprintf(stderr, "%s: unknown CHTOC item \"%s\"\n",
4620 __FUNCTION__, (char *)(p + 0x14));
4627 s->state = imagehdr;
4634 s->count = omap3_get_le32(data);
4635 s->addr = omap3_get_le32(data + 4);
4636 if (!s->count || !s->addr || s->addr == 0xffffffff)
4638 s->mpu->env->regs[15] = s->addr;
4644 i = (s->count >= data_len) ? data_len : s->count;
4645 cpu_physical_memory_write(s->addr, data, i);
4657 /* returns ptr to matching dir entry / zero entry or 0 if unsuccessful */
4658 static const uint8_t *omap3_scan_fat_dir_sector(const uint8_t *s)
4662 /* there are 0x10 items with 0x20 bytes per item */
4663 for (i = 0x10; i--; s += 0x20) {
4664 if (*s == 0xe5 || (s[0x0b] & 0x0f) == 0x0f) continue; /* erased/LFN */
4665 if (!*s || !strncasecmp((void *)s, "mlo ", 8+3)) return s;
4670 struct omap3_fat_drv_s {
4671 BlockDriverState *bs;
4672 uint8_t ptype; /* 12, 16, 32 */
4673 uint64_t c0; /* physical byte offset for data cluster 0 */
4674 uint64_t fat; /* physical byte offset for used FAT sector 0 */
4675 uint32_t spc; /* sectors per cluster */
4678 /* returns cluster data in the buffer and next cluster chain number
4679 or 0 if unsuccessful */
4680 static uint32_t omap3_read_fat_cluster(uint8_t *data,
4681 struct omap3_fat_drv_s *drv,
4685 uint32_t len = drv->spc * 0x200; /* number of bytes to read */
4687 switch (drv->ptype) { /* check for EOF */
4688 case 12: if (cl > 0xff0) return 0; break;
4689 case 16: if (cl > 0xfff0) return 0; break;
4690 case 32: if (cl > 0x0ffffff0) return 0; break;
4694 if (bdrv_pread(drv->bs,
4695 drv->c0 + ((drv->ptype == 32 ? cl - 2 : cl) * len),
4699 switch (drv->ptype) { /* determine next cluster # */
4701 fprintf(stderr, "%s: FAT12 parsing not implemented!\n",
4705 return (bdrv_pread(drv->bs, drv->fat + cl * 2, buf, 2) != 2)
4706 ? 0 : omap3_get_le16(buf);
4708 return (bdrv_pread(drv->bs, drv->fat + cl * 4, buf, 4) != 4)
4709 ? 0 : omap3_get_le32(buf) & 0x0fffffff;
4716 static int omap3_mmc_fat_boot(BlockDriverState *bs,
4719 struct omap_mpu_state_s *mpu)
4721 struct omap3_fat_drv_s drv;
4722 struct omap3_boot_s *boot;
4723 uint32_t i, j, cluster0, fatsize, bootsize, rootsize;
4724 const uint8_t *p, *q;
4728 /* determine FAT type */
4731 fatsize = omap3_get_le16(sector + 0x16);
4733 fatsize = omap3_get_le32(sector + 0x24);
4734 bootsize = omap3_get_le16(sector + 0x0e);
4735 cluster0 = bootsize + fatsize * sector[0x10];
4736 rootsize = omap3_get_le16(sector + 0x11);
4737 if (rootsize & 0x0f)
4740 drv.spc = sector[0x0d];
4741 i = omap3_get_le16(sector + 0x13);
4743 i = omap3_get_le32(sector + 0x20);
4744 i = (i - (cluster0 + rootsize)) / drv.spc;
4745 drv.ptype = (i < 4085) ? 12 : (i < 65525) ? 16 : 32;
4747 /* search for boot loader file */
4749 drv.fat = (bootsize + pstart) * 0x200;
4750 drv.c0 = (cluster0 + pstart) * 0x200;
4751 if (drv.ptype == 32) {
4752 i = omap3_get_le32(sector + 0x2c); /* first root cluster # */
4753 j = omap3_get_le16(sector + 0x28);
4755 drv.fat += (j & 0x0f) * fatsize * 0x200;
4756 cluster = qemu_mallocz(drv.spc * 0x200);
4757 for (p = 0; !p && (i = omap3_read_fat_cluster(cluster, &drv, i)); ) {
4758 for (j = drv.spc, q=cluster; j-- & !p; q += 0x200)
4759 p = omap3_scan_fat_dir_sector(q);
4761 memcpy(sector, q - 0x200, 0x200); /* save the sector */
4764 } else { /* FAT12/16 */
4765 for (i = rootsize, j = 0, p = 0; i-- && !p; j++) {
4766 if (bdrv_pread(drv.bs, drv.c0 + j * 0x200, sector, 0x200) != 0x200)
4768 p = omap3_scan_fat_dir_sector(sector);
4772 if (p && *p) { /* did we indeed find the file? */
4773 i = omap3_get_le16(p + 0x14);
4775 i |= omap3_get_le16(p + 0x1a);
4776 j = drv.spc * 0x200;
4777 uint8 *data = qemu_mallocz(j);
4778 if ((i = omap3_read_fat_cluster(data, &drv, i))) {
4779 boot = omap3_boot_init(data, j, mpu);
4780 boot->state = imagehdr; /* override CH detection */
4781 while (omap3_boot_block(data, j, boot))
4782 i = omap3_read_fat_cluster(data, &drv, i);
4783 result = (boot->state == done);
4786 fprintf(stderr, "%s: unable to read MLO file contents from SD card\n",
4790 fprintf(stderr, "%s: MLO file not found in the root directory\n",
4796 static int omap3_mmc_raw_boot(BlockDriverState *bs,
4798 struct omap_mpu_state_s *mpu)
4800 struct omap3_boot_s *boot;
4804 if (bdrv_pread(bs, 0, sector, 0x200) == 0x200) {
4805 boot = omap3_boot_init(sector, 0x200, mpu);
4806 if (boot->state == confighdr) { /* CH must be present for raw boot */
4807 while (omap3_boot_block(sector, 0x200, boot)) {
4808 if (bdrv_pread(bs, ++i, sector, 0x200) != 0x200) {
4809 fprintf(stderr, "%s: error trying to read sector %u on boot device\n",
4815 result = (boot->state == done);
4821 /* returns non-zero if successful, zero if unsuccessful */
4822 int omap3_mmc_boot(struct omap_mpu_state_s *s)
4824 BlockDriverState *bs;
4825 int sdindex = drive_get_index(IF_SD, 0, 0);
4826 uint8_t *sector, *p;
4830 /* very simple implementation for GP device boot,
4831 supports only two modes:
4832 1. MBR partition table with an active FAT partition
4833 and boot loader file (MLO) in its root directory, or
4834 2. CH sector located on first sector, followed by boot loader image */
4836 bs = drives_table[sdindex].bdrv;
4837 sector = qemu_mallocz(0x200);
4838 if (bdrv_pread(bs, 0, sector, 0x200) == 0x200) {
4839 for (i = 0, p = sector + 0x1be; i < 4; i++, p += 0x10)
4840 if (p[0] == 0x80) break;
4841 if (sector[0x1fe] == 0x55 && sector[0x1ff] == 0xaa /* signature */
4842 && i < 4 /* active partition exists */
4843 && (p[4] == 1 || p[4] == 4 || p[4] == 6 || p[4] == 11
4844 || p[4] == 12 || p[4] == 14 || p[4] == 15) /* FAT */
4845 && bdrv_pread(bs, (pstart = omap3_get_le32(p + 8)) * 0x200,
4846 sector, 0x200) == 0x200
4847 && sector[0x1fe] == 0x55 && sector[0x1ff] == 0xaa)
4848 result = omap3_mmc_fat_boot(bs, sector, pstart, s);
4850 result = omap3_mmc_raw_boot(bs, sector, s);
4857 /* returns non-zero if successful, zero if unsuccessful */
4858 int omap3_nand_boot(struct omap_mpu_state_s *mpu,
4859 struct nand_flash_s *nand,
4860 void (*nand_pread_f)(struct nand_flash_s *nand,
4865 struct omap3_boot_s *boot;
4870 data = qemu_mallocz(0x1000);
4871 nand_pread_f(nand, 0, data, 0x1000);
4872 boot = omap3_boot_init(data, 0x1000, mpu);
4873 while (omap3_boot_block(data, 0x1000, boot)) {
4875 nand_pread_f(nand, addr, data, 0x1000);
4877 result = (boot->state == done);