The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/arm/ti/ti_cpuid.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2011
    3  *      Ben Gray <ben.r.gray@gmail.com>.
    4  * All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
   19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   25  * SUCH DAMAGE.
   26  */
   27 
   28 #include <sys/cdefs.h>
   29 __FBSDID("$FreeBSD: releng/10.0/sys/arm/ti/ti_cpuid.c 246850 2013-02-15 21:24:21Z gonzo $");
   30 
   31 #include <sys/param.h>
   32 #include <sys/systm.h>
   33 #include <sys/kernel.h>
   34 #include <sys/module.h>
   35 #include <sys/bus.h>
   36 #include <sys/resource.h>
   37 #include <sys/rman.h>
   38 #include <sys/lock.h>
   39 #include <sys/mutex.h>
   40 
   41 #include <machine/bus.h>
   42 #include <machine/fdt.h>
   43 #include <machine/cpu.h>
   44 #include <machine/cpufunc.h>
   45 #include <machine/frame.h>
   46 #include <machine/resource.h>
   47 #include <machine/intr.h>
   48 
   49 #include <arm/ti/tivar.h>
   50 #include <arm/ti/ti_cpuid.h>
   51 
   52 #include <arm/ti/omap4/omap4_reg.h>
   53 #include <arm/ti/omap3/omap3_reg.h>
   54 #include <arm/ti/am335x/am335x_reg.h>
   55 
   56 #define OMAP4_STD_FUSE_DIE_ID_0    0x2200
   57 #define OMAP4_ID_CODE              0x2204
   58 #define OMAP4_STD_FUSE_DIE_ID_1    0x2208
   59 #define OMAP4_STD_FUSE_DIE_ID_2    0x220C
   60 #define OMAP4_STD_FUSE_DIE_ID_3    0x2210
   61 #define OMAP4_STD_FUSE_PROD_ID_0   0x2214
   62 #define OMAP4_STD_FUSE_PROD_ID_1   0x2218
   63 
   64 #define OMAP3_ID_CODE              0xA204
   65 
   66 static uint32_t chip_revision = 0xffffffff;
   67 
   68 /**
   69  *      ti_revision - Returns the revision number of the device
   70  *
   71  *      Simply returns an identifier for the revision of the chip we are running
   72  *      on.
   73  *
   74  *      RETURNS
   75  *      A 32-bit identifier for the current chip
   76  */
   77 uint32_t
   78 ti_revision(void)
   79 {
   80         return chip_revision;
   81 }
   82 
   83 /**
   84  *      omap4_get_revision - determines omap4 revision
   85  *
   86  *      Reads the registers to determine the revision of the chip we are currently
   87  *      running on.  Stores the information in global variables.
   88  *
   89  *
   90  */
   91 static void
   92 omap4_get_revision(void)
   93 {
   94         uint32_t id_code;
   95         uint32_t revision;
   96         uint32_t hawkeye;
   97         bus_space_handle_t bsh;
   98 
   99         /* The chip revsion is read from the device identification registers and
  100          * the JTAG (?) tap registers, which are located in address 0x4A00_2200 to
  101          * 0x4A00_2218.  This is part of the L4_CORE memory range and should have
  102          * been mapped in by the machdep.c code.
  103          *
  104          *   STD_FUSE_DIE_ID_0    0x4A00 2200
  105          *   ID_CODE              0x4A00 2204   (this is the only one we need)
  106          *   STD_FUSE_DIE_ID_1    0x4A00 2208
  107          *   STD_FUSE_DIE_ID_2    0x4A00 220C
  108          *   STD_FUSE_DIE_ID_3    0x4A00 2210
  109          *   STD_FUSE_PROD_ID_0   0x4A00 2214
  110          *   STD_FUSE_PROD_ID_1   0x4A00 2218
  111          */
  112         /* FIXME Should we map somewhere else? */
  113         bus_space_map(fdtbus_bs_tag,OMAP44XX_L4_CORE_HWBASE, 0x4000, 0, &bsh);
  114         id_code = bus_space_read_4(fdtbus_bs_tag, bsh, OMAP4_ID_CODE);
  115         bus_space_unmap(fdtbus_bs_tag, bsh, 0x4000);
  116 
  117         hawkeye = ((id_code >> 12) & 0xffff);
  118         revision = ((id_code >> 28) & 0xf);
  119 
  120         /* Apparently according to the linux code there were some ES2.0 samples that
  121          * have the wrong id code and report themselves as ES1.0 silicon.  So used
  122          * the ARM cpuid to get the correct revision.
  123          */
  124         if (revision == 0) {
  125                 id_code = cpufunc_id();
  126                 revision = (id_code & 0xf) - 1;
  127         }
  128 
  129         switch (hawkeye) {
  130         case 0xB852:
  131                 switch (revision) {
  132                 case 0:
  133                         chip_revision = OMAP4430_REV_ES1_0;
  134                         break;
  135                 case 1:
  136                         chip_revision = OMAP4430_REV_ES2_1;
  137                         break;
  138                 default:
  139                         chip_revision = OMAP4430_REV_UNKNOWN;
  140                         break;
  141                 }
  142                 break;
  143 
  144         case 0xB95C:
  145                 switch (revision) {
  146                 case 3:
  147                         chip_revision = OMAP4430_REV_ES2_1;
  148                         break;
  149                 case 4:
  150                         chip_revision = OMAP4430_REV_ES2_2;
  151                         break;
  152                 case 6:
  153                         chip_revision = OMAP4430_REV_ES2_3;
  154                         break;
  155                 default:
  156                         chip_revision = OMAP4430_REV_UNKNOWN;
  157                         break;
  158                 }
  159                 break;
  160 
  161         case 0xB94E:
  162                 switch (revision) {
  163                 case 0:
  164                         chip_revision = OMAP4460_REV_ES1_0;
  165                         break;
  166                 case 2:
  167                         chip_revision = OMAP4460_REV_ES1_1;
  168                         break;
  169                 default:
  170                         chip_revision = OMAP4460_REV_UNKNOWN;
  171                         break;
  172                 }
  173                 break;
  174 
  175         case 0xB975:
  176                 switch (revision) {
  177                 case 0:
  178                         chip_revision = OMAP4470_REV_ES1_0;
  179                         break;
  180                 default:
  181                         chip_revision = OMAP4470_REV_UNKNOWN;
  182                         break;
  183                 }
  184                 break;
  185 
  186         default:
  187                 /* Default to the latest revision if we can't determine type */
  188                 chip_revision = OMAP_UNKNOWN_DEV;
  189                 break;
  190         }
  191         if (chip_revision != OMAP_UNKNOWN_DEV) {
  192                 printf("Texas Instruments OMAP%04x Processor, Revision ES%u.%u\n",
  193                     OMAP_REV_DEVICE(chip_revision), OMAP_REV_MAJOR(chip_revision), 
  194                     OMAP_REV_MINOR(chip_revision));
  195         }
  196         else {
  197                 printf("Texas Instruments unknown OMAP chip: %04x, rev %d\n",
  198                     hawkeye, revision); 
  199         }
  200 }
  201 
  202 /**
  203  *      omap3_get_revision - determines omap3 revision
  204  *
  205  *      Reads the registers to determine the revision of the chip we are currently
  206  *      running on.  Stores the information in global variables.
  207  *
  208  *      WARNING: This function currently only really works for OMAP3530 devices.
  209  *
  210  *
  211  *
  212  */
  213 static void
  214 omap3_get_revision(void)
  215 {
  216         uint32_t id_code;
  217         uint32_t revision;
  218         uint32_t hawkeye;
  219         bus_space_handle_t bsh;
  220 
  221         /* The chip revsion is read from the device identification registers and
  222          * the JTAG (?) tap registers, which are located in address 0x4A00_2200 to
  223          * 0x4A00_2218.  This is part of the L4_CORE memory range and should have
  224          * been mapped in by the machdep.c code.
  225          *
  226          *   CONTROL_IDCODE       0x4830 A204   (this is the only one we need)
  227          *
  228          *
  229          */
  230         bus_space_map(fdtbus_bs_tag, OMAP35XX_L4_WAKEUP_HWBASE, 0x10000, 0, &bsh);
  231         id_code = bus_space_read_4(fdtbus_bs_tag, bsh, OMAP3_ID_CODE);
  232         bus_space_unmap(fdtbus_bs_tag, bsh, 0x10000);
  233 
  234         hawkeye = ((id_code >> 12) & 0xffff);
  235         revision = ((id_code >> 28) & 0xf);
  236 
  237         switch (hawkeye) {
  238         case 0xB6D6:
  239                 chip_revision = OMAP3350_REV_ES1_0;
  240                 break;
  241         case 0xB7AE:
  242                 if (revision == 1)
  243                         chip_revision = OMAP3530_REV_ES2_0;
  244                 else if (revision == 2)
  245                         chip_revision = OMAP3530_REV_ES2_1;
  246                 else if (revision == 3)
  247                         chip_revision = OMAP3530_REV_ES3_0;
  248                 else if (revision == 4)
  249                         chip_revision = OMAP3530_REV_ES3_1;
  250                 else if (revision == 7)
  251                         chip_revision = OMAP3530_REV_ES3_1_2;
  252                 break;
  253         default:
  254                 /* Default to the latest revision if we can't determine type */
  255                 chip_revision = OMAP3530_REV_ES3_1_2;
  256                 break;
  257         }
  258         printf("Texas Instruments OMAP%04x Processor, Revision ES%u.%u\n",
  259                 OMAP_REV_DEVICE(chip_revision), OMAP_REV_MAJOR(chip_revision), 
  260                 OMAP_REV_MINOR(chip_revision));
  261 }
  262 
  263 static void
  264 am335x_get_revision(void)
  265 {
  266         uint32_t dev_feature;
  267         uint8_t cpu_last_char;
  268         bus_space_handle_t bsh;
  269 
  270         bus_space_map(fdtbus_bs_tag, AM335X_CONTROL_BASE, AM335X_CONTROL_SIZE, 0, &bsh);
  271         chip_revision = bus_space_read_4(fdtbus_bs_tag, bsh, AM335X_CONTROL_DEVICE_ID);
  272         dev_feature = bus_space_read_4(fdtbus_bs_tag, bsh, AM335X_CONTROL_DEV_FEATURE);
  273         bus_space_unmap(fdtbus_bs_tag, bsh, AM335X_CONTROL_SIZE);
  274 
  275         switch (dev_feature) {
  276                 case 0x00FF0382:
  277                         cpu_last_char='2';
  278                         break;
  279                 case 0x20FF0382:
  280                         cpu_last_char='4';
  281                         break;
  282                 case 0x00FF0383:
  283                         cpu_last_char='6';
  284                         break;
  285                 case 0x00FE0383:
  286                         cpu_last_char='7';
  287                         break;
  288                 case 0x20FF0383:
  289                         cpu_last_char='8';
  290                         break;
  291                 case 0x20FE0383:
  292                         cpu_last_char='9';
  293                         break;
  294                 default:
  295                         cpu_last_char='x';
  296         }
  297 
  298         printf("Texas Instruments AM335%c Processor, Revision ES1.%u\n",
  299                 cpu_last_char, AM335X_DEVREV(chip_revision));
  300 }
  301 
  302 /**
  303  *      ti_cpu_ident - attempts to identify the chip we are running on
  304  *      @dummy: ignored
  305  *
  306  *      This function is called before any of the driver are initialised, however
  307  *      the basic virt to phys maps have been setup in machdep.c so we can still
  308  *      access the required registers, we just have to use direct register reads
  309  *      and writes rather than going through the bus stuff.
  310  *
  311  *
  312  */
  313 static void
  314 ti_cpu_ident(void *dummy)
  315 {
  316         switch(ti_chip()) {
  317         case CHIP_OMAP_3:
  318                 omap3_get_revision();
  319                 break;
  320         case CHIP_OMAP_4:
  321                 omap4_get_revision();
  322                 break;
  323         case CHIP_AM335X:
  324                 am335x_get_revision();
  325                 break;
  326         default:
  327                 panic("Unknown chip type, fixme!\n");
  328         }
  329 }
  330 
  331 SYSINIT(ti_cpu_ident, SI_SUB_CPU, SI_ORDER_SECOND, ti_cpu_ident, NULL);

Cache object: ca4899edfdc914055724834fa01c09e0


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.