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