blob: eacdb36f0efd1ac33d943c8f58245461a0310c8e [file] [log] [blame]
/*
** ###################################################################
** Processors: MIMX8MQ6CVAHZ
** MIMX8MQ6DVAJZ
**
** Compilers: Keil ARM C/C++ Compiler
** GNU C Compiler
** IAR ANSI C/C++ Compiler for ARM
**
** Reference manual: IMX8MDQLQRM, Rev. 0, Jan. 2018
** Version: rev. 4.0, 2018-01-26
** Build: b180903
**
** Abstract:
** Provides a system configuration function and a global variable that
** contains the system frequency. It configures the device and initializes
** the oscillator (PLL) that is part of the microcontroller device.
**
** Copyright 2016 Freescale Semiconductor, Inc.
** Copyright 2016-2018 NXP
** All rights reserved.
**
** SPDX-License-Identifier: BSD-3-Clause
**
** http: www.nxp.com
** mail: support@nxp.com
**
** Revisions:
** - rev. 1.0 (2017-01-10)
** Initial version.
** - rev. 2.0 (2017-04-27)
** Rev.B Header EAR1
** - rev. 3.0 (2017-07-19)
** Rev.C Header EAR2
** - rev. 4.0 (2018-01-26)
** Rev.D Header RFP
**
** ###################################################################
*/
/*!
* @file MIMX8MQ6_cm4
* @version 4.0
* @date 2018-01-26
* @brief Device specific configuration file for MIMX8MQ6_cm4 (implementation
* file)
*
* Provides a system configuration function and a global variable that contains
* the system frequency. It configures the device and initializes the oscillator
* (PLL) that is part of the microcontroller device.
*/
#include <stdint.h>
#include "fsl_device_registers.h"
/*!
* @brief CCM reg macros to extract corresponding registers bit field.
*/
#define CCM_BIT_FIELD_VAL(val, mask, shift) (((val) & mask) >> shift)
/*!
* @brief CCM reg macros to get corresponding registers values.
*/
#define CCM_ANALOG_REG_VAL(base, off) (*((volatile uint32_t *)((uint32_t)base + off)))
uint32_t GetFracPllFreq(volatile uint32_t *base)
{
uint32_t fracCfg0 = CCM_ANALOG_REG_VAL(base, 0U);
uint32_t fracCfg1 = CCM_ANALOG_REG_VAL(base, 4U);
uint32_t refClkFreq = 0U;
uint64_t fracClk = 0U;
uint8_t refSel = CCM_BIT_FIELD_VAL(fracCfg0, CCM_ANALOG_AUDIO_PLL1_CFG0_PLL_REFCLK_SEL_MASK, CCM_ANALOG_AUDIO_PLL1_CFG0_PLL_REFCLK_SEL_SHIFT);
uint8_t refDiv = CCM_BIT_FIELD_VAL(fracCfg0, CCM_ANALOG_AUDIO_PLL1_CFG0_PLL_REFCLK_DIV_VAL_MASK, CCM_ANALOG_AUDIO_PLL1_CFG0_PLL_REFCLK_DIV_VAL_SHIFT);
uint8_t outDiv = CCM_BIT_FIELD_VAL(fracCfg0, CCM_ANALOG_AUDIO_PLL1_CFG0_PLL_OUTPUT_DIV_VAL_MASK, CCM_ANALOG_AUDIO_PLL1_CFG0_PLL_OUTPUT_DIV_VAL_SHIFT);
uint32_t fracDiv = CCM_BIT_FIELD_VAL(fracCfg1, CCM_ANALOG_AUDIO_PLL1_CFG1_PLL_FRAC_DIV_CTL_MASK, CCM_ANALOG_AUDIO_PLL1_CFG1_PLL_FRAC_DIV_CTL_SHIFT);
uint8_t intDiv = CCM_BIT_FIELD_VAL(fracCfg1, CCM_ANALOG_AUDIO_PLL1_CFG1_PLL_INT_DIV_CTL_MASK, CCM_ANALOG_AUDIO_PLL1_CFG1_PLL_INT_DIV_CTL_SHIFT);
if(refSel == 0) /* OSC 25M Clock */
{
refClkFreq = CPU_XTAL_SOSC_CLK_25MHZ;
}
else if ((refSel == 1) || /* OSC 27M Clock */
(refSel == 2)) /* HDMI_PYH 27M Clock */
{
refClkFreq = CPU_XTAL_SOSC_CLK_27MHZ;
}
else
{
refClkFreq = CLK_P_N_FREQ; /* CLK_P_N Clock, please note that the value is 0hz by default, it could be set at system_MIMX8MQx_cm4.h :88 */
}
refClkFreq /= refDiv + 1U;
fracClk = (uint64_t)refClkFreq * 8U * (1U + intDiv) + (((uint64_t)refClkFreq * 8U * fracDiv) >> 24U);
return fracClk / ((outDiv +1U) * 2U);
}
uint32_t GetSSCGPllFreq(volatile uint32_t * base)
{
uint32_t sscgCfg0 = CCM_ANALOG_REG_VAL(base, 0U);
uint32_t sscgCfg1 = CCM_ANALOG_REG_VAL(base, 4U);
uint32_t sscgCfg2 = CCM_ANALOG_REG_VAL(base, 8U);
uint32_t refClkFreq = 0U;
uint64_t pll2InputClock = 0U;
uint8_t pll1Bypass = CCM_BIT_FIELD_VAL(sscgCfg0, CCM_ANALOG_SYS_PLL1_CFG0_PLL_BYPASS1_MASK, CCM_ANALOG_SYS_PLL1_CFG0_PLL_BYPASS1_SHIFT);
uint8_t refSel = CCM_BIT_FIELD_VAL(sscgCfg0, CCM_ANALOG_SYS_PLL1_CFG0_PLL_REFCLK_SEL_MASK, CCM_ANALOG_SYS_PLL1_CFG0_PLL_REFCLK_SEL_SHIFT);
uint8_t refDiv1 = CCM_BIT_FIELD_VAL(sscgCfg2, CCM_ANALOG_SYS_PLL1_CFG2_PLL_REF_DIVR1_MASK, CCM_ANALOG_SYS_PLL1_CFG2_PLL_REF_DIVR1_SHIFT) + 1U;
uint8_t refDiv2 = CCM_BIT_FIELD_VAL(sscgCfg2, CCM_ANALOG_SYS_PLL1_CFG2_PLL_REF_DIVR2_MASK, CCM_ANALOG_SYS_PLL1_CFG2_PLL_REF_DIVR2_SHIFT) + 1U;
uint8_t divf1 = CCM_BIT_FIELD_VAL(sscgCfg2, CCM_ANALOG_SYS_PLL1_CFG2_PLL_FEEDBACK_DIVF1_MASK, CCM_ANALOG_SYS_PLL1_CFG2_PLL_FEEDBACK_DIVF1_SHIFT) + 1U;
uint8_t divf2 = CCM_BIT_FIELD_VAL(sscgCfg2, CCM_ANALOG_SYS_PLL1_CFG2_PLL_FEEDBACK_DIVF2_MASK, CCM_ANALOG_SYS_PLL1_CFG2_PLL_FEEDBACK_DIVF2_SHIFT) + 1U;
uint8_t outDiv = CCM_BIT_FIELD_VAL(sscgCfg2, CCM_ANALOG_SYS_PLL1_CFG2_PLL_OUTPUT_DIV_VAL_MASK, CCM_ANALOG_SYS_PLL1_CFG2_PLL_OUTPUT_DIV_VAL_SHIFT) + 1U;
if(refSel == 0) /* OSC 25M Clock */
{
refClkFreq = CPU_XTAL_SOSC_CLK_25MHZ;
}
else if ((refSel == 1) || /* OSC 27M Clock */
(refSel == 2)) /* HDMI_PYH 27M Clock */
{
refClkFreq = CPU_XTAL_SOSC_CLK_27MHZ;
}
else
{
refClkFreq = CLK_P_N_FREQ; /* CLK_P_N Clock, please note that the value is 0hz by default, it could be set at system_MIMX8MQx_cm4.h :88 */
}
refClkFreq /= refDiv1;
if(pll1Bypass)
{
pll2InputClock = refClkFreq;
}
else if(sscgCfg1 & CCM_ANALOG_SYS_PLL1_CFG1_PLL_SSE_MASK)
{
pll2InputClock = (uint64_t)refClkFreq * 8U * divf1 / refDiv2;
}
else
{
pll2InputClock = refClkFreq * 2U * divf1 / refDiv2;
}
return pll2InputClock * divf2 / outDiv;
}
/* ----------------------------------------------------------------------------
-- Core clock
---------------------------------------------------------------------------- */
uint32_t SystemCoreClock = DEFAULT_SYSTEM_CLOCK;
/* ----------------------------------------------------------------------------
-- SystemInit()
---------------------------------------------------------------------------- */
void SystemInit (void) {
#if ((__FPU_PRESENT == 1) && (__FPU_USED == 1))
SCB->CPACR |= ((3UL << 10*2) | (3UL << 11*2)); /* set CP10, CP11 Full Access */
#endif /* ((__FPU_PRESENT == 1) && (__FPU_USED == 1)) */
/* Initialize Cache */
/* Enable Code Bus Cache */
/* set command to invalidate all ways, and write GO bit to initiate command */
LMEM->PCCCR |= LMEM_PCCCR_INVW1_MASK | LMEM_PCCCR_INVW0_MASK;
LMEM->PCCCR |= LMEM_PCCCR_GO_MASK;
/* Wait until the command completes */
while ((LMEM->PCCCR & LMEM_PCCCR_GO_MASK) != 0U) {
}
/* Enable cache, enable write buffer */
LMEM->PCCCR |= (LMEM_PCCCR_ENWRBUF_MASK | LMEM_PCCCR_ENCACHE_MASK);
/* Enable System Bus Cache */
/* set command to invalidate all ways, and write GO bit to initiate command */
LMEM->PSCCR |= LMEM_PSCCR_INVW1_MASK | LMEM_PSCCR_INVW0_MASK;
LMEM->PSCCR |= LMEM_PSCCR_GO_MASK;
/* Wait until the command completes */
while ((LMEM->PSCCR & LMEM_PSCCR_GO_MASK) != 0U) {
}
/* Enable cache, enable write buffer */
LMEM->PSCCR |= (LMEM_PSCCR_ENWRBUF_MASK | LMEM_PSCCR_ENCACHE_MASK);
__ISB();
__DSB();
SystemInitHook();
}
/* ----------------------------------------------------------------------------
-- SystemCoreClockUpdate()
---------------------------------------------------------------------------- */
void SystemCoreClockUpdate (void) {
volatile uint32_t * M4_ClockRoot = (uint32_t *)(&(CCM)->ROOT[1].TARGET_ROOT);
uint32_t pre = ((*M4_ClockRoot & CCM_TARGET_ROOT_PRE_PODF_MASK) >> CCM_TARGET_ROOT_PRE_PODF_SHIFT) + 1U;
uint32_t post = ((*M4_ClockRoot & CCM_TARGET_ROOT_POST_PODF_MASK) >> CCM_TARGET_ROOT_POST_PODF_SHIFT) + 1U;
uint32_t freq = 0U;
switch((*M4_ClockRoot & CCM_TARGET_ROOT_MUX_MASK) >> CCM_TARGET_ROOT_MUX_SHIFT)
{
case 0U: /* OSC 25M Clock */
freq = CPU_XTAL_SOSC_CLK_25MHZ;
break;
case 1U: /* System PLL2 DIV5 */
freq = GetSSCGPllFreq(&(CCM_ANALOG->SYS_PLL2_CFG0)) / 5; /* Get System PLL2 DIV5 freq */
break;
case 2U: /* System PLL2 DIV4 */
freq = GetSSCGPllFreq(&(CCM_ANALOG->SYS_PLL2_CFG0)) / 4; /* Get System PLL2 DIV4 freq */
break;
case 3U: /* System PLL1 DIV3 */
freq = GetSSCGPllFreq(&(CCM_ANALOG->SYS_PLL1_CFG0)) / 3; /* Get System PLL1 DIV3 freq */
break;
case 4U: /* System PLL1 */
freq = GetSSCGPllFreq(&(CCM_ANALOG->SYS_PLL1_CFG0)); /* Get System PLL1 freq */
break;
case 5U: /* AUDIO PLL1 */
freq = GetFracPllFreq(&(CCM_ANALOG->AUDIO_PLL1_CFG0)); /* Get AUDIO PLL1 freq */
break;
case 6U: /* VIDEO PLL1 */
freq = GetFracPllFreq(&(CCM_ANALOG->VIDEO_PLL1_CFG0)); /* Get VIDEO PLL1 freq */
break;
case 7U: /* System PLL3 */
freq = GetSSCGPllFreq(&(CCM_ANALOG->SYS_PLL3_CFG0)); /* Get System PLL3 freq */
break;
default:
break;
}
SystemCoreClock = freq / pre / post;
}
/* ----------------------------------------------------------------------------
-- SystemInitHook()
---------------------------------------------------------------------------- */
__attribute__ ((weak)) void SystemInitHook (void) {
/* Void implementation of the weak function. */
}