From 359fda61026cdce3d87a69b9f58937558c947dbf Mon Sep 17 00:00:00 2001 From: David Garske Date: Thu, 20 Aug 2026 12:31:05 -0400 Subject: [PATCH] zynq: add ZYNQMP_PHY_OP_DELAY step for PHY post-reset settle time --- hal/zynq.c | 11 +++++++++++ hal/zynq.h | 2 ++ 2 files changed, 13 insertions(+) diff --git a/hal/zynq.c b/hal/zynq.c index 0cad42d1..d1ebac3b 100644 --- a/hal/zynq.c +++ b/hal/zynq.c @@ -1998,6 +1998,11 @@ void hal_delay_ms(uint64_t ms) } } +/* Fallback if CNTFRQ_EL0 is unset (no ATF/BL31); ZynqMP counter is 100 MHz */ +#ifndef ZYNQMP_TIMER_CLK_FREQ +#define ZYNQMP_TIMER_CLK_FREQ 100000000ULL +#endif + uint64_t hal_timer_ms(void) { uint64_t val; @@ -2005,6 +2010,9 @@ uint64_t hal_timer_ms(void) unsigned long cntpct; asm volatile("mrs %0, cntfrq_el0" : "=r" (cntfrq)); asm volatile("mrs %0, cntpct_el0" : "=r" (cntpct)); + /* AArch64 UDIV by 0 yields 0, which would hang hal_delay_ms() */ + if (cntfrq == 0) + cntfrq = ZYNQMP_TIMER_CLK_FREQ; val = cntpct * 1000; val /= cntfrq; return val; @@ -2169,6 +2177,9 @@ static void zynq_phy_init(void) (int)steps[i].arg0, (int)rval); } break; + case ZYNQMP_PHY_OP_DELAY: + hal_delay_ms(steps[i].arg1); + break; default: break; } diff --git a/hal/zynq.h b/hal/zynq.h index 9e6661e9..33c4ef1a 100644 --- a/hal/zynq.h +++ b/hal/zynq.h @@ -501,6 +501,8 @@ #define ZYNQMP_PHY_OP_GPIO 0 /* write arg1 to ZYNQMP_PHY_GPIO_ADDR */ #define ZYNQMP_PHY_OP_WR 1 /* MDIO write: reg=arg0, val=arg1 */ #define ZYNQMP_PHY_OP_RD 2 /* MDIO read: reg=arg0 (arg1 ignored) */ +#define ZYNQMP_PHY_OP_DELAY 3 /* delay arg1 ms, max 65535 (arg0 + * ignored); e.g. PHY reset settle */ /* Default sequence: read the PHY ID registers (2, 3) as a diagnostic. With * DEBUG_UART=1 this prints the ID and confirms MDIO reached the PHY. Override