diff --git a/soc/realtek/ec/CMakeLists.txt b/soc/realtek/ec/CMakeLists.txt new file mode 100644 index 00000000000..9953afd14f4 --- /dev/null +++ b/soc/realtek/ec/CMakeLists.txt @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 +# + +add_subdirectory(${SOC_SERIES}) +add_subdirectory(common) diff --git a/soc/realtek/ec/Kconfig b/soc/realtek/ec/Kconfig new file mode 100644 index 00000000000..a759cb44c37 --- /dev/null +++ b/soc/realtek/ec/Kconfig @@ -0,0 +1,34 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 +# + +if SOC_FAMILY_REALTEK_EC + +menuconfig REALTEK_RTS5912_BOOTROM_HEADER + bool "Create BOOTROM header for RTS5912" + help + The RTS5912 BOOTROM needs the information about boot up progress. + Invoke the 'rts5912_imgtool' to generates the RTS5912 bootrom header. + +if REALTEK_RTS5912_BOOTROM_HEADER + +config REALTEK_HEADER_CHIP + string + default "RTS5912" if SOC_RTS5912 + +DT_CHOSEN_Z_FLASH := zephyr,flash +FLASH_BASE := $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_FLASH)) + +config REALTEK_RTS5912_BOOTROM_HEADER_LOAD_ADDRESS + string "Set the address for BOOTROM" + default "$(FLASH_BASE) - 0x20" + help + This address will be used by the RTS5912 BOOTROM to decide where firmware image start. + +endif # REALTEK_RTS5912_BOOTROM_HEADER + +# Select SoC Part No. and configuration options +rsource "*/Kconfig" + +endif # SOC_FAMILY_REALTEK_EC diff --git a/soc/realtek/ec/Kconfig.defconfig b/soc/realtek/ec/Kconfig.defconfig new file mode 100644 index 00000000000..effe686675a --- /dev/null +++ b/soc/realtek/ec/Kconfig.defconfig @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 +# + +if SOC_FAMILY_REALTEK_EC + +rsource "*/Kconfig.defconfig.series" + +endif # SOC_FAMILY_REALTEK_EC diff --git a/soc/realtek/ec/Kconfig.soc b/soc/realtek/ec/Kconfig.soc new file mode 100644 index 00000000000..fd19689cb07 --- /dev/null +++ b/soc/realtek/ec/Kconfig.soc @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 +# + +config SOC_FAMILY_REALTEK_EC + bool + +config SOC_FAMILY + string + default "realtek_ec" if SOC_FAMILY_REALTEK_EC + +rsource "*/Kconfig.soc" diff --git a/soc/realtek/ec/common/CMakeLists.txt b/soc/realtek/ec/common/CMakeLists.txt new file mode 100644 index 00000000000..de4a266ee39 --- /dev/null +++ b/soc/realtek/ec/common/CMakeLists.txt @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 +# + +zephyr_include_directories(.) + +if (DEFINED CONFIG_REALTEK_RTS5912_BOOTROM_HEADER) + math(EXPR adjustment "${CONFIG_REALTEK_RTS5912_BOOTROM_HEADER_LOAD_ADDRESS}" OUTPUT_FORMAT DECIMAL) + set(RTS5912_BIN_NAME ${CONFIG_KERNEL_BIN_NAME}.rts5912.bin) + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/soc/realtek/ec/common/rts5912_imgtool/img_gen.py + -L ${adjustment} + -I ${KERNEL_BIN_NAME} + -O ${RTS5912_BIN_NAME} + -V + ) +endif() diff --git a/soc/realtek/ec/common/rts5912_imgtool/img_gen.py b/soc/realtek/ec/common/rts5912_imgtool/img_gen.py new file mode 100644 index 00000000000..53fcefb916e --- /dev/null +++ b/soc/realtek/ec/common/rts5912_imgtool/img_gen.py @@ -0,0 +1,161 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 +# Author: Dylan Hsieh + +""" +The RTS5912 specific image header shows the bootROM how to +load the image from flash to internal SRAM, this script obtains +the header to original BIN and output a new BIN file. +""" + +import argparse +import os +import struct + +IMAGE_MAGIC = 0x524C544B # ASCII 'RLTK' +IMAGE_HDR_SIZE = 32 +RAM_LOAD = 0x0000020 +FREQ_50M = 0 +FREQ_25M = 1 +FREQ_12P5M = 2 +FREQ_6P25M = 3 +NORMAL_read = "0x03" +DUAL_read = "0x3B" +QUAD_read = "0x6B" + + +def parse_args(): + """ + Parsing the arguments + """ + parser = argparse.ArgumentParser(allow_abbrev=False) + + parser.add_argument( + "-L", + "--load-addr", + type=int, + dest="load_addr", + help="Load address for image when it should run from RAM.", + ) + + parser.add_argument( + "-I", + "--input", + type=str, + dest="original_bin", + default="zephyr.bin", + help="Input bin file path", + ) + + parser.add_argument( + "-O", + "--output", + type=str, + dest="signed_bin", + default="zephyr.rts5912.bin", + help="Output bin file path", + ) + + parser.add_argument( + "-F", + "--spi-freq", + type=int, + dest="spi_freq", + choices=[FREQ_50M, FREQ_25M, FREQ_12P5M, FREQ_6P25M], + default=FREQ_6P25M, + help="Specify the frequency of SPI I/F.", + ) + + parser.add_argument( + "-R", + "--spi-rdcmd", + type=str, + dest="spi_rdcmd", + choices=[NORMAL_read, DUAL_read, QUAD_read], + default=NORMAL_read, + help="Specify the command for flash read.", + ) + + parser.add_argument("-V", "--verbose", action="count", default=0, help="Verbose Output") + + ret_args = parser.parse_args() + return ret_args + + +def img_gen(load_addr, spi_freq, spi_rdcmd, original_bin, signed_bin): + """ + To obtain the RTS5912 image header and output a new BIN file + """ + img_size = os.path.getsize(original_bin) + payload = bytearray(0) + img_size = os.path.getsize(original_bin) + + fmt = ( + "<" + + + # type ImageHdr struct { + "I" # Magic uint32 + + "I" # LoadAddr uint32 + + "H" # HdrSz uint16 + + "H" # reserved uint16 + + "I" # ImgSz uint32 + + "I" # Flags uint32 + + "I" # reserved uint32 + + "I" # reserved uint32 + + "B" # SpiFmt uint8 + + "B" # SpiRdCmd uint8 + + "H" # reserved uint16 + ) # } + + header = struct.pack( + fmt, + IMAGE_MAGIC, + load_addr, + IMAGE_HDR_SIZE, + 0, + img_size, + RAM_LOAD, + 0, + 0, + 0 + (int(spi_freq) << 2), + int(spi_rdcmd, 0), + 0, + ) + + payload[: len(header)] = header + + with open(signed_bin, "wb") as signed: + signed.write(payload) + signed.flush() + signed.close() + + with open(signed_bin, "ab") as signed, open(original_bin, "rb") as original: + signed.write(original.read()) + signed.flush() + signed.close() + original.close() + + +def main(): + """ + Image generateor tool entry point + """ + args = parse_args() + if args.verbose: + print(f" Input = {args.original_bin}") + print(f" Output = {args.signed_bin}") + print(f" Load Address = {hex(args.load_addr)}") + print(f" SPI Frequency = {args.spi_freq}") + print(f" SPI Read Command = {args.spi_rdcmd}") + img_gen( + args.load_addr, + args.spi_freq, + args.spi_rdcmd, + args.original_bin, + args.signed_bin, + ) + + +if __name__ == "__main__": + main() diff --git a/soc/realtek/ec/rts5912/CMakeLists.txt b/soc/realtek/ec/rts5912/CMakeLists.txt new file mode 100644 index 00000000000..335d40578ba --- /dev/null +++ b/soc/realtek/ec/rts5912/CMakeLists.txt @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 +# + +zephyr_include_directories(${ZEPHYR_BASE}/drivers) +zephyr_sources(soc.c) +zephyr_include_directories(.) + +zephyr_sources_ifdef(CONFIG_PM + device_power.c + power.c + ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/realtek/ec/rts5912/Kconfig b/soc/realtek/ec/rts5912/Kconfig new file mode 100644 index 00000000000..aebac7b3d00 --- /dev/null +++ b/soc/realtek/ec/rts5912/Kconfig @@ -0,0 +1,25 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 +# + +config SOC_SERIES_RTS5912 + select ARM + select CPU_CORTEX_M33 + select SYS_CLOCK_EXISTS + select DYNAMIC_INTERRUPTS + select SOC_EARLY_INIT_HOOK + +if SOC_SERIES_RTS5912 + +config RTS5912_ON_ENTER_CPU_IDLE_HOOK + bool "CPU idle hook enable" + default y + imply ARM_ON_ENTER_CPU_IDLE_HOOK + help + Enables a hook (z_arm_on_enter_cpu_idle()) that is called when + the CPU is made idle (by k_cpu_idle() or k_cpu_atomic_idle()). + If needed, this hook can be used to prevent the CPU from actually + entering sleep by skipping the WFE/WFI instruction. + +endif # SOC_SERIES_RTS5912 diff --git a/soc/realtek/ec/rts5912/Kconfig.defconfig.rts5912 b/soc/realtek/ec/rts5912/Kconfig.defconfig.rts5912 new file mode 100644 index 00000000000..5ff22637497 --- /dev/null +++ b/soc/realtek/ec/rts5912/Kconfig.defconfig.rts5912 @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 +# + +if SOC_RTS5912 + +if REALTEK_RTS5912_RTMR + +config PM + default y + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default 32768 + +config SYS_CLOCK_TICKS_PER_SEC + default 32768 + +config ARCH_HAS_CUSTOM_BUSY_WAIT + default y + +endif # REALTEK_RTS5912_RTMR + +endif # SOC_RTS5912 diff --git a/soc/realtek/ec/rts5912/Kconfig.defconfig.series b/soc/realtek/ec/rts5912/Kconfig.defconfig.series new file mode 100644 index 00000000000..429dbd9c788 --- /dev/null +++ b/soc/realtek/ec/rts5912/Kconfig.defconfig.series @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 +# + +if SOC_SERIES_RTS5912 + +config NUM_IRQS + default 240 + +rsource "Kconfig.defconfig.rts5912" + +endif # SOC_SERIES_RTS5912 diff --git a/soc/realtek/ec/rts5912/Kconfig.soc b/soc/realtek/ec/rts5912/Kconfig.soc new file mode 100644 index 00000000000..cf86fe3bcb7 --- /dev/null +++ b/soc/realtek/ec/rts5912/Kconfig.soc @@ -0,0 +1,20 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 +# + +config SOC_SERIES_RTS5912 + bool + select SOC_FAMILY_REALTEK_EC + help + Enable support for REALTEK EC MCU series + +config SOC_SERIES + default "rts5912" if SOC_SERIES_RTS5912 + +config SOC_RTS5912 + bool + select SOC_SERIES_RTS5912 + +config SOC + default "rts5912" if SOC_RTS5912 diff --git a/soc/realtek/ec/rts5912/device_power.c b/soc/realtek/ec/rts5912/device_power.c new file mode 100644 index 00000000000..b346cafd156 --- /dev/null +++ b/soc/realtek/ec/rts5912/device_power.c @@ -0,0 +1,25 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 + * Author: Lin Yu-Cheng + */ + +#include +#include + +#include +#include "device_power.h" + +void before_rts5912_sleep(void) +{ + __disable_irq(); + __set_BASEPRI(0); + __ISB(); +} + +void after_rts5912_sleep(void) +{ + __enable_irq(); + __ISB(); +} diff --git a/soc/realtek/ec/rts5912/device_power.h b/soc/realtek/ec/rts5912/device_power.h new file mode 100644 index 00000000000..6a2817fa79f --- /dev/null +++ b/soc/realtek/ec/rts5912/device_power.h @@ -0,0 +1,14 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 + * Author: Lin Yu-Cheng + */ + +#ifndef ZEPHYR_SOC_REALTEK_RTS5912_DEVICE_POWER_H +#define ZEPHYR_SOC_REALTEK_RTS5912_DEVICE_POWER_H + +void before_rts5912_sleep(void); +void after_rts5912_sleep(void); + +#endif /* ZEPHYR_SOC_REALTEK_RTS5912_DEVICE_POWER_H */ diff --git a/soc/realtek/ec/rts5912/power.c b/soc/realtek/ec/rts5912/power.c new file mode 100644 index 00000000000..d0702bc4ada --- /dev/null +++ b/soc/realtek/ec/rts5912/power.c @@ -0,0 +1,88 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 + * Author: Lin Yu-Cheng + */ + +#include +#include + +#include +#include "device_power.h" + +#define RTS5912_SCCON_REG_BASE ((SYSTEM_Type *)(DT_REG_ADDR(DT_NODELABEL(sccon)))) + +static void realtek_WFI(void) +{ + __DSB(); + __WFI(); +} + +static void rts5912_light_sleep(void) +{ + SYSTEM_Type *sys_reg = RTS5912_SCCON_REG_BASE; + + before_rts5912_sleep(); + + sys_reg->SLPCTRL &= ~SYSTEM_SLPCTRL_SLPMDSEL_Msk; + + realtek_WFI(); + + after_rts5912_sleep(); +} + +static void rts5912_heavy_sleep(void) +{ + SYSTEM_Type *sys_reg = RTS5912_SCCON_REG_BASE; + int main_clk_src_record = sys_reg->SYSCLK; + int PLL_en_record = sys_reg->PLLCTRL; + + before_rts5912_sleep(); + + if ((main_clk_src_record & SYSTEM_SYSCLK_SRC_Msk) == 0x0) { + if ((PLL_en_record & SYSTEM_PLLCTRL_EN_Msk) == 0x0) { + sys_reg->PLLCTRL |= SYSTEM_PLLCTRL_EN_Msk; /* Force to enable PLL */ + while ((sys_reg->PLLCTRL & SYSTEM_PLLCTRL_RDY_Msk) == 0x00) { + ; /* Wait until PLL is ready */ + } + } + sys_reg->SYSCLK |= SYSTEM_SYSCLK_SRC_Msk; /* Switch system clock to PLL */ + } + + sys_reg->SLPCTRL |= SYSTEM_SLPCTRL_SLPMDSEL_Msk; /* Heavy Sleep mode */ + + realtek_WFI(); + + if ((main_clk_src_record & SYSTEM_SYSCLK_SRC_Msk) == 0) { + sys_reg->SYSCLK &= ~SYSTEM_SYSCLK_SRC_Msk; /* Return system clock to 25M */ + if ((PLL_en_record & SYSTEM_PLLCTRL_EN_Msk) == 0x0) { + sys_reg->PLLCTRL &= ~SYSTEM_PLLCTRL_EN_Msk; /* Disable PLL */ + } + } + + after_rts5912_sleep(); +} + +void pm_state_set(enum pm_state state, uint8_t substate_id) +{ + + switch (state) { + case PM_STATE_SUSPEND_TO_IDLE: + rts5912_light_sleep(); + break; + case PM_STATE_SUSPEND_TO_RAM: + rts5912_heavy_sleep(); + break; + default: + break; + } +} + +void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +{ + ARG_UNUSED(state); + ARG_UNUSED(substate_id); + + irq_unlock(0); +} diff --git a/soc/realtek/ec/rts5912/soc.c b/soc/realtek/ec/rts5912/soc.c new file mode 100644 index 00000000000..adb28d75864 --- /dev/null +++ b/soc/realtek/ec/rts5912/soc.c @@ -0,0 +1,28 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 + * Author: Lin Yu-Cheng / Titan Chen + */ + +#include +#include +#include + +#if defined(CONFIG_RTS5912_ON_ENTER_CPU_IDLE_HOOK) +bool z_arm_on_enter_cpu_idle(void) +{ + /* Returning false prevent device goes to sleep mode */ + return false; +} +#endif + +/** + * @brief Perform basic hardware initialization at boot. + * + * This needs to be run from the very beginning. + */ +void soc_early_init_hook(void) +{ + /* Apply device related preinit configuration */ +} diff --git a/soc/realtek/ec/rts5912/soc.h b/soc/realtek/ec/rts5912/soc.h new file mode 100644 index 00000000000..3824ae900fb --- /dev/null +++ b/soc/realtek/ec/rts5912/soc.h @@ -0,0 +1,13 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 + * Author: Lin Yu-Cheng + */ + +#ifndef SOC_REALTEK_RTS5912_H_ +#define SOC_REALTEK_RTS5912_H_ + +#include + +#endif /* SOC_REALTEK_RTS5912_H_ */ diff --git a/soc/realtek/ec/soc.yml b/soc/realtek/ec/soc.yml new file mode 100644 index 00000000000..928ceedb635 --- /dev/null +++ b/soc/realtek/ec/soc.yml @@ -0,0 +1,2 @@ +socs: +- name: rts5912