Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/powerpc/platforms/83xx/km83xx.c
26481 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
* Copyright 2008-2011 DENX Software Engineering GmbH
4
* Author: Heiko Schocher <[email protected]>
5
*
6
* Description:
7
* Keymile 83xx platform specific routines.
8
*/
9
10
#include <linux/stddef.h>
11
#include <linux/kernel.h>
12
#include <linux/init.h>
13
#include <linux/errno.h>
14
#include <linux/reboot.h>
15
#include <linux/pci.h>
16
#include <linux/kdev_t.h>
17
#include <linux/major.h>
18
#include <linux/console.h>
19
#include <linux/delay.h>
20
#include <linux/seq_file.h>
21
#include <linux/root_dev.h>
22
#include <linux/initrd.h>
23
#include <linux/of.h>
24
#include <linux/of_address.h>
25
26
#include <linux/atomic.h>
27
#include <linux/time.h>
28
#include <linux/io.h>
29
#include <asm/machdep.h>
30
#include <asm/ipic.h>
31
#include <asm/irq.h>
32
#include <asm/udbg.h>
33
#include <sysdev/fsl_soc.h>
34
#include <sysdev/fsl_pci.h>
35
#include <soc/fsl/qe/qe.h>
36
37
#include "mpc83xx.h"
38
39
#define SVR_REV(svr) (((svr) >> 0) & 0xFFFF) /* Revision field */
40
41
static void __init quirk_mpc8360e_qe_enet10(void)
42
{
43
/*
44
* handle mpc8360E Erratum QE_ENET10:
45
* RGMII AC values do not meet the specification
46
*/
47
uint svid = mfspr(SPRN_SVR);
48
struct device_node *np_par;
49
struct resource res;
50
void __iomem *base;
51
int ret;
52
53
np_par = of_find_node_by_name(NULL, "par_io");
54
if (np_par == NULL) {
55
pr_warn("%s couldn't find par_io node\n", __func__);
56
return;
57
}
58
/* Map Parallel I/O ports registers */
59
ret = of_address_to_resource(np_par, 0, &res);
60
if (ret) {
61
pr_warn("%s couldn't map par_io registers\n", __func__);
62
goto out;
63
}
64
65
base = ioremap(res.start, resource_size(&res));
66
if (!base)
67
goto out;
68
69
/*
70
* set output delay adjustments to default values according
71
* table 5 in Errata Rev. 5, 9/2011:
72
*
73
* write 0b01 to UCC1 bits 18:19
74
* write 0b01 to UCC2 option 1 bits 4:5
75
* write 0b01 to UCC2 option 2 bits 16:17
76
*/
77
clrsetbits_be32((base + 0xa8), 0x0c00f000, 0x04005000);
78
79
/*
80
* set output delay adjustments to default values according
81
* table 3-13 in Reference Manual Rev.3 05/2010:
82
*
83
* write 0b01 to UCC2 option 2 bits 16:17
84
* write 0b0101 to UCC1 bits 20:23
85
* write 0b0101 to UCC2 option 1 bits 24:27
86
*/
87
clrsetbits_be32((base + 0xac), 0x0000cff0, 0x00004550);
88
89
if (SVR_REV(svid) == 0x0021) {
90
/*
91
* UCC2 option 1: write 0b1010 to bits 24:27
92
* at address IMMRBAR+0x14AC
93
*/
94
clrsetbits_be32((base + 0xac), 0x000000f0, 0x000000a0);
95
} else if (SVR_REV(svid) == 0x0020) {
96
/*
97
* UCC1: write 0b11 to bits 18:19
98
* at address IMMRBAR+0x14A8
99
*/
100
setbits32((base + 0xa8), 0x00003000);
101
102
/*
103
* UCC2 option 1: write 0b11 to bits 4:5
104
* at address IMMRBAR+0x14A8
105
*/
106
setbits32((base + 0xa8), 0x0c000000);
107
108
/*
109
* UCC2 option 2: write 0b11 to bits 16:17
110
* at address IMMRBAR+0x14AC
111
*/
112
setbits32((base + 0xac), 0x0000c000);
113
}
114
iounmap(base);
115
out:
116
of_node_put(np_par);
117
}
118
119
/* ************************************************************************
120
*
121
* Setup the architecture
122
*
123
*/
124
static void __init mpc83xx_km_setup_arch(void)
125
{
126
#ifdef CONFIG_QUICC_ENGINE
127
struct device_node *np;
128
#endif
129
130
mpc83xx_setup_arch();
131
132
#ifdef CONFIG_QUICC_ENGINE
133
np = of_find_node_by_name(NULL, "par_io");
134
if (np != NULL) {
135
par_io_init(np);
136
of_node_put(np);
137
138
for_each_node_by_name(np, "spi")
139
par_io_of_config(np);
140
141
for_each_node_by_name(np, "ucc")
142
par_io_of_config(np);
143
144
/* Only apply this quirk when par_io is available */
145
np = of_find_compatible_node(NULL, "network", "ucc_geth");
146
if (np != NULL) {
147
quirk_mpc8360e_qe_enet10();
148
of_node_put(np);
149
}
150
}
151
#endif /* CONFIG_QUICC_ENGINE */
152
}
153
154
machine_device_initcall(mpc83xx_km, mpc83xx_declare_of_platform_devices);
155
156
/* list of the supported boards */
157
static char *board[] __initdata = {
158
"Keymile,KMETER1",
159
"Keymile,kmpbec8321",
160
NULL
161
};
162
163
/*
164
* Called very early, MMU is off, device-tree isn't unflattened
165
*/
166
static int __init mpc83xx_km_probe(void)
167
{
168
int i = 0;
169
170
while (board[i]) {
171
if (of_machine_is_compatible(board[i]))
172
break;
173
i++;
174
}
175
return (board[i] != NULL);
176
}
177
178
define_machine(mpc83xx_km) {
179
.name = "mpc83xx-km-platform",
180
.probe = mpc83xx_km_probe,
181
.setup_arch = mpc83xx_km_setup_arch,
182
.discover_phbs = mpc83xx_setup_pci,
183
.init_IRQ = mpc83xx_ipic_init_IRQ,
184
.get_irq = ipic_get_irq,
185
.restart = mpc83xx_restart,
186
.time_init = mpc83xx_time_init,
187
.progress = udbg_progress,
188
};
189
190