diff --git a/components/esp_hw_support/port/esp32s31/peripheral_domain_pd.c b/components/esp_hw_support/port/esp32s31/peripheral_domain_pd.c index 5b7ce3919ab..142a71bc37c 100644 --- a/components/esp_hw_support/port/esp32s31/peripheral_domain_pd.c +++ b/components/esp_hw_support/port/esp32s31/peripheral_domain_pd.c @@ -82,13 +82,15 @@ bool peripheral_domain_pd_allowed(void) RETENTION_MODULE_BITMAP_SET(&mask, SLEEP_RETENTION_MODULE_MCPWM2); RETENTION_MODULE_BITMAP_SET(&mask, SLEEP_RETENTION_MODULE_MCPWM3); - // ESP32S31 supports PCNT sleep retention - RETENTION_MODULE_BITMAP_SET(&mask, SLEEP_RETENTION_MODULE_PCNT0); - RETENTION_MODULE_BITMAP_SET(&mask, SLEEP_RETENTION_MODULE_PCNT1); - // ESP32S31 supports SDM sleep retention RETENTION_MODULE_BITMAP_SET(&mask, SLEEP_RETENTION_MODULE_SDM0); + // ESP32S31 supports LCDCAM sleep retention + RETENTION_MODULE_BITMAP_SET(&mask, SLEEP_RETENTION_MODULE_LCDCAM); + + // ESP32S31 supports JPEG sleep retention + RETENTION_MODULE_BITMAP_SET(&mask, SLEEP_RETENTION_MODULE_JPEG); + const sleep_retention_module_bitmap_t peripheral_domain_inited_modules = sleep_retention_module_bitmap_and(inited_modules, mask); const sleep_retention_module_bitmap_t peripheral_domain_created_modules = sleep_retention_module_bitmap_and(created_modules, mask); return sleep_retention_module_bitmap_eq(peripheral_domain_inited_modules, peripheral_domain_created_modules); diff --git a/components/esp_hw_support/sleep_system_peripheral.c b/components/esp_hw_support/sleep_system_peripheral.c index 73babdba3b7..81d6569e414 100644 --- a/components/esp_hw_support/sleep_system_peripheral.c +++ b/components/esp_hw_support/sleep_system_peripheral.c @@ -34,7 +34,8 @@ static __attribute__((unused)) esp_err_t sleep_sys_periph_hp_system_retention_in static __attribute__((unused)) esp_err_t sleep_sys_periph_tee_apm_retention_init(void *arg) { /* TBD for ESP32P4 IDF-10020. */ -#ifndef CONFIG_IDF_TARGET_ESP32P4 +/* TBD for ESP32S31 IDF-14620. */ +#if !defined(CONFIG_IDF_TARGET_ESP32P4) && !defined(CONFIG_IDF_TARGET_ESP32S31) esp_err_t err = sleep_retention_entries_create(tee_apm_regs_retention, ARRAY_SIZE(tee_apm_regs_retention), REGDMA_LINK_PRI_NON_CRITICAL_TEE_APM, SLEEP_RETENTION_MODULE_SYS_PERIPH); if (err == ESP_OK) { err = sleep_retention_entries_create(tee_apm_highpri_regs_retention, ARRAY_SIZE(tee_apm_highpri_regs_retention), REGDMA_LINK_PRI_CRITICAL_TEE_APM, SLEEP_RETENTION_MODULE_SYS_PERIPH); @@ -74,7 +75,7 @@ static __attribute__((unused)) esp_err_t sleep_sys_periph_flash_spimem_retention return ESP_OK; } -#if CONFIG_SPIRAM && CONFIG_IDF_TARGET_ESP32P4 +#if CONFIG_SPIRAM && SOC_PSRAM_MEMSPI_IS_INDEPENDENT /* TODO: PM-205, In the ESP32C5, Flash and PSRAM use the same set of SPIMEM hardware, while in P4, Flash and PSRAM each have their own SPIMEM hardware. * It’s necessary to confirm whether the ESP32C5 can independently manage SPIMEM retention for Flash and PSRAM in software. */ static __attribute__((unused)) esp_err_t sleep_sys_periph_psram_spimem_retention_init(void *arg) @@ -99,7 +100,7 @@ esp_err_t sleep_sys_periph_cache_retention_init(void) { esp_err_t err = sleep_retention_entries_create(cache_regs_retention, ARRAY_SIZE(cache_regs_retention), REGDMA_LINK_PRI_SYS_PERIPH_HIGH, SLEEP_RETENTION_MODULE_SYS_PERIPH); ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (Cache) retention"); - ESP_LOGI(TAG, "L2 Cache sleep retention initialization"); + ESP_LOGD(TAG, "L2 Cache sleep retention initialization"); return ESP_OK; } #endif @@ -109,7 +110,7 @@ esp_err_t sleep_pau_retention_init(void) { esp_err_t err = sleep_retention_entries_create(pau_regs_retention, ARRAY_SIZE(pau_regs_retention), REGDMA_LINK_PRI_SYS_PERIPH_LOW, SLEEP_RETENTION_MODULE_SYS_PERIPH); ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for system (PAU) retention"); - ESP_LOGI(TAG, "PAU sleep retention initialization"); + ESP_LOGD(TAG, "PAU sleep retention initialization"); return ESP_OK; } #endif @@ -119,7 +120,7 @@ esp_err_t sleep_pvt_retention_init(void) { esp_err_t err = sleep_retention_entries_create(pvt_regs_retention, ARRAY_SIZE(pvt_regs_retention), REGDMA_LINK_PRI_SYS_PERIPH_LOW, SLEEP_RETENTION_MODULE_SYS_PERIPH); ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for system (PVT) retention"); - ESP_LOGI(TAG, "PVT sleep retention initialization"); + ESP_LOGD(TAG, "PVT sleep retention initialization"); return ESP_OK; } #endif @@ -147,7 +148,7 @@ static __attribute__((unused)) esp_err_t sleep_sys_periph_retention_init(void *a if(err) goto error; err = sleep_sys_periph_flash_spimem_retention_init(arg); if(err) goto error; -#if CONFIG_SPIRAM && CONFIG_IDF_TARGET_ESP32P4 +#if CONFIG_SPIRAM && SOC_PSRAM_MEMSPI_IS_INDEPENDENT err = sleep_sys_periph_psram_spimem_retention_init(arg); if(err) goto error; #endif diff --git a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in index 984a7fa3f61..7001db6a976 100644 --- a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in @@ -1411,6 +1411,10 @@ config SOC_MEMSPI_SUPPORT_CONTROL_DUMMY_OUT bool default y +config SOC_PSRAM_MEMSPI_IS_INDEPENDENT + bool + default y + config SOC_SPI_MEM_FLASH_SUPPORT_HPM bool default y diff --git a/components/soc/esp32p4/include/soc/soc_caps.h b/components/soc/esp32p4/include/soc/soc_caps.h index 10193dc3fdb..d9d1c20681f 100644 --- a/components/soc/esp32p4/include/soc/soc_caps.h +++ b/components/soc/esp32p4/include/soc/soc_caps.h @@ -534,6 +534,7 @@ #define SOC_MSPI_HAS_INDEPENT_IOMUX 1 #define SOC_MEMSPI_IS_INDEPENDENT 1 #define SOC_MEMSPI_SUPPORT_CONTROL_DUMMY_OUT 1 +#define SOC_PSRAM_MEMSPI_IS_INDEPENDENT 1 #define SOC_SPI_MEM_FLASH_SUPPORT_HPM (1) /*!< Support High Performance Mode */ diff --git a/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in index 539f4691de8..d9b36b66cd9 100644 --- a/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in @@ -247,6 +247,10 @@ config SOC_MODEM_CLOCK_SUPPORTED bool default y +config SOC_PM_SUPPORTED + bool + default y + config SOC_BITSCRAMBLER_SUPPORTED bool default y @@ -731,6 +735,10 @@ config SOC_MEMSPI_IS_INDEPENDENT bool default y +config SOC_PSRAM_MEMSPI_IS_INDEPENDENT + bool + default y + config SOC_MEMSPI_ENCRYPTION_ALIGNMENT int default 16 @@ -1103,6 +1111,10 @@ config SOC_PM_SUPPORT_VDDSDIO_PD bool default y +config SOC_PM_SUPPORT_TOP_PD + bool + default y + config SOC_PM_SUPPORT_HP_AON_PD bool default y diff --git a/components/soc/esp32s31/include/soc/soc_caps.h b/components/soc/esp32s31/include/soc/soc_caps.h index 6ea35c1ab58..decdf740282 100644 --- a/components/soc/esp32s31/include/soc/soc_caps.h +++ b/components/soc/esp32s31/include/soc/soc_caps.h @@ -100,7 +100,7 @@ #define SOC_LIGHT_SLEEP_SUPPORTED 1 #define SOC_DEEP_SLEEP_SUPPORTED 1 #define SOC_MODEM_CLOCK_SUPPORTED 1 -// #define SOC_PM_SUPPORTED 1 // TODO: [ESP32S31] IDF-14648 +#define SOC_PM_SUPPORTED 1 #define SOC_BITSCRAMBLER_SUPPORTED 1 #define SOC_SIMD_INSTRUCTION_SUPPORTED 1 #define SOC_CORDIC_SUPPORTED 1 @@ -299,6 +299,7 @@ #define SOC_SPI_MEM_SUPPORT_TSUS_TRES_SEPERATE_CTR (1) #define SOC_MEMSPI_IS_INDEPENDENT 1 +#define SOC_PSRAM_MEMSPI_IS_INDEPENDENT 1 #define SOC_MEMSPI_ENCRYPTION_ALIGNMENT 16 /*!< 16-byte alignment restriction to mem addr and size if encryption is enabled */ @@ -446,7 +447,7 @@ #define SOC_PM_SUPPORT_RC32K_PD (1) #define SOC_PM_SUPPORT_RC_FAST_PD (1) #define SOC_PM_SUPPORT_VDDSDIO_PD (1) -// #define SOC_PM_SUPPORT_TOP_PD (1) // TODO: [ESP32S31] IDF-14647 +#define SOC_PM_SUPPORT_TOP_PD (1) #define SOC_PM_SUPPORT_HP_AON_PD (1) #define SOC_PM_SUPPORT_CNNT_PD (1) #define SOC_PM_SUPPORT_RTC_PERIPH_PD (1) diff --git a/components/soc/esp32s31/include/soc/system_periph_retention.h b/components/soc/esp32s31/include/soc/system_periph_retention.h index 7fa9390cd7e..345955df495 100644 --- a/components/soc/esp32s31/include/soc/system_periph_retention.h +++ b/components/soc/esp32s31/include/soc/system_periph_retention.h @@ -25,6 +25,16 @@ extern "C" #define INT_MTX_RETENTION_LINK_LEN 2 extern const regdma_entries_config_t intr_matrix_regs_retention[INT_MTX_RETENTION_LINK_LEN]; +/** + * @brief Provide access to cache configuration registers retention + * context definition. + * + * This is an internal function of the sleep retention driver, and is not + * useful for external use. + */ +#define CACHE_RETENTION_LINK_LEN 4 +extern const regdma_entries_config_t cache_regs_retention[CACHE_RETENTION_LINK_LEN]; + /** * @brief Provide access to tee apm configuration registers retention * context definition. diff --git a/components/soc/esp32s31/system_retention_periph.c b/components/soc/esp32s31/system_retention_periph.c index 56b461576a8..2627754605b 100644 --- a/components/soc/esp32s31/system_retention_periph.c +++ b/components/soc/esp32s31/system_retention_periph.c @@ -38,6 +38,20 @@ const regdma_entries_config_t intr_matrix_regs_retention[] = { }; _Static_assert(ARRAY_SIZE(intr_matrix_regs_retention) == INT_MTX_RETENTION_LINK_LEN, "Inconsistent INT_MTX retention link length definitions"); +#define L1_CACHE_ACS_FAIL_INR_CLR (CACHE_L1_ICACHE0_FAIL_INT_CLR | CACHE_L1_ICACHE1_FAIL_INT_CLR | CACHE_L1_ICACHE2_FAIL_INT_CLR | CACHE_L1_ICACHE3_FAIL_INT_CLR |CACHE_L1_DCACHE_FAIL_INT_CLR) +#define L1_CACHE_ACS_FAIL_INR_CLR_M (CACHE_L1_ICACHE0_FAIL_INT_CLR_M | CACHE_L1_ICACHE1_FAIL_INT_CLR_M | CACHE_L1_ICACHE2_FAIL_INT_CLR_M | CACHE_L1_ICACHE3_FAIL_INT_CLR_M |CACHE_L1_DCACHE_FAIL_INT_CLR_M) + +#define N_REGS_CACHE_0() (((CACHE_L1_CACHE_ATOMIC_CONF_REG - CACHE_L1_ICACHE_CTRL_REG) / 4) + 1) +#define N_REGS_CACHE_1() (((CACHE_L1_CACHE_ACS_FAIL_INT_ENA_REG - CACHE_L1_CACHE_ACS_FAIL_CTRL_REG) / 4) + 1) + +const regdma_entries_config_t cache_regs_retention[] = { + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_CACHE_LINK(0x1), CACHE_L1_ICACHE_CTRL_REG, CACHE_L1_ICACHE_CTRL_REG, N_REGS_CACHE_0(), 0, 1), .owner = ENTRY(0) | ENTRY(2)}, + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_CACHE_LINK(0x2), CACHE_L1_CACHE_ACS_FAIL_CTRL_REG, CACHE_L1_CACHE_ACS_FAIL_CTRL_REG, N_REGS_CACHE_1(), 0, 1), .owner = ENTRY(0) | ENTRY(2)}, + [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_CACHE_LINK(0x3), CACHE_TRACE_ENA_REG, CACHE_TRACE_ENA_REG, 1, 0, 1), .owner = ENTRY(0) | ENTRY(2)}, + [3] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_CACHE_LINK(0x0), CACHE_L1_CACHE_ACS_FAIL_INT_CLR_REG, L1_CACHE_ACS_FAIL_INR_CLR, L1_CACHE_ACS_FAIL_INR_CLR_M, 1, 1), .owner = ENTRY(0) | ENTRY(2) }, +}; +_Static_assert(ARRAY_SIZE(cache_regs_retention) == CACHE_RETENTION_LINK_LEN, "Inconsistent L2 CACHE retention link length definitions"); + #if SOC_APM_SUPPORTED /* TEE APM Registers Context */ #define N_REGS_TEE_0() (((TEE_M87_MODE_CTRL_REG - TEE_M0_MODE_CTRL_REG) / 4) + 1) @@ -132,11 +146,22 @@ _Static_assert(ARRAY_SIZE(flash_spimem_regs_retention) == SPIMEM_FLASH_RETENTION #define N_REGS_SPI1_S_MEM_2() (((SPI1_MEM_S_TIMING_CALI_REG - SPI1_MEM_S_TIMING_CALI_REG) / 4) + 1) const regdma_entries_config_t psram_spimem_regs_retention[SPIMEM_PSRAM_RETENTION_LINK_LEN] = { - [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x00), SPI_MEM_S_CTRL_REG, SPI_MEM_S_CTRL_REG, N_REGS_SPI0_S_MEM_0(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* spi0_mem */ - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x01), SPI_MEM_S_DDR_REG, SPI_MEM_S_DDR_REG, N_REGS_SPI0_S_MEM_1(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x02), SPI1_MEM_S_CMD_REG, SPI1_MEM_S_CMD_REG, N_REGS_SPI1_S_MEM_0(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x03), SPI1_MEM_S_DDR_REG, SPI1_MEM_S_DDR_REG, N_REGS_SPI1_S_MEM_1(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x04), SPI1_MEM_S_TIMING_CALI_REG, SPI1_MEM_S_TIMING_CALI_REG, N_REGS_SPI1_S_MEM_2(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [0] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_SPIMEM_LINK(0x07), HP_SYS_CLKRST_PSRAM_CTRL0_REG, HP_SYS_CLKRST_REG_PSRAM_CORE_CLK_EN, HP_SYS_CLKRST_REG_PSRAM_CORE_CLK_EN_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, // Enable PSRAM mspi core clock on restore + [1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_SPIMEM_LINK(0x08), HP_SYS_CLKRST_PSRAM_CTRL0_REG, HP_SYS_CLKRST_REG_PSRAM_SYS_CLK_EN, HP_SYS_CLKRST_REG_PSRAM_SYS_CLK_EN_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, // Enable PSRAM mspi core clock on restore + [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x09), SPI_MEM_S_CTRL_REG, SPI_MEM_S_CTRL_REG, N_REGS_SPI0_S_MEM_0(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* spi0_mem */ + [3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x0a), SPI_MEM_S_MISC_REG, SPI_MEM_S_MISC_REG, N_REGS_SPI0_S_MEM_1(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x0b), SPI_MEM_S_INT_ENA_REG, SPI_MEM_S_INT_ENA_REG, N_REGS_SPI0_S_MEM_2(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [5] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x0c), SPI_MEM_S_ECC_CTRL_REG, SPI_MEM_S_ECC_CTRL_REG, N_REGS_SPI0_S_MEM_3(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x0d), SPI_MEM_S_MMU_POWER_CTRL_REG, SPI_MEM_S_MMU_POWER_CTRL_REG, N_REGS_SPI0_S_MEM_4(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [7] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x0e), SPI1_MEM_S_CMD_REG, SPI1_MEM_S_CMD_REG, N_REGS_SPI1_S_MEM_0(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* spi1_mem */ + [8] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x0f), SPI1_MEM_S_FLASH_WAITI_CTRL_REG, SPI1_MEM_S_FLASH_WAITI_CTRL_REG, N_REGS_SPI1_S_MEM_1(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [9] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x10), SPI1_MEM_S_INT_ENA_REG, SPI1_MEM_S_INT_ENA_REG, N_REGS_SPI1_S_MEM_2(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [10] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x11), SPI1_MEM_S_TIMING_CALI_REG, SPI1_MEM_S_TIMING_CALI_REG, N_REGS_SPI1_S_MEM_3(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [11] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x12), SPI1_MEM_S_CLOCK_GATE_REG, SPI1_MEM_S_CLOCK_GATE_REG, N_REGS_SPI1_S_MEM_4(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [12] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_SPIMEM_LINK(0x13), HP_SYS_CLKRST_PSRAM_CTRL0_REG, 0, HP_SYS_CLKRST_REG_PSRAM_CORE_CLK_EN_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, // Disable PSRAM mspi core clock on backup + [13] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_SPIMEM_LINK(0x14), HP_SYS_CLKRST_PSRAM_CTRL0_REG, 0, HP_SYS_CLKRST_REG_PSRAM_SYS_CLK_EN_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, // Disable PSRAM mspi core clock on backup + /* PSRAM MSPI IOMUX */ + [14] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x15), IOMUX_MSPI_PIN_PSRAM_D_PIN0_REG, IOMUX_MSPI_PIN_PSRAM_D_PIN0_REG, N_REGS_MSPI1_IOMUX(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, }; _Static_assert(ARRAY_SIZE(psram_spimem_regs_retention) == SPIMEM_PSRAM_RETENTION_LINK_LEN, "Inconsistent PSRAM SPI Mem retention link length definitions"); diff --git a/examples/lowpower/power_management/README.md b/examples/lowpower/power_management/README.md index 313c27f354a..14e521c079f 100644 --- a/examples/lowpower/power_management/README.md +++ b/examples/lowpower/power_management/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | ESP32-S31 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- | --------- | # Power Management Example