summaryrefslogtreecommitdiff
path: root/drivers/acpi/cppc_acpi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/cppc_acpi.c')
-rw-r--r--drivers/acpi/cppc_acpi.c34
1 files changed, 24 insertions, 10 deletions
diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
index f370be8715ae..9f572f481241 100644
--- a/drivers/acpi/cppc_acpi.c
+++ b/drivers/acpi/cppc_acpi.c
@@ -134,7 +134,7 @@ static DEFINE_PER_CPU(struct cpc_desc *, cpc_desc_ptr);
* cpc_regs[] with the corresponding index. 0 means mandatory and 1
* means optional.
*/
-#define REG_OPTIONAL (0x1FC7D0)
+#define REG_OPTIONAL (0x7FC7D0)
/*
* Use the index of the register in per-cpu cpc_regs[] to check if
@@ -185,8 +185,13 @@ show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, nominal_freq);
show_cppc_data(cppc_get_perf_ctrs, cppc_perf_fb_ctrs, wraparound_time);
-/* Check for valid access_width, otherwise, fallback to using bit_width */
-#define GET_BIT_WIDTH(reg) ((reg)->access_width ? (8 << ((reg)->access_width - 1)) : (reg)->bit_width)
+/*
+ * PCC reuses the access_width field as the subspace id, so only decode access
+ * size for non-PCC registers. Otherwise, use the bit_width.
+ */
+#define GET_BIT_WIDTH(reg) (((reg)->access_width && \
+ (reg)->space_id != ACPI_ADR_SPACE_PLATFORM_COMM) ? \
+ (8 << ((reg)->access_width - 1)) : (reg)->bit_width)
/* Shift and apply the mask for CPC reads/writes */
#define MASK_VAL_READ(reg, val) (((val) >> (reg)->bit_offset) & \
@@ -751,18 +756,19 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
/*
* Disregard _CPC if the number of entries in the return package is not
* as expected, but support future revisions being proper supersets of
- * the v3 and only causing more entries to be returned by _CPC.
+ * the v4 and only causing more entries to be returned by _CPC.
*/
if ((cpc_rev == CPPC_V2_REV && num_ent != CPPC_V2_NUM_ENT) ||
(cpc_rev == CPPC_V3_REV && num_ent != CPPC_V3_NUM_ENT) ||
- (cpc_rev > CPPC_V3_REV && num_ent <= CPPC_V3_NUM_ENT)) {
+ (cpc_rev == CPPC_V4_REV && num_ent != CPPC_V4_NUM_ENT) ||
+ (cpc_rev > CPPC_V4_REV && num_ent <= CPPC_V4_NUM_ENT)) {
pr_debug("Unexpected number of _CPC return package entries (%d) for CPU:%d\n",
num_ent, pr->id);
goto out_free;
}
- if (cpc_rev > CPPC_V3_REV) {
- num_ent = CPPC_V3_NUM_ENT;
- cpc_rev = CPPC_V3_REV;
+ if (cpc_rev > CPPC_V4_REV) {
+ num_ent = CPPC_V4_NUM_ENT;
+ cpc_rev = CPPC_V4_REV;
}
cpc_ptr->num_entries = num_ent;
@@ -845,6 +851,16 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
cpc_ptr->cpc_regs[i-2].type = ACPI_TYPE_BUFFER;
memcpy(&cpc_ptr->cpc_regs[i-2].cpc_entry.reg, gas_t, sizeof(*gas_t));
+ } else if (cpc_obj->type == ACPI_TYPE_PACKAGE && (i - 2) == RESOURCE_PRIORITY) {
+ /*
+ * ACPI 6.6, s8.4.6.1.2.7 defines Resource Priority as a
+ * Package of Resource Priority Register Descriptor sub-packages.
+ * Parsing the full structure is not yet supported.
+ * Mark the register as unsupported for now.
+ */
+ pr_debug("CPU:%d Resource Priority not supported\n", pr->id);
+ cpc_ptr->cpc_regs[i-2].type = ACPI_TYPE_INTEGER;
+ cpc_ptr->cpc_regs[i-2].cpc_entry.int_value = 0;
} else {
pr_debug("Invalid entry type (%d) in _CPC for CPU:%d\n",
i, pr->id);
@@ -1045,7 +1061,6 @@ static int cpc_read(int cpu, struct cpc_register_resource *reg_res, u64 *val)
* by the bit width field; the access size is used to indicate
* the PCC subspace id.
*/
- size = reg->bit_width;
vaddr = GET_PCC_VADDR(reg->address, pcc_ss_id);
}
else if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
@@ -1118,7 +1133,6 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val)
* by the bit width field; the access size is used to indicate
* the PCC subspace id.
*/
- size = reg->bit_width;
vaddr = GET_PCC_VADDR(reg->address, pcc_ss_id);
}
else if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)