summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/fuse.c
diff options
context:
space:
mode:
authorHiro Sugawara <hsugawara@nvidia.com>2011-04-04 15:53:35 -0700
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:42:29 -0800
commitdfa19fda0eaacab6549a553aa42e807d9594b39c (patch)
tree8c8bf5403ad389d30643a4c3630ff5d30c980af3 /arch/arm/mach-tegra/fuse.c
parent036ff33ba0fbe4b8660ee3e151eebffe24ed1bc3 (diff)
ARM: tegra: chipid: Parse and save Tegra chip ID passed by fastboot
Original-Change-Id: Ibb00d64820cc81b6af08c4ac7266d2df94bd6a1e Reviewed-on: http://git-master/r/26631 Tested-by: Hiro Sugawara <hsugawara@nvidia.com> Reviewed-by: Krishna Reddy <vdumpa@nvidia.com> Reviewed-by: Scott Williams <scwilliams@nvidia.com> Original-Change-Id: Idc50a6f9891bc61f19e1f282480519ffccf11ad4 Rebase-Id: R787474379574ab1e081e49528af749709856b682
Diffstat (limited to 'arch/arm/mach-tegra/fuse.c')
-rw-r--r--arch/arm/mach-tegra/fuse.c87
1 files changed, 82 insertions, 5 deletions
diff --git a/arch/arm/mach-tegra/fuse.c b/arch/arm/mach-tegra/fuse.c
index 21224c292d7d..ae9beaf9c867 100644
--- a/arch/arm/mach-tegra/fuse.c
+++ b/arch/arm/mach-tegra/fuse.c
@@ -2,7 +2,7 @@
* arch/arm/mach-tegra/fuse.c
*
* Copyright (C) 2010 Google, Inc.
- * Copyright (C) 2010-2011 NVIDIA, Corp.
+ * Copyright (C) 2010-2011 NVIDIA Corp.
*
* Author:
* Colin Cross <ccross@android.com>
@@ -20,6 +20,7 @@
#include <linux/kernel.h>
#include <linux/io.h>
+#include <linux/init.h>
#include <mach/iomap.h>
@@ -191,12 +192,38 @@ int tegra_sku_id(void)
return sku_id;
}
-enum tegra_revision tegra_get_revision(void)
+struct tegra_id tegra_id;
+
+static enum tegra_revision tegra_decode_revision(const struct tegra_id *id)
{
- void __iomem *chip_id = IO_ADDRESS(TEGRA_APB_MISC_BASE) + 0x804;
- u32 id = readl(chip_id);
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+ if ((id->chipid & 0xf0) != 0x20)
+ return TEGRA_REVISION_UNKNOWN;
+#endif
+#ifdef CONFIG_ARCH_TEGRA_3x_SOC
+ if ((id->chipid & 0xf0) != 0x30)
+ return TEGRA_REVISION_UNKNOWN;
+
+ switch (id->major) {
+ case 0:
+ if (id->minor != 1)
+ return TEGRA_REVISION_UNKNOWN;
+ else if (id->netlist == 12 && (id->patch & 0xf) == 12)
+ return TEGRA_REVISION_A01;
+ else if (id->netlist == 12 && (id->patch & 0xf) > 12)
+ return TEGRA_REVISION_A02;
+ else if (id->netlist > 12)
+ return TEGRA_REVISION_A02;
+ else
+ return TEGRA_REVISION_UNKNOWN;
+ case 1:
+ break;
+ default:
+ return TEGRA_REVISION_UNKNOWN;
+ }
+#endif
- switch ((id >> 16) & 0xf) {
+ switch (id->minor) {
#ifdef CONFIG_ARCH_TEGRA_3x_SOC
case 1:
return TEGRA_REVISION_A01;
@@ -214,3 +241,53 @@ enum tegra_revision tegra_get_revision(void)
return TEGRA_REVISION_UNKNOWN;
}
}
+
+static enum tegra_revision tegra_set_revision(u32 chipid,
+ u32 major, u32 minor,
+ u32 nlist, u32 patch)
+{
+ tegra_id.chipid = chipid;
+ tegra_id.major = major;
+ tegra_id.minor = minor;
+ tegra_id.netlist = nlist;
+ tegra_id.patch = patch;
+ tegra_id.revision = tegra_decode_revision(&tegra_id);
+ return tegra_id.revision;
+}
+
+enum tegra_revision tegra_get_revision(void)
+{
+ if (tegra_id.chipid)
+ return tegra_id.revision;
+ else {/* Boot loader did not pass a valid chip ID */
+ void __iomem *chip_id = IO_ADDRESS(TEGRA_APB_MISC_BASE) + 0x804;
+ void __iomem *netlist = IO_ADDRESS(TEGRA_APB_MISC_BASE) + 0x860;
+ u32 cid = readl(chip_id);
+ u32 nlist = readl(netlist);
+
+ return tegra_set_revision((cid >> 8) & 0xff,
+ (cid >> 4) & 0xf,
+ (cid >> 16) & 0xf,
+ (nlist >> 0) & 0xffff,
+ (nlist >> 16) & 0xffff);
+ }
+}
+
+static int __init tegra_bootloader_tegraid(char *str)
+{
+ u32 id[5];
+ int i = 0;
+
+ do {
+ id[i++] = simple_strtoul(str, &str, 16);
+ } while (*str++ && i < ARRAY_SIZE(id));
+
+ while (i < ARRAY_SIZE(id))
+ id[i++] = 0;
+
+ (void)tegra_set_revision(id[0], id[1], id[2], id[3], id[4]);
+ return 0;
+}
+
+/* tegraid=chipid.major.minor.netlist.patch */
+early_param("tegraid", tegra_bootloader_tegraid);