1e8de0fa8SMarek Vasut /* 2e8de0fa8SMarek Vasut * PXA CPU information display 3e8de0fa8SMarek Vasut * 4e8de0fa8SMarek Vasut * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com> 5e8de0fa8SMarek Vasut * 6e8de0fa8SMarek Vasut * This program is free software; you can redistribute it and/or 7e8de0fa8SMarek Vasut * modify it under the terms of the GNU General Public License as 8e8de0fa8SMarek Vasut * published by the Free Software Foundation; either version 2 of 9e8de0fa8SMarek Vasut * the License, or (at your option) any later version. 10e8de0fa8SMarek Vasut * 11e8de0fa8SMarek Vasut * This program is distributed in the hope that it will be useful, 12e8de0fa8SMarek Vasut * but WITHOUT ANY WARRANTY; without even the implied warranty of 13e8de0fa8SMarek Vasut * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14e8de0fa8SMarek Vasut * GNU General Public License for more details. 15e8de0fa8SMarek Vasut * 16e8de0fa8SMarek Vasut * You should have received a copy of the GNU General Public License 17e8de0fa8SMarek Vasut * along with this program; if not, write to the Free Software 18e8de0fa8SMarek Vasut * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 19e8de0fa8SMarek Vasut * MA 02111-1307 USA 20e8de0fa8SMarek Vasut */ 21e8de0fa8SMarek Vasut 22e8de0fa8SMarek Vasut #include <common.h> 23e8de0fa8SMarek Vasut #include <asm/io.h> 24e8de0fa8SMarek Vasut #include <errno.h> 25e8de0fa8SMarek Vasut #include <linux/compiler.h> 26e8de0fa8SMarek Vasut 27*539e9ffdSLukasz Dalek #define CPU_MASK_PXA_PRODID 0x000003f0 28*539e9ffdSLukasz Dalek #define CPU_MASK_PXA_REVID 0x0000000f 29e8de0fa8SMarek Vasut 30*539e9ffdSLukasz Dalek #define CPU_MASK_PRODREV (CPU_MASK_PXA_PRODID | CPU_MASK_PXA_REVID) 31*539e9ffdSLukasz Dalek 32e8de0fa8SMarek Vasut #define CPU_VALUE_PXA25X 0x100 33e8de0fa8SMarek Vasut #define CPU_VALUE_PXA27X 0x110 34e8de0fa8SMarek Vasut 35e8de0fa8SMarek Vasut static uint32_t pxa_get_cpuid(void) 36e8de0fa8SMarek Vasut { 37e8de0fa8SMarek Vasut uint32_t cpuid; 38e8de0fa8SMarek Vasut asm volatile("mrc p15, 0, %0, c0, c0, 0" : "=r"(cpuid)); 39e8de0fa8SMarek Vasut return cpuid; 40e8de0fa8SMarek Vasut } 41e8de0fa8SMarek Vasut 42e8de0fa8SMarek Vasut int cpu_is_pxa25x(void) 43e8de0fa8SMarek Vasut { 44e8de0fa8SMarek Vasut uint32_t id = pxa_get_cpuid(); 45e8de0fa8SMarek Vasut id &= CPU_MASK_PXA_PRODID; 46e8de0fa8SMarek Vasut return id == CPU_VALUE_PXA25X; 47e8de0fa8SMarek Vasut } 48e8de0fa8SMarek Vasut 49e8de0fa8SMarek Vasut int cpu_is_pxa27x(void) 50e8de0fa8SMarek Vasut { 51e8de0fa8SMarek Vasut uint32_t id = pxa_get_cpuid(); 52e8de0fa8SMarek Vasut id &= CPU_MASK_PXA_PRODID; 53e8de0fa8SMarek Vasut return id == CPU_VALUE_PXA27X; 54e8de0fa8SMarek Vasut } 55e8de0fa8SMarek Vasut 56*539e9ffdSLukasz Dalek uint32_t pxa_get_cpu_revision(void) 57*539e9ffdSLukasz Dalek { 58*539e9ffdSLukasz Dalek return pxa_get_cpuid() & CPU_MASK_PRODREV; 59*539e9ffdSLukasz Dalek } 60*539e9ffdSLukasz Dalek 61e8de0fa8SMarek Vasut #ifdef CONFIG_DISPLAY_CPUINFO 62e8de0fa8SMarek Vasut static const char *pxa25x_get_revision(void) 63e8de0fa8SMarek Vasut { 64e8de0fa8SMarek Vasut static __maybe_unused const char * const revs_25x[] = { "A0" }; 65e8de0fa8SMarek Vasut static __maybe_unused const char * const revs_26x[] = { 66e8de0fa8SMarek Vasut "A0", "B0", "B1" 67e8de0fa8SMarek Vasut }; 68e8de0fa8SMarek Vasut static const char *unknown = "Unknown"; 69e8de0fa8SMarek Vasut uint32_t id; 70e8de0fa8SMarek Vasut 71e8de0fa8SMarek Vasut if (!cpu_is_pxa25x()) 72e8de0fa8SMarek Vasut return unknown; 73e8de0fa8SMarek Vasut 74e8de0fa8SMarek Vasut id = pxa_get_cpuid() & CPU_MASK_PXA_REVID; 75e8de0fa8SMarek Vasut 76e8de0fa8SMarek Vasut /* PXA26x is a sick special case as it can't be told apart from PXA25x :-( */ 77e8de0fa8SMarek Vasut #ifdef CONFIG_CPU_PXA26X 78e8de0fa8SMarek Vasut switch (id) { 79e8de0fa8SMarek Vasut case 3: return revs_26x[0]; 80e8de0fa8SMarek Vasut case 5: return revs_26x[1]; 81e8de0fa8SMarek Vasut case 6: return revs_26x[2]; 82e8de0fa8SMarek Vasut } 83e8de0fa8SMarek Vasut #else 84e8de0fa8SMarek Vasut if (id == 6) 85e8de0fa8SMarek Vasut return revs_25x[0]; 86e8de0fa8SMarek Vasut #endif 87e8de0fa8SMarek Vasut return unknown; 88e8de0fa8SMarek Vasut } 89e8de0fa8SMarek Vasut 90e8de0fa8SMarek Vasut static const char *pxa27x_get_revision(void) 91e8de0fa8SMarek Vasut { 92e8de0fa8SMarek Vasut static const char *const rev[] = { "A0", "A1", "B0", "B1", "C0", "C5" }; 93e8de0fa8SMarek Vasut static const char *unknown = "Unknown"; 94e8de0fa8SMarek Vasut uint32_t id; 95e8de0fa8SMarek Vasut 96e8de0fa8SMarek Vasut if (!cpu_is_pxa27x()) 97e8de0fa8SMarek Vasut return unknown; 98e8de0fa8SMarek Vasut 99e8de0fa8SMarek Vasut id = pxa_get_cpuid() & CPU_MASK_PXA_REVID; 100e8de0fa8SMarek Vasut 101e8de0fa8SMarek Vasut if ((id == 5) || (id == 6) || (id > 7)) 102e8de0fa8SMarek Vasut return unknown; 103e8de0fa8SMarek Vasut 104e8de0fa8SMarek Vasut /* Cap the special PXA270 C5 case. */ 105e8de0fa8SMarek Vasut if (id == 7) 106e8de0fa8SMarek Vasut id = 5; 107e8de0fa8SMarek Vasut 108e8de0fa8SMarek Vasut return rev[id]; 109e8de0fa8SMarek Vasut } 110e8de0fa8SMarek Vasut 111e8de0fa8SMarek Vasut static int print_cpuinfo_pxa2xx(void) 112e8de0fa8SMarek Vasut { 113e8de0fa8SMarek Vasut if (cpu_is_pxa25x()) { 114e8de0fa8SMarek Vasut puts("Marvell PXA25x rev. "); 115e8de0fa8SMarek Vasut puts(pxa25x_get_revision()); 116e8de0fa8SMarek Vasut } else if (cpu_is_pxa27x()) { 117e8de0fa8SMarek Vasut puts("Marvell PXA27x rev. "); 118e8de0fa8SMarek Vasut puts(pxa27x_get_revision()); 119e8de0fa8SMarek Vasut } else 120e8de0fa8SMarek Vasut return -EINVAL; 121e8de0fa8SMarek Vasut 122e8de0fa8SMarek Vasut puts("\n"); 123e8de0fa8SMarek Vasut 124e8de0fa8SMarek Vasut return 0; 125e8de0fa8SMarek Vasut } 126e8de0fa8SMarek Vasut 127e8de0fa8SMarek Vasut int print_cpuinfo(void) 128e8de0fa8SMarek Vasut { 129e8de0fa8SMarek Vasut int ret; 130e8de0fa8SMarek Vasut 131e8de0fa8SMarek Vasut puts("CPU: "); 132e8de0fa8SMarek Vasut 133e8de0fa8SMarek Vasut ret = print_cpuinfo_pxa2xx(); 134e8de0fa8SMarek Vasut if (!ret) 135e8de0fa8SMarek Vasut return ret; 136e8de0fa8SMarek Vasut 137e8de0fa8SMarek Vasut return ret; 138e8de0fa8SMarek Vasut } 139e8de0fa8SMarek Vasut #endif 140