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>
This commit is contained in:
parent
8c5994f92d
commit
fa1befcb57
|
@ -162,26 +162,29 @@ static int wait_for_ready(u8 *base)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wait 50usec for the codec to indicate that it accepted the previous command.
|
* Wait for the codec to indicate that it accepted the previous command.
|
||||||
* No response would imply that the code is non-operative.
|
* No response would imply that the codec is non-operative.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int wait_for_valid(u8 *base)
|
static int wait_for_valid(u8 *base)
|
||||||
{
|
{
|
||||||
struct stopwatch sw;
|
struct stopwatch sw;
|
||||||
u32 reg32;
|
u32 reg32;
|
||||||
/* Use a 50 usec timeout - the Linux kernel uses the same duration */
|
|
||||||
int timeout = 25;
|
|
||||||
|
|
||||||
/* Send the verb to the codec */
|
/* Send the verb to the codec */
|
||||||
reg32 = read32(base + HDA_ICII_REG);
|
reg32 = read32(base + HDA_ICII_REG);
|
||||||
reg32 |= HDA_ICII_BUSY | HDA_ICII_VALID;
|
reg32 |= HDA_ICII_BUSY | HDA_ICII_VALID;
|
||||||
write32(base + HDA_ICII_REG, reg32);
|
write32(base + HDA_ICII_REG, reg32);
|
||||||
|
|
||||||
while (timeout--)
|
/*
|
||||||
udelay(1);
|
* The timeout is never reached when the codec is functioning properly.
|
||||||
|
* Using a small timeout value can result in spurious errors with some
|
||||||
stopwatch_init_usecs_expire(&sw, 50);
|
* 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)) {
|
while (!stopwatch_expired(&sw)) {
|
||||||
reg32 = read32(base + HDA_ICII_REG);
|
reg32 = read32(base + HDA_ICII_REG);
|
||||||
if ((reg32 & (HDA_ICII_VALID | HDA_ICII_BUSY)) == HDA_ICII_VALID)
|
if ((reg32 & (HDA_ICII_VALID | HDA_ICII_BUSY)) == HDA_ICII_VALID)
|
||||||
|
|
Loading…
Reference in New Issue