nxp_kinetis: Refactor K64F init to use CMSIS register accesses

The K64F SoC initialization previously used macros and structs
custom-defined in Zephyr in order to access peripheral registers.
Refactored it to use CMSIS-style register accesses from the ksdk
instead.

Change-Id: I80975c62de07ec95cf830e99cd5b0abb9623acd0
Signed-off-by: Maureen Helm <maureen.helm@nxp.com>
This commit is contained in:
Maureen Helm 2016-07-23 10:13:01 -05:00 committed by Inaky Perez-Gonzalez
commit dc631750fa
2 changed files with 61 additions and 73 deletions

View file

@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2014-2015 Wind River Systems, Inc. * Copyright (c) 2014-2015 Wind River Systems, Inc.
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -26,14 +27,9 @@
#include <device.h> #include <device.h>
#include <init.h> #include <init.h>
#include <soc.h> #include <soc.h>
#include <drivers/k20_mcg.h>
#include <uart.h> #include <uart.h>
#include <drivers/k20_pcr.h>
#include <drivers/k20_sim.h>
#include <drivers/k6x_mpu.h>
#include <drivers/k6x_pmc.h>
#include <sections.h> #include <sections.h>
#include <fsl_common.h>
#include <arch/cpu.h> #include <arch/cpu.h>
@ -43,6 +39,19 @@
/* board's setting for PLL multipler (VDIV0) */ /* board's setting for PLL multipler (VDIV0) */
#define FRDM_K64F_PLL_MULT_48 (48 - 24) #define FRDM_K64F_PLL_MULT_48 (48 - 24)
/* MCG register field encodings */
#define MCG_C1_CLKS_FLL_PLL (MCG_C1_CLKS(0))
#define MCG_C1_CLKS_EXT_REF (MCG_C1_CLKS(2))
#define MCG_C1_FRDIV_32_1024 (MCG_C1_FRDIV(5))
#define MCG_C1_IREFS_EXT (MCG_C1_IREFS(0))
#define MCG_C2_RANGE_VHIGH (MCG_C2_RANGE(2))
#define MCG_C2_HGO_LO_PWR (MCG_C2_HGO(0))
#define MCG_C2_EREFS_EXT_CLK (MCG_C2_EREFS(0))
#define MCG_C6_PLLS_PLL (MCG_C6_PLLS(1))
#define MCG_C7_OSCSEL_OSC0 (MCG_C7_OSCSEL(0))
#define MCG_S_CLKST_EXT_REF (MCG_S_CLKST(2))
#define MCG_S_CLKST_PLL (MCG_S_CLKST(3))
/* /*
* K64F Flash configuration fields * K64F Flash configuration fields
* These 16 bytes, which must be loaded to address 0x400, include default * These 16 bytes, which must be loaded to address 0x400, include default
@ -94,7 +103,6 @@ uint8_t __security_frdm_k64f_section __security_frdm_k64f[] = {
static ALWAYS_INLINE void clkInit(void) static ALWAYS_INLINE void clkInit(void)
{ {
uint8_t temp_reg; uint8_t temp_reg;
K20_MCG_t *mcg_p = (K20_MCG_t *)PERIPH_ADDR_BASE_MCG; /* clk gen. ctl */
/* /*
* Select the 50 Mhz external clock as the MCG OSC clock. * Select the 50 Mhz external clock as the MCG OSC clock.
@ -102,9 +110,9 @@ static ALWAYS_INLINE void clkInit(void)
* - Select OSCCLK0 / XTAL * - Select OSCCLK0 / XTAL
*/ */
temp_reg = mcg_p->c7 & ~MCG_C7_OSCSEL_MASK; temp_reg = MCG->C7 & ~MCG_C7_OSCSEL_MASK;
temp_reg |= MCG_C7_OSCSEL_OSC0; temp_reg |= MCG_C7_OSCSEL_OSC0;
mcg_p->c7 = temp_reg; MCG->C7 = temp_reg;
/* /*
* Transition MCG from FEI mode (at reset) to FBE mode. * Transition MCG from FEI mode (at reset) to FBE mode.
@ -118,13 +126,13 @@ static ALWAYS_INLINE void clkInit(void)
* - Select external reference clock as the oscillator source * - Select external reference clock as the oscillator source
*/ */
temp_reg = mcg_p->c2 & temp_reg = MCG->C2 &
~(MCG_C2_RANGE_MASK | MCG_C2_HGO_MASK | MCG_C2_EREFS_MASK); ~(MCG_C2_RANGE_MASK | MCG_C2_HGO_MASK | MCG_C2_EREFS_MASK);
temp_reg |= temp_reg |=
(MCG_C2_RANGE_VHIGH | MCG_C2_HGO_LO_PWR | MCG_C2_EREFS_EXT_CLK); (MCG_C2_RANGE_VHIGH | MCG_C2_HGO_LO_PWR | MCG_C2_EREFS_EXT_CLK);
mcg_p->c2 = temp_reg; MCG->C2 = temp_reg;
/* /*
* MCG Control 1 register: * MCG Control 1 register:
@ -140,20 +148,20 @@ static ALWAYS_INLINE void clkInit(void)
* *
*/ */
temp_reg = mcg_p->c1 & temp_reg = MCG->C1 &
~(MCG_C1_CLKS_MASK | MCG_C1_FRDIV_MASK | MCG_C1_IREFS_MASK); ~(MCG_C1_CLKS_MASK | MCG_C1_FRDIV_MASK | MCG_C1_IREFS_MASK);
temp_reg |= temp_reg |=
(MCG_C1_CLKS_EXT_REF | MCG_C1_FRDIV_32_1024 | MCG_C1_IREFS_EXT); (MCG_C1_CLKS_EXT_REF | MCG_C1_FRDIV_32_1024 | MCG_C1_IREFS_EXT);
mcg_p->c1 = temp_reg; MCG->C1 = temp_reg;
/* /*
* Confirm that the external reference clock is the FLL reference * Confirm that the external reference clock is the FLL reference
* source * source
*/ */
while ((mcg_p->s & MCG_S_IREFST_MASK) != 0) while ((MCG->S & MCG_S_IREFST_MASK) != 0)
; ;
; ;
@ -162,7 +170,7 @@ static ALWAYS_INLINE void clkInit(void)
* (MCGOUTCLK) * (MCGOUTCLK)
*/ */
while ((mcg_p->s & MCG_S_CLKST_MASK) != MCG_S_CLKST_EXT_REF) while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST_EXT_REF)
; ;
; ;
@ -181,11 +189,11 @@ static ALWAYS_INLINE void clkInit(void)
* - Set the PLL divider * - Set the PLL divider
*/ */
temp_reg = mcg_p->c5 & ~MCG_C5_PRDIV0_MASK; temp_reg = MCG->C5 & ~MCG_C5_PRDIV0_MASK;
temp_reg |= FRDM_K64F_PLL_DIV_20; temp_reg |= FRDM_K64F_PLL_DIV_20;
mcg_p->c5 = temp_reg; MCG->C5 = temp_reg;
/* /*
* MCG Control 6 register: * MCG Control 6 register:
@ -193,21 +201,21 @@ static ALWAYS_INLINE void clkInit(void)
* - Set the PLL multiplier * - Set the PLL multiplier
*/ */
temp_reg = mcg_p->c6 & ~(MCG_C6_PLLS_MASK | MCG_C6_VDIV0_MASK); temp_reg = MCG->C6 & ~(MCG_C6_PLLS_MASK | MCG_C6_VDIV0_MASK);
temp_reg |= (MCG_C6_PLLS_PLL | FRDM_K64F_PLL_MULT_48); temp_reg |= (MCG_C6_PLLS_PLL | FRDM_K64F_PLL_MULT_48);
mcg_p->c6 = temp_reg; MCG->C6 = temp_reg;
/* Confirm that the PLL clock is selected as the PLL output */ /* Confirm that the PLL clock is selected as the PLL output */
while ((mcg_p->s & MCG_S_PLLST_MASK) == 0) while ((MCG->S & MCG_S_PLLST_MASK) == 0)
; ;
; ;
/* Confirm that the PLL has acquired lock */ /* Confirm that the PLL has acquired lock */
while ((mcg_p->s & MCG_S_LOCK0_MASK) == 0) while ((MCG->S & MCG_S_LOCK0_MASK) == 0)
; ;
; ;
@ -217,15 +225,15 @@ static ALWAYS_INLINE void clkInit(void)
* - Select PLL as the system clock source (MCGOUTCLK) * - Select PLL as the system clock source (MCGOUTCLK)
*/ */
temp_reg = mcg_p->c1 & ~MCG_C1_CLKS_MASK; temp_reg = MCG->C1 & ~MCG_C1_CLKS_MASK;
temp_reg |= MCG_C1_CLKS_FLL_PLL; temp_reg |= MCG_C1_CLKS_FLL_PLL;
mcg_p->c1 = temp_reg; MCG->C1 = temp_reg;
/* Confirm that the PLL output is the system clock source (MCGOUTCLK) */ /* Confirm that the PLL output is the system clock source (MCGOUTCLK) */
while ((mcg_p->s & MCG_S_CLKST_MASK) != MCG_S_CLKST_PLL) while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST_PLL)
; ;
; ;
} }
@ -244,17 +252,6 @@ static ALWAYS_INLINE void clkInit(void)
static int fsl_frdm_k64f_init(struct device *arg) static int fsl_frdm_k64f_init(struct device *arg)
{ {
ARG_UNUSED(arg); ARG_UNUSED(arg);
/* System Integration module */
volatile struct K20_SIM *sim_p =
(volatile struct K20_SIM *)PERIPH_ADDR_BASE_SIM;
/* Power Mgt Control module */
volatile struct K6x_PMC *pmc_p =
(volatile struct K6x_PMC *)PERIPH_ADDR_BASE_PMC;
/* Power Mgt Control module */
volatile struct K6x_MPU *mpu_p =
(volatile struct K6x_MPU *)PERIPH_ADDR_BASE_MPU;
int oldLevel; /* old interrupt lock level */ int oldLevel; /* old interrupt lock level */
uint32_t temp_reg; uint32_t temp_reg;
@ -263,12 +260,12 @@ static int fsl_frdm_k64f_init(struct device *arg)
oldLevel = irq_lock(); oldLevel = irq_lock();
/* enable the port clocks */ /* enable the port clocks */
sim_p->scgc5.value |= (SIM_SCGC5_PORTA_CLK_EN | SIM_SCGC5_PORTB_CLK_EN | SIM->SCGC5 |= (SIM_SCGC5_PORTA(1) | SIM_SCGC5_PORTB(1) |
SIM_SCGC5_PORTC_CLK_EN | SIM_SCGC5_PORTD_CLK_EN | SIM_SCGC5_PORTC(1) | SIM_SCGC5_PORTD(1) |
SIM_SCGC5_PORTE_CLK_EN); SIM_SCGC5_PORTE(1));
/* release I/O power hold to allow normal run state */ /* release I/O power hold to allow normal run state */
pmc_p->regsc.value |= PMC_REGSC_ACKISO_MASK; PMC->REGSC |= PMC_REGSC_ACKISO_MASK;
/* /*
* Disable memory protection and clear slave port errors. * Disable memory protection and clear slave port errors.
@ -276,10 +273,10 @@ static int fsl_frdm_k64f_init(struct device *arg)
* protection unit (MPU), specified by the architecture (PMSAv7), in the * protection unit (MPU), specified by the architecture (PMSAv7), in the
* Cortex-M4 core. Instead, the processor includes its own MPU module. * Cortex-M4 core. Instead, the processor includes its own MPU module.
*/ */
temp_reg = mpu_p->ctrlErrStatus.value; temp_reg = MPU->CESR;
temp_reg &= ~MPU_VALID_MASK; temp_reg &= ~MPU_CESR_VLD_MASK;
temp_reg |= MPU_SLV_PORT_ERR_MASK; temp_reg |= MPU_CESR_SPERR_MASK;
mpu_p->ctrlErrStatus.value = temp_reg; MPU->CESR = temp_reg;
/* clear all faults */ /* clear all faults */
@ -296,15 +293,11 @@ static int fsl_frdm_k64f_init(struct device *arg)
* FlexBus clock = 40 MHz (PLL/OUTDIV3) * FlexBus clock = 40 MHz (PLL/OUTDIV3)
* Flash clock = 24 MHz (PLL/OUTDIV4) * Flash clock = 24 MHz (PLL/OUTDIV4)
*/ */
sim_p->clkdiv1.value = ( SIM->CLKDIV1 = (
(SIM_CLKDIV(CONFIG_K64_CORE_CLOCK_DIVIDER) << SIM_CLKDIV1_OUTDIV1(CONFIG_K64_CORE_CLOCK_DIVIDER - 1) |
SIM_CLKDIV1_OUTDIV1_SHIFT) | SIM_CLKDIV1_OUTDIV2(CONFIG_K64_BUS_CLOCK_DIVIDER - 1) |
(SIM_CLKDIV(CONFIG_K64_BUS_CLOCK_DIVIDER) << SIM_CLKDIV1_OUTDIV3(CONFIG_K64_FLEXBUS_CLOCK_DIVIDER - 1) |
SIM_CLKDIV1_OUTDIV2_SHIFT) | SIM_CLKDIV1_OUTDIV4(CONFIG_K64_FLASH_CLOCK_DIVIDER - 1));
(SIM_CLKDIV(CONFIG_K64_FLEXBUS_CLOCK_DIVIDER) <<
SIM_CLKDIV1_OUTDIV3_SHIFT) |
(SIM_CLKDIV(CONFIG_K64_FLASH_CLOCK_DIVIDER) <<
SIM_CLKDIV1_OUTDIV4_SHIFT));
/* Initialize PLL/system clock to 120 MHz */ /* Initialize PLL/system clock to 120 MHz */
clkInit(); clkInit();

View file

@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2015 Intel Corporation. * Copyright (c) 2015 Intel Corporation.
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -24,11 +25,10 @@
#include <nanokernel.h> #include <nanokernel.h>
#include "soc.h" #include "soc.h"
#include <fsl_common.h>
#ifdef CONFIG_UART_K20 #ifdef CONFIG_UART_K20
#include <uart.h> #include <uart.h>
#include <drivers/k20_pcr.h>
#include <drivers/k20_sim.h>
#include <console/uart_console.h> #include <console/uart_console.h>
#include <serial/uart_k20_priv.h> #include <serial/uart_k20_priv.h>
#endif /* CONFIG_UART_K20 */ #endif /* CONFIG_UART_K20 */
@ -42,6 +42,8 @@
#if defined(CONFIG_UART_CONSOLE) && \ #if defined(CONFIG_UART_CONSOLE) && \
(defined(CONFIG_PRINTK) || defined(CONFIG_STDOUT_CONSOLE)) (defined(CONFIG_PRINTK) || defined(CONFIG_STDOUT_CONSOLE))
static PORT_Type *const ports[] = PORT_BASE_PTRS;
/** /**
* @brief Initialize K20 serial port as console * @brief Initialize K20 serial port as console
* *
@ -53,25 +55,20 @@
*/ */
static ALWAYS_INLINE int uart_k20_console_init(void) static ALWAYS_INLINE int uart_k20_console_init(void)
{ {
uint32_t port; PORT_Type *port;
uint32_t rxPin; uint32_t rxPin;
uint32_t txPin; uint32_t txPin;
union K20_PCR pcr = {0}; /* Pin Control Register */
/* Port/pin ctrl module */ /* Port/pin ctrl module */
volatile struct K20_PORT_PCR *port_pcr_p = port = ports[CONFIG_UART_CONSOLE_PORT];
(volatile struct K20_PORT_PCR *)PERIPH_ADDR_BASE_PCR;
/* UART0 Rx and Tx pin assignments */ /* UART0 Rx and Tx pin assignments */
port = CONFIG_UART_CONSOLE_PORT;
rxPin = CONFIG_UART_CONSOLE_PORT_RX_PIN; rxPin = CONFIG_UART_CONSOLE_PORT_RX_PIN;
txPin = CONFIG_UART_CONSOLE_PORT_TX_PIN; txPin = CONFIG_UART_CONSOLE_PORT_TX_PIN;
/* Enable the UART Rx and Tx Pins */ /* Enable the UART Rx and Tx Pins */
pcr.field.mux = CONFIG_UART_CONSOLE_PORT_MUX_FUNC; port->PCR[rxPin] = PORT_PCR_MUX(CONFIG_UART_CONSOLE_PORT_MUX_FUNC);
port->PCR[txPin] = PORT_PCR_MUX(CONFIG_UART_CONSOLE_PORT_MUX_FUNC);
port_pcr_p->port[port].pcr[rxPin] = pcr;
port_pcr_p->port[port].pcr[txPin] = pcr;
return 0; return 0;
} }
@ -82,9 +79,7 @@ static ALWAYS_INLINE int uart_k20_console_init(void)
static int uart_k20_init(struct device *dev) static int uart_k20_init(struct device *dev)
{ {
volatile struct K20_SIM *sim = /* sys integ. ctl */ uint32_t scgc4;
(volatile struct K20_SIM *)PERIPH_ADDR_BASE_SIM;
SIM_SCGC4_t scgc4;
ARG_UNUSED(dev); ARG_UNUSED(dev);
@ -92,28 +87,28 @@ static int uart_k20_init(struct device *dev)
* *sim directly, the following code saves about 20 bytes * *sim directly, the following code saves about 20 bytes
* of ROM space, compared to direct modification. * of ROM space, compared to direct modification.
*/ */
scgc4.value = sim->scgc4.value; scgc4 = SIM->SCGC4;
#ifdef CONFIG_UART_K20_PORT_0 #ifdef CONFIG_UART_K20_PORT_0
scgc4.field.uart0_clk_en = 1; scgc4 |= SIM_SCGC4_UART0(1);
#endif #endif
#ifdef CONFIG_UART_K20_PORT_1 #ifdef CONFIG_UART_K20_PORT_1
scgc4.field.uart1_clk_en = 1; scgc4 |= SIM_SCGC4_UART1(1);
#endif #endif
#ifdef CONFIG_UART_K20_PORT_2 #ifdef CONFIG_UART_K20_PORT_2
scgc4.field.uart2_clk_en = 1; scgc4 |= SIM_SCGC4_UART2(1);
#endif #endif
#ifdef CONFIG_UART_K20_PORT_3 #ifdef CONFIG_UART_K20_PORT_3
scgc4.field.uart3_clk_en = 1; scgc4 |= SIM_SCGC4_UART3(1);
#endif #endif
sim->scgc4.value = scgc4.value; SIM->SCGC4 = scgc4;
#ifdef CONFIG_UART_K20_PORT_4 #ifdef CONFIG_UART_K20_PORT_4
sim->scgc1.field.uart4_clk_en = 1; SIM->SCGC1 |= SIM_SCGC1_UART4(1);
#endif #endif
/* Initialize UART port for console if needed */ /* Initialize UART port for console if needed */