aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>2014-03-21 13:31:44 -0400
committerMyungJoo Ham <myungjoo.ham@samsung.com>2014-05-24 04:56:40 -0400
commitf4145270894ba3e4edc120d8940f515a2cd75b4c (patch)
treeaa74694e8351d40162cd34a8a8e6c659b1b31097
parentba778b374d55945a190f01f7a741c9657ae5f519 (diff)
PM / devfreq: exynos4: introduce struct busfreq_ppmu_data
This is a preparation for making more PPMU code common for EXYNOS devfreq drivers. There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
-rw-r--r--drivers/devfreq/exynos/exynos4_bus.c74
1 files changed, 46 insertions, 28 deletions
diff --git a/drivers/devfreq/exynos/exynos4_bus.c b/drivers/devfreq/exynos/exynos4_bus.c
index 228c658c0e8c..d99ef9e80517 100644
--- a/drivers/devfreq/exynos/exynos4_bus.c
+++ b/drivers/devfreq/exynos/exynos4_bus.c
@@ -75,6 +75,11 @@ struct busfreq_opp_info {
75 unsigned long volt; 75 unsigned long volt;
76}; 76};
77 77
78struct busfreq_ppmu_data {
79 struct exynos_ppmu *ppmu;
80 int ppmu_end;
81};
82
78struct busfreq_data { 83struct busfreq_data {
79 enum exynos4_busf_type type; 84 enum exynos4_busf_type type;
80 struct device *dev; 85 struct device *dev;
@@ -83,7 +88,7 @@ struct busfreq_data {
83 struct regulator *vdd_int; 88 struct regulator *vdd_int;
84 struct regulator *vdd_mif; /* Exynos4412/4212 only */ 89 struct regulator *vdd_mif; /* Exynos4412/4212 only */
85 struct busfreq_opp_info curr_oppinfo; 90 struct busfreq_opp_info curr_oppinfo;
86 struct exynos_ppmu ppmu[PPMU_END]; 91 struct busfreq_ppmu_data ppmu_data;
87 92
88 struct notifier_block pm_notifier; 93 struct notifier_block pm_notifier;
89 struct mutex lock; 94 struct mutex lock;
@@ -510,47 +515,47 @@ static int exynos4x12_set_busclk(struct busfreq_data *data,
510 return 0; 515 return 0;
511} 516}
512 517
513static void busfreq_mon_reset(struct busfreq_data *data) 518static void busfreq_mon_reset(struct busfreq_ppmu_data *ppmu_data)
514{ 519{
515 unsigned int i; 520 unsigned int i;
516 521
517 for (i = 0; i < PPMU_END; i++) { 522 for (i = 0; i < ppmu_data->ppmu_end; i++) {
518 void __iomem *ppmu_base = data->ppmu[i].hw_base; 523 void __iomem *ppmu_base = ppmu_data->ppmu[i].hw_base;
519 524
520 /* Reset the performance and cycle counters */ 525 /* Reset the performance and cycle counters */
521 exynos_ppmu_reset(ppmu_base); 526 exynos_ppmu_reset(ppmu_base);
522 527
523 /* Setup count registers to monitor read/write transactions */ 528 /* Setup count registers to monitor read/write transactions */
524 data->ppmu[i].event[PPMU_PMNCNT3] = RDWR_DATA_COUNT; 529 ppmu_data->ppmu[i].event[PPMU_PMNCNT3] = RDWR_DATA_COUNT;
525 exynos_ppmu_setevent(ppmu_base, PPMU_PMNCNT3, 530 exynos_ppmu_setevent(ppmu_base, PPMU_PMNCNT3,
526 data->ppmu[i].event[PPMU_PMNCNT3]); 531 ppmu_data->ppmu[i].event[PPMU_PMNCNT3]);
527 532
528 exynos_ppmu_start(ppmu_base); 533 exynos_ppmu_start(ppmu_base);
529 } 534 }
530} 535}
531 536
532static void exynos4_read_ppmu(struct busfreq_data *data) 537static void exynos4_read_ppmu(struct busfreq_ppmu_data *ppmu_data)
533{ 538{
534 int i, j; 539 int i, j;
535 540
536 for (i = 0; i < PPMU_END; i++) { 541 for (i = 0; i < ppmu_data->ppmu_end; i++) {
537 void __iomem *ppmu_base = data->ppmu[i].hw_base; 542 void __iomem *ppmu_base = ppmu_data->ppmu[i].hw_base;
538 543
539 exynos_ppmu_stop(ppmu_base); 544 exynos_ppmu_stop(ppmu_base);
540 545
541 /* Update local data from PPMU */ 546 /* Update local data from PPMU */
542 data->ppmu[i].ccnt = __raw_readl(ppmu_base + PPMU_CCNT); 547 ppmu_data->ppmu[i].ccnt = __raw_readl(ppmu_base + PPMU_CCNT);
543 548
544 for (j = PPMU_PMNCNT0; j < PPMU_PMNCNT_MAX; j++) { 549 for (j = PPMU_PMNCNT0; j < PPMU_PMNCNT_MAX; j++) {
545 if (data->ppmu[i].event[j] == 0) 550 if (ppmu_data->ppmu[i].event[j] == 0)
546 data->ppmu[i].count[j] = 0; 551 ppmu_data->ppmu[i].count[j] = 0;
547 else 552 else
548 data->ppmu[i].count[j] = 553 ppmu_data->ppmu[i].count[j] =
549 exynos_ppmu_read(ppmu_base, j); 554 exynos_ppmu_read(ppmu_base, j);
550 } 555 }
551 } 556 }
552 557
553 busfreq_mon_reset(data); 558 busfreq_mon_reset(ppmu_data);
554} 559}
555 560
556static int exynos4x12_get_intspec(unsigned long mifclk) 561static int exynos4x12_get_intspec(unsigned long mifclk)
@@ -676,16 +681,16 @@ out:
676 return err; 681 return err;
677} 682}
678 683
679static int exynos4_get_busier_ppmu(struct busfreq_data *data) 684static int exynos4_get_busier_ppmu(struct busfreq_ppmu_data *ppmu_data)
680{ 685{
681 int i, j; 686 int i, j;
682 int busy = 0; 687 int busy = 0;
683 unsigned int temp = 0; 688 unsigned int temp = 0;
684 689
685 for (i = 0; i < PPMU_END; i++) { 690 for (i = 0; i < ppmu_data->ppmu_end; i++) {
686 for (j = PPMU_PMNCNT0; j < PPMU_PMNCNT_MAX; j++) { 691 for (j = PPMU_PMNCNT0; j < PPMU_PMNCNT_MAX; j++) {
687 if (data->ppmu[i].count[j] > temp) { 692 if (ppmu_data->ppmu[i].count[j] > temp) {
688 temp = data->ppmu[i].count[j]; 693 temp = ppmu_data->ppmu[i].count[j];
689 busy = i; 694 busy = i;
690 } 695 }
691 } 696 }
@@ -698,20 +703,21 @@ static int exynos4_bus_get_dev_status(struct device *dev,
698 struct devfreq_dev_status *stat) 703 struct devfreq_dev_status *stat)
699{ 704{
700 struct busfreq_data *data = dev_get_drvdata(dev); 705 struct busfreq_data *data = dev_get_drvdata(dev);
706 struct busfreq_ppmu_data *ppmu_data = &data->ppmu_data;
701 int busier; 707 int busier;
702 708
703 exynos4_read_ppmu(data); 709 exynos4_read_ppmu(ppmu_data);
704 busier = exynos4_get_busier_ppmu(data); 710 busier = exynos4_get_busier_ppmu(ppmu_data);
705 stat->current_frequency = data->curr_oppinfo.rate; 711 stat->current_frequency = data->curr_oppinfo.rate;
706 712
707 /* Number of cycles spent on memory access */ 713 /* Number of cycles spent on memory access */
708 stat->busy_time = data->ppmu[busier].count[PPMU_PMNCNT3]; 714 stat->busy_time = ppmu_data->ppmu[busier].count[PPMU_PMNCNT3];
709 stat->busy_time *= 100 / BUS_SATURATION_RATIO; 715 stat->busy_time *= 100 / BUS_SATURATION_RATIO;
710 stat->total_time = data->ppmu[busier].ccnt; 716 stat->total_time = ppmu_data->ppmu[busier].ccnt;
711 717
712 /* If the counters have overflown, retry */ 718 /* If the counters have overflown, retry */
713 if (data->ppmu[busier].ccnt_overflow || 719 if (ppmu_data->ppmu[busier].ccnt_overflow ||
714 data->ppmu[busier].count_overflow[0]) 720 ppmu_data->ppmu[busier].count_overflow[0])
715 return -EAGAIN; 721 return -EAGAIN;
716 722
717 return 0; 723 return 0;
@@ -966,6 +972,7 @@ unlock:
966static int exynos4_busfreq_probe(struct platform_device *pdev) 972static int exynos4_busfreq_probe(struct platform_device *pdev)
967{ 973{
968 struct busfreq_data *data; 974 struct busfreq_data *data;
975 struct busfreq_ppmu_data *ppmu_data;
969 struct dev_pm_opp *opp; 976 struct dev_pm_opp *opp;
970 struct device *dev = &pdev->dev; 977 struct device *dev = &pdev->dev;
971 int err = 0; 978 int err = 0;
@@ -976,9 +983,19 @@ static int exynos4_busfreq_probe(struct platform_device *pdev)
976 return -ENOMEM; 983 return -ENOMEM;
977 } 984 }
978 985
986 ppmu_data = &data->ppmu_data;
987 ppmu_data->ppmu_end = PPMU_END;
988 ppmu_data->ppmu = devm_kzalloc(dev,
989 sizeof(struct exynos_ppmu) * PPMU_END,
990 GFP_KERNEL);
991 if (!ppmu_data->ppmu) {
992 dev_err(dev, "Failed to allocate memory for exynos_ppmu\n");
993 return -ENOMEM;
994 }
995
979 data->type = pdev->id_entry->driver_data; 996 data->type = pdev->id_entry->driver_data;
980 data->ppmu[PPMU_DMC0].hw_base = S5P_VA_DMC0; 997 ppmu_data->ppmu[PPMU_DMC0].hw_base = S5P_VA_DMC0;
981 data->ppmu[PPMU_DMC1].hw_base = S5P_VA_DMC1; 998 ppmu_data->ppmu[PPMU_DMC1].hw_base = S5P_VA_DMC1;
982 data->pm_notifier.notifier_call = exynos4_busfreq_pm_notifier_event; 999 data->pm_notifier.notifier_call = exynos4_busfreq_pm_notifier_event;
983 data->dev = dev; 1000 data->dev = dev;
984 mutex_init(&data->lock); 1001 mutex_init(&data->lock);
@@ -1037,7 +1054,7 @@ static int exynos4_busfreq_probe(struct platform_device *pdev)
1037 * Start PPMU (Performance Profiling Monitoring Unit) to check 1054 * Start PPMU (Performance Profiling Monitoring Unit) to check
1038 * utilization of each IP in the Exynos4 SoC. 1055 * utilization of each IP in the Exynos4 SoC.
1039 */ 1056 */
1040 busfreq_mon_reset(data); 1057 busfreq_mon_reset(ppmu_data);
1041 1058
1042 /* Register opp_notifier for Exynos4 busfreq */ 1059 /* Register opp_notifier for Exynos4 busfreq */
1043 err = devfreq_register_opp_notifier(dev, data->devfreq); 1060 err = devfreq_register_opp_notifier(dev, data->devfreq);
@@ -1081,8 +1098,9 @@ static int exynos4_busfreq_remove(struct platform_device *pdev)
1081static int exynos4_busfreq_resume(struct device *dev) 1098static int exynos4_busfreq_resume(struct device *dev)
1082{ 1099{
1083 struct busfreq_data *data = dev_get_drvdata(dev); 1100 struct busfreq_data *data = dev_get_drvdata(dev);
1101 struct busfreq_ppmu_data *ppmu_data = &data->ppmu_data;
1084 1102
1085 busfreq_mon_reset(data); 1103 busfreq_mon_reset(ppmu_data);
1086 return 0; 1104 return 0;
1087} 1105}
1088#endif 1106#endif