summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/soc/intel/skylake/Kconfig5
-rw-r--r--src/soc/intel/skylake/Makefile.inc4
-rw-r--r--src/soc/intel/skylake/bootblock/bootblock.c2
-rw-r--r--src/soc/intel/skylake/chip.h4
-rw-r--r--src/soc/intel/skylake/gspi.c70
-rw-r--r--src/soc/intel/skylake/include/soc/iomap.h1
-rw-r--r--src/soc/intel/skylake/include/soc/pci_devs.h10
-rw-r--r--src/soc/intel/skylake/spi.c28
8 files changed, 101 insertions, 23 deletions
diff --git a/src/soc/intel/skylake/Kconfig b/src/soc/intel/skylake/Kconfig
index df8ae2bd2d..82e5d55555 100644
--- a/src/soc/intel/skylake/Kconfig
+++ b/src/soc/intel/skylake/Kconfig
@@ -50,6 +50,7 @@ config CPU_SPECIFIC_OPTIONS
select SOC_INTEL_COMMON
select SOC_INTEL_COMMON_ACPI_WAKE_SOURCE
select SOC_INTEL_COMMON_BLOCK
+ select SOC_INTEL_COMMON_BLOCK_GSPI
select SOC_INTEL_COMMON_BLOCK_SA
select SOC_INTEL_COMMON_BLOCK_XHCI
select SOC_INTEL_COMMON_LPSS_I2C
@@ -300,4 +301,8 @@ config SOC_INTEL_COMMON_LPSS_CLOCK_MHZ
int
default 120
+config SOC_INTEL_COMMON_BLOCK_GSPI_MAX
+ int
+ default 2
+
endif
diff --git a/src/soc/intel/skylake/Makefile.inc b/src/soc/intel/skylake/Makefile.inc
index f9c267e435..cb8eb89514 100644
--- a/src/soc/intel/skylake/Makefile.inc
+++ b/src/soc/intel/skylake/Makefile.inc
@@ -19,6 +19,7 @@ bootblock-y += flash_controller.c
bootblock-$(CONFIG_UART_DEBUG) += bootblock/uart.c
bootblock-$(CONFIG_UART_DEBUG) += uart_debug.c
bootblock-y += gpio.c
+bootblock-y += gspi.c
bootblock-y += monotonic_timer.c
bootblock-y += pch.c
bootblock-y += pcr.c
@@ -27,6 +28,7 @@ bootblock-y += spi.c
bootblock-y += tsc_freq.c
verstage-y += flash_controller.c
+verstage-y += gspi.c
verstage-y += monotonic_timer.c
verstage-y += pch.c
verstage-$(CONFIG_UART_DEBUG) += uart_debug.c
@@ -37,6 +39,7 @@ verstage-y += tsc_freq.c
romstage-y += flash_controller.c
romstage-y += gpio.c
+romstage-y += gspi.c
romstage-y += bootblock/i2c.c
romstage-y += memmap.c
romstage-y += monotonic_timer.c
@@ -62,6 +65,7 @@ ramstage-y += elog.c
ramstage-y += finalize.c
ramstage-y += flash_controller.c
ramstage-y += gpio.c
+ramstage-y += gspi.c
ramstage-y += i2c.c
ramstage-y += igd.c
ramstage-y += irq.c
diff --git a/src/soc/intel/skylake/bootblock/bootblock.c b/src/soc/intel/skylake/bootblock/bootblock.c
index c11d3d2152..f386f96360 100644
--- a/src/soc/intel/skylake/bootblock/bootblock.c
+++ b/src/soc/intel/skylake/bootblock/bootblock.c
@@ -14,6 +14,7 @@
*/
#include <bootblock_common.h>
+#include <intelblocks/gspi.h>
#include <soc/bootblock.h>
asmlinkage void bootblock_c_entry(uint64_t base_timestamp)
@@ -48,4 +49,5 @@ void bootblock_soc_init(void)
set_max_freq();
pch_early_init();
i2c_early_init();
+ gspi_early_bar_init();
}
diff --git a/src/soc/intel/skylake/chip.h b/src/soc/intel/skylake/chip.h
index 85857d8200..ce5fe22b98 100644
--- a/src/soc/intel/skylake/chip.h
+++ b/src/soc/intel/skylake/chip.h
@@ -21,6 +21,7 @@
#include <arch/acpi_device.h>
#include <device/i2c.h>
+#include <intelblocks/gspi.h>
#include <stdint.h>
#include <soc/gpio_defs.h>
#include <soc/gpe.h>
@@ -208,6 +209,9 @@ struct soc_intel_skylake_config {
enum skylake_i2c_voltage i2c_voltage[SKYLAKE_I2C_DEV_MAX];
struct lpss_i2c_bus_config i2c[SKYLAKE_I2C_DEV_MAX];
+ /* GSPI */
+ struct gspi_cfg gspi[CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX];
+
/* Camera */
u8 Cio2Enable;
u8 SaImguEnable;
diff --git a/src/soc/intel/skylake/gspi.c b/src/soc/intel/skylake/gspi.c
new file mode 100644
index 0000000000..e04ae93b52
--- /dev/null
+++ b/src/soc/intel/skylake/gspi.c
@@ -0,0 +1,70 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2017 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <assert.h>
+#include <device/device.h>
+#include <intelblocks/gspi.h>
+#include <soc/iomap.h>
+#include "chip.h"
+
+const struct gspi_cfg *gspi_get_soc_cfg(void)
+{
+ ROMSTAGE_CONST struct soc_intel_skylake_config *config;
+ int devfn = SA_DEVFN_ROOT;
+ ROMSTAGE_CONST struct device *dev = dev_find_slot(0, devfn);
+
+ if (!dev || !dev->chip_info) {
+ printk(BIOS_ERR, "%s: Could not find SoC devicetree config!\n",
+ __func__);
+ return NULL;
+ }
+
+ config = dev->chip_info;
+
+ return &config->gspi[0];
+}
+
+uintptr_t gspi_get_soc_early_base(void)
+{
+ return EARLY_GSPI_BASE_ADDRESS;
+}
+
+/*
+ * SPI Bus 0 is Fast SPI and GSPI starts from SPI bus # 1 onwards. Thus, adjust
+ * the bus # accordingly when referring to SPI / GSPI bus numbers.
+ */
+#define GSPI_TO_SPI_BUS(x) (x + 1)
+#define SPI_TO_GSPI_BUS(x) (x - 1)
+
+int gspi_soc_spi_to_gspi_bus(unsigned int spi_bus, unsigned int *gspi_bus)
+{
+ if (spi_bus == 0)
+ return -1;
+
+ *gspi_bus = SPI_TO_GSPI_BUS(spi_bus);
+ if (*gspi_bus >= CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX)
+ return -1;
+
+ return 0;
+}
+
+int gspi_soc_bus_to_devfn(unsigned int gspi_bus)
+{
+ if (gspi_bus >= CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX)
+ return -1;
+
+ return spi_bus_to_devfn(GSPI_TO_SPI_BUS(gspi_bus));
+}
diff --git a/src/soc/intel/skylake/include/soc/iomap.h b/src/soc/intel/skylake/include/soc/iomap.h
index a6f7287f3a..e2662cc7c0 100644
--- a/src/soc/intel/skylake/include/soc/iomap.h
+++ b/src/soc/intel/skylake/include/soc/iomap.h
@@ -53,6 +53,7 @@
#define PCH_PWRM_BASE_SIZE 0x10000
#define SPI_BASE_ADDRESS 0xfe010000
+#define EARLY_GSPI_BASE_ADDRESS 0xfe011000
#define GPIO_BASE_SIZE 0x10000
diff --git a/src/soc/intel/skylake/include/soc/pci_devs.h b/src/soc/intel/skylake/include/soc/pci_devs.h
index 469d7e9992..13114f1f95 100644
--- a/src/soc/intel/skylake/include/soc/pci_devs.h
+++ b/src/soc/intel/skylake/include/soc/pci_devs.h
@@ -186,4 +186,14 @@ static inline int spi_devfn_to_bus(unsigned int devfn)
return -1;
}
+static inline int spi_bus_to_devfn(unsigned int bus)
+{
+ switch (bus) {
+ case 0: return PCH_DEVFN_SPI;
+ case 1: return PCH_DEVFN_GSPI0;
+ case 2: return PCH_DEVFN_GSPI1;
+ }
+ return -1;
+}
+
#endif
diff --git a/src/soc/intel/skylake/spi.c b/src/soc/intel/skylake/spi.c
index 4a2ae9d8b8..e11e13f763 100644
--- a/src/soc/intel/skylake/spi.c
+++ b/src/soc/intel/skylake/spi.c
@@ -20,6 +20,7 @@
#include <device/pci_def.h>
#include <device/pci_ids.h>
#include <device/spi.h>
+#include <intelblocks/gspi.h>
#include <soc/ramstage.h>
#include <spi-generic.h>
@@ -39,31 +40,12 @@ static const struct spi_ctrlr flash_spi_ctrlr = {
.setup = flash_spi_ctrlr_setup,
};
-static int gspi_ctrlr_get_config(const struct spi_slave *dev,
- struct spi_cfg *cfg)
-{
- if (dev->cs != 0) {
- printk(BIOS_ERR, "%s: Unsupported device "
- "bus=0x%x,cs=0x%x!\n", __func__, dev->bus, dev->cs);
- return -1;
- }
-
- cfg->clk_phase = SPI_CLOCK_PHASE_FIRST;
- cfg->clk_polarity = SPI_POLARITY_LOW;
- cfg->cs_polarity = SPI_POLARITY_LOW;
- cfg->wire_mode = SPI_4_WIRE_MODE;
- cfg->data_bit_length = 8;
-
- return 0;
-}
-
-static const struct spi_ctrlr gspi_ctrlr = {
- .get_config = gspi_ctrlr_get_config,
-};
-
const struct spi_ctrlr_buses spi_ctrlr_bus_map[] = {
{ .ctrlr = &flash_spi_ctrlr, .bus_start = 0, .bus_end = 0 },
- { .ctrlr = &gspi_ctrlr, .bus_start = 1, .bus_end = 2 },
+#if !ENV_SMM
+ { .ctrlr = &gspi_ctrlr, .bus_start = 1,
+ .bus_end = 1 + (CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX - 1)},
+#endif
};
const size_t spi_ctrlr_bus_map_count = ARRAY_SIZE(spi_ctrlr_bus_map);