xref: /openbmc/linux/arch/arm/mach-imx/cpu-imx5.c (revision 87b30c4b)
1fcaf2036SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2784a90c0SSascha Hauer /*
3784a90c0SSascha Hauer  * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
4784a90c0SSascha Hauer  *
5784a90c0SSascha Hauer  * This file contains the CPU initialization code.
6784a90c0SSascha Hauer  */
7784a90c0SSascha Hauer 
8784a90c0SSascha Hauer #include <linux/types.h>
9784a90c0SSascha Hauer #include <linux/kernel.h>
10784a90c0SSascha Hauer #include <linux/init.h>
11784a90c0SSascha Hauer #include <linux/module.h>
12eaed435aSLinus Torvalds #include <linux/io.h>
13ee18a715SShawn Guo #include <linux/of.h>
14ee18a715SShawn Guo #include <linux/of_address.h>
15784a90c0SSascha Hauer 
1650f2de61SShawn Guo #include "hardware.h"
1722567796SFabio Estevam #include "common.h"
1850f2de61SShawn Guo 
19784a90c0SSascha Hauer static int mx5_cpu_rev = -1;
20784a90c0SSascha Hauer 
21784a90c0SSascha Hauer #define IIM_SREV 0x24
22784a90c0SSascha Hauer 
imx5_read_srev_reg(const char * compat)23ee18a715SShawn Guo static u32 imx5_read_srev_reg(const char *compat)
24ee18a715SShawn Guo {
25ee18a715SShawn Guo 	void __iomem *iim_base;
26ee18a715SShawn Guo 	struct device_node *np;
27ee18a715SShawn Guo 	u32 srev;
28ee18a715SShawn Guo 
29ee18a715SShawn Guo 	np = of_find_compatible_node(NULL, NULL, compat);
30ee18a715SShawn Guo 	iim_base = of_iomap(np, 0);
31*87b30c4bSDario Binacchi 	of_node_put(np);
32ee18a715SShawn Guo 	WARN_ON(!iim_base);
33ee18a715SShawn Guo 
34ee18a715SShawn Guo 	srev = readl(iim_base + IIM_SREV) & 0xff;
35ee18a715SShawn Guo 
36ee18a715SShawn Guo 	iounmap(iim_base);
37ee18a715SShawn Guo 
38ee18a715SShawn Guo 	return srev;
39ee18a715SShawn Guo }
40ee18a715SShawn Guo 
get_mx51_srev(void)41784a90c0SSascha Hauer static int get_mx51_srev(void)
42784a90c0SSascha Hauer {
43ee18a715SShawn Guo 	u32 rev = imx5_read_srev_reg("fsl,imx51-iim");
44784a90c0SSascha Hauer 
45784a90c0SSascha Hauer 	switch (rev) {
46784a90c0SSascha Hauer 	case 0x0:
47784a90c0SSascha Hauer 		return IMX_CHIP_REVISION_2_0;
48784a90c0SSascha Hauer 	case 0x10:
49784a90c0SSascha Hauer 		return IMX_CHIP_REVISION_3_0;
50784a90c0SSascha Hauer 	default:
51784a90c0SSascha Hauer 		return IMX_CHIP_REVISION_UNKNOWN;
52784a90c0SSascha Hauer 	}
53784a90c0SSascha Hauer }
54784a90c0SSascha Hauer 
55784a90c0SSascha Hauer /*
56784a90c0SSascha Hauer  * Returns:
57784a90c0SSascha Hauer  *	the silicon revision of the cpu
58784a90c0SSascha Hauer  */
mx51_revision(void)59784a90c0SSascha Hauer int mx51_revision(void)
60784a90c0SSascha Hauer {
61784a90c0SSascha Hauer 	if (mx5_cpu_rev == -1)
62784a90c0SSascha Hauer 		mx5_cpu_rev = get_mx51_srev();
63784a90c0SSascha Hauer 
64784a90c0SSascha Hauer 	return mx5_cpu_rev;
65784a90c0SSascha Hauer }
66784a90c0SSascha Hauer EXPORT_SYMBOL(mx51_revision);
67784a90c0SSascha Hauer 
68784a90c0SSascha Hauer #ifdef CONFIG_NEON
69784a90c0SSascha Hauer 
70784a90c0SSascha Hauer /*
71784a90c0SSascha Hauer  * All versions of the silicon before Rev. 3 have broken NEON implementations.
72784a90c0SSascha Hauer  * Dependent on link order - so the assumption is that vfp_init is called
73784a90c0SSascha Hauer  * before us.
74784a90c0SSascha Hauer  */
mx51_neon_fixup(void)758321b758SShawn Guo int __init mx51_neon_fixup(void)
76784a90c0SSascha Hauer {
77eaed435aSLinus Torvalds 	if (mx51_revision() < IMX_CHIP_REVISION_3_0 &&
78eaed435aSLinus Torvalds 			(elf_hwcap & HWCAP_NEON)) {
79784a90c0SSascha Hauer 		elf_hwcap &= ~HWCAP_NEON;
80784a90c0SSascha Hauer 		pr_info("Turning off NEON support, detected broken NEON implementation\n");
81784a90c0SSascha Hauer 	}
82784a90c0SSascha Hauer 	return 0;
83784a90c0SSascha Hauer }
84784a90c0SSascha Hauer 
85784a90c0SSascha Hauer #endif
86784a90c0SSascha Hauer 
get_mx53_srev(void)87784a90c0SSascha Hauer static int get_mx53_srev(void)
88784a90c0SSascha Hauer {
89ee18a715SShawn Guo 	u32 rev = imx5_read_srev_reg("fsl,imx53-iim");
90784a90c0SSascha Hauer 
91784a90c0SSascha Hauer 	switch (rev) {
92784a90c0SSascha Hauer 	case 0x0:
93784a90c0SSascha Hauer 		return IMX_CHIP_REVISION_1_0;
94784a90c0SSascha Hauer 	case 0x2:
95784a90c0SSascha Hauer 		return IMX_CHIP_REVISION_2_0;
96784a90c0SSascha Hauer 	case 0x3:
97784a90c0SSascha Hauer 		return IMX_CHIP_REVISION_2_1;
98784a90c0SSascha Hauer 	default:
99784a90c0SSascha Hauer 		return IMX_CHIP_REVISION_UNKNOWN;
100784a90c0SSascha Hauer 	}
101784a90c0SSascha Hauer }
102784a90c0SSascha Hauer 
103784a90c0SSascha Hauer /*
104784a90c0SSascha Hauer  * Returns:
105784a90c0SSascha Hauer  *	the silicon revision of the cpu
106784a90c0SSascha Hauer  */
mx53_revision(void)107784a90c0SSascha Hauer int mx53_revision(void)
108784a90c0SSascha Hauer {
109784a90c0SSascha Hauer 	if (mx5_cpu_rev == -1)
110784a90c0SSascha Hauer 		mx5_cpu_rev = get_mx53_srev();
111784a90c0SSascha Hauer 
112784a90c0SSascha Hauer 	return mx5_cpu_rev;
113784a90c0SSascha Hauer }
114784a90c0SSascha Hauer EXPORT_SYMBOL(mx53_revision);
11526b754f9SFabio Estevam 
11626b754f9SFabio Estevam #define ARM_GPC		0x4
11726b754f9SFabio Estevam #define DBGEN		BIT(16)
11826b754f9SFabio Estevam 
11926b754f9SFabio Estevam /*
12026b754f9SFabio Estevam  * This enables the DBGEN bit in ARM_GPC register, which is
12126b754f9SFabio Estevam  * required for accessing some performance counter features.
12226b754f9SFabio Estevam  * Technically it is only required while perf is used, but to
12326b754f9SFabio Estevam  * keep the source code simple we just enable it all the time
12426b754f9SFabio Estevam  * when the kernel configuration allows using the feature.
12526b754f9SFabio Estevam  */
imx5_pmu_init(void)12626b754f9SFabio Estevam void __init imx5_pmu_init(void)
12726b754f9SFabio Estevam {
12826b754f9SFabio Estevam 	void __iomem *tigerp_base;
12926b754f9SFabio Estevam 	struct device_node *np;
13026b754f9SFabio Estevam 	u32 gpc;
13126b754f9SFabio Estevam 
13226b754f9SFabio Estevam 	if (!IS_ENABLED(CONFIG_ARM_PMU))
13326b754f9SFabio Estevam 		return;
13426b754f9SFabio Estevam 
13526b754f9SFabio Estevam 	np = of_find_compatible_node(NULL, NULL, "arm,cortex-a8-pmu");
13626b754f9SFabio Estevam 	if (!np)
13726b754f9SFabio Estevam 		return;
13826b754f9SFabio Estevam 
13926b754f9SFabio Estevam 	if (!of_property_read_bool(np, "secure-reg-access"))
14026b754f9SFabio Estevam 		goto exit;
14126b754f9SFabio Estevam 
14226b754f9SFabio Estevam 	of_node_put(np);
14326b754f9SFabio Estevam 
14426b754f9SFabio Estevam 	np = of_find_compatible_node(NULL, NULL, "fsl,imx51-tigerp");
14526b754f9SFabio Estevam 	if (!np)
14626b754f9SFabio Estevam 		return;
14726b754f9SFabio Estevam 
14826b754f9SFabio Estevam 	tigerp_base = of_iomap(np, 0);
14926b754f9SFabio Estevam 	if (!tigerp_base)
15026b754f9SFabio Estevam 		goto exit;
15126b754f9SFabio Estevam 
15226b754f9SFabio Estevam 	gpc = readl_relaxed(tigerp_base + ARM_GPC);
15326b754f9SFabio Estevam 	gpc |= DBGEN;
15426b754f9SFabio Estevam 	writel_relaxed(gpc, tigerp_base + ARM_GPC);
15526b754f9SFabio Estevam 	iounmap(tigerp_base);
15626b754f9SFabio Estevam exit:
15726b754f9SFabio Estevam 	of_node_put(np);
15826b754f9SFabio Estevam 
15926b754f9SFabio Estevam }
160