summaryrefslogtreecommitdiff
path: root/arch/x86
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/cpu/broadwell/Makefile1
-rw-r--r--arch/x86/cpu/broadwell/adsp.c156
-rw-r--r--arch/x86/cpu/broadwell/pch.c110
-rw-r--r--arch/x86/cpu/broadwell/pinctrl_broadwell.c3
-rw-r--r--arch/x86/cpu/ivybridge/Kconfig1
-rw-r--r--arch/x86/cpu/ivybridge/bd82x6x.c27
-rw-r--r--arch/x86/cpu/ivybridge/northbridge.c32
-rw-r--r--arch/x86/dts/chromebook_link.dts96
-rw-r--r--arch/x86/dts/chromebook_samus.dts49
-rw-r--r--arch/x86/include/asm/arch-broadwell/adsp.h46
-rw-r--r--arch/x86/include/asm/arch-broadwell/pch.h3
-rw-r--r--arch/x86/include/asm/arch-broadwell/rcb.h2
-rw-r--r--arch/x86/include/asm/arch-broadwell/serialio.h82
-rw-r--r--arch/x86/include/asm/arch-ivybridge/sandybridge.h3
-rw-r--r--arch/x86/include/asm/i8254.h18
-rw-r--r--arch/x86/include/asm/io.h16
-rw-r--r--arch/x86/lib/i8254.c35
17 files changed, 661 insertions, 19 deletions
diff --git a/arch/x86/cpu/broadwell/Makefile b/arch/x86/cpu/broadwell/Makefile
index a032861e57..d3785aabdf 100644
--- a/arch/x86/cpu/broadwell/Makefile
+++ b/arch/x86/cpu/broadwell/Makefile
@@ -2,6 +2,7 @@
#
# Copyright (c) 2016 Google, Inc
+obj-y += adsp.o
obj-y += cpu.o
obj-y += iobp.o
obj-y += lpc.o
diff --git a/arch/x86/cpu/broadwell/adsp.c b/arch/x86/cpu/broadwell/adsp.c
new file mode 100644
index 0000000000..2ac8cea7c3
--- /dev/null
+++ b/arch/x86/cpu/broadwell/adsp.c
@@ -0,0 +1,156 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Support for Intel Application Digital Signal Processor
+ *
+ * Copyright 2019 Google LLC
+ *
+ * Modified from coreboot file of the same name
+ */
+
+#define LOG_CATEGORY UCLASS_SYSCON
+
+#include <common.h>
+#include <dm.h>
+#include <pci.h>
+#include <asm/io.h>
+#include <asm/cpu.h>
+#include <asm/intel_regs.h>
+#include <asm/arch/adsp.h>
+#include <asm/arch/pch.h>
+#include <asm/arch/rcb.h>
+
+enum pci_type_t {
+ LYNX_POINT,
+ WILDCAT_POINT,
+};
+
+struct broadwell_adsp_priv {
+ bool adsp_d3_pg_enable;
+ bool adsp_sram_pg_enable;
+ bool sio_acpi_mode;
+};
+
+static int broadwell_adsp_probe(struct udevice *dev)
+{
+ struct broadwell_adsp_priv *priv = dev_get_priv(dev);
+ enum pci_type_t type;
+ u32 bar0, bar1;
+ u32 tmp32;
+
+ /* Find BAR0 and BAR1 */
+ bar0 = dm_pci_read_bar32(dev, 0);
+ if (!bar0)
+ return -EINVAL;
+ bar1 = dm_pci_read_bar32(dev, 1);
+ if (!bar1)
+ return -EINVAL;
+
+ /*
+ * Set LTR value in DSP shim LTR control register to 3ms
+ * SNOOP_REQ[13]=1b SNOOP_SCALE[12:10]=100b (1ms) SNOOP_VAL[9:0]=3h
+ */
+ type = dev_get_driver_data(dev);
+ tmp32 = type == WILDCAT_POINT ? ADSP_SHIM_BASE_WPT : ADSP_SHIM_BASE_LPT;
+ writel(ADSP_SHIM_LTRC_VALUE, bar0 + tmp32);
+
+ /* Program VDRTCTL2 D19:F0:A8[31:0] = 0x00000fff */
+ dm_pci_write_config32(dev, ADSP_PCI_VDRTCTL2, ADSP_VDRTCTL2_VALUE);
+
+ /* Program ADSP IOBP VDLDAT1 to 0x040100 */
+ pch_iobp_write(ADSP_IOBP_VDLDAT1, ADSP_VDLDAT1_VALUE);
+
+ /* Set D3 Power Gating Enable in D19:F0:A0 based on PCH type */
+ dm_pci_read_config32(dev, ADSP_PCI_VDRTCTL0, &tmp32);
+ if (type == WILDCAT_POINT) {
+ if (priv->adsp_d3_pg_enable) {
+ tmp32 &= ~ADSP_VDRTCTL0_D3PGD_WPT;
+ if (priv->adsp_sram_pg_enable)
+ tmp32 &= ~ADSP_VDRTCTL0_D3SRAMPGD_WPT;
+ else
+ tmp32 |= ADSP_VDRTCTL0_D3SRAMPGD_WPT;
+ } else {
+ tmp32 |= ADSP_VDRTCTL0_D3PGD_WPT;
+ }
+ } else {
+ if (priv->adsp_d3_pg_enable) {
+ tmp32 &= ~ADSP_VDRTCTL0_D3PGD_LPT;
+ if (priv->adsp_sram_pg_enable)
+ tmp32 &= ~ADSP_VDRTCTL0_D3SRAMPGD_LPT;
+ else
+ tmp32 |= ADSP_VDRTCTL0_D3SRAMPGD_LPT;
+ } else {
+ tmp32 |= ADSP_VDRTCTL0_D3PGD_LPT;
+ }
+ }
+ dm_pci_write_config32(dev, ADSP_PCI_VDRTCTL0, tmp32);
+
+ /* Set PSF Snoop to SA, RCBA+0x3350[10]=1b */
+ setbits_le32(RCB_REG(0x3350), 1 << 10);
+
+ /* Set DSP IOBP PMCTL 0x1e0=0x3f */
+ pch_iobp_write(ADSP_IOBP_PMCTL, ADSP_PMCTL_VALUE);
+
+ if (priv->sio_acpi_mode) {
+ /* Configure for ACPI mode */
+ log_info("ADSP: Enable ACPI Mode IRQ3\n");
+
+ /* Set interrupt de-assert/assert opcode override to IRQ3 */
+ pch_iobp_write(ADSP_IOBP_VDLDAT2, ADSP_IOBP_ACPI_IRQ3);
+
+ /* Enable IRQ3 in RCBA */
+ setbits_le32(RCB_REG(ACPIIRQEN), ADSP_ACPI_IRQEN);
+
+ /* Set ACPI Interrupt Enable Bit */
+ pch_iobp_update(ADSP_IOBP_PCICFGCTL, ~ADSP_PCICFGCTL_SPCBAD,
+ ADSP_PCICFGCTL_ACPIIE);
+
+ /* Put ADSP in D3hot */
+ clrbits_le32(bar1 + PCH_PCS, PCH_PCS_PS_D3HOT);
+ } else {
+ log_info("ADSP: Enable PCI Mode IRQ23\n");
+
+ /* Configure for PCI mode */
+ dm_pci_write_config32(dev, PCI_INTERRUPT_LINE, ADSP_PCI_IRQ);
+
+ /* Clear ACPI Interrupt Enable Bit */
+ pch_iobp_update(ADSP_IOBP_PCICFGCTL,
+ ~(ADSP_PCICFGCTL_SPCBAD |
+ ADSP_PCICFGCTL_ACPIIE), 0);
+ }
+
+ return 0;
+}
+
+static int broadwell_adsp_ofdata_to_platdata(struct udevice *dev)
+{
+ struct broadwell_adsp_priv *priv = dev_get_priv(dev);
+
+ priv->adsp_d3_pg_enable = dev_read_bool(dev, "intel,adsp-d3-pg-enable");
+ priv->adsp_sram_pg_enable = dev_read_bool(dev,
+ "intel,adsp-sram-pg-enable");
+ priv->sio_acpi_mode = dev_read_bool(dev, "intel,sio-acpi-mode");
+
+ return 0;
+}
+
+static const struct udevice_id broadwell_adsp_ids[] = {
+ { .compatible = "intel,wildcatpoint-adsp", .data = WILDCAT_POINT },
+ { }
+};
+
+U_BOOT_DRIVER(broadwell_adsp_drv) = {
+ .name = "adsp",
+ .id = UCLASS_SYSCON,
+ .ofdata_to_platdata = broadwell_adsp_ofdata_to_platdata,
+ .of_match = broadwell_adsp_ids,
+ .bind = dm_scan_fdt_dev,
+ .probe = broadwell_adsp_probe,
+};
+
+static struct pci_device_id broadwell_adsp_supported[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL,
+ PCI_DEVICE_ID_INTEL_WILDCATPOINT_ADSP) },
+ { },
+};
+
+U_BOOT_PCI_DEVICE(broadwell_adsp_drv, broadwell_adsp_supported);
diff --git a/arch/x86/cpu/broadwell/pch.c b/arch/x86/cpu/broadwell/pch.c
index 82506ba35e..73d3d3b515 100644
--- a/arch/x86/cpu/broadwell/pch.c
+++ b/arch/x86/cpu/broadwell/pch.c
@@ -20,7 +20,9 @@
#include <asm/arch/pch.h>
#include <asm/arch/pm.h>
#include <asm/arch/rcb.h>
+#include <asm/arch/serialio.h>
#include <asm/arch/spi.h>
+#include <dm/uclass-internal.h>
#define BIOS_CTRL 0xdc
@@ -456,6 +458,111 @@ static void systemagent_init(void)
cpu_set_power_limits(28);
}
+/* Enable LTR Auto Mode for D21:F1-F6 */
+static void serialio_d21_ltr(u32 bar0)
+{
+ /* 1. Program BAR0 + 808h[2] = 0b */
+ clrbits_le32(bar0 + SIO_REG_PPR_GEN, SIO_REG_PPR_GEN_LTR_MODE_MASK);
+
+ /* 2. Program BAR0 + 804h[1:0] = 00b */
+ clrbits_le32(bar0 + SIO_REG_PPR_RST, SIO_REG_PPR_RST_ASSERT);
+
+ /* 3. Program BAR0 + 804h[1:0] = 11b */
+ setbits_le32(bar0 + SIO_REG_PPR_RST, SIO_REG_PPR_RST_ASSERT);
+
+ /* 4. Program BAR0 + 814h[31:0] = 00000000h */
+ writel(0, bar0 + SIO_REG_AUTO_LTR);
+}
+
+/* Select I2C voltage of 1.8V or 3.3V */
+static void serialio_i2c_voltage_sel(u32 bar0, uint voltage)
+{
+ clrsetbits_le32(bar0 + SIO_REG_PPR_GEN, SIO_REG_PPR_GEN_VOLTAGE_MASK,
+ SIO_REG_PPR_GEN_VOLTAGE(voltage));
+}
+
+/* Put Serial IO D21:F0-F6 device into desired mode */
+static void serialio_d21_mode(int sio_index, int int_pin, bool acpi_mode)
+{
+ u32 portctrl = SIO_IOBP_PORTCTRL_PM_CAP_PRSNT;
+
+ /* Snoop select 1 */
+ portctrl |= SIO_IOBP_PORTCTRL_SNOOP_SELECT(1);
+
+ /* Set interrupt pin */
+ portctrl |= SIO_IOBP_PORTCTRL_INT_PIN(int_pin);
+
+ if (acpi_mode) {
+ /* Enable ACPI interrupt mode */
+ portctrl |= SIO_IOBP_PORTCTRL_ACPI_IRQ_EN;
+ }
+
+ pch_iobp_update(SIO_IOBP_PORTCTRLX(sio_index), 0, portctrl);
+}
+
+/* Init sequence to be run once, done as part of D21:F0 (SDMA) init */
+static void serialio_init_once(bool acpi_mode)
+{
+ if (acpi_mode) {
+ /* Enable ACPI IRQ for IRQ13, IRQ7, IRQ6, IRQ5 in RCBA */
+ setbits_le32(RCB_REG(ACPIIRQEN),
+ 1 << 13 | 1 << 7 | 1 << 6 | 1 << 5);
+ }
+
+ /* Program IOBP CB000154h[12,9:8,4:0] = 1001100011111b */
+ pch_iobp_update(SIO_IOBP_GPIODF, ~0x0000131f, 0x0000131f);
+
+ /* Program IOBP CB000180h[5:0] = 111111b (undefined register) */
+ pch_iobp_update(0xcb000180, ~0x0000003f, 0x0000003f);
+}
+
+/**
+ * pch_serialio_init() - set up serial I/O devices
+ *
+ * @return 0 if OK, -ve on error
+ */
+static int pch_serialio_init(void)
+{
+ struct udevice *dev, *hda;
+ bool acpi_mode = true;
+ u32 bar0, bar1;
+ int ret;
+
+ ret = uclass_find_first_device(UCLASS_I2C, &dev);
+ if (ret)
+ return ret;
+ bar0 = dm_pci_read_bar32(dev, 0);
+ if (!bar0)
+ return -EINVAL;
+ bar1 = dm_pci_read_bar32(dev, 1);
+ if (!bar1)
+ return -EINVAL;
+
+ serialio_init_once(acpi_mode);
+ serialio_d21_mode(SIO_ID_SDMA, SIO_PIN_INTB, acpi_mode);
+
+ serialio_d21_ltr(bar0);
+ serialio_i2c_voltage_sel(bar0, 1); /* Select 1.8V always */
+ serialio_d21_mode(SIO_ID_I2C0, SIO_PIN_INTC, acpi_mode);
+ setbits_le32(bar1 + PCH_PCS, PCH_PCS_PS_D3HOT);
+
+ clrbits_le32(bar1 + PCH_PCS, PCH_PCS_PS_D3HOT);
+
+ setbits_le32(bar0 + SIO_REG_PPR_CLOCK, SIO_REG_PPR_CLOCK_EN);
+
+ /* Manually find the High-definition audio, to turn it off */
+ ret = dm_pci_bus_find_bdf(PCI_BDF(0, 0x1b, 0), &hda);
+ if (ret)
+ return -ENOENT;
+ dm_pci_clrset_config8(hda, 0x43, 0, 0x6f);
+
+ /* Route I/O buffers to ADSP function */
+ dm_pci_clrset_config8(hda, 0x42, 0, 1 << 7 | 1 << 6);
+ log_debug("HDA disabled, I/O buffers routed to ADSP\n");
+
+ return 0;
+}
+
static int broadwell_pch_init(struct udevice *dev)
{
int ret;
@@ -482,6 +589,9 @@ static int broadwell_pch_init(struct udevice *dev)
return ret;
pch_pm_init(dev);
pch_cg_init(dev);
+ ret = pch_serialio_init();
+ if (ret)
+ return ret;
systemagent_init();
return 0;
diff --git a/arch/x86/cpu/broadwell/pinctrl_broadwell.c b/arch/x86/cpu/broadwell/pinctrl_broadwell.c
index 914ecfb314..aa83abbf85 100644
--- a/arch/x86/cpu/broadwell/pinctrl_broadwell.c
+++ b/arch/x86/cpu/broadwell/pinctrl_broadwell.c
@@ -16,6 +16,7 @@
#include <asm/arch/gpio.h>
#include <dt-bindings/gpio/x86-gpio.h>
#include <dm/pinctrl.h>
+#include <dm/uclass-internal.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -214,7 +215,7 @@ static int broadwell_pinctrl_probe(struct udevice *dev)
u32 gpiobase;
int ret;
- ret = uclass_first_device(UCLASS_PCH, &pch);
+ ret = uclass_find_first_device(UCLASS_PCH, &pch);
if (ret)
return ret;
if (!pch)
diff --git a/arch/x86/cpu/ivybridge/Kconfig b/arch/x86/cpu/ivybridge/Kconfig
index 5f0e60837c..2f42393786 100644
--- a/arch/x86/cpu/ivybridge/Kconfig
+++ b/arch/x86/cpu/ivybridge/Kconfig
@@ -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
diff --git a/arch/x86/cpu/ivybridge/bd82x6x.c b/arch/x86/cpu/ivybridge/bd82x6x.c
index a78bb02544..ed9bce6416 100644
--- a/arch/x86/cpu/ivybridge/bd82x6x.c
+++ b/arch/x86/cpu/ivybridge/bd82x6x.c
@@ -20,8 +20,12 @@
DECLARE_GLOBAL_DATA_PTR;
-#define GPIO_BASE 0x48
-#define BIOS_CTRL 0xdc
+#define GPIO_BASE 0x48
+#define BIOS_CTRL 0xdc
+
+#define RCBA_AUDIO_CONFIG 0x2030
+#define RCBA_AUDIO_CONFIG_HDA BIT(31)
+#define RCBA_AUDIO_CONFIG_MASK 0xfe
#ifndef CONFIG_HAVE_FSP
static int pch_revision_id = -1;
@@ -212,10 +216,29 @@ static int bd82x6x_get_gpio_base(struct udevice *dev, u32 *gbasep)
return 0;
}
+static int bd82x6x_ioctl(struct udevice *dev, enum pch_req_t req, void *data,
+ int size)
+{
+ u32 rcba, val;
+
+ switch (req) {
+ case PCH_REQ_HDA_CONFIG:
+ dm_pci_read_config32(dev, PCH_RCBA, &rcba);
+ val = readl(rcba + RCBA_AUDIO_CONFIG);
+ if (!(val & RCBA_AUDIO_CONFIG_HDA))
+ return -ENOENT;
+
+ return val & RCBA_AUDIO_CONFIG_MASK;
+ default:
+ return -ENOSYS;
+ }
+}
+
static const struct pch_ops bd82x6x_pch_ops = {
.get_spi_base = bd82x6x_pch_get_spi_base,
.set_spi_protect = bd82x6x_set_spi_protect,
.get_gpio_base = bd82x6x_get_gpio_base,
+ .ioctl = bd82x6x_ioctl,
};
static const struct udevice_id bd82x6x_ids[] = {
diff --git a/arch/x86/cpu/ivybridge/northbridge.c b/arch/x86/cpu/ivybridge/northbridge.c
index 39bab7bdf3..a809b823b3 100644
--- a/arch/x86/cpu/ivybridge/northbridge.c
+++ b/arch/x86/cpu/ivybridge/northbridge.c
@@ -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);
diff --git a/arch/x86/dts/chromebook_link.dts b/arch/x86/dts/chromebook_link.dts
index f9f0979730..c5653feac7 100644
--- a/arch/x86/dts/chromebook_link.dts
+++ b/arch/x86/dts/chromebook_link.dts
@@ -1,6 +1,8 @@
/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)>;
+};
diff --git a/arch/x86/dts/chromebook_samus.dts b/arch/x86/dts/chromebook_samus.dts
index b58936b4ac..ad687ce2cc 100644
--- a/arch/x86/dts/chromebook_samus.dts
+++ b/arch/x86/dts/chromebook_samus.dts
@@ -494,10 +494,20 @@
intel,pre-graphics-delay = <200>;
};
- me@16,0 {
- reg = <0x0000b000 0 0 0 0>;
- compatible = "intel,me";
- u-boot,dm-pre-reloc;
+ adsp@13,0 {
+ reg = <0x00009800 0 0 0 0>;
+ compatible = "intel,wildcatpoint-adsp";
+ intel,adsp-d3-pg-enable = <0>;
+ intel,adsp-sram-pg-enable = <0>;
+ intel,sio-acpi-mode;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ i2s: shim {
+ compatible = "intel,broadwell-i2s";
+ #sound-dai-cells = <1>;
+ reg = <0xfb000 0xfc000 0xfd000>;
+ };
};
usb_1: usb@14,0 {
@@ -505,6 +515,25 @@
compatible = "xhci-pci";
};
+ i2c0: i2c@15,1 {
+ reg = <0x0000a900 0 0 0 0>;
+ compatible = "snps,designware-i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ rt5677: rt5677@2c {
+ compatible = "realtek,rt5677";
+ #sound-dai-cells = <1>;
+ reg = <0x2c>;
+ };
+ };
+
+ me@16,0 {
+ reg = <0x0000b000 0 0 0 0>;
+ compatible = "intel,me";
+ u-boot,dm-pre-reloc;
+ };
+
usb_0: usb@1d,0 {
status = "disabled";
reg = <0x0000e800 0 0 0 0>;
@@ -626,4 +655,16 @@
};
};
+ sound {
+ compatible = "google,samus-sound";
+ codec-enable-gpio = <&gpio_b 11 GPIO_ACTIVE_HIGH>;
+ cpu {
+ sound-dai = <&i2s 0>;
+ };
+
+ codec {
+ sound-dai = <&rt5677 0>;
+ };
+ };
+
};
diff --git a/arch/x86/include/asm/arch-broadwell/adsp.h b/arch/x86/include/asm/arch-broadwell/adsp.h
new file mode 100644
index 0000000000..eb825ce1c0
--- /dev/null
+++ b/arch/x86/include/asm/arch-broadwell/adsp.h
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Support for Intel Application Digital Signal Processor
+ *
+ * Copyright 2019 Google LLC
+ *
+ * Modified from coreboot file of the same name
+ */
+
+#ifndef __ASM_ARCH_BROADWELL_ADSP_H
+#define __ASM_ARCH_BROADWELL_ADSP_H
+
+#define ADSP_PCI_IRQ 23
+#define ADSP_ACPI_IRQ 3
+#define ADSP_ACPI_IRQEN BIT(3)
+
+#define ADSP_SHIM_BASE_LPT 0xe7000
+#define ADSP_SHIM_BASE_WPT 0xfb000
+#define ADSP_SHIM_LTRC 0xe0
+#define ADSP_SHIM_LTRC_VALUE 0x3003
+#define ADSP_SHIM_IMC 0x28
+#define ADSP_SHIM_IPCD 0x40
+
+#define ADSP_PCI_VDRTCTL0 0xa0
+#define ADSP_VDRTCTL0_D3PGD_LPT BIT(1)
+#define ADSP_VDRTCTL0_D3PGD_WPT BIT(0)
+#define ADSP_VDRTCTL0_D3SRAMPGD_LPT BIT(2)
+#define ADSP_VDRTCTL0_D3SRAMPGD_WPT BIT(1)
+#define ADSP_PCI_VDRTCTL1 0xa4
+#define ADSP_PCI_VDRTCTL2 0xa8
+#define ADSP_VDRTCTL2_VALUE 0x00000fff
+
+#define ADSP_IOBP_VDLDAT1 0xd7000624
+#define ADSP_VDLDAT1_VALUE 0x00040100
+#define ADSP_IOBP_VDLDAT2 0xd7000628
+#define ADSP_IOBP_ACPI_IRQ3 0xd9d8
+#define ADSP_IOBP_ACPI_IRQ3I 0xd8d9
+#define ADSP_IOBP_ACPI_IRQ4 0xdbda
+#define ADSP_IOBP_PMCTL 0xd70001e0
+#define ADSP_PMCTL_VALUE 0x3f
+#define ADSP_IOBP_PCICFGCTL 0xd7000500
+#define ADSP_PCICFGCTL_PCICD BIT(0)
+#define ADSP_PCICFGCTL_ACPIIE BIT(1)
+#define ADSP_PCICFGCTL_SPCBAD BIT(7)
+
+#endif /* __ASM_ARCH_BROADWELL_ADSP_H */
diff --git a/arch/x86/include/asm/arch-broadwell/pch.h b/arch/x86/include/asm/arch-broadwell/pch.h
index 23ccd68484..23153a040f 100644
--- a/arch/x86/include/asm/arch-broadwell/pch.h
+++ b/arch/x86/include/asm/arch-broadwell/pch.h
@@ -109,6 +109,9 @@
#define SATA_DTLE_EDGE_SHIFT 16
/* Power Management */
+#define PCH_PCS 0x84
+#define PCH_PCS_PS_D3HOT 3
+
#define GEN_PMCON_1 0xa0
#define SMI_LOCK (1 << 4)
#define GEN_PMCON_2 0xa2
diff --git a/arch/x86/include/asm/arch-broadwell/rcb.h b/arch/x86/include/asm/arch-broadwell/rcb.h
index e7340c1e5a..b7ce8746c8 100644
--- a/arch/x86/include/asm/arch-broadwell/rcb.h
+++ b/arch/x86/include/asm/arch-broadwell/rcb.h
@@ -6,6 +6,8 @@
#ifndef __asm_arch_rcba_h
#define __asm_arch_rcba_h
+#define ACPIIRQEN 0x31e0 /* 32bit */
+
#define PMSYNC_CONFIG 0x33c4 /* 32bit */
#define PMSYNC_CONFIG2 0x33cc /* 32bit */
diff --git a/arch/x86/include/asm/arch-broadwell/serialio.h b/arch/x86/include/asm/arch-broadwell/serialio.h
new file mode 100644
index 0000000000..5e98eaf53f
--- /dev/null
+++ b/arch/x86/include/asm/arch-broadwell/serialio.h
@@ -0,0 +1,82 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Serial IO defintiions (taken from coreboot file of same name)
+ *
+ * Copyright 2019 Google LLC
+ */
+
+#ifndef __ARCH_BROADWELL_SERIALIO_H_
+#define __ARCH_BROADWELL_SERIALIO_H_
+
+/* Serial IO IOBP Registers */
+#define SIO_IOBP_PORTCTRL0 0xcb000000 /* SDIO D23:F0 */
+#define SIO_IOBP_PORTCTRL0_ACPI_IRQ_EN BIT(5)
+#define SIO_IOBP_PORTCTRL0_PCI_CONF_DIS BIT(4)
+#define SIO_IOBP_PORTCTRL1 0xcb000014 /* SDIO D23:F0 */
+#define SIO_IOBP_PORTCTRL1_SNOOP_SELECT(x) (((x) & 3) << 13)
+#define SIO_IOBP_GPIODF 0xcb000154
+#define SIO_IOBP_GPIODF_SDIO_IDLE_DET_EN BIT(4)
+#define SIO_IOBP_GPIODF_DMA_IDLE_DET_EN BIT(3)
+#define SIO_IOBP_GPIODF_UART_IDLE_DET_EN BIT(2)
+#define SIO_IOBP_GPIODF_I2C_IDLE_DET_EN BIT(1)
+#define SIO_IOBP_GPIODF_SPI_IDLE_DET_EN BIT(0)
+#define SIO_IOBP_GPIODF_UART0_BYTE_ACCESS BIT(10)
+#define SIO_IOBP_GPIODF_UART1_BYTE_ACCESS BIT(11)
+#define SIO_IOBP_PORTCTRL2 0xcb000240 /* DMA D21:F0 */
+#define SIO_IOBP_PORTCTRL3 0xcb000248 /* I2C0 D21:F1 */
+#define SIO_IOBP_PORTCTRL4 0xcb000250 /* I2C1 D21:F2 */
+#define SIO_IOBP_PORTCTRL5 0xcb000258 /* SPI0 D21:F3 */
+#define SIO_IOBP_PORTCTRL6 0xcb000260 /* SPI1 D21:F4 */
+#define SIO_IOBP_PORTCTRL7 0xcb000268 /* UART0 D21:F5 */
+#define SIO_IOBP_PORTCTRL8 0xcb000270 /* UART1 D21:F6 */
+#define SIO_IOBP_PORTCTRLX(x) (0xcb000240 + ((x) * 8))
+/* PORTCTRL 2-8 have the same layout */
+#define SIO_IOBP_PORTCTRL_ACPI_IRQ_EN BIT(21)
+#define SIO_IOBP_PORTCTRL_PCI_CONF_DIS BIT(20)
+#define SIO_IOBP_PORTCTRL_SNOOP_SELECT(x) (((x) & 3) << 18)
+#define SIO_IOBP_PORTCTRL_INT_PIN(x) (((x) & 0xf) << 2)
+#define SIO_IOBP_PORTCTRL_PM_CAP_PRSNT BIT(1)
+#define SIO_IOBP_FUNCDIS0 0xce00aa07 /* DMA D21:F0 */
+#define SIO_IOBP_FUNCDIS1 0xce00aa47 /* I2C0 D21:F1 */
+#define SIO_IOBP_FUNCDIS2 0xce00aa87 /* I2C1 D21:F2 */
+#define SIO_IOBP_FUNCDIS3 0xce00aac7 /* SPI0 D21:F3 */
+#define SIO_IOBP_FUNCDIS4 0xce00ab07 /* SPI1 D21:F4 */
+#define SIO_IOBP_FUNCDIS5 0xce00ab47 /* UART0 D21:F5 */
+#define SIO_IOBP_FUNCDIS6 0xce00ab87 /* UART1 D21:F6 */
+#define SIO_IOBP_FUNCDIS7 0xce00ae07 /* SDIO D23:F0 */
+#define SIO_IOBP_FUNCDIS_DIS BIT(8)
+
+/* Serial IO Devices */
+#define SIO_ID_SDMA 0 /* D21:F0 */
+#define SIO_ID_I2C0 1 /* D21:F1 */
+#define SIO_ID_I2C1 2 /* D21:F2 */
+#define SIO_ID_SPI0 3 /* D21:F3 */
+#define SIO_ID_SPI1 4 /* D21:F4 */
+#define SIO_ID_UART0 5 /* D21:F5 */
+#define SIO_ID_UART1 6 /* D21:F6 */
+#define SIO_ID_SDIO 7 /* D23:F0 */
+
+#define SIO_REG_PPR_CLOCK 0x800
+#define SIO_REG_PPR_CLOCK_EN BIT(0)
+#define SIO_REG_PPR_CLOCK_UPDATE BIT(31)
+#define SIO_REG_PPR_CLOCK_M_DIV 0x25a
+#define SIO_REG_PPR_CLOCK_N_DIV 0x7fff
+#define SIO_REG_PPR_RST 0x804
+#define SIO_REG_PPR_RST_ASSERT 0x3
+#define SIO_REG_PPR_GEN 0x808
+#define SIO_REG_PPR_GEN_LTR_MODE_MASK BIT(2)
+#define SIO_REG_PPR_GEN_VOLTAGE_MASK BIT(3)
+#define SIO_REG_PPR_GEN_VOLTAGE(x) ((x & 1) << 3)
+#define SIO_REG_AUTO_LTR 0x814
+
+#define SIO_REG_SDIO_PPR_GEN 0x1008
+#define SIO_REG_SDIO_PPR_SW_LTR 0x1010
+#define SIO_REG_SDIO_PPR_CMD12 0x3c
+#define SIO_REG_SDIO_PPR_CMD12_B30 BIT(30)
+
+#define SIO_PIN_INTA 1 /* IRQ5 in ACPI mode */
+#define SIO_PIN_INTB 2 /* IRQ6 in ACPI mode */
+#define SIO_PIN_INTC 3 /* IRQ7 in ACPI mode */
+#define SIO_PIN_INTD 4 /* IRQ13 in ACPI mode */
+
+#endif /* __ARCH_BROADWELL_SERIALIO_H_ */
diff --git a/arch/x86/include/asm/arch-ivybridge/sandybridge.h b/arch/x86/include/asm/arch-ivybridge/sandybridge.h
index a96c951c85..a3a507f2b3 100644
--- a/arch/x86/include/asm/arch-ivybridge/sandybridge.h
+++ b/arch/x86/include/asm/arch-ivybridge/sandybridge.h
@@ -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
diff --git a/arch/x86/include/asm/i8254.h b/arch/x86/include/asm/i8254.h
index 65c97614d3..d769daf85d 100644
--- a/arch/x86/include/asm/i8254.h
+++ b/arch/x86/include/asm/i8254.h
@@ -35,4 +35,22 @@
/* The clock frequency of the i8253/i8254 PIT */
#define PIT_TICK_RATE 1193182
+/**
+ * i8254_enable_beep() - Start a beep using the PCAT timer
+ *
+ * This starts beeping using the legacy i8254 timer. The beep may be silenced
+ * after a delay with i8254_disable_beep().
+ *
+ * @frequency_hz: Frequency of beep in Hz
+ * @return 0 if OK, -EINVAL if frequency_hz is 0
+ */
+int i8254_enable_beep(uint frequency_hz);
+
+/**
+ * i8254_disable_beep() - Disable the bepper
+ *
+ * This stops any existing beep
+ */
+void i8254_disable_beep(void);
+
#endif /* _ASMI386_I8954_H_ */
diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
index 81def0afd3..cf6c33cbe3 100644
--- a/arch/x86/include/asm/io.h
+++ b/arch/x86/include/asm/io.h
@@ -57,19 +57,19 @@
* memory location directly.
*/
-#define readb(addr) (*(volatile unsigned char *) (addr))
-#define readw(addr) (*(volatile unsigned short *) (addr))
-#define readl(addr) (*(volatile unsigned int *) (addr))
-#define readq(addr) (*(volatile unsigned long long *) (addr))
+#define readb(addr) (*(volatile u8 *)(uintptr_t)(addr))
+#define readw(addr) (*(volatile u16 *)(uintptr_t)(addr))
+#define readl(addr) (*(volatile u32 *)(uintptr_t)(addr))
+#define readq(addr) (*(volatile u64 *)(uintptr_t)(addr))
#define __raw_readb readb
#define __raw_readw readw
#define __raw_readl readl
#define __raw_readq readq
-#define writeb(b,addr) (*(volatile unsigned char *) (addr) = (b))
-#define writew(b,addr) (*(volatile unsigned short *) (addr) = (b))
-#define writel(b,addr) (*(volatile unsigned int *) (addr) = (b))
-#define writeq(b,addr) (*(volatile unsigned long long *) (addr) = (b))
+#define writeb(b, addr) (*(volatile u8 *)(addr) = (b))
+#define writew(b, addr) (*(volatile u16 *)(addr) = (b))
+#define writel(b, addr) (*(volatile u32 *)(addr) = (b))
+#define writeq(b, addr) (*(volatile u64 *)(addr) = (b))
#define __raw_writeb writeb
#define __raw_writew writew
#define __raw_writel writel
diff --git a/arch/x86/lib/i8254.c b/arch/x86/lib/i8254.c
index 1f1012488c..d0227954b1 100644
--- a/arch/x86/lib/i8254.c
+++ b/arch/x86/lib/i8254.c
@@ -8,8 +8,20 @@
#include <asm/io.h>
#include <asm/i8254.h>
-#define TIMER1_VALUE 18 /* 15.6us */
-#define TIMER2_VALUE 0x0a8e /* 440Hz */
+#define TIMER1_VALUE 18 /* 15.6us */
+#define BEEP_FREQUENCY_HZ 440
+#define SYSCTL_PORTB 0x61
+#define PORTB_BEEP_ENABLE 0x3
+
+static void i8254_set_beep_freq(uint frequency_hz)
+{
+ uint countdown;
+
+ countdown = PIT_TICK_RATE / frequency_hz;
+
+ outb(countdown & 0xff, PIT_BASE + PIT_T2);
+ outb((countdown >> 8) & 0xff, PIT_BASE + PIT_T2);
+}
int i8254_init(void)
{
@@ -29,8 +41,23 @@ int i8254_init(void)
*/
outb(PIT_CMD_CTR2 | PIT_CMD_BOTH | PIT_CMD_MODE3,
PIT_BASE + PIT_COMMAND);
- outb(TIMER2_VALUE & 0xff, PIT_BASE + PIT_T2);
- outb(TIMER2_VALUE >> 8, PIT_BASE + PIT_T2);
+ i8254_set_beep_freq(BEEP_FREQUENCY_HZ);
+
+ return 0;
+}
+
+int i8254_enable_beep(uint frequency_hz)
+{
+ if (!frequency_hz)
+ return -EINVAL;
+
+ i8254_set_beep_freq(frequency_hz);
+ setio_8(SYSCTL_PORTB, PORTB_BEEP_ENABLE);
return 0;
}
+
+void i8254_disable_beep(void)
+{
+ clrio_8(SYSCTL_PORTB, PORTB_BEEP_ENABLE);
+}