1 // SPDX-License-Identifier: GPL-2.0
6 #include <dt-bindings/firmware/imx/rsrc.h>
7 #include <linux/firmware/imx/sci.h>
8 #include <linux/slab.h>
9 #include <linux/sys_soc.h>
10 #include <linux/platform_device.h>
13 static struct imx_sc_ipc
*imx_sc_soc_ipc_handle
;
15 struct imx_sc_msg_misc_get_soc_id
{
16 struct imx_sc_rpc_msg hdr
;
26 } __packed
__aligned(4);
28 struct imx_sc_msg_misc_get_soc_uid
{
29 struct imx_sc_rpc_msg hdr
;
34 static int imx_scu_soc_uid(u64
*soc_uid
)
36 struct imx_sc_msg_misc_get_soc_uid msg
;
37 struct imx_sc_rpc_msg
*hdr
= &msg
.hdr
;
40 hdr
->ver
= IMX_SC_RPC_VERSION
;
41 hdr
->svc
= IMX_SC_RPC_SVC_MISC
;
42 hdr
->func
= IMX_SC_MISC_FUNC_UNIQUE_ID
;
45 ret
= imx_scu_call_rpc(imx_sc_soc_ipc_handle
, &msg
, true);
47 pr_err("%s: get soc uid failed, ret %d\n", __func__
, ret
);
51 *soc_uid
= msg
.uid_high
;
53 *soc_uid
|= msg
.uid_low
;
58 static int imx_scu_soc_id(void)
60 struct imx_sc_msg_misc_get_soc_id msg
;
61 struct imx_sc_rpc_msg
*hdr
= &msg
.hdr
;
64 hdr
->ver
= IMX_SC_RPC_VERSION
;
65 hdr
->svc
= IMX_SC_RPC_SVC_MISC
;
66 hdr
->func
= IMX_SC_MISC_FUNC_GET_CONTROL
;
69 msg
.data
.req
.control
= IMX_SC_C_ID
;
70 msg
.data
.req
.resource
= IMX_SC_R_SYSTEM
;
72 ret
= imx_scu_call_rpc(imx_sc_soc_ipc_handle
, &msg
, true);
74 pr_err("%s: get soc info failed, ret %d\n", __func__
, ret
);
78 return msg
.data
.resp
.id
;
81 int imx_scu_soc_init(struct device
*dev
)
83 struct soc_device_attribute
*soc_dev_attr
;
84 struct soc_device
*soc_dev
;
89 ret
= imx_scu_get_handle(&imx_sc_soc_ipc_handle
);
93 soc_dev_attr
= devm_kzalloc(dev
, sizeof(*soc_dev_attr
),
98 soc_dev_attr
->family
= "Freescale i.MX";
100 ret
= of_property_read_string(of_root
,
102 &soc_dev_attr
->machine
);
106 id
= imx_scu_soc_id();
110 ret
= imx_scu_soc_uid(&uid
);
114 /* format soc_id value passed from SCU firmware */
116 soc_dev_attr
->soc_id
= devm_kasprintf(dev
, GFP_KERNEL
, "0x%x", val
);
117 if (!soc_dev_attr
->soc_id
)
120 /* format revision value passed from SCU firmware */
121 val
= (id
>> 5) & 0xf;
122 val
= (((val
>> 2) + 1) << 4) | (val
& 0x3);
123 soc_dev_attr
->revision
= devm_kasprintf(dev
, GFP_KERNEL
, "%d.%d",
124 (val
>> 4) & 0xf, val
& 0xf);
125 if (!soc_dev_attr
->revision
)
128 soc_dev_attr
->serial_number
= devm_kasprintf(dev
, GFP_KERNEL
,
130 if (!soc_dev_attr
->serial_number
)
133 soc_dev
= soc_device_register(soc_dev_attr
);
135 return PTR_ERR(soc_dev
);