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