fbede45d914812d87a4c6e87c6ad6b780550ffb7
[pandora-kernel.git] / arch / arm / mach-omap2 / id.c
1 /*
2  * linux/arch/arm/mach-omap2/id.c
3  *
4  * OMAP2 CPU identification code
5  *
6  * Copyright (C) 2005 Nokia Corporation
7  * Written by Tony Lindgren <tony@atomide.com>
8  *
9  * Copyright (C) 2009-11 Texas Instruments
10  * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License version 2 as
14  * published by the Free Software Foundation.
15  */
16
17 #include <linux/module.h>
18 #include <linux/kernel.h>
19 #include <linux/init.h>
20 #include <linux/io.h>
21 #include <linux/slab.h>
22
23 #ifdef CONFIG_SOC_BUS
24 #include <linux/sys_soc.h>
25 #include <linux/err.h>
26 #endif
27
28 #include <asm/cputype.h>
29
30 #include <plat/common.h>
31 #include <plat/cpu.h>
32
33 #include <mach/id.h>
34
35 #include "control.h"
36
37 #define OMAP_SOC_MAX_NAME_LENGTH                16
38
39 static unsigned int omap_revision;
40 static char soc_name[OMAP_SOC_MAX_NAME_LENGTH];
41 static char soc_rev[OMAP_SOC_MAX_NAME_LENGTH];
42 u32 omap_features;
43
44 unsigned int omap_rev(void)
45 {
46         return omap_revision;
47 }
48 EXPORT_SYMBOL(omap_rev);
49
50 int omap_type(void)
51 {
52         u32 val = 0;
53
54         if (cpu_is_omap24xx()) {
55                 val = omap_ctrl_readl(OMAP24XX_CONTROL_STATUS);
56         } else if (cpu_is_omap34xx()) {
57                 val = omap_ctrl_readl(OMAP343X_CONTROL_STATUS);
58         } else if (cpu_is_omap44xx()) {
59                 val = omap_ctrl_readl(OMAP4_CTRL_MODULE_CORE_STATUS);
60         } else {
61                 pr_err("Cannot detect omap type!\n");
62                 goto out;
63         }
64
65         val &= OMAP2_DEVICETYPE_MASK;
66         val >>= 8;
67
68 out:
69         return val;
70 }
71 EXPORT_SYMBOL(omap_type);
72
73
74 /*----------------------------------------------------------------------------*/
75
76 #define OMAP_TAP_IDCODE         0x0204
77 #define OMAP_TAP_DIE_ID_0       0x0218
78 #define OMAP_TAP_DIE_ID_1       0x021C
79 #define OMAP_TAP_DIE_ID_2       0x0220
80 #define OMAP_TAP_DIE_ID_3       0x0224
81
82 #define OMAP_TAP_DIE_ID_44XX_0  0x0200
83 #define OMAP_TAP_DIE_ID_44XX_1  0x0208
84 #define OMAP_TAP_DIE_ID_44XX_2  0x020c
85 #define OMAP_TAP_DIE_ID_44XX_3  0x0210
86
87 #define read_tap_reg(reg)       __raw_readl(tap_base  + (reg))
88
89 struct omap_id {
90         u16     hawkeye;        /* Silicon type (Hawkeye id) */
91         u8      dev;            /* Device type from production_id reg */
92         u32     type;           /* Combined type id copied to omap_revision */
93 };
94
95 /* Register values to detect the OMAP version */
96 static struct omap_id omap_ids[] __initdata = {
97         { .hawkeye = 0xb5d9, .dev = 0x0, .type = 0x24200024 },
98         { .hawkeye = 0xb5d9, .dev = 0x1, .type = 0x24201024 },
99         { .hawkeye = 0xb5d9, .dev = 0x2, .type = 0x24202024 },
100         { .hawkeye = 0xb5d9, .dev = 0x4, .type = 0x24220024 },
101         { .hawkeye = 0xb5d9, .dev = 0x8, .type = 0x24230024 },
102         { .hawkeye = 0xb68a, .dev = 0x0, .type = 0x24300024 },
103 };
104
105 static void __iomem *tap_base;
106 static u16 tap_prod_id;
107
108 void omap_get_die_id(struct omap_die_id *odi)
109 {
110         if (cpu_is_omap44xx()) {
111                 odi->id_0 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_0);
112                 odi->id_1 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_1);
113                 odi->id_2 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_2);
114                 odi->id_3 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_3);
115
116                 return;
117         }
118         odi->id_0 = read_tap_reg(OMAP_TAP_DIE_ID_0);
119         odi->id_1 = read_tap_reg(OMAP_TAP_DIE_ID_1);
120         odi->id_2 = read_tap_reg(OMAP_TAP_DIE_ID_2);
121         odi->id_3 = read_tap_reg(OMAP_TAP_DIE_ID_3);
122 }
123
124 void __init omap2xxx_check_revision(void)
125 {
126         int i, j;
127         u32 idcode, prod_id;
128         u16 hawkeye;
129         u8  dev_type, rev;
130         struct omap_die_id odi;
131
132         idcode = read_tap_reg(OMAP_TAP_IDCODE);
133         prod_id = read_tap_reg(tap_prod_id);
134         hawkeye = (idcode >> 12) & 0xffff;
135         rev = (idcode >> 28) & 0x0f;
136         dev_type = (prod_id >> 16) & 0x0f;
137         omap_get_die_id(&odi);
138
139         pr_debug("OMAP_TAP_IDCODE 0x%08x REV %i HAWKEYE 0x%04x MANF %03x\n",
140                  idcode, rev, hawkeye, (idcode >> 1) & 0x7ff);
141         pr_debug("OMAP_TAP_DIE_ID_0: 0x%08x\n", odi.id_0);
142         pr_debug("OMAP_TAP_DIE_ID_1: 0x%08x DEV_REV: %i\n",
143                  odi.id_1, (odi.id_1 >> 28) & 0xf);
144         pr_debug("OMAP_TAP_DIE_ID_2: 0x%08x\n", odi.id_2);
145         pr_debug("OMAP_TAP_DIE_ID_3: 0x%08x\n", odi.id_3);
146         pr_debug("OMAP_TAP_PROD_ID_0: 0x%08x DEV_TYPE: %i\n",
147                  prod_id, dev_type);
148
149         /* Check hawkeye ids */
150         for (i = 0; i < ARRAY_SIZE(omap_ids); i++) {
151                 if (hawkeye == omap_ids[i].hawkeye)
152                         break;
153         }
154
155         if (i == ARRAY_SIZE(omap_ids)) {
156                 printk(KERN_ERR "Unknown OMAP CPU id\n");
157                 return;
158         }
159
160         for (j = i; j < ARRAY_SIZE(omap_ids); j++) {
161                 if (dev_type == omap_ids[j].dev)
162                         break;
163         }
164
165         if (j == ARRAY_SIZE(omap_ids)) {
166                 printk(KERN_ERR "Unknown OMAP device type. "
167                                 "Handling it as OMAP%04x\n",
168                                 omap_ids[i].type >> 16);
169                 j = i;
170         }
171
172         sprintf(soc_name, "OMAP%04x", omap_rev() >> 16);
173         sprintf(soc_rev, "ES%x", (omap_rev() >> 12) & 0xf);
174
175         pr_info("%s", soc_name);
176         if ((omap_rev() >> 8) & 0x0f)
177                 pr_info("%s", soc_rev);
178         pr_info("\n");
179 }
180
181 #define OMAP3_SHOW_FEATURE(feat)                \
182         if (omap3_has_ ##feat())                \
183                 printk(#feat" ");
184
185 static void __init omap3_cpuinfo(void)
186 {
187         const char *cpu_name;
188
189         /*
190          * OMAP3430 and OMAP3530 are assumed to be same.
191          *
192          * OMAP3525, OMAP3515 and OMAP3503 can be detected only based
193          * on available features. Upon detection, update the CPU id
194          * and CPU class bits.
195          */
196         if (cpu_is_omap3630()) {
197                 cpu_name = "OMAP3630";
198         } else if (cpu_is_omap3517()) {
199                 /* AM35xx devices */
200                 cpu_name = (omap3_has_sgx()) ? "AM3517" : "AM3505";
201         } else if (cpu_is_ti816x()) {
202                 cpu_name = "TI816X";
203         } else if (omap3_has_iva() && omap3_has_sgx()) {
204                 /* OMAP3430, OMAP3525, OMAP3515, OMAP3503 devices */
205                 cpu_name = "OMAP3430/3530";
206         } else if (omap3_has_iva()) {
207                 cpu_name = "OMAP3525";
208         } else if (omap3_has_sgx()) {
209                 cpu_name = "OMAP3515";
210         } else {
211                 cpu_name = "OMAP3503";
212         }
213
214         sprintf(soc_name, "%s", cpu_name);
215
216         /* Print verbose information */
217         pr_info("%s %s (", soc_name, soc_rev);
218
219         OMAP3_SHOW_FEATURE(l2cache);
220         OMAP3_SHOW_FEATURE(iva);
221         OMAP3_SHOW_FEATURE(sgx);
222         OMAP3_SHOW_FEATURE(neon);
223         OMAP3_SHOW_FEATURE(isp);
224         OMAP3_SHOW_FEATURE(192mhz_clk);
225
226         printk(")\n");
227 }
228
229 #define OMAP3_CHECK_FEATURE(status,feat)                                \
230         if (((status & OMAP3_ ##feat## _MASK)                           \
231                 >> OMAP3_ ##feat## _SHIFT) != FEAT_ ##feat## _NONE) {   \
232                 omap_features |= OMAP3_HAS_ ##feat;                     \
233         }
234
235 void __init omap3xxx_check_features(void)
236 {
237         u32 status;
238
239         omap_features = 0;
240
241         status = omap_ctrl_readl(OMAP3_CONTROL_OMAP_STATUS);
242
243         OMAP3_CHECK_FEATURE(status, L2CACHE);
244         OMAP3_CHECK_FEATURE(status, IVA);
245         OMAP3_CHECK_FEATURE(status, SGX);
246         OMAP3_CHECK_FEATURE(status, NEON);
247         OMAP3_CHECK_FEATURE(status, ISP);
248         if (cpu_is_omap3630())
249                 omap_features |= OMAP3_HAS_192MHZ_CLK;
250         if (cpu_is_omap3430() || cpu_is_omap3630())
251                 omap_features |= OMAP3_HAS_IO_WAKEUP;
252         if (cpu_is_omap3630() || omap_rev() == OMAP3430_REV_ES3_1 ||
253             omap_rev() == OMAP3430_REV_ES3_1_2)
254                 omap_features |= OMAP3_HAS_IO_CHAIN_CTRL;
255
256         omap_features |= OMAP3_HAS_SDRC;
257
258         /*
259          * TODO: Get additional info (where applicable)
260          *       e.g. Size of L2 cache.
261          */
262
263         omap3_cpuinfo();
264 }
265
266 void __init omap4xxx_check_features(void)
267 {
268         u32 si_type;
269
270         if (cpu_is_omap443x())
271                 omap_features |= OMAP4_HAS_MPU_1GHZ;
272
273
274         if (cpu_is_omap446x()) {
275                 si_type =
276                         read_tap_reg(OMAP4_CTRL_MODULE_CORE_STD_FUSE_PROD_ID_1);
277                 switch ((si_type & (3 << 16)) >> 16) {
278                 case 2:
279                         /* High performance device */
280                         omap_features |= OMAP4_HAS_MPU_1_5GHZ;
281                         break;
282                 case 1:
283                 default:
284                         /* Standard device */
285                         omap_features |= OMAP4_HAS_MPU_1_2GHZ;
286                         break;
287                 }
288         }
289 }
290
291 void __init ti81xx_check_features(void)
292 {
293         omap_features = OMAP3_HAS_NEON;
294         omap3_cpuinfo();
295 }
296
297 void __init omap3xxx_check_revision(void)
298 {
299         const char *cpu_rev;
300         u32 cpuid, idcode;
301         u16 hawkeye;
302         u8 rev;
303
304         /*
305          * We cannot access revision registers on ES1.0.
306          * If the processor type is Cortex-A8 and the revision is 0x0
307          * it means its Cortex r0p0 which is 3430 ES1.0.
308          */
309         cpuid = read_cpuid(CPUID_ID);
310         if ((((cpuid >> 4) & 0xfff) == 0xc08) && ((cpuid & 0xf) == 0x0)) {
311                 omap_revision = OMAP3430_REV_ES1_0;
312                 cpu_rev = "1.0";
313                 return;
314         }
315
316         /*
317          * Detection for 34xx ES2.0 and above can be done with just
318          * hawkeye and rev. See TRM 1.5.2 Device Identification.
319          * Note that rev does not map directly to our defined processor
320          * revision numbers as ES1.0 uses value 0.
321          */
322         idcode = read_tap_reg(OMAP_TAP_IDCODE);
323         hawkeye = (idcode >> 12) & 0xffff;
324         rev = (idcode >> 28) & 0xff;
325
326         switch (hawkeye) {
327         case 0xb7ae:
328                 /* Handle 34xx/35xx devices */
329                 switch (rev) {
330                 case 0: /* Take care of early samples */
331                 case 1:
332                         omap_revision = OMAP3430_REV_ES2_0;
333                         cpu_rev = "2.0";
334                         break;
335                 case 2:
336                         omap_revision = OMAP3430_REV_ES2_1;
337                         cpu_rev = "2.1";
338                         break;
339                 case 3:
340                         omap_revision = OMAP3430_REV_ES3_0;
341                         cpu_rev = "3.0";
342                         break;
343                 case 4:
344                         omap_revision = OMAP3430_REV_ES3_1;
345                         cpu_rev = "3.1";
346                         break;
347                 case 7:
348                 /* FALLTHROUGH */
349                 default:
350                         /* Use the latest known revision as default */
351                         omap_revision = OMAP3430_REV_ES3_1_2;
352                         cpu_rev = "3.1.2";
353                 }
354                 break;
355         case 0xb868:
356                 /*
357                  * Handle OMAP/AM 3505/3517 devices
358                  *
359                  * Set the device to be OMAP3517 here. Actual device
360                  * is identified later based on the features.
361                  */
362                 switch (rev) {
363                 case 0:
364                         omap_revision = OMAP3517_REV_ES1_0;
365                         cpu_rev = "1.0";
366                         break;
367                 case 1:
368                 /* FALLTHROUGH */
369                 default:
370                         omap_revision = OMAP3517_REV_ES1_1;
371                         cpu_rev = "1.1";
372                 }
373                 break;
374         case 0xb891:
375                 /* Handle 36xx devices */
376
377                 switch(rev) {
378                 case 0: /* Take care of early samples */
379                         omap_revision = OMAP3630_REV_ES1_0;
380                         cpu_rev = "1.0";
381                         break;
382                 case 1:
383                         omap_revision = OMAP3630_REV_ES1_1;
384                         cpu_rev = "1.1";
385                         break;
386                 case 2:
387                 /* FALLTHROUGH */
388                 default:
389                         omap_revision = OMAP3630_REV_ES1_2;
390                         cpu_rev = "1.2";
391                 }
392                 break;
393         case 0xb81e:
394                 switch (rev) {
395                 case 0:
396                         omap_revision = TI8168_REV_ES1_0;
397                         cpu_rev = "1.0";
398                         break;
399                 case 1:
400                 /* FALLTHROUGH */
401                 default:
402                         omap_revision = TI8168_REV_ES1_1;
403                         cpu_rev = "1.1";
404                         break;
405                 }
406                 break;
407         default:
408                 /* Unknown default to latest silicon rev as default */
409                 omap_revision = OMAP3630_REV_ES1_2;
410                 cpu_rev = "1.2";
411                 pr_warn("Warning: unknown chip type; assuming OMAP3630ES1.2\n");
412         }
413         sprintf(soc_rev, "ES%s", cpu_rev);
414 }
415
416 void __init omap4xxx_check_revision(void)
417 {
418         u32 idcode;
419         u16 hawkeye;
420         u8 rev;
421
422         /*
423          * The IC rev detection is done with hawkeye and rev.
424          * Note that rev does not map directly to defined processor
425          * revision numbers as ES1.0 uses value 0.
426          */
427         idcode = read_tap_reg(OMAP_TAP_IDCODE);
428         hawkeye = (idcode >> 12) & 0xffff;
429         rev = (idcode >> 28) & 0xf;
430
431         /*
432          * Few initial 4430 ES2.0 samples IDCODE is same as ES1.0
433          * Use ARM register to detect the correct ES version
434          */
435         if (!rev && (hawkeye != 0xb94e)) {
436                 idcode = read_cpuid(CPUID_ID);
437                 rev = (idcode & 0xf) - 1;
438         }
439
440         switch (hawkeye) {
441         case 0xb852:
442                 switch (rev) {
443                 case 0:
444                         omap_revision = OMAP4430_REV_ES1_0;
445                         break;
446                 case 1:
447                 default:
448                         omap_revision = OMAP4430_REV_ES2_0;
449                 }
450                 break;
451         case 0xb95c:
452                 switch (rev) {
453                 case 3:
454                         omap_revision = OMAP4430_REV_ES2_1;
455                         break;
456                 case 4:
457                 default:
458                         omap_revision = OMAP4430_REV_ES2_2;
459                 }
460                 break;
461         case 0xb94e:
462                 switch (rev) {
463                 case 0:
464                 default:
465                         omap_revision = OMAP4460_REV_ES1_0;
466                         break;
467                 }
468                 break;
469         default:
470                 /* Unknown default to latest silicon rev as default */
471                 omap_revision = OMAP4430_REV_ES2_2;
472         }
473
474         sprintf(soc_name, "OMAP%04x", omap_rev() >> 16);
475         sprintf(soc_rev, "ES%d.%d", (omap_rev() >> 12) & 0xf,
476                                                 (omap_rev() >> 8) & 0xf);
477         pr_info("%s %s\n", soc_name, soc_rev);
478 }
479
480 /*
481  * Set up things for map_io and processor detection later on. Gets called
482  * pretty much first thing from board init. For multi-omap, this gets
483  * cpu_is_omapxxxx() working accurately enough for map_io. Then we'll try to
484  * detect the exact revision later on in omap2_detect_revision() once map_io
485  * is done.
486  */
487 void __init omap2_set_globals_tap(struct omap_globals *omap2_globals)
488 {
489         omap_revision = omap2_globals->class;
490         tap_base = omap2_globals->tap;
491
492         if (cpu_is_omap34xx())
493                 tap_prod_id = 0x0210;
494         else
495                 tap_prod_id = 0x0208;
496 }
497
498 #ifdef CONFIG_SOC_BUS
499
500 static const char const *omap_types[] = {
501         [OMAP2_DEVICE_TYPE_TEST]        = "TST",
502         [OMAP2_DEVICE_TYPE_EMU]         = "EMU",
503         [OMAP2_DEVICE_TYPE_SEC]         = "HS",
504         [OMAP2_DEVICE_TYPE_GP]          = "GP",
505         [OMAP2_DEVICE_TYPE_BAD]         = "BAD",
506 };
507
508 static const char * __init omap_get_family(void)
509 {
510         if (cpu_is_omap24xx())
511                 return kasprintf(GFP_KERNEL, "OMAP2");
512         else if (cpu_is_omap34xx())
513                 return kasprintf(GFP_KERNEL, "OMAP3");
514         else if (cpu_is_omap44xx())
515                 return kasprintf(GFP_KERNEL, "OMAP4");
516         else
517                 return kasprintf(GFP_KERNEL, "Unknown");
518 }
519
520 static ssize_t omap_get_type(struct device *dev,
521                                         struct device_attribute *attr,
522                                         char *buf)
523 {
524         return sprintf(buf, "%s\n", omap_types[omap_type()]);
525 }
526
527 static struct device_attribute omap_soc_attr =
528         __ATTR(type,  S_IRUGO, omap_get_type,  NULL);
529
530 int __init omap_soc_device_init(void)
531 {
532         struct device *parent;
533         struct soc_device *soc_dev;
534         struct soc_device_attribute *soc_dev_attr;
535         int ret = 0;
536
537         soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
538         if (!soc_dev_attr)
539                 return -ENOMEM;
540
541         soc_dev_attr->machine  = soc_name;
542         soc_dev_attr->family   = omap_get_family();
543         soc_dev_attr->revision = soc_rev;
544
545         soc_dev = soc_device_register(soc_dev_attr);
546         if (IS_ERR_OR_NULL(soc_dev)) {
547                 kfree(soc_dev_attr);
548                 return -ENODEV;
549         }
550
551         parent = soc_device_to_device(soc_dev);
552         if (!IS_ERR_OR_NULL(parent))
553                 ret = device_create_file(parent, &omap_soc_attr);
554
555         return ret;
556 }
557 late_initcall(omap_soc_device_init);
558
559 #endif /* CONFIG_SOC_BUS */