From 2bd755c95dfda8c55904607b8a222e661d25e2ff Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Fri, 19 Jan 2024 16:43:59 +0800 Subject: [PATCH 1/3] refactor(esp_hw_support): move TIMG_WDT_WKEY_VALUE defination from hal to soc --- components/hal/esp32/include/hal/mwdt_ll.h | 3 --- components/hal/esp32c2/include/hal/mwdt_ll.h | 3 --- components/hal/esp32c3/include/hal/mwdt_ll.h | 3 --- components/hal/esp32c5/include/hal/mwdt_ll.h | 3 --- components/hal/esp32c6/include/hal/mwdt_ll.h | 3 --- components/hal/esp32h2/include/hal/mwdt_ll.h | 3 --- components/hal/esp32p4/include/hal/mwdt_ll.h | 3 --- components/hal/esp32s2/include/hal/mwdt_ll.h | 3 --- components/soc/include/soc/timer_periph.h | 3 +++ 9 files changed, 3 insertions(+), 24 deletions(-) diff --git a/components/hal/esp32/include/hal/mwdt_ll.h b/components/hal/esp32/include/hal/mwdt_ll.h index c60c16d510..48a468f5ac 100644 --- a/components/hal/esp32/include/hal/mwdt_ll.h +++ b/components/hal/esp32/include/hal/mwdt_ll.h @@ -26,9 +26,6 @@ extern "C" { /* Pre-calculated prescaler to achieve 500 ticks/us (MWDT1_TICKS_PER_US) when using default clock (MWDT_CLK_SRC_DEFAULT ) */ #define MWDT_LL_DEFAULT_CLK_PRESCALER 40000 -/* The value that needs to be written to TIMG_WDT_WKEY to write-enable the wdt registers */ -#define TIMG_WDT_WKEY_VALUE 0x50D83AA1 - /* Possible values for TIMG_WDT_STGx */ #define TIMG_WDT_STG_SEL_OFF 0 #define TIMG_WDT_STG_SEL_INT 1 diff --git a/components/hal/esp32c2/include/hal/mwdt_ll.h b/components/hal/esp32c2/include/hal/mwdt_ll.h index 1fe9d77d6c..cb3649497b 100644 --- a/components/hal/esp32c2/include/hal/mwdt_ll.h +++ b/components/hal/esp32c2/include/hal/mwdt_ll.h @@ -26,9 +26,6 @@ extern "C" { /* Pre-calculated prescaler to achieve 500 ticks/us (MWDT1_TICKS_PER_US) when using default clock (MWDT_CLK_SRC_DEFAULT ) */ #define MWDT_LL_DEFAULT_CLK_PRESCALER 20000 -/* The value that needs to be written to TIMG_WDT_WKEY to write-enable the wdt registers */ -#define TIMG_WDT_WKEY_VALUE 0x50D83AA1 - /* Possible values for TIMG_WDT_STGx */ #define TIMG_WDT_STG_SEL_OFF 0 #define TIMG_WDT_STG_SEL_INT 1 diff --git a/components/hal/esp32c3/include/hal/mwdt_ll.h b/components/hal/esp32c3/include/hal/mwdt_ll.h index 264a59951f..24fd44803e 100644 --- a/components/hal/esp32c3/include/hal/mwdt_ll.h +++ b/components/hal/esp32c3/include/hal/mwdt_ll.h @@ -26,9 +26,6 @@ extern "C" { /* Pre-calculated prescaler to achieve 500 ticks/us (MWDT1_TICKS_PER_US) when using default clock (MWDT_CLK_SRC_DEFAULT ) */ #define MWDT_LL_DEFAULT_CLK_PRESCALER 20000 -/* The value that needs to be written to TIMG_WDT_WKEY to write-enable the wdt registers */ -#define TIMG_WDT_WKEY_VALUE 0x50D83AA1 - /* Possible values for TIMG_WDT_STGx */ #define TIMG_WDT_STG_SEL_OFF 0 #define TIMG_WDT_STG_SEL_INT 1 diff --git a/components/hal/esp32c5/include/hal/mwdt_ll.h b/components/hal/esp32c5/include/hal/mwdt_ll.h index ab70f2cffd..2a335affcb 100644 --- a/components/hal/esp32c5/include/hal/mwdt_ll.h +++ b/components/hal/esp32c5/include/hal/mwdt_ll.h @@ -27,9 +27,6 @@ extern "C" { /* Pre-calculated prescaler to achieve 500 ticks/us (MWDT1_TICKS_PER_US) when using default clock (MWDT_CLK_SRC_DEFAULT ) */ #define MWDT_LL_DEFAULT_CLK_PRESCALER 20000 -/* The value that needs to be written to TIMG_WDT_WKEY to write-enable the wdt registers */ -#define TIMG_WDT_WKEY_VALUE 0x50D83AA1 - /* Possible values for TIMG_WDT_STGx */ #define TIMG_WDT_STG_SEL_OFF 0 #define TIMG_WDT_STG_SEL_INT 1 diff --git a/components/hal/esp32c6/include/hal/mwdt_ll.h b/components/hal/esp32c6/include/hal/mwdt_ll.h index 45194cd881..28a34eb88a 100644 --- a/components/hal/esp32c6/include/hal/mwdt_ll.h +++ b/components/hal/esp32c6/include/hal/mwdt_ll.h @@ -27,9 +27,6 @@ extern "C" { /* Pre-calculated prescaler to achieve 500 ticks/us (MWDT1_TICKS_PER_US) when using default clock (MWDT_CLK_SRC_DEFAULT ) */ #define MWDT_LL_DEFAULT_CLK_PRESCALER 20000 -/* The value that needs to be written to TIMG_WDT_WKEY to write-enable the wdt registers */ -#define TIMG_WDT_WKEY_VALUE 0x50D83AA1 - /* Possible values for TIMG_WDT_STGx */ #define TIMG_WDT_STG_SEL_OFF 0 #define TIMG_WDT_STG_SEL_INT 1 diff --git a/components/hal/esp32h2/include/hal/mwdt_ll.h b/components/hal/esp32h2/include/hal/mwdt_ll.h index ba7f5b048b..8b2f01e2d5 100644 --- a/components/hal/esp32h2/include/hal/mwdt_ll.h +++ b/components/hal/esp32h2/include/hal/mwdt_ll.h @@ -26,9 +26,6 @@ extern "C" { /* Pre-calculated prescaler to achieve 500 ticks/us (MWDT1_TICKS_PER_US) when using default clock (MWDT_CLK_SRC_DEFAULT ) */ #define MWDT_LL_DEFAULT_CLK_PRESCALER 16000 -/* The value that needs to be written to TIMG_WDT_WKEY to write-enable the wdt registers */ -#define TIMG_WDT_WKEY_VALUE 0x50D83AA1 - /* Possible values for TIMG_WDT_STGx */ #define TIMG_WDT_STG_SEL_OFF 0 #define TIMG_WDT_STG_SEL_INT 1 diff --git a/components/hal/esp32p4/include/hal/mwdt_ll.h b/components/hal/esp32p4/include/hal/mwdt_ll.h index 892e592787..fb0091c50f 100644 --- a/components/hal/esp32p4/include/hal/mwdt_ll.h +++ b/components/hal/esp32p4/include/hal/mwdt_ll.h @@ -27,9 +27,6 @@ extern "C" { /* Pre-calculated prescaler to achieve 500 ticks/us (MWDT1_TICKS_PER_US) when using default clock (MWDT_CLK_SRC_DEFAULT ) */ #define MWDT_LL_DEFAULT_CLK_PRESCALER 20000 -/* The value that needs to be written to TIMG_WDT_WKEY to write-enable the wdt registers */ -#define TIMG_WDT_WKEY_VALUE 0x50D83AA1 - /* Possible values for TIMG_WDT_STGx */ #define TIMG_WDT_STG_SEL_OFF 0 #define TIMG_WDT_STG_SEL_INT 1 diff --git a/components/hal/esp32s2/include/hal/mwdt_ll.h b/components/hal/esp32s2/include/hal/mwdt_ll.h index 0caf6bd864..5f425bada2 100644 --- a/components/hal/esp32s2/include/hal/mwdt_ll.h +++ b/components/hal/esp32s2/include/hal/mwdt_ll.h @@ -26,9 +26,6 @@ extern "C" { /* Pre-calculated prescaler to achieve 500 ticks/us (MWDT1_TICKS_PER_US) when using default clock (MWDT_CLK_SRC_DEFAULT ) */ #define MWDT_LL_DEFAULT_CLK_PRESCALER 40000 -/* The value that needs to be written to TIMG_WDT_WKEY to write-enable the wdt registers */ -#define TIMG_WDT_WKEY_VALUE 0x50D83AA1 - /* Possible values for TIMG_WDT_STGx */ #define TIMG_WDT_STG_SEL_OFF 0 #define TIMG_WDT_STG_SEL_INT 1 diff --git a/components/soc/include/soc/timer_periph.h b/components/soc/include/soc/timer_periph.h index 7ba2047a12..883e69f787 100644 --- a/components/soc/include/soc/timer_periph.h +++ b/components/soc/include/soc/timer_periph.h @@ -16,6 +16,9 @@ extern "C" { #endif +/* The value that needs to be written to TIMG_WDT_WKEY to write-enable the wdt registers */ +#define TIMG_WDT_WKEY_VALUE 0x50D83AA1 + typedef struct { struct { const periph_module_t module; // Peripheral module From 9b3dc69908de8eb023f1b1789906b56713fd59f8 Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Thu, 18 Jan 2024 18:56:40 +0800 Subject: [PATCH 2/3] refactor(esp_hw_support): move regdma structure defination to soc components --- .../include/esp_private/esp_regdma.h | 257 +--------------- .../include/esp_private/sleep_retention.h | 39 +-- components/esp_hw_support/sleep_modem.c | 14 +- components/hal/include/hal/pau_types.h | 7 +- .../include/soc/retention_periph_defs.h | 44 +++ .../include/soc/retention_periph_defs.h | 44 +++ .../include/soc/retention_periph_defs.h | 42 +++ components/soc/include/soc/regdma.h | 282 ++++++++++++++++++ 8 files changed, 434 insertions(+), 295 deletions(-) create mode 100644 components/soc/esp32c5/include/soc/retention_periph_defs.h create mode 100644 components/soc/esp32c6/include/soc/retention_periph_defs.h create mode 100644 components/soc/esp32h2/include/soc/retention_periph_defs.h create mode 100644 components/soc/include/soc/regdma.h diff --git a/components/esp_hw_support/include/esp_private/esp_regdma.h b/components/esp_hw_support/include/esp_private/esp_regdma.h index ebf7ed423c..4ba37c7a91 100644 --- a/components/esp_hw_support/include/esp_private/esp_regdma.h +++ b/components/esp_hw_support/include/esp_private/esp_regdma.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,6 +13,7 @@ #include "esp_err.h" #include "esp_bit_defs.h" #include "soc/soc_caps.h" +#include "soc/regdma.h" #ifdef __cplusplus extern "C" { @@ -22,260 +23,6 @@ extern "C" { #include "hal/pau_types.h" #define REGDMA_LINK_DBG 0 /* Enable REGDMA link info dump apis*/ -#define REGDMA_LINK_ENTRY_NUM (PAU_REGDMA_LINK_NUM) /* Maximum number of REG DMA linked list entries */ - -#define ENTRY(n) (BIT(n)) - -#define REGDMA_PHY_LINK(_pri) ((0x00 << 8) | _pri) -#define REGDMA_PCR_LINK(_pri) ((0x01 << 8) | _pri) -#define REGDMA_MODEMSYSCON_LINK(_pri) ((0x02 << 8) | _pri) -#define REGDMA_MODEMLPCON_LINK(_pri) ((0x03 << 8) | _pri) - -#define REGDMA_INTMTX_LINK(_pri) ((0x0d << 8) | _pri) -#define REGDMA_HPSYS_LINK(_pri) ((0x0e << 8) | _pri) -#define REGDMA_TEEAPM_LINK(_pri) ((0x0f << 8) | _pri) - -#define REGDMA_UART_LINK(_pri) ((0x10 << 8) | _pri) -#define REGDMA_TIMG_LINK(_pri) ((0x11 << 8) | _pri) -#define REGDMA_IOMUX_LINK(_pri) ((0x12 << 8) | _pri) -#define REGDMA_SPIMEM_LINK(_pri) ((0x13 << 8) | _pri) -#define REGDMA_SYSTIMER_LINK(_pri) ((0x14 << 8) | _pri) -#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_FE_LINK(_pri) ((0xFF << 8) | _pri) - -typedef enum { - REGDMA_LINK_PRI_0 = 0, - REGDMA_LINK_PRI_1, - REGDMA_LINK_PRI_2, - REGDMA_LINK_PRI_3, - REGDMA_LINK_PRI_4, - REGDMA_LINK_PRI_5, - REGDMA_LINK_PRI_6, - REGDMA_LINK_PRI_7, -} regdma_link_priority_t; - -typedef pau_regdma_link_addr_t regdma_entry_buf_t; - -typedef enum regdma_link_mode { - REGDMA_LINK_MODE_CONTINUOUS = 0, /*!< Link used to backup registers with consecutive addresses */ - REGDMA_LINK_MODE_ADDR_MAP, /*!< Link used to backup selected registers according to bitmap */ - REGDMA_LINK_MODE_WRITE, /*!< Link used to direct write to registers*/ - REGDMA_LINK_MODE_WAIT /*!< Link used to wait for register value to meet condition*/ -} regdma_link_mode_t; - - -typedef struct regdma_link_head { - volatile uint32_t length: 10, /* total count of registers that need to be backup or restore, unit: 1 word = 4 bytes */ - reserve0: 6, - mode : 4, /* mode of current link */ - reserve1: 8, - branch : 1, /* branch link flag */ - skip_r : 1, /* skip the current linked node when restore the register */ - skip_b : 1, /* skip the current linked node when backup the register */ - eof : 1; /* end of link */ -} regdma_link_head_t; - -/* Continuous type linked list node body type definition */ -typedef struct regdma_link_continuous_body { - volatile void *next; - volatile void *backup; - volatile void *restore; - volatile void *mem; -} regdma_link_continuous_body_t; - -/* Address Map type linked list node body type definition */ -typedef struct regdma_link_addr_map_body { - volatile void *next; - volatile void *backup; - volatile void *restore; - volatile void *mem; - volatile uint32_t map[4]; -} regdma_link_addr_map_body_t; - -/* Write/Wait type linked list node body type definition */ -typedef struct regdma_link_write_wait_body { - volatile void *next; - volatile void *backup; - volatile uint32_t value; - volatile uint32_t mask; -} regdma_link_write_wait_body_t; - -/* Branch Continuous type linked list node body type definition */ -typedef struct regdma_link_branch_continuous_body { - regdma_entry_buf_t next; - volatile void *backup; - volatile void *restore; - volatile void *mem; -} regdma_link_branch_continuous_body_t; - -/* Branch Address Map type linked list node body type definition */ -typedef struct regdma_link_branch_addr_map_body { - regdma_entry_buf_t next; - volatile void *backup; - volatile void *restore; - volatile void *mem; - volatile uint32_t map[4]; -} regdma_link_branch_addr_map_body_t; - -/* Branch Write/Wait type linked list node body type definition */ -typedef struct regdma_link_branch_write_wait_body { - regdma_entry_buf_t next; - volatile void *backup; - volatile uint32_t value; - volatile uint32_t mask; -} regdma_link_branch_write_wait_body_t; - -ESP_STATIC_ASSERT(REGDMA_LINK_ENTRY_NUM < 16, "regdma link entry number should less 16"); -typedef struct regdma_link_stats { - volatile uint32_t ref: REGDMA_LINK_ENTRY_NUM, /* a bitmap, identifies which entry has referenced the current link */ - reserve: 16-REGDMA_LINK_ENTRY_NUM, - id: 16; /* REGDMA linked list node unique identifier */ - volatile uint32_t module; /* a bitmap used to identify the module to which the current node belongs */ -} regdma_link_stats_t; - -typedef struct regdma_link_continuous { - regdma_link_stats_t stat; - regdma_link_head_t head; - regdma_link_continuous_body_t body; - volatile uint32_t buff[0]; -} regdma_link_continuous_t; - -typedef struct regdma_link_addr_map { - regdma_link_stats_t stat; - regdma_link_head_t head; - regdma_link_addr_map_body_t body; - volatile uint32_t buff[0]; -} regdma_link_addr_map_t; - -typedef struct regdma_link_write_wait { - regdma_link_stats_t stat; - regdma_link_head_t head; - regdma_link_write_wait_body_t body; -} regdma_link_write_wait_t; - -typedef struct regdma_link_branch_continuous { - regdma_link_stats_t stat; - regdma_link_head_t head; - regdma_link_branch_continuous_body_t body; - volatile uint32_t buff[0]; -} regdma_link_branch_continuous_t; - -typedef struct regdma_link_branch_addr_map { - regdma_link_stats_t stat; - regdma_link_head_t head; - regdma_link_branch_addr_map_body_t body; - volatile uint32_t buff[0]; -} regdma_link_branch_addr_map_t; - -typedef struct regdma_link_branch_write_wait { - regdma_link_stats_t stat; - regdma_link_head_t head; - regdma_link_branch_write_wait_body_t body; -} regdma_link_branch_write_wait_t; - -typedef struct regdma_link_config { - regdma_link_head_t head; - union { - regdma_link_continuous_body_t continuous; - regdma_link_addr_map_body_t addr_map; - regdma_link_write_wait_body_t write_wait; - }; - int id; /* REGDMA linked list node unique identifier */ -} regdma_link_config_t; - - -#define REGDMA_LINK_HEAD(plink) (((regdma_link_config_t *)plink)->head) - - -#ifndef ARRAY_SIZE -# define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) -#endif - -#define REGDMA_LINK_HEAD_INIT(_l, _m, _b, _sr, _sb) \ - { \ - .length = (_l), \ - .mode = (_m), \ - .branch = (_b), \ - .skip_r = (_sr), \ - .skip_b = (_sb), \ - .eof = 0 \ - } - -#define REGDMA_LINK_CONTINUOUS_INIT(_id, _backup, _restore, _len, _skip_b, _skip_r) \ - { \ - .head = REGDMA_LINK_HEAD_INIT( \ - _len, \ - REGDMA_LINK_MODE_CONTINUOUS,\ - 0, \ - _skip_r, \ - _skip_b \ - ), \ - .continuous = { \ - .next = NULL, \ - .backup = (void *)_backup, \ - .restore = (void *)_restore, \ - .mem = NULL \ - }, \ - .id = (_id) \ - } - -#define REGDMA_LINK_ADDR_MAP_INIT(_id, _backup, _restore, _len, _skip_b, _skip_r, ...) \ - { \ - .head = REGDMA_LINK_HEAD_INIT( \ - _len, \ - REGDMA_LINK_MODE_ADDR_MAP, \ - 0, \ - _skip_r, \ - _skip_b \ - ), \ - .addr_map = { \ - .next = NULL, \ - .backup = (void *)_backup, \ - .restore = (void *)_restore, \ - .mem = NULL, \ - .map = {__VA_ARGS__} \ - }, \ - .id = (_id) \ - } - -#define REGDMA_LINK_WRITE_INIT(_id, _backup, _val, _mask, _skip_b, _skip_r) \ - { \ - .head = REGDMA_LINK_HEAD_INIT( \ - 0, \ - REGDMA_LINK_MODE_WRITE, \ - 0, \ - _skip_r, \ - _skip_b \ - ), \ - .write_wait = { \ - .next = NULL, \ - .backup = (void *)_backup, \ - .value = (_val), \ - .mask = (_mask) \ - }, \ - .id = (_id) \ - } - -#define REGDMA_LINK_WAIT_INIT(_id, _backup, _val, _mask, _skip_b, _skip_r) \ - { \ - .head = REGDMA_LINK_HEAD_INIT( \ - 0, \ - REGDMA_LINK_MODE_WAIT, \ - 0, \ - _skip_r, \ - _skip_b \ - ), \ - .write_wait = { \ - .next = NULL, \ - .backup = (void *)_backup, \ - .value = (_val), \ - .mask = (_mask) \ - }, \ - .id = (_id) \ - } - /** * @brief Create a REGDMA continuous type linked list node without retention buffer and the retention buffer is passed in by the caller diff --git a/components/esp_hw_support/include/esp_private/sleep_retention.h b/components/esp_hw_support/include/esp_private/sleep_retention.h index fd9a622072..2efbbcc7dd 100644 --- a/components/esp_hw_support/include/esp_private/sleep_retention.h +++ b/components/esp_hw_support/include/esp_private/sleep_retention.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,6 +15,7 @@ extern "C" { #if SOC_PAU_SUPPORTED #include "esp_regdma.h" +#include "soc/retention_periph_defs.h" /** * @file sleep_retention.h @@ -22,39 +23,9 @@ extern "C" { * This file contains declarations of sleep retention related functions, it * includes sleep retention list creation, destruction and debugging interfaces. */ - -typedef enum sleep_retention_module_bitmap { - /* clock module, which includes system and modem */ - SLEEP_RETENTION_MODULE_CLOCK_SYSTEM = BIT(1), - SLEEP_RETENTION_MODULE_CLOCK_MODEM = BIT(2), - - /* modem module, which includes WiFi, BLE and 802.15.4 */ - SLEEP_RETENTION_MODULE_WIFI_MAC = BIT(10), - SLEEP_RETENTION_MODULE_WIFI_BB = BIT(11), - SLEEP_RETENTION_MODULE_BLE_MAC = BIT(12), - SLEEP_RETENTION_MODULE_BT_BB = BIT(13), - SLEEP_RETENTION_MODULE_802154_MAC = BIT(14), - - /* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM, - * TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */ - SLEEP_RETENTION_MODULE_INTR_MATRIX = BIT(16), - SLEEP_RETENTION_MODULE_HP_SYSTEM = BIT(17), - SLEEP_RETENTION_MODULE_TEE_APM = BIT(18), - SLEEP_RETENTION_MODULE_UART0 = BIT(19), - SLEEP_RETENTION_MODULE_TG0 = BIT(20), - SLEEP_RETENTION_MODULE_IOMUX = BIT(21), - SLEEP_RETENTION_MODULE_SPIMEM = BIT(22), - SLEEP_RETENTION_MODULE_SYSTIMER = BIT(23), - - SLEEP_RETENTION_MODULE_ALL = (uint32_t)-1 -} sleep_retention_module_bitmap_t; - -typedef regdma_entry_buf_t sleep_retention_entries_t; - -typedef struct { - regdma_link_config_t config; - uint32_t owner; /**< Indicates which regdma entries the current node will insert into */ -} sleep_retention_entries_config_t; +typedef periph_retention_module_bitmap_t sleep_retention_module_bitmap_t; +typedef regdma_entry_buf_t sleep_retention_entries_t; +typedef regdma_entries_config_t sleep_retention_entries_config_t; /** * @brief Create a runtime sleep retention linked list diff --git a/components/esp_hw_support/sleep_modem.c b/components/esp_hw_support/sleep_modem.c index b9a6f6c252..e8480e2cff 100644 --- a/components/esp_hw_support/sleep_modem.c +++ b/components/esp_hw_support/sleep_modem.c @@ -285,16 +285,24 @@ inline __attribute__((always_inline)) bool sleep_modem_wifi_modem_link_done(void bool modem_domain_pd_allowed(void) { #if SOC_PM_MODEM_RETENTION_BY_REGDMA + bool modem_domain_pd_allowed = false; const uint32_t modules = sleep_retention_get_modules(); +#if SOC_WIFI_SUPPORTED const uint32_t mask_wifi = (const uint32_t) (SLEEP_RETENTION_MODULE_WIFI_MAC | SLEEP_RETENTION_MODULE_WIFI_BB); + modem_domain_pd_allowed |= ((modules & mask_wifi) == mask_wifi); +#endif +#if SOC_BT_SUPPORTED const uint32_t mask_ble = (const uint32_t) (SLEEP_RETENTION_MODULE_BLE_MAC | SLEEP_RETENTION_MODULE_BT_BB); + modem_domain_pd_allowed |= ((modules & mask_ble) == mask_ble); +#endif +#if SOC_IEEE802154_SUPPORTED const uint32_t mask_154 = (const uint32_t) (SLEEP_RETENTION_MODULE_802154_MAC | SLEEP_RETENTION_MODULE_BT_BB); - return (((modules & mask_wifi) == mask_wifi) || - ((modules & mask_ble) == mask_ble) || - ((modules & mask_154) == mask_154)); + modem_domain_pd_allowed |= ((modules & mask_154) == mask_154); +#endif + return modem_domain_pd_allowed; #else return false; /* MODEM power domain is controlled by each module (WiFi, Bluetooth or 15.4) of modem */ #endif diff --git a/components/hal/include/hal/pau_types.h b/components/hal/include/hal/pau_types.h index df9f82f76a..27903ceed0 100644 --- a/components/hal/include/hal/pau_types.h +++ b/components/hal/include/hal/pau_types.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,18 +7,19 @@ #include "sdkconfig.h" #include "soc/soc_caps.h" +#include "soc/regdma.h" #ifdef __cplusplus extern "C" { #endif #if SOC_PAU_SUPPORTED -#define PAU_REGDMA_LINK_NUM (SOC_PM_PAU_LINK_NUM) +#define PAU_REGDMA_LINK_NUM (REGDMA_LINK_ENTRY_NUM) /** * @brief PAU REGDMA all link address buffer */ -typedef void * pau_regdma_link_addr_t[PAU_REGDMA_LINK_NUM]; +typedef regdma_entry_buf_t pau_regdma_link_addr_t; #endif diff --git a/components/soc/esp32c5/include/soc/retention_periph_defs.h b/components/soc/esp32c5/include/soc/retention_periph_defs.h new file mode 100644 index 0000000000..6eeefd80be --- /dev/null +++ b/components/soc/esp32c5/include/soc/retention_periph_defs.h @@ -0,0 +1,44 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "esp_bit_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum periph_retention_module_bitmap { + /* clock module, which includes system and modem */ + SLEEP_RETENTION_MODULE_CLOCK_SYSTEM = BIT(1), + SLEEP_RETENTION_MODULE_CLOCK_MODEM = BIT(2), + + /* modem module, which includes WiFi, BLE and 802.15.4 */ + SLEEP_RETENTION_MODULE_WIFI_MAC = BIT(10), + SLEEP_RETENTION_MODULE_WIFI_BB = BIT(11), + SLEEP_RETENTION_MODULE_BLE_MAC = BIT(12), + SLEEP_RETENTION_MODULE_BT_BB = BIT(13), + SLEEP_RETENTION_MODULE_802154_MAC = BIT(14), + + /* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM, + * TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */ + SLEEP_RETENTION_MODULE_INTR_MATRIX = BIT(16), + SLEEP_RETENTION_MODULE_HP_SYSTEM = BIT(17), + SLEEP_RETENTION_MODULE_TEE_APM = BIT(18), + SLEEP_RETENTION_MODULE_UART0 = BIT(19), + SLEEP_RETENTION_MODULE_TG0 = BIT(20), + SLEEP_RETENTION_MODULE_IOMUX = BIT(21), + SLEEP_RETENTION_MODULE_SPIMEM = BIT(22), + SLEEP_RETENTION_MODULE_SYSTIMER = BIT(23), + + SLEEP_RETENTION_MODULE_ALL = (uint32_t)-1 +} periph_retention_module_bitmap_t; + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32c6/include/soc/retention_periph_defs.h b/components/soc/esp32c6/include/soc/retention_periph_defs.h new file mode 100644 index 0000000000..6eeefd80be --- /dev/null +++ b/components/soc/esp32c6/include/soc/retention_periph_defs.h @@ -0,0 +1,44 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "esp_bit_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum periph_retention_module_bitmap { + /* clock module, which includes system and modem */ + SLEEP_RETENTION_MODULE_CLOCK_SYSTEM = BIT(1), + SLEEP_RETENTION_MODULE_CLOCK_MODEM = BIT(2), + + /* modem module, which includes WiFi, BLE and 802.15.4 */ + SLEEP_RETENTION_MODULE_WIFI_MAC = BIT(10), + SLEEP_RETENTION_MODULE_WIFI_BB = BIT(11), + SLEEP_RETENTION_MODULE_BLE_MAC = BIT(12), + SLEEP_RETENTION_MODULE_BT_BB = BIT(13), + SLEEP_RETENTION_MODULE_802154_MAC = BIT(14), + + /* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM, + * TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */ + SLEEP_RETENTION_MODULE_INTR_MATRIX = BIT(16), + SLEEP_RETENTION_MODULE_HP_SYSTEM = BIT(17), + SLEEP_RETENTION_MODULE_TEE_APM = BIT(18), + SLEEP_RETENTION_MODULE_UART0 = BIT(19), + SLEEP_RETENTION_MODULE_TG0 = BIT(20), + SLEEP_RETENTION_MODULE_IOMUX = BIT(21), + SLEEP_RETENTION_MODULE_SPIMEM = BIT(22), + SLEEP_RETENTION_MODULE_SYSTIMER = BIT(23), + + SLEEP_RETENTION_MODULE_ALL = (uint32_t)-1 +} periph_retention_module_bitmap_t; + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32h2/include/soc/retention_periph_defs.h b/components/soc/esp32h2/include/soc/retention_periph_defs.h new file mode 100644 index 0000000000..4b7204b323 --- /dev/null +++ b/components/soc/esp32h2/include/soc/retention_periph_defs.h @@ -0,0 +1,42 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "esp_bit_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum periph_retention_module_bitmap { + /* clock module, which includes system and modem */ + SLEEP_RETENTION_MODULE_CLOCK_SYSTEM = BIT(1), + SLEEP_RETENTION_MODULE_CLOCK_MODEM = BIT(2), + + /* modem module, which includes BLE and 802.15.4 */ + SLEEP_RETENTION_MODULE_BLE_MAC = BIT(12), + SLEEP_RETENTION_MODULE_BT_BB = BIT(13), + SLEEP_RETENTION_MODULE_802154_MAC = BIT(14), + + /* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM, + * TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */ + SLEEP_RETENTION_MODULE_INTR_MATRIX = BIT(16), + SLEEP_RETENTION_MODULE_HP_SYSTEM = BIT(17), + SLEEP_RETENTION_MODULE_TEE_APM = BIT(18), + SLEEP_RETENTION_MODULE_UART0 = BIT(19), + SLEEP_RETENTION_MODULE_TG0 = BIT(20), + SLEEP_RETENTION_MODULE_IOMUX = BIT(21), + SLEEP_RETENTION_MODULE_SPIMEM = BIT(22), + SLEEP_RETENTION_MODULE_SYSTIMER = BIT(23), + + SLEEP_RETENTION_MODULE_ALL = (uint32_t)-1 +} periph_retention_module_bitmap_t; + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/include/soc/regdma.h b/components/soc/include/soc/regdma.h new file mode 100644 index 0000000000..d7bb609001 --- /dev/null +++ b/components/soc/include/soc/regdma.h @@ -0,0 +1,282 @@ +/* + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include "esp_assert.h" +#include "soc/soc_caps.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if SOC_PAU_SUPPORTED + +#define REGDMA_LINK_ENTRY_NUM (SOC_PM_PAU_LINK_NUM) /* Maximum number of REG DMA linked list entries */ + +#ifndef ARRAY_SIZE +# define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) +#endif + +#define ENTRY(n) (BIT(n)) + +#define REGDMA_PHY_LINK(_pri) ((0x00 << 8) | _pri) +#define REGDMA_PCR_LINK(_pri) ((0x01 << 8) | _pri) +#define REGDMA_MODEMSYSCON_LINK(_pri) ((0x02 << 8) | _pri) +#define REGDMA_MODEMLPCON_LINK(_pri) ((0x03 << 8) | _pri) + +#define REGDMA_INTMTX_LINK(_pri) ((0x0d << 8) | _pri) +#define REGDMA_HPSYS_LINK(_pri) ((0x0e << 8) | _pri) +#define REGDMA_TEEAPM_LINK(_pri) ((0x0f << 8) | _pri) + +#define REGDMA_UART_LINK(_pri) ((0x10 << 8) | _pri) +#define REGDMA_TIMG_LINK(_pri) ((0x11 << 8) | _pri) +#define REGDMA_IOMUX_LINK(_pri) ((0x12 << 8) | _pri) +#define REGDMA_SPIMEM_LINK(_pri) ((0x13 << 8) | _pri) +#define REGDMA_SYSTIMER_LINK(_pri) ((0x14 << 8) | _pri) +#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_FE_LINK(_pri) ((0xFF << 8) | _pri) + +typedef enum { + REGDMA_LINK_PRI_0 = 0, + REGDMA_LINK_PRI_1, + REGDMA_LINK_PRI_2, + REGDMA_LINK_PRI_3, + REGDMA_LINK_PRI_4, + REGDMA_LINK_PRI_5, + REGDMA_LINK_PRI_6, + REGDMA_LINK_PRI_7, +} regdma_link_priority_t; + + +typedef void * regdma_entry_buf_t[REGDMA_LINK_ENTRY_NUM]; + +typedef enum regdma_link_mode { + REGDMA_LINK_MODE_CONTINUOUS = 0, /*!< Link used to backup registers with consecutive addresses */ + REGDMA_LINK_MODE_ADDR_MAP, /*!< Link used to backup selected registers according to bitmap */ + REGDMA_LINK_MODE_WRITE, /*!< Link used to direct write to registers*/ + REGDMA_LINK_MODE_WAIT /*!< Link used to wait for register value to meet condition*/ +} regdma_link_mode_t; + + +typedef struct regdma_link_head { + volatile uint32_t length: 10, /* total count of registers that need to be backup or restore, unit: 1 word = 4 bytes */ + reserve0: 6, + mode : 4, /* mode of current link */ + reserve1: 8, + branch : 1, /* branch link flag */ + skip_r : 1, /* skip the current linked node when restore the register */ + skip_b : 1, /* skip the current linked node when backup the register */ + eof : 1; /* end of link */ +} regdma_link_head_t; + +/* Continuous type linked list node body type definition */ +typedef struct regdma_link_continuous_body { + volatile void *next; + volatile void *backup; + volatile void *restore; + volatile void *mem; +} regdma_link_continuous_body_t; + +/* Address Map type linked list node body type definition */ +typedef struct regdma_link_addr_map_body { + volatile void *next; + volatile void *backup; + volatile void *restore; + volatile void *mem; + volatile uint32_t map[4]; +} regdma_link_addr_map_body_t; + +/* Write/Wait type linked list node body type definition */ +typedef struct regdma_link_write_wait_body { + volatile void *next; + volatile void *backup; + volatile uint32_t value; + volatile uint32_t mask; +} regdma_link_write_wait_body_t; + +/* Branch Continuous type linked list node body type definition */ +typedef struct regdma_link_branch_continuous_body { + regdma_entry_buf_t next; + volatile void *backup; + volatile void *restore; + volatile void *mem; +} regdma_link_branch_continuous_body_t; + +/* Branch Address Map type linked list node body type definition */ +typedef struct regdma_link_branch_addr_map_body { + regdma_entry_buf_t next; + volatile void *backup; + volatile void *restore; + volatile void *mem; + volatile uint32_t map[4]; +} regdma_link_branch_addr_map_body_t; + +/* Branch Write/Wait type linked list node body type definition */ +typedef struct regdma_link_branch_write_wait_body { + regdma_entry_buf_t next; + volatile void *backup; + volatile uint32_t value; + volatile uint32_t mask; +} regdma_link_branch_write_wait_body_t; + +ESP_STATIC_ASSERT(REGDMA_LINK_ENTRY_NUM < 16, "regdma link entry number should less 16"); +typedef struct regdma_link_stats { + volatile uint32_t ref: REGDMA_LINK_ENTRY_NUM, /* a bitmap, identifies which entry has referenced the current link */ + reserve: 16-REGDMA_LINK_ENTRY_NUM, + id: 16; /* REGDMA linked list node unique identifier */ + volatile uint32_t module; /* a bitmap used to identify the module to which the current node belongs */ +} regdma_link_stats_t; + +typedef struct regdma_link_continuous { + regdma_link_stats_t stat; + regdma_link_head_t head; + regdma_link_continuous_body_t body; + volatile uint32_t buff[0]; +} regdma_link_continuous_t; + +typedef struct regdma_link_addr_map { + regdma_link_stats_t stat; + regdma_link_head_t head; + regdma_link_addr_map_body_t body; + volatile uint32_t buff[0]; +} regdma_link_addr_map_t; + +typedef struct regdma_link_write_wait { + regdma_link_stats_t stat; + regdma_link_head_t head; + regdma_link_write_wait_body_t body; +} regdma_link_write_wait_t; + +typedef struct regdma_link_branch_continuous { + regdma_link_stats_t stat; + regdma_link_head_t head; + regdma_link_branch_continuous_body_t body; + volatile uint32_t buff[0]; +} regdma_link_branch_continuous_t; + +typedef struct regdma_link_branch_addr_map { + regdma_link_stats_t stat; + regdma_link_head_t head; + regdma_link_branch_addr_map_body_t body; + volatile uint32_t buff[0]; +} regdma_link_branch_addr_map_t; + +typedef struct regdma_link_branch_write_wait { + regdma_link_stats_t stat; + regdma_link_head_t head; + regdma_link_branch_write_wait_body_t body; +} regdma_link_branch_write_wait_t; + +typedef struct regdma_link_config { + regdma_link_head_t head; + union { + regdma_link_continuous_body_t continuous; + regdma_link_addr_map_body_t addr_map; + regdma_link_write_wait_body_t write_wait; + }; + int id; /* REGDMA linked list node unique identifier */ +} regdma_link_config_t; + +typedef struct { + regdma_link_config_t config; + uint32_t owner; /**< Indicates which regdma entries the current node will insert into */ +} regdma_entries_config_t; + +#define REGDMA_LINK_HEAD(plink) (((regdma_link_config_t *)plink)->head) + +#define REGDMA_LINK_HEAD_INIT(_l, _m, _b, _sr, _sb) \ + { \ + .length = (_l), \ + .mode = (_m), \ + .branch = (_b), \ + .skip_r = (_sr), \ + .skip_b = (_sb), \ + .eof = 0 \ + } + +#define REGDMA_LINK_CONTINUOUS_INIT(_id, _backup, _restore, _len, _skip_b, _skip_r) \ + { \ + .head = REGDMA_LINK_HEAD_INIT( \ + _len, \ + REGDMA_LINK_MODE_CONTINUOUS,\ + 0, \ + _skip_r, \ + _skip_b \ + ), \ + .continuous = { \ + .next = NULL, \ + .backup = (void *)_backup, \ + .restore = (void *)_restore, \ + .mem = NULL \ + }, \ + .id = (_id) \ + } + +#define REGDMA_LINK_ADDR_MAP_INIT(_id, _backup, _restore, _len, _skip_b, _skip_r, ...) \ + { \ + .head = REGDMA_LINK_HEAD_INIT( \ + _len, \ + REGDMA_LINK_MODE_ADDR_MAP, \ + 0, \ + _skip_r, \ + _skip_b \ + ), \ + .addr_map = { \ + .next = NULL, \ + .backup = (void *)_backup, \ + .restore = (void *)_restore, \ + .mem = NULL, \ + .map = {__VA_ARGS__} \ + }, \ + .id = (_id) \ + } + +#define REGDMA_LINK_WRITE_INIT(_id, _backup, _val, _mask, _skip_b, _skip_r) \ + { \ + .head = REGDMA_LINK_HEAD_INIT( \ + 0, \ + REGDMA_LINK_MODE_WRITE, \ + 0, \ + _skip_r, \ + _skip_b \ + ), \ + .write_wait = { \ + .next = NULL, \ + .backup = (void *)_backup, \ + .value = (_val), \ + .mask = (_mask) \ + }, \ + .id = (_id) \ + } + +#define REGDMA_LINK_WAIT_INIT(_id, _backup, _val, _mask, _skip_b, _skip_r) \ + { \ + .head = REGDMA_LINK_HEAD_INIT( \ + 0, \ + REGDMA_LINK_MODE_WAIT, \ + 0, \ + _skip_r, \ + _skip_b \ + ), \ + .write_wait = { \ + .next = NULL, \ + .backup = (void *)_backup, \ + .value = (_val), \ + .mask = (_mask) \ + }, \ + .id = (_id) \ + } + +#endif // SOC_PAU_SUPPORTED + +#ifdef __cplusplus +} +#endif From f3f12e973cb3972a5f05218d00c88a44aa69fcd3 Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Fri, 19 Jan 2024 17:48:35 +0800 Subject: [PATCH 3/3] refactor(esp_hw_support): separate different chip system peripheral regs context defs to target folder --- .../esp_hw_support/sleep_system_peripheral.c | 137 +---------------- components/soc/CMakeLists.txt | 4 + .../include/soc/system_periph_retention.h | 104 +++++++++++++ .../soc/esp32c5/system_retention_periph.c | 140 ++++++++++++++++++ .../include/soc/system_periph_retention.h | 102 +++++++++++++ .../soc/esp32c6/system_retention_periph.c | 140 ++++++++++++++++++ .../include/soc/system_periph_retention.h | 102 +++++++++++++ .../soc/esp32h2/system_retention_periph.c | 139 +++++++++++++++++ 8 files changed, 734 insertions(+), 134 deletions(-) create mode 100644 components/soc/esp32c5/include/soc/system_periph_retention.h create mode 100644 components/soc/esp32c5/system_retention_periph.c create mode 100644 components/soc/esp32c6/include/soc/system_periph_retention.h create mode 100644 components/soc/esp32c6/system_retention_periph.c create mode 100644 components/soc/esp32h2/include/soc/system_periph_retention.h create mode 100644 components/soc/esp32h2/system_retention_periph.c diff --git a/components/esp_hw_support/sleep_system_peripheral.c b/components/esp_hw_support/sleep_system_peripheral.c index d4fa793ee3..856ba74b07 100644 --- a/components/esp_hw_support/sleep_system_peripheral.c +++ b/components/esp_hw_support/sleep_system_peripheral.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,6 +9,7 @@ #include "sdkconfig.h" #include "soc/soc_caps.h" +#include "soc/system_periph_retention.h" #include "esp_sleep.h" #include "esp_log.h" @@ -16,19 +17,6 @@ #include "esp_private/startup_internal.h" #include "esp_private/sleep_retention.h" -#include "esp_regdma.h" - -#include "soc/uart_reg.h" -#include "soc/systimer_reg.h" -#include "soc/timer_group_reg.h" -#include "soc/spi_mem_reg.h" -#include "soc/hp_system_reg.h" -#include "soc/tee_reg.h" -#include "soc/hp_apm_reg.h" -#include "soc/gpio_reg.h" -#include "soc/io_mux_reg.h" -#include "soc/interrupt_matrix_reg.h" -#include "hal/mwdt_ll.h" static __attribute__((unused)) const char *TAG = "sleep_sys_periph"; @@ -36,12 +24,6 @@ static __attribute__((unused)) const char *TAG = "sleep_sys_periph"; esp_err_t sleep_sys_periph_intr_matrix_retention_init(void) { - #define N_REGS_INTR_MATRIX() (((INTMTX_CORE0_CLOCK_GATE_REG - DR_REG_INTERRUPT_MATRIX_BASE) / 4) + 1) - - const static sleep_retention_entries_config_t intr_matrix_regs_retention[] = { - [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_INTMTX_LINK(0), DR_REG_INTERRUPT_MATRIX_BASE, DR_REG_INTERRUPT_MATRIX_BASE, N_REGS_INTR_MATRIX(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* intr matrix */ - }; - esp_err_t err = sleep_retention_entries_create(intr_matrix_regs_retention, ARRAY_SIZE(intr_matrix_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_INTR_MATRIX); ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (Interrupt matrix) retention"); ESP_LOGI(TAG, "Interrupt Matrix sleep retention initialization"); @@ -50,12 +32,6 @@ esp_err_t sleep_sys_periph_intr_matrix_retention_init(void) esp_err_t sleep_sys_periph_hp_system_retention_init(void) { - #define N_REGS_HP_SYSTEM() (((HP_SYSTEM_MEM_TEST_CONF_REG - DR_REG_HP_SYSTEM_BASE) / 4) + 1) - - const static sleep_retention_entries_config_t hp_system_regs_retention[] = { - [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_HPSYS_LINK(0), DR_REG_HP_SYSTEM_BASE, DR_REG_HP_SYSTEM_BASE, N_REGS_HP_SYSTEM(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* hp system */ - }; - esp_err_t err = sleep_retention_entries_create(hp_system_regs_retention, ARRAY_SIZE(hp_system_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_HP_SYSTEM); ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (HP system) retention"); ESP_LOGI(TAG, "HP System sleep retention initialization"); @@ -64,20 +40,9 @@ esp_err_t sleep_sys_periph_hp_system_retention_init(void) esp_err_t sleep_sys_periph_tee_apm_retention_init(void) { - #define N_REGS_TEE() (((TEE_CLOCK_GATE_REG - DR_REG_TEE_BASE) / 4) + 1) - #define N_REGS_APM() (((HP_APM_CLOCK_GATE_REG - DR_REG_HP_APM_BASE) / 4) + 1) - - const static sleep_retention_entries_config_t tee_apm_regs_retention[] = { - [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TEEAPM_LINK(0), DR_REG_HP_APM_BASE, DR_REG_HP_APM_BASE, N_REGS_APM(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* apm */ - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TEEAPM_LINK(1), DR_REG_TEE_BASE, DR_REG_TEE_BASE, N_REGS_TEE(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* tee */ - }; - esp_err_t err = sleep_retention_entries_create(tee_apm_regs_retention, ARRAY_SIZE(tee_apm_regs_retention), REGDMA_LINK_PRI_4, SLEEP_RETENTION_MODULE_TEE_APM); if (err == ESP_OK) { - const static sleep_retention_entries_config_t regs_highpri_retention[] = { - [0] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TEEAPM_LINK(2), TEE_M4_MODE_CTRL_REG, 0x0, 0xffffffff, 1, 0), .owner = ENTRY(2) } - }; - err = sleep_retention_entries_create(regs_highpri_retention, ARRAY_SIZE(regs_highpri_retention), REGDMA_LINK_PRI_2, SLEEP_RETENTION_MODULE_TEE_APM); + err = sleep_retention_entries_create(tee_apm_highpri_regs_retention, ARRAY_SIZE(tee_apm_highpri_regs_retention), REGDMA_LINK_PRI_2, SLEEP_RETENTION_MODULE_TEE_APM); } ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (TEE/APM) retention"); ESP_LOGI(TAG, "TEE/APM sleep retention initialization"); @@ -86,15 +51,6 @@ esp_err_t sleep_sys_periph_tee_apm_retention_init(void) esp_err_t sleep_sys_periph_uart0_retention_init(void) { - #define N_REGS_UART() (((UART_ID_REG(0) - UART_INT_RAW_REG(0)) / 4) + 1) - - const static sleep_retention_entries_config_t uart_regs_retention[] = { - [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_UART_LINK(0x00), UART_INT_RAW_REG(0), UART_INT_RAW_REG(0), N_REGS_UART(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* uart */ - /* Note: uart register should set update reg to make the configuration take effect */ - [1] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_UART_LINK(0x01), UART_REG_UPDATE_REG(0), UART_REG_UPDATE, UART_REG_UPDATE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, - [2] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_UART_LINK(0x02), UART_REG_UPDATE_REG(0), 0x0, UART_REG_UPDATE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) } - }; - esp_err_t err = sleep_retention_entries_create(uart_regs_retention, ARRAY_SIZE(uart_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_UART0); ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (UART) retention"); ESP_LOGI(TAG, "UART sleep retention initialization"); @@ -103,20 +59,6 @@ esp_err_t sleep_sys_periph_uart0_retention_init(void) esp_err_t sleep_sys_periph_tg0_retention_init(void) { - #define N_REGS_TG() (((TIMG_REGCLK_REG(0) - REG_TIMG_BASE(0)) / 4) + 1) - - const static sleep_retention_entries_config_t tg_regs_retention[] = { - /*Timer group0 backup. T0_wdt should get of write project firstly. wdt used by RTOS.*/ - [0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x00), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, /* TG0 */ - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TIMG_LINK(0x01), REG_TIMG_BASE(0), REG_TIMG_BASE(0), N_REGS_TG(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [2] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x02), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, - [3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x03), TIMG_WDTCONFIG0_REG(0), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, - [4] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x04), TIMG_T0UPDATE_REG(0), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, - [5] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_TIMG_LINK(0x05), TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, - [6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TIMG_LINK(0x06), TIMG_T0LO_REG(0), TIMG_T0LOADLO_REG(0), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [7] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x07), TIMG_T0LOAD_REG(0), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) } - }; - esp_err_t err = sleep_retention_entries_create(tg_regs_retention, ARRAY_SIZE(tg_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_TG0); ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (Timer Group) retention"); ESP_LOGI(TAG, "Timer Group sleep retention initialization"); @@ -125,24 +67,6 @@ esp_err_t sleep_sys_periph_tg0_retention_init(void) esp_err_t sleep_sys_periph_iomux_retention_init(void) { -#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32C5 // TODO: [ESP32C5] IDF-8638, IDF-8640 - #define N_REGS_IOMUX_0() (((PERIPHS_IO_MUX_SPID_U - REG_IO_MUX_BASE) / 4) + 1) - #define N_REGS_IOMUX_1() (((GPIO_FUNC34_OUT_SEL_CFG_REG - GPIO_FUNC0_OUT_SEL_CFG_REG) / 4) + 1) - #define N_REGS_IOMUX_2() (((GPIO_FUNC124_IN_SEL_CFG_REG - GPIO_STATUS_NEXT_REG) / 4) + 1) - #define N_REGS_IOMUX_3() (((GPIO_PIN34_REG - DR_REG_GPIO_BASE) / 4) + 1) -#elif CONFIG_IDF_TARGET_ESP32H2 - #define N_REGS_IOMUX_0() (((PERIPHS_IO_MUX_SPID_U - REG_IO_MUX_BASE) / 4) + 1) - #define N_REGS_IOMUX_1() (((GPIO_FUNC31_OUT_SEL_CFG_REG - GPIO_FUNC0_OUT_SEL_CFG_REG) / 4) + 1) - #define N_REGS_IOMUX_2() (((GPIO_FUNC124_IN_SEL_CFG_REG - GPIO_STATUS_NEXT_REG) / 4) + 1) - #define N_REGS_IOMUX_3() (((GPIO_PIN31_REG - DR_REG_GPIO_BASE) / 4) + 1) -#endif - const static sleep_retention_entries_config_t iomux_regs_retention[] = { - [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x00), REG_IO_MUX_BASE, REG_IO_MUX_BASE, N_REGS_IOMUX_0(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* io_mux */ - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x01), GPIO_FUNC0_OUT_SEL_CFG_REG, GPIO_FUNC0_OUT_SEL_CFG_REG, N_REGS_IOMUX_1(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x02), GPIO_STATUS_NEXT_REG, GPIO_STATUS_NEXT_REG, N_REGS_IOMUX_2(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x03), DR_REG_GPIO_BASE, DR_REG_GPIO_BASE, N_REGS_IOMUX_3(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } - }; - esp_err_t err = sleep_retention_entries_create(iomux_regs_retention, ARRAY_SIZE(iomux_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_IOMUX); ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (IO Matrix) retention"); ESP_LOGI(TAG, "IO Matrix sleep retention initialization"); @@ -151,30 +75,6 @@ esp_err_t sleep_sys_periph_iomux_retention_init(void) esp_err_t sleep_sys_periph_spimem_retention_init(void) { - #define N_REGS_SPI1_MEM_0() (((SPI_MEM_SPI_SMEM_DDR_REG(1) - REG_SPI_MEM_BASE(1)) / 4) + 1) - #define N_REGS_SPI1_MEM_1() (((SPI_MEM_SPI_SMEM_AC_REG(1) - SPI_MEM_SPI_FMEM_PMS0_ATTR_REG(1)) / 4) + 1) - #define N_REGS_SPI1_MEM_2() (1) - #define N_REGS_SPI1_MEM_3() (((SPI_MEM_DATE_REG(1) - SPI_MEM_MMU_POWER_CTRL_REG(1)) / 4) + 1) - - #define N_REGS_SPI0_MEM_0() (((SPI_MEM_SPI_SMEM_DDR_REG(0) - REG_SPI_MEM_BASE(0)) / 4) + 1) - #define N_REGS_SPI0_MEM_1() (((SPI_MEM_SPI_SMEM_AC_REG(0) - SPI_MEM_SPI_FMEM_PMS0_ATTR_REG(0)) / 4) + 1) - #define N_REGS_SPI0_MEM_2() (1) - #define N_REGS_SPI0_MEM_3() (((SPI_MEM_DATE_REG(0) - SPI_MEM_MMU_POWER_CTRL_REG(0)) / 4) + 1) - - const static sleep_retention_entries_config_t spimem_regs_retention[] = { - /* Note: SPI mem should not to write mmu SPI_MEM_MMU_ITEM_CONTENT_REG and SPI_MEM_MMU_ITEM_INDEX_REG */ - [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x00), REG_SPI_MEM_BASE(1), REG_SPI_MEM_BASE(1), N_REGS_SPI1_MEM_0(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* spi1_mem */ - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x01), SPI_MEM_SPI_FMEM_PMS0_ATTR_REG(1), SPI_MEM_SPI_FMEM_PMS0_ATTR_REG(1), N_REGS_SPI1_MEM_1(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x02), SPI_MEM_CLOCK_GATE_REG(1), SPI_MEM_CLOCK_GATE_REG(1), N_REGS_SPI1_MEM_2(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x03), SPI_MEM_MMU_POWER_CTRL_REG(1), SPI_MEM_MMU_POWER_CTRL_REG(1), N_REGS_SPI1_MEM_3(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - - /* Note: SPI mem should not to write mmu SPI_MEM_MMU_ITEM_CONTENT_REG and SPI_MEM_MMU_ITEM_INDEX_REG */ - [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x04), REG_SPI_MEM_BASE(0), REG_SPI_MEM_BASE(0), N_REGS_SPI0_MEM_0(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* spi0_mem */ - [5] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x05), SPI_MEM_SPI_FMEM_PMS0_ATTR_REG(0), SPI_MEM_SPI_FMEM_PMS0_ATTR_REG(0), N_REGS_SPI0_MEM_1(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x06), SPI_MEM_CLOCK_GATE_REG(0), SPI_MEM_CLOCK_GATE_REG(0), N_REGS_SPI0_MEM_2(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [7] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x07), SPI_MEM_MMU_POWER_CTRL_REG(0), SPI_MEM_MMU_POWER_CTRL_REG(0), N_REGS_SPI0_MEM_3(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } - }; - esp_err_t err = sleep_retention_entries_create(spimem_regs_retention, ARRAY_SIZE(spimem_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_SPIMEM); ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (SPI mem) retention"); ESP_LOGI(TAG, "SPI Mem sleep retention initialization"); @@ -183,37 +83,6 @@ esp_err_t sleep_sys_periph_spimem_retention_init(void) esp_err_t sleep_sys_periph_systimer_retention_init(void) { - #define N_REGS_SYSTIMER_0() (((SYSTIMER_TARGET2_CONF_REG - SYSTIMER_TARGET0_HI_REG) / 4) + 1) - - const static sleep_retention_entries_config_t systimer_regs_retention[] = { - [0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x00), SYSTIMER_UNIT0_OP_REG, SYSTIMER_TIMER_UNIT0_UPDATE_M, SYSTIMER_TIMER_UNIT0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, /* Systimer */ - [1] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_SYSTIMER_LINK(0x01), SYSTIMER_UNIT0_OP_REG, SYSTIMER_TIMER_UNIT0_VALUE_VALID, SYSTIMER_TIMER_UNIT0_VALUE_VALID, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, - [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x02), SYSTIMER_UNIT0_VALUE_HI_REG, SYSTIMER_UNIT0_LOAD_HI_REG, 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x03), SYSTIMER_UNIT0_LOAD_REG, SYSTIMER_TIMER_UNIT0_LOAD_M, SYSTIMER_TIMER_UNIT0_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, - - [4] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x04), SYSTIMER_UNIT1_OP_REG, SYSTIMER_TIMER_UNIT1_UPDATE_M, SYSTIMER_TIMER_UNIT1_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, - [5] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_SYSTIMER_LINK(0x05), SYSTIMER_UNIT1_OP_REG, SYSTIMER_TIMER_UNIT1_VALUE_VALID, SYSTIMER_TIMER_UNIT1_VALUE_VALID, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, - [6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x06), SYSTIMER_UNIT1_VALUE_HI_REG, SYSTIMER_UNIT1_LOAD_HI_REG, 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [7] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x07), SYSTIMER_UNIT1_LOAD_REG, SYSTIMER_TIMER_UNIT1_LOAD_M, SYSTIMER_TIMER_UNIT1_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, - - [8] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x08), SYSTIMER_TARGET0_HI_REG, SYSTIMER_TARGET0_HI_REG, N_REGS_SYSTIMER_0(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* Systimer target value & period */ - - [9] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x09), SYSTIMER_COMP0_LOAD_REG, SYSTIMER_TIMER_COMP0_LOAD, SYSTIMER_TIMER_COMP0_LOAD, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, - [10] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x0a), SYSTIMER_COMP1_LOAD_REG, SYSTIMER_TIMER_COMP1_LOAD, SYSTIMER_TIMER_COMP1_LOAD, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, - [11] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x0b), SYSTIMER_COMP2_LOAD_REG, SYSTIMER_TIMER_COMP2_LOAD, SYSTIMER_TIMER_COMP2_LOAD, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, - - [12] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x0c), SYSTIMER_TARGET0_CONF_REG, 0, SYSTIMER_TARGET0_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, - [13] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x0d), SYSTIMER_TARGET0_CONF_REG, SYSTIMER_TARGET0_PERIOD_MODE_M, SYSTIMER_TARGET0_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, - - [14] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x0e), SYSTIMER_TARGET1_CONF_REG, 0, SYSTIMER_TARGET1_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, - [15] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x0f), SYSTIMER_TARGET1_CONF_REG, SYSTIMER_TARGET1_PERIOD_MODE_M, SYSTIMER_TARGET1_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, - - [16] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x10), SYSTIMER_TARGET2_CONF_REG, 0, SYSTIMER_TARGET2_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, - - [17] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x11), SYSTIMER_CONF_REG, SYSTIMER_CONF_REG, 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* Systimer work enable */ - [18] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x12), SYSTIMER_INT_ENA_REG, SYSTIMER_INT_ENA_REG, 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* Systimer intr enable */ - }; - esp_err_t err = sleep_retention_entries_create(systimer_regs_retention, ARRAY_SIZE(systimer_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_SYSTIMER); ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (SysTimer) retention"); ESP_LOGI(TAG, "SysTimer sleep retention initialization"); diff --git a/components/soc/CMakeLists.txt b/components/soc/CMakeLists.txt index ea4f978498..9f15f0b627 100644 --- a/components/soc/CMakeLists.txt +++ b/components/soc/CMakeLists.txt @@ -126,6 +126,10 @@ if(CONFIG_SOC_SDIO_SLAVE_SUPPORTED) list(APPEND srcs "${target}/sdio_slave_periph.c") endif() +if(CONFIG_SOC_PAU_SUPPORTED) + list(APPEND srcs "${target}/system_retention_periph.c") +endif() + idf_component_register(SRCS ${srcs} INCLUDE_DIRS ${includes} LDFRAGMENTS "linker.lf") diff --git a/components/soc/esp32c5/include/soc/system_periph_retention.h b/components/soc/esp32c5/include/soc/system_periph_retention.h new file mode 100644 index 0000000000..9beb56b644 --- /dev/null +++ b/components/soc/esp32c5/include/soc/system_periph_retention.h @@ -0,0 +1,104 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "soc/soc_caps.h" +#include "soc/regdma.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +#if SOC_PAU_SUPPORTED // TODO: [ESP32C5] IDF-8640 +/** + * @brief Provide access to interrupt matrix configuration registers retention + * context defination. + * + * This is an internal function of the sleep retention driver, and is not + * useful for external use. + */ +#define INT_MTX_RETENTION_LINK_LEN 1 +extern const regdma_entries_config_t intr_matrix_regs_retention[INT_MTX_RETENTION_LINK_LEN]; + +/** + * @brief Provide access to hp_system configuration registers retention + * context defination. + * + * This is an internal function of the sleep retention driver, and is not + * useful for external use. + */ +#define HP_SYSTEM_RETENTION_LINK_LEN 1 +extern const regdma_entries_config_t hp_system_regs_retention[HP_SYSTEM_RETENTION_LINK_LEN]; + +/** + * @brief Provide access to TEE_APM configuration registers retention + * context defination. + * + * This is an internal function of the sleep retention driver, and is not + * useful for external use. + */ +#define TEE_APM_RETENTION_LINK_LEN 2 +extern const regdma_entries_config_t tee_apm_regs_retention[TEE_APM_RETENTION_LINK_LEN]; +#define TEE_APM_HIGH_PRI_RETENTION_LINK_LEN 1 +extern const regdma_entries_config_t tee_apm_highpri_regs_retention[TEE_APM_HIGH_PRI_RETENTION_LINK_LEN]; + +/** + * @brief Provide access to uart configuration registers retention + * context defination. + * + * This is an internal function of the sleep retention driver, and is not + * useful for external use. + */ +#define UART_RETENTION_LINK_LEN 3 +extern const regdma_entries_config_t uart_regs_retention[UART_RETENTION_LINK_LEN]; + +/** + * @brief Provide access to timer group configuration registers retention + * context defination. + * + * This is an internal function of the sleep retention driver, and is not + * useful for external use. + */ +#define TIMG_RETENTION_LINK_LEN 8 +extern const regdma_entries_config_t tg_regs_retention[TIMG_RETENTION_LINK_LEN]; + +/** + * @brief Provide access to IOMUX configuration registers retention + * context defination. + * + * This is an internal function of the sleep retention driver, and is not + * useful for external use. + */ +#define IOMUX_RETENTION_LINK_LEN 4 +extern const regdma_entries_config_t iomux_regs_retention[IOMUX_RETENTION_LINK_LEN]; + +/** + * @brief Provide access to spimem configuration registers retention + * context defination. + * + * This is an internal function of the sleep retention driver, and is not + * useful for external use. + */ +#define SPIMEM_RETENTION_LINK_LEN 8 +extern const regdma_entries_config_t spimem_regs_retention[SPIMEM_RETENTION_LINK_LEN]; + +/** + * @brief Provide access to systimer configuration registers retention + * context defination. + * + * This is an internal function of the sleep retention driver, and is not + * useful for external use. + */ +#define SYSTIMER_RETENTION_LINK_LEN 19 +extern const regdma_entries_config_t systimer_regs_retention[SYSTIMER_RETENTION_LINK_LEN]; +#endif + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32c5/system_retention_periph.c b/components/soc/esp32c5/system_retention_periph.c new file mode 100644 index 0000000000..e894e95b92 --- /dev/null +++ b/components/soc/esp32c5/system_retention_periph.c @@ -0,0 +1,140 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/regdma.h" +#include "soc/system_periph_retention.h" +#include "soc/timer_periph.h" +#include "soc/uart_reg.h" +#include "soc/systimer_reg.h" +#include "soc/timer_group_reg.h" +#include "soc/spi_mem_reg.h" +#include "soc/hp_system_reg.h" +#include "soc/tee_reg.h" +#include "soc/hp_apm_reg.h" +#include "soc/gpio_reg.h" +#include "soc/io_mux_reg.h" +#include "soc/interrupt_matrix_reg.h" + +/* Interrupt Matrix Registers Context */ +#define N_REGS_INTR_MATRIX() (((INTMTX_CORE0_CLOCK_GATE_REG - DR_REG_INTERRUPT_MATRIX_BASE) / 4) + 1) +const regdma_entries_config_t intr_matrix_regs_retention[] = { + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_INTMTX_LINK(0), DR_REG_INTERRUPT_MATRIX_BASE, DR_REG_INTERRUPT_MATRIX_BASE, N_REGS_INTR_MATRIX(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* intr matrix */ +}; +_Static_assert(ARRAY_SIZE(intr_matrix_regs_retention) == INT_MTX_RETENTION_LINK_LEN, "Inconsistent INT_MTX retention link length definitions"); + +/* HP System Registers Context */ +#define N_REGS_HP_SYSTEM() (((HP_SYSTEM_MEM_TEST_CONF_REG - DR_REG_HP_SYSTEM_BASE) / 4) + 1) +const regdma_entries_config_t hp_system_regs_retention[] = { + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_HPSYS_LINK(0), DR_REG_HP_SYSTEM_BASE, DR_REG_HP_SYSTEM_BASE, N_REGS_HP_SYSTEM(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* hp system */ +}; +_Static_assert(ARRAY_SIZE(hp_system_regs_retention) == HP_SYSTEM_RETENTION_LINK_LEN, "Inconsistent HP_SYSTEM retention link length definitions"); + +/* TEE/APM Registers Context */ +#define N_REGS_TEE() (((TEE_CLOCK_GATE_REG - DR_REG_TEE_BASE) / 4) + 1) +#define N_REGS_APM() (((HP_APM_CLOCK_GATE_REG - DR_REG_HP_APM_BASE) / 4) + 1) +const regdma_entries_config_t tee_apm_regs_retention[] = { + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TEEAPM_LINK(0), DR_REG_HP_APM_BASE, DR_REG_HP_APM_BASE, N_REGS_APM(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* apm */ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TEEAPM_LINK(1), DR_REG_TEE_BASE, DR_REG_TEE_BASE, N_REGS_TEE(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* tee */ +}; +const regdma_entries_config_t tee_apm_highpri_regs_retention[] = { + [0] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TEEAPM_LINK(2), TEE_M4_MODE_CTRL_REG, 0x0, 0xffffffff, 1, 0), .owner = ENTRY(2) } +}; +_Static_assert((ARRAY_SIZE(tee_apm_regs_retention) == TEE_APM_RETENTION_LINK_LEN) && (ARRAY_SIZE(tee_apm_highpri_regs_retention) == TEE_APM_HIGH_PRI_RETENTION_LINK_LEN), "Inconsistent TEE_APM retention link length definitions"); + +/* UART0 Registers Context */ +#define N_REGS_UART() (((UART_ID_REG(0) - UART_INT_RAW_REG(0)) / 4) + 1) +const regdma_entries_config_t uart_regs_retention[] = { + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_UART_LINK(0x00), UART_INT_RAW_REG(0), UART_INT_RAW_REG(0), N_REGS_UART(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* uart */ + /* Note: uart register should set update reg to make the configuration take effect */ + [1] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_UART_LINK(0x01), UART_REG_UPDATE_REG(0), UART_REG_UPDATE, UART_REG_UPDATE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [2] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_UART_LINK(0x02), UART_REG_UPDATE_REG(0), 0x0, UART_REG_UPDATE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) } +}; +_Static_assert(ARRAY_SIZE(uart_regs_retention) == UART_RETENTION_LINK_LEN, "Inconsistent UART retention link length definitions"); + +/* Timergroup Registers Context */ +#define N_REGS_TG() (((TIMG_REGCLK_REG(0) - REG_TIMG_BASE(0)) / 4) + 1) +const regdma_entries_config_t tg_regs_retention[] = { + /*Timer group0 backup. T0_wdt should get of write project firstly. wdt used by RTOS.*/ + [0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x00), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, /* TG0 */ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TIMG_LINK(0x01), REG_TIMG_BASE(0), REG_TIMG_BASE(0), N_REGS_TG(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [2] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x02), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x03), TIMG_WDTCONFIG0_REG(0), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [4] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x04), TIMG_T0UPDATE_REG(0), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, + [5] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_TIMG_LINK(0x05), TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, + [6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TIMG_LINK(0x06), TIMG_T0LO_REG(0), TIMG_T0LOADLO_REG(0), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [7] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x07), TIMG_T0LOAD_REG(0), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) } +}; +_Static_assert(ARRAY_SIZE(tg_regs_retention) == TIMG_RETENTION_LINK_LEN, "Inconsistent Timergroup retention link length definitions"); + +/* IO MUX Registers Context */ +// TODO: [ESP32C5] IDF-8638, IDF-8640 +#define N_REGS_IOMUX_0() (((PERIPHS_IO_MUX_SPID_U - REG_IO_MUX_BASE) / 4) + 1) +#define N_REGS_IOMUX_1() (((GPIO_FUNC34_OUT_SEL_CFG_REG - GPIO_FUNC0_OUT_SEL_CFG_REG) / 4) + 1) +#define N_REGS_IOMUX_2() (((GPIO_FUNC124_IN_SEL_CFG_REG - GPIO_STATUS_NEXT_REG) / 4) + 1) +#define N_REGS_IOMUX_3() (((GPIO_PIN34_REG - DR_REG_GPIO_BASE) / 4) + 1) +const regdma_entries_config_t iomux_regs_retention[] = { + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x00), REG_IO_MUX_BASE, REG_IO_MUX_BASE, N_REGS_IOMUX_0(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* io_mux */ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x01), GPIO_FUNC0_OUT_SEL_CFG_REG, GPIO_FUNC0_OUT_SEL_CFG_REG, N_REGS_IOMUX_1(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x02), GPIO_STATUS_NEXT_REG, GPIO_STATUS_NEXT_REG, N_REGS_IOMUX_2(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x03), DR_REG_GPIO_BASE, DR_REG_GPIO_BASE, N_REGS_IOMUX_3(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } +}; +_Static_assert(ARRAY_SIZE(iomux_regs_retention) == IOMUX_RETENTION_LINK_LEN, "Inconsistent IOMUX retention link length definitions"); + +/* Mememory SPI Registers Context */ +#define N_REGS_SPI1_MEM_0() (((SPI_MEM_SPI_SMEM_DDR_REG(1) - REG_SPI_MEM_BASE(1)) / 4) + 1) +#define N_REGS_SPI1_MEM_1() (((SPI_MEM_SPI_SMEM_AC_REG(1) - SPI_MEM_SPI_FMEM_PMS0_ATTR_REG(1)) / 4) + 1) +#define N_REGS_SPI1_MEM_2() (1) +#define N_REGS_SPI1_MEM_3() (((SPI_MEM_DATE_REG(1) - SPI_MEM_MMU_POWER_CTRL_REG(1)) / 4) + 1) +#define N_REGS_SPI0_MEM_0() (((SPI_MEM_SPI_SMEM_DDR_REG(0) - REG_SPI_MEM_BASE(0)) / 4) + 1) +#define N_REGS_SPI0_MEM_1() (((SPI_MEM_SPI_SMEM_AC_REG(0) - SPI_MEM_SPI_FMEM_PMS0_ATTR_REG(0)) / 4) + 1) +#define N_REGS_SPI0_MEM_2() (1) +#define N_REGS_SPI0_MEM_3() (((SPI_MEM_DATE_REG(0) - SPI_MEM_MMU_POWER_CTRL_REG(0)) / 4) + 1) +const regdma_entries_config_t spimem_regs_retention[] = { + /* Note: SPI mem should not to write mmu SPI_MEM_MMU_ITEM_CONTENT_REG and SPI_MEM_MMU_ITEM_INDEX_REG */ + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x00), REG_SPI_MEM_BASE(1), REG_SPI_MEM_BASE(1), N_REGS_SPI1_MEM_0(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* spi1_mem */ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x01), SPI_MEM_SPI_FMEM_PMS0_ATTR_REG(1), SPI_MEM_SPI_FMEM_PMS0_ATTR_REG(1), N_REGS_SPI1_MEM_1(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x02), SPI_MEM_CLOCK_GATE_REG(1), SPI_MEM_CLOCK_GATE_REG(1), N_REGS_SPI1_MEM_2(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x03), SPI_MEM_MMU_POWER_CTRL_REG(1), SPI_MEM_MMU_POWER_CTRL_REG(1), N_REGS_SPI1_MEM_3(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + + /* Note: SPI mem should not to write mmu SPI_MEM_MMU_ITEM_CONTENT_REG and SPI_MEM_MMU_ITEM_INDEX_REG */ + [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x04), REG_SPI_MEM_BASE(0), REG_SPI_MEM_BASE(0), N_REGS_SPI0_MEM_0(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* spi0_mem */ + [5] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x05), SPI_MEM_SPI_FMEM_PMS0_ATTR_REG(0), SPI_MEM_SPI_FMEM_PMS0_ATTR_REG(0), N_REGS_SPI0_MEM_1(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x06), SPI_MEM_CLOCK_GATE_REG(0), SPI_MEM_CLOCK_GATE_REG(0), N_REGS_SPI0_MEM_2(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [7] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x07), SPI_MEM_MMU_POWER_CTRL_REG(0), SPI_MEM_MMU_POWER_CTRL_REG(0), N_REGS_SPI0_MEM_3(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } +}; +_Static_assert(ARRAY_SIZE(spimem_regs_retention) == SPIMEM_RETENTION_LINK_LEN, "Inconsistent SPI Mem retention link length definitions"); + +/* Systimer Registers Context */ +#define N_REGS_SYSTIMER_0() (((SYSTIMER_TARGET2_CONF_REG - SYSTIMER_TARGET0_HI_REG) / 4) + 1) +const regdma_entries_config_t systimer_regs_retention[] = { + [0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x00), SYSTIMER_UNIT0_OP_REG, SYSTIMER_TIMER_UNIT0_UPDATE_M, SYSTIMER_TIMER_UNIT0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, /* Systimer */ + [1] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_SYSTIMER_LINK(0x01), SYSTIMER_UNIT0_OP_REG, SYSTIMER_TIMER_UNIT0_VALUE_VALID, SYSTIMER_TIMER_UNIT0_VALUE_VALID, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, + [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x02), SYSTIMER_UNIT0_VALUE_HI_REG, SYSTIMER_UNIT0_LOAD_HI_REG, 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x03), SYSTIMER_UNIT0_LOAD_REG, SYSTIMER_TIMER_UNIT0_LOAD_M, SYSTIMER_TIMER_UNIT0_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + + [4] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x04), SYSTIMER_UNIT1_OP_REG, SYSTIMER_TIMER_UNIT1_UPDATE_M, SYSTIMER_TIMER_UNIT1_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, + [5] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_SYSTIMER_LINK(0x05), SYSTIMER_UNIT1_OP_REG, SYSTIMER_TIMER_UNIT1_VALUE_VALID, SYSTIMER_TIMER_UNIT1_VALUE_VALID, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, + [6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x06), SYSTIMER_UNIT1_VALUE_HI_REG, SYSTIMER_UNIT1_LOAD_HI_REG, 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [7] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x07), SYSTIMER_UNIT1_LOAD_REG, SYSTIMER_TIMER_UNIT1_LOAD_M, SYSTIMER_TIMER_UNIT1_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + + [8] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x08), SYSTIMER_TARGET0_HI_REG, SYSTIMER_TARGET0_HI_REG, N_REGS_SYSTIMER_0(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* Systimer target value & period */ + + [9] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x09), SYSTIMER_COMP0_LOAD_REG, SYSTIMER_TIMER_COMP0_LOAD, SYSTIMER_TIMER_COMP0_LOAD, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [10] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x0a), SYSTIMER_COMP1_LOAD_REG, SYSTIMER_TIMER_COMP1_LOAD, SYSTIMER_TIMER_COMP1_LOAD, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [11] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x0b), SYSTIMER_COMP2_LOAD_REG, SYSTIMER_TIMER_COMP2_LOAD, SYSTIMER_TIMER_COMP2_LOAD, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + + [12] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x0c), SYSTIMER_TARGET0_CONF_REG, 0, SYSTIMER_TARGET0_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [13] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x0d), SYSTIMER_TARGET0_CONF_REG, SYSTIMER_TARGET0_PERIOD_MODE_M, SYSTIMER_TARGET0_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + + [14] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x0e), SYSTIMER_TARGET1_CONF_REG, 0, SYSTIMER_TARGET1_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [15] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x0f), SYSTIMER_TARGET1_CONF_REG, SYSTIMER_TARGET1_PERIOD_MODE_M, SYSTIMER_TARGET1_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + + [16] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x10), SYSTIMER_TARGET2_CONF_REG, 0, SYSTIMER_TARGET2_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + + [17] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x11), SYSTIMER_CONF_REG, SYSTIMER_CONF_REG, 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* Systimer work enable */ + [18] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x12), SYSTIMER_INT_ENA_REG, SYSTIMER_INT_ENA_REG, 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* Systimer intr enable */ +}; +_Static_assert(ARRAY_SIZE(systimer_regs_retention) == SYSTIMER_RETENTION_LINK_LEN, "Inconsistent Systimer retention link length definitions"); diff --git a/components/soc/esp32c6/include/soc/system_periph_retention.h b/components/soc/esp32c6/include/soc/system_periph_retention.h new file mode 100644 index 0000000000..6c84932742 --- /dev/null +++ b/components/soc/esp32c6/include/soc/system_periph_retention.h @@ -0,0 +1,102 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "soc/soc_caps.h" +#include "soc/regdma.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @brief Provide access to interrupt matrix configuration registers retention + * context defination. + * + * This is an internal function of the sleep retention driver, and is not + * useful for external use. + */ +#define INT_MTX_RETENTION_LINK_LEN 1 +extern const regdma_entries_config_t intr_matrix_regs_retention[INT_MTX_RETENTION_LINK_LEN]; + +/** + * @brief Provide access to hp_system configuration registers retention + * context defination. + * + * This is an internal function of the sleep retention driver, and is not + * useful for external use. + */ +#define HP_SYSTEM_RETENTION_LINK_LEN 1 +extern const regdma_entries_config_t hp_system_regs_retention[HP_SYSTEM_RETENTION_LINK_LEN]; + +/** + * @brief Provide access to TEE_APM configuration registers retention + * context defination. + * + * This is an internal function of the sleep retention driver, and is not + * useful for external use. + */ +#define TEE_APM_RETENTION_LINK_LEN 2 +extern const regdma_entries_config_t tee_apm_regs_retention[TEE_APM_RETENTION_LINK_LEN]; +#define TEE_APM_HIGH_PRI_RETENTION_LINK_LEN 1 +extern const regdma_entries_config_t tee_apm_highpri_regs_retention[TEE_APM_HIGH_PRI_RETENTION_LINK_LEN]; + +/** + * @brief Provide access to uart configuration registers retention + * context defination. + * + * This is an internal function of the sleep retention driver, and is not + * useful for external use. + */ +#define UART_RETENTION_LINK_LEN 3 +extern const regdma_entries_config_t uart_regs_retention[UART_RETENTION_LINK_LEN]; + +/** + * @brief Provide access to timer group configuration registers retention + * context defination. + * + * This is an internal function of the sleep retention driver, and is not + * useful for external use. + */ +#define TIMG_RETENTION_LINK_LEN 8 +extern const regdma_entries_config_t tg_regs_retention[TIMG_RETENTION_LINK_LEN]; + +/** + * @brief Provide access to IOMUX configuration registers retention + * context defination. + * + * This is an internal function of the sleep retention driver, and is not + * useful for external use. + */ +#define IOMUX_RETENTION_LINK_LEN 4 +extern const regdma_entries_config_t iomux_regs_retention[IOMUX_RETENTION_LINK_LEN]; + +/** + * @brief Provide access to spimem configuration registers retention + * context defination. + * + * This is an internal function of the sleep retention driver, and is not + * useful for external use. + */ +#define SPIMEM_RETENTION_LINK_LEN 8 +extern const regdma_entries_config_t spimem_regs_retention[SPIMEM_RETENTION_LINK_LEN]; + +/** + * @brief Provide access to systimer configuration registers retention + * context defination. + * + * This is an internal function of the sleep retention driver, and is not + * useful for external use. + */ +#define SYSTIMER_RETENTION_LINK_LEN 19 +extern const regdma_entries_config_t systimer_regs_retention[SYSTIMER_RETENTION_LINK_LEN]; + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32c6/system_retention_periph.c b/components/soc/esp32c6/system_retention_periph.c new file mode 100644 index 0000000000..0b643f4e5b --- /dev/null +++ b/components/soc/esp32c6/system_retention_periph.c @@ -0,0 +1,140 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/regdma.h" +#include "soc/system_periph_retention.h" +#include "soc/timer_periph.h" +#include "soc/uart_reg.h" +#include "soc/systimer_reg.h" +#include "soc/timer_group_reg.h" +#include "soc/spi_mem_reg.h" +#include "soc/hp_system_reg.h" +#include "soc/tee_reg.h" +#include "soc/hp_apm_reg.h" +#include "soc/gpio_reg.h" +#include "soc/io_mux_reg.h" +#include "soc/interrupt_matrix_reg.h" + +/* Interrupt Matrix Registers Context */ +#define N_REGS_INTR_MATRIX() (((INTMTX_CORE0_CLOCK_GATE_REG - DR_REG_INTERRUPT_MATRIX_BASE) / 4) + 1) +const regdma_entries_config_t intr_matrix_regs_retention[] = { + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_INTMTX_LINK(0), DR_REG_INTERRUPT_MATRIX_BASE, DR_REG_INTERRUPT_MATRIX_BASE, N_REGS_INTR_MATRIX(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* intr matrix */ +}; +_Static_assert(ARRAY_SIZE(intr_matrix_regs_retention) == INT_MTX_RETENTION_LINK_LEN, "Inconsistent INT_MTX retention link length definitions"); + +/* HP System Registers Context */ +#define N_REGS_HP_SYSTEM() (((HP_SYSTEM_MEM_TEST_CONF_REG - DR_REG_HP_SYSTEM_BASE) / 4) + 1) +const regdma_entries_config_t hp_system_regs_retention[] = { + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_HPSYS_LINK(0), DR_REG_HP_SYSTEM_BASE, DR_REG_HP_SYSTEM_BASE, N_REGS_HP_SYSTEM(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* hp system */ +}; +_Static_assert(ARRAY_SIZE(hp_system_regs_retention) == HP_SYSTEM_RETENTION_LINK_LEN, "Inconsistent HP_SYSTEM retention link length definitions"); + +/* TEE/APM Registers Context */ +#define N_REGS_TEE() (((TEE_CLOCK_GATE_REG - DR_REG_TEE_BASE) / 4) + 1) +#define N_REGS_APM() (((HP_APM_CLOCK_GATE_REG - DR_REG_HP_APM_BASE) / 4) + 1) +const regdma_entries_config_t tee_apm_regs_retention[] = { + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TEEAPM_LINK(0), DR_REG_HP_APM_BASE, DR_REG_HP_APM_BASE, N_REGS_APM(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* apm */ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TEEAPM_LINK(1), DR_REG_TEE_BASE, DR_REG_TEE_BASE, N_REGS_TEE(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* tee */ +}; +const regdma_entries_config_t tee_apm_highpri_regs_retention[] = { + [0] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TEEAPM_LINK(2), TEE_M4_MODE_CTRL_REG, 0x0, 0xffffffff, 1, 0), .owner = ENTRY(2) } +}; +_Static_assert((ARRAY_SIZE(tee_apm_regs_retention) == TEE_APM_RETENTION_LINK_LEN) && (ARRAY_SIZE(tee_apm_highpri_regs_retention) == TEE_APM_HIGH_PRI_RETENTION_LINK_LEN), "Inconsistent TEE_APM retention link length definitions"); + +/* UART0 Registers Context */ +#define N_REGS_UART() (((UART_ID_REG(0) - UART_INT_RAW_REG(0)) / 4) + 1) +const regdma_entries_config_t uart_regs_retention[] = { + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_UART_LINK(0x00), UART_INT_RAW_REG(0), UART_INT_RAW_REG(0), N_REGS_UART(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* uart */ + /* Note: uart register should set update reg to make the configuration take effect */ + [1] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_UART_LINK(0x01), UART_REG_UPDATE_REG(0), UART_REG_UPDATE, UART_REG_UPDATE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [2] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_UART_LINK(0x02), UART_REG_UPDATE_REG(0), 0x0, UART_REG_UPDATE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) } +}; +_Static_assert(ARRAY_SIZE(uart_regs_retention) == UART_RETENTION_LINK_LEN, "Inconsistent UART retention link length definitions"); + +/* Timergroup Registers Context */ +#define N_REGS_TG() (((TIMG_REGCLK_REG(0) - REG_TIMG_BASE(0)) / 4) + 1) +const regdma_entries_config_t tg_regs_retention[] = { + /*Timer group0 backup. T0_wdt should get of write project firstly. wdt used by RTOS.*/ + [0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x00), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, /* TG0 */ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TIMG_LINK(0x01), REG_TIMG_BASE(0), REG_TIMG_BASE(0), N_REGS_TG(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [2] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x02), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x03), TIMG_WDTCONFIG0_REG(0), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [4] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x04), TIMG_T0UPDATE_REG(0), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, + [5] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_TIMG_LINK(0x05), TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, + [6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TIMG_LINK(0x06), TIMG_T0LO_REG(0), TIMG_T0LOADLO_REG(0), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [7] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x07), TIMG_T0LOAD_REG(0), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) } +}; +_Static_assert(ARRAY_SIZE(tg_regs_retention) == TIMG_RETENTION_LINK_LEN, "Inconsistent Timergroup retention link length definitions"); + +/* IO MUX Registers Context */ +#define N_REGS_IOMUX_0() (((PERIPHS_IO_MUX_SPID_U - REG_IO_MUX_BASE) / 4) + 1) +#define N_REGS_IOMUX_1() (((GPIO_FUNC34_OUT_SEL_CFG_REG - GPIO_FUNC0_OUT_SEL_CFG_REG) / 4) + 1) +#define N_REGS_IOMUX_2() (((GPIO_FUNC124_IN_SEL_CFG_REG - GPIO_STATUS_NEXT_REG) / 4) + 1) +#define N_REGS_IOMUX_3() (((GPIO_PIN34_REG - DR_REG_GPIO_BASE) / 4) + 1) + +const regdma_entries_config_t iomux_regs_retention[] = { + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x00), REG_IO_MUX_BASE, REG_IO_MUX_BASE, N_REGS_IOMUX_0(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* io_mux */ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x01), GPIO_FUNC0_OUT_SEL_CFG_REG, GPIO_FUNC0_OUT_SEL_CFG_REG, N_REGS_IOMUX_1(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x02), GPIO_STATUS_NEXT_REG, GPIO_STATUS_NEXT_REG, N_REGS_IOMUX_2(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x03), DR_REG_GPIO_BASE, DR_REG_GPIO_BASE, N_REGS_IOMUX_3(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } +}; +_Static_assert(ARRAY_SIZE(iomux_regs_retention) == IOMUX_RETENTION_LINK_LEN, "Inconsistent IOMUX retention link length definitions"); + +/* Mememory SPI Registers Context */ +#define N_REGS_SPI1_MEM_0() (((SPI_MEM_SPI_SMEM_DDR_REG(1) - REG_SPI_MEM_BASE(1)) / 4) + 1) +#define N_REGS_SPI1_MEM_1() (((SPI_MEM_SPI_SMEM_AC_REG(1) - SPI_MEM_SPI_FMEM_PMS0_ATTR_REG(1)) / 4) + 1) +#define N_REGS_SPI1_MEM_2() (1) +#define N_REGS_SPI1_MEM_3() (((SPI_MEM_DATE_REG(1) - SPI_MEM_MMU_POWER_CTRL_REG(1)) / 4) + 1) +#define N_REGS_SPI0_MEM_0() (((SPI_MEM_SPI_SMEM_DDR_REG(0) - REG_SPI_MEM_BASE(0)) / 4) + 1) +#define N_REGS_SPI0_MEM_1() (((SPI_MEM_SPI_SMEM_AC_REG(0) - SPI_MEM_SPI_FMEM_PMS0_ATTR_REG(0)) / 4) + 1) +#define N_REGS_SPI0_MEM_2() (1) +#define N_REGS_SPI0_MEM_3() (((SPI_MEM_DATE_REG(0) - SPI_MEM_MMU_POWER_CTRL_REG(0)) / 4) + 1) +const regdma_entries_config_t spimem_regs_retention[] = { + /* Note: SPI mem should not to write mmu SPI_MEM_MMU_ITEM_CONTENT_REG and SPI_MEM_MMU_ITEM_INDEX_REG */ + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x00), REG_SPI_MEM_BASE(1), REG_SPI_MEM_BASE(1), N_REGS_SPI1_MEM_0(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* spi1_mem */ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x01), SPI_MEM_SPI_FMEM_PMS0_ATTR_REG(1), SPI_MEM_SPI_FMEM_PMS0_ATTR_REG(1), N_REGS_SPI1_MEM_1(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x02), SPI_MEM_CLOCK_GATE_REG(1), SPI_MEM_CLOCK_GATE_REG(1), N_REGS_SPI1_MEM_2(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x03), SPI_MEM_MMU_POWER_CTRL_REG(1), SPI_MEM_MMU_POWER_CTRL_REG(1), N_REGS_SPI1_MEM_3(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + + /* Note: SPI mem should not to write mmu SPI_MEM_MMU_ITEM_CONTENT_REG and SPI_MEM_MMU_ITEM_INDEX_REG */ + [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x04), REG_SPI_MEM_BASE(0), REG_SPI_MEM_BASE(0), N_REGS_SPI0_MEM_0(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* spi0_mem */ + [5] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x05), SPI_MEM_SPI_FMEM_PMS0_ATTR_REG(0), SPI_MEM_SPI_FMEM_PMS0_ATTR_REG(0), N_REGS_SPI0_MEM_1(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x06), SPI_MEM_CLOCK_GATE_REG(0), SPI_MEM_CLOCK_GATE_REG(0), N_REGS_SPI0_MEM_2(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [7] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x07), SPI_MEM_MMU_POWER_CTRL_REG(0), SPI_MEM_MMU_POWER_CTRL_REG(0), N_REGS_SPI0_MEM_3(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } +}; +_Static_assert(ARRAY_SIZE(spimem_regs_retention) == SPIMEM_RETENTION_LINK_LEN, "Inconsistent SPI Mem retention link length definitions"); + +/* Systimer Registers Context */ +#define N_REGS_SYSTIMER_0() (((SYSTIMER_TARGET2_CONF_REG - SYSTIMER_TARGET0_HI_REG) / 4) + 1) +const regdma_entries_config_t systimer_regs_retention[] = { + [0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x00), SYSTIMER_UNIT0_OP_REG, SYSTIMER_TIMER_UNIT0_UPDATE_M, SYSTIMER_TIMER_UNIT0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, /* Systimer */ + [1] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_SYSTIMER_LINK(0x01), SYSTIMER_UNIT0_OP_REG, SYSTIMER_TIMER_UNIT0_VALUE_VALID, SYSTIMER_TIMER_UNIT0_VALUE_VALID, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, + [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x02), SYSTIMER_UNIT0_VALUE_HI_REG, SYSTIMER_UNIT0_LOAD_HI_REG, 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x03), SYSTIMER_UNIT0_LOAD_REG, SYSTIMER_TIMER_UNIT0_LOAD_M, SYSTIMER_TIMER_UNIT0_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + + [4] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x04), SYSTIMER_UNIT1_OP_REG, SYSTIMER_TIMER_UNIT1_UPDATE_M, SYSTIMER_TIMER_UNIT1_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, + [5] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_SYSTIMER_LINK(0x05), SYSTIMER_UNIT1_OP_REG, SYSTIMER_TIMER_UNIT1_VALUE_VALID, SYSTIMER_TIMER_UNIT1_VALUE_VALID, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, + [6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x06), SYSTIMER_UNIT1_VALUE_HI_REG, SYSTIMER_UNIT1_LOAD_HI_REG, 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [7] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x07), SYSTIMER_UNIT1_LOAD_REG, SYSTIMER_TIMER_UNIT1_LOAD_M, SYSTIMER_TIMER_UNIT1_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + + [8] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x08), SYSTIMER_TARGET0_HI_REG, SYSTIMER_TARGET0_HI_REG, N_REGS_SYSTIMER_0(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* Systimer target value & period */ + + [9] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x09), SYSTIMER_COMP0_LOAD_REG, SYSTIMER_TIMER_COMP0_LOAD, SYSTIMER_TIMER_COMP0_LOAD, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [10] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x0a), SYSTIMER_COMP1_LOAD_REG, SYSTIMER_TIMER_COMP1_LOAD, SYSTIMER_TIMER_COMP1_LOAD, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [11] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x0b), SYSTIMER_COMP2_LOAD_REG, SYSTIMER_TIMER_COMP2_LOAD, SYSTIMER_TIMER_COMP2_LOAD, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + + [12] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x0c), SYSTIMER_TARGET0_CONF_REG, 0, SYSTIMER_TARGET0_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [13] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x0d), SYSTIMER_TARGET0_CONF_REG, SYSTIMER_TARGET0_PERIOD_MODE_M, SYSTIMER_TARGET0_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + + [14] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x0e), SYSTIMER_TARGET1_CONF_REG, 0, SYSTIMER_TARGET1_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [15] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x0f), SYSTIMER_TARGET1_CONF_REG, SYSTIMER_TARGET1_PERIOD_MODE_M, SYSTIMER_TARGET1_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + + [16] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x10), SYSTIMER_TARGET2_CONF_REG, 0, SYSTIMER_TARGET2_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + + [17] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x11), SYSTIMER_CONF_REG, SYSTIMER_CONF_REG, 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* Systimer work enable */ + [18] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x12), SYSTIMER_INT_ENA_REG, SYSTIMER_INT_ENA_REG, 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* Systimer intr enable */ +}; +_Static_assert(ARRAY_SIZE(systimer_regs_retention) == SYSTIMER_RETENTION_LINK_LEN, "Inconsistent Systimer retention link length definitions"); diff --git a/components/soc/esp32h2/include/soc/system_periph_retention.h b/components/soc/esp32h2/include/soc/system_periph_retention.h new file mode 100644 index 0000000000..6c84932742 --- /dev/null +++ b/components/soc/esp32h2/include/soc/system_periph_retention.h @@ -0,0 +1,102 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "soc/soc_caps.h" +#include "soc/regdma.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @brief Provide access to interrupt matrix configuration registers retention + * context defination. + * + * This is an internal function of the sleep retention driver, and is not + * useful for external use. + */ +#define INT_MTX_RETENTION_LINK_LEN 1 +extern const regdma_entries_config_t intr_matrix_regs_retention[INT_MTX_RETENTION_LINK_LEN]; + +/** + * @brief Provide access to hp_system configuration registers retention + * context defination. + * + * This is an internal function of the sleep retention driver, and is not + * useful for external use. + */ +#define HP_SYSTEM_RETENTION_LINK_LEN 1 +extern const regdma_entries_config_t hp_system_regs_retention[HP_SYSTEM_RETENTION_LINK_LEN]; + +/** + * @brief Provide access to TEE_APM configuration registers retention + * context defination. + * + * This is an internal function of the sleep retention driver, and is not + * useful for external use. + */ +#define TEE_APM_RETENTION_LINK_LEN 2 +extern const regdma_entries_config_t tee_apm_regs_retention[TEE_APM_RETENTION_LINK_LEN]; +#define TEE_APM_HIGH_PRI_RETENTION_LINK_LEN 1 +extern const regdma_entries_config_t tee_apm_highpri_regs_retention[TEE_APM_HIGH_PRI_RETENTION_LINK_LEN]; + +/** + * @brief Provide access to uart configuration registers retention + * context defination. + * + * This is an internal function of the sleep retention driver, and is not + * useful for external use. + */ +#define UART_RETENTION_LINK_LEN 3 +extern const regdma_entries_config_t uart_regs_retention[UART_RETENTION_LINK_LEN]; + +/** + * @brief Provide access to timer group configuration registers retention + * context defination. + * + * This is an internal function of the sleep retention driver, and is not + * useful for external use. + */ +#define TIMG_RETENTION_LINK_LEN 8 +extern const regdma_entries_config_t tg_regs_retention[TIMG_RETENTION_LINK_LEN]; + +/** + * @brief Provide access to IOMUX configuration registers retention + * context defination. + * + * This is an internal function of the sleep retention driver, and is not + * useful for external use. + */ +#define IOMUX_RETENTION_LINK_LEN 4 +extern const regdma_entries_config_t iomux_regs_retention[IOMUX_RETENTION_LINK_LEN]; + +/** + * @brief Provide access to spimem configuration registers retention + * context defination. + * + * This is an internal function of the sleep retention driver, and is not + * useful for external use. + */ +#define SPIMEM_RETENTION_LINK_LEN 8 +extern const regdma_entries_config_t spimem_regs_retention[SPIMEM_RETENTION_LINK_LEN]; + +/** + * @brief Provide access to systimer configuration registers retention + * context defination. + * + * This is an internal function of the sleep retention driver, and is not + * useful for external use. + */ +#define SYSTIMER_RETENTION_LINK_LEN 19 +extern const regdma_entries_config_t systimer_regs_retention[SYSTIMER_RETENTION_LINK_LEN]; + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32h2/system_retention_periph.c b/components/soc/esp32h2/system_retention_periph.c new file mode 100644 index 0000000000..38b2177c95 --- /dev/null +++ b/components/soc/esp32h2/system_retention_periph.c @@ -0,0 +1,139 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/regdma.h" +#include "soc/system_periph_retention.h" +#include "soc/timer_periph.h" +#include "soc/uart_reg.h" +#include "soc/systimer_reg.h" +#include "soc/timer_group_reg.h" +#include "soc/spi_mem_reg.h" +#include "soc/hp_system_reg.h" +#include "soc/tee_reg.h" +#include "soc/hp_apm_reg.h" +#include "soc/gpio_reg.h" +#include "soc/io_mux_reg.h" +#include "soc/interrupt_matrix_reg.h" + +/* Interrupt Matrix Registers Context */ +#define N_REGS_INTR_MATRIX() (((INTMTX_CORE0_CLOCK_GATE_REG - DR_REG_INTERRUPT_MATRIX_BASE) / 4) + 1) +const regdma_entries_config_t intr_matrix_regs_retention[] = { + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_INTMTX_LINK(0), DR_REG_INTERRUPT_MATRIX_BASE, DR_REG_INTERRUPT_MATRIX_BASE, N_REGS_INTR_MATRIX(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* intr matrix */ +}; +_Static_assert(ARRAY_SIZE(intr_matrix_regs_retention) == INT_MTX_RETENTION_LINK_LEN, "Inconsistent INT_MTX retention link length definitions"); + +/* HP System Registers Context */ +#define N_REGS_HP_SYSTEM() (((HP_SYSTEM_MEM_TEST_CONF_REG - DR_REG_HP_SYSTEM_BASE) / 4) + 1) +const regdma_entries_config_t hp_system_regs_retention[] = { + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_HPSYS_LINK(0), DR_REG_HP_SYSTEM_BASE, DR_REG_HP_SYSTEM_BASE, N_REGS_HP_SYSTEM(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* hp system */ +}; +_Static_assert(ARRAY_SIZE(hp_system_regs_retention) == HP_SYSTEM_RETENTION_LINK_LEN, "Inconsistent HP_SYSTEM retention link length definitions"); + +/* TEE/APM Registers Context */ +#define N_REGS_TEE() (((TEE_CLOCK_GATE_REG - DR_REG_TEE_BASE) / 4) + 1) +#define N_REGS_APM() (((HP_APM_CLOCK_GATE_REG - DR_REG_HP_APM_BASE) / 4) + 1) +const regdma_entries_config_t tee_apm_regs_retention[] = { + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TEEAPM_LINK(0), DR_REG_HP_APM_BASE, DR_REG_HP_APM_BASE, N_REGS_APM(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* apm */ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TEEAPM_LINK(1), DR_REG_TEE_BASE, DR_REG_TEE_BASE, N_REGS_TEE(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* tee */ +}; +const regdma_entries_config_t tee_apm_highpri_regs_retention[] = { + [0] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TEEAPM_LINK(2), TEE_M4_MODE_CTRL_REG, 0x0, 0xffffffff, 1, 0), .owner = ENTRY(2) } +}; +_Static_assert((ARRAY_SIZE(tee_apm_regs_retention) == TEE_APM_RETENTION_LINK_LEN) && (ARRAY_SIZE(tee_apm_highpri_regs_retention) == TEE_APM_HIGH_PRI_RETENTION_LINK_LEN), "Inconsistent TEE_APM retention link length definitions"); + +/* UART0 Registers Context */ +#define N_REGS_UART() (((UART_ID_REG(0) - UART_INT_RAW_REG(0)) / 4) + 1) +const regdma_entries_config_t uart_regs_retention[] = { + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_UART_LINK(0x00), UART_INT_RAW_REG(0), UART_INT_RAW_REG(0), N_REGS_UART(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* uart */ + /* Note: uart register should set update reg to make the configuration take effect */ + [1] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_UART_LINK(0x01), UART_REG_UPDATE_REG(0), UART_REG_UPDATE, UART_REG_UPDATE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [2] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_UART_LINK(0x02), UART_REG_UPDATE_REG(0), 0x0, UART_REG_UPDATE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) } +}; +_Static_assert(ARRAY_SIZE(uart_regs_retention) == UART_RETENTION_LINK_LEN, "Inconsistent UART retention link length definitions"); + +/* Timergroup Registers Context */ +#define N_REGS_TG() (((TIMG_REGCLK_REG(0) - REG_TIMG_BASE(0)) / 4) + 1) +const regdma_entries_config_t tg_regs_retention[] = { + /*Timer group0 backup. T0_wdt should get of write project firstly. wdt used by RTOS.*/ + [0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x00), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, /* TG0 */ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TIMG_LINK(0x01), REG_TIMG_BASE(0), REG_TIMG_BASE(0), N_REGS_TG(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [2] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x02), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x03), TIMG_WDTCONFIG0_REG(0), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [4] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x04), TIMG_T0UPDATE_REG(0), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, + [5] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_TIMG_LINK(0x05), TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, + [6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TIMG_LINK(0x06), TIMG_T0LO_REG(0), TIMG_T0LOADLO_REG(0), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [7] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x07), TIMG_T0LOAD_REG(0), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) } +}; +_Static_assert(ARRAY_SIZE(tg_regs_retention) == TIMG_RETENTION_LINK_LEN, "Inconsistent Timergroup retention link length definitions"); + +/* IO MUX Registers Context */ +#define N_REGS_IOMUX_0() (((PERIPHS_IO_MUX_SPID_U - REG_IO_MUX_BASE) / 4) + 1) +#define N_REGS_IOMUX_1() (((GPIO_FUNC31_OUT_SEL_CFG_REG - GPIO_FUNC0_OUT_SEL_CFG_REG) / 4) + 1) +#define N_REGS_IOMUX_2() (((GPIO_FUNC124_IN_SEL_CFG_REG - GPIO_STATUS_NEXT_REG) / 4) + 1) +#define N_REGS_IOMUX_3() (((GPIO_PIN31_REG - DR_REG_GPIO_BASE) / 4) + 1) +const regdma_entries_config_t iomux_regs_retention[] = { + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x00), REG_IO_MUX_BASE, REG_IO_MUX_BASE, N_REGS_IOMUX_0(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* io_mux */ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x01), GPIO_FUNC0_OUT_SEL_CFG_REG, GPIO_FUNC0_OUT_SEL_CFG_REG, N_REGS_IOMUX_1(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x02), GPIO_STATUS_NEXT_REG, GPIO_STATUS_NEXT_REG, N_REGS_IOMUX_2(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x03), DR_REG_GPIO_BASE, DR_REG_GPIO_BASE, N_REGS_IOMUX_3(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } +}; +_Static_assert(ARRAY_SIZE(iomux_regs_retention) == IOMUX_RETENTION_LINK_LEN, "Inconsistent IOMUX retention link length definitions"); + +/* Mememory SPI Registers Context */ +#define N_REGS_SPI1_MEM_0() (((SPI_MEM_SPI_SMEM_DDR_REG(1) - REG_SPI_MEM_BASE(1)) / 4) + 1) +#define N_REGS_SPI1_MEM_1() (((SPI_MEM_SPI_SMEM_AC_REG(1) - SPI_MEM_SPI_FMEM_PMS0_ATTR_REG(1)) / 4) + 1) +#define N_REGS_SPI1_MEM_2() (1) +#define N_REGS_SPI1_MEM_3() (((SPI_MEM_DATE_REG(1) - SPI_MEM_MMU_POWER_CTRL_REG(1)) / 4) + 1) +#define N_REGS_SPI0_MEM_0() (((SPI_MEM_SPI_SMEM_DDR_REG(0) - REG_SPI_MEM_BASE(0)) / 4) + 1) +#define N_REGS_SPI0_MEM_1() (((SPI_MEM_SPI_SMEM_AC_REG(0) - SPI_MEM_SPI_FMEM_PMS0_ATTR_REG(0)) / 4) + 1) +#define N_REGS_SPI0_MEM_2() (1) +#define N_REGS_SPI0_MEM_3() (((SPI_MEM_DATE_REG(0) - SPI_MEM_MMU_POWER_CTRL_REG(0)) / 4) + 1) +const regdma_entries_config_t spimem_regs_retention[] = { + /* Note: SPI mem should not to write mmu SPI_MEM_MMU_ITEM_CONTENT_REG and SPI_MEM_MMU_ITEM_INDEX_REG */ + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x00), REG_SPI_MEM_BASE(1), REG_SPI_MEM_BASE(1), N_REGS_SPI1_MEM_0(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* spi1_mem */ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x01), SPI_MEM_SPI_FMEM_PMS0_ATTR_REG(1), SPI_MEM_SPI_FMEM_PMS0_ATTR_REG(1), N_REGS_SPI1_MEM_1(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x02), SPI_MEM_CLOCK_GATE_REG(1), SPI_MEM_CLOCK_GATE_REG(1), N_REGS_SPI1_MEM_2(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x03), SPI_MEM_MMU_POWER_CTRL_REG(1), SPI_MEM_MMU_POWER_CTRL_REG(1), N_REGS_SPI1_MEM_3(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + + /* Note: SPI mem should not to write mmu SPI_MEM_MMU_ITEM_CONTENT_REG and SPI_MEM_MMU_ITEM_INDEX_REG */ + [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x04), REG_SPI_MEM_BASE(0), REG_SPI_MEM_BASE(0), N_REGS_SPI0_MEM_0(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* spi0_mem */ + [5] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x05), SPI_MEM_SPI_FMEM_PMS0_ATTR_REG(0), SPI_MEM_SPI_FMEM_PMS0_ATTR_REG(0), N_REGS_SPI0_MEM_1(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x06), SPI_MEM_CLOCK_GATE_REG(0), SPI_MEM_CLOCK_GATE_REG(0), N_REGS_SPI0_MEM_2(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [7] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x07), SPI_MEM_MMU_POWER_CTRL_REG(0), SPI_MEM_MMU_POWER_CTRL_REG(0), N_REGS_SPI0_MEM_3(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } +}; +_Static_assert(ARRAY_SIZE(spimem_regs_retention) == SPIMEM_RETENTION_LINK_LEN, "Inconsistent SPI Mem retention link length definitions"); + +/* Systimer Registers Context */ +#define N_REGS_SYSTIMER_0() (((SYSTIMER_TARGET2_CONF_REG - SYSTIMER_TARGET0_HI_REG) / 4) + 1) +const regdma_entries_config_t systimer_regs_retention[] = { + [0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x00), SYSTIMER_UNIT0_OP_REG, SYSTIMER_TIMER_UNIT0_UPDATE_M, SYSTIMER_TIMER_UNIT0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, /* Systimer */ + [1] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_SYSTIMER_LINK(0x01), SYSTIMER_UNIT0_OP_REG, SYSTIMER_TIMER_UNIT0_VALUE_VALID, SYSTIMER_TIMER_UNIT0_VALUE_VALID, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, + [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x02), SYSTIMER_UNIT0_VALUE_HI_REG, SYSTIMER_UNIT0_LOAD_HI_REG, 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x03), SYSTIMER_UNIT0_LOAD_REG, SYSTIMER_TIMER_UNIT0_LOAD_M, SYSTIMER_TIMER_UNIT0_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + + [4] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x04), SYSTIMER_UNIT1_OP_REG, SYSTIMER_TIMER_UNIT1_UPDATE_M, SYSTIMER_TIMER_UNIT1_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, + [5] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_SYSTIMER_LINK(0x05), SYSTIMER_UNIT1_OP_REG, SYSTIMER_TIMER_UNIT1_VALUE_VALID, SYSTIMER_TIMER_UNIT1_VALUE_VALID, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, + [6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x06), SYSTIMER_UNIT1_VALUE_HI_REG, SYSTIMER_UNIT1_LOAD_HI_REG, 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [7] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x07), SYSTIMER_UNIT1_LOAD_REG, SYSTIMER_TIMER_UNIT1_LOAD_M, SYSTIMER_TIMER_UNIT1_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + + [8] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x08), SYSTIMER_TARGET0_HI_REG, SYSTIMER_TARGET0_HI_REG, N_REGS_SYSTIMER_0(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* Systimer target value & period */ + + [9] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x09), SYSTIMER_COMP0_LOAD_REG, SYSTIMER_TIMER_COMP0_LOAD, SYSTIMER_TIMER_COMP0_LOAD, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [10] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x0a), SYSTIMER_COMP1_LOAD_REG, SYSTIMER_TIMER_COMP1_LOAD, SYSTIMER_TIMER_COMP1_LOAD, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [11] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x0b), SYSTIMER_COMP2_LOAD_REG, SYSTIMER_TIMER_COMP2_LOAD, SYSTIMER_TIMER_COMP2_LOAD, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + + [12] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x0c), SYSTIMER_TARGET0_CONF_REG, 0, SYSTIMER_TARGET0_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [13] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x0d), SYSTIMER_TARGET0_CONF_REG, SYSTIMER_TARGET0_PERIOD_MODE_M, SYSTIMER_TARGET0_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + + [14] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x0e), SYSTIMER_TARGET1_CONF_REG, 0, SYSTIMER_TARGET1_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [15] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x0f), SYSTIMER_TARGET1_CONF_REG, SYSTIMER_TARGET1_PERIOD_MODE_M, SYSTIMER_TARGET1_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + + [16] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SYSTIMER_LINK(0x10), SYSTIMER_TARGET2_CONF_REG, 0, SYSTIMER_TARGET2_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + + [17] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x11), SYSTIMER_CONF_REG, SYSTIMER_CONF_REG, 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* Systimer work enable */ + [18] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x12), SYSTIMER_INT_ENA_REG, SYSTIMER_INT_ENA_REG, 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* Systimer intr enable */ +}; +_Static_assert(ARRAY_SIZE(systimer_regs_retention) == SYSTIMER_RETENTION_LINK_LEN, "Inconsistent Systimer retention link length definitions");