]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
f8027f6b | 2 | /* |
e628c8f7 | 3 | * Copyright 2009-2014 Freescale Semiconductor, Inc. |
5d3bcdb1 | 4 | * Copyright 2020 NXP |
f8027f6b | 5 | * |
a47a12be SR |
6 | * This file is derived from arch/powerpc/cpu/mpc85xx/cpu.c and |
7 | * arch/powerpc/cpu/mpc86xx/cpu.c. Basically this file contains | |
8d1f2682 | 8 | * cpu specific common code for 85xx/86xx processors. |
f8027f6b PA |
9 | */ |
10 | ||
d678a59d | 11 | #include <common.h> |
b5981474 | 12 | #include <cpu_func.h> |
b08c8c48 | 13 | #include <linux/libfdt.h> |
f8027f6b | 14 | #include <fdt_support.h> |
8f3a7fa4 | 15 | #include <asm/mp.h> |
a09b9b68 | 16 | #include <asm/fsl_serdes.h> |
865ff856 | 17 | #include <phy.h> |
72f4980b | 18 | #include <hwconfig.h> |
57567361 | 19 | |
8f3a7fa4 | 20 | #if defined(CONFIG_MP) && (defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx)) |
11beefa3 KG |
21 | static int ft_del_cpuhandle(void *blob, int cpuhandle) |
22 | { | |
23 | int off, ret = -FDT_ERR_NOTFOUND; | |
24 | ||
25 | /* if we find a match, we'll delete at it which point the offsets are | |
26 | * invalid so we start over from the beginning | |
27 | */ | |
28 | off = fdt_node_offset_by_prop_value(blob, -1, "cpu-handle", | |
29 | &cpuhandle, 4); | |
30 | while (off != -FDT_ERR_NOTFOUND) { | |
31 | fdt_delprop(blob, off, "cpu-handle"); | |
32 | ret = 1; | |
33 | off = fdt_node_offset_by_prop_value(blob, -1, "cpu-handle", | |
34 | &cpuhandle, 4); | |
35 | } | |
36 | ||
37 | return ret; | |
38 | } | |
39 | ||
f8027f6b PA |
40 | void ft_fixup_num_cores(void *blob) { |
41 | int off, num_cores, del_cores; | |
42 | ||
43 | del_cores = 0; | |
44 | num_cores = cpu_numcores(); | |
45 | ||
46 | off = fdt_node_offset_by_prop_value(blob, -1, "device_type", "cpu", 4); | |
47 | while (off != -FDT_ERR_NOTFOUND) { | |
48 | u32 *reg = (u32 *)fdt_getprop(blob, off, "reg", 0); | |
709389b6 | 49 | u32 phys_cpu_id = thread_to_core(*reg); |
f8027f6b | 50 | |
709389b6 | 51 | if (!is_core_valid(phys_cpu_id) || is_core_disabled(phys_cpu_id)) { |
11beefa3 KG |
52 | int ph = fdt_get_phandle(blob, off); |
53 | ||
54 | /* Delete the cpu node once there are no cpu handles */ | |
55 | if (-FDT_ERR_NOTFOUND == ft_del_cpuhandle(blob, ph)) { | |
56 | fdt_del_node(blob, off); | |
57 | del_cores++; | |
58 | } | |
59 | /* either we deleted some cpu handles or the cpu node | |
60 | * so we reset the offset back to the start since we | |
61 | * can't trust the offsets anymore | |
62 | */ | |
f8027f6b PA |
63 | off = -1; |
64 | } | |
65 | off = fdt_node_offset_by_prop_value(blob, off, | |
66 | "device_type", "cpu", 4); | |
67 | } | |
68 | debug ("%x core system found\n", num_cores); | |
69 | debug ("deleted %d extra core entry entries from device tree\n", | |
70 | del_cores); | |
71 | } | |
5d0c3b57 KP |
72 | #endif /* defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx) */ |
73 | ||
865ff856 | 74 | int fdt_fixup_phy_connection(void *blob, int offset, phy_interface_t phyc) |
a1964ea5 | 75 | { |
5d3bcdb1 FI |
76 | const char *conn; |
77 | ||
78 | /* Do NOT apply fixup for backplane modes specified in DT */ | |
79 | if (phyc == PHY_INTERFACE_MODE_XGMII) { | |
80 | conn = fdt_getprop(blob, offset, "phy-connection-type", NULL); | |
81 | if (is_backplane_mode(conn)) | |
82 | return 0; | |
83 | } | |
a1964ea5 | 84 | return fdt_setprop_string(blob, offset, "phy-connection-type", |
865ff856 | 85 | phy_string_for_interface(phyc)); |
a1964ea5 | 86 | } |
a09b9b68 KG |
87 | |
88 | #ifdef CONFIG_SYS_SRIO | |
9c42ef61 KG |
89 | static inline void ft_disable_srio_port(void *blob, int srio_off, int port) |
90 | { | |
91 | int off = fdt_node_offset_by_prop_value(blob, srio_off, | |
92 | "cell-index", &port, 4); | |
93 | if (off >= 0) { | |
94 | off = fdt_setprop_string(blob, off, "status", "disabled"); | |
95 | if (off > 0) | |
96 | printf("WARNING unable to set status for fsl,srio " | |
97 | "port %d: %s\n", port, fdt_strerror(off)); | |
98 | } | |
99 | } | |
100 | ||
101 | static inline void ft_disable_rman(void *blob) | |
102 | { | |
103 | int off = fdt_node_offset_by_compatible(blob, -1, "fsl,rman"); | |
104 | if (off >= 0) { | |
105 | off = fdt_setprop_string(blob, off, "status", "disabled"); | |
106 | if (off > 0) | |
107 | printf("WARNING unable to set status for fsl,rman %s\n", | |
108 | fdt_strerror(off)); | |
109 | } | |
110 | } | |
111 | ||
112 | static inline void ft_disable_rmu(void *blob) | |
113 | { | |
114 | int off = fdt_node_offset_by_compatible(blob, -1, "fsl,srio-rmu"); | |
115 | if (off >= 0) { | |
116 | off = fdt_setprop_string(blob, off, "status", "disabled"); | |
117 | if (off > 0) | |
118 | printf("WARNING unable to set status for " | |
119 | "fsl,srio-rmu %s\n", fdt_strerror(off)); | |
120 | } | |
121 | } | |
122 | ||
a09b9b68 KG |
123 | void ft_srio_setup(void *blob) |
124 | { | |
9c42ef61 KG |
125 | int srio1_used = 0, srio2_used = 0; |
126 | int srio_off; | |
127 | ||
128 | /* search for srio node, if doesn't exist just return - nothing todo */ | |
129 | srio_off = fdt_node_offset_by_compatible(blob, -1, "fsl,srio"); | |
130 | if (srio_off < 0) | |
ea253ad7 | 131 | return; |
9c42ef61 | 132 | |
a09b9b68 | 133 | #ifdef CONFIG_SRIO1 |
9c42ef61 KG |
134 | if (is_serdes_configured(SRIO1)) |
135 | srio1_used = 1; | |
a09b9b68 KG |
136 | #endif |
137 | #ifdef CONFIG_SRIO2 | |
9c42ef61 KG |
138 | if (is_serdes_configured(SRIO2)) |
139 | srio2_used = 1; | |
a09b9b68 | 140 | #endif |
9c42ef61 KG |
141 | |
142 | /* mark port1 disabled */ | |
143 | if (!srio1_used) | |
144 | ft_disable_srio_port(blob, srio_off, 1); | |
145 | ||
146 | /* mark port2 disabled */ | |
147 | if (!srio2_used) | |
148 | ft_disable_srio_port(blob, srio_off, 2); | |
149 | ||
150 | /* if both ports not used, disable controller, rmu and rman */ | |
151 | if (!srio1_used && !srio2_used) { | |
152 | fdt_setprop_string(blob, srio_off, "status", "disabled"); | |
153 | ||
154 | ft_disable_rman(blob); | |
155 | ft_disable_rmu(blob); | |
156 | } | |
a09b9b68 KG |
157 | } |
158 | #endif |