soc/intel/apollolake: Fix FSP SATA speed limit configuraion

With commit f165bbdcf043 ("soc/intel/apollolake: Make SATA speed limit
configurable") came the expansion to adjust the SATA speed.
Unfortunately, APL FSP-S sets only the default value, so Gen 3, and
ignores the passing parameter value. Since the corresponding register
entry can only be changed once, the setting must be made on coreboot
side before FSP-S is called. This patch fixes the SATA speed
configuration for Apollo Lake CPUs.

Link to Intel Pentium and Celeron N- and J- series datasheet volume 2:
https://web.archive.org/web/20230614130311/https://www.intel.com/content/www/us/en/content-details/334818/intel-pentium-and-celeron-processor-n-and-j-series-datasheet-volume-2.html

BUG=none
TEST=Boot into Linux and check SATA configuration via dmesg

ahci 0000:00:12.0: AHCI 0001.0301 32 slots 1 ports 3 Gbps 0x1 impl SATA
mode
ata1: SATA max UDMA/133 abar m2048@0x9872a000 port 0x9872a100 irq 126
ata1: SATA link up 3.0 Gbps (SStatus 123 SControl 300)

Change-Id: I6f55f40941fa618e7de13a5cefe9e17ae34c5c99
Signed-off-by: Mario Scheithauer <mario.scheithauer@siemens.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/75820
Reviewed-by: Felix Singer <service+coreboot-gerrit@felixsinger.de>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
diff --git a/src/soc/intel/apollolake/Makefile.inc b/src/soc/intel/apollolake/Makefile.inc
index 107a913..82937bc 100644
--- a/src/soc/intel/apollolake/Makefile.inc
+++ b/src/soc/intel/apollolake/Makefile.inc
@@ -46,6 +46,7 @@
 smm-y += xhci.c
 
 ramstage-$(CONFIG_HAVE_ACPI_TABLES) += acpi.c
+ramstage-y += ahci.c
 ramstage-y += cpu.c
 ramstage-y += chip.c
 ramstage-y += cse.c
diff --git a/src/soc/intel/apollolake/ahci.c b/src/soc/intel/apollolake/ahci.c
new file mode 100644
index 0000000..39121d7
--- /dev/null
+++ b/src/soc/intel/apollolake/ahci.c
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <console/console.h>
+#include <device/pci_ops.h>
+#include <soc/ahci.h>
+#include <soc/pci_devs.h>
+#include <soc/soc_chip.h>
+#include <types.h>
+
+void ahci_set_speed(enum sata_speed_limit speed)
+{
+	if (speed == SATA_DEFAULT)
+		return;
+
+	/* Setup temporary base address for BAR5. */
+	pci_write_config32(PCH_DEV_SATA, PCI_BASE_ADDRESS_5, AHCI_TMP_BASE_ADDR);
+	/* Enable memory access for pci_dev. */
+	pci_or_config16(PCH_DEV_SATA, PCI_COMMAND, PCI_COMMAND_MEMORY);
+
+	printk(BIOS_DEBUG, "AHCI: Set SATA speed to Gen %d\n", speed);
+	clrsetbits32((void *)(AHCI_TMP_BASE_ADDR + AHCI_CAP), AHCI_CAP_ISS_MASK,
+			AHCI_SPEED(speed));
+
+	/* Disable memory access for pci_dev. */
+	pci_and_config16(PCH_DEV_SATA, PCI_COMMAND, ~PCI_COMMAND_MEMORY);
+	/* Clear temporary base address for BAR5. */
+	pci_write_config32(PCH_DEV_SATA, PCI_BASE_ADDRESS_5, 0);
+}
diff --git a/src/soc/intel/apollolake/chip.c b/src/soc/intel/apollolake/chip.c
index 04aa2eb..9ec52b1 100644
--- a/src/soc/intel/apollolake/chip.c
+++ b/src/soc/intel/apollolake/chip.c
@@ -24,6 +24,7 @@
 #include <intelblocks/pmclib.h>
 #include <intelblocks/systemagent.h>
 #include <option.h>
+#include <soc/ahci.h>
 #include <soc/cpu.h>
 #include <soc/heci.h>
 #include <soc/intel/common/vbt.h>
@@ -736,7 +737,7 @@
 	/* SATA config */
 	if (is_devfn_enabled(PCH_DEVFN_SATA)) {
 		silconfig->SataSalpSupport = !(cfg->DisableSataSalpSupport);
-		silconfig->SpeedLimit = cfg->sata_speed;
+		ahci_set_speed(cfg->sata_speed);
 		memcpy(silconfig->SataPortsEnable, cfg->sata_ports_enable,
 			sizeof(silconfig->SataPortsEnable));
 		memcpy(silconfig->SataPortsSolidStateDrive, cfg->sata_ports_ssd,
diff --git a/src/soc/intel/apollolake/include/soc/ahci.h b/src/soc/intel/apollolake/include/soc/ahci.h
new file mode 100644
index 0000000..d129979
--- /dev/null
+++ b/src/soc/intel/apollolake/include/soc/ahci.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#ifndef _SOC_APOLLOLAKE_AHCI_H_
+#define _SOC_APOLLOLAKE_AHCI_H_
+
+#include <soc/soc_chip.h>
+
+#define AHCI_TMP_BASE_ADDR		0x9872c000
+
+#define AHCI_CAP			0x0
+#define AHCI_CAP_ISS_MASK		0x00f00000
+#define  AHCI_SPEED(speed)		(speed << 20)
+
+/* Set SATA controller speed. */
+void ahci_set_speed(enum sata_speed_limit speed);
+
+#endif /* _SOC_APOLLOLAKE_AHCI_H_ */