mmc: dw_mmc: fix the max_blk_count in IDMAC
[firefly-linux-kernel-4.4.55.git] / drivers / gator / gator_iks.c
1 /**
2  * Copyright (C) ARM Limited 2013-2015. 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  */
9
10 #if GATOR_IKS_SUPPORT
11
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>
16
17 static bool map_cpuids;
18 static int mpidr_cpuids[NR_CPUS];
19 static const struct gator_cpu *mpidr_cpus[NR_CPUS];
20 static int __lcpu_to_pcpu[NR_CPUS];
21
22 static const struct gator_cpu *gator_find_cpu_by_dt_name(const char *const name)
23 {
24         int i;
25
26         for (i = 0; gator_cpus[i].cpuid != 0; ++i) {
27                 const struct gator_cpu *const gator_cpu = &gator_cpus[i];
28
29                 if (gator_cpu->dt_name != NULL && strcmp(gator_cpu->dt_name, name) == 0)
30                         return gator_cpu;
31         }
32
33         return NULL;
34 }
35
36 static void calc_first_cluster_size(void)
37 {
38         int len;
39         const u32 *val;
40         const char *compatible;
41         struct device_node *cn = NULL;
42         int mpidr_cpuids_count = 0;
43
44         /* Zero is a valid cpuid, so initialize the array to 0xff's */
45         memset(&mpidr_cpuids, 0xff, sizeof(mpidr_cpuids));
46         memset(&mpidr_cpus, 0, sizeof(mpidr_cpus));
47
48         while ((cn = of_find_node_by_type(cn, "cpu"))) {
49                 BUG_ON(mpidr_cpuids_count >= NR_CPUS);
50
51                 val = of_get_property(cn, "reg", &len);
52                 if (!val || len != 4) {
53                         pr_err("%s missing reg property\n", cn->full_name);
54                         continue;
55                 }
56                 compatible = of_get_property(cn, "compatible", NULL);
57                 if (compatible == NULL) {
58                         pr_err("%s missing compatible property\n", cn->full_name);
59                         continue;
60                 }
61
62                 mpidr_cpuids[mpidr_cpuids_count] = be32_to_cpup(val);
63                 mpidr_cpus[mpidr_cpuids_count] = gator_find_cpu_by_dt_name(compatible);
64                 ++mpidr_cpuids_count;
65         }
66
67         map_cpuids = (mpidr_cpuids_count == nr_cpu_ids);
68 }
69
70 static int linearize_mpidr(int mpidr)
71 {
72         int i;
73
74         for (i = 0; i < nr_cpu_ids; ++i) {
75                 if (mpidr_cpuids[i] == mpidr)
76                         return i;
77         }
78
79         BUG();
80 }
81
82 int lcpu_to_pcpu(const int lcpu)
83 {
84         int pcpu;
85
86         if (!map_cpuids)
87                 return lcpu;
88
89         BUG_ON(lcpu >= nr_cpu_ids || lcpu < 0);
90         pcpu = __lcpu_to_pcpu[lcpu];
91         BUG_ON(pcpu >= nr_cpu_ids || pcpu < 0);
92         return pcpu;
93 }
94
95 int pcpu_to_lcpu(const int pcpu)
96 {
97         int lcpu;
98
99         if (!map_cpuids)
100                 return pcpu;
101
102         BUG_ON(pcpu >= nr_cpu_ids || pcpu < 0);
103         for (lcpu = 0; lcpu < nr_cpu_ids; ++lcpu) {
104                 if (__lcpu_to_pcpu[lcpu] == pcpu) {
105                         BUG_ON(lcpu >= nr_cpu_ids || lcpu < 0);
106                         return lcpu;
107                 }
108         }
109         BUG();
110 }
111
112 static void gator_update_cpu_mapping(u32 cpu_hwid)
113 {
114         int lcpu = smp_processor_id();
115         int pcpu = linearize_mpidr(cpu_hwid & MPIDR_HWID_BITMASK);
116
117         BUG_ON(lcpu >= nr_cpu_ids || lcpu < 0);
118         BUG_ON(pcpu >= nr_cpu_ids || pcpu < 0);
119         __lcpu_to_pcpu[lcpu] = pcpu;
120 }
121
122 GATOR_DEFINE_PROBE(cpu_migrate_begin, TP_PROTO(u64 timestamp, u32 cpu_hwid))
123 {
124         const int cpu = get_physical_cpu();
125
126         gator_timer_offline((void *)1);
127         gator_timer_offline_dispatch(cpu, true);
128 }
129
130 GATOR_DEFINE_PROBE(cpu_migrate_finish, TP_PROTO(u64 timestamp, u32 cpu_hwid))
131 {
132         int cpu;
133
134         gator_update_cpu_mapping(cpu_hwid);
135
136         /* get_physical_cpu must be called after gator_update_cpu_mapping */
137         cpu = get_physical_cpu();
138         gator_timer_online_dispatch(cpu, true);
139         gator_timer_online((void *)1);
140 }
141
142 GATOR_DEFINE_PROBE(cpu_migrate_current, TP_PROTO(u64 timestamp, u32 cpu_hwid))
143 {
144         gator_update_cpu_mapping(cpu_hwid);
145 }
146
147 static void gator_send_iks_core_names(void)
148 {
149         int cpu;
150         /* Send the cpu names */
151         preempt_disable();
152         for (cpu = 0; cpu < nr_cpu_ids; ++cpu) {
153                 if (mpidr_cpus[cpu] != NULL)
154                         gator_send_core_name(cpu, mpidr_cpus[cpu]->cpuid);
155         }
156         preempt_enable();
157 }
158
159 static int gator_migrate_start(void)
160 {
161         int retval = 0;
162
163         if (!map_cpuids)
164                 return retval;
165
166         if (retval == 0)
167                 retval = GATOR_REGISTER_TRACE(cpu_migrate_begin);
168         if (retval == 0)
169                 retval = GATOR_REGISTER_TRACE(cpu_migrate_finish);
170         if (retval == 0)
171                 retval = GATOR_REGISTER_TRACE(cpu_migrate_current);
172         if (retval == 0) {
173                 /* Initialize the logical to physical cpu mapping */
174                 memset(&__lcpu_to_pcpu, 0xff, sizeof(__lcpu_to_pcpu));
175                 bL_switcher_trace_trigger();
176         }
177         return retval;
178 }
179
180 static void gator_migrate_stop(void)
181 {
182         if (!map_cpuids)
183                 return;
184
185         GATOR_UNREGISTER_TRACE(cpu_migrate_current);
186         GATOR_UNREGISTER_TRACE(cpu_migrate_finish);
187         GATOR_UNREGISTER_TRACE(cpu_migrate_begin);
188 }
189
190 #else
191
192 #define calc_first_cluster_size()
193 #define gator_send_iks_core_names()
194 #define gator_migrate_start() 0
195 #define gator_migrate_stop()
196
197 #endif