mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 19:13:21 +00:00
Merge branch 'fix/p4_fixed_mdc_config_v5.5' into 'release/v5.5'
fix(esp_eth): fixed ESP32P4 CSR clock range used to determine MDC (v5.5) See merge request espressif/esp-idf!44225
This commit is contained in:
@@ -182,6 +182,7 @@ typedef struct {
|
||||
#if !SOC_EMAC_RMII_CLK_OUT_INTERNAL_LOOPBACK
|
||||
eth_mac_clock_config_t clock_config_out_in; /*!< EMAC input clock configuration for internally generated output clock (when output clock is looped back externally) */
|
||||
#endif //SOC_EMAC_RMII_CLK_OUT_INTERNAL_LOOPBACK
|
||||
int32_t mdc_freq_hz; /*!< EMAC MDC frequency range limit, if set to 0 or a negative value, the driver will set the CSR clock range up to 2.5 MHz */
|
||||
} eth_esp32_emac_config_t;
|
||||
|
||||
/**
|
||||
@@ -257,6 +258,7 @@ typedef bool (*ts_target_exceed_cb_from_isr_t)(esp_eth_mediator_t *eth, void *us
|
||||
}, \
|
||||
.dma_burst_len = ETH_DMA_BURST_LEN_32, \
|
||||
.intr_priority = 0, \
|
||||
.mdc_freq_hz = 0, \
|
||||
}
|
||||
#elif CONFIG_IDF_TARGET_ESP32P4
|
||||
#define ETH_ESP32_EMAC_DEFAULT_CONFIG() \
|
||||
@@ -277,6 +279,7 @@ typedef bool (*ts_target_exceed_cb_from_isr_t)(esp_eth_mediator_t *eth, void *us
|
||||
}, \
|
||||
.dma_burst_len = ETH_DMA_BURST_LEN_32, \
|
||||
.intr_priority = 0, \
|
||||
.mdc_freq_hz = 0, \
|
||||
.emac_dataif_gpio = \
|
||||
{ \
|
||||
.rmii = \
|
||||
|
||||
@@ -73,6 +73,7 @@ typedef struct {
|
||||
bool do_flow_ctrl; // indicates whether we need to do software flow control
|
||||
bool use_pll; // Only use (A/M)PLL in EMAC_DATA_INTERFACE_RMII && EMAC_CLK_OUT
|
||||
SemaphoreHandle_t multi_reg_mutex; // lock for multiple register access
|
||||
int32_t mdc_freq_hz;
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
esp_pm_lock_handle_t pm_lock;
|
||||
#endif
|
||||
@@ -547,7 +548,14 @@ static esp_err_t emac_esp32_init(esp_eth_mac_t *mac)
|
||||
}
|
||||
ESP_GOTO_ON_FALSE(to < emac->sw_reset_timeout_ms / 10, ESP_ERR_TIMEOUT, err, TAG, "reset timeout");
|
||||
/* set smi clock */
|
||||
emac_hal_set_csr_clock_range(&emac->hal, esp_clk_apb_freq());
|
||||
uint32_t csr_freq_hz;
|
||||
soc_module_clk_t csr_clk_src = emac_ll_get_csr_clk_src();
|
||||
ESP_GOTO_ON_ERROR(esp_clk_tree_src_get_freq_hz(csr_clk_src, ESP_CLK_TREE_SRC_FREQ_PRECISION_APPROX, &csr_freq_hz), err, TAG, "get CSR frequency failed");
|
||||
if (emac->mdc_freq_hz <= 0) {
|
||||
emac_hal_set_csr_clock_range(&emac->hal, csr_freq_hz);
|
||||
} else {
|
||||
emac_hal_find_set_closest_csr_clock_range(&emac->hal, emac->mdc_freq_hz, csr_freq_hz);
|
||||
}
|
||||
/* init mac registers by default */
|
||||
emac_hal_init_mac_default(&emac->hal);
|
||||
/* init dma registers with selected EMAC-DMA configuration */
|
||||
@@ -843,6 +851,8 @@ esp_eth_mac_t *esp_eth_mac_new_esp32(const eth_esp32_emac_config_t *esp32_config
|
||||
emac->dma_burst_len = esp32_config->dma_burst_len;
|
||||
emac->sw_reset_timeout_ms = config->sw_reset_timeout_ms;
|
||||
|
||||
emac->mdc_freq_hz = esp32_config->mdc_freq_hz;
|
||||
|
||||
emac->flow_control_high_water_mark = FLOW_CONTROL_HIGH_WATER_MARK;
|
||||
emac->flow_control_low_water_mark = FLOW_CONTROL_LOW_WATER_MARK;
|
||||
emac->parent.set_mediator = emac_esp32_set_mediator;
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "esp_clk_tree.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_check.h"
|
||||
#include "soc/clk_tree_defs.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "hal/clk_gate_ll.h"
|
||||
#include "hal/clk_tree_hal.h"
|
||||
@@ -32,6 +33,12 @@ esp_err_t esp_clk_tree_src_get_freq_hz(soc_module_clk_t clk_src, esp_clk_tree_sr
|
||||
case SOC_MOD_CLK_XTAL:
|
||||
clk_src_freq = clk_hal_xtal_get_freq_mhz() * MHZ;
|
||||
break;
|
||||
case SOC_MOD_CLK_SYS:
|
||||
clk_src_freq = clk_hal_sys_get_freq_hz();
|
||||
break;
|
||||
case SOC_MOD_CLK_APB:
|
||||
clk_src_freq = clk_hal_apb_get_freq_hz();
|
||||
break;
|
||||
case SOC_MOD_CLK_PLL_F20M:
|
||||
clk_src_freq = CLK_LL_PLL_480M_FREQ_MHZ / clk_ll_pll_f20m_get_divider() * MHZ;
|
||||
break;
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "sdkconfig.h"
|
||||
#include <stdlib.h>
|
||||
#include "soc/soc_caps.h"
|
||||
#include "esp_attr.h"
|
||||
#include "hal/emac_hal.h"
|
||||
#include "hal/emac_ll.h"
|
||||
@@ -13,6 +15,15 @@
|
||||
#define EMAC_PTP_INIT_TIMEOUT_US (10)
|
||||
#endif // SOC_EMAC_IEEE1588V2_SUPPORTED
|
||||
|
||||
static uint8_t emac_crs_div_table[] = {
|
||||
42,
|
||||
62,
|
||||
16,
|
||||
26,
|
||||
102,
|
||||
124,
|
||||
};
|
||||
|
||||
static esp_err_t emac_hal_flush_trans_fifo(emac_hal_context_t *hal)
|
||||
{
|
||||
emac_ll_flush_trans_fifo_enable(hal->dma_regs, true);
|
||||
@@ -39,6 +50,21 @@ void emac_hal_init(emac_hal_context_t *hal)
|
||||
#endif
|
||||
}
|
||||
|
||||
void emac_hal_find_set_closest_csr_clock_range(emac_hal_context_t *hal, int mdc_freq_hz, int freq_hz)
|
||||
{
|
||||
int min_diff = abs(freq_hz / emac_crs_div_table[0] - mdc_freq_hz);
|
||||
uint32_t best_div = 0;
|
||||
|
||||
for (int i = 1; i < sizeof(emac_crs_div_table) / sizeof(emac_crs_div_table[0]); i++) {
|
||||
int cur_diff = abs(freq_hz / emac_crs_div_table[i] - mdc_freq_hz);
|
||||
if (cur_diff < min_diff) {
|
||||
min_diff = cur_diff;
|
||||
best_div = i;
|
||||
}
|
||||
}
|
||||
emac_ll_set_csr_clock_division(hal->mac_regs, best_div);
|
||||
}
|
||||
|
||||
void emac_hal_set_csr_clock_range(emac_hal_context_t *hal, int freq)
|
||||
{
|
||||
/* Tell MAC system clock Frequency in MHz, which will determine the frequency range of MDC(1MHz~2.5MHz) */
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "soc/emac_mac_struct.h"
|
||||
#include "soc/emac_ext_struct.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include "soc/clk_tree_defs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -694,6 +695,12 @@ static inline void emac_ll_pause_frame_enable(emac_ext_dev_t *ext_regs, bool ena
|
||||
}
|
||||
/*************** End of ext regs operation *********************/
|
||||
|
||||
static inline soc_module_clk_t emac_ll_get_csr_clk_src(void)
|
||||
{
|
||||
// Source of the ESP32 EMAC CRS clock is APB clock.
|
||||
return SOC_MOD_CLK_APB;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -45,7 +45,7 @@ static uint32_t clk_hal_mem_get_freq_hz(void)
|
||||
return clk_hal_cpu_get_freq_hz() / clk_ll_mem_get_divider();
|
||||
}
|
||||
|
||||
static uint32_t clk_hal_sys_get_freq_hz(void)
|
||||
uint32_t clk_hal_sys_get_freq_hz(void)
|
||||
{
|
||||
return clk_hal_mem_get_freq_hz() / clk_ll_sys_get_divider();
|
||||
}
|
||||
|
||||
@@ -816,6 +816,12 @@ static inline void emac_ll_ts_target_int_trig_enable(emac_ptp_dev_t *ptp_regs)
|
||||
|
||||
/************** End of ptp regs operation ********************/
|
||||
|
||||
static inline soc_module_clk_t emac_ll_get_csr_clk_src(void)
|
||||
{
|
||||
// Source of the ESP32P4 EMAC CRS clock is SYS clock.
|
||||
return SOC_MOD_CLK_SYS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the bus clock for the EMAC module
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -35,7 +35,14 @@ uint32_t clk_hal_soc_root_get_freq_mhz(soc_cpu_clk_src_t cpu_clk_src);
|
||||
uint32_t clk_hal_cpu_get_freq_hz(void);
|
||||
|
||||
/**
|
||||
* @brief Get APB_CLK frequency
|
||||
* @brief Get SYS_CLK frequency, derived from MEM_CLK
|
||||
*
|
||||
* @return SYS clock frequency, in Hz. Returns 0 if internal clock configuration is invalid.
|
||||
*/
|
||||
uint32_t clk_hal_sys_get_freq_hz(void);
|
||||
|
||||
/**
|
||||
* @brief Get APB_CLK frequency, derived from SYS_CLK
|
||||
*
|
||||
* @return APB clock frequency, in Hz. Returns 0 if internal clock configuration is invalid.
|
||||
*/
|
||||
|
||||
@@ -246,6 +246,8 @@ void emac_hal_init(emac_hal_context_t *hal);
|
||||
|
||||
#define emac_hal_is_reset_done(hal) emac_ll_is_reset_done((hal)->dma_regs)
|
||||
|
||||
void emac_hal_find_set_closest_csr_clock_range(emac_hal_context_t *hal, int mdc_freq_hz, int freq_hz);
|
||||
|
||||
void emac_hal_set_csr_clock_range(emac_hal_context_t *hal, int freq);
|
||||
|
||||
void emac_hal_init_mac_default(emac_hal_context_t *hal);
|
||||
|
||||
@@ -146,6 +146,8 @@ typedef enum {
|
||||
SOC_MOD_CLK_RTC_FAST, /*!< RTC_FAST_CLK can be sourced from XTAL, RC_FAST, or LP_PLL by configuring soc_rtc_fast_clk_src_t */
|
||||
SOC_MOD_CLK_RTC_SLOW, /*!< RTC_SLOW_CLK can be sourced from RC_SLOW, XTAL32K, or RC32K by configuring soc_rtc_slow_clk_src_t */
|
||||
// For digital domain: peripherals
|
||||
SOC_MOD_CLK_SYS, /*!< SYS_CLK is the system clock, derived from HP_ROOT clock source */
|
||||
SOC_MOD_CLK_APB, /*!< APB_CLK is highly dependent on the CPU_CLK source */
|
||||
SOC_MOD_CLK_PLL_F20M, /*!< PLL_F20M_CLK is derived from SPLL (clock gating + default divider 24), its default frequency is 20MHz */
|
||||
SOC_MOD_CLK_PLL_F25M, /*!< PLL_F25M_CLK is derived from MPLL (clock gating + configurable divider), it will have a frequency of 25MHz */
|
||||
SOC_MOD_CLK_PLL_F50M, /*!< PLL_F50M_CLK is derived from MPLL (clock gating + configurable divider 10), it will have a frequency of 50MHz */
|
||||
|
||||
Reference in New Issue
Block a user