From 8e2922e357fe0157593063d46f8e9bd2c25a00e0 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 27 May 2020 06:58:46 -0600 Subject: [PATCH 01/16] x86: spi: Add a way to access the SPI mapping via registers At present the PCI BDF (bus/device/function) is needed to access the SPI mapping, since the registers are at BAR0. This doesn't work when PCI auto-config has not been done yet, since BARs are unassigned. Add another way to find the mapping, using the MMIO base, if the caller knows this. Also add a missing function comment. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- arch/x86/cpu/intel_common/fast_spi.c | 25 +++++++++++++++++-------- arch/x86/include/asm/fast_spi.h | 19 +++++++++++++++++++ 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/arch/x86/cpu/intel_common/fast_spi.c b/arch/x86/cpu/intel_common/fast_spi.c index a6e3d0a5bf..5d3944dee2 100644 --- a/arch/x86/cpu/intel_common/fast_spi.c +++ b/arch/x86/cpu/intel_common/fast_spi.c @@ -31,16 +31,11 @@ static ulong fast_spi_get_bios_region(struct fast_spi_regs *regs, return bios_start; } -int fast_spi_get_bios_mmap(pci_dev_t pdev, ulong *map_basep, uint *map_sizep, - uint *offsetp) +int fast_spi_get_bios_mmap_regs(struct fast_spi_regs *regs, ulong *map_basep, + uint *map_sizep, uint *offsetp) { - struct fast_spi_regs *regs; - ulong bar, base, mmio_base; + ulong base; - /* Special case to find mapping without probing the device */ - pci_x86_read_config(pdev, PCI_BASE_ADDRESS_0, &bar, 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; @@ -48,6 +43,20 @@ int fast_spi_get_bios_mmap(pci_dev_t pdev, ulong *map_basep, uint *map_sizep, return 0; } +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, mmio_base; + + /* Special case to find mapping without probing the device */ + pci_x86_read_config(pdev, PCI_BASE_ADDRESS_0, &bar, PCI_SIZE_32); + mmio_base = bar & PCI_BASE_ADDRESS_MEM_MASK; + regs = (struct fast_spi_regs *)mmio_base; + + return fast_spi_get_bios_mmap_regs(regs, map_basep, map_sizep, offsetp); +} + int fast_spi_early_init(pci_dev_t pdev, ulong mmio_base) { /* Program Temporary BAR for SPI */ diff --git a/arch/x86/include/asm/fast_spi.h b/arch/x86/include/asm/fast_spi.h index 47c1da80d7..7a81d4f05c 100644 --- a/arch/x86/include/asm/fast_spi.h +++ b/arch/x86/include/asm/fast_spi.h @@ -64,6 +64,25 @@ check_member(fast_spi_regs, ptdata, 0xd0); int fast_spi_get_bios_mmap(pci_dev_t pdev, ulong *map_basep, uint *map_sizep, uint *offsetp); +/** + * fast_spi_get_bios_mmap_regs() - Get memory map for SPI flash given regs + * + * @regs: SPI registers to use + * @map_basep: Returns base memory address for mapped SPI + * @map_sizep: Returns size of mapped SPI + * @offsetp: Returns start offset of SPI flash where the map works + * correctly (offsets before this are not visible) + * @return 0 (always) + */ +int fast_spi_get_bios_mmap_regs(struct fast_spi_regs *regs, ulong *map_basep, + uint *map_sizep, uint *offsetp); + +/** + * fast_spi_early_init() - Set up a BAR to use SPI early in U-Boot + * + * @pdev: PCI device to use (this is the Fast SPI device) + * @mmio_base: MMIO base to use to access registers + */ int fast_spi_early_init(pci_dev_t pdev, ulong mmio_base); #endif /* ASM_FAST_SPI_H */ From 609b90a6a9c0da42c4e52cd519bfd546367fa880 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 27 May 2020 06:58:47 -0600 Subject: [PATCH 02/16] x86: spi: Rewrite logic for obtaining the SPI memory map At present this logic does not work on link and samus, since their SPI controller is not a PCI device, but a child of the PCH. Unfortunately, fixing this involves a lot of extra logic. Still, this was requested in the review of the fix-up patch, so here it is. Fixes: 92842147c31 ("spi: ich: Add support for get_mmap() method") Signed-off-by: Simon Glass Reviewed-by: Bin Meng Tested-by: Bin Meng (on Intel minnowmax) --- drivers/spi/ich.c | 103 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 88 insertions(+), 15 deletions(-) diff --git a/drivers/spi/ich.c b/drivers/spi/ich.c index 7405062846..e1336b89c5 100644 --- a/drivers/spi/ich.c +++ b/drivers/spi/ich.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -614,15 +615,94 @@ static int ich_spi_exec_op(struct spi_slave *slave, const struct spi_mem_op *op) return ret; } +/** + * ich_spi_get_basics() - Get basic information about the ICH device + * + * This works without probing any devices if requested. + * + * @bus: SPI controller to use + * @can_probe: true if this function is allowed to probe the PCH + * @pchp: Returns a pointer to the pch, or NULL if not found + * @ich_versionp: Returns ICH version detected on success + * @mmio_basep: Returns the address of the SPI registers on success + * @return 0 if OK, -EPROTOTYPE if the PCH could not be found, -EAGAIN if + * the function cannot success without probing, possible another error if + * pch_get_spi_base() fails + */ +static int ich_spi_get_basics(struct udevice *bus, bool can_probe, + struct udevice **pchp, + enum ich_version *ich_versionp, ulong *mmio_basep) +{ + struct udevice *pch = NULL; + int ret = 0; + + /* Find a PCH if there is one */ + if (can_probe) { + pch = dev_get_parent(bus); + if (device_get_uclass_id(pch) != UCLASS_PCH) { + uclass_first_device(UCLASS_PCH, &pch); + if (!pch) + return log_msg_ret("uclass", -EPROTOTYPE); + } + } + + *ich_versionp = dev_get_driver_data(bus); + if (*ich_versionp == ICHV_APL) + *mmio_basep = dm_pci_read_bar32(bus, 0); + else if (pch) + ret = pch_get_spi_base(pch, mmio_basep); + else + return -EAGAIN; + *pchp = pch; + + return ret; +} + +/** + * ich_get_mmap_bus() - Handle the get_mmap() method for a bus + * + * There are several cases to consider: + * 1. Using of-platdata, in which case we have the BDF and can access the + * registers by reading the BAR + * 2. Not using of-platdata, but still with a SPI controller that is on its own + * PCI PDF. In this case we read the BDF from the parent platdata and again get + * the registers by reading the BAR + * 3. Using a SPI controller that is a child of the PCH, in which case we try + * to find the registers by asking the PCH. This only works if the PCH has + * been probed (which it will be if the bus is probed since parents are + * probed before children), since the PCH may not have a PCI address until + * its parent (the PCI bus itself) has been probed. If you are using this + * method then you should make sure the SPI bus is probed. + * + * The first two cases are useful in early init. The last one is more useful + * afterwards. + */ 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); + if (device_is_on_pci_bus(bus)) { + struct pci_child_platdata *pplat; - spi_bdf = pplat->devfn; + pplat = dev_get_parent_platdata(bus); + spi_bdf = pplat->devfn; + } else { + enum ich_version ich_version; + struct fast_spi_regs *regs; + struct udevice *pch; + ulong mmio_base; + int ret; + + ret = ich_spi_get_basics(bus, device_active(bus), &pch, + &ich_version, &mmio_base); + if (ret) + return log_msg_ret("basics", ret); + regs = (struct fast_spi_regs *)mmio_base; + + return fast_spi_get_bios_mmap_regs(regs, map_basep, map_sizep, + offsetp); + } #else struct ich_spi_platdata *plat = dev_get_platdata(bus); @@ -866,23 +946,16 @@ 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); + int ret; #if !CONFIG_IS_ENABLED(OF_PLATDATA) struct ich_spi_priv *priv = dev_get_priv(dev); - /* Find a PCH if there is one */ - uclass_first_device(UCLASS_PCH, &priv->pch); - if (!priv->pch) - priv->pch = dev_get_parent(dev); - - plat->ich_version = dev_get_driver_data(dev); + ret = ich_spi_get_basics(dev, true, &priv->pch, &plat->ich_version, + &plat->mmio_base); + if (ret) + return log_msg_ret("basics", ret); plat->lockdown = dev_read_bool(dev, "intel,spi-lock-down"); - 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, &plat->mmio_base); - } /* * Use an int so that the property is present in of-platdata even * when false. From d7413deaddfc247a0d911fcfdcccba412e3661ed Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 27 May 2020 06:58:48 -0600 Subject: [PATCH 03/16] x86: spl: Print the error on SPL failure The error code is often useful to figure out what is going on. Printing it does not increase code size much, so print out the error and then hang. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- arch/x86/lib/spl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/lib/spl.c b/arch/x86/lib/spl.c index b6f9a70ba7..cf22fa2d7b 100644 --- a/arch/x86/lib/spl.c +++ b/arch/x86/lib/spl.c @@ -164,8 +164,8 @@ void board_init_f(ulong flags) ret = x86_spl_init(); if (ret) { - debug("Error %d\n", ret); - panic("x86_spl_init fail"); + printf("x86_spl_init: error %d\n", ret); + hang(); } #if IS_ENABLED(CONFIG_TPL) || IS_ENABLED(CONFIG_SYS_COREBOOT) gd->bd = malloc(sizeof(*gd->bd)); From 70c3c911cc29237fdb1a561ea64df05b35a6790a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 27 May 2020 06:58:49 -0600 Subject: [PATCH 04/16] x86: mrccache: Allow use before driver model is active The change to avoid searching the device tree does not work on boards wich don't have driver model set up this early, for example minnowmax. Put back the old code (converted to livetree) as a fallback for these devices. Also update the documentation. This is tested on minnowmax, link, samus and coral. Fixes: 87f1084a630 (x86: Adjust mrccache_get_region() to use livetree) Signed-off-by: Simon Glass Reviewed-by: Bin Meng Tested-by: Bin Meng (on Intel minnowmax) --- arch/x86/include/asm/mrccache.h | 15 ++++---------- arch/x86/lib/mrccache.c | 35 +++++++++++++++++++++++---------- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/arch/x86/include/asm/mrccache.h b/arch/x86/include/asm/mrccache.h index d6b7529073..b60d1171f7 100644 --- a/arch/x86/include/asm/mrccache.h +++ b/arch/x86/include/asm/mrccache.h @@ -66,19 +66,12 @@ int mrccache_reserve(void); * mrccache_get_region() - get MRC region on the SPI flash * * This gets MRC region whose offset and size are described in the device tree - * as a subnode to the SPI flash. If a non-NULL device pointer is supplied, - * this also probes the SPI flash device and returns its device pointer for - * the caller to use later. - * - * Be careful when calling this routine with a non-NULL device pointer: - * - driver model initialization must be complete - * - calling in the pre-relocation phase may bring some side effects during - * the SPI flash device probe (eg: for SPI controllers on a PCI bus, it - * triggers PCI bus enumeration during which insufficient memory issue - * might be exposed and it causes subsequent SPI flash probe fails). + * as a subnode to the SPI flash. This tries to find the SPI flash device + * (without probing it), falling back to looking for the devicetree node if + * driver model is not inited or the SPI flash is not found. * * @type: Type of MRC data to use - * @devp: Returns pointer to the SPI flash device + * @devp: Returns pointer to the SPI flash device, if found * @entry: Position and size of MRC cache in SPI flash * @return 0 if success, -ENOENT if SPI flash node does not exist in the * device tree, -EPERM if MRC region subnode does not exist in the device diff --git a/arch/x86/lib/mrccache.c b/arch/x86/lib/mrccache.c index 21c71e036e..f181e8100c 100644 --- a/arch/x86/lib/mrccache.c +++ b/arch/x86/lib/mrccache.c @@ -233,6 +233,7 @@ int mrccache_get_region(enum mrc_type_t type, struct udevice **devp, ulong map_base; uint map_size; uint offset; + ofnode node; u32 reg[2]; int ret; @@ -242,23 +243,36 @@ int mrccache_get_region(enum mrc_type_t type, struct udevice **devp, * memory map cannot be read. */ ret = uclass_find_first_device(UCLASS_SPI_FLASH, &dev); - if (!ret && !dev) + if (ret || !dev) { + /* + * Fall back to searching the device tree since driver model + * may not be ready yet (e.g. with FSPv1) + */ + node = ofnode_by_compatible(ofnode_null(), "jedec,spi-nor"); + if (!ofnode_valid(node)) + return log_msg_ret("Cannot find SPI flash\n", -ENOENT); ret = -ENODEV; - if (ret) - return log_msg_ret("Cannot find SPI flash\n", ret); - ret = dm_spi_get_mmap(dev, &map_base, &map_size, &offset); - if (!ret) { - entry->base = map_base; } else { - ret = dev_read_u32_array(dev, "memory-map", reg, 2); + ret = dm_spi_get_mmap(dev, &map_base, &map_size, &offset); + if (!ret) + entry->base = map_base; + node = dev_ofnode(dev); + } + + /* + * At this point we have entry->base if ret == 0. If not, then we have + * the node and can look for memory-map + */ + if (ret) { + ret = ofnode_read_u32_array(node, "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, type == MRC_TYPE_NORMAL ? - "rw-mrc-cache" : "rw-var-mrc-cache"); + mrc_node = ofnode_find_subnode(node, type == MRC_TYPE_NORMAL ? + "rw-mrc-cache" : "rw-var-mrc-cache"); if (!ofnode_valid(mrc_node)) return log_msg_ret("Cannot find node", -EPERM); @@ -271,7 +285,8 @@ int mrccache_get_region(enum mrc_type_t type, struct udevice **devp, if (devp) *devp = dev; debug("MRC cache type %d in '%s', offset %x, len %x, base %x\n", - type, dev->name, entry->offset, entry->length, entry->base); + type, dev ? dev->name : ofnode_get_name(node), entry->offset, + entry->length, entry->base); return 0; } From 537558b22644851eeae2d2fd2816cddbec2218ba Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 27 May 2020 05:42:11 -0600 Subject: [PATCH 05/16] x86: coral: Correct some FSP-M settings Some settings were modified slightly in the device-tree conversion. Return these to their original values. Signed-off-by: Simon Glass Acked-by: Bin Meng --- arch/x86/dts/chromebook_coral.dts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/x86/dts/chromebook_coral.dts b/arch/x86/dts/chromebook_coral.dts index dea35b73a0..fe0d4dedd7 100644 --- a/arch/x86/dts/chromebook_coral.dts +++ b/arch/x86/dts/chromebook_coral.dts @@ -516,6 +516,11 @@ 20 23 22 21 18 19 16 17 /* DQB[7:15] pins of LPDDR4 module with offset of 16 */ 25 28 30 31 26 27 24 29>; + + fspm,dimm0-spd-address = <0>; + fspm,dimm1-spd-address = <0>; + fspm,skip-cse-rbp = <1>; + fspm,enable-s3-heci2 = <0>; }; &fsp_s { From 6e5ac59ec3788d8abd297084040445113c7af8ce Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 27 May 2020 05:42:12 -0600 Subject: [PATCH 06/16] x86: apl: Add hex offsets for registers in FSP-M When comparing hex dumps it is useful to see the offsets of the registers. Add them in where they correspond to a multiple of 16. Possibly it would be useful to have a a command to output the FSP values in human-readable form, making use of the fsp_bindings implementation. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- .../include/asm/arch-apollolake/fsp/fsp_m_upd.h | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) 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 index a77964f30c..5275b75f3b 100644 --- a/arch/x86/include/asm/arch-apollolake/fsp/fsp_m_upd.h +++ b/arch/x86/include/asm/arch-apollolake/fsp/fsp_m_upd.h @@ -34,7 +34,15 @@ struct __packed fsp_ram_channel { u8 odt_levels; }; +/** + * struct fsp_m_config - FSP-M configuration + * + * Note that headers precede this and are 64 bytes long. The hex offsets + * mentioned in this file are relative to the start of the header, the same + * convention used in Intel's APL FSP header file. + */ struct __packed fsp_m_config { + /* 0x40 */ u32 serial_debug_port_address; u8 serial_debug_port_type; u8 serial_debug_port_device; @@ -49,6 +57,7 @@ struct __packed fsp_m_config { u8 profile; u8 memory_down; + /* 0x50 */ u8 ddr3_l_page_size; u8 ddr3_lasr; u8 scrambler_support; @@ -62,6 +71,7 @@ struct __packed fsp_m_config { u16 memory_size_limit; u16 low_memory_max_value; + /* 0x60 */ u16 high_memory_max_value; u8 disable_fast_boot; u8 dimm0_spd_address; @@ -73,6 +83,7 @@ struct __packed fsp_m_config { u32 msg_level_mask; u8 unused_upd_space0[4]; + /* 0x110 */ u8 pre_mem_gpio_table_pin_num[4]; u32 pre_mem_gpio_table_ptr; u8 pre_mem_gpio_table_entry_num; @@ -81,8 +92,10 @@ struct __packed fsp_m_config { u8 mrc_data_saving; u32 oem_loading_base; + /* 0x120 */ u8 oem_file_name[16]; + /* 0x130 */ void *mrc_boot_data_ptr; u8 e_mmc_trace_len; u8 skip_cse_rbp; @@ -94,20 +107,20 @@ struct __packed fsp_m_config { u8 msc1_wrap; u32 msc0_size; + /* 0x140 */ 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]; + /* 0x150 */ void *variable_nvs_buffer_ptr; u8 reserved_fspm_upd[12]; }; From 501ba58ae614b2c65e302bfd6ea68f1e2c52ced0 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 27 May 2020 05:42:13 -0600 Subject: [PATCH 07/16] x86: coral: Correct some FSP-S settings Some settings were modified slightly in the device-tree conversion. Return these to their original values. This includes some audio settings and a few others that have changed. Note that we still rely on the FSP defaults for most values, so there is no need to specify a value if the FSP default is suitable. This makes WiFi work again. Signed-off-by: Simon Glass Acked-by: Bin Meng --- arch/x86/dts/chromebook_coral.dts | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/arch/x86/dts/chromebook_coral.dts b/arch/x86/dts/chromebook_coral.dts index fe0d4dedd7..965d9f387d 100644 --- a/arch/x86/dts/chromebook_coral.dts +++ b/arch/x86/dts/chromebook_coral.dts @@ -599,13 +599,9 @@ fsps,emmc-rx-cmd-data-cntl1 = <0x00181717>; fsps,emmc-rx-cmd-data-cntl2 = <0x10008>; - /* Enable Audio Clock and Power gating */ - fsps,hd-audio-clk-gate = <1>; - fsps,hd-audio-pwr-gate = <1>; - fsps,bios-cfg-lock-down = <1>; - - /* Enable lpss s0ix */ - fsps,lpss-s0ix-enable = <1>; + /* Enable WiFi */ + fsps,pcie-root-port-en = [01 00 00 00 00 00]; + fsps,pcie-rp-hot-plug = [00 00 00 00 00 00]; fsps,skip-mp-init = <1>; fsps,spi-eiss = <0>; From 4711c1f548d1f6dfa63f70dd5356bd40fa37b996 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 27 May 2020 05:42:14 -0600 Subject: [PATCH 08/16] x86: apl: Add hex offsets for registers in FSP-S When comparing hex dumps it is useful to see the offsets of the registers. Add them in where they correspond to a multiple of 16. Possibly it would be useful to have a a command to output the FSP values in human-readable form, making use of the fsp_bindings implementation. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- .../asm/arch-apollolake/fsp/fsp_s_upd.h | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/arch/x86/include/asm/arch-apollolake/fsp/fsp_s_upd.h b/arch/x86/include/asm/arch-apollolake/fsp/fsp_s_upd.h index 87596ffd9d..451a7a254a 100644 --- a/arch/x86/include/asm/arch-apollolake/fsp/fsp_s_upd.h +++ b/arch/x86/include/asm/arch-apollolake/fsp/fsp_s_upd.h @@ -9,7 +9,15 @@ #ifndef __ASSEMBLY__ #include +/** + * struct fsp_s_config - FSP-S configuration + * + * Note that struct fsp_upd_header preceeds this and is 32 bytes long. The + * hex offsets mentioned in this file are relative to the start of the header, + * the same convention used in Intel's APL FSP header file. + */ struct __packed fsp_s_config { + /* 0x20 */ u8 active_processor_cores; u8 disable_core1; u8 disable_core2; @@ -26,6 +34,8 @@ struct __packed fsp_s_config { u8 c_state_auto_demotion; u8 c_state_un_demotion; u8 max_core_c_state; + + /* 0x30 */ u8 pkg_c_state_demotion; u8 pkg_c_state_un_demotion; u8 turbo_mode; @@ -36,6 +46,8 @@ struct __packed fsp_s_config { u8 ipu_acpi_mode; u8 force_wake; u32 gtt_mm_adr; + + /* 0x40 */ u32 gm_adr; u8 pavp_lock; u8 graphics_freq_modify; @@ -49,6 +61,8 @@ struct __packed fsp_s_config { u8 power_gating; u8 unit_level_clock_gating; u8 fast_boot; + + /* 0x50 */ u8 dyn_sr; u8 sa_ipu_enable; u8 pm_support; @@ -56,6 +70,8 @@ struct __packed fsp_s_config { u32 logo_size; u32 logo_ptr; u32 graphics_config_ptr; + + /* 0x60 */ u8 pavp_enable; u8 pavp_pr3; u8 cd_clock; @@ -78,6 +94,8 @@ struct __packed fsp_s_config { u8 hda_enable; u8 dsp_enable; u8 pme; + + /* 0x90 */ u8 hd_audio_io_buffer_ownership; u8 hd_audio_io_buffer_voltage; u8 hd_audio_vc_type; @@ -94,6 +112,8 @@ struct __packed fsp_s_config { u8 hmt; u8 hd_audio_pwr_gate; u8 hd_audio_clk_gate; + + /* 0xa0 */ u32 dsp_feature_mask; u32 dsp_pp_module_mask; u8 bios_cfg_lock_down; @@ -104,6 +124,8 @@ struct __packed fsp_s_config { u8 hpet_function_number; u8 io_apic_bdf_valid; u8 io_apic_bus_number; + + /* 0xb0 */ u8 io_apic_device_number; u8 io_apic_function_number; u8 io_apic_entry24_119; @@ -124,6 +146,8 @@ struct __packed fsp_s_config { u8 i2c2_enable; u8 i2c3_enable; u8 i2c4_enable; + + /* 0xd0 */ u8 i2c5_enable; u8 i2c6_enable; u8 i2c7_enable; @@ -137,6 +161,8 @@ struct __packed fsp_s_config { u8 os_dbg_enable; u8 dci_en; u32 uart2_kernel_debug_base_address; + + /* 0xe0 */ u8 pcie_clock_gating_disabled; u8 pcie_root_port8xh_decode; u8 pcie8xh_decode_port_index; @@ -150,6 +176,8 @@ struct __packed fsp_s_config { u8 pcie_rp_pm_sci[6]; u8 pcie_rp_ext_sync[6]; u8 pcie_rp_transmitter_half_swing[6]; + + /* 0x110 */ u8 pcie_rp_acs_enabled[6]; u8 pcie_rp_clk_req_supported[6]; u8 pcie_rp_clk_req_number[6]; @@ -158,6 +186,8 @@ struct __packed fsp_s_config { u8 pme_interrupt[6]; u8 unsupported_request_report[6]; u8 fatal_error_report[6]; + + /* 0x140 */ u8 no_fatal_error_report[6]; u8 correctable_error_report[6]; u8 system_error_on_fatal_error[6]; @@ -166,6 +196,8 @@ struct __packed fsp_s_config { u8 pcie_rp_speed[6]; u8 physical_slot_number[6]; u8 pcie_rp_completion_timeout[6]; + + /* 0x170 */ u8 ptm_enable[6]; u8 pcie_rp_aspm[6]; u8 pcie_rp_l1_substates[6]; @@ -173,6 +205,8 @@ struct __packed fsp_s_config { u8 pcie_rp_ltr_config_lock[6]; u8 pme_b0_s5_dis; u8 pci_clock_run; + + /* 0x190 */ u8 timer8254_clk_setting; u8 enable_sata; u8 sata_mode; @@ -185,6 +219,8 @@ struct __packed fsp_s_config { u8 sata_ports_dev_slp[2]; u8 sata_ports_hot_plug[2]; u8 sata_ports_interlock_sw[2]; + + /* 0x1a0 */ u8 sata_ports_external[2]; u8 sata_ports_spin_up[2]; u8 sata_ports_solid_state_drive[2]; @@ -192,6 +228,8 @@ struct __packed fsp_s_config { u8 sata_ports_dm_val[2]; u8 unused_upd_space3[2]; u16 sata_ports_dito_val[2]; + + /* 0x1b0 */ u16 sub_system_vendor_id; u16 sub_system_id; u8 crid_settings; @@ -206,6 +244,8 @@ struct __packed fsp_s_config { u8 sirq_mode; u8 start_frame_pulse; u8 smbus_enable; + + /* 0x1c0 */ u8 arp_enable; u8 unused_upd_space4; u16 num_rsvd_smbus_addresses; @@ -215,10 +255,14 @@ struct __packed fsp_s_config { u8 usb30_mode; u8 unused_upd_space5[1]; u8 port_usb20_enable[8]; + + /* 0x250 */ u8 port_us20b_over_current_pin[8]; u8 usb_otg; u8 hsic_support_enable; u8 port_usb30_enable[6]; + + /* 0x260 */ u8 port_us30b_over_current_pin[6]; u8 ssic_port_enable[2]; u16 dlane_pwr_gating; @@ -227,9 +271,13 @@ struct __packed fsp_s_config { u16 reset_wait_timer; u8 rtc_lock; u8 sata_test_mode; + + /* 0x270 */ u8 ssic_rate[2]; u16 dynamic_power_gating; u16 pcie_rp_ltr_max_snoop_latency[6]; + + /* 0x280 */ u8 pcie_rp_snoop_latency_override_mode[6]; u8 unused_upd_space6[2]; u16 pcie_rp_snoop_latency_override_value[6]; @@ -240,45 +288,69 @@ struct __packed fsp_s_config { u8 pcie_rp_non_snoop_latency_override_mode[6]; u8 tco_timer_halt_lock; u8 pwr_btn_override_period; + + /* 0x2b0 */ u16 pcie_rp_non_snoop_latency_override_value[6]; u8 pcie_rp_non_snoop_latency_override_multiplier[6]; u8 pcie_rp_slot_power_limit_scale[6]; u8 pcie_rp_slot_power_limit_value[6]; u8 disable_native_power_button; u8 power_butter_debounce_mode; + + /* 0x2d0 */ u32 sdio_tx_cmd_cntl; u32 sdio_tx_data_cntl1; u32 sdio_tx_data_cntl2; u32 sdio_rx_cmd_data_cntl1; + + /* 0x2e0 */ u32 sdio_rx_cmd_data_cntl2; u32 sdcard_tx_cmd_cntl; u32 sdcard_tx_data_cntl1; u32 sdcard_tx_data_cntl2; + + /* 0x2f0 */ u32 sdcard_rx_cmd_data_cntl1; u32 sdcard_rx_strobe_cntl; u32 sdcard_rx_cmd_data_cntl2; u32 emmc_tx_cmd_cntl; + + /* 0x300 */ u32 emmc_tx_data_cntl1; u32 emmc_tx_data_cntl2; u32 emmc_rx_cmd_data_cntl1; u32 emmc_rx_strobe_cntl; + + /* 0x310 */ u32 emmc_rx_cmd_data_cntl2; u32 emmc_master_sw_cntl; u8 pcie_rp_selectable_deemphasis[6]; u8 monitor_mwait_enable; u8 hd_audio_dsp_uaa_compliance; + + /* 0x320 */ u32 ipc[4]; + + /* 0x330 */ u8 sata_ports_disable_dynamic_pg[2]; u8 init_s3_cpu; u8 skip_punit_init; u8 unused_upd_space7[4]; u8 port_usb20_per_port_tx_pe_half[8]; + + /* 0x340 */ u8 port_usb20_per_port_pe_txi_set[8]; u8 port_usb20_per_port_txi_set[8]; + + /* 0x350 */ u8 port_usb20_hs_skew_sel[8]; u8 port_usb20_i_usb_tx_emphasis_en[8]; + + /* 0x360 */ u8 port_usb20_per_port_rxi_set[8]; u8 port_usb20_hs_npre_drv_sel[8]; + + /* 0x370 */ u8 reserved_fsps_upd[16]; }; From b523c174d6f016ebf071a02b398dc790457cb9c5 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 27 May 2020 06:56:53 -0600 Subject: [PATCH 09/16] x86: minnowmax: Add support for Winbond flash This allows the use of the Dediprog em100pro so I can test SPI flash on this board in my lab. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- board/intel/minnowmax/Kconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/board/intel/minnowmax/Kconfig b/board/intel/minnowmax/Kconfig index 543468cab5..82a6ca904e 100644 --- a/board/intel/minnowmax/Kconfig +++ b/board/intel/minnowmax/Kconfig @@ -21,6 +21,9 @@ config BOARD_SPECIFIC_OPTIONS # dummy select INTEL_BAYTRAIL select BOARD_ROMSIZE_KB_8192 select SPI_FLASH_STMICRO + # Enable Winbond so we can use Dediprog em100pro emulator which does + # not support N25Q064 + select SPI_FLASH_WINBOND config PCIE_ECAM_BASE default 0xe0000000 From d8177a94ca0f3447a60c405cb595143f26a8edbf Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 28 May 2020 12:17:33 +0300 Subject: [PATCH 10/16] x86: tangier: acpi: Create buffers outside of the methods Create buffers outside of the methods as ACPICA 20200214 complains about this: Remark 2173 - Creation of named objects within a method is highly inefficient, use globals or method local variables instead Reported-by: Bin Meng Signed-off-by: Andy Shevchenko Reviewed-by: Bin Meng Tested-by: Bin Meng --- .../asm/arch-tangier/acpi/southcluster.asl | 95 ++++++++++--------- 1 file changed, 49 insertions(+), 46 deletions(-) diff --git a/arch/x86/include/asm/arch-tangier/acpi/southcluster.asl b/arch/x86/include/asm/arch-tangier/acpi/southcluster.asl index f088fe3cf5..9d81abbdb6 100644 --- a/arch/x86/include/asm/arch-tangier/acpi/southcluster.asl +++ b/arch/x86/include/asm/arch-tangier/acpi/southcluster.asl @@ -338,12 +338,12 @@ Device (PCI0) { Name (_ADR, Zero) + Name (PCKG, Package () { + Buffer (0x14) {} + }) + /* GPLD: Generate Port Location Data (PLD) */ Method (GPLD, 1, Serialized) { - Name (PCKG, Package () { - Buffer (0x14) {} - }) - /* REV: Revision 0x02 for ACPI 5.0 */ CreateField (DerefOf (Index (PCKG, Zero)), Zero, 0x07, REV) Store (0x0002, REV) @@ -401,20 +401,21 @@ Device (PCI0) Return (STA_VISIBLE) } + Name (RBUF, ResourceTemplate() + { + UartSerialBus(0x0001C200, DataBitsEight, StopBitsOne, + 0xFC, LittleEndian, ParityTypeNone, FlowControlHardware, + 0x20, 0x20, "\\_SB.PCI0.HSU0", 0, ResourceConsumer, , ) + GpioInt(Level, ActiveHigh, Exclusive, PullNone, 0, + "\\_SB.PCI0.GPIO", 0, ResourceConsumer, , ) { 185 } + GpioIo(Exclusive, PullDefault, 0, 0, IoRestrictionOutputOnly, + "\\_SB.PCI0.GPIO", 0, ResourceConsumer, , ) { 184 } + GpioIo(Exclusive, PullDefault, 0, 0, IoRestrictionOutputOnly, + "\\_SB.PCI0.GPIO", 0, ResourceConsumer, , ) { 71 } + }) + Method (_CRS, 0, Serialized) { - Name (RBUF, ResourceTemplate() - { - UartSerialBus(0x0001C200, DataBitsEight, StopBitsOne, - 0xFC, LittleEndian, ParityTypeNone, FlowControlHardware, - 0x20, 0x20, "\\_SB.PCI0.HSU0", 0, ResourceConsumer, , ) - GpioInt(Level, ActiveHigh, Exclusive, PullNone, 0, - "\\_SB.PCI0.GPIO", 0, ResourceConsumer, , ) { 185 } - GpioIo(Exclusive, PullDefault, 0, 0, IoRestrictionOutputOnly, - "\\_SB.PCI0.GPIO", 0, ResourceConsumer, , ) { 184 } - GpioIo(Exclusive, PullDefault, 0, 0, IoRestrictionOutputOnly, - "\\_SB.PCI0.GPIO", 0, ResourceConsumer, , ) { 71 } - }) Return (RBUF) } @@ -454,33 +455,34 @@ Device (PCI0) Return (STA_VISIBLE) } + Name (RBUF, ResourceTemplate() + { + /* + * Shadow registers in SRAM for PMIC: + * SRAM PMIC register + * -------------------- + * 0x00- Unknown + * 0x03 THRMIRQ (0x04) + * 0x04 BCUIRQ (0x05) + * 0x05 ADCIRQ (0x06) + * 0x06 CHGRIRQ0 (0x07) + * 0x07 CHGRIRQ1 (0x08) + * 0x08- Unknown + * 0x0a PBSTATUS (0x27) + * 0x0b- Unknown + */ + Memory32Fixed(ReadWrite, 0xFFFFF610, 0x00000010) + Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 30 } + Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 23 } + Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 52 } + Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 51 } + Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 50 } + Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 27 } + Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 49 } + }) + Method (_CRS, 0, Serialized) { - Name (RBUF, ResourceTemplate() - { - /* - * Shadow registers in SRAM for PMIC: - * SRAM PMIC register - * -------------------- - * 0x00- Unknown - * 0x03 THRMIRQ (0x04) - * 0x04 BCUIRQ (0x05) - * 0x05 ADCIRQ (0x06) - * 0x06 CHGRIRQ0 (0x07) - * 0x07 CHGRIRQ1 (0x08) - * 0x08- Unknown - * 0x0a PBSTATUS (0x27) - * 0x0b- Unknown - */ - Memory32Fixed(ReadWrite, 0xFFFFF610, 0x00000010) - Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 30 } - Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 23 } - Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 52 } - Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 51 } - Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 50 } - Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 27 } - Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 49 } - }) Return (RBUF) } @@ -527,13 +529,14 @@ Device (PCI0) Return (STA_VISIBLE) } + Name (RBUF, ResourceTemplate () + { + Memory32Fixed(ReadWrite, 0xFF192000, 0x00001000) + Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 32 } + }) + Method (_CRS, 0, Serialized) { - Name (RBUF, ResourceTemplate () - { - Memory32Fixed(ReadWrite, 0xFF192000, 0x00001000) - Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 32 } - }) Return (RBUF) } } From 55f54538f8b45963724d69b481ee624478582321 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 28 May 2020 12:17:34 +0300 Subject: [PATCH 11/16] x86: tangier: acpi: Replace _ADR() by _UID() in description of PCI host bridge PCI Firmware specification requires _UID() and doesn't require _ADR() to be set. Replace latter by former. Reported-by: Bin Meng Signed-off-by: Andy Shevchenko Reviewed-by: Bin Meng Tested-by: Bin Meng --- arch/x86/include/asm/arch-tangier/acpi/southcluster.asl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/include/asm/arch-tangier/acpi/southcluster.asl b/arch/x86/include/asm/arch-tangier/acpi/southcluster.asl index 9d81abbdb6..11b06e5fe9 100644 --- a/arch/x86/include/asm/arch-tangier/acpi/southcluster.asl +++ b/arch/x86/include/asm/arch-tangier/acpi/southcluster.asl @@ -10,7 +10,7 @@ Device (PCI0) Name (_HID, EISAID("PNP0A08")) /* PCIe */ Name (_CID, EISAID("PNP0A03")) /* PCI */ - Name (_ADR, Zero) + Name (_UID, Zero) Name (_BBN, Zero) Name (MCRS, ResourceTemplate() From 10a428ed1540c255bf52ee5b6df4a575913885d2 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 28 May 2020 12:17:35 +0300 Subject: [PATCH 12/16] x86: tangier: acpi: Drop _ADR() where _HID() is present ACPICA complains that either _HID() or _ADR() should be used. Drop _ADR() where _HID() is present. Reported-by: Bin Meng Signed-off-by: Andy Shevchenko Reviewed-by: Bin Meng Tested-by: Bin Meng --- arch/x86/include/asm/arch-tangier/acpi/southcluster.asl | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/x86/include/asm/arch-tangier/acpi/southcluster.asl b/arch/x86/include/asm/arch-tangier/acpi/southcluster.asl index 11b06e5fe9..f9da188b38 100644 --- a/arch/x86/include/asm/arch-tangier/acpi/southcluster.asl +++ b/arch/x86/include/asm/arch-tangier/acpi/southcluster.asl @@ -441,7 +441,6 @@ Device (PCI0) Device (PMIC) { - Name (_ADR, Zero) Name (_HID, "INTC100E") Name (_CID, "INTC100E") Name (_DDN, "Basin Cove PMIC") From b9ce32ec3a0483ad4eee0f85ed2b4085fe69349a Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 28 May 2020 12:17:36 +0300 Subject: [PATCH 13/16] x86: tangier: acpi: Drop _HID() where enumerated by _ADR() ACPICA complains that either _HID() or _ADR() should be used. For General Purpose DMA we may not drop the _ADR() because the device is enumerated by PCI. Thus, simple drop _HID(). Reported-by: Bin Meng Signed-off-by: Andy Shevchenko Reviewed-by: Bin Meng Tested-by: Bin Meng --- arch/x86/include/asm/arch-tangier/acpi/southcluster.asl | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/x86/include/asm/arch-tangier/acpi/southcluster.asl b/arch/x86/include/asm/arch-tangier/acpi/southcluster.asl index f9da188b38..df66625930 100644 --- a/arch/x86/include/asm/arch-tangier/acpi/southcluster.asl +++ b/arch/x86/include/asm/arch-tangier/acpi/southcluster.asl @@ -520,7 +520,6 @@ Device (PCI0) Device (GDMA) { Name (_ADR, 0x00150000) - Name (_HID, "808611A2") Name (_UID, Zero) Method (_STA, 0, NotSerialized) From 319506c7a972fcf89a804c1345b2644c2e3f29e9 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Sun, 31 May 2020 21:15:13 -0700 Subject: [PATCH 14/16] x86: baytrail: acpi: Create buffers outside of the methods Create buffers outside of the methods as ACPICA 20200430 complains about this: Remark 2173 - Creation of named objects within a method is highly inefficient, use globals or method local variables instead (\_SB.PCI0.LPCB.IURT._CRS) Signed-off-by: Bin Meng Reviewed-by: Andy Shevchenko --- .../include/asm/arch-baytrail/acpi/lpc.asl | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/arch/x86/include/asm/arch-baytrail/acpi/lpc.asl b/arch/x86/include/asm/arch-baytrail/acpi/lpc.asl index 08b2f53132..69455d90da 100644 --- a/arch/x86/include/asm/arch-baytrail/acpi/lpc.asl +++ b/arch/x86/include/asm/arch-baytrail/acpi/lpc.asl @@ -136,20 +136,20 @@ Device (LPCB) Store(0, C1EN) } + Name(BUF0, ResourceTemplate() + { + IO(Decode16, 0x03f8, 0x03f8, 0x01, 0x08) + IRQNoFlags() { 3 } + }) + + Name(BUF1, ResourceTemplate() + { + IO(Decode16, 0x03f8, 0x03f8, 0x01, 0x08) + IRQNoFlags() { 4 } + }) + Method(_CRS, 0, Serialized) { - Name(BUF0, ResourceTemplate() - { - IO(Decode16, 0x03f8, 0x03f8, 0x01, 0x08) - IRQNoFlags() { 3 } - }) - - Name(BUF1, ResourceTemplate() - { - IO(Decode16, 0x03f8, 0x03f8, 0x01, 0x08) - IRQNoFlags() { 4 } - }) - If (LLessEqual(SRID, 0x04)) { Return (BUF0) } Else { From d8b5f5d4363340f535605e80487b01333aa5168b Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Sun, 31 May 2020 21:15:14 -0700 Subject: [PATCH 15/16] x86: baytrail: acpi: Replace _ADR() by _UID() in description of PCI host bridge PCI Firmware specification requires _UID() and doesn't require _ADR() to be set. Replace latter by former. This fixes the following warning reported by ACPICA 20200430: Warning 3073 - Multiple types (Device object requires either a _HID or _ADR, but not both) Signed-off-by: Bin Meng Reviewed-by: Andy Shevchenko --- arch/x86/include/asm/arch-baytrail/acpi/southcluster.asl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/include/asm/arch-baytrail/acpi/southcluster.asl b/arch/x86/include/asm/arch-baytrail/acpi/southcluster.asl index 2a1c31cdc4..3b220c7ac2 100644 --- a/arch/x86/include/asm/arch-baytrail/acpi/southcluster.asl +++ b/arch/x86/include/asm/arch-baytrail/acpi/southcluster.asl @@ -11,7 +11,7 @@ Device (PCI0) Name(_HID, EISAID("PNP0A08")) /* PCIe */ Name(_CID, EISAID("PNP0A03")) /* PCI */ - Name(_ADR, 0) + Name(_UID, 0) Name(_BBN, 0) Name(MCRS, ResourceTemplate() From 95cfa1d46c61461bdadb195799a205b48b907a5e Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Sun, 31 May 2020 21:15:15 -0700 Subject: [PATCH 16/16] x86: quark: acpi: Replace _ADR() by _UID() in description of PCI host bridge PCI Firmware specification requires _UID() and doesn't require _ADR() to be set. Replace latter by former. This fixes the following warning reported by ACPICA 20200430: Warning 3073 - Multiple types (Device object requires either a _HID or _ADR, but not both) Signed-off-by: Bin Meng Reviewed-by: Andy Shevchenko --- arch/x86/include/asm/arch-quark/acpi/southcluster.asl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/include/asm/arch-quark/acpi/southcluster.asl b/arch/x86/include/asm/arch-quark/acpi/southcluster.asl index fe9edc1a87..384dab25bd 100644 --- a/arch/x86/include/asm/arch-quark/acpi/southcluster.asl +++ b/arch/x86/include/asm/arch-quark/acpi/southcluster.asl @@ -8,7 +8,7 @@ Device (PCI0) Name(_HID, EISAID("PNP0A08")) /* PCIe */ Name(_CID, EISAID("PNP0A03")) /* PCI */ - Name(_ADR, 0) + Name(_UID, 0) Name(_BBN, 0) Name(MCRS, ResourceTemplate()