From ab70690fff4034b5a5ea74be94adddfd9f5cc45a Mon Sep 17 00:00:00 2001 From: morris Date: Thu, 2 Jul 2026 16:01:26 +0800 Subject: [PATCH] refactor(lcd): move sleep retention config into driver layer Move LCD I80 retention descriptors and related comments out of esp_hal_lcd and into esp_lcd so the backup policy stays with the driver implementation. --- components/esp_hal_lcd/esp32p4/lcd_periph.c | 34 --------------- components/esp_hal_lcd/esp32s31/lcd_periph.c | 34 --------------- .../esp_hal_lcd/include/hal/lcd_periph.h | 16 ------- components/esp_lcd/CMakeLists.txt | 5 ++- .../esp_lcd/i80/esp32p4/lcd_retention.c | 42 +++++++++++++++++++ .../esp_lcd/i80/esp32s31/lcd_retention.c | 42 +++++++++++++++++++ components/esp_lcd/i80/esp_lcd_panel_io_i80.c | 12 +++--- components/esp_lcd/i80/i80_io_priv.h | 14 +++++++ 8 files changed, 108 insertions(+), 91 deletions(-) create mode 100644 components/esp_lcd/i80/esp32p4/lcd_retention.c create mode 100644 components/esp_lcd/i80/esp32s31/lcd_retention.c diff --git a/components/esp_hal_lcd/esp32p4/lcd_periph.c b/components/esp_hal_lcd/esp32p4/lcd_periph.c index 8e40fb2c8cf..4cd796e9aed 100644 --- a/components/esp_hal_lcd/esp32p4/lcd_periph.c +++ b/components/esp_hal_lcd/esp32p4/lcd_periph.c @@ -81,37 +81,3 @@ const soc_lcd_rgb_signal_desc_t soc_lcd_rgb_signals[1] = { .disp_sig = SIG_GPIO_OUT_IDX, } }; - -/** - * LCD_CAM Registers to be saved during sleep retention - * - LCD Clock Configuration registers: LCDCAM_LCD_CLOCK_REG (0x0) - * - LCD User Configuration registers: LCDCAM_LCD_USER_REG (0x14), LCDCAM_LCD_MISC_REG (0x18) - * - LCD Control registers: LCDCAM_LCD_CTRL_REG (0x1c) (Note: lcd_rgb_mode_en is in this register) - * - LCD Delay Mode Configuration registers: LCDCAM_LCD_DLY_MODE_CFG1_REG (0x30), LCDCAM_LCD_DLY_MODE_CFG2_REG (0x38) - * - LCD DMA Interrupt Enable register: LCDCAM_LC_DMA_INT_ENA_REG (0x64) - * - * NOTE: Only I80 LCD supports sleep retention, not RGB LCD. - */ -#define LCD_RETENTION_REGS_CNT 7 -#define LCD_RETENTION_REGS_BASE (DR_REG_LCDCAM_BASE + 0x0) -static const uint32_t lcd_cam_regs_map[4] = {0x20050e1, 0x0, 0x0, 0x0}; -static const regdma_entries_config_t lcd_regs_retention[] = { - // backup stage: save configuration registers - // restore stage: restore the configuration registers - [0] = { - .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LCDCAM_LINK(0x00), - LCD_RETENTION_REGS_BASE, LCD_RETENTION_REGS_BASE, - LCD_RETENTION_REGS_CNT, 0, 0, - lcd_cam_regs_map[0], lcd_cam_regs_map[1], - lcd_cam_regs_map[2], lcd_cam_regs_map[3]), - .owner = ENTRY(0), - }, -}; - -const soc_i80_lcd_retention_info_t soc_i80_lcd_retention_info[1] = { - [0] = { - .regdma_entry_array = lcd_regs_retention, - .array_size = ARRAY_SIZE(lcd_regs_retention), - .retention_module = SLEEP_RETENTION_MODULE_LCDCAM - }, -}; diff --git a/components/esp_hal_lcd/esp32s31/lcd_periph.c b/components/esp_hal_lcd/esp32s31/lcd_periph.c index df7de0ed2eb..a5abffd2c01 100644 --- a/components/esp_hal_lcd/esp32s31/lcd_periph.c +++ b/components/esp_hal_lcd/esp32s31/lcd_periph.c @@ -117,37 +117,3 @@ const soc_lcd_rgb_iomux_desc_t soc_lcd_rgb_iomux_descs[1] = { .de_pin = { .gpio_num = GPIO_NUM_43, .func = FUNC_GPIO43_LCD_H_ENABLE_PAD }, }, }; - -/** - * LCD_CAM Registers to be saved during sleep retention - * - LCD Clock Configuration registers: LCDCAM_LCD_CLOCK_REG (0x0) - * - LCD User Configuration registers: LCDCAM_LCD_USER_REG (0x14), LCDCAM_LCD_MISC_REG (0x18) - * - LCD Delay Mode Configuration registers: LCDCAM_LCD_DLY_MODE_CFG1_REG (0x34), LCDCAM_LCD_DLY_MODE_CFG2_REG (0x38) - * - LCD Transfer Buffer Configuration registers: LCDCAM_LCD_TRANS_BUFF_CFG_REG(0x3C) - * - LCD DMA Interrupt Enable register: LCDCAM_LC_DMA_INT_ENA_REG (0x64) - * - * NOTE: Only I80 LCD supports sleep retention, not RGB LCD. - */ -#define LCD_RETENTION_REGS_CNT 7 -#define LCD_RETENTION_REGS_BASE (DR_REG_LCDCAM_BASE + 0x0) -static const uint32_t lcd_cam_regs_map[4] = {0x200e061, 0x0, 0x0, 0x0}; -static const regdma_entries_config_t lcd_regs_retention[] = { - // backup stage: save configuration registers - // restore stage: restore the configuration registers - [0] = { - .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LCDCAM_LINK(0x00), - LCD_RETENTION_REGS_BASE, LCD_RETENTION_REGS_BASE, - LCD_RETENTION_REGS_CNT, 0, 0, - lcd_cam_regs_map[0], lcd_cam_regs_map[1], - lcd_cam_regs_map[2], lcd_cam_regs_map[3]), - .owner = ENTRY(0) | ENTRY(2), - }, -}; - -const soc_i80_lcd_retention_info_t soc_i80_lcd_retention_info[1] = { - [0] = { - .regdma_entry_array = lcd_regs_retention, - .array_size = ARRAY_SIZE(lcd_regs_retention), - .retention_module = SLEEP_RETENTION_MODULE_LCDCAM - }, -}; diff --git a/components/esp_hal_lcd/include/hal/lcd_periph.h b/components/esp_hal_lcd/include/hal/lcd_periph.h index 3850fe89fd8..2a1455ed50b 100644 --- a/components/esp_hal_lcd/include/hal/lcd_periph.h +++ b/components/esp_hal_lcd/include/hal/lcd_periph.h @@ -9,17 +9,12 @@ #include #include "soc/soc_caps.h" #include "soc/periph_defs.h" -#include "soc/regdma.h" #if SOC_HAS(I2S) #include "hal/i2s_ll.h" #endif #if SOC_HAS(LCDCAM_I80_LCD) || SOC_HAS(LCDCAM_RGB_LCD) #include "hal/lcd_ll.h" #endif -#if SOC_HAS(PAU) -#include "soc/retention_periph_defs.h" -#endif - #ifdef __cplusplus extern "C" { #endif @@ -80,17 +75,6 @@ typedef struct { extern const soc_lcd_i2s_signal_desc_t soc_lcd_i2s_signals[I2S_LL_GET(INST_NUM)]; #endif // SOC_HAS(I2S_I80_LCD) -#if SOC_HAS(PAU) && SOC_HAS(LCDCAM_I80_LCD) -// Only LCDCAM I80 LCD supports sleep retention -typedef struct { - const periph_retention_module_t retention_module; - const regdma_entries_config_t *regdma_entry_array; - uint32_t array_size; -} soc_i80_lcd_retention_info_t; - -extern const soc_i80_lcd_retention_info_t soc_i80_lcd_retention_info[LCD_LL_GET(I80_BUS_NUM)]; -#endif // SOC_HAS(PAU) && SOC_HAS(LCDCAM_I80_LCD) - #ifdef __cplusplus } #endif diff --git a/components/esp_lcd/CMakeLists.txt b/components/esp_lcd/CMakeLists.txt index ccd234c1163..5fe569752b1 100644 --- a/components/esp_lcd/CMakeLists.txt +++ b/components/esp_lcd/CMakeLists.txt @@ -31,6 +31,9 @@ endif() if(CONFIG_SOC_LCDCAM_I80_LCD_SUPPORTED) list(APPEND srcs "i80/esp_lcd_panel_io_i80.c") + if(CONFIG_SOC_PAU_SUPPORTED) + list(APPEND srcs "i80/${target}/lcd_retention.c") + endif() endif() if(CONFIG_SOC_LCDCAM_RGB_LCD_SUPPORTED) @@ -45,7 +48,7 @@ endif() idf_component_register(SRCS ${srcs} INCLUDE_DIRS ${includes} - PRIV_INCLUDE_DIRS "priv_include" + PRIV_INCLUDE_DIRS "priv_include" "i80" PRIV_REQUIRES ${priv_requires} REQUIRES ${public_requires} LDFRAGMENTS linker.lf) diff --git a/components/esp_lcd/i80/esp32p4/lcd_retention.c b/components/esp_lcd/i80/esp32p4/lcd_retention.c new file mode 100644 index 00000000000..7391310c910 --- /dev/null +++ b/components/esp_lcd/i80/esp32p4/lcd_retention.c @@ -0,0 +1,42 @@ +/* + * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "i80_io_priv.h" +#include "soc/lcd_cam_reg.h" + +/** + * LCD_CAM Registers to be saved during sleep retention + * - LCD Clock Configuration registers: LCDCAM_LCD_CLOCK_REG (0x0) + * - LCD User Configuration registers: LCDCAM_LCD_USER_REG (0x14), LCDCAM_LCD_MISC_REG (0x18) + * - LCD Control registers: LCDCAM_LCD_CTRL_REG (0x1c) (Note: lcd_rgb_mode_en is in this register) + * - LCD Delay Mode Configuration registers: LCDCAM_LCD_DLY_MODE_CFG1_REG (0x30), LCDCAM_LCD_DLY_MODE_CFG2_REG (0x38) + * - LCD DMA Interrupt Enable register: LCDCAM_LC_DMA_INT_ENA_REG (0x64) + * + * NOTE: Only I80 LCD supports sleep retention, not RGB LCD. + */ +#define LCD_RETENTION_REGS_CNT 7 +#define LCD_RETENTION_REGS_BASE (DR_REG_LCDCAM_BASE + 0x0) +static const uint32_t lcd_cam_regs_map[4] = {0x20050e1, 0x0, 0x0, 0x0}; +static const regdma_entries_config_t lcd_regs_retention[] = { + // backup stage: save configuration registers + // restore stage: restore the configuration registers + [0] = { + .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LCDCAM_LINK(0x00), + LCD_RETENTION_REGS_BASE, LCD_RETENTION_REGS_BASE, + LCD_RETENTION_REGS_CNT, 0, 0, + lcd_cam_regs_map[0], lcd_cam_regs_map[1], + lcd_cam_regs_map[2], lcd_cam_regs_map[3]), + .owner = ENTRY(0), + }, +}; + +const lcd_i80_reg_retention_info_t lcd_i80_reg_retention_info[1] = { + [0] = { + .regdma_entry_array = lcd_regs_retention, + .array_size = ARRAY_SIZE(lcd_regs_retention), + .retention_module = SLEEP_RETENTION_MODULE_LCDCAM + }, +}; diff --git a/components/esp_lcd/i80/esp32s31/lcd_retention.c b/components/esp_lcd/i80/esp32s31/lcd_retention.c new file mode 100644 index 00000000000..d452de68d5e --- /dev/null +++ b/components/esp_lcd/i80/esp32s31/lcd_retention.c @@ -0,0 +1,42 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "i80_io_priv.h" +#include "soc/lcd_cam_reg.h" + +/** + * LCD_CAM Registers to be saved during sleep retention + * - LCD Clock Configuration registers: LCDCAM_LCD_CLOCK_REG (0x0) + * - LCD User Configuration registers: LCDCAM_LCD_USER_REG (0x14), LCDCAM_LCD_MISC_REG (0x18) + * - LCD Delay Mode Configuration registers: LCDCAM_LCD_DLY_MODE_CFG1_REG (0x34), LCDCAM_LCD_DLY_MODE_CFG2_REG (0x38) + * - LCD Transfer Buffer Configuration registers: LCDCAM_LCD_TRANS_BUFF_CFG_REG(0x3C) + * - LCD DMA Interrupt Enable register: LCDCAM_LC_DMA_INT_ENA_REG (0x64) + * + * NOTE: Only I80 LCD supports sleep retention, not RGB LCD. + */ +#define LCD_RETENTION_REGS_CNT 7 +#define LCD_RETENTION_REGS_BASE (DR_REG_LCDCAM_BASE + 0x0) +static const uint32_t lcd_cam_regs_map[4] = {0x200e061, 0x0, 0x0, 0x0}; +static const regdma_entries_config_t lcd_regs_retention[] = { + // backup stage: save configuration registers + // restore stage: restore the configuration registers + [0] = { + .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_LCDCAM_LINK(0x00), + LCD_RETENTION_REGS_BASE, LCD_RETENTION_REGS_BASE, + LCD_RETENTION_REGS_CNT, 0, 0, + lcd_cam_regs_map[0], lcd_cam_regs_map[1], + lcd_cam_regs_map[2], lcd_cam_regs_map[3]), + .owner = ENTRY(0) | ENTRY(2), + }, +}; + +const lcd_i80_reg_retention_info_t lcd_i80_reg_retention_info[1] = { + [0] = { + .regdma_entry_array = lcd_regs_retention, + .array_size = ARRAY_SIZE(lcd_regs_retention), + .retention_module = SLEEP_RETENTION_MODULE_LCDCAM + }, +}; diff --git a/components/esp_lcd/i80/esp_lcd_panel_io_i80.c b/components/esp_lcd/i80/esp_lcd_panel_io_i80.c index bb6960baeca..8e39afb418f 100644 --- a/components/esp_lcd/i80/esp_lcd_panel_io_i80.c +++ b/components/esp_lcd/i80/esp_lcd_panel_io_i80.c @@ -164,7 +164,7 @@ esp_err_t esp_lcd_new_i80_bus(const esp_lcd_i80_bus_config_t *bus_config, esp_lc } #if I80_USE_RETENTION_LINK // no need to acquire mutex, because the bus is exclusive - sleep_retention_module_t module_id = soc_i80_lcd_retention_info[bus_id].retention_module; + sleep_retention_module_t module_id = lcd_i80_reg_retention_info[bus_id].retention_module; sleep_retention_module_init_param_t init_param = { .cbs = { .create = { @@ -292,7 +292,7 @@ esp_err_t esp_lcd_del_i80_bus(esp_lcd_i80_bus_handle_t bus) bus->clk_src = SOC_MOD_CLK_INVALID; } #if I80_USE_RETENTION_LINK - const periph_retention_module_t module_id = soc_i80_lcd_retention_info[bus_id].retention_module; + const periph_retention_module_t module_id = lcd_i80_reg_retention_info[bus_id].retention_module; sleep_retention_module_detach(module_id); if (sleep_retention_is_module_created(module_id)) { assert(sleep_retention_is_module_inited(module_id)); @@ -616,9 +616,9 @@ static esp_err_t lcd_i80_create_sleep_retention_link_cb(void *arg) { esp_lcd_i80_bus_t *bus = (esp_lcd_i80_bus_t *)arg; int bus_id = bus->bus_id; - sleep_retention_module_t module_id = soc_i80_lcd_retention_info[bus_id].retention_module; - esp_err_t err = sleep_retention_entries_create(soc_i80_lcd_retention_info[bus_id].regdma_entry_array, - soc_i80_lcd_retention_info[bus_id].array_size, + sleep_retention_module_t module_id = lcd_i80_reg_retention_info[bus_id].retention_module; + esp_err_t err = sleep_retention_entries_create(lcd_i80_reg_retention_info[bus_id].regdma_entry_array, + lcd_i80_reg_retention_info[bus_id].array_size, REGDMA_LINK_PRI_LCDCAM, module_id); ESP_RETURN_ON_ERROR(err, TAG, "create retention link failed"); return ESP_OK; @@ -627,7 +627,7 @@ static esp_err_t lcd_i80_create_sleep_retention_link_cb(void *arg) static void lcd_i80_create_retention_module(esp_lcd_i80_bus_t *bus) { int bus_id = bus->bus_id; - sleep_retention_module_t module_id = soc_i80_lcd_retention_info[bus_id].retention_module; + sleep_retention_module_t module_id = lcd_i80_reg_retention_info[bus_id].retention_module; if (sleep_retention_is_module_inited(module_id) && !sleep_retention_is_module_created(module_id)) { if (sleep_retention_module_allocate(module_id) != ESP_OK) { diff --git a/components/esp_lcd/i80/i80_io_priv.h b/components/esp_lcd/i80/i80_io_priv.h index 33d0022ba3c..c6007d938e5 100644 --- a/components/esp_lcd/i80/i80_io_priv.h +++ b/components/esp_lcd/i80/i80_io_priv.h @@ -42,6 +42,10 @@ #include "hal/lcd_periph.h" #include "soc/io_mux_reg.h" #include "soc/gpio_sig_map.h" +#if SOC_HAS(PAU) +#include "soc/regdma.h" +#include "soc/retention_periph_defs.h" +#endif ///!< Logging settings #define TAG "lcd.i80" @@ -50,6 +54,16 @@ extern "C" { #endif +#if SOC_HAS(PAU) +typedef struct { + const periph_retention_module_t retention_module; + const regdma_entries_config_t *regdma_entry_array; + uint32_t array_size; +} lcd_i80_reg_retention_info_t; + +extern const lcd_i80_reg_retention_info_t lcd_i80_reg_retention_info[LCD_LL_GET(I80_BUS_NUM)]; +#endif + #ifdef __cplusplus } #endif