soc: arm: ambiq: apollo510: Add support for Apollo510 SoC

Add all required parts (new SoC family/series, device tree) for
the Ambiq Apollo510 SoC.

Signed-off-by: Hao Luo <hluo@ambiq.com>
This commit is contained in:
Hao Luo 2025-02-11 17:22:40 +08:00 committed by Benjamin Cabé
commit c188125165
13 changed files with 580 additions and 2 deletions

View file

@ -0,0 +1,276 @@
/* Copyright (c) 2025 Ambiq Micro Inc. */
/* SPDX-License-Identifier: Apache-2.0 */
#include <arm/armv8.1-m.dtsi>
#include <mem.h>
#include <freq.h>
#include <apollo510/am_apollo510.h>
#include <zephyr/dt-bindings/memory-attr/memory-attr-arm.h>
#include <zephyr/dt-bindings/adc/adc.h>
#include <zephyr/dt-bindings/i2c/i2c.h>
#include <zephyr/dt-bindings/gpio/gpio.h>
/ {
clocks {
uartclk: apb-pclk {
compatible = "fixed-clock";
clock-frequency = <DT_FREQ_M(24)>;
#clock-cells = <0>;
};
xo32m_xtal: xo32m_xtal {
compatible = "fixed-clock";
clock-frequency = <DT_FREQ_M(32)>;
#clock-cells = <0>;
};
xo32m_ext: xo32m_ext {
compatible = "fixed-clock";
clock-frequency = <DT_FREQ_M(32)>;
#clock-cells = <0>;
};
xo32k_xtal: xo32k_xtal {
compatible = "fixed-clock";
clock-frequency = <32768>;
#clock-cells = <0>;
};
xo32k_ext: xo32k_ext {
compatible = "fixed-clock";
clock-frequency = <32768>;
#clock-cells = <0>;
};
extrefclk: extrefclk {
compatible = "fixed-clock";
clock-frequency = <0>;
#clock-cells = <0>;
};
};
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu0: cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-m55";
reg = <0>;
#address-cells = <1>;
#size-cells = <1>;
cpu-power-states = <&idle &suspend_to_ram>;
itm: itm@e0000000 {
compatible = "arm,armv8m-itm";
reg = <0xe0000000 0x1000>;
swo-ref-frequency = <DT_FREQ_M(48)>;
};
mpu: mpu@e000ed90 {
compatible = "arm,armv8m.1-mpu";
reg = <0xe000ed90 0x40>;
};
};
power-states {
idle: idle {
compatible = "zephyr,power-state";
power-state-name = "suspend-to-idle";
min-residency-us = <2000>;
exit-latency-us = <5>;
};
suspend_to_ram: suspend_to_ram {
compatible = "zephyr,power-state";
power-state-name = "suspend-to-ram";
min-residency-us = <5000>;
exit-latency-us = <125>;
};
};
};
/* MRAM region */
flash0: flash@MRAM_BASE_NAME {
compatible = "soc-nv-flash";
reg = <MRAM_BASE_ADDR MRAM_MAX_SIZE>;
};
/* TCM */
itcm: itcm@ITCM_BASE_NAME {
compatible = "zephyr,memory-region";
reg = <ITCM_BASE_ADDR ITCM_MAX_SIZE>;
zephyr,memory-region = "ITCM";
};
dtcm: dtcm@DTCM_BASE_NAME {
compatible = "zephyr,memory-region";
reg = <DTCM_BASE_ADDR DTCM_MAX_SIZE>;
zephyr,memory-region = "DTCM";
};
/* SRAM */
sram: memory@SSRAM_BASE_NAME {
compatible = "mmio-sram";
reg = <SSRAM_BASE_ADDR SSRAM_MAX_SIZE>;
};
soc {
compatible = "ambiq,apollo510", "ambiq,apollo5x", "simple-bus";
pwrcfg: pwrcfg@PWRCTRL_BASE_NAME {
compatible = "ambiq,pwrctrl";
reg = <PWRCTRL_REG_BASE PWRCTRL_REG_SIZE>;
#pwrcfg-cells = <2>;
};
stimer0: stimer@STIMER_BASE_NAME {
compatible = "ambiq,stimer";
reg = <STIMER_REG_BASE STIMER_REG_SIZE>;
interrupts = <32 0>;
status = "okay";
};
wdt0: watchdog@WDT_BASE_NAME {
compatible = "ambiq,watchdog";
reg = <WDT_REG_BASE WDT_REG_SIZE>;
interrupts = <1 0>;
clock-frequency = <16>;
status = "disabled";
};
uart0: uart@UART0_BASE_NAME {
compatible = "ambiq,uart", "arm,pl011";
reg = <UART0_REG_BASE UART0_REG_SIZE>;
interrupts = <15 0>;
interrupt-names = "UART0";
status = "disabled";
clocks = <&uartclk>;
ambiq,pwrcfg = <&pwrcfg 0x4 0x200>;
};
uart1: uart@UART1_BASE_NAME {
compatible = "ambiq,uart", "arm,pl011";
reg = <UART1_REG_BASE UART1_REG_SIZE>;
interrupts = <16 0>;
interrupt-names = "UART1";
status = "disabled";
clocks = <&uartclk>;
ambiq,pwrcfg = <&pwrcfg 0x4 0x400>;
};
uart2: uart@UART2_BASE_NAME {
compatible = "ambiq,uart", "arm,pl011";
reg = <UART2_REG_BASE UART2_REG_SIZE>;
interrupts = <17 0>;
interrupt-names = "UART2";
status = "disabled";
clocks = <&uartclk>;
ambiq,pwrcfg = <&pwrcfg 0x4 0x800>;
};
uart3: uart@UART3_BASE_NAME {
compatible = "ambiq,uart", "arm,pl011";
reg = <UART3_REG_BASE UART3_REG_SIZE>;
interrupts = <18 0>;
interrupt-names = "UART3";
status = "disabled";
clocks = <&uartclk>;
ambiq,pwrcfg = <&pwrcfg 0x4 0x1000>;
};
pinctrl: pin-controller@GPIO_BASE_NAME {
compatible = "ambiq,apollo5-pinctrl";
reg = <GPIO_REG_BASE GPIO_REG_SIZE>;
#address-cells = <1>;
#size-cells = <0>;
gpio: gpio@GPIO_BASE_NAME {
compatible = "ambiq,gpio";
gpio-map-mask = <0xffffffe0 0xffffffc0>;
gpio-map-pass-thru = <0x1f 0x3f>;
gpio-map = <
0x00 0x0 &gpio0_31 0x0 0x0
0x20 0x0 &gpio32_63 0x0 0x0
0x40 0x0 &gpio64_95 0x0 0x0
0x60 0x0 &gpio96_127 0x0 0x0
0x80 0x0 &gpio128_159 0x0 0x0
0xA0 0x0 &gpio160_191 0x0 0x0
0xC0 0x0 &gpio192_223 0x0 0x0
>;
reg = <GPIO_REG_BASE>;
#gpio-cells = <2>;
#address-cells = <1>;
#size-cells = <0>;
ranges;
gpio0_31: gpio0_31@0 {
compatible = "ambiq,gpio-bank";
gpio-controller;
#gpio-cells = <2>;
reg = <0>;
interrupts = <56 0>;
status = "disabled";
};
gpio32_63: gpio32_63@80 {
compatible = "ambiq,gpio-bank";
gpio-controller;
#gpio-cells = <2>;
reg = <0x80>;
interrupts = <57 0>;
status = "disabled";
};
gpio64_95: gpio64_95@100 {
compatible = "ambiq,gpio-bank";
gpio-controller;
#gpio-cells = <2>;
reg = <0x100>;
interrupts = <58 0>;
status = "disabled";
};
gpio96_127: gpio96_127@180 {
compatible = "ambiq,gpio-bank";
gpio-controller;
#gpio-cells = <2>;
reg = <0x180>;
interrupts = <59 0>;
status = "disabled";
};
gpio128_159: gpio128_159@200 {
compatible = "ambiq,gpio-bank";
gpio-controller;
#gpio-cells = <2>;
reg = <0x200>;
interrupts = <60 0>;
status = "disabled";
};
gpio160_191: gpio160_191@280 {
compatible = "ambiq,gpio-bank";
gpio-controller;
#gpio-cells = <2>;
reg = <0x280>;
interrupts = <61 0>;
status = "disabled";
};
gpio192_223: gpio192_223@300 {
compatible = "ambiq,gpio-bank";
gpio-controller;
#gpio-cells = <2>;
reg = <0x300>;
interrupts = <62 0>;
status = "disabled";
};
};
};
};
};
&nvic {
arm,num-irq-priority-bits = <4>;
};

View file

@ -5,7 +5,7 @@
config AMBIQ_HAL
bool "Ambiq HAL drivers support"
depends on SOC_SERIES_APOLLO3X || SOC_SERIES_APOLLO4X
depends on SOC_SERIES_APOLLO3X || SOC_SERIES_APOLLO4X || SOC_SERIES_APOLLO5X
help
Use the Ambiq HAL

View file

@ -0,0 +1,11 @@
# Copyright (c) 2025 Ambiq Micro Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
zephyr_sources(soc.c)
zephyr_include_directories(.)
zephyr_sources_ifdef(CONFIG_PM power.c)
zephyr_include_directories(${ZEPHYR_BASE}/soc/arm/common/cortex_m)
set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "")

View file

@ -0,0 +1,21 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (c) 2025 Ambiq Micro Inc.
config SOC_SERIES_APOLLO5X
select ARM
select CPU_CORTEX_M55
select CPU_CORTEX_M_HAS_DWT
select CPU_CORTEX_M_HAS_VTOR
select CPU_HAS_ARM_SAU
select CPU_HAS_ARM_MPU
select CPU_HAS_FPU
select ARMV8_M_DSP
select ARMV8_1_M_MVEI
select ARMV8_1_M_MVEF
select ARMV8_1_M_PMU
select HAS_SWO
select AMBIQ_HAL
select HAS_PM
select SOC_EARLY_INIT_HOOK
select REQUIRES_FULL_LIBC

View file

@ -0,0 +1,21 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (c) 2025 Ambiq Micro Inc.
if SOC_SERIES_APOLLO5X
rsource "Kconfig.defconfig.apollo5*"
config CACHE_MANAGEMENT
default y
config AMBIQ_CACHEABLE_DMA_BUFFER_ALIGNMENT
int
default DCACHE_LINE_SIZE
# Need to enlarge the IDLE stack size because the power
# management operations are executed in the idle task
config IDLE_STACK_SIZE
default 2048 if PM
endif # SOC_SERIES_APOLLO5X

View file

@ -0,0 +1,10 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (c) 2025 Ambiq Micro Inc.
if SOC_APOLLO510
config NUM_IRQS
default 134
endif # SOC_APOLLO510

View file

@ -0,0 +1,23 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (c) 2025 Ambiq Micro Inc.
config SOC_SERIES_APOLLO5X
bool
select SOC_FAMILY_AMBIQ
help
Apollo5 Series MCU
config SOC_APOLLO510
bool
select SOC_SERIES_APOLLO5X
config ARMV8_1_M_PMU_EVENTCNT
int
default 8
config SOC_SERIES
default "apollo5x" if SOC_SERIES_APOLLO5X
config SOC
default "apollo510" if SOC_APOLLO510

View file

@ -0,0 +1,87 @@
/*
* Copyright (c) 2025 Ambiq Micro Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_SOC_ARM_AMBIQ_APOLLO5_PINCTRL_SOC_H_
#define ZEPHYR_SOC_ARM_AMBIQ_APOLLO5_PINCTRL_SOC_H_
#include <zephyr/dt-bindings/pinctrl/ambiq-apollo5-pinctrl.h>
/**
* @brief Type to hold a pin's pinctrl configuration.
*/
struct apollo5_pinctrl_soc_pin {
/** Pin number 0..223 */
uint64_t pin_num: 8;
/** Alternative function (UART, SPI, etc.) */
uint64_t alt_func: 4;
/** Enable the pin as an input */
uint64_t input_enable: 1;
/** Drive strength, relative to full-driver strength */
uint64_t drive_strength: 3;
/** Drive actively high or low */
uint64_t push_pull: 1;
/** Drive with open drain */
uint64_t open_drain: 1;
/** High impedance mode */
uint64_t tristate: 1;
/** Enable the internal pull up resistor */
uint64_t bias_pull_up: 1;
/** Enable the internal pull down resistor */
uint64_t bias_pull_down: 1;
/** pullup resistor value */
uint64_t ambiq_pull_up_ohms: 3;
/** nCE module select */
uint64_t nce: 6;
/** nCE module polarity */
uint64_t nce_pol: 1;
/** SDIF CD WP pad select */
uint64_t sdif_cdwp: 3;
};
typedef struct apollo5_pinctrl_soc_pin pinctrl_soc_pin_t;
/**
* @brief Utility macro to initialize each pin.
*
* @param node_id Node identifier.
* @param prop Property name.
* @param idx Property entry index.
*/
#define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) \
{ \
APOLLO5_GET_PIN_NUM(DT_PROP_BY_IDX(node_id, prop, idx)), \
APOLLO5_GET_PIN_ALT_FUNC(DT_PROP_BY_IDX(node_id, prop, idx)), \
DT_PROP(node_id, input_enable), \
DT_ENUM_IDX(node_id, drive_strength), \
DT_PROP(node_id, drive_push_pull), \
DT_PROP(node_id, drive_open_drain), \
DT_PROP(node_id, bias_high_impedance), \
DT_PROP(node_id, bias_pull_up), \
DT_PROP(node_id, bias_pull_down), \
DT_ENUM_IDX(node_id, ambiq_pull_up_ohms), \
DT_PROP(node_id, ambiq_nce_src), \
DT_PROP(node_id, ambiq_nce_pol), \
DT_PROP(node_id, ambiq_sdif_cdwp), \
},
/**
* @brief Utility macro to initialize state pins contained in a given property.
*
* @param node_id Node identifier.
* @param prop Property name describing state pins.
*/
#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \
{DT_FOREACH_CHILD_VARGS(DT_PHANDLE(node_id, prop), \
DT_FOREACH_PROP_ELEM, pinmux, \
Z_PINCTRL_STATE_PIN_INIT)}
#define APOLLO5_GET_PIN_NUM(pinctrl) \
(((pinctrl) >> APOLLO5_PIN_NUM_POS) & APOLLO5_PIN_NUM_MASK)
#define APOLLO5_GET_PIN_ALT_FUNC(pinctrl) \
(((pinctrl) >> APOLLO5_ALT_FUNC_POS) & APOLLO5_ALT_FUNC_MASK)
#endif /* ZEPHYR_SOC_ARM_AMBIQ_APOLLO5_PINCTRL_SOC_H_ */

View file

@ -0,0 +1,67 @@
/*
* Copyright (c) 2025 Ambiq LLC
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <soc.h>
#include <zephyr/drivers/interrupt_controller/gic.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/pm/pm.h>
#include <zephyr/init.h>
LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL);
void pm_state_set(enum pm_state state, uint8_t substate_id)
{
ARG_UNUSED(substate_id);
__disable_irq();
__set_BASEPRI(0);
switch (state) {
case PM_STATE_SUSPEND_TO_IDLE: {
/* Put ARM core to normal sleep. */
am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_NORMAL);
break;
}
case PM_STATE_SUSPEND_TO_RAM: {
/* Put ARM core to deep sleep. */
/* Cotex-m: power down, register value preserve.*/
/* Cache: power down*/
/* MRAM: power down*/
/* ITCM + DTCM: retention, active on request*/
/* Sram: retention, active on request*/
am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP);
break;
}
default: {
LOG_DBG("Unsupported power state %u", state);
break;
}
}
}
/**
* @brief PM State Exit Post Operations
*
* For PM_STATE_SUSPEND_TO_IDLE:
* Nothing is needed after soc woken up.
*
* For PM_STATE_SUSPEND_TO_RAM:
* Flash, cache, sram automatically switch
* to active state on wake up
*
* @param state PM State
* @param substate_id Unused
*
*/
void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id)
{
ARG_UNUSED(substate_id);
__enable_irq();
irq_unlock(0);
}

47
soc/ambiq/apollo5x/soc.c Normal file
View file

@ -0,0 +1,47 @@
/*
* Copyright (c) 2025 Ambiq Micro Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/init.h>
#include <zephyr/cache.h>
#include "soc.h"
#define SCRATCH0_OEM_RCV_RETRY_MAGIC 0xA86
void soc_early_init_hook(void)
{
/* Enable Loop and branch info cache */
SCB->CCR |= SCB_CCR_LOB_Msk;
__DSB();
__ISB();
if ((MCUCTRL->SCRATCH0 >> 20) == SCRATCH0_OEM_RCV_RETRY_MAGIC) {
/*
* Clear the scratch register
*/
MCUCTRL->SCRATCH0 = 0x00;
}
/* Internal timer15 for SPOT manager */
IRQ_CONNECT(82, 0, hal_internal_timer_isr, 0, 0);
/* Initialize for low power in the power control block */
am_hal_pwrctrl_low_power_init();
/* Enable SIMOBUCK for the apollo5 Family */
am_hal_pwrctrl_control(AM_HAL_PWRCTRL_CONTROL_SIMOBUCK_INIT, NULL);
/*
* Set default temperature for spotmgr to room temperature
*/
am_hal_pwrctrl_temp_thresh_t dummy[32];
am_hal_pwrctrl_temp_update(25.0f, dummy);
/* Enable Icache*/
sys_cache_instr_enable();
/* Enable Dcache */
sys_cache_data_enable();
}

12
soc/ambiq/apollo5x/soc.h Normal file
View file

@ -0,0 +1,12 @@
/*
* Copyright (c) 2025 Ambiq Micro Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __SOC_H__
#define __SOC_H__
#include <am_mcu_apollo.h>
#endif /* __SOC_H__ */

View file

@ -9,3 +9,6 @@ family:
socs:
- name: apollo3_blue
- name: apollo3p_blue
- name: apollo5x
socs:
- name: apollo510

View file

@ -152,7 +152,7 @@ manifest:
groups:
- hal
- name: hal_ambiq
revision: a6dff0a5f49e898f29bc428e01538a8911364460
revision: e916e84a103e13ce8bcf8b7f53dafbe57ed0b846
path: modules/hal/ambiq
groups:
- hal