1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/
4  *	Dave Gerlach <d-gerlach@ti.com>
5  */
6 
7 #include <common.h>
8 #include <dm.h>
9 #include <soc.h>
10 
11 #include <asm/io.h>
12 
13 #define AM65X			0xbb5a
14 #define J721E			0xbb64
15 #define J7200			0xbb6d
16 
17 #define REV_SR1_0		0
18 #define REV_SR2_0		1
19 
20 #define JTAG_ID_VARIANT_SHIFT	28
21 #define JTAG_ID_VARIANT_MASK	(0xf << 28)
22 #define JTAG_ID_PARTNO_SHIFT	12
23 #define JTAG_ID_PARTNO_MASK	(0xffff << 12)
24 
25 struct soc_ti_k3_plat {
26 	const char *family;
27 	const char *revision;
28 };
29 
get_family_string(u32 idreg)30 static const char *get_family_string(u32 idreg)
31 {
32 	const char *family;
33 	u32 soc;
34 
35 	soc = (idreg & JTAG_ID_PARTNO_MASK) >> JTAG_ID_PARTNO_SHIFT;
36 
37 	switch (soc) {
38 	case AM65X:
39 		family = "AM65X";
40 		break;
41 	case J721E:
42 		family = "J721E";
43 		break;
44 	case J7200:
45 		family = "J7200";
46 		break;
47 	default:
48 		family = "Unknown Silicon";
49 	};
50 
51 	return family;
52 }
53 
get_rev_string(u32 idreg)54 static const char *get_rev_string(u32 idreg)
55 {
56 	const char *revision;
57 	u32 rev;
58 
59 	rev = (idreg & JTAG_ID_VARIANT_MASK) >> JTAG_ID_VARIANT_SHIFT;
60 
61 	switch (rev) {
62 	case REV_SR1_0:
63 		revision = "1.0";
64 		break;
65 	case REV_SR2_0:
66 		revision = "2.0";
67 		break;
68 	default:
69 		revision = "Unknown Revision";
70 	};
71 
72 	return revision;
73 }
74 
soc_ti_k3_get_family(struct udevice * dev,char * buf,int size)75 static int soc_ti_k3_get_family(struct udevice *dev, char *buf, int size)
76 {
77 	struct soc_ti_k3_plat *plat = dev_get_plat(dev);
78 
79 	snprintf(buf, size, "%s", plat->family);
80 
81 	return 0;
82 }
83 
soc_ti_k3_get_revision(struct udevice * dev,char * buf,int size)84 static int soc_ti_k3_get_revision(struct udevice *dev, char *buf, int size)
85 {
86 	struct soc_ti_k3_plat *plat = dev_get_plat(dev);
87 
88 	snprintf(buf, size, "SR%s", plat->revision);
89 
90 	return 0;
91 }
92 
93 static const struct soc_ops soc_ti_k3_ops = {
94 	.get_family = soc_ti_k3_get_family,
95 	.get_revision = soc_ti_k3_get_revision,
96 };
97 
soc_ti_k3_probe(struct udevice * dev)98 int soc_ti_k3_probe(struct udevice *dev)
99 {
100 	struct soc_ti_k3_plat *plat = dev_get_plat(dev);
101 	u32 idreg;
102 	void *idreg_addr;
103 
104 	idreg_addr = dev_read_addr_ptr(dev);
105 	if (!idreg_addr)
106 		return -EINVAL;
107 
108 	idreg = readl(idreg_addr);
109 
110 	plat->family = get_family_string(idreg);
111 	plat->revision = get_rev_string(idreg);
112 
113 	return 0;
114 }
115 
116 static const struct udevice_id soc_ti_k3_ids[] = {
117 	{ .compatible = "ti,am654-chipid" },
118 	{ }
119 };
120 
121 U_BOOT_DRIVER(soc_ti_k3) = {
122 	.name           = "soc_ti_k3",
123 	.id             = UCLASS_SOC,
124 	.ops		= &soc_ti_k3_ops,
125 	.of_match       = soc_ti_k3_ids,
126 	.probe          = soc_ti_k3_probe,
127 	.plat_auto	= sizeof(struct soc_ti_k3_plat),
128 };
129