Skip to content

Commit 379ac9e

Browse files
jonhunterthierryreding
authored andcommitted
soc/tegra: fuse: Add custom SoC attributes
Add a custom SoC attribute for Tegra to expose the HIDREV register fields to userspace via the sysfs. This register provides additional details about the type of device (eg, silicon, FPGA, etc) as well as revision. Exposing this information is useful for identifying the exact device revision and device type. For Tegra devices up until Tegra186, the majorrev and minorrev fields of the HIDREV register are used to determine the device revision and device type. For Tegra194, the majorrev and minorrev fields only determine the revision. Starting with Tegra194, there is an additional field, pre_si_platform (which occupies bits 20-23), that now determines device type. Therefore, for all Tegra devices, add a custom SoC attribute for the majorrev and minorrev fields and for Tegra194 add an additional attribute for the pre_si_platform field. Signed-off-by: Jon Hunter <[email protected]> Signed-off-by: Thierry Reding <[email protected]>
1 parent c78cf99 commit 379ac9e

File tree

5 files changed

+79
-0
lines changed

5 files changed

+79
-0
lines changed

drivers/soc/tegra/fuse/fuse-tegra.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,59 @@ static void tegra_enable_fuse_clk(void __iomem *base)
300300
writel(reg, base + 0x14);
301301
}
302302

303+
static ssize_t major_show(struct device *dev, struct device_attribute *attr,
304+
char *buf)
305+
{
306+
return sprintf(buf, "%d\n", tegra_get_major_rev());
307+
}
308+
309+
static DEVICE_ATTR_RO(major);
310+
311+
static ssize_t minor_show(struct device *dev, struct device_attribute *attr,
312+
char *buf)
313+
{
314+
return sprintf(buf, "%d\n", tegra_get_minor_rev());
315+
}
316+
317+
static DEVICE_ATTR_RO(minor);
318+
319+
static struct attribute *tegra_soc_attr[] = {
320+
&dev_attr_major.attr,
321+
&dev_attr_minor.attr,
322+
NULL,
323+
};
324+
325+
const struct attribute_group tegra_soc_attr_group = {
326+
.attrs = tegra_soc_attr,
327+
};
328+
329+
#ifdef CONFIG_ARCH_TEGRA_194_SOC
330+
static ssize_t platform_show(struct device *dev, struct device_attribute *attr,
331+
char *buf)
332+
{
333+
/*
334+
* Displays the value in the 'pre_si_platform' field of the HIDREV
335+
* register for Tegra194 devices. A value of 0 indicates that the
336+
* platform type is silicon and all other non-zero values indicate
337+
* the type of simulation platform is being used.
338+
*/
339+
return sprintf(buf, "%d\n", (tegra_read_chipid() >> 20) & 0xf);
340+
}
341+
342+
static DEVICE_ATTR_RO(platform);
343+
344+
static struct attribute *tegra194_soc_attr[] = {
345+
&dev_attr_major.attr,
346+
&dev_attr_minor.attr,
347+
&dev_attr_platform.attr,
348+
NULL,
349+
};
350+
351+
const struct attribute_group tegra194_soc_attr_group = {
352+
.attrs = tegra194_soc_attr,
353+
};
354+
#endif
355+
303356
struct device * __init tegra_soc_device_register(void)
304357
{
305358
struct soc_device_attribute *attr;
@@ -312,6 +365,7 @@ struct device * __init tegra_soc_device_register(void)
312365
attr->family = kasprintf(GFP_KERNEL, "Tegra");
313366
attr->revision = kasprintf(GFP_KERNEL, "%d", tegra_sku_info.revision);
314367
attr->soc_id = kasprintf(GFP_KERNEL, "%u", tegra_get_chip_id());
368+
attr->custom_attr_group = fuse->soc->soc_attr_group;
315369

316370
dev = soc_device_register(attr);
317371
if (IS_ERR(dev)) {

drivers/soc/tegra/fuse/fuse-tegra20.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,4 +164,5 @@ const struct tegra_fuse_soc tegra20_fuse_soc = {
164164
.speedo_init = tegra20_init_speedo_data,
165165
.probe = tegra20_fuse_probe,
166166
.info = &tegra20_fuse_info,
167+
.soc_attr_group = &tegra_soc_attr_group,
167168
};

drivers/soc/tegra/fuse/fuse-tegra30.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ const struct tegra_fuse_soc tegra30_fuse_soc = {
111111
.init = tegra30_fuse_init,
112112
.speedo_init = tegra30_init_speedo_data,
113113
.info = &tegra30_fuse_info,
114+
.soc_attr_group = &tegra_soc_attr_group,
114115
};
115116
#endif
116117

@@ -125,6 +126,7 @@ const struct tegra_fuse_soc tegra114_fuse_soc = {
125126
.init = tegra30_fuse_init,
126127
.speedo_init = tegra114_init_speedo_data,
127128
.info = &tegra114_fuse_info,
129+
.soc_attr_group = &tegra_soc_attr_group,
128130
};
129131
#endif
130132

@@ -205,6 +207,7 @@ const struct tegra_fuse_soc tegra124_fuse_soc = {
205207
.info = &tegra124_fuse_info,
206208
.lookups = tegra124_fuse_lookups,
207209
.num_lookups = ARRAY_SIZE(tegra124_fuse_lookups),
210+
.soc_attr_group = &tegra_soc_attr_group,
208211
};
209212
#endif
210213

@@ -290,6 +293,7 @@ const struct tegra_fuse_soc tegra210_fuse_soc = {
290293
.info = &tegra210_fuse_info,
291294
.lookups = tegra210_fuse_lookups,
292295
.num_lookups = ARRAY_SIZE(tegra210_fuse_lookups),
296+
.soc_attr_group = &tegra_soc_attr_group,
293297
};
294298
#endif
295299

@@ -319,6 +323,7 @@ const struct tegra_fuse_soc tegra186_fuse_soc = {
319323
.info = &tegra186_fuse_info,
320324
.lookups = tegra186_fuse_lookups,
321325
.num_lookups = ARRAY_SIZE(tegra186_fuse_lookups),
326+
.soc_attr_group = &tegra_soc_attr_group,
322327
};
323328
#endif
324329

@@ -348,5 +353,6 @@ const struct tegra_fuse_soc tegra194_fuse_soc = {
348353
.info = &tegra194_fuse_info,
349354
.lookups = tegra194_fuse_lookups,
350355
.num_lookups = ARRAY_SIZE(tegra194_fuse_lookups),
356+
.soc_attr_group = &tegra194_soc_attr_group,
351357
};
352358
#endif

drivers/soc/tegra/fuse/fuse.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ struct tegra_fuse_soc {
3232

3333
const struct nvmem_cell_lookup *lookups;
3434
unsigned int num_lookups;
35+
36+
const struct attribute_group *soc_attr_group;
3537
};
3638

3739
struct tegra_fuse {
@@ -64,6 +66,11 @@ void tegra_init_apbmisc(void);
6466
bool __init tegra_fuse_read_spare(unsigned int spare);
6567
u32 __init tegra_fuse_read_early(unsigned int offset);
6668

69+
u8 tegra_get_major_rev(void);
70+
u8 tegra_get_minor_rev(void);
71+
72+
extern const struct attribute_group tegra_soc_attr_group;
73+
6774
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
6875
void tegra20_init_speedo_data(struct tegra_sku_info *sku_info);
6976
#endif
@@ -110,6 +117,7 @@ extern const struct tegra_fuse_soc tegra186_fuse_soc;
110117

111118
#ifdef CONFIG_ARCH_TEGRA_194_SOC
112119
extern const struct tegra_fuse_soc tegra194_fuse_soc;
120+
extern const struct attribute_group tegra194_soc_attr_group;
113121
#endif
114122

115123
#endif

drivers/soc/tegra/fuse/tegra-apbmisc.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,16 @@ u8 tegra_get_chip_id(void)
3737
return (tegra_read_chipid() >> 8) & 0xff;
3838
}
3939

40+
u8 tegra_get_major_rev(void)
41+
{
42+
return (tegra_read_chipid() >> 4) & 0xf;
43+
}
44+
45+
u8 tegra_get_minor_rev(void)
46+
{
47+
return (tegra_read_chipid() >> 16) & 0xf;
48+
}
49+
4050
u32 tegra_read_straps(void)
4151
{
4252
WARN(!chipid, "Tegra ABP MISC not yet available\n");

0 commit comments

Comments
 (0)