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 of_node_put(np); 32 BUG_ON(!ccm_base); 33 /* 34 * now we have access to the IO registers. As we need 35 * the silicon revision very early we read it here to 36 * avoid any further hooks 37 */ 38 val = imx_readl(ccm_base + SYSCTRL_OFFSET + SYS_CHIP_ID); 39 40 mx27_cpu_partnumber = (int)((val >> 12) & 0xFFFF); 41 42 switch (val >> 28) { 43 case 0: 44 return IMX_CHIP_REVISION_1_0; 45 case 1: 46 return IMX_CHIP_REVISION_2_0; 47 case 2: 48 return IMX_CHIP_REVISION_2_1; 49 default: 50 return IMX_CHIP_REVISION_UNKNOWN; 51 } 52 } 53 54 /* 55 * Returns: 56 * the silicon revision of the cpu 57 * -EINVAL - not a mx27 58 */ 59 int mx27_revision(void) 60 { 61 if (mx27_cpu_rev == -1) 62 mx27_cpu_rev = mx27_read_cpu_rev(); 63 64 if (mx27_cpu_partnumber != 0x8821) 65 return -EINVAL; 66 67 return mx27_cpu_rev; 68 } 69 EXPORT_SYMBOL(mx27_revision); 70