soc: realrek: ec: Add Realtek RTS5912 SoC

Add support for Realtek RTS5912 embedded controller (EC).

Signed-off-by: Lin Yu-Cheng <lin_yu_cheng@realtek.com>
This commit is contained in:
Lin Yu-Cheng 2024-11-22 16:54:13 +08:00 committed by Benjamin Cabé
commit b83501e6cc
17 changed files with 510 additions and 0 deletions

View file

@ -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)

34
soc/realtek/ec/Kconfig Normal file
View file

@ -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

View file

@ -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

View file

@ -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"

View file

@ -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()

View file

@ -0,0 +1,161 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7
# Author: Dylan Hsieh <dylan.hsieh@realtek.com>
"""
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()

View file

@ -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 "")

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -0,0 +1,25 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7
* Author: Lin Yu-Cheng <lin_yu_cheng@realtek.com>
*/
#include <zephyr/logging/log.h>
#include <zephyr/kernel.h>
#include <reg/reg_system.h>
#include "device_power.h"
void before_rts5912_sleep(void)
{
__disable_irq();
__set_BASEPRI(0);
__ISB();
}
void after_rts5912_sleep(void)
{
__enable_irq();
__ISB();
}

View file

@ -0,0 +1,14 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7
* Author: Lin Yu-Cheng <lin_yu_cheng@realtek.com>
*/
#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 */

View file

@ -0,0 +1,88 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7
* Author: Lin Yu-Cheng <lin_yu_cheng@realtek.com>
*/
#include <zephyr/kernel.h>
#include <zephyr/pm/pm.h>
#include <reg/reg_system.h>
#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);
}

View file

@ -0,0 +1,28 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7
* Author: Lin Yu-Cheng <lin_yu_cheng@realtek.com> / Titan Chen
*/
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/init.h>
#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 */
}

View file

@ -0,0 +1,13 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7
* Author: Lin Yu-Cheng <lin_yu_cheng@realtek.com>
*/
#ifndef SOC_REALTEK_RTS5912_H_
#define SOC_REALTEK_RTS5912_H_
#include <cmsis_core_m_defaults.h>
#endif /* SOC_REALTEK_RTS5912_H_ */

2
soc/realtek/ec/soc.yml Normal file
View file

@ -0,0 +1,2 @@
socs:
- name: rts5912