1 /* Copyright 2013-2014 IBM Corp.
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * 	http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12  * implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <device.h>
18 #include "spira.h"
19 #include <cpu.h>
20 #include <vpd.h>
21 #include <ccan/str/str.h>
22 #include <interrupts.h>
23 #include <inttypes.h>
24 #include <phys-map.h>
25 #include <chip.h>
26 #include <ipmi.h>
27 
28 #include "hdata.h"
29 
30 enum sp_type {
31 	SP_BAD = 0,
32 	SP_UNKNOWN,
33 	SP_FSP,
34 	SP_BMC,
35 };
36 
37 static const char * const sp_names[] = {
38 	"Broken", "Unknown", "FSP", "BMC",
39 };
40 
find_service_proc_type(const struct HDIF_common_hdr * spss,int index)41 static enum sp_type find_service_proc_type(const struct HDIF_common_hdr *spss,
42 		int index)
43 {
44 	const struct spss_sp_impl *sp_impl;
45 	int hw_ver, sw_ver, flags;
46 	enum sp_type sp_type;
47 	bool functional, installed;
48 
49 	/* Find an check the SP Implementation structure */
50 	sp_impl = HDIF_get_idata(spss, SPSS_IDATA_SP_IMPL, NULL);
51 	if (!CHECK_SPPTR(sp_impl)) {
52 		prerror("SP #%d: SPSS/SP_Implementation not found !\n", index);
53 		return SP_BAD;
54 	}
55 
56 	hw_ver = be16_to_cpu(sp_impl->hw_version);
57 	sw_ver = be16_to_cpu(sp_impl->sw_version);
58 	flags  = be16_to_cpu(sp_impl->func_flags);
59 
60 	switch (hw_ver) {
61 	case 0x1:
62 	case 0x2: /* We only support FSP2 */
63 		sp_type = SP_FSP;
64 		break;
65 	case 0x3:
66 		sp_type = SP_BMC;
67 		break;
68 	default:
69 		sp_type = SP_UNKNOWN;
70 	}
71 
72 	if (sp_type == SP_UNKNOWN)
73 		return SP_UNKNOWN;
74 
75 	installed  = !!(flags & SPSS_SP_IMPL_FLAGS_INSTALLED);
76 	functional = !!(flags & SPSS_SP_IMPL_FLAGS_FUNCTIONAL);
77 
78 	if (!installed || !functional) {
79 		prerror("%s #%d not usable: %sinstalled, %sfunctional\n",
80 			sp_names[sp_type], index,
81 			installed  ? "" : "not ",
82 			functional ? "" : "not ");
83 
84 		return SP_BAD;
85 	}
86 
87 	prlog(PR_INFO, "%s #%d: HW version %d, SW version %d, chip DD%d.%d\n",
88 	      sp_names[sp_type], index, hw_ver, sw_ver,
89 	      sp_impl->chip_version >> 4,
90 	      sp_impl->chip_version & 0xf);
91 
92 	return sp_type;
93 }
94 
95 /*
96  * Note on DT representation of the PSI links and FSPs:
97  *
98  * We create a XSCOM node for each PSI host bridge(one per chip),
99  *
100  * This is done in spira.c
101  *
102  * We do not create the /psi MMIO variant at this stage, it will
103  * be added by the psi driver in skiboot.
104  *
105  * We do not put the FSP(s) as children of these. Instead, we create
106  * a top-level /fsps node with the FSPs as children.
107  *
108  * Each FSP then has a "links" property which is an array of chip IDs
109  */
110 
fsp_create_node(const void * spss,int i,struct dt_node * parent)111 static struct dt_node *fsp_create_node(const void *spss, int i,
112 				       struct dt_node *parent)
113 {
114 	const struct spss_sp_impl *sp_impl;
115 	struct dt_node *node;
116 
117 	sp_impl = HDIF_get_idata(spss, SPSS_IDATA_SP_IMPL, NULL);
118 
119 	node = dt_new_addr(parent, "fsp", i);
120 	assert(node);
121 
122 	dt_add_property_cells(node, "reg", i);
123 
124 	if (be16_to_cpu(sp_impl->hw_version) == 1) {
125 		dt_add_property_strings(node, "compatible", "ibm,fsp",
126 				"ibm,fsp1");
127 		/* Offset into the FSP MMIO space where the mailbox
128 		 * registers are */
129 		/* seen in the FSP1 spec */
130 		dt_add_property_cells(node, "reg-offset", 0xb0016000);
131 	} else if (be16_to_cpu(sp_impl->hw_version) == 2) {
132 		dt_add_property_strings(node, "compatible", "ibm,fsp",
133 				"ibm,fsp2");
134 		dt_add_property_cells(node, "reg-offset", 0xb0011000);
135 	}
136 	dt_add_property_cells(node, "hw-version", be16_to_cpu(sp_impl->hw_version));
137 	dt_add_property_cells(node, "sw-version", be16_to_cpu(sp_impl->sw_version));
138 
139 	if (be16_to_cpu(sp_impl->func_flags) & SPSS_SP_IMPL_FLAGS_PRIMARY)
140 		dt_add_property(node, "primary", NULL, 0);
141 
142 	return node;
143 }
144 
fsp_create_link(const struct spss_iopath * iopath,int index,int fsp_index)145 static uint32_t fsp_create_link(const struct spss_iopath *iopath, int index,
146 				int fsp_index)
147 {
148 	struct dt_node *node;
149 	const char *ststr;
150 	bool current = false;
151 	bool working = false;
152 	uint32_t chip_id;
153 
154 	switch(be16_to_cpu(iopath->psi.link_status)) {
155 	case SPSS_IO_PATH_PSI_LINK_BAD_FRU:
156 		ststr = "Broken";
157 		break;
158 	case SPSS_IO_PATH_PSI_LINK_CURRENT:
159 		ststr = "Active";
160 		current = working = true;
161 		break;
162 	case SPSS_IO_PATH_PSI_LINK_BACKUP:
163 		ststr = "Backup";
164 		working = true;
165 		break;
166 	default:
167 		ststr = "Unknown";
168 	}
169 	prlog(PR_DEBUG, "FSP #%d: IO PATH %d is %s PSI Link, GXHB at %" PRIx64 "\n",
170 	      fsp_index, index, ststr, be64_to_cpu(iopath->psi.gxhb_base));
171 
172 	chip_id = pcid_to_chip_id(be32_to_cpu(iopath->psi.proc_chip_id));
173 	node = dt_find_compatible_node_on_chip(dt_root, NULL, "ibm,psihb-x",
174 					       chip_id);
175 	if (!node) {
176 		prerror("FSP #%d: Can't find psihb node for link %d\n",
177 			fsp_index, index);
178 	} else {
179 		if (current)
180 			dt_add_property(node, "boot-link", NULL, 0);
181 		dt_add_property_strings(node, "status", working ? "ok" : "bad");
182 	}
183 
184 	return chip_id;
185 }
186 
fsp_create_links(const void * spss,int index,struct dt_node * fsp_node)187 static void fsp_create_links(const void *spss, int index,
188 			     struct dt_node *fsp_node)
189 {
190 	uint32_t *links = NULL;
191 	unsigned int i, lp, lcount = 0;
192 	int count;
193 
194 	count = HDIF_get_iarray_size(spss, SPSS_IDATA_SP_IOPATH);
195 	if (count < 0) {
196 		prerror("FSP #%d: Can't find IO PATH array size !\n", index);
197 		return;
198 	}
199 	prlog(PR_DEBUG, "FSP #%d: Found %d IO PATH\n", index, count);
200 
201 	/* Iterate all links */
202 	for (i = 0; i < count; i++) {
203 		const struct spss_iopath *iopath;
204 		unsigned int iopath_sz;
205 		uint32_t chip;
206 
207 		iopath = HDIF_get_iarray_item(spss, SPSS_IDATA_SP_IOPATH,
208 					      i, &iopath_sz);
209 		if (!CHECK_SPPTR(iopath)) {
210 			prerror("FSP #%d: Can't find IO PATH %d\n", index, i);
211 			break;
212 		}
213 		if (be16_to_cpu(iopath->iopath_type) != SPSS_IOPATH_TYPE_PSI) {
214 			prerror("FSP #%d: Unsupported IO PATH %d type 0x%04x\n",
215 				index, i, iopath->iopath_type);
216 			continue;
217 		}
218 
219 		chip = fsp_create_link(iopath, i, index);
220 		lp = lcount++;
221 		links = realloc(links, 4 * lcount);
222 		links[lp] = chip;
223 	}
224 	if (links)
225 		dt_add_property(fsp_node, "ibm,psi-links", links, lcount * 4);
226 
227 	free(links);
228 }
229 
add_lpc_io_node(struct dt_node * parent,const char * name,u32 offset,u32 size)230 static struct dt_node *add_lpc_io_node(struct dt_node *parent,
231 	const char *name, u32 offset, u32 size)
232 {
233 	struct dt_node *n;
234 	char buffer[32];
235 
236 	/*
237 	 * LPC bus addresses have strange DT names, they have the
238 	 * Bus address space embedded into the unit address e.g.
239 	 * serial@i3f8 - refers to offset 0x3f8 in the IO space
240 	 */
241 
242 	snprintf(buffer, sizeof(buffer), "%s@i%x", name, offset);
243 	n = dt_new(parent, buffer);
244 	assert(n);
245 
246 	/* first address cell of 1 indicates the LPC IO space */
247 	dt_add_property_cells(n, "reg", 1, offset, size);
248 
249 	return n;
250 }
251 
add_uart(const struct spss_iopath * iopath,struct dt_node * lpc)252 static void add_uart(const struct spss_iopath *iopath, struct dt_node *lpc)
253 {
254 	struct dt_node *serial;
255 	u64 base;
256 
257 	/* XXX: The spec says this is supposed to be a MMIO address.
258 	 *      However, in practice we get an LPC IO Space offset.
259 	 */
260 	base = be64_to_cpu(iopath->lpc.uart_base);
261 
262 	serial = add_lpc_io_node(lpc, "serial", base,
263 		be32_to_cpu(iopath->lpc.uart_size));
264 
265 	dt_add_property_string(serial, "compatible", "ns16550");
266 
267 	dt_add_property_cells(serial, "current-speed",
268 		be32_to_cpu(iopath->lpc.uart_baud));
269 	dt_add_property_cells(serial, "clock-frequency",
270 		be32_to_cpu(iopath->lpc.uart_clk));
271 	dt_add_property_cells(serial, "interrupts",
272 		be32_to_cpu(iopath->lpc.uart_int_number));
273 	dt_add_property_string(serial, "device_type", "serial");
274 
275 
276 	prlog(PR_DEBUG, "LPC UART: base addr = %#" PRIx64" (%#" PRIx64 ") size = %#x clk = %u, baud = %u\n",
277 		be64_to_cpu(iopath->lpc.uart_base),
278 		base,
279 		be32_to_cpu(iopath->lpc.uart_size),
280 		be32_to_cpu(iopath->lpc.uart_clk),
281 		be32_to_cpu(iopath->lpc.uart_baud));
282 }
283 
add_chip_id_to_sensors(struct dt_node * sensor_node,__be32 slca_index)284 static void add_chip_id_to_sensors(struct dt_node *sensor_node, __be32 slca_index)
285 {
286 	unsigned int i;
287 	const void *hdif;
288 	const struct slca_entry *slca;
289 	const struct spira_fru_id *fru_id;
290 	const struct sppcrd_chip_info *cinfo;
291 
292 	slca = slca_get_entry(slca_index);
293 	if (slca == NULL) {
294 		prlog(PR_WARNING, "SENSORS: Invalid slca index\n");
295 		return;
296 	}
297 
298 	for_each_ntuple_idx(&spira.ntuples.proc_chip, hdif, i, SPPCRD_HDIF_SIG) {
299 		fru_id = HDIF_get_idata(hdif, SPPCRD_IDATA_FRU_ID, NULL);
300 		if (!fru_id)
301 			return;
302 
303 		if (fru_id->rsrc_id != slca->rsrc_id)
304 			continue;
305 
306 		cinfo = HDIF_get_idata(hdif, SPPCRD_IDATA_CHIP_INFO, NULL);
307 		if (!CHECK_SPPTR(cinfo)) {
308 			prlog(PR_ERR, "SENSORS: Bad ChipID data %d\n", i);
309 			return;
310 		}
311 
312 		dt_add_property_cells(sensor_node,
313 				      "ibm,chip-id", be32_to_cpu(cinfo->xscom_id));
314 		return;
315 	}
316 }
317 
add_ipmi_sensors(struct dt_node * bmc_node)318 static void add_ipmi_sensors(struct dt_node *bmc_node)
319 {
320 	int i;
321 	const struct HDIF_common_hdr *hdif_sensor;
322 	const struct ipmi_sensors *ipmi_sensors;
323 	struct dt_node *sensors_node, *sensor_node;
324 
325 	hdif_sensor = get_hdif(&spira.ntuples.ipmi_sensor, IPMI_SENSORS_HDIF_SIG);
326 	if (!hdif_sensor) {
327 		prlog(PR_DEBUG, "SENSORS: Missing IPMI sensors mappings tuple\n");
328 		return;
329 	}
330 
331 	ipmi_sensors = HDIF_get_idata(hdif_sensor, IPMI_SENSORS_IDATA_SENSORS, NULL);
332 	if (!ipmi_sensors) {
333 		prlog(PR_DEBUG, "SENSORS: bad data\n");
334 		return;
335 	}
336 
337 	sensors_node = dt_new(bmc_node, "sensors");
338 	assert(sensors_node);
339 
340 	dt_add_property_cells(sensors_node, "#address-cells", 1);
341 	dt_add_property_cells(sensors_node, "#size-cells", 0);
342 
343 	for (i = 0; i < be32_to_cpu(ipmi_sensors->count); i++) {
344 		if(dt_find_by_name_addr(sensors_node, "sensor",
345 					ipmi_sensors->data[i].id)) {
346 			prlog(PR_WARNING, "SENSORS: Duplicate sensor ID : %x\n",
347 			      ipmi_sensors->data[i].id);
348 			continue;
349 		}
350 
351 		/* We support only < MAX_IPMI_SENSORS sensors */
352 		if (!(ipmi_sensors->data[i].type < MAX_IPMI_SENSORS))
353 			continue;
354 
355 		sensor_node = dt_new_addr(sensors_node, "sensor",
356 					  ipmi_sensors->data[i].id);
357 		assert(sensor_node);
358 		dt_add_property_string(sensor_node, "compatible", "ibm,ipmi-sensor");
359 		dt_add_property_cells(sensor_node, "reg", ipmi_sensors->data[i].id);
360 		dt_add_property_cells(sensor_node, "ipmi-sensor-type",
361 				      ipmi_sensors->data[i].type);
362 
363 		add_chip_id_to_sensors(sensor_node, ipmi_sensors->data[i].slca_index);
364 	}
365 }
366 
bmc_create_node(const struct HDIF_common_hdr * sp)367 static void bmc_create_node(const struct HDIF_common_hdr *sp)
368 {
369 	struct dt_node *bmc_node;
370 	u32 fw_bar, io_bar, mem_bar, internal_bar;
371 	const struct spss_iopath *iopath;
372 	const struct spss_sp_impl *sp_impl;
373 	struct dt_node *lpcm, *lpc, *n;
374 	u64 lpcm_base, lpcm_end;
375 	uint32_t chip_id;
376 	int size;
377 
378 	bmc_node = dt_new(dt_root, "bmc");
379 	assert(bmc_node);
380 
381 	dt_add_property_cells(bmc_node, "#address-cells", 1);
382 	dt_add_property_cells(bmc_node, "#size-cells", 0);
383 
384 	/* Add sensor info under /bmc */
385 	add_ipmi_sensors(bmc_node);
386 
387 	sp_impl = HDIF_get_idata(sp, SPSS_IDATA_SP_IMPL, &size);
388 	if (CHECK_SPPTR(sp_impl) && (size > 8)) {
389 		dt_add_property_strings(bmc_node, "compatible", sp_impl->sp_family);
390 		prlog(PR_INFO, "SP Family is %s\n", sp_impl->sp_family);
391 	}
392 
393 	iopath = HDIF_get_iarray_item(sp, SPSS_IDATA_SP_IOPATH, 0, NULL);
394 
395 	if (be16_to_cpu(iopath->iopath_type) != SPSS_IOPATH_TYPE_LPC) {
396 		prerror("BMC: Non-LPC IOPATH, this is probably broken\n");
397 		return;
398 	}
399 
400 	/*
401 	 * For now we only instantiate the LPC node for the LPC that is used
402 	 * for Host <-> BMC comms. The secondary LPCs can be skipped.
403 	 */
404 	if (be16_to_cpu(iopath->lpc.link_status) != LPC_STATUS_ACTIVE)
405 		return;
406 
407 #define GB (1024ul * 1024ul * 1024ul)
408 	/*
409 	 * convert the hdat chip ID the HW chip id so we get the right
410 	 * phys map offset
411 	 */
412 	chip_id = pcid_to_chip_id(be32_to_cpu(iopath->lpc.chip_id));
413 
414 	phys_map_get(chip_id, LPC_BUS, 0, &lpcm_base, NULL);
415 	lpcm = dt_new_addr(dt_root, "lpcm-opb", lpcm_base);
416 	assert(lpcm);
417 
418 	dt_add_property_cells(lpcm, "#address-cells", 1);
419 	dt_add_property_cells(lpcm, "#size-cells", 1);
420 	dt_add_property_strings(lpcm, "compatible",
421 		"ibm,power9-lpcm-opb", "simple-bus");
422 	dt_add_property_u64s(lpcm, "reg", lpcm_base, 0x100000000ul);
423 
424 	dt_add_property_cells(lpcm, "ibm,chip-id", chip_id);
425 
426 	/* Setup the ranges for the MMIO LPC */
427 	lpcm_end = lpcm_base + 2 * GB;
428 	dt_add_property_cells(lpcm, "ranges",
429 		0x00000000, hi32(lpcm_base), lo32(lpcm_base), 2 * GB,
430 		0x80000000, hi32(lpcm_end),  lo32(lpcm_end),  2 * GB);
431 
432 	/*
433 	 * Despite the name the "BAR" values provided through the HDAT are
434 	 * the base addresses themselves rather than the BARs
435 	 */
436 	fw_bar = be32_to_cpu(iopath->lpc.firmware_bar);
437 	mem_bar = be32_to_cpu(iopath->lpc.memory_bar);
438 	io_bar = be32_to_cpu(iopath->lpc.io_bar);
439 	internal_bar = be32_to_cpu(iopath->lpc.internal_bar);
440 
441 	prlog(PR_DEBUG, "LPC: IOPATH chip id = %x\n", chip_id);
442 	prlog(PR_DEBUG, "LPC: FW BAR       = %#x\n", fw_bar);
443 	prlog(PR_DEBUG, "LPC: MEM BAR      = %#x\n", mem_bar);
444 	prlog(PR_DEBUG, "LPC: IO BAR       = %#x\n", io_bar);
445 	prlog(PR_DEBUG, "LPC: Internal BAR = %#x\n", internal_bar);
446 
447 	/*
448 	 * The internal address space BAR actually points to the LPC master
449 	 * registers. So we "fix" it by masking off the low bits.
450 	 *
451 	 * XXX: we probably need separate base addresses for all these things
452 	 */
453 	internal_bar &= 0xf0000000;
454 
455 	/* Add the various internal bus devices */
456 	n = dt_new_addr(lpcm, "opb-master", internal_bar + 0x10000);
457 	dt_add_property_string(n, "compatible", "ibm,power9-lpcm-opb-master");
458 	dt_add_property_cells(n, "reg", internal_bar + 0x10000, 0x60);
459 
460 	n = dt_new_addr(lpcm, "opb-arbiter", internal_bar + 0x11000);
461 	dt_add_property_string(n, "compatible", "ibm,power9-lpcm-opb-arbiter");
462 	dt_add_property_cells(n, "reg", internal_bar + 0x11000, 0x8);
463 
464 	n = dt_new_addr(lpcm, "lpc-controller", internal_bar + 0x12000);
465 	dt_add_property_string(n, "compatible", "ibm,power9-lpc-controller");
466 	dt_add_property_cells(n, "reg", internal_bar + 0x12000, 0x100);
467 
468 	/*
469 	 * FIXME: lpc@0 might not be accurate, but i'm pretty sure
470 	 * lpc@f0000000 isn't right either.
471 	 */
472 	lpc = dt_new_addr(lpcm, "lpc", 0x0);
473 	dt_add_property_cells(lpc, "#address-cells", 2);
474 	dt_add_property_cells(lpc, "#size-cells", 1);
475 	dt_add_property_strings(lpc, "compatible",
476 				"ibm,power9-lpc", "ibm,power8-lpc");
477 
478 	dt_add_property_cells(lpc, "ranges",
479 		0, 0, mem_bar, 0x10000000, /* MEM space */
480 		1, 0, io_bar,  0x00010000, /* IO space  */
481 		/* we don't expose the internal space */
482 		3, 0, fw_bar,  0x10000000  /* FW space  */
483 	);
484 
485 	add_uart(iopath, lpc);
486 
487 	/* BT device info isn't currently populated */
488 	prlog(PR_DEBUG, "LPC: BT [%#"PRIx64", %#x] sms_int: %u, bmc_int: %u\n",
489 		iopath->lpc.bt_base, iopath->lpc.bt_size,
490 		iopath->lpc.bt_sms_int_num, iopath->lpc.bt_bmc_response_int_num
491 	);
492 }
493 
494 /*
495  * Search for and instanciate BMC nodes. This is mostly the same as fsp_parse()
496  * below, but it can be called earlier since BMCs don't depend on the psihb
497  * nodes being added.
498  */
bmc_parse(void)499 void bmc_parse(void)
500 {
501 	bool found = false;
502 	const void *sp;
503 	int i;
504 
505 	sp = get_hdif(&spira.ntuples.sp_subsys, SPSS_HDIF_SIG);
506 	if (!sp)
507 		return;
508 
509 	for_each_ntuple_idx(&spira.ntuples.sp_subsys, sp, i, SPSS_HDIF_SIG) {
510 		if (find_service_proc_type(sp, i) == SP_BMC) {
511 			bmc_create_node(sp);
512 			found = true;
513 		}
514 	}
515 
516 	if (found)
517 		early_uart_init();
518 }
519 
fsp_parse(void)520 void fsp_parse(void)
521 {
522 	struct dt_node *fsp_root = NULL, *fsp_node;
523 	const void *sp;
524 	int index;
525 
526 	/* Find SPSS tuple in SPIRA */
527 	sp = get_hdif(&spira.ntuples.sp_subsys, SPSS_HDIF_SIG);
528 	if (!sp) {
529 		prlog(PR_WARNING, "HDAT: No FSP/BMC found!\n");
530 		return;
531 	}
532 
533 	for_each_ntuple_idx(&spira.ntuples.sp_subsys, sp, index, SPSS_HDIF_SIG) {
534 		switch (find_service_proc_type(sp, index)) {
535 		case SP_FSP:
536 			if (!fsp_root) {
537 				fsp_root = dt_new(dt_root, "fsps");
538 				assert(fsp_root);
539 
540 				dt_add_property_cells(fsp_root,
541 					"#address-cells", 1);
542 				dt_add_property_cells(fsp_root,
543 					"#size-cells", 0);
544 			}
545 
546 			fsp_node = fsp_create_node(sp, index, fsp_root);
547 			if (fsp_node)
548 				fsp_create_links(sp, index, fsp_node);
549 
550 			break;
551 
552 		case SP_BMC:
553 			/* Handled above */
554 			break;
555 
556 		case SP_BAD:
557 			break;
558 
559 		default:
560 			prerror("SP #%d: This service processor is not supported\n", index);
561 			break;
562 		}
563 	}
564 }
565