mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
feat(esp_eth): add ESP32-S31 EMAC support
Add internal EMAC support for ESP32-S31, including: - HAL/LL layer: emac_ll, emac_hal, emac_clk, emac_periph for S31 - SOC layer: register structs, soc_caps, peripherals linker script, interrupt definitions - MAC driver: clock source configuration via Kconfig, GPIO/DMA adaptations, PHY register defs for clause-45 MDIO - Ethernet examples updated for S31 (basic, build-test-rules, PTP readme) - Refactored existing ESP32/ESP32-P4 EMAC code for shared patterns (emac_clk extraction, struct alignment, periph descriptor cleanup)
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "hal/emac_clk.h"
|
||||
|
||||
/* MPLL VCO frequency step for targets that program MPLL from the 40 MHz XTAL (see clk_ll_mpll_set_*). */
|
||||
#define EMAC_MPLL_GRID_STEP_HZ (20000000)
|
||||
#define EMAC_MPLL_GRID_MAX_STEPS (32)
|
||||
|
||||
static const emac_clk_info_t emac_clk_mpll = {
|
||||
.clk_id = SOC_MOD_CLK_MPLL,
|
||||
.step_hz = EMAC_MPLL_GRID_STEP_HZ,
|
||||
.max_steps = EMAC_MPLL_GRID_MAX_STEPS,
|
||||
.clk_name = "MPLL",
|
||||
};
|
||||
|
||||
const emac_clk_internal_info_t emac_clk_internal = {
|
||||
.clk_count = 0,
|
||||
.clk_src = NULL,
|
||||
};
|
||||
|
||||
const emac_clk_info_t *emac_clk_phy_ref_src[] = {
|
||||
&emac_clk_mpll,
|
||||
};
|
||||
|
||||
const emac_clk_phy_ref_info_t emac_clk_phy_ref = {
|
||||
.derived_clk_id = SOC_MOD_CLK_PLL_F50M,
|
||||
.clk_count = sizeof(emac_clk_phy_ref_src) / sizeof(emac_clk_phy_ref_src[0]),
|
||||
.clk_src = emac_clk_phy_ref_src,
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -41,6 +41,7 @@ const emac_io_info_t emac_io_idx = {
|
||||
.mii_rx_er_i_idx = EMAC_PHY_RXER_PAD_IN_IDX,
|
||||
.rmii_refclk_i_idx = SIG_GPIO_OUT_IDX,
|
||||
.rmii_refclk_o_idx = SIG_GPIO_OUT_IDX,
|
||||
.phy_ref_clk_o_idx = SIG_GPIO_OUT_IDX,
|
||||
#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300
|
||||
.ptp_pps_idx = EMAC_PTP_PPS_PAD_OUT_IDX,
|
||||
#else
|
||||
@@ -66,7 +67,7 @@ static const emac_iomux_info_t emac_rmii_iomux_clki[] = {
|
||||
}
|
||||
};
|
||||
|
||||
static const emac_iomux_info_t emac_rmii_iomux_clko[] = {
|
||||
static const emac_iomux_info_t emac_rmii_iomux_phy_ref_clk[] = {
|
||||
[0] = {
|
||||
.gpio_num = 23,
|
||||
.func = FUNC_GPIO23_REF_50M_CLK_PAD,
|
||||
@@ -91,7 +92,7 @@ static const emac_iomux_info_t emac_rmii_iomux_tx_en[] = {
|
||||
},
|
||||
[2] = {
|
||||
.gpio_num = 49,
|
||||
.func = FUNC_GPIO40_EMAC_PHY_TXEN_PAD,
|
||||
.func = FUNC_GPIO49_EMAC_PHY_TXEN_PAD,
|
||||
},
|
||||
[3] = {
|
||||
.gpio_num = GPIO_NUM_MAX,
|
||||
@@ -214,7 +215,7 @@ static const emac_iomux_info_t emac_rmii_iomux_rx_er[] = {
|
||||
|
||||
const emac_rmii_iomux_info_t emac_rmii_iomux_pins = {
|
||||
.clki = emac_rmii_iomux_clki,
|
||||
.clko = emac_rmii_iomux_clko,
|
||||
.clko = NULL,
|
||||
.tx_en = emac_rmii_iomux_tx_en,
|
||||
.txd0 = emac_rmii_iomux_txd0,
|
||||
.txd1 = emac_rmii_iomux_txd1,
|
||||
@@ -225,6 +226,10 @@ const emac_rmii_iomux_info_t emac_rmii_iomux_pins = {
|
||||
.rx_er = emac_rmii_iomux_rx_er,
|
||||
};
|
||||
|
||||
const emac_ref_clk_iomux_info_t emac_ref_clk_iomux_pins = {
|
||||
.phy_ref_clk = emac_rmii_iomux_phy_ref_clk,
|
||||
};
|
||||
|
||||
const emac_mii_iomux_info_t emac_mii_iomux_pins = { 0 };
|
||||
|
||||
/* Registers in retention context:
|
||||
|
||||
@@ -94,6 +94,7 @@ extern "C" {
|
||||
|
||||
#define EMAC_LL_DMADESC_OWNER_CPU (0)
|
||||
#define EMAC_LL_DMADESC_OWNER_DMA (1)
|
||||
#define EMAC_LL_DMA_MEM_ALIGNMENT (4)
|
||||
|
||||
/* Time stamp status flags */
|
||||
#define EMAC_LL_TS_SECONDS_OVERFLOW 0x00000001U
|
||||
@@ -672,6 +673,12 @@ static inline uint32_t emac_ll_get_hw_feat(emac_dma_dev_t *dma_regs)
|
||||
return dma_regs->hwfeat;
|
||||
}
|
||||
|
||||
/* emacstatus */
|
||||
static inline uint32_t emac_ll_get_gmii_status(emac_mac_dev_t *mac_regs)
|
||||
{
|
||||
return mac_regs->emaccstatus.val;
|
||||
}
|
||||
|
||||
/*************** End of dma regs operation *********************/
|
||||
|
||||
/************** Start of ptp regs operation ********************/
|
||||
@@ -980,10 +987,29 @@ static inline void emac_ll_clock_enable_rmii_input(void *ext_regs)
|
||||
emac_ll_clock_enable_rmii_input(__VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
// ESP32P4 uses phy_ref_clk_output only
|
||||
static inline void emac_ll_clock_enable_rmii_output(void *ext_regs)
|
||||
{
|
||||
(void)ext_regs;
|
||||
}
|
||||
|
||||
static inline void emac_ll_enable_phy_ref_clock_output(void *ext_regs)
|
||||
{
|
||||
HP_SYS_CLKRST.peri_clk_ctrl00.reg_pad_emac_ref_clk_en = 1;
|
||||
}
|
||||
|
||||
/// use a macro to wrap the function, force the caller to use it in a critical section
|
||||
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
|
||||
#define emac_ll_enable_phy_ref_clock_output(...) do { \
|
||||
(void)__DECLARE_RCC_ATOMIC_ENV; \
|
||||
emac_ll_enable_phy_ref_clock_output(__VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
static inline void emac_ll_clock_rmii_rx_tx_div(void *ext_regs, int div)
|
||||
{
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl01, reg_emac_rx_clk_div_num, div);
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl01, reg_emac_tx_clk_div_num, div);
|
||||
|
||||
}
|
||||
|
||||
/// use a macro to wrap the function, force the caller to use it in a critical section
|
||||
@@ -993,19 +1019,28 @@ static inline void emac_ll_clock_rmii_rx_tx_div(void *ext_regs, int div)
|
||||
emac_ll_clock_rmii_rx_tx_div(__VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
static inline void emac_ll_clock_enable_rmii_output(void *ext_regs)
|
||||
static inline bool emac_ll_ref_clock_supported(void)
|
||||
{
|
||||
HP_SYSTEM.sys_gmac_ctrl0.sys_phy_intf_sel = 0x4; // set RMII
|
||||
|
||||
HP_SYS_CLKRST.peri_clk_ctrl00.reg_pad_emac_ref_clk_en = 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// use a macro to wrap the function, force the caller to use it in a critical section
|
||||
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
|
||||
#define emac_ll_clock_enable_rmii_output(...) do { \
|
||||
(void)__DECLARE_RCC_ATOMIC_ENV; \
|
||||
emac_ll_clock_enable_rmii_output(__VA_ARGS__); \
|
||||
} while(0)
|
||||
static inline void emac_ll_ref_clock_enable(void *ext_regs, bool enable)
|
||||
{
|
||||
(void)ext_regs;
|
||||
(void)enable;
|
||||
}
|
||||
|
||||
static inline void emac_ll_ref_clock_select(void *ext_regs, int sel)
|
||||
{
|
||||
(void)ext_regs;
|
||||
(void)sel;
|
||||
}
|
||||
|
||||
static inline void emac_ll_ref_clock_div(void *ext_regs, int div)
|
||||
{
|
||||
(void)ext_regs;
|
||||
(void)div;
|
||||
}
|
||||
|
||||
static inline void emac_ll_clock_enable_ptp(void *ext_regs, soc_periph_emac_ptp_clk_src_t clk_src, bool enable)
|
||||
{
|
||||
@@ -1038,6 +1073,12 @@ static inline void emac_ll_pause_frame_enable(void *ext_regs, bool enable)
|
||||
HP_SYSTEM.sys_gmac_ctrl0.sys_sbd_flowctrl = enable;
|
||||
}
|
||||
|
||||
static inline void emac_ll_gpio_init(void *ext_regs, uint32_t gpio_num)
|
||||
{
|
||||
(void)ext_regs;
|
||||
(void)gpio_num;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user