linux/arch/arm/mach-omap2/id.c
<<
>>
Prefs
   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 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
  22#include <asm/cputype.h>
  23
  24#include <mach/common.h>
  25#include <mach/control.h>
  26#include <mach/cpu.h>
  27
  28static struct omap_chip_id omap_chip;
  29static unsigned int omap_revision;
  30
  31
  32unsigned int omap_rev(void)
  33{
  34        return omap_revision;
  35}
  36EXPORT_SYMBOL(omap_rev);
  37
  38/**
  39 * omap_chip_is - test whether currently running OMAP matches a chip type
  40 * @oc: omap_chip_t to test against
  41 *
  42 * Test whether the currently-running OMAP chip matches the supplied
  43 * chip type 'oc'.  Returns 1 upon a match; 0 upon failure.
  44 */
  45int omap_chip_is(struct omap_chip_id oci)
  46{
  47        return (oci.oc & omap_chip.oc) ? 1 : 0;
  48}
  49EXPORT_SYMBOL(omap_chip_is);
  50
  51int omap_type(void)
  52{
  53        u32 val = 0;
  54
  55        if (cpu_is_omap24xx())
  56                val = omap_ctrl_readl(OMAP24XX_CONTROL_STATUS);
  57        else if (cpu_is_omap34xx())
  58                val = omap_ctrl_readl(OMAP343X_CONTROL_STATUS);
  59        else {
  60                pr_err("Cannot detect omap type!\n");
  61                goto out;
  62        }
  63
  64        val &= OMAP2_DEVICETYPE_MASK;
  65        val >>= 8;
  66
  67out:
  68        return val;
  69}
  70EXPORT_SYMBOL(omap_type);
  71
  72
  73/*----------------------------------------------------------------------------*/
  74
  75#define OMAP_TAP_IDCODE         0x0204
  76#define OMAP_TAP_DIE_ID_0       0x0218
  77#define OMAP_TAP_DIE_ID_1       0x021C
  78#define OMAP_TAP_DIE_ID_2       0x0220
  79#define OMAP_TAP_DIE_ID_3       0x0224
  80
  81#define read_tap_reg(reg)       __raw_readl(tap_base  + (reg))
  82
  83struct omap_id {
  84        u16     hawkeye;        /* Silicon type (Hawkeye id) */
  85        u8      dev;            /* Device type from production_id reg */
  86        u32     type;           /* Combined type id copied to omap_revision */
  87};
  88
  89/* Register values to detect the OMAP version */
  90static struct omap_id omap_ids[] __initdata = {
  91        { .hawkeye = 0xb5d9, .dev = 0x0, .type = 0x24200024 },
  92        { .hawkeye = 0xb5d9, .dev = 0x1, .type = 0x24201024 },
  93        { .hawkeye = 0xb5d9, .dev = 0x2, .type = 0x24202024 },
  94        { .hawkeye = 0xb5d9, .dev = 0x4, .type = 0x24220024 },
  95        { .hawkeye = 0xb5d9, .dev = 0x8, .type = 0x24230024 },
  96        { .hawkeye = 0xb68a, .dev = 0x0, .type = 0x24300024 },
  97};
  98
  99static void __iomem *tap_base;
 100static u16 tap_prod_id;
 101
 102void __init omap24xx_check_revision(void)
 103{
 104        int i, j;
 105        u32 idcode, prod_id;
 106        u16 hawkeye;
 107        u8  dev_type, rev;
 108
 109        idcode = read_tap_reg(OMAP_TAP_IDCODE);
 110        prod_id = read_tap_reg(tap_prod_id);
 111        hawkeye = (idcode >> 12) & 0xffff;
 112        rev = (idcode >> 28) & 0x0f;
 113        dev_type = (prod_id >> 16) & 0x0f;
 114
 115        pr_debug("OMAP_TAP_IDCODE 0x%08x REV %i HAWKEYE 0x%04x MANF %03x\n",
 116                 idcode, rev, hawkeye, (idcode >> 1) & 0x7ff);
 117        pr_debug("OMAP_TAP_DIE_ID_0: 0x%08x\n",
 118                 read_tap_reg(OMAP_TAP_DIE_ID_0));
 119        pr_debug("OMAP_TAP_DIE_ID_1: 0x%08x DEV_REV: %i\n",
 120                 read_tap_reg(OMAP_TAP_DIE_ID_1),
 121                 (read_tap_reg(OMAP_TAP_DIE_ID_1) >> 28) & 0xf);
 122        pr_debug("OMAP_TAP_DIE_ID_2: 0x%08x\n",
 123                 read_tap_reg(OMAP_TAP_DIE_ID_2));
 124        pr_debug("OMAP_TAP_DIE_ID_3: 0x%08x\n",
 125                 read_tap_reg(OMAP_TAP_DIE_ID_3));
 126        pr_debug("OMAP_TAP_PROD_ID_0: 0x%08x DEV_TYPE: %i\n",
 127                 prod_id, dev_type);
 128
 129        /* Check hawkeye ids */
 130        for (i = 0; i < ARRAY_SIZE(omap_ids); i++) {
 131                if (hawkeye == omap_ids[i].hawkeye)
 132                        break;
 133        }
 134
 135        if (i == ARRAY_SIZE(omap_ids)) {
 136                printk(KERN_ERR "Unknown OMAP CPU id\n");
 137                return;
 138        }
 139
 140        for (j = i; j < ARRAY_SIZE(omap_ids); j++) {
 141                if (dev_type == omap_ids[j].dev)
 142                        break;
 143        }
 144
 145        if (j == ARRAY_SIZE(omap_ids)) {
 146                printk(KERN_ERR "Unknown OMAP device type. "
 147                                "Handling it as OMAP%04x\n",
 148                                omap_ids[i].type >> 16);
 149                j = i;
 150        }
 151
 152        pr_info("OMAP%04x", omap_rev() >> 16);
 153        if ((omap_rev() >> 8) & 0x0f)
 154                pr_info("ES%x", (omap_rev() >> 12) & 0xf);
 155        pr_info("\n");
 156}
 157
 158void __init omap34xx_check_revision(void)
 159{
 160        u32 cpuid, idcode;
 161        u16 hawkeye;
 162        u8 rev;
 163        char *rev_name = "ES1.0";
 164
 165        /*
 166         * We cannot access revision registers on ES1.0.
 167         * If the processor type is Cortex-A8 and the revision is 0x0
 168         * it means its Cortex r0p0 which is 3430 ES1.0.
 169         */
 170        cpuid = read_cpuid(CPUID_ID);
 171        if ((((cpuid >> 4) & 0xfff) == 0xc08) && ((cpuid & 0xf) == 0x0)) {
 172                omap_revision = OMAP3430_REV_ES1_0;
 173                goto out;
 174        }
 175
 176        /*
 177         * Detection for 34xx ES2.0 and above can be done with just
 178         * hawkeye and rev. See TRM 1.5.2 Device Identification.
 179         * Note that rev does not map directly to our defined processor
 180         * revision numbers as ES1.0 uses value 0.
 181         */
 182        idcode = read_tap_reg(OMAP_TAP_IDCODE);
 183        hawkeye = (idcode >> 12) & 0xffff;
 184        rev = (idcode >> 28) & 0xff;
 185
 186        if (hawkeye == 0xb7ae) {
 187                switch (rev) {
 188                case 0:
 189                        omap_revision = OMAP3430_REV_ES2_0;
 190                        rev_name = "ES2.0";
 191                        break;
 192                case 2:
 193                        omap_revision = OMAP3430_REV_ES2_1;
 194                        rev_name = "ES2.1";
 195                        break;
 196                case 3:
 197                        omap_revision = OMAP3430_REV_ES3_0;
 198                        rev_name = "ES3.0";
 199                        break;
 200                case 4:
 201                        omap_revision = OMAP3430_REV_ES3_1;
 202                        rev_name = "ES3.1";
 203                        break;
 204                default:
 205                        /* Use the latest known revision as default */
 206                        omap_revision = OMAP3430_REV_ES3_1;
 207                        rev_name = "Unknown revision\n";
 208                }
 209        }
 210
 211out:
 212        pr_info("OMAP%04x %s\n", omap_rev() >> 16, rev_name);
 213}
 214
 215/*
 216 * Try to detect the exact revision of the omap we're running on
 217 */
 218void __init omap2_check_revision(void)
 219{
 220        /*
 221         * At this point we have an idea about the processor revision set
 222         * earlier with omap2_set_globals_tap().
 223         */
 224        if (cpu_is_omap24xx())
 225                omap24xx_check_revision();
 226        else if (cpu_is_omap34xx())
 227                omap34xx_check_revision();
 228        else if (cpu_is_omap44xx()) {
 229                printk(KERN_INFO "FIXME: CPU revision = OMAP4430\n");
 230                return;
 231        } else
 232                pr_err("OMAP revision unknown, please fix!\n");
 233
 234        /*
 235         * OK, now we know the exact revision. Initialize omap_chip bits
 236         * for powerdowmain and clockdomain code.
 237         */
 238        if (cpu_is_omap243x()) {
 239                /* Currently only supports 2430ES2.1 and 2430-all */
 240                omap_chip.oc |= CHIP_IS_OMAP2430;
 241        } else if (cpu_is_omap242x()) {
 242                /* Currently only supports 2420ES2.1.1 and 2420-all */
 243                omap_chip.oc |= CHIP_IS_OMAP2420;
 244        } else if (cpu_is_omap343x()) {
 245                omap_chip.oc = CHIP_IS_OMAP3430;
 246                if (omap_rev() == OMAP3430_REV_ES1_0)
 247                        omap_chip.oc |= CHIP_IS_OMAP3430ES1;
 248                else if (omap_rev() >= OMAP3430_REV_ES2_0 &&
 249                         omap_rev() <= OMAP3430_REV_ES2_1)
 250                        omap_chip.oc |= CHIP_IS_OMAP3430ES2;
 251                else if (omap_rev() == OMAP3430_REV_ES3_0)
 252                        omap_chip.oc |= CHIP_IS_OMAP3430ES3_0;
 253                else if (omap_rev() == OMAP3430_REV_ES3_1)
 254                        omap_chip.oc |= CHIP_IS_OMAP3430ES3_1;
 255        } else {
 256                pr_err("Uninitialized omap_chip, please fix!\n");
 257        }
 258}
 259
 260/*
 261 * Set up things for map_io and processor detection later on. Gets called
 262 * pretty much first thing from board init. For multi-omap, this gets
 263 * cpu_is_omapxxxx() working accurately enough for map_io. Then we'll try to
 264 * detect the exact revision later on in omap2_detect_revision() once map_io
 265 * is done.
 266 */
 267void __init omap2_set_globals_tap(struct omap_globals *omap2_globals)
 268{
 269        omap_revision = omap2_globals->class;
 270        tap_base = omap2_globals->tap;
 271
 272        if (cpu_is_omap34xx())
 273                tap_prod_id = 0x0210;
 274        else
 275                tap_prod_id = 0x0208;
 276}
 277