1 /*
2  * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <stdlib.h>
8 #include <string.h>
9 #include "sdkconfig.h"
10 #include "soc/soc_caps.h"
11 
12 #include "esp_err.h"
13 #if CONFIG_GDMA_ENABLE_DEBUG_LOG
14 // The local log level must be defined before including esp_log.h
15 // Set the maximum log level for this source file
16 #define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
17 #endif
18 #include "esp_log.h"
19 #include "esp_check.h"
20 #include "esp_private/sleep_retention.h"
21 #include "esp_private/esp_regdma.h"
22 
23 #include "hal/gdma_ll.h"
24 
25 static const char *TAG = "gdma";
26 
27 typedef struct {
28     int group_id;
29     int pair_id;
30 } gdma_channel_retention_arg_t;
31 
32 typedef struct gdma_chx_reg_ctx_link {
33     const sleep_retention_entries_config_t *link_list;
34     uint32_t link_num;
35 } gdma_chx_reg_ctx_link_t;
36 
37 #include "sleep_gdma_retention_context.inc"
38 
sleep_gdma_channel_retention_init(void * arg)39 static esp_err_t sleep_gdma_channel_retention_init(void *arg)
40 {
41     gdma_channel_retention_arg_t *parg = (gdma_channel_retention_arg_t *)arg;
42     int group_id = parg->group_id;
43     int pair_id = parg->pair_id;
44 
45     sleep_retention_module_bitmap_t module = GDMA_CH_RETENTION_GET_MODULE_ID(group_id, pair_id);
46     esp_err_t err = sleep_retention_entries_create(gdma_chx_regs_retention[group_id][pair_id].link_list, gdma_chx_regs_retention[group_id][pair_id].link_num, REGDMA_LINK_PRI_GDMA, module);
47     if (err == ESP_OK) {
48         ESP_LOGD(TAG, "GDMA pair (%d, %d) retention initialization", group_id, pair_id);
49     }
50 
51     ESP_RETURN_ON_ERROR(err, TAG, "Failed to create sleep retention linked list for GDMA pair (%d, %d) retention", group_id, pair_id);
52     return err;
53 }
54 
gdma_sleep_retention_init(int group_id,int pair_id)55 esp_err_t gdma_sleep_retention_init(int group_id, int pair_id)
56 {
57     gdma_channel_retention_arg_t arg = { .group_id = group_id, .pair_id = pair_id };
58     sleep_retention_module_init_param_t init_param = {
59         .cbs = { .create = { .handle = sleep_gdma_channel_retention_init, .arg = &arg } },
60         .depends = BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM)
61     };
62     sleep_retention_module_bitmap_t module = GDMA_CH_RETENTION_GET_MODULE_ID(group_id, pair_id);
63     esp_err_t err = sleep_retention_module_init(module, &init_param);
64     if (err == ESP_OK) {
65         err = sleep_retention_module_allocate(module);
66         if (err != ESP_OK) {
67             ESP_LOGW(TAG, "Failed to allocate sleep retention linked list for GDMA retention");
68         }
69     }
70     return err;
71 }
72 
gdma_sleep_retention_deinit(int group_id,int pair_id)73 esp_err_t gdma_sleep_retention_deinit(int group_id, int pair_id)
74 {
75     esp_err_t err = sleep_retention_module_free(GDMA_CH_RETENTION_GET_MODULE_ID(group_id, pair_id));
76     if (err != ESP_OK) {
77         ESP_LOGW(TAG, "GDMA pair (%d, %d) retention destroy failed", group_id, pair_id);
78     }
79     err = sleep_retention_module_deinit(GDMA_CH_RETENTION_GET_MODULE_ID(group_id, pair_id));
80     if (err != ESP_OK) {
81         ESP_LOGW(TAG, "GDMA pair (%d, %d) retention deinit failed", group_id, pair_id);
82     }
83     return err;
84 }
85