Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
0004  *
0005  * This file contains the CPU initialization code.
0006  */
0007 
0008 #include <linux/types.h>
0009 #include <linux/kernel.h>
0010 #include <linux/init.h>
0011 #include <linux/module.h>
0012 #include <linux/io.h>
0013 #include <linux/of.h>
0014 #include <linux/of_address.h>
0015 
0016 #include "hardware.h"
0017 #include "common.h"
0018 
0019 static int mx5_cpu_rev = -1;
0020 
0021 #define IIM_SREV 0x24
0022 
0023 static u32 imx5_read_srev_reg(const char *compat)
0024 {
0025     void __iomem *iim_base;
0026     struct device_node *np;
0027     u32 srev;
0028 
0029     np = of_find_compatible_node(NULL, NULL, compat);
0030     iim_base = of_iomap(np, 0);
0031     WARN_ON(!iim_base);
0032 
0033     srev = readl(iim_base + IIM_SREV) & 0xff;
0034 
0035     iounmap(iim_base);
0036 
0037     return srev;
0038 }
0039 
0040 static int get_mx51_srev(void)
0041 {
0042     u32 rev = imx5_read_srev_reg("fsl,imx51-iim");
0043 
0044     switch (rev) {
0045     case 0x0:
0046         return IMX_CHIP_REVISION_2_0;
0047     case 0x10:
0048         return IMX_CHIP_REVISION_3_0;
0049     default:
0050         return IMX_CHIP_REVISION_UNKNOWN;
0051     }
0052 }
0053 
0054 /*
0055  * Returns:
0056  *  the silicon revision of the cpu
0057  */
0058 int mx51_revision(void)
0059 {
0060     if (mx5_cpu_rev == -1)
0061         mx5_cpu_rev = get_mx51_srev();
0062 
0063     return mx5_cpu_rev;
0064 }
0065 EXPORT_SYMBOL(mx51_revision);
0066 
0067 #ifdef CONFIG_NEON
0068 
0069 /*
0070  * All versions of the silicon before Rev. 3 have broken NEON implementations.
0071  * Dependent on link order - so the assumption is that vfp_init is called
0072  * before us.
0073  */
0074 int __init mx51_neon_fixup(void)
0075 {
0076     if (mx51_revision() < IMX_CHIP_REVISION_3_0 &&
0077             (elf_hwcap & HWCAP_NEON)) {
0078         elf_hwcap &= ~HWCAP_NEON;
0079         pr_info("Turning off NEON support, detected broken NEON implementation\n");
0080     }
0081     return 0;
0082 }
0083 
0084 #endif
0085 
0086 static int get_mx53_srev(void)
0087 {
0088     u32 rev = imx5_read_srev_reg("fsl,imx53-iim");
0089 
0090     switch (rev) {
0091     case 0x0:
0092         return IMX_CHIP_REVISION_1_0;
0093     case 0x2:
0094         return IMX_CHIP_REVISION_2_0;
0095     case 0x3:
0096         return IMX_CHIP_REVISION_2_1;
0097     default:
0098         return IMX_CHIP_REVISION_UNKNOWN;
0099     }
0100 }
0101 
0102 /*
0103  * Returns:
0104  *  the silicon revision of the cpu
0105  */
0106 int mx53_revision(void)
0107 {
0108     if (mx5_cpu_rev == -1)
0109         mx5_cpu_rev = get_mx53_srev();
0110 
0111     return mx5_cpu_rev;
0112 }
0113 EXPORT_SYMBOL(mx53_revision);
0114 
0115 #define ARM_GPC     0x4
0116 #define DBGEN       BIT(16)
0117 
0118 /*
0119  * This enables the DBGEN bit in ARM_GPC register, which is
0120  * required for accessing some performance counter features.
0121  * Technically it is only required while perf is used, but to
0122  * keep the source code simple we just enable it all the time
0123  * when the kernel configuration allows using the feature.
0124  */
0125 void __init imx5_pmu_init(void)
0126 {
0127     void __iomem *tigerp_base;
0128     struct device_node *np;
0129     u32 gpc;
0130 
0131     if (!IS_ENABLED(CONFIG_ARM_PMU))
0132         return;
0133 
0134     np = of_find_compatible_node(NULL, NULL, "arm,cortex-a8-pmu");
0135     if (!np)
0136         return;
0137 
0138     if (!of_property_read_bool(np, "secure-reg-access"))
0139         goto exit;
0140 
0141     of_node_put(np);
0142 
0143     np = of_find_compatible_node(NULL, NULL, "fsl,imx51-tigerp");
0144     if (!np)
0145         return;
0146 
0147     tigerp_base = of_iomap(np, 0);
0148     if (!tigerp_base)
0149         goto exit;
0150 
0151     gpc = readl_relaxed(tigerp_base + ARM_GPC);
0152     gpc |= DBGEN;
0153     writel_relaxed(gpc, tigerp_base + ARM_GPC);
0154     iounmap(tigerp_base);
0155 exit:
0156     of_node_put(np);
0157 
0158 }