xref: /openbmc/qemu/hw/arm/omap1.c (revision f774a677507966222624a9b2859f06ede7608100)
1  /*
2   * TI OMAP processors emulation.
3   *
4   * Copyright (C) 2006-2008 Andrzej Zaborowski  <balrog@zabor.org>
5   *
6   * This program is free software; you can redistribute it and/or
7   * modify it under the terms of the GNU General Public License as
8   * published by the Free Software Foundation; either version 2 or
9   * (at your option) version 3 of the License.
10   *
11   * This program is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   * GNU General Public License for more details.
15   *
16   * You should have received a copy of the GNU General Public License along
17   * with this program; if not, see <http://www.gnu.org/licenses/>.
18   */
19  
20  #include "qemu/osdep.h"
21  #include "qemu/log.h"
22  #include "qemu/error-report.h"
23  #include "qemu/main-loop.h"
24  #include "qapi/error.h"
25  #include "cpu.h"
26  #include "exec/address-spaces.h"
27  #include "hw/hw.h"
28  #include "hw/irq.h"
29  #include "hw/qdev-properties.h"
30  #include "hw/arm/boot.h"
31  #include "hw/arm/omap.h"
32  #include "sysemu/blockdev.h"
33  #include "sysemu/sysemu.h"
34  #include "hw/arm/soc_dma.h"
35  #include "sysemu/qtest.h"
36  #include "sysemu/reset.h"
37  #include "sysemu/runstate.h"
38  #include "sysemu/rtc.h"
39  #include "qemu/range.h"
40  #include "hw/sysbus.h"
41  #include "qemu/cutils.h"
42  #include "qemu/bcd.h"
43  #include "target/arm/cpu-qom.h"
44  
omap_log_badwidth(const char * funcname,hwaddr addr,int sz)45  static inline void omap_log_badwidth(const char *funcname, hwaddr addr, int sz)
46  {
47      qemu_log_mask(LOG_GUEST_ERROR, "%s: %d-bit register %#08" HWADDR_PRIx "\n",
48                    funcname, 8 * sz, addr);
49  }
50  
51  /* Should signal the TCMI/GPMC */
omap_badwidth_read8(void * opaque,hwaddr addr)52  uint32_t omap_badwidth_read8(void *opaque, hwaddr addr)
53  {
54      uint8_t ret;
55  
56      omap_log_badwidth(__func__, addr, 1);
57      cpu_physical_memory_read(addr, &ret, 1);
58      return ret;
59  }
60  
omap_badwidth_write8(void * opaque,hwaddr addr,uint32_t value)61  void omap_badwidth_write8(void *opaque, hwaddr addr,
62                  uint32_t value)
63  {
64      uint8_t val8 = value;
65  
66      omap_log_badwidth(__func__, addr, 1);
67      cpu_physical_memory_write(addr, &val8, 1);
68  }
69  
omap_badwidth_read16(void * opaque,hwaddr addr)70  uint32_t omap_badwidth_read16(void *opaque, hwaddr addr)
71  {
72      uint16_t ret;
73  
74      omap_log_badwidth(__func__, addr, 2);
75      cpu_physical_memory_read(addr, &ret, 2);
76      return ret;
77  }
78  
omap_badwidth_write16(void * opaque,hwaddr addr,uint32_t value)79  void omap_badwidth_write16(void *opaque, hwaddr addr,
80                  uint32_t value)
81  {
82      uint16_t val16 = value;
83  
84      omap_log_badwidth(__func__, addr, 2);
85      cpu_physical_memory_write(addr, &val16, 2);
86  }
87  
omap_badwidth_read32(void * opaque,hwaddr addr)88  uint32_t omap_badwidth_read32(void *opaque, hwaddr addr)
89  {
90      uint32_t ret;
91  
92      omap_log_badwidth(__func__, addr, 4);
93      cpu_physical_memory_read(addr, &ret, 4);
94      return ret;
95  }
96  
omap_badwidth_write32(void * opaque,hwaddr addr,uint32_t value)97  void omap_badwidth_write32(void *opaque, hwaddr addr,
98                  uint32_t value)
99  {
100      omap_log_badwidth(__func__, addr, 4);
101      cpu_physical_memory_write(addr, &value, 4);
102  }
103  
104  /* MPU OS timers */
105  struct omap_mpu_timer_s {
106      MemoryRegion iomem;
107      qemu_irq irq;
108      omap_clk clk;
109      uint32_t val;
110      int64_t time;
111      QEMUTimer *timer;
112      QEMUBH *tick;
113      int64_t rate;
114      int it_ena;
115  
116      int enable;
117      int ptv;
118      int ar;
119      int st;
120      uint32_t reset_val;
121  };
122  
omap_timer_read(struct omap_mpu_timer_s * timer)123  static inline uint32_t omap_timer_read(struct omap_mpu_timer_s *timer)
124  {
125      uint64_t distance = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - timer->time;
126  
127      if (timer->st && timer->enable && timer->rate)
128          return timer->val - muldiv64(distance >> (timer->ptv + 1),
129                                       timer->rate, NANOSECONDS_PER_SECOND);
130      else
131          return timer->val;
132  }
133  
omap_timer_sync(struct omap_mpu_timer_s * timer)134  static inline void omap_timer_sync(struct omap_mpu_timer_s *timer)
135  {
136      timer->val = omap_timer_read(timer);
137      timer->time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
138  }
139  
omap_timer_update(struct omap_mpu_timer_s * timer)140  static inline void omap_timer_update(struct omap_mpu_timer_s *timer)
141  {
142      int64_t expires;
143  
144      if (timer->enable && timer->st && timer->rate) {
145          timer->val = timer->reset_val;	/* Should skip this on clk enable */
146          expires = muldiv64((uint64_t) timer->val << (timer->ptv + 1),
147                             NANOSECONDS_PER_SECOND, timer->rate);
148  
149          /* If timer expiry would be sooner than in about 1 ms and
150           * auto-reload isn't set, then fire immediately.  This is a hack
151           * to make systems like PalmOS run in acceptable time.  PalmOS
152           * sets the interval to a very low value and polls the status bit
153           * in a busy loop when it wants to sleep just a couple of CPU
154           * ticks.  */
155          if (expires > (NANOSECONDS_PER_SECOND >> 10) || timer->ar) {
156              timer_mod(timer->timer, timer->time + expires);
157          } else {
158              qemu_bh_schedule(timer->tick);
159          }
160      } else
161          timer_del(timer->timer);
162  }
163  
omap_timer_fire(void * opaque)164  static void omap_timer_fire(void *opaque)
165  {
166      struct omap_mpu_timer_s *timer = opaque;
167  
168      if (!timer->ar) {
169          timer->val = 0;
170          timer->st = 0;
171      }
172  
173      if (timer->it_ena)
174          /* Edge-triggered irq */
175          qemu_irq_pulse(timer->irq);
176  }
177  
omap_timer_tick(void * opaque)178  static void omap_timer_tick(void *opaque)
179  {
180      struct omap_mpu_timer_s *timer = opaque;
181  
182      omap_timer_sync(timer);
183      omap_timer_fire(timer);
184      omap_timer_update(timer);
185  }
186  
omap_timer_clk_update(void * opaque,int line,int on)187  static void omap_timer_clk_update(void *opaque, int line, int on)
188  {
189      struct omap_mpu_timer_s *timer = opaque;
190  
191      omap_timer_sync(timer);
192      timer->rate = on ? omap_clk_getrate(timer->clk) : 0;
193      omap_timer_update(timer);
194  }
195  
omap_timer_clk_setup(struct omap_mpu_timer_s * timer)196  static void omap_timer_clk_setup(struct omap_mpu_timer_s *timer)
197  {
198      omap_clk_adduser(timer->clk,
199                      qemu_allocate_irq(omap_timer_clk_update, timer, 0));
200      timer->rate = omap_clk_getrate(timer->clk);
201  }
202  
omap_mpu_timer_read(void * opaque,hwaddr addr,unsigned size)203  static uint64_t omap_mpu_timer_read(void *opaque, hwaddr addr,
204                                      unsigned size)
205  {
206      struct omap_mpu_timer_s *s = opaque;
207  
208      if (size != 4) {
209          return omap_badwidth_read32(opaque, addr);
210      }
211  
212      switch (addr) {
213      case 0x00:	/* CNTL_TIMER */
214          return (s->enable << 5) | (s->ptv << 2) | (s->ar << 1) | s->st;
215  
216      case 0x04:	/* LOAD_TIM */
217          break;
218  
219      case 0x08:	/* READ_TIM */
220          return omap_timer_read(s);
221      }
222  
223      OMAP_BAD_REG(addr);
224      return 0;
225  }
226  
omap_mpu_timer_write(void * opaque,hwaddr addr,uint64_t value,unsigned size)227  static void omap_mpu_timer_write(void *opaque, hwaddr addr,
228                                   uint64_t value, unsigned size)
229  {
230      struct omap_mpu_timer_s *s = opaque;
231  
232      if (size != 4) {
233          omap_badwidth_write32(opaque, addr, value);
234          return;
235      }
236  
237      switch (addr) {
238      case 0x00:	/* CNTL_TIMER */
239          omap_timer_sync(s);
240          s->enable = (value >> 5) & 1;
241          s->ptv = (value >> 2) & 7;
242          s->ar = (value >> 1) & 1;
243          s->st = value & 1;
244          omap_timer_update(s);
245          return;
246  
247      case 0x04:	/* LOAD_TIM */
248          s->reset_val = value;
249          return;
250  
251      case 0x08:	/* READ_TIM */
252          OMAP_RO_REG(addr);
253          break;
254  
255      default:
256          OMAP_BAD_REG(addr);
257      }
258  }
259  
260  static const MemoryRegionOps omap_mpu_timer_ops = {
261      .read = omap_mpu_timer_read,
262      .write = omap_mpu_timer_write,
263      .endianness = DEVICE_LITTLE_ENDIAN,
264  };
265  
omap_mpu_timer_reset(struct omap_mpu_timer_s * s)266  static void omap_mpu_timer_reset(struct omap_mpu_timer_s *s)
267  {
268      timer_del(s->timer);
269      s->enable = 0;
270      s->reset_val = 31337;
271      s->val = 0;
272      s->ptv = 0;
273      s->ar = 0;
274      s->st = 0;
275      s->it_ena = 1;
276  }
277  
omap_mpu_timer_init(MemoryRegion * system_memory,hwaddr base,qemu_irq irq,omap_clk clk)278  static struct omap_mpu_timer_s *omap_mpu_timer_init(MemoryRegion *system_memory,
279                  hwaddr base,
280                  qemu_irq irq, omap_clk clk)
281  {
282      struct omap_mpu_timer_s *s = g_new0(struct omap_mpu_timer_s, 1);
283  
284      s->irq = irq;
285      s->clk = clk;
286      s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_timer_tick, s);
287      s->tick = qemu_bh_new(omap_timer_fire, s);
288      omap_mpu_timer_reset(s);
289      omap_timer_clk_setup(s);
290  
291      memory_region_init_io(&s->iomem, NULL, &omap_mpu_timer_ops, s,
292                            "omap-mpu-timer", 0x100);
293  
294      memory_region_add_subregion(system_memory, base, &s->iomem);
295  
296      return s;
297  }
298  
299  /* Watchdog timer */
300  struct omap_watchdog_timer_s {
301      struct omap_mpu_timer_s timer;
302      MemoryRegion iomem;
303      uint8_t last_wr;
304      int mode;
305      int free;
306      int reset;
307  };
308  
omap_wd_timer_read(void * opaque,hwaddr addr,unsigned size)309  static uint64_t omap_wd_timer_read(void *opaque, hwaddr addr,
310                                     unsigned size)
311  {
312      struct omap_watchdog_timer_s *s = opaque;
313  
314      if (size != 2) {
315          return omap_badwidth_read16(opaque, addr);
316      }
317  
318      switch (addr) {
319      case 0x00:	/* CNTL_TIMER */
320          return (s->timer.ptv << 9) | (s->timer.ar << 8) |
321                  (s->timer.st << 7) | (s->free << 1);
322  
323      case 0x04:	/* READ_TIMER */
324          return omap_timer_read(&s->timer);
325  
326      case 0x08:	/* TIMER_MODE */
327          return s->mode << 15;
328      }
329  
330      OMAP_BAD_REG(addr);
331      return 0;
332  }
333  
omap_wd_timer_write(void * opaque,hwaddr addr,uint64_t value,unsigned size)334  static void omap_wd_timer_write(void *opaque, hwaddr addr,
335                                  uint64_t value, unsigned size)
336  {
337      struct omap_watchdog_timer_s *s = opaque;
338  
339      if (size != 2) {
340          omap_badwidth_write16(opaque, addr, value);
341          return;
342      }
343  
344      switch (addr) {
345      case 0x00:	/* CNTL_TIMER */
346          omap_timer_sync(&s->timer);
347          s->timer.ptv = (value >> 9) & 7;
348          s->timer.ar = (value >> 8) & 1;
349          s->timer.st = (value >> 7) & 1;
350          s->free = (value >> 1) & 1;
351          omap_timer_update(&s->timer);
352          break;
353  
354      case 0x04:	/* LOAD_TIMER */
355          s->timer.reset_val = value & 0xffff;
356          break;
357  
358      case 0x08:	/* TIMER_MODE */
359          if (!s->mode && ((value >> 15) & 1))
360              omap_clk_get(s->timer.clk);
361          s->mode |= (value >> 15) & 1;
362          if (s->last_wr == 0xf5) {
363              if ((value & 0xff) == 0xa0) {
364                  if (s->mode) {
365                      s->mode = 0;
366                      omap_clk_put(s->timer.clk);
367                  }
368              } else {
369                  /* XXX: on T|E hardware somehow this has no effect,
370                   * on Zire 71 it works as specified.  */
371                  s->reset = 1;
372                  qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
373              }
374          }
375          s->last_wr = value & 0xff;
376          break;
377  
378      default:
379          OMAP_BAD_REG(addr);
380      }
381  }
382  
383  static const MemoryRegionOps omap_wd_timer_ops = {
384      .read = omap_wd_timer_read,
385      .write = omap_wd_timer_write,
386      .endianness = DEVICE_NATIVE_ENDIAN,
387  };
388  
omap_wd_timer_reset(struct omap_watchdog_timer_s * s)389  static void omap_wd_timer_reset(struct omap_watchdog_timer_s *s)
390  {
391      timer_del(s->timer.timer);
392      if (!s->mode)
393          omap_clk_get(s->timer.clk);
394      s->mode = 1;
395      s->free = 1;
396      s->reset = 0;
397      s->timer.enable = 1;
398      s->timer.it_ena = 1;
399      s->timer.reset_val = 0xffff;
400      s->timer.val = 0;
401      s->timer.st = 0;
402      s->timer.ptv = 0;
403      s->timer.ar = 0;
404      omap_timer_update(&s->timer);
405  }
406  
omap_wd_timer_init(MemoryRegion * memory,hwaddr base,qemu_irq irq,omap_clk clk)407  static struct omap_watchdog_timer_s *omap_wd_timer_init(MemoryRegion *memory,
408                  hwaddr base,
409                  qemu_irq irq, omap_clk clk)
410  {
411      struct omap_watchdog_timer_s *s = g_new0(struct omap_watchdog_timer_s, 1);
412  
413      s->timer.irq = irq;
414      s->timer.clk = clk;
415      s->timer.timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_timer_tick, &s->timer);
416      omap_wd_timer_reset(s);
417      omap_timer_clk_setup(&s->timer);
418  
419      memory_region_init_io(&s->iomem, NULL, &omap_wd_timer_ops, s,
420                            "omap-wd-timer", 0x100);
421      memory_region_add_subregion(memory, base, &s->iomem);
422  
423      return s;
424  }
425  
426  /* 32-kHz timer */
427  struct omap_32khz_timer_s {
428      struct omap_mpu_timer_s timer;
429      MemoryRegion iomem;
430  };
431  
omap_os_timer_read(void * opaque,hwaddr addr,unsigned size)432  static uint64_t omap_os_timer_read(void *opaque, hwaddr addr,
433                                     unsigned size)
434  {
435      struct omap_32khz_timer_s *s = opaque;
436      int offset = addr & OMAP_MPUI_REG_MASK;
437  
438      if (size != 4) {
439          return omap_badwidth_read32(opaque, addr);
440      }
441  
442      switch (offset) {
443      case 0x00:	/* TVR */
444          return s->timer.reset_val;
445  
446      case 0x04:	/* TCR */
447          return omap_timer_read(&s->timer);
448  
449      case 0x08:	/* CR */
450          return (s->timer.ar << 3) | (s->timer.it_ena << 2) | s->timer.st;
451  
452      default:
453          break;
454      }
455      OMAP_BAD_REG(addr);
456      return 0;
457  }
458  
omap_os_timer_write(void * opaque,hwaddr addr,uint64_t value,unsigned size)459  static void omap_os_timer_write(void *opaque, hwaddr addr,
460                                  uint64_t value, unsigned size)
461  {
462      struct omap_32khz_timer_s *s = opaque;
463      int offset = addr & OMAP_MPUI_REG_MASK;
464  
465      if (size != 4) {
466          omap_badwidth_write32(opaque, addr, value);
467          return;
468      }
469  
470      switch (offset) {
471      case 0x00:	/* TVR */
472          s->timer.reset_val = value & 0x00ffffff;
473          break;
474  
475      case 0x04:	/* TCR */
476          OMAP_RO_REG(addr);
477          break;
478  
479      case 0x08:	/* CR */
480          s->timer.ar = (value >> 3) & 1;
481          s->timer.it_ena = (value >> 2) & 1;
482          if (s->timer.st != (value & 1) || (value & 2)) {
483              omap_timer_sync(&s->timer);
484              s->timer.enable = value & 1;
485              s->timer.st = value & 1;
486              omap_timer_update(&s->timer);
487          }
488          break;
489  
490      default:
491          OMAP_BAD_REG(addr);
492      }
493  }
494  
495  static const MemoryRegionOps omap_os_timer_ops = {
496      .read = omap_os_timer_read,
497      .write = omap_os_timer_write,
498      .endianness = DEVICE_NATIVE_ENDIAN,
499  };
500  
omap_os_timer_reset(struct omap_32khz_timer_s * s)501  static void omap_os_timer_reset(struct omap_32khz_timer_s *s)
502  {
503      timer_del(s->timer.timer);
504      s->timer.enable = 0;
505      s->timer.it_ena = 0;
506      s->timer.reset_val = 0x00ffffff;
507      s->timer.val = 0;
508      s->timer.st = 0;
509      s->timer.ptv = 0;
510      s->timer.ar = 1;
511  }
512  
omap_os_timer_init(MemoryRegion * memory,hwaddr base,qemu_irq irq,omap_clk clk)513  static struct omap_32khz_timer_s *omap_os_timer_init(MemoryRegion *memory,
514                  hwaddr base,
515                  qemu_irq irq, omap_clk clk)
516  {
517      struct omap_32khz_timer_s *s = g_new0(struct omap_32khz_timer_s, 1);
518  
519      s->timer.irq = irq;
520      s->timer.clk = clk;
521      s->timer.timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_timer_tick, &s->timer);
522      omap_os_timer_reset(s);
523      omap_timer_clk_setup(&s->timer);
524  
525      memory_region_init_io(&s->iomem, NULL, &omap_os_timer_ops, s,
526                            "omap-os-timer", 0x800);
527      memory_region_add_subregion(memory, base, &s->iomem);
528  
529      return s;
530  }
531  
532  /* Ultra Low-Power Device Module */
omap_ulpd_pm_read(void * opaque,hwaddr addr,unsigned size)533  static uint64_t omap_ulpd_pm_read(void *opaque, hwaddr addr,
534                                    unsigned size)
535  {
536      struct omap_mpu_state_s *s = opaque;
537      uint16_t ret;
538  
539      if (size != 2) {
540          return omap_badwidth_read16(opaque, addr);
541      }
542  
543      switch (addr) {
544      case 0x14:	/* IT_STATUS */
545          ret = s->ulpd_pm_regs[addr >> 2];
546          s->ulpd_pm_regs[addr >> 2] = 0;
547          qemu_irq_lower(qdev_get_gpio_in(s->ih[1], OMAP_INT_GAUGE_32K));
548          return ret;
549  
550      case 0x18:	/* Reserved */
551      case 0x1c:	/* Reserved */
552      case 0x20:	/* Reserved */
553      case 0x28:	/* Reserved */
554      case 0x2c:	/* Reserved */
555          OMAP_BAD_REG(addr);
556          /* fall through */
557      case 0x00:	/* COUNTER_32_LSB */
558      case 0x04:	/* COUNTER_32_MSB */
559      case 0x08:	/* COUNTER_HIGH_FREQ_LSB */
560      case 0x0c:	/* COUNTER_HIGH_FREQ_MSB */
561      case 0x10:	/* GAUGING_CTRL */
562      case 0x24:	/* SETUP_ANALOG_CELL3_ULPD1 */
563      case 0x30:	/* CLOCK_CTRL */
564      case 0x34:	/* SOFT_REQ */
565      case 0x38:	/* COUNTER_32_FIQ */
566      case 0x3c:	/* DPLL_CTRL */
567      case 0x40:	/* STATUS_REQ */
568          /* XXX: check clk::usecount state for every clock */
569      case 0x48:	/* LOCL_TIME */
570      case 0x4c:	/* APLL_CTRL */
571      case 0x50:	/* POWER_CTRL */
572          return s->ulpd_pm_regs[addr >> 2];
573      }
574  
575      OMAP_BAD_REG(addr);
576      return 0;
577  }
578  
omap_ulpd_clk_update(struct omap_mpu_state_s * s,uint16_t diff,uint16_t value)579  static inline void omap_ulpd_clk_update(struct omap_mpu_state_s *s,
580                  uint16_t diff, uint16_t value)
581  {
582      if (diff & (1 << 4))				/* USB_MCLK_EN */
583          omap_clk_onoff(omap_findclk(s, "usb_clk0"), (value >> 4) & 1);
584      if (diff & (1 << 5))				/* DIS_USB_PVCI_CLK */
585          omap_clk_onoff(omap_findclk(s, "usb_w2fc_ck"), (~value >> 5) & 1);
586  }
587  
omap_ulpd_req_update(struct omap_mpu_state_s * s,uint16_t diff,uint16_t value)588  static inline void omap_ulpd_req_update(struct omap_mpu_state_s *s,
589                  uint16_t diff, uint16_t value)
590  {
591      if (diff & (1 << 0))				/* SOFT_DPLL_REQ */
592          omap_clk_canidle(omap_findclk(s, "dpll4"), (~value >> 0) & 1);
593      if (diff & (1 << 1))				/* SOFT_COM_REQ */
594          omap_clk_canidle(omap_findclk(s, "com_mclk_out"), (~value >> 1) & 1);
595      if (diff & (1 << 2))				/* SOFT_SDW_REQ */
596          omap_clk_canidle(omap_findclk(s, "bt_mclk_out"), (~value >> 2) & 1);
597      if (diff & (1 << 3))				/* SOFT_USB_REQ */
598          omap_clk_canidle(omap_findclk(s, "usb_clk0"), (~value >> 3) & 1);
599  }
600  
omap_ulpd_pm_write(void * opaque,hwaddr addr,uint64_t value,unsigned size)601  static void omap_ulpd_pm_write(void *opaque, hwaddr addr,
602                                 uint64_t value, unsigned size)
603  {
604      struct omap_mpu_state_s *s = opaque;
605      int64_t now, ticks;
606      int div, mult;
607      static const int bypass_div[4] = { 1, 2, 4, 4 };
608      uint16_t diff;
609  
610      if (size != 2) {
611          omap_badwidth_write16(opaque, addr, value);
612          return;
613      }
614  
615      switch (addr) {
616      case 0x00:	/* COUNTER_32_LSB */
617      case 0x04:	/* COUNTER_32_MSB */
618      case 0x08:	/* COUNTER_HIGH_FREQ_LSB */
619      case 0x0c:	/* COUNTER_HIGH_FREQ_MSB */
620      case 0x14:	/* IT_STATUS */
621      case 0x40:	/* STATUS_REQ */
622          OMAP_RO_REG(addr);
623          break;
624  
625      case 0x10:	/* GAUGING_CTRL */
626          /* Bits 0 and 1 seem to be confused in the OMAP 310 TRM */
627          if ((s->ulpd_pm_regs[addr >> 2] ^ value) & 1) {
628              now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
629  
630              if (value & 1)
631                  s->ulpd_gauge_start = now;
632              else {
633                  now -= s->ulpd_gauge_start;
634  
635                  /* 32-kHz ticks */
636                  ticks = muldiv64(now, 32768, NANOSECONDS_PER_SECOND);
637                  s->ulpd_pm_regs[0x00 >> 2] = (ticks >>  0) & 0xffff;
638                  s->ulpd_pm_regs[0x04 >> 2] = (ticks >> 16) & 0xffff;
639                  if (ticks >> 32)	/* OVERFLOW_32K */
640                      s->ulpd_pm_regs[0x14 >> 2] |= 1 << 2;
641  
642                  /* High frequency ticks */
643                  ticks = muldiv64(now, 12000000, NANOSECONDS_PER_SECOND);
644                  s->ulpd_pm_regs[0x08 >> 2] = (ticks >>  0) & 0xffff;
645                  s->ulpd_pm_regs[0x0c >> 2] = (ticks >> 16) & 0xffff;
646                  if (ticks >> 32)	/* OVERFLOW_HI_FREQ */
647                      s->ulpd_pm_regs[0x14 >> 2] |= 1 << 1;
648  
649                  s->ulpd_pm_regs[0x14 >> 2] |= 1 << 0;	/* IT_GAUGING */
650                  qemu_irq_raise(qdev_get_gpio_in(s->ih[1], OMAP_INT_GAUGE_32K));
651              }
652          }
653          s->ulpd_pm_regs[addr >> 2] = value;
654          break;
655  
656      case 0x18:	/* Reserved */
657      case 0x1c:	/* Reserved */
658      case 0x20:	/* Reserved */
659      case 0x28:	/* Reserved */
660      case 0x2c:	/* Reserved */
661          OMAP_BAD_REG(addr);
662          /* fall through */
663      case 0x24:	/* SETUP_ANALOG_CELL3_ULPD1 */
664      case 0x38:	/* COUNTER_32_FIQ */
665      case 0x48:	/* LOCL_TIME */
666      case 0x50:	/* POWER_CTRL */
667          s->ulpd_pm_regs[addr >> 2] = value;
668          break;
669  
670      case 0x30:	/* CLOCK_CTRL */
671          diff = s->ulpd_pm_regs[addr >> 2] ^ value;
672          s->ulpd_pm_regs[addr >> 2] = value & 0x3f;
673          omap_ulpd_clk_update(s, diff, value);
674          break;
675  
676      case 0x34:	/* SOFT_REQ */
677          diff = s->ulpd_pm_regs[addr >> 2] ^ value;
678          s->ulpd_pm_regs[addr >> 2] = value & 0x1f;
679          omap_ulpd_req_update(s, diff, value);
680          break;
681  
682      case 0x3c:	/* DPLL_CTRL */
683          /* XXX: OMAP310 TRM claims bit 3 is PLL_ENABLE, and bit 4 is
684           * omitted altogether, probably a typo.  */
685          /* This register has identical semantics with DPLL(1:3) control
686           * registers, see omap_dpll_write() */
687          diff = s->ulpd_pm_regs[addr >> 2] & value;
688          s->ulpd_pm_regs[addr >> 2] = value & 0x2fff;
689          if (diff & (0x3ff << 2)) {
690              if (value & (1 << 4)) {			/* PLL_ENABLE */
691                  div = ((value >> 5) & 3) + 1;		/* PLL_DIV */
692                  mult = MIN((value >> 7) & 0x1f, 1);	/* PLL_MULT */
693              } else {
694                  div = bypass_div[((value >> 2) & 3)];	/* BYPASS_DIV */
695                  mult = 1;
696              }
697              omap_clk_setrate(omap_findclk(s, "dpll4"), div, mult);
698          }
699  
700          /* Enter the desired mode.  */
701          s->ulpd_pm_regs[addr >> 2] =
702                  (s->ulpd_pm_regs[addr >> 2] & 0xfffe) |
703                  ((s->ulpd_pm_regs[addr >> 2] >> 4) & 1);
704  
705          /* Act as if the lock is restored.  */
706          s->ulpd_pm_regs[addr >> 2] |= 2;
707          break;
708  
709      case 0x4c:	/* APLL_CTRL */
710          diff = s->ulpd_pm_regs[addr >> 2] & value;
711          s->ulpd_pm_regs[addr >> 2] = value & 0xf;
712          if (diff & (1 << 0))				/* APLL_NDPLL_SWITCH */
713              omap_clk_reparent(omap_findclk(s, "ck_48m"), omap_findclk(s,
714                                      (value & (1 << 0)) ? "apll" : "dpll4"));
715          break;
716  
717      default:
718          OMAP_BAD_REG(addr);
719      }
720  }
721  
722  static const MemoryRegionOps omap_ulpd_pm_ops = {
723      .read = omap_ulpd_pm_read,
724      .write = omap_ulpd_pm_write,
725      .endianness = DEVICE_NATIVE_ENDIAN,
726  };
727  
omap_ulpd_pm_reset(struct omap_mpu_state_s * mpu)728  static void omap_ulpd_pm_reset(struct omap_mpu_state_s *mpu)
729  {
730      mpu->ulpd_pm_regs[0x00 >> 2] = 0x0001;
731      mpu->ulpd_pm_regs[0x04 >> 2] = 0x0000;
732      mpu->ulpd_pm_regs[0x08 >> 2] = 0x0001;
733      mpu->ulpd_pm_regs[0x0c >> 2] = 0x0000;
734      mpu->ulpd_pm_regs[0x10 >> 2] = 0x0000;
735      mpu->ulpd_pm_regs[0x18 >> 2] = 0x01;
736      mpu->ulpd_pm_regs[0x1c >> 2] = 0x01;
737      mpu->ulpd_pm_regs[0x20 >> 2] = 0x01;
738      mpu->ulpd_pm_regs[0x24 >> 2] = 0x03ff;
739      mpu->ulpd_pm_regs[0x28 >> 2] = 0x01;
740      mpu->ulpd_pm_regs[0x2c >> 2] = 0x01;
741      omap_ulpd_clk_update(mpu, mpu->ulpd_pm_regs[0x30 >> 2], 0x0000);
742      mpu->ulpd_pm_regs[0x30 >> 2] = 0x0000;
743      omap_ulpd_req_update(mpu, mpu->ulpd_pm_regs[0x34 >> 2], 0x0000);
744      mpu->ulpd_pm_regs[0x34 >> 2] = 0x0000;
745      mpu->ulpd_pm_regs[0x38 >> 2] = 0x0001;
746      mpu->ulpd_pm_regs[0x3c >> 2] = 0x2211;
747      mpu->ulpd_pm_regs[0x40 >> 2] = 0x0000; /* FIXME: dump a real STATUS_REQ */
748      mpu->ulpd_pm_regs[0x48 >> 2] = 0x960;
749      mpu->ulpd_pm_regs[0x4c >> 2] = 0x08;
750      mpu->ulpd_pm_regs[0x50 >> 2] = 0x08;
751      omap_clk_setrate(omap_findclk(mpu, "dpll4"), 1, 4);
752      omap_clk_reparent(omap_findclk(mpu, "ck_48m"), omap_findclk(mpu, "dpll4"));
753  }
754  
omap_ulpd_pm_init(MemoryRegion * system_memory,hwaddr base,struct omap_mpu_state_s * mpu)755  static void omap_ulpd_pm_init(MemoryRegion *system_memory,
756                  hwaddr base,
757                  struct omap_mpu_state_s *mpu)
758  {
759      memory_region_init_io(&mpu->ulpd_pm_iomem, NULL, &omap_ulpd_pm_ops, mpu,
760                            "omap-ulpd-pm", 0x800);
761      memory_region_add_subregion(system_memory, base, &mpu->ulpd_pm_iomem);
762      omap_ulpd_pm_reset(mpu);
763  }
764  
765  /* OMAP Pin Configuration */
omap_pin_cfg_read(void * opaque,hwaddr addr,unsigned size)766  static uint64_t omap_pin_cfg_read(void *opaque, hwaddr addr,
767                                    unsigned size)
768  {
769      struct omap_mpu_state_s *s = opaque;
770  
771      if (size != 4) {
772          return omap_badwidth_read32(opaque, addr);
773      }
774  
775      switch (addr) {
776      case 0x00:	/* FUNC_MUX_CTRL_0 */
777      case 0x04:	/* FUNC_MUX_CTRL_1 */
778      case 0x08:	/* FUNC_MUX_CTRL_2 */
779          return s->func_mux_ctrl[addr >> 2];
780  
781      case 0x0c:	/* COMP_MODE_CTRL_0 */
782          return s->comp_mode_ctrl[0];
783  
784      case 0x10:	/* FUNC_MUX_CTRL_3 */
785      case 0x14:	/* FUNC_MUX_CTRL_4 */
786      case 0x18:	/* FUNC_MUX_CTRL_5 */
787      case 0x1c:	/* FUNC_MUX_CTRL_6 */
788      case 0x20:	/* FUNC_MUX_CTRL_7 */
789      case 0x24:	/* FUNC_MUX_CTRL_8 */
790      case 0x28:	/* FUNC_MUX_CTRL_9 */
791      case 0x2c:	/* FUNC_MUX_CTRL_A */
792      case 0x30:	/* FUNC_MUX_CTRL_B */
793      case 0x34:	/* FUNC_MUX_CTRL_C */
794      case 0x38:	/* FUNC_MUX_CTRL_D */
795          return s->func_mux_ctrl[(addr >> 2) - 1];
796  
797      case 0x40:	/* PULL_DWN_CTRL_0 */
798      case 0x44:	/* PULL_DWN_CTRL_1 */
799      case 0x48:	/* PULL_DWN_CTRL_2 */
800      case 0x4c:	/* PULL_DWN_CTRL_3 */
801          return s->pull_dwn_ctrl[(addr & 0xf) >> 2];
802  
803      case 0x50:	/* GATE_INH_CTRL_0 */
804          return s->gate_inh_ctrl[0];
805  
806      case 0x60:	/* VOLTAGE_CTRL_0 */
807          return s->voltage_ctrl[0];
808  
809      case 0x70:	/* TEST_DBG_CTRL_0 */
810          return s->test_dbg_ctrl[0];
811  
812      case 0x80:	/* MOD_CONF_CTRL_0 */
813          return s->mod_conf_ctrl[0];
814      }
815  
816      OMAP_BAD_REG(addr);
817      return 0;
818  }
819  
omap_pin_funcmux0_update(struct omap_mpu_state_s * s,uint32_t diff,uint32_t value)820  static inline void omap_pin_funcmux0_update(struct omap_mpu_state_s *s,
821                  uint32_t diff, uint32_t value)
822  {
823      if (s->compat1509) {
824          if (diff & (1 << 9))			/* BLUETOOTH */
825              omap_clk_onoff(omap_findclk(s, "bt_mclk_out"),
826                              (~value >> 9) & 1);
827          if (diff & (1 << 7))			/* USB.CLKO */
828              omap_clk_onoff(omap_findclk(s, "usb.clko"),
829                              (value >> 7) & 1);
830      }
831  }
832  
omap_pin_funcmux1_update(struct omap_mpu_state_s * s,uint32_t diff,uint32_t value)833  static inline void omap_pin_funcmux1_update(struct omap_mpu_state_s *s,
834                  uint32_t diff, uint32_t value)
835  {
836      if (s->compat1509) {
837          if (diff & (1U << 31)) {
838              /* MCBSP3_CLK_HIZ_DI */
839              omap_clk_onoff(omap_findclk(s, "mcbsp3.clkx"), (value >> 31) & 1);
840          }
841          if (diff & (1 << 1)) {
842              /* CLK32K */
843              omap_clk_onoff(omap_findclk(s, "clk32k_out"), (~value >> 1) & 1);
844          }
845      }
846  }
847  
omap_pin_modconf1_update(struct omap_mpu_state_s * s,uint32_t diff,uint32_t value)848  static inline void omap_pin_modconf1_update(struct omap_mpu_state_s *s,
849                  uint32_t diff, uint32_t value)
850  {
851      if (diff & (1U << 31)) {
852          /* CONF_MOD_UART3_CLK_MODE_R */
853          omap_clk_reparent(omap_findclk(s, "uart3_ck"),
854                            omap_findclk(s, ((value >> 31) & 1) ?
855                                         "ck_48m" : "armper_ck"));
856      }
857      if (diff & (1 << 30))			/* CONF_MOD_UART2_CLK_MODE_R */
858           omap_clk_reparent(omap_findclk(s, "uart2_ck"),
859                           omap_findclk(s, ((value >> 30) & 1) ?
860                                   "ck_48m" : "armper_ck"));
861      if (diff & (1 << 29))			/* CONF_MOD_UART1_CLK_MODE_R */
862           omap_clk_reparent(omap_findclk(s, "uart1_ck"),
863                           omap_findclk(s, ((value >> 29) & 1) ?
864                                   "ck_48m" : "armper_ck"));
865      if (diff & (1 << 23))			/* CONF_MOD_MMC_SD_CLK_REQ_R */
866           omap_clk_reparent(omap_findclk(s, "mmc_ck"),
867                           omap_findclk(s, ((value >> 23) & 1) ?
868                                   "ck_48m" : "armper_ck"));
869      if (diff & (1 << 12))			/* CONF_MOD_COM_MCLK_12_48_S */
870           omap_clk_reparent(omap_findclk(s, "com_mclk_out"),
871                           omap_findclk(s, ((value >> 12) & 1) ?
872                                   "ck_48m" : "armper_ck"));
873      if (diff & (1 << 9))			/* CONF_MOD_USB_HOST_HHC_UHO */
874           omap_clk_onoff(omap_findclk(s, "usb_hhc_ck"), (value >> 9) & 1);
875  }
876  
omap_pin_cfg_write(void * opaque,hwaddr addr,uint64_t value,unsigned size)877  static void omap_pin_cfg_write(void *opaque, hwaddr addr,
878                                 uint64_t value, unsigned size)
879  {
880      struct omap_mpu_state_s *s = opaque;
881      uint32_t diff;
882  
883      if (size != 4) {
884          omap_badwidth_write32(opaque, addr, value);
885          return;
886      }
887  
888      switch (addr) {
889      case 0x00:	/* FUNC_MUX_CTRL_0 */
890          diff = s->func_mux_ctrl[addr >> 2] ^ value;
891          s->func_mux_ctrl[addr >> 2] = value;
892          omap_pin_funcmux0_update(s, diff, value);
893          return;
894  
895      case 0x04:	/* FUNC_MUX_CTRL_1 */
896          diff = s->func_mux_ctrl[addr >> 2] ^ value;
897          s->func_mux_ctrl[addr >> 2] = value;
898          omap_pin_funcmux1_update(s, diff, value);
899          return;
900  
901      case 0x08:	/* FUNC_MUX_CTRL_2 */
902          s->func_mux_ctrl[addr >> 2] = value;
903          return;
904  
905      case 0x0c:	/* COMP_MODE_CTRL_0 */
906          s->comp_mode_ctrl[0] = value;
907          s->compat1509 = (value != 0x0000eaef);
908          omap_pin_funcmux0_update(s, ~0, s->func_mux_ctrl[0]);
909          omap_pin_funcmux1_update(s, ~0, s->func_mux_ctrl[1]);
910          return;
911  
912      case 0x10:	/* FUNC_MUX_CTRL_3 */
913      case 0x14:	/* FUNC_MUX_CTRL_4 */
914      case 0x18:	/* FUNC_MUX_CTRL_5 */
915      case 0x1c:	/* FUNC_MUX_CTRL_6 */
916      case 0x20:	/* FUNC_MUX_CTRL_7 */
917      case 0x24:	/* FUNC_MUX_CTRL_8 */
918      case 0x28:	/* FUNC_MUX_CTRL_9 */
919      case 0x2c:	/* FUNC_MUX_CTRL_A */
920      case 0x30:	/* FUNC_MUX_CTRL_B */
921      case 0x34:	/* FUNC_MUX_CTRL_C */
922      case 0x38:	/* FUNC_MUX_CTRL_D */
923          s->func_mux_ctrl[(addr >> 2) - 1] = value;
924          return;
925  
926      case 0x40:	/* PULL_DWN_CTRL_0 */
927      case 0x44:	/* PULL_DWN_CTRL_1 */
928      case 0x48:	/* PULL_DWN_CTRL_2 */
929      case 0x4c:	/* PULL_DWN_CTRL_3 */
930          s->pull_dwn_ctrl[(addr & 0xf) >> 2] = value;
931          return;
932  
933      case 0x50:	/* GATE_INH_CTRL_0 */
934          s->gate_inh_ctrl[0] = value;
935          return;
936  
937      case 0x60:	/* VOLTAGE_CTRL_0 */
938          s->voltage_ctrl[0] = value;
939          return;
940  
941      case 0x70:	/* TEST_DBG_CTRL_0 */
942          s->test_dbg_ctrl[0] = value;
943          return;
944  
945      case 0x80:	/* MOD_CONF_CTRL_0 */
946          diff = s->mod_conf_ctrl[0] ^ value;
947          s->mod_conf_ctrl[0] = value;
948          omap_pin_modconf1_update(s, diff, value);
949          return;
950  
951      default:
952          OMAP_BAD_REG(addr);
953      }
954  }
955  
956  static const MemoryRegionOps omap_pin_cfg_ops = {
957      .read = omap_pin_cfg_read,
958      .write = omap_pin_cfg_write,
959      .endianness = DEVICE_NATIVE_ENDIAN,
960  };
961  
omap_pin_cfg_reset(struct omap_mpu_state_s * mpu)962  static void omap_pin_cfg_reset(struct omap_mpu_state_s *mpu)
963  {
964      /* Start in Compatibility Mode.  */
965      mpu->compat1509 = 1;
966      omap_pin_funcmux0_update(mpu, mpu->func_mux_ctrl[0], 0);
967      omap_pin_funcmux1_update(mpu, mpu->func_mux_ctrl[1], 0);
968      omap_pin_modconf1_update(mpu, mpu->mod_conf_ctrl[0], 0);
969      memset(mpu->func_mux_ctrl, 0, sizeof(mpu->func_mux_ctrl));
970      memset(mpu->comp_mode_ctrl, 0, sizeof(mpu->comp_mode_ctrl));
971      memset(mpu->pull_dwn_ctrl, 0, sizeof(mpu->pull_dwn_ctrl));
972      memset(mpu->gate_inh_ctrl, 0, sizeof(mpu->gate_inh_ctrl));
973      memset(mpu->voltage_ctrl, 0, sizeof(mpu->voltage_ctrl));
974      memset(mpu->test_dbg_ctrl, 0, sizeof(mpu->test_dbg_ctrl));
975      memset(mpu->mod_conf_ctrl, 0, sizeof(mpu->mod_conf_ctrl));
976  }
977  
omap_pin_cfg_init(MemoryRegion * system_memory,hwaddr base,struct omap_mpu_state_s * mpu)978  static void omap_pin_cfg_init(MemoryRegion *system_memory,
979                  hwaddr base,
980                  struct omap_mpu_state_s *mpu)
981  {
982      memory_region_init_io(&mpu->pin_cfg_iomem, NULL, &omap_pin_cfg_ops, mpu,
983                            "omap-pin-cfg", 0x800);
984      memory_region_add_subregion(system_memory, base, &mpu->pin_cfg_iomem);
985      omap_pin_cfg_reset(mpu);
986  }
987  
988  /* Device Identification, Die Identification */
omap_id_read(void * opaque,hwaddr addr,unsigned size)989  static uint64_t omap_id_read(void *opaque, hwaddr addr,
990                               unsigned size)
991  {
992      struct omap_mpu_state_s *s = opaque;
993  
994      if (size != 4) {
995          return omap_badwidth_read32(opaque, addr);
996      }
997  
998      switch (addr) {
999      case 0xfffe1800:	/* DIE_ID_LSB */
1000          return 0xc9581f0e;
1001      case 0xfffe1804:	/* DIE_ID_MSB */
1002          return 0xa8858bfa;
1003  
1004      case 0xfffe2000:	/* PRODUCT_ID_LSB */
1005          return 0x00aaaafc;
1006      case 0xfffe2004:	/* PRODUCT_ID_MSB */
1007          return 0xcafeb574;
1008  
1009      case 0xfffed400:	/* JTAG_ID_LSB */
1010          switch (s->mpu_model) {
1011          case omap310:
1012              return 0x03310315;
1013          case omap1510:
1014              return 0x03310115;
1015          default:
1016              hw_error("%s: bad mpu model\n", __func__);
1017          }
1018          break;
1019  
1020      case 0xfffed404:	/* JTAG_ID_MSB */
1021          switch (s->mpu_model) {
1022          case omap310:
1023              return 0xfb57402f;
1024          case omap1510:
1025              return 0xfb47002f;
1026          default:
1027              hw_error("%s: bad mpu model\n", __func__);
1028          }
1029          break;
1030      }
1031  
1032      OMAP_BAD_REG(addr);
1033      return 0;
1034  }
1035  
omap_id_write(void * opaque,hwaddr addr,uint64_t value,unsigned size)1036  static void omap_id_write(void *opaque, hwaddr addr,
1037                            uint64_t value, unsigned size)
1038  {
1039      if (size != 4) {
1040          omap_badwidth_write32(opaque, addr, value);
1041          return;
1042      }
1043  
1044      OMAP_BAD_REG(addr);
1045  }
1046  
1047  static const MemoryRegionOps omap_id_ops = {
1048      .read = omap_id_read,
1049      .write = omap_id_write,
1050      .endianness = DEVICE_NATIVE_ENDIAN,
1051  };
1052  
omap_id_init(MemoryRegion * memory,struct omap_mpu_state_s * mpu)1053  static void omap_id_init(MemoryRegion *memory, struct omap_mpu_state_s *mpu)
1054  {
1055      memory_region_init_io(&mpu->id_iomem, NULL, &omap_id_ops, mpu,
1056                            "omap-id", 0x100000000ULL);
1057      memory_region_init_alias(&mpu->id_iomem_e18, NULL, "omap-id-e18", &mpu->id_iomem,
1058                               0xfffe1800, 0x800);
1059      memory_region_add_subregion(memory, 0xfffe1800, &mpu->id_iomem_e18);
1060      memory_region_init_alias(&mpu->id_iomem_ed4, NULL, "omap-id-ed4", &mpu->id_iomem,
1061                               0xfffed400, 0x100);
1062      memory_region_add_subregion(memory, 0xfffed400, &mpu->id_iomem_ed4);
1063      if (!cpu_is_omap15xx(mpu)) {
1064          memory_region_init_alias(&mpu->id_iomem_ed4, NULL, "omap-id-e20",
1065                                   &mpu->id_iomem, 0xfffe2000, 0x800);
1066          memory_region_add_subregion(memory, 0xfffe2000, &mpu->id_iomem_e20);
1067      }
1068  }
1069  
1070  /* MPUI Control (Dummy) */
omap_mpui_read(void * opaque,hwaddr addr,unsigned size)1071  static uint64_t omap_mpui_read(void *opaque, hwaddr addr,
1072                                 unsigned size)
1073  {
1074      struct omap_mpu_state_s *s = opaque;
1075  
1076      if (size != 4) {
1077          return omap_badwidth_read32(opaque, addr);
1078      }
1079  
1080      switch (addr) {
1081      case 0x00:	/* CTRL */
1082          return s->mpui_ctrl;
1083      case 0x04:	/* DEBUG_ADDR */
1084          return 0x01ffffff;
1085      case 0x08:	/* DEBUG_DATA */
1086          return 0xffffffff;
1087      case 0x0c:	/* DEBUG_FLAG */
1088          return 0x00000800;
1089      case 0x10:	/* STATUS */
1090          return 0x00000000;
1091  
1092      /* Not in OMAP310 */
1093      case 0x14:	/* DSP_STATUS */
1094      case 0x18:	/* DSP_BOOT_CONFIG */
1095          return 0x00000000;
1096      case 0x1c:	/* DSP_MPUI_CONFIG */
1097          return 0x0000ffff;
1098      }
1099  
1100      OMAP_BAD_REG(addr);
1101      return 0;
1102  }
1103  
omap_mpui_write(void * opaque,hwaddr addr,uint64_t value,unsigned size)1104  static void omap_mpui_write(void *opaque, hwaddr addr,
1105                              uint64_t value, unsigned size)
1106  {
1107      struct omap_mpu_state_s *s = opaque;
1108  
1109      if (size != 4) {
1110          omap_badwidth_write32(opaque, addr, value);
1111          return;
1112      }
1113  
1114      switch (addr) {
1115      case 0x00:	/* CTRL */
1116          s->mpui_ctrl = value & 0x007fffff;
1117          break;
1118  
1119      case 0x04:	/* DEBUG_ADDR */
1120      case 0x08:	/* DEBUG_DATA */
1121      case 0x0c:	/* DEBUG_FLAG */
1122      case 0x10:	/* STATUS */
1123      /* Not in OMAP310 */
1124      case 0x14:	/* DSP_STATUS */
1125          OMAP_RO_REG(addr);
1126          break;
1127      case 0x18:	/* DSP_BOOT_CONFIG */
1128      case 0x1c:	/* DSP_MPUI_CONFIG */
1129          break;
1130  
1131      default:
1132          OMAP_BAD_REG(addr);
1133      }
1134  }
1135  
1136  static const MemoryRegionOps omap_mpui_ops = {
1137      .read = omap_mpui_read,
1138      .write = omap_mpui_write,
1139      .endianness = DEVICE_NATIVE_ENDIAN,
1140  };
1141  
omap_mpui_reset(struct omap_mpu_state_s * s)1142  static void omap_mpui_reset(struct omap_mpu_state_s *s)
1143  {
1144      s->mpui_ctrl = 0x0003ff1b;
1145  }
1146  
omap_mpui_init(MemoryRegion * memory,hwaddr base,struct omap_mpu_state_s * mpu)1147  static void omap_mpui_init(MemoryRegion *memory, hwaddr base,
1148                  struct omap_mpu_state_s *mpu)
1149  {
1150      memory_region_init_io(&mpu->mpui_iomem, NULL, &omap_mpui_ops, mpu,
1151                            "omap-mpui", 0x100);
1152      memory_region_add_subregion(memory, base, &mpu->mpui_iomem);
1153  
1154      omap_mpui_reset(mpu);
1155  }
1156  
1157  /* TIPB Bridges */
1158  struct omap_tipb_bridge_s {
1159      qemu_irq abort;
1160      MemoryRegion iomem;
1161  
1162      int width_intr;
1163      uint16_t control;
1164      uint16_t alloc;
1165      uint16_t buffer;
1166      uint16_t enh_control;
1167  };
1168  
omap_tipb_bridge_read(void * opaque,hwaddr addr,unsigned size)1169  static uint64_t omap_tipb_bridge_read(void *opaque, hwaddr addr,
1170                                        unsigned size)
1171  {
1172      struct omap_tipb_bridge_s *s = opaque;
1173  
1174      if (size < 2) {
1175          return omap_badwidth_read16(opaque, addr);
1176      }
1177  
1178      switch (addr) {
1179      case 0x00:	/* TIPB_CNTL */
1180          return s->control;
1181      case 0x04:	/* TIPB_BUS_ALLOC */
1182          return s->alloc;
1183      case 0x08:	/* MPU_TIPB_CNTL */
1184          return s->buffer;
1185      case 0x0c:	/* ENHANCED_TIPB_CNTL */
1186          return s->enh_control;
1187      case 0x10:	/* ADDRESS_DBG */
1188      case 0x14:	/* DATA_DEBUG_LOW */
1189      case 0x18:	/* DATA_DEBUG_HIGH */
1190          return 0xffff;
1191      case 0x1c:	/* DEBUG_CNTR_SIG */
1192          return 0x00f8;
1193      }
1194  
1195      OMAP_BAD_REG(addr);
1196      return 0;
1197  }
1198  
omap_tipb_bridge_write(void * opaque,hwaddr addr,uint64_t value,unsigned size)1199  static void omap_tipb_bridge_write(void *opaque, hwaddr addr,
1200                                     uint64_t value, unsigned size)
1201  {
1202      struct omap_tipb_bridge_s *s = opaque;
1203  
1204      if (size < 2) {
1205          omap_badwidth_write16(opaque, addr, value);
1206          return;
1207      }
1208  
1209      switch (addr) {
1210      case 0x00:	/* TIPB_CNTL */
1211          s->control = value & 0xffff;
1212          break;
1213  
1214      case 0x04:	/* TIPB_BUS_ALLOC */
1215          s->alloc = value & 0x003f;
1216          break;
1217  
1218      case 0x08:	/* MPU_TIPB_CNTL */
1219          s->buffer = value & 0x0003;
1220          break;
1221  
1222      case 0x0c:	/* ENHANCED_TIPB_CNTL */
1223          s->width_intr = !(value & 2);
1224          s->enh_control = value & 0x000f;
1225          break;
1226  
1227      case 0x10:	/* ADDRESS_DBG */
1228      case 0x14:	/* DATA_DEBUG_LOW */
1229      case 0x18:	/* DATA_DEBUG_HIGH */
1230      case 0x1c:	/* DEBUG_CNTR_SIG */
1231          OMAP_RO_REG(addr);
1232          break;
1233  
1234      default:
1235          OMAP_BAD_REG(addr);
1236      }
1237  }
1238  
1239  static const MemoryRegionOps omap_tipb_bridge_ops = {
1240      .read = omap_tipb_bridge_read,
1241      .write = omap_tipb_bridge_write,
1242      .endianness = DEVICE_NATIVE_ENDIAN,
1243  };
1244  
omap_tipb_bridge_reset(struct omap_tipb_bridge_s * s)1245  static void omap_tipb_bridge_reset(struct omap_tipb_bridge_s *s)
1246  {
1247      s->control = 0xffff;
1248      s->alloc = 0x0009;
1249      s->buffer = 0x0000;
1250      s->enh_control = 0x000f;
1251  }
1252  
omap_tipb_bridge_init(MemoryRegion * memory,hwaddr base,qemu_irq abort_irq,omap_clk clk)1253  static struct omap_tipb_bridge_s *omap_tipb_bridge_init(
1254      MemoryRegion *memory, hwaddr base,
1255      qemu_irq abort_irq, omap_clk clk)
1256  {
1257      struct omap_tipb_bridge_s *s = g_new0(struct omap_tipb_bridge_s, 1);
1258  
1259      s->abort = abort_irq;
1260      omap_tipb_bridge_reset(s);
1261  
1262      memory_region_init_io(&s->iomem, NULL, &omap_tipb_bridge_ops, s,
1263                            "omap-tipb-bridge", 0x100);
1264      memory_region_add_subregion(memory, base, &s->iomem);
1265  
1266      return s;
1267  }
1268  
1269  /* Dummy Traffic Controller's Memory Interface */
omap_tcmi_read(void * opaque,hwaddr addr,unsigned size)1270  static uint64_t omap_tcmi_read(void *opaque, hwaddr addr,
1271                                 unsigned size)
1272  {
1273      struct omap_mpu_state_s *s = opaque;
1274      uint32_t ret;
1275  
1276      if (size != 4) {
1277          return omap_badwidth_read32(opaque, addr);
1278      }
1279  
1280      switch (addr) {
1281      case 0x00:	/* IMIF_PRIO */
1282      case 0x04:	/* EMIFS_PRIO */
1283      case 0x08:	/* EMIFF_PRIO */
1284      case 0x0c:	/* EMIFS_CONFIG */
1285      case 0x10:	/* EMIFS_CS0_CONFIG */
1286      case 0x14:	/* EMIFS_CS1_CONFIG */
1287      case 0x18:	/* EMIFS_CS2_CONFIG */
1288      case 0x1c:	/* EMIFS_CS3_CONFIG */
1289      case 0x24:	/* EMIFF_MRS */
1290      case 0x28:	/* TIMEOUT1 */
1291      case 0x2c:	/* TIMEOUT2 */
1292      case 0x30:	/* TIMEOUT3 */
1293      case 0x3c:	/* EMIFF_SDRAM_CONFIG_2 */
1294      case 0x40:	/* EMIFS_CFG_DYN_WAIT */
1295          return s->tcmi_regs[addr >> 2];
1296  
1297      case 0x20:	/* EMIFF_SDRAM_CONFIG */
1298          ret = s->tcmi_regs[addr >> 2];
1299          s->tcmi_regs[addr >> 2] &= ~1; /* XXX: Clear SLRF on SDRAM access */
1300          /* XXX: We can try using the VGA_DIRTY flag for this */
1301          return ret;
1302      }
1303  
1304      OMAP_BAD_REG(addr);
1305      return 0;
1306  }
1307  
omap_tcmi_write(void * opaque,hwaddr addr,uint64_t value,unsigned size)1308  static void omap_tcmi_write(void *opaque, hwaddr addr,
1309                              uint64_t value, unsigned size)
1310  {
1311      struct omap_mpu_state_s *s = opaque;
1312  
1313      if (size != 4) {
1314          omap_badwidth_write32(opaque, addr, value);
1315          return;
1316      }
1317  
1318      switch (addr) {
1319      case 0x00:	/* IMIF_PRIO */
1320      case 0x04:	/* EMIFS_PRIO */
1321      case 0x08:	/* EMIFF_PRIO */
1322      case 0x10:	/* EMIFS_CS0_CONFIG */
1323      case 0x14:	/* EMIFS_CS1_CONFIG */
1324      case 0x18:	/* EMIFS_CS2_CONFIG */
1325      case 0x1c:	/* EMIFS_CS3_CONFIG */
1326      case 0x20:	/* EMIFF_SDRAM_CONFIG */
1327      case 0x24:	/* EMIFF_MRS */
1328      case 0x28:	/* TIMEOUT1 */
1329      case 0x2c:	/* TIMEOUT2 */
1330      case 0x30:	/* TIMEOUT3 */
1331      case 0x3c:	/* EMIFF_SDRAM_CONFIG_2 */
1332      case 0x40:	/* EMIFS_CFG_DYN_WAIT */
1333          s->tcmi_regs[addr >> 2] = value;
1334          break;
1335      case 0x0c:	/* EMIFS_CONFIG */
1336          s->tcmi_regs[addr >> 2] = (value & 0xf) | (1 << 4);
1337          break;
1338  
1339      default:
1340          OMAP_BAD_REG(addr);
1341      }
1342  }
1343  
1344  static const MemoryRegionOps omap_tcmi_ops = {
1345      .read = omap_tcmi_read,
1346      .write = omap_tcmi_write,
1347      .endianness = DEVICE_NATIVE_ENDIAN,
1348  };
1349  
omap_tcmi_reset(struct omap_mpu_state_s * mpu)1350  static void omap_tcmi_reset(struct omap_mpu_state_s *mpu)
1351  {
1352      mpu->tcmi_regs[0x00 >> 2] = 0x00000000;
1353      mpu->tcmi_regs[0x04 >> 2] = 0x00000000;
1354      mpu->tcmi_regs[0x08 >> 2] = 0x00000000;
1355      mpu->tcmi_regs[0x0c >> 2] = 0x00000010;
1356      mpu->tcmi_regs[0x10 >> 2] = 0x0010fffb;
1357      mpu->tcmi_regs[0x14 >> 2] = 0x0010fffb;
1358      mpu->tcmi_regs[0x18 >> 2] = 0x0010fffb;
1359      mpu->tcmi_regs[0x1c >> 2] = 0x0010fffb;
1360      mpu->tcmi_regs[0x20 >> 2] = 0x00618800;
1361      mpu->tcmi_regs[0x24 >> 2] = 0x00000037;
1362      mpu->tcmi_regs[0x28 >> 2] = 0x00000000;
1363      mpu->tcmi_regs[0x2c >> 2] = 0x00000000;
1364      mpu->tcmi_regs[0x30 >> 2] = 0x00000000;
1365      mpu->tcmi_regs[0x3c >> 2] = 0x00000003;
1366      mpu->tcmi_regs[0x40 >> 2] = 0x00000000;
1367  }
1368  
omap_tcmi_init(MemoryRegion * memory,hwaddr base,struct omap_mpu_state_s * mpu)1369  static void omap_tcmi_init(MemoryRegion *memory, hwaddr base,
1370                  struct omap_mpu_state_s *mpu)
1371  {
1372      memory_region_init_io(&mpu->tcmi_iomem, NULL, &omap_tcmi_ops, mpu,
1373                            "omap-tcmi", 0x100);
1374      memory_region_add_subregion(memory, base, &mpu->tcmi_iomem);
1375      omap_tcmi_reset(mpu);
1376  }
1377  
1378  /* Digital phase-locked loops control */
1379  struct dpll_ctl_s {
1380      MemoryRegion iomem;
1381      uint16_t mode;
1382      omap_clk dpll;
1383  };
1384  
omap_dpll_read(void * opaque,hwaddr addr,unsigned size)1385  static uint64_t omap_dpll_read(void *opaque, hwaddr addr,
1386                                 unsigned size)
1387  {
1388      struct dpll_ctl_s *s = opaque;
1389  
1390      if (size != 2) {
1391          return omap_badwidth_read16(opaque, addr);
1392      }
1393  
1394      if (addr == 0x00)	/* CTL_REG */
1395          return s->mode;
1396  
1397      OMAP_BAD_REG(addr);
1398      return 0;
1399  }
1400  
omap_dpll_write(void * opaque,hwaddr addr,uint64_t value,unsigned size)1401  static void omap_dpll_write(void *opaque, hwaddr addr,
1402                              uint64_t value, unsigned size)
1403  {
1404      struct dpll_ctl_s *s = opaque;
1405      uint16_t diff;
1406      static const int bypass_div[4] = { 1, 2, 4, 4 };
1407      int div, mult;
1408  
1409      if (size != 2) {
1410          omap_badwidth_write16(opaque, addr, value);
1411          return;
1412      }
1413  
1414      if (addr == 0x00) {	/* CTL_REG */
1415          /* See omap_ulpd_pm_write() too */
1416          diff = s->mode & value;
1417          s->mode = value & 0x2fff;
1418          if (diff & (0x3ff << 2)) {
1419              if (value & (1 << 4)) {			/* PLL_ENABLE */
1420                  div = ((value >> 5) & 3) + 1;		/* PLL_DIV */
1421                  mult = MIN((value >> 7) & 0x1f, 1);	/* PLL_MULT */
1422              } else {
1423                  div = bypass_div[((value >> 2) & 3)];	/* BYPASS_DIV */
1424                  mult = 1;
1425              }
1426              omap_clk_setrate(s->dpll, div, mult);
1427          }
1428  
1429          /* Enter the desired mode.  */
1430          s->mode = (s->mode & 0xfffe) | ((s->mode >> 4) & 1);
1431  
1432          /* Act as if the lock is restored.  */
1433          s->mode |= 2;
1434      } else {
1435          OMAP_BAD_REG(addr);
1436      }
1437  }
1438  
1439  static const MemoryRegionOps omap_dpll_ops = {
1440      .read = omap_dpll_read,
1441      .write = omap_dpll_write,
1442      .endianness = DEVICE_NATIVE_ENDIAN,
1443  };
1444  
omap_dpll_reset(struct dpll_ctl_s * s)1445  static void omap_dpll_reset(struct dpll_ctl_s *s)
1446  {
1447      s->mode = 0x2002;
1448      omap_clk_setrate(s->dpll, 1, 1);
1449  }
1450  
omap_dpll_init(MemoryRegion * memory,hwaddr base,omap_clk clk)1451  static struct dpll_ctl_s  *omap_dpll_init(MemoryRegion *memory,
1452                             hwaddr base, omap_clk clk)
1453  {
1454      struct dpll_ctl_s *s = g_malloc0(sizeof(*s));
1455      memory_region_init_io(&s->iomem, NULL, &omap_dpll_ops, s, "omap-dpll", 0x100);
1456  
1457      s->dpll = clk;
1458      omap_dpll_reset(s);
1459  
1460      memory_region_add_subregion(memory, base, &s->iomem);
1461      return s;
1462  }
1463  
1464  /* MPU Clock/Reset/Power Mode Control */
omap_clkm_read(void * opaque,hwaddr addr,unsigned size)1465  static uint64_t omap_clkm_read(void *opaque, hwaddr addr,
1466                                 unsigned size)
1467  {
1468      struct omap_mpu_state_s *s = opaque;
1469  
1470      if (size != 2) {
1471          return omap_badwidth_read16(opaque, addr);
1472      }
1473  
1474      switch (addr) {
1475      case 0x00:	/* ARM_CKCTL */
1476          return s->clkm.arm_ckctl;
1477  
1478      case 0x04:	/* ARM_IDLECT1 */
1479          return s->clkm.arm_idlect1;
1480  
1481      case 0x08:	/* ARM_IDLECT2 */
1482          return s->clkm.arm_idlect2;
1483  
1484      case 0x0c:	/* ARM_EWUPCT */
1485          return s->clkm.arm_ewupct;
1486  
1487      case 0x10:	/* ARM_RSTCT1 */
1488          return s->clkm.arm_rstct1;
1489  
1490      case 0x14:	/* ARM_RSTCT2 */
1491          return s->clkm.arm_rstct2;
1492  
1493      case 0x18:	/* ARM_SYSST */
1494          return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start;
1495  
1496      case 0x1c:	/* ARM_CKOUT1 */
1497          return s->clkm.arm_ckout1;
1498  
1499      case 0x20:	/* ARM_CKOUT2 */
1500          break;
1501      }
1502  
1503      OMAP_BAD_REG(addr);
1504      return 0;
1505  }
1506  
omap_clkm_ckctl_update(struct omap_mpu_state_s * s,uint16_t diff,uint16_t value)1507  static inline void omap_clkm_ckctl_update(struct omap_mpu_state_s *s,
1508                  uint16_t diff, uint16_t value)
1509  {
1510      omap_clk clk;
1511  
1512      if (diff & (1 << 14)) {				/* ARM_INTHCK_SEL */
1513          if (value & (1 << 14))
1514              /* Reserved */;
1515          else {
1516              clk = omap_findclk(s, "arminth_ck");
1517              omap_clk_reparent(clk, omap_findclk(s, "tc_ck"));
1518          }
1519      }
1520      if (diff & (1 << 12)) {				/* ARM_TIMXO */
1521          clk = omap_findclk(s, "armtim_ck");
1522          if (value & (1 << 12))
1523              omap_clk_reparent(clk, omap_findclk(s, "clkin"));
1524          else
1525              omap_clk_reparent(clk, omap_findclk(s, "ck_gen1"));
1526      }
1527      /* XXX: en_dspck */
1528      if (diff & (3 << 10)) {				/* DSPMMUDIV */
1529          clk = omap_findclk(s, "dspmmu_ck");
1530          omap_clk_setrate(clk, 1 << ((value >> 10) & 3), 1);
1531      }
1532      if (diff & (3 << 8)) {				/* TCDIV */
1533          clk = omap_findclk(s, "tc_ck");
1534          omap_clk_setrate(clk, 1 << ((value >> 8) & 3), 1);
1535      }
1536      if (diff & (3 << 6)) {				/* DSPDIV */
1537          clk = omap_findclk(s, "dsp_ck");
1538          omap_clk_setrate(clk, 1 << ((value >> 6) & 3), 1);
1539      }
1540      if (diff & (3 << 4)) {				/* ARMDIV */
1541          clk = omap_findclk(s, "arm_ck");
1542          omap_clk_setrate(clk, 1 << ((value >> 4) & 3), 1);
1543      }
1544      if (diff & (3 << 2)) {				/* LCDDIV */
1545          clk = omap_findclk(s, "lcd_ck");
1546          omap_clk_setrate(clk, 1 << ((value >> 2) & 3), 1);
1547      }
1548      if (diff & (3 << 0)) {				/* PERDIV */
1549          clk = omap_findclk(s, "armper_ck");
1550          omap_clk_setrate(clk, 1 << ((value >> 0) & 3), 1);
1551      }
1552  }
1553  
omap_clkm_idlect1_update(struct omap_mpu_state_s * s,uint16_t diff,uint16_t value)1554  static inline void omap_clkm_idlect1_update(struct omap_mpu_state_s *s,
1555                  uint16_t diff, uint16_t value)
1556  {
1557      omap_clk clk;
1558  
1559      if (value & (1 << 11)) {                            /* SETARM_IDLE */
1560          cpu_interrupt(CPU(s->cpu), CPU_INTERRUPT_HALT);
1561      }
1562      if (!(value & (1 << 10))) {                         /* WKUP_MODE */
1563          /* XXX: disable wakeup from IRQ */
1564          qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
1565      }
1566  
1567  #define SET_CANIDLE(clock, bit)				\
1568      if (diff & (1 << bit)) {				\
1569          clk = omap_findclk(s, clock);			\
1570          omap_clk_canidle(clk, (value >> bit) & 1);	\
1571      }
1572      SET_CANIDLE("mpuwd_ck", 0)				/* IDLWDT_ARM */
1573      SET_CANIDLE("armxor_ck", 1)				/* IDLXORP_ARM */
1574      SET_CANIDLE("mpuper_ck", 2)				/* IDLPER_ARM */
1575      SET_CANIDLE("lcd_ck", 3)				/* IDLLCD_ARM */
1576      SET_CANIDLE("lb_ck", 4)				/* IDLLB_ARM */
1577      SET_CANIDLE("hsab_ck", 5)				/* IDLHSAB_ARM */
1578      SET_CANIDLE("tipb_ck", 6)				/* IDLIF_ARM */
1579      SET_CANIDLE("dma_ck", 6)				/* IDLIF_ARM */
1580      SET_CANIDLE("tc_ck", 6)				/* IDLIF_ARM */
1581      SET_CANIDLE("dpll1", 7)				/* IDLDPLL_ARM */
1582      SET_CANIDLE("dpll2", 7)				/* IDLDPLL_ARM */
1583      SET_CANIDLE("dpll3", 7)				/* IDLDPLL_ARM */
1584      SET_CANIDLE("mpui_ck", 8)				/* IDLAPI_ARM */
1585      SET_CANIDLE("armtim_ck", 9)				/* IDLTIM_ARM */
1586  }
1587  
omap_clkm_idlect2_update(struct omap_mpu_state_s * s,uint16_t diff,uint16_t value)1588  static inline void omap_clkm_idlect2_update(struct omap_mpu_state_s *s,
1589                  uint16_t diff, uint16_t value)
1590  {
1591      omap_clk clk;
1592  
1593  #define SET_ONOFF(clock, bit)				\
1594      if (diff & (1 << bit)) {				\
1595          clk = omap_findclk(s, clock);			\
1596          omap_clk_onoff(clk, (value >> bit) & 1);	\
1597      }
1598      SET_ONOFF("mpuwd_ck", 0)				/* EN_WDTCK */
1599      SET_ONOFF("armxor_ck", 1)				/* EN_XORPCK */
1600      SET_ONOFF("mpuper_ck", 2)				/* EN_PERCK */
1601      SET_ONOFF("lcd_ck", 3)				/* EN_LCDCK */
1602      SET_ONOFF("lb_ck", 4)				/* EN_LBCK */
1603      SET_ONOFF("hsab_ck", 5)				/* EN_HSABCK */
1604      SET_ONOFF("mpui_ck", 6)				/* EN_APICK */
1605      SET_ONOFF("armtim_ck", 7)				/* EN_TIMCK */
1606      SET_CANIDLE("dma_ck", 8)				/* DMACK_REQ */
1607      SET_ONOFF("arm_gpio_ck", 9)				/* EN_GPIOCK */
1608      SET_ONOFF("lbfree_ck", 10)				/* EN_LBFREECK */
1609  }
1610  
omap_clkm_ckout1_update(struct omap_mpu_state_s * s,uint16_t diff,uint16_t value)1611  static inline void omap_clkm_ckout1_update(struct omap_mpu_state_s *s,
1612                  uint16_t diff, uint16_t value)
1613  {
1614      omap_clk clk;
1615  
1616      if (diff & (3 << 4)) {				/* TCLKOUT */
1617          clk = omap_findclk(s, "tclk_out");
1618          switch ((value >> 4) & 3) {
1619          case 1:
1620              omap_clk_reparent(clk, omap_findclk(s, "ck_gen3"));
1621              omap_clk_onoff(clk, 1);
1622              break;
1623          case 2:
1624              omap_clk_reparent(clk, omap_findclk(s, "tc_ck"));
1625              omap_clk_onoff(clk, 1);
1626              break;
1627          default:
1628              omap_clk_onoff(clk, 0);
1629          }
1630      }
1631      if (diff & (3 << 2)) {				/* DCLKOUT */
1632          clk = omap_findclk(s, "dclk_out");
1633          switch ((value >> 2) & 3) {
1634          case 0:
1635              omap_clk_reparent(clk, omap_findclk(s, "dspmmu_ck"));
1636              break;
1637          case 1:
1638              omap_clk_reparent(clk, omap_findclk(s, "ck_gen2"));
1639              break;
1640          case 2:
1641              omap_clk_reparent(clk, omap_findclk(s, "dsp_ck"));
1642              break;
1643          case 3:
1644              omap_clk_reparent(clk, omap_findclk(s, "ck_ref14"));
1645              break;
1646          }
1647      }
1648      if (diff & (3 << 0)) {				/* ACLKOUT */
1649          clk = omap_findclk(s, "aclk_out");
1650          switch ((value >> 0) & 3) {
1651          case 1:
1652              omap_clk_reparent(clk, omap_findclk(s, "ck_gen1"));
1653              omap_clk_onoff(clk, 1);
1654              break;
1655          case 2:
1656              omap_clk_reparent(clk, omap_findclk(s, "arm_ck"));
1657              omap_clk_onoff(clk, 1);
1658              break;
1659          case 3:
1660              omap_clk_reparent(clk, omap_findclk(s, "ck_ref14"));
1661              omap_clk_onoff(clk, 1);
1662              break;
1663          default:
1664              omap_clk_onoff(clk, 0);
1665          }
1666      }
1667  }
1668  
omap_clkm_write(void * opaque,hwaddr addr,uint64_t value,unsigned size)1669  static void omap_clkm_write(void *opaque, hwaddr addr,
1670                              uint64_t value, unsigned size)
1671  {
1672      struct omap_mpu_state_s *s = opaque;
1673      uint16_t diff;
1674      omap_clk clk;
1675      static const char *clkschemename[8] = {
1676          "fully synchronous", "fully asynchronous", "synchronous scalable",
1677          "mix mode 1", "mix mode 2", "bypass mode", "mix mode 3", "mix mode 4",
1678      };
1679  
1680      if (size != 2) {
1681          omap_badwidth_write16(opaque, addr, value);
1682          return;
1683      }
1684  
1685      switch (addr) {
1686      case 0x00:	/* ARM_CKCTL */
1687          diff = s->clkm.arm_ckctl ^ value;
1688          s->clkm.arm_ckctl = value & 0x7fff;
1689          omap_clkm_ckctl_update(s, diff, value);
1690          return;
1691  
1692      case 0x04:	/* ARM_IDLECT1 */
1693          diff = s->clkm.arm_idlect1 ^ value;
1694          s->clkm.arm_idlect1 = value & 0x0fff;
1695          omap_clkm_idlect1_update(s, diff, value);
1696          return;
1697  
1698      case 0x08:	/* ARM_IDLECT2 */
1699          diff = s->clkm.arm_idlect2 ^ value;
1700          s->clkm.arm_idlect2 = value & 0x07ff;
1701          omap_clkm_idlect2_update(s, diff, value);
1702          return;
1703  
1704      case 0x0c:	/* ARM_EWUPCT */
1705          s->clkm.arm_ewupct = value & 0x003f;
1706          return;
1707  
1708      case 0x10:	/* ARM_RSTCT1 */
1709          diff = s->clkm.arm_rstct1 ^ value;
1710          s->clkm.arm_rstct1 = value & 0x0007;
1711          if (value & 9) {
1712              qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
1713              s->clkm.cold_start = 0xa;
1714          }
1715          if (diff & ~value & 4) {				/* DSP_RST */
1716              omap_mpui_reset(s);
1717              omap_tipb_bridge_reset(s->private_tipb);
1718              omap_tipb_bridge_reset(s->public_tipb);
1719          }
1720          if (diff & 2) {						/* DSP_EN */
1721              clk = omap_findclk(s, "dsp_ck");
1722              omap_clk_canidle(clk, (~value >> 1) & 1);
1723          }
1724          return;
1725  
1726      case 0x14:	/* ARM_RSTCT2 */
1727          s->clkm.arm_rstct2 = value & 0x0001;
1728          return;
1729  
1730      case 0x18:	/* ARM_SYSST */
1731          if ((s->clkm.clocking_scheme ^ (value >> 11)) & 7) {
1732              s->clkm.clocking_scheme = (value >> 11) & 7;
1733              printf("%s: clocking scheme set to %s\n", __func__,
1734                     clkschemename[s->clkm.clocking_scheme]);
1735          }
1736          s->clkm.cold_start &= value & 0x3f;
1737          return;
1738  
1739      case 0x1c:	/* ARM_CKOUT1 */
1740          diff = s->clkm.arm_ckout1 ^ value;
1741          s->clkm.arm_ckout1 = value & 0x003f;
1742          omap_clkm_ckout1_update(s, diff, value);
1743          return;
1744  
1745      case 0x20:	/* ARM_CKOUT2 */
1746      default:
1747          OMAP_BAD_REG(addr);
1748      }
1749  }
1750  
1751  static const MemoryRegionOps omap_clkm_ops = {
1752      .read = omap_clkm_read,
1753      .write = omap_clkm_write,
1754      .endianness = DEVICE_NATIVE_ENDIAN,
1755  };
1756  
omap_clkdsp_read(void * opaque,hwaddr addr,unsigned size)1757  static uint64_t omap_clkdsp_read(void *opaque, hwaddr addr,
1758                                   unsigned size)
1759  {
1760      struct omap_mpu_state_s *s = opaque;
1761      CPUState *cpu = CPU(s->cpu);
1762  
1763      if (size != 2) {
1764          return omap_badwidth_read16(opaque, addr);
1765      }
1766  
1767      switch (addr) {
1768      case 0x04:	/* DSP_IDLECT1 */
1769          return s->clkm.dsp_idlect1;
1770  
1771      case 0x08:	/* DSP_IDLECT2 */
1772          return s->clkm.dsp_idlect2;
1773  
1774      case 0x14:	/* DSP_RSTCT2 */
1775          return s->clkm.dsp_rstct2;
1776  
1777      case 0x18:	/* DSP_SYSST */
1778          return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start |
1779                  (cpu->halted << 6);      /* Quite useless... */
1780      }
1781  
1782      OMAP_BAD_REG(addr);
1783      return 0;
1784  }
1785  
omap_clkdsp_idlect1_update(struct omap_mpu_state_s * s,uint16_t diff,uint16_t value)1786  static inline void omap_clkdsp_idlect1_update(struct omap_mpu_state_s *s,
1787                  uint16_t diff, uint16_t value)
1788  {
1789      omap_clk clk;
1790  
1791      SET_CANIDLE("dspxor_ck", 1);			/* IDLXORP_DSP */
1792  }
1793  
omap_clkdsp_idlect2_update(struct omap_mpu_state_s * s,uint16_t diff,uint16_t value)1794  static inline void omap_clkdsp_idlect2_update(struct omap_mpu_state_s *s,
1795                  uint16_t diff, uint16_t value)
1796  {
1797      omap_clk clk;
1798  
1799      SET_ONOFF("dspxor_ck", 1);				/* EN_XORPCK */
1800  }
1801  
omap_clkdsp_write(void * opaque,hwaddr addr,uint64_t value,unsigned size)1802  static void omap_clkdsp_write(void *opaque, hwaddr addr,
1803                                uint64_t value, unsigned size)
1804  {
1805      struct omap_mpu_state_s *s = opaque;
1806      uint16_t diff;
1807  
1808      if (size != 2) {
1809          omap_badwidth_write16(opaque, addr, value);
1810          return;
1811      }
1812  
1813      switch (addr) {
1814      case 0x04:	/* DSP_IDLECT1 */
1815          diff = s->clkm.dsp_idlect1 ^ value;
1816          s->clkm.dsp_idlect1 = value & 0x01f7;
1817          omap_clkdsp_idlect1_update(s, diff, value);
1818          break;
1819  
1820      case 0x08:	/* DSP_IDLECT2 */
1821          s->clkm.dsp_idlect2 = value & 0x0037;
1822          diff = s->clkm.dsp_idlect1 ^ value;
1823          omap_clkdsp_idlect2_update(s, diff, value);
1824          break;
1825  
1826      case 0x14:	/* DSP_RSTCT2 */
1827          s->clkm.dsp_rstct2 = value & 0x0001;
1828          break;
1829  
1830      case 0x18:	/* DSP_SYSST */
1831          s->clkm.cold_start &= value & 0x3f;
1832          break;
1833  
1834      default:
1835          OMAP_BAD_REG(addr);
1836      }
1837  }
1838  
1839  static const MemoryRegionOps omap_clkdsp_ops = {
1840      .read = omap_clkdsp_read,
1841      .write = omap_clkdsp_write,
1842      .endianness = DEVICE_NATIVE_ENDIAN,
1843  };
1844  
omap_clkm_reset(struct omap_mpu_state_s * s)1845  static void omap_clkm_reset(struct omap_mpu_state_s *s)
1846  {
1847      if (s->wdt && s->wdt->reset)
1848          s->clkm.cold_start = 0x6;
1849      s->clkm.clocking_scheme = 0;
1850      omap_clkm_ckctl_update(s, ~0, 0x3000);
1851      s->clkm.arm_ckctl = 0x3000;
1852      omap_clkm_idlect1_update(s, s->clkm.arm_idlect1 ^ 0x0400, 0x0400);
1853      s->clkm.arm_idlect1 = 0x0400;
1854      omap_clkm_idlect2_update(s, s->clkm.arm_idlect2 ^ 0x0100, 0x0100);
1855      s->clkm.arm_idlect2 = 0x0100;
1856      s->clkm.arm_ewupct = 0x003f;
1857      s->clkm.arm_rstct1 = 0x0000;
1858      s->clkm.arm_rstct2 = 0x0000;
1859      s->clkm.arm_ckout1 = 0x0015;
1860      s->clkm.dpll1_mode = 0x2002;
1861      omap_clkdsp_idlect1_update(s, s->clkm.dsp_idlect1 ^ 0x0040, 0x0040);
1862      s->clkm.dsp_idlect1 = 0x0040;
1863      omap_clkdsp_idlect2_update(s, ~0, 0x0000);
1864      s->clkm.dsp_idlect2 = 0x0000;
1865      s->clkm.dsp_rstct2 = 0x0000;
1866  }
1867  
omap_clkm_init(MemoryRegion * memory,hwaddr mpu_base,hwaddr dsp_base,struct omap_mpu_state_s * s)1868  static void omap_clkm_init(MemoryRegion *memory, hwaddr mpu_base,
1869                  hwaddr dsp_base, struct omap_mpu_state_s *s)
1870  {
1871      memory_region_init_io(&s->clkm_iomem, NULL, &omap_clkm_ops, s,
1872                            "omap-clkm", 0x100);
1873      memory_region_init_io(&s->clkdsp_iomem, NULL, &omap_clkdsp_ops, s,
1874                            "omap-clkdsp", 0x1000);
1875  
1876      s->clkm.arm_idlect1 = 0x03ff;
1877      s->clkm.arm_idlect2 = 0x0100;
1878      s->clkm.dsp_idlect1 = 0x0002;
1879      omap_clkm_reset(s);
1880      s->clkm.cold_start = 0x3a;
1881  
1882      memory_region_add_subregion(memory, mpu_base, &s->clkm_iomem);
1883      memory_region_add_subregion(memory, dsp_base, &s->clkdsp_iomem);
1884  }
1885  
1886  /* MPU I/O */
1887  struct omap_mpuio_s {
1888      qemu_irq irq;
1889      qemu_irq kbd_irq;
1890      qemu_irq *in;
1891      qemu_irq handler[16];
1892      qemu_irq wakeup;
1893      MemoryRegion iomem;
1894  
1895      uint16_t inputs;
1896      uint16_t outputs;
1897      uint16_t dir;
1898      uint16_t edge;
1899      uint16_t mask;
1900      uint16_t ints;
1901  
1902      uint16_t debounce;
1903      uint16_t latch;
1904      uint8_t event;
1905  
1906      uint8_t buttons[5];
1907      uint8_t row_latch;
1908      uint8_t cols;
1909      int kbd_mask;
1910      int clk;
1911  };
1912  
omap_mpuio_set(void * opaque,int line,int level)1913  static void omap_mpuio_set(void *opaque, int line, int level)
1914  {
1915      struct omap_mpuio_s *s = opaque;
1916      uint16_t prev = s->inputs;
1917  
1918      if (level)
1919          s->inputs |= 1 << line;
1920      else
1921          s->inputs &= ~(1 << line);
1922  
1923      if (((1 << line) & s->dir & ~s->mask) && s->clk) {
1924          if ((s->edge & s->inputs & ~prev) | (~s->edge & ~s->inputs & prev)) {
1925              s->ints |= 1 << line;
1926              qemu_irq_raise(s->irq);
1927              /* TODO: wakeup */
1928          }
1929          if ((s->event & (1 << 0)) &&		/* SET_GPIO_EVENT_MODE */
1930                  (s->event >> 1) == line)	/* PIN_SELECT */
1931              s->latch = s->inputs;
1932      }
1933  }
1934  
omap_mpuio_kbd_update(struct omap_mpuio_s * s)1935  static void omap_mpuio_kbd_update(struct omap_mpuio_s *s)
1936  {
1937      int i;
1938      uint8_t *row, rows = 0, cols = ~s->cols;
1939  
1940      for (row = s->buttons + 4, i = 1 << 4; i; row --, i >>= 1)
1941          if (*row & cols)
1942              rows |= i;
1943  
1944      qemu_set_irq(s->kbd_irq, rows && !s->kbd_mask && s->clk);
1945      s->row_latch = ~rows;
1946  }
1947  
omap_mpuio_read(void * opaque,hwaddr addr,unsigned size)1948  static uint64_t omap_mpuio_read(void *opaque, hwaddr addr,
1949                                  unsigned size)
1950  {
1951      struct omap_mpuio_s *s = opaque;
1952      int offset = addr & OMAP_MPUI_REG_MASK;
1953      uint16_t ret;
1954  
1955      if (size != 2) {
1956          return omap_badwidth_read16(opaque, addr);
1957      }
1958  
1959      switch (offset) {
1960      case 0x00:	/* INPUT_LATCH */
1961          return s->inputs;
1962  
1963      case 0x04:	/* OUTPUT_REG */
1964          return s->outputs;
1965  
1966      case 0x08:	/* IO_CNTL */
1967          return s->dir;
1968  
1969      case 0x10:	/* KBR_LATCH */
1970          return s->row_latch;
1971  
1972      case 0x14:	/* KBC_REG */
1973          return s->cols;
1974  
1975      case 0x18:	/* GPIO_EVENT_MODE_REG */
1976          return s->event;
1977  
1978      case 0x1c:	/* GPIO_INT_EDGE_REG */
1979          return s->edge;
1980  
1981      case 0x20:	/* KBD_INT */
1982          return (~s->row_latch & 0x1f) && !s->kbd_mask;
1983  
1984      case 0x24:	/* GPIO_INT */
1985          ret = s->ints;
1986          s->ints &= s->mask;
1987          if (ret)
1988              qemu_irq_lower(s->irq);
1989          return ret;
1990  
1991      case 0x28:	/* KBD_MASKIT */
1992          return s->kbd_mask;
1993  
1994      case 0x2c:	/* GPIO_MASKIT */
1995          return s->mask;
1996  
1997      case 0x30:	/* GPIO_DEBOUNCING_REG */
1998          return s->debounce;
1999  
2000      case 0x34:	/* GPIO_LATCH_REG */
2001          return s->latch;
2002      }
2003  
2004      OMAP_BAD_REG(addr);
2005      return 0;
2006  }
2007  
omap_mpuio_write(void * opaque,hwaddr addr,uint64_t value,unsigned size)2008  static void omap_mpuio_write(void *opaque, hwaddr addr,
2009                               uint64_t value, unsigned size)
2010  {
2011      struct omap_mpuio_s *s = opaque;
2012      int offset = addr & OMAP_MPUI_REG_MASK;
2013      uint16_t diff;
2014      int ln;
2015  
2016      if (size != 2) {
2017          omap_badwidth_write16(opaque, addr, value);
2018          return;
2019      }
2020  
2021      switch (offset) {
2022      case 0x04:	/* OUTPUT_REG */
2023          diff = (s->outputs ^ value) & ~s->dir;
2024          s->outputs = value;
2025          while ((ln = ctz32(diff)) != 32) {
2026              if (s->handler[ln])
2027                  qemu_set_irq(s->handler[ln], (value >> ln) & 1);
2028              diff &= ~(1 << ln);
2029          }
2030          break;
2031  
2032      case 0x08:	/* IO_CNTL */
2033          diff = s->outputs & (s->dir ^ value);
2034          s->dir = value;
2035  
2036          value = s->outputs & ~s->dir;
2037          while ((ln = ctz32(diff)) != 32) {
2038              if (s->handler[ln])
2039                  qemu_set_irq(s->handler[ln], (value >> ln) & 1);
2040              diff &= ~(1 << ln);
2041          }
2042          break;
2043  
2044      case 0x14:	/* KBC_REG */
2045          s->cols = value;
2046          omap_mpuio_kbd_update(s);
2047          break;
2048  
2049      case 0x18:	/* GPIO_EVENT_MODE_REG */
2050          s->event = value & 0x1f;
2051          break;
2052  
2053      case 0x1c:	/* GPIO_INT_EDGE_REG */
2054          s->edge = value;
2055          break;
2056  
2057      case 0x28:	/* KBD_MASKIT */
2058          s->kbd_mask = value & 1;
2059          omap_mpuio_kbd_update(s);
2060          break;
2061  
2062      case 0x2c:	/* GPIO_MASKIT */
2063          s->mask = value;
2064          break;
2065  
2066      case 0x30:	/* GPIO_DEBOUNCING_REG */
2067          s->debounce = value & 0x1ff;
2068          break;
2069  
2070      case 0x00:	/* INPUT_LATCH */
2071      case 0x10:	/* KBR_LATCH */
2072      case 0x20:	/* KBD_INT */
2073      case 0x24:	/* GPIO_INT */
2074      case 0x34:	/* GPIO_LATCH_REG */
2075          OMAP_RO_REG(addr);
2076          return;
2077  
2078      default:
2079          OMAP_BAD_REG(addr);
2080          return;
2081      }
2082  }
2083  
2084  static const MemoryRegionOps omap_mpuio_ops  = {
2085      .read = omap_mpuio_read,
2086      .write = omap_mpuio_write,
2087      .endianness = DEVICE_NATIVE_ENDIAN,
2088  };
2089  
omap_mpuio_reset(struct omap_mpuio_s * s)2090  static void omap_mpuio_reset(struct omap_mpuio_s *s)
2091  {
2092      s->inputs = 0;
2093      s->outputs = 0;
2094      s->dir = ~0;
2095      s->event = 0;
2096      s->edge = 0;
2097      s->kbd_mask = 0;
2098      s->mask = 0;
2099      s->debounce = 0;
2100      s->latch = 0;
2101      s->ints = 0;
2102      s->row_latch = 0x1f;
2103      s->clk = 1;
2104  }
2105  
omap_mpuio_onoff(void * opaque,int line,int on)2106  static void omap_mpuio_onoff(void *opaque, int line, int on)
2107  {
2108      struct omap_mpuio_s *s = opaque;
2109  
2110      s->clk = on;
2111      if (on)
2112          omap_mpuio_kbd_update(s);
2113  }
2114  
omap_mpuio_init(MemoryRegion * memory,hwaddr base,qemu_irq kbd_int,qemu_irq gpio_int,qemu_irq wakeup,omap_clk clk)2115  static struct omap_mpuio_s *omap_mpuio_init(MemoryRegion *memory,
2116                  hwaddr base,
2117                  qemu_irq kbd_int, qemu_irq gpio_int, qemu_irq wakeup,
2118                  omap_clk clk)
2119  {
2120      struct omap_mpuio_s *s = g_new0(struct omap_mpuio_s, 1);
2121  
2122      s->irq = gpio_int;
2123      s->kbd_irq = kbd_int;
2124      s->wakeup = wakeup;
2125      s->in = qemu_allocate_irqs(omap_mpuio_set, s, 16);
2126      omap_mpuio_reset(s);
2127  
2128      memory_region_init_io(&s->iomem, NULL, &omap_mpuio_ops, s,
2129                            "omap-mpuio", 0x800);
2130      memory_region_add_subregion(memory, base, &s->iomem);
2131  
2132      omap_clk_adduser(clk, qemu_allocate_irq(omap_mpuio_onoff, s, 0));
2133  
2134      return s;
2135  }
2136  
omap_mpuio_in_get(struct omap_mpuio_s * s)2137  qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s)
2138  {
2139      return s->in;
2140  }
2141  
omap_mpuio_out_set(struct omap_mpuio_s * s,int line,qemu_irq handler)2142  void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler)
2143  {
2144      if (line >= 16 || line < 0)
2145          hw_error("%s: No GPIO line %i\n", __func__, line);
2146      s->handler[line] = handler;
2147  }
2148  
omap_mpuio_key(struct omap_mpuio_s * s,int row,int col,int down)2149  void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down)
2150  {
2151      if (row >= 5 || row < 0)
2152          hw_error("%s: No key %i-%i\n", __func__, col, row);
2153  
2154      if (down)
2155          s->buttons[row] |= 1 << col;
2156      else
2157          s->buttons[row] &= ~(1 << col);
2158  
2159      omap_mpuio_kbd_update(s);
2160  }
2161  
2162  /* MicroWire Interface */
2163  struct omap_uwire_s {
2164      MemoryRegion iomem;
2165      qemu_irq txirq;
2166      qemu_irq rxirq;
2167      qemu_irq txdrq;
2168  
2169      uint16_t txbuf;
2170      uint16_t rxbuf;
2171      uint16_t control;
2172      uint16_t setup[5];
2173  };
2174  
omap_uwire_transfer_start(struct omap_uwire_s * s)2175  static void omap_uwire_transfer_start(struct omap_uwire_s *s)
2176  {
2177      int chipselect = (s->control >> 10) & 3;		/* INDEX */
2178  
2179      if ((s->control >> 5) & 0x1f) {			/* NB_BITS_WR */
2180          if (s->control & (1 << 12)) {       /* CS_CMD */
2181              qemu_log_mask(LOG_UNIMP, "uWireSlave TX CS:%d data:0x%04x\n",
2182                            chipselect,
2183                            s->txbuf >> (16 - ((s->control >> 5) & 0x1f)));
2184          }
2185          s->control &= ~(1 << 14);			/* CSRB */
2186          /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
2187           * a DRQ.  When is the level IRQ supposed to be reset?  */
2188      }
2189  
2190      if ((s->control >> 0) & 0x1f) {			/* NB_BITS_RD */
2191          if (s->control & (1 << 12)) {       /* CS_CMD */
2192              qemu_log_mask(LOG_UNIMP, "uWireSlave RX CS:%d\n", chipselect);
2193          }
2194          s->control |= 1 << 15;				/* RDRB */
2195          /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
2196           * a DRQ.  When is the level IRQ supposed to be reset?  */
2197      }
2198  }
2199  
omap_uwire_read(void * opaque,hwaddr addr,unsigned size)2200  static uint64_t omap_uwire_read(void *opaque, hwaddr addr, unsigned size)
2201  {
2202      struct omap_uwire_s *s = opaque;
2203      int offset = addr & OMAP_MPUI_REG_MASK;
2204  
2205      if (size != 2) {
2206          return omap_badwidth_read16(opaque, addr);
2207      }
2208  
2209      switch (offset) {
2210      case 0x00:	/* RDR */
2211          s->control &= ~(1 << 15);			/* RDRB */
2212          return s->rxbuf;
2213  
2214      case 0x04:	/* CSR */
2215          return s->control;
2216  
2217      case 0x08:	/* SR1 */
2218          return s->setup[0];
2219      case 0x0c:	/* SR2 */
2220          return s->setup[1];
2221      case 0x10:	/* SR3 */
2222          return s->setup[2];
2223      case 0x14:	/* SR4 */
2224          return s->setup[3];
2225      case 0x18:	/* SR5 */
2226          return s->setup[4];
2227      }
2228  
2229      OMAP_BAD_REG(addr);
2230      return 0;
2231  }
2232  
omap_uwire_write(void * opaque,hwaddr addr,uint64_t value,unsigned size)2233  static void omap_uwire_write(void *opaque, hwaddr addr,
2234                               uint64_t value, unsigned size)
2235  {
2236      struct omap_uwire_s *s = opaque;
2237      int offset = addr & OMAP_MPUI_REG_MASK;
2238  
2239      if (size != 2) {
2240          omap_badwidth_write16(opaque, addr, value);
2241          return;
2242      }
2243  
2244      switch (offset) {
2245      case 0x00:	/* TDR */
2246          s->txbuf = value;				/* TD */
2247          if ((s->setup[4] & (1 << 2)) &&			/* AUTO_TX_EN */
2248                          ((s->setup[4] & (1 << 3)) ||	/* CS_TOGGLE_TX_EN */
2249                           (s->control & (1 << 12)))) {	/* CS_CMD */
2250              s->control |= 1 << 14;			/* CSRB */
2251              omap_uwire_transfer_start(s);
2252          }
2253          break;
2254  
2255      case 0x04:	/* CSR */
2256          s->control = value & 0x1fff;
2257          if (value & (1 << 13))				/* START */
2258              omap_uwire_transfer_start(s);
2259          break;
2260  
2261      case 0x08:	/* SR1 */
2262          s->setup[0] = value & 0x003f;
2263          break;
2264  
2265      case 0x0c:	/* SR2 */
2266          s->setup[1] = value & 0x0fc0;
2267          break;
2268  
2269      case 0x10:	/* SR3 */
2270          s->setup[2] = value & 0x0003;
2271          break;
2272  
2273      case 0x14:	/* SR4 */
2274          s->setup[3] = value & 0x0001;
2275          break;
2276  
2277      case 0x18:	/* SR5 */
2278          s->setup[4] = value & 0x000f;
2279          break;
2280  
2281      default:
2282          OMAP_BAD_REG(addr);
2283          return;
2284      }
2285  }
2286  
2287  static const MemoryRegionOps omap_uwire_ops = {
2288      .read = omap_uwire_read,
2289      .write = omap_uwire_write,
2290      .endianness = DEVICE_NATIVE_ENDIAN,
2291  };
2292  
omap_uwire_reset(struct omap_uwire_s * s)2293  static void omap_uwire_reset(struct omap_uwire_s *s)
2294  {
2295      s->control = 0;
2296      s->setup[0] = 0;
2297      s->setup[1] = 0;
2298      s->setup[2] = 0;
2299      s->setup[3] = 0;
2300      s->setup[4] = 0;
2301  }
2302  
omap_uwire_init(MemoryRegion * system_memory,hwaddr base,qemu_irq txirq,qemu_irq rxirq,qemu_irq dma,omap_clk clk)2303  static struct omap_uwire_s *omap_uwire_init(MemoryRegion *system_memory,
2304                                              hwaddr base,
2305                                              qemu_irq txirq, qemu_irq rxirq,
2306                                              qemu_irq dma,
2307                                              omap_clk clk)
2308  {
2309      struct omap_uwire_s *s = g_new0(struct omap_uwire_s, 1);
2310  
2311      s->txirq = txirq;
2312      s->rxirq = rxirq;
2313      s->txdrq = dma;
2314      omap_uwire_reset(s);
2315  
2316      memory_region_init_io(&s->iomem, NULL, &omap_uwire_ops, s, "omap-uwire", 0x800);
2317      memory_region_add_subregion(system_memory, base, &s->iomem);
2318  
2319      return s;
2320  }
2321  
2322  /* Pseudonoise Pulse-Width Light Modulator */
2323  struct omap_pwl_s {
2324      MemoryRegion iomem;
2325      uint8_t output;
2326      uint8_t level;
2327      uint8_t enable;
2328      int clk;
2329  };
2330  
omap_pwl_update(struct omap_pwl_s * s)2331  static void omap_pwl_update(struct omap_pwl_s *s)
2332  {
2333      int output = (s->clk && s->enable) ? s->level : 0;
2334  
2335      if (output != s->output) {
2336          s->output = output;
2337          printf("%s: Backlight now at %i/256\n", __func__, output);
2338      }
2339  }
2340  
omap_pwl_read(void * opaque,hwaddr addr,unsigned size)2341  static uint64_t omap_pwl_read(void *opaque, hwaddr addr, unsigned size)
2342  {
2343      struct omap_pwl_s *s = opaque;
2344      int offset = addr & OMAP_MPUI_REG_MASK;
2345  
2346      if (size != 1) {
2347          return omap_badwidth_read8(opaque, addr);
2348      }
2349  
2350      switch (offset) {
2351      case 0x00:	/* PWL_LEVEL */
2352          return s->level;
2353      case 0x04:	/* PWL_CTRL */
2354          return s->enable;
2355      }
2356      OMAP_BAD_REG(addr);
2357      return 0;
2358  }
2359  
omap_pwl_write(void * opaque,hwaddr addr,uint64_t value,unsigned size)2360  static void omap_pwl_write(void *opaque, hwaddr addr,
2361                             uint64_t value, unsigned size)
2362  {
2363      struct omap_pwl_s *s = opaque;
2364      int offset = addr & OMAP_MPUI_REG_MASK;
2365  
2366      if (size != 1) {
2367          omap_badwidth_write8(opaque, addr, value);
2368          return;
2369      }
2370  
2371      switch (offset) {
2372      case 0x00:	/* PWL_LEVEL */
2373          s->level = value;
2374          omap_pwl_update(s);
2375          break;
2376      case 0x04:	/* PWL_CTRL */
2377          s->enable = value & 1;
2378          omap_pwl_update(s);
2379          break;
2380      default:
2381          OMAP_BAD_REG(addr);
2382          return;
2383      }
2384  }
2385  
2386  static const MemoryRegionOps omap_pwl_ops = {
2387      .read = omap_pwl_read,
2388      .write = omap_pwl_write,
2389      .endianness = DEVICE_NATIVE_ENDIAN,
2390  };
2391  
omap_pwl_reset(struct omap_pwl_s * s)2392  static void omap_pwl_reset(struct omap_pwl_s *s)
2393  {
2394      s->output = 0;
2395      s->level = 0;
2396      s->enable = 0;
2397      s->clk = 1;
2398      omap_pwl_update(s);
2399  }
2400  
omap_pwl_clk_update(void * opaque,int line,int on)2401  static void omap_pwl_clk_update(void *opaque, int line, int on)
2402  {
2403      struct omap_pwl_s *s = opaque;
2404  
2405      s->clk = on;
2406      omap_pwl_update(s);
2407  }
2408  
omap_pwl_init(MemoryRegion * system_memory,hwaddr base,omap_clk clk)2409  static struct omap_pwl_s *omap_pwl_init(MemoryRegion *system_memory,
2410                                          hwaddr base,
2411                                          omap_clk clk)
2412  {
2413      struct omap_pwl_s *s = g_malloc0(sizeof(*s));
2414  
2415      omap_pwl_reset(s);
2416  
2417      memory_region_init_io(&s->iomem, NULL, &omap_pwl_ops, s,
2418                            "omap-pwl", 0x800);
2419      memory_region_add_subregion(system_memory, base, &s->iomem);
2420  
2421      omap_clk_adduser(clk, qemu_allocate_irq(omap_pwl_clk_update, s, 0));
2422      return s;
2423  }
2424  
2425  /* Pulse-Width Tone module */
2426  struct omap_pwt_s {
2427      MemoryRegion iomem;
2428      uint8_t frc;
2429      uint8_t vrc;
2430      uint8_t gcr;
2431      omap_clk clk;
2432  };
2433  
omap_pwt_read(void * opaque,hwaddr addr,unsigned size)2434  static uint64_t omap_pwt_read(void *opaque, hwaddr addr, unsigned size)
2435  {
2436      struct omap_pwt_s *s = opaque;
2437      int offset = addr & OMAP_MPUI_REG_MASK;
2438  
2439      if (size != 1) {
2440          return omap_badwidth_read8(opaque, addr);
2441      }
2442  
2443      switch (offset) {
2444      case 0x00:	/* FRC */
2445          return s->frc;
2446      case 0x04:	/* VCR */
2447          return s->vrc;
2448      case 0x08:	/* GCR */
2449          return s->gcr;
2450      }
2451      OMAP_BAD_REG(addr);
2452      return 0;
2453  }
2454  
omap_pwt_write(void * opaque,hwaddr addr,uint64_t value,unsigned size)2455  static void omap_pwt_write(void *opaque, hwaddr addr,
2456                             uint64_t value, unsigned size)
2457  {
2458      struct omap_pwt_s *s = opaque;
2459      int offset = addr & OMAP_MPUI_REG_MASK;
2460  
2461      if (size != 1) {
2462          omap_badwidth_write8(opaque, addr, value);
2463          return;
2464      }
2465  
2466      switch (offset) {
2467      case 0x00:	/* FRC */
2468          s->frc = value & 0x3f;
2469          break;
2470      case 0x04:	/* VRC */
2471          if ((value ^ s->vrc) & 1) {
2472              if (value & 1)
2473                  printf("%s: %iHz buzz on\n", __func__, (int)
2474                                  /* 1.5 MHz from a 12-MHz or 13-MHz PWT_CLK */
2475                                  ((omap_clk_getrate(s->clk) >> 3) /
2476                                   /* Pre-multiplexer divider */
2477                                   ((s->gcr & 2) ? 1 : 154) /
2478                                   /* Octave multiplexer */
2479                                   (2 << (value & 3)) *
2480                                   /* 101/107 divider */
2481                                   ((value & (1 << 2)) ? 101 : 107) *
2482                                   /*  49/55 divider */
2483                                   ((value & (1 << 3)) ?  49 : 55) *
2484                                   /*  50/63 divider */
2485                                   ((value & (1 << 4)) ?  50 : 63) *
2486                                   /*  80/127 divider */
2487                                   ((value & (1 << 5)) ?  80 : 127) /
2488                                   (107 * 55 * 63 * 127)));
2489              else
2490                  printf("%s: silence!\n", __func__);
2491          }
2492          s->vrc = value & 0x7f;
2493          break;
2494      case 0x08:	/* GCR */
2495          s->gcr = value & 3;
2496          break;
2497      default:
2498          OMAP_BAD_REG(addr);
2499          return;
2500      }
2501  }
2502  
2503  static const MemoryRegionOps omap_pwt_ops = {
2504      .read =omap_pwt_read,
2505      .write = omap_pwt_write,
2506      .endianness = DEVICE_NATIVE_ENDIAN,
2507  };
2508  
omap_pwt_reset(struct omap_pwt_s * s)2509  static void omap_pwt_reset(struct omap_pwt_s *s)
2510  {
2511      s->frc = 0;
2512      s->vrc = 0;
2513      s->gcr = 0;
2514  }
2515  
omap_pwt_init(MemoryRegion * system_memory,hwaddr base,omap_clk clk)2516  static struct omap_pwt_s *omap_pwt_init(MemoryRegion *system_memory,
2517                                          hwaddr base,
2518                                          omap_clk clk)
2519  {
2520      struct omap_pwt_s *s = g_malloc0(sizeof(*s));
2521      s->clk = clk;
2522      omap_pwt_reset(s);
2523  
2524      memory_region_init_io(&s->iomem, NULL, &omap_pwt_ops, s,
2525                            "omap-pwt", 0x800);
2526      memory_region_add_subregion(system_memory, base, &s->iomem);
2527      return s;
2528  }
2529  
2530  /* Real-time Clock module */
2531  struct omap_rtc_s {
2532      MemoryRegion iomem;
2533      qemu_irq irq;
2534      qemu_irq alarm;
2535      QEMUTimer *clk;
2536  
2537      uint8_t interrupts;
2538      uint8_t status;
2539      int16_t comp_reg;
2540      int running;
2541      int pm_am;
2542      int auto_comp;
2543      int round;
2544      struct tm alarm_tm;
2545      time_t alarm_ti;
2546  
2547      struct tm current_tm;
2548      time_t ti;
2549      uint64_t tick;
2550  };
2551  
omap_rtc_interrupts_update(struct omap_rtc_s * s)2552  static void omap_rtc_interrupts_update(struct omap_rtc_s *s)
2553  {
2554      /* s->alarm is level-triggered */
2555      qemu_set_irq(s->alarm, (s->status >> 6) & 1);
2556  }
2557  
omap_rtc_alarm_update(struct omap_rtc_s * s)2558  static void omap_rtc_alarm_update(struct omap_rtc_s *s)
2559  {
2560      s->alarm_ti = mktimegm(&s->alarm_tm);
2561      if (s->alarm_ti == -1)
2562          printf("%s: conversion failed\n", __func__);
2563  }
2564  
omap_rtc_read(void * opaque,hwaddr addr,unsigned size)2565  static uint64_t omap_rtc_read(void *opaque, hwaddr addr, unsigned size)
2566  {
2567      struct omap_rtc_s *s = opaque;
2568      int offset = addr & OMAP_MPUI_REG_MASK;
2569      uint8_t i;
2570  
2571      if (size != 1) {
2572          return omap_badwidth_read8(opaque, addr);
2573      }
2574  
2575      switch (offset) {
2576      case 0x00:	/* SECONDS_REG */
2577          return to_bcd(s->current_tm.tm_sec);
2578  
2579      case 0x04:	/* MINUTES_REG */
2580          return to_bcd(s->current_tm.tm_min);
2581  
2582      case 0x08:	/* HOURS_REG */
2583          if (s->pm_am)
2584              return ((s->current_tm.tm_hour > 11) << 7) |
2585                      to_bcd(((s->current_tm.tm_hour - 1) % 12) + 1);
2586          else
2587              return to_bcd(s->current_tm.tm_hour);
2588  
2589      case 0x0c:	/* DAYS_REG */
2590          return to_bcd(s->current_tm.tm_mday);
2591  
2592      case 0x10:	/* MONTHS_REG */
2593          return to_bcd(s->current_tm.tm_mon + 1);
2594  
2595      case 0x14:	/* YEARS_REG */
2596          return to_bcd(s->current_tm.tm_year % 100);
2597  
2598      case 0x18:	/* WEEK_REG */
2599          return s->current_tm.tm_wday;
2600  
2601      case 0x20:	/* ALARM_SECONDS_REG */
2602          return to_bcd(s->alarm_tm.tm_sec);
2603  
2604      case 0x24:	/* ALARM_MINUTES_REG */
2605          return to_bcd(s->alarm_tm.tm_min);
2606  
2607      case 0x28:	/* ALARM_HOURS_REG */
2608          if (s->pm_am)
2609              return ((s->alarm_tm.tm_hour > 11) << 7) |
2610                      to_bcd(((s->alarm_tm.tm_hour - 1) % 12) + 1);
2611          else
2612              return to_bcd(s->alarm_tm.tm_hour);
2613  
2614      case 0x2c:	/* ALARM_DAYS_REG */
2615          return to_bcd(s->alarm_tm.tm_mday);
2616  
2617      case 0x30:	/* ALARM_MONTHS_REG */
2618          return to_bcd(s->alarm_tm.tm_mon + 1);
2619  
2620      case 0x34:	/* ALARM_YEARS_REG */
2621          return to_bcd(s->alarm_tm.tm_year % 100);
2622  
2623      case 0x40:	/* RTC_CTRL_REG */
2624          return (s->pm_am << 3) | (s->auto_comp << 2) |
2625                  (s->round << 1) | s->running;
2626  
2627      case 0x44:	/* RTC_STATUS_REG */
2628          i = s->status;
2629          s->status &= ~0x3d;
2630          return i;
2631  
2632      case 0x48:	/* RTC_INTERRUPTS_REG */
2633          return s->interrupts;
2634  
2635      case 0x4c:	/* RTC_COMP_LSB_REG */
2636          return ((uint16_t) s->comp_reg) & 0xff;
2637  
2638      case 0x50:	/* RTC_COMP_MSB_REG */
2639          return ((uint16_t) s->comp_reg) >> 8;
2640      }
2641  
2642      OMAP_BAD_REG(addr);
2643      return 0;
2644  }
2645  
omap_rtc_write(void * opaque,hwaddr addr,uint64_t value,unsigned size)2646  static void omap_rtc_write(void *opaque, hwaddr addr,
2647                             uint64_t value, unsigned size)
2648  {
2649      struct omap_rtc_s *s = opaque;
2650      int offset = addr & OMAP_MPUI_REG_MASK;
2651      struct tm new_tm;
2652      time_t ti[2];
2653  
2654      if (size != 1) {
2655          omap_badwidth_write8(opaque, addr, value);
2656          return;
2657      }
2658  
2659      switch (offset) {
2660      case 0x00:	/* SECONDS_REG */
2661  #ifdef ALMDEBUG
2662          printf("RTC SEC_REG <-- %02x\n", value);
2663  #endif
2664          s->ti -= s->current_tm.tm_sec;
2665          s->ti += from_bcd(value);
2666          return;
2667  
2668      case 0x04:	/* MINUTES_REG */
2669  #ifdef ALMDEBUG
2670          printf("RTC MIN_REG <-- %02x\n", value);
2671  #endif
2672          s->ti -= s->current_tm.tm_min * 60;
2673          s->ti += from_bcd(value) * 60;
2674          return;
2675  
2676      case 0x08:	/* HOURS_REG */
2677  #ifdef ALMDEBUG
2678          printf("RTC HRS_REG <-- %02x\n", value);
2679  #endif
2680          s->ti -= s->current_tm.tm_hour * 3600;
2681          if (s->pm_am) {
2682              s->ti += (from_bcd(value & 0x3f) & 12) * 3600;
2683              s->ti += ((value >> 7) & 1) * 43200;
2684          } else
2685              s->ti += from_bcd(value & 0x3f) * 3600;
2686          return;
2687  
2688      case 0x0c:	/* DAYS_REG */
2689  #ifdef ALMDEBUG
2690          printf("RTC DAY_REG <-- %02x\n", value);
2691  #endif
2692          s->ti -= s->current_tm.tm_mday * 86400;
2693          s->ti += from_bcd(value) * 86400;
2694          return;
2695  
2696      case 0x10:	/* MONTHS_REG */
2697  #ifdef ALMDEBUG
2698          printf("RTC MTH_REG <-- %02x\n", value);
2699  #endif
2700          memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
2701          new_tm.tm_mon = from_bcd(value);
2702          ti[0] = mktimegm(&s->current_tm);
2703          ti[1] = mktimegm(&new_tm);
2704  
2705          if (ti[0] != -1 && ti[1] != -1) {
2706              s->ti -= ti[0];
2707              s->ti += ti[1];
2708          } else {
2709              /* A less accurate version */
2710              s->ti -= s->current_tm.tm_mon * 2592000;
2711              s->ti += from_bcd(value) * 2592000;
2712          }
2713          return;
2714  
2715      case 0x14:	/* YEARS_REG */
2716  #ifdef ALMDEBUG
2717          printf("RTC YRS_REG <-- %02x\n", value);
2718  #endif
2719          memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
2720          new_tm.tm_year += from_bcd(value) - (new_tm.tm_year % 100);
2721          ti[0] = mktimegm(&s->current_tm);
2722          ti[1] = mktimegm(&new_tm);
2723  
2724          if (ti[0] != -1 && ti[1] != -1) {
2725              s->ti -= ti[0];
2726              s->ti += ti[1];
2727          } else {
2728              /* A less accurate version */
2729              s->ti -= (time_t)(s->current_tm.tm_year % 100) * 31536000;
2730              s->ti += (time_t)from_bcd(value) * 31536000;
2731          }
2732          return;
2733  
2734      case 0x18:	/* WEEK_REG */
2735          return;	/* Ignored */
2736  
2737      case 0x20:	/* ALARM_SECONDS_REG */
2738  #ifdef ALMDEBUG
2739          printf("ALM SEC_REG <-- %02x\n", value);
2740  #endif
2741          s->alarm_tm.tm_sec = from_bcd(value);
2742          omap_rtc_alarm_update(s);
2743          return;
2744  
2745      case 0x24:	/* ALARM_MINUTES_REG */
2746  #ifdef ALMDEBUG
2747          printf("ALM MIN_REG <-- %02x\n", value);
2748  #endif
2749          s->alarm_tm.tm_min = from_bcd(value);
2750          omap_rtc_alarm_update(s);
2751          return;
2752  
2753      case 0x28:	/* ALARM_HOURS_REG */
2754  #ifdef ALMDEBUG
2755          printf("ALM HRS_REG <-- %02x\n", value);
2756  #endif
2757          if (s->pm_am)
2758              s->alarm_tm.tm_hour =
2759                      ((from_bcd(value & 0x3f)) % 12) +
2760                      ((value >> 7) & 1) * 12;
2761          else
2762              s->alarm_tm.tm_hour = from_bcd(value);
2763          omap_rtc_alarm_update(s);
2764          return;
2765  
2766      case 0x2c:	/* ALARM_DAYS_REG */
2767  #ifdef ALMDEBUG
2768          printf("ALM DAY_REG <-- %02x\n", value);
2769  #endif
2770          s->alarm_tm.tm_mday = from_bcd(value);
2771          omap_rtc_alarm_update(s);
2772          return;
2773  
2774      case 0x30:	/* ALARM_MONTHS_REG */
2775  #ifdef ALMDEBUG
2776          printf("ALM MON_REG <-- %02x\n", value);
2777  #endif
2778          s->alarm_tm.tm_mon = from_bcd(value);
2779          omap_rtc_alarm_update(s);
2780          return;
2781  
2782      case 0x34:	/* ALARM_YEARS_REG */
2783  #ifdef ALMDEBUG
2784          printf("ALM YRS_REG <-- %02x\n", value);
2785  #endif
2786          s->alarm_tm.tm_year = from_bcd(value);
2787          omap_rtc_alarm_update(s);
2788          return;
2789  
2790      case 0x40:	/* RTC_CTRL_REG */
2791  #ifdef ALMDEBUG
2792          printf("RTC CONTROL <-- %02x\n", value);
2793  #endif
2794          s->pm_am = (value >> 3) & 1;
2795          s->auto_comp = (value >> 2) & 1;
2796          s->round = (value >> 1) & 1;
2797          s->running = value & 1;
2798          s->status &= 0xfd;
2799          s->status |= s->running << 1;
2800          return;
2801  
2802      case 0x44:	/* RTC_STATUS_REG */
2803  #ifdef ALMDEBUG
2804          printf("RTC STATUSL <-- %02x\n", value);
2805  #endif
2806          s->status &= ~((value & 0xc0) ^ 0x80);
2807          omap_rtc_interrupts_update(s);
2808          return;
2809  
2810      case 0x48:	/* RTC_INTERRUPTS_REG */
2811  #ifdef ALMDEBUG
2812          printf("RTC INTRS <-- %02x\n", value);
2813  #endif
2814          s->interrupts = value;
2815          return;
2816  
2817      case 0x4c:	/* RTC_COMP_LSB_REG */
2818  #ifdef ALMDEBUG
2819          printf("RTC COMPLSB <-- %02x\n", value);
2820  #endif
2821          s->comp_reg &= 0xff00;
2822          s->comp_reg |= 0x00ff & value;
2823          return;
2824  
2825      case 0x50:	/* RTC_COMP_MSB_REG */
2826  #ifdef ALMDEBUG
2827          printf("RTC COMPMSB <-- %02x\n", value);
2828  #endif
2829          s->comp_reg &= 0x00ff;
2830          s->comp_reg |= 0xff00 & (value << 8);
2831          return;
2832  
2833      default:
2834          OMAP_BAD_REG(addr);
2835          return;
2836      }
2837  }
2838  
2839  static const MemoryRegionOps omap_rtc_ops = {
2840      .read = omap_rtc_read,
2841      .write = omap_rtc_write,
2842      .endianness = DEVICE_NATIVE_ENDIAN,
2843  };
2844  
omap_rtc_tick(void * opaque)2845  static void omap_rtc_tick(void *opaque)
2846  {
2847      struct omap_rtc_s *s = opaque;
2848  
2849      if (s->round) {
2850          /* Round to nearest full minute.  */
2851          if (s->current_tm.tm_sec < 30)
2852              s->ti -= s->current_tm.tm_sec;
2853          else
2854              s->ti += 60 - s->current_tm.tm_sec;
2855  
2856          s->round = 0;
2857      }
2858  
2859      localtime_r(&s->ti, &s->current_tm);
2860  
2861      if ((s->interrupts & 0x08) && s->ti == s->alarm_ti) {
2862          s->status |= 0x40;
2863          omap_rtc_interrupts_update(s);
2864      }
2865  
2866      if (s->interrupts & 0x04)
2867          switch (s->interrupts & 3) {
2868          case 0:
2869              s->status |= 0x04;
2870              qemu_irq_pulse(s->irq);
2871              break;
2872          case 1:
2873              if (s->current_tm.tm_sec)
2874                  break;
2875              s->status |= 0x08;
2876              qemu_irq_pulse(s->irq);
2877              break;
2878          case 2:
2879              if (s->current_tm.tm_sec || s->current_tm.tm_min)
2880                  break;
2881              s->status |= 0x10;
2882              qemu_irq_pulse(s->irq);
2883              break;
2884          case 3:
2885              if (s->current_tm.tm_sec ||
2886                              s->current_tm.tm_min || s->current_tm.tm_hour)
2887                  break;
2888              s->status |= 0x20;
2889              qemu_irq_pulse(s->irq);
2890              break;
2891          }
2892  
2893      /* Move on */
2894      if (s->running)
2895          s->ti ++;
2896      s->tick += 1000;
2897  
2898      /*
2899       * Every full hour add a rough approximation of the compensation
2900       * register to the 32kHz Timer (which drives the RTC) value.
2901       */
2902      if (s->auto_comp && !s->current_tm.tm_sec && !s->current_tm.tm_min)
2903          s->tick += s->comp_reg * 1000 / 32768;
2904  
2905      timer_mod(s->clk, s->tick);
2906  }
2907  
omap_rtc_reset(struct omap_rtc_s * s)2908  static void omap_rtc_reset(struct omap_rtc_s *s)
2909  {
2910      struct tm tm;
2911  
2912      s->interrupts = 0;
2913      s->comp_reg = 0;
2914      s->running = 0;
2915      s->pm_am = 0;
2916      s->auto_comp = 0;
2917      s->round = 0;
2918      s->tick = qemu_clock_get_ms(rtc_clock);
2919      memset(&s->alarm_tm, 0, sizeof(s->alarm_tm));
2920      s->alarm_tm.tm_mday = 0x01;
2921      s->status = 1 << 7;
2922      qemu_get_timedate(&tm, 0);
2923      s->ti = mktimegm(&tm);
2924  
2925      omap_rtc_alarm_update(s);
2926      omap_rtc_tick(s);
2927  }
2928  
omap_rtc_init(MemoryRegion * system_memory,hwaddr base,qemu_irq timerirq,qemu_irq alarmirq,omap_clk clk)2929  static struct omap_rtc_s *omap_rtc_init(MemoryRegion *system_memory,
2930                                          hwaddr base,
2931                                          qemu_irq timerirq, qemu_irq alarmirq,
2932                                          omap_clk clk)
2933  {
2934      struct omap_rtc_s *s = g_new0(struct omap_rtc_s, 1);
2935  
2936      s->irq = timerirq;
2937      s->alarm = alarmirq;
2938      s->clk = timer_new_ms(rtc_clock, omap_rtc_tick, s);
2939  
2940      omap_rtc_reset(s);
2941  
2942      memory_region_init_io(&s->iomem, NULL, &omap_rtc_ops, s,
2943                            "omap-rtc", 0x800);
2944      memory_region_add_subregion(system_memory, base, &s->iomem);
2945  
2946      return s;
2947  }
2948  
2949  /* Multi-channel Buffered Serial Port interfaces */
2950  struct omap_mcbsp_s {
2951      MemoryRegion iomem;
2952      qemu_irq txirq;
2953      qemu_irq rxirq;
2954      qemu_irq txdrq;
2955      qemu_irq rxdrq;
2956  
2957      uint16_t spcr[2];
2958      uint16_t rcr[2];
2959      uint16_t xcr[2];
2960      uint16_t srgr[2];
2961      uint16_t mcr[2];
2962      uint16_t pcr;
2963      uint16_t rcer[8];
2964      uint16_t xcer[8];
2965      int tx_rate;
2966      int rx_rate;
2967      int tx_req;
2968      int rx_req;
2969  
2970      I2SCodec *codec;
2971      QEMUTimer *source_timer;
2972      QEMUTimer *sink_timer;
2973  };
2974  
omap_mcbsp_intr_update(struct omap_mcbsp_s * s)2975  static void omap_mcbsp_intr_update(struct omap_mcbsp_s *s)
2976  {
2977      int irq;
2978  
2979      switch ((s->spcr[0] >> 4) & 3) {			/* RINTM */
2980      case 0:
2981          irq = (s->spcr[0] >> 1) & 1;			/* RRDY */
2982          break;
2983      case 3:
2984          irq = (s->spcr[0] >> 3) & 1;			/* RSYNCERR */
2985          break;
2986      default:
2987          irq = 0;
2988          break;
2989      }
2990  
2991      if (irq)
2992          qemu_irq_pulse(s->rxirq);
2993  
2994      switch ((s->spcr[1] >> 4) & 3) {			/* XINTM */
2995      case 0:
2996          irq = (s->spcr[1] >> 1) & 1;			/* XRDY */
2997          break;
2998      case 3:
2999          irq = (s->spcr[1] >> 3) & 1;			/* XSYNCERR */
3000          break;
3001      default:
3002          irq = 0;
3003          break;
3004      }
3005  
3006      if (irq)
3007          qemu_irq_pulse(s->txirq);
3008  }
3009  
omap_mcbsp_rx_newdata(struct omap_mcbsp_s * s)3010  static void omap_mcbsp_rx_newdata(struct omap_mcbsp_s *s)
3011  {
3012      if ((s->spcr[0] >> 1) & 1)				/* RRDY */
3013          s->spcr[0] |= 1 << 2;				/* RFULL */
3014      s->spcr[0] |= 1 << 1;				/* RRDY */
3015      qemu_irq_raise(s->rxdrq);
3016      omap_mcbsp_intr_update(s);
3017  }
3018  
omap_mcbsp_source_tick(void * opaque)3019  static void omap_mcbsp_source_tick(void *opaque)
3020  {
3021      struct omap_mcbsp_s *s = opaque;
3022      static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
3023  
3024      if (!s->rx_rate)
3025          return;
3026      if (s->rx_req)
3027          printf("%s: Rx FIFO overrun\n", __func__);
3028  
3029      s->rx_req = s->rx_rate << bps[(s->rcr[0] >> 5) & 7];
3030  
3031      omap_mcbsp_rx_newdata(s);
3032      timer_mod(s->source_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
3033                     NANOSECONDS_PER_SECOND);
3034  }
3035  
omap_mcbsp_rx_start(struct omap_mcbsp_s * s)3036  static void omap_mcbsp_rx_start(struct omap_mcbsp_s *s)
3037  {
3038      if (!s->codec || !s->codec->rts)
3039          omap_mcbsp_source_tick(s);
3040      else if (s->codec->in.len) {
3041          s->rx_req = s->codec->in.len;
3042          omap_mcbsp_rx_newdata(s);
3043      }
3044  }
3045  
omap_mcbsp_rx_stop(struct omap_mcbsp_s * s)3046  static void omap_mcbsp_rx_stop(struct omap_mcbsp_s *s)
3047  {
3048      timer_del(s->source_timer);
3049  }
3050  
omap_mcbsp_rx_done(struct omap_mcbsp_s * s)3051  static void omap_mcbsp_rx_done(struct omap_mcbsp_s *s)
3052  {
3053      s->spcr[0] &= ~(1 << 1);				/* RRDY */
3054      qemu_irq_lower(s->rxdrq);
3055      omap_mcbsp_intr_update(s);
3056  }
3057  
omap_mcbsp_tx_newdata(struct omap_mcbsp_s * s)3058  static void omap_mcbsp_tx_newdata(struct omap_mcbsp_s *s)
3059  {
3060      s->spcr[1] |= 1 << 1;				/* XRDY */
3061      qemu_irq_raise(s->txdrq);
3062      omap_mcbsp_intr_update(s);
3063  }
3064  
omap_mcbsp_sink_tick(void * opaque)3065  static void omap_mcbsp_sink_tick(void *opaque)
3066  {
3067      struct omap_mcbsp_s *s = opaque;
3068      static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
3069  
3070      if (!s->tx_rate)
3071          return;
3072      if (s->tx_req)
3073          printf("%s: Tx FIFO underrun\n", __func__);
3074  
3075      s->tx_req = s->tx_rate << bps[(s->xcr[0] >> 5) & 7];
3076  
3077      omap_mcbsp_tx_newdata(s);
3078      timer_mod(s->sink_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
3079                     NANOSECONDS_PER_SECOND);
3080  }
3081  
omap_mcbsp_tx_start(struct omap_mcbsp_s * s)3082  static void omap_mcbsp_tx_start(struct omap_mcbsp_s *s)
3083  {
3084      if (!s->codec || !s->codec->cts)
3085          omap_mcbsp_sink_tick(s);
3086      else if (s->codec->out.size) {
3087          s->tx_req = s->codec->out.size;
3088          omap_mcbsp_tx_newdata(s);
3089      }
3090  }
3091  
omap_mcbsp_tx_done(struct omap_mcbsp_s * s)3092  static void omap_mcbsp_tx_done(struct omap_mcbsp_s *s)
3093  {
3094      s->spcr[1] &= ~(1 << 1);				/* XRDY */
3095      qemu_irq_lower(s->txdrq);
3096      omap_mcbsp_intr_update(s);
3097      if (s->codec && s->codec->cts)
3098          s->codec->tx_swallow(s->codec->opaque);
3099  }
3100  
omap_mcbsp_tx_stop(struct omap_mcbsp_s * s)3101  static void omap_mcbsp_tx_stop(struct omap_mcbsp_s *s)
3102  {
3103      s->tx_req = 0;
3104      omap_mcbsp_tx_done(s);
3105      timer_del(s->sink_timer);
3106  }
3107  
omap_mcbsp_req_update(struct omap_mcbsp_s * s)3108  static void omap_mcbsp_req_update(struct omap_mcbsp_s *s)
3109  {
3110      int prev_rx_rate, prev_tx_rate;
3111      int rx_rate = 0, tx_rate = 0;
3112      int cpu_rate = 1500000;	/* XXX */
3113  
3114      /* TODO: check CLKSTP bit */
3115      if (s->spcr[1] & (1 << 6)) {			/* GRST */
3116          if (s->spcr[0] & (1 << 0)) {			/* RRST */
3117              if ((s->srgr[1] & (1 << 13)) &&		/* CLKSM */
3118                              (s->pcr & (1 << 8))) {	/* CLKRM */
3119                  if (~s->pcr & (1 << 7))			/* SCLKME */
3120                      rx_rate = cpu_rate /
3121                              ((s->srgr[0] & 0xff) + 1);	/* CLKGDV */
3122              } else
3123                  if (s->codec)
3124                      rx_rate = s->codec->rx_rate;
3125          }
3126  
3127          if (s->spcr[1] & (1 << 0)) {			/* XRST */
3128              if ((s->srgr[1] & (1 << 13)) &&		/* CLKSM */
3129                              (s->pcr & (1 << 9))) {	/* CLKXM */
3130                  if (~s->pcr & (1 << 7))			/* SCLKME */
3131                      tx_rate = cpu_rate /
3132                              ((s->srgr[0] & 0xff) + 1);	/* CLKGDV */
3133              } else
3134                  if (s->codec)
3135                      tx_rate = s->codec->tx_rate;
3136          }
3137      }
3138      prev_tx_rate = s->tx_rate;
3139      prev_rx_rate = s->rx_rate;
3140      s->tx_rate = tx_rate;
3141      s->rx_rate = rx_rate;
3142  
3143      if (s->codec)
3144          s->codec->set_rate(s->codec->opaque, rx_rate, tx_rate);
3145  
3146      if (!prev_tx_rate && tx_rate)
3147          omap_mcbsp_tx_start(s);
3148      else if (s->tx_rate && !tx_rate)
3149          omap_mcbsp_tx_stop(s);
3150  
3151      if (!prev_rx_rate && rx_rate)
3152          omap_mcbsp_rx_start(s);
3153      else if (prev_tx_rate && !tx_rate)
3154          omap_mcbsp_rx_stop(s);
3155  }
3156  
omap_mcbsp_read(void * opaque,hwaddr addr,unsigned size)3157  static uint64_t omap_mcbsp_read(void *opaque, hwaddr addr,
3158                                  unsigned size)
3159  {
3160      struct omap_mcbsp_s *s = opaque;
3161      int offset = addr & OMAP_MPUI_REG_MASK;
3162      uint16_t ret;
3163  
3164      if (size != 2) {
3165          return omap_badwidth_read16(opaque, addr);
3166      }
3167  
3168      switch (offset) {
3169      case 0x00:	/* DRR2 */
3170          if (((s->rcr[0] >> 5) & 7) < 3)			/* RWDLEN1 */
3171              return 0x0000;
3172          /* Fall through.  */
3173      case 0x02:	/* DRR1 */
3174          if (s->rx_req < 2) {
3175              printf("%s: Rx FIFO underrun\n", __func__);
3176              omap_mcbsp_rx_done(s);
3177          } else {
3178              s->tx_req -= 2;
3179              if (s->codec && s->codec->in.len >= 2) {
3180                  ret = s->codec->in.fifo[s->codec->in.start ++] << 8;
3181                  ret |= s->codec->in.fifo[s->codec->in.start ++];
3182                  s->codec->in.len -= 2;
3183              } else
3184                  ret = 0x0000;
3185              if (!s->tx_req)
3186                  omap_mcbsp_rx_done(s);
3187              return ret;
3188          }
3189          return 0x0000;
3190  
3191      case 0x04:	/* DXR2 */
3192      case 0x06:	/* DXR1 */
3193          return 0x0000;
3194  
3195      case 0x08:	/* SPCR2 */
3196          return s->spcr[1];
3197      case 0x0a:	/* SPCR1 */
3198          return s->spcr[0];
3199      case 0x0c:	/* RCR2 */
3200          return s->rcr[1];
3201      case 0x0e:	/* RCR1 */
3202          return s->rcr[0];
3203      case 0x10:	/* XCR2 */
3204          return s->xcr[1];
3205      case 0x12:	/* XCR1 */
3206          return s->xcr[0];
3207      case 0x14:	/* SRGR2 */
3208          return s->srgr[1];
3209      case 0x16:	/* SRGR1 */
3210          return s->srgr[0];
3211      case 0x18:	/* MCR2 */
3212          return s->mcr[1];
3213      case 0x1a:	/* MCR1 */
3214          return s->mcr[0];
3215      case 0x1c:	/* RCERA */
3216          return s->rcer[0];
3217      case 0x1e:	/* RCERB */
3218          return s->rcer[1];
3219      case 0x20:	/* XCERA */
3220          return s->xcer[0];
3221      case 0x22:	/* XCERB */
3222          return s->xcer[1];
3223      case 0x24:	/* PCR0 */
3224          return s->pcr;
3225      case 0x26:	/* RCERC */
3226          return s->rcer[2];
3227      case 0x28:	/* RCERD */
3228          return s->rcer[3];
3229      case 0x2a:	/* XCERC */
3230          return s->xcer[2];
3231      case 0x2c:	/* XCERD */
3232          return s->xcer[3];
3233      case 0x2e:	/* RCERE */
3234          return s->rcer[4];
3235      case 0x30:	/* RCERF */
3236          return s->rcer[5];
3237      case 0x32:	/* XCERE */
3238          return s->xcer[4];
3239      case 0x34:	/* XCERF */
3240          return s->xcer[5];
3241      case 0x36:	/* RCERG */
3242          return s->rcer[6];
3243      case 0x38:	/* RCERH */
3244          return s->rcer[7];
3245      case 0x3a:	/* XCERG */
3246          return s->xcer[6];
3247      case 0x3c:	/* XCERH */
3248          return s->xcer[7];
3249      }
3250  
3251      OMAP_BAD_REG(addr);
3252      return 0;
3253  }
3254  
omap_mcbsp_writeh(void * opaque,hwaddr addr,uint32_t value)3255  static void omap_mcbsp_writeh(void *opaque, hwaddr addr,
3256                  uint32_t value)
3257  {
3258      struct omap_mcbsp_s *s = opaque;
3259      int offset = addr & OMAP_MPUI_REG_MASK;
3260  
3261      switch (offset) {
3262      case 0x00:	/* DRR2 */
3263      case 0x02:	/* DRR1 */
3264          OMAP_RO_REG(addr);
3265          return;
3266  
3267      case 0x04:	/* DXR2 */
3268          if (((s->xcr[0] >> 5) & 7) < 3)			/* XWDLEN1 */
3269              return;
3270          /* Fall through.  */
3271      case 0x06:	/* DXR1 */
3272          if (s->tx_req > 1) {
3273              s->tx_req -= 2;
3274              if (s->codec && s->codec->cts) {
3275                  s->codec->out.fifo[s->codec->out.len ++] = (value >> 8) & 0xff;
3276                  s->codec->out.fifo[s->codec->out.len ++] = (value >> 0) & 0xff;
3277              }
3278              if (s->tx_req < 2)
3279                  omap_mcbsp_tx_done(s);
3280          } else
3281              printf("%s: Tx FIFO overrun\n", __func__);
3282          return;
3283  
3284      case 0x08:	/* SPCR2 */
3285          s->spcr[1] &= 0x0002;
3286          s->spcr[1] |= 0x03f9 & value;
3287          s->spcr[1] |= 0x0004 & (value << 2);		/* XEMPTY := XRST */
3288          if (~value & 1)					/* XRST */
3289              s->spcr[1] &= ~6;
3290          omap_mcbsp_req_update(s);
3291          return;
3292      case 0x0a:	/* SPCR1 */
3293          s->spcr[0] &= 0x0006;
3294          s->spcr[0] |= 0xf8f9 & value;
3295          if (value & (1 << 15))				/* DLB */
3296              printf("%s: Digital Loopback mode enable attempt\n", __func__);
3297          if (~value & 1) {				/* RRST */
3298              s->spcr[0] &= ~6;
3299              s->rx_req = 0;
3300              omap_mcbsp_rx_done(s);
3301          }
3302          omap_mcbsp_req_update(s);
3303          return;
3304  
3305      case 0x0c:	/* RCR2 */
3306          s->rcr[1] = value & 0xffff;
3307          return;
3308      case 0x0e:	/* RCR1 */
3309          s->rcr[0] = value & 0x7fe0;
3310          return;
3311      case 0x10:	/* XCR2 */
3312          s->xcr[1] = value & 0xffff;
3313          return;
3314      case 0x12:	/* XCR1 */
3315          s->xcr[0] = value & 0x7fe0;
3316          return;
3317      case 0x14:	/* SRGR2 */
3318          s->srgr[1] = value & 0xffff;
3319          omap_mcbsp_req_update(s);
3320          return;
3321      case 0x16:	/* SRGR1 */
3322          s->srgr[0] = value & 0xffff;
3323          omap_mcbsp_req_update(s);
3324          return;
3325      case 0x18:	/* MCR2 */
3326          s->mcr[1] = value & 0x03e3;
3327          if (value & 3)					/* XMCM */
3328              printf("%s: Tx channel selection mode enable attempt\n", __func__);
3329          return;
3330      case 0x1a:	/* MCR1 */
3331          s->mcr[0] = value & 0x03e1;
3332          if (value & 1)					/* RMCM */
3333              printf("%s: Rx channel selection mode enable attempt\n", __func__);
3334          return;
3335      case 0x1c:	/* RCERA */
3336          s->rcer[0] = value & 0xffff;
3337          return;
3338      case 0x1e:	/* RCERB */
3339          s->rcer[1] = value & 0xffff;
3340          return;
3341      case 0x20:	/* XCERA */
3342          s->xcer[0] = value & 0xffff;
3343          return;
3344      case 0x22:	/* XCERB */
3345          s->xcer[1] = value & 0xffff;
3346          return;
3347      case 0x24:	/* PCR0 */
3348          s->pcr = value & 0x7faf;
3349          return;
3350      case 0x26:	/* RCERC */
3351          s->rcer[2] = value & 0xffff;
3352          return;
3353      case 0x28:	/* RCERD */
3354          s->rcer[3] = value & 0xffff;
3355          return;
3356      case 0x2a:	/* XCERC */
3357          s->xcer[2] = value & 0xffff;
3358          return;
3359      case 0x2c:	/* XCERD */
3360          s->xcer[3] = value & 0xffff;
3361          return;
3362      case 0x2e:	/* RCERE */
3363          s->rcer[4] = value & 0xffff;
3364          return;
3365      case 0x30:	/* RCERF */
3366          s->rcer[5] = value & 0xffff;
3367          return;
3368      case 0x32:	/* XCERE */
3369          s->xcer[4] = value & 0xffff;
3370          return;
3371      case 0x34:	/* XCERF */
3372          s->xcer[5] = value & 0xffff;
3373          return;
3374      case 0x36:	/* RCERG */
3375          s->rcer[6] = value & 0xffff;
3376          return;
3377      case 0x38:	/* RCERH */
3378          s->rcer[7] = value & 0xffff;
3379          return;
3380      case 0x3a:	/* XCERG */
3381          s->xcer[6] = value & 0xffff;
3382          return;
3383      case 0x3c:	/* XCERH */
3384          s->xcer[7] = value & 0xffff;
3385          return;
3386      }
3387  
3388      OMAP_BAD_REG(addr);
3389  }
3390  
omap_mcbsp_writew(void * opaque,hwaddr addr,uint32_t value)3391  static void omap_mcbsp_writew(void *opaque, hwaddr addr,
3392                  uint32_t value)
3393  {
3394      struct omap_mcbsp_s *s = opaque;
3395      int offset = addr & OMAP_MPUI_REG_MASK;
3396  
3397      if (offset == 0x04) {				/* DXR */
3398          if (((s->xcr[0] >> 5) & 7) < 3)			/* XWDLEN1 */
3399              return;
3400          if (s->tx_req > 3) {
3401              s->tx_req -= 4;
3402              if (s->codec && s->codec->cts) {
3403                  s->codec->out.fifo[s->codec->out.len ++] =
3404                          (value >> 24) & 0xff;
3405                  s->codec->out.fifo[s->codec->out.len ++] =
3406                          (value >> 16) & 0xff;
3407                  s->codec->out.fifo[s->codec->out.len ++] =
3408                          (value >> 8) & 0xff;
3409                  s->codec->out.fifo[s->codec->out.len ++] =
3410                          (value >> 0) & 0xff;
3411              }
3412              if (s->tx_req < 4)
3413                  omap_mcbsp_tx_done(s);
3414          } else
3415              printf("%s: Tx FIFO overrun\n", __func__);
3416          return;
3417      }
3418  
3419      omap_badwidth_write16(opaque, addr, value);
3420  }
3421  
omap_mcbsp_write(void * opaque,hwaddr addr,uint64_t value,unsigned size)3422  static void omap_mcbsp_write(void *opaque, hwaddr addr,
3423                               uint64_t value, unsigned size)
3424  {
3425      switch (size) {
3426      case 2:
3427          omap_mcbsp_writeh(opaque, addr, value);
3428          break;
3429      case 4:
3430          omap_mcbsp_writew(opaque, addr, value);
3431          break;
3432      default:
3433          omap_badwidth_write16(opaque, addr, value);
3434      }
3435  }
3436  
3437  static const MemoryRegionOps omap_mcbsp_ops = {
3438      .read = omap_mcbsp_read,
3439      .write = omap_mcbsp_write,
3440      .endianness = DEVICE_NATIVE_ENDIAN,
3441  };
3442  
omap_mcbsp_reset(struct omap_mcbsp_s * s)3443  static void omap_mcbsp_reset(struct omap_mcbsp_s *s)
3444  {
3445      memset(&s->spcr, 0, sizeof(s->spcr));
3446      memset(&s->rcr, 0, sizeof(s->rcr));
3447      memset(&s->xcr, 0, sizeof(s->xcr));
3448      s->srgr[0] = 0x0001;
3449      s->srgr[1] = 0x2000;
3450      memset(&s->mcr, 0, sizeof(s->mcr));
3451      memset(&s->pcr, 0, sizeof(s->pcr));
3452      memset(&s->rcer, 0, sizeof(s->rcer));
3453      memset(&s->xcer, 0, sizeof(s->xcer));
3454      s->tx_req = 0;
3455      s->rx_req = 0;
3456      s->tx_rate = 0;
3457      s->rx_rate = 0;
3458      timer_del(s->source_timer);
3459      timer_del(s->sink_timer);
3460  }
3461  
omap_mcbsp_init(MemoryRegion * system_memory,hwaddr base,qemu_irq txirq,qemu_irq rxirq,qemu_irq * dma,omap_clk clk)3462  static struct omap_mcbsp_s *omap_mcbsp_init(MemoryRegion *system_memory,
3463                                              hwaddr base,
3464                                              qemu_irq txirq, qemu_irq rxirq,
3465                                              qemu_irq *dma, omap_clk clk)
3466  {
3467      struct omap_mcbsp_s *s = g_new0(struct omap_mcbsp_s, 1);
3468  
3469      s->txirq = txirq;
3470      s->rxirq = rxirq;
3471      s->txdrq = dma[0];
3472      s->rxdrq = dma[1];
3473      s->sink_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_mcbsp_sink_tick, s);
3474      s->source_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_mcbsp_source_tick, s);
3475      omap_mcbsp_reset(s);
3476  
3477      memory_region_init_io(&s->iomem, NULL, &omap_mcbsp_ops, s, "omap-mcbsp", 0x800);
3478      memory_region_add_subregion(system_memory, base, &s->iomem);
3479  
3480      return s;
3481  }
3482  
omap_mcbsp_i2s_swallow(void * opaque,int line,int level)3483  static void omap_mcbsp_i2s_swallow(void *opaque, int line, int level)
3484  {
3485      struct omap_mcbsp_s *s = opaque;
3486  
3487      if (s->rx_rate) {
3488          s->rx_req = s->codec->in.len;
3489          omap_mcbsp_rx_newdata(s);
3490      }
3491  }
3492  
omap_mcbsp_i2s_start(void * opaque,int line,int level)3493  static void omap_mcbsp_i2s_start(void *opaque, int line, int level)
3494  {
3495      struct omap_mcbsp_s *s = opaque;
3496  
3497      if (s->tx_rate) {
3498          s->tx_req = s->codec->out.size;
3499          omap_mcbsp_tx_newdata(s);
3500      }
3501  }
3502  
omap_mcbsp_i2s_attach(struct omap_mcbsp_s * s,I2SCodec * slave)3503  void omap_mcbsp_i2s_attach(struct omap_mcbsp_s *s, I2SCodec *slave)
3504  {
3505      s->codec = slave;
3506      slave->rx_swallow = qemu_allocate_irq(omap_mcbsp_i2s_swallow, s, 0);
3507      slave->tx_start = qemu_allocate_irq(omap_mcbsp_i2s_start, s, 0);
3508  }
3509  
3510  /* LED Pulse Generators */
3511  struct omap_lpg_s {
3512      MemoryRegion iomem;
3513      QEMUTimer *tm;
3514  
3515      uint8_t control;
3516      uint8_t power;
3517      int64_t on;
3518      int64_t period;
3519      int clk;
3520      int cycle;
3521  };
3522  
omap_lpg_tick(void * opaque)3523  static void omap_lpg_tick(void *opaque)
3524  {
3525      struct omap_lpg_s *s = opaque;
3526  
3527      if (s->cycle)
3528          timer_mod(s->tm, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + s->period - s->on);
3529      else
3530          timer_mod(s->tm, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + s->on);
3531  
3532      s->cycle = !s->cycle;
3533      printf("%s: LED is %s\n", __func__, s->cycle ? "on" : "off");
3534  }
3535  
omap_lpg_update(struct omap_lpg_s * s)3536  static void omap_lpg_update(struct omap_lpg_s *s)
3537  {
3538      int64_t on, period = 1, ticks = 1000;
3539      static const int per[8] = { 1, 2, 4, 8, 12, 16, 20, 24 };
3540  
3541      if (~s->control & (1 << 6))					/* LPGRES */
3542          on = 0;
3543      else if (s->control & (1 << 7))				/* PERM_ON */
3544          on = period;
3545      else {
3546          period = muldiv64(ticks, per[s->control & 7],		/* PERCTRL */
3547                          256 / 32);
3548          on = (s->clk && s->power) ? muldiv64(ticks,
3549                          per[(s->control >> 3) & 7], 256) : 0;	/* ONCTRL */
3550      }
3551  
3552      timer_del(s->tm);
3553      if (on == period && s->on < s->period)
3554          printf("%s: LED is on\n", __func__);
3555      else if (on == 0 && s->on)
3556          printf("%s: LED is off\n", __func__);
3557      else if (on && (on != s->on || period != s->period)) {
3558          s->cycle = 0;
3559          s->on = on;
3560          s->period = period;
3561          omap_lpg_tick(s);
3562          return;
3563      }
3564  
3565      s->on = on;
3566      s->period = period;
3567  }
3568  
omap_lpg_reset(struct omap_lpg_s * s)3569  static void omap_lpg_reset(struct omap_lpg_s *s)
3570  {
3571      s->control = 0x00;
3572      s->power = 0x00;
3573      s->clk = 1;
3574      omap_lpg_update(s);
3575  }
3576  
omap_lpg_read(void * opaque,hwaddr addr,unsigned size)3577  static uint64_t omap_lpg_read(void *opaque, hwaddr addr, unsigned size)
3578  {
3579      struct omap_lpg_s *s = opaque;
3580      int offset = addr & OMAP_MPUI_REG_MASK;
3581  
3582      if (size != 1) {
3583          return omap_badwidth_read8(opaque, addr);
3584      }
3585  
3586      switch (offset) {
3587      case 0x00:	/* LCR */
3588          return s->control;
3589  
3590      case 0x04:	/* PMR */
3591          return s->power;
3592      }
3593  
3594      OMAP_BAD_REG(addr);
3595      return 0;
3596  }
3597  
omap_lpg_write(void * opaque,hwaddr addr,uint64_t value,unsigned size)3598  static void omap_lpg_write(void *opaque, hwaddr addr,
3599                             uint64_t value, unsigned size)
3600  {
3601      struct omap_lpg_s *s = opaque;
3602      int offset = addr & OMAP_MPUI_REG_MASK;
3603  
3604      if (size != 1) {
3605          omap_badwidth_write8(opaque, addr, value);
3606          return;
3607      }
3608  
3609      switch (offset) {
3610      case 0x00:	/* LCR */
3611          if (~value & (1 << 6))					/* LPGRES */
3612              omap_lpg_reset(s);
3613          s->control = value & 0xff;
3614          omap_lpg_update(s);
3615          return;
3616  
3617      case 0x04:	/* PMR */
3618          s->power = value & 0x01;
3619          omap_lpg_update(s);
3620          return;
3621  
3622      default:
3623          OMAP_BAD_REG(addr);
3624          return;
3625      }
3626  }
3627  
3628  static const MemoryRegionOps omap_lpg_ops = {
3629      .read = omap_lpg_read,
3630      .write = omap_lpg_write,
3631      .endianness = DEVICE_NATIVE_ENDIAN,
3632  };
3633  
omap_lpg_clk_update(void * opaque,int line,int on)3634  static void omap_lpg_clk_update(void *opaque, int line, int on)
3635  {
3636      struct omap_lpg_s *s = opaque;
3637  
3638      s->clk = on;
3639      omap_lpg_update(s);
3640  }
3641  
omap_lpg_init(MemoryRegion * system_memory,hwaddr base,omap_clk clk)3642  static struct omap_lpg_s *omap_lpg_init(MemoryRegion *system_memory,
3643                                          hwaddr base, omap_clk clk)
3644  {
3645      struct omap_lpg_s *s = g_new0(struct omap_lpg_s, 1);
3646  
3647      s->tm = timer_new_ms(QEMU_CLOCK_VIRTUAL, omap_lpg_tick, s);
3648  
3649      omap_lpg_reset(s);
3650  
3651      memory_region_init_io(&s->iomem, NULL, &omap_lpg_ops, s, "omap-lpg", 0x800);
3652      memory_region_add_subregion(system_memory, base, &s->iomem);
3653  
3654      omap_clk_adduser(clk, qemu_allocate_irq(omap_lpg_clk_update, s, 0));
3655  
3656      return s;
3657  }
3658  
3659  /* MPUI Peripheral Bridge configuration */
omap_mpui_io_read(void * opaque,hwaddr addr,unsigned size)3660  static uint64_t omap_mpui_io_read(void *opaque, hwaddr addr,
3661                                    unsigned size)
3662  {
3663      if (size != 2) {
3664          return omap_badwidth_read16(opaque, addr);
3665      }
3666  
3667      if (addr == OMAP_MPUI_BASE)	/* CMR */
3668          return 0xfe4d;
3669  
3670      OMAP_BAD_REG(addr);
3671      return 0;
3672  }
3673  
omap_mpui_io_write(void * opaque,hwaddr addr,uint64_t value,unsigned size)3674  static void omap_mpui_io_write(void *opaque, hwaddr addr,
3675                                 uint64_t value, unsigned size)
3676  {
3677      /* FIXME: infinite loop */
3678      omap_badwidth_write16(opaque, addr, value);
3679  }
3680  
3681  static const MemoryRegionOps omap_mpui_io_ops = {
3682      .read = omap_mpui_io_read,
3683      .write = omap_mpui_io_write,
3684      .endianness = DEVICE_NATIVE_ENDIAN,
3685  };
3686  
omap_setup_mpui_io(MemoryRegion * system_memory,struct omap_mpu_state_s * mpu)3687  static void omap_setup_mpui_io(MemoryRegion *system_memory,
3688                                 struct omap_mpu_state_s *mpu)
3689  {
3690      memory_region_init_io(&mpu->mpui_io_iomem, NULL, &omap_mpui_io_ops, mpu,
3691                            "omap-mpui-io", 0x7fff);
3692      memory_region_add_subregion(system_memory, OMAP_MPUI_BASE,
3693                                  &mpu->mpui_io_iomem);
3694  }
3695  
3696  /* General chip reset */
omap1_mpu_reset(void * opaque)3697  static void omap1_mpu_reset(void *opaque)
3698  {
3699      struct omap_mpu_state_s *mpu = opaque;
3700  
3701      omap_dma_reset(mpu->dma);
3702      omap_mpu_timer_reset(mpu->timer[0]);
3703      omap_mpu_timer_reset(mpu->timer[1]);
3704      omap_mpu_timer_reset(mpu->timer[2]);
3705      omap_wd_timer_reset(mpu->wdt);
3706      omap_os_timer_reset(mpu->os_timer);
3707      omap_lcdc_reset(mpu->lcd);
3708      omap_ulpd_pm_reset(mpu);
3709      omap_pin_cfg_reset(mpu);
3710      omap_mpui_reset(mpu);
3711      omap_tipb_bridge_reset(mpu->private_tipb);
3712      omap_tipb_bridge_reset(mpu->public_tipb);
3713      omap_dpll_reset(mpu->dpll[0]);
3714      omap_dpll_reset(mpu->dpll[1]);
3715      omap_dpll_reset(mpu->dpll[2]);
3716      omap_uart_reset(mpu->uart[0]);
3717      omap_uart_reset(mpu->uart[1]);
3718      omap_uart_reset(mpu->uart[2]);
3719      omap_mmc_reset(mpu->mmc);
3720      omap_mpuio_reset(mpu->mpuio);
3721      omap_uwire_reset(mpu->microwire);
3722      omap_pwl_reset(mpu->pwl);
3723      omap_pwt_reset(mpu->pwt);
3724      omap_rtc_reset(mpu->rtc);
3725      omap_mcbsp_reset(mpu->mcbsp1);
3726      omap_mcbsp_reset(mpu->mcbsp2);
3727      omap_mcbsp_reset(mpu->mcbsp3);
3728      omap_lpg_reset(mpu->led[0]);
3729      omap_lpg_reset(mpu->led[1]);
3730      omap_clkm_reset(mpu);
3731      cpu_reset(CPU(mpu->cpu));
3732  }
3733  
3734  static const struct omap_map_s {
3735      hwaddr phys_dsp;
3736      hwaddr phys_mpu;
3737      uint32_t size;
3738      const char *name;
3739  } omap15xx_dsp_mm[] = {
3740      /* Strobe 0 */
3741      { 0xe1010000, 0xfffb0000, 0x800, "UART1 BT" },		/* CS0 */
3742      { 0xe1010800, 0xfffb0800, 0x800, "UART2 COM" },		/* CS1 */
3743      { 0xe1011800, 0xfffb1800, 0x800, "McBSP1 audio" },		/* CS3 */
3744      { 0xe1012000, 0xfffb2000, 0x800, "MCSI2 communication" },	/* CS4 */
3745      { 0xe1012800, 0xfffb2800, 0x800, "MCSI1 BT u-Law" },	/* CS5 */
3746      { 0xe1013000, 0xfffb3000, 0x800, "uWire" },			/* CS6 */
3747      { 0xe1013800, 0xfffb3800, 0x800, "I^2C" },			/* CS7 */
3748      { 0xe1014000, 0xfffb4000, 0x800, "USB W2FC" },		/* CS8 */
3749      { 0xe1014800, 0xfffb4800, 0x800, "RTC" },			/* CS9 */
3750      { 0xe1015000, 0xfffb5000, 0x800, "MPUIO" },			/* CS10 */
3751      { 0xe1015800, 0xfffb5800, 0x800, "PWL" },			/* CS11 */
3752      { 0xe1016000, 0xfffb6000, 0x800, "PWT" },			/* CS12 */
3753      { 0xe1017000, 0xfffb7000, 0x800, "McBSP3" },		/* CS14 */
3754      { 0xe1017800, 0xfffb7800, 0x800, "MMC" },			/* CS15 */
3755      { 0xe1019000, 0xfffb9000, 0x800, "32-kHz timer" },		/* CS18 */
3756      { 0xe1019800, 0xfffb9800, 0x800, "UART3" },			/* CS19 */
3757      { 0xe101c800, 0xfffbc800, 0x800, "TIPB switches" },		/* CS25 */
3758      /* Strobe 1 */
3759      { 0xe101e000, 0xfffce000, 0x800, "GPIOs" },			/* CS28 */
3760  
3761      { 0 }
3762  };
3763  
omap_setup_dsp_mapping(MemoryRegion * system_memory,const struct omap_map_s * map)3764  static void omap_setup_dsp_mapping(MemoryRegion *system_memory,
3765                                     const struct omap_map_s *map)
3766  {
3767      MemoryRegion *io;
3768  
3769      for (; map->phys_dsp; map ++) {
3770          io = g_new(MemoryRegion, 1);
3771          memory_region_init_alias(io, NULL, map->name,
3772                                   system_memory, map->phys_mpu, map->size);
3773          memory_region_add_subregion(system_memory, map->phys_dsp, io);
3774      }
3775  }
3776  
omap_mpu_wakeup(void * opaque,int irq,int req)3777  void omap_mpu_wakeup(void *opaque, int irq, int req)
3778  {
3779      struct omap_mpu_state_s *mpu = opaque;
3780      CPUState *cpu = CPU(mpu->cpu);
3781  
3782      if (cpu->halted) {
3783          cpu_interrupt(cpu, CPU_INTERRUPT_EXITTB);
3784      }
3785  }
3786  
3787  static const struct dma_irq_map omap1_dma_irq_map[] = {
3788      { 0, OMAP_INT_DMA_CH0_6 },
3789      { 0, OMAP_INT_DMA_CH1_7 },
3790      { 0, OMAP_INT_DMA_CH2_8 },
3791      { 0, OMAP_INT_DMA_CH3 },
3792      { 0, OMAP_INT_DMA_CH4 },
3793      { 0, OMAP_INT_DMA_CH5 },
3794      { 1, OMAP_INT_1610_DMA_CH6 },
3795      { 1, OMAP_INT_1610_DMA_CH7 },
3796      { 1, OMAP_INT_1610_DMA_CH8 },
3797      { 1, OMAP_INT_1610_DMA_CH9 },
3798      { 1, OMAP_INT_1610_DMA_CH10 },
3799      { 1, OMAP_INT_1610_DMA_CH11 },
3800      { 1, OMAP_INT_1610_DMA_CH12 },
3801      { 1, OMAP_INT_1610_DMA_CH13 },
3802      { 1, OMAP_INT_1610_DMA_CH14 },
3803      { 1, OMAP_INT_1610_DMA_CH15 }
3804  };
3805  
3806  /* DMA ports for OMAP1 */
omap_validate_emiff_addr(struct omap_mpu_state_s * s,hwaddr addr)3807  static int omap_validate_emiff_addr(struct omap_mpu_state_s *s,
3808                  hwaddr addr)
3809  {
3810      return range_covers_byte(OMAP_EMIFF_BASE, s->sdram_size, addr);
3811  }
3812  
omap_validate_emifs_addr(struct omap_mpu_state_s * s,hwaddr addr)3813  static int omap_validate_emifs_addr(struct omap_mpu_state_s *s,
3814                  hwaddr addr)
3815  {
3816      return range_covers_byte(OMAP_EMIFS_BASE, OMAP_EMIFF_BASE - OMAP_EMIFS_BASE,
3817                               addr);
3818  }
3819  
omap_validate_imif_addr(struct omap_mpu_state_s * s,hwaddr addr)3820  static int omap_validate_imif_addr(struct omap_mpu_state_s *s,
3821                  hwaddr addr)
3822  {
3823      return range_covers_byte(OMAP_IMIF_BASE, s->sram_size, addr);
3824  }
3825  
omap_validate_tipb_addr(struct omap_mpu_state_s * s,hwaddr addr)3826  static int omap_validate_tipb_addr(struct omap_mpu_state_s *s,
3827                  hwaddr addr)
3828  {
3829      return range_covers_byte(0xfffb0000, 0xffff0000 - 0xfffb0000, addr);
3830  }
3831  
omap_validate_local_addr(struct omap_mpu_state_s * s,hwaddr addr)3832  static int omap_validate_local_addr(struct omap_mpu_state_s *s,
3833                  hwaddr addr)
3834  {
3835      return range_covers_byte(OMAP_LOCALBUS_BASE, 0x1000000, addr);
3836  }
3837  
omap_validate_tipb_mpui_addr(struct omap_mpu_state_s * s,hwaddr addr)3838  static int omap_validate_tipb_mpui_addr(struct omap_mpu_state_s *s,
3839                  hwaddr addr)
3840  {
3841      return range_covers_byte(0xe1010000, 0xe1020004 - 0xe1010000, addr);
3842  }
3843  
omap310_mpu_init(MemoryRegion * dram,const char * cpu_type)3844  struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *dram,
3845                  const char *cpu_type)
3846  {
3847      int i;
3848      struct omap_mpu_state_s *s = g_new0(struct omap_mpu_state_s, 1);
3849      qemu_irq dma_irqs[6];
3850      DriveInfo *dinfo;
3851      SysBusDevice *busdev;
3852      MemoryRegion *system_memory = get_system_memory();
3853  
3854      /* Core */
3855      s->mpu_model = omap310;
3856      s->cpu = ARM_CPU(cpu_create(cpu_type));
3857      s->sdram_size = memory_region_size(dram);
3858      s->sram_size = OMAP15XX_SRAM_SIZE;
3859  
3860      s->wakeup = qemu_allocate_irq(omap_mpu_wakeup, s, 0);
3861  
3862      /* Clocks */
3863      omap_clk_init(s);
3864  
3865      /* Memory-mapped stuff */
3866      memory_region_init_ram(&s->imif_ram, NULL, "omap1.sram", s->sram_size,
3867                             &error_fatal);
3868      memory_region_add_subregion(system_memory, OMAP_IMIF_BASE, &s->imif_ram);
3869  
3870      omap_clkm_init(system_memory, 0xfffece00, 0xe1008000, s);
3871  
3872      s->ih[0] = qdev_new("omap-intc");
3873      qdev_prop_set_uint32(s->ih[0], "size", 0x100);
3874      omap_intc_set_iclk(OMAP_INTC(s->ih[0]), omap_findclk(s, "arminth_ck"));
3875      busdev = SYS_BUS_DEVICE(s->ih[0]);
3876      sysbus_realize_and_unref(busdev, &error_fatal);
3877      sysbus_connect_irq(busdev, 0,
3878                         qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ));
3879      sysbus_connect_irq(busdev, 1,
3880                         qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_FIQ));
3881      sysbus_mmio_map(busdev, 0, 0xfffecb00);
3882      s->ih[1] = qdev_new("omap-intc");
3883      qdev_prop_set_uint32(s->ih[1], "size", 0x800);
3884      omap_intc_set_iclk(OMAP_INTC(s->ih[1]), omap_findclk(s, "arminth_ck"));
3885      busdev = SYS_BUS_DEVICE(s->ih[1]);
3886      sysbus_realize_and_unref(busdev, &error_fatal);
3887      sysbus_connect_irq(busdev, 0,
3888                         qdev_get_gpio_in(s->ih[0], OMAP_INT_15XX_IH2_IRQ));
3889      /* The second interrupt controller's FIQ output is not wired up */
3890      sysbus_mmio_map(busdev, 0, 0xfffe0000);
3891  
3892      for (i = 0; i < 6; i++) {
3893          dma_irqs[i] = qdev_get_gpio_in(s->ih[omap1_dma_irq_map[i].ih],
3894                                         omap1_dma_irq_map[i].intr);
3895      }
3896      s->dma = omap_dma_init(0xfffed800, dma_irqs, system_memory,
3897                             qdev_get_gpio_in(s->ih[0], OMAP_INT_DMA_LCD),
3898                             s, omap_findclk(s, "dma_ck"), omap_dma_3_1);
3899  
3900      s->port[emiff    ].addr_valid = omap_validate_emiff_addr;
3901      s->port[emifs    ].addr_valid = omap_validate_emifs_addr;
3902      s->port[imif     ].addr_valid = omap_validate_imif_addr;
3903      s->port[tipb     ].addr_valid = omap_validate_tipb_addr;
3904      s->port[local    ].addr_valid = omap_validate_local_addr;
3905      s->port[tipb_mpui].addr_valid = omap_validate_tipb_mpui_addr;
3906  
3907      /* Register SDRAM and SRAM DMA ports for fast transfers.  */
3908      soc_dma_port_add_mem(s->dma, memory_region_get_ram_ptr(dram),
3909                           OMAP_EMIFF_BASE, s->sdram_size);
3910      soc_dma_port_add_mem(s->dma, memory_region_get_ram_ptr(&s->imif_ram),
3911                           OMAP_IMIF_BASE, s->sram_size);
3912  
3913      s->timer[0] = omap_mpu_timer_init(system_memory, 0xfffec500,
3914                      qdev_get_gpio_in(s->ih[0], OMAP_INT_TIMER1),
3915                      omap_findclk(s, "mputim_ck"));
3916      s->timer[1] = omap_mpu_timer_init(system_memory, 0xfffec600,
3917                      qdev_get_gpio_in(s->ih[0], OMAP_INT_TIMER2),
3918                      omap_findclk(s, "mputim_ck"));
3919      s->timer[2] = omap_mpu_timer_init(system_memory, 0xfffec700,
3920                      qdev_get_gpio_in(s->ih[0], OMAP_INT_TIMER3),
3921                      omap_findclk(s, "mputim_ck"));
3922  
3923      s->wdt = omap_wd_timer_init(system_memory, 0xfffec800,
3924                      qdev_get_gpio_in(s->ih[0], OMAP_INT_WD_TIMER),
3925                      omap_findclk(s, "armwdt_ck"));
3926  
3927      s->os_timer = omap_os_timer_init(system_memory, 0xfffb9000,
3928                      qdev_get_gpio_in(s->ih[1], OMAP_INT_OS_TIMER),
3929                      omap_findclk(s, "clk32-kHz"));
3930  
3931      s->lcd = omap_lcdc_init(system_memory, 0xfffec000,
3932                              qdev_get_gpio_in(s->ih[0], OMAP_INT_LCD_CTRL),
3933                              omap_dma_get_lcdch(s->dma),
3934                              omap_findclk(s, "lcd_ck"));
3935  
3936      omap_ulpd_pm_init(system_memory, 0xfffe0800, s);
3937      omap_pin_cfg_init(system_memory, 0xfffe1000, s);
3938      omap_id_init(system_memory, s);
3939  
3940      omap_mpui_init(system_memory, 0xfffec900, s);
3941  
3942      s->private_tipb = omap_tipb_bridge_init(system_memory, 0xfffeca00,
3943                      qdev_get_gpio_in(s->ih[0], OMAP_INT_BRIDGE_PRIV),
3944                      omap_findclk(s, "tipb_ck"));
3945      s->public_tipb = omap_tipb_bridge_init(system_memory, 0xfffed300,
3946                      qdev_get_gpio_in(s->ih[0], OMAP_INT_BRIDGE_PUB),
3947                      omap_findclk(s, "tipb_ck"));
3948  
3949      omap_tcmi_init(system_memory, 0xfffecc00, s);
3950  
3951      s->uart[0] = omap_uart_init(0xfffb0000,
3952                                  qdev_get_gpio_in(s->ih[1], OMAP_INT_UART1),
3953                      omap_findclk(s, "uart1_ck"),
3954                      omap_findclk(s, "uart1_ck"),
3955                      s->drq[OMAP_DMA_UART1_TX], s->drq[OMAP_DMA_UART1_RX],
3956                      "uart1",
3957                      serial_hd(0));
3958      s->uart[1] = omap_uart_init(0xfffb0800,
3959                                  qdev_get_gpio_in(s->ih[1], OMAP_INT_UART2),
3960                      omap_findclk(s, "uart2_ck"),
3961                      omap_findclk(s, "uart2_ck"),
3962                      s->drq[OMAP_DMA_UART2_TX], s->drq[OMAP_DMA_UART2_RX],
3963                      "uart2",
3964                      serial_hd(0) ? serial_hd(1) : NULL);
3965      s->uart[2] = omap_uart_init(0xfffb9800,
3966                                  qdev_get_gpio_in(s->ih[0], OMAP_INT_UART3),
3967                      omap_findclk(s, "uart3_ck"),
3968                      omap_findclk(s, "uart3_ck"),
3969                      s->drq[OMAP_DMA_UART3_TX], s->drq[OMAP_DMA_UART3_RX],
3970                      "uart3",
3971                      serial_hd(0) && serial_hd(1) ? serial_hd(2) : NULL);
3972  
3973      s->dpll[0] = omap_dpll_init(system_memory, 0xfffecf00,
3974                                  omap_findclk(s, "dpll1"));
3975      s->dpll[1] = omap_dpll_init(system_memory, 0xfffed000,
3976                                  omap_findclk(s, "dpll2"));
3977      s->dpll[2] = omap_dpll_init(system_memory, 0xfffed100,
3978                                  omap_findclk(s, "dpll3"));
3979  
3980      dinfo = drive_get(IF_SD, 0, 0);
3981      if (!dinfo && !qtest_enabled()) {
3982          warn_report("missing SecureDigital device");
3983      }
3984      s->mmc = omap_mmc_init(0xfffb7800, system_memory,
3985                             dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
3986                             qdev_get_gpio_in(s->ih[1], OMAP_INT_OQN),
3987                             &s->drq[OMAP_DMA_MMC_TX],
3988                      omap_findclk(s, "mmc_ck"));
3989  
3990      s->mpuio = omap_mpuio_init(system_memory, 0xfffb5000,
3991                                 qdev_get_gpio_in(s->ih[1], OMAP_INT_KEYBOARD),
3992                                 qdev_get_gpio_in(s->ih[1], OMAP_INT_MPUIO),
3993                                 s->wakeup, omap_findclk(s, "clk32-kHz"));
3994  
3995      s->gpio = qdev_new("omap-gpio");
3996      qdev_prop_set_int32(s->gpio, "mpu_model", s->mpu_model);
3997      omap_gpio_set_clk(OMAP1_GPIO(s->gpio), omap_findclk(s, "arm_gpio_ck"));
3998      sysbus_realize_and_unref(SYS_BUS_DEVICE(s->gpio), &error_fatal);
3999      sysbus_connect_irq(SYS_BUS_DEVICE(s->gpio), 0,
4000                         qdev_get_gpio_in(s->ih[0], OMAP_INT_GPIO_BANK1));
4001      sysbus_mmio_map(SYS_BUS_DEVICE(s->gpio), 0, 0xfffce000);
4002  
4003      s->microwire = omap_uwire_init(system_memory, 0xfffb3000,
4004                                     qdev_get_gpio_in(s->ih[1], OMAP_INT_uWireTX),
4005                                     qdev_get_gpio_in(s->ih[1], OMAP_INT_uWireRX),
4006                      s->drq[OMAP_DMA_UWIRE_TX], omap_findclk(s, "mpuper_ck"));
4007  
4008      s->pwl = omap_pwl_init(system_memory, 0xfffb5800,
4009                             omap_findclk(s, "armxor_ck"));
4010      s->pwt = omap_pwt_init(system_memory, 0xfffb6000,
4011                             omap_findclk(s, "armxor_ck"));
4012  
4013      s->i2c[0] = qdev_new("omap_i2c");
4014      qdev_prop_set_uint8(s->i2c[0], "revision", 0x11);
4015      omap_i2c_set_fclk(OMAP_I2C(s->i2c[0]), omap_findclk(s, "mpuper_ck"));
4016      busdev = SYS_BUS_DEVICE(s->i2c[0]);
4017      sysbus_realize_and_unref(busdev, &error_fatal);
4018      sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(s->ih[1], OMAP_INT_I2C));
4019      sysbus_connect_irq(busdev, 1, s->drq[OMAP_DMA_I2C_TX]);
4020      sysbus_connect_irq(busdev, 2, s->drq[OMAP_DMA_I2C_RX]);
4021      sysbus_mmio_map(busdev, 0, 0xfffb3800);
4022  
4023      s->rtc = omap_rtc_init(system_memory, 0xfffb4800,
4024                             qdev_get_gpio_in(s->ih[1], OMAP_INT_RTC_TIMER),
4025                             qdev_get_gpio_in(s->ih[1], OMAP_INT_RTC_ALARM),
4026                      omap_findclk(s, "clk32-kHz"));
4027  
4028      s->mcbsp1 = omap_mcbsp_init(system_memory, 0xfffb1800,
4029                                  qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP1TX),
4030                                  qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP1RX),
4031                      &s->drq[OMAP_DMA_MCBSP1_TX], omap_findclk(s, "dspxor_ck"));
4032      s->mcbsp2 = omap_mcbsp_init(system_memory, 0xfffb1000,
4033                                  qdev_get_gpio_in(s->ih[0],
4034                                                   OMAP_INT_310_McBSP2_TX),
4035                                  qdev_get_gpio_in(s->ih[0],
4036                                                   OMAP_INT_310_McBSP2_RX),
4037                      &s->drq[OMAP_DMA_MCBSP2_TX], omap_findclk(s, "mpuper_ck"));
4038      s->mcbsp3 = omap_mcbsp_init(system_memory, 0xfffb7000,
4039                                  qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP3TX),
4040                                  qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP3RX),
4041                      &s->drq[OMAP_DMA_MCBSP3_TX], omap_findclk(s, "dspxor_ck"));
4042  
4043      s->led[0] = omap_lpg_init(system_memory,
4044                                0xfffbd000, omap_findclk(s, "clk32-kHz"));
4045      s->led[1] = omap_lpg_init(system_memory,
4046                                0xfffbd800, omap_findclk(s, "clk32-kHz"));
4047  
4048      /* Register mappings not currently implemented:
4049       * MCSI2 Comm	fffb2000 - fffb27ff (not mapped on OMAP310)
4050       * MCSI1 Bluetooth	fffb2800 - fffb2fff (not mapped on OMAP310)
4051       * USB W2FC		fffb4000 - fffb47ff
4052       * Camera Interface	fffb6800 - fffb6fff
4053       * USB Host		fffba000 - fffba7ff
4054       * FAC		fffba800 - fffbafff
4055       * HDQ/1-Wire	fffbc000 - fffbc7ff
4056       * TIPB switches	fffbc800 - fffbcfff
4057       * Mailbox		fffcf000 - fffcf7ff
4058       * Local bus IF	fffec100 - fffec1ff
4059       * Local bus MMU	fffec200 - fffec2ff
4060       * DSP MMU		fffed200 - fffed2ff
4061       */
4062  
4063      omap_setup_dsp_mapping(system_memory, omap15xx_dsp_mm);
4064      omap_setup_mpui_io(system_memory, s);
4065  
4066      qemu_register_reset(omap1_mpu_reset, s);
4067  
4068      return s;
4069  }
4070