Skip to content

Commit 821b67f

Browse files
committed
firmware: smccc: Add ARCH_SOC_ID support
SMCCC v1.2 adds a new optional function SMCCC_ARCH_SOC_ID to obtain a SiP defined SoC identification value. Add support for the same. Also using the SoC bus infrastructure, let us expose the platform specific SoC atrributes under sysfs. There are various ways in which it can be represented in shortened form for efficiency and ease of parsing for userspace. The chosen form is described in the ABI document. Link: https://lore.kernel.org/r/[email protected] Cc: Etienne Carriere <[email protected]> Reviewed-by: Steven Price <[email protected]> Signed-off-by: Sudeep Holla <[email protected]>
1 parent 475d04b commit 821b67f

File tree

5 files changed

+159
-0
lines changed

5 files changed

+159
-0
lines changed

Documentation/ABI/testing/sysfs-devices-soc

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,30 @@ Description:
2626
Read-only attribute common to all SoCs. Contains SoC family name
2727
(e.g. DB8500).
2828

29+
On many of ARM based silicon with SMCCC v1.2+ compliant firmware
30+
this will contain the JEDEC JEP106 manufacturer’s identification
31+
code. The format is "jep106:XXYY" where XX is identity code and
32+
YY is continuation code.
33+
34+
This manufacturer’s identification code is defined by one
35+
or more eight (8) bit fields, each consisting of seven (7)
36+
data bits plus one (1) odd parity bit. It is a single field,
37+
limiting the possible number of vendors to 126. To expand
38+
the maximum number of identification codes, a continuation
39+
scheme has been defined.
40+
41+
The specified mechanism is that an identity code of 0x7F
42+
represents the "continuation code" and implies the presence
43+
of an additional identity code field, and this mechanism
44+
may be extended to multiple continuation codes followed
45+
by the manufacturer's identity code.
46+
47+
For example, ARM has identity code 0x7F 0x7F 0x7F 0x7F 0x3B,
48+
which is code 0x3B on the fifth 'page'. This is shortened
49+
as JEP106 identity code of 0x3B and a continuation code of
50+
0x4 to represent the four continuation codes preceding the
51+
identity code.
52+
2953
What: /sys/devices/socX/serial_number
3054
Date: January 2019
3155
contact: Bjorn Andersson <[email protected]>
@@ -40,6 +64,12 @@ Description:
4064
Read-only attribute supported by most SoCs. In the case of
4165
ST-Ericsson's chips this contains the SoC serial number.
4266

67+
On many of ARM based silicon with SMCCC v1.2+ compliant firmware
68+
this will contain the SOC ID appended to the family attribute
69+
to ensure there is no conflict in this namespace across various
70+
vendors. The format is "jep106:XXYY:ZZZZ" where XX is identity
71+
code, YY is continuation code and ZZZZ is the SOC ID.
72+
4373
What: /sys/devices/socX/revision
4474
Date: January 2012
4575
contact: Lee Jones <[email protected]>

drivers/firmware/smccc/Kconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,12 @@ config HAVE_ARM_SMCCC_DISCOVERY
1414
to add SMCCC discovery mechanism though the PSCI firmware
1515
implementation of PSCI_FEATURES(SMCCC_VERSION) which returns
1616
success on firmware compliant to SMCCC v1.1 and above.
17+
18+
config ARM_SMCCC_SOC_ID
19+
bool "SoC bus device for the ARM SMCCC SOC_ID"
20+
depends on HAVE_ARM_SMCCC_DISCOVERY
21+
default y
22+
select SOC_BUS
23+
help
24+
Include support for the SoC bus on the ARM SMCCC firmware based
25+
platforms providing some sysfs information about the SoC variant.

drivers/firmware/smccc/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
# SPDX-License-Identifier: GPL-2.0
22
#
33
obj-$(CONFIG_HAVE_ARM_SMCCC_DISCOVERY) += smccc.o
4+
obj-$(CONFIG_ARM_SMCCC_SOC_ID) += soc_id.o

drivers/firmware/smccc/soc_id.c

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/*
3+
* Copyright 2020 Arm Limited
4+
*/
5+
6+
#define pr_fmt(fmt) "SMCCC: SOC_ID: " fmt
7+
8+
#include <linux/arm-smccc.h>
9+
#include <linux/bitfield.h>
10+
#include <linux/device.h>
11+
#include <linux/module.h>
12+
#include <linux/kernel.h>
13+
#include <linux/slab.h>
14+
#include <linux/sys_soc.h>
15+
16+
#define SMCCC_SOC_ID_JEP106_BANK_IDX_MASK GENMASK(30, 24)
17+
/*
18+
* As per the SMC Calling Convention specification v1.2 (ARM DEN 0028C)
19+
* Section 7.4 SMCCC_ARCH_SOC_ID bits[23:16] are JEP-106 identification
20+
* code with parity bit for the SiP. We can drop the parity bit.
21+
*/
22+
#define SMCCC_SOC_ID_JEP106_ID_CODE_MASK GENMASK(22, 16)
23+
#define SMCCC_SOC_ID_IMP_DEF_SOC_ID_MASK GENMASK(15, 0)
24+
25+
#define JEP106_BANK_CONT_CODE(x) \
26+
(u8)(FIELD_GET(SMCCC_SOC_ID_JEP106_BANK_IDX_MASK, (x)))
27+
#define JEP106_ID_CODE(x) \
28+
(u8)(FIELD_GET(SMCCC_SOC_ID_JEP106_ID_CODE_MASK, (x)))
29+
#define IMP_DEF_SOC_ID(x) \
30+
(u16)(FIELD_GET(SMCCC_SOC_ID_IMP_DEF_SOC_ID_MASK, (x)))
31+
32+
static struct soc_device *soc_dev;
33+
static struct soc_device_attribute *soc_dev_attr;
34+
35+
static int __init smccc_soc_init(void)
36+
{
37+
struct arm_smccc_res res;
38+
int soc_id_rev, soc_id_version;
39+
static char soc_id_str[20], soc_id_rev_str[12];
40+
static char soc_id_jep106_id_str[12];
41+
42+
if (arm_smccc_get_version() < ARM_SMCCC_VERSION_1_2)
43+
return 0;
44+
45+
if (arm_smccc_1_1_get_conduit() == SMCCC_CONDUIT_NONE) {
46+
pr_err("%s: invalid SMCCC conduit\n", __func__);
47+
return -EOPNOTSUPP;
48+
}
49+
50+
arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
51+
ARM_SMCCC_ARCH_SOC_ID, &res);
52+
53+
if (res.a0 == SMCCC_RET_NOT_SUPPORTED) {
54+
pr_info("ARCH_SOC_ID not implemented, skipping ....\n");
55+
return 0;
56+
}
57+
58+
if ((int)res.a0 < 0) {
59+
pr_info("ARCH_FEATURES(ARCH_SOC_ID) returned error: %lx\n",
60+
res.a0);
61+
return -EINVAL;
62+
}
63+
64+
arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_SOC_ID, 0, &res);
65+
if ((int)res.a0 < 0) {
66+
pr_err("ARCH_SOC_ID(0) returned error: %lx\n", res.a0);
67+
return -EINVAL;
68+
}
69+
70+
soc_id_version = res.a0;
71+
72+
arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_SOC_ID, 1, &res);
73+
if ((int)res.a0 < 0) {
74+
pr_err("ARCH_SOC_ID(1) returned error: %lx\n", res.a0);
75+
return -EINVAL;
76+
}
77+
78+
soc_id_rev = res.a0;
79+
80+
soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
81+
if (!soc_dev_attr)
82+
return -ENOMEM;
83+
84+
sprintf(soc_id_rev_str, "0x%08x", soc_id_rev);
85+
sprintf(soc_id_jep106_id_str, "jep106:%02x%02x",
86+
JEP106_BANK_CONT_CODE(soc_id_version),
87+
JEP106_ID_CODE(soc_id_version));
88+
sprintf(soc_id_str, "%s:%04x", soc_id_jep106_id_str,
89+
IMP_DEF_SOC_ID(soc_id_version));
90+
91+
soc_dev_attr->soc_id = soc_id_str;
92+
soc_dev_attr->revision = soc_id_rev_str;
93+
soc_dev_attr->family = soc_id_jep106_id_str;
94+
95+
soc_dev = soc_device_register(soc_dev_attr);
96+
if (IS_ERR(soc_dev)) {
97+
kfree(soc_dev_attr);
98+
return PTR_ERR(soc_dev);
99+
}
100+
101+
pr_info("ID = %s Revision = %s\n", soc_dev_attr->soc_id,
102+
soc_dev_attr->revision);
103+
104+
return 0;
105+
}
106+
module_init(smccc_soc_init);
107+
108+
static void __exit smccc_soc_exit(void)
109+
{
110+
if (soc_dev)
111+
soc_device_unregister(soc_dev);
112+
kfree(soc_dev_attr);
113+
}
114+
module_exit(smccc_soc_exit);

include/linux/arm-smccc.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@
7171
ARM_SMCCC_SMC_32, \
7272
0, 1)
7373

74+
#define ARM_SMCCC_ARCH_SOC_ID \
75+
ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
76+
ARM_SMCCC_SMC_32, \
77+
0, 2)
78+
7479
#define ARM_SMCCC_ARCH_WORKAROUND_1 \
7580
ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
7681
ARM_SMCCC_SMC_32, \

0 commit comments

Comments
 (0)