From 682ed861fa167765ceda54a005882a06229bc211 Mon Sep 17 00:00:00 2001 From: DrDoof <8052722+DrDoof@users.noreply.github.com> Date: Wed, 23 Sep 2026 05:53:15 +0200 Subject: [PATCH] rtl8224: wait for the PHY to answer instead of a fixed 2.5 s rtl8224_enable() waits 2.5 s after releasing the RTL8224 reset before anything talks to the PHY. On an SWTGW218AS the chip id already reads back 0x8224 at the first poll, about 265 ms after the release. Remember when the reset was released and, once SMI is up, poll the chip id until it answers, giving up after the same 2.5 s as before. The PHY writes that follow read back the same as before. The reset pulse before it goes from 0.5 s to 20 ms, twice the 10 ms the related RTL8372 and RTL8221B need. The pulse does reset the chip: the MDI reverse register (MMD 30, 0x0a90) still reads its power-on value 0x00f3 just before the init writes 0x00fc, as it does with 0.5 s. Together the console banner comes 3 s sooner. The SerDes write loop in phy_config_8224() waited on the busy bit with no limit, so a PHY that never answers stopped the boot before the network came up. Bound it and report a timeout. --- boot.c | 5 +++-- rtl837x_phy.c | 18 +++++++++++++++++- rtl837x_phy.h | 1 + rtlplayground.c | 2 ++ 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/boot.c b/boot.c index 66ccd38b..9e271660 100644 --- a/boot.c +++ b/boot.c @@ -21,6 +21,7 @@ extern __code const struct machine machine; extern __xdata struct machine_runtime machine_detected; extern __xdata uint8_t sfr_data[4]; extern volatile __xdata uint32_t ticks; +__xdata uint32_t rtl8224_release_tick; extern __xdata uint8_t tx_seq; extern __code const uint8_t * __code const hex; @@ -240,10 +241,10 @@ void rtl8224_enable(void) __banked reg_bit_clear(RTL837X_REG_GPIO_32_63_OUTPUT, 4); // Configure Pin as output reg_bit_set(RTL837X_REG_GPIO_32_63_DIRECTION, 4); - delay(100); + delay(4); // Set pin 4 high reg_bit_set(RTL837X_REG_GPIO_32_63_OUTPUT, 4); - delay(500); + rtl8224_release_tick = ticks; } diff --git a/rtl837x_phy.c b/rtl837x_phy.c index eb106d98..aa9c2ba5 100644 --- a/rtl837x_phy.c +++ b/rtl837x_phy.c @@ -23,6 +23,8 @@ extern __code const uint16_t bit_mask[16]; extern __code const struct machine machine; extern __xdata struct machine_runtime machine_detected; +extern volatile __xdata uint32_t ticks; +extern __xdata uint32_t rtl8224_release_tick; __xdata struct phy_settings phy_settings; @@ -214,9 +216,20 @@ void phy_config(uint8_t phy) __banked } +void rtl8224_wait_ready(void) __banked +{ + do { + rtl8224_read_reg_u16(RTL837X_REG_CHIP_ID + 1); + if (SFR_DATA_U16 == 0x8224) + return; + } while ((ticks - rtl8224_release_tick) < (SYS_TICK_HZ * 5 / 2)); + print_string("\r\nRTL8224 not responding\r\n"); +} + void phy_config_8224(void) __banked { uint16_t pval; + uint16_t tries; print_string("\r\nphy_config_8224 called\r\nRTL8224 ID: "); // Print RTL8224 chip id @@ -244,9 +257,12 @@ void phy_config_8224(void) __banked i++; rtl8224_write_reg_u16(RTL837X_SDS_INDACS_CMD, rtl8224_sds0_setttings[i]); i++; + tries = 0xffff; do { rtl8224_read_reg_u16(0x3f8); - } while (SFR_DATA_8 & 0x80); + } while ((SFR_DATA_8 & 0x80) && --tries); + if (SFR_DATA_8 & 0x80) + print_string("\r\nRTL8224 SerDes access timed out\r\n"); } print_string("\r\nphy_config_8224 done\r\n"); diff --git a/rtl837x_phy.h b/rtl837x_phy.h index 91e675d9..2c2447e5 100644 --- a/rtl837x_phy.h +++ b/rtl837x_phy.h @@ -22,6 +22,7 @@ extern __xdata struct phy_settings phy_settings; void rtl8224_phy_enable(void) __banked; void phy_config(uint8_t phy) __banked; void phy_config_8224(void) __banked; +void rtl8224_wait_ready(void) __banked; void phy_set_speed(void) __banked; void phy_set_duplex(void) __banked; void phy_show(uint8_t port) __banked; diff --git a/rtlplayground.c b/rtlplayground.c index 80f599cb..d8bf8279 100644 --- a/rtlplayground.c +++ b/rtlplayground.c @@ -1701,6 +1701,8 @@ void main(void) REG_SET(RTL837X_PIN_MUX_2, 0x0); // Disable pins for ACL init_smi(); + if (machine_detected.isRTL8373) + rtl8224_wait_ready(); rtl8373_revision();