summaryrefslogtreecommitdiff
path: root/src/device
diff options
context:
space:
mode:
authorAngel Pons <th3fanbus@gmail.com>2021-03-18 14:12:32 +0100
committerPatrick Georgi <pgeorgi@google.com>2021-03-24 07:54:34 +0000
commitfa1befcb575c30f59d8622547974c92cde92eb98 (patch)
treec71e1d7aa94e0a1daecea0bcf4efdb383a983a47 /src/device
parent8c5994f92d2c23d011daaa39dbb0fab88425a1d2 (diff)
downloadcoreboot-fa1befcb575c30f59d8622547974c92cde92eb98.tar.xz
device/azalia_device.c: Unify `wait_for_valid` timeouts
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 <th3fanbus@gmail.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/51634 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Nico Huber <nico.h@gmx.de>
Diffstat (limited to 'src/device')
-rw-r--r--src/device/azalia_device.c19
1 files 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)