light sleep: add cpu power down support for esp32s3

This commit is contained in:
Li Shuai 2021-06-18 17:25:04 +08:00
parent 15fc449793
commit 03746de96f
9 changed files with 181 additions and 16 deletions

View File

@ -29,7 +29,11 @@ static DRAM_ATTR sleep_retention_t s_retention;
#if SOC_PM_SUPPORT_CPU_PD
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2
#define CPU_PD_MEM_TYPE_CAPS (MALLOC_CAP_RETENTION | MALLOC_CAP_DEFAULT)
#else
#define CPU_PD_MEM_TYPE_CAPS (MALLOC_CAP_DMA | MALLOC_CAP_DEFAULT)
#endif
esp_err_t esp_sleep_cpu_pd_low_init(bool enable)
{

View File

@ -96,10 +96,12 @@ menu "Power Management"
config PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP
bool "Power down CPU in light sleep"
depends on IDF_TARGET_ESP32C3
depends on IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3
default y
help
If enabled, the CPU will be powered down in light sleep. Enabling this option will consume
1.68 KB of internal RAM and will reduce sleep current consumption by about 100 uA.
If enabled, the CPU will be powered down in light sleep. On esp32c3 soc, enabling this
option will consume 1.68 KB of internal RAM and will reduce sleep current consumption
by about 100 uA. On esp32s3 soc, enabling this option will consume 8.58 KB of internal
RAM and will reduce sleep current consumption by about 650 uA.
endmenu # "Power Management"

View File

@ -85,6 +85,7 @@ if(NOT BOOTLOADER_BUILD)
"esp32s3/hmac_hal.c"
"esp32s3/interrupt_descriptor_table.c"
"esp32s3/touch_sensor_hal.c"
"esp32s3/rtc_cntl_hal.c"
"usbh_hal.c")
endif()

View File

@ -47,12 +47,18 @@ static inline void rtc_cntl_ll_gpio_clear_wakeup_pins(void)
REG_SET_BIT(RTC_CNTL_GPIO_WAKEUP_REG, RTC_CNTL_GPIO_WAKEUP_STATUS_CLR);
}
static inline void rtc_cntl_ll_enable_cpu_retention(uint32_t addr)
static inline void rtc_cntl_ll_set_cpu_retention_link_addr(uint32_t addr)
{
/* write memory address to register */
REG_SET_FIELD(APB_CTRL_RETENTION_CTRL_REG, APB_CTRL_RETENTION_LINK_ADDR, (uint32_t)addr);
/* Enable clock */
}
static inline void rtc_cntl_ll_enable_cpu_retention_clock(void)
{
REG_SET_BIT(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN);
}
static inline void rtc_cntl_ll_enable_cpu_retention(void)
{
/* Enable retention when cpu sleep enable */
REG_SET_BIT(RTC_CNTL_RETENTION_CTRL_REG, RTC_CNTL_RETENTION_EN);
}

View File

@ -16,8 +16,10 @@
#include "soc/soc_caps.h"
#include "soc/lldesc.h"
#include "hal/dma_types.h"
#include "hal/rtc_hal.h"
#include "hal/assert.h"
#include "esp_attr.h"
#define RTC_CNTL_HAL_LINK_BUF_SIZE_MIN (SOC_RTC_CNTL_CPU_PD_DMA_BLOCK_SIZE) /* The minimum size of dma link buffer */
@ -34,7 +36,7 @@ void * rtc_cntl_hal_dma_link_init(void *elem, void *buff, int size, void *next)
lldesc_t *plink = (lldesc_t *)elem;
plink->eof = next ? 0 : 1;
plink->owner = 1;
plink->owner = DMA_DESCRIPTOR_BUFFER_OWNER_DMA;
plink->size = size >> 4; /* in unit of 16 bytes */
plink->length = size >> 4;
plink->buf = buff;
@ -44,18 +46,39 @@ void * rtc_cntl_hal_dma_link_init(void *elem, void *buff, int size, void *next)
return (void *)plink;
}
#if SOC_PM_SUPPORT_CPU_PD
void rtc_cntl_hal_enable_cpu_retention(void *addr)
{
rtc_cntl_sleep_retent_t *retent = (rtc_cntl_sleep_retent_t *)addr;
if (addr) {
lldesc_t *plink = (lldesc_t *)addr;
if (retent->cpu_pd_mem) {
lldesc_t *plink = (lldesc_t *)retent->cpu_pd_mem;
/* dma link buffer configure */
rtc_cntl_link_buf_conf_t *pbuf = (rtc_cntl_link_buf_conf_t *)plink->buf;
pbuf->cfg[0] = 0;
pbuf->cfg[1] = 0;
pbuf->cfg[2] = 0;
pbuf->cfg[3] = (uint32_t)-1;
/* dma link buffer configure */
rtc_cntl_link_buf_conf_t *pbuf = (rtc_cntl_link_buf_conf_t *)plink->buf;
pbuf->cfg[0] = 0;
pbuf->cfg[1] = 0;
pbuf->cfg[2] = 0;
pbuf->cfg[3] = (uint32_t)-1;
rtc_cntl_ll_enable_cpu_retention((uint32_t)addr);
rtc_cntl_ll_set_cpu_retention_link_addr((uint32_t)plink);
rtc_cntl_ll_enable_cpu_retention_clock();
rtc_cntl_ll_enable_cpu_retention();
}
}
}
void IRAM_ATTR rtc_cntl_hal_disable_cpu_retention(void *addr)
{
rtc_cntl_sleep_retent_t *retent = (rtc_cntl_sleep_retent_t *)addr;
if (addr) {
if (retent->cpu_pd_mem) {
rtc_cntl_ll_disable_cpu_retention();
}
}
}
#endif // SOC_PM_SUPPORT_CPU_PD

View File

@ -17,6 +17,7 @@
#include "soc/soc.h"
#include "soc/rtc.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/apb_ctrl_reg.h"
#ifdef __cplusplus
extern "C" {
@ -53,6 +54,35 @@ static inline void rtc_cntl_ll_ulp_wakeup_enable(void)
SET_PERI_REG_BITS(RTC_CNTL_STATE0_REG, RTC_CNTL_WAKEUP_ENA_V, 0x800, RTC_CNTL_WAKEUP_ENA_S);
}
static inline void rtc_cntl_ll_set_cpu_retention_link_addr(uint32_t link_addr)
{
REG_SET_FIELD(APB_CTRL_RETENTION_CTRL_REG, APB_CTRL_RETENTION_CPU_LINK_ADDR, link_addr);
}
static inline void rtc_cntl_ll_enable_cpu_retention_clock(void)
{
REG_SET_BIT(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN); /* Enable internal 20 MHz clock */
}
static inline void rtc_cntl_ll_enable_cpu_retention(void)
{
uint32_t target = REG_GET_FIELD(RTC_CNTL_RETENTION_CTRL_REG, RTC_CNTL_RETENTION_TARGET);
/* TODO: I/d-Cache tagmem retention has not been implementted yet,
* so i/d-cache tagmem retention is explicitly disabled */
REG_CLR_BIT(APB_CTRL_RETENTION_CTRL2_REG, APB_CTRL_RET_ICACHE_ENABLE);
REG_CLR_BIT(APB_CTRL_RETENTION_CTRL3_REG, APB_CTRL_RET_DCACHE_ENABLE);
REG_SET_FIELD(RTC_CNTL_RETENTION_CTRL_REG, RTC_CNTL_RETENTION_TARGET, (target | 0x1));
/* Enable retention when cpu sleep enable */
REG_SET_BIT(RTC_CNTL_RETENTION_CTRL_REG, RTC_CNTL_RETENTION_EN);
}
static inline void rtc_cntl_ll_disable_cpu_retention(void)
{
REG_CLR_BIT(RTC_CNTL_RETENTION_CTRL_REG, RTC_CNTL_RETENTION_EN);
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,82 @@
/*
* SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
// The HAL layer for RTC CNTL (common part)
#include "hal/rtc_hal.h"
#include "soc/soc_caps.h"
#include "esp32s3/rom/lldesc.h"
#include "esp32s3/rom/cache.h"
#include "hal/dma_types.h"
#include "hal/assert.h"
#include "esp_attr.h"
#define RTC_CNTL_HAL_LINK_BUF_SIZE_MIN (SOC_RTC_CNTL_CPU_PD_DMA_BLOCK_SIZE) /* The minimum size of dma link buffer */
typedef struct rtc_cntl_link_buf_conf {
uint32_t cfg[4]; /* 4 word for dma link buffer configuration */
} rtc_cntl_link_buf_conf_t;
void * rtc_cntl_hal_dma_link_init(void *elem, void *buff, int size, void *next)
{
HAL_ASSERT(elem != NULL);
HAL_ASSERT(buff != NULL);
HAL_ASSERT(size >= RTC_CNTL_HAL_LINK_BUF_SIZE_MIN);
lldesc_t *plink = (lldesc_t *)elem;
plink->eof = next ? 0 : 1;
plink->owner = DMA_DESCRIPTOR_BUFFER_OWNER_DMA;
plink->size = size >> 4; /* in unit of 16 bytes */
plink->length = size >> 4;
plink->buf = buff;
plink->offset = 0;
plink->sosf = 0;
STAILQ_NEXT(plink, qe) = next;
return (void *)plink;
}
#if SOC_PM_SUPPORT_CPU_PD
void rtc_cntl_hal_enable_cpu_retention(void *addr)
{
rtc_cntl_sleep_retent_t *retent = (rtc_cntl_sleep_retent_t *)addr;
if (addr) {
if (retent->cpu_pd_mem) {
lldesc_t *plink = (lldesc_t *)retent->cpu_pd_mem;
/* dma link buffer configure */
rtc_cntl_link_buf_conf_t *pbuf = (rtc_cntl_link_buf_conf_t *)plink->buf;
pbuf->cfg[0] = 0;
pbuf->cfg[1] = 0;
pbuf->cfg[2] = 0;
pbuf->cfg[3] = 0xfffe0000;
rtc_cntl_ll_set_cpu_retention_link_addr((uint32_t)plink);
rtc_cntl_ll_enable_cpu_retention_clock();
rtc_cntl_ll_enable_cpu_retention();
}
}
}
void IRAM_ATTR rtc_cntl_hal_disable_cpu_retention(void *addr)
{
rtc_cntl_sleep_retent_t *retent = (rtc_cntl_sleep_retent_t *)addr;
if (addr) {
if (retent->cpu_pd_mem) {
/* TODO: I/d-cache tagmem retention has not been implemented yet,
* so after the system wakes up, all the contents of i/d-cache need
* to be invalidated. */
Cache_Invalidate_ICache_All();
Cache_Invalidate_DCache_All();
rtc_cntl_ll_disable_cpu_retention();
}
}
}
#endif // SOC_PM_SUPPORT_CPU_PD

View File

@ -14,12 +14,19 @@
#pragma once
#include "soc/soc_caps.h"
#include "hal/gpio_types.h"
#include "hal/rtc_cntl_ll.h"
#if !CONFIG_IDF_TARGET_ESP32C3 && !CONFIG_IDF_TARGET_ESP32H2
#include "hal/rtc_io_ll.h"
#endif
typedef struct rtc_cntl_sleep_retent {
#if SOC_PM_SUPPORT_CPU_PD
void *cpu_pd_mem; /* Internal ram address for cpu retention */
#endif // SOC_PM_SUPPORT_CPU_PD
} rtc_cntl_sleep_retent_t;
#define RTC_HAL_DMA_LINK_NODE_SIZE (16)
#if SOC_PM_SUPPORT_EXT_WAKEUP
@ -48,7 +55,7 @@ void * rtc_cntl_hal_dma_link_init(void *elem, void *buff, int size, void *next);
void rtc_cntl_hal_enable_cpu_retention(void *addr);
#define rtc_cntl_hal_disable_cpu_retention() rtc_cntl_ll_disable_cpu_retention()
void rtc_cntl_hal_disable_cpu_retention(void *addr);
/*
* Enable wakeup from ULP coprocessor.

View File

@ -118,6 +118,14 @@
#define SOC_LCD_I80_BUS_WIDTH (16) /*!< Intel 8080 bus width */
#define SOC_LCD_RGB_DATA_WIDTH (16) /*!< Number of LCD data lines */
/*-------------------------- RTC CAPS --------------------------------------*/
#define SOC_RTC_CNTL_CPU_PD_DMA_BUS_WIDTH (128)
#define SOC_RTC_CNTL_CPU_PD_REG_FILE_NUM (549)
#define SOC_RTC_CNTL_CPU_PD_DMA_ADDR_ALIGN (SOC_RTC_CNTL_CPU_PD_DMA_BUS_WIDTH >> 3)
#define SOC_RTC_CNTL_CPU_PD_DMA_BLOCK_SIZE (SOC_RTC_CNTL_CPU_PD_DMA_BUS_WIDTH >> 3)
#define SOC_RTC_CNTL_CPU_PD_RETENTION_MEM_SIZE (SOC_RTC_CNTL_CPU_PD_REG_FILE_NUM * (SOC_RTC_CNTL_CPU_PD_DMA_BUS_WIDTH >> 3))
/*-------------------------- RTCIO CAPS --------------------------------------*/
#include "rtc_io_caps.h"
@ -210,6 +218,8 @@
#define SOC_PM_SUPPORT_BT_WAKEUP (1)
#define SOC_PM_SUPPORT_CPU_PD (1)
/*-------------------------- Flash Encryption CAPS----------------------------*/
#define SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX (64)