blob: ad60c2a063da94361b54cd7d90e7360013a23d73 [file] [log] [blame]
/*
* Copyright (c) 2020, NXP
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief System/hardware module for nxp_lpc55s69 platform
*
* This module provides routines to initialize and support board-level
* hardware for the nxp_lpc55s69 platform.
*/
#include <kernel.h>
#include <device.h>
#include <init.h>
#include <soc.h>
#include <drivers/uart.h>
#include <linker/sections.h>
#include <arch/cpu.h>
#include <aarch32/cortex_m/exc.h>
#include <fsl_power.h>
#include <fsl_clock.h>
#include <fsl_common.h>
#include <fsl_device_registers.h>
#define SYSTEM_IS_XIP_FLEXSPI() \
((((uint32_t)nxp_rt600_init >= 0x08000000U) && \
((uint32_t)nxp_rt600_init < 0x10000000U)) || \
(((uint32_t)nxp_rt600_init >= 0x18000000U) && \
((uint32_t)nxp_rt600_init < 0x20000000U)))
#ifdef CONFIG_INIT_SYS_PLL
const clock_sys_pll_config_t g_sysPllConfig = {
.sys_pll_src = kCLOCK_SysPllXtalIn,
.numerator = 0,
.denominator = 1,
.sys_pll_mult = kCLOCK_SysPllMult22
};
#endif
#ifdef CONFIG_INIT_AUDIO_PLL
const clock_audio_pll_config_t g_audioPllConfig = {
.audio_pll_src = kCLOCK_AudioPllXtalIn,
.numerator = 5040,
.denominator = 27000,
.audio_pll_mult = kCLOCK_AudioPllMult22
};
#endif
#ifdef CONFIG_NXP_IMX_RT6XX_BOOT_HEADER
extern char z_main_stack[];
extern char _flash_used[];
extern void z_arm_reset(void);
extern void z_arm_nmi(void);
extern void z_arm_hard_fault(void);
extern void z_arm_mpu_fault(void);
extern void z_arm_bus_fault(void);
extern void z_arm_usage_fault(void);
extern void z_arm_secure_fault(void);
extern void z_arm_svc(void);
extern void z_arm_debug_monitor(void);
extern void z_arm_pendsv(void);
extern void sys_clock_isr(void);
extern void z_arm_exc_spurious(void);
__imx_boot_ivt_section void (* const image_vector_table[])(void) = {
(void (*)())(z_main_stack + CONFIG_MAIN_STACK_SIZE), /* 0x00 */
z_arm_reset, /* 0x04 */
z_arm_nmi, /* 0x08 */
z_arm_hard_fault, /* 0x0C */
z_arm_mpu_fault, /* 0x10 */
z_arm_bus_fault, /* 0x14 */
z_arm_usage_fault, /* 0x18 */
#if defined(CONFIG_ARM_SECURE_FIRMWARE)
z_arm_secure_fault, /* 0x1C */
#else
z_arm_exc_spurious,
#endif /* CONFIG_ARM_SECURE_FIRMWARE */
(void (*)())_flash_used, /* 0x20, imageLength. */
0, /* 0x24, imageType (Plain Image) */
0, /* 0x28, authBlockOffset/crcChecksum */
z_arm_svc, /* 0x2C */
z_arm_debug_monitor, /* 0x30 */
(void (*)())image_vector_table, /* 0x34, imageLoadAddress. */
z_arm_pendsv, /* 0x38 */
#if defined(CONFIG_SYS_CLOCK_EXISTS)
sys_clock_isr, /* 0x3C */
#else
z_arm_exc_spurious,
#endif
};
#endif /* CONFIG_NXP_IMX_RT6XX_BOOT_HEADER */
/**
*
* @brief Initialize the system clock
*
* @return N/A
*
*/
static ALWAYS_INLINE void clock_init(void)
{
#ifdef CONFIG_SOC_MIMXRT685S_CM33
/* Configure LPOSC clock*/
POWER_DisablePD(kPDRUNCFG_PD_LPOSC);
/* Configure FFRO clock */
POWER_DisablePD(kPDRUNCFG_PD_FFRO);
CLOCK_EnableFfroClk(kCLOCK_Ffro48M);
/* Configure SFRO clock */
POWER_DisablePD(kPDRUNCFG_PD_SFRO);
CLOCK_EnableSfroClk();
/* Let CPU run on FFRO for safe switching. */
CLOCK_AttachClk(kFFRO_to_MAIN_CLK);
/* Configure SYSOSC clock source */
POWER_DisablePD(kPDRUNCFG_PD_SYSXTAL);
POWER_UpdateOscSettlingTime(CONFIG_SYSOSC_SETTLING_US);
CLOCK_EnableSysOscClk(true, true, CONFIG_SYSOSC_SETTLING_US);
CLOCK_SetXtalFreq(CONFIG_XTAL_SYS_CLK_HZ);
#ifdef CONFIG_INIT_SYS_PLL
/* Configure SysPLL0 clock source */
CLOCK_InitSysPll(&g_sysPllConfig);
CLOCK_InitSysPfd(kCLOCK_Pfd0, 19);
CLOCK_InitSysPfd(kCLOCK_Pfd2, 24);
#endif
#ifdef CONFIG_INIT_AUDIO_PLL
/* Configure Audio PLL clock source */
CLOCK_InitAudioPll(&g_audioPllConfig);
CLOCK_InitAudioPfd(kCLOCK_Pfd0, 26);
CLOCK_SetClkDiv(kCLOCK_DivAudioPllClk, 15U);
#endif
/* Set SYSCPUAHBCLKDIV divider to value 2 */
CLOCK_SetClkDiv(kCLOCK_DivSysCpuAhbClk, 2U);
/* Set up clock selectors - Attach clocks to the peripheries */
CLOCK_AttachClk(kMAIN_PLL_to_MAIN_CLK);
/* Set up dividers */
/* Set PFC0DIV divider to value 2 */
CLOCK_SetClkDiv(kCLOCK_DivPfc0Clk, 2U);
/* Set FRGPLLCLKDIV divider to value 12 */
CLOCK_SetClkDiv(kCLOCK_DivPllFrgClk, 12U);
CLOCK_AttachClk(kSFRO_to_FLEXCOMM0);
#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexcomm2), nxp_lpc_i2c, okay)
CLOCK_AttachClk(kSFRO_to_FLEXCOMM2);
#endif
#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexcomm5), nxp_lpc_spi, okay)
CLOCK_AttachClk(kFFRO_to_FLEXCOMM5);
#endif
#if (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexcomm1), nxp_lpc_i2s, okay))
/* attach AUDIO PLL clock to FLEXCOMM1 (I2S1) */
CLOCK_AttachClk(kAUDIO_PLL_to_FLEXCOMM1);
#endif
#if (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexcomm3), nxp_lpc_i2s, okay))
/* attach AUDIO PLL clock to FLEXCOMM3 (I2S3) */
CLOCK_AttachClk(kAUDIO_PLL_to_FLEXCOMM3);
#endif
#endif /* CONFIG_SOC_MIMXRT685S_CM33 */
}
/**
*
* @brief Perform basic hardware initialization
*
* Initialize the interrupt controller device drivers.
* Also initialize the timer device driver, if required.
*
* @return 0
*/
static int nxp_rt600_init(const struct device *arg)
{
ARG_UNUSED(arg);
/* old interrupt lock level */
unsigned int oldLevel;
/* disable interrupts */
oldLevel = irq_lock();
/* Enable cache to accelerate boot. */
if (SYSTEM_IS_XIP_FLEXSPI() && (CACHE64_POLSEL->POLSEL == 0)) {
/*
* Set command to invalidate all ways and write GO bit
* to initiate command
*/
CACHE64->CCR = (CACHE64_CTRL_CCR_INVW1_MASK |
CACHE64_CTRL_CCR_INVW0_MASK);
CACHE64->CCR |= CACHE64_CTRL_CCR_GO_MASK;
/* Wait until the command completes */
while (CACHE64->CCR & CACHE64_CTRL_CCR_GO_MASK) {
}
/* Enable cache, enable write buffer */
CACHE64->CCR = (CACHE64_CTRL_CCR_ENWRBUF_MASK |
CACHE64_CTRL_CCR_ENCACHE_MASK);
/* Set whole FlexSPI0 space to write through. */
CACHE64_POLSEL->REG0_TOP = 0x07FFFC00U;
CACHE64_POLSEL->REG1_TOP = 0x0U;
CACHE64_POLSEL->POLSEL = 0x1U;
__ISB();
__DSB();
}
/* Initialize clock */
clock_init();
/*
* 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(nxp_rt600_init, PRE_KERNEL_1, 0);