Merge tag 'u-boot-atmel-fixes-2020.07-a' of https://gitlab.denx.de/u-boot/custodians...
[oweals/u-boot.git] / arch / arm / mach-meson / board-info.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2019 Julien Masson <jmasson@baylibre.com>
4  * (C) Copyright 2019 Neil Armstrong <narmstrong@baylibre.com>
5  */
6
7 #include <common.h>
8 #include <init.h>
9 #include <asm/io.h>
10 #include <dm.h>
11 #include <linux/bitfield.h>
12 #include <regmap.h>
13 #include <syscon.h>
14 #include <linux/bitops.h>
15 #include <linux/err.h>
16
17 #define AO_SEC_SD_CFG8          0xe0
18 #define AO_SEC_SOCINFO_OFFSET   AO_SEC_SD_CFG8
19
20 #define SOCINFO_MAJOR   GENMASK(31, 24)
21 #define SOCINFO_PACK    GENMASK(23, 16)
22 #define SOCINFO_MINOR   GENMASK(15, 8)
23 #define SOCINFO_MISC    GENMASK(7, 0)
24
25 static const struct meson_gx_soc_id {
26         const char *name;
27         unsigned int id;
28 } soc_ids[] = {
29         { "GXBB",   0x1f },
30         { "GXTVBB", 0x20 },
31         { "GXL",    0x21 },
32         { "GXM",    0x22 },
33         { "TXL",    0x23 },
34         { "TXLX",   0x24 },
35         { "AXG",    0x25 },
36         { "GXLX",   0x26 },
37         { "TXHD",   0x27 },
38         { "G12A",   0x28 },
39         { "G12B",   0x29 },
40         { "SM1",    0x2b },
41 };
42
43 static const struct meson_gx_package_id {
44         const char *name;
45         unsigned int major_id;
46         unsigned int pack_id;
47         unsigned int pack_mask;
48 } soc_packages[] = {
49         { "S905",   0x1f, 0,    0x20 }, /* pack_id != 0x20 */
50         { "S905H",  0x1f, 0x3,  0xf },  /* pack_id & 0xf == 0x3 */
51         { "S905M",  0x1f, 0x20, 0xf0 }, /* pack_id == 0x20 */
52         { "S905D",  0x21, 0,    0xf0 },
53         { "S905X",  0x21, 0x80, 0xf0 },
54         { "S905W",  0x21, 0xa0, 0xf0 },
55         { "S905L",  0x21, 0xc0, 0xf0 },
56         { "S905M2", 0x21, 0xe0, 0xf0 },
57         { "S805X",  0x21, 0x30, 0xf0 },
58         { "S805Y",  0x21, 0xb0, 0xf0 },
59         { "S912",   0x22, 0,    0x0 },  /* Only S912 is known for GXM */
60         { "962X",   0x24, 0x10, 0xf0 },
61         { "962E",   0x24, 0x20, 0xf0 },
62         { "A113X",  0x25, 0x37, 0xff },
63         { "A113D",  0x25, 0x22, 0xff },
64         { "S905D2", 0x28, 0x10, 0xf0 },
65         { "S905X2", 0x28, 0x40, 0xf0 },
66         { "A311D",  0x29, 0x10, 0xf0 },
67         { "S922X",  0x29, 0x40, 0xf0 },
68         { "S905X3", 0x2b, 0x5, 0xf },
69 };
70
71 DECLARE_GLOBAL_DATA_PTR;
72
73 static inline unsigned int socinfo_to_major(u32 socinfo)
74 {
75         return FIELD_GET(SOCINFO_MAJOR, socinfo);
76 }
77
78 static inline unsigned int socinfo_to_minor(u32 socinfo)
79 {
80         return FIELD_GET(SOCINFO_MINOR, socinfo);
81 }
82
83 static inline unsigned int socinfo_to_pack(u32 socinfo)
84 {
85         return FIELD_GET(SOCINFO_PACK, socinfo);
86 }
87
88 static inline unsigned int socinfo_to_misc(u32 socinfo)
89 {
90         return FIELD_GET(SOCINFO_MISC, socinfo);
91 }
92
93 static const char *socinfo_to_package_id(u32 socinfo)
94 {
95         unsigned int pack = socinfo_to_pack(socinfo);
96         unsigned int major = socinfo_to_major(socinfo);
97         int i;
98
99         for (i = 0 ; i < ARRAY_SIZE(soc_packages) ; ++i) {
100                 if (soc_packages[i].major_id == major &&
101                     soc_packages[i].pack_id ==
102                     (pack & soc_packages[i].pack_mask))
103                         return soc_packages[i].name;
104         }
105
106         return "Unknown";
107 }
108
109 static const char *socinfo_to_soc_id(u32 socinfo)
110 {
111         unsigned int id = socinfo_to_major(socinfo);
112         int i;
113
114         for (i = 0 ; i < ARRAY_SIZE(soc_ids) ; ++i) {
115                 if (soc_ids[i].id == id)
116                         return soc_ids[i].name;
117         }
118
119         return "Unknown";
120 }
121
122 static void print_board_model(void)
123 {
124         const char *model;
125         model = fdt_getprop(gd->fdt_blob, 0, "model", NULL);
126         printf("Model: %s\n", model ? model : "Unknown");
127 }
128
129 int show_board_info(void)
130 {
131         struct regmap *regmap;
132         int nodeoffset, ret;
133         ofnode node;
134         unsigned int socinfo;
135
136         /* find the offset of compatible node */
137         nodeoffset = fdt_node_offset_by_compatible(gd->fdt_blob, -1,
138                                                    "amlogic,meson-gx-ao-secure");
139         if (nodeoffset < 0)
140                 return 0;
141
142         /* check if chip-id is available */
143         if (!fdt_getprop(gd->fdt_blob, nodeoffset, "amlogic,has-chip-id", NULL))
144                 return 0;
145
146         /* get regmap from the syscon node */
147         node = offset_to_ofnode(nodeoffset);
148         regmap = syscon_node_to_regmap(node);
149         if (IS_ERR(regmap)) {
150                 printf("%s: failed to get regmap\n", __func__);
151                 return 0;
152         }
153
154         /* read soc info */
155         ret = regmap_read(regmap, AO_SEC_SOCINFO_OFFSET, &socinfo);
156         if (ret && !socinfo) {
157                 printf("%s: invalid chipid value\n", __func__);
158                 return 0;
159         }
160
161         /* print board information */
162         print_board_model();
163         printf("SoC:   Amlogic Meson %s (%s) Revision %x:%x (%x:%x)\n",
164                socinfo_to_soc_id(socinfo),
165                socinfo_to_package_id(socinfo),
166                socinfo_to_major(socinfo),
167                socinfo_to_minor(socinfo),
168                socinfo_to_pack(socinfo),
169                socinfo_to_misc(socinfo));
170
171         return 0;
172 }