summaryrefslogtreecommitdiff
path: root/platform/devices/MCIMX7D/startup/system_MCIMX7D_M4.c
diff options
context:
space:
mode:
Diffstat (limited to 'platform/devices/MCIMX7D/startup/system_MCIMX7D_M4.c')
-rw-r--r--platform/devices/MCIMX7D/startup/system_MCIMX7D_M4.c332
1 files changed, 320 insertions, 12 deletions
diff --git a/platform/devices/MCIMX7D/startup/system_MCIMX7D_M4.c b/platform/devices/MCIMX7D/startup/system_MCIMX7D_M4.c
index 550e4ba..dedf6de 100644
--- a/platform/devices/MCIMX7D/startup/system_MCIMX7D_M4.c
+++ b/platform/devices/MCIMX7D/startup/system_MCIMX7D_M4.c
@@ -30,6 +30,10 @@
#include <stdbool.h>
#include "MCIMX7D_M4.h"
+/* ----------------------------------------------------------------------------
+ -- Helper macro
+ ---------------------------------------------------------------------------- */
+#define EXTRACT_BITFIELD(reg, shift, width) ((*(reg) & (((1 << (width)) - 1) << (shift))) >> (shift))
/* ----------------------------------------------------------------------------
-- Vector Table offset
@@ -39,35 +43,145 @@
/* ----------------------------------------------------------------------------
-- Core clock
---------------------------------------------------------------------------- */
-uint32_t SystemCoreClock = 240000000;
+uint32_t SystemCoreClock = 240000000ul;
/* ----------------------------------------------------------------------------
-- SystemInit()
---------------------------------------------------------------------------- */
void SystemInit(void)
{
- // The Vector table base address is given by linker script.
+ /* The Vector table base address is given by linker script. */
#if defined(__CC_ARM)
- extern uint32_t Image$$ER_m_text$$Base[];
+ extern uint32_t Image$$VECTOR_ROM$$Base[];
#else
extern uint32_t __VECTOR_TABLE[];
#endif
-
+ /* Enable FPU */
#if ((1 == __FPU_PRESENT) && (1 == __FPU_USED))
SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
#endif
- /* M4 core root SYS PLL Div2: 240MHz */
+ /* Set M4 core clock to SYS_PLL_Div2 @ 240MHz. */
CCM_TARGET_ROOT1 = 0x11000000;
- /* initialize cache */
- // Enable I_Cache
- // Enable D_Cache
+ /* Initialize MPU */
+ /* Make sure outstanding transfers are done. */
+ __DMB();
+ /* Disable the MPU. */
+ MPU->CTRL = 0;
+
+ /* Select Region 0 to configure. */
+ MPU->RNR = 0;
+ /* Set base address of Region 0 to the base of Default CODE + SRAM memory region(1GB). */
+ MPU->RBAR = 0x00000000;
+ /* Region 0 setting:
+ * 1) Enable Instruction Access;
+ * 2) Full Data Access Permission;
+ * 3) Outer and inner Non-Cacheable;
+ * 4) Region Not Shared;
+ * 5) All Sub-Region Enable;
+ * 6) MPU Protection Region size = 1GB;
+ * 7) Enable Region 0.
+ */
+ MPU->RASR = 0x0308003B;
+
+ /* Select Region 1 to configure. */
+ MPU->RNR = 1;
+ /* Set base address of Region 1 to the base of Default RAM memory region(2GB). */
+ MPU->RBAR = 0x60000000;
+ /* Region 1 setting:
+ * 1) Enable Instruction Access;
+ * 2) Full Data Access Permission;
+ * 3) Outer and inner Non-Cacheable;
+ * 4) Region Not Shared;
+ * 5) All Sub-Region Enable;
+ * 6) MPU Protection Region size = 2GB;
+ * 7) Enable Region 1.
+ */
+ MPU->RASR = 0x0308003D;
+
+ /* Select Region 2 to configure. */
+ MPU->RNR = 2;
+ /* Set base address of Region 2 to the base of Cacheable OCRAM region(128KB). */
+ MPU->RBAR = 0x20200000;
+ /* Region 2 setting:
+ * 1) Enable Instruction Access;
+ * 2) Full Data Access Permission;
+ * 3) Write Back, Write Allocate;
+ * 4) Region Not Shared;
+ * 5) All Sub-Region Enable;
+ * 6) MPU Protection Region size = 128KB;
+ * 7) Enable Region 2.
+ */
+ MPU->RASR = 0x030B0021;
+
+ /* Select Region 3 to configure. */
+ MPU->RNR = 3;
+ /* Set base address of Region 3 to the base of Cacheable QSPI Flash region(2MB). */
+ MPU->RBAR = 0x60000000;
+ /* Region 3 setting:
+ * 1) Enable Instruction Access;
+ * 2) Full Data Access Permission;
+ * 3) Write Back, Write Allocate;
+ * 4) Region Not Shared;
+ * 5) All Sub-Region Enable;
+ * 6) MPU Protection Region size = 2MB;
+ * 7) Enable Region 3.
+ */
+ MPU->RASR = 0x030B0029;
- /* relocate vector table */
+ /* Select Region 4 to configure. */
+ MPU->RNR = 4;
+ /* Set base address of Region 4 to the base of Cacheable DDR RAM region(2MB). */
+ MPU->RBAR = 0x80000000;
+ /* Region 4 setting:
+ * 1) Enable Instruction Access;
+ * 2) Full Data Access Permission;
+ * 3) Write Back, Write Allocate;
+ * 4) Region Not Shared;
+ * 5) All Sub-Region Enable;
+ * 6) MPU Protection Region size = 2MB;
+ * 7) Enable Region 4.
+ */
+ MPU->RASR = 0x030B0029;
+
+ /* Disable unused regions. */
+ MPU->RNR = 5;
+ MPU->RBAR = 0;
+ MPU->RASR = 0;
+ MPU->RNR = 6;
+ MPU->RBAR = 0;
+ MPU->RASR = 0;
+ MPU->RNR = 7;
+ MPU->RBAR = 0;
+ MPU->RASR = 0;
+
+ /* Enable Privileged default memory map and the MPU. */
+ MPU->CTRL = MPU_CTRL_ENABLE_Msk |
+ MPU_CTRL_PRIVDEFENA_Msk;
+ /* Memory barriers to ensure subsequence data & instruction
+ * transfers using updated MPU settings.
+ */
+ __DSB();
+ __ISB();
+
+ /* Initialize Cache */
+ /* Enable System Bus Cache */
+ /* set command to invalidate all ways, enable write buffer
+ and write GO bit to initiate command */
+ LMEM_PSCCR = LMEM_PSCCR_INVW1_MASK | LMEM_PSCCR_INVW0_MASK;
+ LMEM_PSCCR |= LMEM_PSCCR_GO_MASK;
+ /* wait until the command completes */
+ while (LMEM_PSCCR & LMEM_PSCCR_GO_MASK);
+ /* Enable cache, enable write buffer */
+ LMEM_PSCCR = (LMEM_PSCCR_ENWRBUF_MASK | LMEM_PSCCR_ENCACHE_MASK);
+ __DSB();
+ __ISB();
+
+ /* Relocate vector table */
#if defined(__CC_ARM)
- SCB->VTOR = (uint32_t)Image$$ER_m_text$$Base + VECT_TAB_OFFSET;
+ SCB->VTOR = (uint32_t)Image$$VECTOR_ROM$$Base + VECT_TAB_OFFSET;
#else
SCB->VTOR = (uint32_t)__VECTOR_TABLE + VECT_TAB_OFFSET;
#endif
@@ -76,10 +190,204 @@ void SystemInit(void)
/* ----------------------------------------------------------------------------
-- SystemCoreClockUpdate()
---------------------------------------------------------------------------- */
-
void SystemCoreClockUpdate(void)
{
- SystemCoreClock = 240000000;
+ uint8_t coreClockRoot = EXTRACT_BITFIELD(&CCM_TARGET_ROOT1, 24, 3);
+ uint8_t coreClockPreDiv = EXTRACT_BITFIELD(&CCM_TARGET_ROOT1, 16, 3) + 1;
+ uint8_t coreClockPostDiv = EXTRACT_BITFIELD(&CCM_TARGET_ROOT1, 0, 6) + 1;
+ float temp;
+
+ switch (coreClockRoot)
+ {
+ /* OSC_24M: */
+ case 0:
+ SystemCoreClock = 24000000ul;
+ break;
+
+ /* SYS_PLL_DIV2: */
+ case 1:
+ /* Check SYS PLL bypass bit. */
+ if (!EXTRACT_BITFIELD(&CCM_ANALOG_PLL_480_REG(CCM_ANALOG), 16, 1))
+ {
+ SystemCoreClock = (1 == EXTRACT_BITFIELD(&CCM_ANALOG_PLL_480_REG(CCM_ANALOG), \
+ 0, 1)) ? 264000000ul : 240000000ul;
+ }
+ else
+ {
+ SystemCoreClock = 24000000ul;
+ }
+ break;
+
+ /* ENET_PLL_DIV4: */
+ case 2:
+ /* Check ENET PLL bypass bit. */
+ if (!EXTRACT_BITFIELD(&CCM_ANALOG_PLL_ENET_REG(CCM_ANALOG), 16, 1))
+ SystemCoreClock = 250000000ul;
+ else
+ SystemCoreClock = 24000000ul;
+ break;
+
+ /* SYS_PLL_PFD2: */
+ case 3:
+ /* Check SYS SYS PLL bypass bit. */
+ if (!EXTRACT_BITFIELD(&CCM_ANALOG_PLL_480_REG(CCM_ANALOG), 16, 1))
+ {
+ SystemCoreClock = (1 == EXTRACT_BITFIELD(&CCM_ANALOG_PLL_480_REG(CCM_ANALOG), \
+ 0, 1)) ? 528000000ul : 480000000ul;
+ SystemCoreClock /= EXTRACT_BITFIELD(&CCM_ANALOG_PFD_480A_REG(CCM_ANALOG), 16, 6);
+ SystemCoreClock *= 18;
+ }
+ else
+ {
+ SystemCoreClock = 24000000ul;
+ }
+ break;
+
+ /* DDR_PLL_DIV2: */
+ case 4:
+ /* Check DDR PLL bypass bit. */
+ if (!EXTRACT_BITFIELD(&CCM_ANALOG_PLL_DDR_REG(CCM_ANALOG), 16, 1))
+ {
+ if (1 == EXTRACT_BITFIELD(&CCM_ANALOG_PLL_DDR_SS_REG(CCM_ANALOG), 15, 1))
+ {
+ temp = (float)EXTRACT_BITFIELD(&CCM_ANALOG_PLL_DDR_SS_REG(CCM_ANALOG), 0, 15) /
+ (float)EXTRACT_BITFIELD(&CCM_ANALOG_PLL_DDR_DENOM_REG(CCM_ANALOG), 0, 30) *
+ (float)EXTRACT_BITFIELD(&CCM_ANALOG_PLL_DDR_NUM_REG(CCM_ANALOG), 0, 30);
+ temp += EXTRACT_BITFIELD(&CCM_ANALOG_PLL_DDR_REG(CCM_ANALOG), 0, 7);
+ SystemCoreClock = (uint32_t)(24000000ul * temp);
+ }
+ else
+ SystemCoreClock = 24000000ul * EXTRACT_BITFIELD(&CCM_ANALOG_PLL_DDR_REG(CCM_ANALOG), 0, 7);
+
+ switch (EXTRACT_BITFIELD(&CCM_ANALOG_PLL_DDR_REG(CCM_ANALOG), 21, 2))
+ {
+ case 0:
+ SystemCoreClock >>= 2;
+ break;
+ case 1:
+ SystemCoreClock >>= 1;
+ break;
+ case 2:
+ case 3:
+ break;
+ }
+
+ SystemCoreClock >>= 1;
+ }
+ else
+ {
+ SystemCoreClock = 24000000ul;
+ }
+ break;
+
+ /* AUDIO_PLL: */
+ case 5:
+ /* Check AUDIO PLL bypass bit. */
+ if (!EXTRACT_BITFIELD(&CCM_ANALOG_PLL_AUDIO_REG(CCM_ANALOG), 16, 1))
+ {
+ if (1 == EXTRACT_BITFIELD(&CCM_ANALOG_PLL_AUDIO_SS_REG(CCM_ANALOG), 15, 1))
+ {
+ temp = (float)EXTRACT_BITFIELD(&CCM_ANALOG_PLL_AUDIO_SS_REG(CCM_ANALOG), 0, 15) /
+ (float)EXTRACT_BITFIELD(&CCM_ANALOG_PLL_AUDIO_DENOM_REG(CCM_ANALOG), 0, 30) *
+ (float)EXTRACT_BITFIELD(&CCM_ANALOG_PLL_AUDIO_NUM_REG(CCM_ANALOG), 0, 30);
+ temp += EXTRACT_BITFIELD(&CCM_ANALOG_PLL_AUDIO_REG(CCM_ANALOG), 0, 7);
+ SystemCoreClock = (uint32_t)(24000000ul * temp);
+ }
+ else
+ SystemCoreClock = 24000000ul * EXTRACT_BITFIELD(&CCM_ANALOG_PLL_AUDIO_REG(CCM_ANALOG), 0, 7);
+
+ switch (EXTRACT_BITFIELD(&CCM_ANALOG_PLL_AUDIO_REG(CCM_ANALOG), 19, 2))
+ {
+ case 0x0:
+ SystemCoreClock >>= 2;
+ break;
+ case 0x1:
+ SystemCoreClock >>= 1;
+ break;
+ case 0x2:
+ case 0x3:
+ break;
+ }
+
+ switch (EXTRACT_BITFIELD(&CCM_ANALOG_PLL_AUDIO_REG(CCM_ANALOG), 22, 2))
+ {
+ case 0x0:
+ case 0x2:
+ break;
+ case 0x1:
+ SystemCoreClock >>= 1;
+ break;
+ case 0x3:
+ SystemCoreClock >>= 2;
+ break;
+ }
+ }
+ else
+ {
+ SystemCoreClock = 24000000ul;
+ }
+ break;
+
+ /* VIDEO_PLL: */
+ case 6:
+ /* Check VIDEO PLL bypass bit. */
+ if (!EXTRACT_BITFIELD(&CCM_ANALOG_PLL_VIDEO_REG(CCM_ANALOG), 16, 1))
+ {
+ if (1 == EXTRACT_BITFIELD(&CCM_ANALOG_PLL_VIDEO_SS_REG(CCM_ANALOG), 15, 1))
+ {
+ temp = (float)EXTRACT_BITFIELD(&CCM_ANALOG_PLL_VIDEO_SS_REG(CCM_ANALOG), 0, 15) /
+ (float)EXTRACT_BITFIELD(&CCM_ANALOG_PLL_VIDEO_DENOM_REG(CCM_ANALOG), 0, 30) *
+ (float)EXTRACT_BITFIELD(&CCM_ANALOG_PLL_VIDEO_NUM_REG(CCM_ANALOG), 0, 30);
+ temp += EXTRACT_BITFIELD(&CCM_ANALOG_PLL_VIDEO_REG(CCM_ANALOG), 0, 7);
+ SystemCoreClock = (uint32_t)(24000000ul * temp);
+ }
+ else
+ SystemCoreClock = 24000000ul * EXTRACT_BITFIELD(&CCM_ANALOG_PLL_VIDEO_REG(CCM_ANALOG), 0, 7);
+
+ switch (EXTRACT_BITFIELD(&CCM_ANALOG_PLL_VIDEO_REG(CCM_ANALOG), 19, 2))
+ {
+ case 0x0:
+ SystemCoreClock >>= 2;
+ break;
+ case 0x1:
+ SystemCoreClock >>= 1;
+ break;
+ case 0x2:
+ case 0x3:
+ break;
+ }
+
+ switch (EXTRACT_BITFIELD(&CCM_ANALOG_PLL_VIDEO_REG(CCM_ANALOG), 22, 2))
+ {
+ case 0x0:
+ case 0x2:
+ break;
+ case 0x1:
+ SystemCoreClock >>= 1;
+ break;
+ case 0x3:
+ SystemCoreClock >>= 2;
+ break;
+ }
+ }
+ else
+ {
+ SystemCoreClock = 24000000ul;
+ }
+ break;
+
+ /* USB_PLL: */
+ case 7:
+ SystemCoreClock = 480000000ul;
+ break;
+
+ default:
+ /* Set SystemCoreClock to default clock freq. */
+ SystemCoreClock = 240000000ul;
+ break;
+ }
+
+ SystemCoreClock = (SystemCoreClock / coreClockPreDiv) / coreClockPostDiv;
}
/*******************************************************************************