aboutsummaryrefslogtreecommitdiff
path: root/arch/x86/cpu
diff options
context:
space:
mode:
authorAndy Shevchenko2017-10-03 14:55:07 +0300
committerBin Meng2017-10-07 15:07:59 +0800
commit39665beed6f741fd8ae6ebf23d07fbd546a0d55e (patch)
treec04c918b4a6bbe45b903af031806d9f01dacd53c /arch/x86/cpu
parentb6519b777d4a2fa3ee8a94e269f13afb79bacf6b (diff)
x86: tangier: Enable ACPI support for Intel Tangier
Intel Tangier SoC is a part of Intel Merrifield platform which doesn't utilize ACPI by default. Here is an attempt to unleash ACPI flexibility power on Intel Merrifield based platforms. The change brings minimum support of the devices that found on Intel Merrifield based end user device. Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Diffstat (limited to 'arch/x86/cpu')
-rw-r--r--arch/x86/cpu/tangier/Makefile1
-rw-r--r--arch/x86/cpu/tangier/acpi.c87
2 files changed, 88 insertions, 0 deletions
diff --git a/arch/x86/cpu/tangier/Makefile b/arch/x86/cpu/tangier/Makefile
index d146b3f5c28..92cfa555ed4 100644
--- a/arch/x86/cpu/tangier/Makefile
+++ b/arch/x86/cpu/tangier/Makefile
@@ -5,3 +5,4 @@
#
obj-y += car.o tangier.o sdram.o
+obj-$(CONFIG_GENERATE_ACPI_TABLE) += acpi.o
diff --git a/arch/x86/cpu/tangier/acpi.c b/arch/x86/cpu/tangier/acpi.c
new file mode 100644
index 00000000000..75e777dcd76
--- /dev/null
+++ b/arch/x86/cpu/tangier/acpi.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2017 Intel Corporation
+ *
+ * Partially based on acpi.c for other x86 platforms
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <cpu.h>
+#include <dm.h>
+#include <dm/uclass-internal.h>
+#include <asm/acpi_table.h>
+#include <asm/ioapic.h>
+#include <asm/mpspec.h>
+#include <asm/tables.h>
+#include <asm/arch/global_nvs.h>
+
+void acpi_create_fadt(struct acpi_fadt *fadt, struct acpi_facs *facs,
+ void *dsdt)
+{
+ struct acpi_table_header *header = &(fadt->header);
+
+ memset((void *)fadt, 0, sizeof(struct acpi_fadt));
+
+ acpi_fill_header(header, "FACP");
+ header->length = sizeof(struct acpi_fadt);
+ header->revision = 6;
+
+ fadt->firmware_ctrl = (u32)facs;
+ fadt->dsdt = (u32)dsdt;
+ fadt->preferred_pm_profile = ACPI_PM_UNSPECIFIED;
+
+ fadt->iapc_boot_arch = ACPI_FADT_VGA_NOT_PRESENT |
+ ACPI_FADT_NO_PCIE_ASPM_CONTROL;
+ fadt->flags =
+ ACPI_FADT_WBINVD |
+ ACPI_FADT_POWER_BUTTON | ACPI_FADT_SLEEP_BUTTON |
+ ACPI_FADT_SEALED_CASE | ACPI_FADT_HEADLESS |
+ ACPI_FADT_HW_REDUCED_ACPI;
+
+ fadt->minor_revision = 2;
+
+ fadt->x_firmware_ctl_l = (u32)facs;
+ fadt->x_firmware_ctl_h = 0;
+ fadt->x_dsdt_l = (u32)dsdt;
+ fadt->x_dsdt_h = 0;
+
+ header->checksum = table_compute_checksum(fadt, header->length);
+}
+
+u32 acpi_fill_madt(u32 current)
+{
+ current += acpi_create_madt_lapics(current);
+
+ current += acpi_create_madt_ioapic((struct acpi_madt_ioapic *)current,
+ io_apic_read(IO_APIC_ID) >> 24, IO_APIC_ADDR, 0);
+
+ return current;
+}
+
+u32 acpi_fill_mcfg(u32 current)
+{
+ /* TODO: Derive parameters from SFI MCFG table */
+ current += acpi_create_mcfg_mmconfig
+ ((struct acpi_mcfg_mmconfig *)current,
+ 0x3f500000, 0x0, 0x0, 0x0);
+
+ return current;
+}
+
+void acpi_create_gnvs(struct acpi_global_nvs *gnvs)
+{
+ struct udevice *dev;
+ int ret;
+
+ /* at least we have one processor */
+ gnvs->pcnt = 1;
+
+ /* override the processor count with actual number */
+ ret = uclass_find_first_device(UCLASS_CPU, &dev);
+ if (ret == 0 && dev != NULL) {
+ ret = cpu_get_count(dev);
+ if (ret > 0)
+ gnvs->pcnt = ret;
+ }
+}