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