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