Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/powerpc/sysdev/fsl_soc.c
26442 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
* FSL SoC setup code
4
*
5
* Maintained by Kumar Gala (see MAINTAINERS for contact information)
6
*
7
* 2006 (c) MontaVista Software, Inc.
8
* Vitaly Bordug <[email protected]>
9
*/
10
11
#include <linux/stddef.h>
12
#include <linux/kernel.h>
13
#include <linux/init.h>
14
#include <linux/errno.h>
15
#include <linux/major.h>
16
#include <linux/delay.h>
17
#include <linux/irq.h>
18
#include <linux/export.h>
19
#include <linux/device.h>
20
#include <linux/platform_device.h>
21
#include <linux/of.h>
22
#include <linux/phy.h>
23
#include <linux/spi/spi.h>
24
#include <linux/fsl_devices.h>
25
#include <linux/reboot.h>
26
27
#include <linux/atomic.h>
28
#include <asm/io.h>
29
#include <asm/irq.h>
30
#include <asm/time.h>
31
#include <asm/machdep.h>
32
#include <sysdev/fsl_soc.h>
33
#include <mm/mmu_decl.h>
34
#include <asm/cpm2.h>
35
#include <asm/fsl_hcalls.h> /* For the Freescale hypervisor */
36
37
static phys_addr_t immrbase = -1;
38
39
phys_addr_t get_immrbase(void)
40
{
41
struct device_node *soc;
42
43
if (immrbase != -1)
44
return immrbase;
45
46
soc = of_find_node_by_type(NULL, "soc");
47
if (soc) {
48
struct resource res;
49
50
if (!of_range_to_resource(soc, 0, &res))
51
immrbase = res.start;
52
53
of_node_put(soc);
54
}
55
56
return immrbase;
57
}
58
59
EXPORT_SYMBOL(get_immrbase);
60
61
u32 fsl_get_sys_freq(void)
62
{
63
static u32 sysfreq = -1;
64
struct device_node *soc;
65
66
if (sysfreq != -1)
67
return sysfreq;
68
69
soc = of_find_node_by_type(NULL, "soc");
70
if (!soc)
71
return -1;
72
73
of_property_read_u32(soc, "clock-frequency", &sysfreq);
74
if (sysfreq == -1 || !sysfreq)
75
of_property_read_u32(soc, "bus-frequency", &sysfreq);
76
77
of_node_put(soc);
78
return sysfreq;
79
}
80
EXPORT_SYMBOL(fsl_get_sys_freq);
81
82
#if defined(CONFIG_CPM) || defined(CONFIG_QUICC_ENGINE)
83
84
u32 get_brgfreq(void)
85
{
86
static u32 brgfreq = -1;
87
struct device_node *node;
88
89
if (brgfreq != -1)
90
return brgfreq;
91
92
node = of_find_compatible_node(NULL, NULL, "fsl,cpm-brg");
93
if (node) {
94
of_property_read_u32(node, "clock-frequency", &brgfreq);
95
of_node_put(node);
96
return brgfreq;
97
}
98
99
/* Legacy device binding -- will go away when no users are left. */
100
node = of_find_node_by_type(NULL, "cpm");
101
if (!node)
102
node = of_find_compatible_node(NULL, NULL, "fsl,qe");
103
if (!node)
104
node = of_find_node_by_type(NULL, "qe");
105
106
if (node) {
107
of_property_read_u32(node, "brg-frequency", &brgfreq);
108
if (brgfreq == -1 || !brgfreq)
109
if (!of_property_read_u32(node, "bus-frequency",
110
&brgfreq))
111
brgfreq /= 2;
112
of_node_put(node);
113
}
114
115
return brgfreq;
116
}
117
118
EXPORT_SYMBOL(get_brgfreq);
119
120
u32 get_baudrate(void)
121
{
122
static u32 fs_baudrate = -1;
123
struct device_node *node;
124
125
if (fs_baudrate != -1)
126
return fs_baudrate;
127
128
node = of_find_node_by_type(NULL, "serial");
129
if (node) {
130
of_property_read_u32(node, "current-speed", &fs_baudrate);
131
of_node_put(node);
132
}
133
134
return fs_baudrate;
135
}
136
137
EXPORT_SYMBOL(get_baudrate);
138
#endif /* CONFIG_CPM2 */
139
140
#if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
141
static __be32 __iomem *rstcr;
142
143
static int fsl_rstcr_restart(struct notifier_block *this,
144
unsigned long mode, void *cmd)
145
{
146
local_irq_disable();
147
/* set reset control register */
148
out_be32(rstcr, 0x2); /* HRESET_REQ */
149
150
return NOTIFY_DONE;
151
}
152
153
static int __init setup_rstcr(void)
154
{
155
struct device_node *np;
156
157
static struct notifier_block restart_handler = {
158
.notifier_call = fsl_rstcr_restart,
159
.priority = 128,
160
};
161
162
for_each_node_by_name(np, "global-utilities") {
163
if (of_property_read_bool(np, "fsl,has-rstcr")) {
164
rstcr = of_iomap(np, 0) + 0xb0;
165
if (!rstcr) {
166
printk (KERN_ERR "Error: reset control "
167
"register not mapped!\n");
168
} else {
169
register_restart_handler(&restart_handler);
170
}
171
break;
172
}
173
}
174
175
of_node_put(np);
176
177
return 0;
178
}
179
180
arch_initcall(setup_rstcr);
181
182
#endif
183
184
#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
185
struct platform_diu_data_ops diu_ops;
186
EXPORT_SYMBOL(diu_ops);
187
#endif
188
189
#ifdef CONFIG_EPAPR_PARAVIRT
190
/*
191
* Restart the current partition
192
*
193
* This function should be assigned to the ppc_md.restart function pointer,
194
* to initiate a partition restart when we're running under the Freescale
195
* hypervisor.
196
*/
197
void __noreturn fsl_hv_restart(char *cmd)
198
{
199
pr_info("hv restart\n");
200
fh_partition_restart(-1);
201
while (1) ;
202
}
203
204
/*
205
* Halt the current partition
206
*
207
* This function should be assigned to the pm_power_off and ppc_md.halt
208
* function pointers, to shut down the partition when we're running under
209
* the Freescale hypervisor.
210
*/
211
void __noreturn fsl_hv_halt(void)
212
{
213
pr_info("hv exit\n");
214
fh_partition_stop(-1);
215
while (1) ;
216
}
217
#endif
218
219