diff --git a/boards/ti/tms570_launchxl2/Kconfig.tms570_launchxl2 b/boards/ti/tms570_launchxl2/Kconfig.tms570_launchxl2 new file mode 100644 index 0000000000000..b709ab52ec4c9 --- /dev/null +++ b/boards/ti/tms570_launchxl2/Kconfig.tms570_launchxl2 @@ -0,0 +1,6 @@ +# Copyright (c) 2025 ispace, inc. +# +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_TMS570_LAUNCHXL2 + select SOC_TI_TMS570LC43X if BOARD_TMS570_LAUNCHXL2 diff --git a/boards/ti/tms570_launchxl2/board.yml b/boards/ti/tms570_launchxl2/board.yml new file mode 100644 index 0000000000000..492629ade64e9 --- /dev/null +++ b/boards/ti/tms570_launchxl2/board.yml @@ -0,0 +1,6 @@ +board: + name: tms570_launchxl2 + full_name: Hercules TMS570LC43x LaunchPad + vendor: ti + socs: + - name: ti_tms570lc43x diff --git a/boards/ti/tms570_launchxl2/doc/index.rst b/boards/ti/tms570_launchxl2/doc/index.rst new file mode 100644 index 0000000000000..37e842281b9d6 --- /dev/null +++ b/boards/ti/tms570_launchxl2/doc/index.rst @@ -0,0 +1,45 @@ +.. zephyr:board:: tms570_launchxl2 + +Overview +******** + +The Texas Instruments Hercules |trade| TMS570LC43x LaunchPad |trade| (LAUNCHXL2-570LC43) is a +development kit for the TMS570LC4357 MCU. + +See the `TI LAUNCHXL2-570LC43 Product Page`_ for details. + +Hardware +******** + +This development kit features the TMS570LC4357 MCU, which is a lockstep cached 300MHz +ARM® Cortex®-R5F based TMS570 series automotive-grade MCU designed to aid in the +development of ISO 26262 and IEC 61508 functional safety applications. + +The board is equipped with two LEDs, two push buttons and BoosterPack connectors +for expansion. It also includes an integrated (XDS110) debugger. + +See the `TI TMS570LC4357 Product Page`_ for additional details. + +Supported Features +================== + +.. zephyr:board-supported-hw:: + + +Programming and Debugging +************************* + +.. zephyr:board-supported-runners:: + +Programming and debugging is supported via either on-board XDS110 debugger, or +via another debugger such as the SEGGER J-Link connected on the 20 pin JTAG +connector. + +References +********** + +.. target-notes:: + +.. _TI LAUNCHXL2-570LC43 Product Page: https://www.ti.com/tool/LAUNCHXL2-570LC43 + +.. _TI TMS570LC4357 Product Page: https://www.ti.com/product/TMS570LC4357 diff --git a/boards/ti/tms570_launchxl2/tms570_launchxl2.dts b/boards/ti/tms570_launchxl2/tms570_launchxl2.dts new file mode 100644 index 0000000000000..dd65e6f1b3bc6 --- /dev/null +++ b/boards/ti/tms570_launchxl2/tms570_launchxl2.dts @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2025 ispace, inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +/dts-v1/; + +#include +#include +#include + +/ { + + model = "Hercules TMS570LC43x LaunchPad Development Kit"; + compatible = "ti,hercules-tms570-launchpad", "ti,tms570"; + + chosen { + zephyr,console = &sci1; + zephyr,shell-uart = &sci1; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + }; + + aliases { + led0 = &led_b7; + }; + + leds { + compatible = "gpio-leds"; + + led_b7: led_b7 { + gpios = <&gpio_b 7 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&sci1 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <>; + pinctrl-names = "default"; +}; + +&sci3 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&sci3_rx &sci3_tx>; + pinctrl-names = "default"; +}; + +&pinctrl { + sci3_rx: sci3_rx { + pinmux = <29 17>; + }; + + sci3_tx: sci3_tx { + pinmux = <31 9>; + }; +}; diff --git a/boards/ti/tms570_launchxl2/tms570_launchxl2_defconfig b/boards/ti/tms570_launchxl2/tms570_launchxl2_defconfig new file mode 100644 index 0000000000000..1deb21c2fe954 --- /dev/null +++ b/boards/ti/tms570_launchxl2/tms570_launchxl2_defconfig @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 +CONFIG_SERIAL=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_GPIO=y diff --git a/drivers/gpio/CMakeLists.txt b/drivers/gpio/CMakeLists.txt index 0e1cf4155ed9a..90bdde33be1c4 100644 --- a/drivers/gpio/CMakeLists.txt +++ b/drivers/gpio/CMakeLists.txt @@ -117,6 +117,7 @@ zephyr_library_sources_ifdef(CONFIG_GPIO_TCA6424A gpio_tca6424a.c) zephyr_library_sources_ifdef(CONFIG_GPIO_TELINK_B91 gpio_b91.c) zephyr_library_sources_ifdef(CONFIG_GPIO_TEST gpio_test.c) zephyr_library_sources_ifdef(CONFIG_GPIO_TLE9104 gpio_tle9104.c) +zephyr_library_sources_ifdef(CONFIG_GPIO_TMS570 gpio_tms570.c) zephyr_library_sources_ifdef(CONFIG_GPIO_WCH_GPIO wch_gpio_ch32v00x.c) zephyr_library_sources_ifdef(CONFIG_GPIO_XEC gpio_mchp_xec.c) zephyr_library_sources_ifdef(CONFIG_GPIO_XEC_V2 gpio_mchp_xec_v2.c) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 87271f0ff9411..c55def55b75d8 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -197,6 +197,7 @@ source "drivers/gpio/Kconfig.sy1xx" source "drivers/gpio/Kconfig.tca6424a" source "drivers/gpio/Kconfig.test" source "drivers/gpio/Kconfig.tle9104" +source "drivers/gpio/Kconfig.tms570" source "drivers/gpio/Kconfig.wch_ch32v00x" source "drivers/gpio/Kconfig.xec" source "drivers/gpio/Kconfig.xlnx" diff --git a/drivers/gpio/Kconfig.tms570 b/drivers/gpio/Kconfig.tms570 new file mode 100644 index 0000000000000..1ebe303394127 --- /dev/null +++ b/drivers/gpio/Kconfig.tms570 @@ -0,0 +1,9 @@ +# Copyright (c) 2025 ispace, inc. +# SPDX-License-Identifier: Apache-2.0 + +config GPIO_TMS570 + bool "TMS570 GPIO driver" + default y + depends on DT_HAS_TI_TMS570_GPIO_ENABLED + help + Enable driver for the TI TMS570 GPIO controller. diff --git a/drivers/gpio/gpio_tms570.c b/drivers/gpio/gpio_tms570.c new file mode 100644 index 0000000000000..3262c4848851c --- /dev/null +++ b/drivers/gpio/gpio_tms570.c @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2025 ispace, inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT ti_tms570_gpio + +#include +#include +#include +#include +#include + +/* port registers */ +#define REG_DIR 0x0000 /* Data Direction Register */ +#define REG_DIN 0x0004 /* Data Input Register */ +#define REG_DOUT 0x0008 /* Data Output Register */ +#define REG_DSET 0x000C /* Data Output Set Register */ +#define REG_DCLR 0x0010 /* Data Output Clear Register */ +#define REG_PDR 0x0014 /* Open Drain Register */ +#define REG_PULDIS 0x0018 /* Pullup Disable Register */ +#define REG_PSL 0x001C /* Pull Up/Down Selection Register */ + +/* GIO base registers */ +#define REG_GCR0 0x0000 /* Global Control Register */ +#define REG_INTDET 0x0008 /* Interrupt Detect Register*/ +#define REG_POL 0x000C /* Interrupt Polarity Register */ +#define REG_ENASET 0x0010 /* Interrupt Enable Set Register */ +#define REG_ENACLR 0x0014 /* Interrupt Enable Clear Register */ +#define REG_LVLSET 0x0018 /* Interrupt Priority Set Register */ +#define REG_LVLCLR 0x001C /* Interrupt Priority Clear Register */ +#define REG_FLG 0x0020 /* Interrupt Flag Register */ +#define REG_OFF1 0x0024 /* Interrupt Offset A Register */ +#define REG_OFF2 0x0028 /* Interrupt Offset B Register */ +#define REG_EMU1 0x002C /* Emulation 1 Register */ +#define REG_EMU2 0x0030 /* Emulation 2 Register */ + +struct gpio_tms570_config { + /* gpio_driver_config needs to be first */ + struct gpio_driver_config common; + uint32_t reg_gio; + uint32_t reg_port; +}; + +struct gpio_tms570_data { + /* gpio_driver_data needs to be first */ + struct gpio_driver_data common; +}; + +static int gpio_tms570_set_bits(const struct device *dev, gpio_port_pins_t pins) +{ + const struct gpio_tms570_config *config = dev->config; + + sys_write32(pins, config->reg_port + REG_DSET); + + return 0; +} + +static int gpio_tms570_clear_bits(const struct device *dev, gpio_port_pins_t pins) +{ + const struct gpio_tms570_config *config = dev->config; + uint32_t val; + + val = sys_read32(config->reg_port + REG_DIN); + sys_write32(val & pins, config->reg_port + REG_DCLR); + + return 0; +} + +static int gpio_tms570_port_set_masked_raw(const struct device *dev, + gpio_port_pins_t mask, + gpio_port_value_t value) +{ + const struct gpio_tms570_config *config = dev->config; + uint32_t cur_out; + uint32_t cur_dir; + uint32_t val_set; + uint32_t val_clr; + + cur_out = sys_read32(config->reg_port + REG_DIN); + cur_dir = sys_read32(config->reg_port + REG_DIR); + val_clr = cur_dir & cur_out & ~value & mask; + val_set = cur_dir & ~cur_out & value & mask; + + sys_write32(val_clr, config->reg_port + REG_DCLR); + sys_write32(val_set, config->reg_port + REG_DSET); + + return 0; +} + +static int gpio_tms570_port_toggle_bits(const struct device *dev, + gpio_port_pins_t pins) +{ + const struct gpio_tms570_config *config = dev->config; + uint32_t cur_out; + uint32_t cur_dir; + uint32_t val_set; + uint32_t val_clr; + + cur_out = sys_read32(config->reg_port + REG_DIN); + cur_dir = sys_read32(config->reg_port + REG_DIR); + val_clr = cur_dir & cur_out & pins; + val_set = cur_dir & ~cur_out & pins; + sys_write32(val_clr, config->reg_port + REG_DCLR); + sys_write32(val_set, config->reg_port + REG_DSET); + + return 0; +} + + +static int gpio_tms570_get(const struct device *dev, gpio_port_value_t *value) +{ + const struct gpio_tms570_config *config = dev->config; + + *value = sys_read32(config->reg_port + REG_DIN); + + return 0; +} + +static int gpio_tms570_configure(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags) +{ + const struct gpio_tms570_config *config = dev->config; + uint32_t current_config; + int ret; + + /* Read the current configuration of the pins */ + current_config = sys_read32(config->reg_port + REG_DIR); + + /* We only support changes in the direction of the pins */ + if ((flags & GPIO_INPUT) != 0U) { + /* Pins specified as input will have their DIR register's bit set to 0 */ + sys_write32(current_config & ~BIT(pin), config->reg_port + REG_DIR); + } else if ((flags & GPIO_OUTPUT) != 0U) { + /* Pins specified as output will have their DIR register's bit set to 1 */ + sys_write32(current_config | BIT(pin), config->reg_port + REG_DIR); + + if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0U) { + ret = gpio_tms570_set_bits(dev, (gpio_port_pins_t)BIT(pin)); + if (ret < 0) { + return ret; + } + } else if ((flags & GPIO_OUTPUT_INIT_LOW) != 0U) { + ret = gpio_tms570_clear_bits(dev, (gpio_port_pins_t)BIT(pin)); + if (ret < 0) { + return ret; + } + } + } else { + return -EINVAL; + } + + return 0; +} + +static int gpio_tms570_pin_interrupt_configure(const struct device *dev, gpio_pin_t pin, + enum gpio_int_mode mode, enum gpio_int_trig trig) +{ + return -ENOTSUP; +} + +static int gpio_tms570_manage_callback(const struct device *dev, struct gpio_callback *callback, + bool set) +{ + return -ENOTSUP; +} + +static const struct gpio_driver_api gpio_tms570_api = { + .port_get_raw = gpio_tms570_get, + .port_set_masked_raw = gpio_tms570_port_set_masked_raw, + .port_set_bits_raw = gpio_tms570_set_bits, + .port_clear_bits_raw = gpio_tms570_clear_bits, + .pin_configure = gpio_tms570_configure, + .port_toggle_bits = gpio_tms570_port_toggle_bits, + .pin_interrupt_configure = gpio_tms570_pin_interrupt_configure, + .manage_callback = gpio_tms570_manage_callback, +}; + +static int gpio_tms570_init(const struct device *dev) +{ + const struct gpio_tms570_config *config = dev->config; + static int gpio_tms570_init_done; + + if (gpio_tms570_init_done == 0) { + gpio_tms570_init_done = 1; + sys_write32(1, config->reg_gio + REG_GCR0); + sys_write32(0xFFU, config->reg_gio + REG_ENACLR); + sys_write32(0xFFU, config->reg_gio + REG_LVLCLR); + } + + return 0; +} + +#define TMS570_GPIO_INIT(n) \ + static struct gpio_tms570_data gpio_tms570_data_##n = { \ + }; \ + static struct gpio_tms570_config gpio_tms570_config_##n = { \ + .common = { \ + .port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(n), \ + }, \ + .reg_port = DT_INST_REG_ADDR_BY_IDX(n, 0), \ + .reg_gio = DT_INST_REG_ADDR_BY_IDX(n, 1), \ + }; \ + DEVICE_DT_INST_DEFINE(n, gpio_tms570_init, NULL, \ + &gpio_tms570_data_##n, &gpio_tms570_config_##n, \ + POST_KERNEL, CONFIG_GPIO_INIT_PRIORITY, \ + &gpio_tms570_api); + +DT_INST_FOREACH_STATUS_OKAY(TMS570_GPIO_INIT) diff --git a/drivers/interrupt_controller/CMakeLists.txt b/drivers/interrupt_controller/CMakeLists.txt index 080dcfe331816..acb300c8bc6c4 100644 --- a/drivers/interrupt_controller/CMakeLists.txt +++ b/drivers/interrupt_controller/CMakeLists.txt @@ -34,6 +34,7 @@ zephyr_library_sources_ifdef(CONFIG_INTC_ESP32 intc_esp32.c) zephyr_library_sources_ifdef(CONFIG_SWERV_PIC intc_swerv_pic.c) zephyr_library_sources_ifdef(CONFIG_VEXRISCV_LITEX_IRQ intc_vexriscv_litex.c) zephyr_library_sources_ifdef(CONFIG_VIM intc_vim.c) +zephyr_library_sources_ifdef(CONFIG_TMS570_VIM intc_tms570_vim.c) zephyr_library_sources_ifdef(CONFIG_CLIC intc_clic.c) zephyr_library_sources_ifdef(CONFIG_CLIC intc_clic.S) zephyr_library_sources_ifdef(CONFIG_NRFX_CLIC intc_nrfx_clic.c) diff --git a/drivers/interrupt_controller/Kconfig b/drivers/interrupt_controller/Kconfig index 3e6e554bc6d87..b320893d1a477 100644 --- a/drivers/interrupt_controller/Kconfig +++ b/drivers/interrupt_controller/Kconfig @@ -102,6 +102,8 @@ source "drivers/interrupt_controller/Kconfig.nxp_pint" source "drivers/interrupt_controller/Kconfig.vim" +source "drivers/interrupt_controller/Kconfig.tms570_vim" + source "drivers/interrupt_controller/Kconfig.renesas_rz" source "drivers/interrupt_controller/Kconfig.renesas_rx" diff --git a/drivers/interrupt_controller/Kconfig.tms570_vim b/drivers/interrupt_controller/Kconfig.tms570_vim new file mode 100644 index 0000000000000..3c5ffeb474f92 --- /dev/null +++ b/drivers/interrupt_controller/Kconfig.tms570_vim @@ -0,0 +1,11 @@ +# Copyright (C) 2025 ispace, inc. +# +# SPDX-License-Identifier: Apache-2.0 + +config TMS570_VIM + bool "TI Vectored Interrupt Manager (TMS570)" + default y + depends on DT_HAS_TI_TMS570_VIM_ENABLED + help + The TI Vectored Interrupt Manager provides hardware assistance for prioritizing + and aggregating the interrupt sources for TI herules ARM Cortex-R4/R5 processor cores. diff --git a/drivers/interrupt_controller/intc_tms570_vim.c b/drivers/interrupt_controller/intc_tms570_vim.c new file mode 100644 index 0000000000000..48178fad0a134 --- /dev/null +++ b/drivers/interrupt_controller/intc_tms570_vim.c @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2025 ispace, inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include +#include "soc_internal.h" +#include + +#define DT_DRV_COMPAT ti_tms570_vim + +#define DRV_CONTROL_REG DT_INST_REG_ADDR_BY_IDX(0, 0) +#define DRV_ECC_REG DT_INST_REG_ADDR_BY_IDX(0, 1) +#define DRV_VIMRAM_REG DT_INST_REG_ADDR_BY_IDX(0, 2) +#define DRV_VIMRAM_REG_SIZE DT_INST_REG_SIZE_BY_IDX(0, 2) + +/* control registers */ +#define VIM_REG_IRQINDEX (DRV_CONTROL_REG + 0x00) +#define VIM_REG_FIQINDEX (DRV_CONTROL_REG + 0x04) +#define VIM_REG_REQMASKSET_0 (DRV_CONTROL_REG + 0x30) +#define VIM_REG_REQMASKCLR_0 (DRV_CONTROL_REG + 0x40) + +/* ECC related registers */ +#define VIM_ECC_CTL (DRV_ECC_REG + 0xF0) + +#define REQUMASK_IRQ_PER_REG (32u) + +static inline void set_reqmask_bit(unsigned int irq, uintptr_t reg_0_addr) +{ + sys_write32(1 << (irq % REQUMASK_IRQ_PER_REG), + reg_0_addr + (irq / REQUMASK_IRQ_PER_REG) * sizeof(uint32_t)); +} + +static inline int get_reqmask_bit(unsigned int irq, uintptr_t reg_0_addr) +{ + return sys_read32(reg_0_addr + (irq / REQUMASK_IRQ_PER_REG) * sizeof(uint32_t)); +} + +/* count of number of times the phantom interrupt happened */ +unsigned int nr_phantom_isr; + +static void phantom_isr(void) +{ + /** + * we don't want this to call the z_spurious_irq because we have seen + * phantom irq happen even though we don't expect it to happen. + */ + nr_phantom_isr++; +} + +#if defined(CONFIG_RUNTIME_NMI) +static void tms570_nmi_handler(void) +{ + uint32_t vec = sys_read32(REG_ESM_IOFFHR) - 1; + + if (vec < 32) { + sys_write32(1 << vec, REG_ESM_SR1_0); + printk("\nESM Group 1 chan %u\n", vec); + } else if (vec < 64) { + sys_write32(1 << (vec - 32), REG_ESM_SR1_1); + printk("\nESM Group 2 chan %u\n", vec - 32); + } else if (vec < 96U) { + sys_write32(1 << (vec - 64), REG_ESM_SR4_0); + printk("\nESM Group 1 chan %u\n", vec - 32); + } else if ((vec >= 128U) && (vec < 160U)) { + sys_write32(1 << (vec - 128), REG_ESM_SR7_0); + printk("\nESM Group 1 chan %u\n", vec - 96); + } else { + sys_write32(0xFFFFFFFF, REG_ESM_SR7_0); + sys_write32(0xFFFFFFFF, REG_ESM_SR4_0); + sys_write32(0xFFFFFFFF, REG_ESM_SR1_0); + sys_write32(0xFFFFFFFF, REG_ESM_SR1_1); + } + + sys_reboot(SYS_REBOOT_WARM); +} +#endif + +/** + * @brief Get active interrupt ID (IRQ only) + * + * @return Returns the ID of an active interrupt + */ +unsigned int z_soc_irq_get_active(void) +{ + unsigned int irq_idx; + + /* a 0 means phantom ISR, channel 0 starts from index 1 */ + irq_idx = sys_read32(VIM_REG_IRQINDEX); + if (irq_idx > 0) { + z_soc_irq_disable(irq_idx - 1); + return irq_idx - 1; + + } else { + phantom_isr(); + } + + return (CONFIG_NUM_IRQS + 1); +} + +void z_soc_irq_priority_set(unsigned int irq, unsigned int prio, uint32_t flags) +{ + /** + * not supported, all IRQ sources generate IRQ, instead of FIQ, + * and with the default priority. + */ +} + +void z_soc_irq_enable(unsigned int irq) +{ + set_reqmask_bit(irq, VIM_REG_REQMASKSET_0); +} + +void z_soc_irq_disable(unsigned int irq) +{ + set_reqmask_bit(irq, VIM_REG_REQMASKCLR_0); +} + +int z_soc_irq_is_enabled(unsigned int irq) +{ + return get_reqmask_bit(irq, VIM_REG_REQMASKSET_0); +} + +/** + * @brief Signal end-of-interrupt + * + * @param irq interrupt ID + */ +void z_soc_irq_eoi(unsigned int irq) +{ + z_soc_irq_enable(irq); +} + +void z_soc_irq_init(void) +{ + /** + * ref. SPNA218.pdf + * We are implementing what is referred to as "Legacy ARM7 Interrupts". + * We do not use the VIM_RAM at all. + * Sequence is like this: + * 1. Interrupt request happens + * 2. Exception vector 0x18 (IRQ) or 0x1C (FIQ) is taken + * - in case of IRQ "ldr pc, =_isr_wrapper" + * - in case of FIQ "ldr pc, =z_arm_nmi" + * 3. _isr_wrapper uses z_soc_irq_get_active to get index into + * _sw_isr_table for arg and ISR handler + * 4. run ISR handler + * + * Drivers attach interrupts using IRQ_CONNECT/IRQ_DIRECT_CONNECT like: + * IRQ_CONNECT(irqnum, irqnum, z_irq_spurious, NULL, 0); + */ + + /* Errata VIM#28 Workaround: Disable Single Bit error correction */ + sys_write32((0xAU << 0U) | (0x5U << 16U), VIM_ECC_CTL); + + /** + * We do not use VIM RAM, or need to care about ECC, but if we do not set + * the VIM RAM locations to a _valid_ memory address (memset to 0 doesn't work), + * it keeps generating ESM NMI with ESM group 1 status = 0x80008000. + * Doing the following stops it. + */ + uint32_t *p = (void *) DRV_VIMRAM_REG; + + for (int i = 0; i < DRV_VIMRAM_REG_SIZE / 4; i++) { + *(p + i) = (uint32_t) &z_irq_spurious; + } + +#if defined(CONFIG_RUNTIME_NMI) + z_arm_nmi_set_handler(tms570_nmi_handler); +#endif + + /* enable interrupt */ + arch_irq_unlock(0); +} diff --git a/drivers/pinctrl/CMakeLists.txt b/drivers/pinctrl/CMakeLists.txt index dd46c54f977b5..0c0ca3a5fcc0c 100644 --- a/drivers/pinctrl/CMakeLists.txt +++ b/drivers/pinctrl/CMakeLists.txt @@ -41,6 +41,7 @@ zephyr_library_sources_ifdef(CONFIG_PINCTRL_GECKO pinctrl_gecko.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_SILABS_SIWX91X pinctrl_silabs_siwx91x.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_SILABS_DBUS pinctrl_silabs_dbus.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_TI_K3 pinctrl_ti_k3.c) +zephyr_library_sources_ifdef(CONFIG_PINCTRL_TI_TMS570 pinctrl_ti_tms570.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_EMSDP pinctrl_emsdp.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_TI_CC32XX pinctrl_ti_cc32xx.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_NUMAKER pinctrl_numaker.c) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 05a097040688b..f6ded03296cc5 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -75,6 +75,7 @@ source "drivers/pinctrl/Kconfig.siwx91x" source "drivers/pinctrl/Kconfig.ti_k3" source "drivers/pinctrl/Kconfig.emsdp" source "drivers/pinctrl/Kconfig.ti_cc32xx" +source "drivers/pinctrl/Kconfig.ti_tms570" source "drivers/pinctrl/Kconfig.numaker" source "drivers/pinctrl/Kconfig.eos_s3" source "drivers/pinctrl/Kconfig.mci_io_mux" diff --git a/drivers/pinctrl/Kconfig.ti_tms570 b/drivers/pinctrl/Kconfig.ti_tms570 new file mode 100644 index 0000000000000..04ef79865b488 --- /dev/null +++ b/drivers/pinctrl/Kconfig.ti_tms570 @@ -0,0 +1,9 @@ +# Copyright (c) 2025 ispace, inc. +# SPDX-License-Identifier: Apache-2.0 + +config PINCTRL_TI_TMS570 + bool "TI TMS570 pinctrl driver" + default y + depends on DT_HAS_TI_TMS570_PINMUX_ENABLED + help + Enable the TI TMS570 pinmux driver diff --git a/drivers/pinctrl/pinctrl_ti_tms570.c b/drivers/pinctrl/pinctrl_ti_tms570.c new file mode 100644 index 0000000000000..9616003d63c68 --- /dev/null +++ b/drivers/pinctrl/pinctrl_ti_tms570.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2025 ispace, inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#define DT_DRV_COMPAT ti_tms570_pinmux +#define DRV_REG_ADDR DT_INST_REG_ADDR(0) + +#define REG_KICK0_OFFSET (0x38) +#define REG_KICK1_OFFSET (0x3C) + +/* value used to unlock */ +#define KICK0_VALUE (0x83E70B13) +#define KICK1_VALUE (0x95A4F1E0) + +#define REG_PINMMR_0_OFFSET (0x110) + +int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg) +{ + uint32_t nibble_start; + uint32_t mask; + + ARG_UNUSED(reg); + + /* unlock */ + sys_write32(KICK0_VALUE, DRV_REG_ADDR + REG_KICK0_OFFSET); + sys_write32(KICK1_VALUE, DRV_REG_ADDR + REG_KICK1_OFFSET); + + for (uint8_t i = 0; i < pin_cnt; i++) { + nibble_start = (pins[i].bit / 4) * 4; + mask = 0xff << nibble_start; + sys_write32(mask & BIT(pins[i].bit), + DRV_REG_ADDR + REG_PINMMR_0_OFFSET + (pins[i].pinmmr * 4)); + } + + /* lock */ + sys_write32(0, DRV_REG_ADDR + REG_KICK0_OFFSET); + sys_write32(0, DRV_REG_ADDR + REG_KICK1_OFFSET); + + return 0; +} diff --git a/drivers/serial/CMakeLists.txt b/drivers/serial/CMakeLists.txt index 05289856ac968..2adc932e2be9c 100644 --- a/drivers/serial/CMakeLists.txt +++ b/drivers/serial/CMakeLists.txt @@ -96,6 +96,7 @@ zephyr_library_sources_ifdef(CONFIG_UART_STELLARIS uart_stellaris.c) zephyr_library_sources_ifdef(CONFIG_UART_STM32 uart_stm32.c) zephyr_library_sources_ifdef(CONFIG_UART_SY1XX uart_sy1xx.c) zephyr_library_sources_ifdef(CONFIG_UART_TELINK_B91 uart_b91.c) +zephyr_library_sources_ifdef(CONFIG_UART_TMS570 uart_tms570.c) zephyr_library_sources_ifdef(CONFIG_UART_WCH_USART uart_wch_usart.c) zephyr_library_sources_ifdef(CONFIG_UART_XEC uart_mchp_xec.c) zephyr_library_sources_ifdef(CONFIG_UART_XEN_HVC uart_hvc_xen.c) diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 3a13969e5a9a6..9458d2d5a349e 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -234,6 +234,7 @@ rsource "Kconfig.stellaris" rsource "Kconfig.stm32" rsource "Kconfig.sy1xx" rsource "Kconfig.test" +rsource "Kconfig.tms570" rsource "Kconfig.uart_sam" rsource "Kconfig.usart_sam" rsource "Kconfig.wch_usart" diff --git a/drivers/serial/Kconfig.tms570 b/drivers/serial/Kconfig.tms570 new file mode 100644 index 0000000000000..d3b462e9f6239 --- /dev/null +++ b/drivers/serial/Kconfig.tms570 @@ -0,0 +1,11 @@ +# Copyright (c) 2025 ispace, inc. +# SPDX-License-Identifier: Apache-2.0 + +config UART_TMS570 + bool "TI TMS570 series SCI USART driver" + default y + depends on DT_HAS_TI_TMS570_UART_ENABLED + select SERIAL_HAS_DRIVER + select PINCTRL + help + This option enables the TMS570 UART driver. diff --git a/drivers/serial/uart_tms570.c b/drivers/serial/uart_tms570.c new file mode 100644 index 0000000000000..418f6cbebb003 --- /dev/null +++ b/drivers/serial/uart_tms570.c @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2025 ispace, inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#define DT_DRV_COMPAT ti_tms570_uart + +#define VCLK_FREQUENCY DT_PROP(DT_NODELABEL(clk_vclk), clock_frequency) + +#define TMS570_GCR0 (0x00) +#define TMS570_GCR1 (0x04) +#define TMS570_GCR2 (0x08) +#define TMS570_SETINT (0x0c) +#define TMS570_CLEARINT (0x10) +#define TMS570_SETINTLVL (0x14) +#define TMS570_CLEARINTLVL (0x18) +#define TMS570_FLR (0x1c) +#define TMS570_INTVECT0 (0x20) +#define TMS570_INTVECT1 (0x24) +#define TMS570_FORMAT (0x28) +#define TMS570_BRS (0x2c) +#define TMS570_ED (0x30) +#define TMS570_RD (0x34) +#define TMS570_TD (0x38) +#define TMS570_PIO0 (0x3c) +#define TMS570_PIO1 (0x40) +#define TMS570_PIO2 (0x44) +#define TMS570_PIO3 (0x48) +#define TMS570_PIO4 (0x4c) +#define TMS570_PIO5 (0x50) +#define TMS570_PIO6 (0x54) +#define TMS570_PIO7 (0x58) +#define TMS570_PIO8 (0x5c) +#define TMS570_IODFTCTRL (0x90) + +#define TMS570_SCI_REG_GCR0 (dev_cfg->base_addr + TMS570_GCR0) +#define TMS570_SCI_REG_GCR1 (dev_cfg->base_addr + TMS570_GCR1) +#define TMS570_SCI_REG_CLEARINT (dev_cfg->base_addr + TMS570_CLEARINT) +#define TMS570_SCI_REG_CLEARINTLVL (dev_cfg->base_addr + TMS570_CLEARINTLVL) +#define TMS570_SCI_REG_FORMAT (dev_cfg->base_addr + TMS570_FORMAT) +#define TMS570_SCI_REG_BRS (dev_cfg->base_addr + TMS570_BRS) +#define TMS570_SCI_REG_FUNC (dev_cfg->base_addr + TMS570_PIO0) +#define TMS570_SCI_REG_PIO8 (dev_cfg->base_addr + TMS570_PIO8) +#define TMS570_SCI_REG_RD (dev_cfg->base_addr + TMS570_RD) +#define TMS570_SCI_REG_TD (dev_cfg->base_addr + TMS570_TD) +#define TMS570_SCI_REG_FLR (dev_cfg->base_addr + TMS570_FLR) + +#define GCR1_TXENA (1 << 25) +#define GCR1_RXENA (1 << 24) +#define GCR1_CONT (1 << 17) +#define GCR1_LOOPBACK (1 << 16) +#define GCR1_STOP_EXT_FRAME (1 << 13) +#define GCR1_HGEN_CTRL (1 << 12) +#define GCR1_CTYPE (1 << 11) +#define GCR1_MBUF_MODE (1 << 10) +#define GCR1_ADAPT (1 << 9) +#define GCR1_SLEEP (1 << 8) +#define GCR1_SWnRST (1 << 7) +#define GCR1_LIN_MODE (1 << 6) +#define GCR1_CLOCK (1 << 5) +#define GCR1_STOP_BIT_1 (0 << 4) +#define GCR1_STOP_BIT_2 (1 << 4) +#define GCR1_PARITY_ENA (1 << 2) +#define GCR1_PARITY_ODD ((0 << 3) | GCR1_PARITY_ENA) +#define GCR1_PARITY_EVEN ((1 << 3) | GCR1_PARITY_ENA) +#define GCR1_PARITY_NONE (0) +#define GCR1_TIMING_MODE_SYNC (0 << 1) +#define GCR1_TIMING_MODE_ASYNC (1 << 1) +#define GCR1_COMM_MODE (1 << 0) + +#define FLR_RX_RDY (1 << 9) +#define FLR_TX_RDY (1 << 8) + +#define FORMAT_CHARS_IN_FRAME(x) (((x - 1) & 0x7) << 16) +#define FORMAT_BITS_PER_CHAR(x) (((x - 1) & 0x7)) +#define FORMAT_8_BIT_1_CHAR (FORMAT_CHARS_IN_FRAME(1) | FORMAT_BITS_PER_CHAR(8)) + +#define PIO_TX_EN (1 << 2) +#define PIO_RX_EN (1 << 1) + +/* Device data structure */ +struct uart_tms570_dev_cfg_t { + const uint32_t base_addr; /* Register base address */ + const uint32_t baud_rate; /* Baud rate */ + const struct pinctrl_dev_config *pincfg; +}; + + +static void uart_tms570_poll_out(const struct device *dev, uint8_t c) +{ + const struct uart_tms570_dev_cfg_t *dev_cfg = + (const struct uart_tms570_dev_cfg_t *) dev->config; + + while ((sys_read32(TMS570_SCI_REG_FLR) & 0x00000100U) == 0U) { + /* wait */ + } + + sys_write32(c, TMS570_SCI_REG_TD); +} + +static int uart_tms570_poll_in(const struct device *dev, uint8_t *c) +{ + const struct uart_tms570_dev_cfg_t *dev_cfg = + (const struct uart_tms570_dev_cfg_t *) dev->config; + uint32_t flags; + + flags = sys_read32(TMS570_SCI_REG_FLR); + if ((flags & FLR_RX_RDY) != 0) { + *c = (uint8_t)sys_read32(TMS570_SCI_REG_RD); + return 0; + } else { + return -1; + } +} + +static int uart_tms570_init(const struct device *dev) +{ + const struct uart_tms570_dev_cfg_t *dev_cfg = + (const struct uart_tms570_dev_cfg_t *) dev->config; + + /* reset SCI */ + sys_write32(0, TMS570_SCI_REG_GCR0); + sys_write32(1, TMS570_SCI_REG_GCR0); + + /* enable and set up uart */ + sys_write32(GCR1_TXENA | GCR1_RXENA | /* enable both tx and rx */ + GCR1_CLOCK | /* internal clock (device has no clock pin) */ + GCR1_STOP_BIT_1 | + GCR1_PARITY_NONE | + GCR1_TIMING_MODE_ASYNC, + TMS570_SCI_REG_GCR1); + + /* make pins SCI mode */ + sys_write32(PIO_TX_EN | PIO_RX_EN, TMS570_SCI_REG_FUNC); + pinctrl_apply_state(dev_cfg->pincfg, PINCTRL_STATE_DEFAULT); + + /* baudrate */ + sys_write32(VCLK_FREQUENCY / ((dev_cfg->baud_rate - 1) * 16), TMS570_SCI_REG_BRS); + + /* we want 8 bit per char and 1 char per frame */ + sys_write32(FORMAT_8_BIT_1_CHAR, TMS570_SCI_REG_FORMAT); + + /* start */ + sys_write32(sys_read32(TMS570_SCI_REG_GCR1) | GCR1_SWnRST, TMS570_SCI_REG_GCR1); + + return 0; +} + +static const struct uart_driver_api uart_tms570_driver_api = { + .poll_in = uart_tms570_poll_in, + .poll_out = uart_tms570_poll_out, + .err_check = NULL, +}; + +#define TMS570_UART_INIT(idx) \ + PINCTRL_DT_INST_DEFINE(idx); \ + static struct uart_tms570_dev_cfg_t tms570__uart##idx##_cfg = { \ + .base_addr = DT_INST_REG_ADDR(idx), \ + .baud_rate = DT_INST_PROP(idx, current_speed), \ + .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(idx), \ + }; \ + DEVICE_DT_INST_DEFINE(idx, &uart_tms570_init, NULL, NULL, \ + &tms570__uart##idx##_cfg, PRE_KERNEL_1, \ + CONFIG_SERIAL_INIT_PRIORITY, \ + &uart_tms570_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(TMS570_UART_INIT) diff --git a/drivers/timer/CMakeLists.txt b/drivers/timer/CMakeLists.txt index a354de5e35e31..bbd5895a8cf7a 100644 --- a/drivers/timer/CMakeLists.txt +++ b/drivers/timer/CMakeLists.txt @@ -41,6 +41,7 @@ zephyr_library_sources_ifdef(CONFIG_SAM0_RTC_TIMER sam0_rtc_timer.c) zephyr_library_sources_ifdef(CONFIG_SILABS_SLEEPTIMER_TIMER silabs_sleeptimer_timer.c) zephyr_library_sources_ifdef(CONFIG_STM32_LPTIM_TIMER stm32_lptim_timer.c) zephyr_library_sources_ifdef(CONFIG_TI_DM_TIMER ti_dmtimer.c) +zephyr_library_sources_ifdef(CONFIG_TMS570_RTI_TIMER tms570_rti_timer.c) zephyr_library_sources_ifdef(CONFIG_XLNX_PSTTC_TIMER xlnx_psttc_timer.c) zephyr_library_sources_ifdef(CONFIG_XTENSA_TIMER xtensa_sys_timer.c) zephyr_library_sources_ifdef(CONFIG_SMARTBOND_TIMER smartbond_timer.c) diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig index 1cb165f329ff8..68e28daa5246e 100644 --- a/drivers/timer/Kconfig +++ b/drivers/timer/Kconfig @@ -99,6 +99,7 @@ source "drivers/timer/Kconfig.silabs" source "drivers/timer/Kconfig.smartbond" source "drivers/timer/Kconfig.stm32_lptim" source "drivers/timer/Kconfig.ti_dm_timer" +source "drivers/timer/Kconfig.tms570_rti_timer" source "drivers/timer/Kconfig.xlnx_psttc" source "drivers/timer/Kconfig.xtensa" source "drivers/timer/Kconfig.mtk_adsp" diff --git a/drivers/timer/Kconfig.tms570_rti_timer b/drivers/timer/Kconfig.tms570_rti_timer new file mode 100644 index 0000000000000..c8438c0863691 --- /dev/null +++ b/drivers/timer/Kconfig.tms570_rti_timer @@ -0,0 +1,11 @@ +# Copyright (C) 2025 ispace, inc. +# +# SPDX-License-Identifier: Apache-2.0 + +config TMS570_RTI_TIMER + bool "TI TMS570 RTI Timer" + default y + depends on SOC_TI_TMS570LC43X + help + This module implements a kernel device driver for the TI TMS570 RTI + timer. diff --git a/drivers/timer/tms570_rti_timer.c b/drivers/timer/tms570_rti_timer.c new file mode 100644 index 0000000000000..ad95ef8ba01a4 --- /dev/null +++ b/drivers/timer/tms570_rti_timer.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2025 ispace, inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#define DT_DRV_COMPAT ti_tms570_rti + +#define REG_RTI DT_INST_REG_ADDR_BY_IDX(0, 0) +#define RTI_CLK_FREQ DT_PROP(DT_NODELABEL(clk_rticlk), clock_frequency) + +#define RTI_INTFLAG_COMP0 BIT(0) +#define RTI_INTENA_COMP0 BIT(0) + +#define RTI_INTCLR_ALL (BIT(18) | BIT(17) | BIT(16) | \ + BIT(3) | BIT(2) | BIT(1) | BIT(0)) + +#define RTIGCTRL (REG_RTI + 0x00) +#define RTITBCTRL (REG_RTI + 0x04) +#define RTICAPCTRL (REG_RTI + 0x08) +#define RTICOMPCTRL (REG_RTI + 0x0C) +#define RTISETINTENA (REG_RTI + 0x80) +#define RTICLEARINTENA (REG_RTI + 0x84) +#define RTIINTFLAG (REG_RTI + 0x88) +#define RTIFRC0 (REG_RTI + 0x10) +#define RTIUC0 (REG_RTI + 0x14) +#define RTICPUC0 (REG_RTI + 0x18) +#define RTICAFRC0 (REG_RTI + 0x20) +#define RTICAUC0 (REG_RTI + 0x24) +#define RTICOMP0 (REG_RTI + 0x50) +#define RTIUDCP0 (REG_RTI + 0x54) + +#define RTIGCTRL_COS_OFFSET (15) +#define CNT1EN BIT(1) +#define CNT0EN BIT(0) + +static struct k_spinlock ticks_lock; +static volatile uint64_t ticks; + +uint32_t sys_clock_elapsed(void) +{ + return 0; +} + +uint32_t sys_clock_cycle_get_32(void) +{ + return sys_read32(RTIFRC0); +} + +static void rti_compare0_isr(const void *arg) +{ + ARG_UNUSED(arg); + + K_SPINLOCK(&ticks_lock) { + ticks += k_ticks_to_cyc_floor32(1); + } + + sys_write32(RTI_INTFLAG_COMP0, RTIINTFLAG); + sys_clock_announce(1); +} + +static int rti_timer_init(void) +{ + /** + * TODO Counter block 0 can be synchronized with Network Time (NTU), + * we can make use of that. + */ + + /* disable counters and interrupts */ + sys_write32(1 << RTIGCTRL_COS_OFFSET, RTIGCTRL); + sys_write32(RTI_INTCLR_ALL, RTICLEARINTENA); + + /** + * We use counter 0 and compare register 0. + */ + + /* default compare control and capture control */ + sys_write32(0, RTICOMPCTRL); + sys_write32(0, RTICAPCTRL); + + /* Initialize counter 0 */ + sys_write32(0, RTIUC0); + sys_write32(0, RTIFRC0); + sys_write32(0, RTITBCTRL); + + /** + * Set up free running counter interrupt cycle. + * UCx - up-counter or prescale counter - driven by RTICLK + * CPUCx - compare up-counter, it acts like a prescaler over UCx + * FRCx - when CPUCx value matches UCx, this reg is incremented by one + * COMPx - this is compared with FRCx, a match generates an interrupt + * UDCPx - UDCPx is added to COMPx when a match occues (COMPx matches FRCx), + * so that we can generate periodic interrupts1 + */ + sys_write32(RTI_CLK_FREQ / CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC - 1U, RTICPUC0); + /* free running counter, compare match period = 10 ms */ + sys_write32(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / CONFIG_SYS_CLOCK_TICKS_PER_SEC, RTICOMP0); + sys_write32(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / CONFIG_SYS_CLOCK_TICKS_PER_SEC, RTIUDCP0); + + /* Clear all pending interrupts */ + sys_write32(RTI_INTCLR_ALL, RTIINTFLAG); + + /* connect irq */ + IRQ_CONNECT(IRQ_RTI_COMPARE_0, IRQ_RTI_COMPARE_0, rti_compare0_isr, NULL, 0); + irq_enable(IRQ_RTI_COMPARE_0); + + /* Enable interrupt */ + sys_write32(RTI_INTENA_COMP0, RTISETINTENA); + /* Enable timer */ + sys_write32(sys_read32(RTIGCTRL) | CNT1EN | CNT0EN, RTIGCTRL); + + return 0; +} + +SYS_INIT(rti_timer_init, PRE_KERNEL_2, CONFIG_SYSTEM_CLOCK_INIT_PRIORITY); diff --git a/dts/arm/ti/tms570.dtsi b/dts/arm/ti/tms570.dtsi new file mode 100644 index 0000000000000..0c11def4982ad --- /dev/null +++ b/dts/arm/ti/tms570.dtsi @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2025 ispace inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include + +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-r5"; + reg = <0>; + status = "okay"; + }; + }; + + clocks { + /* + * OSC_IN (16 MHZ) + * -> PLL1 (300 MHz) + * -> GCLK1 (300 MHz) + * -> HCLK (150 MHz) + * -> VCLK (75 MHz) + * -> RTICLK (75 MHz, divider is bypassed when VCLK is the source) + */ + + osc_in: osc_in { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = ; + status = "okay"; + }; + + clk_vclk: clk_vclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = ; + status = "okay"; + }; + + clk_rticlk: clk_rticlk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = ; + status = "okay"; + }; + }; + + soc { + #address-cells = <1>; + #size-cells = <1>; + + sys: sys@ffffff00 { + reg = <0xffffff00 256>, /* SYS1 */ + <0xffffe100 256>, /* SYS2 */ + <0xffff1000 0x800>, /* PCR1 */ + <0xfcff1000 0x800>, /* PCR2 */ + <0xfff78000 0x800>, /* PCR3 */ + <0xfff87000 0x1000>, /* FCR */ + <0xfffff500 0x100>, /* ESM */ + <0xFFFFFF00 0xfc>, /* SYSBASE */ + <0xFFFFFC98 4>, /* WATCHDOG_STATUS */ + <0xFFFFEC00 44>, /* DCC */ + <0xFFA04000 0x10>; /* POM_CONTROL_BASE */ + }; + + rti: rti@fffffc00 { + compatible = "ti,tms570-rti"; + reg = <0xfffffc00 256>; + clock-frequency = ; + tick-frequency = <100>; + status = "okay"; + }; + + sram0: memory@8000000 { + compatible = "mmio-sram"; + reg = <0x08000000 DT_SIZE_K(512)>; + }; + + flc0: flash_controller@f0000000 { + compatible = "flash-controller"; + reg = <0xf0000000 0x00480000>; + #address-cells = <1>; + #size-cells = <1>; + status = "okay"; + + flash0: flash@0 { + compatible = "soc-nv-flash"; + reg = <0x00000000 DT_SIZE_M(4)>; + }; + }; + + pinctrl: pin-controller@ffff1c00 { + compatible = "ti,tms570-pinmux"; + reg = <0xffff1c00 0x400>; + status = "okay"; + }; + + vim: interrupt-controller@fffffe00 { + compatible = "ti,tms570-vim"; + reg = <0xfffffe00 0x00000100>, /* VIM control */ + <0xfffffd00 0x00000100>, /* ECC related */ + <0xfff82000 128>; /* VIM_RAM */ + status = "okay"; + interrupt-controller; + #interrupt-cells = <2>; + #address-cells = <1>; + }; + + sci1: uart@fff7e400 { + compatible = "ti,tms570-uart"; + reg = <0xfff7e400 256>; + status = "disabled"; + }; + + sci3: uart@fff7e500 { + compatible = "ti,tms570-uart"; + reg = <0xfff7e500 256>; + status = "disabled"; + }; + + gpio_a: gpio@fff7bc34 { + compatible = "ti,tms570-gpio"; + reg = <0xfff7bc34 0x34 /* GIO port base */ + 0xfff7bc00 0x20>; /* GIO base */ + interrupts = <13 0>; + interrupt-parent = <&vim>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + status = "okay"; + }; + + gpio_b: gpio@fff7bc54 { + compatible = "ti,tms570-gpio"; + reg = <0xfff7bc54 0x34 /* GIO port base */ + 0xfff7bc00 0x20>; /* GIO base */ + interrupts = <13 0>; + interrupt-parent = <&vim>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + status = "okay"; + }; + }; +}; diff --git a/dts/bindings/gpio/ti,tms570-gpio.yaml b/dts/bindings/gpio/ti,tms570-gpio.yaml new file mode 100644 index 0000000000000..ef3b21812028c --- /dev/null +++ b/dts/bindings/gpio/ti,tms570-gpio.yaml @@ -0,0 +1,25 @@ +# Copyright (c) 2025 ispace, inc. +# SPDX-License-Identifier: Apache-2.0 + +description: TMS570 GPIO + +compatible: "ti,tms570-gpio" + +include: [gpio-controller.yaml, base.yaml] + +properties: + # NOTE: Register ranges: + # - 0 : GIO port registers + # - 1 : GIO base registers + reg: + required: true + + interrupt-parent: + required: true + + ngpios: + required: true + +gpio-cells: + - pin + - flags diff --git a/dts/bindings/interrupt-controller/ti,tms570-vim.yaml b/dts/bindings/interrupt-controller/ti,tms570-vim.yaml new file mode 100644 index 0000000000000..e4e834e62ed26 --- /dev/null +++ b/dts/bindings/interrupt-controller/ti,tms570-vim.yaml @@ -0,0 +1,24 @@ +# Copyright (c) 2025 ispace, inc. +# SPDX-License-Identifier: Apache-2.0 + +description: VIM for TMS570 + +compatible: "ti,tms570-vim" + +include: [interrupt-controller.yaml, base.yaml] + + +properties: + # NOTE: Register ranges: + # - 0 : VIM control registers + # - 1 : VIM ECC related registers + # - 2 : VIM RAM + reg: + required: true + + "#interrupt-cells": + const: 2 + +interrupt-cells: + - irq + - priority diff --git a/dts/bindings/pinctrl/ti,tms570-pinmux.yaml b/dts/bindings/pinctrl/ti,tms570-pinmux.yaml new file mode 100644 index 0000000000000..061d90e41a77e --- /dev/null +++ b/dts/bindings/pinctrl/ti,tms570-pinmux.yaml @@ -0,0 +1,21 @@ +# Copyright (c) 2025 ispace, inc. +# SPDX-License-Identifier: Apache-2.0 + +description: TI TMS570 pinmux driver + +compatible: "ti,tms570-pinmux" + +include: base.yaml + +properties: + reg: + required: true + +child-binding: + properties: + pinmux: + required: true + type: array + description: | + TMS570 pin's configuration (select bit pair) based on the "Output Multiplexing" + table in the reference manual. diff --git a/dts/bindings/serial/ti,tms570-uart.yaml b/dts/bindings/serial/ti,tms570-uart.yaml new file mode 100644 index 0000000000000..ae8c2f319e26c --- /dev/null +++ b/dts/bindings/serial/ti,tms570-uart.yaml @@ -0,0 +1,12 @@ +# Copyright (c) 2025, ispace, inc. +# SPDX-License-Identifier: Apache-2.0 + +description: TI TMS570 UART + +compatible: "ti,tms570-uart" + +include: [uart-controller.yaml, pinctrl-device.yaml, base.yaml] + +properties: + reg: + required: true diff --git a/dts/bindings/timer/ti,tms570-rti.yaml b/dts/bindings/timer/ti,tms570-rti.yaml new file mode 100644 index 0000000000000..6e1c4d4ed3679 --- /dev/null +++ b/dts/bindings/timer/ti,tms570-rti.yaml @@ -0,0 +1,16 @@ +# Copyright (c) 2025 ispace, inc. +# SPDX-License-Identifier: Apache-2.0 + +description: Real-time interrupt for TMS570 + +compatible: "ti,tms570-rti" + +include: [base.yaml] + +properties: + clock-frequency: + type: int + description: Clock frequency of RTI up counter + tick-frequency: + type: int + description: Frequency of RTI interrupt for system tick diff --git a/soc/ti/hercules/CMakeLists.txt b/soc/ti/hercules/CMakeLists.txt new file mode 100644 index 0000000000000..5cb8e1d66d852 --- /dev/null +++ b/soc/ti/hercules/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +add_subdirectory(${SOC_NAME}) + +zephyr_include_directories(${SOC_NAME}) diff --git a/soc/ti/hercules/Kconfig b/soc/ti/hercules/Kconfig new file mode 100644 index 0000000000000..aceb77ea1ea6d --- /dev/null +++ b/soc/ti/hercules/Kconfig @@ -0,0 +1,8 @@ +# Copyright (c) 2025 ispace, inc. +# SPDX-License-Identifier: Apache-2.0 + +if SOC_FAMILY_TI_HERCULES + +rsource "*/Kconfig" + +endif # SOC_FAMILY_TI_HERCULES diff --git a/soc/ti/hercules/Kconfig.defconfig b/soc/ti/hercules/Kconfig.defconfig new file mode 100644 index 0000000000000..5e01391c63dd4 --- /dev/null +++ b/soc/ti/hercules/Kconfig.defconfig @@ -0,0 +1,8 @@ +# Copyright (c) 2025 ispace, inc. +# SPDX-License-Identifier: Apache-2.0 + +if SOC_FAMILY_TI_HERCULES + +rsource "*/Kconfig.defconfig" + +endif # SOC_FAMILY_TI_HERCULES diff --git a/soc/ti/hercules/Kconfig.soc b/soc/ti/hercules/Kconfig.soc new file mode 100644 index 0000000000000..5b8b1feaab5ee --- /dev/null +++ b/soc/ti/hercules/Kconfig.soc @@ -0,0 +1,10 @@ +# Copyright (c) 2025 ispace, inc. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_TI_HERCULES + bool + +config SOC_FAMILY + default "ti_hercules" if SOC_FAMILY_TI_HERCULES + +rsource "*/Kconfig.soc" diff --git a/soc/ti/hercules/soc.yml b/soc/ti/hercules/soc.yml new file mode 100644 index 0000000000000..9336e8a25ef8e --- /dev/null +++ b/soc/ti/hercules/soc.yml @@ -0,0 +1,6 @@ +family: +- name: ti_hercules + series: + - name: ti_tms570 + socs: + - name: ti_tms570lc43x diff --git a/soc/ti/hercules/ti_tms570lc43x/CMakeLists.txt b/soc/ti/hercules/ti_tms570lc43x/CMakeLists.txt new file mode 100644 index 0000000000000..de3445de6731c --- /dev/null +++ b/soc/ti/hercules/ti_tms570lc43x/CMakeLists.txt @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: Apache-2.0 + +# TMS470 requires the ARM "legacy Word Invariant Addressing big-endian mode" +zephyr_compile_options( + -mbe32 + ${TOOLCHAIN_C_FLAGS} +) + +zephyr_ld_options( + -mbe32 + ${TOOLCHAIN_LD_FLAGS} +) + +zephyr_library_include_directories( + ${ZEPHYR_BASE}/kernel/include + ${ZEPHYR_BASE}/arch/arm/include + ) + +zephyr_include_directories(.) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_r/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/ti/hercules/ti_tms570lc43x/Kconfig b/soc/ti/hercules/ti_tms570lc43x/Kconfig new file mode 100644 index 0000000000000..e50482ce889ff --- /dev/null +++ b/soc/ti/hercules/ti_tms570lc43x/Kconfig @@ -0,0 +1,16 @@ +# Copyright (c) 2025 ispace, inc. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_TI_TMS570LC43X + select ARM + select CPU_CORTEX_R5 + select BIG_ENDIAN + select CPU_HAS_DCLS + select CPU_HAS_ARM_MPU + select CPU_HAS_DCACHE + select CPU_HAS_ICACHE + select CACHE_MANAGEMENT + select SOC_RESET_HOOK + select ARM_CUSTOM_INTERRUPT_CONTROLLER + select HAS_TMS570_HALCOGEN_CODE + imply XIP diff --git a/soc/ti/hercules/ti_tms570lc43x/Kconfig.defconfig b/soc/ti/hercules/ti_tms570lc43x/Kconfig.defconfig new file mode 100644 index 0000000000000..c58a3665a445a --- /dev/null +++ b/soc/ti/hercules/ti_tms570lc43x/Kconfig.defconfig @@ -0,0 +1,37 @@ +# Copyright (c) Copyright (c) 2025 ispace, inc. +# SPDX-License-Identifier: Apache-2.0 + +if SOC_TI_TMS570LC43X + +config SYS_CLOCK_EXISTS + default y + +config DYNAMIC_INTERRUPTS + default n + +config GEN_SW_ISR_TABLE + default y + +config GEN_ISR_TABLES + default y + +config GEN_IRQ_VECTOR_TABLE + default n + +config USE_SWITCH + default n + +config RUNTIME_NMI + default y + +config SYS_CLOCK_TICKS_PER_SEC + default $(dt_node_int_prop_int,/soc/rti@fffffc00,tick-frequency) + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,/soc/rti@fffffc00,clock-frequency) + +config NUM_IRQS + # must be >= the highest interrupt number used + default 127 + +endif # SOC_TI_TMS570LC43X diff --git a/soc/ti/hercules/ti_tms570lc43x/Kconfig.soc b/soc/ti/hercules/ti_tms570lc43x/Kconfig.soc new file mode 100644 index 0000000000000..f454e1cd8f548 --- /dev/null +++ b/soc/ti/hercules/ti_tms570lc43x/Kconfig.soc @@ -0,0 +1,23 @@ +# Copyright (c) 2024 ispace, inc. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_TI_TMS570 + bool + select SOC_FAMILY_TI_HERCULES + help + TI Hercules family + +config SOC_TI_TMS570LC43X + bool + select SOC_SERIES_TI_TMS570 + help + TI TMS570LC43X + +config HAS_TMS570_HALCOGEN_CODE + bool + +config SOC_SERIES + default "ti_tms570" if SOC_SERIES_TI_TMS570 + +config SOC + default "ti_tms570lc43x" if SOC_TI_TMS570LC43X diff --git a/soc/ti/hercules/ti_tms570lc43x/linker.ld b/soc/ti/hercules/ti_tms570lc43x/linker.ld new file mode 100644 index 0000000000000..367c97892be26 --- /dev/null +++ b/soc/ti/hercules/ti_tms570lc43x/linker.ld @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2025 ispace, inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include diff --git a/soc/ti/hercules/ti_tms570lc43x/pinctrl_soc.h b/soc/ti/hercules/ti_tms570lc43x/pinctrl_soc.h new file mode 100644 index 0000000000000..384d884a3a88c --- /dev/null +++ b/soc/ti/hercules/ti_tms570lc43x/pinctrl_soc.h @@ -0,0 +1,31 @@ +/* + * Copyright 2025 ispace, inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SOC_TI_TMS570_PINCTRL_SOC_H_ +#define ZEPHYR_SOC_TI_TMS570_PINCTRL_SOC_H_ + +#include +#include + +typedef struct pinctrl_soc_pin_t { + uint8_t pinmmr; + uint8_t bit; +} pinctrl_soc_pin_t; + +#define TI_TMS570_DT_PIN(node_id) \ + { \ + .pinmmr = DT_PROP_BY_IDX(node_id, pinmux, 0), \ + .bit = DT_PROP_BY_IDX(node_id, pinmux, 1) \ + }, + +#define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) \ + TI_TMS570_DT_PIN(DT_PROP_BY_IDX(node_id, prop, idx)) + +#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \ + { DT_FOREACH_PROP_ELEM(node_id, prop, Z_PINCTRL_STATE_PIN_INIT) } + + +#endif /* ZEPHYR_SOC_TI_TMS570_PINCTRL_SOC_H_ */ diff --git a/soc/ti/hercules/ti_tms570lc43x/soc.h b/soc/ti/hercules/ti_tms570lc43x/soc.h new file mode 100644 index 0000000000000..939d1be7e0e03 --- /dev/null +++ b/soc/ti/hercules/ti_tms570lc43x/soc.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2025 ispace, inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __TMS570_SOC_H__ +#define __TMS570_SOC_H__ + +/* Do not let CMSIS to handle GIC and Timer */ +#include +#define __GIC_PRESENT 0 + +/* these are the default "Interrupt request assignments", see table in datasheet with same name */ +#define IRQ_NUM_ESM_HIGH 0 /* cannot be remapped, is NMI (FIQ) */ +#define IRQ_RTI_COMPARE_0 2 /* RTI1 compare interrupt 0 */ +#define IRQ_RTI_COMPARE_1 3 /* RTI1 compare interrupt 1 */ +#define IRQ_RTI_COMPARE_2 4 /* RTI1 compare interrupt 2 */ +#define IRQ_RTI_COMPARE_3 5 /* RTI1 compare interrupt 3 */ +#define IRQ_RTI_OVERFLOW_0 6 /* RTI1 overflow interrupt 1 */ +#define IRQ_RTI_OVERFLOW_1 7 /* RTI1 overflow interrupt 1 */ +#define IRQ_RTI_TIME_BASE 8 /* RTI1 time-base */ +#define IRQ_GIO_HIGH_LEVEL 9 /* GIO high level interrupt */ +#define IRQ_NUM_ESM_LOW 20 /* ESM low level interrupt */ + +#define DRV_SYS DT_NODELABEL(sys) + +#define DRV_SYS1 DT_REG_ADDR_BY_IDX(DRV_SYS, 0) +#define DRV_SYS2 DT_REG_ADDR_BY_IDX(DRV_SYS, 1) +#define DRV_PCR1 DT_REG_ADDR_BY_IDX(DRV_SYS, 2) +#define DRV_PCR2 DT_REG_ADDR_BY_IDX(DRV_SYS, 3) +#define DRV_PCR3 DT_REG_ADDR_BY_IDX(DRV_SYS, 4) +#define DRV_FCR DT_REG_ADDR_BY_IDX(DRV_SYS, 5) +#define DRV_ESM DT_REG_ADDR_BY_IDX(DRV_SYS, 6) +#define DRV_SYSBASE DT_REG_ADDR_BY_IDX(DRV_SYS, 7) +#define DRV_WATCHDOG_STATUS DT_REG_ADDR_BY_IDX(DRV_SYS, 8) +#define DRV_DCC DT_REG_ADDR_BY_IDX(DRV_SYS, 9) +#define DRV_POM_CONTROL DT_REG_ADDR_BY_IDX(DRV_SYS, 10) + +#define DRV_VIMRAM DT_REG_ADDR_BY_IDX(DT_NODELABEL(vim), 2) +#define DRV_VIMRAM_SZ DT_REG_SIZE_BY_IDX(DT_NODELABEL(vim), 2) + +#endif /* __TMS570_SOC_H__ */ diff --git a/soc/ti/hercules/ti_tms570lc43x/soc_defaults.h b/soc/ti/hercules/ti_tms570lc43x/soc_defaults.h new file mode 100644 index 0000000000000..9e6698c31c569 --- /dev/null +++ b/soc/ti/hercules/ti_tms570lc43x/soc_defaults.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2025 ispace, inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __TMS570_SOC_PRIVATE_H__ +#define __TMS570_SOC_PRIVATE_H__ + +#define OSC_IN_FREQ_MHZ DT_PROP(DT_NODELABEL(osc_in), clock_frequency) / 1000000 + +/** + * - BPOS = 1, Bypass on PLL Slip is enabled + * - PLLDIV = 31 (R = 32) + * - REFCLKDIV = OSC_IN_FREQ_MHZ - 1 (ref clock divider) + * - PLLMUL = 0x9500 (NF, multiplication factor = 0x95+1 = 150) + * + * NOTE: the divider value is changed later on, to be 0 (R=1) + */ +#define PLLCTL1_INIT_VALUE (1 << PLLCTL1_BPOS_OFFSET | \ + 31 << PLLCTL1_PLLDIV_OFFSET | \ + (OSC_IN_FREQ_MHZ - 1) << PLLCTL1_REFCLKDIV_OFFSET | \ + 0x9500) + +/** + *- SPREADINGRATE = 255 (NS = 256) + *- MULMOD = 7 + *- ODPLL = 0 (OD, output divider = 0) + *- SPR_AMOUNT = 61 (NV = 62/2048) + */ +#define PLLCTL2_INIT_VALUE (255 << PLLCTL2_SPREADINGRATE_OFFSET | \ + 7 << PLLCTL2_MULMOD_OFFSET | \ + 61 << PLLCTL2_SPR_AMOUNT_OFFSET) + +/** + *- ODPLL2 = 0 (OD2 = 1) + *- PLLDIV2 = 31 (R2 = 32) + *- REFCLKDIV2 = 7 (NR2 = 8) + *- PLLMUL2 = 0x9500 (NF2 = 150) + */ +#define PLLCTL3_INIT_VALUE (31 << PLLCTL3_PLLDIV2_OFFSET | \ + 7 << PLLCTL3_REFCLKDIV2_OFFSET | \ + 0x9500 << PLLCTL3_PLLMUL2_OFFSET) + +/** + *- RWAIT = 3 Random/data Read Wait State + *- PFUENB = 1 Prefetch Enable for Port B + *- PFUENA = 1 Prefetch Enable for Port A + */ +#define FRDCNTL_INIT_VALUE (3 << FRDCNTL_RWAIT_OFFSET | FRDCNTL_PFUENA | FRDCNTL_PFUENB) + +/** + * - EEPROM Wait state Counter = 9 + */ +#define EEPROM_CONFIG_INIT_VALUE (9 << EWAIT_OFFSET) + +#define FBPWRMODE_INIT_VALUE (BANKPWR_VAL_ACTIVE << BANKPWR0_OFFSET | \ + BANKPWR_VAL_ACTIVE << BANKPWR1_OFFSET | \ + BANKPWR_VAL_ACTIVE << BANKPWR7_OFFSET) + +/* GCLK, HCLK and VCLK source is PLL1 */ +#define GHVSRC_INIT_VALUE (1 << GHVWAKE_OFFSET | 1 << HVLPM_OFFSET | 1 << GHVSRC_OFFSET) + +/** + * - RTI1DIV = 0, divider = 1 (NOTE: divider is bypassed when VCLK is the source) + * - RTI1SRC = 9, VCLK as source, 8 to 0xF is VCLK + */ +#define RCLKSRC_INIT_VALUE (0 << RTI1DIV_OFFSET | 9 << RTI1SRC_OFFSET) + +/** + *- VCLKA1S = 9, VCLK is source + *- VCLKA2S = 9, VCLK is source + */ +#define VCLKASRC_INIT_VALUE (9 << VCLKA1S_OFFSET | 9 << VCLKA2S_OFFSET) + +/* + * - VCLKA4R = 0, divider=1 + * - VCLKA4_DIV_CDDIS = 0, Disable the VCLKA4 divider output + * - VCLKA4S = 9, source=VCLK + */ +#define VCLKACON1_INIT_VALUE (0 << VCLKA4R_OFFSET | VCLKA4_DIV_CDDIS | 9 << VCLKA4S_OFFSET) + +#endif /* __TMS570_SOC_PRIVATE_H__ */ diff --git a/soc/ti/hercules/ti_tms570lc43x/soc_internal.h b/soc/ti/hercules/ti_tms570lc43x/soc_internal.h new file mode 100644 index 0000000000000..10e451f645517 --- /dev/null +++ b/soc/ti/hercules/ti_tms570lc43x/soc_internal.h @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2025 ispace, inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __TMS570_SOC_INTERNAL_H__ +#define __TMS570_SOC_INTERNAL_H__ + +#include +#include + +/* Primary System Control Registers (SYS) */ +#define REG_SYS1_CSDIS (DRV_SYS1 + 0x0030) +#define REG_SYS1_CSDISSET (DRV_SYS1 + 0x0034) +#define REG_SYS1_CSDISCLR (DRV_SYS1 + 0x0038) +#define REG_SYS1_CDDIS (DRV_SYS1 + 0x003C) +#define REG_SYS1_GHVSRC (DRV_SYS1 + 0x0048) +#define REG_SYS1_VCLKASRC (DRV_SYS1 + 0x004C) +#define REG_SYS1_RCLKSRC (DRV_SYS1 + 0x0050) +#define REG_SYS1_CSVSTAT (DRV_SYS1 + 0x0054) +#define REG_SYS1_PLLCTL1 (DRV_SYS1 + 0x0070) +#define REG_SYS1_PLLCTL2 (DRV_SYS1 + 0x0074) +#define REG_SYS1_CLKCNTL (DRV_SYS1 + 0x00D0) +#define REG_SYS1_GBLSTAT (DRV_SYS1 + 0x00EC) + +/* Secondary System Control Registers (SYS2) */ +#define REG_SYS2_PLLCTL3 (DRV_SYS2 + 0x0000) +#define REG_SYS2_CLK2CNTRL (DRV_SYS2 + 0x003C) +#define REG_SYS2_VCLKACON1 (DRV_SYS2 + 0x0040) +#define REG_SYS2_HCLKCNTL (DRV_SYS2 + 0x0054) + +/* peripheral control resgisters */ +#define REG_PCR1_PSPWRDWNCLR0 (DRV_PCR1 + 0x00A0) +#define REG_PCR1_PSPWRDWNCLR1 (DRV_PCR1 + 0x00A4) +#define REG_PCR1_PSPWRDWNCLR2 (DRV_PCR1 + 0x00A8) +#define REG_PCR1_PSPWRDWNCLR3 (DRV_PCR1 + 0x00AC) + +#define REG_PCR2_PSPWRDWNCLR0 (DRV_PCR2 + 0x00A0) +#define REG_PCR2_PSPWRDWNCLR1 (DRV_PCR2 + 0x00A4) +#define REG_PCR2_PSPWRDWNCLR2 (DRV_PCR2 + 0x00A8) +#define REG_PCR2_PSPWRDWNCLR3 (DRV_PCR2 + 0x00AC) + +#define REG_PCR3_PSPWRDWNCLR0 (DRV_PCR3 + 0x00A0) +#define REG_PCR3_PSPWRDWNCLR1 (DRV_PCR3 + 0x00A4) +#define REG_PCR3_PSPWRDWNCLR2 (DRV_PCR3 + 0x00A8) +#define REG_PCR3_PSPWRDWNCLR3 (DRV_PCR3 + 0x00AC) + +/* flash control registers */ +#define REG_FCR_FRDCNTL (DRV_FCR + 0x0000) +#define REG_FCR_FBPWRMODE (DRV_FCR + 0x0040) +#define REG_FCR_FSM_WR_ENA (DRV_FCR + 0x0288) +#define REG_FCR_EEPROM_CONFIG (DRV_FCR + 0x02B8) + +/* error signalling module registers */ +#define REG_ESM_EEPAPR1 (DRV_ESM + 0x0000) +#define REG_ESM_DEPAPR1 (DRV_ESM + 0x0004) +#define REG_ESM_IESR1 (DRV_ESM + 0x0008) +#define REG_ESM_IECR1 (DRV_ESM + 0x000C) +#define REG_ESM_ILSR1 (DRV_ESM + 0x0010) +#define REG_ESM_ILCR1 (DRV_ESM + 0x0014) +#define REG_ESM_SR1_0 (DRV_ESM + 0x0018) +#define REG_ESM_SR1_1 (DRV_ESM + 0x001C) +#define REG_ESM_SR1_2 (DRV_ESM + 0x0020) +#define REG_ESM_EPSR (DRV_ESM + 0x0024) +#define REG_ESM_IOFFHR (DRV_ESM + 0x0028) +#define REG_ESM_IOFFLR (DRV_ESM + 0x002C) +#define REG_ESM_LTCR (DRV_ESM + 0x0030) +#define REG_ESM_LTCPR (DRV_ESM + 0x0034) +#define REG_ESM_EKR (DRV_ESM + 0x0038) +#define REG_ESM_SSR2 (DRV_ESM + 0x003C) +#define REG_ESM_IEPSR4 (DRV_ESM + 0x0040) +#define REG_ESM_IEPCR4 (DRV_ESM + 0x0044) +#define REG_ESM_IESR4 (DRV_ESM + 0x0048) +#define REG_ESM_IECR4 (DRV_ESM + 0x004C) +#define REG_ESM_ILSR4 (DRV_ESM + 0x0050) +#define REG_ESM_ILCR4 (DRV_ESM + 0x0054) +#define REG_ESM_SR4_0 (DRV_ESM + 0x0058) +#define REG_ESM_SR4_1 (DRV_ESM + 0x005C) +#define REG_ESM_SR4_2 (DRV_ESM + 0x0060) +#define REG_ESM_IEPSR7 (DRV_ESM + 0x0080) +#define REG_ESM_IEPCR7 (DRV_ESM + 0x0084) +#define REG_ESM_IESR7 (DRV_ESM + 0x0088) +#define REG_ESM_IECR7 (DRV_ESM + 0x008C) +#define REG_ESM_ILSR7 (DRV_ESM + 0x0090) +#define REG_ESM_ILCR7 (DRV_ESM + 0x0094) +#define REG_ESM_SR7_0 (DRV_ESM + 0x0098) +#define REG_ESM_SR7_1 (DRV_ESM + 0x009C) +#define REG_ESM_SR7_2 (DRV_ESM + 0x00A0) + +#define REG_SYSECR (DRV_SYSBASE + 0xE0) +#define REG_SYSESR (DRV_SYSBASE + 0xE4) + +#define REG_POMGLBCTRL (DRV_POM_CONTROL + 0x00) + +#define CSDIS_SRC_OSC BIT(0) +#define CSDIS_SRC_PLL1 BIT(1) +#define CSDIS_SRC_LFLPO BIT(4) +#define CSDIS_SRC_HFLPO BIT(5) +#define CSDIS_SRC_PLL2 BIT(6) +#define CSDIS_SRC_MASK (0xFF) + +#define GLBSTAT_OSCFAIL BIT(0) +#define GLBSTAT_RFSLIP BIT(8) +#define GLBSTAT_FBSLIP BIT(9) + +#define CLKCNTL_PERIPHENA BIT(8) + +#define FRDCNTL_RWAIT_OFFSET (8) +#define FRDCNTL_PFUENB BIT(1) +#define FRDCNTL_PFUENA BIT(0) + +#define FSM_WR_ENA_ENABLE_VAL (5 << 0) +#define FSM_WR_ENA_DISABLE_VAL (2 << 0) + +#define EWAIT_OFFSET (16) + +#define BANKPWR0_OFFSET (0) +#define BANKPWR1_OFFSET (2) +#define BANKPWR7_OFFSET (14) +#define BANKPWR_VAL_ACTIVE (3) + +#define GHVWAKE_OFFSET (24) +#define HVLPM_OFFSET (16) +#define GHVSRC_OFFSET (0) + +#define RTI1DIV_OFFSET (8) +#define RTI1SRC_OFFSET (0) + +#define VCLKA1S_OFFSET (0) +#define VCLKA2S_OFFSET (8) + +#define CLKCNTL_VCLKR_OFFSET (16) +#define CLKCNTL_VCLKR_MASK (0xF << CLKCNTL_VCLKR_OFFSET) +#define CLKCNTL_VCLK2R_OFFSET (24) +#define CLKCNTL_VCLK2R_MASK (0xF << CLKCNTL_VCLK2R_OFFSET) +#define CLKCNTL_PENA BIT(8) +#define CLK2CNTRL_VCLK3R_OFFSET (0) +#define CLK2CNTRL_VCLK3R_MASK (0xF << CLK2CNTRL_VCLK3R_OFFSET) + +#define VCLKA4R_OFFSET (24) +#define VCLKA4_DIV_CDDIS BIT(20) +#define VCLKA4S_OFFSET (16) + +#define PLLCTL1_PLLDIV_OFFSET (24) +#define PLLCTL1_PLLDIV_MASK ~(0x1F << PLLCTL1_PLLDIV_OFFSET) +#define PLLCTL1_BPOS_OFFSET (29) +#define PLLCTL1_REFCLKDIV_OFFSET (16) + +#define PLLCTL2_SPREADINGRATE_OFFSET (22) +#define PLLCTL2_MULMOD_OFFSET (12) +#define PLLCTL2_SPR_AMOUNT_OFFSET (0) + +#define PLLCTL3_PLLDIV2_OFFSET (24) +#define PLLCTL3_PLLDIV2_MASK ~(0x1F << PLLCTL3_PLLDIV2_OFFSET) +#define PLLCTL3_REFCLKDIV2_OFFSET (16) +#define PLLCTL3_PLLMUL2_OFFSET (0) + +#define HCLKCNTL_HCLKR_OFFSET (0) + +#define CDDIS_VCLKA2 BIT(5) + +typedef enum { + POWERON_RESET = 0x8000U, /**< Alias for Power On Reset */ + OSC_FAILURE_RESET = 0x4000U, /**< Alias for Osc Failure Reset */ + WATCHDOG_RESET = 0x2000U, /**< Alias for Watch Dog Reset */ + WATCHDOG2_RESET = 0x1000U, /**< Alias for Watch Dog 2 Reset */ + DEBUG_RESET = 0x0800U, /**< Alias for Debug Reset */ + INTERCONNECT_RESET = 0x0080U, /**< Alias for Interconnect Reset */ + CPU0_RESET = 0x0020U, /**< Alias for CPU 0 Reset */ + SW_RESET = 0x0010U, /**< Alias for Software Reset */ + EXT_RESET = 0x0008U, /**< Alias for External Reset */ + NO_RESET = 0x0000U /**< Alias for No Reset */ +} resetSource_t; + + +void _mpuInit_(void); +uint32_t _errata_SSWF021_45_both_plls(uint32_t count); + +#endif /* __TMS570_SOC_INTERNAL_H__ */