1 /* 2 * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved. 3 * 4 * The code contained herein is licensed under the GNU General Public 5 * License. You may obtain a copy of the GNU General Public License 6 * Version 2 or later at the following locations: 7 * 8 * http://www.opensource.org/licenses/gpl-license.html 9 * http://www.gnu.org/copyleft/gpl.html 10 * 11 * This file contains the CPU initialization code. 12 */ 13 14 #include <linux/types.h> 15 #include <linux/kernel.h> 16 #include <linux/init.h> 17 #include <linux/module.h> 18 #include <mach/hardware.h> 19 #include <linux/io.h> 20 21 static int mx5_cpu_rev = -1; 22 23 #define IIM_SREV 0x24 24 #define MX50_HW_ADADIG_DIGPROG 0xB0 25 26 static int get_mx51_srev(void) 27 { 28 void __iomem *iim_base = MX51_IO_ADDRESS(MX51_IIM_BASE_ADDR); 29 u32 rev = readl(iim_base + IIM_SREV) & 0xff; 30 31 switch (rev) { 32 case 0x0: 33 return IMX_CHIP_REVISION_2_0; 34 case 0x10: 35 return IMX_CHIP_REVISION_3_0; 36 default: 37 return IMX_CHIP_REVISION_UNKNOWN; 38 } 39 } 40 41 /* 42 * Returns: 43 * the silicon revision of the cpu 44 * -EINVAL - not a mx51 45 */ 46 int mx51_revision(void) 47 { 48 if (!cpu_is_mx51()) 49 return -EINVAL; 50 51 if (mx5_cpu_rev == -1) 52 mx5_cpu_rev = get_mx51_srev(); 53 54 return mx5_cpu_rev; 55 } 56 EXPORT_SYMBOL(mx51_revision); 57 58 #ifdef CONFIG_NEON 59 60 /* 61 * All versions of the silicon before Rev. 3 have broken NEON implementations. 62 * Dependent on link order - so the assumption is that vfp_init is called 63 * before us. 64 */ 65 int __init mx51_neon_fixup(void) 66 { 67 if (mx51_revision() < IMX_CHIP_REVISION_3_0 && 68 (elf_hwcap & HWCAP_NEON)) { 69 elf_hwcap &= ~HWCAP_NEON; 70 pr_info("Turning off NEON support, detected broken NEON implementation\n"); 71 } 72 return 0; 73 } 74 75 #endif 76 77 static int get_mx53_srev(void) 78 { 79 void __iomem *iim_base = MX51_IO_ADDRESS(MX53_IIM_BASE_ADDR); 80 u32 rev = readl(iim_base + IIM_SREV) & 0xff; 81 82 switch (rev) { 83 case 0x0: 84 return IMX_CHIP_REVISION_1_0; 85 case 0x2: 86 return IMX_CHIP_REVISION_2_0; 87 case 0x3: 88 return IMX_CHIP_REVISION_2_1; 89 default: 90 return IMX_CHIP_REVISION_UNKNOWN; 91 } 92 } 93 94 /* 95 * Returns: 96 * the silicon revision of the cpu 97 * -EINVAL - not a mx53 98 */ 99 int mx53_revision(void) 100 { 101 if (!cpu_is_mx53()) 102 return -EINVAL; 103 104 if (mx5_cpu_rev == -1) 105 mx5_cpu_rev = get_mx53_srev(); 106 107 return mx5_cpu_rev; 108 } 109 EXPORT_SYMBOL(mx53_revision); 110 111 static int get_mx50_srev(void) 112 { 113 void __iomem *anatop = ioremap(MX50_ANATOP_BASE_ADDR, SZ_8K); 114 u32 rev; 115 116 if (!anatop) { 117 mx5_cpu_rev = -EINVAL; 118 return 0; 119 } 120 121 rev = readl(anatop + MX50_HW_ADADIG_DIGPROG); 122 rev &= 0xff; 123 124 iounmap(anatop); 125 if (rev == 0x0) 126 return IMX_CHIP_REVISION_1_0; 127 else if (rev == 0x1) 128 return IMX_CHIP_REVISION_1_1; 129 return 0; 130 } 131 132 /* 133 * Returns: 134 * the silicon revision of the cpu 135 * -EINVAL - not a mx50 136 */ 137 int mx50_revision(void) 138 { 139 if (!cpu_is_mx50()) 140 return -EINVAL; 141 142 if (mx5_cpu_rev == -1) 143 mx5_cpu_rev = get_mx50_srev(); 144 145 return mx5_cpu_rev; 146 } 147 EXPORT_SYMBOL(mx50_revision); 148