1239281Sgonzo/*- 2239281Sgonzo * Copyright (c) 2011 3239281Sgonzo * Ben Gray <ben.r.gray@gmail.com>. 4239281Sgonzo * All rights reserved. 5239281Sgonzo * 6239281Sgonzo * Redistribution and use in source and binary forms, with or without 7239281Sgonzo * modification, are permitted provided that the following conditions 8239281Sgonzo * are met: 9239281Sgonzo * 1. Redistributions of source code must retain the above copyright 10239281Sgonzo * notice, this list of conditions and the following disclaimer. 11239281Sgonzo * 2. Redistributions in binary form must reproduce the above copyright 12239281Sgonzo * notice, this list of conditions and the following disclaimer in the 13239281Sgonzo * documentation and/or other materials provided with the distribution. 14239281Sgonzo * 15239281Sgonzo * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16239281Sgonzo * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17239281Sgonzo * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18239281Sgonzo * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 19239281Sgonzo * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20239281Sgonzo * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21239281Sgonzo * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22239281Sgonzo * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23239281Sgonzo * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24239281Sgonzo * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25239281Sgonzo * SUCH DAMAGE. 26239281Sgonzo */ 27239281Sgonzo 28239281Sgonzo#include <sys/cdefs.h> 29239281Sgonzo__FBSDID("$FreeBSD: stable/11/sys/arm/ti/ti_cpuid.c 308325 2016-11-05 04:30:44Z mmel $"); 30239281Sgonzo 31239281Sgonzo#include <sys/param.h> 32239281Sgonzo#include <sys/systm.h> 33239281Sgonzo#include <sys/kernel.h> 34239281Sgonzo#include <sys/module.h> 35239281Sgonzo#include <sys/bus.h> 36239281Sgonzo#include <sys/resource.h> 37239281Sgonzo#include <sys/rman.h> 38239281Sgonzo#include <sys/lock.h> 39239281Sgonzo#include <sys/mutex.h> 40239281Sgonzo 41239281Sgonzo#include <machine/bus.h> 42239281Sgonzo#include <machine/fdt.h> 43239281Sgonzo#include <machine/resource.h> 44239281Sgonzo#include <machine/intr.h> 45239281Sgonzo 46239281Sgonzo#include <arm/ti/tivar.h> 47239281Sgonzo#include <arm/ti/ti_cpuid.h> 48239281Sgonzo 49239281Sgonzo#include <arm/ti/omap4/omap4_reg.h> 50239281Sgonzo#include <arm/ti/am335x/am335x_reg.h> 51239281Sgonzo 52239281Sgonzo#define OMAP4_STD_FUSE_DIE_ID_0 0x2200 53239281Sgonzo#define OMAP4_ID_CODE 0x2204 54239281Sgonzo#define OMAP4_STD_FUSE_DIE_ID_1 0x2208 55239281Sgonzo#define OMAP4_STD_FUSE_DIE_ID_2 0x220C 56239281Sgonzo#define OMAP4_STD_FUSE_DIE_ID_3 0x2210 57239281Sgonzo#define OMAP4_STD_FUSE_PROD_ID_0 0x2214 58239281Sgonzo#define OMAP4_STD_FUSE_PROD_ID_1 0x2218 59239281Sgonzo 60239281Sgonzo#define OMAP3_ID_CODE 0xA204 61239281Sgonzo 62239281Sgonzostatic uint32_t chip_revision = 0xffffffff; 63239281Sgonzo 64239281Sgonzo/** 65239281Sgonzo * ti_revision - Returns the revision number of the device 66239281Sgonzo * 67239281Sgonzo * Simply returns an identifier for the revision of the chip we are running 68239281Sgonzo * on. 69239281Sgonzo * 70239281Sgonzo * RETURNS 71239281Sgonzo * A 32-bit identifier for the current chip 72239281Sgonzo */ 73239281Sgonzouint32_t 74239281Sgonzoti_revision(void) 75239281Sgonzo{ 76239281Sgonzo return chip_revision; 77239281Sgonzo} 78239281Sgonzo 79239281Sgonzo/** 80239281Sgonzo * omap4_get_revision - determines omap4 revision 81239281Sgonzo * 82239281Sgonzo * Reads the registers to determine the revision of the chip we are currently 83239281Sgonzo * running on. Stores the information in global variables. 84239281Sgonzo * 85239281Sgonzo * 86239281Sgonzo */ 87239281Sgonzostatic void 88239281Sgonzoomap4_get_revision(void) 89239281Sgonzo{ 90239281Sgonzo uint32_t id_code; 91239281Sgonzo uint32_t revision; 92239281Sgonzo uint32_t hawkeye; 93239281Sgonzo bus_space_handle_t bsh; 94239281Sgonzo 95239281Sgonzo /* The chip revsion is read from the device identification registers and 96239281Sgonzo * the JTAG (?) tap registers, which are located in address 0x4A00_2200 to 97239281Sgonzo * 0x4A00_2218. This is part of the L4_CORE memory range and should have 98239281Sgonzo * been mapped in by the machdep.c code. 99239281Sgonzo * 100239281Sgonzo * STD_FUSE_DIE_ID_0 0x4A00 2200 101239281Sgonzo * ID_CODE 0x4A00 2204 (this is the only one we need) 102239281Sgonzo * STD_FUSE_DIE_ID_1 0x4A00 2208 103239281Sgonzo * STD_FUSE_DIE_ID_2 0x4A00 220C 104239281Sgonzo * STD_FUSE_DIE_ID_3 0x4A00 2210 105239281Sgonzo * STD_FUSE_PROD_ID_0 0x4A00 2214 106239281Sgonzo * STD_FUSE_PROD_ID_1 0x4A00 2218 107239281Sgonzo */ 108246850Sgonzo /* FIXME Should we map somewhere else? */ 109239281Sgonzo bus_space_map(fdtbus_bs_tag,OMAP44XX_L4_CORE_HWBASE, 0x4000, 0, &bsh); 110239281Sgonzo id_code = bus_space_read_4(fdtbus_bs_tag, bsh, OMAP4_ID_CODE); 111239281Sgonzo bus_space_unmap(fdtbus_bs_tag, bsh, 0x4000); 112239281Sgonzo 113239281Sgonzo hawkeye = ((id_code >> 12) & 0xffff); 114239281Sgonzo revision = ((id_code >> 28) & 0xf); 115239281Sgonzo 116239281Sgonzo /* Apparently according to the linux code there were some ES2.0 samples that 117239281Sgonzo * have the wrong id code and report themselves as ES1.0 silicon. So used 118239281Sgonzo * the ARM cpuid to get the correct revision. 119239281Sgonzo */ 120239281Sgonzo if (revision == 0) { 121295123Smmel id_code = cpu_ident(); 122239281Sgonzo revision = (id_code & 0xf) - 1; 123239281Sgonzo } 124239281Sgonzo 125239281Sgonzo switch (hawkeye) { 126239281Sgonzo case 0xB852: 127245137Sgonzo switch (revision) { 128245137Sgonzo case 0: 129239281Sgonzo chip_revision = OMAP4430_REV_ES1_0; 130245137Sgonzo break; 131245137Sgonzo case 1: 132245137Sgonzo chip_revision = OMAP4430_REV_ES2_1; 133245137Sgonzo break; 134245137Sgonzo default: 135245137Sgonzo chip_revision = OMAP4430_REV_UNKNOWN; 136245137Sgonzo break; 137245137Sgonzo } 138239281Sgonzo break; 139245137Sgonzo 140239281Sgonzo case 0xB95C: 141245137Sgonzo switch (revision) { 142245137Sgonzo case 3: 143239281Sgonzo chip_revision = OMAP4430_REV_ES2_1; 144245137Sgonzo break; 145245137Sgonzo case 4: 146239281Sgonzo chip_revision = OMAP4430_REV_ES2_2; 147245137Sgonzo break; 148245137Sgonzo case 6: 149239281Sgonzo chip_revision = OMAP4430_REV_ES2_3; 150245137Sgonzo break; 151245137Sgonzo default: 152245137Sgonzo chip_revision = OMAP4430_REV_UNKNOWN; 153245137Sgonzo break; 154245137Sgonzo } 155239281Sgonzo break; 156245137Sgonzo 157245137Sgonzo case 0xB94E: 158245137Sgonzo switch (revision) { 159245137Sgonzo case 0: 160245137Sgonzo chip_revision = OMAP4460_REV_ES1_0; 161245137Sgonzo break; 162245137Sgonzo case 2: 163245137Sgonzo chip_revision = OMAP4460_REV_ES1_1; 164245137Sgonzo break; 165245137Sgonzo default: 166245137Sgonzo chip_revision = OMAP4460_REV_UNKNOWN; 167245137Sgonzo break; 168245137Sgonzo } 169245137Sgonzo break; 170245137Sgonzo 171245137Sgonzo case 0xB975: 172245137Sgonzo switch (revision) { 173245137Sgonzo case 0: 174245137Sgonzo chip_revision = OMAP4470_REV_ES1_0; 175245137Sgonzo break; 176245137Sgonzo default: 177245137Sgonzo chip_revision = OMAP4470_REV_UNKNOWN; 178245137Sgonzo break; 179245137Sgonzo } 180245137Sgonzo break; 181245137Sgonzo 182239281Sgonzo default: 183239281Sgonzo /* Default to the latest revision if we can't determine type */ 184245137Sgonzo chip_revision = OMAP_UNKNOWN_DEV; 185239281Sgonzo break; 186239281Sgonzo } 187245137Sgonzo if (chip_revision != OMAP_UNKNOWN_DEV) { 188245137Sgonzo printf("Texas Instruments OMAP%04x Processor, Revision ES%u.%u\n", 189245137Sgonzo OMAP_REV_DEVICE(chip_revision), OMAP_REV_MAJOR(chip_revision), 190245137Sgonzo OMAP_REV_MINOR(chip_revision)); 191245137Sgonzo } 192245137Sgonzo else { 193245137Sgonzo printf("Texas Instruments unknown OMAP chip: %04x, rev %d\n", 194245137Sgonzo hawkeye, revision); 195245137Sgonzo } 196239281Sgonzo} 197239281Sgonzo 198239281Sgonzostatic void 199239281Sgonzoam335x_get_revision(void) 200239281Sgonzo{ 201239281Sgonzo uint32_t dev_feature; 202239281Sgonzo uint8_t cpu_last_char; 203239281Sgonzo bus_space_handle_t bsh; 204239281Sgonzo 205239281Sgonzo bus_space_map(fdtbus_bs_tag, AM335X_CONTROL_BASE, AM335X_CONTROL_SIZE, 0, &bsh); 206239281Sgonzo chip_revision = bus_space_read_4(fdtbus_bs_tag, bsh, AM335X_CONTROL_DEVICE_ID); 207239281Sgonzo dev_feature = bus_space_read_4(fdtbus_bs_tag, bsh, AM335X_CONTROL_DEV_FEATURE); 208239281Sgonzo bus_space_unmap(fdtbus_bs_tag, bsh, AM335X_CONTROL_SIZE); 209239281Sgonzo 210239281Sgonzo switch (dev_feature) { 211239281Sgonzo case 0x00FF0382: 212239281Sgonzo cpu_last_char='2'; 213239281Sgonzo break; 214239281Sgonzo case 0x20FF0382: 215239281Sgonzo cpu_last_char='4'; 216239281Sgonzo break; 217239281Sgonzo case 0x00FF0383: 218239281Sgonzo cpu_last_char='6'; 219239281Sgonzo break; 220239281Sgonzo case 0x00FE0383: 221239281Sgonzo cpu_last_char='7'; 222239281Sgonzo break; 223239281Sgonzo case 0x20FF0383: 224239281Sgonzo cpu_last_char='8'; 225239281Sgonzo break; 226239281Sgonzo case 0x20FE0383: 227239281Sgonzo cpu_last_char='9'; 228239281Sgonzo break; 229239281Sgonzo default: 230239281Sgonzo cpu_last_char='x'; 231239281Sgonzo } 232239281Sgonzo 233239281Sgonzo printf("Texas Instruments AM335%c Processor, Revision ES1.%u\n", 234239281Sgonzo cpu_last_char, AM335X_DEVREV(chip_revision)); 235239281Sgonzo} 236239281Sgonzo 237239281Sgonzo/** 238239281Sgonzo * ti_cpu_ident - attempts to identify the chip we are running on 239239281Sgonzo * @dummy: ignored 240239281Sgonzo * 241239281Sgonzo * This function is called before any of the driver are initialised, however 242239281Sgonzo * the basic virt to phys maps have been setup in machdep.c so we can still 243239281Sgonzo * access the required registers, we just have to use direct register reads 244239281Sgonzo * and writes rather than going through the bus stuff. 245239281Sgonzo * 246239281Sgonzo * 247239281Sgonzo */ 248239281Sgonzostatic void 249239281Sgonzoti_cpu_ident(void *dummy) 250239281Sgonzo{ 251239281Sgonzo switch(ti_chip()) { 252239281Sgonzo case CHIP_OMAP_4: 253239281Sgonzo omap4_get_revision(); 254239281Sgonzo break; 255239281Sgonzo case CHIP_AM335X: 256239281Sgonzo am335x_get_revision(); 257239281Sgonzo break; 258239281Sgonzo default: 259239281Sgonzo panic("Unknown chip type, fixme!\n"); 260239281Sgonzo } 261239281Sgonzo} 262239281Sgonzo 263239281SgonzoSYSINIT(ti_cpu_ident, SI_SUB_CPU, SI_ORDER_SECOND, ti_cpu_ident, NULL); 264