summaryrefslogtreecommitdiff
path: root/resources/coreboot/haswell/patches/0007-sb-intel-lynxpoint-Add-native-PCH-init.patch
diff options
context:
space:
mode:
authorLeah Rowe <leah@libreboot.org>2023-03-18 00:36:27 +0000
committerLeah Rowe <leah@libreboot.org>2023-03-18 00:55:10 +0000
commit548872ce8e84fe10d52417acab9b3cf886821386 (patch)
treeb549ad51c9c693a323f0f8edc9a11eab92220013 /resources/coreboot/haswell/patches/0007-sb-intel-lynxpoint-Add-native-PCH-init.patch
parenta942bd6590dd450140fc0af8549ca470a065adf5 (diff)
haswell boards: use libre mrc.bin replacement
courtesy of Angel Pons from the coreboot project this uses the following patch set from gerrit, as yet unmerged (in coreboot master) on this date: https://review.coreboot.org/c/coreboot/+/64198/5 logic for downloading mrc blobs has been deleted from lbmk, as this is now completely obsolete (for haswell boards) if other platforms are added later that need mrc.bin, then logic will be re-added again for that
Diffstat (limited to 'resources/coreboot/haswell/patches/0007-sb-intel-lynxpoint-Add-native-PCH-init.patch')
-rw-r--r--resources/coreboot/haswell/patches/0007-sb-intel-lynxpoint-Add-native-PCH-init.patch785
1 files changed, 785 insertions, 0 deletions
diff --git a/resources/coreboot/haswell/patches/0007-sb-intel-lynxpoint-Add-native-PCH-init.patch b/resources/coreboot/haswell/patches/0007-sb-intel-lynxpoint-Add-native-PCH-init.patch
new file mode 100644
index 00000000..74427f5d
--- /dev/null
+++ b/resources/coreboot/haswell/patches/0007-sb-intel-lynxpoint-Add-native-PCH-init.patch
@@ -0,0 +1,785 @@
+From 7378cb4fefc87b9a096bb14820a44f26f3a628f5 Mon Sep 17 00:00:00 2001
+From: Angel Pons <th3fanbus@gmail.com>
+Date: Fri, 6 May 2022 23:43:46 +0200
+Subject: [PATCH 07/26] sb/intel/lynxpoint: Add native PCH init
+
+Implement native PCH initialisation for Lynx Point. This is only needed
+when MRC.bin is not used.
+
+Change-Id: I36867bdc8b20000e44ff9d0d7b2c0d63952bd561
+Signed-off-by: Angel Pons <th3fanbus@gmail.com>
+---
+ .../haswell/native_raminit/raminit_native.c | 3 +-
+ src/southbridge/intel/lynxpoint/Makefile.inc | 1 +
+ .../intel/lynxpoint/early_pch_native.c | 123 +++++++++
+ .../intel/lynxpoint/hsio/Makefile.inc | 8 +
+ src/southbridge/intel/lynxpoint/hsio/common.c | 52 ++++
+ src/southbridge/intel/lynxpoint/hsio/hsio.h | 46 ++++
+ .../intel/lynxpoint/hsio/lpt_h_cx.c | 244 ++++++++++++++++++
+ .../intel/lynxpoint/hsio/lpt_lp_bx.c | 180 +++++++++++++
+ src/southbridge/intel/lynxpoint/pch.h | 6 +
+ 9 files changed, 661 insertions(+), 2 deletions(-)
+ create mode 100644 src/southbridge/intel/lynxpoint/hsio/Makefile.inc
+ create mode 100644 src/southbridge/intel/lynxpoint/hsio/common.c
+ create mode 100644 src/southbridge/intel/lynxpoint/hsio/hsio.h
+ create mode 100644 src/southbridge/intel/lynxpoint/hsio/lpt_h_cx.c
+ create mode 100644 src/southbridge/intel/lynxpoint/hsio/lpt_lp_bx.c
+
+diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_native.c b/src/northbridge/intel/haswell/native_raminit/raminit_native.c
+index dd1f1ec14e..b6efb6b40d 100644
+--- a/src/northbridge/intel/haswell/native_raminit/raminit_native.c
++++ b/src/northbridge/intel/haswell/native_raminit/raminit_native.c
+@@ -16,8 +16,7 @@ static bool early_init_native(int s3resume)
+ /** TODO: CPU replacement check must be skipped in warm boots and S3 resumes **/
+ const bool cpu_replaced = !s3resume && intel_early_me_cpu_replacement_check();
+
+- early_thermal_init();
+- early_usb_init();
++ early_pch_init_native(s3resume);
+
+ if (!CONFIG(INTEL_LYNXPOINT_LP))
+ dmi_early_init();
+diff --git a/src/southbridge/intel/lynxpoint/Makefile.inc b/src/southbridge/intel/lynxpoint/Makefile.inc
+index a9a9b153d6..63243ecc86 100644
+--- a/src/southbridge/intel/lynxpoint/Makefile.inc
++++ b/src/southbridge/intel/lynxpoint/Makefile.inc
+@@ -38,6 +38,7 @@ romstage-y += early_usb.c early_me.c me_status.c early_pch.c
+ romstage-y += pmutil.c
+
+ romstage-$(CONFIG_USE_NATIVE_RAMINIT) += early_pch_native.c early_usb_native.c iobp.c thermal.c
++subdirs-$(CONFIG_USE_NATIVE_RAMINIT) += hsio
+
+ ifeq ($(CONFIG_INTEL_LYNXPOINT_LP),y)
+ romstage-y += lp_gpio.c
+diff --git a/src/southbridge/intel/lynxpoint/early_pch_native.c b/src/southbridge/intel/lynxpoint/early_pch_native.c
+index c28ddfcf5d..421821fa5d 100644
+--- a/src/southbridge/intel/lynxpoint/early_pch_native.c
++++ b/src/southbridge/intel/lynxpoint/early_pch_native.c
+@@ -1,10 +1,133 @@
+ /* SPDX-License-Identifier: GPL-2.0-or-later */
+
+ #include <console/console.h>
++#include <device/pci_def.h>
+ #include <device/pci_ops.h>
++#include <southbridge/intel/lynxpoint/hsio/hsio.h>
+ #include <southbridge/intel/lynxpoint/pch.h>
+ #include <types.h>
+
++static void early_sata_init(const uint8_t pch_revision)
++{
++ const bool is_mobile = get_pch_platform_type() != PCH_TYPE_DESKTOP;
++
++ const uint8_t lane_owner = pci_read_config8(PCI_DEV(0, 0x1c, 0), 0x410);
++ printk(BIOS_DEBUG, "HSIO lane owner: 0x%02x\n", lane_owner);
++
++ /* BWG Step 2 */
++ pci_update_config32(PCH_SATA_DEV, SATA_SCLKG, ~0x1ff, 0x183);
++
++ /* BWG Step 3: Set OOB Retry Mode */
++ pci_or_config16(PCH_SATA_DEV, SATA_PCS, 1 << 15);
++
++ /* BWG Step 4: Program the SATA mPHY tables */
++ if (pch_is_lp()) {
++ if (pch_revision >= LPT_LP_STEP_B0 && pch_revision <= LPT_LP_STEP_B2) {
++ program_hsio_sata_lpt_lp_bx(is_mobile);
++ } else {
++ printk(BIOS_ERR, "Unsupported PCH-LP stepping 0x%02x\n", pch_revision);
++ }
++ } else {
++ if (pch_revision >= LPT_H_STEP_C0) {
++ program_hsio_sata_lpt_h_cx(is_mobile);
++ } else {
++ printk(BIOS_ERR, "Unsupported PCH-H stepping 0x%02x\n", pch_revision);
++ }
++ }
++
++ /** FIXME: Program SATA RxEq tables **/
++
++ /* BWG Step 5 */
++ /** FIXME: Only for desktop and mobile (skip this on workstation and server) **/
++ pci_or_config32(PCH_SATA_DEV, 0x98, BIT(22));
++
++ /* BWG Step 6 */
++ pci_or_config32(PCH_SATA_DEV, 0x98, BIT(19));
++
++ /* BWG Step 7 */
++ pci_update_config32(PCH_SATA_DEV, 0x98, ~(0x3f << 7), 0x04 << 7);
++
++ /* BWG Step 8 */
++ pci_or_config32(PCH_SATA_DEV, 0x98, BIT(20));
++
++ /* BWG Step 9 */
++ pci_update_config32(PCH_SATA_DEV, 0x98, ~(3 << 5), 1 << 5);
++
++ /* BWG Step 10 */
++ pci_or_config32(PCH_SATA_DEV, 0x98, BIT(18));
++
++ /* Enable SATA ports */
++ uint8_t sata_pcs = 0;
++ if (CONFIG(INTEL_LYNXPOINT_LP)) {
++ for (uint8_t i = 0; i < 4; i++) {
++ if ((lane_owner & BIT(7 - i)) == 0) {
++ sata_pcs |= BIT(i);
++ }
++ }
++ } else {
++ sata_pcs |= 0x0f;
++ for (uint8_t i = 4; i < 6; i++) {
++ if ((lane_owner & BIT(i)) == 0) {
++ sata_pcs |= BIT(i);
++ }
++ }
++ }
++ printk(BIOS_DEBUG, "SATA port enables: 0x%02x\n", sata_pcs);
++ pci_or_config8(PCH_SATA_DEV, SATA_PCS, sata_pcs);
++}
++
++void early_pch_init_native(int s3resume)
++{
++ const uint8_t pch_revision = pci_read_config8(PCH_LPC_DEV, PCI_REVISION_ID);
++
++ RCBA16(DISPBDF) = 0x0010;
++ RCBA32_OR(FD2, PCH_ENABLE_DBDF);
++
++ /** FIXME: Check GEN_PMCON_3 and handle RTC failure? **/
++
++ RCBA32(PRSTS) = BIT(4);
++
++ early_sata_init(pch_revision);
++
++ pci_or_config8(PCH_LPC_DEV, 0xa6, 1 << 1);
++ pci_and_config8(PCH_LPC_DEV, 0xdc, ~(1 << 5 | 1 << 1));
++
++ /** TODO: Send GET HSIO VER and update ChipsetInit table? Is it needed? **/
++
++ /** FIXME: GbE handling? **/
++
++ pci_update_config32(PCH_LPC_DEV, 0xac, ~(1 << 20), 0);
++
++ for (uint8_t i = 0; i < 8; i++)
++ pci_update_config32(PCI_DEV(0, 0x1c, i), 0x338, ~(1 << 26), 0);
++
++ pci_update_config8(PCI_DEV(0, 0x1c, 0), 0xf4, ~(3 << 5), 1 << 7);
++
++ pci_update_config8(PCI_DEV(0, 26, 0), 0x88, ~(1 << 2), 0);
++ pci_update_config8(PCI_DEV(0, 29, 0), 0x88, ~(1 << 2), 0);
++
++ /** FIXME: Disable SATA2 device? **/
++
++ if (pch_is_lp()) {
++ if (pch_revision >= LPT_LP_STEP_B0 && pch_revision <= LPT_LP_STEP_B2) {
++ program_hsio_xhci_lpt_lp_bx();
++ program_hsio_igbe_lpt_lp_bx();
++ } else {
++ printk(BIOS_ERR, "Unsupported PCH-LP stepping 0x%02x\n", pch_revision);
++ }
++ } else {
++ if (pch_revision >= LPT_H_STEP_C0) {
++ program_hsio_xhci_lpt_h_cx();
++ program_hsio_igbe_lpt_h_cx();
++ } else {
++ printk(BIOS_ERR, "Unsupported PCH-H stepping 0x%02x\n", pch_revision);
++ }
++ }
++
++ early_thermal_init();
++ early_usb_init();
++}
++
+ void pch_dmi_setup_physical_layer(void)
+ {
+ /* FIXME: We need to make sure the SA supports Gen2 as well */
+diff --git a/src/southbridge/intel/lynxpoint/hsio/Makefile.inc b/src/southbridge/intel/lynxpoint/hsio/Makefile.inc
+new file mode 100644
+index 0000000000..6b74997511
+--- /dev/null
++++ b/src/southbridge/intel/lynxpoint/hsio/Makefile.inc
+@@ -0,0 +1,8 @@
++## SPDX-License-Identifier: GPL-2.0-or-later
++
++romstage-y += common.c
++ifeq ($(CONFIG_INTEL_LYNXPOINT_LP),y)
++romstage-y += lpt_lp_bx.c
++else
++romstage-y += lpt_h_cx.c
++endif
+diff --git a/src/southbridge/intel/lynxpoint/hsio/common.c b/src/southbridge/intel/lynxpoint/hsio/common.c
+new file mode 100644
+index 0000000000..9935ca347a
+--- /dev/null
++++ b/src/southbridge/intel/lynxpoint/hsio/common.c
+@@ -0,0 +1,52 @@
++/* SPDX-License-Identifier: GPL-2.0-or-later */
++
++#include <device/pci_ops.h>
++#include <southbridge/intel/lynxpoint/hsio/hsio.h>
++#include <types.h>
++
++/*
++ * FIXME: Ask Intel whether all lanes need to be programmed as specified
++ * in the PCH BWG. If not, make separate tables and only check this once.
++ */
++void hsio_sata_shared_update(const uint32_t addr, const uint32_t and, const uint32_t or)
++{
++ const uint8_t lane_owner = pci_read_config8(PCI_DEV(0, 0x1c, 0), 0x410);
++
++ if ((addr & 0xfe00) == 0x2000 && (lane_owner & (1 << 4)))
++ return;
++
++ if ((addr & 0xfe00) == 0x2200 && (lane_owner & (1 << 5)))
++ return;
++
++ if (CONFIG(INTEL_LYNXPOINT_LP)) {
++ if ((addr & 0xfe00) == 0x2400 && (lane_owner & (1 << 6)))
++ return;
++
++ if ((addr & 0xfe00) == 0x2600 && (lane_owner & (1 << 7)))
++ return;
++ }
++ hsio_update(addr, and, or);
++}
++
++/*
++ * FIXME: Ask Intel whether all lanes need to be programmed as specified
++ * in the PCH BWG. If not, make separate tables and only check this once.
++ */
++void hsio_xhci_shared_update(const uint32_t addr, const uint32_t and, const uint32_t or)
++{
++ const uint8_t lane_owner = pci_read_config8(PCI_DEV(0, 0x1c, 0), 0x410);
++ if (CONFIG(INTEL_LYNXPOINT_LP)) {
++ if ((addr & 0xfe00) == 0x2400 && ((lane_owner >> 0) & 3) != 2)
++ return;
++
++ if ((addr & 0xfe00) == 0x2600 && ((lane_owner >> 2) & 3) != 2)
++ return;
++ } else {
++ if ((addr & 0xfe00) == 0x2c00 && ((lane_owner >> 2) & 3) != 2)
++ return;
++
++ if ((addr & 0xfe00) == 0x2e00 && ((lane_owner >> 0) & 3) != 2)
++ return;
++ }
++ hsio_update(addr, and, or);
++}
+diff --git a/src/southbridge/intel/lynxpoint/hsio/hsio.h b/src/southbridge/intel/lynxpoint/hsio/hsio.h
+new file mode 100644
+index 0000000000..689ef4a05b
+--- /dev/null
++++ b/src/southbridge/intel/lynxpoint/hsio/hsio.h
+@@ -0,0 +1,46 @@
++/* SPDX-License-Identifier: GPL-2.0-or-later */
++
++#ifndef SOUTHBRIDGE_INTEL_LYNXPOINT_HSIO_H
++#define SOUTHBRIDGE_INTEL_LYNXPOINT_HSIO_H
++
++#include <southbridge/intel/lynxpoint/iobp.h>
++#include <types.h>
++
++struct hsio_table_row {
++ uint32_t addr;
++ uint32_t and;
++ uint32_t or;
++};
++
++static inline void hsio_update(const uint32_t addr, const uint32_t and, const uint32_t or)
++{
++ pch_iobp_update(addr, and, or);
++}
++
++static inline void hsio_update_row(const struct hsio_table_row row)
++{
++ hsio_update(row.addr, row.and, row.or);
++}
++
++void hsio_xhci_shared_update(const uint32_t addr, const uint32_t and, const uint32_t or);
++void hsio_sata_shared_update(const uint32_t addr, const uint32_t and, const uint32_t or);
++
++static inline void hsio_sata_shared_update_row(const struct hsio_table_row row)
++{
++ hsio_sata_shared_update(row.addr, row.and, row.or);
++}
++
++static inline void hsio_xhci_shared_update_row(const struct hsio_table_row row)
++{
++ hsio_xhci_shared_update(row.addr, row.and, row.or);
++}
++
++void program_hsio_sata_lpt_h_cx(const bool is_mobile);
++void program_hsio_xhci_lpt_h_cx(void);
++void program_hsio_igbe_lpt_h_cx(void);
++
++void program_hsio_sata_lpt_lp_bx(const bool is_mobile);
++void program_hsio_xhci_lpt_lp_bx(void);
++void program_hsio_igbe_lpt_lp_bx(void);
++
++#endif
+diff --git a/src/southbridge/intel/lynxpoint/hsio/lpt_h_cx.c b/src/southbridge/intel/lynxpoint/hsio/lpt_h_cx.c
+new file mode 100644
+index 0000000000..b5dd402742
+--- /dev/null
++++ b/src/southbridge/intel/lynxpoint/hsio/lpt_h_cx.c
+@@ -0,0 +1,244 @@
++/* SPDX-License-Identifier: GPL-2.0-or-later */
++
++#include <device/pci_ops.h>
++#include <southbridge/intel/lynxpoint/hsio/hsio.h>
++#include <types.h>
++
++const struct hsio_table_row hsio_sata_shared_lpt_h_cx[] = {
++ { 0xea002008, ~0xfffc6108, 0xea6c6108 },
++ { 0xea002208, ~0xfffc6108, 0xea6c6108 },
++ { 0xea002038, ~0x3f00000f, 0x0700000d },
++ { 0xea002238, ~0x3f00000f, 0x0700000d },
++ { 0xea00202c, ~0x00020f00, 0x00020100 },
++ { 0xea00222c, ~0x00020f00, 0x00020100 },
++ { 0xea002040, ~0x1f000000, 0x01000000 },
++ { 0xea002240, ~0x1f000000, 0x01000000 },
++ { 0xea002010, ~0xffff0000, 0x0d510000 },
++ { 0xea002210, ~0xffff0000, 0x0d510000 },
++ { 0xea002018, ~0xffff0300, 0x38250100 },
++ { 0xea002218, ~0xffff0300, 0x38250100 },
++ { 0xea002000, ~0xcf030000, 0xcf030000 },
++ { 0xea002200, ~0xcf030000, 0xcf030000 },
++ { 0xea002028, ~0xff1f0000, 0x580e0000 },
++ { 0xea002228, ~0xff1f0000, 0x580e0000 },
++ { 0xea00201c, ~0x00007c00, 0x00002400 },
++ { 0xea00221c, ~0x00007c00, 0x00002400 },
++ { 0xea00208c, ~0x00ff0000, 0x00800000 },
++ { 0xea00228c, ~0x00ff0000, 0x00800000 },
++ { 0xea0020a4, ~0x0030ff00, 0x00308300 },
++ { 0xea0022a4, ~0x0030ff00, 0x00308300 },
++ { 0xea0020ac, ~0x00000030, 0x00000020 },
++ { 0xea0022ac, ~0x00000030, 0x00000020 },
++ { 0xea002140, ~0x00ffffff, 0x00140718 },
++ { 0xea002340, ~0x00ffffff, 0x00140718 },
++ { 0xea002144, ~0x00ffffff, 0x00140998 },
++ { 0xea002344, ~0x00ffffff, 0x00140998 },
++ { 0xea002148, ~0x00ffffff, 0x00140998 },
++ { 0xea002348, ~0x00ffffff, 0x00140998 },
++ { 0xea00217c, ~0x03000000, 0x03000000 },
++ { 0xea00237c, ~0x03000000, 0x03000000 },
++ { 0xea002178, ~0x00001f00, 0x00001800 },
++ { 0xea002378, ~0x00001f00, 0x00001800 },
++ { 0xea00210c, ~0x0038000f, 0x00000005 },
++ { 0xea00230c, ~0x0038000f, 0x00000005 },
++};
++
++const struct hsio_table_row hsio_sata_lpt_h_cx[] = {
++ { 0xea008008, ~0xff000000, 0x1c000000 },
++ { 0xea002408, ~0xfffc6108, 0xea6c6108 },
++ { 0xea002608, ~0xfffc6108, 0xea6c6108 },
++ { 0xea000808, ~0xfffc6108, 0xea6c6108 },
++ { 0xea000a08, ~0xfffc6108, 0xea6c6108 },
++ { 0xea002438, ~0x3f00000f, 0x0700000d },
++ { 0xea002638, ~0x3f00000f, 0x0700000d },
++ { 0xea000838, ~0x3f00000f, 0x0700000d },
++ { 0xea000a38, ~0x3f00000f, 0x0700000d },
++ { 0xea002440, ~0x1f000000, 0x01000000 },
++ { 0xea002640, ~0x1f000000, 0x01000000 },
++ { 0xea000840, ~0x1f000000, 0x01000000 },
++ { 0xea000a40, ~0x1f000000, 0x01000000 },
++ { 0xea002410, ~0xffff0000, 0x0d510000 },
++ { 0xea002610, ~0xffff0000, 0x0d510000 },
++ { 0xea000810, ~0xffff0000, 0x0d510000 },
++ { 0xea000a10, ~0xffff0000, 0x0d510000 },
++ { 0xea00242c, ~0x00020800, 0x00020000 },
++ { 0xea00262c, ~0x00020800, 0x00020000 },
++ { 0xea00082c, ~0x00020800, 0x00020000 },
++ { 0xea000a2c, ~0x00020800, 0x00020000 },
++ { 0xea002418, ~0xffff0300, 0x38250100 },
++ { 0xea002618, ~0xffff0300, 0x38250100 },
++ { 0xea000818, ~0xffff0300, 0x38250100 },
++ { 0xea000a18, ~0xffff0300, 0x38250100 },
++ { 0xea002400, ~0xcf030000, 0xcf030000 },
++ { 0xea002600, ~0xcf030000, 0xcf030000 },
++ { 0xea000800, ~0xcf030000, 0xcf030000 },
++ { 0xea000a00, ~0xcf030000, 0xcf030000 },
++ { 0xea002428, ~0xff1f0000, 0x580e0000 },
++ { 0xea002628, ~0xff1f0000, 0x580e0000 },
++ { 0xea000828, ~0xff1f0000, 0x580e0000 },
++ { 0xea000a28, ~0xff1f0000, 0x580e0000 },
++ { 0xea00241c, ~0x00007c00, 0x00002400 },
++ { 0xea00261c, ~0x00007c00, 0x00002400 },
++ { 0xea00081c, ~0x00007c00, 0x00002400 },
++ { 0xea000a1c, ~0x00007c00, 0x00002400 },
++ { 0xea00248c, ~0x00ff0000, 0x00800000 },
++ { 0xea00268c, ~0x00ff0000, 0x00800000 },
++ { 0xea00088c, ~0x00ff0000, 0x00800000 },
++ { 0xea000a8c, ~0x00ff0000, 0x00800000 },
++ { 0xea0024a4, ~0x0030ff00, 0x00308300 },
++ { 0xea0026a4, ~0x0030ff00, 0x00308300 },
++ { 0xea0008a4, ~0x0030ff00, 0x00308300 },
++ { 0xea000aa4, ~0x0030ff00, 0x00308300 },
++ { 0xea0024ac, ~0x00000030, 0x00000020 },
++ { 0xea0026ac, ~0x00000030, 0x00000020 },
++ { 0xea0008ac, ~0x00000030, 0x00000020 },
++ { 0xea000aac, ~0x00000030, 0x00000020 },
++ { 0xea002540, ~0x00ffffff, 0x00140718 },
++ { 0xea002740, ~0x00ffffff, 0x00140718 },
++ { 0xea000940, ~0x00ffffff, 0x00140718 },
++ { 0xea000b40, ~0x00ffffff, 0x00140718 },
++ { 0xea002544, ~0x00ffffff, 0x00140998 },
++ { 0xea002744, ~0x00ffffff, 0x00140998 },
++ { 0xea000944, ~0x00ffffff, 0x00140998 },
++ { 0xea000b44, ~0x00ffffff, 0x00140998 },
++ { 0xea002548, ~0x00ffffff, 0x00140998 },
++ { 0xea002748, ~0x00ffffff, 0x00140998 },
++ { 0xea000948, ~0x00ffffff, 0x00140998 },
++ { 0xea000b48, ~0x00ffffff, 0x00140998 },
++ { 0xea00257c, ~0x03000000, 0x03000000 },
++ { 0xea00277c, ~0x03000000, 0x03000000 },
++ { 0xea00097c, ~0x03000000, 0x03000000 },
++ { 0xea000b7c, ~0x03000000, 0x03000000 },
++ { 0xea002578, ~0x00001f00, 0x00001800 },
++ { 0xea002778, ~0x00001f00, 0x00001800 },
++ { 0xea000978, ~0x00001f00, 0x00001800 },
++ { 0xea000b78, ~0x00001f00, 0x00001800 },
++ { 0xea00250c, ~0x0038000f, 0x00000005 },
++ { 0xea00270c, ~0x0038000f, 0x00000005 },
++ { 0xea00090c, ~0x0038000f, 0x00000005 },
++ { 0xea000b0c, ~0x0038000f, 0x00000005 },
++};
++
++const struct hsio_table_row hsio_xhci_shared_lpt_h_cx[] = {
++ { 0xe9002c2c, ~0x00000700, 0x00000100 },
++ { 0xe9002e2c, ~0x00000700, 0x00000100 },
++ { 0xe9002dcc, ~0x00001407, 0x00001407 },
++ { 0xe9002fcc, ~0x00001407, 0x00001407 },
++ { 0xe9002d68, ~0x01000f3c, 0x00000a28 },
++ { 0xe9002f68, ~0x01000f3c, 0x00000a28 },
++ { 0xe9002d6c, ~0x000000ff, 0x0000003f },
++ { 0xe9002f6c, ~0x000000ff, 0x0000003f },
++ { 0xe9002d4c, ~0x00ffff00, 0x00120500 },
++ { 0xe9002f4c, ~0x00ffff00, 0x00120500 },
++ { 0xe9002d14, ~0x38000700, 0x00000100 },
++ { 0xe9002f14, ~0x38000700, 0x00000100 },
++ { 0xe9002d64, ~0x0000f000, 0x00005000 },
++ { 0xe9002f64, ~0x0000f000, 0x00005000 },
++ { 0xe9002d70, ~0x00000018, 0x00000000 },
++ { 0xe9002f70, ~0x00000018, 0x00000000 },
++ { 0xe9002c38, ~0x3f00000f, 0x0700000b },
++ { 0xe9002e38, ~0x3f00000f, 0x0700000b },
++ { 0xe9002d40, ~0x00800000, 0x00000000 },
++ { 0xe9002f40, ~0x00800000, 0x00000000 },
++};
++
++const struct hsio_table_row hsio_xhci_lpt_h_cx[] = {
++ { 0xe90031cc, ~0x00001407, 0x00001407 },
++ { 0xe90033cc, ~0x00001407, 0x00001407 },
++ { 0xe90015cc, ~0x00001407, 0x00001407 },
++ { 0xe90017cc, ~0x00001407, 0x00001407 },
++ { 0xe9003168, ~0x01000f3c, 0x00000a28 },
++ { 0xe9003368, ~0x01000f3c, 0x00000a28 },
++ { 0xe9001568, ~0x01000f3c, 0x00000a28 },
++ { 0xe9001768, ~0x01000f3c, 0x00000a28 },
++ { 0xe900316c, ~0x000000ff, 0x0000003f },
++ { 0xe900336c, ~0x000000ff, 0x0000003f },
++ { 0xe900156c, ~0x000000ff, 0x0000003f },
++ { 0xe900176c, ~0x000000ff, 0x0000003f },
++ { 0xe900314c, ~0x00ffff00, 0x00120500 },
++ { 0xe900334c, ~0x00ffff00, 0x00120500 },
++ { 0xe900154c, ~0x00ffff00, 0x00120500 },
++ { 0xe900174c, ~0x00ffff00, 0x00120500 },
++ { 0xe9003114, ~0x38000700, 0x00000100 },
++ { 0xe9003314, ~0x38000700, 0x00000100 },
++ { 0xe9001514, ~0x38000700, 0x00000100 },
++ { 0xe9001714, ~0x38000700, 0x00000100 },
++ { 0xe9003164, ~0x0000f000, 0x00005000 },
++ { 0xe9003364, ~0x0000f000, 0x00005000 },
++ { 0xe9001564, ~0x0000f000, 0x00005000 },
++ { 0xe9001764, ~0x0000f000, 0x00005000 },
++ { 0xe9003170, ~0x00000018, 0x00000000 },
++ { 0xe9003370, ~0x00000018, 0x00000000 },
++ { 0xe9001570, ~0x00000018, 0x00000000 },
++ { 0xe9001770, ~0x00000018, 0x00000000 },
++ { 0xe9003038, ~0x3f00000f, 0x0700000b },
++ { 0xe9003238, ~0x3f00000f, 0x0700000b },
++ { 0xe9001438, ~0x3f00000f, 0x0700000b },
++ { 0xe9001638, ~0x3f00000f, 0x0700000b },
++ { 0xe9003140, ~0x00800000, 0x00000000 },
++ { 0xe9003340, ~0x00800000, 0x00000000 },
++ { 0xe9001540, ~0x00800000, 0x00000000 },
++ { 0xe9001740, ~0x00800000, 0x00000000 },
++};
++
++void program_hsio_sata_lpt_h_cx(const bool is_mobile)
++{
++ const struct hsio_table_row *pch_hsio_table;
++ size_t len;
++
++ pch_hsio_table = hsio_sata_lpt_h_cx;
++ len = ARRAY_SIZE(hsio_sata_lpt_h_cx);
++ for (size_t i = 0; i < len; i++)
++ hsio_update_row(pch_hsio_table[i]);
++
++ pch_hsio_table = hsio_sata_shared_lpt_h_cx;
++ len = ARRAY_SIZE(hsio_sata_shared_lpt_h_cx);
++ for (size_t i = 0; i < len; i++)
++ hsio_sata_shared_update_row(pch_hsio_table[i]);
++
++ const uint32_t hsio_sata_value = is_mobile ? 0x00004c5a : 0x00003e67;
++
++ hsio_update(0xea002490, ~0x0000ffff, hsio_sata_value);
++ hsio_update(0xea002690, ~0x0000ffff, hsio_sata_value);
++ hsio_update(0xea000890, ~0x0000ffff, hsio_sata_value);
++ hsio_update(0xea000a90, ~0x0000ffff, hsio_sata_value);
++
++ hsio_sata_shared_update(0xea002090, ~0x0000ffff, hsio_sata_value);
++ hsio_sata_shared_update(0xea002290, ~0x0000ffff, hsio_sata_value);
++}
++
++void program_hsio_xhci_lpt_h_cx(void)
++{
++ const struct hsio_table_row *pch_hsio_table;
++ size_t len;
++
++ pch_hsio_table = hsio_xhci_lpt_h_cx;
++ len = ARRAY_SIZE(hsio_xhci_lpt_h_cx);
++
++ for (size_t i = 0; i < len; i++)
++ hsio_update_row(pch_hsio_table[i]);
++
++ pch_hsio_table = hsio_xhci_shared_lpt_h_cx;
++ len = ARRAY_SIZE(hsio_xhci_shared_lpt_h_cx);
++
++ for (size_t i = 0; i < len; i++)
++ hsio_xhci_shared_update_row(pch_hsio_table[i]);
++}
++
++void program_hsio_igbe_lpt_h_cx(void)
++{
++ const uint32_t strpfusecfg1 = pci_read_config32(PCI_DEV(0, 0x1c, 0), 0xfc);
++ if (!(strpfusecfg1 & (1 << 19)))
++ return;
++
++ const uint8_t gbe_port = (strpfusecfg1 >> 16) & 0x7;
++ const uint8_t lane_owner = pci_read_config8(PCI_DEV(0, 0x1c, 0), 0x410);
++ if (gbe_port == 0 && ((lane_owner >> 0) & 3) != 1)
++ return;
++
++ if (gbe_port == 1 && ((lane_owner >> 2) & 3) != 1)
++ return;
++
++ const uint32_t gbe_hsio_base = 0xe900 << 16 | (0x2e - 2 * gbe_port) << 8;
++ hsio_update(gbe_hsio_base + 0x08, ~0xf0000100, 0xe0000100);
++}
+diff --git a/src/southbridge/intel/lynxpoint/hsio/lpt_lp_bx.c b/src/southbridge/intel/lynxpoint/hsio/lpt_lp_bx.c
+new file mode 100644
+index 0000000000..24679e791a
+--- /dev/null
++++ b/src/southbridge/intel/lynxpoint/hsio/lpt_lp_bx.c
+@@ -0,0 +1,180 @@
++/* SPDX-License-Identifier: GPL-2.0-or-later */
++
++#include <device/pci_ops.h>
++#include <southbridge/intel/lynxpoint/iobp.h>
++#include <southbridge/intel/lynxpoint/hsio/hsio.h>
++#include <types.h>
++
++const struct hsio_table_row hsio_sata_shared_lpt_lp_bx[] = {
++ { 0xea008008, ~0xff000000, 0x1c000000 },
++ { 0xea002008, ~0xfffc6108, 0xea6c6108 },
++ { 0xea002208, ~0xfffc6108, 0xea6c6108 },
++ { 0xea002408, ~0xfffc6108, 0xea6c6108 },
++ { 0xea002608, ~0xfffc6108, 0xea6c6108 },
++ { 0xea002038, ~0x0000000f, 0x0000000d },
++ { 0xea002238, ~0x0000000f, 0x0000000d },
++ { 0xea002438, ~0x0000000f, 0x0000000d },
++ { 0xea002638, ~0x0000000f, 0x0000000d },
++ { 0xea00202c, ~0x00020f00, 0x00020100 },
++ { 0xea00222c, ~0x00020f00, 0x00020100 },
++ { 0xea00242c, ~0x00020f00, 0x00020100 },
++ { 0xea00262c, ~0x00020f00, 0x00020100 },
++ { 0xea002040, ~0x1f000000, 0x01000000 },
++ { 0xea002240, ~0x1f000000, 0x01000000 },
++ { 0xea002440, ~0x1f000000, 0x01000000 },
++ { 0xea002640, ~0x1f000000, 0x01000000 },
++ { 0xea002010, ~0xffff0000, 0x55510000 },
++ { 0xea002210, ~0xffff0000, 0x55510000 },
++ { 0xea002410, ~0xffff0000, 0x55510000 },
++ { 0xea002610, ~0xffff0000, 0x55510000 },
++ { 0xea002140, ~0x00ffffff, 0x00140718 },
++ { 0xea002340, ~0x00ffffff, 0x00140718 },
++ { 0xea002540, ~0x00ffffff, 0x00140718 },
++ { 0xea002740, ~0x00ffffff, 0x00140718 },
++ { 0xea002144, ~0x00ffffff, 0x00140998 },
++ { 0xea002344, ~0x00ffffff, 0x00140998 },
++ { 0xea002544, ~0x00ffffff, 0x00140998 },
++ { 0xea002744, ~0x00ffffff, 0x00140998 },
++ { 0xea002148, ~0x00ffffff, 0x00140998 },
++ { 0xea002348, ~0x00ffffff, 0x00140998 },
++ { 0xea002548, ~0x00ffffff, 0x00140998 },
++ { 0xea002748, ~0x00ffffff, 0x00140998 },
++ { 0xea00217c, ~0x03000000, 0x03000000 },
++ { 0xea00237c, ~0x03000000, 0x03000000 },
++ { 0xea00257c, ~0x03000000, 0x03000000 },
++ { 0xea00277c, ~0x03000000, 0x03000000 },
++ { 0xea00208c, ~0x00ff0000, 0x00800000 },
++ { 0xea00228c, ~0x00ff0000, 0x00800000 },
++ { 0xea00248c, ~0x00ff0000, 0x00800000 },
++ { 0xea00268c, ~0x00ff0000, 0x00800000 },
++ { 0xea0020a4, ~0x0030ff00, 0x00308300 },
++ { 0xea0022a4, ~0x0030ff00, 0x00308300 },
++ { 0xea0024a4, ~0x0030ff00, 0x00308300 },
++ { 0xea0026a4, ~0x0030ff00, 0x00308300 },
++ { 0xea0020ac, ~0x00000030, 0x00000020 },
++ { 0xea0022ac, ~0x00000030, 0x00000020 },
++ { 0xea0024ac, ~0x00000030, 0x00000020 },
++ { 0xea0026ac, ~0x00000030, 0x00000020 },
++ { 0xea002018, ~0xffff0300, 0x38250100 },
++ { 0xea002218, ~0xffff0300, 0x38250100 },
++ { 0xea002418, ~0xffff0300, 0x38250100 },
++ { 0xea002618, ~0xffff0300, 0x38250100 },
++ { 0xea002000, ~0xcf030000, 0xcf030000 },
++ { 0xea002200, ~0xcf030000, 0xcf030000 },
++ { 0xea002400, ~0xcf030000, 0xcf030000 },
++ { 0xea002600, ~0xcf030000, 0xcf030000 },
++ { 0xea002028, ~0xff1f0000, 0x580e0000 },
++ { 0xea002228, ~0xff1f0000, 0x580e0000 },
++ { 0xea002428, ~0xff1f0000, 0x580e0000 },
++ { 0xea002628, ~0xff1f0000, 0x580e0000 },
++ { 0xea00201c, ~0x00007c00, 0x00002400 },
++ { 0xea00221c, ~0x00007c00, 0x00002400 },
++ { 0xea00241c, ~0x00007c00, 0x00002400 },
++ { 0xea00261c, ~0x00007c00, 0x00002400 },
++ { 0xea002178, ~0x00001f00, 0x00001800 },
++ { 0xea002378, ~0x00001f00, 0x00001800 },
++ { 0xea002578, ~0x00001f00, 0x00001800 },
++ { 0xea002778, ~0x00001f00, 0x00001800 },
++ { 0xea00210c, ~0x0038000f, 0x00000005 },
++ { 0xea00230c, ~0x0038000f, 0x00000005 },
++ { 0xea00250c, ~0x0038000f, 0x00000005 },
++ { 0xea00270c, ~0x0038000f, 0x00000005 },
++};
++
++const struct hsio_table_row hsio_xhci_shared_lpt_lp_bx[] = {
++ { 0xe90025cc, ~0x00001407, 0x00001407 },
++ { 0xe90027cc, ~0x00001407, 0x00001407 },
++ { 0xe9002568, ~0x01000f3c, 0x00000a28 },
++ { 0xe9002768, ~0x01000f3c, 0x00000a28 },
++ { 0xe900242c, ~0x00000700, 0x00000100 },
++ { 0xe900262c, ~0x00000700, 0x00000100 },
++ { 0xe900256c, ~0x000000ff, 0x0000003f },
++ { 0xe900276c, ~0x000000ff, 0x0000003f },
++ { 0xe900254c, ~0x00ffff00, 0x00120500 },
++ { 0xe900274c, ~0x00ffff00, 0x00120500 },
++ { 0xe9002564, ~0x0000f000, 0x00005000 },
++ { 0xe9002764, ~0x0000f000, 0x00005000 },
++ { 0xe9002570, ~0x00000018, 0x00000000 },
++ { 0xe9002770, ~0x00000018, 0x00000000 },
++ { 0xe9002514, ~0x38000700, 0x00000100 },
++ { 0xe9002714, ~0x38000700, 0x00000100 },
++ { 0xe9002438, ~0x0000000f, 0x0000000b },
++ { 0xe9002638, ~0x0000000f, 0x0000000b },
++ { 0xe9002414, ~0x0000fe00, 0x00006600 },
++ { 0xe9002614, ~0x0000fe00, 0x00006600 },
++ { 0xe9002540, ~0x00800000, 0x00000000 },
++ { 0xe9002740, ~0x00800000, 0x00000000 },
++};
++
++const struct hsio_table_row hsio_xhci_lpt_lp_bx[] = {
++ { 0xe90021cc, ~0x00001407, 0x00001407 },
++ { 0xe90023cc, ~0x00001407, 0x00001407 },
++ { 0xe9002168, ~0x01000f3c, 0x00000a28 },
++ { 0xe9002368, ~0x01000f3c, 0x00000a28 },
++ { 0xe900216c, ~0x000000ff, 0x0000003f },
++ { 0xe900236c, ~0x000000ff, 0x0000003f },
++ { 0xe900214c, ~0x00ffff00, 0x00120500 },
++ { 0xe900234c, ~0x00ffff00, 0x00120500 },
++ { 0xe9002164, ~0x0000f000, 0x00005000 },
++ { 0xe9002364, ~0x0000f000, 0x00005000 },
++ { 0xe9002170, ~0x00000018, 0x00000000 },
++ { 0xe9002370, ~0x00000018, 0x00000000 },
++ { 0xe9002114, ~0x38000700, 0x00000100 },
++ { 0xe9002314, ~0x38000700, 0x00000100 },
++ { 0xe9002038, ~0x0000000f, 0x0000000b },
++ { 0xe9002238, ~0x0000000f, 0x0000000b },
++ { 0xe9002014, ~0x0000fe00, 0x00006600 },
++ { 0xe9002214, ~0x0000fe00, 0x00006600 },
++ { 0xe9002140, ~0x00800000, 0x00000000 },
++ { 0xe9002340, ~0x00800000, 0x00000000 },
++};
++
++void program_hsio_sata_lpt_lp_bx(const bool is_mobile)
++{
++ const struct hsio_table_row *pch_hsio_table;
++ size_t len;
++
++ pch_hsio_table = hsio_sata_shared_lpt_lp_bx;
++ len = ARRAY_SIZE(hsio_sata_shared_lpt_lp_bx);
++ for (size_t i = 0; i < len; i++)
++ hsio_sata_shared_update_row(pch_hsio_table[i]);
++
++ const uint32_t hsio_sata_value = is_mobile ? 0x00004c5a : 0x00003e67;
++
++ hsio_sata_shared_update(0xea002090, ~0x0000ffff, hsio_sata_value);
++ hsio_sata_shared_update(0xea002290, ~0x0000ffff, hsio_sata_value);
++ hsio_sata_shared_update(0xea002490, ~0x0000ffff, hsio_sata_value);
++ hsio_sata_shared_update(0xea002690, ~0x0000ffff, hsio_sata_value);
++}
++
++void program_hsio_xhci_lpt_lp_bx(void)
++{
++ const struct hsio_table_row *pch_hsio_table;
++ size_t len;
++
++ pch_hsio_table = hsio_xhci_lpt_lp_bx;
++ len = ARRAY_SIZE(hsio_xhci_lpt_lp_bx);
++
++ for (size_t i = 0; i < len; i++)
++ hsio_update_row(pch_hsio_table[i]);
++
++ pch_hsio_table = hsio_xhci_shared_lpt_lp_bx;
++ len = ARRAY_SIZE(hsio_xhci_shared_lpt_lp_bx);
++
++ for (size_t i = 0; i < len; i++)
++ hsio_xhci_shared_update_row(pch_hsio_table[i]);
++}
++
++void program_hsio_igbe_lpt_lp_bx(void)
++{
++ const uint32_t strpfusecfg1 = pci_read_config32(PCI_DEV(0, 0x1c, 0), 0xfc);
++ if (!(strpfusecfg1 & (1 << 19)))
++ return;
++
++ const uint8_t gbe_port = (strpfusecfg1 >> 16) & 0x7;
++ if (gbe_port > 5)
++ return;
++
++ const uint32_t gbe_hsio_base = 0xe900 << 16 | (0x08 + 2 * gbe_port) << 8;
++ hsio_update(gbe_hsio_base + 0x08, ~0xf0000100, 0xe0000100);
++}
+diff --git a/src/southbridge/intel/lynxpoint/pch.h b/src/southbridge/intel/lynxpoint/pch.h
+index 38a9349220..74b4d50017 100644
+--- a/src/southbridge/intel/lynxpoint/pch.h
++++ b/src/southbridge/intel/lynxpoint/pch.h
+@@ -117,6 +117,7 @@ void pch_dmi_setup_physical_layer(void);
+ void pch_dmi_tc_vc_mapping(u32 vc0, u32 vc1, u32 vcp, u32 vcm);
+ void early_usb_init(void);
+ void early_thermal_init(void);
++void early_pch_init_native(int s3resume);
+
+ void usb_ehci_sleep_prepare(pci_devfn_t dev, u8 slp_typ);
+ void usb_ehci_disable(pci_devfn_t dev);
+@@ -271,6 +272,10 @@ void mainboard_config_rcba(void);
+ #define IDE_DECODE_ENABLE (1 << 15)
+ #define IDE_TIM_SEC 0x42 /* IDE timings, secondary */
+
++#define SATA_MAP 0x90
++#define SATA_PCS 0x92
++#define SATA_SCLKG 0x94
++
+ #define SATA_SIRI 0xa0 /* SATA Indexed Register Index */
+ #define SATA_SIRD 0xa4 /* SATA Indexed Register Data */
+ #define SATA_SP 0xd0 /* Scratchpad */
+@@ -580,6 +585,7 @@ void mainboard_config_rcba(void);
+ #define D19IR 0x3168 /* 16bit */
+ #define ACPIIRQEN 0x31e0 /* 32bit */
+ #define OIC 0x31fe /* 16bit */
++#define PRSTS 0x3310 /* 32bit */
+ #define PMSYNC_CONFIG 0x33c4 /* 32bit */
+ #define PMSYNC_CONFIG2 0x33cc /* 32bit */
+ #define SOFT_RESET_CTRL 0x38f4
+--
+2.39.2
+