summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/soc/intel/apollolake/Makefile.inc1
-rw-r--r--src/soc/intel/apollolake/ahci.c28
-rw-r--r--src/soc/intel/apollolake/chip.c3
-rw-r--r--src/soc/intel/apollolake/include/soc/ahci.h17
4 files changed, 48 insertions, 1 deletions
diff --git a/src/soc/intel/apollolake/Makefile.inc b/src/soc/intel/apollolake/Makefile.inc
index 107a913932..82937bc9a6 100644
--- a/src/soc/intel/apollolake/Makefile.inc
+++ b/src/soc/intel/apollolake/Makefile.inc
@@ -46,6 +46,7 @@ smm-y += elog.c
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 0000000000..39121d7114
--- /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 04aa2ebd99..9ec52b1b41 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 @@ void platform_fsp_silicon_init_params_cb(FSPS_UPD *silupd)
/* 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 0000000000..d129979327
--- /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_ */