Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/arm/mach-imx/cpu-imx5.c
26295 views
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
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
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
*/
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
*/
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
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
*/
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
*/
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
161