linux/arch/arm/mach-imx/cpu-imx5.c
<<
>>
Prefs
   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
  21static int mx5_cpu_rev = -1;
  22
  23#define IIM_SREV 0x24
  24#define MX50_HW_ADADIG_DIGPROG  0xB0
  25
  26static 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 */
  46int 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}
  56EXPORT_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 */
  65int __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
  77static 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 */
  99int 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}
 109EXPORT_SYMBOL(mx53_revision);
 110
 111static 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 */
 137int 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}
 147EXPORT_SYMBOL(mx50_revision);
 148