1e8de0fa8SMarek Vasut /* 2e8de0fa8SMarek Vasut * PXA CPU information display 3e8de0fa8SMarek Vasut * 4e8de0fa8SMarek Vasut * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com> 5e8de0fa8SMarek Vasut * 61a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 7e8de0fa8SMarek Vasut */ 8e8de0fa8SMarek Vasut 9e8de0fa8SMarek Vasut #include <common.h> 10e8de0fa8SMarek Vasut #include <asm/io.h> 11e8de0fa8SMarek Vasut #include <errno.h> 12e8de0fa8SMarek Vasut #include <linux/compiler.h> 13e8de0fa8SMarek Vasut 14*23ff29bcSAlbert ARIBAUD #ifdef CONFIG_CPU_PXA25X 15*23ff29bcSAlbert ARIBAUD #if ((CONFIG_SYS_INIT_SP_ADDR) != 0xfffff800) 16*23ff29bcSAlbert ARIBAUD #error "Init SP address must be set to 0xfffff800 for PXA250" 17*23ff29bcSAlbert ARIBAUD #endif 18*23ff29bcSAlbert ARIBAUD #endif 19*23ff29bcSAlbert ARIBAUD 20539e9ffdSLukasz Dalek #define CPU_MASK_PXA_PRODID 0x000003f0 21539e9ffdSLukasz Dalek #define CPU_MASK_PXA_REVID 0x0000000f 22e8de0fa8SMarek Vasut 23539e9ffdSLukasz Dalek #define CPU_MASK_PRODREV (CPU_MASK_PXA_PRODID | CPU_MASK_PXA_REVID) 24539e9ffdSLukasz Dalek 25e8de0fa8SMarek Vasut #define CPU_VALUE_PXA25X 0x100 26e8de0fa8SMarek Vasut #define CPU_VALUE_PXA27X 0x110 27e8de0fa8SMarek Vasut 28e8de0fa8SMarek Vasut static uint32_t pxa_get_cpuid(void) 29e8de0fa8SMarek Vasut { 30e8de0fa8SMarek Vasut uint32_t cpuid; 31e8de0fa8SMarek Vasut asm volatile("mrc p15, 0, %0, c0, c0, 0" : "=r"(cpuid)); 32e8de0fa8SMarek Vasut return cpuid; 33e8de0fa8SMarek Vasut } 34e8de0fa8SMarek Vasut 35e8de0fa8SMarek Vasut int cpu_is_pxa25x(void) 36e8de0fa8SMarek Vasut { 37e8de0fa8SMarek Vasut uint32_t id = pxa_get_cpuid(); 38e8de0fa8SMarek Vasut id &= CPU_MASK_PXA_PRODID; 39e8de0fa8SMarek Vasut return id == CPU_VALUE_PXA25X; 40e8de0fa8SMarek Vasut } 41e8de0fa8SMarek Vasut 42e8de0fa8SMarek Vasut int cpu_is_pxa27x(void) 43e8de0fa8SMarek Vasut { 44e8de0fa8SMarek Vasut uint32_t id = pxa_get_cpuid(); 45e8de0fa8SMarek Vasut id &= CPU_MASK_PXA_PRODID; 46e8de0fa8SMarek Vasut return id == CPU_VALUE_PXA27X; 47e8de0fa8SMarek Vasut } 48e8de0fa8SMarek Vasut 49539e9ffdSLukasz Dalek uint32_t pxa_get_cpu_revision(void) 50539e9ffdSLukasz Dalek { 51539e9ffdSLukasz Dalek return pxa_get_cpuid() & CPU_MASK_PRODREV; 52539e9ffdSLukasz Dalek } 53539e9ffdSLukasz Dalek 54e8de0fa8SMarek Vasut #ifdef CONFIG_DISPLAY_CPUINFO 55e8de0fa8SMarek Vasut static const char *pxa25x_get_revision(void) 56e8de0fa8SMarek Vasut { 57e8de0fa8SMarek Vasut static __maybe_unused const char * const revs_25x[] = { "A0" }; 58e8de0fa8SMarek Vasut static __maybe_unused const char * const revs_26x[] = { 59e8de0fa8SMarek Vasut "A0", "B0", "B1" 60e8de0fa8SMarek Vasut }; 61e8de0fa8SMarek Vasut static const char *unknown = "Unknown"; 62e8de0fa8SMarek Vasut uint32_t id; 63e8de0fa8SMarek Vasut 64e8de0fa8SMarek Vasut if (!cpu_is_pxa25x()) 65e8de0fa8SMarek Vasut return unknown; 66e8de0fa8SMarek Vasut 67e8de0fa8SMarek Vasut id = pxa_get_cpuid() & CPU_MASK_PXA_REVID; 68e8de0fa8SMarek Vasut 69e8de0fa8SMarek Vasut /* PXA26x is a sick special case as it can't be told apart from PXA25x :-( */ 70e8de0fa8SMarek Vasut #ifdef CONFIG_CPU_PXA26X 71e8de0fa8SMarek Vasut switch (id) { 72e8de0fa8SMarek Vasut case 3: return revs_26x[0]; 73e8de0fa8SMarek Vasut case 5: return revs_26x[1]; 74e8de0fa8SMarek Vasut case 6: return revs_26x[2]; 75e8de0fa8SMarek Vasut } 76e8de0fa8SMarek Vasut #else 77e8de0fa8SMarek Vasut if (id == 6) 78e8de0fa8SMarek Vasut return revs_25x[0]; 79e8de0fa8SMarek Vasut #endif 80e8de0fa8SMarek Vasut return unknown; 81e8de0fa8SMarek Vasut } 82e8de0fa8SMarek Vasut 83e8de0fa8SMarek Vasut static const char *pxa27x_get_revision(void) 84e8de0fa8SMarek Vasut { 85e8de0fa8SMarek Vasut static const char *const rev[] = { "A0", "A1", "B0", "B1", "C0", "C5" }; 86e8de0fa8SMarek Vasut static const char *unknown = "Unknown"; 87e8de0fa8SMarek Vasut uint32_t id; 88e8de0fa8SMarek Vasut 89e8de0fa8SMarek Vasut if (!cpu_is_pxa27x()) 90e8de0fa8SMarek Vasut return unknown; 91e8de0fa8SMarek Vasut 92e8de0fa8SMarek Vasut id = pxa_get_cpuid() & CPU_MASK_PXA_REVID; 93e8de0fa8SMarek Vasut 94e8de0fa8SMarek Vasut if ((id == 5) || (id == 6) || (id > 7)) 95e8de0fa8SMarek Vasut return unknown; 96e8de0fa8SMarek Vasut 97e8de0fa8SMarek Vasut /* Cap the special PXA270 C5 case. */ 98e8de0fa8SMarek Vasut if (id == 7) 99e8de0fa8SMarek Vasut id = 5; 100e8de0fa8SMarek Vasut 101e8de0fa8SMarek Vasut return rev[id]; 102e8de0fa8SMarek Vasut } 103e8de0fa8SMarek Vasut 104e8de0fa8SMarek Vasut static int print_cpuinfo_pxa2xx(void) 105e8de0fa8SMarek Vasut { 106e8de0fa8SMarek Vasut if (cpu_is_pxa25x()) { 107e8de0fa8SMarek Vasut puts("Marvell PXA25x rev. "); 108e8de0fa8SMarek Vasut puts(pxa25x_get_revision()); 109e8de0fa8SMarek Vasut } else if (cpu_is_pxa27x()) { 110e8de0fa8SMarek Vasut puts("Marvell PXA27x rev. "); 111e8de0fa8SMarek Vasut puts(pxa27x_get_revision()); 112e8de0fa8SMarek Vasut } else 113e8de0fa8SMarek Vasut return -EINVAL; 114e8de0fa8SMarek Vasut 115e8de0fa8SMarek Vasut puts("\n"); 116e8de0fa8SMarek Vasut 117e8de0fa8SMarek Vasut return 0; 118e8de0fa8SMarek Vasut } 119e8de0fa8SMarek Vasut 120e8de0fa8SMarek Vasut int print_cpuinfo(void) 121e8de0fa8SMarek Vasut { 122e8de0fa8SMarek Vasut int ret; 123e8de0fa8SMarek Vasut 124e8de0fa8SMarek Vasut puts("CPU: "); 125e8de0fa8SMarek Vasut 126e8de0fa8SMarek Vasut ret = print_cpuinfo_pxa2xx(); 127e8de0fa8SMarek Vasut if (!ret) 128e8de0fa8SMarek Vasut return ret; 129e8de0fa8SMarek Vasut 130e8de0fa8SMarek Vasut return ret; 131e8de0fa8SMarek Vasut } 132e8de0fa8SMarek Vasut #endif 133