From ae79a4af9f58addc8084fec3891b9852f77d5c98 Mon Sep 17 00:00:00 2001 From: Ian Morris Date: Sat, 30 Mar 2024 15:08:13 -0700 Subject: [PATCH] soc: renesas: ra: configure option settings memory An area of flash memory on the RA4M1 MCU is used to store information used to configure the device following a reset. This patch instructs the linker to reserve this memory area and provides kconfig options that are used to populate it (at build time) with the desired device configuration. Signed-off-by: Ian Morris --- soc/renesas/ra/ra2a1/CMakeLists.txt | 9 ++ soc/renesas/ra/ra2a1/Kconfig | 23 +++++ soc/renesas/ra/ra2a1/opt_set_mem.ld | 11 +++ soc/renesas/ra/ra2a1/soc.c | 148 ++++++++++++++++++++++++++++ 4 files changed, 191 insertions(+) create mode 100644 soc/renesas/ra/ra2a1/opt_set_mem.ld create mode 100644 soc/renesas/ra/ra2a1/soc.c diff --git a/soc/renesas/ra/ra2a1/CMakeLists.txt b/soc/renesas/ra/ra2a1/CMakeLists.txt index 78cb8a9e0136d15..3d373798683fc12 100644 --- a/soc/renesas/ra/ra2a1/CMakeLists.txt +++ b/soc/renesas/ra/ra2a1/CMakeLists.txt @@ -3,4 +3,13 @@ zephyr_include_directories(.) +zephyr_library_sources_ifdef(CONFIG_OPTION_SETTING_MEMORY + soc.c +) + +zephyr_linker_sources_ifdef(CONFIG_OPTION_SETTING_MEMORY + ROM_START + ${CMAKE_CURRENT_SOURCE_DIR}/opt_set_mem.ld +) + set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra2a1/Kconfig b/soc/renesas/ra/ra2a1/Kconfig index e81f5531fa5fb86..949cf5b995419ba 100644 --- a/soc/renesas/ra/ra2a1/Kconfig +++ b/soc/renesas/ra/ra2a1/Kconfig @@ -10,3 +10,26 @@ config SOC_SERIES_RA2A1 select DYNAMIC_INTERRUPTS select TIMER_READS_ITS_FREQUENCY_AT_RUNTIME select XIP + +config SOC_OPTION_SETTING_MEMORY + bool "Option Setting Memory" + default y + +config SOC_OPTION_SETTING_LVDAS_DISABLE + bool "Disable voltage monitor 0 after reset" + default y + depends on SOC_OPTION_SETTING_MEMORY + +config SOC_OPTION_SETTING_HOCO_DISABLE + bool "Disable HOCO oscillator after reset" + depends on SOC_OPTION_SETTING_MEMORY + +config SOC_OPTION_SETTING_HOCO_FREQ + int "HOCO oscillator frequency" + default 48000000 + depends on SOC_OPTION_SETTING_MEMORY + +config SOC_OPTION_SETTING_VDSEL + int "Voltage Detection 0 Level Select" + default 1900 + depends on SOC_OPTION_SETTING_MEMORY diff --git a/soc/renesas/ra/ra2a1/opt_set_mem.ld b/soc/renesas/ra/ra2a1/opt_set_mem.ld new file mode 100644 index 000000000000000..c05238789af716b --- /dev/null +++ b/soc/renesas/ra/ra2a1/opt_set_mem.ld @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2024 Ian Morris + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +. = 0x400; +FILL(0xFF) +KEEP(*(.opt_set_mem*)) +. = 0x500; diff --git a/soc/renesas/ra/ra2a1/soc.c b/soc/renesas/ra/ra2a1/soc.c new file mode 100644 index 000000000000000..b1425bb1f3e6693 --- /dev/null +++ b/soc/renesas/ra/ra2a1/soc.c @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2024 Ian Morris + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include + +#if MHZ(24) == CONFIG_SOC_OPTION_SETTING_HOCO_FREQ +#define OFS1_HOCO_FREQ 0 +#elif MHZ(32) == CONFIG_SOC_OPTION_SETTING_HOCO_FREQ +#define OFS1_HOCO_FREQ 2 +#elif MHZ(48) == CONFIG_SOC_OPTION_SETTING_HOCO_FREQ +#define OFS1_HOCO_FREQ 4 +#elif MHZ(64) == CONFIG_SOC_OPTION_SETTING_HOCO_FREQ +#define OFS1_HOCO_FREQ 5 +#else +#error "Unsupported HOCO frequency" +#endif + +#if 3840 == CONFIG_SOC_OPTION_SETTING_VDSEL +#define OFS1_VDSEL 0 +#elif 2820 == CONFIG_SOC_OPTION_SETTING_VDSEL +#define OFS1_VDSEL 1 +#elif 2510 == CONFIG_SOC_OPTION_SETTING_VDSEL +#define OFS1_VDSEL 2 +#elif 1900 == CONFIG_SOC_OPTION_SETTING_VDSEL +#define OFS1_VDSEL 3 +#elif 1700 == CONFIG_SOC_OPTION_SETTING_VDSEL +#define OFS1_VDSEL 4 +#else +#error "Unsupported voltage detection level" +#endif + +struct ofs0_reg { + uint32_t RSVD1: 1; + uint32_t IWDTSTRT: 1; + uint32_t IWDTTOPS: 2; + uint32_t IWDTCKS: 4; + uint32_t IWDTRPES: 2; + uint32_t IWDTRPSS: 2; + uint32_t IWDTRSTIRQS: 1; + uint32_t RSVD2: 1; + uint32_t IWDTSTPCTL: 1; + uint32_t RSVD3: 2; + uint32_t WDTSTRT: 1; + uint32_t WDTTOPS: 2; + uint32_t WDTCKS: 4; + uint32_t WDTRPES: 2; + uint32_t WDTRPSS: 2; + uint32_t WDTRSTIRQS: 1; + uint32_t RSVD4: 1; + uint32_t WDTSTPCTL: 1; + uint32_t RSVD5: 1; +}; + +struct ofs1_reg { + uint32_t RSVD1: 2; + uint32_t LVDAS: 1; + uint32_t VDSEL1: 3; + uint32_t RSVD2: 2; + uint32_t HOCOEN: 1; + uint32_t RSVD3: 3; + uint32_t HOCOFRQ1: 3; + uint32_t RSVD4: 17; +}; + +struct mpu_regs { + uint32_t SECMPUPCSO; + uint32_t SECMPUPCEO; + uint32_t SECMPUPCS1; + uint32_t SECMPUPCE1; + uint32_t SECMPUS0; + uint32_t SECMPUE0; + uint32_t SECMPUS1; + uint32_t SECMPUE1; + uint32_t SECMPUS2; + uint32_t SECMPUE2; + uint32_t SECMPUS3; + uint32_t SECMPUE3; + uint32_t SECMPUAC; +}; + +struct opt_set_mem { + struct ofs0_reg ofs0; + struct ofs1_reg ofs1; + struct mpu_regs mpu; +}; + +#ifdef CONFIG_SOC_OPTION_SETTING_MEMORY +const struct opt_set_mem ops __attribute__((section(".opt_set_mem"))) = { + .ofs0 = { + /* + * Initial settings for watchdog timers. Set all fields to 1, + * disabling watchdog functionality as config options have not + * yet been implemented. + */ + .RSVD1 = 0x1, + .IWDTSTRT = 0x1, + .IWDTTOPS = 0x3, + .IWDTCKS = 0xf, + .IWDTRPES = 0x3, + .IWDTRPSS = 0x3, + .IWDTRSTIRQS = 0x1, + .RSVD2 = 0x1, + .IWDTSTPCTL = 0x1, + .RSVD3 = 0x3, + .WDTSTRT = 0x1, + .WDTTOPS = 0x3, + .WDTCKS = 0xf, + .WDTRPES = 0x3, + .WDTRPSS = 0x3, + .WDTRSTIRQS = 0x1, + .RSVD4 = 0x1, + .WDTSTPCTL = 0x1, + .RSVD5 = 0x1, + }, + .ofs1 = { + .RSVD1 = 0x3, + .LVDAS = IS_ENABLED(CONFIG_SOC_OPTION_SETTING_LVDAS_DISABLE), + .VDSEL1 = OFS1_VDSEL, + .RSVD2 = 0x3, + .HOCOEN = IS_ENABLED(CONFIG_SOC_OPTION_SETTING_HOCO_DISABLE), + .RSVD3 = 0x7, + .HOCOFRQ1 = OFS1_HOCO_FREQ, + .RSVD4 = 0x1ffff, + }, + .mpu = { + /* + * Initial settings for MPU. Set all areas to maximum values + * essentially disabling MPU functionality as config options + * have not yet been implemented. + */ + .SECMPUPCSO = 0x00fffffc, + .SECMPUPCEO = 0x00ffffff, + .SECMPUPCS1 = 0x00fffffc, + .SECMPUPCE1 = 0x00ffffff, + .SECMPUS0 = 0x00fffffc, + .SECMPUE0 = 0x00ffffff, + .SECMPUS1 = 0x200ffffc, + .SECMPUE1 = 0x200fffff, + .SECMPUS2 = 0x407ffffc, + .SECMPUE2 = 0x407fffff, + .SECMPUS3 = 0x40dffffc, + .SECMPUE3 = 0x40dfffff, + .SECMPUAC = 0xffffffff, + } +}; +#endif