mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 19:13:21 +00:00
Merge branch 'bugfix/pm-673_v5.5' into 'release/v5.5'
backport v5.5: fix analog i2c master race cause by phy retention link See merge request espressif/esp-idf!46436
This commit is contained in:
@@ -246,6 +246,13 @@ esp_err_t sleep_modem_state_phy_link_init(void **link_head);
|
|||||||
* - ESP_ERR_INVALID_STATE if the phy module retention state is invalid
|
* - ESP_ERR_INVALID_STATE if the phy module retention state is invalid
|
||||||
*/
|
*/
|
||||||
esp_err_t sleep_modem_state_phy_link_deinit(void *link_head);
|
esp_err_t sleep_modem_state_phy_link_deinit(void *link_head);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function to configure PHY link regdma description at runtime
|
||||||
|
* @param link_context PHY link regdma description conteoxt pointer
|
||||||
|
* @param flags A bitmap to indicate the PHY link regdma description configuration flag
|
||||||
|
*/
|
||||||
|
void sleep_modem_state_phy_link_config(void *link_context, uint32_t flags);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "esp_check.h"
|
#include "esp_check.h"
|
||||||
|
#include "esp_attr.h"
|
||||||
|
|
||||||
#include "soc/soc_caps.h"
|
#include "soc/soc_caps.h"
|
||||||
#include "soc/i2c_ana_mst_reg.h"
|
#include "soc/i2c_ana_mst_reg.h"
|
||||||
@@ -37,6 +38,13 @@
|
|||||||
static __attribute__((unused)) const char *TAG = "sleep";
|
static __attribute__((unused)) const char *TAG = "sleep";
|
||||||
|
|
||||||
#if SOC_PM_PAU_REGDMA_LINK_IDX_WIFIMAC
|
#if SOC_PM_PAU_REGDMA_LINK_IDX_WIFIMAC
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
#define DESC_IDX_I2C_MST_ENA (0)
|
||||||
|
#define DESC_IDX_I2C_MST_DIS (1)
|
||||||
|
void *regdma_desc[DESC_IDX_I2C_MST_DIS + 1];
|
||||||
|
} sleep_modem_state_phy_link_context_t;
|
||||||
|
|
||||||
static esp_err_t sleep_modem_state_phy_wifi_init(void *arg)
|
static esp_err_t sleep_modem_state_phy_wifi_init(void *arg)
|
||||||
{
|
{
|
||||||
#define WIFIMAC_ENTRY() (BIT(SOC_PM_PAU_REGDMA_LINK_IDX_WIFIMAC))
|
#define WIFIMAC_ENTRY() (BIT(SOC_PM_PAU_REGDMA_LINK_IDX_WIFIMAC))
|
||||||
@@ -98,13 +106,41 @@ esp_err_t sleep_modem_state_phy_link_init(void **link_head)
|
|||||||
if (err == ESP_OK) {
|
if (err == ESP_OK) {
|
||||||
err = sleep_retention_module_allocate(SLEEP_RETENTION_MODULE_MODEM_PHY);
|
err = sleep_retention_module_allocate(SLEEP_RETENTION_MODULE_MODEM_PHY);
|
||||||
if (err == ESP_OK) {
|
if (err == ESP_OK) {
|
||||||
*link_head = sleep_retention_find_link_by_id(REGDMA_PHY_LINK(0x00));
|
const int id_array[] = { REGDMA_PHY_LINK(0x00), REGDMA_PHY_LINK(0x14) };
|
||||||
|
static DRAM_ATTR sleep_modem_state_phy_link_context_t phy_link_context;
|
||||||
|
|
||||||
|
for (int i = 0; (err == ESP_OK) && (i < ARRAY_SIZE(phy_link_context.regdma_desc)); i++) {
|
||||||
|
void *desc = sleep_retention_find_link_by_id(id_array[i]);
|
||||||
|
if (desc) {
|
||||||
|
phy_link_context.regdma_desc[i] = desc;
|
||||||
|
} else {
|
||||||
|
err = ESP_ERR_NOT_FOUND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (err == ESP_OK) {
|
||||||
|
*link_head = (void *)&phy_link_context;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IRAM_ATTR sleep_modem_state_phy_link_config(void *link_context, uint32_t flags)
|
||||||
|
{
|
||||||
|
#if SOC_PM_PAU_REGDMA_LINK_IDX_WIFIMAC
|
||||||
|
sleep_modem_state_phy_link_context_t *phy_link_context = (sleep_modem_state_phy_link_context_t *)link_context;
|
||||||
|
|
||||||
|
if (flags & BIT(0)) {
|
||||||
|
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_I2C_MST_ENA], true, true);
|
||||||
|
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_I2C_MST_DIS], true, true);
|
||||||
|
} else {
|
||||||
|
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_I2C_MST_ENA], true, false);
|
||||||
|
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_I2C_MST_DIS], false, true);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
esp_err_t sleep_modem_state_phy_link_deinit(void *link_head)
|
esp_err_t sleep_modem_state_phy_link_deinit(void *link_head)
|
||||||
{
|
{
|
||||||
esp_err_t err = ESP_OK;
|
esp_err_t err = ESP_OK;
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
#include "esp_attr.h"
|
||||||
|
|
||||||
#include "soc/soc_caps.h"
|
#include "soc/soc_caps.h"
|
||||||
#include "soc/i2c_ana_mst_reg.h"
|
#include "soc/i2c_ana_mst_reg.h"
|
||||||
#include "soc/pmu_reg.h"
|
#include "soc/pmu_reg.h"
|
||||||
@@ -32,6 +34,14 @@
|
|||||||
#define MODEM_FE_DATA_BASE (0x600a0400)
|
#define MODEM_FE_DATA_BASE (0x600a0400)
|
||||||
#define MODEM_FE_CTRL_BASE (0x600a0800)
|
#define MODEM_FE_CTRL_BASE (0x600a0800)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
void *link_head;
|
||||||
|
#define DESC_IDX_I2C_MST_ENA (0)
|
||||||
|
#define DESC_IDX_I2C_MST_SEL (1)
|
||||||
|
#define DESC_IDX_I2C_MST_DIS (2)
|
||||||
|
void *regdma_desc[DESC_IDX_I2C_MST_DIS + 1];
|
||||||
|
} sleep_modem_state_phy_link_context_t;
|
||||||
|
|
||||||
esp_err_t sleep_modem_state_phy_link_init(void **link_head)
|
esp_err_t sleep_modem_state_phy_link_init(void **link_head)
|
||||||
{
|
{
|
||||||
esp_err_t err = ESP_OK;
|
esp_err_t err = ESP_OK;
|
||||||
@@ -105,16 +115,46 @@ esp_err_t sleep_modem_state_phy_link_init(void **link_head)
|
|||||||
}
|
}
|
||||||
if (err == ESP_OK) {
|
if (err == ESP_OK) {
|
||||||
pau_regdma_set_modem_link_addr(link);
|
pau_regdma_set_modem_link_addr(link);
|
||||||
*link_head = link;
|
|
||||||
|
const int id_array[] = { REGDMA_PHY_LINK(0x00), REGDMA_PHY_LINK(0x01), REGDMA_PHY_LINK(0x1b) };
|
||||||
|
static DRAM_ATTR sleep_modem_state_phy_link_context_t phy_link_context;
|
||||||
|
|
||||||
|
for (int i = 0; (err == ESP_OK) && (i < ARRAY_SIZE(phy_link_context.regdma_desc)); i++) {
|
||||||
|
void *desc = regdma_find_link_by_id(link, 0, id_array[i]);
|
||||||
|
if (desc) {
|
||||||
|
phy_link_context.regdma_desc[i] = desc;
|
||||||
|
} else {
|
||||||
|
err = ESP_ERR_NOT_FOUND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (err == ESP_OK) {
|
||||||
|
phy_link_context.link_head = link;
|
||||||
|
*link_head = (void *)&phy_link_context;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IRAM_ATTR sleep_modem_state_phy_link_config(void *link_context, uint32_t flags)
|
||||||
|
{
|
||||||
|
sleep_modem_state_phy_link_context_t *phy_link_context = (sleep_modem_state_phy_link_context_t *)link_context;
|
||||||
|
|
||||||
|
if (flags & BIT(0)) {
|
||||||
|
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_I2C_MST_ENA], true, true);
|
||||||
|
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_I2C_MST_SEL], true, true);
|
||||||
|
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_I2C_MST_DIS], true, true);
|
||||||
|
} else {
|
||||||
|
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_I2C_MST_ENA], true, false);
|
||||||
|
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_I2C_MST_SEL], true, false);
|
||||||
|
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_I2C_MST_DIS], false, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
esp_err_t sleep_modem_state_phy_link_deinit(void *link_head)
|
esp_err_t sleep_modem_state_phy_link_deinit(void *link_head)
|
||||||
{
|
{
|
||||||
#if SOC_PM_PAU_REGDMA_LINK_WIFIMAC
|
#if SOC_PM_PAU_REGDMA_LINK_WIFIMAC
|
||||||
regdma_link_destroy(link_head, 0);
|
regdma_link_destroy(((sleep_modem_state_phy_link_context_t *)link_head)->link_head, 0);
|
||||||
#endif
|
#endif
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
#include "esp_attr.h"
|
||||||
|
|
||||||
#include "soc/soc_caps.h"
|
#include "soc/soc_caps.h"
|
||||||
#include "soc/i2c_ana_mst_reg.h"
|
#include "soc/i2c_ana_mst_reg.h"
|
||||||
#include "soc/pmu_reg.h"
|
#include "soc/pmu_reg.h"
|
||||||
@@ -30,6 +32,13 @@
|
|||||||
#define WDEVTXQ_BLOCK (0x600a4ca8)
|
#define WDEVTXQ_BLOCK (0x600a4ca8)
|
||||||
#define WDEV_RXBLOCK (BIT(12))
|
#define WDEV_RXBLOCK (BIT(12))
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
void *link_head;
|
||||||
|
#define DESC_IDX_I2C_MST_ENA (0)
|
||||||
|
#define DESC_IDX_I2C_MST_DIS (1)
|
||||||
|
void *regdma_desc[DESC_IDX_I2C_MST_DIS + 1];
|
||||||
|
} sleep_modem_state_phy_link_context_t;
|
||||||
|
|
||||||
esp_err_t sleep_modem_state_phy_link_init(void **link_head)
|
esp_err_t sleep_modem_state_phy_link_init(void **link_head)
|
||||||
{
|
{
|
||||||
esp_err_t err = ESP_OK;
|
esp_err_t err = ESP_OK;
|
||||||
@@ -101,16 +110,44 @@ esp_err_t sleep_modem_state_phy_link_init(void **link_head)
|
|||||||
}
|
}
|
||||||
if (err == ESP_OK) {
|
if (err == ESP_OK) {
|
||||||
pau_regdma_set_modem_link_addr(link);
|
pau_regdma_set_modem_link_addr(link);
|
||||||
*link_head = link;
|
|
||||||
|
const int id_array[] = { REGDMA_PHY_LINK(0x00), REGDMA_PHY_LINK(0x1a) };
|
||||||
|
static DRAM_ATTR sleep_modem_state_phy_link_context_t phy_link_context;
|
||||||
|
|
||||||
|
for (int i = 0; (err == ESP_OK) && (i < ARRAY_SIZE(phy_link_context.regdma_desc)); i++) {
|
||||||
|
void *desc = regdma_find_link_by_id(link, 0, id_array[i]);
|
||||||
|
if (desc) {
|
||||||
|
phy_link_context.regdma_desc[i] = desc;
|
||||||
|
} else {
|
||||||
|
err = ESP_ERR_NOT_FOUND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (err == ESP_OK) {
|
||||||
|
phy_link_context.link_head = link;
|
||||||
|
*link_head = (void *)&phy_link_context;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IRAM_ATTR sleep_modem_state_phy_link_config(void *link_context, uint32_t flags)
|
||||||
|
{
|
||||||
|
sleep_modem_state_phy_link_context_t *phy_link_context = (sleep_modem_state_phy_link_context_t *)link_context;
|
||||||
|
|
||||||
|
if (flags & BIT(0)) {
|
||||||
|
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_I2C_MST_ENA], true, true);
|
||||||
|
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_I2C_MST_DIS], true, true);
|
||||||
|
} else {
|
||||||
|
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_I2C_MST_ENA], true, false);
|
||||||
|
regdma_link_set_skip_flag(phy_link_context->regdma_desc[DESC_IDX_I2C_MST_DIS], false, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
esp_err_t sleep_modem_state_phy_link_deinit(void *link_head)
|
esp_err_t sleep_modem_state_phy_link_deinit(void *link_head)
|
||||||
{
|
{
|
||||||
#if SOC_PM_PAU_REGDMA_LINK_WIFIMAC
|
#if SOC_PM_PAU_REGDMA_LINK_WIFIMAC
|
||||||
regdma_link_destroy(link_head, 0);
|
regdma_link_destroy(((sleep_modem_state_phy_link_context_t *)link_head)->link_head, 0);
|
||||||
#endif
|
#endif
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -173,7 +173,9 @@ __attribute__((unused)) void sleep_modem_wifi_modem_state_deinit(void)
|
|||||||
|
|
||||||
void IRAM_ATTR sleep_modem_wifi_do_phy_retention(bool restore)
|
void IRAM_ATTR sleep_modem_wifi_do_phy_retention(bool restore)
|
||||||
{
|
{
|
||||||
|
sleep_modem_state_phy_link_config(s_sleep_modem.wifi.phy_link, 1);
|
||||||
sleep_retention_do_phy_retention(!restore);
|
sleep_retention_do_phy_retention(!restore);
|
||||||
|
sleep_modem_state_phy_link_config(s_sleep_modem.wifi.phy_link, 0);
|
||||||
if (!restore) {
|
if (!restore) {
|
||||||
s_sleep_modem.wifi.modem_state_phy_done = 1;
|
s_sleep_modem.wifi.modem_state_phy_done = 1;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user