diff --git a/boards/ti/am261x_lp/Kconfig b/boards/ti/am261x_lp/Kconfig deleted file mode 100644 index 9df3e04136f30..0000000000000 --- a/boards/ti/am261x_lp/Kconfig +++ /dev/null @@ -1,9 +0,0 @@ -# TI AM261X LaunchPad board -# -# Copyright (c) 2025 Texas Instruments Incorporated -# -# SPDX-License-Identifier: Apache-2.0 - -config SOC_PACKAGE_ZFG - bool "This Board has ZFG package" - default y diff --git a/boards/ti/am261x_lp/Kconfig.am261x_lp b/boards/ti/am261x_lp/Kconfig.am261x_lp index 7aaf52484037d..5b288acbfca60 100644 --- a/boards/ti/am261x_lp/Kconfig.am261x_lp +++ b/boards/ti/am261x_lp/Kconfig.am261x_lp @@ -5,19 +5,5 @@ # SPDX-License-Identifier: Apache-2.0 config BOARD_AM261X_LP - bool "Board AM261X LP Selecting" - select SOC_SERIES_AM261X_R5F - -config BOARD_AM261X_LP_AM2612_R5F0_0 - bool "TI AM261X LaunchPad For Core R5F0_0" - select BOARD_AM261X_LP - select SOC_AM261X_R5F0_0 - help - Build for TI AM261X LaunchPad with R5F Core 0 - -config BOARD_AM261X_LP_AM2612_R5F0_1 - bool "TI AM261X LaunchPad For Core R5F0_1" - select BOARD_AM261X_LP - select SOC_AM261X_R5F0_1 - help - Build for TI AM261X LaunchPad with R5F Core 1 + select SOC_AM261X_R5F0_0 if BOARD_AM261X_LP_AM2612_R5F0_0 + select SOC_AM261X_R5F0_1 if BOARD_AM261X_LP_AM2612_R5F0_1 \ No newline at end of file diff --git a/boards/ti/am261x_lp/am261x_lp_am2612_r5f0_0.dts b/boards/ti/am261x_lp/am261x_lp_am2612_r5f0_0.dts index 3b8776c139c5f..b38afc312dc7a 100644 --- a/boards/ti/am261x_lp/am261x_lp_am2612_r5f0_0.dts +++ b/boards/ti/am261x_lp/am261x_lp_am2612_r5f0_0.dts @@ -4,8 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -/dts-v1/; - #include #include #include @@ -29,6 +27,7 @@ leds { compatible = "gpio-leds"; + led0: led_0 { /* gpio 84 is in bank 5, so 20th pin in the bank4-5 set */ gpios = <&gpio0_bank_4_5 20 1>; @@ -38,10 +37,11 @@ buttons { compatible = "gpio-keys"; + user_button: button_0 { - /* Replace with the correct GPIO pin for your button */ - gpios = <&gpio0_bank_6_7 28 1>; - label = "User Button"; + /* Replace with the correct GPIO pin for your button */ + gpios = <&gpio0_bank_6_7 28 1>; + label = "User Button"; }; }; }; @@ -77,24 +77,26 @@ pinmux = ; }; + spi2_d0: spi2_d0 { pinmux = ; }; + spi2_d1: spi2_d1 { pinmux = ; }; + spi2_cs0: spi2_cs0 { pinmux = ; }; + spi2_cs1: spi2_cs1 { pinmux = ; }; - - }; &uart0 { @@ -107,6 +109,7 @@ &gpio0_bank_4_5 { status = "okay"; + mux-hog { gpio-hog; gpios = <20 1>; @@ -126,7 +129,6 @@ status = "okay"; region-id = <0>; queue-number = <0>; - edma-resources = , ; }; @@ -134,5 +136,4 @@ &mcspi2 { pinctrl-0 = <&spi2_clk &spi2_cs0 &spi2_d0 &spi2_d1>; pinctrl-names = "default"; - status = "okay"; }; diff --git a/boards/ti/am261x_lp/am261x_lp_am2612_r5f0_1.dts b/boards/ti/am261x_lp/am261x_lp_am2612_r5f0_1.dts index 0db3a38899738..728ea478192e0 100644 --- a/boards/ti/am261x_lp/am261x_lp_am2612_r5f0_1.dts +++ b/boards/ti/am261x_lp/am261x_lp_am2612_r5f0_1.dts @@ -4,8 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -/dts-v1/; - #include #include #include @@ -29,6 +27,7 @@ leds { compatible = "gpio-leds"; + led0: led_0 { /* gpio 84 is in bank 5, so 20th pin in the bank4-5 set */ gpios = <&gpio1_bank_4_5 20 1>; @@ -38,10 +37,11 @@ buttons { compatible = "gpio-keys"; + user_button: button_0 { - /* Replace with the correct GPIO pin for your button */ - gpios = <&gpio1_bank_6_7 28 1>; - label = "User Button"; + /* Replace with the correct GPIO pin for your button */ + gpios = <&gpio1_bank_6_7 28 1>; + label = "User Button"; }; }; }; @@ -77,23 +77,26 @@ pinmux = ; }; + spi2_d0: spi2_d0 { pinmux = ; }; + spi2_d1: spi2_d1 { pinmux = ; }; + spi2_cs0: spi2_cs0 { pinmux = ; }; + spi2_cs1: spi2_cs1 { pinmux = ; }; - }; &uart0 { @@ -106,6 +109,7 @@ &gpio1_bank_4_5 { status = "okay"; + mux-hog { gpio-hog; gpios = <20 1>; @@ -125,7 +129,6 @@ status = "okay"; region-id = <1>; queue-number = <0>; - edma-resources = , ; }; @@ -133,5 +136,4 @@ &mcspi2 { pinctrl-0 = <&spi2_clk &spi2_cs0 &spi2_d0 &spi2_d1>; pinctrl-names = "default"; - status = "okay"; }; diff --git a/boards/ti/am261x_lp/doc/index.rst b/boards/ti/am261x_lp/doc/index.rst index d4aa6b5ae2d8a..b0d5497e4654b 100644 --- a/boards/ti/am261x_lp/doc/index.rst +++ b/boards/ti/am261x_lp/doc/index.rst @@ -76,6 +76,8 @@ In AM261x, each McSPI supports up to 2 CS lines. However, the McSPI driver currently supports only single-channel transfer per McSPI interface. +**NOTE:Only Channel 0 of any McSPI has default DMA support.** + | Data Movement Architecture @@ -148,6 +150,14 @@ Some IPs also have DMA channels configured by default: +----------+--------------+--------------+ | UART5 | Tx:11 Rx:12 | Tx: 43 Rx: 44| +----------+--------------+--------------+ +| McSPI0 | Tx:13 Rx:14 | Tx: 45 Rx: 46| ++----------+--------------+--------------+ +| McSPI1 | Tx:15 Rx:16 | Tx: 47 Rx: 48| ++----------+--------------+--------------+ +| McSPI2 | Tx:17 Rx:18 | Tx: 49 Rx: 50| ++----------+--------------+--------------+ +| McSPI3 | Tx:19 Rx:20 | Tx: 51 Rx: 52| ++----------+--------------+--------------+ | diff --git a/drivers/dma/dma_ti_edma.c b/drivers/dma/dma_ti_edma.c index 0a2c29ca0c59f..f279815a2c32b 100644 --- a/drivers/dma/dma_ti_edma.c +++ b/drivers/dma/dma_ti_edma.c @@ -21,7 +21,7 @@ struct ti_edma_config { uint16_t num_edma_resources; EDMA_Params gEdmaParams; /* Performing static allocation of this array */ - EDMA_Attrs gEdmaAttrs; /* Stores eDMA configuration info */ + EDMA_Attrs gEdmaAttrs; /* Stores eDMA configuration info */ void (*register_isr)(); }; @@ -47,12 +47,13 @@ static void EDMA_dummyIsrFxn(void *args); static void ti_edma_resource_alloc(uint32_t *arr, uint32_t len, uint32_t start_index, uint32_t end_index); static int edma_resource_validate_and_alloc(const struct device *dev, int idx); +static void ti_edma_chan_release(const struct device *dev, uint32_t channel); static int ti_edma_deconfigure(const struct device *dev, uint32_t channel); static int ti_edma_init(const struct device *dev); static int ti_edma_configure(const struct device *dev, uint32_t channel, struct dma_config *config); static int ti_edma_start(const struct device *dev, uint32_t channel); -static void ti_edma_get_status(const struct device *dev, uint32_t channel, - struct dma_status *status); +static int ti_edma_get_status(const struct device *dev, uint32_t channel, + struct dma_status *status); static int ti_edma_stop(const struct device *dev, uint32_t channel); /* All static functions have been defined */ @@ -96,16 +97,13 @@ static int populate_PARAM_set(const struct device *dev, uint32_t channel, struct struct dma_block_config *block, EDMACCPaRAMEntry *edmaParam) { - const struct ti_edma_config *dev_config = dev->config; struct ti_edma_data *dev_data = dev->data; - EDMA_Handle edma_handle = dev_data->gEdmaHandle; edmaParam->srcAddr = (uint32_t)block->source_address; edmaParam->destAddr = (uint32_t)block->dest_address; uint32_t tcc = channel; uint16_t EDMA_A_COUNT, EDMA_B_COUNT, EDMA_C_COUNT; - uint32_t opt_flags = 0; switch (config->channel_direction) { case MEMORY_TO_MEMORY: @@ -130,7 +128,6 @@ static int populate_PARAM_set(const struct device *dev, uint32_t channel, struct } dev_data->channel_data[channel].chan_dir = MEMORY_TO_MEMORY; - uint32_t transfer_memory_size = block->block_size; EDMA_A_COUNT = config->source_data_size; EDMA_B_COUNT = (uint16_t)(block->block_size / EDMA_A_COUNT); @@ -384,7 +381,8 @@ static int edma_resource_validate_and_alloc(const struct device *dev, int idx) enum EDMA_Resource_Type resource_type = dev_config->edma_resources[idx]; uint16_t start_index = dev_config->edma_resources[idx + 1]; uint16_t end_index = dev_config->edma_resources[idx + 2]; - EDMA_ResourceObject *ownResource = &(dev_config->gEdmaAttrs.initPrms.ownResource); + EDMA_ResourceObject *ownResource = + (EDMA_ResourceObject *)&(dev_config->gEdmaAttrs.initPrms.ownResource); switch (resource_type) { @@ -396,14 +394,14 @@ static int edma_resource_validate_and_alloc(const struct device *dev, int idx) return -EINVAL; /* Invalid range */ } - ti_edma_resource_alloc(&(ownResource->dmaCh), + ti_edma_resource_alloc((uint32_t *)&(ownResource->dmaCh), (dev_data->dma_ctx.dma_channels % 32 == 0) ? (dev_data->dma_ctx.dma_channels / 32U) : (dev_data->dma_ctx.dma_channels / 32U) + 1, start_index, end_index); /* NOTE: Assuming TCC number = Dma Channel number */ - ti_edma_resource_alloc(&(ownResource->tcc), + ti_edma_resource_alloc((uint32_t *)&(ownResource->tcc), (dev_data->dma_ctx.dma_channels % 32 == 0) ? (dev_data->dma_ctx.dma_channels / 32U) : (dev_data->dma_ctx.dma_channels / 32U) + 1, @@ -419,7 +417,7 @@ static int edma_resource_validate_and_alloc(const struct device *dev, int idx) return -EINVAL; /* Invalid range */ } - ti_edma_resource_alloc(&(ownResource->paramSet), + ti_edma_resource_alloc((uint32_t *)&(ownResource->paramSet), (dev_config->max_num_params % 32 == 0) ? (dev_config->max_num_params / 32U) : (dev_config->max_num_params / 32U) + 1, @@ -495,16 +493,21 @@ static int ti_edma_deconfigure(const struct device *dev, uint32_t channel) return 0; } +static void ti_edma_chan_release(const struct device *dev, uint32_t channel) +{ + (void)ti_edma_deconfigure(dev, channel); +} + static int ti_edma_init(const struct device *dev) { - struct ti_edma_config *dev_config = dev->config; + const struct ti_edma_config *dev_config = dev->config; struct ti_edma_data *dev_data = dev->data; uint8_t instNum = dev_data->instNum; - gEdmaConfig[instNum].attrs = &(dev_config->gEdmaAttrs); - gEdmaConfig[instNum].object = &(dev_data->gEdmaObject); + gEdmaConfig[instNum].attrs = (EDMA_Attrs *)&(dev_config->gEdmaAttrs); + gEdmaConfig[instNum].object = (EDMA_Object *)&(dev_data->gEdmaObject); for (int idx = 0; idx < dev_config->num_edma_resources; idx += 3) { edma_resource_validate_and_alloc(dev, idx); @@ -551,12 +554,14 @@ static int ti_edma_configure(const struct device *dev, uint32_t channel, struct regionId = EDMA_getRegionId(edma_handle); dmaCh = tcc = channel; + dev_data->channel_data[channel].dma_slot = config->dma_slot; /* If channel is already configured, deconfigure first */ if (atomic_test_bit(dev_data->dma_ctx.atomic, channel)) { LOG_DBG("Deconfiguring and re-configuring channel %d of %s\n", channel, dev->name); testStatus = ti_edma_deconfigure(dev, channel); - if (testStatus) { /* If dealloc failed */ + if (testStatus) { + /* If dealloc failed */ LOG_ERR("Failed to deconfigure channel %d of %s\n", channel, dev->name); return testStatus; } @@ -611,7 +616,7 @@ static int ti_edma_configure(const struct device *dev, uint32_t channel, struct isr_data->cb = config->dma_callback; isr_data->args = config->user_data; - isr_data->dev = dev; + isr_data->dev = (struct device *)dev; isr_data->channel = channel; EDMA_enableEvtIntrRegion(baseAddr, dev_config->gEdmaAttrs.initPrms.regionId, @@ -666,7 +671,12 @@ static int ti_edma_start(const struct device *dev, uint32_t channel) EDMA_clrIntrRegion(baseAddr, regionId, channel); EDMA_enableTransferRegion(baseAddr, regionId, channel, EDMA_TRIG_MODE_EVENT); - EDMA_enableTransferRegion(baseAddr, regionId, channel, EDMA_TRIG_MODE_MANUAL); + /* Do a manual transfer if configured */ + if (FIELD_GET(DMA_M2P_KICKSTART_TRANSFER, + dev_data->channel_data[channel].dma_slot) == 1) { + EDMA_enableTransferRegion(baseAddr, regionId, channel, + EDMA_TRIG_MODE_MANUAL); + } break; default: @@ -677,8 +687,7 @@ static int ti_edma_start(const struct device *dev, uint32_t channel) return 0; } -static void ti_edma_get_status(const struct device *dev, uint32_t channel, - struct dma_status *status) +static int ti_edma_get_status(const struct device *dev, uint32_t channel, struct dma_status *status) { struct ti_edma_data *dev_data = dev->data; @@ -724,6 +733,8 @@ static void ti_edma_get_status(const struct device *dev, uint32_t channel, status->total_copied = 0; status->write_position = 0; status->read_position = 0; + + return 0; } static int ti_edma_stop(const struct device *dev, uint32_t channel) @@ -767,9 +778,6 @@ static int ti_edma_stop(const struct device *dev, uint32_t channel) EDMA_clrEvtRegion(baseAddr, regionId, channel); EDMA_clrIntrRegion(baseAddr, regionId, channel); - /* Clear any error status */ - uint32_t queNum = gEdmaConfig[dev_data->instNum].attrs->initPrms.queNum; - LOG_DBG("Stopped DMA transfer on channel %d", channel); return 0; } @@ -777,7 +785,7 @@ static int ti_edma_stop(const struct device *dev, uint32_t channel) static DEVICE_API(dma, ti_edma_driver_api) = { .config = ti_edma_configure, .start = ti_edma_start, - .chan_release = ti_edma_deconfigure, + .chan_release = ti_edma_chan_release, .get_status = ti_edma_get_status, .stop = ti_edma_stop, }; @@ -845,7 +853,7 @@ static DEVICE_API(dma, ti_edma_driver_api) = { }, \ }, \ .max_num_params = DT_INST_PROP(inst, edma_params), \ - .edma_resources = &edma_resources_##inst, \ + .edma_resources = (uint16_t *)&edma_resources_##inst, \ .num_edma_resources = NUM_EDMA_RESOURCES(inst), \ .register_isr = &ti_edma_register_isr_##inst, \ }; \ diff --git a/drivers/serial/Kconfig.ns16550 b/drivers/serial/Kconfig.ns16550 index fcf8c6331de27..d22b390c50e50 100644 --- a/drivers/serial/Kconfig.ns16550 +++ b/drivers/serial/Kconfig.ns16550 @@ -77,6 +77,14 @@ config UART_NS16550_TI_K3 Texas Instruments K3 SoCs by enabling a vendor specific extended register set. +config UART_NS16550_TI_EDMA + bool "TI EDMA support for NS16550" + default n + depends on UART_ASYNC_API + depends on DMA + help + This enables support for TI EDMA for Async operations. + config UART_NS16550_DW8250_DW_APB bool "Synopsys DesignWare 8250" help diff --git a/drivers/serial/uart_ns16550.c b/drivers/serial/uart_ns16550.c index 055a332d071c9..2969b9e61ea09 100644 --- a/drivers/serial/uart_ns16550.c +++ b/drivers/serial/uart_ns16550.c @@ -629,19 +629,13 @@ static uint32_t UART_operatingModeSelect(uint32_t baseAddr, uint32_t modeFlag) /* Enables DMA FIFO for UART based on input fifoConfig */ static void enable_dma_fifo(uint32_t baseAddr, uint32_t fifoConfig) { - uint32_t enhanFnBitVal, tcrTlrBitVal, tlrValue; + uint32_t enhanFnBitVal, tlrValue; uint32_t fcrValue = 0U; uint32_t lcrRegValue, tcrTlrValue, sleepMdBitVal, divRegVal, operMode; - uint32_t txGra = (fifoConfig & UART_FIFO_CONFIG_TXGRA_MASK) >> UART_FIFO_CONFIG_TXGRA_SHIFT; - uint32_t rxGra = (fifoConfig & UART_FIFO_CONFIG_RXGRA_MASK) >> UART_FIFO_CONFIG_RXGRA_SHIFT; uint32_t txTrigLvl = (fifoConfig & UART_FIFO_CONFIG_TXTRIG_MASK) >> UART_FIFO_CONFIG_TXTRIG_SHIFT; uint32_t rxTrigLvl = (fifoConfig & UART_FIFO_CONFIG_RXTRIG_MASK) >> UART_FIFO_CONFIG_RXTRIG_SHIFT; - uint32_t txClr = (fifoConfig & UART_FIFO_CONFIG_TXCLR_MASK) >> UART_FIFO_CONFIG_TXCLR_SHIFT; - uint32_t rxClr = (fifoConfig & UART_FIFO_CONFIG_RXCLR_MASK) >> UART_FIFO_CONFIG_RXCLR_SHIFT; - uint32_t dmaEnPath = - (fifoConfig & UART_FIFO_CONFIG_DMAENPATH_MASK) >> UART_FIFO_CONFIG_DMAENPATH_SHIFT; uint32_t dmaMode = (fifoConfig & UART_FIFO_CONFIG_DMAMODE_MASK) >> UART_FIFO_CONFIG_DMAMODE_SHIFT; @@ -733,7 +727,7 @@ static void enable_dma_fifo(uint32_t baseAddr, uint32_t fifoConfig) /* Restoring the value of TCRTLR bit in MCR. */ UART_regConfigModeEnable(baseAddr, UART_REG_CONFIG_MODE_A); - write_reg_fields(tcrTlrBitVal, baseAddr + UART_MCR, UART_MCR_TCR_TLR_MASK, + write_reg_fields(tcrTlrValue, baseAddr + UART_MCR, UART_MCR_TCR_TLR_MASK, UART_MCR_TCR_TLR_SHIFT); /* Restoring the value of EFR[4] to the original value. */ @@ -1817,6 +1811,10 @@ static int uart_ns16550_tx(const struct device *dev, const uint8_t *buf, size_t tx_params->active_dma_block.block_size = len; tx_params->active_dma_block.next_block = NULL; +#ifdef CONFIG_UART_NS16550_TI_EDMA + tx_params->dma_cfg.dma_slot = 1; +#endif /* CONFIG_UART_NS16550_TI_EDMA */ + ret = dma_config(tx_params->dma_dev, tx_params->dma_channel, (struct dma_config *)&tx_params->dma_cfg); diff --git a/drivers/spi/Kconfig.omap b/drivers/spi/Kconfig.omap index fd6cd83788634..c84947cc23caf 100644 --- a/drivers/spi/Kconfig.omap +++ b/drivers/spi/Kconfig.omap @@ -8,3 +8,11 @@ config SPI_OMAP_MCSPI select PINCTRL help Enable support for TI OMAP MCSPI driver. + +config SPI_DMA + bool "SPI DMA enabled" + default n + depends on SPI_ASYNC + depends on DMA + help + Enable DMA for SPI diff --git a/drivers/spi/spi_omap_mcspi.c b/drivers/spi/spi_omap_mcspi.c index 2d5faf1aa23d9..5f87ec7f2c94c 100644 --- a/drivers/spi/spi_omap_mcspi.c +++ b/drivers/spi/spi_omap_mcspi.c @@ -11,6 +11,11 @@ LOG_MODULE_REGISTER(omap_mcspi); #include #include #include "spi_context.h" +#include + +#ifdef CONFIG_SPI_DMA +#include +#endif /* CONFIG_SPI_DMA */ /* Max clock divisor for granularity of 1 (12-bit) */ #define OMAP_MCSPI_CLK_1_MAX_DIV (4096) @@ -64,6 +69,8 @@ struct omap_mcspi_regs { #define OMAP_MCSPI_CHCONF_IS BIT(18) /* Input select */ #define OMAP_MCSPI_CHCONF_DPE1 BIT(17) /* Transmission enabled for data line 1 */ #define OMAP_MCSPI_CHCONF_DPE0 BIT(16) /* Transmission enabled for data line 0 */ +#define OMAP_MCSPI_CHCONF_DMAR BIT(15) /* Enable DMA Read Request */ +#define OMAP_MCSPI_CHCONF_DMAW BIT(14) /* Enable DMA Write Request */ #define OMAP_MCSPI_CHCONF_TRM GENMASK(13, 12) /* TX/RX mode */ #define OMAP_MCSPI_CHCONF_TRM_TX_ONLY BIT(13) /* TX/RX mode - Transmit only */ #define OMAP_MCSPI_CHCONF_TRM_RX_ONLY BIT(12) /* TX/RX mode - Receive only */ @@ -86,11 +93,40 @@ struct omap_mcspi_regs { /* FIFO transfer level register */ #define OMAP_MCSPI_XFERLEVEL_WCNT GENMASK(31, 16) /* Word counter for transfer */ +#define OMAP_MCSPI_XFERLEVEL_AFL GENMASK(15, 8) /* Buffer Almost Full Trig level */ +#define OMAP_MCSPI_XFERLEVEL_AEL GENMASK(7, 0) /* Buffer Almost Empty Trig level */ #define DEV_CFG(dev) ((const struct omap_mcspi_cfg *)(dev)->config) #define DEV_DATA(dev) ((struct omap_mcspi_data *)(dev)->data) #define DEV_REGS(dev) ((struct omap_mcspi_regs *)DEVICE_MMIO_GET(dev)) +#ifdef CONFIG_SPI_DMA +struct omap_mcspi_work_struct { + struct k_work work; + const struct device *spi_dev; +}; + +struct omap_dma_data { + const struct device *dma_dev; + uint32_t dma_channel; + struct dma_config dma_cfg; + struct dma_block_config blk_cfg; +}; + +struct omap_mcspi_channel_data { + uint32_t ch_num; /* McSPI Channel Number */ + struct omap_dma_data tx_dma_data; + struct omap_dma_data rx_dma_data; + uint8_t dma_completion_flags; /* Stores the necessary completion status of DMA */ + uint8_t dma_status_flags; /* Stores the status of DMA transfer */ + struct k_sem dma_completion_sem; +}; +#endif /* CONFIG_SPI_DMA */ + +#define DMA_CHANNEL_RX_DONE_FLAG BIT(0) +#define DMA_CHANNEL_TX_DONE_FLAG BIT(1) +#define DMA_CHANNEL_ERROR_FLAG BIT(2) + struct omap_mcspi_cfg { DEVICE_MMIO_ROM; const struct pinctrl_dev_config *pinctrl; @@ -106,8 +142,39 @@ struct omap_mcspi_data { uint32_t chconf; uint32_t chctrl; uint8_t dfs; /* data frame size - word length in bytes */ +#ifdef CONFIG_SPI_DMA + struct omap_mcspi_channel_data chan_data[OMAP_MCSPI_NUM_CHANNELS]; + struct omap_mcspi_work_struct work_struct; +#endif /* CONFIG_SPI_DMA */ }; +#ifdef CONFIG_SPI_DMA +static void spi_dma_callback(const struct device *dma_dev, void *arg, uint32_t dma_channel, + int status) +{ + struct omap_mcspi_channel_data *chan_data = (struct omap_mcspi_channel_data *)arg; + + if (dma_channel == chan_data->tx_dma_data.dma_channel) { + if (status == DMA_STATUS_COMPLETE) { + chan_data->dma_status_flags |= DMA_CHANNEL_TX_DONE_FLAG; + } + } else if (dma_channel == chan_data->rx_dma_data.dma_channel) { + if (status == DMA_STATUS_COMPLETE) { + chan_data->dma_status_flags |= DMA_CHANNEL_RX_DONE_FLAG; + } + } else { + LOG_ERR("Unexpected error in dma callback function for DMA channel %d.", + dma_channel); + chan_data->dma_status_flags |= DMA_CHANNEL_ERROR_FLAG; + k_sem_give(&(chan_data->dma_completion_sem)); + } + + if (chan_data->dma_status_flags == chan_data->dma_completion_flags) { + k_sem_give(&(chan_data->dma_completion_sem)); + } +} +#endif /* CONFIG_SPI_DMA */ + static void omap_mcspi_channel_enable(const struct device *dev, bool enable) { struct omap_mcspi_regs *regs = DEV_REGS(dev); @@ -471,7 +538,200 @@ static int omap_mcspi_transceive_pio(const struct device *dev, size_t count) return count; } -static int omap_mcspi_transceive_one(const struct device *dev) +#ifdef CONFIG_SPI_DMA +static int spi_dma_rx_tx_done(struct omap_mcspi_channel_data *chan_data) +{ + int ret; + + ret = k_sem_take(&chan_data->dma_completion_sem, K_FOREVER); + if (ret != 0) { + LOG_ERR("Sem take error %d", ret); + return ret; + } + if (chan_data->dma_status_flags & DMA_CHANNEL_ERROR_FLAG) { + LOG_ERR("Unexpected IO error"); + return -EIO; + } + if (chan_data->dma_status_flags == chan_data->dma_completion_flags) { + return 0; + } + return ret; +} +static int omap_mcspi_transceive_dma(const struct device *dev, size_t *count) +{ + struct omap_mcspi_data *data = DEV_DATA(dev); + struct omap_mcspi_regs *regs = DEV_REGS(dev); + struct spi_context *ctx = &data->ctx; + const uint8_t chan = ctx->config->slave; + const uint8_t dfs = data->dfs; + const uint8_t *tx_buf = ctx->tx_buf; + uint8_t *rx_buf = ctx->rx_buf; + struct omap_dma_data *rx_dma = NULL, *tx_dma = NULL; + struct omap_mcspi_channel_data *chan_data = &data->chan_data[chan]; + + k_sem_reset(&chan_data->dma_completion_sem); /* Reset DMA Semaphore */ + + volatile uint32_t *tx_reg = ®s->CHAN[chan].TX; + + uint32_t ret; + uint32_t rx_burst_len = 1, tx_burst_len = 1; + uint32_t num_words_transferred = 0; + + if (FIELD_GET(OMAP_MCSPI_CHCONF_FFER, regs->CHAN[chan].CHCONF) && + FIELD_GET(OMAP_MCSPI_CHCONF_FFEW, regs->CHAN[chan].CHCONF)) { + rx_burst_len = tx_burst_len = data->fifo_depth / (2 * dfs); + } else if (FIELD_GET(OMAP_MCSPI_CHCONF_FFER, regs->CHAN[chan].CHCONF)) { + rx_burst_len = data->fifo_depth / (dfs); + } else if (FIELD_GET(OMAP_MCSPI_CHCONF_FFEW, regs->CHAN[chan].CHCONF)) { + tx_burst_len = data->fifo_depth / (dfs); + } + + /* DMA Rx channel config */ + if (rx_buf) { + while (ctx->current_rx->len % rx_burst_len) { + rx_burst_len--; + } + rx_dma = &(chan_data->rx_dma_data); + rx_dma->dma_cfg.source_data_size = dfs; + rx_dma->dma_cfg.dest_data_size = dfs; + rx_dma->dma_cfg.source_burst_length = rx_burst_len; + rx_dma->dma_cfg.dest_burst_length = rx_burst_len; + rx_dma->dma_cfg.user_data = (void *)chan_data; + + rx_dma->blk_cfg.source_address = (uint32_t)&(regs->CHAN[chan].RX); + rx_dma->blk_cfg.dest_address = (uint32_t)ctx->current_rx->buf; + rx_dma->blk_cfg.block_size = ctx->current_rx->len; + } + /* DMA Tx channel config */ + if (tx_buf) { + while (ctx->current_tx->len % tx_burst_len) { + tx_burst_len--; + } + + tx_dma = &(chan_data->tx_dma_data); + tx_dma->dma_cfg.source_data_size = dfs; + tx_dma->dma_cfg.dest_data_size = dfs; + tx_dma->dma_cfg.source_burst_length = tx_burst_len; + tx_dma->dma_cfg.dest_burst_length = tx_burst_len; + tx_dma->dma_cfg.user_data = (void *)chan_data; + + tx_dma->blk_cfg.source_address = (uint32_t)ctx->current_tx->buf; + tx_dma->blk_cfg.dest_address = ((uint32_t)&(regs->CHAN[chan].TX)); + tx_dma->blk_cfg.block_size = ctx->current_tx->len; + } + + /* Add DMA Trigger level for Rx and Tx */ + regs->XFERLEVEL = (OMAP_MCSPI_XFERLEVEL_WCNT & regs->XFERLEVEL) | + FIELD_PREP(OMAP_MCSPI_XFERLEVEL_AFL, (rx_burst_len * dfs - 1)) | + FIELD_PREP(OMAP_MCSPI_XFERLEVEL_AEL, (tx_burst_len * dfs - 1)); + + /* RX only */ + if (!tx_buf) { + /* write dummy value of 0 to TX FIFO */ + *tx_reg = 0; + + /* Set expected completion flag, reset the status flag */ + chan_data->dma_completion_flags = DMA_CHANNEL_RX_DONE_FLAG; + chan_data->dma_status_flags = 0; + + /* Start Rx DMA Transfer */ + ret = dma_config(rx_dma->dma_dev, rx_dma->dma_channel, &rx_dma->dma_cfg); + if (ret) { + LOG_ERR("Rx DMA configuration failed."); + return ret; + } + ret = dma_start(rx_dma->dma_dev, rx_dma->dma_channel); + if (ret) { + LOG_ERR("Rx DMA start failed."); + return ret; + } + + num_words_transferred = rx_dma->blk_cfg.block_size / dfs; + + /* TX only */ + } else if (!rx_buf) { + + /* Set expected completion flag, reset the status flag */ + chan_data->dma_completion_flags = DMA_CHANNEL_TX_DONE_FLAG; + chan_data->dma_status_flags = 0; + + /* Start Tx DMA transfer */ + ret = dma_config(tx_dma->dma_dev, tx_dma->dma_channel, &tx_dma->dma_cfg); + if (ret) { + LOG_ERR("Tx DMA configuration failed."); + return ret; + } + ret = dma_start(tx_dma->dma_dev, tx_dma->dma_channel); + if (ret) { + LOG_ERR("Tx DMA start failed."); + return ret; + } + num_words_transferred = tx_dma->blk_cfg.block_size / dfs; + + /* Both RX and TX */ + } else { + /* Set expected completion flag, reset the status flag */ + chan_data->dma_completion_flags = + DMA_CHANNEL_RX_DONE_FLAG | DMA_CHANNEL_TX_DONE_FLAG; + chan_data->dma_status_flags = 0; + + ret = dma_config(rx_dma->dma_dev, rx_dma->dma_channel, &rx_dma->dma_cfg); + if (ret) { + LOG_ERR("Rx DMA configuration failed."); + return ret; + } + ret = dma_config(tx_dma->dma_dev, tx_dma->dma_channel, &tx_dma->dma_cfg); + if (ret) { + LOG_ERR("Tx DMA configuration failed."); + return ret; + } + + /* Start Rx DMA first */ + ret = dma_start(rx_dma->dma_dev, rx_dma->dma_channel); + if (ret) { + LOG_ERR("Rx DMA start failed."); + return ret; + } + + /* Start Tx DMA */ + ret = dma_start(tx_dma->dma_dev, tx_dma->dma_channel); + if (ret) { + LOG_ERR("Tx DMA start failed."); + return ret; + } + num_words_transferred = tx_dma->blk_cfg.block_size / dfs; + } + /* Enable channel */ + omap_mcspi_channel_enable(dev, true); + + ret = spi_dma_rx_tx_done(chan_data); + if (ret) { + return ret; + } + *count = *count - num_words_transferred; + + /* Disable channel */ + omap_mcspi_channel_enable(dev, false); + + /* update rx buffer */ + spi_context_update_rx(ctx, data->dfs, num_words_transferred); + + /* update tx buffer */ + spi_context_update_tx(ctx, data->dfs, num_words_transferred); + + /* Stop DMA */ + if (rx_buf) { + dma_stop(rx_dma->dma_dev, rx_dma->dma_channel); + } + if (tx_buf) { + dma_stop(tx_dma->dma_dev, tx_dma->dma_channel); + } + + return ret; +} +#endif /* CONFIG_SPI_DMA */ + +static int omap_mcspi_transceive_one(const struct device *dev, bool asynchronous) { struct omap_mcspi_data *data = DEV_DATA(dev); struct omap_mcspi_regs *regs = DEV_REGS(dev); @@ -513,11 +773,23 @@ static int omap_mcspi_transceive_one(const struct device *dev) data->chconf &= ~OMAP_MCSPI_CHCONF_FFEW; } + /* Don't let Turbo Mode interfere with SPI+DMA */ +#ifndef CONFIG_SPI_DMA if (count > 1) { data->chconf |= OMAP_MCSPI_CHCONF_TURBO; } else { data->chconf &= ~OMAP_MCSPI_CHCONF_TURBO; } +#endif /* CONFIG_SPI_DMA */ + +#ifdef CONFIG_SPI_DMA + if (rx_buf) { + data->chconf |= OMAP_MCSPI_CHCONF_DMAR; + } + if (tx_buf) { + data->chconf |= OMAP_MCSPI_CHCONF_DMAW; + } +#endif /* write chconf and chctrl */ regs->CHAN[chan].CHCONF = data->chconf; @@ -526,12 +798,27 @@ static int omap_mcspi_transceive_one(const struct device *dev) /* write WCNT */ regs->XFERLEVEL = FIELD_PREP(OMAP_MCSPI_XFERLEVEL_WCNT, count); +#ifdef CONFIG_SPI_DMA + if (asynchronous) { + /* + * NOTE: Only one channel of McSPI can use FIFO + * DFS length may vary among channels if using multiple channels at a time + * Consider moving dfs size to specific channel data struct + */ + while (count > 0) { + rv = omap_mcspi_transceive_dma(dev, &count); + if (rv) { + LOG_ERR("DMA transceive failed"); + return rv; + } + } + return 0; + } +#endif /* CONFIG_SPI_DMA*/ + /* enable channel */ omap_mcspi_channel_enable(dev, true); - /* we only support PIO for now - * TODO: add DMA - */ rv = omap_mcspi_transceive_pio(dev, count); if (rv) { return -EIO; @@ -547,6 +834,34 @@ static int omap_mcspi_transceive_one(const struct device *dev) return 0; } +#ifdef CONFIG_SPI_DMA +static void omap_mcspi_transceive_work_handler(struct k_work *work) +{ + + struct omap_mcspi_work_struct *work_struct = + CONTAINER_OF(work, struct omap_mcspi_work_struct, work); + const struct device *dev = work_struct->spi_dev; + int ret = 0; + + struct omap_mcspi_data *data = DEV_DATA(dev); + struct spi_context *ctx = &data->ctx; + + while (spi_context_tx_on(ctx) || spi_context_rx_on(ctx)) { + ret = omap_mcspi_transceive_one(dev, true); + if (ret < 0) { + LOG_ERR("Transaction failed, TX/RX left: %zu/%zu", + spi_context_tx_len_left(ctx, data->dfs), + spi_context_rx_len_left(ctx, data->dfs)); + goto cleanup; + } + } + +cleanup: + spi_context_cs_control(ctx, false); + spi_context_complete(ctx, dev, ret); +} +#endif /* CONFIG_SPI_DMA */ + static int omap_mcspi_transceive_all(const struct device *dev, const struct spi_config *config, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, bool asynchronous, @@ -572,8 +887,21 @@ static int omap_mcspi_transceive_all(const struct device *dev, const struct spi_ spi_context_cs_control(ctx, true); +#ifdef CONFIG_SPI_DMA + if (asynchronous) { + k_work_init(&(data->work_struct.work), omap_mcspi_transceive_work_handler); + ret = k_work_submit(&(data->work_struct.work)); + + if (ret < 0) { + LOG_ERR("Failed to submit workqueue"); + goto cleanup; + } + return 0; + } +#endif + while (spi_context_tx_on(ctx) || spi_context_rx_on(ctx)) { - ret = omap_mcspi_transceive_one(dev); + ret = omap_mcspi_transceive_one(dev, false); if (ret < 0) { LOG_ERR("Transaction failed, TX/RX left: %zu/%zu", spi_context_tx_len_left(ctx, data->dfs), @@ -588,6 +916,7 @@ static int omap_mcspi_transceive_all(const struct device *dev, const struct spi_ if (!(config->operation & SPI_LOCK_ON)) { spi_context_release(ctx, ret); } + return ret; } @@ -605,7 +934,7 @@ static int omap_mcspi_transceive_async(const struct device *dev, const struct sp void *userdata) { /* wait for DMA to be implemented to use IRQ and ASYNC */ - return -ENOTSUP; + return omap_mcspi_transceive_all(dev, config, tx_bufs, rx_bufs, true, callback, userdata); } #endif /* CONFIG_SPI_ASYNC */ @@ -642,6 +971,22 @@ static int omap_mcspi_init(const struct device *dev) data->fifo_depth = FIELD_GET(OMAP_MCSPI_HWINFO_FFNBYTE, regs->HWINFO) << 4; +#ifdef CONFIG_SPI_DMA + /* Ensure work_struct is pointing back to spi_dev */ + data->work_struct.spi_dev = dev; + + struct omap_mcspi_channel_data *chan_data; + + for (int i = 0; i < OMAP_MCSPI_NUM_CHANNELS; i++) { + chan_data = &data->chan_data[i]; + k_sem_init(&chan_data->dma_completion_sem, 0, 1); + + chan_data->tx_dma_data.dma_cfg.head_block = &(chan_data->tx_dma_data.blk_cfg); + chan_data->rx_dma_data.dma_cfg.head_block = &(chan_data->rx_dma_data.blk_cfg); + } + +#endif + spi_context_unlock_unconditionally(&data->ctx); return 0; @@ -656,6 +1001,47 @@ static int omap_mcspi_release(const struct device *dev, const struct spi_config return 0; } +#if defined(CONFIG_SPI_DMA) + +#define SPI_DMA_CHANNEL_INIT(n, dir, ch_dir, burst_len) \ + .dma_dev = DEVICE_DT_GET(DT_INST_DMAS_CTLR_BY_NAME(n, dir)), \ + .dma_channel = DT_INST_DMAS_CELL_BY_NAME(n, dir, channel), \ + .dma_cfg = { \ + .channel_direction = ch_dir, \ + .source_data_size = 1, \ + .dest_data_size = 1, \ + .source_burst_length = burst_len, \ + .dest_burst_length = burst_len, \ + .block_count = 1, \ + .dma_callback = spi_dma_callback, \ + .complete_callback_en = true, \ + }, + +#define SPI_DMA_CHANNEL(n, dir, ch_dir, burst_len) \ + .dir##_dma_data = {COND_CODE_1( \ + DT_INST_DMAS_HAS_NAME(n, dir), \ + (SPI_DMA_CHANNEL_INIT(n, dir, ch_dir, burst_len)), (NULL))}, + +#define SPI_CHAN_DATA_STRUCT_INIT(index, n) \ + {.ch_num = index, \ + SPI_DMA_CHANNEL(n, rx, PERIPHERAL_TO_MEMORY, 1) \ + SPI_DMA_CHANNEL(n, tx, MEMORY_TO_PERIPHERAL, 1)} + +#define SPI_CHAN_NUM_DUMMY_MACRO(i, _) i +#define SPI_CHAN_DATA_INIT(n) \ + .chan_data = {FOR_EACH_FIXED_ARG(SPI_CHAN_DATA_STRUCT_INIT, (,), n, \ + LISTIFY(4, SPI_CHAN_NUM_DUMMY_MACRO, (,)))} + +#else +#define SPI_CHAN_DATA_INIT(n) +#endif /* CONFIG_SPI_DMA */ + +/* + * TODO: Every channel in McSPI has a unique pair of DMA channels + * In DTS, need to define as rx0, tx0, rx1, tx1... + * How to pull SPI Channel number from DTS? + */ + static DEVICE_API(spi, omap_mcspi_api) = { .transceive = omap_mcspi_transceive, #ifdef CONFIG_SPI_ASYNC @@ -677,7 +1063,7 @@ static DEVICE_API(spi, omap_mcspi_api) = { static struct omap_mcspi_data omap_mcspi_data_##n = { \ SPI_CONTEXT_INIT_LOCK(omap_mcspi_data_##n, ctx), \ SPI_CONTEXT_INIT_SYNC(omap_mcspi_data_##n, ctx), \ - SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(n), ctx)}; \ + SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(n), ctx) SPI_CHAN_DATA_INIT(n)}; \ \ SPI_DEVICE_DT_INST_DEFINE(n, omap_mcspi_init, NULL, &omap_mcspi_data_##n, \ &omap_mcspi_config_##n, POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, \ diff --git a/dts/arm/ti/am26x/am261x.dtsi b/dts/arm/ti/am26x/am261x.dtsi index 7e86619320d3d..27dda06a9091e 100644 --- a/dts/arm/ti/am26x/am261x.dtsi +++ b/dts/arm/ti/am26x/am261x.dtsi @@ -3,6 +3,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ +/dts-v1/; #include #include diff --git a/dts/arm/ti/am26x/am261x_r5f0_0.dtsi b/dts/arm/ti/am26x/am261x_r5f0_0.dtsi index e7ded3e9bf432..54bd7da372fc2 100644 --- a/dts/arm/ti/am26x/am261x_r5f0_0.dtsi +++ b/dts/arm/ti/am26x/am261x_r5f0_0.dtsi @@ -64,3 +64,23 @@ core-id = <0>; }; +/* NOTE: Only Channel 0 of McSPI currently supports DMA */ +&mcspi0 { + dmas = <&edma0 13>, <&edma0 14>; + dma-names = "tx", "rx"; +}; + +&mcspi1 { + dmas = <&edma0 15>, <&edma0 16>; + dma-names = "tx", "rx"; +}; + +&mcspi2 { + dmas = <&edma0 17>, <&edma0 18>; + dma-names = "tx", "rx"; +}; + +&mcspi3 { + dmas = <&edma0 19>, <&edma0 20>; + dma-names = "tx", "rx"; +}; diff --git a/dts/arm/ti/am26x/am261x_r5f0_1.dtsi b/dts/arm/ti/am26x/am261x_r5f0_1.dtsi index f6c442c74840c..7b5ca4aa58eb6 100644 --- a/dts/arm/ti/am26x/am261x_r5f0_1.dtsi +++ b/dts/arm/ti/am26x/am261x_r5f0_1.dtsi @@ -66,3 +66,23 @@ }; +/* NOTE: Only Channel 0 of McSPI currently supports DMA */ +&mcspi0 { + dmas = <&edma0 45>, <&edma0 46>; + dma-names = "tx", "rx"; +}; + +&mcspi1 { + dmas = <&edma0 47>, <&edma0 48>; + dma-names = "tx", "rx"; +}; + +&mcspi2 { + dmas = <&edma0 49>, <&edma0 50>; + dma-names = "tx", "rx"; +}; + +&mcspi3 { + dmas = <&edma0 51>, <&edma0 52>; + dma-names = "tx", "rx"; +}; diff --git a/dts/bindings/dma/ti,edma.yaml b/dts/bindings/dma/ti,edma.yaml index ec4d928c51ea1..c93aafc97da8e 100644 --- a/dts/bindings/dma/ti,edma.yaml +++ b/dts/bindings/dma/ti,edma.yaml @@ -18,6 +18,9 @@ description: | - For M2P/P2M, Block size MUST be a multiple of Burst Length (application must pad appropriately) - This driver does NOT support chaining, linked transfers, or gather/scatter operations. + DMA Slot options: + - Bit 0 is set to 1 to enable Manual Transfer at start of M2P + compatible: "ti,edma" include: dma-controller.yaml diff --git a/include/zephyr/drivers/dma/dma_ti_edma.h b/include/zephyr/drivers/dma/dma_ti_edma.h index a2b7d6b64f34e..f34fd94d57ba4 100644 --- a/include/zephyr/drivers/dma/dma_ti_edma.h +++ b/include/zephyr/drivers/dma/dma_ti_edma.h @@ -34,6 +34,10 @@ struct EDMA_ISR_Data { struct EDMA_Channel { enum dma_channel_direction chan_dir; struct EDMA_ISR_Data isr_data; + uint8_t dma_slot; }; -#endif /* __TI_EDMA_HEADERS__ */ +/* These macros are bitfields for the DMA Slot */ +#define DMA_M2P_KICKSTART_TRANSFER BIT(0) + +#endif /* __TI_EDMA_HEADERS__ */ diff --git a/soc/ti/am26x/am261x/CMakeLists.txt b/soc/ti/am26x/am261x/CMakeLists.txt index 92f3c8e0b9da9..acefee83ea5f2 100644 --- a/soc/ti/am26x/am261x/CMakeLists.txt +++ b/soc/ti/am26x/am261x/CMakeLists.txt @@ -6,7 +6,7 @@ zephyr_include_directories(.) -if( CONFIG_SOC_SERIES_AM261X_R5F ) +if(CONFIG_SOC_SERIES_AM261X_R5F) zephyr_sources(r5/soc.c) zephyr_include_directories(r5) diff --git a/soc/ti/am26x/am261x/Kconfig b/soc/ti/am26x/am261x/Kconfig index f6b29e1337588..7840d2aaecad2 100644 --- a/soc/ti/am26x/am261x/Kconfig +++ b/soc/ti/am26x/am261x/Kconfig @@ -10,6 +10,7 @@ config SOC_SERIES_AM261X_R5F select CPU_CORTEX_R5 select CPU_HAS_ICACHE select CPU_HAS_DCACHE + select CPU_HAS_FPU select CPU_HAS_ARM_MPU select DMA select FPU @@ -21,10 +22,4 @@ config SOC_SERIES_AM261X_R5F select VIM config SOC_PART_NUMBER - default "AM2612" if SOC_AM261X_R5F0_0 || SOC_AM261X_R5F0_1 - -config CORTEX_R_BOOT_ADDRESS - hex "Cortex-R Boot Address" - default 0x0 - help - This option specifies the boot address for the Cortex-R core + default "AM2612" if SOC_AM261X_R5F0_0 || SOC_AM261X_R5F0_1 \ No newline at end of file diff --git a/soc/ti/am26x/am261x/Kconfig.defconfig b/soc/ti/am26x/am261x/Kconfig.defconfig index 0cc9c5e1dd41c..2d21814c1d486 100644 --- a/soc/ti/am26x/am261x/Kconfig.defconfig +++ b/soc/ti/am26x/am261x/Kconfig.defconfig @@ -13,22 +13,13 @@ config MAX_CPUS_NUM config KERNEL_ENTRY default "_vector_table" if SOC_SERIES_AM261X_R5F -config SOC_SERIES - default "am261x" - config SYS_CLOCK_HW_CYCLES_PER_SEC -# Input frequency to RTI is 250MHz, but prescaler halves frequency to 125MHz by default - default 125000000 if SOC_PACKAGE_ZFG + # Input frequency to RTI is 250MHz, but prescaler halves frequency to 125MHz by default + default 125000000 config NUM_IRQS default 222 -config SRAM_SIZE - default 1536 - -config SRAM_BASE_ADDRESS - default 0x70000000 - config ARM_MPU default y if SOC_SERIES_AM261X_R5F @@ -47,8 +38,16 @@ choice UART_NS16550_VARIANT default UART_NS16550_VARIANT_NS16750 endchoice +config UART_NS16550_TI_EDMA + default y if SOC_SERIES_AM261X_R5F + endif # SERIAL +if SPI + config SPI_ASYNC + default y if SOC_SERIES_AM261X_R5F +endif # SPI + config DCACHE_LINE_SIZE default 32 if CPU_HAS_DCACHE diff --git a/soc/ti/am26x/am261x/Kconfig.soc b/soc/ti/am26x/am261x/Kconfig.soc index 7a7befd86c429..ec0df9e5bb796 100644 --- a/soc/ti/am26x/am261x/Kconfig.soc +++ b/soc/ti/am26x/am261x/Kconfig.soc @@ -4,7 +4,6 @@ # # SPDX-License-Identifier: Apache-2.0 - config SOC_SERIES_AM261X bool "TI AM261x Series MCU" select SOC_FAMILY_TI_AM26X @@ -14,36 +13,19 @@ config SOC_SERIES_AM261X config SOC_SERIES_AM261X_R5F bool select SOC_SERIES_AM261X - help - Enable support for TI AM261X R5 MCU config SOC_AM261X_R5F0_0 - bool "TI AM261X R5F Core 0" + bool select SOC_SERIES_AM261X_R5F - help - Enable support for TI AM261X R5F Core 0 config SOC_AM261X_R5F0_1 - bool "TI AM261X R5F Core 1" + bool select SOC_SERIES_AM261X_R5F - help - Enable support for TI AM261X R5F Core 1 config SOC_AM2612_R5F bool default y if SOC_AM261X_R5F0_0 || SOC_AM261X_R5F0_1 -config SOC_SERIES_AM261X_PACKAGE - string - default "ZFG" if SOC_PACKAGE_ZFG - help - This option specifies the package variant - -config SOC_PACKAGE_ZFG - bool "ZFG package variant" - help - Package variant with 500MHz R5F cores - config SOC_SERIES default "am261x" if SOC_SERIES_AM261X @@ -55,4 +37,4 @@ config CORES_IN_LOCKSTEP_MODE default n help Set this symbol to y using overlay file if the R5F cores - are operating in lockstep mode + are operating in lockstep mode \ No newline at end of file diff --git a/soc/ti/am26x/am261x/common/xbar_configs.c b/soc/ti/am26x/am261x/common/xbar_configs.c index 22081833d2224..7f3978dc5bf47 100644 --- a/soc/ti/am26x/am261x/common/xbar_configs.c +++ b/soc/ti/am26x/am261x/common/xbar_configs.c @@ -89,6 +89,51 @@ void configure_dma_xbars(void) CSL_EDMA_TRIG_XBAR_U_BASE, DT_DMAS_CELL_BY_NAME(DT_NODELABEL(uart5), tx, channel), DMA_TRIG_XBAR_USART5_DMA_0); /* Tx */ #endif -#endif /* DT_NODE_HAS_STATUS(DT_NODELABEL(uart5), okay) */ +#endif + +/* NOTE: Enabling for Channel 0 of McSPI by default */ +#if DT_NODE_HAS_STATUS(DT_NODELABEL(mcspi0), okay) +#if DT_DMAS_HAS_NAME(DT_NODELABEL(mcspi0), rx) && DT_DMAS_HAS_NAME(DT_NODELABEL(mcspi0), tx) + SOC_xbarSelectEdmaTrigXbarInputSource( + CSL_EDMA_TRIG_XBAR_U_BASE, DT_DMAS_CELL_BY_NAME(DT_NODELABEL(mcspi0), rx, channel), + DMA_TRIG_XBAR_SPI0_DMA_READ_REQ0); /* Rx */ + SOC_xbarSelectEdmaTrigXbarInputSource( + CSL_EDMA_TRIG_XBAR_U_BASE, DT_DMAS_CELL_BY_NAME(DT_NODELABEL(mcspi0), tx, channel), + DMA_TRIG_XBAR_SPI0_DMA_WRITE_REQ0); /* Tx */ +#endif +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(mcspi1), okay) +#if DT_DMAS_HAS_NAME(DT_NODELABEL(mcspi1), rx) && DT_DMAS_HAS_NAME(DT_NODELABEL(mcspi1), tx) + SOC_xbarSelectEdmaTrigXbarInputSource( + CSL_EDMA_TRIG_XBAR_U_BASE, DT_DMAS_CELL_BY_NAME(DT_NODELABEL(mcspi1), rx, channel), + DMA_TRIG_XBAR_SPI1_DMA_READ_REQ0); /* Rx */ + SOC_xbarSelectEdmaTrigXbarInputSource( + CSL_EDMA_TRIG_XBAR_U_BASE, DT_DMAS_CELL_BY_NAME(DT_NODELABEL(mcspi1), tx, channel), + DMA_TRIG_XBAR_SPI1_DMA_WRITE_REQ0); /* Tx */ +#endif +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(mcspi2), okay) +#if DT_DMAS_HAS_NAME(DT_NODELABEL(mcspi2), rx) && DT_DMAS_HAS_NAME(DT_NODELABEL(mcspi2), tx) + SOC_xbarSelectEdmaTrigXbarInputSource( + CSL_EDMA_TRIG_XBAR_U_BASE, DT_DMAS_CELL_BY_NAME(DT_NODELABEL(mcspi2), rx, channel), + DMA_TRIG_XBAR_SPI2_DMA_READ_REQ0); /* Rx */ + SOC_xbarSelectEdmaTrigXbarInputSource( + CSL_EDMA_TRIG_XBAR_U_BASE, DT_DMAS_CELL_BY_NAME(DT_NODELABEL(mcspi2), tx, channel), + DMA_TRIG_XBAR_SPI2_DMA_WRITE_REQ0); /* Tx */ +#endif +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(mcspi3), okay) +#if DT_DMAS_HAS_NAME(DT_NODELABEL(mcspi3), rx) && DT_DMAS_HAS_NAME(DT_NODELABEL(mcspi3), tx) + SOC_xbarSelectEdmaTrigXbarInputSource( + CSL_EDMA_TRIG_XBAR_U_BASE, DT_DMAS_CELL_BY_NAME(DT_NODELABEL(mcspi3), rx, channel), + DMA_TRIG_XBAR_SPI3_DMA_READ_REQ0); /* Rx */ + SOC_xbarSelectEdmaTrigXbarInputSource( + CSL_EDMA_TRIG_XBAR_U_BASE, DT_DMAS_CELL_BY_NAME(DT_NODELABEL(mcspi3), tx, channel), + DMA_TRIG_XBAR_SPI3_DMA_WRITE_REQ0); /* Tx */ +#endif +#endif } #endif /* CONFIG_DMA */