summaryrefslogtreecommitdiffstats
path: root/drivers/cpuidle
diff options
context:
space:
mode:
authorKrishna Sitaraman <ksitaraman@nvidia.com>2016-02-08 20:21:33 -0500
committerKrishna Sitaraman <ksitaraman@nvidia.com>2016-02-24 14:26:05 -0500
commit2e29dd4687e6b0bae2f3e8d428c32c25d5dac7ee (patch)
tree1eba4559749e87f697583228d98e5fef29bb9eff /drivers/cpuidle
parent116e0682ec38a5c2ec53c9750bf6dc4b47250105 (diff)
t18x: cpuidle: Move xover init to platform init
Bug 200166800 Crossover threshold programming was part of early init separated from rest of the cpuidle init. Moving it be part of the platform init with rest of cpuidle initialization. Change-Id: I52873e8f842d5938b38753877b61c526ad778484 Signed-off-by: Krishna Sitaraman <ksitaraman@nvidia.com> Reviewed-on: http://git-master/r/1009750 GVS: Gerrit_Virtual_Submit Reviewed-by: Alexander Van Brunt <avanbrunt@nvidia.com>
Diffstat (limited to 'drivers/cpuidle')
-rw-r--r--drivers/cpuidle/cpuidle-tegra18x.c155
1 files changed, 68 insertions, 87 deletions
diff --git a/drivers/cpuidle/cpuidle-tegra18x.c b/drivers/cpuidle/cpuidle-tegra18x.c
index df82cb141..fe7beb88b 100644
--- a/drivers/cpuidle/cpuidle-tegra18x.c
+++ b/drivers/cpuidle/cpuidle-tegra18x.c
@@ -471,6 +471,72 @@ static void cluster_state_init(void *data)
471 } 471 }
472} 472}
473 473
474struct xover_table {
475 char *name;
476 int index;
477};
478
479static void send_crossover(void *data)
480{
481 struct device_node *child;
482 struct device_node *of_states = (struct device_node *)data;
483 u32 value;
484 int i;
485
486 struct xover_table table1[] = {
487 {"crossover_c1_c6", TEGRA_MCE_XOVER_C1_C6},
488 {"crossover_cc1_cc6", TEGRA_MCE_XOVER_CC1_CC6},
489 {"crossover_cc1_cc7", TEGRA_MCE_XOVER_CC1_CC7},
490 {"crossover_ccp1_ccp3", TEGRA_MCE_XOVER_CCP1_CCP3},
491 {"crossover_ccp3_sc2", TEGRA_MCE_XOVER_CCP3_SC2},
492 {"crossover_ccp3_sc3", TEGRA_MCE_XOVER_CCP3_SC3},
493 {"crossover_ccp3_sc4", TEGRA_MCE_XOVER_CCP3_SC4},
494 {"crossover_ccp3_sc7", TEGRA_MCE_XOVER_CCP3_SC7},
495 };
496
497 for_each_child_of_node(of_states, child)
498 for (i = 0; i < TEGRA_MCE_XOVER_MAX; i++) {
499 if (of_property_read_u32(child,
500 table1[i].name, &value) == 0)
501 tegra_mce_update_crossover_time
502 (table1[i].index, value);
503 }
504}
505
506static int crossover_init(struct cpumask *denver_cpumask,
507 struct cpumask *a57_cpumask)
508{
509 struct device_node *denver_xover;
510 struct device_node *a57_xover;
511
512 if (!check_mce_version()) {
513 pr_err("WARNING: cpuidle: skipping crossover programming."
514 " Incompatible MCE version.\n");
515 return -ENODEV;
516 }
517
518 denver_xover = of_find_node_by_name(NULL,
519 "denver_crossover_thresholds");
520 a57_xover = of_find_node_by_name(NULL, "a57_crossover_thresholds");
521
522 pr_debug("cpuidle: Init Power Crossover thresholds.\n");
523 if (!a57_xover)
524 pr_err("WARNING: cpuidle: %s: DT entry missing for A57"
525 " thresholds\n", __func__);
526 else
527 smp_call_function_any(a57_cpumask, send_crossover,
528 a57_xover, 1);
529
530 if (!denver_xover)
531 pr_err("WARNING: cpuidle: %s: DT entry missing for Denver"
532 " thresholds\n", __func__);
533 else
534 smp_call_function_any(denver_cpumask, send_crossover,
535 denver_xover, 1);
536
537 return 0;
538}
539
474static int tegra18x_cpuidle_probe(struct platform_device *pdev) 540static int tegra18x_cpuidle_probe(struct platform_device *pdev)
475{ 541{
476 int cpu_number; 542 int cpu_number;
@@ -504,6 +570,8 @@ static int tegra18x_cpuidle_probe(struct platform_device *pdev)
504 } 570 }
505 } 571 }
506 572
573 crossover_init(&denver_cpumask, &a57_cpumask);
574
507 a57_cluster_states = 575 a57_cluster_states =
508 of_find_node_by_name(NULL, "a57_cluster_power_states"); 576 of_find_node_by_name(NULL, "a57_cluster_power_states");
509 denver_cluster_states = 577 denver_cluster_states =
@@ -577,90 +645,3 @@ static struct platform_driver tegra18x_cpuidle_driver = {
577}; 645};
578 646
579module_platform_driver(tegra18x_cpuidle_driver); 647module_platform_driver(tegra18x_cpuidle_driver);
580
581struct xover_table {
582 char *name;
583 int index;
584};
585
586static void crossover_init(struct device_node *of_states) {
587
588 struct device_node *child;
589 u32 value;
590 int i;
591
592 struct xover_table table1[] = {
593 {"crossover_c1_c6", TEGRA_MCE_XOVER_C1_C6},
594 {"crossover_cc1_cc6", TEGRA_MCE_XOVER_CC1_CC6},
595 {"crossover_cc1_cc7", TEGRA_MCE_XOVER_CC1_CC7},
596 {"crossover_ccp1_ccp3", TEGRA_MCE_XOVER_CCP1_CCP3},
597 {"crossover_ccp3_sc2", TEGRA_MCE_XOVER_CCP3_SC2},
598 {"crossover_ccp3_sc3", TEGRA_MCE_XOVER_CCP3_SC3},
599 {"crossover_ccp3_sc4", TEGRA_MCE_XOVER_CCP3_SC4},
600 {"crossover_ccp3_sc7", TEGRA_MCE_XOVER_CCP3_SC7},
601 };
602
603 for_each_child_of_node(of_states, child)
604 for (i=0; i< TEGRA_MCE_XOVER_MAX; i++) {
605 if (of_property_read_u32(child,
606 table1[i].name, &value) == 0)
607 tegra_mce_update_crossover_time
608 (table1[i].index, value);
609 }
610}
611
612static int tegra_mce_cpu_notify(struct notifier_block *nb,
613 unsigned long action, void *pcpu)
614{
615 struct device_node *denver_xover;
616 struct device_node *a57_xover;
617 int cpu = (long)pcpu;
618
619 denver_xover = of_find_node_by_name(NULL, "denver_crossover_thresholds");
620 a57_xover = of_find_node_by_name(NULL, "a57_crossover_thresholds");
621
622 switch (action) {
623 case CPU_STARTING:
624 pr_debug("cpuidle: Init Power Crossover thresholds for core %d\n"
625 , cpu);
626 if (read_cpuid_implementor() == ARM_CPU_IMP_ARM) {
627 if (!a57_xover) {
628 pr_err("%s: failed to init xover for core %d\n",
629 __func__, cpu);
630 break;
631 }
632 crossover_init(a57_xover);
633 } else {
634 if (!denver_xover) {
635 pr_err("%s: failed to init xover for core %d\n",
636 __func__, cpu);
637 break;
638 }
639 crossover_init(denver_xover);
640 }
641 break;
642 }
643
644 return NOTIFY_OK;
645}
646
647static struct notifier_block mce_cpu_notifier = {
648 .notifier_call = tegra_mce_cpu_notify,
649};
650
651static int __init tegra_mce_early_init(void)
652{
653
654 if (!check_mce_version()) {
655 pr_err("cpuidle: skipping crossover programming."
656 " Incompatible MCE version.\n");
657 return -ENODEV;
658 }
659
660 /* Initialize thresholds for boot cpu now */
661 tegra_mce_cpu_notify(NULL, CPU_STARTING, (void *)0);
662 /* Initialize thresholds for rest of the cpu when they start */
663 register_cpu_notifier(&mce_cpu_notifier);
664 return 0;
665}
666early_initcall(tegra_mce_early_init);