aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/idle/intel_idle.c141
1 files changed, 140 insertions, 1 deletions
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
index 710ab54ab04b..9ddbf550bafa 100644
--- a/drivers/idle/intel_idle.c
+++ b/drivers/idle/intel_idle.c
@@ -283,6 +283,105 @@ static struct cpuidle_state ivb_cstates[] = {
283 .enter = NULL } 283 .enter = NULL }
284}; 284};
285 285
286static struct cpuidle_state ivt_cstates[] = {
287 {
288 .name = "C1-IVT",
289 .desc = "MWAIT 0x00",
290 .flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_TIME_VALID,
291 .exit_latency = 1,
292 .target_residency = 1,
293 .enter = &intel_idle },
294 {
295 .name = "C1E-IVT",
296 .desc = "MWAIT 0x01",
297 .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_TIME_VALID,
298 .exit_latency = 10,
299 .target_residency = 80,
300 .enter = &intel_idle },
301 {
302 .name = "C3-IVT",
303 .desc = "MWAIT 0x10",
304 .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
305 .exit_latency = 59,
306 .target_residency = 156,
307 .enter = &intel_idle },
308 {
309 .name = "C6-IVT",
310 .desc = "MWAIT 0x20",
311 .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
312 .exit_latency = 82,
313 .target_residency = 300,
314 .enter = &intel_idle },
315 {
316 .enter = NULL }
317};
318
319static struct cpuidle_state ivt_cstates_4s[] = {
320 {
321 .name = "C1-IVT-4S",
322 .desc = "MWAIT 0x00",
323 .flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_TIME_VALID,
324 .exit_latency = 1,
325 .target_residency = 1,
326 .enter = &intel_idle },
327 {
328 .name = "C1E-IVT-4S",
329 .desc = "MWAIT 0x01",
330 .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_TIME_VALID,
331 .exit_latency = 10,
332 .target_residency = 250,
333 .enter = &intel_idle },
334 {
335 .name = "C3-IVT-4S",
336 .desc = "MWAIT 0x10",
337 .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
338 .exit_latency = 59,
339 .target_residency = 300,
340 .enter = &intel_idle },
341 {
342 .name = "C6-IVT-4S",
343 .desc = "MWAIT 0x20",
344 .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
345 .exit_latency = 84,
346 .target_residency = 400,
347 .enter = &intel_idle },
348 {
349 .enter = NULL }
350};
351
352static struct cpuidle_state ivt_cstates_8s[] = {
353 {
354 .name = "C1-IVT-8S",
355 .desc = "MWAIT 0x00",
356 .flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_TIME_VALID,
357 .exit_latency = 1,
358 .target_residency = 1,
359 .enter = &intel_idle },
360 {
361 .name = "C1E-IVT-8S",
362 .desc = "MWAIT 0x01",
363 .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_TIME_VALID,
364 .exit_latency = 10,
365 .target_residency = 500,
366 .enter = &intel_idle },
367 {
368 .name = "C3-IVT-8S",
369 .desc = "MWAIT 0x10",
370 .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
371 .exit_latency = 59,
372 .target_residency = 600,
373 .enter = &intel_idle },
374 {
375 .name = "C6-IVT-8S",
376 .desc = "MWAIT 0x20",
377 .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
378 .exit_latency = 88,
379 .target_residency = 700,
380 .enter = &intel_idle },
381 {
382 .enter = NULL }
383};
384
286static struct cpuidle_state hsw_cstates[] = { 385static struct cpuidle_state hsw_cstates[] = {
287 { 386 {
288 .name = "C1-HSW", 387 .name = "C1-HSW",
@@ -521,6 +620,11 @@ static const struct idle_cpu idle_cpu_ivb = {
521 .disable_promotion_to_c1e = true, 620 .disable_promotion_to_c1e = true,
522}; 621};
523 622
623static const struct idle_cpu idle_cpu_ivt = {
624 .state_table = ivt_cstates,
625 .disable_promotion_to_c1e = true,
626};
627
524static const struct idle_cpu idle_cpu_hsw = { 628static const struct idle_cpu idle_cpu_hsw = {
525 .state_table = hsw_cstates, 629 .state_table = hsw_cstates,
526 .disable_promotion_to_c1e = true, 630 .disable_promotion_to_c1e = true,
@@ -549,7 +653,7 @@ static const struct x86_cpu_id intel_idle_ids[] = {
549 ICPU(0x36, idle_cpu_atom), 653 ICPU(0x36, idle_cpu_atom),
550 ICPU(0x37, idle_cpu_byt), 654 ICPU(0x37, idle_cpu_byt),
551 ICPU(0x3a, idle_cpu_ivb), 655 ICPU(0x3a, idle_cpu_ivb),
552 ICPU(0x3e, idle_cpu_ivb), 656 ICPU(0x3e, idle_cpu_ivt),
553 ICPU(0x3c, idle_cpu_hsw), 657 ICPU(0x3c, idle_cpu_hsw),
554 ICPU(0x3f, idle_cpu_hsw), 658 ICPU(0x3f, idle_cpu_hsw),
555 ICPU(0x45, idle_cpu_hsw), 659 ICPU(0x45, idle_cpu_hsw),
@@ -626,6 +730,39 @@ static void intel_idle_cpuidle_devices_uninit(void)
626 free_percpu(intel_idle_cpuidle_devices); 730 free_percpu(intel_idle_cpuidle_devices);
627 return; 731 return;
628} 732}
733
734/*
735 * intel_idle_state_table_update()
736 *
737 * Update the default state_table for this CPU-id
738 *
739 * Currently used to access tuned IVT multi-socket targets
740 * Assumption: num_sockets == (max_package_num + 1)
741 */
742void intel_idle_state_table_update(void)
743{
744 /* IVT uses a different table for 1-2, 3-4, and > 4 sockets */
745 if (boot_cpu_data.x86_model == 0x3e) { /* IVT */
746 int cpu, package_num, num_sockets = 1;
747
748 for_each_online_cpu(cpu) {
749 package_num = topology_physical_package_id(cpu);
750 if (package_num + 1 > num_sockets) {
751 num_sockets = package_num + 1;
752
753 if (num_sockets > 4)
754 cpuidle_state_table = ivt_cstates_8s;
755 return;
756 }
757 }
758
759 if (num_sockets > 2)
760 cpuidle_state_table = ivt_cstates_4s;
761 /* else, 1 and 2 socket systems use default ivt_cstates */
762 }
763 return;
764}
765
629/* 766/*
630 * intel_idle_cpuidle_driver_init() 767 * intel_idle_cpuidle_driver_init()
631 * allocate, initialize cpuidle_states 768 * allocate, initialize cpuidle_states
@@ -635,6 +772,8 @@ static int __init intel_idle_cpuidle_driver_init(void)
635 int cstate; 772 int cstate;
636 struct cpuidle_driver *drv = &intel_idle_driver; 773 struct cpuidle_driver *drv = &intel_idle_driver;
637 774
775 intel_idle_state_table_update();
776
638 drv->state_count = 1; 777 drv->state_count = 1;
639 778
640 for (cstate = 0; cstate < CPUIDLE_STATE_MAX; ++cstate) { 779 for (cstate = 0; cstate < CPUIDLE_STATE_MAX; ++cstate) {