/* * Copyright (c) 2021, Laird Connectivity * * 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 M7 core to specific RDC domain 1 */ rdc_domain_assignment_t assignment = {0}; uint8_t domainId = 0U; domainId = RDC_GetCurrentMasterDomainId(RDC); /* Only configure the RDC if RDC peripheral write access allowed. */ if ((0x1U & RDC_GetPeriphAccessPolicy(RDC, kRDC_Periph_RDC, domainId)) != 0U) { assignment.domainId = M7_DOMAIN_ID; RDC_SetMasterDomainAssignment(RDC, kRDC_Master_M7, &assignment); } /* * The M7 core is running at domain 1, now enable the clock gate of the following IP/BUS/PLL * in domain 1 in the CCM. In this way, to ensure the clock of the peripherals used by M * core not be affected by A core which is running at domain 0. */ CLOCK_EnableClock(kCLOCK_Iomux); CLOCK_EnableClock(kCLOCK_Ipmux1); CLOCK_EnableClock(kCLOCK_Ipmux2); CLOCK_EnableClock(kCLOCK_Ipmux3); #if defined(FLASH_TARGET) CLOCK_EnableClock(kCLOCK_Qspi); #endif /* Enable the CCGR gate for SysPLL1 in Domain 1 */ CLOCK_ControlGate(kCLOCK_SysPll1Gate, kCLOCK_ClockNeededAll); /* Enable the CCGR gate for SysPLL2 in Domain 1 */ CLOCK_ControlGate(kCLOCK_SysPll2Gate, kCLOCK_ClockNeededAll); /* Enable the CCGR gate for SysPLL3 in Domain 1 */ CLOCK_ControlGate(kCLOCK_SysPll3Gate, kCLOCK_ClockNeededAll); #ifdef CONFIG_INIT_VIDEO_PLL /* Enable the CCGR gate for VideoPLL1 in Domain 1 */ CLOCK_ControlGate(kCLOCK_VideoPll1Gate, kCLOCK_ClockNeededAll); #endif } /* Integer PLLs: Fout = (mainDiv * refSel) / (preDiv * 2^ postDiv) */ /* SYSTEM PLL1 configuration */ const ccm_analog_integer_pll_config_t g_sysPll1Config = { .refSel = kANALOG_PllRefOsc24M, /*!< PLL reference OSC24M */ .mainDiv = 400U, .preDiv = 3U, .postDiv = 2U, /*!< SYSTEM PLL1 frequency = 800MHZ */ }; /* SYSTEM PLL2 configuration */ const ccm_analog_integer_pll_config_t g_sysPll2Config = { .refSel = kANALOG_PllRefOsc24M, /*!< PLL reference OSC24M */ .mainDiv = 250U, .preDiv = 3U, .postDiv = 1U, /*!< SYSTEM PLL2 frequency = 1000MHZ */ }; /* SYSTEM PLL3 configuration */ const ccm_analog_integer_pll_config_t g_sysPll3Config = { .refSel = kANALOG_PllRefOsc24M, /*!< PLL reference OSC24M */ .mainDiv = 300, .preDiv = 3U, .postDiv = 2U, /*!< SYSTEM PLL3 frequency = 600MHZ */ }; static void SOC_ClockInit(void) { /* * The following steps just show how to configure the PLL clock sources using the clock * driver on M7 core side . Please note that the ROM has already configured the SYSTEM PLL1 * to 800Mhz when power up the SOC, meanwhile A core would enable SYSTEM PLL1, SYSTEM PLL2 * and SYSTEM PLL3 by U-Boot. Therefore, there is no need to configure the system PLL again * on M7 side, otherwise it would have a risk to make the SOC hang. */ /* switch AHB NOC root to 24M first in order to configure the SYSTEM PLL1. */ CLOCK_SetRootMux(kCLOCK_RootAhb, kCLOCK_AhbRootmuxOsc24M); /* switch AXI M7 root to 24M first in order to configure the SYSTEM PLL2. */ CLOCK_SetRootMux(kCLOCK_RootM7, kCLOCK_M7RootmuxOsc24M); /* Set root clock to 800M */ CLOCK_SetRootDivider(kCLOCK_RootM7, 1U, 1U); /* switch cortex-m7 to SYSTEM PLL1 */ CLOCK_SetRootMux(kCLOCK_RootM7, kCLOCK_M7RootmuxSysPll1); /* Set root clock freq to 133M / 1= 133MHZ */ CLOCK_SetRootDivider(kCLOCK_RootAhb, 1U, 1U); /* switch AHB to SYSTEM PLL1 DIV6 */ CLOCK_SetRootMux(kCLOCK_RootAhb, kCLOCK_AhbRootmuxSysPll1Div6); #if defined(CONFIG_UART_MCUX_IUART) #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(uart1)) /* Set UART source to SysPLL1 Div10 80MHZ */ CLOCK_SetRootMux(kCLOCK_RootUart1, kCLOCK_UartRootmuxSysPll1Div10); /* Set root clock to 80MHZ/ 1= 80MHZ */ CLOCK_SetRootDivider(kCLOCK_RootUart1, 1U, 1U); #endif #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(uart2)) /* Set UART source to SysPLL1 Div10 80MHZ */ CLOCK_SetRootMux(kCLOCK_RootUart2, kCLOCK_UartRootmuxSysPll1Div10); /* Set root clock to 80MHZ/ 1= 80MHZ */ CLOCK_SetRootDivider(kCLOCK_RootUart2, 1U, 1U); #endif #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(uart3)) /* Set UART source to SysPLL1 Div10 80MHZ */ CLOCK_SetRootMux(kCLOCK_RootUart3, kCLOCK_UartRootmuxSysPll1Div10); /* Set root clock to 80MHZ/ 1= 80MHZ */ CLOCK_SetRootDivider(kCLOCK_RootUart3, 1U, 1U); #endif #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(uart4)) /* 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); #endif #endif #if defined(CONFIG_SPI_MCUX_ECSPI) #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(ecspi1)) /* Set ECSPI1 source to SYSTEM PLL1 800MHZ */ CLOCK_SetRootMux(kCLOCK_RootEcspi1, kCLOCK_EcspiRootmuxSysPll1); /* Set root clock to 800MHZ / 10 = 80MHZ */ CLOCK_SetRootDivider(kCLOCK_RootEcspi1, 2U, 5U); #endif #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(ecspi2)) /* Set ECSPI2 source to SYSTEM PLL1 800MHZ */ CLOCK_SetRootMux(kCLOCK_RootEcspi2, kCLOCK_EcspiRootmuxSysPll1); /* Set root clock to 800MHZ / 10 = 80MHZ */ CLOCK_SetRootDivider(kCLOCK_RootEcspi2, 2U, 5U); #endif #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(ecspi3)) /* Set ECSPI3 source to SYSTEM PLL1 800MHZ */ CLOCK_SetRootMux(kCLOCK_RootEcspi3, kCLOCK_EcspiRootmuxSysPll1); /* Set root clock to 800MHZ / 10 = 80MHZ */ CLOCK_SetRootDivider(kCLOCK_RootEcspi3, 2U, 5U); #endif #endif CLOCK_EnableClock(kCLOCK_Rdc); /* Enable RDC clock */ CLOCK_EnableClock(kCLOCK_Ocram); /* Enable Ocram clock */ /* The purpose to enable the following modules clock is to make sure the M7 core could work * normally when A53 core enters the low power status. */ 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); } static void gpio_init(void) { #if defined(CONFIG_GPIO_MCUX_IGPIO) #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(gpio1)) CLOCK_EnableClock(kCLOCK_Gpio1); #endif #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(gpio2)) CLOCK_EnableClock(kCLOCK_Gpio2); #endif #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(gpio3)) CLOCK_EnableClock(kCLOCK_Gpio3); #endif #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(gpio4)) CLOCK_EnableClock(kCLOCK_Gpio4); #endif #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(gpio5)) CLOCK_EnableClock(kCLOCK_Gpio5); #endif #endif } void soc_early_init_hook(void) { /* SoC specific RDC settings */ SOC_RdcInit(); /* SoC specific Clock settings */ SOC_ClockInit(); gpio_init(); }