From e7a3231d7a3ab54f21deefb6cf91109b046063d2 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 17 Aug 2019 11:50:32 -0600 Subject: [PATCH] Squashed commit of the following: Finishes peripheral clock initialization: arch/arm/src/s32k1xx/s32k11x/s32k11x_clockmapping.c arch/arm/src/s32k1xx/s32k14x/s32k14x_clockmapping.c Provide MCU-specific mapping of clock names to PCC control registers. boards/arm/s32k1xx/s32k118evb/src/s32k118_periphclocks.c Provides initial clocking for for the S32K118EVB arch/arm/src/s32k1xx/s32k1xx_periphclocks.c: Add logic to initialize peripheral clocking. arch/arm/src/s32k1xx/s32k1xx_clockconfig.c: Add SIM clock configuration. --- arch/arm/src/s32k1xx/Kconfig | 18 +- arch/arm/src/s32k1xx/Make.defs | 4 +- arch/arm/src/s32k1xx/hardware/s32k1xx_pcc.h | 3 +- arch/arm/src/s32k1xx/hardware/s32k1xx_sim.h | 3 + arch/arm/src/s32k1xx/s32k11x/Make.defs | 2 +- .../s32k1xx/s32k11x/s32k11x_clockmapping.c | 128 +++++++++ arch/arm/src/s32k1xx/s32k14x/Make.defs | 2 +- .../s32k1xx/s32k14x/s32k14x_clockmapping.c | 128 +++++++++ arch/arm/src/s32k1xx/s32k1xx_clockconfig.c | 173 +++++++++++-- arch/arm/src/s32k1xx/s32k1xx_clockconfig.h | 70 +---- arch/arm/src/s32k1xx/s32k1xx_periphclocks.c | 212 +++++++++++++++ arch/arm/src/s32k1xx/s32k1xx_periphclocks.h | 244 ++++++++++++++++++ boards/arm/s32k1xx/s32k118evb/src/Makefile | 5 +- .../s32k118evb/src/s32k118_clockconfig.c | 16 +- .../s32k118evb/src/s32k118_periphclocks.c | 152 +++++++++++ .../arm/s32k1xx/s32k118evb/src/s32k118evb.h | 11 + 16 files changed, 1061 insertions(+), 110 deletions(-) create mode 100644 arch/arm/src/s32k1xx/s32k11x/s32k11x_clockmapping.c create mode 100644 arch/arm/src/s32k1xx/s32k14x/s32k14x_clockmapping.c create mode 100644 arch/arm/src/s32k1xx/s32k1xx_periphclocks.c create mode 100644 arch/arm/src/s32k1xx/s32k1xx_periphclocks.h create mode 100644 boards/arm/s32k1xx/s32k118evb/src/s32k118_periphclocks.c diff --git a/arch/arm/src/s32k1xx/Kconfig b/arch/arm/src/s32k1xx/Kconfig index 78519772362..2d0b7898914 100644 --- a/arch/arm/src/s32k1xx/Kconfig +++ b/arch/arm/src/s32k1xx/Kconfig @@ -85,6 +85,10 @@ config S32K1XX_HAVE_HSRUN bool default n +config S32K1XX_HAVE_QSPI + bool + default n + config S32K1XX_HAVE_SAI bool default n @@ -95,11 +99,11 @@ config S32K1XX_HAVE_SPLL # Peripheral Group Selections -config S32K1XX_HAVE_LPUART +config S32K1XX_LPUART bool default n -config S32K1XX_HAVE_LPSPI +config S32K1XX_LPSPI bool default n @@ -110,31 +114,31 @@ menu "S32K1XX Peripheral Selection" config S32K1XX_LPUART0 bool "LPUART0" default n - select S32K1XX_HAVE_LPUART + select S32K1XX_LPUART select LPUART0_SERIALDRIVER config S32K1XX_LPUART1 bool "LPUART1" default n - select S32K1XX_HAVE_LPUART + select S32K1XX_LPUART select LPUART1_SERIALDRIVER config S32K1XX_LPUART2 bool "LPUART2" default n - select S32K1XX_HAVE_LPUART + select S32K1XX_LPUART select LPUART2_SERIALDRIVER config S32K1XX_LPSPI0 bool "LPSPI0" default n - select S32K1XX_HAVE_LPSPI + select S32K1XX_LPSPI select SPI config S32K1XX_LPSPI1 bool "LPSPI1" default n - select S32K1XX_HAVE_LPSPI + select S32K1XX_LPSPI select SPI endmenu # S32K1XX Peripheral Selection diff --git a/arch/arm/src/s32k1xx/Make.defs b/arch/arm/src/s32k1xx/Make.defs index 7cc45ac82be..e74f6ed7ecb 100644 --- a/arch/arm/src/s32k1xx/Make.defs +++ b/arch/arm/src/s32k1xx/Make.defs @@ -54,9 +54,9 @@ endif CHIP_ASRCS = CHIP_CSRCS = s32k1xx_start.c s32k1xx_lowputc.c s32k1xx_clockconfig.c -CHIP_CSRCS += s32k1xx_pin.c +CHIP_CSRCS += s32k1xx_periphclocks.c s32k1xx_pin.c -ifeq ($(CONFIG_S32K1XX_HAVE_LPUART),y) +ifeq ($(CONFIG_S32K1XX_LPUART),y) CHIP_CSRCS += s32k1xx_serial.c endif diff --git a/arch/arm/src/s32k1xx/hardware/s32k1xx_pcc.h b/arch/arm/src/s32k1xx/hardware/s32k1xx_pcc.h index b16410fa3c3..173267d72dc 100644 --- a/arch/arm/src/s32k1xx/hardware/s32k1xx_pcc.h +++ b/arch/arm/src/s32k1xx/hardware/s32k1xx_pcc.h @@ -142,7 +142,7 @@ /* PCC Register Bitfield Definitions ************************************************/ /* The form of each PCC register is the same as follows. Some register, however, do - * not support all of the files: + * not support all of the fields: * * PCD - ENET * FRAC - ENET @@ -158,6 +158,7 @@ #define PCC_FRAC (1 << 3) /* Bits 3: Peripheral Clock Divider Fraction */ #define PCC_PCS_SHIFT (24) /* Bits 24-26: Peripheral Clock Source Select */ #define PCC_PCS_MASK (7 << PCC_PCS_SHIFT) +# define PCC_PCS(n) ((uint32_t)(n) << PCC_PCS_SHIFT) # define PCC_PCS_OFF (0 << PCC_PCS_SHIFT) /* Clock is off */ # define PCC_PCS_OPTION1 (1 << PCC_PCS_SHIFT) /* Clock option 1 */ # define PCC_PCS_OPTION2 (2 << PCC_PCS_SHIFT) /* Clock option 2 */ diff --git a/arch/arm/src/s32k1xx/hardware/s32k1xx_sim.h b/arch/arm/src/s32k1xx/hardware/s32k1xx_sim.h index fb5de07f842..8a84d0900ec 100644 --- a/arch/arm/src/s32k1xx/hardware/s32k1xx_sim.h +++ b/arch/arm/src/s32k1xx/hardware/s32k1xx_sim.h @@ -95,6 +95,7 @@ # define SIM_CHIPCTL_ADC_INTERLEAVE_PTB0 (0 << SIM_CHIPCTL_ADC_INTERLEAVE_EN_SHIFT) #define SIM_CHIPCTL_CLKOUTSEL_SHIFT (4) /* Bits 4-7: CLKOUT Select */ #define SIM_CHIPCTL_CLKOUTSEL_MASK (15 << SIM_CHIPCTL_CLKOUTSEL_SHIFT) +# define SIM_CHIPCTL_CLKOUTSEL(n) ((uint32_t)(n) << SIM_CHIPCTL_CLKOUTSEL_SHIFT) # define SIM_CHIPCTL_CLKOUTSEL_SCGC_LKOUT (0 << SIM_CHIPCTL_CLKOUTSEL_SHIFT) # define SIM_CHIPCTL_CLKOUTSEL_SOSC_DIV2_CLK (2 << SIM_CHIPCTL_CLKOUTSEL_SHIFT) # define SIM_CHIPCTL_CLKOUTSEL_SIRC_DIV2_CLK (4 << SIM_CHIPCTL_CLKOUTSEL_SHIFT) @@ -181,12 +182,14 @@ #define SIM_LPOCLKS_LPO32KCLKEN (1 << 1) /* Bit 1: 32kHz LPO_CLK enable */ #define SIM_LPOCLKS_LPOCLKSEL_SHIFT (2) /* Bits 2-3: LPO clock source select */ #define SIM_LPOCLKS_LPOCLKSEL_MASK (3 << SIM_LPOCLKS_LPOCLKSEL_SHIFT) +# define SIM_LPOCLKS_LPOCLKSEL(n) ((uint32_t)(n) << SIM_LPOCLKS_LPOCLKSEL_SHIFT) # define SIM_LPOCLKS_LPOCLKSEL_128KHz_LPO_CLK (0 << SIM_LPOCLKS_LPOCLKSEL_SHIFT) /* 128kHz LPO_CLK */ # define SIM_LPOCLKS_LPOCLKSEL_NO_CLOCK (1 << SIM_LPOCLKS_LPOCLKSEL_SHIFT) /* No clock */ # define SIM_LPOCLKS_LPOCLKSEL_32KHz_LPO_CLK (2 << SIM_LPOCLKS_LPOCLKSEL_SHIFT) /* 32kHz LPO_CLK derived from 128 kHz LPO_CLK */ # define SIM_LPOCLKS_LPOCLKSEL_1KHz_LPO_CLK (3 << SIM_LPOCLKS_LPOCLKSEL_SHIFT) /* 1kHz LPO_CLK derived from 128 kHz LPO_CLK */ #define SIM_LPOCLKS_RTCCLKSEL_SHIFT (4) /* Bits 4-5: 32kHz clock source select */ #define SIM_LPOCLKS_RTCCLKSEL_MASK (3 << SIM_LPOCLKS_RTCCLKSEL_SHIFT) +# define SIM_LPOCLKS_RTCCLKSEL(n) ((uint32_t)(n) << SIM_LPOCLKS_RTCCLKSEL_SHIFT) # define SIM_LPOCLKS_RTCCLKSEL_SOSCDIV1_CLK (0 << SIM_LPOCLKS_RTCCLKSEL_SHIFT) /* SOSCDIV1_CLK */ # define SIM_LPOCLKS_RTCCLKSEL_32KHz_LPO_CLK (1 << SIM_LPOCLKS_RTCCLKSEL_SHIFT) /* 32KHz LPO_CLK */ # define SIM_LPOCLKS_RTCCLKSEL_32KHz_RTC_CLKIN (2 << SIM_LPOCLKS_RTCCLKSEL_SHIFT) /* 32KHz RTC_CLKIN clock */ diff --git a/arch/arm/src/s32k1xx/s32k11x/Make.defs b/arch/arm/src/s32k1xx/s32k11x/Make.defs index 0225755b717..fe7fedd740d 100644 --- a/arch/arm/src/s32k1xx/s32k11x/Make.defs +++ b/arch/arm/src/s32k1xx/s32k11x/Make.defs @@ -55,7 +55,7 @@ endif # Source file specific to the S32k11x family -CHIP_CSRCS += s32k11x_irq.c +CHIP_CSRCS += s32k11x_irq.c s32k11x_clockmapping.c # Configuration-dependent S32k11x files diff --git a/arch/arm/src/s32k1xx/s32k11x/s32k11x_clockmapping.c b/arch/arm/src/s32k1xx/s32k11x/s32k11x_clockmapping.c new file mode 100644 index 00000000000..e2651dbf2c4 --- /dev/null +++ b/arch/arm/src/s32k1xx/s32k11x/s32k11x_clockmapping.c @@ -0,0 +1,128 @@ +/**************************************************************************** + * arch/arm/src/s32k1xx/s32k11x/s32k11x_clockmapping.c + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "s32k1xx_periphclocks.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* Clock name mappings. + * + * Each S32K1xx architecture must provide this array. This is a constant + * array storing the mappings between clock names and peripheral clock + * control indexes. If there is no peripheral clock control index for a + * clock name, then the corresponding value is PCC_INVALID_INDEX. + */ + +const uint16_t g_clkname_mapping[] = +{ + PCC_INVALID_INDEX, /* Core clock 0 */ + PCC_INVALID_INDEX, /* Bus clock 1 */ + PCC_INVALID_INDEX, /* Slow clock 2 */ + PCC_INVALID_INDEX, /* CLKOUT clock 3 */ + PCC_INVALID_INDEX, /* SIRC clock 4 */ + PCC_INVALID_INDEX, /* FIRC clock 5 */ + PCC_INVALID_INDEX, /* SOSC clock 6 */ + PCC_INVALID_INDEX, /* No clock entry in clock_names_t 7 */ + PCC_INVALID_INDEX, /* RTC_CLKIN clock 8 */ + PCC_INVALID_INDEX, /* SCG CLK_OUT clock 9 */ + PCC_INVALID_INDEX, /* SIRCDIV1 functional clock 10 */ + PCC_INVALID_INDEX, /* SIRCDIV2 functional clock 11 */ + PCC_INVALID_INDEX, /* FIRCDIV1 functional clock 12 */ + PCC_INVALID_INDEX, /* FIRCDIV2 functional clock 13 */ + PCC_INVALID_INDEX, /* SOSCDIV1 functional clock 14 */ + PCC_INVALID_INDEX, /* SOSCDIV2 functional clock 15 */ + PCC_INVALID_INDEX, /* No clock entry in clock_names_t 16 */ + PCC_INVALID_INDEX, /* No clock entry in clock_names_t 17 */ + PCC_INVALID_INDEX, /* End of SCG clocks 18 */ + PCC_INVALID_INDEX, /* No clock entry in clock_names_t 19 */ + PCC_INVALID_INDEX, /* No clock entry in clock_names_t 20 */ + PCC_INVALID_INDEX, /* FTM0 External Clock Pin Select 21 */ + PCC_INVALID_INDEX, /* FTM1 External Clock Pin Select 22 */ + PCC_INVALID_INDEX, /* CLKOUT Select 23 */ + PCC_INVALID_INDEX, /* CLK32K clock 24 */ + PCC_INVALID_INDEX, /* LPO clock 25 */ + PCC_INVALID_INDEX, /* LPO 1KHz clock 26 */ + PCC_INVALID_INDEX, /* LPO 32KHz clock 27 */ + PCC_INVALID_INDEX, /* LPO 128KHz clock 28 */ + PCC_INVALID_INDEX, /* EIM clock source 29 */ + PCC_INVALID_INDEX, /* ERM clock source 30 */ + PCC_INVALID_INDEX, /* DMA clock source 31 */ + PCC_INVALID_INDEX, /* MPU clock source 32 */ + PCC_INVALID_INDEX, /* MSCM clock source 33 */ + PCC_INVALID_INDEX, /* No clock entry in clock_names_t 34 */ + PCC_INVALID_INDEX, /* No clock entry in clock_names_t 35 */ + PCC_INVALID_INDEX, /* No clock entry in clock_names_t 36 */ + PCC_INVALID_INDEX, /* No clock entry in clock_names_t 37 */ + PCC_INVALID_INDEX, /* No clock entry in clock_names_t 38 */ + PCC_INVALID_INDEX, /* No clock entry in clock_names_t 39 */ + PCC_INVALID_INDEX, /* No clock entry in clock_names_t 40 */ + PCC_CMP0_INDEX, /* CMP0 clock source 41 */ + PCC_CRC_INDEX, /* CRC clock source 42 */ + PCC_DMAMUX_INDEX, /* DMAMUX clock source 43 */ + PCC_PORTA_INDEX, /* PORTA clock source 44 */ + PCC_PORTB_INDEX, /* PORTB clock source 45 */ + PCC_PORTC_INDEX, /* PORTC clock source 46 */ + PCC_PORTD_INDEX, /* PORTD clock source 47 */ + PCC_PORTE_INDEX, /* PORTE clock source 48 */ + PCC_RTC_INDEX, /* RTC clock source 49 */ + PCC_INVALID_INDEX, /* End of BUS clocks 50 */ + PCC_FLEXCAN0_INDEX, /* FlexCAN0 clock source 51 */ + PCC_PDB0_INDEX, /* PDB0 clock source 52 */ + PCC_INVALID_INDEX, /* End of SYS clocks 53 */ + PCC_FTFC_INDEX, /* FTFC clock source 54 */ + PCC_INVALID_INDEX, /* End of SLOW clocks 55 */ + PCC_FTM0_INDEX, /* FTM0 clock source 56 */ + PCC_FTM1_INDEX, /* FTM1 clock source 57 */ + PCC_INVALID_INDEX, /* End of ASYNCH DIV1 clocks 58 */ + PCC_ADC0_INDEX, /* ADC0 clock source 59 */ + PCC_FLEXIO_INDEX, /* FlexIO clock source 60 */ + PCC_LPI2C0_INDEX, /* LPI2C0 clock source 61 */ + PCC_LPIT_INDEX, /* LPIT clock source 62 */ + PCC_LPSPI0_INDEX, /* LPSPI0 clock source 63 */ + PCC_LPSPI1_INDEX, /* LPSPI1 clock source 64 */ + PCC_LPTMR0_INDEX, /* LPTMR0 clock source 65 */ + PCC_LPUART0_INDEX, /* LPUART0 clock source 66 */ + PCC_LPUART1_INDEX, /* LPUART1 clock source 67 */ + PCC_INVALID_INDEX, /* End of ASYNCH DIV2 clocks 68 */ + PCC_INVALID_INDEX, /* End of PCC clocks 69 */ +}; diff --git a/arch/arm/src/s32k1xx/s32k14x/Make.defs b/arch/arm/src/s32k1xx/s32k14x/Make.defs index e8498cb26bb..7d1a3b06b56 100644 --- a/arch/arm/src/s32k1xx/s32k14x/Make.defs +++ b/arch/arm/src/s32k1xx/s32k14x/Make.defs @@ -75,7 +75,7 @@ endif # Source file specific to the S32k11x family CHIP_ASRCS = -CHIP_CSRCS = s32k14x_irq.c s32k14x_clrpend.c +CHIP_CSRCS = s32k14x_irq.c s32k14x_clrpend.c s32k14x_clockmapping.c # Configuration-dependent S32k14x files diff --git a/arch/arm/src/s32k1xx/s32k14x/s32k14x_clockmapping.c b/arch/arm/src/s32k1xx/s32k14x/s32k14x_clockmapping.c new file mode 100644 index 00000000000..30bc49aafe8 --- /dev/null +++ b/arch/arm/src/s32k1xx/s32k14x/s32k14x_clockmapping.c @@ -0,0 +1,128 @@ +/**************************************************************************** + * arch/arm/src/s32k1xx/s32k14x/s32k14x_clockmapping.c + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "s32k1xx_periphclocks.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* Clock name mappings. + * + * Each S32K1xx architecture must provide this array. This is a constant + * array storing the mappings between clock names and peripheral clock + * control indexes. If there is no peripheral clock control index for a + * clock name, then the corresponding value is PCC_INVALID_INDEX. + */ + +const uint16_t g_clkname_mapping[] = +{ + PCC_INVALID_INDEX, /* Core clock 0 */ + PCC_INVALID_INDEX, /* Bus clock 1 */ + PCC_INVALID_INDEX, /* Slow clock 2 */ + PCC_INVALID_INDEX, /* CLKOUT clock 3 */ + PCC_INVALID_INDEX, /* SIRC clock 4 */ + PCC_INVALID_INDEX, /* FIRC clock 5 */ + PCC_INVALID_INDEX, /* SOSC clock 6 */ + PCC_INVALID_INDEX, /* No clock entry in clock_names_t 7 */ + PCC_INVALID_INDEX, /* RTC_CLKIN clock 8 */ + PCC_INVALID_INDEX, /* SCG CLK_OUT clock 9 */ + PCC_INVALID_INDEX, /* SIRCDIV1 functional clock 10 */ + PCC_INVALID_INDEX, /* SIRCDIV2 functional clock 11 */ + PCC_INVALID_INDEX, /* FIRCDIV1 functional clock 12 */ + PCC_INVALID_INDEX, /* FIRCDIV2 functional clock 13 */ + PCC_INVALID_INDEX, /* SOSCDIV1 functional clock 14 */ + PCC_INVALID_INDEX, /* SOSCDIV2 functional clock 15 */ + PCC_INVALID_INDEX, /* No clock entry in clock_names_t 16 */ + PCC_INVALID_INDEX, /* No clock entry in clock_names_t 17 */ + PCC_INVALID_INDEX, /* End of SCG clocks 18 */ + PCC_INVALID_INDEX, /* No clock entry in clock_names_t 19 */ + PCC_INVALID_INDEX, /* No clock entry in clock_names_t 20 */ + PCC_INVALID_INDEX, /* FTM0 External Clock Pin Select 21 */ + PCC_INVALID_INDEX, /* FTM1 External Clock Pin Select 22 */ + PCC_INVALID_INDEX, /* CLKOUT Select 23 */ + PCC_INVALID_INDEX, /* CLK32K clock 24 */ + PCC_INVALID_INDEX, /* LPO clock 25 */ + PCC_INVALID_INDEX, /* LPO 1KHz clock 26 */ + PCC_INVALID_INDEX, /* LPO 32KHz clock 27 */ + PCC_INVALID_INDEX, /* LPO 128KHz clock 28 */ + PCC_INVALID_INDEX, /* EIM clock source 29 */ + PCC_INVALID_INDEX, /* ERM clock source 30 */ + PCC_INVALID_INDEX, /* DMA clock source 31 */ + PCC_INVALID_INDEX, /* MPU clock source 32 */ + PCC_INVALID_INDEX, /* MSCM clock source 33 */ + PCC_INVALID_INDEX, /* No clock entry in clock_names_t 34 */ + PCC_INVALID_INDEX, /* No clock entry in clock_names_t 35 */ + PCC_INVALID_INDEX, /* No clock entry in clock_names_t 36 */ + PCC_INVALID_INDEX, /* No clock entry in clock_names_t 37 */ + PCC_INVALID_INDEX, /* No clock entry in clock_names_t 38 */ + PCC_INVALID_INDEX, /* No clock entry in clock_names_t 39 */ + PCC_INVALID_INDEX, /* No clock entry in clock_names_t 40 */ + PCC_CMP0_INDEX, /* CMP0 clock source 41 */ + PCC_CRC_INDEX, /* CRC clock source 42 */ + PCC_DMAMUX_INDEX, /* DMAMUX clock source 43 */ + PCC_PORTA_INDEX, /* PORTA clock source 44 */ + PCC_PORTB_INDEX, /* PORTB clock source 45 */ + PCC_PORTC_INDEX, /* PORTC clock source 46 */ + PCC_PORTD_INDEX, /* PORTD clock source 47 */ + PCC_PORTE_INDEX, /* PORTE clock source 48 */ + PCC_RTC_INDEX, /* RTC clock source 49 */ + PCC_INVALID_INDEX, /* End of BUS clocks 50 */ + PCC_FLEXCAN0_INDEX, /* FlexCAN0 clock source 51 */ + PCC_PDB0_INDEX, /* PDB0 clock source 52 */ + PCC_INVALID_INDEX, /* End of SYS clocks 53 */ + PCC_FTFC_INDEX, /* FTFC clock source 54 */ + PCC_INVALID_INDEX, /* End of SLOW clocks 55 */ + PCC_FTM0_INDEX, /* FTM0 clock source 56 */ + PCC_FTM1_INDEX, /* FTM1 clock source 57 */ + PCC_INVALID_INDEX, /* End of ASYNCH DIV1 clocks 58 */ + PCC_ADC0_INDEX, /* ADC0 clock source 59 */ + PCC_FLEXIO_INDEX, /* FlexIO clock source 60 */ + PCC_LPI2C0_INDEX, /* LPI2C0 clock source 61 */ + PCC_LPIT_INDEX, /* LPIT clock source 62 */ + PCC_LPSPI0_INDEX, /* LPSPI0 clock source 63 */ + PCC_LPSPI1_INDEX, /* LPSPI1 clock source 64 */ + PCC_LPTMR0_INDEX, /* LPTMR0 clock source 65 */ + PCC_LPUART0_INDEX, /* LPUART0 clock source 66 */ + PCC_LPUART1_INDEX, /* LPUART1 clock source 67 */ + PCC_INVALID_INDEX, /* End of ASYNCH DIV2 clocks 68 */ + PCC_INVALID_INDEX, /* End of PCC clocks 69 */ +}; diff --git a/arch/arm/src/s32k1xx/s32k1xx_clockconfig.c b/arch/arm/src/s32k1xx/s32k1xx_clockconfig.c index b835bd18261..3aeabd7f8fc 100644 --- a/arch/arm/src/s32k1xx/s32k1xx_clockconfig.c +++ b/arch/arm/src/s32k1xx/s32k1xx_clockconfig.c @@ -69,7 +69,9 @@ #include "hardware/s32k1xx_scg.h" #include "hardware/s32k1xx_smc.h" +#include "hardware/s32k1xx_sim.h" #include "hardware/s32k1xx_pmc.h" +#include "s32k1xx_periphclocks.h" #include "s32k1xx_clockconfig.h" #include /* Include last. May have dependencies */ @@ -196,10 +198,14 @@ static const uint32_t g_hsrun_maxsysclks[MODES_MAX_NO][SYS_CLK_MAX_NO] = }; #endif -#if 0 /* Not used */ +#if 0 /* Not currently used */ static uint32_t g_rtc_clkin; /* RTC CLKIN clock */ #endif +#if 0 /* Not currently used */ +static uint32_t g_tclkfreq[NUMBER_OF_TCLK_INPUTS]; /* TCLKx clocks */ +#endif + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -1353,25 +1359,6 @@ static int s32k1xx_scg_config(const struct scg_config_s *scgcfg) return ret; } -/**************************************************************************** - * Name: s32k1xx_pcc_config - * - * Description: - * Configure PCC clocking. - * - * Input Parameters: - * pcccfg - Describes the new PCC clock configuration - * - * Returned Value: - * None. - * - *****************************************************************************/ - -static void s32k1xx_pcc_config(const struct pcc_config_s *pcccfg) -{ -#warning Missing logic -} - /**************************************************************************** * Name: s32k1xx_sim_config * @@ -1388,7 +1375,149 @@ static void s32k1xx_pcc_config(const struct pcc_config_s *pcccfg) static void s32k1xx_sim_config(const struct sim_clock_config_s *simcfg) { -#warning Missing logic + uint32_t regval; +#ifdef CONFIG_S32K1XX_HAVE_QSPI + int i; +#endif + + DEBUGASSERT(simcfg != NULL); + + /* ClockOut settings. */ + + if (simcfg->clockout.initialize) + { + regval = getreg32(S32K1XX_SIM_CHIPCTL); + regval &= ~(SIM_CHIPCTL_CLKOUTEN | SIM_CHIPCTL_CLKOUTDIV_MASK | + SIM_CHIPCTL_CLKOUTSEL_MASK); + + if (simcfg->clockout.enable) + { + regval |= SIM_CHIPCTL_CLKOUTEN; + } + + regval |= SIM_CHIPCTL_CLKOUTSEL(simcfg->clockout.source); + regval |= SIM_CHIPCTL_CLKOUTDIV(simcfg->clockout.divider); + putreg32(regval, S32K1XX_SIM_CHIPCTL); + } + + /* Low Power Clock settings from SIM. */ + + if (simcfg->lpoclk.initialize) + { + regval = getreg32(S32K1XX_SIM_LPOCLKS); + regval &= ~(SIM_LPOCLKS_LPO1KCLKEN | SIM_LPOCLKS_LPO32KCLKEN | + SIM_LPOCLKS_LPOCLKSEL_MASK | SIM_LPOCLKS_RTCCLKSEL_MASK); + + if (simcfg->lpoclk.lpo1k) + { + regval |= SIM_LPOCLKS_LPO1KCLKEN; + } + + if (simcfg->lpoclk.lpo32k) + { + regval |= SIM_LPOCLKS_LPO32KCLKEN; + } + + regval |= SIM_LPOCLKS_LPOCLKSEL(simcfg->lpoclk.lpo_source); + regval |= SIM_LPOCLKS_RTCCLKSEL(simcfg->lpoclk.rtc_source); + + putreg32(regval, S32K1XX_SIM_LPOCLKS); + } + + /* Platform Gate Clock settings. */ + + if (simcfg->platgate.initialize) + { + regval = getreg32(S32K1XX_SIM_PLATCGC); + regval &= ~(SIM_PLATCGC_CGCMSCM | SIM_PLATCGC_CGCMPU | + SIM_PLATCGC_CGCDMA | SIM_PLATCGC_CGCERM | + SIM_PLATCGC_CGCEIM); + + if (simcfg->platgate.mscm) + { + regval |= SIM_PLATCGC_CGCMSCM; + } + + if (simcfg->platgate.mpu) + { + regval |= SIM_PLATCGC_CGCMPU; + } + + if (simcfg->platgate.dma) + { + regval |= SIM_PLATCGC_CGCDMA; + } + + if (simcfg->platgate.erm) + { + regval |= SIM_PLATCGC_CGCERM; + } + + if (simcfg->platgate.eim) + { + regval |= SIM_PLATCGC_CGCEIM; + } + + putreg32(regval, S32K1XX_SIM_PLATCGC); + +#ifdef CONFIG_S32K1XX_HAVE_QSPI + regval = getreg32(S32K1XX_SIM_MISCTRL0); + regval &= ~SIM_MISCTRL0_QSPI_CLK_SEL; + + if (simcfg->qspirefclk.refclk) + { + regval |= SIM_MISCTRL0_QSPI_CLK_SEL; + } + + putreg32(regval, S32K1XX_SIM_MISCTRL0); +#endif + } + +#if 0 /* REVISIT: Not currently used */ + /* TCLK Clock settings. */ + + if (simcfg->tclk.initialize) + { + for (i = 0; i < NUMBER_OF_TCLK_INPUTS; i++) + { + g_tclkfreq[i] = simcfg->tclk.tclkfreq[i]; + } + } +#endif + + /* Debug trace Clock settings. */ + + if (simcfg->traceclk.initialize) + { + /* Disable divider. */ + + putreg32(0, S32K1XX_SIM_CLKDIV4); + + /* Configure trace source. */ + + regval = getreg32(S32K1XX_SIM_CHIPCTL); + regval &= ~SIM_CHIPCTL_TRACECLK_SEL; + + if (simcfg->traceclk.source) + { + regval |= SIM_CHIPCTL_TRACECLK_SEL; + } + + putreg32(regval, S32K1XX_SIM_CHIPCTL); + + if (simcfg->traceclk.enable) + { + regval = SIM_CLKDIV4_TRACEDIVEN | + SIM_CLKDIV4_TRACEDIV(simcfg->traceclk.divider); + + if (simcfg->traceclk.fraction) + { + regval |= SIM_CLKDIV4_TRACEFRAC; + } + + putreg32(regval, S32K1XX_SIM_CLKDIV4); + } + } } /**************************************************************************** @@ -1471,7 +1600,7 @@ int s32k1xx_clockconfig(const struct clock_configuration_s *clkcfg) { /* Set PCC configuration */ - s32k1xx_pcc_config(&clkcfg->pcc); + s32k1xx_periphclocks(clkcfg->pcc.count, clkcfg->pcc.pclks); /* Set SIM configuration */ diff --git a/arch/arm/src/s32k1xx/s32k1xx_clockconfig.h b/arch/arm/src/s32k1xx/s32k1xx_clockconfig.h index 085281bb85b..0a93761bf43 100644 --- a/arch/arm/src/s32k1xx/s32k1xx_clockconfig.h +++ b/arch/arm/src/s32k1xx/s32k1xx_clockconfig.h @@ -31,7 +31,7 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - * Some of the definitions within this file derives from NXP sample code for + * Some of the definitions within this file derive from NXP sample code for * the S32K1xx MCUs. That sample code has this licensing information: * * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. @@ -64,12 +64,6 @@ #include #include -#if defined(CONFIG_ARCH_CHIP_S32K11X) -# include "s32k14x/s32k14x_clocknames.h" -#elif defined(CONFIG_ARCH_CHIP_S32K14X) -# include "s32k14x/s32k14x_clocknames.h" -#endif - /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ @@ -82,24 +76,6 @@ #define NUMBER_OF_TCLK_INPUTS 3 -/* Values for peripheral_clock_source_t. An enumeration is not appropriate - * because some of the values are duplicates. - */ - -#define CLK_SRC_OFF 0 /* Clock is off */ -#define CLK_SRC_SOSC 1 /* OSCCLK - System Oscillator Bus Clock */ -#define CLK_SRC_SIRC 2 /* SCGIRCLK - Slow IRC Clock */ -#define CLK_SRC_FIRC 3 /* SCGFIRCLK - Fast IRC Clock */ -#define CLK_SRC_SPLL 6 /* SCGPCLK System PLL clock */ -#define CLK_SRC_SOSC_DIV1 1 /* OSCCLK - System Oscillator Bus Clock */ -#define CLK_SRC_SIRC_DIV1 2 /* SCGIRCLK - Slow IRC Clock */ -#define CLK_SRC_FIRC_DIV1 3 /* SCGFIRCLK - Fast IRC Clock */ -#define CLK_SRC_SPLL_DIV1 6 /* SCGPCLK System PLL clock */ -#define CLK_SRC_SOSC_DIV2 1 /* OSCCLK - System Oscillator Bus Clock */ -#define CLK_SRC_SIRC_DIV2 2 /* SCGIRCLK - Slow IRC Clock */ -#define CLK_SRC_FIRC_DIV2 3 /* SCGFIRCLK - Fast IRC Clock */ -#define CLK_SRC_SPLL_DIV2 6 /* SCGPCLK System PLL clock */ - /**************************************************************************** * Public Types ****************************************************************************/ @@ -415,18 +391,20 @@ enum clock_trace_src_e struct sim_trace_clock_config_s { enum clock_trace_src_e source; /* Trace clock select */ - uint8_t divider; /* Trace clock divider divisor */ + uint8_t divider; /* Trace clock divider divisor, range 1..8 */ bool initialize; /* true: Initialize the Trace clock */ bool enable; /* true: Enable Trace clock divider */ bool fraction; /* true: EnableTrace clock divider fraction */ }; +#ifdef CONFIG_S32K1XX_HAVE_QSPI /* SIM QSPI clock configuration */ struct sim_qspi_ref_clk_gating_s { bool refclk; /* true: Enable QSPI internal reference clock gating */ }; +#endif /* Overall SIM clock configuration */ @@ -437,48 +415,18 @@ struct sim_clock_config_s struct sim_tclk_config_s tclk; /* Platform Gate Clock configuration */ struct sim_plat_gate_config_s platgate; /* Platform Gate Clock configuration */ struct sim_trace_clock_config_s traceclk; /* Trace clock configuration */ +#ifdef CONFIG_S32K1XX_HAVE_QSPI struct sim_qspi_ref_clk_gating_s qspirefclk; /* Qspi Reference Clock Gating */ +#endif }; /* PCC clock configuration */ -typedef uint8_t peripheral_clock_source_t; /* See CLK_SRC_* definitions */ - -enum peripheral_clock_frac_e -{ - MULTIPLY_BY_ONE = 0, /* Fractional value is zero */ - MULTIPLY_BY_TWO = 1 /* Fractional value is one */ -}; - -enum peripheral_clock_divider_e -{ - DIVIDE_BY_ONE = 0, /* Divide by 1 (pass-through, no clock divide) */ - DIVIDE_BY_TWO = 1, /* Divide by 2 */ - DIVIDE_BY_THREE = 2, /* Divide by 3 */ - DIVIDE_BY_FOUR = 3, /* Divide by 4 */ - DIVIDE_BY_FIVE = 4, /* Divide by 5 */ - DIVIDE_BY_SIX = 5, /* Divide by 6 */ - DIVIDE_BY_SEVEN = 6, /* Divide by 7 */ - DIVIDE_BY_EIGTH = 7 /* Divide by 8 */ -}; - -struct peripheral_clock_config_s -{ - /* clkname is the name of the peripheral clock. It must be one of the values - * defined in the chip specific xxxxxx_configname.h header file. - */ - - enum clock_names_e clkname; /* Peripheral clock name */ - bool clkgate; /* Peripheral clock gate */ - peripheral_clock_source_t clksrc; /* Peripheral clock source */ - enum peripheral_clock_frac_e frac; /* Peripheral clock fractional value */ - enum peripheral_clock_divider_e divider; /* Peripheral clock divider value */ -}; - +struct peripheral_clock_config_s; /* Forward reference */ struct pcc_config_s { - uint32_t count; /* Number of peripherals to be configured */ - struct peripheral_clock_config_s *pclks; /* Pointer to the peripheral clock configurations array */ + unsigned int count; /* Number of peripherals to be configured */ + const struct peripheral_clock_config_s *pclks; /* The peripheral clock configuration array */ }; /* PMC clock configuration */ diff --git a/arch/arm/src/s32k1xx/s32k1xx_periphclocks.c b/arch/arm/src/s32k1xx/s32k1xx_periphclocks.c new file mode 100644 index 00000000000..08a275901d6 --- /dev/null +++ b/arch/arm/src/s32k1xx/s32k1xx_periphclocks.c @@ -0,0 +1,212 @@ +/**************************************************************************** + * arch/arm/src/s32k1xx/s32k1xx_periphclocks.c + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Much of the logic within this file derives from NXP sample code for + * the S32K1xx MCUs. That sample code has this licensing information: + * + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2018 NXP + * All rights reserved. + * + * THIS SOFTWARE IS PROVIDED BY NXP "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL NXP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include "up_arch.h" +#include "hardware/s32k1xx_pcc.h" +#include "s32k1xx_periphclocks.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: s32k1xx_get_pclkctrl + * + * Description: + * Given a clock name, this functions returns the address the the PCC + * control register for the peripheral. + * + * Input Parameters: + * clkname - The name of the peripheral clock. + * + * Returned Value: + * Address of peripheral control register. NULL is returned if the clock + * name does not map to a PCC control register. + * + ****************************************************************************/ + +static uint32_t *s32k1xx_get_pclkctrl(enum clock_names_e clkname) +{ + /* Map the clock name to an index to the corresponding PCC control register. */ + + uintptr_t index = (uintptr_t)g_clkname_mapping[clkname]; + + if (index != PCC_INVALID_INDEX) + { + /* Return the fall address of the PCC control register */ + + return (uint32_t *)((uintptr_t)S32K1XX_PCC_BASE + (index << 2)); + } + + return NULL; +} + +/**************************************************************************** + * Name: s32k1xx_pclk_disable + * + * Description: + * This function enables/disables the clock for a given peripheral. + * + * Input Parameters: + * clkname - The name of the peripheral clock to be disabled + * enable - true: Enable the peripheral clock. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void s32k1xx_pclk_disable(enum clock_names_e clkname) +{ + uint32_t *ctrlp = s32k1xx_get_pclkctrl(clkname); + DEBUGASSERT(ctrlp != NULL); + + *ctrlp &= ~PCC_CGC; +} + +/**************************************************************************** + * Name: s32k1xx_set_pclkctrl + * + * Description: + * Sets PCC control register. + * + * Input Parameters: + * pclk - Describes the PCLK configuration. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void s32k1xx_set_pclkctrl(struct peripheral_clock_config_s *pclk) +{ + uint32_t *ctrlp = s32k1xx_get_pclkctrl(pclk->clkname); + uint32_t regval; + + DEBUGASSERT(ctrlp != NULL); + + /* Configure the peripheral clock source, the fractional clock divider + * and the clock gate. + */ + + regval = PCC_PCS(pclk->clksrc) | PCC_PCD( pclk->divider); + + if (pclk->frac == MULTIPLY_BY_TWO) + { + regval |= PCC_FRAC; + } + + if (pclk->clkgate) + { + regval |= PCC_CGC; + } + + *ctrlp = regval; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: s32k1xx_periphclocks + * + * Description: + * This function configures peripheral clocks in the PCC block. + * + * Input Parameters: + * count - Number of peripheral clocks to be configured + * pclks - Pointer to an array of peripheral clock configurations + * + * Returned Value: + * None + * + ****************************************************************************/ + +void s32k1xx_periphclocks(unsigned int count, + struct peripheral_clock_config_s *pclks) +{ + unsigned int i; + + DEBUGASSERT(pclks != NULL); + + for (i = 0; i < count; i++, pclks++) + { + /* Disable the peripheral clock */ + + s32k1xx_pclk_disable(pclks->clkname); + + /* Set peripheral clock control */ + + s32k1xx_set_pclkctrl(pclks); + } +} diff --git a/arch/arm/src/s32k1xx/s32k1xx_periphclocks.h b/arch/arm/src/s32k1xx/s32k1xx_periphclocks.h new file mode 100644 index 00000000000..989d55d5337 --- /dev/null +++ b/arch/arm/src/s32k1xx/s32k1xx_periphclocks.h @@ -0,0 +1,244 @@ +/**************************************************************************** + * arch/arm/src/s32k1xx/s32k1xx_preriphclocks.h + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Some of the definitions within this file derive from NXP sample code for + * the S32K1xx MCUs. That sample code has this licensing information: + * + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2018 NXP + * All rights reserved. + * + * THIS SOFTWARE IS PROVIDED BY NXP "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL NXP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_S32K1XX_S32K1XX_PERIPHCLOCKS_H +#define __ARCH_ARM_SRC_S32K1XX_S32K1XX_PERIPHCLOCKS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "s32k1xx_config.h" + +#if defined(CONFIG_ARCH_CHIP_S32K11X) +# include "s32k14x/s32k14x_clocknames.h" +#elif defined(CONFIG_ARCH_CHIP_S32K14X) +# include "s32k14x/s32k14x_clocknames.h" +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Values for peripheral_clock_source_t. An enumeration is not appropriate + * because some of the values are duplicates. + */ + +#define CLK_SRC_OFF 0 /* Clock is off */ +#define CLK_SRC_SOSC 1 /* OSCCLK - System Oscillator Bus Clock */ +#define CLK_SRC_SIRC 2 /* SCGIRCLK - Slow IRC Clock */ +#define CLK_SRC_FIRC 3 /* SCGFIRCLK - Fast IRC Clock */ +#define CLK_SRC_SPLL 6 /* SCGPCLK System PLL clock */ +#define CLK_SRC_SOSC_DIV1 1 /* OSCCLK - System Oscillator Bus Clock */ +#define CLK_SRC_SIRC_DIV1 2 /* SCGIRCLK - Slow IRC Clock */ +#define CLK_SRC_FIRC_DIV1 3 /* SCGFIRCLK - Fast IRC Clock */ +#define CLK_SRC_SPLL_DIV1 6 /* SCGPCLK System PLL clock */ +#define CLK_SRC_SOSC_DIV2 1 /* OSCCLK - System Oscillator Bus Clock */ +#define CLK_SRC_SIRC_DIV2 2 /* SCGIRCLK - Slow IRC Clock */ +#define CLK_SRC_FIRC_DIV2 3 /* SCGFIRCLK - Fast IRC Clock */ +#define CLK_SRC_SPLL_DIV2 6 /* SCGPCLK System PLL clock */ + +/* PCC index offsets (all S32K1xx families). These are used in in the + * family-specific mapping table g_clkname_mapping[] that is used to map a + * clock name to a PCC control register index. + */ + +#define PCC_INVALID_INDEX 0 + +#define PCC_FTFC_INDEX 32 +#define PCC_DMAMUX_INDEX 33 +#define PCC_FLEXCAN0_INDEX 36 +#define PCC_FLEXCAN1_INDEX 37 +#define PCC_FTM3_INDEX 38 +#define PCC_ADC1_INDEX 39 +#define PCC_FLEXCAN2_INDEX 43 +#define PCC_LPSPI0_INDEX 44 +#define PCC_LPSPI1_INDEX 45 +#define PCC_LPSPI2_INDEX 46 +#define PCC_PDB1_INDEX 49 +#define PCC_CRC_INDEX 50 +#define PCC_PDB0_INDEX 54 +#define PCC_LPIT_INDEX 55 +#define PCC_FTM0_INDEX 56 +#define PCC_FTM1_INDEX 57 +#define PCC_FTM2_INDEX 58 +#define PCC_ADC0_INDEX 59 +#define PCC_RTC_INDEX 61 +#define PCC_CMU0_INDEX 62 +#define PCC_CMU1_INDEX 63 +#define PCC_LPTMR0_INDEX 64 +#define PCC_PORTA_INDEX 73 +#define PCC_PORTB_INDEX 74 +#define PCC_PORTC_INDEX 75 +#define PCC_PORTD_INDEX 76 +#define PCC_PORTE_INDEX 77 +#define PCC_SAI0_INDEX 84 +#define PCC_SAI1_INDEX 85 +#define PCC_FLEXIO_INDEX 90 +#define PCC_EWM_INDEX 97 +#define PCC_LPI2C0_INDEX 102 +#define PCC_LPI2C1_INDEX 103 +#define PCC_LPUART0_INDEX 106 +#define PCC_LPUART1_INDEX 107 +#define PCC_LPUART2_INDEX 108 +#define PCC_FTM4_INDEX 110 +#define PCC_FTM5_INDEX 111 +#define PCC_FTM6_INDEX 112 +#define PCC_FTM7_INDEX 113 +#define PCC_CMP0_INDEX 115 +#define PCC_QSPI_INDEX 118 +#define PCC_ENET_INDEX 121 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +typedef uint8_t peripheral_clock_source_t; /* See CLK_SRC_* definitions */ + +enum peripheral_clock_frac_e +{ + MULTIPLY_BY_ONE = 0, /* Fractional value is zero */ + MULTIPLY_BY_TWO = 1 /* Fractional value is one */ +}; + +enum peripheral_clock_divider_e +{ + DIVIDE_BY_ONE = 0, /* Divide by 1 (pass-through, no clock divide) */ + DIVIDE_BY_TWO = 1, /* Divide by 2 */ + DIVIDE_BY_THREE = 2, /* Divide by 3 */ + DIVIDE_BY_FOUR = 3, /* Divide by 4 */ + DIVIDE_BY_FIVE = 4, /* Divide by 5 */ + DIVIDE_BY_SIX = 5, /* Divide by 6 */ + DIVIDE_BY_SEVEN = 6, /* Divide by 7 */ + DIVIDE_BY_EIGTH = 7 /* Divide by 8 */ +}; + +struct peripheral_clock_config_s +{ + /* clkname is the name of the peripheral clock. It must be one of the values + * defined in the chip specific xxxxxx_configname.h header file. + */ + + enum clock_names_e clkname; /* Peripheral clock name */ + bool clkgate; /* Peripheral clock gate */ + peripheral_clock_source_t clksrc; /* Peripheral clock source */ + enum peripheral_clock_frac_e frac; /* Peripheral clock fractional value */ + enum peripheral_clock_divider_e divider; /* Peripheral clock divider value */ +}; + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* Clock name mappings. + * + * Each S32K1xx architecture must provide this array. This is a constant + * array storing the mappings between clock names and peripheral clock + * control indexes. If there is no peripheral clock control index for a + * clock name, then the corresponding value is PCC_INVALID_INDEX. + */ + +EXTERN const uint16_t g_clkname_mapping[]; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: s32k1xx_periphclocks + * + * Description: + * This function configures peripheral clocks in the PCC block. + * + * Input Parameters: + * count - Number of peripheral clocks to be configured + * pclks - Pointer to an array of peripheral clock configurations + * + * Returned Value: + * None + * + ****************************************************************************/ + +void s32k1xx_periphclocks(unsigned int count, + struct peripheral_clock_config_s *pclks); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_S32K1XX_S32K1XX_PERIPHCLOCKS_H */ diff --git a/boards/arm/s32k1xx/s32k118evb/src/Makefile b/boards/arm/s32k1xx/s32k118evb/src/Makefile index a8ca7202d12..ef53d27691a 100644 --- a/boards/arm/s32k1xx/s32k118evb/src/Makefile +++ b/boards/arm/s32k1xx/s32k118evb/src/Makefile @@ -35,8 +35,9 @@ -include $(TOPDIR)/Make.defs -ASRCS = -CSRCS = s32k118_boot.c s32k118_bringup.c s32k118_clockconfig.c +ASRCS = +CSRCS = s32k118_boot.c s32k118_bringup.c s32k118_clockconfig.c +CSRCS += s32k118_periphclocks.c ifeq ($(CONFIG_ARCH_LEDS),y) CSRCS += s32k118_autoleds.c diff --git a/boards/arm/s32k1xx/s32k118evb/src/s32k118_clockconfig.c b/boards/arm/s32k1xx/s32k118evb/src/s32k118_clockconfig.c index 20279ef3198..32583cd2484 100644 --- a/boards/arm/s32k1xx/s32k118evb/src/s32k118_clockconfig.c +++ b/boards/arm/s32k1xx/s32k118evb/src/s32k118_clockconfig.c @@ -65,22 +65,10 @@ #include "s32k1xx_start.h" #include "s32k118evb.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/* Count of peripheral clock user configurations */ - -#define NUM_OF_PERIPHERAL_CLOCKS_0 10U - /**************************************************************************** * Public Data ****************************************************************************/ -/* User peripheral configuration structure 0 */ - -extern struct peripheral_clock_config_s g_peripheral_clockconfig0[]; - /* Each S32K1xx board must provide the following initialized structure. This is * needed to establish the initial board clocking. */ @@ -190,15 +178,17 @@ const struct clock_configuration_s g_initial_clkconfig = .traceclk = /* Debug trace Clock Configuration. */ { .source = CLOCK_TRACE_SRC_CORE_CLK, /* TRACECLK_SEL */ - .divider = 0, /* TRACEDIV */ + .divider = 1, /* TRACEDIV, range 1..8 */ .initialize = true, /* Initialize */ .enable = true, /* TRACEDIVEN */ .fraction = false, /* TRACEFRAC */ }, +#ifdef CONFIG_S32K1XX_HAVE_QSPI .qspirefclk = /* Quad Spi Internal Reference Clock Gating. */ { .refclk = false, /* Qspi reference clock gating */ }, +#endif }, .pcc = { diff --git a/boards/arm/s32k1xx/s32k118evb/src/s32k118_periphclocks.c b/boards/arm/s32k1xx/s32k118evb/src/s32k118_periphclocks.c new file mode 100644 index 00000000000..1e576c01d0e --- /dev/null +++ b/boards/arm/s32k1xx/s32k118evb/src/s32k118_periphclocks.c @@ -0,0 +1,152 @@ +/**************************************************************************** + * boards/arm/s32k1xx/s32k118evb/src/s32k118_periphclks.c + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Most of the settings within this file derives from NXP sample code for + * the S32K118 MCUs. That sample code has this licensing information: + * + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2018 NXP + * All rights reserved. + * + * THIS SOFTWARE IS PROVIDED BY NXP "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL NXP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "s32k1xx_periphclocks.h" +#include "s32k118evb.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* Each S32K1xx board must provide the following initialized structure. This is + * needed to establish the initial peripheral clocking. + */ + +const struct peripheral_clock_config_s g_peripheral_clockconfig0[] = +{ + { + .clkname = ADC0_CLK, + .clkgate = true, + .clksrc = CLK_SRC_SIRC_DIV2, + .frac = MULTIPLY_BY_ONE, + .divider = DIVIDE_BY_ONE, + }, + { + .clkname = DMAMUX0_CLK, + .clkgate = true, + .clksrc = CLK_SRC_OFF, + .frac = MULTIPLY_BY_ONE, + .divider = DIVIDE_BY_ONE, + }, + { + .clkname = LPTMR0_CLK, + .clkgate = true, + .clksrc = CLK_SRC_SIRC_DIV2, + .frac = MULTIPLY_BY_ONE, + .divider = DIVIDE_BY_ONE, + }, + { + .clkname = LPUART0_CLK, + .clkgate = true, + .clksrc = CLK_SRC_SIRC_DIV2, + .frac = MULTIPLY_BY_ONE, + .divider = DIVIDE_BY_ONE, + }, + { + .clkname = LPUART1_CLK, + .clkgate = true, + .clksrc = CLK_SRC_SIRC_DIV2, + .frac = MULTIPLY_BY_ONE, + .divider = DIVIDE_BY_ONE, + }, + { + .clkname = PORTA_CLK, + .clkgate = true, + .clksrc = CLK_SRC_OFF, + .frac = MULTIPLY_BY_ONE, + .divider = DIVIDE_BY_ONE, + }, + { + .clkname = PORTB_CLK, + .clkgate = true, + .clksrc = CLK_SRC_OFF, + .frac = MULTIPLY_BY_ONE, + .divider = DIVIDE_BY_ONE, + }, + { + .clkname = PORTC_CLK, + .clkgate = true, + .clksrc = CLK_SRC_OFF, + .frac = MULTIPLY_BY_ONE, + .divider = DIVIDE_BY_ONE, + }, + { + .clkname = PORTD_CLK, + .clkgate = true, + .clksrc = CLK_SRC_OFF, + .frac = MULTIPLY_BY_ONE, + .divider = DIVIDE_BY_ONE, + }, + { + .clkname = PORTE_CLK, + .clkgate = true, + .clksrc = CLK_SRC_OFF, + .frac = MULTIPLY_BY_ONE, + .divider = DIVIDE_BY_ONE, + }, +}; diff --git a/boards/arm/s32k1xx/s32k118evb/src/s32k118evb.h b/boards/arm/s32k1xx/s32k118evb/src/s32k118evb.h index 021a6f483b8..28df4547526 100644 --- a/boards/arm/s32k1xx/s32k118evb/src/s32k118evb.h +++ b/boards/arm/s32k1xx/s32k118evb/src/s32k118evb.h @@ -42,8 +42,11 @@ #include #include + #include +#include "s32k1xx_periphclocks.h" + /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ @@ -64,6 +67,10 @@ /* SPI chip selects */ +/* Count of peripheral clock user configurations */ + +#define NUM_OF_PERIPHERAL_CLOCKS_0 10U + /**************************************************************************** * Public Types ****************************************************************************/ @@ -74,6 +81,10 @@ #ifndef __ASSEMBLY__ +/* User peripheral configuration structure 0 */ + +extern const struct peripheral_clock_config_s g_peripheral_clockconfig0[]; + /**************************************************************************** * Public Functions ****************************************************************************/