932be26bfcf7f57d7995a289a85aa27c398b52d8
[android-sdk/arm-ds5-gator.git] / driver / gator_iks.c
1 /**
2  * Copyright (C) ARM Limited 2013. All rights reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  */
10 #if GATOR_IKS_SUPPORT
12 #include <linux/of.h>
13 #include <asm/bL_switcher.h>
14 #include <asm/smp_plat.h>
15 #include <trace/events/power_cpu_migrate.h>
17 static int mpidr_cpuids[NR_CPUS];
18 static int __lcpu_to_pcpu[NR_CPUS];
20 static void calc_first_cluster_size(void)
21 {
22         int len;
23         const u32 *val;
24         struct device_node *cn = NULL;
25         int mpidr_cpuids_count = 0;
27         // Zero is a valid cpuid, so initialize the array to 0xff's
28         memset(&mpidr_cpuids, 0xff, sizeof(mpidr_cpuids));
30         while ((cn = of_find_node_by_type(cn, "cpu"))) {
31                 BUG_ON(mpidr_cpuids_count >= NR_CPUS);
33                 val = of_get_property(cn, "reg", &len);
34                 if (!val || len != 4) {
35                         pr_err("%s missing reg property\n", cn->full_name);
36                         continue;
37                 }
39                 mpidr_cpuids[mpidr_cpuids_count] = be32_to_cpup(val);
40                 ++mpidr_cpuids_count;
41         }
43         BUG_ON(mpidr_cpuids_count != nr_cpu_ids);
44 }
46 static int linearize_mpidr(int mpidr)
47 {
48         int i;
49         for (i = 0; i < nr_cpu_ids; ++i) {
50                 if (mpidr_cpuids[i] == mpidr) {
51                         return i;
52                 }
53         }
55         BUG();
56 }
58 int lcpu_to_pcpu(const int lcpu)
59 {
60         int pcpu;
61         BUG_ON(lcpu >= nr_cpu_ids || lcpu < 0);
62         pcpu = __lcpu_to_pcpu[lcpu];
63         BUG_ON(pcpu >= nr_cpu_ids || pcpu < 0);
64         return pcpu;
65 }
67 int pcpu_to_lcpu(const int pcpu)
68 {
69         int lcpu;
70         BUG_ON(pcpu >= nr_cpu_ids || pcpu < 0);
71         for (lcpu = 0; lcpu < nr_cpu_ids; ++lcpu) {
72                 if (__lcpu_to_pcpu[lcpu] == pcpu) {
73                         BUG_ON(lcpu >= nr_cpu_ids || lcpu < 0);
74                         return lcpu;
75                 }
76         }
77         BUG();
78 }
80 static void gator_update_cpu_mapping(u32 cpu_hwid)
81 {
82         int lcpu = smp_processor_id();
83         int pcpu = linearize_mpidr(cpu_hwid & MPIDR_HWID_BITMASK);
84         BUG_ON(lcpu >= nr_cpu_ids || lcpu < 0);
85         BUG_ON(pcpu >= nr_cpu_ids || pcpu < 0);
86         __lcpu_to_pcpu[lcpu] = pcpu;
87 }
89 GATOR_DEFINE_PROBE(cpu_migrate_begin, TP_PROTO(u64 timestamp, u32 cpu_hwid))
90 {
91         const int cpu = get_physical_cpu();
93         gator_timer_offline((void *)1);
94         gator_timer_offline_dispatch(cpu, true);
95 }
97 GATOR_DEFINE_PROBE(cpu_migrate_finish, TP_PROTO(u64 timestamp, u32 cpu_hwid))
98 {
99         int cpu;
101         gator_update_cpu_mapping(cpu_hwid);
103         // get_physical_cpu must be called after gator_update_cpu_mapping
104         cpu = get_physical_cpu();
105         gator_timer_online_dispatch(cpu, true);
106         gator_timer_online((void *)1);
109 GATOR_DEFINE_PROBE(cpu_migrate_current, TP_PROTO(u64 timestamp, u32 cpu_hwid))
111         gator_update_cpu_mapping(cpu_hwid);
114 static int gator_migrate_start(void)
116         int retval = 0;
117         if (retval == 0)
118                 retval = GATOR_REGISTER_TRACE(cpu_migrate_begin);
119         if (retval == 0)
120                 retval = GATOR_REGISTER_TRACE(cpu_migrate_finish);
121         if (retval == 0)
122                 retval = GATOR_REGISTER_TRACE(cpu_migrate_current);
123         if (retval == 0) {
124                 // Initialize the logical to physical cpu mapping
125                 memset(&__lcpu_to_pcpu, 0xff, sizeof(__lcpu_to_pcpu));
126                 bL_switcher_trace_trigger();
127         }
128         return retval;
131 static void gator_migrate_stop(void)
133         GATOR_UNREGISTER_TRACE(cpu_migrate_current);
134         GATOR_UNREGISTER_TRACE(cpu_migrate_finish);
135         GATOR_UNREGISTER_TRACE(cpu_migrate_begin);
138 #else
140 #define calc_first_cluster_size()
141 #define gator_migrate_start() 0
142 #define gator_migrate_stop()
144 #endif