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 static const char *imx_scu_soc_name(u32 id
)
97 int imx_scu_soc_init(struct device
*dev
)
99 struct soc_device_attribute
*soc_dev_attr
;
100 struct soc_device
*soc_dev
;
105 ret
= imx_scu_get_handle(&imx_sc_soc_ipc_handle
);
109 soc_dev_attr
= devm_kzalloc(dev
, sizeof(*soc_dev_attr
),
114 soc_dev_attr
->family
= "Freescale i.MX";
116 ret
= of_property_read_string(of_root
,
118 &soc_dev_attr
->machine
);
122 id
= imx_scu_soc_id();
126 ret
= imx_scu_soc_uid(&uid
);
130 /* format soc_id value passed from SCU firmware */
132 soc_dev_attr
->soc_id
= imx_scu_soc_name(val
);
134 /* format revision value passed from SCU firmware */
135 val
= (id
>> 5) & 0xf;
136 val
= (((val
>> 2) + 1) << 4) | (val
& 0x3);
137 soc_dev_attr
->revision
= devm_kasprintf(dev
, GFP_KERNEL
, "%d.%d",
138 (val
>> 4) & 0xf, val
& 0xf);
139 if (!soc_dev_attr
->revision
)
142 soc_dev_attr
->serial_number
= devm_kasprintf(dev
, GFP_KERNEL
,
144 if (!soc_dev_attr
->serial_number
)
147 soc_dev
= soc_device_register(soc_dev_attr
);
149 return PTR_ERR(soc_dev
);