From fa1befcb575c30f59d8622547974c92cde92eb98 Mon Sep 17 00:00:00 2001 From: Angel Pons Date: Thu, 18 Mar 2021 14:12:32 +0100 Subject: [PATCH] device/azalia_device.c: Unify `wait_for_valid` timeouts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The timeout is never reached when the codec is functioning properly. Using a small timeout value can result in spurious errors with some codecs, e.g. a codec that is slow to respond but operates correctly. When a codec is non-operative, the timeout is only reached once per verb table, thus the impact on booting time is relatively small. So, use a reasonably long enough timeout to cover all possible cases. Remove the unconditional 25 µs delay and increase the timeout delay. The new value of 1 ms is the maximum of all existing implementations. Currently, the only boards using this code are AMD reference boards: - AMD Bilby - AMD Mandolin - AMD Padmelon Change-Id: Ia5e4829d404dcecdb9e7a377e896a319cb38531a Signed-off-by: Angel Pons Reviewed-on: https://review.coreboot.org/c/coreboot/+/51634 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber --- src/device/azalia_device.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/device/azalia_device.c b/src/device/azalia_device.c index 2787cb218e..a0b8d5f5be 100644 --- a/src/device/azalia_device.c +++ b/src/device/azalia_device.c @@ -162,26 +162,29 @@ static int wait_for_ready(u8 *base) } /* - * Wait 50usec for the codec to indicate that it accepted the previous command. - * No response would imply that the code is non-operative. + * Wait for the codec to indicate that it accepted the previous command. + * No response would imply that the codec is non-operative. */ static int wait_for_valid(u8 *base) { struct stopwatch sw; u32 reg32; - /* Use a 50 usec timeout - the Linux kernel uses the same duration */ - int timeout = 25; /* Send the verb to the codec */ reg32 = read32(base + HDA_ICII_REG); reg32 |= HDA_ICII_BUSY | HDA_ICII_VALID; write32(base + HDA_ICII_REG, reg32); - while (timeout--) - udelay(1); - - stopwatch_init_usecs_expire(&sw, 50); + /* + * The timeout is never reached when the codec is functioning properly. + * Using a small timeout value can result in spurious errors with some + * codecs, e.g. a codec that is slow to respond but operates correctly. + * When a codec is non-operative, the timeout is only reached once per + * verb table, thus the impact on booting time is relatively small. So, + * use a reasonably long enough timeout to cover all possible cases. + */ + stopwatch_init_msecs_expire(&sw, 1); while (!stopwatch_expired(&sw)) { reg32 = read32(base + HDA_ICII_REG); if ((reg32 & (HDA_ICII_VALID | HDA_ICII_BUSY)) == HDA_ICII_VALID)