123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- // SPDX-License-Identifier: GPL-2.0
- /*
- * Intel HDA audio (Azalia) for ivybridge
- *
- * Originally from coreboot file bd82x6x/azalia.c
- *
- * Copyright (C) 2008 Advanced Micro Devices, Inc.
- * Copyright (C) 2008-2009 coresystems GmbH
- * Copyright (C) 2011 The ChromiumOS Authors.
- * Copyright 2018 Google LLC
- */
- #define LOG_CATEGORY UCLASS_SOUND
- #include <common.h>
- #include <dm.h>
- #include <hda_codec.h>
- #include <log.h>
- #include <pch.h>
- #include <sound.h>
- #include <linux/bitops.h>
- #include <asm/global_data.h>
- static int bd82x6x_azalia_probe(struct udevice *dev)
- {
- struct pci_child_plat *plat;
- struct hda_codec_priv *priv;
- struct udevice *pch;
- u32 codec_mask;
- int conf;
- int ret;
- /* Only init after relocation */
- if (!(gd->flags & GD_FLG_RELOC))
- return 0;
- ret = hda_codec_init(dev);
- if (ret) {
- log_debug("Cannot set up HDA codec (err=%d)\n", ret);
- return ret;
- }
- priv = dev_get_priv(dev);
- ret = uclass_first_device_err(UCLASS_PCH, &pch);
- log_debug("PCH %p %s\n", pch, pch->name);
- if (ret)
- return ret;
- conf = pch_ioctl(pch, PCH_REQ_HDA_CONFIG, NULL, 0);
- log_debug("conf = %x\n", conf);
- if (conf >= 0) {
- dm_pci_clrset_config32(dev, 0x120, 7 << 24 | 0xfe,
- 1 << 24 | /* 2 << 24 for server */
- conf);
- dm_pci_clrset_config16(dev, 0x78, 0, 1 << 1);
- } else {
- log_debug("V1CTL disabled\n");
- }
- dm_pci_clrset_config32(dev, 0x114, 0xfe, 0);
- /* Set VCi enable bit */
- dm_pci_clrset_config32(dev, 0x120, 0, 1U << 31);
- /* Enable HDMI codec */
- dm_pci_clrset_config32(dev, 0xc4, 0, 1 << 1);
- dm_pci_clrset_config8(dev, 0x43, 0, 1 << 6);
- /* Additional programming steps */
- dm_pci_clrset_config32(dev, 0xc4, 0, 1 << 13);
- dm_pci_clrset_config32(dev, 0xc4, 0, 1 << 10);
- dm_pci_clrset_config32(dev, 0xd0, 1U << 31, 0);
- /* Additional step on Panther Point */
- plat = dev_get_parent_plat(dev);
- if (plat->device == PCI_DEVICE_ID_INTEL_PANTHERPOINT_HDA)
- dm_pci_clrset_config32(dev, 0xc4, 0, 1 << 17);
- dm_pci_write_config8(dev, 0x3c, 0xa); /* unused? */
- /* Audio Control: Select Azalia mode */
- dm_pci_clrset_config8(dev, 0x40, 0, 1);
- dm_pci_clrset_config8(dev, 0x4d, 1 << 7, 0); /* Docking not supported */
- codec_mask = hda_codec_detect(priv->regs);
- log_debug("codec_mask = %02x\n", codec_mask);
- if (codec_mask) {
- ret = hda_codecs_init(dev, priv->regs, codec_mask);
- if (ret) {
- log_err("Codec init failed (err=%d)\n", ret);
- return ret;
- }
- }
- /* Enable dynamic clock gating */
- dm_pci_clrset_config8(dev, 0x43, 7, BIT(2) | BIT(0));
- ret = hda_codec_finish_init(dev);
- if (ret) {
- log_debug("Cannot set up HDA codec (err=%d)\n", ret);
- return ret;
- }
- return 0;
- }
- static int bd82x6x_azalia_setup(struct udevice *dev)
- {
- return 0;
- }
- int bd82x6x_azalia_start_beep(struct udevice *dev, int frequency_hz)
- {
- return hda_codec_start_beep(dev, frequency_hz);
- }
- int bd82x6x_azalia_stop_beep(struct udevice *dev)
- {
- return hda_codec_stop_beep(dev);
- }
- static const struct sound_ops bd82x6x_azalia_ops = {
- .setup = bd82x6x_azalia_setup,
- .start_beep = bd82x6x_azalia_start_beep,
- .stop_beep = bd82x6x_azalia_stop_beep,
- };
- static const struct udevice_id bd82x6x_azalia_ids[] = {
- { .compatible = "intel,hd-audio" },
- { }
- };
- U_BOOT_DRIVER(bd82x6x_azalia_drv) = {
- .name = "bd82x6x-hda",
- .id = UCLASS_SOUND,
- .of_match = bd82x6x_azalia_ids,
- .probe = bd82x6x_azalia_probe,
- .ops = &bd82x6x_azalia_ops,
- .priv_auto = sizeof(struct hda_codec_priv),
- };
|