aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFurquan Shaikh <furquan@chromium.org>2017-03-31 14:02:47 -0700
committerFurquan Shaikh <furquan@google.com>2017-04-06 00:45:36 +0200
commit05a6f29d32c246569b7a0561d35ccbf49eec1fb8 (patch)
treea0347e4edb13a2f3bebcbbf8745a4af0a5f18969
parent108f87262bf47ce3549fa0c5ed16a40fe916656f (diff)
soc/intel/skylake: Add support for GSPI controller
Sky Lake PCH contains two GSPI controllers. Using the common GSPI controller driver implementation for Intel PCH, add support for GSPI controller buses on Sky Lake/Kaby Lake. BUG=b:35583330 Change-Id: I29b1d4d5a6ee4093f2596065ac375c06f17d33ac Signed-off-by: Furquan Shaikh <furquan@chromium.org> Reviewed-on: https://review.coreboot.org/19099 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin <adurbin@chromium.org>
-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);