Skip to content

Commit

Permalink
Merge branch 'feature/support_gdma_retention_v5.2' into 'release/v5.2'
Browse files Browse the repository at this point in the history
feature: support gdma retention in pd_top lightsleep (v5.2)

See merge request espressif/esp-idf!29090
  • Loading branch information
jack0c committed Feb 19, 2024
2 parents 4bd5fa2 + eeed231 commit 2b084b1
Show file tree
Hide file tree
Showing 16 changed files with 280 additions and 21 deletions.
3 changes: 3 additions & 0 deletions components/esp_hw_support/CMakeLists.txt
Expand Up @@ -62,6 +62,9 @@ if(NOT BOOTLOADER_BUILD)

if(CONFIG_SOC_GDMA_SUPPORTED)
list(APPEND srcs "dma/gdma.c")
if(CONFIG_SOC_PAU_SUPPORTED)
list(APPEND srcs "dma/gdma_sleep_retention.c")
endif()
endif()

if(CONFIG_SOC_ASYNC_MEMCPY_SUPPORTED)
Expand Down
12 changes: 11 additions & 1 deletion components/esp_hw_support/dma/gdma.c
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -47,6 +47,10 @@
#include "hal/cache_hal.h"
#include "hal/cache_ll.h"

#if CONFIG_PM_ENABLE && SOC_PAU_SUPPORTED
#include "esp_private/gdma_sleep_retention.h"
#endif

static const char *TAG = "gdma";

#if !SOC_RCC_IS_INDEPENDENT
Expand Down Expand Up @@ -689,6 +693,9 @@ static void gdma_release_pair_handle(gdma_pair_t *pair)

if (do_deinitialize) {
free(pair);
#if CONFIG_PM_ENABLE && SOC_PAU_SUPPORTED
gdma_sleep_retention_deinit(group->group_id, pair_id);
#endif
ESP_LOGD(TAG, "del pair (%d,%d)", group->group_id, pair_id);
gdma_release_group_handle(group);
}
Expand Down Expand Up @@ -726,6 +733,9 @@ static gdma_pair_t *gdma_acquire_pair_handle(gdma_group_t *group, int pair_id)
s_platform.group_ref_counts[group->group_id]++;
portEXIT_CRITICAL(&s_platform.spinlock);

#if CONFIG_PM_ENABLE && SOC_PAU_SUPPORTED
gdma_sleep_retention_init(group->group_id, pair_id);
#endif
ESP_LOGD(TAG, "new pair (%d,%d) at %p", group->group_id, pair_id, pair);
} else {
free(pre_alloc_pair);
Expand Down
48 changes: 48 additions & 0 deletions components/esp_hw_support/dma/gdma_sleep_retention.c
@@ -0,0 +1,48 @@
/*
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <stdlib.h>
#include <string.h>
#include "sdkconfig.h"
#include "soc/soc_caps.h"

#include "esp_err.h"
#include "esp_check.h"
#include "esp_log.h"
#include "esp_private/sleep_retention.h"
#include "esp_private/esp_regdma.h"

#include "sleep_gdma_retention_context.inc"

static const char *TAG = "gdma";

#define SLEEP_RETENTION_MODULE_GDMA_CH(group_id, pair_id) (SLEEP_RETENTION_MODULE_GDMA_CH0 << (SOC_GDMA_PAIRS_PER_GROUP_MAX * group_id) << pair_id)

static esp_err_t sleep_modem_gdma_channel_retention_init(sleep_retention_module_bitmap_t module)
{
uint32_t id = __builtin_ctz(module / SLEEP_RETENTION_MODULE_GDMA_CH0);
esp_err_t err = sleep_retention_entries_create(gdma_chx_regs_retention[id].link_list, gdma_chx_regs_retention[id].link_num, REGDMA_LINK_PRI_7, module);
if (err == ESP_OK) {
int group_id = id / SOC_GDMA_PAIRS_PER_GROUP_MAX;
int pair_id = id % SOC_GDMA_PAIRS_PER_GROUP_MAX;
ESP_LOGI(TAG, "GDMA pair (%d, %d) retention initialization", group_id, pair_id);
}
return err;
}

esp_err_t gdma_sleep_retention_init(int group_id, int pair_id)
{
esp_err_t err = ESP_OK;
err = sleep_modem_gdma_channel_retention_init(SLEEP_RETENTION_MODULE_GDMA_CH(group_id, pair_id));
ESP_RETURN_ON_ERROR(err, TAG, "Failed to create sleep retention linked list for GDMA pair (%d, %d) retention", group_id, pair_id);
return err;
}

esp_err_t gdma_sleep_retention_deinit(int group_id, int pair_id)
{
sleep_retention_entries_destroy(SLEEP_RETENTION_MODULE_GDMA_CH(group_id, pair_id));
return ESP_OK;;
}
1 change: 1 addition & 0 deletions components/esp_hw_support/include/esp_private/esp_regdma.h
Expand Up @@ -43,6 +43,7 @@ extern "C" {
#define REGDMA_BLE_MAC_LINK(_pri) ((0x15 << 8) | _pri)
#define REGDMA_MODEM_BT_BB_LINK(_pri) ((0x16 << 8) | _pri)
#define REGDMA_MODEM_IEEE802154_LINK(_pri) ((0x17 << 8) | _pri)
#define REGDMA_MODEM_GDMA_LINK(_pri) ((0x18 << 8) | _pri)
#define REGDMA_MODEM_FE_LINK(_pri) ((0xFF << 8) | _pri)

typedef enum {
Expand Down
@@ -0,0 +1,40 @@
/*
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/

// DO NOT USE THESE APIS IN ANY APPLICATIONS
// GDMA driver is not public for end users, but for ESP-IDF developers.

#pragma once

#include "esp_err.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
* Initialize GDMA channel retention link for powerdown the TOP powerdomain during lightsleep
* @param group_id Group id
* @param pair_id Pair id
* @return
* - ESP_OK: Create DMA retention link successfully
* - ESP_ERR_NO_MEM: Create DMA retention link failed because out of memory
*/
esp_err_t gdma_sleep_retention_init(int group_id, int pair_id);



/**
* Destroy GDMA channel retention link
* @param group_id Group id
* @param pair_id Pair id
* @return always return ESP_OK
*/
esp_err_t gdma_sleep_retention_deinit(int group_id, int pair_id);

#ifdef __cplusplus
}
#endif
Expand Up @@ -45,6 +45,10 @@ typedef enum sleep_retention_module_bitmap {
SLEEP_RETENTION_MODULE_IOMUX = BIT(21),
SLEEP_RETENTION_MODULE_SPIMEM = BIT(22),
SLEEP_RETENTION_MODULE_SYSTIMER = BIT(23),
SLEEP_RETENTION_MODULE_GDMA_CH0 = BIT(24),
SLEEP_RETENTION_MODULE_GDMA_CH1 = BIT(25),
SLEEP_RETENTION_MODULE_GDMA_CH2 = BIT(26),


SLEEP_RETENTION_MODULE_ALL = (uint32_t)-1
} sleep_retention_module_bitmap_t;
Expand Down
2 changes: 2 additions & 0 deletions components/esp_hw_support/port/esp32c6/pmu_param.c
Expand Up @@ -286,6 +286,7 @@ const pmu_hp_system_analog_param_t * pmu_hp_system_analog_param_default(pmu_hp_m
.hp_modem2active_backup_en = 0, \
}, \
.backup_clk = ( \
BIT(PMU_ICG_FUNC_ENA_GDMA) | \
BIT(PMU_ICG_FUNC_ENA_REGDMA) | \
BIT(PMU_ICG_FUNC_ENA_TG0) | \
BIT(PMU_ICG_FUNC_ENA_TG1) | \
Expand Down Expand Up @@ -335,6 +336,7 @@ const pmu_hp_system_analog_param_t * pmu_hp_system_analog_param_default(pmu_hp_m
.hp_active2sleep_backup_en = 0, \
}, \
.backup_clk = ( \
BIT(PMU_ICG_FUNC_ENA_GDMA) | \
BIT(PMU_ICG_FUNC_ENA_REGDMA) | \
BIT(PMU_ICG_FUNC_ENA_TG0) | \
BIT(PMU_ICG_FUNC_ENA_TG1) | \
Expand Down
@@ -0,0 +1,81 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/

#include "soc/soc_caps.h"
#include "soc/gdma_reg.h"


/* GDMA Channel (Group0, Pair0) Registers Context
Include: GDMA_MISC_CONF_REG /
GDMA_IN_INT_ENA_CH0_REG / GDMA_OUT_INT_ENA_CH0_REG / GDMA_IN_PERI_SEL_CH0_REG / GDMA_OUT_PERI_SEL_CH0_REG
GDMA_IN_CONF0_CH0_REG / GDMA_IN_CONF1_CH0_REG / GDMA_IN_LINK_CH0_REG / GDMA_IN_PRI_CH0_REG
GDMA_OUT_CONF0_CH0_REG / GDMA_OUT_CONF1_CH0_REG / GDMA_OUT_LINK_CH0_REG /GDMA_OUT_PRI_CH0_REG
*/
#define G0P0_RETENTION_REGS_CNT 13
#define G0P0_RETENTION_MAP_BASE GDMA_IN_INT_ENA_CH0_REG
static const uint32_t g0p0_regs_map[4] = {0x4C801001, 0x604C0060, 0, 0};
static const sleep_retention_entries_config_t gdma_g0p0_regs_retention[] = {
[0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_MODEM_GDMA_LINK(0x00), \
G0P0_RETENTION_MAP_BASE, G0P0_RETENTION_MAP_BASE, \
G0P0_RETENTION_REGS_CNT, 0, 0, \
g0p0_regs_map[0], g0p0_regs_map[1], \
g0p0_regs_map[2], g0p0_regs_map[3]), \
.owner = ENTRY(0) | ENTRY(2) },
};

/* GDMA Channel (Group0, Pair1) Registers Context
Include: GDMA_MISC_CONF_REG /
GDMA_IN_INT_ENA_CH1_REG / GDMA_OUT_INT_ENA_CH1_REG / GDMA_IN_PERI_SEL_CH1_REG / GDMA_OUT_PERI_SEL_CH1_REG
GDMA_IN_CONF0_CH1_REG / GDMA_IN_CONF1_CH1_REG / GDMA_IN_LINK_CH1_REG / GDMA_IN_PRI_CH1_REG
GDMA_OUT_CONF0_CH1_REG / GDMA_OUT_CONF1_CH1_REG / GDMA_OUT_LINK_CH1_REG /GDMA_OUT_PRI_CH1_REG
*/
#define G0P1_RETENTION_REGS_CNT 13
#define G0P1_RETENTION_MAP_BASE GDMA_IN_INT_ENA_CH1_REG
static const uint32_t g0p1_regs_map[4] = {0x81001, 0, 0xC00604C0, 0x604};
static const sleep_retention_entries_config_t gdma_g0p1_regs_retention[] = {
[0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_MODEM_GDMA_LINK(0x00), \
G0P1_RETENTION_MAP_BASE, G0P1_RETENTION_MAP_BASE, \
G0P1_RETENTION_REGS_CNT, 0, 0, \
g0p1_regs_map[0], g0p1_regs_map[1], \
g0p1_regs_map[2], g0p1_regs_map[3]), \
.owner = ENTRY(0) | ENTRY(2) },
};

/* GDMA Channel (Group0, Pair2) Registers Context
Include: GDMA_MISC_CONF_REG /
GDMA_IN_INT_ENA_CH2_REG / GDMA_OUT_INT_ENA_CH2_REG / GDMA_IN_PERI_SEL_CH2_REG / GDMA_OUT_PERI_SEL_CH2_REG
GDMA_IN_CONF0_CH2_REG / GDMA_IN_CONF1_CH2_REG / GDMA_IN_LINK_CH2_REG / GDMA_IN_PRI_CH2_REG
GDMA_OUT_CONF0_CH2_REG / GDMA_OUT_CONF1_CH2_REG / GDMA_OUT_LINK_CH2_REG /GDMA_OUT_PRI_CH2_REG
*/
#define G0P1_RETENTION_REGS_CNT_0 6
#define G0P2_RETENTION_MAP_BASE_0 GDMA_IN_INT_ENA_CH2_REG
#define G0P1_RETENTION_REGS_CNT_1 7
#define G0P2_RETENTION_MAP_BASE_1 GDMA_IN_PRI_CH2_REG
static const uint32_t g0p2_regs_map0[4] = {0x9001, 0, 0, 0x4C0000};
static const uint32_t g0p2_regs_map1[4] = {0x3026003, 0, 0, 0};
static const sleep_retention_entries_config_t gdma_g0p2_regs_retention[] = {
[0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_MODEM_GDMA_LINK(0x00), \
G0P2_RETENTION_MAP_BASE_0, G0P2_RETENTION_MAP_BASE_0, \
G0P1_RETENTION_REGS_CNT_0, 0, 0, \
g0p2_regs_map0[0], g0p2_regs_map0[1], \
g0p2_regs_map0[2], g0p2_regs_map0[3]), \
.owner = ENTRY(0) | ENTRY(2) },
[1] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_MODEM_GDMA_LINK(0x00), \
G0P2_RETENTION_MAP_BASE_1, G0P2_RETENTION_MAP_BASE_1, \
G0P1_RETENTION_REGS_CNT_1, 0, 0, \
g0p2_regs_map1[0], g0p2_regs_map1[1], \
g0p2_regs_map1[2], g0p2_regs_map1[3]), \
.owner = ENTRY(0) | ENTRY(2) },
};

static const struct {
const sleep_retention_entries_config_t *link_list;
uint32_t link_num;
} gdma_chx_regs_retention[SOC_GDMA_PAIRS_PER_GROUP_MAX*SOC_GDMA_PAIRS_PER_GROUP_MAX] = {
[0] = {gdma_g0p0_regs_retention, ARRAY_SIZE(gdma_g0p0_regs_retention)},
[1] = {gdma_g0p1_regs_retention, ARRAY_SIZE(gdma_g0p1_regs_retention)},
[2] = {gdma_g0p2_regs_retention, ARRAY_SIZE(gdma_g0p2_regs_retention)}
};
14 changes: 9 additions & 5 deletions components/esp_hw_support/port/esp32h2/pmu_param.c
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -286,7 +286,9 @@ const pmu_hp_system_analog_param_t * pmu_hp_system_analog_param_default(pmu_hp_m
.hp_sleep2active_backup_en = 0, \
.hp_modem2active_backup_en = 0, \
}, \
.backup_clk = (BIT(PMU_ICG_FUNC_ENA_REGDMA) \
.backup_clk = ( \
BIT(PMU_ICG_FUNC_ENA_GDMA) \
| BIT(PMU_ICG_FUNC_ENA_REGDMA) \
| BIT(PMU_ICG_FUNC_ENA_TG0) \
| BIT(PMU_ICG_FUNC_ENA_HPBUS) \
| BIT(PMU_ICG_FUNC_ENA_MSPI) \
Expand Down Expand Up @@ -333,14 +335,16 @@ const pmu_hp_system_analog_param_t * pmu_hp_system_analog_param_default(pmu_hp_m
.hp_modem2sleep_backup_en = 0, \
.hp_active2sleep_backup_en = 0, \
}, \
.backup_clk = (BIT(PMU_ICG_FUNC_ENA_REGDMA) \
.backup_clk = ( \
BIT(PMU_ICG_FUNC_ENA_GDMA) \
| BIT(PMU_ICG_FUNC_ENA_REGDMA) \
| BIT(PMU_ICG_FUNC_ENA_TG0) \
| BIT(PMU_ICG_FUNC_ENA_HPBUS) \
| BIT(PMU_ICG_FUNC_ENA_MSPI) \
| BIT(PMU_ICG_FUNC_ENA_IOMUX) \
| BIT(PMU_ICG_FUNC_ENA_SPI2) \
| BIT(PMU_ICG_FUNC_ENA_SEC) \
| BIT(PMU_ICG_FUNC_ENA_PWM) \
| BIT(PMU_ICG_FUNC_ENA_SEC) \
| BIT(PMU_ICG_FUNC_ENA_PWM) \
| BIT(PMU_ICG_FUNC_ENA_SYSTIMER) \
| BIT(PMU_ICG_FUNC_ENA_UART0)), \
}
Expand Down
@@ -0,0 +1,81 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/

#include "soc/soc_caps.h"
#include "soc/gdma_reg.h"


/* GDMA Channel (Group0, Pair0) Registers Context
Include: GDMA_MISC_CONF_REG /
GDMA_IN_INT_ENA_CH0_REG / GDMA_OUT_INT_ENA_CH0_REG / GDMA_IN_PERI_SEL_CH0_REG / GDMA_OUT_PERI_SEL_CH0_REG
GDMA_IN_CONF0_CH0_REG / GDMA_IN_CONF1_CH0_REG / GDMA_IN_LINK_CH0_REG / GDMA_IN_PRI_CH0_REG
GDMA_OUT_CONF0_CH0_REG / GDMA_OUT_CONF1_CH0_REG / GDMA_OUT_LINK_CH0_REG /GDMA_OUT_PRI_CH0_REG
*/
#define G0P0_RETENTION_REGS_CNT 13
#define G0P0_RETENTION_MAP_BASE GDMA_IN_INT_ENA_CH0_REG
static const uint32_t g0p0_regs_map[4] = {0x4C801001, 0x604C0060, 0, 0};
static const sleep_retention_entries_config_t gdma_g0p0_regs_retention[] = {
[0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_MODEM_GDMA_LINK(0x00), \
G0P0_RETENTION_MAP_BASE, G0P0_RETENTION_MAP_BASE, \
G0P0_RETENTION_REGS_CNT, 0, 0, \
g0p0_regs_map[0], g0p0_regs_map[1], \
g0p0_regs_map[2], g0p0_regs_map[3]), \
.owner = ENTRY(0) | ENTRY(2) },
};

/* GDMA Channel (Group0, Pair1) Registers Context
Include: GDMA_MISC_CONF_REG /
GDMA_IN_INT_ENA_CH1_REG / GDMA_OUT_INT_ENA_CH1_REG / GDMA_IN_PERI_SEL_CH1_REG / GDMA_OUT_PERI_SEL_CH1_REG
GDMA_IN_CONF0_CH1_REG / GDMA_IN_CONF1_CH1_REG / GDMA_IN_LINK_CH1_REG / GDMA_IN_PRI_CH1_REG
GDMA_OUT_CONF0_CH1_REG / GDMA_OUT_CONF1_CH1_REG / GDMA_OUT_LINK_CH1_REG /GDMA_OUT_PRI_CH1_REG
*/
#define G0P1_RETENTION_REGS_CNT 13
#define G0P1_RETENTION_MAP_BASE GDMA_IN_INT_ENA_CH1_REG
static const uint32_t g0p1_regs_map[4] = {0x81001, 0, 0xC00604C0, 0x604};
static const sleep_retention_entries_config_t gdma_g0p1_regs_retention[] = {
[0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_MODEM_GDMA_LINK(0x00), \
G0P1_RETENTION_MAP_BASE, G0P1_RETENTION_MAP_BASE, \
G0P1_RETENTION_REGS_CNT, 0, 0, \
g0p1_regs_map[0], g0p1_regs_map[1], \
g0p1_regs_map[2], g0p1_regs_map[3]), \
.owner = ENTRY(0) | ENTRY(2) },
};

/* GDMA Channel (Group0, Pair2) Registers Context
Include: GDMA_MISC_CONF_REG /
GDMA_IN_INT_ENA_CH2_REG / GDMA_OUT_INT_ENA_CH2_REG / GDMA_IN_PERI_SEL_CH2_REG / GDMA_OUT_PERI_SEL_CH2_REG
GDMA_IN_CONF0_CH2_REG / GDMA_IN_CONF1_CH2_REG / GDMA_IN_LINK_CH2_REG / GDMA_IN_PRI_CH2_REG
GDMA_OUT_CONF0_CH2_REG / GDMA_OUT_CONF1_CH2_REG / GDMA_OUT_LINK_CH2_REG /GDMA_OUT_PRI_CH2_REG
*/
#define G0P1_RETENTION_REGS_CNT_0 6
#define G0P2_RETENTION_MAP_BASE_0 GDMA_IN_INT_ENA_CH2_REG
#define G0P1_RETENTION_REGS_CNT_1 7
#define G0P2_RETENTION_MAP_BASE_1 GDMA_IN_PRI_CH2_REG
static const uint32_t g0p2_regs_map0[4] = {0x9001, 0, 0, 0x4C0000};
static const uint32_t g0p2_regs_map1[4] = {0x3026003, 0, 0, 0};
static const sleep_retention_entries_config_t gdma_g0p2_regs_retention[] = {
[0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_MODEM_GDMA_LINK(0x00), \
G0P2_RETENTION_MAP_BASE_0, G0P2_RETENTION_MAP_BASE_0, \
G0P1_RETENTION_REGS_CNT_0, 0, 0, \
g0p2_regs_map0[0], g0p2_regs_map0[1], \
g0p2_regs_map0[2], g0p2_regs_map0[3]), \
.owner = ENTRY(0) | ENTRY(2) },
[1] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_MODEM_GDMA_LINK(0x00), \
G0P2_RETENTION_MAP_BASE_1, G0P2_RETENTION_MAP_BASE_1, \
G0P1_RETENTION_REGS_CNT_1, 0, 0, \
g0p2_regs_map1[0], g0p2_regs_map1[1], \
g0p2_regs_map1[2], g0p2_regs_map1[3]), \
.owner = ENTRY(0) | ENTRY(2) },
};

static const struct {
const sleep_retention_entries_config_t *link_list;
uint32_t link_num;
} gdma_chx_regs_retention[SOC_GDMA_PAIRS_PER_GROUP_MAX*SOC_GDMA_PAIRS_PER_GROUP_MAX] = {
[0] = {gdma_g0p0_regs_retention, ARRAY_SIZE(gdma_g0p0_regs_retention)},
[1] = {gdma_g0p1_regs_retention, ARRAY_SIZE(gdma_g0p1_regs_retention)},
[2] = {gdma_g0p2_regs_retention, ARRAY_SIZE(gdma_g0p2_regs_retention)}
};
1 change: 0 additions & 1 deletion docs/en/api-reference/system/power_management.rst
Expand Up @@ -142,7 +142,6 @@ Light-sleep Peripheral Power Down
- SYSTIMER

The following peripherals are not yet supported:
- GDMA
- ETM
- TIMG1
- ASSIST_DEBUG
Expand Down
1 change: 0 additions & 1 deletion docs/zh_CN/api-reference/system/power_management.rst
Expand Up @@ -142,7 +142,6 @@ Light-sleep 外设下电
- SYSTIMER

以下外设尚未支持:
- GDMA
- ETM
- TIMG1
- ASSIST_DEBUG
Expand Down

0 comments on commit 2b084b1

Please sign in to comment.