提交 6744c0d6 编写于 作者: S Simon Glass 提交者: Bin Meng

sound: x86: link: Add sound support

Add sound support for link, using the HDA codec implementation.
Signed-off-by: NSimon Glass <sjg@chromium.org>
Reviewed-by: NBin Meng <bmeng.cn@gmail.com>
上级 ecc7973d
......@@ -21,6 +21,7 @@ config NORTHBRIDGE_INTEL_IVYBRIDGE
imply USB_EHCI_HCD
imply USB_XHCI_HCD
imply VIDEO_VESA
imply SOUND_IVYBRIDGE
if NORTHBRIDGE_INTEL_IVYBRIDGE
......
......@@ -177,6 +177,35 @@ static void sandybridge_setup_northbridge_bars(struct udevice *dev)
dm_pci_write_config8(dev, PAM6, 0x33);
}
/**
* sandybridge_init_iommu() - Set up IOMMU so that azalia can be used
*
* It is not obvious where these values come from. They may be undocumented.
*/
static void sandybridge_init_iommu(struct udevice *dev)
{
u32 capid0_a;
dm_pci_read_config32(dev, 0xe4, &capid0_a);
if (capid0_a & (1 << 23)) {
log_debug("capid0_a not needed\n");
return;
}
/* setup BARs */
writel(IOMMU_BASE1 >> 32, MCHBAR_REG(0x5404));
writel(IOMMU_BASE1 | 1, MCHBAR_REG(0x5400));
writel(IOMMU_BASE2 >> 32, MCHBAR_REG(0x5414));
writel(IOMMU_BASE2 | 1, MCHBAR_REG(0x5410));
/* lock policies */
writel(0x80000000, IOMMU_BASE1 + 0xff0);
/* Enable azalia sound */
writel(0x20000000, IOMMU_BASE2 + 0xff0);
writel(0xa0000000, IOMMU_BASE2 + 0xff0);
}
static int bd82x6x_northbridge_early_init(struct udevice *dev)
{
const int chipset_type = SANDYBRIDGE_MOBILE;
......@@ -197,6 +226,9 @@ static int bd82x6x_northbridge_early_init(struct udevice *dev)
sandybridge_setup_northbridge_bars(dev);
/* Setup IOMMU BARs */
sandybridge_init_iommu(dev);
/* Device Enable */
dm_pci_write_config32(dev, DEVEN, DEVEN_HOST | DEVEN_IGD);
......
/dts-v1/;
#include <dt-bindings/gpio/x86-gpio.h>
#include <dt-bindings/sound/azalia.h>
#include <pci_ids.h>
/include/ "skeleton.dtsi"
/include/ "keyboard.dtsi"
......@@ -372,6 +374,32 @@
compatible = "ehci-pci";
};
hda@1b,0 {
reg = <0x0000d800 0 0 0 0>;
compatible = "intel,bd82x6x-hda";
/* These correspond to the Intel HDA specification */
beep-verbs = <
0x00170500 /* power up codec */
0x00270500 /* power up DAC */
0x00b70500 /* power up speaker */
0x00b70740 /* enable speaker out */
0x00b78d00 /* enable EAPD pin */
0x00b70c02 /* set EAPD pin */
0x0143b013>; /* beep volume */
codecs {
creative_codec: creative-ca0132 {
vendor-id = <PCI_VENDOR_ID_CREATIVE>;
device-id = <PCI_DEVICE_ID_CREATIVE_CA01322>;
};
intel_hdmi: hdmi {
vendor-id = <PCI_VENDOR_ID_INTEL>;
device-id = <PCI_DEVICE_ID_INTEL_COUGARPOINT_HDMI>;
};
};
};
usb_0: usb@1d,0 {
reg = <0x0000e800 0 0 0 0>;
compatible = "ehci-pci";
......@@ -492,3 +520,71 @@
};
};
&creative_codec {
verbs = <
/**
* Malcolm Setup. These correspond to the Intel HDA
* specification.
*/
0x01570d09 0x01570c23 0x01570a01 0x01570df0
0x01570efe 0x01570775 0x015707d3 0x01570709
0x01570753 0x015707d4 0x015707ef 0x01570775
0x015707d3 0x01570709 0x01570702 0x01570737
0x01570778 0x01553cce 0x015575c9 0x01553dce
0x0155b7c9 0x01570de8 0x01570efe 0x01570702
0x01570768 0x01570762 0x01553ace 0x015546c9
0x01553bce 0x0155e8c9 0x01570d49 0x01570c88
0x01570d20 0x01570e19 0x01570700 0x01571a05
0x01571b29 0x01571a04 0x01571b29 0x01570a01
/* Pin Widget Verb Table */
/* NID 0x01, HDA Codec Subsystem ID Verb Table: 0x144dc0c2 */
AZALIA_SUBVENDOR(0x0, 0x144dc0c2)
/*
* Pin Complex (NID 0x0B) Port-G Analog Unknown
* Speaker at Int N/A
*/
AZALIA_PIN_CFG(0x0, 0x0b, 0x901700f0)
/* Pin Complex (NID 0x0C) N/C */
AZALIA_PIN_CFG(0x0, 0x0c, 0x70f000f0)
/* Pin Complex (NID 0x0D) N/C */
AZALIA_PIN_CFG(0x0, 0x0d, 0x70f000f0)
/* Pin Complex (NID 0x0E) N/C */
AZALIA_PIN_CFG(0x0, 0x0e, 0x70f000f0)
/* Pin Complex (NID 0x0F) N/C */
AZALIA_PIN_CFG(0x0, 0x0f, 0x70f000f0)
/* Pin Complex (NID 0x10) Port-D 1/8 Black HP Out at Ext Left */
AZALIA_PIN_CFG(0x0, 0x10, 0x032110f0)
/* Pin Complex (NID 0x11) Port-B Click Mic */
AZALIA_PIN_CFG(0x0, 0x11, 0x90a700f0)
/* Pin Complex (NID 0x12) Port-C Combo Jack Mic or D-Mic */
AZALIA_PIN_CFG(0x0, 0x12, 0x03a110f0)
/* Pin Complex (NID 0x13) What you hear */
AZALIA_PIN_CFG(0x0, 0x13, 0x90d600f0)>;
};
&intel_hdmi {
verbs = <
/* NID 0x01, HDA Codec Subsystem ID Verb Table: 0x80860101 */
AZALIA_SUBVENDOR(0x3, 0x80860101)
/* Pin Complex (NID 0x05) Digital Out at Int HDMI */
AZALIA_PIN_CFG(0x3, 0x05, 0x18560010)
/* Pin Complex (NID 0x06) Digital Out at Int HDMI */
AZALIA_PIN_CFG(0x3, 0x06, 0x18560020)
/* Pin Complex (NID 0x07) Digital Out at Int HDMI */
AZALIA_PIN_CFG(0x3, 0x07, 0x18560030)>;
};
......@@ -43,6 +43,9 @@
/* 4 KB per PCIe device */
#define DEFAULT_PCIEXBAR CONFIG_PCIE_ECAM_BASE
#define IOMMU_BASE1 0xfed90000ULL
#define IOMMU_BASE2 0xfed91000ULL
/* Device 0:0.0 PCI configuration space (Host Bridge) */
#define EPBAR 0x40
#define MCHBAR 0x48
......
......@@ -33,6 +33,7 @@ CONFIG_CMD_DHCP=y
# CONFIG_CMD_NFS is not set
CONFIG_CMD_PING=y
CONFIG_CMD_TIME=y
CONFIG_CMD_SOUND=y
CONFIG_CMD_BOOTSTAGE=y
CONFIG_CMD_TPM=y
CONFIG_CMD_TPM_TEST=y
......@@ -53,6 +54,7 @@ CONFIG_SYS_I2C_INTEL=y
CONFIG_CROS_EC=y
CONFIG_CROS_EC_LPC=y
CONFIG_SYS_NS16550=y
CONFIG_SOUND=y
CONFIG_SPI=y
CONFIG_TPM_TIS_LPC=y
CONFIG_USB_STORAGE=y
......
......@@ -49,6 +49,16 @@ config SOUND_INTEL_HDA
Azalia which was the development code-name. It requires setup
information in the device tree (see intel-hda.txt).
config SOUND_IVYBRIDGE
bool "Intel Ivybridge sound support"
depends on SOUND
select SOUND_INTEL_HDA
help
Enable sound output on supported Intel Ivybridge-based boards. This
driver uses Intel's High-definition Audio (HDA) architecture,
sometimes called Azalia. The audio codec is detected using a
semi-automatic mechanism.
config SOUND_MAX98088
bool "Support Maxim max98088 audio codec"
depends on I2S
......
......@@ -16,3 +16,4 @@ obj-$(CONFIG_SOUND_MAX98088) += max98088.o maxim_codec.o
obj-$(CONFIG_SOUND_MAX98090) += max98090.o maxim_codec.o
obj-$(CONFIG_SOUND_MAX98095) += max98095.o maxim_codec.o
obj-$(CONFIG_SOUND_INTEL_HDA) += hda_codec.o
obj-$(CONFIG_SOUND_IVYBRIDGE) += ivybridge_sound.o
// 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 <pch.h>
#include <sound.h>
static int bd82x6x_azalia_probe(struct udevice *dev)
{
struct pci_child_platdata *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_platdata(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_alloc_size = sizeof(struct hda_codec_priv),
};
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册