blob: 119ede3f007991984e6cd2e461b637c762cd4c92 [file] [log] [blame]
Bhargav Gurappadia9e6ab42016-08-01 23:35:54 -07001/*
Runmin Wang717ee362017-02-23 13:26:48 -08002 * Copyright (c) 2009-2017, The Linux Foundation. All rights reserved.
Bhargav Gurappadia9e6ab42016-08-01 23:35:54 -07003 *
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 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 */
14/*
15 * SOC Info Routines
16 *
17 */
18
19#define pr_fmt(fmt) "%s: " fmt, __func__
20
21#include <linux/export.h>
22#include <linux/module.h>
23#include <linux/err.h>
24#include <linux/of.h>
25#include <linux/platform_device.h>
26#include <linux/sys_soc.h>
27#include <linux/slab.h>
28#include <linux/stat.h>
29#include <linux/string.h>
30#include <linux/types.h>
31
32#include <asm/system_misc.h>
33
34#include <soc/qcom/socinfo.h>
35#include <soc/qcom/smem.h>
36#include <soc/qcom/boot_stats.h>
37
38#define BUILD_ID_LENGTH 32
39#define SMEM_IMAGE_VERSION_BLOCKS_COUNT 32
40#define SMEM_IMAGE_VERSION_SINGLE_BLOCK_SIZE 128
41#define SMEM_IMAGE_VERSION_SIZE 4096
42#define SMEM_IMAGE_VERSION_NAME_SIZE 75
43#define SMEM_IMAGE_VERSION_VARIANT_SIZE 20
44#define SMEM_IMAGE_VERSION_VARIANT_OFFSET 75
45#define SMEM_IMAGE_VERSION_OEM_SIZE 32
46#define SMEM_IMAGE_VERSION_OEM_OFFSET 96
47#define SMEM_IMAGE_VERSION_PARTITION_APPS 10
48
49enum {
50 HW_PLATFORM_UNKNOWN = 0,
51 HW_PLATFORM_SURF = 1,
52 HW_PLATFORM_FFA = 2,
53 HW_PLATFORM_FLUID = 3,
54 HW_PLATFORM_SVLTE_FFA = 4,
55 HW_PLATFORM_SVLTE_SURF = 5,
56 HW_PLATFORM_MTP_MDM = 7,
57 HW_PLATFORM_MTP = 8,
58 HW_PLATFORM_LIQUID = 9,
59 /* Dragonboard platform id is assigned as 10 in CDT */
60 HW_PLATFORM_DRAGON = 10,
61 HW_PLATFORM_QRD = 11,
62 HW_PLATFORM_HRD = 13,
63 HW_PLATFORM_DTV = 14,
64 HW_PLATFORM_RCM = 21,
65 HW_PLATFORM_STP = 23,
66 HW_PLATFORM_SBC = 24,
67 HW_PLATFORM_INVALID
68};
69
70const char *hw_platform[] = {
71 [HW_PLATFORM_UNKNOWN] = "Unknown",
72 [HW_PLATFORM_SURF] = "Surf",
73 [HW_PLATFORM_FFA] = "FFA",
74 [HW_PLATFORM_FLUID] = "Fluid",
75 [HW_PLATFORM_SVLTE_FFA] = "SVLTE_FFA",
76 [HW_PLATFORM_SVLTE_SURF] = "SLVTE_SURF",
77 [HW_PLATFORM_MTP_MDM] = "MDM_MTP_NO_DISPLAY",
78 [HW_PLATFORM_MTP] = "MTP",
79 [HW_PLATFORM_RCM] = "RCM",
80 [HW_PLATFORM_LIQUID] = "Liquid",
81 [HW_PLATFORM_DRAGON] = "Dragon",
82 [HW_PLATFORM_QRD] = "QRD",
83 [HW_PLATFORM_HRD] = "HRD",
84 [HW_PLATFORM_DTV] = "DTV",
85 [HW_PLATFORM_STP] = "STP",
86 [HW_PLATFORM_SBC] = "SBC",
87};
88
89enum {
90 ACCESSORY_CHIP_UNKNOWN = 0,
91 ACCESSORY_CHIP_CHARM = 58,
92};
93
94enum {
95 PLATFORM_SUBTYPE_QRD = 0x0,
96 PLATFORM_SUBTYPE_SKUAA = 0x1,
97 PLATFORM_SUBTYPE_SKUF = 0x2,
98 PLATFORM_SUBTYPE_SKUAB = 0x3,
99 PLATFORM_SUBTYPE_SKUG = 0x5,
100 PLATFORM_SUBTYPE_QRD_INVALID,
101};
102
103const char *qrd_hw_platform_subtype[] = {
104 [PLATFORM_SUBTYPE_QRD] = "QRD",
105 [PLATFORM_SUBTYPE_SKUAA] = "SKUAA",
106 [PLATFORM_SUBTYPE_SKUF] = "SKUF",
107 [PLATFORM_SUBTYPE_SKUAB] = "SKUAB",
108 [PLATFORM_SUBTYPE_SKUG] = "SKUG",
109 [PLATFORM_SUBTYPE_QRD_INVALID] = "INVALID",
110};
111
112enum {
113 PLATFORM_SUBTYPE_UNKNOWN = 0x0,
114 PLATFORM_SUBTYPE_CHARM = 0x1,
115 PLATFORM_SUBTYPE_STRANGE = 0x2,
116 PLATFORM_SUBTYPE_STRANGE_2A = 0x3,
117 PLATFORM_SUBTYPE_INVALID,
118};
119
120const char *hw_platform_subtype[] = {
121 [PLATFORM_SUBTYPE_UNKNOWN] = "Unknown",
122 [PLATFORM_SUBTYPE_CHARM] = "charm",
123 [PLATFORM_SUBTYPE_STRANGE] = "strange",
124 [PLATFORM_SUBTYPE_STRANGE_2A] = "strange_2a",
125 [PLATFORM_SUBTYPE_INVALID] = "Invalid",
126};
127
128/* Used to parse shared memory. Must match the modem. */
129struct socinfo_v0_1 {
130 uint32_t format;
131 uint32_t id;
132 uint32_t version;
133 char build_id[BUILD_ID_LENGTH];
134};
135
136struct socinfo_v0_2 {
137 struct socinfo_v0_1 v0_1;
138 uint32_t raw_id;
139 uint32_t raw_version;
140};
141
142struct socinfo_v0_3 {
143 struct socinfo_v0_2 v0_2;
144 uint32_t hw_platform;
145};
146
147struct socinfo_v0_4 {
148 struct socinfo_v0_3 v0_3;
149 uint32_t platform_version;
150};
151
152struct socinfo_v0_5 {
153 struct socinfo_v0_4 v0_4;
154 uint32_t accessory_chip;
155};
156
157struct socinfo_v0_6 {
158 struct socinfo_v0_5 v0_5;
159 uint32_t hw_platform_subtype;
160};
161
162struct socinfo_v0_7 {
163 struct socinfo_v0_6 v0_6;
164 uint32_t pmic_model;
165 uint32_t pmic_die_revision;
166};
167
168struct socinfo_v0_8 {
169 struct socinfo_v0_7 v0_7;
170 uint32_t pmic_model_1;
171 uint32_t pmic_die_revision_1;
172 uint32_t pmic_model_2;
173 uint32_t pmic_die_revision_2;
174};
175
176struct socinfo_v0_9 {
177 struct socinfo_v0_8 v0_8;
178 uint32_t foundry_id;
179};
180
181struct socinfo_v0_10 {
182 struct socinfo_v0_9 v0_9;
183 uint32_t serial_number;
184};
185
186struct socinfo_v0_11 {
187 struct socinfo_v0_10 v0_10;
188 uint32_t num_pmics;
189 uint32_t pmic_array_offset;
190};
191
192struct socinfo_v0_12 {
193 struct socinfo_v0_11 v0_11;
194 uint32_t chip_family;
195 uint32_t raw_device_family;
196 uint32_t raw_device_number;
197};
198
Runmin Wang717ee362017-02-23 13:26:48 -0800199struct socinfo_v0_13 {
200 struct socinfo_v0_12 v0_12;
201 uint32_t nproduct_id;
202};
203
Bhargav Gurappadia9e6ab42016-08-01 23:35:54 -0700204static union {
205 struct socinfo_v0_1 v0_1;
206 struct socinfo_v0_2 v0_2;
207 struct socinfo_v0_3 v0_3;
208 struct socinfo_v0_4 v0_4;
209 struct socinfo_v0_5 v0_5;
210 struct socinfo_v0_6 v0_6;
211 struct socinfo_v0_7 v0_7;
212 struct socinfo_v0_8 v0_8;
213 struct socinfo_v0_9 v0_9;
214 struct socinfo_v0_10 v0_10;
215 struct socinfo_v0_11 v0_11;
216 struct socinfo_v0_12 v0_12;
Runmin Wang717ee362017-02-23 13:26:48 -0800217 struct socinfo_v0_13 v0_13;
Bhargav Gurappadia9e6ab42016-08-01 23:35:54 -0700218} *socinfo;
219
220/* max socinfo format version supported */
Runmin Wang717ee362017-02-23 13:26:48 -0800221#define MAX_SOCINFO_FORMAT SOCINFO_VERSION(0, 13)
Bhargav Gurappadia9e6ab42016-08-01 23:35:54 -0700222
223static struct msm_soc_info cpu_of_id[] = {
224
225 /* 7x01 IDs */
226 [0] = {MSM_CPU_UNKNOWN, "Unknown CPU"},
227 [1] = {MSM_CPU_7X01, "MSM7X01"},
228 [16] = {MSM_CPU_7X01, "MSM7X01"},
229 [17] = {MSM_CPU_7X01, "MSM7X01"},
230 [18] = {MSM_CPU_7X01, "MSM7X01"},
231 [19] = {MSM_CPU_7X01, "MSM7X01"},
232 [23] = {MSM_CPU_7X01, "MSM7X01"},
233 [25] = {MSM_CPU_7X01, "MSM7X01"},
234 [26] = {MSM_CPU_7X01, "MSM7X01"},
235 [32] = {MSM_CPU_7X01, "MSM7X01"},
236 [33] = {MSM_CPU_7X01, "MSM7X01"},
237 [34] = {MSM_CPU_7X01, "MSM7X01"},
238 [35] = {MSM_CPU_7X01, "MSM7X01"},
239
240 /* 7x25 IDs */
241 [20] = {MSM_CPU_7X25, "MSM7X25"},
242 [21] = {MSM_CPU_7X25, "MSM7X25"},
243 [24] = {MSM_CPU_7X25, "MSM7X25"},
244 [27] = {MSM_CPU_7X25, "MSM7X25"},
245 [39] = {MSM_CPU_7X25, "MSM7X25"},
246 [40] = {MSM_CPU_7X25, "MSM7X25"},
247 [41] = {MSM_CPU_7X25, "MSM7X25"},
248 [42] = {MSM_CPU_7X25, "MSM7X25"},
249 [62] = {MSM_CPU_7X25, "MSM7X25"},
250 [63] = {MSM_CPU_7X25, "MSM7X25"},
251 [66] = {MSM_CPU_7X25, "MSM7X25"},
252
253
254 /* 7x27 IDs */
255 [43] = {MSM_CPU_7X27, "MSM7X27"},
256 [44] = {MSM_CPU_7X27, "MSM7X27"},
257 [61] = {MSM_CPU_7X27, "MSM7X27"},
258 [67] = {MSM_CPU_7X27, "MSM7X27"},
259 [68] = {MSM_CPU_7X27, "MSM7X27"},
260 [69] = {MSM_CPU_7X27, "MSM7X27"},
261
262
263 /* 8x50 IDs */
264 [30] = {MSM_CPU_8X50, "MSM8X50"},
265 [36] = {MSM_CPU_8X50, "MSM8X50"},
266 [37] = {MSM_CPU_8X50, "MSM8X50"},
267 [38] = {MSM_CPU_8X50, "MSM8X50"},
268
269 /* 7x30 IDs */
270 [59] = {MSM_CPU_7X30, "MSM7X30"},
271 [60] = {MSM_CPU_7X30, "MSM7X30"},
272
273 /* 8x55 IDs */
274 [74] = {MSM_CPU_8X55, "MSM8X55"},
275 [75] = {MSM_CPU_8X55, "MSM8X55"},
276 [85] = {MSM_CPU_8X55, "MSM8X55"},
277
278 /* 8x60 IDs */
279 [70] = {MSM_CPU_8X60, "MSM8X60"},
280 [71] = {MSM_CPU_8X60, "MSM8X60"},
281 [86] = {MSM_CPU_8X60, "MSM8X60"},
282
283 /* 8960 IDs */
284 [87] = {MSM_CPU_8960, "MSM8960"},
285
286 /* 7x25A IDs */
287 [88] = {MSM_CPU_7X25A, "MSM7X25A"},
288 [89] = {MSM_CPU_7X25A, "MSM7X25A"},
289 [96] = {MSM_CPU_7X25A, "MSM7X25A"},
290
291 /* 7x27A IDs */
292 [90] = {MSM_CPU_7X27A, "MSM7X27A"},
293 [91] = {MSM_CPU_7X27A, "MSM7X27A"},
294 [92] = {MSM_CPU_7X27A, "MSM7X27A"},
295 [97] = {MSM_CPU_7X27A, "MSM7X27A"},
296
297 /* FSM9xxx ID */
298 [94] = {FSM_CPU_9XXX, "FSM9XXX"},
299 [95] = {FSM_CPU_9XXX, "FSM9XXX"},
300
301 /* 7x25AA ID */
302 [98] = {MSM_CPU_7X25AA, "MSM7X25AA"},
303 [99] = {MSM_CPU_7X25AA, "MSM7X25AA"},
304 [100] = {MSM_CPU_7X25AA, "MSM7X25AA"},
305
306 /* 7x27AA ID */
307 [101] = {MSM_CPU_7X27AA, "MSM7X27AA"},
308 [102] = {MSM_CPU_7X27AA, "MSM7X27AA"},
309 [103] = {MSM_CPU_7X27AA, "MSM7X27AA"},
310 [136] = {MSM_CPU_7X27AA, "MSM7X27AA"},
311
312 /* 9x15 ID */
313 [104] = {MSM_CPU_9615, "MSM9615"},
314 [105] = {MSM_CPU_9615, "MSM9615"},
315 [106] = {MSM_CPU_9615, "MSM9615"},
316 [107] = {MSM_CPU_9615, "MSM9615"},
317 [171] = {MSM_CPU_9615, "MSM9615"},
318
319 /* 8064 IDs */
320 [109] = {MSM_CPU_8064, "APQ8064"},
321
322 /* 8930 IDs */
323 [116] = {MSM_CPU_8930, "MSM8930"},
324 [117] = {MSM_CPU_8930, "MSM8930"},
325 [118] = {MSM_CPU_8930, "MSM8930"},
326 [119] = {MSM_CPU_8930, "MSM8930"},
327 [179] = {MSM_CPU_8930, "MSM8930"},
328
329 /* 8627 IDs */
330 [120] = {MSM_CPU_8627, "MSM8627"},
331 [121] = {MSM_CPU_8627, "MSM8627"},
332
333 /* 8660A ID */
334 [122] = {MSM_CPU_8960, "MSM8960"},
335
336 /* 8260A ID */
337 [123] = {MSM_CPU_8960, "MSM8960"},
338
339 /* 8060A ID */
340 [124] = {MSM_CPU_8960, "MSM8960"},
341
342 /* 8974 IDs */
343 [126] = {MSM_CPU_8974, "MSM8974"},
344 [184] = {MSM_CPU_8974, "MSM8974"},
345 [185] = {MSM_CPU_8974, "MSM8974"},
346 [186] = {MSM_CPU_8974, "MSM8974"},
347
348 /* 8974AA IDs */
349 [208] = {MSM_CPU_8974PRO_AA, "MSM8974PRO-AA"},
350 [211] = {MSM_CPU_8974PRO_AA, "MSM8974PRO-AA"},
351 [214] = {MSM_CPU_8974PRO_AA, "MSM8974PRO-AA"},
352 [217] = {MSM_CPU_8974PRO_AA, "MSM8974PRO-AA"},
353
354 /* 8974AB IDs */
355 [209] = {MSM_CPU_8974PRO_AB, "MSM8974PRO-AB"},
356 [212] = {MSM_CPU_8974PRO_AB, "MSM8974PRO-AB"},
357 [215] = {MSM_CPU_8974PRO_AB, "MSM8974PRO-AB"},
358 [218] = {MSM_CPU_8974PRO_AB, "MSM8974PRO-AB"},
359
360 /* 8974AC IDs */
361 [194] = {MSM_CPU_8974PRO_AC, "MSM8974PRO-AC"},
362 [210] = {MSM_CPU_8974PRO_AC, "MSM8974PRO-AC"},
363 [213] = {MSM_CPU_8974PRO_AC, "MSM8974PRO-AC"},
364 [216] = {MSM_CPU_8974PRO_AC, "MSM8974PRO-AC"},
365
366 /* 8625 IDs */
367 [127] = {MSM_CPU_8625, "MSM8625"},
368 [128] = {MSM_CPU_8625, "MSM8625"},
369 [129] = {MSM_CPU_8625, "MSM8625"},
370 [137] = {MSM_CPU_8625, "MSM8625"},
371 [167] = {MSM_CPU_8625, "MSM8625"},
372
373 /* 8064 MPQ ID */
374 [130] = {MSM_CPU_8064, "APQ8064"},
375
376 /* 7x25AB IDs */
377 [131] = {MSM_CPU_7X25AB, "MSM7X25AB"},
378 [132] = {MSM_CPU_7X25AB, "MSM7X25AB"},
379 [133] = {MSM_CPU_7X25AB, "MSM7X25AB"},
380 [135] = {MSM_CPU_7X25AB, "MSM7X25AB"},
381
382 /* 9625 IDs */
383 [134] = {MSM_CPU_9625, "MSM9625"},
384 [148] = {MSM_CPU_9625, "MSM9625"},
385 [149] = {MSM_CPU_9625, "MSM9625"},
386 [150] = {MSM_CPU_9625, "MSM9625"},
387 [151] = {MSM_CPU_9625, "MSM9625"},
388 [152] = {MSM_CPU_9625, "MSM9625"},
389 [173] = {MSM_CPU_9625, "MSM9625"},
390 [174] = {MSM_CPU_9625, "MSM9625"},
391 [175] = {MSM_CPU_9625, "MSM9625"},
392
393 /* 8960AB IDs */
394 [138] = {MSM_CPU_8960AB, "MSM8960AB"},
395 [139] = {MSM_CPU_8960AB, "MSM8960AB"},
396 [140] = {MSM_CPU_8960AB, "MSM8960AB"},
397 [141] = {MSM_CPU_8960AB, "MSM8960AB"},
398
399 /* 8930AA IDs */
400 [142] = {MSM_CPU_8930AA, "MSM8930AA"},
401 [143] = {MSM_CPU_8930AA, "MSM8930AA"},
402 [144] = {MSM_CPU_8930AA, "MSM8930AA"},
403 [160] = {MSM_CPU_8930AA, "MSM8930AA"},
404 [180] = {MSM_CPU_8930AA, "MSM8930AA"},
405
406 /* 8226 IDs */
407 [145] = {MSM_CPU_8226, "MSM8626"},
408 [158] = {MSM_CPU_8226, "MSM8226"},
409 [159] = {MSM_CPU_8226, "MSM8526"},
410 [198] = {MSM_CPU_8226, "MSM8126"},
411 [199] = {MSM_CPU_8226, "APQ8026"},
412 [200] = {MSM_CPU_8226, "MSM8926"},
413 [205] = {MSM_CPU_8226, "MSM8326"},
414 [219] = {MSM_CPU_8226, "APQ8028"},
415 [220] = {MSM_CPU_8226, "MSM8128"},
416 [221] = {MSM_CPU_8226, "MSM8228"},
417 [222] = {MSM_CPU_8226, "MSM8528"},
418 [223] = {MSM_CPU_8226, "MSM8628"},
419 [224] = {MSM_CPU_8226, "MSM8928"},
420
421 /* 8610 IDs */
422 [147] = {MSM_CPU_8610, "MSM8610"},
423 [161] = {MSM_CPU_8610, "MSM8110"},
424 [162] = {MSM_CPU_8610, "MSM8210"},
425 [163] = {MSM_CPU_8610, "MSM8810"},
426 [164] = {MSM_CPU_8610, "MSM8212"},
427 [165] = {MSM_CPU_8610, "MSM8612"},
428 [166] = {MSM_CPU_8610, "MSM8112"},
429 [225] = {MSM_CPU_8610, "MSM8510"},
430 [226] = {MSM_CPU_8610, "MSM8512"},
431
432 /* 8064AB IDs */
433 [153] = {MSM_CPU_8064AB, "APQ8064AB"},
434
435 /* 8930AB IDs */
436 [154] = {MSM_CPU_8930AB, "MSM8930AB"},
437 [155] = {MSM_CPU_8930AB, "MSM8930AB"},
438 [156] = {MSM_CPU_8930AB, "MSM8930AB"},
439 [157] = {MSM_CPU_8930AB, "MSM8930AB"},
440 [181] = {MSM_CPU_8930AB, "MSM8930AB"},
441
442 /* 8625Q IDs */
443 [168] = {MSM_CPU_8625Q, "MSM8225Q"},
444 [169] = {MSM_CPU_8625Q, "MSM8625Q"},
445 [170] = {MSM_CPU_8625Q, "MSM8125Q"},
446
447 /* 8064AA IDs */
448 [172] = {MSM_CPU_8064AA, "APQ8064AA"},
449
450 /* 8084 IDs */
451 [178] = {MSM_CPU_8084, "APQ8084"},
452
453 /* 9630 IDs */
454 [187] = {MSM_CPU_9630, "MDM9630"},
455 [227] = {MSM_CPU_9630, "MDM9630"},
456 [228] = {MSM_CPU_9630, "MDM9630"},
457 [229] = {MSM_CPU_9630, "MDM9630"},
458 [230] = {MSM_CPU_9630, "MDM9630"},
459 [231] = {MSM_CPU_9630, "MDM9630"},
460
461 /* FSM9900 ID */
462 [188] = {FSM_CPU_9900, "FSM9900"},
463 [189] = {FSM_CPU_9900, "FSM9900"},
464 [190] = {FSM_CPU_9900, "FSM9900"},
465 [191] = {FSM_CPU_9900, "FSM9900"},
466 [192] = {FSM_CPU_9900, "FSM9900"},
467 [193] = {FSM_CPU_9900, "FSM9900"},
468
469 /* 8916 IDs */
470 [206] = {MSM_CPU_8916, "MSM8916"},
471 [247] = {MSM_CPU_8916, "APQ8016"},
472 [248] = {MSM_CPU_8916, "MSM8216"},
473 [249] = {MSM_CPU_8916, "MSM8116"},
474 [250] = {MSM_CPU_8916, "MSM8616"},
475
476 /* 8936 IDs */
477 [233] = {MSM_CPU_8936, "MSM8936"},
478 [240] = {MSM_CPU_8936, "APQ8036"},
479 [242] = {MSM_CPU_8936, "MSM8236"},
480
481 /* 8939 IDs */
482 [239] = {MSM_CPU_8939, "MSM8939"},
483 [241] = {MSM_CPU_8939, "APQ8039"},
484 [263] = {MSM_CPU_8939, "MSM8239"},
485
486 /* 8909 IDs */
487 [245] = {MSM_CPU_8909, "MSM8909"},
488 [258] = {MSM_CPU_8909, "MSM8209"},
489 [259] = {MSM_CPU_8909, "MSM8208"},
490 [265] = {MSM_CPU_8909, "APQ8009"},
491 [260] = {MSM_CPU_8909, "MDMFERRUM"},
492 [261] = {MSM_CPU_8909, "MDMFERRUM"},
493 [262] = {MSM_CPU_8909, "MDMFERRUM"},
494 [300] = {MSM_CPU_8909, "MSM8909W"},
495 [301] = {MSM_CPU_8909, "APQ8009W"},
496
497 /* ZIRC IDs */
498 [234] = {MSM_CPU_ZIRC, "MSMZIRC"},
499 [235] = {MSM_CPU_ZIRC, "MSMZIRC"},
500 [236] = {MSM_CPU_ZIRC, "MSMZIRC"},
501 [237] = {MSM_CPU_ZIRC, "MSMZIRC"},
502 [238] = {MSM_CPU_ZIRC, "MSMZIRC"},
503
504 /* 8994 ID */
505 [207] = {MSM_CPU_8994, "MSM8994"},
506 [253] = {MSM_CPU_8994, "APQ8094"},
507
508 /* 8992 ID */
509 [251] = {MSM_CPU_8992, "MSM8992"},
510
511 /* FSM9010 ID */
512 [254] = {FSM_CPU_9010, "FSM9010"},
513 [255] = {FSM_CPU_9010, "FSM9010"},
514 [256] = {FSM_CPU_9010, "FSM9010"},
515 [257] = {FSM_CPU_9010, "FSM9010"},
516
517 /* Tellurium ID */
518 [264] = {MSM_CPU_TELLURIUM, "MSMTELLURIUM"},
519
520 /* 8996 IDs */
521 [246] = {MSM_CPU_8996, "MSM8996"},
522 [310] = {MSM_CPU_8996, "MSM8996"},
523 [311] = {MSM_CPU_8996, "APQ8096"},
524 [291] = {MSM_CPU_8996, "APQ8096"},
525 [305] = {MSM_CPU_8996, "MSM8996pro"},
526 [312] = {MSM_CPU_8996, "APQ8096pro"},
527
528 /* 8976 ID */
529 [266] = {MSM_CPU_8976, "MSM8976"},
530
531 /* 8929 IDs */
532 [268] = {MSM_CPU_8929, "MSM8929"},
533 [269] = {MSM_CPU_8929, "MSM8629"},
534 [270] = {MSM_CPU_8929, "MSM8229"},
535 [271] = {MSM_CPU_8929, "APQ8029"},
536
537 /* Cobalt IDs */
538 [292] = {MSM_CPU_COBALT, "MSMCOBALT"},
539 [319] = {MSM_CPU_COBALT, "APQCOBALT"},
540
541 /* Hamster ID */
542 [306] = {MSM_CPU_HAMSTER, "MSMHAMSTER"},
543
544 /* falcon ID */
545 [317] = {MSM_CPU_FALCON, "MSMFALCON"},
546
Kyle Yan6a20fae2017-02-14 13:34:41 -0800547 /* sdm845 ID */
548 [321] = {MSM_CPU_SDM845, "SDM845"},
Channagoud Kadabi7de40b42016-08-23 22:30:40 -0700549
Kyle Yaneee60c92016-11-08 15:27:22 -0800550 /* Bat ID */
Kyle Yan6a20fae2017-02-14 13:34:41 -0800551 [328] = {MSM_CPU_SDM830, "SDM830"},
Kyle Yaneee60c92016-11-08 15:27:22 -0800552
Runmin Wang88a6fcb2017-04-19 15:28:07 -0700553 /* sdxpoorwills ID */
554 [334] = {SDX_CPU_SDXPOORWILLS, "SDXPOORWILLS"},
555
Bhargav Gurappadia9e6ab42016-08-01 23:35:54 -0700556 /* Uninitialized IDs are not known to run Linux.
557 * MSM_CPU_UNKNOWN is set to 0 to ensure these IDs are
558 * considered as unknown CPU.
559 */
560};
561
562static enum msm_cpu cur_cpu;
563static int current_image;
564static uint32_t socinfo_format;
565
566static struct socinfo_v0_1 dummy_socinfo = {
567 .format = SOCINFO_VERSION(0, 1),
568 .version = 1,
569};
570
571uint32_t socinfo_get_id(void)
572{
573 return (socinfo) ? socinfo->v0_1.id : 0;
574}
575EXPORT_SYMBOL_GPL(socinfo_get_id);
576
577static char *socinfo_get_id_string(void)
578{
579 return (socinfo) ? cpu_of_id[socinfo->v0_1.id].soc_id_string : NULL;
580}
581
582uint32_t socinfo_get_version(void)
583{
584 return (socinfo) ? socinfo->v0_1.version : 0;
585}
586
587char *socinfo_get_build_id(void)
588{
589 return (socinfo) ? socinfo->v0_1.build_id : NULL;
590}
591
592static char *msm_read_hardware_id(void)
593{
594 static char msm_soc_str[256] = "Qualcomm Technologies, Inc ";
595 static bool string_generated;
596 int ret = 0;
597
598 if (string_generated)
599 return msm_soc_str;
600 if (!socinfo)
601 goto err_path;
602 if (!cpu_of_id[socinfo->v0_1.id].soc_id_string)
603 goto err_path;
604
605 ret = strlcat(msm_soc_str, cpu_of_id[socinfo->v0_1.id].soc_id_string,
606 sizeof(msm_soc_str));
607 if (ret > sizeof(msm_soc_str))
608 goto err_path;
609
610 string_generated = true;
611 return msm_soc_str;
612err_path:
613 return "UNKNOWN SOC TYPE";
614}
615
616uint32_t socinfo_get_raw_id(void)
617{
618 return socinfo ?
619 (socinfo_format >= SOCINFO_VERSION(0, 2) ?
620 socinfo->v0_2.raw_id : 0)
621 : 0;
622}
623
624uint32_t socinfo_get_raw_version(void)
625{
626 return socinfo ?
627 (socinfo_format >= SOCINFO_VERSION(0, 2) ?
628 socinfo->v0_2.raw_version : 0)
629 : 0;
630}
631
632uint32_t socinfo_get_platform_type(void)
633{
634 return socinfo ?
635 (socinfo_format >= SOCINFO_VERSION(0, 3) ?
636 socinfo->v0_3.hw_platform : 0)
637 : 0;
638}
639
640
641uint32_t socinfo_get_platform_version(void)
642{
643 return socinfo ?
644 (socinfo_format >= SOCINFO_VERSION(0, 4) ?
645 socinfo->v0_4.platform_version : 0)
646 : 0;
647}
648
649/* This information is directly encoded by the machine id */
650/* Thus no external callers rely on this information at the moment */
651static uint32_t socinfo_get_accessory_chip(void)
652{
653 return socinfo ?
654 (socinfo_format >= SOCINFO_VERSION(0, 5) ?
655 socinfo->v0_5.accessory_chip : 0)
656 : 0;
657}
658
659uint32_t socinfo_get_platform_subtype(void)
660{
661 return socinfo ?
662 (socinfo_format >= SOCINFO_VERSION(0, 6) ?
663 socinfo->v0_6.hw_platform_subtype : 0)
664 : 0;
665}
666
667static uint32_t socinfo_get_foundry_id(void)
668{
669 return socinfo ?
670 (socinfo_format >= SOCINFO_VERSION(0, 9) ?
671 socinfo->v0_9.foundry_id : 0)
672 : 0;
673}
674
675uint32_t socinfo_get_serial_number(void)
676{
677 return socinfo ?
678 (socinfo_format >= SOCINFO_VERSION(0, 10) ?
679 socinfo->v0_10.serial_number : 0)
680 : 0;
681}
682EXPORT_SYMBOL(socinfo_get_serial_number);
683
684static uint32_t socinfo_get_chip_family(void)
685{
686 return socinfo ?
687 (socinfo_format >= SOCINFO_VERSION(0, 12) ?
688 socinfo->v0_12.chip_family : 0)
689 : 0;
690}
691
692static uint32_t socinfo_get_raw_device_family(void)
693{
694 return socinfo ?
695 (socinfo_format >= SOCINFO_VERSION(0, 12) ?
696 socinfo->v0_12.raw_device_family : 0)
697 : 0;
698}
699
700static uint32_t socinfo_get_raw_device_number(void)
701{
702 return socinfo ?
703 (socinfo_format >= SOCINFO_VERSION(0, 12) ?
704 socinfo->v0_12.raw_device_number : 0)
705 : 0;
706}
707
Runmin Wang717ee362017-02-23 13:26:48 -0800708static uint32_t socinfo_get_nproduct_id(void)
709{
710 return socinfo ?
711 (socinfo_format >= SOCINFO_VERSION(0, 13) ?
712 socinfo->v0_13.nproduct_id : 0)
713 : 0;
714}
715
Bhargav Gurappadia9e6ab42016-08-01 23:35:54 -0700716enum pmic_model socinfo_get_pmic_model(void)
717{
718 return socinfo ?
719 (socinfo_format >= SOCINFO_VERSION(0, 7) ?
720 socinfo->v0_7.pmic_model : PMIC_MODEL_UNKNOWN)
721 : PMIC_MODEL_UNKNOWN;
722}
723
724uint32_t socinfo_get_pmic_die_revision(void)
725{
726 return socinfo ?
727 (socinfo_format >= SOCINFO_VERSION(0, 7) ?
728 socinfo->v0_7.pmic_die_revision : 0)
729 : 0;
730}
731
732static char *socinfo_get_image_version_base_address(void)
733{
734 return smem_find(SMEM_IMAGE_VERSION_TABLE,
735 SMEM_IMAGE_VERSION_SIZE, 0, SMEM_ANY_HOST_FLAG);
736}
737
738enum msm_cpu socinfo_get_msm_cpu(void)
739{
740 return cur_cpu;
741}
742EXPORT_SYMBOL_GPL(socinfo_get_msm_cpu);
743
744static ssize_t
745msm_get_vendor(struct device *dev,
746 struct device_attribute *attr,
747 char *buf)
748{
749 return snprintf(buf, PAGE_SIZE, "Qualcomm\n");
750}
751
752static ssize_t
753msm_get_raw_id(struct device *dev,
754 struct device_attribute *attr,
755 char *buf)
756{
757 return snprintf(buf, PAGE_SIZE, "%u\n",
758 socinfo_get_raw_id());
759}
760
761static ssize_t
762msm_get_raw_version(struct device *dev,
763 struct device_attribute *attr,
764 char *buf)
765{
766 return snprintf(buf, PAGE_SIZE, "%u\n",
767 socinfo_get_raw_version());
768}
769
770static ssize_t
771msm_get_build_id(struct device *dev,
772 struct device_attribute *attr,
773 char *buf)
774{
775 return snprintf(buf, PAGE_SIZE, "%-.32s\n",
776 socinfo_get_build_id());
777}
778
779static ssize_t
780msm_get_hw_platform(struct device *dev,
781 struct device_attribute *attr,
782 char *buf)
783{
784 uint32_t hw_type;
785
786 hw_type = socinfo_get_platform_type();
787
788 return snprintf(buf, PAGE_SIZE, "%-.32s\n",
789 hw_platform[hw_type]);
790}
791
792static ssize_t
793msm_get_platform_version(struct device *dev,
794 struct device_attribute *attr,
795 char *buf)
796{
797 return snprintf(buf, PAGE_SIZE, "%u\n",
798 socinfo_get_platform_version());
799}
800
801static ssize_t
802msm_get_accessory_chip(struct device *dev,
803 struct device_attribute *attr,
804 char *buf)
805{
806 return snprintf(buf, PAGE_SIZE, "%u\n",
807 socinfo_get_accessory_chip());
808}
809
810static ssize_t
811msm_get_platform_subtype(struct device *dev,
812 struct device_attribute *attr,
813 char *buf)
814{
815 uint32_t hw_subtype;
816
817 hw_subtype = socinfo_get_platform_subtype();
818 if (HW_PLATFORM_QRD == socinfo_get_platform_type()) {
819 if (hw_subtype >= PLATFORM_SUBTYPE_QRD_INVALID) {
820 pr_err("Invalid hardware platform sub type for qrd found\n");
821 hw_subtype = PLATFORM_SUBTYPE_QRD_INVALID;
822 }
823 return snprintf(buf, PAGE_SIZE, "%-.32s\n",
824 qrd_hw_platform_subtype[hw_subtype]);
825 } else {
826 if (hw_subtype >= PLATFORM_SUBTYPE_INVALID) {
827 pr_err("Invalid hardware platform subtype\n");
828 hw_subtype = PLATFORM_SUBTYPE_INVALID;
829 }
830 return snprintf(buf, PAGE_SIZE, "%-.32s\n",
831 hw_platform_subtype[hw_subtype]);
832 }
833}
834
835static ssize_t
836msm_get_platform_subtype_id(struct device *dev,
837 struct device_attribute *attr,
838 char *buf)
839{
840 uint32_t hw_subtype;
841
842 hw_subtype = socinfo_get_platform_subtype();
843 return snprintf(buf, PAGE_SIZE, "%u\n",
844 hw_subtype);
845}
846
847static ssize_t
848msm_get_foundry_id(struct device *dev,
849 struct device_attribute *attr,
850 char *buf)
851{
852 return snprintf(buf, PAGE_SIZE, "%u\n",
853 socinfo_get_foundry_id());
854}
855
856static ssize_t
857msm_get_serial_number(struct device *dev,
858 struct device_attribute *attr,
859 char *buf)
860{
861 return snprintf(buf, PAGE_SIZE, "%u\n",
862 socinfo_get_serial_number());
863}
864
865static ssize_t
866msm_get_chip_family(struct device *dev,
867 struct device_attribute *attr,
868 char *buf)
869{
870 return snprintf(buf, PAGE_SIZE, "0x%x\n",
871 socinfo_get_chip_family());
872}
873
874static ssize_t
875msm_get_raw_device_family(struct device *dev,
876 struct device_attribute *attr,
877 char *buf)
878{
879 return snprintf(buf, PAGE_SIZE, "0x%x\n",
880 socinfo_get_raw_device_family());
881}
882
883static ssize_t
884msm_get_raw_device_number(struct device *dev,
885 struct device_attribute *attr,
886 char *buf)
887{
888 return snprintf(buf, PAGE_SIZE, "0x%x\n",
889 socinfo_get_raw_device_number());
890}
891
892static ssize_t
Runmin Wang717ee362017-02-23 13:26:48 -0800893msm_get_nproduct_id(struct device *dev,
894 struct device_attribute *attr,
895 char *buf)
896{
897 return snprintf(buf, PAGE_SIZE, "0x%x\n",
898 socinfo_get_nproduct_id());
899}
900
901static ssize_t
Bhargav Gurappadia9e6ab42016-08-01 23:35:54 -0700902msm_get_pmic_model(struct device *dev,
903 struct device_attribute *attr,
904 char *buf)
905{
906 return snprintf(buf, PAGE_SIZE, "%u\n",
907 socinfo_get_pmic_model());
908}
909
910static ssize_t
911msm_get_pmic_die_revision(struct device *dev,
912 struct device_attribute *attr,
913 char *buf)
914{
915 return snprintf(buf, PAGE_SIZE, "%u\n",
916 socinfo_get_pmic_die_revision());
917}
918
919static ssize_t
920msm_get_image_version(struct device *dev,
921 struct device_attribute *attr,
922 char *buf)
923{
924 char *string_address;
925
926 string_address = socinfo_get_image_version_base_address();
927 if (IS_ERR_OR_NULL(string_address)) {
928 pr_err("Failed to get image version base address");
929 return snprintf(buf, SMEM_IMAGE_VERSION_NAME_SIZE, "Unknown");
930 }
931 string_address += current_image * SMEM_IMAGE_VERSION_SINGLE_BLOCK_SIZE;
932 return snprintf(buf, SMEM_IMAGE_VERSION_NAME_SIZE, "%-.75s\n",
933 string_address);
934}
935
936static ssize_t
937msm_set_image_version(struct device *dev,
938 struct device_attribute *attr,
939 const char *buf,
940 size_t count)
941{
942 char *store_address;
943
944 if (current_image != SMEM_IMAGE_VERSION_PARTITION_APPS)
945 return count;
946 store_address = socinfo_get_image_version_base_address();
947 if (IS_ERR_OR_NULL(store_address)) {
948 pr_err("Failed to get image version base address");
949 return count;
950 }
951 store_address += current_image * SMEM_IMAGE_VERSION_SINGLE_BLOCK_SIZE;
952 snprintf(store_address, SMEM_IMAGE_VERSION_NAME_SIZE, "%-.75s", buf);
953 return count;
954}
955
956static ssize_t
957msm_get_image_variant(struct device *dev,
958 struct device_attribute *attr,
959 char *buf)
960{
961 char *string_address;
962
963 string_address = socinfo_get_image_version_base_address();
964 if (IS_ERR_OR_NULL(string_address)) {
965 pr_err("Failed to get image version base address");
966 return snprintf(buf, SMEM_IMAGE_VERSION_VARIANT_SIZE,
967 "Unknown");
968 }
969 string_address += current_image * SMEM_IMAGE_VERSION_SINGLE_BLOCK_SIZE;
970 string_address += SMEM_IMAGE_VERSION_VARIANT_OFFSET;
971 return snprintf(buf, SMEM_IMAGE_VERSION_VARIANT_SIZE, "%-.20s\n",
972 string_address);
973}
974
975static ssize_t
976msm_set_image_variant(struct device *dev,
977 struct device_attribute *attr,
978 const char *buf,
979 size_t count)
980{
981 char *store_address;
982
983 if (current_image != SMEM_IMAGE_VERSION_PARTITION_APPS)
984 return count;
985 store_address = socinfo_get_image_version_base_address();
986 if (IS_ERR_OR_NULL(store_address)) {
987 pr_err("Failed to get image version base address");
988 return count;
989 }
990 store_address += current_image * SMEM_IMAGE_VERSION_SINGLE_BLOCK_SIZE;
991 store_address += SMEM_IMAGE_VERSION_VARIANT_OFFSET;
992 snprintf(store_address, SMEM_IMAGE_VERSION_VARIANT_SIZE, "%-.20s", buf);
993 return count;
994}
995
996static ssize_t
997msm_get_image_crm_version(struct device *dev,
998 struct device_attribute *attr,
999 char *buf)
1000{
1001 char *string_address;
1002
1003 string_address = socinfo_get_image_version_base_address();
1004 if (IS_ERR_OR_NULL(string_address)) {
1005 pr_err("Failed to get image version base address");
1006 return snprintf(buf, SMEM_IMAGE_VERSION_OEM_SIZE, "Unknown");
1007 }
1008 string_address += current_image * SMEM_IMAGE_VERSION_SINGLE_BLOCK_SIZE;
1009 string_address += SMEM_IMAGE_VERSION_OEM_OFFSET;
1010 return snprintf(buf, SMEM_IMAGE_VERSION_OEM_SIZE, "%-.32s\n",
1011 string_address);
1012}
1013
1014static ssize_t
1015msm_set_image_crm_version(struct device *dev,
1016 struct device_attribute *attr,
1017 const char *buf,
1018 size_t count)
1019{
1020 char *store_address;
1021
1022 if (current_image != SMEM_IMAGE_VERSION_PARTITION_APPS)
1023 return count;
1024 store_address = socinfo_get_image_version_base_address();
1025 if (IS_ERR_OR_NULL(store_address)) {
1026 pr_err("Failed to get image version base address");
1027 return count;
1028 }
1029 store_address += current_image * SMEM_IMAGE_VERSION_SINGLE_BLOCK_SIZE;
1030 store_address += SMEM_IMAGE_VERSION_OEM_OFFSET;
1031 snprintf(store_address, SMEM_IMAGE_VERSION_OEM_SIZE, "%-.32s", buf);
1032 return count;
1033}
1034
1035static ssize_t
1036msm_get_image_number(struct device *dev,
1037 struct device_attribute *attr,
1038 char *buf)
1039{
1040 return snprintf(buf, PAGE_SIZE, "%d\n",
1041 current_image);
1042}
1043
1044static ssize_t
1045msm_select_image(struct device *dev, struct device_attribute *attr,
1046 const char *buf, size_t count)
1047{
1048 int ret, digit;
1049
1050 ret = kstrtoint(buf, 10, &digit);
1051 if (ret)
1052 return ret;
1053 if (digit >= 0 && digit < SMEM_IMAGE_VERSION_BLOCKS_COUNT)
1054 current_image = digit;
1055 else
1056 current_image = 0;
1057 return count;
1058}
1059
1060static ssize_t
1061msm_get_images(struct device *dev,
1062 struct device_attribute *attr, char *buf)
1063{
1064 int pos = 0;
1065 int image;
1066 char *image_address;
1067
1068 image_address = socinfo_get_image_version_base_address();
1069 if (IS_ERR_OR_NULL(image_address))
1070 return snprintf(buf, PAGE_SIZE, "Unavailable\n");
1071
1072 *buf = '\0';
1073 for (image = 0; image < SMEM_IMAGE_VERSION_BLOCKS_COUNT; image++) {
1074 if (*image_address == '\0') {
1075 image_address += SMEM_IMAGE_VERSION_SINGLE_BLOCK_SIZE;
1076 continue;
1077 }
1078
1079 pos += snprintf(buf + pos, PAGE_SIZE - pos, "%d:\n",
1080 image);
1081 pos += snprintf(buf + pos, PAGE_SIZE - pos,
1082 "\tCRM:\t\t%-.75s\n", image_address);
1083 pos += snprintf(buf + pos, PAGE_SIZE - pos, "\tVariant:\t%-.20s\n",
1084 image_address + SMEM_IMAGE_VERSION_VARIANT_OFFSET);
1085 pos += snprintf(buf + pos, PAGE_SIZE - pos, "\tVersion:\t%-.32s\n\n",
1086 image_address + SMEM_IMAGE_VERSION_OEM_OFFSET);
1087
1088 image_address += SMEM_IMAGE_VERSION_SINGLE_BLOCK_SIZE;
1089 }
1090
1091 return pos;
1092}
1093
1094static struct device_attribute msm_soc_attr_raw_version =
1095 __ATTR(raw_version, S_IRUGO, msm_get_raw_version, NULL);
1096
1097static struct device_attribute msm_soc_attr_raw_id =
1098 __ATTR(raw_id, S_IRUGO, msm_get_raw_id, NULL);
1099
1100static struct device_attribute msm_soc_attr_vendor =
1101 __ATTR(vendor, S_IRUGO, msm_get_vendor, NULL);
1102
1103static struct device_attribute msm_soc_attr_build_id =
1104 __ATTR(build_id, S_IRUGO, msm_get_build_id, NULL);
1105
1106static struct device_attribute msm_soc_attr_hw_platform =
1107 __ATTR(hw_platform, S_IRUGO, msm_get_hw_platform, NULL);
1108
1109
1110static struct device_attribute msm_soc_attr_platform_version =
1111 __ATTR(platform_version, S_IRUGO,
1112 msm_get_platform_version, NULL);
1113
1114static struct device_attribute msm_soc_attr_accessory_chip =
1115 __ATTR(accessory_chip, S_IRUGO,
1116 msm_get_accessory_chip, NULL);
1117
1118static struct device_attribute msm_soc_attr_platform_subtype =
1119 __ATTR(platform_subtype, S_IRUGO,
1120 msm_get_platform_subtype, NULL);
1121
1122/* Platform Subtype String is being deprecated. Use Platform
1123 * Subtype ID instead.
1124 */
1125static struct device_attribute msm_soc_attr_platform_subtype_id =
1126 __ATTR(platform_subtype_id, S_IRUGO,
1127 msm_get_platform_subtype_id, NULL);
1128
1129static struct device_attribute msm_soc_attr_foundry_id =
1130 __ATTR(foundry_id, S_IRUGO,
1131 msm_get_foundry_id, NULL);
1132
1133static struct device_attribute msm_soc_attr_serial_number =
1134 __ATTR(serial_number, S_IRUGO,
1135 msm_get_serial_number, NULL);
1136
1137static struct device_attribute msm_soc_attr_chip_family =
1138 __ATTR(chip_family, S_IRUGO,
1139 msm_get_chip_family, NULL);
1140
1141static struct device_attribute msm_soc_attr_raw_device_family =
1142 __ATTR(raw_device_family, S_IRUGO,
1143 msm_get_raw_device_family, NULL);
1144
1145static struct device_attribute msm_soc_attr_raw_device_number =
1146 __ATTR(raw_device_number, S_IRUGO,
1147 msm_get_raw_device_number, NULL);
1148
Runmin Wang717ee362017-02-23 13:26:48 -08001149static struct device_attribute msm_soc_attr_nproduct_id =
1150 __ATTR(nproduct_id, 0444,
1151 msm_get_nproduct_id, NULL);
1152
Bhargav Gurappadia9e6ab42016-08-01 23:35:54 -07001153static struct device_attribute msm_soc_attr_pmic_model =
1154 __ATTR(pmic_model, S_IRUGO,
1155 msm_get_pmic_model, NULL);
1156
1157static struct device_attribute msm_soc_attr_pmic_die_revision =
1158 __ATTR(pmic_die_revision, S_IRUGO,
1159 msm_get_pmic_die_revision, NULL);
1160
1161static struct device_attribute image_version =
1162 __ATTR(image_version, S_IRUGO | S_IWUSR,
1163 msm_get_image_version, msm_set_image_version);
1164
1165static struct device_attribute image_variant =
1166 __ATTR(image_variant, S_IRUGO | S_IWUSR,
1167 msm_get_image_variant, msm_set_image_variant);
1168
1169static struct device_attribute image_crm_version =
1170 __ATTR(image_crm_version, S_IRUGO | S_IWUSR,
1171 msm_get_image_crm_version, msm_set_image_crm_version);
1172
1173static struct device_attribute select_image =
1174 __ATTR(select_image, S_IRUGO | S_IWUSR,
1175 msm_get_image_number, msm_select_image);
1176
1177static struct device_attribute images =
1178 __ATTR(images, S_IRUGO, msm_get_images, NULL);
1179
1180static void * __init setup_dummy_socinfo(void)
1181{
1182 if (early_machine_is_apq8084()) {
1183 dummy_socinfo.id = 178;
1184 strlcpy(dummy_socinfo.build_id, "apq8084 - ",
1185 sizeof(dummy_socinfo.build_id));
1186 } else if (early_machine_is_mdm9630()) {
1187 dummy_socinfo.id = 187;
1188 strlcpy(dummy_socinfo.build_id, "mdm9630 - ",
1189 sizeof(dummy_socinfo.build_id));
1190 } else if (early_machine_is_msm8909()) {
1191 dummy_socinfo.id = 245;
1192 strlcpy(dummy_socinfo.build_id, "msm8909 - ",
1193 sizeof(dummy_socinfo.build_id));
1194 } else if (early_machine_is_msm8916()) {
1195 dummy_socinfo.id = 206;
1196 strlcpy(dummy_socinfo.build_id, "msm8916 - ",
1197 sizeof(dummy_socinfo.build_id));
1198 } else if (early_machine_is_msm8939()) {
1199 dummy_socinfo.id = 239;
1200 strlcpy(dummy_socinfo.build_id, "msm8939 - ",
1201 sizeof(dummy_socinfo.build_id));
1202 } else if (early_machine_is_msm8936()) {
1203 dummy_socinfo.id = 233;
1204 strlcpy(dummy_socinfo.build_id, "msm8936 - ",
1205 sizeof(dummy_socinfo.build_id));
1206 } else if (early_machine_is_msmzirc()) {
1207 dummy_socinfo.id = 238;
1208 strlcpy(dummy_socinfo.build_id, "msmzirc - ",
1209 sizeof(dummy_socinfo.build_id));
1210 } else if (early_machine_is_msm8994()) {
1211 dummy_socinfo.id = 207;
1212 strlcpy(dummy_socinfo.build_id, "msm8994 - ",
1213 sizeof(dummy_socinfo.build_id));
1214 } else if (early_machine_is_msm8992()) {
1215 dummy_socinfo.id = 251;
1216 strlcpy(dummy_socinfo.build_id, "msm8992 - ",
1217 sizeof(dummy_socinfo.build_id));
1218 } else if (early_machine_is_msm8976()) {
1219 dummy_socinfo.id = 266;
1220 strlcpy(dummy_socinfo.build_id, "msm8976 - ",
1221 sizeof(dummy_socinfo.build_id));
1222 } else if (early_machine_is_msmtellurium()) {
1223 dummy_socinfo.id = 264;
1224 strlcpy(dummy_socinfo.build_id, "msmtellurium - ",
1225 sizeof(dummy_socinfo.build_id));
1226 } else if (early_machine_is_msm8996()) {
1227 dummy_socinfo.id = 246;
1228 strlcpy(dummy_socinfo.build_id, "msm8996 - ",
1229 sizeof(dummy_socinfo.build_id));
1230 } else if (early_machine_is_msm8996_auto()) {
1231 dummy_socinfo.id = 310;
1232 strlcpy(dummy_socinfo.build_id, "msm8996-auto - ",
1233 sizeof(dummy_socinfo.build_id));
1234 } else if (early_machine_is_msm8929()) {
1235 dummy_socinfo.id = 268;
1236 strlcpy(dummy_socinfo.build_id, "msm8929 - ",
1237 sizeof(dummy_socinfo.build_id));
1238 } else if (early_machine_is_msmcobalt()) {
1239 dummy_socinfo.id = 292;
1240 strlcpy(dummy_socinfo.build_id, "msmcobalt - ",
1241 sizeof(dummy_socinfo.build_id));
1242 } else if (early_machine_is_msmhamster()) {
1243 dummy_socinfo.id = 306;
1244 strlcpy(dummy_socinfo.build_id, "msmhamster - ",
1245 sizeof(dummy_socinfo.build_id));
1246 } else if (early_machine_is_msmfalcon()) {
1247 dummy_socinfo.id = 317;
1248 strlcpy(dummy_socinfo.build_id, "msmfalcon - ",
1249 sizeof(dummy_socinfo.build_id));
1250 } else if (early_machine_is_apqcobalt()) {
1251 dummy_socinfo.id = 319;
1252 strlcpy(dummy_socinfo.build_id, "apqcobalt - ",
1253 sizeof(dummy_socinfo.build_id));
Kyle Yan6a20fae2017-02-14 13:34:41 -08001254 } else if (early_machine_is_sdm845()) {
Channagoud Kadabi04eded92016-09-14 12:09:43 -07001255 dummy_socinfo.id = 321;
Kyle Yan6a20fae2017-02-14 13:34:41 -08001256 strlcpy(dummy_socinfo.build_id, "sdm845 - ",
Channagoud Kadabi04eded92016-09-14 12:09:43 -07001257 sizeof(dummy_socinfo.build_id));
Kyle Yan6a20fae2017-02-14 13:34:41 -08001258 } else if (early_machine_is_sdm830()) {
Kyle Yaneee60c92016-11-08 15:27:22 -08001259 dummy_socinfo.id = 328;
Kyle Yan6a20fae2017-02-14 13:34:41 -08001260 strlcpy(dummy_socinfo.build_id, "sdm830 - ",
Kyle Yaneee60c92016-11-08 15:27:22 -08001261 sizeof(dummy_socinfo.build_id));
Runmin Wang88a6fcb2017-04-19 15:28:07 -07001262 } else if (early_machine_is_sdxpoorwills()) {
1263 dummy_socinfo.id = 334;
1264 strlcpy(dummy_socinfo.build_id, "sdxpoorwills - ",
1265 sizeof(dummy_socinfo.build_id));
Bhargav Gurappadia9e6ab42016-08-01 23:35:54 -07001266 }
1267
1268 strlcat(dummy_socinfo.build_id, "Dummy socinfo",
1269 sizeof(dummy_socinfo.build_id));
1270 return (void *) &dummy_socinfo;
1271}
1272
1273static void __init populate_soc_sysfs_files(struct device *msm_soc_device)
1274{
1275 device_create_file(msm_soc_device, &msm_soc_attr_vendor);
1276 device_create_file(msm_soc_device, &image_version);
1277 device_create_file(msm_soc_device, &image_variant);
1278 device_create_file(msm_soc_device, &image_crm_version);
1279 device_create_file(msm_soc_device, &select_image);
1280 device_create_file(msm_soc_device, &images);
1281
1282 switch (socinfo_format) {
Runmin Wang717ee362017-02-23 13:26:48 -08001283 case SOCINFO_VERSION(0, 13):
1284 device_create_file(msm_soc_device,
1285 &msm_soc_attr_nproduct_id);
Bhargav Gurappadia9e6ab42016-08-01 23:35:54 -07001286 case SOCINFO_VERSION(0, 12):
1287 device_create_file(msm_soc_device,
1288 &msm_soc_attr_chip_family);
1289 device_create_file(msm_soc_device,
1290 &msm_soc_attr_raw_device_family);
1291 device_create_file(msm_soc_device,
1292 &msm_soc_attr_raw_device_number);
1293 case SOCINFO_VERSION(0, 11):
1294 case SOCINFO_VERSION(0, 10):
1295 device_create_file(msm_soc_device,
1296 &msm_soc_attr_serial_number);
1297 case SOCINFO_VERSION(0, 9):
1298 device_create_file(msm_soc_device,
1299 &msm_soc_attr_foundry_id);
1300 case SOCINFO_VERSION(0, 8):
1301 case SOCINFO_VERSION(0, 7):
1302 device_create_file(msm_soc_device,
1303 &msm_soc_attr_pmic_model);
1304 device_create_file(msm_soc_device,
1305 &msm_soc_attr_pmic_die_revision);
1306 case SOCINFO_VERSION(0, 6):
1307 device_create_file(msm_soc_device,
1308 &msm_soc_attr_platform_subtype);
1309 device_create_file(msm_soc_device,
1310 &msm_soc_attr_platform_subtype_id);
1311 case SOCINFO_VERSION(0, 5):
1312 device_create_file(msm_soc_device,
1313 &msm_soc_attr_accessory_chip);
1314 case SOCINFO_VERSION(0, 4):
1315 device_create_file(msm_soc_device,
1316 &msm_soc_attr_platform_version);
1317 case SOCINFO_VERSION(0, 3):
1318 device_create_file(msm_soc_device,
1319 &msm_soc_attr_hw_platform);
1320 case SOCINFO_VERSION(0, 2):
1321 device_create_file(msm_soc_device,
1322 &msm_soc_attr_raw_id);
1323 device_create_file(msm_soc_device,
1324 &msm_soc_attr_raw_version);
1325 case SOCINFO_VERSION(0, 1):
1326 device_create_file(msm_soc_device,
1327 &msm_soc_attr_build_id);
1328 break;
1329 default:
1330 pr_err("Unknown socinfo format: v%u.%u\n",
1331 SOCINFO_VERSION_MAJOR(socinfo_format),
1332 SOCINFO_VERSION_MINOR(socinfo_format));
1333 break;
1334 }
1335
1336}
1337
1338static void __init soc_info_populate(struct soc_device_attribute *soc_dev_attr)
1339{
1340 uint32_t soc_version = socinfo_get_version();
1341
1342 soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "%d", socinfo_get_id());
1343 soc_dev_attr->family = "Snapdragon";
1344 soc_dev_attr->machine = socinfo_get_id_string();
1345 soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%u.%u",
1346 SOCINFO_VERSION_MAJOR(soc_version),
1347 SOCINFO_VERSION_MINOR(soc_version));
1348 return;
1349
1350}
1351
1352static int __init socinfo_init_sysfs(void)
1353{
1354 struct device *msm_soc_device;
1355 struct soc_device *soc_dev;
1356 struct soc_device_attribute *soc_dev_attr;
1357
1358 if (!socinfo) {
1359 pr_err("No socinfo found!\n");
1360 return -ENODEV;
1361 }
1362
1363 soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
1364 if (!soc_dev_attr) {
1365 pr_err("Soc Device alloc failed!\n");
1366 return -ENOMEM;
1367 }
1368
1369 soc_info_populate(soc_dev_attr);
1370 soc_dev = soc_device_register(soc_dev_attr);
1371 if (IS_ERR_OR_NULL(soc_dev)) {
1372 kfree(soc_dev_attr);
1373 pr_err("Soc device register failed\n");
1374 return -EIO;
1375 }
1376
1377 msm_soc_device = soc_device_to_device(soc_dev);
1378 populate_soc_sysfs_files(msm_soc_device);
1379 return 0;
1380}
1381
1382late_initcall(socinfo_init_sysfs);
1383
1384static void socinfo_print(void)
1385{
1386 uint32_t f_maj = SOCINFO_VERSION_MAJOR(socinfo_format);
1387 uint32_t f_min = SOCINFO_VERSION_MINOR(socinfo_format);
1388 uint32_t v_maj = SOCINFO_VERSION_MAJOR(socinfo->v0_1.version);
1389 uint32_t v_min = SOCINFO_VERSION_MINOR(socinfo->v0_1.version);
1390
1391 switch (socinfo_format) {
1392 case SOCINFO_VERSION(0, 1):
1393 pr_info("v%u.%u, id=%u, ver=%u.%u\n",
1394 f_maj, f_min, socinfo->v0_1.id, v_maj, v_min);
1395 break;
1396 case SOCINFO_VERSION(0, 2):
1397 pr_info("v%u.%u, id=%u, ver=%u.%u, "
1398 "raw_id=%u, raw_ver=%u\n",
1399 f_maj, f_min, socinfo->v0_1.id, v_maj, v_min,
1400 socinfo->v0_2.raw_id, socinfo->v0_2.raw_version);
1401 break;
1402 case SOCINFO_VERSION(0, 3):
1403 pr_info("v%u.%u, id=%u, ver=%u.%u, "
1404 "raw_id=%u, raw_ver=%u, hw_plat=%u\n",
1405 f_maj, f_min, socinfo->v0_1.id, v_maj, v_min,
1406 socinfo->v0_2.raw_id, socinfo->v0_2.raw_version,
1407 socinfo->v0_3.hw_platform);
1408 break;
1409 case SOCINFO_VERSION(0, 4):
1410 pr_info("v%u.%u, id=%u, ver=%u.%u, "
1411 "raw_id=%u, raw_ver=%u, hw_plat=%u, hw_plat_ver=%u\n",
1412 f_maj, f_min, socinfo->v0_1.id, v_maj, v_min,
1413 socinfo->v0_2.raw_id, socinfo->v0_2.raw_version,
1414 socinfo->v0_3.hw_platform,
1415 socinfo->v0_4.platform_version);
1416 break;
1417 case SOCINFO_VERSION(0, 5):
1418 pr_info("v%u.%u, id=%u, ver=%u.%u, "
1419 "raw_id=%u, raw_ver=%u, hw_plat=%u, hw_plat_ver=%u\n"
1420 " accessory_chip=%u\n",
1421 f_maj, f_min, socinfo->v0_1.id, v_maj, v_min,
1422 socinfo->v0_2.raw_id, socinfo->v0_2.raw_version,
1423 socinfo->v0_3.hw_platform,
1424 socinfo->v0_4.platform_version,
1425 socinfo->v0_5.accessory_chip);
1426 break;
1427 case SOCINFO_VERSION(0, 6):
1428 pr_info("v%u.%u, id=%u, ver=%u.%u, "
1429 "raw_id=%u, raw_ver=%u, hw_plat=%u, hw_plat_ver=%u\n"
1430 " accessory_chip=%u hw_plat_subtype=%u\n",
1431 f_maj, f_min, socinfo->v0_1.id, v_maj, v_min,
1432 socinfo->v0_2.raw_id, socinfo->v0_2.raw_version,
1433 socinfo->v0_3.hw_platform,
1434 socinfo->v0_4.platform_version,
1435 socinfo->v0_5.accessory_chip,
1436 socinfo->v0_6.hw_platform_subtype);
1437 break;
1438 case SOCINFO_VERSION(0, 7):
1439 case SOCINFO_VERSION(0, 8):
1440 pr_info("v%u.%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",
1441 f_maj, f_min, socinfo->v0_1.id, v_maj, v_min,
1442 socinfo->v0_2.raw_id, socinfo->v0_2.raw_version,
1443 socinfo->v0_3.hw_platform,
1444 socinfo->v0_4.platform_version,
1445 socinfo->v0_5.accessory_chip,
1446 socinfo->v0_6.hw_platform_subtype,
1447 socinfo->v0_7.pmic_model,
1448 socinfo->v0_7.pmic_die_revision);
1449 break;
1450 case SOCINFO_VERSION(0, 9):
1451 pr_info("v%u.%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 foundry_id=%u\n",
1452 f_maj, f_min, socinfo->v0_1.id, v_maj, v_min,
1453 socinfo->v0_2.raw_id, socinfo->v0_2.raw_version,
1454 socinfo->v0_3.hw_platform,
1455 socinfo->v0_4.platform_version,
1456 socinfo->v0_5.accessory_chip,
1457 socinfo->v0_6.hw_platform_subtype,
1458 socinfo->v0_7.pmic_model,
1459 socinfo->v0_7.pmic_die_revision,
1460 socinfo->v0_9.foundry_id);
1461 break;
1462 case SOCINFO_VERSION(0, 10):
1463 pr_info("v%u.%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 foundry_id=%u serial_number=%u\n",
1464 f_maj, f_min, socinfo->v0_1.id, v_maj, v_min,
1465 socinfo->v0_2.raw_id, socinfo->v0_2.raw_version,
1466 socinfo->v0_3.hw_platform,
1467 socinfo->v0_4.platform_version,
1468 socinfo->v0_5.accessory_chip,
1469 socinfo->v0_6.hw_platform_subtype,
1470 socinfo->v0_7.pmic_model,
1471 socinfo->v0_7.pmic_die_revision,
1472 socinfo->v0_9.foundry_id,
1473 socinfo->v0_10.serial_number);
1474 break;
1475 case SOCINFO_VERSION(0, 11):
1476 pr_info("v%u.%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 foundry_id=%u serial_number=%u num_pmics=%u\n",
1477 f_maj, f_min, socinfo->v0_1.id, v_maj, v_min,
1478 socinfo->v0_2.raw_id, socinfo->v0_2.raw_version,
1479 socinfo->v0_3.hw_platform,
1480 socinfo->v0_4.platform_version,
1481 socinfo->v0_5.accessory_chip,
1482 socinfo->v0_6.hw_platform_subtype,
1483 socinfo->v0_7.pmic_model,
1484 socinfo->v0_7.pmic_die_revision,
1485 socinfo->v0_9.foundry_id,
1486 socinfo->v0_10.serial_number,
1487 socinfo->v0_11.num_pmics);
1488 break;
1489 case SOCINFO_VERSION(0, 12):
1490 pr_info("v%u.%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 foundry_id=%u serial_number=%u num_pmics=%u chip_family=0x%x raw_device_family=0x%x raw_device_number=0x%x\n",
1491 f_maj, f_min, socinfo->v0_1.id, v_maj, v_min,
1492 socinfo->v0_2.raw_id, socinfo->v0_2.raw_version,
1493 socinfo->v0_3.hw_platform,
1494 socinfo->v0_4.platform_version,
1495 socinfo->v0_5.accessory_chip,
1496 socinfo->v0_6.hw_platform_subtype,
1497 socinfo->v0_7.pmic_model,
1498 socinfo->v0_7.pmic_die_revision,
1499 socinfo->v0_9.foundry_id,
1500 socinfo->v0_10.serial_number,
1501 socinfo->v0_11.num_pmics,
1502 socinfo->v0_12.chip_family,
1503 socinfo->v0_12.raw_device_family,
1504 socinfo->v0_12.raw_device_number);
1505 break;
Runmin Wang717ee362017-02-23 13:26:48 -08001506 case SOCINFO_VERSION(0, 13):
1507 pr_info("v%u.%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 foundry_id=%u serial_number=%u num_pmics=%u chip_family=0x%x raw_device_family=0x%x raw_device_number=0x%x nproduct_id=0x%x\n",
1508 f_maj, f_min, socinfo->v0_1.id, v_maj, v_min,
1509 socinfo->v0_2.raw_id, socinfo->v0_2.raw_version,
1510 socinfo->v0_3.hw_platform,
1511 socinfo->v0_4.platform_version,
1512 socinfo->v0_5.accessory_chip,
1513 socinfo->v0_6.hw_platform_subtype,
1514 socinfo->v0_7.pmic_model,
1515 socinfo->v0_7.pmic_die_revision,
1516 socinfo->v0_9.foundry_id,
1517 socinfo->v0_10.serial_number,
1518 socinfo->v0_11.num_pmics,
1519 socinfo->v0_12.chip_family,
1520 socinfo->v0_12.raw_device_family,
1521 socinfo->v0_12.raw_device_number,
1522 socinfo->v0_13.nproduct_id);
1523 break;
Bhargav Gurappadia9e6ab42016-08-01 23:35:54 -07001524
1525 default:
1526 pr_err("Unknown format found: v%u.%u\n", f_maj, f_min);
1527 break;
1528 }
1529}
1530
1531static void socinfo_select_format(void)
1532{
1533 uint32_t f_maj = SOCINFO_VERSION_MAJOR(socinfo->v0_1.format);
1534 uint32_t f_min = SOCINFO_VERSION_MINOR(socinfo->v0_1.format);
1535
1536 if (f_maj != 0) {
1537 pr_err("Unsupported format v%u.%u. Falling back to dummy values.\n",
1538 f_maj, f_min);
1539 socinfo = setup_dummy_socinfo();
1540 }
1541
1542 if (socinfo->v0_1.format > MAX_SOCINFO_FORMAT) {
1543 pr_warn("Unsupported format v%u.%u. Falling back to v%u.%u.\n",
1544 f_maj, f_min, SOCINFO_VERSION_MAJOR(MAX_SOCINFO_FORMAT),
1545 SOCINFO_VERSION_MINOR(MAX_SOCINFO_FORMAT));
1546 socinfo_format = MAX_SOCINFO_FORMAT;
1547 } else {
1548 socinfo_format = socinfo->v0_1.format;
1549 }
1550}
1551
1552int __init socinfo_init(void)
1553{
1554 static bool socinfo_init_done;
1555 unsigned int size;
1556
1557 if (socinfo_init_done)
1558 return 0;
1559
1560 socinfo = smem_get_entry(SMEM_HW_SW_BUILD_ID, &size, 0,
1561 SMEM_ANY_HOST_FLAG);
1562 if (IS_ERR_OR_NULL(socinfo)) {
1563 pr_warn("Can't find SMEM_HW_SW_BUILD_ID; falling back on dummy values.\n");
1564 socinfo = setup_dummy_socinfo();
1565 }
1566
1567 socinfo_select_format();
1568
1569 WARN(!socinfo_get_id(), "Unknown SOC ID!\n");
1570
1571 if (socinfo_get_id() >= ARRAY_SIZE(cpu_of_id))
1572 BUG_ON("New IDs added! ID => CPU mapping needs an update.\n");
1573 else
1574 cur_cpu = cpu_of_id[socinfo->v0_1.id].generic_soc_type;
1575
1576 boot_stats_init();
1577 socinfo_print();
1578 arch_read_hardware_id = msm_read_hardware_id;
1579 socinfo_init_done = true;
1580
1581 return 0;
1582}
1583subsys_initcall(socinfo_init);