mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-03 03:31:41 +03:00
refactor(spi): move sleep retention config into driver layer
Move per-target GPSPI regdma retention descriptors out of esp_hal_gpspi and into esp_driver_spi so the driver owns its backup scope and restore sequence.
This commit is contained in:
@@ -13,6 +13,9 @@ if(CONFIG_SOC_GPSPI_SUPPORTED)
|
||||
"src/gpspi/spi_master.c"
|
||||
"src/gpspi/spi_slave.c"
|
||||
)
|
||||
if(CONFIG_SOC_PAU_SUPPORTED)
|
||||
list(APPEND srcs "src/${target}/spi_retention.c")
|
||||
endif()
|
||||
|
||||
if(NOT CONFIG_SOC_GDMA_SUPPORTED)
|
||||
list(APPEND srcs "src/gpspi/spi_dma.c")
|
||||
|
||||
@@ -8,8 +8,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <esp_intr_alloc.h>
|
||||
#include "esp_pm.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "esp_macros.h"
|
||||
#include "soc/soc.h" //for SOC_NON_CACHEABLE_OFFSET_SRAM
|
||||
#include "driver/spi_common.h"
|
||||
#include "hal/spi_types.h"
|
||||
@@ -17,14 +18,16 @@
|
||||
#include "esp_private/spi_dma.h"
|
||||
#include "esp_private/gdma.h"
|
||||
#include "esp_private/spi_share_hw_ctrl.h"
|
||||
#if SOC_PAU_SUPPORTED
|
||||
#include "soc/regdma.h"
|
||||
#include "soc/retention_periph_defs.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#define SPI_ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
|
||||
|
||||
//NOTE!! If both A and B are not defined, '#if (A==B)' is true, because GCC use 0 stand for undefined symbol
|
||||
#if SOC_GPSPI_SUPPORTED && defined(SOC_GDMA_BUS_AXI) && (SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AXI)
|
||||
#define DMA_DESC_MEM_ALIGN_SIZE 8
|
||||
@@ -81,6 +84,16 @@ typedef struct {
|
||||
spi_dma_desc_t *dmadesc_rx; ///< DMA descriptor array for RX
|
||||
} spi_dma_ctx_t;
|
||||
|
||||
#if SOC_PAU_SUPPORTED
|
||||
typedef struct {
|
||||
const periph_retention_module_t module_id;
|
||||
const regdma_entries_config_t *entry_array;
|
||||
uint32_t array_size;
|
||||
} spi_reg_retention_info_t;
|
||||
|
||||
extern const spi_reg_retention_info_t spi_reg_retention_info[SOC_SPI_PERIPH_NUM - 1]; // -1 to except mspi
|
||||
#endif
|
||||
|
||||
/// Destructor called when a bus is deinitialized.
|
||||
typedef esp_err_t (*spi_destroy_func_t)(void*);
|
||||
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include "esp_private/spi_common_internal.h"
|
||||
#include "soc/spi_periph.h"
|
||||
|
||||
/**
|
||||
* Backup registers in Light sleep: (total cnt 29)
|
||||
*
|
||||
* cmd
|
||||
* addr
|
||||
* ctrl
|
||||
* clock
|
||||
* user
|
||||
* user1
|
||||
* user2
|
||||
* ms_dlen
|
||||
* misc
|
||||
* dma_conf
|
||||
* dma_int_ena
|
||||
* data_buf[0-15] // slave driver only
|
||||
* slave
|
||||
* slave1
|
||||
*/
|
||||
#define SPI_RETENTION_REGS_CNT 29
|
||||
static const uint32_t spi_regs_map[4] = {0x31ff, 0x33fffc0, 0x0, 0x0};
|
||||
#define SPI_REG_RETENTION_ENTRIES(num) { \
|
||||
[0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_GPSPI_LINK(0), \
|
||||
REG_SPI_BASE(num), REG_SPI_BASE(num), \
|
||||
SPI_RETENTION_REGS_CNT, 0, 0, \
|
||||
spi_regs_map[0], spi_regs_map[1], \
|
||||
spi_regs_map[2], spi_regs_map[3]), \
|
||||
.owner = ENTRY(0) | ENTRY(2) }, \
|
||||
/* Additional interrupt setting is required by idf SPI drivers after register recovered */ \
|
||||
[1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_GPSPI_LINK(1), \
|
||||
SPI_DMA_INT_SET_REG(num), \
|
||||
SPI_TRANS_DONE_INT_SET | SPI_DMA_SEG_TRANS_DONE_INT_SET | SPI_SLV_CMD7_INT_SET | SPI_SLV_CMD8_INT_SET , \
|
||||
UINT32_MAX, 1, 0), \
|
||||
.owner = ENTRY(0) | ENTRY(2) }, \
|
||||
}
|
||||
|
||||
static const regdma_entries_config_t spi2_regs_retention[] = SPI_REG_RETENTION_ENTRIES(2); // '2' for GPSPI2
|
||||
|
||||
const spi_reg_retention_info_t spi_reg_retention_info[SOC_SPI_PERIPH_NUM - 1] = { // '-1' to except mspi
|
||||
{
|
||||
.module_id = SLEEP_RETENTION_MODULE_GPSPI2,
|
||||
.entry_array = spi2_regs_retention,
|
||||
.array_size = ARRAY_SIZE(spi2_regs_retention),
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include "esp_private/spi_common_internal.h"
|
||||
#include "soc/spi_periph.h"
|
||||
|
||||
/**
|
||||
* Backup registers in Light sleep: (total cnt 29)
|
||||
*
|
||||
* cmd
|
||||
* addr
|
||||
* ctrl
|
||||
* clock
|
||||
* user
|
||||
* user1
|
||||
* user2
|
||||
* ms_dlen
|
||||
* misc
|
||||
* dma_conf
|
||||
* dma_int_ena
|
||||
* data_buf[0-15] // slave driver only
|
||||
* slave
|
||||
* slave1
|
||||
*/
|
||||
#define SPI_RETENTION_REGS_CNT 29
|
||||
static const uint32_t spi_regs_map[4] = {0x31ff, 0x33fffc0, 0x0, 0x0};
|
||||
#define SPI_REG_RETENTION_ENTRIES(num) { \
|
||||
[0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_GPSPI_LINK(0), \
|
||||
REG_SPI_BASE(num), REG_SPI_BASE(num), \
|
||||
SPI_RETENTION_REGS_CNT, 0, 0, \
|
||||
spi_regs_map[0], spi_regs_map[1], \
|
||||
spi_regs_map[2], spi_regs_map[3]), \
|
||||
.owner = ENTRY(0) | ENTRY(2) }, \
|
||||
/* Additional interrupt setting is required by idf SPI drivers after register recovered */ \
|
||||
[1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_GPSPI_LINK(1), \
|
||||
SPI_DMA_INT_SET_REG(num), \
|
||||
SPI_TRANS_DONE_INT_SET | SPI_DMA_SEG_TRANS_DONE_INT_SET | SPI_SLV_CMD7_INT_SET | SPI_SLV_CMD8_INT_SET , \
|
||||
UINT32_MAX, 1, 0), \
|
||||
.owner = ENTRY(0) | ENTRY(2) }, \
|
||||
}
|
||||
|
||||
static const regdma_entries_config_t spi2_regs_retention[] = SPI_REG_RETENTION_ENTRIES(2); // '2' for GPSPI2
|
||||
|
||||
const spi_reg_retention_info_t spi_reg_retention_info[SOC_SPI_PERIPH_NUM - 1] = { // '-1' to except mspi
|
||||
{
|
||||
.module_id = SLEEP_RETENTION_MODULE_GPSPI2,
|
||||
.entry_array = spi2_regs_retention,
|
||||
.array_size = ARRAY_SIZE(spi2_regs_retention),
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include "esp_private/spi_common_internal.h"
|
||||
#include "soc/spi_periph.h"
|
||||
|
||||
/**
|
||||
* Backup registers in Light sleep: (total cnt 29)
|
||||
*
|
||||
* cmd
|
||||
* addr
|
||||
* ctrl
|
||||
* clock
|
||||
* user
|
||||
* user1
|
||||
* user2
|
||||
* ms_dlen
|
||||
* misc
|
||||
* dma_conf
|
||||
* dma_int_ena
|
||||
* data_buf[0-15] // slave driver only
|
||||
* slave
|
||||
* slave1
|
||||
*/
|
||||
#define SPI_RETENTION_REGS_CNT 29
|
||||
static const uint32_t spi_regs_map[4] = {0x31ff, 0x33fffc0, 0x0, 0x0};
|
||||
#define SPI_REG_RETENTION_ENTRIES(num) { \
|
||||
[0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_GPSPI_LINK(0), \
|
||||
REG_SPI_BASE(num), REG_SPI_BASE(num), \
|
||||
SPI_RETENTION_REGS_CNT, 0, 0, \
|
||||
spi_regs_map[0], spi_regs_map[1], \
|
||||
spi_regs_map[2], spi_regs_map[3]), \
|
||||
.owner = ENTRY(0) | ENTRY(2) }, \
|
||||
/* Additional interrupt setting is required by idf SPI drivers after register recovered */ \
|
||||
[1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_GPSPI_LINK(1), \
|
||||
SPI_DMA_INT_SET_REG(num), \
|
||||
SPI_TRANS_DONE_INT_SET | SPI_DMA_SEG_TRANS_DONE_INT_SET | SPI_SLV_CMD7_INT_SET | SPI_SLV_CMD8_INT_SET , \
|
||||
UINT32_MAX, 1, 0), \
|
||||
.owner = ENTRY(0) | ENTRY(2) }, \
|
||||
}
|
||||
|
||||
static const regdma_entries_config_t spi2_regs_retention[] = SPI_REG_RETENTION_ENTRIES(2); // '2' for GPSPI2
|
||||
|
||||
const spi_reg_retention_info_t spi_reg_retention_info[SOC_SPI_PERIPH_NUM - 1] = { // '-1' to except mspi
|
||||
{
|
||||
.module_id = SLEEP_RETENTION_MODULE_GPSPI2,
|
||||
.entry_array = spi2_regs_retention,
|
||||
.array_size = ARRAY_SIZE(spi2_regs_retention),
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include "esp_private/spi_common_internal.h"
|
||||
#include "soc/spi_periph.h"
|
||||
|
||||
/**
|
||||
* Backup registers in Light sleep: (total cnt 29)
|
||||
*
|
||||
* cmd
|
||||
* addr
|
||||
* ctrl
|
||||
* clock
|
||||
* user
|
||||
* user1
|
||||
* user2
|
||||
* ms_dlen
|
||||
* misc
|
||||
* dma_conf
|
||||
* dma_int_ena
|
||||
* data_buf[0-15] // slave driver only
|
||||
* slave
|
||||
* slave1
|
||||
*/
|
||||
#define SPI_RETENTION_REGS_CNT 29
|
||||
static const uint32_t spi_regs_map[4] = {0x31ff, 0x33fffc0, 0x0, 0x0};
|
||||
#define SPI_REG_RETENTION_ENTRIES(num) { \
|
||||
[0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_GPSPI_LINK(0), \
|
||||
REG_SPI_BASE(num), REG_SPI_BASE(num), \
|
||||
SPI_RETENTION_REGS_CNT, 0, 0, \
|
||||
spi_regs_map[0], spi_regs_map[1], \
|
||||
spi_regs_map[2], spi_regs_map[3]), \
|
||||
.owner = ENTRY(0) | ENTRY(2) }, \
|
||||
/* Additional interrupt setting is required by idf SPI drivers after register recovered */ \
|
||||
[1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_GPSPI_LINK(1), \
|
||||
SPI_DMA_INT_SET_REG(num), \
|
||||
SPI_TRANS_DONE_INT_SET | SPI_DMA_SEG_TRANS_DONE_INT_SET | SPI_SLV_CMD7_INT_SET | SPI_SLV_CMD8_INT_SET , \
|
||||
UINT32_MAX, 1, 0), \
|
||||
.owner = ENTRY(0) | ENTRY(2) }, \
|
||||
}
|
||||
|
||||
static const regdma_entries_config_t spi2_regs_retention[] = SPI_REG_RETENTION_ENTRIES(2); // '2' for GPSPI2
|
||||
|
||||
const spi_reg_retention_info_t spi_reg_retention_info[SOC_SPI_PERIPH_NUM - 1] = { // '-1' to except mspi
|
||||
{
|
||||
.module_id = SLEEP_RETENTION_MODULE_GPSPI2,
|
||||
.entry_array = spi2_regs_retention,
|
||||
.array_size = ARRAY_SIZE(spi2_regs_retention),
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include "esp_private/spi_common_internal.h"
|
||||
#include "soc/spi_periph.h"
|
||||
|
||||
/**
|
||||
* Backup registers in Light sleep: (total cnt 29)
|
||||
*
|
||||
* cmd
|
||||
* addr
|
||||
* ctrl
|
||||
* clock
|
||||
* user
|
||||
* user1
|
||||
* user2
|
||||
* ms_dlen
|
||||
* misc
|
||||
* dma_conf
|
||||
* dma_int_ena
|
||||
* data_buf[0-15] // slave driver only
|
||||
* slave
|
||||
* slave1
|
||||
*/
|
||||
#define SPI_RETENTION_REGS_CNT 29
|
||||
static const uint32_t spi_regs_map[4] = {0x31ff, 0x33fffc0, 0x0, 0x0};
|
||||
#define SPI_REG_RETENTION_ENTRIES(num) { \
|
||||
[0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_GPSPI_LINK(0), \
|
||||
DR_REG_SPI_BASE(num), DR_REG_SPI_BASE(num), \
|
||||
SPI_RETENTION_REGS_CNT, 0, 0, \
|
||||
spi_regs_map[0], spi_regs_map[1], \
|
||||
spi_regs_map[2], spi_regs_map[3]), \
|
||||
.owner = ENTRY(0) }, \
|
||||
/* Additional interrupt setting is required by idf SPI drivers after register recovered */ \
|
||||
[1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_GPSPI_LINK(1), \
|
||||
SPI_DMA_INT_SET_REG(num), \
|
||||
SPI_TRANS_DONE_INT_SET | SPI_DMA_SEG_TRANS_DONE_INT_SET | SPI_SLV_CMD7_INT_SET | SPI_SLV_CMD8_INT_SET , \
|
||||
UINT32_MAX, 1, 0), \
|
||||
.owner = ENTRY(0) }, \
|
||||
}
|
||||
|
||||
static const regdma_entries_config_t spi2_regs_retention[] = SPI_REG_RETENTION_ENTRIES(2); // '2' for GPSPI2
|
||||
|
||||
const spi_reg_retention_info_t spi_reg_retention_info[SOC_SPI_PERIPH_NUM - 1] = { // '-1' to except mspi
|
||||
{
|
||||
.module_id = SLEEP_RETENTION_MODULE_GPSPI2,
|
||||
.entry_array = spi2_regs_retention,
|
||||
.array_size = ARRAY_SIZE(spi2_regs_retention),
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include "esp_private/spi_common_internal.h"
|
||||
#include "soc/spi_periph.h"
|
||||
|
||||
/**
|
||||
* Backup registers in Light sleep: (total cnt 29)
|
||||
*
|
||||
* cmd
|
||||
* addr
|
||||
* ctrl
|
||||
* clock
|
||||
* user
|
||||
* user1
|
||||
* user2
|
||||
* ms_dlen
|
||||
* misc
|
||||
* dma_conf
|
||||
* dma_int_ena
|
||||
* data_buf[0-15] // slave driver only
|
||||
* slave
|
||||
* slave1
|
||||
*/
|
||||
#define SPI_RETENTION_REGS_CNT 29
|
||||
static const uint32_t spi_regs_map[4] = {0x31ff, 0x33fffc0, 0x0, 0x0};
|
||||
#define SPI_REG_RETENTION_ENTRIES(num) { \
|
||||
[0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_GPSPI_LINK(0), \
|
||||
DR_REG_SPI_BASE(num), DR_REG_SPI_BASE(num), \
|
||||
SPI_RETENTION_REGS_CNT, 0, 0, \
|
||||
spi_regs_map[0], spi_regs_map[1], \
|
||||
spi_regs_map[2], spi_regs_map[3]), \
|
||||
.owner = ENTRY(0) | ENTRY(2) }, \
|
||||
/* Additional interrupt setting is required by idf SPI drivers after register recovered */ \
|
||||
[1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_GPSPI_LINK(1), \
|
||||
SPI_DMA_INT_SET_REG(num), \
|
||||
SPI_TRANS_DONE_INT_SET | SPI_DMA_SEG_TRANS_DONE_INT_SET | SPI_SLV_CMD7_INT_SET | SPI_SLV_CMD8_INT_SET , \
|
||||
UINT32_MAX, 1, 0), \
|
||||
.owner = ENTRY(0) | ENTRY(2) }, \
|
||||
}
|
||||
|
||||
static const regdma_entries_config_t spi2_regs_retention[] = SPI_REG_RETENTION_ENTRIES(2); // '2' for GPSPI2
|
||||
static const regdma_entries_config_t spi3_regs_retention[] = SPI_REG_RETENTION_ENTRIES(3); // '3' for GPSPI3
|
||||
|
||||
const spi_reg_retention_info_t spi_reg_retention_info[SOC_SPI_PERIPH_NUM - 1] = { // '-1' to except mspi
|
||||
{
|
||||
.module_id = SLEEP_RETENTION_MODULE_GPSPI2,
|
||||
.entry_array = spi2_regs_retention,
|
||||
.array_size = ARRAY_SIZE(spi2_regs_retention),
|
||||
}, {
|
||||
.module_id = SLEEP_RETENTION_MODULE_GPSPI3,
|
||||
.entry_array = spi3_regs_retention,
|
||||
.array_size = ARRAY_SIZE(spi3_regs_retention),
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include "esp_private/spi_common_internal.h"
|
||||
#include "soc/spi_periph.h"
|
||||
|
||||
/**
|
||||
* Backup registers in Light sleep: (total cnt 29)
|
||||
*
|
||||
* cmd
|
||||
* addr
|
||||
* ctrl
|
||||
* clock
|
||||
* user
|
||||
* user1
|
||||
* user2
|
||||
* ms_dlen
|
||||
* misc
|
||||
* dma_conf
|
||||
* dma_int_ena
|
||||
* data_buf[0-15] // slave driver only
|
||||
* slave
|
||||
* slave1
|
||||
*/
|
||||
#define SPI_RETENTION_REGS_CNT 29
|
||||
static const uint32_t spi_regs_map[4] = {0x31ff, 0x33fffc0, 0x0, 0x0};
|
||||
#define SPI_REG_RETENTION_ENTRIES(num) { \
|
||||
[0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_GPSPI_LINK(0), \
|
||||
REG_SPI_BASE(num), REG_SPI_BASE(num), \
|
||||
SPI_RETENTION_REGS_CNT, 0, 0, \
|
||||
spi_regs_map[0], spi_regs_map[1], \
|
||||
spi_regs_map[2], spi_regs_map[3]), \
|
||||
.owner = ENTRY(0) }, \
|
||||
/* Additional interrupt setting is required by idf SPI drivers after register recovered */ \
|
||||
[1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_GPSPI_LINK(1), \
|
||||
SPI_DMA_INT_SET_REG(num), \
|
||||
SPI_TRANS_DONE_INT_SET | SPI_DMA_SEG_TRANS_DONE_INT_SET | SPI_SLV_CMD7_INT_SET | SPI_SLV_CMD8_INT_SET , \
|
||||
UINT32_MAX, 1, 0), \
|
||||
.owner = ENTRY(0) }, \
|
||||
}
|
||||
|
||||
static const regdma_entries_config_t spi2_regs_retention[] = SPI_REG_RETENTION_ENTRIES(2); // '2' for GPSPI2
|
||||
static const regdma_entries_config_t spi3_regs_retention[] = SPI_REG_RETENTION_ENTRIES(3);
|
||||
|
||||
const spi_reg_retention_info_t spi_reg_retention_info[SOC_SPI_PERIPH_NUM - 1] = { // '-1' to except mspi
|
||||
{
|
||||
.module_id = SLEEP_RETENTION_MODULE_GPSPI2,
|
||||
.entry_array = spi2_regs_retention,
|
||||
.array_size = ARRAY_SIZE(spi2_regs_retention),
|
||||
},
|
||||
{
|
||||
.module_id = SLEEP_RETENTION_MODULE_GPSPI3,
|
||||
.entry_array = spi3_regs_retention,
|
||||
.array_size = ARRAY_SIZE(spi3_regs_retention),
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include "esp_private/spi_common_internal.h"
|
||||
#include "soc/spi_periph.h"
|
||||
|
||||
/**
|
||||
* Backup registers in Light sleep: (total cnt 29)
|
||||
*
|
||||
* cmd
|
||||
* addr
|
||||
* ctrl
|
||||
* clock
|
||||
* user
|
||||
* user1
|
||||
* user2
|
||||
* ms_dlen
|
||||
* misc
|
||||
* dma_conf
|
||||
* dma_int_ena
|
||||
* data_buf[0-15] // slave driver only
|
||||
* slave
|
||||
* slave1
|
||||
*/
|
||||
#define SPI_RETENTION_REGS_CNT 29
|
||||
static const uint32_t spi_regs_map[4] = {0x31ff, 0x33fffc0, 0x0, 0x0};
|
||||
#define SPI_REG_RETENTION_ENTRIES(num) { \
|
||||
[0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_GPSPI_LINK(0), \
|
||||
REG_SPI_BASE(num), REG_SPI_BASE(num), \
|
||||
SPI_RETENTION_REGS_CNT, 0, 0, \
|
||||
spi_regs_map[0], spi_regs_map[1], \
|
||||
spi_regs_map[2], spi_regs_map[3]), \
|
||||
.owner = ENTRY(0) | ENTRY(2)}, \
|
||||
/* Additional interrupt setting is required by idf SPI drivers after register recovered */ \
|
||||
[1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_GPSPI_LINK(1), \
|
||||
SPI_DMA_INT_SET_REG(num), \
|
||||
SPI_TRANS_DONE_INT_SET | SPI_DMA_SEG_TRANS_DONE_INT_SET | SPI_SLV_CMD7_INT_SET | SPI_SLV_CMD8_INT_SET , \
|
||||
UINT32_MAX, 1, 0), \
|
||||
.owner = ENTRY(0) | ENTRY(2)}, \
|
||||
}
|
||||
|
||||
static const regdma_entries_config_t spi2_regs_retention[] = SPI_REG_RETENTION_ENTRIES(2); // '2' for GPSPI2
|
||||
static const regdma_entries_config_t spi3_regs_retention[] = SPI_REG_RETENTION_ENTRIES(3);
|
||||
|
||||
const spi_reg_retention_info_t spi_reg_retention_info[SOC_SPI_PERIPH_NUM - 1] = { // '-1' to except mspi
|
||||
{
|
||||
.module_id = SLEEP_RETENTION_MODULE_GPSPI2,
|
||||
.entry_array = spi2_regs_retention,
|
||||
.array_size = ARRAY_SIZE(spi2_regs_retention),
|
||||
},
|
||||
{
|
||||
.module_id = SLEEP_RETENTION_MODULE_GPSPI3,
|
||||
.entry_array = spi3_regs_retention,
|
||||
.array_size = ARRAY_SIZE(spi3_regs_retention),
|
||||
},
|
||||
};
|
||||
@@ -160,21 +160,21 @@ static inline void _spicommon_dma_rcc_clock_ctrl(spi_dma_chan_t dma_chan, bool e
|
||||
if (enable) {
|
||||
PERIPH_RCC_ACQUIRE_ATOMIC(dma_periph, ref_count) {
|
||||
if (ref_count == 0) {
|
||||
spi_dma_ll_enable_bus_clock(dma_chan, true);
|
||||
spi_dma_ll_reset_register(dma_chan);
|
||||
spi_ll_dma_enable_bus_clock(dma_chan, true);
|
||||
spi_ll_dma_reset_register(dma_chan);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
PERIPH_RCC_RELEASE_ATOMIC(dma_periph, ref_count) {
|
||||
if (ref_count == 0) {
|
||||
spi_dma_ll_enable_bus_clock(dma_chan, false);
|
||||
spi_ll_dma_enable_bus_clock(dma_chan, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
PERIPH_RCC_ATOMIC() {
|
||||
spi_dma_ll_enable_bus_clock(dma_chan, enable);
|
||||
spi_dma_ll_reset_register(dma_chan);
|
||||
spi_ll_dma_enable_bus_clock(dma_chan, enable);
|
||||
spi_ll_dma_reset_register(dma_chan);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -380,7 +380,7 @@ esp_err_t spicommon_dma_desc_alloc(spi_host_device_t host_id, int cfg_max_sz, in
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
// cache sync using align_up length thanks to heap alloc already consider the cache alignment requirement
|
||||
uint8_t aligned_len = SPI_ALIGN_UP(sizeof(spi_dma_desc_t) * dma_desc_ct, bus_ctx[host_id]->bus_attr.cache_align_int);
|
||||
size_t aligned_len = ESP_ALIGN_UP(sizeof(spi_dma_desc_t) * dma_desc_ct, bus_ctx[host_id]->bus_attr.cache_align_int);
|
||||
// write back and then invalidate the cache, because later we will read/write the link list items by non-cached address
|
||||
esp_err_t ret = esp_cache_msync(dma_ctx->dmadesc_tx, aligned_len, ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_INVALIDATE);
|
||||
ESP_RETURN_ON_FALSE_ISR((ret == ESP_OK) || (ret == ESP_ERR_NOT_SUPPORTED), ESP_ERR_INVALID_ARG, SPI_TAG, "dma desc sync failed");
|
||||
@@ -1127,7 +1127,7 @@ bool SPI_COMMON_ISR_ATTR spicommon_dmaworkaround_req_reset(int dmachan, dmaworka
|
||||
} else {
|
||||
//Reset DMA
|
||||
PERIPH_RCC_ATOMIC() {
|
||||
spi_dma_ll_reset_register(dmachan);
|
||||
spi_ll_dma_reset_register(dmachan);
|
||||
}
|
||||
ret = true;
|
||||
}
|
||||
@@ -1147,7 +1147,7 @@ void SPI_COMMON_ISR_ATTR spicommon_dmaworkaround_idle(int dmachan)
|
||||
if (dmaworkaround_waiting_for_chan == dmachan) {
|
||||
//Reset DMA
|
||||
PERIPH_RCC_ATOMIC() {
|
||||
spi_dma_ll_reset_register(dmachan);
|
||||
spi_ll_dma_reset_register(dmachan);
|
||||
}
|
||||
dmaworkaround_waiting_for_chan = 0;
|
||||
//Call callback
|
||||
|
||||
@@ -19,11 +19,11 @@ void spi_dma_enable_burst(spi_dma_chan_handle_t chan_handle, bool data_burst, bo
|
||||
spi_dma_dev_t *spi_dma = SPI_LL_GET_HW(chan_handle.host_id);
|
||||
|
||||
if (chan_handle.dir == DMA_CHANNEL_DIRECTION_TX) {
|
||||
spi_dma_ll_tx_enable_burst_data(spi_dma, chan_handle.chan_id, data_burst);
|
||||
spi_dma_ll_tx_enable_burst_desc(spi_dma, chan_handle.chan_id, desc_burst);
|
||||
spi_ll_dma_tx_enable_burst_data(spi_dma, chan_handle.chan_id, data_burst);
|
||||
spi_ll_dma_tx_enable_burst_desc(spi_dma, chan_handle.chan_id, desc_burst);
|
||||
} else {
|
||||
spi_dma_ll_rx_enable_burst_data(spi_dma, chan_handle.chan_id, data_burst);
|
||||
spi_dma_ll_rx_enable_burst_desc(spi_dma, chan_handle.chan_id, desc_burst);
|
||||
spi_ll_dma_rx_enable_burst_data(spi_dma, chan_handle.chan_id, data_burst);
|
||||
spi_ll_dma_rx_enable_burst_desc(spi_dma, chan_handle.chan_id, desc_burst);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ void spi_dma_get_alignment_constraints(spi_dma_chan_handle_t chan_handle, size_t
|
||||
*internal_size = 1; // TX don't need to follow dma alignment in driver design
|
||||
*external_size = 1;
|
||||
} else {
|
||||
spi_dma_ll_get_rx_alignment_require(spi_dma, (uint32_t *)internal_size, (uint32_t *)external_size);
|
||||
spi_ll_dma_get_rx_alignment_require(spi_dma, (uint32_t *)internal_size, (uint32_t *)external_size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,9 +45,9 @@ void spi_dma_append(spi_dma_chan_handle_t chan_handle)
|
||||
spi_dma_dev_t *spi_dma = SPI_LL_GET_HW(chan_handle.host_id);
|
||||
|
||||
if (chan_handle.dir == DMA_CHANNEL_DIRECTION_TX) {
|
||||
spi_dma_ll_tx_restart(spi_dma, chan_handle.chan_id);
|
||||
spi_ll_dma_tx_restart(spi_dma, chan_handle.chan_id);
|
||||
} else {
|
||||
spi_dma_ll_rx_restart(spi_dma, chan_handle.chan_id);
|
||||
spi_ll_dma_rx_restart(spi_dma, chan_handle.chan_id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,8 +58,8 @@ uint32_t SPI_DMA_ISR_ATTR spi_dma_get_eof_desc(spi_dma_chan_handle_t chan_handle
|
||||
spi_dma_dev_t *spi_dma = SPI_LL_GET_HW(chan_handle.host_id);
|
||||
|
||||
return (chan_handle.dir == DMA_CHANNEL_DIRECTION_TX) ?
|
||||
spi_dma_ll_get_out_eof_desc_addr(spi_dma, chan_handle.chan_id) :
|
||||
spi_dma_ll_get_in_suc_eof_desc_addr(spi_dma, chan_handle.chan_id);
|
||||
spi_ll_dma_get_out_eof_desc_addr(spi_dma, chan_handle.chan_id) :
|
||||
spi_ll_dma_get_in_suc_eof_desc_addr(spi_dma, chan_handle.chan_id);
|
||||
}
|
||||
#endif //SOC_SPI_SUPPORT_SLAVE_HD_VER2
|
||||
|
||||
@@ -68,9 +68,9 @@ void SPI_DMA_ISR_ATTR spi_dma_reset(spi_dma_chan_handle_t chan_handle)
|
||||
spi_dma_dev_t *spi_dma = SPI_LL_GET_HW(chan_handle.host_id);
|
||||
|
||||
if (chan_handle.dir == DMA_CHANNEL_DIRECTION_TX) {
|
||||
spi_dma_ll_tx_reset(spi_dma, chan_handle.chan_id);
|
||||
spi_ll_dma_tx_reset(spi_dma, chan_handle.chan_id);
|
||||
} else {
|
||||
spi_dma_ll_rx_reset(spi_dma, chan_handle.chan_id);
|
||||
spi_ll_dma_rx_reset(spi_dma, chan_handle.chan_id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,8 +79,8 @@ void SPI_DMA_ISR_ATTR spi_dma_start(spi_dma_chan_handle_t chan_handle, void *add
|
||||
spi_dma_dev_t *spi_dma = SPI_LL_GET_HW(chan_handle.host_id);
|
||||
|
||||
if (chan_handle.dir == DMA_CHANNEL_DIRECTION_TX) {
|
||||
spi_dma_ll_tx_start(spi_dma, chan_handle.chan_id, (lldesc_t *)addr);
|
||||
spi_ll_dma_tx_start(spi_dma, chan_handle.chan_id, (lldesc_t *)addr);
|
||||
} else {
|
||||
spi_dma_ll_rx_start(spi_dma, chan_handle.chan_id, (lldesc_t *)addr);
|
||||
spi_ll_dma_rx_start(spi_dma, chan_handle.chan_id, (lldesc_t *)addr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,8 +141,8 @@ esp_err_t spi_slave_hd_init(spi_host_device_t host_id, const spi_bus_config_t *b
|
||||
};
|
||||
gdma_apply_strategy(host->dma_ctx->tx_dma_chan, &dma_strategy);
|
||||
#else
|
||||
spi_dma_ll_enable_out_auto_wrback(spi_periph_signal[host->dma_ctx->tx_dma_chan.host_id].hw, host->dma_ctx->tx_dma_chan.chan_id, 1);
|
||||
spi_dma_ll_set_out_eof_generation(spi_periph_signal[host->dma_ctx->tx_dma_chan.host_id].hw, host->dma_ctx->tx_dma_chan.chan_id, 1);
|
||||
spi_ll_dma_enable_out_auto_wrback(spi_periph_signal[host->dma_ctx->tx_dma_chan.host_id].hw, host->dma_ctx->tx_dma_chan.chan_id, 1);
|
||||
spi_ll_dma_set_out_eof_generation(spi_periph_signal[host->dma_ctx->tx_dma_chan.host_id].hw, host->dma_ctx->tx_dma_chan.chan_id, 1);
|
||||
#endif
|
||||
ret = spicommon_dma_desc_alloc(host_id, bus_config->max_transfer_sz, &host->bus_attr->max_transfer_sz);
|
||||
if (ret != ESP_OK) {
|
||||
|
||||
Reference in New Issue
Block a user