From db1a873682d040160acc67e3d7398919151de1dc Mon Sep 17 00:00:00 2001 From: "weiyi.zuo" Date: Fri, 14 Aug 2026 08:12:11 +0000 Subject: [PATCH] a9 : rx suspend immediately wakes up [1/1] PD#SWPL-275664 Problem: rx suspend immediately wakes up Solution: temporary avoidance, Check HDMI RX wake-up logic Fixed conflicts: NA Verify: a9 Change-Id: I0637c760ca82a00460a89a70420ca3ef338734ec Signed-off-by: weiyi.zuo --- hdmirx/hdmirx_wake.c | 55 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 12 deletions(-) diff --git a/hdmirx/hdmirx_wake.c b/hdmirx/hdmirx_wake.c index 81f6e95..787f7ba 100644 --- a/hdmirx/hdmirx_wake.c +++ b/hdmirx/hdmirx_wake.c @@ -276,6 +276,9 @@ void hdmirx_phy_init(void) #endif } +/* bit4: hpd override, bit5: hpd reverse, bits[3:0]: hpd level (1 = high). + * Keep HPD high for the whole suspend, or the source never outputs TMDS. + */ void top_common_init_t3x(void) { unsigned long data32 = 0; @@ -285,12 +288,9 @@ void top_common_init_t3x(void) hdmirx_wr_single_top(TOP_SW_RESET, 0, E_PORT2); hdmirx_wr_single_top(TOP_SW_RESET, 0, E_PORT3); hdmirx_wr_common_top(HDMIRX_TOP_SW_RESET_COMMON, 0); - data32 = 0; - /* bit4: hpd override, bit5: hpd reverse */ data32 |= 1 << 4; data32 |= 1 << 5; data32 |= 0xf << 0; - /* pull down all the hpd */ hdmirx_wr_common_top(TOP_HPD_PWR5V, data32); } @@ -299,12 +299,9 @@ void top_common_init_a9(void) unsigned long data32 = 0; hdmirx_wr_common_top(TOP_SW_RESET, 0); - data32 = 0; - /* bit4: hpd override, bit5: hpd reverse */ data32 |= 1 << 4; data32 |= 1 << 5; data32 |= 0xf << 0; - /* pull down all the hpd */ hdmirx_wr_common_top(TOP_HPD_PWR5V, data32); } @@ -353,27 +350,61 @@ static int hdmirx_get_squelch_sts(void) #endif } +/* hdmirx_phy_init() breaks the PHY lock, so squelch only becomes + * trustworthy ~1-1.2s later. Sample the baseline after that, or an + * already-connected source reads as "absent" and its re-lock then looks + * like a plug-in. Keep this loop free of per-tick printf: the task runs on + * configMINIMAL_STACK_SIZE and overflowing it halts the whole AOCPU. + */ +#define HDMIRX_SQO_SETTLE_MS 2000 +#define HDMIRX_SQO_DEBOUNCE_CNT 5 /* 5 * 20ms = 100ms noise immunity */ + static int sqo_sts_init; void vHDMIRX_task(void *pvParameters) { (void)pvParameters; uint32_t buf[4] = {0}; unsigned long sqo_sts; + int stable_cnt = 0; hdmirx_init(); + vTaskDelay(pdMS_TO_TICKS(HDMIRX_SQO_SETTLE_MS)); sqo_sts_init = hdmirx_get_squelch_sts(); while (1) { vTaskDelay(pdMS_TO_TICKS(20)); sqo_sts = hdmirx_get_squelch_sts(); if (sqo_sts_init == 1) { - if (sqo_sts) - sqo_sts_init = 0; + if (sqo_sts) { + if (++stable_cnt >= HDMIRX_SQO_DEBOUNCE_CNT) { + sqo_sts_init = 0; + stable_cnt = 0; + } + } else { + stable_cnt = 0; + } } else if (!sqo_sts_init) { - if (!sqo_sts) - sqo_sts_init = 2; + if (!sqo_sts) { + if (++stable_cnt >= HDMIRX_SQO_DEBOUNCE_CNT) { + sqo_sts_init = 2; + stable_cnt = 0; + } + } else { + stable_cnt = 0; + } } else if ((sqo_sts_init == 2)) { - if (sqo_sts) - sqo_sts_init = 3; + /* Leaky bucket, not reset-to-0: a freshly plugged + * source glitches squelch while its PHY/CDR locks. + */ + if (sqo_sts) { + if (stable_cnt < HDMIRX_SQO_DEBOUNCE_CNT) + stable_cnt++; + if (stable_cnt >= HDMIRX_SQO_DEBOUNCE_CNT) { + sqo_sts_init = 3; + stable_cnt = 0; + } + } else if (stable_cnt > 0) { + stable_cnt--; + } } if (sqo_sts && sqo_sts_init == 3) { buf[0] = HDMI_RX_WAKEUP; -- 2.43.2