~ubuntu-branches/ubuntu/trusty/qemu/trusty

« back to all changes in this revision

Viewing changes to debian/patches/linaro-patches-1.5.0/0048-hw-omap3.c-add-omap3-basic-support.patch

  • Committer: Package Import Robot
  • Author(s): Serge Hallyn
  • Date: 2013-10-22 22:47:07 UTC
  • mfrom: (1.8.3) (10.1.42 sid)
  • Revision ID: package-import@ubuntu.com-20131022224707-1lya34fw3k3f24tv
Tags: 1.6.0+dfsg-2ubuntu1
* Merge 1.6.0~rc0+dfsg-2exp from debian experimental.  Remaining changes:
  - debian/control
    * update maintainer
    * remove libiscsi, usb-redir, vde, vnc-jpeg, and libssh2-1-dev
      from build-deps
    * enable rbd
    * add qemu-system and qemu-common B/R to qemu-keymaps
    * add D:udev, R:qemu, R:qemu-common and B:qemu-common to
      qemu-system-common
    * qemu-system-arm, qemu-system-ppc, qemu-system-sparc:
      - add qemu-kvm to Provides
      - add qemu-common, qemu-kvm, kvm to B/R
      - remove openbios-sparc from qemu-system-sparc D
      - drop openbios-ppc and openhackware Depends to Suggests (for now)
    * qemu-system-x86:
      - add qemu-common to Breaks/Replaces.
      - add cpu-checker to Recommends.
    * qemu-user: add B/R:qemu-kvm
    * qemu-kvm:
      - add armhf armel powerpc sparc to Architecture
      - C/R/P: qemu-kvm-spice
    * add qemu-common package
    * drop qemu-slof which is not packaged in ubuntu
  - add qemu-system-common.links for tap ifup/down scripts and OVMF link.
  - qemu-system-x86.links:
    * remove pxe rom links which are in kvm-ipxe
    * add symlink for kvm.1 manpage
  - debian/rules
    * add kvm-spice symlink to qemu-kvm
    * call dh_installmodules for qemu-system-x86
    * update dh_installinit to install upstart script
    * run dh_installman (Closes: #709241) (cherrypicked from 1.5.0+dfsg-2)
  - Add qemu-utils.links for kvm-* symlinks.
  - Add qemu-system-x86.qemu-kvm.upstart and .default
  - Add qemu-system-x86.modprobe to set nesting=1
  - Add qemu-system-common.preinst to add kvm group
  - qemu-system-common.postinst: remove bad group acl if there, then have
    udev relabel /dev/kvm.
  - New linaro patches from qemu-linaro rebasing branch
  - Dropped patches:
    * xen-simplify-xen_enabled.patch
    * sparc-linux-user-fix-missing-symbols-in-.rel-.rela.plt-sections.patch
    * main_loop-do-not-set-nonblocking-if-xen_enabled.patch
    * xen_machine_pv-do-not-create-a-dummy-CPU-in-machine-.patch
    * virtio-rng-fix-crash
  - Kept patches:
    * expose_vms_qemu64cpu.patch - updated
    * linaro arm patches from qemu-linaro rebasing branch
  - New patches:
    * fix-pci-add: change CONFIG variable in ifdef to make sure that
      pci_add is defined.
* Add linaro patches
* Add experimental mach-virt patches for arm virtualization.
* qemu-system-common.install: add debian/tmp/usr/lib to install the
  qemu-bridge-helper

Show diffs side-by-side

added added

removed removed

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