#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_
[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;
}
}
+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[] = {
}
}
+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[] = {
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;
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_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));
}
return bus;
+#endif
}
typedef enum {
/* 48061000-48061FFF */ L4ID_I2C3_TA,
/* 48062000-48062FFF */ L4ID_USBTLL,
/* 48063000-48063FFF */ L4ID_USBTLL_TA,
- /* 48064000-48064FFF */ L4ID_HSUSBHOST,
- /* 48065000-48065FFF */ L4ID_HSUSBHOST_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,
[L4ID_I2C3_TA ] = {0x00061000, 0x1000, L4TYPE_TA},
[L4ID_USBTLL ] = {0x00062000, 0x1000, L4TYPE_GENERIC},
[L4ID_USBTLL_TA ] = {0x00063000, 0x1000, L4TYPE_TA},
- [L4ID_HSUSBHOST ] = {0x00064000, 0x1000, L4TYPE_GENERIC},
- [L4ID_HSUSBHOST_TA] = {0x00065000, 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},
L4A_TAP,
L4A_USBHS_OTG,
L4A_USBHS_HOST,
- L4A_USBHS_TLL
+ 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 {
{L4A_DSS, L4ID_DSI, 6},
/* TODO: camera */
{L4A_USBHS_OTG, L4ID_HSUSBOTG, 2},
- {L4A_USBHS_HOST, L4ID_HSUSBHOST, 2},
+ {L4A_USBHS_HOST, L4ID_USBHOST, 4},
{L4A_USBHS_TLL, L4ID_USBTLL, 2},
{L4A_UART1, L4ID_UART1, 2},
{L4A_UART2, L4ID_UART2, 2},
/* TODO: McBSP5 */
{L4A_GPTIMER10, L4ID_GPTIMER10, 2},
{L4A_GPTIMER11, L4ID_GPTIMER11, 2},
- /* TODO: SPI1 */
- /* TODO: SPI2 */
+ {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 */
- /* TODO: SPI3 */
- /* TODO: SPI4 */
- /* TODO: SDMA */
+ {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},
{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;
}
}
+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,
omap_badwidth_write32,
omap3_l4ta_write,
};
+#endif
static struct omap_target_agent_s *omap3_l4ta_init(struct omap_l4_s *bus, int cs)
{
- int i, iomemtype;
+#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;
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_wkdep; /* c8 */
- uint32_t pm_pwstctrl; /* e0 */
- uint32_t pm_pwstst; /* e4 */
- uint32_t pm_prepwstst; /* e8 */
+ 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 {
struct omap3_prm_domain_s neon;
struct omap3_prm_domain_s usbhost;
- uint32_t iva2_prm_irqstatus;
- uint32_t iva2_prm_irqenable;
+ uint32_t prm_irqstatus_iva2;
+ uint32_t prm_irqenable_iva2;
- uint32_t mpu_pm_evgenctrl;
- uint32_t mpu_pm_evgenontim;
- uint32_t mpu_pm_evgenofftim;
-
- uint32_t core_pm_wkst3;
- uint32_t core_pm_wken3;
- uint32_t core_pm_iva2grpsel3;
- uint32_t core_pm_mpugrpsel3;
+ uint32_t pm_iva2grpsel3_core;
+ uint32_t pm_mpugrpsel3_core;
struct {
uint32_t prm_revision;
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->iva2_prm_irqstatus & s->iva2_prm_irqenable);
+ 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->iva2.pm_prepwstst = 0x0;
- s->iva2_prm_irqstatus = 0x0;
- s->iva2_prm_irqenable = 0x0;
+ 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;
- s->ocp.prm_irqstatus_mpu = 0x0;
- s->ocp.prm_irqenable_mpu = 0x0;
-
+
+ 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_pwstst = 0x0;
- s->mpu_pm_evgenctrl = 0x12;
- s->mpu_pm_evgenontim = 0x0;
- s->mpu_pm_evgenofftim = 0x0;
+ 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_wkst = 0x0;
s->core.pm_pwstctrl = 0xf0307;
s->core.pm_pwstst = 0xf7;
- s->core.pm_prepwstst = 0x0;
- s->core_pm_wkst3 = 0x0;
- s->core_pm_wken3 = 0x4;
- s->core_pm_iva2grpsel3 = 0x4;
- s->core_pm_mpugrpsel3 = 0x4;
+ 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;
- s->sgx.pm_prepwstst = 0x0;
+ bzero(&s->wkup, sizeof(s->wkup));
s->wkup.pm_wken = 0x3cb;
s->wkup.pm_mpugrpsel = 0x3cb;
- s->wkup.pm_ivagrpsel = 0x0;
- s->wkup.pm_wkst = 0x0;
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;
- s->dss.pm_prepwstst = 0x0;
+ 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;
- s->cam.pm_prepwstst = 0x0;
+ 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_wkst = 0x0;
s->per.pm_wkdep = 0x17;
s->per.pm_pwstctrl = 0x30107;
s->per.pm_pwstst = 0x7;
- s->per.pm_prepwstst = 0x0;
+ bzero(&s->emu, sizeof(s->emu));
s->emu.rm_rstst = 0x1;
s->emu.pm_pwstst = 0x13;
- s->gr.prm_vc_smps_sa = 0x0;
- s->gr.prm_vc_smps_vol_ra = 0x0;
- s->gr.prm_vc_smps_cmd_ra = 0x0;
- s->gr.prm_vc_cmd_val_0 = 0x0;
- s->gr.prm_vc_cmd_val_1 = 0x0;
- s->gr.prm_vc_hc_conf = 0x0;
+ bzero(&s->gr, sizeof(s->gr));
s->gr.prm_vc_i2c_cfg = 0x18;
- s->gr.prm_vc_bypass_val = 0x0;
- s->gr.prm_rstctrl = 0x0;
s->gr.prm_rsttimer = 0x1006;
s->gr.prm_rstst = 0x1;
- s->gr.prm_voltctrl = 0x0;
s->gr.prm_sram_pcharge = 0x50;
s->gr.prm_clksrc_ctrl = 0x43;
- s->gr.prm_obs = 0x0;
- s->gr.prm_voltsetup1 = 0x0;
- s->gr.prm_voltoffset = 0x0;
- s->gr.prm_clksetup = 0x0;
s->gr.prm_polctrl = 0xa;
- s->gr.prm_voltsetup2 = 0x0;
+ 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;
- s->neon.pm_prepwstst = 0x0;
+ 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_wkst = 0x0;
s->usbhost.pm_wkdep = 0x17;
s->usbhost.pm_pwstctrl = 0x30107;
s->usbhost.pm_pwstst = 0x3;
- s->usbhost.pm_prepwstst = 0x0;
omap3_prm_int_update(s);
}
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->iva2_prm_irqstatus;
- case 0x00fc: return s->iva2_prm_irqenable;
+ 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 0x09d4: return s->mpu_pm_evgenctrl;
- case 0x09d8: return s->mpu_pm_evgenontim;
- case 0x09dc: return s->mpu_pm_evgenofftim;
- case 0x0ab8: return s->core_pm_wkst3;
- case 0x0af0: return s->core_pm_wken3;
- case 0x0af4: return s->core_pm_iva2grpsel3;
- case 0x0af8: return s->core_pm_mpugrpsel3;
+ 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 */
return 0;
}
-static inline void omap3_prm_clksrc_ctrl_update(struct omap3_prm_s *s,
- uint32_t value)
+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)
case 0x00e4: OMAP_RO_REG(addr); break;
case 0x00e8: s->iva2.pm_prepwstst = value & 0xff7;
case 0x00f8:
- s->iva2_prm_irqstatus &= ~(value & 0x7);
+ s->prm_irqstatus_iva2 &= ~(value & 0x7);
omap3_prm_int_update(s);
break;
case 0x00fc:
- s->iva2_prm_irqenable = value & 0x7;
+ s->prm_irqenable_iva2 = value & 0x7;
omap3_prm_int_update(s);
break;
/* OCP_System_Reg_PRM */
/* 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 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;
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 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->core_pm_iva2grpsel3 = value & 0x4; break;
- case 0x0af8: s->core_pm_mpugrpsel3 = value & 0x4; 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 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, s->gr.prm_clksrc_ctrl);
+ omap3_prm_clksrc_ctrl_update(s);
break;
case 0x1280: OMAP_RO_REG(addr); break;
case 0x1290: s->gr.prm_voltsetup1 = 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_write,
};
-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)
+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));
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;
}
uint32_t cm_clkstst_usbhost; /* 4c */
};
-/*
-static inline void omap3_cm_fclken_wkup_update(struct omap3_cm_s *s,
- uint32_t value)
+static inline void omap3_cm_clksel_wkup_update(struct omap3_cm_s *s)
{
-
- if (value & 0x28)
- omap_clk_onoff(omap_findclk(s->mpu,"omap3_wkup_32k_fclk"), 1);
- else
- omap_clk_onoff(omap_findclk(s->mpu,"omap3_wkup_32k_fclk"), 0);
-
- if (value &0x1)
- omap_clk_onoff(omap_findclk(s->mpu,"omap3_gp1_fclk"), 1);
- else
- omap_clk_onoff(omap_findclk(s->mpu,"omap3_gp1_fclk"), 0);
-
-}
-static inline void omap3_cm_iclken_wkup_update(struct omap3_cm_s *s,
- uint32_t value)
-{
-
- if (value & 0x3f)
- omap_clk_onoff(omap_findclk(s->mpu,"omap3_wkup_l4_iclk"), 1);
- else
- omap_clk_onoff(omap_findclk(s->mpu,"omap3_wkup_l4_iclk"), 0);
-
-}
-*/
-static inline void omap3_cm_clksel_wkup_update(struct omap3_cm_s *s,
- uint32_t value)
-{
- omap_clk gp1_fclk = omap_findclk(s->mpu, "omap3_gp1_fclk");
-
- if (value & 0x1)
- omap_clk_reparent(gp1_fclk, omap_findclk(s->mpu, "omap3_sys_clk"));
- else
- omap_clk_reparent(gp1_fclk, omap_findclk(s->mpu, "omap3_32k_fclk"));
- /*Tell GPTIMER to generate new clk rate */
+ 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("omap3_gp1_fclk %lld",
+ TRACE("gptimer1 fclk=%lld",
omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp1_fclk")));
- /*TODO:CM_USIM_CLK CLKSEL_RM */
+ /* TODO: CM_USIM_CLK */
}
static inline void omap3_cm_iva2_update(struct omap3_cm_s *s)
{
- uint32_t m = ((s->cm_clksel1_pll_iva2 >> 8) & 0x7ff);
- uint32_t n, divide, m2;
+ 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 (m < 2)
+ if (iva2_dpll_mul < 2)
s->cm_idlest_pll_iva2 &= ~1;
else
s->cm_idlest_pll_iva2 |= 1;
}
if (s->cm_idlest_pll_iva2 & 1) {
- n = (s->cm_clksel1_pll_iva2 & 0x7f);
- m2 = (s->cm_clksel2_pll_iva2 & 0x1f);
+ 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, (n + 1) * m2, m);
+ omap_clk_setrate(iva2_clk,
+ (iva2_dpll_div + 1) * iva2_dpll_clkout_div,
+ iva2_dpll_mul);
} else {
/* bypass mode */
- divide = (s->cm_clksel1_pll_iva2 & 0x380000) >> 19;
+ 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, divide, 1);
+ omap_clk_setrate(iva2_clk, iva2_clk_src, 1);
}
}
static inline void omap3_cm_mpu_update(struct omap3_cm_s *s)
{
- uint32_t m = ((s->cm_clksel1_pll_mpu >> 8) & 0x7ff);
- uint32_t n, divide, m2;
+ 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)) {
s->cm_idlest_pll_mpu &= ~1;
break;
case 0x07: /* locked */
- if (m < 2)
+ if (mpu_dpll_mul < 2)
s->cm_idlest_pll_mpu &= ~1;
else
s->cm_idlest_pll_mpu |= 1;
}
if (s->cm_idlest_pll_mpu & 1) {
- n = (s->cm_clksel1_pll_mpu & 0x7f);
- m2 = (s->cm_clksel2_pll_mpu & 0x1f);
+ 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, (n + 1) * m2, m);
+ omap_clk_setrate(mpu_clk,
+ (mpu_dpll_div + 1) * mpu_dpll_clkout_div,
+ mpu_dpll_mul);
} else {
/* bypass mode */
- divide = (s->cm_clksel1_pll_mpu & 0x380000) >> 19;
+ 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, divide, 1);
+ omap_clk_setrate(mpu_clk, mpu_clk_src, 1);
}
}
static inline void omap3_cm_dpll3_update(struct omap3_cm_s *s)
{
- uint32_t m = ((s->cm_clksel1_pll >> 16) & 0x7ff);
- uint32_t n, m2, m3;
+ 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 */
s->cm_idlest_ckgen &= ~1;
break;
case 0x07: /* locked */
- if (m < 2)
+ if (core_dpll_mul < 2)
s->cm_idlest_ckgen &= ~1;
else
s->cm_idlest_ckgen |= 1;
}
if (s->cm_idlest_ckgen & 1) {
- n = (s->cm_clksel1_pll & 0x3f00) >> 8;
- m2 = (s->cm_clksel1_pll & 0xf8000000) >> 27;
- m3 = (s->cm_clksel1_emu & 0x1f0000) >> 16;
+ 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 control of DPLL3 */
- m = (s->cm_clksel2_emu & 0x7ff) >> 8;
- n = s->cm_clksel2_emu & 0x7f;
+ 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"), (n + 1) * m2, m);
- omap_clk_setrate(omap_findclk(s->mpu, "omap3_core2_clk"), (n + 1) * m2, m * 2);
- omap_clk_setrate(omap_findclk(s->mpu, "omap3_emu_core_alwon_clk"), (n + 1) * m3, m * 2);
+ 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);
static inline void omap3_cm_dpll4_update(struct omap3_cm_s *s)
{
- uint32_t m = ((s->cm_clksel2_pll >> 8) & 0x7ff);
- uint32_t n, m2, m3, m4, m5, m6;
+ 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 (m < 2)
+ if (per_dpll_mul < 2)
s->cm_idlest_ckgen &= ~2;
else
s->cm_idlest_ckgen |= 2;
}
if (s->cm_idlest_ckgen & 2) {
- n = (s->cm_clksel2_pll & 0x7f);
- m2 = s->cm_clksel3_pll & 0x1f;
- m3 = (s->cm_clksel_dss & 0x1f00) >> 8;
- m4 = s->cm_clksel_dss & 0x1f;
- m5 = s->cm_clksel_cam & 0x1f;
- m6 = (s->cm_clksel1_emu & 0x1f000000) >> 24;
+ 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 control of DPLL4 */
- m = (s->cm_clksel3_emu & 0x7ff) >> 8;
- n = s->cm_clksel3_emu & 0x7f;
+ 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"), (n + 1) * m2, m * 2);
- omap_clk_setrate(omap_findclk(s->mpu, "omap3_54m_fclk"), (n + 1) * m3, m * 2);
- omap_clk_setrate(omap_findclk(s->mpu, "omap3_dss1_alwon_fclk"), (n + 1) * m4, m * 2);
- omap_clk_setrate(omap_findclk(s->mpu, "omap3_cam_mclk"), (n + 1) * m5, m * 2);
- omap_clk_setrate(omap_findclk(s->mpu, "omap3_per_alwon_clk"), (n + 1) * m6, m * 2);
+ 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);
static inline void omap3_cm_dpll5_update(struct omap3_cm_s *s)
{
- uint32_t m = ((s->cm_clksel4_pll >> 8) & 0x7ff);
- uint32_t n, m2;
+ 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 (m < 2)
+ if (per2_dpll_mul < 2)
s->cm_idlest2_ckgen &= ~1;
else
s->cm_idlest2_ckgen |= 1;
}
if (s->cm_idlest2_ckgen & 1) {
- m = (s->cm_clksel4_pll & 0x7ff00)>>8;
- n = s->cm_clksel4_pll & 0x3f00;
- m2 = s->cm_clksel5_pll & 0x1f;
+ 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"), (n + 1) * m2, m);
+ 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)
{
- if (s->cm_clksel1_pll & 0x8)
- {
- /*parent is sysaltclk */
- omap_clk_reparent(omap_findclk(s->mpu, "omap3_48m_fclk"),
- omap_findclk(s->mpu, "omap3_sys_altclk"));
- omap_clk_reparent(omap_findclk(s->mpu, "omap3_12m_fclk"),
- omap_findclk(s->mpu, "omap3_sys_altclk"));
- /*TODO:need to set rate ? */
-
- }
- else
- {
- omap_clk_reparent(omap_findclk(s->mpu, "omap3_12m_fclk"),
- omap_findclk(s->mpu, "omap3_96m_fclk"));
- omap_clk_reparent(omap_findclk(s->mpu, "omap3_48m_fclk"),
- omap_findclk(s->mpu, "omap3_96m_fclk"));
- omap_clk_setrate(omap_findclk(s->mpu, "omap3_48m_fclk"), 2, 1);
- omap_clk_setrate(omap_findclk(s->mpu, "omap3_12m_fclk"), 8, 1);
-
- }
-
+ 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_gp10_update(struct omap3_cm_s *s)
+static inline void omap3_cm_gp10gp11_update(struct omap3_cm_s *s)
{
- omap_clk gp10_fclk = omap_findclk(s->mpu, "omap3_gp10_fclk");
-
- if (s->cm_clksel_core & 0x40)
- omap_clk_reparent(gp10_fclk, omap_findclk(s->mpu, "omap3_sys_clk"));
- else
- omap_clk_reparent(gp10_fclk, omap_findclk(s->mpu, "omap3_32k_fclk"));
+ 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");
- /*Tell GPTIMER10 to generate new clk rate */
+ 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]);
- TRACE("omap3_gp10_fclk %lld",
- omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp10_fclk")));
-}
-
-static inline void omap3_cm_gp11_update(struct omap3_cm_s *s)
-{
- omap_clk gp11_fclk = omap_findclk(s->mpu, "omap3_gp11_fclk");
-
- if (s->cm_clksel_core & 0x80)
- omap_clk_reparent(gp11_fclk, omap_findclk(s->mpu, "omap3_sys_clk"));
- else
- omap_clk_reparent(gp11_fclk, omap_findclk(s->mpu, "omap3_32k_fclk"));
- /*Tell GPTIMER11 to generate new clk rate */
omap_gp_timer_change_clk(s->mpu->gptimer[10]);
- TRACE("omap3_gp11_fclk %lld",
- omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp11_fclk")));
+
+ TRACE("gptimer10 fclk = %lld", omap_clk_getrate(gp10));
+ TRACE("gptimer11 fclk = %lld", omap_clk_getrate(gp11));
}
-static inline void omap3_cm_l3clk_update(struct omap3_cm_s *s)
+static inline void omap3_cm_per_gptimer_update(struct omap3_cm_s *s)
{
- omap_clk l3_iclk = omap_findclk(s->mpu, "omap3_l3_iclk");
- if ((s->cm_clksel_core & 0x3) == 0x1)
- omap_clk_setrate(l3_iclk, 1, 1);
- else if ((s->cm_clksel_core & 0x3) == 0x2)
- omap_clk_setrate(l3_iclk, 2, 1);
+ 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_l4clk_update(struct omap3_cm_s *s)
+static inline void omap3_cm_clkout2_update(struct omap3_cm_s *s)
{
- omap_clk l4_iclk = omap_findclk(s->mpu, "omap3_l4_iclk");
- if ((s->cm_clksel_core & 0xc) == 0x4)
- omap_clk_setrate(l4_iclk, 1, 1);
- else if ((s->cm_clksel_core & 0xc) == 0x8)
- omap_clk_setrate(l4_iclk, 2, 1);
+ 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_per_gptimer_update(struct omap3_cm_s *s)
+static inline void omap3_cm_fclken1_core_update(struct omap3_cm_s *s)
{
- uint32_t cm_clksel_per = s->cm_clksel_per;
-
- if (cm_clksel_per & 0x1)
- omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp2_fclk"),
- omap_findclk(s->mpu, "omap3_sys_clk"));
- else
- omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp2_fclk"),
- omap_findclk(s->mpu, "omap3_32k_fclk"));
- omap_gp_timer_change_clk(s->mpu->gptimer[1]);
-
- if (cm_clksel_per & 0x2)
- omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp3_fclk"),
- omap_findclk(s->mpu, "omap3_sys_clk"));
- else
- omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp3_fclk"),
- omap_findclk(s->mpu, "omap3_32k_fclk"));
- omap_gp_timer_change_clk(s->mpu->gptimer[2]);
-
- if (cm_clksel_per & 0x4)
- omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp4_fclk"),
- omap_findclk(s->mpu, "omap3_sys_clk"));
- else
- omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp4_fclk"),
- omap_findclk(s->mpu, "omap3_32k_fclk"));
- omap_gp_timer_change_clk(s->mpu->gptimer[3]);
-
- if (cm_clksel_per & 0x8)
- omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp5_fclk"),
- omap_findclk(s->mpu, "omap3_sys_clk"));
- else
- omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp5_fclk"),
- omap_findclk(s->mpu, "omap3_32k_fclk"));
- omap_gp_timer_change_clk(s->mpu->gptimer[4]);
-
- if (cm_clksel_per & 0x10)
- omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp6_fclk"),
- omap_findclk(s->mpu, "omap3_sys_clk"));
- else
- omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp6_fclk"),
- omap_findclk(s->mpu, "omap3_32k_fclk"));
- omap_gp_timer_change_clk(s->mpu->gptimer[5]);
+ uint32_t v = s->cm_fclken1_core;
- if (cm_clksel_per & 0x20)
- omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp7_fclk"),
- omap_findclk(s->mpu, "omap3_sys_clk"));
- else
- omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp7_fclk"),
- omap_findclk(s->mpu, "omap3_32k_fclk"));
- omap_gp_timer_change_clk(s->mpu->gptimer[6]);
-
+ /* 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);
+}
- if (cm_clksel_per & 0x40)
- omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp8_fclk"),
- omap_findclk(s->mpu, "omap3_sys_clk"));
- else
- omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp8_fclk"),
- omap_findclk(s->mpu, "omap3_32k_fclk"));
- omap_gp_timer_change_clk(s->mpu->gptimer[7]);
+static inline void omap3_cm_iclken1_core_update(struct omap3_cm_s *s)
+{
+ uint32_t v = s->cm_iclken1_core;
- if (cm_clksel_per & 0x80)
- omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp9_fclk"),
- omap_findclk(s->mpu, "omap3_sys_clk"));
- else
- omap_clk_reparent(omap_findclk(s->mpu, "omap3_gp9_fclk"),
- omap_findclk(s->mpu, "omap3_32k_fclk"));
- omap_gp_timer_change_clk(s->mpu->gptimer[8]);
-
- /*TODO:Tell GPTIMER to generate new clk rate */
- TRACE("omap3_gp2_fclk %lld",
- omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp2_fclk")));
- TRACE("omap3_gp3_fclk %lld",
- omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp3_fclk")));
- TRACE("omap3_gp4_fclk %lld",
- omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp4_fclk")));
- TRACE("omap3_gp5_fclk %lld",
- omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp5_fclk")));
- TRACE("omap3_gp6_fclk %lld",
- omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp6_fclk")));
- TRACE("omap3_gp7_fclk %lld",
- omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp7_fclk")));
- TRACE("omap3_gp8_fclk %lld",
- omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp8_fclk")));
- TRACE("omap3_gp9_fclk %lld",
- omap_clk_getrate(omap_findclk(s->mpu, "omap3_gp9_fclk")));
+ /* 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_clkout2_update(struct omap3_cm_s *s)
+static inline void omap3_cm_l3l4iclk_update(struct omap3_cm_s *s)
{
- uint32 divor;
-
- if (!s->cm_clkout_ctrl&0x80)
- return;
-
- switch (s->cm_clkout_ctrl&0x3)
- {
- case 0x0:
- omap_clk_reparent(omap_findclk(s->mpu, "omap3_sys_clkout2"),
- omap_findclk(s->mpu, "omap3_core_clk"));
- break;
- case 0x1:
- omap_clk_reparent(omap_findclk(s->mpu, "omap3_sys_clkout2"),
- omap_findclk(s->mpu, "omap3_sys_clk"));
- break;
- case 0x2:
- omap_clk_reparent(omap_findclk(s->mpu, "omap3_sys_clkout2"),
- omap_findclk(s->mpu, "omap3_96m_fclk"));
- break;
- case 0x3:
- omap_clk_reparent(omap_findclk(s->mpu, "omap3_sys_clkout2"),
- omap_findclk(s->mpu, "omap3_54m_fclk"));
- break;
- }
-
- divor = (s->cm_clkout_ctrl&0x31)>>3;
- divor = 1<<divor;
- omap_clk_setrate(omap_findclk(s->mpu, "omap3_sys_clkout2"), divor, 1);
-
+ 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)
OMAP_RO_REGV(addr, value);
break;
/* IVA2_CM */
- case 0x0000: s->cm_fclken_iva2 = value & 0x1; 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;
+ 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;
+ 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;
+ 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; break;
- case 0xa08: s->cm_fclken3_core = value & 0x7; break;
+ 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;
- s->cm_idlest1_core = ~s->cm_iclken1_core;
- /* TODO: replace code below with real implementation */
- s->cm_idlest1_core &= ~0x20; /* HS OTG USB idle */
- s->cm_idlest1_core |= 4; /* SDMA in standby */
+ omap3_cm_iclken1_core_update(s);
+ break;
+ case 0xa14:
+ s->cm_iclken2_core = value & 0x1f;
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 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);
- s->cm_clksel_core |= 0x100;
- omap3_cm_gp10_update(s);
- omap3_cm_gp11_update(s);
- omap3_cm_l3clk_update(s);
- omap3_cm_l4clk_update(s);
- break;
- case 0xa48: s->cm_clkstctrl_core = value & 0xf; break;
+ 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 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; break;
- case 0xc10: s->cm_iclken_wkup = value & 0x2ff; break;
+ 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, s->cm_clksel_wkup);
+ omap3_cm_clksel_wkup_update(s);
break;
/* Clock_Control_Reg_CM */
case 0xd00:
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: /*CM_CLKSEL3_PLL */
+ case 0xd48:
s->cm_clksel3_pll = value & 0x1f;
omap3_cm_dpll4_update(s);
break;
- case 0xd4c: /*CM_CLKSEL4_PLL */
+ case 0xd4c:
s->cm_clksel4_pll = value & 0x7ff7f;
omap3_cm_dpll5_update(s);
break;
- case 0xd50: /*CM_CLKSEL5_PLL */
+ case 0xd50:
s->cm_clksel5_pll = value & 0x1f;
omap3_cm_dpll5_update(s);
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;
+ 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,
omap3_cm_write,
};
-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)
+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));
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;
}
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,
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 {
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 { \
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;
}
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;
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;
}
-#define OMAP3_BOOT_ROM_SIZE 0x1c000 /* 80 + 32 kB */
-
static const struct dma_irq_map omap3_dma_irq_map[] = {
{0, OMAP_INT_3XXX_SDMA_IRQ0},
{0, OMAP_INT_3XXX_SDMA_IRQ1},
}
struct omap_mpu_state_s *omap3530_mpu_init(unsigned long sdram_size,
- const char *core)
+ 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, bootrom_base;
+ ram_addr_t sram_base, q2_base;
qemu_irq *cpu_irq;
- qemu_irq dma_irqs[4];
+ qemu_irq drqs[4];
int i;
s->mpu_model = omap3530;
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);
- bootrom_base = qemu_ram_alloc(OMAP3XXX_BOOTROM_SIZE);
- cpu_register_physical_memory(OMAP3_Q1_BASE, OMAP3_BOOT_ROM_SIZE,
- bootrom_base | IO_MEM_ROM);
- cpu_register_physical_memory(0, OMAP3_BOOT_ROM_SIZE,
- bootrom_base | IO_MEM_ROM);
s->l4 = omap_l4_init(OMAP3_L4_BASE,
sizeof(omap3_l4_agent_info)
omap_findclk(s, "omap3_mpu_intc_iclk"));
for (i = 0; i < 4; i++)
- dma_irqs[i] =
- s->irq[omap3_dma_irq_map[i].ih][omap3_dma_irq_map[i].intr];
- s->dma = omap_dma4_init(0x48056000, dma_irqs, s, 256, 32,
- omap_findclk(s, "omap3_sdma_fclk"),
- omap_findclk(s, "omap3_sdma_iclk"));
+ 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;
-
- /* Register SDRAM and SRAM ports for fast DMA transfers. */
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);
omap_findclk(s, "omap3_uart1_fclk"),
omap_findclk(s, "omap3_uart1_iclk"),
s->drq[OMAP3XXX_DMA_UART1_TX],
- s->drq[OMAP3XXX_DMA_UART1_RX], 0);
+ 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], 0);
+ 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], 0);
+ 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],
+ 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],
+ 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],
+ 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],
+ 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],
+ 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],
+ 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->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;
}