arch/x86/acpigen: add methods for cppc
This change adds 2 methods for Conginuous Performance Control that was added in ACPI 5.0 and expanded twice in later versions. One function will create a global table based on a provided struct, while the other function is used to add a _CPC method in each processor object. Change-Id: I8798a4c72c681b960087ed65668f01b2ca77d2ce Signed-off-by: Matt Delco <delco@chromium.org> Reviewed-on: https://review.coreboot.org/28066 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Aaron Durbin <adurbin@chromium.org> Reviewed-by: Furquan Shaikh <furquan@google.com>
This commit is contained in:
parent
e37d771001
commit
b425bc8cd0
|
@ -1339,6 +1339,55 @@ void acpigen_write_dsm_uuid_arr(struct dsm_uuid *ids, size_t count)
|
||||||
acpigen_pop_len(); /* Method _DSM */
|
acpigen_pop_len(); /* Method _DSM */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define CPPC_PACKAGE_NAME "\\GCPC"
|
||||||
|
|
||||||
|
void acpigen_write_CPPC_package(const struct cppc_config *config)
|
||||||
|
{
|
||||||
|
u32 i;
|
||||||
|
u32 max;
|
||||||
|
switch (config->version) {
|
||||||
|
case 1:
|
||||||
|
max = CPPC_MAX_FIELDS_VER_1;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
max = CPPC_MAX_FIELDS_VER_2;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
max = CPPC_MAX_FIELDS_VER_3;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printk(BIOS_ERR, "ERROR: CPPC version %u is not implemented\n",
|
||||||
|
config->version);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
acpigen_write_name(CPPC_PACKAGE_NAME);
|
||||||
|
|
||||||
|
/* Adding 2 to account for length and version fields */
|
||||||
|
acpigen_write_package(max + 2);
|
||||||
|
acpigen_write_dword(max + 2);
|
||||||
|
|
||||||
|
acpigen_write_byte(config->version);
|
||||||
|
|
||||||
|
for (i = 0; i < max; ++i) {
|
||||||
|
const acpi_addr_t *reg = &(config->regs[i]);
|
||||||
|
if (reg->space_id == ACPI_ADDRESS_SPACE_MEMORY &&
|
||||||
|
reg->bit_width == 32 && reg->access_size == 0) {
|
||||||
|
acpigen_write_dword(reg->addrl);
|
||||||
|
} else {
|
||||||
|
acpigen_write_register_resource(reg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
acpigen_pop_len();
|
||||||
|
}
|
||||||
|
|
||||||
|
void acpigen_write_CPPC_method(void)
|
||||||
|
{
|
||||||
|
acpigen_write_method("_CPC", 0);
|
||||||
|
acpigen_emit_byte(RETURN_OP);
|
||||||
|
acpigen_emit_namestring(CPPC_PACKAGE_NAME);
|
||||||
|
acpigen_pop_len();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generate ACPI AML code for _ROM method.
|
* Generate ACPI AML code for _ROM method.
|
||||||
* This function takes as input ROM data and ROM length.
|
* This function takes as input ROM data and ROM length.
|
||||||
|
|
|
@ -167,6 +167,56 @@ struct dsm_uuid {
|
||||||
void *arg;
|
void *arg;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*version 1 has 15 fields, version 2 has 19, and version 3 has 21 */
|
||||||
|
enum cppc_fields {
|
||||||
|
CPPC_HIGHEST_PERF, /* can be DWORD */
|
||||||
|
CPPC_NOMINAL_PERF, /* can be DWORD */
|
||||||
|
CPPC_LOWEST_NONL_PERF, /* can be DWORD */
|
||||||
|
CPPC_LOWEST_PERF, /* can be DWORD */
|
||||||
|
CPPC_GUARANTEED_PERF,
|
||||||
|
CPPC_DESIRED_PERF,
|
||||||
|
CPPC_MIN_PERF,
|
||||||
|
CPPC_MAX_PERF,
|
||||||
|
CPPC_PERF_REDUCE_TOLERANCE,
|
||||||
|
CPPC_TIME_WINDOW,
|
||||||
|
CPPC_COUNTER_WRAP, /* can be DWORD */
|
||||||
|
CPPC_REF_PERF_COUNTER,
|
||||||
|
CPPC_DELIVERED_PERF_COUNTER,
|
||||||
|
CPPC_PERF_LIMITED,
|
||||||
|
CPPC_ENABLE, /* can be System I/O */
|
||||||
|
CPPC_MAX_FIELDS_VER_1,
|
||||||
|
CPPC_AUTO_SELECT = /* can be DWORD */
|
||||||
|
CPPC_MAX_FIELDS_VER_1,
|
||||||
|
CPPC_AUTO_ACTIVITY_WINDOW,
|
||||||
|
CPPC_PERF_PREF,
|
||||||
|
CPPC_REF_PERF, /* can be DWORD */
|
||||||
|
CPPC_MAX_FIELDS_VER_2,
|
||||||
|
CPPC_LOWEST_FREQ = /* can be DWORD */
|
||||||
|
CPPC_MAX_FIELDS_VER_2,
|
||||||
|
CPPC_NOMINAL_FREQ, /* can be DWORD */
|
||||||
|
CPPC_MAX_FIELDS_VER_3,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cppc_config {
|
||||||
|
u32 version; /* must be 1, 2, or 3 */
|
||||||
|
/*
|
||||||
|
* The generic acpi_addr_t structure is being used, though
|
||||||
|
* anything besides PPC or FFIXED generally requires checking
|
||||||
|
* if the OS has advertised support for it (via _OSC).
|
||||||
|
*
|
||||||
|
* NOTE: some fields permit DWORDs to be used. If you
|
||||||
|
* provide a System Memory register with all zeros (which
|
||||||
|
* represents unsupported) then this will be used as-is.
|
||||||
|
* Otherwise, a System Memory register with a 32-bit
|
||||||
|
* width will be converted into a DWORD field (the value
|
||||||
|
* of which will be the value of 'addrl'. Any other use
|
||||||
|
* of System Memory register is currently undefined.
|
||||||
|
* (i.e., if you have an actual need for System Memory
|
||||||
|
* then you'll need to adjust this kludge).
|
||||||
|
*/
|
||||||
|
acpi_addr_t regs[CPPC_MAX_FIELDS_VER_3];
|
||||||
|
};
|
||||||
|
|
||||||
void acpigen_write_return_integer(uint64_t arg);
|
void acpigen_write_return_integer(uint64_t arg);
|
||||||
void acpigen_write_return_string(const char *arg);
|
void acpigen_write_return_string(const char *arg);
|
||||||
void acpigen_write_len_f(void);
|
void acpigen_write_len_f(void);
|
||||||
|
@ -268,6 +318,15 @@ void acpigen_write_dsm(const char *uuid, void (**callbacks)(void *),
|
||||||
size_t count, void *arg);
|
size_t count, void *arg);
|
||||||
void acpigen_write_dsm_uuid_arr(struct dsm_uuid *ids, size_t count);
|
void acpigen_write_dsm_uuid_arr(struct dsm_uuid *ids, size_t count);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generate ACPI AML code for _CPC (Continuous Perfmance Control).
|
||||||
|
* Execute the package function once to create a global table, then
|
||||||
|
* execute the method function within each processor object to
|
||||||
|
* create a method that points to the global table.
|
||||||
|
*/
|
||||||
|
void acpigen_write_CPPC_package(const struct cppc_config *config);
|
||||||
|
void acpigen_write_CPPC_method(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generate ACPI AML code for _ROM method.
|
* Generate ACPI AML code for _ROM method.
|
||||||
* This function takes as input ROM data and ROM length.
|
* This function takes as input ROM data and ROM length.
|
||||||
|
|
Loading…
Reference in New Issue