1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * Copyright 2008-2011 DENX Software Engineering GmbH |
4 | * Author: Heiko Schocher <hs@denx.de> |
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, name: "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(dev: np_par, index: 0, r: &res); |
60 | if (ret) { |
61 | pr_warn("%s couldn't map par_io registers\n" , __func__); |
62 | goto out; |
63 | } |
64 | |
65 | base = ioremap(offset: res.start, size: resource_size(res: &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(addr: base); |
115 | out: |
116 | of_node_put(node: 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, name: "par_io" ); |
134 | if (np != NULL) { |
135 | par_io_init(np); |
136 | of_node_put(node: 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, type: "network" , compat: "ucc_geth" ); |
146 | if (np != NULL) { |
147 | quirk_mpc8360e_qe_enet10(); |
148 | of_node_put(node: 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(compat: 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 | |