xref: /openbmc/qemu/hw/arm/omap2.c (revision cb94ff5f)
1dd285b06SPaolo Bonzini /*
2dd285b06SPaolo Bonzini  * TI OMAP processors emulation.
3dd285b06SPaolo Bonzini  *
4dd285b06SPaolo Bonzini  * Copyright (C) 2007-2008 Nokia Corporation
5dd285b06SPaolo Bonzini  * Written by Andrzej Zaborowski <andrew@openedhand.com>
6dd285b06SPaolo Bonzini  *
7dd285b06SPaolo Bonzini  * This program is free software; you can redistribute it and/or
8dd285b06SPaolo Bonzini  * modify it under the terms of the GNU General Public License as
9dd285b06SPaolo Bonzini  * published by the Free Software Foundation; either version 2 or
10dd285b06SPaolo Bonzini  * (at your option) version 3 of the License.
11dd285b06SPaolo Bonzini  *
12dd285b06SPaolo Bonzini  * This program is distributed in the hope that it will be useful,
13dd285b06SPaolo Bonzini  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14dd285b06SPaolo Bonzini  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15dd285b06SPaolo Bonzini  * GNU General Public License for more details.
16dd285b06SPaolo Bonzini  *
17dd285b06SPaolo Bonzini  * You should have received a copy of the GNU General Public License along
18dd285b06SPaolo Bonzini  * with this program; if not, see <http://www.gnu.org/licenses/>.
19dd285b06SPaolo Bonzini  */
20dd285b06SPaolo Bonzini 
2112b16722SPeter Maydell #include "qemu/osdep.h"
22c0dbca36SAlistair Francis #include "qemu/error-report.h"
23da34e65cSMarkus Armbruster #include "qapi/error.h"
244771d756SPaolo Bonzini #include "cpu.h"
25e285e867SPhilippe Mathieu-Daudé #include "exec/address-spaces.h"
2612e9493dSMarkus Armbruster #include "sysemu/blockdev.h"
27a82929a2SThomas Huth #include "sysemu/qtest.h"
2871e8a915SMarkus Armbruster #include "sysemu/reset.h"
2954d31236SMarkus Armbruster #include "sysemu/runstate.h"
3064552b6bSMarkus Armbruster #include "hw/irq.h"
31a27bd6c7SMarkus Armbruster #include "hw/qdev-properties.h"
3212ec8bd5SPeter Maydell #include "hw/arm/boot.h"
330d09e41aSPaolo Bonzini #include "hw/arm/omap.h"
34dd285b06SPaolo Bonzini #include "sysemu/sysemu.h"
35dd285b06SPaolo Bonzini #include "qemu/timer.h"
364d43a603SMarc-André Lureau #include "chardev/char-fe.h"
370d09e41aSPaolo Bonzini #include "hw/block/flash.h"
380d09e41aSPaolo Bonzini #include "hw/arm/soc_dma.h"
39dd285b06SPaolo Bonzini #include "hw/sysbus.h"
40b8ab0303SMartin Kletzander #include "hw/boards.h"
41dd285b06SPaolo Bonzini #include "audio/audio.h"
42dd285b06SPaolo Bonzini 
43dd285b06SPaolo Bonzini /* Enhanced Audio Controller (CODEC only) */
44dd285b06SPaolo Bonzini struct omap_eac_s {
45dd285b06SPaolo Bonzini     qemu_irq irq;
46dd285b06SPaolo Bonzini     MemoryRegion iomem;
47dd285b06SPaolo Bonzini 
48dd285b06SPaolo Bonzini     uint16_t sysconfig;
49dd285b06SPaolo Bonzini     uint8_t config[4];
50dd285b06SPaolo Bonzini     uint8_t control;
51dd285b06SPaolo Bonzini     uint8_t address;
52dd285b06SPaolo Bonzini     uint16_t data;
53dd285b06SPaolo Bonzini     uint8_t vtol;
54dd285b06SPaolo Bonzini     uint8_t vtsl;
55dd285b06SPaolo Bonzini     uint16_t mixer;
56dd285b06SPaolo Bonzini     uint16_t gain[4];
57dd285b06SPaolo Bonzini     uint8_t att;
58dd285b06SPaolo Bonzini     uint16_t max[7];
59dd285b06SPaolo Bonzini 
60dd285b06SPaolo Bonzini     struct {
61dd285b06SPaolo Bonzini         qemu_irq txdrq;
62dd285b06SPaolo Bonzini         qemu_irq rxdrq;
63dd285b06SPaolo Bonzini         uint32_t (*txrx)(void *opaque, uint32_t, int);
64dd285b06SPaolo Bonzini         void *opaque;
65dd285b06SPaolo Bonzini 
66dd285b06SPaolo Bonzini #define EAC_BUF_LEN 1024
67dd285b06SPaolo Bonzini         uint32_t rxbuf[EAC_BUF_LEN];
68dd285b06SPaolo Bonzini         int rxoff;
69dd285b06SPaolo Bonzini         int rxlen;
70dd285b06SPaolo Bonzini         int rxavail;
71dd285b06SPaolo Bonzini         uint32_t txbuf[EAC_BUF_LEN];
72dd285b06SPaolo Bonzini         int txlen;
73dd285b06SPaolo Bonzini         int txavail;
74dd285b06SPaolo Bonzini 
75dd285b06SPaolo Bonzini         int enable;
76dd285b06SPaolo Bonzini         int rate;
77dd285b06SPaolo Bonzini 
78dd285b06SPaolo Bonzini         uint16_t config[4];
79dd285b06SPaolo Bonzini 
80dd285b06SPaolo Bonzini         /* These need to be moved to the actual codec */
81dd285b06SPaolo Bonzini         QEMUSoundCard card;
82dd285b06SPaolo Bonzini         SWVoiceIn *in_voice;
83dd285b06SPaolo Bonzini         SWVoiceOut *out_voice;
84dd285b06SPaolo Bonzini         int hw_enable;
85dd285b06SPaolo Bonzini     } codec;
86dd285b06SPaolo Bonzini 
87dd285b06SPaolo Bonzini     struct {
88dd285b06SPaolo Bonzini         uint8_t control;
89dd285b06SPaolo Bonzini         uint16_t config;
90dd285b06SPaolo Bonzini     } modem, bt;
91dd285b06SPaolo Bonzini };
92dd285b06SPaolo Bonzini 
omap_eac_interrupt_update(struct omap_eac_s * s)93dd285b06SPaolo Bonzini static inline void omap_eac_interrupt_update(struct omap_eac_s *s)
94dd285b06SPaolo Bonzini {
95dd285b06SPaolo Bonzini     qemu_set_irq(s->irq, (s->codec.config[1] >> 14) & 1);	/* AURDI */
96dd285b06SPaolo Bonzini }
97dd285b06SPaolo Bonzini 
omap_eac_in_dmarequest_update(struct omap_eac_s * s)98dd285b06SPaolo Bonzini static inline void omap_eac_in_dmarequest_update(struct omap_eac_s *s)
99dd285b06SPaolo Bonzini {
100dd285b06SPaolo Bonzini     qemu_set_irq(s->codec.rxdrq, (s->codec.rxavail || s->codec.rxlen) &&
101dd285b06SPaolo Bonzini                     ((s->codec.config[1] >> 12) & 1));		/* DMAREN */
102dd285b06SPaolo Bonzini }
103dd285b06SPaolo Bonzini 
omap_eac_out_dmarequest_update(struct omap_eac_s * s)104dd285b06SPaolo Bonzini static inline void omap_eac_out_dmarequest_update(struct omap_eac_s *s)
105dd285b06SPaolo Bonzini {
106dd285b06SPaolo Bonzini     qemu_set_irq(s->codec.txdrq, s->codec.txlen < s->codec.txavail &&
107dd285b06SPaolo Bonzini                     ((s->codec.config[1] >> 11) & 1));		/* DMAWEN */
108dd285b06SPaolo Bonzini }
109dd285b06SPaolo Bonzini 
omap_eac_in_refill(struct omap_eac_s * s)110dd285b06SPaolo Bonzini static inline void omap_eac_in_refill(struct omap_eac_s *s)
111dd285b06SPaolo Bonzini {
112dd285b06SPaolo Bonzini     int left = MIN(EAC_BUF_LEN - s->codec.rxlen, s->codec.rxavail) << 2;
113dd285b06SPaolo Bonzini     int start = ((s->codec.rxoff + s->codec.rxlen) & (EAC_BUF_LEN - 1)) << 2;
114dd285b06SPaolo Bonzini     int leftwrap = MIN(left, (EAC_BUF_LEN << 2) - start);
115dd285b06SPaolo Bonzini     int recv = 1;
116dd285b06SPaolo Bonzini     uint8_t *buf = (uint8_t *) s->codec.rxbuf + start;
117dd285b06SPaolo Bonzini 
118dd285b06SPaolo Bonzini     left -= leftwrap;
119dd285b06SPaolo Bonzini     start = 0;
120dd285b06SPaolo Bonzini     while (leftwrap && (recv = AUD_read(s->codec.in_voice, buf + start,
121dd285b06SPaolo Bonzini                                     leftwrap)) > 0) {	/* Be defensive */
122dd285b06SPaolo Bonzini         start += recv;
123dd285b06SPaolo Bonzini         leftwrap -= recv;
124dd285b06SPaolo Bonzini     }
125dd285b06SPaolo Bonzini     if (recv <= 0)
126dd285b06SPaolo Bonzini         s->codec.rxavail = 0;
127dd285b06SPaolo Bonzini     else
128dd285b06SPaolo Bonzini         s->codec.rxavail -= start >> 2;
129dd285b06SPaolo Bonzini     s->codec.rxlen += start >> 2;
130dd285b06SPaolo Bonzini 
131dd285b06SPaolo Bonzini     if (recv > 0 && left > 0) {
132dd285b06SPaolo Bonzini         start = 0;
133dd285b06SPaolo Bonzini         while (left && (recv = AUD_read(s->codec.in_voice,
134dd285b06SPaolo Bonzini                                         (uint8_t *) s->codec.rxbuf + start,
135dd285b06SPaolo Bonzini                                         left)) > 0) {	/* Be defensive */
136dd285b06SPaolo Bonzini             start += recv;
137dd285b06SPaolo Bonzini             left -= recv;
138dd285b06SPaolo Bonzini         }
139dd285b06SPaolo Bonzini         if (recv <= 0)
140dd285b06SPaolo Bonzini             s->codec.rxavail = 0;
141dd285b06SPaolo Bonzini         else
142dd285b06SPaolo Bonzini             s->codec.rxavail -= start >> 2;
143dd285b06SPaolo Bonzini         s->codec.rxlen += start >> 2;
144dd285b06SPaolo Bonzini     }
145dd285b06SPaolo Bonzini }
146dd285b06SPaolo Bonzini 
omap_eac_out_empty(struct omap_eac_s * s)147dd285b06SPaolo Bonzini static inline void omap_eac_out_empty(struct omap_eac_s *s)
148dd285b06SPaolo Bonzini {
149dd285b06SPaolo Bonzini     int left = s->codec.txlen << 2;
150dd285b06SPaolo Bonzini     int start = 0;
151dd285b06SPaolo Bonzini     int sent = 1;
152dd285b06SPaolo Bonzini 
153dd285b06SPaolo Bonzini     while (left && (sent = AUD_write(s->codec.out_voice,
154dd285b06SPaolo Bonzini                                     (uint8_t *) s->codec.txbuf + start,
155dd285b06SPaolo Bonzini                                     left)) > 0) {	/* Be defensive */
156dd285b06SPaolo Bonzini         start += sent;
157dd285b06SPaolo Bonzini         left -= sent;
158dd285b06SPaolo Bonzini     }
159dd285b06SPaolo Bonzini 
160dd285b06SPaolo Bonzini     if (!sent) {
161dd285b06SPaolo Bonzini         s->codec.txavail = 0;
162dd285b06SPaolo Bonzini         omap_eac_out_dmarequest_update(s);
163dd285b06SPaolo Bonzini     }
164dd285b06SPaolo Bonzini 
165dd285b06SPaolo Bonzini     if (start)
166dd285b06SPaolo Bonzini         s->codec.txlen = 0;
167dd285b06SPaolo Bonzini }
168dd285b06SPaolo Bonzini 
omap_eac_in_cb(void * opaque,int avail_b)169dd285b06SPaolo Bonzini static void omap_eac_in_cb(void *opaque, int avail_b)
170dd285b06SPaolo Bonzini {
171a75ed3c4SPhilippe Mathieu-Daudé     struct omap_eac_s *s = opaque;
172dd285b06SPaolo Bonzini 
173dd285b06SPaolo Bonzini     s->codec.rxavail = avail_b >> 2;
174dd285b06SPaolo Bonzini     omap_eac_in_refill(s);
175dd285b06SPaolo Bonzini     /* TODO: possibly discard current buffer if overrun */
176dd285b06SPaolo Bonzini     omap_eac_in_dmarequest_update(s);
177dd285b06SPaolo Bonzini }
178dd285b06SPaolo Bonzini 
omap_eac_out_cb(void * opaque,int free_b)179dd285b06SPaolo Bonzini static void omap_eac_out_cb(void *opaque, int free_b)
180dd285b06SPaolo Bonzini {
181a75ed3c4SPhilippe Mathieu-Daudé     struct omap_eac_s *s = opaque;
182dd285b06SPaolo Bonzini 
183dd285b06SPaolo Bonzini     s->codec.txavail = free_b >> 2;
184dd285b06SPaolo Bonzini     if (s->codec.txlen)
185dd285b06SPaolo Bonzini         omap_eac_out_empty(s);
186dd285b06SPaolo Bonzini     else
187dd285b06SPaolo Bonzini         omap_eac_out_dmarequest_update(s);
188dd285b06SPaolo Bonzini }
189dd285b06SPaolo Bonzini 
omap_eac_enable_update(struct omap_eac_s * s)190dd285b06SPaolo Bonzini static void omap_eac_enable_update(struct omap_eac_s *s)
191dd285b06SPaolo Bonzini {
192dd285b06SPaolo Bonzini     s->codec.enable = !(s->codec.config[1] & 1) &&		/* EACPWD */
193dd285b06SPaolo Bonzini             (s->codec.config[1] & 2) &&				/* AUDEN */
194dd285b06SPaolo Bonzini             s->codec.hw_enable;
195dd285b06SPaolo Bonzini }
196dd285b06SPaolo Bonzini 
197dd285b06SPaolo Bonzini static const int omap_eac_fsint[4] = {
198dd285b06SPaolo Bonzini     8000,
199dd285b06SPaolo Bonzini     11025,
200dd285b06SPaolo Bonzini     22050,
201dd285b06SPaolo Bonzini     44100,
202dd285b06SPaolo Bonzini };
203dd285b06SPaolo Bonzini 
204dd285b06SPaolo Bonzini static const int omap_eac_fsint2[8] = {
205dd285b06SPaolo Bonzini     8000,
206dd285b06SPaolo Bonzini     11025,
207dd285b06SPaolo Bonzini     22050,
208dd285b06SPaolo Bonzini     44100,
209dd285b06SPaolo Bonzini     48000,
210dd285b06SPaolo Bonzini     0, 0, 0,
211dd285b06SPaolo Bonzini };
212dd285b06SPaolo Bonzini 
213dd285b06SPaolo Bonzini static const int omap_eac_fsint3[16] = {
214dd285b06SPaolo Bonzini     8000,
215dd285b06SPaolo Bonzini     11025,
216dd285b06SPaolo Bonzini     16000,
217dd285b06SPaolo Bonzini     22050,
218dd285b06SPaolo Bonzini     24000,
219dd285b06SPaolo Bonzini     32000,
220dd285b06SPaolo Bonzini     44100,
221dd285b06SPaolo Bonzini     48000,
222dd285b06SPaolo Bonzini     0, 0, 0, 0, 0, 0, 0, 0,
223dd285b06SPaolo Bonzini };
224dd285b06SPaolo Bonzini 
omap_eac_rate_update(struct omap_eac_s * s)225dd285b06SPaolo Bonzini static void omap_eac_rate_update(struct omap_eac_s *s)
226dd285b06SPaolo Bonzini {
227dd285b06SPaolo Bonzini     int fsint[3];
228dd285b06SPaolo Bonzini 
229dd285b06SPaolo Bonzini     fsint[2] = (s->codec.config[3] >> 9) & 0xf;
230dd285b06SPaolo Bonzini     fsint[1] = (s->codec.config[2] >> 0) & 0x7;
231dd285b06SPaolo Bonzini     fsint[0] = (s->codec.config[0] >> 6) & 0x3;
232dd285b06SPaolo Bonzini     if (fsint[2] < 0xf)
233dd285b06SPaolo Bonzini         s->codec.rate = omap_eac_fsint3[fsint[2]];
234dd285b06SPaolo Bonzini     else if (fsint[1] < 0x7)
235dd285b06SPaolo Bonzini         s->codec.rate = omap_eac_fsint2[fsint[1]];
236dd285b06SPaolo Bonzini     else
237dd285b06SPaolo Bonzini         s->codec.rate = omap_eac_fsint[fsint[0]];
238dd285b06SPaolo Bonzini }
239dd285b06SPaolo Bonzini 
omap_eac_volume_update(struct omap_eac_s * s)240dd285b06SPaolo Bonzini static void omap_eac_volume_update(struct omap_eac_s *s)
241dd285b06SPaolo Bonzini {
242dd285b06SPaolo Bonzini     /* TODO */
243dd285b06SPaolo Bonzini }
244dd285b06SPaolo Bonzini 
omap_eac_format_update(struct omap_eac_s * s)245dd285b06SPaolo Bonzini static void omap_eac_format_update(struct omap_eac_s *s)
246dd285b06SPaolo Bonzini {
247dd285b06SPaolo Bonzini     struct audsettings fmt;
248dd285b06SPaolo Bonzini 
249dd285b06SPaolo Bonzini     /* The hardware buffers at most one sample */
250dd285b06SPaolo Bonzini     if (s->codec.rxlen)
251dd285b06SPaolo Bonzini         s->codec.rxlen = 1;
252dd285b06SPaolo Bonzini 
253dd285b06SPaolo Bonzini     if (s->codec.in_voice) {
254dd285b06SPaolo Bonzini         AUD_set_active_in(s->codec.in_voice, 0);
255dd285b06SPaolo Bonzini         AUD_close_in(&s->codec.card, s->codec.in_voice);
256dd285b06SPaolo Bonzini         s->codec.in_voice = NULL;
257dd285b06SPaolo Bonzini     }
258dd285b06SPaolo Bonzini     if (s->codec.out_voice) {
259dd285b06SPaolo Bonzini         omap_eac_out_empty(s);
260dd285b06SPaolo Bonzini         AUD_set_active_out(s->codec.out_voice, 0);
261dd285b06SPaolo Bonzini         AUD_close_out(&s->codec.card, s->codec.out_voice);
262dd285b06SPaolo Bonzini         s->codec.out_voice = NULL;
263dd285b06SPaolo Bonzini         s->codec.txavail = 0;
264dd285b06SPaolo Bonzini     }
265dd285b06SPaolo Bonzini     /* Discard what couldn't be written */
266dd285b06SPaolo Bonzini     s->codec.txlen = 0;
267dd285b06SPaolo Bonzini 
268dd285b06SPaolo Bonzini     omap_eac_enable_update(s);
269dd285b06SPaolo Bonzini     if (!s->codec.enable)
270dd285b06SPaolo Bonzini         return;
271dd285b06SPaolo Bonzini 
272dd285b06SPaolo Bonzini     omap_eac_rate_update(s);
273dd285b06SPaolo Bonzini     fmt.endianness = ((s->codec.config[0] >> 8) & 1);		/* LI_BI */
274dd285b06SPaolo Bonzini     fmt.nchannels = ((s->codec.config[0] >> 10) & 1) ? 2 : 1;	/* MN_ST */
275dd285b06SPaolo Bonzini     fmt.freq = s->codec.rate;
276dd285b06SPaolo Bonzini     /* TODO: signedness possibly depends on the CODEC hardware - or
277dd285b06SPaolo Bonzini      * does I2S specify it?  */
278a07d9df0SThomas Huth     /* All register writes are 16 bits so we store 16-bit samples
279dd285b06SPaolo Bonzini      * in the buffers regardless of AGCFR[B8_16] value.  */
28085bc5852SKővágó, Zoltán     fmt.fmt = AUDIO_FORMAT_U16;
281dd285b06SPaolo Bonzini 
282dd285b06SPaolo Bonzini     s->codec.in_voice = AUD_open_in(&s->codec.card, s->codec.in_voice,
283dd285b06SPaolo Bonzini                     "eac.codec.in", s, omap_eac_in_cb, &fmt);
284dd285b06SPaolo Bonzini     s->codec.out_voice = AUD_open_out(&s->codec.card, s->codec.out_voice,
285dd285b06SPaolo Bonzini                     "eac.codec.out", s, omap_eac_out_cb, &fmt);
286dd285b06SPaolo Bonzini 
287dd285b06SPaolo Bonzini     omap_eac_volume_update(s);
288dd285b06SPaolo Bonzini 
289dd285b06SPaolo Bonzini     AUD_set_active_in(s->codec.in_voice, 1);
290dd285b06SPaolo Bonzini     AUD_set_active_out(s->codec.out_voice, 1);
291dd285b06SPaolo Bonzini }
292dd285b06SPaolo Bonzini 
omap_eac_reset(struct omap_eac_s * s)293dd285b06SPaolo Bonzini static void omap_eac_reset(struct omap_eac_s *s)
294dd285b06SPaolo Bonzini {
295dd285b06SPaolo Bonzini     s->sysconfig = 0;
296dd285b06SPaolo Bonzini     s->config[0] = 0x0c;
297dd285b06SPaolo Bonzini     s->config[1] = 0x09;
298dd285b06SPaolo Bonzini     s->config[2] = 0xab;
299dd285b06SPaolo Bonzini     s->config[3] = 0x03;
300dd285b06SPaolo Bonzini     s->control = 0x00;
301dd285b06SPaolo Bonzini     s->address = 0x00;
302dd285b06SPaolo Bonzini     s->data = 0x0000;
303dd285b06SPaolo Bonzini     s->vtol = 0x00;
304dd285b06SPaolo Bonzini     s->vtsl = 0x00;
305dd285b06SPaolo Bonzini     s->mixer = 0x0000;
306dd285b06SPaolo Bonzini     s->gain[0] = 0xe7e7;
307dd285b06SPaolo Bonzini     s->gain[1] = 0x6767;
308dd285b06SPaolo Bonzini     s->gain[2] = 0x6767;
309dd285b06SPaolo Bonzini     s->gain[3] = 0x6767;
310dd285b06SPaolo Bonzini     s->att = 0xce;
311dd285b06SPaolo Bonzini     s->max[0] = 0;
312dd285b06SPaolo Bonzini     s->max[1] = 0;
313dd285b06SPaolo Bonzini     s->max[2] = 0;
314dd285b06SPaolo Bonzini     s->max[3] = 0;
315dd285b06SPaolo Bonzini     s->max[4] = 0;
316dd285b06SPaolo Bonzini     s->max[5] = 0;
317dd285b06SPaolo Bonzini     s->max[6] = 0;
318dd285b06SPaolo Bonzini 
319dd285b06SPaolo Bonzini     s->modem.control = 0x00;
320dd285b06SPaolo Bonzini     s->modem.config = 0x0000;
321dd285b06SPaolo Bonzini     s->bt.control = 0x00;
322dd285b06SPaolo Bonzini     s->bt.config = 0x0000;
323dd285b06SPaolo Bonzini     s->codec.config[0] = 0x0649;
324dd285b06SPaolo Bonzini     s->codec.config[1] = 0x0000;
325dd285b06SPaolo Bonzini     s->codec.config[2] = 0x0007;
326dd285b06SPaolo Bonzini     s->codec.config[3] = 0x1ffc;
327dd285b06SPaolo Bonzini     s->codec.rxoff = 0;
328dd285b06SPaolo Bonzini     s->codec.rxlen = 0;
329dd285b06SPaolo Bonzini     s->codec.txlen = 0;
330dd285b06SPaolo Bonzini     s->codec.rxavail = 0;
331dd285b06SPaolo Bonzini     s->codec.txavail = 0;
332dd285b06SPaolo Bonzini 
333dd285b06SPaolo Bonzini     omap_eac_format_update(s);
334dd285b06SPaolo Bonzini     omap_eac_interrupt_update(s);
335dd285b06SPaolo Bonzini }
336dd285b06SPaolo Bonzini 
omap_eac_read(void * opaque,hwaddr addr,unsigned size)337a75ed3c4SPhilippe Mathieu-Daudé static uint64_t omap_eac_read(void *opaque, hwaddr addr, unsigned size)
338dd285b06SPaolo Bonzini {
339a75ed3c4SPhilippe Mathieu-Daudé     struct omap_eac_s *s = opaque;
340dd285b06SPaolo Bonzini     uint32_t ret;
341dd285b06SPaolo Bonzini 
342dd285b06SPaolo Bonzini     if (size != 2) {
343dd285b06SPaolo Bonzini         return omap_badwidth_read16(opaque, addr);
344dd285b06SPaolo Bonzini     }
345dd285b06SPaolo Bonzini 
346dd285b06SPaolo Bonzini     switch (addr) {
347dd285b06SPaolo Bonzini     case 0x000:	/* CPCFR1 */
348dd285b06SPaolo Bonzini         return s->config[0];
349dd285b06SPaolo Bonzini     case 0x004:	/* CPCFR2 */
350dd285b06SPaolo Bonzini         return s->config[1];
351dd285b06SPaolo Bonzini     case 0x008:	/* CPCFR3 */
352dd285b06SPaolo Bonzini         return s->config[2];
353dd285b06SPaolo Bonzini     case 0x00c:	/* CPCFR4 */
354dd285b06SPaolo Bonzini         return s->config[3];
355dd285b06SPaolo Bonzini 
356dd285b06SPaolo Bonzini     case 0x010:	/* CPTCTL */
357dd285b06SPaolo Bonzini         return s->control | ((s->codec.rxavail + s->codec.rxlen > 0) << 7) |
358dd285b06SPaolo Bonzini                 ((s->codec.txlen < s->codec.txavail) << 5);
359dd285b06SPaolo Bonzini 
360dd285b06SPaolo Bonzini     case 0x014:	/* CPTTADR */
361dd285b06SPaolo Bonzini         return s->address;
362dd285b06SPaolo Bonzini     case 0x018:	/* CPTDATL */
363dd285b06SPaolo Bonzini         return s->data & 0xff;
364dd285b06SPaolo Bonzini     case 0x01c:	/* CPTDATH */
365dd285b06SPaolo Bonzini         return s->data >> 8;
366dd285b06SPaolo Bonzini     case 0x020:	/* CPTVSLL */
367dd285b06SPaolo Bonzini         return s->vtol;
368dd285b06SPaolo Bonzini     case 0x024:	/* CPTVSLH */
369dd285b06SPaolo Bonzini         return s->vtsl | (3 << 5);	/* CRDY1 | CRDY2 */
370dd285b06SPaolo Bonzini     case 0x040:	/* MPCTR */
371dd285b06SPaolo Bonzini         return s->modem.control;
372dd285b06SPaolo Bonzini     case 0x044:	/* MPMCCFR */
373dd285b06SPaolo Bonzini         return s->modem.config;
374dd285b06SPaolo Bonzini     case 0x060:	/* BPCTR */
375dd285b06SPaolo Bonzini         return s->bt.control;
376dd285b06SPaolo Bonzini     case 0x064:	/* BPMCCFR */
377dd285b06SPaolo Bonzini         return s->bt.config;
378dd285b06SPaolo Bonzini     case 0x080:	/* AMSCFR */
379dd285b06SPaolo Bonzini         return s->mixer;
380dd285b06SPaolo Bonzini     case 0x084:	/* AMVCTR */
381dd285b06SPaolo Bonzini         return s->gain[0];
382dd285b06SPaolo Bonzini     case 0x088:	/* AM1VCTR */
383dd285b06SPaolo Bonzini         return s->gain[1];
384dd285b06SPaolo Bonzini     case 0x08c:	/* AM2VCTR */
385dd285b06SPaolo Bonzini         return s->gain[2];
386dd285b06SPaolo Bonzini     case 0x090:	/* AM3VCTR */
387dd285b06SPaolo Bonzini         return s->gain[3];
388dd285b06SPaolo Bonzini     case 0x094:	/* ASTCTR */
389dd285b06SPaolo Bonzini         return s->att;
390dd285b06SPaolo Bonzini     case 0x098:	/* APD1LCR */
391dd285b06SPaolo Bonzini         return s->max[0];
392dd285b06SPaolo Bonzini     case 0x09c:	/* APD1RCR */
393dd285b06SPaolo Bonzini         return s->max[1];
394dd285b06SPaolo Bonzini     case 0x0a0:	/* APD2LCR */
395dd285b06SPaolo Bonzini         return s->max[2];
396dd285b06SPaolo Bonzini     case 0x0a4:	/* APD2RCR */
397dd285b06SPaolo Bonzini         return s->max[3];
398dd285b06SPaolo Bonzini     case 0x0a8:	/* APD3LCR */
399dd285b06SPaolo Bonzini         return s->max[4];
400dd285b06SPaolo Bonzini     case 0x0ac:	/* APD3RCR */
401dd285b06SPaolo Bonzini         return s->max[5];
402dd285b06SPaolo Bonzini     case 0x0b0:	/* APD4R */
403dd285b06SPaolo Bonzini         return s->max[6];
404dd285b06SPaolo Bonzini     case 0x0b4:	/* ADWR */
405dd285b06SPaolo Bonzini         /* This should be write-only?  Docs list it as read-only.  */
406dd285b06SPaolo Bonzini         return 0x0000;
407dd285b06SPaolo Bonzini     case 0x0b8:	/* ADRDR */
408dd285b06SPaolo Bonzini         if (likely(s->codec.rxlen > 1)) {
409dd285b06SPaolo Bonzini             ret = s->codec.rxbuf[s->codec.rxoff ++];
410dd285b06SPaolo Bonzini             s->codec.rxlen --;
411dd285b06SPaolo Bonzini             s->codec.rxoff &= EAC_BUF_LEN - 1;
412dd285b06SPaolo Bonzini             return ret;
413dd285b06SPaolo Bonzini         } else if (s->codec.rxlen) {
414dd285b06SPaolo Bonzini             ret = s->codec.rxbuf[s->codec.rxoff ++];
415dd285b06SPaolo Bonzini             s->codec.rxlen --;
416dd285b06SPaolo Bonzini             s->codec.rxoff &= EAC_BUF_LEN - 1;
417dd285b06SPaolo Bonzini             if (s->codec.rxavail)
418dd285b06SPaolo Bonzini                 omap_eac_in_refill(s);
419dd285b06SPaolo Bonzini             omap_eac_in_dmarequest_update(s);
420dd285b06SPaolo Bonzini             return ret;
421dd285b06SPaolo Bonzini         }
422dd285b06SPaolo Bonzini         return 0x0000;
423dd285b06SPaolo Bonzini     case 0x0bc:	/* AGCFR */
424dd285b06SPaolo Bonzini         return s->codec.config[0];
425dd285b06SPaolo Bonzini     case 0x0c0:	/* AGCTR */
426dd285b06SPaolo Bonzini         return s->codec.config[1] | ((s->codec.config[1] & 2) << 14);
427dd285b06SPaolo Bonzini     case 0x0c4:	/* AGCFR2 */
428dd285b06SPaolo Bonzini         return s->codec.config[2];
429dd285b06SPaolo Bonzini     case 0x0c8:	/* AGCFR3 */
430dd285b06SPaolo Bonzini         return s->codec.config[3];
431dd285b06SPaolo Bonzini     case 0x0cc:	/* MBPDMACTR */
432dd285b06SPaolo Bonzini     case 0x0d0:	/* MPDDMARR */
433dd285b06SPaolo Bonzini     case 0x0d8:	/* MPUDMARR */
434dd285b06SPaolo Bonzini     case 0x0e4:	/* BPDDMARR */
435dd285b06SPaolo Bonzini     case 0x0ec:	/* BPUDMARR */
436dd285b06SPaolo Bonzini         return 0x0000;
437dd285b06SPaolo Bonzini 
438dd285b06SPaolo Bonzini     case 0x100:	/* VERSION_NUMBER */
439dd285b06SPaolo Bonzini         return 0x0010;
440dd285b06SPaolo Bonzini 
441dd285b06SPaolo Bonzini     case 0x104:	/* SYSCONFIG */
442dd285b06SPaolo Bonzini         return s->sysconfig;
443dd285b06SPaolo Bonzini 
444dd285b06SPaolo Bonzini     case 0x108:	/* SYSSTATUS */
445dd285b06SPaolo Bonzini         return 1 | 0xe;					/* RESETDONE | stuff */
446dd285b06SPaolo Bonzini     }
447dd285b06SPaolo Bonzini 
448dd285b06SPaolo Bonzini     OMAP_BAD_REG(addr);
449dd285b06SPaolo Bonzini     return 0;
450dd285b06SPaolo Bonzini }
451dd285b06SPaolo Bonzini 
omap_eac_write(void * opaque,hwaddr addr,uint64_t value,unsigned size)452dd285b06SPaolo Bonzini static void omap_eac_write(void *opaque, hwaddr addr,
453dd285b06SPaolo Bonzini                            uint64_t value, unsigned size)
454dd285b06SPaolo Bonzini {
455a75ed3c4SPhilippe Mathieu-Daudé     struct omap_eac_s *s = opaque;
456dd285b06SPaolo Bonzini 
457dd285b06SPaolo Bonzini     if (size != 2) {
45877a8257eSStefan Weil         omap_badwidth_write16(opaque, addr, value);
45977a8257eSStefan Weil         return;
460dd285b06SPaolo Bonzini     }
461dd285b06SPaolo Bonzini 
462dd285b06SPaolo Bonzini     switch (addr) {
463dd285b06SPaolo Bonzini     case 0x098:	/* APD1LCR */
464dd285b06SPaolo Bonzini     case 0x09c:	/* APD1RCR */
465dd285b06SPaolo Bonzini     case 0x0a0:	/* APD2LCR */
466dd285b06SPaolo Bonzini     case 0x0a4:	/* APD2RCR */
467dd285b06SPaolo Bonzini     case 0x0a8:	/* APD3LCR */
468dd285b06SPaolo Bonzini     case 0x0ac:	/* APD3RCR */
469dd285b06SPaolo Bonzini     case 0x0b0:	/* APD4R */
470dd285b06SPaolo Bonzini     case 0x0b8:	/* ADRDR */
471dd285b06SPaolo Bonzini     case 0x0d0:	/* MPDDMARR */
472dd285b06SPaolo Bonzini     case 0x0d8:	/* MPUDMARR */
473dd285b06SPaolo Bonzini     case 0x0e4:	/* BPDDMARR */
474dd285b06SPaolo Bonzini     case 0x0ec:	/* BPUDMARR */
475dd285b06SPaolo Bonzini     case 0x100:	/* VERSION_NUMBER */
476dd285b06SPaolo Bonzini     case 0x108:	/* SYSSTATUS */
477dd285b06SPaolo Bonzini         OMAP_RO_REG(addr);
478dd285b06SPaolo Bonzini         return;
479dd285b06SPaolo Bonzini 
480dd285b06SPaolo Bonzini     case 0x000:	/* CPCFR1 */
481dd285b06SPaolo Bonzini         s->config[0] = value & 0xff;
482dd285b06SPaolo Bonzini         omap_eac_format_update(s);
483dd285b06SPaolo Bonzini         break;
484dd285b06SPaolo Bonzini     case 0x004:	/* CPCFR2 */
485dd285b06SPaolo Bonzini         s->config[1] = value & 0xff;
486dd285b06SPaolo Bonzini         omap_eac_format_update(s);
487dd285b06SPaolo Bonzini         break;
488dd285b06SPaolo Bonzini     case 0x008:	/* CPCFR3 */
489dd285b06SPaolo Bonzini         s->config[2] = value & 0xff;
490dd285b06SPaolo Bonzini         omap_eac_format_update(s);
491dd285b06SPaolo Bonzini         break;
492dd285b06SPaolo Bonzini     case 0x00c:	/* CPCFR4 */
493dd285b06SPaolo Bonzini         s->config[3] = value & 0xff;
494dd285b06SPaolo Bonzini         omap_eac_format_update(s);
495dd285b06SPaolo Bonzini         break;
496dd285b06SPaolo Bonzini 
497dd285b06SPaolo Bonzini     case 0x010:	/* CPTCTL */
498dd285b06SPaolo Bonzini         /* Assuming TXF and TXE bits are read-only... */
499dd285b06SPaolo Bonzini         s->control = value & 0x5f;
500dd285b06SPaolo Bonzini         omap_eac_interrupt_update(s);
501dd285b06SPaolo Bonzini         break;
502dd285b06SPaolo Bonzini 
503dd285b06SPaolo Bonzini     case 0x014:	/* CPTTADR */
504dd285b06SPaolo Bonzini         s->address = value & 0xff;
505dd285b06SPaolo Bonzini         break;
506dd285b06SPaolo Bonzini     case 0x018:	/* CPTDATL */
507dd285b06SPaolo Bonzini         s->data &= 0xff00;
508dd285b06SPaolo Bonzini         s->data |= value & 0xff;
509dd285b06SPaolo Bonzini         break;
510dd285b06SPaolo Bonzini     case 0x01c:	/* CPTDATH */
511dd285b06SPaolo Bonzini         s->data &= 0x00ff;
512dd285b06SPaolo Bonzini         s->data |= value << 8;
513dd285b06SPaolo Bonzini         break;
514dd285b06SPaolo Bonzini     case 0x020:	/* CPTVSLL */
515dd285b06SPaolo Bonzini         s->vtol = value & 0xf8;
516dd285b06SPaolo Bonzini         break;
517dd285b06SPaolo Bonzini     case 0x024:	/* CPTVSLH */
518dd285b06SPaolo Bonzini         s->vtsl = value & 0x9f;
519dd285b06SPaolo Bonzini         break;
520dd285b06SPaolo Bonzini     case 0x040:	/* MPCTR */
521dd285b06SPaolo Bonzini         s->modem.control = value & 0x8f;
522dd285b06SPaolo Bonzini         break;
523dd285b06SPaolo Bonzini     case 0x044:	/* MPMCCFR */
524dd285b06SPaolo Bonzini         s->modem.config = value & 0x7fff;
525dd285b06SPaolo Bonzini         break;
526dd285b06SPaolo Bonzini     case 0x060:	/* BPCTR */
527dd285b06SPaolo Bonzini         s->bt.control = value & 0x8f;
528dd285b06SPaolo Bonzini         break;
529dd285b06SPaolo Bonzini     case 0x064:	/* BPMCCFR */
530dd285b06SPaolo Bonzini         s->bt.config = value & 0x7fff;
531dd285b06SPaolo Bonzini         break;
532dd285b06SPaolo Bonzini     case 0x080:	/* AMSCFR */
533dd285b06SPaolo Bonzini         s->mixer = value & 0x0fff;
534dd285b06SPaolo Bonzini         break;
535dd285b06SPaolo Bonzini     case 0x084:	/* AMVCTR */
536dd285b06SPaolo Bonzini         s->gain[0] = value & 0xffff;
537dd285b06SPaolo Bonzini         break;
538dd285b06SPaolo Bonzini     case 0x088:	/* AM1VCTR */
539dd285b06SPaolo Bonzini         s->gain[1] = value & 0xff7f;
540dd285b06SPaolo Bonzini         break;
541dd285b06SPaolo Bonzini     case 0x08c:	/* AM2VCTR */
542dd285b06SPaolo Bonzini         s->gain[2] = value & 0xff7f;
543dd285b06SPaolo Bonzini         break;
544dd285b06SPaolo Bonzini     case 0x090:	/* AM3VCTR */
545dd285b06SPaolo Bonzini         s->gain[3] = value & 0xff7f;
546dd285b06SPaolo Bonzini         break;
547dd285b06SPaolo Bonzini     case 0x094:	/* ASTCTR */
548dd285b06SPaolo Bonzini         s->att = value & 0xff;
549dd285b06SPaolo Bonzini         break;
550dd285b06SPaolo Bonzini 
551dd285b06SPaolo Bonzini     case 0x0b4:	/* ADWR */
552dd285b06SPaolo Bonzini         s->codec.txbuf[s->codec.txlen ++] = value;
553dd285b06SPaolo Bonzini         if (unlikely(s->codec.txlen == EAC_BUF_LEN ||
554dd285b06SPaolo Bonzini                                 s->codec.txlen == s->codec.txavail)) {
555dd285b06SPaolo Bonzini             if (s->codec.txavail)
556dd285b06SPaolo Bonzini                 omap_eac_out_empty(s);
557dd285b06SPaolo Bonzini             /* Discard what couldn't be written */
558dd285b06SPaolo Bonzini             s->codec.txlen = 0;
559dd285b06SPaolo Bonzini         }
560dd285b06SPaolo Bonzini         break;
561dd285b06SPaolo Bonzini 
562dd285b06SPaolo Bonzini     case 0x0bc:	/* AGCFR */
563dd285b06SPaolo Bonzini         s->codec.config[0] = value & 0x07ff;
564dd285b06SPaolo Bonzini         omap_eac_format_update(s);
565dd285b06SPaolo Bonzini         break;
566dd285b06SPaolo Bonzini     case 0x0c0:	/* AGCTR */
567dd285b06SPaolo Bonzini         s->codec.config[1] = value & 0x780f;
568dd285b06SPaolo Bonzini         omap_eac_format_update(s);
569dd285b06SPaolo Bonzini         break;
570dd285b06SPaolo Bonzini     case 0x0c4:	/* AGCFR2 */
571dd285b06SPaolo Bonzini         s->codec.config[2] = value & 0x003f;
572dd285b06SPaolo Bonzini         omap_eac_format_update(s);
573dd285b06SPaolo Bonzini         break;
574dd285b06SPaolo Bonzini     case 0x0c8:	/* AGCFR3 */
575dd285b06SPaolo Bonzini         s->codec.config[3] = value & 0xffff;
576dd285b06SPaolo Bonzini         omap_eac_format_update(s);
577dd285b06SPaolo Bonzini         break;
578dd285b06SPaolo Bonzini     case 0x0cc:	/* MBPDMACTR */
579dd285b06SPaolo Bonzini     case 0x0d4:	/* MPDDMAWR */
580dd285b06SPaolo Bonzini     case 0x0e0:	/* MPUDMAWR */
581dd285b06SPaolo Bonzini     case 0x0e8:	/* BPDDMAWR */
582dd285b06SPaolo Bonzini     case 0x0f0:	/* BPUDMAWR */
583dd285b06SPaolo Bonzini         break;
584dd285b06SPaolo Bonzini 
585dd285b06SPaolo Bonzini     case 0x104:	/* SYSCONFIG */
586dd285b06SPaolo Bonzini         if (value & (1 << 1))				/* SOFTRESET */
587dd285b06SPaolo Bonzini             omap_eac_reset(s);
588dd285b06SPaolo Bonzini         s->sysconfig = value & 0x31d;
589dd285b06SPaolo Bonzini         break;
590dd285b06SPaolo Bonzini 
591dd285b06SPaolo Bonzini     default:
592dd285b06SPaolo Bonzini         OMAP_BAD_REG(addr);
593dd285b06SPaolo Bonzini         return;
594dd285b06SPaolo Bonzini     }
595dd285b06SPaolo Bonzini }
596dd285b06SPaolo Bonzini 
597dd285b06SPaolo Bonzini static const MemoryRegionOps omap_eac_ops = {
598dd285b06SPaolo Bonzini     .read = omap_eac_read,
599dd285b06SPaolo Bonzini     .write = omap_eac_write,
600dd285b06SPaolo Bonzini     .endianness = DEVICE_NATIVE_ENDIAN,
601dd285b06SPaolo Bonzini };
602dd285b06SPaolo Bonzini 
omap_eac_init(struct omap_target_agent_s * ta,qemu_irq irq,qemu_irq * drq,omap_clk fclk,omap_clk iclk)603dd285b06SPaolo Bonzini static struct omap_eac_s *omap_eac_init(struct omap_target_agent_s *ta,
604dd285b06SPaolo Bonzini                 qemu_irq irq, qemu_irq *drq, omap_clk fclk, omap_clk iclk)
605dd285b06SPaolo Bonzini {
606b45c03f5SMarkus Armbruster     struct omap_eac_s *s = g_new0(struct omap_eac_s, 1);
607dd285b06SPaolo Bonzini 
608dd285b06SPaolo Bonzini     s->irq = irq;
609dd285b06SPaolo Bonzini     s->codec.rxdrq = *drq ++;
610dd285b06SPaolo Bonzini     s->codec.txdrq = *drq;
611dd285b06SPaolo Bonzini     omap_eac_reset(s);
612dd285b06SPaolo Bonzini 
613b8ab0303SMartin Kletzander     if (current_machine->audiodev) {
614b8ab0303SMartin Kletzander         s->codec.card.name = g_strdup(current_machine->audiodev);
615b8ab0303SMartin Kletzander         s->codec.card.state = audio_state_by_name(s->codec.card.name, &error_fatal);
616b8ab0303SMartin Kletzander     }
617*cb94ff5fSMartin Kletzander     AUD_register_card("OMAP EAC", &s->codec.card, &error_fatal);
618dd285b06SPaolo Bonzini 
6192c9b15caSPaolo Bonzini     memory_region_init_io(&s->iomem, NULL, &omap_eac_ops, s, "omap.eac",
620dd285b06SPaolo Bonzini                           omap_l4_region_size(ta, 0));
621dd285b06SPaolo Bonzini     omap_l4_attach(ta, 0, &s->iomem);
622dd285b06SPaolo Bonzini 
623dd285b06SPaolo Bonzini     return s;
624dd285b06SPaolo Bonzini }
625dd285b06SPaolo Bonzini 
626dd285b06SPaolo Bonzini /* STI/XTI (emulation interface) console - reverse engineered only */
627dd285b06SPaolo Bonzini struct omap_sti_s {
628dd285b06SPaolo Bonzini     qemu_irq irq;
629dd285b06SPaolo Bonzini     MemoryRegion iomem;
630dd285b06SPaolo Bonzini     MemoryRegion iomem_fifo;
63132a6ebecSMarc-André Lureau     CharBackend chr;
632dd285b06SPaolo Bonzini 
633dd285b06SPaolo Bonzini     uint32_t sysconfig;
634dd285b06SPaolo Bonzini     uint32_t systest;
635dd285b06SPaolo Bonzini     uint32_t irqst;
636dd285b06SPaolo Bonzini     uint32_t irqen;
637dd285b06SPaolo Bonzini     uint32_t clkcontrol;
638dd285b06SPaolo Bonzini     uint32_t serial_config;
639dd285b06SPaolo Bonzini };
640dd285b06SPaolo Bonzini 
641dd285b06SPaolo Bonzini #define STI_TRACE_CONSOLE_CHANNEL	239
642dd285b06SPaolo Bonzini #define STI_TRACE_CONTROL_CHANNEL	253
643dd285b06SPaolo Bonzini 
omap_sti_interrupt_update(struct omap_sti_s * s)644dd285b06SPaolo Bonzini static inline void omap_sti_interrupt_update(struct omap_sti_s *s)
645dd285b06SPaolo Bonzini {
646dd285b06SPaolo Bonzini     qemu_set_irq(s->irq, s->irqst & s->irqen);
647dd285b06SPaolo Bonzini }
648dd285b06SPaolo Bonzini 
omap_sti_reset(struct omap_sti_s * s)649dd285b06SPaolo Bonzini static void omap_sti_reset(struct omap_sti_s *s)
650dd285b06SPaolo Bonzini {
651dd285b06SPaolo Bonzini     s->sysconfig = 0;
652dd285b06SPaolo Bonzini     s->irqst = 0;
653dd285b06SPaolo Bonzini     s->irqen = 0;
654dd285b06SPaolo Bonzini     s->clkcontrol = 0;
655dd285b06SPaolo Bonzini     s->serial_config = 0;
656dd285b06SPaolo Bonzini 
657dd285b06SPaolo Bonzini     omap_sti_interrupt_update(s);
658dd285b06SPaolo Bonzini }
659dd285b06SPaolo Bonzini 
omap_sti_read(void * opaque,hwaddr addr,unsigned size)660dd285b06SPaolo Bonzini static uint64_t omap_sti_read(void *opaque, hwaddr addr,
661dd285b06SPaolo Bonzini                               unsigned size)
662dd285b06SPaolo Bonzini {
663a75ed3c4SPhilippe Mathieu-Daudé     struct omap_sti_s *s = opaque;
664dd285b06SPaolo Bonzini 
665dd285b06SPaolo Bonzini     if (size != 4) {
666dd285b06SPaolo Bonzini         return omap_badwidth_read32(opaque, addr);
667dd285b06SPaolo Bonzini     }
668dd285b06SPaolo Bonzini 
669dd285b06SPaolo Bonzini     switch (addr) {
670dd285b06SPaolo Bonzini     case 0x00:	/* STI_REVISION */
671dd285b06SPaolo Bonzini         return 0x10;
672dd285b06SPaolo Bonzini 
673dd285b06SPaolo Bonzini     case 0x10:	/* STI_SYSCONFIG */
674dd285b06SPaolo Bonzini         return s->sysconfig;
675dd285b06SPaolo Bonzini 
676dd285b06SPaolo Bonzini     case 0x14:	/* STI_SYSSTATUS / STI_RX_STATUS / XTI_SYSSTATUS */
677dd285b06SPaolo Bonzini         return 0x00;
678dd285b06SPaolo Bonzini 
679dd285b06SPaolo Bonzini     case 0x18:	/* STI_IRQSTATUS */
680dd285b06SPaolo Bonzini         return s->irqst;
681dd285b06SPaolo Bonzini 
682dd285b06SPaolo Bonzini     case 0x1c:	/* STI_IRQSETEN / STI_IRQCLREN */
683dd285b06SPaolo Bonzini         return s->irqen;
684dd285b06SPaolo Bonzini 
685dd285b06SPaolo Bonzini     case 0x24:	/* STI_ER / STI_DR / XTI_TRACESELECT */
686dd285b06SPaolo Bonzini     case 0x28:	/* STI_RX_DR / XTI_RXDATA */
687dd285b06SPaolo Bonzini         /* TODO */
688dd285b06SPaolo Bonzini         return 0;
689dd285b06SPaolo Bonzini 
690dd285b06SPaolo Bonzini     case 0x2c:	/* STI_CLK_CTRL / XTI_SCLKCRTL */
691dd285b06SPaolo Bonzini         return s->clkcontrol;
692dd285b06SPaolo Bonzini 
693dd285b06SPaolo Bonzini     case 0x30:	/* STI_SERIAL_CFG / XTI_SCONFIG */
694dd285b06SPaolo Bonzini         return s->serial_config;
695dd285b06SPaolo Bonzini     }
696dd285b06SPaolo Bonzini 
697dd285b06SPaolo Bonzini     OMAP_BAD_REG(addr);
698dd285b06SPaolo Bonzini     return 0;
699dd285b06SPaolo Bonzini }
700dd285b06SPaolo Bonzini 
omap_sti_write(void * opaque,hwaddr addr,uint64_t value,unsigned size)701dd285b06SPaolo Bonzini static void omap_sti_write(void *opaque, hwaddr addr,
702dd285b06SPaolo Bonzini                            uint64_t value, unsigned size)
703dd285b06SPaolo Bonzini {
704a75ed3c4SPhilippe Mathieu-Daudé     struct omap_sti_s *s = opaque;
705dd285b06SPaolo Bonzini 
706dd285b06SPaolo Bonzini     if (size != 4) {
70777a8257eSStefan Weil         omap_badwidth_write32(opaque, addr, value);
70877a8257eSStefan Weil         return;
709dd285b06SPaolo Bonzini     }
710dd285b06SPaolo Bonzini 
711dd285b06SPaolo Bonzini     switch (addr) {
712dd285b06SPaolo Bonzini     case 0x00:	/* STI_REVISION */
713dd285b06SPaolo Bonzini     case 0x14:	/* STI_SYSSTATUS / STI_RX_STATUS / XTI_SYSSTATUS */
714dd285b06SPaolo Bonzini         OMAP_RO_REG(addr);
715dd285b06SPaolo Bonzini         return;
716dd285b06SPaolo Bonzini 
717dd285b06SPaolo Bonzini     case 0x10:	/* STI_SYSCONFIG */
718dd285b06SPaolo Bonzini         if (value & (1 << 1))				/* SOFTRESET */
719dd285b06SPaolo Bonzini             omap_sti_reset(s);
720dd285b06SPaolo Bonzini         s->sysconfig = value & 0xfe;
721dd285b06SPaolo Bonzini         break;
722dd285b06SPaolo Bonzini 
723dd285b06SPaolo Bonzini     case 0x18:	/* STI_IRQSTATUS */
724dd285b06SPaolo Bonzini         s->irqst &= ~value;
725dd285b06SPaolo Bonzini         omap_sti_interrupt_update(s);
726dd285b06SPaolo Bonzini         break;
727dd285b06SPaolo Bonzini 
728dd285b06SPaolo Bonzini     case 0x1c:	/* STI_IRQSETEN / STI_IRQCLREN */
729dd285b06SPaolo Bonzini         s->irqen = value & 0xffff;
730dd285b06SPaolo Bonzini         omap_sti_interrupt_update(s);
731dd285b06SPaolo Bonzini         break;
732dd285b06SPaolo Bonzini 
733dd285b06SPaolo Bonzini     case 0x2c:	/* STI_CLK_CTRL / XTI_SCLKCRTL */
734dd285b06SPaolo Bonzini         s->clkcontrol = value & 0xff;
735dd285b06SPaolo Bonzini         break;
736dd285b06SPaolo Bonzini 
737dd285b06SPaolo Bonzini     case 0x30:	/* STI_SERIAL_CFG / XTI_SCONFIG */
738dd285b06SPaolo Bonzini         s->serial_config = value & 0xff;
739dd285b06SPaolo Bonzini         break;
740dd285b06SPaolo Bonzini 
741dd285b06SPaolo Bonzini     case 0x24:	/* STI_ER / STI_DR / XTI_TRACESELECT */
742dd285b06SPaolo Bonzini     case 0x28:	/* STI_RX_DR / XTI_RXDATA */
743dd285b06SPaolo Bonzini         /* TODO */
744dd285b06SPaolo Bonzini         return;
745dd285b06SPaolo Bonzini 
746dd285b06SPaolo Bonzini     default:
747dd285b06SPaolo Bonzini         OMAP_BAD_REG(addr);
748dd285b06SPaolo Bonzini         return;
749dd285b06SPaolo Bonzini     }
750dd285b06SPaolo Bonzini }
751dd285b06SPaolo Bonzini 
752dd285b06SPaolo Bonzini static const MemoryRegionOps omap_sti_ops = {
753dd285b06SPaolo Bonzini     .read = omap_sti_read,
754dd285b06SPaolo Bonzini     .write = omap_sti_write,
755dd285b06SPaolo Bonzini     .endianness = DEVICE_NATIVE_ENDIAN,
756dd285b06SPaolo Bonzini };
757dd285b06SPaolo Bonzini 
omap_sti_fifo_read(void * opaque,hwaddr addr,unsigned size)758a75ed3c4SPhilippe Mathieu-Daudé static uint64_t omap_sti_fifo_read(void *opaque, hwaddr addr, unsigned size)
759dd285b06SPaolo Bonzini {
760dd285b06SPaolo Bonzini     OMAP_BAD_REG(addr);
761dd285b06SPaolo Bonzini     return 0;
762dd285b06SPaolo Bonzini }
763dd285b06SPaolo Bonzini 
omap_sti_fifo_write(void * opaque,hwaddr addr,uint64_t value,unsigned size)764dd285b06SPaolo Bonzini static void omap_sti_fifo_write(void *opaque, hwaddr addr,
765dd285b06SPaolo Bonzini                                 uint64_t value, unsigned size)
766dd285b06SPaolo Bonzini {
767a75ed3c4SPhilippe Mathieu-Daudé     struct omap_sti_s *s = opaque;
768dd285b06SPaolo Bonzini     int ch = addr >> 6;
769dd285b06SPaolo Bonzini     uint8_t byte = value;
770dd285b06SPaolo Bonzini 
771dd285b06SPaolo Bonzini     if (size != 1) {
77277a8257eSStefan Weil         omap_badwidth_write8(opaque, addr, size);
77377a8257eSStefan Weil         return;
774dd285b06SPaolo Bonzini     }
775dd285b06SPaolo Bonzini 
776dd285b06SPaolo Bonzini     if (ch == STI_TRACE_CONTROL_CHANNEL) {
777dd285b06SPaolo Bonzini         /* Flush channel <i>value</i>.  */
7786ab3fc32SDaniel P. Berrange         /* XXX this blocks entire thread. Rewrite to use
7796ab3fc32SDaniel P. Berrange          * qemu_chr_fe_write and background I/O callbacks */
7805345fdb4SMarc-André Lureau         qemu_chr_fe_write_all(&s->chr, (const uint8_t *) "\r", 1);
781dd285b06SPaolo Bonzini     } else if (ch == STI_TRACE_CONSOLE_CHANNEL || 1) {
782dd285b06SPaolo Bonzini         if (value == 0xc0 || value == 0xc3) {
783dd285b06SPaolo Bonzini             /* Open channel <i>ch</i>.  */
7845345fdb4SMarc-André Lureau         } else if (value == 0x00) {
7855345fdb4SMarc-André Lureau             qemu_chr_fe_write_all(&s->chr, (const uint8_t *) "\n", 1);
7865345fdb4SMarc-André Lureau         } else {
7875345fdb4SMarc-André Lureau             qemu_chr_fe_write_all(&s->chr, &byte, 1);
7885345fdb4SMarc-André Lureau         }
789dd285b06SPaolo Bonzini     }
790dd285b06SPaolo Bonzini }
791dd285b06SPaolo Bonzini 
792dd285b06SPaolo Bonzini static const MemoryRegionOps omap_sti_fifo_ops = {
793dd285b06SPaolo Bonzini     .read = omap_sti_fifo_read,
794dd285b06SPaolo Bonzini     .write = omap_sti_fifo_write,
795dd285b06SPaolo Bonzini     .endianness = DEVICE_NATIVE_ENDIAN,
796dd285b06SPaolo Bonzini };
797dd285b06SPaolo Bonzini 
omap_sti_init(struct omap_target_agent_s * ta,MemoryRegion * sysmem,hwaddr channel_base,qemu_irq irq,omap_clk clk,Chardev * chr)798dd285b06SPaolo Bonzini static struct omap_sti_s *omap_sti_init(struct omap_target_agent_s *ta,
799dd285b06SPaolo Bonzini                 MemoryRegion *sysmem,
800dd285b06SPaolo Bonzini                 hwaddr channel_base, qemu_irq irq, omap_clk clk,
8010ec7b3e7SMarc-André Lureau                 Chardev *chr)
802dd285b06SPaolo Bonzini {
803b45c03f5SMarkus Armbruster     struct omap_sti_s *s = g_new0(struct omap_sti_s, 1);
804dd285b06SPaolo Bonzini 
805dd285b06SPaolo Bonzini     s->irq = irq;
806dd285b06SPaolo Bonzini     omap_sti_reset(s);
807dd285b06SPaolo Bonzini 
8084ad6f6cbSPaolo Bonzini     qemu_chr_fe_init(&s->chr, chr ?: qemu_chr_new("null", "null", NULL),
80932a6ebecSMarc-André Lureau                      &error_abort);
810dd285b06SPaolo Bonzini 
8112c9b15caSPaolo Bonzini     memory_region_init_io(&s->iomem, NULL, &omap_sti_ops, s, "omap.sti",
812dd285b06SPaolo Bonzini                           omap_l4_region_size(ta, 0));
813dd285b06SPaolo Bonzini     omap_l4_attach(ta, 0, &s->iomem);
814dd285b06SPaolo Bonzini 
8152c9b15caSPaolo Bonzini     memory_region_init_io(&s->iomem_fifo, NULL, &omap_sti_fifo_ops, s,
816dd285b06SPaolo Bonzini                           "omap.sti.fifo", 0x10000);
817dd285b06SPaolo Bonzini     memory_region_add_subregion(sysmem, channel_base, &s->iomem_fifo);
818dd285b06SPaolo Bonzini 
819dd285b06SPaolo Bonzini     return s;
820dd285b06SPaolo Bonzini }
821dd285b06SPaolo Bonzini 
822dd285b06SPaolo Bonzini /* L4 Interconnect */
823dd285b06SPaolo Bonzini #define L4TA(n)		(n)
824dd285b06SPaolo Bonzini #define L4TAO(n)	((n) + 39)
825dd285b06SPaolo Bonzini 
826dd285b06SPaolo Bonzini static const struct omap_l4_region_s omap_l4_region[125] = {
827dd285b06SPaolo Bonzini     [  1] = { 0x40800,  0x800, 32          }, /* Initiator agent */
828dd285b06SPaolo Bonzini     [  2] = { 0x41000, 0x1000, 32          }, /* Link agent */
829dd285b06SPaolo Bonzini     [  0] = { 0x40000,  0x800, 32          }, /* Address and protection */
830dd285b06SPaolo Bonzini     [  3] = { 0x00000, 0x1000, 32 | 16 | 8 }, /* System Control and Pinout */
831dd285b06SPaolo Bonzini     [  4] = { 0x01000, 0x1000, 32 | 16 | 8 }, /* L4TAO1 */
832dd285b06SPaolo Bonzini     [  5] = { 0x04000, 0x1000, 32 | 16     }, /* 32K Timer */
833dd285b06SPaolo Bonzini     [  6] = { 0x05000, 0x1000, 32 | 16 | 8 }, /* L4TAO2 */
834dd285b06SPaolo Bonzini     [  7] = { 0x08000,  0x800, 32          }, /* PRCM Region A */
835dd285b06SPaolo Bonzini     [  8] = { 0x08800,  0x800, 32          }, /* PRCM Region B */
836dd285b06SPaolo Bonzini     [  9] = { 0x09000, 0x1000, 32 | 16 | 8 }, /* L4TAO */
837dd285b06SPaolo Bonzini     [ 10] = { 0x12000, 0x1000, 32 | 16 | 8 }, /* Test (BCM) */
838dd285b06SPaolo Bonzini     [ 11] = { 0x13000, 0x1000, 32 | 16 | 8 }, /* L4TA1 */
839dd285b06SPaolo Bonzini     [ 12] = { 0x14000, 0x1000, 32          }, /* Test/emulation (TAP) */
840dd285b06SPaolo Bonzini     [ 13] = { 0x15000, 0x1000, 32 | 16 | 8 }, /* L4TA2 */
841dd285b06SPaolo Bonzini     [ 14] = { 0x18000, 0x1000, 32 | 16 | 8 }, /* GPIO1 */
842dd285b06SPaolo Bonzini     [ 16] = { 0x1a000, 0x1000, 32 | 16 | 8 }, /* GPIO2 */
843dd285b06SPaolo Bonzini     [ 18] = { 0x1c000, 0x1000, 32 | 16 | 8 }, /* GPIO3 */
844dd285b06SPaolo Bonzini     [ 19] = { 0x1e000, 0x1000, 32 | 16 | 8 }, /* GPIO4 */
845dd285b06SPaolo Bonzini     [ 15] = { 0x19000, 0x1000, 32 | 16 | 8 }, /* Quad GPIO TOP */
846dd285b06SPaolo Bonzini     [ 17] = { 0x1b000, 0x1000, 32 | 16 | 8 }, /* L4TA3 */
847dd285b06SPaolo Bonzini     [ 20] = { 0x20000, 0x1000, 32 | 16 | 8 }, /* WD Timer 1 (Secure) */
848dd285b06SPaolo Bonzini     [ 22] = { 0x22000, 0x1000, 32 | 16 | 8 }, /* WD Timer 2 (OMAP) */
849dd285b06SPaolo Bonzini     [ 21] = { 0x21000, 0x1000, 32 | 16 | 8 }, /* Dual WD timer TOP */
850dd285b06SPaolo Bonzini     [ 23] = { 0x23000, 0x1000, 32 | 16 | 8 }, /* L4TA4 */
851dd285b06SPaolo Bonzini     [ 24] = { 0x28000, 0x1000, 32 | 16 | 8 }, /* GP Timer 1 */
852dd285b06SPaolo Bonzini     [ 25] = { 0x29000, 0x1000, 32 | 16 | 8 }, /* L4TA7 */
853dd285b06SPaolo Bonzini     [ 26] = { 0x48000, 0x2000, 32 | 16 | 8 }, /* Emulation (ARM11ETB) */
854dd285b06SPaolo Bonzini     [ 27] = { 0x4a000, 0x1000, 32 | 16 | 8 }, /* L4TA9 */
855dd285b06SPaolo Bonzini     [ 28] = { 0x50000,  0x400, 32 | 16 | 8 }, /* Display top */
856dd285b06SPaolo Bonzini     [ 29] = { 0x50400,  0x400, 32 | 16 | 8 }, /* Display control */
857dd285b06SPaolo Bonzini     [ 30] = { 0x50800,  0x400, 32 | 16 | 8 }, /* Display RFBI */
858dd285b06SPaolo Bonzini     [ 31] = { 0x50c00,  0x400, 32 | 16 | 8 }, /* Display encoder */
859dd285b06SPaolo Bonzini     [ 32] = { 0x51000, 0x1000, 32 | 16 | 8 }, /* L4TA10 */
860dd285b06SPaolo Bonzini     [ 33] = { 0x52000,  0x400, 32 | 16 | 8 }, /* Camera top */
861dd285b06SPaolo Bonzini     [ 34] = { 0x52400,  0x400, 32 | 16 | 8 }, /* Camera core */
862dd285b06SPaolo Bonzini     [ 35] = { 0x52800,  0x400, 32 | 16 | 8 }, /* Camera DMA */
863dd285b06SPaolo Bonzini     [ 36] = { 0x52c00,  0x400, 32 | 16 | 8 }, /* Camera MMU */
864dd285b06SPaolo Bonzini     [ 37] = { 0x53000, 0x1000, 32 | 16 | 8 }, /* L4TA11 */
865dd285b06SPaolo Bonzini     [ 38] = { 0x56000, 0x1000, 32 | 16 | 8 }, /* sDMA */
866dd285b06SPaolo Bonzini     [ 39] = { 0x57000, 0x1000, 32 | 16 | 8 }, /* L4TA12 */
867dd285b06SPaolo Bonzini     [ 40] = { 0x58000, 0x1000, 32 | 16 | 8 }, /* SSI top */
868dd285b06SPaolo Bonzini     [ 41] = { 0x59000, 0x1000, 32 | 16 | 8 }, /* SSI GDD */
869dd285b06SPaolo Bonzini     [ 42] = { 0x5a000, 0x1000, 32 | 16 | 8 }, /* SSI Port1 */
870dd285b06SPaolo Bonzini     [ 43] = { 0x5b000, 0x1000, 32 | 16 | 8 }, /* SSI Port2 */
871dd285b06SPaolo Bonzini     [ 44] = { 0x5c000, 0x1000, 32 | 16 | 8 }, /* L4TA13 */
872dd285b06SPaolo Bonzini     [ 45] = { 0x5e000, 0x1000, 32 | 16 | 8 }, /* USB OTG */
873dd285b06SPaolo Bonzini     [ 46] = { 0x5f000, 0x1000, 32 | 16 | 8 }, /* L4TAO4 */
874dd285b06SPaolo Bonzini     [ 47] = { 0x60000, 0x1000, 32 | 16 | 8 }, /* Emulation (WIN_TRACER1SDRC) */
875dd285b06SPaolo Bonzini     [ 48] = { 0x61000, 0x1000, 32 | 16 | 8 }, /* L4TA14 */
876dd285b06SPaolo Bonzini     [ 49] = { 0x62000, 0x1000, 32 | 16 | 8 }, /* Emulation (WIN_TRACER2GPMC) */
877dd285b06SPaolo Bonzini     [ 50] = { 0x63000, 0x1000, 32 | 16 | 8 }, /* L4TA15 */
878dd285b06SPaolo Bonzini     [ 51] = { 0x64000, 0x1000, 32 | 16 | 8 }, /* Emulation (WIN_TRACER3OCM) */
879dd285b06SPaolo Bonzini     [ 52] = { 0x65000, 0x1000, 32 | 16 | 8 }, /* L4TA16 */
880dd285b06SPaolo Bonzini     [ 53] = { 0x66000,  0x300, 32 | 16 | 8 }, /* Emulation (WIN_TRACER4L4) */
881dd285b06SPaolo Bonzini     [ 54] = { 0x67000, 0x1000, 32 | 16 | 8 }, /* L4TA17 */
882dd285b06SPaolo Bonzini     [ 55] = { 0x68000, 0x1000, 32 | 16 | 8 }, /* Emulation (XTI) */
883dd285b06SPaolo Bonzini     [ 56] = { 0x69000, 0x1000, 32 | 16 | 8 }, /* L4TA18 */
884dd285b06SPaolo Bonzini     [ 57] = { 0x6a000, 0x1000,      16 | 8 }, /* UART1 */
885dd285b06SPaolo Bonzini     [ 58] = { 0x6b000, 0x1000, 32 | 16 | 8 }, /* L4TA19 */
886dd285b06SPaolo Bonzini     [ 59] = { 0x6c000, 0x1000,      16 | 8 }, /* UART2 */
887dd285b06SPaolo Bonzini     [ 60] = { 0x6d000, 0x1000, 32 | 16 | 8 }, /* L4TA20 */
888dd285b06SPaolo Bonzini     [ 61] = { 0x6e000, 0x1000,      16 | 8 }, /* UART3 */
889dd285b06SPaolo Bonzini     [ 62] = { 0x6f000, 0x1000, 32 | 16 | 8 }, /* L4TA21 */
890dd285b06SPaolo Bonzini     [ 63] = { 0x70000, 0x1000,      16     }, /* I2C1 */
891dd285b06SPaolo Bonzini     [ 64] = { 0x71000, 0x1000, 32 | 16 | 8 }, /* L4TAO5 */
892dd285b06SPaolo Bonzini     [ 65] = { 0x72000, 0x1000,      16     }, /* I2C2 */
893dd285b06SPaolo Bonzini     [ 66] = { 0x73000, 0x1000, 32 | 16 | 8 }, /* L4TAO6 */
894dd285b06SPaolo Bonzini     [ 67] = { 0x74000, 0x1000,      16     }, /* McBSP1 */
895dd285b06SPaolo Bonzini     [ 68] = { 0x75000, 0x1000, 32 | 16 | 8 }, /* L4TAO7 */
896dd285b06SPaolo Bonzini     [ 69] = { 0x76000, 0x1000,      16     }, /* McBSP2 */
897dd285b06SPaolo Bonzini     [ 70] = { 0x77000, 0x1000, 32 | 16 | 8 }, /* L4TAO8 */
898dd285b06SPaolo Bonzini     [ 71] = { 0x24000, 0x1000, 32 | 16 | 8 }, /* WD Timer 3 (DSP) */
899dd285b06SPaolo Bonzini     [ 72] = { 0x25000, 0x1000, 32 | 16 | 8 }, /* L4TA5 */
900dd285b06SPaolo Bonzini     [ 73] = { 0x26000, 0x1000, 32 | 16 | 8 }, /* WD Timer 4 (IVA) */
901dd285b06SPaolo Bonzini     [ 74] = { 0x27000, 0x1000, 32 | 16 | 8 }, /* L4TA6 */
902dd285b06SPaolo Bonzini     [ 75] = { 0x2a000, 0x1000, 32 | 16 | 8 }, /* GP Timer 2 */
903dd285b06SPaolo Bonzini     [ 76] = { 0x2b000, 0x1000, 32 | 16 | 8 }, /* L4TA8 */
904dd285b06SPaolo Bonzini     [ 77] = { 0x78000, 0x1000, 32 | 16 | 8 }, /* GP Timer 3 */
905dd285b06SPaolo Bonzini     [ 78] = { 0x79000, 0x1000, 32 | 16 | 8 }, /* L4TA22 */
906dd285b06SPaolo Bonzini     [ 79] = { 0x7a000, 0x1000, 32 | 16 | 8 }, /* GP Timer 4 */
907dd285b06SPaolo Bonzini     [ 80] = { 0x7b000, 0x1000, 32 | 16 | 8 }, /* L4TA23 */
908dd285b06SPaolo Bonzini     [ 81] = { 0x7c000, 0x1000, 32 | 16 | 8 }, /* GP Timer 5 */
909dd285b06SPaolo Bonzini     [ 82] = { 0x7d000, 0x1000, 32 | 16 | 8 }, /* L4TA24 */
910dd285b06SPaolo Bonzini     [ 83] = { 0x7e000, 0x1000, 32 | 16 | 8 }, /* GP Timer 6 */
911dd285b06SPaolo Bonzini     [ 84] = { 0x7f000, 0x1000, 32 | 16 | 8 }, /* L4TA25 */
912dd285b06SPaolo Bonzini     [ 85] = { 0x80000, 0x1000, 32 | 16 | 8 }, /* GP Timer 7 */
913dd285b06SPaolo Bonzini     [ 86] = { 0x81000, 0x1000, 32 | 16 | 8 }, /* L4TA26 */
914dd285b06SPaolo Bonzini     [ 87] = { 0x82000, 0x1000, 32 | 16 | 8 }, /* GP Timer 8 */
915dd285b06SPaolo Bonzini     [ 88] = { 0x83000, 0x1000, 32 | 16 | 8 }, /* L4TA27 */
916dd285b06SPaolo Bonzini     [ 89] = { 0x84000, 0x1000, 32 | 16 | 8 }, /* GP Timer 9 */
917dd285b06SPaolo Bonzini     [ 90] = { 0x85000, 0x1000, 32 | 16 | 8 }, /* L4TA28 */
918dd285b06SPaolo Bonzini     [ 91] = { 0x86000, 0x1000, 32 | 16 | 8 }, /* GP Timer 10 */
919dd285b06SPaolo Bonzini     [ 92] = { 0x87000, 0x1000, 32 | 16 | 8 }, /* L4TA29 */
920dd285b06SPaolo Bonzini     [ 93] = { 0x88000, 0x1000, 32 | 16 | 8 }, /* GP Timer 11 */
921dd285b06SPaolo Bonzini     [ 94] = { 0x89000, 0x1000, 32 | 16 | 8 }, /* L4TA30 */
922dd285b06SPaolo Bonzini     [ 95] = { 0x8a000, 0x1000, 32 | 16 | 8 }, /* GP Timer 12 */
923dd285b06SPaolo Bonzini     [ 96] = { 0x8b000, 0x1000, 32 | 16 | 8 }, /* L4TA31 */
924dd285b06SPaolo Bonzini     [ 97] = { 0x90000, 0x1000,      16     }, /* EAC */
925dd285b06SPaolo Bonzini     [ 98] = { 0x91000, 0x1000, 32 | 16 | 8 }, /* L4TA32 */
926dd285b06SPaolo Bonzini     [ 99] = { 0x92000, 0x1000,      16     }, /* FAC */
927dd285b06SPaolo Bonzini     [100] = { 0x93000, 0x1000, 32 | 16 | 8 }, /* L4TA33 */
928dd285b06SPaolo Bonzini     [101] = { 0x94000, 0x1000, 32 | 16 | 8 }, /* IPC (MAILBOX) */
929dd285b06SPaolo Bonzini     [102] = { 0x95000, 0x1000, 32 | 16 | 8 }, /* L4TA34 */
930dd285b06SPaolo Bonzini     [103] = { 0x98000, 0x1000, 32 | 16 | 8 }, /* SPI1 */
931dd285b06SPaolo Bonzini     [104] = { 0x99000, 0x1000, 32 | 16 | 8 }, /* L4TA35 */
932dd285b06SPaolo Bonzini     [105] = { 0x9a000, 0x1000, 32 | 16 | 8 }, /* SPI2 */
933dd285b06SPaolo Bonzini     [106] = { 0x9b000, 0x1000, 32 | 16 | 8 }, /* L4TA36 */
934dd285b06SPaolo Bonzini     [107] = { 0x9c000, 0x1000,      16 | 8 }, /* MMC SDIO */
935dd285b06SPaolo Bonzini     [108] = { 0x9d000, 0x1000, 32 | 16 | 8 }, /* L4TAO9 */
936dd285b06SPaolo Bonzini     [109] = { 0x9e000, 0x1000, 32 | 16 | 8 }, /* MS_PRO */
937dd285b06SPaolo Bonzini     [110] = { 0x9f000, 0x1000, 32 | 16 | 8 }, /* L4TAO10 */
938dd285b06SPaolo Bonzini     [111] = { 0xa0000, 0x1000, 32          }, /* RNG */
939dd285b06SPaolo Bonzini     [112] = { 0xa1000, 0x1000, 32 | 16 | 8 }, /* L4TAO11 */
940dd285b06SPaolo Bonzini     [113] = { 0xa2000, 0x1000, 32          }, /* DES3DES */
941dd285b06SPaolo Bonzini     [114] = { 0xa3000, 0x1000, 32 | 16 | 8 }, /* L4TAO12 */
942dd285b06SPaolo Bonzini     [115] = { 0xa4000, 0x1000, 32          }, /* SHA1MD5 */
943dd285b06SPaolo Bonzini     [116] = { 0xa5000, 0x1000, 32 | 16 | 8 }, /* L4TAO13 */
944dd285b06SPaolo Bonzini     [117] = { 0xa6000, 0x1000, 32          }, /* AES */
945dd285b06SPaolo Bonzini     [118] = { 0xa7000, 0x1000, 32 | 16 | 8 }, /* L4TA37 */
946dd285b06SPaolo Bonzini     [119] = { 0xa8000, 0x2000, 32          }, /* PKA */
947dd285b06SPaolo Bonzini     [120] = { 0xaa000, 0x1000, 32 | 16 | 8 }, /* L4TA38 */
948dd285b06SPaolo Bonzini     [121] = { 0xb0000, 0x1000, 32          }, /* MG */
949dd285b06SPaolo Bonzini     [122] = { 0xb1000, 0x1000, 32 | 16 | 8 },
950dd285b06SPaolo Bonzini     [123] = { 0xb2000, 0x1000, 32          }, /* HDQ/1-Wire */
951dd285b06SPaolo Bonzini     [124] = { 0xb3000, 0x1000, 32 | 16 | 8 }, /* L4TA39 */
952dd285b06SPaolo Bonzini };
953dd285b06SPaolo Bonzini 
954dd285b06SPaolo Bonzini static const struct omap_l4_agent_info_s omap_l4_agent_info[54] = {
955dd285b06SPaolo Bonzini     { 0,           0, 3, 2 }, /* L4IA initiatior agent */
956dd285b06SPaolo Bonzini     { L4TAO(1),    3, 2, 1 }, /* Control and pinout module */
957dd285b06SPaolo Bonzini     { L4TAO(2),    5, 2, 1 }, /* 32K timer */
958dd285b06SPaolo Bonzini     { L4TAO(3),    7, 3, 2 }, /* PRCM */
959dd285b06SPaolo Bonzini     { L4TA(1),    10, 2, 1 }, /* BCM */
960dd285b06SPaolo Bonzini     { L4TA(2),    12, 2, 1 }, /* Test JTAG */
961dd285b06SPaolo Bonzini     { L4TA(3),    14, 6, 3 }, /* Quad GPIO */
962dd285b06SPaolo Bonzini     { L4TA(4),    20, 4, 3 }, /* WD timer 1/2 */
963dd285b06SPaolo Bonzini     { L4TA(7),    24, 2, 1 }, /* GP timer 1 */
964dd285b06SPaolo Bonzini     { L4TA(9),    26, 2, 1 }, /* ATM11 ETB */
965dd285b06SPaolo Bonzini     { L4TA(10),   28, 5, 4 }, /* Display subsystem */
966dd285b06SPaolo Bonzini     { L4TA(11),   33, 5, 4 }, /* Camera subsystem */
967dd285b06SPaolo Bonzini     { L4TA(12),   38, 2, 1 }, /* sDMA */
968dd285b06SPaolo Bonzini     { L4TA(13),   40, 5, 4 }, /* SSI */
969dd285b06SPaolo Bonzini     { L4TAO(4),   45, 2, 1 }, /* USB */
970dd285b06SPaolo Bonzini     { L4TA(14),   47, 2, 1 }, /* Win Tracer1 */
971dd285b06SPaolo Bonzini     { L4TA(15),   49, 2, 1 }, /* Win Tracer2 */
972dd285b06SPaolo Bonzini     { L4TA(16),   51, 2, 1 }, /* Win Tracer3 */
973dd285b06SPaolo Bonzini     { L4TA(17),   53, 2, 1 }, /* Win Tracer4 */
974dd285b06SPaolo Bonzini     { L4TA(18),   55, 2, 1 }, /* XTI */
975dd285b06SPaolo Bonzini     { L4TA(19),   57, 2, 1 }, /* UART1 */
976dd285b06SPaolo Bonzini     { L4TA(20),   59, 2, 1 }, /* UART2 */
977dd285b06SPaolo Bonzini     { L4TA(21),   61, 2, 1 }, /* UART3 */
978dd285b06SPaolo Bonzini     { L4TAO(5),   63, 2, 1 }, /* I2C1 */
979dd285b06SPaolo Bonzini     { L4TAO(6),   65, 2, 1 }, /* I2C2 */
980dd285b06SPaolo Bonzini     { L4TAO(7),   67, 2, 1 }, /* McBSP1 */
981dd285b06SPaolo Bonzini     { L4TAO(8),   69, 2, 1 }, /* McBSP2 */
982dd285b06SPaolo Bonzini     { L4TA(5),    71, 2, 1 }, /* WD Timer 3 (DSP) */
983dd285b06SPaolo Bonzini     { L4TA(6),    73, 2, 1 }, /* WD Timer 4 (IVA) */
984dd285b06SPaolo Bonzini     { L4TA(8),    75, 2, 1 }, /* GP Timer 2 */
985dd285b06SPaolo Bonzini     { L4TA(22),   77, 2, 1 }, /* GP Timer 3 */
986dd285b06SPaolo Bonzini     { L4TA(23),   79, 2, 1 }, /* GP Timer 4 */
987dd285b06SPaolo Bonzini     { L4TA(24),   81, 2, 1 }, /* GP Timer 5 */
988dd285b06SPaolo Bonzini     { L4TA(25),   83, 2, 1 }, /* GP Timer 6 */
989dd285b06SPaolo Bonzini     { L4TA(26),   85, 2, 1 }, /* GP Timer 7 */
990dd285b06SPaolo Bonzini     { L4TA(27),   87, 2, 1 }, /* GP Timer 8 */
991dd285b06SPaolo Bonzini     { L4TA(28),   89, 2, 1 }, /* GP Timer 9 */
992dd285b06SPaolo Bonzini     { L4TA(29),   91, 2, 1 }, /* GP Timer 10 */
993dd285b06SPaolo Bonzini     { L4TA(30),   93, 2, 1 }, /* GP Timer 11 */
994dd285b06SPaolo Bonzini     { L4TA(31),   95, 2, 1 }, /* GP Timer 12 */
995dd285b06SPaolo Bonzini     { L4TA(32),   97, 2, 1 }, /* EAC */
996dd285b06SPaolo Bonzini     { L4TA(33),   99, 2, 1 }, /* FAC */
997dd285b06SPaolo Bonzini     { L4TA(34),  101, 2, 1 }, /* IPC */
998dd285b06SPaolo Bonzini     { L4TA(35),  103, 2, 1 }, /* SPI1 */
999dd285b06SPaolo Bonzini     { L4TA(36),  105, 2, 1 }, /* SPI2 */
1000dd285b06SPaolo Bonzini     { L4TAO(9),  107, 2, 1 }, /* MMC SDIO */
1001dd285b06SPaolo Bonzini     { L4TAO(10), 109, 2, 1 },
1002dd285b06SPaolo Bonzini     { L4TAO(11), 111, 2, 1 }, /* RNG */
1003dd285b06SPaolo Bonzini     { L4TAO(12), 113, 2, 1 }, /* DES3DES */
1004dd285b06SPaolo Bonzini     { L4TAO(13), 115, 2, 1 }, /* SHA1MD5 */
1005dd285b06SPaolo Bonzini     { L4TA(37),  117, 2, 1 }, /* AES */
1006dd285b06SPaolo Bonzini     { L4TA(38),  119, 2, 1 }, /* PKA */
1007dd285b06SPaolo Bonzini     { -1,        121, 2, 1 },
1008dd285b06SPaolo Bonzini     { L4TA(39),  123, 2, 1 }, /* HDQ/1-Wire */
1009dd285b06SPaolo Bonzini };
1010dd285b06SPaolo Bonzini 
1011dd285b06SPaolo Bonzini #define omap_l4ta(bus, cs)	\
1012dd285b06SPaolo Bonzini     omap_l4ta_get(bus, omap_l4_region, omap_l4_agent_info, L4TA(cs))
1013dd285b06SPaolo Bonzini #define omap_l4tao(bus, cs)	\
1014dd285b06SPaolo Bonzini     omap_l4ta_get(bus, omap_l4_region, omap_l4_agent_info, L4TAO(cs))
1015dd285b06SPaolo Bonzini 
1016dd285b06SPaolo Bonzini /* Power, Reset, and Clock Management */
1017dd285b06SPaolo Bonzini struct omap_prcm_s {
1018dd285b06SPaolo Bonzini     qemu_irq irq[3];
1019dd285b06SPaolo Bonzini     struct omap_mpu_state_s *mpu;
1020dd285b06SPaolo Bonzini     MemoryRegion iomem0;
1021dd285b06SPaolo Bonzini     MemoryRegion iomem1;
1022dd285b06SPaolo Bonzini 
1023dd285b06SPaolo Bonzini     uint32_t irqst[3];
1024dd285b06SPaolo Bonzini     uint32_t irqen[3];
1025dd285b06SPaolo Bonzini 
1026dd285b06SPaolo Bonzini     uint32_t sysconfig;
1027dd285b06SPaolo Bonzini     uint32_t voltctrl;
1028dd285b06SPaolo Bonzini     uint32_t scratch[20];
1029dd285b06SPaolo Bonzini 
1030dd285b06SPaolo Bonzini     uint32_t clksrc[1];
1031dd285b06SPaolo Bonzini     uint32_t clkout[1];
1032dd285b06SPaolo Bonzini     uint32_t clkemul[1];
1033dd285b06SPaolo Bonzini     uint32_t clkpol[1];
1034dd285b06SPaolo Bonzini     uint32_t clksel[8];
1035dd285b06SPaolo Bonzini     uint32_t clken[12];
1036dd285b06SPaolo Bonzini     uint32_t clkctrl[4];
1037dd285b06SPaolo Bonzini     uint32_t clkidle[7];
1038dd285b06SPaolo Bonzini     uint32_t setuptime[2];
1039dd285b06SPaolo Bonzini 
1040dd285b06SPaolo Bonzini     uint32_t wkup[3];
1041dd285b06SPaolo Bonzini     uint32_t wken[3];
1042dd285b06SPaolo Bonzini     uint32_t wkst[3];
1043dd285b06SPaolo Bonzini     uint32_t rst[4];
1044dd285b06SPaolo Bonzini     uint32_t rstctrl[1];
1045dd285b06SPaolo Bonzini     uint32_t power[4];
1046dd285b06SPaolo Bonzini     uint32_t rsttime_wkup;
1047dd285b06SPaolo Bonzini 
1048dd285b06SPaolo Bonzini     uint32_t ev;
1049dd285b06SPaolo Bonzini     uint32_t evtime[2];
1050dd285b06SPaolo Bonzini 
1051dd285b06SPaolo Bonzini     int dpll_lock, apll_lock[2];
1052dd285b06SPaolo Bonzini };
1053dd285b06SPaolo Bonzini 
omap_prcm_int_update(struct omap_prcm_s * s,int dom)1054dd285b06SPaolo Bonzini static void omap_prcm_int_update(struct omap_prcm_s *s, int dom)
1055dd285b06SPaolo Bonzini {
1056dd285b06SPaolo Bonzini     qemu_set_irq(s->irq[dom], s->irqst[dom] & s->irqen[dom]);
1057dd285b06SPaolo Bonzini     /* XXX or is the mask applied before PRCM_IRQSTATUS_* ? */
1058dd285b06SPaolo Bonzini }
1059dd285b06SPaolo Bonzini 
omap_prcm_read(void * opaque,hwaddr addr,unsigned size)1060dd285b06SPaolo Bonzini static uint64_t omap_prcm_read(void *opaque, hwaddr addr,
1061dd285b06SPaolo Bonzini                                unsigned size)
1062dd285b06SPaolo Bonzini {
1063a75ed3c4SPhilippe Mathieu-Daudé     struct omap_prcm_s *s = opaque;
1064dd285b06SPaolo Bonzini     uint32_t ret;
1065dd285b06SPaolo Bonzini 
1066dd285b06SPaolo Bonzini     if (size != 4) {
1067dd285b06SPaolo Bonzini         return omap_badwidth_read32(opaque, addr);
1068dd285b06SPaolo Bonzini     }
1069dd285b06SPaolo Bonzini 
1070dd285b06SPaolo Bonzini     switch (addr) {
1071dd285b06SPaolo Bonzini     case 0x000:	/* PRCM_REVISION */
1072dd285b06SPaolo Bonzini         return 0x10;
1073dd285b06SPaolo Bonzini 
1074dd285b06SPaolo Bonzini     case 0x010:	/* PRCM_SYSCONFIG */
1075dd285b06SPaolo Bonzini         return s->sysconfig;
1076dd285b06SPaolo Bonzini 
1077dd285b06SPaolo Bonzini     case 0x018:	/* PRCM_IRQSTATUS_MPU */
1078dd285b06SPaolo Bonzini         return s->irqst[0];
1079dd285b06SPaolo Bonzini 
1080dd285b06SPaolo Bonzini     case 0x01c:	/* PRCM_IRQENABLE_MPU */
1081dd285b06SPaolo Bonzini         return s->irqen[0];
1082dd285b06SPaolo Bonzini 
1083dd285b06SPaolo Bonzini     case 0x050:	/* PRCM_VOLTCTRL */
1084dd285b06SPaolo Bonzini         return s->voltctrl;
1085dd285b06SPaolo Bonzini     case 0x054:	/* PRCM_VOLTST */
1086dd285b06SPaolo Bonzini         return s->voltctrl & 3;
1087dd285b06SPaolo Bonzini 
1088dd285b06SPaolo Bonzini     case 0x060:	/* PRCM_CLKSRC_CTRL */
1089dd285b06SPaolo Bonzini         return s->clksrc[0];
1090dd285b06SPaolo Bonzini     case 0x070:	/* PRCM_CLKOUT_CTRL */
1091dd285b06SPaolo Bonzini         return s->clkout[0];
1092dd285b06SPaolo Bonzini     case 0x078:	/* PRCM_CLKEMUL_CTRL */
1093dd285b06SPaolo Bonzini         return s->clkemul[0];
1094dd285b06SPaolo Bonzini     case 0x080:	/* PRCM_CLKCFG_CTRL */
1095dd285b06SPaolo Bonzini     case 0x084:	/* PRCM_CLKCFG_STATUS */
1096dd285b06SPaolo Bonzini         return 0;
1097dd285b06SPaolo Bonzini 
1098dd285b06SPaolo Bonzini     case 0x090:	/* PRCM_VOLTSETUP */
1099dd285b06SPaolo Bonzini         return s->setuptime[0];
1100dd285b06SPaolo Bonzini 
1101dd285b06SPaolo Bonzini     case 0x094:	/* PRCM_CLKSSETUP */
1102dd285b06SPaolo Bonzini         return s->setuptime[1];
1103dd285b06SPaolo Bonzini 
1104dd285b06SPaolo Bonzini     case 0x098:	/* PRCM_POLCTRL */
1105dd285b06SPaolo Bonzini         return s->clkpol[0];
1106dd285b06SPaolo Bonzini 
1107dd285b06SPaolo Bonzini     case 0x0b0:	/* GENERAL_PURPOSE1 */
1108dd285b06SPaolo Bonzini     case 0x0b4:	/* GENERAL_PURPOSE2 */
1109dd285b06SPaolo Bonzini     case 0x0b8:	/* GENERAL_PURPOSE3 */
1110dd285b06SPaolo Bonzini     case 0x0bc:	/* GENERAL_PURPOSE4 */
1111dd285b06SPaolo Bonzini     case 0x0c0:	/* GENERAL_PURPOSE5 */
1112dd285b06SPaolo Bonzini     case 0x0c4:	/* GENERAL_PURPOSE6 */
1113dd285b06SPaolo Bonzini     case 0x0c8:	/* GENERAL_PURPOSE7 */
1114dd285b06SPaolo Bonzini     case 0x0cc:	/* GENERAL_PURPOSE8 */
1115dd285b06SPaolo Bonzini     case 0x0d0:	/* GENERAL_PURPOSE9 */
1116dd285b06SPaolo Bonzini     case 0x0d4:	/* GENERAL_PURPOSE10 */
1117dd285b06SPaolo Bonzini     case 0x0d8:	/* GENERAL_PURPOSE11 */
1118dd285b06SPaolo Bonzini     case 0x0dc:	/* GENERAL_PURPOSE12 */
1119dd285b06SPaolo Bonzini     case 0x0e0:	/* GENERAL_PURPOSE13 */
1120dd285b06SPaolo Bonzini     case 0x0e4:	/* GENERAL_PURPOSE14 */
1121dd285b06SPaolo Bonzini     case 0x0e8:	/* GENERAL_PURPOSE15 */
1122dd285b06SPaolo Bonzini     case 0x0ec:	/* GENERAL_PURPOSE16 */
1123dd285b06SPaolo Bonzini     case 0x0f0:	/* GENERAL_PURPOSE17 */
1124dd285b06SPaolo Bonzini     case 0x0f4:	/* GENERAL_PURPOSE18 */
1125dd285b06SPaolo Bonzini     case 0x0f8:	/* GENERAL_PURPOSE19 */
1126dd285b06SPaolo Bonzini     case 0x0fc:	/* GENERAL_PURPOSE20 */
1127dd285b06SPaolo Bonzini         return s->scratch[(addr - 0xb0) >> 2];
1128dd285b06SPaolo Bonzini 
1129dd285b06SPaolo Bonzini     case 0x140:	/* CM_CLKSEL_MPU */
1130dd285b06SPaolo Bonzini         return s->clksel[0];
1131dd285b06SPaolo Bonzini     case 0x148:	/* CM_CLKSTCTRL_MPU */
1132dd285b06SPaolo Bonzini         return s->clkctrl[0];
1133dd285b06SPaolo Bonzini 
1134dd285b06SPaolo Bonzini     case 0x158:	/* RM_RSTST_MPU */
1135dd285b06SPaolo Bonzini         return s->rst[0];
1136dd285b06SPaolo Bonzini     case 0x1c8:	/* PM_WKDEP_MPU */
1137dd285b06SPaolo Bonzini         return s->wkup[0];
1138dd285b06SPaolo Bonzini     case 0x1d4:	/* PM_EVGENCTRL_MPU */
1139dd285b06SPaolo Bonzini         return s->ev;
1140dd285b06SPaolo Bonzini     case 0x1d8:	/* PM_EVEGENONTIM_MPU */
1141dd285b06SPaolo Bonzini         return s->evtime[0];
1142dd285b06SPaolo Bonzini     case 0x1dc:	/* PM_EVEGENOFFTIM_MPU */
1143dd285b06SPaolo Bonzini         return s->evtime[1];
1144dd285b06SPaolo Bonzini     case 0x1e0:	/* PM_PWSTCTRL_MPU */
1145dd285b06SPaolo Bonzini         return s->power[0];
1146dd285b06SPaolo Bonzini     case 0x1e4:	/* PM_PWSTST_MPU */
1147dd285b06SPaolo Bonzini         return 0;
1148dd285b06SPaolo Bonzini 
1149dd285b06SPaolo Bonzini     case 0x200:	/* CM_FCLKEN1_CORE */
1150dd285b06SPaolo Bonzini         return s->clken[0];
1151dd285b06SPaolo Bonzini     case 0x204:	/* CM_FCLKEN2_CORE */
1152dd285b06SPaolo Bonzini         return s->clken[1];
1153dd285b06SPaolo Bonzini     case 0x210:	/* CM_ICLKEN1_CORE */
1154dd285b06SPaolo Bonzini         return s->clken[2];
1155dd285b06SPaolo Bonzini     case 0x214:	/* CM_ICLKEN2_CORE */
1156dd285b06SPaolo Bonzini         return s->clken[3];
1157dd285b06SPaolo Bonzini     case 0x21c:	/* CM_ICLKEN4_CORE */
1158dd285b06SPaolo Bonzini         return s->clken[4];
1159dd285b06SPaolo Bonzini 
1160dd285b06SPaolo Bonzini     case 0x220:	/* CM_IDLEST1_CORE */
1161dd285b06SPaolo Bonzini         /* TODO: check the actual iclk status */
1162dd285b06SPaolo Bonzini         return 0x7ffffff9;
1163dd285b06SPaolo Bonzini     case 0x224:	/* CM_IDLEST2_CORE */
1164dd285b06SPaolo Bonzini         /* TODO: check the actual iclk status */
1165dd285b06SPaolo Bonzini         return 0x00000007;
1166dd285b06SPaolo Bonzini     case 0x22c:	/* CM_IDLEST4_CORE */
1167dd285b06SPaolo Bonzini         /* TODO: check the actual iclk status */
1168dd285b06SPaolo Bonzini         return 0x0000001f;
1169dd285b06SPaolo Bonzini 
1170dd285b06SPaolo Bonzini     case 0x230:	/* CM_AUTOIDLE1_CORE */
1171dd285b06SPaolo Bonzini         return s->clkidle[0];
1172dd285b06SPaolo Bonzini     case 0x234:	/* CM_AUTOIDLE2_CORE */
1173dd285b06SPaolo Bonzini         return s->clkidle[1];
1174dd285b06SPaolo Bonzini     case 0x238:	/* CM_AUTOIDLE3_CORE */
1175dd285b06SPaolo Bonzini         return s->clkidle[2];
1176dd285b06SPaolo Bonzini     case 0x23c:	/* CM_AUTOIDLE4_CORE */
1177dd285b06SPaolo Bonzini         return s->clkidle[3];
1178dd285b06SPaolo Bonzini 
1179dd285b06SPaolo Bonzini     case 0x240:	/* CM_CLKSEL1_CORE */
1180dd285b06SPaolo Bonzini         return s->clksel[1];
1181dd285b06SPaolo Bonzini     case 0x244:	/* CM_CLKSEL2_CORE */
1182dd285b06SPaolo Bonzini         return s->clksel[2];
1183dd285b06SPaolo Bonzini 
1184dd285b06SPaolo Bonzini     case 0x248:	/* CM_CLKSTCTRL_CORE */
1185dd285b06SPaolo Bonzini         return s->clkctrl[1];
1186dd285b06SPaolo Bonzini 
1187dd285b06SPaolo Bonzini     case 0x2a0:	/* PM_WKEN1_CORE */
1188dd285b06SPaolo Bonzini         return s->wken[0];
1189dd285b06SPaolo Bonzini     case 0x2a4:	/* PM_WKEN2_CORE */
1190dd285b06SPaolo Bonzini         return s->wken[1];
1191dd285b06SPaolo Bonzini 
1192dd285b06SPaolo Bonzini     case 0x2b0:	/* PM_WKST1_CORE */
1193dd285b06SPaolo Bonzini         return s->wkst[0];
1194dd285b06SPaolo Bonzini     case 0x2b4:	/* PM_WKST2_CORE */
1195dd285b06SPaolo Bonzini         return s->wkst[1];
1196dd285b06SPaolo Bonzini     case 0x2c8:	/* PM_WKDEP_CORE */
1197dd285b06SPaolo Bonzini         return 0x1e;
1198dd285b06SPaolo Bonzini 
1199dd285b06SPaolo Bonzini     case 0x2e0:	/* PM_PWSTCTRL_CORE */
1200dd285b06SPaolo Bonzini         return s->power[1];
1201dd285b06SPaolo Bonzini     case 0x2e4:	/* PM_PWSTST_CORE */
1202dd285b06SPaolo Bonzini         return 0x000030 | (s->power[1] & 0xfc00);
1203dd285b06SPaolo Bonzini 
1204dd285b06SPaolo Bonzini     case 0x300:	/* CM_FCLKEN_GFX */
1205dd285b06SPaolo Bonzini         return s->clken[5];
1206dd285b06SPaolo Bonzini     case 0x310:	/* CM_ICLKEN_GFX */
1207dd285b06SPaolo Bonzini         return s->clken[6];
1208dd285b06SPaolo Bonzini     case 0x320:	/* CM_IDLEST_GFX */
1209dd285b06SPaolo Bonzini         /* TODO: check the actual iclk status */
1210dd285b06SPaolo Bonzini         return 0x00000001;
1211dd285b06SPaolo Bonzini     case 0x340:	/* CM_CLKSEL_GFX */
1212dd285b06SPaolo Bonzini         return s->clksel[3];
1213dd285b06SPaolo Bonzini     case 0x348:	/* CM_CLKSTCTRL_GFX */
1214dd285b06SPaolo Bonzini         return s->clkctrl[2];
1215dd285b06SPaolo Bonzini     case 0x350:	/* RM_RSTCTRL_GFX */
1216dd285b06SPaolo Bonzini         return s->rstctrl[0];
1217dd285b06SPaolo Bonzini     case 0x358:	/* RM_RSTST_GFX */
1218dd285b06SPaolo Bonzini         return s->rst[1];
1219dd285b06SPaolo Bonzini     case 0x3c8:	/* PM_WKDEP_GFX */
1220dd285b06SPaolo Bonzini         return s->wkup[1];
1221dd285b06SPaolo Bonzini 
1222dd285b06SPaolo Bonzini     case 0x3e0:	/* PM_PWSTCTRL_GFX */
1223dd285b06SPaolo Bonzini         return s->power[2];
1224dd285b06SPaolo Bonzini     case 0x3e4:	/* PM_PWSTST_GFX */
1225dd285b06SPaolo Bonzini         return s->power[2] & 3;
1226dd285b06SPaolo Bonzini 
1227dd285b06SPaolo Bonzini     case 0x400:	/* CM_FCLKEN_WKUP */
1228dd285b06SPaolo Bonzini         return s->clken[7];
1229dd285b06SPaolo Bonzini     case 0x410:	/* CM_ICLKEN_WKUP */
1230dd285b06SPaolo Bonzini         return s->clken[8];
1231dd285b06SPaolo Bonzini     case 0x420:	/* CM_IDLEST_WKUP */
1232dd285b06SPaolo Bonzini         /* TODO: check the actual iclk status */
1233dd285b06SPaolo Bonzini         return 0x0000003f;
1234dd285b06SPaolo Bonzini     case 0x430:	/* CM_AUTOIDLE_WKUP */
1235dd285b06SPaolo Bonzini         return s->clkidle[4];
1236dd285b06SPaolo Bonzini     case 0x440:	/* CM_CLKSEL_WKUP */
1237dd285b06SPaolo Bonzini         return s->clksel[4];
1238dd285b06SPaolo Bonzini     case 0x450:	/* RM_RSTCTRL_WKUP */
1239dd285b06SPaolo Bonzini         return 0;
1240dd285b06SPaolo Bonzini     case 0x454:	/* RM_RSTTIME_WKUP */
1241dd285b06SPaolo Bonzini         return s->rsttime_wkup;
1242dd285b06SPaolo Bonzini     case 0x458:	/* RM_RSTST_WKUP */
1243dd285b06SPaolo Bonzini         return s->rst[2];
1244dd285b06SPaolo Bonzini     case 0x4a0:	/* PM_WKEN_WKUP */
1245dd285b06SPaolo Bonzini         return s->wken[2];
1246dd285b06SPaolo Bonzini     case 0x4b0:	/* PM_WKST_WKUP */
1247dd285b06SPaolo Bonzini         return s->wkst[2];
1248dd285b06SPaolo Bonzini 
1249dd285b06SPaolo Bonzini     case 0x500:	/* CM_CLKEN_PLL */
1250dd285b06SPaolo Bonzini         return s->clken[9];
1251dd285b06SPaolo Bonzini     case 0x520:	/* CM_IDLEST_CKGEN */
1252dd285b06SPaolo Bonzini         ret = 0x0000070 | (s->apll_lock[0] << 9) | (s->apll_lock[1] << 8);
1253dd285b06SPaolo Bonzini         if (!(s->clksel[6] & 3))
1254dd285b06SPaolo Bonzini             /* Core uses 32-kHz clock */
1255dd285b06SPaolo Bonzini             ret |= 3 << 0;
1256dd285b06SPaolo Bonzini         else if (!s->dpll_lock)
1257dd285b06SPaolo Bonzini             /* DPLL not locked, core uses ref_clk */
1258dd285b06SPaolo Bonzini             ret |= 1 << 0;
1259dd285b06SPaolo Bonzini         else
1260dd285b06SPaolo Bonzini             /* Core uses DPLL */
1261dd285b06SPaolo Bonzini             ret |= 2 << 0;
1262dd285b06SPaolo Bonzini         return ret;
1263dd285b06SPaolo Bonzini     case 0x530:	/* CM_AUTOIDLE_PLL */
1264dd285b06SPaolo Bonzini         return s->clkidle[5];
1265dd285b06SPaolo Bonzini     case 0x540:	/* CM_CLKSEL1_PLL */
1266dd285b06SPaolo Bonzini         return s->clksel[5];
1267dd285b06SPaolo Bonzini     case 0x544:	/* CM_CLKSEL2_PLL */
1268dd285b06SPaolo Bonzini         return s->clksel[6];
1269dd285b06SPaolo Bonzini 
1270dd285b06SPaolo Bonzini     case 0x800:	/* CM_FCLKEN_DSP */
1271dd285b06SPaolo Bonzini         return s->clken[10];
1272dd285b06SPaolo Bonzini     case 0x810:	/* CM_ICLKEN_DSP */
1273dd285b06SPaolo Bonzini         return s->clken[11];
1274dd285b06SPaolo Bonzini     case 0x820:	/* CM_IDLEST_DSP */
1275dd285b06SPaolo Bonzini         /* TODO: check the actual iclk status */
1276dd285b06SPaolo Bonzini         return 0x00000103;
1277dd285b06SPaolo Bonzini     case 0x830:	/* CM_AUTOIDLE_DSP */
1278dd285b06SPaolo Bonzini         return s->clkidle[6];
1279dd285b06SPaolo Bonzini     case 0x840:	/* CM_CLKSEL_DSP */
1280dd285b06SPaolo Bonzini         return s->clksel[7];
1281dd285b06SPaolo Bonzini     case 0x848:	/* CM_CLKSTCTRL_DSP */
1282dd285b06SPaolo Bonzini         return s->clkctrl[3];
1283dd285b06SPaolo Bonzini     case 0x850:	/* RM_RSTCTRL_DSP */
1284dd285b06SPaolo Bonzini         return 0;
1285dd285b06SPaolo Bonzini     case 0x858:	/* RM_RSTST_DSP */
1286dd285b06SPaolo Bonzini         return s->rst[3];
1287dd285b06SPaolo Bonzini     case 0x8c8:	/* PM_WKDEP_DSP */
1288dd285b06SPaolo Bonzini         return s->wkup[2];
1289dd285b06SPaolo Bonzini     case 0x8e0:	/* PM_PWSTCTRL_DSP */
1290dd285b06SPaolo Bonzini         return s->power[3];
1291dd285b06SPaolo Bonzini     case 0x8e4:	/* PM_PWSTST_DSP */
1292dd285b06SPaolo Bonzini         return 0x008030 | (s->power[3] & 0x3003);
1293dd285b06SPaolo Bonzini 
1294dd285b06SPaolo Bonzini     case 0x8f0:	/* PRCM_IRQSTATUS_DSP */
1295dd285b06SPaolo Bonzini         return s->irqst[1];
1296dd285b06SPaolo Bonzini     case 0x8f4:	/* PRCM_IRQENABLE_DSP */
1297dd285b06SPaolo Bonzini         return s->irqen[1];
1298dd285b06SPaolo Bonzini 
1299dd285b06SPaolo Bonzini     case 0x8f8:	/* PRCM_IRQSTATUS_IVA */
1300dd285b06SPaolo Bonzini         return s->irqst[2];
1301dd285b06SPaolo Bonzini     case 0x8fc:	/* PRCM_IRQENABLE_IVA */
1302dd285b06SPaolo Bonzini         return s->irqen[2];
1303dd285b06SPaolo Bonzini     }
1304dd285b06SPaolo Bonzini 
1305dd285b06SPaolo Bonzini     OMAP_BAD_REG(addr);
1306dd285b06SPaolo Bonzini     return 0;
1307dd285b06SPaolo Bonzini }
1308dd285b06SPaolo Bonzini 
omap_prcm_apll_update(struct omap_prcm_s * s)1309dd285b06SPaolo Bonzini static void omap_prcm_apll_update(struct omap_prcm_s *s)
1310dd285b06SPaolo Bonzini {
1311dd285b06SPaolo Bonzini     int mode[2];
1312dd285b06SPaolo Bonzini 
1313dd285b06SPaolo Bonzini     mode[0] = (s->clken[9] >> 6) & 3;
1314dd285b06SPaolo Bonzini     s->apll_lock[0] = (mode[0] == 3);
1315dd285b06SPaolo Bonzini     mode[1] = (s->clken[9] >> 2) & 3;
1316dd285b06SPaolo Bonzini     s->apll_lock[1] = (mode[1] == 3);
1317dd285b06SPaolo Bonzini     /* TODO: update clocks */
1318dd285b06SPaolo Bonzini 
1319dd285b06SPaolo Bonzini     if (mode[0] == 1 || mode[0] == 2 || mode[1] == 1 || mode[1] == 2)
1320dd285b06SPaolo Bonzini         fprintf(stderr, "%s: bad EN_54M_PLL or bad EN_96M_PLL\n",
1321a89f364aSAlistair Francis                         __func__);
1322dd285b06SPaolo Bonzini }
1323dd285b06SPaolo Bonzini 
omap_prcm_dpll_update(struct omap_prcm_s * s)1324dd285b06SPaolo Bonzini static void omap_prcm_dpll_update(struct omap_prcm_s *s)
1325dd285b06SPaolo Bonzini {
1326dd285b06SPaolo Bonzini     omap_clk dpll = omap_findclk(s->mpu, "dpll");
1327dd285b06SPaolo Bonzini     omap_clk dpll_x2 = omap_findclk(s->mpu, "dpll");
1328dd285b06SPaolo Bonzini     omap_clk core = omap_findclk(s->mpu, "core_clk");
1329dd285b06SPaolo Bonzini     int mode = (s->clken[9] >> 0) & 3;
1330dd285b06SPaolo Bonzini     int mult, div;
1331dd285b06SPaolo Bonzini 
1332dd285b06SPaolo Bonzini     mult = (s->clksel[5] >> 12) & 0x3ff;
1333dd285b06SPaolo Bonzini     div = (s->clksel[5] >> 8) & 0xf;
1334dd285b06SPaolo Bonzini     if (mult == 0 || mult == 1)
1335dd285b06SPaolo Bonzini         mode = 1;	/* Bypass */
1336dd285b06SPaolo Bonzini 
1337dd285b06SPaolo Bonzini     s->dpll_lock = 0;
1338dd285b06SPaolo Bonzini     switch (mode) {
1339dd285b06SPaolo Bonzini     case 0:
1340a89f364aSAlistair Francis         fprintf(stderr, "%s: bad EN_DPLL\n", __func__);
1341dd285b06SPaolo Bonzini         break;
1342dd285b06SPaolo Bonzini     case 1:	/* Low-power bypass mode (Default) */
1343dd285b06SPaolo Bonzini     case 2:	/* Fast-relock bypass mode */
1344dd285b06SPaolo Bonzini         omap_clk_setrate(dpll, 1, 1);
1345dd285b06SPaolo Bonzini         omap_clk_setrate(dpll_x2, 1, 1);
1346dd285b06SPaolo Bonzini         break;
1347dd285b06SPaolo Bonzini     case 3:	/* Lock mode */
1348dd285b06SPaolo Bonzini         s->dpll_lock = 1; /* After 20 FINT cycles (ref_clk / (div + 1)).  */
1349dd285b06SPaolo Bonzini 
1350dd285b06SPaolo Bonzini         omap_clk_setrate(dpll, div + 1, mult);
1351dd285b06SPaolo Bonzini         omap_clk_setrate(dpll_x2, div + 1, mult * 2);
1352dd285b06SPaolo Bonzini         break;
1353dd285b06SPaolo Bonzini     }
1354dd285b06SPaolo Bonzini 
1355dd285b06SPaolo Bonzini     switch ((s->clksel[6] >> 0) & 3) {
1356dd285b06SPaolo Bonzini     case 0:
1357dd285b06SPaolo Bonzini         omap_clk_reparent(core, omap_findclk(s->mpu, "clk32-kHz"));
1358dd285b06SPaolo Bonzini         break;
1359dd285b06SPaolo Bonzini     case 1:
1360dd285b06SPaolo Bonzini         omap_clk_reparent(core, dpll);
1361dd285b06SPaolo Bonzini         break;
1362dd285b06SPaolo Bonzini     case 2:
1363dd285b06SPaolo Bonzini         /* Default */
1364dd285b06SPaolo Bonzini         omap_clk_reparent(core, dpll_x2);
1365dd285b06SPaolo Bonzini         break;
1366dd285b06SPaolo Bonzini     case 3:
1367a89f364aSAlistair Francis         fprintf(stderr, "%s: bad CORE_CLK_SRC\n", __func__);
1368dd285b06SPaolo Bonzini         break;
1369dd285b06SPaolo Bonzini     }
1370dd285b06SPaolo Bonzini }
1371dd285b06SPaolo Bonzini 
omap_prcm_write(void * opaque,hwaddr addr,uint64_t value,unsigned size)1372dd285b06SPaolo Bonzini static void omap_prcm_write(void *opaque, hwaddr addr,
1373dd285b06SPaolo Bonzini                             uint64_t value, unsigned size)
1374dd285b06SPaolo Bonzini {
1375a75ed3c4SPhilippe Mathieu-Daudé     struct omap_prcm_s *s = opaque;
1376dd285b06SPaolo Bonzini 
1377dd285b06SPaolo Bonzini     if (size != 4) {
137877a8257eSStefan Weil         omap_badwidth_write32(opaque, addr, value);
137977a8257eSStefan Weil         return;
1380dd285b06SPaolo Bonzini     }
1381dd285b06SPaolo Bonzini 
1382dd285b06SPaolo Bonzini     switch (addr) {
1383dd285b06SPaolo Bonzini     case 0x000:	/* PRCM_REVISION */
1384dd285b06SPaolo Bonzini     case 0x054:	/* PRCM_VOLTST */
1385dd285b06SPaolo Bonzini     case 0x084:	/* PRCM_CLKCFG_STATUS */
1386dd285b06SPaolo Bonzini     case 0x1e4:	/* PM_PWSTST_MPU */
1387dd285b06SPaolo Bonzini     case 0x220:	/* CM_IDLEST1_CORE */
1388dd285b06SPaolo Bonzini     case 0x224:	/* CM_IDLEST2_CORE */
1389dd285b06SPaolo Bonzini     case 0x22c:	/* CM_IDLEST4_CORE */
1390dd285b06SPaolo Bonzini     case 0x2c8:	/* PM_WKDEP_CORE */
1391dd285b06SPaolo Bonzini     case 0x2e4:	/* PM_PWSTST_CORE */
1392dd285b06SPaolo Bonzini     case 0x320:	/* CM_IDLEST_GFX */
1393dd285b06SPaolo Bonzini     case 0x3e4:	/* PM_PWSTST_GFX */
1394dd285b06SPaolo Bonzini     case 0x420:	/* CM_IDLEST_WKUP */
1395dd285b06SPaolo Bonzini     case 0x520:	/* CM_IDLEST_CKGEN */
1396dd285b06SPaolo Bonzini     case 0x820:	/* CM_IDLEST_DSP */
1397dd285b06SPaolo Bonzini     case 0x8e4:	/* PM_PWSTST_DSP */
1398dd285b06SPaolo Bonzini         OMAP_RO_REG(addr);
1399dd285b06SPaolo Bonzini         return;
1400dd285b06SPaolo Bonzini 
1401dd285b06SPaolo Bonzini     case 0x010:	/* PRCM_SYSCONFIG */
1402dd285b06SPaolo Bonzini         s->sysconfig = value & 1;
1403dd285b06SPaolo Bonzini         break;
1404dd285b06SPaolo Bonzini 
1405dd285b06SPaolo Bonzini     case 0x018:	/* PRCM_IRQSTATUS_MPU */
1406dd285b06SPaolo Bonzini         s->irqst[0] &= ~value;
1407dd285b06SPaolo Bonzini         omap_prcm_int_update(s, 0);
1408dd285b06SPaolo Bonzini         break;
1409dd285b06SPaolo Bonzini     case 0x01c:	/* PRCM_IRQENABLE_MPU */
1410dd285b06SPaolo Bonzini         s->irqen[0] = value & 0x3f;
1411dd285b06SPaolo Bonzini         omap_prcm_int_update(s, 0);
1412dd285b06SPaolo Bonzini         break;
1413dd285b06SPaolo Bonzini 
1414dd285b06SPaolo Bonzini     case 0x050:	/* PRCM_VOLTCTRL */
1415dd285b06SPaolo Bonzini         s->voltctrl = value & 0xf1c3;
1416dd285b06SPaolo Bonzini         break;
1417dd285b06SPaolo Bonzini 
1418dd285b06SPaolo Bonzini     case 0x060:	/* PRCM_CLKSRC_CTRL */
1419dd285b06SPaolo Bonzini         s->clksrc[0] = value & 0xdb;
1420dd285b06SPaolo Bonzini         /* TODO update clocks */
1421dd285b06SPaolo Bonzini         break;
1422dd285b06SPaolo Bonzini 
1423dd285b06SPaolo Bonzini     case 0x070:	/* PRCM_CLKOUT_CTRL */
1424dd285b06SPaolo Bonzini         s->clkout[0] = value & 0xbbbb;
1425dd285b06SPaolo Bonzini         /* TODO update clocks */
1426dd285b06SPaolo Bonzini         break;
1427dd285b06SPaolo Bonzini 
1428dd285b06SPaolo Bonzini     case 0x078:	/* PRCM_CLKEMUL_CTRL */
1429dd285b06SPaolo Bonzini         s->clkemul[0] = value & 1;
1430dd285b06SPaolo Bonzini         /* TODO update clocks */
1431dd285b06SPaolo Bonzini         break;
1432dd285b06SPaolo Bonzini 
1433dd285b06SPaolo Bonzini     case 0x080:	/* PRCM_CLKCFG_CTRL */
1434dd285b06SPaolo Bonzini         break;
1435dd285b06SPaolo Bonzini 
1436dd285b06SPaolo Bonzini     case 0x090:	/* PRCM_VOLTSETUP */
1437dd285b06SPaolo Bonzini         s->setuptime[0] = value & 0xffff;
1438dd285b06SPaolo Bonzini         break;
1439dd285b06SPaolo Bonzini     case 0x094:	/* PRCM_CLKSSETUP */
1440dd285b06SPaolo Bonzini         s->setuptime[1] = value & 0xffff;
1441dd285b06SPaolo Bonzini         break;
1442dd285b06SPaolo Bonzini 
1443dd285b06SPaolo Bonzini     case 0x098:	/* PRCM_POLCTRL */
1444dd285b06SPaolo Bonzini         s->clkpol[0] = value & 0x701;
1445dd285b06SPaolo Bonzini         break;
1446dd285b06SPaolo Bonzini 
1447dd285b06SPaolo Bonzini     case 0x0b0:	/* GENERAL_PURPOSE1 */
1448dd285b06SPaolo Bonzini     case 0x0b4:	/* GENERAL_PURPOSE2 */
1449dd285b06SPaolo Bonzini     case 0x0b8:	/* GENERAL_PURPOSE3 */
1450dd285b06SPaolo Bonzini     case 0x0bc:	/* GENERAL_PURPOSE4 */
1451dd285b06SPaolo Bonzini     case 0x0c0:	/* GENERAL_PURPOSE5 */
1452dd285b06SPaolo Bonzini     case 0x0c4:	/* GENERAL_PURPOSE6 */
1453dd285b06SPaolo Bonzini     case 0x0c8:	/* GENERAL_PURPOSE7 */
1454dd285b06SPaolo Bonzini     case 0x0cc:	/* GENERAL_PURPOSE8 */
1455dd285b06SPaolo Bonzini     case 0x0d0:	/* GENERAL_PURPOSE9 */
1456dd285b06SPaolo Bonzini     case 0x0d4:	/* GENERAL_PURPOSE10 */
1457dd285b06SPaolo Bonzini     case 0x0d8:	/* GENERAL_PURPOSE11 */
1458dd285b06SPaolo Bonzini     case 0x0dc:	/* GENERAL_PURPOSE12 */
1459dd285b06SPaolo Bonzini     case 0x0e0:	/* GENERAL_PURPOSE13 */
1460dd285b06SPaolo Bonzini     case 0x0e4:	/* GENERAL_PURPOSE14 */
1461dd285b06SPaolo Bonzini     case 0x0e8:	/* GENERAL_PURPOSE15 */
1462dd285b06SPaolo Bonzini     case 0x0ec:	/* GENERAL_PURPOSE16 */
1463dd285b06SPaolo Bonzini     case 0x0f0:	/* GENERAL_PURPOSE17 */
1464dd285b06SPaolo Bonzini     case 0x0f4:	/* GENERAL_PURPOSE18 */
1465dd285b06SPaolo Bonzini     case 0x0f8:	/* GENERAL_PURPOSE19 */
1466dd285b06SPaolo Bonzini     case 0x0fc:	/* GENERAL_PURPOSE20 */
1467dd285b06SPaolo Bonzini         s->scratch[(addr - 0xb0) >> 2] = value;
1468dd285b06SPaolo Bonzini         break;
1469dd285b06SPaolo Bonzini 
1470dd285b06SPaolo Bonzini     case 0x140:	/* CM_CLKSEL_MPU */
1471dd285b06SPaolo Bonzini         s->clksel[0] = value & 0x1f;
1472dd285b06SPaolo Bonzini         /* TODO update clocks */
1473dd285b06SPaolo Bonzini         break;
1474dd285b06SPaolo Bonzini     case 0x148:	/* CM_CLKSTCTRL_MPU */
1475dd285b06SPaolo Bonzini         s->clkctrl[0] = value & 0x1f;
1476dd285b06SPaolo Bonzini         break;
1477dd285b06SPaolo Bonzini 
1478dd285b06SPaolo Bonzini     case 0x158:	/* RM_RSTST_MPU */
1479dd285b06SPaolo Bonzini         s->rst[0] &= ~value;
1480dd285b06SPaolo Bonzini         break;
1481dd285b06SPaolo Bonzini     case 0x1c8:	/* PM_WKDEP_MPU */
1482dd285b06SPaolo Bonzini         s->wkup[0] = value & 0x15;
1483dd285b06SPaolo Bonzini         break;
1484dd285b06SPaolo Bonzini 
1485dd285b06SPaolo Bonzini     case 0x1d4:	/* PM_EVGENCTRL_MPU */
1486dd285b06SPaolo Bonzini         s->ev = value & 0x1f;
1487dd285b06SPaolo Bonzini         break;
1488dd285b06SPaolo Bonzini     case 0x1d8:	/* PM_EVEGENONTIM_MPU */
1489dd285b06SPaolo Bonzini         s->evtime[0] = value;
1490dd285b06SPaolo Bonzini         break;
1491dd285b06SPaolo Bonzini     case 0x1dc:	/* PM_EVEGENOFFTIM_MPU */
1492dd285b06SPaolo Bonzini         s->evtime[1] = value;
1493dd285b06SPaolo Bonzini         break;
1494dd285b06SPaolo Bonzini 
1495dd285b06SPaolo Bonzini     case 0x1e0:	/* PM_PWSTCTRL_MPU */
1496dd285b06SPaolo Bonzini         s->power[0] = value & 0xc0f;
1497dd285b06SPaolo Bonzini         break;
1498dd285b06SPaolo Bonzini 
1499dd285b06SPaolo Bonzini     case 0x200:	/* CM_FCLKEN1_CORE */
1500dd285b06SPaolo Bonzini         s->clken[0] = value & 0xbfffffff;
1501dd285b06SPaolo Bonzini         /* TODO update clocks */
1502dd285b06SPaolo Bonzini         /* The EN_EAC bit only gets/puts func_96m_clk.  */
1503dd285b06SPaolo Bonzini         break;
1504dd285b06SPaolo Bonzini     case 0x204:	/* CM_FCLKEN2_CORE */
1505dd285b06SPaolo Bonzini         s->clken[1] = value & 0x00000007;
1506dd285b06SPaolo Bonzini         /* TODO update clocks */
1507dd285b06SPaolo Bonzini         break;
1508dd285b06SPaolo Bonzini     case 0x210:	/* CM_ICLKEN1_CORE */
1509dd285b06SPaolo Bonzini         s->clken[2] = value & 0xfffffff9;
1510dd285b06SPaolo Bonzini         /* TODO update clocks */
1511dd285b06SPaolo Bonzini         /* The EN_EAC bit only gets/puts core_l4_iclk.  */
1512dd285b06SPaolo Bonzini         break;
1513dd285b06SPaolo Bonzini     case 0x214:	/* CM_ICLKEN2_CORE */
1514dd285b06SPaolo Bonzini         s->clken[3] = value & 0x00000007;
1515dd285b06SPaolo Bonzini         /* TODO update clocks */
1516dd285b06SPaolo Bonzini         break;
1517dd285b06SPaolo Bonzini     case 0x21c:	/* CM_ICLKEN4_CORE */
1518dd285b06SPaolo Bonzini         s->clken[4] = value & 0x0000001f;
1519dd285b06SPaolo Bonzini         /* TODO update clocks */
1520dd285b06SPaolo Bonzini         break;
1521dd285b06SPaolo Bonzini 
1522dd285b06SPaolo Bonzini     case 0x230:	/* CM_AUTOIDLE1_CORE */
1523dd285b06SPaolo Bonzini         s->clkidle[0] = value & 0xfffffff9;
1524dd285b06SPaolo Bonzini         /* TODO update clocks */
1525dd285b06SPaolo Bonzini         break;
1526dd285b06SPaolo Bonzini     case 0x234:	/* CM_AUTOIDLE2_CORE */
1527dd285b06SPaolo Bonzini         s->clkidle[1] = value & 0x00000007;
1528dd285b06SPaolo Bonzini         /* TODO update clocks */
1529dd285b06SPaolo Bonzini         break;
1530dd285b06SPaolo Bonzini     case 0x238:	/* CM_AUTOIDLE3_CORE */
1531dd285b06SPaolo Bonzini         s->clkidle[2] = value & 0x00000007;
1532dd285b06SPaolo Bonzini         /* TODO update clocks */
1533dd285b06SPaolo Bonzini         break;
1534dd285b06SPaolo Bonzini     case 0x23c:	/* CM_AUTOIDLE4_CORE */
1535dd285b06SPaolo Bonzini         s->clkidle[3] = value & 0x0000001f;
1536dd285b06SPaolo Bonzini         /* TODO update clocks */
1537dd285b06SPaolo Bonzini         break;
1538dd285b06SPaolo Bonzini 
1539dd285b06SPaolo Bonzini     case 0x240:	/* CM_CLKSEL1_CORE */
1540dd285b06SPaolo Bonzini         s->clksel[1] = value & 0x0fffbf7f;
1541dd285b06SPaolo Bonzini         /* TODO update clocks */
1542dd285b06SPaolo Bonzini         break;
1543dd285b06SPaolo Bonzini 
1544dd285b06SPaolo Bonzini     case 0x244:	/* CM_CLKSEL2_CORE */
1545dd285b06SPaolo Bonzini         s->clksel[2] = value & 0x00fffffc;
1546dd285b06SPaolo Bonzini         /* TODO update clocks */
1547dd285b06SPaolo Bonzini         break;
1548dd285b06SPaolo Bonzini 
1549dd285b06SPaolo Bonzini     case 0x248:	/* CM_CLKSTCTRL_CORE */
1550dd285b06SPaolo Bonzini         s->clkctrl[1] = value & 0x7;
1551dd285b06SPaolo Bonzini         break;
1552dd285b06SPaolo Bonzini 
1553dd285b06SPaolo Bonzini     case 0x2a0:	/* PM_WKEN1_CORE */
1554dd285b06SPaolo Bonzini         s->wken[0] = value & 0x04667ff8;
1555dd285b06SPaolo Bonzini         break;
1556dd285b06SPaolo Bonzini     case 0x2a4:	/* PM_WKEN2_CORE */
1557dd285b06SPaolo Bonzini         s->wken[1] = value & 0x00000005;
1558dd285b06SPaolo Bonzini         break;
1559dd285b06SPaolo Bonzini 
1560dd285b06SPaolo Bonzini     case 0x2b0:	/* PM_WKST1_CORE */
1561dd285b06SPaolo Bonzini         s->wkst[0] &= ~value;
1562dd285b06SPaolo Bonzini         break;
1563dd285b06SPaolo Bonzini     case 0x2b4:	/* PM_WKST2_CORE */
1564dd285b06SPaolo Bonzini         s->wkst[1] &= ~value;
1565dd285b06SPaolo Bonzini         break;
1566dd285b06SPaolo Bonzini 
1567dd285b06SPaolo Bonzini     case 0x2e0:	/* PM_PWSTCTRL_CORE */
1568dd285b06SPaolo Bonzini         s->power[1] = (value & 0x00fc3f) | (1 << 2);
1569dd285b06SPaolo Bonzini         break;
1570dd285b06SPaolo Bonzini 
1571dd285b06SPaolo Bonzini     case 0x300:	/* CM_FCLKEN_GFX */
1572dd285b06SPaolo Bonzini         s->clken[5] = value & 6;
1573dd285b06SPaolo Bonzini         /* TODO update clocks */
1574dd285b06SPaolo Bonzini         break;
1575dd285b06SPaolo Bonzini     case 0x310:	/* CM_ICLKEN_GFX */
1576dd285b06SPaolo Bonzini         s->clken[6] = value & 1;
1577dd285b06SPaolo Bonzini         /* TODO update clocks */
1578dd285b06SPaolo Bonzini         break;
1579dd285b06SPaolo Bonzini     case 0x340:	/* CM_CLKSEL_GFX */
1580dd285b06SPaolo Bonzini         s->clksel[3] = value & 7;
1581dd285b06SPaolo Bonzini         /* TODO update clocks */
1582dd285b06SPaolo Bonzini         break;
1583dd285b06SPaolo Bonzini     case 0x348:	/* CM_CLKSTCTRL_GFX */
1584dd285b06SPaolo Bonzini         s->clkctrl[2] = value & 1;
1585dd285b06SPaolo Bonzini         break;
1586dd285b06SPaolo Bonzini     case 0x350:	/* RM_RSTCTRL_GFX */
1587dd285b06SPaolo Bonzini         s->rstctrl[0] = value & 1;
1588dd285b06SPaolo Bonzini         /* TODO: reset */
1589dd285b06SPaolo Bonzini         break;
1590dd285b06SPaolo Bonzini     case 0x358:	/* RM_RSTST_GFX */
1591dd285b06SPaolo Bonzini         s->rst[1] &= ~value;
1592dd285b06SPaolo Bonzini         break;
1593dd285b06SPaolo Bonzini     case 0x3c8:	/* PM_WKDEP_GFX */
1594dd285b06SPaolo Bonzini         s->wkup[1] = value & 0x13;
1595dd285b06SPaolo Bonzini         break;
1596dd285b06SPaolo Bonzini     case 0x3e0:	/* PM_PWSTCTRL_GFX */
1597dd285b06SPaolo Bonzini         s->power[2] = (value & 0x00c0f) | (3 << 2);
1598dd285b06SPaolo Bonzini         break;
1599dd285b06SPaolo Bonzini 
1600dd285b06SPaolo Bonzini     case 0x400:	/* CM_FCLKEN_WKUP */
1601dd285b06SPaolo Bonzini         s->clken[7] = value & 0xd;
1602dd285b06SPaolo Bonzini         /* TODO update clocks */
1603dd285b06SPaolo Bonzini         break;
1604dd285b06SPaolo Bonzini     case 0x410:	/* CM_ICLKEN_WKUP */
1605dd285b06SPaolo Bonzini         s->clken[8] = value & 0x3f;
1606dd285b06SPaolo Bonzini         /* TODO update clocks */
1607dd285b06SPaolo Bonzini         break;
1608dd285b06SPaolo Bonzini     case 0x430:	/* CM_AUTOIDLE_WKUP */
1609dd285b06SPaolo Bonzini         s->clkidle[4] = value & 0x0000003f;
1610dd285b06SPaolo Bonzini         /* TODO update clocks */
1611dd285b06SPaolo Bonzini         break;
1612dd285b06SPaolo Bonzini     case 0x440:	/* CM_CLKSEL_WKUP */
1613dd285b06SPaolo Bonzini         s->clksel[4] = value & 3;
1614dd285b06SPaolo Bonzini         /* TODO update clocks */
1615dd285b06SPaolo Bonzini         break;
1616dd285b06SPaolo Bonzini     case 0x450:	/* RM_RSTCTRL_WKUP */
1617dd285b06SPaolo Bonzini         /* TODO: reset */
1618dd285b06SPaolo Bonzini         if (value & 2)
1619cf83f140SEric Blake             qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
1620dd285b06SPaolo Bonzini         break;
1621dd285b06SPaolo Bonzini     case 0x454:	/* RM_RSTTIME_WKUP */
1622dd285b06SPaolo Bonzini         s->rsttime_wkup = value & 0x1fff;
1623dd285b06SPaolo Bonzini         break;
1624dd285b06SPaolo Bonzini     case 0x458:	/* RM_RSTST_WKUP */
1625dd285b06SPaolo Bonzini         s->rst[2] &= ~value;
1626dd285b06SPaolo Bonzini         break;
1627dd285b06SPaolo Bonzini     case 0x4a0:	/* PM_WKEN_WKUP */
1628dd285b06SPaolo Bonzini         s->wken[2] = value & 0x00000005;
1629dd285b06SPaolo Bonzini         break;
1630dd285b06SPaolo Bonzini     case 0x4b0:	/* PM_WKST_WKUP */
1631dd285b06SPaolo Bonzini         s->wkst[2] &= ~value;
1632dd285b06SPaolo Bonzini         break;
1633dd285b06SPaolo Bonzini 
1634dd285b06SPaolo Bonzini     case 0x500:	/* CM_CLKEN_PLL */
1635dd285b06SPaolo Bonzini         if (value & 0xffffff30)
1636dd285b06SPaolo Bonzini             fprintf(stderr, "%s: write 0s in CM_CLKEN_PLL for "
1637a89f364aSAlistair Francis                             "future compatibility\n", __func__);
1638dd285b06SPaolo Bonzini         if ((s->clken[9] ^ value) & 0xcc) {
1639dd285b06SPaolo Bonzini             s->clken[9] &= ~0xcc;
1640dd285b06SPaolo Bonzini             s->clken[9] |= value & 0xcc;
1641dd285b06SPaolo Bonzini             omap_prcm_apll_update(s);
1642dd285b06SPaolo Bonzini         }
1643dd285b06SPaolo Bonzini         if ((s->clken[9] ^ value) & 3) {
1644dd285b06SPaolo Bonzini             s->clken[9] &= ~3;
1645dd285b06SPaolo Bonzini             s->clken[9] |= value & 3;
1646dd285b06SPaolo Bonzini             omap_prcm_dpll_update(s);
1647dd285b06SPaolo Bonzini         }
1648dd285b06SPaolo Bonzini         break;
1649dd285b06SPaolo Bonzini     case 0x530:	/* CM_AUTOIDLE_PLL */
1650dd285b06SPaolo Bonzini         s->clkidle[5] = value & 0x000000cf;
1651dd285b06SPaolo Bonzini         /* TODO update clocks */
1652dd285b06SPaolo Bonzini         break;
1653dd285b06SPaolo Bonzini     case 0x540:	/* CM_CLKSEL1_PLL */
1654dd285b06SPaolo Bonzini         if (value & 0xfc4000d7)
1655dd285b06SPaolo Bonzini             fprintf(stderr, "%s: write 0s in CM_CLKSEL1_PLL for "
1656a89f364aSAlistair Francis                             "future compatibility\n", __func__);
1657dd285b06SPaolo Bonzini         if ((s->clksel[5] ^ value) & 0x003fff00) {
1658dd285b06SPaolo Bonzini             s->clksel[5] = value & 0x03bfff28;
1659dd285b06SPaolo Bonzini             omap_prcm_dpll_update(s);
1660dd285b06SPaolo Bonzini         }
1661dd285b06SPaolo Bonzini         /* TODO update the other clocks */
1662dd285b06SPaolo Bonzini 
1663dd285b06SPaolo Bonzini         s->clksel[5] = value & 0x03bfff28;
1664dd285b06SPaolo Bonzini         break;
1665dd285b06SPaolo Bonzini     case 0x544:	/* CM_CLKSEL2_PLL */
1666dd285b06SPaolo Bonzini         if (value & ~3)
1667dd285b06SPaolo Bonzini             fprintf(stderr, "%s: write 0s in CM_CLKSEL2_PLL[31:2] for "
1668a89f364aSAlistair Francis                             "future compatibility\n", __func__);
1669dd285b06SPaolo Bonzini         if (s->clksel[6] != (value & 3)) {
1670dd285b06SPaolo Bonzini             s->clksel[6] = value & 3;
1671dd285b06SPaolo Bonzini             omap_prcm_dpll_update(s);
1672dd285b06SPaolo Bonzini         }
1673dd285b06SPaolo Bonzini         break;
1674dd285b06SPaolo Bonzini 
1675dd285b06SPaolo Bonzini     case 0x800:	/* CM_FCLKEN_DSP */
1676dd285b06SPaolo Bonzini         s->clken[10] = value & 0x501;
1677dd285b06SPaolo Bonzini         /* TODO update clocks */
1678dd285b06SPaolo Bonzini         break;
1679dd285b06SPaolo Bonzini     case 0x810:	/* CM_ICLKEN_DSP */
1680dd285b06SPaolo Bonzini         s->clken[11] = value & 0x2;
1681dd285b06SPaolo Bonzini         /* TODO update clocks */
1682dd285b06SPaolo Bonzini         break;
1683dd285b06SPaolo Bonzini     case 0x830:	/* CM_AUTOIDLE_DSP */
1684dd285b06SPaolo Bonzini         s->clkidle[6] = value & 0x2;
1685dd285b06SPaolo Bonzini         /* TODO update clocks */
1686dd285b06SPaolo Bonzini         break;
1687dd285b06SPaolo Bonzini     case 0x840:	/* CM_CLKSEL_DSP */
1688dd285b06SPaolo Bonzini         s->clksel[7] = value & 0x3fff;
1689dd285b06SPaolo Bonzini         /* TODO update clocks */
1690dd285b06SPaolo Bonzini         break;
1691dd285b06SPaolo Bonzini     case 0x848:	/* CM_CLKSTCTRL_DSP */
1692dd285b06SPaolo Bonzini         s->clkctrl[3] = value & 0x101;
1693dd285b06SPaolo Bonzini         break;
1694dd285b06SPaolo Bonzini     case 0x850:	/* RM_RSTCTRL_DSP */
1695dd285b06SPaolo Bonzini         /* TODO: reset */
1696dd285b06SPaolo Bonzini         break;
1697dd285b06SPaolo Bonzini     case 0x858:	/* RM_RSTST_DSP */
1698dd285b06SPaolo Bonzini         s->rst[3] &= ~value;
1699dd285b06SPaolo Bonzini         break;
1700dd285b06SPaolo Bonzini     case 0x8c8:	/* PM_WKDEP_DSP */
1701dd285b06SPaolo Bonzini         s->wkup[2] = value & 0x13;
1702dd285b06SPaolo Bonzini         break;
1703dd285b06SPaolo Bonzini     case 0x8e0:	/* PM_PWSTCTRL_DSP */
1704dd285b06SPaolo Bonzini         s->power[3] = (value & 0x03017) | (3 << 2);
1705dd285b06SPaolo Bonzini         break;
1706dd285b06SPaolo Bonzini 
1707dd285b06SPaolo Bonzini     case 0x8f0:	/* PRCM_IRQSTATUS_DSP */
1708dd285b06SPaolo Bonzini         s->irqst[1] &= ~value;
1709dd285b06SPaolo Bonzini         omap_prcm_int_update(s, 1);
1710dd285b06SPaolo Bonzini         break;
1711dd285b06SPaolo Bonzini     case 0x8f4:	/* PRCM_IRQENABLE_DSP */
1712dd285b06SPaolo Bonzini         s->irqen[1] = value & 0x7;
1713dd285b06SPaolo Bonzini         omap_prcm_int_update(s, 1);
1714dd285b06SPaolo Bonzini         break;
1715dd285b06SPaolo Bonzini 
1716dd285b06SPaolo Bonzini     case 0x8f8:	/* PRCM_IRQSTATUS_IVA */
1717dd285b06SPaolo Bonzini         s->irqst[2] &= ~value;
1718dd285b06SPaolo Bonzini         omap_prcm_int_update(s, 2);
1719dd285b06SPaolo Bonzini         break;
1720dd285b06SPaolo Bonzini     case 0x8fc:	/* PRCM_IRQENABLE_IVA */
1721dd285b06SPaolo Bonzini         s->irqen[2] = value & 0x7;
1722dd285b06SPaolo Bonzini         omap_prcm_int_update(s, 2);
1723dd285b06SPaolo Bonzini         break;
1724dd285b06SPaolo Bonzini 
1725dd285b06SPaolo Bonzini     default:
1726dd285b06SPaolo Bonzini         OMAP_BAD_REG(addr);
1727dd285b06SPaolo Bonzini         return;
1728dd285b06SPaolo Bonzini     }
1729dd285b06SPaolo Bonzini }
1730dd285b06SPaolo Bonzini 
1731dd285b06SPaolo Bonzini static const MemoryRegionOps omap_prcm_ops = {
1732dd285b06SPaolo Bonzini     .read = omap_prcm_read,
1733dd285b06SPaolo Bonzini     .write = omap_prcm_write,
1734dd285b06SPaolo Bonzini     .endianness = DEVICE_NATIVE_ENDIAN,
1735dd285b06SPaolo Bonzini };
1736dd285b06SPaolo Bonzini 
omap_prcm_reset(struct omap_prcm_s * s)1737dd285b06SPaolo Bonzini static void omap_prcm_reset(struct omap_prcm_s *s)
1738dd285b06SPaolo Bonzini {
1739dd285b06SPaolo Bonzini     s->sysconfig = 0;
1740dd285b06SPaolo Bonzini     s->irqst[0] = 0;
1741dd285b06SPaolo Bonzini     s->irqst[1] = 0;
1742dd285b06SPaolo Bonzini     s->irqst[2] = 0;
1743dd285b06SPaolo Bonzini     s->irqen[0] = 0;
1744dd285b06SPaolo Bonzini     s->irqen[1] = 0;
1745dd285b06SPaolo Bonzini     s->irqen[2] = 0;
1746dd285b06SPaolo Bonzini     s->voltctrl = 0x1040;
1747dd285b06SPaolo Bonzini     s->ev = 0x14;
1748dd285b06SPaolo Bonzini     s->evtime[0] = 0;
1749dd285b06SPaolo Bonzini     s->evtime[1] = 0;
1750dd285b06SPaolo Bonzini     s->clkctrl[0] = 0;
1751dd285b06SPaolo Bonzini     s->clkctrl[1] = 0;
1752dd285b06SPaolo Bonzini     s->clkctrl[2] = 0;
1753dd285b06SPaolo Bonzini     s->clkctrl[3] = 0;
1754dd285b06SPaolo Bonzini     s->clken[1] = 7;
1755dd285b06SPaolo Bonzini     s->clken[3] = 7;
1756dd285b06SPaolo Bonzini     s->clken[4] = 0;
1757dd285b06SPaolo Bonzini     s->clken[5] = 0;
1758dd285b06SPaolo Bonzini     s->clken[6] = 0;
1759dd285b06SPaolo Bonzini     s->clken[7] = 0xc;
1760dd285b06SPaolo Bonzini     s->clken[8] = 0x3e;
1761dd285b06SPaolo Bonzini     s->clken[9] = 0x0d;
1762dd285b06SPaolo Bonzini     s->clken[10] = 0;
1763dd285b06SPaolo Bonzini     s->clken[11] = 0;
1764dd285b06SPaolo Bonzini     s->clkidle[0] = 0;
1765dd285b06SPaolo Bonzini     s->clkidle[2] = 7;
1766dd285b06SPaolo Bonzini     s->clkidle[3] = 0;
1767dd285b06SPaolo Bonzini     s->clkidle[4] = 0;
1768dd285b06SPaolo Bonzini     s->clkidle[5] = 0x0c;
1769dd285b06SPaolo Bonzini     s->clkidle[6] = 0;
1770dd285b06SPaolo Bonzini     s->clksel[0] = 0x01;
1771dd285b06SPaolo Bonzini     s->clksel[1] = 0x02100121;
1772dd285b06SPaolo Bonzini     s->clksel[2] = 0x00000000;
1773dd285b06SPaolo Bonzini     s->clksel[3] = 0x01;
1774dd285b06SPaolo Bonzini     s->clksel[4] = 0;
1775dd285b06SPaolo Bonzini     s->clksel[7] = 0x0121;
1776dd285b06SPaolo Bonzini     s->wkup[0] = 0x15;
1777dd285b06SPaolo Bonzini     s->wkup[1] = 0x13;
1778dd285b06SPaolo Bonzini     s->wkup[2] = 0x13;
1779dd285b06SPaolo Bonzini     s->wken[0] = 0x04667ff8;
1780dd285b06SPaolo Bonzini     s->wken[1] = 0x00000005;
1781dd285b06SPaolo Bonzini     s->wken[2] = 5;
1782dd285b06SPaolo Bonzini     s->wkst[0] = 0;
1783dd285b06SPaolo Bonzini     s->wkst[1] = 0;
1784dd285b06SPaolo Bonzini     s->wkst[2] = 0;
1785dd285b06SPaolo Bonzini     s->power[0] = 0x00c;
1786dd285b06SPaolo Bonzini     s->power[1] = 4;
1787dd285b06SPaolo Bonzini     s->power[2] = 0x0000c;
1788dd285b06SPaolo Bonzini     s->power[3] = 0x14;
1789dd285b06SPaolo Bonzini     s->rstctrl[0] = 1;
1790dd285b06SPaolo Bonzini     s->rst[3] = 1;
1791dd285b06SPaolo Bonzini     omap_prcm_apll_update(s);
1792dd285b06SPaolo Bonzini     omap_prcm_dpll_update(s);
1793dd285b06SPaolo Bonzini }
1794dd285b06SPaolo Bonzini 
omap_prcm_coldreset(struct omap_prcm_s * s)1795dd285b06SPaolo Bonzini static void omap_prcm_coldreset(struct omap_prcm_s *s)
1796dd285b06SPaolo Bonzini {
1797dd285b06SPaolo Bonzini     s->setuptime[0] = 0;
1798dd285b06SPaolo Bonzini     s->setuptime[1] = 0;
1799dd285b06SPaolo Bonzini     memset(&s->scratch, 0, sizeof(s->scratch));
1800dd285b06SPaolo Bonzini     s->rst[0] = 0x01;
1801dd285b06SPaolo Bonzini     s->rst[1] = 0x00;
1802dd285b06SPaolo Bonzini     s->rst[2] = 0x01;
1803dd285b06SPaolo Bonzini     s->clken[0] = 0;
1804dd285b06SPaolo Bonzini     s->clken[2] = 0;
1805dd285b06SPaolo Bonzini     s->clkidle[1] = 0;
1806dd285b06SPaolo Bonzini     s->clksel[5] = 0;
1807dd285b06SPaolo Bonzini     s->clksel[6] = 2;
1808dd285b06SPaolo Bonzini     s->clksrc[0] = 0x43;
1809dd285b06SPaolo Bonzini     s->clkout[0] = 0x0303;
1810dd285b06SPaolo Bonzini     s->clkemul[0] = 0;
1811dd285b06SPaolo Bonzini     s->clkpol[0] = 0x100;
1812dd285b06SPaolo Bonzini     s->rsttime_wkup = 0x1002;
1813dd285b06SPaolo Bonzini 
1814dd285b06SPaolo Bonzini     omap_prcm_reset(s);
1815dd285b06SPaolo Bonzini }
1816dd285b06SPaolo Bonzini 
omap_prcm_init(struct omap_target_agent_s * ta,qemu_irq mpu_int,qemu_irq dsp_int,qemu_irq iva_int,struct omap_mpu_state_s * mpu)1817dd285b06SPaolo Bonzini static struct omap_prcm_s *omap_prcm_init(struct omap_target_agent_s *ta,
1818dd285b06SPaolo Bonzini                 qemu_irq mpu_int, qemu_irq dsp_int, qemu_irq iva_int,
1819dd285b06SPaolo Bonzini                 struct omap_mpu_state_s *mpu)
1820dd285b06SPaolo Bonzini {
1821b45c03f5SMarkus Armbruster     struct omap_prcm_s *s = g_new0(struct omap_prcm_s, 1);
1822dd285b06SPaolo Bonzini 
1823dd285b06SPaolo Bonzini     s->irq[0] = mpu_int;
1824dd285b06SPaolo Bonzini     s->irq[1] = dsp_int;
1825dd285b06SPaolo Bonzini     s->irq[2] = iva_int;
1826dd285b06SPaolo Bonzini     s->mpu = mpu;
1827dd285b06SPaolo Bonzini     omap_prcm_coldreset(s);
1828dd285b06SPaolo Bonzini 
18292c9b15caSPaolo Bonzini     memory_region_init_io(&s->iomem0, NULL, &omap_prcm_ops, s, "omap.pcrm0",
1830dd285b06SPaolo Bonzini                           omap_l4_region_size(ta, 0));
18312c9b15caSPaolo Bonzini     memory_region_init_io(&s->iomem1, NULL, &omap_prcm_ops, s, "omap.pcrm1",
1832dd285b06SPaolo Bonzini                           omap_l4_region_size(ta, 1));
1833dd285b06SPaolo Bonzini     omap_l4_attach(ta, 0, &s->iomem0);
1834dd285b06SPaolo Bonzini     omap_l4_attach(ta, 1, &s->iomem1);
1835dd285b06SPaolo Bonzini 
1836dd285b06SPaolo Bonzini     return s;
1837dd285b06SPaolo Bonzini }
1838dd285b06SPaolo Bonzini 
1839dd285b06SPaolo Bonzini /* System and Pinout control */
1840dd285b06SPaolo Bonzini struct omap_sysctl_s {
1841dd285b06SPaolo Bonzini     struct omap_mpu_state_s *mpu;
1842dd285b06SPaolo Bonzini     MemoryRegion iomem;
1843dd285b06SPaolo Bonzini 
1844dd285b06SPaolo Bonzini     uint32_t sysconfig;
1845dd285b06SPaolo Bonzini     uint32_t devconfig;
1846dd285b06SPaolo Bonzini     uint32_t psaconfig;
1847dd285b06SPaolo Bonzini     uint32_t padconf[0x45];
1848dd285b06SPaolo Bonzini     uint8_t obs;
1849dd285b06SPaolo Bonzini     uint32_t msuspendmux[5];
1850dd285b06SPaolo Bonzini };
1851dd285b06SPaolo Bonzini 
omap_sysctl_read8(void * opaque,hwaddr addr)1852dd285b06SPaolo Bonzini static uint32_t omap_sysctl_read8(void *opaque, hwaddr addr)
1853dd285b06SPaolo Bonzini {
1854dd285b06SPaolo Bonzini 
1855a75ed3c4SPhilippe Mathieu-Daudé     struct omap_sysctl_s *s = opaque;
1856dd285b06SPaolo Bonzini     int pad_offset, byte_offset;
1857dd285b06SPaolo Bonzini     int value;
1858dd285b06SPaolo Bonzini 
1859dd285b06SPaolo Bonzini     switch (addr) {
1860dd285b06SPaolo Bonzini     case 0x030 ... 0x140:	/* CONTROL_PADCONF - only used in the POP */
1861dd285b06SPaolo Bonzini         pad_offset = (addr - 0x30) >> 2;
1862dd285b06SPaolo Bonzini         byte_offset = (addr - 0x30) & (4 - 1);
1863dd285b06SPaolo Bonzini 
1864dd285b06SPaolo Bonzini         value = s->padconf[pad_offset];
1865dd285b06SPaolo Bonzini         value = (value >> (byte_offset * 8)) & 0xff;
1866dd285b06SPaolo Bonzini 
1867dd285b06SPaolo Bonzini         return value;
1868dd285b06SPaolo Bonzini 
1869dd285b06SPaolo Bonzini     default:
1870dd285b06SPaolo Bonzini         break;
1871dd285b06SPaolo Bonzini     }
1872dd285b06SPaolo Bonzini 
1873dd285b06SPaolo Bonzini     OMAP_BAD_REG(addr);
1874dd285b06SPaolo Bonzini     return 0;
1875dd285b06SPaolo Bonzini }
1876dd285b06SPaolo Bonzini 
omap_sysctl_read(void * opaque,hwaddr addr)1877dd285b06SPaolo Bonzini static uint32_t omap_sysctl_read(void *opaque, hwaddr addr)
1878dd285b06SPaolo Bonzini {
1879a75ed3c4SPhilippe Mathieu-Daudé     struct omap_sysctl_s *s = opaque;
1880dd285b06SPaolo Bonzini 
1881dd285b06SPaolo Bonzini     switch (addr) {
1882dd285b06SPaolo Bonzini     case 0x000:	/* CONTROL_REVISION */
1883dd285b06SPaolo Bonzini         return 0x20;
1884dd285b06SPaolo Bonzini 
1885dd285b06SPaolo Bonzini     case 0x010:	/* CONTROL_SYSCONFIG */
1886dd285b06SPaolo Bonzini         return s->sysconfig;
1887dd285b06SPaolo Bonzini 
1888dd285b06SPaolo Bonzini     case 0x030 ... 0x140:	/* CONTROL_PADCONF - only used in the POP */
1889dd285b06SPaolo Bonzini         return s->padconf[(addr - 0x30) >> 2];
1890dd285b06SPaolo Bonzini 
1891dd285b06SPaolo Bonzini     case 0x270:	/* CONTROL_DEBOBS */
1892dd285b06SPaolo Bonzini         return s->obs;
1893dd285b06SPaolo Bonzini 
1894dd285b06SPaolo Bonzini     case 0x274:	/* CONTROL_DEVCONF */
1895dd285b06SPaolo Bonzini         return s->devconfig;
1896dd285b06SPaolo Bonzini 
1897dd285b06SPaolo Bonzini     case 0x28c:	/* CONTROL_EMU_SUPPORT */
1898dd285b06SPaolo Bonzini         return 0;
1899dd285b06SPaolo Bonzini 
1900dd285b06SPaolo Bonzini     case 0x290:	/* CONTROL_MSUSPENDMUX_0 */
1901dd285b06SPaolo Bonzini         return s->msuspendmux[0];
1902dd285b06SPaolo Bonzini     case 0x294:	/* CONTROL_MSUSPENDMUX_1 */
1903dd285b06SPaolo Bonzini         return s->msuspendmux[1];
1904dd285b06SPaolo Bonzini     case 0x298:	/* CONTROL_MSUSPENDMUX_2 */
1905dd285b06SPaolo Bonzini         return s->msuspendmux[2];
1906dd285b06SPaolo Bonzini     case 0x29c:	/* CONTROL_MSUSPENDMUX_3 */
1907dd285b06SPaolo Bonzini         return s->msuspendmux[3];
1908dd285b06SPaolo Bonzini     case 0x2a0:	/* CONTROL_MSUSPENDMUX_4 */
1909dd285b06SPaolo Bonzini         return s->msuspendmux[4];
1910dd285b06SPaolo Bonzini     case 0x2a4:	/* CONTROL_MSUSPENDMUX_5 */
1911dd285b06SPaolo Bonzini         return 0;
1912dd285b06SPaolo Bonzini 
1913dd285b06SPaolo Bonzini     case 0x2b8:	/* CONTROL_PSA_CTRL */
1914dd285b06SPaolo Bonzini         return s->psaconfig;
1915dd285b06SPaolo Bonzini     case 0x2bc:	/* CONTROL_PSA_CMD */
1916dd285b06SPaolo Bonzini     case 0x2c0:	/* CONTROL_PSA_VALUE */
1917dd285b06SPaolo Bonzini         return 0;
1918dd285b06SPaolo Bonzini 
1919dd285b06SPaolo Bonzini     case 0x2b0:	/* CONTROL_SEC_CTRL */
1920dd285b06SPaolo Bonzini         return 0x800000f1;
1921dd285b06SPaolo Bonzini     case 0x2d0:	/* CONTROL_SEC_EMU */
1922dd285b06SPaolo Bonzini         return 0x80000015;
1923dd285b06SPaolo Bonzini     case 0x2d4:	/* CONTROL_SEC_TAP */
1924dd285b06SPaolo Bonzini         return 0x8000007f;
1925dd285b06SPaolo Bonzini     case 0x2b4:	/* CONTROL_SEC_TEST */
1926dd285b06SPaolo Bonzini     case 0x2f0:	/* CONTROL_SEC_STATUS */
1927dd285b06SPaolo Bonzini     case 0x2f4:	/* CONTROL_SEC_ERR_STATUS */
1928dd285b06SPaolo Bonzini         /* Secure mode is not present on general-pusrpose device.  Outside
1929dd285b06SPaolo Bonzini          * secure mode these values cannot be read or written.  */
1930dd285b06SPaolo Bonzini         return 0;
1931dd285b06SPaolo Bonzini 
1932dd285b06SPaolo Bonzini     case 0x2d8:	/* CONTROL_OCM_RAM_PERM */
1933dd285b06SPaolo Bonzini         return 0xff;
1934dd285b06SPaolo Bonzini     case 0x2dc:	/* CONTROL_OCM_PUB_RAM_ADD */
1935dd285b06SPaolo Bonzini     case 0x2e0:	/* CONTROL_EXT_SEC_RAM_START_ADD */
1936dd285b06SPaolo Bonzini     case 0x2e4:	/* CONTROL_EXT_SEC_RAM_STOP_ADD */
1937dd285b06SPaolo Bonzini         /* No secure mode so no Extended Secure RAM present.  */
1938dd285b06SPaolo Bonzini         return 0;
1939dd285b06SPaolo Bonzini 
1940dd285b06SPaolo Bonzini     case 0x2f8:	/* CONTROL_STATUS */
1941dd285b06SPaolo Bonzini         /* Device Type => General-purpose */
1942dd285b06SPaolo Bonzini         return 0x0300;
1943dd285b06SPaolo Bonzini     case 0x2fc:	/* CONTROL_GENERAL_PURPOSE_STATUS */
1944dd285b06SPaolo Bonzini 
1945dd285b06SPaolo Bonzini     case 0x300:	/* CONTROL_RPUB_KEY_H_0 */
1946dd285b06SPaolo Bonzini     case 0x304:	/* CONTROL_RPUB_KEY_H_1 */
1947dd285b06SPaolo Bonzini     case 0x308:	/* CONTROL_RPUB_KEY_H_2 */
1948dd285b06SPaolo Bonzini     case 0x30c:	/* CONTROL_RPUB_KEY_H_3 */
1949dd285b06SPaolo Bonzini         return 0xdecafbad;
1950dd285b06SPaolo Bonzini 
1951dd285b06SPaolo Bonzini     case 0x310:	/* CONTROL_RAND_KEY_0 */
1952dd285b06SPaolo Bonzini     case 0x314:	/* CONTROL_RAND_KEY_1 */
1953dd285b06SPaolo Bonzini     case 0x318:	/* CONTROL_RAND_KEY_2 */
1954dd285b06SPaolo Bonzini     case 0x31c:	/* CONTROL_RAND_KEY_3 */
1955dd285b06SPaolo Bonzini     case 0x320:	/* CONTROL_CUST_KEY_0 */
1956dd285b06SPaolo Bonzini     case 0x324:	/* CONTROL_CUST_KEY_1 */
1957dd285b06SPaolo Bonzini     case 0x330:	/* CONTROL_TEST_KEY_0 */
1958dd285b06SPaolo Bonzini     case 0x334:	/* CONTROL_TEST_KEY_1 */
1959dd285b06SPaolo Bonzini     case 0x338:	/* CONTROL_TEST_KEY_2 */
1960dd285b06SPaolo Bonzini     case 0x33c:	/* CONTROL_TEST_KEY_3 */
1961dd285b06SPaolo Bonzini     case 0x340:	/* CONTROL_TEST_KEY_4 */
1962dd285b06SPaolo Bonzini     case 0x344:	/* CONTROL_TEST_KEY_5 */
1963dd285b06SPaolo Bonzini     case 0x348:	/* CONTROL_TEST_KEY_6 */
1964dd285b06SPaolo Bonzini     case 0x34c:	/* CONTROL_TEST_KEY_7 */
1965dd285b06SPaolo Bonzini     case 0x350:	/* CONTROL_TEST_KEY_8 */
1966dd285b06SPaolo Bonzini     case 0x354:	/* CONTROL_TEST_KEY_9 */
1967dd285b06SPaolo Bonzini         /* Can only be accessed in secure mode and when C_FieldAccEnable
1968dd285b06SPaolo Bonzini          * bit is set in CONTROL_SEC_CTRL.
1969dd285b06SPaolo Bonzini          * TODO: otherwise an interconnect access error is generated.  */
1970dd285b06SPaolo Bonzini         return 0;
1971dd285b06SPaolo Bonzini     }
1972dd285b06SPaolo Bonzini 
1973dd285b06SPaolo Bonzini     OMAP_BAD_REG(addr);
1974dd285b06SPaolo Bonzini     return 0;
1975dd285b06SPaolo Bonzini }
1976dd285b06SPaolo Bonzini 
omap_sysctl_write8(void * opaque,hwaddr addr,uint32_t value)1977a75ed3c4SPhilippe Mathieu-Daudé static void omap_sysctl_write8(void *opaque, hwaddr addr, uint32_t value)
1978dd285b06SPaolo Bonzini {
1979a75ed3c4SPhilippe Mathieu-Daudé     struct omap_sysctl_s *s = opaque;
1980dd285b06SPaolo Bonzini     int pad_offset, byte_offset;
1981dd285b06SPaolo Bonzini     int prev_value;
1982dd285b06SPaolo Bonzini 
1983dd285b06SPaolo Bonzini     switch (addr) {
1984dd285b06SPaolo Bonzini     case 0x030 ... 0x140:	/* CONTROL_PADCONF - only used in the POP */
1985dd285b06SPaolo Bonzini         pad_offset = (addr - 0x30) >> 2;
1986dd285b06SPaolo Bonzini         byte_offset = (addr - 0x30) & (4 - 1);
1987dd285b06SPaolo Bonzini 
1988dd285b06SPaolo Bonzini         prev_value = s->padconf[pad_offset];
1989dd285b06SPaolo Bonzini         prev_value &= ~(0xff << (byte_offset * 8));
1990dd285b06SPaolo Bonzini         prev_value |= ((value & 0x1f1f1f1f) << (byte_offset * 8)) & 0x1f1f1f1f;
1991dd285b06SPaolo Bonzini         s->padconf[pad_offset] = prev_value;
1992dd285b06SPaolo Bonzini         break;
1993dd285b06SPaolo Bonzini 
1994dd285b06SPaolo Bonzini     default:
1995dd285b06SPaolo Bonzini         OMAP_BAD_REG(addr);
1996dd285b06SPaolo Bonzini         break;
1997dd285b06SPaolo Bonzini     }
1998dd285b06SPaolo Bonzini }
1999dd285b06SPaolo Bonzini 
omap_sysctl_write(void * opaque,hwaddr addr,uint32_t value)2000a75ed3c4SPhilippe Mathieu-Daudé static void omap_sysctl_write(void *opaque, hwaddr addr, uint32_t value)
2001dd285b06SPaolo Bonzini {
2002a75ed3c4SPhilippe Mathieu-Daudé     struct omap_sysctl_s *s = opaque;
2003dd285b06SPaolo Bonzini 
2004dd285b06SPaolo Bonzini     switch (addr) {
2005dd285b06SPaolo Bonzini     case 0x000:	/* CONTROL_REVISION */
2006dd285b06SPaolo Bonzini     case 0x2a4:	/* CONTROL_MSUSPENDMUX_5 */
2007dd285b06SPaolo Bonzini     case 0x2c0:	/* CONTROL_PSA_VALUE */
2008dd285b06SPaolo Bonzini     case 0x2f8:	/* CONTROL_STATUS */
2009dd285b06SPaolo Bonzini     case 0x2fc:	/* CONTROL_GENERAL_PURPOSE_STATUS */
2010dd285b06SPaolo Bonzini     case 0x300:	/* CONTROL_RPUB_KEY_H_0 */
2011dd285b06SPaolo Bonzini     case 0x304:	/* CONTROL_RPUB_KEY_H_1 */
2012dd285b06SPaolo Bonzini     case 0x308:	/* CONTROL_RPUB_KEY_H_2 */
2013dd285b06SPaolo Bonzini     case 0x30c:	/* CONTROL_RPUB_KEY_H_3 */
2014dd285b06SPaolo Bonzini     case 0x310:	/* CONTROL_RAND_KEY_0 */
2015dd285b06SPaolo Bonzini     case 0x314:	/* CONTROL_RAND_KEY_1 */
2016dd285b06SPaolo Bonzini     case 0x318:	/* CONTROL_RAND_KEY_2 */
2017dd285b06SPaolo Bonzini     case 0x31c:	/* CONTROL_RAND_KEY_3 */
2018dd285b06SPaolo Bonzini     case 0x320:	/* CONTROL_CUST_KEY_0 */
2019dd285b06SPaolo Bonzini     case 0x324:	/* CONTROL_CUST_KEY_1 */
2020dd285b06SPaolo Bonzini     case 0x330:	/* CONTROL_TEST_KEY_0 */
2021dd285b06SPaolo Bonzini     case 0x334:	/* CONTROL_TEST_KEY_1 */
2022dd285b06SPaolo Bonzini     case 0x338:	/* CONTROL_TEST_KEY_2 */
2023dd285b06SPaolo Bonzini     case 0x33c:	/* CONTROL_TEST_KEY_3 */
2024dd285b06SPaolo Bonzini     case 0x340:	/* CONTROL_TEST_KEY_4 */
2025dd285b06SPaolo Bonzini     case 0x344:	/* CONTROL_TEST_KEY_5 */
2026dd285b06SPaolo Bonzini     case 0x348:	/* CONTROL_TEST_KEY_6 */
2027dd285b06SPaolo Bonzini     case 0x34c:	/* CONTROL_TEST_KEY_7 */
2028dd285b06SPaolo Bonzini     case 0x350:	/* CONTROL_TEST_KEY_8 */
2029dd285b06SPaolo Bonzini     case 0x354:	/* CONTROL_TEST_KEY_9 */
2030dd285b06SPaolo Bonzini         OMAP_RO_REG(addr);
2031dd285b06SPaolo Bonzini         return;
2032dd285b06SPaolo Bonzini 
2033dd285b06SPaolo Bonzini     case 0x010:	/* CONTROL_SYSCONFIG */
2034dd285b06SPaolo Bonzini         s->sysconfig = value & 0x1e;
2035dd285b06SPaolo Bonzini         break;
2036dd285b06SPaolo Bonzini 
2037dd285b06SPaolo Bonzini     case 0x030 ... 0x140:	/* CONTROL_PADCONF - only used in the POP */
2038dd285b06SPaolo Bonzini         /* XXX: should check constant bits */
2039dd285b06SPaolo Bonzini         s->padconf[(addr - 0x30) >> 2] = value & 0x1f1f1f1f;
2040dd285b06SPaolo Bonzini         break;
2041dd285b06SPaolo Bonzini 
2042dd285b06SPaolo Bonzini     case 0x270:	/* CONTROL_DEBOBS */
2043dd285b06SPaolo Bonzini         s->obs = value & 0xff;
2044dd285b06SPaolo Bonzini         break;
2045dd285b06SPaolo Bonzini 
2046dd285b06SPaolo Bonzini     case 0x274:	/* CONTROL_DEVCONF */
2047dd285b06SPaolo Bonzini         s->devconfig = value & 0xffffc7ff;
2048dd285b06SPaolo Bonzini         break;
2049dd285b06SPaolo Bonzini 
2050dd285b06SPaolo Bonzini     case 0x28c:	/* CONTROL_EMU_SUPPORT */
2051dd285b06SPaolo Bonzini         break;
2052dd285b06SPaolo Bonzini 
2053dd285b06SPaolo Bonzini     case 0x290:	/* CONTROL_MSUSPENDMUX_0 */
2054dd285b06SPaolo Bonzini         s->msuspendmux[0] = value & 0x3fffffff;
2055dd285b06SPaolo Bonzini         break;
2056dd285b06SPaolo Bonzini     case 0x294:	/* CONTROL_MSUSPENDMUX_1 */
2057dd285b06SPaolo Bonzini         s->msuspendmux[1] = value & 0x3fffffff;
2058dd285b06SPaolo Bonzini         break;
2059dd285b06SPaolo Bonzini     case 0x298:	/* CONTROL_MSUSPENDMUX_2 */
2060dd285b06SPaolo Bonzini         s->msuspendmux[2] = value & 0x3fffffff;
2061dd285b06SPaolo Bonzini         break;
2062dd285b06SPaolo Bonzini     case 0x29c:	/* CONTROL_MSUSPENDMUX_3 */
2063dd285b06SPaolo Bonzini         s->msuspendmux[3] = value & 0x3fffffff;
2064dd285b06SPaolo Bonzini         break;
2065dd285b06SPaolo Bonzini     case 0x2a0:	/* CONTROL_MSUSPENDMUX_4 */
2066dd285b06SPaolo Bonzini         s->msuspendmux[4] = value & 0x3fffffff;
2067dd285b06SPaolo Bonzini         break;
2068dd285b06SPaolo Bonzini 
2069dd285b06SPaolo Bonzini     case 0x2b8:	/* CONTROL_PSA_CTRL */
2070dd285b06SPaolo Bonzini         s->psaconfig = value & 0x1c;
2071dd285b06SPaolo Bonzini         s->psaconfig |= (value & 0x20) ? 2 : 1;
2072dd285b06SPaolo Bonzini         break;
2073dd285b06SPaolo Bonzini     case 0x2bc:	/* CONTROL_PSA_CMD */
2074dd285b06SPaolo Bonzini         break;
2075dd285b06SPaolo Bonzini 
2076dd285b06SPaolo Bonzini     case 0x2b0:	/* CONTROL_SEC_CTRL */
2077dd285b06SPaolo Bonzini     case 0x2b4:	/* CONTROL_SEC_TEST */
2078dd285b06SPaolo Bonzini     case 0x2d0:	/* CONTROL_SEC_EMU */
2079dd285b06SPaolo Bonzini     case 0x2d4:	/* CONTROL_SEC_TAP */
2080dd285b06SPaolo Bonzini     case 0x2d8:	/* CONTROL_OCM_RAM_PERM */
2081dd285b06SPaolo Bonzini     case 0x2dc:	/* CONTROL_OCM_PUB_RAM_ADD */
2082dd285b06SPaolo Bonzini     case 0x2e0:	/* CONTROL_EXT_SEC_RAM_START_ADD */
2083dd285b06SPaolo Bonzini     case 0x2e4:	/* CONTROL_EXT_SEC_RAM_STOP_ADD */
2084dd285b06SPaolo Bonzini     case 0x2f0:	/* CONTROL_SEC_STATUS */
2085dd285b06SPaolo Bonzini     case 0x2f4:	/* CONTROL_SEC_ERR_STATUS */
2086dd285b06SPaolo Bonzini         break;
2087dd285b06SPaolo Bonzini 
2088dd285b06SPaolo Bonzini     default:
2089dd285b06SPaolo Bonzini         OMAP_BAD_REG(addr);
2090dd285b06SPaolo Bonzini         return;
2091dd285b06SPaolo Bonzini     }
2092dd285b06SPaolo Bonzini }
2093dd285b06SPaolo Bonzini 
omap_sysctl_readfn(void * opaque,hwaddr addr,unsigned size)2094fc14cf0eSPeter Maydell static uint64_t omap_sysctl_readfn(void *opaque, hwaddr addr,
2095fc14cf0eSPeter Maydell                                    unsigned size)
2096fc14cf0eSPeter Maydell {
2097fc14cf0eSPeter Maydell     switch (size) {
2098fc14cf0eSPeter Maydell     case 1:
2099fc14cf0eSPeter Maydell         return omap_sysctl_read8(opaque, addr);
2100fc14cf0eSPeter Maydell     case 2:
2101fc14cf0eSPeter Maydell         return omap_badwidth_read32(opaque, addr); /* TODO */
2102fc14cf0eSPeter Maydell     case 4:
2103fc14cf0eSPeter Maydell         return omap_sysctl_read(opaque, addr);
2104fc14cf0eSPeter Maydell     default:
2105fc14cf0eSPeter Maydell         g_assert_not_reached();
2106fc14cf0eSPeter Maydell     }
2107fc14cf0eSPeter Maydell }
2108fc14cf0eSPeter Maydell 
omap_sysctl_writefn(void * opaque,hwaddr addr,uint64_t value,unsigned size)2109fc14cf0eSPeter Maydell static void omap_sysctl_writefn(void *opaque, hwaddr addr,
2110fc14cf0eSPeter Maydell                                 uint64_t value, unsigned size)
2111fc14cf0eSPeter Maydell {
2112fc14cf0eSPeter Maydell     switch (size) {
2113fc14cf0eSPeter Maydell     case 1:
2114fc14cf0eSPeter Maydell         omap_sysctl_write8(opaque, addr, value);
2115fc14cf0eSPeter Maydell         break;
2116fc14cf0eSPeter Maydell     case 2:
2117fc14cf0eSPeter Maydell         omap_badwidth_write32(opaque, addr, value); /* TODO */
2118fc14cf0eSPeter Maydell         break;
2119fc14cf0eSPeter Maydell     case 4:
2120fc14cf0eSPeter Maydell         omap_sysctl_write(opaque, addr, value);
2121fc14cf0eSPeter Maydell         break;
2122fc14cf0eSPeter Maydell     default:
2123fc14cf0eSPeter Maydell         g_assert_not_reached();
2124fc14cf0eSPeter Maydell     }
2125fc14cf0eSPeter Maydell }
2126fc14cf0eSPeter Maydell 
2127dd285b06SPaolo Bonzini static const MemoryRegionOps omap_sysctl_ops = {
2128fc14cf0eSPeter Maydell     .read = omap_sysctl_readfn,
2129fc14cf0eSPeter Maydell     .write = omap_sysctl_writefn,
2130fc14cf0eSPeter Maydell     .valid.min_access_size = 1,
2131fc14cf0eSPeter Maydell     .valid.max_access_size = 4,
2132dd285b06SPaolo Bonzini     .endianness = DEVICE_NATIVE_ENDIAN,
2133dd285b06SPaolo Bonzini };
2134dd285b06SPaolo Bonzini 
omap_sysctl_reset(struct omap_sysctl_s * s)2135dd285b06SPaolo Bonzini static void omap_sysctl_reset(struct omap_sysctl_s *s)
2136dd285b06SPaolo Bonzini {
2137dd285b06SPaolo Bonzini     /* (power-on reset) */
2138dd285b06SPaolo Bonzini     s->sysconfig = 0;
2139dd285b06SPaolo Bonzini     s->obs = 0;
2140dd285b06SPaolo Bonzini     s->devconfig = 0x0c000000;
2141dd285b06SPaolo Bonzini     s->msuspendmux[0] = 0x00000000;
2142dd285b06SPaolo Bonzini     s->msuspendmux[1] = 0x00000000;
2143dd285b06SPaolo Bonzini     s->msuspendmux[2] = 0x00000000;
2144dd285b06SPaolo Bonzini     s->msuspendmux[3] = 0x00000000;
2145dd285b06SPaolo Bonzini     s->msuspendmux[4] = 0x00000000;
2146dd285b06SPaolo Bonzini     s->psaconfig = 1;
2147dd285b06SPaolo Bonzini 
2148dd285b06SPaolo Bonzini     s->padconf[0x00] = 0x000f0f0f;
2149dd285b06SPaolo Bonzini     s->padconf[0x01] = 0x00000000;
2150dd285b06SPaolo Bonzini     s->padconf[0x02] = 0x00000000;
2151dd285b06SPaolo Bonzini     s->padconf[0x03] = 0x00000000;
2152dd285b06SPaolo Bonzini     s->padconf[0x04] = 0x00000000;
2153dd285b06SPaolo Bonzini     s->padconf[0x05] = 0x00000000;
2154dd285b06SPaolo Bonzini     s->padconf[0x06] = 0x00000000;
2155dd285b06SPaolo Bonzini     s->padconf[0x07] = 0x00000000;
2156dd285b06SPaolo Bonzini     s->padconf[0x08] = 0x08080800;
2157dd285b06SPaolo Bonzini     s->padconf[0x09] = 0x08080808;
2158dd285b06SPaolo Bonzini     s->padconf[0x0a] = 0x08080808;
2159dd285b06SPaolo Bonzini     s->padconf[0x0b] = 0x08080808;
2160dd285b06SPaolo Bonzini     s->padconf[0x0c] = 0x08080808;
2161dd285b06SPaolo Bonzini     s->padconf[0x0d] = 0x08080800;
2162dd285b06SPaolo Bonzini     s->padconf[0x0e] = 0x08080808;
2163dd285b06SPaolo Bonzini     s->padconf[0x0f] = 0x08080808;
2164dd285b06SPaolo Bonzini     s->padconf[0x10] = 0x18181808;	/* | 0x07070700 if SBoot3 */
2165dd285b06SPaolo Bonzini     s->padconf[0x11] = 0x18181818;	/* | 0x07070707 if SBoot3 */
2166dd285b06SPaolo Bonzini     s->padconf[0x12] = 0x18181818;	/* | 0x07070707 if SBoot3 */
2167dd285b06SPaolo Bonzini     s->padconf[0x13] = 0x18181818;	/* | 0x07070707 if SBoot3 */
2168dd285b06SPaolo Bonzini     s->padconf[0x14] = 0x18181818;	/* | 0x00070707 if SBoot3 */
2169dd285b06SPaolo Bonzini     s->padconf[0x15] = 0x18181818;
2170dd285b06SPaolo Bonzini     s->padconf[0x16] = 0x18181818;	/* | 0x07000000 if SBoot3 */
2171dd285b06SPaolo Bonzini     s->padconf[0x17] = 0x1f001f00;
2172dd285b06SPaolo Bonzini     s->padconf[0x18] = 0x1f1f1f1f;
2173dd285b06SPaolo Bonzini     s->padconf[0x19] = 0x00000000;
2174dd285b06SPaolo Bonzini     s->padconf[0x1a] = 0x1f180000;
2175dd285b06SPaolo Bonzini     s->padconf[0x1b] = 0x00001f1f;
2176dd285b06SPaolo Bonzini     s->padconf[0x1c] = 0x1f001f00;
2177dd285b06SPaolo Bonzini     s->padconf[0x1d] = 0x00000000;
2178dd285b06SPaolo Bonzini     s->padconf[0x1e] = 0x00000000;
2179dd285b06SPaolo Bonzini     s->padconf[0x1f] = 0x08000000;
2180dd285b06SPaolo Bonzini     s->padconf[0x20] = 0x08080808;
2181dd285b06SPaolo Bonzini     s->padconf[0x21] = 0x08080808;
2182dd285b06SPaolo Bonzini     s->padconf[0x22] = 0x0f080808;
2183dd285b06SPaolo Bonzini     s->padconf[0x23] = 0x0f0f0f0f;
2184dd285b06SPaolo Bonzini     s->padconf[0x24] = 0x000f0f0f;
2185dd285b06SPaolo Bonzini     s->padconf[0x25] = 0x1f1f1f0f;
2186dd285b06SPaolo Bonzini     s->padconf[0x26] = 0x080f0f1f;
2187dd285b06SPaolo Bonzini     s->padconf[0x27] = 0x070f1808;
2188dd285b06SPaolo Bonzini     s->padconf[0x28] = 0x0f070707;
2189dd285b06SPaolo Bonzini     s->padconf[0x29] = 0x000f0f1f;
2190dd285b06SPaolo Bonzini     s->padconf[0x2a] = 0x0f0f0f1f;
2191dd285b06SPaolo Bonzini     s->padconf[0x2b] = 0x08000000;
2192dd285b06SPaolo Bonzini     s->padconf[0x2c] = 0x0000001f;
2193dd285b06SPaolo Bonzini     s->padconf[0x2d] = 0x0f0f1f00;
2194dd285b06SPaolo Bonzini     s->padconf[0x2e] = 0x1f1f0f0f;
2195dd285b06SPaolo Bonzini     s->padconf[0x2f] = 0x0f1f1f1f;
2196dd285b06SPaolo Bonzini     s->padconf[0x30] = 0x0f0f0f0f;
2197dd285b06SPaolo Bonzini     s->padconf[0x31] = 0x0f1f0f1f;
2198dd285b06SPaolo Bonzini     s->padconf[0x32] = 0x0f0f0f0f;
2199dd285b06SPaolo Bonzini     s->padconf[0x33] = 0x0f1f0f1f;
2200dd285b06SPaolo Bonzini     s->padconf[0x34] = 0x1f1f0f0f;
2201dd285b06SPaolo Bonzini     s->padconf[0x35] = 0x0f0f1f1f;
2202dd285b06SPaolo Bonzini     s->padconf[0x36] = 0x0f0f1f0f;
2203dd285b06SPaolo Bonzini     s->padconf[0x37] = 0x0f0f0f0f;
2204dd285b06SPaolo Bonzini     s->padconf[0x38] = 0x1f18180f;
2205dd285b06SPaolo Bonzini     s->padconf[0x39] = 0x1f1f1f1f;
2206dd285b06SPaolo Bonzini     s->padconf[0x3a] = 0x00001f1f;
2207dd285b06SPaolo Bonzini     s->padconf[0x3b] = 0x00000000;
2208dd285b06SPaolo Bonzini     s->padconf[0x3c] = 0x00000000;
2209dd285b06SPaolo Bonzini     s->padconf[0x3d] = 0x0f0f0f0f;
2210dd285b06SPaolo Bonzini     s->padconf[0x3e] = 0x18000f0f;
2211dd285b06SPaolo Bonzini     s->padconf[0x3f] = 0x00070000;
2212dd285b06SPaolo Bonzini     s->padconf[0x40] = 0x00000707;
2213dd285b06SPaolo Bonzini     s->padconf[0x41] = 0x0f1f0700;
2214dd285b06SPaolo Bonzini     s->padconf[0x42] = 0x1f1f070f;
2215dd285b06SPaolo Bonzini     s->padconf[0x43] = 0x0008081f;
2216dd285b06SPaolo Bonzini     s->padconf[0x44] = 0x00000800;
2217dd285b06SPaolo Bonzini }
2218dd285b06SPaolo Bonzini 
omap_sysctl_init(struct omap_target_agent_s * ta,omap_clk iclk,struct omap_mpu_state_s * mpu)2219dd285b06SPaolo Bonzini static struct omap_sysctl_s *omap_sysctl_init(struct omap_target_agent_s *ta,
2220dd285b06SPaolo Bonzini                 omap_clk iclk, struct omap_mpu_state_s *mpu)
2221dd285b06SPaolo Bonzini {
2222b45c03f5SMarkus Armbruster     struct omap_sysctl_s *s = g_new0(struct omap_sysctl_s, 1);
2223dd285b06SPaolo Bonzini 
2224dd285b06SPaolo Bonzini     s->mpu = mpu;
2225dd285b06SPaolo Bonzini     omap_sysctl_reset(s);
2226dd285b06SPaolo Bonzini 
22272c9b15caSPaolo Bonzini     memory_region_init_io(&s->iomem, NULL, &omap_sysctl_ops, s, "omap.sysctl",
2228dd285b06SPaolo Bonzini                           omap_l4_region_size(ta, 0));
2229dd285b06SPaolo Bonzini     omap_l4_attach(ta, 0, &s->iomem);
2230dd285b06SPaolo Bonzini 
2231dd285b06SPaolo Bonzini     return s;
2232dd285b06SPaolo Bonzini }
2233dd285b06SPaolo Bonzini 
2234dd285b06SPaolo Bonzini /* General chip reset */
omap2_mpu_reset(void * opaque)2235dd285b06SPaolo Bonzini static void omap2_mpu_reset(void *opaque)
2236dd285b06SPaolo Bonzini {
2237a75ed3c4SPhilippe Mathieu-Daudé     struct omap_mpu_state_s *mpu = opaque;
2238dd285b06SPaolo Bonzini 
2239dd285b06SPaolo Bonzini     omap_dma_reset(mpu->dma);
2240dd285b06SPaolo Bonzini     omap_prcm_reset(mpu->prcm);
2241dd285b06SPaolo Bonzini     omap_sysctl_reset(mpu->sysc);
2242dd285b06SPaolo Bonzini     omap_gp_timer_reset(mpu->gptimer[0]);
2243dd285b06SPaolo Bonzini     omap_gp_timer_reset(mpu->gptimer[1]);
2244dd285b06SPaolo Bonzini     omap_gp_timer_reset(mpu->gptimer[2]);
2245dd285b06SPaolo Bonzini     omap_gp_timer_reset(mpu->gptimer[3]);
2246dd285b06SPaolo Bonzini     omap_gp_timer_reset(mpu->gptimer[4]);
2247dd285b06SPaolo Bonzini     omap_gp_timer_reset(mpu->gptimer[5]);
2248dd285b06SPaolo Bonzini     omap_gp_timer_reset(mpu->gptimer[6]);
2249dd285b06SPaolo Bonzini     omap_gp_timer_reset(mpu->gptimer[7]);
2250dd285b06SPaolo Bonzini     omap_gp_timer_reset(mpu->gptimer[8]);
2251dd285b06SPaolo Bonzini     omap_gp_timer_reset(mpu->gptimer[9]);
2252dd285b06SPaolo Bonzini     omap_gp_timer_reset(mpu->gptimer[10]);
2253dd285b06SPaolo Bonzini     omap_gp_timer_reset(mpu->gptimer[11]);
2254dd285b06SPaolo Bonzini     omap_synctimer_reset(mpu->synctimer);
2255dd285b06SPaolo Bonzini     omap_sdrc_reset(mpu->sdrc);
2256dd285b06SPaolo Bonzini     omap_gpmc_reset(mpu->gpmc);
2257dd285b06SPaolo Bonzini     omap_dss_reset(mpu->dss);
2258dd285b06SPaolo Bonzini     omap_uart_reset(mpu->uart[0]);
2259dd285b06SPaolo Bonzini     omap_uart_reset(mpu->uart[1]);
2260dd285b06SPaolo Bonzini     omap_uart_reset(mpu->uart[2]);
2261dd285b06SPaolo Bonzini     omap_mmc_reset(mpu->mmc);
2262dd285b06SPaolo Bonzini     omap_mcspi_reset(mpu->mcspi[0]);
2263dd285b06SPaolo Bonzini     omap_mcspi_reset(mpu->mcspi[1]);
2264dd285b06SPaolo Bonzini     cpu_reset(CPU(mpu->cpu));
2265dd285b06SPaolo Bonzini }
2266dd285b06SPaolo Bonzini 
omap2_validate_addr(struct omap_mpu_state_s * s,hwaddr addr)2267dd285b06SPaolo Bonzini static int omap2_validate_addr(struct omap_mpu_state_s *s,
2268dd285b06SPaolo Bonzini                 hwaddr addr)
2269dd285b06SPaolo Bonzini {
2270dd285b06SPaolo Bonzini     return 1;
2271dd285b06SPaolo Bonzini }
2272dd285b06SPaolo Bonzini 
2273dd285b06SPaolo Bonzini static const struct dma_irq_map omap2_dma_irq_map[] = {
2274dd285b06SPaolo Bonzini     { 0, OMAP_INT_24XX_SDMA_IRQ0 },
2275dd285b06SPaolo Bonzini     { 0, OMAP_INT_24XX_SDMA_IRQ1 },
2276dd285b06SPaolo Bonzini     { 0, OMAP_INT_24XX_SDMA_IRQ2 },
2277dd285b06SPaolo Bonzini     { 0, OMAP_INT_24XX_SDMA_IRQ3 },
2278dd285b06SPaolo Bonzini };
2279dd285b06SPaolo Bonzini 
omap2420_mpu_init(MemoryRegion * sdram,const char * cpu_type)2280e285e867SPhilippe Mathieu-Daudé struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sdram,
2281ba1ba5ccSIgor Mammedov                 const char *cpu_type)
2282dd285b06SPaolo Bonzini {
2283b45c03f5SMarkus Armbruster     struct omap_mpu_state_s *s = g_new0(struct omap_mpu_state_s, 1);
2284dd285b06SPaolo Bonzini     qemu_irq dma_irqs[4];
2285dd285b06SPaolo Bonzini     DriveInfo *dinfo;
2286dd285b06SPaolo Bonzini     int i;
2287dd285b06SPaolo Bonzini     SysBusDevice *busdev;
2288dd285b06SPaolo Bonzini     struct omap_target_agent_s *ta;
2289e285e867SPhilippe Mathieu-Daudé     MemoryRegion *sysmem = get_system_memory();
2290dd285b06SPaolo Bonzini 
2291dd285b06SPaolo Bonzini     /* Core */
2292dd285b06SPaolo Bonzini     s->mpu_model = omap2420;
2293ba1ba5ccSIgor Mammedov     s->cpu = ARM_CPU(cpu_create(cpu_type));
2294dd285b06SPaolo Bonzini     s->sram_size = OMAP242X_SRAM_SIZE;
2295dd285b06SPaolo Bonzini 
2296f3c7d038SAndreas Färber     s->wakeup = qemu_allocate_irq(omap_mpu_wakeup, s, 0);
2297dd285b06SPaolo Bonzini 
2298dd285b06SPaolo Bonzini     /* Clocks */
2299dd285b06SPaolo Bonzini     omap_clk_init(s);
2300dd285b06SPaolo Bonzini 
2301dd285b06SPaolo Bonzini     /* Memory-mapped stuff */
230298a99ce0SPeter Maydell     memory_region_init_ram(&s->sram, NULL, "omap2.sram", s->sram_size,
2303f8ed85acSMarkus Armbruster                            &error_fatal);
2304dd285b06SPaolo Bonzini     memory_region_add_subregion(sysmem, OMAP2_SRAM_BASE, &s->sram);
2305dd285b06SPaolo Bonzini 
2306dd285b06SPaolo Bonzini     s->l4 = omap_l4_init(sysmem, OMAP2_L4_BASE, 54);
2307dd285b06SPaolo Bonzini 
2308dd285b06SPaolo Bonzini     /* Actually mapped at any 2K boundary in the ARM11 private-peripheral if */
23093e80f690SMarkus Armbruster     s->ih[0] = qdev_new("omap2-intc");
2310dd285b06SPaolo Bonzini     qdev_prop_set_uint8(s->ih[0], "revision", 0x21);
2311bab592a2SMarc-André Lureau     omap_intc_set_fclk(OMAP_INTC(s->ih[0]), omap_findclk(s, "mpu_intc_fclk"));
2312bab592a2SMarc-André Lureau     omap_intc_set_iclk(OMAP_INTC(s->ih[0]), omap_findclk(s, "mpu_intc_iclk"));
2313dd285b06SPaolo Bonzini     busdev = SYS_BUS_DEVICE(s->ih[0]);
23143c6ef471SMarkus Armbruster     sysbus_realize_and_unref(busdev, &error_fatal);
2315437f0f10SPeter Maydell     sysbus_connect_irq(busdev, 0,
2316437f0f10SPeter Maydell                        qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ));
2317437f0f10SPeter Maydell     sysbus_connect_irq(busdev, 1,
2318437f0f10SPeter Maydell                        qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_FIQ));
2319dd285b06SPaolo Bonzini     sysbus_mmio_map(busdev, 0, 0x480fe000);
2320dd285b06SPaolo Bonzini     s->prcm = omap_prcm_init(omap_l4tao(s->l4, 3),
2321dd285b06SPaolo Bonzini                              qdev_get_gpio_in(s->ih[0],
2322dd285b06SPaolo Bonzini                                               OMAP_INT_24XX_PRCM_MPU_IRQ),
2323dd285b06SPaolo Bonzini                              NULL, NULL, s);
2324dd285b06SPaolo Bonzini 
2325dd285b06SPaolo Bonzini     s->sysc = omap_sysctl_init(omap_l4tao(s->l4, 1),
2326dd285b06SPaolo Bonzini                     omap_findclk(s, "omapctrl_iclk"), s);
2327dd285b06SPaolo Bonzini 
2328dd285b06SPaolo Bonzini     for (i = 0; i < 4; i++) {
2329dd285b06SPaolo Bonzini         dma_irqs[i] = qdev_get_gpio_in(s->ih[omap2_dma_irq_map[i].ih],
2330dd285b06SPaolo Bonzini                                        omap2_dma_irq_map[i].intr);
2331dd285b06SPaolo Bonzini     }
2332dd285b06SPaolo Bonzini     s->dma = omap_dma4_init(0x48056000, dma_irqs, sysmem, s, 256, 32,
2333dd285b06SPaolo Bonzini                     omap_findclk(s, "sdma_iclk"),
2334dd285b06SPaolo Bonzini                     omap_findclk(s, "sdma_fclk"));
2335dd285b06SPaolo Bonzini     s->port->addr_valid = omap2_validate_addr;
2336dd285b06SPaolo Bonzini 
2337dd285b06SPaolo Bonzini     /* Register SDRAM and SRAM ports for fast DMA transfers.  */
2338e285e867SPhilippe Mathieu-Daudé     soc_dma_port_add_mem(s->dma, memory_region_get_ram_ptr(sdram),
2339e285e867SPhilippe Mathieu-Daudé                          OMAP2_Q2_BASE, memory_region_size(sdram));
2340dd285b06SPaolo Bonzini     soc_dma_port_add_mem(s->dma, memory_region_get_ram_ptr(&s->sram),
2341dd285b06SPaolo Bonzini                          OMAP2_SRAM_BASE, s->sram_size);
2342dd285b06SPaolo Bonzini 
2343dd285b06SPaolo Bonzini     s->uart[0] = omap2_uart_init(sysmem, omap_l4ta(s->l4, 19),
2344dd285b06SPaolo Bonzini                                  qdev_get_gpio_in(s->ih[0],
2345dd285b06SPaolo Bonzini                                                   OMAP_INT_24XX_UART1_IRQ),
2346dd285b06SPaolo Bonzini                     omap_findclk(s, "uart1_fclk"),
2347dd285b06SPaolo Bonzini                     omap_findclk(s, "uart1_iclk"),
2348dd285b06SPaolo Bonzini                     s->drq[OMAP24XX_DMA_UART1_TX],
2349dd285b06SPaolo Bonzini                     s->drq[OMAP24XX_DMA_UART1_RX],
2350dd285b06SPaolo Bonzini                     "uart1",
23519bca0edbSPeter Maydell                     serial_hd(0));
2352dd285b06SPaolo Bonzini     s->uart[1] = omap2_uart_init(sysmem, omap_l4ta(s->l4, 20),
2353dd285b06SPaolo Bonzini                                  qdev_get_gpio_in(s->ih[0],
2354dd285b06SPaolo Bonzini                                                   OMAP_INT_24XX_UART2_IRQ),
2355dd285b06SPaolo Bonzini                     omap_findclk(s, "uart2_fclk"),
2356dd285b06SPaolo Bonzini                     omap_findclk(s, "uart2_iclk"),
2357dd285b06SPaolo Bonzini                     s->drq[OMAP24XX_DMA_UART2_TX],
2358dd285b06SPaolo Bonzini                     s->drq[OMAP24XX_DMA_UART2_RX],
2359dd285b06SPaolo Bonzini                     "uart2",
23609bca0edbSPeter Maydell                     serial_hd(0) ? serial_hd(1) : NULL);
2361dd285b06SPaolo Bonzini     s->uart[2] = omap2_uart_init(sysmem, omap_l4ta(s->l4, 21),
2362dd285b06SPaolo Bonzini                                  qdev_get_gpio_in(s->ih[0],
2363dd285b06SPaolo Bonzini                                                   OMAP_INT_24XX_UART3_IRQ),
2364dd285b06SPaolo Bonzini                     omap_findclk(s, "uart3_fclk"),
2365dd285b06SPaolo Bonzini                     omap_findclk(s, "uart3_iclk"),
2366dd285b06SPaolo Bonzini                     s->drq[OMAP24XX_DMA_UART3_TX],
2367dd285b06SPaolo Bonzini                     s->drq[OMAP24XX_DMA_UART3_RX],
2368dd285b06SPaolo Bonzini                     "uart3",
23699bca0edbSPeter Maydell                     serial_hd(0) && serial_hd(1) ? serial_hd(2) : NULL);
2370dd285b06SPaolo Bonzini 
2371dd285b06SPaolo Bonzini     s->gptimer[0] = omap_gp_timer_init(omap_l4ta(s->l4, 7),
2372dd285b06SPaolo Bonzini                     qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER1),
2373dd285b06SPaolo Bonzini                     omap_findclk(s, "wu_gpt1_clk"),
2374dd285b06SPaolo Bonzini                     omap_findclk(s, "wu_l4_iclk"));
2375dd285b06SPaolo Bonzini     s->gptimer[1] = omap_gp_timer_init(omap_l4ta(s->l4, 8),
2376dd285b06SPaolo Bonzini                     qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER2),
2377dd285b06SPaolo Bonzini                     omap_findclk(s, "core_gpt2_clk"),
2378dd285b06SPaolo Bonzini                     omap_findclk(s, "core_l4_iclk"));
2379dd285b06SPaolo Bonzini     s->gptimer[2] = omap_gp_timer_init(omap_l4ta(s->l4, 22),
2380dd285b06SPaolo Bonzini                     qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER3),
2381dd285b06SPaolo Bonzini                     omap_findclk(s, "core_gpt3_clk"),
2382dd285b06SPaolo Bonzini                     omap_findclk(s, "core_l4_iclk"));
2383dd285b06SPaolo Bonzini     s->gptimer[3] = omap_gp_timer_init(omap_l4ta(s->l4, 23),
2384dd285b06SPaolo Bonzini                     qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER4),
2385dd285b06SPaolo Bonzini                     omap_findclk(s, "core_gpt4_clk"),
2386dd285b06SPaolo Bonzini                     omap_findclk(s, "core_l4_iclk"));
2387dd285b06SPaolo Bonzini     s->gptimer[4] = omap_gp_timer_init(omap_l4ta(s->l4, 24),
2388dd285b06SPaolo Bonzini                     qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER5),
2389dd285b06SPaolo Bonzini                     omap_findclk(s, "core_gpt5_clk"),
2390dd285b06SPaolo Bonzini                     omap_findclk(s, "core_l4_iclk"));
2391dd285b06SPaolo Bonzini     s->gptimer[5] = omap_gp_timer_init(omap_l4ta(s->l4, 25),
2392dd285b06SPaolo Bonzini                     qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER6),
2393dd285b06SPaolo Bonzini                     omap_findclk(s, "core_gpt6_clk"),
2394dd285b06SPaolo Bonzini                     omap_findclk(s, "core_l4_iclk"));
2395dd285b06SPaolo Bonzini     s->gptimer[6] = omap_gp_timer_init(omap_l4ta(s->l4, 26),
2396dd285b06SPaolo Bonzini                     qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER7),
2397dd285b06SPaolo Bonzini                     omap_findclk(s, "core_gpt7_clk"),
2398dd285b06SPaolo Bonzini                     omap_findclk(s, "core_l4_iclk"));
2399dd285b06SPaolo Bonzini     s->gptimer[7] = omap_gp_timer_init(omap_l4ta(s->l4, 27),
2400dd285b06SPaolo Bonzini                     qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER8),
2401dd285b06SPaolo Bonzini                     omap_findclk(s, "core_gpt8_clk"),
2402dd285b06SPaolo Bonzini                     omap_findclk(s, "core_l4_iclk"));
2403dd285b06SPaolo Bonzini     s->gptimer[8] = omap_gp_timer_init(omap_l4ta(s->l4, 28),
2404dd285b06SPaolo Bonzini                     qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER9),
2405dd285b06SPaolo Bonzini                     omap_findclk(s, "core_gpt9_clk"),
2406dd285b06SPaolo Bonzini                     omap_findclk(s, "core_l4_iclk"));
2407dd285b06SPaolo Bonzini     s->gptimer[9] = omap_gp_timer_init(omap_l4ta(s->l4, 29),
2408dd285b06SPaolo Bonzini                     qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER10),
2409dd285b06SPaolo Bonzini                     omap_findclk(s, "core_gpt10_clk"),
2410dd285b06SPaolo Bonzini                     omap_findclk(s, "core_l4_iclk"));
2411dd285b06SPaolo Bonzini     s->gptimer[10] = omap_gp_timer_init(omap_l4ta(s->l4, 30),
2412dd285b06SPaolo Bonzini                     qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER11),
2413dd285b06SPaolo Bonzini                     omap_findclk(s, "core_gpt11_clk"),
2414dd285b06SPaolo Bonzini                     omap_findclk(s, "core_l4_iclk"));
2415dd285b06SPaolo Bonzini     s->gptimer[11] = omap_gp_timer_init(omap_l4ta(s->l4, 31),
2416dd285b06SPaolo Bonzini                     qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER12),
2417dd285b06SPaolo Bonzini                     omap_findclk(s, "core_gpt12_clk"),
2418dd285b06SPaolo Bonzini                     omap_findclk(s, "core_l4_iclk"));
2419dd285b06SPaolo Bonzini 
2420dd285b06SPaolo Bonzini     omap_tap_init(omap_l4ta(s->l4, 2), s);
2421dd285b06SPaolo Bonzini 
2422dd285b06SPaolo Bonzini     s->synctimer = omap_synctimer_init(omap_l4tao(s->l4, 2), s,
2423dd285b06SPaolo Bonzini                     omap_findclk(s, "clk32-kHz"),
2424dd285b06SPaolo Bonzini                     omap_findclk(s, "core_l4_iclk"));
2425dd285b06SPaolo Bonzini 
24263e80f690SMarkus Armbruster     s->i2c[0] = qdev_new("omap_i2c");
2427dd285b06SPaolo Bonzini     qdev_prop_set_uint8(s->i2c[0], "revision", 0x34);
24280fd20c53SMarc-André Lureau     omap_i2c_set_iclk(OMAP_I2C(s->i2c[0]), omap_findclk(s, "i2c1.iclk"));
24290fd20c53SMarc-André Lureau     omap_i2c_set_fclk(OMAP_I2C(s->i2c[0]), omap_findclk(s, "i2c1.fclk"));
2430dd285b06SPaolo Bonzini     busdev = SYS_BUS_DEVICE(s->i2c[0]);
24313c6ef471SMarkus Armbruster     sysbus_realize_and_unref(busdev, &error_fatal);
2432dd285b06SPaolo Bonzini     sysbus_connect_irq(busdev, 0,
2433dd285b06SPaolo Bonzini                        qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_I2C1_IRQ));
2434dd285b06SPaolo Bonzini     sysbus_connect_irq(busdev, 1, s->drq[OMAP24XX_DMA_I2C1_TX]);
2435dd285b06SPaolo Bonzini     sysbus_connect_irq(busdev, 2, s->drq[OMAP24XX_DMA_I2C1_RX]);
2436dd285b06SPaolo Bonzini     sysbus_mmio_map(busdev, 0, omap_l4_region_base(omap_l4tao(s->l4, 5), 0));
2437dd285b06SPaolo Bonzini 
24383e80f690SMarkus Armbruster     s->i2c[1] = qdev_new("omap_i2c");
2439dd285b06SPaolo Bonzini     qdev_prop_set_uint8(s->i2c[1], "revision", 0x34);
24400fd20c53SMarc-André Lureau     omap_i2c_set_iclk(OMAP_I2C(s->i2c[1]), omap_findclk(s, "i2c2.iclk"));
24410fd20c53SMarc-André Lureau     omap_i2c_set_fclk(OMAP_I2C(s->i2c[1]), omap_findclk(s, "i2c2.fclk"));
2442dd285b06SPaolo Bonzini     busdev = SYS_BUS_DEVICE(s->i2c[1]);
24433c6ef471SMarkus Armbruster     sysbus_realize_and_unref(busdev, &error_fatal);
2444dd285b06SPaolo Bonzini     sysbus_connect_irq(busdev, 0,
2445dd285b06SPaolo Bonzini                        qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_I2C2_IRQ));
2446dd285b06SPaolo Bonzini     sysbus_connect_irq(busdev, 1, s->drq[OMAP24XX_DMA_I2C2_TX]);
2447dd285b06SPaolo Bonzini     sysbus_connect_irq(busdev, 2, s->drq[OMAP24XX_DMA_I2C2_RX]);
2448dd285b06SPaolo Bonzini     sysbus_mmio_map(busdev, 0, omap_l4_region_base(omap_l4tao(s->l4, 6), 0));
2449dd285b06SPaolo Bonzini 
24503e80f690SMarkus Armbruster     s->gpio = qdev_new("omap2-gpio");
2451dd285b06SPaolo Bonzini     qdev_prop_set_int32(s->gpio, "mpu_model", s->mpu_model);
2452ba2aba83SMarc-André Lureau     omap2_gpio_set_iclk(OMAP2_GPIO(s->gpio), omap_findclk(s, "gpio_iclk"));
2453ba2aba83SMarc-André Lureau     omap2_gpio_set_fclk(OMAP2_GPIO(s->gpio), 0, omap_findclk(s, "gpio1_dbclk"));
2454ba2aba83SMarc-André Lureau     omap2_gpio_set_fclk(OMAP2_GPIO(s->gpio), 1, omap_findclk(s, "gpio2_dbclk"));
2455ba2aba83SMarc-André Lureau     omap2_gpio_set_fclk(OMAP2_GPIO(s->gpio), 2, omap_findclk(s, "gpio3_dbclk"));
2456ba2aba83SMarc-André Lureau     omap2_gpio_set_fclk(OMAP2_GPIO(s->gpio), 3, omap_findclk(s, "gpio4_dbclk"));
2457dd285b06SPaolo Bonzini     if (s->mpu_model == omap2430) {
2458ba2aba83SMarc-André Lureau         omap2_gpio_set_fclk(OMAP2_GPIO(s->gpio), 4,
2459ba2aba83SMarc-André Lureau                             omap_findclk(s, "gpio5_dbclk"));
2460dd285b06SPaolo Bonzini     }
2461dd285b06SPaolo Bonzini     busdev = SYS_BUS_DEVICE(s->gpio);
24623c6ef471SMarkus Armbruster     sysbus_realize_and_unref(busdev, &error_fatal);
2463dd285b06SPaolo Bonzini     sysbus_connect_irq(busdev, 0,
2464dd285b06SPaolo Bonzini                        qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPIO_BANK1));
2465dd285b06SPaolo Bonzini     sysbus_connect_irq(busdev, 3,
2466dd285b06SPaolo Bonzini                        qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPIO_BANK2));
2467dd285b06SPaolo Bonzini     sysbus_connect_irq(busdev, 6,
2468dd285b06SPaolo Bonzini                        qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPIO_BANK3));
2469dd285b06SPaolo Bonzini     sysbus_connect_irq(busdev, 9,
2470dd285b06SPaolo Bonzini                        qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPIO_BANK4));
2471dd285b06SPaolo Bonzini     if (s->mpu_model == omap2430) {
2472dd285b06SPaolo Bonzini         sysbus_connect_irq(busdev, 12,
2473dd285b06SPaolo Bonzini                            qdev_get_gpio_in(s->ih[0],
2474dd285b06SPaolo Bonzini                                             OMAP_INT_243X_GPIO_BANK5));
2475dd285b06SPaolo Bonzini     }
2476dd285b06SPaolo Bonzini     ta = omap_l4ta(s->l4, 3);
2477dd285b06SPaolo Bonzini     sysbus_mmio_map(busdev, 0, omap_l4_region_base(ta, 1));
2478dd285b06SPaolo Bonzini     sysbus_mmio_map(busdev, 1, omap_l4_region_base(ta, 0));
2479dd285b06SPaolo Bonzini     sysbus_mmio_map(busdev, 2, omap_l4_region_base(ta, 2));
2480dd285b06SPaolo Bonzini     sysbus_mmio_map(busdev, 3, omap_l4_region_base(ta, 4));
2481dd285b06SPaolo Bonzini     sysbus_mmio_map(busdev, 4, omap_l4_region_base(ta, 5));
2482dd285b06SPaolo Bonzini 
2483dd285b06SPaolo Bonzini     s->sdrc = omap_sdrc_init(sysmem, 0x68009000);
2484dd285b06SPaolo Bonzini     s->gpmc = omap_gpmc_init(s, 0x6800a000,
2485dd285b06SPaolo Bonzini                              qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPMC_IRQ),
2486dd285b06SPaolo Bonzini                              s->drq[OMAP24XX_DMA_GPMC]);
2487dd285b06SPaolo Bonzini 
2488dd285b06SPaolo Bonzini     dinfo = drive_get(IF_SD, 0, 0);
2489a82929a2SThomas Huth     if (!dinfo && !qtest_enabled()) {
2490a82929a2SThomas Huth         warn_report("missing SecureDigital device");
2491dd285b06SPaolo Bonzini     }
2492fa1d36dfSMarkus Armbruster     s->mmc = omap2_mmc_init(omap_l4tao(s->l4, 9),
2493a82929a2SThomas Huth                     dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
2494dd285b06SPaolo Bonzini                     qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_MMC_IRQ),
2495dd285b06SPaolo Bonzini                     &s->drq[OMAP24XX_DMA_MMC1_TX],
2496dd285b06SPaolo Bonzini                     omap_findclk(s, "mmc_fclk"), omap_findclk(s, "mmc_iclk"));
2497dd285b06SPaolo Bonzini 
2498dd285b06SPaolo Bonzini     s->mcspi[0] = omap_mcspi_init(omap_l4ta(s->l4, 35), 4,
2499dd285b06SPaolo Bonzini                     qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_MCSPI1_IRQ),
2500dd285b06SPaolo Bonzini                     &s->drq[OMAP24XX_DMA_SPI1_TX0],
2501dd285b06SPaolo Bonzini                     omap_findclk(s, "spi1_fclk"),
2502dd285b06SPaolo Bonzini                     omap_findclk(s, "spi1_iclk"));
2503dd285b06SPaolo Bonzini     s->mcspi[1] = omap_mcspi_init(omap_l4ta(s->l4, 36), 2,
2504dd285b06SPaolo Bonzini                     qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_MCSPI2_IRQ),
2505dd285b06SPaolo Bonzini                     &s->drq[OMAP24XX_DMA_SPI2_TX0],
2506dd285b06SPaolo Bonzini                     omap_findclk(s, "spi2_fclk"),
2507dd285b06SPaolo Bonzini                     omap_findclk(s, "spi2_iclk"));
2508dd285b06SPaolo Bonzini 
2509dd285b06SPaolo Bonzini     s->dss = omap_dss_init(omap_l4ta(s->l4, 10), sysmem, 0x68000800,
2510dd285b06SPaolo Bonzini                     /* XXX wire M_IRQ_25, D_L2_IRQ_30 and I_IRQ_13 together */
2511dd285b06SPaolo Bonzini                     qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_DSS_IRQ),
2512dd285b06SPaolo Bonzini                            s->drq[OMAP24XX_DMA_DSS],
2513dd285b06SPaolo Bonzini                     omap_findclk(s, "dss_clk1"), omap_findclk(s, "dss_clk2"),
2514dd285b06SPaolo Bonzini                     omap_findclk(s, "dss_54m_clk"),
2515dd285b06SPaolo Bonzini                     omap_findclk(s, "dss_l3_iclk"),
2516dd285b06SPaolo Bonzini                     omap_findclk(s, "dss_l4_iclk"));
2517dd285b06SPaolo Bonzini 
2518dd285b06SPaolo Bonzini     omap_sti_init(omap_l4ta(s->l4, 18), sysmem, 0x54000000,
2519dd285b06SPaolo Bonzini                   qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_STI),
2520dd285b06SPaolo Bonzini                   omap_findclk(s, "emul_ck"),
25219bca0edbSPeter Maydell                     serial_hd(0) && serial_hd(1) && serial_hd(2) ?
25229bca0edbSPeter Maydell                     serial_hd(3) : NULL);
2523dd285b06SPaolo Bonzini 
2524dd285b06SPaolo Bonzini     s->eac = omap_eac_init(omap_l4ta(s->l4, 32),
2525dd285b06SPaolo Bonzini                            qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_EAC_IRQ),
2526dd285b06SPaolo Bonzini                     /* Ten consecutive lines */
2527dd285b06SPaolo Bonzini                     &s->drq[OMAP24XX_DMA_EAC_AC_RD],
2528dd285b06SPaolo Bonzini                     omap_findclk(s, "func_96m_clk"),
2529dd285b06SPaolo Bonzini                     omap_findclk(s, "core_l4_iclk"));
2530dd285b06SPaolo Bonzini 
2531b3db996fSStefan Weil     /* All register mappings (including those not currently implemented):
2532dd285b06SPaolo Bonzini      * SystemControlMod	48000000 - 48000fff
2533dd285b06SPaolo Bonzini      * SystemControlL4	48001000 - 48001fff
2534dd285b06SPaolo Bonzini      * 32kHz Timer Mod	48004000 - 48004fff
2535dd285b06SPaolo Bonzini      * 32kHz Timer L4	48005000 - 48005fff
2536dd285b06SPaolo Bonzini      * PRCM ModA	48008000 - 480087ff
2537dd285b06SPaolo Bonzini      * PRCM ModB	48008800 - 48008fff
2538dd285b06SPaolo Bonzini      * PRCM L4		48009000 - 48009fff
2539dd285b06SPaolo Bonzini      * TEST-BCM Mod	48012000 - 48012fff
2540dd285b06SPaolo Bonzini      * TEST-BCM L4	48013000 - 48013fff
2541dd285b06SPaolo Bonzini      * TEST-TAP Mod	48014000 - 48014fff
2542dd285b06SPaolo Bonzini      * TEST-TAP L4	48015000 - 48015fff
2543dd285b06SPaolo Bonzini      * GPIO1 Mod	48018000 - 48018fff
2544dd285b06SPaolo Bonzini      * GPIO Top		48019000 - 48019fff
2545dd285b06SPaolo Bonzini      * GPIO2 Mod	4801a000 - 4801afff
2546dd285b06SPaolo Bonzini      * GPIO L4		4801b000 - 4801bfff
2547dd285b06SPaolo Bonzini      * GPIO3 Mod	4801c000 - 4801cfff
2548dd285b06SPaolo Bonzini      * GPIO4 Mod	4801e000 - 4801efff
2549dd285b06SPaolo Bonzini      * WDTIMER1 Mod	48020000 - 48010fff
2550dd285b06SPaolo Bonzini      * WDTIMER Top	48021000 - 48011fff
2551dd285b06SPaolo Bonzini      * WDTIMER2 Mod	48022000 - 48012fff
2552dd285b06SPaolo Bonzini      * WDTIMER L4	48023000 - 48013fff
2553dd285b06SPaolo Bonzini      * WDTIMER3 Mod	48024000 - 48014fff
2554dd285b06SPaolo Bonzini      * WDTIMER3 L4	48025000 - 48015fff
2555dd285b06SPaolo Bonzini      * WDTIMER4 Mod	48026000 - 48016fff
2556dd285b06SPaolo Bonzini      * WDTIMER4 L4	48027000 - 48017fff
2557dd285b06SPaolo Bonzini      * GPTIMER1 Mod	48028000 - 48018fff
2558dd285b06SPaolo Bonzini      * GPTIMER1 L4	48029000 - 48019fff
2559dd285b06SPaolo Bonzini      * GPTIMER2 Mod	4802a000 - 4801afff
2560dd285b06SPaolo Bonzini      * GPTIMER2 L4	4802b000 - 4801bfff
2561dd285b06SPaolo Bonzini      * L4-Config AP	48040000 - 480407ff
2562dd285b06SPaolo Bonzini      * L4-Config IP	48040800 - 48040fff
2563dd285b06SPaolo Bonzini      * L4-Config LA	48041000 - 48041fff
2564dd285b06SPaolo Bonzini      * ARM11ETB Mod	48048000 - 48049fff
2565dd285b06SPaolo Bonzini      * ARM11ETB L4	4804a000 - 4804afff
2566dd285b06SPaolo Bonzini      * DISPLAY Top	48050000 - 480503ff
2567dd285b06SPaolo Bonzini      * DISPLAY DISPC	48050400 - 480507ff
2568dd285b06SPaolo Bonzini      * DISPLAY RFBI	48050800 - 48050bff
2569dd285b06SPaolo Bonzini      * DISPLAY VENC	48050c00 - 48050fff
2570dd285b06SPaolo Bonzini      * DISPLAY L4	48051000 - 48051fff
2571dd285b06SPaolo Bonzini      * CAMERA Top	48052000 - 480523ff
2572dd285b06SPaolo Bonzini      * CAMERA core	48052400 - 480527ff
2573dd285b06SPaolo Bonzini      * CAMERA DMA	48052800 - 48052bff
2574dd285b06SPaolo Bonzini      * CAMERA MMU	48052c00 - 48052fff
2575dd285b06SPaolo Bonzini      * CAMERA L4	48053000 - 48053fff
2576dd285b06SPaolo Bonzini      * SDMA Mod		48056000 - 48056fff
2577dd285b06SPaolo Bonzini      * SDMA L4		48057000 - 48057fff
2578dd285b06SPaolo Bonzini      * SSI Top		48058000 - 48058fff
2579dd285b06SPaolo Bonzini      * SSI GDD		48059000 - 48059fff
2580dd285b06SPaolo Bonzini      * SSI Port1	4805a000 - 4805afff
2581dd285b06SPaolo Bonzini      * SSI Port2	4805b000 - 4805bfff
2582dd285b06SPaolo Bonzini      * SSI L4		4805c000 - 4805cfff
2583dd285b06SPaolo Bonzini      * USB Mod		4805e000 - 480fefff
2584dd285b06SPaolo Bonzini      * USB L4		4805f000 - 480fffff
2585dd285b06SPaolo Bonzini      * WIN_TRACER1 Mod	48060000 - 48060fff
2586dd285b06SPaolo Bonzini      * WIN_TRACER1 L4	48061000 - 48061fff
2587dd285b06SPaolo Bonzini      * WIN_TRACER2 Mod	48062000 - 48062fff
2588dd285b06SPaolo Bonzini      * WIN_TRACER2 L4	48063000 - 48063fff
2589dd285b06SPaolo Bonzini      * WIN_TRACER3 Mod	48064000 - 48064fff
2590dd285b06SPaolo Bonzini      * WIN_TRACER3 L4	48065000 - 48065fff
2591dd285b06SPaolo Bonzini      * WIN_TRACER4 Top	48066000 - 480660ff
2592dd285b06SPaolo Bonzini      * WIN_TRACER4 ETT	48066100 - 480661ff
2593dd285b06SPaolo Bonzini      * WIN_TRACER4 WT	48066200 - 480662ff
2594dd285b06SPaolo Bonzini      * WIN_TRACER4 L4	48067000 - 48067fff
2595dd285b06SPaolo Bonzini      * XTI Mod		48068000 - 48068fff
2596dd285b06SPaolo Bonzini      * XTI L4		48069000 - 48069fff
2597dd285b06SPaolo Bonzini      * UART1 Mod	4806a000 - 4806afff
2598dd285b06SPaolo Bonzini      * UART1 L4		4806b000 - 4806bfff
2599dd285b06SPaolo Bonzini      * UART2 Mod	4806c000 - 4806cfff
2600dd285b06SPaolo Bonzini      * UART2 L4		4806d000 - 4806dfff
2601dd285b06SPaolo Bonzini      * UART3 Mod	4806e000 - 4806efff
2602dd285b06SPaolo Bonzini      * UART3 L4		4806f000 - 4806ffff
2603dd285b06SPaolo Bonzini      * I2C1 Mod		48070000 - 48070fff
2604dd285b06SPaolo Bonzini      * I2C1 L4		48071000 - 48071fff
2605dd285b06SPaolo Bonzini      * I2C2 Mod		48072000 - 48072fff
2606dd285b06SPaolo Bonzini      * I2C2 L4		48073000 - 48073fff
2607dd285b06SPaolo Bonzini      * McBSP1 Mod	48074000 - 48074fff
2608dd285b06SPaolo Bonzini      * McBSP1 L4	48075000 - 48075fff
2609dd285b06SPaolo Bonzini      * McBSP2 Mod	48076000 - 48076fff
2610dd285b06SPaolo Bonzini      * McBSP2 L4	48077000 - 48077fff
2611dd285b06SPaolo Bonzini      * GPTIMER3 Mod	48078000 - 48078fff
2612dd285b06SPaolo Bonzini      * GPTIMER3 L4	48079000 - 48079fff
2613dd285b06SPaolo Bonzini      * GPTIMER4 Mod	4807a000 - 4807afff
2614dd285b06SPaolo Bonzini      * GPTIMER4 L4	4807b000 - 4807bfff
2615dd285b06SPaolo Bonzini      * GPTIMER5 Mod	4807c000 - 4807cfff
2616dd285b06SPaolo Bonzini      * GPTIMER5 L4	4807d000 - 4807dfff
2617dd285b06SPaolo Bonzini      * GPTIMER6 Mod	4807e000 - 4807efff
2618dd285b06SPaolo Bonzini      * GPTIMER6 L4	4807f000 - 4807ffff
2619dd285b06SPaolo Bonzini      * GPTIMER7 Mod	48080000 - 48080fff
2620dd285b06SPaolo Bonzini      * GPTIMER7 L4	48081000 - 48081fff
2621dd285b06SPaolo Bonzini      * GPTIMER8 Mod	48082000 - 48082fff
2622dd285b06SPaolo Bonzini      * GPTIMER8 L4	48083000 - 48083fff
2623dd285b06SPaolo Bonzini      * GPTIMER9 Mod	48084000 - 48084fff
2624dd285b06SPaolo Bonzini      * GPTIMER9 L4	48085000 - 48085fff
2625dd285b06SPaolo Bonzini      * GPTIMER10 Mod	48086000 - 48086fff
2626dd285b06SPaolo Bonzini      * GPTIMER10 L4	48087000 - 48087fff
2627dd285b06SPaolo Bonzini      * GPTIMER11 Mod	48088000 - 48088fff
2628dd285b06SPaolo Bonzini      * GPTIMER11 L4	48089000 - 48089fff
2629dd285b06SPaolo Bonzini      * GPTIMER12 Mod	4808a000 - 4808afff
2630dd285b06SPaolo Bonzini      * GPTIMER12 L4	4808b000 - 4808bfff
2631dd285b06SPaolo Bonzini      * EAC Mod		48090000 - 48090fff
2632dd285b06SPaolo Bonzini      * EAC L4		48091000 - 48091fff
2633dd285b06SPaolo Bonzini      * FAC Mod		48092000 - 48092fff
2634dd285b06SPaolo Bonzini      * FAC L4		48093000 - 48093fff
2635dd285b06SPaolo Bonzini      * MAILBOX Mod	48094000 - 48094fff
2636dd285b06SPaolo Bonzini      * MAILBOX L4	48095000 - 48095fff
2637dd285b06SPaolo Bonzini      * SPI1 Mod		48098000 - 48098fff
2638dd285b06SPaolo Bonzini      * SPI1 L4		48099000 - 48099fff
2639dd285b06SPaolo Bonzini      * SPI2 Mod		4809a000 - 4809afff
2640dd285b06SPaolo Bonzini      * SPI2 L4		4809b000 - 4809bfff
2641dd285b06SPaolo Bonzini      * MMC/SDIO Mod	4809c000 - 4809cfff
2642dd285b06SPaolo Bonzini      * MMC/SDIO L4	4809d000 - 4809dfff
2643dd285b06SPaolo Bonzini      * MS_PRO Mod	4809e000 - 4809efff
2644dd285b06SPaolo Bonzini      * MS_PRO L4	4809f000 - 4809ffff
2645dd285b06SPaolo Bonzini      * RNG Mod		480a0000 - 480a0fff
2646dd285b06SPaolo Bonzini      * RNG L4		480a1000 - 480a1fff
2647dd285b06SPaolo Bonzini      * DES3DES Mod	480a2000 - 480a2fff
2648dd285b06SPaolo Bonzini      * DES3DES L4	480a3000 - 480a3fff
2649dd285b06SPaolo Bonzini      * SHA1MD5 Mod	480a4000 - 480a4fff
2650dd285b06SPaolo Bonzini      * SHA1MD5 L4	480a5000 - 480a5fff
2651dd285b06SPaolo Bonzini      * AES Mod		480a6000 - 480a6fff
2652dd285b06SPaolo Bonzini      * AES L4		480a7000 - 480a7fff
2653dd285b06SPaolo Bonzini      * PKA Mod		480a8000 - 480a9fff
2654dd285b06SPaolo Bonzini      * PKA L4		480aa000 - 480aafff
2655dd285b06SPaolo Bonzini      * MG Mod		480b0000 - 480b0fff
2656dd285b06SPaolo Bonzini      * MG L4		480b1000 - 480b1fff
2657dd285b06SPaolo Bonzini      * HDQ/1-wire Mod	480b2000 - 480b2fff
2658dd285b06SPaolo Bonzini      * HDQ/1-wire L4	480b3000 - 480b3fff
2659dd285b06SPaolo Bonzini      * MPU interrupt	480fe000 - 480fefff
2660dd285b06SPaolo Bonzini      * STI channel base	54000000 - 5400ffff
2661dd285b06SPaolo Bonzini      * IVA RAM		5c000000 - 5c01ffff
2662dd285b06SPaolo Bonzini      * IVA ROM		5c020000 - 5c027fff
2663dd285b06SPaolo Bonzini      * IMG_BUF_A	5c040000 - 5c040fff
2664dd285b06SPaolo Bonzini      * IMG_BUF_B	5c042000 - 5c042fff
2665dd285b06SPaolo Bonzini      * VLCDS		5c048000 - 5c0487ff
2666dd285b06SPaolo Bonzini      * IMX_COEF		5c049000 - 5c04afff
2667dd285b06SPaolo Bonzini      * IMX_CMD		5c051000 - 5c051fff
2668dd285b06SPaolo Bonzini      * VLCDQ		5c053000 - 5c0533ff
2669dd285b06SPaolo Bonzini      * VLCDH		5c054000 - 5c054fff
2670dd285b06SPaolo Bonzini      * SEQ_CMD		5c055000 - 5c055fff
2671dd285b06SPaolo Bonzini      * IMX_REG		5c056000 - 5c0560ff
2672dd285b06SPaolo Bonzini      * VLCD_REG		5c056100 - 5c0561ff
2673dd285b06SPaolo Bonzini      * SEQ_REG		5c056200 - 5c0562ff
2674dd285b06SPaolo Bonzini      * IMG_BUF_REG	5c056300 - 5c0563ff
2675dd285b06SPaolo Bonzini      * SEQIRQ_REG	5c056400 - 5c0564ff
2676dd285b06SPaolo Bonzini      * OCP_REG		5c060000 - 5c060fff
2677dd285b06SPaolo Bonzini      * SYSC_REG		5c070000 - 5c070fff
2678dd285b06SPaolo Bonzini      * MMU_REG		5d000000 - 5d000fff
2679dd285b06SPaolo Bonzini      * sDMA R		68000400 - 680005ff
2680dd285b06SPaolo Bonzini      * sDMA W		68000600 - 680007ff
2681dd285b06SPaolo Bonzini      * Display Control	68000800 - 680009ff
2682dd285b06SPaolo Bonzini      * DSP subsystem	68000a00 - 68000bff
2683dd285b06SPaolo Bonzini      * MPU subsystem	68000c00 - 68000dff
2684dd285b06SPaolo Bonzini      * IVA subsystem	68001000 - 680011ff
2685dd285b06SPaolo Bonzini      * USB		68001200 - 680013ff
2686dd285b06SPaolo Bonzini      * Camera		68001400 - 680015ff
2687dd285b06SPaolo Bonzini      * VLYNQ (firewall)	68001800 - 68001bff
2688dd285b06SPaolo Bonzini      * VLYNQ		68001e00 - 68001fff
2689dd285b06SPaolo Bonzini      * SSI		68002000 - 680021ff
2690dd285b06SPaolo Bonzini      * L4		68002400 - 680025ff
2691dd285b06SPaolo Bonzini      * DSP (firewall)	68002800 - 68002bff
2692dd285b06SPaolo Bonzini      * DSP subsystem	68002e00 - 68002fff
2693dd285b06SPaolo Bonzini      * IVA (firewall)	68003000 - 680033ff
2694dd285b06SPaolo Bonzini      * IVA		68003600 - 680037ff
2695dd285b06SPaolo Bonzini      * GFX		68003a00 - 68003bff
2696dd285b06SPaolo Bonzini      * CMDWR emulation	68003c00 - 68003dff
2697dd285b06SPaolo Bonzini      * SMS		68004000 - 680041ff
2698dd285b06SPaolo Bonzini      * OCM		68004200 - 680043ff
2699dd285b06SPaolo Bonzini      * GPMC		68004400 - 680045ff
2700dd285b06SPaolo Bonzini      * RAM (firewall)	68005000 - 680053ff
2701dd285b06SPaolo Bonzini      * RAM (err login)	68005400 - 680057ff
2702dd285b06SPaolo Bonzini      * ROM (firewall)	68005800 - 68005bff
2703dd285b06SPaolo Bonzini      * ROM (err login)	68005c00 - 68005fff
2704dd285b06SPaolo Bonzini      * GPMC (firewall)	68006000 - 680063ff
2705dd285b06SPaolo Bonzini      * GPMC (err login)	68006400 - 680067ff
2706dd285b06SPaolo Bonzini      * SMS (err login)	68006c00 - 68006fff
2707dd285b06SPaolo Bonzini      * SMS registers	68008000 - 68008fff
2708dd285b06SPaolo Bonzini      * SDRC registers	68009000 - 68009fff
2709dd285b06SPaolo Bonzini      * GPMC registers	6800a000   6800afff
2710dd285b06SPaolo Bonzini      */
2711dd285b06SPaolo Bonzini 
2712dd285b06SPaolo Bonzini     qemu_register_reset(omap2_mpu_reset, s);
2713dd285b06SPaolo Bonzini 
2714dd285b06SPaolo Bonzini     return s;
2715dd285b06SPaolo Bonzini }
2716