mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 19:13:21 +00:00
Merge branch 'bugfix/pm-673_v5.2' into 'release/v5.2'
backport v5.2: fix analog i2c master race cause by phy retention link See merge request espressif/esp-idf!46452
This commit is contained in:
@@ -174,6 +174,14 @@ typedef struct sleep_modem_config {
|
||||
|
||||
static sleep_modem_config_t s_sleep_modem = { .wifi.phy_link = NULL, .wifi.flags = 0 };
|
||||
|
||||
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_wifi_modem_state_init(void)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
@@ -198,38 +206,48 @@ esp_err_t sleep_modem_wifi_modem_state_init(void)
|
||||
[5] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x03), PMU_RF_PWR_REG, 0xf0000000, 0xf0000000, 1, 0),
|
||||
[6] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x04), SARADC_TSENS_REG, SARADC_TSENS_PU, 0x400000, 1, 0),
|
||||
[7] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x05), I2C_ANA_MST_I2C_BURST_CONF_REG, 0, 0xffffffff, 1, 0),
|
||||
[8] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x06), I2C_ANA_MST_I2C_BURST_STATUS_REG, I2C_ANA_MST_BURST_DONE, 0x1, 1, 0),
|
||||
[9] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x07), FECOEX_SET_FREQ_SET_CHAN_REG, FECOEX_SET_CHAN_EN, 0x4000, 1, 0),
|
||||
[10] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x08), FECOEX_SET_FREQ_SET_CHAN_REG, 0, 0x4000, 1, 0),
|
||||
[11] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x09), FECOEX_SET_FREQ_SET_CHAN_ST_REG, FECOEX_SET_CHAN_DONE, 0x100, 1, 0),
|
||||
[12] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0a), MODEM_SYSCON_WIFI_BB_CFG_REG, BIT(1), 0x2, 1, 0),
|
||||
[13] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0b), FECOEX_AGC_CONF_REG, 0, 0x20000000, 1, 0),
|
||||
[8] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x06), PMU_DATE_REG, ~I2C_ANA_MST_BURST_DONE, 0x1, 1, 0),
|
||||
[9] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x07), PMU_DATE_REG, ~I2C_ANA_MST_BURST_DONE, 0x1, 1, 0),
|
||||
[10] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x08), I2C_ANA_MST_I2C_BURST_STATUS_REG, I2C_ANA_MST_BURST_DONE, 0x1, 1, 0),
|
||||
[11] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x09), FECOEX_SET_FREQ_SET_CHAN_REG, FECOEX_SET_CHAN_EN, 0x4000, 1, 0),
|
||||
[12] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0a), FECOEX_SET_FREQ_SET_CHAN_REG, 0, 0x4000, 1, 0),
|
||||
[13] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0b), PMU_DATE_REG, ~FECOEX_SET_CHAN_DONE, 0x100, 1, 0),
|
||||
[14] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x0c), PMU_DATE_REG, ~FECOEX_SET_CHAN_DONE, 0x100, 1, 0),
|
||||
[15] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x0d), FECOEX_SET_FREQ_SET_CHAN_ST_REG, FECOEX_SET_CHAN_DONE, 0x100, 1, 0),
|
||||
[16] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0e), MODEM_SYSCON_WIFI_BB_CFG_REG, BIT(1), 0x2, 1, 0),
|
||||
[17] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0f), FECOEX_AGC_CONF_REG, 0, 0x20000000, 1, 0),
|
||||
|
||||
/* PMU to trigger enable RXBLOCK */
|
||||
[14] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0c), WDEVTXQ_BLOCK, 0, 0x1000, 1, 0),
|
||||
[18] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x10), WDEVTXQ_BLOCK, 0, 0x1000, 1, 0),
|
||||
|
||||
/* PMU or software to trigger disable RF PHY */
|
||||
[15] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0d), FECOEX_AGC_CONF_REG, FECOEX_AGC_DIS, 0x20000000, 0, 1),
|
||||
[16] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0e), MODEM_SYSCON_WIFI_BB_CFG_REG, 0, 0x2, 0, 1),
|
||||
[17] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0f), FECOEX_SET_FREQ_SET_CHAN_REG, 0, 0x4000, 0, 1),
|
||||
[18] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x10), I2C_ANA_MST_I2C_BURST_CONF_REG, 0, 0xffffffff, 0, 1),
|
||||
[19] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x11), I2C_ANA_MST_I2C_BURST_STATUS_REG, I2C_ANA_MST_BURST_DONE, 0x1, 0, 1),
|
||||
[20] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x12), SARADC_TSENS_REG, 0, 0x400000, 0, 1),
|
||||
[21] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x13), PMU_RF_PWR_REG, 0, 0xf0000000, 0, 1),
|
||||
[22] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x14), I2C_ANA_MST_ANA_CONF0_REG, 0x4, 0xc, 0, 1), /* BBPLL calibration disable */
|
||||
[19] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x11), FECOEX_AGC_CONF_REG, FECOEX_AGC_DIS, 0x20000000, 0, 1),
|
||||
[20] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x12), MODEM_SYSCON_WIFI_BB_CFG_REG, 0, 0x2, 0, 1),
|
||||
[21] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x13), FECOEX_SET_FREQ_SET_CHAN_REG, 0, 0x4000, 0, 1),
|
||||
[22] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x14), I2C_ANA_MST_I2C_BURST_CONF_REG, 0, 0xffffffff, 0, 1),
|
||||
[23] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x15), PMU_DATE_REG, ~I2C_ANA_MST_BURST_DONE, 0x1, 0, 1),
|
||||
[24] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x16), PMU_DATE_REG, ~I2C_ANA_MST_BURST_DONE, 0x1, 0, 1),
|
||||
[25] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x17), I2C_ANA_MST_I2C_BURST_STATUS_REG, I2C_ANA_MST_BURST_DONE, 0x1, 0, 1),
|
||||
[26] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x18), SARADC_TSENS_REG, 0, 0x400000, 0, 1),
|
||||
[27] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x19), PMU_RF_PWR_REG, 0, 0xf0000000, 0, 1),
|
||||
[28] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x1a), I2C_ANA_MST_ANA_CONF0_REG, 0x4, 0xc, 0, 1), /* BBPLL calibration disable */
|
||||
|
||||
[23] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x15), MODEM_LPCON_CLK_CONF_REG, 0, MODEM_LPCON_CLK_I2C_MST_EN_M, 0, 1), /* I2C MST disable */
|
||||
[29] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x1b), MODEM_LPCON_CLK_CONF_REG, 0, MODEM_LPCON_CLK_I2C_MST_EN_M, 0, 1), /* I2C MST disable */
|
||||
|
||||
/* PMU to trigger disable RXBLOCK */
|
||||
[24] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x17), WDEVTXQ_BLOCK, 0, 0x6000, 0, 1),
|
||||
[25] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x18), WDEVTXQ_BLOCK, WDEV_RXBLOCK, 0x1000, 0, 1),
|
||||
[26] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x19), WDEVTXQ_BLOCK, 0, 0x6000, 0, 1),
|
||||
[30] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x1c), PMU_DATE_REG, ~0, 0x6000, 0, 1),
|
||||
[31] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x1d), PMU_DATE_REG, ~0, 0x6000, 0, 1),
|
||||
[32] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x1e), WDEVTXQ_BLOCK, 0, 0x6000, 0, 1),
|
||||
[33] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x1f), WDEVTXQ_BLOCK, WDEV_RXBLOCK, 0x1000, 0, 1),
|
||||
[34] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x20), PMU_DATE_REG, ~0, 0x6000, 0, 1),
|
||||
[35] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x21), PMU_DATE_REG, ~0, 0x6000, 0, 1),
|
||||
[36] = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x22), WDEVTXQ_BLOCK, 0, 0x6000, 0, 1),
|
||||
|
||||
[27] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x1a), PMU_SLP_WAKEUP_CNTL7_REG, 0x200000, 0xffff0000, 1, 0),
|
||||
[28] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x1b), PMU_SLP_WAKEUP_CNTL7_REG, 0x9730000, 0xffff0000, 0, 1)
|
||||
[37] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x23), PMU_SLP_WAKEUP_CNTL7_REG, 0x200000, 0xffff0000, 1, 0),
|
||||
[38] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x24), PMU_SLP_WAKEUP_CNTL7_REG, 0x9730000, 0xffff0000, 0, 1)
|
||||
};
|
||||
wifi_modem_config[7].write_wait.value = I2C_BURST_VAL(cmd.config[1].host_id, cmd.config[1].start, cmd.config[1].end);
|
||||
wifi_modem_config[18].write_wait.value = I2C_BURST_VAL(cmd.config[0].host_id, cmd.config[0].start, cmd.config[0].end);
|
||||
wifi_modem_config[22].write_wait.value = I2C_BURST_VAL(cmd.config[0].host_id, cmd.config[0].start, cmd.config[0].end);
|
||||
|
||||
void *link = NULL;
|
||||
if (s_sleep_modem.wifi.phy_link == NULL) {
|
||||
@@ -244,17 +262,47 @@ esp_err_t sleep_modem_wifi_modem_state_init(void)
|
||||
}
|
||||
if (err == ESP_OK) {
|
||||
pau_regdma_set_modem_link_addr(link);
|
||||
s_sleep_modem.wifi.phy_link = link;
|
||||
s_sleep_modem.wifi.flags = 0;
|
||||
|
||||
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;
|
||||
s_sleep_modem.wifi.phy_link = (void *)&phy_link_context;
|
||||
s_sleep_modem.wifi.flags = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static 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);
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((unused)) void sleep_modem_wifi_modem_state_deinit(void)
|
||||
{
|
||||
if (s_sleep_modem.wifi.phy_link) {
|
||||
regdma_link_destroy(s_sleep_modem.wifi.phy_link, 0);
|
||||
regdma_link_destroy(((sleep_modem_state_phy_link_context_t *)(s_sleep_modem.wifi.phy_link))->link_head, 0);
|
||||
s_sleep_modem.wifi.phy_link = NULL;
|
||||
s_sleep_modem.wifi.flags = 0;
|
||||
}
|
||||
@@ -262,12 +310,14 @@ __attribute__((unused)) void sleep_modem_wifi_modem_state_deinit(void)
|
||||
|
||||
void IRAM_ATTR sleep_modem_wifi_do_phy_retention(bool restore)
|
||||
{
|
||||
sleep_modem_state_phy_link_config(s_sleep_modem.wifi.phy_link, 1);
|
||||
if (restore) {
|
||||
pau_regdma_trigger_modem_link_restore();
|
||||
} else {
|
||||
pau_regdma_trigger_modem_link_backup();
|
||||
s_sleep_modem.wifi.modem_state_phy_done = 1;
|
||||
}
|
||||
sleep_modem_state_phy_link_config(s_sleep_modem.wifi.phy_link, 0);
|
||||
}
|
||||
|
||||
inline __attribute__((always_inline)) bool sleep_modem_wifi_modem_state_enabled(void)
|
||||
|
||||
Reference in New Issue
Block a user