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 <jonathanh@nvidia.com> Signed-off-by: Thierry Reding <treding@nvidia.com>
This commit is contained in:
parent
c78cf9956f
commit
379ac9eb1f
|
@ -300,6 +300,59 @@ static void tegra_enable_fuse_clk(void __iomem *base)
|
|||
writel(reg, base + 0x14);
|
||||
}
|
||||
|
||||
static ssize_t major_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return sprintf(buf, "%d\n", tegra_get_major_rev());
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RO(major);
|
||||
|
||||
static ssize_t minor_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return sprintf(buf, "%d\n", tegra_get_minor_rev());
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RO(minor);
|
||||
|
||||
static struct attribute *tegra_soc_attr[] = {
|
||||
&dev_attr_major.attr,
|
||||
&dev_attr_minor.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
const struct attribute_group tegra_soc_attr_group = {
|
||||
.attrs = tegra_soc_attr,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_ARCH_TEGRA_194_SOC
|
||||
static ssize_t platform_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
/*
|
||||
* Displays the value in the 'pre_si_platform' field of the HIDREV
|
||||
* register for Tegra194 devices. A value of 0 indicates that the
|
||||
* platform type is silicon and all other non-zero values indicate
|
||||
* the type of simulation platform is being used.
|
||||
*/
|
||||
return sprintf(buf, "%d\n", (tegra_read_chipid() >> 20) & 0xf);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RO(platform);
|
||||
|
||||
static struct attribute *tegra194_soc_attr[] = {
|
||||
&dev_attr_major.attr,
|
||||
&dev_attr_minor.attr,
|
||||
&dev_attr_platform.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
const struct attribute_group tegra194_soc_attr_group = {
|
||||
.attrs = tegra194_soc_attr,
|
||||
};
|
||||
#endif
|
||||
|
||||
struct device * __init tegra_soc_device_register(void)
|
||||
{
|
||||
struct soc_device_attribute *attr;
|
||||
|
@ -312,6 +365,7 @@ struct device * __init tegra_soc_device_register(void)
|
|||
attr->family = kasprintf(GFP_KERNEL, "Tegra");
|
||||
attr->revision = kasprintf(GFP_KERNEL, "%d", tegra_sku_info.revision);
|
||||
attr->soc_id = kasprintf(GFP_KERNEL, "%u", tegra_get_chip_id());
|
||||
attr->custom_attr_group = fuse->soc->soc_attr_group;
|
||||
|
||||
dev = soc_device_register(attr);
|
||||
if (IS_ERR(dev)) {
|
||||
|
|
|
@ -164,4 +164,5 @@ const struct tegra_fuse_soc tegra20_fuse_soc = {
|
|||
.speedo_init = tegra20_init_speedo_data,
|
||||
.probe = tegra20_fuse_probe,
|
||||
.info = &tegra20_fuse_info,
|
||||
.soc_attr_group = &tegra_soc_attr_group,
|
||||
};
|
||||
|
|
|
@ -111,6 +111,7 @@ const struct tegra_fuse_soc tegra30_fuse_soc = {
|
|||
.init = tegra30_fuse_init,
|
||||
.speedo_init = tegra30_init_speedo_data,
|
||||
.info = &tegra30_fuse_info,
|
||||
.soc_attr_group = &tegra_soc_attr_group,
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -125,6 +126,7 @@ const struct tegra_fuse_soc tegra114_fuse_soc = {
|
|||
.init = tegra30_fuse_init,
|
||||
.speedo_init = tegra114_init_speedo_data,
|
||||
.info = &tegra114_fuse_info,
|
||||
.soc_attr_group = &tegra_soc_attr_group,
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -205,6 +207,7 @@ const struct tegra_fuse_soc tegra124_fuse_soc = {
|
|||
.info = &tegra124_fuse_info,
|
||||
.lookups = tegra124_fuse_lookups,
|
||||
.num_lookups = ARRAY_SIZE(tegra124_fuse_lookups),
|
||||
.soc_attr_group = &tegra_soc_attr_group,
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -290,6 +293,7 @@ const struct tegra_fuse_soc tegra210_fuse_soc = {
|
|||
.info = &tegra210_fuse_info,
|
||||
.lookups = tegra210_fuse_lookups,
|
||||
.num_lookups = ARRAY_SIZE(tegra210_fuse_lookups),
|
||||
.soc_attr_group = &tegra_soc_attr_group,
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -319,6 +323,7 @@ const struct tegra_fuse_soc tegra186_fuse_soc = {
|
|||
.info = &tegra186_fuse_info,
|
||||
.lookups = tegra186_fuse_lookups,
|
||||
.num_lookups = ARRAY_SIZE(tegra186_fuse_lookups),
|
||||
.soc_attr_group = &tegra_soc_attr_group,
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -348,5 +353,6 @@ const struct tegra_fuse_soc tegra194_fuse_soc = {
|
|||
.info = &tegra194_fuse_info,
|
||||
.lookups = tegra194_fuse_lookups,
|
||||
.num_lookups = ARRAY_SIZE(tegra194_fuse_lookups),
|
||||
.soc_attr_group = &tegra194_soc_attr_group,
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -32,6 +32,8 @@ struct tegra_fuse_soc {
|
|||
|
||||
const struct nvmem_cell_lookup *lookups;
|
||||
unsigned int num_lookups;
|
||||
|
||||
const struct attribute_group *soc_attr_group;
|
||||
};
|
||||
|
||||
struct tegra_fuse {
|
||||
|
@ -64,6 +66,11 @@ void tegra_init_apbmisc(void);
|
|||
bool __init tegra_fuse_read_spare(unsigned int spare);
|
||||
u32 __init tegra_fuse_read_early(unsigned int offset);
|
||||
|
||||
u8 tegra_get_major_rev(void);
|
||||
u8 tegra_get_minor_rev(void);
|
||||
|
||||
extern const struct attribute_group tegra_soc_attr_group;
|
||||
|
||||
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
|
||||
void tegra20_init_speedo_data(struct tegra_sku_info *sku_info);
|
||||
#endif
|
||||
|
@ -110,6 +117,7 @@ extern const struct tegra_fuse_soc tegra186_fuse_soc;
|
|||
|
||||
#ifdef CONFIG_ARCH_TEGRA_194_SOC
|
||||
extern const struct tegra_fuse_soc tegra194_fuse_soc;
|
||||
extern const struct attribute_group tegra194_soc_attr_group;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -37,6 +37,16 @@ u8 tegra_get_chip_id(void)
|
|||
return (tegra_read_chipid() >> 8) & 0xff;
|
||||
}
|
||||
|
||||
u8 tegra_get_major_rev(void)
|
||||
{
|
||||
return (tegra_read_chipid() >> 4) & 0xf;
|
||||
}
|
||||
|
||||
u8 tegra_get_minor_rev(void)
|
||||
{
|
||||
return (tegra_read_chipid() >> 16) & 0xf;
|
||||
}
|
||||
|
||||
u32 tegra_read_straps(void)
|
||||
{
|
||||
WARN(!chipid, "Tegra ABP MISC not yet available\n");
|
||||
|
|
Loading…
Reference in New Issue