Merge tag 'dm-pull-20jul20' of git://git.denx.de/u-boot-dm
[platform/kernel/u-boot.git] / drivers / soc / soc_ti_k3.c
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
16 #define REV_SR1_0               0
17 #define REV_SR2_0               1
18
19 #define JTAG_ID_VARIANT_SHIFT   28
20 #define JTAG_ID_VARIANT_MASK    (0xf << 28)
21 #define JTAG_ID_PARTNO_SHIFT    12
22 #define JTAG_ID_PARTNO_MASK     (0xffff << 12)
23
24 struct soc_ti_k3_platdata {
25         const char *family;
26         const char *revision;
27 };
28
29 static const char *get_family_string(u32 idreg)
30 {
31         const char *family;
32         u32 soc;
33
34         soc = (idreg & JTAG_ID_PARTNO_MASK) >> JTAG_ID_PARTNO_SHIFT;
35
36         switch (soc) {
37         case AM65X:
38                 family = "AM65X";
39                 break;
40         case J721E:
41                 family = "J721E";
42                 break;
43         default:
44                 family = "Unknown Silicon";
45         };
46
47         return family;
48 }
49
50 static const char *get_rev_string(u32 idreg)
51 {
52         const char *revision;
53         u32 rev;
54
55         rev = (idreg & JTAG_ID_VARIANT_MASK) >> JTAG_ID_VARIANT_SHIFT;
56
57         switch (rev) {
58         case REV_SR1_0:
59                 revision = "1.0";
60                 break;
61         case REV_SR2_0:
62                 revision = "2.0";
63                 break;
64         default:
65                 revision = "Unknown Revision";
66         };
67
68         return revision;
69 }
70
71 static int soc_ti_k3_get_family(struct udevice *dev, char *buf, int size)
72 {
73         struct soc_ti_k3_platdata *plat = dev_get_platdata(dev);
74
75         snprintf(buf, size, "%s", plat->family);
76
77         return 0;
78 }
79
80 static int soc_ti_k3_get_revision(struct udevice *dev, char *buf, int size)
81 {
82         struct soc_ti_k3_platdata *plat = dev_get_platdata(dev);
83
84         snprintf(buf, size, "SR%s", plat->revision);
85
86         return 0;
87 }
88
89 static const struct soc_ops soc_ti_k3_ops = {
90         .get_family = soc_ti_k3_get_family,
91         .get_revision = soc_ti_k3_get_revision,
92 };
93
94 int soc_ti_k3_probe(struct udevice *dev)
95 {
96         struct soc_ti_k3_platdata *plat = dev_get_platdata(dev);
97         u32 idreg;
98         void *idreg_addr;
99
100         idreg_addr = dev_read_addr_ptr(dev);
101         if (!idreg_addr)
102                 return -EINVAL;
103
104         idreg = readl(idreg_addr);
105
106         plat->family = get_family_string(idreg);
107         plat->revision = get_rev_string(idreg);
108
109         return 0;
110 }
111
112 static const struct udevice_id soc_ti_k3_ids[] = {
113         { .compatible = "ti,am654-chipid" },
114         { }
115 };
116
117 U_BOOT_DRIVER(soc_ti_k3) = {
118         .name           = "soc_ti_k3",
119         .id             = UCLASS_SOC,
120         .ops            = &soc_ti_k3_ops,
121         .of_match       = soc_ti_k3_ids,
122         .probe          = soc_ti_k3_probe,
123         .platdata_auto_alloc_size = sizeof(struct soc_ti_k3_platdata),
124 };