add savevm support in several modules
[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 } omap3_l4_agent_info_id_t;
1217
1218 struct omap3_l4_agent_info_s {
1219     omap3_l4_agent_info_id_t agent_id;
1220     omap3_l4_region_id_t     first_region_id;
1221     int                      region_count;
1222 };
1223
1224 static const struct omap3_l4_agent_info_s omap3_l4_agent_info[] = {
1225     /* L4-Core Agents */
1226     {L4A_DSS,        L4ID_DSI,       6},
1227     /* TODO: camera */
1228     {L4A_USBHS_OTG,  L4ID_HSUSBOTG,  2},
1229     {L4A_USBHS_HOST, L4ID_HSUSBHOST, 2},
1230     {L4A_USBHS_TLL,  L4ID_USBTLL,    2},
1231     {L4A_UART1,      L4ID_UART1,     2},
1232     {L4A_UART2,      L4ID_UART2,     2},
1233     {L4A_I2C1,       L4ID_I2C1,      2},
1234     {L4A_I2C2,       L4ID_I2C2,      2},
1235     {L4A_I2C3,       L4ID_I2C3,      2},
1236     /* TODO: McBSP1 */
1237     /* TODO: McBSP5 */
1238     {L4A_GPTIMER10,  L4ID_GPTIMER10, 2},
1239     {L4A_GPTIMER11,  L4ID_GPTIMER11, 2},
1240     /* TODO: SPI1 */
1241     /* TODO: SPI2 */
1242     {L4A_MMC1,       L4ID_MMCSDIO1,  2},
1243     {L4A_MMC2,       L4ID_MMCSDIO2,  2},
1244     {L4A_MMC3,       L4ID_MMCSDIO3,  2},
1245     /* TODO: HDQ/1-Wire */
1246     /* TODO: Mailbox */
1247     /* TODO: SPI3 */
1248     /* TODO: SPI4 */
1249     /* TODO: SDMA */
1250     {L4A_CM,         L4ID_CM_A,      3},
1251     {L4A_SCM,        L4ID_SCM,       2},
1252     {L4A_TAP,        L4ID_TAP,       2},
1253     /* L4-Wakeup Agents */
1254     {L4A_GPTIMER12,  L4ID_GPTIMER12, 2},
1255     {L4A_PRM,        L4ID_PRM_A,     3},
1256     {L4A_GPIO1,      L4ID_GPIO1,     2},
1257     {L4A_WDTIMER2,   L4ID_WDTIMER2,  2},
1258     {L4A_GPTIMER1,   L4ID_GPTIMER1,  2},
1259     {L4A_32KTIMER,   L4ID_32KTIMER,  2},
1260     /* L4-Per Agents */
1261     {L4A_UART3,      L4ID_UART3,     2},
1262     /* TODO: McBSP2 */
1263     /* TODO: McBSP3 */
1264     {L4A_GPTIMER2,   L4ID_GPTIMER2,  2},
1265     {L4A_GPTIMER3,   L4ID_GPTIMER3,  2},
1266     {L4A_GPTIMER4,   L4ID_GPTIMER4,  2},
1267     {L4A_GPTIMER5,   L4ID_GPTIMER5,  2},
1268     {L4A_GPTIMER6,   L4ID_GPTIMER6,  2},
1269     {L4A_GPTIMER7,   L4ID_GPTIMER7,  2},
1270     {L4A_GPTIMER8,   L4ID_GPTIMER8,  2},
1271     {L4A_GPTIMER9,   L4ID_GPTIMER9,  2},
1272     {L4A_GPIO2,      L4ID_GPIO2,     2},
1273     {L4A_GPIO3,      L4ID_GPIO3,     2},
1274     {L4A_GPIO4,      L4ID_GPIO4,     2},
1275     {L4A_GPIO5,      L4ID_GPIO5,     2},
1276     {L4A_GPIO6,      L4ID_GPIO6,     2},
1277 };
1278
1279 static uint32_t omap3_l4ta_read(void *opaque, target_phys_addr_t addr)
1280 {
1281     struct omap_target_agent_s *s = (struct omap_target_agent_s *)opaque;
1282     
1283     switch (addr) {
1284         case 0x00: /* COMPONENT_L */
1285             return s->component;
1286         case 0x04: /* COMPONENT_H */
1287             return 0;
1288         case 0x18: /* CORE_L */
1289             return s->component;
1290         case 0x1c: /* CORE_H */
1291             return (s->component >> 16);
1292         case 0x20: /* AGENT_CONTROL_L */
1293             return s->control;
1294         case 0x24: /* AGENT_CONTROL_H */
1295             return s->control_h;
1296         case 0x28: /* AGENT_STATUS_L */
1297             return s->status;
1298         case 0x2c: /* AGENT_STATUS_H */
1299             return 0;
1300         default:
1301             break;
1302     }
1303     
1304     OMAP_BAD_REG(s->base + addr);
1305     return 0;
1306 }
1307
1308 static void omap3_l4ta_write(void *opaque, target_phys_addr_t addr,
1309                              uint32_t value)
1310 {
1311     struct omap_target_agent_s *s = (struct omap_target_agent_s *)opaque;
1312     
1313     switch (addr) {
1314         case 0x00: /* COMPONENT_L */
1315         case 0x04: /* COMPONENT_H */
1316         case 0x18: /* CORE_L */
1317         case 0x1c: /* CORE_H */
1318             OMAP_RO_REG(s->base + addr);
1319             break;
1320         case 0x20: /* AGENT_CONTROL_L */
1321             s->control = value & 0x00000701;
1322             break;
1323         case 0x24: /* AGENT_CONTROL_H */
1324             s->control_h = value & 0x100; /* TODO: shouldn't this be read-only? */
1325             break;
1326         case 0x28: /* AGENT_STATUS_L */
1327             if (value & 0x100)
1328                 s->status &= ~0x100; /* REQ_TIMEOUT */
1329             break;
1330         case 0x2c: /* AGENT_STATUS_H */
1331             /* no writable bits although the register is listed as RW */
1332             break;
1333         default:
1334             OMAP_BAD_REG(s->base + addr);
1335             break;
1336     }
1337 }
1338
1339 static void omap3_l4ta_save_state(QEMUFile *f, void *opaque)
1340 {
1341     struct omap_target_agent_s *s = (struct omap_target_agent_s *)opaque;
1342     
1343     qemu_put_be32(f, s->control);
1344     qemu_put_be32(f, s->control_h);
1345     qemu_put_be32(f, s->status);
1346 }
1347
1348 static int omap3_l4ta_load_state(QEMUFile *f, void *opaque, int version_id)
1349 {
1350     struct omap_target_agent_s *s = (struct omap_target_agent_s *)opaque;
1351     
1352     if (version_id)
1353         return -EINVAL;
1354     
1355     s->control = qemu_get_be32(f);
1356     s->control_h = qemu_get_be32(f);
1357     s->status = qemu_get_be32(f);
1358     
1359     return 0;
1360 }
1361
1362 static CPUReadMemoryFunc *omap3_l4ta_readfn[] = {
1363     omap_badwidth_read32,
1364     omap_badwidth_read32,
1365     omap3_l4ta_read,
1366 };
1367
1368 static CPUWriteMemoryFunc *omap3_l4ta_writefn[] = {
1369     omap_badwidth_write32,
1370     omap_badwidth_write32,
1371     omap3_l4ta_write,
1372 };
1373
1374 static struct omap_target_agent_s *omap3_l4ta_init(struct omap_l4_s *bus, int cs)
1375 {
1376     int i, iomemtype;
1377     struct omap_target_agent_s *ta = 0;
1378     const struct omap3_l4_agent_info_s *info = 0;
1379
1380     for (i = 0; i < bus->ta_num; i++)
1381         if (omap3_l4_agent_info[i].agent_id == cs) {
1382             ta = &bus->ta[i];
1383             info = &omap3_l4_agent_info[i];
1384             break;
1385         }
1386     if (!ta) {
1387         fprintf(stderr, "%s: invalid agent id (%i)\n", __FUNCTION__, cs);
1388         exit(-1);
1389     }
1390     if (ta->bus) {
1391         fprintf(stderr, "%s: target agent (%d) already initialized\n",
1392                 __FUNCTION__, cs);
1393         exit(-1);
1394     }
1395
1396     ta->bus = bus;
1397     ta->start = &omap3_l4_region[info->first_region_id];
1398     ta->regions = info->region_count;
1399
1400     ta->component = ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
1401     ta->status = 0x00000000;
1402     ta->control = 0x00000200;
1403
1404     for (i = 0; i < info->region_count; i++)
1405         if (omap3_l4_region[info->first_region_id + i].access == L4TYPE_TA)
1406             break;
1407     if (i >= info->region_count) {
1408         fprintf(stderr, "%s: specified agent (%d) has no TA region\n",
1409                 __FUNCTION__, cs);
1410         exit(-1);
1411     }
1412     
1413     iomemtype = l4_register_io_memory(0, omap3_l4ta_readfn,
1414                                       omap3_l4ta_writefn, ta);
1415     ta->base = omap_l4_attach(ta, i, iomemtype);
1416
1417     register_savevm("omap3_l4ta", ta->base >> 8, 0,
1418                     omap3_l4ta_save_state, omap3_l4ta_load_state, ta);
1419
1420     return ta;
1421 }
1422
1423 /* common PRM domain registers */
1424 struct omap3_prm_domain_s {
1425     uint32_t rm_rstctrl;     /* 50 */
1426     uint32_t rm_rstst;       /* 58 */
1427     uint32_t pm_wken;        /* a0 */
1428     uint32_t pm_mpugrpsel;   /* a4 */
1429     uint32_t pm_ivagrpsel;   /* a8 */
1430     uint32_t pm_wkst;        /* b0 */
1431     uint32_t pm_wkst3;       /* b8 */
1432     uint32_t pm_wkdep;       /* c8 */
1433     uint32_t pm_evgenctrl;   /* d4 */
1434     uint32_t pm_evgenontim;  /* d8 */
1435     uint32_t pm_evgenofftim; /* dc */
1436     uint32_t pm_pwstctrl;    /* e0 */
1437     uint32_t pm_pwstst;      /* e4 */
1438     uint32_t pm_prepwstst;   /* e8 */
1439     uint32_t pm_wken3;       /* f0 */
1440 };
1441
1442 struct omap3_prm_s {
1443     qemu_irq mpu_irq;
1444     qemu_irq iva_irq;
1445     struct omap_mpu_state_s *omap;
1446
1447     struct omap3_prm_domain_s iva2;
1448     struct omap3_prm_domain_s mpu;
1449     struct omap3_prm_domain_s core;
1450     struct omap3_prm_domain_s sgx;
1451     struct omap3_prm_domain_s wkup;
1452     struct omap3_prm_domain_s dss;
1453     struct omap3_prm_domain_s cam;
1454     struct omap3_prm_domain_s per;
1455     struct omap3_prm_domain_s emu;
1456     struct omap3_prm_domain_s neon;
1457     struct omap3_prm_domain_s usbhost;
1458
1459     uint32_t prm_irqstatus_iva2;
1460     uint32_t prm_irqenable_iva2;
1461     
1462     uint32_t pm_iva2grpsel3_core;
1463     uint32_t pm_mpugrpsel3_core;
1464
1465     struct {
1466         uint32_t prm_revision;
1467         uint32_t prm_sysconfig;
1468         uint32_t prm_irqstatus_mpu;
1469         uint32_t prm_irqenable_mpu;
1470     } ocp;
1471
1472     struct {
1473         uint32_t prm_clksel;
1474         uint32_t prm_clkout_ctrl;
1475     } ccr; /* clock_control_reg */
1476
1477     struct {
1478         uint32_t prm_vc_smps_sa;
1479         uint32_t prm_vc_smps_vol_ra;
1480         uint32_t prm_vc_smps_cmd_ra;
1481         uint32_t prm_vc_cmd_val_0;
1482         uint32_t prm_vc_cmd_val_1;
1483         uint32_t prm_vc_hc_conf;
1484         uint32_t prm_vc_i2c_cfg;
1485         uint32_t prm_vc_bypass_val;
1486         uint32_t prm_rstctrl;
1487         uint32_t prm_rsttimer;
1488         uint32_t prm_rstst;
1489         uint32_t prm_voltctrl;
1490         uint32_t prm_sram_pcharge;
1491         uint32_t prm_clksrc_ctrl;
1492         uint32_t prm_obs;
1493         uint32_t prm_voltsetup1;
1494         uint32_t prm_voltoffset;
1495         uint32_t prm_clksetup;
1496         uint32_t prm_polctrl;
1497         uint32_t prm_voltsetup2;
1498     } gr; /* global_reg */
1499 };
1500
1501 static void omap3_prm_int_update(struct omap3_prm_s *s)
1502 {
1503     qemu_set_irq(s->mpu_irq, s->ocp.prm_irqstatus_mpu & s->ocp.prm_irqenable_mpu);
1504     qemu_set_irq(s->iva_irq, s->prm_irqstatus_iva2 & s->prm_irqenable_iva2);
1505 }
1506
1507 static void omap3_prm_reset(struct omap3_prm_s *s)
1508 {
1509     bzero(&s->iva2, sizeof(s->iva2));
1510     s->iva2.rm_rstctrl    = 0x7;
1511     s->iva2.rm_rstst      = 0x1;
1512     s->iva2.pm_wkdep      = 0xb3;
1513     s->iva2.pm_pwstctrl   = 0xff0f07;
1514     s->iva2.pm_pwstst     = 0xff7;
1515     s->prm_irqstatus_iva2 = 0x0;
1516     s->prm_irqenable_iva2 = 0x0;
1517
1518     bzero(&s->ocp, sizeof(s->ocp));
1519     s->ocp.prm_revision      = 0x10;
1520     s->ocp.prm_sysconfig     = 0x1;
1521     
1522     bzero(&s->mpu, sizeof(s->mpu));
1523     s->mpu.rm_rstst       = 0x1;
1524     s->mpu.pm_wkdep       = 0xa5;
1525     s->mpu.pm_pwstctrl    = 0x30107;
1526     s->mpu.pm_pwstst      = 0xc7;
1527     s->mpu.pm_evgenctrl   = 0x12;
1528
1529     bzero(&s->core, sizeof(s->core));
1530     s->core.rm_rstst       = 0x1;
1531     s->core.pm_wken        = 0xc33ffe18;
1532     s->core.pm_mpugrpsel   = 0xc33ffe18;
1533     s->core.pm_ivagrpsel   = 0xc33ffe18;
1534     s->core.pm_pwstctrl    = 0xf0307;
1535     s->core.pm_pwstst      = 0xf7;
1536     s->core.pm_wken3       = 0x4;
1537     s->pm_iva2grpsel3_core = 0x4;
1538     s->pm_mpugrpsel3_core  = 0x4;
1539
1540     bzero(&s->sgx, sizeof(s->sgx));
1541     s->sgx.rm_rstst     = 0x1;
1542     s->sgx.pm_wkdep     = 0x16;
1543     s->sgx.pm_pwstctrl  = 0x30107;
1544     s->sgx.pm_pwstst    = 0x3;
1545
1546     bzero(&s->wkup, sizeof(s->wkup));
1547     s->wkup.pm_wken      = 0x3cb;
1548     s->wkup.pm_mpugrpsel = 0x3cb;
1549     s->wkup.pm_pwstst    = 0x3; /* TODO: check on real hardware */
1550
1551     bzero(&s->ccr, sizeof(s->ccr));
1552     s->ccr.prm_clksel      = 0x3; /* TRM says 0x4, but on HW this is 0x3 */
1553     s->ccr.prm_clkout_ctrl = 0x80;
1554
1555     bzero(&s->dss, sizeof(s->dss));
1556     s->dss.rm_rstst     = 0x1;
1557     s->dss.pm_wken      = 0x1;
1558     s->dss.pm_wkdep     = 0x16;
1559     s->dss.pm_pwstctrl  = 0x30107;
1560     s->dss.pm_pwstst    = 0x3;
1561
1562     bzero(&s->cam, sizeof(s->cam));
1563     s->cam.rm_rstst     = 0x1;
1564     s->cam.pm_wkdep     = 0x16;
1565     s->cam.pm_pwstctrl  = 0x30107;
1566     s->cam.pm_pwstst    = 0x3;
1567
1568     bzero(&s->per, sizeof(s->per));
1569     s->per.rm_rstst     = 0x1;
1570     s->per.pm_wken      = 0x3efff;
1571     s->per.pm_mpugrpsel = 0x3efff;
1572     s->per.pm_ivagrpsel = 0x3efff;
1573     s->per.pm_wkdep     = 0x17;
1574     s->per.pm_pwstctrl  = 0x30107;
1575     s->per.pm_pwstst    = 0x7;
1576
1577     bzero(&s->emu, sizeof(s->emu));
1578     s->emu.rm_rstst  = 0x1;
1579     s->emu.pm_pwstst = 0x13;
1580
1581     bzero(&s->gr, sizeof(s->gr));
1582     s->gr.prm_vc_i2c_cfg     = 0x18;
1583     s->gr.prm_rsttimer       = 0x1006;
1584     s->gr.prm_rstst          = 0x1;
1585     s->gr.prm_sram_pcharge   = 0x50;
1586     s->gr.prm_clksrc_ctrl    = 0x43;
1587     s->gr.prm_polctrl        = 0xa;
1588
1589     bzero(&s->neon, sizeof(s->neon));
1590     s->neon.rm_rstst     = 0x1;
1591     s->neon.pm_wkdep     = 0x2;
1592     s->neon.pm_pwstctrl  = 0x7;
1593     s->neon.pm_pwstst    = 0x3;
1594
1595     bzero(&s->usbhost, sizeof(s->usbhost));
1596     s->usbhost.rm_rstst     = 0x1;
1597     s->usbhost.pm_wken      = 0x1;
1598     s->usbhost.pm_mpugrpsel = 0x1;
1599     s->usbhost.pm_ivagrpsel = 0x1;
1600     s->usbhost.pm_wkdep     = 0x17;
1601     s->usbhost.pm_pwstctrl  = 0x30107;
1602     s->usbhost.pm_pwstst    = 0x3;
1603
1604     omap3_prm_int_update(s);
1605 }
1606
1607 static uint32_t omap3_prm_read(void *opaque, target_phys_addr_t addr)
1608 {
1609     struct omap3_prm_s *s = (struct omap3_prm_s *)opaque;
1610     struct omap3_prm_domain_s *d = 0;
1611
1612     TRACE("%04x", addr);
1613     
1614     /* handle common domain registers first - all domains may not
1615        have all common registers though but we're returning zeroes there */
1616     switch ((addr >> 8) & 0xff) {
1617         case 0x00: d = &s->iva2; break;
1618         case 0x09: d = &s->mpu; break;
1619         case 0x0a: d = &s->core; break;
1620         case 0x0b: d = &s->sgx; break;
1621         case 0x0c: d = &s->wkup; break;
1622         case 0x0e: d = &s->dss; break;
1623         case 0x0f: d = &s->cam; break;
1624         case 0x10: d = &s->per; break;
1625         case 0x11: d = &s->emu; break;
1626         case 0x13: d = &s->neon; break;
1627         case 0x14: d = &s->usbhost; break;
1628         default: break;
1629     }
1630     if (d)
1631         switch (addr & 0xff) {
1632             case 0x50: return d->rm_rstctrl;
1633             case 0x58: return d->rm_rstst;
1634             case 0xa0: return d->pm_wken;
1635             case 0xa4: return d->pm_mpugrpsel;
1636             case 0xa8: return d->pm_ivagrpsel;
1637             case 0xb0: return d->pm_wkst;
1638             case 0xb8: return d->pm_wkst3;
1639             case 0xc8: return d->pm_wkdep;
1640             case 0xd4: return d->pm_evgenctrl;
1641             case 0xd8: return d->pm_evgenontim;
1642             case 0xdc: return d->pm_evgenofftim;
1643             case 0xe0: return d->pm_pwstctrl;
1644             case 0xe4: return d->pm_pwstst;
1645             case 0xe8: return d->pm_prepwstst;
1646             case 0xf0: return d->pm_wken3;
1647             default: break;
1648         }
1649
1650     /* okay, not a common domain register so let's take a closer look */
1651     switch (addr) {
1652         case 0x00f8: return s->prm_irqstatus_iva2;
1653         case 0x00fc: return s->prm_irqenable_iva2;
1654         case 0x0804: return s->ocp.prm_revision;
1655         case 0x0814: return s->ocp.prm_sysconfig;
1656         case 0x0818: return s->ocp.prm_irqstatus_mpu;
1657         case 0x081c: return s->ocp.prm_irqenable_mpu;
1658         case 0x0af4: return s->pm_iva2grpsel3_core;
1659         case 0x0af8: return s->pm_mpugrpsel3_core;
1660         case 0x0d40: return s->ccr.prm_clksel;
1661         case 0x0d70: return s->ccr.prm_clkout_ctrl;
1662         case 0x0de4: return 0x3; /* TODO: check on real hardware */
1663         case 0x1220: return s->gr.prm_vc_smps_sa;
1664         case 0x1224: return s->gr.prm_vc_smps_vol_ra;
1665         case 0x1228: return s->gr.prm_vc_smps_cmd_ra;
1666         case 0x122c: return s->gr.prm_vc_cmd_val_0;
1667         case 0x1230: return s->gr.prm_vc_cmd_val_1;
1668         case 0x1234: return s->gr.prm_vc_hc_conf;
1669         case 0x1238: return s->gr.prm_vc_i2c_cfg;
1670         case 0x123c: return s->gr.prm_vc_bypass_val;
1671         case 0x1250: return s->gr.prm_rstctrl;
1672         case 0x1254: return s->gr.prm_rsttimer;
1673         case 0x1258: return s->gr.prm_rstst;
1674         case 0x1260: return s->gr.prm_voltctrl;
1675         case 0x1264: return s->gr.prm_sram_pcharge;     
1676         case 0x1270: return s->gr.prm_clksrc_ctrl;
1677         case 0x1280: return s->gr.prm_obs;
1678         case 0x1290: return s->gr.prm_voltsetup1;
1679         case 0x1294: return s->gr.prm_voltoffset;
1680         case 0x1298: return s->gr.prm_clksetup;
1681         case 0x129c: return s->gr.prm_polctrl;
1682         case 0x12a0: return s->gr.prm_voltsetup2;
1683         default: break;
1684     }
1685
1686     OMAP_BAD_REG(addr);
1687     return 0;
1688 }
1689
1690 static inline void omap3_prm_clksrc_ctrl_update(struct omap3_prm_s *s)
1691 {
1692     uint32_t value = s->gr.prm_clksrc_ctrl;
1693     
1694     if ((value & 0xd0) == 0x40)
1695         omap_clk_setrate(omap_findclk(s->omap, "omap3_sys_clk"), 1, 1);
1696     else if ((value & 0xd0) == 0x80)
1697         omap_clk_setrate(omap_findclk(s->omap, "omap3_sys_clk"), 2, 1);
1698 }
1699
1700 static void omap3_prm_clksel_update(struct omap3_prm_s *s)
1701 {
1702     omap_clk newparent = 0;
1703     
1704     switch (s->ccr.prm_clksel & 7) {
1705         case 0: newparent = omap_findclk(s->omap, "omap3_osc_sys_clk12"); break;
1706         case 1: newparent = omap_findclk(s->omap, "omap3_osc_sys_clk13"); break;
1707         case 2: newparent = omap_findclk(s->omap, "omap3_osc_sys_clk192"); break;
1708         case 3: newparent = omap_findclk(s->omap, "omap3_osc_sys_clk26"); break;
1709         case 4: newparent = omap_findclk(s->omap, "omap3_osc_sys_clk384"); break;
1710         case 5: newparent = omap_findclk(s->omap, "omap3_osc_sys_clk168"); break;
1711         default:
1712             fprintf(stderr, "%s: invalid sys_clk input selection (%d) - ignored\n",
1713                     __FUNCTION__, s->ccr.prm_clksel & 7);
1714             break;
1715     }
1716     if (newparent) {
1717         omap_clk_reparent(omap_findclk(s->omap, "omap3_sys_clk"), newparent);
1718         omap_clk_reparent(omap_findclk(s->omap, "omap3_sys_clkout1"), newparent);
1719     }
1720 }
1721
1722 static void omap3_prm_write(void *opaque, target_phys_addr_t addr,
1723                             uint32_t value)
1724 {
1725     struct omap3_prm_s *s = (struct omap3_prm_s *)opaque;
1726
1727     TRACE("%04x = %08x", addr, value);
1728     switch (addr) {
1729         /* IVA2_PRM */
1730         case 0x0050: s->iva2.rm_rstctrl = value & 0x7; break;
1731         case 0x0058: s->iva2.rm_rstst &= ~(value & 0x3f0f); break;
1732         case 0x00c8: s->iva2.pm_wkdep = value & 0xb3; break;
1733         case 0x00e0: s->iva2.pm_pwstctrl = 0xcff000 | (value & 0x300f0f); break;
1734         case 0x00e4: OMAP_RO_REG(addr); break;
1735         case 0x00e8: s->iva2.pm_prepwstst = value & 0xff7;
1736         case 0x00f8:
1737             s->prm_irqstatus_iva2 &= ~(value & 0x7);
1738             omap3_prm_int_update(s);
1739             break;
1740         case 0x00fc:
1741             s->prm_irqenable_iva2 = value & 0x7;
1742             omap3_prm_int_update(s);
1743             break;
1744         /* OCP_System_Reg_PRM */
1745         case 0x0804: OMAP_RO_REG(addr); break;
1746         case 0x0814: s->ocp.prm_sysconfig = value & 0x1; break;
1747         case 0x0818:
1748             s->ocp.prm_irqstatus_mpu &= ~(value & 0x03c003fd);
1749             omap3_prm_int_update(s);
1750             break;
1751         case 0x081c:
1752             s->ocp.prm_irqenable_mpu = value & 0x03c003fd;
1753             omap3_prm_int_update(s);
1754             break;
1755         /* MPU_PRM */
1756         case 0x0958: s->mpu.rm_rstst &= ~(value & 0x080f); break;
1757         case 0x09c8: s->mpu.pm_wkdep = value & 0xa5; break;
1758         case 0x09d4: s->mpu.pm_evgenctrl = value & 0x1f; break;
1759         case 0x09d8: s->mpu.pm_evgenontim = value; break;
1760         case 0x09dc: s->mpu.pm_evgenofftim = value; break;
1761         case 0x09e0: s->mpu.pm_pwstctrl = value & 0x3010f; break;
1762         case 0x09e4: OMAP_RO_REG(addr); break;
1763         case 0x09e8: s->mpu.pm_prepwstst = value & 0xc7; break;
1764         /* CORE_PRM */
1765         case 0x0a50: s->core.rm_rstctrl = value & 0x3; break; /* TODO: check if available on real hw */
1766         case 0x0a58: s->core.rm_rstst &= ~(value & 0x7); break;
1767         case 0x0aa0: s->core.pm_wken = 0x80000008 | (value & 0x433ffe10); break;
1768         case 0x0aa4: s->core.pm_mpugrpsel = 0x80000008 | (value & 0x433ffe10); break;
1769         case 0x0aa8: s->core.pm_ivagrpsel = 0x80000008 | (value & 0x433ffe10); break;
1770         case 0x0ab0: s->core.pm_wkst = value & 0x433ffe10; break;
1771         case 0x0ab8: s->core.pm_wkst3 &= ~(value & 0x4); break;
1772         case 0x0ae0: s->core.pm_pwstctrl = (value & 0x0f031f); break;
1773         case 0x0ae4: OMAP_RO_REG(addr); break;
1774         case 0x0ae8: s->core.pm_prepwstst = value & 0xf7; break;
1775         case 0x0af0: s->core.pm_wken3 = value & 0x4; break;
1776         case 0x0af4: s->pm_iva2grpsel3_core = value & 0x4; break;
1777         case 0x0af8: s->pm_mpugrpsel3_core = value & 0x4; break;
1778         /* SGX_PRM */
1779         case 0x0b58: s->sgx.rm_rstst &= ~(value & 0xf); break;
1780         case 0x0bc8: s->sgx.pm_wkdep = value & 0x16; break;
1781         case 0x0be0: s->sgx.pm_pwstctrl = 0x030104 | (value & 0x3); break;
1782         case 0x0be4: OMAP_RO_REG(addr); break;
1783         case 0x0be8: s->sgx.pm_prepwstst = value & 0x3; break;
1784         /* WKUP_PRM */
1785         case 0x0ca0: s->wkup.pm_wken = 0x2 | (value & 0x0103c9); break;
1786         case 0x0ca4: s->wkup.pm_mpugrpsel = 0x0102 | (value & 0x02c9); break;
1787         case 0x0ca8: s->wkup.pm_ivagrpsel = value & 0x03cb; break;
1788         case 0x0cb0: s->wkup.pm_wkst &= ~(value & 0x0103cb); break;
1789         /* Clock_Control_Reg_PRM */
1790         case 0x0d40: 
1791             s->ccr.prm_clksel = value & 0x7;
1792             omap3_prm_clksel_update(s);
1793             break;
1794         case 0x0d70:
1795             s->ccr.prm_clkout_ctrl = value & 0x80;
1796             omap_clk_onoff(omap_findclk(s->omap, "omap3_sys_clkout1"),
1797                            s->ccr.prm_clkout_ctrl & 0x80);
1798             break;
1799         /* DSS_PRM */
1800         case 0x0e58: s->dss.rm_rstst &= ~(value & 0xf); break;
1801         case 0x0ea0: s->dss.pm_wken = value & 1; break;
1802         case 0x0ec8: s->dss.pm_wkdep = value & 0x16; break;
1803         case 0x0ee0: s->dss.pm_pwstctrl = 0x030104 | (value & 3); break;
1804         case 0x0ee4: OMAP_RO_REG(addr); break;
1805         case 0x0ee8: s->dss.pm_prepwstst = value & 3; break;
1806         /* CAM_PRM */
1807         case 0x0f58: s->cam.rm_rstst &= (value & 0xf); break;
1808         case 0x0fc8: s->cam.pm_wkdep = value & 0x16; break;
1809         case 0x0fe0: s->cam.pm_pwstctrl = 0x030104 | (value & 3); break;
1810         case 0x0fe4: OMAP_RO_REG(addr); break;
1811         case 0x0fe8: s->cam.pm_prepwstst = value & 0x3; break;
1812         /* PER_PRM */
1813         case 0x1058: s->per.rm_rstst &= ~(value & 0xf); break;
1814         case 0x10a0: s->per.pm_wken = value & 0x03efff; break;
1815         case 0x10a4: s->per.pm_mpugrpsel = value & 0x03efff; break;
1816         case 0x10a8: s->per.pm_ivagrpsel = value & 0x03efff; break;
1817         case 0x10b0: s->per.pm_wkst &= ~(value & 0x03efff); break;
1818         case 0x10c8: s->per.pm_wkdep = value & 0x17; break;
1819         case 0x10e0: s->per.pm_pwstctrl = 0x030100 | (value & 7); break;
1820         case 0x10e4: OMAP_RO_REG(addr); break;
1821         case 0x10e8: s->per.pm_prepwstst = value & 0x7; break;
1822         /* EMU_PRM */
1823         case 0x1158: s->emu.rm_rstst &= ~(value & 7); break;
1824         case 0x11e4: OMAP_RO_REG(addr); break;
1825         /* Global_Reg_PRM */
1826         case 0x1220: s->gr.prm_vc_smps_sa = value & 0x7f007f; break;
1827         case 0x1224: s->gr.prm_vc_smps_vol_ra = value & 0xff00ff; break;
1828         case 0x1228: s->gr.prm_vc_smps_cmd_ra = value & 0xff00ff; break;
1829         case 0x122c: s->gr.prm_vc_cmd_val_0 = value; break;
1830         case 0x1230: s->gr.prm_vc_cmd_val_1 = value; break;
1831         case 0x1234: s->gr.prm_vc_hc_conf = value & 0x1f001f; break;
1832         case 0x1238: s->gr.prm_vc_i2c_cfg = value & 0x3f; break;
1833         case 0x123c: s->gr.prm_vc_bypass_val = value & 0x01ffff7f; break;
1834         case 0x1250: s->gr.prm_rstctrl = 0; break; /* TODO: resets */
1835         case 0x1254: s->gr.prm_rsttimer = value & 0x1fff; break;
1836         case 0x1258: s->gr.prm_rstst &= ~(value & 0x7fb); break;
1837         case 0x1260: s->gr.prm_voltctrl = value & 0x1f; break;
1838         case 0x1264: s->gr.prm_sram_pcharge = value & 0xff; break;
1839         case 0x1270:
1840             s->gr.prm_clksrc_ctrl = value & 0xd8; /* set osc bypass mode */ 
1841             omap3_prm_clksrc_ctrl_update(s);
1842             break;
1843         case 0x1280: OMAP_RO_REG(addr); break;
1844         case 0x1290: s->gr.prm_voltsetup1 = value; break;
1845         case 0x1294: s->gr.prm_voltoffset = value & 0xffff; break;
1846         case 0x1298: s->gr.prm_clksetup = value & 0xffff; break;
1847         case 0x129c: s->gr.prm_polctrl = value & 0xf; break;
1848         case 0x12a0: s->gr.prm_voltsetup2 = value & 0xffff; break;
1849         /* NEON_PRM */
1850         case 0x1358: s->neon.rm_rstst &= ~(value & 0xf); break;
1851         case 0x13c8: s->neon.pm_wkdep = value & 0x2; break;
1852         case 0x13e0: s->neon.pm_pwstctrl = 0x4 | (value & 3); break;
1853         case 0x13e4: OMAP_RO_REG(addr); break;
1854         case 0x13e8: s->neon.pm_prepwstst = value & 3; break;
1855         /* USBHOST_PRM */
1856         case 0x1458: s->usbhost.rm_rstst &= ~(value & 0xf); break;
1857         case 0x14a0: s->usbhost.pm_wken = value & 1; break;
1858         case 0x14a4: s->usbhost.pm_mpugrpsel = value & 1; break;
1859         case 0x14a8: s->usbhost.pm_ivagrpsel = value & 1; break;
1860         case 0x14b0: s->usbhost.pm_wkst &= ~(value & 1); break;
1861         case 0x14c8: s->usbhost.pm_wkdep = value & 0x17; break;
1862         case 0x14e0: s->usbhost.pm_pwstctrl = 0x030104 | (value & 0x13); break;
1863         case 0x14e4: OMAP_RO_REG(addr); break;
1864         case 0x14e8: s->usbhost.pm_prepwstst = value & 3; break;
1865         default:
1866             OMAP_BAD_REGV(addr, value);
1867             break;
1868     }
1869 }
1870
1871 static void omap3_prm_save_domain_state(QEMUFile *f,
1872                                         struct omap3_prm_domain_s *s)
1873 {
1874     qemu_put_be32(f, s->rm_rstctrl);
1875     qemu_put_be32(f, s->rm_rstst);
1876     qemu_put_be32(f, s->pm_wken);
1877     qemu_put_be32(f, s->pm_mpugrpsel);
1878     qemu_put_be32(f, s->pm_ivagrpsel);
1879     qemu_put_be32(f, s->pm_wkst);
1880     qemu_put_be32(f, s->pm_wkst3);
1881     qemu_put_be32(f, s->pm_wkdep);
1882     qemu_put_be32(f, s->pm_evgenctrl);
1883     qemu_put_be32(f, s->pm_evgenontim);
1884     qemu_put_be32(f, s->pm_evgenofftim);
1885     qemu_put_be32(f, s->pm_pwstctrl);
1886     qemu_put_be32(f, s->pm_pwstst);
1887     qemu_put_be32(f, s->pm_prepwstst);
1888     qemu_put_be32(f, s->pm_wken3);
1889 }
1890
1891 static void omap3_prm_load_domain_state(QEMUFile *f,
1892                                         struct omap3_prm_domain_s *s)
1893 {
1894     s->rm_rstctrl = qemu_get_be32(f);
1895     s->rm_rstst = qemu_get_be32(f);
1896     s->pm_wken = qemu_get_be32(f);
1897     s->pm_mpugrpsel = qemu_get_be32(f);
1898     s->pm_ivagrpsel = qemu_get_be32(f);
1899     s->pm_wkst = qemu_get_be32(f);
1900     s->pm_wkst3 = qemu_get_be32(f);
1901     s->pm_wkdep = qemu_get_be32(f);
1902     s->pm_evgenctrl = qemu_get_be32(f);
1903     s->pm_evgenontim = qemu_get_be32(f);
1904     s->pm_evgenofftim = qemu_get_be32(f);
1905     s->pm_pwstctrl = qemu_get_be32(f);
1906     s->pm_pwstst = qemu_get_be32(f);
1907     s->pm_prepwstst = qemu_get_be32(f);
1908     s->pm_wken3 = qemu_get_be32(f);
1909 }
1910
1911 static void omap3_prm_save_state(QEMUFile *f, void *opaque)
1912 {
1913     struct omap3_prm_s *s = (struct omap3_prm_s *)opaque;
1914     
1915     omap3_prm_save_domain_state(f, &s->iva2);
1916     omap3_prm_save_domain_state(f, &s->mpu);
1917     omap3_prm_save_domain_state(f, &s->core);
1918     omap3_prm_save_domain_state(f, &s->sgx);
1919     omap3_prm_save_domain_state(f, &s->wkup);
1920     omap3_prm_save_domain_state(f, &s->dss);
1921     omap3_prm_save_domain_state(f, &s->cam);
1922     omap3_prm_save_domain_state(f, &s->per);
1923     omap3_prm_save_domain_state(f, &s->emu);
1924     omap3_prm_save_domain_state(f, &s->neon);
1925     omap3_prm_save_domain_state(f, &s->usbhost);
1926     
1927     qemu_put_be32(f, s->prm_irqstatus_iva2);
1928     qemu_put_be32(f, s->prm_irqenable_iva2);
1929     qemu_put_be32(f, s->pm_iva2grpsel3_core);
1930     qemu_put_be32(f, s->pm_mpugrpsel3_core);
1931     
1932     qemu_put_be32(f, s->ocp.prm_revision);
1933     qemu_put_be32(f, s->ocp.prm_sysconfig);
1934     qemu_put_be32(f, s->ocp.prm_irqstatus_mpu);
1935     qemu_put_be32(f, s->ocp.prm_irqenable_mpu);
1936     
1937     qemu_put_be32(f, s->ccr.prm_clksel);
1938     qemu_put_be32(f, s->ccr.prm_clkout_ctrl);
1939     
1940     qemu_put_be32(f, s->gr.prm_vc_smps_sa);
1941     qemu_put_be32(f, s->gr.prm_vc_smps_vol_ra);
1942     qemu_put_be32(f, s->gr.prm_vc_smps_cmd_ra);
1943     qemu_put_be32(f, s->gr.prm_vc_cmd_val_0);
1944     qemu_put_be32(f, s->gr.prm_vc_cmd_val_1);
1945     qemu_put_be32(f, s->gr.prm_vc_hc_conf);
1946     qemu_put_be32(f, s->gr.prm_vc_i2c_cfg);
1947     qemu_put_be32(f, s->gr.prm_vc_bypass_val);
1948     qemu_put_be32(f, s->gr.prm_rstctrl);
1949     qemu_put_be32(f, s->gr.prm_rsttimer);
1950     qemu_put_be32(f, s->gr.prm_rstst);
1951     qemu_put_be32(f, s->gr.prm_voltctrl);
1952     qemu_put_be32(f, s->gr.prm_sram_pcharge);
1953     qemu_put_be32(f, s->gr.prm_clksrc_ctrl);
1954     qemu_put_be32(f, s->gr.prm_obs);
1955     qemu_put_be32(f, s->gr.prm_voltsetup1);
1956     qemu_put_be32(f, s->gr.prm_voltoffset);
1957     qemu_put_be32(f, s->gr.prm_clksetup);
1958     qemu_put_be32(f, s->gr.prm_polctrl);
1959     qemu_put_be32(f, s->gr.prm_voltsetup2);
1960 }
1961
1962 static int omap3_prm_load_state(QEMUFile *f, void *opaque, int version_id)
1963 {
1964     struct omap3_prm_s *s = (struct omap3_prm_s *)opaque;
1965     
1966     if (version_id)
1967         return -EINVAL;
1968     
1969     omap3_prm_load_domain_state(f, &s->iva2);
1970     omap3_prm_load_domain_state(f, &s->mpu);
1971     omap3_prm_load_domain_state(f, &s->core);
1972     omap3_prm_load_domain_state(f, &s->sgx);
1973     omap3_prm_load_domain_state(f, &s->wkup);
1974     omap3_prm_load_domain_state(f, &s->dss);
1975     omap3_prm_load_domain_state(f, &s->cam);
1976     omap3_prm_load_domain_state(f, &s->per);
1977     omap3_prm_load_domain_state(f, &s->emu);
1978     omap3_prm_load_domain_state(f, &s->neon);
1979     omap3_prm_load_domain_state(f, &s->usbhost);
1980     
1981     s->prm_irqstatus_iva2 = qemu_get_be32(f);
1982     s->prm_irqenable_iva2 = qemu_get_be32(f);
1983     s->pm_iva2grpsel3_core = qemu_get_be32(f);
1984     s->pm_mpugrpsel3_core = qemu_get_be32(f);
1985     
1986     s->ocp.prm_revision = qemu_get_be32(f);
1987     s->ocp.prm_sysconfig = qemu_get_be32(f);
1988     s->ocp.prm_irqstatus_mpu = qemu_get_be32(f);
1989     s->ocp.prm_irqenable_mpu = qemu_get_be32(f);
1990     
1991     s->ccr.prm_clksel = qemu_get_be32(f);
1992     s->ccr.prm_clkout_ctrl = qemu_get_be32(f);
1993     
1994     s->gr.prm_vc_smps_sa = qemu_get_be32(f);
1995     s->gr.prm_vc_smps_vol_ra = qemu_get_be32(f);
1996     s->gr.prm_vc_smps_cmd_ra = qemu_get_be32(f);
1997     s->gr.prm_vc_cmd_val_0 = qemu_get_be32(f);
1998     s->gr.prm_vc_cmd_val_1 = qemu_get_be32(f);
1999     s->gr.prm_vc_hc_conf = qemu_get_be32(f);
2000     s->gr.prm_vc_i2c_cfg = qemu_get_be32(f);
2001     s->gr.prm_vc_bypass_val = qemu_get_be32(f);
2002     s->gr.prm_rstctrl = qemu_get_be32(f);
2003     s->gr.prm_rsttimer = qemu_get_be32(f);
2004     s->gr.prm_rstst = qemu_get_be32(f);
2005     s->gr.prm_voltctrl = qemu_get_be32(f);
2006     s->gr.prm_sram_pcharge = qemu_get_be32(f);
2007     s->gr.prm_clksrc_ctrl = qemu_get_be32(f);
2008     s->gr.prm_obs = qemu_get_be32(f);
2009     s->gr.prm_voltsetup1 = qemu_get_be32(f);
2010     s->gr.prm_voltoffset = qemu_get_be32(f);
2011     s->gr.prm_clksetup = qemu_get_be32(f);
2012     s->gr.prm_polctrl = qemu_get_be32(f);
2013     s->gr.prm_voltsetup2 = qemu_get_be32(f);
2014     
2015     omap3_prm_int_update(s);
2016     omap3_prm_clksrc_ctrl_update(s);
2017     omap3_prm_clksel_update(s);
2018     omap_clk_onoff(omap_findclk(s->omap, "omap3_sys_clkout1"),
2019                    s->ccr.prm_clkout_ctrl & 0x80);
2020     
2021     return 0;
2022 }
2023
2024 static CPUReadMemoryFunc *omap3_prm_readfn[] = {
2025     omap_badwidth_read32,
2026     omap_badwidth_read32,
2027     omap3_prm_read,
2028 };
2029
2030 static CPUWriteMemoryFunc *omap3_prm_writefn[] = {
2031     omap_badwidth_write32,
2032     omap_badwidth_write32,
2033     omap3_prm_write,
2034 };
2035
2036 struct omap3_prm_s *omap3_prm_init(struct omap_target_agent_s *ta,
2037                                    qemu_irq mpu_int, qemu_irq iva_int,
2038                                    struct omap_mpu_state_s *mpu)
2039 {
2040     int iomemtype;
2041     struct omap3_prm_s *s = (struct omap3_prm_s *) qemu_mallocz(sizeof(*s));
2042
2043     s->mpu_irq = mpu_int;
2044     s->iva_irq = iva_int;
2045     s->omap = mpu;
2046     omap3_prm_reset(s);
2047
2048     iomemtype = l4_register_io_memory(0, omap3_prm_readfn,
2049                                       omap3_prm_writefn, s);
2050     omap_l4_attach(ta, 0, iomemtype);
2051     omap_l4_attach(ta, 1, iomemtype);
2052
2053     register_savevm("omap3_prm", -1, 0,
2054                     omap3_prm_save_state, omap3_prm_load_state, s);
2055
2056     return s;
2057 }
2058
2059 struct omap3_cm_s {
2060     qemu_irq irq[3];
2061     struct omap_mpu_state_s *mpu;
2062
2063     /* IVA2_CM: base + 0x0000 */
2064     uint32_t cm_fclken_iva2;       /* 00 */
2065     uint32_t cm_clken_pll_iva2;    /* 04 */
2066     uint32_t cm_idlest_iva2;       /* 20 */
2067     uint32_t cm_idlest_pll_iva2;   /* 24 */
2068     uint32_t cm_autoidle_pll_iva2; /* 34 */
2069     uint32_t cm_clksel1_pll_iva2;  /* 40 */
2070     uint32_t cm_clksel2_pll_iva2;  /* 44 */
2071     uint32_t cm_clkstctrl_iva2;    /* 48 */
2072     uint32_t cm_clkstst_iva2;      /* 4c */
2073
2074     /* OCP_System_Reg_CM: base + 0x0800 */
2075     uint32_t cm_revision;  /* 00 */
2076     uint32_t cm_sysconfig; /* 10 */
2077
2078     /* MPU_CM: base + 0x0900 */
2079     uint32_t cm_clken_pll_mpu;    /* 04 */
2080     uint32_t cm_idlest_mpu;       /* 20 */
2081     uint32_t cm_idlest_pll_mpu;   /* 24 */
2082     uint32_t cm_autoidle_pll_mpu; /* 34 */
2083     uint32_t cm_clksel1_pll_mpu;  /* 40 */
2084     uint32_t cm_clksel2_pll_mpu;  /* 44 */
2085     uint32_t cm_clkstctrl_mpu;    /* 48 */
2086     uint32_t cm_clkstst_mpu;      /* 4c */
2087
2088     /* CORE_CM: base + 0x0a00 */
2089     uint32_t cm_fclken1_core;   /* 0a00 */
2090     uint32_t cm_fclken3_core;   /* 0a08 */
2091     uint32_t cm_iclken1_core;   /* 0a10 */
2092     uint32_t cm_iclken2_core;   /* 0a14 */
2093     uint32_t cm_iclken3_core;   /* 0a18 */
2094     uint32_t cm_idlest1_core;   /* 0a20 */
2095     uint32_t cm_idlest2_core;   /* 0a24 */
2096     uint32_t cm_idlest3_core;   /* 0a28 */
2097     uint32_t cm_autoidle1_core; /* 0a30 */
2098     uint32_t cm_autoidle2_core; /* 0a34 */
2099     uint32_t cm_autoidle3_core; /* 0a38 */
2100     uint32_t cm_clksel_core;    /* 0a40 */
2101     uint32_t cm_clkstctrl_core; /* 0a48 */
2102     uint32_t cm_clkstst_core;   /* 0a4c */
2103
2104     /* SGX_CM: base + 0x0b00 */
2105     uint32_t cm_fclken_sgx;    /* 00 */
2106     uint32_t cm_iclken_sgx;    /* 10 */
2107     uint32_t cm_idlest_sgx;    /* 20 */
2108     uint32_t cm_clksel_sgx;    /* 40 */
2109     uint32_t cm_sleepdep_sgx;  /* 44 */
2110     uint32_t cm_clkstctrl_sgx; /* 48 */
2111     uint32_t cm_clkstst_sgx;   /* 4c */
2112
2113     /* WKUP_CM: base + 0x0c00 */
2114     uint32_t cm_fclken_wkup;   /* 00 */
2115     uint32_t cm_iclken_wkup;   /* 10 */
2116     uint32_t cm_idlest_wkup;   /* 20 */
2117     uint32_t cm_autoidle_wkup; /* 30 */
2118     uint32_t cm_clksel_wkup;   /* 40 */
2119     uint32_t cm_c48;           /* 48 */
2120
2121     /* Clock_Control_Reg_CM: base + 0x0d00 */
2122     uint32_t cm_clken_pll;     /* 00 */
2123     uint32_t cm_clken2_pll;    /* 04 */
2124     uint32_t cm_idlest_ckgen;  /* 20 */
2125     uint32_t cm_idlest2_ckgen; /* 24 */
2126     uint32_t cm_autoidle_pll;  /* 30 */
2127     uint32_t cm_autoidle2_pll; /* 34 */
2128     uint32_t cm_clksel1_pll;   /* 40 */
2129     uint32_t cm_clksel2_pll;   /* 44 */
2130     uint32_t cm_clksel3_pll;   /* 48 */
2131     uint32_t cm_clksel4_pll;   /* 4c */
2132     uint32_t cm_clksel5_pll;   /* 50 */
2133     uint32_t cm_clkout_ctrl;   /* 70 */
2134
2135     /* DSS_CM: base + 0x0e00 */
2136     uint32_t cm_fclken_dss;    /* 00 */
2137     uint32_t cm_iclken_dss;    /* 10 */
2138     uint32_t cm_idlest_dss;    /* 20 */
2139     uint32_t cm_autoidle_dss;  /* 30 */
2140     uint32_t cm_clksel_dss;    /* 40 */
2141     uint32_t cm_sleepdep_dss;  /* 44 */
2142     uint32_t cm_clkstctrl_dss; /* 48 */
2143     uint32_t cm_clkstst_dss;   /* 4c */
2144
2145    /* CAM_CM: base + 0x0f00 */
2146     uint32_t cm_fclken_cam;    /* 00 */
2147     uint32_t cm_iclken_cam;    /* 10 */
2148     uint32_t cm_idlest_cam;    /* 20 */
2149     uint32_t cm_autoidle_cam;  /* 30 */
2150     uint32_t cm_clksel_cam;    /* 40 */
2151     uint32_t cm_sleepdep_cam;  /* 44 */
2152     uint32_t cm_clkstctrl_cam; /* 48 */
2153     uint32_t cm_clkstst_cam;   /* 4c */
2154
2155     /* PER_CM: base + 0x1000 */
2156     uint32_t cm_fclken_per;    /* 00 */
2157     uint32_t cm_iclken_per;    /* 10 */
2158     uint32_t cm_idlest_per;    /* 20 */
2159     uint32_t cm_autoidle_per;  /* 30 */
2160     uint32_t cm_clksel_per;    /* 40 */
2161     uint32_t cm_sleepdep_per;  /* 44 */
2162     uint32_t cm_clkstctrl_per; /* 48 */
2163     uint32_t cm_clkstst_per;   /* 4c */
2164
2165     /* EMU_CM: base + 0x1100 */
2166     uint32_t cm_clksel1_emu;   /* 40 */
2167     uint32_t cm_clkstctrl_emu; /* 48 */
2168     uint32_t cm_clkstst_emu;   /* 4c */
2169     uint32_t cm_clksel2_emu;   /* 50 */
2170     uint32_t cm_clksel3_emu;   /* 54 */
2171
2172     /* Global_Reg_CM: base + 0x1200 */
2173     uint32_t cm_polctrl; /* 9c */
2174
2175     /* NEON_CM: base + 0x1300 */
2176     uint32_t cm_idlest_neon;    /* 20 */
2177     uint32_t cm_clkstctrl_neon; /* 48 */
2178
2179     /* USBHOST_CM: base + 0x1400 */
2180     uint32_t cm_fclken_usbhost;    /* 00 */
2181     uint32_t cm_iclken_usbhost;    /* 10 */
2182     uint32_t cm_idlest_usbhost;    /* 20 */
2183     uint32_t cm_autoidle_usbhost;  /* 30 */
2184     uint32_t cm_sleepdep_usbhost;  /* 44 */
2185     uint32_t cm_clkstctrl_usbhost; /* 48 */
2186     uint32_t cm_clkstst_usbhost;   /* 4c */
2187 };
2188
2189 static inline void omap3_cm_clksel_wkup_update(struct omap3_cm_s *s)
2190 {
2191     omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp1_fclk"),
2192                       omap_findclk(s->mpu,
2193                                    (s->cm_clksel_wkup & 1) /* CLKSEL_GPT1 */
2194                                    ? "omap3_sys_clk"
2195                                    : "omap3_32k_fclk"));
2196     omap_clk_setrate(omap_findclk(s->mpu, "omap3_rm_iclk"),
2197                      (s->cm_clksel_wkup >> 1) & 3, /* CLKSEL_RM */
2198                      1);
2199
2200     /* Tell GPTIMER to generate new clk rate */
2201     omap_gp_timer_change_clk(s->mpu->gptimer[0]);
2202
2203     TRACE("gptimer1 fclk=%lld",
2204           omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp1_fclk")));
2205
2206     /* TODO: CM_USIM_CLK */
2207 }
2208
2209 static inline void omap3_cm_iva2_update(struct omap3_cm_s *s)
2210 {
2211     uint32_t iva2_dpll_mul = ((s->cm_clksel1_pll_iva2 >> 8) & 0x7ff);
2212     uint32_t iva2_dpll_div, iva2_dpll_clkout_div, iva2_clk_src;
2213     omap_clk iva2_clk = omap_findclk(s->mpu, "omap3_iva2_clk");
2214
2215     omap_clk_onoff(iva2_clk, s->cm_fclken_iva2 & 1);
2216
2217     switch ((s->cm_clken_pll_iva2 & 0x7)) {
2218         case 0x01: /* low power stop mode */
2219         case 0x05: /* low power bypass mode */
2220             s->cm_idlest_pll_iva2 &= ~1;
2221             break;
2222         case 0x07: /* locked */
2223             if (iva2_dpll_mul < 2)
2224                 s->cm_idlest_pll_iva2 &= ~1;
2225             else
2226                 s->cm_idlest_pll_iva2 |= 1;
2227             break;
2228         default:
2229             break;
2230     }
2231     
2232     if (s->cm_idlest_pll_iva2 & 1) {
2233         iva2_dpll_div = s->cm_clksel1_pll_iva2 & 0x7f;
2234         iva2_dpll_clkout_div = s->cm_clksel2_pll_iva2 & 0x1f;
2235         omap_clk_reparent(iva2_clk, omap_findclk(s->mpu, "omap3_sys_clk"));
2236         omap_clk_setrate(iva2_clk,
2237                          (iva2_dpll_div + 1) * iva2_dpll_clkout_div,
2238                          iva2_dpll_mul);
2239     } else {
2240         /* bypass mode */
2241         iva2_clk_src = (s->cm_clksel1_pll_iva2 >> 19) & 0x07;
2242         omap_clk_reparent(iva2_clk, omap_findclk(s->mpu, "omap3_core_clk"));
2243         omap_clk_setrate(iva2_clk, iva2_clk_src, 1);
2244     }
2245 }
2246
2247 static inline void omap3_cm_mpu_update(struct omap3_cm_s *s)
2248 {
2249     uint32_t mpu_dpll_mul = ((s->cm_clksel1_pll_mpu >> 8) & 0x7ff);
2250     uint32_t mpu_dpll_div, mpu_dpll_clkout_div, mpu_clk_src;
2251     omap_clk mpu_clk = omap_findclk(s->mpu, "omap3_mpu_clk");
2252     
2253     switch ((s->cm_clken_pll_mpu & 0x7)) {
2254         case 0x05: /* low power bypass mode */
2255             s->cm_idlest_pll_mpu &= ~1;
2256             break;
2257         case 0x07: /* locked */
2258             if (mpu_dpll_mul < 2)
2259                 s->cm_idlest_pll_mpu &= ~1;
2260             else
2261                 s->cm_idlest_pll_mpu |= 1;
2262             break;
2263         default:
2264             break;
2265     }
2266     
2267     if (s->cm_idlest_pll_mpu & 1) {
2268         mpu_dpll_div = s->cm_clksel1_pll_mpu & 0x7f;
2269         mpu_dpll_clkout_div = s->cm_clksel2_pll_mpu & 0x1f;
2270         omap_clk_reparent(mpu_clk, omap_findclk(s->mpu, "omap3_sys_clk"));
2271         omap_clk_setrate(mpu_clk,
2272                          (mpu_dpll_div + 1) * mpu_dpll_clkout_div,
2273                          mpu_dpll_mul);
2274     } else {
2275         /* bypass mode */
2276         mpu_clk_src = (s->cm_clksel1_pll_mpu >> 19) & 0x07;
2277         omap_clk_reparent(mpu_clk, omap_findclk(s->mpu, "omap3_core_clk"));
2278         omap_clk_setrate(mpu_clk, mpu_clk_src, 1);
2279     }
2280 }
2281
2282 static inline void omap3_cm_dpll3_update(struct omap3_cm_s *s)
2283 {
2284     uint32_t core_dpll_mul = ((s->cm_clksel1_pll >> 16) & 0x7ff);
2285     uint32_t core_dpll_div, core_dpll_clkout_div, div_dpll3;
2286
2287     switch ((s->cm_clken_pll & 0x7)) {
2288         case 0x05: /* low power bypass */
2289         case 0x06: /* fast relock bypass */
2290             s->cm_idlest_ckgen &= ~1;
2291             break;
2292         case 0x07: /* locked */
2293             if (core_dpll_mul < 2)
2294                 s->cm_idlest_ckgen &= ~1;
2295             else
2296                 s->cm_idlest_ckgen |= 1;
2297             break;
2298         default:
2299             break;
2300     }
2301
2302     if (s->cm_idlest_ckgen & 1) {
2303         core_dpll_div = (s->cm_clksel1_pll >> 8) & 0x7f;
2304         core_dpll_clkout_div = (s->cm_clksel1_pll >> 27) & 0x1f;
2305         div_dpll3 = (s->cm_clksel1_emu >> 16) & 0x1f;
2306         
2307         if (s->cm_clksel2_emu & 0x80000) { /* OVERRIDE_ENABLE */
2308                 core_dpll_mul = (s->cm_clksel2_emu >> 8) & 0x7ff;
2309                 core_dpll_div = s->cm_clksel2_emu & 0x7f;
2310         }
2311         
2312         omap_clk_setrate(omap_findclk(s->mpu, "omap3_core_clk"),
2313                          (core_dpll_div + 1) * core_dpll_clkout_div,
2314                          core_dpll_mul);
2315         omap_clk_setrate(omap_findclk(s->mpu, "omap3_core2_clk"),
2316                          (core_dpll_div + 1) * core_dpll_clkout_div,
2317                          core_dpll_mul * 2);
2318         omap_clk_setrate(omap_findclk(s->mpu, "omap3_emu_core_alwon_clk"),
2319                          (core_dpll_div + 1) * div_dpll3,
2320                          core_dpll_mul * 2);
2321     } else {
2322         /* bypass mode */
2323         omap_clk_setrate(omap_findclk(s->mpu, "omap3_core_clk"), 1, 1);
2324         omap_clk_setrate(omap_findclk(s->mpu, "omap3_core2_clk"), 1, 1);
2325         omap_clk_setrate(omap_findclk(s->mpu, "omap3_emu_core_alwon_clk"), 1, 1);
2326     }
2327 }
2328
2329 static inline void omap3_cm_dpll4_update(struct omap3_cm_s *s)
2330 {
2331     uint32_t per_dpll_mul = ((s->cm_clksel2_pll >> 8) & 0x7ff);
2332     uint32_t per_dpll_div, div_96m, clksel_tv, clksel_dss1, clksel_cam, div_dpll4;
2333
2334     switch (((s->cm_clken_pll >> 16) & 0x7)) {
2335         case 0x01: /* lower power stop mode */
2336             s->cm_idlest_ckgen &= ~2;
2337             break;
2338         case 0x07: /* locked */
2339             if (per_dpll_mul < 2)
2340                 s->cm_idlest_ckgen &= ~2;
2341             else
2342                 s->cm_idlest_ckgen |= 2;
2343             break;
2344         default:
2345             break;
2346     }
2347
2348     if (s->cm_idlest_ckgen & 2) {
2349         per_dpll_div = s->cm_clksel2_pll & 0x7f;
2350         div_96m = s->cm_clksel3_pll & 0x1f;
2351         clksel_tv = (s->cm_clksel_dss >> 8) & 0x1f;
2352         clksel_dss1 = s->cm_clksel_dss & 0x1f;
2353         clksel_cam = s->cm_clksel_cam & 0x1f;
2354         div_dpll4 = (s->cm_clksel1_emu >> 24) & 0x1f;
2355         
2356         if (s->cm_clksel3_emu & 0x80000) { /* OVERRIDE_ENABLE */
2357                 per_dpll_mul = (s->cm_clksel3_emu >> 8) & 0x7ff;
2358                 per_dpll_div =  s->cm_clksel3_emu & 0x7f;
2359         }
2360         
2361         omap_clk_setrate(omap_findclk(s->mpu, "omap3_96m_fclk"),
2362                          (per_dpll_div + 1) * div_96m,
2363                          per_dpll_mul * 2);
2364         omap_clk_setrate(omap_findclk(s->mpu, "omap3_54m_fclk"),
2365                          (per_dpll_div + 1) * clksel_tv,
2366                          per_dpll_mul * 2);
2367         omap_clk_setrate(omap_findclk(s->mpu, "omap3_dss1_alwon_fclk"),
2368                          (per_dpll_div + 1) * clksel_dss1,
2369                          per_dpll_mul * 2);
2370         omap_clk_setrate(omap_findclk(s->mpu, "omap3_cam_mclk"),
2371                          (per_dpll_div + 1) * clksel_cam,
2372                          per_dpll_mul * 2);
2373         omap_clk_setrate(omap_findclk(s->mpu, "omap3_per_alwon_clk"),
2374                          (per_dpll_div + 1) * div_dpll4,
2375                          per_dpll_mul * 2);
2376     } else {
2377         /* bypass mode */
2378         omap_clk_setrate(omap_findclk(s->mpu, "omap3_96m_fclk"), 1, 1);
2379         omap_clk_setrate(omap_findclk(s->mpu, "omap3_54m_fclk"), 1, 1);
2380         omap_clk_setrate(omap_findclk(s->mpu, "omap3_dss1_alwon_fclk"), 1, 1);
2381         omap_clk_setrate(omap_findclk(s->mpu, "omap3_cam_mclk"), 1, 1);
2382         omap_clk_setrate(omap_findclk(s->mpu, "omap3_per_alwon_clk"), 1, 1);
2383     }
2384 }
2385
2386 static inline void omap3_cm_dpll5_update(struct omap3_cm_s *s)
2387 {
2388     uint32_t per2_dpll_mul = ((s->cm_clksel4_pll >> 8) & 0x7ff);
2389     uint32_t per2_dpll_div, div_120m;
2390
2391     switch ((s->cm_clken2_pll & 0x7)) {
2392         case 0x01: /* low power stop mode */
2393             s->cm_idlest2_ckgen &= ~1;
2394             break;
2395         case 0x07: /* locked */
2396             if (per2_dpll_mul < 2)
2397                 s->cm_idlest2_ckgen &= ~1;
2398             else
2399                 s->cm_idlest2_ckgen |= 1;
2400             break;
2401         default:
2402             break;
2403     }
2404
2405     if (s->cm_idlest2_ckgen & 1) {
2406         per2_dpll_div = s->cm_clksel4_pll & 0x7f;
2407         div_120m = s->cm_clksel5_pll & 0x1f;
2408         
2409         omap_clk_setrate(omap_findclk(s->mpu, "omap3_120m_fclk"),
2410                          (per2_dpll_div + 1) * div_120m,
2411                          per2_dpll_mul);
2412     } else {
2413         /* bypass mode */
2414         omap_clk_setrate(omap_findclk(s->mpu, "omap3_120m_fclk"), 1, 1);
2415     }
2416 }
2417
2418 static inline void omap3_cm_48m_update(struct omap3_cm_s *s)
2419 {
2420     omap_clk pclk = omap_findclk(s->mpu,
2421                                  (s->cm_clksel1_pll & 0x8) /* SOURCE_48M */
2422                                  ? "omap3_sys_altclk"
2423                                  : "omap3_96m_fclk");
2424     
2425     omap_clk_reparent(omap_findclk(s->mpu, "omap3_48m_fclk"), pclk);
2426     omap_clk_reparent(omap_findclk(s->mpu, "omap3_12m_fclk"), pclk);
2427 }
2428
2429 static inline void omap3_cm_gp10gp11_update(struct omap3_cm_s *s)
2430 {
2431     omap_clk gp10 = omap_findclk(s->mpu, "omap3_gp10_fclk");
2432     omap_clk gp11 = omap_findclk(s->mpu, "omap3_gp11_fclk");
2433     omap_clk sys  = omap_findclk(s->mpu, "omap3_sys_clk");
2434     omap_clk f32k = omap_findclk(s->mpu, "omap3_32k_fclk");
2435
2436     omap_clk_reparent(gp10, (s->cm_clksel_core & 0x40) ? sys : f32k);
2437     omap_clk_reparent(gp11, (s->cm_clksel_core & 0x80) ? sys : f32k);
2438     omap_gp_timer_change_clk(s->mpu->gptimer[9]);
2439     omap_gp_timer_change_clk(s->mpu->gptimer[10]);
2440     
2441     TRACE("gptimer10 fclk = %lld", omap_clk_getrate(gp10));
2442     TRACE("gptimer11 fclk = %lld", omap_clk_getrate(gp11));
2443 }
2444
2445 static inline void omap3_cm_per_gptimer_update(struct omap3_cm_s *s)
2446 {
2447     omap_clk sys = omap_findclk(s->mpu, "omap3_sys_clk");
2448     omap_clk f32k = omap_findclk(s->mpu, "omap3_32k_fclk");
2449     uint32_t cm_clksel_per = s->cm_clksel_per;
2450     uint32_t n;
2451     char clkname[] = "omap3_gp#_fclk";
2452
2453     for (n = 1; n < 9; n++, cm_clksel_per >>= 1) {
2454         clkname[8] = '1' + n; /* 2 - 9 */
2455         omap_clk_reparent(omap_findclk(s->mpu, clkname),
2456                           (cm_clksel_per & 1) ? sys : f32k);
2457         omap_gp_timer_change_clk(s->mpu->gptimer[n]);
2458         TRACE("gptimer%d fclk = %lld", n + 1,
2459               omap_clk_getrate(omap_findclk(s->mpu, clkname)));
2460     }
2461 }
2462
2463 static inline void omap3_cm_clkout2_update(struct omap3_cm_s *s)
2464 {
2465     omap_clk c = omap_findclk(s->mpu, "omap3_sys_clkout2");
2466         
2467     omap_clk_onoff(c, (s->cm_clkout_ctrl >> 7) & 1);
2468     switch (s->cm_clkout_ctrl & 0x3) {
2469         case 0:
2470             omap_clk_reparent(c, omap_findclk(s->mpu, "omap3_core_clk"));
2471             break;
2472         case 1:
2473             omap_clk_reparent(c, omap_findclk(s->mpu, "omap3_sys_clk"));
2474             break;
2475         case 2:
2476             omap_clk_reparent(c, omap_findclk(s->mpu, "omap3_96m_fclk"));
2477             break;
2478         case 3:
2479             omap_clk_reparent(c, omap_findclk(s->mpu, "omap3_54m_fclk"));
2480             break;
2481         default:
2482             break;
2483     }
2484     omap_clk_setrate(c, 1 << ((s->cm_clkout_ctrl >> 3) & 7), 1);
2485 }
2486
2487 static inline void omap3_cm_fclken1_core_update(struct omap3_cm_s *s)
2488 {
2489     uint32_t v = s->cm_fclken1_core;
2490     
2491     /* TODO: EN_MCBSP1,5 */
2492     omap_clk_onoff(omap_findclk(s->mpu, "omap3_gp10_fclk"),  (v >> 11) & 1);
2493     omap_clk_onoff(omap_findclk(s->mpu, "omap3_gp11_fclk"),  (v >> 12) & 1);
2494     omap_clk_onoff(omap_findclk(s->mpu, "omap3_uart1_fclk"), (v >> 13) & 1);
2495     omap_clk_onoff(omap_findclk(s->mpu, "omap3_uart2_fclk"), (v >> 14) & 1);
2496     omap_clk_onoff(omap_findclk(s->mpu, "omap3_i2c1_fclk"),  (v >> 15) & 1);
2497     omap_clk_onoff(omap_findclk(s->mpu, "omap3_i2c2_fclk"),  (v >> 16) & 1);
2498     omap_clk_onoff(omap_findclk(s->mpu, "omap3_i2c3_fclk"),  (v >> 17) & 1);
2499     /* TODO: EN_HDQ, EN_SPI1-4 */
2500     omap_clk_onoff(omap_findclk(s->mpu, "omap3_mmc1_fclk"),  (v >> 24) & 1);
2501     omap_clk_onoff(omap_findclk(s->mpu, "omap3_mmc2_fclk"),  (v >> 25) & 1);
2502     omap_clk_onoff(omap_findclk(s->mpu, "omap3_mmc3_fclk"),  (v >> 30) & 1);
2503 }
2504
2505 static inline void omap3_cm_iclken1_core_update(struct omap3_cm_s *s)
2506 {
2507     uint32_t v = s->cm_iclken1_core;
2508     
2509     /* TODO: EN_SDRC, EN_HSOTGUSB, EN_OMAPCTRL, EN_MAILBOXES, EN_MCBSP1,5 */
2510     /* TODO: EN_GPT10, EN_GPT11 */
2511     omap_clk_onoff(omap_findclk(s->mpu, "omap3_uart1_iclk"), (v >> 13) & 1);
2512     omap_clk_onoff(omap_findclk(s->mpu, "omap3_uart2_iclk"), (v >> 14) & 1);
2513     omap_clk_onoff(omap_findclk(s->mpu, "omap3_i2c1_iclk"),  (v >> 15) & 1);
2514     omap_clk_onoff(omap_findclk(s->mpu, "omap3_i2c2_iclk"),  (v >> 16) & 1);
2515     omap_clk_onoff(omap_findclk(s->mpu, "omap3_i2c3_iclk"),  (v >> 17) & 1);
2516     /* TODO: EN_HDQ, EN_SPI1-4 */
2517     omap_clk_onoff(omap_findclk(s->mpu, "omap3_mmc1_iclk"),  (v >> 24) & 1);
2518     omap_clk_onoff(omap_findclk(s->mpu, "omap3_mmc2_iclk"),  (v >> 25) & 1);
2519     omap_clk_onoff(omap_findclk(s->mpu, "omap3_mmc3_iclk"),  (v >> 30) & 1);
2520     /* set USB OTG idle if iclk is enabled and SDMA always in standby */
2521     v &= ~0x24;
2522     v |= (v & 0x10) << 1;
2523     s->cm_idlest1_core = ~v;
2524 }
2525
2526 static inline void omap3_cm_l3l4iclk_update(struct omap3_cm_s *s)
2527 {
2528     omap_clk_setrate(omap_findclk(s->mpu, "omap3_l3_iclk"),
2529                      s->cm_clksel_core & 0x3, 1);
2530     omap_clk_setrate(omap_findclk(s->mpu, "omap3_l4_iclk"),
2531                      (s->cm_clksel_core >> 2) & 0x3, 1);
2532 }
2533
2534 static void omap3_cm_reset(struct omap3_cm_s *s)
2535 {
2536     s->cm_fclken_iva2 = 0x0;
2537     s->cm_clken_pll_iva2 = 0x11;
2538     s->cm_idlest_iva2 = 0x1;
2539     s->cm_idlest_pll_iva2 = 0;
2540     s->cm_autoidle_pll_iva2 = 0x0;
2541     s->cm_clksel1_pll_iva2 = 0x80000;
2542     s->cm_clksel2_pll_iva2 = 0x1;
2543     s->cm_clkstctrl_iva2 = 0x0;
2544     s->cm_clkstst_iva2 = 0x0;
2545
2546     s->cm_revision = 0x10;
2547     s->cm_sysconfig = 0x1;
2548
2549     s->cm_clken_pll_mpu = 0x15;
2550     s->cm_idlest_mpu = 0x1;
2551     s->cm_idlest_pll_mpu = 0;
2552     s->cm_autoidle_pll_mpu = 0x0;
2553     s->cm_clksel1_pll_mpu = 0x80000;
2554     s->cm_clksel2_pll_mpu = 0x1;
2555     s->cm_clkstctrl_mpu = 0x0;
2556     s->cm_clkstst_mpu = 0x0;
2557
2558     s->cm_fclken1_core = 0x0;
2559     s->cm_fclken3_core = 0x0;
2560     s->cm_iclken1_core = 0x42;
2561     s->cm_iclken2_core = 0x0;
2562     s->cm_iclken3_core = 0x0;
2563     /*allow access to devices*/
2564     s->cm_idlest1_core = 0x0;
2565     s->cm_idlest2_core = 0x0;
2566     /*ide status =0 */
2567     s->cm_idlest3_core = 0xa; 
2568     s->cm_autoidle1_core = 0x0;
2569     s->cm_autoidle2_core = 0x0;
2570     s->cm_autoidle3_core = 0x0;
2571     s->cm_clksel_core = 0x105;
2572     s->cm_clkstctrl_core = 0x0;
2573     s->cm_clkstst_core = 0x0;
2574
2575     s->cm_fclken_sgx = 0x0;
2576     s->cm_iclken_sgx = 0x0;
2577     s->cm_idlest_sgx = 0x1;
2578     s->cm_clksel_sgx = 0x0;
2579     s->cm_sleepdep_sgx = 0x0;
2580     s->cm_clkstctrl_sgx = 0x0;
2581     s->cm_clkstst_sgx = 0x0;
2582
2583     s->cm_fclken_wkup = 0x0;
2584     s->cm_iclken_wkup = 0x0;
2585     /*assume all clock can be accessed*/
2586     s->cm_idlest_wkup = 0x0;
2587     s->cm_autoidle_wkup = 0x0;
2588     s->cm_clksel_wkup = 0x12;
2589
2590     s->cm_clken_pll = 0x110015;
2591     s->cm_clken2_pll = 0x11;
2592     s->cm_idlest_ckgen = 0x3f3c; /* FIXME: provide real clock statuses */
2593     s->cm_idlest2_ckgen = 0xa; /* FIXME: provide real clock statuses */
2594     s->cm_autoidle_pll = 0x0;
2595     s->cm_autoidle2_pll = 0x0;
2596     s->cm_clksel1_pll = 0x8000040;
2597     s->cm_clksel2_pll = 0x0;
2598     s->cm_clksel3_pll = 0x1;
2599     s->cm_clksel4_pll = 0x0;
2600     s->cm_clksel5_pll = 0x1;
2601     s->cm_clkout_ctrl = 0x3;
2602
2603
2604     s->cm_fclken_dss = 0x0;
2605     s->cm_iclken_dss = 0x0;
2606     /*dss can be accessed*/
2607     s->cm_idlest_dss = 0x0;
2608     s->cm_autoidle_dss = 0x0;
2609     s->cm_clksel_dss = 0x1010;
2610     s->cm_sleepdep_dss = 0x0;
2611     s->cm_clkstctrl_dss = 0x0;
2612     s->cm_clkstst_dss = 0x0;
2613
2614     s->cm_fclken_cam = 0x0;
2615     s->cm_iclken_cam = 0x0;
2616     s->cm_idlest_cam = 0x1;
2617     s->cm_autoidle_cam = 0x0;
2618     s->cm_clksel_cam = 0x10;
2619     s->cm_sleepdep_cam = 0x0;
2620     s->cm_clkstctrl_cam = 0x0;
2621     s->cm_clkstst_cam = 0x0;
2622
2623     s->cm_fclken_per = 0x0;
2624     s->cm_iclken_per = 0x0;
2625     //s->cm_idlest_per = 0x3ffff;
2626     s->cm_idlest_per = 0x0; //enable GPIO access
2627     s->cm_autoidle_per = 0x0;
2628     s->cm_clksel_per = 0x0;
2629     s->cm_sleepdep_per = 0x0;
2630     s->cm_clkstctrl_per = 0x0;
2631     s->cm_clkstst_per = 0x0;
2632
2633     s->cm_clksel1_emu = 0x10100a50;
2634     s->cm_clkstctrl_emu = 0x2;
2635     s->cm_clkstst_emu = 0x0;
2636     s->cm_clksel2_emu = 0x0;
2637     s->cm_clksel3_emu = 0x0;
2638
2639     s->cm_polctrl = 0x0;
2640
2641     s->cm_idlest_neon = 0x1;
2642     s->cm_clkstctrl_neon = 0x0;
2643
2644     s->cm_fclken_usbhost = 0x0;
2645     s->cm_iclken_usbhost = 0x0;
2646     s->cm_idlest_usbhost = 0x3;
2647     s->cm_autoidle_usbhost = 0x0;
2648     s->cm_sleepdep_usbhost = 0x0;
2649     s->cm_clkstctrl_usbhost = 0x0;
2650     s->cm_clkstst_usbhost = 0x0;
2651 }
2652
2653 static uint32_t omap3_cm_read(void *opaque, target_phys_addr_t addr)
2654 {
2655     struct omap3_cm_s *s = (struct omap3_cm_s *) opaque;
2656
2657     switch (addr) {
2658         /* IVA2_CM */
2659         case 0x0000: return s->cm_fclken_iva2;
2660         case 0x0004: return s->cm_clken_pll_iva2;
2661         case 0x0020: return s->cm_idlest_iva2;
2662         case 0x0024: return s->cm_idlest_pll_iva2;
2663         case 0x0034: return s->cm_autoidle_pll_iva2;
2664         case 0x0040: return s->cm_clksel1_pll_iva2;
2665         case 0x0044: return s->cm_clksel2_pll_iva2;
2666         case 0x0048: return s->cm_clkstctrl_iva2;
2667         case 0x004c: return s->cm_clkstst_iva2;
2668         /* OCP_System_Reg_CM */
2669         case 0x0800: return s->cm_revision;
2670         case 0x0810: return s->cm_sysconfig;
2671         /* MPU_CM */
2672         case 0x0904: return s->cm_clken_pll_mpu;
2673         case 0x0920: return s->cm_idlest_mpu & 0x0; /*MPU is active*/
2674         case 0x0924: return s->cm_idlest_pll_mpu;
2675         case 0x0934: return s->cm_autoidle_pll_mpu;
2676         case 0x0940: return s->cm_clksel1_pll_mpu;
2677         case 0x0944: return s->cm_clksel2_pll_mpu;
2678         case 0x0948: return s->cm_clkstctrl_mpu;
2679         case 0x094c: return s->cm_clkstst_mpu;
2680         /* CORE_CM */
2681         case 0x0a00: return s->cm_fclken1_core;
2682         case 0x0a08: return s->cm_fclken3_core;
2683         case 0x0a10: return s->cm_iclken1_core;
2684         case 0x0a14: return s->cm_iclken2_core;
2685         case 0x0a20: return s->cm_idlest1_core;
2686         case 0x0a24: return s->cm_idlest2_core;
2687         case 0x0a28: return s->cm_idlest3_core;
2688         case 0x0a30: return s->cm_autoidle1_core;
2689         case 0x0a34: return s->cm_autoidle2_core;
2690         case 0x0a38: return s->cm_autoidle3_core;
2691         case 0x0a40: return s->cm_clksel_core;
2692         case 0x0a48: return s->cm_clkstctrl_core;
2693         case 0x0a4c: return s->cm_clkstst_core;
2694         /* SGX_CM */
2695         case 0x0b00: return s->cm_fclken_sgx;
2696         case 0x0b10: return s->cm_iclken_sgx;
2697         case 0x0b20: return s->cm_idlest_sgx & 0x0;
2698         case 0x0b40: return s->cm_clksel_sgx;
2699         case 0x0b48: return s->cm_clkstctrl_sgx;
2700         case 0x0b4c: return s->cm_clkstst_sgx;
2701         /* WKUP_CM */
2702         case 0x0c00: return s->cm_fclken_wkup;
2703         case 0x0c10: return s->cm_iclken_wkup;
2704         case 0x0c20: return 0; /* TODO: Check if the timer can be accessed. */
2705         case 0x0c30: return s->cm_idlest_wkup;
2706         case 0x0c40: return s->cm_clksel_wkup;
2707         case 0x0c48: return s->cm_c48;
2708         /* Clock_Control_Reg_CM */
2709         case 0x0d00: return s->cm_clken_pll;
2710         case 0x0d04: return s->cm_clken2_pll;
2711         case 0x0d20: return s->cm_idlest_ckgen;
2712         case 0x0d24: return s->cm_idlest2_ckgen;
2713         case 0x0d30: return s->cm_autoidle_pll;
2714         case 0x0d34: return s->cm_autoidle2_pll;
2715         case 0x0d40: return s->cm_clksel1_pll;
2716         case 0x0d44: return s->cm_clksel2_pll;
2717         case 0x0d48: return s->cm_clksel3_pll;
2718         case 0x0d4c: return s->cm_clksel4_pll;
2719         case 0x0d50: return s->cm_clksel5_pll;
2720         case 0x0d70: return s->cm_clkout_ctrl;
2721         /* DSS_CM */
2722         case 0x0e00: return s->cm_fclken_dss;
2723         case 0x0e10: return s->cm_iclken_dss;
2724         case 0x0e20: return s->cm_idlest_dss;
2725         case 0x0e30: return s->cm_autoidle_dss;
2726         case 0x0e40: return s->cm_clksel_dss;
2727         case 0x0e44: return s->cm_sleepdep_dss;
2728         case 0x0e48: return s->cm_clkstctrl_dss;
2729         case 0x0e4c: return s->cm_clkstst_dss;
2730         /* CAM_CM */
2731         case 0x0f00: return s->cm_fclken_cam;
2732         case 0x0f10: return s->cm_iclken_cam;
2733         case 0x0f20: return s->cm_idlest_cam & 0x0;
2734         case 0x0f30: return s->cm_autoidle_cam;
2735         case 0x0f40: return s->cm_clksel_cam;
2736         case 0x0f44: return s->cm_sleepdep_cam;
2737         case 0x0f48: return s->cm_clkstctrl_cam;
2738         case 0x0f4c: return s->cm_clkstst_cam;
2739         /* PER_CM */
2740         case 0x1000: return s->cm_fclken_per;
2741         case 0x1010: return s->cm_iclken_per;
2742         case 0x1020: return s->cm_idlest_per ;
2743         case 0x1030: return s->cm_autoidle_per;
2744         case 0x1040: return s->cm_clksel_per;
2745         case 0x1044: return s->cm_sleepdep_per;
2746         case 0x1048: return s->cm_clkstctrl_per;
2747         case 0x104c: return s->cm_clkstst_per;
2748         /* EMU_CM */
2749         case 0x1140: return s->cm_clksel1_emu;
2750         case 0x1148: return s->cm_clkstctrl_emu;
2751         case 0x114c: return s->cm_clkstst_emu & 0x0;
2752         case 0x1150: return s->cm_clksel2_emu;
2753         case 0x1154: return s->cm_clksel3_emu;
2754         /* Global_Reg_CM */
2755         case 0x129c: return s->cm_polctrl;
2756         /* NEON_CM */
2757         case 0x1320: return s->cm_idlest_neon & 0x0;
2758         case 0x1348: return s->cm_clkstctrl_neon;
2759         /* USBHOST_CM */
2760         case 0x1400: return s->cm_fclken_usbhost;
2761         case 0x1410: return s->cm_iclken_usbhost;
2762         case 0x1420: return s->cm_idlest_usbhost & 0x0;
2763         case 0x1430: return s->cm_autoidle_usbhost;
2764         case 0x1444: return s->cm_sleepdep_usbhost;
2765         case 0x1448: return s->cm_clkstctrl_usbhost;
2766         case 0x144c: return s->cm_clkstst_usbhost;
2767         /* unknown */
2768         default: break;
2769     }
2770     OMAP_BAD_REG(addr);
2771     return 0;
2772 }
2773
2774 static void omap3_cm_write(void *opaque,
2775                            target_phys_addr_t addr,
2776                            uint32_t value)
2777 {
2778     struct omap3_cm_s *s = (struct omap3_cm_s *)opaque;
2779
2780     switch (addr) {
2781         case 0x0020:
2782         case 0x0024:
2783         case 0x004c:
2784         case 0x0800:
2785         case 0x0920:
2786         case 0x0924:
2787         case 0x094c:
2788         case 0x0a20:
2789         case 0x0a24:
2790         case 0x0a28:
2791         case 0x0a4c:
2792         case 0x0b20:
2793         case 0x0b4c:
2794         case 0x0c20:
2795         case 0x0d20:
2796         case 0x0d24:
2797         case 0x0e20:
2798         case 0x0e4c:
2799         case 0x0f20:
2800         case 0x0f4c:
2801         case 0x1020:
2802         case 0x104c:
2803         case 0x114c:
2804         case 0x1320:
2805         case 0x1420:
2806         case 0x144c:
2807             OMAP_RO_REGV(addr, value);
2808             break;
2809         /* IVA2_CM */
2810         case 0x0000:
2811             s->cm_fclken_iva2 = value & 0x1;
2812             omap3_cm_iva2_update(s);
2813             break;
2814         case 0x0004: 
2815             s->cm_clken_pll_iva2 = value & 0x7ff;
2816             omap3_cm_iva2_update(s);
2817             break;
2818         case 0x0034:
2819             s->cm_autoidle_pll_iva2 = value & 0x7;
2820             break;
2821         case 0x0040:
2822             s->cm_clksel1_pll_iva2 = value & 0x3fff7f;
2823             omap3_cm_iva2_update(s);
2824             break;
2825         case 0x0044:
2826             s->cm_clksel2_pll_iva2 = value & 0x1f;
2827             omap3_cm_iva2_update(s);
2828             break;
2829         case 0x0048:
2830             s->cm_clkstctrl_iva2 = value & 0x3;
2831             break;
2832         /* OCP_System_Reg_CM */
2833         case 0x0810:
2834             s->cm_sysconfig = value & 0x1;
2835             break;
2836         /* MPU_CM */
2837         case 0x0904:
2838             s->cm_clken_pll_mpu = value & 0x7ff;
2839             omap3_cm_mpu_update(s);
2840             break;
2841         case 0x0934:
2842             s->cm_autoidle_pll_mpu = value & 0x7;
2843             break;
2844         case 0x0940:
2845             s->cm_clksel1_pll_mpu = value & 0x3fff7f;
2846             omap3_cm_mpu_update(s);
2847             break;
2848         case 0x0944:
2849             s->cm_clksel2_pll_mpu = value & 0x1f;
2850             omap3_cm_mpu_update(s);
2851             break;
2852         case 0x0948:
2853             s->cm_clkstctrl_mpu = value & 0x3;
2854             break;
2855         /* CORE_CM */
2856         case 0xa00:
2857             s->cm_fclken1_core = value & 0x43fffe00;
2858             omap3_cm_fclken1_core_update(s);
2859             break;
2860         case 0xa08:
2861             s->cm_fclken3_core = value & 0x7;
2862             /* TODO: EN_USBTLL, EN_TS */
2863             break;
2864         case 0xa10:
2865             s->cm_iclken1_core = value & 0x637ffed2;
2866             omap3_cm_iclken1_core_update(s);
2867             break;
2868         case 0xa14:
2869             s->cm_iclken2_core = value & 0x1f;
2870             break;
2871         case 0xa18:
2872             s->cm_iclken3_core = value & 0x4;
2873             s->cm_idlest3_core = 0xd & ~(s->cm_iclken3_core & 4);
2874             break;
2875         case 0xa30:
2876             s->cm_autoidle1_core = value & 0x7ffffed0;
2877             break;
2878         case 0xa34:
2879             s->cm_autoidle2_core = value & 0x1f;
2880             break;
2881         case 0xa38:
2882             s->cm_autoidle3_core = value & 0x2;
2883             break;
2884         case 0xa40:
2885             s->cm_clksel_core = (value & 0xff) | 0x100;
2886             omap3_cm_gp10gp11_update(s);
2887             omap3_cm_l3l4iclk_update(s);
2888             break;
2889         case 0xa48:
2890             s->cm_clkstctrl_core = value & 0xf;
2891             break;
2892         /* SGX_CM */
2893         case 0xb00: s->cm_fclken_sgx = value & 0x2; break;
2894         case 0xb10: s->cm_iclken_sgx = value & 0x1; break;
2895         case 0xb40: s->cm_clksel_sgx = value; break; /* TODO: SGX clock */
2896         case 0xb44: s->cm_sleepdep_sgx = value &0x2; break;
2897         case 0xb48: s->cm_clkstctrl_sgx = value & 0x3; break;
2898         /* WKUP_CM */
2899         case 0xc00:
2900             s->cm_fclken_wkup = value & 0x2e9;
2901             omap_clk_onoff(omap_findclk(s->mpu, "omap3_gp1_fclk"),
2902                            s->cm_fclken_wkup & 1);
2903             /* TODO: EN_GPIO1 */
2904             /* TODO: EN_WDT2 */
2905             break;
2906         case 0xc10:
2907             s->cm_iclken_wkup = value & 0x23f;
2908             omap_clk_onoff(omap_findclk(s->mpu, "omap3_wkup_l4_iclk"),
2909                            s->cm_iclken_wkup ? 1 : 0);
2910             break;
2911         case 0xc30: s->cm_autoidle_wkup = value & 0x23f; break;
2912         case 0xc40:
2913             s->cm_clksel_wkup = value & 0x7f;
2914             omap3_cm_clksel_wkup_update(s);
2915             break;
2916         /* Clock_Control_Reg_CM */
2917         case 0xd00:
2918             s->cm_clken_pll = value & 0xffff17ff;
2919             omap3_cm_dpll3_update(s);
2920             omap3_cm_dpll4_update(s);
2921             break;
2922         case 0xd04:
2923             s->cm_clken2_pll = value & 0x7ff;
2924             omap3_cm_dpll5_update(s);
2925             break;
2926         case 0xd30: s->cm_autoidle_pll = value & 0x3f; break;
2927         case 0xd34: s->cm_autoidle2_pll = value & 0x7; break;
2928         case 0xd40:
2929             s->cm_clksel1_pll = value & 0xffffbffc;
2930             omap3_cm_dpll3_update(s);
2931             omap3_cm_48m_update(s);
2932             /* TODO: 96m and 54m update */
2933             break;
2934         case 0xd44:
2935             s->cm_clksel2_pll = value & 0x7ff7f;
2936             omap3_cm_dpll4_update(s);
2937             break;
2938         case 0xd48:
2939             s->cm_clksel3_pll = value & 0x1f;
2940             omap3_cm_dpll4_update(s);
2941             break;
2942         case 0xd4c:
2943             s->cm_clksel4_pll = value & 0x7ff7f;
2944             omap3_cm_dpll5_update(s);
2945             break;
2946         case 0xd50:
2947             s->cm_clksel5_pll = value & 0x1f;
2948             omap3_cm_dpll5_update(s);
2949             break;
2950         case 0xd70:
2951             s->cm_clkout_ctrl = value & 0xbb;
2952             omap3_cm_clkout2_update(s);
2953             break;
2954         /* DSS_CM */
2955         case 0xe00: s->cm_fclken_dss = value & 0x7; break;
2956         case 0xe10: s->cm_iclken_dss = value & 0x1; break;
2957         case 0xe30: s->cm_autoidle_dss = value & 0x1; break;
2958         case 0xe40:
2959             s->cm_clksel_dss = value & 0x1f1f;
2960             omap3_cm_dpll4_update(s);
2961             break;
2962         case 0xe44: s->cm_sleepdep_dss = value & 0x7; break;
2963         case 0xe48: s->cm_clkstctrl_dss = value & 0x3; break;
2964         /* CAM_CM */
2965         case 0xf00: s->cm_fclken_cam = value & 0x3; break;
2966         case 0xf10: s->cm_iclken_cam = value & 0x1; break;
2967         case 0xf30: s->cm_autoidle_cam = value & 0x1; break;
2968         case 0xf40:
2969             s->cm_clksel_cam = value & 0x1f;
2970             omap3_cm_dpll4_update(s);
2971             break;
2972         case 0xf44: s->cm_sleepdep_cam = value & 0x2; break;
2973         case 0xf48: s->cm_clkstctrl_cam = value & 0x3; break;
2974         /* PER_CM */
2975         case 0x1000: s->cm_fclken_per = value & 0x3ffff; break;
2976         case 0x1010: s->cm_iclken_per = value & 0x3ffff; break;
2977         case 0x1030: s->cm_autoidle_per = value &0x3ffff; break;
2978         case 0x1040:
2979             s->cm_clksel_per = value & 0xff;
2980             omap3_cm_per_gptimer_update(s);
2981             break;
2982         case 0x1044: s->cm_sleepdep_per = value & 0x6; break;
2983         case 0x1048: s->cm_clkstctrl_per = value &0x7; break;
2984         /* EMU_CM */
2985         case 0x1140:
2986             s->cm_clksel1_emu = value & 0x1f1f3fff;
2987             omap3_cm_dpll3_update(s);
2988             omap3_cm_dpll4_update(s);
2989             break;
2990         case 0x1148: s->cm_clkstctrl_emu = value & 0x3; break;
2991         case 0x1150:
2992             s->cm_clksel2_emu = value & 0xfff7f;
2993             omap3_cm_dpll3_update(s);
2994             break;
2995         case 0x1154:
2996             s->cm_clksel3_emu = value & 0xfff7f;
2997             omap3_cm_dpll4_update(s);
2998             break;
2999         /* Global_Reg_CM */
3000         case 0x129c: s->cm_polctrl = value & 0x1; break;
3001         /* NEON_CM */
3002         case 0x1348: s->cm_clkstctrl_neon = value & 0x3; break;
3003         /* USBHOST_CM */
3004         case 0x1400: s->cm_fclken_usbhost = value & 0x3; break;
3005         case 0x1410: s->cm_iclken_usbhost = value & 0x1; break;
3006         case 0x1430: s->cm_autoidle_usbhost = value & 0x1; break;
3007         case 0x1444: s->cm_sleepdep_usbhost = value & 0x6; break;
3008         case 0x1448: s->cm_clkstctrl_usbhost = value & 0x3; break;
3009         /* unknown */
3010         default:
3011             OMAP_BAD_REGV(addr, value);
3012             break;
3013     }
3014 }
3015
3016 static void omap3_cm_save_state(QEMUFile *f, void *opaque)
3017 {
3018     struct omap3_cm_s *s = (struct omap3_cm_s *)opaque;
3019     
3020     qemu_put_be32(f, s->cm_fclken_iva2);
3021     qemu_put_be32(f, s->cm_clken_pll_iva2);
3022     qemu_put_be32(f, s->cm_idlest_iva2);
3023     qemu_put_be32(f, s->cm_idlest_pll_iva2);
3024     qemu_put_be32(f, s->cm_autoidle_pll_iva2);
3025     qemu_put_be32(f, s->cm_clksel1_pll_iva2);
3026     qemu_put_be32(f, s->cm_clksel2_pll_iva2);
3027     qemu_put_be32(f, s->cm_clkstctrl_iva2);
3028     qemu_put_be32(f, s->cm_clkstst_iva2);
3029     
3030     qemu_put_be32(f, s->cm_revision);
3031     qemu_put_be32(f, s->cm_sysconfig);
3032     
3033     qemu_put_be32(f, s->cm_clken_pll_mpu);
3034     qemu_put_be32(f, s->cm_idlest_mpu);
3035     qemu_put_be32(f, s->cm_idlest_pll_mpu);
3036     qemu_put_be32(f, s->cm_autoidle_pll_mpu);
3037     qemu_put_be32(f, s->cm_clksel1_pll_mpu);
3038     qemu_put_be32(f, s->cm_clksel2_pll_mpu);
3039     qemu_put_be32(f, s->cm_clkstctrl_mpu);
3040     qemu_put_be32(f, s->cm_clkstst_mpu);
3041     
3042     qemu_put_be32(f, s->cm_fclken1_core);
3043     qemu_put_be32(f, s->cm_fclken3_core);
3044     qemu_put_be32(f, s->cm_iclken1_core);
3045     qemu_put_be32(f, s->cm_iclken2_core);
3046     qemu_put_be32(f, s->cm_iclken3_core);
3047     qemu_put_be32(f, s->cm_idlest1_core);
3048     qemu_put_be32(f, s->cm_idlest2_core);
3049     qemu_put_be32(f, s->cm_idlest3_core);
3050     qemu_put_be32(f, s->cm_autoidle1_core);
3051     qemu_put_be32(f, s->cm_autoidle2_core);
3052     qemu_put_be32(f, s->cm_autoidle3_core);
3053     qemu_put_be32(f, s->cm_clksel_core);
3054     qemu_put_be32(f, s->cm_clkstctrl_core);
3055     qemu_put_be32(f, s->cm_clkstst_core);
3056     
3057     qemu_put_be32(f, s->cm_fclken_sgx);
3058     qemu_put_be32(f, s->cm_iclken_sgx);
3059     qemu_put_be32(f, s->cm_idlest_sgx);
3060     qemu_put_be32(f, s->cm_clksel_sgx);
3061     qemu_put_be32(f, s->cm_sleepdep_sgx);
3062     qemu_put_be32(f, s->cm_clkstctrl_sgx);
3063     qemu_put_be32(f, s->cm_clkstst_sgx);
3064     
3065     qemu_put_be32(f, s->cm_fclken_wkup);
3066     qemu_put_be32(f, s->cm_iclken_wkup);
3067     qemu_put_be32(f, s->cm_idlest_wkup);
3068     qemu_put_be32(f, s->cm_autoidle_wkup);
3069     qemu_put_be32(f, s->cm_clksel_wkup);
3070     qemu_put_be32(f, s->cm_c48);
3071     
3072     qemu_put_be32(f, s->cm_clken_pll);
3073     qemu_put_be32(f, s->cm_clken2_pll);
3074     qemu_put_be32(f, s->cm_idlest_ckgen);
3075     qemu_put_be32(f, s->cm_idlest2_ckgen);
3076     qemu_put_be32(f, s->cm_autoidle_pll);
3077     qemu_put_be32(f, s->cm_autoidle2_pll);
3078     qemu_put_be32(f, s->cm_clksel1_pll);
3079     qemu_put_be32(f, s->cm_clksel2_pll);
3080     qemu_put_be32(f, s->cm_clksel3_pll);
3081     qemu_put_be32(f, s->cm_clksel4_pll);
3082     qemu_put_be32(f, s->cm_clksel5_pll);
3083     qemu_put_be32(f, s->cm_clkout_ctrl);
3084     
3085     qemu_put_be32(f, s->cm_fclken_dss);
3086     qemu_put_be32(f, s->cm_iclken_dss);
3087     qemu_put_be32(f, s->cm_idlest_dss);
3088     qemu_put_be32(f, s->cm_autoidle_dss);
3089     qemu_put_be32(f, s->cm_clksel_dss);
3090     qemu_put_be32(f, s->cm_sleepdep_dss);
3091     qemu_put_be32(f, s->cm_clkstctrl_dss);
3092     qemu_put_be32(f, s->cm_clkstst_dss);
3093     
3094     qemu_put_be32(f, s->cm_fclken_cam);
3095     qemu_put_be32(f, s->cm_iclken_cam);
3096     qemu_put_be32(f, s->cm_idlest_cam);
3097     qemu_put_be32(f, s->cm_autoidle_cam);
3098     qemu_put_be32(f, s->cm_clksel_cam);
3099     qemu_put_be32(f, s->cm_sleepdep_cam);
3100     qemu_put_be32(f, s->cm_clkstctrl_cam);
3101     qemu_put_be32(f, s->cm_clkstst_cam);
3102
3103     qemu_put_be32(f, s->cm_fclken_per);
3104     qemu_put_be32(f, s->cm_iclken_per);
3105     qemu_put_be32(f, s->cm_idlest_per);
3106     qemu_put_be32(f, s->cm_autoidle_per);
3107     qemu_put_be32(f, s->cm_clksel_per);
3108     qemu_put_be32(f, s->cm_sleepdep_per);
3109     qemu_put_be32(f, s->cm_clkstctrl_per);
3110     qemu_put_be32(f, s->cm_clkstst_per);
3111     
3112     qemu_put_be32(f, s->cm_clksel1_emu);
3113     qemu_put_be32(f, s->cm_clkstctrl_emu);
3114     qemu_put_be32(f, s->cm_clkstst_emu);
3115     qemu_put_be32(f, s->cm_clksel2_emu);
3116     qemu_put_be32(f, s->cm_clksel3_emu);
3117     
3118     qemu_put_be32(f, s->cm_polctrl);
3119
3120     qemu_put_be32(f, s->cm_idlest_neon);
3121     qemu_put_be32(f, s->cm_clkstctrl_neon);
3122
3123     qemu_put_be32(f, s->cm_fclken_usbhost);
3124     qemu_put_be32(f, s->cm_iclken_usbhost);
3125     qemu_put_be32(f, s->cm_idlest_usbhost);
3126     qemu_put_be32(f, s->cm_autoidle_usbhost);
3127     qemu_put_be32(f, s->cm_sleepdep_usbhost);
3128     qemu_put_be32(f, s->cm_clkstctrl_usbhost);
3129     qemu_put_be32(f, s->cm_clkstst_usbhost);
3130 }
3131
3132 static int omap3_cm_load_state(QEMUFile *f, void *opaque, int version_id)
3133 {
3134     struct omap3_cm_s *s = (struct omap3_cm_s *)opaque;
3135     
3136     if (version_id)
3137         return -EINVAL;
3138     
3139     s->cm_fclken_iva2 = qemu_get_be32(f);
3140     s->cm_clken_pll_iva2 = qemu_get_be32(f);
3141     s->cm_idlest_iva2 = qemu_get_be32(f);
3142     s->cm_idlest_pll_iva2 = qemu_get_be32(f);
3143     s->cm_autoidle_pll_iva2 = qemu_get_be32(f);
3144     s->cm_clksel1_pll_iva2 = qemu_get_be32(f);
3145     s->cm_clksel2_pll_iva2 = qemu_get_be32(f);
3146     s->cm_clkstctrl_iva2 = qemu_get_be32(f);
3147     s->cm_clkstst_iva2 = qemu_get_be32(f);
3148     
3149     s->cm_revision = qemu_get_be32(f);
3150     s->cm_sysconfig = qemu_get_be32(f);
3151     
3152     s->cm_clken_pll_mpu = qemu_get_be32(f);
3153     s->cm_idlest_mpu = qemu_get_be32(f);
3154     s->cm_idlest_pll_mpu = qemu_get_be32(f);
3155     s->cm_autoidle_pll_mpu = qemu_get_be32(f);
3156     s->cm_clksel1_pll_mpu = qemu_get_be32(f);
3157     s->cm_clksel2_pll_mpu = qemu_get_be32(f);
3158     s->cm_clkstctrl_mpu = qemu_get_be32(f);
3159     s->cm_clkstst_mpu = qemu_get_be32(f);
3160     
3161     s->cm_fclken1_core = qemu_get_be32(f);
3162     s->cm_fclken3_core = qemu_get_be32(f);
3163     s->cm_iclken1_core = qemu_get_be32(f);
3164     s->cm_iclken2_core = qemu_get_be32(f);
3165     s->cm_iclken3_core = qemu_get_be32(f);
3166     s->cm_idlest1_core = qemu_get_be32(f);
3167     s->cm_idlest2_core = qemu_get_be32(f);
3168     s->cm_idlest3_core = qemu_get_be32(f);
3169     s->cm_autoidle1_core = qemu_get_be32(f);
3170     s->cm_autoidle2_core = qemu_get_be32(f);
3171     s->cm_autoidle3_core = qemu_get_be32(f);
3172     s->cm_clksel_core = qemu_get_be32(f);
3173     s->cm_clkstctrl_core = qemu_get_be32(f);
3174     s->cm_clkstst_core = qemu_get_be32(f);
3175     
3176     s->cm_fclken_sgx = qemu_get_be32(f);
3177     s->cm_iclken_sgx = qemu_get_be32(f);
3178     s->cm_idlest_sgx = qemu_get_be32(f);
3179     s->cm_clksel_sgx = qemu_get_be32(f);
3180     s->cm_sleepdep_sgx = qemu_get_be32(f);
3181     s->cm_clkstctrl_sgx = qemu_get_be32(f);
3182     s->cm_clkstst_sgx = qemu_get_be32(f);
3183     
3184     s->cm_fclken_wkup = qemu_get_be32(f);
3185     s->cm_iclken_wkup = qemu_get_be32(f);
3186     s->cm_idlest_wkup = qemu_get_be32(f);
3187     s->cm_autoidle_wkup = qemu_get_be32(f);
3188     s->cm_clksel_wkup = qemu_get_be32(f);
3189     s->cm_c48 = qemu_get_be32(f);
3190     
3191     s->cm_clken_pll = qemu_get_be32(f);
3192     s->cm_clken2_pll = qemu_get_be32(f);
3193     s->cm_idlest_ckgen = qemu_get_be32(f);
3194     s->cm_idlest2_ckgen = qemu_get_be32(f);
3195     s->cm_autoidle_pll = qemu_get_be32(f);
3196     s->cm_autoidle2_pll = qemu_get_be32(f);
3197     s->cm_clksel1_pll = qemu_get_be32(f);
3198     s->cm_clksel2_pll = qemu_get_be32(f);
3199     s->cm_clksel3_pll = qemu_get_be32(f);
3200     s->cm_clksel4_pll = qemu_get_be32(f);
3201     s->cm_clksel5_pll = qemu_get_be32(f);
3202     s->cm_clkout_ctrl = qemu_get_be32(f);
3203     
3204     s->cm_fclken_dss = qemu_get_be32(f);
3205     s->cm_iclken_dss = qemu_get_be32(f);
3206     s->cm_idlest_dss = qemu_get_be32(f);
3207     s->cm_autoidle_dss = qemu_get_be32(f);
3208     s->cm_clksel_dss = qemu_get_be32(f);
3209     s->cm_sleepdep_dss = qemu_get_be32(f);
3210     s->cm_clkstctrl_dss = qemu_get_be32(f);
3211     s->cm_clkstst_dss = qemu_get_be32(f);
3212     
3213     s->cm_fclken_cam = qemu_get_be32(f);
3214     s->cm_iclken_cam = qemu_get_be32(f);
3215     s->cm_idlest_cam = qemu_get_be32(f);
3216     s->cm_autoidle_cam = qemu_get_be32(f);
3217     s->cm_clksel_cam = qemu_get_be32(f);
3218     s->cm_sleepdep_cam = qemu_get_be32(f);
3219     s->cm_clkstctrl_cam = qemu_get_be32(f);
3220     s->cm_clkstst_cam = qemu_get_be32(f);
3221     
3222     s->cm_fclken_per = qemu_get_be32(f);
3223     s->cm_iclken_per = qemu_get_be32(f);
3224     s->cm_idlest_per = qemu_get_be32(f);
3225     s->cm_autoidle_per = qemu_get_be32(f);
3226     s->cm_clksel_per = qemu_get_be32(f);
3227     s->cm_sleepdep_per = qemu_get_be32(f);
3228     s->cm_clkstctrl_per = qemu_get_be32(f);
3229     s->cm_clkstst_per = qemu_get_be32(f);
3230     
3231     s->cm_clksel1_emu = qemu_get_be32(f);
3232     s->cm_clkstctrl_emu = qemu_get_be32(f);
3233     s->cm_clkstst_emu = qemu_get_be32(f);
3234     s->cm_clksel2_emu = qemu_get_be32(f);
3235     s->cm_clksel3_emu = qemu_get_be32(f);
3236     
3237     s->cm_polctrl = qemu_get_be32(f);
3238     
3239     s->cm_idlest_neon = qemu_get_be32(f);
3240     s->cm_clkstctrl_neon = qemu_get_be32(f);
3241     
3242     s->cm_fclken_usbhost = qemu_get_be32(f);
3243     s->cm_iclken_usbhost = qemu_get_be32(f);
3244     s->cm_idlest_usbhost = qemu_get_be32(f);
3245     s->cm_autoidle_usbhost = qemu_get_be32(f);
3246     s->cm_sleepdep_usbhost = qemu_get_be32(f);
3247     s->cm_clkstctrl_usbhost = qemu_get_be32(f);
3248     s->cm_clkstst_usbhost = qemu_get_be32(f);
3249
3250     omap3_cm_iva2_update(s);
3251     omap3_cm_mpu_update(s);
3252     omap3_cm_fclken1_core_update(s);
3253     omap3_cm_iclken1_core_update(s);
3254     omap3_cm_gp10gp11_update(s);
3255     omap3_cm_l3l4iclk_update(s);
3256     omap_clk_onoff(omap_findclk(s->mpu, "omap3_gp1_fclk"),
3257                    s->cm_fclken_wkup & 1);
3258     omap_clk_onoff(omap_findclk(s->mpu, "omap3_wkup_l4_iclk"),
3259                    s->cm_iclken_wkup ? 1 : 0);
3260     omap3_cm_clksel_wkup_update(s);
3261     omap3_cm_dpll3_update(s);
3262     omap3_cm_dpll4_update(s);
3263     omap3_cm_dpll5_update(s);
3264     omap3_cm_48m_update(s);
3265     omap3_cm_clkout2_update(s);
3266     omap3_cm_per_gptimer_update(s);
3267     
3268     return 0;
3269 }
3270
3271 static CPUReadMemoryFunc *omap3_cm_readfn[] = {
3272     omap_badwidth_read32,
3273     omap_badwidth_read32,
3274     omap3_cm_read,
3275 };
3276
3277 static CPUWriteMemoryFunc *omap3_cm_writefn[] = {
3278     omap_badwidth_write32,
3279     omap_badwidth_write32,
3280     omap3_cm_write,
3281 };
3282
3283 struct omap3_cm_s *omap3_cm_init(struct omap_target_agent_s *ta,
3284                                  qemu_irq mpu_int, qemu_irq dsp_int,
3285                                  qemu_irq iva_int, struct omap_mpu_state_s *mpu)
3286 {
3287     int iomemtype;
3288     struct omap3_cm_s *s = (struct omap3_cm_s *) qemu_mallocz(sizeof(*s));
3289
3290     s->irq[0] = mpu_int;
3291     s->irq[1] = dsp_int;
3292     s->irq[2] = iva_int;
3293     s->mpu = mpu;
3294     omap3_cm_reset(s);
3295
3296     iomemtype = l4_register_io_memory(0, omap3_cm_readfn, omap3_cm_writefn, s);
3297     omap_l4_attach(ta, 0, iomemtype);
3298     omap_l4_attach(ta, 1, iomemtype);
3299
3300     register_savevm("omap3_cm", -1, 0,
3301                     omap3_cm_save_state, omap3_cm_load_state, s);
3302     return s;
3303 }
3304
3305 #define OMAP3_SEC_WDT          1
3306 #define OMAP3_MPU_WDT         2
3307 #define OMAP3_IVA2_WDT        3
3308 /*omap3 watchdog timer*/
3309 struct omap3_wdt_s
3310 {
3311     qemu_irq irq;               /*IVA2 IRQ */
3312     struct omap_mpu_state_s *mpu;
3313     omap_clk clk;
3314     QEMUTimer *timer;
3315
3316     int active;
3317     int64_t rate;
3318     int64_t time;
3319     //int64_t ticks_per_sec;
3320
3321     uint32_t wd_sysconfig;
3322     uint32_t wd_sysstatus;
3323     uint32_t wisr;
3324     uint32_t wier;
3325     uint32_t wclr;
3326     uint32_t wcrr;
3327     uint32_t wldr;
3328     uint32_t wtgr;
3329     uint32_t wwps;
3330     uint32_t wspr;
3331
3332     /*pre and ptv in wclr */
3333     uint32_t pre;
3334     uint32_t ptv;
3335     //uint32_t val;
3336
3337     uint16_t writeh;            /* LSB */
3338     uint16_t readh;             /* MSB */
3339 };
3340
3341 static inline void omap3_wdt_timer_update(struct omap3_wdt_s *wdt_timer)
3342 {
3343     int64_t expires;
3344     if (wdt_timer->active) {
3345         expires = muldiv64(0xffffffffll - wdt_timer->wcrr,
3346                            ticks_per_sec, wdt_timer->rate);
3347         qemu_mod_timer(wdt_timer->timer, wdt_timer->time + expires);
3348     } else
3349         qemu_del_timer(wdt_timer->timer);
3350 }
3351
3352 static void omap3_wdt_clk_setup(struct omap3_wdt_s *timer)
3353 {
3354     /*TODO: Add irq as user to clk */
3355 }
3356
3357 static inline uint32_t omap3_wdt_timer_read(struct omap3_wdt_s *timer)
3358 {
3359     uint64_t distance;
3360
3361     if (timer->active) {
3362         distance = qemu_get_clock(vm_clock) - timer->time;
3363         distance = muldiv64(distance, timer->rate, ticks_per_sec);
3364
3365         if (distance >= 0xffffffff - timer->wcrr)
3366             return 0xffffffff;
3367         else
3368             return timer->wcrr + distance;
3369     } else
3370         return timer->wcrr;
3371 }
3372
3373 /*
3374 static inline void omap3_wdt_timer_sync(struct omap3_wdt_s *timer)
3375 {
3376     if (timer->active) {
3377         timer->val = omap3_wdt_timer_read(timer);
3378         timer->time = qemu_get_clock(vm_clock);
3379     }
3380 }*/
3381
3382 static void omap3_wdt_reset(struct omap3_wdt_s *s, int wdt_index)
3383 {
3384     s->wd_sysconfig = 0x0;
3385     s->wd_sysstatus = 0x0;
3386     s->wisr = 0x0;
3387     s->wier = 0x0;
3388     s->wclr = 0x20;
3389     s->wcrr = 0x0;
3390     switch (wdt_index) {
3391         case OMAP3_MPU_WDT:
3392         case OMAP3_IVA2_WDT:
3393             s->wldr = 0xfffb0000;
3394             break;
3395         case OMAP3_SEC_WDT:
3396             s->wldr = 0xffa60000;
3397             break;
3398         default:
3399             break;
3400     }
3401     s->wtgr = 0x0;
3402     s->wwps = 0x0;
3403     s->wspr = 0x0;
3404
3405     switch (wdt_index) {
3406         case OMAP3_SEC_WDT:
3407         case OMAP3_MPU_WDT:
3408             s->active = 1;
3409             break;
3410         case OMAP3_IVA2_WDT:
3411             s->active = 0;
3412             break;
3413         default:
3414             break;
3415     }
3416     s->pre = s->wclr & (1 << 5);
3417     s->ptv = (s->wclr & 0x1c) >> 2;
3418     s->rate = omap_clk_getrate(s->clk) >> (s->pre ? s->ptv : 0);
3419
3420     s->active = 1;
3421     s->time = qemu_get_clock(vm_clock);
3422     omap3_wdt_timer_update(s);
3423 }
3424
3425 static uint32_t omap3_wdt_read32(void *opaque, target_phys_addr_t addr,
3426                                  int wdt_index)
3427 {
3428     struct omap3_wdt_s *s = (struct omap3_wdt_s *) opaque;
3429
3430     switch (addr) {
3431         case 0x10: return s->wd_sysconfig;
3432         case 0x14: return s->wd_sysstatus;
3433         case 0x18: return s->wisr & 0x1;
3434         case 0x1c: return s->wier & 0x1;
3435         case 0x24: return s->wclr & 0x3c;
3436         case 0x28: /* WCRR */
3437             s->wcrr = omap3_wdt_timer_read(s);
3438             s->time = qemu_get_clock(vm_clock);
3439             return s->wcrr;
3440         case 0x2c: return s->wldr;
3441         case 0x30: return s->wtgr;
3442         case 0x34: return s->wwps;
3443         case 0x48: return s->wspr;
3444         default: break;
3445     }
3446     OMAP_BAD_REG(addr);
3447     return 0;
3448 }
3449
3450 static uint32_t omap3_mpu_wdt_read16(void *opaque, target_phys_addr_t addr)
3451 {
3452     struct omap3_wdt_s *s = (struct omap3_wdt_s *) opaque;
3453     uint32_t ret;
3454
3455     if (addr & 2)
3456         return s->readh;
3457
3458     ret = omap3_wdt_read32(opaque, addr, OMAP3_MPU_WDT);
3459     s->readh = ret >> 16;
3460     return ret & 0xffff;
3461 }
3462
3463 static uint32_t omap3_mpu_wdt_read32(void *opaque, target_phys_addr_t addr)
3464 {
3465     return omap3_wdt_read32(opaque, addr, OMAP3_MPU_WDT);
3466 }
3467
3468 static void omap3_wdt_write32(void *opaque, target_phys_addr_t addr,
3469                               uint32_t value, int wdt_index)
3470 {
3471     struct omap3_wdt_s *s = (struct omap3_wdt_s *) opaque;
3472
3473     switch (addr) {
3474     case 0x14: /* WD_SYSSTATUS */
3475     case 0x34: /* WWPS */
3476         OMAP_RO_REGV(addr, value);
3477         break;
3478     case 0x10: /*WD_SYSCONFIG */
3479         s->wd_sysconfig = value & 0x33f;
3480         break;
3481     case 0x18: /* WISR */
3482          s->wisr = value & 0x1;
3483         break;
3484     case 0x1c: /* WIER */
3485         s->wier = value & 0x1;
3486         break;
3487     case 0x24: /* WCLR */
3488         s->wclr = value & 0x3c;
3489         break;
3490     case 0x28: /* WCRR */
3491         s->wcrr = value;
3492         s->time = qemu_get_clock(vm_clock);
3493         omap3_wdt_timer_update(s);
3494         break;
3495     case 0x2c: /* WLDR */
3496         s->wldr = value; /* It will take effect after next overflow */
3497         break;
3498     case 0x30: /* WTGR */
3499         if (value != s->wtgr) {
3500             s->wcrr = s->wldr;
3501             s->pre = s->wclr & (1 << 5);
3502             s->ptv = (s->wclr & 0x1c) >> 2;
3503             s->rate = omap_clk_getrate(s->clk) >> (s->pre ? s->ptv : 0);
3504             s->time = qemu_get_clock(vm_clock);
3505             omap3_wdt_timer_update(s);
3506         }
3507         s->wtgr = value;
3508         break;
3509     case 0x48: /* WSPR */
3510         if (((value & 0xffff) == 0x5555) && ((s->wspr & 0xffff) == 0xaaaa)) {
3511             s->active = 0;
3512             s->wcrr = omap3_wdt_timer_read(s);
3513             omap3_wdt_timer_update(s);
3514         }
3515         if (((value & 0xffff) == 0x4444) && ((s->wspr & 0xffff) == 0xbbbb)) {
3516             s->active = 1;
3517             s->time = qemu_get_clock(vm_clock);
3518             omap3_wdt_timer_update(s);
3519         }
3520         s->wspr = value;
3521         break;
3522     default:
3523         OMAP_BAD_REGV(addr, value);
3524         break;
3525     }
3526 }
3527
3528 static void omap3_mpu_wdt_write16(void *opaque, target_phys_addr_t addr,
3529                                   uint32_t value)
3530 {
3531     struct omap3_wdt_s *s = (struct omap3_wdt_s *) opaque;
3532
3533     if (addr & 2)
3534         return omap3_wdt_write32(opaque, addr, (value << 16) | s->writeh,
3535                                  OMAP3_MPU_WDT);
3536     else
3537         s->writeh = (uint16_t) value;
3538 }
3539
3540 static void omap3_mpu_wdt_write32(void *opaque, target_phys_addr_t addr,
3541                                   uint32_t value)
3542 {
3543     omap3_wdt_write32(opaque, addr, value, OMAP3_MPU_WDT);
3544 }
3545
3546 static CPUReadMemoryFunc *omap3_mpu_wdt_readfn[] = {
3547     omap_badwidth_read32,
3548     omap3_mpu_wdt_read16,
3549     omap3_mpu_wdt_read32,
3550 };
3551
3552 static CPUWriteMemoryFunc *omap3_mpu_wdt_writefn[] = {
3553     omap_badwidth_write32,
3554     omap3_mpu_wdt_write16,
3555     omap3_mpu_wdt_write32,
3556 };
3557
3558 static void omap3_mpu_wdt_timer_tick(void *opaque)
3559 {
3560     struct omap3_wdt_s *wdt_timer = (struct omap3_wdt_s *) opaque;
3561
3562     /*TODO:Sent reset pulse to PRCM */
3563     wdt_timer->wcrr = wdt_timer->wldr;
3564
3565     /*after overflow, generate the new wdt_timer->rate */
3566     wdt_timer->pre = wdt_timer->wclr & (1 << 5);
3567     wdt_timer->ptv = (wdt_timer->wclr & 0x1c) >> 2;
3568     wdt_timer->rate =
3569         omap_clk_getrate(wdt_timer->clk) >> (wdt_timer->pre ? wdt_timer->
3570                                              ptv : 0);
3571
3572     wdt_timer->time = qemu_get_clock(vm_clock);
3573     omap3_wdt_timer_update(wdt_timer);
3574 }
3575
3576 static void omap3_mpu_wdt_save_state(QEMUFile *f, void *opaque)
3577 {
3578     struct omap3_wdt_s *s = (struct omap3_wdt_s *)opaque;
3579
3580     qemu_put_timer(f, s->timer);
3581     qemu_put_sbe32(f, s->active);
3582     qemu_put_be64(f, s->rate);
3583     qemu_put_be64(f, s->time);
3584     qemu_put_be32(f, s->wd_sysconfig);
3585     qemu_put_be32(f, s->wd_sysstatus);
3586     qemu_put_be32(f, s->wisr);
3587     qemu_put_be32(f, s->wier);
3588     qemu_put_be32(f, s->wclr);
3589     qemu_put_be32(f, s->wcrr);
3590     qemu_put_be32(f, s->wldr);
3591     qemu_put_be32(f, s->wtgr);
3592     qemu_put_be32(f, s->wwps);
3593     qemu_put_be32(f, s->wspr);
3594     qemu_put_be32(f, s->pre);
3595     qemu_put_be32(f, s->ptv);
3596     qemu_put_be16(f, s->writeh);
3597     qemu_put_be16(f, s->readh);
3598 }
3599
3600 static int omap3_mpu_wdt_load_state(QEMUFile *f, void *opaque, int version_id)
3601 {
3602     struct omap3_wdt_s *s = (struct omap3_wdt_s *)opaque;
3603     
3604     if (version_id)
3605         return -EINVAL;
3606     
3607     qemu_get_timer(f, s->timer);
3608     s->active = qemu_get_sbe32(f);
3609     s->rate = qemu_get_be64(f);
3610     s->time = qemu_get_be64(f);
3611     s->wd_sysconfig = qemu_get_be32(f);
3612     s->wd_sysstatus = qemu_get_be32(f);
3613     s->wisr = qemu_get_be32(f);
3614     s->wier = qemu_get_be32(f);
3615     s->wclr = qemu_get_be32(f);
3616     s->wcrr = qemu_get_be32(f);
3617     s->wldr = qemu_get_be32(f);
3618     s->wtgr = qemu_get_be32(f);
3619     s->wwps = qemu_get_be32(f);
3620     s->wspr = qemu_get_be32(f);
3621     s->pre = qemu_get_be32(f);
3622     s->ptv = qemu_get_be32(f);
3623     s->writeh = qemu_get_be16(f);
3624     s->readh = qemu_get_be16(f);
3625     
3626     return 0;
3627 }
3628
3629 static struct omap3_wdt_s *omap3_mpu_wdt_init(struct omap_target_agent_s *ta,
3630                                               qemu_irq irq, omap_clk fclk,
3631                                               omap_clk iclk,
3632                                               struct omap_mpu_state_s *mpu)
3633 {
3634     int iomemtype;
3635     struct omap3_wdt_s *s = (struct omap3_wdt_s *) qemu_mallocz(sizeof(*s));
3636
3637     s->irq = irq;
3638     s->clk = fclk;
3639     s->timer = qemu_new_timer(vm_clock, omap3_mpu_wdt_timer_tick, s);
3640
3641     omap3_wdt_reset(s, OMAP3_MPU_WDT);
3642     if (irq != NULL)
3643         omap3_wdt_clk_setup(s);
3644
3645     iomemtype = l4_register_io_memory(0, omap3_mpu_wdt_readfn,
3646                                       omap3_mpu_wdt_writefn, s);
3647     omap_l4_attach(ta, 0, iomemtype);
3648
3649     register_savevm("omap3_mpu_wdt", -1, 0,
3650                     omap3_mpu_wdt_save_state, omap3_mpu_wdt_load_state, s);
3651     return s;
3652 }
3653
3654 struct omap3_scm_s {
3655     struct omap_mpu_state_s *mpu;
3656
3657         uint8 interface[48];     /*0x4800 2000*/
3658         uint8 padconfs[576];     /*0x4800 2030*/
3659         uint32 general[228];     /*0x4800 2270*/
3660         uint8 mem_wkup[1024];    /*0x4800 2600*/
3661         uint8 padconfs_wkup[84]; /*0x4800 2a00*/
3662         uint32 general_wkup[8];  /*0x4800 2a60*/
3663 };
3664
3665 static void omap3_scm_save_state(QEMUFile *f, void *opaque)
3666 {
3667     struct omap3_scm_s *s = (struct omap3_scm_s *)opaque;
3668     int i;
3669
3670     qemu_put_buffer(f, s->interface, sizeof(s->interface));
3671     qemu_put_buffer(f, s->padconfs, sizeof(s->padconfs));
3672     for (i = 0; i < sizeof(s->general)/sizeof(uint32); i++)
3673         qemu_put_be32(f, s->general[i]);
3674     qemu_put_buffer(f, s->mem_wkup, sizeof(s->mem_wkup));
3675     qemu_put_buffer(f, s->padconfs_wkup, sizeof(s->padconfs_wkup));
3676     for (i = 0; i < sizeof(s->general_wkup)/sizeof(uint32); i++)
3677         qemu_put_be32(f, s->general_wkup[i]);
3678 }
3679
3680 static int omap3_scm_load_state(QEMUFile *f, void *opaque, int version_id)
3681 {
3682     struct omap3_scm_s *s = (struct omap3_scm_s *)opaque;
3683     int i;
3684     
3685     if (version_id)
3686         return -EINVAL;
3687     
3688     qemu_get_buffer(f, s->interface, sizeof(s->interface));
3689     qemu_get_buffer(f, s->padconfs, sizeof(s->padconfs));
3690     for (i = 0; i < sizeof(s->general)/sizeof(uint32); i++)
3691         s->general[i] = qemu_get_be32(f);
3692     qemu_get_buffer(f, s->mem_wkup, sizeof(s->mem_wkup));
3693     qemu_get_buffer(f, s->padconfs_wkup, sizeof(s->padconfs_wkup));
3694     for (i = 0; i < sizeof(s->general_wkup)/sizeof(uint32); i++)
3695         s->general_wkup[i] = qemu_get_be32(f);
3696
3697     return 0;
3698 }
3699
3700 #define PADCONFS_VALUE(wakeup0,wakeup1,offmode0,offmode1, \
3701                                                 inputenable0,inputenable1,pupd0,pupd1,muxmode0,muxmode1,offset) \
3702         do { \
3703                  *(padconfs+offset/4) = (wakeup0 <<14)|(offmode0<<9)|(inputenable0<<8)|(pupd0<<3)|(muxmode0); \
3704                  *(padconfs+offset/4) |= (wakeup1 <<30)|(offmode1<<25)|(inputenable1<<24)|(pupd1<<19)|(muxmode1<<16); \
3705 } while (0)
3706
3707
3708 static void omap3_scm_reset(struct omap3_scm_s *s)
3709 {
3710     uint32 * padconfs;
3711     padconfs = (uint32 *)(s->padconfs);
3712     PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x0);
3713     PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x4);
3714     PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x8);
3715     PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0xc);
3716     PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x10);
3717     PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x14);
3718     PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x18);
3719     PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x1c);
3720     PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x20);
3721     PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x24);
3722     PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x28);
3723     PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x2c);
3724     PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x30);
3725     PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x34);
3726     PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x38);
3727     PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x3c);
3728     PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x40);
3729     PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x44);
3730     PADCONFS_VALUE(0,0,0,0,1,1,0,1,0,7,0x48);
3731     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x4c);
3732     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x50);
3733     PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x54);
3734     PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x58);
3735     PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,0,0x5c);
3736     PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x60);
3737     PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x64);
3738     PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x68);
3739     PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x6c);
3740     PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x70);
3741     PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x74);
3742     PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x78);
3743     PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x7c);
3744     PADCONFS_VALUE(0,0,0,0,1,1,0,3,0,7,0x80);
3745     PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x84);
3746     PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x88);
3747     PADCONFS_VALUE(0,0,0,0,1,1,3,0,7,0,0x8c);
3748     PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x90);
3749     PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x94);
3750     PADCONFS_VALUE(0,0,0,0,1,1,1,0,7,0,0x98);
3751     PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,7,0x9c);
3752     PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0xa0);
3753     PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0xa4);
3754     PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0xa8);
3755     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xac);
3756     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xb0);
3757     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xb4);
3758     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xb8);
3759     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xbc);
3760     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xc0);
3761     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xc4);
3762     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xc8);
3763     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xcc);
3764     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xd0);
3765     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xd4);
3766     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xd8);
3767     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xdc);
3768     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xe0);
3769     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xe4);
3770     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xe8);
3771     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xec);
3772     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xf0);
3773     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xf4);
3774     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xf8);
3775     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xfc);
3776     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x100);
3777     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x104);
3778     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x108);
3779     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x10c);
3780     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x110);
3781     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x114);
3782     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x118);
3783     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x11c);
3784     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x120);
3785     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x124);
3786     PADCONFS_VALUE(0,0,0,0,1,1,1,3,7,7,0x128);
3787     PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x12c);
3788     PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x130);
3789     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x134);
3790     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x138);
3791     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x13c);
3792     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x140);
3793     PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x144);
3794     PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x148);
3795     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x14c);
3796     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x150);
3797     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x154);
3798     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x158);
3799     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x15c);
3800     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x160);
3801     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x164);
3802     PADCONFS_VALUE(0,0,0,0,1,1,1,3,7,7,0x168);
3803     PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x16c);
3804     PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0x170);
3805     PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0x174);
3806     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x178);
3807     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x17c);
3808     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x180);
3809     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x184);
3810     PADCONFS_VALUE(0,0,0,0,1,1,1,3,7,7,0x188);
3811     PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x18c);
3812     PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x190);
3813     PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x194);
3814     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x198);
3815     PADCONFS_VALUE(0,0,0,0,1,1,1,3,7,7,0x19c);
3816     PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x1a0);
3817     PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0x1a4);
3818     PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x1a8);
3819     PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0x1ac);
3820     PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0x1b0);
3821     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1b4);
3822     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1b8);
3823     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1bc);
3824     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1c0);
3825     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1c4);
3826     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1c8);
3827     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1cc);
3828     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1d0);
3829     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1d4);
3830     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1d8);
3831     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1dc);
3832     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1e0);
3833     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1e4);
3834     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1e8);
3835     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1ec);
3836     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1f0);
3837     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1f4);
3838     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1f8);
3839     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1fc);
3840     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x200);
3841     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x204);
3842     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x208);
3843     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x20c);
3844     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x210);
3845     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x214);
3846     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x218);
3847     PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x21c);
3848     PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x220);
3849     PADCONFS_VALUE(0,0,0,0,1,1,3,1,0,0,0x224);
3850     PADCONFS_VALUE(0,0,0,0,1,1,0,1,0,0,0x228);
3851     PADCONFS_VALUE(0,0,0,0,1,1,0,1,0,0,0x22c);
3852     PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x230);
3853     PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x234);
3854
3855         padconfs = (uint32 *)(s->general);
3856     memset(s->general, 0, sizeof(s->general));
3857         s->general[0x01] = 0x4000000;  /* CONTROL_DEVCONF_0 */
3858         s->general[0x1c] = 0x1;        /* 0x480022e0?? */
3859     s->general[0x20] = 0x30f;      /* CONTROL_STATUS:
3860                                     * - device type  = GP Device
3861                                     * - sys_boot:6   = oscillator bypass mode
3862                                     * - sys_boot:0-5 = NAND, USB, UART3, MMC1*/
3863         s->general[0x75] = 0x7fc0;     /* CONTROL_PROG_IO0 */
3864         s->general[0x76] = 0xaa;       /* CONTROL_PROG_IO1 */
3865         s->general[0x7c] = 0x2700;     /* CONTROL_SDRC_SHARING */
3866         s->general[0x7d] = 0x300000;   /* CONTROL_SDRC_MCFG0 */
3867         s->general[0x7e] = 0x300000;   /* CONTROL_SDRC_MCFG1 */
3868         s->general[0x81] = 0xffff;     /* CONTROL_MODEM_GPMC_DT_FW_REQ_INFO */
3869         s->general[0x82] = 0xffff;     /* CONTROL_MODEM_GPMC_DT_FW_RD */
3870         s->general[0x83] = 0xffff;     /* CONTROL_MODEM_GPMC_DT_FW_WR */
3871         s->general[0x84] = 0x6;        /* CONTROL_MODEM_GPMC_BOOT_CODE */
3872         s->general[0x85] = 0xffffffff; /* CONTROL_MODEM_SMS_RG_ATT1 */
3873         s->general[0x86] = 0xffff;     /* CONTROL_MODEM_SMS_RG_RDPERM1 */
3874         s->general[0x87] = 0xffff;     /* CONTROL_MODEM_SMS_RG_WRPERM1 */
3875         s->general[0x88] = 0x1;        /* CONTROL_MODEM_D2D_FW_DEBUG_MODE */
3876         s->general[0x8b] = 0xffffffff; /* CONTROL_DPF_OCM_RAM_FW_REQINFO */
3877         s->general[0x8c] = 0xffff;     /* CONTROL_DPF_OCM_RAM_FW_WR */
3878         s->general[0x8e] = 0xffff;     /* CONTROL_DPF_REGION4_GPMC_FW_REQINFO */
3879         s->general[0x8f] = 0xffff;     /* CONTROL_DPF_REGION4_GPMC_FW_WR */
3880         s->general[0x91] = 0xffff;     /* CONTROL_DPF_REGION1_IVA2_FW_REQINFO */
3881         s->general[0x92] = 0xffff;     /* CONTROL_DPF_REGION1_IVA2_FW_WR */
3882         s->general[0xac] = 0x109;      /* CONTROL_PBIAS_LITE */
3883         s->general[0xb2] = 0xffff;     /* CONTROL_DPF_MAD2D_FW_ADDR_MATCH */
3884         s->general[0xb3] = 0xffff;     /* CONTROL_DPF_MAD2D_FW_REQINFO */
3885         s->general[0xb4] = 0xffff;     /* CONTROL_DPF_MAD2D_FW_WR */
3886         PADCONFS_VALUE(0,0,0,0,1,1,3,3,4,4,0x368); /* PADCONF_ETK_CLK */
3887     PADCONFS_VALUE(0,0,0,0,1,1,3,3,4,4,0x36c); /* PADCONF_ETK_D0 */
3888     PADCONFS_VALUE(0,0,0,0,1,1,3,3,4,4,0x370); /* PADCONF_ETK_D2 */
3889     PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x374); /* PADCONF_ETK_D4 */
3890     PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x378); /* PADCONF_ETK_D6 */
3891     PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x37c); /* PADCONF_ETK_D8 */
3892     PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x380); /* PADCONF_ETK_D10 */
3893     PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x384); /* PADCONF_ETK_D12 */
3894     PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x388); /* PADCONF_ETK_D14 */
3895
3896         padconfs = (uint32 *)(s->padconfs_wkup);
3897         PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x0);
3898         PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x4);
3899         PADCONFS_VALUE(0,0,0,0,1,1,3,0,0,0,0x8);
3900         PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0xc);
3901         PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x10);
3902         PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x14);
3903         PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x18);
3904         PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1c);
3905         PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x20);
3906         PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x24);
3907         PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x2c);
3908
3909         s->general_wkup[0] = 0x66ff; /* 0x48002A60?? */
3910 }
3911
3912 static uint32_t omap3_scm_read8(void *opaque, target_phys_addr_t addr)
3913 {
3914     struct omap3_scm_s *s = (struct omap3_scm_s *) opaque;
3915     uint8_t* temp;
3916         
3917     switch (addr) {
3918         case 0x000 ... 0x02f: return s->interface[addr];
3919         case 0x030 ... 0x26f: return s->padconfs[addr - 0x30];
3920         case 0x270 ... 0x5ff: temp = (uint8_t *)s->general; return temp[addr - 0x270];
3921         case 0x600 ... 0x9ff: return s->mem_wkup[addr - 0x600];
3922         case 0xa00 ... 0xa5f: return s->padconfs_wkup[addr - 0xa00];
3923         case 0xa60 ... 0xa7f: temp = (uint8_t *)s->general_wkup; return temp[addr - 0xa60];
3924         default: break;
3925     }
3926     OMAP_BAD_REG(addr);
3927     return 0;
3928 }
3929
3930 static uint32_t omap3_scm_read16(void *opaque, target_phys_addr_t addr)
3931 {
3932     uint32_t v;
3933     v = omap3_scm_read8(opaque, addr);
3934     v |= omap3_scm_read8(opaque, addr + 1) << 8;
3935     return v;
3936 }
3937
3938 static uint32_t omap3_scm_read32(void *opaque, target_phys_addr_t addr)
3939 {
3940     uint32_t v;
3941     v = omap3_scm_read8(opaque, addr);
3942     v |= omap3_scm_read8(opaque, addr + 1) << 8;
3943     v |= omap3_scm_read8(opaque, addr + 2) << 16;
3944     v |= omap3_scm_read8(opaque, addr + 3) << 24;
3945     return v;
3946 }
3947
3948 static void omap3_scm_write8(void *opaque, target_phys_addr_t addr,
3949                              uint32_t value)
3950 {
3951     struct omap3_scm_s *s = (struct omap3_scm_s *) opaque;
3952     uint8_t* temp;
3953
3954     switch (addr) {
3955         case 0x000 ... 0x02f: s->interface[addr] = value; break;
3956         case 0x030 ... 0x26f: s->padconfs[addr-0x30] = value; break;
3957         case 0x270 ... 0x5ff: temp = (uint8_t *)s->general; temp[addr-0x270] = value; break;
3958         case 0x600 ... 0x9ff: s->mem_wkup[addr-0x600] = value; break;
3959         case 0xa00 ... 0xa5f: s->padconfs_wkup[addr-0xa00] = value; break;
3960         case 0xa60 ... 0xa7f: temp = (uint8_t *)s->general_wkup; temp[addr-0xa60] = value; break;
3961         default: OMAP_BAD_REGV(addr, value); break;
3962     }
3963 }
3964
3965 static void omap3_scm_write16(void *opaque, target_phys_addr_t addr,
3966                               uint32_t value)
3967 {
3968     omap3_scm_write8(opaque, addr + 0, (value) & 0xff);
3969     omap3_scm_write8(opaque, addr + 1, (value >> 8) & 0xff);
3970 }
3971
3972 static void omap3_scm_write32(void *opaque, target_phys_addr_t addr,
3973                               uint32_t value)
3974 {
3975     omap3_scm_write8(opaque, addr + 0, (value) & 0xff);
3976     omap3_scm_write8(opaque, addr + 1, (value >> 8) & 0xff);
3977     omap3_scm_write8(opaque, addr + 2, (value >> 16) & 0xff);
3978     omap3_scm_write8(opaque, addr + 3, (value >> 24) & 0xff);
3979 }
3980
3981 static CPUReadMemoryFunc *omap3_scm_readfn[] = {
3982     omap3_scm_read8,
3983     omap3_scm_read16,
3984     omap3_scm_read32,
3985 };
3986
3987 static CPUWriteMemoryFunc *omap3_scm_writefn[] = {
3988     omap3_scm_write8,
3989     omap3_scm_write16,
3990     omap3_scm_write32,
3991 };
3992
3993 static struct omap3_scm_s *omap3_scm_init(struct omap_target_agent_s *ta,
3994                                           struct omap_mpu_state_s *mpu)
3995 {
3996     int iomemtype;
3997     struct omap3_scm_s *s = (struct omap3_scm_s *) qemu_mallocz(sizeof(*s));
3998
3999     s->mpu = mpu;
4000
4001     omap3_scm_reset(s);
4002
4003     iomemtype = l4_register_io_memory(0, omap3_scm_readfn,
4004                                       omap3_scm_writefn, s);
4005     omap_l4_attach(ta, 0, iomemtype);
4006     
4007     register_savevm("omap3_scm", -1, 0,
4008                     omap3_scm_save_state, omap3_scm_load_state, s);
4009     return s;
4010 }
4011
4012 /*dummy SDRAM Memory Scheduler emulation*/
4013 struct omap3_sms_s
4014 {
4015     struct omap_mpu_state_s *mpu;
4016
4017     uint32 sms_sysconfig;
4018     uint32 sms_sysstatus;
4019     uint32 sms_rg_att[8];
4020     uint32 sms_rg_rdperm[8];
4021     uint32 sms_rg_wrperm[8];
4022     uint32 sms_rg_start[7];
4023     uint32 sms_rg_end[7];
4024     uint32 sms_security_control;
4025     uint32 sms_class_arbiter0;
4026     uint32 sms_class_arbiter1;
4027     uint32 sms_class_arbiter2;
4028     uint32 sms_interclass_arbiter;
4029     uint32 sms_class_rotation[3];
4030     uint32 sms_err_addr;
4031     uint32 sms_err_type;
4032     uint32 sms_pow_ctrl;
4033     uint32 sms_rot_control[12];
4034     uint32 sms_rot_size[12];
4035     uint32 sms_rot_physical_ba[12];
4036 };
4037
4038 static void omap3_sms_save_state(QEMUFile *f, void *opaque)
4039 {
4040     struct omap3_sms_s *s = (struct omap3_sms_s *)opaque;
4041     int i;
4042
4043     qemu_put_be32(f, s->sms_sysconfig);
4044     qemu_put_be32(f, s->sms_sysstatus);
4045     for (i = 0; i < 8; i++) {
4046         qemu_put_be32(f, s->sms_rg_att[i]);
4047         qemu_put_be32(f, s->sms_rg_rdperm[i]);
4048         qemu_put_be32(f, s->sms_rg_wrperm[i]);
4049         if (i < 7) {
4050             qemu_put_be32(f, s->sms_rg_start[i]);
4051             qemu_put_be32(f, s->sms_rg_end[i]);
4052         }
4053     }
4054     qemu_put_be32(f, s->sms_security_control);
4055     qemu_put_be32(f, s->sms_class_arbiter0);
4056     qemu_put_be32(f, s->sms_class_arbiter1);
4057     qemu_put_be32(f, s->sms_class_arbiter2);
4058     qemu_put_be32(f, s->sms_interclass_arbiter);
4059     qemu_put_be32(f, s->sms_class_rotation[0]);
4060     qemu_put_be32(f, s->sms_class_rotation[1]);
4061     qemu_put_be32(f, s->sms_class_rotation[2]);
4062     qemu_put_be32(f, s->sms_err_addr);
4063     qemu_put_be32(f, s->sms_err_type);
4064     qemu_put_be32(f, s->sms_pow_ctrl);
4065     for (i = 0; i< 12; i++) {
4066         qemu_put_be32(f, s->sms_rot_control[i]);
4067         qemu_put_be32(f, s->sms_rot_size[i]);
4068         qemu_put_be32(f, s->sms_rot_physical_ba[i]);
4069     }
4070 }
4071
4072 static int omap3_sms_load_state(QEMUFile *f, void *opaque, int version_id)
4073 {
4074     struct omap3_sms_s *s = (struct omap3_sms_s *)opaque;
4075     int i;
4076     
4077     if (version_id)
4078         return -EINVAL;
4079     
4080     s->sms_sysconfig = qemu_get_be32(f);
4081     s->sms_sysstatus = qemu_get_be32(f);
4082     for (i = 0; i < 8; i++) {
4083         s->sms_rg_att[i] = qemu_get_be32(f);
4084         s->sms_rg_rdperm[i] = qemu_get_be32(f);
4085         s->sms_rg_wrperm[i] = qemu_get_be32(f);
4086         if (i < 7) {
4087             s->sms_rg_start[i] = qemu_get_be32(f);
4088             s->sms_rg_end[i] = qemu_get_be32(f);
4089         }
4090     }
4091     s->sms_security_control = qemu_get_be32(f);
4092     s->sms_class_arbiter0 = qemu_get_be32(f);
4093     s->sms_class_arbiter1 = qemu_get_be32(f);
4094     s->sms_class_arbiter2 = qemu_get_be32(f);
4095     s->sms_interclass_arbiter = qemu_get_be32(f);
4096     s->sms_class_rotation[0] = qemu_get_be32(f);
4097     s->sms_class_rotation[1] = qemu_get_be32(f);
4098     s->sms_class_rotation[2] = qemu_get_be32(f);
4099     s->sms_err_addr = qemu_get_be32(f);
4100     s->sms_err_type = qemu_get_be32(f);
4101     s->sms_pow_ctrl = qemu_get_be32(f);
4102     for (i = 0; i< 12; i++) {
4103         s->sms_rot_control[i] = qemu_get_be32(f);
4104         s->sms_rot_size[i] = qemu_get_be32(f);
4105         s->sms_rot_physical_ba[i] = qemu_get_be32(f);
4106     }
4107     
4108     return 0;
4109 }
4110
4111 static uint32_t omap3_sms_read32(void *opaque, target_phys_addr_t addr)
4112 {
4113     struct omap3_sms_s *s = (struct omap3_sms_s *) opaque;
4114
4115     switch (addr)
4116     {
4117     case 0x10:
4118         return s->sms_sysconfig;
4119     case 0x14:
4120         return s->sms_sysstatus;
4121     case 0x48:
4122     case 0x68:
4123     case 0x88:
4124     case 0xa8:
4125     case 0xc8:
4126     case 0xe8:
4127     case 0x108:
4128     case 0x128:
4129         return s->sms_rg_att[(addr-0x48)/0x20];
4130     case 0x50:
4131     case 0x70:
4132     case 0x90:
4133     case 0xb0:
4134     case 0xd0:
4135     case 0xf0:
4136     case 0x110:
4137     case 0x130:
4138         return s->sms_rg_rdperm[(addr-0x50)/0x20];
4139     case 0x58:
4140     case 0x78:
4141     case 0x98:
4142     case 0xb8:
4143     case 0xd8:
4144     case 0xf8:
4145     case 0x118:
4146         return s->sms_rg_wrperm[(addr-0x58)/0x20];
4147     case 0x60:
4148     case 0x80:
4149     case 0xa0:
4150     case 0xc0:
4151     case 0xe0:
4152     case 0x100:
4153     case 0x120:
4154         return s->sms_rg_start[(addr-0x60)/0x20];
4155
4156     case 0x64:
4157     case 0x84:
4158     case 0xa4:
4159     case 0xc4:
4160     case 0xe4:
4161     case 0x104:
4162     case 0x124:
4163         return s->sms_rg_end[(addr-0x64)/0x20];
4164     case 0x140:
4165         return s->sms_security_control;
4166     case 0x150:
4167         return s->sms_class_arbiter0;
4168         case 0x154:
4169                 return s->sms_class_arbiter1;
4170         case 0x158:
4171                 return s->sms_class_arbiter2;
4172         case 0x160:
4173                 return s->sms_interclass_arbiter;
4174         case 0x164:
4175         case 0x168:
4176         case 0x16c:
4177                 return s->sms_class_rotation[(addr-0x164)/4];
4178         case 0x170:
4179                 return s->sms_err_addr;
4180         case 0x174:
4181                 return s->sms_err_type;
4182         case 0x178:
4183                 return s->sms_pow_ctrl;
4184         case 0x180:
4185         case 0x190:
4186         case 0x1a0:
4187         case 0x1b0:
4188         case 0x1c0:
4189         case 0x1d0:
4190         case 0x1e0:
4191         case 0x1f0:
4192         case 0x200:
4193         case 0x210:
4194         case 0x220:
4195         case 0x230:
4196                 return s->sms_rot_control[(addr-0x180)/0x10];
4197         case 0x184:
4198         case 0x194:
4199         case 0x1a4:
4200         case 0x1b4:
4201         case 0x1c4:
4202         case 0x1d4:
4203         case 0x1e4:
4204         case 0x1f4:
4205         case 0x204:
4206         case 0x214:
4207         case 0x224:
4208         case 0x234:
4209                 return s->sms_rot_size[(addr-0x184)/0x10];
4210
4211         case 0x188:
4212         case 0x198:
4213         case 0x1a8:
4214         case 0x1b8:
4215         case 0x1c8:
4216         case 0x1d8:
4217         case 0x1e8:
4218         case 0x1f8:
4219         case 0x208:
4220         case 0x218:
4221         case 0x228:
4222         case 0x238:
4223                 return s->sms_rot_size[(addr-0x188)/0x10];
4224
4225     default:
4226         break;
4227     }
4228     OMAP_BAD_REG(addr);
4229     return 0;
4230 }
4231
4232 static void omap3_sms_write32(void *opaque, target_phys_addr_t addr,
4233                               uint32_t value)
4234 {
4235     struct omap3_sms_s *s = (struct omap3_sms_s *) opaque;
4236     //int i;
4237
4238     switch (addr)
4239     {
4240     case 0x14:
4241         OMAP_RO_REG(addr);
4242         return;
4243     case 0x10:
4244         s->sms_sysconfig = value & 0x1f;
4245         break;
4246     
4247     case 0x48:
4248     case 0x68:
4249     case 0x88:
4250     case 0xa8:
4251     case 0xc8:
4252     case 0xe8:
4253     case 0x108:
4254     case 0x128:
4255         s->sms_rg_att[(addr-0x48)/0x20] = value;
4256         break;
4257     case 0x50:
4258     case 0x70:
4259     case 0x90:
4260     case 0xb0:
4261     case 0xd0:
4262     case 0xf0:
4263     case 0x110:
4264     case 0x130:
4265         s->sms_rg_rdperm[(addr-0x50)/0x20] = value&0xffff;
4266         break;
4267     case 0x58:
4268     case 0x78:
4269     case 0x98:
4270     case 0xb8:
4271     case 0xd8:
4272     case 0xf8:
4273     case 0x118:
4274         s->sms_rg_wrperm[(addr-0x58)/0x20] = value&0xffff;
4275         break;          
4276     case 0x60:
4277     case 0x80:
4278     case 0xa0:
4279     case 0xc0:
4280     case 0xe0:
4281     case 0x100:
4282     case 0x120:
4283         s->sms_rg_start[(addr-0x60)/0x20] = value;
4284         break;
4285     case 0x64:
4286     case 0x84:
4287     case 0xa4:
4288     case 0xc4:
4289     case 0xe4:
4290     case 0x104:
4291     case 0x124:
4292         s->sms_rg_end[(addr-0x64)/0x20] = value;
4293         break;
4294     case 0x140:
4295         s->sms_security_control = value &0xfffffff;
4296         break;
4297     case 0x150:
4298         s->sms_class_arbiter0 = value;
4299         break;
4300         case 0x154:
4301                 s->sms_class_arbiter1 = value;
4302                 break;
4303         case 0x158:
4304                 s->sms_class_arbiter2 = value;
4305                 break;
4306         case 0x160:
4307                 s->sms_interclass_arbiter = value;
4308                 break;
4309         case 0x164:
4310         case 0x168:
4311         case 0x16c:
4312                 s->sms_class_rotation[(addr-0x164)/4] = value;
4313                 break;
4314         case 0x170:
4315                 s->sms_err_addr = value;
4316                 break;
4317         case 0x174:
4318                 s->sms_err_type = value;
4319                 break;
4320         case 0x178:
4321                 s->sms_pow_ctrl = value;
4322                 break;
4323         case 0x180:
4324         case 0x190:
4325         case 0x1a0:
4326         case 0x1b0:
4327         case 0x1c0:
4328         case 0x1d0:
4329         case 0x1e0:
4330         case 0x1f0:
4331         case 0x200:
4332         case 0x210:
4333         case 0x220:
4334         case 0x230:
4335                 s->sms_rot_control[(addr-0x180)/0x10] = value;
4336                 break;
4337         case 0x184:
4338         case 0x194:
4339         case 0x1a4:
4340         case 0x1b4:
4341         case 0x1c4:
4342         case 0x1d4:
4343         case 0x1e4:
4344         case 0x1f4:
4345         case 0x204:
4346         case 0x214:
4347         case 0x224:
4348         case 0x234:
4349                 s->sms_rot_size[(addr-0x184)/0x10] = value;
4350                 break;
4351
4352         case 0x188:
4353         case 0x198:
4354         case 0x1a8:
4355         case 0x1b8:
4356         case 0x1c8:
4357         case 0x1d8:
4358         case 0x1e8:
4359         case 0x1f8:
4360         case 0x208:
4361         case 0x218:
4362         case 0x228:
4363         case 0x238:
4364                 s->sms_rot_size[(addr-0x188)/0x10] = value;   
4365                 break;
4366         default:
4367         OMAP_BAD_REGV(addr, value);
4368         break;
4369     }
4370 }
4371
4372 static CPUReadMemoryFunc *omap3_sms_readfn[] = {
4373     omap_badwidth_read32,
4374     omap_badwidth_read32,
4375     omap3_sms_read32,
4376 };
4377
4378 static CPUWriteMemoryFunc *omap3_sms_writefn[] = {
4379     omap_badwidth_write32,
4380     omap_badwidth_write32,
4381     omap3_sms_write32,
4382 };
4383
4384 static void omap3_sms_reset(struct omap3_sms_s *s)
4385 {
4386         s->sms_sysconfig = 0x1;
4387         s->sms_class_arbiter0 = 0x500000;
4388         s->sms_class_arbiter1 = 0x500;
4389         s->sms_class_arbiter2 = 0x55000;
4390         s->sms_interclass_arbiter = 0x400040;
4391         s->sms_class_rotation[0] = 0x1;
4392         s->sms_class_rotation[1] = 0x1;
4393         s->sms_class_rotation[2] = 0x1;
4394         s->sms_pow_ctrl = 0x80;
4395 }
4396
4397 static struct omap3_sms_s *omap3_sms_init(struct omap_mpu_state_s *mpu)
4398 {
4399     int iomemtype;
4400     struct omap3_sms_s *s = (struct omap3_sms_s *) qemu_mallocz(sizeof(*s));
4401
4402     s->mpu = mpu;
4403
4404     omap3_sms_reset(s);
4405     
4406     iomemtype = cpu_register_io_memory(0, omap3_sms_readfn,
4407                                        omap3_sms_writefn, s);
4408     cpu_register_physical_memory(0x6c000000, 0x10000, iomemtype);
4409
4410     register_savevm("omap3_sms", -1, 0,
4411                     omap3_sms_save_state, omap3_sms_load_state, s);
4412     return s;
4413 }
4414
4415 static const struct dma_irq_map omap3_dma_irq_map[] = {
4416     {0, OMAP_INT_3XXX_SDMA_IRQ0},
4417     {0, OMAP_INT_3XXX_SDMA_IRQ1},
4418     {0, OMAP_INT_3XXX_SDMA_IRQ2},
4419     {0, OMAP_INT_3XXX_SDMA_IRQ3},
4420 };
4421
4422 static int omap3_validate_addr(struct omap_mpu_state_s *s,
4423                                target_phys_addr_t addr)
4424 {
4425     return 1;
4426 }
4427
4428 struct omap_mpu_state_s *omap3530_mpu_init(unsigned long sdram_size,
4429                                            const char *core)
4430 {
4431     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
4432         qemu_mallocz(sizeof(struct omap_mpu_state_s));
4433     ram_addr_t sram_base, q2_base, bootrom_base;
4434     qemu_irq *cpu_irq;
4435     qemu_irq dma_irqs[4];
4436     int i;
4437
4438     s->mpu_model = omap3530;
4439     s->env = cpu_init("cortex-a8-r2");
4440     if (!s->env) {
4441         fprintf(stderr, "Unable to find CPU definition\n");
4442         exit(1);
4443     }
4444     s->sdram_size = sdram_size;
4445     s->sram_size = OMAP3XXX_SRAM_SIZE;
4446
4447     /* Clocks */
4448     omap_clk_init(s);
4449
4450     /* Memory-mapped stuff */
4451
4452     q2_base = qemu_ram_alloc(s->sdram_size);
4453     cpu_register_physical_memory(OMAP3_Q2_BASE, s->sdram_size,
4454                                  q2_base | IO_MEM_RAM);
4455     sram_base = qemu_ram_alloc(s->sram_size);
4456     cpu_register_physical_memory(OMAP3_SRAM_BASE, s->sram_size,
4457                                  sram_base | IO_MEM_RAM);
4458     bootrom_base = qemu_ram_alloc(OMAP3XXX_BOOTROM_SIZE);
4459     cpu_register_physical_memory(OMAP3_Q1_BASE + 0x14000,
4460                                  OMAP3XXX_BOOTROM_SIZE,
4461                                  bootrom_base | IO_MEM_ROM);
4462     cpu_register_physical_memory(0, OMAP3XXX_BOOTROM_SIZE,
4463                                  bootrom_base | IO_MEM_ROM);
4464
4465     s->l4 = omap_l4_init(OMAP3_L4_BASE, 
4466                          sizeof(omap3_l4_agent_info) 
4467                          / sizeof(struct omap3_l4_agent_info_s));
4468
4469     cpu_irq = arm_pic_init_cpu(s->env);
4470     s->ih[0] = omap2_inth_init(s, 0x48200000, 0x1000, 3, &s->irq[0],
4471                                cpu_irq[ARM_PIC_CPU_IRQ],
4472                                cpu_irq[ARM_PIC_CPU_FIQ], 
4473                                omap_findclk(s, "omap3_mpu_intc_fclk"),
4474                                omap_findclk(s, "omap3_mpu_intc_iclk"));
4475
4476     for (i = 0; i < 4; i++)
4477         dma_irqs[i] =
4478             s->irq[omap3_dma_irq_map[i].ih][omap3_dma_irq_map[i].intr];
4479     s->dma = omap_dma4_init(0x48056000, dma_irqs, s, 256, 32,
4480                             omap_findclk(s, "omap3_sdma_fclk"),
4481                             omap_findclk(s, "omap3_sdma_iclk"));
4482     s->port->addr_valid = omap3_validate_addr;
4483
4484     /* Register SDRAM and SRAM ports for fast DMA transfers.  */
4485     soc_dma_port_add_mem_ram(s->dma, q2_base, OMAP2_Q2_BASE, s->sdram_size);
4486     soc_dma_port_add_mem_ram(s->dma, sram_base, OMAP2_SRAM_BASE, s->sram_size);
4487
4488
4489     s->omap3_cm = omap3_cm_init(omap3_l4ta_init(s->l4, L4A_CM), NULL, NULL, NULL, s);
4490
4491     s->omap3_prm = omap3_prm_init(omap3_l4ta_init(s->l4, L4A_PRM),
4492                                   s->irq[0][OMAP_INT_3XXX_PRCM_MPU_IRQ],
4493                                   NULL, s);
4494
4495     s->omap3_mpu_wdt = omap3_mpu_wdt_init(omap3_l4ta_init(s->l4, L4A_WDTIMER2),
4496                                           NULL,
4497                                           omap_findclk(s, "omap3_wkup_32k_fclk"),
4498                                           omap_findclk(s, "omap3_wkup_l4_iclk"),
4499                                           s);
4500
4501     s->omap3_l3 = omap3_l3_init(OMAP3_L3_BASE, 
4502                                 omap3_l3_region,
4503                                 sizeof(omap3_l3_region)
4504                                 / sizeof(struct omap_l3_region_s));
4505     s->omap3_scm = omap3_scm_init(omap3_l4ta_init(s->l4, L4A_SCM), s);
4506
4507     s->omap3_sms = omap3_sms_init(s);
4508
4509     s->gptimer[0] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER1),
4510                                        s->irq[0][OMAP_INT_3XXX_GPT1_IRQ],
4511                                        omap_findclk(s, "omap3_gp1_fclk"),
4512                                        omap_findclk(s, "omap3_wkup_l4_iclk"));
4513     s->gptimer[1] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER2),
4514                                        s->irq[0][OMAP_INT_3XXX_GPT2_IRQ],
4515                                        omap_findclk(s, "omap3_gp2_fclk"),
4516                                        omap_findclk(s, "omap3_per_l4_iclk"));
4517     s->gptimer[2] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER3),
4518                                        s->irq[0][OMAP_INT_3XXX_GPT3_IRQ],
4519                                        omap_findclk(s, "omap3_gp3_fclk"),
4520                                        omap_findclk(s, "omap3_per_l4_iclk"));
4521     s->gptimer[3] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER4),
4522                                        s->irq[0][OMAP_INT_3XXX_GPT4_IRQ],
4523                                        omap_findclk(s, "omap3_gp4_fclk"),
4524                                        omap_findclk(s, "omap3_per_l4_iclk"));
4525     s->gptimer[4] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER5),
4526                                        s->irq[0][OMAP_INT_3XXX_GPT5_IRQ],
4527                                        omap_findclk(s, "omap3_gp5_fclk"),
4528                                        omap_findclk(s, "omap3_per_l4_iclk"));
4529     s->gptimer[5] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER6),
4530                                        s->irq[0][OMAP_INT_3XXX_GPT6_IRQ],
4531                                        omap_findclk(s, "omap3_gp6_fclk"),
4532                                        omap_findclk(s, "omap3_per_l4_iclk"));
4533     s->gptimer[6] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER7),
4534                                        s->irq[0][OMAP_INT_3XXX_GPT7_IRQ],
4535                                        omap_findclk(s, "omap3_gp7_fclk"),
4536                                        omap_findclk(s, "omap3_per_l4_iclk"));
4537     s->gptimer[7] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER8),
4538                                        s->irq[0][OMAP_INT_3XXX_GPT8_IRQ],
4539                                        omap_findclk(s, "omap3_gp8_fclk"),
4540                                        omap_findclk(s, "omap3_per_l4_iclk"));
4541     s->gptimer[8] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER9),
4542                                        s->irq[0][OMAP_INT_3XXX_GPT9_IRQ],
4543                                        omap_findclk(s, "omap3_gp9_fclk"),
4544                                        omap_findclk(s, "omap3_per_l4_iclk"));
4545     s->gptimer[9] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER10),
4546                                        s->irq[0][OMAP_INT_3XXX_GPT10_IRQ],
4547                                        omap_findclk(s, "omap3_gp10_fclk"),
4548                                        omap_findclk(s, "omap3_core_l4_iclk"));
4549     s->gptimer[10] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER11),
4550                                        s->irq[0][OMAP_INT_3XXX_GPT11_IRQ],
4551                                        omap_findclk(s, "omap3_gp12_fclk"),
4552                                        omap_findclk(s, "omap3_core_l4_iclk"));
4553     s->gptimer[11] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER12),
4554                                         s->irq[0][OMAP_INT_3XXX_GPT12_IRQ],
4555                                         omap_findclk(s, "omap3_gp12_fclk"),
4556                                         omap_findclk(s, "omap3_wkup_l4_iclk"));
4557     
4558         
4559     omap_synctimer_init(omap3_l4ta_init(s->l4, L4A_32KTIMER), s,
4560                         omap_findclk(s, "omap3_sys_32k"), NULL);
4561
4562     s->sdrc = omap_sdrc_init(0x6d000000);
4563     
4564     s->gpmc = omap_gpmc_init(s, 0x6e000000, s->irq[0][OMAP_INT_3XXX_GPMC_IRQ]);
4565     
4566
4567     s->uart[0] = omap2_uart_init(omap3_l4ta_init(s->l4, L4A_UART1),
4568                                  s->irq[0][OMAP_INT_3XXX_UART1_IRQ],
4569                                  omap_findclk(s, "omap3_uart1_fclk"),
4570                                  omap_findclk(s, "omap3_uart1_iclk"),
4571                                  s->drq[OMAP3XXX_DMA_UART1_TX],
4572                                  s->drq[OMAP3XXX_DMA_UART1_RX], 0);
4573     s->uart[1] = omap2_uart_init(omap3_l4ta_init(s->l4, L4A_UART2),
4574                                  s->irq[0][OMAP_INT_3XXX_UART2_IRQ],
4575                                  omap_findclk(s, "omap3_uart2_fclk"),
4576                                  omap_findclk(s, "omap3_uart2_iclk"),
4577                                  s->drq[OMAP3XXX_DMA_UART2_TX],
4578                                  s->drq[OMAP3XXX_DMA_UART2_RX], 0);
4579     s->uart[2] = omap2_uart_init(omap3_l4ta_init(s->l4, L4A_UART3),
4580                                  s->irq[0][OMAP_INT_3XXX_UART3_IRQ],
4581                                  omap_findclk(s, "omap3_uart2_fclk"),
4582                                  omap_findclk(s, "omap3_uart3_iclk"),
4583                                  s->drq[OMAP3XXX_DMA_UART3_TX],
4584                                  s->drq[OMAP3XXX_DMA_UART3_RX], 0);
4585     
4586     s->dss = omap_dss_init(s, omap3_l4ta_init(s->l4, L4A_DSS), 
4587                     s->irq[0][OMAP_INT_3XXX_DSS_IRQ], s->drq[OMAP24XX_DMA_DSS],
4588                    NULL,NULL,NULL,NULL,NULL);
4589
4590     s->gpif = omap3_gpif_init();
4591     omap3_gpio_init(s, s->gpif ,omap3_l4ta_init(s->l4, L4A_GPIO1),
4592                     &s->irq[0][OMAP_INT_3XXX_GPIO1_MPU_IRQ], 
4593                     NULL,NULL,0);
4594     omap3_gpio_init(s, s->gpif ,omap3_l4ta_init(s->l4, L4A_GPIO2),
4595                     &s->irq[0][OMAP_INT_3XXX_GPIO2_MPU_IRQ], 
4596                     NULL,NULL,1);
4597     omap3_gpio_init(s, s->gpif ,omap3_l4ta_init(s->l4, L4A_GPIO3),
4598                     &s->irq[0][OMAP_INT_3XXX_GPIO3_MPU_IRQ], 
4599                     NULL,NULL,2);
4600     omap3_gpio_init(s, s->gpif ,omap3_l4ta_init(s->l4, L4A_GPIO4),
4601                     &s->irq[0][OMAP_INT_3XXX_GPIO4_MPU_IRQ], 
4602                     NULL,NULL,3);
4603     omap3_gpio_init(s, s->gpif ,omap3_l4ta_init(s->l4, L4A_GPIO5),
4604                     &s->irq[0][OMAP_INT_3XXX_GPIO5_MPU_IRQ], 
4605                     NULL,NULL,4);
4606     omap3_gpio_init(s, s->gpif ,omap3_l4ta_init(s->l4, L4A_GPIO6),
4607                     &s->irq[0][OMAP_INT_3XXX_GPIO6_MPU_IRQ], 
4608                     NULL,NULL,5);
4609
4610     omap_tap_init(omap3_l4ta_init(s->l4, L4A_TAP), s);
4611
4612     s->omap3_mmc[0] = omap3_mmc_init(omap3_l4ta_init(s->l4, L4A_MMC1),
4613                                      s->irq[0][OMAP_INT_3XXX_MMC1_IRQ],
4614                                      &s->drq[OMAP3XXX_DMA_MMC1_TX],
4615                                      omap_findclk(s, "omap3_mmc1_fclk"),
4616                                      omap_findclk(s, "omap3_mmc1_iclk"));
4617
4618     s->omap3_mmc[1] = omap3_mmc_init(omap3_l4ta_init(s->l4, L4A_MMC2),
4619                                      s->irq[0][OMAP_INT_3XXX_MMC2_IRQ],
4620                                      &s->drq[OMAP3XXX_DMA_MMC2_TX],
4621                                      omap_findclk(s, "omap3_mmc2_fclk"),
4622                                      omap_findclk(s, "omap3_mmc2_iclk"));
4623
4624     s->omap3_mmc[2] = omap3_mmc_init(omap3_l4ta_init(s->l4, L4A_MMC3),
4625                                      s->irq[0][OMAP_INT_3XXX_MMC3_IRQ],
4626                                      &s->drq[OMAP3XXX_DMA_MMC3_TX],
4627                                      omap_findclk(s, "omap3_mmc3_fclk"),
4628                                      omap_findclk(s, "omap3_mmc3_iclk"));
4629
4630     s->i2c[0] = omap3_i2c_init(omap3_l4ta_init(s->l4, L4A_I2C1),
4631                                s->irq[0][OMAP_INT_3XXX_I2C1_IRQ],
4632                                &s->drq[OMAP3XXX_DMA_I2C1_TX],
4633                                omap_findclk(s, "omap3_i2c1_fclk"),
4634                                omap_findclk(s, "omap3_i2c1_iclk"),
4635                                8);
4636     s->i2c[1] = omap3_i2c_init(omap3_l4ta_init(s->l4, L4A_I2C2),
4637                                s->irq[0][OMAP_INT_3XXX_I2C2_IRQ],
4638                                &s->drq[OMAP3XXX_DMA_I2C2_TX],
4639                                omap_findclk(s, "omap3_i2c2_fclk"),
4640                                omap_findclk(s, "omap3_i2c2_iclk"),
4641                                8);
4642     s->i2c[2] = omap3_i2c_init(omap3_l4ta_init(s->l4, L4A_I2C3),
4643                                s->irq[0][OMAP_INT_3XXX_I2C3_IRQ],
4644                                &s->drq[OMAP3XXX_DMA_I2C3_TX],
4645                                omap_findclk(s, "omap3_i2c3_fclk"),
4646                                omap_findclk(s, "omap3_i2c3_iclk"),
4647                                64);
4648
4649     s->omap3_usb = omap3_hsusb_init(omap3_l4ta_init(s->l4, L4A_USBHS_OTG),
4650                                     omap3_l4ta_init(s->l4, L4A_USBHS_HOST),
4651                                     omap3_l4ta_init(s->l4, L4A_USBHS_TLL),
4652                                     s->irq[0][OMAP_INT_3XXX_HSUSB_MC],
4653                                     s->irq[0][OMAP_INT_3XXX_HSUSB_DMA],
4654                                     s->irq[0][OMAP_INT_3XXX_OHCI_IRQ],
4655                                     s->irq[0][OMAP_INT_3XXX_EHCI_IRQ],
4656                                     s->irq[0][OMAP_INT_3XXX_TLL_IRQ]);
4657     return s;
4658 }