18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved. 48c2ecf20Sopenharmony_ci * Copyright 2008 Juergen Beisert, kernel@pengutronix.de 58c2ecf20Sopenharmony_ci */ 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci/* 88c2ecf20Sopenharmony_ci * i.MX27 specific CPU detection code 98c2ecf20Sopenharmony_ci */ 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include <linux/io.h> 128c2ecf20Sopenharmony_ci#include <linux/of_address.h> 138c2ecf20Sopenharmony_ci#include <linux/module.h> 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci#include "hardware.h" 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_cistatic int mx27_cpu_rev = -1; 188c2ecf20Sopenharmony_cistatic int mx27_cpu_partnumber; 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci#define SYS_CHIP_ID 0x00 /* The offset of CHIP ID register */ 218c2ecf20Sopenharmony_ci#define SYSCTRL_OFFSET 0x800 /* Offset from CCM base address */ 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_cistatic int mx27_read_cpu_rev(void) 248c2ecf20Sopenharmony_ci{ 258c2ecf20Sopenharmony_ci void __iomem *ccm_base; 268c2ecf20Sopenharmony_ci struct device_node *np; 278c2ecf20Sopenharmony_ci u32 val; 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci np = of_find_compatible_node(NULL, NULL, "fsl,imx27-ccm"); 308c2ecf20Sopenharmony_ci ccm_base = of_iomap(np, 0); 318c2ecf20Sopenharmony_ci of_node_put(np); 328c2ecf20Sopenharmony_ci BUG_ON(!ccm_base); 338c2ecf20Sopenharmony_ci /* 348c2ecf20Sopenharmony_ci * now we have access to the IO registers. As we need 358c2ecf20Sopenharmony_ci * the silicon revision very early we read it here to 368c2ecf20Sopenharmony_ci * avoid any further hooks 378c2ecf20Sopenharmony_ci */ 388c2ecf20Sopenharmony_ci val = imx_readl(ccm_base + SYSCTRL_OFFSET + SYS_CHIP_ID); 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci mx27_cpu_partnumber = (int)((val >> 12) & 0xFFFF); 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci switch (val >> 28) { 438c2ecf20Sopenharmony_ci case 0: 448c2ecf20Sopenharmony_ci return IMX_CHIP_REVISION_1_0; 458c2ecf20Sopenharmony_ci case 1: 468c2ecf20Sopenharmony_ci return IMX_CHIP_REVISION_2_0; 478c2ecf20Sopenharmony_ci case 2: 488c2ecf20Sopenharmony_ci return IMX_CHIP_REVISION_2_1; 498c2ecf20Sopenharmony_ci default: 508c2ecf20Sopenharmony_ci return IMX_CHIP_REVISION_UNKNOWN; 518c2ecf20Sopenharmony_ci } 528c2ecf20Sopenharmony_ci} 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci/* 558c2ecf20Sopenharmony_ci * Returns: 568c2ecf20Sopenharmony_ci * the silicon revision of the cpu 578c2ecf20Sopenharmony_ci * -EINVAL - not a mx27 588c2ecf20Sopenharmony_ci */ 598c2ecf20Sopenharmony_ciint mx27_revision(void) 608c2ecf20Sopenharmony_ci{ 618c2ecf20Sopenharmony_ci if (mx27_cpu_rev == -1) 628c2ecf20Sopenharmony_ci mx27_cpu_rev = mx27_read_cpu_rev(); 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci if (mx27_cpu_partnumber != 0x8821) 658c2ecf20Sopenharmony_ci return -EINVAL; 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci return mx27_cpu_rev; 688c2ecf20Sopenharmony_ci} 698c2ecf20Sopenharmony_ciEXPORT_SYMBOL(mx27_revision); 70