blob: 8af3890bf4bba4c84c820f45868c31915ce70c76 [file] [log] [blame]
Abhimanyu Kapur440cdde2012-12-04 00:05:40 -08001/* 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
Abhimanyu Kapur440cdde2012-12-04 00:05:40 -080018#include <linux/err.h>
19#include <linux/of.h>
20#include <linux/platform_device.h>
21#include <linux/sys_soc.h>
22#include <linux/slab.h>
23#include <linux/stat.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070024#include <linux/sysdev.h>
Abhimanyu Kapur440cdde2012-12-04 00:05:40 -080025#include <linux/types.h>
26
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070027#include <asm/mach-types.h>
Abhimanyu Kapur440cdde2012-12-04 00:05:40 -080028
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070029#include <mach/socinfo.h>
Jeff Hugo5ba15fe2013-05-06 14:24:24 -060030#include <mach/msm_smem.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070031
Abhimanyu Kapurcf3ed152013-03-01 19:32:19 -080032#include "boot_stats.h"
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070033
34#define BUILD_ID_LENGTH 32
Yulian Shandoroved2265b2013-08-16 00:46:59 -070035#define SMEM_IMAGE_VERSION_BLOCKS_COUNT 32
36#define SMEM_IMAGE_VERSION_SINGLE_BLOCK_SIZE 128
37#define SMEM_IMAGE_VERSION_SIZE 4096
38#define SMEM_IMAGE_VERSION_NAME_SIZE 75
39#define SMEM_IMAGE_VERSION_NAME_OFFSET 3
40#define SMEM_IMAGE_VERSION_VARIANT_SIZE 20
41#define SMEM_IMAGE_VERSION_VARIANT_OFFSET 75
42#define SMEM_IMAGE_VERSION_OEM_SIZE 32
43#define SMEM_IMAGE_VERSION_OEM_OFFSET 96
Yulian Shandorov4c2d6c62013-10-09 06:51:36 -070044#define SMEM_IMAGE_VERSION_PARTITION_APPS 10
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070045
46enum {
47 HW_PLATFORM_UNKNOWN = 0,
48 HW_PLATFORM_SURF = 1,
49 HW_PLATFORM_FFA = 2,
50 HW_PLATFORM_FLUID = 3,
51 HW_PLATFORM_SVLTE_FFA = 4,
52 HW_PLATFORM_SVLTE_SURF = 5,
Jin Hong49753322011-12-15 16:55:37 -080053 HW_PLATFORM_MTP = 8,
Amir Samuelov1b0dc312011-11-17 20:43:33 +020054 HW_PLATFORM_LIQUID = 9,
Zhang Chang Ken59004eb2011-08-08 09:06:58 -040055 /* Dragonboard platform id is assigned as 10 in CDT */
56 HW_PLATFORM_DRAGON = 10,
David Ng32dfa3c2013-03-19 16:55:54 -070057 HW_PLATFORM_QRD = 11,
ChandraMouli Bothsaeae28bb2012-09-20 09:57:37 +053058 HW_PLATFORM_HRD = 13,
59 HW_PLATFORM_DTV = 14,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070060 HW_PLATFORM_INVALID
61};
62
63const char *hw_platform[] = {
64 [HW_PLATFORM_UNKNOWN] = "Unknown",
65 [HW_PLATFORM_SURF] = "Surf",
66 [HW_PLATFORM_FFA] = "FFA",
67 [HW_PLATFORM_FLUID] = "Fluid",
68 [HW_PLATFORM_SVLTE_FFA] = "SVLTE_FFA",
Zhang Chang Kenef05b172011-07-27 15:28:13 -040069 [HW_PLATFORM_SVLTE_SURF] = "SLVTE_SURF",
Jin Hong49753322011-12-15 16:55:37 -080070 [HW_PLATFORM_MTP] = "MTP",
71 [HW_PLATFORM_LIQUID] = "Liquid",
ChandraMouli Bothsaeae28bb2012-09-20 09:57:37 +053072 [HW_PLATFORM_DRAGON] = "Dragon",
David Ng32dfa3c2013-03-19 16:55:54 -070073 [HW_PLATFORM_QRD] = "QRD",
ChandraMouli Bothsaeae28bb2012-09-20 09:57:37 +053074 [HW_PLATFORM_HRD] = "HRD",
75 [HW_PLATFORM_DTV] = "DTV",
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070076};
77
78enum {
79 ACCESSORY_CHIP_UNKNOWN = 0,
80 ACCESSORY_CHIP_CHARM = 58,
81};
82
83enum {
Maria Yu0b563c22013-06-07 20:24:09 +080084 PLATFORM_SUBTYPE_QRD = 0x0,
85 PLATFORM_SUBTYPE_SKUAA = 0x1,
86 PLATFORM_SUBTYPE_SKUF = 0x2,
87 PLATFORM_SUBTYPE_SKUAB = 0x3,
Jie Cheng04ad8302013-08-01 16:17:54 +080088 PLATFORM_SUBTYPE_SKUG = 0x5,
Maria Yu0b563c22013-06-07 20:24:09 +080089 PLATFORM_SUBTYPE_QRD_INVALID,
90};
91
92const char *qrd_hw_platform_subtype[] = {
93 [PLATFORM_SUBTYPE_QRD] = "QRD",
94 [PLATFORM_SUBTYPE_SKUAA] = "SKUAA",
95 [PLATFORM_SUBTYPE_SKUF] = "SKUF",
96 [PLATFORM_SUBTYPE_SKUAB] = "SKUAB",
Jie Cheng04ad8302013-08-01 16:17:54 +080097 [PLATFORM_SUBTYPE_SKUG] = "SKUG",
Maria Yu8ac65722013-08-20 16:43:51 +080098 [PLATFORM_SUBTYPE_QRD_INVALID] = "INVALID",
Maria Yu0b563c22013-06-07 20:24:09 +080099};
100
101enum {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700102 PLATFORM_SUBTYPE_UNKNOWN = 0x0,
103 PLATFORM_SUBTYPE_CHARM = 0x1,
104 PLATFORM_SUBTYPE_STRANGE = 0x2,
105 PLATFORM_SUBTYPE_STRANGE_2A = 0x3,
106 PLATFORM_SUBTYPE_INVALID,
107};
108
109const char *hw_platform_subtype[] = {
110 [PLATFORM_SUBTYPE_UNKNOWN] = "Unknown",
111 [PLATFORM_SUBTYPE_CHARM] = "charm",
112 [PLATFORM_SUBTYPE_STRANGE] = "strange",
113 [PLATFORM_SUBTYPE_STRANGE_2A] = "strange_2a,"
114};
115
116/* Used to parse shared memory. Must match the modem. */
117struct socinfo_v1 {
118 uint32_t format;
119 uint32_t id;
120 uint32_t version;
121 char build_id[BUILD_ID_LENGTH];
122};
123
124struct socinfo_v2 {
125 struct socinfo_v1 v1;
126
127 /* only valid when format==2 */
128 uint32_t raw_id;
129 uint32_t raw_version;
130};
131
132struct socinfo_v3 {
133 struct socinfo_v2 v2;
134
135 /* only valid when format==3 */
136 uint32_t hw_platform;
137};
138
139struct socinfo_v4 {
140 struct socinfo_v3 v3;
141
142 /* only valid when format==4 */
143 uint32_t platform_version;
144};
145
146struct socinfo_v5 {
147 struct socinfo_v4 v4;
148
149 /* only valid when format==5 */
150 uint32_t accessory_chip;
151};
152
153struct socinfo_v6 {
154 struct socinfo_v5 v5;
155
156 /* only valid when format==6 */
157 uint32_t hw_platform_subtype;
158};
159
Jin Hong9b556c32012-08-13 23:06:26 -0700160struct socinfo_v7 {
161 struct socinfo_v6 v6;
162
163 /* only valid when format==7 */
164 uint32_t pmic_model;
165 uint32_t pmic_die_revision;
166};
167
Abhimanyu Kapur781c03d2013-02-21 16:20:23 -0800168struct socinfo_v8 {
169 struct socinfo_v7 v7;
170
171 /* only valid when format==8*/
172 uint32_t pmic_model_1;
173 uint32_t pmic_die_revision_1;
174 uint32_t pmic_model_2;
175 uint32_t pmic_die_revision_2;
176};
177
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700178static union {
179 struct socinfo_v1 v1;
180 struct socinfo_v2 v2;
181 struct socinfo_v3 v3;
182 struct socinfo_v4 v4;
183 struct socinfo_v5 v5;
184 struct socinfo_v6 v6;
Jin Hong9b556c32012-08-13 23:06:26 -0700185 struct socinfo_v7 v7;
Abhimanyu Kapur781c03d2013-02-21 16:20:23 -0800186 struct socinfo_v8 v8;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700187} *socinfo;
188
189static enum msm_cpu cpu_of_id[] = {
190
191 /* 7x01 IDs */
192 [1] = MSM_CPU_7X01,
193 [16] = MSM_CPU_7X01,
194 [17] = MSM_CPU_7X01,
195 [18] = MSM_CPU_7X01,
196 [19] = MSM_CPU_7X01,
197 [23] = MSM_CPU_7X01,
198 [25] = MSM_CPU_7X01,
199 [26] = MSM_CPU_7X01,
200 [32] = MSM_CPU_7X01,
201 [33] = MSM_CPU_7X01,
202 [34] = MSM_CPU_7X01,
203 [35] = MSM_CPU_7X01,
204
205 /* 7x25 IDs */
206 [20] = MSM_CPU_7X25,
207 [21] = MSM_CPU_7X25, /* 7225 */
208 [24] = MSM_CPU_7X25, /* 7525 */
209 [27] = MSM_CPU_7X25, /* 7625 */
210 [39] = MSM_CPU_7X25,
211 [40] = MSM_CPU_7X25,
212 [41] = MSM_CPU_7X25,
213 [42] = MSM_CPU_7X25,
214 [62] = MSM_CPU_7X25, /* 7625-1 */
215 [63] = MSM_CPU_7X25, /* 7225-1 */
216 [66] = MSM_CPU_7X25, /* 7225-2 */
217
218
219 /* 7x27 IDs */
220 [43] = MSM_CPU_7X27,
221 [44] = MSM_CPU_7X27,
222 [61] = MSM_CPU_7X27,
223 [67] = MSM_CPU_7X27, /* 7227-1 */
224 [68] = MSM_CPU_7X27, /* 7627-1 */
225 [69] = MSM_CPU_7X27, /* 7627-2 */
226
227
228 /* 8x50 IDs */
229 [30] = MSM_CPU_8X50,
230 [36] = MSM_CPU_8X50,
231 [37] = MSM_CPU_8X50,
232 [38] = MSM_CPU_8X50,
233
234 /* 7x30 IDs */
235 [59] = MSM_CPU_7X30,
236 [60] = MSM_CPU_7X30,
237
238 /* 8x55 IDs */
239 [74] = MSM_CPU_8X55,
240 [75] = MSM_CPU_8X55,
241 [85] = MSM_CPU_8X55,
242
243 /* 8x60 IDs */
244 [70] = MSM_CPU_8X60,
245 [71] = MSM_CPU_8X60,
246 [86] = MSM_CPU_8X60,
247
248 /* 8960 IDs */
249 [87] = MSM_CPU_8960,
250
251 /* 7x25A IDs */
252 [88] = MSM_CPU_7X25A,
253 [89] = MSM_CPU_7X25A,
254 [96] = MSM_CPU_7X25A,
255
256 /* 7x27A IDs */
257 [90] = MSM_CPU_7X27A,
258 [91] = MSM_CPU_7X27A,
259 [92] = MSM_CPU_7X27A,
260 [97] = MSM_CPU_7X27A,
261
262 /* FSM9xxx ID */
263 [94] = FSM_CPU_9XXX,
264 [95] = FSM_CPU_9XXX,
265
266 /* 7x25AA ID */
267 [98] = MSM_CPU_7X25AA,
268 [99] = MSM_CPU_7X25AA,
269 [100] = MSM_CPU_7X25AA,
270
Joel Kingbf2ff512011-07-22 13:43:11 -0700271 /* 7x27AA ID */
272 [101] = MSM_CPU_7X27AA,
273 [102] = MSM_CPU_7X27AA,
274 [103] = MSM_CPU_7X27AA,
Kaushal Kumardc0beb92012-06-29 19:31:05 +0530275 [136] = MSM_CPU_7X27AA,
Joel Kingbf2ff512011-07-22 13:43:11 -0700276
Rohit Vaswani8a28b4a2011-08-10 19:07:00 -0700277 /* 9x15 ID */
278 [104] = MSM_CPU_9615,
Rohit Vaswani865f2ca2011-10-03 17:40:42 -0700279 [105] = MSM_CPU_9615,
Rohit Vaswani7a83fa92012-01-11 15:05:39 -0800280 [106] = MSM_CPU_9615,
281 [107] = MSM_CPU_9615,
Abhimanyu Kapur45149122013-03-20 01:07:52 -0700282 [171] = MSM_CPU_9615,
Rohit Vaswani8a28b4a2011-08-10 19:07:00 -0700283
Stepan Moskovchenkoa8f0a222011-10-24 18:53:17 -0700284 /* 8064 IDs */
Joel Kingbf2ff512011-07-22 13:43:11 -0700285 [109] = MSM_CPU_8064,
286
Stepan Moskovchenkoa8f0a222011-10-24 18:53:17 -0700287 /* 8930 IDs */
288 [116] = MSM_CPU_8930,
Stepan Moskovchenkodb71cd62011-11-23 14:28:57 -0800289 [117] = MSM_CPU_8930,
290 [118] = MSM_CPU_8930,
291 [119] = MSM_CPU_8930,
David Ngc103f1c2013-02-12 18:49:25 -0800292 [179] = MSM_CPU_8930,
Stepan Moskovchenkodb71cd62011-11-23 14:28:57 -0800293
294 /* 8627 IDs */
295 [120] = MSM_CPU_8627,
296 [121] = MSM_CPU_8627,
Stepan Moskovchenkoa8f0a222011-10-24 18:53:17 -0700297
Jin Hong0698b562011-11-05 13:57:25 -0700298 /* 8660A ID */
299 [122] = MSM_CPU_8960,
300
301 /* 8260A ID */
302 [123] = MSM_CPU_8960,
303
304 /* 8060A ID */
305 [124] = MSM_CPU_8960,
306
Abhimanyu Kapur90ced6e2012-06-26 17:41:25 -0700307 /* 8974 IDs */
308 [126] = MSM_CPU_8974,
Stepan Moskovchenko22dce832013-03-25 14:36:52 -0700309 [184] = MSM_CPU_8974,
Stepan Moskovchenko2f06d832013-05-06 12:52:32 -0700310 [185] = MSM_CPU_8974,
311 [186] = MSM_CPU_8974,
Sathish Ambleya99d6852011-10-31 15:50:55 -0700312
Stepan Moskovchenko015c4982013-05-06 12:52:32 -0700313 /* 8974AA IDs */
314 [208] = MSM_CPU_8974PRO_AA,
315 [211] = MSM_CPU_8974PRO_AA,
316 [214] = MSM_CPU_8974PRO_AA,
317 [217] = MSM_CPU_8974PRO_AA,
318
319 /* 8974AB IDs */
320 [209] = MSM_CPU_8974PRO_AB,
321 [212] = MSM_CPU_8974PRO_AB,
322 [215] = MSM_CPU_8974PRO_AB,
323 [218] = MSM_CPU_8974PRO_AB,
324
325 /* 8974AC IDs */
326 [194] = MSM_CPU_8974PRO_AC,
327 [210] = MSM_CPU_8974PRO_AC,
328 [213] = MSM_CPU_8974PRO_AC,
329 [216] = MSM_CPU_8974PRO_AC,
330
Taniya Dasa04e1892011-11-16 14:49:12 +0530331 /* 8625 IDs */
332 [127] = MSM_CPU_8625,
333 [128] = MSM_CPU_8625,
334 [129] = MSM_CPU_8625,
Kaushal Kumar1f8876a2012-08-21 14:53:50 +0530335 [137] = MSM_CPU_8625,
Kaushal Kumarc84b9c22012-10-12 12:47:55 +0530336 [167] = MSM_CPU_8625,
Taniya Dasa04e1892011-11-16 14:49:12 +0530337
Joel King8e0bf672012-05-18 15:40:40 -0700338 /* 8064 MPQ ID */
339 [130] = MSM_CPU_8064,
Rohit Vaswani47ee9e92012-04-23 18:42:03 -0700340
Pankaj Kumarfee56a82012-04-17 14:26:49 +0530341 /* 7x25AB IDs */
342 [131] = MSM_CPU_7X25AB,
343 [132] = MSM_CPU_7X25AB,
344 [133] = MSM_CPU_7X25AB,
Kaushal Kumardc0beb92012-06-29 19:31:05 +0530345 [135] = MSM_CPU_7X25AB,
Pankaj Kumarfee56a82012-04-17 14:26:49 +0530346
Joel King8e0bf672012-05-18 15:40:40 -0700347 /* 9625 IDs */
348 [134] = MSM_CPU_9625,
Abhimanyu Kapur430add82013-01-28 13:51:01 -0800349 [148] = MSM_CPU_9625,
Abhimanyu Kapur0e088bb2013-01-08 18:41:17 -0800350 [149] = MSM_CPU_9625,
351 [150] = MSM_CPU_9625,
Abhimanyu Kapur430add82013-01-28 13:51:01 -0800352 [151] = MSM_CPU_9625,
353 [152] = MSM_CPU_9625,
354 [173] = MSM_CPU_9625,
355 [174] = MSM_CPU_9625,
356 [175] = MSM_CPU_9625,
Joel King8e0bf672012-05-18 15:40:40 -0700357
Stepan Moskovchenkoec6a8032012-07-06 15:42:01 -0700358 /* 8960AB IDs */
359 [138] = MSM_CPU_8960AB,
360 [139] = MSM_CPU_8960AB,
361 [140] = MSM_CPU_8960AB,
362 [141] = MSM_CPU_8960AB,
363
Stepan Moskovchenko8f362fe2012-07-12 19:19:52 -0700364 /* 8930AA IDs */
Stepan Moskovchenko8b38bb32012-07-06 16:57:34 -0700365 [142] = MSM_CPU_8930AA,
Stepan Moskovchenko8f362fe2012-07-12 19:19:52 -0700366 [143] = MSM_CPU_8930AA,
367 [144] = MSM_CPU_8930AA,
Stepan Moskovchenko9e83cb92012-10-22 18:52:06 -0700368 [160] = MSM_CPU_8930AA,
David Ngc103f1c2013-02-12 18:49:25 -0800369 [180] = MSM_CPU_8930AA,
Stepan Moskovchenko8b38bb32012-07-06 16:57:34 -0700370
Syed Rameez Mustafad6084d32012-08-23 15:47:50 -0700371 /* 8226 IDs */
372 [145] = MSM_CPU_8226,
Stepan Moskovchenkof5c55ae2013-05-06 12:52:32 -0700373 [158] = MSM_CPU_8226,
374 [159] = MSM_CPU_8226,
375 [198] = MSM_CPU_8226,
Syed Rameez Mustafabd714672013-05-20 15:19:37 -0700376 [199] = MSM_CPU_8226,
377 [200] = MSM_CPU_8226,
378 [205] = MSM_CPU_8226,
Syed Rameez Mustafa7e2d7252013-08-28 19:52:13 -0700379 [219] = MSM_CPU_8226,
380 [220] = MSM_CPU_8226,
381 [221] = MSM_CPU_8226,
382 [222] = MSM_CPU_8226,
383 [223] = MSM_CPU_8226,
384 [224] = MSM_CPU_8226,
Syed Rameez Mustafad6084d32012-08-23 15:47:50 -0700385
Ravi Kumar V754282d2012-08-31 22:32:20 +0530386 /* 8092 IDs */
387 [146] = MSM_CPU_8092,
388
Syed Rameez Mustafa3971c142013-01-09 19:04:53 -0800389 /* 8610 IDs */
390 [147] = MSM_CPU_8610,
Abhimanyu Kapur35bc0842013-04-19 20:02:58 -0700391 [161] = MSM_CPU_8610,
392 [162] = MSM_CPU_8610,
393 [163] = MSM_CPU_8610,
394 [164] = MSM_CPU_8610,
David Nge7b76b82013-04-10 14:59:52 -0700395 [165] = MSM_CPU_8610,
Abhimanyu Kapur35bc0842013-04-19 20:02:58 -0700396 [166] = MSM_CPU_8610,
Syed Rameez Mustafa158d6682012-09-21 18:25:50 -0700397
Jay Chokshib2de5092012-09-19 18:28:12 -0700398 /* 8064AB IDs */
399 [153] = MSM_CPU_8064AB,
400
Stepan Moskovchenkoa03e7612012-10-16 18:34:17 -0700401 /* 8930AB IDs */
402 [154] = MSM_CPU_8930AB,
403 [155] = MSM_CPU_8930AB,
404 [156] = MSM_CPU_8930AB,
Utsab Bose89b32992012-11-08 11:15:45 +0530405 [157] = MSM_CPU_8930AB,
David Ngc103f1c2013-02-12 18:49:25 -0800406 [181] = MSM_CPU_8930AB,
Utsab Bose89b32992012-11-08 11:15:45 +0530407
408 /* 8625Q IDs */
409 [168] = MSM_CPU_8625Q,
410 [169] = MSM_CPU_8625Q,
411 [170] = MSM_CPU_8625Q,
412
Jay Chokshif9294742013-01-15 13:06:27 -0800413 /* 8064AA IDs */
414 [172] = MSM_CPU_8064AA,
Stepan Moskovchenkoa03e7612012-10-16 18:34:17 -0700415
Stepan Moskovchenkoe90cd652013-04-18 12:54:47 -0700416 /* 8084 IDs */
417 [178] = MSM_CPU_8084,
Stepan Moskovchenko55dfdc32013-01-24 15:48:23 -0800418
Abhimanyu Kapur37bea772013-04-11 18:19:38 -0700419 /* krypton IDs */
420 [187] = MSM_CPU_KRYPTON,
421
Rohit Vaswanic3df8b92013-03-20 19:11:15 -0700422 /* FSM9900 ID */
423 [188] = FSM_CPU_9900,
424
Jay Chokshieb3e8b62013-05-10 17:33:54 -0700425 /* Samarium IDs */
426 [195] = MSM_CPU_SAMARIUM,
427
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700428 /* Uninitialized IDs are not known to run Linux.
429 MSM_CPU_UNKNOWN is set to 0 to ensure these IDs are
430 considered as unknown CPU. */
431};
432
433static enum msm_cpu cur_cpu;
Yulian Shandoroved2265b2013-08-16 00:46:59 -0700434static int current_image;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700435
436static struct socinfo_v1 dummy_socinfo = {
437 .format = 1,
438 .version = 1,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700439};
440
441uint32_t socinfo_get_id(void)
442{
443 return (socinfo) ? socinfo->v1.id : 0;
444}
445EXPORT_SYMBOL_GPL(socinfo_get_id);
446
447uint32_t socinfo_get_version(void)
448{
449 return (socinfo) ? socinfo->v1.version : 0;
450}
451
452char *socinfo_get_build_id(void)
453{
454 return (socinfo) ? socinfo->v1.build_id : NULL;
455}
456
457uint32_t socinfo_get_raw_id(void)
458{
459 return socinfo ?
460 (socinfo->v1.format >= 2 ? socinfo->v2.raw_id : 0)
461 : 0;
462}
463
464uint32_t socinfo_get_raw_version(void)
465{
466 return socinfo ?
467 (socinfo->v1.format >= 2 ? socinfo->v2.raw_version : 0)
468 : 0;
469}
470
471uint32_t socinfo_get_platform_type(void)
472{
473 return socinfo ?
474 (socinfo->v1.format >= 3 ? socinfo->v3.hw_platform : 0)
475 : 0;
476}
477
478
479uint32_t socinfo_get_platform_version(void)
480{
481 return socinfo ?
482 (socinfo->v1.format >= 4 ? socinfo->v4.platform_version : 0)
483 : 0;
484}
485
486/* This information is directly encoded by the machine id */
487/* Thus no external callers rely on this information at the moment */
488static uint32_t socinfo_get_accessory_chip(void)
489{
490 return socinfo ?
491 (socinfo->v1.format >= 5 ? socinfo->v5.accessory_chip : 0)
492 : 0;
493}
494
495uint32_t socinfo_get_platform_subtype(void)
496{
497 return socinfo ?
498 (socinfo->v1.format >= 6 ? socinfo->v6.hw_platform_subtype : 0)
499 : 0;
500}
501
Jin Hong9b556c32012-08-13 23:06:26 -0700502enum pmic_model socinfo_get_pmic_model(void)
503{
504 return socinfo ?
505 (socinfo->v1.format >= 7 ? socinfo->v7.pmic_model
506 : PMIC_MODEL_UNKNOWN)
507 : PMIC_MODEL_UNKNOWN;
508}
509
510uint32_t socinfo_get_pmic_die_revision(void)
511{
512 return socinfo ?
513 (socinfo->v1.format >= 7 ? socinfo->v7.pmic_die_revision : 0)
514 : 0;
515}
516
Yulian Shandoroved2265b2013-08-16 00:46:59 -0700517static char *socinfo_get_image_version_base_address(void)
518{
519 return smem_alloc(SMEM_IMAGE_VERSION_TABLE, SMEM_IMAGE_VERSION_SIZE);
520}
521
Abhimanyu Kapur440cdde2012-12-04 00:05:40 -0800522static uint32_t socinfo_get_format(void)
523{
524 return socinfo ? socinfo->v1.format : 0;
525}
526
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700527enum msm_cpu socinfo_get_msm_cpu(void)
528{
529 return cur_cpu;
530}
531EXPORT_SYMBOL_GPL(socinfo_get_msm_cpu);
532
533static ssize_t
534socinfo_show_id(struct sys_device *dev,
535 struct sysdev_attribute *attr,
536 char *buf)
537{
538 if (!socinfo) {
539 pr_err("%s: No socinfo found!\n", __func__);
540 return 0;
541 }
542
543 return snprintf(buf, PAGE_SIZE, "%u\n", socinfo_get_id());
544}
545
546static ssize_t
547socinfo_show_version(struct sys_device *dev,
548 struct sysdev_attribute *attr,
549 char *buf)
550{
551 uint32_t version;
552
553 if (!socinfo) {
554 pr_err("%s: No socinfo found!\n", __func__);
555 return 0;
556 }
557
558 version = socinfo_get_version();
559 return snprintf(buf, PAGE_SIZE, "%u.%u\n",
560 SOCINFO_VERSION_MAJOR(version),
561 SOCINFO_VERSION_MINOR(version));
562}
563
564static ssize_t
565socinfo_show_build_id(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
574 return snprintf(buf, PAGE_SIZE, "%-.32s\n", socinfo_get_build_id());
575}
576
577static ssize_t
578socinfo_show_raw_id(struct sys_device *dev,
579 struct sysdev_attribute *attr,
580 char *buf)
581{
582 if (!socinfo) {
583 pr_err("%s: No socinfo found!\n", __func__);
584 return 0;
585 }
586 if (socinfo->v1.format < 2) {
587 pr_err("%s: Raw ID not available!\n", __func__);
588 return 0;
589 }
590
591 return snprintf(buf, PAGE_SIZE, "%u\n", socinfo_get_raw_id());
592}
593
594static ssize_t
595socinfo_show_raw_version(struct sys_device *dev,
596 struct sysdev_attribute *attr,
597 char *buf)
598{
599 if (!socinfo) {
600 pr_err("%s: No socinfo found!\n", __func__);
601 return 0;
602 }
603 if (socinfo->v1.format < 2) {
604 pr_err("%s: Raw version not available!\n", __func__);
605 return 0;
606 }
607
608 return snprintf(buf, PAGE_SIZE, "%u\n", socinfo_get_raw_version());
609}
610
611static ssize_t
612socinfo_show_platform_type(struct sys_device *dev,
613 struct sysdev_attribute *attr,
614 char *buf)
615{
616 uint32_t hw_type;
617
618 if (!socinfo) {
619 pr_err("%s: No socinfo found!\n", __func__);
620 return 0;
621 }
622 if (socinfo->v1.format < 3) {
623 pr_err("%s: platform type not available!\n", __func__);
624 return 0;
625 }
626
627 hw_type = socinfo_get_platform_type();
628 if (hw_type >= HW_PLATFORM_INVALID) {
629 pr_err("%s: Invalid hardware platform type found\n",
630 __func__);
631 hw_type = HW_PLATFORM_UNKNOWN;
632 }
633
634 return snprintf(buf, PAGE_SIZE, "%-.32s\n", hw_platform[hw_type]);
635}
636
637static ssize_t
638socinfo_show_platform_version(struct sys_device *dev,
639 struct sysdev_attribute *attr,
640 char *buf)
641{
642
643 if (!socinfo) {
644 pr_err("%s: No socinfo found!\n", __func__);
645 return 0;
646 }
647 if (socinfo->v1.format < 4) {
648 pr_err("%s: platform version not available!\n", __func__);
649 return 0;
650 }
651
652 return snprintf(buf, PAGE_SIZE, "%u\n",
653 socinfo_get_platform_version());
654}
655
656static ssize_t
657socinfo_show_accessory_chip(struct sys_device *dev,
658 struct sysdev_attribute *attr,
659 char *buf)
660{
661 if (!socinfo) {
662 pr_err("%s: No socinfo found!\n", __func__);
663 return 0;
664 }
665 if (socinfo->v1.format < 5) {
666 pr_err("%s: accessory chip not available!\n", __func__);
667 return 0;
668 }
669
670 return snprintf(buf, PAGE_SIZE, "%u\n",
671 socinfo_get_accessory_chip());
672}
673
674static ssize_t
675socinfo_show_platform_subtype(struct sys_device *dev,
676 struct sysdev_attribute *attr,
677 char *buf)
678{
679 uint32_t hw_subtype;
680 if (!socinfo) {
681 pr_err("%s: No socinfo found!\n", __func__);
682 return 0;
683 }
684 if (socinfo->v1.format < 6) {
685 pr_err("%s: platform subtype not available!\n", __func__);
686 return 0;
687 }
688
689 hw_subtype = socinfo_get_platform_subtype();
Maria Yu0b563c22013-06-07 20:24:09 +0800690 if (HW_PLATFORM_QRD == socinfo_get_platform_type()) {
691 if (hw_subtype >= PLATFORM_SUBTYPE_QRD_INVALID) {
692 pr_err("%s: Invalid hardware platform sub type for qrd found\n",
693 __func__);
Maria Yu8ac65722013-08-20 16:43:51 +0800694 hw_subtype = PLATFORM_SUBTYPE_QRD_INVALID;
Maria Yu0b563c22013-06-07 20:24:09 +0800695 }
696 return snprintf(buf, PAGE_SIZE, "%-.32s\n",
697 qrd_hw_platform_subtype[hw_subtype]);
698 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700699 if (hw_subtype >= PLATFORM_SUBTYPE_INVALID) {
700 pr_err("%s: Invalid hardware platform sub type found\n",
Maria Yu0b563c22013-06-07 20:24:09 +0800701 __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700702 hw_subtype = PLATFORM_SUBTYPE_UNKNOWN;
703 }
704 return snprintf(buf, PAGE_SIZE, "%-.32s\n",
705 hw_platform_subtype[hw_subtype]);
706}
707
Jin Hong9b556c32012-08-13 23:06:26 -0700708static ssize_t
709socinfo_show_pmic_model(struct sys_device *dev,
710 struct sysdev_attribute *attr,
711 char *buf)
712{
713 if (!socinfo) {
714 pr_err("%s: No socinfo found!\n", __func__);
715 return 0;
716 }
717 if (socinfo->v1.format < 7) {
718 pr_err("%s: pmic_model not available!\n", __func__);
719 return 0;
720 }
721
722 return snprintf(buf, PAGE_SIZE, "%u\n",
723 socinfo_get_pmic_model());
724}
725
726static ssize_t
727socinfo_show_pmic_die_revision(struct sys_device *dev,
728 struct sysdev_attribute *attr,
729 char *buf)
730{
731 if (!socinfo) {
732 pr_err("%s: No socinfo found!\n", __func__);
733 return 0;
734 }
735 if (socinfo->v1.format < 7) {
736 pr_err("%s: pmic_die_revision not available!\n", __func__);
737 return 0;
738 }
739
740 return snprintf(buf, PAGE_SIZE, "%u\n",
741 socinfo_get_pmic_die_revision());
742}
743
Abhimanyu Kapur440cdde2012-12-04 00:05:40 -0800744static 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 hw_type = socinfo_get_platform_type();
786
787 return snprintf(buf, PAGE_SIZE, "%-.32s\n",
788 hw_platform[hw_type]);
789}
790
791static ssize_t
792msm_get_platform_version(struct device *dev,
793 struct device_attribute *attr,
794 char *buf)
795{
796 return snprintf(buf, PAGE_SIZE, "%u\n",
797 socinfo_get_platform_version());
798}
799
800static ssize_t
801msm_get_accessory_chip(struct device *dev,
802 struct device_attribute *attr,
803 char *buf)
804{
805 return snprintf(buf, PAGE_SIZE, "%u\n",
806 socinfo_get_accessory_chip());
807}
808
809static ssize_t
810msm_get_platform_subtype(struct device *dev,
811 struct device_attribute *attr,
812 char *buf)
813{
814 uint32_t hw_subtype;
815 hw_subtype = socinfo_get_platform_subtype();
Maria Yu8ac65722013-08-20 16:43:51 +0800816 if (HW_PLATFORM_QRD == socinfo_get_platform_type()) {
817 if (hw_subtype >= PLATFORM_SUBTYPE_QRD_INVALID) {
818 pr_err("%s: Invalid hardware platform sub type for qrd found\n",
819 __func__);
820 hw_subtype = PLATFORM_SUBTYPE_QRD_INVALID;
821 }
822 return snprintf(buf, PAGE_SIZE, "%-.32s\n",
823 qrd_hw_platform_subtype[hw_subtype]);
824 }
825
Abhimanyu Kapur440cdde2012-12-04 00:05:40 -0800826 return snprintf(buf, PAGE_SIZE, "%-.32s\n",
827 hw_platform_subtype[hw_subtype]);
828}
829
830static ssize_t
831msm_get_pmic_model(struct device *dev,
832 struct device_attribute *attr,
833 char *buf)
834{
835 return snprintf(buf, PAGE_SIZE, "%u\n",
836 socinfo_get_pmic_model());
837}
838
839static ssize_t
840msm_get_pmic_die_revision(struct device *dev,
841 struct device_attribute *attr,
842 char *buf)
843{
844 return snprintf(buf, PAGE_SIZE, "%u\n",
845 socinfo_get_pmic_die_revision());
846}
847
Yulian Shandoroved2265b2013-08-16 00:46:59 -0700848static ssize_t
849msm_get_image_version(struct device *dev,
850 struct device_attribute *attr,
851 char *buf)
852{
853 char *string_address;
854
855 string_address = socinfo_get_image_version_base_address();
856 if (string_address == NULL) {
857 pr_err("%s : Failed to get image version base address",
858 __func__);
859 return snprintf(buf, SMEM_IMAGE_VERSION_NAME_SIZE, "Unknown");
860 }
861 string_address += current_image * SMEM_IMAGE_VERSION_SINGLE_BLOCK_SIZE;
862 string_address += SMEM_IMAGE_VERSION_NAME_OFFSET;
Yulian Shandorov4c2d6c62013-10-09 06:51:36 -0700863 return snprintf(buf, SMEM_IMAGE_VERSION_NAME_SIZE, "%-.72s\n",
Yulian Shandoroved2265b2013-08-16 00:46:59 -0700864 string_address);
865}
866
867static ssize_t
Yulian Shandorov4c2d6c62013-10-09 06:51:36 -0700868msm_set_image_version(struct device *dev,
869 struct device_attribute *attr,
870 const char *buf,
871 size_t count)
Yulian Shandoroved2265b2013-08-16 00:46:59 -0700872{
Yulian Shandorov4c2d6c62013-10-09 06:51:36 -0700873 char *store_address;
Yulian Shandoroved2265b2013-08-16 00:46:59 -0700874
Yulian Shandorov4c2d6c62013-10-09 06:51:36 -0700875 if (current_image != SMEM_IMAGE_VERSION_PARTITION_APPS)
876 return count;
877 store_address = socinfo_get_image_version_base_address();
878 if (store_address == NULL) {
879 pr_err("%s : Failed to get image version base address",
880 __func__);
881 return count;
882 }
883 store_address += current_image * SMEM_IMAGE_VERSION_SINGLE_BLOCK_SIZE;
884 snprintf(store_address, SMEM_IMAGE_VERSION_NAME_SIZE, "%-.75s", buf);
Yulian Shandoroved2265b2013-08-16 00:46:59 -0700885 return count;
886}
887
888static ssize_t
889msm_get_image_variant(struct device *dev,
890 struct device_attribute *attr,
891 char *buf)
892{
893 char *string_address;
894
895 string_address = socinfo_get_image_version_base_address();
896 if (string_address == NULL) {
897 pr_err("%s : Failed to get image version base address",
898 __func__);
899 return snprintf(buf, SMEM_IMAGE_VERSION_VARIANT_SIZE,
900 "Unknown");
901 }
902 string_address += current_image * SMEM_IMAGE_VERSION_SINGLE_BLOCK_SIZE;
903 string_address += SMEM_IMAGE_VERSION_VARIANT_OFFSET;
Yulian Shandorov4c2d6c62013-10-09 06:51:36 -0700904 return snprintf(buf, SMEM_IMAGE_VERSION_VARIANT_SIZE, "%-.20s\n",
Yulian Shandoroved2265b2013-08-16 00:46:59 -0700905 string_address);
906}
907
908static ssize_t
Yulian Shandorov4c2d6c62013-10-09 06:51:36 -0700909msm_set_image_variant(struct device *dev,
910 struct device_attribute *attr,
911 const char *buf,
912 size_t count)
913{
914 char *store_address;
915
916 if (current_image != SMEM_IMAGE_VERSION_PARTITION_APPS)
917 return count;
918 store_address = socinfo_get_image_version_base_address();
919 if (store_address == NULL) {
920 pr_err("%s : Failed to get image version base address",
921 __func__);
922 return count;
923 }
924 store_address += current_image * SMEM_IMAGE_VERSION_SINGLE_BLOCK_SIZE;
925 store_address += SMEM_IMAGE_VERSION_VARIANT_OFFSET;
926 snprintf(store_address, SMEM_IMAGE_VERSION_VARIANT_SIZE, "%-.20s", buf);
927 return count;
928}
929
930static ssize_t
Yulian Shandoroved2265b2013-08-16 00:46:59 -0700931msm_get_image_crm_version(struct device *dev,
932 struct device_attribute *attr,
933 char *buf)
934{
935 char *string_address;
936
937 string_address = socinfo_get_image_version_base_address();
938 if (string_address == NULL) {
939 pr_err("%s : Failed to get image version base address",
940 __func__);
941 return snprintf(buf, SMEM_IMAGE_VERSION_OEM_SIZE, "Unknown");
942 }
943 string_address += current_image * SMEM_IMAGE_VERSION_SINGLE_BLOCK_SIZE;
944 string_address += SMEM_IMAGE_VERSION_OEM_OFFSET;
945 return snprintf(buf, SMEM_IMAGE_VERSION_OEM_SIZE, "%-.32s\n",
946 string_address);
947}
948
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700949static struct sysdev_attribute socinfo_v1_files[] = {
950 _SYSDEV_ATTR(id, 0444, socinfo_show_id, NULL),
951 _SYSDEV_ATTR(version, 0444, socinfo_show_version, NULL),
952 _SYSDEV_ATTR(build_id, 0444, socinfo_show_build_id, NULL),
953};
954
955static struct sysdev_attribute socinfo_v2_files[] = {
956 _SYSDEV_ATTR(raw_id, 0444, socinfo_show_raw_id, NULL),
957 _SYSDEV_ATTR(raw_version, 0444, socinfo_show_raw_version, NULL),
958};
959
960static struct sysdev_attribute socinfo_v3_files[] = {
961 _SYSDEV_ATTR(hw_platform, 0444, socinfo_show_platform_type, NULL),
962};
963
964static struct sysdev_attribute socinfo_v4_files[] = {
965 _SYSDEV_ATTR(platform_version, 0444,
966 socinfo_show_platform_version, NULL),
967};
968
969static struct sysdev_attribute socinfo_v5_files[] = {
970 _SYSDEV_ATTR(accessory_chip, 0444,
971 socinfo_show_accessory_chip, NULL),
972};
973
974static struct sysdev_attribute socinfo_v6_files[] = {
975 _SYSDEV_ATTR(platform_subtype, 0444,
976 socinfo_show_platform_subtype, NULL),
977};
978
Jin Hong9b556c32012-08-13 23:06:26 -0700979static struct sysdev_attribute socinfo_v7_files[] = {
980 _SYSDEV_ATTR(pmic_model, 0444,
981 socinfo_show_pmic_model, NULL),
982 _SYSDEV_ATTR(pmic_die_revision, 0444,
983 socinfo_show_pmic_die_revision, NULL),
984};
985
Yulian Shandorov4c2d6c62013-10-09 06:51:36 -0700986static ssize_t
987msm_set_image_crm_version(struct device *dev,
988 struct device_attribute *attr,
989 const char *buf,
990 size_t count)
991{
992 char *store_address;
993
994 if (current_image != SMEM_IMAGE_VERSION_PARTITION_APPS)
995 return count;
996 store_address = socinfo_get_image_version_base_address();
997 if (store_address == NULL) {
998 pr_err("%s : Failed to get image version base address",
999 __func__);
1000 return count;
1001 }
1002 store_address += current_image * SMEM_IMAGE_VERSION_SINGLE_BLOCK_SIZE;
1003 store_address += SMEM_IMAGE_VERSION_OEM_OFFSET;
1004 snprintf(store_address, SMEM_IMAGE_VERSION_OEM_SIZE, "%-.32s", buf);
1005 return count;
1006}
1007
1008static ssize_t
1009msm_get_image_number(struct device *dev,
1010 struct device_attribute *attr,
1011 char *buf)
1012{
1013 return snprintf(buf, PAGE_SIZE, "%d\n",
1014 current_image);
1015}
1016
1017static ssize_t
1018msm_select_image(struct device *dev, struct device_attribute *attr,
1019 const char *buf, size_t count)
1020{
1021 int ret, digit;
1022
1023 ret = kstrtoint(buf, 10, &digit);
1024 if (ret)
1025 return ret;
1026 if (0 <= digit && digit < SMEM_IMAGE_VERSION_BLOCKS_COUNT)
1027 current_image = digit;
1028 else
1029 current_image = 0;
1030 return count;
1031}
1032
1033
Abhimanyu Kapur440cdde2012-12-04 00:05:40 -08001034static struct device_attribute msm_soc_attr_raw_version =
1035 __ATTR(raw_version, S_IRUGO, msm_get_raw_version, NULL);
1036
1037static struct device_attribute msm_soc_attr_raw_id =
1038 __ATTR(raw_id, S_IRUGO, msm_get_raw_id, NULL);
1039
1040static struct device_attribute msm_soc_attr_vendor =
1041 __ATTR(vendor, S_IRUGO, msm_get_vendor, NULL);
1042
1043static struct device_attribute msm_soc_attr_build_id =
1044 __ATTR(build_id, S_IRUGO, msm_get_build_id, NULL);
1045
1046static struct device_attribute msm_soc_attr_hw_platform =
1047 __ATTR(hw_platform, S_IRUGO, msm_get_hw_platform, NULL);
1048
1049
1050static struct device_attribute msm_soc_attr_platform_version =
1051 __ATTR(platform_version, S_IRUGO,
1052 msm_get_platform_version, NULL);
1053
1054static struct device_attribute msm_soc_attr_accessory_chip =
1055 __ATTR(accessory_chip, S_IRUGO,
1056 msm_get_accessory_chip, NULL);
1057
1058static struct device_attribute msm_soc_attr_platform_subtype =
1059 __ATTR(platform_subtype, S_IRUGO,
1060 msm_get_platform_subtype, NULL);
1061
1062static struct device_attribute msm_soc_attr_pmic_model =
1063 __ATTR(pmic_model, S_IRUGO,
1064 msm_get_pmic_model, NULL);
1065
1066static struct device_attribute msm_soc_attr_pmic_die_revision =
1067 __ATTR(pmic_die_revision, S_IRUGO,
1068 msm_get_pmic_die_revision, NULL);
1069
Yulian Shandoroved2265b2013-08-16 00:46:59 -07001070static struct device_attribute image_version =
1071 __ATTR(image_version, S_IRUGO | S_IWUSR,
Yulian Shandorov4c2d6c62013-10-09 06:51:36 -07001072 msm_get_image_version, msm_set_image_version);
Yulian Shandoroved2265b2013-08-16 00:46:59 -07001073
1074static struct device_attribute image_variant =
Yulian Shandorov4c2d6c62013-10-09 06:51:36 -07001075 __ATTR(image_variant, S_IRUGO | S_IWUSR,
1076 msm_get_image_variant, msm_set_image_variant);
Yulian Shandoroved2265b2013-08-16 00:46:59 -07001077
1078static struct device_attribute image_crm_version =
Yulian Shandorov4c2d6c62013-10-09 06:51:36 -07001079 __ATTR(image_crm_version, S_IRUGO | S_IWUSR,
1080 msm_get_image_crm_version, msm_set_image_crm_version);
1081
1082static struct device_attribute select_image =
1083 __ATTR(select_image, S_IRUGO | S_IWUGO,
1084 msm_get_image_number, msm_select_image);
Yulian Shandoroved2265b2013-08-16 00:46:59 -07001085
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001086static struct sysdev_class soc_sysdev_class = {
1087 .name = "soc",
1088};
1089
1090static struct sys_device soc_sys_device = {
1091 .id = 0,
1092 .cls = &soc_sysdev_class,
1093};
1094
1095static int __init socinfo_create_files(struct sys_device *dev,
1096 struct sysdev_attribute files[],
1097 int size)
1098{
1099 int i;
1100 for (i = 0; i < size; i++) {
1101 int err = sysdev_create_file(dev, &files[i]);
1102 if (err) {
1103 pr_err("%s: sysdev_create_file(%s)=%d\n",
1104 __func__, files[i].attr.name, err);
1105 return err;
1106 }
1107 }
1108 return 0;
1109}
1110
Stephen Boyd69a22e42012-02-22 09:16:07 -08001111static void * __init setup_dummy_socinfo(void)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001112{
Stepan Moskovchenko070a05d2013-04-02 18:07:17 -07001113 if (early_machine_is_mpq8092()) {
Ravi Kumar V754282d2012-08-31 22:32:20 +05301114 dummy_socinfo.id = 146;
1115 strlcpy(dummy_socinfo.build_id, "mpq8092 - ",
1116 sizeof(dummy_socinfo.build_id));
Stepan Moskovchenkoe90cd652013-04-18 12:54:47 -07001117 } else if (early_machine_is_apq8084()) {
Stepan Moskovchenkof07190a2013-01-24 15:48:49 -08001118 dummy_socinfo.id = 178;
Stepan Moskovchenkoe90cd652013-04-18 12:54:47 -07001119 strlcpy(dummy_socinfo.build_id, "apq8084 - ",
Stepan Moskovchenkof07190a2013-01-24 15:48:49 -08001120 sizeof(dummy_socinfo.build_id));
Abhimanyu Kapur37bea772013-04-11 18:19:38 -07001121 } else if (early_machine_is_msmkrypton()) {
1122 dummy_socinfo.id = 187;
1123 strlcpy(dummy_socinfo.build_id, "msmkrypton - ",
1124 sizeof(dummy_socinfo.build_id));
Jay Chokshieb3e8b62013-05-10 17:33:54 -07001125 } else if (early_machine_is_msmsamarium()) {
1126 dummy_socinfo.id = 195;
1127 strlcpy(dummy_socinfo.build_id, "msmsamarium - ",
1128 sizeof(dummy_socinfo.build_id));
Ravi Kumar V754282d2012-08-31 22:32:20 +05301129 }
Sathish Ambley3e265ce2012-03-08 16:44:04 -08001130 strlcat(dummy_socinfo.build_id, "Dummy socinfo",
1131 sizeof(dummy_socinfo.build_id));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001132 return (void *) &dummy_socinfo;
1133}
1134
Abhimanyu Kapur440cdde2012-12-04 00:05:40 -08001135static void __init populate_soc_sysfs_files(struct device *msm_soc_device)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001136{
Abhimanyu Kapur440cdde2012-12-04 00:05:40 -08001137 uint32_t legacy_format = socinfo_get_format();
Jin Hong9b556c32012-08-13 23:06:26 -07001138
Abhimanyu Kapur440cdde2012-12-04 00:05:40 -08001139 device_create_file(msm_soc_device, &msm_soc_attr_vendor);
Yulian Shandoroved2265b2013-08-16 00:46:59 -07001140 device_create_file(msm_soc_device, &image_version);
1141 device_create_file(msm_soc_device, &image_variant);
1142 device_create_file(msm_soc_device, &image_crm_version);
Yulian Shandorov4c2d6c62013-10-09 06:51:36 -07001143 device_create_file(msm_soc_device, &select_image);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001144
Abhimanyu Kapur440cdde2012-12-04 00:05:40 -08001145 switch (legacy_format) {
Abhimanyu Kapur781c03d2013-02-21 16:20:23 -08001146 case 8:
Abhimanyu Kapur440cdde2012-12-04 00:05:40 -08001147 case 7:
1148 device_create_file(msm_soc_device,
1149 &msm_soc_attr_pmic_model);
1150 device_create_file(msm_soc_device,
1151 &msm_soc_attr_pmic_die_revision);
1152 case 6:
1153 device_create_file(msm_soc_device,
1154 &msm_soc_attr_platform_subtype);
1155 case 5:
1156 device_create_file(msm_soc_device,
1157 &msm_soc_attr_accessory_chip);
1158 case 4:
1159 device_create_file(msm_soc_device,
1160 &msm_soc_attr_platform_version);
1161 case 3:
1162 device_create_file(msm_soc_device,
1163 &msm_soc_attr_hw_platform);
1164 case 2:
1165 device_create_file(msm_soc_device,
1166 &msm_soc_attr_raw_id);
1167 device_create_file(msm_soc_device,
1168 &msm_soc_attr_raw_version);
1169 case 1:
1170 device_create_file(msm_soc_device,
1171 &msm_soc_attr_build_id);
1172 break;
1173 default:
1174 pr_err("%s:Unknown socinfo format:%u\n", __func__,
1175 legacy_format);
1176 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001177 }
1178
Abhimanyu Kapur440cdde2012-12-04 00:05:40 -08001179 return;
1180}
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001181
Abhimanyu Kapur440cdde2012-12-04 00:05:40 -08001182static void __init soc_info_populate(struct soc_device_attribute *soc_dev_attr)
1183{
1184 uint32_t soc_version = socinfo_get_version();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001185
Abhimanyu Kapur440cdde2012-12-04 00:05:40 -08001186 soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "%d", socinfo_get_id());
1187 soc_dev_attr->machine = "Snapdragon";
1188 soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%u.%u",
1189 SOCINFO_VERSION_MAJOR(soc_version),
1190 SOCINFO_VERSION_MINOR(soc_version));
1191 return;
1192
1193}
1194
Abhimanyu Kapur91a0a502013-01-11 19:24:59 -08001195static int __init socinfo_init_sysdev(void)
1196{
1197 int err;
1198 struct device *msm_soc_device;
1199 struct soc_device *soc_dev;
1200 struct soc_device_attribute *soc_dev_attr;
1201
1202 if (!socinfo) {
1203 pr_err("%s: No socinfo found!\n", __func__);
1204 return -ENODEV;
1205 }
1206
1207 soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
1208 if (!soc_dev_attr) {
1209 pr_err("%s: Soc Device alloc failed!\n", __func__);
1210 return -ENOMEM;
1211 }
1212
1213 soc_info_populate(soc_dev_attr);
1214 soc_dev = soc_device_register(soc_dev_attr);
1215 if (IS_ERR_OR_NULL(soc_dev)) {
1216 kfree(soc_dev_attr);
1217 pr_err("%s: Soc device register failed\n", __func__);
1218 return -EIO;
1219 }
1220
1221 msm_soc_device = soc_device_to_device(soc_dev);
1222 populate_soc_sysfs_files(msm_soc_device);
Syed Rameez Mustafae81dc932013-10-16 13:52:58 -07001223
Abhimanyu Kapur91a0a502013-01-11 19:24:59 -08001224 err = sysdev_class_register(&soc_sysdev_class);
1225 if (err) {
1226 pr_err("%s: sysdev_class_register fail (%d)\n",
1227 __func__, err);
Syed Rameez Mustafae81dc932013-10-16 13:52:58 -07001228 goto socinfo_init_err;
Abhimanyu Kapur91a0a502013-01-11 19:24:59 -08001229 }
Syed Rameez Mustafae81dc932013-10-16 13:52:58 -07001230
Abhimanyu Kapur91a0a502013-01-11 19:24:59 -08001231 err = sysdev_register(&soc_sys_device);
1232 if (err) {
1233 pr_err("%s: sysdev_register fail (%d)\n",
1234 __func__, err);
Syed Rameez Mustafae81dc932013-10-16 13:52:58 -07001235 goto socinfo_init_err;
Abhimanyu Kapur91a0a502013-01-11 19:24:59 -08001236 }
Syed Rameez Mustafae81dc932013-10-16 13:52:58 -07001237
Abhimanyu Kapur91a0a502013-01-11 19:24:59 -08001238 socinfo_create_files(&soc_sys_device, socinfo_v1_files,
1239 ARRAY_SIZE(socinfo_v1_files));
1240 if (socinfo->v1.format < 2)
Syed Rameez Mustafae81dc932013-10-16 13:52:58 -07001241 goto socinfo_init_err;
1242
Abhimanyu Kapur91a0a502013-01-11 19:24:59 -08001243 socinfo_create_files(&soc_sys_device, socinfo_v2_files,
1244 ARRAY_SIZE(socinfo_v2_files));
1245
1246 if (socinfo->v1.format < 3)
Syed Rameez Mustafae81dc932013-10-16 13:52:58 -07001247 goto socinfo_init_err;
Abhimanyu Kapur91a0a502013-01-11 19:24:59 -08001248
1249 socinfo_create_files(&soc_sys_device, socinfo_v3_files,
1250 ARRAY_SIZE(socinfo_v3_files));
1251
1252 if (socinfo->v1.format < 4)
Syed Rameez Mustafae81dc932013-10-16 13:52:58 -07001253 goto socinfo_init_err;
Abhimanyu Kapur91a0a502013-01-11 19:24:59 -08001254
1255 socinfo_create_files(&soc_sys_device, socinfo_v4_files,
1256 ARRAY_SIZE(socinfo_v4_files));
1257
1258 if (socinfo->v1.format < 5)
Syed Rameez Mustafae81dc932013-10-16 13:52:58 -07001259 goto socinfo_init_err;
Abhimanyu Kapur91a0a502013-01-11 19:24:59 -08001260
1261 socinfo_create_files(&soc_sys_device, socinfo_v5_files,
1262 ARRAY_SIZE(socinfo_v5_files));
1263
1264 if (socinfo->v1.format < 6)
Syed Rameez Mustafae81dc932013-10-16 13:52:58 -07001265 goto socinfo_init_err;
Abhimanyu Kapur91a0a502013-01-11 19:24:59 -08001266
1267 socinfo_create_files(&soc_sys_device, socinfo_v6_files,
1268 ARRAY_SIZE(socinfo_v6_files));
1269
1270 if (socinfo->v1.format < 7)
Syed Rameez Mustafae81dc932013-10-16 13:52:58 -07001271 goto socinfo_init_err;
Abhimanyu Kapur91a0a502013-01-11 19:24:59 -08001272
1273 socinfo_create_files(&soc_sys_device, socinfo_v7_files,
1274 ARRAY_SIZE(socinfo_v7_files));
1275
1276 return 0;
Syed Rameez Mustafae81dc932013-10-16 13:52:58 -07001277
1278socinfo_init_err:
1279 kfree(soc_dev_attr);
1280 return err;
Abhimanyu Kapur91a0a502013-01-11 19:24:59 -08001281}
1282
1283arch_initcall(socinfo_init_sysdev);
1284
Abhimanyu Kapur440cdde2012-12-04 00:05:40 -08001285static void socinfo_print(void)
1286{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001287 switch (socinfo->v1.format) {
1288 case 1:
1289 pr_info("%s: v%u, id=%u, ver=%u.%u\n",
1290 __func__, socinfo->v1.format, socinfo->v1.id,
1291 SOCINFO_VERSION_MAJOR(socinfo->v1.version),
1292 SOCINFO_VERSION_MINOR(socinfo->v1.version));
1293 break;
1294 case 2:
1295 pr_info("%s: v%u, id=%u, ver=%u.%u, "
1296 "raw_id=%u, raw_ver=%u\n",
1297 __func__, socinfo->v1.format, socinfo->v1.id,
1298 SOCINFO_VERSION_MAJOR(socinfo->v1.version),
1299 SOCINFO_VERSION_MINOR(socinfo->v1.version),
1300 socinfo->v2.raw_id, socinfo->v2.raw_version);
1301 break;
1302 case 3:
1303 pr_info("%s: v%u, id=%u, ver=%u.%u, "
1304 "raw_id=%u, raw_ver=%u, hw_plat=%u\n",
1305 __func__, socinfo->v1.format, socinfo->v1.id,
1306 SOCINFO_VERSION_MAJOR(socinfo->v1.version),
1307 SOCINFO_VERSION_MINOR(socinfo->v1.version),
1308 socinfo->v2.raw_id, socinfo->v2.raw_version,
1309 socinfo->v3.hw_platform);
1310 break;
1311 case 4:
1312 pr_info("%s: v%u, id=%u, ver=%u.%u, "
1313 "raw_id=%u, raw_ver=%u, hw_plat=%u, hw_plat_ver=%u\n",
1314 __func__, socinfo->v1.format, socinfo->v1.id,
1315 SOCINFO_VERSION_MAJOR(socinfo->v1.version),
1316 SOCINFO_VERSION_MINOR(socinfo->v1.version),
1317 socinfo->v2.raw_id, socinfo->v2.raw_version,
1318 socinfo->v3.hw_platform, socinfo->v4.platform_version);
1319 break;
1320 case 5:
1321 pr_info("%s: v%u, id=%u, ver=%u.%u, "
1322 "raw_id=%u, raw_ver=%u, hw_plat=%u, hw_plat_ver=%u\n"
1323 " accessory_chip=%u\n", __func__, socinfo->v1.format,
1324 socinfo->v1.id,
1325 SOCINFO_VERSION_MAJOR(socinfo->v1.version),
1326 SOCINFO_VERSION_MINOR(socinfo->v1.version),
1327 socinfo->v2.raw_id, socinfo->v2.raw_version,
1328 socinfo->v3.hw_platform, socinfo->v4.platform_version,
1329 socinfo->v5.accessory_chip);
1330 break;
1331 case 6:
1332 pr_info("%s: v%u, id=%u, ver=%u.%u, "
1333 "raw_id=%u, raw_ver=%u, hw_plat=%u, hw_plat_ver=%u\n"
1334 " accessory_chip=%u hw_plat_subtype=%u\n", __func__,
1335 socinfo->v1.format,
1336 socinfo->v1.id,
1337 SOCINFO_VERSION_MAJOR(socinfo->v1.version),
1338 SOCINFO_VERSION_MINOR(socinfo->v1.version),
1339 socinfo->v2.raw_id, socinfo->v2.raw_version,
1340 socinfo->v3.hw_platform, socinfo->v4.platform_version,
1341 socinfo->v5.accessory_chip,
1342 socinfo->v6.hw_platform_subtype);
1343 break;
Abhimanyu Kapur781c03d2013-02-21 16:20:23 -08001344 case 8:
Jin Hong9b556c32012-08-13 23:06:26 -07001345 case 7:
1346 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",
1347 __func__,
1348 socinfo->v1.format,
1349 socinfo->v1.id,
1350 SOCINFO_VERSION_MAJOR(socinfo->v1.version),
1351 SOCINFO_VERSION_MINOR(socinfo->v1.version),
1352 socinfo->v2.raw_id, socinfo->v2.raw_version,
1353 socinfo->v3.hw_platform, socinfo->v4.platform_version,
1354 socinfo->v5.accessory_chip,
1355 socinfo->v6.hw_platform_subtype,
1356 socinfo->v7.pmic_model,
1357 socinfo->v7.pmic_die_revision);
1358 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001359 default:
1360 pr_err("%s: Unknown format found\n", __func__);
1361 break;
1362 }
Abhimanyu Kapur440cdde2012-12-04 00:05:40 -08001363}
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001364
Abhimanyu Kapur91a0a502013-01-11 19:24:59 -08001365int __init socinfo_init(void)
Abhimanyu Kapur440cdde2012-12-04 00:05:40 -08001366{
Abhimanyu Kapur781c03d2013-02-21 16:20:23 -08001367 socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID, sizeof(struct socinfo_v8));
1368
1369 if (!socinfo)
1370 socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
1371 sizeof(struct socinfo_v7));
Abhimanyu Kapur440cdde2012-12-04 00:05:40 -08001372
1373 if (!socinfo)
1374 socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
1375 sizeof(struct socinfo_v6));
1376
1377 if (!socinfo)
1378 socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
1379 sizeof(struct socinfo_v5));
1380
1381 if (!socinfo)
1382 socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
1383 sizeof(struct socinfo_v4));
1384
1385 if (!socinfo)
1386 socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
1387 sizeof(struct socinfo_v3));
1388
1389 if (!socinfo)
1390 socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
1391 sizeof(struct socinfo_v2));
1392
1393 if (!socinfo)
1394 socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
1395 sizeof(struct socinfo_v1));
1396
1397 if (!socinfo) {
1398 pr_warn("%s: Can't find SMEM_HW_SW_BUILD_ID; falling back on dummy values.\n",
1399 __func__);
1400 socinfo = setup_dummy_socinfo();
1401 }
1402
1403 WARN(!socinfo_get_id(), "Unknown SOC ID!\n");
1404 WARN(socinfo_get_id() >= ARRAY_SIZE(cpu_of_id),
1405 "New IDs added! ID => CPU mapping might need an update.\n");
1406
1407 if (socinfo->v1.id < ARRAY_SIZE(cpu_of_id))
1408 cur_cpu = cpu_of_id[socinfo->v1.id];
1409
Abhimanyu Kapurcf3ed152013-03-01 19:32:19 -08001410 boot_stats_init();
Abhimanyu Kapur440cdde2012-12-04 00:05:40 -08001411 socinfo_print();
Abhimanyu Kapur440cdde2012-12-04 00:05:40 -08001412
Abhimanyu Kapur91a0a502013-01-11 19:24:59 -08001413 return 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001414}
Stepan Moskovchenkoeff783a2011-08-22 19:01:58 -07001415
1416const int get_core_count(void)
1417{
1418 if (!(read_cpuid_mpidr() & BIT(31)))
1419 return 1;
1420
Jin Hongc5f5d542012-04-12 16:48:51 -07001421 if (read_cpuid_mpidr() & BIT(30))
Stepan Moskovchenkoeff783a2011-08-22 19:01:58 -07001422 return 1;
1423
1424 /* 1 + the PART[1:0] field of MIDR */
1425 return ((read_cpuid_id() >> 4) & 3) + 1;
1426}
1427
1428const int read_msm_cpu_type(void)
1429{
Stepan Moskovchenkoa8f0a222011-10-24 18:53:17 -07001430 if (socinfo_get_msm_cpu() != MSM_CPU_UNKNOWN)
1431 return socinfo_get_msm_cpu();
1432
Stepan Moskovchenkoeff783a2011-08-22 19:01:58 -07001433 switch (read_cpuid_id()) {
1434 case 0x510F02D0:
1435 case 0x510F02D2:
1436 case 0x510F02D4:
1437 return MSM_CPU_8X60;
1438
1439 case 0x510F04D0:
1440 case 0x510F04D1:
1441 case 0x510F04D2:
Stepan Moskovchenkoa8f0a222011-10-24 18:53:17 -07001442 case 0x511F04D0:
1443 case 0x512F04D0:
Stepan Moskovchenkoeff783a2011-08-22 19:01:58 -07001444 return MSM_CPU_8960;
1445
Stepan Moskovchenkoa8f0a222011-10-24 18:53:17 -07001446 case 0x51404D11: /* We can't get here unless we are in bringup */
1447 return MSM_CPU_8930;
Stepan Moskovchenkoeff783a2011-08-22 19:01:58 -07001448
1449 case 0x510F06F0:
1450 return MSM_CPU_8064;
1451
Stepan Moskovchenko02c4d0c2012-07-26 14:33:02 -07001452 case 0x511F06F1:
Matt Wagantallbdff7fe2013-01-08 13:36:40 -08001453 case 0x511F06F2:
Stepan Moskovchenko02c4d0c2012-07-26 14:33:02 -07001454 case 0x512F06F0:
1455 return MSM_CPU_8974;
1456
Stepan Moskovchenkoeff783a2011-08-22 19:01:58 -07001457 default:
1458 return MSM_CPU_UNKNOWN;
1459 };
1460}
Stepan Moskovchenko70dc7cf2011-08-22 19:08:42 -07001461
Jin Hong12b8b432012-07-18 10:00:31 -07001462const int cpu_is_krait(void)
1463{
1464 return ((read_cpuid_id() & 0xFF00FC00) == 0x51000400);
1465}
1466
Stepan Moskovchenko70dc7cf2011-08-22 19:08:42 -07001467const int cpu_is_krait_v1(void)
1468{
1469 switch (read_cpuid_id()) {
1470 case 0x510F04D0:
1471 case 0x510F04D1:
1472 case 0x510F04D2:
1473 return 1;
1474
1475 default:
1476 return 0;
1477 };
1478}
Jin Hong12b8b432012-07-18 10:00:31 -07001479
1480const int cpu_is_krait_v2(void)
1481{
1482 switch (read_cpuid_id()) {
1483 case 0x511F04D0:
1484 case 0x511F04D1:
1485 case 0x511F04D2:
1486 case 0x511F04D3:
1487 case 0x511F04D4:
1488
1489 case 0x510F06F0:
1490 case 0x510F06F1:
1491 case 0x510F06F2:
1492 return 1;
1493
1494 default:
1495 return 0;
1496 };
1497}
Joel King824bd1f2012-08-19 12:55:49 -07001498
1499const int cpu_is_krait_v3(void)
1500{
1501 switch (read_cpuid_id()) {
1502 case 0x512F04D0:
1503 case 0x511F06F0:
1504 case 0x511F06F1:
Matt Wagantallbdff7fe2013-01-08 13:36:40 -08001505 case 0x511F06F2:
Joel King824bd1f2012-08-19 12:55:49 -07001506 case 0x510F05D0:
1507 return 1;
1508
1509 default:
1510 return 0;
1511 };
1512}