Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/arm/mach-mx5/cpu.c
10817 views
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 <asm/io.h>
20
21
static int cpu_silicon_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
if (rev == 0x0)
32
return IMX_CHIP_REVISION_2_0;
33
else if (rev == 0x10)
34
return IMX_CHIP_REVISION_3_0;
35
return 0;
36
}
37
38
/*
39
* Returns:
40
* the silicon revision of the cpu
41
* -EINVAL - not a mx51
42
*/
43
int mx51_revision(void)
44
{
45
if (!cpu_is_mx51())
46
return -EINVAL;
47
48
if (cpu_silicon_rev == -1)
49
cpu_silicon_rev = get_mx51_srev();
50
51
return cpu_silicon_rev;
52
}
53
EXPORT_SYMBOL(mx51_revision);
54
55
void mx51_display_revision(void)
56
{
57
int rev;
58
char *srev;
59
rev = mx51_revision();
60
61
switch (rev) {
62
case IMX_CHIP_REVISION_2_0:
63
srev = IMX_CHIP_REVISION_2_0_STRING;
64
break;
65
case IMX_CHIP_REVISION_3_0:
66
srev = IMX_CHIP_REVISION_3_0_STRING;
67
break;
68
default:
69
srev = IMX_CHIP_REVISION_UNKNOWN_STRING;
70
}
71
printk(KERN_INFO "CPU identified as i.MX51, silicon rev %s\n", srev);
72
}
73
EXPORT_SYMBOL(mx51_display_revision);
74
75
#ifdef CONFIG_NEON
76
77
/*
78
* All versions of the silicon before Rev. 3 have broken NEON implementations.
79
* Dependent on link order - so the assumption is that vfp_init is called
80
* before us.
81
*/
82
static int __init mx51_neon_fixup(void)
83
{
84
if (!cpu_is_mx51())
85
return 0;
86
87
if (mx51_revision() < IMX_CHIP_REVISION_3_0 && (elf_hwcap & HWCAP_NEON)) {
88
elf_hwcap &= ~HWCAP_NEON;
89
pr_info("Turning off NEON support, detected broken NEON implementation\n");
90
}
91
return 0;
92
}
93
94
late_initcall(mx51_neon_fixup);
95
#endif
96
97
static int get_mx53_srev(void)
98
{
99
void __iomem *iim_base = MX51_IO_ADDRESS(MX53_IIM_BASE_ADDR);
100
u32 rev = readl(iim_base + IIM_SREV) & 0xff;
101
102
switch (rev) {
103
case 0x0:
104
return IMX_CHIP_REVISION_1_0;
105
case 0x2:
106
return IMX_CHIP_REVISION_2_0;
107
case 0x3:
108
return IMX_CHIP_REVISION_2_1;
109
default:
110
return IMX_CHIP_REVISION_UNKNOWN;
111
}
112
}
113
114
/*
115
* Returns:
116
* the silicon revision of the cpu
117
* -EINVAL - not a mx53
118
*/
119
int mx53_revision(void)
120
{
121
if (!cpu_is_mx53())
122
return -EINVAL;
123
124
if (cpu_silicon_rev == -1)
125
cpu_silicon_rev = get_mx53_srev();
126
127
return cpu_silicon_rev;
128
}
129
EXPORT_SYMBOL(mx53_revision);
130
131
static int get_mx50_srev(void)
132
{
133
void __iomem *anatop = ioremap(MX50_ANATOP_BASE_ADDR, SZ_8K);
134
u32 rev;
135
136
if (!anatop) {
137
cpu_silicon_rev = -EINVAL;
138
return 0;
139
}
140
141
rev = readl(anatop + MX50_HW_ADADIG_DIGPROG);
142
rev &= 0xff;
143
144
iounmap(anatop);
145
if (rev == 0x0)
146
return IMX_CHIP_REVISION_1_0;
147
else if (rev == 0x1)
148
return IMX_CHIP_REVISION_1_1;
149
return 0;
150
}
151
152
/*
153
* Returns:
154
* the silicon revision of the cpu
155
* -EINVAL - not a mx50
156
*/
157
int mx50_revision(void)
158
{
159
if (!cpu_is_mx50())
160
return -EINVAL;
161
162
if (cpu_silicon_rev == -1)
163
cpu_silicon_rev = get_mx50_srev();
164
165
return cpu_silicon_rev;
166
}
167
EXPORT_SYMBOL(mx50_revision);
168
169
void mx53_display_revision(void)
170
{
171
int rev;
172
char *srev;
173
rev = mx53_revision();
174
175
switch (rev) {
176
case IMX_CHIP_REVISION_1_0:
177
srev = IMX_CHIP_REVISION_1_0_STRING;
178
break;
179
case IMX_CHIP_REVISION_2_0:
180
srev = IMX_CHIP_REVISION_2_0_STRING;
181
break;
182
case IMX_CHIP_REVISION_2_1:
183
srev = IMX_CHIP_REVISION_2_1_STRING;
184
break;
185
default:
186
srev = IMX_CHIP_REVISION_UNKNOWN_STRING;
187
}
188
printk(KERN_INFO "CPU identified as i.MX53, silicon rev %s\n", srev);
189
}
190
EXPORT_SYMBOL(mx53_display_revision);
191
192
static int __init post_cpu_init(void)
193
{
194
unsigned int reg;
195
void __iomem *base;
196
197
if (cpu_is_mx51() || cpu_is_mx53()) {
198
if (cpu_is_mx51())
199
base = MX51_IO_ADDRESS(MX51_AIPS1_BASE_ADDR);
200
else
201
base = MX53_IO_ADDRESS(MX53_AIPS1_BASE_ADDR);
202
203
__raw_writel(0x0, base + 0x40);
204
__raw_writel(0x0, base + 0x44);
205
__raw_writel(0x0, base + 0x48);
206
__raw_writel(0x0, base + 0x4C);
207
reg = __raw_readl(base + 0x50) & 0x00FFFFFF;
208
__raw_writel(reg, base + 0x50);
209
210
if (cpu_is_mx51())
211
base = MX51_IO_ADDRESS(MX51_AIPS2_BASE_ADDR);
212
else
213
base = MX53_IO_ADDRESS(MX53_AIPS2_BASE_ADDR);
214
215
__raw_writel(0x0, base + 0x40);
216
__raw_writel(0x0, base + 0x44);
217
__raw_writel(0x0, base + 0x48);
218
__raw_writel(0x0, base + 0x4C);
219
reg = __raw_readl(base + 0x50) & 0x00FFFFFF;
220
__raw_writel(reg, base + 0x50);
221
}
222
223
return 0;
224
}
225
226
postcore_initcall(post_cpu_init);
227
228