blob: 79a8499a591445a27eea29f635a28e8bc0647fd3 [file] [log] [blame]
Taniya Dasc4e26c22013-03-16 14:53:06 +05301/* Copyright (c) 2009-2013, 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,
Taniya Dasc4e26c22013-03-16 14:53:06 +053038 HW_PLATFORM_QRD = 11,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070039 HW_PLATFORM_INVALID
40};
41
42const char *hw_platform[] = {
43 [HW_PLATFORM_UNKNOWN] = "Unknown",
44 [HW_PLATFORM_SURF] = "Surf",
45 [HW_PLATFORM_FFA] = "FFA",
46 [HW_PLATFORM_FLUID] = "Fluid",
47 [HW_PLATFORM_SVLTE_FFA] = "SVLTE_FFA",
Zhang Chang Kenef05b172011-07-27 15:28:13 -040048 [HW_PLATFORM_SVLTE_SURF] = "SLVTE_SURF",
Jin Hong49753322011-12-15 16:55:37 -080049 [HW_PLATFORM_MTP] = "MTP",
50 [HW_PLATFORM_LIQUID] = "Liquid",
Zhang Chang Kenef05b172011-07-27 15:28:13 -040051 [HW_PLATFORM_DRAGON] = "Dragon"
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070052};
53
54enum {
55 ACCESSORY_CHIP_UNKNOWN = 0,
56 ACCESSORY_CHIP_CHARM = 58,
57};
58
59enum {
60 PLATFORM_SUBTYPE_UNKNOWN = 0x0,
61 PLATFORM_SUBTYPE_CHARM = 0x1,
62 PLATFORM_SUBTYPE_STRANGE = 0x2,
63 PLATFORM_SUBTYPE_STRANGE_2A = 0x3,
64 PLATFORM_SUBTYPE_INVALID,
65};
66
67const char *hw_platform_subtype[] = {
68 [PLATFORM_SUBTYPE_UNKNOWN] = "Unknown",
69 [PLATFORM_SUBTYPE_CHARM] = "charm",
70 [PLATFORM_SUBTYPE_STRANGE] = "strange",
71 [PLATFORM_SUBTYPE_STRANGE_2A] = "strange_2a,"
72};
73
74/* Used to parse shared memory. Must match the modem. */
75struct socinfo_v1 {
76 uint32_t format;
77 uint32_t id;
78 uint32_t version;
79 char build_id[BUILD_ID_LENGTH];
80};
81
82struct socinfo_v2 {
83 struct socinfo_v1 v1;
84
85 /* only valid when format==2 */
86 uint32_t raw_id;
87 uint32_t raw_version;
88};
89
90struct socinfo_v3 {
91 struct socinfo_v2 v2;
92
93 /* only valid when format==3 */
94 uint32_t hw_platform;
95};
96
97struct socinfo_v4 {
98 struct socinfo_v3 v3;
99
100 /* only valid when format==4 */
101 uint32_t platform_version;
102};
103
104struct socinfo_v5 {
105 struct socinfo_v4 v4;
106
107 /* only valid when format==5 */
108 uint32_t accessory_chip;
109};
110
111struct socinfo_v6 {
112 struct socinfo_v5 v5;
113
114 /* only valid when format==6 */
115 uint32_t hw_platform_subtype;
116};
117
Jin Honge795bd22012-08-13 23:06:26 -0700118struct socinfo_v7 {
119 struct socinfo_v6 v6;
120
121 /* only valid when format==7 */
122 uint32_t pmic_model;
123 uint32_t pmic_die_revision;
124};
125
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700126static union {
127 struct socinfo_v1 v1;
128 struct socinfo_v2 v2;
129 struct socinfo_v3 v3;
130 struct socinfo_v4 v4;
131 struct socinfo_v5 v5;
132 struct socinfo_v6 v6;
Jin Honge795bd22012-08-13 23:06:26 -0700133 struct socinfo_v7 v7;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700134} *socinfo;
135
136static enum msm_cpu cpu_of_id[] = {
137
138 /* 7x01 IDs */
139 [1] = MSM_CPU_7X01,
140 [16] = MSM_CPU_7X01,
141 [17] = MSM_CPU_7X01,
142 [18] = MSM_CPU_7X01,
143 [19] = MSM_CPU_7X01,
144 [23] = MSM_CPU_7X01,
145 [25] = MSM_CPU_7X01,
146 [26] = MSM_CPU_7X01,
147 [32] = MSM_CPU_7X01,
148 [33] = MSM_CPU_7X01,
149 [34] = MSM_CPU_7X01,
150 [35] = MSM_CPU_7X01,
151
152 /* 7x25 IDs */
153 [20] = MSM_CPU_7X25,
154 [21] = MSM_CPU_7X25, /* 7225 */
155 [24] = MSM_CPU_7X25, /* 7525 */
156 [27] = MSM_CPU_7X25, /* 7625 */
157 [39] = MSM_CPU_7X25,
158 [40] = MSM_CPU_7X25,
159 [41] = MSM_CPU_7X25,
160 [42] = MSM_CPU_7X25,
161 [62] = MSM_CPU_7X25, /* 7625-1 */
162 [63] = MSM_CPU_7X25, /* 7225-1 */
163 [66] = MSM_CPU_7X25, /* 7225-2 */
164
165
166 /* 7x27 IDs */
167 [43] = MSM_CPU_7X27,
168 [44] = MSM_CPU_7X27,
169 [61] = MSM_CPU_7X27,
170 [67] = MSM_CPU_7X27, /* 7227-1 */
171 [68] = MSM_CPU_7X27, /* 7627-1 */
172 [69] = MSM_CPU_7X27, /* 7627-2 */
173
174
175 /* 8x50 IDs */
176 [30] = MSM_CPU_8X50,
177 [36] = MSM_CPU_8X50,
178 [37] = MSM_CPU_8X50,
179 [38] = MSM_CPU_8X50,
180
181 /* 7x30 IDs */
182 [59] = MSM_CPU_7X30,
183 [60] = MSM_CPU_7X30,
184
185 /* 8x55 IDs */
186 [74] = MSM_CPU_8X55,
187 [75] = MSM_CPU_8X55,
188 [85] = MSM_CPU_8X55,
189
190 /* 8x60 IDs */
191 [70] = MSM_CPU_8X60,
192 [71] = MSM_CPU_8X60,
193 [86] = MSM_CPU_8X60,
194
195 /* 8960 IDs */
196 [87] = MSM_CPU_8960,
197
198 /* 7x25A IDs */
199 [88] = MSM_CPU_7X25A,
200 [89] = MSM_CPU_7X25A,
201 [96] = MSM_CPU_7X25A,
202
203 /* 7x27A IDs */
204 [90] = MSM_CPU_7X27A,
205 [91] = MSM_CPU_7X27A,
206 [92] = MSM_CPU_7X27A,
207 [97] = MSM_CPU_7X27A,
208
209 /* FSM9xxx ID */
210 [94] = FSM_CPU_9XXX,
211 [95] = FSM_CPU_9XXX,
212
213 /* 7x25AA ID */
214 [98] = MSM_CPU_7X25AA,
215 [99] = MSM_CPU_7X25AA,
216 [100] = MSM_CPU_7X25AA,
217
Joel Kingbf2ff512011-07-22 13:43:11 -0700218 /* 7x27AA ID */
219 [101] = MSM_CPU_7X27AA,
220 [102] = MSM_CPU_7X27AA,
221 [103] = MSM_CPU_7X27AA,
Kaushal Kumardc0beb92012-06-29 19:31:05 +0530222 [136] = MSM_CPU_7X27AA,
Joel Kingbf2ff512011-07-22 13:43:11 -0700223
Rohit Vaswani8a28b4a2011-08-10 19:07:00 -0700224 /* 9x15 ID */
225 [104] = MSM_CPU_9615,
Rohit Vaswani865f2ca2011-10-03 17:40:42 -0700226 [105] = MSM_CPU_9615,
Rohit Vaswani7a83fa92012-01-11 15:05:39 -0800227 [106] = MSM_CPU_9615,
228 [107] = MSM_CPU_9615,
Rohit Vaswani8a28b4a2011-08-10 19:07:00 -0700229
Stepan Moskovchenkoa8f0a222011-10-24 18:53:17 -0700230 /* 8064 IDs */
Joel Kingbf2ff512011-07-22 13:43:11 -0700231 [109] = MSM_CPU_8064,
232
Stepan Moskovchenkoa8f0a222011-10-24 18:53:17 -0700233 /* 8930 IDs */
234 [116] = MSM_CPU_8930,
Stepan Moskovchenkodb71cd62011-11-23 14:28:57 -0800235 [117] = MSM_CPU_8930,
236 [118] = MSM_CPU_8930,
237 [119] = MSM_CPU_8930,
David Ng7ea5a252013-02-12 18:49:25 -0800238 [179] = MSM_CPU_8930,
Stepan Moskovchenkodb71cd62011-11-23 14:28:57 -0800239
240 /* 8627 IDs */
241 [120] = MSM_CPU_8627,
242 [121] = MSM_CPU_8627,
Stepan Moskovchenkoa8f0a222011-10-24 18:53:17 -0700243
Jin Hong0698b562011-11-05 13:57:25 -0700244 /* 8660A ID */
245 [122] = MSM_CPU_8960,
246
247 /* 8260A ID */
248 [123] = MSM_CPU_8960,
249
250 /* 8060A ID */
251 [124] = MSM_CPU_8960,
252
Abhimanyu Kapur90ced6e2012-06-26 17:41:25 -0700253 /* 8974 IDs */
254 [126] = MSM_CPU_8974,
Sathish Ambleya99d6852011-10-31 15:50:55 -0700255
Taniya Dasa04e1892011-11-16 14:49:12 +0530256 /* 8625 IDs */
257 [127] = MSM_CPU_8625,
258 [128] = MSM_CPU_8625,
259 [129] = MSM_CPU_8625,
260
Joel King8e0bf672012-05-18 15:40:40 -0700261 /* 8064 MPQ ID */
262 [130] = MSM_CPU_8064,
Rohit Vaswani47ee9e92012-04-23 18:42:03 -0700263
Pankaj Kumarfee56a82012-04-17 14:26:49 +0530264 /* 7x25AB IDs */
265 [131] = MSM_CPU_7X25AB,
266 [132] = MSM_CPU_7X25AB,
267 [133] = MSM_CPU_7X25AB,
Kaushal Kumardc0beb92012-06-29 19:31:05 +0530268 [135] = MSM_CPU_7X25AB,
Pankaj Kumarfee56a82012-04-17 14:26:49 +0530269
Joel King8e0bf672012-05-18 15:40:40 -0700270 /* 9625 IDs */
271 [134] = MSM_CPU_9625,
272
Stepan Moskovchenkoec6a8032012-07-06 15:42:01 -0700273 /* 8960AB IDs */
274 [138] = MSM_CPU_8960AB,
275 [139] = MSM_CPU_8960AB,
276 [140] = MSM_CPU_8960AB,
277 [141] = MSM_CPU_8960AB,
278
Stepan Moskovchenko8f362fe2012-07-12 19:19:52 -0700279 /* 8930AA IDs */
Stepan Moskovchenko8b38bb32012-07-06 16:57:34 -0700280 [142] = MSM_CPU_8930AA,
Stepan Moskovchenko8f362fe2012-07-12 19:19:52 -0700281 [143] = MSM_CPU_8930AA,
282 [144] = MSM_CPU_8930AA,
Stepan Moskovchenko7494f362012-10-22 18:52:06 -0700283 [160] = MSM_CPU_8930AA,
David Ng7ea5a252013-02-12 18:49:25 -0800284 [180] = MSM_CPU_8930AA,
Stepan Moskovchenko8b38bb32012-07-06 16:57:34 -0700285
Syed Rameez Mustafa36a63712012-08-23 15:47:50 -0700286 /* 8226 IDs */
287 [145] = MSM_CPU_8226,
288
289 /* 8092 IDs */
290 [146] = MSM_CPU_8092,
291
Jay Chokshi91b7d3e2012-09-19 18:28:12 -0700292 /* 8064AB IDs */
293 [153] = MSM_CPU_8064AB,
294
Stepan Moskovchenkob2eca962012-10-16 18:34:17 -0700295 /* 8930AB IDs */
296 [154] = MSM_CPU_8930AB,
297 [155] = MSM_CPU_8930AB,
298 [156] = MSM_CPU_8930AB,
Jay Chokshi72870802013-01-15 13:06:27 -0800299 [157] = MSM_CPU_8930AB,
David Ng7ea5a252013-02-12 18:49:25 -0800300 [181] = MSM_CPU_8930AB,
Jay Chokshi72870802013-01-15 13:06:27 -0800301
302 /* 8064AA IDs */
303 [172] = MSM_CPU_8064AA,
Stepan Moskovchenkob2eca962012-10-16 18:34:17 -0700304
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700305 /* Uninitialized IDs are not known to run Linux.
306 MSM_CPU_UNKNOWN is set to 0 to ensure these IDs are
307 considered as unknown CPU. */
308};
309
310static enum msm_cpu cur_cpu;
311
312static struct socinfo_v1 dummy_socinfo = {
313 .format = 1,
314 .version = 1,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700315};
316
317uint32_t socinfo_get_id(void)
318{
319 return (socinfo) ? socinfo->v1.id : 0;
320}
321EXPORT_SYMBOL_GPL(socinfo_get_id);
322
323uint32_t socinfo_get_version(void)
324{
325 return (socinfo) ? socinfo->v1.version : 0;
326}
327
328char *socinfo_get_build_id(void)
329{
330 return (socinfo) ? socinfo->v1.build_id : NULL;
331}
332
333uint32_t socinfo_get_raw_id(void)
334{
335 return socinfo ?
336 (socinfo->v1.format >= 2 ? socinfo->v2.raw_id : 0)
337 : 0;
338}
339
340uint32_t socinfo_get_raw_version(void)
341{
342 return socinfo ?
343 (socinfo->v1.format >= 2 ? socinfo->v2.raw_version : 0)
344 : 0;
345}
346
347uint32_t socinfo_get_platform_type(void)
348{
349 return socinfo ?
350 (socinfo->v1.format >= 3 ? socinfo->v3.hw_platform : 0)
351 : 0;
352}
353
354
355uint32_t socinfo_get_platform_version(void)
356{
357 return socinfo ?
358 (socinfo->v1.format >= 4 ? socinfo->v4.platform_version : 0)
359 : 0;
360}
361
362/* This information is directly encoded by the machine id */
363/* Thus no external callers rely on this information at the moment */
364static uint32_t socinfo_get_accessory_chip(void)
365{
366 return socinfo ?
367 (socinfo->v1.format >= 5 ? socinfo->v5.accessory_chip : 0)
368 : 0;
369}
370
371uint32_t socinfo_get_platform_subtype(void)
372{
373 return socinfo ?
374 (socinfo->v1.format >= 6 ? socinfo->v6.hw_platform_subtype : 0)
375 : 0;
376}
377
Jin Honge795bd22012-08-13 23:06:26 -0700378enum pmic_model socinfo_get_pmic_model(void)
379{
380 return socinfo ?
381 (socinfo->v1.format >= 7 ? socinfo->v7.pmic_model
382 : PMIC_MODEL_UNKNOWN)
383 : PMIC_MODEL_UNKNOWN;
384}
385
386uint32_t socinfo_get_pmic_die_revision(void)
387{
388 return socinfo ?
389 (socinfo->v1.format >= 7 ? socinfo->v7.pmic_die_revision : 0)
390 : 0;
391}
392
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700393enum msm_cpu socinfo_get_msm_cpu(void)
394{
395 return cur_cpu;
396}
397EXPORT_SYMBOL_GPL(socinfo_get_msm_cpu);
398
399static ssize_t
400socinfo_show_id(struct sys_device *dev,
401 struct sysdev_attribute *attr,
402 char *buf)
403{
404 if (!socinfo) {
405 pr_err("%s: No socinfo found!\n", __func__);
406 return 0;
407 }
408
409 return snprintf(buf, PAGE_SIZE, "%u\n", socinfo_get_id());
410}
411
412static ssize_t
413socinfo_show_version(struct sys_device *dev,
414 struct sysdev_attribute *attr,
415 char *buf)
416{
417 uint32_t version;
418
419 if (!socinfo) {
420 pr_err("%s: No socinfo found!\n", __func__);
421 return 0;
422 }
423
424 version = socinfo_get_version();
425 return snprintf(buf, PAGE_SIZE, "%u.%u\n",
426 SOCINFO_VERSION_MAJOR(version),
427 SOCINFO_VERSION_MINOR(version));
428}
429
430static ssize_t
431socinfo_show_build_id(struct sys_device *dev,
432 struct sysdev_attribute *attr,
433 char *buf)
434{
435 if (!socinfo) {
436 pr_err("%s: No socinfo found!\n", __func__);
437 return 0;
438 }
439
440 return snprintf(buf, PAGE_SIZE, "%-.32s\n", socinfo_get_build_id());
441}
442
443static ssize_t
444socinfo_show_raw_id(struct sys_device *dev,
445 struct sysdev_attribute *attr,
446 char *buf)
447{
448 if (!socinfo) {
449 pr_err("%s: No socinfo found!\n", __func__);
450 return 0;
451 }
452 if (socinfo->v1.format < 2) {
453 pr_err("%s: Raw ID not available!\n", __func__);
454 return 0;
455 }
456
457 return snprintf(buf, PAGE_SIZE, "%u\n", socinfo_get_raw_id());
458}
459
460static ssize_t
461socinfo_show_raw_version(struct sys_device *dev,
462 struct sysdev_attribute *attr,
463 char *buf)
464{
465 if (!socinfo) {
466 pr_err("%s: No socinfo found!\n", __func__);
467 return 0;
468 }
469 if (socinfo->v1.format < 2) {
470 pr_err("%s: Raw version not available!\n", __func__);
471 return 0;
472 }
473
474 return snprintf(buf, PAGE_SIZE, "%u\n", socinfo_get_raw_version());
475}
476
477static ssize_t
478socinfo_show_platform_type(struct sys_device *dev,
479 struct sysdev_attribute *attr,
480 char *buf)
481{
482 uint32_t hw_type;
483
484 if (!socinfo) {
485 pr_err("%s: No socinfo found!\n", __func__);
486 return 0;
487 }
488 if (socinfo->v1.format < 3) {
489 pr_err("%s: platform type not available!\n", __func__);
490 return 0;
491 }
492
493 hw_type = socinfo_get_platform_type();
494 if (hw_type >= HW_PLATFORM_INVALID) {
495 pr_err("%s: Invalid hardware platform type found\n",
496 __func__);
497 hw_type = HW_PLATFORM_UNKNOWN;
498 }
499
500 return snprintf(buf, PAGE_SIZE, "%-.32s\n", hw_platform[hw_type]);
501}
502
503static ssize_t
504socinfo_show_platform_version(struct sys_device *dev,
505 struct sysdev_attribute *attr,
506 char *buf)
507{
508
509 if (!socinfo) {
510 pr_err("%s: No socinfo found!\n", __func__);
511 return 0;
512 }
513 if (socinfo->v1.format < 4) {
514 pr_err("%s: platform version not available!\n", __func__);
515 return 0;
516 }
517
518 return snprintf(buf, PAGE_SIZE, "%u\n",
519 socinfo_get_platform_version());
520}
521
522static ssize_t
523socinfo_show_accessory_chip(struct sys_device *dev,
524 struct sysdev_attribute *attr,
525 char *buf)
526{
527 if (!socinfo) {
528 pr_err("%s: No socinfo found!\n", __func__);
529 return 0;
530 }
531 if (socinfo->v1.format < 5) {
532 pr_err("%s: accessory chip not available!\n", __func__);
533 return 0;
534 }
535
536 return snprintf(buf, PAGE_SIZE, "%u\n",
537 socinfo_get_accessory_chip());
538}
539
540static ssize_t
541socinfo_show_platform_subtype(struct sys_device *dev,
542 struct sysdev_attribute *attr,
543 char *buf)
544{
545 uint32_t hw_subtype;
546 if (!socinfo) {
547 pr_err("%s: No socinfo found!\n", __func__);
548 return 0;
549 }
550 if (socinfo->v1.format < 6) {
551 pr_err("%s: platform subtype not available!\n", __func__);
552 return 0;
553 }
554
555 hw_subtype = socinfo_get_platform_subtype();
556 if (hw_subtype >= PLATFORM_SUBTYPE_INVALID) {
557 pr_err("%s: Invalid hardware platform sub type found\n",
558 __func__);
559 hw_subtype = PLATFORM_SUBTYPE_UNKNOWN;
560 }
561 return snprintf(buf, PAGE_SIZE, "%-.32s\n",
562 hw_platform_subtype[hw_subtype]);
563}
564
Jin Honge795bd22012-08-13 23:06:26 -0700565static ssize_t
566socinfo_show_pmic_model(struct sys_device *dev,
567 struct sysdev_attribute *attr,
568 char *buf)
569{
570 if (!socinfo) {
571 pr_err("%s: No socinfo found!\n", __func__);
572 return 0;
573 }
574 if (socinfo->v1.format < 7) {
575 pr_err("%s: pmic_model not available!\n", __func__);
576 return 0;
577 }
578
579 return snprintf(buf, PAGE_SIZE, "%u\n",
580 socinfo_get_pmic_model());
581}
582
583static ssize_t
584socinfo_show_pmic_die_revision(struct sys_device *dev,
585 struct sysdev_attribute *attr,
586 char *buf)
587{
588 if (!socinfo) {
589 pr_err("%s: No socinfo found!\n", __func__);
590 return 0;
591 }
592 if (socinfo->v1.format < 7) {
593 pr_err("%s: pmic_die_revision not available!\n", __func__);
594 return 0;
595 }
596
597 return snprintf(buf, PAGE_SIZE, "%u\n",
598 socinfo_get_pmic_die_revision());
599}
600
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700601static struct sysdev_attribute socinfo_v1_files[] = {
602 _SYSDEV_ATTR(id, 0444, socinfo_show_id, NULL),
603 _SYSDEV_ATTR(version, 0444, socinfo_show_version, NULL),
604 _SYSDEV_ATTR(build_id, 0444, socinfo_show_build_id, NULL),
605};
606
607static struct sysdev_attribute socinfo_v2_files[] = {
608 _SYSDEV_ATTR(raw_id, 0444, socinfo_show_raw_id, NULL),
609 _SYSDEV_ATTR(raw_version, 0444, socinfo_show_raw_version, NULL),
610};
611
612static struct sysdev_attribute socinfo_v3_files[] = {
613 _SYSDEV_ATTR(hw_platform, 0444, socinfo_show_platform_type, NULL),
614};
615
616static struct sysdev_attribute socinfo_v4_files[] = {
617 _SYSDEV_ATTR(platform_version, 0444,
618 socinfo_show_platform_version, NULL),
619};
620
621static struct sysdev_attribute socinfo_v5_files[] = {
622 _SYSDEV_ATTR(accessory_chip, 0444,
623 socinfo_show_accessory_chip, NULL),
624};
625
626static struct sysdev_attribute socinfo_v6_files[] = {
627 _SYSDEV_ATTR(platform_subtype, 0444,
628 socinfo_show_platform_subtype, NULL),
629};
630
Jin Honge795bd22012-08-13 23:06:26 -0700631static struct sysdev_attribute socinfo_v7_files[] = {
632 _SYSDEV_ATTR(pmic_model, 0444,
633 socinfo_show_pmic_model, NULL),
634 _SYSDEV_ATTR(pmic_die_revision, 0444,
635 socinfo_show_pmic_die_revision, NULL),
636};
637
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700638static struct sysdev_class soc_sysdev_class = {
639 .name = "soc",
640};
641
642static struct sys_device soc_sys_device = {
643 .id = 0,
644 .cls = &soc_sysdev_class,
645};
646
647static int __init socinfo_create_files(struct sys_device *dev,
648 struct sysdev_attribute files[],
649 int size)
650{
651 int i;
652 for (i = 0; i < size; i++) {
653 int err = sysdev_create_file(dev, &files[i]);
654 if (err) {
655 pr_err("%s: sysdev_create_file(%s)=%d\n",
656 __func__, files[i].attr.name, err);
657 return err;
658 }
659 }
660 return 0;
661}
662
663static int __init socinfo_init_sysdev(void)
664{
665 int err;
666
667 if (!socinfo) {
668 pr_err("%s: No socinfo found!\n", __func__);
669 return -ENODEV;
670 }
671
672 err = sysdev_class_register(&soc_sysdev_class);
673 if (err) {
674 pr_err("%s: sysdev_class_register fail (%d)\n",
675 __func__, err);
676 return err;
677 }
678 err = sysdev_register(&soc_sys_device);
679 if (err) {
680 pr_err("%s: sysdev_register fail (%d)\n",
681 __func__, err);
682 return err;
683 }
684 socinfo_create_files(&soc_sys_device, socinfo_v1_files,
685 ARRAY_SIZE(socinfo_v1_files));
686 if (socinfo->v1.format < 2)
687 return err;
688 socinfo_create_files(&soc_sys_device, socinfo_v2_files,
689 ARRAY_SIZE(socinfo_v2_files));
690
691 if (socinfo->v1.format < 3)
692 return err;
693
694 socinfo_create_files(&soc_sys_device, socinfo_v3_files,
695 ARRAY_SIZE(socinfo_v3_files));
696
697 if (socinfo->v1.format < 4)
698 return err;
699
700 socinfo_create_files(&soc_sys_device, socinfo_v4_files,
701 ARRAY_SIZE(socinfo_v4_files));
702
703 if (socinfo->v1.format < 5)
704 return err;
705
706 socinfo_create_files(&soc_sys_device, socinfo_v5_files,
707 ARRAY_SIZE(socinfo_v5_files));
708
709 if (socinfo->v1.format < 6)
710 return err;
711
Jin Honge795bd22012-08-13 23:06:26 -0700712 socinfo_create_files(&soc_sys_device, socinfo_v6_files,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700713 ARRAY_SIZE(socinfo_v6_files));
714
Jin Honge795bd22012-08-13 23:06:26 -0700715 if (socinfo->v1.format < 7)
716 return err;
717
718 return socinfo_create_files(&soc_sys_device, socinfo_v7_files,
719 ARRAY_SIZE(socinfo_v7_files));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700720}
721
722arch_initcall(socinfo_init_sysdev);
723
Stephen Boyd69a22e42012-02-22 09:16:07 -0800724static void * __init setup_dummy_socinfo(void)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700725{
Syed Rameez Mustafacf645e82012-07-06 19:00:49 -0700726 if (machine_is_msm8960_cdp())
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700727 dummy_socinfo.id = 87;
Rohit Vaswani8a28b4a2011-08-10 19:07:00 -0700728 else if (machine_is_msm9615_mtp() || machine_is_msm9615_cdp())
729 dummy_socinfo.id = 104;
Abhimanyu Kapur90ced6e2012-06-26 17:41:25 -0700730 else if (early_machine_is_msm8974()) {
Sathish Ambleya99d6852011-10-31 15:50:55 -0700731 dummy_socinfo.id = 126;
Abhimanyu Kapur90ced6e2012-06-26 17:41:25 -0700732 strlcpy(dummy_socinfo.build_id, "msm8974 - ",
Sathish Ambley3e265ce2012-03-08 16:44:04 -0800733 sizeof(dummy_socinfo.build_id));
Rohit Vaswani47ee9e92012-04-23 18:42:03 -0700734 } else if (early_machine_is_msm9625()) {
Joel King8e0bf672012-05-18 15:40:40 -0700735 dummy_socinfo.id = 134;
Rohit Vaswani47ee9e92012-04-23 18:42:03 -0700736 strlcpy(dummy_socinfo.build_id, "msm9625 - ",
737 sizeof(dummy_socinfo.build_id));
Syed Rameez Mustafa36a63712012-08-23 15:47:50 -0700738 } else if (early_machine_is_msm8226()) {
739 dummy_socinfo.id = 145;
740 strlcpy(dummy_socinfo.build_id, "msm8226 - ",
741 sizeof(dummy_socinfo.build_id));
Sathish Ambley3e265ce2012-03-08 16:44:04 -0800742 } else if (machine_is_msm8625_rumi3())
Taniya Dasa04e1892011-11-16 14:49:12 +0530743 dummy_socinfo.id = 127;
Sathish Ambley3e265ce2012-03-08 16:44:04 -0800744 strlcat(dummy_socinfo.build_id, "Dummy socinfo",
745 sizeof(dummy_socinfo.build_id));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700746 return (void *) &dummy_socinfo;
747}
748
749int __init socinfo_init(void)
750{
Jin Honge795bd22012-08-13 23:06:26 -0700751 socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID, sizeof(struct socinfo_v7));
752
753 if (!socinfo)
754 socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
755 sizeof(struct socinfo_v6));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700756
757 if (!socinfo)
758 socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
759 sizeof(struct socinfo_v5));
760
761 if (!socinfo)
762 socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
763 sizeof(struct socinfo_v4));
764
765 if (!socinfo)
766 socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
767 sizeof(struct socinfo_v3));
768
769 if (!socinfo)
770 socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
771 sizeof(struct socinfo_v2));
772
773 if (!socinfo)
774 socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
775 sizeof(struct socinfo_v1));
776
777 if (!socinfo) {
778 pr_warn("%s: Can't find SMEM_HW_SW_BUILD_ID; falling back on "
779 "dummy values.\n", __func__);
780 socinfo = setup_dummy_socinfo();
781 }
782
783 WARN(!socinfo_get_id(), "Unknown SOC ID!\n");
784 WARN(socinfo_get_id() >= ARRAY_SIZE(cpu_of_id),
785 "New IDs added! ID => CPU mapping might need an update.\n");
786
787 if (socinfo->v1.id < ARRAY_SIZE(cpu_of_id))
788 cur_cpu = cpu_of_id[socinfo->v1.id];
789
790 switch (socinfo->v1.format) {
791 case 1:
792 pr_info("%s: v%u, id=%u, ver=%u.%u\n",
793 __func__, socinfo->v1.format, socinfo->v1.id,
794 SOCINFO_VERSION_MAJOR(socinfo->v1.version),
795 SOCINFO_VERSION_MINOR(socinfo->v1.version));
796 break;
797 case 2:
798 pr_info("%s: v%u, id=%u, ver=%u.%u, "
799 "raw_id=%u, raw_ver=%u\n",
800 __func__, socinfo->v1.format, socinfo->v1.id,
801 SOCINFO_VERSION_MAJOR(socinfo->v1.version),
802 SOCINFO_VERSION_MINOR(socinfo->v1.version),
803 socinfo->v2.raw_id, socinfo->v2.raw_version);
804 break;
805 case 3:
806 pr_info("%s: v%u, id=%u, ver=%u.%u, "
807 "raw_id=%u, raw_ver=%u, hw_plat=%u\n",
808 __func__, socinfo->v1.format, socinfo->v1.id,
809 SOCINFO_VERSION_MAJOR(socinfo->v1.version),
810 SOCINFO_VERSION_MINOR(socinfo->v1.version),
811 socinfo->v2.raw_id, socinfo->v2.raw_version,
812 socinfo->v3.hw_platform);
813 break;
814 case 4:
815 pr_info("%s: v%u, id=%u, ver=%u.%u, "
816 "raw_id=%u, raw_ver=%u, hw_plat=%u, hw_plat_ver=%u\n",
817 __func__, socinfo->v1.format, socinfo->v1.id,
818 SOCINFO_VERSION_MAJOR(socinfo->v1.version),
819 SOCINFO_VERSION_MINOR(socinfo->v1.version),
820 socinfo->v2.raw_id, socinfo->v2.raw_version,
821 socinfo->v3.hw_platform, socinfo->v4.platform_version);
822 break;
823 case 5:
824 pr_info("%s: v%u, id=%u, ver=%u.%u, "
825 "raw_id=%u, raw_ver=%u, hw_plat=%u, hw_plat_ver=%u\n"
826 " accessory_chip=%u\n", __func__, socinfo->v1.format,
827 socinfo->v1.id,
828 SOCINFO_VERSION_MAJOR(socinfo->v1.version),
829 SOCINFO_VERSION_MINOR(socinfo->v1.version),
830 socinfo->v2.raw_id, socinfo->v2.raw_version,
831 socinfo->v3.hw_platform, socinfo->v4.platform_version,
832 socinfo->v5.accessory_chip);
833 break;
834 case 6:
835 pr_info("%s: v%u, id=%u, ver=%u.%u, "
836 "raw_id=%u, raw_ver=%u, hw_plat=%u, hw_plat_ver=%u\n"
837 " accessory_chip=%u hw_plat_subtype=%u\n", __func__,
838 socinfo->v1.format,
839 socinfo->v1.id,
840 SOCINFO_VERSION_MAJOR(socinfo->v1.version),
841 SOCINFO_VERSION_MINOR(socinfo->v1.version),
842 socinfo->v2.raw_id, socinfo->v2.raw_version,
843 socinfo->v3.hw_platform, socinfo->v4.platform_version,
844 socinfo->v5.accessory_chip,
845 socinfo->v6.hw_platform_subtype);
846 break;
Jin Honge795bd22012-08-13 23:06:26 -0700847 case 7:
848 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",
849 __func__,
850 socinfo->v1.format,
851 socinfo->v1.id,
852 SOCINFO_VERSION_MAJOR(socinfo->v1.version),
853 SOCINFO_VERSION_MINOR(socinfo->v1.version),
854 socinfo->v2.raw_id, socinfo->v2.raw_version,
855 socinfo->v3.hw_platform, socinfo->v4.platform_version,
856 socinfo->v5.accessory_chip,
857 socinfo->v6.hw_platform_subtype,
858 socinfo->v7.pmic_model,
859 socinfo->v7.pmic_die_revision);
860 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700861 default:
862 pr_err("%s: Unknown format found\n", __func__);
863 break;
864 }
865
866 return 0;
867}
Stepan Moskovchenkoeff783a2011-08-22 19:01:58 -0700868
869const int get_core_count(void)
870{
871 if (!(read_cpuid_mpidr() & BIT(31)))
872 return 1;
873
Jin Hongc5f5d542012-04-12 16:48:51 -0700874 if (read_cpuid_mpidr() & BIT(30))
Stepan Moskovchenkoeff783a2011-08-22 19:01:58 -0700875 return 1;
876
877 /* 1 + the PART[1:0] field of MIDR */
878 return ((read_cpuid_id() >> 4) & 3) + 1;
879}
880
881const int read_msm_cpu_type(void)
882{
Stepan Moskovchenkoa8f0a222011-10-24 18:53:17 -0700883 if (socinfo_get_msm_cpu() != MSM_CPU_UNKNOWN)
884 return socinfo_get_msm_cpu();
885
Stepan Moskovchenkoeff783a2011-08-22 19:01:58 -0700886 switch (read_cpuid_id()) {
887 case 0x510F02D0:
888 case 0x510F02D2:
889 case 0x510F02D4:
890 return MSM_CPU_8X60;
891
892 case 0x510F04D0:
893 case 0x510F04D1:
894 case 0x510F04D2:
Stepan Moskovchenkoa8f0a222011-10-24 18:53:17 -0700895 case 0x511F04D0:
896 case 0x512F04D0:
Stepan Moskovchenkoeff783a2011-08-22 19:01:58 -0700897 return MSM_CPU_8960;
898
Stepan Moskovchenkoa8f0a222011-10-24 18:53:17 -0700899 case 0x51404D11: /* We can't get here unless we are in bringup */
900 return MSM_CPU_8930;
Stepan Moskovchenkoeff783a2011-08-22 19:01:58 -0700901
902 case 0x510F06F0:
903 return MSM_CPU_8064;
904
Stepan Moskovchenko02c4d0c2012-07-26 14:33:02 -0700905 case 0x511F06F1:
906 case 0x512F06F0:
907 return MSM_CPU_8974;
908
Stepan Moskovchenkoeff783a2011-08-22 19:01:58 -0700909 default:
910 return MSM_CPU_UNKNOWN;
911 };
912}
Stepan Moskovchenko70dc7cf2011-08-22 19:08:42 -0700913
Jin Hong12b8b432012-07-18 10:00:31 -0700914const int cpu_is_krait(void)
915{
916 return ((read_cpuid_id() & 0xFF00FC00) == 0x51000400);
917}
918
Stepan Moskovchenko70dc7cf2011-08-22 19:08:42 -0700919const int cpu_is_krait_v1(void)
920{
921 switch (read_cpuid_id()) {
922 case 0x510F04D0:
923 case 0x510F04D1:
924 case 0x510F04D2:
925 return 1;
926
927 default:
928 return 0;
929 };
930}
Jin Hong12b8b432012-07-18 10:00:31 -0700931
932const int cpu_is_krait_v2(void)
933{
934 switch (read_cpuid_id()) {
935 case 0x511F04D0:
936 case 0x511F04D1:
937 case 0x511F04D2:
938 case 0x511F04D3:
939 case 0x511F04D4:
940
941 case 0x510F06F0:
942 case 0x510F06F1:
943 case 0x510F06F2:
944 return 1;
945
946 default:
947 return 0;
948 };
949}
Joel Kingffb79662012-08-19 12:55:49 -0700950
951const int cpu_is_krait_v3(void)
952{
953 switch (read_cpuid_id()) {
954 case 0x512F04D0:
955 case 0x511F06F0:
956 case 0x511F06F1:
957 case 0x510F05D0:
958 return 1;
959
960 default:
961 return 0;
962 };
963}