diff options
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/cpu/broadwell/Makefile | 1 | ||||
-rw-r--r-- | arch/x86/cpu/broadwell/adsp.c | 156 | ||||
-rw-r--r-- | arch/x86/cpu/broadwell/pch.c | 110 | ||||
-rw-r--r-- | arch/x86/cpu/broadwell/pinctrl_broadwell.c | 3 | ||||
-rw-r--r-- | arch/x86/cpu/ivybridge/Kconfig | 1 | ||||
-rw-r--r-- | arch/x86/cpu/ivybridge/bd82x6x.c | 27 | ||||
-rw-r--r-- | arch/x86/cpu/ivybridge/northbridge.c | 32 | ||||
-rw-r--r-- | arch/x86/dts/chromebook_link.dts | 96 | ||||
-rw-r--r-- | arch/x86/dts/chromebook_samus.dts | 49 | ||||
-rw-r--r-- | arch/x86/include/asm/arch-broadwell/adsp.h | 46 | ||||
-rw-r--r-- | arch/x86/include/asm/arch-broadwell/pch.h | 3 | ||||
-rw-r--r-- | arch/x86/include/asm/arch-broadwell/rcb.h | 2 | ||||
-rw-r--r-- | arch/x86/include/asm/arch-broadwell/serialio.h | 82 | ||||
-rw-r--r-- | arch/x86/include/asm/arch-ivybridge/sandybridge.h | 3 | ||||
-rw-r--r-- | arch/x86/include/asm/i8254.h | 18 | ||||
-rw-r--r-- | arch/x86/include/asm/io.h | 16 | ||||
-rw-r--r-- | arch/x86/lib/i8254.c | 35 |
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); +} |