device/azalia_device.c: Add option to lock down GCAP

On Intel 6-series PCHs, the GCAP register is R/WO (Read / Write Once),
and needs to be written to after the HD Audio controller is taken out
of reset. Add a Kconfig option to read and write back GCAP in order to
lock it down. Follow-up commits will select this option when switching
platforms to use common Azalia code, to preserve original behaviour.

Change-Id: I70bab20816fb6c0bf7bff35c3d2f5828cd96172d
Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Signed-off-by: Angel Pons <th3fanbus@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/50794
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
This commit is contained in:
Angel Pons 2021-03-22 14:21:28 +01:00
parent 6b89746644
commit b922cbbdd6
2 changed files with 14 additions and 0 deletions

View File

@ -527,6 +527,15 @@ config AZALIA_MAX_CODECS
help help
The maximum number of codecs supported on a single HD Audio controller. The maximum number of codecs supported on a single HD Audio controller.
config AZALIA_LOCK_DOWN_R_WO_GCAP
def_bool n
depends on AZALIA_PLUGIN_SUPPORT
help
The GCAP register is implemented as R/WO (Read / Write Once) on some
HD Audio controllers, such as Intel 6-series PCHs. Select this option
to lock down the GCAP register after deasserting the controller reset
bit. Locking is done by reading GCAP and writing back the read value.
config PCIEXP_PLUGIN_SUPPORT config PCIEXP_PLUGIN_SUPPORT
bool bool
default y default y

View File

@ -56,6 +56,11 @@ static u16 codec_detect(u8 *base)
if (azalia_exit_reset(base) < 0) if (azalia_exit_reset(base) < 0)
goto no_codec; goto no_codec;
if (CONFIG(AZALIA_LOCK_DOWN_R_WO_GCAP)) {
/* If GCAP is R/WO, lock it down after deasserting controller reset */
write16(base + HDA_GCAP_REG, read16(base + HDA_GCAP_REG));
}
/* clear STATESTS bits (BAR + 0xe)[2:0] */ /* clear STATESTS bits (BAR + 0xe)[2:0] */
reg16 = read16(base + HDA_STATESTS_REG); reg16 = read16(base + HDA_STATESTS_REG);
reg16 |= codec_mask; reg16 |= codec_mask;