From 9b3dc69908de8eb023f1b1789906b56713fd59f8 Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Thu, 18 Jan 2024 18:56:40 +0800 Subject: [PATCH] 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