From cbf852734576dc1a7fddfab8549a4cdcb3aab0b7 Mon Sep 17 00:00:00 2001 From: Nicholas Sudsgaard Date: Sun, 24 Aug 2025 11:00:37 +0900 Subject: [PATCH] device/azalia: Amend the mistake of codec_is_operative() One of my previous commits attempted to simplify azalia_codec_init(), but resulted in illogical code which also introduced a bug in certain cases. To summarize, codec_is_operative() tells the controller to get the vendor ID of a specific codec. While doing so, this also checks how the controller and codec respond to see if they are functioning. However, we read the response in azalia_codec_init(). Therefore, these functions must be called sequentially in order to initialize the codecs correctly. In certain cases, we would attempt to read the response without requesting the vendor ID in the first place. This possibly caused these verbs to not get loaded at all. These are the areas affected by the bug: - northbridge/intel/haswell/minihd.c - soc/intel/broadwell/minihd.c TEST=Verbs were loaded on HP ProBook 450 G3 Fixes: 516d05f43dad ("device/azalia: Separate codec checking and initialization") Change-Id: I82ada9e6eca0539b854b5bc61f6f7a88ffd1cdc5 Signed-off-by: Nicholas Sudsgaard Reviewed-on: https://review.coreboot.org/c/coreboot/+/88918 Reviewed-by: Paul Menzel Reviewed-by: Patrick Rudolph Tested-by: build bot (Jenkins) --- src/device/azalia_device.c | 28 +++++----------------------- 1 file changed, 5 insertions(+), 23 deletions(-) diff --git a/src/device/azalia_device.c b/src/device/azalia_device.c index f634908daa..fb31d8f7ca 100644 --- a/src/device/azalia_device.c +++ b/src/device/azalia_device.c @@ -242,25 +242,12 @@ __weak void mainboard_azalia_program_runtime_verbs(u8 *base, u32 viddid) { } -static bool codec_is_operative(u8 *base, const int addr) -{ - if (wait_for_ready(base) < 0) { - printk(BIOS_WARNING, "azalia_audio: controller not ready\n"); - return false; - } - - write32(base + HDA_IC_REG, AZALIA_VERB_GET_VENDOR_ID(addr)); - - if (wait_for_valid(base) < 0) { - printk(BIOS_NOTICE, "azalia_audio: codec #%d doesn't respond\n", addr); - return false; - } - return true; -} - void azalia_codec_init(u8 *base, int addr, const u32 *verb_table, u32 verb_table_bytes) { - const u32 viddid = read32(base + HDA_IR_REG); + if (azalia_write_verb(base, AZALIA_VERB_GET_VENDOR_ID(addr)) < 0) + return; + u32 viddid = read32(base + HDA_IR_REG); + const u32 *verb; u32 verb_size; @@ -283,15 +270,10 @@ void azalia_codec_init(u8 *base, int addr, const u32 *verb_table, u32 verb_table mainboard_azalia_program_runtime_verbs(base, viddid); } -static bool codec_can_init(const u16 codec_mask, u8 *base, const int addr) -{ - return codec_mask & (1 << addr) && codec_is_operative(base, addr); -} - void azalia_codecs_init(u8 *base, u16 codec_mask) { for (int i = AZALIA_MAX_CODECS - 1; i >= 0; i--) { - if (codec_can_init(codec_mask, base, i)) + if (codec_mask & BIT(i)) azalia_codec_init(base, i, cim_verb_data, cim_verb_data_size); }