aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-tegra/fuse.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-tegra/fuse.c')
-rw-r--r--arch/arm/mach-tegra/fuse.c49
1 files changed, 38 insertions, 11 deletions
diff --git a/arch/arm/mach-tegra/fuse.c b/arch/arm/mach-tegra/fuse.c
index 6c752e8f1f06..8121742711fe 100644
--- a/arch/arm/mach-tegra/fuse.c
+++ b/arch/arm/mach-tegra/fuse.c
@@ -28,14 +28,21 @@
28#define FUSE_UID_LOW 0x108 28#define FUSE_UID_LOW 0x108
29#define FUSE_UID_HIGH 0x10c 29#define FUSE_UID_HIGH 0x10c
30#define FUSE_SKU_INFO 0x110 30#define FUSE_SKU_INFO 0x110
31#define FUSE_SPARE_BIT 0x200 31
32#define TEGRA20_FUSE_SPARE_BIT 0x200
33#define TEGRA30_FUSE_SPARE_BIT 0x244
32 34
33int tegra_sku_id; 35int tegra_sku_id;
34int tegra_cpu_process_id; 36int tegra_cpu_process_id;
35int tegra_core_process_id; 37int tegra_core_process_id;
36int tegra_chip_id; 38int tegra_chip_id;
39int tegra_cpu_speedo_id; /* only exist in Tegra30 and later */
40int tegra_soc_speedo_id;
37enum tegra_revision tegra_revision; 41enum tegra_revision tegra_revision;
38 42
43static int tegra_fuse_spare_bit;
44static void (*tegra_init_speedo_data)(void);
45
39/* The BCT to use at boot is specified by board straps that can be read 46/* The BCT to use at boot is specified by board straps that can be read
40 * through a APB misc register and decoded. 2 bits, i.e. 4 possible BCTs. 47 * through a APB misc register and decoded. 2 bits, i.e. 4 possible BCTs.
41 */ 48 */
@@ -56,14 +63,14 @@ static const char *tegra_revision_name[TEGRA_REVISION_MAX] = {
56 [TEGRA_REVISION_A04] = "A04", 63 [TEGRA_REVISION_A04] = "A04",
57}; 64};
58 65
59static inline u32 tegra_fuse_readl(unsigned long offset) 66u32 tegra_fuse_readl(unsigned long offset)
60{ 67{
61 return tegra_apb_readl(TEGRA_FUSE_BASE + offset); 68 return tegra_apb_readl(TEGRA_FUSE_BASE + offset);
62} 69}
63 70
64static inline bool get_spare_fuse(int bit) 71bool tegra_spare_fuse(int bit)
65{ 72{
66 return tegra_fuse_readl(FUSE_SPARE_BIT + bit * 4); 73 return tegra_fuse_readl(tegra_fuse_spare_bit + bit * 4);
67} 74}
68 75
69static enum tegra_revision tegra_get_revision(u32 id) 76static enum tegra_revision tegra_get_revision(u32 id)
@@ -77,7 +84,7 @@ static enum tegra_revision tegra_get_revision(u32 id)
77 return TEGRA_REVISION_A02; 84 return TEGRA_REVISION_A02;
78 case 3: 85 case 3:
79 if (tegra_chip_id == TEGRA20 && 86 if (tegra_chip_id == TEGRA20 &&
80 (get_spare_fuse(18) || get_spare_fuse(19))) 87 (tegra_spare_fuse(18) || tegra_spare_fuse(19)))
81 return TEGRA_REVISION_A03p; 88 return TEGRA_REVISION_A03p;
82 else 89 else
83 return TEGRA_REVISION_A03; 90 return TEGRA_REVISION_A03;
@@ -88,6 +95,16 @@ static enum tegra_revision tegra_get_revision(u32 id)
88 } 95 }
89} 96}
90 97
98static void tegra_get_process_id(void)
99{
100 u32 reg;
101
102 reg = tegra_fuse_readl(tegra_fuse_spare_bit);
103 tegra_cpu_process_id = (reg >> 6) & 3;
104 reg = tegra_fuse_readl(tegra_fuse_spare_bit);
105 tegra_core_process_id = (reg >> 12) & 3;
106}
107
91void tegra_init_fuse(void) 108void tegra_init_fuse(void)
92{ 109{
93 u32 id; 110 u32 id;
@@ -99,19 +116,29 @@ void tegra_init_fuse(void)
99 reg = tegra_fuse_readl(FUSE_SKU_INFO); 116 reg = tegra_fuse_readl(FUSE_SKU_INFO);
100 tegra_sku_id = reg & 0xFF; 117 tegra_sku_id = reg & 0xFF;
101 118
102 reg = tegra_fuse_readl(FUSE_SPARE_BIT);
103 tegra_cpu_process_id = (reg >> 6) & 3;
104
105 reg = tegra_fuse_readl(FUSE_SPARE_BIT);
106 tegra_core_process_id = (reg >> 12) & 3;
107
108 reg = tegra_apb_readl(TEGRA_APB_MISC_BASE + STRAP_OPT); 119 reg = tegra_apb_readl(TEGRA_APB_MISC_BASE + STRAP_OPT);
109 tegra_bct_strapping = (reg & RAM_ID_MASK) >> RAM_CODE_SHIFT; 120 tegra_bct_strapping = (reg & RAM_ID_MASK) >> RAM_CODE_SHIFT;
110 121
111 id = readl_relaxed(IO_ADDRESS(TEGRA_APB_MISC_BASE) + 0x804); 122 id = readl_relaxed(IO_ADDRESS(TEGRA_APB_MISC_BASE) + 0x804);
112 tegra_chip_id = (id >> 8) & 0xff; 123 tegra_chip_id = (id >> 8) & 0xff;
113 124
125 switch (tegra_chip_id) {
126 case TEGRA20:
127 tegra_fuse_spare_bit = TEGRA20_FUSE_SPARE_BIT;
128 tegra_init_speedo_data = &tegra20_init_speedo_data;
129 break;
130 case TEGRA30:
131 tegra_fuse_spare_bit = TEGRA30_FUSE_SPARE_BIT;
132 tegra_init_speedo_data = &tegra30_init_speedo_data;
133 break;
134 default:
135 pr_warn("Tegra: unknown chip id %d\n", tegra_chip_id);
136 tegra_fuse_spare_bit = TEGRA20_FUSE_SPARE_BIT;
137 tegra_init_speedo_data = &tegra_get_process_id;
138 }
139
114 tegra_revision = tegra_get_revision(id); 140 tegra_revision = tegra_get_revision(id);
141 tegra_init_speedo_data();
115 142
116 pr_info("Tegra Revision: %s SKU: %d CPU Process: %d Core Process: %d\n", 143 pr_info("Tegra Revision: %s SKU: %d CPU Process: %d Core Process: %d\n",
117 tegra_revision_name[tegra_revision], 144 tegra_revision_name[tegra_revision],