zephyr/soc/arm/nxp_imx/mcimx6x_m4/soc.c
Carlo Caione aec9a8c4be arch: arm: Move ARM code to AArch32 sub-directory
Before introducing the code for ARM64 (AArch64) we need to relocate the
current ARM code to a new AArch32 sub-directory. For now we can assume
that no code is shared between ARM and ARM64.

There are no functional changes. The code is moved to the new location
and the file paths are fixed to reflect this change.

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
2019-12-20 11:40:59 -05:00

205 lines
6.5 KiB
C

/*
* Copyright (c) 2018, NXP
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <init.h>
#include <soc.h>
#include <dt-bindings/rdc/imx_rdc.h>
#include <arch/arm/aarch32/cortex_m/cmsis.h>
#include "wdog_imx.h"
/* Initialize Resource Domain Controller. */
static void SOC_RdcInit(void)
{
/* Move M4 core to the configured RDC domain */
RDC_SetDomainID(RDC, rdcMdaM4, M4_DOMAIN_ID, false);
/* Set access to WDOG3 for M4 core */
RDC_SetPdapAccess(RDC, rdcPdapWdog3,
RDC_DOMAIN_PERM(M4_DOMAIN_ID, RDC_DOMAIN_PERM_RW),
false, false);
#ifdef CONFIG_UART_IMX_UART_1
/* Set access to UART_1 for M4 core */
RDC_SetPdapAccess(RDC, rdcPdapUart1, DT_NXP_IMX_UART_UART_1_RDC, false, false);
#endif /* CONFIG_UART_IMX_UART_1 */
#ifdef CONFIG_UART_IMX_UART_2
/* Set access to UART_2 for M4 core */
RDC_SetPdapAccess(RDC, rdcPdapUart2, DT_NXP_IMX_UART_UART_2_RDC, false, false);
#endif /* CONFIG_UART_IMX_UART_2 */
#ifdef CONFIG_UART_IMX_UART_3
/* Set access to UART_3 for M4 core */
RDC_SetPdapAccess(RDC, rdcPdapUart3, DT_NXP_IMX_UART_UART_3_RDC, false, false);
#endif /* CONFIG_UART_IMX_UART_3 */
#ifdef CONFIG_UART_IMX_UART_4
/* Set access to UART_4 for M4 core */
RDC_SetPdapAccess(RDC, rdcPdapUart4, DT_NXP_IMX_UART_UART_4_RDC, false, false);
#endif /* CONFIG_UART_IMX_UART_4 */
#ifdef CONFIG_UART_IMX_UART_5
/* Set access to UART_5 for M4 core */
RDC_SetPdapAccess(RDC, rdcPdapUart5, DT_NXP_IMX_UART_UART_5_RDC, false, false);
#endif /* CONFIG_UART_IMX_UART_5 */
#ifdef CONFIG_UART_IMX_UART_6
/* Set access to UART_6 for M4 core */
RDC_SetPdapAccess(RDC, rdcPdapUart6, DT_NXP_IMX_UART_UART_6_RDC, false, false);
#endif /* CONFIG_UART_IMX_UART_6 */
#ifdef CONFIG_GPIO_IMX_PORT_1
/* Set access to GPIO_1 for M4 core */
RDC_SetPdapAccess(RDC, rdcPdapGpio1, DT_NXP_IMX_GPIO_GPIO_1_RDC, false, false);
#endif /* CONFIG_GPIO_IMX_PORT_1 */
#ifdef CONFIG_GPIO_IMX_PORT_2
/* Set access to GPIO_2 for M4 core */
RDC_SetPdapAccess(RDC, rdcPdapGpio2, DT_NXP_IMX_GPIO_GPIO_2_RDC, false, false);
#endif /* CONFIG_GPIO_IMX_PORT_2 */
#ifdef CONFIG_GPIO_IMX_PORT_3
/* Set access to GPIO_3 for M4 core */
RDC_SetPdapAccess(RDC, rdcPdapGpio3, DT_NXP_IMX_GPIO_GPIO_3_RDC, false, false);
#endif /* CONFIG_GPIO_IMX_PORT_3 */
#ifdef CONFIG_GPIO_IMX_PORT_4
/* Set access to GPIO_4 for M4 core */
RDC_SetPdapAccess(RDC, rdcPdapGpio4, DT_NXP_IMX_GPIO_GPIO_4_RDC, false, false);
#endif /* CONFIG_GPIO_IMX_PORT_4 */
#ifdef CONFIG_GPIO_IMX_PORT_5
/* Set access to GPIO_5 for M4 core */
RDC_SetPdapAccess(RDC, rdcPdapGpio5, DT_NXP_IMX_GPIO_GPIO_5_RDC, false, false);
#endif /* CONFIG_GPIO_IMX_PORT_5 */
#ifdef CONFIG_GPIO_IMX_PORT_6
/* Set access to GPIO_6 for M4 core */
RDC_SetPdapAccess(RDC, rdcPdapGpio6, DT_NXP_IMX_GPIO_GPIO_6_RDC, false, false);
#endif /* CONFIG_GPIO_IMX_PORT_6 */
#ifdef CONFIG_GPIO_IMX_PORT_7
/* Set access to GPIO_7 for M4 core */
RDC_SetPdapAccess(RDC, rdcPdapGpio7, DT_NXP_IMX_GPIO_GPIO_7_RDC, false, false);
#endif /* CONFIG_GPIO_IMX_PORT_7 */
#ifdef CONFIG_IPM_IMX
/* Set access to MU B for M4 core */
RDC_SetPdapAccess(RDC, rdcPdapMuB, DT_NXP_IMX_MU_MU_B_RDC, false, false);
#endif /* CONFIG_IPM_IMX */
#ifdef CONFIG_COUNTER_IMX_EPIT_1
/* Set access to EPIT_1 for M4 core */
RDC_SetPdapAccess(RDC, rdcPdapEpit1, DT_NXP_IMX_EPIT_EPIT_1_RDC, false, false);
#endif /* CONFIG_COUNTER_IMX_EPIT_1 */
#ifdef CONFIG_COUNTER_IMX_EPIT_2
/* Set access to EPIT_2 for M4 core */
RDC_SetPdapAccess(RDC, rdcPdapEpit2, DT_NXP_IMX_EPIT_EPIT_2_RDC, false, false);
#endif /* CONFIG_COUNTER_IMX_EPIT_2 */
}
/* Initialize cache. */
static void SOC_CacheInit(void)
{
/* Enable System Bus Cache */
/* set command to invalidate all ways 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 system bus cache, enable write buffer */
LMEM_PSCCR = (LMEM_PSCCR_ENWRBUF_MASK | LMEM_PSCCR_ENCACHE_MASK);
__ISB();
/* Enable Code Bus Cache */
/* set command to invalidate all ways and write GO bit
* to initiate command
*/
LMEM_PCCCR = LMEM_PCCCR_INVW1_MASK | LMEM_PCCCR_INVW0_MASK;
LMEM_PCCCR |= LMEM_PCCCR_GO_MASK;
/* Wait until the command completes */
while (LMEM_PCCCR & LMEM_PCCCR_GO_MASK)
;
/* Enable code bus cache, enable write buffer */
LMEM_PCCCR = (LMEM_PCCCR_ENWRBUF_MASK | LMEM_PCCCR_ENCACHE_MASK);
__ISB();
__DSB();
}
/* Initialize clock. */
static void SOC_ClockInit(void)
{
/* OSC/PLL is already initialized by Cortex-A9 core */
/* Enable IP bridge and IO mux clock */
CCM_ControlGate(CCM, ccmCcgrGateIomuxIptClkIo, ccmClockNeededAll);
CCM_ControlGate(CCM, ccmCcgrGateIpmux1Clk, ccmClockNeededAll);
CCM_ControlGate(CCM, ccmCcgrGateIpmux2Clk, ccmClockNeededAll);
CCM_ControlGate(CCM, ccmCcgrGateIpmux3Clk, ccmClockNeededAll);
#ifdef CONFIG_UART_IMX
/* Set UART clock is derived from OSC clock (24M) */
CCM_SetRootMux(CCM, ccmRootUartClkSel, ccmRootmuxUartClkOsc24m);
/* Configure UART divider */
CCM_SetRootDivider(CCM, ccmRootUartClkPodf, 0);
/* Enable UART clock */
CCM_ControlGate(CCM, ccmCcgrGateUartClk, ccmClockNeededAll);
CCM_ControlGate(CCM, ccmCcgrGateUartSerialClk, ccmClockNeededAll);
#endif /* CONFIG_UART_IMX */
#ifdef CONFIG_COUNTER_IMX_EPIT
/* Select EPIT clock is derived from OSC (24M) */
CCM_SetRootMux(CCM, ccmRootPerclkClkSel, ccmRootmuxPerclkClkOsc24m);
/* Configure EPIT divider */
CCM_SetRootDivider(CCM, ccmRootPerclkPodf, 0);
/* Enable EPIT clocks */
#ifdef CONFIG_COUNTER_IMX_EPIT_1
CCM_ControlGate(CCM, ccmCcgrGateEpit1Clk, ccmClockNeededAll);
#endif /* CONFIG_COUNTER_IMX_EPIT_1 */
#ifdef CONFIG_COUNTER_IMX_EPIT_2
CCM_ControlGate(CCM, ccmCcgrGateEpit2Clk, ccmClockNeededAll);
#endif /* CONFIG_COUNTER_IMX_EPIT_2 */
#endif /* CONFIG_COUNTER_IMX_EPIT */
}
/**
*
* @brief Perform basic hardware initialization
*
* Initialize the interrupt controller device drivers.
* Also initialize the counter device driver, if required.
*
* @return 0
*/
static int mcimx6x_m4_init(struct device *arg)
{
ARG_UNUSED(arg);
unsigned int oldLevel; /* Old interrupt lock level */
/* Disable interrupts */
oldLevel = irq_lock();
/* Configure RDC */
SOC_RdcInit();
/* Disable WDOG3 powerdown */
WDOG_DisablePowerdown(WDOG3);
/* Initialize Cache */
SOC_CacheInit();
/* Initialize clock */
SOC_ClockInit();
/*
* Install default handler that simply resets the CPU
* if configured in the kernel, NOP otherwise
*/
NMI_INIT();
/* Restore interrupt state */
irq_unlock(oldLevel);
return 0;
}
SYS_INIT(mcimx6x_m4_init, PRE_KERNEL_1, 0);