aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap1/id.c
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2005-07-10 14:58:12 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2005-07-10 14:58:12 -0400
commitf577ffd75c02b6087d5bf5ca89f806b10f2a0246 (patch)
tree9dc99ecfe14981cbe057ebaf35e40b5797f1211a /arch/arm/mach-omap1/id.c
parentdbdf9cedfcc81202360763530412d746d798b7b6 (diff)
[PATCH] ARM: 2801/1: OMAP update 6/11: Split OMAP1 common code into id, io and serial
Patch from Tony Lindgren This patch by Juha Yrjölä and other OMAP developers splits OMAP1 specific common code into OMAP1 id, io, and serial code in mach-omap1 directory. Signed-off-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-omap1/id.c')
-rw-r--r--arch/arm/mach-omap1/id.c188
1 files changed, 188 insertions, 0 deletions
diff --git a/arch/arm/mach-omap1/id.c b/arch/arm/mach-omap1/id.c
new file mode 100644
index 000000000000..986c3b7e09bb
--- /dev/null
+++ b/arch/arm/mach-omap1/id.c
@@ -0,0 +1,188 @@
1/*
2 * linux/arch/arm/mach-omap1/id.c
3 *
4 * OMAP1 CPU identification code
5 *
6 * Copyright (C) 2004 Nokia Corporation
7 * Written by Tony Lindgren <tony@atomide.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/config.h>
15#include <linux/module.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18
19#include <asm/io.h>
20
21struct omap_id {
22 u16 jtag_id; /* Used to determine OMAP type */
23 u8 die_rev; /* Processor revision */
24 u32 omap_id; /* OMAP revision */
25 u32 type; /* Cpu id bits [31:08], cpu class bits [07:00] */
26};
27
28/* Register values to detect the OMAP version */
29static struct omap_id omap_ids[] __initdata = {
30 { .jtag_id = 0x355f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300100},
31 { .jtag_id = 0xb55f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300300},
32 { .jtag_id = 0xb470, .die_rev = 0x0, .omap_id = 0x03310100, .type = 0x15100000},
33 { .jtag_id = 0xb576, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x16100000},
34 { .jtag_id = 0xb576, .die_rev = 0x2, .omap_id = 0x03320100, .type = 0x16110000},
35 { .jtag_id = 0xb576, .die_rev = 0x3, .omap_id = 0x03320100, .type = 0x16100c00},
36 { .jtag_id = 0xb576, .die_rev = 0x0, .omap_id = 0x03320200, .type = 0x16100d00},
37 { .jtag_id = 0xb613, .die_rev = 0x0, .omap_id = 0x03320300, .type = 0x1610ef00},
38 { .jtag_id = 0xb613, .die_rev = 0x0, .omap_id = 0x03320300, .type = 0x1610ef00},
39 { .jtag_id = 0xb576, .die_rev = 0x1, .omap_id = 0x03320100, .type = 0x16110000},
40 { .jtag_id = 0xb58c, .die_rev = 0x2, .omap_id = 0x03320200, .type = 0x16110b00},
41 { .jtag_id = 0xb58c, .die_rev = 0x3, .omap_id = 0x03320200, .type = 0x16110c00},
42 { .jtag_id = 0xb65f, .die_rev = 0x0, .omap_id = 0x03320400, .type = 0x16212300},
43 { .jtag_id = 0xb65f, .die_rev = 0x1, .omap_id = 0x03320400, .type = 0x16212300},
44 { .jtag_id = 0xb65f, .die_rev = 0x1, .omap_id = 0x03320500, .type = 0x16212300},
45 { .jtag_id = 0xb5f7, .die_rev = 0x0, .omap_id = 0x03330000, .type = 0x17100000},
46 { .jtag_id = 0xb5f7, .die_rev = 0x1, .omap_id = 0x03330100, .type = 0x17100000},
47 { .jtag_id = 0xb5f7, .die_rev = 0x2, .omap_id = 0x03330100, .type = 0x17100000},
48};
49
50/*
51 * Get OMAP type from PROD_ID.
52 * 1710 has the PROD_ID in bits 15:00, not in 16:01 as documented in TRM.
53 * 1510 PROD_ID is empty, and 1610 PROD_ID does not make sense.
54 * Undocumented register in TEST BLOCK is used as fallback; This seems to
55 * work on 1510, 1610 & 1710. The official way hopefully will work in future
56 * processors.
57 */
58static u16 __init omap_get_jtag_id(void)
59{
60 u32 prod_id, omap_id;
61
62 prod_id = omap_readl(OMAP_PRODUCTION_ID_1);
63 omap_id = omap_readl(OMAP32_ID_1);
64
65 /* Check for unusable OMAP_PRODUCTION_ID_1 on 1611B/5912 and 730 */
66 if (((prod_id >> 20) == 0) || (prod_id == omap_id))
67 prod_id = 0;
68 else
69 prod_id &= 0xffff;
70
71 if (prod_id)
72 return prod_id;
73
74 /* Use OMAP32_ID_1 as fallback */
75 prod_id = ((omap_id >> 12) & 0xffff);
76
77 return prod_id;
78}
79
80/*
81 * Get OMAP revision from DIE_REV.
82 * Early 1710 processors may have broken OMAP_DIE_ID, it contains PROD_ID.
83 * Undocumented register in the TEST BLOCK is used as fallback.
84 * REVISIT: This does not seem to work on 1510
85 */
86static u8 __init omap_get_die_rev(void)
87{
88 u32 die_rev;
89
90 die_rev = omap_readl(OMAP_DIE_ID_1);
91
92 /* Check for broken OMAP_DIE_ID on early 1710 */
93 if (((die_rev >> 12) & 0xffff) == omap_get_jtag_id())
94 die_rev = 0;
95
96 die_rev = (die_rev >> 17) & 0xf;
97 if (die_rev)
98 return die_rev;
99
100 die_rev = (omap_readl(OMAP32_ID_1) >> 28) & 0xf;
101
102 return die_rev;
103}
104
105void __init omap_check_revision(void)
106{
107 int i;
108 u16 jtag_id;
109 u8 die_rev;
110 u32 omap_id;
111 u8 cpu_type;
112
113 jtag_id = omap_get_jtag_id();
114 die_rev = omap_get_die_rev();
115 omap_id = omap_readl(OMAP32_ID_0);
116
117#ifdef DEBUG
118 printk("OMAP_DIE_ID_0: 0x%08x\n", omap_readl(OMAP_DIE_ID_0));
119 printk("OMAP_DIE_ID_1: 0x%08x DIE_REV: %i\n",
120 omap_readl(OMAP_DIE_ID_1),
121 (omap_readl(OMAP_DIE_ID_1) >> 17) & 0xf);
122 printk("OMAP_PRODUCTION_ID_0: 0x%08x\n", omap_readl(OMAP_PRODUCTION_ID_0));
123 printk("OMAP_PRODUCTION_ID_1: 0x%08x JTAG_ID: 0x%04x\n",
124 omap_readl(OMAP_PRODUCTION_ID_1),
125 omap_readl(OMAP_PRODUCTION_ID_1) & 0xffff);
126 printk("OMAP32_ID_0: 0x%08x\n", omap_readl(OMAP32_ID_0));
127 printk("OMAP32_ID_1: 0x%08x\n", omap_readl(OMAP32_ID_1));
128 printk("JTAG_ID: 0x%04x DIE_REV: %i\n", jtag_id, die_rev);
129#endif
130
131 system_serial_high = omap_readl(OMAP_DIE_ID_0);
132 system_serial_low = omap_readl(OMAP_DIE_ID_1);
133
134 /* First check only the major version in a safe way */
135 for (i = 0; i < ARRAY_SIZE(omap_ids); i++) {
136 if (jtag_id == (omap_ids[i].jtag_id)) {
137 system_rev = omap_ids[i].type;
138 break;
139 }
140 }
141
142 /* Check if we can find the die revision */
143 for (i = 0; i < ARRAY_SIZE(omap_ids); i++) {
144 if (jtag_id == omap_ids[i].jtag_id && die_rev == omap_ids[i].die_rev) {
145 system_rev = omap_ids[i].type;
146 break;
147 }
148 }
149
150 /* Finally check also the omap_id */
151 for (i = 0; i < ARRAY_SIZE(omap_ids); i++) {
152 if (jtag_id == omap_ids[i].jtag_id
153 && die_rev == omap_ids[i].die_rev
154 && omap_id == omap_ids[i].omap_id) {
155 system_rev = omap_ids[i].type;
156 break;
157 }
158 }
159
160 /* Add the cpu class info (7xx, 15xx, 16xx, 24xx) */
161 cpu_type = system_rev >> 24;
162
163 switch (cpu_type) {
164 case 0x07:
165 system_rev |= 0x07;
166 break;
167 case 0x15:
168 system_rev |= 0x15;
169 break;
170 case 0x16:
171 case 0x17:
172 system_rev |= 0x16;
173 break;
174 case 0x24:
175 system_rev |= 0x24;
176 break;
177 default:
178 printk("Unknown OMAP cpu type: 0x%02x\n", cpu_type);
179 }
180
181 printk("OMAP%04x", system_rev >> 16);
182 if ((system_rev >> 8) & 0xff)
183 printk("%x", (system_rev >> 8) & 0xff);
184 printk(" revision %i handled as %02xxx id: %08x%08x\n",
185 die_rev, system_rev & 0xff, system_serial_low,
186 system_serial_high);
187}
188