From f7ef0826f54aaec9ee2c555a68acb045ea43ce86 Mon Sep 17 00:00:00 2001 From: Santhosh Charles Date: Tue, 30 Sep 2025 14:11:34 +0530 Subject: [PATCH 1/4] dts: bindings: can: Add DT bindings for TI MSPM0 G-Series MCAN module Add devicetree bindings for the TI MSPM0 G-Series MCAN module. Signed-off-by: Santhosh Charles Signed-off-by: Jackson Farley --- dts/bindings/can/ti,mspm0-canfd.yaml | 39 ++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 dts/bindings/can/ti,mspm0-canfd.yaml diff --git a/dts/bindings/can/ti,mspm0-canfd.yaml b/dts/bindings/can/ti,mspm0-canfd.yaml new file mode 100644 index 0000000000000..51b4b74df4dc5 --- /dev/null +++ b/dts/bindings/can/ti,mspm0-canfd.yaml @@ -0,0 +1,39 @@ +# Copyright (c) 2024 Texas Instruments +# SPDX-License-Identifier: Apache-2.0 + +description: TI MSPM0 CANFD + +compatible: "ti,mspm0-canfd" + +include: ["bosch,m_can-base.yaml", "pinctrl-device.yaml"] + +properties: + reg: + required: true + + interrupts: + required: true + + clocks: + required: true + + ti,canclk-source: + type: int + required: false + enum: + - 0 + - 1 + default: 1 + description: | + Selects the source clock for the CANCLK (MCAN_FCLK). + 0: HFCLK + 1: PLLCLK1 + If not specified, defaults to PLLCLK1 (1). + + ti,divider: + type: int + required: true + description: | + Clock divide ratio specification. Enables configuring clock divide + settings for the MCAN functional clock input to the MCAN-SS. + Divide by 1 is the default unless the property is configured. From 9b2cd75f1c8c18e6fbc2dc4c5b480afa6071e592 Mon Sep 17 00:00:00 2001 From: Santhosh Charles Date: Tue, 30 Sep 2025 15:38:02 +0530 Subject: [PATCH 2/4] drivers: can: Add driver support for TI MSPM0 G-Series MCAN module Add driver support for MCAN module on TI's MSPM0 G-Series MCUs. The MCAN module supports both classic CAN and CAN FD protocols. Signed-off-by: Santhosh Charles Signed-off-by: Jackson Farley Signed-off-by: Tomasz Bursztyka --- drivers/can/CMakeLists.txt | 1 + drivers/can/Kconfig | 1 + drivers/can/Kconfig.mspm0 | 31 ++++ drivers/can/can_mspm0_canfd.c | 276 ++++++++++++++++++++++++++++++++++ modules/Kconfig.mspm0 | 3 + 5 files changed, 312 insertions(+) create mode 100644 drivers/can/Kconfig.mspm0 create mode 100644 drivers/can/can_mspm0_canfd.c diff --git a/drivers/can/CMakeLists.txt b/drivers/can/CMakeLists.txt index 350136edd5893..1dab801a91a4a 100644 --- a/drivers/can/CMakeLists.txt +++ b/drivers/can/CMakeLists.txt @@ -23,6 +23,7 @@ zephyr_library_sources_ifdef(CONFIG_CAN_MCP2515 can_mcp2515.c) zephyr_library_sources_ifdef(CONFIG_CAN_MCP251XFD can_mcp251xfd.c) zephyr_library_sources_ifdef(CONFIG_CAN_MCUX_FLEXCAN can_mcux_flexcan.c) zephyr_library_sources_ifdef(CONFIG_CAN_MCUX_MCAN can_mcux_mcan.c) +zephyr_library_sources_ifdef(CONFIG_CAN_MSPM0_CANFD can_mspm0_canfd.c) zephyr_library_sources_ifdef(CONFIG_CAN_NRF can_nrf.c) zephyr_library_sources_ifdef(CONFIG_CAN_NUMAKER can_numaker.c) zephyr_library_sources_ifdef(CONFIG_CAN_NXP_S32_CANXL can_nxp_s32_canxl.c) diff --git a/drivers/can/Kconfig b/drivers/can/Kconfig index ca157669d60ff..aa5d74ebb9cec 100644 --- a/drivers/can/Kconfig +++ b/drivers/can/Kconfig @@ -140,6 +140,7 @@ source "drivers/can/Kconfig.nrf" source "drivers/can/Kconfig.renesas_ra" source "drivers/can/Kconfig.renesas_rz" source "drivers/can/Kconfig.max32" +source "drivers/can/Kconfig.mspm0" source "drivers/can/transceiver/Kconfig" diff --git a/drivers/can/Kconfig.mspm0 b/drivers/can/Kconfig.mspm0 new file mode 100644 index 0000000000000..c70eb573ea330 --- /dev/null +++ b/drivers/can/Kconfig.mspm0 @@ -0,0 +1,31 @@ +# Copyright (c) 2024 Texas Instruments +# SPDX-License-Identifier: Apache-2.0 + +config CAN_MSPM0_CANFD + bool "MSPM0 CANFD driver" + default y + depends on DT_HAS_TI_MSPM0_CANFD_ENABLED + select CAN_MCAN + select USE_MSPM0_DL_MCAN + help + Enable support for CANFD on the TI MSPM0 series. + +if CAN_MSPM0_CANFD + +config CAN_MAX_STD_ID_FILTER + int "Maximum number of standard (11-bit) ID filters" + default 128 + range 0 128 + help + Defines the maximum number of filters with standard ID (11-bit) + that can be added by the application. + +config CAN_MAX_EXT_ID_FILTER + int "Maximum number of extended (29-bit) ID filters" + default 64 + range 0 64 + help + Defines the maximum number of filters with extended ID (29-bit) + that can be added by the application. + +endif # CAN_MSPM0G3XXX_CANFD diff --git a/drivers/can/can_mspm0_canfd.c b/drivers/can/can_mspm0_canfd.c new file mode 100644 index 0000000000000..4ce76dff71f3a --- /dev/null +++ b/drivers/can/can_mspm0_canfd.c @@ -0,0 +1,276 @@ +/* + * Copyright (c) 2024 Texas Instruments + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +/* Driverlib includes */ +#include + +LOG_MODULE_REGISTER(can_mspm0_canfd, CONFIG_CAN_LOG_LEVEL); + +#define DT_DRV_COMPAT ti_mspm0_canfd + +#define CAN_MSPM0_CLK_SRC_PLLCLK1 1 + +struct can_mspm0_canfd_config { + uint32_t ti_canfd_base; + const struct mspm0_sys_clock *clock_subsys; + + const DL_MCAN_ClockConfig clock_cfg; + mm_reg_t mcan_base; + mem_addr_t mram; + + void (*irq_cfg_func)(void); + const struct pinctrl_dev_config *pinctrl; +}; + +static int can_mspm0_canfd_read_reg(const struct device *dev, uint16_t reg, uint32_t *val) +{ + const struct can_mcan_config *mcan_config = dev->config; + const struct can_mspm0_canfd_config *config = mcan_config->custom; + + return can_mcan_sys_read_reg(config->mcan_base, reg, val); +} + +static int can_mspm0_canfd_write_reg(const struct device *dev, uint16_t reg, uint32_t val) +{ + const struct can_mcan_config *mcan_config = dev->config; + const struct can_mspm0_canfd_config *config = mcan_config->custom; + + return can_mcan_sys_write_reg(config->mcan_base, reg, val); +} + +static int can_mspm0_canfd_read_mram(const struct device *dev, uint16_t offset, void *dst, + size_t len) +{ + const struct can_mcan_config *mcan_config = dev->config; + const struct can_mspm0_canfd_config *config = mcan_config->custom; + + return can_mcan_sys_read_mram(config->mram, offset, dst, len); +} + +static int can_mspm0_canfd_write_mram(const struct device *dev, uint16_t offset, const void *src, + size_t len) +{ + const struct can_mcan_config *mcan_config = dev->config; + const struct can_mspm0_canfd_config *config = mcan_config->custom; + + return can_mcan_sys_write_mram(config->mram, offset, src, len); +} + +static int can_mspm0_canfd_clear_mram(const struct device *dev, uint16_t offset, size_t len) +{ + const struct can_mcan_config *mcan_config = dev->config; + const struct can_mspm0_canfd_config *config = mcan_config->custom; + + return can_mcan_sys_clear_mram(config->mram, offset, len); +} + +static int can_mspm0_canfd_get_core_clock(const struct device *dev, uint32_t *rate) +{ + const struct can_mcan_config *mcan_config = dev->config; + const struct can_mspm0_canfd_config *config = mcan_config->custom; + const struct device *clk_dev = DEVICE_DT_GET(DT_NODELABEL(ckm)); + uint32_t clock_rate; + int ret; + + ret = clock_control_get_rate(clk_dev, (struct mspm0_sys_clock *)config->clock_subsys, + &clock_rate); + if (ret < 0) { + return ret; + } + + if (config->clock_cfg.divider != DL_MCAN_FCLK_DIV_1) { + *rate = clock_rate / (config->clock_cfg.divider >> MCAN_CLKDIV_RATIO_OFS); + } else { + *rate = clock_rate; + } + + return ret; +} + +static int can_mspm0_canfd_clock_enable(const struct device *dev) +{ + const struct can_mcan_config *mcan_cfg = dev->config; + const struct can_mspm0_canfd_config *config = mcan_cfg->custom; + DL_MCAN_RevisionId revid_MCAN0; + + DL_MCAN_setClockConfig((MCAN_Regs *)config->ti_canfd_base, + (DL_MCAN_ClockConfig *)&config->clock_cfg); + + /* Get MCANSS Revision ID. */ + do { + DL_MCAN_enableModuleClock((MCAN_Regs *)config->ti_canfd_base); + DL_MCAN_getRevisionId((MCAN_Regs *)config->ti_canfd_base, &revid_MCAN0); + } while ((uint32_t)revid_MCAN0.scheme == 0x00); + + return 0; +} + +static int can_mspm0_canfd_init(const struct device *dev) +{ + const struct can_mcan_config *mcan_cfg = dev->config; + const struct can_mspm0_canfd_config *config = mcan_cfg->custom; + int ret = 0; + + LOG_DBG("Initializing %s", dev->name); + + /* Init GPIO */ + ret = pinctrl_apply_state(config->pinctrl, PINCTRL_STATE_DEFAULT); + if (ret < 0) { + LOG_ERR("MSPM0 CAN pinctrl error (%d)", ret); + return ret; + } + + /* Init power */ + DL_MCAN_reset((MCAN_Regs *)config->ti_canfd_base); + DL_MCAN_enablePower((MCAN_Regs *)config->ti_canfd_base); + delay_cycles(CONFIG_MSPM0_PERIPH_STARTUP_DELAY); + + can_mspm0_canfd_clock_enable(dev); + + while (false == DL_MCAN_isMemInitDone((MCAN_Regs *)config->ti_canfd_base)) { + /* Wait for Memory initialization to be completed. */ + } + + ret = can_mcan_configure_mram(dev, 0x8000, config->mram); + if (ret != 0) { + return ret; + } + + ret = can_mcan_init(dev); + if (ret != 0) { + return ret; + } + + DL_MCAN_clearInterruptStatus((MCAN_Regs *)config->ti_canfd_base, + (DL_MCAN_MSP_INTERRUPT_LINE0 | DL_MCAN_MSP_INTERRUPT_LINE1)); + DL_MCAN_enableInterrupt((MCAN_Regs *)config->ti_canfd_base, + (DL_MCAN_MSP_INTERRUPT_LINE0 | DL_MCAN_MSP_INTERRUPT_LINE1)); + config->irq_cfg_func(); + + return ret; +} + +static void can_mspm0_canfd_isr(const struct device *dev) +{ + const struct can_mcan_config *mcan_cfg = dev->config; + const struct can_mspm0_canfd_config *config = mcan_cfg->custom; + + switch (DL_MCAN_getPendingInterrupt((MCAN_Regs *)config->ti_canfd_base)) { + case DL_MCAN_IIDX_LINE0: + can_mcan_line_0_isr(dev); + ((MCAN_Regs *)config->ti_canfd_base) + ->MCANSS.TI_WRAPPER.PROCESSORS.MCANSS_REGS.MCANSS_EOI = + DL_MCAN_INTR_SRC_MCAN_LINE_0; + break; + case DL_MCAN_IIDX_LINE1: + can_mcan_line_1_isr(dev); + ((MCAN_Regs *)config->ti_canfd_base) + ->MCANSS.TI_WRAPPER.PROCESSORS.MCANSS_REGS.MCANSS_EOI = + DL_MCAN_INTR_SRC_MCAN_LINE_1; + break; + default: + break; + } +} + +static const struct can_driver_api can_mspm0_canfd_driver_api = { + .get_capabilities = can_mcan_get_capabilities, + .start = can_mcan_start, + .stop = can_mcan_stop, + .set_mode = can_mcan_set_mode, + .set_timing = can_mcan_set_timing, + .send = can_mcan_send, + .add_rx_filter = can_mcan_add_rx_filter, + .remove_rx_filter = can_mcan_remove_rx_filter, + .get_state = can_mcan_get_state, +#ifdef CONFIG_CAN_MANUAL_RECOVERY_MODE + .recover = can_mcan_recover, +#endif /* CONFIG_CAN_MANUAL_RECOVERY_MODE */ + .get_core_clock = can_mspm0_canfd_get_core_clock, + .get_max_filters = can_mcan_get_max_filters, + .set_state_change_callback = can_mcan_set_state_change_callback, + .timing_min = CAN_MCAN_TIMING_MIN_INITIALIZER, + .timing_max = CAN_MCAN_TIMING_MAX_INITIALIZER, +#ifdef CONFIG_CAN_FD_MODE + .set_timing_data = can_mcan_set_timing_data, + .timing_data_min = CAN_MCAN_TIMING_DATA_MIN_INITIALIZER, + .timing_data_max = CAN_MCAN_TIMING_DATA_MAX_INITIALIZER, +#endif /* CONFIG_CAN_FD_MODE */ +}; + +static const struct can_mcan_ops can_mspm0_canfd_ops = { + .read_reg = can_mspm0_canfd_read_reg, + .write_reg = can_mspm0_canfd_write_reg, + .read_mram = can_mspm0_canfd_read_mram, + .write_mram = can_mspm0_canfd_write_mram, + .clear_mram = can_mspm0_canfd_clear_mram, +}; + +#define can_mspm0_canfd_IRQ_CFG_FUNCTION(index) \ + static void config_can_##index(void) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(index), DT_INST_IRQ(index, priority), \ + can_mspm0_canfd_isr, DEVICE_DT_INST_GET(index), 0); \ + irq_enable(DT_INST_IRQN(index)); \ + } + +#define can_mspm0_canfd_CFG_INST(index) \ + BUILD_ASSERT(CAN_MCAN_DT_INST_MRAM_ELEMENTS_SIZE(index) <= \ + CAN_MCAN_DT_INST_MRAM_SIZE(index), \ + "Insufficient Message RAM size"); \ + \ + PINCTRL_DT_INST_DEFINE(index); \ + CAN_MCAN_CALLBACKS_DEFINE(can_mspm0_canfd_cbs_##index, \ + CAN_MCAN_DT_INST_MRAM_TX_BUFFER_ELEMENTS(index), \ + CONFIG_CAN_MAX_STD_ID_FILTER, CONFIG_CAN_MAX_EXT_ID_FILTER); \ + \ + static const struct mspm0_sys_clock mspm0_can_sys_clock##index = \ + MSPM0_CLOCK_SUBSYS_FN(index); \ + \ + static const struct can_mspm0_canfd_config can_mspm0_canfd_cfg_##index = { \ + .ti_canfd_base = DT_REG_ADDR_BY_NAME(DT_DRV_INST(index), ti_canfd), \ + .clock_subsys = &mspm0_can_sys_clock##index, \ + .clock_cfg = \ + { \ + .clockSel = DT_PROP_OR(DT_DRV_INST(index), \ + ti_canclk_source, CAN_MSPM0_CLK_SRC_PLLCLK1) == \ + CAN_MSPM0_CLK_SRC_PLLCLK1 ? DL_MCAN_FCLK_SYSPLLCLK1 \ + : DL_MCAN_FCLK_HFCLK, \ + .divider = DT_PROP(DT_DRV_INST(index), ti_divider), \ + }, \ + .mcan_base = CAN_MCAN_DT_INST_MCAN_ADDR(index), \ + .mram = CAN_MCAN_DT_INST_MRAM_ADDR(index), \ + .irq_cfg_func = config_can_##index, \ + .pinctrl = PINCTRL_DT_INST_DEV_CONFIG_GET(index), \ + }; \ + \ + static const struct can_mcan_config can_mcan_cfg_##index = CAN_MCAN_DT_CONFIG_INST_GET( \ + index, &can_mspm0_canfd_cfg_##index, &can_mspm0_canfd_ops, \ + &can_mspm0_canfd_cbs_##index); + +#define can_mspm0_canfd_DATA_INST(index) \ + static struct can_mcan_data can_mcan_data_##index = CAN_MCAN_DATA_INITIALIZER(NULL); + +#define can_mspm0_canfd_DEVICE_INST(index) \ + CAN_DEVICE_DT_INST_DEFINE(index, can_mspm0_canfd_init, NULL, &can_mcan_data_##index, \ + &can_mcan_cfg_##index, POST_KERNEL, CONFIG_CAN_INIT_PRIORITY, \ + &can_mspm0_canfd_driver_api); + +#define can_mspm0_canfd_INST(index) \ + can_mspm0_canfd_IRQ_CFG_FUNCTION(index) can_mspm0_canfd_CFG_INST(index) \ + can_mspm0_canfd_DATA_INST(index) can_mspm0_canfd_DEVICE_INST(index) + +DT_INST_FOREACH_STATUS_OKAY(can_mspm0_canfd_INST) diff --git a/modules/Kconfig.mspm0 b/modules/Kconfig.mspm0 index 7125ff4919672..4aeaa220176b5 100644 --- a/modules/Kconfig.mspm0 +++ b/modules/Kconfig.mspm0 @@ -14,3 +14,6 @@ config USE_MSPM0_DL_UART config USE_MSPM0_DL_TIMER bool + +config USE_MSPM0_DL_MCAN + bool From e26a7bc121f6d101ee81ff0ae8e2da41f2f76ec3 Mon Sep 17 00:00:00 2001 From: Santhosh Charles Date: Tue, 23 Sep 2025 14:04:19 +0530 Subject: [PATCH 3/4] dts: arm: ti: mspm0: g: Add CAN-FD support for TI MSPM0 G-Series Add CAN-FD devicetree nodes for MSPM0 G-Series SoCs that include the peripheral: mspm0g310x, mspm0g350x and mspm0gx51x. Signed-off-by: Santhosh Charles Signed-off-by: Tomasz Bursztyka --- dts/arm/ti/mspm0/g/mspm0g310x.dtsi | 26 ++++++++++++++++++ dts/arm/ti/mspm0/g/mspm0g350x.dtsi | 26 ++++++++++++++++++ dts/arm/ti/mspm0/g/mspm0gx51x.dtsi | 44 ++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+) diff --git a/dts/arm/ti/mspm0/g/mspm0g310x.dtsi b/dts/arm/ti/mspm0/g/mspm0g310x.dtsi index 7662a074329d6..5d9c6272a4ef0 100644 --- a/dts/arm/ti/mspm0/g/mspm0g310x.dtsi +++ b/dts/arm/ti/mspm0/g/mspm0g310x.dtsi @@ -1,3 +1,29 @@ /* SPDX-License-Identifier: Apache-2.0 */ #include + +/ { + soc { + canfd0: can@40508000 { + compatible = "ti,mspm0-canfd"; + reg = <0x40508000 0x8000>, <0x4050F000 0x1000>, <0x40508000 0x400>; + reg-names = "ti_canfd", "m_can", "message_ram"; + interrupts = <6 0>; + clocks = <&ckm MSPM0_CLOCK_CANCLK>; + ti,divider = <0>; + bosch,mram-cfg = <0x0 20 8 3 3 0 3 3>; + /* + * # 20 11-bit filter elements = 20x4 = 80B + * # 8 29-bit filter elements = 8x8 = 64B + * # 3 RX FIFO0 elements = 3x72 = 216B + * # 3 RX FIFO1 elements = 3x72 = 216B + * # 0 RX buffer elemets = 0x72 = 0B + * # 3 TX FIFO elements = 3x8 = 24B + * # 3 TX Buffer elements = 3x72 = 216B + * # Total RAM = 816B + */ + sample-point = <875>; + status = "disabled"; + }; + }; +}; diff --git a/dts/arm/ti/mspm0/g/mspm0g350x.dtsi b/dts/arm/ti/mspm0/g/mspm0g350x.dtsi index 7662a074329d6..5d9c6272a4ef0 100644 --- a/dts/arm/ti/mspm0/g/mspm0g350x.dtsi +++ b/dts/arm/ti/mspm0/g/mspm0g350x.dtsi @@ -1,3 +1,29 @@ /* SPDX-License-Identifier: Apache-2.0 */ #include + +/ { + soc { + canfd0: can@40508000 { + compatible = "ti,mspm0-canfd"; + reg = <0x40508000 0x8000>, <0x4050F000 0x1000>, <0x40508000 0x400>; + reg-names = "ti_canfd", "m_can", "message_ram"; + interrupts = <6 0>; + clocks = <&ckm MSPM0_CLOCK_CANCLK>; + ti,divider = <0>; + bosch,mram-cfg = <0x0 20 8 3 3 0 3 3>; + /* + * # 20 11-bit filter elements = 20x4 = 80B + * # 8 29-bit filter elements = 8x8 = 64B + * # 3 RX FIFO0 elements = 3x72 = 216B + * # 3 RX FIFO1 elements = 3x72 = 216B + * # 0 RX buffer elemets = 0x72 = 0B + * # 3 TX FIFO elements = 3x8 = 24B + * # 3 TX Buffer elements = 3x72 = 216B + * # Total RAM = 816B + */ + sample-point = <875>; + status = "disabled"; + }; + }; +}; diff --git a/dts/arm/ti/mspm0/g/mspm0gx51x.dtsi b/dts/arm/ti/mspm0/g/mspm0gx51x.dtsi index 9095207243da1..69ad187ed9681 100644 --- a/dts/arm/ti/mspm0/g/mspm0gx51x.dtsi +++ b/dts/arm/ti/mspm0/g/mspm0gx51x.dtsi @@ -60,5 +60,49 @@ status = "disabled"; }; }; + + canfd0: can@40508000 { + compatible = "ti,mspm0-canfd"; + reg = <0x40508000 0x8000>, <0x4050F000 0x1000>, <0x40508000 0x400>; + reg-names = "ti_canfd", "m_can", "message_ram"; + interrupts = <6 0>; + clocks = <&ckm MSPM0_CLOCK_CANCLK>; + ti,divider = <0>; + bosch,mram-cfg = <0x0 20 8 3 3 0 3 3>; + /* + * # 20 11-bit filter elements = 20x4 = 80B + * # 8 29-bit filter elements = 8x8 = 64B + * # 3 RX FIFO0 elements = 3x72 = 216B + * # 3 RX FIFO1 elements = 3x72 = 216B + * # 0 RX buffer elemets = 0x72 = 0B + * # 3 TX FIFO elements = 3x8 = 24B + * # 3 TX Buffer elements = 3x72 = 216B + * # Total RAM = 816B + */ + sample-point = <875>; + status = "disabled"; + }; + + canfd1: can@40510000 { + compatible = "ti,mspm0-canfd"; + reg = <0x40510000 0x8000>, <0x40510000 0x1000>, <0x40510000 0x400>; + reg-names = "ti_canfd", "m_can", "message_ram"; + interrupts = <12 0>; + clocks = <&ckm MSPM0_CLOCK_CANCLK>; + ti,divider = <0>; + bosch,mram-cfg = <0x0 20 8 3 3 0 3 3>; + /* + * # 20 11-bit filter elements = 20x4 = 80B + * # 8 29-bit filter elements = 8x8 = 64B + * # 3 RX FIFO0 elements = 3x72 = 216B + * # 3 RX FIFO1 elements = 3x72 = 216B + * # 0 RX buffer elemets = 0x72 = 0B + * # 3 TX FIFO elements = 3x8 = 24B + * # 3 TX Buffer elements = 3x72 = 216B + * # Total RAM = 816B + */ + sample-point = <875>; + status = "disabled"; + }; }; }; From 0b687bad8592dfba46c4dee2a9e1d49d87dc73b0 Mon Sep 17 00:00:00 2001 From: Santhosh Charles Date: Thu, 25 Sep 2025 19:23:28 +0530 Subject: [PATCH 4/4] drivers: clock_control: mspm0: Add CANCLK source support Add support for the CANCLK source for MSPM0. `mspm0_canclk_cfg` config struct is used to provide CAN-FD clock frequency selection. - Select HFCLK (HFXT) freq when `ti,canclk-source = 0` - ELse fall back to SYSOSC frequency. Signed-off-by: Santhosh Charles --- drivers/clock_control/clock_control_mspm0.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/clock_control/clock_control_mspm0.c b/drivers/clock_control/clock_control_mspm0.c index a03d10b6d9349..a153af1e2ac22 100644 --- a/drivers/clock_control/clock_control_mspm0.c +++ b/drivers/clock_control/clock_control_mspm0.c @@ -57,6 +57,14 @@ static struct mspm0_clk_cfg mspm0_lfclk_cfg = { .clk_freq = DT_PROP(DT_NODELABEL(lfclk), clock_frequency), }; +static struct mspm0_clk_cfg mspm0_canclk_cfg = { +#if MSPM0_HFCLK_ENABLED && (DT_PROP(canfd0, ti_canclk_source) == 0) + .clk_freq = DT_PROP(DT_NODELABEL(hfxt), clock_frequency), +#else + .clk_freq = DT_PROP(DT_NODELABEL(sysosc), clock_frequency), +#endif +}; + static struct mspm0_clk_cfg mspm0_ulpclk_cfg = { .clk_freq = DT_PROP(DT_NODELABEL(ulpclk), clock_frequency), .clk_div = MSPM0_ULPCLK_DIV, @@ -141,8 +149,11 @@ static int clock_mspm0_get_rate(const struct device *dev, break; #endif - case MSPM0_CLOCK_MFCLK: case MSPM0_CLOCK_CANCLK: + *rate = mspm0_canclk_cfg.clk_freq; + break; + + case MSPM0_CLOCK_MFCLK: default: return -ENOTSUP; }