Skip to content
Permalink
Browse files

soc : arm : microchip_mec Add Microchip MEC1501 SoC

Initial support for Microchip MEC1501 series is added to the tree.
Additional support for UART is also included. This SoC supports
two operational modes for interrupts (Direct and Aggregated). For
this commit, the direct capable interrupt are configured in direct
mode.

Signed-off-by: Scott Worley <scott.worley@microchip.com>
  • Loading branch information...
scottwcpg authored and andrewboie committed Apr 1, 2019
1 parent a0a9a1f commit 37df2566580b7ea177a0b3a8aa21e527cb44ff3b
@@ -0,0 +1,9 @@
#
# Copyright (c) 2019, Microchip Technology Inc.
#
# SPDX-License-Identifier: Apache-2.0
#

zephyr_sources(
soc.c
)
@@ -0,0 +1,25 @@
# Kconfig - Microchip MEC1501HSZ MCU
#
# Copyright (c) 2018 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#

if SOC_MEC1501_HSZ

config SOC
string
default "mec1501hsz"

config SYS_CLOCK_HW_CYCLES_PER_SEC
int
default 48000000

if SERIAL

config UART_NS16550
def_bool y

endif # SERIAL

endif # SOC_MEC1501_HSZ
@@ -0,0 +1,22 @@
# Kconfig - Microchip MEC MCU series configuration options
#
# Copyright (c) 2018 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#

if SOC_SERIES_MEC1501X

config SOC_SERIES
string
default "mec1501"

config NUM_IRQS
int
# must be >= the highest interrupt number used
# - include the UART interrupts
# All NVIC external sources.
default 174

source "soc/arm/microchip_mec/mec1501/Kconfig.defconfig.mec1501*"
endif # SOC_SERIES_MEC1501X
@@ -0,0 +1,15 @@
# Kconfig - Microchip MEC1501 MCU core series
#
# Copyright (c) 2018 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#

config SOC_SERIES_MEC1501X
bool "Microchip MEC1501X Series"
select CPU_CORTEX_M
select CPU_CORTEX_M4
select SOC_FAMILY_MEC
select CPU_CORTEX_M_HAS_SYSTICK
help
Enable support for Microchip MEC Cortex-M4 MCU series
@@ -0,0 +1,65 @@
# Kconfig - Microchip MEC1501 MCU core series

#
# Copyright (c) 2018 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#

choice
prompt "MEC1501 Selection"
depends on SOC_SERIES_MEC1501X

config SOC_MEC1501_HSZ
bool "MEC1501_HSZ"
select HAS_MEC_HAL

endchoice

config SOC_MEC1501_PROC_CLK_DIV
int "PROC_CLK_DIV"
default 1
range 1 48
help
This divisor defines a ratio between processor clock (HCLK)
and master clock (MCK):
HCLK = MCK / PROC_CLK_DIV
Allowed divider values: 1, 3, 4, 16, and 48.

config SOC_MEC1501_EXT_32K
bool "Use external 32KHz clock source"
default n
help
Use an external 32768 Hz clock source for PLL reference
clock.

Say y if you want to use an external source for the PLL
32KHz reference clock.

Say n to use the +/-2% internal silicon oscillator.

config SOC_MEC1501_EXT_32K_CRYSTAL
bool "External 32KHz is a crystal"
depends on SOC_MEC1501_EXT_32K
default y
help
Choose a crystal as the external 32KHz source.

Say y if you wish to use a crystal as the external
32KHz clock source.

Saying n will select the 32KHZ_IN pin as the external
32KHz clock source.

config SOC_MEC1501_EXT_32K_PARALLEL_CRYSTAL
bool "Use parallel connected 32KHz crystal"
depends on SOC_MEC1501_EXT_32K_CRYSTAL
default y
help
Choose external 32KHz crystal connection.

Say y if the crystal is connected parallel between
the XTAL1 and XTAL pins.

Say n if the crystal is connected single ended to
the XTAL2 pin or a 32KHz square wave is on XTAL2.
@@ -0,0 +1,46 @@
/*
* Copyright (c) 2019 Microchip Technology Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/

/* This file is a temporary workaround for mapping of the generated information
* to the current driver definitions. This will be removed when the drivers
* are modified to handle the generated information, or the mapping of
* generated data matches the driver definitions.
*/


#define DT_NUM_IRQ_PRIO_BITS \
DT_ARM_V7M_NVIC_E000E100_ARM_NUM_IRQ_PRIORITY_BITS
#define DT_NS16550_REG_SHIFT \
DT_NS16550_400F2400_REG_SHIFT
#define DT_UART_NS16550_PORT_0_BASE_ADDR \
DT_NS16550_400F2400_BASE_ADDRESS
#define DT_UART_NS16550_PORT_0_CLK_FREQ 1843200
#define DT_UART_NS16550_PORT_0_NAME DT_NS16550_400F2400_LABEL
#define DT_UART_NS16550_PORT_0_BAUD_RATE \
DT_NS16550_400F2400_CURRENT_SPEED
#define DT_UART_NS16550_PORT_0_IRQ DT_NS16550_400F2400_IRQ_0
#define DT_UART_NS16550_PORT_0_IRQ_PRI DT_NS16550_0_IRQ_0_PRIORITY
#define DT_UART_NS16550_PORT_0_IRQ_FLAGS 0 /* Deault */

#define DT_UART_NS16550_PORT_1_BASE_ADDR \
DT_NS16550_400F2800_BASE_ADDRESS
#define DT_UART_NS16550_PORT_1_CLK_FREQ 1843200
#define DT_UART_NS16550_PORT_1_NAME DT_NS16550_400F2800_LABEL
#define DT_UART_NS16550_PORT_1_BAUD_RATE \
DT_NS16550_400F2800_CURRENT_SPEED
#define DT_UART_NS16550_PORT_1_IRQ DT_NS16550_400F2800_IRQ_0
#define DT_UART_NS16550_PORT_1_IRQ_PRI DT_NS16550_1_IRQ_0_PRIORITY
#define DT_UART_NS16550_PORT_1_IRQ_FLAGS 0 /* Default */

#define DT_UART_NS16550_PORT_2_BASE_ADDR \
DT_NS16550_400F2C00_BASE_ADDRESS
#define DT_UART_NS16550_PORT_2_CLK_FREQ 1843200
#define DT_UART_NS16550_PORT_2_NAME DT_NS16550_400F2C00_LABEL
#define DT_UART_NS16550_PORT_2_BAUD_RATE \
DT_NS16550_400F2C00_CURRENT_SPEED
#define DT_UART_NS16550_PORT_2_IRQ DT_NS16550_400F2C00_IRQ_0
#define DT_UART_NS16550_PORT_2_IRQ_PRI DT_NS16550_2_IRQ_0_PRIORITY
#define DT_UART_NS16550_PORT_2_IRQ_FLAGS 0 /* Default */
@@ -0,0 +1,9 @@
/* linker.ld - Linker command/script file */

/*
* Copyright (c) 2014 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <arch/arm/cortex_m/scripts/linker.ld>
@@ -0,0 +1,163 @@
/*
* Copyright (c) 2019 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <device.h>
#include <init.h>
#include <soc.h>
#include <kernel.h>
#include <arch/cpu.h>
#include <cortex_m/exc.h>


/*
* Make sure PCR sleep enables are clear except for crypto
* which do not have internal clock gating.
*/
static int soc_pcr_init(void)
{
PCR_REGS->SLP_EN0 = 0;
PCR_REGS->SLP_EN1 = 0;
PCR_REGS->SLP_EN2 = 0;
PCR_REGS->SLP_EN4 = 0;
PCR_REGS->SLP_EN3 = MCHP_PCR3_CRYPTO_MASK;

return 0;
}

/*
* Select 32KHz clock source used for PLL reference.
* Options are:
* Internal 32KHz silicon oscillator.
* External parallel resonant crystal between XTAL1 and XTAL2 pins.
* External single ended crystal connected to XTAL2 pin.
* External 32KHz square wave from Host chipset/board on 32KHZ_IN pin.
* NOTES:
* PLL can take up to 3 ms to lock. Before lock the PLL output
* will be ramping up from ~20MHz.
* 32KHZ_IN pin must be configured for 32KHZ_IN function.
* Crystals vary and may take longer time to stabilize this will
* affect PLL lock time.
* Crystal do not like to be power cycled. If using a crystal
* the board should supply a battery backed (VBAT) power rail.
* The VBAT clock control register selecting 32KHz source is
* connected to the VBAT power rail. If using a battery one can
* check the VBAT Power Fail and Reset Status register for a VBAT POR.
*/
static void clk32_change(u8_t new_clk32)
{
new_clk32 &= MCHP_VBATR_CLKEN_MASK;

if ((VBATR_REGS->CLK32_EN & MCHP_VBATR_CLKEN_MASK)
== (u32_t)new_clk32) {
return;
}

if (new_clk32 == MCHP_VBATR_USE_SIL_OSC) {
VBATR_REGS->CLK32_EN = new_clk32;
} else {
/* 1. switch to internal oscillator */
VBATR_REGS->CLK32_EN = MCHP_VBATR_USE_SIL_OSC;
/* 2. delay for PLL */
while ((PCR_REGS->OSC_ID & MCHP_PCR_OSC_ID_PLL_LOCK) == 0)
;
/* 3. switch to desired source */
VBATR_REGS->CLK32_EN = new_clk32;
}
}

static int soc_clk32_init(void)
{
u8_t new_clk32;

#ifdef CONFIG_SOC_MEC1501_EXT_32K
#ifdef CONFIG_SOC_MEC1501_EXT_32K_CRYSTAL
#ifdef CONFIG_SOC_MEC1501_EXT_32K_PARALLEL_CRYSTAL
new_clk32 = MCHP_VBATR_USE_PAR_CRYSTAL;
#else
new_clk32 = MCHP_VBATR_USE_SE_CRYSTAL;
#endif
#else
/* Use 32KHZ_PIN as 32KHz source */
new_clk32 = MCHP_VBATR_USE_32KIN_PIN;
#endif
#else
/* Use internal 32KHz +/-2% silicon oscillator */
new_clk32 = MCHP_VBATR_USE_SIL_OSC;
#endif
clk32_change(new_clk32);

return 0;
}

/*
* Initialize MEC1501 EC Interrupt Aggregator (ECIA) and external NVIC
* inputs.
*/
static int soc_ecia_init(void)
{
GIRQ_Type *pg;
u32_t n;

mchp_pcr_periph_slp_ctrl(PCR_ECIA, MCHP_PCR_SLEEP_DIS);

ECS_REGS->INTR_CTRL |= MCHP_ECS_ICTRL_DIRECT_EN;

/* gate off all aggregated outputs */
ECIA_REGS->BLK_EN_CLR = 0xFFFFFFFFul;
/* gate on GIRQ's that are aggregated only */
ECIA_REGS->BLK_EN_SET = MCHP_ECIA_AGGR_BITMAP;

/* Clear all GIRQn source enables and source status */
pg = &ECIA_REGS->GIRQ08;
for (n = 0u; n < MCHP_GIRQ_ZID_MAX; n++) {
pg->EN_CLR = 0xFFFFFFFFul;
pg->SRC = 0xFFFFFFFFul;
pg++;
}

/* Clear all external NVIC enables and pending status */
for (n = 0u; n < MCHP_NUM_NVIC_REGS; n++) {
NVIC->ICER[n] = 0xFFFFFFFFul;
NVIC->ICPR[n] = 0xFFFFFFFFul;
}

return 0;
}

static int soc_init(struct device *dev)
{
u32_t isave;

ARG_UNUSED(dev);

isave = __get_PRIMASK();
__disable_irq();

z_clearfaults();

soc_pcr_init();

soc_clk32_init();

/*
* On HW reset PCR Processor Clock Divider = 4 for 48/4 = 12 MHz.
* Set clock divider = 1 for maximum speed.
* NOTE1: This clock divider affects all Cortex-M4 core clocks.
* If you change it you must repogram SYSTICK to maintain the
* same absolute time interval.
*/
PCR_REGS->PROC_CLK_CTRL = CONFIG_SOC_MEC1501_PROC_CLK_DIV;

soc_ecia_init();

if (!isave) {
__enable_irq();
}

return 0;
}

SYS_INIT(soc_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
@@ -0,0 +1,20 @@
/*
* Copyright (c) 2019 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef __MEC_SOC_H
#define __MEC_SOC_H

#define SYSCLK_DEFAULT_IOSC_HZ MHZ(48)

#ifndef _ASMLANGUAGE

#include "MEC1501hsz.h"
#include "regaccess.h"


#endif

#endif

0 comments on commit 37df256

Please sign in to comment.
You can’t perform that action at this time.