Skip to content

Commit

Permalink
hw/misc/imx6ul_ccm: Implement non writable bits in CCM registers
Browse files Browse the repository at this point in the history
Some bits of the CCM registers are non writable.

This was left undone in the initial commit (all bits of registers were
writable).

This patch adds the required code to protect the non writable bits.

Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
Message-id: 20200608133508.550046-1-jcd@tribudubois.net
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
jcdubois authored and pm215 committed Jun 16, 2020
1 parent 9aaa23c commit 3d26d7d
Showing 1 changed file with 63 additions and 13 deletions.
76 changes: 63 additions & 13 deletions hw/misc/imx6ul_ccm.c
Expand Up @@ -19,6 +19,62 @@

#include "trace.h"

static const uint32_t ccm_mask[CCM_MAX] = {
[CCM_CCR] = 0xf01fef80,
[CCM_CCDR] = 0xfffeffff,
[CCM_CSR] = 0xffffffff,
[CCM_CCSR] = 0xfffffef2,
[CCM_CACRR] = 0xfffffff8,
[CCM_CBCDR] = 0xc1f8e000,
[CCM_CBCMR] = 0xfc03cfff,
[CCM_CSCMR1] = 0x80700000,
[CCM_CSCMR2] = 0xe01ff003,
[CCM_CSCDR1] = 0xfe00c780,
[CCM_CS1CDR] = 0xfe00fe00,
[CCM_CS2CDR] = 0xf8007000,
[CCM_CDCDR] = 0xf00fffff,
[CCM_CHSCCDR] = 0xfffc01ff,
[CCM_CSCDR2] = 0xfe0001ff,
[CCM_CSCDR3] = 0xffffc1ff,
[CCM_CDHIPR] = 0xffffffff,
[CCM_CTOR] = 0x00000000,
[CCM_CLPCR] = 0xf39ff01c,
[CCM_CISR] = 0xfb85ffbe,
[CCM_CIMR] = 0xfb85ffbf,
[CCM_CCOSR] = 0xfe00fe00,
[CCM_CGPR] = 0xfffc3fea,
[CCM_CCGR0] = 0x00000000,
[CCM_CCGR1] = 0x00000000,
[CCM_CCGR2] = 0x00000000,
[CCM_CCGR3] = 0x00000000,
[CCM_CCGR4] = 0x00000000,
[CCM_CCGR5] = 0x00000000,
[CCM_CCGR6] = 0x00000000,
[CCM_CMEOR] = 0xafffff1f,
};

static const uint32_t analog_mask[CCM_ANALOG_MAX] = {
[CCM_ANALOG_PLL_ARM] = 0xfff60f80,
[CCM_ANALOG_PLL_USB1] = 0xfffe0fbc,
[CCM_ANALOG_PLL_USB2] = 0xfffe0fbc,
[CCM_ANALOG_PLL_SYS] = 0xfffa0ffe,
[CCM_ANALOG_PLL_SYS_SS] = 0x00000000,
[CCM_ANALOG_PLL_SYS_NUM] = 0xc0000000,
[CCM_ANALOG_PLL_SYS_DENOM] = 0xc0000000,
[CCM_ANALOG_PLL_AUDIO] = 0xffe20f80,
[CCM_ANALOG_PLL_AUDIO_NUM] = 0xc0000000,
[CCM_ANALOG_PLL_AUDIO_DENOM] = 0xc0000000,
[CCM_ANALOG_PLL_VIDEO] = 0xffe20f80,
[CCM_ANALOG_PLL_VIDEO_NUM] = 0xc0000000,
[CCM_ANALOG_PLL_VIDEO_DENOM] = 0xc0000000,
[CCM_ANALOG_PLL_ENET] = 0xffc20ff0,
[CCM_ANALOG_PFD_480] = 0x40404040,
[CCM_ANALOG_PFD_528] = 0x40404040,
[PMU_MISC0] = 0x01fe8306,
[PMU_MISC1] = 0x07fcede0,
[PMU_MISC2] = 0x005f5f5f,
};

static const char *imx6ul_ccm_reg_name(uint32_t reg)
{
static char unknown[20];
Expand Down Expand Up @@ -596,11 +652,8 @@ static void imx6ul_ccm_write(void *opaque, hwaddr offset, uint64_t value,

trace_ccm_write_reg(imx6ul_ccm_reg_name(index), (uint32_t)value);

/*
* We will do a better implementation later. In particular some bits
* cannot be written to.
*/
s->ccm[index] = (uint32_t)value;
s->ccm[index] = (s->ccm[index] & ccm_mask[index]) |
((uint32_t)value & ~ccm_mask[index]);
}

static uint64_t imx6ul_analog_read(void *opaque, hwaddr offset, unsigned size)
Expand Down Expand Up @@ -737,7 +790,7 @@ static void imx6ul_analog_write(void *opaque, hwaddr offset, uint64_t value,
* the REG_NAME register. So we change the value of the
* REG_NAME register, setting bits passed in the value.
*/
s->analog[index - 1] |= value;
s->analog[index - 1] |= (value & ~analog_mask[index - 1]);
break;
case CCM_ANALOG_PLL_ARM_CLR:
case CCM_ANALOG_PLL_USB1_CLR:
Expand All @@ -762,7 +815,7 @@ static void imx6ul_analog_write(void *opaque, hwaddr offset, uint64_t value,
* the REG_NAME register. So we change the value of the
* REG_NAME register, unsetting bits passed in the value.
*/
s->analog[index - 2] &= ~value;
s->analog[index - 2] &= ~(value & ~analog_mask[index - 2]);
break;
case CCM_ANALOG_PLL_ARM_TOG:
case CCM_ANALOG_PLL_USB1_TOG:
Expand All @@ -787,14 +840,11 @@ static void imx6ul_analog_write(void *opaque, hwaddr offset, uint64_t value,
* the REG_NAME register. So we change the value of the
* REG_NAME register, toggling bits passed in the value.
*/
s->analog[index - 3] ^= value;
s->analog[index - 3] ^= (value & ~analog_mask[index - 3]);
break;
default:
/*
* We will do a better implementation later. In particular some bits
* cannot be written to.
*/
s->analog[index] = value;
s->analog[index] = (s->analog[index] & analog_mask[index]) |
(value & ~analog_mask[index]);
break;
}
}
Expand Down

0 comments on commit 3d26d7d

Please sign in to comment.