diff --git a/arch/arm/soc/nxp_imx/CMakeLists.txt b/arch/arm/soc/nxp_imx/CMakeLists.txt new file mode 100644 index 00000000000..00c429b533c --- /dev/null +++ b/arch/arm/soc/nxp_imx/CMakeLists.txt @@ -0,0 +1,7 @@ +# +# Copyright (c) 2017, NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +add_subdirectory(${SOC_SERIES}) diff --git a/arch/arm/soc/nxp_imx/Kconfig b/arch/arm/soc/nxp_imx/Kconfig new file mode 100644 index 00000000000..72ac109e9d6 --- /dev/null +++ b/arch/arm/soc/nxp_imx/Kconfig @@ -0,0 +1,26 @@ +# +# Copyright (c) 2017, NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +config SOC_FAMILY_IMX + bool + # omit prompt to signify a "hidden" option + default n + +if SOC_FAMILY_IMX +config SOC_FAMILY + string + default "nxp_imx" +endif + +source "arch/arm/soc/nxp_imx/*/Kconfig.soc" + +config SOC_PART_NUMBER + string + default SOC_PART_NUMBER_IMX_RT if SOC_SERIES_IMX_RT + help + This string holds the full part number of the SoC. It is a hidden option + that you should not set directly. The part number selection choice defines + the default value for this string. diff --git a/arch/arm/soc/nxp_imx/Kconfig.defconfig b/arch/arm/soc/nxp_imx/Kconfig.defconfig new file mode 100644 index 00000000000..2baa0d2099e --- /dev/null +++ b/arch/arm/soc/nxp_imx/Kconfig.defconfig @@ -0,0 +1,7 @@ +# +# Copyright (c) 2017, NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +source "arch/arm/soc/nxp_imx/*/Kconfig.defconfig.series" diff --git a/arch/arm/soc/nxp_imx/Kconfig.soc b/arch/arm/soc/nxp_imx/Kconfig.soc new file mode 100644 index 00000000000..0b399381d1f --- /dev/null +++ b/arch/arm/soc/nxp_imx/Kconfig.soc @@ -0,0 +1,7 @@ +# +# Copyright (c) 2017, NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +source "arch/arm/soc/nxp_imx/*/Kconfig.series" diff --git a/arch/arm/soc/nxp_imx/rt/CMakeLists.txt b/arch/arm/soc/nxp_imx/rt/CMakeLists.txt new file mode 100644 index 00000000000..09d3c2b6c33 --- /dev/null +++ b/arch/arm/soc/nxp_imx/rt/CMakeLists.txt @@ -0,0 +1,9 @@ +# +# Copyright (c) 2017, NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +zephyr_sources( + soc.c + ) diff --git a/arch/arm/soc/nxp_imx/rt/Kconfig.defconfig.mimxrt1052 b/arch/arm/soc/nxp_imx/rt/Kconfig.defconfig.mimxrt1052 new file mode 100644 index 00000000000..6c5266f8fe9 --- /dev/null +++ b/arch/arm/soc/nxp_imx/rt/Kconfig.defconfig.mimxrt1052 @@ -0,0 +1,38 @@ +# Kconfig - i.MX RT1052 +# +# Copyright (c) 2017, NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +if SOC_MIMXRT1052 + +config SOC + string + default mimxrt1052 + +if CLOCK_CONTROL + +config CLOCK_CONTROL_MCUX_CCM + def_bool y + +endif # CLOCK_CONTROL + +config GPIO + def_bool y + +if GPIO + +config GPIO_MCUX_IGPIO + def_bool y + +endif # GPIO + +if SERIAL + +config UART_MCUX_LPUART + def_bool y + +endif # SERIAL + +endif # SOC_MIMXRT1052 diff --git a/arch/arm/soc/nxp_imx/rt/Kconfig.defconfig.series b/arch/arm/soc/nxp_imx/rt/Kconfig.defconfig.series new file mode 100644 index 00000000000..143102c75cb --- /dev/null +++ b/arch/arm/soc/nxp_imx/rt/Kconfig.defconfig.series @@ -0,0 +1,20 @@ +# Kconfig - i.MX RT series +# +# Copyright (c) 2017, NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +if SOC_SERIES_IMX_RT + +config SOC_SERIES + default rt + +config NUM_IRQS + int + # must be >= the highest interrupt number used + default 160 + +source "arch/arm/soc/nxp_imx/rt/Kconfig.defconfig.mimxrt*" + +endif # SOC_SERIES_IMX_RT diff --git a/arch/arm/soc/nxp_imx/rt/Kconfig.series b/arch/arm/soc/nxp_imx/rt/Kconfig.series new file mode 100644 index 00000000000..b601bef62d0 --- /dev/null +++ b/arch/arm/soc/nxp_imx/rt/Kconfig.series @@ -0,0 +1,17 @@ +# Kconfig - iMX RT series +# +# Copyright (c) 2017, NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +config SOC_SERIES_IMX_RT + bool "i.MX RT Series" + select CPU_CORTEX_M + select CPU_CORTEX_M7 + select SOC_FAMILY_IMX + select SYS_POWER_LOW_POWER_STATE_SUPPORTED + select CPU_HAS_SYSTICK + select CLOCK_CONTROL + help + Enable support for i.MX RT MCU series diff --git a/arch/arm/soc/nxp_imx/rt/Kconfig.soc b/arch/arm/soc/nxp_imx/rt/Kconfig.soc new file mode 100644 index 00000000000..53d8edfe7fb --- /dev/null +++ b/arch/arm/soc/nxp_imx/rt/Kconfig.soc @@ -0,0 +1,55 @@ +# Kconfig - i.MX RT series +# +# Copyright (c) 2017, NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +choice +prompt "i.MX RT Selection" +depends on SOC_SERIES_IMX_RT + +config SOC_MIMXRT1051 + bool "SOC_MIMXRT1051" + select HAS_MCUX + select HAS_MCUX_CCM + select HAS_MCUX_IGPIO + select HAS_MCUX_LPUART + select CPU_HAS_FPU + +config SOC_MIMXRT1052 + bool "SOC_MIMXRT1052" + select HAS_MCUX + select HAS_MCUX_CCM + select HAS_MCUX_IGPIO + select HAS_MCUX_LPUART + select CPU_HAS_FPU + +endchoice + +if SOC_SERIES_IMX_RT + +config SOC_PART_NUMBER_MIMXRT1051CVL5A + bool + +config SOC_PART_NUMBER_MIMXRT1051DVL6A + bool + +config SOC_PART_NUMBER_MIMXRT1052CVL5A + bool + +config SOC_PART_NUMBER_MIMXRT1052DVL6A + bool + +config SOC_PART_NUMBER_IMX_RT + string + default "MIMXRT1051CVL5A" if SOC_PART_NUMBER_MIMXRT1051CVL5A + default "MIMXRT1051DVL6A" if SOC_PART_NUMBER_MIMXRT1051DVL6A + default "MIMXRT1052CVL5A" if SOC_PART_NUMBER_MIMXRT1052CVL5A + default "MIMXRT1052DVL6A" if SOC_PART_NUMBER_MIMXRT1052DVL6A + help + This string holds the full part number of the SoC. It is a hidden option + that you should not set directly. The part number selection choice defines + the default value for this string. + +endif # SOC_SERIES_IMX_RT diff --git a/arch/arm/soc/nxp_imx/rt/linker.ld b/arch/arm/soc/nxp_imx/rt/linker.ld new file mode 100644 index 00000000000..ad3736715ad --- /dev/null +++ b/arch/arm/soc/nxp_imx/rt/linker.ld @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2014 Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include diff --git a/arch/arm/soc/nxp_imx/rt/soc.c b/arch/arm/soc/nxp_imx/rt/soc.c new file mode 100644 index 00000000000..06f437b09cf --- /dev/null +++ b/arch/arm/soc/nxp_imx/rt/soc.c @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2017, NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* ARM PLL configuration for RUN mode */ +const clock_arm_pll_config_t armPllConfig = { + .loopDivider = 100U +}; + +/* SYS PLL configuration for RUN mode */ +const clock_sys_pll_config_t sysPllConfig = { + .loopDivider = 1U +}; + +/* USB1 PLL configuration for RUN mode */ +const clock_usb_pll_config_t usb1PllConfig = { + .loopDivider = 0U +}; + +static void BOARD_BootClockGate(void) +{ + /* Disable all unused peripheral clocks */ + CCM->CCGR0 = CCM_CCGR0_CG15(0) | CCM_CCGR0_CG14(0) | + CCM_CCGR0_CG13(0) | CCM_CCGR0_CG12(0) | + CCM_CCGR0_CG11(3) | CCM_CCGR0_CG10(0) | + CCM_CCGR0_CG9(0) | CCM_CCGR0_CG8(0) | + CCM_CCGR0_CG7(0) | CCM_CCGR0_CG6(0) | + CCM_CCGR0_CG5(0) | CCM_CCGR0_CG4(0) | + CCM_CCGR0_CG3(0) | CCM_CCGR0_CG2(0) | + CCM_CCGR0_CG1(3) | CCM_CCGR0_CG0(3); + + CCM->CCGR1 = CCM_CCGR1_CG15(0) | CCM_CCGR1_CG14(3) | + CCM_CCGR1_CG13(0) | CCM_CCGR1_CG12(0) | + CCM_CCGR1_CG11(0) | CCM_CCGR1_CG10(0) | + CCM_CCGR1_CG9(0) | CCM_CCGR1_CG8(0) | + CCM_CCGR1_CG7(0) | CCM_CCGR1_CG6(0) | + CCM_CCGR1_CG5(0) | CCM_CCGR1_CG4(0) | + CCM_CCGR1_CG3(0) | CCM_CCGR1_CG2(0) | + CCM_CCGR1_CG1(0) | CCM_CCGR1_CG0(0); + + CCM->CCGR2 = CCM_CCGR2_CG15(3) | CCM_CCGR2_CG14(3) | + CCM_CCGR2_CG13(3) | CCM_CCGR2_CG12(3) | + CCM_CCGR2_CG11(0) | CCM_CCGR2_CG10(3) | + CCM_CCGR2_CG9(3) | CCM_CCGR2_CG8(3) | + CCM_CCGR2_CG7(0) | CCM_CCGR2_CG6(3) | + CCM_CCGR2_CG5(0) | CCM_CCGR2_CG4(0) | + CCM_CCGR2_CG3(0) | CCM_CCGR2_CG2(3) | + CCM_CCGR2_CG1(3) | CCM_CCGR2_CG0(3); + + CCM->CCGR3 = CCM_CCGR3_CG15(3) | CCM_CCGR3_CG14(3) | + CCM_CCGR3_CG13(0) | CCM_CCGR3_CG12(0) | + CCM_CCGR3_CG11(0) | CCM_CCGR3_CG10(0) | + CCM_CCGR3_CG9(0) | CCM_CCGR3_CG8(0) | + CCM_CCGR3_CG7(0) | CCM_CCGR3_CG6(0) | + CCM_CCGR3_CG5(0) | CCM_CCGR3_CG4(3) | + CCM_CCGR3_CG3(0) | CCM_CCGR3_CG2(3) | + CCM_CCGR3_CG1(0) | CCM_CCGR3_CG0(0); + + + CCM->CCGR4 = CCM_CCGR4_CG15(0) | CCM_CCGR4_CG14(0) | + CCM_CCGR4_CG13(0) | CCM_CCGR4_CG12(0) | + CCM_CCGR4_CG11(0) | CCM_CCGR4_CG10(0) | + CCM_CCGR4_CG9(0) | CCM_CCGR4_CG8(0) | + CCM_CCGR4_CG7(3) | CCM_CCGR4_CG6(3) | + CCM_CCGR4_CG5(3) | CCM_CCGR4_CG4(3) | + CCM_CCGR4_CG3(0) | CCM_CCGR4_CG2(3) | + CCM_CCGR4_CG1(3) | CCM_CCGR4_CG0(0); + + CCM->CCGR5 = CCM_CCGR5_CG15(3) | CCM_CCGR5_CG14(3) | + CCM_CCGR5_CG13(0) | CCM_CCGR5_CG12(0) | + CCM_CCGR5_CG11(0) | CCM_CCGR5_CG10(0) | + CCM_CCGR5_CG9(0) | CCM_CCGR5_CG8(3) | + CCM_CCGR5_CG7(0) | CCM_CCGR5_CG6(3) | + CCM_CCGR5_CG5(0) | CCM_CCGR5_CG4(3) | + CCM_CCGR5_CG3(0) | CCM_CCGR5_CG2(0) | + CCM_CCGR5_CG1(3) | CCM_CCGR5_CG0(3); + + CCM->CCGR6 = CCM_CCGR6_CG15(0) | CCM_CCGR6_CG14(0) | + CCM_CCGR6_CG13(0) | CCM_CCGR6_CG12(0) | + CCM_CCGR6_CG11(3) | CCM_CCGR6_CG10(3) | + CCM_CCGR6_CG9(3) | CCM_CCGR6_CG8(0) | + CCM_CCGR6_CG7(0) | CCM_CCGR6_CG6(0) | + CCM_CCGR6_CG5(3) | CCM_CCGR6_CG4(3) | + CCM_CCGR6_CG3(0) | CCM_CCGR6_CG2(0) | + CCM_CCGR6_CG1(0) | CCM_CCGR6_CG0(0); +} + +/** + * + * @brief Initialize the system clock + * + * @return N/A + * + */ +static ALWAYS_INLINE void clkInit(void) +{ + /* Boot ROM did initialize the XTAL, here we only sets external XTAL + * OSC freq + */ + CLOCK_SetXtalFreq(24000000U); + CLOCK_SetRtcXtalFreq(32768U); + + /* Set PERIPH_CLK2 MUX to OSC */ + CLOCK_SetMux(kCLOCK_PeriphClk2Mux, 0x1); + + /* Set PERIPH_CLK MUX to PERIPH_CLK2 */ + CLOCK_SetMux(kCLOCK_PeriphMux, 0x1); + + /* Setting the VDD_SOC to 1.5V. It is necessary to config AHB to 600Mhz + */ + DCDC->REG3 = (DCDC->REG3 & (~DCDC_REG3_TRG_MASK)) | DCDC_REG3_TRG(0x12); + + CLOCK_InitArmPll(&armPllConfig); /* Configure ARM PLL to 1200M */ + CLOCK_InitSysPll(&sysPllConfig); /* Configure SYS PLL to 528M */ + CLOCK_InitUsb1Pll(&usb1PllConfig); /* Configure USB1 PLL to 480M */ + + CLOCK_SetDiv(kCLOCK_ArmDiv, 0x1); /* Set ARM PODF to 0, divide by 2 */ + CLOCK_SetDiv(kCLOCK_AhbDiv, 0x0); /* Set AHB PODF to 0, divide by 1 */ + CLOCK_SetDiv(kCLOCK_IpgDiv, 0x3); /* Set IPG PODF to 3, divide by 4 */ + + /* Set PRE_PERIPH_CLK to PLL1, 1200M */ + CLOCK_SetMux(kCLOCK_PrePeriphMux, 0x3); + + /* Set PERIPH_CLK MUX to PRE_PERIPH_CLK */ + CLOCK_SetMux(kCLOCK_PeriphMux, 0x0); + + /* Disable unused clock */ + BOARD_BootClockGate(); + + /* Power down all unused PLL */ + CLOCK_DeinitAudioPll(); + CLOCK_DeinitVideoPll(); + CLOCK_DeinitEnetPll(); + CLOCK_DeinitUsb2Pll(); + +#ifdef CONFIG_UART_MCUX_LPUART + /* Configure UART divider to default */ + CLOCK_SetMux(kCLOCK_UartMux, 0); /* Set UART source to PLL3 80M */ + CLOCK_SetDiv(kCLOCK_UartDiv, 0); /* Set UART divider to 1 */ +#endif +} + +/** + * + * @brief Perform basic hardware initialization + * + * Initialize the interrupt controller device drivers. + * Also initialize the timer device driver, if required. + * + * @return 0 + */ + +static int imxrt_init(struct device *arg) +{ + ARG_UNUSED(arg); + + int oldLevel; /* old interrupt lock level */ + + /* disable interrupts */ + oldLevel = irq_lock(); + + /* Watchdog disable */ + if (WDOG1->WCR & WDOG_WCR_WDE_MASK) { + WDOG1->WCR &= ~WDOG_WCR_WDE_MASK; + } + + if (WDOG2->WCR & WDOG_WCR_WDE_MASK) { + WDOG2->WCR &= ~WDOG_WCR_WDE_MASK; + } + + RTWDOG->CNT = 0xD928C520U; /* 0xD928C520U is the update key */ + RTWDOG->TOVAL = 0xFFFF; + RTWDOG->CS = (uint32_t) ((RTWDOG->CS) & ~RTWDOG_CS_EN_MASK) + | RTWDOG_CS_UPDATE_MASK; + + /* Disable Systick which might be enabled by bootrom */ + if (SysTick->CTRL & SysTick_CTRL_ENABLE_Msk) { + SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; + } + + SCB_EnableICache(); + SCB_EnableDCache(); + + _ClearFaults(); + + /* Initialize PLL/system clock to 120 MHz */ + clkInit(); + + /* + * 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(imxrt_init, PRE_KERNEL_1, 0); diff --git a/arch/arm/soc/nxp_imx/rt/soc.h b/arch/arm/soc/nxp_imx/rt/soc.h new file mode 100644 index 00000000000..5faf2c7d76c --- /dev/null +++ b/arch/arm/soc/nxp_imx/rt/soc.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2017, NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _SOC__H_ +#define _SOC__H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _ASMLANGUAGE + +#include +#include +#include + +#endif /* !_ASMLANGUAGE */ + +#ifdef __cplusplus +} +#endif + +#endif /* _SOC__H_ */ diff --git a/dts/arm/nxp/nxp_rt.dtsi b/dts/arm/nxp/nxp_rt.dtsi new file mode 100644 index 00000000000..4ea999b3ff7 --- /dev/null +++ b/dts/arm/nxp/nxp_rt.dtsi @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2017, NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-m7"; + reg = <0>; + }; + }; + + soc { + flexram0: flexram@400b0000 { + compatible = "nxp,imx-flexram"; + reg = <0x400b0000 0x4000>; + interrupts = <38 0>; + + #address-cells = <1>; + #size-cells = <1>; + + itcm0: itcm0 { + reg = <0x00000000 0x20000>; + }; + + dtcm0: dtcm0 { + reg = <0x20000000 0x20000>; + }; + + ocram0: ocram0 { + reg = <0x20200000 0x40000>; + }; + }; + + ccm: ccm@400fc000 { + compatible = "nxp,imx-ccm"; + reg = <0x400fc000 0x4000>; + label = "CCM"; + + clock-controller; + #clocks-cells = <3>; + }; + + gpio1: gpio@401b8000 { + compatible = "nxp,imx-gpio"; + reg = <0x401b8000 0x4000>; + interrupts = <80 0>, <81 0>; + label = "GPIO_1"; + }; + + gpio2: gpio@401bc000 { + compatible = "nxp,imx-gpio"; + reg = <0x401bc000 0x4000>; + interrupts = <82 0>, <83 0>; + label = "GPIO_2"; + }; + + gpio3: gpio@401c0000 { + compatible = "nxp,imx-gpio"; + reg = <0x401c0000 0x4000>; + interrupts = <84 0>, <85 0>; + label = "GPIO_3"; + }; + + gpio4: gpio@401c4000 { + compatible = "nxp,imx-gpio"; + reg = <0x401c4000 0x4000>; + interrupts = <86 0>, <87 0>; + label = "GPIO_4"; + }; + + gpio5: gpio@400c0000 { + compatible = "nxp,imx-gpio"; + reg = <0x400c0000 0x4000>; + interrupts = <88 0>, <89 0>; + label = "GPIO_5"; + }; + + iomuxc: iomuxc@401f8000 { + reg = <0x401f8000 0x4000>; + label = "PINMUX_0"; + }; + + uart1: uart@40184000 { + compatible = "nxp,kinetis-lpuart"; + reg = <0x40184000 0x4000>; + interrupts = <20 0>; + clocks = <&ccm IMX_CCM_LPUART_CLK 0x7c 24>; + label = "UART_1"; + status = "disabled"; + }; + + uart2: uart@40188000 { + compatible = "nxp,kinetis-lpuart"; + reg = <0x40188000 0x4000>; + interrupts = <21 0>; + clocks = <&ccm IMX_CCM_LPUART_CLK 0x68 28>; + label = "UART_2"; + status = "disabled"; + }; + + uart3: uart@4018c000 { + compatible = "nxp,kinetis-lpuart"; + reg = <0x4018c000 0x4000>; + interrupts = <22 0>; + clocks = <&ccm IMX_CCM_LPUART_CLK 0x68 12>; + label = "UART_3"; + status = "disabled"; + }; + + uart4: uart@40190000 { + compatible = "nxp,kinetis-lpuart"; + reg = <0x40190000 0x4000>; + interrupts = <23 0>; + clocks = <&ccm IMX_CCM_LPUART_CLK 0x6c 24>; + label = "UART_4"; + status = "disabled"; + }; + + uart5: uart@40194000 { + compatible = "nxp,kinetis-lpuart"; + reg = <0x40194000 0x4000>; + interrupts = <24 0>; + clocks = <&ccm IMX_CCM_LPUART_CLK 0x74 2>; + label = "UART_5"; + status = "disabled"; + }; + + uart6: uart@40198000 { + compatible = "nxp,kinetis-lpuart"; + reg = <0x40198000 0x4000>; + interrupts = <25 0>; + clocks = <&ccm IMX_CCM_LPUART_CLK 0x74 6>; + label = "UART_6"; + status = "disabled"; + }; + + uart7: uart@4019c000 { + compatible = "nxp,kinetis-lpuart"; + reg = <0x4019c000 0x4000>; + interrupts = <26 0>; + clocks = <&ccm IMX_CCM_LPUART_CLK 0x7c 26>; + label = "UART_7"; + status = "disabled"; + }; + + uart8: uart@401a0000 { + compatible = "nxp,kinetis-lpuart"; + reg = <0x401a0000 0x4000>; + interrupts = <27 0>; + clocks = <&ccm IMX_CCM_LPUART_CLK 0x80 14>; + label = "UART_8"; + status = "disabled"; + }; + }; +}; + +&nvic { + arm,num-irq-priority-bits = <4>; +};