[PATCH v6 101/102] x86: apl: Add FSP support

2019-12-06 Thread Simon Glass
The memory and silicon init parts of the FSP need support code to work.
Add this for Apollo Lake.

Signed-off-by: Simon Glass 
---

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 00..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 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/*
+ * 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 = >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] - 

[PATCH v6 100/102] x86: apl: Add FSP structures

2019-12-06 Thread Simon Glass
These are mostly specific to a particular SoC. Add the definitions for
Apollo Lake.

Signed-off-by: Simon Glass 
---

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 00..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 00..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 
+
+#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];
+
+   

[PATCH v6 102/102] x86: Add chromebook_coral

2019-12-06 Thread Simon Glass
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 
---

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 +++
 include/configs/chromebook_coral.h|  32 +
 10 files changed, 1295 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 00..24fcbb5063
--- /dev/null
+++ b/arch/x86/dts/chromebook_coral.dts
@@ -0,0 +1,831 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/dts-v1/;
+
+#include 
+
+/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 
+#include 
+#include 
+#include 
+#include 
+
+/ {
+   model = "Google Coral";
+   compatible = "google,coral", "intel,apollolake";
+
+   aliases {
+   cros-ec0 = _ec;
+   fsp = _s;
+   spi0 = 
+   };
+
+   config {
+  silent_console = <0>;
+   };
+
+   chosen {
+   stdout-path = 
+   };
+
+   cpus {
+   u-boot,dm-pre-reloc;
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   cpu@0 {
+   u-boot,dm-pre-reloc;
+   device_type = "cpu";
+   compatible = "intel,apl-cpu";
+   reg = <0>;
+   intel,apic-id = <0>;
+   };
+
+   cpu@1 {
+   device_type = "cpu";
+   compatible = "intel,apl-cpu";
+   reg = <1>;
+   intel,apic-id = <2>;
+   };
+
+   cpu@2 {
+   device_type = "cpu";
+   compatible = "intel,apl-cpu";
+   reg = <2>;
+   intel,apic-id = <4>;
+   };
+
+

[PATCH v6 099/102] x86: apl: Add Kconfig and Makefile

2019-12-06 Thread Simon Glass
Add basic plumbing to allow Apollo Lake support to be used.

Signed-off-by: Simon Glass 
---

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 00..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 0xfef0
+
+config DCACHE_RAM_SIZE
+   default 0xc
+
+config DCACHE_RAM_MRC_VAR_SIZE
+   default 0xb
+
+config CPU_SPECIFIC_OPTIONS
+   def_bool y
+   select SMM_TSEG
+   select X86_RAMTEST
+
+config SMM_TSEG_SIZE
+   hex
+   default 0x80
+
+config MMCONF_BASE_ADDRESS
+   hex
+   default 0xe000
+
+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



[PATCH v6 098/102] x86: apl: Add P2SB driver

2019-12-06 Thread Simon Glass
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 
---

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   | 167 +++
 2 files changed, 168 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 00..0a5deaf4a0
--- /dev/null
+++ b/arch/x86/cpu/apollolake/p2sb.c
@@ -0,0 +1,167 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Primary-to-Sideband Bridge
+ *
+ * Copyright 2019 Google LLC
+ */
+
+#define LOG_CATEGORY UCLASS_P2SB
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+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_OFFSET0x60
+#define HPTC_ADDR_ENABLE_BIT   BIT(7)
+
+/* High Performance Event Timer Configuration */
+#define P2SB_HPTC  0x60
+#define P2SB_HPTC_ADDRESS_ENABLE   BIT(7)
+
+/*
+ * ADDRESS_SELECTENCODING_RANGE
+ *  0 0xfed0  - 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 for FspMemoryInit to store and retrieve a global data
+ * pointer
+ *
+ * @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;
+   

[PATCH v6 097/102] x86: apl: Add SPL/TPL init

2019-12-06 Thread Simon Glass
Add code to init the system both in TPL and SPL. Each phase has its own
procedure.

Signed-off-by: Simon Glass 
---

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 00..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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* 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(0x4402, 0xd0c50650);
+   writel(0x3c47, 0xd0c50654);
+   writel(0x4400, 0xd0c50658);
+   writel(0x3c48, 0xd0c5065c);
+   } else { /* UART2 */
+   writel(0x4402, 0xd0c50670);
+   writel(0x3c4b, 0xd0c50674);
+   writel(0x4400, 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, _base, _size,
+);
+   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;

[PATCH v6 096/102] x86: apl: Add a CPU driver

2019-12-06 Thread Simon Glass
Add a bare-bones CPU driver so that CPUs can be probed.

Signed-off-by: Simon Glass 
---

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 00..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 
+#include 
+#include 
+#include 
+#include 
+
+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= _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 00..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 
+#include 
+#include 
+
+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 00..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   1920
+
+#define MAX_PCIE_PORTS 6
+#define CLKREQ_DISABLED0xf
+
+#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_CTL0x0119
 #define MSR_IA32_BBL_CR_CTL3   0x011e
 #define MSR_POWER_MISC 0x0120
+#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



[PATCH v6 094/102] spl: Add methods to find the position/size of next phase

2019-12-06 Thread Simon Glass
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 
---

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



[PATCH v6 093/102] x86: apl: Add PUNIT driver

2019-12-06 Thread Simon Glass
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 
---

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 00..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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/*
+ * 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, );
+   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 == 0x) {
+   /* 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



[PATCH v6 095/102] x86: apl: Add SPL loaders

2019-12-06 Thread Simon Glass
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 

---

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 00..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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* 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, );
+   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, _base, _size, );
+   if (ret)
+   return log_msg_ret("mmap", ret);
+   } else {
+   ret = fast_spi_get_bios_mmap(PCH_DEV_SPI, _base, _size,
+);
+   if (ret)
+   return ret;
+   }
+   spl_pos += map_base & ~0xff00;
+   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 = >mtd;
+   size_t retlen;
+
+   return log_ret(mtd->_read(mtd, offset, len, , 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, );
+   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,

[PATCH v6 092/102] x86: apl: Add PCH driver

2019-12-06 Thread Simon Glass
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 
Reviewed-by: Bin Meng 
---

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 00..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 
+#include 
+#include 
+#include 
+#include 
+
+#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= _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 00..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



[PATCH v6 091/102] x86: apl: Add LPC driver

2019-12-06 Thread Simon Glass
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 
---

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 00..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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+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),
+   , 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), ,
+   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);
+}
+

[PATCH v6 090/102] x86: apl: Add ITSS driver

2019-12-06 Thread Simon Glass
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 
Reviewed-by: Bin Meng 
---

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 00..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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+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;
+
+ 

[PATCH v6 089/102] x86: apl: Add hostbridge driver

2019-12-06 Thread Simon Glass
This driver models the hostbridge as a northbridge. It simply sets up the
graphics BAR. It supports of-platdata.

Signed-off-by: Simon Glass 
---

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 00..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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/**
+ * 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, );
+   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, , 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, );
+   if (ret)
+   return 

[PATCH v6 088/102] x86: apl: Add systemagent driver

2019-12-06 Thread Simon Glass
This driver handles communication with the systemagent which needs to be
told when U-Boot has completed its init.

Signed-off-by: Simon Glass 

---

Changes in v6: None
Changes in v5: None
Changes in v4:
- Add a comment for enable_bios_reset_cpl()
- Tidy up header guards
- use GENMASK() for VTBAR_MASK

Changes in v3: None
Changes in v2: None

 arch/x86/cpu/apollolake/Makefile  |  2 +
 arch/x86/cpu/apollolake/systemagent.c | 19 ++
 .../include/asm/arch-apollolake/systemagent.h | 37 +++
 3 files changed, 58 insertions(+)
 create mode 100644 arch/x86/cpu/apollolake/systemagent.c
 create mode 100644 arch/x86/include/asm/arch-apollolake/systemagent.h

diff --git a/arch/x86/cpu/apollolake/Makefile b/arch/x86/cpu/apollolake/Makefile
index fdda748ea3..3a8c2f66a3 100644
--- a/arch/x86/cpu/apollolake/Makefile
+++ b/arch/x86/cpu/apollolake/Makefile
@@ -2,5 +2,7 @@
 #
 # Copyright 2019 Google LLC
 
+obj-$(CONFIG_SPL_BUILD) += systemagent.o
+
 obj-y += pmc.o
 obj-y += uart.o
diff --git a/arch/x86/cpu/apollolake/systemagent.c 
b/arch/x86/cpu/apollolake/systemagent.c
new file mode 100644
index 00..3a41b329c3
--- /dev/null
+++ b/arch/x86/cpu/apollolake/systemagent.c
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2017 Intel Corporation.
+ * Take from coreboot project file of the same name
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+void enable_bios_reset_cpl(void)
+{
+   /*
+* Set bits 0+1 of BIOS_RESET_CPL to indicate to the CPU
+* that BIOS has initialised memory and power management
+*/
+   setbits_8(MCHBAR_REG(BIOS_RESET_CPL), 3);
+}
diff --git a/arch/x86/include/asm/arch-apollolake/systemagent.h 
b/arch/x86/include/asm/arch-apollolake/systemagent.h
new file mode 100644
index 00..206d8903fa
--- /dev/null
+++ b/arch/x86/include/asm/arch-apollolake/systemagent.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2017 Intel Corporation.
+ * Take from coreboot project file of the same name
+ */
+
+#ifndef _ASM_ARCH_SYSTEMAGENT_H
+#define _ASM_ARCH_SYSTEMAGENT_H
+
+/* Device 0:0.0 PCI configuration space */
+#define MCHBAR 0x48
+
+/* RAPL Package Power Limit register under MCHBAR */
+#define PUNIT_THERMAL_DEVICE_IRQ   0x700C
+#define PUINT_THERMAL_DEVICE_IRQ_VEC_NUMBER0x18
+#define PUINT_THERMAL_DEVICE_IRQ_LOCK  0x8000
+#define BIOS_RESET_CPL 0x7078
+#define   PCODE_INIT_DONE  BIT(8)
+#define MCHBAR_RAPL_PPL0x70A8
+#define CORE_DISABLE_MASK  0x7168
+#define CAPID0_A   0xE4
+#define   VTD_DISABLE  BIT(23)
+#define DEFVTBAR   0x6c80
+#define GFXVTBAR   0x6c88
+#define   VTBAR_ENABLED0x01
+#define VTBAR_MASK GENMASK_ULL(39, 12)
+#define VTBAR_SIZE 0x1000
+
+/**
+ * enable_bios_reset_cpl() - Tell the system agent that memory/power are ready
+ *
+ * This should be called when U-Boot has set up the memory and power
+ * management.
+ */
+void enable_bios_reset_cpl(void);
+
+#endif
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 085/102] x86: apl: Add UART driver

2019-12-06 Thread Simon Glass
Add a driver for the Apollo Lake UART. It uses the standard ns16550 device
but also sets up the input clock with LPSS and supports configuration via
of-platdata.

Signed-off-by: Simon Glass 
---

Changes in v6:
- Drop code to handle !CONFIG_OF_TRANSLATE case
- Update comment to reference board_debug_uart_init() (its in a later patch)

Changes in v5: None
Changes in v4:
- Add an extra comment to apl_uart_init()
- Tidy up header guards
- apollolake -> Apollo Lake

Changes in v3:
- Use the LPSS code from a separate file

Changes in v2: None

 arch/x86/cpu/apollolake/Makefile|   1 +
 arch/x86/cpu/apollolake/uart.c  | 133 
 arch/x86/include/asm/arch-apollolake/uart.h |  20 +++
 3 files changed, 154 insertions(+)
 create mode 100644 arch/x86/cpu/apollolake/uart.c
 create mode 100644 arch/x86/include/asm/arch-apollolake/uart.h

diff --git a/arch/x86/cpu/apollolake/Makefile b/arch/x86/cpu/apollolake/Makefile
index 5e136b6515..fdda748ea3 100644
--- a/arch/x86/cpu/apollolake/Makefile
+++ b/arch/x86/cpu/apollolake/Makefile
@@ -3,3 +3,4 @@
 # Copyright 2019 Google LLC
 
 obj-y += pmc.o
+obj-y += uart.o
diff --git a/arch/x86/cpu/apollolake/uart.c b/arch/x86/cpu/apollolake/uart.c
new file mode 100644
index 00..f2b356eb44
--- /dev/null
+++ b/arch/x86/cpu/apollolake/uart.c
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Special driver to handle of-platdata
+ *
+ * Copyright 2019 Google LLC
+ *
+ * Some code from coreboot lpss.c
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* Low-power Subsystem (LPSS) clock register */
+enum {
+   LPSS_CLOCK_CTL_REG  = 0x200,
+   LPSS_CNT_CLOCK_EN   = 1,
+   LPSS_CNT_CLK_UPDATE = 1U << 31,
+   LPSS_CLOCK_DIV_N_SHIFT  = 16,
+   LPSS_CLOCK_DIV_N_MASK   = 0x7fff << LPSS_CLOCK_DIV_N_SHIFT,
+   LPSS_CLOCK_DIV_M_SHIFT  = 1,
+   LPSS_CLOCK_DIV_M_MASK   = 0x7fff << LPSS_CLOCK_DIV_M_SHIFT,
+
+   /* These set the UART input clock speed */
+   LPSS_UART_CLK_M_VAL = 0x25a,
+   LPSS_UART_CLK_N_VAL = 0x7fff,
+};
+
+static void lpss_clk_update(void *regs, u32 clk_m_val, u32 clk_n_val)
+{
+   u32 clk_sel;
+
+   clk_sel = clk_n_val << LPSS_CLOCK_DIV_N_SHIFT |
+clk_m_val << LPSS_CLOCK_DIV_M_SHIFT;
+   clk_sel |= LPSS_CNT_CLK_UPDATE | LPSS_CNT_CLOCK_EN;
+
+   writel(clk_sel, regs + LPSS_CLOCK_CTL_REG);
+}
+
+static void uart_lpss_init(void *regs)
+{
+   /* Take UART out of reset */
+   lpss_reset_release(regs);
+
+   /* Set M and N divisor inputs and enable clock */
+   lpss_clk_update(regs, LPSS_UART_CLK_M_VAL, LPSS_UART_CLK_N_VAL);
+}
+
+void apl_uart_init(pci_dev_t bdf, ulong base)
+{
+   /* Set UART base address */
+   pci_x86_write_config(bdf, PCI_BASE_ADDRESS_0, base, PCI_SIZE_32);
+
+   /* Enable memory access and bus master */
+   pci_x86_write_config(bdf, PCI_COMMAND, PCI_COMMAND_MEMORY |
+PCI_COMMAND_MASTER, PCI_SIZE_32);
+
+   uart_lpss_init((void *)base);
+}
+
+/*
+ * This driver uses its own compatible string but almost everything else from
+ * the standard ns16550 driver. This allows us to provide an of-platdata
+ * implementation, since the platdata produced by of-platdata does not match
+ * struct ns16550_platdata.
+ *
+ * When running with of-platdata (generally TPL), the platdata is converted to
+ * something that ns16550 expects. When running withoutof-platdata (SPL, U-Boot
+ * proper), we use ns16550's ofdata_to_platdata routine.
+ */
+
+static int apl_ns16550_probe(struct udevice *dev)
+{
+   struct ns16550_platdata *plat = dev_get_platdata(dev);
+
+   if (!CONFIG_IS_ENABLED(PCI))
+   apl_uart_init(plat->bdf, plat->base);
+
+   return ns16550_serial_probe(dev);
+}
+
+static int apl_ns16550_ofdata_to_platdata(struct udevice *dev)
+{
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+   struct dtd_intel_apl_ns16550 *dtplat = dev_get_platdata(dev);
+   struct ns16550_platdata *plat;
+
+   /*
+* Convert our platdata to the ns16550's platdata, so we can just use
+* that driver
+*/
+   plat = malloc(sizeof(*plat));
+   if (!plat)
+   return -ENOMEM;
+   plat->base = dtplat->early_regs[0];
+   plat->reg_width = 1;
+   plat->reg_shift = dtplat->reg_shift;
+   plat->reg_offset = 0;
+   plat->clock = dtplat->clock_frequency;
+   plat->fcr = UART_FCR_DEFVAL;
+   plat->bdf = pci_ofplat_get_devfn(dtplat->reg[0]);
+   dev->platdata = plat;
+#else
+   int ret;
+
+   ret = ns16550_serial_ofdata_to_platdata(dev);
+   if (ret)
+   return ret;
+#endif /* OF_PLATDATA */
+
+   return 0;
+}
+
+static const struct udevice_id apl_ns16550_serial_ids[] = {
+   { .compatible = "intel,apl-ns16550" },
+   { },
+};
+
+U_BOOT_DRIVER(apl_ns16550) = {
+   .name   = "intel_apl_ns16550",
+   .id = 

[PATCH v6 086/102] x86: apl: Add pinctrl driver

2019-12-06 Thread Simon Glass
Add a driver for the Apollo Lake pinctrl. This mostly makes use of the
common Intel pinctrl support.

Signed-off-by: Simon Glass 
---

Changes in v6: None
Changes in v5: None
Changes in v4:
- Allow pinctrl nodes to have subnodes (i.e. GPIO nodes)
- Drop GPIO_NUM_PAD_CFG_REGS
- Switch over to use pinctrl for pad init/config
- Tidy up the header file a little
- apollolake -> Apollo Lake

Changes in v3:
- Add various minor tidy-ups
- Fix mixed case in GPIO defines
- Rework how pads configuration is defined in TPL and SPL
- Use the IRQ uclass instead of ITSS

Changes in v2: None

 arch/x86/include/asm/arch-apollolake/gpio.h | 490 
 drivers/pinctrl/intel/Kconfig   |   8 +
 drivers/pinctrl/intel/Makefile  |   1 +
 drivers/pinctrl/intel/pinctrl_apl.c | 192 
 4 files changed, 691 insertions(+)
 create mode 100644 arch/x86/include/asm/arch-apollolake/gpio.h
 create mode 100644 drivers/pinctrl/intel/pinctrl_apl.c

diff --git a/arch/x86/include/asm/arch-apollolake/gpio.h 
b/arch/x86/include/asm/arch-apollolake/gpio.h
new file mode 100644
index 00..f33025d7c5
--- /dev/null
+++ b/arch/x86/include/asm/arch-apollolake/gpio.h
@@ -0,0 +1,490 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Definitions for the GPIO subsystem on Apollolake
+ *
+ * Copyright (C) 2015 - 2017 Intel Corp.
+ * (Written by Alexandru Gagniuc  for Intel 
Corp.)
+ *
+ * Placed in a separate file since some of these definitions can be used from
+ * assembly code
+ *
+ * Taken from gpio_apl.h in coreboot
+ */
+
+#ifndef _ASM_ARCH_GPIO_H_
+#define _ASM_ARCH_GPIO_H_
+
+/* Port ids */
+#if IS_ENABLED(CONFIG_SOC_INTEL_GLK)
+#define PID_GPIO_AUDIO 0xC9
+#define PID_GPIO_SCC   0xC8
+#else
+#define PID_GPIO_SW0xC0
+#define PID_GPIO_S 0xC2
+#define PID_GPIO_W 0xC7
+#endif
+#define PID_GPIO_NW0xC4
+#define PID_GPIO_N 0xC5
+#define PID_ITSS   0xD0
+#define PID_RTC0xD1
+
+/*
+ * Miscellaneous Configuration register(MISCCFG). These are community-specific
+ * registers and are meant to house miscellaneous configuration fields per
+ * community. There are 8 GPIO groups: GPP_0 -> GPP_8 (Group 3 is absent)
+ */
+#define GPIO_MISCCFG   0x10 /* Miscellaneous Configuration offset */
+#define  GPIO_GPE_SW_31_0  0 /* SOUTHWEST GPIO#  0 ~ 31 belong to GROUP0 */
+#define  GPIO_GPE_SW_63_32 1 /* SOUTHWEST GPIO# 32 ~ 42 belong to GROUP1 */
+#define  GPIO_GPE_W_31_0   2 /* WEST  GPIO#  0 ~ 25 belong to GROUP2 */
+#define  GPIO_GPE_NW_31_0  4 /* NORTHWEST GPIO#  0 ~ 17 belong to GROUP4 */
+#define  GPIO_GPE_NW_63_32 5 /* NORTHWEST GPIO# 32 ~ 63 belong to GROUP5 */
+#define  GPIO_GPE_NW_95_64 6 /* NORTHWEST GPIO# 64 ~ 76 belong to GROUP6 */
+#define  GPIO_GPE_N_31_0   7 /* NORTH GPIO#  0 ~ 31 belong to GROUP7 */
+#define  GPIO_GPE_N_63_32  8 /* NORTH GPIO# 32 ~ 61 belong to GROUP8 */
+
+#define GPIO_MAX_NUM_PER_GROUP 32
+
+/*
+ * Host Software Pad Ownership Register.
+ * The pins in the community are divided into 3 groups:
+ * GPIO 0 ~ 31, GPIO 32 ~ 63, GPIO 64 ~ 95
+ */
+#define HOSTSW_OWN_REG_0   0x80
+
+#define PAD_CFG_BASE   0x500
+
+#define GPI_INT_STS_0  0x100
+#define GPI_INT_EN_0   0x110
+
+#define GPI_SMI_STS_0  0x140
+#define GPI_SMI_EN_0   0x150
+
+#define NUM_N_PADS (PAD_N(SVID0_CLK) + 1)
+#define NUM_NW_PADS(PAD_NW(GPIO_123) + 1)
+#define NUM_W_PADS (PAD_W(SUSPWRDNACK) + 1)
+#define NUM_SW_PADS(PAD_SW(LPC_FRAMEB) + 1)
+
+#define NUM_N_GPI_REGS \
+   (ALIGN(NUM_N_PADS, GPIO_MAX_NUM_PER_GROUP) / GPIO_MAX_NUM_PER_GROUP)
+
+#define NUM_NW_GPI_REGS\
+   (ALIGN(NUM_NW_PADS, GPIO_MAX_NUM_PER_GROUP) / GPIO_MAX_NUM_PER_GROUP)
+
+#define NUM_W_GPI_REGS \
+   (ALIGN(NUM_W_PADS, GPIO_MAX_NUM_PER_GROUP) / GPIO_MAX_NUM_PER_GROUP)
+
+#define NUM_SW_GPI_REGS\
+   (ALIGN(NUM_SW_PADS, GPIO_MAX_NUM_PER_GROUP) / GPIO_MAX_NUM_PER_GROUP)
+
+/*
+ * Total number of GPI status registers across all GPIO communities in the SOC
+ */
+#define NUM_GPI_STATUS_REGS(NUM_N_GPI_REGS + NUM_NW_GPI_REGS \
+   + NUM_W_GPI_REGS + NUM_SW_GPI_REGS)
+
+/* North community pads */
+#define GPIO_0 0
+#define GPIO_1 1
+#define GPIO_2 2
+#define GPIO_3 3
+#define GPIO_4 4
+#define GPIO_5 5
+#define GPIO_6 6
+#define GPIO_7 7
+#define GPIO_8 8
+#define GPIO_9 9
+#define GPIO_1010
+#define GPIO_1111
+#define GPIO_1212
+#define GPIO_1313
+#define 

[PATCH v6 087/102] i2c: designware: Add Apollo Lake support

2019-12-06 Thread Simon Glass
For Apollo Lake we need to take the I2C bus controller out of reset before
using this. Add this functionality to the driver.

Signed-off-by: Simon Glass 
Reviewed-by: Heiko Schocher 
---

Changes in v6:
- Add .driver_data in the designware_pci_supported array
- Add a comment about VANILLA
- Move lpss_reset_release() to this commit

Changes in v5:
- Drop unrelated change metioned by Heiko

Changes in v4:
- apollolake -> Apollo Lake

Changes in v3:
- Add a weak function to avoid errors on other platforms

Changes in v2: None

 drivers/i2c/designware_i2c_pci.c | 25 +
 1 file changed, 25 insertions(+)

diff --git a/drivers/i2c/designware_i2c_pci.c b/drivers/i2c/designware_i2c_pci.c
index bb1f809af3..a3586371dc 100644
--- a/drivers/i2c/designware_i2c_pci.c
+++ b/drivers/i2c/designware_i2c_pci.c
@@ -8,8 +8,14 @@
 #include 
 #include 
 #include 
+#include 
 #include "designware_i2c.h"
 
+enum {
+   VANILLA = 0,/* standard I2C with no tweaks */
+   INTEL_APL,  /* Apollo Lake I2C */
+};
+
 /* BayTrail HCNT/LCNT/SDA hold time */
 static struct dw_scl_sda_cfg byt_config = {
.ss_hcnt = 0x200,
@@ -19,6 +25,9 @@ static struct dw_scl_sda_cfg byt_config = {
.sda_hold = 0x6,
 };
 
+/* Have a weak function for now - possibly should be a new uclass */
+__weak void lpss_reset_release(void *regs);
+
 static int designware_i2c_pci_ofdata_to_platdata(struct udevice *dev)
 {
struct dw_i2c *priv = dev_get_priv(dev);
@@ -59,6 +68,15 @@ static int designware_i2c_pci_ofdata_to_platdata(struct 
udevice *dev)
 
 static int designware_i2c_pci_probe(struct udevice *dev)
 {
+   struct dw_i2c *priv = dev_get_priv(dev);
+
+   if (dev_get_driver_data(dev) == INTEL_APL) {
+   /* Ensure controller is in D0 state */
+   lpss_set_power_state(dev, STATE_D0);
+
+   lpss_reset_release(priv->regs);
+   }
+
return designware_i2c_probe(dev);
 }
 
@@ -88,6 +106,7 @@ static int designware_i2c_pci_bind(struct udevice *dev)
 
 static const struct udevice_id designware_i2c_pci_ids[] = {
{ .compatible = "snps,designware-i2c-pci" },
+   { .compatible = "intel,apl-i2c", INTEL_APL },
{ }
 };
 
@@ -113,6 +132,12 @@ static struct pci_device_id designware_pci_supported[] = {
{ PCI_VDEVICE(INTEL, 0x0f45) },
{ PCI_VDEVICE(INTEL, 0x0f46) },
{ PCI_VDEVICE(INTEL, 0x0f47) },
+   { PCI_VDEVICE(INTEL, 0x5aac), .driver_data = INTEL_APL },
+   { PCI_VDEVICE(INTEL, 0x5aae), .driver_data = INTEL_APL },
+   { PCI_VDEVICE(INTEL, 0x5ab0), .driver_data = INTEL_APL },
+   { PCI_VDEVICE(INTEL, 0x5ab2), .driver_data = INTEL_APL },
+   { PCI_VDEVICE(INTEL, 0x5ab4), .driver_data = INTEL_APL },
+   { PCI_VDEVICE(INTEL, 0x5ab6), .driver_data = INTEL_APL },
{},
 };
 
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 084/102] x86: apl: Add PMC driver

2019-12-06 Thread Simon Glass
Add a driver for the Apollo Lake SoC. It supports the basic operations and
can use device tree or of-platdata.

Signed-off-by: Simon Glass 
---

Changes in v6:
- Use one space after #defines in pm.h

Changes in v5: None
Changes in v4:
- Fix Makefile copyright message
- Fix incorrect mask check in pmc_gpe_init()
- Switch over to use pinctrl for pad init/config
- Tidy up header guards
- Use pci_ofplat_get_devfn()
- apollolake -> Apollo Lake

Changes in v3:
- Use pci_get_devfn()

Changes in v2: None

 arch/x86/cpu/apollolake/Makefile  |   5 +
 arch/x86/cpu/apollolake/pmc.c | 216 ++
 arch/x86/include/asm/arch-apollolake/pm.h |  19 ++
 drivers/power/acpi_pmc/acpi-pmc-uclass.c  |  56 ++
 4 files changed, 296 insertions(+)
 create mode 100644 arch/x86/cpu/apollolake/Makefile
 create mode 100644 arch/x86/cpu/apollolake/pmc.c
 create mode 100644 arch/x86/include/asm/arch-apollolake/pm.h

diff --git a/arch/x86/cpu/apollolake/Makefile b/arch/x86/cpu/apollolake/Makefile
new file mode 100644
index 00..5e136b6515
--- /dev/null
+++ b/arch/x86/cpu/apollolake/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright 2019 Google LLC
+
+obj-y += pmc.o
diff --git a/arch/x86/cpu/apollolake/pmc.c b/arch/x86/cpu/apollolake/pmc.c
new file mode 100644
index 00..683c6082f2
--- /dev/null
+++ b/arch/x86/cpu/apollolake/pmc.c
@@ -0,0 +1,216 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2017 Intel Corporation.
+ * Copyright 2019 Google LLC
+ *
+ * Modified from coreboot pmclib.c, pmc.c and pmutil.c
+ */
+
+#define LOG_CATEGORY UCLASS_ACPI_PMC
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define GPIO_GPE_CFG   0x1050
+
+/* Memory mapped IO registers behind PMC_BASE_ADDRESS */
+#define PRSTS  0x1000
+#define GEN_PMCON1 0x1020
+#define  COLD_BOOT_STS BIT(27)
+#define  COLD_RESET_STSBIT(26)
+#define  WARM_RESET_STSBIT(25)
+#define  GLOBAL_RESET_STS  BIT(24)
+#define  SRS   BIT(20)
+#define  MS4V  BIT(18)
+#define  RPS   BIT(2)
+#define GEN_PMCON1_CLR1_BITS   (COLD_BOOT_STS | COLD_RESET_STS | \
+WARM_RESET_STS | GLOBAL_RESET_STS | \
+SRS | MS4V)
+#define GEN_PMCON2 0x1024
+#define GEN_PMCON3 0x1028
+
+/* Offset of TCO registers from ACPI base I/O address */
+#define TCO_REG_OFFSET 0x60
+#define TCO1_STS   0x64
+#define   DMISCI_STS   BIT(9)
+#define   BOOT_STS BIT(18)
+#define TCO2_STS   0x66
+#define TCO1_CNT   0x68
+#define   TCO_LOCK BIT(12)
+#define TCO2_CNT   0x6a
+
+enum {
+   ETR = 0x1048,
+   CF9_LOCK= 1UL << 31,
+   CF9_GLB_RST = 1 << 20,
+};
+
+struct apl_pmc_platdata {
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+   struct dtd_intel_apl_pmc dtplat;
+#endif
+   pci_dev_t bdf;
+};
+
+static int apl_pmc_fill_power_state(struct udevice *dev)
+{
+   struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(dev);
+
+   upriv->tco1_sts = inw(upriv->acpi_base + TCO1_STS);
+   upriv->tco2_sts = inw(upriv->acpi_base + TCO2_STS);
+
+   upriv->prsts = readl(upriv->pmc_bar0 + PRSTS);
+   upriv->gen_pmcon1 = readl(upriv->pmc_bar0 + GEN_PMCON1);
+   upriv->gen_pmcon2 = readl(upriv->pmc_bar0 + GEN_PMCON2);
+   upriv->gen_pmcon3 = readl(upriv->pmc_bar0 + GEN_PMCON3);
+
+   return 0;
+}
+
+static int apl_prev_sleep_state(struct udevice *dev, int prev_sleep_state)
+{
+   struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(dev);
+
+   /* WAK_STS bit will not be set when waking from G3 state */
+   if (!(upriv->pm1_sts & WAK_STS) &&
+   (upriv->gen_pmcon1 & COLD_BOOT_STS))
+   prev_sleep_state = ACPI_S5;
+
+   return prev_sleep_state;
+}
+
+static int apl_disable_tco(struct udevice *dev)
+{
+   struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(dev);
+
+   pmc_disable_tco_base(upriv->acpi_base + TCO_REG_OFFSET);
+
+   return 0;
+}
+
+static int apl_global_reset_set_enable(struct udevice *dev, bool enable)
+{
+   struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(dev);
+
+   if (enable)
+   setbits_le32(upriv->pmc_bar0 + ETR, CF9_GLB_RST);
+   else
+   clrbits_le32(upriv->pmc_bar0 + ETR, CF9_GLB_RST);
+
+   return 0;
+}
+
+int apl_pmc_ofdata_to_uc_platdata(struct udevice *dev)
+{
+   struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(dev);
+   struct apl_pmc_platdata *plat = dev_get_platdata(dev);
+
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
+   u32 base[6];
+   int size;
+   int ret;
+
+   ret = dev_read_u32_array(dev, "early-regs", base, ARRAY_SIZE(base));
+   if (ret)
+   return log_msg_ret("Missing/short early-regs", ret);
+   upriv->pmc_bar0 = (void *)base[0];
+   

[PATCH v6 082/102] x86: Move qemu CPU fixup function into its own file

2019-12-06 Thread Simon Glass
This function is specific to qemu so it seems best to keep it separate
from the generic code.

Move it out to a new file and update the condition to use if() instead of
 #ifdef

Signed-off-by: Simon Glass 
---

Changes in v6:
- Add back '#ifdef' line to commit message
- Drop incorrect mention of coreboot in qfw_cpu.c

Changes in v5:
- Add a new patch to move qemu CPU fixup function into its own file

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

 arch/x86/cpu/Makefile  |  1 +
 arch/x86/cpu/mp_init.c | 73 +++---
 arch/x86/cpu/qfw_cpu.c | 73 ++
 include/qfw.h  |  8 +
 4 files changed, 87 insertions(+), 68 deletions(-)
 create mode 100644 arch/x86/cpu/qfw_cpu.c

diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile
index b6a010ea32..0e90a38dc5 100644
--- a/arch/x86/cpu/Makefile
+++ b/arch/x86/cpu/Makefile
@@ -54,6 +54,7 @@ obj-$(CONFIG_INTEL_QUEENSBAY) += queensbay/
 obj-$(CONFIG_INTEL_TANGIER) += tangier/
 obj-$(CONFIG_APIC) += lapic.o ioapic.o
 obj-$(CONFIG_$(SPL_TPL_)X86_32BIT_INIT) += irq.o
+obj-$(CONFIG_QFW) += qfw_cpu.o
 ifndef CONFIG_$(SPL_)X86_64
 obj-$(CONFIG_SMP) += mp_init.o
 endif
diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c
index fefbf8f728..7b09f90cd5 100644
--- a/arch/x86/cpu/mp_init.c
+++ b/arch/x86/cpu/mp_init.c
@@ -418,69 +418,6 @@ static int init_bsp(struct udevice **devp)
return 0;
 }
 
-#ifdef CONFIG_QFW
-static int qemu_cpu_fixup(void)
-{
-   int ret;
-   int cpu_num;
-   int cpu_online;
-   struct udevice *dev, *pdev;
-   struct cpu_platdata *plat;
-   char *cpu;
-
-   /* first we need to find '/cpus' */
-   for (device_find_first_child(dm_root(), );
-pdev;
-device_find_next_child()) {
-   if (!strcmp(pdev->name, "cpus"))
-   break;
-   }
-   if (!pdev) {
-   printf("unable to find cpus device\n");
-   return -ENODEV;
-   }
-
-   /* calculate cpus that are already bound */
-   cpu_num = 0;
-   for (uclass_find_first_device(UCLASS_CPU, );
-dev;
-uclass_find_next_device()) {
-   cpu_num++;
-   }
-
-   /* get actual cpu number */
-   cpu_online = qemu_fwcfg_online_cpus();
-   if (cpu_online < 0) {
-   printf("unable to get online cpu number: %d\n", cpu_online);
-   return cpu_online;
-   }
-
-   /* bind addtional cpus */
-   dev = NULL;
-   for (; cpu_num < cpu_online; cpu_num++) {
-   /*
-* allocate device name here as device_bind_driver() does
-* not copy device name, 8 bytes are enough for
-* sizeof("cpu@") + 3 digits cpu number + '\0'
-*/
-   cpu = malloc(8);
-   if (!cpu) {
-   printf("unable to allocate device name\n");
-   return -ENOMEM;
-   }
-   sprintf(cpu, "cpu@%d", cpu_num);
-   ret = device_bind_driver(pdev, "cpu_qemu", cpu, );
-   if (ret) {
-   printf("binding cpu@%d failed: %d\n", cpu_num, ret);
-   return ret;
-   }
-   plat = dev_get_parent_platdata(dev);
-   plat->cpu_id = cpu_num;
-   }
-   return 0;
-}
-#endif
-
 int mp_init(struct mp_params *p)
 {
int num_aps;
@@ -494,11 +431,11 @@ int mp_init(struct mp_params *p)
if (ret)
return ret;
 
-#ifdef CONFIG_QFW
-   ret = qemu_cpu_fixup();
-   if (ret)
-   return ret;
-#endif
+   if (IS_ENABLED(CONFIG_QFW)) {
+   ret = qemu_cpu_fixup();
+   if (ret)
+   return ret;
+   }
 
ret = init_bsp();
if (ret) {
diff --git a/arch/x86/cpu/qfw_cpu.c b/arch/x86/cpu/qfw_cpu.c
new file mode 100644
index 00..49e9dfcf69
--- /dev/null
+++ b/arch/x86/cpu/qfw_cpu.c
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2015 Google, Inc
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+int qemu_cpu_fixup(void)
+{
+   int ret;
+   int cpu_num;
+   int cpu_online;
+   struct udevice *dev, *pdev;
+   struct cpu_platdata *plat;
+   char *cpu;
+
+   /* first we need to find '/cpus' */
+   for (device_find_first_child(dm_root(), );
+pdev;
+device_find_next_child()) {
+   if (!strcmp(pdev->name, "cpus"))
+   break;
+   }
+   if (!pdev) {
+   printf("unable to find cpus device\n");
+   return -ENODEV;
+   }
+
+   /* calculate cpus that are already bound */
+   cpu_num = 0;
+   for (uclass_find_first_device(UCLASS_CPU, );
+dev;
+uclass_find_next_device()) {
+   cpu_num++;
+   }

[PATCH v6 080/102] x86: Add a generic Intel pinctrl driver

2019-12-06 Thread Simon Glass
Recent Intel SoCs share a pinctrl mechanism with many common elements. Add
an implementation of this core functionality, allowing SoC-specific
drivers to avoid adding common code.

As well as a pinctrl driver this provides a GPIO driver based on the same
code.

Once other SoCs use this driver we may consider moving more properties to
the device tree (e.g. the community info and pad definitions).

Signed-off-by: Simon Glass 
---

Changes in v6:
- Add a comment to intel_pinctrl_ops
- Drop use of GPIO_NUM_PAD_CFG_REGS
- Move Intel Kconfig pinctrl options into this patch

Changes in v5:
- Add function to obtain ACPI gpio number

Changes in v4:
- Add a binding file
- Split out GPIO code from the pinctrl driver
- Switch over to use pinctrl for pad init/config

Changes in v3: None
Changes in v2: None

 arch/x86/include/asm/intel_pinctrl.h  | 306 +
 arch/x86/include/asm/intel_pinctrl_defs.h | 373 ++
 .../pinctrl/intel,apl-pinctrl.txt |  39 ++
 drivers/pinctrl/Kconfig   |   9 +
 drivers/pinctrl/Makefile  |   1 +
 drivers/pinctrl/intel/Kconfig |  16 +
 drivers/pinctrl/intel/Makefile|   5 +
 drivers/pinctrl/intel/pinctrl.c   | 636 ++
 8 files changed, 1385 insertions(+)
 create mode 100644 arch/x86/include/asm/intel_pinctrl.h
 create mode 100644 arch/x86/include/asm/intel_pinctrl_defs.h
 create mode 100644 doc/device-tree-bindings/pinctrl/intel,apl-pinctrl.txt
 create mode 100644 drivers/pinctrl/intel/Kconfig
 create mode 100644 drivers/pinctrl/intel/Makefile
 create mode 100644 drivers/pinctrl/intel/pinctrl.c

diff --git a/arch/x86/include/asm/intel_pinctrl.h 
b/arch/x86/include/asm/intel_pinctrl.h
new file mode 100644
index 00..72fd9246cb
--- /dev/null
+++ b/arch/x86/include/asm/intel_pinctrl.h
@@ -0,0 +1,306 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2017 Intel Corporation.
+ * Copyright 2019 Google LLC
+ *
+ * Modified from coreboot gpio.h
+ */
+
+#ifndef __ASM_INTEL_PINCTRL_H
+#define __ASM_INTEL_PINCTRL_H
+
+#include 
+
+/**
+ * struct pad_config - config for a pad
+ * @pad: offset of pad within community
+ * @pad_config: Pad config data corresponding to DW0, DW1, etc.
+ */
+struct pad_config {
+   int pad;
+   u32 pad_config[4];
+};
+
+#include 
+
+/* GPIO community IOSF sideband clock gating */
+#define MISCCFG_GPSIDEDPCGEN   BIT(5)
+/* GPIO community RCOMP clock gating */
+#define MISCCFG_GPRCOMPCDLCGEN BIT(4)
+/* GPIO community RTC clock gating */
+#define MISCCFG_GPRTCDLCGENBIT(3)
+/* GFX controller clock gating */
+#define MISCCFG_GSXSLCGEN  BIT(2)
+/* GPIO community partition clock gating */
+#define MISCCFG_GPDPCGEN   BIT(1)
+/* GPIO community local clock gating */
+#define MISCCFG_GPDLCGEN   BIT(0)
+/* Enable GPIO community power management configuration */
+#define MISCCFG_ENABLE_GPIO_PM_CONFIG (MISCCFG_GPSIDEDPCGEN | \
+   MISCCFG_GPRCOMPCDLCGEN | MISCCFG_GPRTCDLCGEN | MISCCFG_GSXSLCGEN \
+   | MISCCFG_GPDPCGEN | MISCCFG_GPDLCGEN)
+
+/*
+ * GPIO numbers may not be contiguous and instead will have a different
+ * starting pin number for each pad group.
+ */
+#define INTEL_GPP_BASE(first_of_community, start_of_group, end_of_group,\
+   group_pad_base) \
+   {   \
+   .first_pad = (start_of_group) - (first_of_community),   \
+   .size = (end_of_group) - (start_of_group) + 1,  \
+   .acpi_pad_base = (group_pad_base),  \
+   }
+
+/*
+ * A pad base of -1 indicates that this group uses contiguous numbering
+ * and a pad base should not be used for this group.
+ */
+#define PAD_BASE_NONE  -1
+
+/* The common/default group numbering is contiguous */
+#define INTEL_GPP(first_of_community, start_of_group, end_of_group)\
+   INTEL_GPP_BASE(first_of_community, start_of_group, end_of_group,\
+  PAD_BASE_NONE)
+
+/**
+ * struct reset_mapping - logical to actual value for PADRSTCFG in DW0
+ *
+ * Note that the values are expected to be within the field placement of the
+ * register itself. i.e. if the reset field is at 31:30 then the values within
+ * logical and chipset should occupy 31:30.
+ */
+struct reset_mapping {
+   u32 logical;
+   u32 chipset;
+};
+
+/**
+ * struct pad_group - describes the groups within each community
+ *
+ * @first_pad: offset of first pad of the group relative to the community
+ * @size: size of the group
+ * @acpi_pad_base: starting pin number for the pads in this group when they are
+ * used in ACPI.  This is only needed if the pins are not contiguous across
+ * groups. Most groups will have this set to PAD_BASE_NONE and use
+ * contiguous numbering for ACPI.
+ */
+struct pad_group {
+   int first_pad;
+   uint size;
+   int acpi_pad_base;
+};
+

[PATCH v6 081/102] x86: Add a generic Intel GPIO driver

2019-12-06 Thread Simon Glass
Add a GPIO driver which uses the pinctrl driver to access the pad
information. This driver relies on the GPIO nodes being subnodes to the
pinctrl device.

Signed-off-by: Simon Glass 
---

Changes in v6:
- Fix 'hone' typo
- Remove the * in the first line of the binding file
- Use 'north' as the node name instead of 'n'
- Use a generic compatible string intel,gpio

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

 .../gpio/intel,apl-gpio.txt   |  55 ++
 drivers/gpio/Kconfig  |   9 +
 drivers/gpio/Makefile |   1 +
 drivers/gpio/intel_gpio.c | 161 ++
 4 files changed, 226 insertions(+)
 create mode 100644 doc/device-tree-bindings/gpio/intel,apl-gpio.txt
 create mode 100644 drivers/gpio/intel_gpio.c

diff --git a/doc/device-tree-bindings/gpio/intel,apl-gpio.txt 
b/doc/device-tree-bindings/gpio/intel,apl-gpio.txt
new file mode 100644
index 00..e27a40b437
--- /dev/null
+++ b/doc/device-tree-bindings/gpio/intel,apl-gpio.txt
@@ -0,0 +1,55 @@
+Intel Apollo Lake GPIO controller
+
+The Apollo Lake (APL) GPIO controller is used to control GPIO functions of
+the pins.
+
+Required properties:
+- compatible: "intel,apl-gpio"
+- #gpio-cells: Should be 2. The syntax of the gpio specifier used by client
+  nodes should be the following with values derived from the SoC user manual.
+ <[phandle of the gpio controller node]
+  [pin number within the gpio controller]
+  [flags]>
+
+  Values for gpio specifier:
+  - Pin number: is a GPIO pin number between 0 and 244
+  - Flags: GPIO_ACTIVE_HIGH or GPIO_ACTIVE_LOW
+
+- gpio-controller: Specifies that the node is a gpio controller.
+
+Example:
+
+...
+{
+   p2sb: p2sb@d,0 {
+   reg = <0x02006810 0 0 0 0>;
+   compatible = "intel,apl-p2sb";
+   early-regs = ;
+
+   north {
+   compatible = "intel,apl-pinctrl";
+   intel,p2sb-port-id = ;
+   gpio_n: gpio-n {
+   compatible = "intel,gpio";
+   gpio-controller;
+   #gpio-cells = <2>;
+   };
+   };
+   };
+
+   i2c_2: i2c2@16,2 {
+   compatible = "intel,apl-i2c", "snps,designware-i2c-pci";
+   reg = <0x0200b210 0 0 0 0>;
+   #address-cells = <1>;
+   #size-cells = <0>;
+   clock-frequency = <40>;
+   tpm@50 {
+   reg = <0x50>;
+   compatible = "google,cr50";
+   u-boot,i2c-offset-len = <0>;
+   ready-gpio = <_n GPIO_28 GPIO_ACTIVE_LOW>;
+   };
+   };
+
+};
+...
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 447cf04578..1de6f5225e 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -104,6 +104,15 @@ config INTEL_BROADWELL_GPIO
  driver from the common Intel ICH6 driver. It supports a total of
  95 GPIOs which can be configured from the device tree.
 
+config INTEL_GPIO
+   bool "Intel generic GPIO driver"
+   depends on DM_GPIO
+   help
+ Say yes here to select Intel generic GPIO driver. This controller
+ supports recent chips (e.g. Apollo Lake). It permits basic GPIO
+ control including setting pins to input/output. It makes use of its
+ parent pinctrl driver to actually effect changes.
+
 config INTEL_ICH6_GPIO
bool "Intel ICH6 compatible legacy GPIO driver"
depends on DM_GPIO
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 3612e66786..449046b64c 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -17,6 +17,7 @@ endif
 obj-$(CONFIG_AT91_GPIO)+= at91_gpio.o
 obj-$(CONFIG_ATMEL_PIO4)   += atmel_pio4.o
 obj-$(CONFIG_BCM6345_GPIO) += bcm6345_gpio.o
+obj-$(CONFIG_INTEL_GPIO)   += intel_gpio.o
 obj-$(CONFIG_INTEL_ICH6_GPIO)  += intel_ich6_gpio.o
 obj-$(CONFIG_INTEL_BROADWELL_GPIO) += intel_broadwell_gpio.o
 obj-$(CONFIG_KIRKWOOD_GPIO)+= kw_gpio.o
diff --git a/drivers/gpio/intel_gpio.c b/drivers/gpio/intel_gpio.c
new file mode 100644
index 00..4bf1c9ddc4
--- /dev/null
+++ b/drivers/gpio/intel_gpio.c
@@ -0,0 +1,161 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2019 Google LLC
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static int intel_gpio_direction_input(struct udevice *dev, uint offset)
+{
+   struct udevice *pinctrl = dev_get_parent(dev);
+   uint config_offset = intel_pinctrl_get_config_reg_addr(pinctrl, offset);
+
+   pcr_clrsetbits32(pinctrl, config_offset,
+PAD_CFG0_MODE_MASK | PAD_CFG0_TX_STATE |
+ 

[PATCH v6 083/102] x86: apl: Add basic IO addresses

2019-12-06 Thread Simon Glass
Add some fixed IO and mmap addresses for use in the device tree and with
some early-init code.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 

---

Changes in v6: None
Changes in v5:
- Add ACPI base address and size

Changes in v4:
- Drop TCO_BASE_ADDRESS
- Tidy up header guards

Changes in v3: None
Changes in v2: None

 arch/x86/include/asm/arch-apollolake/iomap.h | 29 
 1 file changed, 29 insertions(+)
 create mode 100644 arch/x86/include/asm/arch-apollolake/iomap.h

diff --git a/arch/x86/include/asm/arch-apollolake/iomap.h 
b/arch/x86/include/asm/arch-apollolake/iomap.h
new file mode 100644
index 00..4ce1017055
--- /dev/null
+++ b/arch/x86/include/asm/arch-apollolake/iomap.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2017 Intel Corporation.
+ * Take from coreboot project file of the same name
+ */
+
+#ifndef _ASM_ARCH_IOMAP_H
+#define _ASM_ARCH_IOMAP_H
+
+#define R_ACPI_PM1_TMR 0x8
+
+/* Put p2sb at 0xd000 in TPL */
+#define IOMAP_P2SB_BAR 0xd000
+
+#define IOMAP_SPI_BASE 0xfe01
+
+#define IOMAP_ACPI_BASE0x400
+#define IOMAP_ACPI_SIZE0x100
+
+/*
+ * Use UART2. To use UART1 you need to set '2' to '1', change device tree 
serial
+ * node name and 'reg' property, and update CONFIG_DEBUG_UART_BASE.
+ */
+#define PCH_DEV_UART   PCI_BDF(0, 0x18, 2)
+
+#define PCH_DEV_LPCPCI_BDF(0, 0x1f, 0)
+#define PCH_DEV_SPIPCI_BDF(0, 0x0d, 2)
+
+#endif
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 077/102] mtd: spi: Export spi_flash_std_probe()

2019-12-06 Thread Simon Glass
With of-platdata we need to create drivers for particular chips, or at
least drivers that are separate from the standard code, since C structures
are created by dtoc which are private to that driver.

To avoid duplicating the probing code, export this probe function for use
by these drivers.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

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

 drivers/mtd/spi/sf_probe.c |  2 +-
 include/spi_flash.h| 12 
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c
index f051e473ff..72b6ee702d 100644
--- a/drivers/mtd/spi/sf_probe.c
+++ b/drivers/mtd/spi/sf_probe.c
@@ -137,7 +137,7 @@ static int spi_flash_std_get_sw_write_prot(struct udevice 
*dev)
return spi_flash_cmd_get_sw_write_prot(flash);
 }
 
-static int spi_flash_std_probe(struct udevice *dev)
+int spi_flash_std_probe(struct udevice *dev)
 {
struct spi_slave *slave = dev_get_parent_priv(dev);
struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev);
diff --git a/include/spi_flash.h b/include/spi_flash.h
index 55b4721813..0b23f57a71 100644
--- a/include/spi_flash.h
+++ b/include/spi_flash.h
@@ -102,6 +102,18 @@ int spi_flash_erase_dm(struct udevice *dev, u32 offset, 
size_t len);
  */
 int spl_flash_get_sw_write_prot(struct udevice *dev);
 
+/**
+ * spi_flash_std_probe() - Probe a SPI flash device
+ *
+ * This is the standard internal method for probing a SPI flash device to
+ * determine its type. It can be used in chip-specific drivers which need to
+ * do this, typically with of-platdata
+ *
+ * @dev: SPI-flash device to probe
+ * @return 0 if OK, -ve on error
+ */
+int spi_flash_std_probe(struct udevice *dev);
+
 int spi_flash_probe_bus_cs(unsigned int busnum, unsigned int cs,
   unsigned int max_hz, unsigned int spi_mode,
   struct udevice **devp);
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 078/102] x86: Enable pinctrl in SPL and TPL

2019-12-06 Thread Simon Glass
If these phases are used we typically want to enable pinctrl in then, so
that pad setup and GPIO access are possible.

Signed-off-by: Simon Glass 
---

Changes in v6: None
Changes in v5:
- Correct build error in chromebook_samus_tpl

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

 arch/Kconfig   | 2 ++
 configs/chromebook_samus_tpl_defconfig | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/arch/Kconfig b/arch/Kconfig
index 54de91afb3..ae9c93ed7b 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -193,6 +193,7 @@ config X86
imply SPL_OF_LIBFDT
imply SPL_DRIVERS_MISC_SUPPORT
imply SPL_GPIO_SUPPORT
+   imply SPL_PINCTRL
imply SPL_LIBCOMMON_SUPPORT
imply SPL_LIBGENERIC_SUPPORT
imply SPL_SERIAL_SUPPORT
@@ -206,6 +207,7 @@ config X86
imply TPL_DM
imply TPL_DRIVERS_MISC_SUPPORT
imply TPL_GPIO_SUPPORT
+   imply TPL_PINCTRL
imply TPL_LIBCOMMON_SUPPORT
imply TPL_LIBGENERIC_SUPPORT
imply TPL_SERIAL_SUPPORT
diff --git a/configs/chromebook_samus_tpl_defconfig 
b/configs/chromebook_samus_tpl_defconfig
index 74b7e9a207..403b754ce9 100644
--- a/configs/chromebook_samus_tpl_defconfig
+++ b/configs/chromebook_samus_tpl_defconfig
@@ -72,6 +72,8 @@ CONFIG_SYS_I2C_DW=y
 CONFIG_TPL_MISC=y
 CONFIG_CROS_EC=y
 CONFIG_CROS_EC_LPC=y
+# CONFIG_SPL_PINCTRL is not set
+# CONFIG_TPL_PINCTRL is not set
 CONFIG_SYS_NS16550=y
 CONFIG_SOUND=y
 CONFIG_SOUND_I8254=y
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 079/102] x86: Add low-power subsystem (lpss) support

2019-12-06 Thread Simon Glass
This subsystem is present on various Intel SoCs.

Add very basic support for taking an lpss device out of reset.

Signed-off-by: Simon Glass 

---

Changes in v6: None
Changes in v5: None
Changes in v4:
- Add support for updating power state
- Move this to intel_common

Changes in v3: None
Changes in v2: None

 arch/x86/cpu/intel_common/Makefile |  1 +
 arch/x86/cpu/intel_common/lpss.c   | 44 ++
 arch/x86/include/asm/lpss.h| 36 
 3 files changed, 81 insertions(+)
 create mode 100644 arch/x86/cpu/intel_common/lpss.c
 create mode 100644 arch/x86/include/asm/lpss.h

diff --git a/arch/x86/cpu/intel_common/Makefile 
b/arch/x86/cpu/intel_common/Makefile
index 09212cee04..cc4e1c962b 100644
--- a/arch/x86/cpu/intel_common/Makefile
+++ b/arch/x86/cpu/intel_common/Makefile
@@ -19,6 +19,7 @@ endif
 obj-y += cpu.o
 obj-y += fast_spi.o
 obj-y += lpc.o
+obj-y += lpss.o
 ifndef CONFIG_TARGET_EFI_APP
 obj-$(CONFIG_$(SPL_TPL_)X86_32BIT_INIT) += microcode.o
 ifndef CONFIG_$(SPL_)X86_64
diff --git a/arch/x86/cpu/intel_common/lpss.c b/arch/x86/cpu/intel_common/lpss.c
new file mode 100644
index 00..26a2d2d1e3
--- /dev/null
+++ b/arch/x86/cpu/intel_common/lpss.c
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Special driver to handle of-platdata
+ *
+ * Copyright 2019 Google LLC
+ *
+ * Some code from coreboot lpss.c
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+enum {
+   LPSS_RESET_CTL_REG  = 0x204,
+
+   /*
+* Bit 1:0 controls LPSS controller reset.
+*
+* 00 ->LPSS Host Controller is in reset (Reset Asserted)
+* 01/10 ->Reserved
+* 11 ->LPSS Host Controller is NOT at reset (Reset Released)
+*/
+   LPSS_CNT_RST_RELEASE= 3,
+
+   /* Power management control and status register */
+   PME_CTRL_STATUS = 0x84,
+
+   /* Bit 1:0 Powerstate, controls D0 and D3 state */
+   POWER_STATE_MASK= 3,
+};
+
+/* Take controller out of reset */
+void lpss_reset_release(void *regs)
+{
+   writel(LPSS_CNT_RST_RELEASE, regs + LPSS_RESET_CTL_REG);
+}
+
+void lpss_set_power_state(struct udevice *dev, enum lpss_pwr_state state)
+{
+   dm_pci_clrset_config8(dev, PME_CTRL_STATUS, POWER_STATE_MASK, state);
+}
diff --git a/arch/x86/include/asm/lpss.h b/arch/x86/include/asm/lpss.h
new file mode 100644
index 00..7814872688
--- /dev/null
+++ b/arch/x86/include/asm/lpss.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2019 Google LLC
+ */
+
+#ifndef __ASM_LPSS_H
+#define __ASM_LPSS_H
+
+struct udevice;
+
+/* D0 and D3 enable config */
+enum lpss_pwr_state {
+   STATE_D0 = 0,
+   STATE_D3 = 3
+};
+
+/**
+ * lpss_reset_release() - Release device from reset
+ *
+ * This is used for devices which have LPSS support.
+ *
+ * @regs: Pointer to device registers
+ */
+void lpss_reset_release(void *regs);
+
+/**
+ * lpss_set_power_state() - Change power state of a device
+ *
+ * This is used for devices which have LPSS support.
+ *
+ * @dev: Device to update
+ * @state: New power state to set
+ */
+void lpss_set_power_state(struct udevice *dev, enum lpss_pwr_state state);
+
+#endif
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 075/102] spi: ich: Add TPL support

2019-12-06 Thread Simon Glass
In TPL we want to reduce code size and support running with CONFIG_PCI
disabled. Add special code to handle this using a fixed BAR programmed
into the SPI on boot. Also cache the SPI flash to speed up boot.

Signed-off-by: Simon Glass 

---

Changes in v6:
- Add a comment about why we should not use MTRR_TYPE_WRBACK
- Use SZ_4G instead of open-coding the size value

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

 drivers/spi/ich.c | 48 +++
 1 file changed, 44 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/ich.c b/drivers/spi/ich.c
index 160ec370fd..0cd073c03c 100644
--- a/drivers/spi/ich.c
+++ b/drivers/spi/ich.c
@@ -19,8 +19,11 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
+#include 
+#include 
 
 #include "ich.h"
 
@@ -115,6 +118,8 @@ static bool ich9_can_do_33mhz(struct udevice *dev)
struct ich_spi_priv *priv = dev_get_priv(dev);
u32 fdod, speed;
 
+   if (!CONFIG_IS_ENABLED(PCI))
+   return false;
/* Observe SPI Descriptor Component Section 0 */
dm_pci_write_config32(priv->pch, 0xb0, 0x1000);
 
@@ -706,6 +711,15 @@ static int ich_init_controller(struct udevice *dev,
   struct ich_spi_platdata *plat,
   struct ich_spi_priv *ctlr)
 {
+   if (spl_phase() == PHASE_TPL) {
+   struct ich_spi_platdata *plat = dev_get_platdata(dev);
+   int ret;
+
+   ret = fast_spi_early_init(plat->bdf, plat->mmio_base);
+   if (ret)
+   return ret;
+   }
+
ctlr->base = (void *)plat->mmio_base;
if (plat->ich_version == ICHV_7) {
struct ich7_spi_regs *ich7_spi = ctlr->base;
@@ -754,6 +768,26 @@ static int ich_init_controller(struct udevice *dev,
return 0;
 }
 
+static int ich_cache_bios_region(struct udevice *dev)
+{
+   ulong map_base;
+   uint map_size;
+   uint offset;
+   ulong base;
+   int ret;
+
+   ret = ich_get_mmap_bus(dev, _base, _size, );
+   if (ret)
+   return ret;
+
+   /* Don't use WRBACK since we are not supposed to write to SPI flash */
+   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 int ich_spi_probe(struct udevice *dev)
 {
struct ich_spi_platdata *plat = dev_get_platdata(dev);
@@ -764,10 +798,16 @@ static int ich_spi_probe(struct udevice *dev)
if (ret)
return ret;
 
-   ret = ich_protect_lockdown(dev);
-   if (ret)
-   return ret;
-
+   if (spl_phase() == PHASE_TPL) {
+   /* Cache the BIOS to speed things up */
+   ret = ich_cache_bios_region(dev);
+   if (ret)
+   return ret;
+   } else {
+   ret = ich_protect_lockdown(dev);
+   if (ret)
+   return ret;
+   }
priv->cur_speed = priv->max_speed;
 
return 0;
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 076/102] spi: ich: Add Apollo Lake support

2019-12-06 Thread Simon Glass
Add support for Apollo Lake to the ICH driver. This involves adjusting the
mmio address and skipping setting of the bbar.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

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

Changes in v3: None
Changes in v2: None

 drivers/spi/ich.c | 19 ++-
 drivers/spi/ich.h |  1 +
 2 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/spi/ich.c b/drivers/spi/ich.c
index 0cd073c03c..133b25b72e 100644
--- a/drivers/spi/ich.c
+++ b/drivers/spi/ich.c
@@ -106,10 +106,12 @@ static void ich_set_bbar(struct ich_spi_priv *ctlr, 
uint32_t minaddr)
const uint32_t bbar_mask = 0x0000;
uint32_t ichspi_bbar;
 
-   minaddr &= bbar_mask;
-   ichspi_bbar = ich_readl(ctlr, ctlr->bbar) & ~bbar_mask;
-   ichspi_bbar |= minaddr;
-   ich_writel(ctlr, ichspi_bbar, ctlr->bbar);
+   if (ctlr->bbar) {
+   minaddr &= bbar_mask;
+   ichspi_bbar = ich_readl(ctlr, ctlr->bbar) & ~bbar_mask;
+   ichspi_bbar |= minaddr;
+   ich_writel(ctlr, ichspi_bbar, ctlr->bbar);
+   }
 }
 
 /* @return 1 if the SPI flash supports the 33MHz speed */
@@ -750,6 +752,7 @@ static int ich_init_controller(struct udevice *dev,
ctlr->preop = offsetof(struct ich9_spi_regs, preop);
ctlr->bcr = offsetof(struct ich9_spi_regs, bcr);
ctlr->pr = _spi->pr[0];
+   } else if (plat->ich_version == ICHV_APL) {
} else {
debug("ICH SPI: Unrecognised ICH version %d\n",
  plat->ich_version);
@@ -878,7 +881,12 @@ static int ich_spi_ofdata_to_platdata(struct udevice *dev)
 
plat->ich_version = dev_get_driver_data(dev);
plat->lockdown = dev_read_bool(dev, "intel,spi-lock-down");
-   pch_get_spi_base(priv->pch, >mmio_base);
+   if (plat->ich_version == ICHV_APL) {
+   plat->mmio_base = dm_pci_read_bar32(dev, 0);
+   } else  {
+   /* SBASE is similar */
+   pch_get_spi_base(priv->pch, >mmio_base);
+   }
/*
 * Use an int so that the property is present in of-platdata even
 * when false.
@@ -916,6 +924,7 @@ static const struct dm_spi_ops ich_spi_ops = {
 static const struct udevice_id ich_spi_ids[] = {
{ .compatible = "intel,ich7-spi", ICHV_7 },
{ .compatible = "intel,ich9-spi", ICHV_9 },
+   { .compatible = "intel,fast-spi", ICHV_APL },
{ }
 };
 
diff --git a/drivers/spi/ich.h b/drivers/spi/ich.h
index c7cf37b932..d7f1ffdf37 100644
--- a/drivers/spi/ich.h
+++ b/drivers/spi/ich.h
@@ -205,6 +205,7 @@ enum hsfsts_cycle_t {
 enum ich_version {
ICHV_7,
ICHV_9,
+   ICHV_APL,
 };
 
 struct ich_spi_priv {
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 073/102] spi: ich: Support hardware sequencing

2019-12-06 Thread Simon Glass
Apollo Lake (APL) only supports hardware sequencing. Add support for this
into the SPI driver, as an option.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 

---

Changes in v6:
- Add a comment as to why dev_read_bool() is not used

Changes in v5: None
Changes in v4:
- Fix comment for exec_sync_hwseq_xfer()
- apollolake -> Apollo Lake

Changes in v3: None
Changes in v2: None

 drivers/spi/ich.c | 209 +-
 drivers/spi/ich.h |  39 +
 2 files changed, 245 insertions(+), 3 deletions(-)

diff --git a/drivers/spi/ich.c b/drivers/spi/ich.c
index 7d66b900c8..db895a396d 100644
--- a/drivers/spi/ich.c
+++ b/drivers/spi/ich.c
@@ -17,7 +17,9 @@
 #include 
 #include 
 #include 
+#include 
 #include 
+#include 
 #include 
 
 #include "ich.h"
@@ -36,6 +38,7 @@ struct ich_spi_platdata {
bool lockdown;  /* lock down controller settings? */
ulong mmio_base;/* Base of MMIO registers */
pci_dev_t bdf;  /* PCI address used by of-platdata */
+   bool hwseq; /* Use hardware sequencing (not s/w) */
 };
 
 static u8 ich_readb(struct ich_spi_priv *priv, int reg)
@@ -245,7 +248,8 @@ static void ich_spi_config_opcode(struct udevice *dev)
ich_writel(ctlr, SPI_OPMENU_UPPER, ctlr->opmenu + sizeof(u32));
 }
 
-static int ich_spi_exec_op(struct spi_slave *slave, const struct spi_mem_op 
*op)
+static int ich_spi_exec_op_swseq(struct spi_slave *slave,
+const struct spi_mem_op *op)
 {
struct udevice *bus = dev_get_parent(slave->dev);
struct ich_spi_platdata *plat = dev_get_platdata(bus);
@@ -416,6 +420,197 @@ static int ich_spi_exec_op(struct spi_slave *slave, const 
struct spi_mem_op *op)
return 0;
 }
 
+/*
+ * Ensure read/write xfer len is not greater than SPIBAR_FDATA_FIFO_SIZE and
+ * that the operation does not cross page boundary.
+ */
+static uint get_xfer_len(u32 offset, int len, int page_size)
+{
+   uint xfer_len = min(len, SPIBAR_FDATA_FIFO_SIZE);
+   uint bytes_left = ALIGN(offset, page_size) - offset;
+
+   if (bytes_left)
+   xfer_len = min(xfer_len, bytes_left);
+
+   return xfer_len;
+}
+
+/* Fill FDATAn FIFO in preparation for a write transaction */
+static void fill_xfer_fifo(struct fast_spi_regs *regs, const void *data,
+  uint len)
+{
+   memcpy(regs->fdata, data, len);
+}
+
+/* Drain FDATAn FIFO after a read transaction populates data */
+static void drain_xfer_fifo(struct fast_spi_regs *regs, void *dest, uint len)
+{
+   memcpy(dest, regs->fdata, len);
+}
+
+/* Fire up a transfer using the hardware sequencer */
+static void start_hwseq_xfer(struct fast_spi_regs *regs, uint hsfsts_cycle,
+uint offset, uint len)
+{
+   /* Make sure all W1C status bits get cleared */
+   u32 hsfsts;
+
+   hsfsts = readl(>hsfsts_ctl);
+   hsfsts &= ~(HSFSTS_FCYCLE_MASK | HSFSTS_FDBC_MASK);
+   hsfsts |= HSFSTS_AEL | HSFSTS_FCERR | HSFSTS_FDONE;
+
+   /* Set up transaction parameters */
+   hsfsts |= hsfsts_cycle << HSFSTS_FCYCLE_SHIFT;
+   hsfsts |= ((len - 1) << HSFSTS_FDBC_SHIFT) & HSFSTS_FDBC_MASK;
+   hsfsts |= HSFSTS_FGO;
+
+   writel(offset, >faddr);
+   writel(hsfsts, >hsfsts_ctl);
+}
+
+static int wait_for_hwseq_xfer(struct fast_spi_regs *regs, uint offset)
+{
+   ulong start;
+   u32 hsfsts;
+
+   start = get_timer(0);
+   do {
+   hsfsts = readl(>hsfsts_ctl);
+   if (hsfsts & HSFSTS_FCERR) {
+   debug("SPI transaction error at offset %x HSFSTS = 
%08x\n",
+ offset, hsfsts);
+   return -EIO;
+   }
+   if (hsfsts & HSFSTS_AEL)
+   return -EPERM;
+
+   if (hsfsts & HSFSTS_FDONE)
+   return 0;
+   } while (get_timer(start) < SPIBAR_HWSEQ_XFER_TIMEOUT_MS);
+
+   debug("SPI transaction timeout at offset %x HSFSTS = %08x, timer %d\n",
+ offset, hsfsts, (uint)get_timer(start));
+
+   return -ETIMEDOUT;
+}
+
+/**
+ * exec_sync_hwseq_xfer() - Execute flash transfer by hardware sequencing
+ *
+ * This waits until complete or timeout
+ *
+ * @regs: SPI registers
+ * @hsfsts_cycle: Cycle type (enum hsfsts_cycle_t)
+ * @offset: Offset to access
+ * @len: Number of bytes to transfer (can be 0)
+ * @return 0 if OK, -EIO on flash-cycle error (FCERR), -EPERM on access error
+ * (AEL), -ETIMEDOUT on timeout
+ */
+static int exec_sync_hwseq_xfer(struct fast_spi_regs *regs, uint hsfsts_cycle,
+   uint offset, uint len)
+{
+   start_hwseq_xfer(regs, hsfsts_cycle, offset, len);
+
+   return wait_for_hwseq_xfer(regs, offset);
+}
+
+static int ich_spi_exec_op_hwseq(struct spi_slave *slave,
+const struct spi_mem_op *op)
+{
+   struct 

[PATCH v6 074/102] spi: ich: Add support for get_mmap() method

2019-12-06 Thread Simon Glass
Add this method so that the memory-mapped location of the SPI flash can
be queried.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

Changes in v6: None
Changes in v5: None
Changes in v4:
- Use the new pci_ofplat_get_devfn() function

Changes in v3: None
Changes in v2: None

 drivers/spi/ich.c | 32 
 1 file changed, 32 insertions(+)

diff --git a/drivers/spi/ich.c b/drivers/spi/ich.c
index db895a396d..160ec370fd 100644
--- a/drivers/spi/ich.c
+++ b/drivers/spi/ich.c
@@ -611,6 +611,37 @@ static int ich_spi_exec_op(struct spi_slave *slave, const 
struct spi_mem_op *op)
return ret;
 }
 
+static int ich_get_mmap_bus(struct udevice *bus, ulong *map_basep,
+   uint *map_sizep, uint *offsetp)
+{
+   pci_dev_t spi_bdf;
+
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
+   struct pci_child_platdata *pplat = dev_get_parent_platdata(bus);
+
+   spi_bdf = pplat->devfn;
+#else
+   struct ich_spi_platdata *plat = dev_get_platdata(bus);
+
+   /*
+* We cannot rely on plat->bdf being set up yet since this method can
+* be called before the device is probed. Use the of-platdata directly
+* instead.
+*/
+   spi_bdf = pci_ofplat_get_devfn(plat->dtplat.reg[0]);
+#endif
+
+   return fast_spi_get_bios_mmap(spi_bdf, map_basep, map_sizep, offsetp);
+}
+
+static int ich_get_mmap(struct udevice *dev, ulong *map_basep, uint *map_sizep,
+   uint *offsetp)
+{
+   struct udevice *bus = dev_get_parent(dev);
+
+   return ich_get_mmap_bus(bus, map_basep, map_sizep, offsetp);
+}
+
 static int ich_spi_adjust_size(struct spi_slave *slave, struct spi_mem_op *op)
 {
unsigned int page_offset;
@@ -835,6 +866,7 @@ static const struct dm_spi_ops ich_spi_ops = {
.set_speed  = ich_spi_set_speed,
.set_mode   = ich_spi_set_mode,
.mem_ops= _controller_mem_ops,
+   .get_mmap   = ich_get_mmap,
/*
 * cs_info is not needed, since we require all chip selects to be
 * in the device tree explicitly
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 070/102] dm: doc: Add a note about of-platdata and header files

2019-12-06 Thread Simon Glass
We don't want to include dt-structs.h in header files, so add a note about
that.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

Changes in v6: None
Changes in v5: None
Changes in v4:
- Add a patch to explain of-platdata and header files

Changes in v3: None
Changes in v2: None

 doc/driver-model/of-plat.rst | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/doc/driver-model/of-plat.rst b/doc/driver-model/of-plat.rst
index 557957d2a1..034a68bb4e 100644
--- a/doc/driver-model/of-plat.rst
+++ b/doc/driver-model/of-plat.rst
@@ -279,6 +279,12 @@ For example:
 };
 
 
+Note that struct mmc_platdata is defined in the C file, not in a header. This
+is to avoid needing to include dt-structs.h in a header file. The idea is to
+keep the use of each of-platdata struct to the smallest possible code area.
+There is just one driver C file for each struct, that can convert from the
+of-platdata struct to the standard one used by the driver.
+
 In the case where SPL_OF_PLATDATA is enabled, platdata_auto_alloc_size is
 still used to allocate space for the platform data. This is different from
 the normal behaviour and is triggered by the use of of-platdata (strictly
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 072/102] spi: ich: Support of-platdata for fast-spi

2019-12-06 Thread Simon Glass
The Intel Fast SPI interface is similar to ICH. Add of-platdata support
for this using the "intel,fast-spi" compatible string.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

Changes in v6: None
Changes in v5: None
Changes in v4:
- Use the new pci_ofplat_get_devfn() function

Changes in v3: None
Changes in v2: None

 drivers/spi/ich.c | 18 +++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/drivers/spi/ich.c b/drivers/spi/ich.c
index 17b7a0ba0b..7d66b900c8 100644
--- a/drivers/spi/ich.c
+++ b/drivers/spi/ich.c
@@ -10,6 +10,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -28,9 +29,13 @@
 #endif
 
 struct ich_spi_platdata {
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+   struct dtd_intel_fast_spi dtplat;
+#endif
enum ich_version ich_version;   /* Controller version, 7 or 9 */
bool lockdown;  /* lock down controller settings? */
ulong mmio_base;/* Base of MMIO registers */
+   pci_dev_t bdf;  /* PCI address used by of-platdata */
 };
 
 static u8 ich_readb(struct ich_spi_priv *priv, int reg)
@@ -594,6 +599,8 @@ static int ich_spi_child_pre_probe(struct udevice *dev)
 static int ich_spi_ofdata_to_platdata(struct udevice *dev)
 {
struct ich_spi_platdata *plat = dev_get_platdata(dev);
+
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
struct ich_spi_priv *priv = dev_get_priv(dev);
 
/* Find a PCH if there is one */
@@ -603,8 +610,13 @@ static int ich_spi_ofdata_to_platdata(struct udevice *dev)
 
plat->ich_version = dev_get_driver_data(dev);
plat->lockdown = dev_read_bool(dev, "intel,spi-lock-down");
-
pch_get_spi_base(priv->pch, >mmio_base);
+#else
+   plat->ich_version = ICHV_APL;
+   plat->mmio_base = plat->dtplat.early_regs[0];
+   plat->bdf = pci_ofplat_get_devfn(plat->dtplat.reg[0]);
+#endif
+   debug("%s: mmio_base=%lx\n", __func__, plat->mmio_base);
 
return 0;
 }
@@ -632,8 +644,8 @@ static const struct udevice_id ich_spi_ids[] = {
{ }
 };
 
-U_BOOT_DRIVER(ich_spi) = {
-   .name   = "ich_spi",
+U_BOOT_DRIVER(intel_fast_spi) = {
+   .name   = "intel_fast_spi",
.id = UCLASS_SPI,
.of_match = ich_spi_ids,
.ops= _spi_ops,
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 071/102] spi: ich: Correct max-size bug in ich_spi_adjust_size()

2019-12-06 Thread Simon Glass
This incorrectly shortens read operations if there is a maximum write size
but no maximum read size. Fix it.

Signed-off-by: Simon Glass 
---

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

 drivers/spi/ich.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/spi/ich.c b/drivers/spi/ich.c
index 08c37ca4ab..17b7a0ba0b 100644
--- a/drivers/spi/ich.c
+++ b/drivers/spi/ich.c
@@ -425,9 +425,11 @@ static int ich_spi_adjust_size(struct spi_slave *slave, 
struct spi_mem_op *op)
page_offset = do_div(aux, ICH_BOUNDARY);
}
 
-   if (op->data.dir == SPI_MEM_DATA_IN && slave->max_read_size) {
-   op->data.nbytes = min(ICH_BOUNDARY - page_offset,
- slave->max_read_size);
+   if (op->data.dir == SPI_MEM_DATA_IN) {
+   if (slave->max_read_size) {
+   op->data.nbytes = min(ICH_BOUNDARY - page_offset,
+ slave->max_read_size);
+   }
} else if (slave->max_write_size) {
op->data.nbytes = min(ICH_BOUNDARY - page_offset,
  slave->max_write_size);
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 068/102] spi: ich: Various small tidy-ups

2019-12-06 Thread Simon Glass
Use debug() instead of printf() to reduce code size and change a bool
return value to the use the 'bool' type. Also drop the global data
declaration since it not actually used. Finally, set the log category.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

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

 drivers/spi/ich.c | 17 -
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/spi/ich.c b/drivers/spi/ich.c
index eeb4c274b8..b83dfb854d 100644
--- a/drivers/spi/ich.c
+++ b/drivers/spi/ich.c
@@ -5,6 +5,8 @@
  * This file is derived from the flashrom project.
  */
 
+#define LOG_CATEGORY   UCLASS_SPI
+
 #include 
 #include 
 #include 
@@ -19,8 +21,6 @@
 
 #include "ich.h"
 
-DECLARE_GLOBAL_DATA_PTR;
-
 #ifdef DEBUG_TRACE
 #define debug_trace(fmt, args...) debug(fmt, ##args)
 #else
@@ -96,7 +96,7 @@ static void ich_set_bbar(struct ich_spi_priv *ctlr, uint32_t 
minaddr)
 }
 
 /* @return 1 if the SPI flash supports the 33MHz speed */
-static int ich9_can_do_33mhz(struct udevice *dev)
+static bool ich9_can_do_33mhz(struct udevice *dev)
 {
struct ich_spi_priv *priv = dev_get_priv(dev);
u32 fdod, speed;
@@ -173,8 +173,7 @@ static int spi_setup_opcode(struct ich_spi_priv *ctlr, 
struct spi_trans *trans,
}
 
if (opcode_index == ctlr->menubytes) {
-   printf("ICH SPI: Opcode %x not found\n",
-  trans->opcode);
+   debug("ICH SPI: Opcode %x not found\n", trans->opcode);
return -EINVAL;
}
 
@@ -182,8 +181,8 @@ static int spi_setup_opcode(struct ich_spi_priv *ctlr, 
struct spi_trans *trans,
optype = (optypes >> (opcode_index * 2)) & 0x3;
 
if (optype != trans->type) {
-   printf("ICH SPI: Transaction doesn't fit type %d\n",
-  optype);
+   debug("ICH SPI: Transaction doesn't fit type %d\n",
+ optype);
return -ENOSPC;
}
return opcode_index;
@@ -214,9 +213,9 @@ static int ich_status_poll(struct ich_spi_priv *ctlr, u16 
bitmask,
}
udelay(10);
}
+   debug("ICH SPI: SCIP timeout, read %x, expected %x, wts %x %x\n",
+ status, bitmask, wait_til_set, status & bitmask);
 
-   printf("ICH SPI: SCIP timeout, read %x, expected %x\n",
-  status, bitmask);
return -ETIMEDOUT;
 }
 
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 067/102] spi: ich: Fix header order

2019-12-06 Thread Simon Glass
Move the header files into the right order.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

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

 drivers/spi/ich.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/ich.c b/drivers/spi/ich.c
index 6460144560..eeb4c274b8 100644
--- a/drivers/spi/ich.c
+++ b/drivers/spi/ich.c
@@ -6,6 +6,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -13,9 +14,8 @@
 #include 
 #include 
 #include 
-#include 
 #include 
-#include 
+#include 
 
 #include "ich.h"
 
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 066/102] spi: ich: Convert to livetree

2019-12-06 Thread Simon Glass
Use dev_get_driver_data() to obtain the device type. It has the same
effect and is shorter.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

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

 drivers/spi/ich.c | 22 +-
 1 file changed, 5 insertions(+), 17 deletions(-)

diff --git a/drivers/spi/ich.c b/drivers/spi/ich.c
index 4d61be02ec..6460144560 100644
--- a/drivers/spi/ich.c
+++ b/drivers/spi/ich.c
@@ -597,28 +597,16 @@ static int ich_spi_ofdata_to_platdata(struct udevice *dev)
 {
struct ich_spi_platdata *plat = dev_get_platdata(dev);
struct ich_spi_priv *priv = dev_get_priv(dev);
-   int node = dev_of_offset(dev);
-   int ret;
 
/* Find a PCH if there is one */
uclass_first_device(UCLASS_PCH, >pch);
if (!priv->pch)
priv->pch = dev_get_parent(dev);
 
-   ret = fdt_node_check_compatible(gd->fdt_blob, node, "intel,ich7-spi");
-   if (ret == 0) {
-   plat->ich_version = ICHV_7;
-   } else {
-   ret = fdt_node_check_compatible(gd->fdt_blob, node,
-   "intel,ich9-spi");
-   if (ret == 0)
-   plat->ich_version = ICHV_9;
-   }
+   plat->ich_version = dev_get_driver_data(dev);
+   plat->lockdown = dev_read_bool(dev, "intel,spi-lock-down");
 
-   plat->lockdown = fdtdec_get_bool(gd->fdt_blob, node,
-"intel,spi-lock-down");
-
-   return ret;
+   return 0;
 }
 
 static const struct spi_controller_mem_ops ich_controller_mem_ops = {
@@ -639,8 +627,8 @@ static const struct dm_spi_ops ich_spi_ops = {
 };
 
 static const struct udevice_id ich_spi_ids[] = {
-   { .compatible = "intel,ich7-spi" },
-   { .compatible = "intel,ich9-spi" },
+   { .compatible = "intel,ich7-spi", ICHV_7 },
+   { .compatible = "intel,ich9-spi", ICHV_9 },
{ }
 };
 
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 069/102] spi: ich: Add mmio_base to struct ich_spi_platdata

2019-12-06 Thread Simon Glass
It is useful to store the mmio base in platdata. It reduces the amount of
casting needed. Update the code and move the struct to the C file at the
same time, as we will need to use with of-platdata.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

Changes in v6: None
Changes in v5: None
Changes in v4:
- Use priv->pch instead of dev->parent

Changes in v3: None
Changes in v2: None

 drivers/spi/ich.c | 27 +--
 drivers/spi/ich.h |  5 -
 2 files changed, 13 insertions(+), 19 deletions(-)

diff --git a/drivers/spi/ich.c b/drivers/spi/ich.c
index b83dfb854d..08c37ca4ab 100644
--- a/drivers/spi/ich.c
+++ b/drivers/spi/ich.c
@@ -27,6 +27,12 @@
 #define debug_trace(x, args...)
 #endif
 
+struct ich_spi_platdata {
+   enum ich_version ich_version;   /* Controller version, 7 or 9 */
+   bool lockdown;  /* lock down controller settings? */
+   ulong mmio_base;/* Base of MMIO registers */
+};
+
 static u8 ich_readb(struct ich_spi_priv *priv, int reg)
 {
u8 value = readb(priv->base + reg);
@@ -467,16 +473,9 @@ static int ich_init_controller(struct udevice *dev,
   struct ich_spi_platdata *plat,
   struct ich_spi_priv *ctlr)
 {
-   ulong sbase_addr;
-   void *sbase;
-
-   /* SBASE is similar */
-   pch_get_spi_base(dev->parent, _addr);
-   sbase = (void *)sbase_addr;
-   debug("%s: sbase=%p\n", __func__, sbase);
-
+   ctlr->base = (void *)plat->mmio_base;
if (plat->ich_version == ICHV_7) {
-   struct ich7_spi_regs *ich7_spi = sbase;
+   struct ich7_spi_regs *ich7_spi = ctlr->base;
 
ctlr->opmenu = offsetof(struct ich7_spi_regs, opmenu);
ctlr->menubytes = sizeof(ich7_spi->opmenu);
@@ -488,9 +487,8 @@ static int ich_init_controller(struct udevice *dev,
ctlr->control = offsetof(struct ich7_spi_regs, spic);
ctlr->bbar = offsetof(struct ich7_spi_regs, bbar);
ctlr->preop = offsetof(struct ich7_spi_regs, preop);
-   ctlr->base = ich7_spi;
} else if (plat->ich_version == ICHV_9) {
-   struct ich9_spi_regs *ich9_spi = sbase;
+   struct ich9_spi_regs *ich9_spi = ctlr->base;
 
ctlr->opmenu = offsetof(struct ich9_spi_regs, opmenu);
ctlr->menubytes = sizeof(ich9_spi->opmenu);
@@ -505,7 +503,6 @@ static int ich_init_controller(struct udevice *dev,
ctlr->preop = offsetof(struct ich9_spi_regs, preop);
ctlr->bcr = offsetof(struct ich9_spi_regs, bcr);
ctlr->pr = _spi->pr[0];
-   ctlr->base = ich9_spi;
} else {
debug("ICH SPI: Unrecognised ICH version %d\n",
  plat->ich_version);
@@ -516,8 +513,8 @@ static int ich_init_controller(struct udevice *dev,
ctlr->max_speed = 2000;
if (plat->ich_version == ICHV_9 && ich9_can_do_33mhz(dev))
ctlr->max_speed = 3300;
-   debug("ICH SPI: Version ID %d detected at %p, speed %ld\n",
- plat->ich_version, ctlr->base, ctlr->max_speed);
+   debug("ICH SPI: Version ID %d detected at %lx, speed %ld\n",
+ plat->ich_version, plat->mmio_base, ctlr->max_speed);
 
ich_set_bbar(ctlr, 0);
 
@@ -605,6 +602,8 @@ static int ich_spi_ofdata_to_platdata(struct udevice *dev)
plat->ich_version = dev_get_driver_data(dev);
plat->lockdown = dev_read_bool(dev, "intel,spi-lock-down");
 
+   pch_get_spi_base(priv->pch, >mmio_base);
+
return 0;
 }
 
diff --git a/drivers/spi/ich.h b/drivers/spi/ich.h
index 77057878a5..623b2c547a 100644
--- a/drivers/spi/ich.h
+++ b/drivers/spi/ich.h
@@ -168,11 +168,6 @@ enum ich_version {
ICHV_9,
 };
 
-struct ich_spi_platdata {
-   enum ich_version ich_version;   /* Controller version, 7 or 9 */
-   bool lockdown;  /* lock down controller settings? */
-};
-
 struct ich_spi_priv {
int opmenu;
int menubytes;
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 065/102] spi: ich: Move the protection/lockdown code into a function

2019-12-06 Thread Simon Glass
Reduce the size of the probe function but putting this code into its own
function.

Also remove the assumption that the PCH is always a parent of the SPI
controller, as this is not the case APL platforms. Use driver model to
find the PCH instead.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

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

 drivers/spi/ich.c | 63 ---
 drivers/spi/ich.h |  1 +
 2 files changed, 44 insertions(+), 20 deletions(-)

diff --git a/drivers/spi/ich.c b/drivers/spi/ich.c
index 3eb4599ba2..4d61be02ec 100644
--- a/drivers/spi/ich.c
+++ b/drivers/spi/ich.c
@@ -98,13 +98,14 @@ static void ich_set_bbar(struct ich_spi_priv *ctlr, 
uint32_t minaddr)
 /* @return 1 if the SPI flash supports the 33MHz speed */
 static int ich9_can_do_33mhz(struct udevice *dev)
 {
+   struct ich_spi_priv *priv = dev_get_priv(dev);
u32 fdod, speed;
 
/* Observe SPI Descriptor Component Section 0 */
-   dm_pci_write_config32(dev->parent, 0xb0, 0x1000);
+   dm_pci_write_config32(priv->pch, 0xb0, 0x1000);
 
/* Extract the Write/Erase SPI Frequency from descriptor */
-   dm_pci_read_config32(dev->parent, 0xb4, );
+   dm_pci_read_config32(priv->pch, 0xb4, );
 
/* Bits 23:21 have the fast read clock frequency, 0=20MHz, 1=33MHz */
speed = (fdod >> 21) & 7;
@@ -432,6 +433,37 @@ static int ich_spi_adjust_size(struct spi_slave *slave, 
struct spi_mem_op *op)
return 0;
 }
 
+static int ich_protect_lockdown(struct udevice *dev)
+{
+   struct ich_spi_platdata *plat = dev_get_platdata(dev);
+   struct ich_spi_priv *priv = dev_get_priv(dev);
+   int ret = -ENOSYS;
+
+   /* Disable the BIOS write protect so write commands are allowed */
+   if (priv->pch)
+   ret = pch_set_spi_protect(priv->pch, false);
+   if (ret == -ENOSYS) {
+   u8 bios_cntl;
+
+   bios_cntl = ich_readb(priv, priv->bcr);
+   bios_cntl &= ~BIT(5);   /* clear Enable InSMM_STS (EISS) */
+   bios_cntl |= 1; /* Write Protect Disable (WPD) */
+   ich_writeb(priv, bios_cntl, priv->bcr);
+   } else if (ret) {
+   debug("%s: Failed to disable write-protect: err=%d\n",
+ __func__, ret);
+   return ret;
+   }
+
+   /* Lock down SPI controller settings if required */
+   if (plat->lockdown) {
+   ich_spi_config_opcode(dev);
+   spi_lock_down(plat, priv->base);
+   }
+
+   return 0;
+}
+
 static int ich_init_controller(struct udevice *dev,
   struct ich_spi_platdata *plat,
   struct ich_spi_priv *ctlr)
@@ -497,30 +529,15 @@ static int ich_spi_probe(struct udevice *dev)
 {
struct ich_spi_platdata *plat = dev_get_platdata(dev);
struct ich_spi_priv *priv = dev_get_priv(dev);
-   uint8_t bios_cntl;
int ret;
 
ret = ich_init_controller(dev, plat, priv);
if (ret)
return ret;
-   /* Disable the BIOS write protect so write commands are allowed */
-   ret = pch_set_spi_protect(dev->parent, false);
-   if (ret == -ENOSYS) {
-   bios_cntl = ich_readb(priv, priv->bcr);
-   bios_cntl &= ~BIT(5);   /* clear Enable InSMM_STS (EISS) */
-   bios_cntl |= 1; /* Write Protect Disable (WPD) */
-   ich_writeb(priv, bios_cntl, priv->bcr);
-   } else if (ret) {
-   debug("%s: Failed to disable write-protect: err=%d\n",
- __func__, ret);
-   return ret;
-   }
 
-   /* Lock down SPI controller settings if required */
-   if (plat->lockdown) {
-   ich_spi_config_opcode(dev);
-   spi_lock_down(plat, priv->base);
-   }
+   ret = ich_protect_lockdown(dev);
+   if (ret)
+   return ret;
 
priv->cur_speed = priv->max_speed;
 
@@ -579,9 +596,15 @@ static int ich_spi_child_pre_probe(struct udevice *dev)
 static int ich_spi_ofdata_to_platdata(struct udevice *dev)
 {
struct ich_spi_platdata *plat = dev_get_platdata(dev);
+   struct ich_spi_priv *priv = dev_get_priv(dev);
int node = dev_of_offset(dev);
int ret;
 
+   /* Find a PCH if there is one */
+   uclass_first_device(UCLASS_PCH, >pch);
+   if (!priv->pch)
+   priv->pch = dev_get_parent(dev);
+
ret = fdt_node_check_compatible(gd->fdt_blob, node, "intel,ich7-spi");
if (ret == 0) {
plat->ich_version = ICHV_7;
diff --git a/drivers/spi/ich.h b/drivers/spi/ich.h
index 3dfb2aaff1..77057878a5 100644
--- a/drivers/spi/ich.h
+++ b/drivers/spi/ich.h
@@ -191,6 +191,7 @@ struct ich_spi_priv {
ulong max_speed;/* Maximum bus speed in MHz */
ulong cur_speed;/* Current bus speed */

[PATCH v6 063/102] x86: spi: Don't enable SPI_FLASH_BAR by default

2019-12-06 Thread Simon Glass
We don't normally need this on x86 unless the size of SPI flash devices is
larger than 16MB. This can be enabled by particular SoCs as needed, since
it adds to code size.

Drop the default enabling of this option on x86.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

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

 drivers/spi/Kconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 8588866489..fae2040af8 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -142,7 +142,6 @@ config FSL_DSPI
 
 config ICH_SPI
bool "Intel ICH SPI driver"
-   imply SPI_FLASH_BAR
help
  Enable the Intel ICH SPI driver. This driver can be used to
  access the SPI NOR flash on platforms embedding this Intel
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 061/102] x86: Make MSR_PKG_POWER_SKU common

2019-12-06 Thread Simon Glass
This is used on several boards so add it to the common file. Also add a
useful power-limit value while we are here.

Reviewed-by: Bin Meng 
Signed-off-by: Simon Glass 
---

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

 arch/x86/include/asm/arch-broadwell/cpu.h | 1 -
 arch/x86/include/asm/arch-ivybridge/model_206ax.h | 1 -
 arch/x86/include/asm/msr-index.h  | 9 -
 3 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/arch-broadwell/cpu.h 
b/arch/x86/include/asm/arch-broadwell/cpu.h
index 3bc3bd6609..2b39a76fbd 100644
--- a/arch/x86/include/asm/arch-broadwell/cpu.h
+++ b/arch/x86/include/asm/arch-broadwell/cpu.h
@@ -27,7 +27,6 @@
 
 #define MSR_VR_CURRENT_CONFIG  0x601
 #define MSR_VR_MISC_CONFIG 0x603
-#define MSR_PKG_POWER_SKU  0x614
 #define MSR_DDR_RAPL_LIMIT 0x618
 #define MSR_VR_MISC_CONFIG20x636
 
diff --git a/arch/x86/include/asm/arch-ivybridge/model_206ax.h 
b/arch/x86/include/asm/arch-ivybridge/model_206ax.h
index 4839ebc312..5c066294bc 100644
--- a/arch/x86/include/asm/arch-ivybridge/model_206ax.h
+++ b/arch/x86/include/asm/arch-ivybridge/model_206ax.h
@@ -43,7 +43,6 @@
 #define MSR_PP1_CURRENT_CONFIG 0x602
 #define  PP1_CURRENT_LIMIT_SNB (35 << 3) /* 35 A */
 #define  PP1_CURRENT_LIMIT_IVB (50 << 3) /* 50 A */
-#define MSR_PKG_POWER_SKU  0x614
 
 #define IVB_CONFIG_TDP_MIN_CPUID   0x306a2
 #define MSR_CONFIG_TDP_LEVEL1  0x649
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 5bc8b6c22c..79a9369de1 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -241,10 +241,17 @@
 #define  PKG_POWER_LIMIT_CLAMP (1 << 16)
 #define  PKG_POWER_LIMIT_TIME_SHIFT17
 #define  PKG_POWER_LIMIT_TIME_MASK 0x7f
+/*
+ * For Mobile, RAPL default PL1 time window value set to 28 seconds.
+ * RAPL time window calculation defined as follows:
+ * Time Window = (float)((1+X/4)*(2*^Y), X Corresponds to [23:22],
+ * Y to [21:17] in MSR 0x610. 28 sec is equal to 0x6e.
+ */
+#define  MB_POWER_LIMIT1_TIME_DEFAULT  0x6e
 
 #define MSR_PKG_ENERGY_STATUS  0x0611
 #define MSR_PKG_PERF_STATUS0x0613
-#define MSR_PKG_POWER_INFO 0x0614
+#define MSR_PKG_POWER_SKU  0x614
 
 #define MSR_DRAM_POWER_LIMIT   0x0618
 #define MSR_DRAM_ENERGY_STATUS 0x0619
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 060/102] x86: Separate out U-Boot and device tree in ROM image

2019-12-06 Thread Simon Glass
At present binman does not support updating a device tree that is part of
U-Boot (i.e u-boot.bin). Separate the entries into two so that we can get
updated entry information. This makes binman_entry_find() work correctly.

Do the same for SPL tool.

In both cases, group the two parts into a section so that SPL symbols get
the correct total size.

It may be possible for binman to handle this automatically at some point,
by ignoring u-boot.bin and always creating it from u-boot-nodtb.bin and
u-boot.dtb

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

Changes in v6: None
Changes in v5:
- Change SPL as well
- Group U-Boot and device tree into a section
- Rename spl section to 'spl' so that binman symbols can find it

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

 arch/x86/dts/u-boot.dtsi | 14 +++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/arch/x86/dts/u-boot.dtsi b/arch/x86/dts/u-boot.dtsi
index e0cca58640..f0f8c71761 100644
--- a/arch/x86/dts/u-boot.dtsi
+++ b/arch/x86/dts/u-boot.dtsi
@@ -44,13 +44,21 @@
u-boot-tpl-dtb {
};
 #endif
-   u-boot-spl {
+   spl {
+   type = "section";
offset = ;
-   };
-   u-boot-spl-dtb {
+   u-boot-spl {
+   };
+   u-boot-spl-dtb {
+   };
};
u-boot {
+   type = "section";
offset = ;
+   u-boot-nodtb {
+   };
+   u-boot-dtb {
+   };
};
 #elif defined(CONFIG_SPL)
u-boot-spl-with-ucode-ptr {
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 064/102] spi: ich: Move init function just above probe()

2019-12-06 Thread Simon Glass
It is annoying to have some of the init code in a different part of the
file. Move ich_init_controller() to just above probe() to keep things
together.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

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

 drivers/spi/ich.c | 122 +++---
 1 file changed, 61 insertions(+), 61 deletions(-)

diff --git a/drivers/spi/ich.c b/drivers/spi/ich.c
index a4e4ad55c6..3eb4599ba2 100644
--- a/drivers/spi/ich.c
+++ b/drivers/spi/ich.c
@@ -112,67 +112,6 @@ static int ich9_can_do_33mhz(struct udevice *dev)
return speed == 1;
 }
 
-static int ich_init_controller(struct udevice *dev,
-  struct ich_spi_platdata *plat,
-  struct ich_spi_priv *ctlr)
-{
-   ulong sbase_addr;
-   void *sbase;
-
-   /* SBASE is similar */
-   pch_get_spi_base(dev->parent, _addr);
-   sbase = (void *)sbase_addr;
-   debug("%s: sbase=%p\n", __func__, sbase);
-
-   if (plat->ich_version == ICHV_7) {
-   struct ich7_spi_regs *ich7_spi = sbase;
-
-   ctlr->opmenu = offsetof(struct ich7_spi_regs, opmenu);
-   ctlr->menubytes = sizeof(ich7_spi->opmenu);
-   ctlr->optype = offsetof(struct ich7_spi_regs, optype);
-   ctlr->addr = offsetof(struct ich7_spi_regs, spia);
-   ctlr->data = offsetof(struct ich7_spi_regs, spid);
-   ctlr->databytes = sizeof(ich7_spi->spid);
-   ctlr->status = offsetof(struct ich7_spi_regs, spis);
-   ctlr->control = offsetof(struct ich7_spi_regs, spic);
-   ctlr->bbar = offsetof(struct ich7_spi_regs, bbar);
-   ctlr->preop = offsetof(struct ich7_spi_regs, preop);
-   ctlr->base = ich7_spi;
-   } else if (plat->ich_version == ICHV_9) {
-   struct ich9_spi_regs *ich9_spi = sbase;
-
-   ctlr->opmenu = offsetof(struct ich9_spi_regs, opmenu);
-   ctlr->menubytes = sizeof(ich9_spi->opmenu);
-   ctlr->optype = offsetof(struct ich9_spi_regs, optype);
-   ctlr->addr = offsetof(struct ich9_spi_regs, faddr);
-   ctlr->data = offsetof(struct ich9_spi_regs, fdata);
-   ctlr->databytes = sizeof(ich9_spi->fdata);
-   ctlr->status = offsetof(struct ich9_spi_regs, ssfs);
-   ctlr->control = offsetof(struct ich9_spi_regs, ssfc);
-   ctlr->speed = ctlr->control + 2;
-   ctlr->bbar = offsetof(struct ich9_spi_regs, bbar);
-   ctlr->preop = offsetof(struct ich9_spi_regs, preop);
-   ctlr->bcr = offsetof(struct ich9_spi_regs, bcr);
-   ctlr->pr = _spi->pr[0];
-   ctlr->base = ich9_spi;
-   } else {
-   debug("ICH SPI: Unrecognised ICH version %d\n",
- plat->ich_version);
-   return -EINVAL;
-   }
-
-   /* Work out the maximum speed we can support */
-   ctlr->max_speed = 2000;
-   if (plat->ich_version == ICHV_9 && ich9_can_do_33mhz(dev))
-   ctlr->max_speed = 3300;
-   debug("ICH SPI: Version ID %d detected at %p, speed %ld\n",
- plat->ich_version, ctlr->base, ctlr->max_speed);
-
-   ich_set_bbar(ctlr, 0);
-
-   return 0;
-}
-
 static void spi_lock_down(struct ich_spi_platdata *plat, void *sbase)
 {
if (plat->ich_version == ICHV_7) {
@@ -493,6 +432,67 @@ static int ich_spi_adjust_size(struct spi_slave *slave, 
struct spi_mem_op *op)
return 0;
 }
 
+static int ich_init_controller(struct udevice *dev,
+  struct ich_spi_platdata *plat,
+  struct ich_spi_priv *ctlr)
+{
+   ulong sbase_addr;
+   void *sbase;
+
+   /* SBASE is similar */
+   pch_get_spi_base(dev->parent, _addr);
+   sbase = (void *)sbase_addr;
+   debug("%s: sbase=%p\n", __func__, sbase);
+
+   if (plat->ich_version == ICHV_7) {
+   struct ich7_spi_regs *ich7_spi = sbase;
+
+   ctlr->opmenu = offsetof(struct ich7_spi_regs, opmenu);
+   ctlr->menubytes = sizeof(ich7_spi->opmenu);
+   ctlr->optype = offsetof(struct ich7_spi_regs, optype);
+   ctlr->addr = offsetof(struct ich7_spi_regs, spia);
+   ctlr->data = offsetof(struct ich7_spi_regs, spid);
+   ctlr->databytes = sizeof(ich7_spi->spid);
+   ctlr->status = offsetof(struct ich7_spi_regs, spis);
+   ctlr->control = offsetof(struct ich7_spi_regs, spic);
+   ctlr->bbar = offsetof(struct ich7_spi_regs, bbar);
+   ctlr->preop = offsetof(struct ich7_spi_regs, preop);
+   ctlr->base = ich7_spi;
+   } else if (plat->ich_version == ICHV_9) {
+   struct ich9_spi_regs *ich9_spi = sbase;
+
+   ctlr->opmenu = offsetof(struct 

[PATCH v6 062/102] spi: Correct operations check in dm_spi_xfer()

2019-12-06 Thread Simon Glass
At present we have to have an xfer() method even if it does nothing. This
is not correct, so fix it.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

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

 drivers/spi/ich.c| 9 +
 drivers/spi/spi-uclass.c | 5 -
 include/spi.h| 2 +-
 3 files changed, 6 insertions(+), 10 deletions(-)

diff --git a/drivers/spi/ich.c b/drivers/spi/ich.c
index fbb58c783e..a4e4ad55c6 100644
--- a/drivers/spi/ich.c
+++ b/drivers/spi/ich.c
@@ -493,13 +493,6 @@ static int ich_spi_adjust_size(struct spi_slave *slave, 
struct spi_mem_op *op)
return 0;
 }
 
-static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen,
-   const void *dout, void *din, unsigned long flags)
-{
-   printf("ICH SPI: Only supports memory operations\n");
-   return -1;
-}
-
 static int ich_spi_probe(struct udevice *dev)
 {
struct ich_spi_platdata *plat = dev_get_platdata(dev);
@@ -612,7 +605,7 @@ static const struct spi_controller_mem_ops 
ich_controller_mem_ops = {
 };
 
 static const struct dm_spi_ops ich_spi_ops = {
-   .xfer   = ich_spi_xfer,
+   /* xfer is not supported */
.set_speed  = ich_spi_set_speed,
.set_mode   = ich_spi_set_mode,
.mem_ops= _controller_mem_ops,
diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c
index 665611f7e2..af910e9efc 100644
--- a/drivers/spi/spi-uclass.c
+++ b/drivers/spi/spi-uclass.c
@@ -85,11 +85,14 @@ int dm_spi_xfer(struct udevice *dev, unsigned int bitlen,
const void *dout, void *din, unsigned long flags)
 {
struct udevice *bus = dev->parent;
+   struct dm_spi_ops *ops = spi_get_ops(bus);
 
if (bus->uclass->uc_drv->id != UCLASS_SPI)
return -EOPNOTSUPP;
+   if (!ops->xfer)
+   return -ENOSYS;
 
-   return spi_get_ops(bus)->xfer(dev, bitlen, dout, din, flags);
+   return ops->xfer(dev, bitlen, dout, din, flags);
 }
 
 int dm_spi_get_mmap(struct udevice *dev, ulong *map_basep, uint *map_sizep,
diff --git a/include/spi.h b/include/spi.h
index 6fbb4336ce..ba2c8406b2 100644
--- a/include/spi.h
+++ b/include/spi.h
@@ -224,7 +224,7 @@ void spi_release_bus(struct spi_slave *slave);
 int spi_set_wordlen(struct spi_slave *slave, unsigned int wordlen);
 
 /**
- * SPI transfer
+ * SPI transfer (optional if mem_ops is used)
  *
  * This writes "bitlen" bits out the SPI MOSI port and simultaneously clocks
  * "bitlen" bits in the SPI MISO port.  That's just the way SPI works.
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 059/102] x86: Don't repeat microcode in U-Boot if not needed

2019-12-06 Thread Simon Glass
At present if SPL sets up the microcode then it is still included in
U-Boot as well. This is wasteful as microcode is large. Adjust the logic
in the image to prevent this.

Reviewed-by: Bin Meng 
Signed-off-by: Simon Glass 
---

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

 arch/x86/dts/u-boot.dtsi | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/arch/x86/dts/u-boot.dtsi b/arch/x86/dts/u-boot.dtsi
index 5ebff4f407..e0cca58640 100644
--- a/arch/x86/dts/u-boot.dtsi
+++ b/arch/x86/dts/u-boot.dtsi
@@ -63,9 +63,16 @@
offset = ;
};
 #else
+# ifdef CONFIG_SPL
+   u-boot {
+   offset = ;
+   };
+# else
+   /* If there is no SPL then we need to put microcode in U-Boot */
u-boot-with-ucode-ptr {
offset = ;
};
+# endif
 #endif
 #ifdef CONFIG_HAVE_MICROCODE
u-boot-dtb-with-ucode {
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 056/102] x86: Add an option to control the position of U-Boot

2019-12-06 Thread Simon Glass
The existing work-around for positioning U-Boot in the ROM when it
actually runs from RAM still exists and there is not obvious way to change
this.

Add a proper Kconfig option to handle this case. This also adds a new bool
property to indicate whether CONFIG_SYS_TEXT_BASE exists.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

Changes in v6: None
Changes in v5: None
Changes in v4:
- Rename option to HAVE_SYS_TEXT_BASE

Changes in v3: None
Changes in v2: None

 Kconfig|  9 ++---
 arch/x86/Kconfig   |  5 +
 arch/x86/dts/u-boot.dtsi   | 18 +++---
 configs/chromebook_samus_tpl_defconfig |  1 +
 configs/qemu-x86_64_defconfig  |  1 +
 5 files changed, 16 insertions(+), 18 deletions(-)

diff --git a/Kconfig b/Kconfig
index 92fc4fc135..46a31f45b9 100644
--- a/Kconfig
+++ b/Kconfig
@@ -545,9 +545,14 @@ config SYS_EXTRA_OPTIONS
  configuration to Kconfig. Since this option will be removed sometime,
  new boards should not use this option.
 
-config SYS_TEXT_BASE
+config HAVE_SYS_TEXT_BASE
+   bool
depends on !NIOS2 && !XTENSA
depends on !EFI_APP
+   default y
+
+config SYS_TEXT_BASE
+   depends on HAVE_SYS_TEXT_BASE
default 0x8080 if ARCH_OMAP2PLUS || ARCH_K3
default 0x4a00 if ARCH_SUNXI && !MACH_SUN9I && !MACH_SUN8I_V3S
default 0x2a00 if ARCH_SUNXI && MACH_SUN9I
@@ -556,8 +561,6 @@ config SYS_TEXT_BASE
help
  The address in memory that U-Boot will be running from, initially.
 
-
-
 config SYS_CLK_FREQ
depends on ARC || ARCH_SUNXI || MPC83xx
int "CPU clock frequency"
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 64f167306b..9d7ff3c07a 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -899,4 +899,9 @@ config CACHE_QOS_SIZE_PER_BIT
depends on INTEL_CAR_CQOS
default 0x2 # 128 KB
 
+config X86_OFFSET_U_BOOT
+   hex "Offset of U-Boot in ROM image"
+   depends on HAVE_SYS_TEXT_BASE
+   default SYS_TEXT_BASE
+
 endmenu
diff --git a/arch/x86/dts/u-boot.dtsi b/arch/x86/dts/u-boot.dtsi
index 14e3c13072..d84c64880a 100644
--- a/arch/x86/dts/u-boot.dtsi
+++ b/arch/x86/dts/u-boot.dtsi
@@ -50,7 +50,7 @@
u-boot-spl-dtb {
};
u-boot {
-   offset = ;
+   offset = ;
};
 #elif defined(CONFIG_SPL)
u-boot-spl-with-ucode-ptr {
@@ -60,23 +60,11 @@
type = "u-boot-dtb-with-ucode";
};
u-boot {
-   /*
-* TODO(s...@chromium.org):
-* Normally we use CONFIG_SYS_TEXT_BASE as the flash offset. But
-* for boards with textbase in SDRAM we cannot do this. Just use
-* an assumed-valid value (1MB before the end of flash) here so
-* that we can actually build an image for coreboot, etc.
-* We need a better solution, perhaps a separate Kconfig.
-*/
-#if CONFIG_SYS_TEXT_BASE == 0x111
-   offset = <0xfff0>;
-#else
-   offset = ;
-#endif
+   offset = ;
};
 #else
u-boot-with-ucode-ptr {
-   offset = ;
+   offset = ;
};
 #endif
 #ifdef CONFIG_HAVE_MICROCODE
diff --git a/configs/chromebook_samus_tpl_defconfig 
b/configs/chromebook_samus_tpl_defconfig
index 5ef2ecb1c4..74b7e9a207 100644
--- a/configs/chromebook_samus_tpl_defconfig
+++ b/configs/chromebook_samus_tpl_defconfig
@@ -16,6 +16,7 @@ CONFIG_HAVE_REFCODE=y
 CONFIG_SMP=y
 CONFIG_HAVE_VGA_BIOS=y
 CONFIG_SPL_TEXT_BASE=0xffe7
+CONFIG_X86_OFFSET_U_BOOT=0xfff0
 CONFIG_BOOTSTAGE=y
 CONFIG_BOOTSTAGE_REPORT=y
 CONFIG_SHOW_BOOT_PROGRESS=y
diff --git a/configs/qemu-x86_64_defconfig b/configs/qemu-x86_64_defconfig
index b88a4c57fe..a37ec4d0d6 100644
--- a/configs/qemu-x86_64_defconfig
+++ b/configs/qemu-x86_64_defconfig
@@ -13,6 +13,7 @@ CONFIG_SMP=y
 CONFIG_GENERATE_PIRQ_TABLE=y
 CONFIG_GENERATE_MP_TABLE=y
 CONFIG_GENERATE_ACPI_TABLE=y
+CONFIG_X86_OFFSET_U_BOOT=0xfff0
 CONFIG_SPL_TEXT_BASE=0xfffd
 CONFIG_DISTRO_DEFAULTS=y
 CONFIG_BUILD_ROM=y
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 054/102] x86: Update the fsp command for FSP2

2019-12-06 Thread Simon Glass
The current 'fsp' command only works with FSP1. Update it to handle FSP2
as well. Convert everything to hex which is what U-Boot uses.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

Changes in v6: None
Changes in v5: None
Changes in v4:
- Explain why FSP-M cannot be shown
- Use hex for size values also

Changes in v3:
- Convert code to use hex increased of decimal
- Update the 'fsp' command for FSP2, instead of disabling it

Changes in v2: None

 cmd/x86/fsp.c | 65 ++-
 1 file changed, 44 insertions(+), 21 deletions(-)

diff --git a/cmd/x86/fsp.c b/cmd/x86/fsp.c
index b3b663021b..6e485fb144 100644
--- a/cmd/x86/fsp.c
+++ b/cmd/x86/fsp.c
@@ -5,23 +5,38 @@
 
 #include 
 #include 
-#include 
+#include 
 
 DECLARE_GLOBAL_DATA_PTR;
 
 static int do_hdr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-   struct fsp_header *hdr = fsp_find_header();
-   u32 img_addr = hdr->img_base;
-   char *sign = (char *)>sign;
+   struct fsp_header *hdr;
+   u32 img_addr;
+   char *sign;
+   uint addr;
int i;
 
-   printf("FSP: binary 0x%08x, header 0x%08x\n",
-  CONFIG_FSP_ADDR, (int)hdr);
+#ifdef CONFIG_FSP_VERSION2
+   /*
+* Only FSP-S is displayed. FSP-M was used in SPL but may not still be
+* around, and we didn't keep a pointer to it.
+*/
+   hdr = gd->arch.fsp_s_hdr;
+   img_addr = hdr->img_base;
+   addr = img_addr;
+#else
+   addr = CONFIG_FSP_ADDR;
+   hdr = fsp_find_header();
+   img_addr = hdr->img_base;
+#endif
+   sign = (char *)>sign;
+
+   printf("FSP: binary %08x, header %08x\n", addr, (int)hdr);
printf("Header : sign ");
for (i = 0; i < sizeof(hdr->sign); i++)
printf("%c", *sign++);
-   printf(", size %d, rev %d\n", hdr->hdr_len, hdr->hdr_rev);
+   printf(", size %x, rev %d\n", hdr->hdr_len, hdr->hdr_rev);
printf("Image  : rev ");
if (hdr->hdr_rev == FSP_HEADER_REVISION_1) {
printf("%d.%d",
@@ -34,24 +49,32 @@ static int do_hdr(cmd_tbl_t *cmdtp, int flag, int argc, 
char * const argv[])
printf(", id ");
for (i = 0; i < ARRAY_SIZE(hdr->img_id); i++)
printf("%c", hdr->img_id[i]);
-   printf(", addr 0x%08x, size %d\n", img_addr, hdr->img_size);
-   if (hdr->hdr_rev == FSP_HEADER_REVISION_2) {
+   printf(", addr %08x, size %x\n", img_addr, hdr->img_size);
+   if (hdr->hdr_rev >= FSP_HEADER_REVISION_1) {
printf("GFX:%ssupported\n",
   hdr->img_attr & FSP_ATTR_GRAPHICS_SUPPORT ? " " : " un");
}
-   printf("VPD: addr 0x%08x, size %d\n",
+   printf("VPD: addr %08x, size %x\n",
   hdr->cfg_region_off + img_addr, hdr->cfg_region_size);
-   printf("\nNumber of APIs Supported : %d\n", hdr->api_num);
-   printf("\tTempRamInit : 0x%08x\n", hdr->fsp_tempram_init + img_addr);
-   printf("\tFspInit : 0x%08x\n", hdr->fsp_init + img_addr);
-   printf("\tFspNotify   : 0x%08x\n", hdr->fsp_notify + img_addr);
-   if (hdr->hdr_rev == FSP_HEADER_REVISION_2) {
-   printf("\tMemoryInit  : 0x%08x\n",
-  hdr->fsp_mem_init + img_addr);
-   printf("\tTempRamExit : 0x%08x\n",
-  hdr->fsp_tempram_exit + img_addr);
-   printf("\tSiliconInit : 0x%08x\n",
-  hdr->fsp_silicon_init + img_addr);
+   if (hdr->hdr_rev <= FSP_HEADER_REVISION_2)
+   printf("\nNumber of APIs Supported : %d\n", hdr->api_num);
+   if (hdr->fsp_tempram_init)
+   printf("\tTempRamInit : %08x\n",
+  hdr->fsp_tempram_init + img_addr);
+   if (hdr->fsp_init)
+   printf("\tFspInit : %08x\n", hdr->fsp_init + img_addr);
+   if (hdr->fsp_notify)
+   printf("\tFspNotify   : %08x\n", hdr->fsp_notify + img_addr);
+   if (hdr->hdr_rev >= FSP_HEADER_REVISION_1) {
+   if (hdr->fsp_mem_init)
+   printf("\tMemoryInit  : %08x\n",
+  hdr->fsp_mem_init + img_addr);
+   if (hdr->fsp_tempram_exit)
+   printf("\tTempRamExit : %08x\n",
+  hdr->fsp_tempram_exit + img_addr);
+   if (hdr->fsp_silicon_init)
+   printf("\tSiliconInit : %08x\n",
+  hdr->fsp_silicon_init + img_addr);
}
 
return 0;
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 057/102] x86: Add an option to control the position of SPL

2019-12-06 Thread Simon Glass
For Apollo Lake SPL is run from CAR (cache-as-RAM) which is in a different
location from where SPL must be placed in ROM. In other words, although
SPL runs before SDRAM is set up, it is not execute-in-place (XIP).

Add a Kconfig option for the ROM position.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

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

Changes in v3:
- Add SPL condition to the option

Changes in v2: None

 arch/x86/Kconfig | 5 +
 arch/x86/dts/u-boot.dtsi | 4 ++--
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 9d7ff3c07a..1d08cb24fb 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -904,4 +904,9 @@ config X86_OFFSET_U_BOOT
depends on HAVE_SYS_TEXT_BASE
default SYS_TEXT_BASE
 
+config X86_OFFSET_SPL
+   hex "Offset of SPL in ROM image"
+   depends on SPL && X86
+   default SPL_TEXT_BASE
+
 endmenu
diff --git a/arch/x86/dts/u-boot.dtsi b/arch/x86/dts/u-boot.dtsi
index d84c64880a..fad3e7c951 100644
--- a/arch/x86/dts/u-boot.dtsi
+++ b/arch/x86/dts/u-boot.dtsi
@@ -45,7 +45,7 @@
};
 #endif
u-boot-spl {
-   offset = ;
+   offset = ;
};
u-boot-spl-dtb {
};
@@ -54,7 +54,7 @@
};
 #elif defined(CONFIG_SPL)
u-boot-spl-with-ucode-ptr {
-   offset = ;
+   offset = ;
};
u-boot-dtb-with-ucode2 {
type = "u-boot-dtb-with-ucode";
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 058/102] x86: Add an fdtmap and image-header

2019-12-06 Thread Simon Glass
Add these entries to the ROM so that we can list the contents of an image
with 'binman ls'. The image-header is not essential but does speed up
access.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

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

 arch/x86/dts/u-boot.dtsi | 5 +
 1 file changed, 5 insertions(+)

diff --git a/arch/x86/dts/u-boot.dtsi b/arch/x86/dts/u-boot.dtsi
index fad3e7c951..5ebff4f407 100644
--- a/arch/x86/dts/u-boot.dtsi
+++ b/arch/x86/dts/u-boot.dtsi
@@ -124,6 +124,8 @@
filename = CONFIG_FSP_FILE_S;
};
 #endif
+   fdtmap {
+   };
 #ifdef CONFIG_HAVE_CMC
intel-cmc {
filename = CONFIG_CMC_FILE;
@@ -169,5 +171,8 @@
offset = ;
};
 #endif
+   image-header {
+   location = "end";
+   };
 };
 #endif
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 055/102] x86: Update .dtsi file for FSP2

2019-12-06 Thread Simon Glass
Include the IFWI section and the FSP-M binary. The FSP-T binary is not
currently used, as CAR is set up manually.

Also drop the FSP binary as this relates only to FSP1.

Reviewed-by: Bin Meng 
Signed-off-by: Simon Glass 
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3:
- Add FSP-S and VBT also
- Drop VBT as we already have it elsewhere

Changes in v2: None

 arch/x86/dts/u-boot.dtsi | 32 +++-
 1 file changed, 31 insertions(+), 1 deletion(-)

diff --git a/arch/x86/dts/u-boot.dtsi b/arch/x86/dts/u-boot.dtsi
index 850fe3ac11..14e3c13072 100644
--- a/arch/x86/dts/u-boot.dtsi
+++ b/arch/x86/dts/u-boot.dtsi
@@ -100,12 +100,42 @@
offset = ;
};
 #endif
-#ifdef CONFIG_HAVE_FSP
+#ifdef CONFIG_FSP_VERSION1
intel-fsp {
filename = CONFIG_FSP_FILE;
offset = ;
};
 #endif
+#ifdef CONFIG_FSP_VERSION2
+   intel-descriptor {
+   filename = CONFIG_FLASH_DESCRIPTOR_FILE;
+   };
+   intel-ifwi {
+   filename = CONFIG_IFWI_INPUT_FILE;
+   convert-fit;
+
+   section {
+   size = <0x8000>;
+   ifwi-replace;
+   ifwi-subpart = "IBBP";
+   ifwi-entry = "IBBL";
+   u-boot-tpl {
+   };
+   x86-start16-tpl {
+   offset = <0x7800>;
+   };
+   x86-reset16-tpl {
+   offset = <0x7ff0>;
+   };
+   };
+   };
+   intel-fsp-m {
+   filename = CONFIG_FSP_FILE_M;
+   };
+   intel-fsp-s {
+   filename = CONFIG_FSP_FILE_S;
+   };
+#endif
 #ifdef CONFIG_HAVE_CMC
intel-cmc {
filename = CONFIG_CMC_FILE;
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 052/102] x86: Add support for newer CAR schemes

2019-12-06 Thread Simon Glass
Newer Intel SoCs have different ways of setting up cache-as-ram (CAR).
Add support for these along with suitable configuration options.

To make the code cleaner, adjust a few definitions in processor.h so that
they can be used from assembler.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

Changes in v6: None
Changes in v5: None
Changes in v4:
- Adjust
- Fix up license header
- Fix various code-style problems
- Use CONFIG_INTEL_CAR_CQOS to control car2.S inclusion
- Use car_init_ret to return
- Use post_code() calls consistent with car.S

Changes in v3:
- Drop dead code
- Drop unneeded Kconfig file
- Use a macro for is-power-of-two

Changes in v2: None

 arch/x86/Kconfig|  16 +
 arch/x86/cpu/intel_common/Makefile  |   8 +
 arch/x86/cpu/intel_common/car2.S| 448 
 arch/x86/cpu/intel_common/car2_uninit.S |  87 +
 arch/x86/include/asm/processor.h|  12 +-
 5 files changed, 564 insertions(+), 7 deletions(-)
 create mode 100644 arch/x86/cpu/intel_common/car2.S
 create mode 100644 arch/x86/cpu/intel_common/car2_uninit.S

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index bcce1114ce..44f7f0ab03 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -879,4 +879,20 @@ config HIGH_TABLE_SIZE
  Increse it if the default size does not fit the board's needs.
  This is most likely due to a large ACPI DSDT table is used.
 
+config INTEL_CAR_CQOS
+   bool "Support Intel Cache Quality of Service"
+   help
+ Cache Quality of Service allows more fine-grained control of cache
+ usage. As result, it is possible to set up a portion of L2 cache for
+ CAR and use the remainder for actual caching.
+
+#
+# Each bit in QOS mask controls this many bytes. This is calculated as:
+# (CACHE_WAYS / CACHE_BITS_PER_MASK) * CACHE_LINE_SIZE * CACHE_SETS
+#
+config CACHE_QOS_SIZE_PER_BIT
+   hex
+   depends on INTEL_CAR_CQOS
+   default 0x2 # 128 KB
+
 endmenu
diff --git a/arch/x86/cpu/intel_common/Makefile 
b/arch/x86/cpu/intel_common/Makefile
index dfbc29f047..09212cee04 100644
--- a/arch/x86/cpu/intel_common/Makefile
+++ b/arch/x86/cpu/intel_common/Makefile
@@ -8,6 +8,14 @@ obj-$(CONFIG_$(SPL_TPL_)X86_32BIT_INIT) += me_status.o
 obj-$(CONFIG_$(SPL_TPL_)X86_32BIT_INIT) += report_platform.o
 obj-$(CONFIG_$(SPL_TPL_)X86_32BIT_INIT) += mrc.o
 endif
+
+ifdef CONFIG_INTEL_CAR_CQOS
+obj-$(CONFIG_TPL_BUILD) += car2.o
+ifndef CONFIG_SPL_BUILD
+obj-y += car2_uninit.o
+endif
+endif
+
 obj-y += cpu.o
 obj-y += fast_spi.o
 obj-y += lpc.o
diff --git a/arch/x86/cpu/intel_common/car2.S b/arch/x86/cpu/intel_common/car2.S
new file mode 100644
index 00..086f987477
--- /dev/null
+++ b/arch/x86/cpu/intel_common/car2.S
@@ -0,0 +1,448 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * This file was modified from the coreboot version.
+ *
+ * Copyright (C) 2015-2016 Intel Corp.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define KiB 1024
+
+#define IS_POWER_OF_2(x)   (!((x) & ((x) - 1)))
+
+.global car_init
+car_init:
+   post_code(POST_CAR_START)
+
+   /*
+* Use the MTRR default type MSR as a proxy for detecting INIT#.
+* Reset the system if any known bits are set in that MSR. That is
+* an indication of the CPU not being properly reset.
+*/
+check_for_clean_reset:
+   mov $MTRR_DEF_TYPE_MSR, %ecx
+   rdmsr
+   and $(MTRR_DEF_TYPE_EN | MTRR_DEF_TYPE_FIX_EN), %eax
+   cmp $0, %eax
+   jz  no_reset
+   /* perform warm reset */
+   movw$IO_PORT_RESET, %dx
+   movb$(SYS_RST | RST_CPU), %al
+   outb%al, %dx
+
+no_reset:
+   post_code(POST_CAR_SIPI)
+
+   /* Clear/disable fixed MTRRs */
+   mov $fixed_mtrr_list_size, %ebx
+   xor %eax, %eax
+   xor %edx, %edx
+
+clear_fixed_mtrr:
+   add $-2, %ebx
+   movzwl  fixed_mtrr_list(%ebx), %ecx
+   wrmsr
+   jnz clear_fixed_mtrr
+
+   post_code(POST_CAR_MTRR)
+
+   /* Figure put how many MTRRs we have, and clear them out */
+   mov $MTRR_CAP_MSR, %ecx
+   rdmsr
+   movzb   %al, %ebx   /* Number of variable MTRRs */
+   mov $MTRR_PHYS_BASE_MSR(0), %ecx
+   xor %eax, %eax
+   xor %edx, %edx
+
+clear_var_mtrr:
+   wrmsr
+   inc %ecx
+   wrmsr
+   inc %ecx
+   dec %ebx
+   jnz clear_var_mtrr
+
+   post_code(POST_CAR_UNCACHEABLE)
+
+   /* Configure default memory type to uncacheable (UC) */
+   mov $MTRR_DEF_TYPE_MSR, %ecx
+   rdmsr
+   /* Clear enable bits and set default type to UC */
+   and $~(MTRR_DEF_TYPE_MASK | MTRR_DEF_TYPE_EN | \
+MTRR_DEF_TYPE_FIX_EN), %eax
+   wrmsr
+
+   /*
+* Configure MTRR_PHYS_MASK_HIGH for proper addressing above 4GB
+* based on the physical address size supported for this processor

[PATCH v6 053/102] x86: Disable microcode section for FSP2

2019-12-06 Thread Simon Glass
At present we don't support loading microcode with FSP2. The correct way
to do this is by adding it to the FIT. For now, disable including
microcode in the image.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3:
- Drop unnecessary #else part of CONFIG_HAVE_MICROCODE

Changes in v2: None

 arch/x86/Kconfig | 4 
 arch/x86/dts/u-boot.dtsi | 7 +++
 2 files changed, 11 insertions(+)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 44f7f0ab03..64f167306b 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -588,6 +588,10 @@ config HAVE_REFCODE
   broadwell) U-Boot will be missing some critical setup steps.
   Various peripherals may fail to work.
 
+config HAVE_MICROCODE
+   bool
+   default y if !FSP_VERSION2
+
 config SMP
bool "Enable Symmetric Multiprocessing"
default n
diff --git a/arch/x86/dts/u-boot.dtsi b/arch/x86/dts/u-boot.dtsi
index 33441c7c80..850fe3ac11 100644
--- a/arch/x86/dts/u-boot.dtsi
+++ b/arch/x86/dts/u-boot.dtsi
@@ -37,11 +37,13 @@
};
 #endif
 #ifdef CONFIG_TPL
+#ifdef CONFIG_HAVE_MICROCODE
u-boot-tpl-with-ucode-ptr {
offset = ;
};
u-boot-tpl-dtb {
};
+#endif
u-boot-spl {
offset = ;
};
@@ -77,11 +79,16 @@
offset = ;
};
 #endif
+#ifdef CONFIG_HAVE_MICROCODE
u-boot-dtb-with-ucode {
};
u-boot-ucode {
align = <16>;
};
+#else
+   u-boot-dtb {
+   };
+#endif
 #ifdef CONFIG_HAVE_X86_FIT
intel-fit {
};
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 049/102] x86: fsp: Make the notify API call common

2019-12-06 Thread Simon Glass
The fsp_notify() API is the same for FSP1 and FSP2. Move it into a new
common API file.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

Changes in v6: None
Changes in v5: None
Changes in v4:
- Drop incorrect coreboot reference from header file

Changes in v3: None
Changes in v2: None

 arch/x86/include/asm/fsp/fsp_api.h  | 24 
 arch/x86/include/asm/fsp1/fsp_api.h | 21 +++--
 2 files changed, 27 insertions(+), 18 deletions(-)
 create mode 100644 arch/x86/include/asm/fsp/fsp_api.h

diff --git a/arch/x86/include/asm/fsp/fsp_api.h 
b/arch/x86/include/asm/fsp/fsp_api.h
new file mode 100644
index 00..e9ac86b2da
--- /dev/null
+++ b/arch/x86/include/asm/fsp/fsp_api.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2019 Google LLC
+ */
+
+#ifndef __ASM_FSP_API_H
+#define __ASM_FSP_API_H
+
+enum fsp_phase {
+   /* Notification code for post PCI enuermation */
+   INIT_PHASE_PCI  = 0x20,
+   /* Notification code before transferring control to the payload */
+   INIT_PHASE_BOOT = 0x40
+};
+
+struct fsp_notify_params {
+   /* Notification phase used for NotifyPhase API */
+   enum fsp_phase  phase;
+};
+
+/* FspNotify API function prototype */
+typedef asmlinkage u32 (*fsp_notify_f)(struct fsp_notify_params *params);
+
+#endif
diff --git a/arch/x86/include/asm/fsp1/fsp_api.h 
b/arch/x86/include/asm/fsp1/fsp_api.h
index f2d70799f3..524da5feb7 100644
--- a/arch/x86/include/asm/fsp1/fsp_api.h
+++ b/arch/x86/include/asm/fsp1/fsp_api.h
@@ -4,11 +4,11 @@
  * Copyright (C) 2014, Bin Meng 
  */
 
-#ifndef __FSP_API_H__
-#define __FSP_API_H__
+#ifndef __FSP1_API_H__
+#define __FSP1_API_H__
 
 #include 
-
+#include 
 /*
  * FSP common configuration structure.
  * This needs to be included in the platform-specific struct fsp_config_data.
@@ -46,22 +46,7 @@ struct common_buf {
u32 reserved[6];/* Reserved */
 };
 
-enum fsp_phase {
-   /* Notification code for post PCI enuermation */
-   INIT_PHASE_PCI  = 0x20,
-   /* Notification code before transfering control to the payload */
-   INIT_PHASE_BOOT = 0x40
-};
-
-struct fsp_notify_params {
-   /* Notification phase used for NotifyPhase API */
-   enum fsp_phase  phase;
-};
-
 /* FspInit API function prototype */
 typedef asmlinkage u32 (*fsp_init_f)(struct fsp_init_params *params);
 
-/* FspNotify API function prototype */
-typedef asmlinkage u32 (*fsp_notify_f)(struct fsp_notify_params *params);
-
 #endif
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 051/102] x86: Add an option to include a FIT

2019-12-06 Thread Simon Glass
Many Intel SoCs require a FIT in order to boot properly. Add an option to
include this and enable it by default.

This term can be confused with FIT (Flat Image Tree) in U-Boot so the
CONFIG option has to include 'X86'.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3:
- Add help to CONFIG_FIT and don't make it 'default y'
- Rename X86_HAS_FIT to HAVE_X86_FIT
- Update commit message to explain why HAVE_FIT woudl be confusing

Changes in v2: None

 arch/x86/Kconfig | 8 
 arch/x86/dts/u-boot.dtsi | 6 ++
 2 files changed, 14 insertions(+)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index e2e0f20f21..bcce1114ce 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -217,6 +217,14 @@ config SYS_X86_START16
depends on X86_RESET_VECTOR
default 0xf800
 
+config HAVE_X86_FIT
+   bool
+   help
+ Enable inclusion of an Intel Firmware Interface Table (FIT) into the
+ image. This table is supposed to point to microcode and the like. So
+ far it is just a fixed table with the minimum set of headers, so that
+ it is actually present.
+
 config X86_LOAD_FROM_32_BIT
bool "Boot from a 32-bit program"
help
diff --git a/arch/x86/dts/u-boot.dtsi b/arch/x86/dts/u-boot.dtsi
index 0e87b88e10..33441c7c80 100644
--- a/arch/x86/dts/u-boot.dtsi
+++ b/arch/x86/dts/u-boot.dtsi
@@ -82,6 +82,12 @@
u-boot-ucode {
align = <16>;
};
+#ifdef CONFIG_HAVE_X86_FIT
+   intel-fit {
+   };
+   intel-fit-ptr {
+   };
+#endif
 #ifdef CONFIG_HAVE_MRC
intel-mrc {
offset = ;
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 050/102] x86: Don't include the BIOS emulator in TPL

2019-12-06 Thread Simon Glass
We don't generally have enough space to run this, so don't build it into
TPL. This helps reduce the size of TPL.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

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

 arch/x86/lib/Makefile | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index ca0ca1066b..5cd4587480 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -4,9 +4,11 @@
 # Wolfgang Denk, DENX Software Engineering, w...@denx.de.
 
 ifndef CONFIG_X86_64
+ifndef CONFIG_TPL_BUILD
 obj-y += bios.o
 obj-y += bios_asm.o
 obj-y += bios_interrupts.o
+endif
 obj-y += string.o
 endif
 ifndef CONFIG_SPL_BUILD
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 047/102] x86: fsp: Add a new arch_fsp_init_r() hook

2019-12-06 Thread Simon Glass
With FSP2 we need to run silicon init early after relocation. Add a new
hook for this.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

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

 common/board_r.c |  3 +++
 include/init.h   | 11 +++
 2 files changed, 14 insertions(+)

diff --git a/common/board_r.c b/common/board_r.c
index 9a25f6ec28..e711de64b5 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -715,6 +715,9 @@ static init_fnc_t init_sequence_r[] = {
efi_memory_init,
 #endif
initr_binman,
+#ifdef CONFIG_FSP_VERSION2
+   arch_fsp_init_r,
+#endif
initr_dm_devices,
stdio_init_tables,
initr_serial,
diff --git a/include/init.h b/include/init.h
index 8b65b2afe4..970a39a6a0 100644
--- a/include/init.h
+++ b/include/init.h
@@ -67,6 +67,17 @@ int mach_cpu_init(void);
  */
 int arch_fsp_init(void);
 
+/**
+ * arch_fsp_init() - perform post-relocation firmware support package init
+ *
+ * Where U-Boot relies on binary blobs to handle part of the system init, this
+ * function can be used to set up the blobs. This is used on some Intel
+ * platforms.
+ *
+ * Return: 0
+ */
+int arch_fsp_init_r(void);
+
 int dram_init(void);
 
 /**
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 046/102] x86: fsp: Set up an MTRR for the graphics frame buffer

2019-12-06 Thread Simon Glass
The FSP-S may do this but at least for coral it does not. Set this up so
that graphics is not deathly slow.

It isn't clear whether the FSP is expected to set up MTRR. It is not
mentioned in the APL FSP document.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

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

 arch/x86/lib/fsp/fsp_graphics.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/arch/x86/lib/fsp/fsp_graphics.c b/arch/x86/lib/fsp/fsp_graphics.c
index 91d2d08557..226c7e66b3 100644
--- a/arch/x86/lib/fsp/fsp_graphics.c
+++ b/arch/x86/lib/fsp/fsp_graphics.c
@@ -8,6 +8,7 @@
 #include 
 #include 
 #include 
+#include 
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -97,6 +98,9 @@ static int fsp_video_probe(struct udevice *dev)
if (ret)
goto err;
 
+   mtrr_add_request(MTRR_TYPE_WRCOMB, vesa->phys_base_ptr, 256 << 20);
+   mtrr_commit(true);
+
printf("%dx%dx%d\n", uc_priv->xsize, uc_priv->ysize,
   vesa->bits_per_pixel);
 
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 045/102] x86: fsp: Add FSP2 base support

2019-12-06 Thread Simon Glass
Add support for some important configuration options and FSP memory init.
The memory init uses swizzle tables from the device tree.

Support for the FSP_S binary is also included.

Bootstage timing is used for both FSP_M and FSP_S and memory-mapped SPI
reads.

Signed-off-by: Simon Glass 
---

Changes in v6:
- Add a lot of comments to get_cbfs_fsp()
- Drop extra conditions on CONFIG_VIDEO_FSP
- Make BOOT_FROM_FAST_SPI_FLASH a Kconfig option
- Remove hyphens from Firmware-Support-Package

Changes in v5:
- Drop SAFETY_MARGIN

Changes in v4:
- Add a LOG_CATEGORY for silicon init
- Drop duplicate VBT file CONFIG
- Enable HAVE_VBT for FSP2 also
- Explain the 'twisty headers' comment
- Fix FSP_M reference to refer to FSP_S in commit message
- Fix comment on fsp_silicon_init()
- Rename arch_fsp_s_preinit() to arch_fsps_preinit()
- Rename get_coreboot_fsp() and add comments
- Switch over to use pinctrl for pad init/config
- Use lower-case pinctrl in arch_cpu_init_dm()

Changes in v3:
- Add a proper implementation of fsp_notify
- Add an fsp: tag
- Add bootstage timing for memory-mapped reads
- Add fsp_locate_fsp to locate an fsp component
- Add fspm_done() hook
- Add support for FSP-S component and VBT
- Simplify types for fsp_locate_fsp()
- Switch mmap to use SPI instead of SPI flash

Changes in v2: None

 arch/x86/Kconfig |  52 +-
 arch/x86/include/asm/fsp2/fsp_api.h  |  63 
 arch/x86/include/asm/fsp2/fsp_internal.h |  97 
 arch/x86/lib/fsp2/Makefile   |  10 ++
 arch/x86/lib/fsp2/fsp_common.c   |  13 ++
 arch/x86/lib/fsp2/fsp_dram.c |  78 +
 arch/x86/lib/fsp2/fsp_init.c | 191 +++
 arch/x86/lib/fsp2/fsp_meminit.c  |  97 
 arch/x86/lib/fsp2/fsp_silicon_init.c |  54 +++
 arch/x86/lib/fsp2/fsp_support.c  | 131 
 include/bootstage.h  |   3 +
 11 files changed, 787 insertions(+), 2 deletions(-)
 create mode 100644 arch/x86/include/asm/fsp2/fsp_api.h
 create mode 100644 arch/x86/include/asm/fsp2/fsp_internal.h
 create mode 100644 arch/x86/lib/fsp2/Makefile
 create mode 100644 arch/x86/lib/fsp2/fsp_common.c
 create mode 100644 arch/x86/lib/fsp2/fsp_dram.c
 create mode 100644 arch/x86/lib/fsp2/fsp_init.c
 create mode 100644 arch/x86/lib/fsp2/fsp_meminit.c
 create mode 100644 arch/x86/lib/fsp2/fsp_silicon_init.c
 create mode 100644 arch/x86/lib/fsp2/fsp_support.c

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 17a6fe6d3d..e2e0f20f21 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -326,7 +326,7 @@ config X86_RAMTEST
 
 config FLASH_DESCRIPTOR_FILE
string "Flash descriptor binary filename"
-   depends on HAVE_INTEL_ME
+   depends on HAVE_INTEL_ME || FSP_VERSION2
default "descriptor.bin"
help
  The filename of the file to use as flash descriptor in the
@@ -411,6 +411,54 @@ config FSP_ADDR
  The default base address of 0xfffc indicates that the binary must
  be located at offset 0xc from the beginning of a 1MB flash device.
 
+if FSP_VERSION2
+
+config FSP_FILE_T
+   string "Firmware Support Package binary filename (Temp RAM)"
+   default "fsp_t.bin"
+   help
+ The filename of the file to use for the temporary-RAM init phase from
+ the Firmware Support Package binary. Put this in the board directory.
+ It is used to set up an initial area of RAM which can be used for the
+ stack and other purposes, while bringing up the main system DRAM.
+
+config FSP_ADDR_T
+   hex "Firmware Support Package binary location (Temp RAM)"
+   default 0x8000
+   help
+ FSP is not Position-Independent Code (PIC) and FSP components have to
+ be rebased if placed at a location which is different from the
+ perferred base address specified during the FSP build. Use Intel's
+ Binary Configuration Tool (BCT) to do the rebase.
+
+config FSP_FILE_M
+   string "Firmware Support Package binary filename (Memory Init)"
+   default "fsp_m.bin"
+   help
+ The filename of the file to use for the RAM init phase from the
+ Firmware Support Package binary. Put this in the board directory.
+ It is used to set up the main system DRAM and runs in SPL, once
+ temporary RAM (CAR) is working.
+
+config FSP_FILE_S
+   string "Firmware Support Package binary filename (Silicon Init)"
+   default "fsp_s.bin"
+   help
+ The filename of the file to use for the Silicon init phase from the
+ Firmware Support Package binary. Put this in the board directory.
+ It is used to set up the silicon to work correctly and must be
+ executed after DRAM is running.
+
+config IFWI_INPUT_FILE
+   string "Filename containing FIT (Firmware Interface Table) with IFWI"
+   default "fitimage.bin"
+   help
+ The IFWI is obtained by 

[PATCH v6 044/102] x86: fsp: Correct wrong header inlude in fsp_support.c

2019-12-06 Thread Simon Glass
This generic FSP file should include the generic FSP support header, not
the FSP1 version. Fix it.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

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

 arch/x86/lib/fsp/fsp_support.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/lib/fsp/fsp_support.c b/arch/x86/lib/fsp/fsp_support.c
index 983888fd74..ee228117d1 100644
--- a/arch/x86/lib/fsp/fsp_support.c
+++ b/arch/x86/lib/fsp/fsp_support.c
@@ -5,7 +5,7 @@
  */
 
 #include 
-#include 
+#include 
 #include 
 
 u32 fsp_get_usable_lowmem_top(const void *hob_list)
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 048/102] x86: fsp: Allow remembering the location of FSP-S

2019-12-06 Thread Simon Glass
FSP-S is used by the notify call after it has been used for silicon init.
To avoid having to load it again, add a field to store the location.

Reviewed-by: Bin Meng 
Signed-off-by: Simon Glass 
---

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

 arch/x86/include/asm/global_data.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/x86/include/asm/global_data.h 
b/arch/x86/include/asm/global_data.h
index 190b604e0f..f4c1839104 100644
--- a/arch/x86/include/asm/global_data.h
+++ b/arch/x86/include/asm/global_data.h
@@ -120,6 +120,9 @@ struct arch_global_data {
int prev_sleep_state;   /* Previous sleep state ACPI_S0/1../5 */
ulong backup_mem;   /* Backup memory address for S3 */
 #endif
+#ifdef CONFIG_FSP_VERSION2
+   struct fsp_header *fsp_s_hdr;   /* Pointer to FSP-S header */
+#endif
 };
 
 #endif
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 041/102] x86: Allow removal of standard PCH drivers

2019-12-06 Thread Simon Glass
These drivers are not needed on all platforms. While they are small, it
is useful in TPL to drop then. Add Kconfig control to allow this.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
- Change 'queensbay' to 'baytrail' in help
- Fix 'proides' typo

 drivers/pch/Kconfig  | 18 ++
 drivers/pch/Makefile |  4 ++--
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/drivers/pch/Kconfig b/drivers/pch/Kconfig
index 18f006de24..c49a92885a 100644
--- a/drivers/pch/Kconfig
+++ b/drivers/pch/Kconfig
@@ -7,3 +7,21 @@ config PCH
  northbridge / southbridge architecture that was previously used. The
  PCH allows for higher performance since the memory functions are
  handled in the CPU.
+
+config X86_PCH7
+   bool "Add support for Intel PCH7"
+   default y if X86
+   help
+ Enable this if your SoC uses Platform Controller Hub 7 (PCH7). This
+ dates from about 2011 and is used on baytrail, for example. The
+ PCH provides access to the GPIO and SPI base addresses, among other
+ functions.
+
+config X86_PCH9
+   bool "Add support for Intel PCH9"
+   default y if X86
+   help
+ Enable this if your SoC uses Platform Controller Hub 9 (PCH9). This
+ dates from about 2015 and is used on baytrail, for example. The
+ PCH provides access to the GPIO and SPI base addresses, among other
+ functions.
diff --git a/drivers/pch/Makefile b/drivers/pch/Makefile
index 8ea6b7852a..d5de3e48be 100644
--- a/drivers/pch/Makefile
+++ b/drivers/pch/Makefile
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0+
 
 obj-y += pch-uclass.o
-obj-y += pch7.o
-obj-y += pch9.o
+obj-$(CONFIG_X86_PCH7) += pch7.o
+obj-$(CONFIG_X86_PCH9) += pch9.o
 obj-$(CONFIG_SANDBOX) += sandbox_pch.o
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 039/102] x86: Set up the MTRR for SDRAM

2019-12-06 Thread Simon Glass
Set up MTRRs for the FSP SDRAM regions to improve performance.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

Changes in v6: None
Changes in v5:
- Fix FST typo

Changes in v4: None
Changes in v3:
- Move mtrr_add_request() call into this patch

Changes in v2: None

 arch/x86/lib/fsp/fsp_dram.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/arch/x86/lib/fsp/fsp_dram.c b/arch/x86/lib/fsp/fsp_dram.c
index 987cb4f8f3..9ce0ddf0d3 100644
--- a/arch/x86/lib/fsp/fsp_dram.c
+++ b/arch/x86/lib/fsp/fsp_dram.c
@@ -9,6 +9,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -61,6 +62,8 @@ int dram_init_banksize(void)
 
gd->bd->bi_dram[bank].start = res_desc->phys_start;
gd->bd->bi_dram[bank].size = res_desc->len;
+   mtrr_add_request(MTRR_TYPE_WRBACK, res_desc->phys_start,
+res_desc->len);
log_debug("ram %llx %llx\n", gd->bd->bi_dram[bank].start,
  gd->bd->bi_dram[bank].size);
}
@@ -69,6 +72,8 @@ int dram_init_banksize(void)
gd->bd->bi_dram[0].start = 0;
gd->bd->bi_dram[0].size = low_end;
 
+   mtrr_add_request(MTRR_TYPE_WRBACK, 0, low_end);
+
return 0;
 }
 
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 042/102] x86: Allow interrupt to happen once

2019-12-06 Thread Simon Glass
At present the interrupt table is included in all phases of U-Boot. Allow
it to be omitted, e.g. in TPL, to reduce size.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3:
- Move write_pirq_routing_table() to avoid 64-bit build error

Changes in v2: None

 arch/x86/cpu/Makefile   |  2 +-
 arch/x86/cpu/irq.c  |  8 
 arch/x86/lib/pirq_routing.c | 10 ++
 3 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile
index 6296b55ff8..b6a010ea32 100644
--- a/arch/x86/cpu/Makefile
+++ b/arch/x86/cpu/Makefile
@@ -53,7 +53,7 @@ obj-$(CONFIG_INTEL_QUARK) += quark/
 obj-$(CONFIG_INTEL_QUEENSBAY) += queensbay/
 obj-$(CONFIG_INTEL_TANGIER) += tangier/
 obj-$(CONFIG_APIC) += lapic.o ioapic.o
-obj-y += irq.o
+obj-$(CONFIG_$(SPL_TPL_)X86_32BIT_INIT) += irq.o
 ifndef CONFIG_$(SPL_)X86_64
 obj-$(CONFIG_SMP) += mp_init.o
 endif
diff --git a/arch/x86/cpu/irq.c b/arch/x86/cpu/irq.c
index cb183496b7..ed9938f7f7 100644
--- a/arch/x86/cpu/irq.c
+++ b/arch/x86/cpu/irq.c
@@ -350,14 +350,6 @@ int irq_router_probe(struct udevice *dev)
return 0;
 }
 
-ulong write_pirq_routing_table(ulong addr)
-{
-   if (!gd->arch.pirq_routing_table)
-   return addr;
-
-   return copy_pirq_routing_table(addr, gd->arch.pirq_routing_table);
-}
-
 static const struct udevice_id irq_router_ids[] = {
{ .compatible = "intel,irq-router" },
{ }
diff --git a/arch/x86/lib/pirq_routing.c b/arch/x86/lib/pirq_routing.c
index e5f0e61424..17bd2fcb9b 100644
--- a/arch/x86/lib/pirq_routing.c
+++ b/arch/x86/lib/pirq_routing.c
@@ -10,6 +10,8 @@
 #include 
 #include 
 
+DECLARE_GLOBAL_DATA_PTR;
+
 static u8 pirq_get_next_free_irq(struct udevice *dev, u8 *pirq, u16 bitmap,
 bool irq_already_routed[])
 {
@@ -131,3 +133,11 @@ u32 copy_pirq_routing_table(u32 addr, struct 
irq_routing_table *rt)
 
return addr + rt->size;
 }
+
+ulong write_pirq_routing_table(ulong addr)
+{
+   if (!gd->arch.pirq_routing_table)
+   return addr;
+
+   return copy_pirq_routing_table(addr, gd->arch.pirq_routing_table);
+}
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 040/102] x86: Don't imply libfdt or SPI flash in TPL

2019-12-06 Thread Simon Glass
We don't want to pull in libfdt if of-platdata is being used, since it
reduces the available code-size saves. Also, SPI flash is seldom needed
in TPL.

Drop these options.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3:
- Don't imply SPI flash either
- Rewrite commit message

Changes in v2: None

 arch/Kconfig | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index 6865e1f909..54de91afb3 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -204,14 +204,11 @@ config X86
imply SPL_SYSCON
# TPL
imply TPL_DM
-   imply TPL_OF_LIBFDT
imply TPL_DRIVERS_MISC_SUPPORT
imply TPL_GPIO_SUPPORT
imply TPL_LIBCOMMON_SUPPORT
imply TPL_LIBGENERIC_SUPPORT
imply TPL_SERIAL_SUPPORT
-   imply TPL_SPI_FLASH_SUPPORT
-   imply TPL_SPI_SUPPORT
imply TPL_OF_CONTROL
imply TPL_TIMER
imply TPL_REGMAP
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 043/102] x86: fsp: Make graphics support common to FSP1/2

2019-12-06 Thread Simon Glass
Both versions of FSP can use the same graphics support, so move it into
the common directory.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

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

 arch/x86/lib/fsp/Makefile | 3 +++
 arch/x86/lib/{fsp1 => fsp}/fsp_graphics.c | 2 +-
 arch/x86/lib/fsp1/Makefile| 1 -
 3 files changed, 4 insertions(+), 2 deletions(-)
 rename arch/x86/lib/{fsp1 => fsp}/fsp_graphics.c (98%)

diff --git a/arch/x86/lib/fsp/Makefile b/arch/x86/lib/fsp/Makefile
index 9e34856473..da6c0a886a 100644
--- a/arch/x86/lib/fsp/Makefile
+++ b/arch/x86/lib/fsp/Makefile
@@ -4,4 +4,7 @@
 
 obj-y += fsp_common.o
 obj-y += fsp_dram.o
+ifndef CONFIG_SPL_BUILD
+obj-$(CONFIG_VIDEO_FSP) += fsp_graphics.o
+endif
 obj-y += fsp_support.o
diff --git a/arch/x86/lib/fsp1/fsp_graphics.c b/arch/x86/lib/fsp/fsp_graphics.c
similarity index 98%
rename from arch/x86/lib/fsp1/fsp_graphics.c
rename to arch/x86/lib/fsp/fsp_graphics.c
index 52e71334f9..91d2d08557 100644
--- a/arch/x86/lib/fsp1/fsp_graphics.c
+++ b/arch/x86/lib/fsp/fsp_graphics.c
@@ -7,7 +7,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 
 DECLARE_GLOBAL_DATA_PTR;
 
diff --git a/arch/x86/lib/fsp1/Makefile b/arch/x86/lib/fsp1/Makefile
index 870de71bd7..1cf5e54191 100644
--- a/arch/x86/lib/fsp1/Makefile
+++ b/arch/x86/lib/fsp1/Makefile
@@ -5,5 +5,4 @@
 obj-y += fsp_car.o
 obj-y += fsp_common.o
 obj-y += fsp_dram.o
-obj-$(CONFIG_VIDEO_FSP) += fsp_graphics.o
 obj-y += fsp_support.o
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 038/102] x86: Set the DRAM banks to reflect real location

2019-12-06 Thread Simon Glass
At present with fsp a single DRAM bank is added which extends to the
whole size of memory. However there is typically only 2GB of memory
available below the 4GB boundary, and this is what is used by U-Boot while
running in 32-bit mode.

Scan the tables to set the banks correct. The first bank is set to memory
below 4GB, and the rest of memory is put into subsequent banks.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3:
- Move mtrr_add_request() call to next patch

Changes in v2: None

 arch/x86/lib/fsp/fsp_dram.c | 30 +-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/arch/x86/lib/fsp/fsp_dram.c b/arch/x86/lib/fsp/fsp_dram.c
index bc456bb4a9..987cb4f8f3 100644
--- a/arch/x86/lib/fsp/fsp_dram.c
+++ b/arch/x86/lib/fsp/fsp_dram.c
@@ -38,8 +38,36 @@ int fsp_scan_for_ram_size(void)
 
 int dram_init_banksize(void)
 {
+   const struct hob_header *hdr;
+   struct hob_res_desc *res_desc;
+   phys_addr_t low_end;
+   uint bank;
+
+   low_end = 0;
+   for (bank = 1, hdr = gd->arch.hob_list;
+bank < CONFIG_NR_DRAM_BANKS && !end_of_hob(hdr);
+hdr = get_next_hob(hdr)) {
+   if (hdr->type != HOB_TYPE_RES_DESC)
+   continue;
+   res_desc = (struct hob_res_desc *)hdr;
+   if (res_desc->type != RES_SYS_MEM &&
+   res_desc->type != RES_MEM_RESERVED)
+   continue;
+   if (res_desc->phys_start < (1ULL << 32)) {
+   low_end = max(low_end,
+ res_desc->phys_start + res_desc->len);
+   continue;
+   }
+
+   gd->bd->bi_dram[bank].start = res_desc->phys_start;
+   gd->bd->bi_dram[bank].size = res_desc->len;
+   log_debug("ram %llx %llx\n", gd->bd->bi_dram[bank].start,
+ gd->bd->bi_dram[bank].size);
+   }
+
+   /* Add the memory below 4GB */
gd->bd->bi_dram[0].start = 0;
-   gd->bd->bi_dram[0].size = gd->ram_size;
+   gd->bd->bi_dram[0].size = low_end;
 
return 0;
 }
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 037/102] x86: Move fsp_prepare_mrc_cache() to fsp1 directory

2019-12-06 Thread Simon Glass
This function needs to be different for FSP2, so move the existing
function into the fsp1 directory. Since it is only called from one file,
drop it from the header file.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

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

 arch/x86/include/asm/fsp/fsp_support.h |  7 ---
 arch/x86/lib/fsp/fsp_common.c  | 20 
 arch/x86/lib/fsp1/fsp_common.c | 20 
 3 files changed, 20 insertions(+), 27 deletions(-)

diff --git a/arch/x86/include/asm/fsp/fsp_support.h 
b/arch/x86/include/asm/fsp/fsp_support.h
index 4ac27d26f5..29e511415c 100644
--- a/arch/x86/include/asm/fsp/fsp_support.h
+++ b/arch/x86/include/asm/fsp/fsp_support.h
@@ -143,13 +143,6 @@ int fsp_init_phase_pci(void);
  */
 int fsp_scan_for_ram_size(void);
 
-/**
- * fsp_prepare_mrc_cache() - Find the DRAM training data from the MRC cache
- *
- * @return pointer to data, or NULL if no cache or no data found in the cache
- */
-void *fsp_prepare_mrc_cache(void);
-
 /**
  * fsp_notify() - FSP notification wrapper function
  *
diff --git a/arch/x86/lib/fsp/fsp_common.c b/arch/x86/lib/fsp/fsp_common.c
index 4c5358e1d2..5eff0f99aa 100644
--- a/arch/x86/lib/fsp/fsp_common.c
+++ b/arch/x86/lib/fsp/fsp_common.c
@@ -58,26 +58,6 @@ void board_final_cleanup(void)
debug("OK\n");
 }
 
-void *fsp_prepare_mrc_cache(void)
-{
-   struct mrc_data_container *cache;
-   struct mrc_region entry;
-   int ret;
-
-   ret = mrccache_get_region(MRC_TYPE_NORMAL, NULL, );
-   if (ret)
-   return NULL;
-
-   cache = mrccache_find_current();
-   if (!cache)
-   return NULL;
-
-   debug("%s: mrc cache at %p, size %x checksum %04x\n", __func__,
- cache->data, cache->data_size, cache->checksum);
-
-   return cache->data;
-}
-
 #ifdef CONFIG_HAVE_ACPI_RESUME
 int fsp_save_s3_stack(void)
 {
diff --git a/arch/x86/lib/fsp1/fsp_common.c b/arch/x86/lib/fsp1/fsp_common.c
index e8066d8de3..ec9c218778 100644
--- a/arch/x86/lib/fsp1/fsp_common.c
+++ b/arch/x86/lib/fsp1/fsp_common.c
@@ -18,6 +18,26 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+static void *fsp_prepare_mrc_cache(void)
+{
+   struct mrc_data_container *cache;
+   struct mrc_region entry;
+   int ret;
+
+   ret = mrccache_get_region(MRC_TYPE_NORMAL, NULL, );
+   if (ret)
+   return NULL;
+
+   cache = mrccache_find_current();
+   if (!cache)
+   return NULL;
+
+   debug("%s: mrc cache at %p, size %x checksum %04x\n", __func__,
+ cache->data, cache->data_size, cache->checksum);
+
+   return cache->data;
+}
+
 int arch_fsp_init(void)
 {
void *nvs;
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 035/102] x86: Add mrccache support for a 'variable' cache

2019-12-06 Thread Simon Glass
Add support for a second cache type, for Apollo Lake.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

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

Changes in v3:
- Move the mrccache_get_region() change into this patch

Changes in v2: None

 arch/x86/include/asm/mrccache.h | 1 +
 arch/x86/lib/mrccache.c | 3 ++-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/x86/include/asm/mrccache.h b/arch/x86/include/asm/mrccache.h
index b81e2b2fb6..0917cf2470 100644
--- a/arch/x86/include/asm/mrccache.h
+++ b/arch/x86/include/asm/mrccache.h
@@ -30,6 +30,7 @@ struct mrc_region {
 /* Types of MRC data */
 enum mrc_type_t {
MRC_TYPE_NORMAL,
+   MRC_TYPE_VAR,
 
MRC_TYPE_COUNT,
 };
diff --git a/arch/x86/lib/mrccache.c b/arch/x86/lib/mrccache.c
index 1278737ce4..10949d249e 100644
--- a/arch/x86/lib/mrccache.c
+++ b/arch/x86/lib/mrccache.c
@@ -241,7 +241,8 @@ int mrccache_get_region(enum mrc_type_t type, struct 
udevice **devp,
}
 
/* Find the place where we put the MRC cache */
-   mrc_node = dev_read_subnode(dev, "rw-mrc-cache");
+   mrc_node = dev_read_subnode(dev, type == MRC_TYPE_NORMAL ?
+   "rw-mrc-cache" : "rw-var-mrc-cache");
if (!ofnode_valid(mrc_node))
return log_msg_ret("Cannot find node", -EPERM);
 
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 034/102] x86: Update mrccache to support multiple caches

2019-12-06 Thread Simon Glass
With Apollo Lake we need to support a normal cache, which almost never
changes and a much smaller 'variable' cache which changes every time.

Update the code to add a cache type, use an array for the caches and use a
for loop to iterate over the caches.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

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

Changes in v3:
- Move line related to variable-cache into the next patch

Changes in v2: None

 arch/x86/cpu/broadwell/sdram.c |  8 ++-
 arch/x86/cpu/ivybridge/sdram.c |  8 ++-
 arch/x86/cpu/quark/dram.c  |  8 ++-
 arch/x86/include/asm/global_data.h | 21 +--
 arch/x86/include/asm/mrccache.h| 11 +++-
 arch/x86/lib/fsp/fsp_common.c  |  2 +-
 arch/x86/lib/fsp1/fsp_dram.c   |  8 ++-
 arch/x86/lib/mrccache.c| 88 --
 8 files changed, 106 insertions(+), 48 deletions(-)

diff --git a/arch/x86/cpu/broadwell/sdram.c b/arch/x86/cpu/broadwell/sdram.c
index dfd8afc35f..15bfc5811c 100644
--- a/arch/x86/cpu/broadwell/sdram.c
+++ b/arch/x86/cpu/broadwell/sdram.c
@@ -83,7 +83,7 @@ static int prepare_mrc_cache(struct pei_data *pei_data)
struct mrc_region entry;
int ret;
 
-   ret = mrccache_get_region(NULL, );
+   ret = mrccache_get_region(MRC_TYPE_NORMAL, NULL, );
if (ret)
return ret;
mrc_cache = mrccache_find_current();
@@ -169,12 +169,14 @@ int dram_init(void)
  pei_data->data_to_save);
/* S3 resume: don't save scrambler seed or MRC data */
if (pei_data->boot_mode != SLEEP_STATE_S3) {
+   struct mrc_output *mrc = >arch.mrc[MRC_TYPE_NORMAL];
+
/*
 * This will be copied to SDRAM in reserve_arch(), then written
 * to SPI flash in mrccache_save()
 */
-   gd->arch.mrc_output = (char *)pei_data->data_to_save;
-   gd->arch.mrc_output_len = pei_data->data_to_save_size;
+   mrc->buf = (char *)pei_data->data_to_save;
+   mrc->len = pei_data->data_to_save_size;
}
gd->arch.pei_meminfo = pei_data->meminfo;
 
diff --git a/arch/x86/cpu/ivybridge/sdram.c b/arch/x86/cpu/ivybridge/sdram.c
index 51ca4ad301..cf34f94a91 100644
--- a/arch/x86/cpu/ivybridge/sdram.c
+++ b/arch/x86/cpu/ivybridge/sdram.c
@@ -116,7 +116,7 @@ static int prepare_mrc_cache(struct pei_data *pei_data)
ret = read_seed_from_cmos(pei_data);
if (ret)
return ret;
-   ret = mrccache_get_region(NULL, );
+   ret = mrccache_get_region(MRC_TYPE_NORMAL, NULL, );
if (ret)
return ret;
mrc_cache = mrccache_find_current();
@@ -538,12 +538,14 @@ int dram_init(void)
 
/* S3 resume: don't save scrambler seed or MRC data */
if (pei_data->boot_mode != PEI_BOOT_RESUME) {
+   struct mrc_output *mrc = >arch.mrc[MRC_TYPE_NORMAL];
+
/*
 * This will be copied to SDRAM in reserve_arch(), then written
 * to SPI flash in mrccache_save()
 */
-   gd->arch.mrc_output = (char *)pei_data->mrc_output;
-   gd->arch.mrc_output_len = pei_data->mrc_output_len;
+   mrc->buf = (char *)pei_data->mrc_output;
+   mrc->len = pei_data->mrc_output_len;
ret = write_seeds_to_cmos(pei_data);
if (ret)
debug("Failed to write seeds to CMOS: %d\n", ret);
diff --git a/arch/x86/cpu/quark/dram.c b/arch/x86/cpu/quark/dram.c
index 995e119fb6..2bf90dcfc6 100644
--- a/arch/x86/cpu/quark/dram.c
+++ b/arch/x86/cpu/quark/dram.c
@@ -24,7 +24,7 @@ static __maybe_unused int prepare_mrc_cache(struct mrc_params 
*mrc_params)
struct mrc_region entry;
int ret;
 
-   ret = mrccache_get_region(NULL, );
+   ret = mrccache_get_region(MRC_TYPE_NORMAL, NULL, );
if (ret)
return ret;
 
@@ -154,9 +154,11 @@ int dram_init(void)
 #ifdef CONFIG_ENABLE_MRC_CACHE
cache = malloc(sizeof(struct mrc_timings));
if (cache) {
+   struct mrc_output *mrc = >arch.mrc[MRC_TYPE_NORMAL];
+
memcpy(cache, _params.timings, sizeof(struct mrc_timings));
-   gd->arch.mrc_output = cache;
-   gd->arch.mrc_output_len = sizeof(struct mrc_timings);
+   mrc->buf = cache;
+   mrc->len = sizeof(struct mrc_timings);
}
 #endif
 
diff --git a/arch/x86/include/asm/global_data.h 
b/arch/x86/include/asm/global_data.h
index 3212b006eb..190b604e0f 100644
--- a/arch/x86/include/asm/global_data.h
+++ b/arch/x86/include/asm/global_data.h
@@ -67,6 +67,21 @@ struct mtrr_request {
uint64_t size;
 };
 
+/**
+ * struct mrc_output - holds the MRC data
+ *
+ * @buf: MRC training data to save for the next boot. This is set to point to
+ * the raw data after SDRAM init is complete. Then 

[PATCH v6 036/102] x86: Don't export mrccache_update()

2019-12-06 Thread Simon Glass
This function is only used within the implementation so make it static.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

Changes in v6: None
Changes in v5: None
Changes in v4:
- Add new patch to make mrccache_update() static

Changes in v3: None
Changes in v2: None

 arch/x86/include/asm/mrccache.h | 15 ---
 arch/x86/lib/mrccache.c | 16 ++--
 2 files changed, 14 insertions(+), 17 deletions(-)

diff --git a/arch/x86/include/asm/mrccache.h b/arch/x86/include/asm/mrccache.h
index 0917cf2470..d6b7529073 100644
--- a/arch/x86/include/asm/mrccache.h
+++ b/arch/x86/include/asm/mrccache.h
@@ -48,21 +48,6 @@ struct udevice;
  */
 struct mrc_data_container *mrccache_find_current(struct mrc_region *entry);
 
-/**
- * mrccache_update() - update the MRC cache with a new record
- *
- * This writes a new record to the end of the MRC cache region. If the new
- * record is the same as the latest record then the write is skipped
- *
- * @sf:SPI flash to write to
- * @entry: Position and size of MRC cache in SPI flash
- * @cur:   Record to write
- * @return 0 if updated, -EEXIST if the record is the same as the latest
- * record, -EINVAL if the record is not valid, other error if SPI write failed
- */
-int mrccache_update(struct udevice *sf, struct mrc_region *entry,
-   struct mrc_data_container *cur);
-
 /**
  * mrccache_reserve() - reserve MRC data on the stack
  *
diff --git a/arch/x86/lib/mrccache.c b/arch/x86/lib/mrccache.c
index 10949d249e..b9420a4cab 100644
--- a/arch/x86/lib/mrccache.c
+++ b/arch/x86/lib/mrccache.c
@@ -118,8 +118,20 @@ static struct mrc_data_container 
*find_next_mrc_cache(struct mrc_region *entry,
return cache;
 }
 
-int mrccache_update(struct udevice *sf, struct mrc_region *entry,
-   struct mrc_data_container *cur)
+/**
+ * mrccache_update() - update the MRC cache with a new record
+ *
+ * This writes a new record to the end of the MRC cache region. If the new
+ * record is the same as the latest record then the write is skipped
+ *
+ * @sf:SPI flash to write to
+ * @entry: Position and size of MRC cache in SPI flash
+ * @cur:   Record to write
+ * @return 0 if updated, -EEXIST if the record is the same as the latest
+ * record, -EINVAL if the record is not valid, other error if SPI write failed
+ */
+static int mrccache_update(struct udevice *sf, struct mrc_region *entry,
+  struct mrc_data_container *cur)
 {
struct mrc_data_container *cache;
ulong offset;
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 032/102] x86: Add a new global_data member for the cache record

2019-12-06 Thread Simon Glass
At present we reuse the mrc_output char * to also point to the cache
record after it has been set up. This is confusing and doesn't save much
data space.

Add a new mrc_cache member instead.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

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

 arch/x86/include/asm/global_data.h |  2 ++
 arch/x86/lib/mrccache.c| 11 +--
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/arch/x86/include/asm/global_data.h 
b/arch/x86/include/asm/global_data.h
index 0e7b946205..3212b006eb 100644
--- a/arch/x86/include/asm/global_data.h
+++ b/arch/x86/include/asm/global_data.h
@@ -10,6 +10,7 @@
 #ifndef __ASSEMBLY__
 
 #include 
+#include 
 
 enum pei_boot_mode_t {
PEI_BOOT_NONE = 0,
@@ -93,6 +94,7 @@ struct arch_global_data {
/* MRC training data to save for the next boot */
char *mrc_output;
unsigned int mrc_output_len;
+   struct mrc_data_container *mrc_cache;
ulong table;/* Table pointer from previous loader */
int turbo_state;/* Current turbo state */
struct irq_routing_table *pirq_routing_table;
diff --git a/arch/x86/lib/mrccache.c b/arch/x86/lib/mrccache.c
index 7136166be6..6e561fe528 100644
--- a/arch/x86/lib/mrccache.c
+++ b/arch/x86/lib/mrccache.c
@@ -188,8 +188,7 @@ static void mrccache_setup(void *data)
cache->reserved = 0;
memcpy(cache->data, gd->arch.mrc_output, cache->data_size);
 
-   /* gd->arch.mrc_output now points to the container */
-   gd->arch.mrc_output = (char *)cache;
+   gd->arch.mrc_cache = cache;
 }
 
 int mrccache_reserve(void)
@@ -255,7 +254,7 @@ int mrccache_get_region(struct udevice **devp, struct 
mrc_region *entry)
 
 int mrccache_save(void)
 {
-   struct mrc_data_container *data;
+   struct mrc_data_container *cache;
struct mrc_region entry;
struct udevice *sf;
int ret;
@@ -271,10 +270,10 @@ int mrccache_save(void)
ret = device_probe(sf);
if (ret)
goto err_entry;
-   data  = (struct mrc_data_container *)gd->arch.mrc_output;
-   ret = mrccache_update(sf, , data);
+   cache = gd->arch.mrc_cache;
+   ret = mrccache_update(sf, , cache);
if (!ret) {
-   debug("Saved MRC data with checksum %04x\n", data->checksum);
+   debug("Saved MRC data with checksum %04x\n", cache->checksum);
} else if (ret == -EEXIST) {
debug("MRC data is the same as last time, skipping save\n");
ret = 0;
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 033/102] x86: Tidy up error handling in mrccache_save()

2019-12-06 Thread Simon Glass
This function is a bit confusing at present due to the error handling.
Update it to remove the goto, returning errors as they happen.

While we are here, use hex for the data size since this is the norm in
U-Boot.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3:
- Move an additional error handling fix from a future patch

Changes in v2: None

 arch/x86/lib/mrccache.c | 19 +++
 1 file changed, 7 insertions(+), 12 deletions(-)

diff --git a/arch/x86/lib/mrccache.c b/arch/x86/lib/mrccache.c
index 6e561fe528..712bacd5d2 100644
--- a/arch/x86/lib/mrccache.c
+++ b/arch/x86/lib/mrccache.c
@@ -168,7 +168,7 @@ int mrccache_update(struct udevice *sf, struct mrc_region 
*entry,
 cur);
if (ret) {
debug("Failed to write to SPI flash\n");
-   return ret;
+   return log_msg_ret("Cannot update mrccache", ret);
}
 
return 0;
@@ -261,28 +261,23 @@ int mrccache_save(void)
 
if (!gd->arch.mrc_output_len)
return 0;
-   debug("Saving %d bytes of MRC output data to SPI flash\n",
+   debug("Saving %#x bytes of MRC output data to SPI flash\n",
  gd->arch.mrc_output_len);
 
ret = mrccache_get_region(, );
if (ret)
-   goto err_entry;
+   return log_msg_ret("Cannot get region", ret);
ret = device_probe(sf);
if (ret)
-   goto err_entry;
+   return log_msg_ret("Cannot probe device", ret);
cache = gd->arch.mrc_cache;
ret = mrccache_update(sf, , cache);
-   if (!ret) {
+   if (!ret)
debug("Saved MRC data with checksum %04x\n", cache->checksum);
-   } else if (ret == -EEXIST) {
+   else if (ret == -EEXIST)
debug("MRC data is the same as last time, skipping save\n");
-   ret = 0;
-   }
 
-err_entry:
-   if (ret)
-   debug("%s: Failed: %d\n", __func__, ret);
-   return ret;
+   return 0;
 }
 
 int mrccache_spl_save(void)
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 030/102] x86: Adjust mrccache_get_region() to use livetree

2019-12-06 Thread Simon Glass
Change the algorithm to first find the flash device then read the
properties using the livetree API. With this change the device is not
probed so this needs to be done in mrccache_save().

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3:
- Update mrccache livetree patch to just convert to livetree

Changes in v2: None

 arch/x86/lib/mrccache.c | 55 +++--
 1 file changed, 26 insertions(+), 29 deletions(-)

diff --git a/arch/x86/lib/mrccache.c b/arch/x86/lib/mrccache.c
index 9d56685d36..50c72bf962 100644
--- a/arch/x86/lib/mrccache.c
+++ b/arch/x86/lib/mrccache.c
@@ -14,6 +14,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -206,45 +208,37 @@ int mrccache_reserve(void)
 
 int mrccache_get_region(struct udevice **devp, struct mrc_region *entry)
 {
-   const void *blob = gd->fdt_blob;
-   int node, mrc_node;
+   struct udevice *dev;
+   ofnode mrc_node;
u32 reg[2];
int ret;
 
-   /* Find the flash chip within the SPI controller node */
-   node = fdtdec_next_compatible(blob, 0, COMPAT_GENERIC_SPI_FLASH);
-   if (node < 0) {
-   debug("%s: Cannot find SPI flash\n", __func__);
-   return -ENOENT;
-   }
-
-   if (fdtdec_get_int_array(blob, node, "memory-map", reg, 2)) {
-   debug("%s: Cannot find memory map\n", __func__);
-   return -EINVAL;
-   }
+   /*
+* Find the flash chip within the SPI controller node. Avoid probing
+* the device here since it may put it into a strange state where the
+* memory map cannot be read.
+*/
+   ret = uclass_find_first_device(UCLASS_SPI_FLASH, );
+   if (ret)
+   return log_msg_ret("Cannot find SPI flash\n", ret);
+   ret = dev_read_u32_array(dev, "memory-map", reg, 2);
+   if (ret)
+   return log_msg_ret("Cannot find memory map\n", ret);
entry->base = reg[0];
 
/* Find the place where we put the MRC cache */
-   mrc_node = fdt_subnode_offset(blob, node, "rw-mrc-cache");
-   if (mrc_node < 0) {
-   debug("%s: Cannot find node\n", __func__);
-   return -EPERM;
-   }
+   mrc_node = dev_read_subnode(dev, "rw-mrc-cache");
+   if (!ofnode_valid(mrc_node))
+   return log_msg_ret("Cannot find node", -EPERM);
 
-   if (fdtdec_get_int_array(blob, mrc_node, "reg", reg, 2)) {
-   debug("%s: Cannot find address\n", __func__);
-   return -EINVAL;
-   }
+   ret = ofnode_read_u32_array(mrc_node, "reg", reg, 2);
+   if (ret)
+   return log_msg_ret("Cannot find address", ret);
entry->offset = reg[0];
entry->length = reg[1];
 
-   if (devp) {
-   ret = uclass_get_device_by_of_offset(UCLASS_SPI_FLASH, node,
-devp);
-   debug("ret = %d\n", ret);
-   if (ret)
-   return ret;
-   }
+   if (devp)
+   *devp = dev;
 
return 0;
 }
@@ -262,6 +256,9 @@ int mrccache_save(void)
  gd->arch.mrc_output_len);
 
ret = mrccache_get_region(, );
+   if (ret)
+   goto err_entry;
+   ret = device_probe(sf);
if (ret)
goto err_entry;
data  = (struct mrc_data_container *)gd->arch.mrc_output;
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 029/102] x86: Correct mrccache find_next_mrc_cache() calculation

2019-12-06 Thread Simon Glass
This should take account of the end of the new cache record since a record
cannot extend beyond the end of the flash region. This problem was not
seen before due to the alignment of the relatively small amount of MRC
data.

But with Apollo Lake the MRC data is about 45KB, even if most of it is
zeroes.

Fix this bug and update the parameter name to be less confusing.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

Changes in v6: None
Changes in v5: None
Changes in v4:
- Add comments about MRC-cache records being the same size
- apollolake -> Apollo Lake

Changes in v3:
- Add an extra size parameter to the find_next_mrc_cache() function

Changes in v2: None

 arch/x86/lib/mrccache.c | 18 ++
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/arch/x86/lib/mrccache.c b/arch/x86/lib/mrccache.c
index 33bb52039b..9d56685d36 100644
--- a/arch/x86/lib/mrccache.c
+++ b/arch/x86/lib/mrccache.c
@@ -80,21 +80,31 @@ struct mrc_data_container *mrccache_find_current(struct 
mrc_region *entry)
 /**
  * find_next_mrc_cache() - get next cache entry
  *
+ * This moves to the next cache entry in the region, making sure it has enough
+ * space to hold data of size @data_size.
+ *
  * @entry: MRC cache flash area
  * @cache: Entry to start from
+ * @data_size: Required data size of the new entry. Note that we assume that
+ * all cache entries are the same size
  *
  * @return next cache entry if found, NULL if we got to the end
  */
 static struct mrc_data_container *find_next_mrc_cache(struct mrc_region *entry,
-   struct mrc_data_container *cache)
+   struct mrc_data_container *prev, int data_size)
 {
+   struct mrc_data_container *cache;
ulong base_addr, end_addr;
 
base_addr = entry->base + entry->offset;
end_addr = base_addr + entry->length;
 
-   cache = next_mrc_block(cache);
-   if ((ulong)cache >= end_addr) {
+   /*
+* We assume that all cache entries are the same size, but let's use
+* data_size here for clarity.
+*/
+   cache = next_mrc_block(prev);
+   if ((ulong)cache + mrc_block_size(data_size) > end_addr) {
/* Crossed the boundary */
cache = NULL;
debug("%s: no available entries found\n", __func__);
@@ -131,7 +141,7 @@ int mrccache_update(struct udevice *sf, struct mrc_region 
*entry,
 
/* Move to the next block, which will be the first unused block */
if (cache)
-   cache = find_next_mrc_cache(entry, cache);
+   cache = find_next_mrc_cache(entry, cache, cur->data_size);
 
/*
 * If we have got to the end, erase the entire mrc-cache area and start
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 028/102] x86: Reduce mrccache record alignment size

2019-12-06 Thread Simon Glass
At present the records are 4KB in size. This is unnecessarily large when
the SPI-flash erase size is 256 bytes. Reduce it so it will be more
efficient with Apollo Lake's 24-byte variable-data record.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 

---

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

Changes in v3: None
Changes in v2: None

 arch/x86/include/asm/mrccache.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/include/asm/mrccache.h b/arch/x86/include/asm/mrccache.h
index 40fda856ff..abf5818223 100644
--- a/arch/x86/include/asm/mrccache.h
+++ b/arch/x86/include/asm/mrccache.h
@@ -7,7 +7,7 @@
 #ifndef _ASM_MRCCACHE_H
 #define _ASM_MRCCACHE_H
 
-#define MRC_DATA_ALIGN 0x1000
+#define MRC_DATA_ALIGN 0x100
 #define MRC_DATA_SIGNATURE (('M' << 0) | ('R' << 8) | \
 ('C' << 16) | ('D'<<24))
 
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 031/102] x86: Adjust mrccache_get_region() to support get_mmap()

2019-12-06 Thread Simon Glass
It is now possible to obtain the memory map for a SPI controllers instead
of having it hard-coded in the device tree. Update the code to support
this.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
- Use SPI mmap() instead of SPI flash

 arch/x86/lib/mrccache.c | 18 ++
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/arch/x86/lib/mrccache.c b/arch/x86/lib/mrccache.c
index 50c72bf962..7136166be6 100644
--- a/arch/x86/lib/mrccache.c
+++ b/arch/x86/lib/mrccache.c
@@ -210,6 +210,9 @@ int mrccache_get_region(struct udevice **devp, struct 
mrc_region *entry)
 {
struct udevice *dev;
ofnode mrc_node;
+   ulong map_base;
+   uint map_size;
+   uint offset;
u32 reg[2];
int ret;
 
@@ -221,10 +224,15 @@ int mrccache_get_region(struct udevice **devp, struct 
mrc_region *entry)
ret = uclass_find_first_device(UCLASS_SPI_FLASH, );
if (ret)
return log_msg_ret("Cannot find SPI flash\n", ret);
-   ret = dev_read_u32_array(dev, "memory-map", reg, 2);
-   if (ret)
-   return log_msg_ret("Cannot find memory map\n", ret);
-   entry->base = reg[0];
+   ret = dm_spi_get_mmap(dev, _base, _size, );
+   if (!ret) {
+   entry->base = map_base;
+   } else {
+   ret = dev_read_u32_array(dev, "memory-map", reg, 2);
+   if (ret)
+   return log_msg_ret("Cannot find memory map\n", ret);
+   entry->base = reg[0];
+   }
 
/* Find the place where we put the MRC cache */
mrc_node = dev_read_subnode(dev, "rw-mrc-cache");
@@ -239,6 +247,8 @@ int mrccache_get_region(struct udevice **devp, struct 
mrc_region *entry)
 
if (devp)
*devp = dev;
+   debug("MRC cache in '%s', offset %x, len %x, base %x\n",
+ dev->name, entry->offset, entry->length, entry->base);
 
return 0;
 }
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 024/102] sandbox: Add PCI driver and test for p2sb

2019-12-06 Thread Simon Glass
Add a sandbox driver and PCI-device emulator for p2sb. Also add a test
which uses a simple 'adder' driver to test the p2sb functionality.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

Changes in v6:
- Correct a few unrelated defconfig changes
- Drop unwanted debug printf()

Changes in v5: None
Changes in v4:
- Drop change to message about a missing uclass
- Drop empty operations struct since p2sb does not need it
- Drop pmic_pm8916 driver name and use a sandbox name instead
- Split out mmio changes into a separate patch

Changes in v3:
- Fix build errors in sandbox_spl, etc

Changes in v2: None

 arch/sandbox/dts/test.dts  |  13 ++
 arch/sandbox/include/asm/test.h|   1 +
 configs/sandbox64_defconfig|   3 +
 configs/sandbox_defconfig  |   1 +
 configs/sandbox_flattree_defconfig |   3 +
 configs/sandbox_spl_defconfig  |   3 +
 configs/tools-only_defconfig   |   2 +
 drivers/misc/Makefile  |   2 +
 drivers/misc/p2sb_emul.c   | 272 +
 drivers/misc/p2sb_sandbox.c|  39 +
 drivers/misc/sandbox_adder.c   |  60 +++
 test/dm/Makefile   |   1 +
 test/dm/p2sb.c |  28 +++
 13 files changed, 428 insertions(+)
 create mode 100644 drivers/misc/p2sb_emul.c
 create mode 100644 drivers/misc/p2sb_sandbox.c
 create mode 100644 drivers/misc/sandbox_adder.c
 create mode 100644 test/dm/p2sb.c

diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 99905677ab..9c8c4e2709 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -471,6 +471,16 @@
   0x01000810 0 0 0 0>;
sandbox,emul = <_case_emul0_1>;
};
+   p2sb-pci@2,0 {
+   compatible = "sandbox,p2sb";
+   reg = <0x02001010 0 0 0 0>;
+   sandbox,emul = <_emul>;
+
+   adder {
+   intel,p2sb-port-id = <3>;
+   compatible = "sandbox,adder";
+   };
+   };
pci@1e,0 {
compatible = "sandbox,pmc";
reg = <0xf000 0 0 0 0>;
@@ -502,6 +512,9 @@
swap_case_emul0_1f: emul0@1f,0 {
compatible = "sandbox,swap-case";
};
+   p2sb_emul: emul@2,0 {
+   compatible = "sandbox,p2sb-emul";
+   };
pmc_emul1e: emul@1e,0 {
compatible = "sandbox,pmc-emul";
};
diff --git a/arch/sandbox/include/asm/test.h b/arch/sandbox/include/asm/test.h
index fa40d21f3f..fdb0ecfed1 100644
--- a/arch/sandbox/include/asm/test.h
+++ b/arch/sandbox/include/asm/test.h
@@ -14,6 +14,7 @@
 #define SANDBOX_PCI_VENDOR_ID  0x1234
 #define SANDBOX_PCI_SWAP_CASE_EMUL_ID  0x5678
 #define SANDBOX_PCI_PMC_EMUL_ID0x5677
+#define SANDBOX_PCI_P2SB_EMUL_ID   0x5676
 #define SANDBOX_PCI_CLASS_CODE PCI_CLASS_CODE_COMM
 #define SANDBOX_PCI_CLASS_SUB_CODE PCI_CLASS_SUB_CODE_COMM_SERIAL
 
diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig
index d467841205..d1ca9eb3da 100644
--- a/configs/sandbox64_defconfig
+++ b/configs/sandbox64_defconfig
@@ -83,6 +83,8 @@ CONFIG_DEVRES=y
 CONFIG_DEBUG_DEVRES=y
 CONFIG_ADC=y
 CONFIG_ADC_SANDBOX=y
+CONFIG_AXI=y
+CONFIG_AXI_SANDBOX=y
 CONFIG_CLK=y
 CONFIG_CPU=y
 CONFIG_DM_DEMO=y
@@ -202,3 +204,4 @@ CONFIG_TEST_FDTDEC=y
 CONFIG_UNIT_TEST=y
 CONFIG_UT_TIME=y
 CONFIG_UT_DM=y
+CONFIG_P2SB=y
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index ed7ff78a86..cc8b44ad28 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -132,6 +132,7 @@ CONFIG_CROS_EC_I2C=y
 CONFIG_CROS_EC_LPC=y
 CONFIG_CROS_EC_SANDBOX=y
 CONFIG_CROS_EC_SPI=y
+CONFIG_P2SB=y
 CONFIG_PWRSEQ=y
 CONFIG_SPL_PWRSEQ=y
 CONFIG_I2C_EEPROM=y
diff --git a/configs/sandbox_flattree_defconfig 
b/configs/sandbox_flattree_defconfig
index 02969f95f1..8477542cb5 100644
--- a/configs/sandbox_flattree_defconfig
+++ b/configs/sandbox_flattree_defconfig
@@ -67,6 +67,8 @@ CONFIG_DEVRES=y
 CONFIG_DEBUG_DEVRES=y
 CONFIG_ADC=y
 CONFIG_ADC_SANDBOX=y
+CONFIG_AXI=y
+CONFIG_AXI_SANDBOX=y
 CONFIG_CLK=y
 CONFIG_CLK_COMPOSITE_CCF=y
 CONFIG_SANDBOX_CLK_CCF=y
@@ -117,6 +119,7 @@ CONFIG_PCI=y
 CONFIG_DM_PCI=y
 CONFIG_DM_PCI_COMPAT=y
 CONFIG_PCI_SANDBOX=y
+CONFIG_P2SB=y
 CONFIG_PHY=y
 CONFIG_PHY_SANDBOX=y
 CONFIG_PINCTRL=y
diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig
index 3b0f15de88..bcc04f0877 100644
--- a/configs/sandbox_spl_defconfig
+++ b/configs/sandbox_spl_defconfig
@@ -88,6 +88,8 @@ CONFIG_DEBUG_DEVRES=y
 # CONFIG_SPL_SIMPLE_BUS is not set
 CONFIG_ADC=y
 CONFIG_ADC_SANDBOX=y
+CONFIG_AXI=y
+CONFIG_AXI_SANDBOX=y
 CONFIG_CLK=y
 CONFIG_CPU=y
 CONFIG_DM_DEMO=y
@@ -201,3 +203,4 @@ CONFIG_ERRNO_STR=y
 CONFIG_UNIT_TEST=y
 

[PATCH v6 023/102] sandbox: Disable mmio by default in tests

2019-12-06 Thread Simon Glass
When reseting sandbox for tests, disable mmio support since that is the
default state.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

Changes in v6: None
Changes in v5: None
Changes in v4:
- Split out into a separate patch

Changes in v3: None
Changes in v2: None

 arch/sandbox/cpu/state.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/sandbox/cpu/state.c b/arch/sandbox/cpu/state.c
index dee5fde4f7..cd46e000f5 100644
--- a/arch/sandbox/cpu/state.c
+++ b/arch/sandbox/cpu/state.c
@@ -356,6 +356,7 @@ void state_reset_for_test(struct sandbox_state *state)
/* No reset yet, so mark it as such. Always allow power reset */
state->last_sysreset = SYSRESET_COUNT;
state->sysreset_allowed[SYSRESET_POWER_OFF] = true;
+   state->allow_memio = false;
 
memset(>wdt, '\0', sizeof(state->wdt));
memset(state->spi, '\0', sizeof(state->spi));
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 025/102] x86: Move UCLASS_IRQ into a separate file

2019-12-06 Thread Simon Glass
Update this uclass to support the needs of the Apollo Lake ITSS. It
supports four operations.

Move the uclass into a separate directory so that sandbox can use it too.
Add a new Kconfig to control it and enable this on x86.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

Changes in v6: None
Changes in v5: None
Changes in v4:
- Drop itss uclass in Makefile
- Fix 'enabled' typo
- apollolake -> Apollo Lake

Changes in v3:
- Add two more operations to IRQ
- Use the IRQ uclass instead of creating a new ITSS uclass

Changes in v2: None

 arch/Kconfig  |  1 +
 arch/x86/cpu/irq.c|  5 ---
 drivers/misc/Kconfig  |  9 
 drivers/misc/Makefile |  1 +
 drivers/misc/irq-uclass.c | 53 +++
 include/irq.h | 88 +++
 6 files changed, 152 insertions(+), 5 deletions(-)
 create mode 100644 drivers/misc/irq-uclass.c
 create mode 100644 include/irq.h

diff --git a/arch/Kconfig b/arch/Kconfig
index e1f1fcd275..6865e1f909 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -186,6 +186,7 @@ config X86
imply USB_HOST_ETHER
imply PCH
imply RTC_MC146818
+   imply IRQ
 
# Thing to enable for when SPL/TPL are enabled: SPL
imply SPL_DM
diff --git a/arch/x86/cpu/irq.c b/arch/x86/cpu/irq.c
index 3adc155818..cb183496b7 100644
--- a/arch/x86/cpu/irq.c
+++ b/arch/x86/cpu/irq.c
@@ -370,8 +370,3 @@ U_BOOT_DRIVER(irq_router_drv) = {
.probe  = irq_router_probe,
.priv_auto_alloc_size = sizeof(struct irq_router),
 };
-
-UCLASS_DRIVER(irq) = {
-   .id = UCLASS_IRQ,
-   .name   = "irq",
-};
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 71643af9c2..f18aa8f7ba 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -203,6 +203,15 @@ config FSL_SEC_MON
  Security Monitor can be transitioned on any security failures,
  like software violations or hardware security violations.
 
+config IRQ
+   bool "Intel Interrupt controller"
+   depends on X86 || SANDBOX
+   help
+ This enables support for Intel interrupt controllers, including ITSS.
+ Some devices have extra features, such as Apollo Lake. The
+ device has its own uclass since there are several operations
+ involved.
+
 config JZ4780_EFUSE
bool "Ingenic JZ4780 eFUSE support"
depends on ARCH_JZ47XX
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 44c9e3ef08..28313e4a65 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -41,6 +41,7 @@ obj-$(CONFIG_FS_LOADER) += fs_loader.o
 obj-$(CONFIG_GDSYS_IOEP) += gdsys_ioep.o
 obj-$(CONFIG_GDSYS_RXAUI_CTRL) += gdsys_rxaui_ctrl.o
 obj-$(CONFIG_GDSYS_SOC) += gdsys_soc.o
+obj-$(CONFIG_IRQ) += irq-uclass.o
 obj-$(CONFIG_$(SPL_)I2C_EEPROM) += i2c_eeprom.o
 obj-$(CONFIG_IHS_FPGA) += ihs_fpga.o
 obj-$(CONFIG_IMX8) += imx8/
diff --git a/drivers/misc/irq-uclass.c b/drivers/misc/irq-uclass.c
new file mode 100644
index 00..d5182cf149
--- /dev/null
+++ b/drivers/misc/irq-uclass.c
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2015, Bin Meng 
+ */
+
+#include 
+#include 
+#include 
+
+int irq_route_pmc_gpio_gpe(struct udevice *dev, uint pmc_gpe_num)
+{
+   const struct irq_ops *ops = irq_get_ops(dev);
+
+   if (!ops->route_pmc_gpio_gpe)
+   return -ENOSYS;
+
+   return ops->route_pmc_gpio_gpe(dev, pmc_gpe_num);
+}
+
+int irq_set_polarity(struct udevice *dev, uint irq, bool active_low)
+{
+   const struct irq_ops *ops = irq_get_ops(dev);
+
+   if (!ops->set_polarity)
+   return -ENOSYS;
+
+   return ops->set_polarity(dev, irq, active_low);
+}
+
+int irq_snapshot_polarities(struct udevice *dev)
+{
+   const struct irq_ops *ops = irq_get_ops(dev);
+
+   if (!ops->snapshot_polarities)
+   return -ENOSYS;
+
+   return ops->snapshot_polarities(dev);
+}
+
+int irq_restore_polarities(struct udevice *dev)
+{
+   const struct irq_ops *ops = irq_get_ops(dev);
+
+   if (!ops->restore_polarities)
+   return -ENOSYS;
+
+   return ops->restore_polarities(dev);
+}
+
+UCLASS_DRIVER(irq) = {
+   .id = UCLASS_IRQ,
+   .name   = "irq",
+};
diff --git a/include/irq.h b/include/irq.h
new file mode 100644
index 00..01ded64f16
--- /dev/null
+++ b/include/irq.h
@@ -0,0 +1,88 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * IRQ is a type of interrupt controller used on recent Intel SoC.
+ *
+ * Copyright 2019 Google LLC
+ */
+
+#ifndef __irq_H
+#define __irq_H
+
+/**
+ * struct irq_ops - Operations for the IRQ
+ */
+struct irq_ops {
+   /**
+* route_pmc_gpio_gpe() - Get the GPIO for an event
+*
+* @dev: IRQ device
+* @pmc_gpe_num: Event number to check
+* @returns GPIO for the event, or -ENOENT if none
+*/
+   int (*route_pmc_gpio_gpe)(struct udevice 

[PATCH v6 026/102] sandbox: Add a test for IRQ

2019-12-06 Thread Simon Glass
Add a simple sandbox test for this uclass.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

Changes in v6:
- Move setting of CONFIG_IRQ in sandbox to this patch

Changes in v5: None
Changes in v4:
- Drop itss uclass change in Makefile (now in previous patch)
- Drop sandbox defconfig change now that p2sb change is correct
- Enable IRQ for sandbox64 too to avoid build error

Changes in v3:
- Change the sandbox test from ITSS to IRQ

Changes in v2: None

 arch/sandbox/dts/test.dts  |  4 +++
 configs/sandbox64_defconfig|  1 +
 configs/sandbox_defconfig  |  1 +
 configs/sandbox_flattree_defconfig |  1 +
 configs/sandbox_spl_defconfig  |  1 +
 drivers/misc/Makefile  |  1 +
 drivers/misc/irq_sandbox.c | 55 ++
 test/dm/Makefile   |  1 +
 test/dm/irq.c  | 32 +
 9 files changed, 97 insertions(+)
 create mode 100644 drivers/misc/irq_sandbox.c
 create mode 100644 test/dm/irq.c

diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 9c8c4e2709..57513a449f 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -353,6 +353,10 @@
vss-microvolts = <0>;
};
 
+   irq {
+   compatible = "sandbox,irq";
+   };
+
lcd {
u-boot,dm-pre-reloc;
compatible = "sandbox,lcd-sdl";
diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig
index d1ca9eb3da..5bdde8afd4 100644
--- a/configs/sandbox64_defconfig
+++ b/configs/sandbox64_defconfig
@@ -114,6 +114,7 @@ CONFIG_CROS_EC_I2C=y
 CONFIG_CROS_EC_LPC=y
 CONFIG_CROS_EC_SANDBOX=y
 CONFIG_CROS_EC_SPI=y
+CONFIG_IRQ=y
 CONFIG_PWRSEQ=y
 CONFIG_SPL_PWRSEQ=y
 CONFIG_I2C_EEPROM=y
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index cc8b44ad28..ff9374 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -132,6 +132,7 @@ CONFIG_CROS_EC_I2C=y
 CONFIG_CROS_EC_LPC=y
 CONFIG_CROS_EC_SANDBOX=y
 CONFIG_CROS_EC_SPI=y
+CONFIG_IRQ=y
 CONFIG_P2SB=y
 CONFIG_PWRSEQ=y
 CONFIG_SPL_PWRSEQ=y
diff --git a/configs/sandbox_flattree_defconfig 
b/configs/sandbox_flattree_defconfig
index 8477542cb5..40a4b2a761 100644
--- a/configs/sandbox_flattree_defconfig
+++ b/configs/sandbox_flattree_defconfig
@@ -100,6 +100,7 @@ CONFIG_CROS_EC_I2C=y
 CONFIG_CROS_EC_LPC=y
 CONFIG_CROS_EC_SANDBOX=y
 CONFIG_CROS_EC_SPI=y
+CONFIG_IRQ=y
 CONFIG_PWRSEQ=y
 CONFIG_SPL_PWRSEQ=y
 CONFIG_I2C_EEPROM=y
diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig
index bcc04f0877..77c56747fb 100644
--- a/configs/sandbox_spl_defconfig
+++ b/configs/sandbox_spl_defconfig
@@ -120,6 +120,7 @@ CONFIG_CROS_EC_I2C=y
 CONFIG_CROS_EC_LPC=y
 CONFIG_CROS_EC_SANDBOX=y
 CONFIG_CROS_EC_SPI=y
+CONFIG_IRQ=y
 CONFIG_PWRSEQ=y
 CONFIG_SPL_PWRSEQ=y
 CONFIG_MMC_SANDBOX=y
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 28313e4a65..d4e8638dea 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_GDSYS_IOEP) += gdsys_ioep.o
 obj-$(CONFIG_GDSYS_RXAUI_CTRL) += gdsys_rxaui_ctrl.o
 obj-$(CONFIG_GDSYS_SOC) += gdsys_soc.o
 obj-$(CONFIG_IRQ) += irq-uclass.o
+obj-$(CONFIG_SANDBOX) += irq_sandbox.o
 obj-$(CONFIG_$(SPL_)I2C_EEPROM) += i2c_eeprom.o
 obj-$(CONFIG_IHS_FPGA) += ihs_fpga.o
 obj-$(CONFIG_IMX8) += imx8/
diff --git a/drivers/misc/irq_sandbox.c b/drivers/misc/irq_sandbox.c
new file mode 100644
index 00..6dda1a4c44
--- /dev/null
+++ b/drivers/misc/irq_sandbox.c
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Sandbox driver for interrupts
+ *
+ * Copyright 2019 Google LLC
+ */
+
+#include 
+#include 
+#include 
+
+static int sandbox_set_polarity(struct udevice *dev, uint irq, bool active_low)
+{
+   if (irq > 10)
+   return -EINVAL;
+
+   return 0;
+}
+
+static int sandbox_route_pmc_gpio_gpe(struct udevice *dev, uint pmc_gpe_num)
+{
+   if (pmc_gpe_num > 10)
+   return -ENOENT;
+
+   return pmc_gpe_num + 1;
+}
+
+static int sandbox_snapshot_polarities(struct udevice *dev)
+{
+   return 0;
+}
+
+static int sandbox_restore_polarities(struct udevice *dev)
+{
+   return 0;
+}
+
+static const struct irq_ops sandbox_irq_ops = {
+   .route_pmc_gpio_gpe = sandbox_route_pmc_gpio_gpe,
+   .set_polarity   = sandbox_set_polarity,
+   .snapshot_polarities= sandbox_snapshot_polarities,
+   .restore_polarities = sandbox_restore_polarities,
+};
+
+static const struct udevice_id sandbox_irq_ids[] = {
+   { .compatible = "sandbox,irq"},
+   { }
+};
+
+U_BOOT_DRIVER(sandbox_irq_drv) = {
+   .name   = "sandbox_irq",
+   .id = UCLASS_IRQ,
+   .of_match   = sandbox_irq_ids,
+   .ops= _irq_ops,
+};
diff --git a/test/dm/Makefile b/test/dm/Makefile
index 129ccb3b49..a268783169 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -25,6 +25,7 @@ 

[PATCH v6 027/102] x86: Define the SPL image start

2019-12-06 Thread Simon Glass
Define this symbol so that we can use binman symbols correctly.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

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

 arch/x86/cpu/u-boot-spl.lds | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/x86/cpu/u-boot-spl.lds b/arch/x86/cpu/u-boot-spl.lds
index c1e9bfbf66..e6c22895b3 100644
--- a/arch/x86/cpu/u-boot-spl.lds
+++ b/arch/x86/cpu/u-boot-spl.lds
@@ -17,7 +17,10 @@ SECTIONS
 
. = IMAGE_TEXT_BASE;/* Location of bootcode in flash */
__text_start = .;
-   .text  : { *(.text*); }
+   .text  : {
+   __image_copy_start = .;
+   *(.text*);
+   }
 
. = ALIGN(4);
 
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 022/102] pci: Add support for p2sb uclass

2019-12-06 Thread Simon Glass
The Primary-to-Sideband bus (P2SB) is used to access various peripherals
through memory-mapped I/O in a large chunk of PCI space. The space is
segmented into different channels and peripherals are accessed by
device-specific means within those channels. Devices should be added in
the device tree as subnodes of the p2sb.

This adds a uclass and enables it for sandbox.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 

---

Changes in v6: None
Changes in v5:
- Add a way to obtain the port ID for a device
- Don't enable p2sb on sandbox in this patch

Changes in v4:
- Adjust condition for binding children

Changes in v3: None
Changes in v2: None

 drivers/misc/Kconfig   |  33 ++
 drivers/misc/Makefile  |   1 +
 drivers/misc/p2sb-uclass.c | 216 +
 include/dm/uclass-id.h |   1 +
 include/p2sb.h | 135 +++
 5 files changed, 386 insertions(+)
 create mode 100644 drivers/misc/p2sb-uclass.c
 create mode 100644 include/p2sb.h

diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 82bb093c56..71643af9c2 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -226,6 +226,39 @@ config NUVOTON_NCT6102D
  disable the legacy UART, the watchdog or other devices
  in the Nuvoton Super IO chips on X86 platforms.
 
+config P2SB
+   bool "Intel Primary-to-Sideband Bus"
+   depends on X86 || SANDBOX
+   help
+ This enables support for the Intel Primary-to-Sideband bus,
+ abbreviated to P2SB. The P2SB is used to access various peripherals
+ such as eSPI, GPIO, through memory-mapped I/O in a large chunk of PCI
+ space. The space is segmented into different channels and peripherals
+ are accessed by device-specific means within those channels. Devices
+ should be added in the device tree as subnodes of the P2SB. A
+ Peripheral Channel Register? (PCR) API is provided to access those
+ devices - see pcr_readl(), etc.
+
+config SPL_P2SB
+   bool "Intel Primary-to-Sideband Bus in SPL"
+   depends on SPL && (X86 || SANDBOX)
+   help
+ The Primary-to-Sideband bus is used to access various peripherals
+ through memory-mapped I/O in a large chunk of PCI space. The space is
+ segmented into different channels and peripherals are accessed by
+ device-specific means within those channels. Devices should be added
+ in the device tree as subnodes of the p2sb.
+
+config TPL_P2SB
+   bool "Intel Primary-to-Sideband Bus in TPL"
+   depends on TPL && (X86 || SANDBOX)
+   help
+ The Primary-to-Sideband bus is used to access various peripherals
+ through memory-mapped I/O in a large chunk of PCI space. The space is
+ segmented into different channels and peripherals are accessed by
+ device-specific means within those channels. Devices should be added
+ in the device tree as subnodes of the p2sb.
+
 config PWRSEQ
bool "Enable power-sequencing drivers"
depends on DM
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 55976d6be5..78b598b367 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -49,6 +49,7 @@ obj-$(CONFIG_MXC_OCOTP) += mxc_ocotp.o
 obj-$(CONFIG_MXS_OCOTP) += mxs_ocotp.o
 obj-$(CONFIG_NS87308) += ns87308.o
 obj-$(CONFIG_NUVOTON_NCT6102D) += nuvoton_nct6102d.o
+obj-$(CONFIG_P2SB) += p2sb-uclass.o
 obj-$(CONFIG_PCA9551_LED) += pca9551_led.o
 obj-$(CONFIG_$(SPL_)PWRSEQ) += pwrseq-uclass.o
 obj-$(CONFIG_QFW) += qfw.o
diff --git a/drivers/misc/p2sb-uclass.c b/drivers/misc/p2sb-uclass.c
new file mode 100644
index 00..a198700b5f
--- /dev/null
+++ b/drivers/misc/p2sb-uclass.c
@@ -0,0 +1,216 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Uclass for Primary-to-sideband bus, used to access various peripherals
+ *
+ * Copyright 2019 Google LLC
+ * Written by Simon Glass 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define PCR_COMMON_IOSF_1_01
+
+static void *_pcr_reg_address(struct udevice *dev, uint offset)
+{
+   struct p2sb_child_platdata *pplat = dev_get_parent_platdata(dev);
+   struct udevice *p2sb = dev_get_parent(dev);
+   struct p2sb_uc_priv *upriv = dev_get_uclass_priv(p2sb);
+   uintptr_t reg_addr;
+
+   /* Create an address based off of port id and offset */
+   reg_addr = upriv->mmio_base;
+   reg_addr += pplat->pid << PCR_PORTID_SHIFT;
+   reg_addr += offset;
+
+   return map_sysmem(reg_addr, 4);
+}
+
+/*
+ * The mapping of addresses via the SBREG_BAR assumes the IOSF-SB
+ * agents are using 32-bit aligned accesses for their configuration
+ * registers. For IOSF versions greater than 1_0, IOSF-SB
+ * agents can use any access (8/16/32 bit aligned) for their
+ * configuration registers
+ */
+static inline void check_pcr_offset_align(uint offset, uint size)
+{
+   const size_t align = PCR_COMMON_IOSF_1_0 ? 

[PATCH v6 021/102] x86: sandbox: Add a PMC emulator and test

2019-12-06 Thread Simon Glass
Add a simple PMC for sandbox to permit tests to run.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3:
- Rename power-mgr uclass to acpi-pmc
- Tidy up Makefile rules to reduce duplication

Changes in v2: None

 arch/Kconfig  |   3 +
 arch/sandbox/dts/sandbox.dtsi |  14 ++
 arch/sandbox/dts/test.dts |  14 ++
 arch/sandbox/include/asm/test.h   |   1 +
 cmd/Kconfig   |   8 +
 cmd/Makefile  |   1 +
 cmd/pmc.c |  81 ++
 drivers/Makefile  |   1 +
 drivers/power/acpi_pmc/Kconfig|   9 ++
 drivers/power/acpi_pmc/Makefile   |   1 +
 drivers/power/acpi_pmc/pmc_emul.c | 246 ++
 drivers/power/acpi_pmc/sandbox.c  |  97 
 test/dm/Makefile  |   1 +
 test/dm/pmc.c |  33 
 14 files changed, 510 insertions(+)
 create mode 100644 cmd/pmc.c
 create mode 100644 drivers/power/acpi_pmc/pmc_emul.c
 create mode 100644 drivers/power/acpi_pmc/sandbox.c
 create mode 100644 test/dm/pmc.c

diff --git a/arch/Kconfig b/arch/Kconfig
index 141e48bc43..e1f1fcd275 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -133,6 +133,9 @@ config SANDBOX
imply PHYLIB
imply DM_MDIO
imply DM_MDIO_MUX
+   imply ACPI_PMC
+   imply ACPI_PMC_SANDBOX
+   imply CMD_PMC
 
 config SH
bool "SuperH architecture"
diff --git a/arch/sandbox/dts/sandbox.dtsi b/arch/sandbox/dts/sandbox.dtsi
index f09bc70b0d..7bf144f532 100644
--- a/arch/sandbox/dts/sandbox.dtsi
+++ b/arch/sandbox/dts/sandbox.dtsi
@@ -100,6 +100,17 @@
};
 
pci-controller {
+   pci@1e,0 {
+   compatible = "sandbox,pmc";
+   reg = <0xf000 0 0 0 0>;
+   sandbox,emul = <_emul>;
+   gpe0-dwx-mask = <0xf>;
+   gpe0-dwx-shift-base = <4>;
+   gpe0-dw = <6 7 9>;
+   gpe0-sts = <0x20>;
+   gpe0-en = <0x30>;
+   };
+
pci@1f,0 {
compatible = "pci-generic";
reg = <0xf800 0 0 0 0>;
@@ -109,6 +120,9 @@
 
emul {
compatible = "sandbox,pci-emul-parent";
+   pmc_emul: emul@1e,0 {
+   compatible = "sandbox,pmc-emul";
+   };
swap_case_emul: emul@1f,0 {
compatible = "sandbox,swap-case";
};
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index fdb08f2111..99905677ab 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -471,6 +471,17 @@
   0x01000810 0 0 0 0>;
sandbox,emul = <_case_emul0_1>;
};
+   pci@1e,0 {
+   compatible = "sandbox,pmc";
+   reg = <0xf000 0 0 0 0>;
+   sandbox,emul = <_emul1e>;
+   acpi-base = <0x400>;
+   gpe0-dwx-mask = <0xf>;
+   gpe0-dwx-shift-base = <4>;
+   gpe0-dw = <6 7 9>;
+   gpe0-sts = <0x20>;
+   gpe0-en = <0x30>;
+   };
pci@1f,0 {
compatible = "pci-generic";
/* reg 0 is at 0x10, using FDT_PCI_SPACE_IO */
@@ -491,6 +502,9 @@
swap_case_emul0_1f: emul0@1f,0 {
compatible = "sandbox,swap-case";
};
+   pmc_emul1e: emul@1e,0 {
+   compatible = "sandbox,pmc-emul";
+   };
};
 
pci1: pci-controller1 {
diff --git a/arch/sandbox/include/asm/test.h b/arch/sandbox/include/asm/test.h
index b885e1a14f..fa40d21f3f 100644
--- a/arch/sandbox/include/asm/test.h
+++ b/arch/sandbox/include/asm/test.h
@@ -13,6 +13,7 @@
 
 #define SANDBOX_PCI_VENDOR_ID  0x1234
 #define SANDBOX_PCI_SWAP_CASE_EMUL_ID  0x5678
+#define SANDBOX_PCI_PMC_EMUL_ID0x5677
 #define SANDBOX_PCI_CLASS_CODE PCI_CLASS_CODE_COMM
 #define SANDBOX_PCI_CLASS_SUB_CODE PCI_CLASS_SUB_CODE_COMM_SERIAL
 
diff --git a/cmd/Kconfig b/cmd/Kconfig
index bc8318d7fa..6fa751 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -228,6 +228,14 @@ config CMD_LICENSE
help
  Print GPL license text
 
+config CMD_PMC
+   bool "pmc"
+   help
+ Provides access to the Intel Power-Management Controller (PMC) so
+ that its state can be examined. This does not currently support
+ changing the state but it is still useful for debugging and seeing
+ what is going on.
+
 config CMD_REGINFO
bool "reginfo"
depends on PPC
diff --git a/cmd/Makefile b/cmd/Makefile
index e87c2f1625..62b38ef7e8 100644

[PATCH v6 020/102] x86: power: Add an ACPI PMC uclass

2019-12-06 Thread Simon Glass
Intel x86 SoCs have a power manager/controller which handles several
power-related aspects of the platform. Add a uclass for this, with a few
useful operations.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

Changes in v6: None
Changes in v5: None
Changes in v4:
- Fix alpha order in Kconfig
- Switch over to use pinctrl for pad init/config

Changes in v3:
- Rename power-mgr uclass to acpi-pmc

Changes in v2: None

 drivers/power/Kconfig|   2 +
 drivers/power/acpi_pmc/Kconfig   |  25 +++
 drivers/power/acpi_pmc/Makefile  |   5 +
 drivers/power/acpi_pmc/acpi-pmc-uclass.c | 188 +++
 include/dm/uclass-id.h   |   1 +
 include/power/acpi_pmc.h | 185 ++
 6 files changed, 406 insertions(+)
 create mode 100644 drivers/power/acpi_pmc/Kconfig
 create mode 100644 drivers/power/acpi_pmc/Makefile
 create mode 100644 drivers/power/acpi_pmc/acpi-pmc-uclass.c
 create mode 100644 include/power/acpi_pmc.h

diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index 9495dca33b..cb2c6fe3eb 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -1,5 +1,7 @@
 menu "Power"
 
+source "drivers/power/acpi_pmc/Kconfig"
+
 source "drivers/power/domain/Kconfig"
 
 source "drivers/power/pmic/Kconfig"
diff --git a/drivers/power/acpi_pmc/Kconfig b/drivers/power/acpi_pmc/Kconfig
new file mode 100644
index 00..472a61a9fd
--- /dev/null
+++ b/drivers/power/acpi_pmc/Kconfig
@@ -0,0 +1,25 @@
+config ACPI_PMC
+   bool "Power Manager (x86 PMC) support"
+   help
+ Enable support for an x86-style power-management controller which
+ provides features including checking whether the system started from
+ resume, powering off the system and enabling/disabling the reset
+ mechanism.
+
+config SPL_ACPI_PMC
+   bool "Power Manager (x86 PMC) support in SPL"
+   default y if ACPI_PMC
+   help
+ Enable support for an x86-style power-management controller which
+ provides features including checking whether the system started from
+ resume, powering off the system and enabling/disabling the reset
+ mechanism.
+
+config TPL_ACPI_PMC
+   bool "Power Manager (x86 PMC) support in TPL"
+   default y if ACPI_PMC
+   help
+ Enable support for an x86-style power-management controller which
+ provides features including checking whether the system started from
+ resume, powering off the system and enabling/disabling the reset
+ mechanism.
diff --git a/drivers/power/acpi_pmc/Makefile b/drivers/power/acpi_pmc/Makefile
new file mode 100644
index 00..7c1ba05c9f
--- /dev/null
+++ b/drivers/power/acpi_pmc/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright 2019 Google LLC
+
+obj-$(CONFIG_$(SPL_TPL_)ACPI_PMC) += acpi-pmc-uclass.o
diff --git a/drivers/power/acpi_pmc/acpi-pmc-uclass.c 
b/drivers/power/acpi_pmc/acpi-pmc-uclass.c
new file mode 100644
index 00..653c71b948
--- /dev/null
+++ b/drivers/power/acpi_pmc/acpi-pmc-uclass.c
@@ -0,0 +1,188 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 Google LLC
+ */
+
+#define LOG_CATEGORY UCLASS_ACPI_PMC
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+enum {
+   PM1_STS = 0x00,
+   PM1_EN  = 0x02,
+   PM1_CNT = 0x04,
+
+   GPE0_STS= 0x20,
+   GPE0_EN = 0x30,
+};
+
+struct tco_regs {
+   u32 tco_rld;
+   u32 tco_sts;
+   u32 tco1_cnt;
+   u32 tco_tmr;
+};
+
+enum {
+   TCO_STS_TIMEOUT = 1 << 3,
+   TCO_STS_SECOND_TO_STS   = 1 << 17,
+   TCO1_CNT_HLT= 1 << 11,
+};
+
+static void pmc_fill_pm_reg_info(struct udevice *dev)
+{
+   struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(dev);
+   int i;
+
+   upriv->pm1_sts = inw(upriv->acpi_base + PM1_STS);
+   upriv->pm1_en = inw(upriv->acpi_base + PM1_EN);
+   upriv->pm1_cnt = inw(upriv->acpi_base + PM1_CNT);
+
+   log_debug("pm1_sts: %04x pm1_en: %04x pm1_cnt: %08x\n",
+ upriv->pm1_sts, upriv->pm1_en, upriv->pm1_cnt);
+
+   for (i = 0; i < GPE0_REG_MAX; i++) {
+   upriv->gpe0_sts[i] = inl(upriv->acpi_base + GPE0_STS + i * 4);
+   upriv->gpe0_en[i] = inl(upriv->acpi_base + GPE0_EN + i * 4);
+   log_debug("gpe0_sts[%d]: %08x gpe0_en[%d]: %08x\n", i,
+ upriv->gpe0_sts[i], i, upriv->gpe0_en[i]);
+   }
+}
+
+int pmc_disable_tco_base(ulong tco_base)
+{
+   struct tco_regs *regs = (struct tco_regs *)tco_base;
+
+   debug("tco_base %lx = %x\n", (ulong)>tco1_cnt, TCO1_CNT_HLT);
+   setio_32(>tco1_cnt, TCO1_CNT_HLT);
+
+   return 0;
+}
+
+int pmc_init(struct udevice *dev)
+{
+   const struct acpi_pmc_ops *ops = acpi_pmc_get_ops(dev);
+   int ret;
+
+   pmc_fill_pm_reg_info(dev);
+   if 

[PATCH v6 019/102] x86: Drop unnecessary interrupt code for TPL

2019-12-06 Thread Simon Glass
We don't expect an exception in TPL and don't need to set up interrupts in
TPL. Drop this whole file.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

Changes in v6: None
Changes in v5: None
Changes in v4:
- Drop the whole interrupt file for TPL

Changes in v3: None
Changes in v2: None

 arch/x86/cpu/i386/Makefile | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/x86/cpu/i386/Makefile b/arch/x86/cpu/i386/Makefile
index 0c47252610..18e152074a 100644
--- a/arch/x86/cpu/i386/Makefile
+++ b/arch/x86/cpu/i386/Makefile
@@ -5,5 +5,7 @@
 
 obj-y += call64.o
 obj-y += cpu.o
+ifndef CONFIG_TPL_BUILD
 obj-y += interrupt.o
+endif
 obj-y += setjmp.o
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 018/102] x86: Drop unnecessary cpu code for TPL

2019-12-06 Thread Simon Glass
We don't need to know every detail about the CPU in TPL. Drop some
superfluous functions to reduce code size. Add a simple CPU detection
algorithm which just supports Intel and AMD, since we only support TPL
on Intel, so far.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

Changes in v6: None
Changes in v5: None
Changes in v4:
- Drop 'if (0)' call to deep_magic_nexgen_probe() and use #ifndef instead
- Fix 'what' typo

Changes in v3: None
Changes in v2: None

 arch/x86/cpu/cpu.c  |  4 
 arch/x86/cpu/i386/cpu.c | 41 +
 2 files changed, 41 insertions(+), 4 deletions(-)

diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c
index 4e59476fc9..d626e38fd1 100644
--- a/arch/x86/cpu/cpu.c
+++ b/arch/x86/cpu/cpu.c
@@ -46,6 +46,7 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#ifndef CONFIG_TPL_BUILD
 static const char *const x86_vendor_name[] = {
[X86_VENDOR_INTEL] = "Intel",
[X86_VENDOR_CYRIX] = "Cyrix",
@@ -58,6 +59,7 @@ static const char *const x86_vendor_name[] = {
[X86_VENDOR_NSC]   = "NSC",
[X86_VENDOR_SIS]   = "SiS",
 };
+#endif
 
 int __weak x86_cleanup_before_linux(void)
 {
@@ -114,6 +116,7 @@ int icache_status(void)
return 1;
 }
 
+#ifndef CONFIG_TPL_BUILD
 const char *cpu_vendor_name(int vendor)
 {
const char *name;
@@ -124,6 +127,7 @@ const char *cpu_vendor_name(int vendor)
 
return name;
 }
+#endif
 
 char *cpu_get_name(char *name)
 {
diff --git a/arch/x86/cpu/i386/cpu.c b/arch/x86/cpu/i386/cpu.c
index c66382bdd2..2b27617ca3 100644
--- a/arch/x86/cpu/i386/cpu.c
+++ b/arch/x86/cpu/i386/cpu.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -58,6 +59,8 @@ struct cpuinfo_x86 {
uint8_t x86_mask;
 };
 
+/* gcc 7.3 does not wwant to drop x86_vendors, so use #ifdef */
+#ifndef CONFIG_TPL_BUILD
 /*
  * List of cpu vendor strings along with their normalized
  * id values.
@@ -78,6 +81,7 @@ static const struct {
{ X86_VENDOR_NSC,   "Geode by NSC", },
{ X86_VENDOR_SIS,   "SiS SiS SiS ", },
 };
+#endif
 
 static void load_ds(u32 segment)
 {
@@ -199,6 +203,7 @@ static inline int test_cyrix_52div(void)
return (unsigned char) (test >> 8) == 0x02;
 }
 
+#ifndef CONFIG_TPL_BUILD
 /*
  * Detect a NexGen CPU running without BIOS hypercode new enough
  * to have CPUID. (Thanks to Herbert Oppmann)
@@ -219,6 +224,7 @@ static int deep_magic_nexgen_probe(void)
: "=a" (ret) : : "cx", "dx");
return  ret;
 }
+#endif
 
 static bool has_cpuid(void)
 {
@@ -230,6 +236,7 @@ static bool has_mtrr(void)
return cpuid_edx(0x0001) & (1 << 12) ? true : false;
 }
 
+#ifndef CONFIG_TPL_BUILD
 static int build_vendor_name(char *vendor_name)
 {
struct cpuid_result result;
@@ -242,14 +249,40 @@ static int build_vendor_name(char *vendor_name)
 
return result.eax;
 }
+#endif
 
 static void identify_cpu(struct cpu_device_id *cpu)
 {
+   cpu->device = 0; /* fix gcc 4.4.4 warning */
+
+   /*
+* Do a quick and dirty check to save space - Intel and AMD only and
+* just the vendor. This is enough for most TPL code.
+*/
+   if (spl_phase() == PHASE_TPL) {
+   struct cpuid_result result;
+
+   result = cpuid(0x);
+   switch (result.ecx >> 24) {
+   case 'l': /* GenuineIntel */
+   cpu->vendor = X86_VENDOR_INTEL;
+   break;
+   case 'D': /* AuthenticAMD */
+   cpu->vendor = X86_VENDOR_AMD;
+   break;
+   default:
+   cpu->vendor = X86_VENDOR_ANY;
+   break;
+   }
+   return;
+   }
+
+/* gcc 7.3 does not want to drop x86_vendors, so use #ifdef */
+#ifndef CONFIG_TPL_BUILD
char vendor_name[16];
int i;
 
vendor_name[0] = '\0'; /* Unset */
-   cpu->device = 0; /* fix gcc 4.4.4 warning */
 
/* Find the id and vendor_name */
if (!has_cpuid()) {
@@ -265,9 +298,8 @@ static void identify_cpu(struct cpu_device_id *cpu)
/* Detect NexGen with old hypercode */
else if (deep_magic_nexgen_probe())
memcpy(vendor_name, "NexGenDriven", 13);
-   }
-   if (has_cpuid()) {
-   int  cpuid_level;
+   } else {
+   int cpuid_level;
 
cpuid_level = build_vendor_name(vendor_name);
vendor_name[12] = '\0';
@@ -287,6 +319,7 @@ static void identify_cpu(struct cpu_device_id *cpu)
break;
}
}
+#endif
 }
 
 static inline void get_fms(struct cpuinfo_x86 *c, uint32_t tfms)
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 014/102] RFC: sandbox: net: Suppress the MAC-address warnings

2019-12-06 Thread Simon Glass
These warnings appear every thing sandbox is run (see below) and dwarf the
actual useful output. Suppress them in two ways:

1. For the mismatch warnings, only set the ethaddr environment
variables when running tests.

2. For the 'MAC address from ROM' warning, never print this on sandbox.

Signed-off-by: Simon Glass 
---
Unfortunately this breaks the tests so is not applicable as is:

$ /tmp/b/sandbox/u-boot -T -c "ut dm eth_prime"

U-Boot 2019.10-00508-g95f6257285-dirty (Oct 13 2019 - 09:21:34 -0600)

Model: sandbox
DRAM:  128 MiB
WDT:   Started with servicing (60s timeout)
MMC:   mmc2: 2 (SD), mmc1: 1 (SD), mmc0: 0 (SD)
In:serial
Out:   vidconsole
Err:   vidconsole
Model: sandbox
SCSI:
Net:
Error: eth@10002000 address not set.
eth-1: eth@10002000
Error: eth@10003000 address not set.
, eth-1: eth@10003000
Error: sbe5 address not set.
, eth-1: sbe5
Error: eth@10004000 address not set.
, eth-1: eth@10004000
Test: dm_test_eth_prime: eth.c
Test: dm_test_eth_prime: eth.c (flat tree)
Failures: 0

Old output:

U-Boot 2019.10-rc2

Model: sandbox
DRAM:  128 MiB

Warning: host_lo MAC addresses don't match:
Address in ROM is  a6:28:b7:47:28:93
Address in environment is  00:00:11:22:33:44

Warning: host_enp5s0 MAC addresses don't match:
Address in ROM is  a6:28:b7:47:28:93
Address in environment is  00:00:11:22:33:45

Warning: host_eth6 using MAC address from ROM

Warning: host_docker0 MAC addresses don't match:
Address in ROM is  a6:28:b7:47:28:93
Address in environment is  00:00:11:22:33:46

Warning: host_docker_gwbridge using MAC address from ROM

Warning: host_veth1118e68 MAC addresses don't match:
Address in ROM is  a6:28:b7:47:28:93
Address in environment is  00:00:11:22:33:47
WDT:   Not found!
MMC:
In:cros-ec-keyb
Out:   vidconsole
Err:   vidconsole
Model: sandbox
SCSI:
Net:   eth0: host_lo, eth1: host_enp5s0, eth2: host_eth6, eth3: host_docker0, 
eth4: host_docker_gwbridge, eth5: host_veth1118e68
Error: eth@10002000 address not set.
, eth-1: eth@10002000
Test 'pmc_base' not found

Warning: host_lo MAC addresses don't match:
Address in ROM is  2a:24:9a:31:90:f8
Address in environment is  00:00:11:22:33:44

Warning: host_enp5s0 MAC addresses don't match:
Address in ROM is  ce:23:d9:74:6f:6c
Address in environment is  00:00:11:22:33:45

Warning: host_eth6 using MAC address from ROM

Warning: host_docker0 MAC addresses don't match:
Address in ROM is  ee:22:1c:3b:be:bc
Address in environment is  00:00:11:22:33:46

Warning: host_docker_gwbridge using MAC address from ROM

Warning: host_veth1118e68 MAC addresses don't match:
Address in ROM is  ae:20:9e:3d:a4:9f
Address in environment is  00:00:11:22:33:47

New output:
U-Boot 2019.10

Model: sandbox
DRAM:  128 MiB
WDT:   Not found!
MMC:
In:cros-ec-keyb
Out:   vidconsole
Err:   vidconsole
Model: sandbox
SCSI:
Net:   eth0: host_lo, eth1: host_enp5s0, eth2: host_eth6, eth3: host_docker0, 
eth4: host_docker_gwbridge, eth5: host_vethc7e1b9e
Error: eth@10002000 address not set.
, eth-1: eth@10002000
Hit any key to stop autoboot:  0
=>


Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3:
- Only supress the 'MAC address from ROM' warning on sandbox
- Set the environment variables at runtime to avoid other warnings

Changes in v2: None

 arch/sandbox/cpu/state.c | 12 ++--
 arch/sandbox/include/asm/state.h |  5 -
 cmd/nvedit.c |  8 
 include/configs/sandbox.h|  7 ++-
 include/env.h| 12 
 net/eth-uclass.c | 11 +--
 test/dm/test-main.c  |  2 +-
 7 files changed, 46 insertions(+), 11 deletions(-)

diff --git a/arch/sandbox/cpu/state.c b/arch/sandbox/cpu/state.c
index dee5fde4f7..70b278e4e2 100644
--- a/arch/sandbox/cpu/state.c
+++ b/arch/sandbox/cpu/state.c
@@ -351,7 +351,7 @@ bool state_get_skip_delays(void)
return state->skip_delays;
 }
 
-void state_reset_for_test(struct sandbox_state *state)
+void state_reset_for_test(struct sandbox_state *state, bool eth_vars)
 {
/* No reset yet, so mark it as such. Always allow power reset */
state->last_sysreset = SYSRESET_COUNT;
@@ -367,6 +367,14 @@ void state_reset_for_test(struct sandbox_state *state)
 */
INIT_LIST_HEAD(>mapmem_head);
state->next_tag = state->ram_size;
+
+   if (eth_vars) {
+   /* set up some environment variables needed by the eth tests */
+   env_set_for_test("ethaddr", "00:00:11:22:33:44");
+   env_set_for_test("eth1addr", "00:00:11:22:33:45");
+   env_set_for_test("eth3addr", "00:00:11:22:33:46");
+   env_set_for_test("eth5addr", "00:00:11:22:33:47");
+   }
 }
 
 int state_init(void)
@@ -377,7 +385,7 @@ int state_init(void)
state->ram_buf = os_malloc(state->ram_size);
assert(state->ram_buf);
 
-   state_reset_for_test(state);
+   

[PATCH v6 015/102] Revert "RFC: sandbox: net: Suppress the MAC-address warnings"

2019-12-06 Thread Simon Glass
This reverts commit 96ac4def8b6686de8566b91419ce98cd5765079b.

Signed-off-by: Simon Glass 
---

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

 arch/sandbox/cpu/state.c | 12 ++--
 arch/sandbox/include/asm/state.h |  5 +
 cmd/nvedit.c |  8 
 include/configs/sandbox.h|  7 +--
 include/env.h| 12 
 net/eth-uclass.c | 11 ++-
 test/dm/test-main.c  |  2 +-
 7 files changed, 11 insertions(+), 46 deletions(-)

diff --git a/arch/sandbox/cpu/state.c b/arch/sandbox/cpu/state.c
index 70b278e4e2..dee5fde4f7 100644
--- a/arch/sandbox/cpu/state.c
+++ b/arch/sandbox/cpu/state.c
@@ -351,7 +351,7 @@ bool state_get_skip_delays(void)
return state->skip_delays;
 }
 
-void state_reset_for_test(struct sandbox_state *state, bool eth_vars)
+void state_reset_for_test(struct sandbox_state *state)
 {
/* No reset yet, so mark it as such. Always allow power reset */
state->last_sysreset = SYSRESET_COUNT;
@@ -367,14 +367,6 @@ void state_reset_for_test(struct sandbox_state *state, 
bool eth_vars)
 */
INIT_LIST_HEAD(>mapmem_head);
state->next_tag = state->ram_size;
-
-   if (eth_vars) {
-   /* set up some environment variables needed by the eth tests */
-   env_set_for_test("ethaddr", "00:00:11:22:33:44");
-   env_set_for_test("eth1addr", "00:00:11:22:33:45");
-   env_set_for_test("eth3addr", "00:00:11:22:33:46");
-   env_set_for_test("eth5addr", "00:00:11:22:33:47");
-   }
 }
 
 int state_init(void)
@@ -385,7 +377,7 @@ int state_init(void)
state->ram_buf = os_malloc(state->ram_size);
assert(state->ram_buf);
 
-   state_reset_for_test(state, false);
+   state_reset_for_test(state);
/*
 * Example of how to use GPIOs:
 *
diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h
index 4fa3b094a9..ad3e94beb9 100644
--- a/arch/sandbox/include/asm/state.h
+++ b/arch/sandbox/include/asm/state.h
@@ -251,11 +251,8 @@ bool state_get_skip_delays(void);
  * state_reset_for_test() - Reset ready to re-run tests
  *
  * This clears out any test state ready for another test run.
- *
- * @param stateSandbox state to update
- * @param eth_vars Set environment variables for eth tests
  */
-void state_reset_for_test(struct sandbox_state *state, bool eth_vars);
+void state_reset_for_test(struct sandbox_state *state);
 
 /**
  * state_show() - Show information about the sandbox state
diff --git a/cmd/nvedit.c b/cmd/nvedit.c
index 746866b348..3420e0b985 100644
--- a/cmd/nvedit.c
+++ b/cmd/nvedit.c
@@ -300,14 +300,6 @@ static int _do_env_set(int flag, int argc, char * const 
argv[], int env_flag)
return 0;
 }
 
-int env_set_for_test(const char *varname, const char *value)
-{
-   const char * const argv[4] = { "setenv", varname, value, NULL };
-
-   assert(value);
-   return _do_env_set(0, 3, (char * const *)argv, 0);
-}
-
 int env_set(const char *varname, const char *varvalue)
 {
const char * const argv[4] = { "setenv", varname, varvalue, NULL };
diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h
index 0866cc3b63..1c13055cdc 100644
--- a/include/configs/sandbox.h
+++ b/include/configs/sandbox.h
@@ -96,8 +96,11 @@
"stderr=serial,vidconsole\0"
 #endif
 
-/* Note that some ethernet variables are set in state_reset_for_test() */
-#define SANDBOX_ETH_SETTINGS   "ipaddr=1.2.3.4\0"
+#define SANDBOX_ETH_SETTINGS   "ethaddr=00:00:11:22:33:44\0" \
+   "eth1addr=00:00:11:22:33:45\0" \
+   "eth3addr=00:00:11:22:33:46\0" \
+   "eth5addr=00:00:11:22:33:47\0" \
+   "ipaddr=1.2.3.4\0"
 
 #define MEM_LAYOUT_ENV_SETTINGS \
"bootm_size=0x1000\0" \
diff --git a/include/env.h b/include/env.h
index cad4338709..d6c2d751d6 100644
--- a/include/env.h
+++ b/include/env.h
@@ -155,18 +155,6 @@ int env_get_yesno(const char *var);
  */
 int env_set(const char *varname, const char *value);
 
-/**
- * env_set_for_test() - Set the value of a variable for testing
- *
- * This works as if the variable value was defined in the built-in environment,
- * so uses a flags value of 0. This should only be used in tests.
- *
- * @varname: Variable to adjust
- * @value: Value to set for the variable (cannot be NULL)
- * @return 0 if OK, 1 on error
- */
-int env_set_for_test(const char *varname, const char *value);
-
 /**
  * env_get_ulong() - Return an environment variable as an integer value
  *
diff --git a/net/eth-uclass.c b/net/eth-uclass.c
index 6c19536138..3bd98b01ad 100644
--- a/net/eth-uclass.c
+++ b/net/eth-uclass.c
@@ -485,12 +485,6 @@ static int 

[PATCH v6 017/102] x86: timer: Reduce timer code size in TPL on Intel CPUs

2019-12-06 Thread Simon Glass
Most of the timer-calibration methods are not needed on recent Intel CPUs
and just increase code size. Add an option to use the known-good way to
get the clock frequency in TPL. Size reduction is about 700 bytes.

Note that version 1 of this commit caused bootstage to crash since the CPU
was not identified. This is corrected by changes previously applied to
make sure that the CPU is identified before spl_init() is called, such as

   39146a2e0b x86: Move CPU init to before spl_init()

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

Changes in v6: None
Changes in v5: None
Changes in v4:
- Update commit message to indicate that CPU-identity bug is fixed

Changes in v3: None
Changes in v2: None

 drivers/timer/Kconfig | 9 +
 drivers/timer/tsc_timer.c | 7 +--
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
index 41f9755133..96cc49273f 100644
--- a/drivers/timer/Kconfig
+++ b/drivers/timer/Kconfig
@@ -188,6 +188,15 @@ config X86_TSC_READ_BASE
  The only exception is when U-Boot is used as a secondary bootloader,
  where this option should be enabled.
 
+config TPL_X86_TSC_TIMER_NATIVE
+   bool "x86 TSC timer uses native calibration"
+   depends on TPL && X86_TSC_TIMER
+   help
+ Selects native timer calibration for TPL and don't include the other
+ methods in the code. This helps to reduce code size in TPL and works
+ on fairly modern Intel chips. Code-size reductions is about 700
+ bytes.
+
 config MTK_TIMER
bool "MediaTek timer support"
depends on TIMER
diff --git a/drivers/timer/tsc_timer.c b/drivers/timer/tsc_timer.c
index 813817f467..43cb2d820e 100644
--- a/drivers/timer/tsc_timer.c
+++ b/drivers/timer/tsc_timer.c
@@ -50,8 +50,7 @@ static unsigned long native_calibrate_tsc(void)
return 0;
 
crystal_freq = tsc_info.ecx / 1000;
-
-   if (!crystal_freq) {
+   if (!CONFIG_IS_ENABLED(X86_TSC_TIMER_NATIVE) && !crystal_freq) {
switch (gd->arch.x86_model) {
case INTEL_FAM6_SKYLAKE_MOBILE:
case INTEL_FAM6_SKYLAKE_DESKTOP:
@@ -407,6 +406,10 @@ static void tsc_timer_ensure_setup(bool early)
if (fast_calibrate)
goto done;
 
+   /* Reduce code size by dropping other methods */
+   if (CONFIG_IS_ENABLED(X86_TSC_TIMER_NATIVE))
+   panic("no timer");
+
fast_calibrate = cpu_mhz_from_cpuid();
if (fast_calibrate)
goto done;
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 016/102] x86: timer: use a timer base of 0

2019-12-06 Thread Simon Glass
On x86 platforms the timer is reset to 0 when the SoC is reset. Having
this as the timer base is useful since it provides an indication of how
long it takes before U-Boot is running.

When U-Boot sets the timer base to something else, time is lost and we
no-longer have an accurate account of the time since reset. This
particularly affects bootstage.

Change the default to not read the timer base, leaving it at 0. Add an
option for when U-Boot is the secondary bootloader.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

Changes in v6: None
Changes in v5: None
Changes in v4:
- Enable option for slimbootloader, coreboot, efi
- Reverse the sense of the CONFIG option

Changes in v3: None
Changes in v2: None

 arch/x86/cpu/coreboot/Kconfig   |  1 +
 arch/x86/cpu/slimbootloader/Kconfig |  1 +
 drivers/timer/Kconfig   | 14 ++
 drivers/timer/tsc_timer.c   |  3 ++-
 lib/efi/Kconfig |  1 +
 5 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/arch/x86/cpu/coreboot/Kconfig b/arch/x86/cpu/coreboot/Kconfig
index 93f61f2fa4..c8e6a889d0 100644
--- a/arch/x86/cpu/coreboot/Kconfig
+++ b/arch/x86/cpu/coreboot/Kconfig
@@ -24,5 +24,6 @@ config SYS_COREBOOT
imply CMD_CBFS
imply FS_CBFS
imply CBMEM_CONSOLE
+   imply X86_TSC_READ_BASE
 
 endif
diff --git a/arch/x86/cpu/slimbootloader/Kconfig 
b/arch/x86/cpu/slimbootloader/Kconfig
index 3ea4c9958c..58a9ca01a9 100644
--- a/arch/x86/cpu/slimbootloader/Kconfig
+++ b/arch/x86/cpu/slimbootloader/Kconfig
@@ -17,3 +17,4 @@ config SYS_SLIMBOOTLOADER
imply USB_EHCI_HCD
imply USB_XHCI_HCD
imply E1000
+   imply X86_TSC_READ_BASE
diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
index 5f4bc6edb6..41f9755133 100644
--- a/drivers/timer/Kconfig
+++ b/drivers/timer/Kconfig
@@ -174,6 +174,20 @@ config X86_TSC_TIMER
help
  Select this to enable Time-Stamp Counter (TSC) timer for x86.
 
+config X86_TSC_READ_BASE
+   bool "Read the TSC timer base on start-up"
+   depends on X86_TSC_TIMER
+   help
+ On x86 platforms the TSC timer tick starts at the value 0 on reset.
+ This it makes no sense to read the timer on boot and use that as the
+ base, since we will miss some time taken to load U-Boot, etc. This
+ delay is controlled by the SoC and we cannot reduce it, but for
+ bootstage we want to record the time since reset as accurately as
+ possible.
+
+ The only exception is when U-Boot is used as a secondary bootloader,
+ where this option should be enabled.
+
 config MTK_TIMER
bool "MediaTek timer support"
depends on TIMER
diff --git a/drivers/timer/tsc_timer.c b/drivers/timer/tsc_timer.c
index 0df551f94c..813817f467 100644
--- a/drivers/timer/tsc_timer.c
+++ b/drivers/timer/tsc_timer.c
@@ -397,7 +397,8 @@ static void tsc_timer_ensure_setup(bool early)
 {
if (gd->arch.tsc_inited)
return;
-   gd->arch.tsc_base = rdtsc();
+   if (IS_ENABLED(CONFIG_X86_TSC_READ_BASE))
+   gd->arch.tsc_base = rdtsc();
 
if (!gd->arch.clock_rate) {
unsigned long fast_calibrate;
diff --git a/lib/efi/Kconfig b/lib/efi/Kconfig
index 919e314a0c..93b8564492 100644
--- a/lib/efi/Kconfig
+++ b/lib/efi/Kconfig
@@ -1,6 +1,7 @@
 config EFI
bool "Support running U-Boot from EFI"
depends on X86
+   imply X86_TSC_READ_BASE
help
  U-Boot can be started from EFI on certain platforms. This allows
  EFI to perform most of the system init and then jump to U-Boot for
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 013/102] board_r: Move early-timer init later

2019-12-06 Thread Simon Glass
At present the early timer init happens as soon as driver model is set up.
This makes it impossible to do anything that needs driver model but must
run before devices are probed (as needed with Intel's FSP-S, for example).

In any case it is not a good idea to tie probing of particular drivers too
closely to the DM init.

Create a new function to init the timer and put it a bit later in the
sequence.

Signed-off-by: Simon Glass 
---

Changes in v6: None
Changes in v5: None
Changes in v4:
- Add new patch to move early-timer init later

Changes in v3: None
Changes in v2: None

 common/board_r.c | 19 ++-
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/common/board_r.c b/common/board_r.c
index 9902c51c5e..9a25f6ec28 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -311,16 +311,24 @@ static int initr_dm(void)
bootstage_accum(BOOTSTATE_ID_ACCUM_DM_R);
if (ret)
return ret;
-#ifdef CONFIG_TIMER_EARLY
-   ret = dm_timer_init();
-   if (ret)
-   return ret;
-#endif
 
return 0;
 }
 #endif
 
+static int initr_dm_devices(void)
+{
+   int ret;
+
+   if (IS_ENABLED(CONFIG_TIMER_EARLY)) {
+   ret = dm_timer_init();
+   if (ret)
+   return ret;
+   }
+
+   return 0;
+}
+
 static int initr_bootstage(void)
 {
bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_R, "board_init_r");
@@ -707,6 +715,7 @@ static init_fnc_t init_sequence_r[] = {
efi_memory_init,
 #endif
initr_binman,
+   initr_dm_devices,
stdio_init_tables,
initr_serial,
initr_announce,
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 012/102] dm: pinctrl: Allow enabling full pinctrl in SPL/TPL

2019-12-06 Thread Simon Glass
At present these options cannot be enabled for SPL/TPL, but this can be
useful in some cases. Add Kconfig options to allow it.

Signed-off-by: Simon Glass 
---

Changes in v6:
- Split out Kconfig change to new patch to enable full pinctrl in SPL/TPL

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

 drivers/pinctrl/Kconfig | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index eadcfd6652..449f614eb2 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -82,6 +82,13 @@ config SPL_PINCTRL
  This option is an SPL-variant of the PINCTRL option.
  See the help of PINCTRL for details.
 
+config TPL_PINCTRL
+   bool "Support pin controllers in TPL"
+   depends on TPL && TPL_DM
+   help
+ This option is an TPL variant of the PINCTRL option.
+ See the help of PINCTRL for details.
+
 config SPL_PINCTRL_FULL
bool "Support full pin controllers in SPL"
depends on SPL_PINCTRL && SPL_OF_CONTROL
@@ -91,6 +98,13 @@ config SPL_PINCTRL_FULL
  This option is an SPL-variant of the PINCTRL_FULL option.
  See the help of PINCTRL_FULL for details.
 
+config TPL_PINCTRL_FULL
+   bool "Support full pin controllers in TPL"
+   depends on TPL_PINCTRL && TPL_OF_CONTROL
+   help
+ This option is an TPL-variant of the PINCTRL_FULL option.
+ See the help of PINCTRL_FULL for details.
+
 config SPL_PINCTRL_GENERIC
bool "Support generic pin controllers in SPL"
depends on SPL_PINCTRL_FULL
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 008/102] i2c: designware: Avoid using static data

2019-12-06 Thread Simon Glass
Drivers are not allowed to use static data since they may be used in SPL
where BSS is not available.

It is possible that driver model may provide support for numbering devices
in the future. But for now, move this to global_data.

Signed-off-by: Simon Glass 
---

Changes in v6: None
Changes in v5: None
Changes in v4:
- Add new patch to drop static data in designware i2c driver

Changes in v3: None
Changes in v2: None

 arch/x86/include/asm/global_data.h | 1 +
 drivers/i2c/designware_i2c_pci.c   | 9 ++---
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/global_data.h 
b/arch/x86/include/asm/global_data.h
index 7f3ada06f6..0e7b946205 100644
--- a/arch/x86/include/asm/global_data.h
+++ b/arch/x86/include/asm/global_data.h
@@ -96,6 +96,7 @@ struct arch_global_data {
ulong table;/* Table pointer from previous loader */
int turbo_state;/* Current turbo state */
struct irq_routing_table *pirq_routing_table;
+   int dw_i2c_num_cards;   /* Used by designware i2c driver */
 #ifdef CONFIG_SEABIOS
u32 high_table_ptr;
u32 high_table_limit;
diff --git a/drivers/i2c/designware_i2c_pci.c b/drivers/i2c/designware_i2c_pci.c
index e8fc6f2a90..8d6bb37f5c 100644
--- a/drivers/i2c/designware_i2c_pci.c
+++ b/drivers/i2c/designware_i2c_pci.c
@@ -34,7 +34,6 @@ static int designware_i2c_pci_probe(struct udevice *dev)
 
 static int designware_i2c_pci_bind(struct udevice *dev)
 {
-   static int num_cards;
char name[20];
 
/*
@@ -45,9 +44,13 @@ static int designware_i2c_pci_bind(struct udevice *dev)
 * using this driver is impossible for PCIe I2C devices.
 * This can be removed, once a better (correct) way for this
 * is found and implemented.
+*
+* TODO(s...@chromium.org): Perhaps if uclasses had platdata this would
+* be possible. We cannot use static data in drivers since they may be
+* used in SPL or before relocation.
 */
-   dev->req_seq = num_cards;
-   sprintf(name, "i2c_designware#%u", num_cards++);
+   dev->req_seq = gd->arch.dw_i2c_num_cards++;
+   sprintf(name, "i2c_designware#%u", dev->req_seq);
device_set_name(dev, name);
 
return 0;
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 009/102] i2c: designware: Support use in SPL

2019-12-06 Thread Simon Glass
Allow this driver to set up an IO address in SPL using an 'early-regs'
property. This allows SPL to use the I2C driver without having to enable
the full PCI stack.

Also split out ofdata_to_platdata in designware driver since this is more
correct, and more convenient for the new logic.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

Changes in v6:
- Move lpss_reset_release() to another commit

Changes in v5: None
Changes in v4:
- Add new patch to allow designware I2C driver to work in SPL

Changes in v3: None
Changes in v2: None

 drivers/i2c/designware_i2c_pci.c | 43 +---
 1 file changed, 40 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/designware_i2c_pci.c b/drivers/i2c/designware_i2c_pci.c
index 8d6bb37f5c..bb1f809af3 100644
--- a/drivers/i2c/designware_i2c_pci.c
+++ b/drivers/i2c/designware_i2c_pci.c
@@ -7,6 +7,7 @@
 
 #include 
 #include 
+#include 
 #include "designware_i2c.h"
 
 /* BayTrail HCNT/LCNT/SDA hold time */
@@ -18,17 +19,46 @@ static struct dw_scl_sda_cfg byt_config = {
.sda_hold = 0x6,
 };
 
-static int designware_i2c_pci_probe(struct udevice *dev)
+static int designware_i2c_pci_ofdata_to_platdata(struct udevice *dev)
 {
struct dw_i2c *priv = dev_get_priv(dev);
 
+   if (spl_phase() < PHASE_SPL) {
+   u32 base;
+   int ret;
+
+   ret = dev_read_u32(dev, "early-regs", );
+   if (ret)
+   return log_msg_ret("early-regs", ret);
+
+   /* Set i2c base address */
+   dm_pci_write_config32(dev, PCI_BASE_ADDRESS_0, base);
+
+   /* Enable memory access and bus master */
+   dm_pci_write_config32(dev, PCI_COMMAND, PCI_COMMAND_MEMORY |
+ PCI_COMMAND_MASTER);
+   }
+
+   if (spl_phase() < PHASE_BOARD_F) {
+   /* Handle early, fixed mapping into a different address space */
+   priv->regs = (struct i2c_regs *)dm_pci_read_bar32(dev, 0);
+   } else {
+   priv->regs = (struct i2c_regs *)
+   dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, PCI_REGION_MEM);
+   }
+   if (!priv->regs)
+   return -EINVAL;
+
/* Save base address from PCI BAR */
-   priv->regs = (struct i2c_regs *)
-   dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, PCI_REGION_MEM);
if (IS_ENABLED(CONFIG_INTEL_BAYTRAIL))
/* Use BayTrail specific timing values */
priv->scl_sda_cfg = _config;
 
+   return 0;
+}
+
+static int designware_i2c_pci_probe(struct udevice *dev)
+{
return designware_i2c_probe(dev);
 }
 
@@ -56,10 +86,17 @@ static int designware_i2c_pci_bind(struct udevice *dev)
return 0;
 }
 
+static const struct udevice_id designware_i2c_pci_ids[] = {
+   { .compatible = "snps,designware-i2c-pci" },
+   { }
+};
+
 U_BOOT_DRIVER(i2c_designware_pci) = {
.name   = "i2c_designware_pci",
.id = UCLASS_I2C,
+   .of_match = designware_i2c_pci_ids,
.bind   = designware_i2c_pci_bind,
+   .ofdata_to_platdata = designware_i2c_pci_ofdata_to_platdata,
.probe  = designware_i2c_pci_probe,
.priv_auto_alloc_size = sizeof(struct dw_i2c),
.remove = designware_i2c_remove,
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 010/102] x86: spi: Add helper functions for Intel Fast SPI

2019-12-06 Thread Simon Glass
Most x86 CPUs use a mechanism where the SPI flash is mapped into the very
top of 32-bit address space, so that it can be executed in place and read
simply by copying from memory. For an 8MB ROM the mapping starts at
0xff80.

However some recent Intel CPUs do not use a simple 1:1 memory map. Instead
the map starts at a different address and not all of the SPI flash is
accessible through the map. This 'Fast SPI' feature requires that U-Boot
check the location of the map. It is also possible (optionally) to read
from the SPI flash using a driver.

Add support for booting from Fast SPI. The memory-mapped version is used
by both TPL and SPL on Apollo Lake.

In respect of a SPI flash driver, the actual SPI driver is ich.c - this
just adds a few helper functions and definitions.

This is used by Apollo Lake.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3:
- Add support for of-platdata for TPL
- Add the missing header file
- Change Fast-SPI driver into a helper file used by ICH SPI
- Don't include write() and erase() in TPL
- Drop 'a4' comment for register offset
- Merge in patch "x86: Add support for booting from Fast SPI"
- Reorder file so that write() and erase() are together
- Use pci_get_devfn()

Changes in v2: None

 arch/x86/cpu/intel_common/Makefile   |  1 +
 arch/x86/cpu/intel_common/fast_spi.c | 73 
 arch/x86/include/asm/fast_spi.h  | 68 ++
 arch/x86/include/asm/spl.h   |  1 +
 4 files changed, 143 insertions(+)
 create mode 100644 arch/x86/cpu/intel_common/fast_spi.c
 create mode 100644 arch/x86/include/asm/fast_spi.h

diff --git a/arch/x86/cpu/intel_common/Makefile 
b/arch/x86/cpu/intel_common/Makefile
index 07f27c29ec..dfbc29f047 100644
--- a/arch/x86/cpu/intel_common/Makefile
+++ b/arch/x86/cpu/intel_common/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_$(SPL_TPL_)X86_32BIT_INIT) += report_platform.o
 obj-$(CONFIG_$(SPL_TPL_)X86_32BIT_INIT) += mrc.o
 endif
 obj-y += cpu.o
+obj-y += fast_spi.o
 obj-y += lpc.o
 ifndef CONFIG_TARGET_EFI_APP
 obj-$(CONFIG_$(SPL_TPL_)X86_32BIT_INIT) += microcode.o
diff --git a/arch/x86/cpu/intel_common/fast_spi.c 
b/arch/x86/cpu/intel_common/fast_spi.c
new file mode 100644
index 00..a6e3d0a5bf
--- /dev/null
+++ b/arch/x86/cpu/intel_common/fast_spi.c
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 Google LLC
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/*
+ * Returns bios_start and fills in size of the BIOS region.
+ */
+static ulong fast_spi_get_bios_region(struct fast_spi_regs *regs,
+ uint *bios_size)
+{
+   ulong bios_start, bios_end;
+
+   /*
+* BIOS_BFPREG provides info about BIOS-Flash Primary Region Base and
+* Limit. Base and Limit fields are in units of 4K.
+*/
+   u32 val = readl(>bfp);
+
+   bios_start = (val & SPIBAR_BFPREG_PRB_MASK) << 12;
+   bios_end = (((val & SPIBAR_BFPREG_PRL_MASK) >>
+SPIBAR_BFPREG_PRL_SHIFT) + 1) << 12;
+   *bios_size = bios_end - bios_start;
+
+   return bios_start;
+}
+
+int fast_spi_get_bios_mmap(pci_dev_t pdev, ulong *map_basep, uint *map_sizep,
+  uint *offsetp)
+{
+   struct fast_spi_regs *regs;
+   ulong bar, base, mmio_base;
+
+   /* Special case to find mapping without probing the device */
+   pci_x86_read_config(pdev, PCI_BASE_ADDRESS_0, , PCI_SIZE_32);
+   mmio_base = bar & PCI_BASE_ADDRESS_MEM_MASK;
+   regs = (struct fast_spi_regs *)mmio_base;
+   base = fast_spi_get_bios_region(regs, map_sizep);
+   *map_basep = (u32)-*map_sizep - base;
+   *offsetp = base;
+
+   return 0;
+}
+
+int fast_spi_early_init(pci_dev_t pdev, ulong mmio_base)
+{
+   /* Program Temporary BAR for SPI */
+   pci_x86_write_config(pdev, PCI_BASE_ADDRESS_0,
+mmio_base | PCI_BASE_ADDRESS_SPACE_MEMORY,
+PCI_SIZE_32);
+
+   /* Enable Bus Master and MMIO Space */
+   pci_x86_clrset_config(pdev, PCI_COMMAND, 0, PCI_COMMAND_MASTER |
+ PCI_COMMAND_MEMORY, PCI_SIZE_8);
+
+   /*
+* Disable the BIOS write protect so write commands are allowed.
+* Enable Prefetching and caching.
+*/
+   pci_x86_clrset_config(pdev, SPIBAR_BIOS_CONTROL,
+ SPIBAR_BIOS_CONTROL_EISS |
+ SPIBAR_BIOS_CONTROL_CACHE_DISABLE,
+ SPIBAR_BIOS_CONTROL_WPD |
+ SPIBAR_BIOS_CONTROL_PREFETCH_ENABLE, PCI_SIZE_8);
+
+   return 0;
+}
diff --git a/arch/x86/include/asm/fast_spi.h b/arch/x86/include/asm/fast_spi.h
new file mode 100644
index 00..6894298526
--- /dev/null
+++ b/arch/x86/include/asm/fast_spi.h
@@ -0,0 +1,68 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 

[PATCH v6 011/102] fdt: Show the preprocessed .dts file on error

2019-12-06 Thread Simon Glass
When device-tree compilation fails it is sometimes tricky to see which
line is broken, since the input file to dtc is a pre-processed version
of the device tree.

Add a line that points to the file that needs to be checked:

When the error is in the main .dts file, output is something like this:

   output: 'Error: arch/x86/dts/.chromebook_coral.dtb.pre.tmp:478.46-47
syntax error
   FATAL ERROR: Unable to parse input tree

but in fact looking at that file shows nothing useful:

   PAD_CFG_NF_IOSSTATE_IOSTERM(GPIO_157, UP_20K, DEEP, NF1, HIZCRX1, DISPUPD)

Instead we need to look at the preprocessed file, which shows:

   163 ((1U << 30) | (1 << 10)) ((0xb << 10) | PAD_CFG1_IOSSTATE_HIZCRX1)

Here it is clear that PAD_CFG1_IOSSTATE_HIZCRX1 is not defined and so is
not being resolved by the preprocessor.

This commit adds an additional useful message:

   Check arch/x86/dts/.chromebook_coral.dtb.dts.tmp for errors

Note that if the error is reported in an included file, such as
u-boot.dtsi then the output is the following:

   Error: arch/x86/dts/u-boot.dtsi:137.14-15 syntax error
   FATAL ERROR: Unable to parse input tree

But again, if the error is due to a preprocessor failure, like this:

   filename = CONFIG_IFW_INPUT_FILE;

then you can't tell what the problem is by looking at the source. All you
see is the original code:

intel-ifwi {
filename = CONFIG_IFW_INPUT_FILE;
...
};
};
intel-fsp-m {
filename = CONFIG_FSP_FILE_M;
};

Everything looks fine. But looking at the output of the preprocessor:

 intel-ifwi {
  filename = CONFIG_IFW_INPUT_FILE;
  ...
 };
 intel-fsp-m {
  filename = "fsp_m.bin";
 };

This shows that the filename (normally "fitimage.bin") has not been
inserted the preprocess, leading to the realisation that the value should
be CONFIG_IFWI_INPUT_FILE.

If the above does not make sense, I encourage people to try introducing
errors in the device tree preprocessed values.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

Changes in v6: None
Changes in v5: None
Changes in v4:
- One last desperate attempt to try to explain the purpose of this commit
- Update the message to mention the preprocessed file, not un-preprocessed

Changes in v3:
- Update example error message to better show the intended purpose

Changes in v2: None

 scripts/Makefile.lib | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index ef116e0e0a..c10cd83a0a 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -300,7 +300,9 @@ cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \
$(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $(pre-tmp) 
; \
$(DTC) -O dtb -o $@ -b 0 \
-i $(dir $<) $(DTC_FLAGS) \
-   -d $(depfile).dtc.tmp $(dtc-tmp) ; \
+   -d $(depfile).dtc.tmp $(dtc-tmp) || \
+   (echo "Check $(shell pwd)/$(pre-tmp) for errors" && false) \
+   ; \
cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile) ; \
sed -i "s:$(pre-tmp):$(<):" $(depfile)
 
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 007/102] i2c: designware: Tidy up PCI support

2019-12-06 Thread Simon Glass
This is hacked into the driver at present. It seems better to have it as
a separate driver that uses the base driver. Create a new file and put
the X86 code into it.

Actually the Baytrail settings should really come from the device tree.

Note that 'has_max_speed' is added as well. This is currently always false
but since only Baytrail provides the config, it does not affect operation
for other devices.

Signed-off-by: Simon Glass 
Reviewed-by: Heiko Schocher 
---

Changes in v6:
- Drop unwanted space before comma

Changes in v5: None
Changes in v4:
- Add a comment about the speed logic in __dw_i2c_set_bus_speed()
- Add a comment in the commit message about why has_max_speed is added
- Drop unwanted debug printf("bad\n")
- Fix indentation nit
- Rename new file to designware_i2c_pci.c

Changes in v3: None
Changes in v2: None

 drivers/i2c/Makefile |   3 +
 drivers/i2c/designware_i2c.c | 106 +--
 drivers/i2c/designware_i2c.h |  35 ++
 drivers/i2c/designware_i2c_pci.c |  79 +++
 4 files changed, 134 insertions(+), 89 deletions(-)
 create mode 100644 drivers/i2c/designware_i2c_pci.c

diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index c2f75d8755..f5a471f887 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -14,6 +14,9 @@ obj-$(CONFIG_SYS_I2C_AT91) += at91_i2c.o
 obj-$(CONFIG_SYS_I2C_CADENCE) += i2c-cdns.o
 obj-$(CONFIG_SYS_I2C_DAVINCI) += davinci_i2c.o
 obj-$(CONFIG_SYS_I2C_DW) += designware_i2c.o
+ifdef CONFIG_DM_PCI
+obj-$(CONFIG_SYS_I2C_DW) += designware_i2c_pci.o
+endif
 obj-$(CONFIG_SYS_I2C_FSL) += fsl_i2c.o
 obj-$(CONFIG_SYS_I2C_IHS) += ihs_i2c.o
 obj-$(CONFIG_SYS_I2C_INTEL) += intel_i2c.o
diff --git a/drivers/i2c/designware_i2c.c b/drivers/i2c/designware_i2c.c
index 6daa90e744..b8cdd1c661 100644
--- a/drivers/i2c/designware_i2c.c
+++ b/drivers/i2c/designware_i2c.c
@@ -13,34 +13,6 @@
 #include 
 #include "designware_i2c.h"
 
-struct dw_scl_sda_cfg {
-   u32 ss_hcnt;
-   u32 fs_hcnt;
-   u32 ss_lcnt;
-   u32 fs_lcnt;
-   u32 sda_hold;
-};
-
-#ifdef CONFIG_X86
-/* BayTrail HCNT/LCNT/SDA hold time */
-static struct dw_scl_sda_cfg byt_config = {
-   .ss_hcnt = 0x200,
-   .fs_hcnt = 0x55,
-   .ss_lcnt = 0x200,
-   .fs_lcnt = 0x99,
-   .sda_hold = 0x6,
-};
-#endif
-
-struct dw_i2c {
-   struct i2c_regs *regs;
-   struct dw_scl_sda_cfg *scl_sda_cfg;
-   struct reset_ctl_bulk resets;
-#if CONFIG_IS_ENABLED(CLK)
-   struct clk clk;
-#endif
-};
-
 #ifdef CONFIG_SYS_I2C_DW_ENABLE_STATUS_UNSUPPORTED
 static int  dw_i2c_enable(struct i2c_regs *i2c_base, bool enable)
 {
@@ -90,7 +62,9 @@ static unsigned int __dw_i2c_set_bus_speed(struct i2c_regs 
*i2c_base,
unsigned int ena;
int i2c_spd;
 
-   if (speed >= I2C_MAX_SPEED)
+   /* Allow max speed if there is no config, or the config allows it */
+   if (speed >= I2C_MAX_SPEED &&
+   (!scl_sda_cfg || scl_sda_cfg->has_max_speed))
i2c_spd = IC_SPEED_MODE_MAX;
else if (speed >= I2C_FAST_SPEED)
i2c_spd = IC_SPEED_MODE_FAST;
@@ -106,7 +80,6 @@ static unsigned int __dw_i2c_set_bus_speed(struct i2c_regs 
*i2c_base,
cntl = (readl(_base->ic_con) & (~IC_CON_SPD_MSK));
 
switch (i2c_spd) {
-#ifndef CONFIG_X86 /* No High-speed for BayTrail yet */
case IC_SPEED_MODE_MAX:
cntl |= IC_CON_SPD_SS;
if (scl_sda_cfg) {
@@ -119,7 +92,6 @@ static unsigned int __dw_i2c_set_bus_speed(struct i2c_regs 
*i2c_base,
writel(hcnt, _base->ic_hs_scl_hcnt);
writel(lcnt, _base->ic_hs_scl_lcnt);
break;
-#endif
 
case IC_SPEED_MODE_STANDARD:
cntl |= IC_CON_SPD_SS;
@@ -565,24 +537,19 @@ static int designware_i2c_probe_chip(struct udevice *bus, 
uint chip_addr,
return ret;
 }
 
-static int designware_i2c_probe(struct udevice *bus)
+static int designware_i2c_ofdata_to_platdata(struct udevice *bus)
 {
struct dw_i2c *priv = dev_get_priv(bus);
-   int ret;
 
-   if (device_is_on_pci_bus(bus)) {
-#ifdef CONFIG_DM_PCI
-   /* Save base address from PCI BAR */
-   priv->regs = (struct i2c_regs *)
-   dm_pci_map_bar(bus, PCI_BASE_ADDRESS_0, PCI_REGION_MEM);
-#ifdef CONFIG_X86
-   /* Use BayTrail specific timing values */
-   priv->scl_sda_cfg = _config;
-#endif
-#endif
-   } else {
-   priv->regs = (struct i2c_regs *)devfdt_get_addr_ptr(bus);
-   }
+   priv->regs = (struct i2c_regs *)devfdt_get_addr_ptr(bus);
+
+   return 0;
+}
+
+int designware_i2c_probe(struct udevice *bus)
+{
+   struct dw_i2c *priv = dev_get_priv(bus);
+   int ret;
 
ret = reset_get_bulk(bus, >resets);
if (ret)
@@ -606,7 +573,7 @@ static int designware_i2c_probe(struct udevice *bus)
return __dw_i2c_init(priv->regs, 0, 0);
 }
 
-static int 

[PATCH v6 006/102] net: Move the checksum functions to lib/

2019-12-06 Thread Simon Glass
These functions are used by code outside the network support, so move them
to lib/ to be more accessible.

Without this, the functions are only accessible in SPL/TPL only if
CONFIG_SPL/TPL_NET are defined. Many boards do not enable those option but
still want to do checksums in this format.

Fix up a few code-style nits while we are here.

Signed-off-by: Simon Glass 
Acked-by: Joe Hershberger 
---

Changes in v6:
- Expand commit message to mention SPL/TPL specifically

Changes in v5: None
Changes in v4:
- Expand commit message to better explain the need to checksum functions

Changes in v3: None
Changes in v2: None

 lib/Makefile|  2 +-
 lib/net_utils.c | 48 
 net/Makefile|  1 -
 net/checksum.c  | 59 -
 4 files changed, 49 insertions(+), 61 deletions(-)
 delete mode 100644 net/checksum.c

diff --git a/lib/Makefile b/lib/Makefile
index 7a713a54dc..6b7b9ce85c 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -78,7 +78,7 @@ endif
 ifdef CONFIG_SPL_BUILD
 obj-$(CONFIG_SPL_YMODEM_SUPPORT) += crc16.o
 obj-$(CONFIG_$(SPL_TPL_)HASH_SUPPORT) += crc16.o
-obj-$(CONFIG_SPL_NET_SUPPORT) += net_utils.o
+obj-y += net_utils.o
 endif
 obj-$(CONFIG_ADDR_MAP) += addr_map.o
 obj-y += qsort.o
diff --git a/lib/net_utils.c b/lib/net_utils.c
index 9fb9d4a4b0..252290210f 100644
--- a/lib/net_utils.c
+++ b/lib/net_utils.c
@@ -41,3 +41,51 @@ struct in_addr string_to_ip(const char *s)
addr.s_addr = htonl(addr.s_addr);
return addr;
 }
+
+uint compute_ip_checksum(const void *vptr, uint nbytes)
+{
+   int sum, oddbyte;
+   const unsigned short *ptr = vptr;
+
+   sum = 0;
+   while (nbytes > 1) {
+   sum += *ptr++;
+   nbytes -= 2;
+   }
+   if (nbytes == 1) {
+   oddbyte = 0;
+   ((u8 *))[0] = *(u8 *)ptr;
+   ((u8 *))[1] = 0;
+   sum += oddbyte;
+   }
+   sum = (sum >> 16) + (sum & 0x);
+   sum += (sum >> 16);
+   sum = ~sum & 0x;
+
+   return sum;
+}
+
+uint add_ip_checksums(uint offset, uint sum, uint new)
+{
+   ulong checksum;
+
+   sum = ~sum & 0x;
+   new = ~new & 0x;
+   if (offset & 1) {
+   /*
+* byte-swap the sum if it came from an odd offset; since the
+* computation is endian-independent this works.
+*/
+   new = ((new >> 8) & 0xff) | ((new << 8) & 0xff00);
+   }
+   checksum = sum + new;
+   if (checksum > 0x)
+   checksum -= 0x;
+
+   return (~checksum) & 0x;
+}
+
+int ip_checksum_ok(const void *addr, uint nbytes)
+{
+   return !(compute_ip_checksum(addr, nbytes) & 0xfffe);
+}
diff --git a/net/Makefile b/net/Makefile
index 2a700c8401..fef71b940a 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -5,7 +5,6 @@
 
 #ccflags-y += -DDEBUG
 
-obj-y += checksum.o
 obj-$(CONFIG_NET)  += arp.o
 obj-$(CONFIG_CMD_BOOTP) += bootp.o
 obj-$(CONFIG_CMD_CDP)  += cdp.o
diff --git a/net/checksum.c b/net/checksum.c
deleted file mode 100644
index 16ef416356..00
--- a/net/checksum.c
+++ /dev/null
@@ -1,59 +0,0 @@
-// SPDX-License-Identifier: BSD-2-Clause
-/*
- * This file was originally taken from the FreeBSD project.
- *
- * Copyright (c) 2001 Charles Mott 
- * Copyright (c) 2008 coresystems GmbH
- * All rights reserved.
- */
-
-#include 
-#include 
-
-unsigned compute_ip_checksum(const void *vptr, unsigned nbytes)
-{
-   int sum, oddbyte;
-   const unsigned short *ptr = vptr;
-
-   sum = 0;
-   while (nbytes > 1) {
-   sum += *ptr++;
-   nbytes -= 2;
-   }
-   if (nbytes == 1) {
-   oddbyte = 0;
-   ((u8 *))[0] = *(u8 *)ptr;
-   ((u8 *))[1] = 0;
-   sum += oddbyte;
-   }
-   sum = (sum >> 16) + (sum & 0x);
-   sum += (sum >> 16);
-   sum = ~sum & 0x;
-
-   return sum;
-}
-
-unsigned add_ip_checksums(unsigned offset, unsigned sum, unsigned new)
-{
-   unsigned long checksum;
-
-   sum = ~sum & 0x;
-   new = ~new & 0x;
-   if (offset & 1) {
-   /*
-* byte-swap the sum if it came from an odd offset; since the
-* computation is endian independant this works.
-*/
-   new = ((new >> 8) & 0xff) | ((new << 8) & 0xff00);
-   }
-   checksum = sum + new;
-   if (checksum > 0x)
-   checksum -= 0x;
-
-   return (~checksum) & 0x;
-}
-
-int ip_checksum_ok(const void *addr, unsigned nbytes)
-{
-   return !(compute_ip_checksum(addr, nbytes) & 0xfffe);
-}
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 005/102] dm: pci: Move pci_get_devfn() into a common file

2019-12-06 Thread Simon Glass
Early in boot it is necessary to decode the PCI device/function values for
particular peripherals in the device tree or of-platdata. This is needed
in TPL where CONFIG_PCI is not defined.

To handle this, move pci_get_devfn() into a file that is built even when
CONFIG_PCI is not defined.

Also add a function for use by of-platdata, to convert a reg property to
a pci_dev_t.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

Changes in v6:
- Rename pci_x86_ofplat_get_devfn() to pci_ofplat_get_devfn() in comment

Changes in v5: None
Changes in v4:
- Add more documentation for pci_ofplat_get_devfn()
- Mention that the return value is pci_dev_t
- Rename pci_x86_ofplat_get_devfn() to pci_ofplat_get_devfn()

Changes in v3:
- Move the function to a common file instead of duplicating it
- Update device type to pci_dev_t

Changes in v2: None

 drivers/core/util.c  | 20 +++
 drivers/pci/pci-uclass.c | 16 ---
 include/dm/pci.h | 43 
 include/pci.h| 12 ++-
 4 files changed, 65 insertions(+), 26 deletions(-)
 create mode 100644 include/dm/pci.h

diff --git a/drivers/core/util.c b/drivers/core/util.c
index 7dc1a2af02..69f83755f0 100644
--- a/drivers/core/util.c
+++ b/drivers/core/util.c
@@ -4,7 +4,9 @@
  */
 
 #include 
+#include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -58,3 +60,21 @@ bool dm_ofnode_pre_reloc(ofnode node)
 #endif
 }
 #endif
+
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
+int pci_get_devfn(struct udevice *dev)
+{
+   struct fdt_pci_addr addr;
+   int ret;
+
+   /* Extract the devfn from fdt_pci_addr */
+   ret = ofnode_read_pci_addr(dev_ofnode(dev), FDT_PCI_SPACE_CONFIG,
+  "reg", );
+   if (ret) {
+   if (ret != -ENOENT)
+   return -EINVAL;
+   }
+
+   return addr.phys_hi & 0xff00;
+}
+#endif
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
index 8e13adb156..7308f612b6 100644
--- a/drivers/pci/pci-uclass.c
+++ b/drivers/pci/pci-uclass.c
@@ -1023,22 +1023,6 @@ static int pci_uclass_post_probe(struct udevice *bus)
return 0;
 }
 
-int pci_get_devfn(struct udevice *dev)
-{
-   struct fdt_pci_addr addr;
-   int ret;
-
-   /* Extract the devfn from fdt_pci_addr */
-   ret = ofnode_read_pci_addr(dev_ofnode(dev), FDT_PCI_SPACE_CONFIG,
-  "reg", );
-   if (ret) {
-   if (ret != -ENOENT)
-   return -EINVAL;
-   }
-
-   return addr.phys_hi & 0xff00;
-}
-
 static int pci_uclass_child_post_bind(struct udevice *dev)
 {
struct pci_child_platdata *pplat;
diff --git a/include/dm/pci.h b/include/dm/pci.h
new file mode 100644
index 00..10f9fd9e37
--- /dev/null
+++ b/include/dm/pci.h
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2019 Google, Inc
+ */
+
+#ifndef __DM_PCI_H
+#define __DM_PCI_H
+
+struct udevice;
+
+/**
+ * pci_get_devfn() - Extract the devfn from fdt_pci_addr of the device
+ *
+ * Get devfn from fdt_pci_addr of the specified device
+ *
+ * This returns an int to avoid a dependency on pci.h
+ *
+ * @dev:   PCI device
+ * @return devfn in bits 15...8 if found (pci_dev_t format), or -ENODEV if not
+ * found
+ */
+int pci_get_devfn(struct udevice *dev);
+
+/**
+ * pci_ofplat_get_devfn() - Get the PCI dev/fn from of-platdata
+ *
+ * This function is used to obtain a PCI device/function from of-platdata
+ * register data. In this case the first cell of the 'reg' property contains
+ * the required information.
+ *
+ * This returns an int to avoid a dependency on pci.h
+ *
+ * @reg: reg value from dt-platdata.c array (first member). This is not a
+ * pointer type, since the caller may use fdt32_t or fdt64_t depending on
+ * the address sizes.
+ * @return device/function for that device (pci_dev_t format)
+ */
+static inline int pci_ofplat_get_devfn(u32 reg)
+{
+   return reg & 0xff00;
+}
+
+#endif
diff --git a/include/pci.h b/include/pci.h
index de17d0ffba..8c761d8da3 100644
--- a/include/pci.h
+++ b/include/pci.h
@@ -482,6 +482,8 @@
 
 #ifndef __ASSEMBLY__
 
+#include 
+
 #ifdef CONFIG_SYS_PCI_64BIT
 typedef u64 pci_addr_t;
 typedef u64 pci_size_t;
@@ -1619,16 +1621,6 @@ int sandbox_pci_get_emul(struct udevice *bus, pci_dev_t 
find_devfn,
  */
 int sandbox_pci_get_client(struct udevice *emul, struct udevice **devp);
 
-/**
- * pci_get_devfn() - Extract the devfn from fdt_pci_addr of the device
- *
- * Get devfn from fdt_pci_addr of the specified device
- *
- * @dev:   PCI device
- * @return devfn in bits 15...8 if found, -ENODEV if not found
- */
-int pci_get_devfn(struct udevice *dev);
-
 #endif /* CONFIG_DM_PCI */
 
 /**
-- 
2.24.0.393.g34dc348eaf-goog



[PATCH v6 002/102] dm: gpio: Allow control of GPIO uclass in SPL

2019-12-06 Thread Simon Glass
At present if CONFIG_SPL_GPIO_SUPPORT is enabled then the GPIO uclass
is included in SPL/TPL without any control for boards. Some boards may
want to disable this to reduce code size where GPIOs are not needed in
SPL or TPL.

Add a new Kconfig option to permit this. Default it to 'y' so that
existing boards work correctly.

Change existing uses of CONFIG_DM_GPIO to CONFIG_IS_ENABLED(DM_GPIO) to
preserve the current behaviour. Also update the 74x164 GPIO driver since
it cannot build with SPL.

This allows us to remove the hacks in config_uncmd_spl.h and
Makefile.uncmd_spl (eventually those files should be removed).

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 

---

Changes in v6: None
Changes in v5: None
Changes in v4:
- Disable SPL_DM_GPIO on omap35_logic to avoid a build error

Changes in v3: None
Changes in v2:
- Fix the Kconfig condition to avoid build errors on snow

 arch/arm/include/asm/omap_gpio.h  |  2 +-
 arch/arm/mach-at91/include/mach/at91sam9260.h |  2 +-
 arch/arm/mach-davinci/include/mach/gpio.h |  2 +-
 arch/arm/mach-omap2/am33xx/board.c|  4 ++--
 arch/arm/mach-omap2/omap3/board.c |  2 +-
 arch/arm/mach-omap2/omap5/hwinit.c|  2 +-
 board/freescale/imx8qm_mek/imx8qm_mek.c   |  2 +-
 board/freescale/imx8qxp_mek/imx8qxp_mek.c |  2 +-
 board/gateworks/gw_ventana/Kconfig|  3 +++
 board/toradex/apalis-imx8/apalis-imx8.c   |  2 +-
 configs/omap35_logic_defconfig|  1 +
 drivers/gpio/Kconfig  | 22 +++
 drivers/gpio/Makefile |  4 +++-
 drivers/gpio/at91_gpio.c  |  6 ++---
 drivers/gpio/atmel_pio4.c |  2 +-
 drivers/gpio/da8xx_gpio.c |  7 +++---
 drivers/gpio/da8xx_gpio.h |  2 +-
 drivers/gpio/mxc_gpio.c   |  4 ++--
 drivers/gpio/mxs_gpio.c   |  4 ++--
 drivers/gpio/omap_gpio.c  |  6 ++---
 drivers/gpio/sunxi_gpio.c |  8 +++
 drivers/i2c/i2c-uclass.c  |  6 ++---
 drivers/i2c/muxes/pca954x.c   |  4 ++--
 drivers/mmc/fsl_esdhc_imx.c   | 13 ++-
 drivers/mmc/omap_hsmmc.c  |  2 +-
 drivers/net/designware.c  | 10 -
 drivers/net/designware.h  |  4 ++--
 drivers/net/fec_mxc.c |  6 ++---
 drivers/net/fec_mxc.h |  2 +-
 drivers/net/mvneta.c  |  4 ++--
 drivers/net/mvpp2.c   |  8 +++
 drivers/net/sun8i_emac.c  | 12 +-
 drivers/pci/pci-aardvark.c|  4 ++--
 drivers/pci/pcie_dw_mvebu.c   |  4 ++--
 drivers/spi/atmel_spi.c   | 10 -
 drivers/spi/designware_spi.c  |  4 ++--
 drivers/tpm/tpm2_tis_spi.c|  2 +-
 include/config_uncmd_spl.h|  1 -
 include/configs/at91-sama5_common.h   |  5 +++--
 include/configs/gw_ventana.h  |  1 -
 include/configs/mx6ul_14x14_evk.h |  1 +
 scripts/Makefile.uncmd_spl|  1 -
 42 files changed, 111 insertions(+), 82 deletions(-)

diff --git a/arch/arm/include/asm/omap_gpio.h b/arch/arm/include/asm/omap_gpio.h
index 20268fa084..151afa8f44 100644
--- a/arch/arm/include/asm/omap_gpio.h
+++ b/arch/arm/include/asm/omap_gpio.h
@@ -22,7 +22,7 @@
 
 #include 
 
-#ifdef CONFIG_DM_GPIO
+#if CONFIG_IS_ENABLED(DM_GPIO)
 
 /* Information about a GPIO bank */
 struct omap_gpio_platdata {
diff --git a/arch/arm/mach-at91/include/mach/at91sam9260.h 
b/arch/arm/mach-at91/include/mach/at91sam9260.h
index 91faf729ae..2daeb4fef8 100644
--- a/arch/arm/mach-at91/include/mach/at91sam9260.h
+++ b/arch/arm/mach-at91/include/mach/at91sam9260.h
@@ -133,7 +133,7 @@
 /*
  * Other misc defines
  */
-#ifndef CONFIG_DM_GPIO
+#if !CONFIG_IS_ENABLED(DM_GPIO)
 #define ATMEL_PIO_PORTS3   /* these SoCs have 3 
PIO */
 #define ATMEL_BASE_PIO ATMEL_BASE_PIOA
 #endif
diff --git a/arch/arm/mach-davinci/include/mach/gpio.h 
b/arch/arm/mach-davinci/include/mach/gpio.h
index c150240962..e5a4053414 100644
--- a/arch/arm/mach-davinci/include/mach/gpio.h
+++ b/arch/arm/mach-davinci/include/mach/gpio.h
@@ -18,7 +18,7 @@
 #define davinci_gpio_bank67 ((struct davinci_gpio *)DAVINCI_GPIO_BANK67)
 #define davinci_gpio_bank8 ((struct davinci_gpio *)DAVINCI_GPIO_BANK8)
 
-#ifndef CONFIG_DM_GPIO
+#if !CONFIG_IS_ENABLED(DM_GPIO)
 #define gpio_status()  gpio_info()
 #endif
 #define GPIO_NAME_SIZE 20
diff --git a/arch/arm/mach-omap2/am33xx/board.c 
b/arch/arm/mach-omap2/am33xx/board.c
index 03460c3eb7..e64942b716 100644
--- a/arch/arm/mach-omap2/am33xx/board.c
+++ b/arch/arm/mach-omap2/am33xx/board.c
@@ -116,7 +116,7 @@ U_BOOT_DEVICES(am33xx_i2c) = {
 };
 

[PATCH v6 004/102] dm: pci: Allow delaying auto-config until after relocation

2019-12-06 Thread Simon Glass
At present PCI auto-configuration happens in U-Boot both before and after
relocation. This is a waste of time and may mess up static addresses used
in board_init_f(). Adjust the code to supporting doing auto-configuration
once, after relocation, under control of a device-tree property.

This is needed for Apollo Lake for debugging the silicon-init code. Once
the UART is moved to a different MMIO address the debug UART does not work
and any debug output in Apollo Lake's arch_fsp_init_r() causes a hang.

Signed-off-by: Simon Glass 
Reviewed-by: Bin Meng 
---

Changes in v6: None
Changes in v5: None
Changes in v4:
- Change the behaviour to be a device-tree option
- apollolake -> Apollo Lake

Changes in v3: None
Changes in v2: None

 doc/device-tree-bindings/pci/x86-pci.txt | 24 
 drivers/pci/pci-uclass.c | 15 ++-
 include/pci.h|  9 -
 3 files changed, 42 insertions(+), 6 deletions(-)
 create mode 100644 doc/device-tree-bindings/pci/x86-pci.txt

diff --git a/doc/device-tree-bindings/pci/x86-pci.txt 
b/doc/device-tree-bindings/pci/x86-pci.txt
new file mode 100644
index 00..3aa5bd9a46
--- /dev/null
+++ b/doc/device-tree-bindings/pci/x86-pci.txt
@@ -0,0 +1,24 @@
+x86 PCI DT details:
+===
+
+Some options are available to affect how PCI operates on x86.
+
+Optional properties:
+- u-boot,skip-auto-config-until-reloc : Don't set up PCI configuration until
+   after U-Boot has relocated. Normally if PCI is used before relocation,
+   this happens before relocation also. Some platforms set up static
+   configuration in TPL/SPL to reduce code size and boot time, since these
+   phases only know about a small subset of PCI devices.
+
+Example:
+
+pci {
+   compatible = "pci-x86";
+   #address-cells = <3>;
+   #size-cells = <2>;
+   u-boot,dm-pre-reloc;
+   ranges = <0x0200 0x0 0xc000 0xc000 0 0x1000
+   0x4200 0x0 0xb000 0xb000 0 0x1000
+   0x0100 0x0 0x1000 0x1000 0 0xefff>;
+   u-boot,skip-auto-config-until-reloc;
+};
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
index fab20fc60e..8e13adb156 100644
--- a/drivers/pci/pci-uclass.c
+++ b/drivers/pci/pci-uclass.c
@@ -975,12 +975,15 @@ static int pci_uclass_pre_probe(struct udevice *bus)
hose->bus = bus;
hose->first_busno = bus->seq;
hose->last_busno = bus->seq;
+   hose->skip_auto_config_until_reloc =
+   dev_read_bool(bus, "u-boot,skip-auto-config-until-reloc");
 
return 0;
 }
 
 static int pci_uclass_post_probe(struct udevice *bus)
 {
+   struct pci_controller *hose = dev_get_uclass_priv(bus);
int ret;
 
debug("%s: probing bus %d\n", __func__, bus->seq);
@@ -988,11 +991,13 @@ static int pci_uclass_post_probe(struct udevice *bus)
if (ret)
return ret;
 
-#if CONFIG_IS_ENABLED(PCI_PNP)
-   ret = pci_auto_config_devices(bus);
-   if (ret < 0)
-   return ret;
-#endif
+   if (CONFIG_IS_ENABLED(PCI_PNP) &&
+   (!hose->skip_auto_config_until_reloc ||
+(gd->flags & GD_FLG_RELOC))) {
+   ret = pci_auto_config_devices(bus);
+   if (ret < 0)
+   return log_msg_ret("pci auto-config", ret);
+   }
 
 #if defined(CONFIG_X86) && defined(CONFIG_HAVE_FSP)
/*
diff --git a/include/pci.h b/include/pci.h
index ff59ac0e69..de17d0ffba 100644
--- a/include/pci.h
+++ b/include/pci.h
@@ -571,15 +571,22 @@ extern void pci_cfgfunc_config_device(struct 
pci_controller* hose, pci_dev_t dev
 
 #define INDIRECT_TYPE_NO_PCIE_LINK 1
 
-/*
+/**
  * Structure of a PCI controller (host bridge)
  *
  * With driver model this is dev_get_uclass_priv(bus)
+ *
+ * @skip_auto_config_until_reloc: true to avoid auto-config until U-Boot has
+ * relocated. Normally if PCI is used before relocation, this happens
+ * before relocation also. Some platforms set up static configuration in
+ * TPL/SPL to reduce code size and boot time, since these phases only know
+ * about a small subset of PCI devices. This is normally false.
  */
 struct pci_controller {
 #ifdef CONFIG_DM_PCI
struct udevice *bus;
struct udevice *ctlr;
+   bool skip_auto_config_until_reloc;
 #else
struct pci_controller *next;
 #endif
-- 
2.24.0.393.g34dc348eaf-goog



  1   2   >