mirror of
https://github.com/espressif/esp-idf.git
synced 2025-09-02 06:38:47 +00:00
fix(dma): abort the axi dma gracefully on CPU SW reset
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -27,6 +27,10 @@
|
||||
#include "soc/hp_sys_clkrst_reg.h"
|
||||
#include "soc/lp_clkrst_reg.h"
|
||||
#include "soc/hp_system_reg.h"
|
||||
#include "hal/gdma_ll.h"
|
||||
#include "hal/axi_dma_ll.h"
|
||||
#include "hal/dw_gdma_ll.h"
|
||||
#include "hal/dma2d_ll.h"
|
||||
|
||||
void IRAM_ATTR esp_system_reset_modules_on_exit(void)
|
||||
{
|
||||
@@ -37,6 +41,32 @@ void IRAM_ATTR esp_system_reset_modules_on_exit(void)
|
||||
}
|
||||
}
|
||||
|
||||
// Note: AXI bus doesn't allow an undergoing transaction to be interrupted in the middle
|
||||
// If you want to reset a AXI master, you should make sure that the master is in IDLE first
|
||||
if (gdma_ll_is_bus_clock_enabled(1)) {
|
||||
for (int i = 0; i < GDMA_LL_AXI_PAIRS_PER_GROUP; i++) {
|
||||
axi_dma_ll_tx_abort(AXI_DMA_LL_GET_HW(0), i, true);
|
||||
axi_dma_ll_rx_abort(AXI_DMA_LL_GET_HW(0), i, true);
|
||||
while (!axi_dma_ll_tx_is_reset_avail(AXI_DMA_LL_GET_HW(0), i));
|
||||
while (!axi_dma_ll_rx_is_reset_avail(AXI_DMA_LL_GET_HW(0), i));
|
||||
}
|
||||
}
|
||||
if (dma2d_ll_is_bus_clock_enabled(0)) {
|
||||
for (int i = 0; i < SOC_DMA2D_RX_CHANNELS_PER_GROUP; i++) {
|
||||
dma2d_ll_rx_abort(DMA2D_LL_GET_HW(0), i, true);
|
||||
while (!dma2d_ll_rx_is_reset_avail(DMA2D_LL_GET_HW(0), i));
|
||||
}
|
||||
for (int i = 0; i < SOC_DMA2D_TX_CHANNELS_PER_GROUP; i++) {
|
||||
dma2d_ll_tx_abort(DMA2D_LL_GET_HW(0), i, true);
|
||||
while (!dma2d_ll_tx_is_reset_avail(DMA2D_LL_GET_HW(0), i));
|
||||
}
|
||||
}
|
||||
if (dw_gdma_ll_is_bus_clock_enabled(0)) {
|
||||
for (int i = 0; i < DW_GDMA_LL_CHANNELS_PER_GROUP; i++) {
|
||||
dw_gdma_ll_channel_abort(DW_GDMA_LL_GET_HW(0), i);
|
||||
}
|
||||
}
|
||||
|
||||
// Set Peripheral clk rst
|
||||
SET_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN1_REG, HP_SYS_CLKRST_REG_RST_EN_TIMERGRP1);
|
||||
SET_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN1_REG, HP_SYS_CLKRST_REG_RST_EN_STIMER);
|
||||
@@ -47,7 +77,6 @@ void IRAM_ATTR esp_system_reset_modules_on_exit(void)
|
||||
SET_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN1_REG, HP_SYS_CLKRST_REG_RST_EN_UART2_CORE);
|
||||
SET_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN1_REG, HP_SYS_CLKRST_REG_RST_EN_UART3_CORE);
|
||||
SET_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN1_REG, HP_SYS_CLKRST_REG_RST_EN_UART4_CORE);
|
||||
SET_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN0_REG, HP_SYS_CLKRST_REG_RST_EN_GDMA);
|
||||
SET_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN2_REG, HP_SYS_CLKRST_REG_RST_EN_ADC);
|
||||
|
||||
// Clear Peripheral clk rst
|
||||
@@ -60,7 +89,6 @@ void IRAM_ATTR esp_system_reset_modules_on_exit(void)
|
||||
CLEAR_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN1_REG, HP_SYS_CLKRST_REG_RST_EN_UART2_CORE);
|
||||
CLEAR_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN1_REG, HP_SYS_CLKRST_REG_RST_EN_UART3_CORE);
|
||||
CLEAR_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN1_REG, HP_SYS_CLKRST_REG_RST_EN_UART4_CORE);
|
||||
CLEAR_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN0_REG, HP_SYS_CLKRST_REG_RST_EN_GDMA);
|
||||
CLEAR_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN2_REG, HP_SYS_CLKRST_REG_RST_EN_ADC);
|
||||
|
||||
#if CONFIG_ESP32P4_REV_MIN_FULL <= 100
|
||||
|
Reference in New Issue
Block a user