[coreboot-gerrit] Patch set updated for coreboot: fb4f375 baytrail: Add ACPI CPU entries

Aaron Durbin (adurbin@google.com) gerrit at coreboot.org
Tue May 6 17:28:12 CEST 2014


Aaron Durbin (adurbin at google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4954

-gerrit

commit fb4f37562a8bc8b729361d9f1f189ea885a67e2b
Author: Duncan Laurie <dlaurie at chromium.org>
Date:   Tue Nov 5 13:02:30 2013 -0800

    baytrail: Add ACPI CPU entries
    
    - C-state table based on static config
    MWAIT values are from ref code for non-S0ix config
    C6 substate 8 is ignored by the kernel as it violates the CPUID
    but it is left in as the other substate may not work.
    - P-state table generated with proper ratio and VID values
    relies on having the package power msr set to magic value
    as the power-on default is wrong
    - T-state table uses static table
    
    BUG=chrome-os-partner:23505
    BRANCH=rambi
    TEST=build and boot on rambi
    
    Change-Id: I7c997e58cb3a71d0ec413b17f0c5467bef4bf62c
    Signed-off-by: Duncan Laurie <dlaurie at chromium.org>
    Reviewed-on: https://chromium-review.googlesource.com/175742
    Reviewed-by: Aaron Durbin <adurbin at chromium.org>
    Commit-Queue: Aaron Durbin <adurbin at chromium.org>
    Signed-off-by: Aaron Durbin <adurbin at chromium.org>
---
 src/soc/intel/baytrail/acpi.c             | 245 ++++++++++++++++++++++++++++++
 src/soc/intel/baytrail/acpi/globalnvs.asl |   1 +
 src/soc/intel/baytrail/baytrail/nvs.h     |   3 +-
 src/soc/intel/baytrail/placeholders.c     |   2 -
 4 files changed, 248 insertions(+), 3 deletions(-)

diff --git a/src/soc/intel/baytrail/acpi.c b/src/soc/intel/baytrail/acpi.c
index ce7f5e4..1f358f4 100644
--- a/src/soc/intel/baytrail/acpi.c
+++ b/src/soc/intel/baytrail/acpi.c
@@ -24,14 +24,56 @@
 #include <arch/smp/mpspec.h>
 #include <console/console.h>
 #include <cpu/x86/smm.h>
+#include <console/console.h>
 #include <types.h>
 #include <string.h>
+#include <arch/cpu.h>
+#include <cpu/x86/msr.h>
+#include <cpu/x86/tsc.h>
+#include <cpu/intel/turbo.h>
 
 #include <baytrail/acpi.h>
 #include <baytrail/iomap.h>
 #include <baytrail/irq.h>
+#include <baytrail/msr.h>
+#include <baytrail/pattrs.h>
 #include <baytrail/pmc.h>
 
+#define MWAIT_RES(state, sub_state)                         \
+	{                                                   \
+		.addrl = (((state) << 4) | (sub_state)),    \
+		.space_id = ACPI_ADDRESS_SPACE_FIXED,       \
+		.bit_width = ACPI_FFIXEDHW_VENDOR_INTEL,    \
+		.bit_offset = ACPI_FFIXEDHW_CLASS_MWAIT,    \
+		.access_size = ACPI_FFIXEDHW_FLAG_HW_COORD, \
+	}
+
+/* C-state map without S0ix */
+static acpi_cstate_t cstate_map[] = {
+	{
+		/* C1 */
+		.ctype = 1, /* ACPI C1 */
+		.latency = 1,
+		.power = 1000,
+		.resource = MWAIT_RES(0, 0),
+	},
+	{
+		/* C6NS with no L2 shrink */
+		/* NOTE: this substate is above CPUID limit */
+		.ctype = 2, /* ACPI C2 */
+		.latency = 500,
+		.power = 10,
+		.resource = MWAIT_RES(5, 8),
+	},
+	{
+		/* C6FS with full L2 shrink */
+		.ctype = 3, /* ACPI C3 */
+		.latency = 1500, /* 1.5ms worst case */
+		.power = 10,
+		.resource = MWAIT_RES(5, 2),
+	}
+};
+
 static int acpi_sci_irq(void)
 {
 	const unsigned long actl = ILB_BASE_ADDRESS + ACTL;
@@ -210,7 +252,210 @@ void acpi_fill_in_fadt(acpi_fadt_t *fadt)
 	fadt->x_gpe1_blk.resv = 0;
 	fadt->x_gpe1_blk.addrl = 0x0;
 	fadt->x_gpe1_blk.addrh = 0x0;
+}
+
+static acpi_tstate_t baytrail_tss_table[] = {
+	{ 100, 1000, 0, 0x00, 0 },
+	{ 88, 875, 0, 0x1e, 0 },
+	{ 75, 750, 0, 0x1c, 0 },
+	{ 63, 625, 0, 0x1a, 0 },
+	{ 50, 500, 0, 0x18, 0 },
+	{ 38, 375, 0, 0x16, 0 },
+	{ 25, 250, 0, 0x14, 0 },
+	{ 13, 125, 0, 0x12, 0 },
+};
+
+static int generate_T_state_entries(int core, int cores_per_package)
+{
+	int len;
+
+	/* Indicate SW_ALL coordination for T-states */
+	len = acpigen_write_TSD_package(core, cores_per_package, SW_ALL);
+
+	/* Indicate FFixedHW so OS will use MSR */
+	len += acpigen_write_empty_PTC();
+
+	/* Set NVS controlled T-state limit */
+	len += acpigen_write_TPC("\\TLVL");
+
+	/* Write TSS table for MSR access */
+	len += acpigen_write_TSS_package(
+		ARRAY_SIZE(baytrail_tss_table), baytrail_tss_table);
+
+	return len;
+}
+
+static int calculate_power(int tdp, int p1_ratio, int ratio)
+{
+	u32 m;
+	u32 power;
+
+	/*
+	 * M = ((1.1 - ((p1_ratio - ratio) * 0.00625)) / 1.1) ^ 2
+	 *
+	 * Power = (ratio / p1_ratio) * m * tdp
+	 */
 
+	m = (110000 - ((p1_ratio - ratio) * 625)) / 11;
+	m = (m * m) / 1000;
+
+	power = ((ratio * 100000 / p1_ratio) / 100);
+	power *= (m / 100) * (tdp / 1000);
+	power /= 1000;
+
+	return (int)power;
+}
+
+static int generate_P_state_entries(int core, int cores_per_package)
+{
+	int len, len_pss;
+	int ratio_min, ratio_max, ratio_turbo, ratio_step, ratio_range_2;
+	int coord_type, power_max, power_unit, num_entries;
+	int ratio, power, clock, clock_max;
+	int vid, vid_turbo, vid_min, vid_max, vid_range_2;
+	u32 control_status;
+	const struct pattrs *pattrs = pattrs_get();
+	msr_t msr;
+
+	/* Inputs from CPU attributes */
+	ratio_max = pattrs->iacore_ratios[IACORE_MAX];
+	ratio_min = pattrs->iacore_ratios[IACORE_LFM];
+	vid_max = pattrs->iacore_vids[IACORE_MAX];
+	vid_min = pattrs->iacore_vids[IACORE_LFM];
+
+	/* Hardware coordination of P-states */
+	coord_type = HW_ALL;
+
+	/* Max Non-Turbo Frequency */
+	clock_max = (ratio_max * pattrs->bclk_khz) / 1000;
+
+	/* Calculate CPU TDP in mW */
+	msr = rdmsr(MSR_PKG_POWER_SKU_UNIT);
+	power_unit = 1 << (msr.lo & 0xf);
+	msr = rdmsr(MSR_PKG_POWER_LIMIT);
+	power_max = ((msr.lo & 0x7fff) / power_unit) * 1000;
+
+	/* Write _PCT indicating use of FFixedHW */
+	len = acpigen_write_empty_PCT();
+
+	/* Write _PPC with no limit on supported P-state */
+	len += acpigen_write_PPC(0);
+
+	/* Write PSD indicating configured coordination type */
+	len += acpigen_write_PSD_package(core, 1, coord_type);
+
+	/* Add P-state entries in _PSS table */
+	len += acpigen_write_name("_PSS");
+
+	/* Determine ratio points */
+	ratio_step = 1;
+	num_entries = (ratio_max - ratio_min) / ratio_step;
+	while (num_entries > 15) { /* ACPI max is 15 ratios */
+		ratio_step <<= 1;
+		num_entries >>= 1;
+	}
+
+	/* P[T] is Turbo state if enabled */
+	if (get_turbo_state() == TURBO_ENABLED) {
+		/* _PSS package count including Turbo */
+		len_pss = acpigen_write_package(num_entries + 2);
+
+		ratio_turbo = pattrs->iacore_ratios[IACORE_TURBO];
+		vid_turbo = pattrs->iacore_vids[IACORE_TURBO];
+		control_status = (ratio_turbo << 8) | vid_turbo;
+
+		/* Add entry for Turbo ratio */
+		len_pss += acpigen_write_PSS_package(
+			clock_max + 1,		/*MHz*/
+			power_max,		/*mW*/
+			10,			/*lat1*/
+			10,			/*lat2*/
+			control_status,		/*control*/
+			control_status);	/*status*/
+	} else {
+		/* _PSS package count without Turbo */
+		len_pss = acpigen_write_package(num_entries + 1);
+		ratio_turbo = ratio_max;
+		vid_turbo = vid_max;
+	}
+
+	/* First regular entry is max non-turbo ratio */
+	control_status = (ratio_max << 8) | vid_max;
+	len_pss += acpigen_write_PSS_package(
+		clock_max,		/*MHz*/
+		power_max,		/*mW*/
+		10,			/*lat1*/
+		10,			/*lat2*/
+		control_status,		/*control */
+		control_status);	/*status*/
+
+	/* Set up ratio and vid ranges for VID calculation */
+	ratio_range_2 = (ratio_turbo - ratio_min) * 2;
+	vid_range_2 = (vid_turbo - vid_min) * 2;
+
+	/* Generate the remaining entries */
+	for (ratio = ratio_min + ((num_entries - 1) * ratio_step);
+	     ratio >= ratio_min; ratio -= ratio_step) {
+
+		/* Calculate VID for this ratio */
+		vid = ((ratio - ratio_min) * vid_range_2) /
+			ratio_range_2 + vid_min;
+		/* Round up if remainder */
+		if (((ratio - ratio_min) * vid_range_2) % ratio_range_2)
+			vid++;
+
+		/* Calculate power at this ratio */
+		power = calculate_power(power_max, ratio_max, ratio);
+		clock = (ratio * pattrs->bclk_khz) / 1000;
+		control_status = (ratio << 8) | (vid & 0xff);
+
+		len_pss += acpigen_write_PSS_package(
+			clock,			/*MHz*/
+			power,			/*mW*/
+			10,			/*lat1*/
+			10,			/*lat2*/
+			control_status,		/*control*/
+			control_status);	/*status*/
+	}
+
+	/* Fix package length */
+	len_pss--;
+	acpigen_patch_len(len_pss);
+
+	return len + len_pss;
+}
+
+void generate_cpu_entries(void)
+{
+	int len_pr, core;
+	int pcontrol_blk = get_pmbase(), plen = 6;
+	const struct pattrs *pattrs = pattrs_get();
+
+	for (core=0; core<pattrs->num_cpus; core++) {
+		if (core > 0) {
+			pcontrol_blk = 0;
+			plen = 0;
+		}
+
+		/* Generate processor \_PR.CPUx */
+		len_pr = acpigen_write_processor(
+			core, pcontrol_blk, plen);
+
+		/* Generate  P-state tables */
+		len_pr += generate_P_state_entries(
+			core, pattrs->num_cpus);
+
+		/* Generate C-state tables */
+		len_pr += acpigen_write_CST_package(
+			cstate_map, ARRAY_SIZE(cstate_map));
+
+		/* Generate T-state tables */
+		len_pr += generate_T_state_entries(
+			core, pattrs->num_cpus);
+
+		len_pr--;
+		acpigen_patch_len(len_pr);
+	}
 }
 
 unsigned long acpi_madt_irq_overrides(unsigned long current)
diff --git a/src/soc/intel/baytrail/acpi/globalnvs.asl b/src/soc/intel/baytrail/acpi/globalnvs.asl
index 37a234c..2f614a9 100644
--- a/src/soc/intel/baytrail/acpi/globalnvs.asl
+++ b/src/soc/intel/baytrail/acpi/globalnvs.asl
@@ -50,6 +50,7 @@ Field (GNVS, ByteAcc, NoLock, Preserve)
 	PWRS,	 8,	// 0x10 - Power State (AC = 1)
 	PCNT,	 8,	// 0x11 - Processor count
 	TPMP,	 8,	// 0x12 - TPM Present and Enabled
+	TLVL,	 8,	// 0x13 - Throttle Level
 
 	/* Device Config */
 	Offset (0x20),
diff --git a/src/soc/intel/baytrail/baytrail/nvs.h b/src/soc/intel/baytrail/baytrail/nvs.h
index e261e7c..aed0974 100644
--- a/src/soc/intel/baytrail/baytrail/nvs.h
+++ b/src/soc/intel/baytrail/baytrail/nvs.h
@@ -36,7 +36,8 @@ typedef struct {
 	u8	pwrs; /* 0x10 - Power state (AC = 1) */
 	u8	pcnt; /* 0x11 - Processor Count */
 	u8	tpmp; /* 0x12 - TPM Present and Enabled */
-	u8	rsvd1[13];
+	u8	tlvl; /* 0x13 - Throttle Level */
+	u8	rsvd1[12];
 
 	/* Device Config */
 	u8	s5u0; /* 0x20 - Enable USB0 in S5 */
diff --git a/src/soc/intel/baytrail/placeholders.c b/src/soc/intel/baytrail/placeholders.c
index b10b7e6..9e1413d 100644
--- a/src/soc/intel/baytrail/placeholders.c
+++ b/src/soc/intel/baytrail/placeholders.c
@@ -5,8 +5,6 @@
 #include <baytrail/acpi.h>
 
 
-void generate_cpu_entries(void) {}
-
 void smm_init(void) {}
 
 /* Rmodules don't like weak symbols. */



More information about the coreboot-gerrit mailing list