Commit 0c572f22 authored by Alexander Potashev's avatar Alexander Potashev

RT79078. k70-som: Enable and use the RTC clock for FLL when switching to FBE mode

 * In order to switch the MCG to the PLL Engaged External mode (PEE
mode), it must pass the FLL Bypassed External mode (FBE mode) as an
intermediate step. See section `25.4.1 MCG Mode State Diagram` on page
656 of the K70 Reference Manual.
 * Enable and use the RTC clock for FLL when switching to the
FLL Bypassed External mode (FBE mode). We do this in `clock_fei_to_fbe()`
in `u-boot/cpu/arm_cortexm3/kinetis/clock.c` before switching to
the FBE mode. This is required, because:
   * In order to switch to the PLL Engaged External mode (PEE mode), we
must pass the FLL Bypassed External mode (FBE mode).
   * This FBE mode requires that there is a working FLL reference clock.
   * Only OSC0 clock (clock or oscillator at EXTAL0/XTAL0) or RTC clock
(oscillator at EXTAL32/XTAL32) can be used as reference clock for FLL.
   * In the K**-SOM/DNI-ETH configuration, nothing is connected to
EXTAL0, therefore we have to use the RTC clock as reference clock
for FLL in the FBE mode.
 * Use RTC for FLL reference clock only on K**-SOMs, but not for
TWR-K70F120M. To do that, we add a new U-Boot configuration option
`KINETIS_FLLREF_RTC` that will control usage of RTC for FLL reference
clock and define this configuration option only in
`u-boot/include/configs/k70-som.h`.
 * Use in-MCU 20pF oscillator load.
parent cffd9a6b
......@@ -123,7 +123,7 @@
* Set KINETIS_MCG_FRDIV to the code for writing into the FRDIV bit field
* of the MCG_C1 register.
*/
#if KINETIS_MCG_FREQ_RANGE == 0
#if KINETIS_MCG_FREQ_RANGE == 0 || defined(KINETIS_FLLREF_RTC)
#if KINETIS_MCG_FRDIV_POW >= 0 && KINETIS_MCG_FRDIV_POW <= 7
#define KINETIS_MCG_FRDIV KINETIS_MCG_FRDIV_POW
#else
......@@ -313,6 +313,11 @@
#define KINETIS_MCG_C6_VDIV_BITS 0
/* PLL Select */
#define KINETIS_MCG_C6_PLLS_MSK (1 << 6)
/*
* MCG Control 7 Register
*/
/* MCG OSC Clock Select */
#define KINETIS_MCG_C7_OSCSEL_MSK (1 << 0)
/*
* MCG Control 10 Register
*/
......@@ -478,6 +483,48 @@
#endif /* !CONFIG_KINETIS_DDR */
#endif /* CONFIG_KINETIS_DDR_SYNC */
/*
* RTC Control Register
*/
/* Oscillator 4pF load configure */
#define KINETIS_RTC_CR_SC4P_MSK (1 << 12)
/* Oscillator 16pF load configure */
#define KINETIS_RTC_CR_SC16P_MSK (1 << 10)
/* Oscillator Enable */
#define KINETIS_RTC_CR_OSCE_MSK (1 << 8)
/*
* Real Time Clock (RTC) register map
*/
struct kinetis_rtc_regs {
u32 tsr; /* RTC Time Seconds Register */
u32 tpr; /* RTC Time Prescaler Register */
u32 tar; /* RTC Time Alarm Register */
u32 tcr; /* RTC Time Compensation Register */
u32 cr; /* RTC Control Register */
u32 sr; /* RTC Status Register */
u32 lr; /* RTC Lock Register */
u32 ier; /* RTC Interrupt Enable Register */
u32 ttsr; /* RTC Tamper Time Seconds Register */
u32 mer; /* RTC Monotonic Enable Register */
u32 mclr; /* RTC Monotonic Counter Low Register */
u32 mchr; /* RTC Monotonic Counter High Register */
u32 ter; /* RTC Tamper Enable Register */
u32 tdr; /* RTC Tamper Detect Register */
u32 ttr; /* RTC Tamper Trim Register */
u32 tir; /* RTC Tamper Interrupt Register */
u32 rsv0[496];
u32 war; /* RTC Write Access Register */
u32 rar; /* RTC Read Access Register */
};
/*
* RTC registers base
*/
#define KINETIS_RTC_BASE (KINETIS_AIPS0PERIPH_BASE + 0x0003D000)
#define KINETIS_RTC ((volatile struct kinetis_rtc_regs *) \
KINETIS_RTC_BASE)
/*
* Clock values
*/
......@@ -509,6 +556,30 @@ static void clock_fei_to_fbe(void)
#endif /* KINETIS_MCG_PLLREFSEL */
#endif /* KINETIS_MCG_EXT_CRYSTAL */
/*
* Use RTC clock for FLL reference clock, if needed.
*/
#ifdef KINETIS_FLLREF_RTC
/*
* Enable the RTC module of the MCU
*/
kinetis_periph_enable(KINETIS_CG_RTC, 1);
/*
* Enable RTC
*
* RTC oscillator load capacity should be 20pF (=16+4) for K70-SOM.
*/
KINETIS_RTC->cr |=
KINETIS_RTC_CR_SC16P_MSK | KINETIS_RTC_CR_SC4P_MSK |
KINETIS_RTC_CR_OSCE_MSK;
/*
* Select 32 kHz RTC as the FLL external reference clock
*/
KINETIS_MCG->c7 |= KINETIS_MCG_C7_OSCSEL_MSK;
#endif /* KINETIS_FLLREF_RTC */
/*
* Set the FLL External Reference Divider.
* Select the clock source for MCGOUTCLK.
......
......@@ -95,6 +95,8 @@ typedef u32 kinetis_clock_gate_t;
#define KINETIS_CG_NFC KINETIS_MKCG(2, 8) /* SIM_SCGC3[8] */
/* OSC1 */
#define KINETIS_CG_OSC1 KINETIS_MKCG(0, 5) /* SIM_SCGC1[5] */
/* RTC */
#define KINETIS_CG_RTC KINETIS_MKCG(5, 29) /* SIM_SCGC6[29] */
/*
* Limits for the `kinetis_periph_enable()` function:
......
......@@ -122,10 +122,16 @@
#define KINETIS_MCG_PLLREFSEL 1 /* OSC1 */
#define KINETIS_MCG_EXT_CRYSTAL
/*
* The EXTAL0 rate divided by the divisor value (2**10 = 1024) specified by this
* constant should be as close to the 32..40 kHz range as possible.
* Use RTC oscillator for FLL reference clock, because on K70-SOM/DNI-ETH
* we do not have reference clock from Ethernet PHY on EXTAL0.
*/
#define KINETIS_MCG_FRDIV_POW 10
#define KINETIS_FLLREF_RTC
/*
* The EXTAL32 rate (32 kHz) divided by the divisor value (2**0 = 1)
* specified by this constant should be as close to the 32..40 kHz
* range as possible.
*/
#define KINETIS_MCG_FRDIV_POW 0
/* Core/system clock divider: 120/1 = 120MHz or 150/1 = 150MHz */
#define KINETIS_CCLK_DIV 1
/* Peripheral clock divider: 120/2 = 60MHz or 150/2 = 75MHz */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment