Skip to content

Commit 5e68c0f

Browse files
xdarklightkhilman
authored andcommitted
soc: amlogic: Add Meson6/Meson8/Meson8b/Meson8m2 SoC Information driver
Amlogic SoCs have an information register which contains the SoC type and revision information. This patchs adds support for decoding those registers and exposing the resulting information via the SoC bus infrastructure. Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com> Signed-off-by: Kevin Hilman <khilman@baylibre.com>
1 parent 2bd6bf0 commit 5e68c0f

File tree

3 files changed

+186
-0
lines changed

3 files changed

+186
-0
lines changed

drivers/soc/amlogic/Kconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,14 @@ config MESON_GX_SOCINFO
99
Say yes to support decoding of Amlogic Meson GX SoC family
1010
information about the type, package and version.
1111

12+
config MESON_MX_SOCINFO
13+
bool "Amlogic Meson MX SoC Information driver"
14+
depends on ARCH_MESON || COMPILE_TEST
15+
default ARCH_MESON
16+
select SOC_BUS
17+
help
18+
Say yes to support decoding of Amlogic Meson6, Meson8,
19+
Meson8b and Meson8m2 SoC family information about the type
20+
and version.
21+
1222
endmenu

drivers/soc/amlogic/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
obj-$(CONFIG_MESON_GX_SOCINFO) += meson-gx-socinfo.o
2+
obj-$(CONFIG_MESON_MX_SOCINFO) += meson-mx-socinfo.o
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
/*
2+
* Copyright (c) 2017 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
3+
*
4+
* SPDX-License-Identifier: GPL-2.0+
5+
*/
6+
7+
#include <linux/io.h>
8+
#include <linux/of.h>
9+
#include <linux/of_address.h>
10+
#include <linux/of_platform.h>
11+
#include <linux/platform_device.h>
12+
#include <linux/slab.h>
13+
#include <linux/sys_soc.h>
14+
#include <linux/bitfield.h>
15+
#include <linux/regmap.h>
16+
#include <linux/mfd/syscon.h>
17+
18+
#define MESON_SOCINFO_MAJOR_VER_MESON6 0x16
19+
#define MESON_SOCINFO_MAJOR_VER_MESON8 0x19
20+
#define MESON_SOCINFO_MAJOR_VER_MESON8B 0x1b
21+
22+
#define MESON_MX_ASSIST_HW_REV 0x14c
23+
24+
#define MESON_MX_ANALOG_TOP_METAL_REVISION 0x0
25+
26+
#define MESON_MX_BOOTROM_MISC_VER 0x4
27+
28+
static const char *meson_mx_socinfo_revision(unsigned int major_ver,
29+
unsigned int misc_ver,
30+
unsigned int metal_rev)
31+
{
32+
unsigned int minor_ver;
33+
34+
switch (major_ver) {
35+
case MESON_SOCINFO_MAJOR_VER_MESON6:
36+
minor_ver = 0xa;
37+
break;
38+
39+
case MESON_SOCINFO_MAJOR_VER_MESON8:
40+
if (metal_rev == 0x11111112)
41+
major_ver = 0x1d;
42+
43+
if (metal_rev == 0x11111111 || metal_rev == 0x11111112)
44+
minor_ver = 0xa;
45+
else if (metal_rev == 0x11111113)
46+
minor_ver = 0xb;
47+
else if (metal_rev == 0x11111133)
48+
minor_ver = 0xc;
49+
else
50+
minor_ver = 0xd;
51+
52+
break;
53+
54+
case MESON_SOCINFO_MAJOR_VER_MESON8B:
55+
if (metal_rev == 0x11111111)
56+
minor_ver = 0xa;
57+
else
58+
minor_ver = 0xb;
59+
60+
break;
61+
62+
default:
63+
minor_ver = 0x0;
64+
break;
65+
}
66+
67+
return kasprintf(GFP_KERNEL, "Rev%X (%x - 0:%X)", minor_ver, major_ver,
68+
misc_ver);
69+
}
70+
71+
static const char *meson_mx_socinfo_soc_id(unsigned int major_ver,
72+
unsigned int metal_rev)
73+
{
74+
const char *soc_id;
75+
76+
switch (major_ver) {
77+
case MESON_SOCINFO_MAJOR_VER_MESON6:
78+
soc_id = "Meson6 (AML8726-MX)";
79+
break;
80+
81+
case MESON_SOCINFO_MAJOR_VER_MESON8:
82+
if (metal_rev == 0x11111112)
83+
soc_id = "Meson8m2 (S812)";
84+
else
85+
soc_id = "Meson8 (S802)";
86+
87+
break;
88+
89+
case MESON_SOCINFO_MAJOR_VER_MESON8B:
90+
soc_id = "Meson8b (S805)";
91+
break;
92+
93+
default:
94+
soc_id = "Unknown";
95+
break;
96+
}
97+
98+
return kstrdup_const(soc_id, GFP_KERNEL);
99+
}
100+
101+
static const struct of_device_id meson_mx_socinfo_analog_top_ids[] = {
102+
{ .compatible = "amlogic,meson8-analog-top", },
103+
{ .compatible = "amlogic,meson8b-analog-top", },
104+
{ /* sentinel */ }
105+
};
106+
107+
int __init meson_mx_socinfo_init(void)
108+
{
109+
struct soc_device_attribute *soc_dev_attr;
110+
struct soc_device *soc_dev;
111+
struct device_node *np;
112+
struct regmap *assist_regmap, *bootrom_regmap, *analog_top_regmap;
113+
unsigned int major_ver, misc_ver, metal_rev = 0;
114+
int ret;
115+
116+
assist_regmap =
117+
syscon_regmap_lookup_by_compatible("amlogic,meson-mx-assist");
118+
if (IS_ERR(assist_regmap))
119+
return PTR_ERR(assist_regmap);
120+
121+
bootrom_regmap =
122+
syscon_regmap_lookup_by_compatible("amlogic,meson-mx-bootrom");
123+
if (IS_ERR(bootrom_regmap))
124+
return PTR_ERR(bootrom_regmap);
125+
126+
np = of_find_matching_node(NULL, meson_mx_socinfo_analog_top_ids);
127+
if (np) {
128+
analog_top_regmap = syscon_node_to_regmap(np);
129+
if (IS_ERR(analog_top_regmap))
130+
return PTR_ERR(analog_top_regmap);
131+
132+
ret = regmap_read(analog_top_regmap,
133+
MESON_MX_ANALOG_TOP_METAL_REVISION,
134+
&metal_rev);
135+
if (ret)
136+
return ret;
137+
}
138+
139+
ret = regmap_read(assist_regmap, MESON_MX_ASSIST_HW_REV, &major_ver);
140+
if (ret < 0)
141+
return ret;
142+
143+
ret = regmap_read(bootrom_regmap, MESON_MX_BOOTROM_MISC_VER,
144+
&misc_ver);
145+
if (ret < 0)
146+
return ret;
147+
148+
soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
149+
if (!soc_dev_attr)
150+
return -ENODEV;
151+
152+
soc_dev_attr->family = "Amlogic Meson";
153+
154+
np = of_find_node_by_path("/");
155+
of_property_read_string(np, "model", &soc_dev_attr->machine);
156+
of_node_put(np);
157+
158+
soc_dev_attr->revision = meson_mx_socinfo_revision(major_ver, misc_ver,
159+
metal_rev);
160+
soc_dev_attr->soc_id = meson_mx_socinfo_soc_id(major_ver, metal_rev);
161+
162+
soc_dev = soc_device_register(soc_dev_attr);
163+
if (IS_ERR(soc_dev)) {
164+
kfree_const(soc_dev_attr->revision);
165+
kfree_const(soc_dev_attr->soc_id);
166+
kfree(soc_dev_attr);
167+
return PTR_ERR(soc_dev);
168+
}
169+
170+
dev_info(soc_device_to_device(soc_dev), "Amlogic %s %s detected\n",
171+
soc_dev_attr->soc_id, soc_dev_attr->revision);
172+
173+
return 0;
174+
}
175+
device_initcall(meson_mx_socinfo_init);

0 commit comments

Comments
 (0)