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