diff --git a/boards/nxp/mr_canhubk3/doc/index.rst b/boards/nxp/mr_canhubk3/doc/index.rst index 905eba1d1d383..2939bed3d7d34 100644 --- a/boards/nxp/mr_canhubk3/doc/index.rst +++ b/boards/nxp/mr_canhubk3/doc/index.rst @@ -143,12 +143,9 @@ flexcan5 | PTC11 | PTC11_CAN0_RX P22/P23 and support maximum 32 message buffers for concurrent active instances with 8 bytes payload. We need to pay attention to configuration options: - 1. :kconfig:option:`CONFIG_CAN_MAX_MB` must be less or equal than the + 1. :kconfig:option:`CONFIG_CAN_MAX_FILTER` must be less or equal than the maximum number of message buffers that is according to the table below. - 2. :kconfig:option:`CONFIG_CAN_MAX_FILTER` must be less or equal than - :kconfig:option:`CONFIG_CAN_MAX_MB`. - =============== ========== ================ ================ Devicetree node Payload Hardware support Software support =============== ========== ================ ================ diff --git a/drivers/can/Kconfig.mcux b/drivers/can/Kconfig.mcux index e2ee5a8d27d8f..ec099c1dcfbc8 100644 --- a/drivers/can/Kconfig.mcux +++ b/drivers/can/Kconfig.mcux @@ -28,30 +28,19 @@ config CAN_MCUX_FLEXCAN_WAIT_TIMEOUT Maximum number of wait loop iterations for the MCUX FlexCAN HAL when entering/leaving freeze mode. -config CAN_MAX_MB - int "Maximum number of message buffers for concurrent active instances" - default 16 - depends on SOC_SERIES_S32K3 || SOC_SERIES_S32K1 || SOC_SERIES_S32ZE - range 1 96 if SOC_SERIES_S32K3 - range 1 32 if SOC_SERIES_S32K1 && !SOC_S32K142W && !SOC_S32K144W - range 1 64 if SOC_S32K142W || SOC_S32K144W - range 1 128 if SOC_SERIES_S32ZE - help - Defines maximum number of message buffers for concurrent active instances. - config CAN_MAX_FILTER int "Maximum number of concurrent active RX filters" default 5 - range 1 15 if SOC_SERIES_KINETIS_KE1XF || SOC_SERIES_KINETIS_K6X - range 1 13 if (SOC_SERIES_IMXRT10XX || SOC_SERIES_IMXRT11XX) && CAN_MCUX_FLEXCAN_FD - range 1 63 if SOC_SERIES_IMXRT10XX || SOC_SERIES_IMXRT11XX - range 1 96 if SOC_SERIES_S32K3 - range 1 32 if SOC_SERIES_S32K1 && !SOC_S32K142W && !SOC_S32K144W - range 1 64 if SOC_S32K142W || SOC_S32K144W - range 1 128 if SOC_SERIES_S32ZE help Defines maximum number of concurrent active RX filters +config CAN_MCUX_FLEXCAN_HEAP_SIZE + int "The heap memory pool that FlexCAN message buffer needed" + default 2048 + help + Defines the heap memory pool size for FlexCAN message buffer allocation + This can be adjusted based on specific platform + endif # CAN_MCUX_FLEXCAN config CAN_MCUX_MCAN diff --git a/drivers/can/can_mcux_flexcan.c b/drivers/can/can_mcux_flexcan.c index 2d090e9f255ab..ae61dd7aa7066 100644 --- a/drivers/can/can_mcux_flexcan.c +++ b/drivers/can/can_mcux_flexcan.c @@ -33,20 +33,6 @@ LOG_MODULE_REGISTER(can_mcux_flexcan, CONFIG_CAN_LOG_LEVEL); #define RX_START_IDX 0 #endif -/* The maximum number of message buffers for concurrent active instances */ -#ifdef CONFIG_CAN_MAX_MB -#define MCUX_FLEXCAN_MAX_MB CONFIG_CAN_MAX_MB -#else -#define MCUX_FLEXCAN_MAX_MB FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(0) -#endif - -/* - * RX message buffers (filters) will take up the first N message - * buffers. The rest are available for TX use. - */ -#define MCUX_FLEXCAN_MAX_RX (CONFIG_CAN_MAX_FILTER + RX_START_IDX) -#define MCUX_FLEXCAN_MAX_TX (MCUX_FLEXCAN_MAX_MB - MCUX_FLEXCAN_MAX_RX) - /* * Convert from RX message buffer index to allocated filter ID and * vice versa. @@ -58,8 +44,8 @@ LOG_MODULE_REGISTER(can_mcux_flexcan, CONFIG_CAN_LOG_LEVEL); * Convert from TX message buffer index to allocated TX ID and vice * versa. */ -#define TX_MBIDX_TO_ALLOC_IDX(x) (x - MCUX_FLEXCAN_MAX_RX) -#define ALLOC_IDX_TO_TXMB_IDX(x) (x + MCUX_FLEXCAN_MAX_RX) +#define TX_MBIDX_TO_ALLOC_IDX(x) (x - data->max_rx_mb) +#define ALLOC_IDX_TO_TXMB_IDX(x) (x + data->max_rx_mb) /* Convert from back from FLEXCAN IDs to Zephyr CAN IDs. */ #define FLEXCAN_ID_TO_CAN_ID_STD(id) \ @@ -79,6 +65,7 @@ struct mcux_flexcan_config { const struct device *clock_dev; clock_control_subsys_t clock_subsys; int clk_source; + uint16_t max_mb; #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD bool flexcan_fd; #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */ @@ -113,16 +100,24 @@ struct mcux_flexcan_data { const struct device *dev; flexcan_handle_t handle; - ATOMIC_DEFINE(rx_allocs, MCUX_FLEXCAN_MAX_RX); - struct k_mutex rx_mutex; - struct mcux_flexcan_rx_callback rx_cbs[MCUX_FLEXCAN_MAX_RX]; - - ATOMIC_DEFINE(tx_allocs, MCUX_FLEXCAN_MAX_TX); - struct k_sem tx_allocs_sem; - struct k_mutex tx_mutex; - struct mcux_flexcan_tx_callback tx_cbs[MCUX_FLEXCAN_MAX_TX]; enum can_state state; struct can_timing timing; + + uint32_t max_tx_mb; + uint32_t max_rx_mb; + + struct k_heap instance_heap; + uint8_t heap_buffer[CONFIG_CAN_MCUX_FLEXCAN_HEAP_SIZE]; + + atomic_t *rx_allocs; + atomic_t *tx_allocs; + struct mcux_flexcan_rx_callback *rx_cbs; + struct mcux_flexcan_tx_callback *tx_cbs; + + struct k_mutex rx_mutex; + struct k_mutex tx_mutex; + struct k_sem tx_allocs_sem; + #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD struct can_timing timing_data; #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */ @@ -133,6 +128,116 @@ static inline CAN_Type *get_base(const struct device *dev) return (CAN_Type *)DEVICE_MMIO_NAMED_GET(dev, flexcan_mmio); } +static int mcux_flexcan_get_mb_config(const struct device *dev, uint32_t *max_mb, + uint32_t *max_rx, uint32_t *max_tx) +{ + const struct mcux_flexcan_config *config = dev->config; + +#ifdef CONFIG_CAN_MCUX_FLEXCAN_FD + /* + * When CAN FD is enabled, FlexCAN RAM can be partitioned into several blocks. + * Each block can accommodate 7 message buffers if payload size is 64-byte. + * Each block can accommodate 32 message buffers if payload size is 8-byte. + * First calculate how many RAM blocks each FlexCAN instance support, then get + * maximum accommodated message buffers under 64-byte payload size. + */ + if (config->flexcan_fd) { + /* For FlexCAN FD instances with 64-byte payload */ + *max_mb = config->max_mb / 32U * 7U; + } else { + /* + * For non-FD FlexCAN instances. + * Some platforms have both classical CAN and CAN FD instances. + * In this case, use the maximum message buffers. + */ + *max_mb = config->max_mb; + } +#else + *max_mb = config->max_mb; +#endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */ + + /* + * RX message buffers (filters) will take up the first N message + * buffers. The rest are available for TX use. + */ + *max_rx = (CONFIG_CAN_MAX_FILTER + RX_START_IDX); + + if (*max_mb < *max_rx) { + LOG_ERR("Insufficient message buffers for RX filters"); + return -EINVAL; + } + + *max_tx = *max_mb - *max_rx; + + return 0; +} + +static int mcux_flexcan_allocate_memory(const struct device *dev) +{ + struct mcux_flexcan_data *data = dev->data; + size_t rx_bitmap_size, tx_bitmap_size; + size_t rx_cb_array_size, tx_cb_array_size; + size_t total_size; + + rx_bitmap_size = ATOMIC_BITMAP_SIZE(data->max_rx_mb) * sizeof(atomic_t); + tx_bitmap_size = ATOMIC_BITMAP_SIZE(data->max_tx_mb) * sizeof(atomic_t); + rx_cb_array_size = data->max_rx_mb * sizeof(struct mcux_flexcan_rx_callback); + tx_cb_array_size = data->max_tx_mb * sizeof(struct mcux_flexcan_tx_callback); + total_size = rx_bitmap_size + tx_bitmap_size + rx_cb_array_size + tx_cb_array_size; + + if (total_size > sizeof(data->heap_buffer)) { + LOG_ERR("Insufficient heap memory for CAN buffers. Required: %zu, Available: %zu", + total_size, sizeof(data->heap_buffer)); + return -ENOMEM; + } + + LOG_DBG("Total memory size to allocate: %zu bytes", total_size); + + data->rx_allocs = NULL; + data->tx_allocs = NULL; + data->rx_cbs = NULL; + data->tx_cbs = NULL; + + /* Dynamic allocate memory for TX RX data structures using heap */ + k_heap_init(&data->instance_heap, data->heap_buffer, sizeof(data->heap_buffer)); + + data->rx_allocs = k_heap_alloc(&data->instance_heap, rx_bitmap_size, K_NO_WAIT); + data->tx_allocs = k_heap_alloc(&data->instance_heap, tx_bitmap_size, K_NO_WAIT); + data->rx_cbs = k_heap_alloc(&data->instance_heap, rx_cb_array_size, K_NO_WAIT); + data->tx_cbs = k_heap_alloc(&data->instance_heap, tx_cb_array_size, K_NO_WAIT); + + if (!data->rx_allocs || !data->tx_allocs || !data->rx_cbs || !data->tx_cbs) { + LOG_ERR("Failed to allocate memory for CAN buffers"); + goto cleanup; + } + + memset(data->rx_allocs, 0, rx_bitmap_size); + memset(data->tx_allocs, 0, tx_bitmap_size); + memset(data->rx_cbs, 0, rx_cb_array_size); + memset(data->tx_cbs, 0, tx_cb_array_size); + + return 0; + +cleanup: + if (data->tx_cbs) { + k_heap_free(&data->instance_heap, data->tx_cbs); + data->tx_cbs = NULL; + } + if (data->rx_cbs) { + k_heap_free(&data->instance_heap, data->rx_cbs); + data->rx_cbs = NULL; + } + if (data->tx_allocs) { + k_heap_free(&data->instance_heap, data->tx_allocs); + data->tx_allocs = NULL; + } + if (data->rx_allocs) { + k_heap_free(&data->instance_heap, data->rx_allocs); + data->rx_allocs = NULL; + } + return -ENOMEM; +} + static int mcux_flexcan_get_core_clock(const struct device *dev, uint32_t *rate) { const struct mcux_flexcan_config *config = dev->config; @@ -209,7 +314,7 @@ static status_t mcux_flexcan_mb_start(const struct device *dev, int alloc) flexcan_mb_transfer_t xfer; status_t status; - __ASSERT_NO_MSG(alloc >= 0 && alloc < ARRAY_SIZE(data->rx_cbs)); + __ASSERT_NO_MSG(alloc >= 0 && alloc < data->max_rx_mb); xfer.mbIdx = ALLOC_IDX_TO_RXMB_IDX(alloc); @@ -237,7 +342,7 @@ static void mcux_flexcan_mb_stop(const struct device *dev, int alloc) struct mcux_flexcan_data *data = dev->data; CAN_Type *base = get_base(dev); - __ASSERT_NO_MSG(alloc >= 0 && alloc < ARRAY_SIZE(data->rx_cbs)); + __ASSERT_NO_MSG(alloc >= 0 && alloc < data->max_rx_mb); #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD if ((data->common.mode & CAN_MODE_FD) != 0U) { @@ -288,7 +393,7 @@ static int mcux_flexcan_start(const struct device *dev) /* Re-add all RX filters using current mode */ k_mutex_lock(&data->rx_mutex, K_FOREVER); - for (alloc = RX_START_IDX; alloc < MCUX_FLEXCAN_MAX_RX; alloc++) { + for (alloc = RX_START_IDX; alloc < data->max_rx_mb; alloc++) { if (atomic_test_bit(data->rx_allocs, alloc)) { status = mcux_flexcan_mb_start(dev, alloc); if (status != kStatus_Success) { @@ -351,7 +456,7 @@ static int mcux_flexcan_stop(const struct device *dev) data->common.started = false; /* Abort any pending TX frames before entering freeze mode */ - for (alloc = 0; alloc < MCUX_FLEXCAN_MAX_TX; alloc++) { + for (alloc = 0; alloc < data->max_tx_mb; alloc++) { function = data->tx_cbs[alloc].function; arg = data->tx_cbs[alloc].arg; @@ -382,7 +487,7 @@ static int mcux_flexcan_stop(const struct device *dev) */ k_mutex_lock(&data->rx_mutex, K_FOREVER); - for (alloc = RX_START_IDX; alloc < MCUX_FLEXCAN_MAX_RX; alloc++) { + for (alloc = RX_START_IDX; alloc < data->max_rx_mb; alloc++) { if (atomic_test_bit(data->rx_allocs, alloc)) { mcux_flexcan_mb_stop(dev, alloc); } @@ -744,7 +849,7 @@ static int mcux_flexcan_send(const struct device *dev, return -EAGAIN; } - for (alloc = 0; alloc < MCUX_FLEXCAN_MAX_TX; alloc++) { + for (alloc = 0; alloc < data->max_tx_mb; alloc++) { if (!atomic_test_and_set_bit(data->tx_allocs, alloc)) { break; } @@ -817,7 +922,7 @@ static int mcux_flexcan_add_rx_filter(const struct device *dev, k_mutex_lock(&data->rx_mutex, K_FOREVER); /* Find and allocate RX message buffer */ - for (i = RX_START_IDX; i < MCUX_FLEXCAN_MAX_RX; i++) { + for (i = RX_START_IDX; i < data->max_rx_mb; i++) { if (!atomic_test_and_set_bit(data->rx_allocs, i)) { alloc = i; break; @@ -920,7 +1025,7 @@ static void mcux_flexcan_remove_rx_filter(const struct device *dev, int filter_i { struct mcux_flexcan_data *data = dev->data; - if (filter_id < 0 || filter_id >= MCUX_FLEXCAN_MAX_RX) { + if (filter_id < 0 || filter_id >= data->max_rx_mb) { LOG_ERR("filter ID %d out of bounds", filter_id); return; } @@ -996,7 +1101,7 @@ static inline void mcux_flexcan_transfer_error_status(const struct device *dev, if (state == CAN_STATE_BUS_OFF) { /* Abort any pending TX frames in case of bus-off */ - for (alloc = 0; alloc < MCUX_FLEXCAN_MAX_TX; alloc++) { + for (alloc = 0; alloc < data->max_tx_mb; alloc++) { /* Copy callback function and argument before clearing bit */ function = data->tx_cbs[alloc].function; arg = data->tx_cbs[alloc].arg; @@ -1159,6 +1264,7 @@ static int mcux_flexcan_init(const struct device *dev) struct mcux_flexcan_data *data = dev->data; CAN_Type *base; flexcan_config_t flexcan_config; + uint32_t max_mb, max_rx, max_tx; uint32_t clock_freq; int err; @@ -1176,10 +1282,30 @@ static int mcux_flexcan_init(const struct device *dev) DEVICE_MMIO_NAMED_MAP(dev, flexcan_mmio, K_MEM_CACHE_NONE | K_MEM_DIRECT_MAP); + err = mcux_flexcan_get_mb_config(dev, &max_mb, &max_rx, &max_tx); + if (err != 0) { + return err; + } + + if (max_mb == 0 || max_rx == 0 || max_tx == 0) { + LOG_ERR("Invalid message buffer configuration. max_mb: %d, rx_mb: %d, tx_mb: %d", + max_mb, max_rx, max_tx); + return -EINVAL; + } + + LOG_DBG("max_mb: %d, rx_mb: %d, tx_mb: %d", max_mb, max_rx, max_tx); + + data->max_rx_mb = max_rx; + data->max_tx_mb = max_tx; + + err = mcux_flexcan_allocate_memory(dev); + if (err != 0) { + return err; + } + k_mutex_init(&data->rx_mutex); k_mutex_init(&data->tx_mutex); - k_sem_init(&data->tx_allocs_sem, MCUX_FLEXCAN_MAX_TX, - MCUX_FLEXCAN_MAX_TX); + k_sem_init(&data->tx_allocs_sem, max_tx, max_tx); err = can_calc_timing(dev, &data->timing, config->common.bitrate, config->common.sample_point); @@ -1235,7 +1361,7 @@ static int mcux_flexcan_init(const struct device *dev) data->dev = dev; FLEXCAN_GetDefaultConfig(&flexcan_config); - flexcan_config.maxMbNum = MCUX_FLEXCAN_MAX_MB; + flexcan_config.maxMbNum = max_mb; flexcan_config.clkSrc = config->clk_source; flexcan_config.baudRate = clock_freq / (1U + data->timing.prop_seg + data->timing.phase_seg1 + @@ -1446,6 +1572,7 @@ static DEVICE_API(can, mcux_flexcan_fd_driver_api) = { .clock_subsys = (clock_control_subsys_t) \ DT_INST_CLOCKS_CELL(id, name), \ .clk_source = DT_INST_PROP(id, clk_source), \ + .max_mb = DT_INST_PROP(id, nxp_max_mb), \ IF_ENABLED(CONFIG_CAN_MCUX_FLEXCAN_FD, ( \ .flexcan_fd = DT_INST_NODE_HAS_COMPAT(id, FLEXCAN_FD_DRV_COMPAT), \ )) \ diff --git a/dts/arm/nxp/nxp_k66.dtsi b/dts/arm/nxp/nxp_k66.dtsi index 5114a616404fe..a7af41f0afc47 100644 --- a/dts/arm/nxp/nxp_k66.dtsi +++ b/dts/arm/nxp/nxp_k66.dtsi @@ -32,6 +32,7 @@ "rx-warning", "wake-up"; clocks = <&sim KINETIS_SIM_BUS_CLK 0x1030 4>; clk-source = <1>; + nxp,max-mb = <16>; status = "disabled"; }; }; diff --git a/dts/arm/nxp/nxp_k6x.dtsi b/dts/arm/nxp/nxp_k6x.dtsi index 05fc5209a3ad8..c2ad3b32d14b7 100644 --- a/dts/arm/nxp/nxp_k6x.dtsi +++ b/dts/arm/nxp/nxp_k6x.dtsi @@ -518,6 +518,7 @@ interrupt-names = "mb-0-15", "bus-off", "error", "tx-warning", "rx-warning", "wake-up"; clocks = <&sim KINETIS_SIM_BUS_CLK 0x103C 4>; clk-source = <1>; + nxp,max-mb = <16>; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_ke1xf.dtsi b/dts/arm/nxp/nxp_ke1xf.dtsi index 87ade664ce622..b51e5243e7727 100644 --- a/dts/arm/nxp/nxp_ke1xf.dtsi +++ b/dts/arm/nxp/nxp_ke1xf.dtsi @@ -411,6 +411,7 @@ "mb-0-15"; clocks = <&scg KINETIS_SCG_BUS_CLK>; clk-source = <1>; + nxp,max-mb = <16>; status = "disabled"; }; @@ -422,6 +423,7 @@ "mb-0-15"; clocks = <&scg KINETIS_SCG_BUS_CLK>; clk-source = <1>; + nxp,max-mb = <16>; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_mcxa156.dtsi b/dts/arm/nxp/nxp_mcxa156.dtsi index 9d08ab4f4e6fe..bbff1361738e7 100644 --- a/dts/arm/nxp/nxp_mcxa156.dtsi +++ b/dts/arm/nxp/nxp_mcxa156.dtsi @@ -266,6 +266,7 @@ interrupt-names = "common"; clocks = <&syscon MCUX_FLEXCAN0_CLK>; clk-source = <0>; + nxp,max-mb = <32>; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_mcxa344.dtsi b/dts/arm/nxp/nxp_mcxa344.dtsi index e7376d9bbcc16..da91fd5ae44c4 100644 --- a/dts/arm/nxp/nxp_mcxa344.dtsi +++ b/dts/arm/nxp/nxp_mcxa344.dtsi @@ -256,6 +256,7 @@ interrupt-names = "common"; clocks = <&syscon MCUX_FLEXCAN0_CLK>; clk-source = <0>; + nxp,max-mb = <32>; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_mcxe245.dtsi b/dts/arm/nxp/nxp_mcxe245.dtsi index d17ea02eba7ce..b2fd2ff5176ac 100644 --- a/dts/arm/nxp/nxp_mcxe245.dtsi +++ b/dts/arm/nxp/nxp_mcxe245.dtsi @@ -39,12 +39,14 @@ compatible = "nxp,flexcan"; interrupts = <85 0>, <86 0>, <88 0>; interrupt-names = "ored-warning-bus-off", "error", "mb-0-15"; + nxp,max-mb = <16>; }; &flexcan2 { compatible = "nxp,flexcan"; interrupts = <92 0>, <93 0>, <95 0>; interrupt-names = "ored-warning-bus-off", "error", "mb-0-15"; + nxp,max-mb = <16>; }; /delete-node/ &ftm4; diff --git a/dts/arm/nxp/nxp_mcxe246.dtsi b/dts/arm/nxp/nxp_mcxe246.dtsi index 342e5384a89fd..a640addfa8cd7 100644 --- a/dts/arm/nxp/nxp_mcxe246.dtsi +++ b/dts/arm/nxp/nxp_mcxe246.dtsi @@ -39,6 +39,7 @@ compatible = "nxp,flexcan"; interrupts = <92 0>, <93 0>, <95 0>; interrupt-names = "ored-warning-bus-off", "error", "mb-0-15"; + nxp,max-mb = <16>; }; /delete-node/ &ftm4; diff --git a/dts/arm/nxp/nxp_mcxe24x_common.dtsi b/dts/arm/nxp/nxp_mcxe24x_common.dtsi index 3fa43feb3c76d..0d557d1a52bbb 100644 --- a/dts/arm/nxp/nxp_mcxe24x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxe24x_common.dtsi @@ -263,6 +263,7 @@ "wake-up", "mb-0-15", "mb-16-31"; clocks = <&scg KINETIS_SCG_CORESYS_CLK>; clk-source = <0>; + nxp,max-mb = <32>; status = "disabled"; }; @@ -273,6 +274,7 @@ interrupt-names = "ored-warning-bus-off", "error", "mb-0-15", "mb-16-31"; clocks = <&scg KINETIS_SCG_CORESYS_CLK>; clk-source = <0>; + nxp,max-mb = <32>; status = "disabled"; }; @@ -283,6 +285,7 @@ interrupt-names = "ored-warning-bus-off", "error", "mb-0-15", "mb-16-31"; clocks = <&scg KINETIS_SCG_CORESYS_CLK>; clk-source = <0>; + nxp,max-mb = <32>; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_mcxe31b.dtsi b/dts/arm/nxp/nxp_mcxe31b.dtsi index ba7fec4f3b4d0..fab93bfb33a37 100644 --- a/dts/arm/nxp/nxp_mcxe31b.dtsi +++ b/dts/arm/nxp/nxp_mcxe31b.dtsi @@ -52,3 +52,27 @@ }; #include + +&flexcan_0 { + nxp,max-mb = <96>; +}; + +&flexcan_1 { + nxp,max-mb = <64>; +}; + +&flexcan_2 { + nxp,max-mb = <64>; +}; + +&flexcan_3 { + nxp,max-mb = <32>; +}; + +&flexcan_4 { + nxp,max-mb = <32>; +}; + +&flexcan_5 { + nxp,max-mb = <32>; +}; diff --git a/dts/arm/nxp/nxp_mcxn23x_common.dtsi b/dts/arm/nxp/nxp_mcxn23x_common.dtsi index 4b88cae0ced77..d9b7dc7c4d85b 100644 --- a/dts/arm/nxp/nxp_mcxn23x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxn23x_common.dtsi @@ -814,6 +814,7 @@ interrupt-names = "common"; clocks = <&syscon MCUX_FLEXCAN0_CLK>; clk-source = <0>; + nxp,max-mb = <32>; status = "disabled"; }; @@ -824,6 +825,7 @@ interrupt-names = "common"; clocks = <&syscon MCUX_FLEXCAN1_CLK>; clk-source = <0>; + nxp,max-mb = <32>; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_mcxn94x_common.dtsi b/dts/arm/nxp/nxp_mcxn94x_common.dtsi index 258d2fba89369..c808cb87649be 100644 --- a/dts/arm/nxp/nxp_mcxn94x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxn94x_common.dtsi @@ -112,6 +112,7 @@ interrupt-names = "common"; clocks = <&syscon MCUX_FLEXCAN1_CLK>; clk-source = <0>; + nxp,max-mb = <32>; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_mcxnx4x_common.dtsi b/dts/arm/nxp/nxp_mcxnx4x_common.dtsi index 0779a92ce3068..2764797863484 100644 --- a/dts/arm/nxp/nxp_mcxnx4x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxnx4x_common.dtsi @@ -1001,6 +1001,7 @@ interrupt-names = "common"; clocks = <&syscon MCUX_FLEXCAN0_CLK>; clk-source = <0>; + nxp,max-mb = <32>; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_mcxw7x_common.dtsi b/dts/arm/nxp/nxp_mcxw7x_common.dtsi index 7b25f3eb406d3..8bbb7fa8c6540 100644 --- a/dts/arm/nxp/nxp_mcxw7x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxw7x_common.dtsi @@ -376,6 +376,7 @@ interrupt-names = "common"; clocks = <&scg SCG_K4_FIRC_CLK 0xec>; clk-source = <2>; + nxp,max-mb = <32>; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_rt10xx.dtsi b/dts/arm/nxp/nxp_rt10xx.dtsi index 24fd38c070ca4..05f10a7bb8644 100644 --- a/dts/arm/nxp/nxp_rt10xx.dtsi +++ b/dts/arm/nxp/nxp_rt10xx.dtsi @@ -970,6 +970,7 @@ interrupt-names = "common"; clocks = <&ccm IMX_CCM_CAN_CLK 0x68 14>; clk-source = <2>; + nxp,max-mb = <64>; status = "disabled"; }; @@ -980,6 +981,7 @@ interrupt-names = "common"; clocks = <&ccm IMX_CCM_CAN_CLK 0x68 18>; clk-source = <2>; + nxp,max-mb = <64>; status = "disabled"; }; @@ -990,6 +992,7 @@ interrupt-names = "common"; clocks = <&ccm IMX_CCM_CAN_CLK 0x84 6>; clk-source = <2>; + nxp,max-mb = <64>; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_rt118x.dtsi b/dts/arm/nxp/nxp_rt118x.dtsi index 7ccf141046c53..04413073643c8 100644 --- a/dts/arm/nxp/nxp_rt118x.dtsi +++ b/dts/arm/nxp/nxp_rt118x.dtsi @@ -774,6 +774,7 @@ interrupt-names = "common", "error"; clocks = <&ccm IMX_CCM_CAN1_CLK 0x68 14>; clk-source = <0>; + nxp,max-mb = <96>; status = "disabled"; }; @@ -784,6 +785,7 @@ interrupt-names = "common", "error"; clocks = <&ccm IMX_CCM_CAN2_CLK 0x68 18>; clk-source = <0>; + nxp,max-mb = <96>; status = "disabled"; }; @@ -794,6 +796,7 @@ interrupt-names = "common", "error"; clocks = <&ccm IMX_CCM_CAN3_CLK 0x84 6>; clk-source = <0>; + nxp,max-mb = <96>; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_rt11xx.dtsi b/dts/arm/nxp/nxp_rt11xx.dtsi index c69d42f0fa629..d2f16077ba477 100644 --- a/dts/arm/nxp/nxp_rt11xx.dtsi +++ b/dts/arm/nxp/nxp_rt11xx.dtsi @@ -917,6 +917,7 @@ interrupt-names = "common", "error"; clocks = <&ccm IMX_CCM_CAN1_CLK 0x68 14>; clk-source = <0>; + nxp,max-mb = <64>; status = "disabled"; }; @@ -927,6 +928,7 @@ interrupt-names = "common", "error"; clocks = <&ccm IMX_CCM_CAN2_CLK 0x68 18>; clk-source = <0>; + nxp,max-mb = <64>; status = "disabled"; }; @@ -937,6 +939,7 @@ interrupt-names = "common", "error"; clocks = <&ccm IMX_CCM_CAN3_CLK 0x84 6>; clk-source = <0>; + nxp,max-mb = <64>; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_s32k146.dtsi b/dts/arm/nxp/nxp_s32k146.dtsi index bfbb1558349a3..28d803ce03e37 100644 --- a/dts/arm/nxp/nxp_s32k146.dtsi +++ b/dts/arm/nxp/nxp_s32k146.dtsi @@ -65,16 +65,19 @@ &flexcan0 { interrupts = <78 0>, <79 0>, <80 0>, <81 0>, <82 0>; interrupt-names = "warning", "error", "wake-up", "mb-0-15", "mb-16-31"; + nxp,max-mb = <32>; }; &flexcan1 { interrupts = <85 0>, <86 0>, <88 0>, <89 0>; interrupt-names = "warning", "error", "mb-0-15", "mb-16-31"; clocks = <&clock NXP_S32_FLEXCAN1_CLK>; + nxp,max-mb = <32>; }; &flexcan2 { interrupts = <92 0>, <93 0>, <95 0>; interrupt-names = "warning", "error", "mb-0-15"; clocks = <&clock NXP_S32_FLEXCAN2_CLK>; + nxp,max-mb = <16>; }; diff --git a/dts/arm/nxp/nxp_s32k148.dtsi b/dts/arm/nxp/nxp_s32k148.dtsi index 25e73912bf96c..bd005fd966292 100644 --- a/dts/arm/nxp/nxp_s32k148.dtsi +++ b/dts/arm/nxp/nxp_s32k148.dtsi @@ -88,16 +88,19 @@ &flexcan0 { interrupts = <78 0>, <79 0>, <80 0>, <81 0>, <82 0>; interrupt-names = "warning", "error", "wake-up", "mb-0-15", "mb-16-31"; + nxp,max-mb = <32>; }; &flexcan1 { interrupts = <85 0>, <86 0>, <88 0>, <89 0>; interrupt-names = "warning", "error", "mb-0-15", "mb-16-31"; clocks = <&clock NXP_S32_FLEXCAN1_CLK>; + nxp,max-mb = <32>; }; &flexcan2 { interrupts = <92 0>, <93 0>, <95 0>, <96 0>; interrupt-names = "warning", "error", "mb-0-15", "mb-16-31"; clocks = <&clock NXP_S32_FLEXCAN2_CLK>; + nxp,max-mb = <32>; }; diff --git a/dts/arm/nxp/nxp_s32k344_m7.dtsi b/dts/arm/nxp/nxp_s32k344_m7.dtsi index 21553748ba66f..07952d97c916c 100644 --- a/dts/arm/nxp/nxp_s32k344_m7.dtsi +++ b/dts/arm/nxp/nxp_s32k344_m7.dtsi @@ -471,6 +471,7 @@ interrupts = <109 0>, <110 0>, <111 0>, <112 0>; interrupt-names = "ored", "ored_0_31_mb", "ored_32_63_mb", "ored_64_95_mb"; + nxp,max-mb = <96>; status = "disabled"; }; @@ -481,6 +482,7 @@ clk-source = <0>; interrupts = <113 0>, <114 0>, <115 0>; interrupt-names = "ored", "ored_0_31_mb", "ored_32_63_mb"; + nxp,max-mb = <64>; status = "disabled"; }; @@ -491,6 +493,7 @@ clk-source = <0>; interrupts = <116 0>, <117 0>, <118 0>; interrupt-names = "ored", "ored_0_31_mb", "ored_32_63_mb"; + nxp,max-mb = <64>; status = "disabled"; }; @@ -501,6 +504,7 @@ clk-source = <0>; interrupts = <119 0>, <120 0>; interrupt-names = "ored", "ored_0_31_mb"; + nxp,max-mb = <32>; status = "disabled"; }; @@ -511,6 +515,7 @@ clk-source = <0>; interrupts = <121 0>, <122 0>; interrupt-names = "ored", "ored_0_31_mb"; + nxp,max-mb = <32>; status = "disabled"; }; @@ -521,6 +526,7 @@ clk-source = <0>; interrupts = <123 0>, <124 0>; interrupt-names = "ored", "ored_0_31_mb"; + nxp,max-mb = <32>; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_s32z27x_r52.dtsi b/dts/arm/nxp/nxp_s32z27x_r52.dtsi index 8395982969c23..40c68a75b30f1 100644 --- a/dts/arm/nxp/nxp_s32z27x_r52.dtsi +++ b/dts/arm/nxp/nxp_s32z27x_r52.dtsi @@ -756,6 +756,7 @@ interrupt-names = "ored", "ored_0_31_mb", "ored_32_63_mb", "ored_64_95_mb", "ored_96_127_mb"; clocks = <&clock NXP_S32_P3_CAN_PE_CLK>; + nxp,max-mb = <128>; status = "disabled"; }; @@ -771,6 +772,7 @@ interrupt-names = "ored", "ored_0_31_mb", "ored_32_63_mb", "ored_64_95_mb", "ored_96_127_mb"; clocks = <&clock NXP_S32_P3_CAN_PE_CLK>; + nxp,max-mb = <128>; status = "disabled"; }; @@ -786,6 +788,7 @@ interrupt-names = "ored", "ored_0_31_mb", "ored_32_63_mb", "ored_64_95_mb", "ored_96_127_mb"; clocks = <&clock NXP_S32_P3_CAN_PE_CLK>; + nxp,max-mb = <128>; status = "disabled"; }; @@ -801,6 +804,7 @@ interrupt-names = "ored", "ored_0_31_mb", "ored_32_63_mb", "ored_64_95_mb", "ored_96_127_mb"; clocks = <&clock NXP_S32_P3_CAN_PE_CLK>; + nxp,max-mb = <128>; status = "disabled"; }; @@ -816,6 +820,7 @@ interrupt-names = "ored", "ored_0_31_mb", "ored_32_63_mb", "ored_64_95_mb", "ored_96_127_mb"; clocks = <&clock NXP_S32_P3_CAN_PE_CLK>; + nxp,max-mb = <128>; status = "disabled"; }; @@ -831,6 +836,7 @@ interrupt-names = "ored", "ored_0_31_mb", "ored_32_63_mb", "ored_64_95_mb", "ored_96_127_mb"; clocks = <&clock NXP_S32_P3_CAN_PE_CLK>; + nxp,max-mb = <128>; status = "disabled"; }; @@ -846,6 +852,7 @@ interrupt-names = "ored", "ored_0_31_mb", "ored_32_63_mb", "ored_64_95_mb", "ored_96_127_mb"; clocks = <&clock NXP_S32_P3_CAN_PE_CLK>; + nxp,max-mb = <128>; status = "disabled"; }; @@ -861,6 +868,7 @@ interrupt-names = "ored", "ored_0_31_mb", "ored_32_63_mb", "ored_64_95_mb", "ored_96_127_mb"; clocks = <&clock NXP_S32_P3_CAN_PE_CLK>; + nxp,max-mb = <128>; status = "disabled"; }; @@ -876,6 +884,7 @@ interrupt-names = "ored", "ored_0_31_mb", "ored_32_63_mb", "ored_64_95_mb", "ored_96_127_mb"; clocks = <&clock NXP_S32_P3_CAN_PE_CLK>; + nxp,max-mb = <128>; status = "disabled"; }; @@ -891,6 +900,7 @@ interrupt-names = "ored", "ored_0_31_mb", "ored_32_63_mb", "ored_64_95_mb", "ored_96_127_mb"; clocks = <&clock NXP_S32_P3_CAN_PE_CLK>; + nxp,max-mb = <128>; status = "disabled"; }; @@ -906,6 +916,7 @@ interrupt-names = "ored", "ored_0_31_mb", "ored_32_63_mb", "ored_64_95_mb", "ored_96_127_mb"; clocks = <&clock NXP_S32_P3_CAN_PE_CLK>; + nxp,max-mb = <128>; status = "disabled"; }; @@ -921,6 +932,7 @@ interrupt-names = "ored", "ored_0_31_mb", "ored_32_63_mb", "ored_64_95_mb", "ored_96_127_mb"; clocks = <&clock NXP_S32_P3_CAN_PE_CLK>; + nxp,max-mb = <128>; status = "disabled"; }; @@ -936,6 +948,7 @@ interrupt-names = "ored", "ored_0_31_mb", "ored_32_63_mb", "ored_64_95_mb", "ored_96_127_mb"; clocks = <&clock NXP_S32_P3_CAN_PE_CLK>; + nxp,max-mb = <128>; status = "disabled"; }; @@ -951,6 +964,7 @@ interrupt-names = "ored", "ored_0_31_mb", "ored_32_63_mb", "ored_64_95_mb", "ored_96_127_mb"; clocks = <&clock NXP_S32_P3_CAN_PE_CLK>; + nxp,max-mb = <128>; status = "disabled"; }; @@ -966,6 +980,7 @@ interrupt-names = "ored", "ored_0_31_mb", "ored_32_63_mb", "ored_64_95_mb", "ored_96_127_mb"; clocks = <&clock NXP_S32_P3_CAN_PE_CLK>; + nxp,max-mb = <128>; status = "disabled"; }; @@ -981,6 +996,7 @@ interrupt-names = "ored", "ored_0_31_mb", "ored_32_63_mb", "ored_64_95_mb", "ored_96_127_mb"; clocks = <&clock NXP_S32_P3_CAN_PE_CLK>; + nxp,max-mb = <128>; status = "disabled"; }; @@ -996,6 +1012,7 @@ interrupt-names = "ored", "ored_0_31_mb", "ored_32_63_mb", "ored_64_95_mb", "ored_96_127_mb"; clocks = <&clock NXP_S32_P3_CAN_PE_CLK>; + nxp,max-mb = <128>; status = "disabled"; }; @@ -1011,6 +1028,7 @@ interrupt-names = "ored", "ored_0_31_mb", "ored_32_63_mb", "ored_64_95_mb", "ored_96_127_mb"; clocks = <&clock NXP_S32_P3_CAN_PE_CLK>; + nxp,max-mb = <128>; status = "disabled"; }; @@ -1026,6 +1044,7 @@ interrupt-names = "ored", "ored_0_31_mb", "ored_32_63_mb", "ored_64_95_mb", "ored_96_127_mb"; clocks = <&clock NXP_S32_P3_CAN_PE_CLK>; + nxp,max-mb = <128>; status = "disabled"; }; @@ -1041,6 +1060,7 @@ interrupt-names = "ored", "ored_0_31_mb", "ored_32_63_mb", "ored_64_95_mb", "ored_96_127_mb"; clocks = <&clock NXP_S32_P3_CAN_PE_CLK>; + nxp,max-mb = <128>; status = "disabled"; }; @@ -1056,6 +1076,7 @@ interrupt-names = "ored", "ored_0_31_mb", "ored_32_63_mb", "ored_64_95_mb", "ored_96_127_mb"; clocks = <&clock NXP_S32_P3_CAN_PE_CLK>; + nxp,max-mb = <128>; status = "disabled"; }; @@ -1071,6 +1092,7 @@ interrupt-names = "ored", "ored_0_31_mb", "ored_32_63_mb", "ored_64_95_mb", "ored_96_127_mb"; clocks = <&clock NXP_S32_P3_CAN_PE_CLK>; + nxp,max-mb = <128>; status = "disabled"; }; @@ -1086,6 +1108,7 @@ interrupt-names = "ored", "ored_0_31_mb", "ored_32_63_mb", "ored_64_95_mb", "ored_96_127_mb"; clocks = <&clock NXP_S32_P3_CAN_PE_CLK>; + nxp,max-mb = <128>; status = "disabled"; }; @@ -1101,6 +1124,7 @@ interrupt-names = "ored", "ored_0_31_mb", "ored_32_63_mb", "ored_64_95_mb", "ored_96_127_mb"; clocks = <&clock NXP_S32_P3_CAN_PE_CLK>; + nxp,max-mb = <128>; status = "disabled"; }; diff --git a/dts/arm64/nxp/nxp_mimx8mp_a53.dtsi b/dts/arm64/nxp/nxp_mimx8mp_a53.dtsi index 3d98094e92142..d4e91eeb85755 100644 --- a/dts/arm64/nxp/nxp_mimx8mp_a53.dtsi +++ b/dts/arm64/nxp/nxp_mimx8mp_a53.dtsi @@ -198,6 +198,7 @@ interrupt-names = "common", "error"; clocks = <&ccm IMX_CCM_CAN1_CLK 0x68 14>; clk-source = <0>; + nxp,max-mb = <64>; rdc = <(RDC_DOMAIN_PERM(A53_DOMAIN_ID, RDC_DOMAIN_PERM_RW) | RDC_DOMAIN_PERM(M7_DOMAIN_ID, RDC_DOMAIN_PERM_RW))>; status = "disabled"; @@ -212,6 +213,7 @@ interrupt-names = "common", "error"; clocks = <&ccm IMX_CCM_CAN2_CLK 0x68 14>; clk-source = <0>; + nxp,max-mb = <64>; rdc = <(RDC_DOMAIN_PERM(A53_DOMAIN_ID, RDC_DOMAIN_PERM_RW) | RDC_DOMAIN_PERM(M7_DOMAIN_ID, RDC_DOMAIN_PERM_RW))>; status = "disabled"; diff --git a/dts/arm64/nxp/nxp_mimx93_a55.dtsi b/dts/arm64/nxp/nxp_mimx93_a55.dtsi index 84a6c00fcae70..af893b3882984 100644 --- a/dts/arm64/nxp/nxp_mimx93_a55.dtsi +++ b/dts/arm64/nxp/nxp_mimx93_a55.dtsi @@ -420,6 +420,7 @@ interrupt-names = "common", "error"; clocks = <&ccm IMX_CCM_CAN1_CLK 0x68 14>; clk-source = <0>; + nxp,max-mb = <96>; status = "disabled"; }; @@ -432,6 +433,7 @@ interrupt-names = "common", "error"; clocks = <&ccm IMX_CCM_CAN2_CLK 0x68 14>; clk-source = <0>; + nxp,max-mb = <96>; status = "disabled"; }; diff --git a/dts/bindings/can/nxp,flexcan-fd.yaml b/dts/bindings/can/nxp,flexcan-fd.yaml index ff778be13c1eb..9ac8ae3b2d7c9 100644 --- a/dts/bindings/can/nxp,flexcan-fd.yaml +++ b/dts/bindings/can/nxp,flexcan-fd.yaml @@ -15,6 +15,7 @@ description: | interrupt-names = "common"; clocks = <&ccm IMX_CCM_CAN_CLK 0x84 6>; clk-source = <2>; + nxp,max-mb = <64>; pinctrl-0 = <&pinmux_flexcan3>; pinctrl-names = "default"; diff --git a/dts/bindings/can/nxp,flexcan.yaml b/dts/bindings/can/nxp,flexcan.yaml index 045c09974fcdd..b2460e71c978a 100644 --- a/dts/bindings/can/nxp,flexcan.yaml +++ b/dts/bindings/can/nxp,flexcan.yaml @@ -13,6 +13,7 @@ description: | interrupt-names = "warning", "error", "wake-up", "mb-0-15"; clocks = <&scg KINETIS_SCG_BUS_CLK>; clk-source = <1>; + nxp,max-mb = <16>; pinctrl-0 = <&pinmux_flexcan0>; pinctrl-names = "default"; @@ -39,3 +40,8 @@ properties: type: int required: true description: CAN engine clock source + + nxp,max-mb: + type: int + required: true + description: Maximum number of 8-byte payload message buffers FlexCAN instance supported