• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  // SPDX-License-Identifier: GPL-2.0-or-later
2  /*
3   * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
4   *
5   * This file contains the CPU initialization code.
6   */
7  
8  #include <linux/types.h>
9  #include <linux/kernel.h>
10  #include <linux/init.h>
11  #include <linux/module.h>
12  #include <linux/io.h>
13  #include <linux/of.h>
14  #include <linux/of_address.h>
15  
16  #include "hardware.h"
17  #include "common.h"
18  
19  static int mx5_cpu_rev = -1;
20  
21  #define IIM_SREV 0x24
22  
imx5_read_srev_reg(const char * compat)23  static u32 imx5_read_srev_reg(const char *compat)
24  {
25  	void __iomem *iim_base;
26  	struct device_node *np;
27  	u32 srev;
28  
29  	np = of_find_compatible_node(NULL, NULL, compat);
30  	iim_base = of_iomap(np, 0);
31  	of_node_put(np);
32  	WARN_ON(!iim_base);
33  
34  	srev = readl(iim_base + IIM_SREV) & 0xff;
35  
36  	iounmap(iim_base);
37  
38  	return srev;
39  }
40  
get_mx51_srev(void)41  static int get_mx51_srev(void)
42  {
43  	u32 rev = imx5_read_srev_reg("fsl,imx51-iim");
44  
45  	switch (rev) {
46  	case 0x0:
47  		return IMX_CHIP_REVISION_2_0;
48  	case 0x10:
49  		return IMX_CHIP_REVISION_3_0;
50  	default:
51  		return IMX_CHIP_REVISION_UNKNOWN;
52  	}
53  }
54  
55  /*
56   * Returns:
57   *	the silicon revision of the cpu
58   */
mx51_revision(void)59  int mx51_revision(void)
60  {
61  	if (mx5_cpu_rev == -1)
62  		mx5_cpu_rev = get_mx51_srev();
63  
64  	return mx5_cpu_rev;
65  }
66  EXPORT_SYMBOL(mx51_revision);
67  
68  #ifdef CONFIG_NEON
69  
70  /*
71   * All versions of the silicon before Rev. 3 have broken NEON implementations.
72   * Dependent on link order - so the assumption is that vfp_init is called
73   * before us.
74   */
mx51_neon_fixup(void)75  int __init mx51_neon_fixup(void)
76  {
77  	if (mx51_revision() < IMX_CHIP_REVISION_3_0 &&
78  			(elf_hwcap & HWCAP_NEON)) {
79  		elf_hwcap &= ~HWCAP_NEON;
80  		pr_info("Turning off NEON support, detected broken NEON implementation\n");
81  	}
82  	return 0;
83  }
84  
85  #endif
86  
get_mx53_srev(void)87  static int get_mx53_srev(void)
88  {
89  	u32 rev = imx5_read_srev_reg("fsl,imx53-iim");
90  
91  	switch (rev) {
92  	case 0x0:
93  		return IMX_CHIP_REVISION_1_0;
94  	case 0x2:
95  		return IMX_CHIP_REVISION_2_0;
96  	case 0x3:
97  		return IMX_CHIP_REVISION_2_1;
98  	default:
99  		return IMX_CHIP_REVISION_UNKNOWN;
100  	}
101  }
102  
103  /*
104   * Returns:
105   *	the silicon revision of the cpu
106   */
mx53_revision(void)107  int mx53_revision(void)
108  {
109  	if (mx5_cpu_rev == -1)
110  		mx5_cpu_rev = get_mx53_srev();
111  
112  	return mx5_cpu_rev;
113  }
114  EXPORT_SYMBOL(mx53_revision);
115  
116  #define ARM_GPC		0x4
117  #define DBGEN		BIT(16)
118  
119  /*
120   * This enables the DBGEN bit in ARM_GPC register, which is
121   * required for accessing some performance counter features.
122   * Technically it is only required while perf is used, but to
123   * keep the source code simple we just enable it all the time
124   * when the kernel configuration allows using the feature.
125   */
imx5_pmu_init(void)126  void __init imx5_pmu_init(void)
127  {
128  	void __iomem *tigerp_base;
129  	struct device_node *np;
130  	u32 gpc;
131  
132  	if (!IS_ENABLED(CONFIG_ARM_PMU))
133  		return;
134  
135  	np = of_find_compatible_node(NULL, NULL, "arm,cortex-a8-pmu");
136  	if (!np)
137  		return;
138  
139  	if (!of_property_read_bool(np, "secure-reg-access"))
140  		goto exit;
141  
142  	of_node_put(np);
143  
144  	np = of_find_compatible_node(NULL, NULL, "fsl,imx51-tigerp");
145  	if (!np)
146  		return;
147  
148  	tigerp_base = of_iomap(np, 0);
149  	if (!tigerp_base)
150  		goto exit;
151  
152  	gpc = readl_relaxed(tigerp_base + ARM_GPC);
153  	gpc |= DBGEN;
154  	writel_relaxed(gpc, tigerp_base + ARM_GPC);
155  	iounmap(tigerp_base);
156  exit:
157  	of_node_put(np);
158  
159  }
160