diff options
author | Jean-Christophe DUBOIS <jcd@tribudubois.net> | 2016-01-11 15:52:18 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2016-01-11 15:52:18 +0000 |
commit | fea01f9604cc7f7834911d9b0517fa48b6e32147 (patch) | |
tree | c39d9e6b539596b42a4791139a12c8662df05dad /hw | |
parent | ac0d9dbf33608d0b178e0bd414ec7397ada17834 (diff) |
i.MX: move i.MX31 CCM object to register array
With this i.MX25 and i.MX31 will have closer implementations.
Moreover all i.MX31 CCM registers are now present.
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
Reviewed-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/misc/imx31_ccm.c | 188 |
1 files changed, 85 insertions, 103 deletions
diff --git a/hw/misc/imx31_ccm.c b/hw/misc/imx31_ccm.c index b92d2e0392..47d6ead5ad 100644 --- a/hw/misc/imx31_ccm.c +++ b/hw/misc/imx31_ccm.c @@ -29,77 +29,73 @@ static char const *imx31_ccm_reg_name(uint32_t reg) { + static char unknown[20]; + switch (reg) { - case 0: + case IMX31_CCM_CCMR_REG: return "CCMR"; - case 1: + case IMX31_CCM_PDR0_REG: return "PDR0"; - case 2: + case IMX31_CCM_PDR1_REG: return "PDR1"; - case 3: + case IMX31_CCM_RCSR_REG: return "RCSR"; - case 4: + case IMX31_CCM_MPCTL_REG: return "MPCTL"; - case 5: + case IMX31_CCM_UPCTL_REG: return "UPCTL"; - case 6: + case IMX31_CCM_SPCTL_REG: return "SPCTL"; - case 7: + case IMX31_CCM_COSR_REG: return "COSR"; - case 8: + case IMX31_CCM_CGR0_REG: return "CGR0"; - case 9: + case IMX31_CCM_CGR1_REG: return "CGR1"; - case 10: + case IMX31_CCM_CGR2_REG: return "CGR2"; - case 11: + case IMX31_CCM_WIMR_REG: return "WIMR"; - case 12: + case IMX31_CCM_LDC_REG: return "LDC"; - case 13: + case IMX31_CCM_DCVR0_REG: return "DCVR0"; - case 14: + case IMX31_CCM_DCVR1_REG: return "DCVR1"; - case 15: + case IMX31_CCM_DCVR2_REG: return "DCVR2"; - case 16: + case IMX31_CCM_DCVR3_REG: return "DCVR3"; - case 17: + case IMX31_CCM_LTR0_REG: return "LTR0"; - case 18: + case IMX31_CCM_LTR1_REG: return "LTR1"; - case 19: + case IMX31_CCM_LTR2_REG: return "LTR2"; - case 20: + case IMX31_CCM_LTR3_REG: return "LTR3"; - case 21: + case IMX31_CCM_LTBR0_REG: return "LTBR0"; - case 22: + case IMX31_CCM_LTBR1_REG: return "LTBR1"; - case 23: + case IMX31_CCM_PMCR0_REG: return "PMCR0"; - case 24: + case IMX31_CCM_PMCR1_REG: return "PMCR1"; - case 25: + case IMX31_CCM_PDR2_REG: return "PDR2"; default: - return "???"; + sprintf(unknown, "[%d ?]", reg); + return unknown; } } static const VMStateDescription vmstate_imx31_ccm = { .name = TYPE_IMX31_CCM, - .version_id = 1, - .minimum_version_id = 1, + .version_id = 2, + .minimum_version_id = 2, .fields = (VMStateField[]) { - VMSTATE_UINT32(ccmr, IMX31CCMState), - VMSTATE_UINT32(pdr0, IMX31CCMState), - VMSTATE_UINT32(pdr1, IMX31CCMState), - VMSTATE_UINT32(mpctl, IMX31CCMState), - VMSTATE_UINT32(spctl, IMX31CCMState), - VMSTATE_UINT32_ARRAY(cgr, IMX31CCMState, 3), - VMSTATE_UINT32(pmcr0, IMX31CCMState), - VMSTATE_UINT32(pmcr1, IMX31CCMState), + VMSTATE_UINT32_ARRAY(reg, IMX31CCMState, IMX31_CCM_MAX_REG), VMSTATE_END_OF_LIST() }, }; @@ -109,10 +105,10 @@ static uint32_t imx31_ccm_get_pll_ref_clk(IMXCCMState *dev) uint32_t freq = 0; IMX31CCMState *s = IMX31_CCM(dev); - if ((s->ccmr & CCMR_PRCS) == 2) { - if (s->ccmr & CCMR_FPME) { + if ((s->reg[IMX31_CCM_CCMR_REG] & CCMR_PRCS) == 2) { + if (s->reg[IMX31_CCM_CCMR_REG] & CCMR_FPME) { freq = CKIL_FREQ; - if (s->ccmr & CCMR_FPMF) { + if (s->reg[IMX31_CCM_CCMR_REG] & CCMR_FPMF) { freq *= 1024; } } @@ -130,7 +126,8 @@ static uint32_t imx31_ccm_get_mpll_clk(IMXCCMState *dev) uint32_t freq; IMX31CCMState *s = IMX31_CCM(dev); - freq = imx_ccm_calc_pll(s->mpctl, imx31_ccm_get_pll_ref_clk(dev)); + freq = imx_ccm_calc_pll(s->reg[IMX31_CCM_MPCTL_REG], + imx31_ccm_get_pll_ref_clk(dev)); DPRINTF("freq = %d\n", freq); @@ -142,7 +139,8 @@ static uint32_t imx31_ccm_get_mcu_main_clk(IMXCCMState *dev) uint32_t freq; IMX31CCMState *s = IMX31_CCM(dev); - if ((s->ccmr & CCMR_MDS) || !(s->ccmr & CCMR_MPE)) { + if ((s->reg[IMX31_CCM_CCMR_REG] & CCMR_MDS) || + !(s->reg[IMX31_CCM_CCMR_REG] & CCMR_MPE)) { freq = imx31_ccm_get_pll_ref_clk(dev); } else { freq = imx31_ccm_get_mpll_clk(dev); @@ -158,7 +156,8 @@ static uint32_t imx31_ccm_get_mcu_clk(IMXCCMState *dev) uint32_t freq; IMX31CCMState *s = IMX31_CCM(dev); - freq = imx31_ccm_get_mcu_main_clk(dev) / (1 + EXTRACT(s->pdr0, MCU)); + freq = imx31_ccm_get_mcu_main_clk(dev) + / (1 + EXTRACT(s->reg[IMX31_CCM_PDR0_REG], MCU)); DPRINTF("freq = %d\n", freq); @@ -170,7 +169,8 @@ static uint32_t imx31_ccm_get_hsp_clk(IMXCCMState *dev) uint32_t freq; IMX31CCMState *s = IMX31_CCM(dev); - freq = imx31_ccm_get_mcu_main_clk(dev) / (1 + EXTRACT(s->pdr0, HSP)); + freq = imx31_ccm_get_mcu_main_clk(dev) + / (1 + EXTRACT(s->reg[IMX31_CCM_PDR0_REG], HSP)); DPRINTF("freq = %d\n", freq); @@ -182,7 +182,8 @@ static uint32_t imx31_ccm_get_hclk_clk(IMXCCMState *dev) uint32_t freq; IMX31CCMState *s = IMX31_CCM(dev); - freq = imx31_ccm_get_mcu_main_clk(dev) / (1 + EXTRACT(s->pdr0, MAX)); + freq = imx31_ccm_get_mcu_main_clk(dev) + / (1 + EXTRACT(s->reg[IMX31_CCM_PDR0_REG], MAX)); DPRINTF("freq = %d\n", freq); @@ -194,7 +195,8 @@ static uint32_t imx31_ccm_get_ipg_clk(IMXCCMState *dev) uint32_t freq; IMX31CCMState *s = IMX31_CCM(dev); - freq = imx31_ccm_get_hclk_clk(dev) / (1 + EXTRACT(s->pdr0, IPG)); + freq = imx31_ccm_get_hclk_clk(dev) + / (1 + EXTRACT(s->reg[IMX31_CCM_PDR0_REG], IPG)); DPRINTF("freq = %d\n", freq); @@ -237,14 +239,24 @@ static void imx31_ccm_reset(DeviceState *dev) DPRINTF("()\n"); - s->ccmr = 0x074b0b7d; - s->pdr0 = 0xff870b48; - s->pdr1 = 0x49fcfe7f; - s->mpctl = 0x04001800; - s->cgr[0] = s->cgr[1] = s->cgr[2] = 0xffffffff; - s->spctl = 0x04043001; - s->pmcr0 = 0x80209828; - s->pmcr1 = 0x00aa0000; + memset(s->reg, 0, sizeof(uint32_t) * IMX31_CCM_MAX_REG); + + s->reg[IMX31_CCM_CCMR_REG] = 0x074b0b7d; + s->reg[IMX31_CCM_PDR0_REG] = 0xff870b48; + s->reg[IMX31_CCM_PDR1_REG] = 0x49fcfe7f; + s->reg[IMX31_CCM_RCSR_REG] = 0x007f0000; + s->reg[IMX31_CCM_MPCTL_REG] = 0x04001800; + s->reg[IMX31_CCM_UPCTL_REG] = 0x04051c03; + s->reg[IMX31_CCM_SPCTL_REG] = 0x04043001; + s->reg[IMX31_CCM_COSR_REG] = 0x00000280; + s->reg[IMX31_CCM_CGR0_REG] = 0xffffffff; + s->reg[IMX31_CCM_CGR1_REG] = 0xffffffff; + s->reg[IMX31_CCM_CGR2_REG] = 0xffffffff; + s->reg[IMX31_CCM_WIMR_REG] = 0xffffffff; + s->reg[IMX31_CCM_LTR1_REG] = 0x00004040; + s->reg[IMX31_CCM_PMCR0_REG] = 0x80209828; + s->reg[IMX31_CCM_PMCR1_REG] = 0x00aa0000; + s->reg[IMX31_CCM_PDR2_REG] = 0x00000285; } static uint64_t imx31_ccm_read(void *opaque, hwaddr offset, unsigned size) @@ -252,41 +264,11 @@ static uint64_t imx31_ccm_read(void *opaque, hwaddr offset, unsigned size) uint32 value = 0; IMX31CCMState *s = (IMX31CCMState *)opaque; - switch (offset >> 2) { - case 0: /* CCMR */ - value = s->ccmr; - break; - case 1: - value = s->pdr0; - break; - case 2: - value = s->pdr1; - break; - case 4: - value = s->mpctl; - break; - case 6: - value = s->spctl; - break; - case 8: - value = s->cgr[0]; - break; - case 9: - value = s->cgr[1]; - break; - case 10: - value = s->cgr[2]; - break; - case 18: /* LTR1 */ - value = 0x00004040; - break; - case 23: - value = s->pmcr0; - break; - default: + if ((offset >> 2) < IMX31_CCM_MAX_REG) { + value = s->reg[offset >> 2]; + } else { qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%" HWADDR_PRIx "\n", TYPE_IMX31_CCM, __func__, offset); - break; } DPRINTF("reg[%s] => 0x%" PRIx32 "\n", imx31_ccm_reg_name(offset >> 2), @@ -304,29 +286,29 @@ static void imx31_ccm_write(void *opaque, hwaddr offset, uint64_t value, (uint32_t)value); switch (offset >> 2) { - case 0: - s->ccmr = CCMR_FPMF | (value & 0x3b6fdfff); + case IMX31_CCM_CCMR_REG: + s->reg[IMX31_CCM_CCMR_REG] = CCMR_FPMF | (value & 0x3b6fdfff); break; - case 1: - s->pdr0 = value & 0xff9f3fff; + case IMX31_CCM_PDR0_REG: + s->reg[IMX31_CCM_PDR0_REG] = value & 0xff9f3fff; break; - case 2: - s->pdr1 = value; + case IMX31_CCM_PDR1_REG: + s->reg[IMX31_CCM_PDR1_REG] = value; break; - case 4: - s->mpctl = value & 0xbfff3fff; + case IMX31_CCM_MPCTL_REG: + s->reg[IMX31_CCM_MPCTL_REG] = value & 0xbfff3fff; break; - case 6: - s->spctl = value & 0xbfff3fff; + case IMX31_CCM_SPCTL_REG: + s->reg[IMX31_CCM_SPCTL_REG] = value & 0xbfff3fff; break; - case 8: - s->cgr[0] = value; + case IMX31_CCM_CGR0_REG: + s->reg[IMX31_CCM_CGR0_REG] = value; break; - case 9: - s->cgr[1] = value; + case IMX31_CCM_CGR1_REG: + s->reg[IMX31_CCM_CGR1_REG] = value; break; - case 10: - s->cgr[2] = value; + case IMX31_CCM_CGR2_REG: + s->reg[IMX31_CCM_CGR2_REG] = value; break; default: qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%" |