1 // SPDX-License-Identifier: GPL-2.0
3 * TI K3 SoC info driver
5 * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com
8 #include <linux/mfd/syscon.h>
10 #include <linux/of_address.h>
11 #include <linux/regmap.h>
12 #include <linux/platform_device.h>
13 #include <linux/slab.h>
14 #include <linux/string.h>
15 #include <linux/sys_soc.h>
17 #define CTRLMMR_WKUP_JTAGID_REG 0
20 * 31-28 VARIANT Device variant
21 * 27-12 PARTNO Part number
22 * 11-1 MFG Indicates TI as manufacturer (0x17)
25 #define CTRLMMR_WKUP_JTAGID_VARIANT_SHIFT (28)
26 #define CTRLMMR_WKUP_JTAGID_VARIANT_MASK GENMASK(31, 28)
28 #define CTRLMMR_WKUP_JTAGID_PARTNO_SHIFT (12)
29 #define CTRLMMR_WKUP_JTAGID_PARTNO_MASK GENMASK(27, 12)
31 #define CTRLMMR_WKUP_JTAGID_MFG_SHIFT (1)
32 #define CTRLMMR_WKUP_JTAGID_MFG_MASK GENMASK(11, 1)
34 #define CTRLMMR_WKUP_JTAGID_MFG_TI 0x17
36 static const struct k3_soc_id
{
38 const char *family_name
;
47 k3_chipinfo_partno_to_names(unsigned int partno
,
48 struct soc_device_attribute
*soc_dev_attr
)
52 for (i
= 0; i
< ARRAY_SIZE(k3_soc_ids
); i
++)
53 if (partno
== k3_soc_ids
[i
].id
) {
54 soc_dev_attr
->family
= k3_soc_ids
[i
].family_name
;
61 static int k3_chipinfo_probe(struct platform_device
*pdev
)
63 struct device_node
*node
= pdev
->dev
.of_node
;
64 struct soc_device_attribute
*soc_dev_attr
;
65 struct device
*dev
= &pdev
->dev
;
66 struct soc_device
*soc_dev
;
67 struct regmap
*regmap
;
74 regmap
= device_node_to_regmap(node
);
76 return PTR_ERR(regmap
);
78 ret
= regmap_read(regmap
, CTRLMMR_WKUP_JTAGID_REG
, &jtag_id
);
82 mfg
= (jtag_id
& CTRLMMR_WKUP_JTAGID_MFG_MASK
) >>
83 CTRLMMR_WKUP_JTAGID_MFG_SHIFT
;
85 if (mfg
!= CTRLMMR_WKUP_JTAGID_MFG_TI
) {
86 dev_err(dev
, "Invalid MFG SoC\n");
90 variant
= (jtag_id
& CTRLMMR_WKUP_JTAGID_VARIANT_MASK
) >>
91 CTRLMMR_WKUP_JTAGID_VARIANT_SHIFT
;
94 partno_id
= (jtag_id
& CTRLMMR_WKUP_JTAGID_PARTNO_MASK
) >>
95 CTRLMMR_WKUP_JTAGID_PARTNO_SHIFT
;
97 soc_dev_attr
= kzalloc(sizeof(*soc_dev_attr
), GFP_KERNEL
);
101 soc_dev_attr
->revision
= kasprintf(GFP_KERNEL
, "SR%x.0", variant
);
102 if (!soc_dev_attr
->revision
) {
107 ret
= k3_chipinfo_partno_to_names(partno_id
, soc_dev_attr
);
109 dev_err(dev
, "Unknown SoC JTAGID[0x%08X]\n", jtag_id
);
114 node
= of_find_node_by_path("/");
115 of_property_read_string(node
, "model", &soc_dev_attr
->machine
);
118 soc_dev
= soc_device_register(soc_dev_attr
);
119 if (IS_ERR(soc_dev
)) {
120 ret
= PTR_ERR(soc_dev
);
124 dev_info(dev
, "Family:%s rev:%s JTAGID[0x%08x] Detected\n",
125 soc_dev_attr
->family
,
126 soc_dev_attr
->revision
, jtag_id
);
131 kfree(soc_dev_attr
->revision
);
137 static const struct of_device_id k3_chipinfo_of_match
[] = {
138 { .compatible
= "ti,am654-chipid", },
142 static struct platform_driver k3_chipinfo_driver
= {
144 .name
= "k3-chipinfo",
145 .of_match_table
= k3_chipinfo_of_match
,
147 .probe
= k3_chipinfo_probe
,
150 static int __init
k3_chipinfo_init(void)
152 return platform_driver_register(&k3_chipinfo_driver
);
154 subsys_initcall(k3_chipinfo_init
);