Merge branch 'bugfix/esp32p4_sdmmc_dma_burst_size' into 'master'

feat(sdmmc): add dma_burst_size config, fix DMA to PSRAM on esp32p4

See merge request espressif/esp-idf!52908
This commit is contained in:
morris
2026-09-20 14:46:49 +08:00
6 changed files with 67 additions and 0 deletions

View File

@@ -22,6 +22,7 @@ extern "C" {
typedef struct {
uint32_t event_queue_items; ///< Event queue items. If 0, fallback to default queue item number (4)
uint32_t dma_desc_num; ///< Number of DMA descriptor, fallback to default dma descriptor number (4)
size_t dma_burst_size; ///< DMA burst size in bytes, a power of two in 4..256. 0 for the default, 1 to disable the burst
} sd_host_sdmmc_cfg_t;
/**

View File

@@ -76,6 +76,11 @@ esp_err_t sd_host_create_sdmmc_controller(const sd_host_sdmmc_cfg_t *config, sd_
esp_err_t ret = ESP_FAIL;
ESP_RETURN_ON_FALSE(config && ret_handle, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
size_t burst_size = config->dma_burst_size ? config->dma_burst_size : SDMMC_LL_DMA_BURST_SIZE_DEFAULT;
ESP_RETURN_ON_FALSE(burst_size == 1 ||
(burst_size >= 4 && burst_size <= 256 && (burst_size & (burst_size - 1)) == 0),
ESP_ERR_INVALID_ARG, TAG, "invalid dma_burst_size");
sd_host_sdmmc_ctlr_t *ctlr = heap_caps_calloc(1, sizeof(sd_host_sdmmc_ctlr_t), SD_HOST_SDMMC_MEM_ALLOC_CAPS);
ESP_RETURN_ON_FALSE(ctlr, ESP_ERR_NO_MEM, TAG, "no mem for sd host controller context");
@@ -127,6 +132,7 @@ esp_err_t sd_host_create_sdmmc_controller(const sd_host_sdmmc_cfg_t *config, sd_
sdmmc_ll_enable_interrupt(ctlr->hal.dev, 0xffffffff, false);
sdmmc_ll_enable_global_interrupt(ctlr->hal.dev, false);
sdmmc_ll_init_dma(ctlr->hal.dev);
sdmmc_ll_set_dma_burst_size(ctlr->hal.dev, burst_size);
ctlr->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED;
ctlr->drv.del_ctlr = sd_host_del_sdmmc_controller;

View File

@@ -88,6 +88,7 @@ extern "C" {
#define SDMMC_LL_HOST_CTLR_NUMS 1U
#define SDMMC_LL_DEFAULT_DIV 2
#define SDMMC_LL_DMA_BURST_SIZE_DEFAULT 1
typedef enum {
SDMMC_LL_DELAY_PHASE_0,
@@ -689,6 +690,20 @@ static inline void sdmmc_ll_init_dma(sdmmc_dev_t *hw)
hw->idinten.ti = 1;
}
/**
* @brief Set the burst size of the internal DMA
*
* @param hw hardware instance address
* @param burst_size burst size in bytes, 1 to disable the data burst,
* otherwise a power of two between 4 and 256
*/
static inline void sdmmc_ll_set_dma_burst_size(sdmmc_dev_t *hw, size_t burst_size)
{
HAL_ASSERT(burst_size == 1 ||
(burst_size >= 4 && burst_size <= 256 && (burst_size & (burst_size - 1)) == 0));
hw->fifoth.dw_dma_mts = (burst_size == 1) ? 0 : (__builtin_ctz(burst_size) - 1);
}
/**
* @brief Enable DMA
*

View File

@@ -96,6 +96,7 @@ extern "C" {
#define SDMMC_LL_SDR50_SUPPORTED 1
#define SDMMC_LL_DEFAULT_DIV 2
#define SDMMC_LL_DMA_BURST_SIZE_DEFAULT 16
/**
* SDMMC delay phase
@@ -878,6 +879,20 @@ static inline void sdmmc_ll_init_dma(sdmmc_dev_t *hw)
hw->idinten.ti = 1;
}
/**
* @brief Set the burst size of the internal DMA
*
* @param hw hardware instance address
* @param burst_size burst size in bytes, 1 to disable the data burst,
* otherwise a power of two between 4 and 256
*/
static inline void sdmmc_ll_set_dma_burst_size(sdmmc_dev_t *hw, size_t burst_size)
{
HAL_ASSERT(burst_size == 1 ||
(burst_size >= 4 && burst_size <= 256 && (burst_size & (burst_size - 1)) == 0));
hw->fifoth.dma_multiple_transaction_size = (burst_size == 1) ? 0 : (__builtin_ctz(burst_size) - 1);
}
/**
* @brief Enable DMA
*

View File

@@ -90,6 +90,7 @@ extern "C" {
#define SDMMC_LL_DELAY_PHASE_SUPPORTED 1
#define SDMMC_LL_DEFAULT_DIV 2
#define SDMMC_LL_DMA_BURST_SIZE_DEFAULT 1
/**
* SDMMC delay phase
@@ -753,6 +754,20 @@ static inline void sdmmc_ll_init_dma(sdmmc_dev_t *hw)
hw->idinten.ti = 1;
}
/**
* @brief Set the burst size of the internal DMA
*
* @param hw hardware instance address
* @param burst_size burst size in bytes, 1 to disable the data burst,
* otherwise a power of two between 4 and 256
*/
static inline void sdmmc_ll_set_dma_burst_size(sdmmc_dev_t *hw, size_t burst_size)
{
HAL_ASSERT(burst_size == 1 ||
(burst_size >= 4 && burst_size <= 256 && (burst_size & (burst_size - 1)) == 0));
hw->fifoth.dw_dma_mts = (burst_size == 1) ? 0 : (__builtin_ctz(burst_size) - 1);
}
/**
* @brief Enable DMA
*

View File

@@ -97,6 +97,7 @@ extern "C" {
#define SDMMC_LL_SDR50_SUPPORTED 1
#define SDMMC_LL_DEFAULT_DIV 8
#define SDMMC_LL_DMA_BURST_SIZE_DEFAULT 64
/**
* SDMMC delay phase
@@ -826,6 +827,20 @@ static inline void sdmmc_ll_init_dma(sdmmc_dev_t *hw)
hw->bmod.bmod_pbl = 0x7;
}
/**
* @brief Set the burst size of the internal DMA
*
* @param hw hardware instance address
* @param burst_size burst size in bytes, 1 to disable the data burst,
* otherwise a power of two between 4 and 256
*/
static inline void sdmmc_ll_set_dma_burst_size(sdmmc_dev_t *hw, size_t burst_size)
{
HAL_ASSERT(burst_size == 1 ||
(burst_size >= 4 && burst_size <= 256 && (burst_size & (burst_size - 1)) == 0));
hw->fifoth.dma_multiple_transaction_size = (burst_size == 1) ? 0 : (__builtin_ctz(burst_size) - 1);
}
/**
* @brief Enable DMA
*