blob: b2dc42d8b2f75d04aeb4827c73904a92b69fff8a [file] [log] [blame]
Duy Truonge833aca2013-02-12 13:35:08 -08001/* Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13/*
14 * SOC Info Routines
15 *
16 */
17
18#include <linux/types.h>
19#include <linux/sysdev.h>
20#include <asm/mach-types.h>
21#include <mach/socinfo.h>
22
23#include "smd_private.h"
24
25#define BUILD_ID_LENGTH 32
26
27enum {
28 HW_PLATFORM_UNKNOWN = 0,
29 HW_PLATFORM_SURF = 1,
30 HW_PLATFORM_FFA = 2,
31 HW_PLATFORM_FLUID = 3,
32 HW_PLATFORM_SVLTE_FFA = 4,
33 HW_PLATFORM_SVLTE_SURF = 5,
Jin Hong49753322011-12-15 16:55:37 -080034 HW_PLATFORM_MTP = 8,
Amir Samuelov1b0dc312011-11-17 20:43:33 +020035 HW_PLATFORM_LIQUID = 9,
Zhang Chang Ken59004eb2011-08-08 09:06:58 -040036 /* Dragonboard platform id is assigned as 10 in CDT */
37 HW_PLATFORM_DRAGON = 10,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070038 HW_PLATFORM_INVALID
39};
40
41const char *hw_platform[] = {
42 [HW_PLATFORM_UNKNOWN] = "Unknown",
43 [HW_PLATFORM_SURF] = "Surf",
44 [HW_PLATFORM_FFA] = "FFA",
45 [HW_PLATFORM_FLUID] = "Fluid",
46 [HW_PLATFORM_SVLTE_FFA] = "SVLTE_FFA",
Zhang Chang Kenef05b172011-07-27 15:28:13 -040047 [HW_PLATFORM_SVLTE_SURF] = "SLVTE_SURF",
Jin Hong49753322011-12-15 16:55:37 -080048 [HW_PLATFORM_MTP] = "MTP",
49 [HW_PLATFORM_LIQUID] = "Liquid",
Zhang Chang Kenef05b172011-07-27 15:28:13 -040050 [HW_PLATFORM_DRAGON] = "Dragon"
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070051};
52
53enum {
54 ACCESSORY_CHIP_UNKNOWN = 0,
55 ACCESSORY_CHIP_CHARM = 58,
56};
57
58enum {
59 PLATFORM_SUBTYPE_UNKNOWN = 0x0,
60 PLATFORM_SUBTYPE_CHARM = 0x1,
61 PLATFORM_SUBTYPE_STRANGE = 0x2,
62 PLATFORM_SUBTYPE_STRANGE_2A = 0x3,
63 PLATFORM_SUBTYPE_INVALID,
64};
65
66const char *hw_platform_subtype[] = {
67 [PLATFORM_SUBTYPE_UNKNOWN] = "Unknown",
68 [PLATFORM_SUBTYPE_CHARM] = "charm",
69 [PLATFORM_SUBTYPE_STRANGE] = "strange",
70 [PLATFORM_SUBTYPE_STRANGE_2A] = "strange_2a,"
71};
72
73/* Used to parse shared memory. Must match the modem. */
74struct socinfo_v1 {
75 uint32_t format;
76 uint32_t id;
77 uint32_t version;
78 char build_id[BUILD_ID_LENGTH];
79};
80
81struct socinfo_v2 {
82 struct socinfo_v1 v1;
83
84 /* only valid when format==2 */
85 uint32_t raw_id;
86 uint32_t raw_version;
87};
88
89struct socinfo_v3 {
90 struct socinfo_v2 v2;
91
92 /* only valid when format==3 */
93 uint32_t hw_platform;
94};
95
96struct socinfo_v4 {
97 struct socinfo_v3 v3;
98
99 /* only valid when format==4 */
100 uint32_t platform_version;
101};
102
103struct socinfo_v5 {
104 struct socinfo_v4 v4;
105
106 /* only valid when format==5 */
107 uint32_t accessory_chip;
108};
109
110struct socinfo_v6 {
111 struct socinfo_v5 v5;
112
113 /* only valid when format==6 */
114 uint32_t hw_platform_subtype;
115};
116
Jin Honge795bd22012-08-13 23:06:26 -0700117struct socinfo_v7 {
118 struct socinfo_v6 v6;
119
120 /* only valid when format==7 */
121 uint32_t pmic_model;
122 uint32_t pmic_die_revision;
123};
124
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700125static union {
126 struct socinfo_v1 v1;
127 struct socinfo_v2 v2;
128 struct socinfo_v3 v3;
129 struct socinfo_v4 v4;
130 struct socinfo_v5 v5;
131 struct socinfo_v6 v6;
Jin Honge795bd22012-08-13 23:06:26 -0700132 struct socinfo_v7 v7;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700133} *socinfo;
134
135static enum msm_cpu cpu_of_id[] = {
136
137 /* 7x01 IDs */
138 [1] = MSM_CPU_7X01,
139 [16] = MSM_CPU_7X01,
140 [17] = MSM_CPU_7X01,
141 [18] = MSM_CPU_7X01,
142 [19] = MSM_CPU_7X01,
143 [23] = MSM_CPU_7X01,
144 [25] = MSM_CPU_7X01,
145 [26] = MSM_CPU_7X01,
146 [32] = MSM_CPU_7X01,
147 [33] = MSM_CPU_7X01,
148 [34] = MSM_CPU_7X01,
149 [35] = MSM_CPU_7X01,
150
151 /* 7x25 IDs */
152 [20] = MSM_CPU_7X25,
153 [21] = MSM_CPU_7X25, /* 7225 */
154 [24] = MSM_CPU_7X25, /* 7525 */
155 [27] = MSM_CPU_7X25, /* 7625 */
156 [39] = MSM_CPU_7X25,
157 [40] = MSM_CPU_7X25,
158 [41] = MSM_CPU_7X25,
159 [42] = MSM_CPU_7X25,
160 [62] = MSM_CPU_7X25, /* 7625-1 */
161 [63] = MSM_CPU_7X25, /* 7225-1 */
162 [66] = MSM_CPU_7X25, /* 7225-2 */
163
164
165 /* 7x27 IDs */
166 [43] = MSM_CPU_7X27,
167 [44] = MSM_CPU_7X27,
168 [61] = MSM_CPU_7X27,
169 [67] = MSM_CPU_7X27, /* 7227-1 */
170 [68] = MSM_CPU_7X27, /* 7627-1 */
171 [69] = MSM_CPU_7X27, /* 7627-2 */
172
173
174 /* 8x50 IDs */
175 [30] = MSM_CPU_8X50,
176 [36] = MSM_CPU_8X50,
177 [37] = MSM_CPU_8X50,
178 [38] = MSM_CPU_8X50,
179
180 /* 7x30 IDs */
181 [59] = MSM_CPU_7X30,
182 [60] = MSM_CPU_7X30,
183
184 /* 8x55 IDs */
185 [74] = MSM_CPU_8X55,
186 [75] = MSM_CPU_8X55,
187 [85] = MSM_CPU_8X55,
188
189 /* 8x60 IDs */
190 [70] = MSM_CPU_8X60,
191 [71] = MSM_CPU_8X60,
192 [86] = MSM_CPU_8X60,
193
194 /* 8960 IDs */
195 [87] = MSM_CPU_8960,
196
197 /* 7x25A IDs */
198 [88] = MSM_CPU_7X25A,
199 [89] = MSM_CPU_7X25A,
200 [96] = MSM_CPU_7X25A,
201
202 /* 7x27A IDs */
203 [90] = MSM_CPU_7X27A,
204 [91] = MSM_CPU_7X27A,
205 [92] = MSM_CPU_7X27A,
206 [97] = MSM_CPU_7X27A,
207
208 /* FSM9xxx ID */
209 [94] = FSM_CPU_9XXX,
210 [95] = FSM_CPU_9XXX,
211
212 /* 7x25AA ID */
213 [98] = MSM_CPU_7X25AA,
214 [99] = MSM_CPU_7X25AA,
215 [100] = MSM_CPU_7X25AA,
216
Joel Kingbf2ff512011-07-22 13:43:11 -0700217 /* 7x27AA ID */
218 [101] = MSM_CPU_7X27AA,
219 [102] = MSM_CPU_7X27AA,
220 [103] = MSM_CPU_7X27AA,
Kaushal Kumardc0beb92012-06-29 19:31:05 +0530221 [136] = MSM_CPU_7X27AA,
Joel Kingbf2ff512011-07-22 13:43:11 -0700222
Rohit Vaswani8a28b4a2011-08-10 19:07:00 -0700223 /* 9x15 ID */
224 [104] = MSM_CPU_9615,
Rohit Vaswani865f2ca2011-10-03 17:40:42 -0700225 [105] = MSM_CPU_9615,
Rohit Vaswani7a83fa92012-01-11 15:05:39 -0800226 [106] = MSM_CPU_9615,
227 [107] = MSM_CPU_9615,
Rohit Vaswani8a28b4a2011-08-10 19:07:00 -0700228
Stepan Moskovchenkoa8f0a222011-10-24 18:53:17 -0700229 /* 8064 IDs */
Joel Kingbf2ff512011-07-22 13:43:11 -0700230 [109] = MSM_CPU_8064,
231
Stepan Moskovchenkoa8f0a222011-10-24 18:53:17 -0700232 /* 8930 IDs */
233 [116] = MSM_CPU_8930,
Stepan Moskovchenkodb71cd62011-11-23 14:28:57 -0800234 [117] = MSM_CPU_8930,
235 [118] = MSM_CPU_8930,
236 [119] = MSM_CPU_8930,
David Ng7ea5a252013-02-12 18:49:25 -0800237 [179] = MSM_CPU_8930,
Stepan Moskovchenkodb71cd62011-11-23 14:28:57 -0800238
239 /* 8627 IDs */
240 [120] = MSM_CPU_8627,
241 [121] = MSM_CPU_8627,
Stepan Moskovchenkoa8f0a222011-10-24 18:53:17 -0700242
Jin Hong0698b562011-11-05 13:57:25 -0700243 /* 8660A ID */
244 [122] = MSM_CPU_8960,
245
246 /* 8260A ID */
247 [123] = MSM_CPU_8960,
248
249 /* 8060A ID */
250 [124] = MSM_CPU_8960,
251
Abhimanyu Kapur90ced6e2012-06-26 17:41:25 -0700252 /* 8974 IDs */
253 [126] = MSM_CPU_8974,
Sathish Ambleya99d6852011-10-31 15:50:55 -0700254
Taniya Dasa04e1892011-11-16 14:49:12 +0530255 /* 8625 IDs */
256 [127] = MSM_CPU_8625,
257 [128] = MSM_CPU_8625,
258 [129] = MSM_CPU_8625,
259
Joel King8e0bf672012-05-18 15:40:40 -0700260 /* 8064 MPQ ID */
261 [130] = MSM_CPU_8064,
Rohit Vaswani47ee9e92012-04-23 18:42:03 -0700262
Pankaj Kumarfee56a82012-04-17 14:26:49 +0530263 /* 7x25AB IDs */
264 [131] = MSM_CPU_7X25AB,
265 [132] = MSM_CPU_7X25AB,
266 [133] = MSM_CPU_7X25AB,
Kaushal Kumardc0beb92012-06-29 19:31:05 +0530267 [135] = MSM_CPU_7X25AB,
Pankaj Kumarfee56a82012-04-17 14:26:49 +0530268
Joel King8e0bf672012-05-18 15:40:40 -0700269 /* 9625 IDs */
270 [134] = MSM_CPU_9625,
271
Stepan Moskovchenkoec6a8032012-07-06 15:42:01 -0700272 /* 8960AB IDs */
273 [138] = MSM_CPU_8960AB,
274 [139] = MSM_CPU_8960AB,
275 [140] = MSM_CPU_8960AB,
276 [141] = MSM_CPU_8960AB,
277
Stepan Moskovchenko8f362fe2012-07-12 19:19:52 -0700278 /* 8930AA IDs */
Stepan Moskovchenko8b38bb32012-07-06 16:57:34 -0700279 [142] = MSM_CPU_8930AA,
Stepan Moskovchenko8f362fe2012-07-12 19:19:52 -0700280 [143] = MSM_CPU_8930AA,
281 [144] = MSM_CPU_8930AA,
Stepan Moskovchenko7494f362012-10-22 18:52:06 -0700282 [160] = MSM_CPU_8930AA,
David Ng7ea5a252013-02-12 18:49:25 -0800283 [180] = MSM_CPU_8930AA,
Stepan Moskovchenko8b38bb32012-07-06 16:57:34 -0700284
Syed Rameez Mustafa36a63712012-08-23 15:47:50 -0700285 /* 8226 IDs */
286 [145] = MSM_CPU_8226,
287
288 /* 8092 IDs */
289 [146] = MSM_CPU_8092,
290
Jay Chokshi91b7d3e2012-09-19 18:28:12 -0700291 /* 8064AB IDs */
292 [153] = MSM_CPU_8064AB,
293
Stepan Moskovchenkob2eca962012-10-16 18:34:17 -0700294 /* 8930AB IDs */
295 [154] = MSM_CPU_8930AB,
296 [155] = MSM_CPU_8930AB,
297 [156] = MSM_CPU_8930AB,
Jay Chokshi72870802013-01-15 13:06:27 -0800298 [157] = MSM_CPU_8930AB,
David Ng7ea5a252013-02-12 18:49:25 -0800299 [181] = MSM_CPU_8930AB,
Jay Chokshi72870802013-01-15 13:06:27 -0800300
301 /* 8064AA IDs */
302 [172] = MSM_CPU_8064AA,
Stepan Moskovchenkob2eca962012-10-16 18:34:17 -0700303
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700304 /* Uninitialized IDs are not known to run Linux.
305 MSM_CPU_UNKNOWN is set to 0 to ensure these IDs are
306 considered as unknown CPU. */
307};
308
309static enum msm_cpu cur_cpu;
310
311static struct socinfo_v1 dummy_socinfo = {
312 .format = 1,
313 .version = 1,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700314};
315
316uint32_t socinfo_get_id(void)
317{
318 return (socinfo) ? socinfo->v1.id : 0;
319}
320EXPORT_SYMBOL_GPL(socinfo_get_id);
321
322uint32_t socinfo_get_version(void)
323{
324 return (socinfo) ? socinfo->v1.version : 0;
325}
326
327char *socinfo_get_build_id(void)
328{
329 return (socinfo) ? socinfo->v1.build_id : NULL;
330}
331
332uint32_t socinfo_get_raw_id(void)
333{
334 return socinfo ?
335 (socinfo->v1.format >= 2 ? socinfo->v2.raw_id : 0)
336 : 0;
337}
338
339uint32_t socinfo_get_raw_version(void)
340{
341 return socinfo ?
342 (socinfo->v1.format >= 2 ? socinfo->v2.raw_version : 0)
343 : 0;
344}
345
346uint32_t socinfo_get_platform_type(void)
347{
348 return socinfo ?
349 (socinfo->v1.format >= 3 ? socinfo->v3.hw_platform : 0)
350 : 0;
351}
352
353
354uint32_t socinfo_get_platform_version(void)
355{
356 return socinfo ?
357 (socinfo->v1.format >= 4 ? socinfo->v4.platform_version : 0)
358 : 0;
359}
360
361/* This information is directly encoded by the machine id */
362/* Thus no external callers rely on this information at the moment */
363static uint32_t socinfo_get_accessory_chip(void)
364{
365 return socinfo ?
366 (socinfo->v1.format >= 5 ? socinfo->v5.accessory_chip : 0)
367 : 0;
368}
369
370uint32_t socinfo_get_platform_subtype(void)
371{
372 return socinfo ?
373 (socinfo->v1.format >= 6 ? socinfo->v6.hw_platform_subtype : 0)
374 : 0;
375}
376
Jin Honge795bd22012-08-13 23:06:26 -0700377enum pmic_model socinfo_get_pmic_model(void)
378{
379 return socinfo ?
380 (socinfo->v1.format >= 7 ? socinfo->v7.pmic_model
381 : PMIC_MODEL_UNKNOWN)
382 : PMIC_MODEL_UNKNOWN;
383}
384
385uint32_t socinfo_get_pmic_die_revision(void)
386{
387 return socinfo ?
388 (socinfo->v1.format >= 7 ? socinfo->v7.pmic_die_revision : 0)
389 : 0;
390}
391
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700392enum msm_cpu socinfo_get_msm_cpu(void)
393{
394 return cur_cpu;
395}
396EXPORT_SYMBOL_GPL(socinfo_get_msm_cpu);
397
398static ssize_t
399socinfo_show_id(struct sys_device *dev,
400 struct sysdev_attribute *attr,
401 char *buf)
402{
403 if (!socinfo) {
404 pr_err("%s: No socinfo found!\n", __func__);
405 return 0;
406 }
407
408 return snprintf(buf, PAGE_SIZE, "%u\n", socinfo_get_id());
409}
410
411static ssize_t
412socinfo_show_version(struct sys_device *dev,
413 struct sysdev_attribute *attr,
414 char *buf)
415{
416 uint32_t version;
417
418 if (!socinfo) {
419 pr_err("%s: No socinfo found!\n", __func__);
420 return 0;
421 }
422
423 version = socinfo_get_version();
424 return snprintf(buf, PAGE_SIZE, "%u.%u\n",
425 SOCINFO_VERSION_MAJOR(version),
426 SOCINFO_VERSION_MINOR(version));
427}
428
429static ssize_t
430socinfo_show_build_id(struct sys_device *dev,
431 struct sysdev_attribute *attr,
432 char *buf)
433{
434 if (!socinfo) {
435 pr_err("%s: No socinfo found!\n", __func__);
436 return 0;
437 }
438
439 return snprintf(buf, PAGE_SIZE, "%-.32s\n", socinfo_get_build_id());
440}
441
442static ssize_t
443socinfo_show_raw_id(struct sys_device *dev,
444 struct sysdev_attribute *attr,
445 char *buf)
446{
447 if (!socinfo) {
448 pr_err("%s: No socinfo found!\n", __func__);
449 return 0;
450 }
451 if (socinfo->v1.format < 2) {
452 pr_err("%s: Raw ID not available!\n", __func__);
453 return 0;
454 }
455
456 return snprintf(buf, PAGE_SIZE, "%u\n", socinfo_get_raw_id());
457}
458
459static ssize_t
460socinfo_show_raw_version(struct sys_device *dev,
461 struct sysdev_attribute *attr,
462 char *buf)
463{
464 if (!socinfo) {
465 pr_err("%s: No socinfo found!\n", __func__);
466 return 0;
467 }
468 if (socinfo->v1.format < 2) {
469 pr_err("%s: Raw version not available!\n", __func__);
470 return 0;
471 }
472
473 return snprintf(buf, PAGE_SIZE, "%u\n", socinfo_get_raw_version());
474}
475
476static ssize_t
477socinfo_show_platform_type(struct sys_device *dev,
478 struct sysdev_attribute *attr,
479 char *buf)
480{
481 uint32_t hw_type;
482
483 if (!socinfo) {
484 pr_err("%s: No socinfo found!\n", __func__);
485 return 0;
486 }
487 if (socinfo->v1.format < 3) {
488 pr_err("%s: platform type not available!\n", __func__);
489 return 0;
490 }
491
492 hw_type = socinfo_get_platform_type();
493 if (hw_type >= HW_PLATFORM_INVALID) {
494 pr_err("%s: Invalid hardware platform type found\n",
495 __func__);
496 hw_type = HW_PLATFORM_UNKNOWN;
497 }
498
499 return snprintf(buf, PAGE_SIZE, "%-.32s\n", hw_platform[hw_type]);
500}
501
502static ssize_t
503socinfo_show_platform_version(struct sys_device *dev,
504 struct sysdev_attribute *attr,
505 char *buf)
506{
507
508 if (!socinfo) {
509 pr_err("%s: No socinfo found!\n", __func__);
510 return 0;
511 }
512 if (socinfo->v1.format < 4) {
513 pr_err("%s: platform version not available!\n", __func__);
514 return 0;
515 }
516
517 return snprintf(buf, PAGE_SIZE, "%u\n",
518 socinfo_get_platform_version());
519}
520
521static ssize_t
522socinfo_show_accessory_chip(struct sys_device *dev,
523 struct sysdev_attribute *attr,
524 char *buf)
525{
526 if (!socinfo) {
527 pr_err("%s: No socinfo found!\n", __func__);
528 return 0;
529 }
530 if (socinfo->v1.format < 5) {
531 pr_err("%s: accessory chip not available!\n", __func__);
532 return 0;
533 }
534
535 return snprintf(buf, PAGE_SIZE, "%u\n",
536 socinfo_get_accessory_chip());
537}
538
539static ssize_t
540socinfo_show_platform_subtype(struct sys_device *dev,
541 struct sysdev_attribute *attr,
542 char *buf)
543{
544 uint32_t hw_subtype;
545 if (!socinfo) {
546 pr_err("%s: No socinfo found!\n", __func__);
547 return 0;
548 }
549 if (socinfo->v1.format < 6) {
550 pr_err("%s: platform subtype not available!\n", __func__);
551 return 0;
552 }
553
554 hw_subtype = socinfo_get_platform_subtype();
555 if (hw_subtype >= PLATFORM_SUBTYPE_INVALID) {
556 pr_err("%s: Invalid hardware platform sub type found\n",
557 __func__);
558 hw_subtype = PLATFORM_SUBTYPE_UNKNOWN;
559 }
560 return snprintf(buf, PAGE_SIZE, "%-.32s\n",
561 hw_platform_subtype[hw_subtype]);
562}
563
Jin Honge795bd22012-08-13 23:06:26 -0700564static ssize_t
565socinfo_show_pmic_model(struct sys_device *dev,
566 struct sysdev_attribute *attr,
567 char *buf)
568{
569 if (!socinfo) {
570 pr_err("%s: No socinfo found!\n", __func__);
571 return 0;
572 }
573 if (socinfo->v1.format < 7) {
574 pr_err("%s: pmic_model not available!\n", __func__);
575 return 0;
576 }
577
578 return snprintf(buf, PAGE_SIZE, "%u\n",
579 socinfo_get_pmic_model());
580}
581
582static ssize_t
583socinfo_show_pmic_die_revision(struct sys_device *dev,
584 struct sysdev_attribute *attr,
585 char *buf)
586{
587 if (!socinfo) {
588 pr_err("%s: No socinfo found!\n", __func__);
589 return 0;
590 }
591 if (socinfo->v1.format < 7) {
592 pr_err("%s: pmic_die_revision not available!\n", __func__);
593 return 0;
594 }
595
596 return snprintf(buf, PAGE_SIZE, "%u\n",
597 socinfo_get_pmic_die_revision());
598}
599
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700600static struct sysdev_attribute socinfo_v1_files[] = {
601 _SYSDEV_ATTR(id, 0444, socinfo_show_id, NULL),
602 _SYSDEV_ATTR(version, 0444, socinfo_show_version, NULL),
603 _SYSDEV_ATTR(build_id, 0444, socinfo_show_build_id, NULL),
604};
605
606static struct sysdev_attribute socinfo_v2_files[] = {
607 _SYSDEV_ATTR(raw_id, 0444, socinfo_show_raw_id, NULL),
608 _SYSDEV_ATTR(raw_version, 0444, socinfo_show_raw_version, NULL),
609};
610
611static struct sysdev_attribute socinfo_v3_files[] = {
612 _SYSDEV_ATTR(hw_platform, 0444, socinfo_show_platform_type, NULL),
613};
614
615static struct sysdev_attribute socinfo_v4_files[] = {
616 _SYSDEV_ATTR(platform_version, 0444,
617 socinfo_show_platform_version, NULL),
618};
619
620static struct sysdev_attribute socinfo_v5_files[] = {
621 _SYSDEV_ATTR(accessory_chip, 0444,
622 socinfo_show_accessory_chip, NULL),
623};
624
625static struct sysdev_attribute socinfo_v6_files[] = {
626 _SYSDEV_ATTR(platform_subtype, 0444,
627 socinfo_show_platform_subtype, NULL),
628};
629
Jin Honge795bd22012-08-13 23:06:26 -0700630static struct sysdev_attribute socinfo_v7_files[] = {
631 _SYSDEV_ATTR(pmic_model, 0444,
632 socinfo_show_pmic_model, NULL),
633 _SYSDEV_ATTR(pmic_die_revision, 0444,
634 socinfo_show_pmic_die_revision, NULL),
635};
636
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700637static struct sysdev_class soc_sysdev_class = {
638 .name = "soc",
639};
640
641static struct sys_device soc_sys_device = {
642 .id = 0,
643 .cls = &soc_sysdev_class,
644};
645
646static int __init socinfo_create_files(struct sys_device *dev,
647 struct sysdev_attribute files[],
648 int size)
649{
650 int i;
651 for (i = 0; i < size; i++) {
652 int err = sysdev_create_file(dev, &files[i]);
653 if (err) {
654 pr_err("%s: sysdev_create_file(%s)=%d\n",
655 __func__, files[i].attr.name, err);
656 return err;
657 }
658 }
659 return 0;
660}
661
662static int __init socinfo_init_sysdev(void)
663{
664 int err;
665
666 if (!socinfo) {
667 pr_err("%s: No socinfo found!\n", __func__);
668 return -ENODEV;
669 }
670
671 err = sysdev_class_register(&soc_sysdev_class);
672 if (err) {
673 pr_err("%s: sysdev_class_register fail (%d)\n",
674 __func__, err);
675 return err;
676 }
677 err = sysdev_register(&soc_sys_device);
678 if (err) {
679 pr_err("%s: sysdev_register fail (%d)\n",
680 __func__, err);
681 return err;
682 }
683 socinfo_create_files(&soc_sys_device, socinfo_v1_files,
684 ARRAY_SIZE(socinfo_v1_files));
685 if (socinfo->v1.format < 2)
686 return err;
687 socinfo_create_files(&soc_sys_device, socinfo_v2_files,
688 ARRAY_SIZE(socinfo_v2_files));
689
690 if (socinfo->v1.format < 3)
691 return err;
692
693 socinfo_create_files(&soc_sys_device, socinfo_v3_files,
694 ARRAY_SIZE(socinfo_v3_files));
695
696 if (socinfo->v1.format < 4)
697 return err;
698
699 socinfo_create_files(&soc_sys_device, socinfo_v4_files,
700 ARRAY_SIZE(socinfo_v4_files));
701
702 if (socinfo->v1.format < 5)
703 return err;
704
705 socinfo_create_files(&soc_sys_device, socinfo_v5_files,
706 ARRAY_SIZE(socinfo_v5_files));
707
708 if (socinfo->v1.format < 6)
709 return err;
710
Jin Honge795bd22012-08-13 23:06:26 -0700711 socinfo_create_files(&soc_sys_device, socinfo_v6_files,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700712 ARRAY_SIZE(socinfo_v6_files));
713
Jin Honge795bd22012-08-13 23:06:26 -0700714 if (socinfo->v1.format < 7)
715 return err;
716
717 return socinfo_create_files(&soc_sys_device, socinfo_v7_files,
718 ARRAY_SIZE(socinfo_v7_files));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700719}
720
721arch_initcall(socinfo_init_sysdev);
722
Stephen Boyd69a22e42012-02-22 09:16:07 -0800723static void * __init setup_dummy_socinfo(void)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700724{
Syed Rameez Mustafacf645e82012-07-06 19:00:49 -0700725 if (machine_is_msm8960_cdp())
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700726 dummy_socinfo.id = 87;
Rohit Vaswani8a28b4a2011-08-10 19:07:00 -0700727 else if (machine_is_msm9615_mtp() || machine_is_msm9615_cdp())
728 dummy_socinfo.id = 104;
Abhimanyu Kapur90ced6e2012-06-26 17:41:25 -0700729 else if (early_machine_is_msm8974()) {
Sathish Ambleya99d6852011-10-31 15:50:55 -0700730 dummy_socinfo.id = 126;
Abhimanyu Kapur90ced6e2012-06-26 17:41:25 -0700731 strlcpy(dummy_socinfo.build_id, "msm8974 - ",
Sathish Ambley3e265ce2012-03-08 16:44:04 -0800732 sizeof(dummy_socinfo.build_id));
Rohit Vaswani47ee9e92012-04-23 18:42:03 -0700733 } else if (early_machine_is_msm9625()) {
Joel King8e0bf672012-05-18 15:40:40 -0700734 dummy_socinfo.id = 134;
Rohit Vaswani47ee9e92012-04-23 18:42:03 -0700735 strlcpy(dummy_socinfo.build_id, "msm9625 - ",
736 sizeof(dummy_socinfo.build_id));
Syed Rameez Mustafa36a63712012-08-23 15:47:50 -0700737 } else if (early_machine_is_msm8226()) {
738 dummy_socinfo.id = 145;
739 strlcpy(dummy_socinfo.build_id, "msm8226 - ",
740 sizeof(dummy_socinfo.build_id));
Sathish Ambley3e265ce2012-03-08 16:44:04 -0800741 } else if (machine_is_msm8625_rumi3())
Taniya Dasa04e1892011-11-16 14:49:12 +0530742 dummy_socinfo.id = 127;
Sathish Ambley3e265ce2012-03-08 16:44:04 -0800743 strlcat(dummy_socinfo.build_id, "Dummy socinfo",
744 sizeof(dummy_socinfo.build_id));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700745 return (void *) &dummy_socinfo;
746}
747
748int __init socinfo_init(void)
749{
Jin Honge795bd22012-08-13 23:06:26 -0700750 socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID, sizeof(struct socinfo_v7));
751
752 if (!socinfo)
753 socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
754 sizeof(struct socinfo_v6));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700755
756 if (!socinfo)
757 socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
758 sizeof(struct socinfo_v5));
759
760 if (!socinfo)
761 socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
762 sizeof(struct socinfo_v4));
763
764 if (!socinfo)
765 socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
766 sizeof(struct socinfo_v3));
767
768 if (!socinfo)
769 socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
770 sizeof(struct socinfo_v2));
771
772 if (!socinfo)
773 socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
774 sizeof(struct socinfo_v1));
775
776 if (!socinfo) {
777 pr_warn("%s: Can't find SMEM_HW_SW_BUILD_ID; falling back on "
778 "dummy values.\n", __func__);
779 socinfo = setup_dummy_socinfo();
780 }
781
782 WARN(!socinfo_get_id(), "Unknown SOC ID!\n");
783 WARN(socinfo_get_id() >= ARRAY_SIZE(cpu_of_id),
784 "New IDs added! ID => CPU mapping might need an update.\n");
785
786 if (socinfo->v1.id < ARRAY_SIZE(cpu_of_id))
787 cur_cpu = cpu_of_id[socinfo->v1.id];
788
789 switch (socinfo->v1.format) {
790 case 1:
791 pr_info("%s: v%u, id=%u, ver=%u.%u\n",
792 __func__, socinfo->v1.format, socinfo->v1.id,
793 SOCINFO_VERSION_MAJOR(socinfo->v1.version),
794 SOCINFO_VERSION_MINOR(socinfo->v1.version));
795 break;
796 case 2:
797 pr_info("%s: v%u, id=%u, ver=%u.%u, "
798 "raw_id=%u, raw_ver=%u\n",
799 __func__, socinfo->v1.format, socinfo->v1.id,
800 SOCINFO_VERSION_MAJOR(socinfo->v1.version),
801 SOCINFO_VERSION_MINOR(socinfo->v1.version),
802 socinfo->v2.raw_id, socinfo->v2.raw_version);
803 break;
804 case 3:
805 pr_info("%s: v%u, id=%u, ver=%u.%u, "
806 "raw_id=%u, raw_ver=%u, hw_plat=%u\n",
807 __func__, socinfo->v1.format, socinfo->v1.id,
808 SOCINFO_VERSION_MAJOR(socinfo->v1.version),
809 SOCINFO_VERSION_MINOR(socinfo->v1.version),
810 socinfo->v2.raw_id, socinfo->v2.raw_version,
811 socinfo->v3.hw_platform);
812 break;
813 case 4:
814 pr_info("%s: v%u, id=%u, ver=%u.%u, "
815 "raw_id=%u, raw_ver=%u, hw_plat=%u, hw_plat_ver=%u\n",
816 __func__, socinfo->v1.format, socinfo->v1.id,
817 SOCINFO_VERSION_MAJOR(socinfo->v1.version),
818 SOCINFO_VERSION_MINOR(socinfo->v1.version),
819 socinfo->v2.raw_id, socinfo->v2.raw_version,
820 socinfo->v3.hw_platform, socinfo->v4.platform_version);
821 break;
822 case 5:
823 pr_info("%s: v%u, id=%u, ver=%u.%u, "
824 "raw_id=%u, raw_ver=%u, hw_plat=%u, hw_plat_ver=%u\n"
825 " accessory_chip=%u\n", __func__, socinfo->v1.format,
826 socinfo->v1.id,
827 SOCINFO_VERSION_MAJOR(socinfo->v1.version),
828 SOCINFO_VERSION_MINOR(socinfo->v1.version),
829 socinfo->v2.raw_id, socinfo->v2.raw_version,
830 socinfo->v3.hw_platform, socinfo->v4.platform_version,
831 socinfo->v5.accessory_chip);
832 break;
833 case 6:
834 pr_info("%s: v%u, id=%u, ver=%u.%u, "
835 "raw_id=%u, raw_ver=%u, hw_plat=%u, hw_plat_ver=%u\n"
836 " accessory_chip=%u hw_plat_subtype=%u\n", __func__,
837 socinfo->v1.format,
838 socinfo->v1.id,
839 SOCINFO_VERSION_MAJOR(socinfo->v1.version),
840 SOCINFO_VERSION_MINOR(socinfo->v1.version),
841 socinfo->v2.raw_id, socinfo->v2.raw_version,
842 socinfo->v3.hw_platform, socinfo->v4.platform_version,
843 socinfo->v5.accessory_chip,
844 socinfo->v6.hw_platform_subtype);
845 break;
Jin Honge795bd22012-08-13 23:06:26 -0700846 case 7:
847 pr_info("%s: v%u, id=%u, ver=%u.%u, raw_id=%u, raw_ver=%u, hw_plat=%u, hw_plat_ver=%u\n accessory_chip=%u, hw_plat_subtype=%u, pmic_model=%u, pmic_die_revision=%u\n",
848 __func__,
849 socinfo->v1.format,
850 socinfo->v1.id,
851 SOCINFO_VERSION_MAJOR(socinfo->v1.version),
852 SOCINFO_VERSION_MINOR(socinfo->v1.version),
853 socinfo->v2.raw_id, socinfo->v2.raw_version,
854 socinfo->v3.hw_platform, socinfo->v4.platform_version,
855 socinfo->v5.accessory_chip,
856 socinfo->v6.hw_platform_subtype,
857 socinfo->v7.pmic_model,
858 socinfo->v7.pmic_die_revision);
859 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700860 default:
861 pr_err("%s: Unknown format found\n", __func__);
862 break;
863 }
864
865 return 0;
866}
Stepan Moskovchenkoeff783a2011-08-22 19:01:58 -0700867
868const int get_core_count(void)
869{
870 if (!(read_cpuid_mpidr() & BIT(31)))
871 return 1;
872
Jin Hongc5f5d542012-04-12 16:48:51 -0700873 if (read_cpuid_mpidr() & BIT(30))
Stepan Moskovchenkoeff783a2011-08-22 19:01:58 -0700874 return 1;
875
876 /* 1 + the PART[1:0] field of MIDR */
877 return ((read_cpuid_id() >> 4) & 3) + 1;
878}
879
880const int read_msm_cpu_type(void)
881{
Stepan Moskovchenkoa8f0a222011-10-24 18:53:17 -0700882 if (socinfo_get_msm_cpu() != MSM_CPU_UNKNOWN)
883 return socinfo_get_msm_cpu();
884
Stepan Moskovchenkoeff783a2011-08-22 19:01:58 -0700885 switch (read_cpuid_id()) {
886 case 0x510F02D0:
887 case 0x510F02D2:
888 case 0x510F02D4:
889 return MSM_CPU_8X60;
890
891 case 0x510F04D0:
892 case 0x510F04D1:
893 case 0x510F04D2:
Stepan Moskovchenkoa8f0a222011-10-24 18:53:17 -0700894 case 0x511F04D0:
895 case 0x512F04D0:
Stepan Moskovchenkoeff783a2011-08-22 19:01:58 -0700896 return MSM_CPU_8960;
897
Stepan Moskovchenkoa8f0a222011-10-24 18:53:17 -0700898 case 0x51404D11: /* We can't get here unless we are in bringup */
899 return MSM_CPU_8930;
Stepan Moskovchenkoeff783a2011-08-22 19:01:58 -0700900
901 case 0x510F06F0:
902 return MSM_CPU_8064;
903
Stepan Moskovchenko02c4d0c2012-07-26 14:33:02 -0700904 case 0x511F06F1:
905 case 0x512F06F0:
906 return MSM_CPU_8974;
907
Stepan Moskovchenkoeff783a2011-08-22 19:01:58 -0700908 default:
909 return MSM_CPU_UNKNOWN;
910 };
911}
Stepan Moskovchenko70dc7cf2011-08-22 19:08:42 -0700912
Jin Hong12b8b432012-07-18 10:00:31 -0700913const int cpu_is_krait(void)
914{
915 return ((read_cpuid_id() & 0xFF00FC00) == 0x51000400);
916}
917
Stepan Moskovchenko70dc7cf2011-08-22 19:08:42 -0700918const int cpu_is_krait_v1(void)
919{
920 switch (read_cpuid_id()) {
921 case 0x510F04D0:
922 case 0x510F04D1:
923 case 0x510F04D2:
924 return 1;
925
926 default:
927 return 0;
928 };
929}
Jin Hong12b8b432012-07-18 10:00:31 -0700930
931const int cpu_is_krait_v2(void)
932{
933 switch (read_cpuid_id()) {
934 case 0x511F04D0:
935 case 0x511F04D1:
936 case 0x511F04D2:
937 case 0x511F04D3:
938 case 0x511F04D4:
939
940 case 0x510F06F0:
941 case 0x510F06F1:
942 case 0x510F06F2:
943 return 1;
944
945 default:
946 return 0;
947 };
948}
Joel Kingffb79662012-08-19 12:55:49 -0700949
950const int cpu_is_krait_v3(void)
951{
952 switch (read_cpuid_id()) {
953 case 0x512F04D0:
954 case 0x511F06F0:
955 case 0x511F06F1:
956 case 0x510F05D0:
957 return 1;
958
959 default:
960 return 0;
961 };
962}