All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v7 04/17] x86: apl: Add hostbridge driver
@ 2019-12-09  0:40 Simon Glass
  2019-12-09  0:40 ` [PATCH v7 05/17] x86: apl: Add ITSS driver Simon Glass
                   ` (13 more replies)
  0 siblings, 14 replies; 29+ messages in thread
From: Simon Glass @ 2019-12-09  0:40 UTC (permalink / raw)
  To: u-boot

This driver models the hostbridge as a northbridge. It simply sets up the
graphics BAR. It supports of-platdata.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

Changes in v7: None
Changes in v6:
- Fix comments for struct apl_hostbridge_platdata

Changes in v5: None
Changes in v4:
- Avoid needing to know internals of pinctrl in this driver
- Move code to pinctrl driver
- Switch over to use pinctrl for pad init/config

Changes in v3:
- Move pad programming into the hostbridge to reduce TPL device-tree size
- Use pci_get_devfn()

Changes in v2: None

 arch/x86/cpu/apollolake/Makefile     |   1 +
 arch/x86/cpu/apollolake/hostbridge.c | 179 +++++++++++++++++++++++++++
 2 files changed, 180 insertions(+)
 create mode 100644 arch/x86/cpu/apollolake/hostbridge.c

diff --git a/arch/x86/cpu/apollolake/Makefile b/arch/x86/cpu/apollolake/Makefile
index 3a8c2f66a3..4d3c08f84e 100644
--- a/arch/x86/cpu/apollolake/Makefile
+++ b/arch/x86/cpu/apollolake/Makefile
@@ -4,5 +4,6 @@
 
 obj-$(CONFIG_SPL_BUILD) += systemagent.o
 
+obj-y += hostbridge.o
 obj-y += pmc.o
 obj-y += uart.o
diff --git a/arch/x86/cpu/apollolake/hostbridge.c b/arch/x86/cpu/apollolake/hostbridge.c
new file mode 100644
index 0000000000..793853d5b5
--- /dev/null
+++ b/arch/x86/cpu/apollolake/hostbridge.c
@@ -0,0 +1,179 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 Google LLC
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dt-structs.h>
+#include <spl.h>
+#include <asm/intel_pinctrl.h>
+#include <asm/intel_regs.h>
+#include <asm/pci.h>
+#include <asm/arch/systemagent.h>
+
+/**
+ * struct apl_hostbridge_platdata - platform data for hostbridge
+ *
+ * @dtplat: Platform data for of-platdata
+ * @early_pads: Early pad data to set up, each (pad, cfg0, cfg1)
+ * @early_pads_count: Number of pads to process
+ * @pciex_region_size: BAR length in bytes
+ * @bdf: Bus/device/function of hostbridge
+ */
+struct apl_hostbridge_platdata {
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+	struct dtd_intel_apl_hostbridge dtplat;
+#endif
+	u32 *early_pads;
+	int early_pads_count;
+	uint pciex_region_size;
+	pci_dev_t bdf;
+};
+
+enum {
+	PCIEXBAR		= 0x60,
+	PCIEXBAR_LENGTH_256MB	= 0,
+	PCIEXBAR_LENGTH_128MB,
+	PCIEXBAR_LENGTH_64MB,
+
+	PCIEXBAR_PCIEXBAREN	= 1 << 0,
+
+	TSEG			= 0xb8,  /* TSEG base */
+};
+
+static int apl_hostbridge_early_init_pinctrl(struct udevice *dev)
+{
+	struct apl_hostbridge_platdata *plat = dev_get_platdata(dev);
+	struct udevice *pinctrl;
+	int ret;
+
+	ret = uclass_first_device_err(UCLASS_PINCTRL, &pinctrl);
+	if (ret)
+		return log_msg_ret("no hostbridge pinctrl", ret);
+
+	return pinctrl_config_pads(pinctrl, plat->early_pads,
+				   plat->early_pads_count);
+}
+
+static int apl_hostbridge_early_init(struct udevice *dev)
+{
+	struct apl_hostbridge_platdata *plat = dev_get_platdata(dev);
+	u32 region_size;
+	ulong base;
+	u32 reg;
+	int ret;
+
+	/* Set up the MCHBAR */
+	pci_x86_read_config(plat->bdf, MCHBAR, &base, PCI_SIZE_32);
+	base = MCH_BASE_ADDRESS;
+	pci_x86_write_config(plat->bdf, MCHBAR, base | 1, PCI_SIZE_32);
+
+	/*
+	 * The PCIEXBAR is assumed to live in the memory mapped IO space under
+	 * 4GiB
+	 */
+	pci_x86_write_config(plat->bdf, PCIEXBAR + 4, 0, PCI_SIZE_32);
+
+	switch (plat->pciex_region_size >> 20) {
+	default:
+	case 256:
+		region_size = PCIEXBAR_LENGTH_256MB;
+		break;
+	case 128:
+		region_size = PCIEXBAR_LENGTH_128MB;
+		break;
+	case 64:
+		region_size = PCIEXBAR_LENGTH_64MB;
+		break;
+	}
+
+	reg = CONFIG_MMCONF_BASE_ADDRESS | (region_size << 1)
+				| PCIEXBAR_PCIEXBAREN;
+	pci_x86_write_config(plat->bdf, PCIEXBAR, reg, PCI_SIZE_32);
+
+	/*
+	 * TSEG defines the base of SMM range. BIOS determines the base
+	 * of TSEG memory which must be at or below Graphics base of GTT
+	 * Stolen memory, hence its better to clear TSEG register early
+	 * to avoid power on default non-zero value (if any).
+	 */
+	pci_x86_write_config(plat->bdf, TSEG, 0, PCI_SIZE_32);
+
+	ret = apl_hostbridge_early_init_pinctrl(dev);
+	if (ret)
+		return log_msg_ret("pinctrl", ret);
+
+	return 0;
+}
+
+static int apl_hostbridge_ofdata_to_platdata(struct udevice *dev)
+{
+	struct apl_hostbridge_platdata *plat = dev_get_platdata(dev);
+	struct udevice *pinctrl;
+	int ret;
+
+	/*
+	 * The host bridge holds the early pad data needed to get through TPL.
+	 * This is a small amount of data, enough to fit in TPL, so we keep it
+	 * separate from the full pad data, stored in the fsp-s subnode. That
+	 * subnode is not present in TPL, to save space.
+	 */
+	ret = uclass_first_device_err(UCLASS_PINCTRL, &pinctrl);
+	if (ret)
+		return log_msg_ret("no hostbridge PINCTRL", ret);
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
+	int root;
+
+	/* Get length of PCI Express Region */
+	plat->pciex_region_size = dev_read_u32_default(dev, "pciex-region-size",
+						       256 << 20);
+
+	root = pci_get_devfn(dev);
+	if (root < 0)
+		return log_msg_ret("Cannot get host-bridge PCI address", root);
+	plat->bdf = root;
+
+	ret = pinctrl_read_pads(pinctrl, dev_ofnode(dev), "early-pads",
+				&plat->early_pads, &plat->early_pads_count);
+	if (ret)
+		return log_msg_ret("early-pads", ret);
+#else
+	struct dtd_intel_apl_hostbridge *dtplat = &plat->dtplat;
+	int size;
+
+	plat->pciex_region_size = dtplat->pciex_region_size;
+	plat->bdf = pci_ofplat_get_devfn(dtplat->reg[0]);
+
+	/* Assume that if everything is 0, it is empty */
+	plat->early_pads = dtplat->early_pads;
+	size = ARRAY_SIZE(dtplat->early_pads);
+	plat->early_pads_count = pinctrl_count_pads(pinctrl, plat->early_pads,
+						    size);
+
+#endif
+
+	return 0;
+}
+
+static int apl_hostbridge_probe(struct udevice *dev)
+{
+	if (spl_phase() == PHASE_TPL)
+		return apl_hostbridge_early_init(dev);
+
+	return 0;
+}
+
+static const struct udevice_id apl_hostbridge_ids[] = {
+	{ .compatible = "intel,apl-hostbridge" },
+	{ }
+};
+
+U_BOOT_DRIVER(apl_hostbridge_drv) = {
+	.name		= "intel_apl_hostbridge",
+	.id		= UCLASS_NORTHBRIDGE,
+	.of_match	= apl_hostbridge_ids,
+	.ofdata_to_platdata = apl_hostbridge_ofdata_to_platdata,
+	.probe		= apl_hostbridge_probe,
+	.platdata_auto_alloc_size = sizeof(struct apl_hostbridge_platdata),
+};
-- 
2.24.0.393.g34dc348eaf-goog

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v7 05/17] x86: apl: Add ITSS driver
  2019-12-09  0:40 [PATCH v7 04/17] x86: apl: Add hostbridge driver Simon Glass
@ 2019-12-09  0:40 ` Simon Glass
  2019-12-15  0:36   ` Bin Meng
  2019-12-09  0:40 ` [PATCH v7 06/17] x86: apl: Add LPC driver Simon Glass
                   ` (12 subsequent siblings)
  13 siblings, 1 reply; 29+ messages in thread
From: Simon Glass @ 2019-12-09  0:40 UTC (permalink / raw)
  To: u-boot

This driver models some sort of interrupt thingy but there are so many
abreviations that I cannot find out what it stands for. Possibly something
to do with interrupts.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4:
- Tidy up header guards

Changes in v3:
- Add snapshot/restore for IRQs
- Use the IRQ uclass instead of ITSS

Changes in v2: None

 arch/x86/cpu/apollolake/Makefile            |   1 +
 arch/x86/cpu/apollolake/itss.c              | 214 ++++++++++++++++++++
 arch/x86/include/asm/arch-apollolake/itss.h |  43 ++++
 3 files changed, 258 insertions(+)
 create mode 100644 arch/x86/cpu/apollolake/itss.c
 create mode 100644 arch/x86/include/asm/arch-apollolake/itss.h

diff --git a/arch/x86/cpu/apollolake/Makefile b/arch/x86/cpu/apollolake/Makefile
index 4d3c08f84e..2d78368150 100644
--- a/arch/x86/cpu/apollolake/Makefile
+++ b/arch/x86/cpu/apollolake/Makefile
@@ -5,5 +5,6 @@
 obj-$(CONFIG_SPL_BUILD) += systemagent.o
 
 obj-y += hostbridge.o
+obj-y += itss.o
 obj-y += pmc.o
 obj-y += uart.o
diff --git a/arch/x86/cpu/apollolake/itss.c b/arch/x86/cpu/apollolake/itss.c
new file mode 100644
index 0000000000..8789f8e6bb
--- /dev/null
+++ b/arch/x86/cpu/apollolake/itss.c
@@ -0,0 +1,214 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Something to do with Interrupts, but I don't know what ITSS stands for
+ *
+ * Copyright (C) 2017 Intel Corporation.
+ * Copyright (C) 2017 Siemens AG
+ * Copyright 2019 Google LLC
+ *
+ * Taken from coreboot itss.c
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dt-structs.h>
+#include <irq.h>
+#include <p2sb.h>
+#include <spl.h>
+#include <asm/arch/itss.h>
+
+struct apl_itss_platdata {
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+	/* Put this first since driver model will copy the data here */
+	struct dtd_intel_apl_itss dtplat;
+#endif
+};
+
+/* struct pmc_route - Routing for PMC to GPIO */
+struct pmc_route {
+	u32 pmc;
+	u32 gpio;
+};
+
+struct apl_itss_priv {
+	struct pmc_route *route;
+	uint route_count;
+	u32 irq_snapshot[NUM_IPC_REGS];
+};
+
+static int apl_set_polarity(struct udevice *dev, uint irq, bool active_low)
+{
+	u32 mask;
+	uint reg;
+
+	if (irq > ITSS_MAX_IRQ)
+		return -EINVAL;
+
+	reg = PCR_ITSS_IPC0_CONF + sizeof(u32) * (irq / IRQS_PER_IPC);
+	mask = 1 << (irq % IRQS_PER_IPC);
+
+	pcr_clrsetbits32(dev, reg, mask, active_low ? mask : 0);
+
+	return 0;
+}
+
+#ifndef CONFIG_TPL_BUILD
+static int apl_snapshot_polarities(struct udevice *dev)
+{
+	struct apl_itss_priv *priv = dev_get_priv(dev);
+	const int start = GPIO_IRQ_START;
+	const int end = GPIO_IRQ_END;
+	int reg_start;
+	int reg_end;
+	int i;
+
+	reg_start = start / IRQS_PER_IPC;
+	reg_end = (end + IRQS_PER_IPC - 1) / IRQS_PER_IPC;
+
+	for (i = reg_start; i < reg_end; i++) {
+		uint reg = PCR_ITSS_IPC0_CONF + sizeof(u32) * i;
+
+		priv->irq_snapshot[i] = pcr_read32(dev, reg);
+	}
+
+	return 0;
+}
+
+static void show_polarities(struct udevice *dev, const char *msg)
+{
+	int i;
+
+	log_info("ITSS IRQ Polarities %s:\n", msg);
+	for (i = 0; i < NUM_IPC_REGS; i++) {
+		uint reg = PCR_ITSS_IPC0_CONF + sizeof(u32) * i;
+
+		log_info("IPC%d: 0x%08x\n", i, pcr_read32(dev, reg));
+	}
+}
+
+static int apl_restore_polarities(struct udevice *dev)
+{
+	struct apl_itss_priv *priv = dev_get_priv(dev);
+	const int start = GPIO_IRQ_START;
+	const int end = GPIO_IRQ_END;
+	int reg_start;
+	int reg_end;
+	int i;
+
+	show_polarities(dev, "Before");
+
+	reg_start = start / IRQS_PER_IPC;
+	reg_end = (end + IRQS_PER_IPC - 1) / IRQS_PER_IPC;
+
+	for (i = reg_start; i < reg_end; i++) {
+		u32 mask;
+		u16 reg;
+		int irq_start;
+		int irq_end;
+
+		irq_start = i * IRQS_PER_IPC;
+		irq_end = min(irq_start + IRQS_PER_IPC - 1, ITSS_MAX_IRQ);
+
+		if (start > irq_end)
+			continue;
+		if (end < irq_start)
+			break;
+
+		/* Track bits within the bounds of of the register */
+		irq_start = max(start, irq_start) % IRQS_PER_IPC;
+		irq_end = min(end, irq_end) % IRQS_PER_IPC;
+
+		/* Create bitmask of the inclusive range of start and end */
+		mask = (((1U << irq_end) - 1) | (1U << irq_end));
+		mask &= ~((1U << irq_start) - 1);
+
+		reg = PCR_ITSS_IPC0_CONF + sizeof(u32) * i;
+		pcr_clrsetbits32(dev, reg, mask, mask & priv->irq_snapshot[i]);
+	}
+
+	show_polarities(dev, "After");
+
+	return 0;
+}
+#endif
+
+static int apl_route_pmc_gpio_gpe(struct udevice *dev, uint pmc_gpe_num)
+{
+	struct apl_itss_priv *priv = dev_get_priv(dev);
+	struct pmc_route *route;
+	int i;
+
+	for (i = 0, route = priv->route; i < priv->route_count; i++, route++) {
+		if (pmc_gpe_num == route->pmc)
+			return route->gpio;
+	}
+
+	return -ENOENT;
+}
+
+static int apl_itss_ofdata_to_platdata(struct udevice *dev)
+{
+	struct apl_itss_priv *priv = dev_get_priv(dev);
+	int ret;
+
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+	struct apl_itss_platdata *plat = dev_get_platdata(dev);
+	struct dtd_intel_apl_itss *dtplat = &plat->dtplat;
+
+	/*
+	 * It would be nice to do this in the bind() method, but with
+	 * of-platdata binding happens in the order that DM finds things in the
+	 * linker list (i.e. alphabetical order by driver name). So the GPIO
+	 * device may well be bound before its parent (p2sb), and this call
+	 * will fail if p2sb is not bound yet.
+	 *
+	 * TODO(sjg at chromium.org): Add a parent pointer to child devices in dtoc
+	 */
+	ret = p2sb_set_port_id(dev, dtplat->intel_p2sb_port_id);
+	if (ret)
+		return log_msg_ret("Could not set port id", ret);
+	priv->route = (struct pmc_route *)dtplat->intel_pmc_routes;
+	priv->route_count = ARRAY_SIZE(dtplat->intel_pmc_routes) /
+		 sizeof(struct pmc_route);
+#else
+	int size;
+
+	size = dev_read_size(dev, "intel,pmc-routes");
+	if (size < 0)
+		return size;
+	priv->route = malloc(size);
+	if (!priv->route)
+		return -ENOMEM;
+	ret = dev_read_u32_array(dev, "intel,pmc-routes", (u32 *)priv->route,
+				 size / sizeof(fdt32_t));
+	if (ret)
+		return log_msg_ret("Cannot read pmc-routes", ret);
+	priv->route_count = size / sizeof(struct pmc_route);
+#endif
+
+	return 0;
+}
+
+static const struct irq_ops apl_itss_ops = {
+	.route_pmc_gpio_gpe	= apl_route_pmc_gpio_gpe,
+	.set_polarity	= apl_set_polarity,
+#ifndef CONFIG_TPL_BUILD
+	.snapshot_polarities = apl_snapshot_polarities,
+	.restore_polarities = apl_restore_polarities,
+#endif
+};
+
+static const struct udevice_id apl_itss_ids[] = {
+	{ .compatible = "intel,apl-itss"},
+	{ }
+};
+
+U_BOOT_DRIVER(apl_itss_drv) = {
+	.name		= "intel_apl_itss",
+	.id		= UCLASS_IRQ,
+	.of_match	= apl_itss_ids,
+	.ops		= &apl_itss_ops,
+	.ofdata_to_platdata = apl_itss_ofdata_to_platdata,
+	.platdata_auto_alloc_size = sizeof(struct apl_itss_platdata),
+	.priv_auto_alloc_size = sizeof(struct apl_itss_priv),
+};
diff --git a/arch/x86/include/asm/arch-apollolake/itss.h b/arch/x86/include/asm/arch-apollolake/itss.h
new file mode 100644
index 0000000000..1e29503974
--- /dev/null
+++ b/arch/x86/include/asm/arch-apollolake/itss.h
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2017 Intel Corporation.
+ * Copyright 2019 Google LLC
+ *
+ * Modified from coreboot itss.h
+ */
+
+#ifndef _ASM_ARCH_ITSS_H
+#define _ASM_ARCH_ITSS_H
+
+#define GPIO_IRQ_START	50
+#define GPIO_IRQ_END	ITSS_MAX_IRQ
+
+#define ITSS_MAX_IRQ	119
+#define IRQS_PER_IPC	32
+#define NUM_IPC_REGS	((ITSS_MAX_IRQ + IRQS_PER_IPC - 1) / IRQS_PER_IPC)
+
+/* Max PXRC registers in ITSS */
+#define MAX_PXRC_CONFIG	(PCR_ITSS_PIRQH_ROUT - PCR_ITSS_PIRQA_ROUT + 1)
+
+/* PIRQA Routing Control Register */
+#define PCR_ITSS_PIRQA_ROUT	0x3100
+/* PIRQB Routing Control Register */
+#define PCR_ITSS_PIRQB_ROUT	0x3101
+/* PIRQC Routing Control Register */
+#define PCR_ITSS_PIRQC_ROUT	0x3102
+/* PIRQD Routing Control Register */
+#define PCR_ITSS_PIRQD_ROUT	0x3103
+/* PIRQE Routing Control Register */
+#define PCR_ITSS_PIRQE_ROUT	0x3104
+/* PIRQF Routing Control Register */
+#define PCR_ITSS_PIRQF_ROUT	0x3105
+/* PIRQG Routing Control Register */
+#define PCR_ITSS_PIRQG_ROUT	0x3106
+/* PIRQH Routing Control Register */
+#define PCR_ITSS_PIRQH_ROUT	0x3107
+/* ITSS Interrupt polarity control */
+#define PCR_ITSS_IPC0_CONF	0x3200
+/* ITSS Power reduction control */
+#define PCR_ITSS_ITSSPRC	0x3300
+
+#endif /* _ASM_ARCH_ITSS_H */
-- 
2.24.0.393.g34dc348eaf-goog

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v7 06/17] x86: apl: Add LPC driver
  2019-12-09  0:40 [PATCH v7 04/17] x86: apl: Add hostbridge driver Simon Glass
  2019-12-09  0:40 ` [PATCH v7 05/17] x86: apl: Add ITSS driver Simon Glass
@ 2019-12-09  0:40 ` Simon Glass
  2019-12-15  0:38   ` Bin Meng
  2019-12-09  0:40 ` [PATCH v7 07/17] x86: apl: Add PCH driver Simon Glass
                   ` (11 subsequent siblings)
  13 siblings, 1 reply; 29+ messages in thread
From: Simon Glass @ 2019-12-09  0:40 UTC (permalink / raw)
  To: u-boot

This driver the LPC and provides a few functions to set up LPC features.
These should probably use ioctls() or perhaps, better, have specific
uclass methods.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

Changes in v7: None
Changes in v6:
- Drop init of ComB since it is not used
- Drop lpc_configure_pads() and probe() function, add a comment about pads

Changes in v5: None
Changes in v4:
- Add comments for exported functions
- Tidy up header guards
- Use 'Apollo Lake'
- Use BIT() macro a bit more
- Use tabs instead of spaces

Changes in v3:
- Drop unused code in lpc_configure_pads()
- Fix value of LPC_BC_LE

Changes in v2: None

 arch/x86/cpu/apollolake/Makefile           |   1 +
 arch/x86/cpu/apollolake/lpc.c              | 122 +++++++++++++++++++++
 arch/x86/include/asm/arch-apollolake/lpc.h |  82 ++++++++++++++
 3 files changed, 205 insertions(+)
 create mode 100644 arch/x86/cpu/apollolake/lpc.c
 create mode 100644 arch/x86/include/asm/arch-apollolake/lpc.h

diff --git a/arch/x86/cpu/apollolake/Makefile b/arch/x86/cpu/apollolake/Makefile
index 2d78368150..31045a03c1 100644
--- a/arch/x86/cpu/apollolake/Makefile
+++ b/arch/x86/cpu/apollolake/Makefile
@@ -6,5 +6,6 @@ obj-$(CONFIG_SPL_BUILD) += systemagent.o
 
 obj-y += hostbridge.o
 obj-y += itss.o
+obj-y += lpc.o
 obj-y += pmc.o
 obj-y += uart.o
diff --git a/arch/x86/cpu/apollolake/lpc.c b/arch/x86/cpu/apollolake/lpc.c
new file mode 100644
index 0000000000..45b2144fc6
--- /dev/null
+++ b/arch/x86/cpu/apollolake/lpc.c
@@ -0,0 +1,122 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 Google LLC
+ *
+ * From coreboot Apollo Lake support lpc.c
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <spl.h>
+#include <asm/lpc_common.h>
+#include <asm/pci.h>
+#include <asm/arch/iomap.h>
+#include <asm/arch/lpc.h>
+#include <linux/log2.h>
+
+void lpc_enable_fixed_io_ranges(uint io_enables)
+{
+	pci_x86_clrset_config(PCH_DEV_LPC, LPC_IO_ENABLES, 0, io_enables,
+			      PCI_SIZE_16);
+}
+
+/*
+ * Find the first unused IO window.
+ * Returns -1 if not found, 0 for reg 0x84, 1 for reg 0x88 ...
+ */
+static int find_unused_pmio_window(void)
+{
+	int i;
+	ulong lgir;
+
+	for (i = 0; i < LPC_NUM_GENERIC_IO_RANGES; i++) {
+		pci_x86_read_config(PCH_DEV_LPC, LPC_GENERIC_IO_RANGE(i),
+				    &lgir, PCI_SIZE_32);
+
+		if (!(lgir & LPC_LGIR_EN))
+			return i;
+	}
+
+	return -1;
+}
+
+int lpc_open_pmio_window(uint base, uint size)
+{
+	int i, lgir_reg_num;
+	u32 lgir_reg_offset, lgir, window_size, alignment;
+	ulong bridged_size, bridge_base;
+	ulong reg;
+
+	log_debug("LPC: Trying to open IO window from %x size %x\n", base,
+		  size);
+
+	bridged_size = 0;
+	bridge_base = base;
+
+	while (bridged_size < size) {
+		/* Each IO range register can only open a 256-byte window */
+		window_size = min(size, (uint)LPC_LGIR_MAX_WINDOW_SIZE);
+
+		/* Window size must be a power of two for the AMASK to work */
+		alignment = 1UL << (order_base_2(window_size));
+		window_size = ALIGN(window_size, alignment);
+
+		/* Address[15:2] in LGIR[15:12] and Mask[7:2] in LGIR[23:18] */
+		lgir = (bridge_base & LPC_LGIR_ADDR_MASK) | LPC_LGIR_EN;
+		lgir |= ((window_size - 1) << 16) & LPC_LGIR_AMASK_MASK;
+
+		/* Skip programming if same range already programmed */
+		for (i = 0; i < LPC_NUM_GENERIC_IO_RANGES; i++) {
+			pci_x86_read_config(PCH_DEV_LPC,
+					    LPC_GENERIC_IO_RANGE(i), &reg,
+					    PCI_SIZE_32);
+			if (lgir == reg)
+				return -EALREADY;
+		}
+
+		lgir_reg_num = find_unused_pmio_window();
+		if (lgir_reg_num < 0) {
+			log_err("LPC: Cannot open IO window: %lx size %lx\n",
+				bridge_base, size - bridged_size);
+			log_err("No more IO windows\n");
+
+			return -ENOSPC;
+		}
+		lgir_reg_offset = LPC_GENERIC_IO_RANGE(lgir_reg_num);
+
+		pci_x86_write_config(PCH_DEV_LPC, lgir_reg_offset, lgir,
+				     PCI_SIZE_32);
+
+		log_debug("LPC: Opened IO window LGIR%d: base %lx size %x\n",
+			  lgir_reg_num, bridge_base, window_size);
+
+		bridged_size += window_size;
+		bridge_base += window_size;
+	}
+
+	return 0;
+}
+
+void lpc_io_setup_comm_a_b(void)
+{
+	/* ComA Range 3F8h-3FFh [2:0] */
+	u16 com_ranges = LPC_IOD_COMA_RANGE;
+	u16 com_enable = LPC_IOE_COMA_EN;
+
+	/* Setup I/O Decode Range Register for LPC */
+	pci_write_config16(PCH_DEV_LPC, LPC_IO_DECODE, com_ranges);
+	/* Enable ComA and ComB Port */
+	lpc_enable_fixed_io_ranges(com_enable);
+}
+
+static const struct udevice_id apl_lpc_ids[] = {
+	{ .compatible = "intel,apl-lpc" },
+	{ }
+};
+
+/* All pads are LPC already configured by the hostbridge, so no probing here */
+U_BOOT_DRIVER(apl_lpc_drv) = {
+	.name		= "intel_apl_lpc",
+	.id		= UCLASS_LPC,
+	.of_match	= apl_lpc_ids,
+};
diff --git a/arch/x86/include/asm/arch-apollolake/lpc.h b/arch/x86/include/asm/arch-apollolake/lpc.h
new file mode 100644
index 0000000000..5d2adad319
--- /dev/null
+++ b/arch/x86/include/asm/arch-apollolake/lpc.h
@@ -0,0 +1,82 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2017 Intel Corporation.
+ * Take from coreboot project file of the same name
+ */
+
+#ifndef _ASM_ARCH_LPC_H
+#define _ASM_ARCH_LPC_H
+
+#define LPC_SERIRQ_CTL			0x64
+#define  LPC_SCNT_EN			BIT(7)
+#define  LPC_SCNT_MODE			BIT(6)
+#define LPC_IO_DECODE			0x80
+#define  LPC_IOD_COMA_RANGE             (0 << 0) /* 0x3F8 - 0x3FF COMA*/
+#define  LPC_IOD_COMB_RANGE             (1 << 4) /* 0x2F8 - 0x2FF COMB*/
+/*
+ * Use IO_<peripheral>_<IO port> style macros defined in lpc_lib.h
+ * to enable decoding of I/O locations for a peripheral
+ */
+#define LPC_IO_ENABLES			0x82
+#define LPC_GENERIC_IO_RANGE(n)		((((n) & 0x3) * 4) + 0x84)
+#define  LPC_LGIR_AMASK_MASK		(0xfc << 16)
+#define  LPC_LGIR_ADDR_MASK		0xfffc
+#define  LPC_LGIR_EN			BIT(0)
+#define LPC_LGIR_MAX_WINDOW_SIZE	256
+#define LPC_GENERIC_MEM_RANGE		0x98
+#define  LPC_LGMR_ADDR_MASK		0xffff0000
+#define  LPC_LGMR_EN			BIT(0)
+#define LPC_LGMR_WINDOW_SIZE		(64 * KiB)
+#define LPC_BIOS_CNTL			0xdc
+#define  LPC_BC_BILD			BIT(7)
+#define  LPC_BC_LE			BIT(1)
+#define  LPC_BC_EISS			BIT(5)
+#define LPC_PCCTL			0xE0	/* PCI Clock Control */
+#define  LPC_PCCTL_CLKRUN_EN		BIT(0)
+
+/*
+ * IO decode enable macros are in the format IO_<peripheral>_<IO port>.
+ * For example, to open ports 0x60, 0x64 for the keyboard controller,
+ * use IOE_KBC_60_64 macro. For IOE_ macros that do not specify a port range,
+ * the port range is selectable via the IO decodes register.
+ */
+#define LPC_IOE_EC_4E_4F		BIT(13)
+#define LPC_IOE_SUPERIO_2E_2F		BIT(12)
+#define LPC_IOE_EC_62_66		BIT(11)
+#define LPC_IOE_KBC_60_64		BIT(10)
+#define LPC_IOE_HGE_208			BIT(9)
+#define LPC_IOE_LGE_200			BIT(8)
+#define LPC_IOE_FDD_EN			BIT(3)
+#define LPC_IOE_LPT_EN			BIT(2)
+#define LPC_IOE_COMB_EN			BIT(1)
+#define LPC_IOE_COMA_EN			BIT(0)
+#define LPC_NUM_GENERIC_IO_RANGES	4
+
+#define LPC_IO_ENABLES			0x82
+
+/**
+ * lpc_enable_fixed_io_ranges() - enable the fixed I/O ranges
+ *
+ * @io_enables: Mask of things to enable (LPC_IOE_.)
+ */
+void lpc_enable_fixed_io_ranges(uint io_enables);
+
+/**
+ * lpc_open_pmio_window() - Open an IO port range
+ *
+ * @base: Base I/O address (e.g. 0x800)
+ * @size: Size of window (e.g. 0x100)
+ * @return 0 if OK, -ENOSPC if there are no more windows available, -EALREADY
+ *	if already set up
+ */
+int lpc_open_pmio_window(uint base, uint size);
+
+/**
+ * lpc_io_setup_comm_a_b() - Set up basic serial UARTs
+ *
+ * Set up the LPC to handle I/O to the COMA/COMB serial UART addresses
+ * 2f8-2ff and 3f8-3ff.
+ */
+void lpc_io_setup_comm_a_b(void);
+
+#endif
-- 
2.24.0.393.g34dc348eaf-goog

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v7 07/17] x86: apl: Add PCH driver
  2019-12-09  0:40 [PATCH v7 04/17] x86: apl: Add hostbridge driver Simon Glass
  2019-12-09  0:40 ` [PATCH v7 05/17] x86: apl: Add ITSS driver Simon Glass
  2019-12-09  0:40 ` [PATCH v7 06/17] x86: apl: Add LPC driver Simon Glass
@ 2019-12-09  0:40 ` Simon Glass
  2019-12-15  0:39   ` Bin Meng
  2019-12-09  0:40 ` [PATCH v7 08/17] x86: apl: Add PUNIT driver Simon Glass
                   ` (10 subsequent siblings)
  13 siblings, 1 reply; 29+ messages in thread
From: Simon Glass @ 2019-12-09  0:40 UTC (permalink / raw)
  To: u-boot

Add a driver for the Apollo Lake Platform Controller Hub. It does not have
any functionality and is just a placeholder for now.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4:
- Tidy up header guards
- Update SPI flash protection only in SPL
- apollolake -> Apollo Lake

Changes in v3: None
Changes in v2:
- Drop probe() function
- Implement set_spi_protect()

 arch/x86/cpu/apollolake/Makefile           |  1 +
 arch/x86/cpu/apollolake/pch.c              | 36 ++++++++++++++++++++++
 arch/x86/include/asm/arch-apollolake/pch.h |  9 ++++++
 3 files changed, 46 insertions(+)
 create mode 100644 arch/x86/cpu/apollolake/pch.c
 create mode 100644 arch/x86/include/asm/arch-apollolake/pch.h

diff --git a/arch/x86/cpu/apollolake/Makefile b/arch/x86/cpu/apollolake/Makefile
index 31045a03c1..36eefcbad7 100644
--- a/arch/x86/cpu/apollolake/Makefile
+++ b/arch/x86/cpu/apollolake/Makefile
@@ -7,5 +7,6 @@ obj-$(CONFIG_SPL_BUILD) += systemagent.o
 obj-y += hostbridge.o
 obj-y += itss.o
 obj-y += lpc.o
+obj-y += pch.o
 obj-y += pmc.o
 obj-y += uart.o
diff --git a/arch/x86/cpu/apollolake/pch.c b/arch/x86/cpu/apollolake/pch.c
new file mode 100644
index 0000000000..1a5a985221
--- /dev/null
+++ b/arch/x86/cpu/apollolake/pch.c
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 Google LLC
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <pch.h>
+#include <spl.h>
+#include <asm/lpc_common.h>
+
+#define BIOS_CTRL	0xdc
+
+static int apl_set_spi_protect(struct udevice *dev, bool protect)
+{
+	if (spl_phase() == PHASE_SPL)
+		return lpc_set_spi_protect(dev, BIOS_CTRL, protect);
+
+	return 0;
+}
+
+static const struct pch_ops apl_pch_ops = {
+	.set_spi_protect = apl_set_spi_protect,
+};
+
+static const struct udevice_id apl_pch_ids[] = {
+	{ .compatible = "intel,apl-pch" },
+	{ }
+};
+
+U_BOOT_DRIVER(apl_pch) = {
+	.name		= "apl_pch",
+	.id		= UCLASS_PCH,
+	.of_match	= apl_pch_ids,
+	.ops		= &apl_pch_ops,
+};
diff --git a/arch/x86/include/asm/arch-apollolake/pch.h b/arch/x86/include/asm/arch-apollolake/pch.h
new file mode 100644
index 0000000000..bf3e1670d2
--- /dev/null
+++ b/arch/x86/include/asm/arch-apollolake/pch.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2019 Google LLC
+ */
+
+#ifndef _ASM_ARCH_PCH_H
+#define _ASM_ARCH_PCH_H
+
+#endif /* _ASM_ARCH_PCH_H */
-- 
2.24.0.393.g34dc348eaf-goog

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v7 08/17] x86: apl: Add PUNIT driver
  2019-12-09  0:40 [PATCH v7 04/17] x86: apl: Add hostbridge driver Simon Glass
                   ` (2 preceding siblings ...)
  2019-12-09  0:40 ` [PATCH v7 07/17] x86: apl: Add PCH driver Simon Glass
@ 2019-12-09  0:40 ` Simon Glass
  2019-12-15  0:40   ` Bin Meng
  2019-12-09  0:40 ` [PATCH v7 09/17] spl: Add methods to find the position/size of next phase Simon Glass
                   ` (9 subsequent siblings)
  13 siblings, 1 reply; 29+ messages in thread
From: Simon Glass @ 2019-12-09  0:40 UTC (permalink / raw)
  To: u-boot

Add a driver for the Apollo Lake P-unit (power unit). It is modelled as a
syscon driver since it only needs to be probed.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

Changes in v7: None
Changes in v6:
- Drop Glacier Lake code
- Drop platform data and pre-PCI code, since DM PCI is available in SPL

Changes in v5: None
Changes in v4:
- Name this P-Unit instead of power unit, in the commit message
- apollolake -> Apollo Lake

Changes in v3:
- Use pci_get_devfn()

Changes in v2: None

 arch/x86/cpu/apollolake/Makefile |  3 +
 arch/x86/cpu/apollolake/punit.c  | 94 ++++++++++++++++++++++++++++++++
 2 files changed, 97 insertions(+)
 create mode 100644 arch/x86/cpu/apollolake/punit.c

diff --git a/arch/x86/cpu/apollolake/Makefile b/arch/x86/cpu/apollolake/Makefile
index 36eefcbad7..875d454157 100644
--- a/arch/x86/cpu/apollolake/Makefile
+++ b/arch/x86/cpu/apollolake/Makefile
@@ -3,6 +3,9 @@
 # Copyright 2019 Google LLC
 
 obj-$(CONFIG_SPL_BUILD) += systemagent.o
+ifndef CONFIG_TPL_BUILD
+obj-y += punit.o
+endif
 
 obj-y += hostbridge.o
 obj-y += itss.o
diff --git a/arch/x86/cpu/apollolake/punit.c b/arch/x86/cpu/apollolake/punit.c
new file mode 100644
index 0000000000..1a131fb0b1
--- /dev/null
+++ b/arch/x86/cpu/apollolake/punit.c
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 Google LLC
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <spl.h>
+#include <asm/cpu.h>
+#include <asm/cpu_common.h>
+#include <asm/intel_regs.h>
+#include <asm/io.h>
+#include <asm/pci.h>
+#include <asm/arch/systemagent.h>
+
+/*
+ * Punit Initialisation code. This all isn't documented, but
+ * this is the recipe.
+ */
+static int punit_init(struct udevice *dev)
+{
+	struct udevice *cpu;
+	u32 reg;
+	ulong start;
+	int ret;
+
+	/* Thermal throttle activation offset */
+	ret = uclass_first_device_err(UCLASS_CPU, &cpu);
+	if (ret)
+		return log_msg_ret("Cannot find CPU", ret);
+	cpu_configure_thermal_target(cpu);
+
+	/*
+	 * Software Core Disable Mask (P_CR_CORE_DISABLE_MASK_0_0_0_MCHBAR).
+	 * Enable all cores here.
+	 */
+	writel(0, MCHBAR_REG(CORE_DISABLE_MASK));
+
+	/* P-Unit bring up */
+	reg = readl(MCHBAR_REG(BIOS_RESET_CPL));
+	if (reg == 0xffffffff) {
+		/* P-unit not found */
+		debug("Punit MMIO not available\n");
+		return -ENOENT;
+	}
+
+	/* Set Punit interrupt pin IPIN offset 3D */
+	dm_pci_write_config8(dev, PCI_INTERRUPT_PIN, 0x2);
+
+	/* Set PUINT IRQ to 24 and INTPIN LOCK */
+	writel(PUINT_THERMAL_DEVICE_IRQ_VEC_NUMBER |
+	       PUINT_THERMAL_DEVICE_IRQ_LOCK,
+	       MCHBAR_REG(PUNIT_THERMAL_DEVICE_IRQ));
+
+	/* Stage0 BIOS Reset Complete (RST_CPL) */
+	enable_bios_reset_cpl();
+
+	/*
+	 * Poll for bit 8 to check if PCODE has completed its action in response
+	 * to BIOS Reset complete.  We wait here till 1 ms for the bit to get
+	 * set.
+	 */
+	start = get_timer(0);
+	while (!(readl(MCHBAR_REG(BIOS_RESET_CPL)) & PCODE_INIT_DONE)) {
+		if (get_timer(start) > 1) {
+			debug("PCODE Init Done timeout\n");
+			return -ETIMEDOUT;
+		}
+		udelay(100);
+	}
+	debug("PUNIT init complete\n");
+
+	return 0;
+}
+
+static int apl_punit_probe(struct udevice *dev)
+{
+	if (spl_phase() == PHASE_SPL)
+		return punit_init(dev);
+
+	return 0;
+}
+
+static const struct udevice_id apl_syscon_ids[] = {
+	{ .compatible = "intel,apl-punit", .data = X86_SYSCON_PUNIT },
+	{ }
+};
+
+U_BOOT_DRIVER(syscon_intel_punit) = {
+	.name		= "intel_punit_syscon",
+	.id		= UCLASS_SYSCON,
+	.of_match	= apl_syscon_ids,
+	.probe		= apl_punit_probe,
+};
-- 
2.24.0.393.g34dc348eaf-goog

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v7 09/17] spl: Add methods to find the position/size of next phase
  2019-12-09  0:40 [PATCH v7 04/17] x86: apl: Add hostbridge driver Simon Glass
                   ` (3 preceding siblings ...)
  2019-12-09  0:40 ` [PATCH v7 08/17] x86: apl: Add PUNIT driver Simon Glass
@ 2019-12-09  0:40 ` Simon Glass
  2019-12-15  0:40   ` Bin Meng
  2019-12-09  0:40 ` [PATCH v7 10/17] x86: apl: Add SPL loaders Simon Glass
                   ` (8 subsequent siblings)
  13 siblings, 1 reply; 29+ messages in thread
From: Simon Glass @ 2019-12-09  0:40 UTC (permalink / raw)
  To: u-boot

Binman supports writing the position and size of U-Boot proper and SPL
into the previous phase of U-Boot. This allows the next phase to be easily
located and loaded.

Add functions to return these useful values, along with symbols to allow
TPL to load SPL.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

Changes in v7: None
Changes in v6:
- Add new patch with methods to find the position/size of next SPL phase

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 common/spl/spl.c | 20 ++++++++++++++++++++
 include/spl.h    | 21 ++++++++++++++++++++-
 2 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/common/spl/spl.c b/common/spl/spl.c
index d51dbe9942..c1fce62b91 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -42,6 +42,12 @@ u32 *boot_params_ptr = NULL;
 
 /* See spl.h for information about this */
 binman_sym_declare(ulong, u_boot_any, image_pos);
+binman_sym_declare(ulong, u_boot_any, size);
+
+#ifdef CONFIG_TPL
+binman_sym_declare(ulong, spl, image_pos);
+binman_sym_declare(ulong, spl, size);
+#endif
 
 /* Define board data structure */
 static bd_t bdata __attribute__ ((section(".data")));
@@ -120,6 +126,20 @@ void spl_fixup_fdt(void)
 #endif
 }
 
+ulong spl_get_image_pos(void)
+{
+	return spl_phase() == PHASE_TPL ?
+		binman_sym(ulong, spl, image_pos) :
+		binman_sym(ulong, u_boot_any, image_pos);
+}
+
+ulong spl_get_image_size(void)
+{
+	return spl_phase() == PHASE_TPL ?
+		binman_sym(ulong, spl, size) :
+		binman_sym(ulong, u_boot_any, size);
+}
+
 /*
  * Weak default function for board specific cleanup/preparation before
  * Linux boot. Some boards/platforms might not need it, so just provide
diff --git a/include/spl.h b/include/spl.h
index 08ffddac29..02aa1ff85d 100644
--- a/include/spl.h
+++ b/include/spl.h
@@ -169,10 +169,29 @@ struct spl_load_info {
  * We need to know the position of U-Boot in memory so we can jump to it. We
  * allow any U-Boot binary to be used (u-boot.bin, u-boot-nodtb.bin,
  * u-boot.img), hence the '_any'. These is no checking here that the correct
- * image is found. For * example if u-boot.img is used we don't check that
+ * image is found. For example if u-boot.img is used we don't check that
  * spl_parse_image_header() can parse a valid header.
+ *
+ * Similarly for SPL, so that TPL can jump to SPL.
  */
 binman_sym_extern(ulong, u_boot_any, image_pos);
+binman_sym_extern(ulong, u_boot_any, size);
+binman_sym_extern(ulong, spl, image_pos);
+binman_sym_extern(ulong, spl, size);
+
+/**
+ * spl_get_image_pos() - get the image position of the next phase
+ *
+ * This returns the image position to use to load the next phase of U-Boot
+ */
+ulong spl_get_image_pos(void);
+
+/**
+ * spl_get_image_size() - get the size of the next phase
+ *
+ * This returns the size to use to load the next phase of U-Boot
+ */
+ulong spl_get_image_size(void);
 
 /**
  * spl_load_simple_fit_skip_processing() - Hook to allow skipping the FIT
-- 
2.24.0.393.g34dc348eaf-goog

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v7 10/17] x86: apl: Add SPL loaders
  2019-12-09  0:40 [PATCH v7 04/17] x86: apl: Add hostbridge driver Simon Glass
                   ` (4 preceding siblings ...)
  2019-12-09  0:40 ` [PATCH v7 09/17] spl: Add methods to find the position/size of next phase Simon Glass
@ 2019-12-09  0:40 ` Simon Glass
  2019-12-15  0:41   ` Bin Meng
  2019-12-09  0:40 ` [PATCH v7 11/17] x86: apl: Add a CPU driver Simon Glass
                   ` (7 subsequent siblings)
  13 siblings, 1 reply; 29+ messages in thread
From: Simon Glass @ 2019-12-09  0:40 UTC (permalink / raw)
  To: u-boot

Add loaders for SPL and TPL so that the next stage can be loaded from
memory-mapped SPI or, failing that, the Fast SPI driver.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>

---

Changes in v7: None
Changes in v6:
- Make BOOT_FROM_FAST_SPI_FLASH a Kconfig option
- Move image pos/size access functions and symbols to generic SPL code

Changes in v5:
- Add L2 cache flush functoin
- Drop SAFETY_MARGIN

Changes in v4: None
Changes in v3:
- Add a driver for APL SPI for TPL (using of-platdata)
- Support TPL without CONFIG_TPL_SPI_SUPPORT
- Support bootstage timing

Changes in v2: None

 arch/x86/cpu/apollolake/Makefile |   2 +
 arch/x86/cpu/apollolake/spl.c    | 178 +++++++++++++++++++++++++++++++
 2 files changed, 180 insertions(+)
 create mode 100644 arch/x86/cpu/apollolake/spl.c

diff --git a/arch/x86/cpu/apollolake/Makefile b/arch/x86/cpu/apollolake/Makefile
index 875d454157..1fde400d77 100644
--- a/arch/x86/cpu/apollolake/Makefile
+++ b/arch/x86/cpu/apollolake/Makefile
@@ -2,7 +2,9 @@
 #
 # Copyright 2019 Google LLC
 
+obj-$(CONFIG_SPL_BUILD) += spl.o
 obj-$(CONFIG_SPL_BUILD) += systemagent.o
+
 ifndef CONFIG_TPL_BUILD
 obj-y += punit.o
 endif
diff --git a/arch/x86/cpu/apollolake/spl.c b/arch/x86/cpu/apollolake/spl.c
new file mode 100644
index 0000000000..7ab7243311
--- /dev/null
+++ b/arch/x86/cpu/apollolake/spl.c
@@ -0,0 +1,178 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 Google LLC
+ */
+
+#include <common.h>
+#include <binman_sym.h>
+#include <dm.h>
+#include <spi.h>
+#include <spl.h>
+#include <spi_flash.h>
+#include <asm/fast_spi.h>
+#include <asm/spl.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/iomap.h>
+#include <dm/device-internal.h>
+#include <dm/uclass-internal.h>
+
+/* This reads the next phase from mapped SPI flash */
+static int rom_load_image(struct spl_image_info *spl_image,
+			  struct spl_boot_device *bootdev)
+{
+	ulong spl_pos = spl_get_image_pos();
+	ulong spl_size = spl_get_image_size();
+	struct udevice *dev;
+	ulong map_base;
+	size_t map_size;
+	uint offset;
+	int ret;
+
+	spl_image->size = CONFIG_SYS_MONITOR_LEN;  /* We don't know SPL size */
+	spl_image->entry_point = spl_phase() == PHASE_TPL ?
+		CONFIG_SPL_TEXT_BASE : CONFIG_SYS_TEXT_BASE;
+	spl_image->load_addr = spl_image->entry_point;
+	spl_image->os = IH_OS_U_BOOT;
+	spl_image->name = "U-Boot";
+	debug("Reading from mapped SPI %lx, size %lx", spl_pos, spl_size);
+
+	if (CONFIG_IS_ENABLED(SPI_FLASH_SUPPORT)) {
+		ret = uclass_find_first_device(UCLASS_SPI_FLASH, &dev);
+		if (ret)
+			return log_msg_ret("spi_flash", ret);
+		if (!dev)
+			return log_msg_ret("spi_flash dev", -ENODEV);
+		ret = dm_spi_get_mmap(dev, &map_base, &map_size, &offset);
+		if (ret)
+			return log_msg_ret("mmap", ret);
+	} else {
+		ret = fast_spi_get_bios_mmap(PCH_DEV_SPI, &map_base, &map_size,
+					     &offset);
+		if (ret)
+			return ret;
+	}
+	spl_pos += map_base & ~0xff000000;
+	debug(", base %lx, pos %lx\n", map_base, spl_pos);
+	bootstage_start(BOOTSTAGE_ID_ACCUM_MMAP_SPI, "mmap_spi");
+	memcpy((void *)spl_image->load_addr, (void *)spl_pos, spl_size);
+	cpu_flush_l1d_to_l2();
+	bootstage_accum(BOOTSTAGE_ID_ACCUM_MMAP_SPI);
+
+	return 0;
+}
+SPL_LOAD_IMAGE_METHOD("Mapped SPI", 2, BOOT_DEVICE_SPI_MMAP, rom_load_image);
+
+#if CONFIG_IS_ENABLED(SPI_FLASH_SUPPORT)
+
+static int apl_flash_std_read(struct udevice *dev, u32 offset, size_t len,
+			      void *buf)
+{
+	struct spi_flash *flash = dev_get_uclass_priv(dev);
+	struct mtd_info *mtd = &flash->mtd;
+	size_t retlen;
+
+	return log_ret(mtd->_read(mtd, offset, len, &retlen, buf));
+}
+
+static int apl_flash_probe(struct udevice *dev)
+{
+	return spi_flash_std_probe(dev);
+}
+
+/*
+ * Manually set the parent of the SPI flash to SPI, since dtoc doesn't. We also
+ * need to allocate the parent_platdata since by the time this function is
+ * called device_bind() has already gone past that step.
+ */
+static int apl_flash_bind(struct udevice *dev)
+{
+	if (CONFIG_IS_ENABLED(OF_PLATDATA)) {
+		struct dm_spi_slave_platdata *plat;
+		struct udevice *spi;
+		int ret;
+
+		ret = uclass_first_device_err(UCLASS_SPI, &spi);
+		if (ret)
+			return ret;
+		dev->parent = spi;
+
+		plat = calloc(sizeof(*plat), 1);
+		if (!plat)
+			return -ENOMEM;
+		dev->parent_platdata = plat;
+	}
+
+	return 0;
+}
+
+static const struct dm_spi_flash_ops apl_flash_ops = {
+	.read		= apl_flash_std_read,
+};
+
+static const struct udevice_id apl_flash_ids[] = {
+	{ .compatible = "jedec,spi-nor" },
+	{ }
+};
+
+U_BOOT_DRIVER(winbond_w25q128fw) = {
+	.name		= "winbond_w25q128fw",
+	.id		= UCLASS_SPI_FLASH,
+	.of_match	= apl_flash_ids,
+	.bind		= apl_flash_bind,
+	.probe		= apl_flash_probe,
+	.priv_auto_alloc_size = sizeof(struct spi_flash),
+	.ops		= &apl_flash_ops,
+};
+
+/* This uses a SPI flash device to read the next phase */
+static int spl_fast_spi_load_image(struct spl_image_info *spl_image,
+				   struct spl_boot_device *bootdev)
+{
+	ulong spl_pos = spl_get_image_pos();
+	ulong spl_size = spl_get_image_size();
+	struct udevice *dev;
+	int ret;
+
+	ret = uclass_first_device_err(UCLASS_SPI_FLASH, &dev);
+	if (ret)
+		return ret;
+
+	spl_image->size = CONFIG_SYS_MONITOR_LEN;  /* We don't know SPL size */
+	spl_image->entry_point = spl_phase() == PHASE_TPL ?
+		CONFIG_SPL_TEXT_BASE : CONFIG_SYS_TEXT_BASE;
+	spl_image->load_addr = spl_image->entry_point;
+	spl_image->os = IH_OS_U_BOOT;
+	spl_image->name = "U-Boot";
+	spl_pos &= ~0xff000000;
+	debug("Reading from flash %lx, size %lx\n", spl_pos, spl_size);
+	ret = spi_flash_read_dm(dev, spl_pos, spl_size,
+				(void *)spl_image->load_addr);
+	cpu_flush_l1d_to_l2();
+	if (ret)
+		return ret;
+
+	return 0;
+}
+SPL_LOAD_IMAGE_METHOD("Fast SPI", 1, BOOT_DEVICE_FAST_SPI,
+		      spl_fast_spi_load_image);
+
+void board_boot_order(u32 *spl_boot_list)
+{
+	bool use_spi_flash = IS_ENABLED(CONFIG_APL_BOOT_FROM_FAST_SPI_FLASH);
+
+	if (use_spi_flash) {
+		spl_boot_list[0] = BOOT_DEVICE_FAST_SPI;
+		spl_boot_list[1] = BOOT_DEVICE_SPI_MMAP;
+	} else {
+		spl_boot_list[0] = BOOT_DEVICE_SPI_MMAP;
+		spl_boot_list[1] = BOOT_DEVICE_FAST_SPI;
+	}
+}
+
+#else
+
+void board_boot_order(u32 *spl_boot_list)
+{
+	spl_boot_list[0] = BOOT_DEVICE_SPI_MMAP;
+}
+#endif
-- 
2.24.0.393.g34dc348eaf-goog

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v7 11/17] x86: apl: Add a CPU driver
  2019-12-09  0:40 [PATCH v7 04/17] x86: apl: Add hostbridge driver Simon Glass
                   ` (5 preceding siblings ...)
  2019-12-09  0:40 ` [PATCH v7 10/17] x86: apl: Add SPL loaders Simon Glass
@ 2019-12-09  0:40 ` Simon Glass
  2019-12-15  0:43   ` Bin Meng
  2019-12-09  0:40 ` [PATCH v7 12/17] x86: apl: Add SPL/TPL init Simon Glass
                   ` (6 subsequent siblings)
  13 siblings, 1 reply; 29+ messages in thread
From: Simon Glass @ 2019-12-09  0:40 UTC (permalink / raw)
  To: u-boot

Add a bare-bones CPU driver so that CPUs can be probed.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

Changes in v7: None
Changes in v6:
- Drop unnecessary priv struct and probe method
- Make BOOT_FROM_FAST_SPI_FLASH a Kconfig option

Changes in v5:
- Add L2 cache flush function
- Drop SAFETY_MARGIN

Changes in v4:
- Change apollolake to apl
- Tidy up header guards

Changes in v3:
- Add two more defines for the CPU driver
- Expand comments for BOOT_FROM_FAST_SPI_FLASH

Changes in v2: None

 arch/x86/cpu/apollolake/Makefile           |  2 ++
 arch/x86/cpu/apollolake/cpu.c              | 41 ++++++++++++++++++++++
 arch/x86/cpu/apollolake/cpu_common.c       | 17 +++++++++
 arch/x86/include/asm/arch-apollolake/cpu.h | 20 +++++++++++
 arch/x86/include/asm/msr-index.h           |  1 +
 5 files changed, 81 insertions(+)
 create mode 100644 arch/x86/cpu/apollolake/cpu.c
 create mode 100644 arch/x86/cpu/apollolake/cpu_common.c
 create mode 100644 arch/x86/include/asm/arch-apollolake/cpu.h

diff --git a/arch/x86/cpu/apollolake/Makefile b/arch/x86/cpu/apollolake/Makefile
index 1fde400d77..37e42092ec 100644
--- a/arch/x86/cpu/apollolake/Makefile
+++ b/arch/x86/cpu/apollolake/Makefile
@@ -4,8 +4,10 @@
 
 obj-$(CONFIG_SPL_BUILD) += spl.o
 obj-$(CONFIG_SPL_BUILD) += systemagent.o
+obj-y += cpu_common.o
 
 ifndef CONFIG_TPL_BUILD
+obj-y += cpu.o
 obj-y += punit.o
 endif
 
diff --git a/arch/x86/cpu/apollolake/cpu.c b/arch/x86/cpu/apollolake/cpu.c
new file mode 100644
index 0000000000..3d05c82a5c
--- /dev/null
+++ b/arch/x86/cpu/apollolake/cpu.c
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 Google LLC
+ */
+
+#include <common.h>
+#include <cpu.h>
+#include <dm.h>
+#include <asm/cpu_common.h>
+#include <asm/cpu_x86.h>
+
+static int apl_get_info(struct udevice *dev, struct cpu_info *info)
+{
+	return cpu_intel_get_info(info, INTEL_BCLK_MHZ);
+}
+
+static int apl_get_count(struct udevice *dev)
+{
+	return 4;
+}
+
+static const struct cpu_ops cpu_x86_apl_ops = {
+	.get_desc	= cpu_x86_get_desc,
+	.get_info	= apl_get_info,
+	.get_count	= apl_get_count,
+	.get_vendor	= cpu_x86_get_vendor,
+};
+
+static const struct udevice_id cpu_x86_apl_ids[] = {
+	{ .compatible = "intel,apl-cpu" },
+	{ }
+};
+
+U_BOOT_DRIVER(cpu_x86_apl_drv) = {
+	.name		= "cpu_x86_apl",
+	.id		= UCLASS_CPU,
+	.of_match	= cpu_x86_apl_ids,
+	.bind		= cpu_x86_bind,
+	.ops		= &cpu_x86_apl_ops,
+	.flags		= DM_FLAG_PRE_RELOC,
+};
diff --git a/arch/x86/cpu/apollolake/cpu_common.c b/arch/x86/cpu/apollolake/cpu_common.c
new file mode 100644
index 0000000000..ba6bda37bc
--- /dev/null
+++ b/arch/x86/cpu/apollolake/cpu_common.c
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 Google LLC
+ */
+
+#include <common.h>
+#include <asm/cpu_common.h>
+#include <asm/msr.h>
+
+void cpu_flush_l1d_to_l2(void)
+{
+	struct msr_t msr;
+
+	msr = msr_read(MSR_POWER_MISC);
+	msr.lo |= FLUSH_DL1_L2;
+	msr_write(MSR_POWER_MISC, msr);
+}
diff --git a/arch/x86/include/asm/arch-apollolake/cpu.h b/arch/x86/include/asm/arch-apollolake/cpu.h
new file mode 100644
index 0000000000..5e906c5e7d
--- /dev/null
+++ b/arch/x86/include/asm/arch-apollolake/cpu.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2019 Google LLC
+ */
+
+#ifndef _ASM_ARCH_CPU_H
+#define _ASM_ARCH_CPU_H
+
+/* Common Timer Copy (CTC) frequency - 19.2MHz */
+#define CTC_FREQ		19200000
+
+#define MAX_PCIE_PORTS		6
+#define CLKREQ_DISABLED		0xf
+
+#ifndef __ASSEMBLY__
+/* Flush L1D to L2 */
+void cpu_flush_l1d_to_l2(void);
+#endif
+
+#endif /* _ASM_ARCH_CPU_H */
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 79a9369de1..246c14f815 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -70,6 +70,7 @@
 #define MSR_IA32_BBL_CR_CTL		0x00000119
 #define MSR_IA32_BBL_CR_CTL3		0x0000011e
 #define MSR_POWER_MISC			0x00000120
+#define  FLUSH_DL1_L2			(1 << 8)
 #define ENABLE_ULFM_AUTOCM_MASK		(1 << 2)
 #define ENABLE_INDP_AUTOCM_MASK		(1 << 3)
 
-- 
2.24.0.393.g34dc348eaf-goog

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v7 12/17] x86: apl: Add SPL/TPL init
  2019-12-09  0:40 [PATCH v7 04/17] x86: apl: Add hostbridge driver Simon Glass
                   ` (6 preceding siblings ...)
  2019-12-09  0:40 ` [PATCH v7 11/17] x86: apl: Add a CPU driver Simon Glass
@ 2019-12-09  0:40 ` Simon Glass
  2019-12-15  0:44   ` Bin Meng
  2019-12-09  0:40 ` [PATCH v7 13/17] x86: apl: Add P2SB driver Simon Glass
                   ` (5 subsequent siblings)
  13 siblings, 1 reply; 29+ messages in thread
From: Simon Glass @ 2019-12-09  0:40 UTC (permalink / raw)
  To: u-boot

Add code to init the system both in TPL and SPL. Each phase has its own
procedure.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

Changes in v7: None
Changes in v6:
- Change comment to apl_hostbridge_early_init_pinctrl, not apl_gpio_early_init
- Change commented-out enable_rtc_upper_bank() call to a TODO
- Make BOOT_FROM_FAST_SPI_FLASH a Kconfig option
- Rename init_for_uart() to board_debug_uart_init()
- Use SZ_4G instead of open-coded shift

Changes in v5: None
Changes in v4:
- Switch over to use pinctrl for pad init/config

Changes in v3:
- Adjust fast_spi_cache_bios_region() to avoid using SPI driver
- Drop calls to x86_cpu_init_f(), x86_cpu_reinit_f()
- Fix build error when debug UART is disabled
- Init the p2sb before the northbridge since the latter so it can use GPIOs
- Move location of fast_spi.h header file
- Shorten log_msg_ret() calls since the function name is always printed
- Support TPL without CONFIG_TPL_SPI_SUPPORT (reduces code size)

Changes in v2: None

 arch/x86/cpu/apollolake/Makefile  |   1 +
 arch/x86/cpu/apollolake/cpu_spl.c | 271 ++++++++++++++++++++++++++++++
 2 files changed, 272 insertions(+)
 create mode 100644 arch/x86/cpu/apollolake/cpu_spl.c

diff --git a/arch/x86/cpu/apollolake/Makefile b/arch/x86/cpu/apollolake/Makefile
index 37e42092ec..edde122f75 100644
--- a/arch/x86/cpu/apollolake/Makefile
+++ b/arch/x86/cpu/apollolake/Makefile
@@ -2,6 +2,7 @@
 #
 # Copyright 2019 Google LLC
 
+obj-$(CONFIG_SPL_BUILD) += cpu_spl.o
 obj-$(CONFIG_SPL_BUILD) += spl.o
 obj-$(CONFIG_SPL_BUILD) += systemagent.o
 obj-y += cpu_common.o
diff --git a/arch/x86/cpu/apollolake/cpu_spl.c b/arch/x86/cpu/apollolake/cpu_spl.c
new file mode 100644
index 0000000000..8a39c3128e
--- /dev/null
+++ b/arch/x86/cpu/apollolake/cpu_spl.c
@@ -0,0 +1,271 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Portions taken from coreboot
+ */
+
+#include <common.h>
+#include <acpi_s3.h>
+#include <dm.h>
+#include <ec_commands.h>
+#include <log.h>
+#include <spi_flash.h>
+#include <spl.h>
+#include <syscon.h>
+#include <asm/cpu.h>
+#include <asm/cpu_common.h>
+#include <asm/cpu_x86.h>
+#include <asm/fast_spi.h>
+#include <asm/intel_pinctrl.h>
+#include <asm/intel_regs.h>
+#include <asm/io.h>
+#include <asm/msr.h>
+#include <asm/mtrr.h>
+#include <asm/pci.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/iomap.h>
+#include <asm/arch/lpc.h>
+#include <asm/arch/pch.h>
+#include <asm/arch/systemagent.h>
+#include <asm/arch/uart.h>
+#include <asm/fsp2/fsp_api.h>
+#include <linux/sizes.h>
+#include <power/acpi_pmc.h>
+
+/* Define this here to avoid referencing any drivers for the debug UART 1 */
+#define PCH_DEV_P2SB	PCI_BDF(0, 0x0d, 0)
+
+static void pch_uart_init(void)
+{
+	/*
+	 * Set up the pinmux so that the UART rx/tx signals are connected
+	 * outside the SoC.
+	 *
+	 * There are about 500 lines of code required to program the GPIO
+	 * configuration for the UARTs. But it boils down to four writes, and
+	 * for the debug UART we want the minimum possible amount of code before
+	 * the UART is running. So just add the magic writes here. See
+	 * apl_hostbridge_early_init_pinctrl() for the full horror.
+	 */
+	if (PCI_FUNC(PCH_DEV_UART) == 1) {
+		writel(0x40000402, 0xd0c50650);
+		writel(0x3c47, 0xd0c50654);
+		writel(0x40000400, 0xd0c50658);
+		writel(0x3c48, 0xd0c5065c);
+	} else { /* UART2 */
+		writel(0x40000402, 0xd0c50670);
+		writel(0x3c4b, 0xd0c50674);
+		writel(0x40000400, 0xd0c50678);
+		writel(0x3c4c, 0xd0c5067c);
+	}
+
+#ifdef CONFIG_DEBUG_UART
+	apl_uart_init(PCH_DEV_UART, CONFIG_DEBUG_UART_BASE);
+#endif
+}
+
+static void p2sb_enable_bar(ulong bar)
+{
+	/* Enable PCR Base address in PCH */
+	pci_x86_write_config(PCH_DEV_P2SB, PCI_BASE_ADDRESS_0, bar,
+			     PCI_SIZE_32);
+	pci_x86_write_config(PCH_DEV_P2SB, PCI_BASE_ADDRESS_1, 0, PCI_SIZE_32);
+
+	/* Enable P2SB MSE */
+	pci_x86_write_config(PCH_DEV_P2SB, PCI_COMMAND,
+			     PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY,
+			     PCI_SIZE_8);
+}
+
+/*
+ * board_debug_uart_init() - Init the debug UART ready for use
+ *
+ * This is the minimum init needed to get the UART running. It avoids any
+ * drivers or complex code, so that the UART is running as soon as possible.
+ */
+void board_debug_uart_init(void)
+{
+	p2sb_enable_bar(IOMAP_P2SB_BAR);
+	pch_uart_init();
+}
+
+static int fast_spi_cache_bios_region(void)
+{
+	uint map_size, offset;
+	ulong map_base, base;
+	int ret;
+
+	ret = fast_spi_early_init(PCH_DEV_SPI, IOMAP_SPI_BASE);
+	if (ret)
+		return log_msg_ret("early_init", ret);
+
+	ret = fast_spi_get_bios_mmap(PCH_DEV_SPI, &map_base, &map_size,
+				     &offset);
+	if (ret)
+		return log_msg_ret("get_mmap", ret);
+
+	base = SZ_4G - map_size;
+	mtrr_set_next_var(MTRR_TYPE_WRPROT, base, map_size);
+	log_debug("BIOS cache base=%lx, size=%x\n", base, (uint)map_size);
+
+	return 0;
+}
+
+static void enable_pm_timer_emulation(struct udevice *pmc)
+{
+	struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(pmc);
+	msr_t msr;
+
+	/*
+	 * The derived frequency is calculated as follows:
+	 *    (CTC_FREQ * msr[63:32]) >> 32 = target frequency.
+	 *
+	 * Back-solve the multiplier so the 3.579545MHz ACPI timer frequency is
+	 * used.
+	 */
+	msr.hi = (3579545ULL << 32) / CTC_FREQ;
+
+	/* Set PM1 timer IO port and enable */
+	msr.lo = EMULATE_PM_TMR_EN | (upriv->acpi_base + R_ACPI_PM1_TMR);
+	debug("PM timer %x %x\n", msr.hi, msr.lo);
+	msr_write(MSR_EMULATE_PM_TIMER, msr);
+}
+
+static void google_chromeec_ioport_range(uint *out_basep, uint *out_sizep)
+{
+	uint base;
+	uint size;
+
+	if (IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC_MEC)) {
+		base = MEC_EMI_BASE;
+		size = MEC_EMI_SIZE;
+	} else {
+		base = EC_HOST_CMD_REGION0;
+		size = 2 * EC_HOST_CMD_REGION_SIZE;
+		/* Make sure MEMMAP region follows host cmd region */
+		assert(base + size == EC_LPC_ADDR_MEMMAP);
+		size += EC_MEMMAP_SIZE;
+	}
+
+	*out_basep = base;
+	*out_sizep = size;
+}
+
+static void early_ec_init(void)
+{
+	uint base, size;
+
+	/*
+	 * Set up LPC decoding for the Chrome OS EC I/O port ranges:
+	 * - Ports 62/66, 60/64, and 200->208
+	 * - Chrome OS EC communication I/O ports
+	 */
+	lpc_enable_fixed_io_ranges(LPC_IOE_EC_62_66 | LPC_IOE_KBC_60_64 |
+				   LPC_IOE_LGE_200);
+	google_chromeec_ioport_range(&base, &size);
+	lpc_open_pmio_window(base, size);
+}
+
+static int arch_cpu_init_tpl(void)
+{
+	struct udevice *pmc, *sa, *p2sb, *serial, *spi, *lpc;
+	int ret;
+
+	ret = uclass_first_device_err(UCLASS_ACPI_PMC, &pmc);
+	if (ret)
+		return log_msg_ret("PMC", ret);
+
+	/* Clear global reset promotion bit */
+	ret = pmc_global_reset_set_enable(pmc, false);
+	if (ret)
+		return log_msg_ret("disable global reset", ret);
+
+	enable_pm_timer_emulation(pmc);
+
+	ret = uclass_first_device_err(UCLASS_P2SB, &p2sb);
+	if (ret)
+		return log_msg_ret("p2sb", ret);
+	ret = uclass_first_device_err(UCLASS_NORTHBRIDGE, &sa);
+	if (ret)
+		return log_msg_ret("northbridge", ret);
+	gd->baudrate = CONFIG_BAUDRATE;
+	ret = uclass_first_device_err(UCLASS_SERIAL, &serial);
+	if (ret)
+		return log_msg_ret("serial", ret);
+	if (CONFIG_IS_ENABLED(SPI_FLASH_SUPPORT)) {
+		ret = uclass_first_device_err(UCLASS_SPI, &spi);
+		if (ret)
+			return log_msg_ret("SPI", ret);
+	} else {
+		/* Alternative code if we don't have SPI in TPL */
+		if (IS_ENABLED(CONFIG_APL_BOOT_FROM_FAST_SPI_FLASH))
+			printf("Warning: Enable APL_SPI_FLASHBOOT to use SPI-flash driver in TPL");
+		ret = fast_spi_cache_bios_region();
+		if (ret)
+			return log_msg_ret("BIOS cache", ret);
+	}
+	ret = pmc_disable_tco(pmc);
+	if (ret)
+		return log_msg_ret("disable TCO", ret);
+	ret = pmc_gpe_init(pmc);
+	if (ret)
+		return log_msg_ret("pmc_gpe", ret);
+	ret = uclass_first_device_err(UCLASS_LPC, &lpc);
+	if (ret)
+		return log_msg_ret("lpc", ret);
+
+	early_ec_init();
+
+	return 0;
+}
+
+/*
+ * Enables several BARs and devices which are needed for memory init
+ * - MCH_BASE_ADDR is needed in order to talk to the memory controller
+ * - HPET is enabled because FSP wants to store a pointer to global data in the
+ *   HPET comparator register
+ */
+static int arch_cpu_init_spl(void)
+{
+	struct udevice *pmc, *p2sb;
+	int ret;
+
+	ret = uclass_first_device_err(UCLASS_ACPI_PMC, &pmc);
+	if (ret)
+		return log_msg_ret("Could not probe PMC", ret);
+	ret = uclass_first_device_err(UCLASS_P2SB, &p2sb);
+	if (ret)
+		return log_msg_ret("Cannot set up p2sb", ret);
+
+	lpc_io_setup_comm_a_b();
+
+	/* TODO(sjg at chromium.org): Enable upper RTC bank here */
+
+	ret = pmc_init(pmc);
+	if (ret < 0)
+		return log_msg_ret("Could not init PMC", ret);
+#ifdef CONFIG_HAVE_ACPI_RESUME
+	ret = pmc_prev_sleep_state(pmc);
+	if (ret < 0)
+		return log_msg_ret("Could not get PMC sleep state", ret);
+	gd->arch.prev_sleep_state = ret;
+#endif
+
+	return 0;
+}
+
+int arch_cpu_init(void)
+{
+	int ret = 0;
+
+	if (spl_phase() == PHASE_TPL)
+		ret = arch_cpu_init_tpl();
+	else if (spl_phase() == PHASE_SPL)
+		ret = arch_cpu_init_spl();
+	if (ret)
+		printf("%s: Error %d\n", __func__, ret);
+
+	return ret;
+}
-- 
2.24.0.393.g34dc348eaf-goog

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v7 13/17] x86: apl: Add P2SB driver
  2019-12-09  0:40 [PATCH v7 04/17] x86: apl: Add hostbridge driver Simon Glass
                   ` (7 preceding siblings ...)
  2019-12-09  0:40 ` [PATCH v7 12/17] x86: apl: Add SPL/TPL init Simon Glass
@ 2019-12-09  0:40 ` Simon Glass
  2019-12-10 14:11   ` Bin Meng
  2019-12-09  0:40 ` [PATCH v7 14/17] x86: apl: Add Kconfig and Makefile Simon Glass
                   ` (4 subsequent siblings)
  13 siblings, 1 reply; 29+ messages in thread
From: Simon Glass @ 2019-12-09  0:40 UTC (permalink / raw)
  To: u-boot

Adds a driver for the Apollo Lake Primary-to-sideband bus. This supports
various child devices. It supposed both device tree and of-platdata.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v7:
- Update comment in apl_p2sb_early_init()

Changes in v6: None
Changes in v5: None
Changes in v4:
- Detect zero mmio address
- Use BIT() macro bit more
- apollolake -> Apollo Lake

Changes in v3:
- Use pci_get_devfn()

Changes in v2: None

 arch/x86/cpu/apollolake/Makefile |   1 +
 arch/x86/cpu/apollolake/p2sb.c   | 166 +++++++++++++++++++++++++++++++
 2 files changed, 167 insertions(+)
 create mode 100644 arch/x86/cpu/apollolake/p2sb.c

diff --git a/arch/x86/cpu/apollolake/Makefile b/arch/x86/cpu/apollolake/Makefile
index edde122f75..dc6df15dab 100644
--- a/arch/x86/cpu/apollolake/Makefile
+++ b/arch/x86/cpu/apollolake/Makefile
@@ -15,6 +15,7 @@ endif
 obj-y += hostbridge.o
 obj-y += itss.o
 obj-y += lpc.o
+obj-y += p2sb.o
 obj-y += pch.o
 obj-y += pmc.o
 obj-y += uart.o
diff --git a/arch/x86/cpu/apollolake/p2sb.c b/arch/x86/cpu/apollolake/p2sb.c
new file mode 100644
index 0000000000..eb27861b7a
--- /dev/null
+++ b/arch/x86/cpu/apollolake/p2sb.c
@@ -0,0 +1,166 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Primary-to-Sideband Bridge
+ *
+ * Copyright 2019 Google LLC
+ */
+
+#define LOG_CATEGORY UCLASS_P2SB
+
+#include <common.h>
+#include <dm.h>
+#include <dt-structs.h>
+#include <p2sb.h>
+#include <spl.h>
+#include <asm/pci.h>
+
+struct p2sb_platdata {
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+	struct dtd_intel_apl_p2sb dtplat;
+#endif
+	ulong mmio_base;
+	pci_dev_t bdf;
+};
+
+/* PCI config space registers */
+#define HPTC_OFFSET		0x60
+#define HPTC_ADDR_ENABLE_BIT	BIT(7)
+
+/* High Performance Event Timer Configuration */
+#define P2SB_HPTC				0x60
+#define P2SB_HPTC_ADDRESS_ENABLE		BIT(7)
+
+/*
+ * ADDRESS_SELECT            ENCODING_RANGE
+ *      0                 0xfed0 0000 - 0xfed0 03ff
+ *      1                 0xfed0 1000 - 0xfed0 13ff
+ *      2                 0xfed0 2000 - 0xfed0 23ff
+ *      3                 0xfed0 3000 - 0xfed0 33ff
+ */
+#define P2SB_HPTC_ADDRESS_SELECT_0		(0 << 0)
+#define P2SB_HPTC_ADDRESS_SELECT_1		(1 << 0)
+#define P2SB_HPTC_ADDRESS_SELECT_2		(2 << 0)
+#define P2SB_HPTC_ADDRESS_SELECT_3		(3 << 0)
+
+/*
+ * apl_p2sb_early_init() - Enable decoding for HPET range
+ *
+ * This is needed by FSP-M which uses the High Precision Event Timer.
+ *
+ * @dev: P2SB device
+ * @return 0 if OK, -ve on error
+ */
+static int apl_p2sb_early_init(struct udevice *dev)
+{
+	struct p2sb_platdata *plat = dev_get_platdata(dev);
+	pci_dev_t pdev = plat->bdf;
+
+	/*
+	 * Enable decoding for HPET memory address range.
+	 * HPTC_OFFSET(0x60) bit 7, when set the P2SB will decode
+	 * the High Performance Timer memory address range
+	 * selected by bits 1:0
+	 */
+	pci_x86_write_config(pdev, HPTC_OFFSET, HPTC_ADDR_ENABLE_BIT,
+			     PCI_SIZE_8);
+
+	/* Enable PCR Base address in PCH */
+	pci_x86_write_config(pdev, PCI_BASE_ADDRESS_0, plat->mmio_base,
+			     PCI_SIZE_32);
+	pci_x86_write_config(pdev, PCI_BASE_ADDRESS_1, 0, PCI_SIZE_32);
+
+	/* Enable P2SB MSE */
+	pci_x86_write_config(pdev, PCI_COMMAND, PCI_COMMAND_MASTER |
+			     PCI_COMMAND_MEMORY, PCI_SIZE_8);
+
+	return 0;
+}
+
+static int apl_p2sb_spl_init(struct udevice *dev)
+{
+	/* Enable decoding for HPET. Needed for FSP global pointer storage */
+	dm_pci_write_config(dev, P2SB_HPTC, P2SB_HPTC_ADDRESS_SELECT_0 |
+			    P2SB_HPTC_ADDRESS_ENABLE, PCI_SIZE_8);
+
+	return 0;
+}
+
+int apl_p2sb_ofdata_to_platdata(struct udevice *dev)
+{
+	struct p2sb_uc_priv *upriv = dev_get_uclass_priv(dev);
+	struct p2sb_platdata *plat = dev_get_platdata(dev);
+
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
+	int ret;
+
+	if (spl_phase() == PHASE_TPL) {
+		u32 base[2];
+
+		/* TPL sets up the initial BAR */
+		ret = dev_read_u32_array(dev, "early-regs", base,
+					 ARRAY_SIZE(base));
+		if (ret)
+			return log_msg_ret("Missing/short early-regs", ret);
+		plat->mmio_base = base[0];
+		plat->bdf = pci_get_devfn(dev);
+		if (plat->bdf < 0)
+			return log_msg_ret("Cannot get p2sb PCI address",
+					   plat->bdf);
+	} else {
+		plat->mmio_base = dev_read_addr_pci(dev);
+		/* Don't set BDF since it should not be used */
+		if (!plat->mmio_base || plat->mmio_base == FDT_ADDR_T_NONE)
+			return -EINVAL;
+	}
+#else
+	plat->mmio_base = plat->dtplat.early_regs[0];
+	plat->bdf = pci_ofplat_get_devfn(plat->dtplat.reg[0]);
+#endif
+	upriv->mmio_base = plat->mmio_base;
+	debug("p2sb: mmio_base=%x\n", (uint)plat->mmio_base);
+
+	return 0;
+}
+
+static int apl_p2sb_probe(struct udevice *dev)
+{
+	if (spl_phase() == PHASE_TPL)
+		return apl_p2sb_early_init(dev);
+	else if (spl_phase() == PHASE_SPL)
+		return apl_p2sb_spl_init(dev);
+
+	return 0;
+}
+
+static int p2sb_child_post_bind(struct udevice *dev)
+{
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
+	struct p2sb_child_platdata *pplat = dev_get_parent_platdata(dev);
+	int ret;
+	u32 pid;
+
+	ret = dev_read_u32(dev, "intel,p2sb-port-id", &pid);
+	if (ret)
+		return ret;
+	pplat->pid = pid;
+#endif
+
+	return 0;
+}
+
+static const struct udevice_id apl_p2sb_ids[] = {
+	{ .compatible = "intel,apl-p2sb" },
+	{ }
+};
+
+U_BOOT_DRIVER(apl_p2sb_drv) = {
+	.name		= "intel_apl_p2sb",
+	.id		= UCLASS_P2SB,
+	.of_match	= apl_p2sb_ids,
+	.probe		= apl_p2sb_probe,
+	.ofdata_to_platdata = apl_p2sb_ofdata_to_platdata,
+	.platdata_auto_alloc_size = sizeof(struct p2sb_platdata),
+	.per_child_platdata_auto_alloc_size =
+		sizeof(struct p2sb_child_platdata),
+	.child_post_bind = p2sb_child_post_bind,
+};
-- 
2.24.0.393.g34dc348eaf-goog

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v7 14/17] x86: apl: Add Kconfig and Makefile
  2019-12-09  0:40 [PATCH v7 04/17] x86: apl: Add hostbridge driver Simon Glass
                   ` (8 preceding siblings ...)
  2019-12-09  0:40 ` [PATCH v7 13/17] x86: apl: Add P2SB driver Simon Glass
@ 2019-12-09  0:40 ` Simon Glass
  2019-12-15  0:45   ` Bin Meng
  2019-12-09  0:40 ` [PATCH v7 15/17] x86: apl: Add FSP structures Simon Glass
                   ` (3 subsequent siblings)
  13 siblings, 1 reply; 29+ messages in thread
From: Simon Glass @ 2019-12-09  0:40 UTC (permalink / raw)
  To: u-boot

Add basic plumbing to allow Apollo Lake support to be used.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

Changes in v7: None
Changes in v6:
- Make BOOT_FROM_FAST_SPI_FLASH a Kconfig option

Changes in v5:
- Enable SMP

Changes in v4:
- Enable HAVE_X86_FIT
- Enable INTEL_GPIO
- Switch over to use pinctrl for pad init/config
- Use existing VBT Kconfig option
- apollolake -> Apollo Lake

Changes in v3:
- Add MMC, video, USB configs
- Add an APL_SPI_FLASH_BOOT option to enable non-mmap boot
- Fix the incorrect value of CPU_ADDR_BITS

Changes in v2: None

 arch/x86/Kconfig                |  1 +
 arch/x86/cpu/Makefile           |  1 +
 arch/x86/cpu/apollolake/Kconfig | 96 +++++++++++++++++++++++++++++++++
 3 files changed, 98 insertions(+)
 create mode 100644 arch/x86/cpu/apollolake/Kconfig

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 1d08cb24fb..89b93e5de2 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -106,6 +106,7 @@ source "board/google/Kconfig"
 source "board/intel/Kconfig"
 
 # platform-specific options below
+source "arch/x86/cpu/apollolake/Kconfig"
 source "arch/x86/cpu/baytrail/Kconfig"
 source "arch/x86/cpu/braswell/Kconfig"
 source "arch/x86/cpu/broadwell/Kconfig"
diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile
index 0e90a38dc5..5b40838e60 100644
--- a/arch/x86/cpu/Makefile
+++ b/arch/x86/cpu/Makefile
@@ -41,6 +41,7 @@ extra-y += call32.o
 endif
 
 obj-y += intel_common/
+obj-$(CONFIG_INTEL_APOLLOLAKE) += apollolake/
 obj-$(CONFIG_INTEL_BAYTRAIL) += baytrail/
 obj-$(CONFIG_INTEL_BRASWELL) += braswell/
 obj-$(CONFIG_INTEL_BROADWELL) += broadwell/
diff --git a/arch/x86/cpu/apollolake/Kconfig b/arch/x86/cpu/apollolake/Kconfig
new file mode 100644
index 0000000000..fcff176c27
--- /dev/null
+++ b/arch/x86/cpu/apollolake/Kconfig
@@ -0,0 +1,96 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright 2019 Google LLC
+#
+
+config INTEL_APOLLOLAKE
+	bool
+	select FSP_VERSION2
+	select HAVE_FSP
+	select ARCH_MISC_INIT
+	select USE_CAR
+	select INTEL_PMC
+	select TPL_X86_TSC_TIMER_NATIVE
+	select SPL_PCH_SUPPORT
+	select TPL_PCH_SUPPORT
+	select PCH_SUPPORT
+	select P2SB
+	imply ENABLE_MRC_CACHE
+	imply AHCI_PCI
+	imply SCSI
+	imply SCSI_AHCI
+	imply SPI_FLASH
+	imply USB
+	imply USB_EHCI_HCD
+	imply TPL
+	imply SPL
+	imply TPL_X86_16BIT_INIT
+	imply TPL_OF_PLATDATA
+	imply ACPI_PMC
+	imply MMC
+	imply DM_MMC
+	imply MMC_PCI
+	imply MMC_SDHCI
+	imply CMD_MMC
+	imply VIDEO_FSP
+	imply PINCTRL_INTEL
+	imply PINCTRL_INTEL_APL
+	imply HAVE_VBT
+	imply HAVE_X86_FIT
+	imply INTEL_GPIO
+	imply SMP
+
+if INTEL_APOLLOLAKE
+
+config DCACHE_RAM_BASE
+	default 0xfef00000
+
+config DCACHE_RAM_SIZE
+	default 0xc0000
+
+config DCACHE_RAM_MRC_VAR_SIZE
+	default 0xb0000
+
+config CPU_SPECIFIC_OPTIONS
+	def_bool y
+	select SMM_TSEG
+	select X86_RAMTEST
+
+config SMM_TSEG_SIZE
+	hex
+	default 0x800000
+
+config MMCONF_BASE_ADDRESS
+	hex
+	default 0xe0000000
+
+config TPL_SIZE_LIMIT
+	default 0x7800
+
+config CPU_ADDR_BITS
+	default 39
+
+config APL_SPI_FLASH_BOOT
+	bool "Support booting with SPI-flash driver instead memory-mapped SPI"
+	select TPL_SPI_FLASH_SUPPORT
+	select TPL_SPI_SUPPORT
+	help
+	  This enables SPI and SPI flash in TPL. Without the this only
+	  available boot method is to use memory-mapped SPI. Since this is
+	  actually fast and produces a TPL which is 7KB smaller, memory-mapped
+	  SPI is the default.
+
+config APL_BOOT_FROM_FAST_SPI_FLASH
+	bool "Boot using SPI flash driver"
+	select APL_SPI_FLASH_BOOT
+	help
+	  This option is separate from APL_SPI_FLASH_BOOT since it is useful to
+	  be able to compare booting speed with the same build. Enable this to
+	  use the SPI-flash driver to load SPL, U-Boot and FSP-M. For technical
+	  reasons FSP-S is currently always loaded from memory-mapped SPI. See
+	  Apollo Lake's arch_fsp_init_r() for details about that.
+
+config VBT_ADDR
+	default 0xff3f1000
+
+endif
-- 
2.24.0.393.g34dc348eaf-goog

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v7 15/17] x86: apl: Add FSP structures
  2019-12-09  0:40 [PATCH v7 04/17] x86: apl: Add hostbridge driver Simon Glass
                   ` (9 preceding siblings ...)
  2019-12-09  0:40 ` [PATCH v7 14/17] x86: apl: Add Kconfig and Makefile Simon Glass
@ 2019-12-09  0:40 ` Simon Glass
  2019-12-15  0:46   ` Bin Meng
  2019-12-09  0:40 ` [PATCH v7 16/17] x86: apl: Add FSP support Simon Glass
                   ` (2 subsequent siblings)
  13 siblings, 1 reply; 29+ messages in thread
From: Simon Glass @ 2019-12-09  0:40 UTC (permalink / raw)
  To: u-boot

These are mostly specific to a particular SoC. Add the definitions for
Apollo Lake.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

Changes in v7: None
Changes in v6:
- Fix FSP-M and FSP-S in comments

Changes in v5: None
Changes in v4:
- apollolake -> Apollo Lake

Changes in v3:
- Add VBT signature
- Add structures for FSP-S also
- Drop struct fsp_usp_header as it is now in the API file

Changes in v2: None

 .../asm/arch-apollolake/fsp/fsp_configs.h     |  14 +
 .../asm/arch-apollolake/fsp/fsp_m_upd.h       | 123 ++++++++
 .../asm/arch-apollolake/fsp/fsp_s_upd.h       | 292 ++++++++++++++++++
 .../include/asm/arch-apollolake/fsp/fsp_vpd.h |  11 +
 4 files changed, 440 insertions(+)
 create mode 100644 arch/x86/include/asm/arch-apollolake/fsp/fsp_configs.h
 create mode 100644 arch/x86/include/asm/arch-apollolake/fsp/fsp_m_upd.h
 create mode 100644 arch/x86/include/asm/arch-apollolake/fsp/fsp_s_upd.h
 create mode 100644 arch/x86/include/asm/arch-apollolake/fsp/fsp_vpd.h

diff --git a/arch/x86/include/asm/arch-apollolake/fsp/fsp_configs.h b/arch/x86/include/asm/arch-apollolake/fsp/fsp_configs.h
new file mode 100644
index 0000000000..9185d94b2b
--- /dev/null
+++ b/arch/x86/include/asm/arch-apollolake/fsp/fsp_configs.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: Intel */
+/*
+ * Copyright 2019 Google LLC
+ */
+
+#ifndef __FSP_CONFIGS_H__
+#define __FSP_CONFIGS_H__
+
+#define FSPT_UPD_SIGNATURE	0x545F4450554C5041	/* 'APLUPD_T' */
+#define FSPM_UPD_SIGNATURE	0x4D5F4450554C5041	/* 'APLUPD_M' */
+#define FSPS_UPD_SIGNATURE	0x535F4450554C5041	/* 'APLUPD_S' */
+#define VBT_SIGNATURE		0x54425624
+
+#endif
diff --git a/arch/x86/include/asm/arch-apollolake/fsp/fsp_m_upd.h b/arch/x86/include/asm/arch-apollolake/fsp/fsp_m_upd.h
new file mode 100644
index 0000000000..93bee5b2d1
--- /dev/null
+++ b/arch/x86/include/asm/arch-apollolake/fsp/fsp_m_upd.h
@@ -0,0 +1,123 @@
+/* SPDX-License-Identifier: Intel */
+/*
+ * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright 2019 Google LLC
+ */
+
+#ifndef	__ASM_ARCH_FSP_M_UDP_H
+#define	__ASM_ARCH_FSP_M_UDP_H
+
+#include <asm/fsp2/fsp_api.h>
+
+#define FSP_DRAM_CHANNELS	4
+
+struct __packed fspm_arch_upd {
+	u8	revision;
+	u8	reserved[3];
+	void	*nvs_buffer_ptr;
+	void	*stack_base;
+	u32	stack_size;
+	u32	boot_loader_tolum_size;
+	u32	boot_mode;
+	u8	reserved1[8];
+};
+
+struct __packed fsp_ram_channel {
+	u8	rank_enable;
+	u8	device_width;
+	u8	dram_density;
+	u8	option;
+	u8	odt_config;
+	u8	tristate_clk1;
+	u8	mode2_n;
+	u8	odt_levels;
+};
+
+struct __packed fsp_m_config {
+	u32	serial_debug_port_address;
+	u8	serial_debug_port_type;
+	u8	serial_debug_port_device;
+	u8	serial_debug_port_stride_size;
+	u8	mrc_fast_boot;
+	u8	igd;
+	u8	igd_dvmt50_pre_alloc;
+	u8	igd_aperture_size;
+	u8	gtt_size;
+	u8	primary_video_adaptor;
+	u8	package;
+	u8	profile;
+	u8	memory_down;
+
+	u8	ddr3_l_page_size;
+	u8	ddr3_lasr;
+	u8	scrambler_support;
+	u8	interleaved_mode;
+	u16	channel_hash_mask;
+	u16	slice_hash_mask;
+	u8	channels_slices_enable;
+	u8	min_ref_rate2x_enable;
+	u8	dual_rank_support_enable;
+	u8	rmt_mode;
+	u16	memory_size_limit;
+	u16	low_memory_max_value;
+
+	u16	high_memory_max_value;
+	u8	disable_fast_boot;
+	u8	dimm0_spd_address;
+	u8	dimm1_spd_address;
+	struct fsp_ram_channel chan[FSP_DRAM_CHANNELS];
+	u8	rmt_check_run;
+	u16	rmt_margin_check_scale_high_threshold;
+	u8	ch_bit_swizzling[FSP_DRAM_CHANNELS][32];
+	u32	msg_level_mask;
+	u8	unused_upd_space0[4];
+
+	u8	pre_mem_gpio_table_pin_num[4];
+	u32	pre_mem_gpio_table_ptr;
+	u8	pre_mem_gpio_table_entry_num;
+	u8	enhance_port8xh_decoding;
+	u8	spd_write_enable;
+	u8	mrc_data_saving;
+	u32	oem_loading_base;
+
+	u8	oem_file_name[16];
+
+	void	*mrc_boot_data_ptr;
+	u8	e_mmc_trace_len;
+	u8	skip_cse_rbp;
+	u8	npk_en;
+	u8	fw_trace_en;
+	u8	fw_trace_destination;
+	u8	recover_dump;
+	u8	msc0_wrap;
+	u8	msc1_wrap;
+	u32	msc0_size;
+
+	u32	msc1_size;
+	u8	pti_mode;
+	u8	pti_training;
+	u8	pti_speed;
+	u8	punit_mlvl;
+
+	u8	pmc_mlvl;
+	u8	sw_trace_en;
+	u8	periodic_retraining_disable;
+	u8	enable_reset_system;
+
+	u8	enable_s3_heci2;
+	u8	unused_upd_space1[3];
+
+	void	*variable_nvs_buffer_ptr;
+	u8	reserved_fspm_upd[12];
+};
+
+/** FSP-M UPD Configuration */
+struct __packed fspm_upd {
+	struct fsp_upd_header header;
+	struct fspm_arch_upd arch;
+	struct fsp_m_config config;
+	u8 unused_upd_space2[158];
+	u16 upd_terminator;
+};
+
+#endif
diff --git a/arch/x86/include/asm/arch-apollolake/fsp/fsp_s_upd.h b/arch/x86/include/asm/arch-apollolake/fsp/fsp_s_upd.h
new file mode 100644
index 0000000000..4a868e80ba
--- /dev/null
+++ b/arch/x86/include/asm/arch-apollolake/fsp/fsp_s_upd.h
@@ -0,0 +1,292 @@
+/* SPDX-License-Identifier: Intel */
+/*
+ * Copyright (c) 2016, Intel Corporation. All rights reserved.
+ * Copyright 2019 Google LLC
+ */
+#ifndef __ASM_ARCH_FSP_S_UDP_H
+#define __ASM_ARCH_FSP_S_UDP_H
+
+#include <asm/fsp2/fsp_api.h>
+
+struct __packed fsp_s_config {
+	u8	active_processor_cores;
+	u8	disable_core1;
+	u8	disable_core2;
+	u8	disable_core3;
+	u8	vmx_enable;
+	u8	proc_trace_mem_size;
+	u8	proc_trace_enable;
+	u8	eist;
+	u8	boot_p_state;
+	u8	enable_cx;
+	u8	c1e;
+	u8	bi_proc_hot;
+	u8	pkg_c_state_limit;
+	u8	c_state_auto_demotion;
+	u8	c_state_un_demotion;
+	u8	max_core_c_state;
+	u8	pkg_c_state_demotion;
+	u8	pkg_c_state_un_demotion;
+	u8	turbo_mode;
+	u8	hda_verb_table_entry_num;
+	u32	hda_verb_table_ptr;
+	u8	p2sb_unhide;
+	u8	ipu_en;
+	u8	ipu_acpi_mode;
+	u8	force_wake;
+	u32	gtt_mm_adr;
+	u32	gm_adr;
+	u8	pavp_lock;
+	u8	graphics_freq_modify;
+	u8	graphics_freq_req;
+	u8	graphics_video_freq;
+	u8	pm_lock;
+	u8	dop_clock_gating;
+	u8	unsolicited_attack_override;
+	u8	wopcm_support;
+	u8	wopcm_size;
+	u8	power_gating;
+	u8	unit_level_clock_gating;
+	u8	fast_boot;
+	u8	dyn_sr;
+	u8	sa_ipu_enable;
+	u8	pm_support;
+	u8	enable_render_standby;
+	u32	logo_size;
+	u32	logo_ptr;
+	u32	graphics_config_ptr;
+	u8	pavp_enable;
+	u8	pavp_pr3;
+	u8	cd_clock;
+	u8	pei_graphics_peim_init;
+	u8	write_protection_enable[5];
+	u8	read_protection_enable[5];
+	u16	protected_range_limit[5];
+	u16	protected_range_base[5];
+	u8	gmm;
+	u8	clk_gating_pgcb_clk_trunk;
+	u8	clk_gating_sb;
+	u8	clk_gating_sb_clk_trunk;
+	u8	clk_gating_sb_clk_partition;
+	u8	clk_gating_core;
+	u8	clk_gating_dma;
+	u8	clk_gating_reg_access;
+	u8	clk_gating_host;
+	u8	clk_gating_partition;
+	u8	clk_gating_trunk;
+	u8	hda_enable;
+	u8	dsp_enable;
+	u8	pme;
+	u8	hd_audio_io_buffer_ownership;
+	u8	hd_audio_io_buffer_voltage;
+	u8	hd_audio_vc_type;
+	u8	hd_audio_link_frequency;
+	u8	hd_audio_i_disp_link_frequency;
+	u8	hd_audio_i_disp_link_tmode;
+	u8	dsp_endpoint_dmic;
+	u8	dsp_endpoint_bluetooth;
+	u8	dsp_endpoint_i2s_skp;
+	u8	dsp_endpoint_i2s_hp;
+	u8	audio_ctl_pwr_gate;
+	u8	audio_dsp_pwr_gate;
+	u8	mmt;
+	u8	hmt;
+	u8	hd_audio_pwr_gate;
+	u8	hd_audio_clk_gate;
+	u32	dsp_feature_mask;
+	u32	dsp_pp_module_mask;
+	u8	bios_cfg_lock_down;
+	u8	hpet;
+	u8	hpet_bdf_valid;
+	u8	hpet_bus_number;
+	u8	hpet_device_number;
+	u8	hpet_function_number;
+	u8	io_apic_bdf_valid;
+	u8	io_apic_bus_number;
+	u8	io_apic_device_number;
+	u8	io_apic_function_number;
+	u8	io_apic_entry24_119;
+	u8	io_apic_id;
+	u8	io_apic_range_select;
+	u8	ish_enable;
+	u8	bios_interface;
+	u8	bios_lock;
+	u8	spi_eiss;
+	u8	bios_lock_sw_smi_number;
+	u8	lpss_s0ix_enable;
+	u8	unused_upd_space0[1];
+	u8	i2c_clk_gate_cfg[8];
+	u8	hsuart_clk_gate_cfg[4];
+	u8	spi_clk_gate_cfg[3];
+	u8	i2c0_enable;
+	u8	i2c1_enable;
+	u8	i2c2_enable;
+	u8	i2c3_enable;
+	u8	i2c4_enable;
+	u8	i2c5_enable;
+	u8	i2c6_enable;
+	u8	i2c7_enable;
+	u8	hsuart0_enable;
+	u8	hsuart1_enable;
+	u8	hsuart2_enable;
+	u8	hsuart3_enable;
+	u8	spi0_enable;
+	u8	spi1_enable;
+	u8	spi2_enable;
+	u8	os_dbg_enable;
+	u8	dci_en;
+	u32	uart2_kernel_debug_base_address;
+	u8	pcie_clock_gating_disabled;
+	u8	pcie_root_port8xh_decode;
+	u8	pcie8xh_decode_port_index;
+	u8	pcie_root_port_peer_memory_write_enable;
+	u8	pcie_aspm_sw_smi_number;
+	u8	unused_upd_space1[1];
+	u8	pcie_root_port_en[6];
+	u8	pcie_rp_hide[6];
+	u8	pcie_rp_slot_implemented[6];
+	u8	pcie_rp_hot_plug[6];
+	u8	pcie_rp_pm_sci[6];
+	u8	pcie_rp_ext_sync[6];
+	u8	pcie_rp_transmitter_half_swing[6];
+	u8	pcie_rp_acs_enabled[6];
+	u8	pcie_rp_clk_req_supported[6];
+	u8	pcie_rp_clk_req_number[6];
+	u8	pcie_rp_clk_req_detect[6];
+	u8	advanced_error_reporting[6];
+	u8	pme_interrupt[6];
+	u8	unsupported_request_report[6];
+	u8	fatal_error_report[6];
+	u8	no_fatal_error_report[6];
+	u8	correctable_error_report[6];
+	u8	system_error_on_fatal_error[6];
+	u8	system_error_on_non_fatal_error[6];
+	u8	system_error_on_correctable_error[6];
+	u8	pcie_rp_speed[6];
+	u8	physical_slot_number[6];
+	u8	pcie_rp_completion_timeout[6];
+	u8	ptm_enable[6];
+	u8	pcie_rp_aspm[6];
+	u8	pcie_rp_l1_substates[6];
+	u8	pcie_rp_ltr_enable[6];
+	u8	pcie_rp_ltr_config_lock[6];
+	u8	pme_b0_s5_dis;
+	u8	pci_clock_run;
+	u8	timer8254_clk_setting;
+	u8	enable_sata;
+	u8	sata_mode;
+	u8	sata_salp_support;
+	u8	sata_pwr_opt_enable;
+	u8	e_sata_speed_limit;
+	u8	speed_limit;
+	u8	unused_upd_space2[1];
+	u8	sata_ports_enable[2];
+	u8	sata_ports_dev_slp[2];
+	u8	sata_ports_hot_plug[2];
+	u8	sata_ports_interlock_sw[2];
+	u8	sata_ports_external[2];
+	u8	sata_ports_spin_up[2];
+	u8	sata_ports_solid_state_drive[2];
+	u8	sata_ports_enable_dito_config[2];
+	u8	sata_ports_dm_val[2];
+	u8	unused_upd_space3[2];
+	u16	sata_ports_dito_val[2];
+	u16	sub_system_vendor_id;
+	u16	sub_system_id;
+	u8	crid_settings;
+	u8	reset_select;
+	u8	sdcard_enabled;
+	u8	e_mmc_enabled;
+	u8	e_mmc_host_max_speed;
+	u8	ufs_enabled;
+	u8	sdio_enabled;
+	u8	gpp_lock;
+	u8	sirq_enable;
+	u8	sirq_mode;
+	u8	start_frame_pulse;
+	u8	smbus_enable;
+	u8	arp_enable;
+	u8	unused_upd_space4;
+	u16	num_rsvd_smbus_addresses;
+	u8	rsvd_smbus_address_table[128];
+	u8	disable_compliance_mode;
+	u8	usb_per_port_ctl;
+	u8	usb30_mode;
+	u8	unused_upd_space5[1];
+	u8	port_usb20_enable[8];
+	u8	port_us20b_over_current_pin[8];
+	u8	usb_otg;
+	u8	hsic_support_enable;
+	u8	port_usb30_enable[6];
+	u8	port_us30b_over_current_pin[6];
+	u8	ssic_port_enable[2];
+	u16	dlane_pwr_gating;
+	u8	vtd_enable;
+	u8	lock_down_global_smi;
+	u16	reset_wait_timer;
+	u8	rtc_lock;
+	u8	sata_test_mode;
+	u8	ssic_rate[2];
+	u16	dynamic_power_gating;
+	u16	pcie_rp_ltr_max_snoop_latency[6];
+	u8	pcie_rp_snoop_latency_override_mode[6];
+	u8	unused_upd_space6[2];
+	u16	pcie_rp_snoop_latency_override_value[6];
+	u8	pcie_rp_snoop_latency_override_multiplier[6];
+	u8	skip_mp_init;
+	u8	dci_auto_detect;
+	u16	pcie_rp_ltr_max_non_snoop_latency[6];
+	u8	pcie_rp_non_snoop_latency_override_mode[6];
+	u8	tco_timer_halt_lock;
+	u8	pwr_btn_override_period;
+	u16	pcie_rp_non_snoop_latency_override_value[6];
+	u8	pcie_rp_non_snoop_latency_override_multiplier[6];
+	u8	pcie_rp_slot_power_limit_scale[6];
+	u8	pcie_rp_slot_power_limit_value[6];
+	u8	disable_native_power_button;
+	u8	power_butter_debounce_mode;
+	u32	sdio_tx_cmd_cntl;
+	u32	sdio_tx_data_cntl1;
+	u32	sdio_tx_data_cntl2;
+	u32	sdio_rx_cmd_data_cntl1;
+	u32	sdio_rx_cmd_data_cntl2;
+	u32	sdcard_tx_cmd_cntl;
+	u32	sdcard_tx_data_cntl1;
+	u32	sdcard_tx_data_cntl2;
+	u32	sdcard_rx_cmd_data_cntl1;
+	u32	sdcard_rx_strobe_cntl;
+	u32	sdcard_rx_cmd_data_cntl2;
+	u32	emmc_tx_cmd_cntl;
+	u32	emmc_tx_data_cntl1;
+	u32	emmc_tx_data_cntl2;
+	u32	emmc_rx_cmd_data_cntl1;
+	u32	emmc_rx_strobe_cntl;
+	u32	emmc_rx_cmd_data_cntl2;
+	u32	emmc_master_sw_cntl;
+	u8	pcie_rp_selectable_deemphasis[6];
+	u8	monitor_mwait_enable;
+	u8	hd_audio_dsp_uaa_compliance;
+	u32	ipc[4];
+	u8	sata_ports_disable_dynamic_pg[2];
+	u8	init_s3_cpu;
+	u8	skip_punit_init;
+	u8	unused_upd_space7[4];
+	u8	port_usb20_per_port_tx_pe_half[8];
+	u8	port_usb20_per_port_pe_txi_set[8];
+	u8	port_usb20_per_port_txi_set[8];
+	u8	port_usb20_hs_skew_sel[8];
+	u8	port_usb20_i_usb_tx_emphasis_en[8];
+	u8	port_usb20_per_port_rxi_set[8];
+	u8	port_usb20_hs_npre_drv_sel[8];
+	u8	reserved_fsps_upd[16];
+};
+
+/** struct fsps_upd - FSP-S Configuration */
+struct __packed fsps_upd {
+	struct fsp_upd_header header;
+	struct fsp_s_config config;
+	u8 unused_upd_space2[46];
+	u16 upd_terminator;
+};
+
+#endif
diff --git a/arch/x86/include/asm/arch-apollolake/fsp/fsp_vpd.h b/arch/x86/include/asm/arch-apollolake/fsp/fsp_vpd.h
new file mode 100644
index 0000000000..b14f28b236
--- /dev/null
+++ b/arch/x86/include/asm/arch-apollolake/fsp/fsp_vpd.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: Intel */
+/*
+ * Copyright 2019 Google LLC
+ */
+
+#ifndef __FSP_VPD_H
+#define __FSP_VPD_H
+
+/* Nothing to declare here for FSP2 */
+
+#endif
-- 
2.24.0.393.g34dc348eaf-goog

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v7 16/17] x86: apl: Add FSP support
  2019-12-09  0:40 [PATCH v7 04/17] x86: apl: Add hostbridge driver Simon Glass
                   ` (10 preceding siblings ...)
  2019-12-09  0:40 ` [PATCH v7 15/17] x86: apl: Add FSP structures Simon Glass
@ 2019-12-09  0:40 ` Simon Glass
  2019-12-15  0:46   ` Bin Meng
  2019-12-09  0:40 ` [PATCH v7 17/17] x86: Add chromebook_coral Simon Glass
  2019-12-15  0:36 ` [PATCH v7 04/17] x86: apl: Add hostbridge driver Bin Meng
  13 siblings, 1 reply; 29+ messages in thread
From: Simon Glass @ 2019-12-09  0:40 UTC (permalink / raw)
  To: u-boot

The memory and silicon init parts of the FSP need support code to work.
Add this for Apollo Lake.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

Changes in v7: None
Changes in v6:
- Drop mention of devicetree for VTD feature
- Drop mention of ramstage
- Fix various coding style problems
- Make BOOT_FROM_FAST_SPI_FLASH a Kconfig option
- Use 'No SPI' instead of 'SPI2' as a debug message

Changes in v5:
- Allocate the FSP-S data instead of using the stack
- Rename APOLLOLAKE_USB2_PORT_MAX

Changes in v4:
- Adjust the comment for struct dw_i2c_speed_config
- Rename arch_fsp_s_preinit() to arch_fsps_preinit()
- Switch over to use pinctrl for pad init/config
- Tidy up mixed case in FSP code
- apollolake -> Apollo Lake

Changes in v3:
- Add bootstage timing for reading vbt
- Add fspm_done() hook to handle FSP-S wierdness (it breaks SPI flash)
- Don't allow BOOT_FROM_FAST_SPI_FLASH with FSP-S
- Set boot_loader_tolum_size to 0
- Use the IRQ uclass instead of ITSS

Changes in v2: None

 arch/x86/cpu/apollolake/Makefile |   6 +
 arch/x86/cpu/apollolake/fsp_m.c  | 210 ++++++++++
 arch/x86/cpu/apollolake/fsp_s.c  | 661 +++++++++++++++++++++++++++++++
 3 files changed, 877 insertions(+)
 create mode 100644 arch/x86/cpu/apollolake/fsp_m.c
 create mode 100644 arch/x86/cpu/apollolake/fsp_s.c

diff --git a/arch/x86/cpu/apollolake/Makefile b/arch/x86/cpu/apollolake/Makefile
index dc6df15dab..1760df54d8 100644
--- a/arch/x86/cpu/apollolake/Makefile
+++ b/arch/x86/cpu/apollolake/Makefile
@@ -10,6 +10,12 @@ obj-y += cpu_common.o
 ifndef CONFIG_TPL_BUILD
 obj-y += cpu.o
 obj-y += punit.o
+ifdef CONFIG_SPL_BUILD
+obj-y += fsp_m.o
+endif
+endif
+ifndef CONFIG_SPL_BUILD
+obj-y += fsp_s.o
 endif
 
 obj-y += hostbridge.o
diff --git a/arch/x86/cpu/apollolake/fsp_m.c b/arch/x86/cpu/apollolake/fsp_m.c
new file mode 100644
index 0000000000..5308af8ed4
--- /dev/null
+++ b/arch/x86/cpu/apollolake/fsp_m.c
@@ -0,0 +1,210 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2019 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <asm/arch/iomap.h>
+#include <asm/arch/fsp/fsp_configs.h>
+#include <asm/arch/fsp/fsp_m_upd.h>
+#include <asm/fsp2/fsp_internal.h>
+#include <dm/uclass-internal.h>
+
+/*
+ * ODT settings:
+ * If ODT PIN to LP4 DRAM is pulled HIGH for ODT_A and HIGH for ODT_B,
+ * choose ODT_A_B_HIGH_HIGH. If ODT PIN to LP4 DRAM is pulled HIGH for ODT_A
+ * and LOW for ODT_B, choose ODT_A_B_HIGH_LOW.
+ *
+ * Note that the enum values correspond to the interpreted UPD fields
+ * within Ch[3:0]_OdtConfig parameters.
+ */
+enum {
+	ODT_A_B_HIGH_LOW	= 0 << 1,
+	ODT_A_B_HIGH_HIGH	= 1 << 1,
+	N_WR_24			= 1 << 5,
+};
+
+/*
+ * LPDDR4 helper routines for configuring the memory UPD for LPDDR4 operation.
+ * There are four physical LPDDR4 channels, each 32-bits wide. There are two
+ * logical channels using two physical channels together to form a 64-bit
+ * interface to memory for each logical channel.
+ */
+
+enum {
+	LP4_PHYS_CH0A,
+	LP4_PHYS_CH0B,
+	LP4_PHYS_CH1A,
+	LP4_PHYS_CH1B,
+
+	LP4_NUM_PHYS_CHANNELS,
+};
+
+/*
+ * The DQs within a physical channel can be bit-swizzled within each byte.
+ * Within a channel the bytes can be swapped, but the DQs need to be routed
+ * with the corresponding DQS (strobe).
+ */
+enum {
+	LP4_DQS0,
+	LP4_DQS1,
+	LP4_DQS2,
+	LP4_DQS3,
+
+	LP4_NUM_BYTE_LANES,
+	DQ_BITS_PER_DQS		= 8,
+};
+
+/* Provide bit swizzling per DQS and byte swapping within a channel */
+struct lpddr4_chan_swizzle_cfg {
+	u8 dqs[LP4_NUM_BYTE_LANES][DQ_BITS_PER_DQS];
+};
+
+struct lpddr4_swizzle_cfg {
+	struct lpddr4_chan_swizzle_cfg phys[LP4_NUM_PHYS_CHANNELS];
+};
+
+static void setup_sdram(struct fsp_m_config *cfg,
+			const struct lpddr4_swizzle_cfg *swizzle_cfg)
+{
+	const struct lpddr4_chan_swizzle_cfg *sch;
+	/* Number of bytes to copy per DQS */
+	const size_t sz = DQ_BITS_PER_DQS;
+	int chan;
+
+	cfg->memory_down = 1;
+	cfg->scrambler_support = 1;
+	cfg->channel_hash_mask = 0x36;
+	cfg->slice_hash_mask = 9;
+	cfg->interleaved_mode = 2;
+	cfg->channels_slices_enable = 0;
+	cfg->min_ref_rate2x_enable = 0;
+	cfg->dual_rank_support_enable = 1;
+
+	/* LPDDR4 is memory down so no SPD addresses */
+	cfg->dimm0_spd_address = 0;
+	cfg->dimm1_spd_address = 0;
+
+	for (chan = 0; chan < 4; chan++) {
+		struct fsp_ram_channel *ch = &cfg->chan[chan];
+
+		ch->rank_enable = 1;
+		ch->device_width = 1;
+		ch->dram_density = 2;
+		ch->option = 3;
+		ch->odt_config = ODT_A_B_HIGH_HIGH;
+	}
+
+	/*
+	 * CH0_DQB byte lanes in the bit swizzle configuration field are
+	 * not 1:1. The mapping within the swizzling field is:
+	 *   indices [0:7]   - byte lane 1 (DQS1) DQ[8:15]
+	 *   indices [8:15]  - byte lane 0 (DQS0) DQ[0:7]
+	 *   indices [16:23] - byte lane 3 (DQS3) DQ[24:31]
+	 *   indices [24:31] - byte lane 2 (DQS2) DQ[16:23]
+	 */
+	sch = &swizzle_cfg->phys[LP4_PHYS_CH0B];
+	memcpy(&cfg->ch_bit_swizzling[0][0], &sch->dqs[LP4_DQS1], sz);
+	memcpy(&cfg->ch_bit_swizzling[0][8], &sch->dqs[LP4_DQS0], sz);
+	memcpy(&cfg->ch_bit_swizzling[0][16], &sch->dqs[LP4_DQS3], sz);
+	memcpy(&cfg->ch_bit_swizzling[0][24], &sch->dqs[LP4_DQS2], sz);
+
+	/*
+	 * CH0_DQA byte lanes in the bit swizzle configuration field are 1:1.
+	 */
+	sch = &swizzle_cfg->phys[LP4_PHYS_CH0A];
+	memcpy(&cfg->ch_bit_swizzling[1][0], &sch->dqs[LP4_DQS0], sz);
+	memcpy(&cfg->ch_bit_swizzling[1][8], &sch->dqs[LP4_DQS1], sz);
+	memcpy(&cfg->ch_bit_swizzling[1][16], &sch->dqs[LP4_DQS2], sz);
+	memcpy(&cfg->ch_bit_swizzling[1][24], &sch->dqs[LP4_DQS3], sz);
+
+	sch = &swizzle_cfg->phys[LP4_PHYS_CH1B];
+	memcpy(&cfg->ch_bit_swizzling[2][0], &sch->dqs[LP4_DQS1], sz);
+	memcpy(&cfg->ch_bit_swizzling[2][8], &sch->dqs[LP4_DQS0], sz);
+	memcpy(&cfg->ch_bit_swizzling[2][16], &sch->dqs[LP4_DQS3], sz);
+	memcpy(&cfg->ch_bit_swizzling[2][24], &sch->dqs[LP4_DQS2], sz);
+
+	/*
+	 * CH0_DQA byte lanes in the bit swizzle configuration field are 1:1.
+	 */
+	sch = &swizzle_cfg->phys[LP4_PHYS_CH1A];
+	memcpy(&cfg->ch_bit_swizzling[3][0], &sch->dqs[LP4_DQS0], sz);
+	memcpy(&cfg->ch_bit_swizzling[3][8], &sch->dqs[LP4_DQS1], sz);
+	memcpy(&cfg->ch_bit_swizzling[3][16], &sch->dqs[LP4_DQS2], sz);
+	memcpy(&cfg->ch_bit_swizzling[3][24], &sch->dqs[LP4_DQS3], sz);
+}
+
+int fspm_update_config(struct udevice *dev, struct fspm_upd *upd)
+{
+	struct fsp_m_config *cfg = &upd->config;
+	struct fspm_arch_upd *arch = &upd->arch;
+
+	arch->nvs_buffer_ptr = NULL;
+	prepare_mrc_cache(upd);
+	arch->stack_base = (void *)0xfef96000;
+	arch->boot_loader_tolum_size = 0;
+
+	arch->boot_mode = FSP_BOOT_WITH_FULL_CONFIGURATION;
+	cfg->serial_debug_port_type = 2;
+	cfg->serial_debug_port_device = 2;
+	cfg->serial_debug_port_stride_size = 2;
+	cfg->serial_debug_port_address = 0;
+
+	cfg->package = 1;
+	/* Don't enforce a memory size limit */
+	cfg->memory_size_limit = 0;
+	cfg->low_memory_max_value = 2048;  /* 2 GB */
+	/* No restrictions on memory above 4GiB */
+	cfg->high_memory_max_value = 0;
+
+	/* Always default to attempt to use saved training data */
+	cfg->disable_fast_boot = 0;
+
+	const u8 *swizzle_data;
+
+	swizzle_data = dev_read_u8_array_ptr(dev, "lpddr4-swizzle",
+					     LP4_NUM_BYTE_LANES *
+					     DQ_BITS_PER_DQS *
+					     LP4_NUM_PHYS_CHANNELS);
+	if (!swizzle_data)
+		return log_msg_ret("Cannot read swizzel data", -EINVAL);
+
+	setup_sdram(cfg, (struct lpddr4_swizzle_cfg *)swizzle_data);
+
+	cfg->pre_mem_gpio_table_ptr = 0;
+
+	cfg->profile = 0xb;
+	cfg->msg_level_mask = 0;
+
+	/* other */
+	cfg->skip_cse_rbp = 1;
+	cfg->periodic_retraining_disable = 0;
+	cfg->enable_s3_heci2 = 0;
+
+	return 0;
+}
+
+/*
+ * The FSP-M binary appears to break the SPI controller. It can be fixed by
+ * writing the BAR again, so do that here
+ */
+int fspm_done(struct udevice *dev)
+{
+	struct udevice *spi;
+	int ret;
+
+	/* Don't probe the device, since that reads the BAR */
+	ret = uclass_find_first_device(UCLASS_SPI, &spi);
+	if (ret)
+		return log_msg_ret("SPI", ret);
+	if (!spi)
+		return log_msg_ret("no SPI", -ENODEV);
+
+	dm_pci_write_config32(spi, PCI_BASE_ADDRESS_0,
+			      IOMAP_SPI_BASE | PCI_BASE_ADDRESS_SPACE_MEMORY);
+
+	return 0;
+}
diff --git a/arch/x86/cpu/apollolake/fsp_s.c b/arch/x86/cpu/apollolake/fsp_s.c
new file mode 100644
index 0000000000..9804227f80
--- /dev/null
+++ b/arch/x86/cpu/apollolake/fsp_s.c
@@ -0,0 +1,661 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2019 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <common.h>
+#include <acpi_s3.h>
+#include <binman.h>
+#include <dm.h>
+#include <irq.h>
+#include <asm/intel_pinctrl.h>
+#include <asm/io.h>
+#include <asm/intel_regs.h>
+#include <asm/msr.h>
+#include <asm/msr-index.h>
+#include <asm/pci.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/systemagent.h>
+#include <asm/arch/fsp/fsp_configs.h>
+#include <asm/arch/fsp/fsp_s_upd.h>
+
+#define PCH_P2SB_E0		0xe0
+#define HIDE_BIT		BIT(0)
+
+#define INTEL_GSPI_MAX		3
+#define INTEL_I2C_DEV_MAX	8
+#define MAX_USB2_PORTS		8
+
+enum {
+	CHIPSET_LOCKDOWN_FSP = 0, /* FSP handles locking per UPDs */
+	CHIPSET_LOCKDOWN_COREBOOT, /* coreboot handles locking */
+};
+
+enum i2c_speed {
+	I2C_SPEED_STANDARD	= 100000,
+	I2C_SPEED_FAST		= 400000,
+	I2C_SPEED_FAST_PLUS	= 1000000,
+	I2C_SPEED_HIGH		= 3400000,
+	I2C_SPEED_FAST_ULTRA	= 5000000,
+};
+
+/*
+ * Timing values are in units of clock period, with the clock speed
+ * provided by the SOC
+ *
+ * TODO(sjg at chromium.org): Connect this up to the I2C driver
+ */
+struct dw_i2c_speed_config {
+	enum i2c_speed speed;
+	/* SCL high and low period count */
+	u16 scl_lcnt;
+	u16 scl_hcnt;
+	/*
+	 * SDA hold time should be 300ns in standard and fast modes
+	 * and long enough for deterministic logic level change in
+	 * fast-plus and high speed modes.
+	 *
+	 *  [15:0] SDA TX Hold Time
+	 * [23:16] SDA RX Hold Time
+	 */
+	u32 sda_hold;
+};
+
+/* Serial IRQ control. SERIRQ_QUIET is the default (0) */
+enum serirq_mode {
+	SERIRQ_QUIET,
+	SERIRQ_CONTINUOUS,
+	SERIRQ_OFF,
+};
+
+/*
+ * This I2C controller has support for 3 independent speed configs but can
+ * support both FAST_PLUS and HIGH speeds through the same set of speed
+ * config registers.  These are treated separately so the speed config values
+ * can be provided via ACPI to the OS.
+ */
+#define DW_I2C_SPEED_CONFIG_COUNT	4
+
+struct dw_i2c_bus_config {
+	/* Bus should be enabled in TPL with temporary base */
+	int early_init;
+	/* Bus speed in Hz, default is I2C_SPEED_FAST (400 KHz) */
+	enum i2c_speed speed;
+	/*
+	 * If rise_time_ns is non-zero the calculations for lcnt and hcnt
+	 * registers take into account the times of the bus. However, if
+	 * there is a match in speed_config those register values take
+	 * precedence
+	 */
+	int rise_time_ns;
+	int fall_time_ns;
+	int data_hold_time_ns;
+	/* Specific bus speed configuration */
+	struct dw_i2c_speed_config speed_config[DW_I2C_SPEED_CONFIG_COUNT];
+};
+
+struct gspi_cfg {
+	/* Bus speed in MHz */
+	u32 speed_mhz;
+	/* Bus should be enabled prior to ramstage with temporary base */
+	u8 early_init;
+};
+
+/*
+ * This structure will hold data required by common blocks.
+ * These are soc specific configurations which will be filled by soc.
+ * We'll fill this structure once during init and use the data in common block.
+ */
+struct soc_intel_common_config {
+	int chipset_lockdown;
+	struct gspi_cfg gspi[INTEL_GSPI_MAX];
+	struct dw_i2c_bus_config i2c[INTEL_I2C_DEV_MAX];
+};
+
+enum pnp_settings {
+	PNP_PERF,
+	PNP_POWER,
+	PNP_PERF_POWER,
+};
+
+struct usb2_eye_per_port {
+	u8 per_port_tx_pe_half;
+	u8 per_port_pe_txi_set;
+	u8 per_port_txi_set;
+	u8 hs_skew_sel;
+	u8 usb_tx_emphasis_en;
+	u8 per_port_rxi_set;
+	u8 hs_npre_drv_sel;
+	u8 override_en;
+};
+
+struct apl_config {
+	/* Common structure containing soc config data required by common code*/
+	struct soc_intel_common_config common_soc_config;
+
+	/*
+	 * Mapping from PCIe root port to CLKREQ input on the SOC. The SOC has
+	 * four CLKREQ inputs, but six root ports. Root ports without an
+	 * associated CLKREQ signal must be marked with "CLKREQ_DISABLED"
+	 */
+	u8 pcie_rp_clkreq_pin[MAX_PCIE_PORTS];
+
+	/* Enable/disable hot-plug for root ports (0 = disable, 1 = enable) */
+	u8 pcie_rp_hotplug_enable[MAX_PCIE_PORTS];
+
+	/* De-emphasis enable configuration for each PCIe root port */
+	u8 pcie_rp_deemphasis_enable[MAX_PCIE_PORTS];
+
+	/*
+	 * [14:8] DDR mode Number of dealy elements.Each = 125pSec.
+	 * [6:0] SDR mode Number of dealy elements.Each = 125pSec.
+	 */
+	u32 emmc_tx_cmd_cntl;
+
+	/*
+	 * [14:8] HS400 mode Number of dealy elements.Each = 125pSec.
+	 * [6:0] SDR104/HS200 mode Number of dealy elements.Each = 125pSec.
+	 */
+	u32 emmc_tx_data_cntl1;
+
+	/*
+	 * [30:24] SDR50 mode Number of dealy elements.Each = 125pSec.
+	 * [22:16] DDR50 mode Number of dealy elements.Each = 125pSec.
+	 * [14:8] SDR25/HS50 mode Number of dealy elements.Each = 125pSec.
+	 * [6:0] SDR12/Compatibility mode Number of dealy elements.
+	 *       Each = 125pSec.
+	 */
+	u32 emmc_tx_data_cntl2;
+
+	/*
+	 * [30:24] SDR50 mode Number of dealy elements.Each = 125pSec.
+	 * [22:16] DDR50 mode Number of dealy elements.Each = 125pSec.
+	 * [14:8] SDR25/HS50 mode Number of dealy elements.Each = 125pSec.
+	 * [6:0] SDR12/Compatibility mode Number of dealy elements.
+	 *       Each = 125pSec.
+	 */
+	u32 emmc_rx_cmd_data_cntl1;
+
+	/*
+	 * [14:8] HS400 mode 1 Number of dealy elements.Each = 125pSec.
+	 * [6:0] HS400 mode 2 Number of dealy elements.Each = 125pSec.
+	 */
+	u32 emmc_rx_strobe_cntl;
+
+	/*
+	 * [13:8] Auto Tuning mode Number of dealy elements.Each = 125pSec.
+	 * [6:0] SDR104/HS200 Number of dealy elements.Each = 125pSec.
+	 */
+	u32 emmc_rx_cmd_data_cntl2;
+
+	/* Select the eMMC max speed allowed */
+	u32 emmc_host_max_speed;
+
+	/* Specifies on which IRQ the SCI will internally appear */
+	u32 sci_irq;
+
+	/* Configure serial IRQ (SERIRQ) line */
+	enum serirq_mode serirq_mode;
+
+	/* Configure LPSS S0ix Enable */
+	bool lpss_s0ix_enable;
+
+	/* Enable DPTF support */
+	bool dptf_enable;
+
+	/* TCC activation offset value in degrees Celsius */
+	int tcc_offset;
+
+	/*
+	 * Configure Audio clk gate and power gate
+	 * IOSF-SB port ID 92 offset 0x530 [5] and [3]
+	 */
+	bool hdaudio_clk_gate_enable;
+	bool hdaudio_pwr_gate_enable;
+	bool hdaudio_bios_config_lockdown;
+
+	/* SLP S3 minimum assertion width */
+	int slp_s3_assertion_width_usecs;
+
+	/* GPIO pin for PERST_0 */
+	u32 prt0_gpio;
+
+	/* USB2 eye diagram settings per port */
+	struct usb2_eye_per_port usb2eye[MAX_USB2_PORTS];
+
+	/* GPIO SD card detect pin */
+	unsigned int sdcard_cd_gpio;
+
+	/*
+	 * PRMRR size setting with three options
+	 *  0x02000000 - 32MiB
+	 *  0x04000000 - 64MiB
+	 *  0x08000000 - 128MiB
+	 */
+	u32 PrmrrSize;
+
+	/*
+	 * Enable SGX feature.
+	 * Enabling SGX feature is 2 step process,
+	 * (1) set sgx_enable = 1
+	 * (2) set PrmrrSize to supported size
+	 */
+	bool sgx_enable;
+
+	/*
+	 * Select PNP Settings.
+	 * (0) Performance,
+	 * (1) Power
+	 * (2) Power & Performance
+	 */
+	enum pnp_settings pnp_settings;
+
+	/*
+	 * PMIC PCH_PWROK delay configuration - IPC Configuration
+	 * Upd for changing PCH_PWROK delay configuration : I2C_Slave_Address
+	 * (31:24) + Register_Offset (23:16) + OR Value (15:8) + AND Value (7:0)
+	 */
+	u32 pmic_pmc_ipc_ctrl;
+
+	/*
+	 * Options to disable XHCI Link Compliance Mode. Default is FALSE to not
+	 * disable Compliance Mode. Set TRUE to disable Compliance Mode.
+	 * 0:FALSE(Default), 1:True.
+	 */
+	bool disable_compliance_mode;
+
+	/*
+	 * Options to change USB3 ModPhy setting for the Integrated Filter (IF)
+	 * value. Default is 0 to not changing default IF value (0x12). Set
+	 * value with the range from 0x01 to 0xff to change IF value.
+	 */
+	u32 mod_phy_if_value;
+
+	/*
+	 * Options to bump USB3 LDO voltage. Default is FALSE to not increasing
+	 * LDO voltage. Set TRUE to increase LDO voltage with 40mV.
+	 * 0:FALSE (default), 1:True.
+	 */
+	bool mod_phy_voltage_bump;
+
+	/*
+	 * Options to adjust PMIC Vdd2 voltage. Default is 0 to not adjusting
+	 * the PMIC Vdd2 default voltage 1.20v. Upd for changing Vdd2 Voltage
+	 * configuration: I2C_Slave_Address (31:23) + Register_Offset (23:16)
+	 * + OR Value (15:8) + AND Value (7:0) through BUCK5_VID[3:2]:
+	 * 00=1.10v, 01=1.15v, 10=1.24v, 11=1.20v (default).
+	 */
+	u32 pmic_vdd2_voltage;
+
+	/* Option to enable VTD feature */
+	bool enable_vtd;
+};
+
+static int get_config(struct udevice *dev, struct apl_config *apl)
+{
+	const u8 *ptr;
+	ofnode node;
+	u32 emmc[4];
+	int ret;
+
+	memset(apl, '\0', sizeof(*apl));
+
+	node = dev_read_subnode(dev, "fsp-s");
+	if (!ofnode_valid(node))
+		return log_msg_ret("fsp-s settings", -ENOENT);
+
+	ptr = ofnode_read_u8_array_ptr(node, "pcie-rp-clkreq-pin",
+				       MAX_PCIE_PORTS);
+	if (!ptr)
+		return log_msg_ret("pcie-rp-clkreq-pin", -EINVAL);
+	memcpy(apl->pcie_rp_clkreq_pin, ptr, MAX_PCIE_PORTS);
+
+	ret = ofnode_read_u32(node, "prt0-gpio", &apl->prt0_gpio);
+	if (ret)
+		return log_msg_ret("prt0-gpio", ret);
+	ret = ofnode_read_u32(node, "sdcard-cd-gpio", &apl->sdcard_cd_gpio);
+	if (ret)
+		return log_msg_ret("sdcard-cd-gpio", ret);
+
+	ret = ofnode_read_u32_array(node, "emmc", emmc, ARRAY_SIZE(emmc));
+	if (ret)
+		return log_msg_ret("emmc", ret);
+	apl->emmc_tx_data_cntl1 = emmc[0];
+	apl->emmc_tx_data_cntl2 = emmc[1];
+	apl->emmc_rx_cmd_data_cntl1 = emmc[2];
+	apl->emmc_rx_cmd_data_cntl2 = emmc[3];
+
+	apl->dptf_enable = ofnode_read_bool(node, "dptf-enable");
+
+	apl->hdaudio_clk_gate_enable = ofnode_read_bool(node,
+						"hdaudio-clk-gate-enable");
+	apl->hdaudio_pwr_gate_enable = ofnode_read_bool(node,
+						"hdaudio-pwr-gate-enable");
+	apl->hdaudio_bios_config_lockdown = ofnode_read_bool(node,
+					     "hdaudio-bios-config-lockdown");
+	apl->lpss_s0ix_enable = ofnode_read_bool(node, "lpss-s0ix-enable");
+
+	/* Santa */
+	apl->usb2eye[1].per_port_pe_txi_set = 7;
+	apl->usb2eye[1].per_port_txi_set = 2;
+
+	return 0;
+}
+
+static void apl_fsp_silicon_init_params_cb(struct apl_config *apl,
+					   struct fsp_s_config *cfg)
+{
+	u8 port;
+
+	for (port = 0; port < MAX_USB2_PORTS; port++) {
+		if (apl->usb2eye[port].per_port_tx_pe_half)
+			cfg->port_usb20_per_port_tx_pe_half[port] =
+				apl->usb2eye[port].per_port_tx_pe_half;
+
+		if (apl->usb2eye[port].per_port_pe_txi_set)
+			cfg->port_usb20_per_port_pe_txi_set[port] =
+				apl->usb2eye[port].per_port_pe_txi_set;
+
+		if (apl->usb2eye[port].per_port_txi_set)
+			cfg->port_usb20_per_port_txi_set[port] =
+				apl->usb2eye[port].per_port_txi_set;
+
+		if (apl->usb2eye[port].hs_skew_sel)
+			cfg->port_usb20_hs_skew_sel[port] =
+				apl->usb2eye[port].hs_skew_sel;
+
+		if (apl->usb2eye[port].usb_tx_emphasis_en)
+			cfg->port_usb20_i_usb_tx_emphasis_en[port] =
+				apl->usb2eye[port].usb_tx_emphasis_en;
+
+		if (apl->usb2eye[port].per_port_rxi_set)
+			cfg->port_usb20_per_port_rxi_set[port] =
+				apl->usb2eye[port].per_port_rxi_set;
+
+		if (apl->usb2eye[port].hs_npre_drv_sel)
+			cfg->port_usb20_hs_npre_drv_sel[port] =
+				apl->usb2eye[port].hs_npre_drv_sel;
+	}
+}
+
+int fsps_update_config(struct udevice *dev, ulong rom_offset,
+		       struct fsps_upd *upd)
+{
+	struct fsp_s_config *cfg = &upd->config;
+	struct apl_config *apl;
+	struct binman_entry vbt;
+	void *buf;
+	int ret;
+
+	ret = binman_entry_find("intel-vbt", &vbt);
+	if (ret)
+		return log_msg_ret("Cannot find VBT", ret);
+	vbt.image_pos += rom_offset;
+	buf = malloc(vbt.size);
+	if (!buf)
+		return log_msg_ret("Alloc VBT", -ENOMEM);
+
+	/*
+	 * Load VBT before devicetree-specific config. This only supports
+	 * memory-mapped SPI at present.
+	 */
+	bootstage_start(BOOTSTAGE_ID_ACCUM_MMAP_SPI, "mmap_spi");
+	memcpy(buf, (void *)vbt.image_pos, vbt.size);
+	bootstage_accum(BOOTSTAGE_ID_ACCUM_MMAP_SPI);
+	if (*(u32 *)buf != VBT_SIGNATURE)
+		return log_msg_ret("VBT signature", -EINVAL);
+	cfg->graphics_config_ptr = (ulong)buf;
+
+	apl = malloc(sizeof(*apl));
+	if (!apl)
+		return log_msg_ret("config", -ENOMEM);
+	get_config(dev, apl);
+
+	cfg->ish_enable = 0;
+	cfg->enable_sata = 0;
+	cfg->pcie_root_port_en[2] = 0;
+	cfg->pcie_rp_hot_plug[2] = 0;
+	cfg->pcie_root_port_en[3] = 0;
+	cfg->pcie_rp_hot_plug[3] = 0;
+	cfg->pcie_root_port_en[4] = 0;
+	cfg->pcie_rp_hot_plug[4] = 0;
+	cfg->pcie_root_port_en[5] = 0;
+	cfg->pcie_rp_hot_plug[5] = 0;
+	cfg->pcie_root_port_en[1] = 0;
+	cfg->pcie_rp_hot_plug[1] = 0;
+	cfg->usb_otg = 0;
+	cfg->i2c6_enable = 0;
+	cfg->i2c7_enable = 0;
+	cfg->hsuart3_enable = 0;
+	cfg->spi1_enable = 0;
+	cfg->spi2_enable = 0;
+	cfg->sdio_enabled = 0;
+
+	memcpy(cfg->pcie_rp_clk_req_number, apl->pcie_rp_clkreq_pin,
+	       sizeof(cfg->pcie_rp_clk_req_number));
+
+	memcpy(cfg->pcie_rp_hot_plug, apl->pcie_rp_hotplug_enable,
+	       sizeof(cfg->pcie_rp_hot_plug));
+
+	switch (apl->serirq_mode) {
+	case SERIRQ_QUIET:
+		cfg->sirq_enable = 1;
+		cfg->sirq_mode = 0;
+		break;
+	case SERIRQ_CONTINUOUS:
+		cfg->sirq_enable = 1;
+		cfg->sirq_mode = 1;
+		break;
+	case SERIRQ_OFF:
+	default:
+		cfg->sirq_enable = 0;
+		break;
+	}
+
+	if (apl->emmc_tx_cmd_cntl)
+		cfg->emmc_tx_cmd_cntl = apl->emmc_tx_cmd_cntl;
+	if (apl->emmc_tx_data_cntl1)
+		cfg->emmc_tx_data_cntl1 = apl->emmc_tx_data_cntl1;
+	if (apl->emmc_tx_data_cntl2)
+		cfg->emmc_tx_data_cntl2 = apl->emmc_tx_data_cntl2;
+	if (apl->emmc_rx_cmd_data_cntl1)
+		cfg->emmc_rx_cmd_data_cntl1 = apl->emmc_rx_cmd_data_cntl1;
+	if (apl->emmc_rx_strobe_cntl)
+		cfg->emmc_rx_strobe_cntl = apl->emmc_rx_strobe_cntl;
+	if (apl->emmc_rx_cmd_data_cntl2)
+		cfg->emmc_rx_cmd_data_cntl2 = apl->emmc_rx_cmd_data_cntl2;
+	if (apl->emmc_host_max_speed)
+		cfg->e_mmc_host_max_speed = apl->emmc_host_max_speed;
+
+	cfg->lpss_s0ix_enable = apl->lpss_s0ix_enable;
+
+	cfg->skip_mp_init = true;
+
+	/* Disable setting of EISS bit in FSP */
+	cfg->spi_eiss = 0;
+
+	/* Disable FSP from locking access to the RTC NVRAM */
+	cfg->rtc_lock = 0;
+
+	/* Enable Audio clk gate and power gate */
+	cfg->hd_audio_clk_gate = apl->hdaudio_clk_gate_enable;
+	cfg->hd_audio_pwr_gate = apl->hdaudio_pwr_gate_enable;
+	/* Bios config lockdown Audio clk and power gate */
+	cfg->bios_cfg_lock_down = apl->hdaudio_bios_config_lockdown;
+	apl_fsp_silicon_init_params_cb(apl, cfg);
+
+	cfg->usb_otg = true;
+	cfg->vtd_enable = apl->enable_vtd;
+
+	return 0;
+}
+
+static void p2sb_set_hide_bit(pci_dev_t dev, int hide)
+{
+	pci_x86_clrset_config(dev, PCH_P2SB_E0 + 1, HIDE_BIT,
+			      hide ? HIDE_BIT : 0, PCI_SIZE_8);
+}
+
+/* Configure package power limits */
+static int set_power_limits(struct udevice *dev)
+{
+	msr_t rapl_msr_reg, limit;
+	u32 power_unit;
+	u32 tdp, min_power, max_power;
+	u32 pl2_val;
+	u32 override_tdp[2];
+	int ret;
+
+	/* Get units */
+	rapl_msr_reg = msr_read(MSR_PKG_POWER_SKU_UNIT);
+	power_unit = 1 << (rapl_msr_reg.lo & 0xf);
+
+	/* Get power defaults for this SKU */
+	rapl_msr_reg = msr_read(MSR_PKG_POWER_SKU);
+	tdp = rapl_msr_reg.lo & PKG_POWER_LIMIT_MASK;
+	pl2_val = rapl_msr_reg.hi & PKG_POWER_LIMIT_MASK;
+	min_power = (rapl_msr_reg.lo >> 16) & PKG_POWER_LIMIT_MASK;
+	max_power = rapl_msr_reg.hi & PKG_POWER_LIMIT_MASK;
+
+	if (min_power > 0 && tdp < min_power)
+		tdp = min_power;
+
+	if (max_power > 0 && tdp > max_power)
+		tdp = max_power;
+
+	ret = dev_read_u32_array(dev, "tdp-pl-override-mw", override_tdp,
+				 ARRAY_SIZE(override_tdp));
+	if (ret)
+		return log_msg_ret("tdp-pl-override-mw", ret);
+
+	/* Set PL1 override value */
+	if (override_tdp[0])
+		tdp = override_tdp[0] * power_unit / 1000;
+
+	/* Set PL2 override value */
+	if (override_tdp[1])
+		pl2_val = override_tdp[1] * power_unit / 1000;
+
+	/* Set long term power limit to TDP */
+	limit.lo = tdp & PKG_POWER_LIMIT_MASK;
+	/* Set PL1 Pkg Power clamp bit */
+	limit.lo |= PKG_POWER_LIMIT_CLAMP;
+
+	limit.lo |= PKG_POWER_LIMIT_EN;
+	limit.lo |= (MB_POWER_LIMIT1_TIME_DEFAULT &
+		PKG_POWER_LIMIT_TIME_MASK) << PKG_POWER_LIMIT_TIME_SHIFT;
+
+	/* Set short term power limit PL2 */
+	limit.hi = pl2_val & PKG_POWER_LIMIT_MASK;
+	limit.hi |= PKG_POWER_LIMIT_EN;
+
+	/* Program package power limits in RAPL MSR */
+	msr_write(MSR_PKG_POWER_LIMIT, limit);
+	log_info("RAPL PL1 %d.%dW\n", tdp / power_unit,
+		 100 * (tdp % power_unit) / power_unit);
+	log_info("RAPL PL2 %d.%dW\n", pl2_val / power_unit,
+		 100 * (pl2_val % power_unit) / power_unit);
+
+	/*
+	 * Sett RAPL MMIO register for Power limits. RAPL driver is using MSR
+	 * instead of MMIO, so disable LIMIT_EN bit for MMIO
+	 */
+	writel(limit.lo & ~PKG_POWER_LIMIT_EN, MCHBAR_REG(MCHBAR_RAPL_PPL));
+	writel(limit.hi & ~PKG_POWER_LIMIT_EN, MCHBAR_REG(MCHBAR_RAPL_PPL + 4));
+
+	return 0;
+}
+
+int p2sb_unhide(void)
+{
+	pci_dev_t dev = PCI_BDF(0, 0xd, 0);
+	ulong val;
+
+	p2sb_set_hide_bit(dev, 0);
+
+	pci_x86_read_config(dev, PCI_VENDOR_ID, &val, PCI_SIZE_16);
+
+	if (val != PCI_VENDOR_ID_INTEL)
+		return log_msg_ret("p2sb unhide", -EIO);
+
+	return 0;
+}
+
+/* Overwrites the SCI IRQ if another IRQ number is given by device tree */
+static void set_sci_irq(void)
+{
+	/* Skip this for now */
+}
+
+int arch_fsps_preinit(void)
+{
+	struct udevice *itss;
+	int ret;
+
+	ret = uclass_first_device_err(UCLASS_IRQ, &itss);
+	if (ret)
+		return log_msg_ret("no itss", ret);
+	/*
+	 * Snapshot the current GPIO IRQ polarities. FSP is setting a default
+	 * policy that doesn't honour boards' requirements
+	 */
+	irq_snapshot_polarities(itss);
+
+	/*
+	 * Clear the GPI interrupt status and enable registers. These
+	 * registers do not get reset to default state when booting from S5.
+	 */
+	ret = pinctrl_gpi_clear_int_cfg();
+	if (ret)
+		return log_msg_ret("gpi_clear", ret);
+
+	return 0;
+}
+
+int arch_fsp_init_r(void)
+{
+#ifdef CONFIG_HAVE_ACPI_RESUME
+	bool s3wake = gd->arch.prev_sleep_state == ACPI_S3;
+#else
+	bool s3wake = false;
+#endif
+	struct udevice *dev, *itss;
+	int ret;
+
+	/*
+	 * This must be called before any devices are probed. Put any probing
+	 * into arch_fsps_preinit() above.
+	 *
+	 * We don't use CONFIG_APL_BOOT_FROM_FAST_SPI_FLASH here since it will
+	 * force PCI to be probed.
+	 */
+	ret = fsp_silicon_init(s3wake, false);
+	if (ret)
+		return ret;
+
+	ret = uclass_first_device_err(UCLASS_IRQ, &itss);
+	if (ret)
+		return log_msg_ret("no itss", ret);
+	/* Restore GPIO IRQ polarities back to previous settings */
+	irq_restore_polarities(itss);
+
+	/* soc_init() */
+	ret = p2sb_unhide();
+	if (ret)
+		return log_msg_ret("unhide p2sb", ret);
+
+	/* Set RAPL MSR for Package power limits*/
+	ret = uclass_first_device_err(UCLASS_NORTHBRIDGE, &dev);
+	if (ret)
+		return log_msg_ret("Cannot get northbridge", ret);
+	set_power_limits(dev);
+
+	/*
+	 * FSP-S routes SCI to IRQ 9. With the help of this function you can
+	 * select another IRQ for SCI.
+	 */
+	set_sci_irq();
+
+	return 0;
+}
-- 
2.24.0.393.g34dc348eaf-goog

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v7 17/17] x86: Add chromebook_coral
  2019-12-09  0:40 [PATCH v7 04/17] x86: apl: Add hostbridge driver Simon Glass
                   ` (11 preceding siblings ...)
  2019-12-09  0:40 ` [PATCH v7 16/17] x86: apl: Add FSP support Simon Glass
@ 2019-12-09  0:40 ` Simon Glass
  2019-12-15  0:47   ` Bin Meng
  2019-12-15  0:36 ` [PATCH v7 04/17] x86: apl: Add hostbridge driver Bin Meng
  13 siblings, 1 reply; 29+ messages in thread
From: Simon Glass @ 2019-12-09  0:40 UTC (permalink / raw)
  To: u-boot

Add support for coral which is a range of Apollo Lake-based Chromebook
released in 2017. This also includes reef released in 2016, since it is
based on the same SoC.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

Changes in v7:
- Add the new documentation to the index file

Changes in v6:
- Add a comment about the need for board_run_command()
- Use generic gpio compatible string

Changes in v5:
- Add gpio-controller to GPIO nodes
- Comment out GPIOs in the fsp_s node since we don't use them yet
- Correct CPU ACPI IDs
- Use a define for ACPI base address

Changes in v4:
- Add u-boot,skip-auto-config-until-reloc property to PCI
- Drop duplicate commit 'Create a new sandbox_pci_read_bar() function'
- New GPIO driver binding
- Set up LPC pads early
- Switch over to use pinctrl for pad init/config
- Update documentation with more detailed memory map
- Use hyphen for device-tree properties
- apollolake -> Apollo Lake

Changes in v3:
- Ad FSP-S support
- Add CONFIG_TPL_X86_ASSUME_CPUID to reduce code size
- Add Chrome OS EC support
- Add a proper SPI node and make the SPI flash node a child
- Add bootstage support
- Add more documentation
- Add spi alias in device tree
- Disable the bootcommand since it does nothing useful on coral
- Don't enable SPI flash in TPL by default
- Drop CONFIG_SPL_NET_SUPPORT
- Drop patch '86: timer: Reduce timer code size in TPL on Intel CPUs'
- Drop patch 'dm: core: Don't include ofnode functions with of-platdata'
- Drop patch 'spi: sandbox: Add a test driver for sandbox SPI flash'
- Drop patch 'spl: Allow SPL/TPL to use of-platdata without libfdt'
- Drop patch 'x86: apollolake: Add definitions for the Intel Fast SPI interface'
- Drop patch 'x86: timer: Set up the timer in timer_early_get_count()'
- Enable video and USB3
- Reduce amount of early-pad data in TPL
- Tidy up the pad settings in the device tree
- Use a zero-based tsc timer

Changes in v2: None

 arch/x86/dts/Makefile                     |   1 +
 arch/x86/dts/chromebook_coral.dts         | 831 ++++++++++++++++++++++
 board/google/Kconfig                      |  15 +
 board/google/chromebook_coral/Kconfig     |  43 ++
 board/google/chromebook_coral/MAINTAINERS |   6 +
 board/google/chromebook_coral/Makefile    |   5 +
 board/google/chromebook_coral/coral.c     |  19 +
 configs/chromebook_coral_defconfig        | 102 +++
 doc/board/google/chromebook_coral.rst     | 241 +++++++
 doc/board/google/index.rst                |   1 +
 include/configs/chromebook_coral.h        |  32 +
 11 files changed, 1296 insertions(+)
 create mode 100644 arch/x86/dts/chromebook_coral.dts
 create mode 100644 board/google/chromebook_coral/Kconfig
 create mode 100644 board/google/chromebook_coral/MAINTAINERS
 create mode 100644 board/google/chromebook_coral/Makefile
 create mode 100644 board/google/chromebook_coral/coral.c
 create mode 100644 configs/chromebook_coral_defconfig
 create mode 100644 doc/board/google/chromebook_coral.rst
 create mode 100644 include/configs/chromebook_coral.h

diff --git a/arch/x86/dts/Makefile b/arch/x86/dts/Makefile
index d4bdf62be6..be209aaaf8 100644
--- a/arch/x86/dts/Makefile
+++ b/arch/x86/dts/Makefile
@@ -2,6 +2,7 @@
 
 dtb-y += bayleybay.dtb \
 	cherryhill.dtb \
+	chromebook_coral.dtb \
 	chromebook_link.dtb \
 	chromebox_panther.dtb \
 	chromebook_samus.dtb \
diff --git a/arch/x86/dts/chromebook_coral.dts b/arch/x86/dts/chromebook_coral.dts
new file mode 100644
index 0000000000..24fcbb5063
--- /dev/null
+++ b/arch/x86/dts/chromebook_coral.dts
@@ -0,0 +1,831 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/dts-v1/;
+
+#include <dt-bindings/gpio/x86-gpio.h>
+
+/include/ "skeleton.dtsi"
+/include/ "keyboard.dtsi"
+/include/ "reset.dtsi"
+/include/ "rtc.dtsi"
+/include/ "tsc_timer.dtsi"
+
+#ifdef CONFIG_CHROMEOS
+#include "chromeos-x86.dtsi"
+#include "flashmap-x86-ro.dtsi"
+#include "flashmap-16mb-rw.dtsi"
+#endif
+
+#include <asm/intel_pinctrl_defs.h>
+#include <asm/arch-apollolake/cpu.h>
+#include <asm/arch-apollolake/gpio.h>
+#include <asm/arch-apollolake/iomap.h>
+#include <asm/arch-apollolake/pm.h>
+
+/ {
+	model = "Google Coral";
+	compatible = "google,coral", "intel,apollolake";
+
+	aliases {
+		cros-ec0 = &cros_ec;
+		fsp = &fsp_s;
+		spi0 = &spi;
+	};
+
+	config {
+	       silent_console = <0>;
+	};
+
+	chosen {
+		stdout-path = &serial;
+	};
+
+	cpus {
+		u-boot,dm-pre-reloc;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu at 0 {
+			u-boot,dm-pre-reloc;
+			device_type = "cpu";
+			compatible = "intel,apl-cpu";
+			reg = <0>;
+			intel,apic-id = <0>;
+		};
+
+		cpu at 1 {
+			device_type = "cpu";
+			compatible = "intel,apl-cpu";
+			reg = <1>;
+			intel,apic-id = <2>;
+		};
+
+		cpu at 2 {
+			device_type = "cpu";
+			compatible = "intel,apl-cpu";
+			reg = <2>;
+			intel,apic-id = <4>;
+		};
+
+		cpu at 3 {
+			device_type = "cpu";
+			compatible = "intel,apl-cpu";
+			reg = <3>;
+			intel,apic-id = <6>;
+		};
+
+	};
+
+	keyboard {
+		intel,duplicate-por;
+	};
+
+	pci {
+		compatible = "pci-x86";
+		#address-cells = <3>;
+		#size-cells = <2>;
+		u-boot,dm-pre-reloc;
+		ranges = <0x02000000 0x0 0xc0000000 0xc0000000 0 0x10000000
+			0x42000000 0x0 0xb0000000 0xb0000000 0 0x10000000
+			0x01000000 0x0 0x1000 0x1000 0 0xefff>;
+		u-boot,skip-auto-config-until-reloc;
+
+		host_bridge: host-bridge at 0,0 {
+			u-boot,dm-pre-reloc;
+			reg = <0x00000000 0 0 0 0>;
+			compatible = "intel,apl-hostbridge";
+			pciex-region-size = <0x10000000>;
+			/*
+			 * Parameters used by the FSP-S binary blob. This is
+			 * really unfortunate since these parameters mostly
+			 * relate to drivers but we need them in one place. We
+			 * could put them in the driver nodes easily, but then
+			 * would have to scan each node to find them. So just
+			 * dump them here for now.
+			 */
+			fsp_s: fsp-s {
+			};
+		};
+
+		punit at 0,1 {
+			u-boot,dm-pre-reloc;
+			reg = <0x00000800 0 0 0 0>;
+			compatible = "intel,apl-punit";
+		};
+
+		p2sb: p2sb at d,0 {
+			u-boot,dm-pre-reloc;
+			reg = <0x02006810 0 0 0 0>;
+			compatible = "intel,apl-p2sb";
+			early-regs = <IOMAP_P2SB_BAR 0x100000>;
+
+			n {
+				compatible = "intel,apl-pinctrl";
+				u-boot,dm-pre-reloc;
+				intel,p2sb-port-id = <PID_GPIO_N>;
+				gpio_n: gpio-n {
+					compatible = "intel,gpio";
+					u-boot,dm-pre-reloc;
+					gpio-controller;
+					#gpio-cells = <2>;
+				};
+			};
+
+			nw {
+				u-boot,dm-pre-reloc;
+				compatible = "intel,apl-pinctrl";
+				intel,p2sb-port-id = <PID_GPIO_NW>;
+				#gpio-cells = <2>;
+				gpio_nw: gpio-nw {
+					compatible = "intel,gpio";
+					u-boot,dm-pre-reloc;
+					gpio-controller;
+					#gpio-cells = <2>;
+				};
+			};
+
+			w {
+				u-boot,dm-pre-reloc;
+				compatible = "intel,apl-pinctrl";
+				intel,p2sb-port-id = <PID_GPIO_W>;
+				#gpio-cells = <2>;
+				gpio_w: gpio-w {
+					compatible = "intel,gpio";
+					u-boot,dm-pre-reloc;
+					gpio-controller;
+					#gpio-cells = <2>;
+				};
+			};
+
+			sw {
+				u-boot,dm-pre-reloc;
+				compatible = "intel,apl-pinctrl";
+				intel,p2sb-port-id = <PID_GPIO_SW>;
+				#gpio-cells = <2>;
+				gpio_sw: gpio-sw {
+					compatible = "intel,gpio";
+					u-boot,dm-pre-reloc;
+					gpio-controller;
+					#gpio-cells = <2>;
+				};
+			};
+
+			itss {
+				u-boot,dm-pre-reloc;
+				compatible = "intel,apl-itss";
+				intel,p2sb-port-id = <PID_ITSS>;
+				intel,pmc-routes = <
+					PMC_GPE_SW_31_0 GPIO_GPE_SW_31_0
+					PMC_GPE_SW_63_32 GPIO_GPE_SW_63_32
+					PMC_GPE_NW_31_0 GPIO_GPE_NW_31_0
+					PMC_GPE_NW_63_32 GPIO_GPE_NW_63_32
+					PMC_GPE_NW_95_64 GPIO_GPE_NW_95_64
+					PMC_GPE_N_31_0 GPIO_GPE_N_31_0
+					PMC_GPE_N_63_32 GPIO_GPE_N_63_32
+					PMC_GPE_W_31_0 GPIO_GPE_W_31_0>;
+			};
+		};
+
+		pmc at d,1 {
+			u-boot,dm-pre-reloc;
+			reg = <0x6900 0 0 0 0>;
+
+			/*
+			 * Values for BAR0, BAR2 and ACPI_BASE for when PCI
+			 * auto-configure is not available
+			 */
+			early-regs = <0xfe042000 0x2000
+				0xfe044000 0x2000
+				IOMAP_ACPI_BASE IOMAP_ACPI_SIZE>;
+			compatible = "intel,apl-pmc";
+			gpe0-dwx-mask = <0xf>;
+			gpe0-dwx-shift-base = <4>;
+
+			/*
+			 * GPE configuration
+			 * Note that GPE events called out in ASL code rely on
+			 * this route, i.e., if this route changes then the
+			 * affected GPE * offset bits also need to be changed.
+			 * This sets the PMC register GPE_CFG fields.
+			 */
+			gpe0-dw = <PMC_GPE_N_31_0
+				PMC_GPE_N_63_32
+				PMC_GPE_SW_31_0>;
+			gpe0-sts = <0x20>;
+			gpe0-en = <0x30>;
+		};
+
+		spi: fast-spi at d,2 {
+			u-boot,dm-pre-reloc;
+			reg = <0x02006a10 0 0 0 0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "intel,fast-spi";
+			early-regs = <IOMAP_SPI_BASE 0x1000>;
+			intel,hardware-seq = <1>;
+
+			fwstore_spi: spi-flash at 0 {
+				#size-cells = <1>;
+				#address-cells = <1>;
+				u-boot,dm-pre-reloc;
+				reg = <0>;
+				compatible = "winbond,w25q128fw",
+					 "jedec,spi-nor";
+				rw-mrc-cache {
+					label = "rw-mrc-cache";
+					reg = <0x008e0000 0x00010000>;
+					u-boot,dm-pre-reloc;
+				};
+				rw-var-mrc-cache {
+					label = "rw-mrc-cache";
+					reg = <0x008f0000 0x0001000>;
+					u-boot,dm-pre-reloc;
+				};
+			};
+		};
+
+		serial: serial at 18,2 {
+			reg = <0x0200c210 0 0 0 0>;
+			u-boot,dm-pre-reloc;
+			compatible = "intel,apl-ns16550";
+			early-regs = <0xde000000 0x20>;
+			reg-shift = <2>;
+			clock-frequency = <1843200>;
+			current-speed = <115200>;
+		};
+
+		pch: pch at 1f,0 {
+			reg = <0x0000f800 0 0 0 0>;
+			compatible = "intel,apl-pch";
+			u-boot,dm-pre-reloc;
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			lpc {
+				compatible = "intel,apl-lpc";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				u-boot,dm-pre-reloc;
+				cros_ec: cros-ec {
+					u-boot,dm-pre-reloc;
+					compatible = "google,cros-ec-lpc";
+					reg = <0x204 1 0x200 1 0x880 0x80>;
+
+					/*
+					 * Describes the flash memory within
+					 * the EC
+					 */
+					#address-cells = <1>;
+					#size-cells = <1>;
+					flash at 8000000 {
+						reg = <0x08000000 0x20000>;
+						erase-value = <0xff>;
+					};
+				};
+			};
+		};
+	};
+
+};
+
+&host_bridge {
+	/*
+	 * PL1 override 12000 mW: the energy calculation is wrong with the
+	 * current VR solution. Experiments show that SoC TDP max (6W) can be
+	 * reached when RAPL PL1 is set to 12W. Set RAPL PL2 to 15W.
+	 */
+	tdp-pl-override-mw = <12000 15000>;
+
+	early-pads = <
+		/* These two are for the debug UART */
+		GPIO_46 /* UART2 RX */
+			(PAD_CFG0_MODE_NF1 | PAD_CFG0_LOGICAL_RESET_DEEP)
+			(PAD_CFG1_PULL_NATIVE | PAD_CFG1_IOSSTATE_TX_LAST_RXE)
+
+		GPIO_47 /* UART2 TX */
+			(PAD_CFG0_MODE_NF1 | PAD_CFG0_LOGICAL_RESET_DEEP)
+			(PAD_CFG1_PULL_NATIVE | PAD_CFG1_IOSSTATE_TX_LAST_RXE)
+
+		GPIO_75 /* I2S1_BCLK -- PCH_WP */
+			(PAD_CFG0_MODE_GPIO | PAD_CFG0_LOGICAL_RESET_DEEP)
+			(PAD_CFG1_PULL_UP_20K | PAD_CFG1_IOSSTATE_TXD_RXE)
+
+		/* I2C2 - TPM  */
+		GPIO_128 /* LPSS_I2C2_SDA */
+			(PAD_CFG0_MODE_NF1 | PAD_CFG0_LOGICAL_RESET_DEEP)
+			(PAD_CFG1_PULL_UP_2K | PAD_CFG1_IOSSTATE_TX_LAST_RXE)
+		GPIO_129 /* LPSS_I2C2_SCL */
+			(PAD_CFG0_MODE_NF1 | PAD_CFG0_LOGICAL_RESET_DEEP)
+			(PAD_CFG1_PULL_UP_2K | PAD_CFG1_IOSSTATE_TX_LAST_RXE)
+		GPIO_28 /* TPM IRQ */
+			(PAD_CFG0_MODE_GPIO | PAD_CFG0_LOGICAL_RESET_DEEP |
+				PAD_CFG0_TX_DISABLE | PAD_CFG0_ROUTE_IOAPIC |
+				PAD_CFG0_TRIG_LEVEL | PAD_CFG0_RX_POL_INVERT)
+			(PAD_CFG1_PULL_NONE | PAD_CFG1_IOSSTATE_TXD_RXE)
+
+		/*
+		 * WLAN_PE_RST - default to deasserted just in case FSP
+		 * misbehaves
+		 */
+		GPIO_122  /* SIO_SPI_2_RXD */
+			(PAD_CFG0_MODE_GPIO | PAD_CFG0_LOGICAL_RESET_DEEP |
+				PAD_CFG0_RX_DISABLE | 0)
+			(PAD_CFG1_PULL_NONE | PAD_CFG1_IOSSTATE_TX_LAST_RXE)
+
+		/* LPC */
+		PAD_CFG_NF(LPC_ILB_SERIRQ, UP_20K, DEEP, NF1) /* LPC_SERIRQ */
+		PAD_CFG_NF(LPC_CLKOUT0, NONE, DEEP, NF1) /* LPC_CLKOUT0 */
+		PAD_CFG_NF(LPC_CLKOUT1, UP_20K, DEEP, NF1)
+		PAD_CFG_NF(LPC_AD0, UP_20K, DEEP, NF1)	 /* LPC_AD0 */
+		PAD_CFG_NF(LPC_AD1, UP_20K, DEEP, NF1)	 /* LPC_AD1 */
+		PAD_CFG_NF(LPC_AD2, UP_20K, DEEP, NF1)	 /* LPC_AD2 */
+		PAD_CFG_NF(LPC_AD3, UP_20K, DEEP, NF1)	 /* LPC_AD3 */
+		PAD_CFG_NF(LPC_CLKRUNB, UP_20K, DEEP, NF1) /* LPC_CLKRUN_N */
+		PAD_CFG_NF(LPC_FRAMEB, NATIVE, DEEP, NF1) /* LPC_FRAME_N */
+		>;
+
+	lpddr4-swizzle = /bits/ 8 <
+		/* LP4_PHYS_CH0A */
+
+		/* DQA[0:7] pins of LPDDR4 module */
+		6 7 5 4 3 1 0 2
+		/* DQA[8:15] pins of LPDDR4 module */
+		12 10 11 13 14 8 9 15
+		/* DQB[0:7] pins of LPDDR4 module with offset of 16 */
+		16 22 23 20 18 17 19 21
+		/* DQB[7:15] pins of LPDDR4 module with offset of 16 */
+		30 28 29 25 24 26 27 31
+
+		/* LP4_PHYS_CH0B */
+		/* DQA[0:7] pins of LPDDR4 module */
+		7 3 5 2 6 0 1 4
+		/* DQA[8:15] pins of LPDDR4 module */
+		 9 14 12 13 10 11 8 15
+		/* DQB[0:7] pins of LPDDR4 module with offset of 16 */
+		20 22 23 16 19 17 18 21
+		/* DQB[7:15] pins of LPDDR4 module with offset of 16 */
+		28 24 26 27 29 30 31 25
+
+		/* LP4_PHYS_CH1A */
+
+		/* DQA[0:7] pins of LPDDR4 module */
+		2 1 6 7 5 4 3 0
+		/* DQA[8:15] pins of LPDDR4 module */
+		11 10 8 9 12 15 13 14
+		/* DQB[0:7] pins of LPDDR4 module with offset of 16 */
+		17 23 19 16 21 22 20 18
+		/* DQB[7:15] pins of LPDDR4 module with offset of 16 */
+		31 29 26 25 28 27 24 30
+
+		/* LP4_PHYS_CH1B */
+
+		/* DQA[0:7] pins of LPDDR4 module */
+		4 3 7 5 6 1 0 2
+		/* DQA[8:15] pins of LPDDR4 module */
+		15 9 8 11 14 13 12 10
+		/* DQB[0:7] pins of LPDDR4 module with offset of 16 */
+		20 23 22 21 18 19 16 17
+		/* DQB[7:15] pins of LPDDR4 module with offset of 16 */
+		25 28 30 31 26 27 24 29>;
+};
+
+&fsp_s {
+	u-boot,dm-pre-proper;
+
+	/* Disable unused clkreq of PCIe root ports */
+	pcie-rp-clkreq-pin = /bits/ 8 <0 /* wifi/bt */
+		CLKREQ_DISABLED
+		CLKREQ_DISABLED
+		CLKREQ_DISABLED
+		CLKREQ_DISABLED
+		CLKREQ_DISABLED>;
+
+	/*
+	 * GPIO for PERST_0
+	 * If the Board has PERST_0 signal, assign the GPIO
+	 * If the Board does not have PERST_0, assign GPIO_PRT0_UDEF
+	 *
+	 * This are not used yet, so comment them out for now.
+	 *
+	 * prt0-gpio = <GPIO_122>;
+	 *
+	 * GPIO for SD card detect
+	 * sdcard-cd-gpio = <GPIO_177>;
+	 */
+
+	/*
+	 * Order is emmc-tx-data-cntl1, emmc-tx-data-cntl2,
+	 * emmc-rx-cmd-data-cntl1, emmc-rx-cmd-data-cntl2
+	 *
+	 * EMMC TX DATA Delay 1
+	 * Refer to EDS-Vol2-22.3
+	 * [14:8] steps of delay for HS400, each 125ps
+	 * [6:0] steps of delay for SDR104/HS200, each 125ps
+
+	/*
+	 * EMMC TX DATA Delay 2
+	 * Refer to EDS-Vol2-22.3.
+	 * [30:24] steps of delay for SDR50, each 125ps
+	 * [22:16] steps of delay for DDR50, each 125ps
+	 * [14:8] steps of delay for SDR25/HS50, each 125ps
+	 * [6:0] steps of delay for SDR12, each 125ps
+	 */
+
+	/*
+	 * EMMC RX CMD/DATA Delay 1
+	 * Refer to EDS-Vol2-22.3.
+	 * [30:24] steps of delay for SDR50, each 125ps
+	 * [22:16] steps of delay for DDR50, each 125ps
+	 * [14:8] steps of delay for SDR25/HS50, each 125ps
+	 * [6:0] steps of delay for SDR12, each 125ps
+	 */
+
+	/*
+	 * EMMC RX CMD/DATA Delay 2
+	 * Refer to EDS-Vol2-22.3.
+	 * [17:16] stands for Rx Clock before Output Buffer
+	 * [14:8] steps of delay for Auto Tuning Mode, each 125ps
+	 * [6:0] steps of delay for HS200, each 125ps
+	 */
+	emmc = <0x0c16 0x28162828 0x00181717 0x10008>;
+
+	/* Enable DPTF */
+	dptf-enable;
+
+	/* Enable Audio Clock and Power gating */
+	hdaudio-clk-gate-enable;
+	hdaudio-pwr-gate-enable;
+	hdaudio-bios-config-lockdown;
+
+	/* Enable lpss s0ix */
+	lpss-s0ix-enable;
+
+	/*
+	 * TODO(sjg at chromium.org): Move this to the I2C nodes
+	 * Intel Common SoC Config
+	 *+-------------------+---------------------------+
+	 *| Field             |  Value                    |
+	 *+-------------------+---------------------------+
+	 *| I2C0              | Audio                     |
+	 *| I2C2              | TPM                       |
+	 *| I2C3              | Touchscreen               |
+	 *| I2C4              | Trackpad                  |
+	 *| I2C5              | Digitizer                 |
+	 *+-------------------+---------------------------+
+	 *
+	common_soc_config" = "{
+		.i2c[0] = {
+			.speed = I2C_SPEED_FAST,
+			.rise-time-ns = 104,
+			.fall-time-ns = 52,
+		},
+		.i2c[2] = {
+			.early_init = 1,
+			.speed = I2C_SPEED_FAST,
+			.rise-time-ns = 57,
+			.fall-time-ns = 28,
+		},
+		.i2c[3] = {
+			.speed = I2C_SPEED_FAST,
+			.rise-time-ns = 76,
+			.fall-time-ns = 164,
+		},
+		.i2c[4] = {
+			.speed = I2C_SPEED_FAST,
+			.rise-time-ns = 114,
+			.fall-time-ns = 164,
+			.data_hold_time_ns = 350,
+		},
+		.i2c[5] = {
+			.speed = I2C_SPEED_FAST,
+			.rise-time-ns = 152,
+			.fall-time-ns = 30,
+		},
+	}"
+	*/
+
+	/* Minimum SLP S3 assertion width 28ms */
+	slp-s3-assertion-width-usecs = <28000>;
+
+	pads = <
+		/* PCIE_WAKE[0:3]_N */
+		PAD_CFG_GPI_SCI_LOW(GPIO_205, UP_20K, DEEP, EDGE_SINGLE) /* WLAN */
+		PAD_CFG_GPI(GPIO_206, UP_20K, DEEP)	 /* Unused */
+		PAD_CFG_GPI(GPIO_207, UP_20K, DEEP)	 /* Unused */
+		PAD_CFG_GPI(GPIO_208, UP_20K, DEEP)	 /* Unused */
+
+		/* EMMC interface */
+		PAD_CFG_NF(GPIO_156, DN_20K, DEEP, NF1) /* EMMC_CLK */
+		PAD_CFG_NF_IOSSTATE_IOSTERM(GPIO_157, UP_20K, DEEP, NF1, HIZCRX1, DISPUPD) /* EMMC_D0 */
+		PAD_CFG_NF_IOSSTATE_IOSTERM(GPIO_158, UP_20K, DEEP, NF1, HIZCRX1, DISPUPD) /* EMMC_D1 */
+		PAD_CFG_NF_IOSSTATE_IOSTERM(GPIO_159, UP_20K, DEEP, NF1, HIZCRX1, DISPUPD) /* EMMC_D2 */
+		PAD_CFG_NF_IOSSTATE_IOSTERM(GPIO_160, UP_20K, DEEP, NF1, HIZCRX1, DISPUPD) /* EMMC_D3 */
+		PAD_CFG_NF_IOSSTATE_IOSTERM(GPIO_161, UP_20K, DEEP, NF1, HIZCRX1, DISPUPD) /* EMMC_D4 */
+		PAD_CFG_NF_IOSSTATE_IOSTERM(GPIO_162, UP_20K, DEEP, NF1, HIZCRX1, DISPUPD) /* EMMC_D5 */
+		PAD_CFG_NF_IOSSTATE_IOSTERM(GPIO_163, UP_20K, DEEP, NF1, HIZCRX1, DISPUPD) /* EMMC_D6 */
+		PAD_CFG_NF_IOSSTATE_IOSTERM(GPIO_164, UP_20K, DEEP, NF1, HIZCRX1, DISPUPD) /* EMMC_D7 */
+		PAD_CFG_NF_IOSSTATE_IOSTERM(GPIO_165, UP_20K, DEEP, NF1, HIZCRX1, DISPUPD) /* EMMC_CMD */
+		PAD_CFG_NF(GPIO_182, DN_20K, DEEP, NF1) /* EMMC_RCLK */
+
+		/* SDIO -- unused */
+		PAD_CFG_GPI(GPIO_166, UP_20K, DEEP)	 /* SDIO_CLK */
+		PAD_CFG_GPI(GPIO_167, UP_20K, DEEP)	 /* SDIO_D0 */
+		/* Configure SDIO to enable power gating */
+		PAD_CFG_NF(GPIO_168, UP_20K, DEEP, NF1)	/* SDIO_D1 */
+		PAD_CFG_GPI(GPIO_169, UP_20K, DEEP)	 /* SDIO_D2 */
+		PAD_CFG_GPI(GPIO_170, UP_20K, DEEP)	 /* SDIO_D3 */
+		PAD_CFG_GPI(GPIO_171, UP_20K, DEEP)	 /* SDIO_CMD */
+
+		/* SDCARD */
+		/* Pull down clock by 20K */
+		PAD_CFG_NF(GPIO_172, DN_20K, DEEP, NF1) /* SDCARD_CLK */
+		PAD_CFG_NF(GPIO_173, UP_20K, DEEP, NF1) /* SDCARD_D0 */
+		PAD_CFG_NF(GPIO_174, UP_20K, DEEP, NF1) /* SDCARD_D1 */
+		PAD_CFG_NF(GPIO_175, UP_20K, DEEP, NF1) /* SDCARD_D2 */
+		PAD_CFG_NF(GPIO_176, UP_20K, DEEP, NF1) /* SDCARD_D3 */
+		/* Card detect is active LOW with external pull up */
+		PAD_CFG_NF(GPIO_177, NONE, DEEP, NF1) /* SDCARD_CD_N */
+		PAD_CFG_NF(GPIO_178, UP_20K, DEEP, NF1) /* SDCARD_CMD */
+		/* CLK feedback, internal signal, needs 20K pull down */
+		PAD_CFG_NF(GPIO_179, DN_20K, DEEP, NF1) /* SDCARD_CLK_FB */
+		/* No h/w write proect for uSD cards, pull down by 20K */
+		PAD_CFG_NF(GPIO_186, DN_20K, DEEP, NF1) /* SDCARD_LVL_WP */
+		/* EN_SD_SOCKET_PWR_L for SD slot power control. Default on */
+		PAD_CFG_GPO(GPIO_183, 0, DEEP)		 /* SDIO_PWR_DOWN_N */
+
+		/* SMBus -- unused */
+		PAD_CFG_GPI(SMB_ALERTB, UP_20K, DEEP)	 /* SMB_ALERT _N */
+		PAD_CFG_GPI(SMB_CLK, UP_20K, DEEP)	 /* SMB_CLK */
+		PAD_CFG_GPI(SMB_DATA, UP_20K, DEEP)	 /* SMB_DATA */
+
+		/* LPC */
+		PAD_CFG_NF(LPC_ILB_SERIRQ, UP_20K, DEEP, NF1) /* LPC_SERIRQ */
+		PAD_CFG_NF(LPC_CLKOUT0, NONE, DEEP, NF1) /* LPC_CLKOUT0 */
+		PAD_CFG_NF(LPC_CLKOUT1, UP_20K, DEEP, NF1)
+		PAD_CFG_NF(LPC_AD0, UP_20K, DEEP, NF1)	 /* LPC_AD0 */
+		PAD_CFG_NF(LPC_AD1, UP_20K, DEEP, NF1)	 /* LPC_AD1 */
+		PAD_CFG_NF(LPC_AD2, UP_20K, DEEP, NF1)	 /* LPC_AD2 */
+		PAD_CFG_NF(LPC_AD3, UP_20K, DEEP, NF1)	 /* LPC_AD3 */
+		PAD_CFG_NF(LPC_CLKRUNB, UP_20K, DEEP, NF1) /* LPC_CLKRUN_N */
+		PAD_CFG_NF(LPC_FRAMEB, NATIVE, DEEP, NF1) /* LPC_FRAME_N */
+
+		/* I2C0 - Audio */
+		PAD_CFG_NF(GPIO_124, UP_2K, DEEP, NF1) /* LPSS_I2C0_SDA */
+		PAD_CFG_NF(GPIO_125, UP_2K, DEEP, NF1) /* LPSS_I2C0_SCL */
+
+		/* I2C1 - NFC with external pulls */
+		PAD_CFG_NF(GPIO_126, NONE, DEEP, NF1) /* LPSS_I2C1_SDA */
+		PAD_CFG_NF(GPIO_127, NONE, DEEP, NF1) /* LPSS_I2C1_SCL */
+
+		/* I2C2 - TPM  */
+		PAD_CFG_NF(GPIO_128, UP_2K, DEEP, NF1) /* LPSS_I2C2_SDA */
+		PAD_CFG_NF(GPIO_129, UP_2K, DEEP, NF1) /* LPSS_I2C2_SCL */
+
+		/* I2C3 - touch */
+		PAD_CFG_NF(GPIO_130, UP_2K, DEEP, NF1) /* LPSS_I2C3_SDA */
+		PAD_CFG_NF(GPIO_131, UP_2K, DEEP, NF1) /* LPSS_I2C3_SCL */
+
+		/* I2C4 - trackpad */
+		/* LPSS_I2C4_SDA */
+		PAD_CFG_NF_IOSSTATE(GPIO_132, UP_2K, DEEP, NF1, HIZCRX1)
+		/* LPSS_I2C4_SCL */
+		PAD_CFG_NF_IOSSTATE(GPIO_133, UP_2K, DEEP, NF1, HIZCRX1)
+
+		/* I2C5 -- pen with external pulls  */
+		PAD_CFG_NF(GPIO_134, NONE, DEEP, NF1) /* LPSS_I2C5_SDA */
+		PAD_CFG_NF(GPIO_135, NONE, DEEP, NF1) /* LPSS_I2C5_SCL */
+
+		/* I2C6-7 -- unused */
+		PAD_CFG_GPI(GPIO_136, UP_20K, DEEP)	 /* LPSS_I2C6_SDA */
+		PAD_CFG_GPI(GPIO_137, UP_20K, DEEP)	 /* LPSS_I2C6_SCL */
+		PAD_CFG_GPI(GPIO_138, UP_20K, DEEP)	 /* LPSS_I2C7_SDA */
+		PAD_CFG_GPI(GPIO_139, UP_20K, DEEP)	 /* LPSS_I2C7_SCL */
+
+		/* Audio Amp - I2S6 */
+		PAD_CFG_NF(GPIO_146, NATIVE, DEEP, NF2) /* ISH_GPIO_0 - I2S6_BCLK */
+		PAD_CFG_NF(GPIO_147, NATIVE, DEEP, NF2) /* ISH_GPIO_1 - I2S6_WS_SYNC */
+		PAD_CFG_GPI(GPIO_148, UP_20K, DEEP)	 /* ISH_GPIO_2 - unused */
+		PAD_CFG_NF(GPIO_149, NATIVE, DEEP, NF2) /* ISH_GPIO_3 - I2S6_SDO */
+
+		/* NFC Reset */
+		PAD_CFG_GPO(GPIO_150, 1, DEEP)		 /* ISH_GPIO_4 */
+
+		PAD_CFG_GPI(GPIO_151, UP_20K, DEEP)	 /* ISH_GPIO_5 - unused */
+
+		/* Touch enable */
+		PAD_CFG_GPO(GPIO_152, 1, DEEP)		 /* ISH_GPIO_6 */
+
+		PAD_CFG_GPI(GPIO_153, UP_20K, DEEP)	 /* ISH_GPIO_7 - unused */
+		PAD_CFG_GPI(GPIO_154, UP_20K, DEEP)	 /* ISH_GPIO_8 - unused */
+		PAD_CFG_GPI(GPIO_155, UP_20K, DEEP)	 /* ISH_GPIO_9 - unused */
+
+		/* PCIE_CLKREQ[0:3]_N */
+		PAD_CFG_NF(GPIO_209, NONE, DEEP, NF1)	 /* WLAN with external pull */
+		PAD_CFG_GPI(GPIO_210, UP_20K, DEEP)	 /* unused */
+		PAD_CFG_GPI(GPIO_211, UP_20K, DEEP)	 /* unused */
+		PAD_CFG_GPI(GPIO_212, UP_20K, DEEP)	 /* unused */
+
+		/* OSC_CLK_OUT_[0:4] -- unused */
+		PAD_CFG_GPI(OSC_CLK_OUT_0, UP_20K, DEEP)
+		PAD_CFG_GPI(OSC_CLK_OUT_1, UP_20K, DEEP)
+		PAD_CFG_GPI(OSC_CLK_OUT_2, UP_20K, DEEP)
+		PAD_CFG_GPI(OSC_CLK_OUT_3, UP_20K, DEEP)
+		PAD_CFG_GPI(OSC_CLK_OUT_4, UP_20K, DEEP)
+
+		/* PMU Signals */
+		PAD_CFG_GPI(PMU_AC_PRESENT, UP_20K, DEEP) /* PMU_AC_PRESENT - unused */
+		PAD_CFG_NF(PMU_BATLOW_B, UP_20K, DEEP, NF1) /* PMU_BATLOW_N */
+		PAD_CFG_NF(PMU_PLTRST_B, NONE, DEEP, NF1) /* PMU_PLTRST_N */
+		PAD_CFG_NF(PMU_PWRBTN_B, UP_20K, DEEP, NF1) /* PMU_PWRBTN_N */
+		PAD_CFG_NF(PMU_RESETBUTTON_B, NONE, DEEP, NF1) /* PMU_RSTBTN_N */
+		PAD_CFG_NF_IOSSTATE(PMU_SLP_S0_B, NONE, DEEP, NF1, IGNORE) /* PMU_SLP_S0_N */
+		PAD_CFG_NF(PMU_SLP_S3_B, NONE, DEEP, NF1) /* PMU_SLP_S3_N */
+		PAD_CFG_NF(PMU_SLP_S4_B, NONE, DEEP, NF1) /* PMU_SLP_S4_N */
+		PAD_CFG_NF(PMU_SUSCLK, NONE, DEEP, NF1) /* PMU_SUSCLK */
+		PAD_CFG_GPO(PMU_WAKE_B, 1, DEEP)	 /* EN_PP3300_EMMC */
+		PAD_CFG_NF(SUS_STAT_B, NONE, DEEP, NF1) /* SUS_STAT_N */
+		PAD_CFG_NF(SUSPWRDNACK, NONE, DEEP, NF1) /* SUSPWRDNACK */
+
+		/* DDI[0:1] SDA and SCL -- unused */
+		PAD_CFG_GPI(GPIO_187, UP_20K, DEEP)	 /* HV_DDI0_DDC_SDA */
+		PAD_CFG_GPI(GPIO_188, UP_20K, DEEP)	 /* HV_DDI0_DDC_SCL */
+		PAD_CFG_GPI(GPIO_189, UP_20K, DEEP)	 /* HV_DDI1_DDC_SDA */
+		PAD_CFG_GPI(GPIO_190, UP_20K, DEEP)	 /* HV_DDI1_DDC_SCL */
+
+		/* MIPI I2C -- unused */
+		PAD_CFG_GPI(GPIO_191, UP_20K, DEEP)	 /* MIPI_I2C_SDA */
+		PAD_CFG_GPI(GPIO_192, UP_20K, DEEP)	 /* MIPI_I2C_SCL */
+
+		/* Panel 0 control */
+		PAD_CFG_NF(GPIO_193, NATIVE, DEEP, NF1) /* PNL0_VDDEN */
+		PAD_CFG_NF(GPIO_194, NATIVE, DEEP, NF1) /* PNL0_BKLTEN */
+		PAD_CFG_NF(GPIO_195, NATIVE, DEEP, NF1) /* PNL0_BKLTCTL */
+
+		/* Panel 1 control -- unused */
+		PAD_CFG_NF(GPIO_196, NATIVE, DEEP, NF1) /* PNL1_VDDEN */
+		PAD_CFG_NF(GPIO_197, NATIVE, DEEP, NF1) /* PNL1_BKLTEN */
+		PAD_CFG_NF(GPIO_198, NATIVE, DEEP, NF1) /* PNL1_BKLTCTL */
+
+		/* Hot plug detect */
+		PAD_CFG_NF(GPIO_199, UP_20K, DEEP, NF2) /* HV_DDI1_HPD */
+		PAD_CFG_NF(GPIO_200, UP_20K, DEEP, NF2) /* HV_DDI0_HPD */
+
+		/* MDSI signals -- unused */
+		PAD_CFG_GPI(GPIO_201, UP_20K, DEEP)	 /* MDSI_A_TE */
+		PAD_CFG_GPI(GPIO_202, UP_20K, DEEP)	 /* MDSI_A_TE */
+
+		/* USB overcurrent pins */
+		PAD_CFG_NF(GPIO_203, UP_20K, DEEP, NF1) /* USB_OC0_N */
+		PAD_CFG_NF(GPIO_204, UP_20K, DEEP, NF1) /* USB_OC1_N */
+
+		/* PMC SPI -- almost entirely unused */
+		PAD_CFG_GPI(PMC_SPI_FS0, UP_20K, DEEP)
+		PAD_CFG_NF(PMC_SPI_FS1, UP_20K, DEEP, NF2) /* HV_DDI2_HPD -- EDP HPD */
+		PAD_CFG_GPI(PMC_SPI_FS2, UP_20K, DEEP)
+		PAD_CFG_GPI(PMC_SPI_RXD, UP_20K, DEEP)
+		PAD_CFG_GPI(PMC_SPI_TXD, UP_20K, DEEP)
+		PAD_CFG_GPI(PMC_SPI_CLK, UP_20K, DEEP)
+
+		/* PMIC Signals Unused signals related to an old PMIC interface */
+		PAD_CFG_NF_IOSSTATE(PMIC_RESET_B, NATIVE, DEEP, NF1, IGNORE) /* PMIC_RESET_B */
+		PAD_CFG_GPI(GPIO_213, NONE, DEEP)	 /* unused external pull */
+		PAD_CFG_GPI(GPIO_214, UP_20K, DEEP)	 /* unused */
+		PAD_CFG_GPI(GPIO_215, UP_20K, DEEP)	 /* unused */
+		PAD_CFG_NF(PMIC_THERMTRIP_B, UP_20K, DEEP, NF1) /* THERMTRIP_N */
+		PAD_CFG_GPI(PMIC_STDBY, UP_20K, DEEP)	 /* unused */
+		PAD_CFG_NF(PROCHOT_B, UP_20K, DEEP, NF1) /* PROCHOT_N */
+		PAD_CFG_NF(PMIC_I2C_SCL, UP_1K, DEEP, NF1) /* PMIC_I2C_SCL */
+		PAD_CFG_NF(PMIC_I2C_SDA, UP_1K, DEEP, NF1) /* PMIC_I2C_SDA */
+
+		/* I2S1 -- largely unused */
+		PAD_CFG_GPI(GPIO_74, UP_20K, DEEP)	/* I2S1_MCLK */
+		PAD_CFG_GPI(GPIO_75, UP_20K, DEEP)	/* I2S1_BCLK -- PCH_WP */
+		PAD_CFG_GPO(GPIO_76, 0, DEEP)		/* I2S1_WS_SYNC -- SPK_PA_EN */
+		PAD_CFG_GPI(GPIO_77, UP_20K, DEEP)	/* I2S1_SDI */
+		PAD_CFG_GPO(GPIO_78, 1, DEEP)		/* I2S1_SDO -- EN_PP3300_DX_LTE_SOC */
+
+		/* DMIC or I2S4 */
+		/* AVS_DMIC_CLK_A1 */
+		PAD_CFG_NF_IOSSTATE(GPIO_79, NATIVE, DEEP, NF1, IGNORE)
+		PAD_CFG_NF(GPIO_80, NATIVE, DEEP, NF1) /* AVS_DMIC_CLK_B1 */
+		PAD_CFG_NF(GPIO_81, NATIVE, DEEP, NF1)	/* AVS_DMIC_DATA_1 */
+		PAD_CFG_GPI(GPIO_82, DN_20K, DEEP)	 /* unused -- strap */
+		PAD_CFG_NF(GPIO_83, NATIVE, DEEP, NF1) /* AVS_DMIC_DATA_2 */
+
+		/* I2S2 -- Headset amp */
+		PAD_CFG_NF(GPIO_84, NATIVE, DEEP, NF1)	 /* AVS_I2S2_MCLK */
+		PAD_CFG_NF(GPIO_85, NATIVE, DEEP, NF1)	 /* AVS_I2S2_BCLK */
+		PAD_CFG_NF(GPIO_86, NATIVE, DEEP, NF1)	 /* AVS_I2S2_SW_SYNC */
+		PAD_CFG_NF(GPIO_87, NATIVE, DEEP, NF1)	 /* AVS_I2S2_SDI */
+		PAD_CFG_NF(GPIO_88, NATIVE, DEEP, NF1)	 /* AVS_I2S2_SDO */
+
+		/* I2S3 -- largely unused */
+		PAD_CFG_GPI(GPIO_89, UP_20K, DEEP)	 /* unused */
+		PAD_CFG_GPI(GPIO_90, UP_20K, DEEP)	 /* GPS_HOST_WAKE */
+		PAD_CFG_GPO(GPIO_91, 1, DEEP)		 /* GPS_EN */
+		PAD_CFG_GPI(GPIO_92, DN_20K, DEEP)	 /* unused -- strap */
+
+		/* Fast SPI */
+		PAD_CFG_NF_IOSSTATE(GPIO_97, NATIVE, DEEP, NF1, IGNORE)	/* FST_SPI_CS0_B */
+		PAD_CFG_GPI(GPIO_98, UP_20K, DEEP)				/* FST_SPI_CS1_B -- unused */
+		PAD_CFG_NF_IOSSTATE(GPIO_99, NATIVE, DEEP, NF1, IGNORE)	/* FST_SPI_MOSI_IO0 */
+		PAD_CFG_NF_IOSSTATE(GPIO_100, NATIVE, DEEP, NF1, IGNORE)	/* FST_SPI_MISO_IO1 */
+		PAD_CFG_GPI(GPIO_101, NONE, DEEP)				/* FST_IO2 -- MEM_CONFIG0 */
+		PAD_CFG_GPI(GPIO_102, NONE, DEEP)				/* FST_IO3 -- MEM_CONFIG1 */
+		PAD_CFG_NF_IOSSTATE(GPIO_103, NATIVE, DEEP, NF1, IGNORE)	/* FST_SPI_CLK */
+		PAD_CFG_NF_IOSSTATE(FST_SPI_CLK_FB, NATIVE, DEEP, NF1, IGNORE) /* FST_SPI_CLK_FB */
+		PAD_CFG_NF_IOSSTATE(GPIO_106, NATIVE, DEEP, NF3, IGNORE)	/* FST_SPI_CS2_N */
+
+		/* SIO_SPI_0 - Used for FP */
+		PAD_CFG_NF(GPIO_104, NATIVE, DEEP, NF1)			/* SIO_SPI_0_CLK */
+		PAD_CFG_NF(GPIO_105, NATIVE, DEEP, NF1)			/* SIO_SPI_0_FS0 */
+		PAD_CFG_NF(GPIO_109, NATIVE, DEEP, NF1)			/* SIO_SPI_0_RXD */
+		PAD_CFG_NF(GPIO_110, NATIVE, DEEP, NF1)			/* SIO_SPI_0_TXD */
+
+		/* SIO_SPI_1 -- largely unused */
+		PAD_CFG_GPI(GPIO_111, UP_20K, DEEP)	 /* SIO_SPI_1_CLK */
+		PAD_CFG_GPI(GPIO_112, UP_20K, DEEP)	 /* SIO_SPI_1_FS0 */
+		PAD_CFG_GPI(GPIO_113, UP_20K, DEEP)	 /* SIO_SPI_1_FS1 */
+		/* Headset interrupt */
+		PAD_CFG_GPI_APIC_LOW(GPIO_116, NONE, DEEP) /* SIO_SPI_1_RXD */
+		PAD_CFG_GPI(GPIO_117, UP_20K, DEEP)	 /* SIO_SPI_1_TXD */
+
+		/* SIO_SPI_2 -- unused */
+		PAD_CFG_GPI(GPIO_118, UP_20K, DEEP)	 /* SIO_SPI_2_CLK */
+		PAD_CFG_GPI(GPIO_119, UP_20K, DEEP)	 /* SIO_SPI_2_FS0 */
+		PAD_CFG_GPI(GPIO_120, UP_20K, DEEP)	 /* SIO_SPI_2_FS1 */
+		PAD_CFG_GPI(GPIO_121, UP_20K, DEEP)	 /* SIO_SPI_2_FS2 */
+		/* WLAN_PE_RST - default to deasserted */
+		PAD_CFG_GPO(GPIO_122, 0, DEEP)		 /* SIO_SPI_2_RXD */
+		PAD_CFG_GPI(GPIO_123, UP_20K, DEEP)	 /* SIO_SPI_2_TXD */
+
+		/* Debug tracing */
+		PAD_CFG_GPI(GPIO_0, UP_20K, DEEP)
+		PAD_CFG_GPI(GPIO_1, UP_20K, DEEP)
+		PAD_CFG_GPI(GPIO_2, UP_20K, DEEP)
+		PAD_CFG_GPI_SCI_HIGH(GPIO_3, DN_20K, DEEP, LEVEL)	 /* FP_INT */
+		PAD_CFG_GPI(GPIO_4, UP_20K, DEEP)
+		PAD_CFG_GPI(GPIO_5, UP_20K, DEEP)
+		PAD_CFG_GPI(GPIO_6, UP_20K, DEEP)
+		PAD_CFG_GPI(GPIO_7, UP_20K, DEEP)
+		PAD_CFG_GPI(GPIO_8, UP_20K, DEEP)
+
+		PAD_CFG_GPI_APIC_LOW(GPIO_9, NONE, DEEP) /* dTPM IRQ */
+		PAD_CFG_GPI(GPIO_10, DN_20K, DEEP)	 /* Board phase enforcement */
+		PAD_CFG_GPI_SCI_LOW(GPIO_11, NONE, DEEP, EDGE_SINGLE) /* EC SCI  */
+		PAD_CFG_GPI(GPIO_12, UP_20K, DEEP)	 /* unused */
+		PAD_CFG_GPI_APIC_LOW(GPIO_13, NONE, DEEP) /* PEN_INT_ODL */
+		PAD_CFG_GPI_APIC_HIGH(GPIO_14, DN_20K, DEEP) /* FP_INT */
+		PAD_CFG_GPI_SCI_LOW(GPIO_15, NONE, DEEP, EDGE_SINGLE)	 /* TRACKPAD_INT_1V8_ODL */
+		PAD_CFG_GPI(GPIO_16, UP_20K, DEEP)	 /* unused */
+		PAD_CFG_GPI(GPIO_17, UP_20K, DEEP)	 /* 1 vs 4 DMIC config */
+		PAD_CFG_GPI_APIC_LOW(GPIO_18, NONE, DEEP) /* Trackpad IRQ */
+		PAD_CFG_GPI(GPIO_19, UP_20K, DEEP)	 /* unused */
+		PAD_CFG_GPI_APIC_LOW(GPIO_20, UP_20K, DEEP) /* NFC IRQ */
+		PAD_CFG_GPI_APIC_LOW(GPIO_21, NONE, DEEP) /* Touch IRQ */
+		PAD_CFG_GPI_SCI_LOW(GPIO_22, NONE, DEEP, EDGE_SINGLE) /* EC wake */
+		PAD_CFG_GPI(GPIO_23, UP_20K, DEEP)	 /* unused */
+		PAD_CFG_GPI(GPIO_24, NONE, DEEP)	 /* PEN_PDCT_ODL */
+		PAD_CFG_GPI(GPIO_25, UP_20K, DEEP)	 /* unused */
+		PAD_CFG_GPI(GPIO_26, UP_20K, DEEP)	 /* unused */
+		PAD_CFG_GPI(GPIO_27, UP_20K, DEEP)	 /* unused */
+		PAD_CFG_GPI_APIC_LOW(GPIO_28, NONE, DEEP) /* TPM IRQ */
+		PAD_CFG_GPO(GPIO_29, 1, DEEP)		 /* FP reset */
+		PAD_CFG_GPI_APIC_LOW(GPIO_30, NONE, DEEP) /* KB IRQ */
+		PAD_CFG_GPO(GPIO_31, 0, DEEP)		 /* NFC FW DL */
+		PAD_CFG_NF(GPIO_32, NONE, DEEP, NF5)	 /* SUS_CLK2 */
+		PAD_CFG_GPI_APIC_LOW(GPIO_33, NONE, DEEP) /* PMIC IRQ */
+		PAD_CFG_GPI(GPIO_34, UP_20K, DEEP)	 /* unused */
+		PAD_CFG_GPO(GPIO_35, 0, DEEP)		 /* PEN_RESET - active high */
+		PAD_CFG_GPO(GPIO_36, 0, DEEP)		 /* touch reset */
+		PAD_CFG_GPI(GPIO_37, UP_20K, DEEP)	 /* unused */
+
+		/* LPSS_UART[0:2] */
+		PAD_CFG_GPI(GPIO_38, NONE, DEEP)	 /* LPSS_UART0_RXD - MEM_CONFIG2*/
+		/* Next 2 are straps */
+		PAD_CFG_GPI(GPIO_39, DN_20K, DEEP)	 /* LPSS_UART0_TXD - unused */
+		PAD_CFG_GPI(GPIO_40, DN_20K, DEEP)	 /* LPSS_UART0_RTS - unused */
+		PAD_CFG_GPI(GPIO_41, NONE, DEEP)	 /* LPSS_UART0_CTS - EC_IN_RW */
+		PAD_CFG_NF(GPIO_42, NATIVE, DEEP, NF1)	 /* LPSS_UART1_RXD */
+		PAD_CFG_NF(GPIO_43, NATIVE, DEEP, NF1)	 /* LPSS_UART1_TXD */
+		PAD_CFG_GPO(GPIO_44, 1, DEEP)	 /* GPS_RST_ODL */
+		PAD_CFG_GPI(GPIO_45, NONE, DEEP)	 /* LPSS_UART1_CTS - MEM_CONFIG3 */
+		PAD_CFG_NF(GPIO_46, NATIVE, DEEP, NF1)	 /* LPSS_UART2_RXD */
+		PAD_CFG_NF_IOSSTATE(GPIO_47, NATIVE, DEEP, NF1, TX1_RX_DCR_X0) /* UART2 TX */
+		PAD_CFG_GPI(GPIO_48, UP_20K, DEEP)	 /* LPSS_UART2_RTS - unused */
+		PAD_CFG_GPI_SMI_LOW(GPIO_49, NONE, DEEP, EDGE_SINGLE) /* LPSS_UART2_CTS - EC_SMI_L */
+
+		/* Camera interface -- completely unused */
+		PAD_CFG_GPI(GPIO_62, UP_20K, DEEP)	 /* GP_CAMERASB00 */
+		PAD_CFG_GPI(GPIO_63, UP_20K, DEEP)	 /* GP_CAMERASB01 */
+		PAD_CFG_GPI(GPIO_64, UP_20K, DEEP)	 /* GP_CAMERASB02 */
+		PAD_CFG_GPI(GPIO_65, UP_20K, DEEP)	 /* GP_CAMERASB03 */
+		PAD_CFG_GPI(GPIO_66, UP_20K, DEEP)	 /* GP_CAMERASB04 */
+		PAD_CFG_GPI(GPIO_67, UP_20K, DEEP)	 /* GP_CAMERASB05 */
+		PAD_CFG_GPI(GPIO_68, UP_20K, DEEP)	 /* GP_CAMERASB06 */
+		PAD_CFG_GPI(GPIO_69, UP_20K, DEEP)	 /* GP_CAMERASB07 */
+		PAD_CFG_GPI(GPIO_70, UP_20K, DEEP)	 /* GP_CAMERASB08 */
+		PAD_CFG_GPI(GPIO_71, UP_20K, DEEP)	 /* GP_CAMERASB09 */
+		PAD_CFG_GPI(GPIO_72, UP_20K, DEEP)	 /* GP_CAMERASB10 */
+		PAD_CFG_GPI(GPIO_73, UP_20K, DEEP)	 /* GP_CAMERASB11 */
+	>;
+};
diff --git a/board/google/Kconfig b/board/google/Kconfig
index 679a0f1023..22c4be392f 100644
--- a/board/google/Kconfig
+++ b/board/google/Kconfig
@@ -8,6 +8,20 @@ choice
 	prompt "Mainboard model"
 	optional
 
+config TARGET_CHROMEBOOK_CORAL
+	bool "Chromebook coral"
+	help
+	  This is a range of Intel-based laptops released in 2018. They use an
+	  Intel Apollo Lake SoC. The design supports WiFi, 4GB to 16GB of
+	  LPDDR4 1600MHz SDRAM, PCIe WiFi and Bluetooth, eMMC (typically 32GB),
+	  up two cameras (front-facing 720p and another 5MP option), USB SD
+	  reader, microphone and speakers. It also includes two USB 3 Type A and
+	  two Type C ports. The latter are used as power input and can also
+	  charge external devices as well as a 4K external display. There is a
+	  Chrome OS EC connected on LPC, a Cr50 secure chip from Google and
+	  various display options. OEMs products include Acer Chromebook 11
+	  (e.g. C732, CB11, CP311) and Lenovo Chromebook (100e, 300e, 500e).
+
 config TARGET_CHROMEBOOK_LINK
 	bool "Chromebook link"
 	help
@@ -62,6 +76,7 @@ config TARGET_CHROMEBOOK_SAMUS_TPL
 
 endchoice
 
+source "board/google/chromebook_coral/Kconfig"
 source "board/google/chromebook_link/Kconfig"
 source "board/google/chromebox_panther/Kconfig"
 source "board/google/chromebook_samus/Kconfig"
diff --git a/board/google/chromebook_coral/Kconfig b/board/google/chromebook_coral/Kconfig
new file mode 100644
index 0000000000..940bee89b0
--- /dev/null
+++ b/board/google/chromebook_coral/Kconfig
@@ -0,0 +1,43 @@
+if TARGET_CHROMEBOOK_CORAL
+
+config SYS_BOARD
+	default "chromebook_coral"
+
+config SYS_VENDOR
+	default "google"
+
+config SYS_SOC
+	default "apollolake"
+
+config SYS_CONFIG_NAME
+	default "chromebook_coral"
+
+config SYS_TEXT_BASE
+	default 0xffe00000
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+	def_bool y
+	select X86_RESET_VECTOR
+	select INTEL_APOLLOLAKE
+	select BOARD_ROMSIZE_KB_16384
+
+config PCIE_ECAM_BASE
+	default 0xf0000000
+
+config EARLY_POST_CROS_EC
+	bool "Enable early post to Chrome OS EC"
+	help
+	  Allow post codes to be sent to the Chroem OS EC early during boot,
+	  to enable monitoring of the boot and debugging when things go wrong.
+	  With this option enabled, the EC console can be used to watch post
+	  codes the first part of boot.
+
+config SYS_CAR_ADDR
+	hex
+	default 0xfef00000
+
+config SYS_CAR_SIZE
+	hex
+	default 0xc0000
+
+endif
diff --git a/board/google/chromebook_coral/MAINTAINERS b/board/google/chromebook_coral/MAINTAINERS
new file mode 100644
index 0000000000..904227e2e2
--- /dev/null
+++ b/board/google/chromebook_coral/MAINTAINERS
@@ -0,0 +1,6 @@
+CHROMEBOOK_CORAL_BOARD
+M:	Simon Glass <sjg@chromium.org>
+S:	Maintained
+F:	board/google/chromebook_coral/
+F:	include/configs/chromebook_coral.h
+F:	configs/chromebook_coral_defconfig
diff --git a/board/google/chromebook_coral/Makefile b/board/google/chromebook_coral/Makefile
new file mode 100644
index 0000000000..6a27ce3da1
--- /dev/null
+++ b/board/google/chromebook_coral/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright 2019 Google LLC
+
+obj-y	+= coral.o
diff --git a/board/google/chromebook_coral/coral.c b/board/google/chromebook_coral/coral.c
new file mode 100644
index 0000000000..4e34710b97
--- /dev/null
+++ b/board/google/chromebook_coral/coral.c
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2019 Google LLC
+ */
+
+#include <common.h>
+
+int arch_misc_init(void)
+{
+	return 0;
+}
+
+/* This function is needed if CONFIG_CMDLINE is not enabled */
+int board_run_command(const char *cmdline)
+{
+	printf("No command line\n");
+
+	return 0;
+}
diff --git a/configs/chromebook_coral_defconfig b/configs/chromebook_coral_defconfig
new file mode 100644
index 0000000000..566d47d22f
--- /dev/null
+++ b/configs/chromebook_coral_defconfig
@@ -0,0 +1,102 @@
+CONFIG_X86=y
+CONFIG_SYS_TEXT_BASE=0x1110000
+CONFIG_SYS_MALLOC_F_LEN=0x3d00
+CONFIG_SPL_SYS_MALLOC_F_LEN=0xf000
+CONFIG_NR_DRAM_BANKS=8
+CONFIG_BOOTSTAGE_STASH_ADDR=0xfef00000
+CONFIG_DEBUG_UART_BOARD_INIT=y
+CONFIG_DEBUG_UART_BASE=0xde000000
+CONFIG_DEBUG_UART_CLOCK=1843200
+CONFIG_VENDOR_GOOGLE=y
+CONFIG_TARGET_CHROMEBOOK_CORAL=y
+CONFIG_DEBUG_UART=y
+CONFIG_FSP_VERSION2=y
+CONFIG_HAVE_ACPI_RESUME=y
+CONFIG_INTEL_CAR_CQOS=y
+CONFIG_X86_OFFSET_U_BOOT=0xffe00000
+CONFIG_X86_OFFSET_SPL=0xffe80000
+CONFIG_SPL_TEXT_BASE=0xfef10000
+CONFIG_BOOTSTAGE=y
+CONFIG_SPL_BOOTSTAGE=y
+CONFIG_TPL_BOOTSTAGE=y
+CONFIG_BOOTSTAGE_REPORT=y
+CONFIG_SPL_BOOTSTAGE_RECORD_COUNT=10
+CONFIG_BOOTSTAGE_STASH=y
+CONFIG_USE_BOOTARGS=y
+CONFIG_BOOTARGS="root=/dev/sdb3 init=/sbin/init rootwait ro earlyprintk console=tty0 console=ttyS0,115200"
+CONFIG_SYS_CONSOLE_INFO_QUIET=y
+CONFIG_SPL_LOG=y
+CONFIG_LOG_DEFAULT_LEVEL=7
+CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_LAST_STAGE_INIT=y
+CONFIG_BLOBLIST=y
+# CONFIG_TPL_BLOBLIST is not set
+CONFIG_BLOBLIST_ADDR=0x100000
+CONFIG_HANDOFF=y
+CONFIG_TPL_SYS_MALLOC_SIMPLE=y
+CONFIG_SPL_SEPARATE_BSS=y
+CONFIG_SPL_CPU_SUPPORT=y
+CONFIG_SPL_PCI=y
+# CONFIG_SPL_SPI_FLASH_TINY is not set
+CONFIG_HUSH_PARSER=y
+CONFIG_CMD_CPU=y
+CONFIG_CMD_PMC=y
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_PART=y
+CONFIG_CMD_READ=y
+CONFIG_CMD_SATA=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_USB=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_TIME=y
+CONFIG_CMD_SOUND=y
+CONFIG_CMD_BOOTSTAGE=y
+CONFIG_CMD_TPM=y
+CONFIG_CMD_TPM_TEST=y
+CONFIG_CMD_EXT2=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_EXT4_WRITE=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_MAC_PARTITION=y
+# CONFIG_SPL_MAC_PARTITION is not set
+# CONFIG_SPL_DOS_PARTITION is not set
+CONFIG_ISO_PARTITION=y
+CONFIG_EFI_PARTITION=y
+# CONFIG_SPL_EFI_PARTITION is not set
+CONFIG_DEFAULT_DEVICE_TREE="chromebook_coral"
+# CONFIG_NET is not set
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_SPL_OF_TRANSLATE=y
+CONFIG_CPU=y
+CONFIG_DM_I2C=y
+CONFIG_SYS_I2C_DW=y
+CONFIG_TPL_MISC=y
+CONFIG_CROS_EC=y
+CONFIG_CROS_EC_LPC=y
+CONFIG_SPI_FLASH_WINBOND=y
+# CONFIG_X86_PCH7 is not set
+# CONFIG_X86_PCH9 is not set
+CONFIG_PINCTRL=y
+# CONFIG_SPL_PINCTRL_FULL is not set
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SYS_NS16550=y
+CONFIG_SOUND=y
+CONFIG_SOUND_I8254=y
+CONFIG_SOUND_RT5677=y
+CONFIG_SPI=y
+CONFIG_ICH_SPI=y
+CONFIG_TPL_SYSRESET=y
+CONFIG_TPM_TIS_LPC=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_KEYBOARD=y
+CONFIG_SPL_FS_CBFS=y
+# CONFIG_SPL_USE_TINY_PRINTF is not set
+CONFIG_TPL_USE_TINY_PRINTF=y
+CONFIG_CMD_DHRYSTONE=y
+CONFIG_TPM=y
+# CONFIG_EFI_LOADER is not set
diff --git a/doc/board/google/chromebook_coral.rst b/doc/board/google/chromebook_coral.rst
new file mode 100644
index 0000000000..515fd06d76
--- /dev/null
+++ b/doc/board/google/chromebook_coral.rst
@@ -0,0 +1,241 @@
+.. SPDX-License-Identifier: GPL-2.0+
+.. sectionauthor:: Simon Glass <sjg@chromium.org>
+
+Chromebook Coral
+================
+
+Coral is a Chromebook (or really about 20 different Chromebooks) which use the
+Intel Apollo Lake platform (APL). The 'reef' Chromebooks use the same APL SoC so
+should also work. Some later ones based on Glacier Lake (GLK) need various
+changes in GPIOs, etc. but are very similar.
+
+It is hoped that this port can enable ports to embedded APL boards which are
+starting to appear.
+
+Note that booting U-Boot on APL is already supported by coreboot and
+Slim Bootloader. This documentation refers to a 'bare metal' port.
+
+
+Boot flow - TPL
+---------------
+
+Apollo Lake boots via an IFWI (Integrated Firmware Image). TPL is placed in
+this, in the IBBL entry.
+
+On boot, an on-chip microcontroller called the CSE (Converged Security Engine)
+sets up some SDRAM at ffff8000 and loads the TPL image to that address. The
+SRAM extends up to the top of 32-bit address space, but the last 2KB is the
+start16 region, so the TPL image must be 30KB at most, and CONFIG_TPL_TEXT_BASE
+must be ffff8000. Actually the start16 region is small and it could probably
+move from f800 to fe00, providing another 1.5KB, but TPL is only about 19KB so
+there is no need to change it at present. The size limit is enforced by
+CONFIG_TPL_SIZE_LIMIT to avoid producing images that won't boot.
+
+TPL (running from start.S) first sets up CAR (Cache-as-RAM) which provides
+larger area of RAM for use while booting. CAR is mapped at CONFIG_SYS_CAR_ADDR
+(fef00000) and is 768KB in size. It then sets up the stack in the botttom 64KB
+of this space (i.e. below fef10000). This means that the stack and early
+malloc() region in TPL can be 64KB at most.
+
+TPL operates without CONFIG_TPL_PCI enabled so PCI config access must use the
+x86-specific functions pci_x86_write_config(), etc. SPL creates a simple-bus
+device so that PCI devices are bound by driver model. Then arch_cpu_init_tpl()
+is called to early init on various devices. This includes placing PCI devices
+at hard-coded addresses in the memory map. PCI auto-config is not used.
+
+Most of the 16KB ROM is mapped into the very top of memory, except for the
+Intel descriptor (first 4KB) and the space for SRAM as above.
+
+TPL does not set up a bloblist since at present it does not have anything to
+pass to SPL.
+
+Once TPL is done it loads SPL from ROM using either the memory-mapped SPI or by
+using the Intel fast SPI driver. SPL is loaded into CAR, at the address given
+by CONFIG_SPL_TEXT_BASE, which is normally fef10000.
+
+Note that booting using the SPI driver results in an TPL image that is about
+26KB in size instead of 19KB. Also boot speed is worse by about 340ms. If you
+really want to use the driver, enable CONFIG_APL_SPI_FLASH_BOOT and set
+BOOT_FROM_FAST_SPI_FLASH to true[2].
+
+
+Boot flow - SPL
+---------------
+
+SPL (running from start_from_tpl.S) continues to use the same stack as TPL.
+It calls arch_cpu_init_spl() to set up a few devices, then init_dram() loads
+the FSP-M binary into CAR and runs to, to set up SDRAM. The address of the
+output 'HOB' list (Hand-off-block) is stored into gd->arch.hob_list for parsing.
+There is a 2GB chunk of SDRAM starting at 0 and the rest is at 4GB.
+
+PCI auto-config is not used in SPL either, but CONFIG_SPL_PCI is defined, so
+proper PCI access is available and normal dm_pci_read_config() calls can be
+used. However PCI auto-config is not used so the same static memory mapping set
+up by TPL is still active.
+
+SPL on x86 always runs with CONFIG_SPL_SEPARATE_BSS=y and BSS is at 120000
+(see u-boot-spl.lds). This works because SPL doesn't access BSS until after
+board_init_r(), as per the rules, and DRAM is available then.
+
+SPL sets up a bloblist and passes the SPL hand-off information to U-Boot proper.
+This includes a pointer to the HOB list as well as DRAM information. See
+struct arch_spl_handoff. The bloblist address is set by CONFIG_BLOBLIST_ADDR,
+normally 100000.
+
+SPL uses SPI flash to update the MRC caches in ROM. This speeds up subsequent
+boots. Be warned that SPL can take 30 seconds without this cache! This is a
+known issue with Intel SoCs with modern DRAM and apparently cannot be improved.
+The MRC caches are used to work around this.
+
+Once SPL is finished it loads U-Boot into SDRAM at CONFIG_SYS_TEXT_BASE, which
+is normally 1110000. Note that CAR is still active.
+
+
+Boot flow - U-Boot pre-relocation
+---------------------------------
+
+U-Boot (running from start_from_spl.S) starts running in RAM and uses the same
+stack as SPL. It does various init activities before relocation. Notably
+arch_cpu_init_dm() sets up the pin muxing for the chip using a very large table
+in the device tree.
+
+PCI auto-config is not used before relocation, but CONFIG_PCI of course is
+defined, so proper PCI access is available. The same static memory mapping set
+up by TPL is still active until relocation.
+
+As per usual, U-Boot allocates memory at the top of available RAM (a bit below
+2GB in this case) and copies things there ready to relocate itself. Notably
+reserve_arch() does not reserve space for the HOB list returned by FSP-M since
+this is already located in RAM.
+
+U-Boot then shuts down CAR and jumps to its relocated version.
+
+
+Boot flow - U-Boot post-relocation
+---------------------------------
+
+U-Boot starts up normally, running near the top of RAM. After driver model is
+running, arch_fsp_init_r() is called which loads and runs the FSP-S binary.
+This updates the HOB list to include graphics information, used by the fsp_video
+driver.
+
+PCI autoconfig is done and a few devices are probed to complete init. Most
+others are started only when they are used.
+
+Note that FSP-S is supposed to run after CAR has been shut down, which happens
+immediately before U-Boot starts up in its relocated position. Therefore we
+cannot run FSP-S before relocation. On the other hand we must run it before
+PCI auto-config is done, since FSP-S may show or hide devices. The first device
+that probes PCI after relocation is the serial port, in initr_serial(), so FSP-S
+must run before that. A corollary is that loading FSP-S must be done without
+using the SPI driver, to avoid probing PCI and causing an autoconfig, so
+memory-mapped reading is always used for FSP-S.
+
+It would be possible to tear down CAR in SPL instead of U-Boot. The SPL handoff
+information could make sure it does not include any pointers into CAR (in fact
+it doesn't). But tearing down CAR in U-Boot allows the initial state used by TPL
+and SPL to be read by U-Boot, which seems useful. It also matches how older
+platforms start up (those that don't use SPL).
+
+
+Performance
+-----------
+
+Bootstage is used through all phases of U-Boot to keep accurate timimgs for
+boot. Use 'bootstage report' in U-Boot to see the report, e.g.:
+
+Timer summary in microseconds (16 records):
+       Mark    Elapsed  Stage
+          0          0  reset
+    155,325    155,325  TPL
+    204,014     48,689  end TPL
+    204,385        371  SPL
+    738,633    534,248  end SPL
+    739,161        528  board_init_f
+    842,764    103,603  board_init_r
+  1,166,233    323,469  main_loop
+  1,166,283         50  id=175
+
+Accumulated time:
+                    62  fast_spi
+                   202  dm_r
+                 7,779  dm_spl
+                15,555  dm_f
+               208,357  fsp-m
+               239,847  fsp-s
+               292,143  mmap_spi
+
+CPU performance is about 3500 DMIPS:
+
+=> dhry
+1000000 iterations in 161 ms: 6211180/s, 3535 DMIPS
+
+
+Partial memory map
+------------------
+
+ffffffff	Top of ROM (and last byte of 32-bit address space)
+ffff8000	TPL loaded here (from IFWI)
+ff000000	Bottom of ROM
+fefc000		 Top of CAR region
+fef96000	Stack for FSP-M
+fef40000 59000	FSP-M
+fef11000	SPL loaded here
+fef10000	CONFIG_BLOBLIST_ADDR
+fef10000	Stack top in TPL, SPL and U-Boot before relocation
+fef00000  1000	CONFIG_BOOTSTAGE_STASH_ADDR
+fef00000	Base of CAR region
+
+   f0000	CONFIG_ROM_TABLE_ADDR
+  120000	BSS (defined in u-boot-spl.lds)
+  200000	FSP-S (which is run after U-Boot is relocated)
+ 1110000	CONFIG_SYS_TEXT_BASE
+
+
+Supported peripherals
+---------------------
+
+- UART
+- SPI flash
+- Video
+- MMC (dev 0) and micro-SD (dev 1)
+- Chrome OS EC
+- Keyboard
+- USB
+
+
+To do
+-----
+
+- Finish peripherals
+   - left-side USB
+   - USB-C
+   - Cr50 (security chip: a basic driver is running but not included here)
+   - I2C (driver exists but not enabled in device tree)
+   - Sound (Intel I2S support exists, but need da7219 driver)
+   - RTC (driver exists but not enabled in device tree)
+   - Various minor features supported by LPC, etc.
+- Booting Chrome OS, e.g. with verified boot
+- Integrate with Chrome OS vboot
+- Improvements to booting from coreboot (i.e. as a coreboot target)
+- Use FSP-T binary instead of our own CAR implementation
+- Use the official FSP package instead of the coreboot one
+- Enable all CPU cores
+- Suspend / resume
+- ACPI
+
+
+Credits
+-------
+
+This is a spare-time project conducted slowly over a long period of time.
+
+Much of the code for this port came from Coreboot, an open-source firmware
+project similar to U-Boot's SPL in terms of features.
+
+Also see [2] for information about the boot flow used by coreboot. It is
+similar, but has an extra postcar stage. U-Boot doesn't need this since it
+supports relocating itself in memory.
+
+
+[2] Intel PDF https://www.coreboot.org/images/2/23/Apollolake_SoC.pdf
diff --git a/doc/board/google/index.rst b/doc/board/google/index.rst
index 7f557feb44..061c797718 100644
--- a/doc/board/google/index.rst
+++ b/doc/board/google/index.rst
@@ -6,5 +6,6 @@ Google
 .. toctree::
    :maxdepth: 2
 
+   chromebook_coral
    chromebook_link
    chromebook_samus
diff --git a/include/configs/chromebook_coral.h b/include/configs/chromebook_coral.h
new file mode 100644
index 0000000000..a63c3c9eea
--- /dev/null
+++ b/include/configs/chromebook_coral.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2019 Google LLC
+ */
+
+/*
+ * board/config.h - configuration options, board-specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#define CONFIG_BOOTCOMMAND	\
+	"fatload mmc 1:c 1000000 syslinux/vmlinuz.A; zboot 1000000"
+
+#include <configs/x86-common.h>
+#include <configs/x86-chromebook.h>
+
+#undef CONFIG_STD_DEVICES_SETTINGS
+#define CONFIG_STD_DEVICES_SETTINGS     "stdin=usbkbd,i8042-kbd,serial\0" \
+					"stdout=vidconsole,serial\0" \
+					"stderr=vidconsole,serial\0"
+
+#define CONFIG_ENV_SECT_SIZE		0x1000
+#define CONFIG_ENV_OFFSET		0x003f8000
+
+#define CONFIG_TPL_TEXT_BASE		0xffff8000
+
+#define CONFIG_SYS_NS16550_MEM32
+#undef CONFIG_SYS_NS16550_PORT_MAPPED
+
+#endif	/* __CONFIG_H */
-- 
2.24.0.393.g34dc348eaf-goog

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v7 13/17] x86: apl: Add P2SB driver
  2019-12-09  0:40 ` [PATCH v7 13/17] x86: apl: Add P2SB driver Simon Glass
@ 2019-12-10 14:11   ` Bin Meng
  2019-12-15  0:44     ` Bin Meng
  0 siblings, 1 reply; 29+ messages in thread
From: Bin Meng @ 2019-12-10 14:11 UTC (permalink / raw)
  To: u-boot

On Mon, Dec 9, 2019 at 8:41 AM Simon Glass <sjg@chromium.org> wrote:
>
> Adds a driver for the Apollo Lake Primary-to-sideband bus. This supports
> various child devices. It supposed both device tree and of-platdata.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v7:
> - Update comment in apl_p2sb_early_init()
>
> Changes in v6: None
> Changes in v5: None
> Changes in v4:
> - Detect zero mmio address
> - Use BIT() macro bit more
> - apollolake -> Apollo Lake
>
> Changes in v3:
> - Use pci_get_devfn()
>
> Changes in v2: None
>
>  arch/x86/cpu/apollolake/Makefile |   1 +
>  arch/x86/cpu/apollolake/p2sb.c   | 166 +++++++++++++++++++++++++++++++
>  2 files changed, 167 insertions(+)
>  create mode 100644 arch/x86/cpu/apollolake/p2sb.c
>

Reviewed-by: Bin Meng <bmeng.cn@gmail.com>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v7 04/17] x86: apl: Add hostbridge driver
  2019-12-09  0:40 [PATCH v7 04/17] x86: apl: Add hostbridge driver Simon Glass
                   ` (12 preceding siblings ...)
  2019-12-09  0:40 ` [PATCH v7 17/17] x86: Add chromebook_coral Simon Glass
@ 2019-12-15  0:36 ` Bin Meng
  13 siblings, 0 replies; 29+ messages in thread
From: Bin Meng @ 2019-12-15  0:36 UTC (permalink / raw)
  To: u-boot

On Mon, Dec 9, 2019 at 8:40 AM Simon Glass <sjg@chromium.org> wrote:
>
> This driver models the hostbridge as a northbridge. It simply sets up the
> graphics BAR. It supports of-platdata.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
> ---
>
> Changes in v7: None
> Changes in v6:
> - Fix comments for struct apl_hostbridge_platdata
>
> Changes in v5: None
> Changes in v4:
> - Avoid needing to know internals of pinctrl in this driver
> - Move code to pinctrl driver
> - Switch over to use pinctrl for pad init/config
>
> Changes in v3:
> - Move pad programming into the hostbridge to reduce TPL device-tree size
> - Use pci_get_devfn()
>
> Changes in v2: None
>
>  arch/x86/cpu/apollolake/Makefile     |   1 +
>  arch/x86/cpu/apollolake/hostbridge.c | 179 +++++++++++++++++++++++++++
>  2 files changed, 180 insertions(+)
>  create mode 100644 arch/x86/cpu/apollolake/hostbridge.c
>

applied to u-boot-x86/next, thanks!

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v7 05/17] x86: apl: Add ITSS driver
  2019-12-09  0:40 ` [PATCH v7 05/17] x86: apl: Add ITSS driver Simon Glass
@ 2019-12-15  0:36   ` Bin Meng
  0 siblings, 0 replies; 29+ messages in thread
From: Bin Meng @ 2019-12-15  0:36 UTC (permalink / raw)
  To: u-boot

On Mon, Dec 9, 2019 at 8:41 AM Simon Glass <sjg@chromium.org> wrote:
>
> This driver models some sort of interrupt thingy but there are so many
> abreviations that I cannot find out what it stands for. Possibly something
> to do with interrupts.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
> ---
>
> Changes in v7: None
> Changes in v6: None
> Changes in v5: None
> Changes in v4:
> - Tidy up header guards
>
> Changes in v3:
> - Add snapshot/restore for IRQs
> - Use the IRQ uclass instead of ITSS
>
> Changes in v2: None
>
>  arch/x86/cpu/apollolake/Makefile            |   1 +
>  arch/x86/cpu/apollolake/itss.c              | 214 ++++++++++++++++++++
>  arch/x86/include/asm/arch-apollolake/itss.h |  43 ++++
>  3 files changed, 258 insertions(+)
>  create mode 100644 arch/x86/cpu/apollolake/itss.c
>  create mode 100644 arch/x86/include/asm/arch-apollolake/itss.h
>

applied to u-boot-x86/next, thanks!

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v7 06/17] x86: apl: Add LPC driver
  2019-12-09  0:40 ` [PATCH v7 06/17] x86: apl: Add LPC driver Simon Glass
@ 2019-12-15  0:38   ` Bin Meng
  0 siblings, 0 replies; 29+ messages in thread
From: Bin Meng @ 2019-12-15  0:38 UTC (permalink / raw)
  To: u-boot

On Mon, Dec 9, 2019 at 8:41 AM Simon Glass <sjg@chromium.org> wrote:
>
> This driver the LPC and provides a few functions to set up LPC features.
> These should probably use ioctls() or perhaps, better, have specific
> uclass methods.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
> ---
>
> Changes in v7: None
> Changes in v6:
> - Drop init of ComB since it is not used
> - Drop lpc_configure_pads() and probe() function, add a comment about pads
>
> Changes in v5: None
> Changes in v4:
> - Add comments for exported functions
> - Tidy up header guards
> - Use 'Apollo Lake'
> - Use BIT() macro a bit more
> - Use tabs instead of spaces
>
> Changes in v3:
> - Drop unused code in lpc_configure_pads()
> - Fix value of LPC_BC_LE
>
> Changes in v2: None
>
>  arch/x86/cpu/apollolake/Makefile           |   1 +
>  arch/x86/cpu/apollolake/lpc.c              | 122 +++++++++++++++++++++
>  arch/x86/include/asm/arch-apollolake/lpc.h |  82 ++++++++++++++
>  3 files changed, 205 insertions(+)
>  create mode 100644 arch/x86/cpu/apollolake/lpc.c
>  create mode 100644 arch/x86/include/asm/arch-apollolake/lpc.h
>

applied to u-boot-x86/next, thanks!

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v7 07/17] x86: apl: Add PCH driver
  2019-12-09  0:40 ` [PATCH v7 07/17] x86: apl: Add PCH driver Simon Glass
@ 2019-12-15  0:39   ` Bin Meng
  0 siblings, 0 replies; 29+ messages in thread
From: Bin Meng @ 2019-12-15  0:39 UTC (permalink / raw)
  To: u-boot

On Mon, Dec 9, 2019 at 8:41 AM Simon Glass <sjg@chromium.org> wrote:
>
> Add a driver for the Apollo Lake Platform Controller Hub. It does not have
> any functionality and is just a placeholder for now.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
> ---
>
> Changes in v7: None
> Changes in v6: None
> Changes in v5: None
> Changes in v4:
> - Tidy up header guards
> - Update SPI flash protection only in SPL
> - apollolake -> Apollo Lake
>
> Changes in v3: None
> Changes in v2:
> - Drop probe() function
> - Implement set_spi_protect()
>
>  arch/x86/cpu/apollolake/Makefile           |  1 +
>  arch/x86/cpu/apollolake/pch.c              | 36 ++++++++++++++++++++++
>  arch/x86/include/asm/arch-apollolake/pch.h |  9 ++++++
>  3 files changed, 46 insertions(+)
>  create mode 100644 arch/x86/cpu/apollolake/pch.c
>  create mode 100644 arch/x86/include/asm/arch-apollolake/pch.h
>

applied to u-boot-x86/next, thanks!

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v7 08/17] x86: apl: Add PUNIT driver
  2019-12-09  0:40 ` [PATCH v7 08/17] x86: apl: Add PUNIT driver Simon Glass
@ 2019-12-15  0:40   ` Bin Meng
  0 siblings, 0 replies; 29+ messages in thread
From: Bin Meng @ 2019-12-15  0:40 UTC (permalink / raw)
  To: u-boot

On Mon, Dec 9, 2019 at 8:41 AM Simon Glass <sjg@chromium.org> wrote:
>
> Add a driver for the Apollo Lake P-unit (power unit). It is modelled as a
> syscon driver since it only needs to be probed.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
> ---
>
> Changes in v7: None
> Changes in v6:
> - Drop Glacier Lake code
> - Drop platform data and pre-PCI code, since DM PCI is available in SPL
>
> Changes in v5: None
> Changes in v4:
> - Name this P-Unit instead of power unit, in the commit message
> - apollolake -> Apollo Lake
>
> Changes in v3:
> - Use pci_get_devfn()
>
> Changes in v2: None
>
>  arch/x86/cpu/apollolake/Makefile |  3 +
>  arch/x86/cpu/apollolake/punit.c  | 94 ++++++++++++++++++++++++++++++++
>  2 files changed, 97 insertions(+)
>  create mode 100644 arch/x86/cpu/apollolake/punit.c
>

applied to u-boot-x86/next, thanks!

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v7 09/17] spl: Add methods to find the position/size of next phase
  2019-12-09  0:40 ` [PATCH v7 09/17] spl: Add methods to find the position/size of next phase Simon Glass
@ 2019-12-15  0:40   ` Bin Meng
  0 siblings, 0 replies; 29+ messages in thread
From: Bin Meng @ 2019-12-15  0:40 UTC (permalink / raw)
  To: u-boot

On Mon, Dec 9, 2019 at 8:41 AM Simon Glass <sjg@chromium.org> wrote:
>
> Binman supports writing the position and size of U-Boot proper and SPL
> into the previous phase of U-Boot. This allows the next phase to be easily
> located and loaded.
>
> Add functions to return these useful values, along with symbols to allow
> TPL to load SPL.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
> ---
>
> Changes in v7: None
> Changes in v6:
> - Add new patch with methods to find the position/size of next SPL phase
>
> Changes in v5: None
> Changes in v4: None
> Changes in v3: None
> Changes in v2: None
>
>  common/spl/spl.c | 20 ++++++++++++++++++++
>  include/spl.h    | 21 ++++++++++++++++++++-
>  2 files changed, 40 insertions(+), 1 deletion(-)
>

applied to u-boot-x86/next, thanks!

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v7 10/17] x86: apl: Add SPL loaders
  2019-12-09  0:40 ` [PATCH v7 10/17] x86: apl: Add SPL loaders Simon Glass
@ 2019-12-15  0:41   ` Bin Meng
  0 siblings, 0 replies; 29+ messages in thread
From: Bin Meng @ 2019-12-15  0:41 UTC (permalink / raw)
  To: u-boot

On Mon, Dec 9, 2019 at 8:41 AM Simon Glass <sjg@chromium.org> wrote:
>
> Add loaders for SPL and TPL so that the next stage can be loaded from
> memory-mapped SPI or, failing that, the Fast SPI driver.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
>
> ---
>
> Changes in v7: None
> Changes in v6:
> - Make BOOT_FROM_FAST_SPI_FLASH a Kconfig option
> - Move image pos/size access functions and symbols to generic SPL code
>
> Changes in v5:
> - Add L2 cache flush functoin
> - Drop SAFETY_MARGIN
>
> Changes in v4: None
> Changes in v3:
> - Add a driver for APL SPI for TPL (using of-platdata)
> - Support TPL without CONFIG_TPL_SPI_SUPPORT
> - Support bootstage timing
>
> Changes in v2: None
>
>  arch/x86/cpu/apollolake/Makefile |   2 +
>  arch/x86/cpu/apollolake/spl.c    | 178 +++++++++++++++++++++++++++++++
>  2 files changed, 180 insertions(+)
>  create mode 100644 arch/x86/cpu/apollolake/spl.c
>

applied to u-boot-x86/next, thanks!

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v7 11/17] x86: apl: Add a CPU driver
  2019-12-09  0:40 ` [PATCH v7 11/17] x86: apl: Add a CPU driver Simon Glass
@ 2019-12-15  0:43   ` Bin Meng
  0 siblings, 0 replies; 29+ messages in thread
From: Bin Meng @ 2019-12-15  0:43 UTC (permalink / raw)
  To: u-boot

On Mon, Dec 9, 2019 at 8:41 AM Simon Glass <sjg@chromium.org> wrote:
>
> Add a bare-bones CPU driver so that CPUs can be probed.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
> ---
>
> Changes in v7: None
> Changes in v6:
> - Drop unnecessary priv struct and probe method
> - Make BOOT_FROM_FAST_SPI_FLASH a Kconfig option
>
> Changes in v5:
> - Add L2 cache flush function
> - Drop SAFETY_MARGIN
>
> Changes in v4:
> - Change apollolake to apl
> - Tidy up header guards
>
> Changes in v3:
> - Add two more defines for the CPU driver
> - Expand comments for BOOT_FROM_FAST_SPI_FLASH
>
> Changes in v2: None
>
>  arch/x86/cpu/apollolake/Makefile           |  2 ++
>  arch/x86/cpu/apollolake/cpu.c              | 41 ++++++++++++++++++++++
>  arch/x86/cpu/apollolake/cpu_common.c       | 17 +++++++++
>  arch/x86/include/asm/arch-apollolake/cpu.h | 20 +++++++++++
>  arch/x86/include/asm/msr-index.h           |  1 +
>  5 files changed, 81 insertions(+)
>  create mode 100644 arch/x86/cpu/apollolake/cpu.c
>  create mode 100644 arch/x86/cpu/apollolake/cpu_common.c
>  create mode 100644 arch/x86/include/asm/arch-apollolake/cpu.h
>

applied to u-boot-x86/next, thanks!

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v7 12/17] x86: apl: Add SPL/TPL init
  2019-12-09  0:40 ` [PATCH v7 12/17] x86: apl: Add SPL/TPL init Simon Glass
@ 2019-12-15  0:44   ` Bin Meng
  0 siblings, 0 replies; 29+ messages in thread
From: Bin Meng @ 2019-12-15  0:44 UTC (permalink / raw)
  To: u-boot

On Mon, Dec 9, 2019 at 8:41 AM Simon Glass <sjg@chromium.org> wrote:
>
> Add code to init the system both in TPL and SPL. Each phase has its own
> procedure.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
> ---
>
> Changes in v7: None
> Changes in v6:
> - Change comment to apl_hostbridge_early_init_pinctrl, not apl_gpio_early_init
> - Change commented-out enable_rtc_upper_bank() call to a TODO
> - Make BOOT_FROM_FAST_SPI_FLASH a Kconfig option
> - Rename init_for_uart() to board_debug_uart_init()
> - Use SZ_4G instead of open-coded shift
>
> Changes in v5: None
> Changes in v4:
> - Switch over to use pinctrl for pad init/config
>
> Changes in v3:
> - Adjust fast_spi_cache_bios_region() to avoid using SPI driver
> - Drop calls to x86_cpu_init_f(), x86_cpu_reinit_f()
> - Fix build error when debug UART is disabled
> - Init the p2sb before the northbridge since the latter so it can use GPIOs
> - Move location of fast_spi.h header file
> - Shorten log_msg_ret() calls since the function name is always printed
> - Support TPL without CONFIG_TPL_SPI_SUPPORT (reduces code size)
>
> Changes in v2: None
>
>  arch/x86/cpu/apollolake/Makefile  |   1 +
>  arch/x86/cpu/apollolake/cpu_spl.c | 271 ++++++++++++++++++++++++++++++
>  2 files changed, 272 insertions(+)
>  create mode 100644 arch/x86/cpu/apollolake/cpu_spl.c
>

applied to u-boot-x86/next, thanks!

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v7 13/17] x86: apl: Add P2SB driver
  2019-12-10 14:11   ` Bin Meng
@ 2019-12-15  0:44     ` Bin Meng
  0 siblings, 0 replies; 29+ messages in thread
From: Bin Meng @ 2019-12-15  0:44 UTC (permalink / raw)
  To: u-boot

On Tue, Dec 10, 2019 at 10:11 PM Bin Meng <bmeng.cn@gmail.com> wrote:
>
> On Mon, Dec 9, 2019 at 8:41 AM Simon Glass <sjg@chromium.org> wrote:
> >
> > Adds a driver for the Apollo Lake Primary-to-sideband bus. This supports
> > various child devices. It supposed both device tree and of-platdata.
> >
> > Signed-off-by: Simon Glass <sjg@chromium.org>
> > ---
> >
> > Changes in v7:
> > - Update comment in apl_p2sb_early_init()
> >
> > Changes in v6: None
> > Changes in v5: None
> > Changes in v4:
> > - Detect zero mmio address
> > - Use BIT() macro bit more
> > - apollolake -> Apollo Lake
> >
> > Changes in v3:
> > - Use pci_get_devfn()
> >
> > Changes in v2: None
> >
> >  arch/x86/cpu/apollolake/Makefile |   1 +
> >  arch/x86/cpu/apollolake/p2sb.c   | 166 +++++++++++++++++++++++++++++++
> >  2 files changed, 167 insertions(+)
> >  create mode 100644 arch/x86/cpu/apollolake/p2sb.c
> >
>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>

applied to u-boot-x86/next, thanks!

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v7 14/17] x86: apl: Add Kconfig and Makefile
  2019-12-09  0:40 ` [PATCH v7 14/17] x86: apl: Add Kconfig and Makefile Simon Glass
@ 2019-12-15  0:45   ` Bin Meng
  0 siblings, 0 replies; 29+ messages in thread
From: Bin Meng @ 2019-12-15  0:45 UTC (permalink / raw)
  To: u-boot

On Mon, Dec 9, 2019 at 8:41 AM Simon Glass <sjg@chromium.org> wrote:
>
> Add basic plumbing to allow Apollo Lake support to be used.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
> ---
>
> Changes in v7: None
> Changes in v6:
> - Make BOOT_FROM_FAST_SPI_FLASH a Kconfig option
>
> Changes in v5:
> - Enable SMP
>
> Changes in v4:
> - Enable HAVE_X86_FIT
> - Enable INTEL_GPIO
> - Switch over to use pinctrl for pad init/config
> - Use existing VBT Kconfig option
> - apollolake -> Apollo Lake
>
> Changes in v3:
> - Add MMC, video, USB configs
> - Add an APL_SPI_FLASH_BOOT option to enable non-mmap boot
> - Fix the incorrect value of CPU_ADDR_BITS
>
> Changes in v2: None
>
>  arch/x86/Kconfig                |  1 +
>  arch/x86/cpu/Makefile           |  1 +
>  arch/x86/cpu/apollolake/Kconfig | 96 +++++++++++++++++++++++++++++++++
>  3 files changed, 98 insertions(+)
>  create mode 100644 arch/x86/cpu/apollolake/Kconfig
>

applied to u-boot-x86/next, thanks!

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v7 15/17] x86: apl: Add FSP structures
  2019-12-09  0:40 ` [PATCH v7 15/17] x86: apl: Add FSP structures Simon Glass
@ 2019-12-15  0:46   ` Bin Meng
  0 siblings, 0 replies; 29+ messages in thread
From: Bin Meng @ 2019-12-15  0:46 UTC (permalink / raw)
  To: u-boot

On Mon, Dec 9, 2019 at 8:41 AM Simon Glass <sjg@chromium.org> wrote:
>
> These are mostly specific to a particular SoC. Add the definitions for
> Apollo Lake.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
> ---
>
> Changes in v7: None
> Changes in v6:
> - Fix FSP-M and FSP-S in comments
>
> Changes in v5: None
> Changes in v4:
> - apollolake -> Apollo Lake
>
> Changes in v3:
> - Add VBT signature
> - Add structures for FSP-S also
> - Drop struct fsp_usp_header as it is now in the API file
>
> Changes in v2: None
>
>  .../asm/arch-apollolake/fsp/fsp_configs.h     |  14 +
>  .../asm/arch-apollolake/fsp/fsp_m_upd.h       | 123 ++++++++
>  .../asm/arch-apollolake/fsp/fsp_s_upd.h       | 292 ++++++++++++++++++
>  .../include/asm/arch-apollolake/fsp/fsp_vpd.h |  11 +
>  4 files changed, 440 insertions(+)
>  create mode 100644 arch/x86/include/asm/arch-apollolake/fsp/fsp_configs.h
>  create mode 100644 arch/x86/include/asm/arch-apollolake/fsp/fsp_m_upd.h
>  create mode 100644 arch/x86/include/asm/arch-apollolake/fsp/fsp_s_upd.h
>  create mode 100644 arch/x86/include/asm/arch-apollolake/fsp/fsp_vpd.h
>

applied to u-boot-x86/next, thanks!

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v7 16/17] x86: apl: Add FSP support
  2019-12-09  0:40 ` [PATCH v7 16/17] x86: apl: Add FSP support Simon Glass
@ 2019-12-15  0:46   ` Bin Meng
  0 siblings, 0 replies; 29+ messages in thread
From: Bin Meng @ 2019-12-15  0:46 UTC (permalink / raw)
  To: u-boot

On Mon, Dec 9, 2019 at 8:42 AM Simon Glass <sjg@chromium.org> wrote:
>
> The memory and silicon init parts of the FSP need support code to work.
> Add this for Apollo Lake.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
> ---
>
> Changes in v7: None
> Changes in v6:
> - Drop mention of devicetree for VTD feature
> - Drop mention of ramstage
> - Fix various coding style problems
> - Make BOOT_FROM_FAST_SPI_FLASH a Kconfig option
> - Use 'No SPI' instead of 'SPI2' as a debug message
>
> Changes in v5:
> - Allocate the FSP-S data instead of using the stack
> - Rename APOLLOLAKE_USB2_PORT_MAX
>
> Changes in v4:
> - Adjust the comment for struct dw_i2c_speed_config
> - Rename arch_fsp_s_preinit() to arch_fsps_preinit()
> - Switch over to use pinctrl for pad init/config
> - Tidy up mixed case in FSP code
> - apollolake -> Apollo Lake
>
> Changes in v3:
> - Add bootstage timing for reading vbt
> - Add fspm_done() hook to handle FSP-S wierdness (it breaks SPI flash)
> - Don't allow BOOT_FROM_FAST_SPI_FLASH with FSP-S
> - Set boot_loader_tolum_size to 0
> - Use the IRQ uclass instead of ITSS
>
> Changes in v2: None
>
>  arch/x86/cpu/apollolake/Makefile |   6 +
>  arch/x86/cpu/apollolake/fsp_m.c  | 210 ++++++++++
>  arch/x86/cpu/apollolake/fsp_s.c  | 661 +++++++++++++++++++++++++++++++
>  3 files changed, 877 insertions(+)
>  create mode 100644 arch/x86/cpu/apollolake/fsp_m.c
>  create mode 100644 arch/x86/cpu/apollolake/fsp_s.c
>

applied to u-boot-x86/next, thanks!

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v7 17/17] x86: Add chromebook_coral
  2019-12-09  0:40 ` [PATCH v7 17/17] x86: Add chromebook_coral Simon Glass
@ 2019-12-15  0:47   ` Bin Meng
  0 siblings, 0 replies; 29+ messages in thread
From: Bin Meng @ 2019-12-15  0:47 UTC (permalink / raw)
  To: u-boot

On Mon, Dec 9, 2019 at 8:42 AM Simon Glass <sjg@chromium.org> wrote:
>
> Add support for coral which is a range of Apollo Lake-based Chromebook
> released in 2017. This also includes reef released in 2016, since it is
> based on the same SoC.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
> ---
>
> Changes in v7:
> - Add the new documentation to the index file
>
> Changes in v6:
> - Add a comment about the need for board_run_command()
> - Use generic gpio compatible string
>
> Changes in v5:
> - Add gpio-controller to GPIO nodes
> - Comment out GPIOs in the fsp_s node since we don't use them yet
> - Correct CPU ACPI IDs
> - Use a define for ACPI base address
>
> Changes in v4:
> - Add u-boot,skip-auto-config-until-reloc property to PCI
> - Drop duplicate commit 'Create a new sandbox_pci_read_bar() function'
> - New GPIO driver binding
> - Set up LPC pads early
> - Switch over to use pinctrl for pad init/config
> - Update documentation with more detailed memory map
> - Use hyphen for device-tree properties
> - apollolake -> Apollo Lake
>
> Changes in v3:
> - Ad FSP-S support
> - Add CONFIG_TPL_X86_ASSUME_CPUID to reduce code size
> - Add Chrome OS EC support
> - Add a proper SPI node and make the SPI flash node a child
> - Add bootstage support
> - Add more documentation
> - Add spi alias in device tree
> - Disable the bootcommand since it does nothing useful on coral
> - Don't enable SPI flash in TPL by default
> - Drop CONFIG_SPL_NET_SUPPORT
> - Drop patch '86: timer: Reduce timer code size in TPL on Intel CPUs'
> - Drop patch 'dm: core: Don't include ofnode functions with of-platdata'
> - Drop patch 'spi: sandbox: Add a test driver for sandbox SPI flash'
> - Drop patch 'spl: Allow SPL/TPL to use of-platdata without libfdt'
> - Drop patch 'x86: apollolake: Add definitions for the Intel Fast SPI interface'
> - Drop patch 'x86: timer: Set up the timer in timer_early_get_count()'
> - Enable video and USB3
> - Reduce amount of early-pad data in TPL
> - Tidy up the pad settings in the device tree
> - Use a zero-based tsc timer
>
> Changes in v2: None
>
>  arch/x86/dts/Makefile                     |   1 +
>  arch/x86/dts/chromebook_coral.dts         | 831 ++++++++++++++++++++++
>  board/google/Kconfig                      |  15 +
>  board/google/chromebook_coral/Kconfig     |  43 ++
>  board/google/chromebook_coral/MAINTAINERS |   6 +
>  board/google/chromebook_coral/Makefile    |   5 +
>  board/google/chromebook_coral/coral.c     |  19 +
>  configs/chromebook_coral_defconfig        | 102 +++
>  doc/board/google/chromebook_coral.rst     | 241 +++++++
>  doc/board/google/index.rst                |   1 +
>  include/configs/chromebook_coral.h        |  32 +
>  11 files changed, 1296 insertions(+)
>  create mode 100644 arch/x86/dts/chromebook_coral.dts
>  create mode 100644 board/google/chromebook_coral/Kconfig
>  create mode 100644 board/google/chromebook_coral/MAINTAINERS
>  create mode 100644 board/google/chromebook_coral/Makefile
>  create mode 100644 board/google/chromebook_coral/coral.c
>  create mode 100644 configs/chromebook_coral_defconfig
>  create mode 100644 doc/board/google/chromebook_coral.rst
>  create mode 100644 include/configs/chromebook_coral.h
>

applied to u-boot-x86/next, thanks!

^ permalink raw reply	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2019-12-15  0:47 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-09  0:40 [PATCH v7 04/17] x86: apl: Add hostbridge driver Simon Glass
2019-12-09  0:40 ` [PATCH v7 05/17] x86: apl: Add ITSS driver Simon Glass
2019-12-15  0:36   ` Bin Meng
2019-12-09  0:40 ` [PATCH v7 06/17] x86: apl: Add LPC driver Simon Glass
2019-12-15  0:38   ` Bin Meng
2019-12-09  0:40 ` [PATCH v7 07/17] x86: apl: Add PCH driver Simon Glass
2019-12-15  0:39   ` Bin Meng
2019-12-09  0:40 ` [PATCH v7 08/17] x86: apl: Add PUNIT driver Simon Glass
2019-12-15  0:40   ` Bin Meng
2019-12-09  0:40 ` [PATCH v7 09/17] spl: Add methods to find the position/size of next phase Simon Glass
2019-12-15  0:40   ` Bin Meng
2019-12-09  0:40 ` [PATCH v7 10/17] x86: apl: Add SPL loaders Simon Glass
2019-12-15  0:41   ` Bin Meng
2019-12-09  0:40 ` [PATCH v7 11/17] x86: apl: Add a CPU driver Simon Glass
2019-12-15  0:43   ` Bin Meng
2019-12-09  0:40 ` [PATCH v7 12/17] x86: apl: Add SPL/TPL init Simon Glass
2019-12-15  0:44   ` Bin Meng
2019-12-09  0:40 ` [PATCH v7 13/17] x86: apl: Add P2SB driver Simon Glass
2019-12-10 14:11   ` Bin Meng
2019-12-15  0:44     ` Bin Meng
2019-12-09  0:40 ` [PATCH v7 14/17] x86: apl: Add Kconfig and Makefile Simon Glass
2019-12-15  0:45   ` Bin Meng
2019-12-09  0:40 ` [PATCH v7 15/17] x86: apl: Add FSP structures Simon Glass
2019-12-15  0:46   ` Bin Meng
2019-12-09  0:40 ` [PATCH v7 16/17] x86: apl: Add FSP support Simon Glass
2019-12-15  0:46   ` Bin Meng
2019-12-09  0:40 ` [PATCH v7 17/17] x86: Add chromebook_coral Simon Glass
2019-12-15  0:47   ` Bin Meng
2019-12-15  0:36 ` [PATCH v7 04/17] x86: apl: Add hostbridge driver Bin Meng

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.