aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-tegra/fuse.c85
-rw-r--r--arch/arm/mach-tegra/fuse.h32
-rw-r--r--arch/arm/mach-tegra/tegra2_clocks.c2
3 files changed, 86 insertions, 33 deletions
diff --git a/arch/arm/mach-tegra/fuse.c b/arch/arm/mach-tegra/fuse.c
index daf3f572acc8..b1895c53ed60 100644
--- a/arch/arm/mach-tegra/fuse.c
+++ b/arch/arm/mach-tegra/fuse.c
@@ -30,20 +30,75 @@
30#define FUSE_SKU_INFO 0x110 30#define FUSE_SKU_INFO 0x110
31#define FUSE_SPARE_BIT 0x200 31#define FUSE_SPARE_BIT 0x200
32 32
33int tegra_sku_id;
34int tegra_cpu_process_id;
35int tegra_core_process_id;
36enum tegra_revision tegra_revision;
37
38static const char *tegra_revision_name[TEGRA_REVISION_MAX] = {
39 [TEGRA_REVISION_UNKNOWN] = "unknown",
40 [TEGRA_REVISION_A01] = "A01",
41 [TEGRA_REVISION_A02] = "A02",
42 [TEGRA_REVISION_A03] = "A03",
43 [TEGRA_REVISION_A03p] = "A03 prime",
44 [TEGRA_REVISION_A04] = "A04",
45};
46
33static inline u32 tegra_fuse_readl(unsigned long offset) 47static inline u32 tegra_fuse_readl(unsigned long offset)
34{ 48{
35 return tegra_apb_readl(TEGRA_FUSE_BASE + offset); 49 return tegra_apb_readl(TEGRA_FUSE_BASE + offset);
36} 50}
37 51
52static inline bool get_spare_fuse(int bit)
53{
54 return tegra_fuse_readl(FUSE_SPARE_BIT + bit * 4);
55}
56
57static enum tegra_revision tegra_get_revision(void)
58{
59 void __iomem *chip_id = IO_ADDRESS(TEGRA_APB_MISC_BASE) + 0x804;
60 u32 id = readl(chip_id);
61 u32 minor_rev = (id >> 16) & 0xf;
62 u32 chipid = (id >> 8) & 0xff;
63
64 switch (minor_rev) {
65 case 1:
66 return TEGRA_REVISION_A01;
67 case 2:
68 return TEGRA_REVISION_A02;
69 case 3:
70 if (chipid == 0x20 && (get_spare_fuse(18) || get_spare_fuse(19)))
71 return TEGRA_REVISION_A03p;
72 else
73 return TEGRA_REVISION_A03;
74 case 4:
75 return TEGRA_REVISION_A04;
76 default:
77 return TEGRA_REVISION_UNKNOWN;
78 }
79}
80
38void tegra_init_fuse(void) 81void tegra_init_fuse(void)
39{ 82{
40 u32 reg = readl(IO_TO_VIRT(TEGRA_CLK_RESET_BASE + 0x48)); 83 u32 reg = readl(IO_TO_VIRT(TEGRA_CLK_RESET_BASE + 0x48));
41 reg |= 1 << 28; 84 reg |= 1 << 28;
42 writel(reg, IO_TO_VIRT(TEGRA_CLK_RESET_BASE + 0x48)); 85 writel(reg, IO_TO_VIRT(TEGRA_CLK_RESET_BASE + 0x48));
43 86
44 pr_info("Tegra SKU: %d CPU Process: %d Core Process: %d\n", 87 reg = tegra_fuse_readl(FUSE_SKU_INFO);
45 tegra_sku_id(), tegra_cpu_process_id(), 88 tegra_sku_id = reg & 0xFF;
46 tegra_core_process_id()); 89
90 reg = tegra_fuse_readl(FUSE_SPARE_BIT);
91 tegra_cpu_process_id = (reg >> 6) & 3;
92
93 reg = tegra_fuse_readl(FUSE_SPARE_BIT);
94 tegra_core_process_id = (reg >> 12) & 3;
95
96 tegra_revision = tegra_get_revision();
97
98 pr_info("Tegra Revision: %s SKU: %d CPU Process: %d Core Process: %d\n",
99 tegra_revision_name[tegra_get_revision()],
100 tegra_sku_id, tegra_cpu_process_id,
101 tegra_core_process_id);
47} 102}
48 103
49unsigned long long tegra_chip_uid(void) 104unsigned long long tegra_chip_uid(void)
@@ -54,27 +109,3 @@ unsigned long long tegra_chip_uid(void)
54 hi = tegra_fuse_readl(FUSE_UID_HIGH); 109 hi = tegra_fuse_readl(FUSE_UID_HIGH);
55 return (hi << 32ull) | lo; 110 return (hi << 32ull) | lo;
56} 111}
57
58int tegra_sku_id(void)
59{
60 int sku_id;
61 u32 reg = tegra_fuse_readl(FUSE_SKU_INFO);
62 sku_id = reg & 0xFF;
63 return sku_id;
64}
65
66int tegra_cpu_process_id(void)
67{
68 int cpu_process_id;
69 u32 reg = tegra_fuse_readl(FUSE_SPARE_BIT);
70 cpu_process_id = (reg >> 6) & 3;
71 return cpu_process_id;
72}
73
74int tegra_core_process_id(void)
75{
76 int core_process_id;
77 u32 reg = tegra_fuse_readl(FUSE_SPARE_BIT);
78 core_process_id = (reg >> 12) & 3;
79 return core_process_id;
80}
diff --git a/arch/arm/mach-tegra/fuse.h b/arch/arm/mach-tegra/fuse.h
index 584b2e27dbda..7576aaf6865c 100644
--- a/arch/arm/mach-tegra/fuse.h
+++ b/arch/arm/mach-tegra/fuse.h
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/arm/mach-tegra/fuse.c
3 *
4 * Copyright (C) 2010 Google, Inc. 2 * Copyright (C) 2010 Google, Inc.
5 * 3 *
6 * Author: 4 * Author:
@@ -17,8 +15,32 @@
17 * 15 *
18 */ 16 */
19 17
18#ifndef __MACH_TEGRA_FUSE_H
19#define __MACH_TEGRA_FUSE_H
20
21enum tegra_revision {
22 TEGRA_REVISION_UNKNOWN = 0,
23 TEGRA_REVISION_A01,
24 TEGRA_REVISION_A02,
25 TEGRA_REVISION_A03,
26 TEGRA_REVISION_A03p,
27 TEGRA_REVISION_A04,
28 TEGRA_REVISION_MAX,
29};
30
31#define SKU_ID_T20 8
32#define SKU_ID_T25SE 20
33#define SKU_ID_AP25 23
34#define SKU_ID_T25 24
35#define SKU_ID_AP25E 27
36#define SKU_ID_T25E 28
37
38extern int tegra_sku_id;
39extern int tegra_cpu_process_id;
40extern int tegra_core_process_id;
41extern enum tegra_revision tegra_revision;
42
20unsigned long long tegra_chip_uid(void); 43unsigned long long tegra_chip_uid(void);
21int tegra_sku_id(void);
22int tegra_cpu_process_id(void);
23int tegra_core_process_id(void);
24void tegra_init_fuse(void); 44void tegra_init_fuse(void);
45
46#endif
diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c
index ff9e6b6c0460..74d314fdf2f9 100644
--- a/arch/arm/mach-tegra/tegra2_clocks.c
+++ b/arch/arm/mach-tegra/tegra2_clocks.c
@@ -720,7 +720,7 @@ static void tegra2_pllx_clk_init(struct clk *c)
720{ 720{
721 tegra2_pll_clk_init(c); 721 tegra2_pll_clk_init(c);
722 722
723 if (tegra_sku_id() == 7) 723 if (tegra_sku_id == 7)
724 c->max_rate = 750000000; 724 c->max_rate = 750000000;
725} 725}
726 726