1259 lines
28 KiB
C
1259 lines
28 KiB
C
/* Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 and
|
|
* only version 2 as published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
*/
|
|
/*
|
|
* SOC Info Routines
|
|
*
|
|
*/
|
|
|
|
#include <linux/err.h>
|
|
#include <linux/of.h>
|
|
#include <linux/platform_device.h>
|
|
#include <linux/sys_soc.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/stat.h>
|
|
#include <linux/sysdev.h>
|
|
#include <linux/types.h>
|
|
|
|
#include <asm/mach-types.h>
|
|
|
|
#include <mach/socinfo.h>
|
|
#include <mach/msm_smem.h>
|
|
|
|
#include "boot_stats.h"
|
|
|
|
#define BUILD_ID_LENGTH 32
|
|
|
|
enum {
|
|
HW_PLATFORM_UNKNOWN = 0,
|
|
HW_PLATFORM_SURF = 1,
|
|
HW_PLATFORM_FFA = 2,
|
|
HW_PLATFORM_FLUID = 3,
|
|
HW_PLATFORM_SVLTE_FFA = 4,
|
|
HW_PLATFORM_SVLTE_SURF = 5,
|
|
HW_PLATFORM_MTP = 8,
|
|
HW_PLATFORM_LIQUID = 9,
|
|
/* Dragonboard platform id is assigned as 10 in CDT */
|
|
HW_PLATFORM_DRAGON = 10,
|
|
HW_PLATFORM_QRD = 11,
|
|
HW_PLATFORM_HRD = 13,
|
|
HW_PLATFORM_DTV = 14,
|
|
HW_PLATFORM_INVALID
|
|
};
|
|
|
|
const char *hw_platform[] = {
|
|
[HW_PLATFORM_UNKNOWN] = "Unknown",
|
|
[HW_PLATFORM_SURF] = "Surf",
|
|
[HW_PLATFORM_FFA] = "FFA",
|
|
[HW_PLATFORM_FLUID] = "Fluid",
|
|
[HW_PLATFORM_SVLTE_FFA] = "SVLTE_FFA",
|
|
[HW_PLATFORM_SVLTE_SURF] = "SLVTE_SURF",
|
|
[HW_PLATFORM_MTP] = "MTP",
|
|
[HW_PLATFORM_LIQUID] = "Liquid",
|
|
[HW_PLATFORM_DRAGON] = "Dragon",
|
|
[HW_PLATFORM_QRD] = "QRD",
|
|
[HW_PLATFORM_HRD] = "HRD",
|
|
[HW_PLATFORM_DTV] = "DTV",
|
|
};
|
|
|
|
enum {
|
|
ACCESSORY_CHIP_UNKNOWN = 0,
|
|
ACCESSORY_CHIP_CHARM = 58,
|
|
};
|
|
|
|
enum {
|
|
PLATFORM_SUBTYPE_UNKNOWN = 0x0,
|
|
PLATFORM_SUBTYPE_CHARM = 0x1,
|
|
PLATFORM_SUBTYPE_STRANGE = 0x2,
|
|
PLATFORM_SUBTYPE_STRANGE_2A = 0x3,
|
|
PLATFORM_SUBTYPE_INVALID,
|
|
};
|
|
|
|
const char *hw_platform_subtype[] = {
|
|
[PLATFORM_SUBTYPE_UNKNOWN] = "Unknown",
|
|
[PLATFORM_SUBTYPE_CHARM] = "charm",
|
|
[PLATFORM_SUBTYPE_STRANGE] = "strange",
|
|
[PLATFORM_SUBTYPE_STRANGE_2A] = "strange_2a,"
|
|
};
|
|
|
|
/* Used to parse shared memory. Must match the modem. */
|
|
struct socinfo_v1 {
|
|
uint32_t format;
|
|
uint32_t id;
|
|
uint32_t version;
|
|
char build_id[BUILD_ID_LENGTH];
|
|
};
|
|
|
|
struct socinfo_v2 {
|
|
struct socinfo_v1 v1;
|
|
|
|
/* only valid when format==2 */
|
|
uint32_t raw_id;
|
|
uint32_t raw_version;
|
|
};
|
|
|
|
struct socinfo_v3 {
|
|
struct socinfo_v2 v2;
|
|
|
|
/* only valid when format==3 */
|
|
uint32_t hw_platform;
|
|
};
|
|
|
|
struct socinfo_v4 {
|
|
struct socinfo_v3 v3;
|
|
|
|
/* only valid when format==4 */
|
|
uint32_t platform_version;
|
|
};
|
|
|
|
struct socinfo_v5 {
|
|
struct socinfo_v4 v4;
|
|
|
|
/* only valid when format==5 */
|
|
uint32_t accessory_chip;
|
|
};
|
|
|
|
struct socinfo_v6 {
|
|
struct socinfo_v5 v5;
|
|
|
|
/* only valid when format==6 */
|
|
uint32_t hw_platform_subtype;
|
|
};
|
|
|
|
struct socinfo_v7 {
|
|
struct socinfo_v6 v6;
|
|
|
|
/* only valid when format==7 */
|
|
uint32_t pmic_model;
|
|
uint32_t pmic_die_revision;
|
|
};
|
|
|
|
struct socinfo_v8 {
|
|
struct socinfo_v7 v7;
|
|
|
|
/* only valid when format==8*/
|
|
uint32_t pmic_model_1;
|
|
uint32_t pmic_die_revision_1;
|
|
uint32_t pmic_model_2;
|
|
uint32_t pmic_die_revision_2;
|
|
};
|
|
|
|
static union {
|
|
struct socinfo_v1 v1;
|
|
struct socinfo_v2 v2;
|
|
struct socinfo_v3 v3;
|
|
struct socinfo_v4 v4;
|
|
struct socinfo_v5 v5;
|
|
struct socinfo_v6 v6;
|
|
struct socinfo_v7 v7;
|
|
struct socinfo_v8 v8;
|
|
} *socinfo;
|
|
|
|
static enum msm_cpu cpu_of_id[] = {
|
|
|
|
/* 7x01 IDs */
|
|
[1] = MSM_CPU_7X01,
|
|
[16] = MSM_CPU_7X01,
|
|
[17] = MSM_CPU_7X01,
|
|
[18] = MSM_CPU_7X01,
|
|
[19] = MSM_CPU_7X01,
|
|
[23] = MSM_CPU_7X01,
|
|
[25] = MSM_CPU_7X01,
|
|
[26] = MSM_CPU_7X01,
|
|
[32] = MSM_CPU_7X01,
|
|
[33] = MSM_CPU_7X01,
|
|
[34] = MSM_CPU_7X01,
|
|
[35] = MSM_CPU_7X01,
|
|
|
|
/* 7x25 IDs */
|
|
[20] = MSM_CPU_7X25,
|
|
[21] = MSM_CPU_7X25, /* 7225 */
|
|
[24] = MSM_CPU_7X25, /* 7525 */
|
|
[27] = MSM_CPU_7X25, /* 7625 */
|
|
[39] = MSM_CPU_7X25,
|
|
[40] = MSM_CPU_7X25,
|
|
[41] = MSM_CPU_7X25,
|
|
[42] = MSM_CPU_7X25,
|
|
[62] = MSM_CPU_7X25, /* 7625-1 */
|
|
[63] = MSM_CPU_7X25, /* 7225-1 */
|
|
[66] = MSM_CPU_7X25, /* 7225-2 */
|
|
|
|
|
|
/* 7x27 IDs */
|
|
[43] = MSM_CPU_7X27,
|
|
[44] = MSM_CPU_7X27,
|
|
[61] = MSM_CPU_7X27,
|
|
[67] = MSM_CPU_7X27, /* 7227-1 */
|
|
[68] = MSM_CPU_7X27, /* 7627-1 */
|
|
[69] = MSM_CPU_7X27, /* 7627-2 */
|
|
|
|
|
|
/* 8x50 IDs */
|
|
[30] = MSM_CPU_8X50,
|
|
[36] = MSM_CPU_8X50,
|
|
[37] = MSM_CPU_8X50,
|
|
[38] = MSM_CPU_8X50,
|
|
|
|
/* 7x30 IDs */
|
|
[59] = MSM_CPU_7X30,
|
|
[60] = MSM_CPU_7X30,
|
|
|
|
/* 8x55 IDs */
|
|
[74] = MSM_CPU_8X55,
|
|
[75] = MSM_CPU_8X55,
|
|
[85] = MSM_CPU_8X55,
|
|
|
|
/* 8x60 IDs */
|
|
[70] = MSM_CPU_8X60,
|
|
[71] = MSM_CPU_8X60,
|
|
[86] = MSM_CPU_8X60,
|
|
|
|
/* 8960 IDs */
|
|
[87] = MSM_CPU_8960,
|
|
|
|
/* 7x25A IDs */
|
|
[88] = MSM_CPU_7X25A,
|
|
[89] = MSM_CPU_7X25A,
|
|
[96] = MSM_CPU_7X25A,
|
|
|
|
/* 7x27A IDs */
|
|
[90] = MSM_CPU_7X27A,
|
|
[91] = MSM_CPU_7X27A,
|
|
[92] = MSM_CPU_7X27A,
|
|
[97] = MSM_CPU_7X27A,
|
|
|
|
/* FSM9xxx ID */
|
|
[94] = FSM_CPU_9XXX,
|
|
[95] = FSM_CPU_9XXX,
|
|
|
|
/* 7x25AA ID */
|
|
[98] = MSM_CPU_7X25AA,
|
|
[99] = MSM_CPU_7X25AA,
|
|
[100] = MSM_CPU_7X25AA,
|
|
|
|
/* 7x27AA ID */
|
|
[101] = MSM_CPU_7X27AA,
|
|
[102] = MSM_CPU_7X27AA,
|
|
[103] = MSM_CPU_7X27AA,
|
|
[136] = MSM_CPU_7X27AA,
|
|
|
|
/* 9x15 ID */
|
|
[104] = MSM_CPU_9615,
|
|
[105] = MSM_CPU_9615,
|
|
[106] = MSM_CPU_9615,
|
|
[107] = MSM_CPU_9615,
|
|
[171] = MSM_CPU_9615,
|
|
|
|
/* 8064 IDs */
|
|
[109] = MSM_CPU_8064,
|
|
|
|
/* 8930 IDs */
|
|
[116] = MSM_CPU_8930,
|
|
[117] = MSM_CPU_8930,
|
|
[118] = MSM_CPU_8930,
|
|
[119] = MSM_CPU_8930,
|
|
[179] = MSM_CPU_8930,
|
|
|
|
/* 8627 IDs */
|
|
[120] = MSM_CPU_8627,
|
|
[121] = MSM_CPU_8627,
|
|
|
|
/* 8660A ID */
|
|
[122] = MSM_CPU_8960,
|
|
|
|
/* 8260A ID */
|
|
[123] = MSM_CPU_8960,
|
|
|
|
/* 8060A ID */
|
|
[124] = MSM_CPU_8960,
|
|
|
|
/* 8974 IDs */
|
|
[126] = MSM_CPU_8974,
|
|
[184] = MSM_CPU_8974,
|
|
[185] = MSM_CPU_8974,
|
|
[186] = MSM_CPU_8974,
|
|
|
|
/* 8625 IDs */
|
|
[127] = MSM_CPU_8625,
|
|
[128] = MSM_CPU_8625,
|
|
[129] = MSM_CPU_8625,
|
|
[137] = MSM_CPU_8625,
|
|
[167] = MSM_CPU_8625,
|
|
|
|
/* 8064 MPQ ID */
|
|
[130] = MSM_CPU_8064,
|
|
|
|
/* 7x25AB IDs */
|
|
[131] = MSM_CPU_7X25AB,
|
|
[132] = MSM_CPU_7X25AB,
|
|
[133] = MSM_CPU_7X25AB,
|
|
[135] = MSM_CPU_7X25AB,
|
|
|
|
/* 9625 IDs */
|
|
[134] = MSM_CPU_9625,
|
|
[148] = MSM_CPU_9625,
|
|
[149] = MSM_CPU_9625,
|
|
[150] = MSM_CPU_9625,
|
|
[151] = MSM_CPU_9625,
|
|
[152] = MSM_CPU_9625,
|
|
[173] = MSM_CPU_9625,
|
|
[174] = MSM_CPU_9625,
|
|
[175] = MSM_CPU_9625,
|
|
|
|
/* 8960AB IDs */
|
|
[138] = MSM_CPU_8960AB,
|
|
[139] = MSM_CPU_8960AB,
|
|
[140] = MSM_CPU_8960AB,
|
|
[141] = MSM_CPU_8960AB,
|
|
|
|
/* 8930AA IDs */
|
|
[142] = MSM_CPU_8930AA,
|
|
[143] = MSM_CPU_8930AA,
|
|
[144] = MSM_CPU_8930AA,
|
|
[160] = MSM_CPU_8930AA,
|
|
[180] = MSM_CPU_8930AA,
|
|
|
|
/* 8226 IDs */
|
|
[145] = MSM_CPU_8226,
|
|
[158] = MSM_CPU_8226,
|
|
[159] = MSM_CPU_8226,
|
|
[198] = MSM_CPU_8226,
|
|
[199] = MSM_CPU_8226,
|
|
[200] = MSM_CPU_8226,
|
|
[205] = MSM_CPU_8226,
|
|
|
|
/* 8092 IDs */
|
|
[146] = MSM_CPU_8092,
|
|
|
|
/* 8610 IDs */
|
|
[147] = MSM_CPU_8610,
|
|
[161] = MSM_CPU_8610,
|
|
[162] = MSM_CPU_8610,
|
|
[163] = MSM_CPU_8610,
|
|
[164] = MSM_CPU_8610,
|
|
[165] = MSM_CPU_8610,
|
|
[166] = MSM_CPU_8610,
|
|
|
|
/* 8064AB IDs */
|
|
[153] = MSM_CPU_8064AB,
|
|
|
|
/* 8930AB IDs */
|
|
[154] = MSM_CPU_8930AB,
|
|
[155] = MSM_CPU_8930AB,
|
|
[156] = MSM_CPU_8930AB,
|
|
[157] = MSM_CPU_8930AB,
|
|
[181] = MSM_CPU_8930AB,
|
|
|
|
/* 8625Q IDs */
|
|
[168] = MSM_CPU_8625Q,
|
|
[169] = MSM_CPU_8625Q,
|
|
[170] = MSM_CPU_8625Q,
|
|
|
|
/* 8064AA IDs */
|
|
[172] = MSM_CPU_8064AA,
|
|
|
|
/* 8084 IDs */
|
|
[178] = MSM_CPU_8084,
|
|
|
|
/* krypton IDs */
|
|
[187] = MSM_CPU_KRYPTON,
|
|
|
|
/* FSM9900 ID */
|
|
[188] = FSM_CPU_9900,
|
|
|
|
/* Samarium IDs */
|
|
[195] = MSM_CPU_SAMARIUM,
|
|
|
|
/* Uninitialized IDs are not known to run Linux.
|
|
MSM_CPU_UNKNOWN is set to 0 to ensure these IDs are
|
|
considered as unknown CPU. */
|
|
};
|
|
|
|
static enum msm_cpu cur_cpu;
|
|
|
|
static struct socinfo_v1 dummy_socinfo = {
|
|
.format = 1,
|
|
.version = 1,
|
|
};
|
|
|
|
uint32_t socinfo_get_id(void)
|
|
{
|
|
return (socinfo) ? socinfo->v1.id : 0;
|
|
}
|
|
EXPORT_SYMBOL_GPL(socinfo_get_id);
|
|
|
|
uint32_t socinfo_get_version(void)
|
|
{
|
|
return (socinfo) ? socinfo->v1.version : 0;
|
|
}
|
|
|
|
char *socinfo_get_build_id(void)
|
|
{
|
|
return (socinfo) ? socinfo->v1.build_id : NULL;
|
|
}
|
|
|
|
uint32_t socinfo_get_raw_id(void)
|
|
{
|
|
return socinfo ?
|
|
(socinfo->v1.format >= 2 ? socinfo->v2.raw_id : 0)
|
|
: 0;
|
|
}
|
|
|
|
uint32_t socinfo_get_raw_version(void)
|
|
{
|
|
return socinfo ?
|
|
(socinfo->v1.format >= 2 ? socinfo->v2.raw_version : 0)
|
|
: 0;
|
|
}
|
|
|
|
uint32_t socinfo_get_platform_type(void)
|
|
{
|
|
return socinfo ?
|
|
(socinfo->v1.format >= 3 ? socinfo->v3.hw_platform : 0)
|
|
: 0;
|
|
}
|
|
|
|
|
|
uint32_t socinfo_get_platform_version(void)
|
|
{
|
|
return socinfo ?
|
|
(socinfo->v1.format >= 4 ? socinfo->v4.platform_version : 0)
|
|
: 0;
|
|
}
|
|
|
|
/* This information is directly encoded by the machine id */
|
|
/* Thus no external callers rely on this information at the moment */
|
|
static uint32_t socinfo_get_accessory_chip(void)
|
|
{
|
|
return socinfo ?
|
|
(socinfo->v1.format >= 5 ? socinfo->v5.accessory_chip : 0)
|
|
: 0;
|
|
}
|
|
|
|
uint32_t socinfo_get_platform_subtype(void)
|
|
{
|
|
return socinfo ?
|
|
(socinfo->v1.format >= 6 ? socinfo->v6.hw_platform_subtype : 0)
|
|
: 0;
|
|
}
|
|
|
|
enum pmic_model socinfo_get_pmic_model(void)
|
|
{
|
|
return socinfo ?
|
|
(socinfo->v1.format >= 7 ? socinfo->v7.pmic_model
|
|
: PMIC_MODEL_UNKNOWN)
|
|
: PMIC_MODEL_UNKNOWN;
|
|
}
|
|
|
|
uint32_t socinfo_get_pmic_die_revision(void)
|
|
{
|
|
return socinfo ?
|
|
(socinfo->v1.format >= 7 ? socinfo->v7.pmic_die_revision : 0)
|
|
: 0;
|
|
}
|
|
|
|
static uint32_t socinfo_get_format(void)
|
|
{
|
|
return socinfo ? socinfo->v1.format : 0;
|
|
}
|
|
|
|
enum msm_cpu socinfo_get_msm_cpu(void)
|
|
{
|
|
return cur_cpu;
|
|
}
|
|
EXPORT_SYMBOL_GPL(socinfo_get_msm_cpu);
|
|
|
|
static ssize_t
|
|
socinfo_show_id(struct sys_device *dev,
|
|
struct sysdev_attribute *attr,
|
|
char *buf)
|
|
{
|
|
if (!socinfo) {
|
|
pr_err("%s: No socinfo found!\n", __func__);
|
|
return 0;
|
|
}
|
|
|
|
return snprintf(buf, PAGE_SIZE, "%u\n", socinfo_get_id());
|
|
}
|
|
|
|
static ssize_t
|
|
socinfo_show_version(struct sys_device *dev,
|
|
struct sysdev_attribute *attr,
|
|
char *buf)
|
|
{
|
|
uint32_t version;
|
|
|
|
if (!socinfo) {
|
|
pr_err("%s: No socinfo found!\n", __func__);
|
|
return 0;
|
|
}
|
|
|
|
version = socinfo_get_version();
|
|
return snprintf(buf, PAGE_SIZE, "%u.%u\n",
|
|
SOCINFO_VERSION_MAJOR(version),
|
|
SOCINFO_VERSION_MINOR(version));
|
|
}
|
|
|
|
static ssize_t
|
|
socinfo_show_build_id(struct sys_device *dev,
|
|
struct sysdev_attribute *attr,
|
|
char *buf)
|
|
{
|
|
if (!socinfo) {
|
|
pr_err("%s: No socinfo found!\n", __func__);
|
|
return 0;
|
|
}
|
|
|
|
return snprintf(buf, PAGE_SIZE, "%-.32s\n", socinfo_get_build_id());
|
|
}
|
|
|
|
static ssize_t
|
|
socinfo_show_raw_id(struct sys_device *dev,
|
|
struct sysdev_attribute *attr,
|
|
char *buf)
|
|
{
|
|
if (!socinfo) {
|
|
pr_err("%s: No socinfo found!\n", __func__);
|
|
return 0;
|
|
}
|
|
if (socinfo->v1.format < 2) {
|
|
pr_err("%s: Raw ID not available!\n", __func__);
|
|
return 0;
|
|
}
|
|
|
|
return snprintf(buf, PAGE_SIZE, "%u\n", socinfo_get_raw_id());
|
|
}
|
|
|
|
static ssize_t
|
|
socinfo_show_raw_version(struct sys_device *dev,
|
|
struct sysdev_attribute *attr,
|
|
char *buf)
|
|
{
|
|
if (!socinfo) {
|
|
pr_err("%s: No socinfo found!\n", __func__);
|
|
return 0;
|
|
}
|
|
if (socinfo->v1.format < 2) {
|
|
pr_err("%s: Raw version not available!\n", __func__);
|
|
return 0;
|
|
}
|
|
|
|
return snprintf(buf, PAGE_SIZE, "%u\n", socinfo_get_raw_version());
|
|
}
|
|
|
|
static ssize_t
|
|
socinfo_show_platform_type(struct sys_device *dev,
|
|
struct sysdev_attribute *attr,
|
|
char *buf)
|
|
{
|
|
uint32_t hw_type;
|
|
|
|
if (!socinfo) {
|
|
pr_err("%s: No socinfo found!\n", __func__);
|
|
return 0;
|
|
}
|
|
if (socinfo->v1.format < 3) {
|
|
pr_err("%s: platform type not available!\n", __func__);
|
|
return 0;
|
|
}
|
|
|
|
hw_type = socinfo_get_platform_type();
|
|
if (hw_type >= HW_PLATFORM_INVALID) {
|
|
pr_err("%s: Invalid hardware platform type found\n",
|
|
__func__);
|
|
hw_type = HW_PLATFORM_UNKNOWN;
|
|
}
|
|
|
|
return snprintf(buf, PAGE_SIZE, "%-.32s\n", hw_platform[hw_type]);
|
|
}
|
|
|
|
static ssize_t
|
|
socinfo_show_platform_version(struct sys_device *dev,
|
|
struct sysdev_attribute *attr,
|
|
char *buf)
|
|
{
|
|
|
|
if (!socinfo) {
|
|
pr_err("%s: No socinfo found!\n", __func__);
|
|
return 0;
|
|
}
|
|
if (socinfo->v1.format < 4) {
|
|
pr_err("%s: platform version not available!\n", __func__);
|
|
return 0;
|
|
}
|
|
|
|
return snprintf(buf, PAGE_SIZE, "%u\n",
|
|
socinfo_get_platform_version());
|
|
}
|
|
|
|
static ssize_t
|
|
socinfo_show_accessory_chip(struct sys_device *dev,
|
|
struct sysdev_attribute *attr,
|
|
char *buf)
|
|
{
|
|
if (!socinfo) {
|
|
pr_err("%s: No socinfo found!\n", __func__);
|
|
return 0;
|
|
}
|
|
if (socinfo->v1.format < 5) {
|
|
pr_err("%s: accessory chip not available!\n", __func__);
|
|
return 0;
|
|
}
|
|
|
|
return snprintf(buf, PAGE_SIZE, "%u\n",
|
|
socinfo_get_accessory_chip());
|
|
}
|
|
|
|
static ssize_t
|
|
socinfo_show_platform_subtype(struct sys_device *dev,
|
|
struct sysdev_attribute *attr,
|
|
char *buf)
|
|
{
|
|
uint32_t hw_subtype;
|
|
if (!socinfo) {
|
|
pr_err("%s: No socinfo found!\n", __func__);
|
|
return 0;
|
|
}
|
|
if (socinfo->v1.format < 6) {
|
|
pr_err("%s: platform subtype not available!\n", __func__);
|
|
return 0;
|
|
}
|
|
|
|
hw_subtype = socinfo_get_platform_subtype();
|
|
if (hw_subtype >= PLATFORM_SUBTYPE_INVALID) {
|
|
pr_err("%s: Invalid hardware platform sub type found\n",
|
|
__func__);
|
|
hw_subtype = PLATFORM_SUBTYPE_UNKNOWN;
|
|
}
|
|
return snprintf(buf, PAGE_SIZE, "%-.32s\n",
|
|
hw_platform_subtype[hw_subtype]);
|
|
}
|
|
|
|
static ssize_t
|
|
socinfo_show_pmic_model(struct sys_device *dev,
|
|
struct sysdev_attribute *attr,
|
|
char *buf)
|
|
{
|
|
if (!socinfo) {
|
|
pr_err("%s: No socinfo found!\n", __func__);
|
|
return 0;
|
|
}
|
|
if (socinfo->v1.format < 7) {
|
|
pr_err("%s: pmic_model not available!\n", __func__);
|
|
return 0;
|
|
}
|
|
|
|
return snprintf(buf, PAGE_SIZE, "%u\n",
|
|
socinfo_get_pmic_model());
|
|
}
|
|
|
|
static ssize_t
|
|
socinfo_show_pmic_die_revision(struct sys_device *dev,
|
|
struct sysdev_attribute *attr,
|
|
char *buf)
|
|
{
|
|
if (!socinfo) {
|
|
pr_err("%s: No socinfo found!\n", __func__);
|
|
return 0;
|
|
}
|
|
if (socinfo->v1.format < 7) {
|
|
pr_err("%s: pmic_die_revision not available!\n", __func__);
|
|
return 0;
|
|
}
|
|
|
|
return snprintf(buf, PAGE_SIZE, "%u\n",
|
|
socinfo_get_pmic_die_revision());
|
|
}
|
|
|
|
static ssize_t
|
|
msm_get_vendor(struct device *dev,
|
|
struct device_attribute *attr,
|
|
char *buf)
|
|
{
|
|
return snprintf(buf, PAGE_SIZE, "Qualcomm\n");
|
|
}
|
|
|
|
static ssize_t
|
|
msm_get_raw_id(struct device *dev,
|
|
struct device_attribute *attr,
|
|
char *buf)
|
|
{
|
|
return snprintf(buf, PAGE_SIZE, "%u\n",
|
|
socinfo_get_raw_id());
|
|
}
|
|
|
|
static ssize_t
|
|
msm_get_raw_version(struct device *dev,
|
|
struct device_attribute *attr,
|
|
char *buf)
|
|
{
|
|
return snprintf(buf, PAGE_SIZE, "%u\n",
|
|
socinfo_get_raw_version());
|
|
}
|
|
|
|
static ssize_t
|
|
msm_get_build_id(struct device *dev,
|
|
struct device_attribute *attr,
|
|
char *buf)
|
|
{
|
|
return snprintf(buf, PAGE_SIZE, "%-.32s\n",
|
|
socinfo_get_build_id());
|
|
}
|
|
|
|
static ssize_t
|
|
msm_get_hw_platform(struct device *dev,
|
|
struct device_attribute *attr,
|
|
char *buf)
|
|
{
|
|
uint32_t hw_type;
|
|
hw_type = socinfo_get_platform_type();
|
|
|
|
return snprintf(buf, PAGE_SIZE, "%-.32s\n",
|
|
hw_platform[hw_type]);
|
|
}
|
|
|
|
static ssize_t
|
|
msm_get_platform_version(struct device *dev,
|
|
struct device_attribute *attr,
|
|
char *buf)
|
|
{
|
|
return snprintf(buf, PAGE_SIZE, "%u\n",
|
|
socinfo_get_platform_version());
|
|
}
|
|
|
|
static ssize_t
|
|
msm_get_accessory_chip(struct device *dev,
|
|
struct device_attribute *attr,
|
|
char *buf)
|
|
{
|
|
return snprintf(buf, PAGE_SIZE, "%u\n",
|
|
socinfo_get_accessory_chip());
|
|
}
|
|
|
|
static ssize_t
|
|
msm_get_platform_subtype(struct device *dev,
|
|
struct device_attribute *attr,
|
|
char *buf)
|
|
{
|
|
uint32_t hw_subtype;
|
|
hw_subtype = socinfo_get_platform_subtype();
|
|
return snprintf(buf, PAGE_SIZE, "%-.32s\n",
|
|
hw_platform_subtype[hw_subtype]);
|
|
}
|
|
|
|
static ssize_t
|
|
msm_get_pmic_model(struct device *dev,
|
|
struct device_attribute *attr,
|
|
char *buf)
|
|
{
|
|
return snprintf(buf, PAGE_SIZE, "%u\n",
|
|
socinfo_get_pmic_model());
|
|
}
|
|
|
|
static ssize_t
|
|
msm_get_pmic_die_revision(struct device *dev,
|
|
struct device_attribute *attr,
|
|
char *buf)
|
|
{
|
|
return snprintf(buf, PAGE_SIZE, "%u\n",
|
|
socinfo_get_pmic_die_revision());
|
|
}
|
|
|
|
static struct sysdev_attribute socinfo_v1_files[] = {
|
|
_SYSDEV_ATTR(id, 0444, socinfo_show_id, NULL),
|
|
_SYSDEV_ATTR(version, 0444, socinfo_show_version, NULL),
|
|
_SYSDEV_ATTR(build_id, 0444, socinfo_show_build_id, NULL),
|
|
};
|
|
|
|
static struct sysdev_attribute socinfo_v2_files[] = {
|
|
_SYSDEV_ATTR(raw_id, 0444, socinfo_show_raw_id, NULL),
|
|
_SYSDEV_ATTR(raw_version, 0444, socinfo_show_raw_version, NULL),
|
|
};
|
|
|
|
static struct sysdev_attribute socinfo_v3_files[] = {
|
|
_SYSDEV_ATTR(hw_platform, 0444, socinfo_show_platform_type, NULL),
|
|
};
|
|
|
|
static struct sysdev_attribute socinfo_v4_files[] = {
|
|
_SYSDEV_ATTR(platform_version, 0444,
|
|
socinfo_show_platform_version, NULL),
|
|
};
|
|
|
|
static struct sysdev_attribute socinfo_v5_files[] = {
|
|
_SYSDEV_ATTR(accessory_chip, 0444,
|
|
socinfo_show_accessory_chip, NULL),
|
|
};
|
|
|
|
static struct sysdev_attribute socinfo_v6_files[] = {
|
|
_SYSDEV_ATTR(platform_subtype, 0444,
|
|
socinfo_show_platform_subtype, NULL),
|
|
};
|
|
|
|
static struct sysdev_attribute socinfo_v7_files[] = {
|
|
_SYSDEV_ATTR(pmic_model, 0444,
|
|
socinfo_show_pmic_model, NULL),
|
|
_SYSDEV_ATTR(pmic_die_revision, 0444,
|
|
socinfo_show_pmic_die_revision, NULL),
|
|
};
|
|
|
|
static struct device_attribute msm_soc_attr_raw_version =
|
|
__ATTR(raw_version, S_IRUGO, msm_get_raw_version, NULL);
|
|
|
|
static struct device_attribute msm_soc_attr_raw_id =
|
|
__ATTR(raw_id, S_IRUGO, msm_get_raw_id, NULL);
|
|
|
|
static struct device_attribute msm_soc_attr_vendor =
|
|
__ATTR(vendor, S_IRUGO, msm_get_vendor, NULL);
|
|
|
|
static struct device_attribute msm_soc_attr_build_id =
|
|
__ATTR(build_id, S_IRUGO, msm_get_build_id, NULL);
|
|
|
|
static struct device_attribute msm_soc_attr_hw_platform =
|
|
__ATTR(hw_platform, S_IRUGO, msm_get_hw_platform, NULL);
|
|
|
|
|
|
static struct device_attribute msm_soc_attr_platform_version =
|
|
__ATTR(platform_version, S_IRUGO,
|
|
msm_get_platform_version, NULL);
|
|
|
|
static struct device_attribute msm_soc_attr_accessory_chip =
|
|
__ATTR(accessory_chip, S_IRUGO,
|
|
msm_get_accessory_chip, NULL);
|
|
|
|
static struct device_attribute msm_soc_attr_platform_subtype =
|
|
__ATTR(platform_subtype, S_IRUGO,
|
|
msm_get_platform_subtype, NULL);
|
|
|
|
static struct device_attribute msm_soc_attr_pmic_model =
|
|
__ATTR(pmic_model, S_IRUGO,
|
|
msm_get_pmic_model, NULL);
|
|
|
|
static struct device_attribute msm_soc_attr_pmic_die_revision =
|
|
__ATTR(pmic_die_revision, S_IRUGO,
|
|
msm_get_pmic_die_revision, NULL);
|
|
|
|
static struct sysdev_class soc_sysdev_class = {
|
|
.name = "soc",
|
|
};
|
|
|
|
static struct sys_device soc_sys_device = {
|
|
.id = 0,
|
|
.cls = &soc_sysdev_class,
|
|
};
|
|
|
|
static int __init socinfo_create_files(struct sys_device *dev,
|
|
struct sysdev_attribute files[],
|
|
int size)
|
|
{
|
|
int i;
|
|
for (i = 0; i < size; i++) {
|
|
int err = sysdev_create_file(dev, &files[i]);
|
|
if (err) {
|
|
pr_err("%s: sysdev_create_file(%s)=%d\n",
|
|
__func__, files[i].attr.name, err);
|
|
return err;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static void * __init setup_dummy_socinfo(void)
|
|
{
|
|
if (early_machine_is_mpq8092()) {
|
|
dummy_socinfo.id = 146;
|
|
strlcpy(dummy_socinfo.build_id, "mpq8092 - ",
|
|
sizeof(dummy_socinfo.build_id));
|
|
} else if (early_machine_is_apq8084()) {
|
|
dummy_socinfo.id = 178;
|
|
strlcpy(dummy_socinfo.build_id, "apq8084 - ",
|
|
sizeof(dummy_socinfo.build_id));
|
|
} else if (early_machine_is_msmkrypton()) {
|
|
dummy_socinfo.id = 187;
|
|
strlcpy(dummy_socinfo.build_id, "msmkrypton - ",
|
|
sizeof(dummy_socinfo.build_id));
|
|
} else if (early_machine_is_msmsamarium()) {
|
|
dummy_socinfo.id = 195;
|
|
strlcpy(dummy_socinfo.build_id, "msmsamarium - ",
|
|
sizeof(dummy_socinfo.build_id));
|
|
}
|
|
strlcat(dummy_socinfo.build_id, "Dummy socinfo",
|
|
sizeof(dummy_socinfo.build_id));
|
|
return (void *) &dummy_socinfo;
|
|
}
|
|
|
|
static void __init populate_soc_sysfs_files(struct device *msm_soc_device)
|
|
{
|
|
uint32_t legacy_format = socinfo_get_format();
|
|
|
|
device_create_file(msm_soc_device, &msm_soc_attr_vendor);
|
|
|
|
switch (legacy_format) {
|
|
case 8:
|
|
case 7:
|
|
device_create_file(msm_soc_device,
|
|
&msm_soc_attr_pmic_model);
|
|
device_create_file(msm_soc_device,
|
|
&msm_soc_attr_pmic_die_revision);
|
|
case 6:
|
|
device_create_file(msm_soc_device,
|
|
&msm_soc_attr_platform_subtype);
|
|
case 5:
|
|
device_create_file(msm_soc_device,
|
|
&msm_soc_attr_accessory_chip);
|
|
case 4:
|
|
device_create_file(msm_soc_device,
|
|
&msm_soc_attr_platform_version);
|
|
case 3:
|
|
device_create_file(msm_soc_device,
|
|
&msm_soc_attr_hw_platform);
|
|
case 2:
|
|
device_create_file(msm_soc_device,
|
|
&msm_soc_attr_raw_id);
|
|
device_create_file(msm_soc_device,
|
|
&msm_soc_attr_raw_version);
|
|
case 1:
|
|
device_create_file(msm_soc_device,
|
|
&msm_soc_attr_build_id);
|
|
break;
|
|
default:
|
|
pr_err("%s:Unknown socinfo format:%u\n", __func__,
|
|
legacy_format);
|
|
break;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
static void __init soc_info_populate(struct soc_device_attribute *soc_dev_attr)
|
|
{
|
|
uint32_t soc_version = socinfo_get_version();
|
|
|
|
soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "%d", socinfo_get_id());
|
|
soc_dev_attr->machine = "Snapdragon";
|
|
soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%u.%u",
|
|
SOCINFO_VERSION_MAJOR(soc_version),
|
|
SOCINFO_VERSION_MINOR(soc_version));
|
|
return;
|
|
|
|
}
|
|
|
|
static int __init socinfo_init_sysdev(void)
|
|
{
|
|
int err;
|
|
struct device *msm_soc_device;
|
|
struct soc_device *soc_dev;
|
|
struct soc_device_attribute *soc_dev_attr;
|
|
|
|
if (!socinfo) {
|
|
pr_err("%s: No socinfo found!\n", __func__);
|
|
return -ENODEV;
|
|
}
|
|
|
|
soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
|
|
if (!soc_dev_attr) {
|
|
pr_err("%s: Soc Device alloc failed!\n", __func__);
|
|
return -ENOMEM;
|
|
}
|
|
|
|
soc_info_populate(soc_dev_attr);
|
|
soc_dev = soc_device_register(soc_dev_attr);
|
|
if (IS_ERR_OR_NULL(soc_dev)) {
|
|
kfree(soc_dev_attr);
|
|
pr_err("%s: Soc device register failed\n", __func__);
|
|
return -EIO;
|
|
}
|
|
|
|
msm_soc_device = soc_device_to_device(soc_dev);
|
|
populate_soc_sysfs_files(msm_soc_device);
|
|
err = sysdev_class_register(&soc_sysdev_class);
|
|
if (err) {
|
|
pr_err("%s: sysdev_class_register fail (%d)\n",
|
|
__func__, err);
|
|
return err;
|
|
}
|
|
err = sysdev_register(&soc_sys_device);
|
|
if (err) {
|
|
pr_err("%s: sysdev_register fail (%d)\n",
|
|
__func__, err);
|
|
return err;
|
|
}
|
|
socinfo_create_files(&soc_sys_device, socinfo_v1_files,
|
|
ARRAY_SIZE(socinfo_v1_files));
|
|
if (socinfo->v1.format < 2)
|
|
return err;
|
|
socinfo_create_files(&soc_sys_device, socinfo_v2_files,
|
|
ARRAY_SIZE(socinfo_v2_files));
|
|
|
|
if (socinfo->v1.format < 3)
|
|
return err;
|
|
|
|
socinfo_create_files(&soc_sys_device, socinfo_v3_files,
|
|
ARRAY_SIZE(socinfo_v3_files));
|
|
|
|
if (socinfo->v1.format < 4)
|
|
return err;
|
|
|
|
socinfo_create_files(&soc_sys_device, socinfo_v4_files,
|
|
ARRAY_SIZE(socinfo_v4_files));
|
|
|
|
if (socinfo->v1.format < 5)
|
|
return err;
|
|
|
|
socinfo_create_files(&soc_sys_device, socinfo_v5_files,
|
|
ARRAY_SIZE(socinfo_v5_files));
|
|
|
|
if (socinfo->v1.format < 6)
|
|
return err;
|
|
|
|
socinfo_create_files(&soc_sys_device, socinfo_v6_files,
|
|
ARRAY_SIZE(socinfo_v6_files));
|
|
|
|
if (socinfo->v1.format < 7)
|
|
return err;
|
|
|
|
socinfo_create_files(&soc_sys_device, socinfo_v7_files,
|
|
ARRAY_SIZE(socinfo_v7_files));
|
|
|
|
return 0;
|
|
}
|
|
|
|
arch_initcall(socinfo_init_sysdev);
|
|
|
|
static void socinfo_print(void)
|
|
{
|
|
switch (socinfo->v1.format) {
|
|
case 1:
|
|
pr_info("%s: v%u, id=%u, ver=%u.%u\n",
|
|
__func__, socinfo->v1.format, socinfo->v1.id,
|
|
SOCINFO_VERSION_MAJOR(socinfo->v1.version),
|
|
SOCINFO_VERSION_MINOR(socinfo->v1.version));
|
|
break;
|
|
case 2:
|
|
pr_info("%s: v%u, id=%u, ver=%u.%u, "
|
|
"raw_id=%u, raw_ver=%u\n",
|
|
__func__, socinfo->v1.format, socinfo->v1.id,
|
|
SOCINFO_VERSION_MAJOR(socinfo->v1.version),
|
|
SOCINFO_VERSION_MINOR(socinfo->v1.version),
|
|
socinfo->v2.raw_id, socinfo->v2.raw_version);
|
|
break;
|
|
case 3:
|
|
pr_info("%s: v%u, id=%u, ver=%u.%u, "
|
|
"raw_id=%u, raw_ver=%u, hw_plat=%u\n",
|
|
__func__, socinfo->v1.format, socinfo->v1.id,
|
|
SOCINFO_VERSION_MAJOR(socinfo->v1.version),
|
|
SOCINFO_VERSION_MINOR(socinfo->v1.version),
|
|
socinfo->v2.raw_id, socinfo->v2.raw_version,
|
|
socinfo->v3.hw_platform);
|
|
break;
|
|
case 4:
|
|
pr_info("%s: v%u, id=%u, ver=%u.%u, "
|
|
"raw_id=%u, raw_ver=%u, hw_plat=%u, hw_plat_ver=%u\n",
|
|
__func__, socinfo->v1.format, socinfo->v1.id,
|
|
SOCINFO_VERSION_MAJOR(socinfo->v1.version),
|
|
SOCINFO_VERSION_MINOR(socinfo->v1.version),
|
|
socinfo->v2.raw_id, socinfo->v2.raw_version,
|
|
socinfo->v3.hw_platform, socinfo->v4.platform_version);
|
|
break;
|
|
case 5:
|
|
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\n", __func__, socinfo->v1.format,
|
|
socinfo->v1.id,
|
|
SOCINFO_VERSION_MAJOR(socinfo->v1.version),
|
|
SOCINFO_VERSION_MINOR(socinfo->v1.version),
|
|
socinfo->v2.raw_id, socinfo->v2.raw_version,
|
|
socinfo->v3.hw_platform, socinfo->v4.platform_version,
|
|
socinfo->v5.accessory_chip);
|
|
break;
|
|
case 6:
|
|
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\n", __func__,
|
|
socinfo->v1.format,
|
|
socinfo->v1.id,
|
|
SOCINFO_VERSION_MAJOR(socinfo->v1.version),
|
|
SOCINFO_VERSION_MINOR(socinfo->v1.version),
|
|
socinfo->v2.raw_id, socinfo->v2.raw_version,
|
|
socinfo->v3.hw_platform, socinfo->v4.platform_version,
|
|
socinfo->v5.accessory_chip,
|
|
socinfo->v6.hw_platform_subtype);
|
|
break;
|
|
case 8:
|
|
case 7:
|
|
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",
|
|
__func__,
|
|
socinfo->v1.format,
|
|
socinfo->v1.id,
|
|
SOCINFO_VERSION_MAJOR(socinfo->v1.version),
|
|
SOCINFO_VERSION_MINOR(socinfo->v1.version),
|
|
socinfo->v2.raw_id, socinfo->v2.raw_version,
|
|
socinfo->v3.hw_platform, socinfo->v4.platform_version,
|
|
socinfo->v5.accessory_chip,
|
|
socinfo->v6.hw_platform_subtype,
|
|
socinfo->v7.pmic_model,
|
|
socinfo->v7.pmic_die_revision);
|
|
break;
|
|
default:
|
|
pr_err("%s: Unknown format found\n", __func__);
|
|
break;
|
|
}
|
|
}
|
|
|
|
int __init socinfo_init(void)
|
|
{
|
|
socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID, sizeof(struct socinfo_v8));
|
|
|
|
if (!socinfo)
|
|
socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
|
|
sizeof(struct socinfo_v7));
|
|
|
|
if (!socinfo)
|
|
socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
|
|
sizeof(struct socinfo_v6));
|
|
|
|
if (!socinfo)
|
|
socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
|
|
sizeof(struct socinfo_v5));
|
|
|
|
if (!socinfo)
|
|
socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
|
|
sizeof(struct socinfo_v4));
|
|
|
|
if (!socinfo)
|
|
socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
|
|
sizeof(struct socinfo_v3));
|
|
|
|
if (!socinfo)
|
|
socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
|
|
sizeof(struct socinfo_v2));
|
|
|
|
if (!socinfo)
|
|
socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
|
|
sizeof(struct socinfo_v1));
|
|
|
|
if (!socinfo) {
|
|
pr_warn("%s: Can't find SMEM_HW_SW_BUILD_ID; falling back on dummy values.\n",
|
|
__func__);
|
|
socinfo = setup_dummy_socinfo();
|
|
}
|
|
|
|
WARN(!socinfo_get_id(), "Unknown SOC ID!\n");
|
|
WARN(socinfo_get_id() >= ARRAY_SIZE(cpu_of_id),
|
|
"New IDs added! ID => CPU mapping might need an update.\n");
|
|
|
|
if (socinfo->v1.id < ARRAY_SIZE(cpu_of_id))
|
|
cur_cpu = cpu_of_id[socinfo->v1.id];
|
|
|
|
boot_stats_init();
|
|
socinfo_print();
|
|
|
|
return 0;
|
|
}
|
|
|
|
const int get_core_count(void)
|
|
{
|
|
if (!(read_cpuid_mpidr() & BIT(31)))
|
|
return 1;
|
|
|
|
if (read_cpuid_mpidr() & BIT(30))
|
|
return 1;
|
|
|
|
/* 1 + the PART[1:0] field of MIDR */
|
|
return ((read_cpuid_id() >> 4) & 3) + 1;
|
|
}
|
|
|
|
const int read_msm_cpu_type(void)
|
|
{
|
|
if (socinfo_get_msm_cpu() != MSM_CPU_UNKNOWN)
|
|
return socinfo_get_msm_cpu();
|
|
|
|
switch (read_cpuid_id()) {
|
|
case 0x510F02D0:
|
|
case 0x510F02D2:
|
|
case 0x510F02D4:
|
|
return MSM_CPU_8X60;
|
|
|
|
case 0x510F04D0:
|
|
case 0x510F04D1:
|
|
case 0x510F04D2:
|
|
case 0x511F04D0:
|
|
case 0x512F04D0:
|
|
return MSM_CPU_8960;
|
|
|
|
case 0x51404D11: /* We can't get here unless we are in bringup */
|
|
return MSM_CPU_8930;
|
|
|
|
case 0x510F06F0:
|
|
return MSM_CPU_8064;
|
|
|
|
case 0x511F06F1:
|
|
case 0x511F06F2:
|
|
case 0x512F06F0:
|
|
return MSM_CPU_8974;
|
|
|
|
default:
|
|
return MSM_CPU_UNKNOWN;
|
|
};
|
|
}
|
|
|
|
const int cpu_is_krait(void)
|
|
{
|
|
return ((read_cpuid_id() & 0xFF00FC00) == 0x51000400);
|
|
}
|
|
|
|
const int cpu_is_krait_v1(void)
|
|
{
|
|
switch (read_cpuid_id()) {
|
|
case 0x510F04D0:
|
|
case 0x510F04D1:
|
|
case 0x510F04D2:
|
|
return 1;
|
|
|
|
default:
|
|
return 0;
|
|
};
|
|
}
|
|
|
|
const int cpu_is_krait_v2(void)
|
|
{
|
|
switch (read_cpuid_id()) {
|
|
case 0x511F04D0:
|
|
case 0x511F04D1:
|
|
case 0x511F04D2:
|
|
case 0x511F04D3:
|
|
case 0x511F04D4:
|
|
|
|
case 0x510F06F0:
|
|
case 0x510F06F1:
|
|
case 0x510F06F2:
|
|
return 1;
|
|
|
|
default:
|
|
return 0;
|
|
};
|
|
}
|
|
|
|
const int cpu_is_krait_v3(void)
|
|
{
|
|
switch (read_cpuid_id()) {
|
|
case 0x512F04D0:
|
|
case 0x511F06F0:
|
|
case 0x511F06F1:
|
|
case 0x511F06F2:
|
|
case 0x510F05D0:
|
|
return 1;
|
|
|
|
default:
|
|
return 0;
|
|
};
|
|
}
|