1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved. 4 * Copyright 2008 Juergen Beisert, kernel@pengutronix.de 5 */ 6 7 /* 8 * i.MX27 specific CPU detection code 9 */ 10 11 #include <linux/io.h> 12 #include <linux/of_address.h> 13 #include <linux/module.h> 14 15 #include "hardware.h" 16 17 static int mx27_cpu_rev = -1; 18 static int mx27_cpu_partnumber; 19 20 #define SYS_CHIP_ID 0x00 /* The offset of CHIP ID register */ 21 #define SYSCTRL_OFFSET 0x800 /* Offset from CCM base address */ 22 23 static int mx27_read_cpu_rev(void) 24 { 25 void __iomem *ccm_base; 26 struct device_node *np; 27 u32 val; 28 29 np = of_find_compatible_node(NULL, NULL, "fsl,imx27-ccm"); 30 ccm_base = of_iomap(np, 0); 31 BUG_ON(!ccm_base); 32 /* 33 * now we have access to the IO registers. As we need 34 * the silicon revision very early we read it here to 35 * avoid any further hooks 36 */ 37 val = imx_readl(ccm_base + SYSCTRL_OFFSET + SYS_CHIP_ID); 38 39 mx27_cpu_partnumber = (int)((val >> 12) & 0xFFFF); 40 41 switch (val >> 28) { 42 case 0: 43 return IMX_CHIP_REVISION_1_0; 44 case 1: 45 return IMX_CHIP_REVISION_2_0; 46 case 2: 47 return IMX_CHIP_REVISION_2_1; 48 default: 49 return IMX_CHIP_REVISION_UNKNOWN; 50 } 51 } 52 53 /* 54 * Returns: 55 * the silicon revision of the cpu 56 * -EINVAL - not a mx27 57 */ 58 int mx27_revision(void) 59 { 60 if (mx27_cpu_rev == -1) 61 mx27_cpu_rev = mx27_read_cpu_rev(); 62 63 if (mx27_cpu_partnumber != 0x8821) 64 return -EINVAL; 65 66 return mx27_cpu_rev; 67 } 68 EXPORT_SYMBOL(mx27_revision); 69