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.2/sys/arm/ti/ti_cpuid.c 259329 2013-12-13 20:43:11Z ian $");
   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/resource.h>
   46 #include <machine/intr.h>
   47 
   48 #include <arm/ti/tivar.h>
   49 #include <arm/ti/ti_cpuid.h>
   50 
   51 #include <arm/ti/omap4/omap4_reg.h>
   52 #include <arm/ti/omap3/omap3_reg.h>
   53 #include <arm/ti/am335x/am335x_reg.h>
   54 
   55 #define OMAP4_STD_FUSE_DIE_ID_0    0x2200
   56 #define OMAP4_ID_CODE              0x2204
   57 #define OMAP4_STD_FUSE_DIE_ID_1    0x2208
   58 #define OMAP4_STD_FUSE_DIE_ID_2    0x220C
   59 #define OMAP4_STD_FUSE_DIE_ID_3    0x2210
   60 #define OMAP4_STD_FUSE_PROD_ID_0   0x2214
   61 #define OMAP4_STD_FUSE_PROD_ID_1   0x2218
   62 
   63 #define OMAP3_ID_CODE              0xA204
   64 
   65 static uint32_t chip_revision = 0xffffffff;
   66 
   67 /**
   68  *      ti_revision - Returns the revision number of the device
   69  *
   70  *      Simply returns an identifier for the revision of the chip we are running
   71  *      on.
   72  *
   73  *      RETURNS
   74  *      A 32-bit identifier for the current chip
   75  */
   76 uint32_t
   77 ti_revision(void)
   78 {
   79         return chip_revision;
   80 }
   81 
   82 /**
   83  *      omap4_get_revision - determines omap4 revision
   84  *
   85  *      Reads the registers to determine the revision of the chip we are currently
   86  *      running on.  Stores the information in global variables.
   87  *
   88  *
   89  */
   90 static void
   91 omap4_get_revision(void)
   92 {
   93         uint32_t id_code;
   94         uint32_t revision;
   95         uint32_t hawkeye;
   96         bus_space_handle_t bsh;
   97 
   98         /* The chip revsion is read from the device identification registers and
   99          * the JTAG (?) tap registers, which are located in address 0x4A00_2200 to
  100          * 0x4A00_2218.  This is part of the L4_CORE memory range and should have
  101          * been mapped in by the machdep.c code.
  102          *
  103          *   STD_FUSE_DIE_ID_0    0x4A00 2200
  104          *   ID_CODE              0x4A00 2204   (this is the only one we need)
  105          *   STD_FUSE_DIE_ID_1    0x4A00 2208
  106          *   STD_FUSE_DIE_ID_2    0x4A00 220C
  107          *   STD_FUSE_DIE_ID_3    0x4A00 2210
  108          *   STD_FUSE_PROD_ID_0   0x4A00 2214
  109          *   STD_FUSE_PROD_ID_1   0x4A00 2218
  110          */
  111         /* FIXME Should we map somewhere else? */
  112         bus_space_map(fdtbus_bs_tag,OMAP44XX_L4_CORE_HWBASE, 0x4000, 0, &bsh);
  113         id_code = bus_space_read_4(fdtbus_bs_tag, bsh, OMAP4_ID_CODE);
  114         bus_space_unmap(fdtbus_bs_tag, bsh, 0x4000);
  115 
  116         hawkeye = ((id_code >> 12) & 0xffff);
  117         revision = ((id_code >> 28) & 0xf);
  118 
  119         /* Apparently according to the linux code there were some ES2.0 samples that
  120          * have the wrong id code and report themselves as ES1.0 silicon.  So used
  121          * the ARM cpuid to get the correct revision.
  122          */
  123         if (revision == 0) {
  124                 id_code = cpufunc_id();
  125                 revision = (id_code & 0xf) - 1;
  126         }
  127 
  128         switch (hawkeye) {
  129         case 0xB852:
  130                 switch (revision) {
  131                 case 0:
  132                         chip_revision = OMAP4430_REV_ES1_0;
  133                         break;
  134                 case 1:
  135                         chip_revision = OMAP4430_REV_ES2_1;
  136                         break;
  137                 default:
  138                         chip_revision = OMAP4430_REV_UNKNOWN;
  139                         break;
  140                 }
  141                 break;
  142 
  143         case 0xB95C:
  144                 switch (revision) {
  145                 case 3:
  146                         chip_revision = OMAP4430_REV_ES2_1;
  147                         break;
  148                 case 4:
  149                         chip_revision = OMAP4430_REV_ES2_2;
  150                         break;
  151                 case 6:
  152                         chip_revision = OMAP4430_REV_ES2_3;
  153                         break;
  154                 default:
  155                         chip_revision = OMAP4430_REV_UNKNOWN;
  156                         break;
  157                 }
  158                 break;
  159 
  160         case 0xB94E:
  161                 switch (revision) {
  162                 case 0:
  163                         chip_revision = OMAP4460_REV_ES1_0;
  164                         break;
  165                 case 2:
  166                         chip_revision = OMAP4460_REV_ES1_1;
  167                         break;
  168                 default:
  169                         chip_revision = OMAP4460_REV_UNKNOWN;
  170                         break;
  171                 }
  172                 break;
  173 
  174         case 0xB975:
  175                 switch (revision) {
  176                 case 0:
  177                         chip_revision = OMAP4470_REV_ES1_0;
  178                         break;
  179                 default:
  180                         chip_revision = OMAP4470_REV_UNKNOWN;
  181                         break;
  182                 }
  183                 break;
  184 
  185         default:
  186                 /* Default to the latest revision if we can't determine type */
  187                 chip_revision = OMAP_UNKNOWN_DEV;
  188                 break;
  189         }
  190         if (chip_revision != OMAP_UNKNOWN_DEV) {
  191                 printf("Texas Instruments OMAP%04x Processor, Revision ES%u.%u\n",
  192                     OMAP_REV_DEVICE(chip_revision), OMAP_REV_MAJOR(chip_revision), 
  193                     OMAP_REV_MINOR(chip_revision));
  194         }
  195         else {
  196                 printf("Texas Instruments unknown OMAP chip: %04x, rev %d\n",
  197                     hawkeye, revision); 
  198         }
  199 }
  200 
  201 /**
  202  *      omap3_get_revision - determines omap3 revision
  203  *
  204  *      Reads the registers to determine the revision of the chip we are currently
  205  *      running on.  Stores the information in global variables.
  206  *
  207  *      WARNING: This function currently only really works for OMAP3530 devices.
  208  *
  209  *
  210  *
  211  */
  212 static void
  213 omap3_get_revision(void)
  214 {
  215         uint32_t id_code;
  216         uint32_t revision;
  217         uint32_t hawkeye;
  218         bus_space_handle_t bsh;
  219 
  220         /* The chip revsion is read from the device identification registers and
  221          * the JTAG (?) tap registers, which are located in address 0x4A00_2200 to
  222          * 0x4A00_2218.  This is part of the L4_CORE memory range and should have
  223          * been mapped in by the machdep.c code.
  224          *
  225          *   CONTROL_IDCODE       0x4830 A204   (this is the only one we need)
  226          *
  227          *
  228          */
  229         bus_space_map(fdtbus_bs_tag, OMAP35XX_L4_WAKEUP_HWBASE, 0x10000, 0, &bsh);
  230         id_code = bus_space_read_4(fdtbus_bs_tag, bsh, OMAP3_ID_CODE);
  231         bus_space_unmap(fdtbus_bs_tag, bsh, 0x10000);
  232 
  233         hawkeye = ((id_code >> 12) & 0xffff);
  234         revision = ((id_code >> 28) & 0xf);
  235 
  236         switch (hawkeye) {
  237         case 0xB6D6:
  238                 chip_revision = OMAP3350_REV_ES1_0;
  239                 break;
  240         case 0xB7AE:
  241                 if (revision == 1)
  242                         chip_revision = OMAP3530_REV_ES2_0;
  243                 else if (revision == 2)
  244                         chip_revision = OMAP3530_REV_ES2_1;
  245                 else if (revision == 3)
  246                         chip_revision = OMAP3530_REV_ES3_0;
  247                 else if (revision == 4)
  248                         chip_revision = OMAP3530_REV_ES3_1;
  249                 else if (revision == 7)
  250                         chip_revision = OMAP3530_REV_ES3_1_2;
  251                 break;
  252         default:
  253                 /* Default to the latest revision if we can't determine type */
  254                 chip_revision = OMAP3530_REV_ES3_1_2;
  255                 break;
  256         }
  257         printf("Texas Instruments OMAP%04x Processor, Revision ES%u.%u\n",
  258                 OMAP_REV_DEVICE(chip_revision), OMAP_REV_MAJOR(chip_revision), 
  259                 OMAP_REV_MINOR(chip_revision));
  260 }
  261 
  262 static void
  263 am335x_get_revision(void)
  264 {
  265         uint32_t dev_feature;
  266         uint8_t cpu_last_char;
  267         bus_space_handle_t bsh;
  268 
  269         bus_space_map(fdtbus_bs_tag, AM335X_CONTROL_BASE, AM335X_CONTROL_SIZE, 0, &bsh);
  270         chip_revision = bus_space_read_4(fdtbus_bs_tag, bsh, AM335X_CONTROL_DEVICE_ID);
  271         dev_feature = bus_space_read_4(fdtbus_bs_tag, bsh, AM335X_CONTROL_DEV_FEATURE);
  272         bus_space_unmap(fdtbus_bs_tag, bsh, AM335X_CONTROL_SIZE);
  273 
  274         switch (dev_feature) {
  275                 case 0x00FF0382:
  276                         cpu_last_char='2';
  277                         break;
  278                 case 0x20FF0382:
  279                         cpu_last_char='4';
  280                         break;
  281                 case 0x00FF0383:
  282                         cpu_last_char='6';
  283                         break;
  284                 case 0x00FE0383:
  285                         cpu_last_char='7';
  286                         break;
  287                 case 0x20FF0383:
  288                         cpu_last_char='8';
  289                         break;
  290                 case 0x20FE0383:
  291                         cpu_last_char='9';
  292                         break;
  293                 default:
  294                         cpu_last_char='x';
  295         }
  296 
  297         printf("Texas Instruments AM335%c Processor, Revision ES1.%u\n",
  298                 cpu_last_char, AM335X_DEVREV(chip_revision));
  299 }
  300 
  301 /**
  302  *      ti_cpu_ident - attempts to identify the chip we are running on
  303  *      @dummy: ignored
  304  *
  305  *      This function is called before any of the driver are initialised, however
  306  *      the basic virt to phys maps have been setup in machdep.c so we can still
  307  *      access the required registers, we just have to use direct register reads
  308  *      and writes rather than going through the bus stuff.
  309  *
  310  *
  311  */
  312 static void
  313 ti_cpu_ident(void *dummy)
  314 {
  315         switch(ti_chip()) {
  316         case CHIP_OMAP_3:
  317                 omap3_get_revision();
  318                 break;
  319         case CHIP_OMAP_4:
  320                 omap4_get_revision();
  321                 break;
  322         case CHIP_AM335X:
  323                 am335x_get_revision();
  324                 break;
  325         default:
  326                 panic("Unknown chip type, fixme!\n");
  327         }
  328 }
  329 
  330 SYSINIT(ti_cpu_ident, SI_SUB_CPU, SI_ORDER_SECOND, ti_cpu_ident, NULL);

Cache object: 00e369a2019643fed2365813ad48c4ba


[ 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.