initial SPI support for OMAP3
[qemu] / hw / omap3.c
1 /*
2  * TI OMAP3 processors emulation.
3  *
4  * Copyright (C) 2008 yajin <yajin@vm-kernel.org>
5  * Copyright (C) 2009 Nokia Corporation
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2 or
10  * (at your option) version 3 of the License.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20  * MA 02111-1307 USA
21  */
22
23 #include "hw.h"
24 #include "arm-misc.h"
25 #include "omap.h"
26 #include "sysemu.h"
27 #include "qemu-timer.h"
28 #include "qemu-char.h"
29 #include "flash.h"
30 #include "soc_dma.h"
31 #include "audio/audio.h"
32 #include "block.h"
33
34 //#define OMAP3_DEBUG_
35
36 #ifdef OMAP3_DEBUG_
37 #define TRACE(fmt, ...) fprintf(stderr, "%s " fmt "\n", __FUNCTION__, ##__VA_ARGS__)
38 #else
39 #define TRACE(...) 
40 #endif
41
42 typedef enum {
43     /* 68000000-680003FF */ L3ID_L3RT = 0,
44     /* 68000400-680007FF */ L3ID_L3SI,
45     /* 68000800-680013FF */
46     /* 68001400-680017FF */ L3ID_MPUSS_IA,
47     /* 68001800-68001BFF */ L3ID_IVASS_IA,
48     /* 68001C00-68001FFF */ L3ID_SGXSS_IA,
49     /* 68002000-680023FF */ L3ID_SMS_TA,
50     /* 68002400-680027FF */ L3ID_GPMC_TA,
51     /* 68002800-68002BFF */ L3ID_OCM_RAM_TA,
52     /* 68002C00-68002FFF */ L3ID_OCM_ROM_TA,
53     /* 68003000-680033FF */ L3ID_D2D_IA,
54     /* 68003400-680037FF */ L3ID_D2D_TA,
55     /* 68003800-68003FFF */
56     /* 68004000-680043FF */ L3ID_HSUSB_HOST_IA,
57     /* 68004400-680047FF */ L3ID_HSUSB_OTG_IA,
58     /* 68004800-68004BFF */
59     /* 68004C00-68004FFF */ L3ID_SDMA_RD_IA,
60     /* 68005000-680053FF */ L3ID_SDMA_WR_IA,
61     /* 68005400-680057FF */ L3ID_DSS_IA,
62     /* 68005800-68005BFF */ L3ID_CAMISP_IA,
63     /* 68005C00-68005FFF */ L3ID_DAP_IA,
64     /* 68006000-680063FF */ L3ID_IVASS_TA,
65     /* 68006400-680067FF */ L3ID_SGXSS_TA,
66     /* 68006800-68006BFF */ L3ID_L4_CORE_TA,
67     /* 68006C00-68006FFF */ L3ID_L4_PER_TA,
68     /* 68007000-680073FF */ L3ID_L4_EMU_TA,
69     /* 68007400-6800FFFF */
70     /* 68010000-680103FF */ L3ID_RT_PM,
71     /* 68010400-680123FF */
72     /* 68012400-680127FF */ L3ID_GPMC_PM,
73     /* 68012800-68012BFF */ L3ID_OCM_RAM_PM,
74     /* 68012C00-68012FFF */ L3ID_OCM_ROM_PM,
75     /* 68013000-680133FF */ L3ID_D2D_PM,
76     /* 68013400-68013FFF */
77     /* 68014000-680143FF */ L3ID_IVA_PM,
78     /* 68014400-68FFFFFF */
79 } omap3_l3_region_id_t;
80
81 struct omap_l3_region_s {
82     target_phys_addr_t offset;
83     size_t size;
84     enum {
85         L3TYPE_GENERIC = 0, /* needs to be mapped separately */
86         L3TYPE_IA,          /* initiator agent */
87         L3TYPE_TA,          /* target agent */
88         L3TYPE_PM,          /* protection mechanism */
89         L3TYPE_UNDEFINED,   /* every access will emit an error message */
90     } type;
91 };
92
93 struct omap3_l3_initiator_agent_s {
94     target_phys_addr_t base;
95     
96     uint32_t component;
97     uint32_t control;
98     uint32_t status;
99 };
100
101 struct omap3_l3pm_s {
102     target_phys_addr_t base;
103     
104     uint32_t error_log;
105     uint8_t  control;
106     uint16_t req_info_permission[8];
107     uint16_t read_permission[8];
108     uint16_t write_permission[8];
109     uint32_t addr_match[7];
110 };
111
112 union omap3_l3_port_s {
113     struct omap_target_agent_s ta;
114     struct omap3_l3_initiator_agent_s ia;
115     struct omap3_l3pm_s pm;
116 };
117
118 struct omap_l3_s {
119     target_phys_addr_t base;
120     int region_count;
121     union omap3_l3_port_s region[0];
122 };
123
124 static struct omap_l3_region_s omap3_l3_region[] = {
125     [L3ID_L3RT         ] = {0x00000000, 0x0400, L3TYPE_UNDEFINED},
126     [L3ID_L3SI         ] = {0x00000400, 0x0400, L3TYPE_UNDEFINED},
127     [L3ID_MPUSS_IA     ] = {0x00001400, 0x0400, L3TYPE_IA},
128     [L3ID_IVASS_IA     ] = {0x00001800, 0x0400, L3TYPE_IA},
129     [L3ID_SGXSS_IA     ] = {0x00001c00, 0x0400, L3TYPE_IA},
130     [L3ID_SMS_TA       ] = {0x00002000, 0x0400, L3TYPE_TA},
131     [L3ID_GPMC_TA      ] = {0x00002400, 0x0400, L3TYPE_TA},
132     [L3ID_OCM_RAM_TA   ] = {0x00002800, 0x0400, L3TYPE_TA},
133     [L3ID_OCM_ROM_TA   ] = {0x00002c00, 0x0400, L3TYPE_TA},
134     [L3ID_D2D_IA       ] = {0x00003000, 0x0400, L3TYPE_IA},
135     [L3ID_D2D_TA       ] = {0x00003400, 0x0400, L3TYPE_TA},
136     [L3ID_HSUSB_HOST_IA] = {0x00004000, 0x0400, L3TYPE_IA},
137     [L3ID_HSUSB_OTG_IA ] = {0x00004400, 0x0400, L3TYPE_IA},
138     [L3ID_SDMA_RD_IA   ] = {0x00004c00, 0x0400, L3TYPE_IA},
139     [L3ID_SDMA_WR_IA   ] = {0x00005000, 0x0400, L3TYPE_IA},
140     [L3ID_DSS_IA       ] = {0x00005400, 0x0400, L3TYPE_IA},
141     [L3ID_CAMISP_IA    ] = {0x00005800, 0x0400, L3TYPE_IA},
142     [L3ID_DAP_IA       ] = {0x00005c00, 0x0400, L3TYPE_IA},
143     [L3ID_IVASS_TA     ] = {0x00006000, 0x0400, L3TYPE_TA},
144     [L3ID_SGXSS_TA     ] = {0x00006400, 0x0400, L3TYPE_TA},
145     [L3ID_L4_CORE_TA   ] = {0x00006800, 0x0400, L3TYPE_TA},
146     [L3ID_L4_PER_TA    ] = {0x00006c00, 0x0400, L3TYPE_TA},
147     [L3ID_L4_EMU_TA    ] = {0x00007000, 0x0400, L3TYPE_TA},
148     [L3ID_RT_PM        ] = {0x00010000, 0x0400, L3TYPE_PM},
149     [L3ID_GPMC_PM      ] = {0x00012400, 0x0400, L3TYPE_PM},
150     [L3ID_OCM_RAM_PM   ] = {0x00012800, 0x0400, L3TYPE_PM},
151     [L3ID_OCM_ROM_PM   ] = {0x00012c00, 0x0400, L3TYPE_PM},
152     [L3ID_D2D_PM       ] = {0x00013000, 0x0400, L3TYPE_PM},
153     [L3ID_IVA_PM       ] = {0x00014000, 0x0400, L3TYPE_PM},
154 };
155
156 static uint32_t omap3_l3ia_read(void *opaque, target_phys_addr_t addr)
157 {
158     struct omap3_l3_initiator_agent_s *s = (struct omap3_l3_initiator_agent_s *)opaque;
159     
160     switch (addr) {
161         case 0x00: /* COMPONENT_L */
162             return s->component;
163         case 0x04: /* COMPONENT_H */
164             return 0;
165         case 0x18: /* CORE_L */
166             return s->component;
167         case 0x1c: /* CORE_H */
168             return (s->component >> 16);
169         case 0x20: /* AGENT_CONTROL_L */
170             return s->control;
171         case 0x24: /* AGENT_CONTROL_H */
172             return 0;
173         case 0x28: /* AGENT_STATUS_L */
174             return s->status;
175         case 0x2c: /* AGENT_STATUS_H */
176             return 0;
177         case 0x58: /* ERROR_LOG_L */
178             return 0;
179         case 0x5c: /* ERROR_LOG_H */
180             return 0;
181         case 0x60: /* ERROR_LOG_ADDR_L */
182             return 0;
183         case 0x64: /* ERROR_LOG_ADDR_H */
184             return 0;
185         default:
186             break;
187     }
188     
189     OMAP_BAD_REG(s->base + addr);
190     return 0;
191 }
192
193 static void omap3_l3ia_write(void *opaque, target_phys_addr_t addr,
194                              uint32_t value)
195 {
196     struct omap3_l3_initiator_agent_s *s = (struct omap3_l3_initiator_agent_s *)opaque;
197     
198     switch (addr) {
199         case 0x00: /* COMPONENT_L */
200         case 0x04: /* COMPONENT_H */
201         case 0x18: /* CORE_L */
202         case 0x1c: /* CORE_H */
203         case 0x60: /* ERROR_LOG_ADDR_L */
204         case 0x64: /* ERROR_LOG_ADDR_H */
205             OMAP_RO_REG(s->base + addr);
206             break;
207         case 0x24: /* AGENT_CONTROL_H */
208         case 0x2c: /* AGENT_STATUS_H */
209         case 0x5c: /* ERROR_LOG_H */
210             /* RW register but all bits are reserved/read-only */
211             break;
212         case 0x20: /* AGENT_CONTROL_L */
213             s->control = value & 0x3e070711;
214             /* TODO: some bits are reserved for some IA instances */
215             break;
216         case 0x28: /* AGENT_STATUS_L */
217             s->status &= ~(value & 0x30000000);
218             break;
219         case 0x58: /* ERROR_LOG_L */
220             /* error logging is not implemented, so ignore */
221             break;
222         default:
223             OMAP_BAD_REG(s->base + addr);
224             break;
225     }
226 }
227
228 static void omap3_l3ia_save_state(QEMUFile *f, void *opaque)
229 {
230     struct omap3_l3_initiator_agent_s *s =
231         (struct omap3_l3_initiator_agent_s *)opaque;
232
233     qemu_put_be32(f, s->control);
234     qemu_put_be32(f, s->status);
235 }
236
237 static int omap3_l3ia_load_state(QEMUFile *f, void *opaque, int version_id)
238 {
239     struct omap3_l3_initiator_agent_s *s =
240         (struct omap3_l3_initiator_agent_s *)opaque;
241     
242     if (version_id)
243         return -EINVAL;
244     
245     s->control = qemu_get_be32(f);
246     s->status = qemu_get_be32(f);
247     
248     return 0;
249 }
250
251 static void omap3_l3ia_init(struct omap3_l3_initiator_agent_s *s)
252 {
253     s->component = ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
254     s->control = 0x3e000000;
255     s->status = 0;
256     
257     register_savevm("omap3_l3ia", (s->base >> 8) & 0xffff, 0,
258                     omap3_l3ia_save_state, omap3_l3ia_load_state, s);
259 }
260
261 static CPUReadMemoryFunc *omap3_l3ia_readfn[] = {
262     omap_badwidth_read32,
263     omap_badwidth_read32,
264     omap3_l3ia_read,
265 };
266
267 static CPUWriteMemoryFunc *omap3_l3ia_writefn[] = {
268     omap_badwidth_write32,
269     omap_badwidth_write32,
270     omap3_l3ia_write,
271 };
272
273 static uint32_t omap3_l3ta_read(void *opaque, target_phys_addr_t addr)
274 {
275     struct omap_target_agent_s *s = (struct omap_target_agent_s *)opaque;
276     
277     switch (addr) {
278         case 0x00: /* COMPONENT_L */
279             return s->component;
280         case 0x04: /* COMPONENT_H */
281             return 0;
282         case 0x18: /* CORE_L */
283             return s->component;
284         case 0x1c: /* CORE_H */
285             return (s->component >> 16);
286         case 0x20: /* AGENT_CONTROL_L */
287             return s->control;
288         case 0x24: /* AGENT_CONTROL_H */
289             return s->control_h;
290         case 0x28: /* AGENT_STATUS_L */
291             return s->status;
292         case 0x2c: /* AGENT_STATUS_H */
293             return 0;
294         case 0x58: /* ERROR_LOG_L */
295             return 0;
296         case 0x5c: /* ERROR_LOG_H */
297             return 0;
298         case 0x60: /* ERROR_LOG_ADDR_L */
299             return 0;
300         case 0x64: /* ERROR_LOG_ADDR_H */
301             return 0;
302         default:
303             break;
304     }
305     
306     OMAP_BAD_REG(s->base + addr);
307     return 0;
308 }
309
310 static void omap3_l3ta_write(void *opaque, target_phys_addr_t addr,
311                              uint32_t value)
312 {
313     struct omap_target_agent_s *s = (struct omap_target_agent_s *)opaque;
314     
315     switch (addr) {
316         case 0x00: /* COMPONENT_L */
317         case 0x04: /* COMPONENT_H */
318         case 0x18: /* CORE_L */
319         case 0x1c: /* CORE_H */
320         case 0x60: /* ERROR_LOG_ADDR_L */
321         case 0x64: /* ERROR_LOG_ADDR_H */
322             OMAP_RO_REG(s->base + addr);
323             break;
324         case 0x24: /* AGENT_CONTROL_H */
325         case 0x5c: /* ERROR_LOG_H */
326             /* RW register but all bits are reserved/read-only */
327             break;
328         case 0x20: /* AGENT_CONTROL_L */
329             s->control = value & 0x03000711;
330             break;
331         case 0x28: /* AGENT_STATUS_L */
332             if (s->base == OMAP3_L3_BASE + omap3_l3_region[L3ID_L4_CORE_TA].offset
333                 || s->base == OMAP3_L3_BASE + omap3_l3_region[L3ID_L4_PER_TA].offset
334                 || s->base == OMAP3_L3_BASE + omap3_l3_region[L3ID_L4_EMU_TA].offset) {
335                 s->status &= ~(value & (1 << 24));
336             } else
337                 OMAP_RO_REG(s->base + addr);
338             break;
339         case 0x2c: /* AGENT_STATUS_H */
340             if (s->base != OMAP3_L3_BASE + omap3_l3_region[L3ID_L4_CORE_TA].offset
341                 && s->base != OMAP3_L3_BASE + omap3_l3_region[L3ID_L4_PER_TA].offset
342                 && s->base != OMAP3_L3_BASE + omap3_l3_region[L3ID_L4_EMU_TA].offset)
343                 OMAP_RO_REG(s->base + addr);
344             /* for L4 core, per, emu TAs this is RW reg */
345             break;
346         case 0x58: /* ERROR_LOG_L */
347             /* error logging is not implemented, so ignore */
348             break;
349         default:
350             OMAP_BAD_REG(s->base + addr);
351             break;
352     }
353 }
354
355 static void omap3_l3ta_save_state(QEMUFile *f, void *opaque)
356 {
357     struct omap_target_agent_s *s =
358         (struct omap_target_agent_s *)opaque;
359     
360     qemu_put_be32(f, s->control);
361     qemu_put_be32(f, s->status);
362 }
363
364 static int omap3_l3ta_load_state(QEMUFile *f, void *opaque, int version_id)
365 {
366     struct omap_target_agent_s *s =
367         (struct omap_target_agent_s *)opaque;
368     
369     if (version_id)
370         return -EINVAL;
371     
372     s->control = qemu_get_be32(f);
373     s->status = qemu_get_be32(f);
374     
375     return 0;
376 }
377
378 static void omap3_l3ta_init(struct omap_target_agent_s *s)
379 {
380     s->component = ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
381     s->control = 0x03000000;
382     s->status = 0;
383
384     register_savevm("omap3_l3ta", (s->base >> 8) & 0xffff, 0,
385                     omap3_l3ta_save_state, omap3_l3ta_load_state, s);
386 }
387
388 static CPUReadMemoryFunc *omap3_l3ta_readfn[] = {
389     omap_badwidth_read32,
390     omap_badwidth_read32,
391     omap3_l3ta_read,
392 };
393
394 static CPUWriteMemoryFunc *omap3_l3ta_writefn[] = {
395     omap_badwidth_write32,
396     omap_badwidth_write32,
397     omap3_l3ta_write,
398 };
399
400 static uint32_t omap3_l3pm_read8(void *opaque, target_phys_addr_t addr)
401 {
402     struct omap3_l3pm_s *s = (struct omap3_l3pm_s *)opaque;
403     int i;
404     
405     switch (addr) {
406         case 0x00 ... 0x1f:
407         case 0x40 ... 0x47:
408             OMAP_BAD_REG(s->base + addr);
409             return 0;
410         /* ERROR_LOG */
411         case 0x20: return s->error_log & 0xff;
412         case 0x21: return (s->error_log >> 8) & 0xff;
413         case 0x22: return (s->error_log >> 16) & 0xff;
414         case 0x23: return (s->error_log >> 24) & 0xff;
415         case 0x24 ... 0x27: return 0;
416         /* CONTROL */
417         case 0x28 ... 0x2a: return 0;
418         case 0x2b: return s->control;
419         case 0x2c ... 0x2f: return 0;
420         /* ERROR_CLEAR_SINGLE */
421         case 0x30: return 0; /* TODO: clear single error from log */
422         case 0x31 ... 0x37: return 0;
423         /* ERROR_CLEAR_MULTI */
424         case 0x38: return 0; /* TODO: clear multiple errors from log */
425         case 0x39 ... 0x3f: return 0;
426         default:
427             break;
428     }
429     
430     i = (addr - 0x48) / 0x20;
431     addr -= i * 0x20;
432     if (i < 7 || (i < 8 && addr < 0x60)) 
433         switch (addr) {
434             /* REQ_INFO_PERMISSION_i */
435             case 0x48: return s->req_info_permission[i] & 0xff;
436             case 0x49: return (s->req_info_permission[i] >> 8) & 0xff;
437             case 0x4a ... 0x4f: return 0;
438             /* READ_PERMISSION_i */
439             case 0x50: return s->read_permission[i] & 0xff;
440             case 0x51: return (s->read_permission[i] >> 8) & 0xff;
441             case 0x52 ... 0x57: return 0;
442             /* WRITE_PERMISSION_i */
443             case 0x58: return s->write_permission[i] & 0xff;
444             case 0x59: return (s->write_permission[i] >> 8) & 0xff;
445             case 0x5a ... 0x5f: return 0;
446             /* ADDR_MATCH_i */
447             case 0x60: return s->addr_match[i] & 0xff;
448             case 0x61: return (s->addr_match[i] >> 8) & 0xff;
449             case 0x62: return (s->addr_match[i] >> 16) & 0xff;
450             case 0x63 ... 0x67: return 0;
451             default:
452                 break;
453         }
454
455     OMAP_BAD_REG(s->base + addr);
456     return 0;
457 }
458
459 static uint32_t omap3_l3pm_read16(void *opaque, target_phys_addr_t addr)
460 {
461     return omap3_l3pm_read8(opaque, addr)
462         | (omap3_l3pm_read8(opaque, addr + 1) << 8);
463 }
464
465 static uint32_t omap3_l3pm_read32(void *opaque, target_phys_addr_t addr)
466 {
467     return omap3_l3pm_read16(opaque, addr)
468         | (omap3_l3pm_read16(opaque, addr + 2) << 16);
469 }
470
471 static void omap3_l3pm_write8(void *opaque, target_phys_addr_t addr,
472                               uint32_t value)
473 {
474     struct omap3_l3pm_s *s = (struct omap3_l3pm_s *)opaque;
475     int i;
476     
477     switch (addr) {
478         case 0x00 ... 0x1f:
479         case 0x40 ... 0x47:
480             OMAP_BAD_REGV(s->base + addr, value);
481             return;
482         /* ERROR_LOG */
483         case 0x23:
484             s->error_log &= ~((value & 0xcf) << 24);
485         case 0x20 ... 0x22:
486         case 0x24 ... 0x27:
487             return;
488         /* CONTROL */
489         case 0x2b:
490             s->control = value & 3;
491         case 0x28 ... 0x2a:
492         case 0x2c ... 0x2f:
493             return;
494         /* ERROR_CLEAR_SINGLE / ERROR_CLEAR_MULTI */
495         case 0x30 ... 0x3f:
496             OMAP_RO_REGV(s->base + addr, value);
497             return;
498         default:
499             break;
500     }
501     
502     i = (addr - 0x48) / 0x20;
503     addr -= i * 0x20;
504     if (i < 7 || (i < 8 && addr < 0x60)) 
505         switch (addr) {
506             /* REQ_INFO_PERMISSION_i */
507             case 0x48:
508                 s->req_info_permission[i] =
509                     (s->req_info_permission[i] & ~0xff) | (value & 0xff);
510                 return;
511             case 0x49:
512                 s->req_info_permission[i] =
513                     (s->req_info_permission[i] & ~0xff00) | ((value & 0xff) << 8);
514                 return;
515             case 0x4a ... 0x4f:
516                 return;
517             /* READ_PERMISSION_i */
518             case 0x50:
519                 s->read_permission[i] =
520                     (s->read_permission[i] & ~0xff) | (value & 0x3e);
521                 return;
522             case 0x51:
523                 s->read_permission[i] =
524                     (s->read_permission[i] & ~0xff00) | ((value & 0x5f) << 8);
525                 return;
526             case 0x52 ... 0x57:
527                 return;
528             /* WRITE_PERMISSION_i */
529             case 0x58:
530                 s->write_permission[i] =
531                     (s->write_permission[i] & ~0xff) | (value & 0x3e);
532                 return;
533             case 0x59:
534                 s->write_permission[i] =
535                     (s->write_permission[i] & ~0xff00) | ((value & 0x5f) << 8);
536                 return;
537             case 0x5a ... 0x5f:
538                 return;
539             /* ADDR_MATCH_i */
540             case 0x60:
541                 s->addr_match[i] = (s->addr_match[i] & ~0xff) | (value & 0xff);
542                 return;
543             case 0x61:
544                 s->addr_match[i] =
545                     (s->addr_match[i] & ~0xfe00) | ((value & 0xfe) << 8);
546                 return;
547             case 0x62:
548                 s->addr_match[i] =
549                     (s->addr_match[i] & ~0x0f0000) | ((value & 0x0f) << 16);
550                 return;
551             case 0x63 ... 0x67:
552                 return;
553             default:
554                 break;
555         }
556     
557     OMAP_BAD_REGV(s->base + addr, value);
558 }
559
560 static void omap3_l3pm_write16(void *opaque, target_phys_addr_t addr,
561                                uint32_t value)
562 {
563     omap3_l3pm_write8(opaque, addr + 0, value & 0xff);
564     omap3_l3pm_write8(opaque, addr + 1, (value >> 8) & 0xff);
565 }
566
567 static void omap3_l3pm_write32(void *opaque, target_phys_addr_t addr,
568                                uint32_t value)
569 {
570     omap3_l3pm_write16(opaque, addr + 0, value & 0xffff);
571     omap3_l3pm_write16(opaque, addr + 2, (value >> 16) & 0xffff);
572 }
573
574 static void omap3_l3pm_save_state(QEMUFile *f, void *opaque)
575 {
576     struct omap3_l3pm_s *s = (struct omap3_l3pm_s *)opaque;
577     int i;
578     
579     qemu_put_be32(f, s->error_log);
580     qemu_put_byte(f, s->control);
581     for (i = 0; i < 8; i++) {
582         qemu_put_be16(f, s->req_info_permission[i]);
583         qemu_put_be16(f, s->read_permission[i]);
584         qemu_put_be16(f, s->write_permission[i]);
585         if (i < 7)
586             qemu_put_be32(f, s->addr_match[i]);
587     }
588 }
589
590 static int omap3_l3pm_load_state(QEMUFile *f, void *opaque, int version_id)
591 {
592     struct omap3_l3pm_s *s = (struct omap3_l3pm_s *)opaque;
593     int i;
594     
595     if (version_id)
596         return -EINVAL;
597     
598     s->error_log = qemu_get_be32(f);
599     s->control = qemu_get_byte(f);
600     for (i = 0; i < 8; i++) {
601         s->req_info_permission[i] = qemu_get_be16(f);
602         s->read_permission[i] = qemu_get_be16(f);
603         s->write_permission[i] = qemu_get_be16(f);
604         if (i < 7)
605             s->addr_match[i] = qemu_get_be32(f);
606     }
607     return 0;
608 }
609
610 static void omap3_l3pm_init(struct omap3_l3pm_s *s)
611 {
612     int i;
613     
614     s->error_log = 0;
615     s->control = 0x03;
616     switch (s->base) {
617         case 0x68010000: /* PM_RT */
618             s->req_info_permission[0] = 0xffff;
619             s->req_info_permission[1] = 0;
620             for (i = 0; i < 2; i++)
621                 s->read_permission[i] = s->write_permission[i] = 0x1406;
622             s->addr_match[0] = 0x10230;
623             break;
624         case 0x68012400: /* PM_GPMC */
625             s->req_info_permission[0] = 0;
626             for (i = 3; i < 8; i++)
627                 s->req_info_permission[i] = 0xffff;
628             for (i = 0; i < 8; i++)
629                 s->read_permission[i] = s->write_permission[i] = 0x563e;
630             s->addr_match[0] = 0x00098;
631             break;
632         case 0x68012800: /* PM_OCM_RAM */
633             s->req_info_permission[0] = 0;
634             for (i = 1; i < 8; i++)
635                 s->req_info_permission[i] = 0xffff;
636             for (i = 0; i < 8; i++)
637                 s->read_permission[i] = s->write_permission[i] = 0x5f3e;
638             s->addr_match[1] = 0x0f810;
639             break;
640         case 0x68012C00: /* PM_OCM_ROM */
641             s->req_info_permission[1] = 0xffff;
642             for (i = 0; i < 2; i++) {
643                 s->read_permission[i] = 0x1002;
644                 s->write_permission[i] = 0;
645             }
646             s->addr_match[0] = 0x14028;
647             break;
648         case 0x68013000: /* PM_MAD2D */
649             s->req_info_permission[0] = 0;
650             for (i = 1; i < 8; i++)
651                 s->req_info_permission[i] = 0xffff;
652             for (i = 0; i < 8; i++)
653                 s->read_permission[i] = s->write_permission[i] = 0x5f1e;
654             break;
655         case 0x68014000: /* PM_IVA2.2 */
656             s->req_info_permission[0] = 0;
657             for (i = 1; i < 4; i++)
658                 s->req_info_permission[i] = 0xffff;
659             for (i = 0; i < 4; i++)
660                 s->read_permission[i] = s->write_permission[i] = 0x140e;
661             break;
662         default:
663             fprintf(stderr, "%s: unknown PM region (0x%08llx)\n",
664                     __FUNCTION__, s->base);
665             exit(-1);
666             break;
667     }
668
669     register_savevm("omap3_l3pm", (s->base >> 8) & 0xffff, 0,
670                     omap3_l3pm_save_state, omap3_l3pm_load_state, s);
671 }
672
673 static CPUReadMemoryFunc *omap3_l3pm_readfn[] = {
674     omap3_l3pm_read8,
675     omap3_l3pm_read16,
676     omap3_l3pm_read32,
677 };
678
679 static CPUWriteMemoryFunc *omap3_l3pm_writefn[] = {
680     omap3_l3pm_write8,
681     omap3_l3pm_write16,
682     omap3_l3pm_write32,
683 };
684
685 static uint32_t omap3_l3undef_read8(void *opaque, target_phys_addr_t addr)
686 {
687     fprintf(stderr, "%s: unsupported register at " OMAP_FMT_plx "\n",
688             __FUNCTION__, addr);
689     return 0;
690 }
691
692 static uint32_t omap3_l3undef_read16(void *opaque, target_phys_addr_t addr)
693 {
694     fprintf(stderr, "%s: unsupported register at " OMAP_FMT_plx "\n",
695             __FUNCTION__, addr);
696     return 0;
697 }
698
699 static uint32_t omap3_l3undef_read32(void *opaque, target_phys_addr_t addr)
700 {
701     fprintf(stderr, "%s: unsupported register at " OMAP_FMT_plx "\n",
702             __FUNCTION__, addr);
703     return 0;
704 }
705
706 static void omap3_l3undef_write8(void *opaque, target_phys_addr_t addr,
707                                uint32_t value)
708 {
709     fprintf(stderr, "%s: unsupported register at " OMAP_FMT_plx ", value %02x\n",
710             __FUNCTION__, addr, value);
711 }
712
713 static void omap3_l3undef_write16(void *opaque, target_phys_addr_t addr,
714                                 uint32_t value)
715 {
716     fprintf(stderr, "%s: unsupported register at " OMAP_FMT_plx ", value %04x\n",
717             __FUNCTION__, addr, value);
718 }
719
720 static void omap3_l3undef_write32(void *opaque, target_phys_addr_t addr,
721                                 uint32_t value)
722 {
723     fprintf(stderr, "%s: unsupported register at " OMAP_FMT_plx ", value %08x\n",
724             __FUNCTION__, addr, value);
725 }
726
727 static CPUReadMemoryFunc *omap3_l3undef_readfn[] = {
728     omap3_l3undef_read8,
729     omap3_l3undef_read16,
730     omap3_l3undef_read32,
731 };
732
733 static CPUWriteMemoryFunc *omap3_l3undef_writefn[] = {
734     omap3_l3undef_write8,
735     omap3_l3undef_write16,
736     omap3_l3undef_write32,
737 };
738
739 static struct omap_l3_s *omap3_l3_init(target_phys_addr_t base,
740                                        struct omap_l3_region_s *regions,
741                                        int n)
742 {
743     int i, iomemtype = 0;
744     
745     struct omap_l3_s *bus = qemu_mallocz(sizeof(*bus) + n * sizeof(*bus->region));
746     bus->region_count = n;
747     bus->base = base;
748     
749     for (i = 0; i < n; i++) {
750         switch (regions[i].type) {
751             case L3TYPE_GENERIC:
752                 /* not mapped for now, mapping will be done later by
753                    specialized code */
754                 break;
755             case L3TYPE_IA:
756                 iomemtype = cpu_register_io_memory(0, omap3_l3ia_readfn,
757                                                    omap3_l3ia_writefn,
758                                                    &bus->region[i].ia);
759                 bus->region[i].ia.base = base + regions[i].offset;
760                 omap3_l3ia_init(&bus->region[i].ia);
761                 break;
762             case L3TYPE_TA:
763                 iomemtype = cpu_register_io_memory(0, omap3_l3ta_readfn,
764                                                    omap3_l3ta_writefn,
765                                                    &bus->region[i].ta);
766                 bus->region[i].ta.base = base + regions[i].offset;
767                 omap3_l3ta_init(&bus->region[i].ta);
768                 break;
769             case L3TYPE_PM:
770                 iomemtype = cpu_register_io_memory(0, omap3_l3pm_readfn,
771                                                    omap3_l3pm_writefn,
772                                                    &bus->region[i].pm);
773                 bus->region[i].pm.base = base + regions[i].offset;
774                 omap3_l3pm_init(&bus->region[i].pm);
775                 break;
776             case L3TYPE_UNDEFINED:
777                 iomemtype = cpu_register_io_memory(0, omap3_l3undef_readfn,
778                                                    omap3_l3undef_writefn,
779                                                    &bus->region[i]);
780                 break;
781             default:
782                 fprintf(stderr, "%s: unknown L3 region type: %d\n",
783                         __FUNCTION__, regions[i].type);
784                 exit(-1);
785                 break;
786         }
787         cpu_register_physical_memory(base + regions[i].offset,
788                                      regions[i].size,
789                                      iomemtype);
790     }
791     
792     return bus;
793 }
794
795 typedef enum {
796     /* 48000000-48001FFF */
797     /* 48002000-48002FFF */ L4ID_SCM = 0,
798     /* 48003000-48003FFF */ L4ID_SCM_TA,
799     /* 48004000-48005FFF */ L4ID_CM_A,
800     /* 48006000-480067FF */ L4ID_CM_B,
801     /* 48006800-48006FFF */
802     /* 48007000-48007FFF */ L4ID_CM_TA,
803     /* 48008000-48023FFF */
804     /* 48024000-48024FFF */
805     /* 48025000-48025FFF */
806     /* 48026000-4803FFFF */
807     /* 48040000-480407FF */ L4ID_CORE_AP,
808     /* 48040800-48040FFF */ L4ID_CORE_IP,
809     /* 48041000-48041FFF */ L4ID_CORE_LA,
810     /* 48042000-4804FBFF */
811     /* 4804FC00-4804FFFF */ L4ID_DSI,
812     /* 48050000-480503FF */ L4ID_DSS,
813     /* 48050400-480507FF */ L4ID_DISPC,
814     /* 48050800-48050BFF */ L4ID_RFBI,
815     /* 48050C00-48050FFF */ L4ID_VENC,
816     /* 48051000-48051FFF */ L4ID_DSS_TA,
817     /* 48052000-48055FFF */
818     /* 48056000-48056FFF */ L4ID_SDMA,
819     /* 48057000-48057FFF */ L4ID_SDMA_TA,
820     /* 48058000-4805FFFF */
821     /* 48060000-48060FFF */ L4ID_I2C3,
822     /* 48061000-48061FFF */ L4ID_I2C3_TA,
823     /* 48062000-48062FFF */ L4ID_USBTLL,
824     /* 48063000-48063FFF */ L4ID_USBTLL_TA,
825     /* 48064000-48064FFF */ L4ID_HSUSBHOST,
826     /* 48065000-48065FFF */ L4ID_HSUSBHOST_TA,
827     /* 48066000-48069FFF */
828     /* 4806A000-4806AFFF */ L4ID_UART1,
829     /* 4806B000-4806BFFF */ L4ID_UART1_TA,
830     /* 4806C000-4806CFFF */ L4ID_UART2,
831     /* 4806D000-4806DFFF */ L4ID_UART2_TA,
832     /* 4806E000-4806FFFF */
833     /* 48070000-48070FFF */ L4ID_I2C1,
834     /* 48071000-48071FFF */ L4ID_I2C1_TA,
835     /* 48072000-48072FFF */ L4ID_I2C2,
836     /* 48073000-48073FFF */ L4ID_I2C2_TA,
837     /* 48074000-48074FFF */ L4ID_MCBSP1,
838     /* 48075000-48075FFF */ L4ID_MCBSP1_TA,
839     /* 48076000-48085FFF */
840     /* 48086000-48086FFF */ L4ID_GPTIMER10,
841     /* 48087000-48087FFF */ L4ID_GPTIMER10_TA,
842     /* 48088000-48088FFF */ L4ID_GPTIMER11,
843     /* 48089000-48089FFF */ L4ID_GPTIMER11_TA,
844     /* 4808A000-4808AFFF */
845     /* 4808B000-4808BFFF */
846     /* 4808C000-48093FFF */
847     /* 48094000-48094FFF */ L4ID_MAILBOX,
848     /* 48095000-48095FFF */ L4ID_MAILBOX_TA,
849     /* 48096000-48096FFF */ L4ID_MCBSP5,
850     /* 48097000-48097FFF */ L4ID_MCBSP5_TA,
851     /* 48098000-48098FFF */ L4ID_MCSPI1,
852     /* 48099000-48099FFF */ L4ID_MCSPI1_TA,
853     /* 4809A000-4809AFFF */ L4ID_MCSPI2,
854     /* 4809B000-4809BFFF */ L4ID_MCSPI2_TA,
855     /* 4809C000-4809CFFF */ L4ID_MMCSDIO1,
856     /* 4809D000-4809DFFF */ L4ID_MMCSDIO1_TA,
857     /* 4809E000-4809EFFF */ L4ID_MSPRO,
858     /* 4809F000-4809FFFF */ L4ID_MSPRO_TA,
859     /* 480A0000-480AAFFF */
860     /* 480AB000-480ABFFF */ L4ID_HSUSBOTG,
861     /* 480AC000-480ACFFF */ L4ID_HSUSBOTG_TA,
862     /* 480AD000-480ADFFF */ L4ID_MMCSDIO3,
863     /* 480AE000-480AEFFF */ L4ID_MMCSDIO3_TA,
864     /* 480AF000-480AFFFF */
865     /* 480B0000-480B0FFF */
866     /* 480B1000-480B1FFF */
867     /* 480B2000-480B2FFF */ L4ID_HDQ1WIRE,
868     /* 480B3000-480B2FFF */ L4ID_HDQ1WIRE_TA,
869     /* 480B4000-480B4FFF */ L4ID_MMCSDIO2,
870     /* 480B5000-480B5FFF */ L4ID_MMCSDIO2_TA,
871     /* 480B6000-480B6FFF */ L4ID_ICRMPU,
872     /* 480B7000-480B7FFF */ L4ID_ICRMPU_TA,
873     /* 480B8000-480B8FFF */ L4ID_MCSPI3,
874     /* 480B9000-480B9FFF */ L4ID_MCSPI3_TA,
875     /* 480BA000-480BAFFF */ L4ID_MCSPI4,
876     /* 480BB000-480BBFFF */ L4ID_MCSPI4_TA,
877     /* 480BC000-480BFFFF */ L4ID_CAMERAISP,
878     /* 480C0000-480C0FFF */ L4ID_CAMERAISP_TA,
879     /* 480C1000-480CCFFF */
880     /* 480CD000-480CDFFF */ L4ID_ICRMODEM,
881     /* 480CE000-480CEFFF */ L4ID_ICRMODEM_TA,
882     /* 480CF000-482FFFFF */
883     /* 48300000-48303FFF */
884     /* 48304000-48304FFF */ L4ID_GPTIMER12,
885     /* 48305000-48305FFF */ L4ID_GPTIMER12_TA,
886     /* 48306000-48307FFF */ L4ID_PRM_A,
887     /* 48308000-483087FF */ L4ID_PRM_B,
888     /* 48308800-48308FFF */
889     /* 48309000-48309FFF */ L4ID_PRM_TA,
890     /* 4830A000-4830AFFF */ L4ID_TAP,
891     /* 4830B000-4830BFFF */ L4ID_TAP_TA,
892     /* 4830C000-4830FFFF */
893     /* 48310000-48310FFF */ L4ID_GPIO1,
894     /* 48311000-48311FFF */ L4ID_GPIO1_TA,
895     /* 48312000-48313FFF */
896     /* 48314000-48314FFF */ L4ID_WDTIMER2,
897     /* 48315000-48315FFF */ L4ID_WDTIMER2_TA,
898     /* 48316000-48317FFF */
899     /* 48318000-48318FFF */ L4ID_GPTIMER1,
900     /* 48319000-48319FFF */ L4ID_GPTIMER1_TA,
901     /* 4831A000-4831FFFF */
902     /* 48320000-48320FFF */ L4ID_32KTIMER,
903     /* 48321000-48321FFF */ L4ID_32KTIMER_TA,
904     /* 48322000-48327FFF */
905     /* 48328000-483287FF */ L4ID_WAKEUP_AP,
906     /* 48328800-48328FFF */ L4ID_WAKEUP_C_IP,
907     /* 48329000-48329FFF */ L4ID_WAKEUP_LA,
908     /* 4832A000-4832A7FF */ L4ID_WAKEUP_E_IP,
909     /* 4832A800-4833FFFF */
910     /* 48340000-48340FFF */
911     /* 48341000-48FFFFFF */
912     /* 49000000-490007FF */ L4ID_PER_AP,
913     /* 49000800-49000FFF */ L4ID_PER_IP,
914     /* 49001000-49001FFF */ L4ID_PER_LA,
915     /* 49002000-4901FFFF */
916     /* 49020000-49020FFF */ L4ID_UART3,
917     /* 49021000-49021FFF */ L4ID_UART3_TA,
918     /* 49022000-49022FFF */ L4ID_MCBSP2,
919     /* 49023000-49023FFF */ L4ID_MCBSP2_TA,
920     /* 49024000-49024FFF */ L4ID_MCBSP3,
921     /* 49025000-49025FFF */ L4ID_MCBSP3_TA,
922     /* 49026000-49026FFF */ L4ID_MCBSP4,
923     /* 49027000-49027FFF */ L4ID_MCBSP4_TA,
924     /* 49028000-49028FFF */ L4ID_MCBSP2S,
925     /* 49029000-49029FFF */ L4ID_MCBSP2S_TA,
926     /* 4902A000-4902AFFF */ L4ID_MCBSP3S,
927     /* 4902B000-4902BFFF */ L4ID_MCBSP3S_TA,
928     /* 4902C000-4902FFFF */
929     /* 49030000-49030FFF */ L4ID_WDTIMER3,
930     /* 49031000-49031FFF */ L4ID_WDTIMER3_TA,
931     /* 49032000-49032FFF */ L4ID_GPTIMER2,
932     /* 49033000-49033FFF */ L4ID_GPTIMER2_TA,
933     /* 49034000-49034FFF */ L4ID_GPTIMER3,
934     /* 49035000-49035FFF */ L4ID_GPTIMER3_TA,
935     /* 49036000-49036FFF */ L4ID_GPTIMER4,
936     /* 49037000-49037FFF */ L4ID_GPTIMER4_TA,
937     /* 49038000-49038FFF */ L4ID_GPTIMER5,
938     /* 49039000-49039FFF */ L4ID_GPTIMER5_TA,
939     /* 4903A000-4903AFFF */ L4ID_GPTIMER6,
940     /* 4903B000-4903BFFF */ L4ID_GPTIMER6_TA,
941     /* 4903C000-4903CFFF */ L4ID_GPTIMER7,
942     /* 4903D000-4903DFFF */ L4ID_GPTIMER7_TA,
943     /* 4903E000-4903EFFF */ L4ID_GPTIMER8,
944     /* 4903F000-4903FFFF */ L4ID_GPTIMER8_TA,
945     /* 49040000-49040FFF */ L4ID_GPTIMER9,
946     /* 49041000-49041FFF */ L4ID_GPTIMER9_TA,
947     /* 49042000-4904FFFF */
948     /* 49050000-49050FFF */ L4ID_GPIO2,
949     /* 49051000-49051FFF */ L4ID_GPIO2_TA,
950     /* 49052000-49052FFF */ L4ID_GPIO3,
951     /* 49053000-49053FFF */ L4ID_GPIO3_TA,
952     /* 49054000-49054FFF */ L4ID_GPIO4,
953     /* 49055000-49055FFF */ L4ID_GPIO4_TA,
954     /* 49056000-49056FFF */ L4ID_GPIO5,
955     /* 49057000-49057FFF */ L4ID_GPIO5_TA,
956     /* 49058000-49058FFF */ L4ID_GPIO6,
957     /* 49059000-49059FFF */ L4ID_GPIO6_TA,
958     /* 4905A000-490FFFFF */
959     /* 54000000-54003FFF */
960     /* 54004000-54005FFF */
961     /* 54006000-540067FF */ L4ID_EMU_AP,
962     /* 54006800-54006FFF */ L4ID_EMU_IP_C,
963     /* 54007000-54007FFF */ L4ID_EMU_LA,
964     /* 54008000-540087FF */ L4ID_EMU_IP_DAP,
965     /* 54008800-5400FFFF */
966     /* 54010000-54017FFF */ L4ID_MPUEMU,
967     /* 54018000-54018FFF */ L4ID_MPUEMU_TA,
968     /* 54019000-54019FFF */ L4ID_TPIU,
969     /* 5401A000-5401AFFF */ L4ID_TPIU_TA,
970     /* 5401B000-5401BFFF */ L4ID_ETB,
971     /* 5401C000-5401CFFF */ L4ID_ETB_TA,
972     /* 5401D000-5401DFFF */ L4ID_DAPCTL,
973     /* 5401E000-5401EFFF */ L4ID_DAPCTL_TA,
974     /* 5401F000-5401FFFF */ L4ID_SDTI_TA,
975     /* 54020000-544FFFFF */
976     /* 54500000-5450FFFF */ L4ID_SDTI_CFG,
977     /* 54510000-545FFFFF */
978     /* 54600000-546FFFFF */ L4ID_SDTI,
979     /* 54700000-54705FFF */
980     /* 54706000-54707FFF */ L4ID_EMU_PRM_A,
981     /* 54708000-547087FF */ L4ID_EMU_PRM_B,
982     /* 54708800-54708FFF */
983     /* 54709000-54709FFF */ L4ID_EMU_PRM_TA,
984     /* 5470A000-5470FFFF */
985     /* 54710000-54710FFF */ L4ID_EMU_GPIO1,
986     /* 54711000-54711FFF */ L4ID_EMU_GPIO1_TA,
987     /* 54712000-54713FFF */
988     /* 54714000-54714FFF */ L4ID_EMU_WDTM2,
989     /* 54715000-54715FFF */ L4ID_EMU_WDTM2_TA,
990     /* 54716000-54717FFF */
991     /* 54718000-54718FFF */ L4ID_EMU_GPTM1,
992     /* 54719000-54719FFF */ L4ID_EMU_GPTM1_TA,
993     /* 5471A000-5471FFFF */
994     /* 54720000-54720FFF */ L4ID_EMU_32KTM,
995     /* 54721000-54721FFF */ L4ID_EMU_32KTM_TA,
996     /* 54722000-54727FFF */
997     /* 54728000-547287FF */ L4ID_EMU_WKUP_AP,
998     /* 54728800-54728FFF */ L4ID_EMU_WKUP_IPC,
999     /* 54729000-54729FFF */ L4ID_EMU_WKUP_LA,
1000     /* 5472A000-5472A7FF */ L4ID_EMU_WKUP_IPE,
1001     /* 5472A800-547FFFFF */
1002 } omap3_l4_region_id_t;
1003
1004 typedef enum {
1005     L4TYPE_GENERIC = 0, /* not mapped by default, must be mapped separately */
1006     L4TYPE_IA,          /* initiator agent */
1007     L4TYPE_TA,          /* target agent */
1008     L4TYPE_LA,          /* link register agent */
1009     L4TYPE_AP           /* address protection */
1010 } omap3_l4_region_type_t;
1011
1012 /* we reuse the "access" member for defining region type -- the original
1013    omap_l4_region_s "access" member is not used anywhere else anyway! */
1014 static struct omap_l4_region_s omap3_l4_region[] = {
1015     /* L4-Core */
1016     [L4ID_SCM         ] = {0x00002000, 0x1000, L4TYPE_GENERIC},
1017     [L4ID_SCM_TA      ] = {0x00003000, 0x1000, L4TYPE_TA},
1018     [L4ID_CM_A        ] = {0x00004000, 0x2000, L4TYPE_GENERIC},
1019     [L4ID_CM_B        ] = {0x00006000, 0x0800, L4TYPE_GENERIC},
1020     [L4ID_CM_TA       ] = {0x00007000, 0x1000, L4TYPE_TA},
1021     [L4ID_CORE_AP     ] = {0x00040000, 0x0800, L4TYPE_AP},
1022     [L4ID_CORE_IP     ] = {0x00040800, 0x0800, L4TYPE_IA},
1023     [L4ID_CORE_LA     ] = {0x00041000, 0x1000, L4TYPE_LA},
1024     [L4ID_DSI         ] = {0x0004fc00, 0x0400, L4TYPE_GENERIC},
1025     [L4ID_DSS         ] = {0x00050000, 0x0400, L4TYPE_GENERIC},
1026     [L4ID_DISPC       ] = {0x00050400, 0x0400, L4TYPE_GENERIC},
1027     [L4ID_RFBI        ] = {0x00050800, 0x0400, L4TYPE_GENERIC},
1028     [L4ID_VENC        ] = {0x00050c00, 0x0400, L4TYPE_GENERIC},
1029     [L4ID_DSS_TA      ] = {0x00051000, 0x1000, L4TYPE_TA},
1030     [L4ID_SDMA        ] = {0x00056000, 0x1000, L4TYPE_GENERIC},
1031     [L4ID_SDMA_TA     ] = {0x00057000, 0x1000, L4TYPE_TA},
1032     [L4ID_I2C3        ] = {0x00060000, 0x1000, L4TYPE_GENERIC},
1033     [L4ID_I2C3_TA     ] = {0x00061000, 0x1000, L4TYPE_TA},
1034     [L4ID_USBTLL      ] = {0x00062000, 0x1000, L4TYPE_GENERIC},
1035     [L4ID_USBTLL_TA   ] = {0x00063000, 0x1000, L4TYPE_TA},
1036     [L4ID_HSUSBHOST   ] = {0x00064000, 0x1000, L4TYPE_GENERIC},
1037     [L4ID_HSUSBHOST_TA] = {0x00065000, 0x1000, L4TYPE_TA},
1038     [L4ID_UART1       ] = {0x0006a000, 0x1000, L4TYPE_GENERIC},
1039     [L4ID_UART1_TA    ] = {0x0006b000, 0x1000, L4TYPE_TA},
1040     [L4ID_UART2       ] = {0x0006c000, 0x1000, L4TYPE_GENERIC},
1041     [L4ID_UART2_TA    ] = {0x0006d000, 0x1000, L4TYPE_TA},
1042     [L4ID_I2C1        ] = {0x00070000, 0x1000, L4TYPE_GENERIC},
1043     [L4ID_I2C1_TA     ] = {0x00071000, 0x1000, L4TYPE_TA},
1044     [L4ID_I2C2        ] = {0x00072000, 0x1000, L4TYPE_GENERIC},
1045     [L4ID_I2C2_TA     ] = {0x00073000, 0x1000, L4TYPE_TA},
1046     [L4ID_MCBSP1      ] = {0x00074000, 0x1000, L4TYPE_GENERIC},
1047     [L4ID_MCBSP1_TA   ] = {0x00075000, 0x1000, L4TYPE_TA},
1048     [L4ID_GPTIMER10   ] = {0x00086000, 0x1000, L4TYPE_GENERIC},
1049     [L4ID_GPTIMER10_TA] = {0x00087000, 0x1000, L4TYPE_TA},
1050     [L4ID_GPTIMER11   ] = {0x00088000, 0x1000, L4TYPE_GENERIC},
1051     [L4ID_GPTIMER11_TA] = {0x00089000, 0x1000, L4TYPE_TA},
1052     [L4ID_MAILBOX     ] = {0x00094000, 0x1000, L4TYPE_GENERIC},
1053     [L4ID_MAILBOX_TA  ] = {0x00095000, 0x1000, L4TYPE_TA},
1054     [L4ID_MCBSP5      ] = {0x00096000, 0x1000, L4TYPE_GENERIC},
1055     [L4ID_MCBSP5_TA   ] = {0x00097000, 0x1000, L4TYPE_TA},
1056     [L4ID_MCSPI1      ] = {0x00098000, 0x1000, L4TYPE_GENERIC},
1057     [L4ID_MCSPI1_TA   ] = {0x00099000, 0x1000, L4TYPE_TA},
1058     [L4ID_MCSPI2      ] = {0x0009a000, 0x1000, L4TYPE_GENERIC},
1059     [L4ID_MCSPI2_TA   ] = {0x0009b000, 0x1000, L4TYPE_TA},
1060     [L4ID_MMCSDIO1    ] = {0x0009c000, 0x1000, L4TYPE_GENERIC},
1061     [L4ID_MMCSDIO1_TA ] = {0x0009d000, 0x1000, L4TYPE_TA},
1062     [L4ID_MSPRO       ] = {0x0009e000, 0x1000, L4TYPE_GENERIC},
1063     [L4ID_MSPRO_TA    ] = {0x0009f000, 0x1000, L4TYPE_TA},
1064     [L4ID_HSUSBOTG    ] = {0x000ab000, 0x1000, L4TYPE_GENERIC},
1065     [L4ID_HSUSBOTG_TA ] = {0x000ac000, 0x1000, L4TYPE_TA},
1066     [L4ID_MMCSDIO3    ] = {0x000ad000, 0x1000, L4TYPE_GENERIC},
1067     [L4ID_MMCSDIO3_TA ] = {0x000ae000, 0x1000, L4TYPE_TA},
1068     [L4ID_HDQ1WIRE    ] = {0x000b2000, 0x1000, L4TYPE_GENERIC},
1069     [L4ID_HDQ1WIRE_TA ] = {0x000b3000, 0x1000, L4TYPE_TA},
1070     [L4ID_MMCSDIO2    ] = {0x000b4000, 0x1000, L4TYPE_GENERIC},
1071     [L4ID_MMCSDIO2_TA ] = {0x000b5000, 0x1000, L4TYPE_TA},
1072     [L4ID_ICRMPU      ] = {0x000b6000, 0x1000, L4TYPE_GENERIC},
1073     [L4ID_ICRMPU_TA   ] = {0x000b7000, 0x1000, L4TYPE_TA},
1074     [L4ID_MCSPI3      ] = {0x000b8000, 0x1000, L4TYPE_GENERIC},
1075     [L4ID_MCSPI3_TA   ] = {0x000b9000, 0x1000, L4TYPE_TA},
1076     [L4ID_MCSPI4      ] = {0x000ba000, 0x1000, L4TYPE_GENERIC},
1077     [L4ID_MCSPI4_TA   ] = {0x000bb000, 0x1000, L4TYPE_TA},
1078     [L4ID_CAMERAISP   ] = {0x000bc000, 0x4000, L4TYPE_GENERIC},
1079     [L4ID_CAMERAISP_TA] = {0x000c0000, 0x1000, L4TYPE_TA},
1080     [L4ID_ICRMODEM    ] = {0x000cd000, 0x1000, L4TYPE_GENERIC},
1081     [L4ID_ICRMODEM_TA ] = {0x000ce000, 0x1000, L4TYPE_TA},
1082     /* L4-Wakeup interconnect region A */
1083     [L4ID_GPTIMER12   ] = {0x00304000, 0x1000, L4TYPE_GENERIC},
1084     [L4ID_GPTIMER12_TA] = {0x00305000, 0x1000, L4TYPE_TA},
1085     [L4ID_PRM_A       ] = {0x00306000, 0x2000, L4TYPE_GENERIC},
1086     [L4ID_PRM_B       ] = {0x00308000, 0x0800, L4TYPE_GENERIC},
1087     [L4ID_PRM_TA      ] = {0x00309000, 0x1000, L4TYPE_TA},
1088     /* L4-Core */
1089     [L4ID_TAP         ] = {0x0030a000, 0x1000, L4TYPE_GENERIC},
1090     [L4ID_TAP_TA      ] = {0x0030b000, 0x1000, L4TYPE_TA},
1091     /* L4-Wakeup interconnect region B */
1092     [L4ID_GPIO1       ] = {0x00310000, 0x1000, L4TYPE_GENERIC},
1093     [L4ID_GPIO1_TA    ] = {0x00311000, 0x1000, L4TYPE_TA},
1094     [L4ID_WDTIMER2    ] = {0x00314000, 0x1000, L4TYPE_GENERIC},
1095     [L4ID_WDTIMER2_TA ] = {0x00315000, 0x1000, L4TYPE_TA},
1096     [L4ID_GPTIMER1    ] = {0x00318000, 0x1000, L4TYPE_GENERIC},
1097     [L4ID_GPTIMER1_TA ] = {0x00319000, 0x1000, L4TYPE_TA},
1098     [L4ID_32KTIMER    ] = {0x00320000, 0x1000, L4TYPE_GENERIC},
1099     [L4ID_32KTIMER_TA ] = {0x00321000, 0x1000, L4TYPE_TA},
1100     [L4ID_WAKEUP_AP   ] = {0x00328000, 0x0800, L4TYPE_AP},
1101     [L4ID_WAKEUP_C_IP ] = {0x00328800, 0x0800, L4TYPE_IA},
1102     [L4ID_WAKEUP_LA   ] = {0x00329000, 0x1000, L4TYPE_LA},
1103     [L4ID_WAKEUP_E_IP ] = {0x0032a000, 0x0800, L4TYPE_IA},
1104     /* L4-Per */
1105     [L4ID_PER_AP      ] = {0x01000000, 0x0800, L4TYPE_AP},
1106     [L4ID_PER_IP      ] = {0x01000800, 0x0800, L4TYPE_IA},
1107     [L4ID_PER_LA      ] = {0x01001000, 0x1000, L4TYPE_LA},
1108     [L4ID_UART3       ] = {0x01020000, 0x1000, L4TYPE_GENERIC},
1109     [L4ID_UART3_TA    ] = {0x01021000, 0x1000, L4TYPE_TA},
1110     [L4ID_MCBSP2      ] = {0x01022000, 0x1000, L4TYPE_GENERIC},
1111     [L4ID_MCBSP2_TA   ] = {0x01023000, 0x1000, L4TYPE_TA},
1112     [L4ID_MCBSP3      ] = {0x01024000, 0x1000, L4TYPE_GENERIC},
1113     [L4ID_MCBSP3_TA   ] = {0x01025000, 0x1000, L4TYPE_TA},
1114     [L4ID_MCBSP4      ] = {0x01026000, 0x1000, L4TYPE_GENERIC},
1115     [L4ID_MCBSP4_TA   ] = {0x01027000, 0x1000, L4TYPE_TA},
1116     [L4ID_MCBSP2S     ] = {0x01028000, 0x1000, L4TYPE_GENERIC},
1117     [L4ID_MCBSP2S_TA  ] = {0x01029000, 0x1000, L4TYPE_TA},
1118     [L4ID_MCBSP3S     ] = {0x0102a000, 0x1000, L4TYPE_GENERIC},
1119     [L4ID_MCBSP3S_TA  ] = {0x0102b000, 0x1000, L4TYPE_TA},
1120     [L4ID_WDTIMER3    ] = {0x01030000, 0x1000, L4TYPE_GENERIC},
1121     [L4ID_WDTIMER3_TA ] = {0x01031000, 0x1000, L4TYPE_TA},
1122     [L4ID_GPTIMER2    ] = {0x01032000, 0x1000, L4TYPE_GENERIC},
1123     [L4ID_GPTIMER2_TA ] = {0x01033000, 0x1000, L4TYPE_TA},
1124     [L4ID_GPTIMER3    ] = {0x01034000, 0x1000, L4TYPE_GENERIC},
1125     [L4ID_GPTIMER3_TA ] = {0x01035000, 0x1000, L4TYPE_TA},
1126     [L4ID_GPTIMER4    ] = {0x01036000, 0x1000, L4TYPE_GENERIC},
1127     [L4ID_GPTIMER4_TA ] = {0x01037000, 0x1000, L4TYPE_TA},
1128     [L4ID_GPTIMER5    ] = {0x01038000, 0x1000, L4TYPE_GENERIC},
1129     [L4ID_GPTIMER5_TA ] = {0x01039000, 0x1000, L4TYPE_TA},
1130     [L4ID_GPTIMER6    ] = {0x0103a000, 0x1000, L4TYPE_GENERIC},
1131     [L4ID_GPTIMER6_TA ] = {0x0103b000, 0x1000, L4TYPE_TA},
1132     [L4ID_GPTIMER7    ] = {0x0103c000, 0x1000, L4TYPE_GENERIC},
1133     [L4ID_GPTIMER7_TA ] = {0x0103d000, 0x1000, L4TYPE_TA},
1134     [L4ID_GPTIMER8    ] = {0x0103e000, 0x1000, L4TYPE_GENERIC},
1135     [L4ID_GPTIMER8_TA ] = {0x0103f000, 0x1000, L4TYPE_TA},
1136     [L4ID_GPTIMER9    ] = {0x01040000, 0x1000, L4TYPE_GENERIC},
1137     [L4ID_GPTIMER9_TA ] = {0x01041000, 0x1000, L4TYPE_TA},
1138     [L4ID_GPIO2       ] = {0x01050000, 0x1000, L4TYPE_GENERIC},
1139     [L4ID_GPIO2_TA    ] = {0x01051000, 0x1000, L4TYPE_TA},
1140     [L4ID_GPIO3       ] = {0x01052000, 0x1000, L4TYPE_GENERIC},
1141     [L4ID_GPIO3_TA    ] = {0x01053000, 0x1000, L4TYPE_TA},
1142     [L4ID_GPIO4       ] = {0x01054000, 0x1000, L4TYPE_GENERIC},
1143     [L4ID_GPIO4_TA    ] = {0x01055000, 0x1000, L4TYPE_TA},
1144     [L4ID_GPIO5       ] = {0x01056000, 0x1000, L4TYPE_GENERIC},
1145     [L4ID_GPIO5_TA    ] = {0x01057000, 0x1000, L4TYPE_TA},
1146     [L4ID_GPIO6       ] = {0x01058000, 0x1000, L4TYPE_GENERIC},
1147     [L4ID_GPIO6_TA    ] = {0x01059000, 0x1000, L4TYPE_TA},
1148     /* L4-Emu */
1149     [L4ID_EMU_AP      ] = {0x0c006000, 0x0800, L4TYPE_AP},
1150     [L4ID_EMU_IP_C    ] = {0x0c006800, 0x0800, L4TYPE_IA},
1151     [L4ID_EMU_LA      ] = {0x0c007000, 0x1000, L4TYPE_LA},
1152     [L4ID_EMU_IP_DAP  ] = {0x0c008000, 0x0800, L4TYPE_IA},
1153     [L4ID_MPUEMU      ] = {0x0c010000, 0x8000, L4TYPE_GENERIC},
1154     [L4ID_MPUEMU_TA   ] = {0x0c018000, 0x1000, L4TYPE_TA},
1155     [L4ID_TPIU        ] = {0x0c019000, 0x1000, L4TYPE_GENERIC},
1156     [L4ID_TPIU_TA     ] = {0x0c01a000, 0x1000, L4TYPE_TA},
1157     [L4ID_ETB         ] = {0x0c01b000, 0x1000, L4TYPE_GENERIC},
1158     [L4ID_ETB_TA      ] = {0x0c01c000, 0x1000, L4TYPE_TA},
1159     [L4ID_DAPCTL      ] = {0x0c01d000, 0x1000, L4TYPE_GENERIC},
1160     [L4ID_DAPCTL_TA   ] = {0x0c01e000, 0x1000, L4TYPE_TA},
1161     [L4ID_EMU_PRM_A   ] = {0x0c706000, 0x2000, L4TYPE_GENERIC},
1162     [L4ID_EMU_PRM_B   ] = {0x0c706800, 0x0800, L4TYPE_GENERIC},
1163     [L4ID_EMU_PRM_TA  ] = {0x0c709000, 0x1000, L4TYPE_TA},
1164     [L4ID_EMU_GPIO1   ] = {0x0c710000, 0x1000, L4TYPE_GENERIC},
1165     [L4ID_EMU_GPIO1_TA] = {0x0c711000, 0x1000, L4TYPE_TA},
1166     [L4ID_EMU_WDTM2   ] = {0x0c714000, 0x1000, L4TYPE_GENERIC},
1167     [L4ID_EMU_WDTM2_TA] = {0x0c715000, 0x1000, L4TYPE_TA},
1168     [L4ID_EMU_GPTM1   ] = {0x0c718000, 0x1000, L4TYPE_GENERIC},
1169     [L4ID_EMU_GPTM1_TA] = {0x0c719000, 0x1000, L4TYPE_TA},
1170     [L4ID_EMU_32KTM   ] = {0x0c720000, 0x1000, L4TYPE_GENERIC},
1171     [L4ID_EMU_32KTM_TA] = {0x0c721000, 0x1000, L4TYPE_TA},
1172     [L4ID_EMU_WKUP_AP ] = {0x0c728000, 0x0800, L4TYPE_AP},
1173     [L4ID_EMU_WKUP_IPC] = {0x0c728800, 0x0800, L4TYPE_IA},
1174     [L4ID_EMU_WKUP_LA ] = {0x0c729000, 0x1000, L4TYPE_LA},
1175     [L4ID_EMU_WKUP_IPE] = {0x0c72a000, 0x0800, L4TYPE_IA},
1176 };
1177
1178 typedef enum {
1179     L4A_SCM = 0,
1180     L4A_CM,
1181     L4A_PRM,
1182     L4A_GPTIMER1,
1183     L4A_GPTIMER2,
1184     L4A_GPTIMER3,
1185     L4A_GPTIMER4,
1186     L4A_GPTIMER5,
1187     L4A_GPTIMER6,
1188     L4A_GPTIMER7,
1189     L4A_GPTIMER8,
1190     L4A_GPTIMER9,
1191     L4A_GPTIMER10,
1192     L4A_GPTIMER11,
1193     L4A_GPTIMER12,
1194     L4A_WDTIMER2,
1195     L4A_32KTIMER,
1196     L4A_UART1,
1197     L4A_UART2,
1198     L4A_UART3,
1199     L4A_DSS,
1200     L4A_GPIO1,
1201     L4A_GPIO2,
1202     L4A_GPIO3,
1203     L4A_GPIO4,
1204     L4A_GPIO5,
1205     L4A_GPIO6,
1206     L4A_MMC1,
1207     L4A_MMC2,
1208     L4A_MMC3,
1209     L4A_I2C1,
1210     L4A_I2C2,
1211     L4A_I2C3,
1212     L4A_TAP,
1213     L4A_USBHS_OTG,
1214     L4A_USBHS_HOST,
1215     L4A_USBHS_TLL,
1216     L4A_MCSPI1,
1217     L4A_MCSPI2,
1218     L4A_MCSPI3,
1219     L4A_MCSPI4,
1220     L4A_SDMA
1221 } omap3_l4_agent_info_id_t;
1222
1223 struct omap3_l4_agent_info_s {
1224     omap3_l4_agent_info_id_t agent_id;
1225     omap3_l4_region_id_t     first_region_id;
1226     int                      region_count;
1227 };
1228
1229 static const struct omap3_l4_agent_info_s omap3_l4_agent_info[] = {
1230     /* L4-Core Agents */
1231     {L4A_DSS,        L4ID_DSI,       6},
1232     /* TODO: camera */
1233     {L4A_USBHS_OTG,  L4ID_HSUSBOTG,  2},
1234     {L4A_USBHS_HOST, L4ID_HSUSBHOST, 2},
1235     {L4A_USBHS_TLL,  L4ID_USBTLL,    2},
1236     {L4A_UART1,      L4ID_UART1,     2},
1237     {L4A_UART2,      L4ID_UART2,     2},
1238     {L4A_I2C1,       L4ID_I2C1,      2},
1239     {L4A_I2C2,       L4ID_I2C2,      2},
1240     {L4A_I2C3,       L4ID_I2C3,      2},
1241     /* TODO: McBSP1 */
1242     /* TODO: McBSP5 */
1243     {L4A_GPTIMER10,  L4ID_GPTIMER10, 2},
1244     {L4A_GPTIMER11,  L4ID_GPTIMER11, 2},
1245     {L4A_MCSPI1,     L4ID_MCSPI1,    2},
1246     {L4A_MCSPI2,     L4ID_MCSPI2,    2},
1247     {L4A_MMC1,       L4ID_MMCSDIO1,  2},
1248     {L4A_MMC2,       L4ID_MMCSDIO2,  2},
1249     {L4A_MMC3,       L4ID_MMCSDIO3,  2},
1250     /* TODO: HDQ/1-Wire */
1251     /* TODO: Mailbox */
1252     {L4A_MCSPI3,     L4ID_MCSPI3,    2},
1253     {L4A_MCSPI4,     L4ID_MCSPI4,    2},
1254     {L4A_SDMA,       L4ID_SDMA,      2},
1255     {L4A_CM,         L4ID_CM_A,      3},
1256     {L4A_SCM,        L4ID_SCM,       2},
1257     {L4A_TAP,        L4ID_TAP,       2},
1258     /* L4-Wakeup Agents */
1259     {L4A_GPTIMER12,  L4ID_GPTIMER12, 2},
1260     {L4A_PRM,        L4ID_PRM_A,     3},
1261     {L4A_GPIO1,      L4ID_GPIO1,     2},
1262     {L4A_WDTIMER2,   L4ID_WDTIMER2,  2},
1263     {L4A_GPTIMER1,   L4ID_GPTIMER1,  2},
1264     {L4A_32KTIMER,   L4ID_32KTIMER,  2},
1265     /* L4-Per Agents */
1266     {L4A_UART3,      L4ID_UART3,     2},
1267     /* TODO: McBSP2 */
1268     /* TODO: McBSP3 */
1269     {L4A_GPTIMER2,   L4ID_GPTIMER2,  2},
1270     {L4A_GPTIMER3,   L4ID_GPTIMER3,  2},
1271     {L4A_GPTIMER4,   L4ID_GPTIMER4,  2},
1272     {L4A_GPTIMER5,   L4ID_GPTIMER5,  2},
1273     {L4A_GPTIMER6,   L4ID_GPTIMER6,  2},
1274     {L4A_GPTIMER7,   L4ID_GPTIMER7,  2},
1275     {L4A_GPTIMER8,   L4ID_GPTIMER8,  2},
1276     {L4A_GPTIMER9,   L4ID_GPTIMER9,  2},
1277     {L4A_GPIO2,      L4ID_GPIO2,     2},
1278     {L4A_GPIO3,      L4ID_GPIO3,     2},
1279     {L4A_GPIO4,      L4ID_GPIO4,     2},
1280     {L4A_GPIO5,      L4ID_GPIO5,     2},
1281     {L4A_GPIO6,      L4ID_GPIO6,     2},
1282 };
1283
1284 static uint32_t omap3_l4ta_read(void *opaque, target_phys_addr_t addr)
1285 {
1286     struct omap_target_agent_s *s = (struct omap_target_agent_s *)opaque;
1287     
1288     switch (addr) {
1289         case 0x00: /* COMPONENT_L */
1290             return s->component;
1291         case 0x04: /* COMPONENT_H */
1292             return 0;
1293         case 0x18: /* CORE_L */
1294             return s->component;
1295         case 0x1c: /* CORE_H */
1296             return (s->component >> 16);
1297         case 0x20: /* AGENT_CONTROL_L */
1298             return s->control;
1299         case 0x24: /* AGENT_CONTROL_H */
1300             return s->control_h;
1301         case 0x28: /* AGENT_STATUS_L */
1302             return s->status;
1303         case 0x2c: /* AGENT_STATUS_H */
1304             return 0;
1305         default:
1306             break;
1307     }
1308     
1309     OMAP_BAD_REG(s->base + addr);
1310     return 0;
1311 }
1312
1313 static void omap3_l4ta_write(void *opaque, target_phys_addr_t addr,
1314                              uint32_t value)
1315 {
1316     struct omap_target_agent_s *s = (struct omap_target_agent_s *)opaque;
1317     
1318     switch (addr) {
1319         case 0x00: /* COMPONENT_L */
1320         case 0x04: /* COMPONENT_H */
1321         case 0x18: /* CORE_L */
1322         case 0x1c: /* CORE_H */
1323             OMAP_RO_REG(s->base + addr);
1324             break;
1325         case 0x20: /* AGENT_CONTROL_L */
1326             s->control = value & 0x00000701;
1327             break;
1328         case 0x24: /* AGENT_CONTROL_H */
1329             s->control_h = value & 0x100; /* TODO: shouldn't this be read-only? */
1330             break;
1331         case 0x28: /* AGENT_STATUS_L */
1332             if (value & 0x100)
1333                 s->status &= ~0x100; /* REQ_TIMEOUT */
1334             break;
1335         case 0x2c: /* AGENT_STATUS_H */
1336             /* no writable bits although the register is listed as RW */
1337             break;
1338         default:
1339             OMAP_BAD_REG(s->base + addr);
1340             break;
1341     }
1342 }
1343
1344 static void omap3_l4ta_save_state(QEMUFile *f, void *opaque)
1345 {
1346     struct omap_target_agent_s *s = (struct omap_target_agent_s *)opaque;
1347     
1348     qemu_put_be32(f, s->control);
1349     qemu_put_be32(f, s->control_h);
1350     qemu_put_be32(f, s->status);
1351 }
1352
1353 static int omap3_l4ta_load_state(QEMUFile *f, void *opaque, int version_id)
1354 {
1355     struct omap_target_agent_s *s = (struct omap_target_agent_s *)opaque;
1356     
1357     if (version_id)
1358         return -EINVAL;
1359     
1360     s->control = qemu_get_be32(f);
1361     s->control_h = qemu_get_be32(f);
1362     s->status = qemu_get_be32(f);
1363     
1364     return 0;
1365 }
1366
1367 static CPUReadMemoryFunc *omap3_l4ta_readfn[] = {
1368     omap_badwidth_read32,
1369     omap_badwidth_read32,
1370     omap3_l4ta_read,
1371 };
1372
1373 static CPUWriteMemoryFunc *omap3_l4ta_writefn[] = {
1374     omap_badwidth_write32,
1375     omap_badwidth_write32,
1376     omap3_l4ta_write,
1377 };
1378
1379 static struct omap_target_agent_s *omap3_l4ta_init(struct omap_l4_s *bus, int cs)
1380 {
1381     int i, iomemtype;
1382     struct omap_target_agent_s *ta = 0;
1383     const struct omap3_l4_agent_info_s *info = 0;
1384
1385     for (i = 0; i < bus->ta_num; i++)
1386         if (omap3_l4_agent_info[i].agent_id == cs) {
1387             ta = &bus->ta[i];
1388             info = &omap3_l4_agent_info[i];
1389             break;
1390         }
1391     if (!ta) {
1392         fprintf(stderr, "%s: invalid agent id (%i)\n", __FUNCTION__, cs);
1393         exit(-1);
1394     }
1395     if (ta->bus) {
1396         fprintf(stderr, "%s: target agent (%d) already initialized\n",
1397                 __FUNCTION__, cs);
1398         exit(-1);
1399     }
1400
1401     ta->bus = bus;
1402     ta->start = &omap3_l4_region[info->first_region_id];
1403     ta->regions = info->region_count;
1404
1405     ta->component = ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
1406     ta->status = 0x00000000;
1407     ta->control = 0x00000200;
1408
1409     for (i = 0; i < info->region_count; i++)
1410         if (omap3_l4_region[info->first_region_id + i].access == L4TYPE_TA)
1411             break;
1412     if (i >= info->region_count) {
1413         fprintf(stderr, "%s: specified agent (%d) has no TA region\n",
1414                 __FUNCTION__, cs);
1415         exit(-1);
1416     }
1417     
1418     iomemtype = l4_register_io_memory(0, omap3_l4ta_readfn,
1419                                       omap3_l4ta_writefn, ta);
1420     ta->base = omap_l4_attach(ta, i, iomemtype);
1421
1422     register_savevm("omap3_l4ta", ta->base >> 8, 0,
1423                     omap3_l4ta_save_state, omap3_l4ta_load_state, ta);
1424
1425     return ta;
1426 }
1427
1428 /* common PRM domain registers */
1429 struct omap3_prm_domain_s {
1430     uint32_t rm_rstctrl;     /* 50 */
1431     uint32_t rm_rstst;       /* 58 */
1432     uint32_t pm_wken;        /* a0 */
1433     uint32_t pm_mpugrpsel;   /* a4 */
1434     uint32_t pm_ivagrpsel;   /* a8 */
1435     uint32_t pm_wkst;        /* b0 */
1436     uint32_t pm_wkst3;       /* b8 */
1437     uint32_t pm_wkdep;       /* c8 */
1438     uint32_t pm_evgenctrl;   /* d4 */
1439     uint32_t pm_evgenontim;  /* d8 */
1440     uint32_t pm_evgenofftim; /* dc */
1441     uint32_t pm_pwstctrl;    /* e0 */
1442     uint32_t pm_pwstst;      /* e4 */
1443     uint32_t pm_prepwstst;   /* e8 */
1444     uint32_t pm_wken3;       /* f0 */
1445 };
1446
1447 struct omap3_prm_s {
1448     qemu_irq mpu_irq;
1449     qemu_irq iva_irq;
1450     struct omap_mpu_state_s *omap;
1451
1452     struct omap3_prm_domain_s iva2;
1453     struct omap3_prm_domain_s mpu;
1454     struct omap3_prm_domain_s core;
1455     struct omap3_prm_domain_s sgx;
1456     struct omap3_prm_domain_s wkup;
1457     struct omap3_prm_domain_s dss;
1458     struct omap3_prm_domain_s cam;
1459     struct omap3_prm_domain_s per;
1460     struct omap3_prm_domain_s emu;
1461     struct omap3_prm_domain_s neon;
1462     struct omap3_prm_domain_s usbhost;
1463
1464     uint32_t prm_irqstatus_iva2;
1465     uint32_t prm_irqenable_iva2;
1466     
1467     uint32_t pm_iva2grpsel3_core;
1468     uint32_t pm_mpugrpsel3_core;
1469
1470     struct {
1471         uint32_t prm_revision;
1472         uint32_t prm_sysconfig;
1473         uint32_t prm_irqstatus_mpu;
1474         uint32_t prm_irqenable_mpu;
1475     } ocp;
1476
1477     struct {
1478         uint32_t prm_clksel;
1479         uint32_t prm_clkout_ctrl;
1480     } ccr; /* clock_control_reg */
1481
1482     struct {
1483         uint32_t prm_vc_smps_sa;
1484         uint32_t prm_vc_smps_vol_ra;
1485         uint32_t prm_vc_smps_cmd_ra;
1486         uint32_t prm_vc_cmd_val_0;
1487         uint32_t prm_vc_cmd_val_1;
1488         uint32_t prm_vc_hc_conf;
1489         uint32_t prm_vc_i2c_cfg;
1490         uint32_t prm_vc_bypass_val;
1491         uint32_t prm_rstctrl;
1492         uint32_t prm_rsttimer;
1493         uint32_t prm_rstst;
1494         uint32_t prm_voltctrl;
1495         uint32_t prm_sram_pcharge;
1496         uint32_t prm_clksrc_ctrl;
1497         uint32_t prm_obs;
1498         uint32_t prm_voltsetup1;
1499         uint32_t prm_voltoffset;
1500         uint32_t prm_clksetup;
1501         uint32_t prm_polctrl;
1502         uint32_t prm_voltsetup2;
1503     } gr; /* global_reg */
1504 };
1505
1506 static void omap3_prm_int_update(struct omap3_prm_s *s)
1507 {
1508     qemu_set_irq(s->mpu_irq, s->ocp.prm_irqstatus_mpu & s->ocp.prm_irqenable_mpu);
1509     qemu_set_irq(s->iva_irq, s->prm_irqstatus_iva2 & s->prm_irqenable_iva2);
1510 }
1511
1512 static void omap3_prm_reset(struct omap3_prm_s *s)
1513 {
1514     bzero(&s->iva2, sizeof(s->iva2));
1515     s->iva2.rm_rstctrl    = 0x7;
1516     s->iva2.rm_rstst      = 0x1;
1517     s->iva2.pm_wkdep      = 0xb3;
1518     s->iva2.pm_pwstctrl   = 0xff0f07;
1519     s->iva2.pm_pwstst     = 0xff7;
1520     s->prm_irqstatus_iva2 = 0x0;
1521     s->prm_irqenable_iva2 = 0x0;
1522
1523     bzero(&s->ocp, sizeof(s->ocp));
1524     s->ocp.prm_revision      = 0x10;
1525     s->ocp.prm_sysconfig     = 0x1;
1526     
1527     bzero(&s->mpu, sizeof(s->mpu));
1528     s->mpu.rm_rstst       = 0x1;
1529     s->mpu.pm_wkdep       = 0xa5;
1530     s->mpu.pm_pwstctrl    = 0x30107;
1531     s->mpu.pm_pwstst      = 0xc7;
1532     s->mpu.pm_evgenctrl   = 0x12;
1533
1534     bzero(&s->core, sizeof(s->core));
1535     s->core.rm_rstst       = 0x1;
1536     s->core.pm_wken        = 0xc33ffe18;
1537     s->core.pm_mpugrpsel   = 0xc33ffe18;
1538     s->core.pm_ivagrpsel   = 0xc33ffe18;
1539     s->core.pm_pwstctrl    = 0xf0307;
1540     s->core.pm_pwstst      = 0xf7;
1541     s->core.pm_wken3       = 0x4;
1542     s->pm_iva2grpsel3_core = 0x4;
1543     s->pm_mpugrpsel3_core  = 0x4;
1544
1545     bzero(&s->sgx, sizeof(s->sgx));
1546     s->sgx.rm_rstst     = 0x1;
1547     s->sgx.pm_wkdep     = 0x16;
1548     s->sgx.pm_pwstctrl  = 0x30107;
1549     s->sgx.pm_pwstst    = 0x3;
1550
1551     bzero(&s->wkup, sizeof(s->wkup));
1552     s->wkup.pm_wken      = 0x3cb;
1553     s->wkup.pm_mpugrpsel = 0x3cb;
1554     s->wkup.pm_pwstst    = 0x3; /* TODO: check on real hardware */
1555
1556     bzero(&s->ccr, sizeof(s->ccr));
1557     s->ccr.prm_clksel      = 0x3; /* TRM says 0x4, but on HW this is 0x3 */
1558     s->ccr.prm_clkout_ctrl = 0x80;
1559
1560     bzero(&s->dss, sizeof(s->dss));
1561     s->dss.rm_rstst     = 0x1;
1562     s->dss.pm_wken      = 0x1;
1563     s->dss.pm_wkdep     = 0x16;
1564     s->dss.pm_pwstctrl  = 0x30107;
1565     s->dss.pm_pwstst    = 0x3;
1566
1567     bzero(&s->cam, sizeof(s->cam));
1568     s->cam.rm_rstst     = 0x1;
1569     s->cam.pm_wkdep     = 0x16;
1570     s->cam.pm_pwstctrl  = 0x30107;
1571     s->cam.pm_pwstst    = 0x3;
1572
1573     bzero(&s->per, sizeof(s->per));
1574     s->per.rm_rstst     = 0x1;
1575     s->per.pm_wken      = 0x3efff;
1576     s->per.pm_mpugrpsel = 0x3efff;
1577     s->per.pm_ivagrpsel = 0x3efff;
1578     s->per.pm_wkdep     = 0x17;
1579     s->per.pm_pwstctrl  = 0x30107;
1580     s->per.pm_pwstst    = 0x7;
1581
1582     bzero(&s->emu, sizeof(s->emu));
1583     s->emu.rm_rstst  = 0x1;
1584     s->emu.pm_pwstst = 0x13;
1585
1586     bzero(&s->gr, sizeof(s->gr));
1587     s->gr.prm_vc_i2c_cfg     = 0x18;
1588     s->gr.prm_rsttimer       = 0x1006;
1589     s->gr.prm_rstst          = 0x1;
1590     s->gr.prm_sram_pcharge   = 0x50;
1591     s->gr.prm_clksrc_ctrl    = 0x43;
1592     s->gr.prm_polctrl        = 0xa;
1593
1594     bzero(&s->neon, sizeof(s->neon));
1595     s->neon.rm_rstst     = 0x1;
1596     s->neon.pm_wkdep     = 0x2;
1597     s->neon.pm_pwstctrl  = 0x7;
1598     s->neon.pm_pwstst    = 0x3;
1599
1600     bzero(&s->usbhost, sizeof(s->usbhost));
1601     s->usbhost.rm_rstst     = 0x1;
1602     s->usbhost.pm_wken      = 0x1;
1603     s->usbhost.pm_mpugrpsel = 0x1;
1604     s->usbhost.pm_ivagrpsel = 0x1;
1605     s->usbhost.pm_wkdep     = 0x17;
1606     s->usbhost.pm_pwstctrl  = 0x30107;
1607     s->usbhost.pm_pwstst    = 0x3;
1608
1609     omap3_prm_int_update(s);
1610 }
1611
1612 static uint32_t omap3_prm_read(void *opaque, target_phys_addr_t addr)
1613 {
1614     struct omap3_prm_s *s = (struct omap3_prm_s *)opaque;
1615     struct omap3_prm_domain_s *d = 0;
1616
1617     TRACE("%04x", addr);
1618     
1619     /* handle common domain registers first - all domains may not
1620        have all common registers though but we're returning zeroes there */
1621     switch ((addr >> 8) & 0xff) {
1622         case 0x00: d = &s->iva2; break;
1623         case 0x09: d = &s->mpu; break;
1624         case 0x0a: d = &s->core; break;
1625         case 0x0b: d = &s->sgx; break;
1626         case 0x0c: d = &s->wkup; break;
1627         case 0x0e: d = &s->dss; break;
1628         case 0x0f: d = &s->cam; break;
1629         case 0x10: d = &s->per; break;
1630         case 0x11: d = &s->emu; break;
1631         case 0x13: d = &s->neon; break;
1632         case 0x14: d = &s->usbhost; break;
1633         default: break;
1634     }
1635     if (d)
1636         switch (addr & 0xff) {
1637             case 0x50: return d->rm_rstctrl;
1638             case 0x58: return d->rm_rstst;
1639             case 0xa0: return d->pm_wken;
1640             case 0xa4: return d->pm_mpugrpsel;
1641             case 0xa8: return d->pm_ivagrpsel;
1642             case 0xb0: return d->pm_wkst;
1643             case 0xb8: return d->pm_wkst3;
1644             case 0xc8: return d->pm_wkdep;
1645             case 0xd4: return d->pm_evgenctrl;
1646             case 0xd8: return d->pm_evgenontim;
1647             case 0xdc: return d->pm_evgenofftim;
1648             case 0xe0: return d->pm_pwstctrl;
1649             case 0xe4: return d->pm_pwstst;
1650             case 0xe8: return d->pm_prepwstst;
1651             case 0xf0: return d->pm_wken3;
1652             default: break;
1653         }
1654
1655     /* okay, not a common domain register so let's take a closer look */
1656     switch (addr) {
1657         case 0x00f8: return s->prm_irqstatus_iva2;
1658         case 0x00fc: return s->prm_irqenable_iva2;
1659         case 0x0804: return s->ocp.prm_revision;
1660         case 0x0814: return s->ocp.prm_sysconfig;
1661         case 0x0818: return s->ocp.prm_irqstatus_mpu;
1662         case 0x081c: return s->ocp.prm_irqenable_mpu;
1663         case 0x0af4: return s->pm_iva2grpsel3_core;
1664         case 0x0af8: return s->pm_mpugrpsel3_core;
1665         case 0x0d40: return s->ccr.prm_clksel;
1666         case 0x0d70: return s->ccr.prm_clkout_ctrl;
1667         case 0x0de4: return 0x3; /* TODO: check on real hardware */
1668         case 0x1220: return s->gr.prm_vc_smps_sa;
1669         case 0x1224: return s->gr.prm_vc_smps_vol_ra;
1670         case 0x1228: return s->gr.prm_vc_smps_cmd_ra;
1671         case 0x122c: return s->gr.prm_vc_cmd_val_0;
1672         case 0x1230: return s->gr.prm_vc_cmd_val_1;
1673         case 0x1234: return s->gr.prm_vc_hc_conf;
1674         case 0x1238: return s->gr.prm_vc_i2c_cfg;
1675         case 0x123c: return s->gr.prm_vc_bypass_val;
1676         case 0x1250: return s->gr.prm_rstctrl;
1677         case 0x1254: return s->gr.prm_rsttimer;
1678         case 0x1258: return s->gr.prm_rstst;
1679         case 0x1260: return s->gr.prm_voltctrl;
1680         case 0x1264: return s->gr.prm_sram_pcharge;     
1681         case 0x1270: return s->gr.prm_clksrc_ctrl;
1682         case 0x1280: return s->gr.prm_obs;
1683         case 0x1290: return s->gr.prm_voltsetup1;
1684         case 0x1294: return s->gr.prm_voltoffset;
1685         case 0x1298: return s->gr.prm_clksetup;
1686         case 0x129c: return s->gr.prm_polctrl;
1687         case 0x12a0: return s->gr.prm_voltsetup2;
1688         default: break;
1689     }
1690
1691     OMAP_BAD_REG(addr);
1692     return 0;
1693 }
1694
1695 static inline void omap3_prm_clksrc_ctrl_update(struct omap3_prm_s *s)
1696 {
1697     uint32_t value = s->gr.prm_clksrc_ctrl;
1698     
1699     if ((value & 0xd0) == 0x40)
1700         omap_clk_setrate(omap_findclk(s->omap, "omap3_sys_clk"), 1, 1);
1701     else if ((value & 0xd0) == 0x80)
1702         omap_clk_setrate(omap_findclk(s->omap, "omap3_sys_clk"), 2, 1);
1703 }
1704
1705 static void omap3_prm_clksel_update(struct omap3_prm_s *s)
1706 {
1707     omap_clk newparent = 0;
1708     
1709     switch (s->ccr.prm_clksel & 7) {
1710         case 0: newparent = omap_findclk(s->omap, "omap3_osc_sys_clk12"); break;
1711         case 1: newparent = omap_findclk(s->omap, "omap3_osc_sys_clk13"); break;
1712         case 2: newparent = omap_findclk(s->omap, "omap3_osc_sys_clk192"); break;
1713         case 3: newparent = omap_findclk(s->omap, "omap3_osc_sys_clk26"); break;
1714         case 4: newparent = omap_findclk(s->omap, "omap3_osc_sys_clk384"); break;
1715         case 5: newparent = omap_findclk(s->omap, "omap3_osc_sys_clk168"); break;
1716         default:
1717             fprintf(stderr, "%s: invalid sys_clk input selection (%d) - ignored\n",
1718                     __FUNCTION__, s->ccr.prm_clksel & 7);
1719             break;
1720     }
1721     if (newparent) {
1722         omap_clk_reparent(omap_findclk(s->omap, "omap3_sys_clk"), newparent);
1723         omap_clk_reparent(omap_findclk(s->omap, "omap3_sys_clkout1"), newparent);
1724     }
1725 }
1726
1727 static void omap3_prm_write(void *opaque, target_phys_addr_t addr,
1728                             uint32_t value)
1729 {
1730     struct omap3_prm_s *s = (struct omap3_prm_s *)opaque;
1731
1732     TRACE("%04x = %08x", addr, value);
1733     switch (addr) {
1734         /* IVA2_PRM */
1735         case 0x0050: s->iva2.rm_rstctrl = value & 0x7; break;
1736         case 0x0058: s->iva2.rm_rstst &= ~(value & 0x3f0f); break;
1737         case 0x00c8: s->iva2.pm_wkdep = value & 0xb3; break;
1738         case 0x00e0: s->iva2.pm_pwstctrl = 0xcff000 | (value & 0x300f0f); break;
1739         case 0x00e4: OMAP_RO_REG(addr); break;
1740         case 0x00e8: s->iva2.pm_prepwstst = value & 0xff7;
1741         case 0x00f8:
1742             s->prm_irqstatus_iva2 &= ~(value & 0x7);
1743             omap3_prm_int_update(s);
1744             break;
1745         case 0x00fc:
1746             s->prm_irqenable_iva2 = value & 0x7;
1747             omap3_prm_int_update(s);
1748             break;
1749         /* OCP_System_Reg_PRM */
1750         case 0x0804: OMAP_RO_REG(addr); break;
1751         case 0x0814: s->ocp.prm_sysconfig = value & 0x1; break;
1752         case 0x0818:
1753             s->ocp.prm_irqstatus_mpu &= ~(value & 0x03c003fd);
1754             omap3_prm_int_update(s);
1755             break;
1756         case 0x081c:
1757             s->ocp.prm_irqenable_mpu = value & 0x03c003fd;
1758             omap3_prm_int_update(s);
1759             break;
1760         /* MPU_PRM */
1761         case 0x0958: s->mpu.rm_rstst &= ~(value & 0x080f); break;
1762         case 0x09c8: s->mpu.pm_wkdep = value & 0xa5; break;
1763         case 0x09d4: s->mpu.pm_evgenctrl = value & 0x1f; break;
1764         case 0x09d8: s->mpu.pm_evgenontim = value; break;
1765         case 0x09dc: s->mpu.pm_evgenofftim = value; break;
1766         case 0x09e0: s->mpu.pm_pwstctrl = value & 0x3010f; break;
1767         case 0x09e4: OMAP_RO_REG(addr); break;
1768         case 0x09e8: s->mpu.pm_prepwstst = value & 0xc7; break;
1769         /* CORE_PRM */
1770         case 0x0a50: s->core.rm_rstctrl = value & 0x3; break; /* TODO: check if available on real hw */
1771         case 0x0a58: s->core.rm_rstst &= ~(value & 0x7); break;
1772         case 0x0aa0: s->core.pm_wken = 0x80000008 | (value & 0x433ffe10); break;
1773         case 0x0aa4: s->core.pm_mpugrpsel = 0x80000008 | (value & 0x433ffe10); break;
1774         case 0x0aa8: s->core.pm_ivagrpsel = 0x80000008 | (value & 0x433ffe10); break;
1775         case 0x0ab0: s->core.pm_wkst = value & 0x433ffe10; break;
1776         case 0x0ab8: s->core.pm_wkst3 &= ~(value & 0x4); break;
1777         case 0x0ae0: s->core.pm_pwstctrl = (value & 0x0f031f); break;
1778         case 0x0ae4: OMAP_RO_REG(addr); break;
1779         case 0x0ae8: s->core.pm_prepwstst = value & 0xf7; break;
1780         case 0x0af0: s->core.pm_wken3 = value & 0x4; break;
1781         case 0x0af4: s->pm_iva2grpsel3_core = value & 0x4; break;
1782         case 0x0af8: s->pm_mpugrpsel3_core = value & 0x4; break;
1783         /* SGX_PRM */
1784         case 0x0b58: s->sgx.rm_rstst &= ~(value & 0xf); break;
1785         case 0x0bc8: s->sgx.pm_wkdep = value & 0x16; break;
1786         case 0x0be0: s->sgx.pm_pwstctrl = 0x030104 | (value & 0x3); break;
1787         case 0x0be4: OMAP_RO_REG(addr); break;
1788         case 0x0be8: s->sgx.pm_prepwstst = value & 0x3; break;
1789         /* WKUP_PRM */
1790         case 0x0ca0: s->wkup.pm_wken = 0x2 | (value & 0x0103c9); break;
1791         case 0x0ca4: s->wkup.pm_mpugrpsel = 0x0102 | (value & 0x02c9); break;
1792         case 0x0ca8: s->wkup.pm_ivagrpsel = value & 0x03cb; break;
1793         case 0x0cb0: s->wkup.pm_wkst &= ~(value & 0x0103cb); break;
1794         /* Clock_Control_Reg_PRM */
1795         case 0x0d40: 
1796             s->ccr.prm_clksel = value & 0x7;
1797             omap3_prm_clksel_update(s);
1798             break;
1799         case 0x0d70:
1800             s->ccr.prm_clkout_ctrl = value & 0x80;
1801             omap_clk_onoff(omap_findclk(s->omap, "omap3_sys_clkout1"),
1802                            s->ccr.prm_clkout_ctrl & 0x80);
1803             break;
1804         /* DSS_PRM */
1805         case 0x0e58: s->dss.rm_rstst &= ~(value & 0xf); break;
1806         case 0x0ea0: s->dss.pm_wken = value & 1; break;
1807         case 0x0ec8: s->dss.pm_wkdep = value & 0x16; break;
1808         case 0x0ee0: s->dss.pm_pwstctrl = 0x030104 | (value & 3); break;
1809         case 0x0ee4: OMAP_RO_REG(addr); break;
1810         case 0x0ee8: s->dss.pm_prepwstst = value & 3; break;
1811         /* CAM_PRM */
1812         case 0x0f58: s->cam.rm_rstst &= (value & 0xf); break;
1813         case 0x0fc8: s->cam.pm_wkdep = value & 0x16; break;
1814         case 0x0fe0: s->cam.pm_pwstctrl = 0x030104 | (value & 3); break;
1815         case 0x0fe4: OMAP_RO_REG(addr); break;
1816         case 0x0fe8: s->cam.pm_prepwstst = value & 0x3; break;
1817         /* PER_PRM */
1818         case 0x1058: s->per.rm_rstst &= ~(value & 0xf); break;
1819         case 0x10a0: s->per.pm_wken = value & 0x03efff; break;
1820         case 0x10a4: s->per.pm_mpugrpsel = value & 0x03efff; break;
1821         case 0x10a8: s->per.pm_ivagrpsel = value & 0x03efff; break;
1822         case 0x10b0: s->per.pm_wkst &= ~(value & 0x03efff); break;
1823         case 0x10c8: s->per.pm_wkdep = value & 0x17; break;
1824         case 0x10e0: s->per.pm_pwstctrl = 0x030100 | (value & 7); break;
1825         case 0x10e4: OMAP_RO_REG(addr); break;
1826         case 0x10e8: s->per.pm_prepwstst = value & 0x7; break;
1827         /* EMU_PRM */
1828         case 0x1158: s->emu.rm_rstst &= ~(value & 7); break;
1829         case 0x11e4: OMAP_RO_REG(addr); break;
1830         /* Global_Reg_PRM */
1831         case 0x1220: s->gr.prm_vc_smps_sa = value & 0x7f007f; break;
1832         case 0x1224: s->gr.prm_vc_smps_vol_ra = value & 0xff00ff; break;
1833         case 0x1228: s->gr.prm_vc_smps_cmd_ra = value & 0xff00ff; break;
1834         case 0x122c: s->gr.prm_vc_cmd_val_0 = value; break;
1835         case 0x1230: s->gr.prm_vc_cmd_val_1 = value; break;
1836         case 0x1234: s->gr.prm_vc_hc_conf = value & 0x1f001f; break;
1837         case 0x1238: s->gr.prm_vc_i2c_cfg = value & 0x3f; break;
1838         case 0x123c: s->gr.prm_vc_bypass_val = value & 0x01ffff7f; break;
1839         case 0x1250: s->gr.prm_rstctrl = 0; break; /* TODO: resets */
1840         case 0x1254: s->gr.prm_rsttimer = value & 0x1fff; break;
1841         case 0x1258: s->gr.prm_rstst &= ~(value & 0x7fb); break;
1842         case 0x1260: s->gr.prm_voltctrl = value & 0x1f; break;
1843         case 0x1264: s->gr.prm_sram_pcharge = value & 0xff; break;
1844         case 0x1270:
1845             s->gr.prm_clksrc_ctrl = value & 0xd8; /* set osc bypass mode */ 
1846             omap3_prm_clksrc_ctrl_update(s);
1847             break;
1848         case 0x1280: OMAP_RO_REG(addr); break;
1849         case 0x1290: s->gr.prm_voltsetup1 = value; break;
1850         case 0x1294: s->gr.prm_voltoffset = value & 0xffff; break;
1851         case 0x1298: s->gr.prm_clksetup = value & 0xffff; break;
1852         case 0x129c: s->gr.prm_polctrl = value & 0xf; break;
1853         case 0x12a0: s->gr.prm_voltsetup2 = value & 0xffff; break;
1854         /* NEON_PRM */
1855         case 0x1358: s->neon.rm_rstst &= ~(value & 0xf); break;
1856         case 0x13c8: s->neon.pm_wkdep = value & 0x2; break;
1857         case 0x13e0: s->neon.pm_pwstctrl = 0x4 | (value & 3); break;
1858         case 0x13e4: OMAP_RO_REG(addr); break;
1859         case 0x13e8: s->neon.pm_prepwstst = value & 3; break;
1860         /* USBHOST_PRM */
1861         case 0x1458: s->usbhost.rm_rstst &= ~(value & 0xf); break;
1862         case 0x14a0: s->usbhost.pm_wken = value & 1; break;
1863         case 0x14a4: s->usbhost.pm_mpugrpsel = value & 1; break;
1864         case 0x14a8: s->usbhost.pm_ivagrpsel = value & 1; break;
1865         case 0x14b0: s->usbhost.pm_wkst &= ~(value & 1); break;
1866         case 0x14c8: s->usbhost.pm_wkdep = value & 0x17; break;
1867         case 0x14e0: s->usbhost.pm_pwstctrl = 0x030104 | (value & 0x13); break;
1868         case 0x14e4: OMAP_RO_REG(addr); break;
1869         case 0x14e8: s->usbhost.pm_prepwstst = value & 3; break;
1870         default:
1871             OMAP_BAD_REGV(addr, value);
1872             break;
1873     }
1874 }
1875
1876 static void omap3_prm_save_domain_state(QEMUFile *f,
1877                                         struct omap3_prm_domain_s *s)
1878 {
1879     qemu_put_be32(f, s->rm_rstctrl);
1880     qemu_put_be32(f, s->rm_rstst);
1881     qemu_put_be32(f, s->pm_wken);
1882     qemu_put_be32(f, s->pm_mpugrpsel);
1883     qemu_put_be32(f, s->pm_ivagrpsel);
1884     qemu_put_be32(f, s->pm_wkst);
1885     qemu_put_be32(f, s->pm_wkst3);
1886     qemu_put_be32(f, s->pm_wkdep);
1887     qemu_put_be32(f, s->pm_evgenctrl);
1888     qemu_put_be32(f, s->pm_evgenontim);
1889     qemu_put_be32(f, s->pm_evgenofftim);
1890     qemu_put_be32(f, s->pm_pwstctrl);
1891     qemu_put_be32(f, s->pm_pwstst);
1892     qemu_put_be32(f, s->pm_prepwstst);
1893     qemu_put_be32(f, s->pm_wken3);
1894 }
1895
1896 static void omap3_prm_load_domain_state(QEMUFile *f,
1897                                         struct omap3_prm_domain_s *s)
1898 {
1899     s->rm_rstctrl = qemu_get_be32(f);
1900     s->rm_rstst = qemu_get_be32(f);
1901     s->pm_wken = qemu_get_be32(f);
1902     s->pm_mpugrpsel = qemu_get_be32(f);
1903     s->pm_ivagrpsel = qemu_get_be32(f);
1904     s->pm_wkst = qemu_get_be32(f);
1905     s->pm_wkst3 = qemu_get_be32(f);
1906     s->pm_wkdep = qemu_get_be32(f);
1907     s->pm_evgenctrl = qemu_get_be32(f);
1908     s->pm_evgenontim = qemu_get_be32(f);
1909     s->pm_evgenofftim = qemu_get_be32(f);
1910     s->pm_pwstctrl = qemu_get_be32(f);
1911     s->pm_pwstst = qemu_get_be32(f);
1912     s->pm_prepwstst = qemu_get_be32(f);
1913     s->pm_wken3 = qemu_get_be32(f);
1914 }
1915
1916 static void omap3_prm_save_state(QEMUFile *f, void *opaque)
1917 {
1918     struct omap3_prm_s *s = (struct omap3_prm_s *)opaque;
1919     
1920     omap3_prm_save_domain_state(f, &s->iva2);
1921     omap3_prm_save_domain_state(f, &s->mpu);
1922     omap3_prm_save_domain_state(f, &s->core);
1923     omap3_prm_save_domain_state(f, &s->sgx);
1924     omap3_prm_save_domain_state(f, &s->wkup);
1925     omap3_prm_save_domain_state(f, &s->dss);
1926     omap3_prm_save_domain_state(f, &s->cam);
1927     omap3_prm_save_domain_state(f, &s->per);
1928     omap3_prm_save_domain_state(f, &s->emu);
1929     omap3_prm_save_domain_state(f, &s->neon);
1930     omap3_prm_save_domain_state(f, &s->usbhost);
1931     
1932     qemu_put_be32(f, s->prm_irqstatus_iva2);
1933     qemu_put_be32(f, s->prm_irqenable_iva2);
1934     qemu_put_be32(f, s->pm_iva2grpsel3_core);
1935     qemu_put_be32(f, s->pm_mpugrpsel3_core);
1936     
1937     qemu_put_be32(f, s->ocp.prm_revision);
1938     qemu_put_be32(f, s->ocp.prm_sysconfig);
1939     qemu_put_be32(f, s->ocp.prm_irqstatus_mpu);
1940     qemu_put_be32(f, s->ocp.prm_irqenable_mpu);
1941     
1942     qemu_put_be32(f, s->ccr.prm_clksel);
1943     qemu_put_be32(f, s->ccr.prm_clkout_ctrl);
1944     
1945     qemu_put_be32(f, s->gr.prm_vc_smps_sa);
1946     qemu_put_be32(f, s->gr.prm_vc_smps_vol_ra);
1947     qemu_put_be32(f, s->gr.prm_vc_smps_cmd_ra);
1948     qemu_put_be32(f, s->gr.prm_vc_cmd_val_0);
1949     qemu_put_be32(f, s->gr.prm_vc_cmd_val_1);
1950     qemu_put_be32(f, s->gr.prm_vc_hc_conf);
1951     qemu_put_be32(f, s->gr.prm_vc_i2c_cfg);
1952     qemu_put_be32(f, s->gr.prm_vc_bypass_val);
1953     qemu_put_be32(f, s->gr.prm_rstctrl);
1954     qemu_put_be32(f, s->gr.prm_rsttimer);
1955     qemu_put_be32(f, s->gr.prm_rstst);
1956     qemu_put_be32(f, s->gr.prm_voltctrl);
1957     qemu_put_be32(f, s->gr.prm_sram_pcharge);
1958     qemu_put_be32(f, s->gr.prm_clksrc_ctrl);
1959     qemu_put_be32(f, s->gr.prm_obs);
1960     qemu_put_be32(f, s->gr.prm_voltsetup1);
1961     qemu_put_be32(f, s->gr.prm_voltoffset);
1962     qemu_put_be32(f, s->gr.prm_clksetup);
1963     qemu_put_be32(f, s->gr.prm_polctrl);
1964     qemu_put_be32(f, s->gr.prm_voltsetup2);
1965 }
1966
1967 static int omap3_prm_load_state(QEMUFile *f, void *opaque, int version_id)
1968 {
1969     struct omap3_prm_s *s = (struct omap3_prm_s *)opaque;
1970     
1971     if (version_id)
1972         return -EINVAL;
1973     
1974     omap3_prm_load_domain_state(f, &s->iva2);
1975     omap3_prm_load_domain_state(f, &s->mpu);
1976     omap3_prm_load_domain_state(f, &s->core);
1977     omap3_prm_load_domain_state(f, &s->sgx);
1978     omap3_prm_load_domain_state(f, &s->wkup);
1979     omap3_prm_load_domain_state(f, &s->dss);
1980     omap3_prm_load_domain_state(f, &s->cam);
1981     omap3_prm_load_domain_state(f, &s->per);
1982     omap3_prm_load_domain_state(f, &s->emu);
1983     omap3_prm_load_domain_state(f, &s->neon);
1984     omap3_prm_load_domain_state(f, &s->usbhost);
1985     
1986     s->prm_irqstatus_iva2 = qemu_get_be32(f);
1987     s->prm_irqenable_iva2 = qemu_get_be32(f);
1988     s->pm_iva2grpsel3_core = qemu_get_be32(f);
1989     s->pm_mpugrpsel3_core = qemu_get_be32(f);
1990     
1991     s->ocp.prm_revision = qemu_get_be32(f);
1992     s->ocp.prm_sysconfig = qemu_get_be32(f);
1993     s->ocp.prm_irqstatus_mpu = qemu_get_be32(f);
1994     s->ocp.prm_irqenable_mpu = qemu_get_be32(f);
1995     
1996     s->ccr.prm_clksel = qemu_get_be32(f);
1997     s->ccr.prm_clkout_ctrl = qemu_get_be32(f);
1998     
1999     s->gr.prm_vc_smps_sa = qemu_get_be32(f);
2000     s->gr.prm_vc_smps_vol_ra = qemu_get_be32(f);
2001     s->gr.prm_vc_smps_cmd_ra = qemu_get_be32(f);
2002     s->gr.prm_vc_cmd_val_0 = qemu_get_be32(f);
2003     s->gr.prm_vc_cmd_val_1 = qemu_get_be32(f);
2004     s->gr.prm_vc_hc_conf = qemu_get_be32(f);
2005     s->gr.prm_vc_i2c_cfg = qemu_get_be32(f);
2006     s->gr.prm_vc_bypass_val = qemu_get_be32(f);
2007     s->gr.prm_rstctrl = qemu_get_be32(f);
2008     s->gr.prm_rsttimer = qemu_get_be32(f);
2009     s->gr.prm_rstst = qemu_get_be32(f);
2010     s->gr.prm_voltctrl = qemu_get_be32(f);
2011     s->gr.prm_sram_pcharge = qemu_get_be32(f);
2012     s->gr.prm_clksrc_ctrl = qemu_get_be32(f);
2013     s->gr.prm_obs = qemu_get_be32(f);
2014     s->gr.prm_voltsetup1 = qemu_get_be32(f);
2015     s->gr.prm_voltoffset = qemu_get_be32(f);
2016     s->gr.prm_clksetup = qemu_get_be32(f);
2017     s->gr.prm_polctrl = qemu_get_be32(f);
2018     s->gr.prm_voltsetup2 = qemu_get_be32(f);
2019     
2020     omap3_prm_int_update(s);
2021     omap3_prm_clksrc_ctrl_update(s);
2022     omap3_prm_clksel_update(s);
2023     omap_clk_onoff(omap_findclk(s->omap, "omap3_sys_clkout1"),
2024                    s->ccr.prm_clkout_ctrl & 0x80);
2025     
2026     return 0;
2027 }
2028
2029 static CPUReadMemoryFunc *omap3_prm_readfn[] = {
2030     omap_badwidth_read32,
2031     omap_badwidth_read32,
2032     omap3_prm_read,
2033 };
2034
2035 static CPUWriteMemoryFunc *omap3_prm_writefn[] = {
2036     omap_badwidth_write32,
2037     omap_badwidth_write32,
2038     omap3_prm_write,
2039 };
2040
2041 struct omap3_prm_s *omap3_prm_init(struct omap_target_agent_s *ta,
2042                                    qemu_irq mpu_int, qemu_irq iva_int,
2043                                    struct omap_mpu_state_s *mpu)
2044 {
2045     int iomemtype;
2046     struct omap3_prm_s *s = (struct omap3_prm_s *) qemu_mallocz(sizeof(*s));
2047
2048     s->mpu_irq = mpu_int;
2049     s->iva_irq = iva_int;
2050     s->omap = mpu;
2051     omap3_prm_reset(s);
2052
2053     iomemtype = l4_register_io_memory(0, omap3_prm_readfn,
2054                                       omap3_prm_writefn, s);
2055     omap_l4_attach(ta, 0, iomemtype);
2056     omap_l4_attach(ta, 1, iomemtype);
2057
2058     register_savevm("omap3_prm", -1, 0,
2059                     omap3_prm_save_state, omap3_prm_load_state, s);
2060
2061     return s;
2062 }
2063
2064 struct omap3_cm_s {
2065     qemu_irq irq[3];
2066     struct omap_mpu_state_s *mpu;
2067
2068     /* IVA2_CM: base + 0x0000 */
2069     uint32_t cm_fclken_iva2;       /* 00 */
2070     uint32_t cm_clken_pll_iva2;    /* 04 */
2071     uint32_t cm_idlest_iva2;       /* 20 */
2072     uint32_t cm_idlest_pll_iva2;   /* 24 */
2073     uint32_t cm_autoidle_pll_iva2; /* 34 */
2074     uint32_t cm_clksel1_pll_iva2;  /* 40 */
2075     uint32_t cm_clksel2_pll_iva2;  /* 44 */
2076     uint32_t cm_clkstctrl_iva2;    /* 48 */
2077     uint32_t cm_clkstst_iva2;      /* 4c */
2078
2079     /* OCP_System_Reg_CM: base + 0x0800 */
2080     uint32_t cm_revision;  /* 00 */
2081     uint32_t cm_sysconfig; /* 10 */
2082
2083     /* MPU_CM: base + 0x0900 */
2084     uint32_t cm_clken_pll_mpu;    /* 04 */
2085     uint32_t cm_idlest_mpu;       /* 20 */
2086     uint32_t cm_idlest_pll_mpu;   /* 24 */
2087     uint32_t cm_autoidle_pll_mpu; /* 34 */
2088     uint32_t cm_clksel1_pll_mpu;  /* 40 */
2089     uint32_t cm_clksel2_pll_mpu;  /* 44 */
2090     uint32_t cm_clkstctrl_mpu;    /* 48 */
2091     uint32_t cm_clkstst_mpu;      /* 4c */
2092
2093     /* CORE_CM: base + 0x0a00 */
2094     uint32_t cm_fclken1_core;   /* 0a00 */
2095     uint32_t cm_fclken3_core;   /* 0a08 */
2096     uint32_t cm_iclken1_core;   /* 0a10 */
2097     uint32_t cm_iclken2_core;   /* 0a14 */
2098     uint32_t cm_iclken3_core;   /* 0a18 */
2099     uint32_t cm_idlest1_core;   /* 0a20 */
2100     uint32_t cm_idlest2_core;   /* 0a24 */
2101     uint32_t cm_idlest3_core;   /* 0a28 */
2102     uint32_t cm_autoidle1_core; /* 0a30 */
2103     uint32_t cm_autoidle2_core; /* 0a34 */
2104     uint32_t cm_autoidle3_core; /* 0a38 */
2105     uint32_t cm_clksel_core;    /* 0a40 */
2106     uint32_t cm_clkstctrl_core; /* 0a48 */
2107     uint32_t cm_clkstst_core;   /* 0a4c */
2108
2109     /* SGX_CM: base + 0x0b00 */
2110     uint32_t cm_fclken_sgx;    /* 00 */
2111     uint32_t cm_iclken_sgx;    /* 10 */
2112     uint32_t cm_idlest_sgx;    /* 20 */
2113     uint32_t cm_clksel_sgx;    /* 40 */
2114     uint32_t cm_sleepdep_sgx;  /* 44 */
2115     uint32_t cm_clkstctrl_sgx; /* 48 */
2116     uint32_t cm_clkstst_sgx;   /* 4c */
2117
2118     /* WKUP_CM: base + 0x0c00 */
2119     uint32_t cm_fclken_wkup;   /* 00 */
2120     uint32_t cm_iclken_wkup;   /* 10 */
2121     uint32_t cm_idlest_wkup;   /* 20 */
2122     uint32_t cm_autoidle_wkup; /* 30 */
2123     uint32_t cm_clksel_wkup;   /* 40 */
2124     uint32_t cm_c48;           /* 48 */
2125
2126     /* Clock_Control_Reg_CM: base + 0x0d00 */
2127     uint32_t cm_clken_pll;     /* 00 */
2128     uint32_t cm_clken2_pll;    /* 04 */
2129     uint32_t cm_idlest_ckgen;  /* 20 */
2130     uint32_t cm_idlest2_ckgen; /* 24 */
2131     uint32_t cm_autoidle_pll;  /* 30 */
2132     uint32_t cm_autoidle2_pll; /* 34 */
2133     uint32_t cm_clksel1_pll;   /* 40 */
2134     uint32_t cm_clksel2_pll;   /* 44 */
2135     uint32_t cm_clksel3_pll;   /* 48 */
2136     uint32_t cm_clksel4_pll;   /* 4c */
2137     uint32_t cm_clksel5_pll;   /* 50 */
2138     uint32_t cm_clkout_ctrl;   /* 70 */
2139
2140     /* DSS_CM: base + 0x0e00 */
2141     uint32_t cm_fclken_dss;    /* 00 */
2142     uint32_t cm_iclken_dss;    /* 10 */
2143     uint32_t cm_idlest_dss;    /* 20 */
2144     uint32_t cm_autoidle_dss;  /* 30 */
2145     uint32_t cm_clksel_dss;    /* 40 */
2146     uint32_t cm_sleepdep_dss;  /* 44 */
2147     uint32_t cm_clkstctrl_dss; /* 48 */
2148     uint32_t cm_clkstst_dss;   /* 4c */
2149
2150    /* CAM_CM: base + 0x0f00 */
2151     uint32_t cm_fclken_cam;    /* 00 */
2152     uint32_t cm_iclken_cam;    /* 10 */
2153     uint32_t cm_idlest_cam;    /* 20 */
2154     uint32_t cm_autoidle_cam;  /* 30 */
2155     uint32_t cm_clksel_cam;    /* 40 */
2156     uint32_t cm_sleepdep_cam;  /* 44 */
2157     uint32_t cm_clkstctrl_cam; /* 48 */
2158     uint32_t cm_clkstst_cam;   /* 4c */
2159
2160     /* PER_CM: base + 0x1000 */
2161     uint32_t cm_fclken_per;    /* 00 */
2162     uint32_t cm_iclken_per;    /* 10 */
2163     uint32_t cm_idlest_per;    /* 20 */
2164     uint32_t cm_autoidle_per;  /* 30 */
2165     uint32_t cm_clksel_per;    /* 40 */
2166     uint32_t cm_sleepdep_per;  /* 44 */
2167     uint32_t cm_clkstctrl_per; /* 48 */
2168     uint32_t cm_clkstst_per;   /* 4c */
2169
2170     /* EMU_CM: base + 0x1100 */
2171     uint32_t cm_clksel1_emu;   /* 40 */
2172     uint32_t cm_clkstctrl_emu; /* 48 */
2173     uint32_t cm_clkstst_emu;   /* 4c */
2174     uint32_t cm_clksel2_emu;   /* 50 */
2175     uint32_t cm_clksel3_emu;   /* 54 */
2176
2177     /* Global_Reg_CM: base + 0x1200 */
2178     uint32_t cm_polctrl; /* 9c */
2179
2180     /* NEON_CM: base + 0x1300 */
2181     uint32_t cm_idlest_neon;    /* 20 */
2182     uint32_t cm_clkstctrl_neon; /* 48 */
2183
2184     /* USBHOST_CM: base + 0x1400 */
2185     uint32_t cm_fclken_usbhost;    /* 00 */
2186     uint32_t cm_iclken_usbhost;    /* 10 */
2187     uint32_t cm_idlest_usbhost;    /* 20 */
2188     uint32_t cm_autoidle_usbhost;  /* 30 */
2189     uint32_t cm_sleepdep_usbhost;  /* 44 */
2190     uint32_t cm_clkstctrl_usbhost; /* 48 */
2191     uint32_t cm_clkstst_usbhost;   /* 4c */
2192 };
2193
2194 static inline void omap3_cm_clksel_wkup_update(struct omap3_cm_s *s)
2195 {
2196     omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp1_fclk"),
2197                       omap_findclk(s->mpu,
2198                                    (s->cm_clksel_wkup & 1) /* CLKSEL_GPT1 */
2199                                    ? "omap3_sys_clk"
2200                                    : "omap3_32k_fclk"));
2201     omap_clk_setrate(omap_findclk(s->mpu, "omap3_rm_iclk"),
2202                      (s->cm_clksel_wkup >> 1) & 3, /* CLKSEL_RM */
2203                      1);
2204
2205     /* Tell GPTIMER to generate new clk rate */
2206     omap_gp_timer_change_clk(s->mpu->gptimer[0]);
2207
2208     TRACE("gptimer1 fclk=%lld",
2209           omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp1_fclk")));
2210
2211     /* TODO: CM_USIM_CLK */
2212 }
2213
2214 static inline void omap3_cm_iva2_update(struct omap3_cm_s *s)
2215 {
2216     uint32_t iva2_dpll_mul = ((s->cm_clksel1_pll_iva2 >> 8) & 0x7ff);
2217     uint32_t iva2_dpll_div, iva2_dpll_clkout_div, iva2_clk_src;
2218     omap_clk iva2_clk = omap_findclk(s->mpu, "omap3_iva2_clk");
2219
2220     omap_clk_onoff(iva2_clk, s->cm_fclken_iva2 & 1);
2221
2222     switch ((s->cm_clken_pll_iva2 & 0x7)) {
2223         case 0x01: /* low power stop mode */
2224         case 0x05: /* low power bypass mode */
2225             s->cm_idlest_pll_iva2 &= ~1;
2226             break;
2227         case 0x07: /* locked */
2228             if (iva2_dpll_mul < 2)
2229                 s->cm_idlest_pll_iva2 &= ~1;
2230             else
2231                 s->cm_idlest_pll_iva2 |= 1;
2232             break;
2233         default:
2234             break;
2235     }
2236     
2237     if (s->cm_idlest_pll_iva2 & 1) {
2238         iva2_dpll_div = s->cm_clksel1_pll_iva2 & 0x7f;
2239         iva2_dpll_clkout_div = s->cm_clksel2_pll_iva2 & 0x1f;
2240         omap_clk_reparent(iva2_clk, omap_findclk(s->mpu, "omap3_sys_clk"));
2241         omap_clk_setrate(iva2_clk,
2242                          (iva2_dpll_div + 1) * iva2_dpll_clkout_div,
2243                          iva2_dpll_mul);
2244     } else {
2245         /* bypass mode */
2246         iva2_clk_src = (s->cm_clksel1_pll_iva2 >> 19) & 0x07;
2247         omap_clk_reparent(iva2_clk, omap_findclk(s->mpu, "omap3_core_clk"));
2248         omap_clk_setrate(iva2_clk, iva2_clk_src, 1);
2249     }
2250 }
2251
2252 static inline void omap3_cm_mpu_update(struct omap3_cm_s *s)
2253 {
2254     uint32_t mpu_dpll_mul = ((s->cm_clksel1_pll_mpu >> 8) & 0x7ff);
2255     uint32_t mpu_dpll_div, mpu_dpll_clkout_div, mpu_clk_src;
2256     omap_clk mpu_clk = omap_findclk(s->mpu, "omap3_mpu_clk");
2257     
2258     switch ((s->cm_clken_pll_mpu & 0x7)) {
2259         case 0x05: /* low power bypass mode */
2260             s->cm_idlest_pll_mpu &= ~1;
2261             break;
2262         case 0x07: /* locked */
2263             if (mpu_dpll_mul < 2)
2264                 s->cm_idlest_pll_mpu &= ~1;
2265             else
2266                 s->cm_idlest_pll_mpu |= 1;
2267             break;
2268         default:
2269             break;
2270     }
2271     
2272     if (s->cm_idlest_pll_mpu & 1) {
2273         mpu_dpll_div = s->cm_clksel1_pll_mpu & 0x7f;
2274         mpu_dpll_clkout_div = s->cm_clksel2_pll_mpu & 0x1f;
2275         omap_clk_reparent(mpu_clk, omap_findclk(s->mpu, "omap3_sys_clk"));
2276         omap_clk_setrate(mpu_clk,
2277                          (mpu_dpll_div + 1) * mpu_dpll_clkout_div,
2278                          mpu_dpll_mul);
2279     } else {
2280         /* bypass mode */
2281         mpu_clk_src = (s->cm_clksel1_pll_mpu >> 19) & 0x07;
2282         omap_clk_reparent(mpu_clk, omap_findclk(s->mpu, "omap3_core_clk"));
2283         omap_clk_setrate(mpu_clk, mpu_clk_src, 1);
2284     }
2285 }
2286
2287 static inline void omap3_cm_dpll3_update(struct omap3_cm_s *s)
2288 {
2289     uint32_t core_dpll_mul = ((s->cm_clksel1_pll >> 16) & 0x7ff);
2290     uint32_t core_dpll_div, core_dpll_clkout_div, div_dpll3;
2291
2292     switch ((s->cm_clken_pll & 0x7)) {
2293         case 0x05: /* low power bypass */
2294         case 0x06: /* fast relock bypass */
2295             s->cm_idlest_ckgen &= ~1;
2296             break;
2297         case 0x07: /* locked */
2298             if (core_dpll_mul < 2)
2299                 s->cm_idlest_ckgen &= ~1;
2300             else
2301                 s->cm_idlest_ckgen |= 1;
2302             break;
2303         default:
2304             break;
2305     }
2306
2307     if (s->cm_idlest_ckgen & 1) {
2308         core_dpll_div = (s->cm_clksel1_pll >> 8) & 0x7f;
2309         core_dpll_clkout_div = (s->cm_clksel1_pll >> 27) & 0x1f;
2310         div_dpll3 = (s->cm_clksel1_emu >> 16) & 0x1f;
2311         
2312         if (s->cm_clksel2_emu & 0x80000) { /* OVERRIDE_ENABLE */
2313                 core_dpll_mul = (s->cm_clksel2_emu >> 8) & 0x7ff;
2314                 core_dpll_div = s->cm_clksel2_emu & 0x7f;
2315         }
2316         
2317         omap_clk_setrate(omap_findclk(s->mpu, "omap3_core_clk"),
2318                          (core_dpll_div + 1) * core_dpll_clkout_div,
2319                          core_dpll_mul);
2320         omap_clk_setrate(omap_findclk(s->mpu, "omap3_core2_clk"),
2321                          (core_dpll_div + 1) * core_dpll_clkout_div,
2322                          core_dpll_mul * 2);
2323         omap_clk_setrate(omap_findclk(s->mpu, "omap3_emu_core_alwon_clk"),
2324                          (core_dpll_div + 1) * div_dpll3,
2325                          core_dpll_mul * 2);
2326     } else {
2327         /* bypass mode */
2328         omap_clk_setrate(omap_findclk(s->mpu, "omap3_core_clk"), 1, 1);
2329         omap_clk_setrate(omap_findclk(s->mpu, "omap3_core2_clk"), 1, 1);
2330         omap_clk_setrate(omap_findclk(s->mpu, "omap3_emu_core_alwon_clk"), 1, 1);
2331     }
2332 }
2333
2334 static inline void omap3_cm_dpll4_update(struct omap3_cm_s *s)
2335 {
2336     uint32_t per_dpll_mul = ((s->cm_clksel2_pll >> 8) & 0x7ff);
2337     uint32_t per_dpll_div, div_96m, clksel_tv, clksel_dss1, clksel_cam, div_dpll4;
2338
2339     switch (((s->cm_clken_pll >> 16) & 0x7)) {
2340         case 0x01: /* lower power stop mode */
2341             s->cm_idlest_ckgen &= ~2;
2342             break;
2343         case 0x07: /* locked */
2344             if (per_dpll_mul < 2)
2345                 s->cm_idlest_ckgen &= ~2;
2346             else
2347                 s->cm_idlest_ckgen |= 2;
2348             break;
2349         default:
2350             break;
2351     }
2352
2353     if (s->cm_idlest_ckgen & 2) {
2354         per_dpll_div = s->cm_clksel2_pll & 0x7f;
2355         div_96m = s->cm_clksel3_pll & 0x1f;
2356         clksel_tv = (s->cm_clksel_dss >> 8) & 0x1f;
2357         clksel_dss1 = s->cm_clksel_dss & 0x1f;
2358         clksel_cam = s->cm_clksel_cam & 0x1f;
2359         div_dpll4 = (s->cm_clksel1_emu >> 24) & 0x1f;
2360         
2361         if (s->cm_clksel3_emu & 0x80000) { /* OVERRIDE_ENABLE */
2362                 per_dpll_mul = (s->cm_clksel3_emu >> 8) & 0x7ff;
2363                 per_dpll_div =  s->cm_clksel3_emu & 0x7f;
2364         }
2365         
2366         omap_clk_setrate(omap_findclk(s->mpu, "omap3_96m_fclk"),
2367                          (per_dpll_div + 1) * div_96m,
2368                          per_dpll_mul * 2);
2369         omap_clk_setrate(omap_findclk(s->mpu, "omap3_54m_fclk"),
2370                          (per_dpll_div + 1) * clksel_tv,
2371                          per_dpll_mul * 2);
2372         omap_clk_setrate(omap_findclk(s->mpu, "omap3_dss1_alwon_fclk"),
2373                          (per_dpll_div + 1) * clksel_dss1,
2374                          per_dpll_mul * 2);
2375         omap_clk_setrate(omap_findclk(s->mpu, "omap3_cam_mclk"),
2376                          (per_dpll_div + 1) * clksel_cam,
2377                          per_dpll_mul * 2);
2378         omap_clk_setrate(omap_findclk(s->mpu, "omap3_per_alwon_clk"),
2379                          (per_dpll_div + 1) * div_dpll4,
2380                          per_dpll_mul * 2);
2381     } else {
2382         /* bypass mode */
2383         omap_clk_setrate(omap_findclk(s->mpu, "omap3_96m_fclk"), 1, 1);
2384         omap_clk_setrate(omap_findclk(s->mpu, "omap3_54m_fclk"), 1, 1);
2385         omap_clk_setrate(omap_findclk(s->mpu, "omap3_dss1_alwon_fclk"), 1, 1);
2386         omap_clk_setrate(omap_findclk(s->mpu, "omap3_cam_mclk"), 1, 1);
2387         omap_clk_setrate(omap_findclk(s->mpu, "omap3_per_alwon_clk"), 1, 1);
2388     }
2389 }
2390
2391 static inline void omap3_cm_dpll5_update(struct omap3_cm_s *s)
2392 {
2393     uint32_t per2_dpll_mul = ((s->cm_clksel4_pll >> 8) & 0x7ff);
2394     uint32_t per2_dpll_div, div_120m;
2395
2396     switch ((s->cm_clken2_pll & 0x7)) {
2397         case 0x01: /* low power stop mode */
2398             s->cm_idlest2_ckgen &= ~1;
2399             break;
2400         case 0x07: /* locked */
2401             if (per2_dpll_mul < 2)
2402                 s->cm_idlest2_ckgen &= ~1;
2403             else
2404                 s->cm_idlest2_ckgen |= 1;
2405             break;
2406         default:
2407             break;
2408     }
2409
2410     if (s->cm_idlest2_ckgen & 1) {
2411         per2_dpll_div = s->cm_clksel4_pll & 0x7f;
2412         div_120m = s->cm_clksel5_pll & 0x1f;
2413         
2414         omap_clk_setrate(omap_findclk(s->mpu, "omap3_120m_fclk"),
2415                          (per2_dpll_div + 1) * div_120m,
2416                          per2_dpll_mul);
2417     } else {
2418         /* bypass mode */
2419         omap_clk_setrate(omap_findclk(s->mpu, "omap3_120m_fclk"), 1, 1);
2420     }
2421 }
2422
2423 static inline void omap3_cm_48m_update(struct omap3_cm_s *s)
2424 {
2425     omap_clk pclk = omap_findclk(s->mpu,
2426                                  (s->cm_clksel1_pll & 0x8) /* SOURCE_48M */
2427                                  ? "omap3_sys_altclk"
2428                                  : "omap3_96m_fclk");
2429     
2430     omap_clk_reparent(omap_findclk(s->mpu, "omap3_48m_fclk"), pclk);
2431     omap_clk_reparent(omap_findclk(s->mpu, "omap3_12m_fclk"), pclk);
2432 }
2433
2434 static inline void omap3_cm_gp10gp11_update(struct omap3_cm_s *s)
2435 {
2436     omap_clk gp10 = omap_findclk(s->mpu, "omap3_gp10_fclk");
2437     omap_clk gp11 = omap_findclk(s->mpu, "omap3_gp11_fclk");
2438     omap_clk sys  = omap_findclk(s->mpu, "omap3_sys_clk");
2439     omap_clk f32k = omap_findclk(s->mpu, "omap3_32k_fclk");
2440
2441     omap_clk_reparent(gp10, (s->cm_clksel_core & 0x40) ? sys : f32k);
2442     omap_clk_reparent(gp11, (s->cm_clksel_core & 0x80) ? sys : f32k);
2443     omap_gp_timer_change_clk(s->mpu->gptimer[9]);
2444     omap_gp_timer_change_clk(s->mpu->gptimer[10]);
2445     
2446     TRACE("gptimer10 fclk = %lld", omap_clk_getrate(gp10));
2447     TRACE("gptimer11 fclk = %lld", omap_clk_getrate(gp11));
2448 }
2449
2450 static inline void omap3_cm_per_gptimer_update(struct omap3_cm_s *s)
2451 {
2452     omap_clk sys = omap_findclk(s->mpu, "omap3_sys_clk");
2453     omap_clk f32k = omap_findclk(s->mpu, "omap3_32k_fclk");
2454     uint32_t cm_clksel_per = s->cm_clksel_per;
2455     uint32_t n;
2456     char clkname[] = "omap3_gp#_fclk";
2457
2458     for (n = 1; n < 9; n++, cm_clksel_per >>= 1) {
2459         clkname[8] = '1' + n; /* 2 - 9 */
2460         omap_clk_reparent(omap_findclk(s->mpu, clkname),
2461                           (cm_clksel_per & 1) ? sys : f32k);
2462         omap_gp_timer_change_clk(s->mpu->gptimer[n]);
2463         TRACE("gptimer%d fclk = %lld", n + 1,
2464               omap_clk_getrate(omap_findclk(s->mpu, clkname)));
2465     }
2466 }
2467
2468 static inline void omap3_cm_clkout2_update(struct omap3_cm_s *s)
2469 {
2470     omap_clk c = omap_findclk(s->mpu, "omap3_sys_clkout2");
2471         
2472     omap_clk_onoff(c, (s->cm_clkout_ctrl >> 7) & 1);
2473     switch (s->cm_clkout_ctrl & 0x3) {
2474         case 0:
2475             omap_clk_reparent(c, omap_findclk(s->mpu, "omap3_core_clk"));
2476             break;
2477         case 1:
2478             omap_clk_reparent(c, omap_findclk(s->mpu, "omap3_sys_clk"));
2479             break;
2480         case 2:
2481             omap_clk_reparent(c, omap_findclk(s->mpu, "omap3_96m_fclk"));
2482             break;
2483         case 3:
2484             omap_clk_reparent(c, omap_findclk(s->mpu, "omap3_54m_fclk"));
2485             break;
2486         default:
2487             break;
2488     }
2489     omap_clk_setrate(c, 1 << ((s->cm_clkout_ctrl >> 3) & 7), 1);
2490 }
2491
2492 static inline void omap3_cm_fclken1_core_update(struct omap3_cm_s *s)
2493 {
2494     uint32_t v = s->cm_fclken1_core;
2495     
2496     /* TODO: EN_MCBSP1,5 */
2497     omap_clk_onoff(omap_findclk(s->mpu, "omap3_gp10_fclk"),  (v >> 11) & 1);
2498     omap_clk_onoff(omap_findclk(s->mpu, "omap3_gp11_fclk"),  (v >> 12) & 1);
2499     omap_clk_onoff(omap_findclk(s->mpu, "omap3_uart1_fclk"), (v >> 13) & 1);
2500     omap_clk_onoff(omap_findclk(s->mpu, "omap3_uart2_fclk"), (v >> 14) & 1);
2501     omap_clk_onoff(omap_findclk(s->mpu, "omap3_i2c1_fclk"),  (v >> 15) & 1);
2502     omap_clk_onoff(omap_findclk(s->mpu, "omap3_i2c2_fclk"),  (v >> 16) & 1);
2503     omap_clk_onoff(omap_findclk(s->mpu, "omap3_i2c3_fclk"),  (v >> 17) & 1);
2504     /* TODO: EN_HDQ, EN_SPI1-4 */
2505     omap_clk_onoff(omap_findclk(s->mpu, "omap3_mmc1_fclk"),  (v >> 24) & 1);
2506     omap_clk_onoff(omap_findclk(s->mpu, "omap3_mmc2_fclk"),  (v >> 25) & 1);
2507     omap_clk_onoff(omap_findclk(s->mpu, "omap3_mmc3_fclk"),  (v >> 30) & 1);
2508 }
2509
2510 static inline void omap3_cm_iclken1_core_update(struct omap3_cm_s *s)
2511 {
2512     uint32_t v = s->cm_iclken1_core;
2513     
2514     /* TODO: EN_SDRC, EN_HSOTGUSB, EN_OMAPCTRL, EN_MAILBOXES, EN_MCBSP1,5 */
2515     /* TODO: EN_GPT10, EN_GPT11 */
2516     omap_clk_onoff(omap_findclk(s->mpu, "omap3_uart1_iclk"), (v >> 13) & 1);
2517     omap_clk_onoff(omap_findclk(s->mpu, "omap3_uart2_iclk"), (v >> 14) & 1);
2518     omap_clk_onoff(omap_findclk(s->mpu, "omap3_i2c1_iclk"),  (v >> 15) & 1);
2519     omap_clk_onoff(omap_findclk(s->mpu, "omap3_i2c2_iclk"),  (v >> 16) & 1);
2520     omap_clk_onoff(omap_findclk(s->mpu, "omap3_i2c3_iclk"),  (v >> 17) & 1);
2521     /* TODO: EN_HDQ, EN_SPI1-4 */
2522     omap_clk_onoff(omap_findclk(s->mpu, "omap3_mmc1_iclk"),  (v >> 24) & 1);
2523     omap_clk_onoff(omap_findclk(s->mpu, "omap3_mmc2_iclk"),  (v >> 25) & 1);
2524     omap_clk_onoff(omap_findclk(s->mpu, "omap3_mmc3_iclk"),  (v >> 30) & 1);
2525     /* set USB OTG idle if iclk is enabled and SDMA always in standby */
2526     v &= ~0x24;
2527     v |= (v & 0x10) << 1;
2528     s->cm_idlest1_core = ~v;
2529 }
2530
2531 static inline void omap3_cm_l3l4iclk_update(struct omap3_cm_s *s)
2532 {
2533     omap_clk_setrate(omap_findclk(s->mpu, "omap3_l3_iclk"),
2534                      s->cm_clksel_core & 0x3, 1);
2535     omap_clk_setrate(omap_findclk(s->mpu, "omap3_l4_iclk"),
2536                      (s->cm_clksel_core >> 2) & 0x3, 1);
2537 }
2538
2539 static void omap3_cm_reset(struct omap3_cm_s *s)
2540 {
2541     s->cm_fclken_iva2 = 0x0;
2542     s->cm_clken_pll_iva2 = 0x11;
2543     s->cm_idlest_iva2 = 0x1;
2544     s->cm_idlest_pll_iva2 = 0;
2545     s->cm_autoidle_pll_iva2 = 0x0;
2546     s->cm_clksel1_pll_iva2 = 0x80000;
2547     s->cm_clksel2_pll_iva2 = 0x1;
2548     s->cm_clkstctrl_iva2 = 0x0;
2549     s->cm_clkstst_iva2 = 0x0;
2550
2551     s->cm_revision = 0x10;
2552     s->cm_sysconfig = 0x1;
2553
2554     s->cm_clken_pll_mpu = 0x15;
2555     s->cm_idlest_mpu = 0x1;
2556     s->cm_idlest_pll_mpu = 0;
2557     s->cm_autoidle_pll_mpu = 0x0;
2558     s->cm_clksel1_pll_mpu = 0x80000;
2559     s->cm_clksel2_pll_mpu = 0x1;
2560     s->cm_clkstctrl_mpu = 0x0;
2561     s->cm_clkstst_mpu = 0x0;
2562
2563     s->cm_fclken1_core = 0x0;
2564     s->cm_fclken3_core = 0x0;
2565     s->cm_iclken1_core = 0x42;
2566     s->cm_iclken2_core = 0x0;
2567     s->cm_iclken3_core = 0x0;
2568     /*allow access to devices*/
2569     s->cm_idlest1_core = 0x0;
2570     s->cm_idlest2_core = 0x0;
2571     /*ide status =0 */
2572     s->cm_idlest3_core = 0xa; 
2573     s->cm_autoidle1_core = 0x0;
2574     s->cm_autoidle2_core = 0x0;
2575     s->cm_autoidle3_core = 0x0;
2576     s->cm_clksel_core = 0x105;
2577     s->cm_clkstctrl_core = 0x0;
2578     s->cm_clkstst_core = 0x0;
2579
2580     s->cm_fclken_sgx = 0x0;
2581     s->cm_iclken_sgx = 0x0;
2582     s->cm_idlest_sgx = 0x1;
2583     s->cm_clksel_sgx = 0x0;
2584     s->cm_sleepdep_sgx = 0x0;
2585     s->cm_clkstctrl_sgx = 0x0;
2586     s->cm_clkstst_sgx = 0x0;
2587
2588     s->cm_fclken_wkup = 0x0;
2589     s->cm_iclken_wkup = 0x0;
2590     /*assume all clock can be accessed*/
2591     s->cm_idlest_wkup = 0x0;
2592     s->cm_autoidle_wkup = 0x0;
2593     s->cm_clksel_wkup = 0x12;
2594
2595     s->cm_clken_pll = 0x110015;
2596     s->cm_clken2_pll = 0x11;
2597     s->cm_idlest_ckgen = 0x3f3c; /* FIXME: provide real clock statuses */
2598     s->cm_idlest2_ckgen = 0xa; /* FIXME: provide real clock statuses */
2599     s->cm_autoidle_pll = 0x0;
2600     s->cm_autoidle2_pll = 0x0;
2601     s->cm_clksel1_pll = 0x8000040;
2602     s->cm_clksel2_pll = 0x0;
2603     s->cm_clksel3_pll = 0x1;
2604     s->cm_clksel4_pll = 0x0;
2605     s->cm_clksel5_pll = 0x1;
2606     s->cm_clkout_ctrl = 0x3;
2607
2608
2609     s->cm_fclken_dss = 0x0;
2610     s->cm_iclken_dss = 0x0;
2611     /*dss can be accessed*/
2612     s->cm_idlest_dss = 0x0;
2613     s->cm_autoidle_dss = 0x0;
2614     s->cm_clksel_dss = 0x1010;
2615     s->cm_sleepdep_dss = 0x0;
2616     s->cm_clkstctrl_dss = 0x0;
2617     s->cm_clkstst_dss = 0x0;
2618
2619     s->cm_fclken_cam = 0x0;
2620     s->cm_iclken_cam = 0x0;
2621     s->cm_idlest_cam = 0x1;
2622     s->cm_autoidle_cam = 0x0;
2623     s->cm_clksel_cam = 0x10;
2624     s->cm_sleepdep_cam = 0x0;
2625     s->cm_clkstctrl_cam = 0x0;
2626     s->cm_clkstst_cam = 0x0;
2627
2628     s->cm_fclken_per = 0x0;
2629     s->cm_iclken_per = 0x0;
2630     //s->cm_idlest_per = 0x3ffff;
2631     s->cm_idlest_per = 0x0; //enable GPIO access
2632     s->cm_autoidle_per = 0x0;
2633     s->cm_clksel_per = 0x0;
2634     s->cm_sleepdep_per = 0x0;
2635     s->cm_clkstctrl_per = 0x0;
2636     s->cm_clkstst_per = 0x0;
2637
2638     s->cm_clksel1_emu = 0x10100a50;
2639     s->cm_clkstctrl_emu = 0x2;
2640     s->cm_clkstst_emu = 0x0;
2641     s->cm_clksel2_emu = 0x0;
2642     s->cm_clksel3_emu = 0x0;
2643
2644     s->cm_polctrl = 0x0;
2645
2646     s->cm_idlest_neon = 0x1;
2647     s->cm_clkstctrl_neon = 0x0;
2648
2649     s->cm_fclken_usbhost = 0x0;
2650     s->cm_iclken_usbhost = 0x0;
2651     s->cm_idlest_usbhost = 0x3;
2652     s->cm_autoidle_usbhost = 0x0;
2653     s->cm_sleepdep_usbhost = 0x0;
2654     s->cm_clkstctrl_usbhost = 0x0;
2655     s->cm_clkstst_usbhost = 0x0;
2656 }
2657
2658 static uint32_t omap3_cm_read(void *opaque, target_phys_addr_t addr)
2659 {
2660     struct omap3_cm_s *s = (struct omap3_cm_s *) opaque;
2661
2662     switch (addr) {
2663         /* IVA2_CM */
2664         case 0x0000: return s->cm_fclken_iva2;
2665         case 0x0004: return s->cm_clken_pll_iva2;
2666         case 0x0020: return s->cm_idlest_iva2;
2667         case 0x0024: return s->cm_idlest_pll_iva2;
2668         case 0x0034: return s->cm_autoidle_pll_iva2;
2669         case 0x0040: return s->cm_clksel1_pll_iva2;
2670         case 0x0044: return s->cm_clksel2_pll_iva2;
2671         case 0x0048: return s->cm_clkstctrl_iva2;
2672         case 0x004c: return s->cm_clkstst_iva2;
2673         /* OCP_System_Reg_CM */
2674         case 0x0800: return s->cm_revision;
2675         case 0x0810: return s->cm_sysconfig;
2676         /* MPU_CM */
2677         case 0x0904: return s->cm_clken_pll_mpu;
2678         case 0x0920: return s->cm_idlest_mpu & 0x0; /*MPU is active*/
2679         case 0x0924: return s->cm_idlest_pll_mpu;
2680         case 0x0934: return s->cm_autoidle_pll_mpu;
2681         case 0x0940: return s->cm_clksel1_pll_mpu;
2682         case 0x0944: return s->cm_clksel2_pll_mpu;
2683         case 0x0948: return s->cm_clkstctrl_mpu;
2684         case 0x094c: return s->cm_clkstst_mpu;
2685         /* CORE_CM */
2686         case 0x0a00: return s->cm_fclken1_core;
2687         case 0x0a08: return s->cm_fclken3_core;
2688         case 0x0a10: return s->cm_iclken1_core;
2689         case 0x0a14: return s->cm_iclken2_core;
2690         case 0x0a20: return s->cm_idlest1_core;
2691         case 0x0a24: return s->cm_idlest2_core;
2692         case 0x0a28: return s->cm_idlest3_core;
2693         case 0x0a30: return s->cm_autoidle1_core;
2694         case 0x0a34: return s->cm_autoidle2_core;
2695         case 0x0a38: return s->cm_autoidle3_core;
2696         case 0x0a40: return s->cm_clksel_core;
2697         case 0x0a48: return s->cm_clkstctrl_core;
2698         case 0x0a4c: return s->cm_clkstst_core;
2699         /* SGX_CM */
2700         case 0x0b00: return s->cm_fclken_sgx;
2701         case 0x0b10: return s->cm_iclken_sgx;
2702         case 0x0b20: return s->cm_idlest_sgx & 0x0;
2703         case 0x0b40: return s->cm_clksel_sgx;
2704         case 0x0b48: return s->cm_clkstctrl_sgx;
2705         case 0x0b4c: return s->cm_clkstst_sgx;
2706         /* WKUP_CM */
2707         case 0x0c00: return s->cm_fclken_wkup;
2708         case 0x0c10: return s->cm_iclken_wkup;
2709         case 0x0c20: return 0; /* TODO: Check if the timer can be accessed. */
2710         case 0x0c30: return s->cm_idlest_wkup;
2711         case 0x0c40: return s->cm_clksel_wkup;
2712         case 0x0c48: return s->cm_c48;
2713         /* Clock_Control_Reg_CM */
2714         case 0x0d00: return s->cm_clken_pll;
2715         case 0x0d04: return s->cm_clken2_pll;
2716         case 0x0d20: return s->cm_idlest_ckgen;
2717         case 0x0d24: return s->cm_idlest2_ckgen;
2718         case 0x0d30: return s->cm_autoidle_pll;
2719         case 0x0d34: return s->cm_autoidle2_pll;
2720         case 0x0d40: return s->cm_clksel1_pll;
2721         case 0x0d44: return s->cm_clksel2_pll;
2722         case 0x0d48: return s->cm_clksel3_pll;
2723         case 0x0d4c: return s->cm_clksel4_pll;
2724         case 0x0d50: return s->cm_clksel5_pll;
2725         case 0x0d70: return s->cm_clkout_ctrl;
2726         /* DSS_CM */
2727         case 0x0e00: return s->cm_fclken_dss;
2728         case 0x0e10: return s->cm_iclken_dss;
2729         case 0x0e20: return s->cm_idlest_dss;
2730         case 0x0e30: return s->cm_autoidle_dss;
2731         case 0x0e40: return s->cm_clksel_dss;
2732         case 0x0e44: return s->cm_sleepdep_dss;
2733         case 0x0e48: return s->cm_clkstctrl_dss;
2734         case 0x0e4c: return s->cm_clkstst_dss;
2735         /* CAM_CM */
2736         case 0x0f00: return s->cm_fclken_cam;
2737         case 0x0f10: return s->cm_iclken_cam;
2738         case 0x0f20: return s->cm_idlest_cam & 0x0;
2739         case 0x0f30: return s->cm_autoidle_cam;
2740         case 0x0f40: return s->cm_clksel_cam;
2741         case 0x0f44: return s->cm_sleepdep_cam;
2742         case 0x0f48: return s->cm_clkstctrl_cam;
2743         case 0x0f4c: return s->cm_clkstst_cam;
2744         /* PER_CM */
2745         case 0x1000: return s->cm_fclken_per;
2746         case 0x1010: return s->cm_iclken_per;
2747         case 0x1020: return s->cm_idlest_per ;
2748         case 0x1030: return s->cm_autoidle_per;
2749         case 0x1040: return s->cm_clksel_per;
2750         case 0x1044: return s->cm_sleepdep_per;
2751         case 0x1048: return s->cm_clkstctrl_per;
2752         case 0x104c: return s->cm_clkstst_per;
2753         /* EMU_CM */
2754         case 0x1140: return s->cm_clksel1_emu;
2755         case 0x1148: return s->cm_clkstctrl_emu;
2756         case 0x114c: return s->cm_clkstst_emu & 0x0;
2757         case 0x1150: return s->cm_clksel2_emu;
2758         case 0x1154: return s->cm_clksel3_emu;
2759         /* Global_Reg_CM */
2760         case 0x129c: return s->cm_polctrl;
2761         /* NEON_CM */
2762         case 0x1320: return s->cm_idlest_neon & 0x0;
2763         case 0x1348: return s->cm_clkstctrl_neon;
2764         /* USBHOST_CM */
2765         case 0x1400: return s->cm_fclken_usbhost;
2766         case 0x1410: return s->cm_iclken_usbhost;
2767         case 0x1420: return s->cm_idlest_usbhost & 0x0;
2768         case 0x1430: return s->cm_autoidle_usbhost;
2769         case 0x1444: return s->cm_sleepdep_usbhost;
2770         case 0x1448: return s->cm_clkstctrl_usbhost;
2771         case 0x144c: return s->cm_clkstst_usbhost;
2772         /* unknown */
2773         default: break;
2774     }
2775     OMAP_BAD_REG(addr);
2776     return 0;
2777 }
2778
2779 static void omap3_cm_write(void *opaque,
2780                            target_phys_addr_t addr,
2781                            uint32_t value)
2782 {
2783     struct omap3_cm_s *s = (struct omap3_cm_s *)opaque;
2784
2785     switch (addr) {
2786         case 0x0020:
2787         case 0x0024:
2788         case 0x004c:
2789         case 0x0800:
2790         case 0x0920:
2791         case 0x0924:
2792         case 0x094c:
2793         case 0x0a20:
2794         case 0x0a24:
2795         case 0x0a28:
2796         case 0x0a4c:
2797         case 0x0b20:
2798         case 0x0b4c:
2799         case 0x0c20:
2800         case 0x0d20:
2801         case 0x0d24:
2802         case 0x0e20:
2803         case 0x0e4c:
2804         case 0x0f20:
2805         case 0x0f4c:
2806         case 0x1020:
2807         case 0x104c:
2808         case 0x114c:
2809         case 0x1320:
2810         case 0x1420:
2811         case 0x144c:
2812             OMAP_RO_REGV(addr, value);
2813             break;
2814         /* IVA2_CM */
2815         case 0x0000:
2816             s->cm_fclken_iva2 = value & 0x1;
2817             omap3_cm_iva2_update(s);
2818             break;
2819         case 0x0004: 
2820             s->cm_clken_pll_iva2 = value & 0x7ff;
2821             omap3_cm_iva2_update(s);
2822             break;
2823         case 0x0034:
2824             s->cm_autoidle_pll_iva2 = value & 0x7;
2825             break;
2826         case 0x0040:
2827             s->cm_clksel1_pll_iva2 = value & 0x3fff7f;
2828             omap3_cm_iva2_update(s);
2829             break;
2830         case 0x0044:
2831             s->cm_clksel2_pll_iva2 = value & 0x1f;
2832             omap3_cm_iva2_update(s);
2833             break;
2834         case 0x0048:
2835             s->cm_clkstctrl_iva2 = value & 0x3;
2836             break;
2837         /* OCP_System_Reg_CM */
2838         case 0x0810:
2839             s->cm_sysconfig = value & 0x1;
2840             break;
2841         /* MPU_CM */
2842         case 0x0904:
2843             s->cm_clken_pll_mpu = value & 0x7ff;
2844             omap3_cm_mpu_update(s);
2845             break;
2846         case 0x0934:
2847             s->cm_autoidle_pll_mpu = value & 0x7;
2848             break;
2849         case 0x0940:
2850             s->cm_clksel1_pll_mpu = value & 0x3fff7f;
2851             omap3_cm_mpu_update(s);
2852             break;
2853         case 0x0944:
2854             s->cm_clksel2_pll_mpu = value & 0x1f;
2855             omap3_cm_mpu_update(s);
2856             break;
2857         case 0x0948:
2858             s->cm_clkstctrl_mpu = value & 0x3;
2859             break;
2860         /* CORE_CM */
2861         case 0xa00:
2862             s->cm_fclken1_core = value & 0x43fffe00;
2863             omap3_cm_fclken1_core_update(s);
2864             break;
2865         case 0xa08:
2866             s->cm_fclken3_core = value & 0x7;
2867             /* TODO: EN_USBTLL, EN_TS */
2868             break;
2869         case 0xa10:
2870             s->cm_iclken1_core = value & 0x637ffed2;
2871             omap3_cm_iclken1_core_update(s);
2872             break;
2873         case 0xa14:
2874             s->cm_iclken2_core = value & 0x1f;
2875             break;
2876         case 0xa18:
2877             s->cm_iclken3_core = value & 0x4;
2878             s->cm_idlest3_core = 0xd & ~(s->cm_iclken3_core & 4);
2879             break;
2880         case 0xa30:
2881             s->cm_autoidle1_core = value & 0x7ffffed0;
2882             break;
2883         case 0xa34:
2884             s->cm_autoidle2_core = value & 0x1f;
2885             break;
2886         case 0xa38:
2887             s->cm_autoidle3_core = value & 0x2;
2888             break;
2889         case 0xa40:
2890             s->cm_clksel_core = (value & 0xff) | 0x100;
2891             omap3_cm_gp10gp11_update(s);
2892             omap3_cm_l3l4iclk_update(s);
2893             break;
2894         case 0xa48:
2895             s->cm_clkstctrl_core = value & 0xf;
2896             break;
2897         /* SGX_CM */
2898         case 0xb00: s->cm_fclken_sgx = value & 0x2; break;
2899         case 0xb10: s->cm_iclken_sgx = value & 0x1; break;
2900         case 0xb40: s->cm_clksel_sgx = value; break; /* TODO: SGX clock */
2901         case 0xb44: s->cm_sleepdep_sgx = value &0x2; break;
2902         case 0xb48: s->cm_clkstctrl_sgx = value & 0x3; break;
2903         /* WKUP_CM */
2904         case 0xc00:
2905             s->cm_fclken_wkup = value & 0x2e9;
2906             omap_clk_onoff(omap_findclk(s->mpu, "omap3_gp1_fclk"),
2907                            s->cm_fclken_wkup & 1);
2908             /* TODO: EN_GPIO1 */
2909             /* TODO: EN_WDT2 */
2910             break;
2911         case 0xc10:
2912             s->cm_iclken_wkup = value & 0x23f;
2913             omap_clk_onoff(omap_findclk(s->mpu, "omap3_wkup_l4_iclk"),
2914                            s->cm_iclken_wkup ? 1 : 0);
2915             break;
2916         case 0xc30: s->cm_autoidle_wkup = value & 0x23f; break;
2917         case 0xc40:
2918             s->cm_clksel_wkup = value & 0x7f;
2919             omap3_cm_clksel_wkup_update(s);
2920             break;
2921         /* Clock_Control_Reg_CM */
2922         case 0xd00:
2923             s->cm_clken_pll = value & 0xffff17ff;
2924             omap3_cm_dpll3_update(s);
2925             omap3_cm_dpll4_update(s);
2926             break;
2927         case 0xd04:
2928             s->cm_clken2_pll = value & 0x7ff;
2929             omap3_cm_dpll5_update(s);
2930             break;
2931         case 0xd30: s->cm_autoidle_pll = value & 0x3f; break;
2932         case 0xd34: s->cm_autoidle2_pll = value & 0x7; break;
2933         case 0xd40:
2934             s->cm_clksel1_pll = value & 0xffffbffc;
2935             omap3_cm_dpll3_update(s);
2936             omap3_cm_48m_update(s);
2937             /* TODO: 96m and 54m update */
2938             break;
2939         case 0xd44:
2940             s->cm_clksel2_pll = value & 0x7ff7f;
2941             omap3_cm_dpll4_update(s);
2942             break;
2943         case 0xd48:
2944             s->cm_clksel3_pll = value & 0x1f;
2945             omap3_cm_dpll4_update(s);
2946             break;
2947         case 0xd4c:
2948             s->cm_clksel4_pll = value & 0x7ff7f;
2949             omap3_cm_dpll5_update(s);
2950             break;
2951         case 0xd50:
2952             s->cm_clksel5_pll = value & 0x1f;
2953             omap3_cm_dpll5_update(s);
2954             break;
2955         case 0xd70:
2956             s->cm_clkout_ctrl = value & 0xbb;
2957             omap3_cm_clkout2_update(s);
2958             break;
2959         /* DSS_CM */
2960         case 0xe00: s->cm_fclken_dss = value & 0x7; break;
2961         case 0xe10: s->cm_iclken_dss = value & 0x1; break;
2962         case 0xe30: s->cm_autoidle_dss = value & 0x1; break;
2963         case 0xe40:
2964             s->cm_clksel_dss = value & 0x1f1f;
2965             omap3_cm_dpll4_update(s);
2966             break;
2967         case 0xe44: s->cm_sleepdep_dss = value & 0x7; break;
2968         case 0xe48: s->cm_clkstctrl_dss = value & 0x3; break;
2969         /* CAM_CM */
2970         case 0xf00: s->cm_fclken_cam = value & 0x3; break;
2971         case 0xf10: s->cm_iclken_cam = value & 0x1; break;
2972         case 0xf30: s->cm_autoidle_cam = value & 0x1; break;
2973         case 0xf40:
2974             s->cm_clksel_cam = value & 0x1f;
2975             omap3_cm_dpll4_update(s);
2976             break;
2977         case 0xf44: s->cm_sleepdep_cam = value & 0x2; break;
2978         case 0xf48: s->cm_clkstctrl_cam = value & 0x3; break;
2979         /* PER_CM */
2980         case 0x1000: s->cm_fclken_per = value & 0x3ffff; break;
2981         case 0x1010: s->cm_iclken_per = value & 0x3ffff; break;
2982         case 0x1030: s->cm_autoidle_per = value &0x3ffff; break;
2983         case 0x1040:
2984             s->cm_clksel_per = value & 0xff;
2985             omap3_cm_per_gptimer_update(s);
2986             break;
2987         case 0x1044: s->cm_sleepdep_per = value & 0x6; break;
2988         case 0x1048: s->cm_clkstctrl_per = value &0x7; break;
2989         /* EMU_CM */
2990         case 0x1140:
2991             s->cm_clksel1_emu = value & 0x1f1f3fff;
2992             omap3_cm_dpll3_update(s);
2993             omap3_cm_dpll4_update(s);
2994             break;
2995         case 0x1148: s->cm_clkstctrl_emu = value & 0x3; break;
2996         case 0x1150:
2997             s->cm_clksel2_emu = value & 0xfff7f;
2998             omap3_cm_dpll3_update(s);
2999             break;
3000         case 0x1154:
3001             s->cm_clksel3_emu = value & 0xfff7f;
3002             omap3_cm_dpll4_update(s);
3003             break;
3004         /* Global_Reg_CM */
3005         case 0x129c: s->cm_polctrl = value & 0x1; break;
3006         /* NEON_CM */
3007         case 0x1348: s->cm_clkstctrl_neon = value & 0x3; break;
3008         /* USBHOST_CM */
3009         case 0x1400: s->cm_fclken_usbhost = value & 0x3; break;
3010         case 0x1410: s->cm_iclken_usbhost = value & 0x1; break;
3011         case 0x1430: s->cm_autoidle_usbhost = value & 0x1; break;
3012         case 0x1444: s->cm_sleepdep_usbhost = value & 0x6; break;
3013         case 0x1448: s->cm_clkstctrl_usbhost = value & 0x3; break;
3014         /* unknown */
3015         default:
3016             OMAP_BAD_REGV(addr, value);
3017             break;
3018     }
3019 }
3020
3021 static void omap3_cm_save_state(QEMUFile *f, void *opaque)
3022 {
3023     struct omap3_cm_s *s = (struct omap3_cm_s *)opaque;
3024     
3025     qemu_put_be32(f, s->cm_fclken_iva2);
3026     qemu_put_be32(f, s->cm_clken_pll_iva2);
3027     qemu_put_be32(f, s->cm_idlest_iva2);
3028     qemu_put_be32(f, s->cm_idlest_pll_iva2);
3029     qemu_put_be32(f, s->cm_autoidle_pll_iva2);
3030     qemu_put_be32(f, s->cm_clksel1_pll_iva2);
3031     qemu_put_be32(f, s->cm_clksel2_pll_iva2);
3032     qemu_put_be32(f, s->cm_clkstctrl_iva2);
3033     qemu_put_be32(f, s->cm_clkstst_iva2);
3034     
3035     qemu_put_be32(f, s->cm_revision);
3036     qemu_put_be32(f, s->cm_sysconfig);
3037     
3038     qemu_put_be32(f, s->cm_clken_pll_mpu);
3039     qemu_put_be32(f, s->cm_idlest_mpu);
3040     qemu_put_be32(f, s->cm_idlest_pll_mpu);
3041     qemu_put_be32(f, s->cm_autoidle_pll_mpu);
3042     qemu_put_be32(f, s->cm_clksel1_pll_mpu);
3043     qemu_put_be32(f, s->cm_clksel2_pll_mpu);
3044     qemu_put_be32(f, s->cm_clkstctrl_mpu);
3045     qemu_put_be32(f, s->cm_clkstst_mpu);
3046     
3047     qemu_put_be32(f, s->cm_fclken1_core);
3048     qemu_put_be32(f, s->cm_fclken3_core);
3049     qemu_put_be32(f, s->cm_iclken1_core);
3050     qemu_put_be32(f, s->cm_iclken2_core);
3051     qemu_put_be32(f, s->cm_iclken3_core);
3052     qemu_put_be32(f, s->cm_idlest1_core);
3053     qemu_put_be32(f, s->cm_idlest2_core);
3054     qemu_put_be32(f, s->cm_idlest3_core);
3055     qemu_put_be32(f, s->cm_autoidle1_core);
3056     qemu_put_be32(f, s->cm_autoidle2_core);
3057     qemu_put_be32(f, s->cm_autoidle3_core);
3058     qemu_put_be32(f, s->cm_clksel_core);
3059     qemu_put_be32(f, s->cm_clkstctrl_core);
3060     qemu_put_be32(f, s->cm_clkstst_core);
3061     
3062     qemu_put_be32(f, s->cm_fclken_sgx);
3063     qemu_put_be32(f, s->cm_iclken_sgx);
3064     qemu_put_be32(f, s->cm_idlest_sgx);
3065     qemu_put_be32(f, s->cm_clksel_sgx);
3066     qemu_put_be32(f, s->cm_sleepdep_sgx);
3067     qemu_put_be32(f, s->cm_clkstctrl_sgx);
3068     qemu_put_be32(f, s->cm_clkstst_sgx);
3069     
3070     qemu_put_be32(f, s->cm_fclken_wkup);
3071     qemu_put_be32(f, s->cm_iclken_wkup);
3072     qemu_put_be32(f, s->cm_idlest_wkup);
3073     qemu_put_be32(f, s->cm_autoidle_wkup);
3074     qemu_put_be32(f, s->cm_clksel_wkup);
3075     qemu_put_be32(f, s->cm_c48);
3076     
3077     qemu_put_be32(f, s->cm_clken_pll);
3078     qemu_put_be32(f, s->cm_clken2_pll);
3079     qemu_put_be32(f, s->cm_idlest_ckgen);
3080     qemu_put_be32(f, s->cm_idlest2_ckgen);
3081     qemu_put_be32(f, s->cm_autoidle_pll);
3082     qemu_put_be32(f, s->cm_autoidle2_pll);
3083     qemu_put_be32(f, s->cm_clksel1_pll);
3084     qemu_put_be32(f, s->cm_clksel2_pll);
3085     qemu_put_be32(f, s->cm_clksel3_pll);
3086     qemu_put_be32(f, s->cm_clksel4_pll);
3087     qemu_put_be32(f, s->cm_clksel5_pll);
3088     qemu_put_be32(f, s->cm_clkout_ctrl);
3089     
3090     qemu_put_be32(f, s->cm_fclken_dss);
3091     qemu_put_be32(f, s->cm_iclken_dss);
3092     qemu_put_be32(f, s->cm_idlest_dss);
3093     qemu_put_be32(f, s->cm_autoidle_dss);
3094     qemu_put_be32(f, s->cm_clksel_dss);
3095     qemu_put_be32(f, s->cm_sleepdep_dss);
3096     qemu_put_be32(f, s->cm_clkstctrl_dss);
3097     qemu_put_be32(f, s->cm_clkstst_dss);
3098     
3099     qemu_put_be32(f, s->cm_fclken_cam);
3100     qemu_put_be32(f, s->cm_iclken_cam);
3101     qemu_put_be32(f, s->cm_idlest_cam);
3102     qemu_put_be32(f, s->cm_autoidle_cam);
3103     qemu_put_be32(f, s->cm_clksel_cam);
3104     qemu_put_be32(f, s->cm_sleepdep_cam);
3105     qemu_put_be32(f, s->cm_clkstctrl_cam);
3106     qemu_put_be32(f, s->cm_clkstst_cam);
3107
3108     qemu_put_be32(f, s->cm_fclken_per);
3109     qemu_put_be32(f, s->cm_iclken_per);
3110     qemu_put_be32(f, s->cm_idlest_per);
3111     qemu_put_be32(f, s->cm_autoidle_per);
3112     qemu_put_be32(f, s->cm_clksel_per);
3113     qemu_put_be32(f, s->cm_sleepdep_per);
3114     qemu_put_be32(f, s->cm_clkstctrl_per);
3115     qemu_put_be32(f, s->cm_clkstst_per);
3116     
3117     qemu_put_be32(f, s->cm_clksel1_emu);
3118     qemu_put_be32(f, s->cm_clkstctrl_emu);
3119     qemu_put_be32(f, s->cm_clkstst_emu);
3120     qemu_put_be32(f, s->cm_clksel2_emu);
3121     qemu_put_be32(f, s->cm_clksel3_emu);
3122     
3123     qemu_put_be32(f, s->cm_polctrl);
3124
3125     qemu_put_be32(f, s->cm_idlest_neon);
3126     qemu_put_be32(f, s->cm_clkstctrl_neon);
3127
3128     qemu_put_be32(f, s->cm_fclken_usbhost);
3129     qemu_put_be32(f, s->cm_iclken_usbhost);
3130     qemu_put_be32(f, s->cm_idlest_usbhost);
3131     qemu_put_be32(f, s->cm_autoidle_usbhost);
3132     qemu_put_be32(f, s->cm_sleepdep_usbhost);
3133     qemu_put_be32(f, s->cm_clkstctrl_usbhost);
3134     qemu_put_be32(f, s->cm_clkstst_usbhost);
3135 }
3136
3137 static int omap3_cm_load_state(QEMUFile *f, void *opaque, int version_id)
3138 {
3139     struct omap3_cm_s *s = (struct omap3_cm_s *)opaque;
3140     
3141     if (version_id)
3142         return -EINVAL;
3143     
3144     s->cm_fclken_iva2 = qemu_get_be32(f);
3145     s->cm_clken_pll_iva2 = qemu_get_be32(f);
3146     s->cm_idlest_iva2 = qemu_get_be32(f);
3147     s->cm_idlest_pll_iva2 = qemu_get_be32(f);
3148     s->cm_autoidle_pll_iva2 = qemu_get_be32(f);
3149     s->cm_clksel1_pll_iva2 = qemu_get_be32(f);
3150     s->cm_clksel2_pll_iva2 = qemu_get_be32(f);
3151     s->cm_clkstctrl_iva2 = qemu_get_be32(f);
3152     s->cm_clkstst_iva2 = qemu_get_be32(f);
3153     
3154     s->cm_revision = qemu_get_be32(f);
3155     s->cm_sysconfig = qemu_get_be32(f);
3156     
3157     s->cm_clken_pll_mpu = qemu_get_be32(f);
3158     s->cm_idlest_mpu = qemu_get_be32(f);
3159     s->cm_idlest_pll_mpu = qemu_get_be32(f);
3160     s->cm_autoidle_pll_mpu = qemu_get_be32(f);
3161     s->cm_clksel1_pll_mpu = qemu_get_be32(f);
3162     s->cm_clksel2_pll_mpu = qemu_get_be32(f);
3163     s->cm_clkstctrl_mpu = qemu_get_be32(f);
3164     s->cm_clkstst_mpu = qemu_get_be32(f);
3165     
3166     s->cm_fclken1_core = qemu_get_be32(f);
3167     s->cm_fclken3_core = qemu_get_be32(f);
3168     s->cm_iclken1_core = qemu_get_be32(f);
3169     s->cm_iclken2_core = qemu_get_be32(f);
3170     s->cm_iclken3_core = qemu_get_be32(f);
3171     s->cm_idlest1_core = qemu_get_be32(f);
3172     s->cm_idlest2_core = qemu_get_be32(f);
3173     s->cm_idlest3_core = qemu_get_be32(f);
3174     s->cm_autoidle1_core = qemu_get_be32(f);
3175     s->cm_autoidle2_core = qemu_get_be32(f);
3176     s->cm_autoidle3_core = qemu_get_be32(f);
3177     s->cm_clksel_core = qemu_get_be32(f);
3178     s->cm_clkstctrl_core = qemu_get_be32(f);
3179     s->cm_clkstst_core = qemu_get_be32(f);
3180     
3181     s->cm_fclken_sgx = qemu_get_be32(f);
3182     s->cm_iclken_sgx = qemu_get_be32(f);
3183     s->cm_idlest_sgx = qemu_get_be32(f);
3184     s->cm_clksel_sgx = qemu_get_be32(f);
3185     s->cm_sleepdep_sgx = qemu_get_be32(f);
3186     s->cm_clkstctrl_sgx = qemu_get_be32(f);
3187     s->cm_clkstst_sgx = qemu_get_be32(f);
3188     
3189     s->cm_fclken_wkup = qemu_get_be32(f);
3190     s->cm_iclken_wkup = qemu_get_be32(f);
3191     s->cm_idlest_wkup = qemu_get_be32(f);
3192     s->cm_autoidle_wkup = qemu_get_be32(f);
3193     s->cm_clksel_wkup = qemu_get_be32(f);
3194     s->cm_c48 = qemu_get_be32(f);
3195     
3196     s->cm_clken_pll = qemu_get_be32(f);
3197     s->cm_clken2_pll = qemu_get_be32(f);
3198     s->cm_idlest_ckgen = qemu_get_be32(f);
3199     s->cm_idlest2_ckgen = qemu_get_be32(f);
3200     s->cm_autoidle_pll = qemu_get_be32(f);
3201     s->cm_autoidle2_pll = qemu_get_be32(f);
3202     s->cm_clksel1_pll = qemu_get_be32(f);
3203     s->cm_clksel2_pll = qemu_get_be32(f);
3204     s->cm_clksel3_pll = qemu_get_be32(f);
3205     s->cm_clksel4_pll = qemu_get_be32(f);
3206     s->cm_clksel5_pll = qemu_get_be32(f);
3207     s->cm_clkout_ctrl = qemu_get_be32(f);
3208     
3209     s->cm_fclken_dss = qemu_get_be32(f);
3210     s->cm_iclken_dss = qemu_get_be32(f);
3211     s->cm_idlest_dss = qemu_get_be32(f);
3212     s->cm_autoidle_dss = qemu_get_be32(f);
3213     s->cm_clksel_dss = qemu_get_be32(f);
3214     s->cm_sleepdep_dss = qemu_get_be32(f);
3215     s->cm_clkstctrl_dss = qemu_get_be32(f);
3216     s->cm_clkstst_dss = qemu_get_be32(f);
3217     
3218     s->cm_fclken_cam = qemu_get_be32(f);
3219     s->cm_iclken_cam = qemu_get_be32(f);
3220     s->cm_idlest_cam = qemu_get_be32(f);
3221     s->cm_autoidle_cam = qemu_get_be32(f);
3222     s->cm_clksel_cam = qemu_get_be32(f);
3223     s->cm_sleepdep_cam = qemu_get_be32(f);
3224     s->cm_clkstctrl_cam = qemu_get_be32(f);
3225     s->cm_clkstst_cam = qemu_get_be32(f);
3226     
3227     s->cm_fclken_per = qemu_get_be32(f);
3228     s->cm_iclken_per = qemu_get_be32(f);
3229     s->cm_idlest_per = qemu_get_be32(f);
3230     s->cm_autoidle_per = qemu_get_be32(f);
3231     s->cm_clksel_per = qemu_get_be32(f);
3232     s->cm_sleepdep_per = qemu_get_be32(f);
3233     s->cm_clkstctrl_per = qemu_get_be32(f);
3234     s->cm_clkstst_per = qemu_get_be32(f);
3235     
3236     s->cm_clksel1_emu = qemu_get_be32(f);
3237     s->cm_clkstctrl_emu = qemu_get_be32(f);
3238     s->cm_clkstst_emu = qemu_get_be32(f);
3239     s->cm_clksel2_emu = qemu_get_be32(f);
3240     s->cm_clksel3_emu = qemu_get_be32(f);
3241     
3242     s->cm_polctrl = qemu_get_be32(f);
3243     
3244     s->cm_idlest_neon = qemu_get_be32(f);
3245     s->cm_clkstctrl_neon = qemu_get_be32(f);
3246     
3247     s->cm_fclken_usbhost = qemu_get_be32(f);
3248     s->cm_iclken_usbhost = qemu_get_be32(f);
3249     s->cm_idlest_usbhost = qemu_get_be32(f);
3250     s->cm_autoidle_usbhost = qemu_get_be32(f);
3251     s->cm_sleepdep_usbhost = qemu_get_be32(f);
3252     s->cm_clkstctrl_usbhost = qemu_get_be32(f);
3253     s->cm_clkstst_usbhost = qemu_get_be32(f);
3254
3255     omap3_cm_iva2_update(s);
3256     omap3_cm_mpu_update(s);
3257     omap3_cm_fclken1_core_update(s);
3258     omap3_cm_iclken1_core_update(s);
3259     omap3_cm_gp10gp11_update(s);
3260     omap3_cm_l3l4iclk_update(s);
3261     omap_clk_onoff(omap_findclk(s->mpu, "omap3_gp1_fclk"),
3262                    s->cm_fclken_wkup & 1);
3263     omap_clk_onoff(omap_findclk(s->mpu, "omap3_wkup_l4_iclk"),
3264                    s->cm_iclken_wkup ? 1 : 0);
3265     omap3_cm_clksel_wkup_update(s);
3266     omap3_cm_dpll3_update(s);
3267     omap3_cm_dpll4_update(s);
3268     omap3_cm_dpll5_update(s);
3269     omap3_cm_48m_update(s);
3270     omap3_cm_clkout2_update(s);
3271     omap3_cm_per_gptimer_update(s);
3272     
3273     return 0;
3274 }
3275
3276 static CPUReadMemoryFunc *omap3_cm_readfn[] = {
3277     omap_badwidth_read32,
3278     omap_badwidth_read32,
3279     omap3_cm_read,
3280 };
3281
3282 static CPUWriteMemoryFunc *omap3_cm_writefn[] = {
3283     omap_badwidth_write32,
3284     omap_badwidth_write32,
3285     omap3_cm_write,
3286 };
3287
3288 struct omap3_cm_s *omap3_cm_init(struct omap_target_agent_s *ta,
3289                                  qemu_irq mpu_int, qemu_irq dsp_int,
3290                                  qemu_irq iva_int, struct omap_mpu_state_s *mpu)
3291 {
3292     int iomemtype;
3293     struct omap3_cm_s *s = (struct omap3_cm_s *) qemu_mallocz(sizeof(*s));
3294
3295     s->irq[0] = mpu_int;
3296     s->irq[1] = dsp_int;
3297     s->irq[2] = iva_int;
3298     s->mpu = mpu;
3299     omap3_cm_reset(s);
3300
3301     iomemtype = l4_register_io_memory(0, omap3_cm_readfn, omap3_cm_writefn, s);
3302     omap_l4_attach(ta, 0, iomemtype);
3303     omap_l4_attach(ta, 1, iomemtype);
3304
3305     register_savevm("omap3_cm", -1, 0,
3306                     omap3_cm_save_state, omap3_cm_load_state, s);
3307     return s;
3308 }
3309
3310 #define OMAP3_SEC_WDT          1
3311 #define OMAP3_MPU_WDT         2
3312 #define OMAP3_IVA2_WDT        3
3313 /*omap3 watchdog timer*/
3314 struct omap3_wdt_s
3315 {
3316     qemu_irq irq;               /*IVA2 IRQ */
3317     struct omap_mpu_state_s *mpu;
3318     omap_clk clk;
3319     QEMUTimer *timer;
3320
3321     int active;
3322     int64_t rate;
3323     int64_t time;
3324     //int64_t ticks_per_sec;
3325
3326     uint32_t wd_sysconfig;
3327     uint32_t wd_sysstatus;
3328     uint32_t wisr;
3329     uint32_t wier;
3330     uint32_t wclr;
3331     uint32_t wcrr;
3332     uint32_t wldr;
3333     uint32_t wtgr;
3334     uint32_t wwps;
3335     uint32_t wspr;
3336
3337     /*pre and ptv in wclr */
3338     uint32_t pre;
3339     uint32_t ptv;
3340     //uint32_t val;
3341
3342     uint16_t writeh;            /* LSB */
3343     uint16_t readh;             /* MSB */
3344 };
3345
3346 static inline void omap3_wdt_timer_update(struct omap3_wdt_s *wdt_timer)
3347 {
3348     int64_t expires;
3349     if (wdt_timer->active) {
3350         expires = muldiv64(0xffffffffll - wdt_timer->wcrr,
3351                            ticks_per_sec, wdt_timer->rate);
3352         qemu_mod_timer(wdt_timer->timer, wdt_timer->time + expires);
3353     } else
3354         qemu_del_timer(wdt_timer->timer);
3355 }
3356
3357 static void omap3_wdt_clk_setup(struct omap3_wdt_s *timer)
3358 {
3359     /*TODO: Add irq as user to clk */
3360 }
3361
3362 static inline uint32_t omap3_wdt_timer_read(struct omap3_wdt_s *timer)
3363 {
3364     uint64_t distance;
3365
3366     if (timer->active) {
3367         distance = qemu_get_clock(vm_clock) - timer->time;
3368         distance = muldiv64(distance, timer->rate, ticks_per_sec);
3369
3370         if (distance >= 0xffffffff - timer->wcrr)
3371             return 0xffffffff;
3372         else
3373             return timer->wcrr + distance;
3374     } else
3375         return timer->wcrr;
3376 }
3377
3378 /*
3379 static inline void omap3_wdt_timer_sync(struct omap3_wdt_s *timer)
3380 {
3381     if (timer->active) {
3382         timer->val = omap3_wdt_timer_read(timer);
3383         timer->time = qemu_get_clock(vm_clock);
3384     }
3385 }*/
3386
3387 static void omap3_wdt_reset(struct omap3_wdt_s *s, int wdt_index)
3388 {
3389     s->wd_sysconfig = 0x0;
3390     s->wd_sysstatus = 0x0;
3391     s->wisr = 0x0;
3392     s->wier = 0x0;
3393     s->wclr = 0x20;
3394     s->wcrr = 0x0;
3395     switch (wdt_index) {
3396         case OMAP3_MPU_WDT:
3397         case OMAP3_IVA2_WDT:
3398             s->wldr = 0xfffb0000;
3399             break;
3400         case OMAP3_SEC_WDT:
3401             s->wldr = 0xffa60000;
3402             break;
3403         default:
3404             break;
3405     }
3406     s->wtgr = 0x0;
3407     s->wwps = 0x0;
3408     s->wspr = 0x0;
3409
3410     switch (wdt_index) {
3411         case OMAP3_SEC_WDT:
3412         case OMAP3_MPU_WDT:
3413             s->active = 1;
3414             break;
3415         case OMAP3_IVA2_WDT:
3416             s->active = 0;
3417             break;
3418         default:
3419             break;
3420     }
3421     s->pre = s->wclr & (1 << 5);
3422     s->ptv = (s->wclr & 0x1c) >> 2;
3423     s->rate = omap_clk_getrate(s->clk) >> (s->pre ? s->ptv : 0);
3424
3425     s->active = 1;
3426     s->time = qemu_get_clock(vm_clock);
3427     omap3_wdt_timer_update(s);
3428 }
3429
3430 static uint32_t omap3_wdt_read32(void *opaque, target_phys_addr_t addr,
3431                                  int wdt_index)
3432 {
3433     struct omap3_wdt_s *s = (struct omap3_wdt_s *) opaque;
3434
3435     switch (addr) {
3436         case 0x10: return s->wd_sysconfig;
3437         case 0x14: return s->wd_sysstatus;
3438         case 0x18: return s->wisr & 0x1;
3439         case 0x1c: return s->wier & 0x1;
3440         case 0x24: return s->wclr & 0x3c;
3441         case 0x28: /* WCRR */
3442             s->wcrr = omap3_wdt_timer_read(s);
3443             s->time = qemu_get_clock(vm_clock);
3444             return s->wcrr;
3445         case 0x2c: return s->wldr;
3446         case 0x30: return s->wtgr;
3447         case 0x34: return s->wwps;
3448         case 0x48: return s->wspr;
3449         default: break;
3450     }
3451     OMAP_BAD_REG(addr);
3452     return 0;
3453 }
3454
3455 static uint32_t omap3_mpu_wdt_read16(void *opaque, target_phys_addr_t addr)
3456 {
3457     struct omap3_wdt_s *s = (struct omap3_wdt_s *) opaque;
3458     uint32_t ret;
3459
3460     if (addr & 2)
3461         return s->readh;
3462
3463     ret = omap3_wdt_read32(opaque, addr, OMAP3_MPU_WDT);
3464     s->readh = ret >> 16;
3465     return ret & 0xffff;
3466 }
3467
3468 static uint32_t omap3_mpu_wdt_read32(void *opaque, target_phys_addr_t addr)
3469 {
3470     return omap3_wdt_read32(opaque, addr, OMAP3_MPU_WDT);
3471 }
3472
3473 static void omap3_wdt_write32(void *opaque, target_phys_addr_t addr,
3474                               uint32_t value, int wdt_index)
3475 {
3476     struct omap3_wdt_s *s = (struct omap3_wdt_s *) opaque;
3477
3478     switch (addr) {
3479     case 0x14: /* WD_SYSSTATUS */
3480     case 0x34: /* WWPS */
3481         OMAP_RO_REGV(addr, value);
3482         break;
3483     case 0x10: /*WD_SYSCONFIG */
3484         s->wd_sysconfig = value & 0x33f;
3485         break;
3486     case 0x18: /* WISR */
3487          s->wisr = value & 0x1;
3488         break;
3489     case 0x1c: /* WIER */
3490         s->wier = value & 0x1;
3491         break;
3492     case 0x24: /* WCLR */
3493         s->wclr = value & 0x3c;
3494         break;
3495     case 0x28: /* WCRR */
3496         s->wcrr = value;
3497         s->time = qemu_get_clock(vm_clock);
3498         omap3_wdt_timer_update(s);
3499         break;
3500     case 0x2c: /* WLDR */
3501         s->wldr = value; /* It will take effect after next overflow */
3502         break;
3503     case 0x30: /* WTGR */
3504         if (value != s->wtgr) {
3505             s->wcrr = s->wldr;
3506             s->pre = s->wclr & (1 << 5);
3507             s->ptv = (s->wclr & 0x1c) >> 2;
3508             s->rate = omap_clk_getrate(s->clk) >> (s->pre ? s->ptv : 0);
3509             s->time = qemu_get_clock(vm_clock);
3510             omap3_wdt_timer_update(s);
3511         }
3512         s->wtgr = value;
3513         break;
3514     case 0x48: /* WSPR */
3515         if (((value & 0xffff) == 0x5555) && ((s->wspr & 0xffff) == 0xaaaa)) {
3516             s->active = 0;
3517             s->wcrr = omap3_wdt_timer_read(s);
3518             omap3_wdt_timer_update(s);
3519         }
3520         if (((value & 0xffff) == 0x4444) && ((s->wspr & 0xffff) == 0xbbbb)) {
3521             s->active = 1;
3522             s->time = qemu_get_clock(vm_clock);
3523             omap3_wdt_timer_update(s);
3524         }
3525         s->wspr = value;
3526         break;
3527     default:
3528         OMAP_BAD_REGV(addr, value);
3529         break;
3530     }
3531 }
3532
3533 static void omap3_mpu_wdt_write16(void *opaque, target_phys_addr_t addr,
3534                                   uint32_t value)
3535 {
3536     struct omap3_wdt_s *s = (struct omap3_wdt_s *) opaque;
3537
3538     if (addr & 2)
3539         return omap3_wdt_write32(opaque, addr, (value << 16) | s->writeh,
3540                                  OMAP3_MPU_WDT);
3541     else
3542         s->writeh = (uint16_t) value;
3543 }
3544
3545 static void omap3_mpu_wdt_write32(void *opaque, target_phys_addr_t addr,
3546                                   uint32_t value)
3547 {
3548     omap3_wdt_write32(opaque, addr, value, OMAP3_MPU_WDT);
3549 }
3550
3551 static CPUReadMemoryFunc *omap3_mpu_wdt_readfn[] = {
3552     omap_badwidth_read32,
3553     omap3_mpu_wdt_read16,
3554     omap3_mpu_wdt_read32,
3555 };
3556
3557 static CPUWriteMemoryFunc *omap3_mpu_wdt_writefn[] = {
3558     omap_badwidth_write32,
3559     omap3_mpu_wdt_write16,
3560     omap3_mpu_wdt_write32,
3561 };
3562
3563 static void omap3_mpu_wdt_timer_tick(void *opaque)
3564 {
3565     struct omap3_wdt_s *wdt_timer = (struct omap3_wdt_s *) opaque;
3566
3567     /*TODO:Sent reset pulse to PRCM */
3568     wdt_timer->wcrr = wdt_timer->wldr;
3569
3570     /*after overflow, generate the new wdt_timer->rate */
3571     wdt_timer->pre = wdt_timer->wclr & (1 << 5);
3572     wdt_timer->ptv = (wdt_timer->wclr & 0x1c) >> 2;
3573     wdt_timer->rate =
3574         omap_clk_getrate(wdt_timer->clk) >> (wdt_timer->pre ? wdt_timer->
3575                                              ptv : 0);
3576
3577     wdt_timer->time = qemu_get_clock(vm_clock);
3578     omap3_wdt_timer_update(wdt_timer);
3579 }
3580
3581 static void omap3_mpu_wdt_save_state(QEMUFile *f, void *opaque)
3582 {
3583     struct omap3_wdt_s *s = (struct omap3_wdt_s *)opaque;
3584
3585     qemu_put_timer(f, s->timer);
3586     qemu_put_sbe32(f, s->active);
3587     qemu_put_be64(f, s->rate);
3588     qemu_put_be64(f, s->time);
3589     qemu_put_be32(f, s->wd_sysconfig);
3590     qemu_put_be32(f, s->wd_sysstatus);
3591     qemu_put_be32(f, s->wisr);
3592     qemu_put_be32(f, s->wier);
3593     qemu_put_be32(f, s->wclr);
3594     qemu_put_be32(f, s->wcrr);
3595     qemu_put_be32(f, s->wldr);
3596     qemu_put_be32(f, s->wtgr);
3597     qemu_put_be32(f, s->wwps);
3598     qemu_put_be32(f, s->wspr);
3599     qemu_put_be32(f, s->pre);
3600     qemu_put_be32(f, s->ptv);
3601     qemu_put_be16(f, s->writeh);
3602     qemu_put_be16(f, s->readh);
3603 }
3604
3605 static int omap3_mpu_wdt_load_state(QEMUFile *f, void *opaque, int version_id)
3606 {
3607     struct omap3_wdt_s *s = (struct omap3_wdt_s *)opaque;
3608     
3609     if (version_id)
3610         return -EINVAL;
3611     
3612     qemu_get_timer(f, s->timer);
3613     s->active = qemu_get_sbe32(f);
3614     s->rate = qemu_get_be64(f);
3615     s->time = qemu_get_be64(f);
3616     s->wd_sysconfig = qemu_get_be32(f);
3617     s->wd_sysstatus = qemu_get_be32(f);
3618     s->wisr = qemu_get_be32(f);
3619     s->wier = qemu_get_be32(f);
3620     s->wclr = qemu_get_be32(f);
3621     s->wcrr = qemu_get_be32(f);
3622     s->wldr = qemu_get_be32(f);
3623     s->wtgr = qemu_get_be32(f);
3624     s->wwps = qemu_get_be32(f);
3625     s->wspr = qemu_get_be32(f);
3626     s->pre = qemu_get_be32(f);
3627     s->ptv = qemu_get_be32(f);
3628     s->writeh = qemu_get_be16(f);
3629     s->readh = qemu_get_be16(f);
3630     
3631     return 0;
3632 }
3633
3634 static struct omap3_wdt_s *omap3_mpu_wdt_init(struct omap_target_agent_s *ta,
3635                                               qemu_irq irq, omap_clk fclk,
3636                                               omap_clk iclk,
3637                                               struct omap_mpu_state_s *mpu)
3638 {
3639     int iomemtype;
3640     struct omap3_wdt_s *s = (struct omap3_wdt_s *) qemu_mallocz(sizeof(*s));
3641
3642     s->irq = irq;
3643     s->clk = fclk;
3644     s->timer = qemu_new_timer(vm_clock, omap3_mpu_wdt_timer_tick, s);
3645
3646     omap3_wdt_reset(s, OMAP3_MPU_WDT);
3647     if (irq != NULL)
3648         omap3_wdt_clk_setup(s);
3649
3650     iomemtype = l4_register_io_memory(0, omap3_mpu_wdt_readfn,
3651                                       omap3_mpu_wdt_writefn, s);
3652     omap_l4_attach(ta, 0, iomemtype);
3653
3654     register_savevm("omap3_mpu_wdt", -1, 0,
3655                     omap3_mpu_wdt_save_state, omap3_mpu_wdt_load_state, s);
3656     return s;
3657 }
3658
3659 struct omap3_scm_s {
3660     struct omap_mpu_state_s *mpu;
3661
3662         uint8 interface[48];     /*0x4800 2000*/
3663         uint8 padconfs[576];     /*0x4800 2030*/
3664         uint32 general[228];     /*0x4800 2270*/
3665         uint8 mem_wkup[1024];    /*0x4800 2600*/
3666         uint8 padconfs_wkup[84]; /*0x4800 2a00*/
3667         uint32 general_wkup[8];  /*0x4800 2a60*/
3668 };
3669
3670 static void omap3_scm_save_state(QEMUFile *f, void *opaque)
3671 {
3672     struct omap3_scm_s *s = (struct omap3_scm_s *)opaque;
3673     int i;
3674
3675     qemu_put_buffer(f, s->interface, sizeof(s->interface));
3676     qemu_put_buffer(f, s->padconfs, sizeof(s->padconfs));
3677     for (i = 0; i < sizeof(s->general)/sizeof(uint32); i++)
3678         qemu_put_be32(f, s->general[i]);
3679     qemu_put_buffer(f, s->mem_wkup, sizeof(s->mem_wkup));
3680     qemu_put_buffer(f, s->padconfs_wkup, sizeof(s->padconfs_wkup));
3681     for (i = 0; i < sizeof(s->general_wkup)/sizeof(uint32); i++)
3682         qemu_put_be32(f, s->general_wkup[i]);
3683 }
3684
3685 static int omap3_scm_load_state(QEMUFile *f, void *opaque, int version_id)
3686 {
3687     struct omap3_scm_s *s = (struct omap3_scm_s *)opaque;
3688     int i;
3689     
3690     if (version_id)
3691         return -EINVAL;
3692     
3693     qemu_get_buffer(f, s->interface, sizeof(s->interface));
3694     qemu_get_buffer(f, s->padconfs, sizeof(s->padconfs));
3695     for (i = 0; i < sizeof(s->general)/sizeof(uint32); i++)
3696         s->general[i] = qemu_get_be32(f);
3697     qemu_get_buffer(f, s->mem_wkup, sizeof(s->mem_wkup));
3698     qemu_get_buffer(f, s->padconfs_wkup, sizeof(s->padconfs_wkup));
3699     for (i = 0; i < sizeof(s->general_wkup)/sizeof(uint32); i++)
3700         s->general_wkup[i] = qemu_get_be32(f);
3701
3702     return 0;
3703 }
3704
3705 #define PADCONFS_VALUE(wakeup0,wakeup1,offmode0,offmode1, \
3706                                                 inputenable0,inputenable1,pupd0,pupd1,muxmode0,muxmode1,offset) \
3707         do { \
3708                  *(padconfs+offset/4) = (wakeup0 <<14)|(offmode0<<9)|(inputenable0<<8)|(pupd0<<3)|(muxmode0); \
3709                  *(padconfs+offset/4) |= (wakeup1 <<30)|(offmode1<<25)|(inputenable1<<24)|(pupd1<<19)|(muxmode1<<16); \
3710 } while (0)
3711
3712
3713 static void omap3_scm_reset(struct omap3_scm_s *s)
3714 {
3715     uint32 * padconfs;
3716     padconfs = (uint32 *)(s->padconfs);
3717     PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x0);
3718     PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x4);
3719     PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x8);
3720     PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0xc);
3721     PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x10);
3722     PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x14);
3723     PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x18);
3724     PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x1c);
3725     PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x20);
3726     PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x24);
3727     PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x28);
3728     PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x2c);
3729     PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x30);
3730     PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x34);
3731     PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x38);
3732     PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x3c);
3733     PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x40);
3734     PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x44);
3735     PADCONFS_VALUE(0,0,0,0,1,1,0,1,0,7,0x48);
3736     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x4c);
3737     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x50);
3738     PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x54);
3739     PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x58);
3740     PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,0,0x5c);
3741     PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x60);
3742     PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x64);
3743     PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x68);
3744     PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x6c);
3745     PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x70);
3746     PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x74);
3747     PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x78);
3748     PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x7c);
3749     PADCONFS_VALUE(0,0,0,0,1,1,0,3,0,7,0x80);
3750     PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x84);
3751     PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x88);
3752     PADCONFS_VALUE(0,0,0,0,1,1,3,0,7,0,0x8c);
3753     PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x90);
3754     PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x94);
3755     PADCONFS_VALUE(0,0,0,0,1,1,1,0,7,0,0x98);
3756     PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,7,0x9c);
3757     PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0xa0);
3758     PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0xa4);
3759     PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0xa8);
3760     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xac);
3761     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xb0);
3762     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xb4);
3763     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xb8);
3764     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xbc);
3765     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xc0);
3766     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xc4);
3767     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xc8);
3768     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xcc);
3769     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xd0);
3770     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xd4);
3771     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xd8);
3772     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xdc);
3773     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xe0);
3774     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xe4);
3775     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xe8);
3776     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xec);
3777     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xf0);
3778     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xf4);
3779     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xf8);
3780     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xfc);
3781     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x100);
3782     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x104);
3783     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x108);
3784     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x10c);
3785     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x110);
3786     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x114);
3787     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x118);
3788     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x11c);
3789     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x120);
3790     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x124);
3791     PADCONFS_VALUE(0,0,0,0,1,1,1,3,7,7,0x128);
3792     PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x12c);
3793     PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x130);
3794     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x134);
3795     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x138);
3796     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x13c);
3797     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x140);
3798     PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x144);
3799     PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x148);
3800     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x14c);
3801     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x150);
3802     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x154);
3803     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x158);
3804     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x15c);
3805     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x160);
3806     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x164);
3807     PADCONFS_VALUE(0,0,0,0,1,1,1,3,7,7,0x168);
3808     PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x16c);
3809     PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0x170);
3810     PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0x174);
3811     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x178);
3812     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x17c);
3813     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x180);
3814     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x184);
3815     PADCONFS_VALUE(0,0,0,0,1,1,1,3,7,7,0x188);
3816     PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x18c);
3817     PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x190);
3818     PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x194);
3819     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x198);
3820     PADCONFS_VALUE(0,0,0,0,1,1,1,3,7,7,0x19c);
3821     PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x1a0);
3822     PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0x1a4);
3823     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x1a8);
3824     PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0x1ac);
3825     PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0x1b0);
3826     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1b4);
3827     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1b8);
3828     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1bc);
3829     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1c0);
3830     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1c4);
3831     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1c8);
3832     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1cc);
3833     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1d0);
3834     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1d4);
3835     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1d8);
3836     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1dc);
3837     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1e0);
3838     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1e4);
3839     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1e8);
3840     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1ec);
3841     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1f0);
3842     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1f4);
3843     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1f8);
3844     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1fc);
3845     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x200);
3846     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x204);
3847     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x208);
3848     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x20c);
3849     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x210);
3850     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x214);
3851     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x218);
3852     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x21c);
3853     PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x220);
3854     PADCONFS_VALUE(0,0,0,0,1,1,3,1,0,0,0x224);
3855     PADCONFS_VALUE(0,0,0,0,1,1,0,1,0,0,0x228);
3856     PADCONFS_VALUE(0,0,0,0,1,1,0,1,0,0,0x22c);
3857     PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x230);
3858     PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x234);
3859
3860         padconfs = (uint32 *)(s->general);
3861     memset(s->general, 0, sizeof(s->general));
3862         s->general[0x01] = 0x4000000;  /* CONTROL_DEVCONF_0 */
3863         s->general[0x1c] = 0x1;        /* 0x480022e0?? */
3864     s->general[0x20] = 0x30f;      /* CONTROL_STATUS:
3865                                     * - device type  = GP Device
3866                                     * - sys_boot:6   = oscillator bypass mode
3867                                     * - sys_boot:0-5 = NAND, USB, UART3, MMC1*/
3868         s->general[0x75] = 0x7fc0;     /* CONTROL_PROG_IO0 */
3869         s->general[0x76] = 0xaa;       /* CONTROL_PROG_IO1 */
3870         s->general[0x7c] = 0x2700;     /* CONTROL_SDRC_SHARING */
3871         s->general[0x7d] = 0x300000;   /* CONTROL_SDRC_MCFG0 */
3872         s->general[0x7e] = 0x300000;   /* CONTROL_SDRC_MCFG1 */
3873         s->general[0x81] = 0xffff;     /* CONTROL_MODEM_GPMC_DT_FW_REQ_INFO */
3874         s->general[0x82] = 0xffff;     /* CONTROL_MODEM_GPMC_DT_FW_RD */
3875         s->general[0x83] = 0xffff;     /* CONTROL_MODEM_GPMC_DT_FW_WR */
3876         s->general[0x84] = 0x6;        /* CONTROL_MODEM_GPMC_BOOT_CODE */
3877         s->general[0x85] = 0xffffffff; /* CONTROL_MODEM_SMS_RG_ATT1 */
3878         s->general[0x86] = 0xffff;     /* CONTROL_MODEM_SMS_RG_RDPERM1 */
3879         s->general[0x87] = 0xffff;     /* CONTROL_MODEM_SMS_RG_WRPERM1 */
3880         s->general[0x88] = 0x1;        /* CONTROL_MODEM_D2D_FW_DEBUG_MODE */
3881         s->general[0x8b] = 0xffffffff; /* CONTROL_DPF_OCM_RAM_FW_REQINFO */
3882         s->general[0x8c] = 0xffff;     /* CONTROL_DPF_OCM_RAM_FW_WR */
3883         s->general[0x8e] = 0xffff;     /* CONTROL_DPF_REGION4_GPMC_FW_REQINFO */
3884         s->general[0x8f] = 0xffff;     /* CONTROL_DPF_REGION4_GPMC_FW_WR */
3885         s->general[0x91] = 0xffff;     /* CONTROL_DPF_REGION1_IVA2_FW_REQINFO */
3886         s->general[0x92] = 0xffff;     /* CONTROL_DPF_REGION1_IVA2_FW_WR */
3887         s->general[0xac] = 0x109;      /* CONTROL_PBIAS_LITE */
3888         s->general[0xb2] = 0xffff;     /* CONTROL_DPF_MAD2D_FW_ADDR_MATCH */
3889         s->general[0xb3] = 0xffff;     /* CONTROL_DPF_MAD2D_FW_REQINFO */
3890         s->general[0xb4] = 0xffff;     /* CONTROL_DPF_MAD2D_FW_WR */
3891         PADCONFS_VALUE(0,0,0,0,1,1,3,3,4,4,0x368); /* PADCONF_ETK_CLK */
3892     PADCONFS_VALUE(0,0,0,0,1,1,3,3,4,4,0x36c); /* PADCONF_ETK_D0 */
3893     PADCONFS_VALUE(0,0,0,0,1,1,3,3,4,4,0x370); /* PADCONF_ETK_D2 */
3894     PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x374); /* PADCONF_ETK_D4 */
3895     PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x378); /* PADCONF_ETK_D6 */
3896     PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x37c); /* PADCONF_ETK_D8 */
3897     PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x380); /* PADCONF_ETK_D10 */
3898     PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x384); /* PADCONF_ETK_D12 */
3899     PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x388); /* PADCONF_ETK_D14 */
3900
3901         padconfs = (uint32 *)(s->padconfs_wkup);
3902         PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x0);
3903         PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x4);
3904         PADCONFS_VALUE(0,0,0,0,1,1,3,0,0,0,0x8);
3905         PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0xc);
3906         PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x10);
3907         PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x14);
3908         PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x18);
3909         PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1c);
3910         PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x20);
3911         PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x24);
3912         PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x2c);
3913
3914         s->general_wkup[0] = 0x66ff; /* 0x48002A60?? */
3915 }
3916
3917 static uint32_t omap3_scm_read8(void *opaque, target_phys_addr_t addr)
3918 {
3919     struct omap3_scm_s *s = (struct omap3_scm_s *) opaque;
3920     uint8_t* temp;
3921         
3922     switch (addr) {
3923         case 0x000 ... 0x02f: return s->interface[addr];
3924         case 0x030 ... 0x26f: return s->padconfs[addr - 0x30];
3925         case 0x270 ... 0x5ff: temp = (uint8_t *)s->general; return temp[addr - 0x270];
3926         case 0x600 ... 0x9ff: return s->mem_wkup[addr - 0x600];
3927         case 0xa00 ... 0xa5f: return s->padconfs_wkup[addr - 0xa00];
3928         case 0xa60 ... 0xa7f: temp = (uint8_t *)s->general_wkup; return temp[addr - 0xa60];
3929         default: break;
3930     }
3931     OMAP_BAD_REG(addr);
3932     return 0;
3933 }
3934
3935 static uint32_t omap3_scm_read16(void *opaque, target_phys_addr_t addr)
3936 {
3937     uint32_t v;
3938     v = omap3_scm_read8(opaque, addr);
3939     v |= omap3_scm_read8(opaque, addr + 1) << 8;
3940     return v;
3941 }
3942
3943 static uint32_t omap3_scm_read32(void *opaque, target_phys_addr_t addr)
3944 {
3945     uint32_t v;
3946     v = omap3_scm_read8(opaque, addr);
3947     v |= omap3_scm_read8(opaque, addr + 1) << 8;
3948     v |= omap3_scm_read8(opaque, addr + 2) << 16;
3949     v |= omap3_scm_read8(opaque, addr + 3) << 24;
3950     return v;
3951 }
3952
3953 static void omap3_scm_write8(void *opaque, target_phys_addr_t addr,
3954                              uint32_t value)
3955 {
3956     struct omap3_scm_s *s = (struct omap3_scm_s *) opaque;
3957     uint8_t* temp;
3958
3959     switch (addr) {
3960         case 0x000 ... 0x02f: s->interface[addr] = value; break;
3961         case 0x030 ... 0x26f: s->padconfs[addr-0x30] = value; break;
3962         case 0x270 ... 0x5ff: temp = (uint8_t *)s->general; temp[addr-0x270] = value; break;
3963         case 0x600 ... 0x9ff: s->mem_wkup[addr-0x600] = value; break;
3964         case 0xa00 ... 0xa5f: s->padconfs_wkup[addr-0xa00] = value; break;
3965         case 0xa60 ... 0xa7f: temp = (uint8_t *)s->general_wkup; temp[addr-0xa60] = value; break;
3966         default: OMAP_BAD_REGV(addr, value); break;
3967     }
3968 }
3969
3970 static void omap3_scm_write16(void *opaque, target_phys_addr_t addr,
3971                               uint32_t value)
3972 {
3973     omap3_scm_write8(opaque, addr + 0, (value) & 0xff);
3974     omap3_scm_write8(opaque, addr + 1, (value >> 8) & 0xff);
3975 }
3976
3977 static void omap3_scm_write32(void *opaque, target_phys_addr_t addr,
3978                               uint32_t value)
3979 {
3980     omap3_scm_write8(opaque, addr + 0, (value) & 0xff);
3981     omap3_scm_write8(opaque, addr + 1, (value >> 8) & 0xff);
3982     omap3_scm_write8(opaque, addr + 2, (value >> 16) & 0xff);
3983     omap3_scm_write8(opaque, addr + 3, (value >> 24) & 0xff);
3984 }
3985
3986 static CPUReadMemoryFunc *omap3_scm_readfn[] = {
3987     omap3_scm_read8,
3988     omap3_scm_read16,
3989     omap3_scm_read32,
3990 };
3991
3992 static CPUWriteMemoryFunc *omap3_scm_writefn[] = {
3993     omap3_scm_write8,
3994     omap3_scm_write16,
3995     omap3_scm_write32,
3996 };
3997
3998 static struct omap3_scm_s *omap3_scm_init(struct omap_target_agent_s *ta,
3999                                           struct omap_mpu_state_s *mpu)
4000 {
4001     int iomemtype;
4002     struct omap3_scm_s *s = (struct omap3_scm_s *) qemu_mallocz(sizeof(*s));
4003
4004     s->mpu = mpu;
4005
4006     omap3_scm_reset(s);
4007
4008     iomemtype = l4_register_io_memory(0, omap3_scm_readfn,
4009                                       omap3_scm_writefn, s);
4010     omap_l4_attach(ta, 0, iomemtype);
4011     
4012     register_savevm("omap3_scm", -1, 0,
4013                     omap3_scm_save_state, omap3_scm_load_state, s);
4014     return s;
4015 }
4016
4017 /*dummy SDRAM Memory Scheduler emulation*/
4018 struct omap3_sms_s
4019 {
4020     struct omap_mpu_state_s *mpu;
4021
4022     uint32 sms_sysconfig;
4023     uint32 sms_sysstatus;
4024     uint32 sms_rg_att[8];
4025     uint32 sms_rg_rdperm[8];
4026     uint32 sms_rg_wrperm[8];
4027     uint32 sms_rg_start[7];
4028     uint32 sms_rg_end[7];
4029     uint32 sms_security_control;
4030     uint32 sms_class_arbiter0;
4031     uint32 sms_class_arbiter1;
4032     uint32 sms_class_arbiter2;
4033     uint32 sms_interclass_arbiter;
4034     uint32 sms_class_rotation[3];
4035     uint32 sms_err_addr;
4036     uint32 sms_err_type;
4037     uint32 sms_pow_ctrl;
4038     uint32 sms_rot_control[12];
4039     uint32 sms_rot_size[12];
4040     uint32 sms_rot_physical_ba[12];
4041 };
4042
4043 static void omap3_sms_save_state(QEMUFile *f, void *opaque)
4044 {
4045     struct omap3_sms_s *s = (struct omap3_sms_s *)opaque;
4046     int i;
4047
4048     qemu_put_be32(f, s->sms_sysconfig);
4049     qemu_put_be32(f, s->sms_sysstatus);
4050     for (i = 0; i < 8; i++) {
4051         qemu_put_be32(f, s->sms_rg_att[i]);
4052         qemu_put_be32(f, s->sms_rg_rdperm[i]);
4053         qemu_put_be32(f, s->sms_rg_wrperm[i]);
4054         if (i < 7) {
4055             qemu_put_be32(f, s->sms_rg_start[i]);
4056             qemu_put_be32(f, s->sms_rg_end[i]);
4057         }
4058     }
4059     qemu_put_be32(f, s->sms_security_control);
4060     qemu_put_be32(f, s->sms_class_arbiter0);
4061     qemu_put_be32(f, s->sms_class_arbiter1);
4062     qemu_put_be32(f, s->sms_class_arbiter2);
4063     qemu_put_be32(f, s->sms_interclass_arbiter);
4064     qemu_put_be32(f, s->sms_class_rotation[0]);
4065     qemu_put_be32(f, s->sms_class_rotation[1]);
4066     qemu_put_be32(f, s->sms_class_rotation[2]);
4067     qemu_put_be32(f, s->sms_err_addr);
4068     qemu_put_be32(f, s->sms_err_type);
4069     qemu_put_be32(f, s->sms_pow_ctrl);
4070     for (i = 0; i< 12; i++) {
4071         qemu_put_be32(f, s->sms_rot_control[i]);
4072         qemu_put_be32(f, s->sms_rot_size[i]);
4073         qemu_put_be32(f, s->sms_rot_physical_ba[i]);
4074     }
4075 }
4076
4077 static int omap3_sms_load_state(QEMUFile *f, void *opaque, int version_id)
4078 {
4079     struct omap3_sms_s *s = (struct omap3_sms_s *)opaque;
4080     int i;
4081     
4082     if (version_id)
4083         return -EINVAL;
4084     
4085     s->sms_sysconfig = qemu_get_be32(f);
4086     s->sms_sysstatus = qemu_get_be32(f);
4087     for (i = 0; i < 8; i++) {
4088         s->sms_rg_att[i] = qemu_get_be32(f);
4089         s->sms_rg_rdperm[i] = qemu_get_be32(f);
4090         s->sms_rg_wrperm[i] = qemu_get_be32(f);
4091         if (i < 7) {
4092             s->sms_rg_start[i] = qemu_get_be32(f);
4093             s->sms_rg_end[i] = qemu_get_be32(f);
4094         }
4095     }
4096     s->sms_security_control = qemu_get_be32(f);
4097     s->sms_class_arbiter0 = qemu_get_be32(f);
4098     s->sms_class_arbiter1 = qemu_get_be32(f);
4099     s->sms_class_arbiter2 = qemu_get_be32(f);
4100     s->sms_interclass_arbiter = qemu_get_be32(f);
4101     s->sms_class_rotation[0] = qemu_get_be32(f);
4102     s->sms_class_rotation[1] = qemu_get_be32(f);
4103     s->sms_class_rotation[2] = qemu_get_be32(f);
4104     s->sms_err_addr = qemu_get_be32(f);
4105     s->sms_err_type = qemu_get_be32(f);
4106     s->sms_pow_ctrl = qemu_get_be32(f);
4107     for (i = 0; i< 12; i++) {
4108         s->sms_rot_control[i] = qemu_get_be32(f);
4109         s->sms_rot_size[i] = qemu_get_be32(f);
4110         s->sms_rot_physical_ba[i] = qemu_get_be32(f);
4111     }
4112     
4113     return 0;
4114 }
4115
4116 static uint32_t omap3_sms_read32(void *opaque, target_phys_addr_t addr)
4117 {
4118     struct omap3_sms_s *s = (struct omap3_sms_s *) opaque;
4119
4120     switch (addr)
4121     {
4122     case 0x10:
4123         return s->sms_sysconfig;
4124     case 0x14:
4125         return s->sms_sysstatus;
4126     case 0x48:
4127     case 0x68:
4128     case 0x88:
4129     case 0xa8:
4130     case 0xc8:
4131     case 0xe8:
4132     case 0x108:
4133     case 0x128:
4134         return s->sms_rg_att[(addr-0x48)/0x20];
4135     case 0x50:
4136     case 0x70:
4137     case 0x90:
4138     case 0xb0:
4139     case 0xd0:
4140     case 0xf0:
4141     case 0x110:
4142     case 0x130:
4143         return s->sms_rg_rdperm[(addr-0x50)/0x20];
4144     case 0x58:
4145     case 0x78:
4146     case 0x98:
4147     case 0xb8:
4148     case 0xd8:
4149     case 0xf8:
4150     case 0x118:
4151         return s->sms_rg_wrperm[(addr-0x58)/0x20];
4152     case 0x60:
4153     case 0x80:
4154     case 0xa0:
4155     case 0xc0:
4156     case 0xe0:
4157     case 0x100:
4158     case 0x120:
4159         return s->sms_rg_start[(addr-0x60)/0x20];
4160
4161     case 0x64:
4162     case 0x84:
4163     case 0xa4:
4164     case 0xc4:
4165     case 0xe4:
4166     case 0x104:
4167     case 0x124:
4168         return s->sms_rg_end[(addr-0x64)/0x20];
4169     case 0x140:
4170         return s->sms_security_control;
4171     case 0x150:
4172         return s->sms_class_arbiter0;
4173         case 0x154:
4174                 return s->sms_class_arbiter1;
4175         case 0x158:
4176                 return s->sms_class_arbiter2;
4177         case 0x160:
4178                 return s->sms_interclass_arbiter;
4179         case 0x164:
4180         case 0x168:
4181         case 0x16c:
4182                 return s->sms_class_rotation[(addr-0x164)/4];
4183         case 0x170:
4184                 return s->sms_err_addr;
4185         case 0x174:
4186                 return s->sms_err_type;
4187         case 0x178:
4188                 return s->sms_pow_ctrl;
4189         case 0x180:
4190         case 0x190:
4191         case 0x1a0:
4192         case 0x1b0:
4193         case 0x1c0:
4194         case 0x1d0:
4195         case 0x1e0:
4196         case 0x1f0:
4197         case 0x200:
4198         case 0x210:
4199         case 0x220:
4200         case 0x230:
4201                 return s->sms_rot_control[(addr-0x180)/0x10];
4202         case 0x184:
4203         case 0x194:
4204         case 0x1a4:
4205         case 0x1b4:
4206         case 0x1c4:
4207         case 0x1d4:
4208         case 0x1e4:
4209         case 0x1f4:
4210         case 0x204:
4211         case 0x214:
4212         case 0x224:
4213         case 0x234:
4214                 return s->sms_rot_size[(addr-0x184)/0x10];
4215
4216         case 0x188:
4217         case 0x198:
4218         case 0x1a8:
4219         case 0x1b8:
4220         case 0x1c8:
4221         case 0x1d8:
4222         case 0x1e8:
4223         case 0x1f8:
4224         case 0x208:
4225         case 0x218:
4226         case 0x228:
4227         case 0x238:
4228                 return s->sms_rot_size[(addr-0x188)/0x10];
4229
4230     default:
4231         break;
4232     }
4233     OMAP_BAD_REG(addr);
4234     return 0;
4235 }
4236
4237 static void omap3_sms_write32(void *opaque, target_phys_addr_t addr,
4238                               uint32_t value)
4239 {
4240     struct omap3_sms_s *s = (struct omap3_sms_s *) opaque;
4241     //int i;
4242
4243     switch (addr)
4244     {
4245     case 0x14:
4246         OMAP_RO_REG(addr);
4247         return;
4248     case 0x10:
4249         s->sms_sysconfig = value & 0x1f;
4250         break;
4251     
4252     case 0x48:
4253     case 0x68:
4254     case 0x88:
4255     case 0xa8:
4256     case 0xc8:
4257     case 0xe8:
4258     case 0x108:
4259     case 0x128:
4260         s->sms_rg_att[(addr-0x48)/0x20] = value;
4261         break;
4262     case 0x50:
4263     case 0x70:
4264     case 0x90:
4265     case 0xb0:
4266     case 0xd0:
4267     case 0xf0:
4268     case 0x110:
4269     case 0x130:
4270         s->sms_rg_rdperm[(addr-0x50)/0x20] = value&0xffff;
4271         break;
4272     case 0x58:
4273     case 0x78:
4274     case 0x98:
4275     case 0xb8:
4276     case 0xd8:
4277     case 0xf8:
4278     case 0x118:
4279         s->sms_rg_wrperm[(addr-0x58)/0x20] = value&0xffff;
4280         break;          
4281     case 0x60:
4282     case 0x80:
4283     case 0xa0:
4284     case 0xc0:
4285     case 0xe0:
4286     case 0x100:
4287     case 0x120:
4288         s->sms_rg_start[(addr-0x60)/0x20] = value;
4289         break;
4290     case 0x64:
4291     case 0x84:
4292     case 0xa4:
4293     case 0xc4:
4294     case 0xe4:
4295     case 0x104:
4296     case 0x124:
4297         s->sms_rg_end[(addr-0x64)/0x20] = value;
4298         break;
4299     case 0x140:
4300         s->sms_security_control = value &0xfffffff;
4301         break;
4302     case 0x150:
4303         s->sms_class_arbiter0 = value;
4304         break;
4305         case 0x154:
4306                 s->sms_class_arbiter1 = value;
4307                 break;
4308         case 0x158:
4309                 s->sms_class_arbiter2 = value;
4310                 break;
4311         case 0x160:
4312                 s->sms_interclass_arbiter = value;
4313                 break;
4314         case 0x164:
4315         case 0x168:
4316         case 0x16c:
4317                 s->sms_class_rotation[(addr-0x164)/4] = value;
4318                 break;
4319         case 0x170:
4320                 s->sms_err_addr = value;
4321                 break;
4322         case 0x174:
4323                 s->sms_err_type = value;
4324                 break;
4325         case 0x178:
4326                 s->sms_pow_ctrl = value;
4327                 break;
4328         case 0x180:
4329         case 0x190:
4330         case 0x1a0:
4331         case 0x1b0:
4332         case 0x1c0:
4333         case 0x1d0:
4334         case 0x1e0:
4335         case 0x1f0:
4336         case 0x200:
4337         case 0x210:
4338         case 0x220:
4339         case 0x230:
4340                 s->sms_rot_control[(addr-0x180)/0x10] = value;
4341                 break;
4342         case 0x184:
4343         case 0x194:
4344         case 0x1a4:
4345         case 0x1b4:
4346         case 0x1c4:
4347         case 0x1d4:
4348         case 0x1e4:
4349         case 0x1f4:
4350         case 0x204:
4351         case 0x214:
4352         case 0x224:
4353         case 0x234:
4354                 s->sms_rot_size[(addr-0x184)/0x10] = value;
4355                 break;
4356
4357         case 0x188:
4358         case 0x198:
4359         case 0x1a8:
4360         case 0x1b8:
4361         case 0x1c8:
4362         case 0x1d8:
4363         case 0x1e8:
4364         case 0x1f8:
4365         case 0x208:
4366         case 0x218:
4367         case 0x228:
4368         case 0x238:
4369                 s->sms_rot_size[(addr-0x188)/0x10] = value;   
4370                 break;
4371         default:
4372         OMAP_BAD_REGV(addr, value);
4373         break;
4374     }
4375 }
4376
4377 static CPUReadMemoryFunc *omap3_sms_readfn[] = {
4378     omap_badwidth_read32,
4379     omap_badwidth_read32,
4380     omap3_sms_read32,
4381 };
4382
4383 static CPUWriteMemoryFunc *omap3_sms_writefn[] = {
4384     omap_badwidth_write32,
4385     omap_badwidth_write32,
4386     omap3_sms_write32,
4387 };
4388
4389 static void omap3_sms_reset(struct omap3_sms_s *s)
4390 {
4391         s->sms_sysconfig = 0x1;
4392         s->sms_class_arbiter0 = 0x500000;
4393         s->sms_class_arbiter1 = 0x500;
4394         s->sms_class_arbiter2 = 0x55000;
4395         s->sms_interclass_arbiter = 0x400040;
4396         s->sms_class_rotation[0] = 0x1;
4397         s->sms_class_rotation[1] = 0x1;
4398         s->sms_class_rotation[2] = 0x1;
4399         s->sms_pow_ctrl = 0x80;
4400 }
4401
4402 static struct omap3_sms_s *omap3_sms_init(struct omap_mpu_state_s *mpu)
4403 {
4404     int iomemtype;
4405     struct omap3_sms_s *s = (struct omap3_sms_s *) qemu_mallocz(sizeof(*s));
4406
4407     s->mpu = mpu;
4408
4409     omap3_sms_reset(s);
4410     
4411     iomemtype = cpu_register_io_memory(0, omap3_sms_readfn,
4412                                        omap3_sms_writefn, s);
4413     cpu_register_physical_memory(0x6c000000, 0x10000, iomemtype);
4414
4415     register_savevm("omap3_sms", -1, 0,
4416                     omap3_sms_save_state, omap3_sms_load_state, s);
4417     return s;
4418 }
4419
4420 static const struct dma_irq_map omap3_dma_irq_map[] = {
4421     {0, OMAP_INT_3XXX_SDMA_IRQ0},
4422     {0, OMAP_INT_3XXX_SDMA_IRQ1},
4423     {0, OMAP_INT_3XXX_SDMA_IRQ2},
4424     {0, OMAP_INT_3XXX_SDMA_IRQ3},
4425 };
4426
4427 static int omap3_validate_addr(struct omap_mpu_state_s *s,
4428                                target_phys_addr_t addr)
4429 {
4430     return 1;
4431 }
4432
4433 struct omap_mpu_state_s *omap3530_mpu_init(unsigned long sdram_size,
4434                                            CharDriverState *chr_uart1,
4435                                            CharDriverState *chr_uart2,
4436                                            CharDriverState *chr_uart3)
4437 {
4438     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
4439         qemu_mallocz(sizeof(struct omap_mpu_state_s));
4440     ram_addr_t sram_base, q2_base, bootrom_base;
4441     qemu_irq *cpu_irq;
4442     qemu_irq drqs[4];
4443     int i;
4444
4445     s->mpu_model = omap3530;
4446     s->env = cpu_init("cortex-a8-r2");
4447     if (!s->env) {
4448         fprintf(stderr, "Unable to find CPU definition\n");
4449         exit(1);
4450     }
4451     s->sdram_size = sdram_size;
4452     s->sram_size = OMAP3XXX_SRAM_SIZE;
4453
4454     /* Clocks */
4455     omap_clk_init(s);
4456
4457     /* Memory-mapped stuff */
4458
4459     q2_base = qemu_ram_alloc(s->sdram_size);
4460     cpu_register_physical_memory(OMAP3_Q2_BASE, s->sdram_size,
4461                                  q2_base | IO_MEM_RAM);
4462     sram_base = qemu_ram_alloc(s->sram_size);
4463     cpu_register_physical_memory(OMAP3_SRAM_BASE, s->sram_size,
4464                                  sram_base | IO_MEM_RAM);
4465     bootrom_base = qemu_ram_alloc(OMAP3XXX_BOOTROM_SIZE);
4466     cpu_register_physical_memory(OMAP3_Q1_BASE + 0x14000,
4467                                  OMAP3XXX_BOOTROM_SIZE,
4468                                  bootrom_base | IO_MEM_ROM);
4469     cpu_register_physical_memory(0, OMAP3XXX_BOOTROM_SIZE,
4470                                  bootrom_base | IO_MEM_ROM);
4471
4472     s->l4 = omap_l4_init(OMAP3_L4_BASE, 
4473                          sizeof(omap3_l4_agent_info) 
4474                          / sizeof(struct omap3_l4_agent_info_s));
4475
4476     cpu_irq = arm_pic_init_cpu(s->env);
4477     s->ih[0] = omap2_inth_init(s, 0x48200000, 0x1000, 3, &s->irq[0],
4478                                cpu_irq[ARM_PIC_CPU_IRQ],
4479                                cpu_irq[ARM_PIC_CPU_FIQ], 
4480                                omap_findclk(s, "omap3_mpu_intc_fclk"),
4481                                omap_findclk(s, "omap3_mpu_intc_iclk"));
4482
4483     for (i = 0; i < 4; i++)
4484         drqs[i] = s->irq[omap3_dma_irq_map[i].ih][omap3_dma_irq_map[i].intr];
4485     s->dma = omap3_dma4_init(omap3_l4ta_init(s->l4, L4A_SDMA), s, drqs, 32,
4486                              omap_findclk(s, "omap3_sdma_fclk"),
4487                              omap_findclk(s, "omap3_sdma_iclk"));
4488     s->port->addr_valid = omap3_validate_addr;
4489     soc_dma_port_add_mem_ram(s->dma, q2_base, OMAP2_Q2_BASE, s->sdram_size);
4490     soc_dma_port_add_mem_ram(s->dma, sram_base, OMAP2_SRAM_BASE, s->sram_size);
4491
4492
4493     s->omap3_cm = omap3_cm_init(omap3_l4ta_init(s->l4, L4A_CM), NULL, NULL, NULL, s);
4494
4495     s->omap3_prm = omap3_prm_init(omap3_l4ta_init(s->l4, L4A_PRM),
4496                                   s->irq[0][OMAP_INT_3XXX_PRCM_MPU_IRQ],
4497                                   NULL, s);
4498
4499     s->omap3_mpu_wdt = omap3_mpu_wdt_init(omap3_l4ta_init(s->l4, L4A_WDTIMER2),
4500                                           NULL,
4501                                           omap_findclk(s, "omap3_wkup_32k_fclk"),
4502                                           omap_findclk(s, "omap3_wkup_l4_iclk"),
4503                                           s);
4504
4505     s->omap3_l3 = omap3_l3_init(OMAP3_L3_BASE, 
4506                                 omap3_l3_region,
4507                                 sizeof(omap3_l3_region)
4508                                 / sizeof(struct omap_l3_region_s));
4509     s->omap3_scm = omap3_scm_init(omap3_l4ta_init(s->l4, L4A_SCM), s);
4510
4511     s->omap3_sms = omap3_sms_init(s);
4512
4513     s->gptimer[0] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER1),
4514                                        s->irq[0][OMAP_INT_3XXX_GPT1_IRQ],
4515                                        omap_findclk(s, "omap3_gp1_fclk"),
4516                                        omap_findclk(s, "omap3_wkup_l4_iclk"));
4517     s->gptimer[1] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER2),
4518                                        s->irq[0][OMAP_INT_3XXX_GPT2_IRQ],
4519                                        omap_findclk(s, "omap3_gp2_fclk"),
4520                                        omap_findclk(s, "omap3_per_l4_iclk"));
4521     s->gptimer[2] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER3),
4522                                        s->irq[0][OMAP_INT_3XXX_GPT3_IRQ],
4523                                        omap_findclk(s, "omap3_gp3_fclk"),
4524                                        omap_findclk(s, "omap3_per_l4_iclk"));
4525     s->gptimer[3] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER4),
4526                                        s->irq[0][OMAP_INT_3XXX_GPT4_IRQ],
4527                                        omap_findclk(s, "omap3_gp4_fclk"),
4528                                        omap_findclk(s, "omap3_per_l4_iclk"));
4529     s->gptimer[4] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER5),
4530                                        s->irq[0][OMAP_INT_3XXX_GPT5_IRQ],
4531                                        omap_findclk(s, "omap3_gp5_fclk"),
4532                                        omap_findclk(s, "omap3_per_l4_iclk"));
4533     s->gptimer[5] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER6),
4534                                        s->irq[0][OMAP_INT_3XXX_GPT6_IRQ],
4535                                        omap_findclk(s, "omap3_gp6_fclk"),
4536                                        omap_findclk(s, "omap3_per_l4_iclk"));
4537     s->gptimer[6] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER7),
4538                                        s->irq[0][OMAP_INT_3XXX_GPT7_IRQ],
4539                                        omap_findclk(s, "omap3_gp7_fclk"),
4540                                        omap_findclk(s, "omap3_per_l4_iclk"));
4541     s->gptimer[7] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER8),
4542                                        s->irq[0][OMAP_INT_3XXX_GPT8_IRQ],
4543                                        omap_findclk(s, "omap3_gp8_fclk"),
4544                                        omap_findclk(s, "omap3_per_l4_iclk"));
4545     s->gptimer[8] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER9),
4546                                        s->irq[0][OMAP_INT_3XXX_GPT9_IRQ],
4547                                        omap_findclk(s, "omap3_gp9_fclk"),
4548                                        omap_findclk(s, "omap3_per_l4_iclk"));
4549     s->gptimer[9] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER10),
4550                                        s->irq[0][OMAP_INT_3XXX_GPT10_IRQ],
4551                                        omap_findclk(s, "omap3_gp10_fclk"),
4552                                        omap_findclk(s, "omap3_core_l4_iclk"));
4553     s->gptimer[10] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER11),
4554                                        s->irq[0][OMAP_INT_3XXX_GPT11_IRQ],
4555                                        omap_findclk(s, "omap3_gp12_fclk"),
4556                                        omap_findclk(s, "omap3_core_l4_iclk"));
4557     s->gptimer[11] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER12),
4558                                         s->irq[0][OMAP_INT_3XXX_GPT12_IRQ],
4559                                         omap_findclk(s, "omap3_gp12_fclk"),
4560                                         omap_findclk(s, "omap3_wkup_l4_iclk"));
4561     
4562         
4563     omap_synctimer_init(omap3_l4ta_init(s->l4, L4A_32KTIMER), s,
4564                         omap_findclk(s, "omap3_sys_32k"), NULL);
4565
4566     s->sdrc = omap_sdrc_init(0x6d000000);
4567     
4568     s->gpmc = omap_gpmc_init(s, 0x6e000000, s->irq[0][OMAP_INT_3XXX_GPMC_IRQ]);
4569     
4570
4571     s->uart[0] = omap2_uart_init(omap3_l4ta_init(s->l4, L4A_UART1),
4572                                  s->irq[0][OMAP_INT_3XXX_UART1_IRQ],
4573                                  omap_findclk(s, "omap3_uart1_fclk"),
4574                                  omap_findclk(s, "omap3_uart1_iclk"),
4575                                  s->drq[OMAP3XXX_DMA_UART1_TX],
4576                                  s->drq[OMAP3XXX_DMA_UART1_RX],
4577                                  chr_uart1);
4578     s->uart[1] = omap2_uart_init(omap3_l4ta_init(s->l4, L4A_UART2),
4579                                  s->irq[0][OMAP_INT_3XXX_UART2_IRQ],
4580                                  omap_findclk(s, "omap3_uart2_fclk"),
4581                                  omap_findclk(s, "omap3_uart2_iclk"),
4582                                  s->drq[OMAP3XXX_DMA_UART2_TX],
4583                                  s->drq[OMAP3XXX_DMA_UART2_RX],
4584                                  chr_uart2);
4585     s->uart[2] = omap2_uart_init(omap3_l4ta_init(s->l4, L4A_UART3),
4586                                  s->irq[0][OMAP_INT_3XXX_UART3_IRQ],
4587                                  omap_findclk(s, "omap3_uart2_fclk"),
4588                                  omap_findclk(s, "omap3_uart3_iclk"),
4589                                  s->drq[OMAP3XXX_DMA_UART3_TX],
4590                                  s->drq[OMAP3XXX_DMA_UART3_RX],
4591                                  chr_uart3);
4592     
4593     s->dss = omap_dss_init(s, omap3_l4ta_init(s->l4, L4A_DSS), 
4594                     s->irq[0][OMAP_INT_3XXX_DSS_IRQ], s->drq[OMAP24XX_DMA_DSS],
4595                    NULL,NULL,NULL,NULL,NULL);
4596
4597     s->gpif = omap3_gpif_init();
4598     omap3_gpio_init(s, s->gpif ,omap3_l4ta_init(s->l4, L4A_GPIO1),
4599                     &s->irq[0][OMAP_INT_3XXX_GPIO1_MPU_IRQ], 
4600                     NULL,NULL,0);
4601     omap3_gpio_init(s, s->gpif ,omap3_l4ta_init(s->l4, L4A_GPIO2),
4602                     &s->irq[0][OMAP_INT_3XXX_GPIO2_MPU_IRQ], 
4603                     NULL,NULL,1);
4604     omap3_gpio_init(s, s->gpif ,omap3_l4ta_init(s->l4, L4A_GPIO3),
4605                     &s->irq[0][OMAP_INT_3XXX_GPIO3_MPU_IRQ], 
4606                     NULL,NULL,2);
4607     omap3_gpio_init(s, s->gpif ,omap3_l4ta_init(s->l4, L4A_GPIO4),
4608                     &s->irq[0][OMAP_INT_3XXX_GPIO4_MPU_IRQ], 
4609                     NULL,NULL,3);
4610     omap3_gpio_init(s, s->gpif ,omap3_l4ta_init(s->l4, L4A_GPIO5),
4611                     &s->irq[0][OMAP_INT_3XXX_GPIO5_MPU_IRQ], 
4612                     NULL,NULL,4);
4613     omap3_gpio_init(s, s->gpif ,omap3_l4ta_init(s->l4, L4A_GPIO6),
4614                     &s->irq[0][OMAP_INT_3XXX_GPIO6_MPU_IRQ], 
4615                     NULL,NULL,5);
4616
4617     omap_tap_init(omap3_l4ta_init(s->l4, L4A_TAP), s);
4618
4619     s->omap3_mmc[0] = omap3_mmc_init(omap3_l4ta_init(s->l4, L4A_MMC1),
4620                                      s->irq[0][OMAP_INT_3XXX_MMC1_IRQ],
4621                                      &s->drq[OMAP3XXX_DMA_MMC1_TX],
4622                                      omap_findclk(s, "omap3_mmc1_fclk"),
4623                                      omap_findclk(s, "omap3_mmc1_iclk"));
4624
4625     s->omap3_mmc[1] = omap3_mmc_init(omap3_l4ta_init(s->l4, L4A_MMC2),
4626                                      s->irq[0][OMAP_INT_3XXX_MMC2_IRQ],
4627                                      &s->drq[OMAP3XXX_DMA_MMC2_TX],
4628                                      omap_findclk(s, "omap3_mmc2_fclk"),
4629                                      omap_findclk(s, "omap3_mmc2_iclk"));
4630
4631     s->omap3_mmc[2] = omap3_mmc_init(omap3_l4ta_init(s->l4, L4A_MMC3),
4632                                      s->irq[0][OMAP_INT_3XXX_MMC3_IRQ],
4633                                      &s->drq[OMAP3XXX_DMA_MMC3_TX],
4634                                      omap_findclk(s, "omap3_mmc3_fclk"),
4635                                      omap_findclk(s, "omap3_mmc3_iclk"));
4636
4637     s->i2c[0] = omap3_i2c_init(omap3_l4ta_init(s->l4, L4A_I2C1),
4638                                s->irq[0][OMAP_INT_3XXX_I2C1_IRQ],
4639                                &s->drq[OMAP3XXX_DMA_I2C1_TX],
4640                                omap_findclk(s, "omap3_i2c1_fclk"),
4641                                omap_findclk(s, "omap3_i2c1_iclk"),
4642                                8);
4643     s->i2c[1] = omap3_i2c_init(omap3_l4ta_init(s->l4, L4A_I2C2),
4644                                s->irq[0][OMAP_INT_3XXX_I2C2_IRQ],
4645                                &s->drq[OMAP3XXX_DMA_I2C2_TX],
4646                                omap_findclk(s, "omap3_i2c2_fclk"),
4647                                omap_findclk(s, "omap3_i2c2_iclk"),
4648                                8);
4649     s->i2c[2] = omap3_i2c_init(omap3_l4ta_init(s->l4, L4A_I2C3),
4650                                s->irq[0][OMAP_INT_3XXX_I2C3_IRQ],
4651                                &s->drq[OMAP3XXX_DMA_I2C3_TX],
4652                                omap_findclk(s, "omap3_i2c3_fclk"),
4653                                omap_findclk(s, "omap3_i2c3_iclk"),
4654                                64);
4655
4656     s->omap3_usb = omap3_hsusb_init(omap3_l4ta_init(s->l4, L4A_USBHS_OTG),
4657                                     omap3_l4ta_init(s->l4, L4A_USBHS_HOST),
4658                                     omap3_l4ta_init(s->l4, L4A_USBHS_TLL),
4659                                     s->irq[0][OMAP_INT_3XXX_HSUSB_MC],
4660                                     s->irq[0][OMAP_INT_3XXX_HSUSB_DMA],
4661                                     s->irq[0][OMAP_INT_3XXX_OHCI_IRQ],
4662                                     s->irq[0][OMAP_INT_3XXX_EHCI_IRQ],
4663                                     s->irq[0][OMAP_INT_3XXX_TLL_IRQ]);
4664
4665     s->mcspi[0] = omap_mcspi_init(omap3_l4ta_init(s->l4, L4A_MCSPI1), 4,
4666                                   s->irq[0][OMAP_INT_3XXX_MCSPI1_IRQ],
4667                                   &s->drq[OMAP3XXX_DMA_SPI1_TX0],
4668                                   omap_findclk(s, "omap3_spi1_fclk"),
4669                                   omap_findclk(s, "omap3_spi1_iclk"));
4670     s->mcspi[1] = omap_mcspi_init(omap3_l4ta_init(s->l4, L4A_MCSPI2), 2,
4671                                   s->irq[0][OMAP_INT_3XXX_MCSPI2_IRQ],
4672                                   &s->drq[OMAP3XXX_DMA_SPI2_TX0],
4673                                   omap_findclk(s, "omap3_spi2_fclk"),
4674                                   omap_findclk(s, "omap3_spi2_iclk"));
4675     drqs[0] = s->drq[OMAP3XXX_DMA_SPI3_TX0];
4676     drqs[1] = s->drq[OMAP3XXX_DMA_SPI3_RX0];
4677     drqs[2] = s->drq[OMAP3XXX_DMA_SPI3_TX1];
4678     drqs[3] = s->drq[OMAP3XXX_DMA_SPI3_RX1];
4679     s->mcspi[2] = omap_mcspi_init(omap3_l4ta_init(s->l4, L4A_MCSPI3), 2,
4680                                   s->irq[0][OMAP_INT_3XXX_MCSPI3_IRQ],
4681                                   drqs,
4682                                   omap_findclk(s, "omap3_spi3_fclk"),
4683                                   omap_findclk(s, "omap3_spi3_iclk"));
4684     s->mcspi[3] = omap_mcspi_init(omap3_l4ta_init(s->l4, L4A_MCSPI4), 1,
4685                                   s->irq[0][OMAP_INT_3XXX_MCSPI4_IRQ],
4686                                   &s->drq[OMAP3XXX_DMA_SPI4_TX0],
4687                                   omap_findclk(s, "omap3_spi4_fclk"),
4688                                   omap_findclk(s, "omap3_spi4_iclk"));
4689     
4690     return s;
4691 }