aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq/acpi-cpufreq.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/cpufreq/acpi-cpufreq.c')
-rw-r--r--drivers/cpufreq/acpi-cpufreq.c43
1 files changed, 37 insertions, 6 deletions
diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c
index 56c6c6b4eb4d..067a61f06bb5 100644
--- a/drivers/cpufreq/acpi-cpufreq.c
+++ b/drivers/cpufreq/acpi-cpufreq.c
@@ -54,10 +54,12 @@ MODULE_LICENSE("GPL");
54enum { 54enum {
55 UNDEFINED_CAPABLE = 0, 55 UNDEFINED_CAPABLE = 0,
56 SYSTEM_INTEL_MSR_CAPABLE, 56 SYSTEM_INTEL_MSR_CAPABLE,
57 SYSTEM_AMD_MSR_CAPABLE,
57 SYSTEM_IO_CAPABLE, 58 SYSTEM_IO_CAPABLE,
58}; 59};
59 60
60#define INTEL_MSR_RANGE (0xffff) 61#define INTEL_MSR_RANGE (0xffff)
62#define AMD_MSR_RANGE (0x7)
61 63
62struct acpi_cpufreq_data { 64struct acpi_cpufreq_data {
63 struct acpi_processor_performance *acpi_data; 65 struct acpi_processor_performance *acpi_data;
@@ -82,6 +84,13 @@ static int check_est_cpu(unsigned int cpuid)
82 return cpu_has(cpu, X86_FEATURE_EST); 84 return cpu_has(cpu, X86_FEATURE_EST);
83} 85}
84 86
87static int check_amd_hwpstate_cpu(unsigned int cpuid)
88{
89 struct cpuinfo_x86 *cpu = &cpu_data(cpuid);
90
91 return cpu_has(cpu, X86_FEATURE_HW_PSTATE);
92}
93
85static unsigned extract_io(u32 value, struct acpi_cpufreq_data *data) 94static unsigned extract_io(u32 value, struct acpi_cpufreq_data *data)
86{ 95{
87 struct acpi_processor_performance *perf; 96 struct acpi_processor_performance *perf;
@@ -101,7 +110,11 @@ static unsigned extract_msr(u32 msr, struct acpi_cpufreq_data *data)
101 int i; 110 int i;
102 struct acpi_processor_performance *perf; 111 struct acpi_processor_performance *perf;
103 112
104 msr &= INTEL_MSR_RANGE; 113 if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
114 msr &= AMD_MSR_RANGE;
115 else
116 msr &= INTEL_MSR_RANGE;
117
105 perf = data->acpi_data; 118 perf = data->acpi_data;
106 119
107 for (i = 0; data->freq_table[i].frequency != CPUFREQ_TABLE_END; i++) { 120 for (i = 0; data->freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
@@ -115,6 +128,7 @@ static unsigned extract_freq(u32 val, struct acpi_cpufreq_data *data)
115{ 128{
116 switch (data->cpu_feature) { 129 switch (data->cpu_feature) {
117 case SYSTEM_INTEL_MSR_CAPABLE: 130 case SYSTEM_INTEL_MSR_CAPABLE:
131 case SYSTEM_AMD_MSR_CAPABLE:
118 return extract_msr(val, data); 132 return extract_msr(val, data);
119 case SYSTEM_IO_CAPABLE: 133 case SYSTEM_IO_CAPABLE:
120 return extract_io(val, data); 134 return extract_io(val, data);
@@ -150,6 +164,7 @@ static void do_drv_read(void *_cmd)
150 164
151 switch (cmd->type) { 165 switch (cmd->type) {
152 case SYSTEM_INTEL_MSR_CAPABLE: 166 case SYSTEM_INTEL_MSR_CAPABLE:
167 case SYSTEM_AMD_MSR_CAPABLE:
153 rdmsr(cmd->addr.msr.reg, cmd->val, h); 168 rdmsr(cmd->addr.msr.reg, cmd->val, h);
154 break; 169 break;
155 case SYSTEM_IO_CAPABLE: 170 case SYSTEM_IO_CAPABLE:
@@ -174,6 +189,9 @@ static void do_drv_write(void *_cmd)
174 lo = (lo & ~INTEL_MSR_RANGE) | (cmd->val & INTEL_MSR_RANGE); 189 lo = (lo & ~INTEL_MSR_RANGE) | (cmd->val & INTEL_MSR_RANGE);
175 wrmsr(cmd->addr.msr.reg, lo, hi); 190 wrmsr(cmd->addr.msr.reg, lo, hi);
176 break; 191 break;
192 case SYSTEM_AMD_MSR_CAPABLE:
193 wrmsr(cmd->addr.msr.reg, cmd->val, 0);
194 break;
177 case SYSTEM_IO_CAPABLE: 195 case SYSTEM_IO_CAPABLE:
178 acpi_os_write_port((acpi_io_address)cmd->addr.io.port, 196 acpi_os_write_port((acpi_io_address)cmd->addr.io.port,
179 cmd->val, 197 cmd->val,
@@ -217,6 +235,10 @@ static u32 get_cur_val(const struct cpumask *mask)
217 cmd.type = SYSTEM_INTEL_MSR_CAPABLE; 235 cmd.type = SYSTEM_INTEL_MSR_CAPABLE;
218 cmd.addr.msr.reg = MSR_IA32_PERF_STATUS; 236 cmd.addr.msr.reg = MSR_IA32_PERF_STATUS;
219 break; 237 break;
238 case SYSTEM_AMD_MSR_CAPABLE:
239 cmd.type = SYSTEM_AMD_MSR_CAPABLE;
240 cmd.addr.msr.reg = MSR_AMD_PERF_STATUS;
241 break;
220 case SYSTEM_IO_CAPABLE: 242 case SYSTEM_IO_CAPABLE:
221 cmd.type = SYSTEM_IO_CAPABLE; 243 cmd.type = SYSTEM_IO_CAPABLE;
222 perf = per_cpu(acfreq_data, cpumask_first(mask))->acpi_data; 244 perf = per_cpu(acfreq_data, cpumask_first(mask))->acpi_data;
@@ -326,6 +348,11 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy,
326 cmd.addr.msr.reg = MSR_IA32_PERF_CTL; 348 cmd.addr.msr.reg = MSR_IA32_PERF_CTL;
327 cmd.val = (u32) perf->states[next_perf_state].control; 349 cmd.val = (u32) perf->states[next_perf_state].control;
328 break; 350 break;
351 case SYSTEM_AMD_MSR_CAPABLE:
352 cmd.type = SYSTEM_AMD_MSR_CAPABLE;
353 cmd.addr.msr.reg = MSR_AMD_PERF_CTL;
354 cmd.val = (u32) perf->states[next_perf_state].control;
355 break;
329 case SYSTEM_IO_CAPABLE: 356 case SYSTEM_IO_CAPABLE:
330 cmd.type = SYSTEM_IO_CAPABLE; 357 cmd.type = SYSTEM_IO_CAPABLE;
331 cmd.addr.io.port = perf->control_register.address; 358 cmd.addr.io.port = perf->control_register.address;
@@ -580,12 +607,16 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
580 break; 607 break;
581 case ACPI_ADR_SPACE_FIXED_HARDWARE: 608 case ACPI_ADR_SPACE_FIXED_HARDWARE:
582 pr_debug("HARDWARE addr space\n"); 609 pr_debug("HARDWARE addr space\n");
583 if (!check_est_cpu(cpu)) { 610 if (check_est_cpu(cpu)) {
584 result = -ENODEV; 611 data->cpu_feature = SYSTEM_INTEL_MSR_CAPABLE;
585 goto err_unreg; 612 break;
586 } 613 }
587 data->cpu_feature = SYSTEM_INTEL_MSR_CAPABLE; 614 if (check_amd_hwpstate_cpu(cpu)) {
588 break; 615 data->cpu_feature = SYSTEM_AMD_MSR_CAPABLE;
616 break;
617 }
618 result = -ENODEV;
619 goto err_unreg;
589 default: 620 default:
590 pr_debug("Unknown addr space %d\n", 621 pr_debug("Unknown addr space %d\n",
591 (u32) (perf->control_register.space_id)); 622 (u32) (perf->control_register.space_id));