From 2aae0b7b5bb99aa57cb69aaa333a96e2bd7d3361 Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Sat, 27 Jul 2019 12:08:00 +0530 Subject: [PATCH] soc: arm: nxp_imx: Add i.MX8M Mini SoC support Add SoC support for the NXP i.MX8M Mini series MIMX8MM6 SoC. This SoC has a quad Cortex-A53 cluster and a single core Cortex-M4 core. Zephyr support is added to the Cortex-M4 core for running at 800MHz. More information about the SoC can be found here: https://www.nxp.com/products/processors-and-microcontrollers/arm-processors/i.mx-applications-processors/i.mx-8-processors/i.mx-8m-mini-arm-cortex-a53-cortex-m4-audio-voice-video:i.MX8MMINI Signed-off-by: Manivannan Sadhasivam --- soc/arm/nxp_imx/Kconfig | 1 + soc/arm/nxp_imx/mimx8mm6_m4/CMakeLists.txt | 9 ++ .../mimx8mm6_m4/Kconfig.defconfig.mimx8mm6_m4 | 37 +++++ .../mimx8mm6_m4/Kconfig.defconfig.series | 18 +++ soc/arm/nxp_imx/mimx8mm6_m4/Kconfig.series | 13 ++ soc/arm/nxp_imx/mimx8mm6_m4/Kconfig.soc | 31 ++++ soc/arm/nxp_imx/mimx8mm6_m4/linker.ld | 7 + soc/arm/nxp_imx/mimx8mm6_m4/soc.c | 144 ++++++++++++++++++ soc/arm/nxp_imx/mimx8mm6_m4/soc.h | 24 +++ 9 files changed, 284 insertions(+) create mode 100644 soc/arm/nxp_imx/mimx8mm6_m4/CMakeLists.txt create mode 100644 soc/arm/nxp_imx/mimx8mm6_m4/Kconfig.defconfig.mimx8mm6_m4 create mode 100644 soc/arm/nxp_imx/mimx8mm6_m4/Kconfig.defconfig.series create mode 100644 soc/arm/nxp_imx/mimx8mm6_m4/Kconfig.series create mode 100644 soc/arm/nxp_imx/mimx8mm6_m4/Kconfig.soc create mode 100644 soc/arm/nxp_imx/mimx8mm6_m4/linker.ld create mode 100644 soc/arm/nxp_imx/mimx8mm6_m4/soc.c create mode 100644 soc/arm/nxp_imx/mimx8mm6_m4/soc.h diff --git a/soc/arm/nxp_imx/Kconfig b/soc/arm/nxp_imx/Kconfig index 99cadcf8bae..bd6e1e9531b 100644 --- a/soc/arm/nxp_imx/Kconfig +++ b/soc/arm/nxp_imx/Kconfig @@ -18,5 +18,6 @@ config SOC_PART_NUMBER default SOC_PART_NUMBER_IMX_RT if SOC_SERIES_IMX_RT default SOC_PART_NUMBER_IMX_6X_M4 if SOC_SERIES_IMX_6X_M4 default SOC_PART_NUMBER_IMX7_M4 if SOC_SERIES_IMX7_M4 + default SOC_PART_NUMBER_IMX8MM_M4 if SOC_SERIES_IMX8MM_M4 endif # SOC_FAMILY_IMX diff --git a/soc/arm/nxp_imx/mimx8mm6_m4/CMakeLists.txt b/soc/arm/nxp_imx/mimx8mm6_m4/CMakeLists.txt new file mode 100644 index 00000000000..6cb751a9861 --- /dev/null +++ b/soc/arm/nxp_imx/mimx8mm6_m4/CMakeLists.txt @@ -0,0 +1,9 @@ +# +# Copyright (c) 2020, Manivannan Sadhasivam +# +# SPDX-License-Identifier: Apache-2.0 +# + +zephyr_sources( + soc.c + ) diff --git a/soc/arm/nxp_imx/mimx8mm6_m4/Kconfig.defconfig.mimx8mm6_m4 b/soc/arm/nxp_imx/mimx8mm6_m4/Kconfig.defconfig.mimx8mm6_m4 new file mode 100644 index 00000000000..488367f0476 --- /dev/null +++ b/soc/arm/nxp_imx/mimx8mm6_m4/Kconfig.defconfig.mimx8mm6_m4 @@ -0,0 +1,37 @@ +# MIMX8MM6 SoC defconfig + +# Copyright (c) 2020, Manivannan Sadhasivam +# SPDX-License-Identifier: Apache-2.0 + +if SOC_MIMX8MM6 + +config SOC + string + default "mimx8mm6" + +config SYS_CLOCK_HW_CYCLES_PER_SEC + int + default 400000000 + +if CLOCK_CONTROL + +config CLOCK_CONTROL_MCUX_CCM + default y if HAS_MCUX_CCM + +endif # CLOCK_CONTROL + +if PINMUX + +config PINMUX_MCUX + default y + +endif # PINMUX + +if SERIAL + +config UART_MCUX_IUART + default y + +endif # SERIAL + +endif # SOC_MIMX8MM6 diff --git a/soc/arm/nxp_imx/mimx8mm6_m4/Kconfig.defconfig.series b/soc/arm/nxp_imx/mimx8mm6_m4/Kconfig.defconfig.series new file mode 100644 index 00000000000..58bf7051fc8 --- /dev/null +++ b/soc/arm/nxp_imx/mimx8mm6_m4/Kconfig.defconfig.series @@ -0,0 +1,18 @@ +# i.MX8MM M4 SoC series defconfig + +# Copyright (c) 2020, Manivannan Sadhasivam +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_IMX8MM_M4 + +config SOC_SERIES + default "mimx8mm6_m4" + +config NUM_IRQS + int + # must be >= the highest interrupt number used + default 127 + +source "soc/arm/nxp_imx/mimx8mm6_m4/Kconfig.defconfig.mimx8mm6_m4" + +endif # SOC_SERIES_IMX8MM_M4 diff --git a/soc/arm/nxp_imx/mimx8mm6_m4/Kconfig.series b/soc/arm/nxp_imx/mimx8mm6_m4/Kconfig.series new file mode 100644 index 00000000000..dddb12d1b70 --- /dev/null +++ b/soc/arm/nxp_imx/mimx8mm6_m4/Kconfig.series @@ -0,0 +1,13 @@ +# i.MX8MM M4 core series + +# Copyright (c) 2020, Manivannan Sadhasivam +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_IMX8MM_M4 + bool "i.MX8MM M4 Core Series" + select ARM + select CPU_CORTEX_M4 + select SOC_FAMILY_IMX + select CPU_HAS_FPU + help + Enable support for i.MX8MM M4 MCU series diff --git a/soc/arm/nxp_imx/mimx8mm6_m4/Kconfig.soc b/soc/arm/nxp_imx/mimx8mm6_m4/Kconfig.soc new file mode 100644 index 00000000000..6dc66b10fb1 --- /dev/null +++ b/soc/arm/nxp_imx/mimx8mm6_m4/Kconfig.soc @@ -0,0 +1,31 @@ +# i.MX8MM M4 SoC series + +# Copyright (c) 2020, Manivannan Sadhasivam +# SPDX-License-Identifier: Apache-2.0 + +choice +prompt "i.MX8MM M4 Selection" +depends on SOC_SERIES_IMX8MM_M4 + +config SOC_MIMX8MM6 + bool "SOC_MIMX8MM6" + select HAS_MCUX + select HAS_MCUX_CCM + select HAS_MCUX_RDC + +endchoice + +if SOC_SERIES_IMX8MM_M4 + +config SOC_PART_NUMBER_MIMX8MM6DVTLZ + bool + +config SOC_PART_NUMBER_IMX8MM_M4 + string + default "MIMX8MM6DVTLZ" if SOC_PART_NUMBER_MIMX8MM6DVTLZ + 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_IMX8MM_M4 diff --git a/soc/arm/nxp_imx/mimx8mm6_m4/linker.ld b/soc/arm/nxp_imx/mimx8mm6_m4/linker.ld new file mode 100644 index 00000000000..57123c8681c --- /dev/null +++ b/soc/arm/nxp_imx/mimx8mm6_m4/linker.ld @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2020, Manivannan Sadhasivam + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include diff --git a/soc/arm/nxp_imx/mimx8mm6_m4/soc.c b/soc/arm/nxp_imx/mimx8mm6_m4/soc.c new file mode 100644 index 00000000000..eb609f14270 --- /dev/null +++ b/soc/arm/nxp_imx/mimx8mm6_m4/soc.c @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2020, Manivannan Sadhasivam + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +/* OSC/PLL is already initialized by ROM and Cortex-A53 (u-boot) */ +static void SOC_RdcInit(void) +{ + /* Move M4 core to specific RDC domain 1 */ + rdc_domain_assignment_t assignment = {0}; + + assignment.domainId = M4_DOMAIN_ID; + RDC_SetMasterDomainAssignment(RDC, kRDC_Master_M4, &assignment); + + /* + * The M4 core is running at domain 1, enable clock gate for + * Iomux to run at domain 1. + */ + CLOCK_EnableClock(kCLOCK_Iomux0); + CLOCK_EnableClock(kCLOCK_Iomux1); + CLOCK_EnableClock(kCLOCK_Iomux2); + CLOCK_EnableClock(kCLOCK_Iomux3); + CLOCK_EnableClock(kCLOCK_Iomux4); + + CLOCK_EnableClock(kCLOCK_Qspi); + + /* + * The M4 core is running at domain 1, enable the PLL clock sources + * to domain 1. + */ + /* Enable SysPLL1 to Domain 1 */ + CLOCK_ControlGate(kCLOCK_SysPll1Gate, kCLOCK_ClockNeededAll); + /* Enable SysPLL2 to Domain 1 */ + CLOCK_ControlGate(kCLOCK_SysPll2Gate, kCLOCK_ClockNeededAll); + /* Enable SysPLL3 to Domain 1 */ + CLOCK_ControlGate(kCLOCK_SysPll3Gate, kCLOCK_ClockNeededAll); + /* Enable AudioPLL1 to Domain 1 */ + CLOCK_ControlGate(kCLOCK_AudioPll1Gate, kCLOCK_ClockNeededAll); + /* Enable AudioPLL2 to Domain 1 */ + CLOCK_ControlGate(kCLOCK_AudioPll2Gate, kCLOCK_ClockNeededAll); + /* Enable VideoPLL1 to Domain 1 */ + CLOCK_ControlGate(kCLOCK_VideoPll1Gate, kCLOCK_ClockNeededAll); +} + +/* AUDIO PLL1 configuration */ +static const ccm_analog_frac_pll_config_t g_audioPll1Config = { + .refSel = kANALOG_PllRefOsc24M, /* PLL reference OSC24M */ + .mainDiv = 655U, + .dsm = 23593U, + .preDiv = 5U, + .postDiv = 2U, /* AUDIO PLL1 frequency = 786432000HZ */ +}; + +/* AUDIO PLL2 configuration */ +static const ccm_analog_frac_pll_config_t g_audioPll2Config = { + .refSel = kANALOG_PllRefOsc24M, /* PLL reference OSC24M */ + .mainDiv = 301U, + .dsm = 3670U, + .preDiv = 5U, + .postDiv = 1U, /* AUDIO PLL2 frequency = 722534399HZ */ +}; + +static void SOC_ClockInit(void) +{ + /* + * Switch AHB NOC root to 24M first in order to configure + * the SYSTEM PLL1 + */ + CLOCK_SetRootMux(kCLOCK_RootAhb, kCLOCK_AhbRootmuxOsc24M); + + /* + * Switch AXI M4 root to 24M first in order to configure + * the SYSTEM PLL2 + */ + CLOCK_SetRootMux(kCLOCK_RootM4, kCLOCK_M4RootmuxOsc24M); + + /* Init AUDIO PLL1 to run at 786432000HZ */ + CLOCK_InitAudioPll1(&g_audioPll1Config); + /* Init AUDIO PLL2 to run at 722534399HZ */ + CLOCK_InitAudioPll2(&g_audioPll2Config); + + CLOCK_SetRootDivider(kCLOCK_RootM4, 1U, 2U); + /* Switch cortex-m4 to SYSTEM PLL1 */ + CLOCK_SetRootMux(kCLOCK_RootM4, kCLOCK_M4RootmuxSysPll1); + + CLOCK_SetRootDivider(kCLOCK_RootAhb, 1U, 1U); + /* Switch AHB to SYSTEM PLL1 DIV6 = 133MHZ */ + CLOCK_SetRootMux(kCLOCK_RootAhb, kCLOCK_AhbRootmuxSysPll1Div6); + + /* Set root clock to 800MHZ/ 2= 400MHZ */ + CLOCK_SetRootDivider(kCLOCK_RootAudioAhb, 1U, 2U); + /* switch AUDIO AHB to SYSTEM PLL1 */ + CLOCK_SetRootMux(kCLOCK_RootAudioAhb, kCLOCK_AudioAhbRootmuxSysPll1); + + /* Set UART source to SysPLL1 Div10 80MHZ */ + CLOCK_SetRootMux(kCLOCK_RootUart4, kCLOCK_UartRootmuxSysPll1Div10); + /* Set root clock to 80MHZ/ 1= 80MHZ */ + CLOCK_SetRootDivider(kCLOCK_RootUart4, 1U, 1U); + + /* Enable RDC clock */ + CLOCK_EnableClock(kCLOCK_Rdc); + + /* + * The purpose to enable the following modules clock is to make + * sure the M4 core could work normally when A53 core + * enters the low power state + */ + CLOCK_EnableClock(kCLOCK_Sim_display); + CLOCK_EnableClock(kCLOCK_Sim_m); + CLOCK_EnableClock(kCLOCK_Sim_main); + CLOCK_EnableClock(kCLOCK_Sim_s); + CLOCK_EnableClock(kCLOCK_Sim_wakeup); + CLOCK_EnableClock(kCLOCK_Debug); + CLOCK_EnableClock(kCLOCK_Dram); + CLOCK_EnableClock(kCLOCK_Sec_Debug); + + CLOCK_EnableClock(kCLOCK_Uart4); +} + +static int nxp_mimx8mm6_init(struct device *arg) +{ + ARG_UNUSED(arg); + + /* SoC specific RDC settings */ + SOC_RdcInit(); + + /* SoC specific Clock settings */ + SOC_ClockInit(); + + return 0; +} + +SYS_INIT(nxp_mimx8mm6_init, PRE_KERNEL_1, 0); diff --git a/soc/arm/nxp_imx/mimx8mm6_m4/soc.h b/soc/arm/nxp_imx/mimx8mm6_m4/soc.h new file mode 100644 index 00000000000..64d9bdae9c7 --- /dev/null +++ b/soc/arm/nxp_imx/mimx8mm6_m4/soc.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2020, Manivannan Sadhasivam + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _SOC__H_ +#define _SOC__H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _ASMLANGUAGE + +#include + +#endif /* !_ASMLANGUAGE */ + +#ifdef __cplusplus +} +#endif + +#endif /* _SOC__H_ */