1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2020 Texas Instruments Incorporated - https://www.ti.com/
4  *	Dave Gerlach <d-gerlach@ti.com>
5  */
6 
7 #include <dm.h>
8 #include <soc.h>
9 
10 #include <asm/arch/hardware.h>
11 #include <asm/io.h>
12 
13 struct soc_ti_k3_plat {
14 	const char *family;
15 	const char *revision;
16 };
17 
get_family_string(u32 idreg)18 static const char *get_family_string(u32 idreg)
19 {
20 	const char *family;
21 	u32 jtag_dev_id;
22 	u32 pkg;
23 	u32 soc;
24 
25 	jtag_dev_id = readl(CTRLMMR_WKUP_JTAG_DEVICE_ID);
26 
27 	soc = (idreg & JTAG_ID_PARTNO_MASK) >> JTAG_ID_PARTNO_SHIFT;
28 
29 	switch (soc) {
30 	case JTAG_ID_PARTNO_AM62X:
31 		family = "AM62X";
32 		break;
33 	case JTAG_ID_PARTNO_AM62AX:
34 		family = "AM62AX";
35 		break;
36 	case JTAG_ID_PARTNO_AM62PX:
37 		family = "AM62PX";
38 		break;
39 	case JTAG_ID_PARTNO_AM64X:
40 		family = "AM64X";
41 		break;
42 	case JTAG_ID_PARTNO_AM65X:
43 		family = "AM65X";
44 		break;
45 	case JTAG_ID_PARTNO_J7200:
46 		family = "J7200";
47 		break;
48 	case JTAG_ID_PARTNO_J721E:
49 		family = "J721E";
50 		break;
51 	case JTAG_ID_PARTNO_J721S2:
52 		family = "J721S2";
53 		break;
54 	case JTAG_ID_PARTNO_J722S:
55 		family = "J722S";
56 		break;
57 	case JTAG_ID_PARTNO_J784S4:
58 		{
59 			/* Keep default family as J784S4 */
60 			family = "J784S4";
61 
62 			pkg = (jtag_dev_id & JTAG_DEV_J742S2_PKG_MASK) >> JTAG_DEV_J742S2_PKG_SHIFT;
63 			if (pkg == JTAG_ID_PKG_J742S2)
64 				family = "J742S2";
65 
66 			break;
67 		}
68 	default:
69 		family = "Unknown Silicon";
70 	};
71 
72 	return family;
73 }
74 
75 static char *j721e_rev_string_map[] = {
76 	"1.0", "1.1", "2.0",
77 };
78 
79 static char *typical_rev_string_map[] = {
80 	"1.0", "2.0", "3.0",
81 };
82 
get_rev_string(u32 idreg)83 static const char *get_rev_string(u32 idreg)
84 {
85 	u32 rev;
86 	u32 soc;
87 
88 	rev = (idreg & JTAG_ID_VARIANT_MASK) >> JTAG_ID_VARIANT_SHIFT;
89 	soc = (idreg & JTAG_ID_PARTNO_MASK) >> JTAG_ID_PARTNO_SHIFT;
90 
91 	switch (soc) {
92 	case JTAG_ID_PARTNO_J721E:
93 		if (rev >= ARRAY_SIZE(j721e_rev_string_map))
94 			goto bail;
95 		return j721e_rev_string_map[rev];
96 
97 	default:
98 		if (rev >= ARRAY_SIZE(typical_rev_string_map))
99 			goto bail;
100 		return typical_rev_string_map[rev];
101 	};
102 
103 bail:
104 	return "Unknown Revision";
105 }
106 
soc_ti_k3_get_family(struct udevice * dev,char * buf,int size)107 static int soc_ti_k3_get_family(struct udevice *dev, char *buf, int size)
108 {
109 	struct soc_ti_k3_plat *plat = dev_get_plat(dev);
110 
111 	snprintf(buf, size, "%s", plat->family);
112 
113 	return 0;
114 }
115 
soc_ti_k3_get_revision(struct udevice * dev,char * buf,int size)116 static int soc_ti_k3_get_revision(struct udevice *dev, char *buf, int size)
117 {
118 	struct soc_ti_k3_plat *plat = dev_get_plat(dev);
119 
120 	snprintf(buf, size, "SR%s", plat->revision);
121 
122 	return 0;
123 }
124 
125 static const struct soc_ops soc_ti_k3_ops = {
126 	.get_family = soc_ti_k3_get_family,
127 	.get_revision = soc_ti_k3_get_revision,
128 };
129 
soc_ti_k3_probe(struct udevice * dev)130 int soc_ti_k3_probe(struct udevice *dev)
131 {
132 	struct soc_ti_k3_plat *plat = dev_get_plat(dev);
133 	u32 idreg;
134 	void *idreg_addr;
135 
136 	idreg_addr = dev_read_addr_ptr(dev);
137 	if (!idreg_addr)
138 		return -EINVAL;
139 
140 	idreg = readl(idreg_addr);
141 
142 	plat->family = get_family_string(idreg);
143 	plat->revision = get_rev_string(idreg);
144 
145 	return 0;
146 }
147 
148 static const struct udevice_id soc_ti_k3_ids[] = {
149 	{ .compatible = "ti,am654-chipid" },
150 	{ }
151 };
152 
153 U_BOOT_DRIVER(soc_ti_k3) = {
154 	.name           = "soc_ti_k3",
155 	.id             = UCLASS_SOC,
156 	.ops		= &soc_ti_k3_ops,
157 	.of_match       = soc_ti_k3_ids,
158 	.probe          = soc_ti_k3_probe,
159 	.plat_auto	= sizeof(struct soc_ti_k3_plat),
160 };
161