1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2018
4  * Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
5  */
6 
7 #include <bitfield.h>
8 #include <clk.h>
9 #include <cpu.h>
10 #include <dm.h>
11 #include <log.h>
12 #include <stdio.h>
13 #include <linux/bitops.h>
14 
15 #include "mpc83xx_cpu.h"
16 
17 /**
18  * struct mpc83xx_cpu_priv - Private data for MPC83xx CPUs
19  * @e300_type:      The e300 core type of the MPC83xx CPU
20  * @family:         The MPC83xx family the CPU belongs to
21  * @type:           The MPC83xx type of the CPU
22  * @is_e_processor: Flag indicating whether the CPU is a E processor or not
23  * @is_a_variant:   Flag indicating whtther the CPU is a A variant or not
24  * @revid:          The revision ID of the CPU
25  * @revid.major:    The major part of the CPU's revision ID
26  * @revid.minor:    The minor part of the CPU's revision ID
27  */
28 struct mpc83xx_cpu_priv {
29 	enum e300_type e300_type;
30 	enum mpc83xx_cpu_family family;
31 	enum mpc83xx_cpu_type type;
32 	bool is_e_processor;
33 	bool is_a_variant;
34 	struct {
35 		uint major;
36 		uint minor;
37 	} revid;
38 };
39 
checkcpu(void)40 int checkcpu(void)
41 {
42 	/* Activate all CPUs  from board_f.c */
43 	return cpu_probe_all();
44 }
45 
46 /**
47  * get_spridr() - Read SPRIDR (System Part and Revision ID Register) of CPU
48  *
49  * Return: The SPRIDR value
50  */
get_spridr(void)51 static inline u32 get_spridr(void)
52 {
53 	immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
54 
55 	return in_be32(&immr->sysconf.spridr);
56 }
57 
58 /**
59  * determine_type() - Determine CPU family of MPC83xx device
60  * @dev: CPU device from which to read CPU family from
61  */
determine_family(const struct udevice * dev)62 static inline void determine_family(const struct udevice *dev)
63 {
64 	struct mpc83xx_cpu_priv *priv = dev_get_priv(dev);
65 	/* Upper 12 bits of PARTID field (bits 0-23 in SPRIDR) */
66 	const u32 PARTID_FAMILY_MASK = 0xFFF00000;
67 
68 	switch (bitfield_extract_by_mask(get_spridr(), PARTID_FAMILY_MASK)) {
69 	case 0x810:
70 	case 0x811:
71 		priv->family = FAMILY_830X;
72 		break;
73 	case 0x80B:
74 		priv->family = FAMILY_831X;
75 		break;
76 	case 0x806:
77 		priv->family = FAMILY_832X;
78 		break;
79 	case 0x803:
80 		priv->family = FAMILY_834X;
81 		break;
82 	case 0x804:
83 		priv->family = FAMILY_836X;
84 		break;
85 	case 0x80C:
86 		priv->family = FAMILY_837X;
87 		break;
88 	default:
89 		priv->family = FAMILY_UNKNOWN;
90 	}
91 }
92 
93 /**
94  * determine_type() - Determine CPU type of MPC83xx device
95  * @dev: CPU device from which to read CPU type from
96  */
determine_type(const struct udevice * dev)97 static inline void determine_type(const struct udevice *dev)
98 {
99 	struct mpc83xx_cpu_priv *priv = dev_get_priv(dev);
100 	/* Upper 16 bits of PVR (Processor Version Register) */
101 	const u32 PCR_UPPER_MASK = 0xFFFF0000;
102 	u32 val;
103 
104 	val = bitfield_extract_by_mask(get_spridr(), PCR_UPPER_MASK);
105 
106 	/* Mask out E-variant bit */
107 	switch (val & 0xFFFE) {
108 	case 0x8100:
109 		priv->type = TYPE_8308;
110 		break;
111 	case 0x8110:
112 		priv->type = TYPE_8309;
113 		break;
114 	case 0x80B2:
115 		priv->type = TYPE_8311;
116 		break;
117 	case 0x80B0:
118 		priv->type = TYPE_8313;
119 		break;
120 	case 0x80B6:
121 		priv->type = TYPE_8314;
122 		break;
123 	case 0x80B4:
124 		priv->type = TYPE_8315;
125 		break;
126 	case 0x8066:
127 		priv->type = TYPE_8321;
128 		break;
129 	case 0x8062:
130 		priv->type = TYPE_8323;
131 		break;
132 	case 0x8036:
133 		priv->type = TYPE_8343;
134 		break;
135 	case 0x8032:
136 		priv->type = TYPE_8347_TBGA;
137 		break;
138 	case 0x8034:
139 		priv->type = TYPE_8347_PBGA;
140 		break;
141 	case 0x8030:
142 		priv->type = TYPE_8349;
143 		break;
144 	case 0x804A:
145 		priv->type = TYPE_8358_TBGA;
146 		break;
147 	case 0x804E:
148 		priv->type = TYPE_8358_PBGA;
149 		break;
150 	case 0x8048:
151 		priv->type = TYPE_8360;
152 		break;
153 	case 0x80C6:
154 		priv->type = TYPE_8377;
155 		break;
156 	case 0x80C4:
157 		priv->type = TYPE_8378;
158 		break;
159 	case 0x80C2:
160 		priv->type = TYPE_8379;
161 		break;
162 	default:
163 		priv->type = TYPE_UNKNOWN;
164 	}
165 }
166 
167 /**
168  * determine_e300_type() - Determine e300 core type of MPC83xx device
169  * @dev: CPU device from which to read e300 core type from
170  */
determine_e300_type(const struct udevice * dev)171 static inline void determine_e300_type(const struct udevice *dev)
172 {
173 	struct mpc83xx_cpu_priv *priv = dev_get_priv(dev);
174 	/* Upper 16 bits of PVR (Processor Version Register) */
175 	const u32 PCR_UPPER_MASK = 0xFFFF0000;
176 	u32 pvr = get_pvr();
177 
178 	switch ((pvr & PCR_UPPER_MASK) >> 16) {
179 	case 0x8083:
180 		priv->e300_type = E300C1;
181 		break;
182 	case 0x8084:
183 		priv->e300_type = E300C2;
184 		break;
185 	case 0x8085:
186 		priv->e300_type = E300C3;
187 		break;
188 	case 0x8086:
189 		priv->e300_type = E300C4;
190 		break;
191 	default:
192 		priv->e300_type = E300_UNKNOWN;
193 	}
194 }
195 
196 /**
197  * determine_revid() - Determine revision ID of CPU device
198  * @dev: CPU device from which to read revision ID
199  */
determine_revid(const struct udevice * dev)200 static inline void determine_revid(const struct udevice *dev)
201 {
202 	struct mpc83xx_cpu_priv *priv = dev_get_priv(dev);
203 	u32 REVID_MAJOR_MASK;
204 	u32 REVID_MINOR_MASK;
205 	u32 spridr = get_spridr();
206 
207 	if (priv->family == FAMILY_834X) {
208 		REVID_MAJOR_MASK = 0x0000FF00;
209 		REVID_MINOR_MASK = 0x000000FF;
210 	} else {
211 		REVID_MAJOR_MASK = 0x000000F0;
212 		REVID_MINOR_MASK = 0x0000000F;
213 	}
214 
215 	priv->revid.major = bitfield_extract_by_mask(spridr, REVID_MAJOR_MASK);
216 	priv->revid.minor = bitfield_extract_by_mask(spridr, REVID_MINOR_MASK);
217 }
218 
219 /**
220  * determine_cpu_data() - Determine CPU information from hardware
221  * @dev: CPU device from which to read information
222  */
determine_cpu_data(const struct udevice * dev)223 static void determine_cpu_data(const struct udevice *dev)
224 {
225 	struct mpc83xx_cpu_priv *priv = dev_get_priv(dev);
226 	const u32 E_FLAG_MASK = 0x00010000;
227 	u32 spridr = get_spridr();
228 
229 	determine_family(dev);
230 	determine_type(dev);
231 	determine_e300_type(dev);
232 	determine_revid(dev);
233 
234 	if ((priv->family == FAMILY_834X ||
235 	     priv->family == FAMILY_836X) && priv->revid.major >= 2)
236 		priv->is_a_variant = true;
237 
238 	priv->is_e_processor = !bitfield_extract_by_mask(spridr, E_FLAG_MASK);
239 }
240 
mpc83xx_cpu_get_desc(const struct udevice * dev,char * buf,int size)241 static int mpc83xx_cpu_get_desc(const struct udevice *dev, char *buf, int size)
242 {
243 	struct mpc83xx_cpu_priv *priv = dev_get_priv(dev);
244 	struct clk core_clk;
245 	struct clk csb_clk;
246 	char core_freq[32];
247 	char csb_freq[32];
248 	int ret;
249 
250 	ret = clk_get_by_index((struct udevice *)dev, 0, &core_clk);
251 	if (ret) {
252 		debug("%s: Failed to get core clock (err = %d)\n",
253 		      dev->name, ret);
254 		return ret;
255 	}
256 
257 	ret = clk_get_by_index((struct udevice *)dev, 1, &csb_clk);
258 	if (ret) {
259 		debug("%s: Failed to get CSB clock (err = %d)\n",
260 		      dev->name, ret);
261 		return ret;
262 	}
263 
264 	determine_cpu_data(dev);
265 
266 	snprintf(buf, size,
267 		 "%s, MPC%s%s%s, Rev: %d.%d at %s MHz, CSB: %s MHz",
268 		 e300_names[priv->e300_type],
269 		 cpu_type_names[priv->type],
270 		 priv->is_e_processor ? "E" : "",
271 		 priv->is_a_variant ? "A" : "",
272 		 priv->revid.major,
273 		 priv->revid.minor,
274 		 strmhz(core_freq, clk_get_rate(&core_clk)),
275 		 strmhz(csb_freq, clk_get_rate(&csb_clk)));
276 
277 	return 0;
278 }
279 
mpc83xx_cpu_get_info(const struct udevice * dev,struct cpu_info * info)280 static int mpc83xx_cpu_get_info(const struct udevice *dev,
281 				struct cpu_info *info)
282 {
283 	struct clk clock;
284 	int ret;
285 	ulong freq;
286 
287 	ret = clk_get_by_index((struct udevice *)dev, 0, &clock);
288 	if (ret) {
289 		debug("%s: Failed to get core clock (err = %d)\n",
290 		      dev->name, ret);
291 		return ret;
292 	}
293 
294 	freq = clk_get_rate(&clock);
295 	if (!freq) {
296 		debug("%s: Core clock speed is zero\n", dev->name);
297 		return -EINVAL;
298 	}
299 
300 	info->cpu_freq = freq;
301 	info->features = BIT(CPU_FEAT_L1_CACHE) | BIT(CPU_FEAT_MMU);
302 
303 	return 0;
304 }
305 
mpc83xx_cpu_get_count(const struct udevice * dev)306 static int mpc83xx_cpu_get_count(const struct udevice *dev)
307 {
308 	/* We have one e300cX core */
309 	return 1;
310 }
311 
mpc83xx_cpu_get_vendor(const struct udevice * dev,char * buf,int size)312 static int mpc83xx_cpu_get_vendor(const struct udevice *dev, char *buf,
313 				  int size)
314 {
315 	snprintf(buf, size, "NXP");
316 
317 	return 0;
318 }
319 
320 static const struct cpu_ops mpc83xx_cpu_ops = {
321 	.get_desc = mpc83xx_cpu_get_desc,
322 	.get_info = mpc83xx_cpu_get_info,
323 	.get_count = mpc83xx_cpu_get_count,
324 	.get_vendor = mpc83xx_cpu_get_vendor,
325 };
326 
mpc83xx_cpu_probe(struct udevice * dev)327 static int mpc83xx_cpu_probe(struct udevice *dev)
328 {
329 	return 0;
330 }
331 
332 static const struct udevice_id mpc83xx_cpu_ids[] = {
333 	{ .compatible = "fsl,mpc83xx", },
334 	{ .compatible = "fsl,mpc8308", },
335 	{ .compatible = "fsl,mpc8309", },
336 	{ .compatible = "fsl,mpc8313", },
337 	{ .compatible = "fsl,mpc8315", },
338 	{ .compatible = "fsl,mpc832x", },
339 	{ .compatible = "fsl,mpc8349", },
340 	{ .compatible = "fsl,mpc8360", },
341 	{ .compatible = "fsl,mpc8379", },
342 	{ /* sentinel */ }
343 };
344 
345 U_BOOT_DRIVER(mpc83xx_cpu) = {
346 	.name = "mpc83xx_cpu",
347 	.id = UCLASS_CPU,
348 	.of_match = mpc83xx_cpu_ids,
349 	.probe = mpc83xx_cpu_probe,
350 	.priv_auto	= sizeof(struct mpc83xx_cpu_priv),
351 	.ops = &mpc83xx_cpu_ops,
352 	.flags = DM_FLAG_PRE_RELOC,
353 };
354