2 * TI OMAP3 processors emulation.
4 * Copyright (C) 2008 yajin <yajin@vm-kernel.org>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 or
9 * (at your option) version 3 of the License.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
26 #include "qemu-timer.h"
27 #include "qemu-char.h"
30 #include "audio/audio.h"
33 //#define OMAP3_DEBUG_
36 #define TRACE(fmt, ...) fprintf(stderr, "%s " fmt "\n", __FUNCTION__, ##__VA_ARGS__)
41 enum omap3_l3_region_id_t {
42 /* 68000000-680003FF */ L3ID_L3RT = 0,
43 /* 68000400-680007FF */ L3ID_L3SI,
44 /* 68000800-680013FF */
45 /* 68001400-680017FF */ L3ID_MPUSS_IA,
46 /* 68001800-68001BFF */ L3ID_IVASS_IA,
47 /* 68001C00-68001FFF */ L3ID_SGXSS_IA,
48 /* 68002000-680023FF */ L3ID_SMS_TA,
49 /* 68002400-680027FF */ L3ID_GPMC_TA,
50 /* 68002800-68002BFF */ L3ID_OCM_RAM_TA,
51 /* 68002C00-68002FFF */ L3ID_OCM_ROM_TA,
52 /* 68003000-680033FF */ L3ID_D2D_IA,
53 /* 68003400-680037FF */ L3ID_D2D_TA,
54 /* 68003800-68003FFF */
55 /* 68004000-680043FF */ L3ID_HSUSB_HOST_IA,
56 /* 68004400-680047FF */ L3ID_HSUSB_OTG_IA,
57 /* 68004800-68004BFF */
58 /* 68004C00-68004FFF */ L3ID_SDMA_RD_IA,
59 /* 68005000-680053FF */ L3ID_SDMA_WR_IA,
60 /* 68005400-680057FF */ L3ID_DSS_IA,
61 /* 68005800-68005BFF */ L3ID_CAMISP_IA,
62 /* 68005C00-68005FFF */ L3ID_DAP_IA,
63 /* 68006000-680063FF */ L3ID_IVASS_TA,
64 /* 68006400-680067FF */ L3ID_SGXSS_TA,
65 /* 68006800-68006BFF */ L3ID_L4_CORE_TA,
66 /* 68006C00-68006FFF */ L3ID_L4_PER_TA,
67 /* 68007000-680073FF */ L3ID_L4_EMU_TA,
68 /* 68007400-6800FFFF */
69 /* 68010000-680103FF */ L3ID_RT_PM,
70 /* 68010400-680123FF */
71 /* 68012400-680127FF */ L3ID_GPMC_PM,
72 /* 68012800-68012BFF */ L3ID_OCM_RAM_PM,
73 /* 68012C00-68012FFF */ L3ID_OCM_ROM_PM,
74 /* 68013000-680133FF */ L3ID_D2D_PM,
75 /* 68013400-68013FFF */
76 /* 68014000-680143FF */ L3ID_IVA_PM,
77 /* 68014400-68FFFFFF */
80 struct omap_l3_region_s {
81 target_phys_addr_t offset;
91 struct omap_l3_initiator_agent_s {
92 target_phys_addr_t base;
100 target_phys_addr_t base;
104 uint16_t req_info_permission[8];
105 uint16_t read_permission[8];
106 uint16_t write_permission[8];
107 uint32_t addr_match[7];
110 union omap_l3_port_s {
111 struct omap_target_agent_s ta;
112 struct omap_l3_initiator_agent_s ia;
113 struct omap3_l3pm_s pm;
117 target_phys_addr_t base;
119 union omap_l3_port_s region[0];
122 static struct omap_l3_region_s omap3_l3_region[] = {
123 [L3ID_L3RT ] = {0x00000000, 0x0400, L3TYPE_GENERIC},
124 [L3ID_L3SI ] = {0x00000400, 0x0400, L3TYPE_GENERIC},
125 [L3ID_MPUSS_IA ] = {0x00001400, 0x0400, L3TYPE_IA},
126 [L3ID_IVASS_IA ] = {0x00001800, 0x0400, L3TYPE_IA},
127 [L3ID_SGXSS_IA ] = {0x00001c00, 0x0400, L3TYPE_IA},
128 [L3ID_SMS_TA ] = {0x00002000, 0x0400, L3TYPE_TA},
129 [L3ID_GPMC_TA ] = {0x00002400, 0x0400, L3TYPE_TA},
130 [L3ID_OCM_RAM_TA ] = {0x00002800, 0x0400, L3TYPE_TA},
131 [L3ID_OCM_ROM_TA ] = {0x00002c00, 0x0400, L3TYPE_TA},
132 [L3ID_D2D_IA ] = {0x00003000, 0x0400, L3TYPE_IA},
133 [L3ID_D2D_TA ] = {0x00003400, 0x0400, L3TYPE_TA},
134 [L3ID_HSUSB_HOST_IA] = {0x00004000, 0x0400, L3TYPE_IA},
135 [L3ID_HSUSB_OTG_IA ] = {0x00004400, 0x0400, L3TYPE_IA},
136 [L3ID_SDMA_RD_IA ] = {0x00004c00, 0x0400, L3TYPE_IA},
137 [L3ID_SDMA_WR_IA ] = {0x00005000, 0x0400, L3TYPE_IA},
138 [L3ID_DSS_IA ] = {0x00005400, 0x0400, L3TYPE_IA},
139 [L3ID_CAMISP_IA ] = {0x00005800, 0x0400, L3TYPE_IA},
140 [L3ID_DAP_IA ] = {0x00005c00, 0x0400, L3TYPE_IA},
141 [L3ID_IVASS_TA ] = {0x00006000, 0x0400, L3TYPE_TA},
142 [L3ID_SGXSS_TA ] = {0x00006400, 0x0400, L3TYPE_TA},
143 [L3ID_L4_CORE_TA ] = {0x00006800, 0x0400, L3TYPE_TA},
144 [L3ID_L4_PER_TA ] = {0x00006c00, 0x0400, L3TYPE_TA},
145 [L3ID_L4_EMU_TA ] = {0x00007000, 0x0400, L3TYPE_TA},
146 [L3ID_RT_PM ] = {0x00010000, 0x0400, L3TYPE_PM},
147 [L3ID_GPMC_PM ] = {0x00012400, 0x0400, L3TYPE_PM},
148 [L3ID_OCM_RAM_PM ] = {0x00012800, 0x0400, L3TYPE_PM},
149 [L3ID_OCM_ROM_PM ] = {0x00012c00, 0x0400, L3TYPE_PM},
150 [L3ID_D2D_PM ] = {0x00013000, 0x0400, L3TYPE_PM},
151 [L3ID_IVA_PM ] = {0x00014000, 0x0400, L3TYPE_PM},
154 static uint32_t omap3_l3ia_read(void *opaque, target_phys_addr_t addr)
156 struct omap_l3_initiator_agent_s *s = (struct omap_l3_initiator_agent_s *)opaque;
159 case 0x00: /* COMPONENT_L */
161 case 0x04: /* COMPONENT_H */
163 case 0x18: /* CORE_L */
165 case 0x1c: /* CORE_H */
166 return (s->component >> 16);
167 case 0x20: /* AGENT_CONTROL_L */
169 case 0x24: /* AGENT_CONTROL_H */
171 case 0x28: /* AGENT_STATUS_L */
173 case 0x2c: /* AGENT_STATUS_H */
175 case 0x58: /* ERROR_LOG_L */
177 case 0x5c: /* ERROR_LOG_H */
179 case 0x60: /* ERROR_LOG_ADDR_L */
181 case 0x64: /* ERROR_LOG_ADDR_H */
187 OMAP_BAD_REG(s->base + addr);
191 static void omap3_l3ia_write(void *opaque, target_phys_addr_t addr,
194 struct omap_l3_initiator_agent_s *s = (struct omap_l3_initiator_agent_s *)opaque;
197 case 0x00: /* COMPONENT_L */
198 case 0x04: /* COMPONENT_H */
199 case 0x18: /* CORE_L */
200 case 0x1c: /* CORE_H */
201 case 0x60: /* ERROR_LOG_ADDR_L */
202 case 0x64: /* ERROR_LOG_ADDR_H */
203 OMAP_RO_REG(s->base + addr);
205 case 0x24: /* AGENT_CONTROL_H */
206 case 0x2c: /* AGENT_STATUS_H */
207 case 0x5c: /* ERROR_LOG_H */
208 /* RW register but all bits are reserved/read-only */
210 case 0x20: /* AGENT_CONTROL_L */
211 s->control = value & 0x3e070711;
212 /* TODO: some bits are reserved for some IA instances */
214 case 0x28: /* AGENT_STATUS_L */
215 s->status &= ~(value & 0x30000000);
217 case 0x58: /* ERROR_LOG_L */
218 /* error logging is not implemented, so ignore */
221 OMAP_BAD_REG(s->base + addr);
226 static void omap3_l3ia_init(struct omap_l3_initiator_agent_s *s)
228 s->component = ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
229 s->control = 0x3e000000;
233 static CPUReadMemoryFunc *omap3_l3ia_readfn[] = {
234 omap_badwidth_read32,
235 omap_badwidth_read32,
239 static CPUWriteMemoryFunc *omap3_l3ia_writefn[] = {
240 omap_badwidth_write32,
241 omap_badwidth_write32,
245 static uint32_t omap3_l3ta_read(void *opaque, target_phys_addr_t addr)
247 struct omap_target_agent_s *s = (struct omap_target_agent_s *)opaque;
250 case 0x00: /* COMPONENT_L */
252 case 0x04: /* COMPONENT_H */
254 case 0x18: /* CORE_L */
256 case 0x1c: /* CORE_H */
257 return (s->component >> 16);
258 case 0x20: /* AGENT_CONTROL_L */
260 case 0x24: /* AGENT_CONTROL_H */
262 case 0x28: /* AGENT_STATUS_L */
264 case 0x2c: /* AGENT_STATUS_H */
266 case 0x58: /* ERROR_LOG_L */
268 case 0x5c: /* ERROR_LOG_H */
270 case 0x60: /* ERROR_LOG_ADDR_L */
272 case 0x64: /* ERROR_LOG_ADDR_H */
278 OMAP_BAD_REG(s->base + addr);
282 static void omap3_l3ta_write(void *opaque, target_phys_addr_t addr,
285 struct omap_target_agent_s *s = (struct omap_target_agent_s *)opaque;
288 case 0x00: /* COMPONENT_L */
289 case 0x04: /* COMPONENT_H */
290 case 0x18: /* CORE_L */
291 case 0x1c: /* CORE_H */
292 case 0x60: /* ERROR_LOG_ADDR_L */
293 case 0x64: /* ERROR_LOG_ADDR_H */
294 OMAP_RO_REG(s->base + addr);
296 case 0x24: /* AGENT_CONTROL_H */
297 case 0x5c: /* ERROR_LOG_H */
298 /* RW register but all bits are reserved/read-only */
300 case 0x20: /* AGENT_CONTROL_L */
301 s->control = value & 0x03000711;
303 case 0x28: /* AGENT_STATUS_L */
304 if (s->base == OMAP3_L3_BASE + omap3_l3_region[L3ID_L4_CORE_TA].offset
305 || s->base == OMAP3_L3_BASE + omap3_l3_region[L3ID_L4_PER_TA].offset
306 || s->base == OMAP3_L3_BASE + omap3_l3_region[L3ID_L4_EMU_TA].offset) {
307 s->status &= ~(value & (1 << 24));
309 OMAP_RO_REG(s->base + addr);
311 case 0x2c: /* AGENT_STATUS_H */
312 if (s->base != OMAP3_L3_BASE + omap3_l3_region[L3ID_L4_CORE_TA].offset
313 && s->base != OMAP3_L3_BASE + omap3_l3_region[L3ID_L4_PER_TA].offset
314 && s->base != OMAP3_L3_BASE + omap3_l3_region[L3ID_L4_EMU_TA].offset)
315 OMAP_RO_REG(s->base + addr);
316 /* for L4 core, per, emu TAs this is RW reg */
318 case 0x58: /* ERROR_LOG_L */
319 /* error logging is not implemented, so ignore */
322 OMAP_BAD_REG(s->base + addr);
327 static void omap3_l3ta_init(struct omap_target_agent_s *s)
329 s->component = ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
330 s->control = 0x03000000;
334 static CPUReadMemoryFunc *omap3_l3ta_readfn[] = {
335 omap_badwidth_read32,
336 omap_badwidth_read32,
340 static CPUWriteMemoryFunc *omap3_l3ta_writefn[] = {
341 omap_badwidth_write32,
342 omap_badwidth_write32,
346 static uint32_t omap3_l3pm_read8(void *opaque, target_phys_addr_t addr)
348 struct omap3_l3pm_s *s = (struct omap3_l3pm_s *)opaque;
354 OMAP_BAD_REG(s->base + addr);
357 case 0x20: return s->error_log & 0xff;
358 case 0x21: return (s->error_log >> 8) & 0xff;
359 case 0x22: return (s->error_log >> 16) & 0xff;
360 case 0x23: return (s->error_log >> 24) & 0xff;
361 case 0x24 ... 0x27: return 0;
363 case 0x28 ... 0x2a: return 0;
364 case 0x2b: return s->control;
365 case 0x2c ... 0x2f: return 0;
366 /* ERROR_CLEAR_SINGLE */
367 case 0x30: return 0; /* TODO: clear single error from log */
368 case 0x31 ... 0x37: return 0;
369 /* ERROR_CLEAR_MULTI */
370 case 0x38: return 0; /* TODO: clear multiple errors from log */
371 case 0x39 ... 0x3f: return 0;
376 i = (addr - 0x48) / 0x20;
378 if (i < 7 || (i < 8 && addr < 0x60))
380 /* REQ_INFO_PERMISSION_i */
381 case 0x48: return s->req_info_permission[i] & 0xff;
382 case 0x49: return (s->req_info_permission[i] >> 8) & 0xff;
383 case 0x4a ... 0x4f: return 0;
384 /* READ_PERMISSION_i */
385 case 0x50: return s->read_permission[i] & 0xff;
386 case 0x51: return (s->read_permission[i] >> 8) & 0xff;
387 case 0x52 ... 0x57: return 0;
388 /* WRITE_PERMISSION_i */
389 case 0x58: return s->write_permission[i] & 0xff;
390 case 0x59: return (s->write_permission[i] >> 8) & 0xff;
391 case 0x5a ... 0x5f: return 0;
393 case 0x60: return s->addr_match[i] & 0xff;
394 case 0x61: return (s->addr_match[i] >> 8) & 0xff;
395 case 0x62: return (s->addr_match[i] >> 16) & 0xff;
396 case 0x63 ... 0x67: return 0;
401 OMAP_BAD_REG(s->base + addr);
405 static uint32_t omap3_l3pm_read16(void *opaque, target_phys_addr_t addr)
407 return omap3_l3pm_read8(opaque, addr)
408 | (omap3_l3pm_read8(opaque, addr + 1) << 8);
411 static uint32_t omap3_l3pm_read32(void *opaque, target_phys_addr_t addr)
413 return omap3_l3pm_read16(opaque, addr)
414 | (omap3_l3pm_read16(opaque, addr + 2) << 16);
417 static void omap3_l3pm_write8(void *opaque, target_phys_addr_t addr,
420 struct omap3_l3pm_s *s = (struct omap3_l3pm_s *)opaque;
426 OMAP_BAD_REGV(s->base + addr, value);
430 s->error_log &= ~((value & 0xcf) << 24);
436 s->control = value & 3;
440 /* ERROR_CLEAR_SINGLE / ERROR_CLEAR_MULTI */
442 OMAP_RO_REGV(s->base + addr, value);
448 i = (addr - 0x48) / 0x20;
450 if (i < 7 || (i < 8 && addr < 0x60))
452 /* REQ_INFO_PERMISSION_i */
454 s->req_info_permission[i] =
455 (s->req_info_permission[i] & ~0xff) | (value & 0xff);
458 s->req_info_permission[i] =
459 (s->req_info_permission[i] & ~0xff00) | ((value & 0xff) << 8);
463 /* READ_PERMISSION_i */
465 s->read_permission[i] =
466 (s->read_permission[i] & ~0xff) | (value & 0x3e);
469 s->read_permission[i] =
470 (s->read_permission[i] & ~0xff00) | ((value & 0x5f) << 8);
474 /* WRITE_PERMISSION_i */
476 s->write_permission[i] =
477 (s->write_permission[i] & ~0xff) | (value & 0x3e);
480 s->write_permission[i] =
481 (s->write_permission[i] & ~0xff00) | ((value & 0x5f) << 8);
487 s->addr_match[i] = (s->addr_match[i] & ~0xff) | (value & 0xff);
491 (s->addr_match[i] & ~0xfe00) | ((value & 0xfe) << 8);
495 (s->addr_match[i] & ~0x0f0000) | ((value & 0x0f) << 16);
503 OMAP_BAD_REGV(s->base + addr, value);
506 static void omap3_l3pm_write16(void *opaque, target_phys_addr_t addr,
509 omap3_l3pm_write8(opaque, addr + 0, value & 0xff);
510 omap3_l3pm_write8(opaque, addr + 1, (value >> 8) & 0xff);
513 static void omap3_l3pm_write32(void *opaque, target_phys_addr_t addr,
516 omap3_l3pm_write16(opaque, addr + 0, value & 0xffff);
517 omap3_l3pm_write16(opaque, addr + 2, (value >> 16) & 0xffff);
520 static void omap3_l3pm_init(struct omap3_l3pm_s *s)
527 case 0x68010000: /* PM_RT */
528 s->req_info_permission[0] = 0xffff;
529 s->req_info_permission[1] = 0;
530 for (i = 0; i < 2; i++)
531 s->read_permission[i] = s->write_permission[i] = 0x1406;
532 s->addr_match[0] = 0x10230;
534 case 0x68012400: /* PM_GPMC */
535 s->req_info_permission[0] = 0;
536 for (i = 3; i < 8; i++)
537 s->req_info_permission[i] = 0xffff;
538 for (i = 0; i < 8; i++)
539 s->read_permission[i] = s->write_permission[i] = 0x563e;
540 s->addr_match[0] = 0x00098;
542 case 0x68012800: /* PM_OCM_RAM */
543 s->req_info_permission[0] = 0;
544 for (i = 1; i < 8; i++)
545 s->req_info_permission[i] = 0xffff;
546 for (i = 0; i < 8; i++)
547 s->read_permission[i] = s->write_permission[i] = 0x5f3e;
548 s->addr_match[1] = 0x0f810;
550 case 0x68012C00: /* PM_OCM_ROM */
551 s->req_info_permission[1] = 0xffff;
552 for (i = 0; i < 2; i++) {
553 s->read_permission[i] = 0x1002;
554 s->write_permission[i] = 0;
556 s->addr_match[0] = 0x14028;
558 case 0x68013000: /* PM_MAD2D */
559 s->req_info_permission[0] = 0;
560 for (i = 1; i < 8; i++)
561 s->req_info_permission[i] = 0xffff;
562 for (i = 0; i < 8; i++)
563 s->read_permission[i] = s->write_permission[i] = 0x5f1e;
565 case 0x68014000: /* PM_IVA2.2 */
566 s->req_info_permission[0] = 0;
567 for (i = 1; i < 4; i++)
568 s->req_info_permission[i] = 0xffff;
569 for (i = 0; i < 4; i++)
570 s->read_permission[i] = s->write_permission[i] = 0x140e;
573 fprintf(stderr, "%s: unknown PM region (0x%08x)\n",
574 __FUNCTION__, s->base);
580 static CPUReadMemoryFunc *omap3_l3pm_readfn[] = {
586 static CPUWriteMemoryFunc *omap3_l3pm_writefn[] = {
592 static uint32_t omap3_l3gen_read8(void *opaque, target_phys_addr_t addr)
594 fprintf(stderr, "%s: unsupported register at %08x\n",
599 static uint32_t omap3_l3gen_read16(void *opaque, target_phys_addr_t addr)
601 fprintf(stderr, "%s: unsupported register at %08x\n",
606 static uint32_t omap3_l3gen_read32(void *opaque, target_phys_addr_t addr)
608 fprintf(stderr, "%s: unsupported register at %08x\n",
613 static void omap3_l3gen_write8(void *opaque, target_phys_addr_t addr,
616 fprintf(stderr, "%s: unsupported register at %08x, value %02x\n",
617 __FUNCTION__, addr, value);
620 static void omap3_l3gen_write16(void *opaque, target_phys_addr_t addr,
623 fprintf(stderr, "%s: unsupported register at %08x, value %04x\n",
624 __FUNCTION__, addr, value);
627 static void omap3_l3gen_write32(void *opaque, target_phys_addr_t addr,
630 fprintf(stderr, "%s: unsupported register at %08x, value %08x\n",
631 __FUNCTION__, addr, value);
634 static CPUReadMemoryFunc *omap3_l3gen_readfn[] = {
640 static CPUWriteMemoryFunc *omap3_l3gen_writefn[] = {
646 static struct omap_l3_s *omap3_l3_init(target_phys_addr_t base,
647 struct omap_l3_region_s *regions,
650 int i, iomemtype = 0;
652 struct omap_l3_s *bus = qemu_mallocz(sizeof(*bus) + n * sizeof(*bus->region));
653 bus->region_count = n;
656 for (i = 0; i < n; i++) {
657 switch (regions[i].type) {
659 iomemtype = cpu_register_io_memory(0, omap3_l3gen_readfn,
664 iomemtype = cpu_register_io_memory(0, omap3_l3ia_readfn,
667 bus->region[i].ia.base = base + regions[i].offset;
668 omap3_l3ia_init(&bus->region[i].ia);
671 iomemtype = cpu_register_io_memory(0, omap3_l3ta_readfn,
674 bus->region[i].ta.base = base + regions[i].offset;
675 omap3_l3ta_init(&bus->region[i].ta);
678 iomemtype = cpu_register_io_memory(0, omap3_l3pm_readfn,
681 bus->region[i].pm.base = base + regions[i].offset;
682 omap3_l3pm_init(&bus->region[i].pm);
685 fprintf(stderr, "%s: unknown L3 region type: %d\n",
686 __FUNCTION__, regions[i].type);
690 cpu_register_physical_memory(base + regions[i].offset,
698 enum omap3_l4_region_id_t {
699 /* 48000000-48001FFF */
700 /* 48002000-48002FFF */ L4ID_SCM = 0,
701 /* 48003000-48003FFF */ L4ID_SCM_TA,
702 /* 48004000-48005FFF */ L4ID_CM_A,
703 /* 48006000-480067FF */ L4ID_CM_B,
704 /* 48006800-48006FFF */
705 /* 48007000-48007FFF */ L4ID_CM_TA,
706 /* 48008000-48023FFF */
707 /* 48024000-48024FFF */
708 /* 48025000-48025FFF */
709 /* 48026000-4803FFFF */
710 /* 48040000-480407FF */ L4ID_CORE_AP,
711 /* 48040800-48040FFF */ L4ID_CORE_IP,
712 /* 48041000-48041FFF */ L4ID_CORE_LA,
713 /* 48042000-4804FBFF */
714 /* 4804FC00-4804FFFF */ L4ID_DSI,
715 /* 48050000-480503FF */ L4ID_DSS,
716 /* 48050400-480507FF */ L4ID_DISPC,
717 /* 48050800-48050BFF */ L4ID_RFBI,
718 /* 48050C00-48050FFF */ L4ID_VENC,
719 /* 48051000-48051FFF */ L4ID_DSS_TA,
720 /* 48052000-48055FFF */
721 /* 48056000-48056FFF */ L4ID_SDMA,
722 /* 48057000-48057FFF */ L4ID_SDMA_TA,
723 /* 48058000-4805FFFF */
724 /* 48060000-48060FFF */ L4ID_I2C3,
725 /* 48061000-48061FFF */ L4ID_I2C3_TA,
726 /* 48062000-48062FFF */ L4ID_USBTLL,
727 /* 48063000-48063FFF */ L4ID_USBTLL_TA,
728 /* 48064000-48064FFF */ L4ID_HSUSBHOST,
729 /* 48065000-48065FFF */ L4ID_HSUSBHOST_TA,
730 /* 48066000-48069FFF */
731 /* 4806A000-4806AFFF */ L4ID_UART1,
732 /* 4806B000-4806BFFF */ L4ID_UART1_TA,
733 /* 4806C000-4806CFFF */ L4ID_UART2,
734 /* 4806D000-4806DFFF */ L4ID_UART2_TA,
735 /* 4806E000-4806FFFF */
736 /* 48070000-48070FFF */ L4ID_I2C1,
737 /* 48071000-48071FFF */ L4ID_I2C1_TA,
738 /* 48072000-48072FFF */ L4ID_I2C2,
739 /* 48073000-48073FFF */ L4ID_I2C2_TA,
740 /* 48074000-48074FFF */ L4ID_MCBSP1,
741 /* 48075000-48075FFF */ L4ID_MCBSP1_TA,
742 /* 48076000-48085FFF */
743 /* 48086000-48086FFF */ L4ID_GPTIMER10,
744 /* 48087000-48087FFF */ L4ID_GPTIMER10_TA,
745 /* 48088000-48088FFF */ L4ID_GPTIMER11,
746 /* 48089000-48089FFF */ L4ID_GPTIMER11_TA,
747 /* 4808A000-4808AFFF */
748 /* 4808B000-4808BFFF */
749 /* 4808C000-48093FFF */
750 /* 48094000-48094FFF */ L4ID_MAILBOX,
751 /* 48095000-48095FFF */ L4ID_MAILBOX_TA,
752 /* 48096000-48096FFF */ L4ID_MCBSP5,
753 /* 48097000-48097FFF */ L4ID_MCBSP5_TA,
754 /* 48098000-48098FFF */ L4ID_MCSPI1,
755 /* 48099000-48099FFF */ L4ID_MCSPI1_TA,
756 /* 4809A000-4809AFFF */ L4ID_MCSPI2,
757 /* 4809B000-4809BFFF */ L4ID_MCSPI2_TA,
758 /* 4809C000-4809CFFF */ L4ID_MMCSDIO1,
759 /* 4809D000-4809DFFF */ L4ID_MMCSDIO1_TA,
760 /* 4809E000-4809EFFF */ L4ID_MSPRO,
761 /* 4809F000-4809FFFF */ L4ID_MSPRO_TA,
762 /* 480A0000-480AAFFF */
763 /* 480AB000-480ABFFF */ L4ID_HSUSBOTG,
764 /* 480AC000-480ACFFF */ L4ID_HSUSBOTG_TA,
765 /* 480AD000-480ADFFF */ L4ID_MMCSDIO3,
766 /* 480AE000-480AEFFF */ L4ID_MMCSDIO3_TA,
767 /* 480AF000-480AFFFF */
768 /* 480B0000-480B0FFF */
769 /* 480B1000-480B1FFF */
770 /* 480B2000-480B2FFF */ L4ID_HDQ1WIRE,
771 /* 480B3000-480B2FFF */ L4ID_HDQ1WIRE_TA,
772 /* 480B4000-480B4FFF */ L4ID_MMCSDIO2,
773 /* 480B5000-480B5FFF */ L4ID_MMCSDIO2_TA,
774 /* 480B6000-480B6FFF */ L4ID_ICRMPU,
775 /* 480B7000-480B7FFF */ L4ID_ICRMPU_TA,
776 /* 480B8000-480B8FFF */ L4ID_MCSPI3,
777 /* 480B9000-480B9FFF */ L4ID_MCSPI3_TA,
778 /* 480BA000-480BAFFF */ L4ID_MCSPI4,
779 /* 480BB000-480BBFFF */ L4ID_MCSPI4_TA,
780 /* 480BC000-480BFFFF */ L4ID_CAMERAISP,
781 /* 480C0000-480C0FFF */ L4ID_CAMERAISP_TA,
782 /* 480C1000-480CCFFF */
783 /* 480CD000-480CDFFF */ L4ID_ICRMODEM,
784 /* 480CE000-480CEFFF */ L4ID_ICRMODEM_TA,
785 /* 480CF000-482FFFFF */
786 /* 48300000-48303FFF */
787 /* 48304000-48304FFF */ L4ID_GPTIMER12,
788 /* 48305000-48305FFF */ L4ID_GPTIMER12_TA,
789 /* 48306000-48307FFF */ L4ID_PRM_A,
790 /* 48308000-483087FF */ L4ID_PRM_B,
791 /* 48308800-48308FFF */
792 /* 48309000-48309FFF */ L4ID_PRM_TA,
793 /* 4830A000-4830AFFF */ L4ID_TAP,
794 /* 4830B000-4830BFFF */ L4ID_TAP_TA,
795 /* 4830C000-4830FFFF */
796 /* 48310000-48310FFF */ L4ID_GPIO1,
797 /* 48311000-48311FFF */ L4ID_GPIO1_TA,
798 /* 48312000-48313FFF */
799 /* 48314000-48314FFF */ L4ID_WDTIMER2,
800 /* 48315000-48315FFF */ L4ID_WDTIMER2_TA,
801 /* 48316000-48317FFF */
802 /* 48318000-48318FFF */ L4ID_GPTIMER1,
803 /* 48319000-48319FFF */ L4ID_GPTIMER1_TA,
804 /* 4831A000-4831FFFF */
805 /* 48320000-48320FFF */ L4ID_32KTIMER,
806 /* 48321000-48321FFF */ L4ID_32KTIMER_TA,
807 /* 48322000-48327FFF */
808 /* 48328000-483287FF */ L4ID_WAKEUP_AP,
809 /* 48328800-48328FFF */ L4ID_WAKEUP_C_IP,
810 /* 48329000-48329FFF */ L4ID_WAKEUP_LA,
811 /* 4832A000-4832A7FF */ L4ID_WAKEUP_E_IP,
812 /* 4832A800-4833FFFF */
813 /* 48340000-48340FFF */
814 /* 48341000-48FFFFFF */
815 /* 49000000-490007FF */ L4ID_PER_AP,
816 /* 49000800-49000FFF */ L4ID_PER_IP,
817 /* 49001000-49001FFF */ L4ID_PER_LA,
818 /* 49002000-4901FFFF */
819 /* 49020000-49020FFF */ L4ID_UART3,
820 /* 49021000-49021FFF */ L4ID_UART3_TA,
821 /* 49022000-49022FFF */ L4ID_MCBSP2,
822 /* 49023000-49023FFF */ L4ID_MCBSP2_TA,
823 /* 49024000-49024FFF */ L4ID_MCBSP3,
824 /* 49025000-49025FFF */ L4ID_MCBSP3_TA,
825 /* 49026000-49026FFF */ L4ID_MCBSP4,
826 /* 49027000-49027FFF */ L4ID_MCBSP4_TA,
827 /* 49028000-49028FFF */ L4ID_MCBSP2S,
828 /* 49029000-49029FFF */ L4ID_MCBSP2S_TA,
829 /* 4902A000-4902AFFF */ L4ID_MCBSP3S,
830 /* 4902B000-4902BFFF */ L4ID_MCBSP3S_TA,
831 /* 4902C000-4902FFFF */
832 /* 49030000-49030FFF */ L4ID_WDTIMER3,
833 /* 49031000-49031FFF */ L4ID_WDTIMER3_TA,
834 /* 49032000-49032FFF */ L4ID_GPTIMER2,
835 /* 49033000-49033FFF */ L4ID_GPTIMER2_TA,
836 /* 49034000-49034FFF */ L4ID_GPTIMER3,
837 /* 49035000-49035FFF */ L4ID_GPTIMER3_TA,
838 /* 49036000-49036FFF */ L4ID_GPTIMER4,
839 /* 49037000-49037FFF */ L4ID_GPTIMER4_TA,
840 /* 49038000-49038FFF */ L4ID_GPTIMER5,
841 /* 49039000-49039FFF */ L4ID_GPTIMER5_TA,
842 /* 4903A000-4903AFFF */ L4ID_GPTIMER6,
843 /* 4903B000-4903BFFF */ L4ID_GPTIMER6_TA,
844 /* 4903C000-4903CFFF */ L4ID_GPTIMER7,
845 /* 4903D000-4903DFFF */ L4ID_GPTIMER7_TA,
846 /* 4903E000-4903EFFF */ L4ID_GPTIMER8,
847 /* 4903F000-4903FFFF */ L4ID_GPTIMER8_TA,
848 /* 49040000-49040FFF */ L4ID_GPTIMER9,
849 /* 49041000-49041FFF */ L4ID_GPTIMER9_TA,
850 /* 49042000-4904FFFF */
851 /* 49050000-49050FFF */ L4ID_GPIO2,
852 /* 49051000-49051FFF */ L4ID_GPIO2_TA,
853 /* 49052000-49052FFF */ L4ID_GPIO3,
854 /* 49053000-49053FFF */ L4ID_GPIO3_TA,
855 /* 49054000-49054FFF */ L4ID_GPIO4,
856 /* 49055000-49055FFF */ L4ID_GPIO4_TA,
857 /* 49056000-49056FFF */ L4ID_GPIO5,
858 /* 49057000-49057FFF */ L4ID_GPIO5_TA,
859 /* 49058000-49058FFF */ L4ID_GPIO6,
860 /* 49059000-49059FFF */ L4ID_GPIO6_TA,
861 /* 4905A000-490FFFFF */
862 /* 54000000-54003FFF */
863 /* 54004000-54005FFF */
864 /* 54006000-540067FF */ L4ID_EMU_AP,
865 /* 54006800-54006FFF */ L4ID_EMU_IP_C,
866 /* 54007000-54007FFF */ L4ID_EMU_LA,
867 /* 54008000-540087FF */ L4ID_EMU_IP_DAP,
868 /* 54008800-5400FFFF */
869 /* 54010000-54017FFF */ L4ID_MPUEMU,
870 /* 54018000-54018FFF */ L4ID_MPUEMU_TA,
871 /* 54019000-54019FFF */ L4ID_TPIU,
872 /* 5401A000-5401AFFF */ L4ID_TPIU_TA,
873 /* 5401B000-5401BFFF */ L4ID_ETB,
874 /* 5401C000-5401CFFF */ L4ID_ETB_TA,
875 /* 5401D000-5401DFFF */ L4ID_DAPCTL,
876 /* 5401E000-5401EFFF */ L4ID_DAPCTL_TA,
877 /* 5401F000-5401FFFF */ L4ID_SDTI_TA,
878 /* 54020000-544FFFFF */
879 /* 54500000-5450FFFF */ L4ID_SDTI_CFG,
880 /* 54510000-545FFFFF */
881 /* 54600000-546FFFFF */ L4ID_SDTI,
882 /* 54700000-54705FFF */
883 /* 54706000-54707FFF */ L4ID_EMU_PRM_A,
884 /* 54708000-547087FF */ L4ID_EMU_PRM_B,
885 /* 54708800-54708FFF */
886 /* 54709000-54709FFF */ L4ID_EMU_PRM_TA,
887 /* 5470A000-5470FFFF */
888 /* 54710000-54710FFF */ L4ID_EMU_GPIO1,
889 /* 54711000-54711FFF */ L4ID_EMU_GPIO1_TA,
890 /* 54712000-54713FFF */
891 /* 54714000-54714FFF */ L4ID_EMU_WDTM2,
892 /* 54715000-54715FFF */ L4ID_EMU_WDTM2_TA,
893 /* 54716000-54717FFF */
894 /* 54718000-54718FFF */ L4ID_EMU_GPTM1,
895 /* 54719000-54719FFF */ L4ID_EMU_GPTM1_TA,
896 /* 5471A000-5471FFFF */
897 /* 54720000-54720FFF */ L4ID_EMU_32KTM,
898 /* 54721000-54721FFF */ L4ID_EMU_32KTM_TA,
899 /* 54722000-54727FFF */
900 /* 54728000-547287FF */ L4ID_EMU_WKUP_AP,
901 /* 54728800-54728FFF */ L4ID_EMU_WKUP_IPC,
902 /* 54729000-54729FFF */ L4ID_EMU_WKUP_LA,
903 /* 5472A000-5472A7FF */ L4ID_EMU_WKUP_IPE,
904 /* 5472A800-547FFFFF */
907 static struct omap_l4_region_s omap3_l4_region[] = {
909 [L4ID_SCM ] = {0x00002000, 0x1000, 32 | 16 | 8},
910 [L4ID_SCM_TA ] = {0x00003000, 0x1000, 32 | 16 | 8},
911 [L4ID_CM_A ] = {0x00004000, 0x2000, 32 },
912 [L4ID_CM_B ] = {0x00006000, 0x0800, 32 },
913 [L4ID_CM_TA ] = {0x00007000, 0x1000, 32 | 16 | 8},
914 [L4ID_CORE_AP ] = {0x00040000, 0x0800, 32 },
915 [L4ID_CORE_IP ] = {0x00040800, 0x0800, 32 },
916 [L4ID_CORE_LA ] = {0x00041000, 0x1000, 32 },
917 [L4ID_DSI ] = {0x0004fc00, 0x0400, 32 | 16 | 8},
918 [L4ID_DSS ] = {0x00050000, 0x0400, 32 | 16 | 8},
919 [L4ID_DISPC ] = {0x00050400, 0x0400, 32 | 16 | 8},
920 [L4ID_RFBI ] = {0x00050800, 0x0400, 32 | 16 | 8},
921 [L4ID_VENC ] = {0x00050c00, 0x0400, 32 | 16 | 8},
922 [L4ID_DSS_TA ] = {0x00051000, 0x1000, 32 | 16 | 8},
923 [L4ID_SDMA ] = {0x00056000, 0x1000, 32 },
924 [L4ID_SDMA_TA ] = {0x00057000, 0x1000, 32 | 16 | 8},
925 [L4ID_I2C3 ] = {0x00060000, 0x1000, 16 | 8},
926 [L4ID_I2C3_TA ] = {0x00061000, 0x1000, 32 | 16 | 8},
927 [L4ID_USBTLL ] = {0x00062000, 0x1000, 32 },
928 [L4ID_USBTLL_TA ] = {0x00063000, 0x1000, 32 | 16 | 8},
929 [L4ID_HSUSBHOST ] = {0x00064000, 0x1000, 32 },
930 [L4ID_HSUSBHOST_TA] = {0x00065000, 0x1000, 32 | 16 | 8},
931 [L4ID_UART1 ] = {0x0006a000, 0x1000, 32 | 16 | 8},
932 [L4ID_UART1_TA ] = {0x0006b000, 0x1000, 32 | 16 | 8},
933 [L4ID_UART2 ] = {0x0006c000, 0x1000, 32 | 16 | 8},
934 [L4ID_UART2_TA ] = {0x0006d000, 0x1000, 32 | 16 | 8},
935 [L4ID_I2C1 ] = {0x00070000, 0x1000, 16 | 8},
936 [L4ID_I2C1_TA ] = {0x00071000, 0x1000, 32 | 16 | 8},
937 [L4ID_I2C2 ] = {0x00072000, 0x1000, 16 | 8},
938 [L4ID_I2C2_TA ] = {0x00073000, 0x1000, 32 | 16 | 8},
939 [L4ID_MCBSP1 ] = {0x00074000, 0x1000, 32 },
940 [L4ID_MCBSP1_TA ] = {0x00075000, 0x1000, 32 | 16 | 8},
941 [L4ID_GPTIMER10 ] = {0x00086000, 0x1000, 32 | 16 },
942 [L4ID_GPTIMER10_TA] = {0x00087000, 0x1000, 32 | 16 | 8},
943 [L4ID_GPTIMER11 ] = {0x00088000, 0x1000, 32 | 16 },
944 [L4ID_GPTIMER11_TA] = {0x00089000, 0x1000, 32 | 16 | 8},
945 [L4ID_MAILBOX ] = {0x00094000, 0x1000, 32 | 16 | 8},
946 [L4ID_MAILBOX_TA ] = {0x00095000, 0x1000, 32 | 16 | 8},
947 [L4ID_MCBSP5 ] = {0x00096000, 0x1000, 32 },
948 [L4ID_MCBSP5_TA ] = {0x00097000, 0x1000, 32 | 16 | 8},
949 [L4ID_MCSPI1 ] = {0x00098000, 0x1000, 32 | 16 | 8},
950 [L4ID_MCSPI1_TA ] = {0x00099000, 0x1000, 32 | 16 | 8},
951 [L4ID_MCSPI2 ] = {0x0009a000, 0x1000, 32 | 16 | 8},
952 [L4ID_MCSPI2_TA ] = {0x0009b000, 0x1000, 32 | 16 | 8},
953 [L4ID_MMCSDIO1 ] = {0x0009c000, 0x1000, 32 },
954 [L4ID_MMCSDIO1_TA ] = {0x0009d000, 0x1000, 32 | 16 | 8},
955 [L4ID_MSPRO ] = {0x0009e000, 0x1000, 32 },
956 [L4ID_MSPRO_TA ] = {0x0009f000, 0x1000, 32 | 16 | 8},
957 [L4ID_HSUSBOTG ] = {0x000ab000, 0x1000, 32 },
958 [L4ID_HSUSBOTG_TA ] = {0x000ac000, 0x1000, 32 | 16 | 8},
959 [L4ID_MMCSDIO3 ] = {0x000ad000, 0x1000, 32 },
960 [L4ID_MMCSDIO3_TA ] = {0x000ae000, 0x1000, 32 | 16 | 8},
961 [L4ID_HDQ1WIRE ] = {0x000b2000, 0x1000, 32 },
962 [L4ID_HDQ1WIRE_TA ] = {0x000b3000, 0x1000, 32 | 16 | 8},
963 [L4ID_MMCSDIO2 ] = {0x000b4000, 0x1000, 32 },
964 [L4ID_MMCSDIO2_TA ] = {0x000b5000, 0x1000, 32 | 16 | 8},
965 [L4ID_ICRMPU ] = {0x000b6000, 0x1000, 32 },
966 [L4ID_ICRMPU_TA ] = {0x000b7000, 0x1000, 32 | 16 | 8},
967 [L4ID_MCSPI3 ] = {0x000b8000, 0x1000, 32 | 16 | 8},
968 [L4ID_MCSPI3_TA ] = {0x000b9000, 0x1000, 32 | 16 | 8},
969 [L4ID_MCSPI4 ] = {0x000ba000, 0x1000, 32 | 16 | 8},
970 [L4ID_MCSPI4_TA ] = {0x000bb000, 0x1000, 32 | 16 | 8},
971 [L4ID_CAMERAISP ] = {0x000bc000, 0x4000, 32 | 16 | 8},
972 [L4ID_CAMERAISP_TA] = {0x000c0000, 0x1000, 32 | 16 | 8},
973 [L4ID_ICRMODEM ] = {0x000cd000, 0x1000, 32 },
974 [L4ID_ICRMODEM_TA ] = {0x000ce000, 0x1000, 32 | 16 | 8},
975 /* L4-Wakeup interconnect region A */
976 [L4ID_GPTIMER12 ] = {0x00304000, 0x1000, 32 | 16 },
977 [L4ID_GPTIMER12_TA] = {0x00305000, 0x1000, 32 | 16 | 8},
978 [L4ID_PRM_A ] = {0x00306000, 0x2000, 32 },
979 [L4ID_PRM_B ] = {0x00308000, 0x0800, 32 },
980 [L4ID_PRM_TA ] = {0x00309000, 0x1000, 32 | 16 | 8},
982 [L4ID_TAP ] = {0x0030a000, 0x1000, 32 | 16 | 8},
983 [L4ID_TAP_TA ] = {0x0030b000, 0x1000, 32 | 16 | 8},
984 /* L4-Wakeup interconnect region B */
985 [L4ID_GPIO1 ] = {0x00310000, 0x1000, 32 | 16 | 8},
986 [L4ID_GPIO1_TA ] = {0x00311000, 0x1000, 32 | 16 | 8},
987 [L4ID_WDTIMER2 ] = {0x00314000, 0x1000, 32 | 16 },
988 [L4ID_WDTIMER2_TA ] = {0x00315000, 0x1000, 32 | 16 | 8},
989 [L4ID_GPTIMER1 ] = {0x00318000, 0x1000, 32 | 16 },
990 [L4ID_GPTIMER1_TA ] = {0x00319000, 0x1000, 32 | 16 | 8},
991 [L4ID_32KTIMER ] = {0x00320000, 0x1000, 32 | 16 },
992 [L4ID_32KTIMER_TA ] = {0x00321000, 0x1000, 32 | 16 | 8},
993 [L4ID_WAKEUP_AP ] = {0x00328000, 0x0800, 32 | 16 | 8},
994 [L4ID_WAKEUP_C_IP ] = {0x00328800, 0x0800, 32 | 16 | 8},
995 [L4ID_WAKEUP_LA ] = {0x00329000, 0x1000, 32 | 16 | 8},
996 [L4ID_WAKEUP_E_IP ] = {0x0032a000, 0x0800, 32 | 16 | 8},
998 [L4ID_PER_AP ] = {0x01000000, 0x0800, 32 | 16 | 8},
999 [L4ID_PER_IP ] = {0x01000800, 0x0800, 32 | 16 | 8},
1000 [L4ID_PER_LA ] = {0x01001000, 0x1000, 32 | 16 | 8},
1001 [L4ID_UART3 ] = {0x01020000, 0x1000, 32 | 16 | 8},
1002 [L4ID_UART3_TA ] = {0x01021000, 0x1000, 32 | 16 | 8},
1003 [L4ID_MCBSP2 ] = {0x01022000, 0x1000, 32 },
1004 [L4ID_MCBSP2_TA ] = {0x01023000, 0x1000, 32 | 16 | 8},
1005 [L4ID_MCBSP3 ] = {0x01024000, 0x1000, 32 },
1006 [L4ID_MCBSP3_TA ] = {0x01025000, 0x1000, 32 | 16 | 8},
1007 [L4ID_MCBSP4 ] = {0x01026000, 0x1000, 32 },
1008 [L4ID_MCBSP4_TA ] = {0x01027000, 0x1000, 32 | 16 | 8},
1009 [L4ID_MCBSP2S ] = {0x01028000, 0x1000, 32 },
1010 [L4ID_MCBSP2S_TA ] = {0x01029000, 0x1000, 32 | 16 | 8},
1011 [L4ID_MCBSP3S ] = {0x0102a000, 0x1000, 32 },
1012 [L4ID_MCBSP3S_TA ] = {0x0102b000, 0x1000, 32 | 16 | 8},
1013 [L4ID_WDTIMER3 ] = {0x01030000, 0x1000, 32 | 16 },
1014 [L4ID_WDTIMER3_TA ] = {0x01031000, 0x1000, 32 | 16 | 8},
1015 [L4ID_GPTIMER2 ] = {0x01032000, 0x1000, 32 | 16 },
1016 [L4ID_GPTIMER2_TA ] = {0x01033000, 0x1000, 32 | 16 | 8},
1017 [L4ID_GPTIMER3 ] = {0x01034000, 0x1000, 32 | 16 },
1018 [L4ID_GPTIMER3_TA ] = {0x01035000, 0x1000, 32 | 16 | 8},
1019 [L4ID_GPTIMER4 ] = {0x01036000, 0x1000, 32 | 16 },
1020 [L4ID_GPTIMER4_TA ] = {0x01037000, 0x1000, 32 | 16 | 8},
1021 [L4ID_GPTIMER5 ] = {0x01038000, 0x1000, 32 | 16 },
1022 [L4ID_GPTIMER5_TA ] = {0x01039000, 0x1000, 32 | 16 | 8},
1023 [L4ID_GPTIMER6 ] = {0x0103a000, 0x1000, 32 | 16 },
1024 [L4ID_GPTIMER6_TA ] = {0x0103b000, 0x1000, 32 | 16 | 8},
1025 [L4ID_GPTIMER7 ] = {0x0103c000, 0x1000, 32 | 16 },
1026 [L4ID_GPTIMER7_TA ] = {0x0103d000, 0x1000, 32 | 16 | 8},
1027 [L4ID_GPTIMER8 ] = {0x0103e000, 0x1000, 32 | 16 },
1028 [L4ID_GPTIMER8_TA ] = {0x0103f000, 0x1000, 32 | 16 | 8},
1029 [L4ID_GPTIMER9 ] = {0x01040000, 0x1000, 32 | 16 },
1030 [L4ID_GPTIMER9_TA ] = {0x01041000, 0x1000, 32 | 16 | 8},
1031 [L4ID_GPIO2 ] = {0x01050000, 0x1000, 32 | 16 | 8},
1032 [L4ID_GPIO2_TA ] = {0x01051000, 0x1000, 32 | 16 | 8},
1033 [L4ID_GPIO3 ] = {0x01052000, 0x1000, 32 | 16 | 8},
1034 [L4ID_GPIO3_TA ] = {0x01053000, 0x1000, 32 | 16 | 8},
1035 [L4ID_GPIO4 ] = {0x01054000, 0x1000, 32 | 16 | 8},
1036 [L4ID_GPIO4_TA ] = {0x01055000, 0x1000, 32 | 16 | 8},
1037 [L4ID_GPIO5 ] = {0x01056000, 0x1000, 32 | 16 | 8},
1038 [L4ID_GPIO5_TA ] = {0x01057000, 0x1000, 32 | 16 | 8},
1039 [L4ID_GPIO6 ] = {0x01058000, 0x1000, 32 | 16 | 8},
1040 [L4ID_GPIO6_TA ] = {0x01059000, 0x1000, 32 | 16 | 8},
1042 [L4ID_EMU_AP ] = {0x0c006000, 0x0800, 32 | 16 | 8},
1043 [L4ID_EMU_IP_C ] = {0x0c006800, 0x0800, 32 | 16 | 8},
1044 [L4ID_EMU_LA ] = {0x0c007000, 0x1000, 32 | 16 | 8},
1045 [L4ID_EMU_IP_DAP ] = {0x0c008000, 0x0800, 32 | 16 | 8},
1046 [L4ID_MPUEMU ] = {0x0c010000, 0x8000, 32 | 16 | 8},
1047 [L4ID_MPUEMU_TA ] = {0x0c018000, 0x1000, 32 | 16 | 8},
1048 [L4ID_TPIU ] = {0x0c019000, 0x1000, 32 },
1049 [L4ID_TPIU_TA ] = {0x0c01a000, 0x1000, 32 | 16 | 8},
1050 [L4ID_ETB ] = {0x0c01b000, 0x1000, 32 },
1051 [L4ID_ETB_TA ] = {0x0c01c000, 0x1000, 32 | 16 | 8},
1052 [L4ID_DAPCTL ] = {0x0c01d000, 0x1000, 32 },
1053 [L4ID_DAPCTL_TA ] = {0x0c01e000, 0x1000, 32 | 16 | 8},
1054 [L4ID_EMU_PRM_A ] = {0x0c706000, 0x2000, 32 },
1055 [L4ID_EMU_PRM_B ] = {0x0c706800, 0x0800, 32 },
1056 [L4ID_EMU_PRM_TA ] = {0x0c709000, 0x1000, 32 | 16 | 8},
1057 [L4ID_EMU_GPIO1 ] = {0x0c710000, 0x1000, 32 | 16 | 8},
1058 [L4ID_EMU_GPIO1_TA] = {0x0c711000, 0x1000, 32 | 16 | 8},
1059 [L4ID_EMU_WDTM2 ] = {0x0c714000, 0x1000, 32 | 16 },
1060 [L4ID_EMU_WDTM2_TA] = {0x0c715000, 0x1000, 32 | 16 | 8},
1061 [L4ID_EMU_GPTM1 ] = {0x0c718000, 0x1000, 32 | 16 | 8},
1062 [L4ID_EMU_GPTM1_TA] = {0x0c719000, 0x1000, 32 | 16 | 8},
1063 [L4ID_EMU_32KTM ] = {0x0c720000, 0x1000, 32 | 16 },
1064 [L4ID_EMU_32KTM_TA] = {0x0c721000, 0x1000, 32 | 16 | 8},
1065 [L4ID_EMU_WKUP_AP ] = {0x0c728000, 0x0800, 32 | 16 | 8},
1066 [L4ID_EMU_WKUP_IPC] = {0x0c728800, 0x0800, 32 | 16 | 8},
1067 [L4ID_EMU_WKUP_LA ] = {0x0c729000, 0x1000, 32 | 16 | 8},
1068 [L4ID_EMU_WKUP_IPE] = {0x0c72a000, 0x0800, 32 | 16 | 8},
1071 enum omap3_l4_agent_info_id_t {
1108 static struct omap_l4_agent_info_s omap3_l4_agent_info[] = {
1109 /* L4-Core Target Agents */
1110 {L4A_DSS, L4ID_DSI, 6, 4},
1112 /* TODO: USBHS OTG */
1113 /* TODO: USBHS host */
1115 {L4A_UART1, L4ID_UART1, 2, 1},
1116 {L4A_UART2, L4ID_UART2, 2, 1},
1117 {L4A_I2C1, L4ID_I2C1, 2, 1},
1118 {L4A_I2C2, L4ID_I2C2, 2, 1},
1119 {L4A_I2C3, L4ID_I2C3, 2, 1},
1122 {L4A_GPTIMER10, L4ID_GPTIMER10, 2, 1},
1123 {L4A_GPTIMER11, L4ID_GPTIMER11, 2, 1},
1126 {L4A_MMC1, L4ID_MMCSDIO1, 2, 1},
1127 {L4A_MMC2, L4ID_MMCSDIO2, 2, 1},
1128 {L4A_MMC3, L4ID_MMCSDIO3, 2, 1},
1129 /* TODO: HDQ/1-Wire */
1134 {L4A_CM, L4ID_CM_A, 3, 2},
1135 {L4A_SCM, L4ID_SCM, 2, 1},
1136 {L4A_TAP, L4ID_TAP, 2, 1},
1137 /* L4-Wakeup Target Agents */
1138 {L4A_GPTIMER12, L4ID_GPTIMER12, 2, 1},
1139 {L4A_PRM, L4ID_PRM_A, 3, 2},
1140 {L4A_GPIO1, L4ID_GPIO1, 2, 1},
1141 {L4A_WDTIMER2, L4ID_WDTIMER2, 2, 1},
1142 {L4A_GPTIMER1, L4ID_GPTIMER1, 2, 1},
1143 {L4A_32KTIMER, L4ID_32KTIMER, 2, 1},
1144 /* L4-Per Target Agents */
1145 {L4A_UART3, L4ID_UART3, 2, 1},
1148 {L4A_GPTIMER2, L4ID_GPTIMER2, 2, 1},
1149 {L4A_GPTIMER3, L4ID_GPTIMER3, 2, 1},
1150 {L4A_GPTIMER4, L4ID_GPTIMER4, 2, 1},
1151 {L4A_GPTIMER5, L4ID_GPTIMER5, 2, 1},
1152 {L4A_GPTIMER6, L4ID_GPTIMER6, 2, 1},
1153 {L4A_GPTIMER7, L4ID_GPTIMER7, 2, 1},
1154 {L4A_GPTIMER8, L4ID_GPTIMER8, 2, 1},
1155 {L4A_GPTIMER9, L4ID_GPTIMER9, 2, 1},
1156 {L4A_GPIO2, L4ID_GPIO2, 2, 1},
1157 {L4A_GPIO3, L4ID_GPIO3, 2, 1},
1158 {L4A_GPIO4, L4ID_GPIO4, 2, 1},
1159 {L4A_GPIO5, L4ID_GPIO5, 2, 1},
1160 {L4A_GPIO6, L4ID_GPIO6, 2, 1},
1163 static uint32_t omap3_l4ta_read(void *opaque, target_phys_addr_t addr)
1165 struct omap_target_agent_s *s = (struct omap_target_agent_s *)opaque;
1168 case 0x00: /* COMPONENT_L */
1169 return s->component;
1170 case 0x04: /* COMPONENT_H */
1172 case 0x18: /* CORE_L */
1173 return s->component;
1174 case 0x1c: /* CORE_H */
1175 return (s->component >> 16);
1176 case 0x20: /* AGENT_CONTROL_L */
1178 case 0x24: /* AGENT_CONTROL_H */
1179 return s->control_h;
1180 case 0x28: /* AGENT_STATUS_L */
1182 case 0x2c: /* AGENT_STATUS_H */
1188 OMAP_BAD_REG(s->base + addr);
1192 static void omap3_l4ta_write(void *opaque, target_phys_addr_t addr,
1195 struct omap_target_agent_s *s = (struct omap_target_agent_s *)opaque;
1198 case 0x00: /* COMPONENT_L */
1199 case 0x04: /* COMPONENT_H */
1200 case 0x18: /* CORE_L */
1201 case 0x1c: /* CORE_H */
1202 OMAP_RO_REG(s->base + addr);
1204 case 0x20: /* AGENT_CONTROL_L */
1205 s->control = value & 0x00000701;
1207 case 0x24: /* AGENT_CONTROL_H */
1208 s->control_h = value & 0x100; /* TODO: shouldn't this be read-only? */
1210 case 0x28: /* AGENT_STATUS_L */
1212 s->status &= ~0x100; /* REQ_TIMEOUT */
1214 case 0x2c: /* AGENT_STATUS_H */
1215 /* no writable bits although the register is listed as RW */
1218 OMAP_BAD_REG(s->base + addr);
1223 static CPUReadMemoryFunc *omap3_l4ta_readfn[] = {
1224 omap_badwidth_read32,
1225 omap_badwidth_read32,
1229 static CPUWriteMemoryFunc *omap3_l4ta_writefn[] = {
1230 omap_badwidth_write32,
1231 omap_badwidth_write32,
1235 static struct omap_target_agent_s *omap3_l4ta_get(struct omap_l4_s *bus, int cs)
1238 struct omap_target_agent_s *ta = 0;
1239 struct omap_l4_agent_info_s *info = 0;
1241 for (i = 0; i < bus->ta_num; i++)
1242 if (omap3_l4_agent_info[i].ta == cs)
1245 info = &omap3_l4_agent_info[i];
1250 fprintf(stderr, "%s: bad target agent (%i)\n", __FUNCTION__, cs);
1255 ta->start = &omap3_l4_region[info->region];
1256 ta->regions = info->regions;
1258 ta->component = ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
1259 ta->status = 0x00000000;
1260 ta->control = 0x00000200; /* XXX 01000200 for L4TAO */
1262 iomemtype = l4_register_io_memory(0, omap3_l4ta_readfn,
1263 omap3_l4ta_writefn, ta);
1264 ta->base = omap_l4_attach(ta, info->ta_region, iomemtype);
1274 struct omap_mpu_state_s *mpu;
1276 /*IVA2_PRM Register */
1277 uint32_t rm_rstctrl_iva2; /*0x4830 6050 */
1278 uint32_t rm_rstst_iva2; /*0x4830 6058 */
1279 uint32_t pm_wkdep_iva2; /*0x4830 60C8 */
1280 uint32_t pm_pwstctrl_iva2; /*0x4830 60E0 */
1281 uint32_t pm_pwstst_iva2; /*0x4830 60E4 */
1282 uint32_t pm_prepwstst_iva2; /*0x4830 60E8 */
1283 uint32_t prm_irqstatus_iva2; /*0x4830 60F8 */
1284 uint32_t prm_irqenable_iva2; /*0x4830 60FC */
1286 /*OCP_System_Reg_PRM Register */
1287 uint32_t prm_revision; /*0x4830 6804 */
1288 uint32_t prm_sysconfig; /*0x4830 6814 */
1289 uint32_t prm_irqstatus_mpu; /*0x4830 6818 */
1290 uint32_t prm_irqenable_mpu; /*0x4830 681c */
1292 /*MPU_PRM Register */
1293 uint32_t rm_rstst_mpu; /*0x4830 6958 */
1294 uint32_t pm_wkdep_mpu; /*0x4830 69c8 */
1295 uint32_t pm_evgenctrl_mpu; /*0x4830 69d4 */
1296 uint32_t pm_evgenontim_mpu; /*0x4830 69d8 */
1297 uint32_t pm_evgenofftim_mpu; /*0x4830 69dc */
1298 uint32_t pm_pwstctrl_mpu; /*0x4830 69e0 */
1299 uint32_t pm_pwstst_mpu; /*0x4830 69e4 */
1300 uint32_t pm_perpwstst_mpu; /*0x4830 69e8 */
1302 /*CORE_PRM Register */
1303 uint32_t rm_rstst_core; /*0x4830 6a58 */
1304 uint32_t pm_wken1_core; /*0x4830 6aa0 */
1305 uint32_t pm_mpugrpsel1_core; /*0x4830 6aa4 */
1306 uint32_t pm_iva2grpsel1_core; /*0x4830 6aa8 */
1307 uint32_t pm_wkst1_core; /*0x4830 6ab0 */
1308 uint32_t pm_wkst3_core; /*0x4830 6ab8 */
1309 uint32_t pm_pwstctrl_core; /*0x4830 6ae0 */
1310 uint32_t pm_pwstst_core; /*0x4830 6ae4 */
1311 uint32_t pm_prepwstst_core; /*0x4830 6ae8 */
1312 uint32_t pm_wken3_core; /*0x4830 6af0 */
1313 uint32_t pm_iva2grpsel3_core; /*0x4830 6af4 */
1314 uint32_t pm_mpugrpsel3_core; /*0x4830 6af8 */
1316 /*SGX_PRM Register */
1317 uint32_t rm_rstst_sgx; /*0x4830 6b58 */
1318 uint32_t pm_wkdep_sgx; /*0x4830 6bc8 */
1319 uint32_t pm_pwstctrl_sgx; /*0x4830 6be0 */
1320 uint32_t pm_pwstst_sgx; /*0x4830 6be4 */
1321 uint32_t pm_prepwstst_sgx; /*0x4830 6be8 */
1323 /*WKUP_PRM Register */
1324 uint32_t pm_wken_wkup; /*0x4830 6ca0 */
1325 uint32_t pm_mpugrpsel_wkup; /*0x4830 6ca4 */
1326 uint32_t pm_iva2grpsel_wkup; /*0x4830 6ca8 */
1327 uint32_t pm_wkst_wkup; /*0x4830 6cb0 */
1329 /*Clock_Control_Reg_PRM Register */
1330 uint32_t prm_clksel; /*0x4830 6D40 */
1331 uint32_t prm_clkout_ctrl; /*0x4830 6D70 */
1333 /*DSS_PRM Register */
1334 uint32_t rm_rstst_dss; /*0x4830 6e58 */
1335 uint32_t pm_wken_dss; /*0x4830 6ea0 */
1336 uint32_t pm_wkdep_dss; /*0x4830 6ec8 */
1337 uint32_t pm_pwstctrl_dss; /*0x4830 6ee0 */
1338 uint32_t pm_pwstst_dss; /*0x4830 6ee4 */
1339 uint32_t pm_prepwstst_dss; /*0x4830 6ee8 */
1341 /*CAM_PRM Register */
1342 uint32_t rm_rstst_cam; /*0x4830 6f58 */
1343 uint32_t pm_wkdep_cam; /*0x4830 6fc8 */
1344 uint32_t pm_pwstctrl_cam; /*0x4830 6fe0 */
1345 uint32_t pm_pwstst_cam; /*0x4830 6fe4 */
1346 uint32_t pm_prepwstst_cam; /*0x4830 6fe8 */
1348 /*PER_PRM Register */
1349 uint32_t rm_rstst_per; /*0x4830 7058 */
1350 uint32_t pm_wken_per; /*0x4830 70a0 */
1351 uint32_t pm_mpugrpsel_per; /*0x4830 70a4 */
1352 uint32_t pm_iva2grpsel_per; /*0x4830 70a8 */
1353 uint32_t pm_wkst_per; /*0x4830 70b0 */
1354 uint32_t pm_wkdep_per; /*0x4830 70c8 */
1355 uint32_t pm_pwstctrl_per; /*0x4830 70e0 */
1356 uint32_t pm_pwstst_per; /*0x4830 70e4 */
1357 uint32_t pm_perpwstst_per; /*0x4830 70e8 */
1359 /*EMU_PRM Register */
1360 uint32_t rm_rstst_emu; /*0x4830 7158 */
1361 uint32_t pm_pwstst_emu; /*0x4830 71e4 */
1363 /*Global_Reg_PRM Register */
1364 uint32_t prm_vc_smps_sa; /*0x4830 7220 */
1365 uint32_t prm_vc_smps_vol_ra; /*0x4830 7224 */
1366 uint32_t prm_vc_smps_cmd_ra; /*0x4830 7228 */
1367 uint32_t prm_vc_cmd_val_0; /*0x4830 722c */
1368 uint32_t prm_vc_cmd_val_1; /*0x4830 7230 */
1369 uint32_t prm_vc_hc_conf; /*0x4830 7234 */
1370 uint32_t prm_vc_i2c_cfg; /*0x4830 7238 */
1371 uint32_t prm_vc_bypass_val; /*0x4830 723c */
1372 uint32_t prm_rstctrl; /*0x4830 7250 */
1373 uint32_t prm_rsttimer; /*0x4830 7254 */
1374 uint32_t prm_rstst; /*0x4830 7258 */
1375 uint32_t prm_voltctrl; /*0x4830 7260 */
1376 uint32_t prm_sram_pcharge; /*0x4830 7264 */
1377 uint32_t prm_clksrc_ctrl; /*0x4830 7270 */
1378 uint32_t prm_obs; /*0x4830 7280 */
1379 uint32_t prm_voltsetup1; /*0x4830 7290 */
1380 uint32_t prm_voltoffset; /*0x4830 7294 */
1381 uint32_t prm_clksetup; /*0x4830 7298 */
1382 uint32_t prm_polctrl; /*0x4830 729c */
1383 uint32_t prm_voltsetup2; /*0x4830 72a0 */
1385 /*NEON_PRM Register */
1386 uint32_t rm_rstst_neon; /*0x4830 7358 */
1387 uint32_t pm_wkdep_neon; /*0x4830 73c8 */
1388 uint32_t pm_pwstctrl_neon; /*0x4830 73e0 */
1389 uint32_t pm_pwstst_neon; /*0x4830 73e4 */
1390 uint32_t pm_prepwstst_neon; /*0x4830 73e8 */
1392 /*USBHOST_PRM Register */
1393 uint32_t rm_rstst_usbhost; /*0x4830 7458 */
1394 uint32_t pm_wken_usbhost; /*0x4830 74a0 */
1395 uint32_t pm_mpugrpsel_usbhost; /*0x4830 74a4 */
1396 uint32_t pm_iva2grpsel_usbhost; /*0x4830 74a8 */
1397 uint32_t pm_wkst_usbhost; /*0x4830 74b0 */
1398 uint32_t pm_wkdep_usbhost; /*0x4830 74c8 */
1399 uint32_t pm_pwstctrl_usbhost; /*0x4830 74e0 */
1400 uint32_t pm_pwstst_usbhost; /*0x4830 74e4 */
1401 uint32_t pm_prepwstst_usbhost; /*0x4830 74e8 */
1405 static void omap3_prm_int_update(struct omap3_prm_s *s)
1407 qemu_set_irq(s->mpu_irq, s->prm_irqstatus_mpu & s->prm_irqenable_mpu);
1408 qemu_set_irq(s->iva_irq, s->prm_irqstatus_iva2 & s->prm_irqenable_iva2);
1411 static void omap3_prm_reset(struct omap3_prm_s *s)
1413 s->rm_rstctrl_iva2 = 0x7;
1414 s->rm_rstst_iva2 = 0x1;
1415 s->pm_wkdep_iva2 = 0xb3;
1416 s->pm_pwstctrl_iva2 = 0xff0f07;
1417 s->pm_pwstst_iva2 = 0xff7;
1418 s->pm_prepwstst_iva2 = 0x0;
1419 s->prm_irqstatus_iva2 = 0x0;
1420 s->prm_irqenable_iva2 = 0x0;
1422 s->prm_revision = 0x10;
1423 s->prm_sysconfig = 0x1;
1424 s->prm_irqstatus_mpu = 0x0;
1425 s->prm_irqenable_mpu = 0x0;
1427 s->rm_rstst_mpu = 0x1;
1428 s->pm_wkdep_mpu = 0xa5;
1429 s->pm_evgenctrl_mpu = 0x12;
1430 s->pm_evgenontim_mpu = 0x0;
1431 s->pm_evgenofftim_mpu = 0x0;
1432 s->pm_pwstctrl_mpu = 0x30107;
1433 s->pm_pwstst_mpu = 0xc7;
1434 s->pm_pwstst_mpu = 0x0;
1436 s->rm_rstst_core = 0x1;
1437 s->pm_wken1_core = 0xc33ffe18;
1438 s->pm_mpugrpsel1_core = 0xc33ffe18;
1439 s->pm_iva2grpsel1_core = 0xc33ffe18;
1440 s->pm_wkst1_core = 0x0;
1441 s->pm_wkst3_core = 0x0;
1442 s->pm_pwstctrl_core = 0xf0307;
1443 s->pm_pwstst_core = 0xf7;
1444 s->pm_prepwstst_core = 0x0;
1445 s->pm_wken3_core = 0x4;
1446 s->pm_iva2grpsel3_core = 0x4;
1447 s->pm_mpugrpsel3_core = 0x4;
1449 s->rm_rstst_sgx = 0x1;
1450 s->pm_wkdep_sgx = 0x16;
1451 s->pm_pwstctrl_sgx = 0x30107;
1452 s->pm_pwstst_sgx = 0x3;
1453 s->pm_prepwstst_sgx = 0x0;
1455 s->pm_wken_wkup = 0x3cb;
1456 s->pm_mpugrpsel_wkup = 0x3cb;
1457 s->pm_iva2grpsel_wkup = 0x0;
1458 s->pm_wkst_wkup = 0x0;
1460 s->prm_clksel = 0x4;
1461 s->prm_clkout_ctrl = 0x80;
1463 s->rm_rstst_dss = 0x1;
1464 s->pm_wken_dss = 0x1;
1465 s->pm_wkdep_dss = 0x16;
1466 s->pm_pwstctrl_dss = 0x30107;
1467 s->pm_pwstst_dss = 0x3;
1468 s->pm_prepwstst_dss = 0x0;
1470 s->rm_rstst_cam = 0x1;
1471 s->pm_wkdep_cam = 0x16;
1472 s->pm_pwstctrl_cam = 0x30107;
1473 s->pm_pwstst_cam = 0x3;
1474 s->pm_prepwstst_cam = 0x0;
1476 s->rm_rstst_per = 0x1;
1477 s->pm_wken_per = 0x3efff;
1478 s->pm_mpugrpsel_per = 0x3efff;
1479 s->pm_iva2grpsel_per = 0x3efff;
1480 s->pm_wkst_per = 0x0;
1481 s->pm_wkdep_per = 0x17;
1482 s->pm_pwstctrl_per = 0x30107;
1483 s->pm_pwstst_per = 0x7;
1484 s->pm_perpwstst_per = 0x0;
1486 s->rm_rstst_emu = 0x1;
1487 s->pm_pwstst_emu = 0x13;
1489 s->prm_vc_smps_sa = 0x0;
1490 s->prm_vc_smps_vol_ra = 0x0;
1491 s->prm_vc_smps_cmd_ra = 0x0;
1492 s->prm_vc_cmd_val_0 = 0x0;
1493 s->prm_vc_cmd_val_1 = 0x0;
1494 s->prm_vc_hc_conf = 0x0;
1495 s->prm_vc_i2c_cfg = 0x18;
1496 s->prm_vc_bypass_val = 0x0;
1497 s->prm_rstctrl = 0x0;
1498 s->prm_rsttimer = 0x1006;
1500 s->prm_voltctrl = 0x0;
1501 s->prm_sram_pcharge = 0x50;
1502 s->prm_clksrc_ctrl = 0x43;
1504 s->prm_voltsetup1 = 0x0;
1505 s->prm_voltoffset = 0x0;
1506 s->prm_clksetup = 0x0;
1507 s->prm_polctrl = 0xa;
1508 s->prm_voltsetup2 = 0x0;
1510 s->rm_rstst_neon = 0x1;
1511 s->pm_wkdep_neon = 0x2;
1512 s->pm_pwstctrl_neon = 0x7;
1513 s->pm_pwstst_neon = 0x3;
1514 s->pm_prepwstst_neon = 0x0;
1516 s->rm_rstst_usbhost = 0x1;
1517 s->pm_wken_usbhost = 0x1;
1518 s->pm_mpugrpsel_usbhost = 0x1;
1519 s->pm_iva2grpsel_usbhost = 0x1;
1520 s->pm_wkst_usbhost = 0x0;
1521 s->pm_wkdep_usbhost = 0x17;
1522 s->pm_pwstctrl_usbhost = 0x30107;
1523 s->pm_pwstst_usbhost = 0x3;
1524 s->pm_prepwstst_usbhost = 0x0;
1526 omap3_prm_int_update(s);
1529 static uint32_t omap3_prm_read(void *opaque, target_phys_addr_t addr)
1531 struct omap3_prm_s *s = (struct omap3_prm_s *)opaque;
1533 TRACE("%04x", addr);
1536 case 0x0050: return s->rm_rstctrl_iva2;
1537 case 0x0058: return s->rm_rstst_iva2;
1538 case 0x00c8: return s->pm_wkdep_iva2;
1539 case 0x00e0: return s->pm_pwstctrl_iva2;
1540 case 0x00e4: return s->pm_pwstst_iva2;
1541 case 0x00e8: return s->pm_prepwstst_iva2;
1542 case 0x00f8: return s->prm_irqstatus_iva2;
1543 case 0x00fc: return s->prm_irqenable_iva2;
1544 /* OCP_System_Reg_PRM */
1545 case 0x0804: return s->prm_revision;
1546 case 0x0814: return s->prm_sysconfig;
1547 case 0x0818: return s->prm_irqstatus_mpu;
1548 case 0x081c: return s->prm_irqenable_mpu;
1550 case 0x0958: return s->rm_rstst_mpu;
1551 case 0x09c8: return s->pm_wkdep_mpu;
1552 case 0x09d4: return s->pm_evgenctrl_mpu;
1553 case 0x09d8: return s->pm_evgenontim_mpu;
1554 case 0x09dc: return s->pm_evgenofftim_mpu;
1555 case 0x09e0: return s->pm_pwstctrl_mpu;
1556 case 0x09e4: return s->pm_pwstst_mpu;
1557 case 0x09e8: return s->pm_perpwstst_mpu;
1559 case 0x0a58: return s->rm_rstst_core;
1560 case 0x0aa0: return s->pm_wken1_core;
1561 case 0x0aa4: return s->pm_mpugrpsel1_core;
1562 case 0x0aa8: return s->pm_iva2grpsel1_core;
1563 case 0x0ab0: return s->pm_wkst1_core;
1564 case 0x0ab8: return s->pm_wkst3_core;
1565 case 0x0ae0: return s->pm_pwstctrl_core;
1566 case 0x0ae4: return s->pm_pwstst_core;
1567 case 0x0ae8: return s->pm_prepwstst_core;
1568 case 0x0af0: return s->pm_wken3_core;
1569 case 0x0af4: return s->pm_iva2grpsel3_core;
1570 case 0x0af8: return s->pm_mpugrpsel3_core;
1572 case 0x0b58: return s->rm_rstst_sgx;
1573 case 0x0bc8: return s->pm_wkdep_sgx;
1574 case 0x0be0: return s->pm_pwstctrl_sgx;
1575 case 0x0be4: return s->pm_pwstst_sgx;
1576 case 0x0be8: return s->pm_prepwstst_sgx;
1578 case 0x0ca0: return s->pm_wken_wkup;
1579 case 0x0ca4: return s->pm_mpugrpsel_wkup;
1580 case 0x0ca8: return s->pm_iva2grpsel_wkup;
1581 case 0x0cb0: return s->pm_wkst_wkup;
1582 //case 0x0ce4: return 0x3; /* power on */
1583 /* Clock_Control_Reg_PRM */
1584 case 0x0d40: return s->prm_clksel;
1585 case 0x0d70: return s->prm_clkout_ctrl;
1586 //case 0x0de4: return 0x3; /* power on */
1588 case 0x0e58: return s->rm_rstst_dss;
1589 case 0x0ea0: return s->pm_wken_dss;
1590 case 0x0ec8: return s->pm_wkdep_dss;
1591 case 0x0ee0: return s->pm_pwstctrl_dss;
1592 case 0x0ee4: return s->pm_pwstst_dss;
1593 case 0x0ee8: return s->pm_prepwstst_dss;
1595 case 0x0f58: return s->rm_rstst_cam;
1596 case 0x0fc8: return s->pm_wkdep_cam;
1597 case 0x0fe0: return s->pm_pwstctrl_cam;
1598 case 0x0fe4: return s->pm_pwstst_cam;
1599 case 0x0fe8: return s->pm_prepwstst_cam;
1601 case 0x1058: return s->rm_rstst_per;
1602 case 0x10a0: return s->pm_wken_per;
1603 case 0x10a4: return s->pm_mpugrpsel_per;
1604 case 0x10a8: return s->pm_iva2grpsel_per;
1605 case 0x10b0: return s->pm_wkst_per;
1606 case 0x10c8: return s->pm_wkdep_per;
1607 case 0x10e0: return s->pm_pwstctrl_per;
1608 case 0x10e4: return s->pm_pwstst_per;
1609 case 0x10e8: return s->pm_perpwstst_per;
1611 case 0x1158: return s->rm_rstst_emu;
1612 case 0x11e4: return s->pm_pwstst_emu;
1613 /* Global_Reg_PRM */
1614 case 0x1220: return s->prm_vc_smps_sa;
1615 case 0x1224: return s->prm_vc_smps_vol_ra;
1616 case 0x1228: return s->prm_vc_smps_cmd_ra;
1617 case 0x122c: return s->prm_vc_cmd_val_0;
1618 case 0x1230: return s->prm_vc_cmd_val_1;
1619 case 0x1234: return s->prm_vc_hc_conf;
1620 case 0x1238: return s->prm_vc_i2c_cfg;
1621 case 0x123c: return s->prm_vc_bypass_val;
1622 case 0x1250: return s->prm_rstctrl;
1623 case 0x1254: return s->prm_rsttimer;
1624 case 0x1258: return s->prm_rstst;
1625 case 0x1260: return s->prm_voltctrl;
1626 case 0x1264: return s->prm_sram_pcharge;
1627 case 0x1270: return s->prm_clksrc_ctrl;
1628 case 0x1280: return s->prm_obs;
1629 case 0x1290: return s->prm_voltsetup1;
1630 case 0x1294: return s->prm_voltoffset;
1631 case 0x1298: return s->prm_clksetup;
1632 case 0x129c: return s->prm_polctrl;
1633 case 0x12a0: return s->prm_voltsetup2;
1635 case 0x1358: return s->rm_rstst_neon;
1636 case 0x13c8: return s->pm_wkdep_neon;
1637 case 0x13e0: return s->pm_pwstctrl_neon;
1638 case 0x13e4: return s->pm_pwstst_neon;
1639 case 0x13e8: return s->pm_prepwstst_neon;
1641 case 0x1458: return s->rm_rstst_usbhost;
1642 case 0x14a0: return s->pm_wken_usbhost;
1643 case 0x14a4: return s->pm_mpugrpsel_usbhost;
1644 case 0x14a8: return s->pm_iva2grpsel_usbhost;
1645 case 0x14b0: return s->pm_wkst_usbhost;
1646 case 0x14c8: return s->pm_wkdep_usbhost;
1647 case 0x14e0: return s->pm_pwstctrl_usbhost;
1648 case 0x14e4: return s->pm_pwstst_usbhost;
1649 case 0x14e8: return s->pm_prepwstst_usbhost;
1656 static inline void omap3_prm_clksrc_ctrl_update(struct omap3_prm_s *s,
1659 if ((value & 0xd0) == 0x40)
1660 omap_clk_setrate(omap_findclk(s->mpu, "omap3_sys_clk"), 1, 1);
1661 else if ((value & 0xd0) == 0x80)
1662 omap_clk_setrate(omap_findclk(s->mpu, "omap3_sys_clk"), 2, 1);
1665 static void omap3_prm_write(void *opaque, target_phys_addr_t addr,
1668 struct omap3_prm_s *s = (struct omap3_prm_s *)opaque;
1670 TRACE("%04x = %08x", addr, value);
1673 case 0x0050: s->rm_rstctrl_iva2 = value & 0x7; break;
1674 case 0x0058: s->rm_rstst_iva2 &= ~(value & 0x3f0f); break;
1675 case 0x00c8: s->pm_wkdep_iva2 = value & 0xb3; break;
1676 case 0x00e0: s->pm_pwstctrl_iva2 = 0xcff000 | (value & 0x300f0f); break;
1677 case 0x00e4: OMAP_RO_REG(addr); break;
1678 case 0x00e8: s->pm_prepwstst_iva2 = value & 0xff7;
1680 s->prm_irqstatus_iva2 &= ~(value & 0x7);
1681 omap3_prm_int_update(s);
1684 s->prm_irqenable_iva2 = value & 0x7;
1685 omap3_prm_int_update(s);
1687 /* OCP_System_Reg_PRM */
1688 case 0x0804: OMAP_RO_REG(addr); break;
1689 case 0x0814: s->prm_sysconfig = value & 0x1; break;
1691 s->prm_irqstatus_mpu &= ~(value & 0x03c003fd);
1692 omap3_prm_int_update(s);
1695 s->prm_irqenable_mpu = value & 0x03c003fd;
1696 omap3_prm_int_update(s);
1699 case 0x0958: s->rm_rstst_mpu &= ~(value & 0x080f); break;
1700 case 0x09c8: s->pm_wkdep_mpu = value & 0xa5; break;
1701 case 0x09d4: s->pm_evgenctrl_mpu = value & 0x1f; break;
1702 case 0x09d8: s->pm_evgenontim_mpu = value; break;
1703 case 0x09dc: s->pm_evgenofftim_mpu = value; break;
1704 case 0x09e0: s->pm_pwstctrl_mpu = value & 0x3010f; break;
1705 case 0x09e4: OMAP_RO_REG(addr); break;
1706 case 0x09e8: s->pm_perpwstst_mpu = value & 0xc7; break;
1708 case 0x0a58: s->rm_rstst_core &= ~(value & 0x7); break;
1709 case 0x0aa0: s->pm_wken1_core = 0x80000008 | (value & 0x433ffe10); break;
1710 case 0x0aa4: s->pm_mpugrpsel1_core = 0x80000008 | (value & 0x433ffe10); break;
1711 case 0x0aa8: s->pm_iva2grpsel1_core = 0x80000008 | (value & 0x433ffe10); break;
1712 case 0x0ab0: s->pm_wkst1_core = value & 0x433ffe10; break;
1713 case 0x0ab8: s->pm_wkst3_core &= ~(value & 0x4); break;
1714 case 0x0ae0: s->pm_pwstctrl_core = (value & 0x0f031f); break;
1715 case 0x0ae4: OMAP_RO_REG(addr); break;
1716 case 0x0ae8: s->pm_prepwstst_core = value & 0xf7; break;
1717 case 0x0af0: s->pm_wken3_core = value & 0x4; break;
1718 case 0x0af4: s->pm_iva2grpsel3_core = value & 0x4; break;
1719 case 0x0af8: s->pm_mpugrpsel3_core = value & 0x4; break;
1721 case 0x0b58: s->rm_rstst_sgx &= ~(value & 0xf); break;
1722 case 0x0bc8: s->pm_wkdep_sgx = value & 0x16; break;
1723 case 0x0be0: s->pm_pwstctrl_sgx = 0x030104 | (value & 0x3); break;
1724 case 0x0be4: OMAP_RO_REG(addr); break;
1725 case 0x0be8: s->pm_prepwstst_sgx = value & 0x3; break;
1727 case 0x0ca0: s->pm_wken_wkup = 0x2 | (value & 0x0103c9); break;
1728 case 0x0ca4: s->pm_mpugrpsel_wkup = 0x0102 | (value & 0x02c9); break;
1729 case 0x0ca8: s->pm_iva2grpsel_wkup = value & 0x03cb; break;
1730 case 0x0cb0: s->pm_wkst_wkup &= ~(value & 0x0103cb); break;
1731 /* Clock_Control_Reg_PRM */
1733 s->prm_clksel = value & 0x7;
1734 fprintf(stderr, "%s PRM_CLKSEL = 0x%x\n", __FUNCTION__,
1736 /* TODO: update clocks */
1739 s->prm_clkout_ctrl = value & 0x80;
1740 fprintf(stderr, "%s PRM_CLKOUT_CTRL = 0x%x\n", __FUNCTION__,
1741 s->prm_clkout_ctrl);
1742 /* TODO: update clocks */
1745 case 0x0e58: s->rm_rstst_dss &= ~(value & 0xf); break;
1746 case 0x0ea0: s->pm_wken_dss = value & 1; break;
1747 case 0x0ec8: s->pm_wkdep_dss = value & 0x16; break;
1748 case 0x0ee0: s->pm_pwstctrl_dss = 0x030104 | (value & 3); break;
1749 case 0x0ee4: OMAP_RO_REG(addr); break;
1750 case 0x0ee8: s->pm_prepwstst_dss = value & 3; break;
1752 case 0x0f58: s->rm_rstst_cam &= (value & 0xf); break;
1753 case 0x0fc8: s->pm_wkdep_cam = value & 0x16; break;
1754 case 0x0fe0: s->pm_pwstctrl_cam = 0x030104 | (value & 3); break;
1755 case 0x0fe4: OMAP_RO_REG(addr); break;
1756 case 0x0fe8: s->pm_prepwstst_cam = value & 0x3; break;
1758 case 0x1058: s->rm_rstst_per &= ~(value & 0xf); break;
1759 case 0x10a0: s->pm_wken_per = value & 0x03efff; break;
1760 case 0x10a4: s->pm_mpugrpsel_per = value & 0x03efff; break;
1761 case 0x10a8: s->pm_iva2grpsel_per = value & 0x03efff; break;
1762 case 0x10b0: s->pm_wkst_per &= ~(value & 0x03efff); break;
1763 case 0x10c8: s->pm_wkdep_per = value & 0x17; break;
1764 case 0x10e0: s->pm_pwstctrl_per = 0x030100 | (value & 7); break;
1765 case 0x10e4: OMAP_RO_REG(addr); break;
1766 case 0x10e8: s->pm_perpwstst_per = value & 0x7; break;
1768 case 0x1158: s->rm_rstst_emu &= ~(value & 7); break;
1769 case 0x11e4: OMAP_RO_REG(addr); break;
1770 /* Global_Reg_PRM */
1771 case 0x1220: s->prm_vc_smps_sa = value & 0x7f007f; break;
1772 case 0x1224: s->prm_vc_smps_vol_ra = value & 0xff00ff; break;
1773 case 0x1228: s->prm_vc_smps_cmd_ra = value & 0xff00ff; break;
1774 case 0x122c: s->prm_vc_cmd_val_0 = value; break;
1775 case 0x1230: s->prm_vc_cmd_val_1 = value; break;
1776 case 0x1234: s->prm_vc_hc_conf = value & 0x1f001f; break;
1777 case 0x1238: s->prm_vc_i2c_cfg = value & 0x3f; break;
1778 case 0x123c: s->prm_vc_bypass_val = value & 0x01ffff7f; break;
1779 case 0x1250: s->prm_rstctrl = 0; break; /* TODO: resets */
1780 case 0x1254: s->prm_rsttimer = value & 0x1fff; break;
1781 case 0x1258: s->prm_rstst &= ~(value & 0x7fb); break;
1782 case 0x1260: s->prm_voltctrl = value & 0x1f; break;
1783 case 0x1264: s->prm_sram_pcharge = value & 0xff; break;
1785 s->prm_clksrc_ctrl = value & (0xd8);
1786 omap3_prm_clksrc_ctrl_update(s, s->prm_clksrc_ctrl);
1787 /* TODO: update SYSCLKSEL bits */
1789 case 0x1280: OMAP_RO_REG(addr); break;
1790 case 0x1290: s->prm_voltsetup1 = value; break;
1791 case 0x1294: s->prm_voltoffset = value & 0xffff; break;
1792 case 0x1298: s->prm_clksetup = value & 0xffff; break;
1793 case 0x129c: s->prm_polctrl = value & 0xf; break;
1794 case 0x12a0: s->prm_voltsetup2 = value & 0xffff; break;
1796 case 0x1358: s->rm_rstst_neon &= ~(value & 0xf); break;
1797 case 0x13c8: s->pm_wkdep_neon = value & 0x2; break;
1798 case 0x13e0: s->pm_pwstctrl_neon = 0x4 | (value & 3); break;
1799 case 0x13e4: OMAP_RO_REG(addr); break;
1800 case 0x13e8: s->pm_prepwstst_neon = value & 3; break;
1802 case 0x1458: s->rm_rstst_usbhost &= ~(value & 0xf); break;
1803 case 0x14a0: s->pm_wken_usbhost = value & 1; break;
1804 case 0x14a4: s->pm_mpugrpsel_usbhost = value & 1; break;
1805 case 0x14a8: s->pm_iva2grpsel_usbhost = value & 1; break;
1806 case 0x14b0: s->pm_wkst_usbhost &= ~(value & 1); break;
1807 case 0x14c8: s->pm_wkdep_usbhost = value & 0x17; break;
1808 case 0x14e0: s->pm_pwstctrl_usbhost = 0x030104 | (value & 0x13); break;
1809 case 0x14e4: OMAP_RO_REG(addr); break;
1810 case 0x14e8: s->pm_prepwstst_usbhost = value & 3; break;
1812 OMAP_BAD_REGV(addr, value);
1817 static CPUReadMemoryFunc *omap3_prm_readfn[] = {
1818 omap_badwidth_read32,
1819 omap_badwidth_read32,
1823 static CPUWriteMemoryFunc *omap3_prm_writefn[] = {
1824 omap_badwidth_write32,
1825 omap_badwidth_write32,
1829 struct omap3_prm_s *omap3_prm_init(struct omap_target_agent_s *ta,
1830 qemu_irq mpu_int, qemu_irq iva_int,
1831 struct omap_mpu_state_s *mpu)
1834 struct omap3_prm_s *s = (struct omap3_prm_s *) qemu_mallocz(sizeof(*s));
1836 s->mpu_irq = mpu_int;
1837 s->iva_irq = iva_int;
1841 iomemtype = l4_register_io_memory(0, omap3_prm_readfn,
1842 omap3_prm_writefn, s);
1843 omap_l4_attach(ta, 0, iomemtype);
1844 omap_l4_attach(ta, 1, iomemtype);
1853 struct omap_mpu_state_s *mpu;
1855 /*IVA2_CM Register */
1856 uint32_t cm_fclken_iva2; /*0x4800 4000 */
1857 uint32_t cm_clken_pll_iva2; /*0x4800 4004 */
1858 uint32_t cm_idlest_iva2; /*0x4800 4020 */
1859 uint32_t cm_idlest_pll_iva2; /*0x4800 4024 */
1860 uint32_t cm_autoidle_pll_iva2; /*0x4800 4034 */
1861 uint32_t cm_clksel1_pll_iva2; /*0x4800 4040 */
1862 uint32_t cm_clksel2_pll_iva2; /*0x4800 4044 */
1863 uint32_t cm_clkstctrl_iva2; /*0x4800 4048 */
1864 uint32_t cm_clkstst_iva2; /*0x4800 404c */
1866 /*OCP_System_Reg_CM */
1867 uint32_t cm_revision; /*0x4800 4800 */
1868 uint32_t cm_sysconfig; /*0x4800 4810 */
1870 /*MPU_CM Register */
1871 uint32_t cm_clken_pll_mpu; /*0x4800 4904 */
1872 uint32_t cm_idlest_mpu; /*0x4800 4920 */
1873 uint32_t cm_idlest_pll_mpu; /*0x4800 4924 */
1874 uint32_t cm_autoidle_pll_mpu; /*0x4800 4934 */
1875 uint32_t cm_clksel1_pll_mpu; /*0x4800 4940 */
1876 uint32_t cm_clksel2_pll_mpu; /*0x4800 4944 */
1877 uint32_t cm_clkstctrl_mpu; /*0x4800 4948 */
1878 uint32_t cm_clkstst_mpu; /*0x4800 494c */
1880 /*CORE_CM Register */
1881 uint32_t cm_fclken1_core; /*0x4800 4a00 */
1882 uint32_t cm_fclken3_core; /*0x4800 4a08 */
1883 uint32_t cm_iclken1_core; /*0x4800 4a10 */
1884 uint32_t cm_iclken2_core; /*0x4800 4a14 */
1885 uint32_t cm_iclken3_core; /*0x4800 4a18 */
1886 uint32_t cm_idlest1_core; /*0x4800 4a20 */
1887 uint32_t cm_idlest2_core; /*0x4800 4a24 */
1888 uint32_t cm_idlest3_core; /*0x4800 4a28 */
1889 uint32_t cm_autoidle1_core; /*0x4800 4a30 */
1890 uint32_t cm_autoidle2_core; /*0x4800 4a34 */
1891 uint32_t cm_autoidle3_core; /*0x4800 4a38 */
1892 uint32_t cm_clksel_core; /*0x4800 4a40 */
1893 uint32_t cm_clkstctrl_core; /*0x4800 4a48 */
1894 uint32_t cm_clkstst_core; /*0x4800 4a4c */
1896 /*SGX_CM Register */
1897 uint32_t cm_fclken_sgx; /*0x4800 4b00 */
1898 uint32_t cm_iclken_sgx; /*0x4800 4b10 */
1899 uint32_t cm_idlest_sgx; /*0x4800 4b20 */
1900 uint32_t cm_clksel_sgx; /*0x4800 4b40 */
1901 uint32_t cm_sleepdep_sgx; /*0x4800 4b44 */
1902 uint32_t cm_clkstctrl_sgx; /*0x4800 4b48 */
1903 uint32_t cm_clkstst_sgx; /*0x4800 4b4c */
1905 /*WKUP_CM Register */
1906 uint32_t cm_fclken_wkup; /*0x4800 4c00 */
1907 uint32_t cm_iclken_wkup; /*0x4800 4c10 */
1908 uint32_t cm_idlest_wkup; /*0x4800 4c20 */
1909 uint32_t cm_autoidle_wkup; /*0x4800 4c30 */
1910 uint32_t cm_clksel_wkup; /*0x4800 4c40 */
1911 uint32_t cm_c48; /*0x4800 4c48 */
1913 /*Clock_Control_Reg_CM Register */
1914 uint32_t cm_clken_pll; /*0x4800 4d00 */
1915 uint32_t cm_clken2_pll; /*0x4800 4d04 */
1916 uint32_t cm_idlest_ckgen; /*0x4800 4d20 */
1917 uint32_t cm_idlest2_ckgen; /*0x4800 4d24 */
1918 uint32_t cm_autoidle_pll; /*0x4800 4d30 */
1919 uint32_t cm_autoidle2_pll; /*0x4800 4d34 */
1920 uint32_t cm_clksel1_pll; /*0x4800 4d40 */
1921 uint32_t cm_clksel2_pll; /*0x4800 4d44 */
1922 uint32_t cm_clksel3_pll; /*0x4800 4d48 */
1923 uint32_t cm_clksel4_pll; /*0x4800 4d4c */
1924 uint32_t cm_clksel5_pll; /*0x4800 4d50 */
1925 uint32_t cm_clkout_ctrl; /*0x4800 4d70 */
1927 /*DSS_CM Register */
1928 uint32_t cm_fclken_dss; /*0x4800 4e00 */
1929 uint32_t cm_iclken_dss; /*0x4800 4e10 */
1930 uint32_t cm_idlest_dss; /*0x4800 4e20 */
1931 uint32_t cm_autoidle_dss; /*0x4800 4e30 */
1932 uint32_t cm_clksel_dss; /*0x4800 4e40 */
1933 uint32_t cm_sleepdep_dss; /*0x4800 4e44 */
1934 uint32_t cm_clkstctrl_dss; /*0x4800 4e48 */
1935 uint32_t cm_clkstst_dss; /*0x4800 4e4c */
1938 /*CAM_CM Register */
1939 uint32_t cm_fclken_cam; /*0x4800 4f00 */
1940 uint32_t cm_iclken_cam; /*0x4800 4f10 */
1941 uint32_t cm_idlest_cam; /*0x4800 4f20 */
1942 uint32_t cm_autoidle_cam; /*0x4800 4f30 */
1943 uint32_t cm_clksel_cam; /*0x4800 4f40 */
1944 uint32_t cm_sleepdep_cam; /*0x4800 4f44 */
1945 uint32_t cm_clkstctrl_cam; /*0x4800 4f48 */
1946 uint32_t cm_clkstst_cam; /*0x4800 4f4c */
1948 /*PER_CM Register */
1949 uint32_t cm_fclken_per; /*0x4800 5000 */
1950 uint32_t cm_iclken_per; /*0x4800 5010 */
1951 uint32_t cm_idlest_per; /*0x4800 5020 */
1952 uint32_t cm_autoidle_per; /*0x4800 5030 */
1953 uint32_t cm_clksel_per; /*0x4800 5040 */
1954 uint32_t cm_sleepdep_per; /*0x4800 5044 */
1955 uint32_t cm_clkstctrl_per; /*0x4800 5048 */
1956 uint32_t cm_clkstst_per; /*0x4800 504c */
1958 /*EMU_CM Register */
1959 uint32_t cm_clksel1_emu; /*0x4800 5140 */
1960 uint32_t cm_clkstctrl_emu; /*0x4800 5148 */
1961 uint32_t cm_clkstst_emu; /*0x4800 514c */
1962 uint32_t cm_clksel2_emu; /*0x4800 5150 */
1963 uint32_t cm_clksel3_emu; /*0x4800 5154 */
1965 /*Global_Reg_CM Register */
1966 uint32_t cm_polctrl; /*0x4800 529c */
1968 /*NEON_CM Register */
1969 uint32_t cm_idlest_neon; /*0x4800 5320 */
1970 uint32_t cm_clkstctrl_neon; /*0x4800 5348 */
1972 /*USBHOST_CM Register */
1973 uint32_t cm_fclken_usbhost; /*0x4800 5400 */
1974 uint32_t cm_iclken_usbhost; /*0x4800 5410 */
1975 uint32_t cm_idlest_usbhost; /*0x4800 5420 */
1976 uint32_t cm_autoidle_usbhost; /*0x4800 5430 */
1977 uint32_t cm_sleepdep_usbhost; /*0x4800 5444 */
1978 uint32_t cm_clkstctrl_usbhost; /*0x4800 5448 */
1979 uint32_t cm_clkstst_usbhost; /*0x4800 544c */
1984 static inline void omap3_cm_fclken_wkup_update(struct omap3_cm_s *s,
1989 omap_clk_onoff(omap_findclk(s->mpu,"omap3_wkup_32k_fclk"), 1);
1991 omap_clk_onoff(omap_findclk(s->mpu,"omap3_wkup_32k_fclk"), 0);
1994 omap_clk_onoff(omap_findclk(s->mpu,"omap3_gp1_fclk"), 1);
1996 omap_clk_onoff(omap_findclk(s->mpu,"omap3_gp1_fclk"), 0);
1999 static inline void omap3_cm_iclken_wkup_update(struct omap3_cm_s *s,
2004 omap_clk_onoff(omap_findclk(s->mpu,"omap3_wkup_l4_iclk"), 1);
2006 omap_clk_onoff(omap_findclk(s->mpu,"omap3_wkup_l4_iclk"), 0);
2010 static inline void omap3_cm_clksel_wkup_update(struct omap3_cm_s *s,
2013 omap_clk gp1_fclk = omap_findclk(s->mpu, "omap3_gp1_fclk");
2016 omap_clk_reparent(gp1_fclk, omap_findclk(s->mpu, "omap3_sys_clk"));
2018 omap_clk_reparent(gp1_fclk, omap_findclk(s->mpu, "omap3_32k_fclk"));
2019 /*Tell GPTIMER to generate new clk rate */
2020 omap_gp_timer_change_clk(s->mpu->gptimer[0]);
2022 TRACE("omap3_gp1_fclk %lld",
2023 omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp1_fclk")));
2025 /*TODO:CM_USIM_CLK CLKSEL_RM */
2028 static inline void omap3_cm_mpu_update(struct omap3_cm_s *s)
2030 uint32_t m, n, divide, m2, cm_clken_pll_mpu;
2031 uint32_t bypass = 1;
2033 cm_clken_pll_mpu = s->cm_clken_pll_mpu;
2034 omap_clk mpu_clk = omap_findclk(s->mpu, "omap3_mpu_clk");
2036 if ((cm_clken_pll_mpu & 0x7) == 0x5)
2040 else if ((cm_clken_pll_mpu & 0x7) == 0x7)
2042 m = (s->cm_clksel1_pll_mpu & 0x7ff00) >> 8;
2043 if ((m == 0) || (m == 1))
2051 divide = (s->cm_clksel1_pll_mpu & 0x380000) >> 19;
2052 //OMAP3_DEBUG(("divide %d\n",divide));
2053 omap_clk_reparent(mpu_clk, omap_findclk(s->mpu, "omap3_core_clk"));
2054 omap_clk_setrate(mpu_clk, divide, 1);
2059 n = (s->cm_clksel1_pll_mpu & 0x7F);
2060 m2 = (s->cm_clksel2_pll_mpu & 0x1F);
2061 //OMAP3_DEBUG(("M %d N %d M2 %d \n",m,n,m2 ));
2062 omap_clk_reparent(mpu_clk, omap_findclk(s->mpu, "omap3_sys_clk"));
2063 omap_clk_setrate(mpu_clk, (n + 1) * m2, m);
2064 //OMAP3_DEBUG(("mpu %d \n",omap_clk_getrate(mpu_clk)));
2069 static inline void omap3_cm_iva2_update(struct omap3_cm_s *s)
2071 uint32_t m, n, divide, m2, cm_clken_pll_iva2;
2072 uint32_t bypass = 1;
2074 cm_clken_pll_iva2 = s->cm_clken_pll_iva2;
2075 omap_clk iva2_clk = omap_findclk(s->mpu, "omap3_iva2_clk");
2077 if (((cm_clken_pll_iva2 & 0x7) == 0x5)
2078 || ((cm_clken_pll_iva2 & 0x7) == 0x1))
2082 else if ((cm_clken_pll_iva2 & 0x7) == 0x7)
2084 m = (s->cm_clksel1_pll_iva2 & 0x7ff00) >> 8;
2085 if ((m == 0) || (m == 1))
2093 divide = (s->cm_clksel1_pll_iva2 & 0x380000) >> 19;
2094 //OMAP3_DEBUG(("divide %d\n",divide));
2095 omap_clk_reparent(iva2_clk, omap_findclk(s->mpu, "omap3_core_clk"));
2096 omap_clk_setrate(iva2_clk, divide, 1);
2101 n = (s->cm_clksel1_pll_iva2 & 0x7F);
2102 m2 = (s->cm_clksel2_pll_iva2 & 0x1F);
2103 //OMAP3_DEBUG(("M %d N %d M2 %d \n",m,n,m2 ));
2104 omap_clk_reparent(iva2_clk, omap_findclk(s->mpu, "omap3_sys_clk"));
2105 omap_clk_setrate(iva2_clk, (n + 1) * m2, m);
2106 //OMAP3_DEBUG(("iva2_clk %d \n",omap_clk_getrate(iva2_clk)));
2112 static inline void omap3_cm_dpll3_update(struct omap3_cm_s *s)
2114 uint32_t m, n, m2, m3, cm_clken_pll;
2115 uint32_t bypass = 1;
2117 cm_clken_pll = s->cm_clken_pll;
2119 /*dpll3 bypass mode. parent clock is always omap3_sys_clk */
2120 if (((cm_clken_pll & 0x7) == 0x5) || ((cm_clken_pll & 0x7) == 0x6))
2124 else if ((cm_clken_pll & 0x7) == 0x7)
2126 m = (s->cm_clksel1_pll & 0x7ff0000) >> 16;
2127 if ((m == 0) || (m == 1))
2134 omap_clk_setrate(omap_findclk(s->mpu, "omap3_core_clk"), 1, 1);
2135 omap_clk_setrate(omap_findclk(s->mpu, "omap3_core2_clk"), 1, 1);
2136 omap_clk_setrate(omap_findclk(s->mpu, "omap3_emu_core_alwon_clk"), 1,
2141 n = (s->cm_clksel1_pll & 0x3f00) >> 8;
2142 m2 = (s->cm_clksel1_pll & 0xf8000000) >> 27;
2143 m3 = (s->cm_clksel1_emu & 0x1f0000) >> 16;
2145 if (s->cm_clksel2_emu&0x80000)
2147 /*override control of DPLL3*/
2148 m = (s->cm_clksel2_emu&0x7ff)>>8;
2149 n = s->cm_clksel2_emu&0x7f;
2150 TRACE("DPLL3 override, m 0x%x n 0x%x",m,n);
2153 //OMAP3_DEBUG(("dpll3 cm_clksel1_pll %x m %d n %d m2 %d m3 %d\n",s->cm_clksel1_pll,m,n,m2,m3 ));
2154 omap_clk_setrate(omap_findclk(s->mpu, "omap3_core_clk"), (n + 1) * m2,
2156 omap_clk_setrate(omap_findclk(s->mpu, "omap3_core2_clk"), (n + 1) * m2,
2158 omap_clk_setrate(omap_findclk(s->mpu, "omap3_emu_core_alwon_clk"),
2159 (n + 1) * m3, m * 2);
2160 TRACE("coreclk %lld",
2161 omap_clk_getrate(omap_findclk(s->mpu, "omap3_core_clk")));
2168 static inline void omap3_cm_dpll4_update(struct omap3_cm_s *s)
2170 uint32_t m, n, m2, m3, m4, m5, m6, cm_clken_pll;
2171 cm_clken_pll = s->cm_clken_pll;
2172 uint32_t bypass = 1;
2174 /*dpll3 bypass mode. parent clock is always omap3_sys_clk */
2176 if ((cm_clken_pll & 0x70000) == 0x10000)
2180 else if ((cm_clken_pll & 0x70000) == 0x70000)
2182 m = (s->cm_clksel2_pll & 0x7ff00) >> 8;
2183 if ((m == 0) || (m == 1))
2190 omap_clk_setrate(omap_findclk(s->mpu, "omap3_96m_fclk"), 1, 1);
2191 omap_clk_setrate(omap_findclk(s->mpu, "omap3_54m_fclk"), 1, 1);
2192 omap_clk_setrate(omap_findclk(s->mpu, "omap3_dss1_alwon_fclk"), 1, 1);
2193 omap_clk_setrate(omap_findclk(s->mpu, "omap3_cam_mclk"), 1, 1);
2194 omap_clk_setrate(omap_findclk(s->mpu, "omap3_per_alwon_clk"), 1, 1);
2198 n = (s->cm_clksel2_pll & 0x7f);
2199 m2 = s->cm_clksel3_pll & 0x1f;
2200 m3 = (s->cm_clksel_dss & 0x1f00) >> 8;
2201 m4 = s->cm_clksel_dss & 0x1f;
2202 m5 = s->cm_clksel_cam & 0x1f;
2203 m6 = (s->cm_clksel1_emu & 0x1f000000) >> 24;
2205 if (s->cm_clksel3_emu&0x80000)
2207 /*override control of DPLL4*/
2208 m = (s->cm_clksel3_emu&0x7ff)>>8;
2209 n = s->cm_clksel3_emu&0x7f;
2210 TRACE("DPLL4 override, m 0x%x n 0x%x",m,n);
2214 //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 ));
2215 omap_clk_setrate(omap_findclk(s->mpu, "omap3_96m_fclk"), (n + 1) * m2,
2217 omap_clk_setrate(omap_findclk(s->mpu, "omap3_54m_fclk"), (n + 1) * m3,
2219 omap_clk_setrate(omap_findclk(s->mpu, "omap3_dss1_alwon_fclk"),
2220 (n + 1) * m4, m * 2);
2221 omap_clk_setrate(omap_findclk(s->mpu, "omap3_cam_mclk"), (n + 1) * m5,
2223 omap_clk_setrate(omap_findclk(s->mpu, "omap3_per_alwon_clk"),
2224 (n + 1) * m6, m * 2);
2226 TRACE("omap3_96m_fclk %lld",
2227 omap_clk_getrate(omap_findclk(s->mpu, "omap3_96m_fclk")));
2228 TRACE("omap3_54m_fclk %lld",
2229 omap_clk_getrate(omap_findclk(s->mpu, "omap3_54m_fclk")));
2230 TRACE("omap3_dss1_alwon_fclk %lld",
2231 omap_clk_getrate(omap_findclk(s->mpu, "omap3_dss1_alwon_fclk")));
2232 TRACE("omap3_cam_mclk %lld",
2233 omap_clk_getrate(omap_findclk(s->mpu, "omap3_cam_mclk")));
2234 TRACE("omap3_per_alwon_clk %lld",
2235 omap_clk_getrate(omap_findclk(s->mpu, "omap3_per_alwon_clk")));
2236 TRACE("omap3_48m_fclk %lld",
2237 omap_clk_getrate(omap_findclk(s->mpu, "omap3_48m_fclk")));
2238 TRACE("omap3_12m_fclk %lld",
2239 omap_clk_getrate(omap_findclk(s->mpu, "omap3_12m_fclk")));
2243 static inline void omap3_cm_dpll5_update(struct omap3_cm_s *s)
2245 uint32_t m, n, m2, cm_idlest2_ckgen;
2246 uint32_t bypass = 1;
2248 cm_idlest2_ckgen = s->cm_idlest2_ckgen;;
2250 /*dpll5 bypass mode */
2251 if ((cm_idlest2_ckgen & 0x1) == 0x0)
2258 omap_clk_setrate(omap_findclk(s->mpu, "omap3_120m_fclk"), 1, 1);
2262 m = (s->cm_clksel4_pll & 0x7ff00)>>8;
2263 n = s->cm_clksel4_pll & 0x3f00;
2264 m2 = s->cm_clksel5_pll & 0x1f;
2266 TRACE("dpll5 m %d n %d m2 %d",m,n,m2);
2267 omap_clk_setrate(omap_findclk(s->mpu, "omap3_120m_fclk"), (n + 1) * m2,
2269 TRACE("omap3_120m_fclk %lld",
2270 omap_clk_getrate(omap_findclk(s->mpu, "omap3_120m_fclk")));
2275 static inline void omap3_cm_48m_update(struct omap3_cm_s *s)
2277 if (s->cm_clksel1_pll & 0x8)
2279 /*parent is sysaltclk */
2280 omap_clk_reparent(omap_findclk(s->mpu, "omap3_48m_fclk"),
2281 omap_findclk(s->mpu, "omap3_sys_altclk"));
2282 omap_clk_reparent(omap_findclk(s->mpu, "omap3_12m_fclk"),
2283 omap_findclk(s->mpu, "omap3_sys_altclk"));
2284 /*TODO:need to set rate ? */
2289 omap_clk_reparent(omap_findclk(s->mpu, "omap3_12m_fclk"),
2290 omap_findclk(s->mpu, "omap3_96m_fclk"));
2291 omap_clk_reparent(omap_findclk(s->mpu, "omap3_48m_fclk"),
2292 omap_findclk(s->mpu, "omap3_96m_fclk"));
2293 omap_clk_setrate(omap_findclk(s->mpu, "omap3_48m_fclk"), 2, 1);
2294 omap_clk_setrate(omap_findclk(s->mpu, "omap3_12m_fclk"), 8, 1);
2300 static inline void omap3_cm_gp10_update(struct omap3_cm_s *s)
2302 omap_clk gp10_fclk = omap_findclk(s->mpu, "omap3_gp10_fclk");
2304 if (s->cm_clksel_core & 0x40)
2305 omap_clk_reparent(gp10_fclk, omap_findclk(s->mpu, "omap3_sys_clk"));
2307 omap_clk_reparent(gp10_fclk, omap_findclk(s->mpu, "omap3_32k_fclk"));
2309 /*Tell GPTIMER10 to generate new clk rate */
2310 omap_gp_timer_change_clk(s->mpu->gptimer[9]);
2311 TRACE("omap3_gp10_fclk %lld",
2312 omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp10_fclk")));
2315 static inline void omap3_cm_gp11_update(struct omap3_cm_s *s)
2317 omap_clk gp11_fclk = omap_findclk(s->mpu, "omap3_gp11_fclk");
2319 if (s->cm_clksel_core & 0x80)
2320 omap_clk_reparent(gp11_fclk, omap_findclk(s->mpu, "omap3_sys_clk"));
2322 omap_clk_reparent(gp11_fclk, omap_findclk(s->mpu, "omap3_32k_fclk"));
2323 /*Tell GPTIMER11 to generate new clk rate */
2324 omap_gp_timer_change_clk(s->mpu->gptimer[10]);
2325 TRACE("omap3_gp11_fclk %lld",
2326 omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp11_fclk")));
2329 static inline void omap3_cm_l3clk_update(struct omap3_cm_s *s)
2331 omap_clk l3_iclk = omap_findclk(s->mpu, "omap3_l3_iclk");
2332 if ((s->cm_clksel_core & 0x3) == 0x1)
2333 omap_clk_setrate(l3_iclk, 1, 1);
2334 else if ((s->cm_clksel_core & 0x3) == 0x2)
2335 omap_clk_setrate(l3_iclk, 2, 1);
2338 static inline void omap3_cm_l4clk_update(struct omap3_cm_s *s)
2340 omap_clk l4_iclk = omap_findclk(s->mpu, "omap3_l4_iclk");
2341 if ((s->cm_clksel_core & 0xc) == 0x4)
2342 omap_clk_setrate(l4_iclk, 1, 1);
2343 else if ((s->cm_clksel_core & 0xc) == 0x8)
2344 omap_clk_setrate(l4_iclk, 2, 1);
2347 static inline void omap3_cm_per_gptimer_update(struct omap3_cm_s *s)
2349 uint32_t cm_clksel_per = s->cm_clksel_per;
2351 if (cm_clksel_per & 0x1)
2352 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp2_fclk"),
2353 omap_findclk(s->mpu, "omap3_sys_clk"));
2355 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp2_fclk"),
2356 omap_findclk(s->mpu, "omap3_32k_fclk"));
2357 omap_gp_timer_change_clk(s->mpu->gptimer[1]);
2359 if (cm_clksel_per & 0x2)
2360 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp3_fclk"),
2361 omap_findclk(s->mpu, "omap3_sys_clk"));
2363 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp3_fclk"),
2364 omap_findclk(s->mpu, "omap3_32k_fclk"));
2365 omap_gp_timer_change_clk(s->mpu->gptimer[2]);
2367 if (cm_clksel_per & 0x4)
2368 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp4_fclk"),
2369 omap_findclk(s->mpu, "omap3_sys_clk"));
2371 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp4_fclk"),
2372 omap_findclk(s->mpu, "omap3_32k_fclk"));
2373 omap_gp_timer_change_clk(s->mpu->gptimer[3]);
2375 if (cm_clksel_per & 0x8)
2376 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp5_fclk"),
2377 omap_findclk(s->mpu, "omap3_sys_clk"));
2379 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp5_fclk"),
2380 omap_findclk(s->mpu, "omap3_32k_fclk"));
2381 omap_gp_timer_change_clk(s->mpu->gptimer[4]);
2383 if (cm_clksel_per & 0x10)
2384 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp6_fclk"),
2385 omap_findclk(s->mpu, "omap3_sys_clk"));
2387 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp6_fclk"),
2388 omap_findclk(s->mpu, "omap3_32k_fclk"));
2389 omap_gp_timer_change_clk(s->mpu->gptimer[5]);
2391 if (cm_clksel_per & 0x20)
2392 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp7_fclk"),
2393 omap_findclk(s->mpu, "omap3_sys_clk"));
2395 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp7_fclk"),
2396 omap_findclk(s->mpu, "omap3_32k_fclk"));
2397 omap_gp_timer_change_clk(s->mpu->gptimer[6]);
2400 if (cm_clksel_per & 0x40)
2401 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp8_fclk"),
2402 omap_findclk(s->mpu, "omap3_sys_clk"));
2404 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp8_fclk"),
2405 omap_findclk(s->mpu, "omap3_32k_fclk"));
2406 omap_gp_timer_change_clk(s->mpu->gptimer[7]);
2408 if (cm_clksel_per & 0x80)
2409 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp9_fclk"),
2410 omap_findclk(s->mpu, "omap3_sys_clk"));
2412 omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp9_fclk"),
2413 omap_findclk(s->mpu, "omap3_32k_fclk"));
2414 omap_gp_timer_change_clk(s->mpu->gptimer[8]);
2416 /*TODO:Tell GPTIMER to generate new clk rate */
2417 TRACE("omap3_gp2_fclk %lld",
2418 omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp2_fclk")));
2419 TRACE("omap3_gp3_fclk %lld",
2420 omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp3_fclk")));
2421 TRACE("omap3_gp4_fclk %lld",
2422 omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp4_fclk")));
2423 TRACE("omap3_gp5_fclk %lld",
2424 omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp5_fclk")));
2425 TRACE("omap3_gp6_fclk %lld",
2426 omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp6_fclk")));
2427 TRACE("omap3_gp7_fclk %lld",
2428 omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp7_fclk")));
2429 TRACE("omap3_gp8_fclk %lld",
2430 omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp8_fclk")));
2431 TRACE("omap3_gp9_fclk %lld",
2432 omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp9_fclk")));
2435 static inline void omap3_cm_clkout2_update(struct omap3_cm_s *s)
2439 if (!s->cm_clkout_ctrl&0x80)
2442 switch (s->cm_clkout_ctrl&0x3)
2445 omap_clk_reparent(omap_findclk(s->mpu, "omap3_sys_clkout2"),
2446 omap_findclk(s->mpu, "omap3_core_clk"));
2449 omap_clk_reparent(omap_findclk(s->mpu, "omap3_sys_clkout2"),
2450 omap_findclk(s->mpu, "omap3_sys_clk"));
2453 omap_clk_reparent(omap_findclk(s->mpu, "omap3_sys_clkout2"),
2454 omap_findclk(s->mpu, "omap3_96m_fclk"));
2457 omap_clk_reparent(omap_findclk(s->mpu, "omap3_sys_clkout2"),
2458 omap_findclk(s->mpu, "omap3_54m_fclk"));
2462 divor = (s->cm_clkout_ctrl&0x31)>>3;
2464 omap_clk_setrate(omap_findclk(s->mpu, "omap3_sys_clkout2"), divor, 1);
2468 static void omap3_cm_reset(struct omap3_cm_s *s)
2470 s->cm_fclken_iva2 = 0x0;
2471 s->cm_clken_pll_iva2 = 0x11;
2472 s->cm_idlest_iva2 = 0x1;
2473 s->cm_idlest_pll_iva2 = 0x0;
2474 s->cm_autoidle_pll_iva2 = 0x0;
2475 s->cm_clksel1_pll_iva2 = 0x80000;
2476 s->cm_clksel2_pll_iva2 = 0x1;
2477 s->cm_clkstctrl_iva2 = 0x0;
2478 s->cm_clkstst_iva2 = 0x0;
2480 s->cm_revision = 0x10;
2481 s->cm_sysconfig = 0x1;
2483 s->cm_clken_pll_mpu = 0x15;
2484 s->cm_idlest_mpu = 0x1;
2485 s->cm_idlest_pll_mpu = 0x0;
2486 s->cm_autoidle_pll_mpu = 0x0;
2487 s->cm_clksel1_pll_mpu = 0x80000;
2488 s->cm_clksel2_pll_mpu = 0x1;
2489 s->cm_clkstctrl_mpu = 0x0;
2490 s->cm_clkstst_mpu = 0x0;
2492 s->cm_fclken1_core = 0x0;
2493 s->cm_fclken3_core = 0x0;
2494 s->cm_iclken1_core = 0x42;
2495 s->cm_iclken2_core = 0x0;
2496 s->cm_iclken3_core = 0x0;
2497 /*allow access to devices*/
2498 s->cm_idlest1_core = 0x0;
2499 s->cm_idlest2_core = 0x0;
2501 s->cm_idlest3_core = 0xa;
2502 s->cm_autoidle1_core = 0x0;
2503 s->cm_autoidle2_core = 0x0;
2504 s->cm_autoidle3_core = 0x0;
2505 s->cm_clksel_core = 0x105;
2506 s->cm_clkstctrl_core = 0x0;
2507 s->cm_clkstst_core = 0x0;
2509 s->cm_fclken_sgx = 0x0;
2510 s->cm_iclken_sgx = 0x0;
2511 s->cm_idlest_sgx = 0x1;
2512 s->cm_clksel_sgx = 0x0;
2513 s->cm_sleepdep_sgx = 0x0;
2514 s->cm_clkstctrl_sgx = 0x0;
2515 s->cm_clkstst_sgx = 0x0;
2517 s->cm_fclken_wkup = 0x0;
2518 s->cm_iclken_wkup = 0x0;
2519 /*assume all clock can be accessed*/
2520 s->cm_idlest_wkup = 0x0;
2521 s->cm_autoidle_wkup = 0x0;
2522 s->cm_clksel_wkup = 0x12;
2524 s->cm_clken_pll = 0x110015;
2525 s->cm_clken2_pll = 0x11;
2526 s->cm_idlest_ckgen = 0x0;
2527 s->cm_idlest2_ckgen = 0x0;
2528 s->cm_autoidle_pll = 0x0;
2529 s->cm_autoidle2_pll = 0x0;
2530 s->cm_clksel1_pll = 0x8000040;
2531 s->cm_clksel2_pll = 0x0;
2532 s->cm_clksel3_pll = 0x1;
2533 s->cm_clksel4_pll = 0x0;
2534 s->cm_clksel5_pll = 0x1;
2535 s->cm_clkout_ctrl = 0x3;
2538 s->cm_fclken_dss = 0x0;
2539 s->cm_iclken_dss = 0x0;
2540 /*dss can be accessed*/
2541 s->cm_idlest_dss = 0x0;
2542 s->cm_autoidle_dss = 0x0;
2543 s->cm_clksel_dss = 0x1010;
2544 s->cm_sleepdep_dss = 0x0;
2545 s->cm_clkstctrl_dss = 0x0;
2546 s->cm_clkstst_dss = 0x0;
2548 s->cm_fclken_cam = 0x0;
2549 s->cm_iclken_cam = 0x0;
2550 s->cm_idlest_cam = 0x1;
2551 s->cm_autoidle_cam = 0x0;
2552 s->cm_clksel_cam = 0x10;
2553 s->cm_sleepdep_cam = 0x0;
2554 s->cm_clkstctrl_cam = 0x0;
2555 s->cm_clkstst_cam = 0x0;
2557 s->cm_fclken_per = 0x0;
2558 s->cm_iclken_per = 0x0;
2559 //s->cm_idlest_per = 0x3ffff;
2560 s->cm_idlest_per = 0x0; //enable GPIO access
2561 s->cm_autoidle_per = 0x0;
2562 s->cm_clksel_per = 0x0;
2563 s->cm_sleepdep_per = 0x0;
2564 s->cm_clkstctrl_per = 0x0;
2565 s->cm_clkstst_per = 0x0;
2567 s->cm_clksel1_emu = 0x10100a50;
2568 s->cm_clkstctrl_emu = 0x2;
2569 s->cm_clkstst_emu = 0x0;
2570 s->cm_clksel2_emu = 0x0;
2571 s->cm_clksel3_emu = 0x0;
2573 s->cm_polctrl = 0x0;
2575 s->cm_idlest_neon = 0x1;
2576 s->cm_clkstctrl_neon = 0x0;
2578 s->cm_fclken_usbhost = 0x0;
2579 s->cm_iclken_usbhost = 0x0;
2580 s->cm_idlest_usbhost = 0x3;
2581 s->cm_autoidle_usbhost = 0x0;
2582 s->cm_sleepdep_usbhost = 0x0;
2583 s->cm_clkstctrl_usbhost = 0x0;
2584 s->cm_clkstst_usbhost = 0x0;
2587 static uint32_t omap3_cm_read(void *opaque, target_phys_addr_t addr)
2589 struct omap3_cm_s *s = (struct omap3_cm_s *) opaque;
2591 uint32_t bypass = 0, m;
2593 TRACE("%04x", addr);
2597 return s->cm_fclken_iva2;
2599 return s->cm_clken_pll_iva2;
2601 return s->cm_idlest_iva2;
2603 if (((s->cm_clken_pll_iva2 & 0x7) == 0x5)
2604 || ((s->cm_clken_pll_iva2 & 0x7) == 0x1))
2608 else if ((s->cm_clken_pll_iva2 & 0x7) == 0x7)
2610 m = (s->cm_clksel1_pll_iva2 & 0x7ff00) >> 8;
2611 if ((m == 0) || (m == 1))
2621 return s->cm_autoidle_pll_iva2;
2623 return s->cm_clksel1_pll_iva2;
2625 return s->cm_clksel2_pll_iva2;
2627 return s->cm_clkstctrl_iva2;
2629 return s->cm_clkstst_iva2;
2632 return s->cm_revision;
2634 return s->cm_sysconfig;
2637 case 0x904: /*CM_CLKEN_PLL_MPU */
2638 return s->cm_clken_pll_mpu;
2640 return s->cm_idlest_mpu & 0x0; /*MPU is active*/
2642 if ((s->cm_clken_pll_mpu & 0x7) == 0x5)
2646 else if ((s->cm_clken_pll_mpu & 0x7) == 0x7)
2648 m = (s->cm_clksel1_pll_mpu & 0x7ff00) >> 8;
2649 if ((m == 0) || (m == 1))
2659 return s->cm_autoidle_pll_mpu;
2661 return s->cm_clksel1_pll_mpu;
2663 return s->cm_clksel2_pll_mpu;
2665 return s->cm_clkstctrl_mpu;
2667 return s->cm_clkstst_mpu;
2672 return s->cm_fclken1_core;
2674 return s->cm_fclken3_core;
2676 return s->cm_iclken1_core;
2678 return s->cm_iclken2_core;
2680 return s->cm_idlest1_core;
2682 return s->cm_idlest2_core;
2684 return s->cm_idlest3_core;
2686 return s->cm_autoidle1_core;
2688 return s->cm_autoidle2_core;
2690 return s->cm_autoidle3_core;
2691 case 0xa40: /*CM_CLKSEL_CORE */
2692 return s->cm_clksel_core;
2694 return s->cm_clkstctrl_core;
2696 return s->cm_clkstst_core;
2699 return s->cm_fclken_sgx;
2701 return s->cm_iclken_sgx;
2703 return s->cm_idlest_sgx&0x0;
2704 case 0xb40: /*CM_CLKSEL_SGX */
2705 return s->cm_clksel_sgx;
2707 return s->cm_clkstctrl_sgx;
2709 return s->cm_clkstst_sgx;
2712 case 0xc00: /*CM_FCLKEN_WKUP */
2713 return s->cm_fclken_wkup;
2714 case 0xc10: /*CM_ICLKEN_WKUP */
2715 return s->cm_iclken_wkup;
2716 case 0xc20: /*CM_IDLEST_WKUP */
2717 /*TODO: Check whether the timer can be accessed. */
2720 return s->cm_idlest_wkup;
2722 return s->cm_clksel_wkup;
2727 case 0xd00: /*CM_CLKEN_PLL */
2728 return s->cm_clken_pll;
2730 return s->cm_clken2_pll;
2732 /*FIXME: all clock is active. we do not care it. */
2737 if (((s->cm_clken_pll & 0x7) == 0x5) || ((s->cm_clken_pll & 0x7) == 0x6))
2739 else if ((s->cm_clken_pll & 0x7) == 0x7) {
2740 m = (s->cm_clksel1_pll & 0x7ff0000) >> 16;
2741 if ((m == 0) || (m == 1))
2751 if ((s->cm_clken_pll & 0x70000) == 0x10000)
2753 else if ((s->cm_clken_pll & 0x70000) == 0x70000) {
2754 m = (s->cm_clksel2_pll & 0x7ff00) >> 8;
2755 if ((m == 0) || (m == 1))
2765 return s->cm_idlest2_ckgen;
2767 return s->cm_autoidle_pll;
2769 return s->cm_autoidle2_pll;
2770 case 0xd40: /*CM_CLKSEL1_PLL */
2771 return s->cm_clksel1_pll;
2773 return s->cm_clksel2_pll;
2774 case 0xd48: /*CM_CLKSEL3_PLL */
2775 return s->cm_clksel3_pll;
2777 return s->cm_clksel4_pll;
2778 case 0xd50: /*CM_CLKSEL5_PLL */
2779 return s->cm_clksel5_pll;
2781 return s->cm_clkout_ctrl;
2785 return s->cm_fclken_dss;
2787 return s->cm_iclken_dss;
2789 return s->cm_idlest_dss;
2791 return s->cm_autoidle_dss;
2793 return s->cm_clksel_dss;
2795 return s->cm_sleepdep_dss;
2797 return s->cm_clkstctrl_dss;
2799 return s->cm_clkstst_dss;
2803 return s->cm_fclken_cam;
2805 return s->cm_iclken_cam;
2807 return s->cm_idlest_cam&0x0;
2809 return s->cm_autoidle_cam;
2811 return s->cm_clksel_cam;
2813 return s->cm_sleepdep_cam;
2815 return s->cm_clkstctrl_cam;
2817 return s->cm_clkstst_cam;
2821 return s->cm_fclken_per;
2823 return s->cm_iclken_per;
2825 return s->cm_idlest_per ;
2827 return s->cm_autoidle_per;
2829 return s->cm_clksel_per;
2831 return s->cm_sleepdep_per;
2833 return s->cm_clkstctrl_per;
2835 return s->cm_clkstst_per;
2838 case 0x1140: /*CM_CLKSEL1_EMU */
2839 return s->cm_clksel1_emu;
2841 return s->cm_clkstctrl_emu;
2843 return s->cm_clkstst_emu&0x0;
2845 return s->cm_clksel2_emu;
2847 return s->cm_clksel3_emu;
2850 return s->cm_polctrl;
2853 return s->cm_idlest_neon&0x0;
2855 return s->cm_clkstctrl_neon;
2858 return s->cm_fclken_usbhost;
2860 return s->cm_iclken_usbhost;
2862 return s->cm_idlest_usbhost&0x0;
2864 return s->cm_autoidle_usbhost;
2866 return s->cm_sleepdep_usbhost;
2868 return s->cm_clkstctrl_usbhost;
2870 return s->cm_clkstst_usbhost;
2873 printf("omap3_cm_read addr %x pc %x \n", addr, cpu_single_env->regs[15] );
2879 static void omap3_cm_write(void *opaque, target_phys_addr_t addr,
2882 struct omap3_cm_s *s = (struct omap3_cm_s *) opaque;
2884 TRACE("%04x = %08x", addr, value);
2900 case 0xc20: /*CM_IDLEST_WKUP */
2918 s->cm_fclken_iva2 = value & 0x1;
2920 case 0x4: /*CM_CLKEN_PLL_IVA2 */
2921 s->cm_clken_pll_iva2 = value & 0x7ff;
2922 omap3_cm_iva2_update(s);
2925 s->cm_autoidle_pll_iva2 = value & 0x7;
2928 s->cm_clksel1_pll_iva2 = value & 0x3fff7f;
2929 //printf("value %x s->cm_clksel1_pll_iva2 %x \n",value,s->cm_clksel1_pll_iva2);
2930 omap3_cm_iva2_update(s);
2933 s->cm_clksel2_pll_iva2 = value & 0x1f;
2934 omap3_cm_iva2_update(s);
2937 s->cm_clkstctrl_iva2 = value& 0x3;
2941 s->cm_sysconfig = value & 0x1;
2945 case 0x904: /*CM_CLKEN_PLL_MPU */
2946 s->cm_clken_pll_mpu = value & 0x7ff;
2947 omap3_cm_mpu_update(s);
2950 s->cm_autoidle_pll_mpu = value & 0x7;
2953 //printf("s->cm_clksel1_pll_mpu %x\n",s->cm_clksel1_pll_mpu );
2954 s->cm_clksel1_pll_mpu = value & 0x3fff7f;
2955 omap3_cm_mpu_update(s);
2958 s->cm_clksel2_pll_mpu = value & 0x1f;
2959 omap3_cm_mpu_update(s);
2962 s->cm_clkstctrl_mpu = value & 0x3;
2967 s->cm_fclken1_core = value & 0x43fffe00;
2970 s->cm_fclken3_core = value & 0x7;
2973 s->cm_iclken1_core = value & 0x637ffed2;
2974 s->cm_idlest1_core = ~s->cm_iclken1_core;
2975 /* TODO: replace code below with real implementation */
2976 s->cm_idlest1_core &= ~0x20; /* HS OTG USB idle */
2977 s->cm_idlest1_core |= 4; /* SDMA in standby */
2980 s->cm_iclken2_core = value & 0x1f;
2983 s->cm_iclken3_core = value & 0x4;
2984 s->cm_idlest3_core = 0xd & ~(s->cm_iclken3_core & 4);
2987 s->cm_autoidle1_core = value & 0x7ffffed0;
2990 s->cm_autoidle2_core = value & 0x1f;
2993 s->cm_autoidle3_core = value & 0x2;
2995 case 0xa40: /*CM_CLKSEL_CORE */
2996 s->cm_clksel_core = (value & 0xff);
2997 s->cm_clksel_core |= 0x100;
2998 omap3_cm_gp10_update(s);
2999 omap3_cm_gp11_update(s);
3000 omap3_cm_l3clk_update(s);
3001 omap3_cm_l4clk_update(s);
3004 s->cm_clkstctrl_core = value & 0xf;
3008 s->cm_fclken_sgx = value &0x2;
3011 s->cm_iclken_sgx = value & 0x1;
3013 case 0xb40: /*CM_CLKSEL_SGX */
3014 /*TODO: SGX Clock!! */
3015 s->cm_clksel_sgx = value;
3018 s->cm_sleepdep_sgx = value &0x2;
3021 s->cm_clkstctrl_sgx = value & 0x3;
3025 case 0xc00: /*CM_FCLKEN_WKUP */
3026 s->cm_fclken_wkup = value & 0x2e9;
3028 case 0xc10: /*CM_ICLKEN_WKUP */
3029 s->cm_iclken_wkup = value & 0x2ff;
3032 s->cm_autoidle_wkup = value & 0x23f;
3034 case 0xc40: /*CM_CLKSEL_WKUP */
3035 s->cm_clksel_wkup = value & 0x7f;
3036 omap3_cm_clksel_wkup_update(s, s->cm_clksel_wkup);
3040 case 0xd00: /*CM_CLKEN_PLL */
3041 s->cm_clken_pll = value & 0xffff17ff;
3042 omap3_cm_dpll3_update(s);
3043 omap3_cm_dpll4_update(s);
3046 s->cm_clken2_pll = value & 0x7ff;
3049 s->cm_autoidle_pll = value & 0x3f;
3052 s->cm_autoidle2_pll = value & 0x7;
3054 case 0xd40: /*CM_CLKSEL1_PLL */
3055 //OMAP3_DEBUG(("WD40 value %x \n",value));
3056 s->cm_clksel1_pll = value & 0xffffbffc;
3057 //OMAP3_DEBUG(("WD40 value %x \n",value));
3058 omap3_cm_dpll3_update(s);
3059 omap3_cm_48m_update(s);
3062 s->cm_clksel2_pll = value & 0x7ff7f;
3063 omap3_cm_dpll4_update(s);
3065 case 0xd48: /*CM_CLKSEL3_PLL */
3066 s->cm_clksel3_pll = value & 0x1f;
3067 omap3_cm_dpll4_update(s);
3069 case 0xd4c: /*CM_CLKSEL4_PLL */
3070 s->cm_clksel4_pll = value & 0x7ff7f;
3071 omap3_cm_dpll5_update(s);
3073 case 0xd50: /*CM_CLKSEL5_PLL */
3074 s->cm_clksel5_pll = value & 0x1f;
3075 omap3_cm_dpll5_update(s);
3078 s->cm_clkout_ctrl = value & 0xbb;
3079 omap3_cm_clkout2_update(s);
3083 s->cm_fclken_dss = value & 0x7;
3086 s->cm_iclken_dss = value & 0x1;
3089 s->cm_autoidle_dss = value & 0x1;
3092 s->cm_clksel_dss = value & 0x1f1f;
3093 omap3_cm_dpll4_update(s);
3096 s->cm_sleepdep_dss = value & 0x7;
3099 s->cm_clkstctrl_dss = value & 0x3;
3103 s->cm_fclken_cam = value & 0x3;
3106 s->cm_iclken_cam = value & 0x1;
3109 s->cm_autoidle_cam = value & 0x1;
3112 s->cm_clksel_cam = value & 0x1f;
3113 omap3_cm_dpll4_update(s);
3116 s->cm_sleepdep_cam = value & 0x2;
3119 s->cm_clkstctrl_cam = value & 0x3;
3123 s->cm_fclken_per = value & 0x3ffff;
3126 s->cm_iclken_per = value & 0x3ffff;
3130 s->cm_autoidle_per = value &0x3ffff;
3133 s->cm_clksel_per = value & 0xff;
3134 omap3_cm_per_gptimer_update(s);
3137 s->cm_sleepdep_per = value & 0x6;
3140 s->cm_clkstctrl_per = value &0x7;
3143 case 0x1140: /*CM_CLKSEL1_EMU */
3144 s->cm_clksel1_emu = value & 0x1f1f3fff;
3145 //printf("cm_clksel1_emu %x\n",s->cm_clksel1_emu);
3146 omap3_cm_dpll3_update(s);
3147 omap3_cm_dpll4_update(s);
3150 s->cm_clkstctrl_emu = value & 0x3;
3153 s->cm_clksel2_emu = value & 0xfff7f;
3154 omap3_cm_dpll3_update(s);
3157 s->cm_clksel3_emu = value & 0xfff7f;
3158 omap3_cm_dpll4_update(s);
3162 s->cm_polctrl = value & 0x1;
3166 s->cm_clkstctrl_neon = value & 0x3;
3170 s->cm_fclken_usbhost = value & 0x3;
3173 s->cm_iclken_usbhost = value & 0x1;
3176 s->cm_autoidle_usbhost = value & 0x1;
3179 s->cm_sleepdep_usbhost = value & 0x6;
3182 s->cm_clkstctrl_usbhost = value & 0x3;
3186 printf("omap3_cm_write addr %x value %x pc %x\n", addr, value,cpu_single_env->regs[15] );
3193 static CPUReadMemoryFunc *omap3_cm_readfn[] = {
3194 omap_badwidth_read32,
3195 omap_badwidth_read32,
3199 static CPUWriteMemoryFunc *omap3_cm_writefn[] = {
3200 omap_badwidth_write32,
3201 omap_badwidth_write32,
3205 struct omap3_cm_s *omap3_cm_init(struct omap_target_agent_s *ta,
3206 qemu_irq mpu_int, qemu_irq dsp_int,
3207 qemu_irq iva_int, struct omap_mpu_state_s *mpu)
3210 struct omap3_cm_s *s = (struct omap3_cm_s *) qemu_mallocz(sizeof(*s));
3212 s->irq[0] = mpu_int;
3213 s->irq[1] = dsp_int;
3214 s->irq[2] = iva_int;
3218 iomemtype = l4_register_io_memory(0, omap3_cm_readfn, omap3_cm_writefn, s);
3219 omap_l4_attach(ta, 0, iomemtype);
3220 omap_l4_attach(ta, 1, iomemtype);
3225 #define OMAP3_SEC_WDT 1
3226 #define OMAP3_MPU_WDT 2
3227 #define OMAP3_IVA2_WDT 3
3228 /*omap3 watchdog timer*/
3231 qemu_irq irq; /*IVA2 IRQ */
3232 struct omap_mpu_state_s *mpu;
3239 //int64_t ticks_per_sec;
3241 uint32_t wd_sysconfig;
3242 uint32_t wd_sysstatus;
3252 /*pre and ptv in wclr */
3257 uint16_t writeh; /* LSB */
3258 uint16_t readh; /* MSB */
3266 static inline void omap3_wdt_timer_update(struct omap3_wdt_s *wdt_timer)
3269 if (wdt_timer->active)
3271 expires = muldiv64(0xffffffffll - wdt_timer->wcrr,
3272 ticks_per_sec, wdt_timer->rate);
3273 qemu_mod_timer(wdt_timer->timer, wdt_timer->time + expires);
3276 qemu_del_timer(wdt_timer->timer);
3278 static void omap3_wdt_clk_setup(struct omap3_wdt_s *timer)
3280 /*TODO: Add irq as user to clk */
3283 static inline uint32_t omap3_wdt_timer_read(struct omap3_wdt_s *timer)
3289 distance = qemu_get_clock(vm_clock) - timer->time;
3290 distance = muldiv64(distance, timer->rate, ticks_per_sec);
3292 if (distance >= 0xffffffff - timer->wcrr)
3295 return timer->wcrr + distance;
3302 static inline void omap3_wdt_timer_sync(struct omap3_wdt_s *timer)
3304 if (timer->active) {
3305 timer->val = omap3_wdt_timer_read(timer);
3306 timer->time = qemu_get_clock(vm_clock);
3310 static void omap3_wdt_reset(struct omap3_wdt_s *s, int wdt_index)
3312 s->wd_sysconfig = 0x0;
3313 s->wd_sysstatus = 0x0;
3321 case OMAP3_IVA2_WDT:
3322 s->wldr = 0xfffb0000;
3325 s->wldr = 0xffa60000;
3338 case OMAP3_IVA2_WDT:
3342 s->pre = s->wclr & (1 << 5);
3343 s->ptv = (s->wclr & 0x1c) >> 2;
3344 s->rate = omap_clk_getrate(s->clk) >> (s->pre ? s->ptv : 0);
3347 s->time = qemu_get_clock(vm_clock);
3348 omap3_wdt_timer_update(s);
3351 static uint32_t omap3_wdt_read32(void *opaque, target_phys_addr_t addr,
3354 struct omap3_wdt_s *s = (struct omap3_wdt_s *) opaque;
3357 //printf("omap3_wdt_read32 addr %x \n",addr);
3360 case 0x10: /*WD_SYSCONFIG */
3361 return s->wd_sysconfig;
3362 case 0x14: /*WD_SYSSTATUS */
3363 return s->wd_sysstatus;
3365 /*WISR*/ return s->wisr & 0x1;
3367 /*WIER*/ return s->wier & 0x1;
3369 /*WCLR*/ return s->wclr & 0x3c;
3371 /*WCRR*/ s->wcrr = omap3_wdt_timer_read(s);
3372 s->time = qemu_get_clock(vm_clock);
3375 /*WLDR*/ return s->wldr;
3377 /*WTGR*/ return s->wtgr;
3379 /*WWPS*/ return s->wwps;
3381 /*WSPR*/ return s->wspr;
3383 printf("omap3_wdt_read32 addr %x \n", addr);
3387 static uint32_t omap3_mpu_wdt_read16(void *opaque, target_phys_addr_t addr)
3389 struct omap3_wdt_s *s = (struct omap3_wdt_s *) opaque;
3396 ret = omap3_wdt_read32(opaque, addr, OMAP3_MPU_WDT);
3397 s->readh = ret >> 16;
3398 return ret & 0xffff;
3401 static uint32_t omap3_mpu_wdt_read32(void *opaque, target_phys_addr_t addr)
3403 return omap3_wdt_read32(opaque, addr, OMAP3_MPU_WDT);
3406 static void omap3_wdt_write32(void *opaque, target_phys_addr_t addr,
3407 uint32_t value, int wdt_index)
3409 struct omap3_wdt_s *s = (struct omap3_wdt_s *) opaque;
3411 //printf("omap3_wdt_write32 addr %x value %x \n",addr,value);
3414 case 0x14: /*WD_SYSSTATUS */
3416 /*WWPS*/ OMAP_RO_REG(addr);
3419 case 0x10: /*WD_SYSCONFIG */
3420 s->wd_sysconfig = value & 0x33f;
3423 /*WISR*/ s->wisr = value & 0x1;
3426 /*WIER*/ s->wier = value & 0x1;
3429 /*WCLR*/ s->wclr = value & 0x3c;
3432 /*WCRR*/ s->wcrr = value;
3433 s->time = qemu_get_clock(vm_clock);
3434 omap3_wdt_timer_update(s);
3437 /*WLDR*/ s->wldr = value; /*It will take effect after next overflow */
3440 /*WTGR*/ if (value != s->wtgr)
3443 s->pre = s->wclr & (1 << 5);
3444 s->ptv = (s->wclr & 0x1c) >> 2;
3445 s->rate = omap_clk_getrate(s->clk) >> (s->pre ? s->ptv : 0);
3446 s->time = qemu_get_clock(vm_clock);
3447 omap3_wdt_timer_update(s);
3453 if (((value & 0xffff) == 0x5555) && ((s->wspr & 0xffff) == 0xaaaa))
3456 s->wcrr = omap3_wdt_timer_read(s);
3457 omap3_wdt_timer_update(s);
3459 if (((value & 0xffff) == 0x4444) && ((s->wspr & 0xffff) == 0xbbbb))
3462 s->time = qemu_get_clock(vm_clock);
3463 omap3_wdt_timer_update(s);
3468 printf("omap3_wdt_write32 addr %x \n", addr);
3473 static void omap3_mpu_wdt_write16(void *opaque, target_phys_addr_t addr,
3476 struct omap3_wdt_s *s = (struct omap3_wdt_s *) opaque;
3479 return omap3_wdt_write32(opaque, addr, (value << 16) | s->writeh,
3482 s->writeh = (uint16_t) value;
3484 static void omap3_mpu_wdt_write32(void *opaque, target_phys_addr_t addr,
3487 omap3_wdt_write32(opaque, addr, value, OMAP3_MPU_WDT);
3491 static CPUReadMemoryFunc *omap3_mpu_wdt_readfn[] = {
3492 omap_badwidth_read32,
3493 omap3_mpu_wdt_read16,
3494 omap3_mpu_wdt_read32,
3497 static CPUWriteMemoryFunc *omap3_mpu_wdt_writefn[] = {
3498 omap_badwidth_write32,
3499 omap3_mpu_wdt_write16,
3500 omap3_mpu_wdt_write32,
3505 static void omap3_mpu_wdt_timer_tick(void *opaque)
3507 struct omap3_wdt_s *wdt_timer = (struct omap3_wdt_s *) opaque;
3509 /*TODO:Sent reset pulse to PRCM */
3510 wdt_timer->wcrr = wdt_timer->wldr;
3512 /*after overflow, generate the new wdt_timer->rate */
3513 wdt_timer->pre = wdt_timer->wclr & (1 << 5);
3514 wdt_timer->ptv = (wdt_timer->wclr & 0x1c) >> 2;
3516 omap_clk_getrate(wdt_timer->clk) >> (wdt_timer->pre ? wdt_timer->
3519 wdt_timer->time = qemu_get_clock(vm_clock);
3520 omap3_wdt_timer_update(wdt_timer);
3523 static struct omap3_wdt_s *omap3_mpu_wdt_init(struct omap_target_agent_s *ta,
3524 qemu_irq irq, omap_clk fclk,
3526 struct omap_mpu_state_s *mpu)
3529 struct omap3_wdt_s *s = (struct omap3_wdt_s *) qemu_mallocz(sizeof(*s));
3533 s->timer = qemu_new_timer(vm_clock, omap3_mpu_wdt_timer_tick, s);
3535 omap3_wdt_reset(s, OMAP3_MPU_WDT);
3537 omap3_wdt_clk_setup(s);
3539 iomemtype = l4_register_io_memory(0, omap3_mpu_wdt_readfn,
3540 omap3_mpu_wdt_writefn, s);
3541 omap_l4_attach(ta, 0, iomemtype);
3548 /*dummy system control module*/
3551 struct omap_mpu_state_s *mpu;
3553 uint8 interface[48]; /*0x4800 2000*/
3554 uint8 padconfs[576]; /*0x4800 2030*/
3555 uint32 general[228]; /*0x4800 2270*/
3556 uint8 mem_wkup[1024]; /*0x4800 2600*/
3557 uint8 padconfs_wkup[84]; /*0x4800 2a00*/
3558 uint32 general_wkup[8]; /*0x4800 2a60*/
3561 #define PADCONFS_VALUE(wakeup0,wakeup1,offmode0,offmode1, \
3562 inputenable0,inputenable1,pupd0,pupd1,muxmode0,muxmode1,offset) \
3564 *(padconfs+offset/4) = (wakeup0 <<14)|(offmode0<<9)|(inputenable0<<8)|(pupd0<<3)|(muxmode0); \
3565 *(padconfs+offset/4) |= (wakeup1 <<30)|(offmode1<<25)|(inputenable1<<24)|(pupd1<<19)|(muxmode1<<16); \
3569 static void omap3_scm_reset(struct omap3_scm_s *s)
3572 padconfs = (uint32 *)(s->padconfs);
3573 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x0);
3574 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x4);
3575 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x8);
3576 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0xc);
3577 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x10);
3578 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x14);
3579 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x18);
3580 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x1c);
3581 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x20);
3582 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x24);
3583 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x28);
3584 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x2c);
3585 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x30);
3586 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x34);
3587 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x38);
3588 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x3c);
3589 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x40);
3590 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x44);
3591 PADCONFS_VALUE(0,0,0,0,1,1,0,1,0,7,0x48);
3592 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x4c);
3593 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x50);
3594 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x54);
3595 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x58);
3596 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,0,0x5c);
3597 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x60);
3598 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x64);
3599 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x68);
3600 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x6c);
3601 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x70);
3602 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x74);
3603 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x78);
3604 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x7c);
3605 PADCONFS_VALUE(0,0,0,0,1,1,0,3,0,7,0x80);
3606 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x84);
3607 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x88);
3608 PADCONFS_VALUE(0,0,0,0,1,1,3,0,7,0,0x8c);
3609 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x90);
3610 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x94);
3611 PADCONFS_VALUE(0,0,0,0,1,1,1,0,7,0,0x98);
3612 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,7,0x9c);
3613 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0xa0);
3614 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0xa4);
3615 PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0xa8);
3616 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xac);
3617 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xb0);
3618 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xb4);
3619 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xb8);
3620 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xbc);
3621 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xc0);
3622 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xc4);
3623 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xc8);
3624 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xcc);
3625 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xd0);
3626 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xd4);
3627 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xd8);
3628 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xdc);
3629 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xe0);
3630 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xe4);
3631 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xe8);
3632 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xec);
3633 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xf0);
3634 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xf4);
3635 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xf8);
3636 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xfc);
3637 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x100);
3638 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x104);
3639 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x108);
3640 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x10c);
3641 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x110);
3642 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x114);
3643 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x118);
3644 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x11c);
3645 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x120);
3646 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x124);
3647 PADCONFS_VALUE(0,0,0,0,1,1,1,3,7,7,0x128);
3648 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x12c);
3649 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x130);
3650 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x134);
3651 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x138);
3652 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x13c);
3653 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x140);
3654 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x144);
3655 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x148);
3656 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x14c);
3657 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x150);
3658 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x154);
3659 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x158);
3660 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x15c);
3661 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x160);
3662 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x164);
3663 PADCONFS_VALUE(0,0,0,0,1,1,1,3,7,7,0x168);
3664 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x16c);
3665 PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0x170);
3666 PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0x174);
3667 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x178);
3668 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x17c);
3669 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x180);
3670 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x184);
3671 PADCONFS_VALUE(0,0,0,0,1,1,1,3,7,7,0x188);
3672 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x18c);
3673 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x190);
3674 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x194);
3675 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x198);
3676 PADCONFS_VALUE(0,0,0,0,1,1,1,3,7,7,0x19c);
3677 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x1a0);
3678 PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0x1a4);
3679 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x1a8);
3680 PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0x1ac);
3681 PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0x1b0);
3682 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1b4);
3683 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1b8);
3684 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1bc);
3685 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1c0);
3686 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1c4);
3687 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1c8);
3688 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1cc);
3689 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1d0);
3690 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1d4);
3691 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1d8);
3692 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1dc);
3693 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1e0);
3694 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1e4);
3695 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1e8);
3696 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1ec);
3697 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1f0);
3698 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1f4);
3699 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1f8);
3700 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1fc);
3701 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x200);
3702 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x204);
3703 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x208);
3704 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x20c);
3705 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x210);
3706 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x214);
3707 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x218);
3708 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x21c);
3709 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x220);
3710 PADCONFS_VALUE(0,0,0,0,1,1,3,1,0,0,0x224);
3711 PADCONFS_VALUE(0,0,0,0,1,1,0,1,0,0,0x228);
3712 PADCONFS_VALUE(0,0,0,0,1,1,0,1,0,0,0x22c);
3713 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x230);
3714 PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x234);
3717 padconfs = (uint32 *)(s->general);
3718 s->general[1] = 0x4000000; /*0x4800 2274*/
3719 s->general[0x1c] = 0x1; /*0x4800 22e0*/
3720 s->general[0x75] = 0x7fc0; /*0x4800 2444*/
3721 s->general[0x76] = 0xaa; /*0x4800 2448*/
3722 s->general[0x7c] = 0x2700; /*0x4800 2460*/
3723 s->general[0x7d] = 0x300000; /*0x4800 2464*/
3724 s->general[0x7e] = 0x300000; /*0x4800 2468*/
3725 s->general[0x81] = 0xffff; /*0x4800 2474*/
3726 s->general[0x82] = 0xffff; /*0x4800 2478*/
3727 s->general[0x83] = 0xffff; /*0x4800 247c*/
3728 s->general[0x84] = 0x6; /*0x4800 2480*/
3729 s->general[0x85] = 0xffffffff; /*0x4800 2484*/
3730 s->general[0x86] = 0xffff; /*0x4800 2488*/
3731 s->general[0x87] = 0xffff; /*0x4800 248c*/
3732 s->general[0x88] = 0x1; /*0x4800 2490*/
3733 s->general[0x8b] = 0xffffffff; /*0x4800 249c*/
3734 s->general[0x8c] = 0xffff; /*0x4800 24a0*/
3735 s->general[0x8e] = 0xffff; /*0x4800 24a8*/
3736 s->general[0x8f] = 0xffff; /*0x4800 24ac*/
3737 s->general[0x91] = 0xffff; /*0x4800 24b4*/
3738 s->general[0x92] = 0xffff; /*0x4800 24b8*/
3739 s->general[0xac] = 0x109; /*0x4800 2520*/
3740 s->general[0xb2] = 0xffff; /*0x4800 2538*/
3741 s->general[0xb3] = 0xffff; /*0x4800 253c*/
3742 s->general[0xb4] = 0xffff; /*0x4800 2540*/
3743 PADCONFS_VALUE(0,0,0,0,1,1,3,3,4,4,0x368);
3744 PADCONFS_VALUE(0,0,0,0,1,1,3,3,4,4,0x36c);
3745 PADCONFS_VALUE(0,0,0,0,1,1,3,3,4,4,0x370);
3746 PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x374);
3747 PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x378);
3748 PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x37c);
3749 PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x380);
3750 PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x384);
3751 PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x388);
3755 padconfs = (uint32 *)(s->padconfs_wkup);
3756 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x0);
3757 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x4);
3758 PADCONFS_VALUE(0,0,0,0,1,1,3,0,0,0,0x8);
3759 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0xc);
3760 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x10);
3761 PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x14);
3762 PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x18);
3763 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1c);
3764 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x20);
3765 PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x24);
3766 PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x2c);
3769 s->general_wkup[0] = 0x66ff; /*0x4800 2A60*/
3773 static uint32_t omap3_scm_read8(void *opaque, target_phys_addr_t addr)
3775 struct omap3_scm_s *s = (struct omap3_scm_s *) opaque;
3780 return s->interface[addr];
3781 case 0x30 ... 0x26f:
3782 return s->padconfs[addr-0x30];
3783 case 0x270 ... 0x5ff:
3784 temp = (uint8_t *)s->general;
3785 return temp[addr-0x270];
3786 case 0x600 ... 0x9ff:
3787 return s->mem_wkup[addr-0x600];
3788 case 0xa00 ... 0xa5f:
3789 return s->padconfs_wkup[addr-0xa00];
3790 case 0xa60 ... 0xa7f:
3791 temp = (uint8_t *)s->general_wkup;
3792 return temp[addr-0xa60];
3794 return s->control_status & 0xff;
3796 return (s->control_status & 0xff00) >> 8;
3798 return (s->control_status & 0xff0000) >> 16;
3800 return (s->control_status & 0xff000000) >> 24; */
3805 printf("omap3_scm_read8 addr %x pc %x \n", addr,cpu_single_env->regs[15] );
3809 static uint32_t omap3_scm_read16(void *opaque, target_phys_addr_t addr)
3812 v = omap3_scm_read8(opaque, addr);
3813 v |= omap3_scm_read8(opaque, addr + 1) << 8;
3817 static uint32_t omap3_scm_read32(void *opaque, target_phys_addr_t addr)
3820 v = omap3_scm_read8(opaque, addr);
3821 v |= omap3_scm_read8(opaque, addr + 1) << 8;
3822 v |= omap3_scm_read8(opaque, addr + 2) << 16;
3823 v |= omap3_scm_read8(opaque, addr + 3) << 24;
3827 static void omap3_scm_write8(void *opaque, target_phys_addr_t addr,
3830 struct omap3_scm_s *s = (struct omap3_scm_s *) opaque;
3836 s->interface[addr] = value;
3838 case 0x30 ... 0x26f:
3839 s->padconfs[addr-0x30] = value;
3841 case 0x270 ... 0x5ff:
3842 temp = (uint8_t *)s->general;
3843 temp[addr-0x270] = value;
3845 case 0x600 ... 0x9ff:
3846 s->mem_wkup[addr-0x600] = value;
3848 case 0xa00 ... 0xa5f:
3849 s->padconfs_wkup[addr-0xa00] = value;
3851 case 0xa60 ... 0xa7f:
3852 temp = (uint8_t *)s->general_wkup;
3853 temp[addr-0xa60] = value;
3856 /*we do not care scm write*/
3857 printf("omap3_scm_write8 addr %x pc %x \n \n", addr,
3858 cpu_single_env->regs[15] - 0x80008000 + 0x80e80000);
3864 static void omap3_scm_write16(void *opaque, target_phys_addr_t addr,
3867 omap3_scm_write8(opaque, addr + 0, (value) & 0xff);
3868 omap3_scm_write8(opaque, addr + 1, (value >> 8) & 0xff);
3871 static void omap3_scm_write32(void *opaque, target_phys_addr_t addr,
3874 omap3_scm_write8(opaque, addr + 0, (value) & 0xff);
3875 omap3_scm_write8(opaque, addr + 1, (value >> 8) & 0xff);
3876 omap3_scm_write8(opaque, addr + 2, (value >> 16) & 0xff);
3877 omap3_scm_write8(opaque, addr + 3, (value >> 24) & 0xff);
3880 static CPUReadMemoryFunc *omap3_scm_readfn[] = {
3886 static CPUWriteMemoryFunc *omap3_scm_writefn[] = {
3892 static struct omap3_scm_s *omap3_scm_init(struct omap_target_agent_s *ta,
3893 struct omap_mpu_state_s *mpu)
3896 struct omap3_scm_s *s = (struct omap3_scm_s *) qemu_mallocz(sizeof(*s));
3902 iomemtype = l4_register_io_memory(0, omap3_scm_readfn,
3903 omap3_scm_writefn, s);
3904 omap_l4_attach(ta, 0, iomemtype);
3909 /*dummy SDRAM Memory Scheduler emulation*/
3912 struct omap_mpu_state_s *mpu;
3914 uint32 sms_sysconfig;
3915 uint32 sms_sysstatus;
3916 uint32 sms_rg_att[8];
3917 uint32 sms_rg_rdperm[8];
3918 uint32 sms_rg_wrperm[8];
3919 uint32 sms_rg_start[7];
3920 uint32 sms_rg_end[7];
3921 uint32 sms_security_control;
3922 uint32 sms_class_arbiter0;
3923 uint32 sms_class_arbiter1;
3924 uint32 sms_class_arbiter2;
3925 uint32 sms_interclass_arbiter;
3926 uint32 sms_class_rotation[3];
3927 uint32 sms_err_addr;
3928 uint32 sms_err_type;
3929 uint32 sms_pow_ctrl;
3930 uint32 sms_rot_control[12];
3931 uint32 sms_rot_size[12];
3932 uint32 sms_rot_physical_ba[12];
3937 static uint32_t omap3_sms_read32(void *opaque, target_phys_addr_t addr)
3939 struct omap3_sms_s *s = (struct omap3_sms_s *) opaque;
3944 return s->sms_sysconfig;
3946 return s->sms_sysstatus;
3955 return s->sms_rg_att[(addr-0x48)/0x20];
3964 return s->sms_rg_rdperm[(addr-0x50)/0x20];
3972 return s->sms_rg_wrperm[(addr-0x58)/0x20];
3980 return s->sms_rg_start[(addr-0x60)/0x20];
3989 return s->sms_rg_end[(addr-0x64)/0x20];
3991 return s->sms_security_control;
3993 return s->sms_class_arbiter0;
3995 return s->sms_class_arbiter1;
3997 return s->sms_class_arbiter2;
3999 return s->sms_interclass_arbiter;
4003 return s->sms_class_rotation[(addr-0x164)/4];
4005 return s->sms_err_addr;
4007 return s->sms_err_type;
4009 return s->sms_pow_ctrl;
4022 return s->sms_rot_control[(addr-0x180)/0x10];
4035 return s->sms_rot_size[(addr-0x184)/0x10];
4049 return s->sms_rot_size[(addr-0x188)/0x10];
4052 printf("omap3_sms_read32 addr %x \n", addr);
4057 static void omap3_sms_write32(void *opaque, target_phys_addr_t addr,
4060 struct omap3_sms_s *s = (struct omap3_sms_s *) opaque;
4069 s->sms_sysconfig = value & 0x1f;
4080 s->sms_rg_att[(addr-0x48)/0x20] = value;
4090 s->sms_rg_rdperm[(addr-0x50)/0x20] = value&0xffff;
4099 s->sms_rg_wrperm[(addr-0x58)/0x20] = value&0xffff;
4108 s->sms_rg_start[(addr-0x60)/0x20] = value;
4117 s->sms_rg_end[(addr-0x64)/0x20] = value;
4120 s->sms_security_control = value &0xfffffff;
4123 s->sms_class_arbiter0 = value;
4126 s->sms_class_arbiter1 = value;
4129 s->sms_class_arbiter2 = value;
4132 s->sms_interclass_arbiter = value;
4137 s->sms_class_rotation[(addr-0x164)/4] = value;
4140 s->sms_err_addr = value;
4143 s->sms_err_type = value;
4146 s->sms_pow_ctrl = value;
4160 s->sms_rot_control[(addr-0x180)/0x10] = value;
4174 s->sms_rot_size[(addr-0x184)/0x10] = value;
4189 s->sms_rot_size[(addr-0x188)/0x10] = value;
4192 printf("omap3_sms_write32 addr %x\n", addr);
4197 static CPUReadMemoryFunc *omap3_sms_readfn[] = {
4198 omap_badwidth_read32,
4199 omap_badwidth_read32,
4203 static CPUWriteMemoryFunc *omap3_sms_writefn[] = {
4204 omap_badwidth_write32,
4205 omap_badwidth_write32,
4209 static void omap3_sms_reset(struct omap3_sms_s *s)
4211 s->sms_sysconfig = 0x1;
4212 s->sms_class_arbiter0 = 0x500000;
4213 s->sms_class_arbiter1 = 0x500;
4214 s->sms_class_arbiter2 = 0x55000;
4215 s->sms_interclass_arbiter = 0x400040;
4216 s->sms_class_rotation[0] = 0x1;
4217 s->sms_class_rotation[1] = 0x1;
4218 s->sms_class_rotation[2] = 0x1;
4219 s->sms_pow_ctrl = 0x80;
4222 static struct omap3_sms_s *omap3_sms_init(struct omap_mpu_state_s *mpu)
4225 struct omap3_sms_s *s = (struct omap3_sms_s *) qemu_mallocz(sizeof(*s));
4231 iomemtype = cpu_register_io_memory(0, omap3_sms_readfn,
4232 omap3_sms_writefn, s);
4233 cpu_register_physical_memory(0x6c000000, 0x10000, iomemtype);
4238 static const struct dma_irq_map omap3_dma_irq_map[] = {
4239 {0, OMAP_INT_35XX_SDMA_IRQ0},
4240 {0, OMAP_INT_35XX_SDMA_IRQ1},
4241 {0, OMAP_INT_35XX_SDMA_IRQ2},
4242 {0, OMAP_INT_35XX_SDMA_IRQ3},
4245 static int omap3_validate_addr(struct omap_mpu_state_s *s,
4246 target_phys_addr_t addr)
4252 set the kind of memory connected to GPMC that we are trying to boot form.
4253 Uses SYS BOOT settings.
4255 void omap3_set_mem_type(struct omap_mpu_state_s *s,int bootfrom)
4259 case 0x0: /*GPMC_NOR*/
4260 s->omap3_scm->general[32] |= 7;
4262 case 0x1: /*GPMC_NAND*/
4263 s->omap3_scm->general[32] |= 1;
4266 s->omap3_scm->general[32] |= 8;
4269 s->omap3_scm->general[32] |= 0;
4272 s->omap3_scm->general[32] |= 17;
4275 s->omap3_scm->general[32] |= 3;
4280 void omap3_set_device_type(struct omap_mpu_state_s *s,int device_type)
4282 s->omap3_scm->general[32] |= (device_type & 0x7) << 8;
4285 struct omap_mpu_state_s *omap3530_mpu_init(unsigned long sdram_size,
4288 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
4289 qemu_mallocz(sizeof(struct omap_mpu_state_s));
4290 ram_addr_t sram_base, q2_base;
4292 qemu_irq dma_irqs[4];
4295 //omap_clk gpio_clks[4];
4298 s->mpu_model = omap3530;
4299 s->env = cpu_init("cortex-a8-r2");
4302 fprintf(stderr, "Unable to find CPU definition\n");
4305 s->sdram_size = sdram_size;
4306 s->sram_size = OMAP3530_SRAM_SIZE;
4308 sdindex = drive_get_index(IF_SD, 0, 0);
4309 if (sdindex == -1) {
4310 fprintf(stderr, "qemu: missing SecureDigital device\n");
4317 /* Memory-mapped stuff */
4319 q2_base = qemu_ram_alloc(s->sdram_size);
4320 cpu_register_physical_memory(OMAP3_Q2_BASE, s->sdram_size,
4321 (q2_base | IO_MEM_RAM));
4322 sram_base = qemu_ram_alloc(s->sram_size);
4323 cpu_register_physical_memory(OMAP3_SRAM_BASE, s->sram_size,
4324 (sram_base | IO_MEM_RAM));
4326 s->l4 = omap_l4_init(OMAP3_L4_BASE,
4327 sizeof(omap3_l4_agent_info)
4328 / sizeof(struct omap_l4_agent_info_s));
4330 cpu_irq = arm_pic_init_cpu(s->env);
4331 s->ih[0] = omap2_inth_init(s, 0x48200000, 0x1000, 3, &s->irq[0],
4332 cpu_irq[ARM_PIC_CPU_IRQ],
4333 cpu_irq[ARM_PIC_CPU_FIQ],
4334 omap_findclk(s, "omap3_mpu_intc_fclk"),
4335 omap_findclk(s, "omap3_mpu_intc_iclk"));
4337 for (i = 0; i < 4; i++)
4339 s->irq[omap3_dma_irq_map[i].ih][omap3_dma_irq_map[i].intr];
4340 s->dma = omap_dma4_init(0x48056000, dma_irqs, s, 256, 32,
4341 omap_findclk(s, "omap3_sdma_fclk"),
4342 omap_findclk(s, "omap3_sdma_iclk"));
4343 s->port->addr_valid = omap3_validate_addr;
4346 /* Register SDRAM and SRAM ports for fast DMA transfers. */
4347 soc_dma_port_add_mem_ram(s->dma, q2_base, OMAP2_Q2_BASE, s->sdram_size);
4348 soc_dma_port_add_mem_ram(s->dma, sram_base, OMAP2_SRAM_BASE, s->sram_size);
4351 s->omap3_cm = omap3_cm_init(omap3_l4ta_get(s->l4, L4A_CM), NULL, NULL, NULL, s);
4353 s->omap3_prm = omap3_prm_init(omap3_l4ta_get(s->l4, L4A_PRM),
4354 s->irq[0][OMAP_INT_35XX_PRCM_MPU_IRQ],
4357 s->omap3_mpu_wdt = omap3_mpu_wdt_init(omap3_l4ta_get(s->l4, L4A_WDTIMER2),
4359 omap_findclk(s, "omap3_wkup_32k_fclk"),
4360 omap_findclk(s, "omap3_wkup_l4_iclk"),
4363 s->omap3_l3 = omap3_l3_init(OMAP3_L3_BASE,
4365 sizeof(omap3_l3_region)
4366 / sizeof(struct omap_l3_region_s));
4367 s->omap3_scm = omap3_scm_init(omap3_l4ta_get(s->l4, L4A_SCM), s);
4369 s->omap3_sms = omap3_sms_init(s);
4371 s->gptimer[0] = omap_gp_timer_init(omap3_l4ta_get(s->l4, L4A_GPTIMER1),
4372 s->irq[0][OMAP_INT_35XX_GPTIMER1],
4373 omap_findclk(s, "omap3_gp1_fclk"),
4374 omap_findclk(s, "omap3_wkup_l4_iclk"));
4375 s->gptimer[1] = omap_gp_timer_init(omap3_l4ta_get(s->l4, L4A_GPTIMER2),
4376 s->irq[0][OMAP_INT_35XX_GPTIMER2],
4377 omap_findclk(s, "omap3_gp2_fclk"),
4378 omap_findclk(s, "omap3_per_l4_iclk"));
4379 s->gptimer[2] = omap_gp_timer_init(omap3_l4ta_get(s->l4, L4A_GPTIMER3),
4380 s->irq[0][OMAP_INT_35XX_GPTIMER3],
4381 omap_findclk(s, "omap3_gp3_fclk"),
4382 omap_findclk(s, "omap3_per_l4_iclk"));
4383 s->gptimer[3] = omap_gp_timer_init(omap3_l4ta_get(s->l4, L4A_GPTIMER4),
4384 s->irq[0][OMAP_INT_35XX_GPTIMER4],
4385 omap_findclk(s, "omap3_gp4_fclk"),
4386 omap_findclk(s, "omap3_per_l4_iclk"));
4387 s->gptimer[4] = omap_gp_timer_init(omap3_l4ta_get(s->l4, L4A_GPTIMER5),
4388 s->irq[0][OMAP_INT_35XX_GPTIMER5],
4389 omap_findclk(s, "omap3_gp5_fclk"),
4390 omap_findclk(s, "omap3_per_l4_iclk"));
4391 s->gptimer[5] = omap_gp_timer_init(omap3_l4ta_get(s->l4, L4A_GPTIMER6),
4392 s->irq[0][OMAP_INT_35XX_GPTIMER6],
4393 omap_findclk(s, "omap3_gp6_fclk"),
4394 omap_findclk(s, "omap3_per_l4_iclk"));
4395 s->gptimer[6] = omap_gp_timer_init(omap3_l4ta_get(s->l4, L4A_GPTIMER7),
4396 s->irq[0][OMAP_INT_35XX_GPTIMER7],
4397 omap_findclk(s, "omap3_gp7_fclk"),
4398 omap_findclk(s, "omap3_per_l4_iclk"));
4399 s->gptimer[7] = omap_gp_timer_init(omap3_l4ta_get(s->l4, L4A_GPTIMER8),
4400 s->irq[0][OMAP_INT_35XX_GPTIMER8],
4401 omap_findclk(s, "omap3_gp8_fclk"),
4402 omap_findclk(s, "omap3_per_l4_iclk"));
4403 s->gptimer[8] = omap_gp_timer_init(omap3_l4ta_get(s->l4, L4A_GPTIMER9),
4404 s->irq[0][OMAP_INT_35XX_GPTIMER9],
4405 omap_findclk(s, "omap3_gp9_fclk"),
4406 omap_findclk(s, "omap3_per_l4_iclk"));
4407 s->gptimer[9] = omap_gp_timer_init(omap3_l4ta_get(s->l4, L4A_GPTIMER10),
4408 s->irq[0][OMAP_INT_35XX_GPTIMER10],
4409 omap_findclk(s, "omap3_gp10_fclk"),
4410 omap_findclk(s, "omap3_core_l4_iclk"));
4411 s->gptimer[10] = omap_gp_timer_init(omap3_l4ta_get(s->l4, L4A_GPTIMER11),
4412 s->irq[0][OMAP_INT_35XX_GPTIMER11],
4413 omap_findclk(s, "omap3_gp12_fclk"),
4414 omap_findclk(s, "omap3_core_l4_iclk"));
4415 s->gptimer[11] = omap_gp_timer_init(omap3_l4ta_get(s->l4, L4A_GPTIMER12),
4416 s->irq[0][OMAP_INT_35XX_GPTIMER12],
4417 omap_findclk(s, "omap3_gp12_fclk"),
4418 omap_findclk(s, "omap3_wkup_l4_iclk"));
4421 omap_synctimer_init(omap3_l4ta_get(s->l4, L4A_32KTIMER), s,
4422 omap_findclk(s, "omap3_sys_32k"), NULL);
4424 s->sdrc = omap_sdrc_init(0x6d000000);
4426 s->gpmc = omap_gpmc_init(s, 0x6e000000, s->irq[0][OMAP_INT_35XX_GPMC_IRQ]);
4429 s->uart[0] = omap2_uart_init(omap3_l4ta_get(s->l4, L4A_UART1),
4430 s->irq[0][OMAP_INT_35XX_UART1_IRQ],
4431 omap_findclk(s, "omap3_uart1_fclk"),
4432 omap_findclk(s, "omap3_uart1_iclk"),
4433 s->drq[OMAP35XX_DMA_UART1_TX],
4434 s->drq[OMAP35XX_DMA_UART1_RX], serial_hds[0]);
4435 s->uart[1] = omap2_uart_init(omap3_l4ta_get(s->l4, L4A_UART2),
4436 s->irq[0][OMAP_INT_35XX_UART2_IRQ],
4437 omap_findclk(s, "omap3_uart2_fclk"),
4438 omap_findclk(s, "omap3_uart2_iclk"),
4439 s->drq[OMAP35XX_DMA_UART2_TX],
4440 s->drq[OMAP35XX_DMA_UART2_RX],
4441 serial_hds[0] ? serial_hds[1] : 0);
4442 s->uart[2] = omap2_uart_init(omap3_l4ta_get(s->l4, L4A_UART3),
4443 s->irq[0][OMAP_INT_35XX_UART3_IRQ],
4444 omap_findclk(s, "omap3_uart2_fclk"),
4445 omap_findclk(s, "omap3_uart3_iclk"),
4446 s->drq[OMAP35XX_DMA_UART3_TX],
4447 s->drq[OMAP35XX_DMA_UART3_RX],
4449 && serial_hds[1] ? serial_hds[2] : 0);
4451 /*attach serial[0] to uart 2 for beagle board */
4452 omap_uart_attach(s->uart[2], serial_hds[0]);
4454 s->dss = omap_dss_init(s, omap3_l4ta_get(s->l4, L4A_DSS),
4455 s->irq[0][OMAP_INT_35XX_DSS_IRQ], s->drq[OMAP24XX_DMA_DSS],
4456 NULL,NULL,NULL,NULL,NULL);
4458 //gpio_clks[0] = NULL;
4459 //gpio_clks[1] = NULL;
4460 //gpio_clks[2] = NULL;
4461 //gpio_clks[3] = NULL;
4463 s->gpif = omap3_gpif_init();
4464 omap3_gpio_init(s, s->gpif ,omap3_l4ta_get(s->l4, L4A_GPIO1),
4465 &s->irq[0][OMAP_INT_35XX_GPIO_BANK1],
4467 omap3_gpio_init(s, s->gpif ,omap3_l4ta_get(s->l4, L4A_GPIO2),
4468 &s->irq[0][OMAP_INT_35XX_GPIO_BANK2],
4470 omap3_gpio_init(s, s->gpif ,omap3_l4ta_get(s->l4, L4A_GPIO3),
4471 &s->irq[0][OMAP_INT_35XX_GPIO_BANK3],
4473 omap3_gpio_init(s, s->gpif ,omap3_l4ta_get(s->l4, L4A_GPIO4),
4474 &s->irq[0][OMAP_INT_35XX_GPIO_BANK4],
4476 omap3_gpio_init(s, s->gpif ,omap3_l4ta_get(s->l4, L4A_GPIO5),
4477 &s->irq[0][OMAP_INT_35XX_GPIO_BANK5],
4479 omap3_gpio_init(s, s->gpif ,omap3_l4ta_get(s->l4, L4A_GPIO6),
4480 &s->irq[0][OMAP_INT_35XX_GPIO_BANK6],
4483 omap_tap_init(omap3_l4ta_get(s->l4, L4A_TAP), s);
4485 s->omap3_mmc[0] = omap3_mmc_init(omap3_l4ta_get(s->l4, L4A_MMC1),
4486 drives_table[sdindex].bdrv,
4487 s->irq[0][OMAP_INT_35XX_MMC1_IRQ],
4488 &s->drq[OMAP35XX_DMA_MMC1_TX],
4489 omap_findclk(s, "omap3_mmc1_fclk"),
4490 omap_findclk(s, "omap3_mmc1_iclk"));
4492 s->omap3_mmc[1] = omap3_mmc_init(omap3_l4ta_get(s->l4, L4A_MMC2),
4494 s->irq[0][OMAP_INT_35XX_MMC2_IRQ],
4495 &s->drq[OMAP35XX_DMA_MMC2_TX],
4496 omap_findclk(s, "omap3_mmc2_fclk"),
4497 omap_findclk(s, "omap3_mmc2_iclk"));
4499 s->omap3_mmc[2] = omap3_mmc_init(omap3_l4ta_get(s->l4, L4A_MMC3),
4501 s->irq[0][OMAP_INT_35XX_MMC3_IRQ],
4502 &s->drq[OMAP35XX_DMA_MMC3_TX],
4503 omap_findclk(s, "omap3_mmc3_fclk"),
4504 omap_findclk(s, "omap3_mmc3_iclk"));
4506 s->i2c[0] = omap3_i2c_init(omap3_l4ta_get(s->l4, L4A_I2C1),
4507 s->irq[0][OMAP_INT_35XX_I2C1_IRQ],
4508 &s->drq[OMAP35XX_DMA_I2C1_TX],
4509 omap_findclk(s, "omap3_i2c1_fclk"),
4510 omap_findclk(s, "omap3_i2c1_iclk"),
4512 s->i2c[1] = omap3_i2c_init(omap3_l4ta_get(s->l4, L4A_I2C2),
4513 s->irq[0][OMAP_INT_35XX_I2C2_IRQ],
4514 &s->drq[OMAP35XX_DMA_I2C2_TX],
4515 omap_findclk(s, "omap3_i2c2_fclk"),
4516 omap_findclk(s, "omap3_i2c2_iclk"),
4518 s->i2c[2] = omap3_i2c_init(omap3_l4ta_get(s->l4, L4A_I2C3),
4519 s->irq[0][OMAP_INT_35XX_I2C3_IRQ],
4520 &s->drq[OMAP35XX_DMA_I2C3_TX],
4521 omap_findclk(s, "omap3_i2c3_fclk"),
4522 omap_findclk(s, "omap3_i2c3_iclk"),
4529 static uint32_t omap3_get_le32(void *p)
4531 uint8_t *q = (uint8_t *)p;
4540 static uint32_t omap3_get_le16(void *p)
4542 uint8_t *q = (uint8_t *)p;
4549 /* returns ptr to matching dir entry / zero entry or 0 if unsuccessful */
4550 static uint8_t *omap3_scan_fat_dir_sector(uint8_t *s)
4554 /* there are 0x10 items with 0x20 bytes per item */
4555 for (i = 0x10; i--; s += 0x20) {
4556 if (*s == 0xe5 || (s[0x0b] & 0x0f) == 0x0f) continue; /* erased/LFN */
4557 if (!*s || !strncasecmp((void *)s, "mlo ", 8+3)) return s;
4562 struct omap3_fat_drv_s {
4563 BlockDriverState *bs;
4564 uint8_t ptype; // 12, 16, 32
4565 uint64_t c0; // physical byte offset for data cluster 0
4566 uint64_t fat; // physical byte offset for used FAT sector 0
4567 uint32_t spc; // sectors per cluster
4570 /* returns cluster data in the buffer and next cluster chain number
4571 or 0 if unsuccessful */
4572 static uint32_t omap3_read_fat_cluster(uint8_t *data,
4573 struct omap3_fat_drv_s *drv,
4577 uint32_t len = drv->spc * 0x200; // number of bytes to read
4579 switch (drv->ptype) { /* check for EOF */
4580 case 12: if (cl > 0xff0) return 0; break;
4581 case 16: if (cl > 0xfff0) return 0; break;
4582 case 32: if (cl > 0x0ffffff0) return 0; break;
4586 if (bdrv_pread(drv->bs,
4587 drv->c0 + ((drv->ptype == 32 ? cl - 2 : cl) * len),
4591 switch (drv->ptype) { /* determine next cluster # */
4593 fprintf(stderr, "%s: FAT12 parsing not implemented!\n",
4597 return (bdrv_pread(drv->bs, drv->fat + cl * 2, buf, 2) != 2)
4598 ? 0 : omap3_get_le16(buf);
4600 return (bdrv_pread(drv->bs, drv->fat + cl * 4, buf, 4) != 4)
4601 ? 0 : omap3_get_le32(buf) & 0x0fffffff;
4608 static int omap3_mmc_fat_boot(BlockDriverState *bs,
4611 struct omap_mpu_state_s *mpu)
4613 struct omap3_fat_drv_s drv;
4614 uint32_t i, j, k, cluster0, fatsize, bootsize, rootsize;
4615 uint32_t img_size, img_addr;
4619 /* determine FAT type */
4622 fatsize = omap3_get_le16(sector + 0x16);
4624 fatsize = omap3_get_le32(sector + 0x24);
4625 bootsize = omap3_get_le16(sector + 0x0e);
4626 cluster0 = bootsize + fatsize * sector[0x10];
4627 rootsize = omap3_get_le16(sector + 0x11);
4628 if (rootsize & 0x0f)
4631 drv.spc = sector[0x0d];
4632 i = omap3_get_le16(sector + 0x13);
4634 i = omap3_get_le32(sector + 0x20);
4635 i = (i - (cluster0 + rootsize)) / drv.spc;
4636 drv.ptype = (i < 4085) ? 12 : (i < 65525) ? 16 : 32;
4638 /* search for boot loader file */
4640 drv.fat = (bootsize + pstart) * 0x200;
4641 drv.c0 = (cluster0 + pstart) * 0x200;
4642 if (drv.ptype == 32) {
4643 i = omap3_get_le32(sector + 0x2c); /* first root cluster # */
4644 j = omap3_get_le16(sector + 0x28);
4646 drv.fat += (j & 0x0f) * fatsize * 0x200;
4647 uint8_t *cluster = qemu_mallocz(drv.spc * 0x200);
4648 for (p = 0; !p && (i = omap3_read_fat_cluster(cluster, &drv, i)); ) {
4649 for (j = drv.spc, q=cluster; j-- & !p; q += 0x200)
4650 p = omap3_scan_fat_dir_sector(q);
4652 memcpy(sector, q - 0x200, 0x200); // save the sector
4655 } else { /* FAT12/16 */
4656 for (i = rootsize, j = 0, p = 0; i-- && !p; j++) {
4657 if (bdrv_pread(drv.bs, drv.c0 + j * 0x200, sector, 0x200) != 0x200)
4659 p = omap3_scan_fat_dir_sector(sector);
4663 if (p && *p) { // did we indeed find the file?
4664 i = omap3_get_le16(p + 0x14);
4666 i |= omap3_get_le16(p + 0x1a);
4667 j = drv.spc * 0x200;
4668 uint8 *data = qemu_mallocz(j);
4669 if ((i = omap3_read_fat_cluster(data, &drv, i))) {
4670 /* TODO: support HS device boot
4671 for now only GP device is supported */
4672 img_size = omap3_get_le32(data);
4673 img_addr = omap3_get_le32(data + 4);
4674 mpu->env->regs[15] = img_addr;
4675 cpu_physical_memory_write(img_addr, data + 8,
4676 (k = (j - 8 >= img_size) ? img_size : j - 8));
4677 for (img_addr += k, img_size -= k;
4678 img_size && (i = omap3_read_fat_cluster(data, &drv, i));
4679 img_addr += k, img_size -= k) {
4680 cpu_physical_memory_write(img_addr, data,
4681 (k = (j >= img_size) ? img_size : j));
4685 fprintf(stderr, "%s: unable to read MLO file contents from SD card\n",
4689 fprintf(stderr, "%s: MLO file not found in the root directory\n",
4695 static int omap3_mmc_raw_boot(BlockDriverState *bs,
4697 struct omap_mpu_state_s *mpu)
4702 /* returns non-zero if successful, zero if unsuccessful */
4703 int omap3_mmc_boot(struct omap_mpu_state_s *s)
4705 BlockDriverState *bs;
4706 int sdindex = drive_get_index(IF_SD, 0, 0);
4707 uint8_t sector[0x200], *p;
4710 /* very simple implementation, supports only two modes:
4711 1. MBR partition table with an active FAT partition
4712 and boot loader file (MLO) in its root directory, or
4713 2. boot loader located on first sector */
4715 bs = drives_table[sdindex].bdrv;
4716 if (bdrv_pread(bs, 0, sector, 0x200) == 0x200) {
4717 for (i = 0, p = sector + 0x1be; i < 4; i++, p += 0x10)
4718 if (p[0] == 0x80) break;
4719 if (sector[0x1fe] == 0x55 && sector[0x1ff] == 0xaa /* signature */
4720 && i < 4 /* active partition exists */
4721 && (p[4] == 1 || p[4] == 4 || p[4] == 6 || p[4] == 11
4722 || p[4] == 12 || p[4] == 14 || p[4] == 15) /* FAT */
4723 && bdrv_pread(bs, (pstart = omap3_get_le32(p + 8)) * 0x200,
4724 sector, 0x200) == 0x200
4725 && sector[0x1fe] == 0x55 && sector[0x1ff] == 0xaa)
4726 return omap3_mmc_fat_boot(bs, sector, pstart, s);
4728 return omap3_mmc_raw_boot(bs, sector, s);