diff --git a/boards/ti/lp_mspm0g3507/Kconfig.lp_mspm0g3507 b/boards/ti/lp_mspm0g3507/Kconfig.lp_mspm0g3507 new file mode 100644 index 0000000000000..cb20275099e27 --- /dev/null +++ b/boards/ti/lp_mspm0g3507/Kconfig.lp_mspm0g3507 @@ -0,0 +1,5 @@ +# Copyright (c) 2024 Texas Instruments +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_LP_MSPM0G3507 + select SOC_MSPM0G3507 diff --git a/boards/ti/lp_mspm0g3507/board.cmake b/boards/ti/lp_mspm0g3507/board.cmake new file mode 100644 index 0000000000000..cbeaea2e4564b --- /dev/null +++ b/boards/ti/lp_mspm0g3507/board.cmake @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 + +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/ti/lp_mspm0g3507/board.yml b/boards/ti/lp_mspm0g3507/board.yml new file mode 100644 index 0000000000000..d870b29966842 --- /dev/null +++ b/boards/ti/lp_mspm0g3507/board.yml @@ -0,0 +1,5 @@ +board: + name: lp_mspm0g3507 + vendor: ti + socs: + - name: mspm0g3507 diff --git a/boards/ti/lp_mspm0g3507/docs/img/lp_mspm0g3507.webp b/boards/ti/lp_mspm0g3507/docs/img/lp_mspm0g3507.webp new file mode 100644 index 0000000000000..dba82b8bb9112 Binary files /dev/null and b/boards/ti/lp_mspm0g3507/docs/img/lp_mspm0g3507.webp differ diff --git a/boards/ti/lp_mspm0g3507/docs/index.rst b/boards/ti/lp_mspm0g3507/docs/index.rst new file mode 100644 index 0000000000000..74803467a709c --- /dev/null +++ b/boards/ti/lp_mspm0g3507/docs/index.rst @@ -0,0 +1,194 @@ +.. _lp_mspm0g3507: + +MSPM0G3507 LaunchPad +######################## + +Overview +******** + +MSPM0G350x microcontrollers (MCUs) are part of the MSP highly integrated, ultra-low-power 32-bit MCU +family based on the enhanced Arm® Cortex®-M0+ 32-bit core platform operating at up to 80-MHz frequency. +These cost-optimized MCUs offer high-performance analog peripheral integration, support extended temperature +ranges from -40°C to 125°C, and operate with supply voltages ranging from 1.62 V to 3.6 V. + +The MSPM0G350x devices provide up to 128KB embedded flash program memory with built-in error correction +code (ECC) and up to 32KB SRAM with a hardware parity option. These MCUs also incorporate a +memory protection unit, 7-channel DMA, math accelerator, and a variety of peripherals including +* Analog. + + * Two 12-bit 4-Msps ADCs. + + * Configurable internal shared voltage reference. + + * One 12-bit 1-Msps DAC. + + * Three high speed comparators with built-in reference DACs. + + * Two zero-drift zero-crossover op-amps with programmable gain. + +* Digital. + + * Two 16-bit advanced control timers. + + * Five general-purpose timers. + + * One 16-bit general-purpose timer for QEI interface. + + * One 32-bit high resolution general-purpose timer. + + * Two 16-bit timers with deadband support and up to 12 PWM Channels. + + * Two windowed-watchdog timers. + + * One RTC with alarm and calendar modes. + +* Data Integrity and Encryption. + + * One AES HW accelerator capable of CTR, CBC, and ECB modes. + + * One Cyclic Redundancy Check (CRC) accelerator. + + * One True Random Number Generator (TRNG). + +* Communication. + + * Four UARTs, one with support for advanced modes such as LIN and Manchester. + + * Two I2C supporting SMBUS/PMBUS and speeds up to FM+ (1Mbits/s). + + * Two SPI, one with max speed 32Mbits/s. + + * One CAN interface supporting CAN 2.0 A or B and CAN-FD. + +.. figure:: img/lp_mspm0g3507.webp + :align: center + :alt: MSPM0G3507 LaunchPad development board + +Zephyr uses the ``lp_mspm0g3507`` board configuration for building +the LP_MSPM0G3507 + +Features: +========= + +- Onboard XDS110 debug probe +- EnergyTrace technology available for ultra-low-power debugging +- 2 buttons, 1 LED and 1 RGB LED for user interaction +- Temperature sensor circuit +- Light sensor circuit +- External OPA2365 (default buffer mode) for ADC (up to 4 Msps) evaluation +- Onboard 32.768-kHz and 40-MHz crystals +- RC filter for ADC input (unpopulated by default) + +Details on the MSPM0G3507 LaunchPad can be found on the `TI LP_MSPM0G3507 Product Page`_. + +Supported Features +================== + +The MSPM0G3507 LaunchPad development board configuration supports the following hardware features: + ++-----------+------------+-----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=======================+ +| NVIC | on-chip | nested vectored | +| | | interrupt controller | ++-----------+------------+-----------------------+ +| SYSTICK | on-chip | system clock | ++-----------+------------+-----------------------+ +| UART | on-chip | serial | ++-----------+------------+-----------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-----------------------+ +| PINMUX | on-chip | pinctrl | ++-----------+------------+-----------------------+ +| CLOCKMUX | on-chip | clockctl | ++-----------+------------+-----------------------+ + +More details about the supported peripherals are available in `MSPM0G3507 TRM`_. +Other hardware features are not currently supported by the Zephyr kernel. + +Building and Flashing +********************* + +Building +======== + +Follow the :ref:`getting_started` instructions for Zephyr application development. + +For example, to build the blinky application for the MSPM0G3507 LaunchPad: + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: lp_mspm0g3507 + :goals: build + +The resulting ``zephyr.bin`` binary in the build directory can be flashed onto +MSPM0G3507 LaunchPad using the steps mentioned below. + +Flashing +======== + +Open OCD is used to program the flash memory on the devices. It may be necessary in earlier versions to use a branch of open OCD onto the device. + +Before OpenOCD is public, one can clone `This Repo `_, and then this can be built with + +``` +cd +./bootstrap (when building from the git repository) +./configure --enable-xds110 +make +sudo make install +``` + +Then after the build, it is possible to flash the device by passing additional arguments to the flash command + +``` +west flash --openocd /src/openocd --openocd-search /tcl +``` + + +`UniFlash`_ can also be used to program the flash memory if needed. The flash utility, +however, requires the use of 8-byte aligned words, so adding alignment to the linker file is necessary. + +Debugging +========= + +The flashing method described above does not include symbols. Thus, debugging requires an additional step to load the symbols. +This section shows how to debug the MSPM0G3507 LaunchPad board using `CCS IDE`_. More information +on debugging using CCS can be found in `CCS User's Guide`_. + +In general, the steps for debugging in CCS are: + + 1. Open CCS + 2. Go to :menuselection:`Window --> Show View --> Target Configruation` + 3. Import target confguration by right clicking User Defined, selecting Import target configuration and pointing to the lp_mspm0g3507/support/MSPM0G3507.ccxml + 4. Launch target configuration by right clicking the new MSPM0G3507.ccxml file and clicking Launch target configuration + 5. Plug in the device and connect to it by going to :menuselection:`Run --> Connect Target` + 6. Go to :menuselection:`Run --> Load --> Load Symbols and load in the zephyr.elf file loaded` + 7. Use CCS to debug + +References +********** + +TI MSPM0 MCU Page: + https://www.ti.com/microcontrollers-mcus-processors/arm-based-microcontrollers/arm-cortex-m0-mcus/overview.html + +TI MSPM0G3507 Product Page: + https://www.ti.com/product/MSPM0G3507 + +TI MSPM0 SDK: + https://www.ti.com/tool/MSPM0-SDK + +.. _CCS User's Guide: + https://software-dl.ti.com/ccs/esd/documents/users_guide/index.html + +.. _MSPM0G3507 TRM: + https://www.ti.com/lit/slau846 + +.. _TI LP_MSPM0G3507 Product Page: + https://www.ti.com/tool/LP-MSPM0G3507 + +.. _UniFlash: + http://processors.wiki.ti.com/index.php/UniFlash_v4_Quick_Guide#Command_Line_Interface + +.. _CCS IDE: + http://www.ti.com/tool/ccstudio diff --git a/boards/ti/lp_mspm0g3507/lp_mspm0g3507.dts b/boards/ti/lp_mspm0g3507/lp_mspm0g3507.dts new file mode 100644 index 0000000000000..0c06c3c7b80df --- /dev/null +++ b/boards/ti/lp_mspm0g3507/lp_mspm0g3507.dts @@ -0,0 +1,85 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +/dts-v1/; + +#include +#include +#include + +/ { + model = "TI LP_MSPM0G3507"; + compatible = "ti,mspm0g3507"; + + aliases { + led0 = &led0; + led1 = &led1; + sw0 = &btn0; + sw1 = &btn1; + }; + + chosen { + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + }; + + leds { + compatible = "gpio-leds"; + led0: led_2_b { + gpios = <&gpiob 22 GPIO_ACTIVE_HIGH>; + label = "Blue RBG LED"; + }; + led1: led_2_r { + gpios = <&gpiob 26 GPIO_ACTIVE_HIGH>; + label = "Red RBG LED"; + }; + led2: led_2_g { + gpios = <&gpiob 27 GPIO_ACTIVE_HIGH>; + label = "Green RBG LED"; + }; + led3: led_1 { + gpios = <&gpioa 0 GPIO_ACTIVE_LOW>; + label = "Red LED"; + }; + }; + + keys { + compatible = "gpio-keys"; + btn0: btn_0 { + gpios = <&gpiob 21 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + label = "Switch 2"; + zephyr,code = ; + }; + btn1: btn_1 { + gpios = <&gpioa 18 GPIO_ACTIVE_HIGH>; + label = "Switch 1"; + zephyr,code = ; + }; + }; +}; + +&cpu0 { + clock-frequency = ; +}; + +&clkmux { + clock-source = <&pll>; + clock-frequency = ; + uclk-div = <2>; +}; + +&gpioa { + status = "okay"; +}; + +&gpiob { + status = "okay"; +}; + +&uart0 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart0_tx_pa10 &uart0_rx_pa11>; + pinctrl-names = "default"; +}; diff --git a/boards/ti/lp_mspm0g3507/lp_mspm0g3507.yaml b/boards/ti/lp_mspm0g3507/lp_mspm0g3507.yaml new file mode 100644 index 0000000000000..6b0cbd0800139 --- /dev/null +++ b/boards/ti/lp_mspm0g3507/lp_mspm0g3507.yaml @@ -0,0 +1,15 @@ +identifier: lp_mspm0g3507 +name: LP_MSPM0G3507 +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb + - xtools +ram: 32 +flash: 128 +supported: + - gpio + - pinctrl + - uart +vendor: ti diff --git a/boards/ti/lp_mspm0g3507/lp_mspm0g3507_defconfig b/boards/ti/lp_mspm0g3507/lp_mspm0g3507_defconfig new file mode 100644 index 0000000000000..c5aeccf7c56df --- /dev/null +++ b/boards/ti/lp_mspm0g3507/lp_mspm0g3507_defconfig @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_CORTEX_M_SYSTICK=y + +# Enable GPIO driver +CONFIG_GPIO=y + +# Enable UART driver +CONFIG_SERIAL=y + +# Enable Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable Clock Control +CONFIG_CLOCK_CONTROL=y diff --git a/boards/ti/lp_mspm0g3507/support/openocd.cfg b/boards/ti/lp_mspm0g3507/support/openocd.cfg new file mode 100644 index 0000000000000..0356c7705cf1b --- /dev/null +++ b/boards/ti/lp_mspm0g3507/support/openocd.cfg @@ -0,0 +1,4 @@ +source [find interface/xds110.cfg] +adapter speed 10000 + +source [find target/ti_mspm0.cfg] diff --git a/drivers/clock_control/CMakeLists.txt b/drivers/clock_control/CMakeLists.txt index b17dc7b86c55b..dfa79684ce43b 100644 --- a/drivers/clock_control/CMakeLists.txt +++ b/drivers/clock_control/CMakeLists.txt @@ -20,6 +20,7 @@ zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_MCUX_SCG_K4 clock_cont zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_MCUX_SIM clock_control_mcux_sim.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_MCUX_SYSCON clock_control_mcux_syscon.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NPCM clock_control_npcm.c) +zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_MSPM0 clock_control_mspm0.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NPCX clock_control_npcx.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NRF clock_control_nrf.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NRF_DRIVER_CALIBRATION nrf_clock_calibration.c) diff --git a/drivers/clock_control/Kconfig b/drivers/clock_control/Kconfig index 040dab163c2b4..f1292bde8f28f 100644 --- a/drivers/clock_control/Kconfig +++ b/drivers/clock_control/Kconfig @@ -52,6 +52,8 @@ source "drivers/clock_control/Kconfig.mcux_syscon" source "drivers/clock_control/Kconfig.npcm" +source "drivers/clock_control/Kconfig.mspm0" + source "drivers/clock_control/Kconfig.npcx" source "drivers/clock_control/Kconfig.rv32m1" diff --git a/drivers/clock_control/Kconfig.mspm0 b/drivers/clock_control/Kconfig.mspm0 new file mode 100644 index 0000000000000..55b94dd9972bc --- /dev/null +++ b/drivers/clock_control/Kconfig.mspm0 @@ -0,0 +1,17 @@ +# TI MSPM0 Family + +# Copyright (c) 2024, Texas Instruments Inc. +# SPDX-License-Identifier: Apache-2.0 + +config CLOCK_CONTROL_MSPM0 + bool "TI MSPM0 clock" + default y + depends on SOC_FAMILY_TI_MSPM0 + help + This option enables the TI MSPM0 Clock Control Enabler + +config CLOCK_CONTROL_MSPM0_USE_PLL + bool "TI MSPM0 Use PLL" + default n + help + This option enables the PLL on MSPM0 devices (if equipped) diff --git a/drivers/clock_control/clock_control_mspm0.c b/drivers/clock_control/clock_control_mspm0.c new file mode 100644 index 0000000000000..305a80699f634 --- /dev/null +++ b/drivers/clock_control/clock_control_mspm0.c @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2024 Texas Instruments + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include + +#define ULPCLK_DIV CONCAT(DL_SYSCTL_ULPCLK_DIV_, DT_PROP(DT_NODELABEL(clkmux), uclk_div)) + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(pll), okay) +#define MSPM0_PLL_ENABLED 1 +#endif + +static const DL_SYSCTL_SYSPLLConfig clock_mspm0_cfg_syspll; + +static int clock_mspm0_on(const struct device *dev, clock_control_subsys_t sys) +{ + return 0; +} + +static int clock_mspm0_off(const struct device *dev, clock_control_subsys_t sys) +{ + return 0; +} + +static enum clock_control_status clock_mspm0_get_status(const struct device *dev, + clock_control_subsys_t sys) +{ + return CLOCK_CONTROL_STATUS_UNKNOWN; +} + +static int clock_mspm0_get_rate(const struct device *dev, clock_control_subsys_t sys, + uint32_t *rate) +{ + struct mspm0_clockSys *clockSys = (struct mspm0_clockSys *)sys; + uint8_t rateNotFound = 0; + + switch (clockSys->bus) { + case MSPM0_CLOCK_BUS_LFCLK: + *rate = 32768; + break; + case MSPM0_CLOCK_BUS_ULPCLK: + *rate = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / + DT_PROP(DT_NODELABEL(clkmux), uclk_div); + break; + case MSPM0_CLOCK_BUS_MCLK: + *rate = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC; + break; + case MSPM0_CLOCK_BUS_MFPCLK: + *rate = 4000000; + break; + case MSPM0_CLOCK_BUS_MFCLK: + case MSPM0_CLOCK_BUS_CANCLK: + default: + rateNotFound = 1; + break; + } + if (rateNotFound == 1) { + return -ENOTSUP; + } else { + return 0; + } +} + +static int clock_mspm0_set_rate(const struct device *dev, clock_control_subsys_t sys, + clock_control_subsys_rate_t rate) +{ + return -ENOTSUP; +} + +static int clock_mspm0_configure(const struct device *dev, clock_control_subsys_t sys, void *data) +{ + return -ENOTSUP; +} + +static int clock_mspm0_init(const struct device *dev) +{ + /* setup clocks based on specific rates */ + DL_SYSCTL_setSYSOSCFreq(DL_SYSCTL_SYSOSC_FREQ_BASE); + + DL_SYSCTL_configSYSPLL((DL_SYSCTL_SYSPLLConfig *)&clock_mspm0_cfg_syspll); + + DL_SYSCTL_setULPCLKDivider(ULPCLK_DIV); + DL_SYSCTL_setMCLKSource(SYSOSC, HSCLK, DL_SYSCTL_HSCLK_SOURCE_SYSPLL); + + return 0; +} + +static const struct clock_control_driver_api clock_mspm0_driver_api = { + .on = clock_mspm0_on, + .off = clock_mspm0_off, + .get_status = clock_mspm0_get_status, + .get_rate = clock_mspm0_get_rate, + .set_rate = clock_mspm0_set_rate, + .configure = clock_mspm0_configure}; + +DEVICE_DT_DEFINE(DT_NODELABEL(clkmux), &clock_mspm0_init, NULL, NULL, NULL, PRE_KERNEL_1, + CONFIG_CLOCK_CONTROL_INIT_PRIORITY, &clock_mspm0_driver_api); + +#if MSPM0_PLL_ENABLED + +/* basic checks of the devicetree to follow */ +#if (DT_NODE_HAS_PROP(DT_NODELABEL(pll), clk2x_div) && \ + DT_NODE_HAS_PROP(DT_NODELABEL(pll), clk0_div)) +#error "Only CLK2X or CLK0 can be enabled at a time on the PLL" +#endif + +#define GENERATE_PLL_STRUCT() \ + static const DL_SYSCTL_SYSPLLConfig clock_mspm0_cfg_syspll = { \ + .inputFreq = DL_SYSCTL_SYSPLL_INPUT_FREQ_32_48_MHZ, \ + .rDivClk2x = (DT_PROP_OR(DT_NODELABEL(pll), clk2x_div, 1) - 1), \ + .rDivClk1 = (DT_PROP_OR(DT_NODELABEL(pll), clk1_div, 1) - 1), \ + .rDivClk0 = (DT_PROP_OR(DT_NODELABEL(pll), clk0_div, 1) - 1), \ + .qDiv = (DT_PROP(DT_NODELABEL(pll), q_div) - 1), \ + .pDiv = CONCAT(DL_SYSCTL_SYSPLL_PDIV_, DT_PROP(DT_NODELABEL(pll), p_div)), \ + .sysPLLMCLK = COND_CODE_1(DT_NODE_HAS_PROP(DT_NODELABEL(pll), clk2x_div), \ + (DL_SYSCTL_SYSPLL_MCLK_CLK2X), (DL_SYSCTL_SYSPLL_MCLK_CLK0)), \ + .enableCLK2x = COND_CODE_1(DT_NODE_HAS_PROP(DT_NODELABEL(pll), clk2x_div), \ + (DL_SYSCTL_SYSPLL_CLK2X_ENABLE), (DL_SYSCTL_SYSPLL_CLK2X_DISABLE)), \ + .enableCLK1 = COND_CODE_1(DT_NODE_HAS_PROP(DT_NODELABEL(pll), clk1_div), \ + (DL_SYSCTL_SYSPLL_CLK1_ENABLE), (DL_SYSCTL_SYSPLL_CLK1_DISABLE)), \ + .enableCLK0 = COND_CODE_1(DT_NODE_HAS_PROP(DT_NODELABEL(pll), clk0_div), \ + (DL_SYSCTL_SYSPLL_CLK0_ENABLE), (DL_SYSCTL_SYSPLL_CLK0_DISABLE)), \ + .sysPLLRef = COND_CODE_1(DT_CLOCKS_CELL(DT_NODELABEL(pll), clocks), \ + (DL_SYSCTL_SYSPLL_REF_HFCLK), (DL_SYSCTL_SYSPLL_REF_SYSOSC)), \ + }; + +GENERATE_PLL_STRUCT() + +#endif /* MSPM0_PLL_ENABLED */ diff --git a/drivers/gpio/CMakeLists.txt b/drivers/gpio/CMakeLists.txt index b1b053f90cebc..434eccad0d0d8 100644 --- a/drivers/gpio/CMakeLists.txt +++ b/drivers/gpio/CMakeLists.txt @@ -52,6 +52,7 @@ zephyr_library_sources_ifdef(CONFIG_GPIO_MCUX_IGPIO gpio_mcux_igpio.c) zephyr_library_sources_ifdef(CONFIG_GPIO_MCUX_LPC gpio_mcux_lpc.c) zephyr_library_sources_ifdef(CONFIG_GPIO_MCUX_RGPIO gpio_mcux_rgpio.c) zephyr_library_sources_ifdef(CONFIG_GPIO_MMIO32 gpio_mmio32.c) +zephyr_library_sources_ifdef(CONFIG_GPIO_MSPM0 gpio_mspm0.c) zephyr_library_sources_ifdef(CONFIG_GPIO_NCT38XX gpio_nct38xx.c) zephyr_library_sources_ifdef(CONFIG_GPIO_NCT38XX gpio_nct38xx_port.c) zephyr_library_sources_ifdef(CONFIG_GPIO_NCT38XX_ALERT gpio_nct38xx_alert.c) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 6bae51f9880ee..a33b7a88d7108 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -141,6 +141,7 @@ source "drivers/gpio/Kconfig.mcux_igpio" source "drivers/gpio/Kconfig.mcux_lpc" source "drivers/gpio/Kconfig.mcux_rgpio" source "drivers/gpio/Kconfig.mmio32" +source "drivers/gpio/Kconfig.mspm0" source "drivers/gpio/Kconfig.nct38xx" source "drivers/gpio/Kconfig.neorv32" source "drivers/gpio/Kconfig.npcx" diff --git a/drivers/gpio/Kconfig.mspm0 b/drivers/gpio/Kconfig.mspm0 new file mode 100644 index 0000000000000..cb7ec576c046f --- /dev/null +++ b/drivers/gpio/Kconfig.mspm0 @@ -0,0 +1,11 @@ +# TI MSPM0 GPIO configuration options + +# Copyright (c) 2024 Texas Instruments +# SPDX-License-Identifier: Apache-2.0 + +config GPIO_MSPM0 + bool "TI SimpleLink MSPM0 GPIO driver" + default y + depends on DT_HAS_TI_MSPM0_GPIO_ENABLED + help + Enable the TI MSPM0 GPIO driver. diff --git a/drivers/gpio/Kconfig.mspm0g3xxx b/drivers/gpio/Kconfig.mspm0g3xxx new file mode 100644 index 0000000000000..e3cd6a23bf47a --- /dev/null +++ b/drivers/gpio/Kconfig.mspm0g3xxx @@ -0,0 +1,11 @@ +# TI MSPM0G3XXX GPIO configuration options + +# Copyright (c) 2024 Texas Instruments +# SPDX-License-Identifier: Apache-2.0 + +config GPIO_MSPM0G3XXX + bool "TI SimpleLink MSPM0G3XXX GPIO driver" + default y + depends on DT_HAS_TI_MSPM0G3XXX_GPIO_ENABLED + help + Enable the TI MSPM0G3XXX GPIO driver. diff --git a/drivers/gpio/gpio_mspm0.c b/drivers/gpio/gpio_mspm0.c new file mode 100644 index 0000000000000..a5c8447f6c4e7 --- /dev/null +++ b/drivers/gpio/gpio_mspm0.c @@ -0,0 +1,300 @@ +/* + * Copyright (c) 2024 Texas Instruments + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT ti_mspm0_gpio + +/* Zephyr includes */ +#include +#include +#include +#include + +/* Driverlib includes */ +#include + +/* GPIO defines */ +#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpioa), okay) +#define GPIOA_NODE DT_NODELABEL(gpioa) + +#ifdef CONFIG_SOC_SERIES_MSPM0G1X0X_G3X0X +#define NUM_GPIOA_PIN 32 +#define gpioa_pins NUM_GPIOA_PIN +static uint32_t gpioa_pincm_lut[NUM_GPIOA_PIN] = { + IOMUX_PINCM1, IOMUX_PINCM2, IOMUX_PINCM7, IOMUX_PINCM8, IOMUX_PINCM9, IOMUX_PINCM10, + IOMUX_PINCM11, IOMUX_PINCM14, IOMUX_PINCM19, IOMUX_PINCM20, IOMUX_PINCM21, IOMUX_PINCM22, + IOMUX_PINCM34, IOMUX_PINCM35, IOMUX_PINCM36, IOMUX_PINCM37, IOMUX_PINCM38, IOMUX_PINCM39, + IOMUX_PINCM40, IOMUX_PINCM41, IOMUX_PINCM42, IOMUX_PINCM46, IOMUX_PINCM47, IOMUX_PINCM53, + IOMUX_PINCM54, IOMUX_PINCM55, IOMUX_PINCM59, IOMUX_PINCM60, IOMUX_PINCM3, IOMUX_PINCM4, + IOMUX_PINCM5, IOMUX_PINCM6, +}; +#else +#throw "series lookup table not supported" +#endif /* if config SOC_SERIES_MSPM0G1X0X_G3X0X */ + +#endif /* DT_NODE_HAS_STATUS(DT_NODELABEL(gpioa), okay) */ + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpiob), okay) +#define GPIOB_NODE DT_NODELABEL(gpiob) +#ifdef CONFIG_SOC_SERIES_MSPM0G1X0X_G3X0X +#define NUM_GPIOB_PIN 28 +#define gpiob_pins NUM_GPIOB_PIN +static uint32_t gpiob_pincm_lut[NUM_GPIOB_PIN] = { + IOMUX_PINCM12, IOMUX_PINCM13, IOMUX_PINCM15, IOMUX_PINCM16, IOMUX_PINCM17, IOMUX_PINCM18, + IOMUX_PINCM23, IOMUX_PINCM24, IOMUX_PINCM25, IOMUX_PINCM26, IOMUX_PINCM27, IOMUX_PINCM28, + IOMUX_PINCM29, IOMUX_PINCM30, IOMUX_PINCM31, IOMUX_PINCM32, IOMUX_PINCM33, IOMUX_PINCM43, + IOMUX_PINCM44, IOMUX_PINCM45, IOMUX_PINCM48, IOMUX_PINCM49, IOMUX_PINCM50, IOMUX_PINCM51, + IOMUX_PINCM52, IOMUX_PINCM56, IOMUX_PINCM57, IOMUX_PINCM58, +}; +#endif /* CONFIG_SOC_SERIES */ +#endif /* DT_NODE_HAS_STATUS(DT_NODELABEL(gpiob), okay) */ + +struct gpio_mspm0_config { + /* gpio_mspm0_config needs to be first (doesn't actually get used) */ + struct gpio_driver_config common; + /* port base address */ + GPIO_Regs *base; + /* port pincm lookup table */ + uint32_t *pincm_lut; +}; + +struct gpio_mspm0_data { + /* gpio_driver_data needs to be first */ + struct gpio_driver_data common; + sys_slist_t callbacks; /* List of interrupt callbacks */ +}; + +static int gpio_mspm0_port_set_bits_raw(const struct device *port, uint32_t mask); +static int gpio_mspm0_port_clear_bits_raw(const struct device *port, uint32_t mask); + +static int gpio_mspm0_pin_configure(const struct device *port, gpio_pin_t pin, gpio_flags_t flags) +{ + const struct gpio_mspm0_config *config = port->config; + /* determine pull up resistor value based on flags */ + DL_GPIO_RESISTOR respull; + + if (flags & GPIO_PULL_UP) { + respull = DL_GPIO_RESISTOR_PULL_UP; + } else if (flags & GPIO_PULL_DOWN) { + respull = DL_GPIO_RESISTOR_PULL_DOWN; + } else { + respull = DL_GPIO_RESISTOR_NONE; + } + /* Config pin based on flags */ + switch (flags & (GPIO_INPUT | GPIO_OUTPUT)) { + case GPIO_INPUT: + DL_GPIO_initDigitalInputFeatures(config->pincm_lut[pin], DL_GPIO_INVERSION_DISABLE, + respull, DL_GPIO_HYSTERESIS_DISABLE, + DL_GPIO_WAKEUP_DISABLE); + break; + case GPIO_OUTPUT: + DL_GPIO_initDigitalOutputFeatures(config->pincm_lut[pin], DL_GPIO_INVERSION_DISABLE, + respull, DL_GPIO_DRIVE_STRENGTH_LOW, + DL_GPIO_HIZ_DISABLE); + + /* Set initial state */ + if (flags & GPIO_OUTPUT_INIT_HIGH) { + gpio_mspm0_port_set_bits_raw(port, BIT(pin)); + } else if (flags & GPIO_OUTPUT_INIT_LOW) { + gpio_mspm0_port_clear_bits_raw(port, BIT(pin)); + } + /* Enable output */ + DL_GPIO_enableOutput(config->base, BIT(pin)); + break; + case GPIO_DISCONNECTED: + DL_GPIO_disableOutput(config->base, BIT(pin)); + break; + default: + return -ENOTSUP; + } + + return 0; +} + +static int gpio_mspm0_port_get_raw(const struct device *port, uint32_t *value) +{ + const struct gpio_mspm0_config *config = port->config; + + /* Read entire port */ + *value = DL_GPIO_readPins(config->base, UINT32_MAX); + + return 0; +} + +static int gpio_mspm0_port_set_masked_raw(const struct device *port, uint32_t mask, uint32_t value) +{ + const struct gpio_mspm0_config *config = port->config; + + DL_GPIO_writePinsVal(config->base, mask, value); + + return 0; +} + +static int gpio_mspm0_port_set_bits_raw(const struct device *port, uint32_t mask) +{ + const struct gpio_mspm0_config *config = port->config; + + DL_GPIO_setPins(config->base, mask); + + return 0; +} + +static int gpio_mspm0_port_clear_bits_raw(const struct device *port, uint32_t mask) +{ + const struct gpio_mspm0_config *config = port->config; + + DL_GPIO_clearPins(config->base, mask); + + return 0; +} + +static int gpio_mspm0_port_toggle_bits(const struct device *port, uint32_t mask) +{ + const struct gpio_mspm0_config *config = port->config; + + DL_GPIO_togglePins(config->base, mask); + + return 0; +} + +static int gpio_mspm0_pin_interrupt_configure(const struct device *port, gpio_pin_t pin, + enum gpio_int_mode mode, enum gpio_int_trig trig) +{ + const struct gpio_mspm0_config *config = port->config; + + /* Config interrupt */ + switch (mode) { + case GPIO_INT_MODE_DISABLED: + DL_GPIO_clearInterruptStatus(config->base, BIT(pin)); + DL_GPIO_disableInterrupt(config->base, BIT(pin)); + break; + case GPIO_INT_MODE_EDGE: + uint32_t polarity = 0x00; + + if (trig & GPIO_INT_TRIG_LOW) { + polarity |= BIT(0); + } + if (trig & GPIO_INT_TRIG_HIGH) { + polarity |= BIT(1); + } + if (pin < 16) { + DL_GPIO_setLowerPinsPolarity(config->base, polarity << (2 * pin)); + } else { + DL_GPIO_setUpperPinsPolarity(config->base, polarity << (2 * (pin - 16))); + } + DL_GPIO_clearInterruptStatus(config->base, BIT(pin)); + DL_GPIO_enableInterrupt(config->base, BIT(pin)); + break; + case GPIO_INT_MODE_LEVEL: + return -ENOTSUP; + } + + return 0; +} + +static int gpio_mspm0_manage_callback(const struct device *port, struct gpio_callback *callback, + bool set) +{ + struct gpio_mspm0_data *data = port->data; + + return gpio_manage_callback(&data->callbacks, callback, set); +} + +static uint32_t gpio_mspm0_get_pending_int(const struct device *port) +{ + const struct gpio_mspm0_config *config = port->config; + + return DL_GPIO_getPendingInterrupt(config->base); +} + +static void gpio_mspm0_isr(const struct device *port) +{ +#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpioa), okay) + const struct device *dev_a = DEVICE_DT_GET(GPIOA_NODE); + struct gpio_mspm0_data *data_a = dev_a->data; + const struct gpio_mspm0_config *config_a = dev_a->config; + + uint32_t status_a = DL_GPIO_getRawInterruptStatus(config_a->base, 0xFFFFFFFF); + + DL_GPIO_clearInterruptStatus(config_a->base, status_a); + + gpio_fire_callbacks(&data_a->callbacks, dev_a, status_a); +#endif /* DT_NODE_HAS_STATUS(DT_NODELABEL(gpioa), okay) */ + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpiob), okay) + const struct device *dev_b = DEVICE_DT_GET(GPIOB_NODE); + struct gpio_mspm0_data *data_b = dev_b->data; + const struct gpio_mspm0_config *config_b = dev_b->config; + + uint32_t status_b = DL_GPIO_getRawInterruptStatus(config_b->base, 0xFFFFFFFF); + + DL_GPIO_clearInterruptStatus(config_b->base, status_b); + + gpio_fire_callbacks(&data_b->callbacks, dev_b, status_b); +#endif /* DT_NODE_HAS_STATUS(DT_NODELABEL(gpiob), okay) */ +} + +static bool init_irq = true; + +static int gpio_mspm0_init(const struct device *port) +{ + /* Powering up of GPIOs is part of soc.c */ + + if (init_irq) { + + init_irq = false; + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpiob), okay) + IRQ_CONNECT(DT_IRQN(GPIOB_NODE), DT_IRQ(GPIOB_NODE, priority), gpio_mspm0_isr, + DEVICE_DT_GET(GPIOB_NODE), 0); + irq_enable(DT_IRQN(GPIOB_NODE)); +#elif DT_NODE_HAS_STATUS(DT_NODELABEL(gpioa), okay) + IRQ_CONNECT(DT_IRQN(GPIOA_NODE), DT_IRQ(GPIOA_NODE, priority), gpio_mspm0_isr, + DEVICE_DT_GET(GPIOA_NODE), 0); + irq_enable(DT_IRQN(GPIOA_NODE)); +#endif + } + + return 0; +} + +static const struct gpio_driver_api gpio_mspm0_driver_api = { + .pin_configure = gpio_mspm0_pin_configure, + .port_get_raw = gpio_mspm0_port_get_raw, + .port_set_masked_raw = gpio_mspm0_port_set_masked_raw, + .port_set_bits_raw = gpio_mspm0_port_set_bits_raw, + .port_clear_bits_raw = gpio_mspm0_port_clear_bits_raw, + .port_toggle_bits = gpio_mspm0_port_toggle_bits, + .pin_interrupt_configure = gpio_mspm0_pin_interrupt_configure, + .manage_callback = gpio_mspm0_manage_callback, + .get_pending_int = gpio_mspm0_get_pending_int, +}; + +#define GPIO_DEVICE_INIT(__node, __suffix, __base_addr) \ + static const struct gpio_mspm0_config gpio_mspm0_cfg_##__suffix = { \ + .common = \ + { \ + .port_pin_mask = \ + GPIO_PORT_PIN_MASK_FROM_NGPIOS(gpio##__suffix##_pins), \ + }, \ + .base = (GPIO_Regs *)__base_addr, \ + .pincm_lut = gpio##__suffix##_pincm_lut, \ + }; \ + static struct gpio_mspm0_data gpio_mspm0_data_##__suffix; \ + DEVICE_DT_DEFINE(__node, gpio_mspm0_init, NULL, &gpio_mspm0_data_##__suffix, \ + &gpio_mspm0_cfg_##__suffix, PRE_KERNEL_1, CONFIG_GPIO_INIT_PRIORITY, \ + &gpio_mspm0_driver_api) + +#define GPIO_DEVICE_INIT_MSPM0(__suffix) \ + GPIO_DEVICE_INIT(DT_NODELABEL(gpio##__suffix), __suffix, \ + DT_REG_ADDR(DT_NODELABEL(gpio##__suffix))) + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpioa), okay) +GPIO_DEVICE_INIT_MSPM0(a); +#endif /* DT_NODE_HAS_STATUS(DT_NODELABEL(gpioa), okay) */ + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpiob), okay) +GPIO_DEVICE_INIT_MSPM0(b); +#endif /* DT_NODE_HAS_STATUS(DT_NODELABEL(gpiob), okay) */ diff --git a/drivers/pinctrl/CMakeLists.txt b/drivers/pinctrl/CMakeLists.txt index d2834504eb2e0..973f2086485c1 100644 --- a/drivers/pinctrl/CMakeLists.txt +++ b/drivers/pinctrl/CMakeLists.txt @@ -33,6 +33,7 @@ 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_EMSDP pinctrl_emsdp.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_TI_CC32XX pinctrl_ti_cc32xx.c) +zephyr_library_sources_ifdef(CONFIG_PINCTRL_MSPM0 pinctrl_mspm0.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_NUMAKER pinctrl_numaker.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_QUICKLOGIC_EOS_S3 pinctrl_eos_s3.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_MCI_IO_MUX pinctrl_mci_io_mux.c) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index d8621e7ad9e1d..79f71807d0eb8 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -59,6 +59,7 @@ source "drivers/pinctrl/Kconfig.nxp_s32" source "drivers/pinctrl/Kconfig.gecko" source "drivers/pinctrl/Kconfig.silabs_dbus" source "drivers/pinctrl/Kconfig.ti_k3" +source "drivers/pinctrl/Kconfig.mspm0" source "drivers/pinctrl/Kconfig.emsdp" source "drivers/pinctrl/Kconfig.ti_cc32xx" source "drivers/pinctrl/Kconfig.numaker" diff --git a/drivers/pinctrl/Kconfig.mspm0 b/drivers/pinctrl/Kconfig.mspm0 new file mode 100644 index 0000000000000..ed2a728ed5f64 --- /dev/null +++ b/drivers/pinctrl/Kconfig.mspm0 @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright (c) 2024 Texas Instruments + +config PINCTRL_MSPM0 + bool "TI pinctrl MSPM0 driver" + default y + depends on DT_HAS_TI_MSPM0_PINCTRL_ENABLED + help + Enable support for the PINCTRL on TI MSPM0 series. diff --git a/drivers/pinctrl/pinctrl_mspm0.c b/drivers/pinctrl/pinctrl_mspm0.c new file mode 100644 index 0000000000000..fffa50a39dacb --- /dev/null +++ b/drivers/pinctrl/pinctrl_mspm0.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024 Texas Instruments + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#define DT_DRV_COMPAT ti_mspm0_pinctrl + +#define MSPM0_PINCM(pinmux) (pinmux >> 0x10) +#define MSPM0_PIN_FUNCTION(pinmux) (pinmux & 0x3F) + +int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg) +{ + ARG_UNUSED(reg); + + uint8_t pin_function; + uint32_t pin_cm; + uint32_t iomux; + + for (int i = 0; i < pin_cnt; i++) { + pin_cm = MSPM0_PINCM(pins[i].pinmux); + pin_function = MSPM0_PIN_FUNCTION(pins[i].pinmux); + iomux = pins[i].iomux; + if (pin_function == 0x00) { + DL_GPIO_initPeripheralAnalogFunction(pin_cm); + } else { + DL_GPIO_initPeripheralFunction(pin_cm, (iomux | pin_function)); + } + } + + return 0; +} diff --git a/drivers/serial/CMakeLists.txt b/drivers/serial/CMakeLists.txt index 15afe117e477e..41ccd97b5982b 100644 --- a/drivers/serial/CMakeLists.txt +++ b/drivers/serial/CMakeLists.txt @@ -43,6 +43,7 @@ zephyr_library_sources_ifdef(CONFIG_UART_MCUX_LPSCI uart_mcux_lpsci.c) zephyr_library_sources_ifdef(CONFIG_UART_MCUX_LPUART uart_mcux_lpuart.c) zephyr_library_sources_ifdef(CONFIG_UART_MIV uart_miv.c) zephyr_library_sources_ifdef(CONFIG_UART_MSP432P4XX uart_msp432p4xx.c) +zephyr_library_sources_ifdef(CONFIG_UART_MSPM0 uart_mspm0.c) zephyr_library_sources_ifdef(CONFIG_UART_NEORV32 uart_neorv32.c) zephyr_library_sources_ifdef(CONFIG_UART_NPCX uart_npcx.c) zephyr_library_sources_ifdef(CONFIG_UART_NRFX_UART uart_nrfx_uart.c) diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 9b76ac170c704..1628239923f70 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -183,6 +183,7 @@ rsource "Kconfig.mcux_lpsci" rsource "Kconfig.mcux_lpuart" rsource "Kconfig.miv" rsource "Kconfig.msp432p4xx" +rsource "Kconfig.mspm0" rsource "Kconfig.native_posix" rsource "Kconfig.native_tty" rsource "Kconfig.neorv32" diff --git a/drivers/serial/Kconfig.mspm0 b/drivers/serial/Kconfig.mspm0 new file mode 100644 index 0000000000000..c71ef5bf8635c --- /dev/null +++ b/drivers/serial/Kconfig.mspm0 @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright (c) 2024 Texas Instruments + +config UART_MSPM0 + bool "MSPM0 UART driver" + default y + depends on DT_HAS_TI_MSPM0_UART_ENABLED + select SERIAL_HAS_DRIVER + select SERIAL_SUPPORT_INTERRUPT + select PINCTRL + help + This option enables the TI MSPM0 UART driver. diff --git a/drivers/serial/uart_mspm0.c b/drivers/serial/uart_mspm0.c new file mode 100644 index 0000000000000..165803017eb34 --- /dev/null +++ b/drivers/serial/uart_mspm0.c @@ -0,0 +1,324 @@ +/* + * Copyright (c) 2024 Texas Instruments + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT ti_mspm0_uart + +/* Zephyr includes */ +#include +#include +#include +#include +#include +#include +#include + +/* Driverlib includes */ +#include + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +#define UART_MSPM0_TX_INTERRUPTS (DL_UART_MAIN_INTERRUPT_TX | DL_UART_MAIN_INTERRUPT_EOT_DONE) +#define UART_MSPM0_RX_INTERRUPTS (DL_UART_MAIN_INTERRUPT_RX) +#endif + +struct uart_mspm0_config { + UART_Regs *regs; + uint32_t clock_frequency; + uint32_t current_speed; + const struct mspm0_clockSys *clock_subsys; + const struct pinctrl_dev_config *pinctrl; +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + uart_irq_config_func_t irq_config_func; +#endif +}; + +struct uart_mspm0_data { + /* UART clock structure */ + DL_UART_Main_ClockConfig clock_config; + /* UART config structure */ + DL_UART_Main_Config config; +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + uint32_t interruptState; /* Masked Interrupt Status when called by irq_update */ + uart_irq_callback_user_data_t cb; /* Callback function pointer */ + void *cb_data; /* Callback function arg */ +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ +}; + + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void uart_mspm0_isr(const struct device *dev); +#define MSPM0_INTERRUPT_CALLBACK_FN(index) .cb = NULL, +#else +#define MSPM0_INTERRUPT_CALLBACK_FN(index) +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + +static int uart_mspm0_init(const struct device *dev) +{ + const struct uart_mspm0_config *config = dev->config; + struct uart_mspm0_data *data = dev->data; + const struct device *const clk_dev = DEVICE_DT_GET(DT_NODELABEL(clkmux)); + uint32_t clock_rate; + int ret; + + /* Reset power */ + DL_UART_Main_reset(config->regs); + DL_UART_Main_enablePower(config->regs); + delay_cycles(POWER_STARTUP_DELAY); + + /* Init UART pins */ + ret = pinctrl_apply_state(config->pinctrl, PINCTRL_STATE_DEFAULT); + if (ret < 0) { + return ret; + } + + /* Set UART configs */ + DL_UART_Main_setClockConfig(config->regs, + (DL_UART_Main_ClockConfig *)&data->clock_config); + DL_UART_Main_init(config->regs, (DL_UART_Main_Config *)&data->config); + + /* + * Configure baud rate by setting oversampling and baud rate divisor + * from the device tree data current-speed + */ + ret = clock_control_get_rate(clk_dev, (clock_control_subsys_t)config->clock_subsys, + &clock_rate); + + if (ret < 0) { + return ret; + } + + DL_UART_Main_configBaudRate(config->regs, clock_rate, config->current_speed); + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + config->irq_config_func(dev); +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + + /* Enable UART */ + DL_UART_Main_enable(config->regs); + + return 0; +} + +static int uart_mspm0_poll_in(const struct device *dev, unsigned char *c) +{ + const struct uart_mspm0_config *config = dev->config; + + return (DL_UART_Main_receiveDataCheck(config->regs, c)) ? 0 : -1; +} + +static void uart_mspm0_poll_out(const struct device *dev, unsigned char c) +{ + const struct uart_mspm0_config *config = dev->config; + + DL_UART_Main_transmitDataBlocking(config->regs, c); +} + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + +static int uart_mspm0_fifo_fill(const struct device *dev, const uint8_t *tx_data, int size) +{ + const struct uart_mspm0_config *config = dev->config; + + return (int)DL_UART_Main_fillTXFIFO(config->regs, (uint8_t *)tx_data, size); +} + +static int uart_mspm0_fifo_read(const struct device *dev, uint8_t *rx_data, const int size) +{ + const struct uart_mspm0_config *config = dev->config; + + return (int)DL_UART_Main_drainRXFIFO(config->regs, rx_data, size); +} + +static void uart_mspm0_irq_rx_enable(const struct device *dev) +{ + const struct uart_mspm0_config *config = dev->config; + + DL_UART_Main_enableInterrupt(config->regs, UART_MSPM0_RX_INTERRUPTS); +} + +static void uart_mspm0_irq_rx_disable(const struct device *dev) +{ + const struct uart_mspm0_config *config = dev->config; + + DL_UART_Main_disableInterrupt(config->regs, UART_MSPM0_RX_INTERRUPTS); +} + +static int uart_mspm0_irq_rx_ready(const struct device *dev) +{ + struct uart_mspm0_data *const dev_data = dev->data; + + return ((dev_data->interruptState & DL_UART_MAIN_INTERRUPT_RX) == DL_UART_MAIN_INTERRUPT_RX) + ? 1 + : 0; +} + +static void uart_mspm0_irq_tx_enable(const struct device *dev) +{ + const struct uart_mspm0_config *config = dev->config; + + DL_UART_Main_enableInterrupt(config->regs, UART_MSPM0_TX_INTERRUPTS); +} + +static void uart_mspm0_irq_tx_disable(const struct device *dev) +{ + const struct uart_mspm0_config *config = dev->config; + + DL_UART_Main_disableInterrupt(config->regs, UART_MSPM0_TX_INTERRUPTS); +} + +static int uart_mspm0_irq_tx_ready(const struct device *dev) +{ + const struct uart_mspm0_config *config = dev->config; + struct uart_mspm0_data *const dev_data = dev->data; + + return (((dev_data->interruptState & DL_UART_MAIN_INTERRUPT_TX) == + DL_UART_MAIN_INTERRUPT_TX) || + DL_UART_Main_isTXFIFOEmpty(config->regs)) + ? 1 + : 0; +} + +static int uart_mspm0_irq_tx_complete(const struct device *dev) +{ + struct uart_mspm0_data *const dev_data = dev->data; + + return ((dev_data->interruptState & DL_UART_MAIN_INTERRUPT_EOT_DONE) == + DL_UART_MAIN_INTERRUPT_EOT_DONE) + ? 1 + : 0; +} + +static int uart_mspm0_irq_is_pending(const struct device *dev) +{ + struct uart_mspm0_data *const dev_data = dev->data; + + return ((dev_data->interruptState != 0) ? 1 : 0); +} + +static int uart_mspm0_irq_update(const struct device *dev) +{ + const struct uart_mspm0_config *config = dev->config; + struct uart_mspm0_data *const dev_data = dev->data; + + dev_data->interruptState = DL_UART_Main_getEnabledInterruptStatus( + config->regs, UART_MSPM0_RX_INTERRUPTS | UART_MSPM0_TX_INTERRUPTS); + + /* + * Clear interrupts explicitly after storing all in the update. Interrupts + * can be re-set by the MIS during the ISR should they be available. + */ + + DL_UART_Main_clearInterruptStatus(config->regs, dev_data->interruptState); + + return 1; +} + +static void uart_mspm0_irq_callback_set(const struct device *dev, uart_irq_callback_user_data_t cb, + void *cb_data) +{ + struct uart_mspm0_data *const dev_data = dev->data; + + /* Set callback function and data */ + dev_data->cb = cb; + dev_data->cb_data = cb_data; +} + +/** + * @brief Interrupt service routine. + * + * This simply calls the callback function, if one exists. + * + * @param arg Argument to ISR. + */ +static void uart_mspm0_isr(const struct device *dev) +{ + const struct uart_mspm0_config *config = dev->config; + struct uart_mspm0_data *const dev_data = dev->data; + uint32_t int_status; + + /* Perform callback if defined */ + if (dev_data->cb) { + dev_data->cb(dev, dev_data->cb_data); + } else { + /* error, callback necessary in order to make progress. Clear interrupts + * temporarily. + */ + int_status = DL_UART_Main_getEnabledInterruptStatus( + config->regs, UART_MSPM0_TX_INTERRUPTS | UART_MSPM0_RX_INTERRUPTS); + DL_UART_Main_clearInterruptStatus(config->regs, int_status); + } +} + +#define MSP_UART_IRQ_REGISTER(index) \ + static void uart_mspm0_##index##_irq_register(const struct device *dev) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(index), DT_INST_IRQ(index, priority), uart_mspm0_isr, \ + DEVICE_DT_INST_GET(index), 0); \ + irq_enable(DT_INST_IRQN(index)); \ + } +#else + +#define MSP_UART_IRQ_REGISTER(index) + +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + +static const struct uart_driver_api uart_mspm0_driver_api = { + .poll_in = uart_mspm0_poll_in, + .poll_out = uart_mspm0_poll_out, +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + .fifo_fill = uart_mspm0_fifo_fill, + .fifo_read = uart_mspm0_fifo_read, + .irq_tx_enable = uart_mspm0_irq_tx_enable, + .irq_tx_disable = uart_mspm0_irq_tx_disable, + .irq_tx_ready = uart_mspm0_irq_tx_ready, + .irq_rx_enable = uart_mspm0_irq_rx_enable, + .irq_rx_disable = uart_mspm0_irq_rx_disable, + .irq_tx_complete = uart_mspm0_irq_tx_complete, + .irq_rx_ready = uart_mspm0_irq_rx_ready, + .irq_is_pending = uart_mspm0_irq_is_pending, + .irq_update = uart_mspm0_irq_update, + .irq_callback_set = uart_mspm0_irq_callback_set, +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ +}; + +#define MSPM0_UART_INIT_FN(index) \ + \ + PINCTRL_DT_INST_DEFINE(index); \ + \ + static const struct mspm0_clockSys mspm0_uart_clockSys##index = \ + MSPM0_CLOCK_SUBSYS_FN(index); \ + \ + MSP_UART_IRQ_REGISTER(index) \ + \ + static const struct uart_mspm0_config uart_mspm0_cfg_##index = { \ + .regs = (UART_Regs *)DT_INST_REG_ADDR(index), \ + .current_speed = DT_INST_PROP(index, current_speed), \ + .pinctrl = PINCTRL_DT_INST_DEV_CONFIG_GET(index), \ + .clock_subsys = &mspm0_uart_clockSys##index, \ + IF_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN, \ + (.irq_config_func = uart_mspm0_##index##_irq_register,)) }; \ + \ + static struct uart_mspm0_data uart_mspm0_data_##index = { \ + .clock_config = {.clockSel = (DT_INST_CLOCKS_CELL(index, bus) & \ + MSPM0_CLOCK_SEL_MASK), \ + .divideRatio = DL_UART_MAIN_CLOCK_DIVIDE_RATIO_1}, \ + .config = \ + { \ + .mode = DL_UART_MAIN_MODE_NORMAL, \ + .direction = DL_UART_MAIN_DIRECTION_TX_RX, \ + .flowControl = (DT_INST_PROP(index, hw_flow_control) \ + ? DL_UART_MAIN_FLOW_CONTROL_RTS_CTS \ + : DL_UART_MAIN_FLOW_CONTROL_NONE), \ + .parity = DL_UART_MAIN_PARITY_NONE, \ + .wordLength = DL_UART_MAIN_WORD_LENGTH_8_BITS, \ + .stopBits = DL_UART_MAIN_STOP_BITS_ONE, \ + }, \ + MSPM0_INTERRUPT_CALLBACK_FN(index)}; \ + \ + DEVICE_DT_INST_DEFINE(index, &uart_mspm0_init, NULL, &uart_mspm0_data_##index, \ + &uart_mspm0_cfg_##index, PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY, \ + &uart_mspm0_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(MSPM0_UART_INIT_FN) diff --git a/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g1106.dtsi b/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g1106.dtsi new file mode 100644 index 0000000000000..f86c4db3c8fc8 --- /dev/null +++ b/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g1106.dtsi @@ -0,0 +1,4 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include diff --git a/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g1107.dtsi b/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g1107.dtsi new file mode 100644 index 0000000000000..c1227ab01ef93 --- /dev/null +++ b/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g1107.dtsi @@ -0,0 +1,4 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include diff --git a/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g110x-pinctrl.dtsi b/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g110x-pinctrl.dtsi new file mode 100644 index 0000000000000..4c9e81bdacc71 --- /dev/null +++ b/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g110x-pinctrl.dtsi @@ -0,0 +1 @@ +#include diff --git a/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g1506.dtsi b/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g1506.dtsi new file mode 100644 index 0000000000000..f86c4db3c8fc8 --- /dev/null +++ b/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g1506.dtsi @@ -0,0 +1,4 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include diff --git a/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g1507.dtsi b/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g1507.dtsi new file mode 100644 index 0000000000000..c1227ab01ef93 --- /dev/null +++ b/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g1507.dtsi @@ -0,0 +1,4 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include diff --git a/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g150x-pinctrl.dtsi b/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g150x-pinctrl.dtsi new file mode 100644 index 0000000000000..4c9e81bdacc71 --- /dev/null +++ b/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g150x-pinctrl.dtsi @@ -0,0 +1 @@ +#include diff --git a/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g1x0x_g3x0x-pinctrl.dtsi b/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g1x0x_g3x0x-pinctrl.dtsi new file mode 100644 index 0000000000000..46a61f83c654d --- /dev/null +++ b/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g1x0x_g3x0x-pinctrl.dtsi @@ -0,0 +1,142 @@ +#include + +&pinctrl { + + /omit-if-no-ref/ i2c0_scl_pa1: i2c0_scl_pa1 { + pinmux = ; + input-enable; + drive-open-drain; + }; + + /omit-if-no-ref/ i2c0_sda_pa0: i2c0_sda_pa0 { + pinmux = ; + input-enable; + drive-open-drain; + }; + + /omit-if-no-ref/ i2c1_sda_pa10: i2c1_sda_pa10 { + pinmux = ; + input-enable; + drive-open-drain; + }; + + /omit-if-no-ref/ i2c1_scl_pa11: i2c1_scl_pa11 { + pinmux = ; + input-enable; + drive-open-drain; + }; + + /omit-if-no-ref/ i2c1_scl_pb2: i2c1_scl_pb2 { + pinmux = ; + input-enable; + drive-open-drain; + }; + + /omit-if-no-ref/ i2c1_sda_pb3: i2c1_sda_pb3 { + pinmux = ; + input-enable; + drive-open-drain; + }; + + /omit-if-no-ref/ i2c1_sda_pa16: i2c1_sda_pa16 { + pinmux = ; + input-enable; + drive-open-drain; + }; + + /omit-if-no-ref/ i2c1_scl_pa17: i2c1_scl_pa17 { + pinmux = ; + input-enable; + drive-open-drain; + }; + + /omit-if-no-ref/ i2c1_scl_pa29: i2c1_scl_pa29 { + pinmux = ; + input-enable; + drive-open-drain; + }; + + /omit-if-no-ref/ i2c1_sda_pa30: i2c1_sda_pa30 { + pinmux = ; + input-enable; + drive-open-drain; + }; + + /omit-if-no-ref/ i2c0_sda_pa28: i2c0_sda_pa28 { + pinmux = ; + input-enable; + drive-open-drain; + }; + + /omit-if-no-ref/ i2c0_scl_pa31: i2c0_scl_pa31 { + pinmux = ; + input-enable; + drive-open-drain; + }; + + /omit-if-no-ref/ uart0_tx_pa10: uart0_tx_pa10 { + pinmux = ; + drive-strength = <20>; + }; + + /omit-if-no-ref/ uart0_rx_pa11: uart0_rx_pa11 { + pinmux = ; + drive-strength = <20>; + input-enable; + }; + + /omit-if-no-ref/ uart0_rts_pa8: uart0_rts_pa8 { + pinmux = ; + }; + + /omit-if-no-ref/ uart0_cts_pb19: uart0_cts_pb19 { + pinmux = ; + input-enable; + }; + + /omit-if-no-ref/ spi1_sclk_pb9: spi1_sclk_pb9 { + pinmux = ; + }; + + /omit-if-no-ref/ spi1_pico_pb8: spi1_pico_pb8 { + pinmux = ; + }; + + /omit-if-no-ref/ spi1_poci_pb7: spi1_poci_pb7 { + pinmux = ; + input-enable; + }; + + /omit-if-no-ref/ spi1_cs0_pb6: spi1_cs0_pb6 { + pinmux = ; + }; + + /omit-if-no-ref/ spi1_cs1_pb17: spi1_cs1_pb17 { + pinmux = ; + }; + + /omit-if-no-ref/ adc0_pa27: adc0_pa27 { + pinmux = ; + }; + + /omit-if-no-ref/ adc0_pa26: adc0_pa26 { + pinmux = ; + }; + + /omit-if-no-ref/ adc0_pa25: adc0_pa25 { + pinmux = ; + }; + + /omit-if-no-ref/ adc0_pb24: adc0_pb24 { + pinmux = ; + }; + + /omit-if-no-ref/ adc0_pb25: adc0_pb25 { + pinmux = ; + }; + + /omit-if-no-ref/ adc1_pb19: adc1_pb19 { + pinmux = ; + }; + +}; diff --git a/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g1x0x_g3x0x.dtsi b/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g1x0x_g3x0x.dtsi new file mode 100644 index 0000000000000..fe7985dbbbcd4 --- /dev/null +++ b/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g1x0x_g3x0x.dtsi @@ -0,0 +1,130 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include +#include +#include +#include + +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-m0+"; + reg = <0>; + }; + }; + + sram0: memory@20200000 { + compatible = "mmio-sram"; + }; + + flash0: serial-flash@0 { + compatible = "serial-flash"; + }; + + sysclk: system-clock { + compatible = "fixed-clock"; + clock-frequency = ; + #clock-cells = <0>; + }; + + clkmux: clock-controller { + compatible = "ti,mspm0-clock-mux"; + mclk-div = <1>; + uclk-div = <1>; + #clock-cells = <1>; + }; + + clocks: clocks { + sysosc: sysosc { + compatible = "ti,mspm0-oscillator"; + clock-frequency = ; + #clock-cells = <0>; + }; + + lfosc: lfosc { + compatible = "fixed-clock"; + clock-frequency = <32678>; + #clock-cells = <0>; + }; + + pll: pll { + compatible = "ti,mspm0-pll"; + clocks = <&sysosc 0>; + p-div = <2>; + q-div = <5>; + clk1-div = <2>; + clk2x-div = <2>; + #clock-cells = <0>; + status = "okay"; + }; + }; + + soc { + + pinctrl: pin-controller@400a0000{ + compatible = "ti,mspm0-pinctrl"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x400a0000 0x4000>; + + gpioa: gpio@400a0000 { + compatible = "ti,mspm0-gpio"; + reg = <0x400a0000 0x2000>; + interrupts = <1 0>; + interrupt-parent = <&nvic>; + status = "disabled"; + gpio-controller; + #gpio-cells = <2>; + }; + + gpiob: gpio@400a2000 { + compatible = "ti,mspm0-gpio"; + reg = <0x400a2000 0x2000>; + interrupts = <1 0>; + interrupt-parent = <&nvic>; + status = "disabled"; + gpio-controller; + #gpio-cells = <2>; + }; + }; + + uart0: uart@40108000 { + compatible = "ti,mspm0-uart"; + reg = <0x40108000 0x2000>; + interrupts = <15 0>; + interrupt-parent = <&nvic>; + current-speed = <115200>; + clocks = <&clkmux MSPM0_CLOCK_BUS_ULPCLK>; + status = "disabled"; + }; + + uart1: uart@40100000 { + compatible = "ti,mspm0-uart"; + reg = <0x40100000 0x2000>; + interrupts = <13 0>; + interrupt-parent = <&nvic>; + current-speed = <115200>; + clocks = <&clkmux MSPM0_CLOCK_BUS_ULPCLK>; + status = "disabled"; + }; + + uart2: uart@40102000 { + compatible = "ti,mspm0-uart"; + reg = <0x40102000 0x2000>; + interrupts = <14 0>; + interrupt-parent = <&nvic>; + current-speed = <115200>; + clocks = <&clkmux MSPM0_CLOCK_BUS_ULPCLK>; + status = "disabled"; + }; + }; +}; + +&nvic { + arm,num-irq-priority-bits = <2>; +}; diff --git a/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g3106.dtsi b/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g3106.dtsi new file mode 100644 index 0000000000000..f86c4db3c8fc8 --- /dev/null +++ b/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g3106.dtsi @@ -0,0 +1,4 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include diff --git a/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g3107.dtsi b/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g3107.dtsi new file mode 100644 index 0000000000000..c1227ab01ef93 --- /dev/null +++ b/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g3107.dtsi @@ -0,0 +1,4 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include diff --git a/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g310x-pinctrl.dtsi b/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g310x-pinctrl.dtsi new file mode 100644 index 0000000000000..23f67d668a372 --- /dev/null +++ b/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g310x-pinctrl.dtsi @@ -0,0 +1,2 @@ +#include +#include diff --git a/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g3506.dtsi b/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g3506.dtsi new file mode 100644 index 0000000000000..f86c4db3c8fc8 --- /dev/null +++ b/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g3506.dtsi @@ -0,0 +1,4 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include diff --git a/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g3507.dtsi b/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g3507.dtsi new file mode 100644 index 0000000000000..c1227ab01ef93 --- /dev/null +++ b/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g3507.dtsi @@ -0,0 +1,4 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include diff --git a/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g350x-pinctrl.dtsi b/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g350x-pinctrl.dtsi new file mode 100644 index 0000000000000..23f67d668a372 --- /dev/null +++ b/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g350x-pinctrl.dtsi @@ -0,0 +1,2 @@ +#include +#include diff --git a/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g3xxx-pinctrl.dtsi b/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g3xxx-pinctrl.dtsi new file mode 100644 index 0000000000000..9127d27318cb3 --- /dev/null +++ b/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0g3xxx-pinctrl.dtsi @@ -0,0 +1,14 @@ +#include + +&pinctrl { + + can0_rx_pa13: can0_rx_pa13 { + pinmux = ; + input-enable; + }; + + can0_tx_pa12: can0_tx_pa12 { + pinmux = ; + }; + +}; diff --git a/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0gxxx6.dtsi b/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0gxxx6.dtsi new file mode 100644 index 0000000000000..0b69a7e698a9f --- /dev/null +++ b/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0gxxx6.dtsi @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include + +/ { + sram0: memory@20200000 { + reg = <0x20200000 DT_SIZE_K(32)>; + }; + + flash0: serial-flash@0 { + reg = <0x0 DT_SIZE_K(64)>; + }; +}; diff --git a/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0gxxx7.dtsi b/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0gxxx7.dtsi new file mode 100644 index 0000000000000..5cda6550db2b8 --- /dev/null +++ b/dts/arm/ti/mspm0g1x0x_g3x0x/mspm0gxxx7.dtsi @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include + +/ { + sram0: memory@20200000 { + reg = <0x20200000 DT_SIZE_K(32)>; + }; + + flash0: serial-flash@0 { + reg = <0x0 DT_SIZE_K(128)>; + }; +}; diff --git a/dts/bindings/clock/ti,mspm0-clock-mux.yaml b/dts/bindings/clock/ti,mspm0-clock-mux.yaml new file mode 100644 index 0000000000000..f8988833a96b7 --- /dev/null +++ b/dts/bindings/clock/ti,mspm0-clock-mux.yaml @@ -0,0 +1,43 @@ +# Copyright (c) 2024 Texas Instruments Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: TI MSPM0 Clock Mux + +compatible: "ti,mspm0-clock-mux" + +include: [clock-controller.yaml, base.yaml] + +properties: + "#clock-cells": + const: 1 + + uclk-div: + type: int + default: 1 + description: | + Divider from MCLK (system clock) to ULPCLK (low power clock). ULPCLK must + be less than or equal to 40 MHz. Valid value is 1 when sourced from SYSOSC + or LFOSC. Valid values are 1 or 2 when sourced from a high speed clock + (such as PLL or external clock). + + mclk-div: + type: int + default: 1 + description: | + Divider for MCLK (system clock) only when source with SYSOSC with a + frequency value of 4 MHz. Disabled otherwise. Valid values are 1-16. + + clock-source: + type: phandle + required: true + description: | + Clock Source for the system clock + + clock-frequency: + required: true + type: int + description: | + default frequency in Hz for clock output + +clock-cells: + - bus diff --git a/dts/bindings/clock/ti,mspm0-oscillator.yaml b/dts/bindings/clock/ti,mspm0-oscillator.yaml new file mode 100644 index 0000000000000..c12f9f4342d8b --- /dev/null +++ b/dts/bindings/clock/ti,mspm0-oscillator.yaml @@ -0,0 +1,13 @@ +# Copyright (c) 2024 Texas Instruments Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: TI MSPM0 Oscillator + +compatible: "ti,mspm0-oscillator" + +include: [fixed-clock.yaml] + +properties: + clock-frequency: + type: int + required: true diff --git a/dts/bindings/clock/ti,mspm0-pll.yaml b/dts/bindings/clock/ti,mspm0-pll.yaml new file mode 100644 index 0000000000000..e31768a8f8a71 --- /dev/null +++ b/dts/bindings/clock/ti,mspm0-pll.yaml @@ -0,0 +1,56 @@ +# Copyright (c) 2024 Texas Instruments Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: TI MSPM0 Phase Locked Loop + +compatible: "ti,mspm0-pll" + +include: [clock-controller.yaml, base.yaml] + +properties: + clocks: + required: true + description: | + Clock reference source + + "#clock-cells": + const: 0 + + p-div: + type: int + required: true + enum: + - 1 + - 2 + - 4 + - 8 + description: | + pdiv is the pre-divider of the output. ref_in / pdiv * qdiv = VCO + + q-div: + type: int + required: true + description: | + qdiv functions as a multiplier value for the ref_in / pdiv * qdiv = VCO + Valid Range: 2 - 128 + + clk0-div: + type: int + description: | + CLK0 PLL output is only enabled if the divider is present. Use CLK0 on + the MSPM0 to output to the MCLK, UCLK, and CPUCLK + Valid Range: 1 - 16 + + clk1-div: + type: int + description: | + CLK1 PLL output is only enabled if the divider is present. Use CLK1 on + the MSPM0 to output to the CANCLK, FCC, or output via EXCLK + Valid Range: 1 - 16 + + clk2x-div: + type: int + description: | + CLK2X PLL output is only enabled if the divider is present. Use CLK2X on + the MSPM0 to output to the MCLK, UCLK, and CPUCLK instead of CLK0 + Valid Range: 1 - 16 diff --git a/dts/bindings/gpio/ti,mspm0-gpio.yaml b/dts/bindings/gpio/ti,mspm0-gpio.yaml new file mode 100644 index 0000000000000..a08a432e4cff5 --- /dev/null +++ b/dts/bindings/gpio/ti,mspm0-gpio.yaml @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: Apache-2.0 + +description: TI MSPM0 GPIO + +compatible: "ti,mspm0-gpio" + +include: [gpio-controller.yaml, base.yaml] + +properties: + reg: + required: true + + interrupts: + required: true + + "#gpio-cells": + const: 2 + +gpio-cells: + - pin + - flags diff --git a/dts/bindings/pinctrl/ti,mspm0-pinctrl.yaml b/dts/bindings/pinctrl/ti,mspm0-pinctrl.yaml new file mode 100644 index 0000000000000..3952a8bec7f18 --- /dev/null +++ b/dts/bindings/pinctrl/ti,mspm0-pinctrl.yaml @@ -0,0 +1,119 @@ +# Copyright (c) 2024 Texas Instruments +# SPDX-License-Identifier: Apache-2.0 + +description: | + TI MSPM0 pinctrl node. + + Device pin configuration should be placed in the child nodes of this node. + Populate the 'pinmux' field with a pair consisting of a pin number and its IO + functions. + + The node has the 'pinctrl' node label set in your SoC's devicetree, + so you can modify it like this: + + &pinctrl { + /* your modifications go here */ + }; + + All device pin configurations should be placed in child nodes of the + 'pinctrl' node, as in the i2c0 example shown at the end. + + Here is a list of + supported standard pin properties: + + - bias-disable: Disable pull-up/down. + - bias-pull-down: Enable pull-down resistor. + - bias-pull-up: Enable pull-up resistor. + - drive-open-drain: Output driver is open-drain. (and is thus high-impedance) + - drive-strength: Maximum current that can be sourced from the pin. + - input-enable: enable input. + - ti,invert: enable logical inversion of a digital input or output + - ti,hysteresis: enable hysteresis control on open-drain pins + + An example for MSPM0 family, include the chip level pinctrl + DTSI file in the board level DTS: + + #include + + We want to configure the I2C pins to open drain, with pullup enabled + and input enabled. + + To change a pin's pinctrl default properties add a reference to the + pin in the board's DTS file or in the project overlay and set the + properties. + + &i2c1 { + pinctrl-0 = <&i2c1_scl_pb2_pull_up &i2c1_sda_pb3_pull_up>; + pinctrl-names = "default"; + } + + The i2c1_scl_pb2_pull_up corresponds to the following pin configuration in + the board dts file: + + &pinctrl { + i2c1_scl_pb2_pull_up: i2c1_scl_pb2_pull_up { + pinmux = ; + input-enable; + bias-pull-up; + drive-open-drain; + }; + }; + + Pin pb2 refers to the device pin name that one would see printed on the + launchpad, and the number 15 in the pinmux define refers to the PINCMx. + + These are obtained from the device-specific datasheet. + +compatible: "ti,mspm0-pinctrl" + +include: base.yaml + +properties: + reg: + required: true + +child-binding: + description: | + This binding gives a base representation of the MSPM0 + pins configuration. + + include: + - name: pincfg-node.yaml + property-allowlist: + - bias-disable + - bias-pull-down + - bias-pull-up + - drive-open-drain + - drive-open-source + - drive-strength + - input-enable + + properties: + pinmux: + required: true + type: int + description: | + MSPM0 pin's configuration (IO pin, IO function). + + drive-strength: + enum: + - 6 + - 20 + default: 6 + description: | + The drive strength controls the maximum output drive strength sunk or + sourced by an I/O pin. + low is max 6 mA (SoC default) + high is max 20 mA on high-drive capable IOs only (HDIO). + + ti,invert: + type: boolean + description: | + Enables inversion of the input or output using the internal + inversion capability of the GPIO + + ti,hysteresis: + type: boolean + description: | + Enables the hysteresis control for access to CMOS logic + (on open-drain capable pins) diff --git a/dts/bindings/serial/ti,mspm0-uart.yaml b/dts/bindings/serial/ti,mspm0-uart.yaml new file mode 100644 index 0000000000000..3fd5ba9bc69cf --- /dev/null +++ b/dts/bindings/serial/ti,mspm0-uart.yaml @@ -0,0 +1,18 @@ +description: TI MSPM0 UART + +compatible: "ti,mspm0-uart" + +include: [uart-controller.yaml, pinctrl-device.yaml, base.yaml] + +properties: + reg: + required: true + + interrupts: + required: true + + pinctrl-0: + required: true + + pinctrl-names: + required: true diff --git a/include/zephyr/drivers/clock_control/mspm0_clock_control.h b/include/zephyr/drivers/clock_control/mspm0_clock_control.h new file mode 100644 index 0000000000000..a8a69ddcde59d --- /dev/null +++ b/include/zephyr/drivers/clock_control/mspm0_clock_control.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2024 Texas Instruments Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_MSPM0_CLOCK_CONTROL +#define ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_MSPM0_CLOCK_CONTROL + +#include + +struct mspm0_clockSys { + uint32_t bus; +}; + +#define MSPM0_CLOCK_SUBSYS_FN(index) {.bus = DT_INST_CLOCKS_CELL(index, bus)} + +#endif /* ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_MSPM0_CLOCK_CONTROL */ diff --git a/include/zephyr/dt-bindings/clock/mspm0_clock.h b/include/zephyr/dt-bindings/clock/mspm0_clock.h new file mode 100644 index 0000000000000..89ead1db2abcb --- /dev/null +++ b/include/zephyr/dt-bindings/clock/mspm0_clock.h @@ -0,0 +1,33 @@ +/* + * Copyright 2024 Texas Instruments Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_MSPM0_CLOCK_H +#define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_MSPM0_CLOCK_H + +/* Clock bus references */ +#define MSPM0_CLOCK_BUS_BUSCLK + +#define MSPM0_CLOCK_BUS_LFCLK (0x02) +#define MSPM0_CLOCK_BUS_MFCLK (0x04) +#define MSPM0_CLOCK_BUS_ULPCLK (0x18) +#define MSPM0_CLOCK_BUS_MCLK (0x28) +#define MSPM0_CLOCK_BUS_MFPCLK (0x50) +#define MSPM0_CLOCK_BUS_CANCLK (0x51) + +#define MSPM0_CLOCK_SEL_MASK (0x0E) + +#define MSPM0_CLOCK_PRESCALE_DIV_1 (0) +#define MSPM0_CLOCK_PRESCALE_DIV_2 (1) +#define MSPM0_CLOCK_PRESCALE_DIV_3 (2) +#define MSPM0_CLOCK_PRESCALE_DIV_4 (3) +#define MSPM0_CLOCK_PRESCALE_DIV_5 (4) +#define MSPM0_CLOCK_PRESCALE_DIV_6 (5) +#define MSPM0_CLOCK_PRESCALE_DIV_7 (6) +#define MSPM0_CLOCK_PRESCALE_DIV_8 (7) + +#define MSPM0_PRESCALE_MASK 0x07 + +#endif diff --git a/include/zephyr/dt-bindings/pinctrl/mspm0-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/mspm0-pinctrl.h new file mode 100644 index 0000000000000..4bb582977ea82 --- /dev/null +++ b/include/zephyr/dt-bindings/pinctrl/mspm0-pinctrl.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2024 Texas Instruments + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _MSPM0_DT_BINDINGS_PINCTRL_H_ +#define _MSPM0_DT_BINDINGS_PINCTRL_H_ + +#define MSP_PORT_INDEX_BY_NAME(x) ((x == "PORTA") ? 0 : 1) + +/* creates a concatination of the correct pin function based on the CM + * and the function suffix. Will evaluate to the pin function number above. + */ + +#define MSPM0_PIN_FUNCTION_ANALOG (0x00000000) +#define MSPM0_PIN_FUNCTION_GPIO (0x00000001) +#define MSPM0_PIN_FUNCTION_2 (0x00000002) +#define MSPM0_PIN_FUNCTION_3 (0x00000003) +#define MSPM0_PIN_FUNCTION_4 (0x00000004) +#define MSPM0_PIN_FUNCTION_5 (0x00000005) +#define MSPM0_PIN_FUNCTION_6 (0x00000006) +#define MSPM0_PIN_FUNCTION_7 (0x00000007) +#define MSPM0_PIN_FUNCTION_8 (0x00000008) +#define MSPM0_PIN_FUNCTION_9 (0x00000009) +#define MSPM0_PIN_FUNCTION_10 (0x0000000A) + +#define MSP_PINMUX(pincm, function) (((pincm - 1) << 0x10) | function) + +#endif diff --git a/modules/Kconfig b/modules/Kconfig index 7e0e2b2872d10..3f720d9f2fd2a 100644 --- a/modules/Kconfig +++ b/modules/Kconfig @@ -24,6 +24,7 @@ source "modules/Kconfig.libmetal" source "modules/lvgl/Kconfig" source "modules/Kconfig.mcux" source "modules/Kconfig.microchip" +source "modules/Kconfig.mspm0" source "modules/Kconfig.nuvoton" source "modules/Kconfig.open-amp" source "modules/Kconfig.picolibc" diff --git a/modules/Kconfig.mspm0 b/modules/Kconfig.mspm0 new file mode 100644 index 0000000000000..fdf1993ab53d9 --- /dev/null +++ b/modules/Kconfig.mspm0 @@ -0,0 +1,7 @@ +# MSPM0 SDK configuration + +# Copyright (c) 2024 Texas Instruments +# SPDX-License-Identifier: Apache-2.0 + +config HAS_MSPM0_SDK + bool diff --git a/soc/ti/mspm0/CMakeLists.txt b/soc/ti/mspm0/CMakeLists.txt new file mode 100644 index 0000000000000..4e105fa57cfdc --- /dev/null +++ b/soc/ti/mspm0/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "SoC Linker Script") + +add_subdirectory(${SOC_SERIES}) diff --git a/soc/ti/mspm0/Kconfig b/soc/ti/mspm0/Kconfig new file mode 100644 index 0000000000000..0010586628a80 --- /dev/null +++ b/soc/ti/mspm0/Kconfig @@ -0,0 +1,9 @@ +# Texas Instruments MSPM0 Family +# Copyright (c) 2024 Texas Instruments +# SPDX-License-Identifier: Apache-2.0 + +if SOC_FAMILY_TI_MSPM0 + +rsource "*/Kconfig" + +endif # SOC_FAMILY_TI_MSPM0 diff --git a/soc/ti/mspm0/Kconfig.defconfig b/soc/ti/mspm0/Kconfig.defconfig new file mode 100644 index 0000000000000..586a2915dd5b3 --- /dev/null +++ b/soc/ti/mspm0/Kconfig.defconfig @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright (c) 2024 Texas Instruments + +if SOC_FAMILY_TI_MSPM0 + +rsource "*/Kconfig.defconfig" + +endif # SOC_FAMILY_TI_MSPM0 diff --git a/soc/ti/mspm0/Kconfig.soc b/soc/ti/mspm0/Kconfig.soc new file mode 100644 index 0000000000000..44098415e0d1f --- /dev/null +++ b/soc/ti/mspm0/Kconfig.soc @@ -0,0 +1,12 @@ +# Texas Instruments MSPM0 Family + +# Copyright (c) 2024 Texas Instruments +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_TI_MSPM0 + bool + +config SOC_FAMILY + default "ti_mspm0" if SOC_FAMILY_TI_MSPM0 + +rsource "*/Kconfig.soc" diff --git a/soc/ti/mspm0/mspm0g1x0x_g3x0x/CMakeLists.txt b/soc/ti/mspm0/mspm0g1x0x_g3x0x/CMakeLists.txt new file mode 100644 index 0000000000000..f1bc1e325b675 --- /dev/null +++ b/soc/ti/mspm0/mspm0g1x0x_g3x0x/CMakeLists.txt @@ -0,0 +1,22 @@ +# SPDX-License-Identifier: Apache-2.0 + +if(CONFIG_SOC_MSPM0G1106) + zephyr_compile_definitions(-D__MSPM0G1106__) +elseif(CONFIG_SOC_MSPM0G1107) + zephyr_compile_definitions(-D__MSPM0G1107__) +elseif(CONFIG_SOC_MSPM0G1506) + zephyr_compile_definitions(-D__MSPM0G1506__) +elseif(CONFIG_SOC_MSPM0G1507) + zephyr_compile_definitions(-D__MSPM0G1507__) +elseif(CONFIG_SOC_MSPM0G3106) + zephyr_compile_definitions(-D__MSPM0G3106__) +elseif(CONFIG_SOC_MSPM0G3107) + zephyr_compile_definitions(-D__MSPM0G3107__) +elseif(CONFIG_SOC_MSPM0G3506) + zephyr_compile_definitions(-D__MSPM0G3506__) +elseif(CONFIG_SOC_MSPM0G3507) + zephyr_compile_definitions(-D__MSPM0G3507__) +endif() + +zephyr_sources(soc.c) +zephyr_include_directories(.) diff --git a/soc/ti/mspm0/mspm0g1x0x_g3x0x/Kconfig b/soc/ti/mspm0/mspm0g1x0x_g3x0x/Kconfig new file mode 100644 index 0000000000000..2ddec387c9c1b --- /dev/null +++ b/soc/ti/mspm0/mspm0g1x0x_g3x0x/Kconfig @@ -0,0 +1,14 @@ +# TI MSPM0G1X0X_G3X0X + +# Copyright (c) 2024 Texas Instruments +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_MSPM0G1X0X_G3X0X + select ARM + select CPU_CORTEX_M0PLUS + select CPU_CORTEX_M_HAS_VTOR + select CPU_HAS_ARM_MPU + select CPU_CORTEX_M_HAS_SYSTICK + select BUILD_OUTPUT_HEX + select HAS_MSPM0_SDK + select CLOCK_CONTROL diff --git a/soc/ti/mspm0/mspm0g1x0x_g3x0x/Kconfig.defconfig b/soc/ti/mspm0/mspm0g1x0x_g3x0x/Kconfig.defconfig new file mode 100644 index 0000000000000..0ef3d3b946070 --- /dev/null +++ b/soc/ti/mspm0/mspm0g1x0x_g3x0x/Kconfig.defconfig @@ -0,0 +1,17 @@ +# TI MSPM0G1X0X_G3X0X + +# Copyright (c) 2024 Texas Instruments +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_MSPM0G1X0X_G3X0X + +DT_MSPM0_CLKMUX_PATH := $(dt_nodelabel_path,clkmux) +DT_MSPM0_CLKMUX_CPU_FREQ := $(dt_node_int_prop_int,$(DT_MSPM0_CLKMUX_PATH),clock-frequency) + +config NUM_IRQS + default 32 + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default "$(DT_MSPM0_CLKMUX_CPU_FREQ)" if "$(dt_nodelabel_enabled,clkmux)" + +endif # SOC_SERIES_MSPM0G1X0X_G3X0X diff --git a/soc/ti/mspm0/mspm0g1x0x_g3x0x/Kconfig.soc b/soc/ti/mspm0/mspm0g1x0x_g3x0x/Kconfig.soc new file mode 100644 index 0000000000000..ac09bc6852861 --- /dev/null +++ b/soc/ti/mspm0/mspm0g1x0x_g3x0x/Kconfig.soc @@ -0,0 +1,53 @@ +# Copyright (c) 2024 Texas Instruments +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_MSPM0G1X0X_G3X0X + bool + select SOC_FAMILY_TI_MSPM0 + help + Enable support for TI MSPM0G1X0X_G3X0X SoCs + +config SOC_MSPM0G1106 + bool + select SOC_SERIES_MSPM0G1X0X_G3X0X + +config SOC_MSPM0G1107 + bool + select SOC_SERIES_MSPM0G1X0X_G3X0X + +config SOC_MSPM0G1506 + bool + select SOC_SERIES_MSPM0G1X0X_G3X0X + +config SOC_MSPM0G1507 + bool + select SOC_SERIES_MSPM0G1X0X_G3X0X + +config SOC_MSPM0G3106 + bool + select SOC_SERIES_MSPM0G1X0X_G3X0X + +config SOC_MSPM0G3107 + bool + select SOC_SERIES_MSPM0G1X0X_G3X0X + +config SOC_MSPM0G3506 + bool + select SOC_SERIES_MSPM0G1X0X_G3X0X + +config SOC_MSPM0G3507 + bool + select SOC_SERIES_MSPM0G1X0X_G3X0X + +config SOC_SERIES + default "mspm0g1x0x_g3x0x" if SOC_SERIES_MSPM0G1X0X_G3X0X + +config SOC + default "mspm0g1106" if SOC_MSPM0G1106 + default "mspm0g1107" if SOC_MSPM0G1107 + default "mspm0g1506" if SOC_MSPM0G1506 + default "mspm0g1507" if SOC_MSPM0G1507 + default "mspm0g3106" if SOC_MSPM0G3106 + default "mspm0g3107" if SOC_MSPM0G3107 + default "mspm0g3506" if SOC_MSPM0G3506 + default "mspm0g3507" if SOC_MSPM0G3507 diff --git a/soc/ti/mspm0/mspm0g1x0x_g3x0x/pinctrl_soc.h b/soc/ti/mspm0/mspm0g1x0x_g3x0x/pinctrl_soc.h new file mode 100644 index 0000000000000..207ccc88f5e19 --- /dev/null +++ b/soc/ti/mspm0/mspm0g1x0x_g3x0x/pinctrl_soc.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) (2024) Texas Instruments + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef SOC_TI_MSPM0_M0G1X0X_G3X0X_PINCTRL_SOC_H_ +#define SOC_TI_MSPM0_M0G1X0X_G3X0X_PINCTRL_SOC_H_ + +#include +#include +#include + +#define MSP_GPIO_RESISTOR_PULL_DOWN (16) +#define MSP_GPIO_RESISTOR_PULL_UP (17) +#define MSP_GPIO_INPUT_ENABLE (18) +#define MSP_GPIO_HIGH_DRIVE (20) +#define MSP_GPIO_HYSTERESIS_ENABLED (19) +#define MSP_GPIO_OPEN_DRAIN_OUTPUT (25) +#define MSP_GPIO_INVERSION_ENABLED (26) + +#define MSP_PINMUX_INIT(node_id) DT_PROP(node_id, pinmux) + +#define MSP_PIN_CONTROL_IOMUX_INIT(node_id) \ + ((DT_PROP(node_id, bias_pull_up) << MSP_GPIO_RESISTOR_PULL_UP) | \ + (DT_PROP(node_id, bias_pull_down) << MSP_GPIO_RESISTOR_PULL_DOWN) | \ + (DT_PROP(node_id, drive_open_drain) << MSP_GPIO_OPEN_DRAIN_OUTPUT) | \ + (DT_ENUM_IDX(node_id, drive_strength) << MSP_GPIO_HIGH_DRIVE) | \ + (DT_PROP(node_id, ti_hysteresis) << MSP_GPIO_HYSTERESIS_ENABLED) | \ + (DT_PROP(node_id, ti_invert) << MSP_GPIO_INVERSION_ENABLED) | \ + (DT_PROP(node_id, input_enable) << MSP_GPIO_INPUT_ENABLE)) + +typedef struct pinctrl_soc_pin { + /* PINCM register index and pin function */ + uint32_t pinmux; + /* IOMUX Pin Control Management (direction, inversion, pullups) */ + uint32_t iomux; +} pinctrl_soc_pin_t; + +#define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) \ + {.pinmux = MSP_PINMUX_INIT(DT_PROP_BY_IDX(node_id, prop, idx)), \ + .iomux = MSP_PIN_CONTROL_IOMUX_INIT(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 /* SOC_TI_MSPM0_M0G1X0X_G3X0X_PINCTRL_SOC_H_ */ diff --git a/soc/ti/mspm0/mspm0g1x0x_g3x0x/soc.c b/soc/ti/mspm0/mspm0g1x0x_g3x0x/soc.c new file mode 100644 index 0000000000000..ed7b8c0d120a7 --- /dev/null +++ b/soc/ti/mspm0/mspm0g1x0x_g3x0x/soc.c @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2024 Texas Instruments + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +void soc_early_init_hook(void) +{ + /* Reset and enable GPIO banks */ + DL_GPIO_reset(GPIOA); + DL_GPIO_reset(GPIOB); + + DL_GPIO_enablePower(GPIOA); + DL_GPIO_enablePower(GPIOB); + + /* Allow delay time to settle */ + delay_cycles(POWER_STARTUP_DELAY); + + /* Low Power Mode is configured to be SLEEP0 */ + DL_SYSCTL_setBORThreshold(DL_SYSCTL_BOR_THRESHOLD_LEVEL_0); +} diff --git a/soc/ti/mspm0/mspm0g1x0x_g3x0x/soc.h b/soc/ti/mspm0/mspm0g1x0x_g3x0x/soc.h new file mode 100644 index 0000000000000..326f97ee54359 --- /dev/null +++ b/soc/ti/mspm0/mspm0g1x0x_g3x0x/soc.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2024 Texas Instruments + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef SOC_TI_MSPM0_SOC_H_ +#define SOC_TI_MSPM0_SOC_H_ + +#define SYSCONFIG_WEAK __attribute__((weak)) + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Per TRM Section 2.2.7 Peripheral Power Enable Control: + * + * After setting the ENABLE | KEY bits in the PWREN Register to enable a + * peripheral, wait at least 4 ULPCLK clock cycles before accessing the rest of + * the peripheral's memory-mapped registers. The 4 cycles allow for the bus + * isolation signals at the peripheral's bus interface to update. + * + * ULPCLK will either be equivalent or half of the main MCLK and CPUCLK, + * yielding the delay time of 8 cycles + */ +#define POWER_STARTUP_DELAY (8) + +#ifdef __cplusplus +} +#endif + +#endif /* SOC_TI_MSPM0_SOC_H_ */ diff --git a/soc/ti/mspm0/soc.yml b/soc/ti/mspm0/soc.yml new file mode 100644 index 0000000000000..d907eca563b41 --- /dev/null +++ b/soc/ti/mspm0/soc.yml @@ -0,0 +1,13 @@ +family: +- name: ti_mspm0 + series: + - name: mspm0g1x0x_g3x0x + socs: + - name: mspm0g1106 + - name: mspm0g1107 + - name: mspm0g1506 + - name: mspm0g1507 + - name: mspm0g3106 + - name: mspm0g3107 + - name: mspm0g3506 + - name: mspm0g3507 diff --git a/west.yml b/west.yml index deecf69acfe98..9551fe736fd96 100644 --- a/west.yml +++ b/west.yml @@ -244,7 +244,7 @@ manifest: groups: - hal - name: hal_ti - revision: 2e7b95ad079e9f636884eedc6853e6ad98b85f65 + revision: pull/51/head path: modules/hal/ti groups: - hal