diff options
Diffstat (limited to 'src/soc')
-rw-r--r-- | src/soc/intel/skylake/Makefile.inc | 1 | ||||
-rw-r--r-- | src/soc/intel/skylake/chip.h | 18 | ||||
-rw-r--r-- | src/soc/intel/skylake/sd.c | 87 |
3 files changed, 106 insertions, 0 deletions
diff --git a/src/soc/intel/skylake/Makefile.inc b/src/soc/intel/skylake/Makefile.inc index e22214f343..ea1895d9c6 100644 --- a/src/soc/intel/skylake/Makefile.inc +++ b/src/soc/intel/skylake/Makefile.inc @@ -53,6 +53,7 @@ ramstage-y += pei_data.c ramstage-y += pmc.c ramstage-y += pmutil.c ramstage-y += ramstage.c +ramstage-y += sd.c ramstage-y += smbus.c ramstage-y += smbus_common.c ramstage-y += smi.c diff --git a/src/soc/intel/skylake/chip.h b/src/soc/intel/skylake/chip.h index 891047971c..2db84b7f25 100644 --- a/src/soc/intel/skylake/chip.h +++ b/src/soc/intel/skylake/chip.h @@ -19,6 +19,7 @@ #ifndef _SOC_CHIP_H_ #define _SOC_CHIP_H_ +#include <arch/acpi_device.h> #include <stdint.h> #include <soc/gpio_defs.h> #include <soc/gpe.h> @@ -339,6 +340,23 @@ struct soc_intel_skylake_config { u8 SendVrMbxCmd; /* Statically clock gate 8254 PIT. */ u8 clock_gate_8254; + + /* + * Use SD card detect GPIO with default config: + * - Edge triggered + * - No internal pull + * - Active both (high + low) + * - Can wake device from D3 + * - 100ms debounce timeout + * + * GpioInt (Edge, ActiveBoth, SharedAndWake, PullNone, 10000, + * "\\_SB.PCI0.GPIO", 0, ResourceConsumer) + * { sdcard_cd_gpio_default } + */ + unsigned sdcard_cd_gpio_default; + + /* Use custom SD card detect GPIO configuration */ + struct acpi_gpio sdcard_cd_gpio; }; typedef struct soc_intel_skylake_config config_t; diff --git a/src/soc/intel/skylake/sd.c b/src/soc/intel/skylake/sd.c new file mode 100644 index 0000000000..80adb9c467 --- /dev/null +++ b/src/soc/intel/skylake/sd.c @@ -0,0 +1,87 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2016 Google Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <arch/acpi_device.h> +#include <arch/acpigen.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <gpio.h> +#include <soc/ramstage.h> +#include "chip.h" + +#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES) +static void sd_fill_ssdt(struct device *dev) +{ + config_t *config = dev->chip_info; + const char *path; + struct acpi_gpio default_gpio = { + .type = ACPI_GPIO_TYPE_INTERRUPT, + .pull = ACPI_GPIO_PULL_NONE, + .irq.mode = IRQ_EDGE_TRIGGERED, + .irq.polarity = IRQ_ACTIVE_BOTH, + .irq.shared = IRQ_SHARED, + .irq.wake = IRQ_WAKE, + .interrupt_debounce_timeout = 10000, /* 100ms */ + .pin_count = 1, + .pins = { config->sdcard_cd_gpio_default } + }; + + if (!dev->enabled) + return; + + /* Nothing to write if GPIO is not set in devicetree */ + if (!config->sdcard_cd_gpio_default && !config->sdcard_cd_gpio.pins[0]) + return; + + /* Use device path as the Scope for the SSDT */ + path = acpi_device_path(dev); + if (!path) + return; + acpigen_write_scope(path); + acpigen_write_name("_CRS"); + + /* Write GpioInt() as default (if set) or custom from devicetree */ + acpigen_write_resourcetemplate_header(); + if (config->sdcard_cd_gpio_default) + acpi_device_write_gpio(&default_gpio); + else + acpi_device_write_gpio(&config->sdcard_cd_gpio); + acpigen_write_resourcetemplate_footer(); + + /* Bind the cd-gpio name to the GpioInt() resource */ + acpi_dp_write_header(); + acpi_dp_write_gpio("cd-gpio", path, 0, 0, 1); + acpi_dp_write_footer(); + + acpigen_pop_len(); +} +#endif + +static struct device_operations dev_ops = { + .read_resources = &pci_dev_read_resources, + .set_resources = &pci_dev_set_resources, + .enable_resources = &pci_dev_enable_resources, + .ops_pci = &soc_pci_ops, +#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES) + .acpi_fill_ssdt_generator = &sd_fill_ssdt, +#endif +}; + +static const struct pci_driver pch_sd __pci_driver = { + .ops = &dev_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = 0x9d2d +}; |