diff options
Diffstat (limited to 'drivers/cpufreq')
-rw-r--r-- | drivers/cpufreq/cpufreq.c | 58 | ||||
-rw-r--r-- | drivers/cpufreq/intel_pstate.c | 61 | ||||
-rw-r--r-- | drivers/cpufreq/powernow-k8.c | 10 |
3 files changed, 74 insertions, 55 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 08ca8c9f41cd..199b52b7c3e1 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -1109,12 +1109,27 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, | |||
1109 | goto err_set_policy_cpu; | 1109 | goto err_set_policy_cpu; |
1110 | } | 1110 | } |
1111 | 1111 | ||
1112 | /* related cpus should atleast have policy->cpus */ | ||
1113 | cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus); | ||
1114 | |||
1115 | /* | ||
1116 | * affected cpus must always be the one, which are online. We aren't | ||
1117 | * managing offline cpus here. | ||
1118 | */ | ||
1119 | cpumask_and(policy->cpus, policy->cpus, cpu_online_mask); | ||
1120 | |||
1121 | if (!frozen) { | ||
1122 | policy->user_policy.min = policy->min; | ||
1123 | policy->user_policy.max = policy->max; | ||
1124 | } | ||
1125 | |||
1126 | down_write(&policy->rwsem); | ||
1112 | write_lock_irqsave(&cpufreq_driver_lock, flags); | 1127 | write_lock_irqsave(&cpufreq_driver_lock, flags); |
1113 | for_each_cpu(j, policy->cpus) | 1128 | for_each_cpu(j, policy->cpus) |
1114 | per_cpu(cpufreq_cpu_data, j) = policy; | 1129 | per_cpu(cpufreq_cpu_data, j) = policy; |
1115 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); | 1130 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); |
1116 | 1131 | ||
1117 | if (cpufreq_driver->get) { | 1132 | if (cpufreq_driver->get && !cpufreq_driver->setpolicy) { |
1118 | policy->cur = cpufreq_driver->get(policy->cpu); | 1133 | policy->cur = cpufreq_driver->get(policy->cpu); |
1119 | if (!policy->cur) { | 1134 | if (!policy->cur) { |
1120 | pr_err("%s: ->get() failed\n", __func__); | 1135 | pr_err("%s: ->get() failed\n", __func__); |
@@ -1162,20 +1177,6 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, | |||
1162 | } | 1177 | } |
1163 | } | 1178 | } |
1164 | 1179 | ||
1165 | /* related cpus should atleast have policy->cpus */ | ||
1166 | cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus); | ||
1167 | |||
1168 | /* | ||
1169 | * affected cpus must always be the one, which are online. We aren't | ||
1170 | * managing offline cpus here. | ||
1171 | */ | ||
1172 | cpumask_and(policy->cpus, policy->cpus, cpu_online_mask); | ||
1173 | |||
1174 | if (!frozen) { | ||
1175 | policy->user_policy.min = policy->min; | ||
1176 | policy->user_policy.max = policy->max; | ||
1177 | } | ||
1178 | |||
1179 | blocking_notifier_call_chain(&cpufreq_policy_notifier_list, | 1180 | blocking_notifier_call_chain(&cpufreq_policy_notifier_list, |
1180 | CPUFREQ_START, policy); | 1181 | CPUFREQ_START, policy); |
1181 | 1182 | ||
@@ -1206,6 +1207,7 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, | |||
1206 | policy->user_policy.policy = policy->policy; | 1207 | policy->user_policy.policy = policy->policy; |
1207 | policy->user_policy.governor = policy->governor; | 1208 | policy->user_policy.governor = policy->governor; |
1208 | } | 1209 | } |
1210 | up_write(&policy->rwsem); | ||
1209 | 1211 | ||
1210 | kobject_uevent(&policy->kobj, KOBJ_ADD); | 1212 | kobject_uevent(&policy->kobj, KOBJ_ADD); |
1211 | up_read(&cpufreq_rwsem); | 1213 | up_read(&cpufreq_rwsem); |
@@ -1323,8 +1325,7 @@ static int __cpufreq_remove_dev_prepare(struct device *dev, | |||
1323 | up_read(&policy->rwsem); | 1325 | up_read(&policy->rwsem); |
1324 | 1326 | ||
1325 | if (cpu != policy->cpu) { | 1327 | if (cpu != policy->cpu) { |
1326 | if (!frozen) | 1328 | sysfs_remove_link(&dev->kobj, "cpufreq"); |
1327 | sysfs_remove_link(&dev->kobj, "cpufreq"); | ||
1328 | } else if (cpus > 1) { | 1329 | } else if (cpus > 1) { |
1329 | new_cpu = cpufreq_nominate_new_policy_cpu(policy, cpu); | 1330 | new_cpu = cpufreq_nominate_new_policy_cpu(policy, cpu); |
1330 | if (new_cpu >= 0) { | 1331 | if (new_cpu >= 0) { |
@@ -1547,23 +1548,16 @@ static unsigned int __cpufreq_get(unsigned int cpu) | |||
1547 | */ | 1548 | */ |
1548 | unsigned int cpufreq_get(unsigned int cpu) | 1549 | unsigned int cpufreq_get(unsigned int cpu) |
1549 | { | 1550 | { |
1550 | struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu); | 1551 | struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); |
1551 | unsigned int ret_freq = 0; | 1552 | unsigned int ret_freq = 0; |
1552 | 1553 | ||
1553 | if (cpufreq_disabled() || !cpufreq_driver) | 1554 | if (policy) { |
1554 | return -ENOENT; | 1555 | down_read(&policy->rwsem); |
1555 | 1556 | ret_freq = __cpufreq_get(cpu); | |
1556 | BUG_ON(!policy); | 1557 | up_read(&policy->rwsem); |
1557 | |||
1558 | if (!down_read_trylock(&cpufreq_rwsem)) | ||
1559 | return 0; | ||
1560 | |||
1561 | down_read(&policy->rwsem); | ||
1562 | |||
1563 | ret_freq = __cpufreq_get(cpu); | ||
1564 | 1558 | ||
1565 | up_read(&policy->rwsem); | 1559 | cpufreq_cpu_put(policy); |
1566 | up_read(&cpufreq_rwsem); | 1560 | } |
1567 | 1561 | ||
1568 | return ret_freq; | 1562 | return ret_freq; |
1569 | } | 1563 | } |
@@ -2149,7 +2143,7 @@ int cpufreq_update_policy(unsigned int cpu) | |||
2149 | * BIOS might change freq behind our back | 2143 | * BIOS might change freq behind our back |
2150 | * -> ask driver for current freq and notify governors about a change | 2144 | * -> ask driver for current freq and notify governors about a change |
2151 | */ | 2145 | */ |
2152 | if (cpufreq_driver->get) { | 2146 | if (cpufreq_driver->get && !cpufreq_driver->setpolicy) { |
2153 | new_policy.cur = cpufreq_driver->get(cpu); | 2147 | new_policy.cur = cpufreq_driver->get(cpu); |
2154 | if (!policy->cur) { | 2148 | if (!policy->cur) { |
2155 | pr_debug("Driver did not initialize current freq"); | 2149 | pr_debug("Driver did not initialize current freq"); |
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 7e257b233602..2cd36b9297f3 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c | |||
@@ -34,12 +34,15 @@ | |||
34 | 34 | ||
35 | #define SAMPLE_COUNT 3 | 35 | #define SAMPLE_COUNT 3 |
36 | 36 | ||
37 | #define BYT_RATIOS 0x66a | 37 | #define BYT_RATIOS 0x66a |
38 | #define BYT_VIDS 0x66b | 38 | #define BYT_VIDS 0x66b |
39 | #define BYT_TURBO_RATIOS 0x66c | ||
39 | 40 | ||
40 | #define FRAC_BITS 8 | 41 | |
42 | #define FRAC_BITS 6 | ||
41 | #define int_tofp(X) ((int64_t)(X) << FRAC_BITS) | 43 | #define int_tofp(X) ((int64_t)(X) << FRAC_BITS) |
42 | #define fp_toint(X) ((X) >> FRAC_BITS) | 44 | #define fp_toint(X) ((X) >> FRAC_BITS) |
45 | #define FP_ROUNDUP(X) ((X) += 1 << FRAC_BITS) | ||
43 | 46 | ||
44 | static inline int32_t mul_fp(int32_t x, int32_t y) | 47 | static inline int32_t mul_fp(int32_t x, int32_t y) |
45 | { | 48 | { |
@@ -51,12 +54,11 @@ static inline int32_t div_fp(int32_t x, int32_t y) | |||
51 | return div_s64((int64_t)x << FRAC_BITS, (int64_t)y); | 54 | return div_s64((int64_t)x << FRAC_BITS, (int64_t)y); |
52 | } | 55 | } |
53 | 56 | ||
54 | static u64 energy_divisor; | ||
55 | |||
56 | struct sample { | 57 | struct sample { |
57 | int32_t core_pct_busy; | 58 | int32_t core_pct_busy; |
58 | u64 aperf; | 59 | u64 aperf; |
59 | u64 mperf; | 60 | u64 mperf; |
61 | unsigned long long tsc; | ||
60 | int freq; | 62 | int freq; |
61 | }; | 63 | }; |
62 | 64 | ||
@@ -96,6 +98,7 @@ struct cpudata { | |||
96 | 98 | ||
97 | u64 prev_aperf; | 99 | u64 prev_aperf; |
98 | u64 prev_mperf; | 100 | u64 prev_mperf; |
101 | unsigned long long prev_tsc; | ||
99 | int sample_ptr; | 102 | int sample_ptr; |
100 | struct sample samples[SAMPLE_COUNT]; | 103 | struct sample samples[SAMPLE_COUNT]; |
101 | }; | 104 | }; |
@@ -357,7 +360,7 @@ static int byt_get_min_pstate(void) | |||
357 | { | 360 | { |
358 | u64 value; | 361 | u64 value; |
359 | rdmsrl(BYT_RATIOS, value); | 362 | rdmsrl(BYT_RATIOS, value); |
360 | return value & 0xFF; | 363 | return (value >> 8) & 0xFF; |
361 | } | 364 | } |
362 | 365 | ||
363 | static int byt_get_max_pstate(void) | 366 | static int byt_get_max_pstate(void) |
@@ -367,6 +370,13 @@ static int byt_get_max_pstate(void) | |||
367 | return (value >> 16) & 0xFF; | 370 | return (value >> 16) & 0xFF; |
368 | } | 371 | } |
369 | 372 | ||
373 | static int byt_get_turbo_pstate(void) | ||
374 | { | ||
375 | u64 value; | ||
376 | rdmsrl(BYT_TURBO_RATIOS, value); | ||
377 | return value & 0x3F; | ||
378 | } | ||
379 | |||
370 | static void byt_set_pstate(struct cpudata *cpudata, int pstate) | 380 | static void byt_set_pstate(struct cpudata *cpudata, int pstate) |
371 | { | 381 | { |
372 | u64 val; | 382 | u64 val; |
@@ -469,7 +479,7 @@ static struct cpu_defaults byt_params = { | |||
469 | .funcs = { | 479 | .funcs = { |
470 | .get_max = byt_get_max_pstate, | 480 | .get_max = byt_get_max_pstate, |
471 | .get_min = byt_get_min_pstate, | 481 | .get_min = byt_get_min_pstate, |
472 | .get_turbo = byt_get_max_pstate, | 482 | .get_turbo = byt_get_turbo_pstate, |
473 | .set = byt_set_pstate, | 483 | .set = byt_set_pstate, |
474 | .get_vid = byt_get_vid, | 484 | .get_vid = byt_get_vid, |
475 | }, | 485 | }, |
@@ -547,31 +557,48 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu) | |||
547 | static inline void intel_pstate_calc_busy(struct cpudata *cpu, | 557 | static inline void intel_pstate_calc_busy(struct cpudata *cpu, |
548 | struct sample *sample) | 558 | struct sample *sample) |
549 | { | 559 | { |
550 | u64 core_pct; | 560 | int32_t core_pct; |
551 | core_pct = div64_u64(int_tofp(sample->aperf * 100), | 561 | int32_t c0_pct; |
552 | sample->mperf); | 562 | |
553 | sample->freq = fp_toint(cpu->pstate.max_pstate * core_pct * 1000); | 563 | core_pct = div_fp(int_tofp((sample->aperf)), |
564 | int_tofp((sample->mperf))); | ||
565 | core_pct = mul_fp(core_pct, int_tofp(100)); | ||
566 | FP_ROUNDUP(core_pct); | ||
567 | |||
568 | c0_pct = div_fp(int_tofp(sample->mperf), int_tofp(sample->tsc)); | ||
554 | 569 | ||
555 | sample->core_pct_busy = core_pct; | 570 | sample->freq = fp_toint( |
571 | mul_fp(int_tofp(cpu->pstate.max_pstate * 1000), core_pct)); | ||
572 | |||
573 | sample->core_pct_busy = mul_fp(core_pct, c0_pct); | ||
556 | } | 574 | } |
557 | 575 | ||
558 | static inline void intel_pstate_sample(struct cpudata *cpu) | 576 | static inline void intel_pstate_sample(struct cpudata *cpu) |
559 | { | 577 | { |
560 | u64 aperf, mperf; | 578 | u64 aperf, mperf; |
579 | unsigned long long tsc; | ||
561 | 580 | ||
562 | rdmsrl(MSR_IA32_APERF, aperf); | 581 | rdmsrl(MSR_IA32_APERF, aperf); |
563 | rdmsrl(MSR_IA32_MPERF, mperf); | 582 | rdmsrl(MSR_IA32_MPERF, mperf); |
583 | tsc = native_read_tsc(); | ||
584 | |||
585 | aperf = aperf >> FRAC_BITS; | ||
586 | mperf = mperf >> FRAC_BITS; | ||
587 | tsc = tsc >> FRAC_BITS; | ||
564 | 588 | ||
565 | cpu->sample_ptr = (cpu->sample_ptr + 1) % SAMPLE_COUNT; | 589 | cpu->sample_ptr = (cpu->sample_ptr + 1) % SAMPLE_COUNT; |
566 | cpu->samples[cpu->sample_ptr].aperf = aperf; | 590 | cpu->samples[cpu->sample_ptr].aperf = aperf; |
567 | cpu->samples[cpu->sample_ptr].mperf = mperf; | 591 | cpu->samples[cpu->sample_ptr].mperf = mperf; |
592 | cpu->samples[cpu->sample_ptr].tsc = tsc; | ||
568 | cpu->samples[cpu->sample_ptr].aperf -= cpu->prev_aperf; | 593 | cpu->samples[cpu->sample_ptr].aperf -= cpu->prev_aperf; |
569 | cpu->samples[cpu->sample_ptr].mperf -= cpu->prev_mperf; | 594 | cpu->samples[cpu->sample_ptr].mperf -= cpu->prev_mperf; |
595 | cpu->samples[cpu->sample_ptr].tsc -= cpu->prev_tsc; | ||
570 | 596 | ||
571 | intel_pstate_calc_busy(cpu, &cpu->samples[cpu->sample_ptr]); | 597 | intel_pstate_calc_busy(cpu, &cpu->samples[cpu->sample_ptr]); |
572 | 598 | ||
573 | cpu->prev_aperf = aperf; | 599 | cpu->prev_aperf = aperf; |
574 | cpu->prev_mperf = mperf; | 600 | cpu->prev_mperf = mperf; |
601 | cpu->prev_tsc = tsc; | ||
575 | } | 602 | } |
576 | 603 | ||
577 | static inline void intel_pstate_set_sample_time(struct cpudata *cpu) | 604 | static inline void intel_pstate_set_sample_time(struct cpudata *cpu) |
@@ -590,7 +617,8 @@ static inline int32_t intel_pstate_get_scaled_busy(struct cpudata *cpu) | |||
590 | core_busy = cpu->samples[cpu->sample_ptr].core_pct_busy; | 617 | core_busy = cpu->samples[cpu->sample_ptr].core_pct_busy; |
591 | max_pstate = int_tofp(cpu->pstate.max_pstate); | 618 | max_pstate = int_tofp(cpu->pstate.max_pstate); |
592 | current_pstate = int_tofp(cpu->pstate.current_pstate); | 619 | current_pstate = int_tofp(cpu->pstate.current_pstate); |
593 | return mul_fp(core_busy, div_fp(max_pstate, current_pstate)); | 620 | core_busy = mul_fp(core_busy, div_fp(max_pstate, current_pstate)); |
621 | return FP_ROUNDUP(core_busy); | ||
594 | } | 622 | } |
595 | 623 | ||
596 | static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu) | 624 | static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu) |
@@ -617,12 +645,10 @@ static void intel_pstate_timer_func(unsigned long __data) | |||
617 | { | 645 | { |
618 | struct cpudata *cpu = (struct cpudata *) __data; | 646 | struct cpudata *cpu = (struct cpudata *) __data; |
619 | struct sample *sample; | 647 | struct sample *sample; |
620 | u64 energy; | ||
621 | 648 | ||
622 | intel_pstate_sample(cpu); | 649 | intel_pstate_sample(cpu); |
623 | 650 | ||
624 | sample = &cpu->samples[cpu->sample_ptr]; | 651 | sample = &cpu->samples[cpu->sample_ptr]; |
625 | rdmsrl(MSR_PKG_ENERGY_STATUS, energy); | ||
626 | 652 | ||
627 | intel_pstate_adjust_busy_pstate(cpu); | 653 | intel_pstate_adjust_busy_pstate(cpu); |
628 | 654 | ||
@@ -631,7 +657,6 @@ static void intel_pstate_timer_func(unsigned long __data) | |||
631 | cpu->pstate.current_pstate, | 657 | cpu->pstate.current_pstate, |
632 | sample->mperf, | 658 | sample->mperf, |
633 | sample->aperf, | 659 | sample->aperf, |
634 | div64_u64(energy, energy_divisor), | ||
635 | sample->freq); | 660 | sample->freq); |
636 | 661 | ||
637 | intel_pstate_set_sample_time(cpu); | 662 | intel_pstate_set_sample_time(cpu); |
@@ -913,7 +938,6 @@ static int __init intel_pstate_init(void) | |||
913 | int cpu, rc = 0; | 938 | int cpu, rc = 0; |
914 | const struct x86_cpu_id *id; | 939 | const struct x86_cpu_id *id; |
915 | struct cpu_defaults *cpu_info; | 940 | struct cpu_defaults *cpu_info; |
916 | u64 units; | ||
917 | 941 | ||
918 | if (no_load) | 942 | if (no_load) |
919 | return -ENODEV; | 943 | return -ENODEV; |
@@ -947,9 +971,6 @@ static int __init intel_pstate_init(void) | |||
947 | if (rc) | 971 | if (rc) |
948 | goto out; | 972 | goto out; |
949 | 973 | ||
950 | rdmsrl(MSR_RAPL_POWER_UNIT, units); | ||
951 | energy_divisor = 1 << ((units >> 8) & 0x1f); /* bits{12:8} */ | ||
952 | |||
953 | intel_pstate_debug_expose_params(); | 974 | intel_pstate_debug_expose_params(); |
954 | intel_pstate_sysfs_expose_params(); | 975 | intel_pstate_sysfs_expose_params(); |
955 | 976 | ||
diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c index e10b646634d7..6684e0342792 100644 --- a/drivers/cpufreq/powernow-k8.c +++ b/drivers/cpufreq/powernow-k8.c | |||
@@ -1076,7 +1076,7 @@ static int powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1076 | { | 1076 | { |
1077 | struct powernow_k8_data *data; | 1077 | struct powernow_k8_data *data; |
1078 | struct init_on_cpu init_on_cpu; | 1078 | struct init_on_cpu init_on_cpu; |
1079 | int rc; | 1079 | int rc, cpu; |
1080 | 1080 | ||
1081 | smp_call_function_single(pol->cpu, check_supported_cpu, &rc, 1); | 1081 | smp_call_function_single(pol->cpu, check_supported_cpu, &rc, 1); |
1082 | if (rc) | 1082 | if (rc) |
@@ -1140,7 +1140,9 @@ static int powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1140 | pr_debug("cpu_init done, current fid 0x%x, vid 0x%x\n", | 1140 | pr_debug("cpu_init done, current fid 0x%x, vid 0x%x\n", |
1141 | data->currfid, data->currvid); | 1141 | data->currfid, data->currvid); |
1142 | 1142 | ||
1143 | per_cpu(powernow_data, pol->cpu) = data; | 1143 | /* Point all the CPUs in this policy to the same data */ |
1144 | for_each_cpu(cpu, pol->cpus) | ||
1145 | per_cpu(powernow_data, cpu) = data; | ||
1144 | 1146 | ||
1145 | return 0; | 1147 | return 0; |
1146 | 1148 | ||
@@ -1155,6 +1157,7 @@ err_out: | |||
1155 | static int powernowk8_cpu_exit(struct cpufreq_policy *pol) | 1157 | static int powernowk8_cpu_exit(struct cpufreq_policy *pol) |
1156 | { | 1158 | { |
1157 | struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu); | 1159 | struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu); |
1160 | int cpu; | ||
1158 | 1161 | ||
1159 | if (!data) | 1162 | if (!data) |
1160 | return -EINVAL; | 1163 | return -EINVAL; |
@@ -1165,7 +1168,8 @@ static int powernowk8_cpu_exit(struct cpufreq_policy *pol) | |||
1165 | 1168 | ||
1166 | kfree(data->powernow_table); | 1169 | kfree(data->powernow_table); |
1167 | kfree(data); | 1170 | kfree(data); |
1168 | per_cpu(powernow_data, pol->cpu) = NULL; | 1171 | for_each_cpu(cpu, pol->cpus) |
1172 | per_cpu(powernow_data, cpu) = NULL; | ||
1169 | 1173 | ||
1170 | return 0; | 1174 | return 0; |
1171 | } | 1175 | } |