diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 240b34c9a0d0e..1881e85171c95 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -4169,6 +4169,19 @@ OpenTitan Platforms: description: >- OpenTitan boards, SOCs, dts files and related drivers. +Realtek Fingerprint Platforms: + status: maintained + maintainers: + - RtkFP + files: + - boards/realtek/rts5817_maa_evb/ + - drivers/*/*rts5817* + - dts/bindings/*/*rts5817* + - dts/arm/realtek/fingerprint/ + - soc/realtek/fingerprint/ + labels: + - "platform: Realtek Fingerprint" + Realtek EC Platforms: status: maintained maintainers: diff --git a/boards/realtek/rts5817_maa_evb/Kconfig.rts5817_maa_evb b/boards/realtek/rts5817_maa_evb/Kconfig.rts5817_maa_evb new file mode 100644 index 0000000000000..59e334d3feef5 --- /dev/null +++ b/boards/realtek/rts5817_maa_evb/Kconfig.rts5817_maa_evb @@ -0,0 +1,5 @@ +# Copyright (c) 2024 Realtek Semiconductor, Inc. +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_RTS5817_MAA_EVB + select SOC_RTS5817 diff --git a/boards/realtek/rts5817_maa_evb/board.cmake b/boards/realtek/rts5817_maa_evb/board.cmake new file mode 100644 index 0000000000000..99b2089132d16 --- /dev/null +++ b/boards/realtek/rts5817_maa_evb/board.cmake @@ -0,0 +1,7 @@ +# Copyright (c) 2024 Realtek Semiconductor, Inc. +# SPDX-License-Identifier: Apache-2.0 +set_property(TARGET runners_yaml_props_target PROPERTY bin_file zephyr.rts5817.bin) + +board_set_flasher_ifnset(rtsflash) +board_runner_args(rtsflash "--pid=0bda:5817" "--alt=0") +board_finalize_runner_args(rtsflash) diff --git a/boards/realtek/rts5817_maa_evb/board.yml b/boards/realtek/rts5817_maa_evb/board.yml new file mode 100644 index 0000000000000..5f40fd9adff0a --- /dev/null +++ b/boards/realtek/rts5817_maa_evb/board.yml @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Realtek Semiconductor, Inc. +# SPDX-License-Identifier: Apache-2.0 + +board: + name: rts5817_maa_evb + vendor: realtek + socs: + - name: rts5817 diff --git a/boards/realtek/rts5817_maa_evb/doc/img/rts5817_maa_evb.webp b/boards/realtek/rts5817_maa_evb/doc/img/rts5817_maa_evb.webp new file mode 100644 index 0000000000000..a4e48cc8d6fea Binary files /dev/null and b/boards/realtek/rts5817_maa_evb/doc/img/rts5817_maa_evb.webp differ diff --git a/boards/realtek/rts5817_maa_evb/doc/index.rst b/boards/realtek/rts5817_maa_evb/doc/index.rst new file mode 100644 index 0000000000000..905fda4a7bcc0 --- /dev/null +++ b/boards/realtek/rts5817_maa_evb/doc/index.rst @@ -0,0 +1,63 @@ +.. zephyr:board:: rts5817_maa_evb + +Overview +******** + +rts5817 is a high-performance MCU based on Realtek Real-M300 ARMv8-M architecture with Cortex-M33 instruction set compatible. + +.. figure:: img/rts5817_maa_evb.webp + :width: 400px + :align: center + :alt: rts5817_maa_evb + +Hardware +******** + +- 240MHz single-core 32-bit CPU with I-cache 32KB, D-cache 16KB +- 48KB boot ROM +- 256KB on-chip SRAM +- 1KB PUFrt OTP +- 2MB Flash +- USB2.0 full speed/high speed device +- Up to 11 GPIO +- 2 x UART +- 2 x Timer +- 2 x SPI, one can support slave mode +- Watchdog +- DMA +- Temperature sensor +- Cryptographic hardware acceleration (RNG, SHA, AES) +- Fingerprint mataching hardware acceleration (MAC, popcount, convolution, etc.) +- SWD for debug + +Supported Features +================== + +.. zephyr:board-supported-hw:: + +Programming and Debugging +************************* + +Building +======== + +#. Build :zephyr:code-sample:`hello_world` application as you would normally do. + +#. The file ``zephyr.rts5817.bin`` will be created if the build system can build successfully. + This binary image can be found under file "build/zephyr/". + +Flashing +======== + +#. Short the two pins of ``J6`` to enter force rom mode (see `RTS5817MAA_EVB_User_Guide`_). +#. Connect the board to your host computer using USB. +#. Use ``west flash`` command to flash the image. +#. Disconnect the two pins of ``J6`` and reboot, The :zephyr:code-sample:`hello_world` application is running. + +References +********** + +.. target-notes:: + +.. _RTS5817MAA_EVB_User_Guide: + https://github.com/RtkFP/Doc/blob/main/RTS5817MAA_EVB%20User%20Guide_V1.0.pdf diff --git a/boards/realtek/rts5817_maa_evb/rts5817_maa_evb-pinctrl.dtsi b/boards/realtek/rts5817_maa_evb/rts5817_maa_evb-pinctrl.dtsi new file mode 100644 index 0000000000000..552856f908859 --- /dev/null +++ b/boards/realtek/rts5817_maa_evb/rts5817_maa_evb-pinctrl.dtsi @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor, Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + uart0_default: uart0_default { + group0 { + pinmux = , ; + }; + }; + + /omit-if-no-ref/ sensor_spi_default: sensor_spi_default { + group0 { + pinmux = , , + ; + power-source = ; + bias-pull-down; + }; + + group1 { + pinmux = , ; + power-source = ; + bias-pull-up; + }; + }; + + /omit-if-no-ref/ ssi_master_default: ssi_master_default { + group0 { + pinmux = , , + , ; + bias-pull-down; + }; + }; +}; diff --git a/boards/realtek/rts5817_maa_evb/rts5817_maa_evb.dts b/boards/realtek/rts5817_maa_evb/rts5817_maa_evb.dts new file mode 100644 index 0000000000000..390f81ce11d3c --- /dev/null +++ b/boards/realtek/rts5817_maa_evb/rts5817_maa_evb.dts @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor, Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "rts5817_maa_evb-pinctrl.dtsi" + +/ { + model = "Realtek rts5817_maa_evb"; + compatible = "realtek,rts5817_maa_evb"; + #address-cells = <1>; + #size-cells = <1>; + + chosen { + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + }; +}; + +&clks { + status = "okay"; +}; + +&reset { + status = "okay"; +}; + +&watchdog { + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_default>; + current-speed = <57600>; + status = "okay"; +}; + +&uart1 { + status = "disabled"; +}; diff --git a/boards/realtek/rts5817_maa_evb/rts5817_maa_evb.yaml b/boards/realtek/rts5817_maa_evb/rts5817_maa_evb.yaml new file mode 100644 index 0000000000000..e33be64c4d61c --- /dev/null +++ b/boards/realtek/rts5817_maa_evb/rts5817_maa_evb.yaml @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Realtek Semiconductor, Inc. +# SPDX-License-Identifier: Apache-2.0 + +identifier: rts5817_maa_evb +name: RTS5817 Platform for fingerprint +type: mcu +arch: arm +ram: 256 +flash: 2048 +toolchain: + - zephyr + - gnuarmemb +testing: + default: true +vendor: realtek diff --git a/boards/realtek/rts5817_maa_evb/rts5817_maa_evb_defconfig b/boards/realtek/rts5817_maa_evb/rts5817_maa_evb_defconfig new file mode 100644 index 0000000000000..7d0bcb05f3744 --- /dev/null +++ b/boards/realtek/rts5817_maa_evb/rts5817_maa_evb_defconfig @@ -0,0 +1,17 @@ +# Copyright (c) 2024 Realtek Semiconductor, Inc. +# SPDX-License-Identifier: Apache-2.0 + +# Enable clocks +CONFIG_CLOCK_CONTROL=y + +# Enable reset +CONFIG_RESET=y + +# Enable serial console +CONFIG_SERIAL=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable watchdog +CONFIG_WATCHDOG=y +CONFIG_WDT_DISABLE_AT_BOOT=y diff --git a/drivers/clock_control/CMakeLists.txt b/drivers/clock_control/CMakeLists.txt index 18b6025df6c7c..d063bb763fc76 100644 --- a/drivers/clock_control/CMakeLists.txt +++ b/drivers/clock_control/CMakeLists.txt @@ -122,3 +122,5 @@ endif() zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_AST10X0 clock_control_ast10x0.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_MAX32 clock_control_max32.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_WCH_RCC clock_control_wch_rcc.c) + +zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_RTS5817 clock_control_rts5817.c) diff --git a/drivers/clock_control/Kconfig b/drivers/clock_control/Kconfig index 05a2a7fb8fa67..9944444b175e2 100644 --- a/drivers/clock_control/Kconfig +++ b/drivers/clock_control/Kconfig @@ -114,4 +114,6 @@ source "drivers/clock_control/Kconfig.wch_rcc" source "drivers/clock_control/Kconfig.it51xxx" +source "drivers/clock_control/Kconfig.rts5817" + endif # CLOCK_CONTROL diff --git a/drivers/clock_control/Kconfig.rts5817 b/drivers/clock_control/Kconfig.rts5817 new file mode 100644 index 0000000000000..cc00f71094456 --- /dev/null +++ b/drivers/clock_control/Kconfig.rts5817 @@ -0,0 +1,9 @@ +# Copyright (c) 2024 Realtek Semiconductor, Inc. +# SPDX-License-Identifier: Apache-2.0 + +config CLOCK_CONTROL_RTS5817 + bool "RTS5817 clock control" + depends on DT_HAS_REALTEK_RTS5817_CLOCK_ENABLED + default y + help + Enable driver for RTS5817 Clock Control. diff --git a/drivers/clock_control/clock_control_rts5817.c b/drivers/clock_control/clock_control_rts5817.c new file mode 100644 index 0000000000000..d7b446ba02f23 --- /dev/null +++ b/drivers/clock_control/clock_control_rts5817.c @@ -0,0 +1,1013 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include "zephyr/arch/common/sys_io.h" +#include "zephyr/device.h" +#include +#include +#include "clock_control_rts5817_control.h" +#include "clock_control_rts5817_gpll.h" + +#define DT_DRV_COMPAT realtek_rts5817_clock + +struct rts_fp_clock_data { + uint32_t syspll_frequency; + struct k_spinlock lock; +}; + +struct rts_fp_clock_config { + mem_addr_t base; + mem_addr_t syspll_base; + mem_addr_t sck_div_base; +}; + +struct clk_rlx { + uint16_t id; + const struct rlx_clk_ops *ops; + uint16_t clkreg; + uint16_t clk_change; +}; + +struct rlx_clk_ops { + int (*enable)(const struct device *dev, const struct clk_rlx *clk); + int (*disable)(const struct device *dev, const struct clk_rlx *clk); + enum clock_control_status (*get_status)(const struct device *dev, + const struct clk_rlx *clk); + uint32_t (*get_rate)(const struct device *dev, const struct clk_rlx *clk); + int (*set_rate)(const struct device *dev, const struct clk_rlx *clk, uint32_t rate); +}; + +static uint8_t m_div_array[] = {1, 2, 4, 6, 8, 10, 12, 14}; + +#define DEFINE_CLK_RLX(_name, _id, _ops, _clk_reg, _clk_change) \ + static const struct clk_rlx _name = { \ + .id = _id, \ + .ops = &_ops, \ + .clkreg = _clk_reg, \ + .clk_change = _clk_change, \ + } +#define CK_CHANGE_NULL 0 + +static inline uint32_t rts_fp_clk_read_reg(const struct device *dev, uint32_t offset) +{ + const struct rts_fp_clock_config *config = dev->config; + + return sys_read32(config->base + offset); +} + +static inline void rts_fp_clk_write_reg(const struct device *dev, uint32_t data, uint32_t offset) +{ + const struct rts_fp_clock_config *config = dev->config; + + sys_write32(data, config->base + offset); +} + +static inline uint32_t rts_fp_read_sck_div_reg(const struct device *dev) +{ + const struct rts_fp_clock_config *config = dev->config; + + return sys_read32(config->sck_div_base); +} + +static inline void rts_fp_write_sck_div_reg(const struct device *dev, uint32_t data) +{ + const struct rts_fp_clock_config *config = dev->config; + + sys_write32(data, config->sck_div_base); +} + +static void set_change_bit(const struct device *dev, uint32_t clk_change) +{ + const struct rts_fp_clock_config *config = dev->config; + + sys_set_bit(config->base + R_SYS_CLK_CHANGE, clk_change); +} + +static void clear_change_bit(const struct device *dev, uint32_t clk_change) +{ + const struct rts_fp_clock_config *config = dev->config; + + sys_clear_bit(config->base + R_SYS_CLK_CHANGE, clk_change); +} + +static int rlx_enable_syspll(const struct device *dev, const struct clk_rlx *clk) +{ + const struct rts_fp_clock_config *config = dev->config; + uint32_t timeout = 1000; + + sys_set_bits(config->syspll_base + R_SYSPLL_CTL, POW_SYSPLL); + k_busy_wait(20); + + sys_set_bits(config->syspll_base + R_SYSPLL_CTL, PLL_LOAD_EN); + k_busy_wait(10); + + sys_clear_bits(config->syspll_base + R_SYSPLL_CTL, PLL_LOAD_EN); + k_busy_wait(70); + + while (!(sys_read32(config->syspll_base + R_SYSPLL_STS) & PLL_CKUSABLE) && timeout--) { + k_busy_wait(10); + } + k_busy_wait(70); + if (timeout) { + return 0; + } else { + return -ETIMEDOUT; + } +} + +static int rlx_disable_syspll(const struct device *dev, const struct clk_rlx *clk) +{ + const struct rts_fp_clock_config *config = dev->config; + + sys_clear_bits(config->syspll_base + R_SYSPLL_CTL, POW_SYSPLL); + k_busy_wait(10); + + return 0; +} + +static enum clock_control_status rlx_syspll_status(const struct device *dev, + const struct clk_rlx *clk) +{ + const struct rts_fp_clock_config *config = dev->config; + + if (sys_read32(config->syspll_base + R_SYSPLL_STS) & PLL_CKUSABLE) { + return CLOCK_CONTROL_STATUS_ON; + } + return CLOCK_CONTROL_STATUS_OFF; +} + +static uint32_t rlx_syspll_get_rate(const struct device *dev, const struct clk_rlx *clk) +{ + ARG_UNUSED(clk); + const struct rts_fp_clock_config *config = dev->config; + struct rts_fp_clock_data *clk_data = dev->data; + uint32_t ssc_n, ssc_f; + uint32_t reg; + + reg = sys_read32(config->syspll_base + R_SYSPLL_NF_CODE); + ssc_n = reg & N_SSC_MASK; + ssc_f = reg & F_SSC_MASK; + clk_data->syspll_frequency = 4000000 * (ssc_n + 2 + ssc_f / 4096); /* Hz */ + + return clk_data->syspll_frequency; +} + +static int rlx_syspll_set_rate(const struct device *dev, const struct clk_rlx *clk, uint32_t rate) +{ + const struct rts_fp_clock_config *config = dev->config; + struct rts_fp_clock_data *clk_data = dev->data; + uint32_t ssc_n, ssc_f; + uint32_t reg; + + clk_data->syspll_frequency = rate; + ssc_n = (rate / 4000000) - 2; + ssc_f = 4096 * (rate % 4000000) / 4000000; + + /* PLL_REG_CCO_SEL=1: use CCO; PLL_REG_CCO_SEL=0: use VCO */ + sys_clear_bits(config->syspll_base + R_SYSPLL_CFG, PLL_REG_CCO_SEL); + if (ssc_f) { + sys_clear_bits(config->syspll_base + R_SYSPLL_CFG, PLL_REG_PI_SEL); + sys_clear_bits(config->syspll_base + R_SYSPLL_CFG, PLL_BYPASS_PI); + } else { + sys_set_bits(config->syspll_base + R_SYSPLL_CFG, PLL_REG_PI_SEL); + sys_set_bits(config->syspll_base + R_SYSPLL_CFG, PLL_BYPASS_PI); + } + sys_set_bits(config->syspll_base + R_SYSPLL_CFG, REG_SC_H); + reg = sys_read32(config->syspll_base + R_SYSPLL_NF_CODE); + reg = (reg & ~(F_SSC | N_SSC)) | (ssc_n << N_SSC_OFFSET) | (ssc_f << F_SSC_OFFSET); + sys_write32(reg, config->syspll_base + R_SYSPLL_NF_CODE); + + return 0; +} + +static const struct rlx_clk_ops rlx_clk_syspll_ops = { + .enable = rlx_enable_syspll, + .disable = rlx_disable_syspll, + .get_status = rlx_syspll_status, + .get_rate = rlx_syspll_get_rate, + .set_rate = rlx_syspll_set_rate, +}; + +static int rlx_enable_clk(const struct device *dev, const struct clk_rlx *clk) +{ + uint32_t reg = rts_fp_clk_read_reg(dev, clk->clkreg); + uint32_t en_mask; + + if (clk->id == RTS_FP_CLK_GE) { + en_mask = (1 << GE_CLK_EN_OFFSET); + } else { + en_mask = (1 << 24); + } + + if (!(reg & en_mask)) { + rts_fp_clk_write_reg(dev, (reg | en_mask), clk->clkreg); + } + return 0; +} + +static int rlx_disable_clk(const struct device *dev, const struct clk_rlx *clk) +{ + uint32_t reg = rts_fp_clk_read_reg(dev, clk->clkreg); + uint32_t en_mask; + + if (clk->id == RTS_FP_CLK_GE) { + en_mask = (1 << GE_CLK_EN_OFFSET); + } else { + en_mask = (1 << 24); + } + + if (reg & en_mask) { + rts_fp_clk_write_reg(dev, (reg & ~en_mask), clk->clkreg); + } + return 0; +} + +static enum clock_control_status rlx_get_status(const struct device *dev, const struct clk_rlx *clk) +{ + uint32_t reg = rts_fp_clk_read_reg(dev, clk->clkreg); + uint32_t en_mask; + + if (clk->id == RTS_FP_CLK_GE) { + en_mask = (1 << GE_CLK_EN_OFFSET); + } else { + en_mask = (1 << 24); + } + + if (reg & en_mask) { + return CLOCK_CONTROL_STATUS_ON; + } else { + return CLOCK_CONTROL_STATUS_OFF; + } +} + +static uint32_t rlx_common_get_rate(const struct device *dev, const struct clk_rlx *clk) +{ + struct rts_fp_clock_data *clk_data = dev->data; + uint32_t src[] = {240000000, 160000000, 96000000, clk_data->syspll_frequency}; + uint32_t reg = rts_fp_clk_read_reg(dev, clk->clkreg); + uint32_t divider, idx; + uint32_t rate; + + idx = reg & 0x3; + divider = (reg >> 2) & 0x7; + rate = src[idx] / m_div_array[divider]; + + return rate; +} + +static void __aligned(32) __noinline change_bus_clk_sub(const struct device *dev, + const struct clk_rlx *clk, uint32_t data) +{ + rts_fp_write_sck_div_reg(dev, 0x02); + set_change_bit(dev, clk->clk_change); + /* Assign writing R_SYS_BUS_CLK_CFG_REG to the next cache line */ + /* to ensure that it takes effect after reading the previous cacheline done */ + arch_nop(); + arch_nop(); + arch_nop(); + arch_nop(); + arch_nop(); + arch_nop(); + rts_fp_clk_write_reg(dev, data, clk->clkreg); + arch_nop(); + arch_nop(); + arch_nop(); + arch_nop(); + clear_change_bit(dev, clk->clk_change); +} + +static void __aligned(32) __noinline change_cache_spi_clk_sub(const struct device *dev, + const struct clk_rlx *clk, + uint32_t data) +{ + set_change_bit(dev, clk->clk_change); + /* Assign writing R_SYS_SPI_CACHE_CLK_CFG_REG to the next cache line */ + /* to ensure that it takes effect after reading the previous cacheline done */ + arch_nop(); + arch_nop(); + arch_nop(); + arch_nop(); + arch_nop(); + arch_nop(); + arch_nop(); + arch_nop(); + rts_fp_clk_write_reg(dev, data, clk->clkreg); + arch_nop(); + arch_nop(); + arch_nop(); + arch_nop(); + clear_change_bit(dev, clk->clk_change); +} + +static int rlx_common_set_rate(const struct device *dev, const struct clk_rlx *clk, uint32_t rate) +{ + struct rts_fp_clock_data *data = dev->data; + uint32_t divider, idx; + uint32_t reg; + k_spinlock_key_t key; + + if (clk->ops->get_rate(dev, clk) == rate) { + return 0; + } + + reg = rts_fp_clk_read_reg(dev, clk->clkreg); + switch (rate) { + case 240000000: + idx = 0; + divider = 0; + break; + case 120000000: + idx = 0; + divider = 1; + break; + case 60000000: + idx = 0; + divider = 2; + break; + case 30000000: + idx = 0; + divider = 4; + break; + case 160000000: + idx = 1; + divider = 0; + break; + case 80000000: + idx = 1; + divider = 1; + break; + case 40000000: + idx = 1; + divider = 2; + break; + case 20000000: + idx = 1; + divider = 4; + break; + case 96000000: + idx = 2; + divider = 0; + break; + case 48000000: + idx = 2; + divider = 1; + break; + case 24000000: + idx = 2; + divider = 2; + break; + case 16000000: + idx = 2; + divider = 3; + break; + default: + return -EINVAL; + } + + reg = (reg & ~0x3f) | idx | (divider << 2); + + if (clk->id == RTS_FP_CLK_BUS) { + uint8_t sck_div = rts_fp_read_sck_div_reg(dev); + + key = k_spin_lock(&data->lock); + change_bus_clk_sub(dev, clk, reg); + k_spin_unlock(&data->lock, key); + rts_fp_write_sck_div_reg(dev, sck_div); + } else if (clk->id == RTS_FP_CLK_SPI_CACHE) { + key = k_spin_lock(&data->lock); + change_cache_spi_clk_sub(dev, clk, reg); + k_spin_unlock(&data->lock, key); + } else { + key = k_spin_lock(&data->lock); + set_change_bit(dev, clk->clk_change); + rts_fp_clk_write_reg(dev, reg, clk->clkreg); + arch_nop(); + arch_nop(); + arch_nop(); + arch_nop(); + clear_change_bit(dev, clk->clk_change); + + k_spin_unlock(&data->lock, key); + } + + return 0; +} + +static const struct rlx_clk_ops rlx_clk_bus_ops = { + .get_rate = rlx_common_get_rate, + .set_rate = rlx_common_set_rate, +}; + +static const struct rlx_clk_ops rlx_clk_common_ops = { + .enable = rlx_enable_clk, + .disable = rlx_disable_clk, + .get_status = rlx_get_status, + .get_rate = rlx_common_get_rate, + .set_rate = rlx_common_set_rate, +}; + +static uint32_t rlx_spi_get_rate(const struct device *dev, const struct clk_rlx *clk) +{ + struct rts_fp_clock_data *clk_data = dev->data; + uint32_t src[] = {240000000, 96000000, 80000000, clk_data->syspll_frequency}; + uint32_t reg = rts_fp_clk_read_reg(dev, clk->clkreg); + uint32_t divider, idx; + uint32_t rate; + + idx = reg & 0x3; + divider = (reg >> 2) & 0x7; + rate = src[idx] / m_div_array[divider]; + + return rate; +} + +static int rlx_spi_set_rate(const struct device *dev, const struct clk_rlx *clk, uint32_t rate) +{ + struct rts_fp_clock_data *data = dev->data; + uint32_t divider, idx; + uint32_t reg; + k_spinlock_key_t key; + + if (clk->ops->get_rate(dev, clk) == rate) { + return 0; + } + + reg = rts_fp_clk_read_reg(dev, clk->clkreg); + switch (rate) { + case 240000000: + idx = 0; + divider = 0; + break; + case 120000000: + idx = 0; + divider = 1; + break; + case 60000000: + idx = 0; + divider = 2; + break; + case 30000000: + idx = 0; + divider = 4; + break; + case 80000000: + idx = 2; + divider = 0; + break; + case 40000000: + idx = 2; + divider = 1; + break; + case 20000000: + idx = 2; + divider = 2; + break; + case 96000000: + idx = 1; + divider = 0; + break; + case 48000000: + idx = 1; + divider = 1; + break; + case 24000000: + idx = 1; + divider = 2; + break; + case 16000000: + idx = 1; + divider = 3; + break; + default: + return -EINVAL; + } + + reg = (reg & ~0x3f) | idx | (divider << 2); + + key = k_spin_lock(&data->lock); + set_change_bit(dev, clk->clk_change); + rts_fp_clk_write_reg(dev, reg, clk->clkreg); + arch_nop(); + arch_nop(); + arch_nop(); + arch_nop(); + clear_change_bit(dev, clk->clk_change); + + k_spin_unlock(&data->lock, key); + + return 0; +} + +static const struct rlx_clk_ops rlx_clk_spi_ops = { + .enable = rlx_enable_clk, + .disable = rlx_disable_clk, + .get_status = rlx_get_status, + .get_rate = rlx_spi_get_rate, + .set_rate = rlx_spi_set_rate, +}; + +static uint32_t rlx_uart_get_rate(const struct device *dev, const struct clk_rlx *clk) +{ + struct rts_fp_clock_data *clk_data = dev->data; + uint32_t src[] = {96000000, 120000000, 0, clk_data->syspll_frequency}; + uint32_t reg = rts_fp_clk_read_reg(dev, clk->clkreg); + uint32_t divider, idx; + uint32_t rate; + + idx = reg & 0x3; + divider = (reg >> 2) & 0x7; + rate = src[idx] / m_div_array[divider]; + + return rate; +} + +static int rlx_uart_set_rate(const struct device *dev, const struct clk_rlx *clk, uint32_t rate) +{ + struct rts_fp_clock_data *data = dev->data; + uint32_t divider, idx; + uint32_t reg; + k_spinlock_key_t key; + + if (clk->ops->get_rate(dev, clk) == rate) { + return 0; + } + + reg = rts_fp_clk_read_reg(dev, clk->clkreg); + switch (rate) { + case 60000000: + idx = 1; + divider = 1; + break; + case 30000000: + idx = 1; + divider = 2; + break; + case 48000000: + idx = 0; + divider = 1; + break; + case 24000000: + idx = 0; + divider = 2; + break; + case 16000000: + idx = 0; + divider = 3; + break; + default: + return -EINVAL; + } + + reg = (reg & ~0x3f) | idx | (divider << 2); + key = k_spin_lock(&data->lock); + set_change_bit(dev, clk->clk_change); + rts_fp_clk_write_reg(dev, reg, clk->clkreg); + arch_nop(); + arch_nop(); + arch_nop(); + arch_nop(); + clear_change_bit(dev, clk->clk_change); + + k_spin_unlock(&data->lock, key); + return 0; +} + +static const struct rlx_clk_ops rlx_clk_uart_ops = { + .enable = rlx_enable_clk, + .disable = rlx_disable_clk, + .get_status = rlx_get_status, + .get_rate = rlx_uart_get_rate, + .set_rate = rlx_uart_set_rate, +}; + +static uint32_t rlx_pke_get_rate(const struct device *dev, const struct clk_rlx *clk) +{ + uint32_t reg = rts_fp_clk_read_reg(dev, clk->clkreg); + uint32_t src_clk_frq = 120000000; + uint32_t divider; + uint32_t rate; + + divider = (reg >> 2) & 0x7; + rate = src_clk_frq / m_div_array[divider]; + + return rate; +} + +static int rlx_pke_set_rate(const struct device *dev, const struct clk_rlx *clk, uint32_t rate) +{ + struct rts_fp_clock_data *data = dev->data; + uint32_t divider; + uint32_t reg; + k_spinlock_key_t key; + + if (clk->ops->get_rate(dev, clk) == rate) { + return 0; + } + + reg = rts_fp_clk_read_reg(dev, clk->clkreg); + switch (rate) { + case 120000000: + divider = 0; + break; + case 60000000: + divider = 1; + break; + case 30000000: + divider = 2; + break; + case 20000000: + divider = 3; + break; + default: + return -EINVAL; + } + + reg = (reg & ~0x1C) | (divider << 2); + key = k_spin_lock(&data->lock); + rts_fp_clk_write_reg(dev, reg, clk->clkreg); + arch_nop(); + arch_nop(); + arch_nop(); + arch_nop(); + k_spin_unlock(&data->lock, key); + return 0; +} + +static const struct rlx_clk_ops rlx_clk_pke_ops = { + .enable = rlx_enable_clk, + .disable = rlx_disable_clk, + .get_status = rlx_get_status, + .get_rate = rlx_pke_get_rate, + .set_rate = rlx_pke_set_rate, +}; + +static int rlx_i2c_enable_clk(const struct device *dev, const struct clk_rlx *clk) +{ + uint32_t reg = rts_fp_clk_read_reg(dev, clk->clkreg); + + reg |= I2C_CLK_EN; + rts_fp_clk_write_reg(dev, reg, clk->clkreg); + if (clk->id == RTS_FP_CLK_I2C0) { + reg |= I2C0_CLK_EN; + } else if (clk->id == RTS_FP_CLK_I2C1) { + reg |= I2C1_CLK_EN; + } else { + return -EINVAL; + } + + rts_fp_clk_write_reg(dev, reg, clk->clkreg); + return 0; +} + +static int rlx_i2c_disable_clk(const struct device *dev, const struct clk_rlx *clk) +{ + uint32_t reg = rts_fp_clk_read_reg(dev, clk->clkreg); + + if (clk->id == RTS_FP_CLK_I2C0) { + reg &= ~I2C0_CLK_EN; + } else if (clk->id == RTS_FP_CLK_I2C1) { + reg &= ~I2C1_CLK_EN; + } else { + return -EINVAL; + } + + rts_fp_clk_write_reg(dev, reg, clk->clkreg); + if (reg & (I2C0_CLK_EN | I2C1_CLK_EN)) { + return 0; + } + + reg &= ~I2C_CLK_EN; + rts_fp_clk_write_reg(dev, reg, clk->clkreg); + + return 0; +} + +static enum clock_control_status rlx_i2c_get_status(const struct device *dev, + const struct clk_rlx *clk) +{ + uint32_t reg = rts_fp_clk_read_reg(dev, clk->clkreg); + uint32_t en_mask; + + if (clk->id == RTS_FP_CLK_I2C0) { + en_mask = I2C0_CLK_EN; + } else if (clk->id == RTS_FP_CLK_I2C1) { + en_mask = I2C1_CLK_EN; + } else { + return -EINVAL; + } + + if (reg & en_mask) { + return CLOCK_CONTROL_STATUS_ON; + } else { + return CLOCK_CONTROL_STATUS_OFF; + } +} + +static uint32_t rlx_i2c_get_rate(const struct device *dev, const struct clk_rlx *clk) +{ + uint32_t reg = rts_fp_clk_read_reg(dev, clk->clkreg); + uint32_t src_clk_frq = 240000000; + uint32_t divider; + uint32_t rate; + + divider = (reg >> 2) & 0x7; + rate = src_clk_frq / m_div_array[divider]; + + return rate; +} + +static int rlx_i2c_set_rate(const struct device *dev, const struct clk_rlx *clk, uint32_t rate) +{ + struct rts_fp_clock_data *data = dev->data; + uint32_t divider; + uint32_t reg; + k_spinlock_key_t key; + + if (clk->ops->get_rate(dev, clk) == rate) { + return 0; + } + + reg = rts_fp_clk_read_reg(dev, clk->clkreg); + switch (rate) { + case 240000000: + divider = 0; + break; + case 120000000: + divider = 1; + break; + case 60000000: + divider = 2; + break; + case 40000000: + divider = 3; + break; + default: + return -EINVAL; + } + + reg = (reg & ~0x1C) | (divider << 2); + key = k_spin_lock(&data->lock); + rts_fp_clk_write_reg(dev, reg, clk->clkreg); + arch_nop(); + arch_nop(); + arch_nop(); + arch_nop(); + k_spin_unlock(&data->lock, key); + return 0; +} + +static const struct rlx_clk_ops rlx_clk_i2c_ops = { + .enable = rlx_i2c_enable_clk, + .disable = rlx_i2c_disable_clk, + .get_status = rlx_i2c_get_status, + .get_rate = rlx_i2c_get_rate, + .set_rate = rlx_i2c_set_rate, +}; + +static int rlx_ck60_enable_clk(const struct device *dev, const struct clk_rlx *clk) +{ + uint32_t reg = rts_fp_clk_read_reg(dev, clk->clkreg); + + if (clk->id == RTS_FP_CLK_TRNG) { + reg |= TRNG_CLK_EN; + } else if (clk->id == RTS_FP_CLK_I2C_S) { + reg |= I2C_S_CLK_EN; + } else { + return -EINVAL; + } + + rts_fp_clk_write_reg(dev, reg, clk->clkreg); + return 0; +} + +static int rlx_ck60_disable_clk(const struct device *dev, const struct clk_rlx *clk) +{ + uint32_t reg = rts_fp_clk_read_reg(dev, clk->clkreg); + + if (clk->id == RTS_FP_CLK_TRNG) { + reg &= ~TRNG_CLK_EN; + } else if (clk->id == RTS_FP_CLK_I2C_S) { + reg &= ~I2C_S_CLK_EN; + } else { + return -EINVAL; + } + + rts_fp_clk_write_reg(dev, reg, clk->clkreg); + + return 0; +} + +static enum clock_control_status rlx_ck60_get_status(const struct device *dev, + const struct clk_rlx *clk) +{ + uint32_t reg = rts_fp_clk_read_reg(dev, clk->clkreg); + uint32_t en_mask; + + if (clk->id == RTS_FP_CLK_TRNG) { + en_mask = TRNG_CLK_EN_MASK; + } else if (clk->id == RTS_FP_CLK_I2C_S) { + en_mask = I2C_S_CLK_EN_MASK; + } else { + return -EINVAL; + } + + if (reg & en_mask) { + return CLOCK_CONTROL_STATUS_ON; + } else { + return CLOCK_CONTROL_STATUS_OFF; + } +} + +static const struct rlx_clk_ops rlx_clk_ck60_ops = { + .enable = rlx_ck60_enable_clk, + .disable = rlx_ck60_disable_clk, + .get_status = rlx_ck60_get_status, +}; + +static const struct rlx_clk_ops rlx_clk_gate_ops = { + .enable = rlx_enable_clk, + .disable = rlx_disable_clk, + .get_status = rlx_get_status, +}; + +DEFINE_CLK_RLX(syspll, RTS_FP_CLK_SYS_PLL, rlx_clk_syspll_ops, 0, 0); +DEFINE_CLK_RLX(bus_clk, RTS_FP_CLK_BUS, rlx_clk_bus_ops, R_SYS_BUS_CLK_CFG_REG, + CHANGE_BUS_CLK_PRE_OFFSET); +DEFINE_CLK_RLX(spi_cache_clk, RTS_FP_CLK_SPI_CACHE, rlx_clk_common_ops, R_SYS_SPI_CACHE_CLK_CFG_REG, + CHANGE_SPI_CACHE_CLK_OFFSET); +DEFINE_CLK_RLX(spi_ssor_clk, RTS_FP_CLK_SPI_SSOR, rlx_clk_spi_ops, R_SYS_SPI_SSOR_CLK_CFG_REG, + CHANGE_SPI_SSOR_CLK_OFFSET); +DEFINE_CLK_RLX(ssi_m_clk, RTS_FP_CLK_SPI_SSI_M, rlx_clk_spi_ops, R_SYS_SPI_SSI_M_CLK_CFG_REG, + CHANGE_SPI_SSI_M_CLK_OFFSET); +DEFINE_CLK_RLX(ssi_s_clk, RTS_FP_CLK_SPI_SSI_S, rlx_clk_spi_ops, R_SYS_SPI_SSI_S_CLK_CFG_REG, + CHANGE_SPI_SSI_S_CLK_OFFSET); +DEFINE_CLK_RLX(sha_clk, RTS_FP_CLK_SHA, rlx_clk_common_ops, R_SYS_SHA_CLK_CFG_REG, + CHANGE_SHA_CLK_OFFSET); +DEFINE_CLK_RLX(aes_clk, RTS_FP_CLK_AES, rlx_clk_common_ops, R_SYS_AES_CLK_CFG_REG, + CHANGE_AES_CLK_OFFSET); +DEFINE_CLK_RLX(pke_clk, RTS_FP_CLK_PKE, rlx_clk_pke_ops, R_SYS_PKE_CLK_CFG_REG, 0); +DEFINE_CLK_RLX(i2c0_clk, RTS_FP_CLK_I2C0, rlx_clk_i2c_ops, R_SYS_I2C_CLK_CFG_REG, 0); +DEFINE_CLK_RLX(i2c1_clk, RTS_FP_CLK_I2C1, rlx_clk_i2c_ops, R_SYS_I2C_CLK_CFG_REG, 0); +DEFINE_CLK_RLX(trng_clk, RTS_FP_CLK_TRNG, rlx_clk_ck60_ops, R_SYS_CK60_CFG_REG, 0); +DEFINE_CLK_RLX(i2c_s_clk, RTS_FP_CLK_I2C_S, rlx_clk_ck60_ops, R_SYS_CK60_CFG_REG, 0); +DEFINE_CLK_RLX(uart0_clk, RTS_FP_CLK_UART0, rlx_clk_uart_ops, R_SYS_UART0_CLK_CFG_REG, + CHANGE_UART0_CLK_OFFSET); +DEFINE_CLK_RLX(uart1_clk, RTS_FP_CLK_UART1, rlx_clk_uart_ops, R_SYS_UART1_CLK_CFG_REG, + CHANGE_UART1_CLK_OFFSET); +DEFINE_CLK_RLX(sie_clk, RTS_FP_CLK_SIE, rlx_clk_gate_ops, R_SYS_SIE_CLK_CFG_REG, 0); +DEFINE_CLK_RLX(puf_clk, RTS_FP_CLK_PUF, rlx_clk_gate_ops, R_SYS_PUF_CLK_CFG_REG, 0); +DEFINE_CLK_RLX(ge_clk, RTS_FP_CLK_GE, rlx_clk_gate_ops, R_SYS_BUS_CLK_CFG_REG, 0); + +static const struct clk_rlx *const m_clks[RLX_CLK_NUM_SIZE] = { + &syspll, &bus_clk, &spi_cache_clk, &spi_ssor_clk, &ssi_m_clk, &ssi_s_clk, + &sha_clk, &aes_clk, &pke_clk, &i2c0_clk, &i2c1_clk, &trng_clk, + &i2c_s_clk, &uart0_clk, &uart1_clk, &sie_clk, &puf_clk, &ge_clk, +}; +static int rts_fp_clk_on(const struct device *dev, clock_control_subsys_t sys) +{ + uint16_t clk_id = (uint32_t)sys; + const struct clk_rlx *clk; + + if (clk_id >= RLX_CLK_NUM_SIZE) { + return -EINVAL; + } + + clk = m_clks[clk_id]; + if (!clk->ops->enable) { + return -ENOSYS; + } + + return clk->ops->enable(dev, clk); +} + +static int rts_fp_clk_off(const struct device *dev, clock_control_subsys_t sys) +{ + uint16_t clk_id = (uint32_t)sys; + const struct clk_rlx *clk; + + if (clk_id >= RLX_CLK_NUM_SIZE) { + return -EINVAL; + } + + clk = m_clks[clk_id]; + if (!clk->ops->disable) { + return -ENOSYS; + } + + return clk->ops->disable(dev, clk); +} + +static enum clock_control_status rts_fp_clk_get_status(const struct device *dev, + clock_control_subsys_t sys) +{ + uint16_t clk_id = (uint32_t)sys; + const struct clk_rlx *clk; + + if (clk_id >= RLX_CLK_NUM_SIZE) { + return -EINVAL; + } + + clk = m_clks[clk_id]; + if (!clk->ops->get_status) { + return CLOCK_CONTROL_STATUS_UNKNOWN; + } + + return clk->ops->get_status(dev, clk); +} + +static int rts_fp_clk_get_rate(const struct device *dev, clock_control_subsys_t sys, uint32_t *rate) +{ + uint16_t clk_id = (uint32_t)sys; + const struct clk_rlx *clk; + + if (clk_id >= RLX_CLK_NUM_SIZE) { + return -EINVAL; + } + + clk = m_clks[clk_id]; + if (!clk->ops->get_rate) { + return -ENOSYS; + } + + *rate = clk->ops->get_rate(dev, clk); + return 0; +} + +static int rts_fp_clk_set_rate(const struct device *dev, clock_control_subsys_t sys, + clock_control_subsys_rate_t rate) +{ + uint16_t clk_id = (uint32_t)sys; + const struct clk_rlx *clk; + + if (clk_id >= RLX_CLK_NUM_SIZE) { + return -EINVAL; + } + + clk = m_clks[clk_id]; + if (!clk->ops->set_rate) { + return -ENOSYS; + } + + return clk->ops->set_rate(dev, clk, (uint32_t)rate); +} + +static const struct clock_control_driver_api rts_fp_clk_api = { + .on = rts_fp_clk_on, + .off = rts_fp_clk_off, + .get_status = rts_fp_clk_get_status, + .get_rate = rts_fp_clk_get_rate, + .set_rate = rts_fp_clk_set_rate, +}; + +/* HACK: enable uart clock for uart_ns16550.c driver */ +static void rts_fp_clk_enable_uart(const struct device *dev) +{ + /* set uart clock source to 120MHz */ + if (DT_NODE_HAS_STATUS(DT_INST(0, ns16550), okay)) { + rts_fp_clk_write_reg(dev, 1 | 1 << 24, R_SYS_UART0_CLK_CFG_REG); + } + + if (DT_NODE_HAS_STATUS(DT_INST(1, ns16550), okay)) { + rts_fp_clk_write_reg(dev, 1 | 1 << 24, R_SYS_UART1_CLK_CFG_REG); + } +} + +static int rts_fp_clk_init(const struct device *dev) +{ + struct rts_fp_clock_data *clk_data = dev->data; + + if (syspll.ops->get_status(dev, &syspll) == CLOCK_CONTROL_STATUS_ON) { + clk_data->syspll_frequency = syspll.ops->get_rate(dev, &syspll); + } + + /* HACK: enable uart clock for uart_ns16550.c driver */ + rts_fp_clk_enable_uart(dev); + + /* set bus rate according to clock-frequency in cpu node */ + clock_control_subsys_t sys = (clock_control_subsys_t)RTS_FP_CLK_BUS; + clock_control_subsys_rate_t rate = + (clock_control_subsys_t)DT_PROP(DT_PATH(cpus, cpu_0), clock_frequency); + + rts_fp_clk_set_rate(dev, sys, rate); + + return 0; +} + +static struct rts_fp_clock_data rts_fp_clock_data = { + .syspll_frequency = 0, +}; + +static const struct rts_fp_clock_config rts_fp_clock_config = { + .base = DT_INST_REG_ADDR(0), + .syspll_base = DT_INST_REG_ADDR_BY_IDX(0, 1), + .sck_div_base = DT_INST_REG_ADDR_BY_IDX(0, 2), +}; + +DEVICE_DT_DEFINE(DT_DRV_INST(0), rts_fp_clk_init, NULL, &rts_fp_clock_data, &rts_fp_clock_config, + PRE_KERNEL_1, CONFIG_CLOCK_CONTROL_INIT_PRIORITY, &rts_fp_clk_api); diff --git a/drivers/clock_control/clock_control_rts5817_control.h b/drivers/clock_control/clock_control_rts5817_control.h new file mode 100644 index 0000000000000..f71aba7624f57 --- /dev/null +++ b/drivers/clock_control/clock_control_rts5817_control.h @@ -0,0 +1,503 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_CLOCK_CONTROL_RTS5817_CONTROL_REG_H_ +#define ZEPHYR_DRIVERS_CLOCK_CONTROL_RTS5817_CONTROL_REG_H_ + +#define SYSCLK_BASE_ADDR 0 +#define R_SYS_CLK_CHANGE (SYSCLK_BASE_ADDR + 0X0000) +#define R_SYS_BUS_CLK_CFG_REG (SYSCLK_BASE_ADDR + 0X0004) +#define R_SYS_SPI_CACHE_CLK_CFG_REG (SYSCLK_BASE_ADDR + 0X0008) +#define R_SYS_SPI_SSOR_CLK_CFG_REG (SYSCLK_BASE_ADDR + 0X000C) +#define R_SYS_SPI_SSI_M_CLK_CFG_REG (SYSCLK_BASE_ADDR + 0X0010) +#define R_SYS_SPI_SSI_S_CLK_CFG_REG (SYSCLK_BASE_ADDR + 0X0014) +#define R_SYS_SHA_CLK_CFG_REG (SYSCLK_BASE_ADDR + 0X0018) +#define R_SYS_AES_CLK_CFG_REG (SYSCLK_BASE_ADDR + 0X001C) +#define R_SYS_PKE_CLK_CFG_REG (SYSCLK_BASE_ADDR + 0X0020) +#define R_SYS_I2C_CLK_CFG_REG (SYSCLK_BASE_ADDR + 0X0024) +#define R_SYS_CK60_CFG_REG (SYSCLK_BASE_ADDR + 0X0028) +#define R_SYS_UART0_CLK_CFG_REG (SYSCLK_BASE_ADDR + 0X002C) +#define R_SYS_UART1_CLK_CFG_REG (SYSCLK_BASE_ADDR + 0X0030) +#define R_SYS_SIE_CLK_CFG_REG (SYSCLK_BASE_ADDR + 0X0034) +#define R_SYS_PUF_CLK_CFG_REG (SYSCLK_BASE_ADDR + 0X0038) + +/* Bits of R_SYS_CLK_CHANGE (0X0300) */ + +#define CHANGE_BUS_CLK_PRE_OFFSET 0 +#define CHANGE_BUS_CLK_PRE_BITS 1 +#define CHANGE_BUS_CLK_PRE_MASK (((1 << 1) - 1) << 0) +#define CHANGE_BUS_CLK_PRE (CHANGE_BUS_CLK_PRE_MASK) + +#define CHANGE_SPI_CACHE_CLK_OFFSET 1 +#define CHANGE_SPI_CACHE_CLK_BITS 1 +#define CHANGE_SPI_CACHE_CLK_MASK (((1 << 1) - 1) << 1) +#define CHANGE_SPI_CACHE_CLK (CHANGE_SPI_CACHE_CLK_MASK) + +#define CHANGE_SPI_SSOR_CLK_OFFSET 2 +#define CHANGE_SPI_SSOR_CLK_BITS 1 +#define CHANGE_SPI_SSOR_CLK_MASK (((1 << 1) - 1) << 2) +#define CHANGE_SPI_SSOR_CLK (CHANGE_SPI_SSOR_CLK_MASK) + +#define CHANGE_SPI_SSI_M_CLK_OFFSET 3 +#define CHANGE_SPI_SSI_M_CLK_BITS 1 +#define CHANGE_SPI_SSI_M_CLK_MASK (((1 << 1) - 1) << 3) +#define CHANGE_SPI_SSI_M_CLK (CHANGE_SPI_SSI_M_CLK_MASK) + +#define CHANGE_SPI_SSI_S_CLK_OFFSET 4 +#define CHANGE_SPI_SSI_S_CLK_BITS 1 +#define CHANGE_SPI_SSI_S_CLK_MASK (((1 << 1) - 1) << 4) +#define CHANGE_SPI_SSI_S_CLK (CHANGE_SPI_SSI_S_CLK_MASK) + +#define CHANGE_SHA_CLK_OFFSET 5 +#define CHANGE_SHA_CLK_BITS 1 +#define CHANGE_SHA_CLK_MASK (((1 << 1) - 1) << 5) +#define CHANGE_SHA_CLK (CHANGE_SHA_CLK_MASK) + +#define CHANGE_AES_CLK_OFFSET 6 +#define CHANGE_AES_CLK_BITS 1 +#define CHANGE_AES_CLK_MASK (((1 << 1) - 1) << 6) +#define CHANGE_AES_CLK (CHANGE_AES_CLK_MASK) + +#define CHANGE_UART0_CLK_OFFSET 7 +#define CHANGE_UART0_CLK_BITS 1 +#define CHANGE_UART0_CLK_MASK (((1 << 1) - 1) << 7) +#define CHANGE_UART0_CLK (CHANGE_UART0_CLK_MASK) + +#define CHANGE_UART1_CLK_OFFSET 8 +#define CHANGE_UART1_CLK_BITS 1 +#define CHANGE_UART1_CLK_MASK (((1 << 1) - 1) << 8) +#define CHANGE_UART1_CLK (CHANGE_UART1_CLK_MASK) + +/* Bits of R_SYS_BUS_CLK_CFG_REG (0X0304) */ + +#define BUS_CLK_SRC_SEL_OFFSET 0 +#define BUS_CLK_SRC_SEL_BITS 2 +#define BUS_CLK_SRC_SEL_MASK (((1 << 2) - 1) << 0) +#define BUS_CLK_SRC_SEL (BUS_CLK_SRC_SEL_MASK) + +#define BUS_CLK_DIV_OFFSET 2 +#define BUS_CLK_DIV_BITS 4 +#define BUS_CLK_DIV_MASK (((1 << 4) - 1) << 2) +#define BUS_CLK_DIV (BUS_CLK_DIV_MASK) + +#define BUS_CLK_NDIV_OFFSET 8 +#define BUS_CLK_NDIV_BITS 2 +#define BUS_CLK_NDIV_MASK (((1 << 2) - 1) << 8) +#define BUS_CLK_NDIV (BUS_CLK_NDIV_MASK) + +#define BUS_CLK_FDIV_OFFSET 16 +#define BUS_CLK_FDIV_BITS 6 +#define BUS_CLK_FDIV_MASK (((1 << 6) - 1) << 16) +#define BUS_CLK_FDIV (BUS_CLK_FDIV_MASK) + +#define GE_CLK_EN_OFFSET 25 +#define GE_CLK_EN_BITS 1 +#define GE_CLK_EN_MASK (((1 << 1) - 1) << 25) +#define GE_CLK_EN (GE_CLK_EN_MASK) + +/* Bits of R_SYS_SPI_CACHE_CLK_CFG_REG (0X0308) */ + +#define SPI_CACHE_CLK_SEL_OFFSET 0 +#define SPI_CACHE_CLK_SEL_BITS 2 +#define SPI_CACHE_CLK_SEL_MASK (((1 << 2) - 1) << 0) +#define SPI_CACHE_CLK_SEL (SPI_CACHE_CLK_SEL_MASK) + +#define SPI_CACHE_CLK_DIV_OFFSET 2 +#define SPI_CACHE_CLK_DIV_BITS 3 +#define SPI_CACHE_CLK_DIV_MASK (((1 << 3) - 1) << 2) +#define SPI_CACHE_CLK_DIV (SPI_CACHE_CLK_DIV_MASK) + +#define SPI_CACHE_CLK_NDIV_OFFSET 8 +#define SPI_CACHE_CLK_NDIV_BITS 2 +#define SPI_CACHE_CLK_NDIV_MASK (((1 << 2) - 1) << 8) +#define SPI_CACHE_CLK_NDIV (SPI_CACHE_CLK_NDIV_MASK) + +#define SPI_CACHE_CLK_FDIV_OFFSET 16 +#define SPI_CACHE_CLK_FDIV_BITS 6 +#define SPI_CACHE_CLK_FDIV_MASK (((1 << 6) - 1) << 16) +#define SPI_CACHE_CLK_FDIV (SPI_CACHE_CLK_FDIV_MASK) + +#define SPI_CACHE_CLK_EN_OFFSET 24 +#define SPI_CACHE_CLK_EN_BITS 1 +#define SPI_CACHE_CLK_EN_MASK (((1 << 1) - 1) << 24) +#define SPI_CACHE_CLK_EN (SPI_CACHE_CLK_EN_MASK) + +/* Bits of R_SYS_SPI_SSOR_CLK_CFG_REG (0X030C) */ + +#define SPI_SSOR_CLK_SEL_OFFSET 0 +#define SPI_SSOR_CLK_SEL_BITS 2 +#define SPI_SSOR_CLK_SEL_MASK (((1 << 2) - 1) << 0) +#define SPI_SSOR_CLK_SEL (SPI_SSOR_CLK_SEL_MASK) + +#define SPI_SSOR_CLK_DIV_OFFSET 2 +#define SPI_SSOR_CLK_DIV_BITS 3 +#define SPI_SSOR_CLK_DIV_MASK (((1 << 3) - 1) << 2) +#define SPI_SSOR_CLK_DIV (SPI_SSOR_CLK_DIV_MASK) + +#define SPI_SSOR_CLK_NDIV_OFFSET 8 +#define SPI_SSOR_CLK_NDIV_BITS 2 +#define SPI_SSOR_CLK_NDIV_MASK (((1 << 2) - 1) << 8) +#define SPI_SSOR_CLK_NDIV (SPI_SSOR_CLK_NDIV_MASK) + +#define SPI_SSOR_CLK_FDIV_OFFSET 16 +#define SPI_SSOR_CLK_FDIV_BITS 6 +#define SPI_SSOR_CLK_FDIV_MASK (((1 << 6) - 1) << 16) +#define SPI_SSOR_CLK_FDIV (SPI_SSOR_CLK_FDIV_MASK) + +#define SPI_SSOR_CLK_EN_OFFSET 24 +#define SPI_SSOR_CLK_EN_BITS 1 +#define SPI_SSOR_CLK_EN_MASK (((1 << 1) - 1) << 24) +#define SPI_SSOR_CLK_EN (SPI_SSOR_CLK_EN_MASK) + +/* Bits of R_SYS_SPI_SSI_M_CLK_CFG_REG (0X0310) */ + +#define SPI_SSI_M_CLK_SEL_OFFSET 0 +#define SPI_SSI_M_CLK_SEL_BITS 2 +#define SPI_SSI_M_CLK_SEL_MASK (((1 << 2) - 1) << 0) +#define SPI_SSI_M_CLK_SEL (SPI_SSI_M_CLK_SEL_MASK) + +#define SPI_SSI_M_CLK_DIV_OFFSET 2 +#define SPI_SSI_M_CLK_DIV_BITS 3 +#define SPI_SSI_M_CLK_DIV_MASK (((1 << 3) - 1) << 2) +#define SPI_SSI_M_CLK_DIV (SPI_SSI_M_CLK_DIV_MASK) + +#define SPI_SSI_M_CLK_NDIV_OFFSET 8 +#define SPI_SSI_M_CLK_NDIV_BITS 2 +#define SPI_SSI_M_CLK_NDIV_MASK (((1 << 2) - 1) << 8) +#define SPI_SSI_M_CLK_NDIV (SPI_SSI_M_CLK_NDIV_MASK) + +#define SPI_SSI_M_CLK_FDIV_OFFSET 16 +#define SPI_SSI_M_CLK_FDIV_BITS 6 +#define SPI_SSI_M_CLK_FDIV_MASK (((1 << 6) - 1) << 16) +#define SPI_SSI_M_CLK_FDIV (SPI_SSI_M_CLK_FDIV_MASK) + +#define SPI_SSI_M_CLK_EN_OFFSET 24 +#define SPI_SSI_M_CLK_EN_BITS 1 +#define SPI_SSI_M_CLK_EN_MASK (((1 << 1) - 1) << 24) +#define SPI_SSI_M_CLK_EN (SPI_SSI_M_CLK_EN_MASK) + +/* Bits of R_SYS_SPI_SSI_S_CLK_CFG_REG (0X0314) */ + +#define SPI_SSI_S_CLK_SEL_OFFSET 0 +#define SPI_SSI_S_CLK_SEL_BITS 2 +#define SPI_SSI_S_CLK_SEL_MASK (((1 << 2) - 1) << 0) +#define SPI_SSI_S_CLK_SEL (SPI_SSI_S_CLK_SEL_MASK) + +#define SPI_SSI_S_CLK_DIV_OFFSET 2 +#define SPI_SSI_S_CLK_DIV_BITS 3 +#define SPI_SSI_S_CLK_DIV_MASK (((1 << 3) - 1) << 2) +#define SPI_SSI_S_CLK_DIV (SPI_SSI_S_CLK_DIV_MASK) + +#define SPI_SSI_S_CLK_NDIV_OFFSET 8 +#define SPI_SSI_S_CLK_NDIV_BITS 2 +#define SPI_SSI_S_CLK_NDIV_MASK (((1 << 2) - 1) << 8) +#define SPI_SSI_S_CLK_NDIV (SPI_SSI_S_CLK_NDIV_MASK) + +#define SPI_SSI_S_CLK_FDIV_OFFSET 16 +#define SPI_SSI_S_CLK_FDIV_BITS 6 +#define SPI_SSI_S_CLK_FDIV_MASK (((1 << 6) - 1) << 16) +#define SPI_SSI_S_CLK_FDIV (SPI_SSI_S_CLK_FDIV_MASK) + +#define SPI_SSI_S_CLK_EN_OFFSET 24 +#define SPI_SSI_S_CLK_EN_BITS 1 +#define SPI_SSI_S_CLK_EN_MASK (((1 << 1) - 1) << 24) +#define SPI_SSI_S_CLK_EN (SPI_SSI_S_CLK_EN_MASK) + +/* Bits of R_SYS_SHA_CLK_CFG_REG (0X0318) */ + +#define SHA_CLK_SEL_OFFSET 0 +#define SHA_CLK_SEL_BITS 2 +#define SHA_CLK_SEL_MASK (((1 << 2) - 1) << 0) +#define SHA_CLK_SEL (SHA_CLK_SEL_MASK) + +#define SHA_CLK_DIV_OFFSET 2 +#define SHA_CLK_DIV_BITS 3 +#define SHA_CLK_DIV_MASK (((1 << 3) - 1) << 2) +#define SHA_CLK_DIV (SHA_CLK_DIV_MASK) + +#define SHA_CLK_NDIV_OFFSET 8 +#define SHA_CLK_NDIV_BITS 2 +#define SHA_CLK_NDIV_MASK (((1 << 2) - 1) << 8) +#define SHA_CLK_NDIV (SHA_CLK_NDIV_MASK) + +#define SHA_CLK_FDIV_OFFSET 16 +#define SHA_CLK_FDIV_BITS 6 +#define SHA_CLK_FDIV_MASK (((1 << 6) - 1) << 16) +#define SHA_CLK_FDIV (SHA_CLK_FDIV_MASK) + +#define SHA_CLK_EN_OFFSET 24 +#define SHA_CLK_EN_BITS 1 +#define SHA_CLK_EN_MASK (((1 << 1) - 1) << 24) +#define SHA_CLK_EN (SHA_CLK_EN_MASK) + +/* Bits of R_SYS_AES_CLK_CFG_REG (0X031C) */ + +#define AES_CLK_SEL_OFFSET 0 +#define AES_CLK_SEL_BITS 2 +#define AES_CLK_SEL_MASK (((1 << 2) - 1) << 0) +#define AES_CLK_SEL (AES_CLK_SEL_MASK) + +#define AES_CLK_DIV_OFFSET 2 +#define AES_CLK_DIV_BITS 3 +#define AES_CLK_DIV_MASK (((1 << 3) - 1) << 2) +#define AES_CLK_DIV (AES_CLK_DIV_MASK) + +#define AES_CLK_NDIV_OFFSET 8 +#define AES_CLK_NDIV_BITS 2 +#define AES_CLK_NDIV_MASK (((1 << 2) - 1) << 8) +#define AES_CLK_NDIV (AES_CLK_NDIV_MASK) + +#define AES_CLK_FDIV_OFFSET 16 +#define AES_CLK_FDIV_BITS 6 +#define AES_CLK_FDIV_MASK (((1 << 6) - 1) << 16) +#define AES_CLK_FDIV (AES_CLK_FDIV_MASK) + +#define AES_CLK_EN_OFFSET 24 +#define AES_CLK_EN_BITS 1 +#define AES_CLK_EN_MASK (((1 << 1) - 1) << 24) +#define AES_CLK_EN (AES_CLK_EN_MASK) + +/* Bits of R_SYS_PKE_CLK_CFG_REG (0X0320) */ + +#define PKE_CLK_DIV_OFFSET 2 +#define PKE_CLK_DIV_BITS 3 +#define PKE_CLK_DIV_MASK (((1 << 3) - 1) << 2) +#define PKE_CLK_DIV (PKE_CLK_DIV_MASK) + +#define PKE_CLK_NDIV_OFFSET 8 +#define PKE_CLK_NDIV_BITS 2 +#define PKE_CLK_NDIV_MASK (((1 << 2) - 1) << 8) +#define PKE_CLK_NDIV (PKE_CLK_NDIV_MASK) + +#define PKE_CLK_FDIV_OFFSET 16 +#define PKE_CLK_FDIV_BITS 6 +#define PKE_CLK_FDIV_MASK (((1 << 6) - 1) << 16) +#define PKE_CLK_FDIV (PKE_CLK_FDIV_MASK) + +#define PKE_CLK_EN_OFFSET 24 +#define PKE_CLK_EN_BITS 1 +#define PKE_CLK_EN_MASK (((1 << 1) - 1) << 24) +#define PKE_CLK_EN (PKE_CLK_EN_MASK) + +/* Bits of R_SYS_I2C_CLK_CFG_REG (0X0324) */ + +#define I2C_CLK_DIV_OFFSET 2 +#define I2C_CLK_DIV_BITS 3 +#define I2C_CLK_DIV_MASK (((1 << 3) - 1) << 2) +#define I2C_CLK_DIV (I2C_CLK_DIV_MASK) + +#define I2C_CLK_NDIV_OFFSET 8 +#define I2C_CLK_NDIV_BITS 2 +#define I2C_CLK_NDIV_MASK (((1 << 2) - 1) << 8) +#define I2C_CLK_NDIV (I2C_CLK_NDIV_MASK) + +#define I2C_CLK_FDIV_OFFSET 16 +#define I2C_CLK_FDIV_BITS 6 +#define I2C_CLK_FDIV_MASK (((1 << 6) - 1) << 16) +#define I2C_CLK_FDIV (I2C_CLK_FDIV_MASK) + +#define I2C_CLK_EN_OFFSET 24 +#define I2C_CLK_EN_BITS 1 +#define I2C_CLK_EN_MASK (((1 << 1) - 1) << 24) +#define I2C_CLK_EN (I2C_CLK_EN_MASK) + +#define I2C0_CLK_EN_OFFSET 25 +#define I2C0_CLK_EN_BITS 1 +#define I2C0_CLK_EN_MASK (((1 << 1) - 1) << 25) +#define I2C0_CLK_EN (I2C0_CLK_EN_MASK) + +#define I2C1_CLK_EN_OFFSET 26 +#define I2C1_CLK_EN_BITS 1 +#define I2C1_CLK_EN_MASK (((1 << 1) - 1) << 26) +#define I2C1_CLK_EN (I2C1_CLK_EN_MASK) + +/* Bits of R_SYS_CK60_CFG_REG (0X0328) */ + +#define I2C_S_CLK_EN_OFFSET 24 +#define I2C_S_CLK_EN_BITS 1 +#define I2C_S_CLK_EN_MASK (((1 << 1) - 1) << 24) +#define I2C_S_CLK_EN (I2C_S_CLK_EN_MASK) + +#define TRNG_CLK_EN_OFFSET 25 +#define TRNG_CLK_EN_BITS 1 +#define TRNG_CLK_EN_MASK (((1 << 1) - 1) << 25) +#define TRNG_CLK_EN (TRNG_CLK_EN_MASK) + +/* Bits of R_SYS_UART0_CLK_CFG_REG (0X032C) */ + +#define UART0_CLK_SEL_OFFSET 0 +#define UART0_CLK_SEL_BITS 2 +#define UART0_CLK_SEL_MASK (((1 << 2) - 1) << 0) +#define UART0_CLK_SEL (UART0_CLK_SEL_MASK) + +#define UART0_CLK_DIV_OFFSET 2 +#define UART0_CLK_DIV_BITS 3 +#define UART0_CLK_DIV_MASK (((1 << 3) - 1) << 2) +#define UART0_CLK_DIV (UART0_CLK_DIV_MASK) + +#define UART0_CLK_NDIV_OFFSET 8 +#define UART0_CLK_NDIV_BITS 2 +#define UART0_CLK_NDIV_MASK (((1 << 2) - 1) << 8) +#define UART0_CLK_NDIV (UART0_CLK_NDIV_MASK) + +#define UART0_CLK_FDIV_OFFSET 16 +#define UART0_CLK_FDIV_BITS 6 +#define UART0_CLK_FDIV_MASK (((1 << 6) - 1) << 16) +#define UART0_CLK_FDIV (UART0_CLK_FDIV_MASK) + +#define UART0_CLK_EN_OFFSET 24 +#define UART0_CLK_EN_BITS 1 +#define UART0_CLK_EN_MASK (((1 << 1) - 1) << 24) +#define UART0_CLK_EN (UART0_CLK_EN_MASK) + +/* Bits of R_SYS_UART1_CLK_CFG_REG (0X0330) */ + +#define UART1_CLK_SEL_OFFSET 0 +#define UART1_CLK_SEL_BITS 2 +#define UART1_CLK_SEL_MASK (((1 << 2) - 1) << 0) +#define UART1_CLK_SEL (UART1_CLK_SEL_MASK) + +#define UART1_CLK_DIV_OFFSET 2 +#define UART1_CLK_DIV_BITS 3 +#define UART1_CLK_DIV_MASK (((1 << 3) - 1) << 2) +#define UART1_CLK_DIV (UART1_CLK_DIV_MASK) + +#define UART1_CLK_NDIV_OFFSET 8 +#define UART1_CLK_NDIV_BITS 2 +#define UART1_CLK_NDIV_MASK (((1 << 2) - 1) << 8) +#define UART1_CLK_NDIV (UART1_CLK_NDIV_MASK) + +#define UART1_CLK_FDIV_OFFSET 16 +#define UART1_CLK_FDIV_BITS 6 +#define UART1_CLK_FDIV_MASK (((1 << 6) - 1) << 16) +#define UART1_CLK_FDIV (UART1_CLK_FDIV_MASK) + +#define UART1_CLK_EN_OFFSET 24 +#define UART1_CLK_EN_BITS 1 +#define UART1_CLK_EN_MASK (((1 << 1) - 1) << 24) +#define UART1_CLK_EN (UART1_CLK_EN_MASK) + +/* Bits of R_SYS_SIE_CLK_CFG_REG (0X0334) */ + +#define SIE_CLK_EN_OFFSET 24 +#define SIE_CLK_EN_BITS 1 +#define SIE_CLK_EN_MASK (((1 << 1) - 1) << 24) +#define SIE_CLK_EN (SIE_CLK_EN_MASK) + +/* Bits of R_SYS_PUF_CLK_CFG_REG (0X0338) */ + +#define PUF_CLK_EN_OFFSET 24 +#define PUF_CLK_EN_BITS 1 +#define PUF_CLK_EN_MASK (((1 << 1) - 1) << 24) +#define PUF_CLK_EN (PUF_CLK_EN_MASK) + +/* Parameters definition */ + +/* Parameters of R_SYS_BUS_CLK_CFG_REG (0x0304) */ +#define BUS_CLK_240M 0x0 +#define BUS_CLK_160M 0x1 +#define BUS_CLK_96M 0x2 +#define BUS_CLK_GPLL0 0x3 + +#define BUS_CLK_DIV_1 0x0 +#define BUS_CLK_DIV_2 0x1 +#define BUS_CLK_DIV_4 0x2 +#define BUS_CLK_DIV_6 0x3 + +/* Parameters of R_SYS_SPI_CACHE_CLK_CFG_REG (0X0308)*/ +#define SPI_CACHE_CLK_240M 0x0 +#define SPI_CACHE_CLK_160M 0x1 +#define SPI_CACHE_CLK_96M 0x2 +#define SPI_CACHE_CLK_GPLL0 0x3 + +#define SPI_CACHE_CLK_DIV_1 0x0 +#define SPI_CACHE_CLK_DIV_2 0x1 +#define SPI_CACHE_CLK_DIV_4 0x2 +#define SPI_CACHE_CLK_DIV_6 0x3 + +/* Parameters of R_SYS_SPI_SSOR_CLK_CFG_REG (0X030C) */ +#define SPI_SSOR_CLK_240M 0x0 +#define SPI_SSOR_CLK_96M 0x1 +#define SPI_SSOR_CLK_80M 0x2 +#define SPI_SSOR_CLK_GPLL0 0x3 + +#define SPI_SSOR_CLK_DIV_1 0x0 +#define SPI_SSOR_CLK_DIV_2 0x1 +#define SPI_SSOR_CLK_DIV_4 0x2 +#define SPI_SSOR_CLK_DIV_6 0x3 + +/* Parameters of R_SYS_SPI_SSI_M_CLK_CFG_REG (0X0310) */ +#define SPI_SSI_MST_CLK_240M 0x0 +#define SPI_SSI_MST_CLK_96M 0x1 +#define SPI_SSI_MST_CLK_80M 0x2 +#define SPI_SSI_MST_CLK_GPLL0 0x3 + +#define SPI_SSI_MST_CLK_DIV_1 0x0 +#define SPI_SSI_MST_CLK_DIV_2 0x1 +#define SPI_SSI_MST_CLK_DIV_4 0x2 +#define SPI_SSI_MST_CLK_DIV_6 0x3 + +/* Parameters of R_SYS_SPI_SSI_S_CLK_CFG_REG (0X0314) */ +#define SPI_SSI_SLV_CLK_240M 0x0 +#define SPI_SSI_SLV_CLK_96M 0x1 +#define SPI_SSI_SLV_CLK_80M 0x2 +#define SPI_SSI_SLV_CLK_GPLL0 0x3 + +#define SPI_SSI_SLV_CLK_DIV_1 0x0 +#define SPI_SSI_SLV_CLK_DIV_2 0x1 +#define SPI_SSI_SLV_CLK_DIV_4 0x2 +#define SPI_SSI_SLV_CLK_DIV_6 0x3 + +/* Parameters of R_SYS_SHA_CLK_CFG_REG (0X0318) */ +#define SHA_CLK_240M 0x0 +#define SHA_CLK_160M 0x1 +#define SHA_CLK_96M 0x2 +#define SHA_CLK_GPLL0 0x3 + +#define SHA_CLK_DIV_1 0x0 +#define SHA_CLK_DIV_2 0x1 +#define SHA_CLK_DIV_4 0x2 +#define SHA_CLK_DIV_6 0x3 + +/* Parameters of R_SYS_AES_CLK_CFG_REG (0X031C) */ +#define AES_CLK_240M 0x0 +#define AES_CLK_160M 0x1 +#define AES_CLK_96M 0x2 +#define AES_CLK_GPLL0 0x3 + +#define AES_CLK_DIV_1 0x0 +#define AES_CLK_DIV_2 0x1 +#define AES_CLK_DIV_4 0x2 +#define AES_CLK_DIV_6 0x3 + +/* Parameters of R_SYS_I2C_CLK_CFG_REG (0X0324) */ +#define I2C_CLK_DIV_1 0x0 +#define I2C_CLK_DIV_2 0x1 +#define I2C_CLK_DIV_4 0x2 +#define I2C_CLK_DIV_6 0x3 + +/* Parameters of R_SYS_UARTx_CLK_CFG_REG (0X032C 0X330) */ +#define UART_CLK_96M 0x0 +#define UART_CLK_120M 0x1 +#define UART_CLK_GPLL0 0x3 + +#define UART_CLK_DIV_1 0x0 +#define UART_CLK_DIV_2 0x1 +#define UART_CLK_DIV_4 0x2 +#define UART_CLK_DIV_6 0x3 + +/***********************Definition created by FW**********************/ +#define SENSOR_SPI_CLK_SEL_240M 0x00 +#define SENSOR_SPI_CLK_SEL_96M 0x01 +#define SENSOR_SPI_CLK_SEL_80M 0x02 +#define SENSOR_SPI_CLK_SEL_SYSPLL 0x03 + +#define SSI_SPI_MST_CLK_SEL_240M 0x00 +#define SSI_SPI_MST_CLK_SEL_96M 0x01 +#define SSI_SPI_MST_CLK_SEL_80M 0x02 +#define SSI_SPI_MST_CLK_SEL_SYSPLL 0x03 + +#endif /* ZEPHYR_DRIVERS_CLOCK_CONTROL_RTS5817_CONTROL_REG_H_ */ diff --git a/drivers/clock_control/clock_control_rts5817_gpll.h b/drivers/clock_control/clock_control_rts5817_gpll.h new file mode 100644 index 0000000000000..1c21d7bb446de --- /dev/null +++ b/drivers/clock_control/clock_control_rts5817_gpll.h @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_CLOCK_CONTROL_RTS5817_GPLL_REG_H_ +#define ZEPHYR_DRIVERS_CLOCK_CONTROL_RTS5817_GPLL_REG_H_ + +#define GPLL_SSCG_BASE_ADDR 0 +#define R_SYSPLL_CFG (GPLL_SSCG_BASE_ADDR + 0X0000) +#define R_SYSPLL_NF_CODE (GPLL_SSCG_BASE_ADDR + 0X0004) +#define R_SYSPLL_CTL (GPLL_SSCG_BASE_ADDR + 0X0008) +#define R_SYSPLL_STS (GPLL_SSCG_BASE_ADDR + 0X000C) + +/* Bits of R_SYSPLL_CFG (0X0000) */ + +#define PLL_ORDER_OFFSET 0 +#define PLL_ORDER_BITS 1 +#define PLL_ORDER_MASK (((1 << 1) - 1) << 0) +#define PLL_ORDER (PLL_ORDER_MASK) + +#define PLL_BYPASS_PI_OFFSET 1 +#define PLL_BYPASS_PI_BITS 1 +#define PLL_BYPASS_PI_MASK (((1 << 1) - 1) << 1) +#define PLL_BYPASS_PI (PLL_BYPASS_PI_MASK) + +#define PLL_REG_CCO_BIG_KVCO_OFFSET 2 +#define PLL_REG_CCO_BIG_KVCO_BITS 1 +#define PLL_REG_CCO_BIG_KVCO_MASK (((1 << 1) - 1) << 2) +#define PLL_REG_CCO_BIG_KVCO (PLL_REG_CCO_BIG_KVCO_MASK) + +#define PLL_REG_CCO_SEL_OFFSET 3 +#define PLL_REG_CCO_SEL_BITS 1 +#define PLL_REG_CCO_SEL_MASK (((1 << 1) - 1) << 3) +#define PLL_REG_CCO_SEL (PLL_REG_CCO_SEL_MASK) + +#define PLL_REG_CP_OFFSET 4 +#define PLL_REG_CP_BITS 3 +#define PLL_REG_CP_MASK (((1 << 3) - 1) << 4) +#define PLL_REG_CP (PLL_REG_CP_MASK) + +#define REG_EN_DCP_OFFSET 7 +#define REG_EN_DCP_BITS 1 +#define REG_EN_DCP_MASK (((1 << 1) - 1) << 7) +#define REG_EN_DCP (REG_EN_DCP_MASK) + +#define REG_PI_BIAS_OFFSET 8 +#define REG_PI_BIAS_BITS 2 +#define REG_PI_BIAS_MASK (((1 << 2) - 1) << 8) +#define REG_PI_BIAS (REG_PI_BIAS_MASK) + +#define PLL_REG_PI_CAP_OFFSET 10 +#define PLL_REG_PI_CAP_BITS 2 +#define PLL_REG_PI_CAP_MASK (((1 << 2) - 1) << 10) +#define PLL_REG_PI_CAP (PLL_REG_PI_CAP_MASK) + +#define REG_PI_EN_OFFSET 12 +#define REG_PI_EN_BITS 3 +#define REG_PI_EN_MASK (((1 << 3) - 1) << 12) +#define REG_PI_EN (REG_PI_EN_MASK) + +#define PLL_REG_PI_SEL_OFFSET 15 +#define PLL_REG_PI_SEL_BITS 1 +#define PLL_REG_PI_SEL_MASK (((1 << 1) - 1) << 15) +#define PLL_REG_PI_SEL (PLL_REG_PI_SEL_MASK) + +#define REG_SD_OFFSET 16 +#define REG_SD_BITS 2 +#define REG_SD_MASK (((1 << 2) - 1) << 16) +#define REG_SD (REG_SD_MASK) + +#define PLL_REG_SEL_VLDO_OFFSET 18 +#define PLL_REG_SEL_VLDO_BITS 2 +#define PLL_REG_SEL_VLDO_MASK (((1 << 2) - 1) << 18) +#define PLL_REG_SEL_VLDO (PLL_REG_SEL_VLDO_MASK) + +#define REG_SR_H_OFFSET 20 +#define REG_SR_H_BITS 3 +#define REG_SR_H_MASK (((1 << 3) - 1) << 20) +#define REG_SR_H (REG_SR_H_MASK) + +#define PLL_REG_EN_NEW_OFFSET 23 +#define PLL_REG_EN_NEW_BITS 1 +#define PLL_REG_EN_NEW_MASK (((1 << 1) - 1) << 23) +#define PLL_REG_EN_NEW (PLL_REG_EN_NEW_MASK) + +#define REG_SC_H_OFFSET 24 +#define REG_SC_H_BITS 1 +#define REG_SC_H_MASK (((1 << 1) - 1) << 24) +#define REG_SC_H (REG_SC_H_MASK) + +/* Bits of R_SYSPLL_NF_CODE (0X0004) */ + +#define N_SSC_OFFSET 0 +#define N_SSC_BITS 9 +#define N_SSC_MASK (((1 << 9) - 1) << 0) +#define N_SSC (N_SSC_MASK) + +#define F_SSC_OFFSET 16 +#define F_SSC_BITS 12 +#define F_SSC_MASK (((1 << 12) - 1) << 16) +#define F_SSC (F_SSC_MASK) + +/* Bits of R_SYSPLL_CTL (0X0008) */ + +#define POW_SYSPLL_OFFSET 0 +#define POW_SYSPLL_BITS 1 +#define POW_SYSPLL_MASK (((1 << 1) - 1) << 0) +#define POW_SYSPLL (POW_SYSPLL_MASK) + +#define PLL_LOAD_EN_OFFSET 1 +#define PLL_LOAD_EN_BITS 1 +#define PLL_LOAD_EN_MASK (((1 << 1) - 1) << 1) +#define PLL_LOAD_EN (PLL_LOAD_EN_MASK) + +#define SYSPLL_REF_SEL_OFFSET 2 +#define SYSPLL_REF_SEL_BITS 1 +#define SYSPLL_REF_SEL_MASK (((1 << 1) - 1) << 2) +#define SYSPLL_REF_SEL (SYSPLL_REF_SEL_MASK) + +/* Bits of R_SYSPLL_STS (0X000C) */ + +#define PLL_CLK_TFBAK_OFFSET 0 +#define PLL_CLK_TFBAK_BITS 1 +#define PLL_CLK_TFBAK_MASK (((1 << 1) - 1) << 0) +#define PLL_CLK_TFBAK (PLL_CLK_TFBAK_MASK) + +#define PLL_CKUSABLE_OFFSET 1 +#define PLL_CKUSABLE_BITS 1 +#define PLL_CKUSABLE_MASK (((1 << 1) - 1) << 1) +#define PLL_CKUSABLE (PLL_CKUSABLE_MASK) + +#endif /* ZEPHYR_DRIVERS_CLOCK_CONTROL_RTS5817_GPLL_REG_H_ */ diff --git a/drivers/pinctrl/CMakeLists.txt b/drivers/pinctrl/CMakeLists.txt index bb302e9c94cfd..127fdb0b8f0cf 100644 --- a/drivers/pinctrl/CMakeLists.txt +++ b/drivers/pinctrl/CMakeLists.txt @@ -57,5 +57,6 @@ zephyr_library_sources_ifdef(CONFIG_PINCTRL_SY1XX pinctrl_sy1xx.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_REALTEK_RTS5912 pinctrl_realtek_rts5912.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_WCH_20X_30X_AFIO pinctrl_wch_20x_30x_afio.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_WCH_00X_AFIO pinctrl_wch_00x_afio.c) +zephyr_library_sources_ifdef(CONFIG_PINCTRL_RTS5817 pinctrl_rts5817.c) add_subdirectory(renesas) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index e13c4e427ff71..5a08cae192c0b 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -82,6 +82,7 @@ source "drivers/pinctrl/Kconfig.sy1xx" source "drivers/pinctrl/Kconfig.realtek_rts5912" source "drivers/pinctrl/Kconfig.wch_20x_30x_afio" source "drivers/pinctrl/Kconfig.wch_00x_afio" +source "drivers/pinctrl/Kconfig.rts5817" rsource "renesas/Kconfig" diff --git a/drivers/pinctrl/Kconfig.rts5817 b/drivers/pinctrl/Kconfig.rts5817 new file mode 100644 index 0000000000000..a8087d57f005d --- /dev/null +++ b/drivers/pinctrl/Kconfig.rts5817 @@ -0,0 +1,9 @@ +# Copyright (c) 2024 Realtek Semiconductor, Inc. +# SPDX-License-Identifier: Apache-2.0 + +config PINCTRL_RTS5817 + bool "RTS5817 pin controller driver" + default y + depends on DT_HAS_REALTEK_RTS5817_PINCTRL_ENABLED + help + Enable driver for RTS5817 pin controller. diff --git a/drivers/pinctrl/pinctrl_rts5817.c b/drivers/pinctrl/pinctrl_rts5817.c new file mode 100644 index 0000000000000..cffc257fa1ca6 --- /dev/null +++ b/drivers/pinctrl/pinctrl_rts5817.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include "pinctrl_rts5817.h" + +#define PAD_CFG_SIZE 0x40 + +static void pinctrl_configure_pin(pinctrl_soc_pin_t pincfg) +{ + uint32_t base; + uint32_t value; + uint8_t h3l1 = pincfg.power_source & BIT(0); + uint8_t iev18 = (pincfg.power_source & BIT(1)) >> 1; + + if (pincfg.pin >= RTS_FP_PIN_AL0 && pincfg.pin <= RTS_FP_PIN_AL2) { + base = DT_REG_ADDR_BY_IDX(DT_NODELABEL(pinctrl), 1); + + value = sys_read32(base); + + value &= ~((0x1 << (pincfg.pin - RTS_FP_PIN_AL0 + AL_GPIO_PU_CTRL_OFFSET)) | + (0x1 << (pincfg.pin - RTS_FP_PIN_AL0 + AL_GPIO_PD_CTRL_OFFSET)) | + (0x1 << (pincfg.pin - RTS_FP_PIN_AL0 + AL_GPIO_SEL_OFFSET))); + + if (pincfg.pin == RTS_FP_PIN_AL0) { + value &= ~(1 << CS1_BRIDGE_EN_OFFSET); + } + + if (pincfg.pin == RTS_FP_PIN_AL0 && pincfg.func == RTS_FP_PIN_FUNC2) { + value |= (1 << CS1_BRIDGE_EN_OFFSET); + } else { + value |= + (pincfg.func << (pincfg.pin - RTS_FP_PIN_AL0 + AL_GPIO_SEL_OFFSET)); + } + + value |= (pincfg.pulldown + << (pincfg.pin - RTS_FP_PIN_AL0 + AL_GPIO_PD_CTRL_OFFSET)) | + (pincfg.pullup << (pincfg.pin - RTS_FP_PIN_AL0 + AL_GPIO_PU_CTRL_OFFSET)); + + sys_write32(value, base); + } else if (pincfg.pin >= RTS_FP_PIN_SNR_RST && pincfg.pin <= RTS_FP_PIN_SNR_CS) { + base = DT_REG_ADDR_BY_IDX(DT_NODELABEL(pinctrl), 2) + + (pincfg.pin - RTS_FP_PIN_SNR_RST) * 0x4; + + value = sys_read32(base); + + value &= ~(SENSOR_SCS_N_SEL_MASK | SENSOR_SCS_N_PDE_MASK | SENSOR_SCS_N_PUE_MASK | + SENSOR_SCS_N_H3L1_MASK | SENSOR_SCS_N_IEV18_MASK); + + value |= (pincfg.func << SENSOR_SCS_N_SEL_OFFSET) | + (pincfg.pulldown << SENSOR_SCS_N_PDE_OFFSET) | + (pincfg.pullup << SENSOR_SCS_N_PUE_OFFSET) | + (h3l1 << SENSOR_SCS_N_H3L1_OFFSET) | (iev18 << SENSOR_SCS_N_IEV18_OFFSET); + + sys_write32(value, base); + } else if (pincfg.pin == RTS_FP_PIN_SNR_GPIO) { + base = DT_REG_ADDR_BY_IDX(DT_NODELABEL(pinctrl), 2) + 0xC; + + value = sys_read32(base); + + value &= ~(GPIO_SVIO_PULLCTL_MASK | GPIO_SVIO_IEV18_MASK | GPIO_SVIO_H3L1_MASK); + + value |= (pincfg.pulldown << GPIO_SVIO_PULLCTL_OFFSET) | + (pincfg.pullup << (GPIO_SVIO_PULLCTL_OFFSET + 1)) | + (iev18 << GPIO_SVIO_IEV18_OFFSET) | (h3l1 << GPIO_SVIO_H3L1_OFFSET); + + sys_write32(value, base); + } else { + base = DT_REG_ADDR(DT_NODELABEL(pinctrl)) + pincfg.pin * PAD_CFG_SIZE; + + value = sys_read32(base + PAD_CFG); + value &= ~(GPIO_FUNCTION_SEL_MASK | IEV18_MASK | H3L1_MASK | PU_MASK | PD_MASK); + value |= (((1 << pincfg.func) << GPIO_FUNCTION_SEL_OFFSET) | + (pincfg.pulldown << PD_OFFSET) | (pincfg.pullup << PU_OFFSET) | + (iev18 << IEV18_OFFSET) | (h3l1 << H3L1_OFFSET)); + + if (pincfg.pin == RTS_FP_PIN_CACHE_CS2) { + sys_write32(0x1, base + PAD_GPIO_INC); + } + + sys_write32(value, base); + } +} + +int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg) +{ + ARG_UNUSED(reg); + + for (int i = 0; i < pin_cnt; i++) { + pinctrl_configure_pin(pins[i]); + } + + return 0; +} diff --git a/drivers/pinctrl/pinctrl_rts5817.h b/drivers/pinctrl/pinctrl_rts5817.h new file mode 100644 index 0000000000000..4e10b4d2248eb --- /dev/null +++ b/drivers/pinctrl/pinctrl_rts5817.h @@ -0,0 +1,454 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_PINCTRL_RTS5817_REG_H_ +#define ZEPHYR_DRIVERS_PINCTRL_RTS5817_REG_H_ + +#define PAD_BASE_ADDR 0x0 + +#define PAD_CFG (PAD_BASE_ADDR + 0X0000) +#define PAD_GPIO_O (PAD_BASE_ADDR + 0X0004) +#define PAD_GPIO_OE (PAD_BASE_ADDR + 0X0008) +#define PAD_GPIO_I (PAD_BASE_ADDR + 0X000C) +#define PAD_GPIO_INC (PAD_BASE_ADDR + 0X0010) +#define PAD_GPIO_INT_EN (PAD_BASE_ADDR + 0X0010) +#define PAD_GPIO_INT (PAD_BASE_ADDR + 0X0014) + +#define SP_BASE0 0x0 +#define AL_GPIO_VALUE (SP_BASE0 + 0X0000) +#define AL_GPIO_CFG (SP_BASE0 + 0X0004) +#define AL_GPIO_IRQ_EN (SP_BASE0 + 0X0008) +#define AL_GPIO_IRQ (SP_BASE0 + 0X000C) +#define AL_SENSOR_RST_CTL (SP_BASE0 + 0X0010) +#define AL_SENSOR_SCS_N_CTL (SP_BASE0 + 0X0014) +#define FW_WAKEUP_TRIG (SP_BASE0 + 0X0018) +#define GPIO_SVIO_CFG (SP_BASE0 + 0X001C) + +#define SP_BASE1 0x0 +#define SENSOR_INT_CFG (SP_BASE1 + 0X0000) +#define SENSOR_INT_FLAG (SP_BASE1 + 0X0004) + +/* Bits of PAD_CFG (0X0000) */ + +#define PD_OFFSET 0 +#define PD_BITS 1 +#define PD_MASK (((1 << 1) - 1) << 0) +#define PD (PD_MASK) + +#define PU_OFFSET 1 +#define PU_BITS 1 +#define PU_MASK (((1 << 1) - 1) << 1) +#define PU (PU_MASK) + +#define H3L1_OFFSET 2 +#define H3L1_BITS 1 +#define H3L1_MASK (((1 << 1) - 1) << 2) +#define H3L1 (H3L1_MASK) + +#define DRIVING_OFFSET 3 +#define DRIVING_BITS 2 +#define DRIVING_MASK (((1 << 2) - 1) << 3) +#define DRIVING (DRIVING_MASK) + +#define SHDN_OFFSET 5 +#define SHDN_BITS 1 +#define SHDN_MASK (((1 << 1) - 1) << 5) +#define SHDN (SHDN_MASK) + +#define IEV18_OFFSET 6 +#define IEV18_BITS 1 +#define IEV18_MASK (((1 << 1) - 1) << 6) +#define IEV18 (IEV18_MASK) + +#define PAD_FUNCTION_SEL_OFFSET 8 +#define PAD_FUNCTION_SEL_BITS 2 +#define PAD_FUNCTION_SEL_MASK (((1 << 2) - 1) << 8) +#define PAD_FUNCTION_SEL (PAD_FUNCTION_SEL_MASK) + +#define GPIO_FUNCTION_SEL_OFFSET 8 +#define GPIO_FUNCTION_SEL_BITS 6 +#define GPIO_FUNCTION_SEL_MASK (((1 << 6) - 1) << 8) +#define GPIO_FUNCTION_SEL (GPIO_FUNCTION_SEL_MASK) + +/* Bits of PAD_GPIO_O (0X0004) */ + +#define GPIO_O_OFFSET 0 +#define GPIO_O_BITS 1 +#define GPIO_O_MASK (((1 << 1) - 1) << 0) +#define GPIO_O (GPIO_O_MASK) + +/* Bits of PAD_GPIO_OE (0X0008) */ + +#define GPIO_OE_OFFSET 0 +#define GPIO_OE_BITS 1 +#define GPIO_OE_MASK (((1 << 1) - 1) << 0) +#define GPIO_OE (GPIO_OE_MASK) + +/* Bits of PAD_GPIO_I (0X000C) */ + +#define GPIO_I_OFFSET 0 +#define GPIO_I_BITS 1 +#define GPIO_I_MASK (((1 << 1) - 1) << 0) +#define GPIO_I (GPIO_I_MASK) + +/* Bits of PAD_GPIO_INT_EN (0X0010) */ + +#define GPIO_FALLING_INT_EN_OFFSET 0 +#define GPIO_FALLING_INT_EN_BITS 1 +#define GPIO_FALLING_INT_EN_MASK (((1 << 1) - 1) << 0) +#define GPIO_FALLING_INT_EN (GPIO_FALLING_INT_EN_MASK) + +#define GPIO_RISING_INT_EN_OFFSET 1 +#define GPIO_RISING_INT_EN_BITS 1 +#define GPIO_RISING_INT_EN_MASK (((1 << 1) - 1) << 1) +#define GPIO_RISING_INT_EN (GPIO_RISING_INT_EN_MASK) + +/* Bits of PAD_GPIO_INT (0X0014) */ + +#define GPIO_FALLING_INT_OFFSET 0 +#define GPIO_FALLING_INT_BITS 1 +#define GPIO_FALLING_INT_MASK (((1 << 1) - 1) << 0) +#define GPIO_FALLING_INT (GPIO_FALLING_INT_MASK) + +#define GPIO_RISING_INT_OFFSET 1 +#define GPIO_RISING_INT_BITS 1 +#define GPIO_RISING_INT_MASK (((1 << 1) - 1) << 1) +#define GPIO_RISING_INT (GPIO_RISING_INT_MASK) + +/* Bits of R_SENSOR_INT_CFG (0X0024) */ + +#define IE_SENSOR_INT_OFFSET 0 +#define IE_SENSOR_INT_BITS 1 +#define IE_SENSOR_INT_MASK (((1 << 1) - 1) << 0) +#define IE_SENSOR_INT (IE_SENSOR_INT_MASK) + +#define I_SENSOR_PRIORITY_OFFSET 1 +#define I_SENSOR_PRIORITY_BITS 1 +#define I_SENSOR_PRIORITY_MASK (((1 << 1) - 1) << 1) +#define I_SENSOR_PRIORITY (I_SENSOR_PRIORITY_MASK) + +#define CFG_SENSOR_INT_POS_EN_OFFSET 2 +#define CFG_SENSOR_INT_POS_EN_BITS 2 +#define CFG_SENSOR_INT_POS_EN_MASK (((1 << 2) - 1) << 2) +#define CFG_SENSOR_INT_POS_EN (CFG_SENSOR_INT_POS_EN_MASK) + +#define CFG_SENSOR_INT_NEG_EN_OFFSET 4 +#define CFG_SENSOR_INT_NEG_EN_BITS 2 +#define CFG_SENSOR_INT_NEG_EN_MASK (((1 << 2) - 1) << 4) +#define CFG_SENSOR_INT_NEG_EN (CFG_SENSOR_INT_NEG_EN_MASK) + +/* Bits of R_SENSOR_INT_FLAG (0X0028) */ + +#define I_SENSOR_INTF_FALL_OFFSET 0 +#define I_SENSOR_INTF_FALL_BITS 2 +#define I_SENSOR_INTF_FALL_MASK (((1 << 2) - 1) << 0) +#define I_SENSOR_INTF_FALL (I_SENSOR_INTF_FALL_MASK) + +#define I_SENSOR_INTF_RISE_OFFSET 2 +#define I_SENSOR_INTF_RISE_BITS 2 +#define I_SENSOR_INTF_RISE_MASK (((1 << 2) - 1) << 2) +#define I_SENSOR_INTF_RISE (I_SENSOR_INTF_RISE_MASK) + +#define I_SENSOR_INTF_OFFSET 4 +#define I_SENSOR_INTF_BITS 2 +#define I_SENSOR_INTF_MASK (((1 << 2) - 1) << 4) +#define I_SENSOR_INTF (I_SENSOR_INTF_MASK) + +#define SENSOR_SCS_N_GPIO_INT_FALL_OFFSET 6 +#define SENSOR_SCS_N_GPIO_INT_FALL_BITS 1 +#define SENSOR_SCS_N_GPIO_INT_FALL_MASK (((1 << 1) - 1) << 6) +#define SENSOR_SCS_N_GPIO_INT_FALL (SENSOR_SCS_N_GPIO_INT_FALL_MASK) + +#define SENSOR_SCS_N_GPIO_INT_RISE_OFFSET 7 +#define SENSOR_SCS_N_GPIO_INT_RISE_BITS 1 +#define SENSOR_SCS_N_GPIO_INT_RISE_MASK (((1 << 1) - 1) << 7) +#define SENSOR_SCS_N_GPIO_INT_RISE (SENSOR_SCS_N_GPIO_INT_RISE_MASK) + +#define GPIO_SVIO_INT_FALL_OFFSET 8 +#define GPIO_SVIO_INT_FALL_BITS 1 +#define GPIO_SVIO_INT_FALL_MASK (((1 << 1) - 1) << 8) +#define GPIO_SVIO_INT_FALL (GPIO_SVIO_INT_FALL_MASK) + +#define GPIO_SVIO_INT_RISE_OFFSET 9 +#define GPIO_SVIO_INT_RISE_BITS 1 +#define GPIO_SVIO_INT_RISE_MASK (((1 << 1) - 1) << 9) +#define GPIO_SVIO_INT_RISE (GPIO_SVIO_INT_RISE_MASK) + +#define SENSOR_RSTN_GPIO_INT_FALL_OFFSET 10 +#define SENSOR_RSTN_GPIO_INT_FALL_BITS 1 +#define SENSOR_RSTN_GPIO_INT_FALL_MASK (((1 << 1) - 1) << 10) +#define SENSOR_RSTN_GPIO_INT_FALL (SENSOR_RSTN_GPIO_INT_FALL_MASK) + +#define SENSOR_RSTN_GPIO_INT_RISE_OFFSET 11 +#define SENSOR_RSTN_GPIO_INT_RISE_BITS 1 +#define SENSOR_RSTN_GPIO_INT_RISE_MASK (((1 << 1) - 1) << 11) +#define SENSOR_RSTN_GPIO_INT_RISE (SENSOR_RSTN_GPIO_INT_RISE_MASK) + +#define WAKE_UP_I_OFFSET 16 +#define WAKE_UP_I_BITS 2 +#define WAKE_UP_I_MASK (((1 << 2) - 1) << 16) +#define WAKE_UP_I (WAKE_UP_I_MASK) + +/* Bits of R_AL_GPIO_VALUE (0X0070) */ + +#define AL_GPIO_O_OFFSET 0 +#define AL_GPIO_O_BITS 3 +#define AL_GPIO_O_MASK (((1 << 3) - 1) << 0) +#define AL_GPIO_O (AL_GPIO_O_MASK) + +#define ASYNC_AL_GPIO_IN_OFFSET 3 +#define ASYNC_AL_GPIO_IN_BITS 3 +#define ASYNC_AL_GPIO_IN_MASK (((1 << 3) - 1) << 3) +#define ASYNC_AL_GPIO_IN (ASYNC_AL_GPIO_IN_MASK) + +#define AL_GPIO_I_OFFSET 6 +#define AL_GPIO_I_BITS 3 +#define AL_GPIO_I_MASK (((1 << 3) - 1) << 6) +#define AL_GPIO_I (AL_GPIO_I_MASK) + +/* Bits of R_AL_GPIO_CFG (0X0074) */ + +#define AL_GPIO_OE_OFFSET 0 +#define AL_GPIO_OE_BITS 3 +#define AL_GPIO_OE_MASK (((1 << 3) - 1) << 0) +#define AL_GPIO_OE (AL_GPIO_OE_MASK) + +#define AL_GPIO_OE2_OFFSET 3 +#define AL_GPIO_OE2_BITS 3 +#define AL_GPIO_OE2_MASK (((1 << 3) - 1) << 3) +#define AL_GPIO_OE2 (AL_GPIO_OE2_MASK) + +#define AL_GPIO_OE3_OFFSET 8 +#define AL_GPIO_OE3_BITS 3 +#define AL_GPIO_OE3_MASK (((1 << 3) - 1) << 8) +#define AL_GPIO_OE3 (AL_GPIO_OE3_MASK) + +#define AL_GPIO_SHDN_OFFSET 11 +#define AL_GPIO_SHDN_BITS 3 +#define AL_GPIO_SHDN_MASK (((1 << 3) - 1) << 11) +#define AL_GPIO_SHDN (AL_GPIO_SHDN_MASK) + +#define AL_GPIO_IEV18_OFFSET 16 +#define AL_GPIO_IEV18_BITS 3 +#define AL_GPIO_IEV18_MASK (((1 << 3) - 1) << 16) +#define AL_GPIO_IEV18 (AL_GPIO_IEV18_MASK) + +#define AL_GPIO_PU_CTRL_OFFSET 19 +#define AL_GPIO_PU_CTRL_BITS 3 +#define AL_GPIO_PU_CTRL_MASK (((1 << 3) - 1) << 19) +#define AL_GPIO_PU_CTRL (AL_GPIO_PU_CTRL_MASK) + +#define AL_GPIO_PD_CTRL_OFFSET 24 +#define AL_GPIO_PD_CTRL_BITS 3 +#define AL_GPIO_PD_CTRL_MASK (((1 << 3) - 1) << 24) +#define AL_GPIO_PD_CTRL (AL_GPIO_PD_CTRL_MASK) + +#define AL_GPIO_SEL_OFFSET 27 +#define AL_GPIO_SEL_BITS 3 +#define AL_GPIO_SEL_MASK (((1 << 3) - 1) << 27) +#define AL_GPIO_SEL (AL_GPIO_SEL_MASK) + +#define CS1_BRIDGE_EN_OFFSET 31 +#define CS1_BRIDGE_EN_BITS 1 +#define CS1_BRIDGE_EN_MASK (((1 << 1) - 1) << 31) +#define CS1_BRIDGE_EN (CS1_BRIDGE_EN_MASK) + +/* Bits of R_AL_GPIO_IRQ_EN (0X0078) */ + +#define AL_GPIO_INT_EN_FALL_OFFSET 0 +#define AL_GPIO_INT_EN_FALL_BITS 3 +#define AL_GPIO_INT_EN_FALL_MASK (((1 << 3) - 1) << 0) +#define AL_GPIO_INT_EN_FALL (AL_GPIO_INT_EN_FALL_MASK) + +#define AL_GPIO_INT_EN_RISE_OFFSET 3 +#define AL_GPIO_INT_EN_RISE_BITS 3 +#define AL_GPIO_INT_EN_RISE_MASK (((1 << 3) - 1) << 3) +#define AL_GPIO_INT_EN_RISE (AL_GPIO_INT_EN_RISE_MASK) + +/* Bits of R_AL_GPIO_IRQ (0X007C) */ + +#define AL_GPIO_INT_FALL_OFFSET 0 +#define AL_GPIO_INT_FALL_BITS 3 +#define AL_GPIO_INT_FALL_MASK (((1 << 3) - 1) << 0) +#define AL_GPIO_INT_FALL (AL_GPIO_INT_FALL_MASK) + +#define AL_GPIO_INT_RISE_OFFSET 3 +#define AL_GPIO_INT_RISE_BITS 3 +#define AL_GPIO_INT_RISE_MASK (((1 << 3) - 1) << 3) +#define AL_GPIO_INT_RISE (AL_GPIO_INT_RISE_MASK) + +/* Bits of R_AL_SENSOR_RST_CTL (0X0080) */ + +#define PAD_SENSOR_RSTN_I_OFFSET 0 +#define PAD_SENSOR_RSTN_I_BITS 1 +#define PAD_SENSOR_RSTN_I_MASK (((1 << 1) - 1) << 0) +#define PAD_SENSOR_RSTN_I (PAD_SENSOR_RSTN_I_MASK) + +#define SENSOR_RSTN_O_OFFSET 1 +#define SENSOR_RSTN_O_BITS 1 +#define SENSOR_RSTN_O_MASK (((1 << 1) - 1) << 1) +#define SENSOR_RSTN_O (SENSOR_RSTN_O_MASK) + +#define SENSOR_RSTN_OE0_OFFSET 2 +#define SENSOR_RSTN_OE0_BITS 1 +#define SENSOR_RSTN_OE0_MASK (((1 << 1) - 1) << 2) +#define SENSOR_RSTN_OE0 (SENSOR_RSTN_OE0_MASK) + +#define SENSOR_RSTN_OE2_OFFSET 3 +#define SENSOR_RSTN_OE2_BITS 1 +#define SENSOR_RSTN_OE2_MASK (((1 << 1) - 1) << 3) +#define SENSOR_RSTN_OE2 (SENSOR_RSTN_OE2_MASK) + +#define SENSOR_RSTN_OE3_OFFSET 4 +#define SENSOR_RSTN_OE3_BITS 1 +#define SENSOR_RSTN_OE3_MASK (((1 << 1) - 1) << 4) +#define SENSOR_RSTN_OE3 (SENSOR_RSTN_OE3_MASK) + +#define SENSOR_RSTN_IEV18_OFFSET 5 +#define SENSOR_RSTN_IEV18_BITS 1 +#define SENSOR_RSTN_IEV18_MASK (((1 << 1) - 1) << 5) +#define SENSOR_RSTN_IEV18 (SENSOR_RSTN_IEV18_MASK) + +#define SENSOR_RSTN_H3L1_OFFSET 6 +#define SENSOR_RSTN_H3L1_BITS 1 +#define SENSOR_RSTN_H3L1_MASK (((1 << 1) - 1) << 6) +#define SENSOR_RSTN_H3L1 (SENSOR_RSTN_H3L1_MASK) + +#define SENSOR_RSTN_PUE_OFFSET 7 +#define SENSOR_RSTN_PUE_BITS 1 +#define SENSOR_RSTN_PUE_MASK (((1 << 1) - 1) << 7) +#define SENSOR_RSTN_PUE (SENSOR_RSTN_PUE_MASK) + +#define SENSOR_RSTN_PDE_OFFSET 8 +#define SENSOR_RSTN_PDE_BITS 1 +#define SENSOR_RSTN_PDE_MASK (((1 << 1) - 1) << 8) +#define SENSOR_RSTN_PDE (SENSOR_RSTN_PDE_MASK) + +#define SENSOR_RSTN_GPIO_INT_EN_RISE_OFFSET 10 +#define SENSOR_RSTN_GPIO_INT_EN_RISE_BITS 1 +#define SENSOR_RSTN_GPIO_INT_EN_RISE_MASK (((1 << 1) - 1) << 10) +#define SENSOR_RSTN_GPIO_INT_EN_RISE (SENSOR_RSTN_GPIO_INT_EN_RISE_MASK) + +#define SENSOR_RSTN_GPIO_INT_EN_FALL_OFFSET 11 +#define SENSOR_RSTN_GPIO_INT_EN_FALL_BITS 1 +#define SENSOR_RSTN_GPIO_INT_EN_FALL_MASK (((1 << 1) - 1) << 11) +#define SENSOR_RSTN_GPIO_INT_EN_FALL (SENSOR_RSTN_GPIO_INT_EN_FALL_MASK) + +/* Bits of R_AL_SENSOR_SCS_N_CTL (0X0084) */ + +#define PAD_SENSOR_SCS_N_I_OFFSET 0 +#define PAD_SENSOR_SCS_N_I_BITS 1 +#define PAD_SENSOR_SCS_N_I_MASK (((1 << 1) - 1) << 0) +#define PAD_SENSOR_SCS_N_I (PAD_SENSOR_SCS_N_I_MASK) + +#define SENSOR_SCS_N_O_OFFSET 1 +#define SENSOR_SCS_N_O_BITS 1 +#define SENSOR_SCS_N_O_MASK (((1 << 1) - 1) << 1) +#define SENSOR_SCS_N_O (SENSOR_SCS_N_O_MASK) + +#define SENSOR_SCS_N_OE0_OFFSET 2 +#define SENSOR_SCS_N_OE0_BITS 1 +#define SENSOR_SCS_N_OE0_MASK (((1 << 1) - 1) << 2) +#define SENSOR_SCS_N_OE0 (SENSOR_SCS_N_OE0_MASK) + +#define SENSOR_SCS_N_OE2_OFFSET 3 +#define SENSOR_SCS_N_OE2_BITS 1 +#define SENSOR_SCS_N_OE2_MASK (((1 << 1) - 1) << 3) +#define SENSOR_SCS_N_OE2 (SENSOR_SCS_N_OE2_MASK) + +#define SENSOR_SCS_N_OE3_OFFSET 4 +#define SENSOR_SCS_N_OE3_BITS 1 +#define SENSOR_SCS_N_OE3_MASK (((1 << 1) - 1) << 4) +#define SENSOR_SCS_N_OE3 (SENSOR_SCS_N_OE3_MASK) + +#define SENSOR_SCS_N_IEV18_OFFSET 5 +#define SENSOR_SCS_N_IEV18_BITS 1 +#define SENSOR_SCS_N_IEV18_MASK (((1 << 1) - 1) << 5) +#define SENSOR_SCS_N_IEV18 (SENSOR_SCS_N_IEV18_MASK) + +#define SENSOR_SCS_N_H3L1_OFFSET 6 +#define SENSOR_SCS_N_H3L1_BITS 1 +#define SENSOR_SCS_N_H3L1_MASK (((1 << 1) - 1) << 6) +#define SENSOR_SCS_N_H3L1 (SENSOR_SCS_N_H3L1_MASK) + +#define SENSOR_SCS_N_PUE_OFFSET 7 +#define SENSOR_SCS_N_PUE_BITS 1 +#define SENSOR_SCS_N_PUE_MASK (((1 << 1) - 1) << 7) +#define SENSOR_SCS_N_PUE (SENSOR_SCS_N_PUE_MASK) + +#define SENSOR_SCS_N_PDE_OFFSET 8 +#define SENSOR_SCS_N_PDE_BITS 1 +#define SENSOR_SCS_N_PDE_MASK (((1 << 1) - 1) << 8) +#define SENSOR_SCS_N_PDE (SENSOR_SCS_N_PDE_MASK) + +#define SENSOR_SCS_N_SEL_OFFSET 9 +#define SENSOR_SCS_N_SEL_BITS 1 +#define SENSOR_SCS_N_SEL_MASK (((1 << 1) - 1) << 9) +#define SENSOR_SCS_N_SEL (SENSOR_SCS_N_SEL_MASK) + +#define SENSOR_SCS_N_GPIO_INT_EN_RISE_OFFSET 10 +#define SENSOR_SCS_N_GPIO_INT_EN_RISE_BITS 1 +#define SENSOR_SCS_N_GPIO_INT_EN_RISE_MASK (((1 << 1) - 1) << 10) +#define SENSOR_SCS_N_GPIO_INT_EN_RISE (SENSOR_SCS_N_GPIO_INT_EN_RISE_MASK) + +#define SENSOR_SCS_N_GPIO_INT_EN_FALL_OFFSET 11 +#define SENSOR_SCS_N_GPIO_INT_EN_FALL_BITS 1 +#define SENSOR_SCS_N_GPIO_INT_EN_FALL_MASK (((1 << 1) - 1) << 11) +#define SENSOR_SCS_N_GPIO_INT_EN_FALL (SENSOR_SCS_N_GPIO_INT_EN_FALL_MASK) + +/* Bits of R_GPIO_SVIO_CFG (0X008C) */ + +#define GPIO_SVIO_I_OFFSET 0 +#define GPIO_SVIO_I_BITS 1 +#define GPIO_SVIO_I_MASK (((1 << 1) - 1) << 0) +#define GPIO_SVIO_I (GPIO_SVIO_I_MASK) + +#define GPIO_SVIO_O_OFFSET 1 +#define GPIO_SVIO_O_BITS 1 +#define GPIO_SVIO_O_MASK (((1 << 1) - 1) << 1) +#define GPIO_SVIO_O (GPIO_SVIO_O_MASK) + +#define GPIO_SVIO_OE0_OFFSET 2 +#define GPIO_SVIO_OE0_BITS 1 +#define GPIO_SVIO_OE0_MASK (((1 << 1) - 1) << 2) +#define GPIO_SVIO_OE0 (GPIO_SVIO_OE0_MASK) + +#define GPIO_SVIO_OE2_OFFSET 3 +#define GPIO_SVIO_OE2_BITS 1 +#define GPIO_SVIO_OE2_MASK (((1 << 1) - 1) << 3) +#define GPIO_SVIO_OE2 (GPIO_SVIO_OE2_MASK) + +#define GPIO_SVIO_OE3_OFFSET 4 +#define GPIO_SVIO_OE3_BITS 1 +#define GPIO_SVIO_OE3_MASK (((1 << 1) - 1) << 4) +#define GPIO_SVIO_OE3 (GPIO_SVIO_OE3_MASK) + +#define GPIO_SVIO_H3L1_OFFSET 5 +#define GPIO_SVIO_H3L1_BITS 1 +#define GPIO_SVIO_H3L1_MASK (((1 << 1) - 1) << 5) +#define GPIO_SVIO_H3L1 (GPIO_SVIO_H3L1_MASK) + +#define GPIO_SVIO_IEV18_OFFSET 6 +#define GPIO_SVIO_IEV18_BITS 1 +#define GPIO_SVIO_IEV18_MASK (((1 << 1) - 1) << 6) +#define GPIO_SVIO_IEV18 (GPIO_SVIO_IEV18_MASK) + +#define GPIO_SVIO_PULLCTL_OFFSET 8 +#define GPIO_SVIO_PULLCTL_BITS 2 +#define GPIO_SVIO_PULLCTL_MASK (((1 << 2) - 1) << 8) +#define GPIO_SVIO_PULLCTL (GPIO_SVIO_PULLCTL_MASK) + +#define GPIO_SVIO_INT_EN_RISE_OFFSET 10 +#define GPIO_SVIO_INT_EN_RISE_BITS 1 +#define GPIO_SVIO_INT_EN_RISE_MASK (((1 << 1) - 1) << 10) +#define GPIO_SVIO_INT_EN_RISE (GPIO_SVIO_INT_EN_RISE_MASK) + +#define GPIO_SVIO_INT_EN_FALL_OFFSET 11 +#define GPIO_SVIO_INT_EN_FALL_BITS 1 +#define GPIO_SVIO_INT_EN_FALL_MASK (((1 << 1) - 1) << 11) +#define GPIO_SVIO_INT_EN_FALL (GPIO_SVIO_INT_EN_FALL_MASK) + +#endif /* ZEPHYR_DRIVERS_PINCTRL_RTS5817_REG_H_ */ diff --git a/drivers/reset/CMakeLists.txt b/drivers/reset/CMakeLists.txt index 4ac4a77017d4d..a600b3350d834 100644 --- a/drivers/reset/CMakeLists.txt +++ b/drivers/reset/CMakeLists.txt @@ -14,3 +14,4 @@ zephyr_library_sources_ifdef(CONFIG_RESET_NXP_SYSCON reset_lpc_syscon.c) zephyr_library_sources_ifdef(CONFIG_RESET_NXP_RSTCTL reset_nxp_rstctl.c) zephyr_library_sources_ifdef(CONFIG_RESET_MMIO reset_mmio.c) zephyr_library_sources_ifdef(CONFIG_RESET_MCHP_MSS reset_mchp_mss.c) +zephyr_library_sources_ifdef(CONFIG_RESET_RTS5817 reset_rts5817.c) diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 3646cf480666c..9841273b7c000 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -38,5 +38,6 @@ rsource "Kconfig.lpc_syscon" rsource "Kconfig.nxp_rstctl" rsource "Kconfig.mmio" rsource "Kconfig.mchp_mss" +rsource "Kconfig.rts5817" endif # RESET diff --git a/drivers/reset/Kconfig.rts5817 b/drivers/reset/Kconfig.rts5817 new file mode 100644 index 0000000000000..7e1d1057d0553 --- /dev/null +++ b/drivers/reset/Kconfig.rts5817 @@ -0,0 +1,9 @@ +# Copyright (c) 2024 Realtek Semiconductor, Inc. +# SPDX-License-Identifier: Apache-2.0 + +config RESET_RTS5817 + bool "RTS5817 Reset Controller Driver" + default y + depends on DT_HAS_REALTEK_RTS5817_RESET_ENABLED + help + This option enables the reset controller driver for RTS5817. diff --git a/drivers/reset/reset_rts5817.c b/drivers/reset/reset_rts5817.c new file mode 100644 index 0000000000000..fb0d337cea447 --- /dev/null +++ b/drivers/reset/reset_rts5817.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT realtek_rts5817_reset + +#include +#include +#include +#include +#include "reset_rts5817.h" + +struct reset_rts5817_config { + uintptr_t base; +}; + +static int reset_rts5817_status(const struct device *dev, uint32_t id, uint8_t *status) +{ + const struct reset_rts5817_config *config = dev->config; + + *status = !!sys_test_bit(config->base + R_SYS_FORCE_RST, id); + + return 0; +} + +static int reset_rts5817_line_assert(const struct device *dev, uint32_t id) +{ + const struct reset_rts5817_config *config = dev->config; + + sys_set_bit(config->base + R_SYS_FORCE_RST, id); + + return 0; +} + +static int reset_rts5817_line_deassert(const struct device *dev, uint32_t id) +{ + const struct reset_rts5817_config *config = dev->config; + + sys_clear_bit(config->base + R_SYS_FORCE_RST, id); + + return 0; +} + +static int reset_rts5817_line_toggle(const struct device *dev, uint32_t id) +{ + reset_rts5817_line_assert(dev, id); + reset_rts5817_line_deassert(dev, id); + + return 0; +} + +static const struct reset_driver_api reset_rts5817_driver_api = { + .status = reset_rts5817_status, + .line_assert = reset_rts5817_line_assert, + .line_deassert = reset_rts5817_line_deassert, + .line_toggle = reset_rts5817_line_toggle, +}; + +static const struct reset_rts5817_config reset_rts5817_config = { + .base = DT_INST_REG_ADDR(0), +}; + +DEVICE_DT_INST_DEFINE(0, NULL, NULL, NULL, &reset_rts5817_config, PRE_KERNEL_1, + CONFIG_RESET_INIT_PRIORITY, &reset_rts5817_driver_api); diff --git a/drivers/reset/reset_rts5817.h b/drivers/reset/reset_rts5817.h new file mode 100644 index 0000000000000..6c32fef3400de --- /dev/null +++ b/drivers/reset/reset_rts5817.h @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_RESET_RESET_RTS5817_REG_H_ +#define ZEPHYR_DRIVERS_RESET_RESET_RTS5817_REG_H_ + +#define SYSRST_BASE_ADDR 0x0 +#define R_SYS_FORCE_RST (SYSRST_BASE_ADDR + 0X0000) + +/* Bits of R_SYS_FORCE_RST (0X0200) */ + +#define SYS_FORCE_RESET_BUS_OFFSET 0 +#define SYS_FORCE_RESET_BUS_BITS 1 +#define SYS_FORCE_RESET_BUS_MASK (((1 << 1) - 1) << 0) +#define SYS_FORCE_RESET_BUS (SYS_FORCE_RESET_BUS_MASK) + +#define SYS_FORCE_RESET_AES_OFFSET 1 +#define SYS_FORCE_RESET_AES_BITS 1 +#define SYS_FORCE_RESET_AES_MASK (((1 << 1) - 1) << 1) +#define SYS_FORCE_RESET_AES (SYS_FORCE_RESET_AES_MASK) + +#define SYS_FORCE_RESET_GE_OFFSET 2 +#define SYS_FORCE_RESET_GE_BITS 1 +#define SYS_FORCE_RESET_GE_MASK (((1 << 1) - 1) << 2) +#define SYS_FORCE_RESET_GE (SYS_FORCE_RESET_GE_MASK) + +#define SYS_FORCE_RESET_SHA_OFFSET 3 +#define SYS_FORCE_RESET_SHA_BITS 1 +#define SYS_FORCE_RESET_SHA_MASK (((1 << 1) - 1) << 3) +#define SYS_FORCE_RESET_SHA (SYS_FORCE_RESET_SHA_MASK) + +#define SYS_FORCE_RESET_SPI_CACHE_OFFSET 4 +#define SYS_FORCE_RESET_SPI_CACHE_BITS 1 +#define SYS_FORCE_RESET_SPI_CACHE_MASK (((1 << 1) - 1) << 4) +#define SYS_FORCE_RESET_SPI_CACHE (SYS_FORCE_RESET_SPI_CACHE_MASK) + +#define SYS_FORCE_RESET_SPI_SENSOR_OFFSET 5 +#define SYS_FORCE_RESET_SPI_SENSOR_BITS 1 +#define SYS_FORCE_RESET_SPI_SENSOR_MASK (((1 << 1) - 1) << 5) +#define SYS_FORCE_RESET_SPI_SENSOR (SYS_FORCE_RESET_SPI_SENSOR_MASK) + +#define SYS_FORCE_RESET_SPI_SSI_M_OFFSET 6 +#define SYS_FORCE_RESET_SPI_SSI_M_BITS 1 +#define SYS_FORCE_RESET_SPI_SSI_M_MASK (((1 << 1) - 1) << 6) +#define SYS_FORCE_RESET_SPI_SSI_M (SYS_FORCE_RESET_SPI_SSI_M_MASK) + +#define SYS_FORCE_RESET_SPI_SSI_S_OFFSET 7 +#define SYS_FORCE_RESET_SPI_SSI_S_BITS 1 +#define SYS_FORCE_RESET_SPI_SSI_S_MASK (((1 << 1) - 1) << 7) +#define SYS_FORCE_RESET_SPI_SSI_S (SYS_FORCE_RESET_SPI_SSI_S_MASK) + +#define SYS_FORCE_RESET_PKE_OFFSET 8 +#define SYS_FORCE_RESET_PKE_BITS 1 +#define SYS_FORCE_RESET_PKE_MASK (((1 << 1) - 1) << 8) +#define SYS_FORCE_RESET_PKE (SYS_FORCE_RESET_PKE_MASK) + +#define SYS_FORCE_RESET_I2C_OFFSET 9 +#define SYS_FORCE_RESET_I2C_BITS 1 +#define SYS_FORCE_RESET_I2C_MASK (((1 << 1) - 1) << 9) +#define SYS_FORCE_RESET_I2C (SYS_FORCE_RESET_I2C_MASK) + +#define SYS_FORCE_RESET_I2C0_OFFSET 10 +#define SYS_FORCE_RESET_I2C0_BITS 1 +#define SYS_FORCE_RESET_I2C0_MASK (((1 << 1) - 1) << 10) +#define SYS_FORCE_RESET_I2C0 (SYS_FORCE_RESET_I2C0_MASK) + +#define SYS_FORCE_RESET_I2C1_OFFSET 11 +#define SYS_FORCE_RESET_I2C1_BITS 1 +#define SYS_FORCE_RESET_I2C1_MASK (((1 << 1) - 1) << 11) +#define SYS_FORCE_RESET_I2C1 (SYS_FORCE_RESET_I2C1_MASK) + +#define SYS_FORCE_RESET_TRNG_OFFSET 12 +#define SYS_FORCE_RESET_TRNG_BITS 1 +#define SYS_FORCE_RESET_TRNG_MASK (((1 << 1) - 1) << 12) +#define SYS_FORCE_RESET_TRNG (SYS_FORCE_RESET_TRNG_MASK) + +#define SYS_FORCE_RESET_I2C_S_OFFSET 13 +#define SYS_FORCE_RESET_I2C_S_BITS 1 +#define SYS_FORCE_RESET_I2C_S_MASK (((1 << 1) - 1) << 13) +#define SYS_FORCE_RESET_I2C_S (SYS_FORCE_RESET_I2C_S_MASK) + +#define SYS_FORCE_RESET_UART0_OFFSET 14 +#define SYS_FORCE_RESET_UART0_BITS 1 +#define SYS_FORCE_RESET_UART0_MASK (((1 << 1) - 1) << 14) +#define SYS_FORCE_RESET_UART0 (SYS_FORCE_RESET_UART0_MASK) + +#define SYS_FORCE_RESET_UART1_OFFSET 15 +#define SYS_FORCE_RESET_UART1_BITS 1 +#define SYS_FORCE_RESET_UART1_MASK (((1 << 1) - 1) << 15) +#define SYS_FORCE_RESET_UART1 (SYS_FORCE_RESET_UART1_MASK) + +#define SYS_FORCE_RESET_PUF_OFFSET 16 +#define SYS_FORCE_RESET_PUF_BITS 1 +#define SYS_FORCE_RESET_PUF_MASK (((1 << 1) - 1) << 16) +#define SYS_FORCE_RESET_PUF (SYS_FORCE_RESET_PUF_MASK) + +#define SYS_FORCE_RESET_USB2_OFFSET 17 +#define SYS_FORCE_RESET_USB2_BITS 1 +#define SYS_FORCE_RESET_USB2_MASK (((1 << 1) - 1) << 17) +#define SYS_FORCE_RESET_USB2 (SYS_FORCE_RESET_USB2_MASK) + +#define SYS_FORCE_RESET_CK30M_OFFSET 18 +#define SYS_FORCE_RESET_CK30M_BITS 1 +#define SYS_FORCE_RESET_CK30M_MASK (((1 << 1) - 1) << 18) +#define SYS_FORCE_RESET_CK30M (SYS_FORCE_RESET_CK30M_MASK) + +#define SYS_FORCE_RESET_CK60M_OFFSET 19 +#define SYS_FORCE_RESET_CK60M_BITS 1 +#define SYS_FORCE_RESET_CK60M_MASK (((1 << 1) - 1) << 19) +#define SYS_FORCE_RESET_CK60M (SYS_FORCE_RESET_CK60M_MASK) + +#define SYS_FORCE_RESET_CK120M_OFFSET 20 +#define SYS_FORCE_RESET_CK120M_BITS 1 +#define SYS_FORCE_RESET_CK120M_MASK (((1 << 1) - 1) << 20) +#define SYS_FORCE_RESET_CK120M (SYS_FORCE_RESET_CK120M_MASK) + +#define USB2_PHY_FORCE_RESET_OFFSET 21 +#define USB2_PHY_FORCE_RESET_BITS 1 +#define USB2_PHY_FORCE_RESET_MASK (((1 << 1) - 1) << 21) +#define USB2_PHY_FORCE_RESET (USB2_PHY_FORCE_RESET_MASK) + +#define SYS_FORCE_RESET_SYS_OFFSET 22 +#define SYS_FORCE_RESET_SYS_BITS 1 +#define SYS_FORCE_RESET_SYS_MASK (((1 << 1) - 1) << 22) +#define SYS_FORCE_RESET_SYS (SYS_FORCE_RESET_SYS_MASK) + +#define SYS_FORCE_RESET_DPHY_OFFSET 23 +#define SYS_FORCE_RESET_DPHY_BITS 1 +#define SYS_FORCE_RESET_DPHY_MASK (((1 << 1) - 1) << 23) +#define SYS_FORCE_RESET_DPHY (SYS_FORCE_RESET_DPHY_MASK) + +#define SYS_FORCE_RESET_SPI_SSISLV_BUS_OFFSET 24 +#define SYS_FORCE_RESET_SPI_SSISLV_BUS_BITS 1 +#define SYS_FORCE_RESET_SPI_SSISLV_BUS_MASK (((1 << 1) - 1) << 24) +#define SYS_FORCE_RESET_SPI_SSISLV_BUS (SYS_FORCE_RESET_SPI_SSISLV_BUS_MASK) + +#endif /* ZEPHYR_DRIVERS_RESET_RESET_RTS5817_REG_H_ */ diff --git a/drivers/watchdog/CMakeLists.txt b/drivers/watchdog/CMakeLists.txt index ab7dcabedc5fb..eb85a8237d800 100644 --- a/drivers/watchdog/CMakeLists.txt +++ b/drivers/watchdog/CMakeLists.txt @@ -54,6 +54,7 @@ zephyr_library_sources_ifdef(CONFIG_WWDT_NUMAKER wdt_wwdt_numaker.c) zephyr_library_sources_ifdef(CONFIG_WDT_ENE_KB106X wdt_ene_kb106x.c) zephyr_library_sources_ifdef(CONFIG_WDT_ENE_KB1200 wdt_ene_kb1200.c) zephyr_library_sources_ifdef(CONFIG_WDT_IWDG_WCH wdt_iwdg_wch.c) +zephyr_library_sources_ifdef(CONFIG_WDT_RTS5817 wdt_rts5817.c) zephyr_library_sources_ifdef(CONFIG_WDT_DW wdt_dw.c wdt_dw_common.c) zephyr_library_sources_ifdef(CONFIG_WDT_INTEL_ADSP wdt_intel_adsp.c wdt_dw_common.c) diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 4fed392fd223c..70198746e1f85 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -157,4 +157,6 @@ source "drivers/watchdog/Kconfig.wch" source "drivers/watchdog/Kconfig.nxp_ewm" +source "drivers/watchdog/Kconfig.rts5817" + endif # WATCHDOG diff --git a/drivers/watchdog/Kconfig.rts5817 b/drivers/watchdog/Kconfig.rts5817 new file mode 100644 index 0000000000000..36ce4e0fc0431 --- /dev/null +++ b/drivers/watchdog/Kconfig.rts5817 @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Realtek Semiconductor, Inc. +# SPDX-License-Identifier: Apache-2.0 + +config WDT_RTS5817 + bool "Realtek RTS5817 Watchdog driver" + default y + depends on DT_HAS_REALTEK_RTS5817_WATCHDOG_ENABLED + select HAS_WDT_DISABLE_AT_BOOT + help + Realtek RTS5817 watchdog driver. diff --git a/drivers/watchdog/wdt_rts5817.c b/drivers/watchdog/wdt_rts5817.c new file mode 100644 index 0000000000000..148840bf2cf5b --- /dev/null +++ b/drivers/watchdog/wdt_rts5817.c @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT realtek_rts5817_watchdog + +#include +#include +#include "wdt_rts5817.h" + +#define LOG_LEVEL CONFIG_WDT_LOG_LEVEL +#include +LOG_MODULE_REGISTER(wdt_rts5817); + +#define WDOG_TIME_1S 0x0 +#define WDOG_TIME_2S 0x1 +#define WDOG_TIME_4S 0x2 +#define WDOG_TIME_8S 0x3 + +struct rts_fp_wdt_config { + mem_addr_t base; +}; + +static inline uint32_t rts_fp_read_reg(const struct device *dev) +{ + const struct rts_fp_wdt_config *config = dev->config; + + return sys_read32(config->base); +} + +static inline void rts_fp_write_reg(const struct device *dev, uint32_t value) +{ + const struct rts_fp_wdt_config *config = dev->config; + + sys_write32(value, config->base); +} + +static int rts_fp_wdt_setup(const struct device *dev, uint8_t options) +{ + uint32_t value; + + if ((options & WDT_OPT_PAUSE_IN_SLEEP) || (options & WDT_OPT_PAUSE_HALTED_BY_DBG)) { + LOG_ERR("Pause in sleep or halted by dbg is not supported"); + return -ENOTSUP; + } + + value = rts_fp_read_reg(dev); + value |= WDOG_EN; + rts_fp_write_reg(dev, value); + + return 0; +} + +static int rts_fp_wdt_disable(const struct device *dev) +{ + uint32_t value; + + value = rts_fp_read_reg(dev); + value &= ~WDOG_EN; + rts_fp_write_reg(dev, value); + + return 0; +} + +static int rts_fp_wdt_install_timeout(const struct device *dev, const struct wdt_timeout_cfg *cfg) +{ + uint32_t value; + + if (cfg->window.min > 0 || cfg->window.max > 8000) { + LOG_ERR("watchdog window.min should be equal to 0 and window.max should not exceed " + "8000"); + return -ENOTSUP; + } + + /* Set mode of watchdog and callback */ + switch (cfg->flags) { + case WDT_FLAG_RESET_NONE: + break; + + case WDT_FLAG_RESET_CPU_CORE: + case WDT_FLAG_RESET_SOC: + if (cfg->callback != NULL) { + LOG_ERR("watchdog callback is not supported"); + return -ENOTSUP; + } + + value = rts_fp_read_reg(dev); + value &= ~WDOG_TIME_MASK; + + if (cfg->window.max <= 1000) { + value |= WDOG_TIME_1S << WDOG_TIME_OFFSET; + } else if (cfg->window.max > 1000 && cfg->window.max <= 2000) { + value |= WDOG_TIME_2S << WDOG_TIME_OFFSET; + } else if (cfg->window.max > 2000 && cfg->window.max <= 4000) { + value |= WDOG_TIME_4S << WDOG_TIME_OFFSET; + } else if (cfg->window.max > 4000 && cfg->window.max <= 8000) { + value |= WDOG_TIME_8S << WDOG_TIME_OFFSET; + } else { + return -ENOTSUP; + } + + rts_fp_write_reg(dev, value); + + break; + + default: + LOG_ERR("unknown watchdog flags"); + return -EINVAL; + } + + return 0; +} + +static int rts_fp_wdt_feed(const struct device *dev, int channel_id) +{ + uint32_t value; + + value = rts_fp_read_reg(dev); + value |= WDOG_CLR; + rts_fp_write_reg(dev, value); + + return 0; +} + +static int rts_fp_wdt_init(const struct device *dev) +{ + /* Note: Watchdog is enabled by default for rts5817. + * so CONFIG_WDT_DISABLE_AT_BOOT needs to be selected by default + */ + + if (IS_ENABLED(CONFIG_WDT_DISABLE_AT_BOOT)) { + rts_fp_wdt_disable(dev); + } + return 0; +} + +static const struct wdt_driver_api rts_fp_wdt_driver_api = { + .setup = rts_fp_wdt_setup, + .disable = rts_fp_wdt_disable, + .install_timeout = rts_fp_wdt_install_timeout, + .feed = rts_fp_wdt_feed, +}; + +const struct rts_fp_wdt_config rts_fp_config = { + .base = DT_INST_REG_ADDR(0), +}; + +DEVICE_DT_INST_DEFINE(0, &rts_fp_wdt_init, NULL, NULL, &rts_fp_config, PRE_KERNEL_1, + CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &rts_fp_wdt_driver_api); diff --git a/drivers/watchdog/wdt_rts5817.h b/drivers/watchdog/wdt_rts5817.h new file mode 100644 index 0000000000000..d15ae1874d067 --- /dev/null +++ b/drivers/watchdog/wdt_rts5817.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_WATCHDOG_WDT_RTS_RTS5817_H_ +#define ZEPHYR_DRIVERS_WATCHDOG_WDT_RTS_RTS5817_H_ + +/* Bits of R_WTDG_CTRL (0X0048) */ + +#define WDOG_EN_OFFSET 0 +#define WDOG_EN_BITS 1 +#define WDOG_EN_MASK (((1 << 1) - 1) << 0) +#define WDOG_EN (WDOG_EN_MASK) + +#define WDOG_CLR_OFFSET 1 +#define WDOG_CLR_BITS 1 +#define WDOG_CLR_MASK (((1 << 1) - 1) << 1) +#define WDOG_CLR (WDOG_CLR_MASK) + +#define WDOG_TIME_OFFSET 2 +#define WDOG_TIME_BITS 2 +#define WDOG_TIME_MASK (((1 << 2) - 1) << 2) +#define WDOG_TIME (WDOG_TIME_MASK) + +#define WDOG_REG_RST_EN_OFFSET 4 +#define WDOG_REG_RST_EN_BITS 1 +#define WDOG_REG_RST_EN_MASK (((1 << 1) - 1) << 4) +#define WDOG_REG_RST_EN (WDOG_REG_RST_EN_MASK) + +#define WDOG_BUS_RST_EN_OFFSET 5 +#define WDOG_BUS_RST_EN_BITS 1 +#define WDOG_BUS_RST_EN_MASK (((1 << 1) - 1) << 5) +#define WDOG_BUS_RST_EN (WDOG_BUS_RST_EN_MASK) + +#define WDOG_INT_EN_OFFSET 6 +#define WDOG_INT_EN_BITS 1 +#define WDOG_INT_EN_MASK (((1 << 1) - 1) << 6) +#define WDOG_INT_EN (WDOG_INT_EN_MASK) + +#define WDOG_INT_CLR_OFFSET 7 +#define WDOG_INT_CLR_BITS 1 +#define WDOG_INT_CLR_MASK (((1 << 1) - 1) << 7) +#define WDOG_INT_CLR (WDOG_INT_CLR_MASK) + +#define WDOG_INT_OFFSET 8 +#define WDOG_INT_BITS 1 +#define WDOG_INT_MASK (((1 << 1) - 1) << 8) +#define WDOG_INT (WDOG_INT_MASK) + +#define WDOG_INT_SEL_OFFSET 9 +#define WDOG_INT_SEL_BITS 1 +#define WDOG_INT_SEL_MASK (((1 << 1) - 1) << 9) +#define WDOG_INT_SEL (WDOG_INT_SEL_MASK) + +#define WDOG_CNT_OFFSET 16 +#define WDOG_CNT_BITS 16 +#define WDOG_CNT_MASK (((1 << 16) - 1) << 16) +#define WDOG_CNT (WDOG_CNT_MASK) + +#endif /* ZEPHYR_DRIVERS_WATCHDOG_WDT_RTS_RTS5817_H_ */ diff --git a/dts/arm/realtek/fingerprint/rts5817/rts5817.dtsi b/dts/arm/realtek/fingerprint/rts5817/rts5817.dtsi new file mode 100644 index 0000000000000..d8a23002cae72 --- /dev/null +++ b/dts/arm/realtek/fingerprint/rts5817/rts5817.dtsi @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor, Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + chosen { + zephyr,flash = &flash0; + }; + + flash0: memory@1800000 { + compatible = "soc-nv-flash"; + reg = <0x1800000 DT_SIZE_K(256)>; + }; +}; diff --git a/dts/arm/realtek/fingerprint/rts5817/rts5817_base.dtsi b/dts/arm/realtek/fingerprint/rts5817/rts5817_base.dtsi new file mode 100644 index 0000000000000..d40be08377741 --- /dev/null +++ b/dts/arm/realtek/fingerprint/rts5817/rts5817_base.dtsi @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor, Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +/ { + chosen { + zephyr,sram = &sram0; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-m33"; + reg = <0>; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <1>; + }; + }; + + sram0: memory@20000000 { + compatible = "mmio-sram"; + reg = <0x20000000 DT_SIZE_K(256)>; + }; + + soc { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + + clks: clks@40100300 { + compatible = "realtek,rts5817-clock"; + reg = <0x40100300 0x100>, + <0x40150000 0x10>, + <0x40000018 0x4>; + #clock-cells = <1>; + status = "disabled"; + }; + + reset: reset@40100200 { + compatible = "realtek,rts5817-reset"; + reg = <0x40100200 0x100>; + #reset-cells = <1>; + status = "disabled"; + }; + + pinctrl: pinctrl@40110000 { + compatible = "realtek,rts5817-pinctrl"; + reg = <0x40110000 0x800>, + <0x401E2074 0x4>, + <0x401E2080 0xC>; + #address-cells = <1>; + #size-cells = <1>; + status = "okay"; + }; + + watchdog: watchdog@40100048 { + compatible = "realtek,rts5817-watchdog"; + reg = <0x40100048 0x4>; + status = "disabled"; + }; + + uart0: dwapb@40120000 { + compatible = "ns16550"; + reg = <0x40120000 0x100>; + reg-shift = <2>; + interrupt-parent = <&nvic>; + interrupts = ; + clocks = <&clks RTS_FP_CLK_UART0>; + resets = <&reset SYS_FORCE_RST_UART0>; + status = "disabled"; + }; + + uart1: dwapb@40128000 { + compatible = "ns16550"; + reg = <0x40128000 0x100>; + reg-shift = <2>; + interrupt-parent = <&nvic>; + interrupts = ; + clocks = <&clks RTS_FP_CLK_UART1>; + resets = <&reset SYS_FORCE_RST_UART1>; + status = "disabled"; + }; + }; +}; + +&nvic { + arm,num-irq-priority-bits = <3>; +}; diff --git a/dts/bindings/clock/realtek,rts5817-clock.yaml b/dts/bindings/clock/realtek,rts5817-clock.yaml new file mode 100644 index 0000000000000..e341c8184ecc1 --- /dev/null +++ b/dts/bindings/clock/realtek,rts5817-clock.yaml @@ -0,0 +1,18 @@ +# Copyright (c) 2024 Realtek Semiconductor, Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: Realtek RTS5817 clock + +compatible: "realtek,rts5817-clock" + +include: [clock-controller.yaml, base.yaml] + +properties: + reg: + required: true + + "#clock-cells": + const: 1 + +clock-cells: + - clkid diff --git a/dts/bindings/pinctrl/realtek,rts5817-pinctrl.yaml b/dts/bindings/pinctrl/realtek,rts5817-pinctrl.yaml new file mode 100644 index 0000000000000..1b7d53bdc8567 --- /dev/null +++ b/dts/bindings/pinctrl/realtek,rts5817-pinctrl.yaml @@ -0,0 +1,33 @@ +# Copyright (c) 2024 Realtek Semiconductor, Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: | + Realtek RTS5817 series pin controller + +compatible: "realtek,rts5817-pinctrl" + +include: base.yaml + +child-binding: + description: RTS5817 pin controller pin group. + child-binding: + description: RTS5817 pin controller pin mux and configuration. + + include: + - name: pincfg-node.yaml + property-allowlist: + - bias-disable + - bias-pull-down + - bias-pull-up + - input-enable + - output-enable + - drive-strength + - power-source + + properties: + pinmux: + required: true + type: array + description: | + An array of pins sharing the same group properties. Must + encode all the pin muxing information in a 32-bit value. diff --git a/dts/bindings/reset/realtek,rts5817-reset.yaml b/dts/bindings/reset/realtek,rts5817-reset.yaml new file mode 100644 index 0000000000000..6d9f8c980ed52 --- /dev/null +++ b/dts/bindings/reset/realtek,rts5817-reset.yaml @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Realtek Semiconductor, Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: Realtek RTS5817 Peripheral reset controller + +compatible: "realtek,rts5817-reset" + +include: [reset-controller.yaml, base.yaml] + +properties: + "#reset-cells": + const: 1 + +reset-cells: + - id diff --git a/dts/bindings/watchdog/realtek,rts5817-watchdog.yaml b/dts/bindings/watchdog/realtek,rts5817-watchdog.yaml new file mode 100644 index 0000000000000..b440dea52b046 --- /dev/null +++ b/dts/bindings/watchdog/realtek,rts5817-watchdog.yaml @@ -0,0 +1,13 @@ +# Copyright (c) 2024 Realtek Semiconductor, Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: | + Realtek RTS5817 Watchdog driver + +compatible: "realtek,rts5817-watchdog" + +include: base.yaml + +properties: + reg: + required: true diff --git a/include/zephyr/dt-bindings/clock/rts5817_clock.h b/include/zephyr/dt-bindings/clock/rts5817_clock.h new file mode 100644 index 0000000000000..a090942a24be6 --- /dev/null +++ b/include/zephyr/dt-bindings/clock/rts5817_clock.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_RTS5817_CLOCK_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_RTS5817_CLOCK_H_ + +#define RTS_FP_CLK_SYS_PLL 0 +#define RTS_FP_CLK_BUS 1 +#define RTS_FP_CLK_SPI_CACHE 2 +#define RTS_FP_CLK_SPI_SSOR 3 +#define RTS_FP_CLK_SPI_SSI_M 4 +#define RTS_FP_CLK_SPI_SSI_S 5 +#define RTS_FP_CLK_SHA 6 +#define RTS_FP_CLK_AES 7 +#define RTS_FP_CLK_PKE 8 +#define RTS_FP_CLK_I2C0 9 +#define RTS_FP_CLK_I2C1 10 +#define RTS_FP_CLK_TRNG 11 +#define RTS_FP_CLK_I2C_S 12 +#define RTS_FP_CLK_UART0 13 +#define RTS_FP_CLK_UART1 14 +#define RTS_FP_CLK_SIE 15 +#define RTS_FP_CLK_PUF 16 +#define RTS_FP_CLK_GE 17 + +#define RLX_CLK_NUM_SIZE (RTS_FP_CLK_GE + 1) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_RTS5817_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/interrupt-controller/rts5817_intc.h b/include/zephyr/dt-bindings/interrupt-controller/rts5817_intc.h new file mode 100644 index 0000000000000..da0214eb15bb7 --- /dev/null +++ b/include/zephyr/dt-bindings/interrupt-controller/rts5817_intc.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_INTERRUPT_CONTROLLER_RTS5817_INTC_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_INTERRUPT_CONTROLLER_RTS5817_INTC_H_ + +#define IRQ_NUM_SIE 0 +#define IRQ_NUM_MC 1 +#define IRQ_NUM_SENSOR_SPI 4 +#define IRQ_NUM_SPI_MASTER 5 +#define IRQ_NUM_AES 6 +#define IRQ_NUM_SHA 7 +#define IRQ_NUM_GPIO 11 +#define IRQ_NUM_SP_GPIO 12 +#define IRQ_NUM_UART0 15 +#define IRQ_NUM_UART1 16 +#define IRQ_NUM_SPI_SLAVE 23 + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_INTERRUPT_CONTROLLER_RTS5817_INTC_H_ */ diff --git a/include/zephyr/dt-bindings/pinctrl/rts5817_pinctrl.h b/include/zephyr/dt-bindings/pinctrl/rts5817_pinctrl.h new file mode 100644 index 0000000000000..3f2cae63a35e6 --- /dev/null +++ b/include/zephyr/dt-bindings/pinctrl/rts5817_pinctrl.h @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_RTS5817_PINCTRL_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_RTS5817_PINCTRL_H_ + +/** + * Fields: + * + * - pin [ 7 : 0 ] + * - func [ 10 : 8 ] + */ +#define RTS_FP_PIN_SHIFT 0U +#define RTS_FP_PIN_MASK 0xFFU +#define RTS_FP_FUNC_SHIFT 8U +#define RTS_FP_FUNC_MASK 0x1FU + +#define RTS_FP_PINMUX(pin, func) \ + ((((RTS_FP_PIN_##pin) & RTS_FP_PIN_MASK) << RTS_FP_PIN_SHIFT) | \ + (((RTS_FP_PIN_##func) & RTS_FP_FUNC_MASK) << RTS_FP_FUNC_SHIFT)) + +#define RTS_FP_PINMUX_PIN(__pin) (((__pin) >> RTS_FP_PIN_SHIFT) & RTS_FP_PIN_MASK) +#define RTS_FP_PINMUX_FUNC(__pin) (((__pin) >> RTS_FP_FUNC_SHIFT) & RTS_FP_FUNC_MASK) + +#define IO_POWER_1V8 0 +#define IO_POWER_3V3 1 + +#define RTS_FP_PIN_FUNC0 0 +#define RTS_FP_PIN_FUNC1 1 +#define RTS_FP_PIN_FUNC2 2 +#define RTS_FP_PIN_FUNC3 3 +#define RTS_FP_PIN_FUNC4 4 +#define RTS_FP_PIN_FUNC5 5 +#define RTS_FP_PIN_FUNC6 6 +#define RTS_FP_PIN_FUNC7 7 + +#define RTS_FP_PIN_CACHE_CS1 0 +#define RTS_FP_PIN_CACHE_MISO 1 +#define RTS_FP_PIN_CACHE_MOSI 2 +#define RTS_FP_PIN_CACHE_SCK 3 +#define RTS_FP_PIN_CACHE_WP 4 +#define RTS_FP_PIN_CACHE_HOLD 5 +#define RTS_FP_PIN_CACHE_CS2 6 +#define RTS_FP_PIN_SNR_MISO 7 +#define RTS_FP_PIN_SNR_MOSI 8 +#define RTS_FP_PIN_SNR_CLK 9 +#define RTS_FP_PIN_SSI_M_MISO 10 +#define RTS_FP_PIN_SSI_M_MOSI 11 +#define RTS_FP_PIN_SSI_M_CS 12 +#define RTS_FP_PIN_SSI_M_SCK 13 +#define RTS_FP_PIN_SCL0 14 +#define RTS_FP_PIN_SDA0 15 +#define RTS_FP_PIN_SCL2 16 +#define RTS_FP_PIN_SDA2 17 +#define RTS_FP_PIN_SCL1 18 +#define RTS_FP_PIN_SDA1 19 +#define RTS_FP_PIN_SSI_S_MISO 20 +#define RTS_FP_PIN_SSI_S_MOSI 21 +#define RTS_FP_PIN_SSI_S_CS 22 +#define RTS_FP_PIN_SSI_S_SCK 23 +#define RTS_FP_PIN_GPIO14 24 +#define RTS_FP_PIN_GPIO15 25 +#define RTS_FP_PIN_AL0 26 +#define RTS_FP_PIN_AL1 27 +#define RTS_FP_PIN_AL2 28 +#define RTS_FP_PIN_SNR_RST 29 +#define RTS_FP_PIN_SNR_CS 30 +#define RTS_FP_PIN_SNR_GPIO 31 + +#define P_CACHE_CS2_F_CACHE_CS2 RTS_FP_PINMUX(CACHE_CS2, FUNC0) +#define P_CACHE_CS2_F_GPIO RTS_FP_PINMUX(CACHE_CS2, FUNC1) + +#define P_SNR_MISO_F_SNR_MISO RTS_FP_PINMUX(SNR_MISO, FUNC0) +#define P_SNR_MOSI_F_SNR_MOSI RTS_FP_PINMUX(SNR_MOSI, FUNC0) +#define P_SNR_CLK_F_SNR_CLK RTS_FP_PINMUX(SNR_CLK, FUNC0) + +#define P_SSI_M_MISO_F_GPIO RTS_FP_PINMUX(SSI_M_MISO, FUNC0) +#define P_SSI_M_MISO_F_PWM RTS_FP_PINMUX(SSI_M_MISO, FUNC1) +#define P_SSI_M_MISO_F_SSI_M_MISO RTS_FP_PINMUX(SSI_M_MISO, FUNC2) +#define P_SSI_M_MISO_F_SSI_S_MISO RTS_FP_PINMUX(SSI_M_MISO, FUNC3) +#define P_SSI_M_MISO_F_UART1_RX RTS_FP_PINMUX(SSI_M_MISO, FUNC4) +#define P_SSI_M_MISO_F_ASIC_DBG RTS_FP_PINMUX(SSI_M_MISO, FUNC5) + +#define P_SSI_M_MOSI_F_GPIO RTS_FP_PINMUX(SSI_M_MOSI, FUNC0) +#define P_SSI_M_MOSI_F_PWM RTS_FP_PINMUX(SSI_M_MOSI, FUNC1) +#define P_SSI_M_MOSI_F_SSI_M_MOSI RTS_FP_PINMUX(SSI_M_MOSI, FUNC2) +#define P_SSI_M_MOSI_F_SSI_S_MOSI RTS_FP_PINMUX(SSI_M_MOSI, FUNC3) +#define P_SSI_M_MOSI_F_UART1_TX RTS_FP_PINMUX(SSI_M_MOSI, FUNC4) +#define P_SSI_M_MOSI_F_ASIC_DBG RTS_FP_PINMUX(SSI_M_MOSI, FUNC5) + +#define P_SSI_M_CS_F_GPIO RTS_FP_PINMUX(SSI_M_CS, FUNC0) +#define P_SSI_M_CS_F_PWM RTS_FP_PINMUX(SSI_M_CS, FUNC1) +#define P_SSI_M_CS_F_SSI_M_CS RTS_FP_PINMUX(SSI_M_CS, FUNC2) +#define P_SSI_M_CS_F_SSI_S_CS RTS_FP_PINMUX(SSI_M_CS, FUNC3) +#define P_SSI_M_CS_F_UART1_RTS RTS_FP_PINMUX(SSI_M_CS, FUNC4) +#define P_SSI_M_CS_F_ASIC_DBG RTS_FP_PINMUX(SSI_M_CS, FUNC5) + +#define P_SSI_M_SCK_F_GPIO RTS_FP_PINMUX(SSI_M_SCK, FUNC0) +#define P_SSI_M_SCK_F_PWM RTS_FP_PINMUX(SSI_M_SCK, FUNC1) +#define P_SSI_M_SCK_F_SSI_M_CLK RTS_FP_PINMUX(SSI_M_SCK, FUNC2) +#define P_SSI_M_SCK_F_SSI_S_CLK RTS_FP_PINMUX(SSI_M_SCK, FUNC3) +#define P_SSI_M_SCK_F_UART1_CTS RTS_FP_PINMUX(SSI_M_SCK, FUNC4) +#define P_SSI_M_SCK_F_ASIC_DBG RTS_FP_PINMUX(SSI_M_SCK, FUNC5) + +#define P_SCL0_F_GPIO RTS_FP_PINMUX(SCL0, FUNC0) +#define P_SCL0_F_PWM RTS_FP_PINMUX(SCL0, FUNC1) +#define P_SCL0_F_I2C0_SCL RTS_FP_PINMUX(SCL0, FUNC2) +#define P_SCL0_F_UART0_RX RTS_FP_PINMUX(SCL0, FUNC3) +#define P_SCL0_F_SWD_CLK RTS_FP_PINMUX(SCL0, FUNC4) +#define P_SCL0_F_ASIC_DBG RTS_FP_PINMUX(SCL0, FUNC5) + +#define P_SDA0_F_GPIO RTS_FP_PINMUX(SDA0, FUNC0) +#define P_SDA0_F_PWM RTS_FP_PINMUX(SDA0, FUNC1) +#define P_SDA0_F_I2C0_SDA RTS_FP_PINMUX(SDA0, FUNC2) +#define P_SDA0_F_UART0_TX RTS_FP_PINMUX(SDA0, FUNC3) +#define P_SDA0_F_SWD_DAT RTS_FP_PINMUX(SDA0, FUNC4) +#define P_SDA0_F_ASIC_DBG RTS_FP_PINMUX(SDA0, FUNC5) + +#define P_SCL2_F_GPIO RTS_FP_PINMUX(SCL2, FUNC0) +#define P_SCL2_F_PWM RTS_FP_PINMUX(SCL2, FUNC1) +#define P_SCL2_F_I2C2_SCL RTS_FP_PINMUX(SCL2, FUNC2) +#define P_SCL2_F_UART0_RX RTS_FP_PINMUX(SCL2, FUNC3) +#define P_SCL2_F_SWD_CLK RTS_FP_PINMUX(SCL2, FUNC4) +#define P_SCL2_F_ASIC_DBG RTS_FP_PINMUX(SCL2, FUNC5) + +#define P_SDA2_F_GPIO RTS_FP_PINMUX(SDA2, FUNC0) +#define P_SDA2_F_PWM RTS_FP_PINMUX(SDA2, FUNC1) +#define P_SDA2_F_I2C2_SDA RTS_FP_PINMUX(SDA2, FUNC2) +#define P_SDA2_F_UART0_TX RTS_FP_PINMUX(SDA2, FUNC3) +#define P_SDA2_F_SWD_DAT RTS_FP_PINMUX(SDA2, FUNC4) +#define P_SDA2_F_ASIC_DBG RTS_FP_PINMUX(SDA2, FUNC5) + +#define P_SCL1_F_GPIO RTS_FP_PINMUX(SCL1, FUNC0) +#define P_SCL1_F_PWM RTS_FP_PINMUX(SCL1, FUNC1) +#define P_SCL1_F_I2C1_SCL RTS_FP_PINMUX(SCL1, FUNC2) +#define P_SCL1_F_JTAG_TCK RTS_FP_PINMUX(SCL1, FUNC4) + +#define P_SDA1_F_GPIO RTS_FP_PINMUX(SDA1, FUNC0) +#define P_SDA1_F_PWM RTS_FP_PINMUX(SDA1, FUNC1) +#define P_SDA1_F_I2C1_SDA RTS_FP_PINMUX(SDA1, FUNC2) +#define P_SDA1_F_JTAG_TMS RTS_FP_PINMUX(SDA1, FUNC4) + +#define P_SSI_S_MISO_F_GPIO RTS_FP_PINMUX(SSI_S_MISO, FUNC0) +#define P_SSI_S_MISO_F_PWM RTS_FP_PINMUX(SSI_S_MISO, FUNC1) +#define P_SSI_S_MISO_F_SSI_S_MISO RTS_FP_PINMUX(SSI_S_MISO, FUNC2) +#define P_SSI_S_MISO_F_UART1_RX RTS_FP_PINMUX(SSI_S_MISO, FUNC3) +#define P_SSI_S_MISO_F_JTAG_TDI RTS_FP_PINMUX(SSI_S_MISO, FUNC4) + +#define P_SSI_S_MOSI_F_GPIO RTS_FP_PINMUX(SSI_S_MOSI, FUNC0) +#define P_SSI_S_MOSI_F_PWM RTS_FP_PINMUX(SSI_S_MOSI, FUNC1) +#define P_SSI_S_MOSI_F_SSI_S_MOSI RTS_FP_PINMUX(SSI_S_MOSI, FUNC2) +#define P_SSI_S_MOSI_F_UART1_TX RTS_FP_PINMUX(SSI_S_MOSI, FUNC3) +#define P_SSI_S_MOSI_F_JTAG_TRST RTS_FP_PINMUX(SSI_S_MOSI, FUNC4) + +#define P_SSI_S_CS_F_GPIO RTS_FP_PINMUX(SSI_S_CS, FUNC0) +#define P_SSI_S_CS_F_PWM RTS_FP_PINMUX(SSI_S_CS, FUNC1) +#define P_SSI_S_CS_F_SSI_S_CS RTS_FP_PINMUX(SSI_S_CS, FUNC2) +#define P_SSI_S_CS_F_UART1_RTS RTS_FP_PINMUX(SSI_S_CS, FUNC3) +#define P_SSI_S_CS_F_JTAG_TDO RTS_FP_PINMUX(SSI_S_CS, FUNC4) + +#define P_SSI_S_SCK_F_GPIO RTS_FP_PINMUX(SSI_S_SCK, FUNC0) +#define P_SSI_S_SCK_F_PWM RTS_FP_PINMUX(SSI_S_SCK, FUNC1) +#define P_SSI_S_SCK_F_SSI_S_CLK RTS_FP_PINMUX(SSI_S_SCK, FUNC2) +#define P_SSI_S_SCK_F_UART1_CTS RTS_FP_PINMUX(SSI_S_SCK, FUNC3) + +#define P_GPIO14_F_GPIO RTS_FP_PINMUX(GPIO14, FUNC0) +#define P_GPIO14_F_PWM RTS_FP_PINMUX(GPIO14, FUNC1) +#define P_GPIO14_F_UART0_RX RTS_FP_PINMUX(GPIO14, FUNC2) + +#define P_GPIO15_F_GPIO RTS_FP_PINMUX(GPIO15, FUNC0) +#define P_GPIO15_F_PWM RTS_FP_PINMUX(GPIO15, FUNC1) +#define P_GPIO15_F_UART0_TX RTS_FP_PINMUX(GPIO15, FUNC2) + +#define P_AL0_F_GPIO RTS_FP_PINMUX(AL0, FUNC0) +#define P_AL0_F_PWM RTS_FP_PINMUX(AL0, FUNC1) +#define P_AL0_F_CS_BRIDGE RTS_FP_PINMUX(AL0, FUNC2) + +#define P_AL1_F_GPIO RTS_FP_PINMUX(AL1, FUNC0) +#define P_AL1_F_PWM RTS_FP_PINMUX(AL1, FUNC1) + +#define P_AL2_F_GPIO RTS_FP_PINMUX(AL2, FUNC0) +#define P_AL2_F_PWM RTS_FP_PINMUX(AL2, FUNC1) + +#define P_SNR_RST_F_SNR_RST RTS_FP_PINMUX(SNR_RST, FUNC0) + +#define P_SNR_CS_F_SNR_CS RTS_FP_PINMUX(SNR_CS, FUNC0) +#define P_SNR_CS_F_GPIO RTS_FP_PINMUX(SNR_CS, FUNC1) + +#define P_SNR_GPIO_F_GPIO RTS_FP_PINMUX(SNR_GPIO, FUNC0) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_RTS5817_PINCTRL_H_ */ diff --git a/include/zephyr/dt-bindings/reset/rts5817_reset.h b/include/zephyr/dt-bindings/reset/rts5817_reset.h new file mode 100644 index 0000000000000..1a889f578cdab --- /dev/null +++ b/include/zephyr/dt-bindings/reset/rts5817_reset.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_RESET_RTS5817_RESET_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_RESET_RTS5817_RESET_H_ + +#define SYS_FORCE_RST_BUS 0 +#define SYS_FORCE_RST_AES 1 +#define SYS_FORCE_RST_GE 2 +#define SYS_FORCE_RST_SHA 3 +#define SYS_FORCE_RST_SPI_CACHE 4 +#define SYS_FORCE_RST_SPI_SSOR 5 +#define SYS_FORCE_RST_SPI_SSI_M 6 +#define SYS_FORCE_RST_SPI_SSI_S 7 +#define SYS_FORCE_RST_PKE 8 +#define SYS_FORCE_RST_I2C 9 +#define SYS_FORCE_RST_I2C0 10 +#define SYS_FORCE_RST_I2C1 11 +#define SYS_FORCE_RST_TRNG 12 +#define SYS_FORCE_RST_I2C_S 13 +#define SYS_FORCE_RST_UART0 14 +#define SYS_FORCE_RST_UART1 15 +#define SYS_FORCE_RST_PUF 16 +#define SYS_FORCE_RST_USB2 17 +#define SYS_FORCE_RST_CK30M 18 +#define SYS_FORCE_RST_CK60M 19 +#define SYS_FORCE_RST_CK120M 20 +#define SYS_FORCE_RST_USB2_PHY 21 +#define SYS_FORCE_RST_SYS 22 +#define SYS_FORCE_RST_DPHY 23 +#define SYS_FORCE_RST_SSI_S_BUS 24 + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_RESET_RTS5817_RESET_H_ */ diff --git a/scripts/west_commands/runners/__init__.py b/scripts/west_commands/runners/__init__.py index fc318e3d6cc7e..5e81a8ed1b203 100644 --- a/scripts/west_commands/runners/__init__.py +++ b/scripts/west_commands/runners/__init__.py @@ -56,6 +56,7 @@ def _import_runner_module(runner_name): 'renode', 'renode-robot', 'rfp', + 'rtsflash', 'silabs_commander', 'spi_burn', 'spsdk', diff --git a/scripts/west_commands/runners/rtsflash.py b/scripts/west_commands/runners/rtsflash.py new file mode 100644 index 0000000000000..784a615fc40cc --- /dev/null +++ b/scripts/west_commands/runners/rtsflash.py @@ -0,0 +1,174 @@ +# Copyright (c) 2024 Realtek Semiconductor, Inc. +# +# SPDX-License-Identifier: Apache-2.0 + +"""Runner for flashing with rtsflash.""" + +import subprocess +import sys +import time + +import usb.core +import usb.util + +from runners.core import RunnerCaps, ZephyrBinaryRunner + +RTS_STANDARD_REQUEST = 0x0 + +RTS_STD_GET_STATUS = 0x1A +RTS_STD_SET_STATUS = 0x1B + +RTS_STD_DOWNLOAD_ENABLE = 0x1 +RTS_STD_DOWNLOAD_DISABLE = 0x1 + +RTS_VENDOR_REQUEST = 0x40 +RTS_VREQ_XMEM_WRITE = 0x40 +RTS_VREQ_XMEM_READ = 0x41 +RTS_VREQ_SF_ERASE_SECTOR = 0x33 + +RTS_SET_FW_VERSION = 0x01 +RTS_DOWNLOAD_IMAGE = 0x03 +RTS_RESET_APP = 0x06 +RTS_GET_UPDATE_RESULT = 0x07 +RTS_RESET_IAP = 0x08 + + +class RtsUsb: + def __init__(self, device=None): + if not device: + idvendor = 0x0BDA + idproduct = 0x5817 + else: + idvendor = int(device.split(':', 1)[0], 16) + idproduct = int(device.split(':', 1)[1], 16) + dev = usb.core.find(idVendor=idvendor, idProduct=idproduct) + if not dev: + raise RuntimeError("device not found") + self.dev = dev + self.mode = "" + self.get_mode() + + def __del__(self): + usb.util.dispose_resources(self.dev) + + def enable_download(self): + if self.mode == "ROM": + status = self.dev.ctrl_transfer( + RTS_STANDARD_REQUEST | 0x80, RTS_STD_GET_STATUS, 0, 0, 1 + ) + if int.from_bytes(status, byteorder="little") == 0: + self.dev.ctrl_transfer(RTS_STANDARD_REQUEST, RTS_STD_SET_STATUS, 1, 0, 0) + + def xmem_write(self, addr, data): + setup_value = addr & 0xFFFF + setup_index = (addr >> 16) & 0xFFFF + self.dev.ctrl_transfer( + RTS_VENDOR_REQUEST, RTS_VREQ_XMEM_WRITE, setup_value, setup_index, data + ) + + def xmem_read(self, addr): + setup_value = addr & 0xFFFF + setup_index = (addr >> 16) & 0xFFFF + ret = self.dev.ctrl_transfer( + RTS_VENDOR_REQUEST | 0x80, RTS_VREQ_XMEM_READ, setup_value, setup_index, 4 + ) + return int.from_bytes(ret, byteorder="little") + + def get_mode(self): + init_vector = self.xmem_read(0x401E2090) + if init_vector == 0: + self.mode = "ROM" + elif init_vector == 0x01800000: + self.mode = "IAP" + else: + raise ValueError("Unknown work mode") + + +class RtsflashBinaryRunner(ZephyrBinaryRunner): + """Runner front-end for rtsflash.""" + + def __init__(self, cfg, dev_id, alt, img, exe='dfu-util'): + super().__init__(cfg) + self.dev_id = dev_id + self.alt = alt + self.img = img + self.cmd = [exe, f'-d {dev_id}'] + try: + self.list_pattern = f', alt={int(self.alt)},' + except ValueError: + self.list_pattern = f', name="{self.alt}",' + self.reset = False + + @classmethod + def name(cls): + return "rtsflash" + + @classmethod + def capabilities(cls): + return RunnerCaps(commands={"flash"}, dev_id=True) + + @classmethod + def dev_id_help(cls) -> str: + return 'USB VID:PID of the connected device.' + + @classmethod + def do_add_parser(cls, parser): + parser.add_argument( + "--alt", required=True, help="interface alternate setting number or name" + ) + parser.add_argument("--pid", dest='dev_id', help=cls.dev_id_help()) + parser.add_argument("--img", help="binary to flash, default is --bin-file") + parser.add_argument( + '--dfu-util', default='dfu-util', help='dfu-util executable; defaults to "dfu-util"' + ) + + @classmethod + def do_create(cls, cfg, args): + if args.img is None: + args.img = cfg.bin_file + + ret = RtsflashBinaryRunner(cfg, args.dev_id, args.alt, args.img, exe=args.dfu_util) + + ret.ensure_device() + return ret + + def ensure_device(self): + if not self.find_device(): + self.reset = True + print('Please reset your board to switch to DFU mode...') + while not self.find_device(): + time.sleep(0.1) + + def find_device(self): + cmd = list(self.cmd) + ['-l'] + output = self.check_output(cmd) + output = output.decode(sys.getdefaultencoding()) + return self.list_pattern in output + + def do_run(self, command, **kwargs): + if not self.dev_id: + raise RuntimeError( + 'Please specify a USB VID:PID with the -i/--dev-id or --pid command-line switch.' + ) + + self.require(self.cmd[0]) + self.ensure_output('bin') + + if not self.find_device(): + raise RuntimeError('device not found') + + fpusb = RtsUsb(self.dev_id) + + fpusb.enable_download() + + try: + self.check_call(['dfu-suffix', '-c', self.img]) + except subprocess.CalledProcessError: + self.call(['dfu-suffix', '-a', self.img]) + + cmd = list(self.cmd) + cmd.extend(['-a', self.alt, '-D', self.img]) + self.check_call(cmd) + + if self.reset: + print('Now reset your board again to switch back to runtime mode.') diff --git a/soc/realtek/fingerprint/CMakeLists.txt b/soc/realtek/fingerprint/CMakeLists.txt new file mode 100644 index 0000000000000..9c70da2e9689c --- /dev/null +++ b/soc/realtek/fingerprint/CMakeLists.txt @@ -0,0 +1,5 @@ +# Copyright (c) 2024 Realtek Semiconductor, Inc. +# SPDX-License-Identifier: Apache-2.0 + +add_subdirectory(common) +add_subdirectory(${SOC_SERIES}) diff --git a/soc/realtek/fingerprint/Kconfig b/soc/realtek/fingerprint/Kconfig new file mode 100644 index 0000000000000..1115379b858e8 --- /dev/null +++ b/soc/realtek/fingerprint/Kconfig @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Realtek Semiconductor, Inc. +# SPDX-License-Identifier: Apache-2.0 + +if SOC_FAMILY_FINGERPRINT + +rsource "*/Kconfig" + +endif # SOC_FAMILY_FINGERPRINT diff --git a/soc/realtek/fingerprint/Kconfig.defconfig b/soc/realtek/fingerprint/Kconfig.defconfig new file mode 100644 index 0000000000000..6099c0fda301b --- /dev/null +++ b/soc/realtek/fingerprint/Kconfig.defconfig @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Realtek Semiconductor, Inc. +# SPDX-License-Identifier: Apache-2.0 + +if SOC_FAMILY_FINGERPRINT + +rsource "*/Kconfig.defconfig" + +endif # SOC_FAMILY_FINGERPRINT diff --git a/soc/realtek/fingerprint/Kconfig.soc b/soc/realtek/fingerprint/Kconfig.soc new file mode 100644 index 0000000000000..a8c804f20a142 --- /dev/null +++ b/soc/realtek/fingerprint/Kconfig.soc @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Realtek Semiconductor, Inc. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_FINGERPRINT + bool + +config SOC_FAMILY + default "fingerprint" if SOC_FAMILY_FINGERPRINT + +rsource "*/Kconfig.soc" diff --git a/soc/realtek/fingerprint/common/CMakeLists.txt b/soc/realtek/fingerprint/common/CMakeLists.txt new file mode 100644 index 0000000000000..5a2c49a163e4e --- /dev/null +++ b/soc/realtek/fingerprint/common/CMakeLists.txt @@ -0,0 +1,20 @@ +# Copyright (c) 2024 Realtek Semiconductor, Inc. +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories(.) + +set(RTS_BIN_NAME ${CONFIG_KERNEL_BIN_NAME}.rts5817.bin) +string(TOUPPER "${SOC_NAME}" soc_name_upper) + +if(APPVERSION) + set(version ${APPVERSION}) +else() + set(version 0) +endif() + +set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + COMMAND ${PYTHON_EXECUTABLE} ${SOC_${soc_name_upper}_DIR}/common/tool/gen_download_bin.py + -i ${KERNEL_BIN_NAME} + -o ${RTS_BIN_NAME} + -v ${version} +) diff --git a/soc/realtek/fingerprint/common/tool/gen_download_bin.py b/soc/realtek/fingerprint/common/tool/gen_download_bin.py new file mode 100755 index 0000000000000..e7e6dc8fa015f --- /dev/null +++ b/soc/realtek/fingerprint/common/tool/gen_download_bin.py @@ -0,0 +1,164 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2024 Realtek Semiconductor, Inc. +# +# SPDX-License-Identifier: Apache-2.0 + +import argparse +import hashlib +import pathlib +import sys + +PATCH_FLAG = 0x3 +PATCH_FLAG_OFFSET = 0x0 +PATCH_FLAG_LEN = 0x4 +PATCH_IMG_SIZE_OFFSET = 0x4 +PATCH_IMG_SIZE_LEN = 0x2 + +PATCH_CONFIG_LEN = 0x50 +PATCH_RESERVED_LEN = 0xF70 +PATCH_SHA_LEN = 0x20 +PATCH_PADDING_LEN = 0x20 + +IMG_HEADER_FLAG = 0x2 +IMG_HEADER_FLAG_OFFSET = 0x0 +IMG_HEADER_FLAG_LEN = 0x4 +IMG_HEADER_VER_OFFSET = 0x4 +IMG_HEADER_VER_LEN = 0x4 +IMG_HEADER_RESERVED_LEN = 0xF8 + +IMG_SIZE_UNIT = 0x1000 +IMG_SHA_LEN = 0x20 +IMG_REAR_PADDING_LEN = 0x60 + + +def create_parser(arg_list): + """create argument parser according to pre-defined arguments + + :param arg_list: when empty, parses command line arguments, + else parses the given string + """ + parser = argparse.ArgumentParser(conflict_handler='resolve', allow_abbrev=False) + parser.add_argument("--input", "-i", nargs='?', dest="input") + parser.add_argument("--output", "-o", nargs='?', dest="output") + parser.add_argument("--version", "-v", type=lambda x: int(x, 16), dest="version") + + args = parser.parse_known_args(arg_list.split()) + + if arg_list == "": + args = parser.parse_known_args() + + return args + + +def file_check(input, output=None): + """check input and output files + If the input file is not exists or empty, raise error + + :param input: the input file object + :param output: the output file object + """ + if not input.exists(): + raise RuntimeError(f'Input file ({input}) is not exists') + elif input.stat().st_size == 0: + raise RuntimeError(f'Input file ({input}) is empty') + + if output is None: + output = ['out_', input] + + if output.exists(): + if output.samefile(input): + raise RuntimeError(f'Input file {input} should be different from Output file {output}') + output.unlink() + + output.touch() + return output + + +def gen_rompatch(img_len): + """generate rom patch for image + + :param img_len: the length of image + """ + patch_config = bytearray([0x0] * PATCH_CONFIG_LEN) + patch_config[PATCH_FLAG_OFFSET] = PATCH_FLAG + patch_config[PATCH_IMG_SIZE_OFFSET] = img_len + patch_reserved = bytearray([0xFF] * PATCH_RESERVED_LEN) + patch = patch_config + patch_reserved + patch_sha = hashlib.sha256(patch).digest() + patch += patch_sha + patch_padding = bytearray([0xFF] * PATCH_PADDING_LEN) + patch += patch_padding + return patch + + +def gen_img_header(img_version=0): + """generate rom patch for image + + :param img_version: the version of image + """ + img_header = IMG_HEADER_FLAG.to_bytes(IMG_HEADER_FLAG_LEN, "little") + img_header += img_version.to_bytes(IMG_HEADER_VER_LEN, "little") + img_header += bytearray([0xFF] * IMG_HEADER_RESERVED_LEN) + return img_header + + +def img_padding(img): + size = len(img) // IMG_SIZE_UNIT + rear = len(img) % IMG_SIZE_UNIT + + if rear <= IMG_SIZE_UNIT - IMG_SHA_LEN - IMG_REAR_PADDING_LEN: + size += 1 + padding_len = IMG_SIZE_UNIT - rear - IMG_SHA_LEN - IMG_REAR_PADDING_LEN + else: + size += 2 + padding_len = 2 * IMG_SIZE_UNIT - rear - IMG_SHA_LEN - IMG_REAR_PADDING_LEN + + img_with_padding = img + bytes([0xFF] * padding_len) + return size, img_with_padding + + +def main(): + """main of the application""" + + if len(sys.argv) < 3: + sys.exit() + + input_file = None + output_file = None + fw_version = 0x0 + + # parser input arguments + arguments = create_parser("") + for arg in vars(arguments[0]): + if (arg == "input") & (arguments[0].input is not None): + input_file = arguments[0].input + elif (arg == "output") & (arguments[0].output is not None): + output_file = arguments[0].output + elif (arg == "version") & (arguments[0].version is not None): + fw_version = arguments[0].version + + # check file + output_file = file_check(pathlib.Path(input_file), pathlib.Path(output_file)) + + # generate image header + header = gen_img_header(fw_version) + + with open(input_file, 'rb') as origin_img_file: + # start handling + origin_img = origin_img_file.read() + img_with_header = header + origin_img + img_size, img_with_padding = img_padding(img_with_header) + img_sha = hashlib.sha256(img_with_padding).digest() + img_with_sha = img_with_padding + img_sha + rompatch = gen_rompatch(img_size) + final_img = rompatch + img_with_sha + bytes([0xFF] * IMG_REAR_PADDING_LEN) + origin_img_file.close() + + with open(output_file, 'wb') as new_fw: + new_fw.write(final_img) + new_fw.close() + + +if __name__ == '__main__': + main() diff --git a/soc/realtek/fingerprint/rts5817/CMakeLists.txt b/soc/realtek/fingerprint/rts5817/CMakeLists.txt new file mode 100644 index 0000000000000..281a5a12d6efa --- /dev/null +++ b/soc/realtek/fingerprint/rts5817/CMakeLists.txt @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Realtek Semiconductor, Inc. +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories(.) + +zephyr_sources(soc.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/realtek/fingerprint/rts5817/Kconfig b/soc/realtek/fingerprint/rts5817/Kconfig new file mode 100644 index 0000000000000..f5e69cb0a550e --- /dev/null +++ b/soc/realtek/fingerprint/rts5817/Kconfig @@ -0,0 +1,16 @@ +# Copyright (c) 2024 Realtek Semiconductor, Inc. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_RTS5817 + select ARM + select CPU_CORTEX_M33 + select CPU_HAS_FPU + select CPU_HAS_ARM_MPU + select CPU_HAS_DCACHE + select CPU_HAS_ICACHE + select CACHE_MANAGEMENT + select ARMV8_M_DSP + select INIT_ARCH_HW_AT_BOOT + select XIP + select ARCH_HAS_EXTRA_EXCEPTION_INFO + select SOC_EARLY_INIT_HOOK diff --git a/soc/realtek/fingerprint/rts5817/Kconfig.defconfig b/soc/realtek/fingerprint/rts5817/Kconfig.defconfig new file mode 100644 index 0000000000000..d22b301d71e1b --- /dev/null +++ b/soc/realtek/fingerprint/rts5817/Kconfig.defconfig @@ -0,0 +1,12 @@ +# Copyright (c) 2024 Realtek Semiconductor, Inc. +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_RTS5817 + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,/cpus/cpu@0,clock-frequency) + +config NUM_IRQS + default 32 + +endif # SOC_SERIES_RTS5817 diff --git a/soc/realtek/fingerprint/rts5817/Kconfig.soc b/soc/realtek/fingerprint/rts5817/Kconfig.soc new file mode 100644 index 0000000000000..34c7c144e2a43 --- /dev/null +++ b/soc/realtek/fingerprint/rts5817/Kconfig.soc @@ -0,0 +1,16 @@ +# Copyright (c) 2024 Realtek Semiconductor, Inc. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_RTS5817 + bool + select SOC_FAMILY_FINGERPRINT + +config SOC_RTS5817 + bool + select SOC_SERIES_RTS5817 + +config SOC + default "rts5817" if SOC_RTS5817 + +config SOC_SERIES + default "rts5817" if SOC_SERIES_RTS5817 diff --git a/soc/realtek/fingerprint/rts5817/pinctrl_soc.h b/soc/realtek/fingerprint/rts5817/pinctrl_soc.h new file mode 100644 index 0000000000000..1286dda78c7d8 --- /dev/null +++ b/soc/realtek/fingerprint/rts5817/pinctrl_soc.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SOC_ARM_REALTEK_RTS5817_PINCTRL_SOC_H_ +#define ZEPHYR_SOC_ARM_REALTEK_RTS5817_PINCTRL_SOC_H_ + +#include +#include + +typedef struct pinctrl_soc_pin { + uint8_t pin: 8; + uint8_t func: 3; + uint8_t pulldown: 1; + uint8_t pullup: 1; + uint8_t power_source: 2; +} pinctrl_soc_pin_t; + +#define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) \ + { \ + .pin = RTS_FP_PINMUX_PIN(DT_PROP_BY_IDX(node_id, prop, idx)), \ + .func = RTS_FP_PINMUX_FUNC(DT_PROP_BY_IDX(node_id, prop, idx)), \ + .pulldown = DT_PROP(node_id, bias_pull_down), \ + .pullup = DT_PROP(node_id, bias_pull_up), \ + .power_source = (DT_PROP_OR(node_id, power_source, IO_POWER_3V3)), \ + }, + +#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)} + +#endif /* ZEPHYR_SOC_ARM_REALTEK_RTS5817_PINCTRL_SOC_H_ */ diff --git a/soc/realtek/fingerprint/rts5817/soc.c b/soc/realtek/fingerprint/rts5817/soc.c new file mode 100644 index 0000000000000..fed999a48db97 --- /dev/null +++ b/soc/realtek/fingerprint/rts5817/soc.c @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#include + +/** + * @brief Initialize cache + * + */ +static void cache_init(void) +{ + sys_cache_instr_enable(); + sys_cache_data_enable(); +} + +/** + * @brief Perform basic hardware initialization at boot. + * + * This needs to be run from the very beginning. + */ +void soc_early_init_hook(void) +{ + cache_init(); +} diff --git a/soc/realtek/fingerprint/rts5817/soc.h b/soc/realtek/fingerprint/rts5817/soc.h new file mode 100644 index 0000000000000..ce0159199ba5f --- /dev/null +++ b/soc/realtek/fingerprint/rts5817/soc.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _SOC_H_ +#define _SOC_H_ + +#include +#include + +#endif /* _SOC_H_ */ diff --git a/soc/realtek/fingerprint/soc.yml b/soc/realtek/fingerprint/soc.yml new file mode 100644 index 0000000000000..a5b868f865229 --- /dev/null +++ b/soc/realtek/fingerprint/soc.yml @@ -0,0 +1,4 @@ +family: +- name: fingerprint + socs: + - name: rts5817