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 <skiboot.h>
18 #include "spira.h"
19 #include <cpu.h>
20 #include <fsp.h>
21 #include <opal.h>
22 #include <ccan/str/str.h>
23 #include <ccan/array_size/array_size.h>
24 #include <device.h>
25 #include <vpd.h>
26 #include <inttypes.h>
27 #include <string.h>
28 
29 #include "hdata.h"
30 
io_get_lx_info(const void * kwvpd,unsigned int kwvpd_sz,int lx_idx,struct dt_node * hn)31 static bool io_get_lx_info(const void *kwvpd, unsigned int kwvpd_sz,
32 			   int lx_idx, struct dt_node *hn)
33 {
34 	const void *lxr;
35 	char recname[5];
36 	uint32_t lxrbuf[2] = { 0, 0 };
37 
38 	/* Find LXRn, where n is the index passed in*/
39 	strcpy(recname, "LXR0");
40 	recname[3] += lx_idx;
41 	lxr = vpd_find(kwvpd, kwvpd_sz, recname, "LX", NULL);
42 	if (!lxr) {
43 		/* Not found, try VINI */
44 		lxr = vpd_find(kwvpd, kwvpd_sz, "VINI",
45 			       "LX",  NULL);
46 		if (lxr)
47 			lx_idx = VPD_LOAD_LXRN_VINI;
48 	}
49 	if (!lxr) {
50 		prlog(PR_DEBUG, "CEC:     LXR%x not found !\n", lx_idx);
51 		return false;
52 	}
53 
54 	memcpy(lxrbuf, lxr, sizeof(uint32_t)*2);
55 
56 	prlog(PR_DEBUG, "CEC:     LXRn=%d LXR=%08x%08x\n", lx_idx, lxrbuf[0], lxrbuf[1]);
57 	prlog(PR_DEBUG, "CEC:     LX Info added to %llx\n", (long long)hn);
58 
59 	/* Add the LX info */
60 	if (!dt_has_node_property(hn, "ibm,vpd-lx-info", NULL)) {
61 		dt_add_property_cells(hn, "ibm,vpd-lx-info",
62 				      lx_idx,
63 				      lxrbuf[0],
64 				      lxrbuf[1]);
65 	}
66 
67 	return true;
68 }
69 
70 
io_get_loc_code(const void * sp_iohubs,struct dt_node * hn,const char * prop_name)71 static void io_get_loc_code(const void *sp_iohubs, struct dt_node *hn, const char *prop_name)
72 {
73 	const struct spira_fru_id *fru_id;
74 	unsigned int fru_id_sz;
75 	char loc_code[LOC_CODE_SIZE + 1];
76 	const char *slca_loc_code;
77 
78 	/* Find SLCA Index */
79 	fru_id = HDIF_get_idata(sp_iohubs, CECHUB_FRU_ID_DATA, &fru_id_sz);
80 	if (fru_id) {
81 		memset(loc_code, 0, sizeof(loc_code));
82 
83 		/* Find LOC Code from SLCA Index */
84 		slca_loc_code = slca_get_loc_code_index(be16_to_cpu(fru_id->slca_index));
85 		if (slca_loc_code) {
86 			strncpy(loc_code, slca_loc_code, LOC_CODE_SIZE);
87 			if (!dt_has_node_property(hn, prop_name, NULL)) {
88 				dt_add_property(hn, prop_name, loc_code,
89 						strlen(loc_code) + 1);
90 			}
91 			prlog(PR_DEBUG, "CEC:     %s: %s (SLCA rsrc 0x%x)\n",
92 			      prop_name, loc_code,
93 			      be16_to_cpu(fru_id->rsrc_id));
94 		} else {
95 			prlog(PR_DEBUG, "CEC:     SLCA Loc not found: "
96 			      "index %d\n", fru_id->slca_index);
97 		}
98 	} else {
99 		prlog(PR_DEBUG, "CEC:     Hub FRU ID not found...\n");
100 	}
101 }
102 
io_add_phb3(const struct cechub_io_hub * hub,const struct HDIF_common_hdr * sp_iohubs,unsigned int index,struct dt_node * xcom,unsigned int pe_xscom,unsigned int pci_xscom,unsigned int spci_xscom)103 static struct dt_node *io_add_phb3(const struct cechub_io_hub *hub,
104 				   const struct HDIF_common_hdr *sp_iohubs,
105 				   unsigned int index, struct dt_node *xcom,
106 				   unsigned int pe_xscom,
107 				   unsigned int pci_xscom,
108 				   unsigned int spci_xscom)
109 {
110 	struct dt_node *pbcq;
111 	uint32_t reg[6];
112 	unsigned int hdif_vers;
113 
114 	/* Get HDIF version */
115 	hdif_vers = be16_to_cpu(sp_iohubs->version);
116 
117 	/* Create PBCQ node under xscom */
118 	pbcq = dt_new_addr(xcom, "pbcq", pe_xscom);
119 	if (!pbcq)
120 		return NULL;
121 
122 	/* "reg" property contains in order the PE, PCI and SPCI XSCOM
123 	 * addresses
124 	 */
125 	reg[0] = pe_xscom;
126 	reg[1] = 0x20;
127 	reg[2] = pci_xscom;
128 	reg[3] = 0x05;
129 	reg[4] = spci_xscom;
130 	reg[5] = 0x15;
131 	dt_add_property(pbcq, "reg", reg, sizeof(reg));
132 
133 	/* A couple more things ... */
134 	dt_add_property_strings(pbcq, "compatible", "ibm,power8-pbcq");
135 	dt_add_property_cells(pbcq, "ibm,phb-index", index);
136 	dt_add_property_cells(pbcq, "ibm,hub-id", be16_to_cpu(hub->hub_num));
137 
138 	/* The loc code of the PHB itself is different from the base
139 	 * loc code of the slots (It's actually the DCM's loc code).
140 	 */
141 	io_get_loc_code(sp_iohubs, pbcq, "ibm,loc-code");
142 
143 	/* We indicate that this is an IBM setup, which means that
144 	 * the presence detect A/B bits are meaningful. So far we
145 	 * don't know whether they make any sense on customer setups
146 	 * so we only set that when booting with HDAT
147 	 */
148 	dt_add_property(pbcq, "ibm,use-ab-detect", NULL, 0);
149 
150 	/* HDAT spec has these in version 0x6A and later */
151 	if (hdif_vers >= 0x6a) {
152 		u64 eq0 = be64_to_cpu(hub->phb_lane_eq[index][0]);
153 		u64 eq1 = be64_to_cpu(hub->phb_lane_eq[index][1]);
154 		u64 eq2 = be64_to_cpu(hub->phb_lane_eq[index][2]);
155 		u64 eq3 = be64_to_cpu(hub->phb_lane_eq[index][3]);
156 
157 		dt_add_property_u64s(pbcq, "ibm,lane-eq", eq0, eq1, eq2, eq3);
158 	}
159 
160 	/* Currently we only create a PBCQ node, the actual PHB nodes
161 	 * will be added by sapphire later on.
162 	 */
163 	return pbcq;
164 }
165 
add_pec_stack(const struct cechub_io_hub * hub,struct dt_node * pbcq,int stack_index,int phb_index,u8 active_phbs)166 static struct dt_node *add_pec_stack(const struct cechub_io_hub *hub,
167 				     struct dt_node *pbcq, int stack_index,
168 				     int phb_index, u8 active_phbs)
169 {
170 	struct dt_node *stack;
171 	u64 eq[8];
172 	u8 *gen4;
173 	int i;
174 
175 	stack = dt_new_addr(pbcq, "stack", stack_index);
176 	assert(stack);
177 
178 	dt_add_property_cells(stack, "reg", stack_index);
179 	dt_add_property_cells(stack, "ibm,phb-index", phb_index);
180 	dt_add_property_string(stack, "compatible", "ibm,power9-phb-stack");
181 
182 	/* XXX: This should probably just return if the PHB is disabled
183 	 *      rather than adding the extra properties.
184 	 */
185 
186 	if (active_phbs & (0x80 >> phb_index))
187 		dt_add_property_string(stack, "status", "okay");
188 	else
189 		dt_add_property_string(stack, "status", "disabled");
190 
191 	for (i = 0; i < 4; i++) /* gen 3 eq settings */
192 		eq[i] = be64_to_cpu(hub->phb_lane_eq[phb_index][i]);
193 	for (i = 0; i < 4; i++) /* gen 4 eq settings */
194 		eq[i+4] = be64_to_cpu(hub->phb4_lane_eq[phb_index][i]);
195 
196 	/* Lane-eq settings are packed 2 bytes per lane for 16 lanes
197 	 * On P9 DD2, 1 byte  per lane is  used in the hardware
198 	 */
199 
200 	/* Repack 2 byte lane settings into 1 byte */
201 	gen4 = (u8 *)&eq[4];
202 	for (i = 0; i < 16; i++)
203 		gen4[i] = gen4[2*i];
204 
205 	dt_add_property_u64s(stack, "ibm,lane-eq", eq[0], eq[1],
206 			     eq[2], eq[3], eq[4], eq[5]);
207 	return stack;
208 }
209 
io_add_phb4(const struct cechub_io_hub * hub,const struct HDIF_common_hdr * sp_iohubs,struct dt_node * xcom,unsigned int pec_index,int stacks,int phb_base)210 static struct dt_node *io_add_phb4(const struct cechub_io_hub *hub,
211 				   const struct HDIF_common_hdr *sp_iohubs,
212 				   struct dt_node *xcom,
213 				   unsigned int pec_index,
214 				   int stacks,
215 				   int phb_base)
216 {
217 	struct dt_node *pbcq;
218 	uint32_t reg[4];
219 	uint8_t active_phb_mask = hub->fab_br0_pdt;
220 	uint32_t pe_xscom  = 0x4010c00 + (pec_index * 0x0000400);
221 	uint32_t pci_xscom = 0xd010800 + (pec_index * 0x1000000);
222 	int i;
223 
224 	/* Create PBCQ node under xscom */
225 	pbcq = dt_new_addr(xcom, "pbcq", pe_xscom);
226 	if (!pbcq)
227 		return NULL;
228 
229 	/* "reg" property contains (in order) the PE and PCI XSCOM addresses */
230 	reg[0] = pe_xscom;
231 	reg[1] = 0x100;
232 	reg[2] = pci_xscom;
233 	reg[3] = 0x200;
234 	dt_add_property(pbcq, "reg", reg, sizeof(reg));
235 
236 	/* The hubs themselves go under the stacks */
237 	dt_add_property_strings(pbcq, "compatible", "ibm,power9-pbcq");
238 	dt_add_property_cells(pbcq, "ibm,pec-index", pec_index);
239 	dt_add_property_cells(pbcq, "#address-cells", 1);
240 	dt_add_property_cells(pbcq, "#size-cells", 0);
241 
242 	for (i = 0; i < stacks; i++)
243 		add_pec_stack(hub, pbcq, i, phb_base + i, active_phb_mask);
244 
245 	dt_add_property_cells(pbcq, "ibm,hub-id", be16_to_cpu(hub->hub_num));
246 
247 	/* The loc code of the PHB itself is different from the base
248 	 * loc code of the slots (It's actually the DCM's loc code).
249 	 */
250 	io_get_loc_code(sp_iohubs, pbcq, "ibm,loc-code");
251 
252 	prlog(PR_INFO, "CEC: Added PHB4 PBCQ %d with %d stacks\n",
253 		pec_index, stacks);
254 
255 	/* the actual PHB nodes created later on by skiboot */
256 	return pbcq;
257 }
258 
io_add_p8(const struct cechub_io_hub * hub,const struct HDIF_common_hdr * sp_iohubs)259 static struct dt_node *io_add_p8(const struct cechub_io_hub *hub,
260 				 const struct HDIF_common_hdr *sp_iohubs)
261 {
262 	struct dt_node *xscom;
263 	unsigned int i, chip_id;
264 
265 	chip_id = pcid_to_chip_id(be32_to_cpu(hub->proc_chip_id));
266 
267 	prlog(PR_INFO, "CEC:     HW CHIP=0x%x, HW TOPO=0x%04x\n", chip_id,
268 	      be16_to_cpu(hub->hw_topology));
269 
270 	xscom = find_xscom_for_chip(chip_id);
271 	if (!xscom) {
272 		prerror("P8: Can't find XSCOM for chip %d\n", chip_id);
273 		return NULL;
274 	}
275 
276 	/* Create PHBs, max 3 */
277 	for (i = 0; i < 3; i++) {
278 		if (hub->fab_br0_pdt & (0x80 >> i))
279 			/* XSCOM addresses are the same on Murano and Venice */
280 			io_add_phb3(hub, sp_iohubs, i, xscom,
281 				    0x02012000 + (i * 0x400),
282 				    0x09012000 + (i * 0x400),
283 				    0x09013c00 + (i * 0x40));
284 	}
285 
286 	/* HACK: We return the XSCOM device for the VPD info */
287 	return xscom;
288 }
289 
io_add_p9(const struct cechub_io_hub * hub,const struct HDIF_common_hdr * sp_iohubs)290 static struct dt_node *io_add_p9(const struct cechub_io_hub *hub,
291 				 const struct HDIF_common_hdr *sp_iohubs)
292 {
293 	struct dt_node *xscom;
294 	unsigned int chip_id;
295 
296 	chip_id = pcid_to_chip_id(be32_to_cpu(hub->proc_chip_id));
297 
298 	prlog(PR_INFO, "CEC:     HW CHIP=0x%x, HW TOPO=0x%04x\n", chip_id,
299 	      be16_to_cpu(hub->hw_topology));
300 
301 	xscom = find_xscom_for_chip(chip_id);
302 	if (!xscom) {
303 		prerror("P9: Can't find XSCOM for chip %d\n", chip_id);
304 		return NULL;
305 	}
306 
307 	prlog(PR_DEBUG, "IOHUB: PHB4 active bridge mask %x\n",
308 		(u32) hub->fab_br0_pdt);
309 
310 	/* Create PBCQs */
311 	io_add_phb4(hub, sp_iohubs, xscom, 0, 1, 0);
312 	io_add_phb4(hub, sp_iohubs, xscom, 1, 2, 1);
313 	io_add_phb4(hub, sp_iohubs, xscom, 2, 3, 3);
314 
315 	return xscom;
316 }
317 
318 
io_add_p8_cec_vpd(const struct HDIF_common_hdr * sp_iohubs)319 static void io_add_p8_cec_vpd(const struct HDIF_common_hdr *sp_iohubs)
320 {
321 	const struct HDIF_child_ptr *iokids;
322 	const void *iokid;
323 	const void *kwvpd;
324 	unsigned int kwvpd_sz;
325 
326 	/* P8 LXR0 kept in IO KID Keyword VPD */
327 	iokids = HDIF_child_arr(sp_iohubs, CECHUB_CHILD_IO_KIDS);
328 	if (!CHECK_SPPTR(iokids)) {
329 		prlog(PR_WARNING, "CEC:     No IOKID child array !\n");
330 		return;
331 	}
332 	if (!iokids->count) {
333 		prlog(PR_WARNING, "CEC:     IOKID count is 0 !\n");
334 		return;
335 	}
336 	if (be32_to_cpu(iokids->count) > 1) {
337 		prlog(PR_WARNING, "CEC:     WARNING ! More than 1 IO KID !!! (%d)\n",
338 		      iokids->count);
339 		/* Ignoring the additional ones */
340 	}
341 
342 	iokid = HDIF_child(sp_iohubs, iokids, 0, "IO KID");
343 	if (!iokid) {
344 		prlog(PR_WARNING, "CEC:     No IO KID structure in child array !\n");
345 		return;
346 	}
347 
348 	/* Grab base location code for slots */
349 	io_get_loc_code(iokid, dt_root, "ibm,io-base-loc-code");
350 
351 	kwvpd = HDIF_get_idata(iokid, CECHUB_ASCII_KEYWORD_VPD, &kwvpd_sz);
352 	if (!kwvpd) {
353 		prlog(PR_WARNING, "CEC:     No VPD entry in IO KID !\n");
354 		return;
355 	}
356 
357 	/* Grab LX load info */
358 	io_get_lx_info(kwvpd, kwvpd_sz, 0, dt_root);
359 }
360 
361 /*
362  * Assumptions:
363  *
364  * a) the IOSLOT index is the hub ID -CHECK
365  *
366  */
367 
368 static struct dt_node *dt_slots;
369 
add_i2c_link(struct dt_node * node,const char * link_name,u32 i2c_link)370 static void add_i2c_link(struct dt_node *node, const char *link_name,
371 			u32 i2c_link)
372 {
373 	/* FIXME: Do something not shit */
374 	dt_add_property_cells(node, link_name, i2c_link);
375 }
376 
377 /*
378  * the root of the slots node has #address-cells = 2, <hub-index, phb-index>
379  * can we ditch hub-index?
380  */
381 
382 
find_slot_details(const struct HDIF_common_hdr * ioslot,int entry)383 static const struct slot_map_details *find_slot_details(
384 		const struct HDIF_common_hdr *ioslot, int entry)
385 {
386 	const struct slot_map_details *details = NULL;
387 	const struct HDIF_array_hdr *arr;
388 	unsigned int i;
389 
390 	arr = HDIF_get_iarray(ioslot, IOSLOT_IDATA_DETAILS, NULL);
391 	HDIF_iarray_for_each(arr, i, details)
392 		if (be16_to_cpu(details->entry) == entry)
393 			break;
394 
395 	return details;
396 }
397 
parse_slot_details(struct dt_node * slot,const struct slot_map_details * details)398 static void parse_slot_details(struct dt_node *slot,
399 		const struct slot_map_details *details)
400 {
401 	u32 slot_caps;
402 
403 	/*
404 	 * generic slot options
405 	 */
406 
407 	dt_add_property_cells(slot, "max-power",
408 		be16_to_cpu(details->max_power));
409 
410 	if (details->perst_ctl_type == SLOT_PERST_PHB_OR_SW)
411 		dt_add_property(slot, "pci-perst", NULL, 0);
412 	else if (details->perst_ctl_type == SLOT_PERST_SW_GPIO)
413 		dt_add_property_cells(slot, "gpio-perst", details->perst_gpio);
414 
415 	if (details->presence_det_type == SLOT_PRESENCE_PCI)
416 		dt_add_property(slot, "pci-presence-detect", NULL, 0);
417 
418 	/*
419 	 * specific slot capabilities
420 	 */
421 	slot_caps = be32_to_cpu(details->slot_caps);
422 
423 	if (slot_caps & SLOT_CAP_LSI)
424 		dt_add_property(slot, "lsi", NULL, 0);
425 
426 	if (slot_caps & SLOT_CAP_CAPI) {
427 		/* XXX: should we be more specific here?
428 		 *
429 		 * Also we should double check that this slot
430 		 * is a root connected slot.
431 		 */
432 		dt_add_property(slot, "capi", NULL, 0);
433 	}
434 
435 	if (slot_caps & SLOT_CAP_CCARD) {
436 		dt_add_property(slot, "cable-card", NULL, 0);
437 
438 		if (details->presence_det_type == SLOT_PRESENCE_I2C)
439 			add_i2c_link(slot, "i2c-presence-detect",
440 				be32_to_cpu(details->i2c_cable_card));
441 	}
442 
443 	if (slot_caps & SLOT_CAP_HOTPLUG) {
444 		dt_add_property(slot, "hotplug", NULL, 0);
445 
446 		/*
447 		 * Power control should only exist when the slot is hotplug
448 		 * capable
449 		 */
450 		if (details->power_ctrl_type == SLOT_PWR_I2C)
451 			add_i2c_link(slot, "i2c-power-ctrl",
452 				be32_to_cpu(details->i2c_power_ctl));
453 	}
454 
455 	/*
456 	 * NB: Additional NVLink specific info is added to this node
457 	 *     when the SMP Link structures are parsed later on.
458 	 */
459 	if (slot_caps & SLOT_CAP_NVLINK)
460 		dt_add_property(slot, "nvlink", NULL, 0);
461 }
462 
find_slot_entry_node(struct dt_node * root,u32 entry_id)463 struct dt_node *find_slot_entry_node(struct dt_node *root, u32 entry_id)
464 {
465 	struct dt_node *node;
466 
467 	for (node = dt_first(root); node; node = dt_next(root, node)) {
468 		if (!dt_has_node_property(node, DT_PRIVATE "entry_id", NULL))
469 			continue;
470 
471 		if (dt_prop_get_u32(node, DT_PRIVATE "entry_id") == entry_id)
472 			return node;
473 	}
474 
475 	return NULL;
476 }
477 
478 /*
479  * The internal HDAT representation of the various types of slot is kinda
480  * dumb, translate it into something more sensible
481  */
482 enum slot_types {
483 	st_root,
484 	st_slot,
485 	st_rc_slot,
486 	st_sw_upstream,
487 	st_sw_downstream,
488 	st_builtin
489 };
490 
st_name(enum slot_types type)491 static const char *st_name(enum slot_types type)
492 {
493 	switch(type) {
494 	case st_root:		return "root-complex";
495 	case st_slot:		return "pluggable";
496 	case st_rc_slot:	return "pluggable"; /* differentiate? */
497 	case st_sw_upstream:	return "switch-up";
498 	case st_sw_downstream:	return "switch-down";
499 	case st_builtin:	return "builtin";
500 	}
501 
502 	return "(none)";
503 }
504 
xlate_type(uint8_t type,u32 features)505 static enum slot_types xlate_type(uint8_t type, u32 features)
506 {
507 	bool is_slot = features & SLOT_FEAT_SLOT;
508 
509 	switch (type) {
510 	case SLOT_TYPE_ROOT_COMPLEX:
511 		return is_slot ? st_rc_slot : st_root;
512 	case SLOT_TYPE_BUILTIN:
513 		return st_builtin;
514 	case SLOT_TYPE_SWITCH_UP:
515 		return st_sw_upstream;
516 	case SLOT_TYPE_SWITCH_DOWN:
517 		return is_slot ? st_slot : st_sw_downstream;
518 	}
519 
520 	return -1; /* shouldn't happen */
521 }
522 
is_port(struct dt_node * n)523 static bool is_port(struct dt_node *n)
524 {
525 	//return dt_node_is_compatible(n, "compatible", "ibm,pcie-port");
526 	return dt_node_is_compatible(n, "ibm,pcie-port");
527 }
528 
529 /* this only works inside parse_one_ioslot() */
530 #define SM_LOG(level, fmt, ...) \
531 	prlog(level, "SLOTMAP: %x:%d:%d " \
532 		fmt, /* user input */ \
533 		chip_id, entry->phb_index, eid, \
534 		##__VA_ARGS__ /* user args */)
535 
536 #define SM_ERR(fmt, ...) SM_LOG(PR_ERR, fmt, ##__VA_ARGS__)
537 #define SM_DBG(fmt, ...) SM_LOG(PR_DEBUG, fmt, ##__VA_ARGS__)
538 
parse_one_slot(const struct slot_map_entry * entry,const struct slot_map_details * details,int chip_id)539 static void parse_one_slot(const struct slot_map_entry *entry,
540 		const struct slot_map_details *details, int chip_id)
541 {
542 	struct dt_node *node, *parent = NULL;
543 	u16 eid, pid, vid, did;
544 	u32 flags;
545 	int type;
546 
547 	flags = be32_to_cpu(entry->features);
548 	type = xlate_type(entry->type, flags);
549 
550 	eid = be16_to_cpu(entry->entry_id);
551 	pid = be16_to_cpu(entry->parent_id);
552 
553 	SM_DBG("%s - eid = %d, pid = %d, name = %8s\n",
554 		st_name(type), eid, pid,
555 		strnlen(entry->name, 8) ? entry->name : "");
556 
557 	/* empty slot, ignore it */
558 	if (eid == 0x0 && pid == 0x0)
559 		return;
560 
561 	if (type != st_root && type != st_rc_slot) {
562 		parent = find_slot_entry_node(dt_slots, pid);
563 		if (!parent) {
564 			SM_ERR("Unable to find node for parent slot (id = %d)\n",
565 				pid);
566 			return;
567 		}
568 	}
569 
570 	switch (type) {
571 	case st_root:
572 	case st_rc_slot:
573 		node = dt_new_2addr(dt_slots, "root-complex",
574 						chip_id, entry->phb_index);
575 		if (!node) {
576 			SM_ERR("Couldn't add DT node\n");
577 			return;
578 		}
579 		dt_add_property_cells(node, "reg", chip_id, entry->phb_index);
580 		dt_add_property_cells(node, "#address-cells", 2);
581 		dt_add_property_cells(node, "#size-cells", 0);
582 		dt_add_property_strings(node, "compatible",
583 				"ibm,pcie-port", "ibm,pcie-root-port");
584 		dt_add_property_cells(node, "ibm,chip-id", chip_id);
585 		parent = node;
586 
587 		/*
588 		 * The representation of slots attached directly to the
589 		 * root complex is a bit wierd. If this is just a root
590 		 * complex then stop here, otherwise fall through to create
591 		 * the slot node.
592 		 */
593 		if (type == st_root)
594 			break;
595 
596 		/* fallthrough*/
597 	case st_sw_upstream:
598 	case st_builtin:
599 	case st_slot:
600 		if (!is_port(parent)) {
601 			SM_ERR("%s connected to %s (%d), should be %s or %s!\n",
602 				st_name(type), parent->name, pid,
603 				st_name(st_root), st_name(st_sw_downstream));
604 			return;
605 		}
606 
607 		vid = (be32_to_cpu(entry->vendor_id) & 0xffff);
608 		did = (be32_to_cpu(entry->device_id) & 0xffff);
609 
610 		prlog(PR_DEBUG, "Found %s slot with %x:%x\n",
611 			st_name(type), vid, did);
612 
613 		/* The VID:DID is only meaningful for builtins and switches */
614 		if (type == st_sw_upstream && vid && did) {
615 			node = dt_new_2addr(parent, st_name(type), vid, did);
616 			dt_add_property_cells(node, "reg", vid, did);
617 		} else {
618 			/*
619 			 * If we get no vdid then create a "wildcard" slot
620 			 * that matches any device
621 			 */
622 			node = dt_new(parent, st_name(type));
623 		}
624 
625 		if (type == st_sw_upstream) {
626 			dt_add_property_cells(node, "#address-cells", 1);
627 			dt_add_property_cells(node, "#size-cells", 0);
628 			dt_add_property_cells(node, "upstream-port",
629 					entry->up_port);
630 		}
631 		break;
632 
633 	case st_sw_downstream: /* slot connected to switch output */
634 		node = dt_new_addr(parent, "down-port", entry->down_port);
635 		dt_add_property_strings(node, "compatible",
636 				"ibm,pcie-port");
637 		dt_add_property_cells(node, "reg", entry->down_port);
638 
639 		break;
640 
641 	default:
642 		SM_ERR("Unknown slot map type %x\n", entry->type);
643 		return;
644 	}
645 
646 	/*
647 	 * Now add any generic slot map properties.
648 	 */
649 
650 	/* private since we don't want hdat stuff leaking */
651 	dt_add_property_cells(node, DT_PRIVATE "entry_id", eid);
652 
653 	if (entry->mrw_slot_id)
654 		dt_add_property_cells(node, "mrw-slot-id",
655 				be16_to_cpu(entry->mrw_slot_id));
656 
657 	if (entry->lane_mask)
658 		dt_add_property_cells(node, "lane-mask",
659 				be16_to_cpu(entry->lane_mask));
660 
661 	/* what is the difference between this and the lane reverse? */
662 	if (entry->lane_reverse)
663 		dt_add_property_cells(node, "lanes-reversed",
664 				be16_to_cpu(entry->lane_reverse));
665 
666 	if (strnlen(entry->name, sizeof(entry->name))) {
667 		/*
668 		 * HACK: On some platforms (witherspoon) the slot label is
669 		 * applied to the device rather than the pcie downstream port
670 		 * that has the slot under it. Hack around this by moving the
671 		 * slot label up if the parent port doesn't have one.
672 		 */
673 		if (dt_node_is_compatible(node->parent, "ibm,pcie-port") &&
674 		    !dt_find_property(node->parent, "ibm,slot-label")) {
675 			dt_add_property_nstr(node->parent, "ibm,slot-label",
676 					entry->name, sizeof(entry->name));
677 		}
678 
679 		dt_add_property_nstr(node, "ibm,slot-label",
680 				entry->name, sizeof(entry->name));
681 	}
682 
683 	if (entry->type == st_slot || entry->type == st_rc_slot)
684 		dt_add_property(node, "ibm,pluggable", NULL, 0);
685 
686 	if (details)
687 		parse_slot_details(node, details);
688 }
689 
690 /*
691  * Under the IOHUB structure we have and idata array describing
692  * the PHBs under each chip. The IOHUB structure also has a child
693  * array called IOSLOT which describes slot map. The i`th element
694  * of the IOSLOT array corresponds to the slot map of the i`th
695  * element of the iohubs idata array.
696  *
697  * Probably.
698  *
699  * Furthermore, arrayarrayarrayarrayarray.
700  */
701 
get_slot_node(void)702 static struct dt_node *get_slot_node(void)
703 {
704 	struct dt_node *slots = dt_find_by_name(dt_root, "ibm,pcie-slots");
705 
706 	if (!slots) {
707 		slots = dt_new(dt_root, "ibm,pcie-slots");
708 		dt_add_property_cells(slots, "#address-cells", 2);
709 		dt_add_property_cells(slots, "#size-cells", 0);
710 	}
711 
712 	return slots;
713 }
714 
io_parse_slots(const struct HDIF_common_hdr * sp_iohubs,int hub_id)715 static void io_parse_slots(const struct HDIF_common_hdr *sp_iohubs, int hub_id)
716 {
717 	const struct HDIF_child_ptr *ioslot_arr;
718 	const struct HDIF_array_hdr *entry_arr;
719 	const struct HDIF_common_hdr *ioslot;
720 	const struct slot_map_entry *entry;
721 	unsigned int i, count;
722 
723 	if (sp_iohubs->child_count <= CECHUB_CHILD_IOSLOTS)
724 		return;
725 
726 	ioslot_arr = HDIF_child_arr(sp_iohubs, CECHUB_CHILD_IOSLOTS);
727 	if (!ioslot_arr)
728 		return;
729 
730 	count = be32_to_cpu(ioslot_arr->count); /* should only be 1 */
731 	if (!count)
732 		return;
733 
734 	dt_slots = get_slot_node();
735 
736 	prlog(PR_DEBUG, "CEC: Found slot map for IOHUB %d\n", hub_id);
737 	if (count > 1)
738 		prerror("CEC: Multiple IOSLOTs found for IO HUB %d\n", hub_id);
739 
740 	ioslot = HDIF_child(sp_iohubs, ioslot_arr, 0, "IOSLOT");
741 	if (!ioslot)
742 		return;
743 
744 	entry_arr = HDIF_get_iarray(ioslot, IOSLOT_IDATA_SLOTMAP, NULL);
745 	HDIF_iarray_for_each(entry_arr, i, entry) {
746 		const struct slot_map_details *details;
747 
748 		details = find_slot_details(ioslot,
749 				be16_to_cpu(entry->entry_id));
750 		parse_one_slot(entry, details, hub_id);
751 	}
752 }
753 
io_parse_fru(const void * sp_iohubs)754 static void io_parse_fru(const void *sp_iohubs)
755 {
756 	unsigned int i;
757 	int count;
758 
759 	count = HDIF_get_iarray_size(sp_iohubs, CECHUB_FRU_IO_HUBS);
760 	if (count < 1) {
761 		prerror("CEC: IO FRU with no chips !\n");
762 		return;
763 	}
764 
765 	prlog(PR_INFO, "CEC:   %d chips in FRU\n", count);
766 
767 	/* Iterate IO hub array */
768 	for (i = 0; i < count; i++) {
769 		const struct cechub_io_hub *hub;
770 		unsigned int size, hub_id;
771 		uint32_t chip_id;
772 
773 		hub = HDIF_get_iarray_item(sp_iohubs, CECHUB_FRU_IO_HUBS,
774 					   i, &size);
775 		if (!hub || size < CECHUB_IOHUB_MIN_SIZE) {
776 			prerror("CEC:     IO-HUB Chip %d bad idata\n", i);
777 			continue;
778 		}
779 
780 		switch (hub->flags & CECHUB_HUB_FLAG_STATE_MASK) {
781 		case CECHUB_HUB_FLAG_STATE_OK:
782 			prlog(PR_DEBUG, "CEC:   IO Hub Chip #%d OK\n", i);
783 			break;
784 		case CECHUB_HUB_FLAG_STATE_FAILURES:
785 			prlog(PR_WARNING, "CEC:   IO Hub Chip #%d OK"
786 			      " with failures\n", i);
787 			break;
788 		case CECHUB_HUB_FLAG_STATE_NOT_INST:
789 			prlog(PR_DEBUG, "CEC:   IO Hub Chip #%d"
790 			      " Not installed\n", i);
791 			continue;
792 		case CECHUB_HUB_FLAG_STATE_UNUSABLE:
793 			prlog(PR_DEBUG, "CEC:   IO Hub Chip #%d Unusable\n", i);
794 			continue;
795 		}
796 
797 		hub_id = be16_to_cpu(hub->iohub_id);
798 
799 		/* GX BAR assignment */
800 		prlog(PR_DEBUG, "CEC:   PChip: %d HUB ID: %04x [EC=0x%x]"
801 		      " Hub#=%d)\n",
802 		      be32_to_cpu(hub->proc_chip_id), hub_id,
803 		      be32_to_cpu(hub->ec_level), be16_to_cpu(hub->hub_num));
804 
805 		switch(hub_id) {
806 		case CECHUB_HUB_MURANO:
807 		case CECHUB_HUB_MURANO_SEGU:
808 			prlog(PR_INFO, "CEC:     Murano !\n");
809 			io_add_p8(hub, sp_iohubs);
810 			break;
811 		case CECHUB_HUB_VENICE_WYATT:
812 			prlog(PR_INFO, "CEC:     Venice !\n");
813 			io_add_p8(hub, sp_iohubs);
814 			break;
815 		case CECHUB_HUB_NIMBUS_SFORAZ:
816 		case CECHUB_HUB_NIMBUS_MONZA:
817 		case CECHUB_HUB_NIMBUS_LAGRANGE:
818 			prlog(PR_INFO, "CEC:     Nimbus !\n");
819 			io_add_p9(hub, sp_iohubs);
820 			break;
821 		case CECHUB_HUB_CUMULUS_DUOMO:
822 			prlog(PR_INFO, "CEC:     Cumulus !\n");
823 			io_add_p9(hub, sp_iohubs);
824 			break;
825 		default:
826 			prlog(PR_ERR, "CEC:     Hub ID 0x%04x unsupported !\n",
827 			      hub_id);
828 		}
829 
830 		chip_id = pcid_to_chip_id(be32_to_cpu(hub->proc_chip_id));
831 
832 		/* parse the slot map if we have one */
833 		io_parse_slots(sp_iohubs, chip_id);
834 	}
835 
836 	if (proc_gen == proc_gen_p8 || proc_gen == proc_gen_p9)
837 		io_add_p8_cec_vpd(sp_iohubs);
838 }
839 
io_parse(void)840 void io_parse(void)
841 {
842 	const struct HDIF_common_hdr *sp_iohubs;
843 	unsigned int i, size;
844 
845 	/* Look for IO Hubs */
846 	if (!get_hdif(&spira.ntuples.cec_iohub_fru, "IO HUB")) {
847 		prerror("CEC: Cannot locate IO Hub FRU data !\n");
848 		return;
849 	}
850 
851 	/*
852 	 * Note about LXRn numbering ...
853 	 *
854 	 * I can't completely make sense of what that is supposed to be, so
855 	 * for now, what we do is look for the first one we can find and
856 	 * increment it for each chip. Works for the machines I have here
857 	 */
858 
859 	for_each_ntuple_idx(&spira.ntuples.cec_iohub_fru, sp_iohubs, i,
860 			    CECHUB_FRU_HDIF_SIG) {
861 		const struct cechub_hub_fru_id *fru_id_data;
862 		unsigned int type;
863 		static const char *typestr[] = {
864 			"Reservation",
865 			"Card",
866 			"CPU Card",
867 			"Backplane",
868 			"Backplane Extension"
869 		};
870 		fru_id_data = HDIF_get_idata(sp_iohubs, CECHUB_FRU_ID_DATA_AREA,
871 					     &size);
872 		if (!fru_id_data || size < sizeof(struct cechub_hub_fru_id)) {
873 			prerror("CEC: IO-HUB FRU %d, bad ID data\n", i);
874 			continue;
875 		}
876 		type = be32_to_cpu(fru_id_data->card_type);
877 
878 		prlog(PR_INFO, "CEC: HUB FRU %d is %s\n",
879 		      i, type > 4 ? "Unknown" : typestr[type]);
880 
881 		/*
882 		 * We currently only handle the backplane (Juno) and
883 		 * processor FRU (P8 machines)
884 		 */
885 		if (type != CECHUB_FRU_TYPE_CEC_BKPLANE &&
886 		    type != CECHUB_FRU_TYPE_CPU_CARD) {
887 			prerror("CEC:   Unsupported type\n");
888 			continue;
889 		}
890 
891 		/* We don't support Hubs connected to pass-through ports */
892 		if (fru_id_data->flags & (CECHUB_FRU_FLAG_HEADLESS |
893 					  CECHUB_FRU_FLAG_PASSTHROUGH)) {
894 			prerror("CEC:   Headless or Passthrough unsupported\n");
895 			continue;
896 		}
897 
898 		/* Ok, we have a reasonable candidate */
899 		io_parse_fru(sp_iohubs);
900 	}
901 }
902 
903