save/load vmstate support in omap3 hsusb host & clean-ups
[qemu] / hw / omap3.c
index d24d2d9..281a650 100644 (file)
-/*\r
- * TI OMAP3 processors emulation.\r
- *\r
- * Copyright (C) 2008 yajin <yajin@vm-kernel.org>\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License as\r
- * published by the Free Software Foundation; either version 2 or\r
- * (at your option) version 3 of the License.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,\r
- * MA 02111-1307 USA\r
- */\r
-\r
-#include "hw.h"\r
-#include "arm-misc.h"\r
-#include "omap.h"\r
-#include "sysemu.h"\r
-#include "qemu-timer.h"\r
-#include "qemu-char.h"\r
-#include "flash.h"\r
-#include "soc_dma.h"\r
-#include "audio/audio.h"\r
-\r
-//#define OMAP3_DEBUG_\r
-\r
-#ifdef OMAP3_DEBUG_\r
-#define TRACE(fmt, ...) fprintf(stderr, "%s " fmt "\n", __FUNCTION__, ##__VA_ARGS__)\r
-#else\r
-#define TRACE(...) \r
-#endif\r
-\r
-static uint32_t omap3_l4ta_read(void *opaque, target_phys_addr_t addr)\r
-{\r
-    struct omap_target_agent_s *s = (struct omap_target_agent_s *)opaque;\r
-\r
-    switch (addr) {\r
-        case 0x00: /* COMPONENT_L */\r
-            return s->component;\r
-        case 0x04: /* COMPONENT_H */\r
-            return 0;\r
-        case 0x18: /* CORE_L */\r
-            return s->component;\r
-        case 0x1c: /* CORE_H */\r
-            return (s->component >> 16);\r
-        case 0x20: /* AGENT_CONTROL_L */\r
-            return s->control;\r
-        case 0x24: /* AGENT_CONTROL_H */\r
-            return s->control_h;\r
-        case 0x28: /* AGENT_STATUS_L */\r
-            return s->status;\r
-        case 0x2c: /* AGENT_STATUS_H */\r
-            return 0;\r
-        default:\r
-            break;\r
-    }\r
-\r
-    OMAP_BAD_REG(s->base + addr);\r
-    return 0;\r
-}\r
-\r
-static void omap3_l4ta_write(void *opaque, target_phys_addr_t addr,\r
-                             uint32_t value)\r
-{\r
-    struct omap_target_agent_s *s = (struct omap_target_agent_s *)opaque;\r
-\r
-    switch (addr) {\r
-        case 0x00: /* COMPONENT_L */\r
-        case 0x04: /* COMPONENT_H */\r
-        case 0x18: /* CORE_L */\r
-        case 0x1c: /* CORE_H */\r
-            OMAP_RO_REG(s->base + addr);\r
-            break;\r
-        case 0x20: /* AGENT_CONTROL_L */\r
-            s->control = value & 0x00000701;\r
-            break;\r
-        case 0x24: /* AGENT_CONTROL_H */\r
-            s->control_h = value & 0x100; /* TODO: shouldn't this be read-only? */\r
-            break;\r
-        case 0x28: /* AGENT_STATUS_L */\r
-            if (value & 0x100)\r
-                s->status &= ~0x100; /* REQ_TIMEOUT */\r
-            break;\r
-        case 0x2c: /* AGENT_STATUS_H */\r
-            /* no writable bits although the register is listed as RW */\r
-            break;\r
-        default:\r
-            OMAP_BAD_REG(s->base + addr);\r
-            break;\r
-    }\r
-}\r
-\r
-static CPUReadMemoryFunc *omap3_l4ta_readfn[] = {\r
-    omap_badwidth_read16,\r
-    omap3_l4ta_read,\r
-    omap_badwidth_read16,\r
-};\r
-\r
-static CPUWriteMemoryFunc *omap3_l4ta_writefn[] = {\r
-    omap_badwidth_write32,\r
-    omap_badwidth_write32,\r
-    omap3_l4ta_write,\r
-};\r
-\r
-static struct omap_l4_region_s omap3_l4_region[158] = {\r
-    /* L4-Core */\r
-    [  0] = {0x00002000, 0x1000, 32 | 16 | 8}, /* SCM */\r
-    [  1] = {0x00003000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [  2] = {0x00004000, 0x2000, 32         }, /* CM Region A */\r
-    [  3] = {0x00006000, 0x0800, 32         }, /* CM Region B */\r
-    [  4] = {0x00007000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [  5] = {0x00040000, 0x0800, 32         }, /* AP */\r
-    [  6] = {0x00040800, 0x0800, 32         }, /* IP */\r
-    [  7] = {0x00041000, 0x1000, 32         }, /* LA */\r
-    [  8] = {0x0004fc00, 0x0400, 32 | 16 | 8}, /* DSI */\r
-    [  9] = {0x00050000, 0x0400, 32 | 16 | 8}, /* DISS */\r
-    [ 10] = {0x00050400, 0x0400, 32 | 16 | 8}, /* DISPC */\r
-    [ 11] = {0x00050800, 0x0400, 32 | 16 | 8}, /* RFBI */\r
-    [ 12] = {0x00050c00, 0x0400, 32 | 16 | 8}, /* VENC */\r
-    [ 13] = {0x00051000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [ 14] = {0x00056000, 0x1000, 32         }, /* SDMA */\r
-    [ 15] = {0x00057000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [ 16] = {0x00060000, 0x1000,      16 | 8}, /* I2C3 */\r
-    [ 17] = {0x00061000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [ 18] = {0x00062000, 0x1000, 32         }, /* USBTLL */\r
-    [ 19] = {0x00063000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [ 20] = {0x00064000, 0x1000, 32         }, /* HS USB HOST */\r
-    [ 21] = {0x00065000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [ 22] = {0x0006a000, 0x1000, 32 | 16 | 8}, /* UART1 */\r
-    [ 23] = {0x0006b000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [ 24] = {0x0006c000, 0x1000, 32 | 16 | 8}, /* UART2 */\r
-    [ 25] = {0x0006d000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [ 26] = {0x00070000, 0x1000,      16 | 8}, /* I2C1 */\r
-    [ 27] = {0x00071000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [ 28] = {0x00072000, 0x1000,      16 | 8}, /* I2C2 */\r
-    [ 29] = {0x00073000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [ 30] = {0x00074000, 0x1000, 32         }, /* McBSP1 */\r
-    [ 31] = {0x00075000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [ 32] = {0x00086000, 0x1000, 32 | 16    }, /* GPTIMER10 */\r
-    [ 33] = {0x00087000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [ 34] = {0x00088000, 0x1000, 32 | 16    }, /* GPTIMER11 */\r
-    [ 35] = {0x00089000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [ 36] = {0x00094000, 0x1000, 32 | 16 | 8}, /* MAILBOX */\r
-    [ 37] = {0x00095000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [ 38] = {0x00096000, 0x1000, 32         }, /* McBSP5 */\r
-    [ 39] = {0x00097000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [ 40] = {0x00098000, 0x1000, 32 | 16 | 8}, /* McSPI1 */\r
-    [ 41] = {0x00099000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [ 42] = {0x0009a000, 0x1000, 32 | 16 | 8}, /* McSPI2 */\r
-    [ 43] = {0x0009b000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [ 44] = {0x0009c000, 0x1000, 32         }, /* MMC/SD/SDIO1 */\r
-    [ 45] = {0x0009d000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [ 46] = {0x0009e000, 0x1000, 32         }, /* MS-PRO */\r
-    [ 47] = {0x0009f000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [ 48] = {0x000ab000, 0x1000, 32         }, /* HS USB OTG */\r
-    [ 49] = {0x000ac000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [ 50] = {0x000ad000, 0x1000, 32         }, /* MMC/SD/SDIO3 */\r
-    [ 51] = {0x000ae000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [ 52] = {0x000b2000, 0x1000, 32         }, /* HDQ/1-Wire */\r
-    [ 53] = {0x000b3000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [ 54] = {0x000b4000, 0x1000, 32         }, /* MMC/SD/SDIO2 */\r
-    [ 55] = {0x000b5000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [ 56] = {0x000b6000, 0x1000, 32         }, /* ICR MPU Port */\r
-    [ 57] = {0x000b7000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [ 58] = {0x000b8000, 0x1000, 32 | 16 | 8}, /* McSPI3 */\r
-    [ 59] = {0x000b9000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [ 60] = {0x000ba000, 0x1000, 32 | 16 | 8}, /* McSPI4 */\r
-    [ 61] = {0x000bb000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [ 62] = {0x000bc000, 0x4000, 32 | 16 | 8}, /* Camera ISP */\r
-    [ 63] = {0x000c0000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [ 64] = {0x000c7000, 0x1000, 32         }, /* Modem */\r
-    [ 65] = {0x000c8000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [ 66] = {0x000cd000, 0x1000, 32         }, /* ICR modem port  */\r
-    [ 67] = {0x000ce000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    /* L4-Wakeup interconnect region A */\r
-    [ 68] = {0x00304000, 0x1000, 32 | 16    }, /* GPTIMER12 */\r
-    [ 69] = {0x00305000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [ 70] = {0x00306000, 0x2000, 32         }, /* PRM region A */\r
-    [ 71] = {0x00308000, 0x0800, 32         }, /* PRM region B */\r
-    [ 72] = {0x00309000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    /* L4-Core */\r
-    [ 73] = {0x0030a000, 0x0800, 32 | 16 | 8}, /* TAP */\r
-    [ 74] = {0x0030b000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    /* L4-Wakeup interconnect region B */\r
-    [ 75] = {0x00310000, 0x1000, 32 | 16 | 8}, /* GPIO1 */\r
-    [ 76] = {0x00311000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [ 77] = {0x00314000, 0x1000, 32 | 16    }, /* WDTIMER2 */\r
-    [ 78] = {0x00315000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [ 79] = {0x00318000, 0x1000, 32 | 16    }, /* GPTIMER1 */\r
-    [ 80] = {0x00319000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [ 81] = {0x00320000, 0x1000, 32 | 16    }, /* 32K Timer */\r
-    [ 82] = {0x00321000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [ 83] = {0x00328000, 0x0800, 32 | 16 | 8}, /* L4-Wakeup config AP */\r
-    [ 84] = {0x00328800, 0x0800, 32 | 16 | 8}, /* L4-Wakeup config IP L4-Core */\r
-    [ 85] = {0x00329000, 0x1000, 32 | 16 | 8}, /* L4-Wakeup config LA */\r
-    [ 86] = {0x0032a000, 0x0800, 32 | 16 | 8}, /* L4-Wakeup config IP L4-Emu */\r
-    [ 87] = {0x00340000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    /* L4-Per */\r
-    [ 88] = {0x01000000, 0x0800, 32 | 16 | 8}, /* AP */\r
-    [ 89] = {0x01000800, 0x0800, 32 | 16 | 8}, /* IP */\r
-    [ 90] = {0x01001000, 0x1000, 32 | 16 | 8}, /* LA */\r
-    [ 91] = {0x01020000, 0x1000, 32 | 16 | 8}, /* UART3 */\r
-    [ 92] = {0x01021000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [ 93] = {0x01022000, 0x1000, 32         }, /* McBSP2 */\r
-    [ 94] = {0x01023000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [ 95] = {0x01024000, 0x1000, 32         }, /* McBSP3 */\r
-    [ 96] = {0x01025000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [ 97] = {0x01026000, 0x1000, 32         }, /* McBSP4 */\r
-    [ 98] = {0x01027000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [ 99] = {0x01028000, 0x1000, 32         }, /* McBSP2 (sidetone) */\r
-    [100] = {0x01029000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [101] = {0x0102a000, 0x1000, 32         }, /* McBSP3 (sidetone) */\r
-    [102] = {0x0102b000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [103] = {0x01030000, 0x1000, 32 | 16    }, /* WDTIMER3  */\r
-    [104] = {0x01031000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [105] = {0x01032000, 0x1000, 32 | 16    }, /* GPTIMER2 */\r
-    [106] = {0x01033000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [107] = {0x01034000, 0x1000, 32 | 16    }, /* GPTIMER3 */\r
-    [108] = {0x01035000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [109] = {0x01036000, 0x1000, 32 | 16    }, /* GPTIMER4 */\r
-    [110] = {0x01037000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [111] = {0x01038000, 0x1000, 32 | 16    }, /* GPTIMER5 */\r
-    [112] = {0x01039000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [113] = {0x0103a000, 0x1000, 32 | 16    }, /* GPTIMER6 */\r
-    [114] = {0x0103b000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [115] = {0x0103c000, 0x1000, 32 | 16    }, /* GPTIMER7 */\r
-    [116] = {0x0103d000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [117] = {0x0103e000, 0x1000, 32 | 16    }, /* GPTIMER8 */\r
-    [118] = {0x0103f000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [119] = {0x01040000, 0x1000, 32 | 16    }, /* GPTIMER9 */\r
-    [120] = {0x01041000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [121] = {0x01050000, 0x1000, 32 | 16 | 8}, /* GPIO2 */\r
-    [122] = {0x01051000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [123] = {0x01052000, 0x1000, 32 | 16 | 8}, /* GPIO3 */\r
-    [124] = {0x01053000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [125] = {0x01054000, 0x1000, 32 | 16 | 8}, /* GPIO4 */\r
-    [126] = {0x01055000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [127] = {0x01056000, 0x1000, 32 | 16 | 8}, /* GPIO5 */\r
-    [128] = {0x01057000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [129] = {0x01058000, 0x1000, 32 | 16 | 8}, /* GPIO6 */\r
-    [130] = {0x01059000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    /* L4-Emu */\r
-    [131] = {0x0c006000, 0x0800, 32 | 16 | 8}, /* AP */\r
-    [132] = {0x0c006800, 0x0800, 32 | 16 | 8}, /* IP L4-Core */\r
-    [133] = {0x0c007000, 0x1000, 32 | 16 | 8}, /* LA */\r
-    [134] = {0x0c008000, 0x0800, 32 | 16 | 8}, /* IP DAP */\r
-    [135] = {0x0c010000, 0x8000, 32 | 16 | 8}, /* MPU Emulation */\r
-    [136] = {0x0c018000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [137] = {0x0c019000, 0x1000, 32         }, /* TPIU */\r
-    [138] = {0x0c01a000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [139] = {0x0c01b000, 0x1000, 32         }, /* ETB */\r
-    [140] = {0x0c01c000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [141] = {0x0c01d000, 0x1000, 32         }, /* DAPCTL */\r
-    [142] = {0x0c01e000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [143] = {0x0c706000, 0x2000, 32         }, /* PRM Region A */\r
-    [144] = {0x0c706800, 0x0800, 32         }, /* PRM Region B */\r
-    [145] = {0x0c709000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [146] = {0x0c710000, 0x1000, 32 | 16 | 8}, /* GPIO1 */\r
-    [147] = {0x0c711000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [148] = {0x0c714000, 0x1000, 32 | 16    }, /* WDTIMER2 */\r
-    [149] = {0x0c715000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [150] = {0x0c718000, 0x1000, 32 | 16 | 8}, /* GPTIMER1 */\r
-    [151] = {0x0c719000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [152] = {0x0c720000, 0x1000, 32 | 16    }, /* 32k timer */\r
-    [153] = {0x0c721000, 0x1000, 32 | 16 | 8}, /* L4IC */\r
-    [154] = {0x0c728000, 0x0800, 32 | 16 | 8}, /* L4-Wakeup config AP */\r
-    [155] = {0x0c728800, 0x0800, 32 | 16 | 8}, /* L4-Wakeup config IP L4-Core */\r
-    [156] = {0x0c729000, 0x1000, 32 | 16 | 8}, /* L4-Wakeup config LA */\r
-    [157] = {0x0c72a000, 0x0800, 32 | 16 | 8}, /* L4-Wakeup config IP L4-Emu */\r
-};\r
-\r
-static struct omap_l4_agent_info_s omap3_l4_agent_info[] = {\r
-    { 0,   0, 2, 1},  /* SCM */\r
-    { 1,   1, 3, 2},  /* CM */\r
-    { 2,  70, 3, 2},  /* PRM */\r
-    { 3,  77, 2, 1},  /* WDTIMER2 */\r
-    { 4,  79, 2, 1},  /* GPTIMER1 */\r
-    { 5, 105, 2, 1},  /* GPTIMER2 */\r
-    { 6, 107, 2, 1},  /* GPTIMER3 */\r
-    { 7, 108, 2, 1},  /* GPTIMER4 */\r
-    { 8, 111, 2, 1},  /* GPTIMER5 */\r
-    { 9, 113, 2, 1},  /* GPTIMER6 */\r
-    {10, 115, 2, 1},  /* GPTIMER7 */\r
-    {11, 116, 2, 1},  /* GPTIMER8 */\r
-    {12, 119, 2, 1},  /* GPTIMER9 */\r
-    {13,  32, 2, 1},  /* GPTIMER10 */\r
-    {14,  34, 2, 1},  /* GPTIMER11 */\r
-    {15,  68, 2, 1},  /* GPTIMER12 */\r
-    {16,  81, 2, 1},  /* 32K Sync timer */\r
-    {17,  22, 2, 1},  /* UART1 */\r
-    {18,  24, 2, 1},  /* UART2 */\r
-    {19,  91, 2, 1},  /* UART3 */\r
-    {20,   8, 6, 4},  /* DSS */\r
-    {21,  75, 2, 1},  /* GPIO1 */\r
-    {22, 121, 2, 1},  /* GPIO2 */\r
-    {23, 123, 2, 1},  /* GPIO3 */\r
-    {24, 125, 2, 1},  /* GPIO4 */\r
-    {25, 127, 2, 1},  /* GPIO5 */\r
-    {26, 129, 2, 1},  /* GPIO6 */\r
-    {27,  73, 2, 1},  /* TAP */\r
-    {28,  44, 2, 1},  /* MMC1 */\r
-    {29,  54, 2, 1},  /* MMC2 */\r
-    {30,  50, 2, 1},  /* MMC3 */\r
-    {31,  26, 2, 1},  /* I2C1 */\r
-    {32,  28, 2, 1},  /* I2C2 */\r
-    {33,  16, 2, 1},  /* I2C3 */\r
-};\r
-\r
-static struct omap_target_agent_s *omap3_l4ta_get(struct omap_l4_s *bus, int cs)\r
-{\r
-    int i, iomemtype;\r
-    struct omap_target_agent_s *ta = 0;\r
-    struct omap_l4_agent_info_s *info = 0;\r
-\r
-    for (i = 0; i < bus->ta_num; i++)\r
-        if (omap3_l4_agent_info[i].ta == cs)\r
-        {\r
-            ta = &bus->ta[i];\r
-            info = &omap3_l4_agent_info[i];\r
-            break;\r
-        }\r
-    if (!ta)\r
-    {\r
-        fprintf(stderr, "%s: bad target agent (%i)\n", __FUNCTION__, cs);\r
-        exit(-1);\r
-    }\r
-\r
-    ta->bus = bus;\r
-    ta->start = &omap3_l4_region[info->region];\r
-    ta->regions = info->regions;\r
-\r
-    ta->component = ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);\r
-    ta->status = 0x00000000;\r
-    ta->control = 0x00000200;   /* XXX 01000200 for L4TAO */\r
-\r
-    iomemtype = l4_register_io_memory(0, omap3_l4ta_readfn,\r
-                                      omap3_l4ta_writefn, ta);\r
-    ta->base = omap_l4_attach(ta, info->ta_region, iomemtype);\r
-\r
-    return ta;\r
-}\r
-\r
-\r
-struct omap3_prm_s\r
-{\r
-    qemu_irq irq[3];\r
-    struct omap_mpu_state_s *mpu;\r
-\r
-    /*IVA2_PRM Register */\r
-    uint32_t rm_rstctrl_iva2;    /*0x4830 6050 */\r
-    uint32_t rm_rstst_iva2;      /*0x4830 6058 */\r
-    uint32_t pm_wkdep_iva2;      /*0x4830 60C8 */\r
-    uint32_t pm_pwstctrl_iva2;   /*0x4830 60E0 */\r
-    uint32_t pm_pwstst_iva2;     /*0x4830 60E4 */\r
-    uint32_t pm_prepwstst_iva2;  /*0x4830 60E8 */\r
-    uint32_t prm_irqstatus_iva2; /*0x4830 60F8 */\r
-    uint32_t prm_irqenable_iva2; /*0x4830 60FC */\r
-\r
-    /*OCP_System_Reg_PRM Registerr */\r
-    uint32_t prm_revision;      /*0x4830 6804 */\r
-    uint32_t prm_sysconfig;     /*0x4830 6814 */\r
-    uint32_t prm_irqstatus_mpu; /*0x4830 6818 */\r
-    uint32_t prm_irqenable_mpu; /*0x4830 681c */\r
-\r
-    /*MPU_PRM Register */\r
-    uint32_t rm_rstst_mpu;      /*0x4830 6958 */\r
-    uint32_t pm_wkdep_mpu;      /*0x4830 69c8 */\r
-    uint32_t pm_evgenctrl_mpu;  /*0x4830 69d4 */\r
-    uint32_t pm_evgenontim_mpu; /*0x4830 69d8 */\r
-    uint32_t pm_evgenofftim_mpu;        /*0x4830 69dc */\r
-    uint32_t pm_pwstctrl_mpu;   /*0x4830 69e0 */\r
-    uint32_t pm_pwstst_mpu;     /*0x4830 69e4 */\r
-    uint32_t pm_perpwstst_mpu;  /*0x4830 69e8 */\r
-\r
-    /*CORE_PRM Register */\r
-    uint32_t rm_rstst_core;     /*0x4830 6a58 */\r
-    uint32_t pm_wken1_core;     /*0x4830 6aa0 */\r
-    uint32_t pm_mpugrpsel1_core;        /*0x4830 6aa4 */\r
-    uint32_t pm_iva2grpsel1_core;       /*0x4830 6aa8 */\r
-    uint32_t pm_wkst1_core;     /*0x4830 6ab0 */\r
-    uint32_t pm_wkst3_core;     /*0x4830 6ab8 */\r
-    uint32_t pm_pwstctrl_core;  /*0x4830 6ae0 */\r
-    uint32_t pm_pwstst_core;    /*0x4830 6ae4 */\r
-    uint32_t pm_prepwstst_core; /*0x4830 6ae8 */\r
-    uint32_t pm_wken3_core;     /*0x4830 6af0 */\r
-    uint32_t pm_iva2grpsel3_core;       /*0x4830 6af4 */\r
-    uint32_t pm_mpugrpsel3_core;        /*0x4830 6af8 */\r
-\r
-    /*SGX_PRM Register */\r
-    uint32_t rm_rstst_sgx;      /*0x4830 6b58 */\r
-    uint32_t pm_wkdep_sgx;      /*0x4830 6bc8 */\r
-    uint32_t pm_pwstctrl_sgx;   /*0x4830 6be0 */\r
-    uint32_t pm_pwstst_sgx;     /*0x4830 6be4 */\r
-    uint32_t pm_prepwstst_sgx;  /*0x4830 6be8 */\r
-\r
-    /*WKUP_PRM Register */\r
-    uint32_t pm_wken_wkup;      /*0x4830 6ca0 */\r
-    uint32_t pm_mpugrpsel_wkup; /*0x4830 6ca4 */\r
-    uint32_t pm_iva2grpsel_wkup;        /*0x4830 6ca8 */\r
-    uint32_t pm_wkst_wkup;      /*0x4830 6cb0 */\r
-\r
-    /*Clock_Control_Reg_PRM Register */\r
-    uint32_t prm_clksel;        /*0x4830 6D40 */\r
-    uint32_t prm_clkout_ctrl;   /*0x4830 6D70 */\r
-\r
-    /*DSS_PRM Register */\r
-    uint32_t rm_rstst_dss;      /*0x4830 6e58 */\r
-    uint32_t pm_wken_dss;       /*0x4830 6ea0 */\r
-    uint32_t pm_wkdep_dss;      /*0x4830 6ec8 */\r
-    uint32_t pm_pwstctrl_dss;   /*0x4830 6ee0 */\r
-    uint32_t pm_pwstst_dss;     /*0x4830 6ee4 */\r
-    uint32_t pm_prepwstst_dss;  /*0x4830 6ee8 */\r
-\r
-    /*CAM_PRM Register */\r
-    uint32_t rm_rstst_cam;      /*0x4830 6f58 */\r
-    uint32_t pm_wkdep_cam;      /*0x4830 6fc8 */\r
-    uint32_t pm_pwstctrl_cam;   /*0x4830 6fe0 */\r
-    uint32_t pm_pwstst_cam;     /*0x4830 6fe4 */\r
-    uint32_t pm_prepwstst_cam;  /*0x4830 6fe8 */\r
-\r
-    /*PER_PRM Register */\r
-    uint32_t rm_rstst_per;      /*0x4830 7058 */\r
-    uint32_t pm_wken_per;       /*0x4830 70a0 */\r
-    uint32_t pm_mpugrpsel_per;  /*0x4830 70a4 */\r
-    uint32_t pm_iva2grpsel_per; /*0x4830 70a8 */\r
-    uint32_t pm_wkst_per;       /*0x4830 70b0 */\r
-    uint32_t pm_wkdep_per;      /*0x4830 70c8 */\r
-    uint32_t pm_pwstctrl_per;   /*0x4830 70e0 */\r
-    uint32_t pm_pwstst_per;     /*0x4830 70e4 */\r
-    uint32_t pm_perpwstst_per;  /*0x4830 70e8 */\r
-\r
-    /*EMU_PRM Register */\r
-    uint32_t rm_rstst_emu;      /*0x4830 7158 */\r
-    uint32_t pm_pwstst_emu;     /*0x4830 71e4 */\r
-\r
-    /*Global_Reg_PRM Register */\r
-    uint32_t prm_vc_smps_sa;    /*0x4830 7220 */\r
-    uint32_t prm_vc_smps_vol_ra;        /*0x4830 7224 */\r
-    uint32_t prm_vc_smps_cmd_ra;        /*0x4830 7228 */\r
-    uint32_t prm_vc_cmd_val_0;  /*0x4830 722c */\r
-    uint32_t prm_vc_cmd_val_1;  /*0x4830 7230 */\r
-    uint32_t prm_vc_hc_conf;    /*0x4830 7234 */\r
-    uint32_t prm_vc_i2c_cfg;    /*0x4830 7238 */\r
-    uint32_t prm_vc_bypass_val; /*0x4830 723c */\r
-    uint32_t prm_rstctrl;       /*0x4830 7250 */\r
-    uint32_t prm_rsttimer;      /*0x4830 7254 */\r
-    uint32_t prm_rstst;         /*0x4830 7258 */\r
-    uint32_t prm_voltctrl;      /*0x4830 7260 */\r
-    uint32_t prm_sram_pcharge;  /*0x4830 7264 */\r
-    uint32_t prm_clksrc_ctrl;   /*0x4830 7270 */\r
-    uint32_t prm_obs;           /*0x4830 7280 */\r
-    uint32_t prm_voltsetup1;    /*0x4830 7290 */\r
-    uint32_t prm_voltoffset;    /*0x4830 7294 */\r
-    uint32_t prm_clksetup;      /*0x4830 7298 */\r
-    uint32_t prm_polctrl;       /*0x4830 729c */\r
-    uint32_t prm_voltsetup2;    /*0x4830 72a0 */\r
-\r
-    /*NEON_PRM Register */\r
-    uint32_t rm_rstst_neon;     /*0x4830 7358 */\r
-    uint32_t pm_wkdep_neon;     /*0x4830 73c8 */\r
-    uint32_t pm_pwstctrl_neon;  /*0x4830 73e0 */\r
-    uint32_t pm_pwstst_neon;    /*0x4830 73e4 */\r
-    uint32_t pm_prepwstst_neon; /*0x4830 73e8 */\r
-\r
-    /*USBHOST_PRM Register */\r
-    uint32_t rm_rstst_usbhost;  /*0x4830 7458 */\r
-    uint32_t pm_wken_usbhost;   /*0x4830 74a0 */\r
-    uint32_t pm_mpugrpsel_usbhost;      /*0x4830 74a4 */\r
-    uint32_t pm_iva2grpsel_usbhost;     /*0x4830 74a8 */\r
-    uint32_t pm_wkst_usbhost;   /*0x4830 74b0 */\r
-    uint32_t pm_wkdep_usbhost;  /*0x4830 74c8 */\r
-    uint32_t pm_pwstctrl_usbhost;       /*0x4830 74e0 */\r
-    uint32_t pm_pwstst_usbhost; /*0x4830 74e4 */\r
-    uint32_t pm_prepwstst_usbhost;      /*0x4830 74e8 */\r
-\r
-};\r
-\r
-static void omap3_prm_reset(struct omap3_prm_s *s)\r
-{\r
-    s->rm_rstctrl_iva2 = 0x7;\r
-    s->rm_rstst_iva2 = 0x1;\r
-    s->pm_wkdep_iva2 = 0xb3;\r
-    s->pm_pwstctrl_iva2 = 0xff0f07;\r
-    s->pm_pwstst_iva2 = 0xff7;\r
-    s->pm_prepwstst_iva2 = 0x0;\r
-    s->prm_irqstatus_iva2 = 0x0;\r
-    s->prm_irqenable_iva2 = 0x0;\r
-\r
-    s->prm_revision = 0x10;\r
-    s->prm_sysconfig = 0x1;\r
-    s->prm_irqstatus_mpu = 0x0;\r
-    s->prm_irqenable_mpu = 0x0;\r
-\r
-    s->rm_rstst_mpu = 0x1;\r
-    s->pm_wkdep_mpu = 0xa5;\r
-    s->pm_evgenctrl_mpu = 0x12;\r
-    s->pm_evgenontim_mpu = 0x0;\r
-    s->pm_evgenofftim_mpu = 0x0;\r
-    s->pm_pwstctrl_mpu = 0x30107;\r
-    s->pm_pwstst_mpu = 0xc7;\r
-    s->pm_pwstst_mpu = 0x0;\r
-\r
-    s->rm_rstst_core = 0x1;\r
-    s->pm_wken1_core = 0xc33ffe18;\r
-    s->pm_mpugrpsel1_core = 0xc33ffe18;\r
-    s->pm_iva2grpsel1_core = 0xc33ffe18;\r
-    s->pm_wkst1_core = 0x0;\r
-    s->pm_wkst3_core = 0x0;\r
-    s->pm_pwstctrl_core = 0xf0307;\r
-    s->pm_pwstst_core = 0xf7;\r
-    s->pm_prepwstst_core = 0x0;\r
-    s->pm_wken3_core = 0x4;\r
-    s->pm_iva2grpsel3_core = 0x4;\r
-    s->pm_mpugrpsel3_core = 0x4;\r
-\r
-    s->rm_rstst_sgx = 0x1;\r
-    s->pm_wkdep_sgx = 0x16;\r
-    s->pm_pwstctrl_sgx = 0x30107;\r
-    s->pm_pwstst_sgx = 0x3;\r
-    s->pm_prepwstst_sgx = 0x0;\r
-\r
-    s->pm_wken_wkup = 0x3cb;\r
-    s->pm_mpugrpsel_wkup = 0x3cb;\r
-    s->pm_iva2grpsel_wkup = 0x0;\r
-    s->pm_wkst_wkup = 0x0;\r
-\r
-    s->prm_clksel = 0x4;\r
-    s->prm_clkout_ctrl = 0x80;\r
-\r
-    s->rm_rstst_dss = 0x1;\r
-    s->pm_wken_dss = 0x1;\r
-    s->pm_wkdep_dss = 0x16;\r
-    s->pm_pwstctrl_dss = 0x30107;\r
-    s->pm_pwstst_dss = 0x3;\r
-    s->pm_prepwstst_dss = 0x0;\r
-\r
-    s->rm_rstst_cam = 0x1;\r
-    s->pm_wkdep_cam = 0x16;\r
-    s->pm_pwstctrl_cam = 0x30107;\r
-    s->pm_pwstst_cam = 0x3;\r
-    s->pm_prepwstst_cam = 0x0;\r
-\r
-    s->rm_rstst_per = 0x1;\r
-    s->pm_wken_per = 0x3efff;\r
-    s->pm_mpugrpsel_per = 0x3efff;\r
-    s->pm_iva2grpsel_per = 0x3efff;\r
-    s->pm_wkst_per = 0x0;\r
-    s->pm_wkdep_per = 0x17;\r
-    s->pm_pwstctrl_per = 0x30107;\r
-    s->pm_pwstst_per = 0x7;\r
-    s->pm_perpwstst_per = 0x0;\r
-\r
-    s->rm_rstst_emu = 0x1;\r
-    s->pm_pwstst_emu = 0x13;\r
-\r
-    s->prm_vc_smps_sa = 0x0;\r
-    s->prm_vc_smps_vol_ra = 0x0;\r
-    s->prm_vc_smps_cmd_ra = 0x0;\r
-    s->prm_vc_cmd_val_0 = 0x0;\r
-    s->prm_vc_cmd_val_1 = 0x0;\r
-    s->prm_vc_hc_conf = 0x0;\r
-    s->prm_vc_i2c_cfg = 0x18;\r
-    s->prm_vc_bypass_val = 0x0;\r
-    s->prm_rstctrl = 0x0;\r
-    s->prm_rsttimer = 0x1006;\r
-    s->prm_rstst = 0x1;\r
-    s->prm_voltctrl = 0x0;\r
-    s->prm_sram_pcharge = 0x50;\r
-    s->prm_clksrc_ctrl = 0x43;\r
-    s->prm_obs = 0x0;\r
-    s->prm_voltsetup1 = 0x0;\r
-    s->prm_voltoffset = 0x0;\r
-    s->prm_clksetup = 0x0;\r
-    s->prm_polctrl = 0xa;\r
-    s->prm_voltsetup2 = 0x0;\r
-\r
-    s->rm_rstst_neon = 0x1;\r
-    s->pm_wkdep_neon = 0x2;\r
-    s->pm_pwstctrl_neon = 0x7;\r
-    s->pm_pwstst_neon = 0x3;\r
-    s->pm_prepwstst_neon = 0x0;\r
-\r
-    s->rm_rstst_usbhost = 0x1;\r
-    s->pm_wken_usbhost = 0x1;\r
-    s->pm_mpugrpsel_usbhost = 0x1;\r
-    s->pm_iva2grpsel_usbhost = 0x1;\r
-    s->pm_wkst_usbhost = 0x0;\r
-    s->pm_wkdep_usbhost = 0x17;\r
-    s->pm_pwstctrl_usbhost = 0x30107;\r
-    s->pm_pwstst_usbhost = 0x3;\r
-    s->pm_prepwstst_usbhost = 0x0;\r
-\r
-}\r
-\r
-static uint32_t omap3_prm_read(void *opaque, target_phys_addr_t addr)\r
-{\r
-    struct omap3_prm_s *s = (struct omap3_prm_s *)opaque;\r
-\r
-    TRACE("%04x", addr);\r
-    switch (addr) {\r
-        /* IVA2_PRM */\r
-        case 0x0050: return s->rm_rstctrl_iva2;\r
-        case 0x0058: return s->rm_rstst_iva2;\r
-        case 0x00c8: return s->pm_wkdep_iva2;\r
-        case 0x00e0: return s->pm_pwstctrl_iva2;\r
-        case 0x00e4: return s->pm_pwstst_iva2;\r
-        case 0x00e8: return s->pm_prepwstst_iva2;\r
-        case 0x00f8: return s->prm_irqstatus_iva2;\r
-        case 0x00fc: return s->prm_irqenable_iva2;\r
-        /* OCP_System_Reg_PRM */\r
-        case 0x0804: return s->prm_revision;\r
-        case 0x0814: return s->prm_sysconfig;\r
-        case 0x0818: return s->prm_irqstatus_mpu;\r
-        case 0x081c: return s->prm_irqenable_mpu;\r
-        /* MPU_PRM */\r
-        case 0x0958: return s->rm_rstst_mpu;\r
-        case 0x09c8: return s->pm_wkdep_mpu;\r
-        case 0x09d4: return s->pm_evgenctrl_mpu;\r
-        case 0x09d8: return s->pm_evgenontim_mpu;\r
-        case 0x09dc: return s->pm_evgenofftim_mpu;\r
-        case 0x09e0: return s->pm_pwstctrl_mpu;\r
-        case 0x09e4: return s->pm_pwstst_mpu;\r
-        case 0x09e8: return s->pm_perpwstst_mpu;\r
-        /* CORE_PRM */\r
-        case 0x0a58: return s->rm_rstst_core;\r
-        case 0x0aa0: return s->pm_wken1_core;\r
-        case 0x0aa4: return s->pm_mpugrpsel1_core;\r
-        case 0x0aa8: return s->pm_iva2grpsel1_core;\r
-        case 0x0ab0: return s->pm_wkst1_core;\r
-        case 0x0ab8: return s->pm_wkst3_core;\r
-        case 0x0ae0: return s->pm_pwstctrl_core;\r
-        case 0x0ae4: return s->pm_pwstst_core;\r
-        case 0x0ae8: return s->pm_prepwstst_core;\r
-        case 0x0af0: return s->pm_wken3_core;\r
-        case 0x0af4: return s->pm_iva2grpsel3_core;\r
-        case 0x0af8: return s->pm_mpugrpsel3_core;\r
-        /* SGX_PRM */\r
-        case 0x0b58: return s->rm_rstst_sgx;\r
-        case 0x0bc8: return s->pm_wkdep_sgx;\r
-        case 0x0be0: return s->pm_pwstctrl_sgx;\r
-        case 0x0be4: return s->pm_pwstst_sgx;\r
-        case 0x0be8: return s->pm_prepwstst_sgx;\r
-       /* WKUP_PRM */\r
-        case 0x0ca0: return s->pm_wken_wkup;\r
-        case 0x0ca4: return s->pm_mpugrpsel_wkup;\r
-        case 0x0ca8: return s->pm_iva2grpsel_wkup;\r
-        case 0x0cb0: return s->pm_wkst_wkup;\r
-       /* Clock_Control_Reg_PRM */\r
-        case 0x0d40: return s->prm_clksel;\r
-        case 0x0d70: return s->prm_clkout_ctrl;\r
-        /* DSS_PRM */\r
-        case 0x0e58: return s->rm_rstst_dss;\r
-        case 0x0ea0: return s->pm_wken_dss;\r
-        case 0x0ec8: return s->pm_wkdep_dss;\r
-        case 0x0ee0: return s->pm_pwstctrl_dss;\r
-        case 0x0ee4: return s->pm_pwstst_dss;\r
-        case 0x0ee8: return s->pm_prepwstst_dss;\r
-        /* CAM_PRM */\r
-        case 0x0f58: return s->rm_rstst_cam;\r
-        case 0x0fc8: return s->pm_wkdep_cam;\r
-        case 0x0fe0: return s->pm_pwstctrl_cam;\r
-        case 0x0fe4: return s->pm_pwstst_cam;\r
-        case 0x0fe8: return s->pm_prepwstst_cam;\r
-        /* PER_PRM */\r
-        case 0x1058: return s->rm_rstst_per;\r
-        case 0x10a0: return s->pm_wken_per;\r
-        case 0x10a4: return s->pm_mpugrpsel_per;\r
-        case 0x10a8: return s->pm_iva2grpsel_per;\r
-        case 0x10b0: return s->pm_wkst_per;\r
-        case 0x10c8: return s->pm_wkdep_per;\r
-        case 0x10e0: return s->pm_pwstctrl_per;\r
-        case 0x10e4: return s->pm_pwstst_per;\r
-        case 0x10e8: return s->pm_perpwstst_per;\r
-        /* EMU_PRM */\r
-        case 0x1158: return s->rm_rstst_emu;\r
-        case 0x11e4: return s->pm_pwstst_emu;\r
-        /* Global_Reg_PRM */\r
-        case 0x1220: return s->prm_vc_smps_sa;\r
-        case 0x1224: return s->prm_vc_smps_vol_ra;\r
-        case 0x1228: return s->prm_vc_smps_cmd_ra;\r
-        case 0x122c: return s->prm_vc_cmd_val_0;\r
-        case 0x1230: return s->prm_vc_cmd_val_1;\r
-        case 0x1234: return s->prm_vc_hc_conf;\r
-        case 0x1238: return s->prm_vc_i2c_cfg;\r
-        case 0x123c: return s->prm_vc_bypass_val;\r
-        case 0x1250: return s->prm_rstctrl;\r
-        case 0x1254: return s->prm_rsttimer;\r
-        case 0x1258: return s->prm_rstst;\r
-        case 0x1260: return s->prm_voltctrl;\r
-        case 0x1264: return s->prm_sram_pcharge;       \r
-        case 0x1270: return s->prm_clksrc_ctrl;\r
-        case 0x1280: return s->prm_obs;\r
-        case 0x1290: return s->prm_voltsetup1;\r
-        case 0x1294: return s->prm_voltoffset;\r
-        case 0x1298: return s->prm_clksetup;\r
-        case 0x129c: return s->prm_polctrl;\r
-        case 0x12a0: return s->prm_voltsetup2;\r
-        /* NEON_PRM */\r
-        case 0x1358: return s->rm_rstst_neon;\r
-        case 0x13c8: return s->pm_wkdep_neon;\r
-        case 0x13e0: return s->pm_pwstctrl_neon;\r
-        case 0x13e4: return s->pm_pwstst_neon;\r
-        case 0x13e8: return s->pm_prepwstst_neon;\r
-        /* USBHOST_PRM */\r
-        case 0x1458: return s->rm_rstst_usbhost;\r
-        case 0x14a0: return s->pm_wken_usbhost;\r
-        case 0x14a4: return s->pm_mpugrpsel_usbhost;\r
-        case 0x14a8: return s->pm_iva2grpsel_usbhost;\r
-        case 0x14b0: return s->pm_wkst_usbhost;\r
-        case 0x14c8: return s->pm_wkdep_usbhost;\r
-        case 0x14e0: return s->pm_pwstctrl_usbhost;\r
-        case 0x14e4: return s->pm_pwstst_usbhost;\r
-        case 0x14e8: return s->pm_prepwstst_usbhost;\r
-        default:\r
-            OMAP_BAD_REG(addr);\r
-            return 0;\r
-    }\r
-}\r
-\r
-static inline void omap3_prm_clksrc_ctrl_update(struct omap3_prm_s *s,\r
-                                                uint32_t value)\r
-{\r
-    if ((value & 0xd0) == 0x40)\r
-        omap_clk_setrate(omap_findclk(s->mpu, "omap3_sys_clk"), 1, 1);\r
-    else if ((value & 0xd0) == 0x80)\r
-        omap_clk_setrate(omap_findclk(s->mpu, "omap3_sys_clk"), 2, 1);\r
-}\r
-\r
-static void omap3_prm_write(void *opaque, target_phys_addr_t addr,\r
-                            uint32_t value)\r
-{\r
-    struct omap3_prm_s *s = (struct omap3_prm_s *)opaque;\r
-\r
-    TRACE("%04x = %08x", addr, value);\r
-    switch (addr) {\r
-        /* IVA2_PRM */\r
-        case 0x0050: s->rm_rstctrl_iva2 = value & 0x7; break;\r
-        case 0x0058: s->rm_rstst_iva2 &= ~(value & 0x3f0f); break;\r
-        case 0x00c8: s->pm_wkdep_iva2 = value & 0xb3; break;\r
-        case 0x00e0: s->pm_pwstctrl_iva2 = 0xcff000 | (value & 0x300f0f); break;\r
-        case 0x00e4: OMAP_RO_REG(addr); break;\r
-        case 0x00e8: s->pm_prepwstst_iva2 = value & 0xff7;\r
-        case 0x00f8: s->prm_irqstatus_iva2 &= ~(value & 0x7); break;\r
-        case 0x00fc: s->prm_irqenable_iva2 = value & 0x7; break;\r
-        /* OCP_System_Reg_PRM */\r
-        case 0x0804: OMAP_RO_REG(addr); break;\r
-        case 0x0814: s->prm_sysconfig = value & 0x1; break;\r
-        case 0x0818: s->prm_irqstatus_mpu &= ~(value & 0x03c003fd); break;\r
-        case 0x081c: s->prm_irqenable_mpu = value & 0x03c003fd; break;\r
-        /* MPU_PRM */\r
-        case 0x0958: s->rm_rstst_mpu &= ~(value & 0x080f); break;\r
-        case 0x09c8: s->pm_wkdep_mpu = value & 0xa5; break;\r
-        case 0x09d4: s->pm_evgenctrl_mpu = value & 0x1f; break;\r
-        case 0x09d8: s->pm_evgenontim_mpu = value; break;\r
-        case 0x09dc: s->pm_evgenofftim_mpu = value; break;\r
-        case 0x09e0: s->pm_pwstctrl_mpu = value & 0x3010f; break;\r
-        case 0x09e4: OMAP_RO_REG(addr); break;\r
-        case 0x09e8: s->pm_perpwstst_mpu = value & 0xc7; break;\r
-        /* CORE_PRM */\r
-        case 0x0a58: s->rm_rstst_core &= ~(value & 0x7); break;\r
-        case 0x0aa0: s->pm_wken1_core = 0x80000008 | (value & 0x433ffe10); break;\r
-        case 0x0aa4: s->pm_mpugrpsel1_core = 0x80000008 | (value & 0x433ffe10); break;\r
-        case 0x0aa8: s->pm_iva2grpsel1_core = 0x80000008 | (value & 0x433ffe10); break;\r
-        case 0x0ab0: s->pm_wkst1_core = value & 0x433ffe10; break;\r
-        case 0x0ab8: s->pm_wkst3_core &= ~(value & 0x4); break;\r
-        case 0x0ae0: s->pm_pwstctrl_core = (value & 0x0f031f); break;\r
-        case 0x0ae4: OMAP_RO_REG(addr); break;\r
-        case 0x0ae8: s->pm_prepwstst_core = value & 0xf7; break;\r
-        case 0x0af0: s->pm_wken3_core = value & 0x4; break;\r
-        case 0x0af4: s->pm_iva2grpsel3_core = value & 0x4; break;\r
-        case 0x0af8: s->pm_mpugrpsel3_core = value & 0x4; break;\r
-        /* SGX_PRM */\r
-        case 0x0b58: s->rm_rstst_sgx &= ~(value & 0xf); break;\r
-        case 0x0bc8: s->pm_wkdep_sgx = value & 0x16; break;\r
-        case 0x0be0: s->pm_pwstctrl_sgx = 0x030104 | (value & 0x3); break;\r
-        case 0x0be4: OMAP_RO_REG(addr); break;\r
-        case 0x0be8: s->pm_prepwstst_sgx = value & 0x3; break;\r
-        /* WKUP_PRM */\r
-        case 0x0ca0: s->pm_wken_wkup = 0x2 | (value & 0x0103c9); break;\r
-        case 0x0ca4: s->pm_mpugrpsel_wkup = 0x0102 | (value & 0x02c9); break;\r
-        case 0x0ca8: s->pm_iva2grpsel_wkup = value & 0x03cb; break;\r
-        case 0x0cb0: s->pm_wkst_wkup &= ~(value & 0x0103cb); break;\r
-        /* Clock_Control_Reg_PRM */\r
-        case 0x0d40: \r
-            s->prm_clksel = value & 0x7;\r
-            fprintf(stderr, "%s PRM_CLKSEL = 0x%x\n", __FUNCTION__,\r
-                    s->prm_clksel);\r
-            /* TODO: update clocks */\r
-            break;\r
-        case 0x0d70:\r
-            s->prm_clkout_ctrl = value & 0x80;\r
-            fprintf(stderr, "%s PRM_CLKOUT_CTRL = 0x%x\n", __FUNCTION__,\r
-                    s->prm_clkout_ctrl);\r
-            /* TODO: check do we need to update something */\r
-            break;\r
-        /* DSS_PRM */\r
-        case 0x0e58: s->rm_rstst_dss &= ~(value & 0xf); break;\r
-        case 0x0ea0: s->pm_wken_dss = value & 1; break;\r
-        case 0x0ec8: s->pm_wkdep_dss = value & 0x16; break;\r
-        case 0x0ee0: s->pm_pwstctrl_dss = 0x030104 | (value & 3); break;\r
-        case 0x0ee4: OMAP_RO_REG(addr); break;\r
-        case 0x0ee8: s->pm_prepwstst_dss = value & 3; break;\r
-        /* CAM_PRM */\r
-        case 0x0f58: s->rm_rstst_cam &= (value & 0xf); break;\r
-        case 0x0fc8: s->pm_wkdep_cam = value & 0x16; break;\r
-        case 0x0fe0: s->pm_pwstctrl_cam = 0x030104 | (value & 3); break;\r
-        case 0x0fe4: OMAP_RO_REG(addr); break;\r
-        case 0x0fe8: s->pm_prepwstst_cam = value & 0x3; break;\r
-        /* PER_PRM */\r
-        case 0x1058: s->rm_rstst_per &= ~(value & 0xf); break;\r
-        case 0x10a0: s->pm_wken_per = value & 0x03efff; break;\r
-        case 0x10a4: s->pm_mpugrpsel_per = value & 0x03efff; break;\r
-        case 0x10a8: s->pm_iva2grpsel_per = value & 0x03efff; break;\r
-        case 0x10b0: s->pm_wkst_per &= ~(value & 0x03efff); break;\r
-        case 0x10c8: s->pm_wkdep_per = value & 0x17; break;\r
-        case 0x10e0: s->pm_pwstctrl_per = 0x030100 | (value & 7); break;\r
-        case 0x10e4: OMAP_RO_REG(addr); break;\r
-        case 0x10e8: s->pm_perpwstst_per = value & 0x7; break;\r
-        /* EMU_PRM */\r
-        case 0x1158: s->rm_rstst_emu &= ~(value & 7); break;\r
-        case 0x11e4: OMAP_RO_REG(addr); break;\r
-        /* Global_Reg_PRM */\r
-        case 0x1220: s->prm_vc_smps_sa = value & 0x7f007f; break;\r
-        case 0x1224: s->prm_vc_smps_vol_ra = value & 0xff00ff; break;\r
-        case 0x1228: s->prm_vc_smps_cmd_ra = value & 0xff00ff; break;\r
-        case 0x122c: s->prm_vc_cmd_val_0 = value; break;\r
-        case 0x1230: s->prm_vc_cmd_val_1 = value; break;\r
-        case 0x1234: s->prm_vc_hc_conf = value & 0x1f001f; break;\r
-        case 0x1238: s->prm_vc_i2c_cfg = value & 0x3f; break;\r
-        case 0x123c: s->prm_vc_bypass_val = value & 0x01ffff7f; break;\r
-        case 0x1250: s->prm_rstctrl = 0; break; /* TODO: resets */\r
-        case 0x1254: s->prm_rsttimer = value & 0x1fff; break;\r
-        case 0x1258: s->prm_rstst &= ~(value & 0x7fb); break;\r
-        case 0x1260: s->prm_voltctrl = value & 0x1f; break;\r
-        case 0x1264: s->prm_sram_pcharge = value & 0xff; break;\r
-        case 0x1270:\r
-            s->prm_clksrc_ctrl = value & (0xd8);\r
-            omap3_prm_clksrc_ctrl_update(s, s->prm_clksrc_ctrl);\r
-            /* TODO: update SYSCLKSEL bits */\r
-            break;\r
-        case 0x1280: OMAP_RO_REG(addr); break;\r
-        case 0x1290: s->prm_voltsetup1 = value; break;\r
-        case 0x1294: s->prm_voltoffset = value & 0xffff; break;\r
-        case 0x1298: s->prm_clksetup = value & 0xffff; break;\r
-        case 0x129c: s->prm_polctrl = value & 0xf; break;\r
-        case 0x12a0: s->prm_voltsetup2 = value & 0xffff; break;\r
-        /* NEON_PRM */\r
-        case 0x1358: s->rm_rstst_neon &= ~(value & 0xf); break;\r
-        case 0x13c8: s->pm_wkdep_neon = value & 0x2; break;\r
-        case 0x13e0: s->pm_pwstctrl_neon = 0x4 | (value & 3); break;\r
-        case 0x13e4: OMAP_RO_REG(addr); break;\r
-        case 0x13e8: s->pm_prepwstst_neon = value & 3; break;\r
-        /* USBHOST_PRM */\r
-        case 0x1458: s->rm_rstst_usbhost &= ~(value & 0xf); break;\r
-        case 0x14a0: s->pm_wken_usbhost = value & 1; break;\r
-        case 0x14a4: s->pm_mpugrpsel_usbhost = value & 1; break;\r
-        case 0x14a8: s->pm_iva2grpsel_usbhost = value & 1; break;\r
-        case 0x14b0: s->pm_wkst_usbhost &= ~(value & 1); break;\r
-        case 0x14c8: s->pm_wkdep_usbhost = value & 0x17; break;\r
-        case 0x14e0: s->pm_pwstctrl_usbhost = 0x030104 | (value & 0x13); break;\r
-        case 0x14e4: OMAP_RO_REG(addr); break;\r
-        case 0x14e8: s->pm_prepwstst_usbhost = value & 3; break;\r
-        default:\r
-            OMAP_BAD_REGV(addr, value);\r
-            break;\r
-    }\r
-}\r
-\r
-static CPUReadMemoryFunc *omap3_prm_readfn[] = {\r
-    omap_badwidth_read32,\r
-    omap_badwidth_read32,\r
-    omap3_prm_read,\r
-};\r
-\r
-static CPUWriteMemoryFunc *omap3_prm_writefn[] = {\r
-    omap_badwidth_write32,\r
-    omap_badwidth_write32,\r
-    omap3_prm_write,\r
-};\r
-\r
-struct omap3_prm_s *omap3_prm_init(struct omap_target_agent_s *ta,\r
-                                   qemu_irq mpu_int, qemu_irq dsp_int,\r
-                                   qemu_irq iva_int,\r
-                                   struct omap_mpu_state_s *mpu)\r
-{\r
-    int iomemtype;\r
-    struct omap3_prm_s *s = (struct omap3_prm_s *) qemu_mallocz(sizeof(*s));\r
-\r
-    s->irq[0] = mpu_int;\r
-    s->irq[1] = dsp_int;\r
-    s->irq[2] = iva_int;\r
-    s->mpu = mpu;\r
-    omap3_prm_reset(s);\r
-\r
-    iomemtype = l4_register_io_memory(0, omap3_prm_readfn,\r
-                                      omap3_prm_writefn, s);\r
-    omap_l4_attach(ta, 0, iomemtype);\r
-    omap_l4_attach(ta, 1, iomemtype);\r
-\r
-    return s;\r
-}\r
-\r
-\r
-struct omap3_cm_s\r
-{\r
-    qemu_irq irq[3];\r
-    struct omap_mpu_state_s *mpu;\r
-\r
-    /*IVA2_CM Register */\r
-    uint32_t cm_fclken_iva2;    /*0x4800 4000 */\r
-    uint32_t cm_clken_pll_iva2; /*0x4800 4004 */\r
-    uint32_t cm_idlest_iva2;    /*0x4800 4020 */\r
-    uint32_t cm_idlest_pll_iva2;        /*0x4800 4024 */\r
-    uint32_t cm_autoidle_pll_iva2;      /*0x4800 4034 */\r
-    uint32_t cm_clksel1_pll_iva2;       /*0x4800 4040 */\r
-    uint32_t cm_clksel2_pll_iva2;       /*0x4800 4044 */\r
-    uint32_t cm_clkstctrl_iva2; /*0x4800 4048 */\r
-    uint32_t cm_clkstst_iva2;   /*0x4800 404c */\r
-\r
-    /*OCP_System_Reg_CM */\r
-    uint32_t cm_revision;       /*0x4800 4800 */\r
-    uint32_t cm_sysconfig;      /*0x4800 4810 */\r
-\r
-    /*MPU_CM Register */\r
-    uint32_t cm_clken_pll_mpu;  /*0x4800 4904 */\r
-    uint32_t cm_idlest_mpu;     /*0x4800 4920 */\r
-    uint32_t cm_idlest_pll_mpu; /*0x4800 4924 */\r
-    uint32_t cm_autoidle_pll_mpu;       /*0x4800 4934 */\r
-    uint32_t cm_clksel1_pll_mpu;        /*0x4800 4940 */\r
-    uint32_t cm_clksel2_pll_mpu;        /*0x4800 4944 */\r
-    uint32_t cm_clkstctrl_mpu;  /*0x4800 4948 */\r
-    uint32_t cm_clkstst_mpu;    /*0x4800 494c */\r
-\r
-    /*CORE_CM Register */\r
-    uint32_t cm_fclken1_core;   /*0x4800 4a00 */\r
-    uint32_t cm_fclken3_core;   /*0x4800 4a08 */\r
-    uint32_t cm_iclken1_core;   /*0x4800 4a10 */\r
-    uint32_t cm_iclken2_core;   /*0x4800 4a14 */\r
-    uint32_t cm_iclken3_core;   /*0x4800 4a18 */\r
-    uint32_t cm_idlest1_core;   /*0x4800 4a20 */\r
-    uint32_t cm_idlest2_core;   /*0x4800 4a24 */\r
-    uint32_t cm_idlest3_core;   /*0x4800 4a28 */\r
-    uint32_t cm_autoidle1_core; /*0x4800 4a30 */\r
-    uint32_t cm_autoidle2_core; /*0x4800 4a34 */\r
-    uint32_t cm_autoidle3_core; /*0x4800 4a38 */\r
-    uint32_t cm_clksel_core;    /*0x4800 4a40 */\r
-    uint32_t cm_clkstctrl_core; /*0x4800 4a48 */\r
-    uint32_t cm_clkstst_core;   /*0x4800 4a4c */\r
-\r
-    /*SGX_CM Register */\r
-    uint32_t cm_fclken_sgx;     /*0x4800 4b00 */\r
-    uint32_t cm_iclken_sgx;     /*0x4800 4b10 */\r
-    uint32_t cm_idlest_sgx;     /*0x4800 4b20 */\r
-    uint32_t cm_clksel_sgx;     /*0x4800 4b40 */\r
-    uint32_t cm_sleepdep_sgx;   /*0x4800 4b44 */\r
-    uint32_t cm_clkstctrl_sgx;  /*0x4800 4b48 */\r
-    uint32_t cm_clkstst_sgx;    /*0x4800 4b4c */\r
-\r
-    /*WKUP_CM Register */\r
-    uint32_t cm_fclken_wkup;    /*0x4800 4c00 */\r
-    uint32_t cm_iclken_wkup;    /*0x4800 4c10 */\r
-    uint32_t cm_idlest_wkup;    /*0x4800 4c20 */\r
-    uint32_t cm_autoidle_wkup;  /*0x4800 4c30 */\r
-    uint32_t cm_clksel_wkup;    /*0x4800 4c40 */\r
-    uint32_t cm_c48;                  /*0x4800 4c48 */\r
-\r
-    /*Clock_Control_Reg_CM Register */\r
-    uint32_t cm_clken_pll;      /*0x4800 4d00 */\r
-    uint32_t cm_clken2_pll;     /*0x4800 4d04 */\r
-    uint32_t cm_idlest_ckgen;   /*0x4800 4d20 */\r
-    uint32_t cm_idlest2_ckgen;  /*0x4800 4d24 */\r
-    uint32_t cm_autoidle_pll;   /*0x4800 4d30 */\r
-    uint32_t cm_autoidle2_pll;  /*0x4800 4d34 */\r
-    uint32_t cm_clksel1_pll;    /*0x4800 4d40 */\r
-    uint32_t cm_clksel2_pll;    /*0x4800 4d44 */\r
-    uint32_t cm_clksel3_pll;    /*0x4800 4d48 */\r
-    uint32_t cm_clksel4_pll;    /*0x4800 4d4c */\r
-    uint32_t cm_clksel5_pll;    /*0x4800 4d50 */\r
-    uint32_t cm_clkout_ctrl;    /*0x4800 4d70 */\r
-\r
-    /*DSS_CM Register */\r
-    uint32_t cm_fclken_dss;     /*0x4800 4e00 */\r
-    uint32_t cm_iclken_dss;     /*0x4800 4e10 */\r
-    uint32_t cm_idlest_dss;     /*0x4800 4e20 */\r
-    uint32_t cm_autoidle_dss;   /*0x4800 4e30 */\r
-    uint32_t cm_clksel_dss;     /*0x4800 4e40 */\r
-    uint32_t cm_sleepdep_dss;   /*0x4800 4e44 */\r
-    uint32_t cm_clkstctrl_dss;  /*0x4800 4e48 */\r
-    uint32_t cm_clkstst_dss;    /*0x4800 4e4c */\r
-\r
-\r
-    /*CAM_CM Register */\r
-    uint32_t cm_fclken_cam;     /*0x4800 4f00 */\r
-    uint32_t cm_iclken_cam;     /*0x4800 4f10 */\r
-    uint32_t cm_idlest_cam;     /*0x4800 4f20 */\r
-    uint32_t cm_autoidle_cam;   /*0x4800 4f30 */\r
-    uint32_t cm_clksel_cam;     /*0x4800 4f40 */\r
-    uint32_t cm_sleepdep_cam;   /*0x4800 4f44 */\r
-    uint32_t cm_clkstctrl_cam;  /*0x4800 4f48 */\r
-    uint32_t cm_clkstst_cam;    /*0x4800 4f4c */\r
-\r
-    /*PER_CM Register */\r
-    uint32_t cm_fclken_per;     /*0x4800 5000 */\r
-    uint32_t cm_iclken_per;     /*0x4800 5010 */\r
-    uint32_t cm_idlest_per;     /*0x4800 5020 */\r
-    uint32_t cm_autoidle_per;   /*0x4800 5030 */\r
-    uint32_t cm_clksel_per;     /*0x4800 5040 */\r
-    uint32_t cm_sleepdep_per;   /*0x4800 5044 */\r
-    uint32_t cm_clkstctrl_per;  /*0x4800 5048 */\r
-    uint32_t cm_clkstst_per;    /*0x4800 504c */\r
-\r
-    /*EMU_CM Register */\r
-    uint32_t cm_clksel1_emu;    /*0x4800 5140 */\r
-    uint32_t cm_clkstctrl_emu;  /*0x4800 5148 */\r
-    uint32_t cm_clkstst_emu;    /*0x4800 514c */\r
-    uint32_t cm_clksel2_emu;    /*0x4800 5150 */\r
-    uint32_t cm_clksel3_emu;    /*0x4800 5154 */\r
-\r
-    /*Global_Reg_CM Register */\r
-    uint32_t cm_polctrl;        /*0x4800 529c */\r
-\r
-    /*NEON_CM Register */\r
-    uint32_t cm_idlest_neon;    /*0x4800 5320 */\r
-    uint32_t cm_clkstctrl_neon; /*0x4800 5348 */\r
-\r
-    /*USBHOST_CM Register */\r
-    uint32_t cm_fclken_usbhost; /*0x4800 5400 */\r
-    uint32_t cm_iclken_usbhost; /*0x4800 5410 */\r
-    uint32_t cm_idlest_usbhost; /*0x4800 5420 */\r
-    uint32_t cm_autoidle_usbhost;       /*0x4800 5430 */\r
-    uint32_t cm_sleepdep_usbhost;       /*0x4800 5444 */\r
-    uint32_t cm_clkstctrl_usbhost;      /*0x4800 5448 */\r
-    uint32_t cm_clkstst_usbhost;        /*0x4800 544c */\r
-\r
-};\r
-\r
-/*\r
-static inline void omap3_cm_fclken_wkup_update(struct omap3_cm_s *s,\r
-                uint32_t value)\r
-{\r
-       \r
-       if (value & 0x28)\r
-       omap_clk_onoff(omap_findclk(s->mpu,"omap3_wkup_32k_fclk"), 1);\r
-    else\r
-       omap_clk_onoff(omap_findclk(s->mpu,"omap3_wkup_32k_fclk"), 0);\r
-\r
-    if (value &0x1)\r
-       omap_clk_onoff(omap_findclk(s->mpu,"omap3_gp1_fclk"), 1);\r
-    else\r
-       omap_clk_onoff(omap_findclk(s->mpu,"omap3_gp1_fclk"), 0);\r
-\r
-}\r
-static inline void omap3_cm_iclken_wkup_update(struct omap3_cm_s *s,\r
-                uint32_t value)\r
-{\r
-       \r
-       if (value & 0x3f)\r
-       omap_clk_onoff(omap_findclk(s->mpu,"omap3_wkup_l4_iclk"), 1);\r
-    else\r
-       omap_clk_onoff(omap_findclk(s->mpu,"omap3_wkup_l4_iclk"), 0);\r
-\r
-}\r
-*/\r
-static inline void omap3_cm_clksel_wkup_update(struct omap3_cm_s *s,\r
-                                               uint32_t value)\r
-{\r
-    omap_clk gp1_fclk = omap_findclk(s->mpu, "omap3_gp1_fclk");\r
-\r
-    if (value & 0x1)\r
-        omap_clk_reparent(gp1_fclk, omap_findclk(s->mpu, "omap3_sys_clk"));\r
-    else\r
-        omap_clk_reparent(gp1_fclk, omap_findclk(s->mpu, "omap3_32k_fclk"));\r
-    /*Tell GPTIMER to generate new clk rate */\r
-    omap_gp_timer_change_clk(s->mpu->gptimer[0]);\r
-\r
-    TRACE("omap3_gp1_fclk %lld",\r
-          omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp1_fclk")));\r
-\r
-    /*TODO:CM_USIM_CLK CLKSEL_RM */\r
-}\r
-\r
-static inline void omap3_cm_mpu_update(struct omap3_cm_s *s)\r
-{\r
-    uint32_t m, n, divide, m2, cm_clken_pll_mpu;\r
-    uint32_t bypass = 1;\r
-\r
-    cm_clken_pll_mpu = s->cm_clken_pll_mpu;\r
-    omap_clk mpu_clk = omap_findclk(s->mpu, "omap3_mpu_clk");\r
-\r
-    if ((cm_clken_pll_mpu & 0x7) == 0x5)\r
-    {\r
-        bypass = 1;\r
-    }\r
-    else if ((cm_clken_pll_mpu & 0x7) == 0x7)\r
-    {\r
-        m = (s->cm_clksel1_pll_mpu & 0x7ff00) >> 8;\r
-        if ((m == 0) || (m == 1))\r
-            bypass = 1;\r
-        else\r
-            bypass = 0;\r
-    }\r
-    if (bypass == 1)\r
-    {\r
-        /*BYPASS Model */\r
-        divide = (s->cm_clksel1_pll_mpu & 0x380000) >> 19;\r
-        //OMAP3_DEBUG(("divide %d\n",divide));\r
-        omap_clk_reparent(mpu_clk, omap_findclk(s->mpu, "omap3_core_clk"));\r
-        omap_clk_setrate(mpu_clk, divide, 1);\r
-\r
-    }\r
-    else\r
-    {\r
-        n = (s->cm_clksel1_pll_mpu & 0x7F);\r
-        m2 = (s->cm_clksel2_pll_mpu & 0x1F);\r
-        //OMAP3_DEBUG(("M  %d N %d M2 %d \n",m,n,m2 ));\r
-        omap_clk_reparent(mpu_clk, omap_findclk(s->mpu, "omap3_sys_clk"));\r
-        omap_clk_setrate(mpu_clk, (n + 1) * m2, m);\r
-        //OMAP3_DEBUG(("mpu %d \n",omap_clk_getrate(mpu_clk)));\r
-\r
-    }\r
-\r
-}\r
-static inline void omap3_cm_iva2_update(struct omap3_cm_s *s)\r
-{\r
-    uint32_t m, n, divide, m2, cm_clken_pll_iva2;\r
-    uint32_t bypass = 1;\r
-\r
-    cm_clken_pll_iva2 = s->cm_clken_pll_iva2;\r
-    omap_clk iva2_clk = omap_findclk(s->mpu, "omap3_iva2_clk");\r
-\r
-    if (((cm_clken_pll_iva2 & 0x7) == 0x5)\r
-        || ((cm_clken_pll_iva2 & 0x7) == 0x1))\r
-    {\r
-        bypass = 1;\r
-    }\r
-    else if ((cm_clken_pll_iva2 & 0x7) == 0x7)\r
-    {\r
-        m = (s->cm_clksel1_pll_iva2 & 0x7ff00) >> 8;\r
-        if ((m == 0) || (m == 1))\r
-            bypass = 1;\r
-        else\r
-            bypass = 0;\r
-    }\r
-    if (bypass == 1)\r
-    {\r
-        /*BYPASS Model */\r
-        divide = (s->cm_clksel1_pll_iva2 & 0x380000) >> 19;\r
-        //OMAP3_DEBUG(("divide %d\n",divide));\r
-        omap_clk_reparent(iva2_clk, omap_findclk(s->mpu, "omap3_core_clk"));\r
-        omap_clk_setrate(iva2_clk, divide, 1);\r
-\r
-    }\r
-    else\r
-    {\r
-        n = (s->cm_clksel1_pll_iva2 & 0x7F);\r
-        m2 = (s->cm_clksel2_pll_iva2 & 0x1F);\r
-        //OMAP3_DEBUG(("M  %d N %d M2 %d \n",m,n,m2 ));\r
-        omap_clk_reparent(iva2_clk, omap_findclk(s->mpu, "omap3_sys_clk"));\r
-        omap_clk_setrate(iva2_clk, (n + 1) * m2, m);\r
-        //OMAP3_DEBUG(("iva2_clk %d \n",omap_clk_getrate(iva2_clk)));\r
-\r
-    }\r
-\r
-}\r
-\r
-static inline void omap3_cm_dpll3_update(struct omap3_cm_s *s)\r
-{\r
-    uint32_t m, n, m2, m3, cm_clken_pll;\r
-    uint32_t bypass = 1;\r
-\r
-    cm_clken_pll = s->cm_clken_pll;\r
-\r
-    /*dpll3 bypass mode. parent clock is always omap3_sys_clk */\r
-    if (((cm_clken_pll & 0x7) == 0x5) || ((cm_clken_pll & 0x7) == 0x6))\r
-    {\r
-        bypass = 1;\r
-    }\r
-    else if ((cm_clken_pll & 0x7) == 0x7)\r
-    {\r
-        m = (s->cm_clksel1_pll & 0x7ff0000) >> 16;\r
-        if ((m == 0) || (m == 1))\r
-            bypass = 1;\r
-        else\r
-            bypass = 0;\r
-    }\r
-    if (bypass == 1)\r
-    {\r
-        omap_clk_setrate(omap_findclk(s->mpu, "omap3_core_clk"), 1, 1);\r
-        omap_clk_setrate(omap_findclk(s->mpu, "omap3_core2_clk"), 1, 1);\r
-        omap_clk_setrate(omap_findclk(s->mpu, "omap3_emu_core_alwon_clk"), 1,\r
-                         1);\r
-    }\r
-    else\r
-    {\r
-        n = (s->cm_clksel1_pll & 0x3f00) >> 8;\r
-        m2 = (s->cm_clksel1_pll & 0xf8000000) >> 27;\r
-        m3 = (s->cm_clksel1_emu & 0x1f0000) >> 16;\r
-\r
-        if (s->cm_clksel2_emu&0x80000)\r
-        {\r
-               /*override control of DPLL3*/\r
-               m = (s->cm_clksel2_emu&0x7ff)>>8;\r
-               n =  s->cm_clksel2_emu&0x7f;\r
-               TRACE("DPLL3 override, m 0x%x n 0x%x",m,n);\r
-        }\r
-\r
-        //OMAP3_DEBUG(("dpll3 cm_clksel1_pll %x m  %d n %d m2 %d  m3 %d\n",s->cm_clksel1_pll,m,n,m2,m3 ));\r
-        omap_clk_setrate(omap_findclk(s->mpu, "omap3_core_clk"), (n + 1) * m2,\r
-                         m);\r
-        omap_clk_setrate(omap_findclk(s->mpu, "omap3_core2_clk"), (n + 1) * m2,\r
-                         m * 2);\r
-        omap_clk_setrate(omap_findclk(s->mpu, "omap3_emu_core_alwon_clk"),\r
-                         (n + 1) * m3, m * 2);\r
-        TRACE("coreclk %lld",\r
-              omap_clk_getrate(omap_findclk(s->mpu, "omap3_core_clk")));\r
-    }\r
-\r
-\r
-}\r
-\r
-\r
-static inline void omap3_cm_dpll4_update(struct omap3_cm_s *s)\r
-{\r
-    uint32_t m, n, m2, m3, m4, m5, m6, cm_clken_pll;\r
-    cm_clken_pll = s->cm_clken_pll;\r
-    uint32_t bypass = 1;\r
-\r
-    /*dpll3 bypass mode. parent clock is always omap3_sys_clk */\r
-    /*DPLL4 */\r
-    if ((cm_clken_pll & 0x70000) == 0x10000)\r
-    {\r
-        bypass = 1;\r
-    }\r
-    else if ((cm_clken_pll & 0x70000) == 0x70000)\r
-    {\r
-        m = (s->cm_clksel2_pll & 0x7ff00) >> 8;\r
-        if ((m == 0) || (m == 1))\r
-            bypass = 1;\r
-        else\r
-            bypass = 0;\r
-    }\r
-    if (bypass == 1)\r
-    {\r
-        omap_clk_setrate(omap_findclk(s->mpu, "omap3_96m_fclk"), 1, 1);\r
-        omap_clk_setrate(omap_findclk(s->mpu, "omap3_54m_fclk"), 1, 1);\r
-        omap_clk_setrate(omap_findclk(s->mpu, "omap3_dss1_alwon_fclk"), 1, 1);\r
-        omap_clk_setrate(omap_findclk(s->mpu, "omap3_cam_mclk"), 1, 1);\r
-        omap_clk_setrate(omap_findclk(s->mpu, "omap3_per_alwon_clk"), 1, 1);\r
-    }\r
-    else\r
-    {\r
-        n = (s->cm_clksel2_pll & 0x7f);\r
-        m2 = s->cm_clksel3_pll & 0x1f;\r
-        m3 = (s->cm_clksel_dss & 0x1f00) >> 8;\r
-        m4 = s->cm_clksel_dss & 0x1f;\r
-        m5 = s->cm_clksel_cam & 0x1f;\r
-        m6 = (s->cm_clksel1_emu & 0x1f000000) >> 24;\r
-\r
-        if (s->cm_clksel3_emu&0x80000)\r
-        {\r
-               /*override control of DPLL4*/\r
-               m = (s->cm_clksel3_emu&0x7ff)>>8;\r
-               n =  s->cm_clksel3_emu&0x7f;\r
-               TRACE("DPLL4 override, m 0x%x n 0x%x",m,n);\r
-        }\r
-\r
-\r
-        //OMAP3_DEBUG(("dpll4 m  %d n %d m2 %d  m3 %d m4 %d m5 %d m6 %d \n",m,n,m2,m3,m4,m5,m6 ));\r
-        omap_clk_setrate(omap_findclk(s->mpu, "omap3_96m_fclk"), (n + 1) * m2,\r
-                         m * 2);\r
-        omap_clk_setrate(omap_findclk(s->mpu, "omap3_54m_fclk"), (n + 1) * m3,\r
-                         m * 2);\r
-        omap_clk_setrate(omap_findclk(s->mpu, "omap3_dss1_alwon_fclk"),\r
-                         (n + 1) * m4, m * 2);\r
-        omap_clk_setrate(omap_findclk(s->mpu, "omap3_cam_mclk"), (n + 1) * m5,\r
-                         m * 2);\r
-        omap_clk_setrate(omap_findclk(s->mpu, "omap3_per_alwon_clk"),\r
-                         (n + 1) * m6, m * 2);\r
-\r
-        TRACE("omap3_96m_fclk %lld",\r
-              omap_clk_getrate(omap_findclk(s->mpu, "omap3_96m_fclk")));\r
-        TRACE("omap3_54m_fclk %lld",\r
-              omap_clk_getrate(omap_findclk(s->mpu, "omap3_54m_fclk")));\r
-        TRACE("omap3_dss1_alwon_fclk %lld",\r
-              omap_clk_getrate(omap_findclk(s->mpu, "omap3_dss1_alwon_fclk")));\r
-        TRACE("omap3_cam_mclk %lld",\r
-              omap_clk_getrate(omap_findclk(s->mpu, "omap3_cam_mclk")));\r
-        TRACE("omap3_per_alwon_clk %lld",\r
-              omap_clk_getrate(omap_findclk(s->mpu, "omap3_per_alwon_clk")));\r
-        TRACE("omap3_48m_fclk %lld",\r
-              omap_clk_getrate(omap_findclk(s->mpu, "omap3_48m_fclk")));\r
-        TRACE("omap3_12m_fclk %lld",\r
-              omap_clk_getrate(omap_findclk(s->mpu, "omap3_12m_fclk")));\r
-    }\r
-}\r
-\r
-static inline void omap3_cm_dpll5_update(struct omap3_cm_s *s)\r
-{\r
-        uint32_t m, n, m2, cm_idlest2_ckgen;\r
-    uint32_t bypass = 1;\r
-\r
-    cm_idlest2_ckgen = s->cm_idlest2_ckgen;;\r
-\r
-    /*dpll5 bypass mode */\r
-    if ((cm_idlest2_ckgen & 0x1) == 0x0) \r
-    {\r
-        bypass = 1;\r
-    }\r
-\r
-    if (bypass == 1)\r
-    {\r
-        omap_clk_setrate(omap_findclk(s->mpu, "omap3_120m_fclk"), 1, 1);\r
-    }\r
-    else\r
-    {\r
-        m = (s->cm_clksel4_pll & 0x7ff00)>>8;\r
-        n = s->cm_clksel4_pll & 0x3f00;\r
-        m2 = s->cm_clksel5_pll & 0x1f;\r
-\r
-        TRACE("dpll5 m %d n %d m2 %d",m,n,m2);\r
-        omap_clk_setrate(omap_findclk(s->mpu, "omap3_120m_fclk"), (n + 1) * m2,\r
-                         m);\r
-        TRACE("omap3_120m_fclk %lld",\r
-              omap_clk_getrate(omap_findclk(s->mpu, "omap3_120m_fclk")));\r
-    }\r
-\r
-\r
-}\r
-static inline void omap3_cm_48m_update(struct omap3_cm_s *s)\r
-{\r
-    if (s->cm_clksel1_pll & 0x8)\r
-    {\r
-        /*parent is sysaltclk */\r
-        omap_clk_reparent(omap_findclk(s->mpu, "omap3_48m_fclk"),\r
-                          omap_findclk(s->mpu, "omap3_sys_altclk"));\r
-        omap_clk_reparent(omap_findclk(s->mpu, "omap3_12m_fclk"),\r
-                          omap_findclk(s->mpu, "omap3_sys_altclk"));\r
-        /*TODO:need to set rate ? */\r
-\r
-    }\r
-    else\r
-    {\r
-        omap_clk_reparent(omap_findclk(s->mpu, "omap3_12m_fclk"),\r
-                          omap_findclk(s->mpu, "omap3_96m_fclk"));\r
-        omap_clk_reparent(omap_findclk(s->mpu, "omap3_48m_fclk"),\r
-                          omap_findclk(s->mpu, "omap3_96m_fclk"));\r
-        omap_clk_setrate(omap_findclk(s->mpu, "omap3_48m_fclk"), 2, 1);\r
-        omap_clk_setrate(omap_findclk(s->mpu, "omap3_12m_fclk"), 8, 1);\r
-\r
-    }\r
-\r
-}\r
-\r
-static inline void omap3_cm_gp10_update(struct omap3_cm_s *s)\r
-{\r
-    omap_clk gp10_fclk = omap_findclk(s->mpu, "omap3_gp10_fclk");\r
-\r
-    if (s->cm_clksel_core & 0x40)\r
-        omap_clk_reparent(gp10_fclk, omap_findclk(s->mpu, "omap3_sys_clk"));\r
-    else\r
-        omap_clk_reparent(gp10_fclk, omap_findclk(s->mpu, "omap3_32k_fclk"));\r
-\r
-    /*Tell GPTIMER10 to generate new clk rate */\r
-    omap_gp_timer_change_clk(s->mpu->gptimer[9]);\r
-    TRACE("omap3_gp10_fclk %lld",\r
-          omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp10_fclk")));\r
-}\r
-\r
-static inline void omap3_cm_gp11_update(struct omap3_cm_s *s)\r
-{\r
-    omap_clk gp11_fclk = omap_findclk(s->mpu, "omap3_gp11_fclk");\r
-\r
-    if (s->cm_clksel_core & 0x80)\r
-        omap_clk_reparent(gp11_fclk, omap_findclk(s->mpu, "omap3_sys_clk"));\r
-    else\r
-        omap_clk_reparent(gp11_fclk, omap_findclk(s->mpu, "omap3_32k_fclk"));\r
-    /*Tell GPTIMER11 to generate new clk rate */\r
-    omap_gp_timer_change_clk(s->mpu->gptimer[10]);\r
-    TRACE("omap3_gp11_fclk %lld",\r
-          omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp11_fclk")));\r
-}\r
-\r
-static inline void omap3_cm_l3clk_update(struct omap3_cm_s *s)\r
-{\r
-    omap_clk l3_iclk = omap_findclk(s->mpu, "omap3_l3_iclk");\r
-    if ((s->cm_clksel_core & 0x3) == 0x1)\r
-        omap_clk_setrate(l3_iclk, 1, 1);\r
-    else if ((s->cm_clksel_core & 0x3) == 0x2)\r
-        omap_clk_setrate(l3_iclk, 2, 1);\r
-}\r
-\r
-static inline void omap3_cm_l4clk_update(struct omap3_cm_s *s)\r
-{\r
-    omap_clk l4_iclk = omap_findclk(s->mpu, "omap3_l4_iclk");\r
-    if ((s->cm_clksel_core & 0xc) == 0x4)\r
-        omap_clk_setrate(l4_iclk, 1, 1);\r
-    else if ((s->cm_clksel_core & 0xc) == 0x8)\r
-        omap_clk_setrate(l4_iclk, 2, 1);\r
-}\r
-\r
-static inline void omap3_cm_per_gptimer_update(struct omap3_cm_s *s)\r
-{\r
-    uint32_t cm_clksel_per = s->cm_clksel_per;\r
-\r
-    if (cm_clksel_per & 0x1)\r
-        omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp2_fclk"),\r
-                          omap_findclk(s->mpu, "omap3_sys_clk"));\r
-    else\r
-        omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp2_fclk"),\r
-                          omap_findclk(s->mpu, "omap3_32k_fclk"));\r
-    omap_gp_timer_change_clk(s->mpu->gptimer[1]);\r
-\r
-    if (cm_clksel_per & 0x2)\r
-        omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp3_fclk"),\r
-                          omap_findclk(s->mpu, "omap3_sys_clk"));\r
-    else\r
-        omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp3_fclk"),\r
-                          omap_findclk(s->mpu, "omap3_32k_fclk"));\r
-    omap_gp_timer_change_clk(s->mpu->gptimer[2]);\r
-\r
-    if (cm_clksel_per & 0x4)\r
-        omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp4_fclk"),\r
-                          omap_findclk(s->mpu, "omap3_sys_clk"));\r
-    else\r
-        omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp4_fclk"),\r
-                          omap_findclk(s->mpu, "omap3_32k_fclk"));\r
-    omap_gp_timer_change_clk(s->mpu->gptimer[3]);\r
-\r
-    if (cm_clksel_per & 0x8)\r
-        omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp5_fclk"),\r
-                          omap_findclk(s->mpu, "omap3_sys_clk"));\r
-    else\r
-        omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp5_fclk"),\r
-                          omap_findclk(s->mpu, "omap3_32k_fclk"));\r
-    omap_gp_timer_change_clk(s->mpu->gptimer[4]);\r
-\r
-    if (cm_clksel_per & 0x10)\r
-        omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp6_fclk"),\r
-                          omap_findclk(s->mpu, "omap3_sys_clk"));\r
-    else\r
-        omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp6_fclk"),\r
-                          omap_findclk(s->mpu, "omap3_32k_fclk"));\r
-    omap_gp_timer_change_clk(s->mpu->gptimer[5]);\r
-    \r
-    if (cm_clksel_per & 0x20)\r
-        omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp7_fclk"),\r
-                          omap_findclk(s->mpu, "omap3_sys_clk"));\r
-    else\r
-        omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp7_fclk"),\r
-                          omap_findclk(s->mpu, "omap3_32k_fclk"));\r
-    omap_gp_timer_change_clk(s->mpu->gptimer[6]);\r
-\r
-\r
-    if (cm_clksel_per & 0x40)\r
-        omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp8_fclk"),\r
-                          omap_findclk(s->mpu, "omap3_sys_clk"));\r
-    else\r
-        omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp8_fclk"),\r
-                          omap_findclk(s->mpu, "omap3_32k_fclk"));\r
-    omap_gp_timer_change_clk(s->mpu->gptimer[7]);\r
-    \r
-    if (cm_clksel_per & 0x80)\r
-        omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp9_fclk"),\r
-                          omap_findclk(s->mpu, "omap3_sys_clk"));\r
-    else\r
-        omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp9_fclk"),\r
-                          omap_findclk(s->mpu, "omap3_32k_fclk"));\r
-    omap_gp_timer_change_clk(s->mpu->gptimer[8]);\r
-\r
-    /*TODO:Tell GPTIMER to generate new clk rate */\r
-    TRACE("omap3_gp2_fclk %lld",\r
-          omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp2_fclk")));\r
-    TRACE("omap3_gp3_fclk %lld",\r
-          omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp3_fclk")));\r
-       TRACE("omap3_gp4_fclk %lld",\r
-          omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp4_fclk")));\r
-    TRACE("omap3_gp5_fclk %lld",\r
-          omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp5_fclk")));\r
-    TRACE("omap3_gp6_fclk %lld",\r
-          omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp6_fclk")));\r
-    TRACE("omap3_gp7_fclk %lld",\r
-          omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp7_fclk")));\r
-    TRACE("omap3_gp8_fclk %lld",\r
-          omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp8_fclk")));\r
-    TRACE("omap3_gp9_fclk %lld",\r
-          omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp9_fclk")));\r
-}\r
-\r
-static inline void omap3_cm_clkout2_update(struct omap3_cm_s *s)\r
-{\r
-       uint32 divor;\r
-       \r
-       if (!s->cm_clkout_ctrl&0x80)\r
-               return;\r
-\r
-       switch (s->cm_clkout_ctrl&0x3)\r
-       {\r
-               case 0x0:\r
-                       omap_clk_reparent(omap_findclk(s->mpu, "omap3_sys_clkout2"),\r
-                          omap_findclk(s->mpu, "omap3_core_clk"));\r
-                       break;\r
-               case 0x1:\r
-                       omap_clk_reparent(omap_findclk(s->mpu, "omap3_sys_clkout2"),\r
-                          omap_findclk(s->mpu, "omap3_sys_clk"));\r
-                       break;\r
-               case 0x2:\r
-                       omap_clk_reparent(omap_findclk(s->mpu, "omap3_sys_clkout2"),\r
-                          omap_findclk(s->mpu, "omap3_96m_fclk"));\r
-                       break;\r
-               case 0x3:\r
-                       omap_clk_reparent(omap_findclk(s->mpu, "omap3_sys_clkout2"),\r
-                          omap_findclk(s->mpu, "omap3_54m_fclk"));\r
-                       break;\r
-       }\r
-\r
-       divor = (s->cm_clkout_ctrl&0x31)>>3;\r
-       divor = 1<<divor;\r
-       omap_clk_setrate(omap_findclk(s->mpu, "omap3_sys_clkout2"), divor, 1);\r
-       \r
-}\r
-\r
-static void omap3_cm_reset(struct omap3_cm_s *s)\r
-{\r
-    s->cm_fclken_iva2 = 0x0;\r
-    s->cm_clken_pll_iva2 = 0x11;\r
-    s->cm_idlest_iva2 = 0x1;\r
-    s->cm_idlest_pll_iva2 = 0x0;\r
-    s->cm_autoidle_pll_iva2 = 0x0;\r
-    s->cm_clksel1_pll_iva2 = 0x80000;\r
-    s->cm_clksel2_pll_iva2 = 0x1;\r
-    s->cm_clkstctrl_iva2 = 0x0;\r
-    s->cm_clkstst_iva2 = 0x0;\r
-\r
-    s->cm_revision = 0x10;\r
-    s->cm_sysconfig = 0x1;\r
-\r
-    s->cm_clken_pll_mpu = 0x15;\r
-    s->cm_idlest_mpu = 0x1;\r
-    s->cm_idlest_pll_mpu = 0x0;\r
-    s->cm_autoidle_pll_mpu = 0x0;\r
-    s->cm_clksel1_pll_mpu = 0x80000;\r
-    s->cm_clksel2_pll_mpu = 0x1;\r
-    s->cm_clkstctrl_mpu = 0x0;\r
-    s->cm_clkstst_mpu = 0x0;\r
-\r
-    s->cm_fclken1_core = 0x0;\r
-    s->cm_fclken3_core = 0x0;\r
-    s->cm_iclken1_core = 0x42;\r
-    s->cm_iclken2_core = 0x0;\r
-    s->cm_iclken3_core = 0x0;\r
-    /*allow access to devices*/\r
-    s->cm_idlest1_core = 0x0;\r
-    s->cm_idlest2_core = 0x0;\r
-    /*ide status =0 */\r
-    s->cm_idlest3_core = 0xa; \r
-    s->cm_autoidle1_core = 0x0;\r
-    s->cm_autoidle2_core = 0x0;\r
-    s->cm_autoidle3_core = 0x0;\r
-    s->cm_clksel_core = 0x105;\r
-    s->cm_clkstctrl_core = 0x0;\r
-    s->cm_clkstst_core = 0x0;\r
-\r
-    s->cm_fclken_sgx = 0x0;\r
-    s->cm_iclken_sgx = 0x0;\r
-    s->cm_idlest_sgx = 0x1;\r
-    s->cm_clksel_sgx = 0x0;\r
-    s->cm_sleepdep_sgx = 0x0;\r
-    s->cm_clkstctrl_sgx = 0x0;\r
-    s->cm_clkstst_sgx = 0x0;\r
-\r
-    s->cm_fclken_wkup = 0x0;\r
-    s->cm_iclken_wkup = 0x0;\r
-    /*assume all clock can be accessed*/\r
-    s->cm_idlest_wkup = 0x0;\r
-    s->cm_autoidle_wkup = 0x0;\r
-    s->cm_clksel_wkup = 0x12;\r
-\r
-    s->cm_clken_pll = 0x110015;\r
-    s->cm_clken2_pll = 0x11;\r
-    s->cm_idlest_ckgen = 0x0;\r
-    s->cm_idlest2_ckgen = 0x0;\r
-    s->cm_autoidle_pll = 0x0;\r
-    s->cm_autoidle2_pll = 0x0;\r
-    s->cm_clksel1_pll = 0x8000040;\r
-    s->cm_clksel2_pll = 0x0;\r
-    s->cm_clksel3_pll = 0x1;\r
-    s->cm_clksel4_pll = 0x0;\r
-    s->cm_clksel5_pll = 0x1;\r
-    s->cm_clkout_ctrl = 0x3;\r
-\r
-\r
-    s->cm_fclken_dss = 0x0;\r
-    s->cm_iclken_dss = 0x0;\r
-    /*dss can be accessed*/\r
-    s->cm_idlest_dss = 0x0;\r
-    s->cm_autoidle_dss = 0x0;\r
-    s->cm_clksel_dss = 0x1010;\r
-    s->cm_sleepdep_dss = 0x0;\r
-    s->cm_clkstctrl_dss = 0x0;\r
-    s->cm_clkstst_dss = 0x0;\r
-\r
-    s->cm_fclken_cam = 0x0;\r
-    s->cm_iclken_cam = 0x0;\r
-    s->cm_idlest_cam = 0x1;\r
-    s->cm_autoidle_cam = 0x0;\r
-    s->cm_clksel_cam = 0x10;\r
-    s->cm_sleepdep_cam = 0x0;\r
-    s->cm_clkstctrl_cam = 0x0;\r
-    s->cm_clkstst_cam = 0x0;\r
-\r
-    s->cm_fclken_per = 0x0;\r
-    s->cm_iclken_per = 0x0;\r
-    //s->cm_idlest_per = 0x3ffff;\r
-    s->cm_idlest_per = 0x0; //enable GPIO access\r
-    s->cm_autoidle_per = 0x0;\r
-    s->cm_clksel_per = 0x0;\r
-    s->cm_sleepdep_per = 0x0;\r
-    s->cm_clkstctrl_per = 0x0;\r
-    s->cm_clkstst_per = 0x0;\r
-\r
-    s->cm_clksel1_emu = 0x10100a50;\r
-    s->cm_clkstctrl_emu = 0x2;\r
-    s->cm_clkstst_emu = 0x0;\r
-    s->cm_clksel2_emu = 0x0;\r
-    s->cm_clksel3_emu = 0x0;\r
-\r
-    s->cm_polctrl = 0x0;\r
-\r
-    s->cm_idlest_neon = 0x1;\r
-    s->cm_clkstctrl_neon = 0x0;\r
-\r
-    s->cm_fclken_usbhost = 0x0;\r
-    s->cm_iclken_usbhost = 0x0;\r
-    s->cm_idlest_usbhost = 0x3;\r
-    s->cm_autoidle_usbhost = 0x0;\r
-    s->cm_sleepdep_usbhost = 0x0;\r
-    s->cm_clkstctrl_usbhost = 0x0;\r
-    s->cm_clkstst_usbhost = 0x0;\r
-}\r
-\r
-static uint32_t omap3_cm_read(void *opaque, target_phys_addr_t addr)\r
-{\r
-    struct omap3_cm_s *s = (struct omap3_cm_s *) opaque;\r
-    uint32_t ret;\r
-    uint32_t bypass = 0, m;\r
-\r
-    TRACE("%04x", addr);\r
-    switch (addr)\r
-    {\r
-    case 0x0:\r
-       return s->cm_fclken_iva2;\r
-    case 0x04:\r
-        return s->cm_clken_pll_iva2;\r
-    case 0x20:\r
-       return s->cm_idlest_iva2;\r
-    case 0x24:\r
-        if (((s->cm_clken_pll_iva2 & 0x7) == 0x5)\r
-            || ((s->cm_clken_pll_iva2 & 0x7) == 0x1))\r
-        {\r
-            bypass = 1;\r
-        }\r
-        else if ((s->cm_clken_pll_iva2 & 0x7) == 0x7)\r
-        {\r
-            m = (s->cm_clksel1_pll_iva2 & 0x7ff00) >> 8;\r
-            if ((m == 0) || (m == 1))\r
-                bypass = 1;\r
-            else\r
-                bypass = 0;\r
-        }\r
-        if (bypass)\r
-            return 0;\r
-        else\r
-            return 1;\r
-    case 0x34:\r
-       return s->cm_autoidle_pll_iva2;\r
-    case 0x40:\r
-        return s->cm_clksel1_pll_iva2;\r
-    case 0x44:\r
-        return s->cm_clksel2_pll_iva2;\r
-    case 0x48:\r
-       return s->cm_clkstctrl_iva2;\r
-    case 0x4c:\r
-       return s->cm_clkstst_iva2;\r
-\r
-   case 0x800:\r
-               return s->cm_revision;\r
-       case 0x810:\r
-               return s->cm_sysconfig;\r
-\r
-       \r
-    case 0x904:                /*CM_CLKEN_PLL_MPU */\r
-        return s->cm_clken_pll_mpu;\r
-   case 0x920:\r
-               return s->cm_idlest_mpu & 0x0;  /*MPU is active*/\r
-    case 0x924:\r
-        if ((s->cm_clken_pll_mpu & 0x7) == 0x5)\r
-        {\r
-            bypass = 1;\r
-        }\r
-        else if ((s->cm_clken_pll_mpu & 0x7) == 0x7)\r
-        {\r
-            m = (s->cm_clksel1_pll_mpu & 0x7ff00) >> 8;\r
-            if ((m == 0) || (m == 1))\r
-                bypass = 1;\r
-            else\r
-                bypass = 0;\r
-        }\r
-        if (bypass)\r
-            return 0;\r
-        else\r
-            return 1;\r
-    case 0x934:\r
-       return s->cm_autoidle_pll_mpu;\r
-    case 0x940:\r
-        return s->cm_clksel1_pll_mpu;\r
-    case 0x944:\r
-        return s->cm_clksel2_pll_mpu;\r
-     case 0x948:\r
-       return s->cm_clkstctrl_mpu;\r
-     case 0x94c:\r
-       return s->cm_clkstst_mpu;\r
-\r
-\r
-       \r
-    case 0xa00:\r
-        return s->cm_fclken1_core;\r
-    case 0xa08:\r
-       return s->cm_fclken3_core;\r
-    case 0xa10:\r
-        return s->cm_iclken1_core;\r
-    case 0xa14:\r
-        return s->cm_iclken2_core;\r
-    case 0xa20:\r
-       return s->cm_idlest1_core;\r
-    case 0xa24:\r
-       return s->cm_idlest2_core;\r
-    case 0xa28:\r
-       return s->cm_idlest3_core;\r
-    case 0xa30:\r
-       return s->cm_autoidle1_core;\r
-    case 0xa34:\r
-       return s->cm_autoidle2_core;\r
-    case 0xa38:\r
-       return s->cm_autoidle3_core;\r
-    case 0xa40:                /*CM_CLKSEL_CORE */\r
-        return s->cm_clksel_core;\r
-    case 0xa48:\r
-        return s->cm_clkstctrl_core;\r
-     case 0xa4c:\r
-       return s->cm_clkstst_core;\r
-\r
-   case 0xb00:\r
-               return s->cm_fclken_sgx;\r
-       case 0xb10:\r
-               return s->cm_iclken_sgx;\r
-       case 0xb20:\r
-               return s->cm_idlest_sgx&0x0;\r
-   case 0xb40:                /*CM_CLKSEL_SGX */\r
-        return s->cm_clksel_sgx;\r
-   case 0xb48:\r
-               return s->cm_clkstctrl_sgx;\r
-       case 0xb4c:\r
-               return s->cm_clkstst_sgx;\r
-\r
-               \r
-    case 0xc00:                /*CM_FCLKEN_WKUP */\r
-        return s->cm_fclken_wkup;\r
-    case 0xc10:                /*CM_ICLKEN_WKUP */\r
-        return s->cm_iclken_wkup;\r
-    case 0xc20:                /*CM_IDLEST_WKUP */\r
-        /*TODO: Check whether the timer can be accessed. */\r
-        return 0x0;\r
-    case 0xc30:\r
-       return s->cm_idlest_wkup;\r
-    case 0xc40:\r
-        return s->cm_clksel_wkup;\r
-    case 0xc48:\r
-       return s->cm_c48;\r
-\r
-       \r
-    case 0xd00:                /*CM_CLKEN_PLL */\r
-        return s->cm_clken_pll;\r
-    case 0xd04:\r
-       return s->cm_clken2_pll;\r
-    case 0xd20:\r
-        /*FIXME: all clock is active. we do not care it. */\r
-        ret = 0x3ffff;\r
-\r
-       /*DPLL3*/\r
-       bypass = 0;\r
-       if (((s->cm_clken_pll & 0x7) == 0x5) || ((s->cm_clken_pll & 0x7) == 0x6))\r
-               bypass = 1;\r
-        else if ((s->cm_clken_pll & 0x7) == 0x7) {\r
-            m = (s->cm_clksel1_pll & 0x7ff0000) >> 16;\r
-            if ((m == 0) || (m == 1))\r
-                bypass = 1;\r
-            else\r
-                bypass = 0;\r
-        }\r
-        if (bypass)\r
-            ret &= 0xfffe;\r
-        \r
-        /*DPLL4*/\r
-           bypass = 0;\r
-           if ((s->cm_clken_pll & 0x70000) == 0x10000)\r
-            bypass = 1;\r
-        else if ((s->cm_clken_pll & 0x70000) == 0x70000) {\r
-            m = (s->cm_clksel2_pll & 0x7ff00) >> 8;\r
-            if ((m == 0) || (m == 1))\r
-                bypass = 1;\r
-            else\r
-                bypass = 0;\r
-        }\r
-        if (bypass)\r
-            ret &= 0xfffd;\r
-       return ret;\r
-       \r
-    case 0xd24:\r
-       return s->cm_idlest2_ckgen;\r
-    case 0xd30:\r
-       return s->cm_autoidle_pll;\r
-    case 0xd34:\r
-       return s->cm_autoidle2_pll;\r
-    case 0xd40:                /*CM_CLKSEL1_PLL */\r
-        return s->cm_clksel1_pll;\r
-    case 0xd44:\r
-        return s->cm_clksel2_pll;\r
-    case 0xd48:                /*CM_CLKSEL3_PLL */\r
-        return s->cm_clksel3_pll;\r
-    case 0xd4c:\r
-        return s->cm_clksel4_pll;\r
-    case 0xd50:                /*CM_CLKSEL5_PLL */\r
-        return s->cm_clksel5_pll;\r
-    case 0xd70:\r
-        return s->cm_clkout_ctrl;\r
-\r
-        \r
-    case 0xe00:\r
-       return s->cm_fclken_dss;\r
-       case 0xe10:\r
-       return s->cm_iclken_dss;\r
-    case 0xe20:\r
-       return s->cm_idlest_dss;\r
-    case 0xe30:\r
-       return s->cm_autoidle_dss;\r
-    case 0xe40:\r
-        return s->cm_clksel_dss;\r
-    case 0xe44:\r
-        return s->cm_sleepdep_dss;\r
-    case 0xe48:\r
-        return s->cm_clkstctrl_dss;\r
-    case 0xe4c:\r
-        return s->cm_clkstst_dss;\r
-\r
-        \r
-    case 0xf00:\r
-       return s->cm_fclken_cam;\r
-    case 0xf10:\r
-       return s->cm_iclken_cam;\r
-    case 0xf20:\r
-       return s->cm_idlest_cam&0x0;\r
-    case 0xf30:\r
-       return s->cm_autoidle_cam;\r
-    case 0xf40:\r
-        return s->cm_clksel_cam;\r
-    case 0xf44:\r
-       return s->cm_sleepdep_cam;\r
-    case 0xf48:\r
-       return s->cm_clkstctrl_cam;\r
-    case 0xf4c:\r
-       return s->cm_clkstst_cam;\r
-\r
-       \r
-    case 0x1000:\r
-        return s->cm_fclken_per;\r
-    case 0x1010:\r
-        return s->cm_iclken_per;\r
-    case 0x1020:\r
-       return s->cm_idlest_per ;\r
-    case 0x1030:\r
-       return s->cm_autoidle_per;\r
-    case 0x1040:\r
-        return s->cm_clksel_per;\r
-    case 0x1044:\r
-       return s->cm_sleepdep_per;\r
-    case 0x1048:\r
-       return s->cm_clkstctrl_per;\r
-    case 0x104c:\r
-               return s->cm_clkstst_per;\r
-\r
-       \r
-    case 0x1140:               /*CM_CLKSEL1_EMU */\r
-        return s->cm_clksel1_emu;\r
-    case 0x1148:\r
-        return s->cm_clkstctrl_emu;\r
-    case 0x114c:\r
-       return s->cm_clkstst_emu&0x0;\r
-    case 0x1150:\r
-       return s->cm_clksel2_emu;\r
-    case 0x1154:\r
-       return s->cm_clksel3_emu;\r
-\r
-   case 0x129c:\r
-               return s->cm_polctrl;\r
-\r
-       case 0x1320:\r
-               return s->cm_idlest_neon&0x0;\r
-       case 0x1348:\r
-               return s->cm_clkstctrl_neon;\r
-\r
-       case 0x1400:\r
-               return s->cm_fclken_usbhost;\r
-       case 0x1410:\r
-               return s->cm_iclken_usbhost;\r
-       case 0x1420:\r
-               return s->cm_idlest_usbhost&0x0;\r
-    case 0x1430:\r
-       return s->cm_autoidle_usbhost;\r
-    case 0x1444:\r
-       return s->cm_sleepdep_usbhost;\r
-    case 0x1448:\r
-       return s->cm_clkstctrl_usbhost;\r
-    case 0x144c:\r
-       return s->cm_clkstst_usbhost;\r
-\r
-    default:\r
-        printf("omap3_cm_read addr %x pc %x \n", addr, cpu_single_env->regs[15] );\r
-        exit(-1);\r
-    }\r
-}\r
-\r
-\r
-static void omap3_cm_write(void *opaque, target_phys_addr_t addr,\r
-                           uint32_t value)\r
-{\r
-    struct omap3_cm_s *s = (struct omap3_cm_s *) opaque;\r
-\r
-    TRACE("%04x = %08x", addr, value);\r
-    switch (addr)\r
-    {\r
-    case 0x20:\r
-    case 0x24:\r
-    case 0x4c:\r
-    case 0x800:\r
-    case 0x920:\r
-    case 0x924:\r
-    case 0x94c:\r
-    case 0xa20:\r
-    case 0xa24:\r
-    case 0xa28:\r
-    case 0xa4c:\r
-    case 0xb20:\r
-    case 0xb4c:\r
-    case 0xc20:                /*CM_IDLEST_WKUP */\r
-    case 0xd20:\r
-    case 0xd24:\r
-    case 0xe20:\r
-    case 0xe4c:\r
-    case 0xf20:\r
-    case 0xf4c:\r
-    case 0x1020:\r
-    case 0x104c:\r
-    case 0x114c:\r
-    case 0x1320:\r
-    case 0x1420:\r
-    case 0x144c:\r
-        OMAP_RO_REG(addr);\r
-        exit(-1);\r
-        break;\r
-        \r
-    case 0x0:\r
-       s->cm_fclken_iva2 = value & 0x1;\r
-       break;\r
-    case 0x4:                  /*CM_CLKEN_PLL_IVA2 */\r
-        s->cm_clken_pll_iva2 = value & 0x7ff;\r
-        omap3_cm_iva2_update(s);\r
-        break;\r
-    case 0x34:\r
-       s->cm_autoidle_pll_iva2 = value & 0x7;\r
-       break;\r
-    case 0x40:\r
-        s->cm_clksel1_pll_iva2 = value & 0x3fff7f;\r
-        //printf("value %x s->cm_clksel1_pll_iva2 %x \n",value,s->cm_clksel1_pll_iva2);\r
-        omap3_cm_iva2_update(s);\r
-        break;\r
-    case 0x44:\r
-        s->cm_clksel2_pll_iva2 = value & 0x1f;\r
-        omap3_cm_iva2_update(s);\r
-        break;\r
-    case 0x48:\r
-       s->cm_clkstctrl_iva2 = value& 0x3;\r
-       break;\r
-\r
-    case 0x810:\r
-       s->cm_sysconfig = value & 0x1;\r
-       break;\r
-\r
-        \r
-    case 0x904:                /*CM_CLKEN_PLL_MPU */\r
-        s->cm_clken_pll_mpu = value & 0x7ff;\r
-        omap3_cm_mpu_update(s);\r
-        break;\r
-    case 0x934:\r
-       s->cm_autoidle_pll_mpu = value & 0x7;\r
-       break;\r
-    case 0x940:\r
-        //printf("s->cm_clksel1_pll_mpu  %x\n",s->cm_clksel1_pll_mpu );\r
-        s->cm_clksel1_pll_mpu = value & 0x3fff7f;\r
-        omap3_cm_mpu_update(s);\r
-        break;\r
-    case 0x944:\r
-        s->cm_clksel2_pll_mpu = value & 0x1f;\r
-        omap3_cm_mpu_update(s);\r
-        break;\r
-    case 0x948:\r
-       s->cm_clkstctrl_mpu = value & 0x3;\r
-       break;\r
-\r
-       \r
-    case 0xa00:\r
-        s->cm_fclken1_core = value & 0x43fffe00;\r
-         break;\r
-    case 0xa08:\r
-        s->cm_fclken3_core = value & 0x7;\r
-        break;\r
-    case 0xa10:\r
-        s->cm_iclken1_core = value & 0x7ffffed2;\r
-         break;\r
-    case 0xa14:\r
-        s->cm_iclken2_core = value & 0x1f;\r
-        break;\r
-    case 0xa18:\r
-       s->cm_iclken3_core = value & 0x2;\r
-       break;\r
-    case 0xa30:\r
-       s->cm_autoidle1_core = value & 0x7ffffed0;\r
-       break;\r
-    case 0xa34:\r
-       s->cm_autoidle2_core = value & 0x1f;\r
-       break;\r
-    case 0xa38:\r
-       s->cm_autoidle3_core = value & 0x2;\r
-       break;\r
-    case 0xa40:                /*CM_CLKSEL_CORE */\r
-        s->cm_clksel_core = (value & 0xff);\r
-        s->cm_clksel_core |= 0x100;\r
-        omap3_cm_gp10_update(s);\r
-        omap3_cm_gp11_update(s);\r
-        omap3_cm_l3clk_update(s);\r
-        omap3_cm_l4clk_update(s);\r
-        break;\r
-    case 0xa48:\r
-       s->cm_clkstctrl_core = value & 0xf;\r
-       break;\r
-\r
-    case 0xb00:\r
-       s->cm_fclken_sgx = value &0x2;\r
-       break;\r
-    case 0xb10:\r
-       s->cm_iclken_sgx = value & 0x1;\r
-       break;\r
-    case 0xb40:                /*CM_CLKSEL_SGX */\r
-        /*TODO: SGX Clock!! */\r
-        s->cm_clksel_sgx = value;\r
-        break;\r
-    case 0xb44:\r
-       s->cm_sleepdep_sgx = value &0x2;\r
-       break;\r
-    case 0xb48:\r
-       s->cm_clkstctrl_sgx = value & 0x3;\r
-       break;\r
-\r
-    \r
-    case 0xc00:                /*CM_FCLKEN_WKUP */\r
-        s->cm_fclken_wkup = value & 0x2e9;\r
-        break;\r
-    case 0xc10:                /*CM_ICLKEN_WKUP */\r
-        s->cm_iclken_wkup = value & 0x2ff;\r
-        break;\r
-    case 0xc30:\r
-       s->cm_autoidle_wkup = value & 0x23f;\r
-       break;\r
-    case 0xc40:                /*CM_CLKSEL_WKUP */\r
-        s->cm_clksel_wkup = value & 0x7f;\r
-        omap3_cm_clksel_wkup_update(s, s->cm_clksel_wkup);\r
-        break;\r
-\r
-        \r
-    case 0xd00:                /*CM_CLKEN_PLL */\r
-        s->cm_clken_pll = value & 0xffff17ff;\r
-        omap3_cm_dpll3_update(s);\r
-        omap3_cm_dpll4_update(s);\r
-        break;\r
-    case 0xd04:\r
-       s->cm_clken2_pll = value & 0x7ff;\r
-       break;\r
-    case 0xd30:\r
-       s->cm_autoidle_pll = value & 0x3f;\r
-       break;\r
-    case 0xd34:\r
-       s->cm_autoidle2_pll = value & 0x7;\r
-       break;\r
-    case 0xd40:                /*CM_CLKSEL1_PLL */\r
-        //OMAP3_DEBUG(("WD40 value %x \n",value));\r
-        s->cm_clksel1_pll = value & 0xffffbffc;\r
-        //OMAP3_DEBUG(("WD40 value %x \n",value));\r
-        omap3_cm_dpll3_update(s);\r
-        omap3_cm_48m_update(s);\r
-        break;\r
-    case 0xd44:\r
-        s->cm_clksel2_pll = value & 0x7ff7f;\r
-        omap3_cm_dpll4_update(s);\r
-        break;\r
-    case 0xd48:                /*CM_CLKSEL3_PLL */\r
-        s->cm_clksel3_pll = value & 0x1f;\r
-        omap3_cm_dpll4_update(s);\r
-        break;\r
-    case 0xd4c:                /*CM_CLKSEL4_PLL */  \r
-       s->cm_clksel4_pll = value & 0x7ff7f;\r
-        omap3_cm_dpll5_update(s);\r
-        break;\r
-     case 0xd50:                /*CM_CLKSEL5_PLL */\r
-        s->cm_clksel5_pll = value & 0x1f;\r
-        omap3_cm_dpll5_update(s);\r
-        break;\r
-    case 0xd70:\r
-       s->cm_clkout_ctrl = value & 0xbb;\r
-       omap3_cm_clkout2_update(s);\r
-       break;\r
-        \r
-    case 0xe00:\r
-       s->cm_fclken_dss = value & 0x7;\r
-       break;\r
-       case 0xe10:\r
-       s->cm_iclken_dss = value & 0x1;\r
-       break;\r
-    case 0xe30:\r
-       s->cm_autoidle_dss = value & 0x1;\r
-       break;\r
-    case 0xe40:\r
-        s->cm_clksel_dss = value & 0x1f1f;\r
-        omap3_cm_dpll4_update(s);\r
-        break;\r
-   case 0xe44:\r
-               s->cm_sleepdep_dss = value & 0x7;\r
-       break;\r
-   case 0xe48:\r
-               s->cm_clkstctrl_dss = value & 0x3;\r
-       break;\r
-        \r
-    case 0xf00:\r
-       s->cm_fclken_cam = value & 0x3;\r
-       break;\r
-    case 0xf10:\r
-       s->cm_iclken_cam = value & 0x1;\r
-       break;\r
-    case 0xf30:\r
-       s->cm_autoidle_cam = value & 0x1;\r
-       break;\r
-    case 0xf40:\r
-        s->cm_clksel_cam = value & 0x1f;\r
-        omap3_cm_dpll4_update(s);\r
-        break;\r
-    case 0xf44:\r
-       s->cm_sleepdep_cam = value & 0x2;\r
-       break;\r
-    case 0xf48:\r
-       s->cm_clkstctrl_cam = value & 0x3;\r
-       break;\r
-   \r
-    case 0x1000:\r
-        s->cm_fclken_per = value & 0x3ffff;\r
-        break;\r
-    case 0x1010:\r
-        s->cm_iclken_per = value & 0x3ffff;\r
-        break;\r
-    \r
-    case 0x1030:\r
-       s->cm_autoidle_per = value &0x3ffff;\r
-       break;\r
-    case 0x1040:\r
-        s->cm_clksel_per = value & 0xff;\r
-        omap3_cm_per_gptimer_update(s);\r
-        break;\r
-    case 0x1044:\r
-       s->cm_sleepdep_per = value & 0x6;\r
-       break;\r
-    case 0x1048:\r
-        s->cm_clkstctrl_per = value &0x7;\r
-        break;\r
-        \r
-    case 0x1140:               /*CM_CLKSEL1_EMU */\r
-        s->cm_clksel1_emu = value & 0x1f1f3fff;\r
-        //printf("cm_clksel1_emu %x\n",s->cm_clksel1_emu);\r
-        omap3_cm_dpll3_update(s);\r
-        omap3_cm_dpll4_update(s);\r
-        break;\r
-    case 0x1148:\r
-       s->cm_clkstctrl_emu = value & 0x3;\r
-       break;\r
-        case 0x1150:\r
-                s->cm_clksel2_emu = value & 0xfff7f;\r
-                omap3_cm_dpll3_update(s);\r
-        break;\r
-    case 0x1154:\r
-        s->cm_clksel3_emu = value & 0xfff7f;\r
-                omap3_cm_dpll4_update(s);\r
-        break;\r
-\r
-    case 0x129c:\r
-        s->cm_polctrl = value & 0x1;\r
-        break;\r
-\r
-   case 0x1348:\r
-               s->cm_clkstctrl_neon = value & 0x3;\r
-               break;\r
-\r
-       case 0x1400:\r
-               s->cm_fclken_usbhost = value & 0x3;\r
-               break;\r
-       case 0x1410:\r
-               s->cm_iclken_usbhost = value & 0x1;\r
-               break;\r
-    case 0x1430:\r
-       s->cm_autoidle_usbhost = value & 0x1;\r
-       break;\r
-    case 0x1444:\r
-       s->cm_sleepdep_usbhost = value & 0x6;\r
-       break;\r
-    case 0x1448:\r
-       s->cm_clkstctrl_usbhost = value & 0x3;\r
-       break;\r
-   \r
-    default:\r
-        printf("omap3_cm_write addr %x value %x pc %x\n", addr, value,cpu_single_env->regs[15] );\r
-        exit(-1);\r
-    }\r
-}\r
-\r
-\r
-\r
-static CPUReadMemoryFunc *omap3_cm_readfn[] = {\r
-    omap_badwidth_read32,\r
-    omap_badwidth_read32,\r
-    omap3_cm_read,\r
-};\r
-\r
-static CPUWriteMemoryFunc *omap3_cm_writefn[] = {\r
-    omap_badwidth_write32,\r
-    omap_badwidth_write32,\r
-    omap3_cm_write,\r
-};\r
-\r
-struct omap3_cm_s *omap3_cm_init(struct omap_target_agent_s *ta,\r
-                                 qemu_irq mpu_int, qemu_irq dsp_int,\r
-                                 qemu_irq iva_int, struct omap_mpu_state_s *mpu)\r
-{\r
-    int iomemtype;\r
-    struct omap3_cm_s *s = (struct omap3_cm_s *) qemu_mallocz(sizeof(*s));\r
-\r
-    s->irq[0] = mpu_int;\r
-    s->irq[1] = dsp_int;\r
-    s->irq[2] = iva_int;\r
-    s->mpu = mpu;\r
-    omap3_cm_reset(s);\r
-\r
-    iomemtype = l4_register_io_memory(0, omap3_cm_readfn, omap3_cm_writefn, s);\r
-    omap_l4_attach(ta, 0, iomemtype);\r
-    omap_l4_attach(ta, 1, iomemtype);\r
-\r
-    return s;\r
-}\r
-\r
-#define OMAP3_SEC_WDT          1\r
-#define OMAP3_MPU_WDT         2\r
-#define OMAP3_IVA2_WDT        3\r
-/*omap3 watchdog timer*/\r
-struct omap3_wdt_s\r
-{\r
-    qemu_irq irq;               /*IVA2 IRQ */\r
-    struct omap_mpu_state_s *mpu;\r
-    omap_clk clk;\r
-    QEMUTimer *timer;\r
-\r
-    int active;\r
-    int64_t rate;\r
-    int64_t time;\r
-    //int64_t ticks_per_sec;\r
-\r
-    uint32_t wd_sysconfig;\r
-    uint32_t wd_sysstatus;\r
-    uint32_t wisr;\r
-    uint32_t wier;\r
-    uint32_t wclr;\r
-    uint32_t wcrr;\r
-    uint32_t wldr;\r
-    uint32_t wtgr;\r
-    uint32_t wwps;\r
-    uint32_t wspr;\r
-\r
-    /*pre and ptv in wclr */\r
-    uint32_t pre;\r
-    uint32_t ptv;\r
-    //uint32_t val;\r
-\r
-    uint16_t writeh;            /* LSB */\r
-    uint16_t readh;             /* MSB */\r
-\r
-};\r
-\r
-\r
-\r
-\r
-\r
-static inline void omap3_wdt_timer_update(struct omap3_wdt_s *wdt_timer)\r
-{\r
-    int64_t expires;\r
-    if (wdt_timer->active)\r
-    {\r
-        expires = muldiv64(0xffffffffll - wdt_timer->wcrr,\r
-                           ticks_per_sec, wdt_timer->rate);\r
-        qemu_mod_timer(wdt_timer->timer, wdt_timer->time + expires);\r
-    }\r
-    else\r
-        qemu_del_timer(wdt_timer->timer);\r
-}\r
-static void omap3_wdt_clk_setup(struct omap3_wdt_s *timer)\r
-{\r
-    /*TODO: Add irq as user to clk */\r
-}\r
-\r
-static inline uint32_t omap3_wdt_timer_read(struct omap3_wdt_s *timer)\r
-{\r
-    uint64_t distance;\r
-\r
-    if (timer->active)\r
-    {\r
-        distance = qemu_get_clock(vm_clock) - timer->time;\r
-        distance = muldiv64(distance, timer->rate, ticks_per_sec);\r
-\r
-        if (distance >= 0xffffffff - timer->wcrr)\r
-            return 0xffffffff;\r
-        else\r
-            return timer->wcrr + distance;\r
-    }\r
-    else\r
-        return timer->wcrr;\r
-}\r
-\r
-/*\r
-static inline void omap3_wdt_timer_sync(struct omap3_wdt_s *timer)\r
-{\r
-    if (timer->active) {\r
-        timer->val = omap3_wdt_timer_read(timer);\r
-        timer->time = qemu_get_clock(vm_clock);\r
-    }\r
-}*/\r
-\r
-static void omap3_wdt_reset(struct omap3_wdt_s *s, int wdt_index)\r
-{\r
-    s->wd_sysconfig = 0x0;\r
-    s->wd_sysstatus = 0x0;\r
-    s->wisr = 0x0;\r
-    s->wier = 0x0;\r
-    s->wclr = 0x20;\r
-    s->wcrr = 0x0;\r
-    switch (wdt_index)\r
-    {\r
-    case OMAP3_MPU_WDT:\r
-    case OMAP3_IVA2_WDT:\r
-        s->wldr = 0xfffb0000;\r
-        break;\r
-    case OMAP3_SEC_WDT:\r
-        s->wldr = 0xffa60000;\r
-        break;\r
-    }\r
-    s->wtgr = 0x0;\r
-    s->wwps = 0x0;\r
-    s->wspr = 0x0;\r
-\r
-    switch (wdt_index)\r
-    {\r
-    case OMAP3_SEC_WDT:\r
-    case OMAP3_MPU_WDT:\r
-        s->active = 1;\r
-        break;\r
-    case OMAP3_IVA2_WDT:\r
-        s->active = 0;\r
-        break;\r
-    }\r
-    s->pre = s->wclr & (1 << 5);\r
-    s->ptv = (s->wclr & 0x1c) >> 2;\r
-    s->rate = omap_clk_getrate(s->clk) >> (s->pre ? s->ptv : 0);\r
-\r
-    s->active = 1;\r
-    s->time = qemu_get_clock(vm_clock);\r
-    omap3_wdt_timer_update(s);\r
-}\r
-\r
-static uint32_t omap3_wdt_read32(void *opaque, target_phys_addr_t addr,\r
-                                 int wdt_index)\r
-{\r
-    struct omap3_wdt_s *s = (struct omap3_wdt_s *) opaque;\r
-\r
-    //uint32_t ret;\r
-    //printf("omap3_wdt_read32 addr %x \n",addr);\r
-    switch (addr)\r
-    {\r
-    case 0x10:                 /*WD_SYSCONFIG */\r
-        return s->wd_sysconfig;\r
-    case 0x14:                 /*WD_SYSSTATUS */\r
-        return s->wd_sysstatus;\r
-    case 0x18:\r
-         /*WISR*/ return s->wisr & 0x1;\r
-    case 0x1c:\r
-         /*WIER*/ return s->wier & 0x1;\r
-    case 0x24:\r
-         /*WCLR*/ return s->wclr & 0x3c;\r
-    case 0x28:\r
-         /*WCRR*/ s->wcrr = omap3_wdt_timer_read(s);\r
-        s->time = qemu_get_clock(vm_clock);\r
-        return s->wcrr;\r
-    case 0x2c:\r
-         /*WLDR*/ return s->wldr;\r
-    case 0x30:\r
-         /*WTGR*/ return s->wtgr;\r
-    case 0x34:\r
-         /*WWPS*/ return s->wwps;\r
-    case 0x48:\r
-         /*WSPR*/ return s->wspr;\r
-    default:\r
-        printf("omap3_wdt_read32 addr %x \n", addr);\r
-        exit(-1);\r
-    }\r
-}\r
-static uint32_t omap3_mpu_wdt_read16(void *opaque, target_phys_addr_t addr)\r
-{\r
-    struct omap3_wdt_s *s = (struct omap3_wdt_s *) opaque;\r
-    uint32_t ret;\r
-\r
-    if (addr & 2)\r
-        return s->readh;\r
-    else\r
-    {\r
-        ret = omap3_wdt_read32(opaque, addr, OMAP3_MPU_WDT);\r
-        s->readh = ret >> 16;\r
-        return ret & 0xffff;\r
-    }\r
-}\r
-static uint32_t omap3_mpu_wdt_read32(void *opaque, target_phys_addr_t addr)\r
-{\r
-    return omap3_wdt_read32(opaque, addr, OMAP3_MPU_WDT);\r
-}\r
-\r
-static void omap3_wdt_write32(void *opaque, target_phys_addr_t addr,\r
-                              uint32_t value, int wdt_index)\r
-{\r
-    struct omap3_wdt_s *s = (struct omap3_wdt_s *) opaque;\r
-\r
-    //printf("omap3_wdt_write32 addr %x value %x \n",addr,value);\r
-    switch (addr)\r
-    {\r
-    case 0x14:                 /*WD_SYSSTATUS */\r
-    case 0x34:\r
-         /*WWPS*/ OMAP_RO_REG(addr);\r
-        exit(-1);\r
-        break;\r
-    case 0x10:                 /*WD_SYSCONFIG */\r
-        s->wd_sysconfig = value & 0x33f;\r
-        break;\r
-    case 0x18:\r
-         /*WISR*/ s->wisr = value & 0x1;\r
-        break;\r
-    case 0x1c:\r
-         /*WIER*/ s->wier = value & 0x1;\r
-        break;\r
-    case 0x24:\r
-         /*WCLR*/ s->wclr = value & 0x3c;\r
-        break;\r
-    case 0x28:\r
-         /*WCRR*/ s->wcrr = value;\r
-        s->time = qemu_get_clock(vm_clock);\r
-        omap3_wdt_timer_update(s);\r
-        break;\r
-    case 0x2c:\r
-         /*WLDR*/ s->wldr = value;      /*It will take effect after next overflow */\r
-        break;\r
-    case 0x30:\r
-         /*WTGR*/ if (value != s->wtgr)\r
-        {\r
-            s->wcrr = s->wldr;\r
-            s->pre = s->wclr & (1 << 5);\r
-            s->ptv = (s->wclr & 0x1c) >> 2;\r
-            s->rate = omap_clk_getrate(s->clk) >> (s->pre ? s->ptv : 0);\r
-            s->time = qemu_get_clock(vm_clock);\r
-            omap3_wdt_timer_update(s);\r
-        }\r
-        s->wtgr = value;\r
-        break;\r
-    case 0x48:\r
-         /*WSPR*/\r
-            if (((value & 0xffff) == 0x5555) && ((s->wspr & 0xffff) == 0xaaaa))\r
-        {\r
-            s->active = 0;\r
-            s->wcrr = omap3_wdt_timer_read(s);\r
-            omap3_wdt_timer_update(s);\r
-        }\r
-        if (((value & 0xffff) == 0x4444) && ((s->wspr & 0xffff) == 0xbbbb))\r
-        {\r
-            s->active = 1;\r
-            s->time = qemu_get_clock(vm_clock);\r
-            omap3_wdt_timer_update(s);\r
-        }\r
-        s->wspr = value;\r
-        break;\r
-    default:\r
-        printf("omap3_wdt_write32 addr %x \n", addr);\r
-        exit(-1);\r
-    }\r
-}\r
-\r
-static void omap3_mpu_wdt_write16(void *opaque, target_phys_addr_t addr,\r
-                                  uint32_t value)\r
-{\r
-    struct omap3_wdt_s *s = (struct omap3_wdt_s *) opaque;\r
-\r
-    if (addr & 2)\r
-        return omap3_wdt_write32(opaque, addr, (value << 16) | s->writeh,\r
-                                 OMAP3_MPU_WDT);\r
-    else\r
-        s->writeh = (uint16_t) value;\r
-}\r
-static void omap3_mpu_wdt_write32(void *opaque, target_phys_addr_t addr,\r
-                                  uint32_t value)\r
-{\r
-    omap3_wdt_write32(opaque, addr, value, OMAP3_MPU_WDT);\r
-}\r
-\r
-\r
-static CPUReadMemoryFunc *omap3_mpu_wdt_readfn[] = {\r
-    omap_badwidth_read32,\r
-    omap3_mpu_wdt_read16,\r
-    omap3_mpu_wdt_read32,\r
-};\r
-\r
-static CPUWriteMemoryFunc *omap3_mpu_wdt_writefn[] = {\r
-    omap_badwidth_write32,\r
-    omap3_mpu_wdt_write16,\r
-    omap3_mpu_wdt_write32,\r
-};\r
-\r
-\r
-\r
-static void omap3_mpu_wdt_timer_tick(void *opaque)\r
-{\r
-    struct omap3_wdt_s *wdt_timer = (struct omap3_wdt_s *) opaque;\r
-\r
-    /*TODO:Sent reset pulse to PRCM */\r
-    wdt_timer->wcrr = wdt_timer->wldr;\r
-\r
-    /*after overflow, generate the new wdt_timer->rate */\r
-    wdt_timer->pre = wdt_timer->wclr & (1 << 5);\r
-    wdt_timer->ptv = (wdt_timer->wclr & 0x1c) >> 2;\r
-    wdt_timer->rate =\r
-        omap_clk_getrate(wdt_timer->clk) >> (wdt_timer->pre ? wdt_timer->\r
-                                             ptv : 0);\r
-\r
-    wdt_timer->time = qemu_get_clock(vm_clock);\r
-    omap3_wdt_timer_update(wdt_timer);\r
-}\r
-\r
-static struct omap3_wdt_s *omap3_mpu_wdt_init(struct omap_target_agent_s *ta,\r
-                                              qemu_irq irq, omap_clk fclk,\r
-                                              omap_clk iclk,\r
-                                              struct omap_mpu_state_s *mpu)\r
-{\r
-    int iomemtype;\r
-    struct omap3_wdt_s *s = (struct omap3_wdt_s *) qemu_mallocz(sizeof(*s));\r
-\r
-    s->irq = irq;\r
-    s->clk = fclk;\r
-    s->timer = qemu_new_timer(vm_clock, omap3_mpu_wdt_timer_tick, s);\r
-\r
-    omap3_wdt_reset(s, OMAP3_MPU_WDT);\r
-    if (irq != NULL)\r
-        omap3_wdt_clk_setup(s);\r
-\r
-    iomemtype = l4_register_io_memory(0, omap3_mpu_wdt_readfn,\r
-                                      omap3_mpu_wdt_writefn, s);\r
-    omap_l4_attach(ta, 0, iomemtype);\r
-\r
-    return s;\r
-\r
-}\r
-\r
-\r
-/*dummy system control module*/\r
-struct omap3_scm_s\r
-{\r
-    struct omap_mpu_state_s *mpu;\r
-\r
-       uint8 interface[48];           /*0x4800 2000*/\r
-       uint8 padconfs[576];         /*0x4800 2030*/\r
-       uint32 general[228];            /*0x4800 2270*/\r
-       uint8 mem_wkup[1024];     /*0x4800 2600*/\r
-       uint8 padconfs_wkup[84]; /*0x4800 2a00*/\r
-       uint32 general_wkup[8];    /*0x4800 2a60*/\r
-};\r
-\r
-#define PADCONFS_VALUE(wakeup0,wakeup1,offmode0,offmode1, \\r
-                                               inputenable0,inputenable1,pupd0,pupd1,muxmode0,muxmode1,offset) \\r
-       do { \\r
-                *(padconfs+offset/4) = (wakeup0 <<14)|(offmode0<<9)|(inputenable0<<8)|(pupd0<<3)|(muxmode0); \\r
-                *(padconfs+offset/4) |= (wakeup1 <<30)|(offmode1<<25)|(inputenable1<<24)|(pupd1<<19)|(muxmode1<<16); \\r
-} while (0)\r
-\r
-\r
-static void omap3_scm_reset(struct omap3_scm_s *s)\r
-{\r
-        uint32 * padconfs;\r
-    padconfs = (uint32 *)(s->padconfs);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x0);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x4);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x8);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0xc);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x10);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x14);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x18);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x1c);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x20);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x24);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x28);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x2c);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x30);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x34);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x38);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x3c);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x40);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x44);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,0,1,0,7,0x48);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x4c);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x50);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x54);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x58);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,0,0x5c);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x60);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x64);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x68);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x6c);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x70);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x74);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x78);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x7c);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,0,3,0,7,0x80);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x84);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x88);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,3,0,7,0,0x8c);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x90);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x94);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,0,7,0,0x98);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,7,0x9c);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0xa0);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0xa4);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0xa8);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xac);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xb0);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xb4);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xb8);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xbc);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xc0);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xc4);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xc8);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xcc);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xd0);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xd4);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xd8);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xdc);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xe0);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xe4);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xe8);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xec);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xf0);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xf4);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xf8);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xfc);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x100);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x104);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x108);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x10c);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x110);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x114);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x118);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x11c);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x120);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x124);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,3,7,7,0x128);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x12c);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x130);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x134);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x138);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x13c);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x140);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x144);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x148);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x14c);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x150);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x154);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x158);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x15c);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x160);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x164);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,3,7,7,0x168);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x16c);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0x170);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0x174);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x178);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x17c);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x180);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x184);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,3,7,7,0x188);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x18c);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x190);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x194);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x198);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,3,7,7,0x19c);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x1a0);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0x1a4);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x1a8);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0x1ac);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0x1b0);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1b4);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1b8);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1bc);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1c0);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1c4);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1c8);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1cc);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1d0);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1d4);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1d8);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1dc);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1e0);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1e4);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1e8);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1ec);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1f0);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1f4);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1f8);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1fc);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x200);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x204);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x208);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x20c);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x210);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x214);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x218);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x21c);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x220);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,3,1,0,0,0x224);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,0,1,0,0,0x228);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,0,1,0,0,0x22c);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x230);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x234);\r
-\r
-\r
-       padconfs = (uint32 *)(s->general);\r
-       s->general[1] = 0x4000000;  /*0x4800 2274*/\r
-       s->general[0x1c] = 0x1;  /*0x4800 22e0*/\r
-       s->general[0x75] = 0x7fc0;  /*0x4800 2444*/\r
-       s->general[0x76] = 0xaa;  /*0x4800 2448*/\r
-       s->general[0x7c] = 0x2700;  /*0x4800 2460*/\r
-       s->general[0x7d] = 0x300000;  /*0x4800 2464*/\r
-       s->general[0x7e] = 0x300000;  /*0x4800 2468*/\r
-       s->general[0x81] = 0xffff;  /*0x4800 2474*/\r
-       s->general[0x82] = 0xffff;  /*0x4800 2478*/\r
-       s->general[0x83] = 0xffff;  /*0x4800 247c*/\r
-       s->general[0x84] = 0x6;  /*0x4800 2480*/\r
-       s->general[0x85] = 0xffffffff;  /*0x4800 2484*/\r
-       s->general[0x86] = 0xffff;  /*0x4800 2488*/\r
-       s->general[0x87] = 0xffff;  /*0x4800 248c*/\r
-       s->general[0x88] = 0x1;  /*0x4800 2490*/\r
-       s->general[0x8b] = 0xffffffff;  /*0x4800 249c*/\r
-       s->general[0x8c] = 0xffff;  /*0x4800 24a0*/\r
-       s->general[0x8e] = 0xffff;  /*0x4800 24a8*/\r
-       s->general[0x8f] = 0xffff;  /*0x4800 24ac*/\r
-       s->general[0x91] = 0xffff;  /*0x4800 24b4*/\r
-       s->general[0x92] = 0xffff;  /*0x4800 24b8*/\r
-       s->general[0xac] = 0x109;  /*0x4800 2520*/\r
-       s->general[0xb2] = 0xffff;  /*0x4800 2538*/\r
-       s->general[0xb3] = 0xffff;  /*0x4800 253c*/\r
-       s->general[0xb4] = 0xffff;  /*0x4800 2540*/\r
-       PADCONFS_VALUE(0,0,0,0,1,1,3,3,4,4,0x368);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,3,3,4,4,0x36c);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,3,3,4,4,0x370);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x374);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x378);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x37c);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x380);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x384);\r
-    PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x388);\r
-\r
-    \r
-\r
-       padconfs = (uint32 *)(s->padconfs_wkup);\r
-       PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x0);\r
-       PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x4);\r
-       PADCONFS_VALUE(0,0,0,0,1,1,3,0,0,0,0x8);\r
-       PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0xc);\r
-       PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x10);\r
-       PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x14);\r
-       PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x18);\r
-       PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1c);\r
-       PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x20);\r
-       PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x24);\r
-       PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x2c);\r
-\r
-\r
-       s->general_wkup[0] = 0x66ff; /*0x4800 2A60*/\r
-           \r
-}\r
-\r
-static uint32_t omap3_scm_read8(void *opaque, target_phys_addr_t addr)\r
-{\r
-    struct omap3_scm_s *s = (struct omap3_scm_s *) opaque;\r
-    uint8_t* temp;\r
-       \r
-    switch (addr) {\r
-    case 0x00 ... 0x2f:\r
-        return s->interface[addr];\r
-    case 0x30 ... 0x26f:\r
-        return s->padconfs[addr-0x30];\r
-    case 0x270 ... 0x5ff:\r
-        temp = (uint8_t *)s->general;\r
-        return temp[addr-0x270];\r
-    case 0x600 ... 0x9ff:\r
-        return s->mem_wkup[addr-0x600];\r
-    case 0xa00 ... 0xa5f:\r
-        return s->padconfs_wkup[addr-0xa00];\r
-    case 0xa60 ... 0xa7f:\r
-        temp = (uint8_t *)s->general_wkup;\r
-        return temp[addr-0xa60];\r
-    /* case 0x2f0:\r
-        return s->control_status & 0xff;\r
-    case 0x2f1:\r
-        return (s->control_status & 0xff00) >> 8;\r
-    case 0x2f2:\r
-        return (s->control_status & 0xff0000) >> 16;\r
-    case 0x2f3:\r
-        return (s->control_status & 0xff000000) >> 24;    */\r
-       \r
-    default:\r
-        break;\r
-    }\r
-    printf("omap3_scm_read8 addr %x pc %x  \n", addr,cpu_single_env->regs[15] );\r
-    return 0;\r
-}\r
-\r
-static uint32_t omap3_scm_read16(void *opaque, target_phys_addr_t addr)\r
-{\r
-    uint32_t v;\r
-    v = omap3_scm_read8(opaque, addr);\r
-    v |= omap3_scm_read8(opaque, addr + 1) << 8;\r
-    return v;\r
-}\r
-\r
-static uint32_t omap3_scm_read32(void *opaque, target_phys_addr_t addr)\r
-{\r
-    uint32_t v;\r
-    v = omap3_scm_read8(opaque, addr);\r
-    v |= omap3_scm_read8(opaque, addr + 1) << 8;\r
-    v |= omap3_scm_read8(opaque, addr + 2) << 16;\r
-    v |= omap3_scm_read8(opaque, addr + 3) << 24;\r
-    return v;\r
-}\r
-\r
-static void omap3_scm_write8(void *opaque, target_phys_addr_t addr,\r
-                             uint32_t value)\r
-{\r
-    struct omap3_scm_s *s = (struct omap3_scm_s *) opaque;\r
-    uint8_t* temp;\r
-\r
-    switch (addr)\r
-    {\r
-    case 0x00 ... 0x2f:\r
-        s->interface[addr] = value;\r
-        break;\r
-    case 0x30 ... 0x26f:\r
-        s->padconfs[addr-0x30] = value;\r
-        break;\r
-    case 0x270 ... 0x5ff:\r
-        temp = (uint8_t *)s->general;\r
-        temp[addr-0x270] = value;\r
-        break;\r
-    case 0x600 ... 0x9ff:\r
-        s->mem_wkup[addr-0x600] = value;\r
-        break;\r
-    case 0xa00 ... 0xa5f:\r
-        s->padconfs_wkup[addr-0xa00] = value;\r
-        break;\r
-    case 0xa60 ... 0xa7f:\r
-        temp = (uint8_t *)s->general_wkup;\r
-        temp[addr-0xa60] = value;\r
-        break;\r
-    default:\r
-        /*we do not care scm write*/\r
-        printf("omap3_scm_write8 addr %x pc %x \n \n", addr,\r
-               cpu_single_env->regs[15] - 0x80008000 + 0x80e80000);\r
-        exit(1);\r
-        //break;\r
-    }\r
-}\r
-\r
-static void omap3_scm_write16(void *opaque, target_phys_addr_t addr,\r
-                              uint32_t value)\r
-{\r
-    omap3_scm_write8(opaque, addr + 0, (value) & 0xff);\r
-    omap3_scm_write8(opaque, addr + 1, (value >> 8) & 0xff);\r
-}\r
-\r
-static void omap3_scm_write32(void *opaque, target_phys_addr_t addr,\r
-                              uint32_t value)\r
-{\r
-    omap3_scm_write8(opaque, addr + 0, (value) & 0xff);\r
-    omap3_scm_write8(opaque, addr + 1, (value >> 8) & 0xff);\r
-    omap3_scm_write8(opaque, addr + 2, (value >> 16) & 0xff);\r
-    omap3_scm_write8(opaque, addr + 3, (value >> 24) & 0xff);\r
-}\r
-\r
-static CPUReadMemoryFunc *omap3_scm_readfn[] = {\r
-    omap3_scm_read8,\r
-    omap3_scm_read16,\r
-    omap3_scm_read32,\r
-};\r
-\r
-static CPUWriteMemoryFunc *omap3_scm_writefn[] = {\r
-    omap3_scm_write8,\r
-    omap3_scm_write16,\r
-    omap3_scm_write32,\r
-};\r
-\r
-static struct omap3_scm_s *omap3_scm_init(struct omap_target_agent_s *ta,\r
-                                          struct omap_mpu_state_s *mpu)\r
-{\r
-    int iomemtype;\r
-    struct omap3_scm_s *s = (struct omap3_scm_s *) qemu_mallocz(sizeof(*s));\r
-\r
-    s->mpu = mpu;\r
-\r
-    omap3_scm_reset(s);\r
-\r
-    iomemtype = l4_register_io_memory(0, omap3_scm_readfn,\r
-                                      omap3_scm_writefn, s);\r
-    omap_l4_attach(ta, 0, iomemtype);\r
-    \r
-    return s;\r
-}\r
-\r
-\r
-/*dummy port protection*/\r
-struct omap3_pm_s\r
-{\r
-    struct omap_mpu_state_s *mpu;\r
-\r
-    uint32_t l3_pm_rt_error_log;        /*0x6801 0020 */\r
-    uint32_t l3_pm_rt_control;  /*0x6801 0028 */\r
-    uint32_t l3_pm_rt_error_clear_single;       /*0x6801 0030 */\r
-    uint32_t l3_pm_rt_error_clear_multi;        /*0x6801 0038 */\r
-    uint32_t l3_pm_rt_req_info_permission[2];   /*0x6801 0048 + (0x20*i) */\r
-    uint32_t l3_pm_rt_read_permission[2];       /*0x6801 0050 + (0x20*i) */\r
-    uint32_t l3_pm_rt_write_permission[2];      /*0x6801 0058 + (0x20*i) */\r
-    uint32_t l3_pm_rt_addr_match[1];    /*0x6801 0060 + (0x20*k) */\r
-\r
-    uint32_t l3_pm_gpmc_error_log;      /*0x6801 2420 */\r
-    uint32_t l3_pm_gpmc_control;        /*0x6801 2428 */\r
-    uint32_t l3_pm_gpmc_error_clear_single;     /*0x6801 2430 */\r
-    uint32_t l3_pm_gpmc_error_clear_multi;      /*0x6801 2438 */\r
-    uint32_t l3_pm_gpmc_req_info_permission[8]; /*0x6801 2448 + (0x20*i) */\r
-    uint32_t l3_pm_gpmc_read_permission[8];     /*0x6801 2450 + (0x20*i) */\r
-    uint32_t l3_pm_gpmc_write_permission[8];    /*0x6801 2458 + (0x20*i) */\r
-    uint32_t l3_pm_gpmc_addr_match[7];  /*0x6801 2460 + (0x20*k) */\r
-\r
-    uint32_t l3_pm_ocmram_error_log;    /*0x6801 2820 */\r
-    uint32_t l3_pm_ocmram_control;      /*0x6801 2828 */\r
-    uint32_t l3_pm_ocmram_error_clear_single;   /*0x6801 2830 */\r
-    uint32_t l3_pm_ocmram_error_clear_multi;    /*0x6801 2838 */\r
-    uint32_t l3_pm_ocmram_req_info_permission[8];       /*0x6801 2848 + (0x20*i) */\r
-    uint32_t l3_pm_ocmram_read_permission[8];   /*0x6801 2850 + (0x20*i) */\r
-    uint32_t l3_pm_ocmram_write_permission[8];  /*0x6801 2858 + (0x20*i) */\r
-    uint32_t l3_pm_ocmram_addr_match[7];        /*0x6801 2860 + (0x20*k) */\r
-\r
-    uint32_t l3_pm_ocmrom_error_log;    /*0x6801 2c20 */\r
-    uint32_t l3_pm_ocmrom_control;      /*0x6801 2c28 */\r
-    uint32_t l3_pm_ocmrom_error_clear_single;   /*0x6801 2c30 */\r
-    uint32_t l3_pm_ocmrom_error_clear_multi;    /*0x6801 2c38 */\r
-    uint32_t l3_pm_ocmrom_req_info_permission[2];       /*0x6801 2c48 + (0x20*i) */\r
-    uint32_t l3_pm_ocmrom_read_permission[2];   /*0x6801 2c50 + (0x20*i) */\r
-    uint32_t l3_pm_ocmrom_write_permission[2];  /*0x6801 2c58 + (0x20*i) */\r
-    uint32_t l3_pm_ocmrom_addr_match[1];        /*0x6801 2c60 + (0x20*k) */\r
-\r
-    uint32_t l3_pm_mad2d_error_log;     /*0x6801 3020 */\r
-    uint32_t l3_pm_mad2d_control;       /*0x6801 3028 */\r
-    uint32_t l3_pm_mad2d_error_clear_single;    /*0x6801 3030 */\r
-    uint32_t l3_pm_mad2d_error_clear_multi;     /*0x6801 3038 */\r
-    uint32_t l3_pm_mad2d_req_info_permission[8];        /*0x6801 3048 + (0x20*i) */\r
-    uint32_t l3_pm_mad2d_read_permission[8];    /*0x6801 3050 + (0x20*i) */\r
-    uint32_t l3_pm_mad2d_write_permission[8];   /*0x6801 3058 + (0x20*i) */\r
-    uint32_t l3_pm_mad2d_addr_match[7]; /*0x6801 3060 + (0x20*k) */\r
-\r
-    uint32_t l3_pm_iva_error_log;       /*0x6801 4020 */\r
-    uint32_t l3_pm_iva_control; /*0x6801 4028 */\r
-    uint32_t l3_pm_iva_error_clear_single;      /*0x6801 4030 */\r
-    uint32_t l3_pm_iva_error_clear_multi;       /*0x6801 4038 */\r
-    uint32_t l3_pm_iva_req_info_permission[4];  /*0x6801 4048 + (0x20*i) */\r
-    uint32_t l3_pm_iva_read_permission[4];      /*0x6801 4050 + (0x20*i) */\r
-    uint32_t l3_pm_iva_write_permission[4];     /*0x6801 4058 + (0x20*i) */\r
-    uint32_t l3_pm_iva_addr_match[3];   /*0x6801 4060 + (0x20*k) */\r
-};\r
-\r
-static void omap3_pm_reset(struct omap3_pm_s *s)\r
-{\r
-    int i;\r
-\r
-    s->l3_pm_rt_control = 0x3000000;\r
-    s->l3_pm_gpmc_control = 0x3000000;\r
-    s->l3_pm_ocmram_control = 0x3000000;\r
-    s->l3_pm_ocmrom_control = 0x3000000;\r
-    s->l3_pm_mad2d_control = 0x3000000;\r
-    s->l3_pm_iva_control = 0x3000000;\r
-\r
-    s->l3_pm_rt_req_info_permission[0] = 0xffff;\r
-    s->l3_pm_rt_req_info_permission[1] = 0x0;\r
-    for (i = 3; i < 8; i++)\r
-        s->l3_pm_gpmc_req_info_permission[i] = 0xffff;\r
-    for (i = 1; i < 8; i++)\r
-        s->l3_pm_ocmram_req_info_permission[i] = 0xffff;\r
-    s->l3_pm_ocmrom_req_info_permission[1] = 0xffff;\r
-    for (i = 1; i < 8; i++)\r
-        s->l3_pm_mad2d_req_info_permission[i] = 0xffff;\r
-    for (i = 1; i < 4; i++)\r
-        s->l3_pm_iva_req_info_permission[i] = 0xffff;\r
-\r
-    s->l3_pm_rt_read_permission[0] = 0x1406;\r
-    s->l3_pm_rt_read_permission[1] = 0x1406;\r
-    s->l3_pm_rt_write_permission[0] = 0x1406;\r
-    s->l3_pm_rt_write_permission[1] = 0x1406;\r
-    for (i = 0; i < 8; i++)\r
-    {\r
-        s->l3_pm_gpmc_read_permission[i] = 0x563e;\r
-        s->l3_pm_gpmc_write_permission[i] = 0x563e;\r
-    }\r
-    for (i = 0; i < 8; i++)\r
-    {\r
-        s->l3_pm_ocmram_read_permission[i] = 0x5f3e;\r
-        s->l3_pm_ocmram_write_permission[i] = 0x5f3e;\r
-    }\r
-    for (i = 0; i < 2; i++)\r
-    {\r
-        s->l3_pm_ocmrom_read_permission[i] = 0x1002;\r
-        s->l3_pm_ocmrom_write_permission[i] = 0x1002;\r
-    }\r
-\r
-    for (i = 0; i < 8; i++)\r
-    {\r
-        s->l3_pm_mad2d_read_permission[i] = 0x5f1e;\r
-        s->l3_pm_mad2d_write_permission[i] = 0x5f1e;\r
-    }\r
-\r
-    for (i = 0; i < 4; i++)\r
-    {\r
-        s->l3_pm_iva_read_permission[i] = 0x140e;\r
-        s->l3_pm_iva_write_permission[i] = 0x140e;\r
-    }\r
-\r
-\r
-    s->l3_pm_rt_addr_match[0] = 0x10230;\r
-\r
-    s->l3_pm_gpmc_addr_match[0] = 0x10230;\r
-}\r
-\r
-static uint32_t omap3_pm_read8(void *opaque, target_phys_addr_t addr)\r
-{\r
-    //struct omap3_pm_s *s = (struct omap3_pm_s *) opaque;\r
-\r
-    switch (addr)\r
-    {\r
-    default:\r
-        printf("omap3_pm_read8 addr %x \n", addr);\r
-        exit(-1);\r
-    }\r
-}\r
-\r
-static uint32_t omap3_pm_read16(void *opaque, target_phys_addr_t addr)\r
-{\r
-    uint32_t v;\r
-    v = omap3_pm_read8(opaque, addr);\r
-    v |= omap3_pm_read8(opaque, addr + 1) << 8;\r
-    return v;\r
-}\r
-\r
-static uint32_t omap3_pm_read32(void *opaque, target_phys_addr_t addr)\r
-{\r
-    uint32_t v;\r
-    v = omap3_pm_read8(opaque, addr);\r
-    v |= omap3_pm_read8(opaque, addr + 1) << 8;\r
-    v |= omap3_pm_read8(opaque, addr + 2) << 16;\r
-    v |= omap3_pm_read8(opaque, addr + 3) << 24;\r
-    return v;\r
-}\r
-\r
-static void omap3_pm_write8(void *opaque, target_phys_addr_t addr,\r
-                            uint32_t value)\r
-{\r
-    struct omap3_pm_s *s = (struct omap3_pm_s *) opaque;\r
-    int i;\r
-\r
-    switch (addr)\r
-    {\r
-    case 0x48 ... 0x4b:\r
-    case 0x68 ... 0x6b:\r
-        i = (addr - 0x48) / 0x20;\r
-        s->l3_pm_rt_req_info_permission[i] &=\r
-            (~(0xff << ((addr - 0x48 - i * 0x20) * 8)));\r
-        s->l3_pm_rt_req_info_permission[i] |=\r
-            (value << (addr - 0x48 - i * 0x20) * 8);\r
-        break;\r
-    case 0x50 ... 0x53:\r
-    case 0x70 ... 0x73:\r
-        i = (addr - 0x50) / 0x20;\r
-        s->l3_pm_rt_read_permission[i] &=\r
-            (~(0xff << ((addr - 0x50 - i * 0x20) * 8)));\r
-        s->l3_pm_rt_read_permission[i] |=\r
-            (value << (addr - 0x50 - i * 0x20) * 8);\r
-        break;\r
-    case 0x58 ... 0x5b:\r
-    case 0x78 ... 0x7b:\r
-        i = (addr - 0x58) / 0x20;\r
-        s->l3_pm_rt_write_permission[i] &=\r
-            (~(0xff << ((addr - 0x58 - i * 0x20) * 8)));\r
-        s->l3_pm_rt_write_permission[i] |=\r
-            (value << (addr - 0x58 - i * 0x20) * 8);\r
-        break;\r
-    case 0x60 ... 0x63:\r
-        s->l3_pm_rt_addr_match[0] &= (~(0xff << ((addr - 0x60) * 8)));\r
-        s->l3_pm_rt_addr_match[0] |= (value << (addr - 0x60) * 8);\r
-        break;\r
-    case 0x2448 ... 0x244b:\r
-    case 0x2468 ... 0x246b:\r
-    case 0x2488 ... 0x248b:\r
-    case 0x24a8 ... 0x24ab:\r
-    case 0x24c8 ... 0x24cb:\r
-    case 0x24e8 ... 0x24eb:\r
-    case 0x2508 ... 0x250b:\r
-    case 0x2528 ... 0x252b:\r
-        i = (addr - 0x2448) / 0x20;\r
-        s->l3_pm_gpmc_req_info_permission[i] &=\r
-            (~(0xff << ((addr - 0x2448 - i * 0x20) * 8)));\r
-        s->l3_pm_gpmc_req_info_permission[i] |=\r
-            (value << (addr - 0x2448 - i * 0x20) * 8);\r
-        break;\r
-    case 0x2450 ... 0x2453:\r
-    case 0x2470 ... 0x2473:\r
-    case 0x2490 ... 0x2493:\r
-    case 0x24b0 ... 0x24b3:\r
-    case 0x24d0 ... 0x24d3:\r
-    case 0x24f0 ... 0x24f3:\r
-    case 0x2510 ... 0x2513:\r
-    case 0x2530 ... 0x2533:\r
-        i = (addr - 0x2450) / 0x20;\r
-        s->l3_pm_gpmc_read_permission[i] &=\r
-            (~(0xff << ((addr - 0x2450 - i * 0x20) * 8)));\r
-        s->l3_pm_gpmc_read_permission[i] |=\r
-            (value << (addr - 0x2450 - i * 0x20) * 8);\r
-        break;\r
-    case 0x2458 ... 0x245b:\r
-    case 0x2478 ... 0x247b:\r
-    case 0x2498 ... 0x249b:\r
-    case 0x24b8 ... 0x24bb:\r
-    case 0x24d8 ... 0x24db:\r
-    case 0x24f8 ... 0x24fb:\r
-    case 0x2518 ... 0x251b:\r
-    case 0x2538 ... 0x253b:\r
-        i = (addr - 0x2458) / 0x20;\r
-        s->l3_pm_gpmc_write_permission[i] &=\r
-            (~(0xff << ((addr - 0x2458 - i * 0x20) * 8)));\r
-        s->l3_pm_gpmc_write_permission[i] |=\r
-            (value << (addr - 0x2458 - i * 0x20) * 8);\r
-        break;\r
-    case 0x2848 ... 0x284b:\r
-    case 0x2868 ... 0x286b:\r
-    case 0x2888 ... 0x288b:\r
-    case 0x28a8 ... 0x28ab:\r
-    case 0x28c8 ... 0x28cb:\r
-    case 0x28e8 ... 0x28eb:\r
-    case 0x2908 ... 0x290b:\r
-    case 0x2928 ... 0x292b:\r
-        i = (addr - 0x2848) / 0x20;\r
-        s->l3_pm_ocmram_req_info_permission[i] &=\r
-            (~(0xff << ((addr - 0x2848 - i * 0x20) * 8)));\r
-        s->l3_pm_ocmram_req_info_permission[i] |=\r
-            (value << (addr - 0x2848 - i * 0x20) * 8);\r
-        break;\r
-    case 0x2850 ... 0x2853:\r
-    case 0x2870 ... 0x2873:\r
-    case 0x2890 ... 0x2893:\r
-    case 0x28b0 ... 0x28b3:\r
-    case 0x28d0 ... 0x28d3:\r
-    case 0x28f0 ... 0x28f3:\r
-    case 0x2910 ... 0x2913:\r
-    case 0x2930 ... 0x2933:\r
-        i = (addr - 0x2850) / 0x20;\r
-        s->l3_pm_ocmram_read_permission[i] &=\r
-            (~(0xff << ((addr - 0x2850 - i * 0x20) * 8)));\r
-        s->l3_pm_ocmram_read_permission[i] |=\r
-            (value << (addr - 0x2850 - i * 0x20) * 8);\r
-        break;\r
-    case 0x2858 ... 0x285b:\r
-    case 0x2878 ... 0x287b:\r
-    case 0x2898 ... 0x289b:\r
-    case 0x28b8 ... 0x28bb:\r
-    case 0x28d8 ... 0x28db:\r
-    case 0x28f8 ... 0x28fb:\r
-    case 0x2918 ... 0x291b:\r
-    case 0x2938 ... 0x293b:\r
-        i = (addr - 0x2858) / 0x20;\r
-        s->l3_pm_ocmram_write_permission[i] &=\r
-            (~(0xff << ((addr - 0x2858 - i * 0x20) * 8)));\r
-        s->l3_pm_ocmram_write_permission[i] |=\r
-            (value << (addr - 0x2858 - i * 0x20) * 8);\r
-        break;\r
-\r
-    case 0x2860 ... 0x2863:\r
-    case 0x2880 ... 0x2883:\r
-    case 0x28a0 ... 0x28a3:\r
-    case 0x28c0 ... 0x28c3:\r
-    case 0x28e0 ... 0x28e3:\r
-    case 0x2900 ... 0x2903:\r
-    case 0x2920 ... 0x2923:\r
-        i = (addr - 0x2860) / 0x20;\r
-        s->l3_pm_ocmram_addr_match[i] &=\r
-            (~(0xff << ((addr - 0x2860 - i * 0x20) * 8)));\r
-        s->l3_pm_ocmram_addr_match[i] |=\r
-            (value << (addr - 0x2860 - i * 0x20) * 8);\r
-        break;\r
-\r
-    case 0x4048 ... 0x404b:\r
-    case 0x4068 ... 0x406b:\r
-    case 0x4088 ... 0x408b:\r
-    case 0x40a8 ... 0x40ab:\r
-        i = (addr - 0x4048) / 0x20;\r
-        s->l3_pm_iva_req_info_permission[i] &=\r
-            (~(0xff << ((addr - 0x4048 - i * 0x20) * 8)));\r
-        s->l3_pm_iva_req_info_permission[i] |=\r
-            (value << (addr - 0x4048 - i * 0x20) * 8);\r
-        break;\r
-    case 0x4050 ... 0x4053:\r
-    case 0x4070 ... 0x4073:\r
-    case 0x4090 ... 0x4093:\r
-    case 0x40b0 ... 0x40b3:\r
-        i = (addr - 0x4050) / 0x20;\r
-        s->l3_pm_iva_read_permission[i] &=\r
-            (~(0xff << ((addr - 0x4050 - i * 0x20) * 8)));\r
-        s->l3_pm_iva_read_permission[i] |=\r
-            (value << (addr - 0x4050 - i * 0x20) * 8);\r
-        break;\r
-    case 0x4058 ... 0x405b:\r
-    case 0x4078 ... 0x407b:\r
-    case 0x4098 ... 0x409b:\r
-    case 0x40b8 ... 0x40bb:\r
-        i = (addr - 0x4058) / 0x20;\r
-        s->l3_pm_iva_write_permission[i] &=\r
-            (~(0xff << ((addr - 0x4058 - i * 0x20) * 8)));\r
-        s->l3_pm_iva_write_permission[i] |=\r
-            (value << (addr - 0x4058 - i * 0x20) * 8);\r
-        break;\r
-    default:\r
-        printf("omap3_pm_write8 addr %x \n", addr);\r
-        exit(-1);\r
-    }\r
-}\r
-\r
-static void omap3_pm_write16(void *opaque, target_phys_addr_t addr,\r
-                             uint32_t value)\r
-{\r
-    omap3_pm_write8(opaque, addr + 0, (value) & 0xff);\r
-    omap3_pm_write8(opaque, addr + 1, (value >> 8) & 0xff);\r
-}\r
-\r
-static void omap3_pm_write32(void *opaque, target_phys_addr_t addr,\r
-                             uint32_t value)\r
-{\r
-    omap3_pm_write8(opaque, addr + 0, (value) & 0xff);\r
-    omap3_pm_write8(opaque, addr + 1, (value >> 8) & 0xff);\r
-    omap3_pm_write8(opaque, addr + 2, (value >> 16) & 0xff);\r
-    omap3_pm_write8(opaque, addr + 3, (value >> 24) & 0xff);\r
-}\r
-\r
-static CPUReadMemoryFunc *omap3_pm_readfn[] = {\r
-    omap3_pm_read8,\r
-    omap3_pm_read16,\r
-    omap3_pm_read32,\r
-};\r
-\r
-static CPUWriteMemoryFunc *omap3_pm_writefn[] = {\r
-    omap3_pm_write8,\r
-    omap3_pm_write16,\r
-    omap3_pm_write32,\r
-};\r
-\r
-static struct omap3_pm_s *omap3_pm_init(struct omap_mpu_state_s *mpu)\r
-{\r
-    int iomemtype;\r
-    struct omap3_pm_s *s = (struct omap3_pm_s *) qemu_mallocz(sizeof(*s));\r
-\r
-    s->mpu = mpu;\r
-    //s->base = 0x68010000;\r
-    //s->size = 0x4400;\r
-\r
-    omap3_pm_reset(s);\r
-\r
-    iomemtype = cpu_register_io_memory(0, omap3_pm_readfn, omap3_pm_writefn, s);\r
-    cpu_register_physical_memory(0x68010000, 0x4400, iomemtype);\r
-\r
-    return s;\r
-}\r
-\r
-/*dummy SDRAM Memory Scheduler emulation*/\r
-struct omap3_sms_s\r
-{\r
-    struct omap_mpu_state_s *mpu;\r
-\r
-    uint32 sms_sysconfig;\r
-    uint32 sms_sysstatus;\r
-    uint32 sms_rg_att[8];\r
-    uint32 sms_rg_rdperm[8];\r
-    uint32 sms_rg_wrperm[8];\r
-    uint32 sms_rg_start[7];\r
-    uint32 sms_rg_end[7];\r
-    uint32 sms_security_control;\r
-    uint32 sms_class_arbiter0;\r
-    uint32 sms_class_arbiter1;\r
-    uint32 sms_class_arbiter2;\r
-    uint32 sms_interclass_arbiter;\r
-    uint32 sms_class_rotation[3];\r
-    uint32 sms_err_addr;\r
-    uint32 sms_err_type;\r
-    uint32 sms_pow_ctrl;\r
-    uint32 sms_rot_control[12];\r
-    uint32 sms_rot_size[12];\r
-    uint32 sms_rot_physical_ba[12];\r
-\r
-\r
-};\r
-\r
-static uint32_t omap3_sms_read32(void *opaque, target_phys_addr_t addr)\r
-{\r
-    struct omap3_sms_s *s = (struct omap3_sms_s *) opaque;\r
-\r
-    switch (addr)\r
-    {\r
-    case 0x10:\r
-       return s->sms_sysconfig;\r
-    case 0x14:\r
-       return s->sms_sysstatus;\r
-    case 0x48:\r
-    case 0x68:\r
-    case 0x88:\r
-    case 0xa8:\r
-    case 0xc8:\r
-    case 0xe8:\r
-    case 0x108:\r
-    case 0x128:\r
-       return s->sms_rg_att[(addr-0x48)/0x20];\r
-    case 0x50:\r
-    case 0x70:\r
-    case 0x90:\r
-    case 0xb0:\r
-    case 0xd0:\r
-    case 0xf0:\r
-    case 0x110:\r
-    case 0x130:\r
-       return s->sms_rg_rdperm[(addr-0x50)/0x20];\r
-    case 0x58:\r
-    case 0x78:\r
-    case 0x98:\r
-    case 0xb8:\r
-    case 0xd8:\r
-    case 0xf8:\r
-    case 0x118:\r
-       return s->sms_rg_wrperm[(addr-0x58)/0x20];\r
-    case 0x60:\r
-    case 0x80:\r
-    case 0xa0:\r
-    case 0xc0:\r
-    case 0xe0:\r
-    case 0x100:\r
-    case 0x120:\r
-       return s->sms_rg_start[(addr-0x60)/0x20];\r
-\r
-    case 0x64:\r
-    case 0x84:\r
-    case 0xa4:\r
-    case 0xc4:\r
-    case 0xe4:\r
-    case 0x104:\r
-    case 0x124:\r
-       return s->sms_rg_end[(addr-0x64)/0x20];\r
-    case 0x140:\r
-       return s->sms_security_control;\r
-    case 0x150:\r
-       return s->sms_class_arbiter0;\r
-       case 0x154:\r
-               return s->sms_class_arbiter1;\r
-       case 0x158:\r
-               return s->sms_class_arbiter2;\r
-       case 0x160:\r
-               return s->sms_interclass_arbiter;\r
-       case 0x164:\r
-       case 0x168:\r
-       case 0x16c:\r
-               return s->sms_class_rotation[(addr-0x164)/4];\r
-       case 0x170:\r
-               return s->sms_err_addr;\r
-       case 0x174:\r
-               return s->sms_err_type;\r
-       case 0x178:\r
-               return s->sms_pow_ctrl;\r
-       case 0x180:\r
-       case 0x190:\r
-       case 0x1a0:\r
-       case 0x1b0:\r
-       case 0x1c0:\r
-       case 0x1d0:\r
-       case 0x1e0:\r
-       case 0x1f0:\r
-       case 0x200:\r
-       case 0x210:\r
-       case 0x220:\r
-       case 0x230:\r
-               return s->sms_rot_control[(addr-0x180)/0x10];\r
-       case 0x184:\r
-       case 0x194:\r
-       case 0x1a4:\r
-       case 0x1b4:\r
-       case 0x1c4:\r
-       case 0x1d4:\r
-       case 0x1e4:\r
-       case 0x1f4:\r
-       case 0x204:\r
-       case 0x214:\r
-       case 0x224:\r
-       case 0x234:\r
-               return s->sms_rot_size[(addr-0x184)/0x10];\r
-\r
-       case 0x188:\r
-       case 0x198:\r
-       case 0x1a8:\r
-       case 0x1b8:\r
-       case 0x1c8:\r
-       case 0x1d8:\r
-       case 0x1e8:\r
-       case 0x1f8:\r
-       case 0x208:\r
-       case 0x218:\r
-       case 0x228:\r
-       case 0x238:\r
-               return s->sms_rot_size[(addr-0x188)/0x10];\r
-\r
-    default:\r
-        printf("omap3_sms_read32 addr %x \n", addr);\r
-        exit(-1);\r
-    }\r
-}\r
-\r
-static void omap3_sms_write32(void *opaque, target_phys_addr_t addr,\r
-                              uint32_t value)\r
-{\r
-    struct omap3_sms_s *s = (struct omap3_sms_s *) opaque;\r
-    //int i;\r
-\r
-    switch (addr)\r
-    {\r
-    case 0x14:\r
-       OMAP_RO_REG(addr);\r
-        return;\r
-    case 0x10:\r
-       s->sms_sysconfig = value & 0x1f;\r
-       break;\r
-    \r
-    case 0x48:\r
-    case 0x68:\r
-    case 0x88:\r
-    case 0xa8:\r
-    case 0xc8:\r
-    case 0xe8:\r
-    case 0x108:\r
-    case 0x128:\r
-       s->sms_rg_att[(addr-0x48)/0x20] = value;\r
-       break;\r
-    case 0x50:\r
-    case 0x70:\r
-    case 0x90:\r
-    case 0xb0:\r
-    case 0xd0:\r
-    case 0xf0:\r
-    case 0x110:\r
-    case 0x130:\r
-       s->sms_rg_rdperm[(addr-0x50)/0x20] = value&0xffff;\r
-       break;\r
-    case 0x58:\r
-    case 0x78:\r
-    case 0x98:\r
-    case 0xb8:\r
-    case 0xd8:\r
-    case 0xf8:\r
-    case 0x118:\r
-       s->sms_rg_wrperm[(addr-0x58)/0x20] = value&0xffff;\r
-       break;          \r
-    case 0x60:\r
-    case 0x80:\r
-    case 0xa0:\r
-    case 0xc0:\r
-    case 0xe0:\r
-    case 0x100:\r
-    case 0x120:\r
-       s->sms_rg_start[(addr-0x60)/0x20] = value;\r
-       break;\r
-    case 0x64:\r
-    case 0x84:\r
-    case 0xa4:\r
-    case 0xc4:\r
-    case 0xe4:\r
-    case 0x104:\r
-    case 0x124:\r
-       s->sms_rg_end[(addr-0x64)/0x20] = value;\r
-       break;\r
-    case 0x140:\r
-       s->sms_security_control = value &0xfffffff;\r
-       break;\r
-    case 0x150:\r
-       s->sms_class_arbiter0 = value;\r
-       break;\r
-       case 0x154:\r
-               s->sms_class_arbiter1 = value;\r
-               break;\r
-       case 0x158:\r
-               s->sms_class_arbiter2 = value;\r
-               break;\r
-       case 0x160:\r
-               s->sms_interclass_arbiter = value;\r
-               break;\r
-       case 0x164:\r
-       case 0x168:\r
-       case 0x16c:\r
-               s->sms_class_rotation[(addr-0x164)/4] = value;\r
-               break;\r
-       case 0x170:\r
-               s->sms_err_addr = value;\r
-               break;\r
-       case 0x174:\r
-               s->sms_err_type = value;\r
-               break;\r
-       case 0x178:\r
-               s->sms_pow_ctrl = value;\r
-               break;\r
-       case 0x180:\r
-       case 0x190:\r
-       case 0x1a0:\r
-       case 0x1b0:\r
-       case 0x1c0:\r
-       case 0x1d0:\r
-       case 0x1e0:\r
-       case 0x1f0:\r
-       case 0x200:\r
-       case 0x210:\r
-       case 0x220:\r
-       case 0x230:\r
-               s->sms_rot_control[(addr-0x180)/0x10] = value;\r
-               break;\r
-       case 0x184:\r
-       case 0x194:\r
-       case 0x1a4:\r
-       case 0x1b4:\r
-       case 0x1c4:\r
-       case 0x1d4:\r
-       case 0x1e4:\r
-       case 0x1f4:\r
-       case 0x204:\r
-       case 0x214:\r
-       case 0x224:\r
-       case 0x234:\r
-               s->sms_rot_size[(addr-0x184)/0x10] = value;\r
-               break;\r
-\r
-       case 0x188:\r
-       case 0x198:\r
-       case 0x1a8:\r
-       case 0x1b8:\r
-       case 0x1c8:\r
-       case 0x1d8:\r
-       case 0x1e8:\r
-       case 0x1f8:\r
-       case 0x208:\r
-       case 0x218:\r
-       case 0x228:\r
-       case 0x238:\r
-               s->sms_rot_size[(addr-0x188)/0x10] = value;   \r
-               break;\r
-       default:\r
-        printf("omap3_sms_write32 addr %x\n", addr);\r
-        exit(-1);\r
-    }\r
-}\r
-\r
-static CPUReadMemoryFunc *omap3_sms_readfn[] = {\r
-    omap_badwidth_read32,\r
-    omap_badwidth_read32,\r
-    omap3_sms_read32,\r
-};\r
-\r
-static CPUWriteMemoryFunc *omap3_sms_writefn[] = {\r
-    omap_badwidth_write32,\r
-    omap_badwidth_write32,\r
-    omap3_sms_write32,\r
-};\r
-\r
-static void omap3_sms_reset(struct omap3_sms_s *s)\r
-{\r
-       s->sms_sysconfig = 0x1;\r
-       s->sms_class_arbiter0 = 0x500000;\r
-       s->sms_class_arbiter1 = 0x500;\r
-       s->sms_class_arbiter2 = 0x55000;\r
-       s->sms_interclass_arbiter = 0x400040;\r
-       s->sms_class_rotation[0] = 0x1;\r
-       s->sms_class_rotation[1] = 0x1;\r
-       s->sms_class_rotation[2] = 0x1;\r
-       s->sms_pow_ctrl = 0x80;\r
-}\r
-\r
-static struct omap3_sms_s *omap3_sms_init(struct omap_mpu_state_s *mpu)\r
-{\r
-    int iomemtype;\r
-    struct omap3_sms_s *s = (struct omap3_sms_s *) qemu_mallocz(sizeof(*s));\r
-\r
-    s->mpu = mpu;\r
-\r
-    omap3_sms_reset(s);\r
-    \r
-    iomemtype = cpu_register_io_memory(0, omap3_sms_readfn,\r
-                                       omap3_sms_writefn, s);\r
-    cpu_register_physical_memory(0x6c000000, 0x10000, iomemtype);\r
-\r
-    return s;\r
-}\r
-\r
-static const struct dma_irq_map omap3_dma_irq_map[] = {\r
-    {0, OMAP_INT_35XX_SDMA_IRQ0},\r
-    {0, OMAP_INT_35XX_SDMA_IRQ1},\r
-    {0, OMAP_INT_35XX_SDMA_IRQ2},\r
-    {0, OMAP_INT_35XX_SDMA_IRQ3},\r
-};\r
-\r
-static int omap3_validate_addr(struct omap_mpu_state_s *s,\r
-                               target_phys_addr_t addr)\r
-{\r
-    return 1;\r
-}\r
-\r
-/*\r
-  set the kind of memory connected to GPMC that we are trying to boot form.\r
-  Uses SYS BOOT settings.\r
-*/\r
-void omap3_set_mem_type(struct omap_mpu_state_s *s,int bootfrom)\r
-{\r
-       switch (bootfrom)\r
-       {\r
-               case 0x0: /*GPMC_NOR*/\r
-                       s->omap3_scm->general[32] |= 7;\r
-                       break;\r
-               case 0x1: /*GPMC_NAND*/\r
-                       s->omap3_scm->general[32] |= 1;\r
-                       break;\r
-               case 0x2:\r
-                       s->omap3_scm->general[32] |= 8;\r
-                       break;\r
-               case 0x3:\r
-                       s->omap3_scm->general[32] |= 0;\r
-                       break;\r
-               case 0x4:\r
-                       s->omap3_scm->general[32] |= 17;\r
-                       break;\r
-               case 0x5:\r
-                       s->omap3_scm->general[32] |= 3;\r
-                       break;\r
-       }\r
-}\r
-\r
-void omap3_set_device_type(struct omap_mpu_state_s *s,int device_type)\r
-{\r
-       s->omap3_scm->general[32] |= (device_type & 0x7) << 8;\r
-}\r
-\r
-struct omap_mpu_state_s *omap3530_mpu_init(unsigned long sdram_size,\r
-                                           DisplayState * ds, const char *core)\r
-{\r
-    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)\r
-        qemu_mallocz(sizeof(struct omap_mpu_state_s));\r
-    ram_addr_t sram_base, q2_base;\r
-    qemu_irq *cpu_irq;\r
-    qemu_irq dma_irqs[4];\r
-    int i;\r
-    int sdindex;\r
-    //omap_clk gpio_clks[4];\r
-\r
-\r
-    s->mpu_model = omap3530;\r
-    s->env = cpu_init("cortex-a8-r2");\r
-    if (!s->env)\r
-    {\r
-        fprintf(stderr, "Unable to find CPU definition\n");\r
-        exit(1);\r
-    }\r
-    s->sdram_size = sdram_size;\r
-    s->sram_size = OMAP3530_SRAM_SIZE;\r
-\r
-    sdindex = drive_get_index(IF_SD, 0, 0);\r
-    if (sdindex == -1) {\r
-        fprintf(stderr, "qemu: missing SecureDigital device\n");\r
-        exit(1);\r
-    }\r
-\r
-    /* Clocks */\r
-    omap_clk_init(s);\r
-\r
-    /* Memory-mapped stuff */\r
-\r
-    q2_base = qemu_ram_alloc(s->sdram_size);\r
-    cpu_register_physical_memory(OMAP3_Q2_BASE, s->sdram_size,\r
-                                 (q2_base | IO_MEM_RAM));\r
-    sram_base = qemu_ram_alloc(s->sram_size);\r
-    cpu_register_physical_memory(OMAP3_SRAM_BASE, s->sram_size,\r
-                                 (sram_base | IO_MEM_RAM));\r
-\r
-\r
-    \r
-\r
-    s->l4 = omap_l4_init(OMAP3_L4_BASE, sizeof(omap3_l4_agent_info) / sizeof(struct omap_l4_agent_info_s));\r
-\r
-    cpu_irq = arm_pic_init_cpu(s->env);\r
-    s->ih[0] = omap2_inth_init(s, 0x48200000, 0x1000, 3, &s->irq[0],\r
-                               cpu_irq[ARM_PIC_CPU_IRQ],\r
-                               cpu_irq[ARM_PIC_CPU_FIQ], \r
-                               omap_findclk(s, "omap3_mpu_intc_fclk"),\r
-                               omap_findclk(s, "omap3_mpu_intc_iclk"));\r
-\r
-    for (i = 0; i < 4; i++)\r
-        dma_irqs[i] =\r
-            s->irq[omap3_dma_irq_map[i].ih][omap3_dma_irq_map[i].intr];\r
-    s->dma = omap_dma4_init(0x48056000, dma_irqs, s, 256, 32,\r
-                            omap_findclk(s, "omap3_sdma_fclk"),\r
-                            omap_findclk(s, "omap3_sdma_iclk"));\r
-    s->port->addr_valid = omap3_validate_addr;\r
-\r
-\r
-    /* Register SDRAM and SRAM ports for fast DMA transfers.  */\r
-    soc_dma_port_add_mem_ram(s->dma, q2_base, OMAP2_Q2_BASE, s->sdram_size);\r
-    soc_dma_port_add_mem_ram(s->dma, sram_base, OMAP2_SRAM_BASE, s->sram_size);\r
-\r
-\r
-    s->omap3_cm = omap3_cm_init(omap3_l4ta_get(s->l4, 1), NULL, NULL, NULL, s);\r
-\r
-    s->omap3_prm = omap3_prm_init(omap3_l4ta_get(s->l4, 2),\r
-                                  NULL, NULL, NULL, s);\r
-\r
-    s->omap3_mpu_wdt = omap3_mpu_wdt_init(omap3_l4ta_get(s->l4, 3),\r
-                                          NULL,\r
-                                          omap_findclk(s,\r
-                                                       "omap3_wkup_32k_fclk"),\r
-                                          omap_findclk(s, "omap3_wkup_l4_iclk"),\r
-                                          s);\r
-\r
-    s->omap3_scm = omap3_scm_init(omap3_l4ta_get(s->l4, 0), s);\r
-\r
-    s->omap3_pm = omap3_pm_init(s);\r
-    s->omap3_sms = omap3_sms_init(s);\r
-\r
-    s->gptimer[0] = omap_gp_timer_init(omap3_l4ta_get(s->l4, 4),\r
-                                       s->irq[0][OMAP_INT_35XX_GPTIMER1],\r
-                                       omap_findclk(s, "omap3_gp1_fclk"),\r
-                                       omap_findclk(s, "omap3_wkup_l4_iclk"));\r
-    s->gptimer[1] = omap_gp_timer_init(omap3_l4ta_get(s->l4, 5),\r
-                                       s->irq[0][OMAP_INT_35XX_GPTIMER2],\r
-                                       omap_findclk(s, "omap3_gp2_fclk"),\r
-                                       omap_findclk(s, "omap3_per_l4_iclk"));\r
-    s->gptimer[2] = omap_gp_timer_init(omap3_l4ta_get(s->l4, 6),\r
-                                       s->irq[0][OMAP_INT_35XX_GPTIMER3],\r
-                                       omap_findclk(s, "omap3_gp3_fclk"),\r
-                                       omap_findclk(s, "omap3_per_l4_iclk"));\r
-    s->gptimer[3] = omap_gp_timer_init(omap3_l4ta_get(s->l4, 7),\r
-                                       s->irq[0][OMAP_INT_35XX_GPTIMER4],\r
-                                       omap_findclk(s, "omap3_gp4_fclk"),\r
-                                       omap_findclk(s, "omap3_per_l4_iclk"));\r
-    s->gptimer[4] = omap_gp_timer_init(omap3_l4ta_get(s->l4, 8),\r
-                                       s->irq[0][OMAP_INT_35XX_GPTIMER5],\r
-                                       omap_findclk(s, "omap3_gp5_fclk"),\r
-                                       omap_findclk(s, "omap3_per_l4_iclk"));\r
-    s->gptimer[5] = omap_gp_timer_init(omap3_l4ta_get(s->l4, 9),\r
-                                       s->irq[0][OMAP_INT_35XX_GPTIMER6],\r
-                                       omap_findclk(s, "omap3_gp6_fclk"),\r
-                                       omap_findclk(s, "omap3_per_l4_iclk"));\r
-    s->gptimer[6] = omap_gp_timer_init(omap3_l4ta_get(s->l4, 10),\r
-                                       s->irq[0][OMAP_INT_35XX_GPTIMER7],\r
-                                       omap_findclk(s, "omap3_gp7_fclk"),\r
-                                       omap_findclk(s, "omap3_per_l4_iclk"));\r
-    s->gptimer[7] = omap_gp_timer_init(omap3_l4ta_get(s->l4, 11),\r
-                                       s->irq[0][OMAP_INT_35XX_GPTIMER8],\r
-                                       omap_findclk(s, "omap3_gp8_fclk"),\r
-                                       omap_findclk(s, "omap3_per_l4_iclk"));\r
-    s->gptimer[8] = omap_gp_timer_init(omap3_l4ta_get(s->l4, 12),\r
-                                       s->irq[0][OMAP_INT_35XX_GPTIMER9],\r
-                                       omap_findclk(s, "omap3_gp9_fclk"),\r
-                                       omap_findclk(s, "omap3_per_l4_iclk"));\r
-    s->gptimer[9] = omap_gp_timer_init(omap3_l4ta_get(s->l4, 13),\r
-                                       s->irq[0][OMAP_INT_35XX_GPTIMER10],\r
-                                       omap_findclk(s, "omap3_gp10_fclk"),\r
-                                       omap_findclk(s, "omap3_core_l4_iclk"));\r
-    s->gptimer[10] = omap_gp_timer_init(omap3_l4ta_get(s->l4, 14),\r
-                                       s->irq[0][OMAP_INT_35XX_GPTIMER11],\r
-                                       omap_findclk(s, "omap3_gp12_fclk"),\r
-                                       omap_findclk(s, "omap3_core_l4_iclk"));\r
-    s->gptimer[11] = omap_gp_timer_init(omap3_l4ta_get(s->l4, 15),\r
-                                        s->irq[0][OMAP_INT_35XX_GPTIMER12],\r
-                                        omap_findclk(s, "omap3_gp12_fclk"),\r
-                                        omap_findclk(s, "omap3_wkup_l4_iclk"));\r
-    \r
-       \r
-    omap_synctimer_init(omap3_l4ta_get(s->l4, 16), s,\r
-                        omap_findclk(s, "omap3_sys_32k"), NULL);\r
-\r
-    s->sdrc = omap_sdrc_init(0x6d000000);\r
-    \r
-    s->gpmc = omap_gpmc_init(s, 0x6e000000, s->irq[0][OMAP_INT_35XX_GPMC_IRQ]);\r
-    \r
-\r
-    s->uart[0] = omap2_uart_init(omap3_l4ta_get(s->l4, 17),\r
-                                 s->irq[0][OMAP_INT_35XX_UART1_IRQ],\r
-                                 omap_findclk(s, "omap3_uart1_fclk"),\r
-                                 omap_findclk(s, "omap3_uart1_iclk"),\r
-                                 s->drq[OMAP35XX_DMA_UART1_TX],\r
-                                 s->drq[OMAP35XX_DMA_UART1_RX], serial_hds[0]);\r
-    s->uart[1] = omap2_uart_init(omap3_l4ta_get(s->l4, 18),\r
-                                 s->irq[0][OMAP_INT_35XX_UART2_IRQ],\r
-                                 omap_findclk(s, "omap3_uart2_fclk"),\r
-                                 omap_findclk(s, "omap3_uart2_iclk"),\r
-                                 s->drq[OMAP35XX_DMA_UART2_TX],\r
-                                 s->drq[OMAP35XX_DMA_UART2_RX],\r
-                                 serial_hds[0] ? serial_hds[1] : 0);\r
-    s->uart[2] = omap2_uart_init(omap3_l4ta_get(s->l4, 19),\r
-                                 s->irq[0][OMAP_INT_35XX_UART3_IRQ],\r
-                                 omap_findclk(s, "omap3_uart2_fclk"),\r
-                                 omap_findclk(s, "omap3_uart3_iclk"),\r
-                                 s->drq[OMAP35XX_DMA_UART3_TX],\r
-                                 s->drq[OMAP35XX_DMA_UART3_RX],\r
-                                 serial_hds[0]\r
-                                 && serial_hds[1] ? serial_hds[2] : 0);\r
-    \r
-    /*attach serial[0] to uart 2 for beagle board */\r
-    omap_uart_attach(s->uart[2], serial_hds[0]);\r
-\r
-    s->dss = omap_dss_init(omap3_l4ta_get(s->l4, 20), 0x68005400, ds,\r
-                    s->irq[0][OMAP_INT_35XX_DSS_IRQ], s->drq[OMAP24XX_DMA_DSS],\r
-                   NULL,NULL,NULL,NULL,NULL);\r
-\r
-    //gpio_clks[0] = NULL;\r
-    //gpio_clks[1] = NULL;\r
-    //gpio_clks[2] = NULL;\r
-    //gpio_clks[3] = NULL;\r
-\r
-    s->gpif = omap3_gpif_init();\r
-    /*gpio 1*/\r
-    omap3_gpio_init(s, s->gpif ,omap3_l4ta_get(s->l4, 21),\r
-                    &s->irq[0][OMAP_INT_35XX_GPIO_BANK1], \r
-                    NULL,NULL,0);\r
-    /*gpio 2*/\r
-    omap3_gpio_init(s, s->gpif ,omap3_l4ta_get(s->l4, 22),\r
-                    &s->irq[0][OMAP_INT_35XX_GPIO_BANK2], \r
-                    NULL,NULL,1);\r
-    /*gpio 3*/\r
-    omap3_gpio_init(s, s->gpif ,omap3_l4ta_get(s->l4, 23),\r
-                    &s->irq[0][OMAP_INT_35XX_GPIO_BANK3], \r
-                    NULL,NULL,2);\r
-    /*gpio 4*/\r
-    omap3_gpio_init(s, s->gpif ,omap3_l4ta_get(s->l4, 24),\r
-                    &s->irq[0][OMAP_INT_35XX_GPIO_BANK4], \r
-                    NULL,NULL,3);\r
-\r
-    /*gpio 5*/\r
-    omap3_gpio_init(s, s->gpif ,omap3_l4ta_get(s->l4, 25),\r
-                    &s->irq[0][OMAP_INT_35XX_GPIO_BANK5], \r
-                    NULL,NULL,4);\r
-     /*gpio 6*/\r
-    omap3_gpio_init(s, s->gpif ,omap3_l4ta_get(s->l4, 26),\r
-                    &s->irq[0][OMAP_INT_35XX_GPIO_BANK6], \r
-                    NULL,NULL,5);\r
-\r
-    omap_tap_init(omap3_l4ta_get(s->l4, 27), s);\r
-\r
-    s->omap3_mmc = omap3_mmc_init(omap3_l4ta_get(s->l4, 28), drives_table[sdindex].bdrv,\r
-                    s->irq[0][OMAP_INT_35XX_MMC1_IRQ],\r
-                    &s->drq[OMAP35XX_DMA_MMC1_TX],\r
-                    omap_findclk(s, "omap3_mmc1_fclk"), omap_findclk(s, "omap3_mmc1_iclk"));\r
-\r
-    s->i2c[0] = omap3_i2c_init(omap3_l4ta_get(s->l4, 31),\r
-                               s->irq[0][OMAP_INT_35XX_I2C1_IRQ],\r
-                               &s->drq[OMAP35XX_DMA_I2C1_TX],\r
-                               omap_findclk(s, "omap3_i2c1_fclk"),\r
-                               omap_findclk(s, "omap3_i2c1_iclk"),\r
-                               8);\r
-    s->i2c[1] = omap3_i2c_init(omap3_l4ta_get(s->l4, 32),\r
-                               s->irq[0][OMAP_INT_35XX_I2C2_IRQ],\r
-                               &s->drq[OMAP35XX_DMA_I2C2_TX],\r
-                               omap_findclk(s, "omap3_i2c2_fclk"),\r
-                               omap_findclk(s, "omap3_i2c2_iclk"),\r
-                               8);\r
-    s->i2c[2] = omap3_i2c_init(omap3_l4ta_get(s->l4, 33),\r
-                               s->irq[0][OMAP_INT_35XX_I2C3_IRQ],\r
-                               &s->drq[OMAP35XX_DMA_I2C3_TX],\r
-                               omap_findclk(s, "omap3_i2c3_fclk"),\r
-                               omap_findclk(s, "omap3_i2c3_iclk"),\r
-                               64);\r
-\r
-    return s;\r
-}\r
+/*
+ * TI OMAP3 processors emulation.
+ *
+ * Copyright (C) 2008 yajin <yajin@vm-kernel.org>
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 or
+ * (at your option) version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include "hw.h"
+#include "arm-misc.h"
+#include "omap.h"
+#include "sysemu.h"
+#include "qemu-timer.h"
+#include "qemu-char.h"
+#include "flash.h"
+#include "soc_dma.h"
+#include "audio/audio.h"
+#include "block.h"
+
+/*
+ * When the flag below is defined, the "less important" I/O regions
+ * will not be mapped -- this is needed because the current maximum
+ * number of I/O regions in qemu-system-arm (128) is easily reached
+ * when everything is mapped.
+ */
+#define OMAP3_REDUCE_IOREGIONS
+
+//#define OMAP3_DEBUG_
+
+#ifdef OMAP3_DEBUG_
+#define TRACE(fmt, ...) fprintf(stderr, "%s " fmt "\n", __FUNCTION__, ##__VA_ARGS__)
+#else
+#define TRACE(...) 
+#endif
+
+typedef enum {
+    /* 68000000-680003FF */ L3ID_L3RT = 0,
+    /* 68000400-680007FF */ L3ID_L3SI,
+    /* 68000800-680013FF */
+    /* 68001400-680017FF */ L3ID_MPUSS_IA,
+    /* 68001800-68001BFF */ L3ID_IVASS_IA,
+    /* 68001C00-68001FFF */ L3ID_SGXSS_IA,
+    /* 68002000-680023FF */ L3ID_SMS_TA,
+    /* 68002400-680027FF */ L3ID_GPMC_TA,
+    /* 68002800-68002BFF */ L3ID_OCM_RAM_TA,
+    /* 68002C00-68002FFF */ L3ID_OCM_ROM_TA,
+    /* 68003000-680033FF */ L3ID_D2D_IA,
+    /* 68003400-680037FF */ L3ID_D2D_TA,
+    /* 68003800-68003FFF */
+    /* 68004000-680043FF */ L3ID_HSUSB_HOST_IA,
+    /* 68004400-680047FF */ L3ID_HSUSB_OTG_IA,
+    /* 68004800-68004BFF */
+    /* 68004C00-68004FFF */ L3ID_SDMA_RD_IA,
+    /* 68005000-680053FF */ L3ID_SDMA_WR_IA,
+    /* 68005400-680057FF */ L3ID_DSS_IA,
+    /* 68005800-68005BFF */ L3ID_CAMISP_IA,
+    /* 68005C00-68005FFF */ L3ID_DAP_IA,
+    /* 68006000-680063FF */ L3ID_IVASS_TA,
+    /* 68006400-680067FF */ L3ID_SGXSS_TA,
+    /* 68006800-68006BFF */ L3ID_L4_CORE_TA,
+    /* 68006C00-68006FFF */ L3ID_L4_PER_TA,
+    /* 68007000-680073FF */ L3ID_L4_EMU_TA,
+    /* 68007400-6800FFFF */
+    /* 68010000-680103FF */ L3ID_RT_PM,
+    /* 68010400-680123FF */
+    /* 68012400-680127FF */ L3ID_GPMC_PM,
+    /* 68012800-68012BFF */ L3ID_OCM_RAM_PM,
+    /* 68012C00-68012FFF */ L3ID_OCM_ROM_PM,
+    /* 68013000-680133FF */ L3ID_D2D_PM,
+    /* 68013400-68013FFF */
+    /* 68014000-680143FF */ L3ID_IVA_PM,
+    /* 68014400-68FFFFFF */
+} omap3_l3_region_id_t;
+
+struct omap_l3_region_s {
+    target_phys_addr_t offset;
+    size_t size;
+    enum {
+        L3TYPE_GENERIC = 0, /* needs to be mapped separately */
+        L3TYPE_IA,          /* initiator agent */
+        L3TYPE_TA,          /* target agent */
+        L3TYPE_PM,          /* protection mechanism */
+        L3TYPE_UNDEFINED,   /* every access will emit an error message */
+    } type;
+};
+
+struct omap3_l3_initiator_agent_s {
+    target_phys_addr_t base;
+    
+    uint32_t component;
+    uint32_t control;
+    uint32_t status;
+};
+
+struct omap3_l3pm_s {
+    target_phys_addr_t base;
+    
+    uint32_t error_log;
+    uint8_t  control;
+    uint16_t req_info_permission[8];
+    uint16_t read_permission[8];
+    uint16_t write_permission[8];
+    uint32_t addr_match[7];
+};
+
+union omap3_l3_port_s {
+    struct omap_target_agent_s ta;
+    struct omap3_l3_initiator_agent_s ia;
+    struct omap3_l3pm_s pm;
+};
+
+struct omap_l3_s {
+    target_phys_addr_t base;
+    int region_count;
+    union omap3_l3_port_s region[0];
+};
+
+static struct omap_l3_region_s omap3_l3_region[] = {
+    [L3ID_L3RT         ] = {0x00000000, 0x0400, L3TYPE_UNDEFINED},
+    [L3ID_L3SI         ] = {0x00000400, 0x0400, L3TYPE_UNDEFINED},
+    [L3ID_MPUSS_IA     ] = {0x00001400, 0x0400, L3TYPE_IA},
+    [L3ID_IVASS_IA     ] = {0x00001800, 0x0400, L3TYPE_IA},
+    [L3ID_SGXSS_IA     ] = {0x00001c00, 0x0400, L3TYPE_IA},
+    [L3ID_SMS_TA       ] = {0x00002000, 0x0400, L3TYPE_TA},
+    [L3ID_GPMC_TA      ] = {0x00002400, 0x0400, L3TYPE_TA},
+    [L3ID_OCM_RAM_TA   ] = {0x00002800, 0x0400, L3TYPE_TA},
+    [L3ID_OCM_ROM_TA   ] = {0x00002c00, 0x0400, L3TYPE_TA},
+    [L3ID_D2D_IA       ] = {0x00003000, 0x0400, L3TYPE_IA},
+    [L3ID_D2D_TA       ] = {0x00003400, 0x0400, L3TYPE_TA},
+    [L3ID_HSUSB_HOST_IA] = {0x00004000, 0x0400, L3TYPE_IA},
+    [L3ID_HSUSB_OTG_IA ] = {0x00004400, 0x0400, L3TYPE_IA},
+    [L3ID_SDMA_RD_IA   ] = {0x00004c00, 0x0400, L3TYPE_IA},
+    [L3ID_SDMA_WR_IA   ] = {0x00005000, 0x0400, L3TYPE_IA},
+    [L3ID_DSS_IA       ] = {0x00005400, 0x0400, L3TYPE_IA},
+    [L3ID_CAMISP_IA    ] = {0x00005800, 0x0400, L3TYPE_IA},
+    [L3ID_DAP_IA       ] = {0x00005c00, 0x0400, L3TYPE_IA},
+    [L3ID_IVASS_TA     ] = {0x00006000, 0x0400, L3TYPE_TA},
+    [L3ID_SGXSS_TA     ] = {0x00006400, 0x0400, L3TYPE_TA},
+    [L3ID_L4_CORE_TA   ] = {0x00006800, 0x0400, L3TYPE_TA},
+    [L3ID_L4_PER_TA    ] = {0x00006c00, 0x0400, L3TYPE_TA},
+    [L3ID_L4_EMU_TA    ] = {0x00007000, 0x0400, L3TYPE_TA},
+    [L3ID_RT_PM        ] = {0x00010000, 0x0400, L3TYPE_PM},
+    [L3ID_GPMC_PM      ] = {0x00012400, 0x0400, L3TYPE_PM},
+    [L3ID_OCM_RAM_PM   ] = {0x00012800, 0x0400, L3TYPE_PM},
+    [L3ID_OCM_ROM_PM   ] = {0x00012c00, 0x0400, L3TYPE_PM},
+    [L3ID_D2D_PM       ] = {0x00013000, 0x0400, L3TYPE_PM},
+    [L3ID_IVA_PM       ] = {0x00014000, 0x0400, L3TYPE_PM},
+};
+
+#ifndef OMAP3_REDUCE_IOREGIONS
+static uint32_t omap3_l3ia_read(void *opaque, target_phys_addr_t addr)
+{
+    struct omap3_l3_initiator_agent_s *s = (struct omap3_l3_initiator_agent_s *)opaque;
+    
+    switch (addr) {
+        case 0x00: /* COMPONENT_L */
+            return s->component;
+        case 0x04: /* COMPONENT_H */
+            return 0;
+        case 0x18: /* CORE_L */
+            return s->component;
+        case 0x1c: /* CORE_H */
+            return (s->component >> 16);
+        case 0x20: /* AGENT_CONTROL_L */
+            return s->control;
+        case 0x24: /* AGENT_CONTROL_H */
+            return 0;
+        case 0x28: /* AGENT_STATUS_L */
+            return s->status;
+        case 0x2c: /* AGENT_STATUS_H */
+            return 0;
+        case 0x58: /* ERROR_LOG_L */
+            return 0;
+        case 0x5c: /* ERROR_LOG_H */
+            return 0;
+        case 0x60: /* ERROR_LOG_ADDR_L */
+            return 0;
+        case 0x64: /* ERROR_LOG_ADDR_H */
+            return 0;
+        default:
+            break;
+    }
+    
+    OMAP_BAD_REG(s->base + addr);
+    return 0;
+}
+
+static void omap3_l3ia_write(void *opaque, target_phys_addr_t addr,
+                             uint32_t value)
+{
+    struct omap3_l3_initiator_agent_s *s = (struct omap3_l3_initiator_agent_s *)opaque;
+    
+    switch (addr) {
+        case 0x00: /* COMPONENT_L */
+        case 0x04: /* COMPONENT_H */
+        case 0x18: /* CORE_L */
+        case 0x1c: /* CORE_H */
+        case 0x60: /* ERROR_LOG_ADDR_L */
+        case 0x64: /* ERROR_LOG_ADDR_H */
+            OMAP_RO_REG(s->base + addr);
+            break;
+        case 0x24: /* AGENT_CONTROL_H */
+        case 0x2c: /* AGENT_STATUS_H */
+        case 0x5c: /* ERROR_LOG_H */
+            /* RW register but all bits are reserved/read-only */
+            break;
+        case 0x20: /* AGENT_CONTROL_L */
+            s->control = value & 0x3e070711;
+            /* TODO: some bits are reserved for some IA instances */
+            break;
+        case 0x28: /* AGENT_STATUS_L */
+            s->status &= ~(value & 0x30000000);
+            break;
+        case 0x58: /* ERROR_LOG_L */
+            /* error logging is not implemented, so ignore */
+            break;
+        default:
+            OMAP_BAD_REG(s->base + addr);
+            break;
+    }
+}
+
+static void omap3_l3ia_save_state(QEMUFile *f, void *opaque)
+{
+    struct omap3_l3_initiator_agent_s *s =
+        (struct omap3_l3_initiator_agent_s *)opaque;
+
+    qemu_put_be32(f, s->control);
+    qemu_put_be32(f, s->status);
+}
+
+static int omap3_l3ia_load_state(QEMUFile *f, void *opaque, int version_id)
+{
+    struct omap3_l3_initiator_agent_s *s =
+        (struct omap3_l3_initiator_agent_s *)opaque;
+    
+    if (version_id)
+        return -EINVAL;
+    
+    s->control = qemu_get_be32(f);
+    s->status = qemu_get_be32(f);
+    
+    return 0;
+}
+
+static void omap3_l3ia_init(struct omap3_l3_initiator_agent_s *s)
+{
+    s->component = ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
+    s->control = 0x3e000000;
+    s->status = 0;
+    
+    register_savevm("omap3_l3ia", (s->base >> 8) & 0xffff, 0,
+                    omap3_l3ia_save_state, omap3_l3ia_load_state, s);
+}
+
+static CPUReadMemoryFunc *omap3_l3ia_readfn[] = {
+    omap_badwidth_read32,
+    omap_badwidth_read32,
+    omap3_l3ia_read,
+};
+
+static CPUWriteMemoryFunc *omap3_l3ia_writefn[] = {
+    omap_badwidth_write32,
+    omap_badwidth_write32,
+    omap3_l3ia_write,
+};
+
+static uint32_t omap3_l3ta_read(void *opaque, target_phys_addr_t addr)
+{
+    struct omap_target_agent_s *s = (struct omap_target_agent_s *)opaque;
+    
+    switch (addr) {
+        case 0x00: /* COMPONENT_L */
+            return s->component;
+        case 0x04: /* COMPONENT_H */
+            return 0;
+        case 0x18: /* CORE_L */
+            return s->component;
+        case 0x1c: /* CORE_H */
+            return (s->component >> 16);
+        case 0x20: /* AGENT_CONTROL_L */
+            return s->control;
+        case 0x24: /* AGENT_CONTROL_H */
+            return s->control_h;
+        case 0x28: /* AGENT_STATUS_L */
+            return s->status;
+        case 0x2c: /* AGENT_STATUS_H */
+            return 0;
+        case 0x58: /* ERROR_LOG_L */
+            return 0;
+        case 0x5c: /* ERROR_LOG_H */
+            return 0;
+        case 0x60: /* ERROR_LOG_ADDR_L */
+            return 0;
+        case 0x64: /* ERROR_LOG_ADDR_H */
+            return 0;
+        default:
+            break;
+    }
+    
+    OMAP_BAD_REG(s->base + addr);
+    return 0;
+}
+
+static void omap3_l3ta_write(void *opaque, target_phys_addr_t addr,
+                             uint32_t value)
+{
+    struct omap_target_agent_s *s = (struct omap_target_agent_s *)opaque;
+    
+    switch (addr) {
+        case 0x00: /* COMPONENT_L */
+        case 0x04: /* COMPONENT_H */
+        case 0x18: /* CORE_L */
+        case 0x1c: /* CORE_H */
+        case 0x60: /* ERROR_LOG_ADDR_L */
+        case 0x64: /* ERROR_LOG_ADDR_H */
+            OMAP_RO_REG(s->base + addr);
+            break;
+        case 0x24: /* AGENT_CONTROL_H */
+        case 0x5c: /* ERROR_LOG_H */
+            /* RW register but all bits are reserved/read-only */
+            break;
+        case 0x20: /* AGENT_CONTROL_L */
+            s->control = value & 0x03000711;
+            break;
+        case 0x28: /* AGENT_STATUS_L */
+            if (s->base == OMAP3_L3_BASE + omap3_l3_region[L3ID_L4_CORE_TA].offset
+                || s->base == OMAP3_L3_BASE + omap3_l3_region[L3ID_L4_PER_TA].offset
+                || s->base == OMAP3_L3_BASE + omap3_l3_region[L3ID_L4_EMU_TA].offset) {
+                s->status &= ~(value & (1 << 24));
+            } else
+                OMAP_RO_REG(s->base + addr);
+            break;
+        case 0x2c: /* AGENT_STATUS_H */
+            if (s->base != OMAP3_L3_BASE + omap3_l3_region[L3ID_L4_CORE_TA].offset
+                && s->base != OMAP3_L3_BASE + omap3_l3_region[L3ID_L4_PER_TA].offset
+                && s->base != OMAP3_L3_BASE + omap3_l3_region[L3ID_L4_EMU_TA].offset)
+                OMAP_RO_REG(s->base + addr);
+            /* for L4 core, per, emu TAs this is RW reg */
+            break;
+        case 0x58: /* ERROR_LOG_L */
+            /* error logging is not implemented, so ignore */
+            break;
+        default:
+            OMAP_BAD_REG(s->base + addr);
+            break;
+    }
+}
+
+static void omap3_l3ta_save_state(QEMUFile *f, void *opaque)
+{
+    struct omap_target_agent_s *s =
+        (struct omap_target_agent_s *)opaque;
+    
+    qemu_put_be32(f, s->control);
+    qemu_put_be32(f, s->status);
+}
+
+static int omap3_l3ta_load_state(QEMUFile *f, void *opaque, int version_id)
+{
+    struct omap_target_agent_s *s =
+        (struct omap_target_agent_s *)opaque;
+    
+    if (version_id)
+        return -EINVAL;
+    
+    s->control = qemu_get_be32(f);
+    s->status = qemu_get_be32(f);
+    
+    return 0;
+}
+
+static void omap3_l3ta_init(struct omap_target_agent_s *s)
+{
+    s->component = ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
+    s->control = 0x03000000;
+    s->status = 0;
+
+    register_savevm("omap3_l3ta", (s->base >> 8) & 0xffff, 0,
+                    omap3_l3ta_save_state, omap3_l3ta_load_state, s);
+}
+
+static CPUReadMemoryFunc *omap3_l3ta_readfn[] = {
+    omap_badwidth_read32,
+    omap_badwidth_read32,
+    omap3_l3ta_read,
+};
+
+static CPUWriteMemoryFunc *omap3_l3ta_writefn[] = {
+    omap_badwidth_write32,
+    omap_badwidth_write32,
+    omap3_l3ta_write,
+};
+
+static uint32_t omap3_l3pm_read8(void *opaque, target_phys_addr_t addr)
+{
+    struct omap3_l3pm_s *s = (struct omap3_l3pm_s *)opaque;
+    int i;
+    
+    switch (addr) {
+        case 0x00 ... 0x1f:
+        case 0x40 ... 0x47:
+            OMAP_BAD_REG(s->base + addr);
+            return 0;
+        /* ERROR_LOG */
+        case 0x20: return s->error_log & 0xff;
+        case 0x21: return (s->error_log >> 8) & 0xff;
+        case 0x22: return (s->error_log >> 16) & 0xff;
+        case 0x23: return (s->error_log >> 24) & 0xff;
+        case 0x24 ... 0x27: return 0;
+        /* CONTROL */
+        case 0x28 ... 0x2a: return 0;
+        case 0x2b: return s->control;
+        case 0x2c ... 0x2f: return 0;
+        /* ERROR_CLEAR_SINGLE */
+        case 0x30: return 0; /* TODO: clear single error from log */
+        case 0x31 ... 0x37: return 0;
+        /* ERROR_CLEAR_MULTI */
+        case 0x38: return 0; /* TODO: clear multiple errors from log */
+        case 0x39 ... 0x3f: return 0;
+        default:
+            break;
+    }
+    
+    i = (addr - 0x48) / 0x20;
+    addr -= i * 0x20;
+    if (i < 7 || (i < 8 && addr < 0x60)) 
+        switch (addr) {
+            /* REQ_INFO_PERMISSION_i */
+            case 0x48: return s->req_info_permission[i] & 0xff;
+            case 0x49: return (s->req_info_permission[i] >> 8) & 0xff;
+            case 0x4a ... 0x4f: return 0;
+            /* READ_PERMISSION_i */
+            case 0x50: return s->read_permission[i] & 0xff;
+            case 0x51: return (s->read_permission[i] >> 8) & 0xff;
+            case 0x52 ... 0x57: return 0;
+            /* WRITE_PERMISSION_i */
+            case 0x58: return s->write_permission[i] & 0xff;
+            case 0x59: return (s->write_permission[i] >> 8) & 0xff;
+            case 0x5a ... 0x5f: return 0;
+            /* ADDR_MATCH_i */
+            case 0x60: return s->addr_match[i] & 0xff;
+            case 0x61: return (s->addr_match[i] >> 8) & 0xff;
+            case 0x62: return (s->addr_match[i] >> 16) & 0xff;
+            case 0x63 ... 0x67: return 0;
+            default:
+                break;
+        }
+
+    OMAP_BAD_REG(s->base + addr);
+    return 0;
+}
+
+static uint32_t omap3_l3pm_read16(void *opaque, target_phys_addr_t addr)
+{
+    return omap3_l3pm_read8(opaque, addr)
+        | (omap3_l3pm_read8(opaque, addr + 1) << 8);
+}
+
+static uint32_t omap3_l3pm_read32(void *opaque, target_phys_addr_t addr)
+{
+    return omap3_l3pm_read16(opaque, addr)
+        | (omap3_l3pm_read16(opaque, addr + 2) << 16);
+}
+
+static void omap3_l3pm_write8(void *opaque, target_phys_addr_t addr,
+                              uint32_t value)
+{
+    struct omap3_l3pm_s *s = (struct omap3_l3pm_s *)opaque;
+    int i;
+    
+    switch (addr) {
+        case 0x00 ... 0x1f:
+        case 0x40 ... 0x47:
+            OMAP_BAD_REGV(s->base + addr, value);
+            return;
+        /* ERROR_LOG */
+        case 0x23:
+            s->error_log &= ~((value & 0xcf) << 24);
+        case 0x20 ... 0x22:
+        case 0x24 ... 0x27:
+            return;
+        /* CONTROL */
+        case 0x2b:
+            s->control = value & 3;
+        case 0x28 ... 0x2a:
+        case 0x2c ... 0x2f:
+            return;
+        /* ERROR_CLEAR_SINGLE / ERROR_CLEAR_MULTI */
+        case 0x30 ... 0x3f:
+            OMAP_RO_REGV(s->base + addr, value);
+            return;
+        default:
+            break;
+    }
+    
+    i = (addr - 0x48) / 0x20;
+    addr -= i * 0x20;
+    if (i < 7 || (i < 8 && addr < 0x60)) 
+        switch (addr) {
+            /* REQ_INFO_PERMISSION_i */
+            case 0x48:
+                s->req_info_permission[i] =
+                    (s->req_info_permission[i] & ~0xff) | (value & 0xff);
+                return;
+            case 0x49:
+                s->req_info_permission[i] =
+                    (s->req_info_permission[i] & ~0xff00) | ((value & 0xff) << 8);
+                return;
+            case 0x4a ... 0x4f:
+                return;
+            /* READ_PERMISSION_i */
+            case 0x50:
+                s->read_permission[i] =
+                    (s->read_permission[i] & ~0xff) | (value & 0x3e);
+                return;
+            case 0x51:
+                s->read_permission[i] =
+                    (s->read_permission[i] & ~0xff00) | ((value & 0x5f) << 8);
+                return;
+            case 0x52 ... 0x57:
+                return;
+            /* WRITE_PERMISSION_i */
+            case 0x58:
+                s->write_permission[i] =
+                    (s->write_permission[i] & ~0xff) | (value & 0x3e);
+                return;
+            case 0x59:
+                s->write_permission[i] =
+                    (s->write_permission[i] & ~0xff00) | ((value & 0x5f) << 8);
+                return;
+            case 0x5a ... 0x5f:
+                return;
+            /* ADDR_MATCH_i */
+            case 0x60:
+                s->addr_match[i] = (s->addr_match[i] & ~0xff) | (value & 0xff);
+                return;
+            case 0x61:
+                s->addr_match[i] =
+                    (s->addr_match[i] & ~0xfe00) | ((value & 0xfe) << 8);
+                return;
+            case 0x62:
+                s->addr_match[i] =
+                    (s->addr_match[i] & ~0x0f0000) | ((value & 0x0f) << 16);
+                return;
+            case 0x63 ... 0x67:
+                return;
+            default:
+                break;
+        }
+    
+    OMAP_BAD_REGV(s->base + addr, value);
+}
+
+static void omap3_l3pm_write16(void *opaque, target_phys_addr_t addr,
+                               uint32_t value)
+{
+    omap3_l3pm_write8(opaque, addr + 0, value & 0xff);
+    omap3_l3pm_write8(opaque, addr + 1, (value >> 8) & 0xff);
+}
+
+static void omap3_l3pm_write32(void *opaque, target_phys_addr_t addr,
+                               uint32_t value)
+{
+    omap3_l3pm_write16(opaque, addr + 0, value & 0xffff);
+    omap3_l3pm_write16(opaque, addr + 2, (value >> 16) & 0xffff);
+}
+
+static void omap3_l3pm_save_state(QEMUFile *f, void *opaque)
+{
+    struct omap3_l3pm_s *s = (struct omap3_l3pm_s *)opaque;
+    int i;
+    
+    qemu_put_be32(f, s->error_log);
+    qemu_put_byte(f, s->control);
+    for (i = 0; i < 8; i++) {
+        qemu_put_be16(f, s->req_info_permission[i]);
+        qemu_put_be16(f, s->read_permission[i]);
+        qemu_put_be16(f, s->write_permission[i]);
+        if (i < 7)
+            qemu_put_be32(f, s->addr_match[i]);
+    }
+}
+
+static int omap3_l3pm_load_state(QEMUFile *f, void *opaque, int version_id)
+{
+    struct omap3_l3pm_s *s = (struct omap3_l3pm_s *)opaque;
+    int i;
+    
+    if (version_id)
+        return -EINVAL;
+    
+    s->error_log = qemu_get_be32(f);
+    s->control = qemu_get_byte(f);
+    for (i = 0; i < 8; i++) {
+        s->req_info_permission[i] = qemu_get_be16(f);
+        s->read_permission[i] = qemu_get_be16(f);
+        s->write_permission[i] = qemu_get_be16(f);
+        if (i < 7)
+            s->addr_match[i] = qemu_get_be32(f);
+    }
+    return 0;
+}
+
+static void omap3_l3pm_init(struct omap3_l3pm_s *s)
+{
+    int i;
+    
+    s->error_log = 0;
+    s->control = 0x03;
+    switch (s->base) {
+        case 0x68010000: /* PM_RT */
+            s->req_info_permission[0] = 0xffff;
+            s->req_info_permission[1] = 0;
+            for (i = 0; i < 2; i++)
+                s->read_permission[i] = s->write_permission[i] = 0x1406;
+            s->addr_match[0] = 0x10230;
+            break;
+        case 0x68012400: /* PM_GPMC */
+            s->req_info_permission[0] = 0;
+            for (i = 3; i < 8; i++)
+                s->req_info_permission[i] = 0xffff;
+            for (i = 0; i < 8; i++)
+                s->read_permission[i] = s->write_permission[i] = 0x563e;
+            s->addr_match[0] = 0x00098;
+            break;
+        case 0x68012800: /* PM_OCM_RAM */
+            s->req_info_permission[0] = 0;
+            for (i = 1; i < 8; i++)
+                s->req_info_permission[i] = 0xffff;
+            for (i = 0; i < 8; i++)
+                s->read_permission[i] = s->write_permission[i] = 0x5f3e;
+            s->addr_match[1] = 0x0f810;
+            break;
+        case 0x68012C00: /* PM_OCM_ROM */
+            s->req_info_permission[1] = 0xffff;
+            for (i = 0; i < 2; i++) {
+                s->read_permission[i] = 0x1002;
+                s->write_permission[i] = 0;
+            }
+            s->addr_match[0] = 0x14028;
+            break;
+        case 0x68013000: /* PM_MAD2D */
+            s->req_info_permission[0] = 0;
+            for (i = 1; i < 8; i++)
+                s->req_info_permission[i] = 0xffff;
+            for (i = 0; i < 8; i++)
+                s->read_permission[i] = s->write_permission[i] = 0x5f1e;
+            break;
+        case 0x68014000: /* PM_IVA2.2 */
+            s->req_info_permission[0] = 0;
+            for (i = 1; i < 4; i++)
+                s->req_info_permission[i] = 0xffff;
+            for (i = 0; i < 4; i++)
+                s->read_permission[i] = s->write_permission[i] = 0x140e;
+            break;
+        default:
+            fprintf(stderr, "%s: unknown PM region (0x%08llx)\n",
+                    __FUNCTION__, s->base);
+            exit(-1);
+            break;
+    }
+
+    register_savevm("omap3_l3pm", (s->base >> 8) & 0xffff, 0,
+                    omap3_l3pm_save_state, omap3_l3pm_load_state, s);
+}
+
+static CPUReadMemoryFunc *omap3_l3pm_readfn[] = {
+    omap3_l3pm_read8,
+    omap3_l3pm_read16,
+    omap3_l3pm_read32,
+};
+
+static CPUWriteMemoryFunc *omap3_l3pm_writefn[] = {
+    omap3_l3pm_write8,
+    omap3_l3pm_write16,
+    omap3_l3pm_write32,
+};
+
+static uint32_t omap3_l3undef_read8(void *opaque, target_phys_addr_t addr)
+{
+    fprintf(stderr, "%s: unsupported register at " OMAP_FMT_plx "\n",
+            __FUNCTION__, addr);
+    return 0;
+}
+
+static uint32_t omap3_l3undef_read16(void *opaque, target_phys_addr_t addr)
+{
+    fprintf(stderr, "%s: unsupported register at " OMAP_FMT_plx "\n",
+            __FUNCTION__, addr);
+    return 0;
+}
+
+static uint32_t omap3_l3undef_read32(void *opaque, target_phys_addr_t addr)
+{
+    fprintf(stderr, "%s: unsupported register at " OMAP_FMT_plx "\n",
+            __FUNCTION__, addr);
+    return 0;
+}
+
+static void omap3_l3undef_write8(void *opaque, target_phys_addr_t addr,
+                               uint32_t value)
+{
+    fprintf(stderr, "%s: unsupported register at " OMAP_FMT_plx ", value %02x\n",
+            __FUNCTION__, addr, value);
+}
+
+static void omap3_l3undef_write16(void *opaque, target_phys_addr_t addr,
+                                uint32_t value)
+{
+    fprintf(stderr, "%s: unsupported register at " OMAP_FMT_plx ", value %04x\n",
+            __FUNCTION__, addr, value);
+}
+
+static void omap3_l3undef_write32(void *opaque, target_phys_addr_t addr,
+                                uint32_t value)
+{
+    fprintf(stderr, "%s: unsupported register at " OMAP_FMT_plx ", value %08x\n",
+            __FUNCTION__, addr, value);
+}
+
+static CPUReadMemoryFunc *omap3_l3undef_readfn[] = {
+    omap3_l3undef_read8,
+    omap3_l3undef_read16,
+    omap3_l3undef_read32,
+};
+
+static CPUWriteMemoryFunc *omap3_l3undef_writefn[] = {
+    omap3_l3undef_write8,
+    omap3_l3undef_write16,
+    omap3_l3undef_write32,
+};
+#endif
+
+static struct omap_l3_s *omap3_l3_init(target_phys_addr_t base,
+                                       struct omap_l3_region_s *regions,
+                                       int n)
+{
+#ifdef OMAP3_REDUCE_IOREGIONS
+    return NULL;
+#else
+    int i, iomemtype = 0;
+    
+    struct omap_l3_s *bus = qemu_mallocz(sizeof(*bus) + n * sizeof(*bus->region));
+    bus->region_count = n;
+    bus->base = base;
+    
+    for (i = 0; i < n; i++) {
+        switch (regions[i].type) {
+            case L3TYPE_GENERIC:
+                /* not mapped for now, mapping will be done later by
+                   specialized code */
+                break;
+            case L3TYPE_IA:
+                iomemtype = cpu_register_io_memory(0, omap3_l3ia_readfn,
+                                                   omap3_l3ia_writefn,
+                                                   &bus->region[i].ia);
+                bus->region[i].ia.base = base + regions[i].offset;
+                omap3_l3ia_init(&bus->region[i].ia);
+                break;
+            case L3TYPE_TA:
+                iomemtype = cpu_register_io_memory(0, omap3_l3ta_readfn,
+                                                   omap3_l3ta_writefn,
+                                                   &bus->region[i].ta);
+                bus->region[i].ta.base = base + regions[i].offset;
+                omap3_l3ta_init(&bus->region[i].ta);
+                break;
+            case L3TYPE_PM:
+                iomemtype = cpu_register_io_memory(0, omap3_l3pm_readfn,
+                                                   omap3_l3pm_writefn,
+                                                   &bus->region[i].pm);
+                bus->region[i].pm.base = base + regions[i].offset;
+                omap3_l3pm_init(&bus->region[i].pm);
+                break;
+            case L3TYPE_UNDEFINED:
+                iomemtype = cpu_register_io_memory(0, omap3_l3undef_readfn,
+                                                   omap3_l3undef_writefn,
+                                                   &bus->region[i]);
+                break;
+            default:
+                fprintf(stderr, "%s: unknown L3 region type: %d\n",
+                        __FUNCTION__, regions[i].type);
+                exit(-1);
+                break;
+        }
+        cpu_register_physical_memory(base + regions[i].offset,
+                                     regions[i].size,
+                                     iomemtype);
+    }
+    
+    return bus;
+#endif
+}
+
+typedef enum {
+    /* 48000000-48001FFF */
+    /* 48002000-48002FFF */ L4ID_SCM = 0,
+    /* 48003000-48003FFF */ L4ID_SCM_TA,
+    /* 48004000-48005FFF */ L4ID_CM_A,
+    /* 48006000-480067FF */ L4ID_CM_B,
+    /* 48006800-48006FFF */
+    /* 48007000-48007FFF */ L4ID_CM_TA,
+    /* 48008000-48023FFF */
+    /* 48024000-48024FFF */
+    /* 48025000-48025FFF */
+    /* 48026000-4803FFFF */
+    /* 48040000-480407FF */ L4ID_CORE_AP,
+    /* 48040800-48040FFF */ L4ID_CORE_IP,
+    /* 48041000-48041FFF */ L4ID_CORE_LA,
+    /* 48042000-4804FBFF */
+    /* 4804FC00-4804FFFF */ L4ID_DSI,
+    /* 48050000-480503FF */ L4ID_DSS,
+    /* 48050400-480507FF */ L4ID_DISPC,
+    /* 48050800-48050BFF */ L4ID_RFBI,
+    /* 48050C00-48050FFF */ L4ID_VENC,
+    /* 48051000-48051FFF */ L4ID_DSS_TA,
+    /* 48052000-48055FFF */
+    /* 48056000-48056FFF */ L4ID_SDMA,
+    /* 48057000-48057FFF */ L4ID_SDMA_TA,
+    /* 48058000-4805FFFF */
+    /* 48060000-48060FFF */ L4ID_I2C3,
+    /* 48061000-48061FFF */ L4ID_I2C3_TA,
+    /* 48062000-48062FFF */ L4ID_USBTLL,
+    /* 48063000-48063FFF */ L4ID_USBTLL_TA,
+    /* 48064000-480643FF */ L4ID_USBHOST,
+    /* 48064400-480647FF */ L4ID_USBHOST_OHCI,
+    /* 48064800-4806BFFF */ L4ID_USBHOST_EHCI,
+    /* 48065000-48065FFF */ L4ID_USBHOST_TA,
+    /* 48066000-48069FFF */
+    /* 4806A000-4806AFFF */ L4ID_UART1,
+    /* 4806B000-4806BFFF */ L4ID_UART1_TA,
+    /* 4806C000-4806CFFF */ L4ID_UART2,
+    /* 4806D000-4806DFFF */ L4ID_UART2_TA,
+    /* 4806E000-4806FFFF */
+    /* 48070000-48070FFF */ L4ID_I2C1,
+    /* 48071000-48071FFF */ L4ID_I2C1_TA,
+    /* 48072000-48072FFF */ L4ID_I2C2,
+    /* 48073000-48073FFF */ L4ID_I2C2_TA,
+    /* 48074000-48074FFF */ L4ID_MCBSP1,
+    /* 48075000-48075FFF */ L4ID_MCBSP1_TA,
+    /* 48076000-48085FFF */
+    /* 48086000-48086FFF */ L4ID_GPTIMER10,
+    /* 48087000-48087FFF */ L4ID_GPTIMER10_TA,
+    /* 48088000-48088FFF */ L4ID_GPTIMER11,
+    /* 48089000-48089FFF */ L4ID_GPTIMER11_TA,
+    /* 4808A000-4808AFFF */
+    /* 4808B000-4808BFFF */
+    /* 4808C000-48093FFF */
+    /* 48094000-48094FFF */ L4ID_MAILBOX,
+    /* 48095000-48095FFF */ L4ID_MAILBOX_TA,
+    /* 48096000-48096FFF */ L4ID_MCBSP5,
+    /* 48097000-48097FFF */ L4ID_MCBSP5_TA,
+    /* 48098000-48098FFF */ L4ID_MCSPI1,
+    /* 48099000-48099FFF */ L4ID_MCSPI1_TA,
+    /* 4809A000-4809AFFF */ L4ID_MCSPI2,
+    /* 4809B000-4809BFFF */ L4ID_MCSPI2_TA,
+    /* 4809C000-4809CFFF */ L4ID_MMCSDIO1,
+    /* 4809D000-4809DFFF */ L4ID_MMCSDIO1_TA,
+    /* 4809E000-4809EFFF */ L4ID_MSPRO,
+    /* 4809F000-4809FFFF */ L4ID_MSPRO_TA,
+    /* 480A0000-480AAFFF */
+    /* 480AB000-480ABFFF */ L4ID_HSUSBOTG,
+    /* 480AC000-480ACFFF */ L4ID_HSUSBOTG_TA,
+    /* 480AD000-480ADFFF */ L4ID_MMCSDIO3,
+    /* 480AE000-480AEFFF */ L4ID_MMCSDIO3_TA,
+    /* 480AF000-480AFFFF */
+    /* 480B0000-480B0FFF */
+    /* 480B1000-480B1FFF */
+    /* 480B2000-480B2FFF */ L4ID_HDQ1WIRE,
+    /* 480B3000-480B2FFF */ L4ID_HDQ1WIRE_TA,
+    /* 480B4000-480B4FFF */ L4ID_MMCSDIO2,
+    /* 480B5000-480B5FFF */ L4ID_MMCSDIO2_TA,
+    /* 480B6000-480B6FFF */ L4ID_ICRMPU,
+    /* 480B7000-480B7FFF */ L4ID_ICRMPU_TA,
+    /* 480B8000-480B8FFF */ L4ID_MCSPI3,
+    /* 480B9000-480B9FFF */ L4ID_MCSPI3_TA,
+    /* 480BA000-480BAFFF */ L4ID_MCSPI4,
+    /* 480BB000-480BBFFF */ L4ID_MCSPI4_TA,
+    /* 480BC000-480BFFFF */ L4ID_CAMERAISP,
+    /* 480C0000-480C0FFF */ L4ID_CAMERAISP_TA,
+    /* 480C1000-480CCFFF */
+    /* 480CD000-480CDFFF */ L4ID_ICRMODEM,
+    /* 480CE000-480CEFFF */ L4ID_ICRMODEM_TA,
+    /* 480CF000-482FFFFF */
+    /* 48300000-48303FFF */
+    /* 48304000-48304FFF */ L4ID_GPTIMER12,
+    /* 48305000-48305FFF */ L4ID_GPTIMER12_TA,
+    /* 48306000-48307FFF */ L4ID_PRM_A,
+    /* 48308000-483087FF */ L4ID_PRM_B,
+    /* 48308800-48308FFF */
+    /* 48309000-48309FFF */ L4ID_PRM_TA,
+    /* 4830A000-4830AFFF */ L4ID_TAP,
+    /* 4830B000-4830BFFF */ L4ID_TAP_TA,
+    /* 4830C000-4830FFFF */
+    /* 48310000-48310FFF */ L4ID_GPIO1,
+    /* 48311000-48311FFF */ L4ID_GPIO1_TA,
+    /* 48312000-48313FFF */
+    /* 48314000-48314FFF */ L4ID_WDTIMER2,
+    /* 48315000-48315FFF */ L4ID_WDTIMER2_TA,
+    /* 48316000-48317FFF */
+    /* 48318000-48318FFF */ L4ID_GPTIMER1,
+    /* 48319000-48319FFF */ L4ID_GPTIMER1_TA,
+    /* 4831A000-4831FFFF */
+    /* 48320000-48320FFF */ L4ID_32KTIMER,
+    /* 48321000-48321FFF */ L4ID_32KTIMER_TA,
+    /* 48322000-48327FFF */
+    /* 48328000-483287FF */ L4ID_WAKEUP_AP,
+    /* 48328800-48328FFF */ L4ID_WAKEUP_C_IP,
+    /* 48329000-48329FFF */ L4ID_WAKEUP_LA,
+    /* 4832A000-4832A7FF */ L4ID_WAKEUP_E_IP,
+    /* 4832A800-4833FFFF */
+    /* 48340000-48340FFF */
+    /* 48341000-48FFFFFF */
+    /* 49000000-490007FF */ L4ID_PER_AP,
+    /* 49000800-49000FFF */ L4ID_PER_IP,
+    /* 49001000-49001FFF */ L4ID_PER_LA,
+    /* 49002000-4901FFFF */
+    /* 49020000-49020FFF */ L4ID_UART3,
+    /* 49021000-49021FFF */ L4ID_UART3_TA,
+    /* 49022000-49022FFF */ L4ID_MCBSP2,
+    /* 49023000-49023FFF */ L4ID_MCBSP2_TA,
+    /* 49024000-49024FFF */ L4ID_MCBSP3,
+    /* 49025000-49025FFF */ L4ID_MCBSP3_TA,
+    /* 49026000-49026FFF */ L4ID_MCBSP4,
+    /* 49027000-49027FFF */ L4ID_MCBSP4_TA,
+    /* 49028000-49028FFF */ L4ID_MCBSP2S,
+    /* 49029000-49029FFF */ L4ID_MCBSP2S_TA,
+    /* 4902A000-4902AFFF */ L4ID_MCBSP3S,
+    /* 4902B000-4902BFFF */ L4ID_MCBSP3S_TA,
+    /* 4902C000-4902FFFF */
+    /* 49030000-49030FFF */ L4ID_WDTIMER3,
+    /* 49031000-49031FFF */ L4ID_WDTIMER3_TA,
+    /* 49032000-49032FFF */ L4ID_GPTIMER2,
+    /* 49033000-49033FFF */ L4ID_GPTIMER2_TA,
+    /* 49034000-49034FFF */ L4ID_GPTIMER3,
+    /* 49035000-49035FFF */ L4ID_GPTIMER3_TA,
+    /* 49036000-49036FFF */ L4ID_GPTIMER4,
+    /* 49037000-49037FFF */ L4ID_GPTIMER4_TA,
+    /* 49038000-49038FFF */ L4ID_GPTIMER5,
+    /* 49039000-49039FFF */ L4ID_GPTIMER5_TA,
+    /* 4903A000-4903AFFF */ L4ID_GPTIMER6,
+    /* 4903B000-4903BFFF */ L4ID_GPTIMER6_TA,
+    /* 4903C000-4903CFFF */ L4ID_GPTIMER7,
+    /* 4903D000-4903DFFF */ L4ID_GPTIMER7_TA,
+    /* 4903E000-4903EFFF */ L4ID_GPTIMER8,
+    /* 4903F000-4903FFFF */ L4ID_GPTIMER8_TA,
+    /* 49040000-49040FFF */ L4ID_GPTIMER9,
+    /* 49041000-49041FFF */ L4ID_GPTIMER9_TA,
+    /* 49042000-4904FFFF */
+    /* 49050000-49050FFF */ L4ID_GPIO2,
+    /* 49051000-49051FFF */ L4ID_GPIO2_TA,
+    /* 49052000-49052FFF */ L4ID_GPIO3,
+    /* 49053000-49053FFF */ L4ID_GPIO3_TA,
+    /* 49054000-49054FFF */ L4ID_GPIO4,
+    /* 49055000-49055FFF */ L4ID_GPIO4_TA,
+    /* 49056000-49056FFF */ L4ID_GPIO5,
+    /* 49057000-49057FFF */ L4ID_GPIO5_TA,
+    /* 49058000-49058FFF */ L4ID_GPIO6,
+    /* 49059000-49059FFF */ L4ID_GPIO6_TA,
+    /* 4905A000-490FFFFF */
+    /* 54000000-54003FFF */
+    /* 54004000-54005FFF */
+    /* 54006000-540067FF */ L4ID_EMU_AP,
+    /* 54006800-54006FFF */ L4ID_EMU_IP_C,
+    /* 54007000-54007FFF */ L4ID_EMU_LA,
+    /* 54008000-540087FF */ L4ID_EMU_IP_DAP,
+    /* 54008800-5400FFFF */
+    /* 54010000-54017FFF */ L4ID_MPUEMU,
+    /* 54018000-54018FFF */ L4ID_MPUEMU_TA,
+    /* 54019000-54019FFF */ L4ID_TPIU,
+    /* 5401A000-5401AFFF */ L4ID_TPIU_TA,
+    /* 5401B000-5401BFFF */ L4ID_ETB,
+    /* 5401C000-5401CFFF */ L4ID_ETB_TA,
+    /* 5401D000-5401DFFF */ L4ID_DAPCTL,
+    /* 5401E000-5401EFFF */ L4ID_DAPCTL_TA,
+    /* 5401F000-5401FFFF */ L4ID_SDTI_TA,
+    /* 54020000-544FFFFF */
+    /* 54500000-5450FFFF */ L4ID_SDTI_CFG,
+    /* 54510000-545FFFFF */
+    /* 54600000-546FFFFF */ L4ID_SDTI,
+    /* 54700000-54705FFF */
+    /* 54706000-54707FFF */ L4ID_EMU_PRM_A,
+    /* 54708000-547087FF */ L4ID_EMU_PRM_B,
+    /* 54708800-54708FFF */
+    /* 54709000-54709FFF */ L4ID_EMU_PRM_TA,
+    /* 5470A000-5470FFFF */
+    /* 54710000-54710FFF */ L4ID_EMU_GPIO1,
+    /* 54711000-54711FFF */ L4ID_EMU_GPIO1_TA,
+    /* 54712000-54713FFF */
+    /* 54714000-54714FFF */ L4ID_EMU_WDTM2,
+    /* 54715000-54715FFF */ L4ID_EMU_WDTM2_TA,
+    /* 54716000-54717FFF */
+    /* 54718000-54718FFF */ L4ID_EMU_GPTM1,
+    /* 54719000-54719FFF */ L4ID_EMU_GPTM1_TA,
+    /* 5471A000-5471FFFF */
+    /* 54720000-54720FFF */ L4ID_EMU_32KTM,
+    /* 54721000-54721FFF */ L4ID_EMU_32KTM_TA,
+    /* 54722000-54727FFF */
+    /* 54728000-547287FF */ L4ID_EMU_WKUP_AP,
+    /* 54728800-54728FFF */ L4ID_EMU_WKUP_IPC,
+    /* 54729000-54729FFF */ L4ID_EMU_WKUP_LA,
+    /* 5472A000-5472A7FF */ L4ID_EMU_WKUP_IPE,
+    /* 5472A800-547FFFFF */
+} omap3_l4_region_id_t;
+
+typedef enum {
+    L4TYPE_GENERIC = 0, /* not mapped by default, must be mapped separately */
+    L4TYPE_IA,          /* initiator agent */
+    L4TYPE_TA,          /* target agent */
+    L4TYPE_LA,          /* link register agent */
+    L4TYPE_AP           /* address protection */
+} omap3_l4_region_type_t;
+
+/* we reuse the "access" member for defining region type -- the original
+   omap_l4_region_s "access" member is not used anywhere else anyway! */
+static struct omap_l4_region_s omap3_l4_region[] = {
+    /* L4-Core */
+    [L4ID_SCM         ] = {0x00002000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_SCM_TA      ] = {0x00003000, 0x1000, L4TYPE_TA},
+    [L4ID_CM_A        ] = {0x00004000, 0x2000, L4TYPE_GENERIC},
+    [L4ID_CM_B        ] = {0x00006000, 0x0800, L4TYPE_GENERIC},
+    [L4ID_CM_TA       ] = {0x00007000, 0x1000, L4TYPE_TA},
+    [L4ID_CORE_AP     ] = {0x00040000, 0x0800, L4TYPE_AP},
+    [L4ID_CORE_IP     ] = {0x00040800, 0x0800, L4TYPE_IA},
+    [L4ID_CORE_LA     ] = {0x00041000, 0x1000, L4TYPE_LA},
+    [L4ID_DSI         ] = {0x0004fc00, 0x0400, L4TYPE_GENERIC},
+    [L4ID_DSS         ] = {0x00050000, 0x0400, L4TYPE_GENERIC},
+    [L4ID_DISPC       ] = {0x00050400, 0x0400, L4TYPE_GENERIC},
+    [L4ID_RFBI        ] = {0x00050800, 0x0400, L4TYPE_GENERIC},
+    [L4ID_VENC        ] = {0x00050c00, 0x0400, L4TYPE_GENERIC},
+    [L4ID_DSS_TA      ] = {0x00051000, 0x1000, L4TYPE_TA},
+    [L4ID_SDMA        ] = {0x00056000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_SDMA_TA     ] = {0x00057000, 0x1000, L4TYPE_TA},
+    [L4ID_I2C3        ] = {0x00060000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_I2C3_TA     ] = {0x00061000, 0x1000, L4TYPE_TA},
+    [L4ID_USBTLL      ] = {0x00062000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_USBTLL_TA   ] = {0x00063000, 0x1000, L4TYPE_TA},
+    [L4ID_USBHOST     ] = {0x00064000, 0x0400, L4TYPE_GENERIC},
+    [L4ID_USBHOST_OHCI] = {0x00064400, 0x0400, L4TYPE_GENERIC},
+    [L4ID_USBHOST_EHCI] = {0x00064800, 0x0400, L4TYPE_GENERIC},
+    [L4ID_USBHOST_TA  ] = {0x00065000, 0x1000, L4TYPE_TA},
+    [L4ID_UART1       ] = {0x0006a000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_UART1_TA    ] = {0x0006b000, 0x1000, L4TYPE_TA},
+    [L4ID_UART2       ] = {0x0006c000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_UART2_TA    ] = {0x0006d000, 0x1000, L4TYPE_TA},
+    [L4ID_I2C1        ] = {0x00070000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_I2C1_TA     ] = {0x00071000, 0x1000, L4TYPE_TA},
+    [L4ID_I2C2        ] = {0x00072000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_I2C2_TA     ] = {0x00073000, 0x1000, L4TYPE_TA},
+    [L4ID_MCBSP1      ] = {0x00074000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_MCBSP1_TA   ] = {0x00075000, 0x1000, L4TYPE_TA},
+    [L4ID_GPTIMER10   ] = {0x00086000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_GPTIMER10_TA] = {0x00087000, 0x1000, L4TYPE_TA},
+    [L4ID_GPTIMER11   ] = {0x00088000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_GPTIMER11_TA] = {0x00089000, 0x1000, L4TYPE_TA},
+    [L4ID_MAILBOX     ] = {0x00094000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_MAILBOX_TA  ] = {0x00095000, 0x1000, L4TYPE_TA},
+    [L4ID_MCBSP5      ] = {0x00096000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_MCBSP5_TA   ] = {0x00097000, 0x1000, L4TYPE_TA},
+    [L4ID_MCSPI1      ] = {0x00098000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_MCSPI1_TA   ] = {0x00099000, 0x1000, L4TYPE_TA},
+    [L4ID_MCSPI2      ] = {0x0009a000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_MCSPI2_TA   ] = {0x0009b000, 0x1000, L4TYPE_TA},
+    [L4ID_MMCSDIO1    ] = {0x0009c000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_MMCSDIO1_TA ] = {0x0009d000, 0x1000, L4TYPE_TA},
+    [L4ID_MSPRO       ] = {0x0009e000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_MSPRO_TA    ] = {0x0009f000, 0x1000, L4TYPE_TA},
+    [L4ID_HSUSBOTG    ] = {0x000ab000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_HSUSBOTG_TA ] = {0x000ac000, 0x1000, L4TYPE_TA},
+    [L4ID_MMCSDIO3    ] = {0x000ad000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_MMCSDIO3_TA ] = {0x000ae000, 0x1000, L4TYPE_TA},
+    [L4ID_HDQ1WIRE    ] = {0x000b2000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_HDQ1WIRE_TA ] = {0x000b3000, 0x1000, L4TYPE_TA},
+    [L4ID_MMCSDIO2    ] = {0x000b4000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_MMCSDIO2_TA ] = {0x000b5000, 0x1000, L4TYPE_TA},
+    [L4ID_ICRMPU      ] = {0x000b6000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_ICRMPU_TA   ] = {0x000b7000, 0x1000, L4TYPE_TA},
+    [L4ID_MCSPI3      ] = {0x000b8000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_MCSPI3_TA   ] = {0x000b9000, 0x1000, L4TYPE_TA},
+    [L4ID_MCSPI4      ] = {0x000ba000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_MCSPI4_TA   ] = {0x000bb000, 0x1000, L4TYPE_TA},
+    [L4ID_CAMERAISP   ] = {0x000bc000, 0x4000, L4TYPE_GENERIC},
+    [L4ID_CAMERAISP_TA] = {0x000c0000, 0x1000, L4TYPE_TA},
+    [L4ID_ICRMODEM    ] = {0x000cd000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_ICRMODEM_TA ] = {0x000ce000, 0x1000, L4TYPE_TA},
+    /* L4-Wakeup interconnect region A */
+    [L4ID_GPTIMER12   ] = {0x00304000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_GPTIMER12_TA] = {0x00305000, 0x1000, L4TYPE_TA},
+    [L4ID_PRM_A       ] = {0x00306000, 0x2000, L4TYPE_GENERIC},
+    [L4ID_PRM_B       ] = {0x00308000, 0x0800, L4TYPE_GENERIC},
+    [L4ID_PRM_TA      ] = {0x00309000, 0x1000, L4TYPE_TA},
+    /* L4-Core */
+    [L4ID_TAP         ] = {0x0030a000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_TAP_TA      ] = {0x0030b000, 0x1000, L4TYPE_TA},
+    /* L4-Wakeup interconnect region B */
+    [L4ID_GPIO1       ] = {0x00310000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_GPIO1_TA    ] = {0x00311000, 0x1000, L4TYPE_TA},
+    [L4ID_WDTIMER2    ] = {0x00314000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_WDTIMER2_TA ] = {0x00315000, 0x1000, L4TYPE_TA},
+    [L4ID_GPTIMER1    ] = {0x00318000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_GPTIMER1_TA ] = {0x00319000, 0x1000, L4TYPE_TA},
+    [L4ID_32KTIMER    ] = {0x00320000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_32KTIMER_TA ] = {0x00321000, 0x1000, L4TYPE_TA},
+    [L4ID_WAKEUP_AP   ] = {0x00328000, 0x0800, L4TYPE_AP},
+    [L4ID_WAKEUP_C_IP ] = {0x00328800, 0x0800, L4TYPE_IA},
+    [L4ID_WAKEUP_LA   ] = {0x00329000, 0x1000, L4TYPE_LA},
+    [L4ID_WAKEUP_E_IP ] = {0x0032a000, 0x0800, L4TYPE_IA},
+    /* L4-Per */
+    [L4ID_PER_AP      ] = {0x01000000, 0x0800, L4TYPE_AP},
+    [L4ID_PER_IP      ] = {0x01000800, 0x0800, L4TYPE_IA},
+    [L4ID_PER_LA      ] = {0x01001000, 0x1000, L4TYPE_LA},
+    [L4ID_UART3       ] = {0x01020000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_UART3_TA    ] = {0x01021000, 0x1000, L4TYPE_TA},
+    [L4ID_MCBSP2      ] = {0x01022000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_MCBSP2_TA   ] = {0x01023000, 0x1000, L4TYPE_TA},
+    [L4ID_MCBSP3      ] = {0x01024000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_MCBSP3_TA   ] = {0x01025000, 0x1000, L4TYPE_TA},
+    [L4ID_MCBSP4      ] = {0x01026000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_MCBSP4_TA   ] = {0x01027000, 0x1000, L4TYPE_TA},
+    [L4ID_MCBSP2S     ] = {0x01028000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_MCBSP2S_TA  ] = {0x01029000, 0x1000, L4TYPE_TA},
+    [L4ID_MCBSP3S     ] = {0x0102a000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_MCBSP3S_TA  ] = {0x0102b000, 0x1000, L4TYPE_TA},
+    [L4ID_WDTIMER3    ] = {0x01030000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_WDTIMER3_TA ] = {0x01031000, 0x1000, L4TYPE_TA},
+    [L4ID_GPTIMER2    ] = {0x01032000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_GPTIMER2_TA ] = {0x01033000, 0x1000, L4TYPE_TA},
+    [L4ID_GPTIMER3    ] = {0x01034000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_GPTIMER3_TA ] = {0x01035000, 0x1000, L4TYPE_TA},
+    [L4ID_GPTIMER4    ] = {0x01036000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_GPTIMER4_TA ] = {0x01037000, 0x1000, L4TYPE_TA},
+    [L4ID_GPTIMER5    ] = {0x01038000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_GPTIMER5_TA ] = {0x01039000, 0x1000, L4TYPE_TA},
+    [L4ID_GPTIMER6    ] = {0x0103a000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_GPTIMER6_TA ] = {0x0103b000, 0x1000, L4TYPE_TA},
+    [L4ID_GPTIMER7    ] = {0x0103c000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_GPTIMER7_TA ] = {0x0103d000, 0x1000, L4TYPE_TA},
+    [L4ID_GPTIMER8    ] = {0x0103e000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_GPTIMER8_TA ] = {0x0103f000, 0x1000, L4TYPE_TA},
+    [L4ID_GPTIMER9    ] = {0x01040000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_GPTIMER9_TA ] = {0x01041000, 0x1000, L4TYPE_TA},
+    [L4ID_GPIO2       ] = {0x01050000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_GPIO2_TA    ] = {0x01051000, 0x1000, L4TYPE_TA},
+    [L4ID_GPIO3       ] = {0x01052000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_GPIO3_TA    ] = {0x01053000, 0x1000, L4TYPE_TA},
+    [L4ID_GPIO4       ] = {0x01054000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_GPIO4_TA    ] = {0x01055000, 0x1000, L4TYPE_TA},
+    [L4ID_GPIO5       ] = {0x01056000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_GPIO5_TA    ] = {0x01057000, 0x1000, L4TYPE_TA},
+    [L4ID_GPIO6       ] = {0x01058000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_GPIO6_TA    ] = {0x01059000, 0x1000, L4TYPE_TA},
+    /* L4-Emu */
+    [L4ID_EMU_AP      ] = {0x0c006000, 0x0800, L4TYPE_AP},
+    [L4ID_EMU_IP_C    ] = {0x0c006800, 0x0800, L4TYPE_IA},
+    [L4ID_EMU_LA      ] = {0x0c007000, 0x1000, L4TYPE_LA},
+    [L4ID_EMU_IP_DAP  ] = {0x0c008000, 0x0800, L4TYPE_IA},
+    [L4ID_MPUEMU      ] = {0x0c010000, 0x8000, L4TYPE_GENERIC},
+    [L4ID_MPUEMU_TA   ] = {0x0c018000, 0x1000, L4TYPE_TA},
+    [L4ID_TPIU        ] = {0x0c019000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_TPIU_TA     ] = {0x0c01a000, 0x1000, L4TYPE_TA},
+    [L4ID_ETB         ] = {0x0c01b000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_ETB_TA      ] = {0x0c01c000, 0x1000, L4TYPE_TA},
+    [L4ID_DAPCTL      ] = {0x0c01d000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_DAPCTL_TA   ] = {0x0c01e000, 0x1000, L4TYPE_TA},
+    [L4ID_EMU_PRM_A   ] = {0x0c706000, 0x2000, L4TYPE_GENERIC},
+    [L4ID_EMU_PRM_B   ] = {0x0c706800, 0x0800, L4TYPE_GENERIC},
+    [L4ID_EMU_PRM_TA  ] = {0x0c709000, 0x1000, L4TYPE_TA},
+    [L4ID_EMU_GPIO1   ] = {0x0c710000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_EMU_GPIO1_TA] = {0x0c711000, 0x1000, L4TYPE_TA},
+    [L4ID_EMU_WDTM2   ] = {0x0c714000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_EMU_WDTM2_TA] = {0x0c715000, 0x1000, L4TYPE_TA},
+    [L4ID_EMU_GPTM1   ] = {0x0c718000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_EMU_GPTM1_TA] = {0x0c719000, 0x1000, L4TYPE_TA},
+    [L4ID_EMU_32KTM   ] = {0x0c720000, 0x1000, L4TYPE_GENERIC},
+    [L4ID_EMU_32KTM_TA] = {0x0c721000, 0x1000, L4TYPE_TA},
+    [L4ID_EMU_WKUP_AP ] = {0x0c728000, 0x0800, L4TYPE_AP},
+    [L4ID_EMU_WKUP_IPC] = {0x0c728800, 0x0800, L4TYPE_IA},
+    [L4ID_EMU_WKUP_LA ] = {0x0c729000, 0x1000, L4TYPE_LA},
+    [L4ID_EMU_WKUP_IPE] = {0x0c72a000, 0x0800, L4TYPE_IA},
+};
+
+typedef enum {
+    L4A_SCM = 0,
+    L4A_CM,
+    L4A_PRM,
+    L4A_GPTIMER1,
+    L4A_GPTIMER2,
+    L4A_GPTIMER3,
+    L4A_GPTIMER4,
+    L4A_GPTIMER5,
+    L4A_GPTIMER6,
+    L4A_GPTIMER7,
+    L4A_GPTIMER8,
+    L4A_GPTIMER9,
+    L4A_GPTIMER10,
+    L4A_GPTIMER11,
+    L4A_GPTIMER12,
+    L4A_WDTIMER2,
+    L4A_32KTIMER,
+    L4A_UART1,
+    L4A_UART2,
+    L4A_UART3,
+    L4A_DSS,
+    L4A_GPIO1,
+    L4A_GPIO2,
+    L4A_GPIO3,
+    L4A_GPIO4,
+    L4A_GPIO5,
+    L4A_GPIO6,
+    L4A_MMC1,
+    L4A_MMC2,
+    L4A_MMC3,
+    L4A_I2C1,
+    L4A_I2C2,
+    L4A_I2C3,
+    L4A_TAP,
+    L4A_USBHS_OTG,
+    L4A_USBHS_HOST,
+    L4A_USBHS_TLL,
+    L4A_MCSPI1,
+    L4A_MCSPI2,
+    L4A_MCSPI3,
+    L4A_MCSPI4,
+    L4A_SDMA
+} omap3_l4_agent_info_id_t;
+
+struct omap3_l4_agent_info_s {
+    omap3_l4_agent_info_id_t agent_id;
+    omap3_l4_region_id_t     first_region_id;
+    int                      region_count;
+};
+
+static const struct omap3_l4_agent_info_s omap3_l4_agent_info[] = {
+    /* L4-Core Agents */
+    {L4A_DSS,        L4ID_DSI,       6},
+    /* TODO: camera */
+    {L4A_USBHS_OTG,  L4ID_HSUSBOTG,  2},
+    {L4A_USBHS_HOST, L4ID_USBHOST,   4},
+    {L4A_USBHS_TLL,  L4ID_USBTLL,    2},
+    {L4A_UART1,      L4ID_UART1,     2},
+    {L4A_UART2,      L4ID_UART2,     2},
+    {L4A_I2C1,       L4ID_I2C1,      2},
+    {L4A_I2C2,       L4ID_I2C2,      2},
+    {L4A_I2C3,       L4ID_I2C3,      2},
+    /* TODO: McBSP1 */
+    /* TODO: McBSP5 */
+    {L4A_GPTIMER10,  L4ID_GPTIMER10, 2},
+    {L4A_GPTIMER11,  L4ID_GPTIMER11, 2},
+    {L4A_MCSPI1,     L4ID_MCSPI1,    2},
+    {L4A_MCSPI2,     L4ID_MCSPI2,    2},
+    {L4A_MMC1,       L4ID_MMCSDIO1,  2},
+    {L4A_MMC2,       L4ID_MMCSDIO2,  2},
+    {L4A_MMC3,       L4ID_MMCSDIO3,  2},
+    /* TODO: HDQ/1-Wire */
+    /* TODO: Mailbox */
+    {L4A_MCSPI3,     L4ID_MCSPI3,    2},
+    {L4A_MCSPI4,     L4ID_MCSPI4,    2},
+    {L4A_SDMA,       L4ID_SDMA,      2},
+    {L4A_CM,         L4ID_CM_A,      3},
+    {L4A_SCM,        L4ID_SCM,       2},
+    {L4A_TAP,        L4ID_TAP,       2},
+    /* L4-Wakeup Agents */
+    {L4A_GPTIMER12,  L4ID_GPTIMER12, 2},
+    {L4A_PRM,        L4ID_PRM_A,     3},
+    {L4A_GPIO1,      L4ID_GPIO1,     2},
+    {L4A_WDTIMER2,   L4ID_WDTIMER2,  2},
+    {L4A_GPTIMER1,   L4ID_GPTIMER1,  2},
+    {L4A_32KTIMER,   L4ID_32KTIMER,  2},
+    /* L4-Per Agents */
+    {L4A_UART3,      L4ID_UART3,     2},
+    /* TODO: McBSP2 */
+    /* TODO: McBSP3 */
+    {L4A_GPTIMER2,   L4ID_GPTIMER2,  2},
+    {L4A_GPTIMER3,   L4ID_GPTIMER3,  2},
+    {L4A_GPTIMER4,   L4ID_GPTIMER4,  2},
+    {L4A_GPTIMER5,   L4ID_GPTIMER5,  2},
+    {L4A_GPTIMER6,   L4ID_GPTIMER6,  2},
+    {L4A_GPTIMER7,   L4ID_GPTIMER7,  2},
+    {L4A_GPTIMER8,   L4ID_GPTIMER8,  2},
+    {L4A_GPTIMER9,   L4ID_GPTIMER9,  2},
+    {L4A_GPIO2,      L4ID_GPIO2,     2},
+    {L4A_GPIO3,      L4ID_GPIO3,     2},
+    {L4A_GPIO4,      L4ID_GPIO4,     2},
+    {L4A_GPIO5,      L4ID_GPIO5,     2},
+    {L4A_GPIO6,      L4ID_GPIO6,     2},
+};
+
+#ifndef OMAP3_REDUCE_IOREGIONS
+static uint32_t omap3_l4ta_read(void *opaque, target_phys_addr_t addr)
+{
+    struct omap_target_agent_s *s = (struct omap_target_agent_s *)opaque;
+    
+    switch (addr) {
+        case 0x00: /* COMPONENT_L */
+            return s->component;
+        case 0x04: /* COMPONENT_H */
+            return 0;
+        case 0x18: /* CORE_L */
+            return s->component;
+        case 0x1c: /* CORE_H */
+            return (s->component >> 16);
+        case 0x20: /* AGENT_CONTROL_L */
+            return s->control;
+        case 0x24: /* AGENT_CONTROL_H */
+            return s->control_h;
+        case 0x28: /* AGENT_STATUS_L */
+            return s->status;
+        case 0x2c: /* AGENT_STATUS_H */
+            return 0;
+        default:
+            break;
+    }
+    
+    OMAP_BAD_REG(s->base + addr);
+    return 0;
+}
+
+static void omap3_l4ta_write(void *opaque, target_phys_addr_t addr,
+                             uint32_t value)
+{
+    struct omap_target_agent_s *s = (struct omap_target_agent_s *)opaque;
+    
+    switch (addr) {
+        case 0x00: /* COMPONENT_L */
+        case 0x04: /* COMPONENT_H */
+        case 0x18: /* CORE_L */
+        case 0x1c: /* CORE_H */
+            OMAP_RO_REG(s->base + addr);
+            break;
+        case 0x20: /* AGENT_CONTROL_L */
+            s->control = value & 0x00000701;
+            break;
+        case 0x24: /* AGENT_CONTROL_H */
+            s->control_h = value & 0x100; /* TODO: shouldn't this be read-only? */
+            break;
+        case 0x28: /* AGENT_STATUS_L */
+            if (value & 0x100)
+                s->status &= ~0x100; /* REQ_TIMEOUT */
+            break;
+        case 0x2c: /* AGENT_STATUS_H */
+            /* no writable bits although the register is listed as RW */
+            break;
+        default:
+            OMAP_BAD_REG(s->base + addr);
+            break;
+    }
+}
+
+static void omap3_l4ta_save_state(QEMUFile *f, void *opaque)
+{
+    struct omap_target_agent_s *s = (struct omap_target_agent_s *)opaque;
+    
+    qemu_put_be32(f, s->control);
+    qemu_put_be32(f, s->control_h);
+    qemu_put_be32(f, s->status);
+}
+
+static int omap3_l4ta_load_state(QEMUFile *f, void *opaque, int version_id)
+{
+    struct omap_target_agent_s *s = (struct omap_target_agent_s *)opaque;
+    
+    if (version_id)
+        return -EINVAL;
+    
+    s->control = qemu_get_be32(f);
+    s->control_h = qemu_get_be32(f);
+    s->status = qemu_get_be32(f);
+    
+    return 0;
+}
+
+static CPUReadMemoryFunc *omap3_l4ta_readfn[] = {
+    omap_badwidth_read32,
+    omap_badwidth_read32,
+    omap3_l4ta_read,
+};
+
+static CPUWriteMemoryFunc *omap3_l4ta_writefn[] = {
+    omap_badwidth_write32,
+    omap_badwidth_write32,
+    omap3_l4ta_write,
+};
+#endif
+
+static struct omap_target_agent_s *omap3_l4ta_init(struct omap_l4_s *bus, int cs)
+{
+#ifndef OMAP3_REDUCE_IOREGIONS
+    int iomemtype;
+#endif
+    int i;
+    struct omap_target_agent_s *ta = 0;
+    const struct omap3_l4_agent_info_s *info = 0;
+
+    for (i = 0; i < bus->ta_num; i++)
+        if (omap3_l4_agent_info[i].agent_id == cs) {
+            ta = &bus->ta[i];
+            info = &omap3_l4_agent_info[i];
+            break;
+        }
+    if (!ta) {
+        fprintf(stderr, "%s: invalid agent id (%i)\n", __FUNCTION__, cs);
+        exit(-1);
+    }
+    if (ta->bus) {
+        fprintf(stderr, "%s: target agent (%d) already initialized\n",
+                __FUNCTION__, cs);
+        exit(-1);
+    }
+
+    ta->bus = bus;
+    ta->start = &omap3_l4_region[info->first_region_id];
+    ta->regions = info->region_count;
+
+    ta->component = ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
+    ta->status = 0x00000000;
+    ta->control = 0x00000200;
+
+    for (i = 0; i < info->region_count; i++)
+        if (omap3_l4_region[info->first_region_id + i].access == L4TYPE_TA)
+            break;
+    if (i >= info->region_count) {
+        fprintf(stderr, "%s: specified agent (%d) has no TA region\n",
+                __FUNCTION__, cs);
+        exit(-1);
+    }
+    
+#ifndef OMAP3_REDUCE_IOREGIONS
+    iomemtype = l4_register_io_memory(0, omap3_l4ta_readfn,
+                                      omap3_l4ta_writefn, ta);
+    ta->base = omap_l4_attach(ta, i, iomemtype);
+
+    register_savevm("omap3_l4ta", ta->base >> 8, 0,
+                    omap3_l4ta_save_state, omap3_l4ta_load_state, ta);
+#else
+    ta->base = ta->bus->base + ta->start[i].offset;
+#endif
+
+    return ta;
+}
+
+/* common PRM domain registers */
+struct omap3_prm_domain_s {
+    uint32_t rm_rstctrl;     /* 50 */
+    uint32_t rm_rstst;       /* 58 */
+    uint32_t pm_wken;        /* a0 */
+    uint32_t pm_mpugrpsel;   /* a4 */
+    uint32_t pm_ivagrpsel;   /* a8 */
+    uint32_t pm_wkst;        /* b0 */
+    uint32_t pm_wkst3;       /* b8 */
+    uint32_t pm_wkdep;       /* c8 */
+    uint32_t pm_evgenctrl;   /* d4 */
+    uint32_t pm_evgenontim;  /* d8 */
+    uint32_t pm_evgenofftim; /* dc */
+    uint32_t pm_pwstctrl;    /* e0 */
+    uint32_t pm_pwstst;      /* e4 */
+    uint32_t pm_prepwstst;   /* e8 */
+    uint32_t pm_wken3;       /* f0 */
+};
+
+struct omap3_prm_s {
+    qemu_irq mpu_irq;
+    qemu_irq iva_irq;
+    struct omap_mpu_state_s *omap;
+
+    struct omap3_prm_domain_s iva2;
+    struct omap3_prm_domain_s mpu;
+    struct omap3_prm_domain_s core;
+    struct omap3_prm_domain_s sgx;
+    struct omap3_prm_domain_s wkup;
+    struct omap3_prm_domain_s dss;
+    struct omap3_prm_domain_s cam;
+    struct omap3_prm_domain_s per;
+    struct omap3_prm_domain_s emu;
+    struct omap3_prm_domain_s neon;
+    struct omap3_prm_domain_s usbhost;
+
+    uint32_t prm_irqstatus_iva2;
+    uint32_t prm_irqenable_iva2;
+    
+    uint32_t pm_iva2grpsel3_core;
+    uint32_t pm_mpugrpsel3_core;
+
+    struct {
+        uint32_t prm_revision;
+        uint32_t prm_sysconfig;
+        uint32_t prm_irqstatus_mpu;
+        uint32_t prm_irqenable_mpu;
+    } ocp;
+
+    struct {
+        uint32_t prm_clksel;
+        uint32_t prm_clkout_ctrl;
+    } ccr; /* clock_control_reg */
+
+    struct {
+        uint32_t prm_vc_smps_sa;
+        uint32_t prm_vc_smps_vol_ra;
+        uint32_t prm_vc_smps_cmd_ra;
+        uint32_t prm_vc_cmd_val_0;
+        uint32_t prm_vc_cmd_val_1;
+        uint32_t prm_vc_hc_conf;
+        uint32_t prm_vc_i2c_cfg;
+        uint32_t prm_vc_bypass_val;
+        uint32_t prm_rstctrl;
+        uint32_t prm_rsttimer;
+        uint32_t prm_rstst;
+        uint32_t prm_voltctrl;
+        uint32_t prm_sram_pcharge;
+        uint32_t prm_clksrc_ctrl;
+        uint32_t prm_obs;
+        uint32_t prm_voltsetup1;
+        uint32_t prm_voltoffset;
+        uint32_t prm_clksetup;
+        uint32_t prm_polctrl;
+        uint32_t prm_voltsetup2;
+    } gr; /* global_reg */
+};
+
+static void omap3_prm_int_update(struct omap3_prm_s *s)
+{
+    qemu_set_irq(s->mpu_irq, s->ocp.prm_irqstatus_mpu & s->ocp.prm_irqenable_mpu);
+    qemu_set_irq(s->iva_irq, s->prm_irqstatus_iva2 & s->prm_irqenable_iva2);
+}
+
+static void omap3_prm_reset(struct omap3_prm_s *s)
+{
+    bzero(&s->iva2, sizeof(s->iva2));
+    s->iva2.rm_rstctrl    = 0x7;
+    s->iva2.rm_rstst      = 0x1;
+    s->iva2.pm_wkdep      = 0xb3;
+    s->iva2.pm_pwstctrl   = 0xff0f07;
+    s->iva2.pm_pwstst     = 0xff7;
+    s->prm_irqstatus_iva2 = 0x0;
+    s->prm_irqenable_iva2 = 0x0;
+
+    bzero(&s->ocp, sizeof(s->ocp));
+    s->ocp.prm_revision      = 0x10;
+    s->ocp.prm_sysconfig     = 0x1;
+    
+    bzero(&s->mpu, sizeof(s->mpu));
+    s->mpu.rm_rstst       = 0x1;
+    s->mpu.pm_wkdep       = 0xa5;
+    s->mpu.pm_pwstctrl    = 0x30107;
+    s->mpu.pm_pwstst      = 0xc7;
+    s->mpu.pm_evgenctrl   = 0x12;
+
+    bzero(&s->core, sizeof(s->core));
+    s->core.rm_rstst       = 0x1;
+    s->core.pm_wken        = 0xc33ffe18;
+    s->core.pm_mpugrpsel   = 0xc33ffe18;
+    s->core.pm_ivagrpsel   = 0xc33ffe18;
+    s->core.pm_pwstctrl    = 0xf0307;
+    s->core.pm_pwstst      = 0xf7;
+    s->core.pm_wken3       = 0x4;
+    s->pm_iva2grpsel3_core = 0x4;
+    s->pm_mpugrpsel3_core  = 0x4;
+
+    bzero(&s->sgx, sizeof(s->sgx));
+    s->sgx.rm_rstst     = 0x1;
+    s->sgx.pm_wkdep     = 0x16;
+    s->sgx.pm_pwstctrl  = 0x30107;
+    s->sgx.pm_pwstst    = 0x3;
+
+    bzero(&s->wkup, sizeof(s->wkup));
+    s->wkup.pm_wken      = 0x3cb;
+    s->wkup.pm_mpugrpsel = 0x3cb;
+    s->wkup.pm_pwstst    = 0x3; /* TODO: check on real hardware */
+
+    bzero(&s->ccr, sizeof(s->ccr));
+    s->ccr.prm_clksel      = 0x3; /* TRM says 0x4, but on HW this is 0x3 */
+    s->ccr.prm_clkout_ctrl = 0x80;
+
+    bzero(&s->dss, sizeof(s->dss));
+    s->dss.rm_rstst     = 0x1;
+    s->dss.pm_wken      = 0x1;
+    s->dss.pm_wkdep     = 0x16;
+    s->dss.pm_pwstctrl  = 0x30107;
+    s->dss.pm_pwstst    = 0x3;
+
+    bzero(&s->cam, sizeof(s->cam));
+    s->cam.rm_rstst     = 0x1;
+    s->cam.pm_wkdep     = 0x16;
+    s->cam.pm_pwstctrl  = 0x30107;
+    s->cam.pm_pwstst    = 0x3;
+
+    bzero(&s->per, sizeof(s->per));
+    s->per.rm_rstst     = 0x1;
+    s->per.pm_wken      = 0x3efff;
+    s->per.pm_mpugrpsel = 0x3efff;
+    s->per.pm_ivagrpsel = 0x3efff;
+    s->per.pm_wkdep     = 0x17;
+    s->per.pm_pwstctrl  = 0x30107;
+    s->per.pm_pwstst    = 0x7;
+
+    bzero(&s->emu, sizeof(s->emu));
+    s->emu.rm_rstst  = 0x1;
+    s->emu.pm_pwstst = 0x13;
+
+    bzero(&s->gr, sizeof(s->gr));
+    s->gr.prm_vc_i2c_cfg     = 0x18;
+    s->gr.prm_rsttimer       = 0x1006;
+    s->gr.prm_rstst          = 0x1;
+    s->gr.prm_sram_pcharge   = 0x50;
+    s->gr.prm_clksrc_ctrl    = 0x43;
+    s->gr.prm_polctrl        = 0xa;
+
+    bzero(&s->neon, sizeof(s->neon));
+    s->neon.rm_rstst     = 0x1;
+    s->neon.pm_wkdep     = 0x2;
+    s->neon.pm_pwstctrl  = 0x7;
+    s->neon.pm_pwstst    = 0x3;
+
+    bzero(&s->usbhost, sizeof(s->usbhost));
+    s->usbhost.rm_rstst     = 0x1;
+    s->usbhost.pm_wken      = 0x1;
+    s->usbhost.pm_mpugrpsel = 0x1;
+    s->usbhost.pm_ivagrpsel = 0x1;
+    s->usbhost.pm_wkdep     = 0x17;
+    s->usbhost.pm_pwstctrl  = 0x30107;
+    s->usbhost.pm_pwstst    = 0x3;
+
+    omap3_prm_int_update(s);
+}
+
+static uint32_t omap3_prm_read(void *opaque, target_phys_addr_t addr)
+{
+    struct omap3_prm_s *s = (struct omap3_prm_s *)opaque;
+    struct omap3_prm_domain_s *d = 0;
+
+    TRACE("%04x", addr);
+    
+    /* handle common domain registers first - all domains may not
+       have all common registers though but we're returning zeroes there */
+    switch ((addr >> 8) & 0xff) {
+        case 0x00: d = &s->iva2; break;
+        case 0x09: d = &s->mpu; break;
+        case 0x0a: d = &s->core; break;
+        case 0x0b: d = &s->sgx; break;
+        case 0x0c: d = &s->wkup; break;
+        case 0x0e: d = &s->dss; break;
+        case 0x0f: d = &s->cam; break;
+        case 0x10: d = &s->per; break;
+        case 0x11: d = &s->emu; break;
+        case 0x13: d = &s->neon; break;
+        case 0x14: d = &s->usbhost; break;
+        default: break;
+    }
+    if (d)
+        switch (addr & 0xff) {
+            case 0x50: return d->rm_rstctrl;
+            case 0x58: return d->rm_rstst;
+            case 0xa0: return d->pm_wken;
+            case 0xa4: return d->pm_mpugrpsel;
+            case 0xa8: return d->pm_ivagrpsel;
+            case 0xb0: return d->pm_wkst;
+            case 0xb8: return d->pm_wkst3;
+            case 0xc8: return d->pm_wkdep;
+            case 0xd4: return d->pm_evgenctrl;
+            case 0xd8: return d->pm_evgenontim;
+            case 0xdc: return d->pm_evgenofftim;
+            case 0xe0: return d->pm_pwstctrl;
+            case 0xe4: return d->pm_pwstst;
+            case 0xe8: return d->pm_prepwstst;
+            case 0xf0: return d->pm_wken3;
+            default: break;
+        }
+
+    /* okay, not a common domain register so let's take a closer look */
+    switch (addr) {
+        case 0x00f8: return s->prm_irqstatus_iva2;
+        case 0x00fc: return s->prm_irqenable_iva2;
+        case 0x0804: return s->ocp.prm_revision;
+        case 0x0814: return s->ocp.prm_sysconfig;
+        case 0x0818: return s->ocp.prm_irqstatus_mpu;
+        case 0x081c: return s->ocp.prm_irqenable_mpu;
+        case 0x0af4: return s->pm_iva2grpsel3_core;
+        case 0x0af8: return s->pm_mpugrpsel3_core;
+        case 0x0d40: return s->ccr.prm_clksel;
+        case 0x0d70: return s->ccr.prm_clkout_ctrl;
+        case 0x0de4: return 0x3; /* TODO: check on real hardware */
+        case 0x1220: return s->gr.prm_vc_smps_sa;
+        case 0x1224: return s->gr.prm_vc_smps_vol_ra;
+        case 0x1228: return s->gr.prm_vc_smps_cmd_ra;
+        case 0x122c: return s->gr.prm_vc_cmd_val_0;
+        case 0x1230: return s->gr.prm_vc_cmd_val_1;
+        case 0x1234: return s->gr.prm_vc_hc_conf;
+        case 0x1238: return s->gr.prm_vc_i2c_cfg;
+        case 0x123c: return s->gr.prm_vc_bypass_val;
+        case 0x1250: return s->gr.prm_rstctrl;
+        case 0x1254: return s->gr.prm_rsttimer;
+        case 0x1258: return s->gr.prm_rstst;
+        case 0x1260: return s->gr.prm_voltctrl;
+        case 0x1264: return s->gr.prm_sram_pcharge;            
+        case 0x1270: return s->gr.prm_clksrc_ctrl;
+        case 0x1280: return s->gr.prm_obs;
+        case 0x1290: return s->gr.prm_voltsetup1;
+        case 0x1294: return s->gr.prm_voltoffset;
+        case 0x1298: return s->gr.prm_clksetup;
+        case 0x129c: return s->gr.prm_polctrl;
+        case 0x12a0: return s->gr.prm_voltsetup2;
+        default: break;
+    }
+
+    OMAP_BAD_REG(addr);
+    return 0;
+}
+
+static inline void omap3_prm_clksrc_ctrl_update(struct omap3_prm_s *s)
+{
+    uint32_t value = s->gr.prm_clksrc_ctrl;
+    
+    if ((value & 0xd0) == 0x40)
+        omap_clk_setrate(omap_findclk(s->omap, "omap3_sys_clk"), 1, 1);
+    else if ((value & 0xd0) == 0x80)
+        omap_clk_setrate(omap_findclk(s->omap, "omap3_sys_clk"), 2, 1);
+}
+
+static void omap3_prm_clksel_update(struct omap3_prm_s *s)
+{
+    omap_clk newparent = 0;
+    
+    switch (s->ccr.prm_clksel & 7) {
+        case 0: newparent = omap_findclk(s->omap, "omap3_osc_sys_clk12"); break;
+        case 1: newparent = omap_findclk(s->omap, "omap3_osc_sys_clk13"); break;
+        case 2: newparent = omap_findclk(s->omap, "omap3_osc_sys_clk192"); break;
+        case 3: newparent = omap_findclk(s->omap, "omap3_osc_sys_clk26"); break;
+        case 4: newparent = omap_findclk(s->omap, "omap3_osc_sys_clk384"); break;
+        case 5: newparent = omap_findclk(s->omap, "omap3_osc_sys_clk168"); break;
+        default:
+            fprintf(stderr, "%s: invalid sys_clk input selection (%d) - ignored\n",
+                    __FUNCTION__, s->ccr.prm_clksel & 7);
+            break;
+    }
+    if (newparent) {
+        omap_clk_reparent(omap_findclk(s->omap, "omap3_sys_clk"), newparent);
+        omap_clk_reparent(omap_findclk(s->omap, "omap3_sys_clkout1"), newparent);
+    }
+}
+
+static void omap3_prm_write(void *opaque, target_phys_addr_t addr,
+                            uint32_t value)
+{
+    struct omap3_prm_s *s = (struct omap3_prm_s *)opaque;
+
+    TRACE("%04x = %08x", addr, value);
+    switch (addr) {
+        /* IVA2_PRM */
+        case 0x0050: s->iva2.rm_rstctrl = value & 0x7; break;
+        case 0x0058: s->iva2.rm_rstst &= ~(value & 0x3f0f); break;
+        case 0x00c8: s->iva2.pm_wkdep = value & 0xb3; break;
+        case 0x00e0: s->iva2.pm_pwstctrl = 0xcff000 | (value & 0x300f0f); break;
+        case 0x00e4: OMAP_RO_REG(addr); break;
+        case 0x00e8: s->iva2.pm_prepwstst = value & 0xff7;
+        case 0x00f8:
+            s->prm_irqstatus_iva2 &= ~(value & 0x7);
+            omap3_prm_int_update(s);
+            break;
+        case 0x00fc:
+            s->prm_irqenable_iva2 = value & 0x7;
+            omap3_prm_int_update(s);
+            break;
+        /* OCP_System_Reg_PRM */
+        case 0x0804: OMAP_RO_REG(addr); break;
+        case 0x0814: s->ocp.prm_sysconfig = value & 0x1; break;
+        case 0x0818:
+            s->ocp.prm_irqstatus_mpu &= ~(value & 0x03c003fd);
+            omap3_prm_int_update(s);
+            break;
+        case 0x081c:
+            s->ocp.prm_irqenable_mpu = value & 0x03c003fd;
+            omap3_prm_int_update(s);
+            break;
+        /* MPU_PRM */
+        case 0x0958: s->mpu.rm_rstst &= ~(value & 0x080f); break;
+        case 0x09c8: s->mpu.pm_wkdep = value & 0xa5; break;
+        case 0x09d4: s->mpu.pm_evgenctrl = value & 0x1f; break;
+        case 0x09d8: s->mpu.pm_evgenontim = value; break;
+        case 0x09dc: s->mpu.pm_evgenofftim = value; break;
+        case 0x09e0: s->mpu.pm_pwstctrl = value & 0x3010f; break;
+        case 0x09e4: OMAP_RO_REG(addr); break;
+        case 0x09e8: s->mpu.pm_prepwstst = value & 0xc7; break;
+        /* CORE_PRM */
+        case 0x0a50: s->core.rm_rstctrl = value & 0x3; break; /* TODO: check if available on real hw */
+        case 0x0a58: s->core.rm_rstst &= ~(value & 0x7); break;
+        case 0x0aa0: s->core.pm_wken = 0x80000008 | (value & 0x433ffe10); break;
+        case 0x0aa4: s->core.pm_mpugrpsel = 0x80000008 | (value & 0x433ffe10); break;
+        case 0x0aa8: s->core.pm_ivagrpsel = 0x80000008 | (value & 0x433ffe10); break;
+        case 0x0ab0: s->core.pm_wkst = value & 0x433ffe10; break;
+        case 0x0ab8: s->core.pm_wkst3 &= ~(value & 0x4); break;
+        case 0x0ae0: s->core.pm_pwstctrl = (value & 0x0f031f); break;
+        case 0x0ae4: OMAP_RO_REG(addr); break;
+        case 0x0ae8: s->core.pm_prepwstst = value & 0xf7; break;
+        case 0x0af0: s->core.pm_wken3 = value & 0x4; break;
+        case 0x0af4: s->pm_iva2grpsel3_core = value & 0x4; break;
+        case 0x0af8: s->pm_mpugrpsel3_core = value & 0x4; break;
+        /* SGX_PRM */
+        case 0x0b58: s->sgx.rm_rstst &= ~(value & 0xf); break;
+        case 0x0bc8: s->sgx.pm_wkdep = value & 0x16; break;
+        case 0x0be0: s->sgx.pm_pwstctrl = 0x030104 | (value & 0x3); break;
+        case 0x0be4: OMAP_RO_REG(addr); break;
+        case 0x0be8: s->sgx.pm_prepwstst = value & 0x3; break;
+        /* WKUP_PRM */
+        case 0x0ca0: s->wkup.pm_wken = 0x2 | (value & 0x0103c9); break;
+        case 0x0ca4: s->wkup.pm_mpugrpsel = 0x0102 | (value & 0x02c9); break;
+        case 0x0ca8: s->wkup.pm_ivagrpsel = value & 0x03cb; break;
+        case 0x0cb0: s->wkup.pm_wkst &= ~(value & 0x0103cb); break;
+        /* Clock_Control_Reg_PRM */
+        case 0x0d40: 
+            s->ccr.prm_clksel = value & 0x7;
+            omap3_prm_clksel_update(s);
+            break;
+        case 0x0d70:
+            s->ccr.prm_clkout_ctrl = value & 0x80;
+            omap_clk_onoff(omap_findclk(s->omap, "omap3_sys_clkout1"),
+                           s->ccr.prm_clkout_ctrl & 0x80);
+            break;
+        /* DSS_PRM */
+        case 0x0e58: s->dss.rm_rstst &= ~(value & 0xf); break;
+        case 0x0ea0: s->dss.pm_wken = value & 1; break;
+        case 0x0ec8: s->dss.pm_wkdep = value & 0x16; break;
+        case 0x0ee0: s->dss.pm_pwstctrl = 0x030104 | (value & 3); break;
+        case 0x0ee4: OMAP_RO_REG(addr); break;
+        case 0x0ee8: s->dss.pm_prepwstst = value & 3; break;
+        /* CAM_PRM */
+        case 0x0f58: s->cam.rm_rstst &= (value & 0xf); break;
+        case 0x0fc8: s->cam.pm_wkdep = value & 0x16; break;
+        case 0x0fe0: s->cam.pm_pwstctrl = 0x030104 | (value & 3); break;
+        case 0x0fe4: OMAP_RO_REG(addr); break;
+        case 0x0fe8: s->cam.pm_prepwstst = value & 0x3; break;
+        /* PER_PRM */
+        case 0x1058: s->per.rm_rstst &= ~(value & 0xf); break;
+        case 0x10a0: s->per.pm_wken = value & 0x03efff; break;
+        case 0x10a4: s->per.pm_mpugrpsel = value & 0x03efff; break;
+        case 0x10a8: s->per.pm_ivagrpsel = value & 0x03efff; break;
+        case 0x10b0: s->per.pm_wkst &= ~(value & 0x03efff); break;
+        case 0x10c8: s->per.pm_wkdep = value & 0x17; break;
+        case 0x10e0: s->per.pm_pwstctrl = 0x030100 | (value & 7); break;
+        case 0x10e4: OMAP_RO_REG(addr); break;
+        case 0x10e8: s->per.pm_prepwstst = value & 0x7; break;
+        /* EMU_PRM */
+        case 0x1158: s->emu.rm_rstst &= ~(value & 7); break;
+        case 0x11e4: OMAP_RO_REG(addr); break;
+        /* Global_Reg_PRM */
+        case 0x1220: s->gr.prm_vc_smps_sa = value & 0x7f007f; break;
+        case 0x1224: s->gr.prm_vc_smps_vol_ra = value & 0xff00ff; break;
+        case 0x1228: s->gr.prm_vc_smps_cmd_ra = value & 0xff00ff; break;
+        case 0x122c: s->gr.prm_vc_cmd_val_0 = value; break;
+        case 0x1230: s->gr.prm_vc_cmd_val_1 = value; break;
+        case 0x1234: s->gr.prm_vc_hc_conf = value & 0x1f001f; break;
+        case 0x1238: s->gr.prm_vc_i2c_cfg = value & 0x3f; break;
+        case 0x123c: s->gr.prm_vc_bypass_val = value & 0x01ffff7f; break;
+        case 0x1250: s->gr.prm_rstctrl = 0; break; /* TODO: resets */
+        case 0x1254: s->gr.prm_rsttimer = value & 0x1fff; break;
+        case 0x1258: s->gr.prm_rstst &= ~(value & 0x7fb); break;
+        case 0x1260: s->gr.prm_voltctrl = value & 0x1f; break;
+        case 0x1264: s->gr.prm_sram_pcharge = value & 0xff; break;
+        case 0x1270:
+            s->gr.prm_clksrc_ctrl = value & 0xd8; /* set osc bypass mode */ 
+            omap3_prm_clksrc_ctrl_update(s);
+            break;
+        case 0x1280: OMAP_RO_REG(addr); break;
+        case 0x1290: s->gr.prm_voltsetup1 = value; break;
+        case 0x1294: s->gr.prm_voltoffset = value & 0xffff; break;
+        case 0x1298: s->gr.prm_clksetup = value & 0xffff; break;
+        case 0x129c: s->gr.prm_polctrl = value & 0xf; break;
+        case 0x12a0: s->gr.prm_voltsetup2 = value & 0xffff; break;
+        /* NEON_PRM */
+        case 0x1358: s->neon.rm_rstst &= ~(value & 0xf); break;
+        case 0x13c8: s->neon.pm_wkdep = value & 0x2; break;
+        case 0x13e0: s->neon.pm_pwstctrl = 0x4 | (value & 3); break;
+        case 0x13e4: OMAP_RO_REG(addr); break;
+        case 0x13e8: s->neon.pm_prepwstst = value & 3; break;
+        /* USBHOST_PRM */
+        case 0x1458: s->usbhost.rm_rstst &= ~(value & 0xf); break;
+        case 0x14a0: s->usbhost.pm_wken = value & 1; break;
+        case 0x14a4: s->usbhost.pm_mpugrpsel = value & 1; break;
+        case 0x14a8: s->usbhost.pm_ivagrpsel = value & 1; break;
+        case 0x14b0: s->usbhost.pm_wkst &= ~(value & 1); break;
+        case 0x14c8: s->usbhost.pm_wkdep = value & 0x17; break;
+        case 0x14e0: s->usbhost.pm_pwstctrl = 0x030104 | (value & 0x13); break;
+        case 0x14e4: OMAP_RO_REG(addr); break;
+        case 0x14e8: s->usbhost.pm_prepwstst = value & 3; break;
+        default:
+            OMAP_BAD_REGV(addr, value);
+            break;
+    }
+}
+
+static void omap3_prm_save_domain_state(QEMUFile *f,
+                                        struct omap3_prm_domain_s *s)
+{
+    qemu_put_be32(f, s->rm_rstctrl);
+    qemu_put_be32(f, s->rm_rstst);
+    qemu_put_be32(f, s->pm_wken);
+    qemu_put_be32(f, s->pm_mpugrpsel);
+    qemu_put_be32(f, s->pm_ivagrpsel);
+    qemu_put_be32(f, s->pm_wkst);
+    qemu_put_be32(f, s->pm_wkst3);
+    qemu_put_be32(f, s->pm_wkdep);
+    qemu_put_be32(f, s->pm_evgenctrl);
+    qemu_put_be32(f, s->pm_evgenontim);
+    qemu_put_be32(f, s->pm_evgenofftim);
+    qemu_put_be32(f, s->pm_pwstctrl);
+    qemu_put_be32(f, s->pm_pwstst);
+    qemu_put_be32(f, s->pm_prepwstst);
+    qemu_put_be32(f, s->pm_wken3);
+}
+
+static void omap3_prm_load_domain_state(QEMUFile *f,
+                                        struct omap3_prm_domain_s *s)
+{
+    s->rm_rstctrl = qemu_get_be32(f);
+    s->rm_rstst = qemu_get_be32(f);
+    s->pm_wken = qemu_get_be32(f);
+    s->pm_mpugrpsel = qemu_get_be32(f);
+    s->pm_ivagrpsel = qemu_get_be32(f);
+    s->pm_wkst = qemu_get_be32(f);
+    s->pm_wkst3 = qemu_get_be32(f);
+    s->pm_wkdep = qemu_get_be32(f);
+    s->pm_evgenctrl = qemu_get_be32(f);
+    s->pm_evgenontim = qemu_get_be32(f);
+    s->pm_evgenofftim = qemu_get_be32(f);
+    s->pm_pwstctrl = qemu_get_be32(f);
+    s->pm_pwstst = qemu_get_be32(f);
+    s->pm_prepwstst = qemu_get_be32(f);
+    s->pm_wken3 = qemu_get_be32(f);
+}
+
+static void omap3_prm_save_state(QEMUFile *f, void *opaque)
+{
+    struct omap3_prm_s *s = (struct omap3_prm_s *)opaque;
+    
+    omap3_prm_save_domain_state(f, &s->iva2);
+    omap3_prm_save_domain_state(f, &s->mpu);
+    omap3_prm_save_domain_state(f, &s->core);
+    omap3_prm_save_domain_state(f, &s->sgx);
+    omap3_prm_save_domain_state(f, &s->wkup);
+    omap3_prm_save_domain_state(f, &s->dss);
+    omap3_prm_save_domain_state(f, &s->cam);
+    omap3_prm_save_domain_state(f, &s->per);
+    omap3_prm_save_domain_state(f, &s->emu);
+    omap3_prm_save_domain_state(f, &s->neon);
+    omap3_prm_save_domain_state(f, &s->usbhost);
+    
+    qemu_put_be32(f, s->prm_irqstatus_iva2);
+    qemu_put_be32(f, s->prm_irqenable_iva2);
+    qemu_put_be32(f, s->pm_iva2grpsel3_core);
+    qemu_put_be32(f, s->pm_mpugrpsel3_core);
+    
+    qemu_put_be32(f, s->ocp.prm_revision);
+    qemu_put_be32(f, s->ocp.prm_sysconfig);
+    qemu_put_be32(f, s->ocp.prm_irqstatus_mpu);
+    qemu_put_be32(f, s->ocp.prm_irqenable_mpu);
+    
+    qemu_put_be32(f, s->ccr.prm_clksel);
+    qemu_put_be32(f, s->ccr.prm_clkout_ctrl);
+    
+    qemu_put_be32(f, s->gr.prm_vc_smps_sa);
+    qemu_put_be32(f, s->gr.prm_vc_smps_vol_ra);
+    qemu_put_be32(f, s->gr.prm_vc_smps_cmd_ra);
+    qemu_put_be32(f, s->gr.prm_vc_cmd_val_0);
+    qemu_put_be32(f, s->gr.prm_vc_cmd_val_1);
+    qemu_put_be32(f, s->gr.prm_vc_hc_conf);
+    qemu_put_be32(f, s->gr.prm_vc_i2c_cfg);
+    qemu_put_be32(f, s->gr.prm_vc_bypass_val);
+    qemu_put_be32(f, s->gr.prm_rstctrl);
+    qemu_put_be32(f, s->gr.prm_rsttimer);
+    qemu_put_be32(f, s->gr.prm_rstst);
+    qemu_put_be32(f, s->gr.prm_voltctrl);
+    qemu_put_be32(f, s->gr.prm_sram_pcharge);
+    qemu_put_be32(f, s->gr.prm_clksrc_ctrl);
+    qemu_put_be32(f, s->gr.prm_obs);
+    qemu_put_be32(f, s->gr.prm_voltsetup1);
+    qemu_put_be32(f, s->gr.prm_voltoffset);
+    qemu_put_be32(f, s->gr.prm_clksetup);
+    qemu_put_be32(f, s->gr.prm_polctrl);
+    qemu_put_be32(f, s->gr.prm_voltsetup2);
+}
+
+static int omap3_prm_load_state(QEMUFile *f, void *opaque, int version_id)
+{
+    struct omap3_prm_s *s = (struct omap3_prm_s *)opaque;
+    
+    if (version_id)
+        return -EINVAL;
+    
+    omap3_prm_load_domain_state(f, &s->iva2);
+    omap3_prm_load_domain_state(f, &s->mpu);
+    omap3_prm_load_domain_state(f, &s->core);
+    omap3_prm_load_domain_state(f, &s->sgx);
+    omap3_prm_load_domain_state(f, &s->wkup);
+    omap3_prm_load_domain_state(f, &s->dss);
+    omap3_prm_load_domain_state(f, &s->cam);
+    omap3_prm_load_domain_state(f, &s->per);
+    omap3_prm_load_domain_state(f, &s->emu);
+    omap3_prm_load_domain_state(f, &s->neon);
+    omap3_prm_load_domain_state(f, &s->usbhost);
+    
+    s->prm_irqstatus_iva2 = qemu_get_be32(f);
+    s->prm_irqenable_iva2 = qemu_get_be32(f);
+    s->pm_iva2grpsel3_core = qemu_get_be32(f);
+    s->pm_mpugrpsel3_core = qemu_get_be32(f);
+    
+    s->ocp.prm_revision = qemu_get_be32(f);
+    s->ocp.prm_sysconfig = qemu_get_be32(f);
+    s->ocp.prm_irqstatus_mpu = qemu_get_be32(f);
+    s->ocp.prm_irqenable_mpu = qemu_get_be32(f);
+    
+    s->ccr.prm_clksel = qemu_get_be32(f);
+    s->ccr.prm_clkout_ctrl = qemu_get_be32(f);
+    
+    s->gr.prm_vc_smps_sa = qemu_get_be32(f);
+    s->gr.prm_vc_smps_vol_ra = qemu_get_be32(f);
+    s->gr.prm_vc_smps_cmd_ra = qemu_get_be32(f);
+    s->gr.prm_vc_cmd_val_0 = qemu_get_be32(f);
+    s->gr.prm_vc_cmd_val_1 = qemu_get_be32(f);
+    s->gr.prm_vc_hc_conf = qemu_get_be32(f);
+    s->gr.prm_vc_i2c_cfg = qemu_get_be32(f);
+    s->gr.prm_vc_bypass_val = qemu_get_be32(f);
+    s->gr.prm_rstctrl = qemu_get_be32(f);
+    s->gr.prm_rsttimer = qemu_get_be32(f);
+    s->gr.prm_rstst = qemu_get_be32(f);
+    s->gr.prm_voltctrl = qemu_get_be32(f);
+    s->gr.prm_sram_pcharge = qemu_get_be32(f);
+    s->gr.prm_clksrc_ctrl = qemu_get_be32(f);
+    s->gr.prm_obs = qemu_get_be32(f);
+    s->gr.prm_voltsetup1 = qemu_get_be32(f);
+    s->gr.prm_voltoffset = qemu_get_be32(f);
+    s->gr.prm_clksetup = qemu_get_be32(f);
+    s->gr.prm_polctrl = qemu_get_be32(f);
+    s->gr.prm_voltsetup2 = qemu_get_be32(f);
+    
+    omap3_prm_int_update(s);
+    omap3_prm_clksrc_ctrl_update(s);
+    omap3_prm_clksel_update(s);
+    omap_clk_onoff(omap_findclk(s->omap, "omap3_sys_clkout1"),
+                   s->ccr.prm_clkout_ctrl & 0x80);
+    
+    return 0;
+}
+
+static CPUReadMemoryFunc *omap3_prm_readfn[] = {
+    omap_badwidth_read32,
+    omap_badwidth_read32,
+    omap3_prm_read,
+};
+
+static CPUWriteMemoryFunc *omap3_prm_writefn[] = {
+    omap_badwidth_write32,
+    omap_badwidth_write32,
+    omap3_prm_write,
+};
+
+static struct omap3_prm_s *omap3_prm_init(struct omap_target_agent_s *ta,
+                                          qemu_irq mpu_int, qemu_irq iva_int,
+                                          struct omap_mpu_state_s *mpu)
+{
+    int iomemtype;
+    struct omap3_prm_s *s = (struct omap3_prm_s *) qemu_mallocz(sizeof(*s));
+
+    s->mpu_irq = mpu_int;
+    s->iva_irq = iva_int;
+    s->omap = mpu;
+    omap3_prm_reset(s);
+
+    iomemtype = l4_register_io_memory(0, omap3_prm_readfn,
+                                      omap3_prm_writefn, s);
+    omap_l4_attach(ta, 0, iomemtype);
+    omap_l4_attach(ta, 1, iomemtype);
+
+    register_savevm("omap3_prm", -1, 0,
+                    omap3_prm_save_state, omap3_prm_load_state, s);
+
+    return s;
+}
+
+struct omap3_cm_s {
+    qemu_irq irq[3];
+    struct omap_mpu_state_s *mpu;
+
+    /* IVA2_CM: base + 0x0000 */
+    uint32_t cm_fclken_iva2;       /* 00 */
+    uint32_t cm_clken_pll_iva2;    /* 04 */
+    uint32_t cm_idlest_iva2;       /* 20 */
+    uint32_t cm_idlest_pll_iva2;   /* 24 */
+    uint32_t cm_autoidle_pll_iva2; /* 34 */
+    uint32_t cm_clksel1_pll_iva2;  /* 40 */
+    uint32_t cm_clksel2_pll_iva2;  /* 44 */
+    uint32_t cm_clkstctrl_iva2;    /* 48 */
+    uint32_t cm_clkstst_iva2;      /* 4c */
+
+    /* OCP_System_Reg_CM: base + 0x0800 */
+    uint32_t cm_revision;  /* 00 */
+    uint32_t cm_sysconfig; /* 10 */
+
+    /* MPU_CM: base + 0x0900 */
+    uint32_t cm_clken_pll_mpu;    /* 04 */
+    uint32_t cm_idlest_mpu;       /* 20 */
+    uint32_t cm_idlest_pll_mpu;   /* 24 */
+    uint32_t cm_autoidle_pll_mpu; /* 34 */
+    uint32_t cm_clksel1_pll_mpu;  /* 40 */
+    uint32_t cm_clksel2_pll_mpu;  /* 44 */
+    uint32_t cm_clkstctrl_mpu;    /* 48 */
+    uint32_t cm_clkstst_mpu;      /* 4c */
+
+    /* CORE_CM: base + 0x0a00 */
+    uint32_t cm_fclken1_core;   /* 0a00 */
+    uint32_t cm_fclken3_core;   /* 0a08 */
+    uint32_t cm_iclken1_core;   /* 0a10 */
+    uint32_t cm_iclken2_core;   /* 0a14 */
+    uint32_t cm_iclken3_core;   /* 0a18 */
+    uint32_t cm_idlest1_core;   /* 0a20 */
+    uint32_t cm_idlest2_core;   /* 0a24 */
+    uint32_t cm_idlest3_core;   /* 0a28 */
+    uint32_t cm_autoidle1_core; /* 0a30 */
+    uint32_t cm_autoidle2_core; /* 0a34 */
+    uint32_t cm_autoidle3_core; /* 0a38 */
+    uint32_t cm_clksel_core;    /* 0a40 */
+    uint32_t cm_clkstctrl_core; /* 0a48 */
+    uint32_t cm_clkstst_core;   /* 0a4c */
+
+    /* SGX_CM: base + 0x0b00 */
+    uint32_t cm_fclken_sgx;    /* 00 */
+    uint32_t cm_iclken_sgx;    /* 10 */
+    uint32_t cm_idlest_sgx;    /* 20 */
+    uint32_t cm_clksel_sgx;    /* 40 */
+    uint32_t cm_sleepdep_sgx;  /* 44 */
+    uint32_t cm_clkstctrl_sgx; /* 48 */
+    uint32_t cm_clkstst_sgx;   /* 4c */
+
+    /* WKUP_CM: base + 0x0c00 */
+    uint32_t cm_fclken_wkup;   /* 00 */
+    uint32_t cm_iclken_wkup;   /* 10 */
+    uint32_t cm_idlest_wkup;   /* 20 */
+    uint32_t cm_autoidle_wkup; /* 30 */
+    uint32_t cm_clksel_wkup;   /* 40 */
+    uint32_t cm_c48;           /* 48 */
+
+    /* Clock_Control_Reg_CM: base + 0x0d00 */
+    uint32_t cm_clken_pll;     /* 00 */
+    uint32_t cm_clken2_pll;    /* 04 */
+    uint32_t cm_idlest_ckgen;  /* 20 */
+    uint32_t cm_idlest2_ckgen; /* 24 */
+    uint32_t cm_autoidle_pll;  /* 30 */
+    uint32_t cm_autoidle2_pll; /* 34 */
+    uint32_t cm_clksel1_pll;   /* 40 */
+    uint32_t cm_clksel2_pll;   /* 44 */
+    uint32_t cm_clksel3_pll;   /* 48 */
+    uint32_t cm_clksel4_pll;   /* 4c */
+    uint32_t cm_clksel5_pll;   /* 50 */
+    uint32_t cm_clkout_ctrl;   /* 70 */
+
+    /* DSS_CM: base + 0x0e00 */
+    uint32_t cm_fclken_dss;    /* 00 */
+    uint32_t cm_iclken_dss;    /* 10 */
+    uint32_t cm_idlest_dss;    /* 20 */
+    uint32_t cm_autoidle_dss;  /* 30 */
+    uint32_t cm_clksel_dss;    /* 40 */
+    uint32_t cm_sleepdep_dss;  /* 44 */
+    uint32_t cm_clkstctrl_dss; /* 48 */
+    uint32_t cm_clkstst_dss;   /* 4c */
+
+   /* CAM_CM: base + 0x0f00 */
+    uint32_t cm_fclken_cam;    /* 00 */
+    uint32_t cm_iclken_cam;    /* 10 */
+    uint32_t cm_idlest_cam;    /* 20 */
+    uint32_t cm_autoidle_cam;  /* 30 */
+    uint32_t cm_clksel_cam;    /* 40 */
+    uint32_t cm_sleepdep_cam;  /* 44 */
+    uint32_t cm_clkstctrl_cam; /* 48 */
+    uint32_t cm_clkstst_cam;   /* 4c */
+
+    /* PER_CM: base + 0x1000 */
+    uint32_t cm_fclken_per;    /* 00 */
+    uint32_t cm_iclken_per;    /* 10 */
+    uint32_t cm_idlest_per;    /* 20 */
+    uint32_t cm_autoidle_per;  /* 30 */
+    uint32_t cm_clksel_per;    /* 40 */
+    uint32_t cm_sleepdep_per;  /* 44 */
+    uint32_t cm_clkstctrl_per; /* 48 */
+    uint32_t cm_clkstst_per;   /* 4c */
+
+    /* EMU_CM: base + 0x1100 */
+    uint32_t cm_clksel1_emu;   /* 40 */
+    uint32_t cm_clkstctrl_emu; /* 48 */
+    uint32_t cm_clkstst_emu;   /* 4c */
+    uint32_t cm_clksel2_emu;   /* 50 */
+    uint32_t cm_clksel3_emu;   /* 54 */
+
+    /* Global_Reg_CM: base + 0x1200 */
+    uint32_t cm_polctrl; /* 9c */
+
+    /* NEON_CM: base + 0x1300 */
+    uint32_t cm_idlest_neon;    /* 20 */
+    uint32_t cm_clkstctrl_neon; /* 48 */
+
+    /* USBHOST_CM: base + 0x1400 */
+    uint32_t cm_fclken_usbhost;    /* 00 */
+    uint32_t cm_iclken_usbhost;    /* 10 */
+    uint32_t cm_idlest_usbhost;    /* 20 */
+    uint32_t cm_autoidle_usbhost;  /* 30 */
+    uint32_t cm_sleepdep_usbhost;  /* 44 */
+    uint32_t cm_clkstctrl_usbhost; /* 48 */
+    uint32_t cm_clkstst_usbhost;   /* 4c */
+};
+
+static inline void omap3_cm_clksel_wkup_update(struct omap3_cm_s *s)
+{
+    omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp1_fclk"),
+                      omap_findclk(s->mpu,
+                                   (s->cm_clksel_wkup & 1) /* CLKSEL_GPT1 */
+                                   ? "omap3_sys_clk"
+                                   : "omap3_32k_fclk"));
+    omap_clk_setrate(omap_findclk(s->mpu, "omap3_rm_iclk"),
+                     (s->cm_clksel_wkup >> 1) & 3, /* CLKSEL_RM */
+                     1);
+
+    /* Tell GPTIMER to generate new clk rate */
+    omap_gp_timer_change_clk(s->mpu->gptimer[0]);
+
+    TRACE("gptimer1 fclk=%lld",
+          omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp1_fclk")));
+
+    /* TODO: CM_USIM_CLK */
+}
+
+static inline void omap3_cm_iva2_update(struct omap3_cm_s *s)
+{
+    uint32_t iva2_dpll_mul = ((s->cm_clksel1_pll_iva2 >> 8) & 0x7ff);
+    uint32_t iva2_dpll_div, iva2_dpll_clkout_div, iva2_clk_src;
+    omap_clk iva2_clk = omap_findclk(s->mpu, "omap3_iva2_clk");
+
+    omap_clk_onoff(iva2_clk, s->cm_fclken_iva2 & 1);
+
+    switch ((s->cm_clken_pll_iva2 & 0x7)) {
+        case 0x01: /* low power stop mode */
+        case 0x05: /* low power bypass mode */
+            s->cm_idlest_pll_iva2 &= ~1;
+            break;
+        case 0x07: /* locked */
+            if (iva2_dpll_mul < 2)
+                s->cm_idlest_pll_iva2 &= ~1;
+            else
+                s->cm_idlest_pll_iva2 |= 1;
+            break;
+        default:
+            break;
+    }
+    
+    if (s->cm_idlest_pll_iva2 & 1) {
+        iva2_dpll_div = s->cm_clksel1_pll_iva2 & 0x7f;
+        iva2_dpll_clkout_div = s->cm_clksel2_pll_iva2 & 0x1f;
+        omap_clk_reparent(iva2_clk, omap_findclk(s->mpu, "omap3_sys_clk"));
+        omap_clk_setrate(iva2_clk,
+                         (iva2_dpll_div + 1) * iva2_dpll_clkout_div,
+                         iva2_dpll_mul);
+    } else {
+        /* bypass mode */
+        iva2_clk_src = (s->cm_clksel1_pll_iva2 >> 19) & 0x07;
+        omap_clk_reparent(iva2_clk, omap_findclk(s->mpu, "omap3_core_clk"));
+        omap_clk_setrate(iva2_clk, iva2_clk_src, 1);
+    }
+}
+
+static inline void omap3_cm_mpu_update(struct omap3_cm_s *s)
+{
+    uint32_t mpu_dpll_mul = ((s->cm_clksel1_pll_mpu >> 8) & 0x7ff);
+    uint32_t mpu_dpll_div, mpu_dpll_clkout_div, mpu_clk_src;
+    omap_clk mpu_clk = omap_findclk(s->mpu, "omap3_mpu_clk");
+    
+    switch ((s->cm_clken_pll_mpu & 0x7)) {
+        case 0x05: /* low power bypass mode */
+            s->cm_idlest_pll_mpu &= ~1;
+            break;
+        case 0x07: /* locked */
+            if (mpu_dpll_mul < 2)
+                s->cm_idlest_pll_mpu &= ~1;
+            else
+                s->cm_idlest_pll_mpu |= 1;
+            break;
+        default:
+            break;
+    }
+    
+    if (s->cm_idlest_pll_mpu & 1) {
+        mpu_dpll_div = s->cm_clksel1_pll_mpu & 0x7f;
+        mpu_dpll_clkout_div = s->cm_clksel2_pll_mpu & 0x1f;
+        omap_clk_reparent(mpu_clk, omap_findclk(s->mpu, "omap3_sys_clk"));
+        omap_clk_setrate(mpu_clk,
+                         (mpu_dpll_div + 1) * mpu_dpll_clkout_div,
+                         mpu_dpll_mul);
+    } else {
+        /* bypass mode */
+        mpu_clk_src = (s->cm_clksel1_pll_mpu >> 19) & 0x07;
+        omap_clk_reparent(mpu_clk, omap_findclk(s->mpu, "omap3_core_clk"));
+        omap_clk_setrate(mpu_clk, mpu_clk_src, 1);
+    }
+}
+
+static inline void omap3_cm_dpll3_update(struct omap3_cm_s *s)
+{
+    uint32_t core_dpll_mul = ((s->cm_clksel1_pll >> 16) & 0x7ff);
+    uint32_t core_dpll_div, core_dpll_clkout_div, div_dpll3;
+
+    switch ((s->cm_clken_pll & 0x7)) {
+        case 0x05: /* low power bypass */
+        case 0x06: /* fast relock bypass */
+            s->cm_idlest_ckgen &= ~1;
+            break;
+        case 0x07: /* locked */
+            if (core_dpll_mul < 2)
+                s->cm_idlest_ckgen &= ~1;
+            else
+                s->cm_idlest_ckgen |= 1;
+            break;
+        default:
+            break;
+    }
+
+    if (s->cm_idlest_ckgen & 1) {
+        core_dpll_div = (s->cm_clksel1_pll >> 8) & 0x7f;
+        core_dpll_clkout_div = (s->cm_clksel1_pll >> 27) & 0x1f;
+        div_dpll3 = (s->cm_clksel1_emu >> 16) & 0x1f;
+        
+        if (s->cm_clksel2_emu & 0x80000) { /* OVERRIDE_ENABLE */
+               core_dpll_mul = (s->cm_clksel2_emu >> 8) & 0x7ff;
+               core_dpll_div = s->cm_clksel2_emu & 0x7f;
+        }
+        
+        omap_clk_setrate(omap_findclk(s->mpu, "omap3_core_clk"),
+                         (core_dpll_div + 1) * core_dpll_clkout_div,
+                         core_dpll_mul);
+        omap_clk_setrate(omap_findclk(s->mpu, "omap3_core2_clk"),
+                         (core_dpll_div + 1) * core_dpll_clkout_div,
+                         core_dpll_mul * 2);
+        omap_clk_setrate(omap_findclk(s->mpu, "omap3_emu_core_alwon_clk"),
+                         (core_dpll_div + 1) * div_dpll3,
+                         core_dpll_mul * 2);
+    } else {
+        /* bypass mode */
+        omap_clk_setrate(omap_findclk(s->mpu, "omap3_core_clk"), 1, 1);
+        omap_clk_setrate(omap_findclk(s->mpu, "omap3_core2_clk"), 1, 1);
+        omap_clk_setrate(omap_findclk(s->mpu, "omap3_emu_core_alwon_clk"), 1, 1);
+    }
+}
+
+static inline void omap3_cm_dpll4_update(struct omap3_cm_s *s)
+{
+    uint32_t per_dpll_mul = ((s->cm_clksel2_pll >> 8) & 0x7ff);
+    uint32_t per_dpll_div, div_96m, clksel_tv, clksel_dss1, clksel_cam, div_dpll4;
+
+    switch (((s->cm_clken_pll >> 16) & 0x7)) {
+        case 0x01: /* lower power stop mode */
+            s->cm_idlest_ckgen &= ~2;
+            break;
+        case 0x07: /* locked */
+            if (per_dpll_mul < 2)
+                s->cm_idlest_ckgen &= ~2;
+            else
+                s->cm_idlest_ckgen |= 2;
+            break;
+        default:
+            break;
+    }
+
+    if (s->cm_idlest_ckgen & 2) {
+        per_dpll_div = s->cm_clksel2_pll & 0x7f;
+        div_96m = s->cm_clksel3_pll & 0x1f;
+        clksel_tv = (s->cm_clksel_dss >> 8) & 0x1f;
+        clksel_dss1 = s->cm_clksel_dss & 0x1f;
+        clksel_cam = s->cm_clksel_cam & 0x1f;
+        div_dpll4 = (s->cm_clksel1_emu >> 24) & 0x1f;
+        
+        if (s->cm_clksel3_emu & 0x80000) { /* OVERRIDE_ENABLE */
+               per_dpll_mul = (s->cm_clksel3_emu >> 8) & 0x7ff;
+               per_dpll_div =  s->cm_clksel3_emu & 0x7f;
+        }
+        
+        omap_clk_setrate(omap_findclk(s->mpu, "omap3_96m_fclk"),
+                         (per_dpll_div + 1) * div_96m,
+                         per_dpll_mul * 2);
+        omap_clk_setrate(omap_findclk(s->mpu, "omap3_54m_fclk"),
+                         (per_dpll_div + 1) * clksel_tv,
+                         per_dpll_mul * 2);
+        omap_clk_setrate(omap_findclk(s->mpu, "omap3_dss1_alwon_fclk"),
+                         (per_dpll_div + 1) * clksel_dss1,
+                         per_dpll_mul * 2);
+        omap_clk_setrate(omap_findclk(s->mpu, "omap3_cam_mclk"),
+                         (per_dpll_div + 1) * clksel_cam,
+                         per_dpll_mul * 2);
+        omap_clk_setrate(omap_findclk(s->mpu, "omap3_per_alwon_clk"),
+                         (per_dpll_div + 1) * div_dpll4,
+                         per_dpll_mul * 2);
+    } else {
+        /* bypass mode */
+        omap_clk_setrate(omap_findclk(s->mpu, "omap3_96m_fclk"), 1, 1);
+        omap_clk_setrate(omap_findclk(s->mpu, "omap3_54m_fclk"), 1, 1);
+        omap_clk_setrate(omap_findclk(s->mpu, "omap3_dss1_alwon_fclk"), 1, 1);
+        omap_clk_setrate(omap_findclk(s->mpu, "omap3_cam_mclk"), 1, 1);
+        omap_clk_setrate(omap_findclk(s->mpu, "omap3_per_alwon_clk"), 1, 1);
+    }
+}
+
+static inline void omap3_cm_dpll5_update(struct omap3_cm_s *s)
+{
+    uint32_t per2_dpll_mul = ((s->cm_clksel4_pll >> 8) & 0x7ff);
+    uint32_t per2_dpll_div, div_120m;
+
+    switch ((s->cm_clken2_pll & 0x7)) {
+        case 0x01: /* low power stop mode */
+            s->cm_idlest2_ckgen &= ~1;
+            break;
+        case 0x07: /* locked */
+            if (per2_dpll_mul < 2)
+                s->cm_idlest2_ckgen &= ~1;
+            else
+                s->cm_idlest2_ckgen |= 1;
+            break;
+        default:
+            break;
+    }
+
+    if (s->cm_idlest2_ckgen & 1) {
+        per2_dpll_div = s->cm_clksel4_pll & 0x7f;
+        div_120m = s->cm_clksel5_pll & 0x1f;
+        
+        omap_clk_setrate(omap_findclk(s->mpu, "omap3_120m_fclk"),
+                         (per2_dpll_div + 1) * div_120m,
+                         per2_dpll_mul);
+    } else {
+        /* bypass mode */
+        omap_clk_setrate(omap_findclk(s->mpu, "omap3_120m_fclk"), 1, 1);
+    }
+}
+
+static inline void omap3_cm_48m_update(struct omap3_cm_s *s)
+{
+    omap_clk pclk = omap_findclk(s->mpu,
+                                 (s->cm_clksel1_pll & 0x8) /* SOURCE_48M */
+                                 ? "omap3_sys_altclk"
+                                 : "omap3_96m_fclk");
+    
+    omap_clk_reparent(omap_findclk(s->mpu, "omap3_48m_fclk"), pclk);
+    omap_clk_reparent(omap_findclk(s->mpu, "omap3_12m_fclk"), pclk);
+}
+
+static inline void omap3_cm_gp10gp11_update(struct omap3_cm_s *s)
+{
+    omap_clk gp10 = omap_findclk(s->mpu, "omap3_gp10_fclk");
+    omap_clk gp11 = omap_findclk(s->mpu, "omap3_gp11_fclk");
+    omap_clk sys  = omap_findclk(s->mpu, "omap3_sys_clk");
+    omap_clk f32k = omap_findclk(s->mpu, "omap3_32k_fclk");
+
+    omap_clk_reparent(gp10, (s->cm_clksel_core & 0x40) ? sys : f32k);
+    omap_clk_reparent(gp11, (s->cm_clksel_core & 0x80) ? sys : f32k);
+    omap_gp_timer_change_clk(s->mpu->gptimer[9]);
+    omap_gp_timer_change_clk(s->mpu->gptimer[10]);
+    
+    TRACE("gptimer10 fclk = %lld", omap_clk_getrate(gp10));
+    TRACE("gptimer11 fclk = %lld", omap_clk_getrate(gp11));
+}
+
+static inline void omap3_cm_per_gptimer_update(struct omap3_cm_s *s)
+{
+    omap_clk sys = omap_findclk(s->mpu, "omap3_sys_clk");
+    omap_clk f32k = omap_findclk(s->mpu, "omap3_32k_fclk");
+    uint32_t cm_clksel_per = s->cm_clksel_per;
+    uint32_t n;
+    char clkname[] = "omap3_gp#_fclk";
+
+    for (n = 1; n < 9; n++, cm_clksel_per >>= 1) {
+        clkname[8] = '1' + n; /* 2 - 9 */
+        omap_clk_reparent(omap_findclk(s->mpu, clkname),
+                          (cm_clksel_per & 1) ? sys : f32k);
+        omap_gp_timer_change_clk(s->mpu->gptimer[n]);
+        TRACE("gptimer%d fclk = %lld", n + 1,
+              omap_clk_getrate(omap_findclk(s->mpu, clkname)));
+    }
+}
+
+static inline void omap3_cm_clkout2_update(struct omap3_cm_s *s)
+{
+    omap_clk c = omap_findclk(s->mpu, "omap3_sys_clkout2");
+       
+    omap_clk_onoff(c, (s->cm_clkout_ctrl >> 7) & 1);
+    switch (s->cm_clkout_ctrl & 0x3) {
+        case 0:
+            omap_clk_reparent(c, omap_findclk(s->mpu, "omap3_core_clk"));
+            break;
+        case 1:
+            omap_clk_reparent(c, omap_findclk(s->mpu, "omap3_sys_clk"));
+            break;
+        case 2:
+            omap_clk_reparent(c, omap_findclk(s->mpu, "omap3_96m_fclk"));
+            break;
+        case 3:
+            omap_clk_reparent(c, omap_findclk(s->mpu, "omap3_54m_fclk"));
+            break;
+        default:
+            break;
+    }
+    omap_clk_setrate(c, 1 << ((s->cm_clkout_ctrl >> 3) & 7), 1);
+}
+
+static inline void omap3_cm_fclken1_core_update(struct omap3_cm_s *s)
+{
+    uint32_t v = s->cm_fclken1_core;
+    
+    /* TODO: EN_MCBSP1,5 */
+    omap_clk_onoff(omap_findclk(s->mpu, "omap3_gp10_fclk"),  (v >> 11) & 1);
+    omap_clk_onoff(omap_findclk(s->mpu, "omap3_gp11_fclk"),  (v >> 12) & 1);
+    omap_clk_onoff(omap_findclk(s->mpu, "omap3_uart1_fclk"), (v >> 13) & 1);
+    omap_clk_onoff(omap_findclk(s->mpu, "omap3_uart2_fclk"), (v >> 14) & 1);
+    omap_clk_onoff(omap_findclk(s->mpu, "omap3_i2c1_fclk"),  (v >> 15) & 1);
+    omap_clk_onoff(omap_findclk(s->mpu, "omap3_i2c2_fclk"),  (v >> 16) & 1);
+    omap_clk_onoff(omap_findclk(s->mpu, "omap3_i2c3_fclk"),  (v >> 17) & 1);
+    /* TODO: EN_HDQ, EN_SPI1-4 */
+    omap_clk_onoff(omap_findclk(s->mpu, "omap3_mmc1_fclk"),  (v >> 24) & 1);
+    omap_clk_onoff(omap_findclk(s->mpu, "omap3_mmc2_fclk"),  (v >> 25) & 1);
+    omap_clk_onoff(omap_findclk(s->mpu, "omap3_mmc3_fclk"),  (v >> 30) & 1);
+}
+
+static inline void omap3_cm_iclken1_core_update(struct omap3_cm_s *s)
+{
+    uint32_t v = s->cm_iclken1_core;
+    
+    /* TODO: EN_SDRC, EN_HSOTGUSB, EN_OMAPCTRL, EN_MAILBOXES, EN_MCBSP1,5 */
+    /* TODO: EN_GPT10, EN_GPT11 */
+    omap_clk_onoff(omap_findclk(s->mpu, "omap3_uart1_iclk"), (v >> 13) & 1);
+    omap_clk_onoff(omap_findclk(s->mpu, "omap3_uart2_iclk"), (v >> 14) & 1);
+    omap_clk_onoff(omap_findclk(s->mpu, "omap3_i2c1_iclk"),  (v >> 15) & 1);
+    omap_clk_onoff(omap_findclk(s->mpu, "omap3_i2c2_iclk"),  (v >> 16) & 1);
+    omap_clk_onoff(omap_findclk(s->mpu, "omap3_i2c3_iclk"),  (v >> 17) & 1);
+    /* TODO: EN_HDQ, EN_SPI1-4 */
+    omap_clk_onoff(omap_findclk(s->mpu, "omap3_mmc1_iclk"),  (v >> 24) & 1);
+    omap_clk_onoff(omap_findclk(s->mpu, "omap3_mmc2_iclk"),  (v >> 25) & 1);
+    omap_clk_onoff(omap_findclk(s->mpu, "omap3_mmc3_iclk"),  (v >> 30) & 1);
+    /* set USB OTG idle if iclk is enabled and SDMA always in standby */
+    v &= ~0x24;
+    v |= (v & 0x10) << 1;
+    s->cm_idlest1_core = ~v;
+}
+
+static inline void omap3_cm_l3l4iclk_update(struct omap3_cm_s *s)
+{
+    omap_clk_setrate(omap_findclk(s->mpu, "omap3_l3_iclk"),
+                     s->cm_clksel_core & 0x3, 1);
+    omap_clk_setrate(omap_findclk(s->mpu, "omap3_l4_iclk"),
+                     (s->cm_clksel_core >> 2) & 0x3, 1);
+}
+
+static void omap3_cm_reset(struct omap3_cm_s *s)
+{
+    s->cm_fclken_iva2 = 0x0;
+    s->cm_clken_pll_iva2 = 0x11;
+    s->cm_idlest_iva2 = 0x1;
+    s->cm_idlest_pll_iva2 = 0;
+    s->cm_autoidle_pll_iva2 = 0x0;
+    s->cm_clksel1_pll_iva2 = 0x80000;
+    s->cm_clksel2_pll_iva2 = 0x1;
+    s->cm_clkstctrl_iva2 = 0x0;
+    s->cm_clkstst_iva2 = 0x0;
+
+    s->cm_revision = 0x10;
+    s->cm_sysconfig = 0x1;
+
+    s->cm_clken_pll_mpu = 0x15;
+    s->cm_idlest_mpu = 0x1;
+    s->cm_idlest_pll_mpu = 0;
+    s->cm_autoidle_pll_mpu = 0x0;
+    s->cm_clksel1_pll_mpu = 0x80000;
+    s->cm_clksel2_pll_mpu = 0x1;
+    s->cm_clkstctrl_mpu = 0x0;
+    s->cm_clkstst_mpu = 0x0;
+
+    s->cm_fclken1_core = 0x0;
+    s->cm_fclken3_core = 0x0;
+    s->cm_iclken1_core = 0x42;
+    s->cm_iclken2_core = 0x0;
+    s->cm_iclken3_core = 0x0;
+    /*allow access to devices*/
+    s->cm_idlest1_core = 0x0;
+    s->cm_idlest2_core = 0x0;
+    /*ide status =0 */
+    s->cm_idlest3_core = 0xa; 
+    s->cm_autoidle1_core = 0x0;
+    s->cm_autoidle2_core = 0x0;
+    s->cm_autoidle3_core = 0x0;
+    s->cm_clksel_core = 0x105;
+    s->cm_clkstctrl_core = 0x0;
+    s->cm_clkstst_core = 0x0;
+
+    s->cm_fclken_sgx = 0x0;
+    s->cm_iclken_sgx = 0x0;
+    s->cm_idlest_sgx = 0x1;
+    s->cm_clksel_sgx = 0x0;
+    s->cm_sleepdep_sgx = 0x0;
+    s->cm_clkstctrl_sgx = 0x0;
+    s->cm_clkstst_sgx = 0x0;
+
+    s->cm_fclken_wkup = 0x0;
+    s->cm_iclken_wkup = 0x0;
+    /*assume all clock can be accessed*/
+    s->cm_idlest_wkup = 0x0;
+    s->cm_autoidle_wkup = 0x0;
+    s->cm_clksel_wkup = 0x12;
+
+    s->cm_clken_pll = 0x110015;
+    s->cm_clken2_pll = 0x11;
+    s->cm_idlest_ckgen = 0x3f3c; /* FIXME: provide real clock statuses */
+    s->cm_idlest2_ckgen = 0xa; /* FIXME: provide real clock statuses */
+    s->cm_autoidle_pll = 0x0;
+    s->cm_autoidle2_pll = 0x0;
+    s->cm_clksel1_pll = 0x8000040;
+    s->cm_clksel2_pll = 0x0;
+    s->cm_clksel3_pll = 0x1;
+    s->cm_clksel4_pll = 0x0;
+    s->cm_clksel5_pll = 0x1;
+    s->cm_clkout_ctrl = 0x3;
+
+
+    s->cm_fclken_dss = 0x0;
+    s->cm_iclken_dss = 0x0;
+    /*dss can be accessed*/
+    s->cm_idlest_dss = 0x0;
+    s->cm_autoidle_dss = 0x0;
+    s->cm_clksel_dss = 0x1010;
+    s->cm_sleepdep_dss = 0x0;
+    s->cm_clkstctrl_dss = 0x0;
+    s->cm_clkstst_dss = 0x0;
+
+    s->cm_fclken_cam = 0x0;
+    s->cm_iclken_cam = 0x0;
+    s->cm_idlest_cam = 0x1;
+    s->cm_autoidle_cam = 0x0;
+    s->cm_clksel_cam = 0x10;
+    s->cm_sleepdep_cam = 0x0;
+    s->cm_clkstctrl_cam = 0x0;
+    s->cm_clkstst_cam = 0x0;
+
+    s->cm_fclken_per = 0x0;
+    s->cm_iclken_per = 0x0;
+    //s->cm_idlest_per = 0x3ffff;
+    s->cm_idlest_per = 0x0; //enable GPIO access
+    s->cm_autoidle_per = 0x0;
+    s->cm_clksel_per = 0x0;
+    s->cm_sleepdep_per = 0x0;
+    s->cm_clkstctrl_per = 0x0;
+    s->cm_clkstst_per = 0x0;
+
+    s->cm_clksel1_emu = 0x10100a50;
+    s->cm_clkstctrl_emu = 0x2;
+    s->cm_clkstst_emu = 0x0;
+    s->cm_clksel2_emu = 0x0;
+    s->cm_clksel3_emu = 0x0;
+
+    s->cm_polctrl = 0x0;
+
+    s->cm_idlest_neon = 0x1;
+    s->cm_clkstctrl_neon = 0x0;
+
+    s->cm_fclken_usbhost = 0x0;
+    s->cm_iclken_usbhost = 0x0;
+    s->cm_idlest_usbhost = 0x3;
+    s->cm_autoidle_usbhost = 0x0;
+    s->cm_sleepdep_usbhost = 0x0;
+    s->cm_clkstctrl_usbhost = 0x0;
+    s->cm_clkstst_usbhost = 0x0;
+}
+
+static uint32_t omap3_cm_read(void *opaque, target_phys_addr_t addr)
+{
+    struct omap3_cm_s *s = (struct omap3_cm_s *) opaque;
+
+    switch (addr) {
+        /* IVA2_CM */
+        case 0x0000: return s->cm_fclken_iva2;
+        case 0x0004: return s->cm_clken_pll_iva2;
+        case 0x0020: return s->cm_idlest_iva2;
+        case 0x0024: return s->cm_idlest_pll_iva2;
+        case 0x0034: return s->cm_autoidle_pll_iva2;
+        case 0x0040: return s->cm_clksel1_pll_iva2;
+        case 0x0044: return s->cm_clksel2_pll_iva2;
+        case 0x0048: return s->cm_clkstctrl_iva2;
+        case 0x004c: return s->cm_clkstst_iva2;
+        /* OCP_System_Reg_CM */
+        case 0x0800: return s->cm_revision;
+        case 0x0810: return s->cm_sysconfig;
+        /* MPU_CM */
+        case 0x0904: return s->cm_clken_pll_mpu;
+        case 0x0920: return s->cm_idlest_mpu & 0x0; /*MPU is active*/
+        case 0x0924: return s->cm_idlest_pll_mpu;
+        case 0x0934: return s->cm_autoidle_pll_mpu;
+        case 0x0940: return s->cm_clksel1_pll_mpu;
+        case 0x0944: return s->cm_clksel2_pll_mpu;
+        case 0x0948: return s->cm_clkstctrl_mpu;
+        case 0x094c: return s->cm_clkstst_mpu;
+        /* CORE_CM */
+        case 0x0a00: return s->cm_fclken1_core;
+        case 0x0a08: return s->cm_fclken3_core;
+        case 0x0a10: return s->cm_iclken1_core;
+        case 0x0a14: return s->cm_iclken2_core;
+        case 0x0a20: return s->cm_idlest1_core;
+        case 0x0a24: return s->cm_idlest2_core;
+        case 0x0a28: return s->cm_idlest3_core;
+        case 0x0a30: return s->cm_autoidle1_core;
+        case 0x0a34: return s->cm_autoidle2_core;
+        case 0x0a38: return s->cm_autoidle3_core;
+        case 0x0a40: return s->cm_clksel_core;
+        case 0x0a48: return s->cm_clkstctrl_core;
+        case 0x0a4c: return s->cm_clkstst_core;
+        /* SGX_CM */
+        case 0x0b00: return s->cm_fclken_sgx;
+        case 0x0b10: return s->cm_iclken_sgx;
+        case 0x0b20: return s->cm_idlest_sgx & 0x0;
+        case 0x0b40: return s->cm_clksel_sgx;
+        case 0x0b48: return s->cm_clkstctrl_sgx;
+        case 0x0b4c: return s->cm_clkstst_sgx;
+        /* WKUP_CM */
+        case 0x0c00: return s->cm_fclken_wkup;
+        case 0x0c10: return s->cm_iclken_wkup;
+        case 0x0c20: return 0; /* TODO: Check if the timer can be accessed. */
+        case 0x0c30: return s->cm_idlest_wkup;
+        case 0x0c40: return s->cm_clksel_wkup;
+        case 0x0c48: return s->cm_c48;
+        /* Clock_Control_Reg_CM */
+        case 0x0d00: return s->cm_clken_pll;
+        case 0x0d04: return s->cm_clken2_pll;
+        case 0x0d20: return s->cm_idlest_ckgen;
+        case 0x0d24: return s->cm_idlest2_ckgen;
+        case 0x0d30: return s->cm_autoidle_pll;
+        case 0x0d34: return s->cm_autoidle2_pll;
+        case 0x0d40: return s->cm_clksel1_pll;
+        case 0x0d44: return s->cm_clksel2_pll;
+        case 0x0d48: return s->cm_clksel3_pll;
+        case 0x0d4c: return s->cm_clksel4_pll;
+        case 0x0d50: return s->cm_clksel5_pll;
+        case 0x0d70: return s->cm_clkout_ctrl;
+        /* DSS_CM */
+        case 0x0e00: return s->cm_fclken_dss;
+        case 0x0e10: return s->cm_iclken_dss;
+        case 0x0e20: return s->cm_idlest_dss;
+        case 0x0e30: return s->cm_autoidle_dss;
+        case 0x0e40: return s->cm_clksel_dss;
+        case 0x0e44: return s->cm_sleepdep_dss;
+        case 0x0e48: return s->cm_clkstctrl_dss;
+        case 0x0e4c: return s->cm_clkstst_dss;
+        /* CAM_CM */
+        case 0x0f00: return s->cm_fclken_cam;
+        case 0x0f10: return s->cm_iclken_cam;
+        case 0x0f20: return s->cm_idlest_cam & 0x0;
+        case 0x0f30: return s->cm_autoidle_cam;
+        case 0x0f40: return s->cm_clksel_cam;
+        case 0x0f44: return s->cm_sleepdep_cam;
+        case 0x0f48: return s->cm_clkstctrl_cam;
+        case 0x0f4c: return s->cm_clkstst_cam;
+        /* PER_CM */
+        case 0x1000: return s->cm_fclken_per;
+        case 0x1010: return s->cm_iclken_per;
+        case 0x1020: return s->cm_idlest_per ;
+        case 0x1030: return s->cm_autoidle_per;
+        case 0x1040: return s->cm_clksel_per;
+        case 0x1044: return s->cm_sleepdep_per;
+        case 0x1048: return s->cm_clkstctrl_per;
+        case 0x104c: return s->cm_clkstst_per;
+        /* EMU_CM */
+        case 0x1140: return s->cm_clksel1_emu;
+        case 0x1148: return s->cm_clkstctrl_emu;
+        case 0x114c: return s->cm_clkstst_emu & 0x0;
+        case 0x1150: return s->cm_clksel2_emu;
+        case 0x1154: return s->cm_clksel3_emu;
+        /* Global_Reg_CM */
+        case 0x129c: return s->cm_polctrl;
+        /* NEON_CM */
+        case 0x1320: return s->cm_idlest_neon & 0x0;
+        case 0x1348: return s->cm_clkstctrl_neon;
+        /* USBHOST_CM */
+        case 0x1400: return s->cm_fclken_usbhost;
+        case 0x1410: return s->cm_iclken_usbhost;
+        case 0x1420: return s->cm_idlest_usbhost & 0x0;
+        case 0x1430: return s->cm_autoidle_usbhost;
+        case 0x1444: return s->cm_sleepdep_usbhost;
+        case 0x1448: return s->cm_clkstctrl_usbhost;
+        case 0x144c: return s->cm_clkstst_usbhost;
+        /* unknown */
+        default: break;
+    }
+    OMAP_BAD_REG(addr);
+    return 0;
+}
+
+static void omap3_cm_write(void *opaque,
+                           target_phys_addr_t addr,
+                           uint32_t value)
+{
+    struct omap3_cm_s *s = (struct omap3_cm_s *)opaque;
+
+    switch (addr) {
+        case 0x0020:
+        case 0x0024:
+        case 0x004c:
+        case 0x0800:
+        case 0x0920:
+        case 0x0924:
+        case 0x094c:
+        case 0x0a20:
+        case 0x0a24:
+        case 0x0a28:
+        case 0x0a4c:
+        case 0x0b20:
+        case 0x0b4c:
+        case 0x0c20:
+        case 0x0d20:
+        case 0x0d24:
+        case 0x0e20:
+        case 0x0e4c:
+        case 0x0f20:
+        case 0x0f4c:
+        case 0x1020:
+        case 0x104c:
+        case 0x114c:
+        case 0x1320:
+        case 0x1420:
+        case 0x144c:
+            OMAP_RO_REGV(addr, value);
+            break;
+        /* IVA2_CM */
+        case 0x0000:
+            s->cm_fclken_iva2 = value & 0x1;
+            omap3_cm_iva2_update(s);
+            break;
+        case 0x0004: 
+            s->cm_clken_pll_iva2 = value & 0x7ff;
+            omap3_cm_iva2_update(s);
+            break;
+        case 0x0034:
+            s->cm_autoidle_pll_iva2 = value & 0x7;
+            break;
+        case 0x0040:
+            s->cm_clksel1_pll_iva2 = value & 0x3fff7f;
+            omap3_cm_iva2_update(s);
+            break;
+        case 0x0044:
+            s->cm_clksel2_pll_iva2 = value & 0x1f;
+            omap3_cm_iva2_update(s);
+            break;
+        case 0x0048:
+            s->cm_clkstctrl_iva2 = value & 0x3;
+            break;
+        /* OCP_System_Reg_CM */
+        case 0x0810:
+            s->cm_sysconfig = value & 0x1;
+            break;
+        /* MPU_CM */
+        case 0x0904:
+            s->cm_clken_pll_mpu = value & 0x7ff;
+            omap3_cm_mpu_update(s);
+            break;
+        case 0x0934:
+            s->cm_autoidle_pll_mpu = value & 0x7;
+            break;
+        case 0x0940:
+            s->cm_clksel1_pll_mpu = value & 0x3fff7f;
+            omap3_cm_mpu_update(s);
+            break;
+        case 0x0944:
+            s->cm_clksel2_pll_mpu = value & 0x1f;
+            omap3_cm_mpu_update(s);
+            break;
+        case 0x0948:
+            s->cm_clkstctrl_mpu = value & 0x3;
+            break;
+        /* CORE_CM */
+        case 0xa00:
+            s->cm_fclken1_core = value & 0x43fffe00;
+            omap3_cm_fclken1_core_update(s);
+            break;
+        case 0xa08:
+            s->cm_fclken3_core = value & 0x7;
+            /* TODO: EN_USBTLL, EN_TS */
+            break;
+        case 0xa10:
+            s->cm_iclken1_core = value & 0x637ffed2;
+            omap3_cm_iclken1_core_update(s);
+            break;
+        case 0xa14:
+            s->cm_iclken2_core = value & 0x1f;
+            break;
+        case 0xa18:
+            s->cm_iclken3_core = value & 0x4;
+            s->cm_idlest3_core = 0xd & ~(s->cm_iclken3_core & 4);
+            break;
+        case 0xa30:
+            s->cm_autoidle1_core = value & 0x7ffffed0;
+            break;
+        case 0xa34:
+            s->cm_autoidle2_core = value & 0x1f;
+            break;
+        case 0xa38:
+            s->cm_autoidle3_core = value & 0x2;
+            break;
+        case 0xa40:
+            s->cm_clksel_core = (value & 0xff) | 0x100;
+            omap3_cm_gp10gp11_update(s);
+            omap3_cm_l3l4iclk_update(s);
+            break;
+        case 0xa48:
+            s->cm_clkstctrl_core = value & 0xf;
+            break;
+        /* SGX_CM */
+        case 0xb00: s->cm_fclken_sgx = value & 0x2; break;
+        case 0xb10: s->cm_iclken_sgx = value & 0x1; break;
+        case 0xb40: s->cm_clksel_sgx = value; break; /* TODO: SGX clock */
+        case 0xb44: s->cm_sleepdep_sgx = value &0x2; break;
+        case 0xb48: s->cm_clkstctrl_sgx = value & 0x3; break;
+        /* WKUP_CM */
+        case 0xc00:
+            s->cm_fclken_wkup = value & 0x2e9;
+            omap_clk_onoff(omap_findclk(s->mpu, "omap3_gp1_fclk"),
+                           s->cm_fclken_wkup & 1);
+            /* TODO: EN_GPIO1 */
+            /* TODO: EN_WDT2 */
+            break;
+        case 0xc10:
+            s->cm_iclken_wkup = value & 0x23f;
+            omap_clk_onoff(omap_findclk(s->mpu, "omap3_wkup_l4_iclk"),
+                           s->cm_iclken_wkup ? 1 : 0);
+            break;
+        case 0xc30: s->cm_autoidle_wkup = value & 0x23f; break;
+        case 0xc40:
+            s->cm_clksel_wkup = value & 0x7f;
+            omap3_cm_clksel_wkup_update(s);
+            break;
+        /* Clock_Control_Reg_CM */
+        case 0xd00:
+            s->cm_clken_pll = value & 0xffff17ff;
+            omap3_cm_dpll3_update(s);
+            omap3_cm_dpll4_update(s);
+            break;
+        case 0xd04:
+            s->cm_clken2_pll = value & 0x7ff;
+            omap3_cm_dpll5_update(s);
+            break;
+        case 0xd30: s->cm_autoidle_pll = value & 0x3f; break;
+        case 0xd34: s->cm_autoidle2_pll = value & 0x7; break;
+        case 0xd40:
+            s->cm_clksel1_pll = value & 0xffffbffc;
+            omap3_cm_dpll3_update(s);
+            omap3_cm_48m_update(s);
+            /* TODO: 96m and 54m update */
+            break;
+        case 0xd44:
+            s->cm_clksel2_pll = value & 0x7ff7f;
+            omap3_cm_dpll4_update(s);
+            break;
+        case 0xd48:
+            s->cm_clksel3_pll = value & 0x1f;
+            omap3_cm_dpll4_update(s);
+            break;
+        case 0xd4c:
+            s->cm_clksel4_pll = value & 0x7ff7f;
+            omap3_cm_dpll5_update(s);
+            break;
+        case 0xd50:
+            s->cm_clksel5_pll = value & 0x1f;
+            omap3_cm_dpll5_update(s);
+            break;
+        case 0xd70:
+            s->cm_clkout_ctrl = value & 0xbb;
+            omap3_cm_clkout2_update(s);
+            break;
+        /* DSS_CM */
+        case 0xe00: s->cm_fclken_dss = value & 0x7; break;
+        case 0xe10: s->cm_iclken_dss = value & 0x1; break;
+        case 0xe30: s->cm_autoidle_dss = value & 0x1; break;
+        case 0xe40:
+            s->cm_clksel_dss = value & 0x1f1f;
+            omap3_cm_dpll4_update(s);
+            break;
+        case 0xe44: s->cm_sleepdep_dss = value & 0x7; break;
+        case 0xe48: s->cm_clkstctrl_dss = value & 0x3; break;
+        /* CAM_CM */
+        case 0xf00: s->cm_fclken_cam = value & 0x3; break;
+        case 0xf10: s->cm_iclken_cam = value & 0x1; break;
+        case 0xf30: s->cm_autoidle_cam = value & 0x1; break;
+        case 0xf40:
+            s->cm_clksel_cam = value & 0x1f;
+            omap3_cm_dpll4_update(s);
+            break;
+        case 0xf44: s->cm_sleepdep_cam = value & 0x2; break;
+        case 0xf48: s->cm_clkstctrl_cam = value & 0x3; break;
+        /* PER_CM */
+        case 0x1000: s->cm_fclken_per = value & 0x3ffff; break;
+        case 0x1010: s->cm_iclken_per = value & 0x3ffff; break;
+        case 0x1030: s->cm_autoidle_per = value &0x3ffff; break;
+        case 0x1040:
+            s->cm_clksel_per = value & 0xff;
+            omap3_cm_per_gptimer_update(s);
+            break;
+        case 0x1044: s->cm_sleepdep_per = value & 0x6; break;
+        case 0x1048: s->cm_clkstctrl_per = value &0x7; break;
+        /* EMU_CM */
+        case 0x1140:
+            s->cm_clksel1_emu = value & 0x1f1f3fff;
+            omap3_cm_dpll3_update(s);
+            omap3_cm_dpll4_update(s);
+            break;
+        case 0x1148: s->cm_clkstctrl_emu = value & 0x3; break;
+        case 0x1150:
+            s->cm_clksel2_emu = value & 0xfff7f;
+            omap3_cm_dpll3_update(s);
+            break;
+        case 0x1154:
+            s->cm_clksel3_emu = value & 0xfff7f;
+            omap3_cm_dpll4_update(s);
+            break;
+        /* Global_Reg_CM */
+        case 0x129c: s->cm_polctrl = value & 0x1; break;
+        /* NEON_CM */
+        case 0x1348: s->cm_clkstctrl_neon = value & 0x3; break;
+        /* USBHOST_CM */
+        case 0x1400: s->cm_fclken_usbhost = value & 0x3; break;
+        case 0x1410: s->cm_iclken_usbhost = value & 0x1; break;
+        case 0x1430: s->cm_autoidle_usbhost = value & 0x1; break;
+        case 0x1444: s->cm_sleepdep_usbhost = value & 0x6; break;
+        case 0x1448: s->cm_clkstctrl_usbhost = value & 0x3; break;
+        /* unknown */
+        default:
+            OMAP_BAD_REGV(addr, value);
+            break;
+    }
+}
+
+static void omap3_cm_save_state(QEMUFile *f, void *opaque)
+{
+    struct omap3_cm_s *s = (struct omap3_cm_s *)opaque;
+    
+    qemu_put_be32(f, s->cm_fclken_iva2);
+    qemu_put_be32(f, s->cm_clken_pll_iva2);
+    qemu_put_be32(f, s->cm_idlest_iva2);
+    qemu_put_be32(f, s->cm_idlest_pll_iva2);
+    qemu_put_be32(f, s->cm_autoidle_pll_iva2);
+    qemu_put_be32(f, s->cm_clksel1_pll_iva2);
+    qemu_put_be32(f, s->cm_clksel2_pll_iva2);
+    qemu_put_be32(f, s->cm_clkstctrl_iva2);
+    qemu_put_be32(f, s->cm_clkstst_iva2);
+    
+    qemu_put_be32(f, s->cm_revision);
+    qemu_put_be32(f, s->cm_sysconfig);
+    
+    qemu_put_be32(f, s->cm_clken_pll_mpu);
+    qemu_put_be32(f, s->cm_idlest_mpu);
+    qemu_put_be32(f, s->cm_idlest_pll_mpu);
+    qemu_put_be32(f, s->cm_autoidle_pll_mpu);
+    qemu_put_be32(f, s->cm_clksel1_pll_mpu);
+    qemu_put_be32(f, s->cm_clksel2_pll_mpu);
+    qemu_put_be32(f, s->cm_clkstctrl_mpu);
+    qemu_put_be32(f, s->cm_clkstst_mpu);
+    
+    qemu_put_be32(f, s->cm_fclken1_core);
+    qemu_put_be32(f, s->cm_fclken3_core);
+    qemu_put_be32(f, s->cm_iclken1_core);
+    qemu_put_be32(f, s->cm_iclken2_core);
+    qemu_put_be32(f, s->cm_iclken3_core);
+    qemu_put_be32(f, s->cm_idlest1_core);
+    qemu_put_be32(f, s->cm_idlest2_core);
+    qemu_put_be32(f, s->cm_idlest3_core);
+    qemu_put_be32(f, s->cm_autoidle1_core);
+    qemu_put_be32(f, s->cm_autoidle2_core);
+    qemu_put_be32(f, s->cm_autoidle3_core);
+    qemu_put_be32(f, s->cm_clksel_core);
+    qemu_put_be32(f, s->cm_clkstctrl_core);
+    qemu_put_be32(f, s->cm_clkstst_core);
+    
+    qemu_put_be32(f, s->cm_fclken_sgx);
+    qemu_put_be32(f, s->cm_iclken_sgx);
+    qemu_put_be32(f, s->cm_idlest_sgx);
+    qemu_put_be32(f, s->cm_clksel_sgx);
+    qemu_put_be32(f, s->cm_sleepdep_sgx);
+    qemu_put_be32(f, s->cm_clkstctrl_sgx);
+    qemu_put_be32(f, s->cm_clkstst_sgx);
+    
+    qemu_put_be32(f, s->cm_fclken_wkup);
+    qemu_put_be32(f, s->cm_iclken_wkup);
+    qemu_put_be32(f, s->cm_idlest_wkup);
+    qemu_put_be32(f, s->cm_autoidle_wkup);
+    qemu_put_be32(f, s->cm_clksel_wkup);
+    qemu_put_be32(f, s->cm_c48);
+    
+    qemu_put_be32(f, s->cm_clken_pll);
+    qemu_put_be32(f, s->cm_clken2_pll);
+    qemu_put_be32(f, s->cm_idlest_ckgen);
+    qemu_put_be32(f, s->cm_idlest2_ckgen);
+    qemu_put_be32(f, s->cm_autoidle_pll);
+    qemu_put_be32(f, s->cm_autoidle2_pll);
+    qemu_put_be32(f, s->cm_clksel1_pll);
+    qemu_put_be32(f, s->cm_clksel2_pll);
+    qemu_put_be32(f, s->cm_clksel3_pll);
+    qemu_put_be32(f, s->cm_clksel4_pll);
+    qemu_put_be32(f, s->cm_clksel5_pll);
+    qemu_put_be32(f, s->cm_clkout_ctrl);
+    
+    qemu_put_be32(f, s->cm_fclken_dss);
+    qemu_put_be32(f, s->cm_iclken_dss);
+    qemu_put_be32(f, s->cm_idlest_dss);
+    qemu_put_be32(f, s->cm_autoidle_dss);
+    qemu_put_be32(f, s->cm_clksel_dss);
+    qemu_put_be32(f, s->cm_sleepdep_dss);
+    qemu_put_be32(f, s->cm_clkstctrl_dss);
+    qemu_put_be32(f, s->cm_clkstst_dss);
+    
+    qemu_put_be32(f, s->cm_fclken_cam);
+    qemu_put_be32(f, s->cm_iclken_cam);
+    qemu_put_be32(f, s->cm_idlest_cam);
+    qemu_put_be32(f, s->cm_autoidle_cam);
+    qemu_put_be32(f, s->cm_clksel_cam);
+    qemu_put_be32(f, s->cm_sleepdep_cam);
+    qemu_put_be32(f, s->cm_clkstctrl_cam);
+    qemu_put_be32(f, s->cm_clkstst_cam);
+
+    qemu_put_be32(f, s->cm_fclken_per);
+    qemu_put_be32(f, s->cm_iclken_per);
+    qemu_put_be32(f, s->cm_idlest_per);
+    qemu_put_be32(f, s->cm_autoidle_per);
+    qemu_put_be32(f, s->cm_clksel_per);
+    qemu_put_be32(f, s->cm_sleepdep_per);
+    qemu_put_be32(f, s->cm_clkstctrl_per);
+    qemu_put_be32(f, s->cm_clkstst_per);
+    
+    qemu_put_be32(f, s->cm_clksel1_emu);
+    qemu_put_be32(f, s->cm_clkstctrl_emu);
+    qemu_put_be32(f, s->cm_clkstst_emu);
+    qemu_put_be32(f, s->cm_clksel2_emu);
+    qemu_put_be32(f, s->cm_clksel3_emu);
+    
+    qemu_put_be32(f, s->cm_polctrl);
+
+    qemu_put_be32(f, s->cm_idlest_neon);
+    qemu_put_be32(f, s->cm_clkstctrl_neon);
+
+    qemu_put_be32(f, s->cm_fclken_usbhost);
+    qemu_put_be32(f, s->cm_iclken_usbhost);
+    qemu_put_be32(f, s->cm_idlest_usbhost);
+    qemu_put_be32(f, s->cm_autoidle_usbhost);
+    qemu_put_be32(f, s->cm_sleepdep_usbhost);
+    qemu_put_be32(f, s->cm_clkstctrl_usbhost);
+    qemu_put_be32(f, s->cm_clkstst_usbhost);
+}
+
+static int omap3_cm_load_state(QEMUFile *f, void *opaque, int version_id)
+{
+    struct omap3_cm_s *s = (struct omap3_cm_s *)opaque;
+    
+    if (version_id)
+        return -EINVAL;
+    
+    s->cm_fclken_iva2 = qemu_get_be32(f);
+    s->cm_clken_pll_iva2 = qemu_get_be32(f);
+    s->cm_idlest_iva2 = qemu_get_be32(f);
+    s->cm_idlest_pll_iva2 = qemu_get_be32(f);
+    s->cm_autoidle_pll_iva2 = qemu_get_be32(f);
+    s->cm_clksel1_pll_iva2 = qemu_get_be32(f);
+    s->cm_clksel2_pll_iva2 = qemu_get_be32(f);
+    s->cm_clkstctrl_iva2 = qemu_get_be32(f);
+    s->cm_clkstst_iva2 = qemu_get_be32(f);
+    
+    s->cm_revision = qemu_get_be32(f);
+    s->cm_sysconfig = qemu_get_be32(f);
+    
+    s->cm_clken_pll_mpu = qemu_get_be32(f);
+    s->cm_idlest_mpu = qemu_get_be32(f);
+    s->cm_idlest_pll_mpu = qemu_get_be32(f);
+    s->cm_autoidle_pll_mpu = qemu_get_be32(f);
+    s->cm_clksel1_pll_mpu = qemu_get_be32(f);
+    s->cm_clksel2_pll_mpu = qemu_get_be32(f);
+    s->cm_clkstctrl_mpu = qemu_get_be32(f);
+    s->cm_clkstst_mpu = qemu_get_be32(f);
+    
+    s->cm_fclken1_core = qemu_get_be32(f);
+    s->cm_fclken3_core = qemu_get_be32(f);
+    s->cm_iclken1_core = qemu_get_be32(f);
+    s->cm_iclken2_core = qemu_get_be32(f);
+    s->cm_iclken3_core = qemu_get_be32(f);
+    s->cm_idlest1_core = qemu_get_be32(f);
+    s->cm_idlest2_core = qemu_get_be32(f);
+    s->cm_idlest3_core = qemu_get_be32(f);
+    s->cm_autoidle1_core = qemu_get_be32(f);
+    s->cm_autoidle2_core = qemu_get_be32(f);
+    s->cm_autoidle3_core = qemu_get_be32(f);
+    s->cm_clksel_core = qemu_get_be32(f);
+    s->cm_clkstctrl_core = qemu_get_be32(f);
+    s->cm_clkstst_core = qemu_get_be32(f);
+    
+    s->cm_fclken_sgx = qemu_get_be32(f);
+    s->cm_iclken_sgx = qemu_get_be32(f);
+    s->cm_idlest_sgx = qemu_get_be32(f);
+    s->cm_clksel_sgx = qemu_get_be32(f);
+    s->cm_sleepdep_sgx = qemu_get_be32(f);
+    s->cm_clkstctrl_sgx = qemu_get_be32(f);
+    s->cm_clkstst_sgx = qemu_get_be32(f);
+    
+    s->cm_fclken_wkup = qemu_get_be32(f);
+    s->cm_iclken_wkup = qemu_get_be32(f);
+    s->cm_idlest_wkup = qemu_get_be32(f);
+    s->cm_autoidle_wkup = qemu_get_be32(f);
+    s->cm_clksel_wkup = qemu_get_be32(f);
+    s->cm_c48 = qemu_get_be32(f);
+    
+    s->cm_clken_pll = qemu_get_be32(f);
+    s->cm_clken2_pll = qemu_get_be32(f);
+    s->cm_idlest_ckgen = qemu_get_be32(f);
+    s->cm_idlest2_ckgen = qemu_get_be32(f);
+    s->cm_autoidle_pll = qemu_get_be32(f);
+    s->cm_autoidle2_pll = qemu_get_be32(f);
+    s->cm_clksel1_pll = qemu_get_be32(f);
+    s->cm_clksel2_pll = qemu_get_be32(f);
+    s->cm_clksel3_pll = qemu_get_be32(f);
+    s->cm_clksel4_pll = qemu_get_be32(f);
+    s->cm_clksel5_pll = qemu_get_be32(f);
+    s->cm_clkout_ctrl = qemu_get_be32(f);
+    
+    s->cm_fclken_dss = qemu_get_be32(f);
+    s->cm_iclken_dss = qemu_get_be32(f);
+    s->cm_idlest_dss = qemu_get_be32(f);
+    s->cm_autoidle_dss = qemu_get_be32(f);
+    s->cm_clksel_dss = qemu_get_be32(f);
+    s->cm_sleepdep_dss = qemu_get_be32(f);
+    s->cm_clkstctrl_dss = qemu_get_be32(f);
+    s->cm_clkstst_dss = qemu_get_be32(f);
+    
+    s->cm_fclken_cam = qemu_get_be32(f);
+    s->cm_iclken_cam = qemu_get_be32(f);
+    s->cm_idlest_cam = qemu_get_be32(f);
+    s->cm_autoidle_cam = qemu_get_be32(f);
+    s->cm_clksel_cam = qemu_get_be32(f);
+    s->cm_sleepdep_cam = qemu_get_be32(f);
+    s->cm_clkstctrl_cam = qemu_get_be32(f);
+    s->cm_clkstst_cam = qemu_get_be32(f);
+    
+    s->cm_fclken_per = qemu_get_be32(f);
+    s->cm_iclken_per = qemu_get_be32(f);
+    s->cm_idlest_per = qemu_get_be32(f);
+    s->cm_autoidle_per = qemu_get_be32(f);
+    s->cm_clksel_per = qemu_get_be32(f);
+    s->cm_sleepdep_per = qemu_get_be32(f);
+    s->cm_clkstctrl_per = qemu_get_be32(f);
+    s->cm_clkstst_per = qemu_get_be32(f);
+    
+    s->cm_clksel1_emu = qemu_get_be32(f);
+    s->cm_clkstctrl_emu = qemu_get_be32(f);
+    s->cm_clkstst_emu = qemu_get_be32(f);
+    s->cm_clksel2_emu = qemu_get_be32(f);
+    s->cm_clksel3_emu = qemu_get_be32(f);
+    
+    s->cm_polctrl = qemu_get_be32(f);
+    
+    s->cm_idlest_neon = qemu_get_be32(f);
+    s->cm_clkstctrl_neon = qemu_get_be32(f);
+    
+    s->cm_fclken_usbhost = qemu_get_be32(f);
+    s->cm_iclken_usbhost = qemu_get_be32(f);
+    s->cm_idlest_usbhost = qemu_get_be32(f);
+    s->cm_autoidle_usbhost = qemu_get_be32(f);
+    s->cm_sleepdep_usbhost = qemu_get_be32(f);
+    s->cm_clkstctrl_usbhost = qemu_get_be32(f);
+    s->cm_clkstst_usbhost = qemu_get_be32(f);
+
+    omap3_cm_iva2_update(s);
+    omap3_cm_mpu_update(s);
+    omap3_cm_fclken1_core_update(s);
+    omap3_cm_iclken1_core_update(s);
+    omap3_cm_gp10gp11_update(s);
+    omap3_cm_l3l4iclk_update(s);
+    omap_clk_onoff(omap_findclk(s->mpu, "omap3_gp1_fclk"),
+                   s->cm_fclken_wkup & 1);
+    omap_clk_onoff(omap_findclk(s->mpu, "omap3_wkup_l4_iclk"),
+                   s->cm_iclken_wkup ? 1 : 0);
+    omap3_cm_clksel_wkup_update(s);
+    omap3_cm_dpll3_update(s);
+    omap3_cm_dpll4_update(s);
+    omap3_cm_dpll5_update(s);
+    omap3_cm_48m_update(s);
+    omap3_cm_clkout2_update(s);
+    omap3_cm_per_gptimer_update(s);
+    
+    return 0;
+}
+
+static CPUReadMemoryFunc *omap3_cm_readfn[] = {
+    omap_badwidth_read32,
+    omap_badwidth_read32,
+    omap3_cm_read,
+};
+
+static CPUWriteMemoryFunc *omap3_cm_writefn[] = {
+    omap_badwidth_write32,
+    omap_badwidth_write32,
+    omap3_cm_write,
+};
+
+static struct omap3_cm_s *omap3_cm_init(struct omap_target_agent_s *ta,
+                                        qemu_irq mpu_int, qemu_irq dsp_int,
+                                        qemu_irq iva_int,
+                                        struct omap_mpu_state_s *mpu)
+{
+    int iomemtype;
+    struct omap3_cm_s *s = (struct omap3_cm_s *) qemu_mallocz(sizeof(*s));
+
+    s->irq[0] = mpu_int;
+    s->irq[1] = dsp_int;
+    s->irq[2] = iva_int;
+    s->mpu = mpu;
+    omap3_cm_reset(s);
+
+    iomemtype = l4_register_io_memory(0, omap3_cm_readfn, omap3_cm_writefn, s);
+    omap_l4_attach(ta, 0, iomemtype);
+    omap_l4_attach(ta, 1, iomemtype);
+
+    register_savevm("omap3_cm", -1, 0,
+                    omap3_cm_save_state, omap3_cm_load_state, s);
+    return s;
+}
+
+#define OMAP3_SEC_WDT          1
+#define OMAP3_MPU_WDT         2
+#define OMAP3_IVA2_WDT        3
+/*omap3 watchdog timer*/
+struct omap3_wdt_s
+{
+    qemu_irq irq;               /*IVA2 IRQ */
+    struct omap_mpu_state_s *mpu;
+    omap_clk clk;
+    QEMUTimer *timer;
+
+    int active;
+    int64_t rate;
+    int64_t time;
+    //int64_t ticks_per_sec;
+
+    uint32_t wd_sysconfig;
+    uint32_t wd_sysstatus;
+    uint32_t wisr;
+    uint32_t wier;
+    uint32_t wclr;
+    uint32_t wcrr;
+    uint32_t wldr;
+    uint32_t wtgr;
+    uint32_t wwps;
+    uint32_t wspr;
+
+    /*pre and ptv in wclr */
+    uint32_t pre;
+    uint32_t ptv;
+    //uint32_t val;
+
+    uint16_t writeh;            /* LSB */
+    uint16_t readh;             /* MSB */
+};
+
+static inline void omap3_wdt_timer_update(struct omap3_wdt_s *wdt_timer)
+{
+    int64_t expires;
+    if (wdt_timer->active) {
+        expires = muldiv64(0xffffffffll - wdt_timer->wcrr,
+                           ticks_per_sec, wdt_timer->rate);
+        qemu_mod_timer(wdt_timer->timer, wdt_timer->time + expires);
+    } else
+        qemu_del_timer(wdt_timer->timer);
+}
+
+static void omap3_wdt_clk_setup(struct omap3_wdt_s *timer)
+{
+    /*TODO: Add irq as user to clk */
+}
+
+static inline uint32_t omap3_wdt_timer_read(struct omap3_wdt_s *timer)
+{
+    uint64_t distance;
+
+    if (timer->active) {
+        distance = qemu_get_clock(vm_clock) - timer->time;
+        distance = muldiv64(distance, timer->rate, ticks_per_sec);
+
+        if (distance >= 0xffffffff - timer->wcrr)
+            return 0xffffffff;
+        else
+            return timer->wcrr + distance;
+    } else
+        return timer->wcrr;
+}
+
+/*
+static inline void omap3_wdt_timer_sync(struct omap3_wdt_s *timer)
+{
+    if (timer->active) {
+        timer->val = omap3_wdt_timer_read(timer);
+        timer->time = qemu_get_clock(vm_clock);
+    }
+}*/
+
+static void omap3_wdt_reset(struct omap3_wdt_s *s, int wdt_index)
+{
+    s->wd_sysconfig = 0x0;
+    s->wd_sysstatus = 0x0;
+    s->wisr = 0x0;
+    s->wier = 0x0;
+    s->wclr = 0x20;
+    s->wcrr = 0x0;
+    switch (wdt_index) {
+        case OMAP3_MPU_WDT:
+        case OMAP3_IVA2_WDT:
+            s->wldr = 0xfffb0000;
+            break;
+        case OMAP3_SEC_WDT:
+            s->wldr = 0xffa60000;
+            break;
+        default:
+            break;
+    }
+    s->wtgr = 0x0;
+    s->wwps = 0x0;
+    s->wspr = 0x0;
+
+    switch (wdt_index) {
+        case OMAP3_SEC_WDT:
+        case OMAP3_MPU_WDT:
+            s->active = 1;
+            break;
+        case OMAP3_IVA2_WDT:
+            s->active = 0;
+            break;
+        default:
+            break;
+    }
+    s->pre = s->wclr & (1 << 5);
+    s->ptv = (s->wclr & 0x1c) >> 2;
+    s->rate = omap_clk_getrate(s->clk) >> (s->pre ? s->ptv : 0);
+
+    s->active = 1;
+    s->time = qemu_get_clock(vm_clock);
+    omap3_wdt_timer_update(s);
+}
+
+static uint32_t omap3_wdt_read32(void *opaque, target_phys_addr_t addr,
+                                 int wdt_index)
+{
+    struct omap3_wdt_s *s = (struct omap3_wdt_s *) opaque;
+
+    switch (addr) {
+        case 0x10: return s->wd_sysconfig;
+        case 0x14: return s->wd_sysstatus;
+        case 0x18: return s->wisr & 0x1;
+        case 0x1c: return s->wier & 0x1;
+        case 0x24: return s->wclr & 0x3c;
+        case 0x28: /* WCRR */
+            s->wcrr = omap3_wdt_timer_read(s);
+            s->time = qemu_get_clock(vm_clock);
+            return s->wcrr;
+        case 0x2c: return s->wldr;
+        case 0x30: return s->wtgr;
+        case 0x34: return s->wwps;
+        case 0x48: return s->wspr;
+        default: break;
+    }
+    OMAP_BAD_REG(addr);
+    return 0;
+}
+
+static uint32_t omap3_mpu_wdt_read16(void *opaque, target_phys_addr_t addr)
+{
+    struct omap3_wdt_s *s = (struct omap3_wdt_s *) opaque;
+    uint32_t ret;
+
+    if (addr & 2)
+        return s->readh;
+
+    ret = omap3_wdt_read32(opaque, addr, OMAP3_MPU_WDT);
+    s->readh = ret >> 16;
+    return ret & 0xffff;
+}
+
+static uint32_t omap3_mpu_wdt_read32(void *opaque, target_phys_addr_t addr)
+{
+    return omap3_wdt_read32(opaque, addr, OMAP3_MPU_WDT);
+}
+
+static void omap3_wdt_write32(void *opaque, target_phys_addr_t addr,
+                              uint32_t value, int wdt_index)
+{
+    struct omap3_wdt_s *s = (struct omap3_wdt_s *) opaque;
+
+    switch (addr) {
+    case 0x14: /* WD_SYSSTATUS */
+    case 0x34: /* WWPS */
+        OMAP_RO_REGV(addr, value);
+        break;
+    case 0x10: /*WD_SYSCONFIG */
+        s->wd_sysconfig = value & 0x33f;
+        break;
+    case 0x18: /* WISR */
+         s->wisr = value & 0x1;
+        break;
+    case 0x1c: /* WIER */
+        s->wier = value & 0x1;
+        break;
+    case 0x24: /* WCLR */
+        s->wclr = value & 0x3c;
+        break;
+    case 0x28: /* WCRR */
+        s->wcrr = value;
+        s->time = qemu_get_clock(vm_clock);
+        omap3_wdt_timer_update(s);
+        break;
+    case 0x2c: /* WLDR */
+        s->wldr = value; /* It will take effect after next overflow */
+        break;
+    case 0x30: /* WTGR */
+        if (value != s->wtgr) {
+            s->wcrr = s->wldr;
+            s->pre = s->wclr & (1 << 5);
+            s->ptv = (s->wclr & 0x1c) >> 2;
+            s->rate = omap_clk_getrate(s->clk) >> (s->pre ? s->ptv : 0);
+            s->time = qemu_get_clock(vm_clock);
+            omap3_wdt_timer_update(s);
+        }
+        s->wtgr = value;
+        break;
+    case 0x48: /* WSPR */
+        if (((value & 0xffff) == 0x5555) && ((s->wspr & 0xffff) == 0xaaaa)) {
+            s->active = 0;
+            s->wcrr = omap3_wdt_timer_read(s);
+            omap3_wdt_timer_update(s);
+        }
+        if (((value & 0xffff) == 0x4444) && ((s->wspr & 0xffff) == 0xbbbb)) {
+            s->active = 1;
+            s->time = qemu_get_clock(vm_clock);
+            omap3_wdt_timer_update(s);
+        }
+        s->wspr = value;
+        break;
+    default:
+        OMAP_BAD_REGV(addr, value);
+        break;
+    }
+}
+
+static void omap3_mpu_wdt_write16(void *opaque, target_phys_addr_t addr,
+                                  uint32_t value)
+{
+    struct omap3_wdt_s *s = (struct omap3_wdt_s *) opaque;
+
+    if (addr & 2)
+        return omap3_wdt_write32(opaque, addr, (value << 16) | s->writeh,
+                                 OMAP3_MPU_WDT);
+    else
+        s->writeh = (uint16_t) value;
+}
+
+static void omap3_mpu_wdt_write32(void *opaque, target_phys_addr_t addr,
+                                  uint32_t value)
+{
+    omap3_wdt_write32(opaque, addr, value, OMAP3_MPU_WDT);
+}
+
+static CPUReadMemoryFunc *omap3_mpu_wdt_readfn[] = {
+    omap_badwidth_read32,
+    omap3_mpu_wdt_read16,
+    omap3_mpu_wdt_read32,
+};
+
+static CPUWriteMemoryFunc *omap3_mpu_wdt_writefn[] = {
+    omap_badwidth_write32,
+    omap3_mpu_wdt_write16,
+    omap3_mpu_wdt_write32,
+};
+
+static void omap3_mpu_wdt_timer_tick(void *opaque)
+{
+    struct omap3_wdt_s *wdt_timer = (struct omap3_wdt_s *) opaque;
+
+    /*TODO:Sent reset pulse to PRCM */
+    wdt_timer->wcrr = wdt_timer->wldr;
+
+    /*after overflow, generate the new wdt_timer->rate */
+    wdt_timer->pre = wdt_timer->wclr & (1 << 5);
+    wdt_timer->ptv = (wdt_timer->wclr & 0x1c) >> 2;
+    wdt_timer->rate =
+        omap_clk_getrate(wdt_timer->clk) >> (wdt_timer->pre ? wdt_timer->
+                                             ptv : 0);
+
+    wdt_timer->time = qemu_get_clock(vm_clock);
+    omap3_wdt_timer_update(wdt_timer);
+}
+
+static void omap3_mpu_wdt_save_state(QEMUFile *f, void *opaque)
+{
+    struct omap3_wdt_s *s = (struct omap3_wdt_s *)opaque;
+
+    qemu_put_timer(f, s->timer);
+    qemu_put_sbe32(f, s->active);
+    qemu_put_be64(f, s->rate);
+    qemu_put_be64(f, s->time);
+    qemu_put_be32(f, s->wd_sysconfig);
+    qemu_put_be32(f, s->wd_sysstatus);
+    qemu_put_be32(f, s->wisr);
+    qemu_put_be32(f, s->wier);
+    qemu_put_be32(f, s->wclr);
+    qemu_put_be32(f, s->wcrr);
+    qemu_put_be32(f, s->wldr);
+    qemu_put_be32(f, s->wtgr);
+    qemu_put_be32(f, s->wwps);
+    qemu_put_be32(f, s->wspr);
+    qemu_put_be32(f, s->pre);
+    qemu_put_be32(f, s->ptv);
+    qemu_put_be16(f, s->writeh);
+    qemu_put_be16(f, s->readh);
+}
+
+static int omap3_mpu_wdt_load_state(QEMUFile *f, void *opaque, int version_id)
+{
+    struct omap3_wdt_s *s = (struct omap3_wdt_s *)opaque;
+    
+    if (version_id)
+        return -EINVAL;
+    
+    qemu_get_timer(f, s->timer);
+    s->active = qemu_get_sbe32(f);
+    s->rate = qemu_get_be64(f);
+    s->time = qemu_get_be64(f);
+    s->wd_sysconfig = qemu_get_be32(f);
+    s->wd_sysstatus = qemu_get_be32(f);
+    s->wisr = qemu_get_be32(f);
+    s->wier = qemu_get_be32(f);
+    s->wclr = qemu_get_be32(f);
+    s->wcrr = qemu_get_be32(f);
+    s->wldr = qemu_get_be32(f);
+    s->wtgr = qemu_get_be32(f);
+    s->wwps = qemu_get_be32(f);
+    s->wspr = qemu_get_be32(f);
+    s->pre = qemu_get_be32(f);
+    s->ptv = qemu_get_be32(f);
+    s->writeh = qemu_get_be16(f);
+    s->readh = qemu_get_be16(f);
+    
+    return 0;
+}
+
+static struct omap3_wdt_s *omap3_mpu_wdt_init(struct omap_target_agent_s *ta,
+                                              qemu_irq irq, omap_clk fclk,
+                                              omap_clk iclk,
+                                              struct omap_mpu_state_s *mpu)
+{
+    int iomemtype;
+    struct omap3_wdt_s *s = (struct omap3_wdt_s *) qemu_mallocz(sizeof(*s));
+
+    s->irq = irq;
+    s->clk = fclk;
+    s->timer = qemu_new_timer(vm_clock, omap3_mpu_wdt_timer_tick, s);
+
+    omap3_wdt_reset(s, OMAP3_MPU_WDT);
+    if (irq != NULL)
+        omap3_wdt_clk_setup(s);
+
+    iomemtype = l4_register_io_memory(0, omap3_mpu_wdt_readfn,
+                                      omap3_mpu_wdt_writefn, s);
+    omap_l4_attach(ta, 0, iomemtype);
+
+    register_savevm("omap3_mpu_wdt", -1, 0,
+                    omap3_mpu_wdt_save_state, omap3_mpu_wdt_load_state, s);
+    return s;
+}
+
+struct omap3_scm_s {
+    struct omap_mpu_state_s *mpu;
+
+       uint8 interface[48];     /*0x4800 2000*/
+       uint8 padconfs[576];     /*0x4800 2030*/
+       uint32 general[228];     /*0x4800 2270*/
+       uint8 mem_wkup[1024];    /*0x4800 2600*/
+       uint8 padconfs_wkup[84]; /*0x4800 2a00*/
+       uint32 general_wkup[8];  /*0x4800 2a60*/
+};
+
+static void omap3_scm_save_state(QEMUFile *f, void *opaque)
+{
+    struct omap3_scm_s *s = (struct omap3_scm_s *)opaque;
+    int i;
+
+    qemu_put_buffer(f, s->interface, sizeof(s->interface));
+    qemu_put_buffer(f, s->padconfs, sizeof(s->padconfs));
+    for (i = 0; i < sizeof(s->general)/sizeof(uint32); i++)
+        qemu_put_be32(f, s->general[i]);
+    qemu_put_buffer(f, s->mem_wkup, sizeof(s->mem_wkup));
+    qemu_put_buffer(f, s->padconfs_wkup, sizeof(s->padconfs_wkup));
+    for (i = 0; i < sizeof(s->general_wkup)/sizeof(uint32); i++)
+        qemu_put_be32(f, s->general_wkup[i]);
+}
+
+static int omap3_scm_load_state(QEMUFile *f, void *opaque, int version_id)
+{
+    struct omap3_scm_s *s = (struct omap3_scm_s *)opaque;
+    int i;
+    
+    if (version_id)
+        return -EINVAL;
+    
+    qemu_get_buffer(f, s->interface, sizeof(s->interface));
+    qemu_get_buffer(f, s->padconfs, sizeof(s->padconfs));
+    for (i = 0; i < sizeof(s->general)/sizeof(uint32); i++)
+        s->general[i] = qemu_get_be32(f);
+    qemu_get_buffer(f, s->mem_wkup, sizeof(s->mem_wkup));
+    qemu_get_buffer(f, s->padconfs_wkup, sizeof(s->padconfs_wkup));
+    for (i = 0; i < sizeof(s->general_wkup)/sizeof(uint32); i++)
+        s->general_wkup[i] = qemu_get_be32(f);
+
+    return 0;
+}
+
+#define PADCONFS_VALUE(wakeup0,wakeup1,offmode0,offmode1, \
+                                               inputenable0,inputenable1,pupd0,pupd1,muxmode0,muxmode1,offset) \
+       do { \
+                *(padconfs+offset/4) = (wakeup0 <<14)|(offmode0<<9)|(inputenable0<<8)|(pupd0<<3)|(muxmode0); \
+                *(padconfs+offset/4) |= (wakeup1 <<30)|(offmode1<<25)|(inputenable1<<24)|(pupd1<<19)|(muxmode1<<16); \
+} while (0)
+
+
+static void omap3_scm_reset(struct omap3_scm_s *s)
+{
+    uint32 * padconfs;
+    padconfs = (uint32 *)(s->padconfs);
+    PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x0);
+    PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x4);
+    PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x8);
+    PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0xc);
+    PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x10);
+    PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x14);
+    PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x18);
+    PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x1c);
+    PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x20);
+    PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x24);
+    PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x28);
+    PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x2c);
+    PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x30);
+    PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x34);
+    PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x38);
+    PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x3c);
+    PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x40);
+    PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x44);
+    PADCONFS_VALUE(0,0,0,0,1,1,0,1,0,7,0x48);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x4c);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x50);
+    PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x54);
+    PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x58);
+    PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,0,0x5c);
+    PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x60);
+    PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x64);
+    PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x68);
+    PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x6c);
+    PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x70);
+    PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x74);
+    PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x78);
+    PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x7c);
+    PADCONFS_VALUE(0,0,0,0,1,1,0,3,0,7,0x80);
+    PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x84);
+    PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x88);
+    PADCONFS_VALUE(0,0,0,0,1,1,3,0,7,0,0x8c);
+    PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x90);
+    PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x94);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,0,7,0,0x98);
+    PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,7,0x9c);
+    PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0xa0);
+    PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0xa4);
+    PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0xa8);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xac);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xb0);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xb4);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xb8);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xbc);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xc0);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xc4);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xc8);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xcc);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xd0);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xd4);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xd8);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xdc);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xe0);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xe4);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xe8);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xec);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xf0);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xf4);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xf8);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0xfc);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x100);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x104);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x108);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x10c);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x110);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x114);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x118);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x11c);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x120);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x124);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,3,7,7,0x128);
+    PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x12c);
+    PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x130);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x134);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x138);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x13c);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x140);
+    PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x144);
+    PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x148);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x14c);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x150);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x154);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x158);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x15c);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x160);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x164);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,3,7,7,0x168);
+    PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x16c);
+    PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0x170);
+    PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0x174);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x178);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x17c);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x180);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x184);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,3,7,7,0x188);
+    PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x18c);
+    PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x190);
+    PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x194);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x198);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,3,7,7,0x19c);
+    PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x1a0);
+    PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0x1a4);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x1a8);
+    PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0x1ac);
+    PADCONFS_VALUE(0,0,0,0,1,1,3,1,7,7,0x1b0);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1b4);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1b8);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1bc);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1c0);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1c4);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1c8);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1cc);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1d0);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1d4);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1d8);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1dc);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1e0);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1e4);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1e8);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1ec);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1f0);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1f4);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1f8);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1fc);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x200);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x204);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x208);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x20c);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x210);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x214);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x218);
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x21c);
+    PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x220);
+    PADCONFS_VALUE(0,0,0,0,1,1,3,1,0,0,0x224);
+    PADCONFS_VALUE(0,0,0,0,1,1,0,1,0,0,0x228);
+    PADCONFS_VALUE(0,0,0,0,1,1,0,1,0,0,0x22c);
+    PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x230);
+    PADCONFS_VALUE(0,0,0,0,1,1,3,3,7,7,0x234);
+
+       padconfs = (uint32 *)(s->general);
+    memset(s->general, 0, sizeof(s->general));
+       s->general[0x01] = 0x4000000;  /* CONTROL_DEVCONF_0 */
+       s->general[0x1c] = 0x1;        /* 0x480022e0?? */
+    s->general[0x20] = 0x30f;      /* CONTROL_STATUS:
+                                    * - device type  = GP Device
+                                    * - sys_boot:6   = oscillator bypass mode
+                                    * - sys_boot:0-5 = NAND, USB, UART3, MMC1*/
+       s->general[0x75] = 0x7fc0;     /* CONTROL_PROG_IO0 */
+       s->general[0x76] = 0xaa;       /* CONTROL_PROG_IO1 */
+       s->general[0x7c] = 0x2700;     /* CONTROL_SDRC_SHARING */
+       s->general[0x7d] = 0x300000;   /* CONTROL_SDRC_MCFG0 */
+       s->general[0x7e] = 0x300000;   /* CONTROL_SDRC_MCFG1 */
+       s->general[0x81] = 0xffff;     /* CONTROL_MODEM_GPMC_DT_FW_REQ_INFO */
+       s->general[0x82] = 0xffff;     /* CONTROL_MODEM_GPMC_DT_FW_RD */
+       s->general[0x83] = 0xffff;     /* CONTROL_MODEM_GPMC_DT_FW_WR */
+       s->general[0x84] = 0x6;        /* CONTROL_MODEM_GPMC_BOOT_CODE */
+       s->general[0x85] = 0xffffffff; /* CONTROL_MODEM_SMS_RG_ATT1 */
+       s->general[0x86] = 0xffff;     /* CONTROL_MODEM_SMS_RG_RDPERM1 */
+       s->general[0x87] = 0xffff;     /* CONTROL_MODEM_SMS_RG_WRPERM1 */
+       s->general[0x88] = 0x1;        /* CONTROL_MODEM_D2D_FW_DEBUG_MODE */
+       s->general[0x8b] = 0xffffffff; /* CONTROL_DPF_OCM_RAM_FW_REQINFO */
+       s->general[0x8c] = 0xffff;     /* CONTROL_DPF_OCM_RAM_FW_WR */
+       s->general[0x8e] = 0xffff;     /* CONTROL_DPF_REGION4_GPMC_FW_REQINFO */
+       s->general[0x8f] = 0xffff;     /* CONTROL_DPF_REGION4_GPMC_FW_WR */
+       s->general[0x91] = 0xffff;     /* CONTROL_DPF_REGION1_IVA2_FW_REQINFO */
+       s->general[0x92] = 0xffff;     /* CONTROL_DPF_REGION1_IVA2_FW_WR */
+       s->general[0xac] = 0x109;      /* CONTROL_PBIAS_LITE */
+       s->general[0xb2] = 0xffff;     /* CONTROL_DPF_MAD2D_FW_ADDR_MATCH */
+       s->general[0xb3] = 0xffff;     /* CONTROL_DPF_MAD2D_FW_REQINFO */
+       s->general[0xb4] = 0xffff;     /* CONTROL_DPF_MAD2D_FW_WR */
+       PADCONFS_VALUE(0,0,0,0,1,1,3,3,4,4,0x368); /* PADCONF_ETK_CLK */
+    PADCONFS_VALUE(0,0,0,0,1,1,3,3,4,4,0x36c); /* PADCONF_ETK_D0 */
+    PADCONFS_VALUE(0,0,0,0,1,1,3,3,4,4,0x370); /* PADCONF_ETK_D2 */
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x374); /* PADCONF_ETK_D4 */
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x378); /* PADCONF_ETK_D6 */
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x37c); /* PADCONF_ETK_D8 */
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x380); /* PADCONF_ETK_D10 */
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x384); /* PADCONF_ETK_D12 */
+    PADCONFS_VALUE(0,0,0,0,1,1,1,1,4,4,0x388); /* PADCONF_ETK_D14 */
+
+       padconfs = (uint32 *)(s->padconfs_wkup);
+       PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x0);
+       PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x4);
+       PADCONFS_VALUE(0,0,0,0,1,1,3,0,0,0,0x8);
+       PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0xc);
+       PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x10);
+       PADCONFS_VALUE(0,0,0,0,1,1,0,0,0,0,0x14);
+       PADCONFS_VALUE(0,0,0,0,1,1,1,1,7,7,0x18);
+       PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x1c);
+       PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x20);
+       PADCONFS_VALUE(0,0,0,0,1,1,3,3,0,0,0x24);
+       PADCONFS_VALUE(0,0,0,0,1,1,1,1,0,0,0x2c);
+
+       s->general_wkup[0] = 0x66ff; /* 0x48002A60?? */
+}
+
+static uint32_t omap3_scm_read8(void *opaque, target_phys_addr_t addr)
+{
+    struct omap3_scm_s *s = (struct omap3_scm_s *) opaque;
+    uint8_t* temp;
+       
+    switch (addr) {
+        case 0x000 ... 0x02f: return s->interface[addr];
+        case 0x030 ... 0x26f: return s->padconfs[addr - 0x30];
+        case 0x270 ... 0x5ff: temp = (uint8_t *)s->general; return temp[addr - 0x270];
+        case 0x600 ... 0x9ff: return s->mem_wkup[addr - 0x600];
+        case 0xa00 ... 0xa5f: return s->padconfs_wkup[addr - 0xa00];
+        case 0xa60 ... 0xa7f: temp = (uint8_t *)s->general_wkup; return temp[addr - 0xa60];
+        default: break;
+    }
+    OMAP_BAD_REG(addr);
+    return 0;
+}
+
+static uint32_t omap3_scm_read16(void *opaque, target_phys_addr_t addr)
+{
+    uint32_t v;
+    v = omap3_scm_read8(opaque, addr);
+    v |= omap3_scm_read8(opaque, addr + 1) << 8;
+    return v;
+}
+
+static uint32_t omap3_scm_read32(void *opaque, target_phys_addr_t addr)
+{
+    uint32_t v;
+    v = omap3_scm_read8(opaque, addr);
+    v |= omap3_scm_read8(opaque, addr + 1) << 8;
+    v |= omap3_scm_read8(opaque, addr + 2) << 16;
+    v |= omap3_scm_read8(opaque, addr + 3) << 24;
+    return v;
+}
+
+static void omap3_scm_write8(void *opaque, target_phys_addr_t addr,
+                             uint32_t value)
+{
+    struct omap3_scm_s *s = (struct omap3_scm_s *) opaque;
+    uint8_t* temp;
+
+    switch (addr) {
+        case 0x000 ... 0x02f: s->interface[addr] = value; break;
+        case 0x030 ... 0x26f: s->padconfs[addr-0x30] = value; break;
+        case 0x270 ... 0x5ff: temp = (uint8_t *)s->general; temp[addr-0x270] = value; break;
+        case 0x600 ... 0x9ff: s->mem_wkup[addr-0x600] = value; break;
+        case 0xa00 ... 0xa5f: s->padconfs_wkup[addr-0xa00] = value; break;
+        case 0xa60 ... 0xa7f: temp = (uint8_t *)s->general_wkup; temp[addr-0xa60] = value; break;
+        default: OMAP_BAD_REGV(addr, value); break;
+    }
+}
+
+static void omap3_scm_write16(void *opaque, target_phys_addr_t addr,
+                              uint32_t value)
+{
+    omap3_scm_write8(opaque, addr + 0, (value) & 0xff);
+    omap3_scm_write8(opaque, addr + 1, (value >> 8) & 0xff);
+}
+
+static void omap3_scm_write32(void *opaque, target_phys_addr_t addr,
+                              uint32_t value)
+{
+    omap3_scm_write8(opaque, addr + 0, (value) & 0xff);
+    omap3_scm_write8(opaque, addr + 1, (value >> 8) & 0xff);
+    omap3_scm_write8(opaque, addr + 2, (value >> 16) & 0xff);
+    omap3_scm_write8(opaque, addr + 3, (value >> 24) & 0xff);
+}
+
+static CPUReadMemoryFunc *omap3_scm_readfn[] = {
+    omap3_scm_read8,
+    omap3_scm_read16,
+    omap3_scm_read32,
+};
+
+static CPUWriteMemoryFunc *omap3_scm_writefn[] = {
+    omap3_scm_write8,
+    omap3_scm_write16,
+    omap3_scm_write32,
+};
+
+static struct omap3_scm_s *omap3_scm_init(struct omap_target_agent_s *ta,
+                                          struct omap_mpu_state_s *mpu)
+{
+    int iomemtype;
+    struct omap3_scm_s *s = (struct omap3_scm_s *) qemu_mallocz(sizeof(*s));
+
+    s->mpu = mpu;
+
+    omap3_scm_reset(s);
+
+    iomemtype = l4_register_io_memory(0, omap3_scm_readfn,
+                                      omap3_scm_writefn, s);
+    omap_l4_attach(ta, 0, iomemtype);
+    
+    register_savevm("omap3_scm", -1, 0,
+                    omap3_scm_save_state, omap3_scm_load_state, s);
+    return s;
+}
+
+/*dummy SDRAM Memory Scheduler emulation*/
+struct omap3_sms_s
+{
+    struct omap_mpu_state_s *mpu;
+
+    uint32 sms_sysconfig;
+    uint32 sms_sysstatus;
+    uint32 sms_rg_att[8];
+    uint32 sms_rg_rdperm[8];
+    uint32 sms_rg_wrperm[8];
+    uint32 sms_rg_start[7];
+    uint32 sms_rg_end[7];
+    uint32 sms_security_control;
+    uint32 sms_class_arbiter0;
+    uint32 sms_class_arbiter1;
+    uint32 sms_class_arbiter2;
+    uint32 sms_interclass_arbiter;
+    uint32 sms_class_rotation[3];
+    uint32 sms_err_addr;
+    uint32 sms_err_type;
+    uint32 sms_pow_ctrl;
+    uint32 sms_rot_control[12];
+    uint32 sms_rot_size[12];
+    uint32 sms_rot_physical_ba[12];
+};
+
+static void omap3_sms_save_state(QEMUFile *f, void *opaque)
+{
+    struct omap3_sms_s *s = (struct omap3_sms_s *)opaque;
+    int i;
+
+    qemu_put_be32(f, s->sms_sysconfig);
+    qemu_put_be32(f, s->sms_sysstatus);
+    for (i = 0; i < 8; i++) {
+        qemu_put_be32(f, s->sms_rg_att[i]);
+        qemu_put_be32(f, s->sms_rg_rdperm[i]);
+        qemu_put_be32(f, s->sms_rg_wrperm[i]);
+        if (i < 7) {
+            qemu_put_be32(f, s->sms_rg_start[i]);
+            qemu_put_be32(f, s->sms_rg_end[i]);
+        }
+    }
+    qemu_put_be32(f, s->sms_security_control);
+    qemu_put_be32(f, s->sms_class_arbiter0);
+    qemu_put_be32(f, s->sms_class_arbiter1);
+    qemu_put_be32(f, s->sms_class_arbiter2);
+    qemu_put_be32(f, s->sms_interclass_arbiter);
+    qemu_put_be32(f, s->sms_class_rotation[0]);
+    qemu_put_be32(f, s->sms_class_rotation[1]);
+    qemu_put_be32(f, s->sms_class_rotation[2]);
+    qemu_put_be32(f, s->sms_err_addr);
+    qemu_put_be32(f, s->sms_err_type);
+    qemu_put_be32(f, s->sms_pow_ctrl);
+    for (i = 0; i< 12; i++) {
+        qemu_put_be32(f, s->sms_rot_control[i]);
+        qemu_put_be32(f, s->sms_rot_size[i]);
+        qemu_put_be32(f, s->sms_rot_physical_ba[i]);
+    }
+}
+
+static int omap3_sms_load_state(QEMUFile *f, void *opaque, int version_id)
+{
+    struct omap3_sms_s *s = (struct omap3_sms_s *)opaque;
+    int i;
+    
+    if (version_id)
+        return -EINVAL;
+    
+    s->sms_sysconfig = qemu_get_be32(f);
+    s->sms_sysstatus = qemu_get_be32(f);
+    for (i = 0; i < 8; i++) {
+        s->sms_rg_att[i] = qemu_get_be32(f);
+        s->sms_rg_rdperm[i] = qemu_get_be32(f);
+        s->sms_rg_wrperm[i] = qemu_get_be32(f);
+        if (i < 7) {
+            s->sms_rg_start[i] = qemu_get_be32(f);
+            s->sms_rg_end[i] = qemu_get_be32(f);
+        }
+    }
+    s->sms_security_control = qemu_get_be32(f);
+    s->sms_class_arbiter0 = qemu_get_be32(f);
+    s->sms_class_arbiter1 = qemu_get_be32(f);
+    s->sms_class_arbiter2 = qemu_get_be32(f);
+    s->sms_interclass_arbiter = qemu_get_be32(f);
+    s->sms_class_rotation[0] = qemu_get_be32(f);
+    s->sms_class_rotation[1] = qemu_get_be32(f);
+    s->sms_class_rotation[2] = qemu_get_be32(f);
+    s->sms_err_addr = qemu_get_be32(f);
+    s->sms_err_type = qemu_get_be32(f);
+    s->sms_pow_ctrl = qemu_get_be32(f);
+    for (i = 0; i< 12; i++) {
+        s->sms_rot_control[i] = qemu_get_be32(f);
+        s->sms_rot_size[i] = qemu_get_be32(f);
+        s->sms_rot_physical_ba[i] = qemu_get_be32(f);
+    }
+    
+    return 0;
+}
+
+static uint32_t omap3_sms_read32(void *opaque, target_phys_addr_t addr)
+{
+    struct omap3_sms_s *s = (struct omap3_sms_s *) opaque;
+
+    switch (addr)
+    {
+    case 0x10:
+       return s->sms_sysconfig;
+    case 0x14:
+       return s->sms_sysstatus;
+    case 0x48:
+    case 0x68:
+    case 0x88:
+    case 0xa8:
+    case 0xc8:
+    case 0xe8:
+    case 0x108:
+    case 0x128:
+       return s->sms_rg_att[(addr-0x48)/0x20];
+    case 0x50:
+    case 0x70:
+    case 0x90:
+    case 0xb0:
+    case 0xd0:
+    case 0xf0:
+    case 0x110:
+    case 0x130:
+       return s->sms_rg_rdperm[(addr-0x50)/0x20];
+    case 0x58:
+    case 0x78:
+    case 0x98:
+    case 0xb8:
+    case 0xd8:
+    case 0xf8:
+    case 0x118:
+       return s->sms_rg_wrperm[(addr-0x58)/0x20];
+    case 0x60:
+    case 0x80:
+    case 0xa0:
+    case 0xc0:
+    case 0xe0:
+    case 0x100:
+    case 0x120:
+       return s->sms_rg_start[(addr-0x60)/0x20];
+
+    case 0x64:
+    case 0x84:
+    case 0xa4:
+    case 0xc4:
+    case 0xe4:
+    case 0x104:
+    case 0x124:
+       return s->sms_rg_end[(addr-0x64)/0x20];
+    case 0x140:
+       return s->sms_security_control;
+    case 0x150:
+       return s->sms_class_arbiter0;
+       case 0x154:
+               return s->sms_class_arbiter1;
+       case 0x158:
+               return s->sms_class_arbiter2;
+       case 0x160:
+               return s->sms_interclass_arbiter;
+       case 0x164:
+       case 0x168:
+       case 0x16c:
+               return s->sms_class_rotation[(addr-0x164)/4];
+       case 0x170:
+               return s->sms_err_addr;
+       case 0x174:
+               return s->sms_err_type;
+       case 0x178:
+               return s->sms_pow_ctrl;
+       case 0x180:
+       case 0x190:
+       case 0x1a0:
+       case 0x1b0:
+       case 0x1c0:
+       case 0x1d0:
+       case 0x1e0:
+       case 0x1f0:
+       case 0x200:
+       case 0x210:
+       case 0x220:
+       case 0x230:
+               return s->sms_rot_control[(addr-0x180)/0x10];
+       case 0x184:
+       case 0x194:
+       case 0x1a4:
+       case 0x1b4:
+       case 0x1c4:
+       case 0x1d4:
+       case 0x1e4:
+       case 0x1f4:
+       case 0x204:
+       case 0x214:
+       case 0x224:
+       case 0x234:
+               return s->sms_rot_size[(addr-0x184)/0x10];
+
+       case 0x188:
+       case 0x198:
+       case 0x1a8:
+       case 0x1b8:
+       case 0x1c8:
+       case 0x1d8:
+       case 0x1e8:
+       case 0x1f8:
+       case 0x208:
+       case 0x218:
+       case 0x228:
+       case 0x238:
+               return s->sms_rot_size[(addr-0x188)/0x10];
+
+    default:
+        break;
+    }
+    OMAP_BAD_REG(addr);
+    return 0;
+}
+
+static void omap3_sms_write32(void *opaque, target_phys_addr_t addr,
+                              uint32_t value)
+{
+    struct omap3_sms_s *s = (struct omap3_sms_s *) opaque;
+    //int i;
+
+    switch (addr)
+    {
+    case 0x14:
+       OMAP_RO_REG(addr);
+        return;
+    case 0x10:
+       s->sms_sysconfig = value & 0x1f;
+       break;
+    
+    case 0x48:
+    case 0x68:
+    case 0x88:
+    case 0xa8:
+    case 0xc8:
+    case 0xe8:
+    case 0x108:
+    case 0x128:
+       s->sms_rg_att[(addr-0x48)/0x20] = value;
+       break;
+    case 0x50:
+    case 0x70:
+    case 0x90:
+    case 0xb0:
+    case 0xd0:
+    case 0xf0:
+    case 0x110:
+    case 0x130:
+       s->sms_rg_rdperm[(addr-0x50)/0x20] = value&0xffff;
+       break;
+    case 0x58:
+    case 0x78:
+    case 0x98:
+    case 0xb8:
+    case 0xd8:
+    case 0xf8:
+    case 0x118:
+       s->sms_rg_wrperm[(addr-0x58)/0x20] = value&0xffff;
+       break;          
+    case 0x60:
+    case 0x80:
+    case 0xa0:
+    case 0xc0:
+    case 0xe0:
+    case 0x100:
+    case 0x120:
+       s->sms_rg_start[(addr-0x60)/0x20] = value;
+       break;
+    case 0x64:
+    case 0x84:
+    case 0xa4:
+    case 0xc4:
+    case 0xe4:
+    case 0x104:
+    case 0x124:
+       s->sms_rg_end[(addr-0x64)/0x20] = value;
+       break;
+    case 0x140:
+       s->sms_security_control = value &0xfffffff;
+       break;
+    case 0x150:
+       s->sms_class_arbiter0 = value;
+       break;
+       case 0x154:
+               s->sms_class_arbiter1 = value;
+               break;
+       case 0x158:
+               s->sms_class_arbiter2 = value;
+               break;
+       case 0x160:
+               s->sms_interclass_arbiter = value;
+               break;
+       case 0x164:
+       case 0x168:
+       case 0x16c:
+               s->sms_class_rotation[(addr-0x164)/4] = value;
+               break;
+       case 0x170:
+               s->sms_err_addr = value;
+               break;
+       case 0x174:
+               s->sms_err_type = value;
+               break;
+       case 0x178:
+               s->sms_pow_ctrl = value;
+               break;
+       case 0x180:
+       case 0x190:
+       case 0x1a0:
+       case 0x1b0:
+       case 0x1c0:
+       case 0x1d0:
+       case 0x1e0:
+       case 0x1f0:
+       case 0x200:
+       case 0x210:
+       case 0x220:
+       case 0x230:
+               s->sms_rot_control[(addr-0x180)/0x10] = value;
+               break;
+       case 0x184:
+       case 0x194:
+       case 0x1a4:
+       case 0x1b4:
+       case 0x1c4:
+       case 0x1d4:
+       case 0x1e4:
+       case 0x1f4:
+       case 0x204:
+       case 0x214:
+       case 0x224:
+       case 0x234:
+               s->sms_rot_size[(addr-0x184)/0x10] = value;
+               break;
+
+       case 0x188:
+       case 0x198:
+       case 0x1a8:
+       case 0x1b8:
+       case 0x1c8:
+       case 0x1d8:
+       case 0x1e8:
+       case 0x1f8:
+       case 0x208:
+       case 0x218:
+       case 0x228:
+       case 0x238:
+               s->sms_rot_size[(addr-0x188)/0x10] = value;   
+               break;
+       default:
+        OMAP_BAD_REGV(addr, value);
+        break;
+    }
+}
+
+static CPUReadMemoryFunc *omap3_sms_readfn[] = {
+    omap_badwidth_read32,
+    omap_badwidth_read32,
+    omap3_sms_read32,
+};
+
+static CPUWriteMemoryFunc *omap3_sms_writefn[] = {
+    omap_badwidth_write32,
+    omap_badwidth_write32,
+    omap3_sms_write32,
+};
+
+static void omap3_sms_reset(struct omap3_sms_s *s)
+{
+       s->sms_sysconfig = 0x1;
+       s->sms_class_arbiter0 = 0x500000;
+       s->sms_class_arbiter1 = 0x500;
+       s->sms_class_arbiter2 = 0x55000;
+       s->sms_interclass_arbiter = 0x400040;
+       s->sms_class_rotation[0] = 0x1;
+       s->sms_class_rotation[1] = 0x1;
+       s->sms_class_rotation[2] = 0x1;
+       s->sms_pow_ctrl = 0x80;
+}
+
+static struct omap3_sms_s *omap3_sms_init(struct omap_mpu_state_s *mpu)
+{
+    int iomemtype;
+    struct omap3_sms_s *s = (struct omap3_sms_s *) qemu_mallocz(sizeof(*s));
+
+    s->mpu = mpu;
+
+    omap3_sms_reset(s);
+    
+    iomemtype = cpu_register_io_memory(0, omap3_sms_readfn,
+                                       omap3_sms_writefn, s);
+    cpu_register_physical_memory(0x6c000000, 0x10000, iomemtype);
+
+    register_savevm("omap3_sms", -1, 0,
+                    omap3_sms_save_state, omap3_sms_load_state, s);
+    return s;
+}
+
+static const struct dma_irq_map omap3_dma_irq_map[] = {
+    {0, OMAP_INT_3XXX_SDMA_IRQ0},
+    {0, OMAP_INT_3XXX_SDMA_IRQ1},
+    {0, OMAP_INT_3XXX_SDMA_IRQ2},
+    {0, OMAP_INT_3XXX_SDMA_IRQ3},
+};
+
+static int omap3_validate_addr(struct omap_mpu_state_s *s,
+                               target_phys_addr_t addr)
+{
+    return 1;
+}
+
+struct omap_mpu_state_s *omap3530_mpu_init(unsigned long sdram_size,
+                                           CharDriverState *chr_uart1,
+                                           CharDriverState *chr_uart2,
+                                           CharDriverState *chr_uart3)
+{
+    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
+        qemu_mallocz(sizeof(struct omap_mpu_state_s));
+    ram_addr_t sram_base, q2_base;
+    qemu_irq *cpu_irq;
+    qemu_irq drqs[4];
+    int i;
+
+    s->mpu_model = omap3530;
+    s->env = cpu_init("cortex-a8-r2");
+    if (!s->env) {
+        fprintf(stderr, "Unable to find CPU definition\n");
+        exit(1);
+    }
+    s->sdram_size = sdram_size;
+    s->sram_size = OMAP3XXX_SRAM_SIZE;
+
+    /* Clocks */
+    omap_clk_init(s);
+
+    /* Memory-mapped stuff */
+    q2_base = qemu_ram_alloc(s->sdram_size);
+    cpu_register_physical_memory(OMAP3_Q2_BASE, s->sdram_size,
+                                 q2_base | IO_MEM_RAM);
+    sram_base = qemu_ram_alloc(s->sram_size);
+    cpu_register_physical_memory(OMAP3_SRAM_BASE, s->sram_size,
+                                 sram_base | IO_MEM_RAM);
+
+    s->l4 = omap_l4_init(OMAP3_L4_BASE, 
+                         sizeof(omap3_l4_agent_info) 
+                         / sizeof(struct omap3_l4_agent_info_s));
+
+    cpu_irq = arm_pic_init_cpu(s->env);
+    s->ih[0] = omap2_inth_init(s, 0x48200000, 0x1000, 3, &s->irq[0],
+                               cpu_irq[ARM_PIC_CPU_IRQ],
+                               cpu_irq[ARM_PIC_CPU_FIQ], 
+                               omap_findclk(s, "omap3_mpu_intc_fclk"),
+                               omap_findclk(s, "omap3_mpu_intc_iclk"));
+
+    for (i = 0; i < 4; i++)
+        drqs[i] = s->irq[omap3_dma_irq_map[i].ih][omap3_dma_irq_map[i].intr];
+    s->dma = omap3_dma4_init(omap3_l4ta_init(s->l4, L4A_SDMA), s, drqs, 32,
+                             omap_findclk(s, "omap3_sdma_fclk"),
+                             omap_findclk(s, "omap3_sdma_iclk"));
+    s->port->addr_valid = omap3_validate_addr;
+    soc_dma_port_add_mem_ram(s->dma, q2_base, OMAP2_Q2_BASE, s->sdram_size);
+    soc_dma_port_add_mem_ram(s->dma, sram_base, OMAP2_SRAM_BASE, s->sram_size);
+
+
+    s->omap3_cm = omap3_cm_init(omap3_l4ta_init(s->l4, L4A_CM), NULL, NULL, NULL, s);
+
+    s->omap3_prm = omap3_prm_init(omap3_l4ta_init(s->l4, L4A_PRM),
+                                  s->irq[0][OMAP_INT_3XXX_PRCM_MPU_IRQ],
+                                  NULL, s);
+
+    s->omap3_mpu_wdt = omap3_mpu_wdt_init(omap3_l4ta_init(s->l4, L4A_WDTIMER2),
+                                          NULL,
+                                          omap_findclk(s, "omap3_wkup_32k_fclk"),
+                                          omap_findclk(s, "omap3_wkup_l4_iclk"),
+                                          s);
+
+    s->omap3_l3 = omap3_l3_init(OMAP3_L3_BASE, 
+                                omap3_l3_region,
+                                sizeof(omap3_l3_region)
+                                / sizeof(struct omap_l3_region_s));
+    s->omap3_scm = omap3_scm_init(omap3_l4ta_init(s->l4, L4A_SCM), s);
+
+    s->omap3_sms = omap3_sms_init(s);
+
+    s->gptimer[0] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER1),
+                                       s->irq[0][OMAP_INT_3XXX_GPT1_IRQ],
+                                       omap_findclk(s, "omap3_gp1_fclk"),
+                                       omap_findclk(s, "omap3_wkup_l4_iclk"));
+    s->gptimer[1] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER2),
+                                       s->irq[0][OMAP_INT_3XXX_GPT2_IRQ],
+                                       omap_findclk(s, "omap3_gp2_fclk"),
+                                       omap_findclk(s, "omap3_per_l4_iclk"));
+    s->gptimer[2] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER3),
+                                       s->irq[0][OMAP_INT_3XXX_GPT3_IRQ],
+                                       omap_findclk(s, "omap3_gp3_fclk"),
+                                       omap_findclk(s, "omap3_per_l4_iclk"));
+    s->gptimer[3] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER4),
+                                       s->irq[0][OMAP_INT_3XXX_GPT4_IRQ],
+                                       omap_findclk(s, "omap3_gp4_fclk"),
+                                       omap_findclk(s, "omap3_per_l4_iclk"));
+    s->gptimer[4] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER5),
+                                       s->irq[0][OMAP_INT_3XXX_GPT5_IRQ],
+                                       omap_findclk(s, "omap3_gp5_fclk"),
+                                       omap_findclk(s, "omap3_per_l4_iclk"));
+    s->gptimer[5] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER6),
+                                       s->irq[0][OMAP_INT_3XXX_GPT6_IRQ],
+                                       omap_findclk(s, "omap3_gp6_fclk"),
+                                       omap_findclk(s, "omap3_per_l4_iclk"));
+    s->gptimer[6] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER7),
+                                       s->irq[0][OMAP_INT_3XXX_GPT7_IRQ],
+                                       omap_findclk(s, "omap3_gp7_fclk"),
+                                       omap_findclk(s, "omap3_per_l4_iclk"));
+    s->gptimer[7] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER8),
+                                       s->irq[0][OMAP_INT_3XXX_GPT8_IRQ],
+                                       omap_findclk(s, "omap3_gp8_fclk"),
+                                       omap_findclk(s, "omap3_per_l4_iclk"));
+    s->gptimer[8] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER9),
+                                       s->irq[0][OMAP_INT_3XXX_GPT9_IRQ],
+                                       omap_findclk(s, "omap3_gp9_fclk"),
+                                       omap_findclk(s, "omap3_per_l4_iclk"));
+    s->gptimer[9] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER10),
+                                       s->irq[0][OMAP_INT_3XXX_GPT10_IRQ],
+                                       omap_findclk(s, "omap3_gp10_fclk"),
+                                       omap_findclk(s, "omap3_core_l4_iclk"));
+    s->gptimer[10] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER11),
+                                       s->irq[0][OMAP_INT_3XXX_GPT11_IRQ],
+                                       omap_findclk(s, "omap3_gp12_fclk"),
+                                       omap_findclk(s, "omap3_core_l4_iclk"));
+    s->gptimer[11] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER12),
+                                        s->irq[0][OMAP_INT_3XXX_GPT12_IRQ],
+                                        omap_findclk(s, "omap3_gp12_fclk"),
+                                        omap_findclk(s, "omap3_wkup_l4_iclk"));
+    
+       
+    omap_synctimer_init(omap3_l4ta_init(s->l4, L4A_32KTIMER), s,
+                        omap_findclk(s, "omap3_sys_32k"), NULL);
+
+    s->sdrc = omap_sdrc_init(0x6d000000);
+    
+    s->gpmc = omap_gpmc_init(s, 0x6e000000, s->irq[0][OMAP_INT_3XXX_GPMC_IRQ]);
+    
+
+    s->uart[0] = omap2_uart_init(omap3_l4ta_init(s->l4, L4A_UART1),
+                                 s->irq[0][OMAP_INT_3XXX_UART1_IRQ],
+                                 omap_findclk(s, "omap3_uart1_fclk"),
+                                 omap_findclk(s, "omap3_uart1_iclk"),
+                                 s->drq[OMAP3XXX_DMA_UART1_TX],
+                                 s->drq[OMAP3XXX_DMA_UART1_RX],
+                                 chr_uart1);
+    s->uart[1] = omap2_uart_init(omap3_l4ta_init(s->l4, L4A_UART2),
+                                 s->irq[0][OMAP_INT_3XXX_UART2_IRQ],
+                                 omap_findclk(s, "omap3_uart2_fclk"),
+                                 omap_findclk(s, "omap3_uart2_iclk"),
+                                 s->drq[OMAP3XXX_DMA_UART2_TX],
+                                 s->drq[OMAP3XXX_DMA_UART2_RX],
+                                 chr_uart2);
+    s->uart[2] = omap2_uart_init(omap3_l4ta_init(s->l4, L4A_UART3),
+                                 s->irq[0][OMAP_INT_3XXX_UART3_IRQ],
+                                 omap_findclk(s, "omap3_uart2_fclk"),
+                                 omap_findclk(s, "omap3_uart3_iclk"),
+                                 s->drq[OMAP3XXX_DMA_UART3_TX],
+                                 s->drq[OMAP3XXX_DMA_UART3_RX],
+                                 chr_uart3);
+    
+    s->dss = omap_dss_init(s, omap3_l4ta_init(s->l4, L4A_DSS), 
+                    s->irq[0][OMAP_INT_3XXX_DSS_IRQ], s->drq[OMAP24XX_DMA_DSS],
+                   NULL,NULL,NULL,NULL,NULL);
+
+    s->gpif = omap3_gpif_init();
+    omap3_gpio_init(s, s->gpif, omap3_l4ta_init(s->l4, L4A_GPIO1),
+                    s->irq[0][OMAP_INT_3XXX_GPIO1_MPU_IRQ], 
+                    NULL,NULL,0);
+    omap3_gpio_init(s, s->gpif, omap3_l4ta_init(s->l4, L4A_GPIO2),
+                    s->irq[0][OMAP_INT_3XXX_GPIO2_MPU_IRQ], 
+                    NULL,NULL,1);
+    omap3_gpio_init(s, s->gpif, omap3_l4ta_init(s->l4, L4A_GPIO3),
+                    s->irq[0][OMAP_INT_3XXX_GPIO3_MPU_IRQ], 
+                    NULL,NULL,2);
+    omap3_gpio_init(s, s->gpif, omap3_l4ta_init(s->l4, L4A_GPIO4),
+                    s->irq[0][OMAP_INT_3XXX_GPIO4_MPU_IRQ], 
+                    NULL,NULL,3);
+    omap3_gpio_init(s, s->gpif, omap3_l4ta_init(s->l4, L4A_GPIO5),
+                    s->irq[0][OMAP_INT_3XXX_GPIO5_MPU_IRQ], 
+                    NULL,NULL,4);
+    omap3_gpio_init(s, s->gpif, omap3_l4ta_init(s->l4, L4A_GPIO6),
+                    s->irq[0][OMAP_INT_3XXX_GPIO6_MPU_IRQ], 
+                    NULL,NULL,5);
+
+    omap_tap_init(omap3_l4ta_init(s->l4, L4A_TAP), s);
+
+    s->omap3_mmc[0] = omap3_mmc_init(omap3_l4ta_init(s->l4, L4A_MMC1),
+                                     s->irq[0][OMAP_INT_3XXX_MMC1_IRQ],
+                                     &s->drq[OMAP3XXX_DMA_MMC1_TX],
+                                     omap_findclk(s, "omap3_mmc1_fclk"),
+                                     omap_findclk(s, "omap3_mmc1_iclk"));
+
+    s->omap3_mmc[1] = omap3_mmc_init(omap3_l4ta_init(s->l4, L4A_MMC2),
+                                     s->irq[0][OMAP_INT_3XXX_MMC2_IRQ],
+                                     &s->drq[OMAP3XXX_DMA_MMC2_TX],
+                                     omap_findclk(s, "omap3_mmc2_fclk"),
+                                     omap_findclk(s, "omap3_mmc2_iclk"));
+
+    s->omap3_mmc[2] = omap3_mmc_init(omap3_l4ta_init(s->l4, L4A_MMC3),
+                                     s->irq[0][OMAP_INT_3XXX_MMC3_IRQ],
+                                     &s->drq[OMAP3XXX_DMA_MMC3_TX],
+                                     omap_findclk(s, "omap3_mmc3_fclk"),
+                                     omap_findclk(s, "omap3_mmc3_iclk"));
+
+    s->i2c[0] = omap3_i2c_init(omap3_l4ta_init(s->l4, L4A_I2C1),
+                               s->irq[0][OMAP_INT_3XXX_I2C1_IRQ],
+                               &s->drq[OMAP3XXX_DMA_I2C1_TX],
+                               omap_findclk(s, "omap3_i2c1_fclk"),
+                               omap_findclk(s, "omap3_i2c1_iclk"),
+                               8);
+    s->i2c[1] = omap3_i2c_init(omap3_l4ta_init(s->l4, L4A_I2C2),
+                               s->irq[0][OMAP_INT_3XXX_I2C2_IRQ],
+                               &s->drq[OMAP3XXX_DMA_I2C2_TX],
+                               omap_findclk(s, "omap3_i2c2_fclk"),
+                               omap_findclk(s, "omap3_i2c2_iclk"),
+                               8);
+    s->i2c[2] = omap3_i2c_init(omap3_l4ta_init(s->l4, L4A_I2C3),
+                               s->irq[0][OMAP_INT_3XXX_I2C3_IRQ],
+                               &s->drq[OMAP3XXX_DMA_I2C3_TX],
+                               omap_findclk(s, "omap3_i2c3_fclk"),
+                               omap_findclk(s, "omap3_i2c3_iclk"),
+                               64);
+
+    s->omap3_usb = omap3_hsusb_init(omap3_l4ta_init(s->l4, L4A_USBHS_OTG),
+                                    omap3_l4ta_init(s->l4, L4A_USBHS_HOST),
+                                    omap3_l4ta_init(s->l4, L4A_USBHS_TLL),
+                                    s->irq[0][OMAP_INT_3XXX_HSUSB_MC],
+                                    s->irq[0][OMAP_INT_3XXX_HSUSB_DMA],
+                                    s->irq[0][OMAP_INT_3XXX_OHCI_IRQ],
+                                    s->irq[0][OMAP_INT_3XXX_EHCI_IRQ],
+                                    s->irq[0][OMAP_INT_3XXX_TLL_IRQ]);
+
+    s->mcspi[0] = omap_mcspi_init(omap3_l4ta_init(s->l4, L4A_MCSPI1), s, 4,
+                                  s->irq[0][OMAP_INT_3XXX_MCSPI1_IRQ],
+                                  &s->drq[OMAP3XXX_DMA_SPI1_TX0],
+                                  omap_findclk(s, "omap3_spi1_fclk"),
+                                  omap_findclk(s, "omap3_spi1_iclk"));
+    s->mcspi[1] = omap_mcspi_init(omap3_l4ta_init(s->l4, L4A_MCSPI2), s, 2,
+                                  s->irq[0][OMAP_INT_3XXX_MCSPI2_IRQ],
+                                  &s->drq[OMAP3XXX_DMA_SPI2_TX0],
+                                  omap_findclk(s, "omap3_spi2_fclk"),
+                                  omap_findclk(s, "omap3_spi2_iclk"));
+    drqs[0] = s->drq[OMAP3XXX_DMA_SPI3_TX0];
+    drqs[1] = s->drq[OMAP3XXX_DMA_SPI3_RX0];
+    drqs[2] = s->drq[OMAP3XXX_DMA_SPI3_TX1];
+    drqs[3] = s->drq[OMAP3XXX_DMA_SPI3_RX1];
+    s->mcspi[2] = omap_mcspi_init(omap3_l4ta_init(s->l4, L4A_MCSPI3), s, 2,
+                                  s->irq[0][OMAP_INT_3XXX_MCSPI3_IRQ],
+                                  drqs,
+                                  omap_findclk(s, "omap3_spi3_fclk"),
+                                  omap_findclk(s, "omap3_spi3_iclk"));
+    s->mcspi[3] = omap_mcspi_init(omap3_l4ta_init(s->l4, L4A_MCSPI4), s, 1,
+                                  s->irq[0][OMAP_INT_3XXX_MCSPI4_IRQ],
+                                  &s->drq[OMAP3XXX_DMA_SPI4_TX0],
+                                  omap_findclk(s, "omap3_spi4_fclk"),
+                                  omap_findclk(s, "omap3_spi4_iclk"));
+    
+    return s;
+}