From 60e42f30c4b706b3456e5d5c267be0a23d3f9a80 Mon Sep 17 00:00:00 2001 From: Darian Leung Date: Mon, 22 May 2023 20:45:02 +0800 Subject: [PATCH 1/2] usb_host: Restrict ESP32-S2 AHB errata workaround to only ECO0 chips --- components/hal/usb_dwc_hal.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/components/hal/usb_dwc_hal.c b/components/hal/usb_dwc_hal.c index 8e26371275..58fc66f443 100644 --- a/components/hal/usb_dwc_hal.c +++ b/components/hal/usb_dwc_hal.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -8,6 +8,8 @@ #include #include #include "sdkconfig.h" +#include "soc/chip_revision.h" +#include "hal/efuse_hal.h" #include "hal/usb_dwc_hal.h" #include "hal/usb_dwc_ll.h" #include "hal/assert.h" @@ -86,11 +88,27 @@ static void set_defaults(usb_dwc_hal_context_t *hal) { //GAHBCFG register usb_dwc_ll_gahbcfg_en_dma_mode(hal->dev); -#ifdef CONFIG_IDF_TARGET_ESP32S2 - usb_dwc_ll_gahbcfg_set_hbstlen(hal->dev, 1); //Use INCR AHB burst. See the ESP32-S2 and later chip ERRATA. -#elif CONFIG_IDF_TARGET_ESP32S3 - usb_dwc_ll_gahbcfg_set_hbstlen(hal->dev, 0); //Do not use USB burst INCR mode for the ESP32-S3, to avoid interference with other peripherals. -#endif + int hbstlen = 0; //Use AHB burst SINGLE by default +#if CONFIG_IDF_TARGET_ESP32S2 && CONFIG_ESP32S2_REV_MIN_FULL < 100 + /* + Hardware errata workaround for the ESP32-S2 ECO0 (see ESP32-S2 Errata Document section 4.0 for full details). + + ESP32-S2 ECO0 has a hardware errata where the AHB bus arbiter may generate incorrect arbitration signals leading to + the DWC_OTG corrupting the DMA transfers of other peripherals (or vice versa) on the same bus. The peripherals that + share the same bus with DWC_OTG include I2C and SPI (see ESP32-S2 Errata Document for more details). To workaround + this, the DWC_OTG's AHB should use INCR mode to prevent change of arbitration during a burst operation, thus + avoiding this errata. + + Note: Setting AHB burst to INCR increases the likeliness of DMA underruns on other peripherals sharing the same bus + arbiter as the DWC_OTG (e.g., I2C and SPI) as change of arbitration during the burst operation is not permitted. + Users should keep this limitation in mind when the DWC_OTG transfers large data payloads (e.g., 512 MPS transfers) + while this workaround is enabled. + */ + if (!ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 100)) { + hbstlen = 1; //Set AHB burst to INCR to workaround hardware errata + } +#endif //CONFIG_IDF_TARGET_ESP32S2 && CONFIG_ESP32S2_REV_MIN_FULL < 100 + usb_dwc_ll_gahbcfg_set_hbstlen(hal->dev, hbstlen); //Set AHB burst mode //GUSBCFG register usb_dwc_ll_gusbcfg_dis_hnp_cap(hal->dev); //Disable HNP usb_dwc_ll_gusbcfg_dis_srp_cap(hal->dev); //Disable SRP From 5cb212665ae62ebfd59fdf8d17c60c769657e6ea Mon Sep 17 00:00:00 2001 From: Darian Leung Date: Fri, 28 Jul 2023 11:30:16 +0200 Subject: [PATCH 2/2] soc: Move revision MAX/MIN static assert to esp_hw_support Previously, "soc/chip_revision.h" contained a static assert to check that the CONFIG_ESP_REV_MIN_FULL <= CONFIG_ESP_REV_MAX_FULL. There are two issues with this assert: - Contained in a header file, so it is only compiled if the "chip_revision.h" is included somewhere - CONFIG_ESP_REV_MIN_FULL and CONFIG_ESP_REV_MAX_FULL are defined in "esp_hw_support", which is a G0 component. This creates a reverse dependency of G0 on G1. This commit moves the static assert "revision.c" in "esp_hw_support" --- components/esp_hw_support/CMakeLists.txt | 1 + components/esp_hw_support/revision.c | 16 ++++++++++++++++ components/soc/include/soc/chip_revision.h | 4 ---- 3 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 components/esp_hw_support/revision.c diff --git a/components/esp_hw_support/CMakeLists.txt b/components/esp_hw_support/CMakeLists.txt index 6a3f494859..e7dd4aaabc 100644 --- a/components/esp_hw_support/CMakeLists.txt +++ b/components/esp_hw_support/CMakeLists.txt @@ -14,6 +14,7 @@ if(NOT BOOTLOADER_BUILD) "hw_random.c" "intr_alloc.c" "mac_addr.c" + "revision.c" "sleep_modes.c" "sleep_gpio.c" "sleep_mac_bb.c" diff --git a/components/esp_hw_support/revision.c b/components/esp_hw_support/revision.c new file mode 100644 index 0000000000..1ff72f8ce5 --- /dev/null +++ b/components/esp_hw_support/revision.c @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "sdkconfig.h" +#include "esp_assert.h" + +/* +Source used to store ESP chip revision and ESP-IDF minimum supported revision in the future. +Currently only used to hold static assert to check that the configured minimum and maximum supported chip revisions of +ESP-IDF are valid. +*/ + +ESP_STATIC_ASSERT(CONFIG_ESP_REV_MIN_FULL <= CONFIG_ESP_REV_MAX_FULL, "Minimum and/or maximum chip revision are invalid"); diff --git a/components/soc/include/soc/chip_revision.h b/components/soc/include/soc/chip_revision.h index 070de4918c..28d3736f30 100644 --- a/components/soc/include/soc/chip_revision.h +++ b/components/soc/include/soc/chip_revision.h @@ -6,8 +6,6 @@ #pragma once -#include "sdkconfig.h" - #ifdef __cplusplus extern "C" { #endif @@ -33,8 +31,6 @@ extern "C" { #define ESP_CHIP_REV_ABOVE(rev, min_rev) ((min_rev) <= (rev)) #define ESP_CHIP_REV_MAJOR_AND_ABOVE(rev, min_rev) (((rev) / 100 == (min_rev) / 100) && ((rev) >= (min_rev))) -_Static_assert(CONFIG_ESP_REV_MIN_FULL <= CONFIG_ESP_REV_MAX_FULL, "Min version must be less than Max version"); - #ifdef __cplusplus } #endif