arm: Introduce NXP i.MX family, RT series, and mimxrt1052 SoC

Adds the mimxrt1052 SoC, which belongs to a new family (nxp_imx) and
series (rt) of SoCs. The mimxrt1052 integrates an Arm Cortex-M7 core,
512 KB TCM, and many peripherals including 2D graphics, an LCD display
controller, camera interface, SPDIF and I2S. Unlike other SoCs in
Zephyr, the mimxrt1052 has no internal flash.

This initial port to mimxrt1052 configures the system clock to operate
at 528 MHz, and enables the serial/uart and gpio interfaces to support
the hello_world and blinky samples. Support for additional Zephyr driver
interfaces will come later.

Signed-off-by: Maureen Helm <maureen.helm@nxp.com>
This commit is contained in:
Maureen Helm 2017-08-11 14:42:40 -05:00 committed by Kumar Gala
commit 41d5808321
13 changed files with 603 additions and 0 deletions

View file

@ -0,0 +1,7 @@
#
# Copyright (c) 2017, NXP
#
# SPDX-License-Identifier: Apache-2.0
#
add_subdirectory(${SOC_SERIES})

View file

@ -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.

View file

@ -0,0 +1,7 @@
#
# Copyright (c) 2017, NXP
#
# SPDX-License-Identifier: Apache-2.0
#
source "arch/arm/soc/nxp_imx/*/Kconfig.defconfig.series"

View file

@ -0,0 +1,7 @@
#
# Copyright (c) 2017, NXP
#
# SPDX-License-Identifier: Apache-2.0
#
source "arch/arm/soc/nxp_imx/*/Kconfig.series"

View file

@ -0,0 +1,9 @@
#
# Copyright (c) 2017, NXP
#
# SPDX-License-Identifier: Apache-2.0
#
zephyr_sources(
soc.c
)

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -0,0 +1,7 @@
/*
* Copyright (c) 2014 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <arch/arm/cortex_m/scripts/linker.ld>

View file

@ -0,0 +1,213 @@
/*
* Copyright (c) 2017, NXP
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <kernel.h>
#include <device.h>
#include <init.h>
#include <soc.h>
#include <uart.h>
#include <linker/sections.h>
#include <fsl_common.h>
#include <fsl_clock.h>
#include <arch/cpu.h>
#include <cortex_m/exc.h>
/* 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);

View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2017, NXP
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _SOC__H_
#define _SOC__H_
#include <misc/util.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef _ASMLANGUAGE
#include <fsl_common.h>
#include <device.h>
#include <misc/util.h>
#endif /* !_ASMLANGUAGE */
#ifdef __cplusplus
}
#endif
#endif /* _SOC__H_ */

169
dts/arm/nxp/nxp_rt.dtsi Normal file
View file

@ -0,0 +1,169 @@
/*
* Copyright (c) 2017, NXP
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <arm/armv7-m.dtsi>
#include <dt-bindings/clock/imx_ccm.h>
/ {
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>;
};