/* Copyright 2013-2014 IBM Corp.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * 	http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <skiboot.h>
#include "spira.h"
#include <cpu.h>
#include <fsp.h>
#include <opal.h>
#include <ccan/str/str.h>
#include <ccan/array_size/array_size.h>
#include <device.h>
#include <p7ioc.h>
#include <vpd.h>
#include <inttypes.h>
#include <string.h>

#include "hdata.h"

static void io_add_common(struct dt_node *hn, const struct cechub_io_hub *hub)
{
	dt_add_property_cells(hn, "#address-cells", 2);
	dt_add_property_cells(hn, "#size-cells", 2);
	dt_add_property_cells(hn, "ibm,buid-ext", be32_to_cpu(hub->buid_ext));
	dt_add_property_cells(hn, "ibm,chip-id",
			      pcid_to_chip_id(be32_to_cpu(hub->proc_chip_id)));
	dt_add_property_cells(hn, "ibm,gx-index", be32_to_cpu(hub->gx_index));
	dt_add_property_cells(hn, "revision", be32_to_cpu(hub->ec_level));

	/* Instead of exposing the GX BARs as separate ranges as we *should*
	 * do in an ideal world, we just create a pass-through ranges and
	 * we use separate properties for the BARs.
	 *
	 * This is hackish but will do for now and avoids us having to
	 * do too complex ranges property parsing
	 */
	dt_add_property(hn, "ranges", NULL, 0);
	dt_add_property_u64(hn, "ibm,gx-bar-1", be64_to_cpu(hub->gx_ctrl_bar1));
	dt_add_property_u64(hn, "ibm,gx-bar-2", be64_to_cpu(hub->gx_ctrl_bar2));

	/* Add presence detect if valid */
	if (hub->flags & CECHUB_HUB_FLAG_FAB_BR0_PDT)
		dt_add_property_cells(hn, "ibm,br0-presence-detect",
				      hub->fab_br0_pdt);
	if (hub->flags & CECHUB_HUB_FLAG_FAB_BR1_PDT)
		dt_add_property_cells(hn, "ibm,br1-presence-detect",
				      hub->fab_br1_pdt);
}

static bool io_get_lx_info(const void *kwvpd, unsigned int kwvpd_sz,
			   int lx_idx, struct dt_node *hn)
{
	const void *lxr;
	char recname[5];
	uint32_t lxrbuf[2] = { 0, 0 };

	/* Find LXRn, where n is the index passed in*/
	strcpy(recname, "LXR0");
	recname[3] += lx_idx;
	lxr = vpd_find(kwvpd, kwvpd_sz, recname, "LX", NULL);
	if (!lxr) {
		/* Not found, try VINI */
		lxr = vpd_find(kwvpd, kwvpd_sz, "VINI",
			       "LX",  NULL);
		if (lxr)
			lx_idx = VPD_LOAD_LXRN_VINI;
	}
	if (!lxr) {
		prlog(PR_DEBUG, "CEC:     LXR%x not found !\n", lx_idx);
		return false;
	}

	if (lxr)
		memcpy(lxrbuf, lxr, sizeof(uint32_t)*2);

	prlog(PR_DEBUG, "CEC:     LXRn=%d LXR=%08x%08x\n", lx_idx, lxrbuf[0], lxrbuf[1]);
	prlog(PR_DEBUG, "CEC:     LX Info added to %llx\n", (long long)hn);

	/* Add the LX info */
	if (!dt_has_node_property(hn, "ibm,vpd-lx-info", NULL)) {
		dt_add_property_cells(hn, "ibm,vpd-lx-info",
				      lx_idx,
				      lxrbuf[0],
				      lxrbuf[1]);
	}

	return true;
}


static void io_get_loc_code(const void *sp_iohubs, struct dt_node *hn, const char *prop_name)
{
	const struct spira_fru_id *fru_id;
	unsigned int fru_id_sz;
	char loc_code[LOC_CODE_SIZE + 1];
	const char *slca_loc_code;

	/* Find SLCA Index */
	fru_id = HDIF_get_idata(sp_iohubs, CECHUB_FRU_ID_DATA, &fru_id_sz);
	if (fru_id) {
		memset(loc_code, 0, sizeof(loc_code));

		/* Find LOC Code from SLCA Index */
		slca_loc_code = slca_get_loc_code_index(be16_to_cpu(fru_id->slca_index));
		if (slca_loc_code) {
			strncpy(loc_code, slca_loc_code, LOC_CODE_SIZE);
			if (!dt_has_node_property(hn, prop_name, NULL)) {
				dt_add_property(hn, prop_name, loc_code,
						strlen(loc_code) + 1);
			}
			prlog(PR_DEBUG, "CEC:     %s: %s (SLCA rsrc 0x%x)\n",
			      prop_name, loc_code,
			      be16_to_cpu(fru_id->rsrc_id));
		} else {
			prlog(PR_DEBUG, "CEC:     SLCA Loc not found: "
			      "index %d\n", fru_id->slca_index);
		}
	} else {
		prlog(PR_DEBUG, "CEC:     Hub FRU ID not found...\n");
	}
}

static struct dt_node *io_add_p7ioc(const struct cechub_io_hub *hub,
				    const void *sp_iohubs)
{
	struct dt_node *hn;
	uint64_t reg[2];

	const void *kwvpd;
	unsigned int kwvpd_sz;

	prlog(PR_DEBUG, "    GX#%d BUID_Ext = 0x%x\n",
	      be32_to_cpu(hub->gx_index),
	      be32_to_cpu(hub->buid_ext));
	prlog(PR_DEBUG, "    GX BAR 0 = 0x%016"PRIx64"\n",
	      be64_to_cpu(hub->gx_ctrl_bar0));
	prlog(PR_DEBUG, "    GX BAR 1 = 0x%016"PRIx64"\n",
	      be64_to_cpu(hub->gx_ctrl_bar1));
	prlog(PR_DEBUG, "    GX BAR 2 = 0x%016"PRIx64"\n",
	      be64_to_cpu(hub->gx_ctrl_bar2));
	prlog(PR_DEBUG, "    GX BAR 3 = 0x%016"PRIx64"\n",
	      be64_to_cpu(hub->gx_ctrl_bar3));
	prlog(PR_DEBUG, "    GX BAR 4 = 0x%016"PRIx64"\n",
	      be64_to_cpu(hub->gx_ctrl_bar4));

	/* We only know about memory map 1 */
	if (be32_to_cpu(hub->mem_map_vers) != 1) {
		prerror("P7IOC: Unknown memory map %d\n", be32_to_cpu(hub->mem_map_vers));
		/* We try to continue anyway ... */
	}

	reg[0] = cleanup_addr(be64_to_cpu(hub->gx_ctrl_bar1));
	reg[1] = 0x2000000;

	hn = dt_new_addr(dt_root, "io-hub", reg[0]);
	if (!hn)
		return NULL;

	dt_add_property(hn, "reg", reg, sizeof(reg));
	dt_add_property_strings(hn, "compatible", "ibm,p7ioc", "ibm,ioda-hub");

	kwvpd = HDIF_get_idata(sp_iohubs, CECHUB_ASCII_KEYWORD_VPD, &kwvpd_sz);
	if (kwvpd && kwvpd != sp_iohubs) {
		/*
		 * XX We don't know how to properly find the LXRn
		 * record so for now we'll just try LXR0 and if not
		 * found, we try LXR1
		 */
		if (!io_get_lx_info(kwvpd, kwvpd_sz, 0, hn))
			io_get_lx_info(kwvpd, kwvpd_sz, 1, hn);
	} else {
		prlog(PR_DEBUG, "CEC:     P7IOC Keywords not found.\n");
	}

	io_get_loc_code(sp_iohubs, hn, "ibm,io-base-loc-code");

	return hn;
}

static struct dt_node *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)
{
	struct dt_node *pbcq;
	uint32_t reg[6];
	unsigned int hdif_vers;

	/* Get HDIF version */
	hdif_vers = be16_to_cpu(sp_iohubs->version);

	/* Create PBCQ node under xscom */
	pbcq = dt_new_addr(xcom, "pbcq", pe_xscom);
	if (!pbcq)
		return NULL;

	/* "reg" property contains in order the PE, PCI and SPCI XSCOM
	 * addresses
	 */
	reg[0] = pe_xscom;
	reg[1] = 0x20;
	reg[2] = pci_xscom;
	reg[3] = 0x05;
	reg[4] = spci_xscom;
	reg[5] = 0x15;
	dt_add_property(pbcq, "reg", reg, sizeof(reg));

	/* A couple more things ... */
	dt_add_property_strings(pbcq, "compatible", "ibm,power8-pbcq");
	dt_add_property_cells(pbcq, "ibm,phb-index", index);
	dt_add_property_cells(pbcq, "ibm,hub-id", be16_to_cpu(hub->hub_num));

	/* The loc code of the PHB itself is different from the base
	 * loc code of the slots (It's actually the DCM's loc code).
	 */
	io_get_loc_code(sp_iohubs, pbcq, "ibm,loc-code");

	/* We indicate that this is an IBM setup, which means that
	 * the presence detect A/B bits are meaningful. So far we
	 * don't know whether they make any sense on customer setups
	 * so we only set that when booting with HDAT
	 */
	dt_add_property(pbcq, "ibm,use-ab-detect", NULL, 0);

	/* HDAT spec has these in version 0x6A and later */
	if (hdif_vers >= 0x6a) {
		u64 eq0 = be64_to_cpu(hub->phb_lane_eq[index][0]);
		u64 eq1 = be64_to_cpu(hub->phb_lane_eq[index][1]);
		u64 eq2 = be64_to_cpu(hub->phb_lane_eq[index][2]);
		u64 eq3 = be64_to_cpu(hub->phb_lane_eq[index][3]);

		dt_add_property_u64s(pbcq, "ibm,lane-eq", eq0, eq1, eq2, eq3);
	}

	/* Currently we only create a PBCQ node, the actual PHB nodes
	 * will be added by sapphire later on.
	 */
	return pbcq;
}

static struct dt_node *add_pec_stack(const struct cechub_io_hub *hub,
				     struct dt_node *pbcq, int stack_index,
				     int phb_index, u8 active_phbs)
{
	struct dt_node *stack;
	u64 eq[8];
	uint32_t version;
	u8 *gen4;
	int i;

	stack = dt_new_addr(pbcq, "stack", stack_index);
	assert(stack);

	dt_add_property_cells(stack, "reg", stack_index);
	dt_add_property_cells(stack, "ibm,phb-index", phb_index);
	dt_add_property_string(stack, "compatible", "ibm,power9-phb-stack");

	/* XXX: This should probably just return if the PHB is disabled
	 *      rather than adding the extra properties.
	 */

	if (active_phbs & (0x80 >> phb_index))
		dt_add_property_string(stack, "status", "okay");
	else
		dt_add_property_string(stack, "status", "disabled");

	for (i = 0; i < 4; i++) /* gen 3 eq settings */
		eq[i] = be64_to_cpu(hub->phb_lane_eq[phb_index][i]);
	for (i = 0; i < 4; i++) /* gen 4 eq settings */
		eq[i+4] = be64_to_cpu(hub->phb4_lane_eq[phb_index][i]);

	/* Lane-eq settings are packed 2 bytes per lane for 16 lanes
	 * On P9 DD1, 2 bytes per lane are used in the hardware
	 * On P9 DD2, 1 byte  per lane is  used in the hardware
	 */
	version = mfspr(SPR_PVR);
	if (is_power9n(version) &&
	    (PVR_VERS_MAJ(version) == 1)) {
		dt_add_property_u64s(stack, "ibm,lane-eq", eq[0], eq[1],
				     eq[2], eq[3], eq[4], eq[5], eq[6], eq[7]);
		return stack;
	}

	/* Repack 2 byte lane settings into 1 byte */
	gen4 = (u8 *)&eq[4];
	for (i = 0; i < 16; i++)
		gen4[i] = gen4[2*i];

	dt_add_property_u64s(stack, "ibm,lane-eq", eq[0], eq[1],
			     eq[2], eq[3], eq[4], eq[5]);
	return stack;
}

static struct dt_node *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)
{
	struct dt_node *pbcq;
	uint32_t reg[4];
	uint8_t active_phb_mask = hub->fab_br0_pdt;
	uint32_t pe_xscom  = 0x4010c00 + (pec_index * 0x0000400);
	uint32_t pci_xscom = 0xd010800 + (pec_index * 0x1000000);
	int i;

	/* Create PBCQ node under xscom */
	pbcq = dt_new_addr(xcom, "pbcq", pe_xscom);
	if (!pbcq)
		return NULL;

	/* "reg" property contains (in order) the PE and PCI XSCOM addresses */
	reg[0] = pe_xscom;
	reg[1] = 0x100;
	reg[2] = pci_xscom;
	reg[3] = 0x200;
	dt_add_property(pbcq, "reg", reg, sizeof(reg));

	/* The hubs themselves go under the stacks */
	dt_add_property_strings(pbcq, "compatible", "ibm,power9-pbcq");
	dt_add_property_cells(pbcq, "ibm,pec-index", pec_index);
	dt_add_property_cells(pbcq, "#address-cells", 1);
	dt_add_property_cells(pbcq, "#size-cells", 0);

	for (i = 0; i < stacks; i++)
		add_pec_stack(hub, pbcq, i, phb_base + i, active_phb_mask);

	dt_add_property_cells(pbcq, "ibm,hub-id", be16_to_cpu(hub->hub_num));

	/* The loc code of the PHB itself is different from the base
	 * loc code of the slots (It's actually the DCM's loc code).
	 */
	io_get_loc_code(sp_iohubs, pbcq, "ibm,loc-code");

	prlog(PR_INFO, "CEC: Added PHB4 PBCQ %d with %d stacks\n",
		pec_index, stacks);

	/* the actual PHB nodes created later on by skiboot */
	return pbcq;
}

static struct dt_node *io_add_p8(const struct cechub_io_hub *hub,
				 const struct HDIF_common_hdr *sp_iohubs)
{
	struct dt_node *xscom;
	unsigned int i, chip_id;

	chip_id = pcid_to_chip_id(be32_to_cpu(hub->proc_chip_id));

	prlog(PR_INFO, "CEC:     HW CHIP=0x%x, HW TOPO=0x%04x\n", chip_id,
	      be16_to_cpu(hub->hw_topology));

	xscom = find_xscom_for_chip(chip_id);
	if (!xscom) {
		prerror("P8: Can't find XSCOM for chip %d\n", chip_id);
		return NULL;
	}

	/* Create PHBs, max 3 */
	for (i = 0; i < 3; i++) {
		if (hub->fab_br0_pdt & (0x80 >> i))
			/* XSCOM addresses are the same on Murano and Venice */
			io_add_phb3(hub, sp_iohubs, i, xscom,
				    0x02012000 + (i * 0x400),
				    0x09012000 + (i * 0x400),
				    0x09013c00 + (i * 0x40));
	}

	/* HACK: We return the XSCOM device for the VPD info */
	return xscom;
}

static struct dt_node *io_add_p9(const struct cechub_io_hub *hub,
				 const struct HDIF_common_hdr *sp_iohubs)
{
	struct dt_node *xscom;
	unsigned int chip_id;

	chip_id = pcid_to_chip_id(be32_to_cpu(hub->proc_chip_id));

	prlog(PR_INFO, "CEC:     HW CHIP=0x%x, HW TOPO=0x%04x\n", chip_id,
	      be16_to_cpu(hub->hw_topology));

	xscom = find_xscom_for_chip(chip_id);
	if (!xscom) {
		prerror("P9: Can't find XSCOM for chip %d\n", chip_id);
		return NULL;
	}

	prlog(PR_DEBUG, "IOHUB: PHB4 active bridge mask %x\n",
		(u32) hub->fab_br0_pdt);

	/* Create PBCQs */
	io_add_phb4(hub, sp_iohubs, xscom, 0, 1, 0);
	io_add_phb4(hub, sp_iohubs, xscom, 1, 2, 1);
	io_add_phb4(hub, sp_iohubs, xscom, 2, 3, 3);

	return xscom;
}


static void io_add_p8_cec_vpd(const struct HDIF_common_hdr *sp_iohubs)
{
	const struct HDIF_child_ptr *iokids;
	const void *iokid;	
	const void *kwvpd;
	unsigned int kwvpd_sz;

	/* P8 LXR0 kept in IO KID Keyword VPD */
	iokids = HDIF_child_arr(sp_iohubs, CECHUB_CHILD_IO_KIDS);
	if (!CHECK_SPPTR(iokids)) {
		prlog(PR_WARNING, "CEC:     No IOKID child array !\n");
		return;
	}
	if (!iokids->count) {
		prlog(PR_WARNING, "CEC:     IOKID count is 0 !\n");
		return;
	}
	if (be32_to_cpu(iokids->count) > 1) {
		prlog(PR_WARNING, "CEC:     WARNING ! More than 1 IO KID !!! (%d)\n",
		      iokids->count);
		/* Ignoring the additional ones */
	}

	iokid = HDIF_child(sp_iohubs, iokids, 0, "IO KID");
	if (!iokid) {
		prlog(PR_WARNING, "CEC:     No IO KID structure in child array !\n");
		return;
	}

	/* Grab base location code for slots */
	io_get_loc_code(iokid, dt_root, "ibm,io-base-loc-code");

	kwvpd = HDIF_get_idata(iokid, CECHUB_ASCII_KEYWORD_VPD, &kwvpd_sz);
	if (!kwvpd) {
		prlog(PR_WARNING, "CEC:     No VPD entry in IO KID !\n");
		return;
	}

	/* Grab LX load info */
	io_get_lx_info(kwvpd, kwvpd_sz, 0, dt_root);
}

/*
 * Assumptions:
 *
 * a) the IOSLOT index is the hub ID -CHECK
 *
 */

static struct dt_node *dt_slots;

static void add_i2c_link(struct dt_node *node, const char *link_name,
			u32 i2c_link)
{
	/* FIXME: Do something not shit */
	dt_add_property_cells(node, link_name, i2c_link);
}

/*
 * the root of the slots node has #address-cells = 2, <hub-index, phb-index>
 * can we ditch hub-index?
 */


static const struct slot_map_details *find_slot_details(
		const struct HDIF_common_hdr *ioslot, int entry)
{
	const struct slot_map_details *details = NULL;
	const struct HDIF_array_hdr *arr;
	unsigned int i;

	arr = HDIF_get_iarray(ioslot, IOSLOT_IDATA_DETAILS, NULL);
	HDIF_iarray_for_each(arr, i, details)
		if (be16_to_cpu(details->entry) == entry)
			break;

	return details;
}

static void parse_slot_details(struct dt_node *slot,
		const struct slot_map_details *details)
{
	u32 slot_caps;

	/*
	 * generic slot options
	 */

	dt_add_property_cells(slot, "max-power",
		be16_to_cpu(details->max_power));

	if (details->perst_ctl_type == SLOT_PERST_PHB_OR_SW)
		dt_add_property(slot, "pci-perst", NULL, 0);
	else if (details->perst_ctl_type == SLOT_PERST_SW_GPIO)
		dt_add_property_cells(slot, "gpio-perst", details->perst_gpio);

	if (details->presence_det_type == SLOT_PRESENCE_PCI)
		dt_add_property(slot, "pci-presence-detect", NULL, 0);

	/*
	 * specific slot capabilities
	 */
	slot_caps = be32_to_cpu(details->slot_caps);

	if (slot_caps & SLOT_CAP_LSI)
		dt_add_property(slot, "lsi", NULL, 0);

	if (slot_caps & SLOT_CAP_CAPI) {
		/* XXX: should we be more specific here?
		 *
		 * Also we should double check that this slot
		 * is a root connected slot.
		 */
		dt_add_property(slot, "capi", NULL, 0);
	}

	if (slot_caps & SLOT_CAP_CCARD) {
		dt_add_property(slot, "cable-card", NULL, 0);

		if (details->presence_det_type == SLOT_PRESENCE_I2C)
			add_i2c_link(slot, "i2c-presence-detect",
				be32_to_cpu(details->i2c_cable_card));
	}

	if (slot_caps & SLOT_CAP_HOTPLUG) {
		dt_add_property(slot, "hotplug", NULL, 0);

		/*
		 * Power control should only exist when the slot is hotplug
		 * capable
		 */
		if (details->power_ctrl_type == SLOT_PWR_I2C)
			add_i2c_link(slot, "i2c-power-ctrl",
				be32_to_cpu(details->i2c_power_ctl));
	}

	/*
	 * NB: Additional NVLink specific info is added to this node
	 *     when the SMP Link structures are parsed later on.
	 */
	if (slot_caps & SLOT_CAP_NVLINK)
		dt_add_property(slot, "nvlink", NULL, 0);
}

struct dt_node *find_slot_entry_node(struct dt_node *root, u32 entry_id)
{
	struct dt_node *node;

	for (node = dt_first(root); node; node = dt_next(root, node)) {
		if (!dt_has_node_property(node, DT_PRIVATE "entry_id", NULL))
			continue;

		if (dt_prop_get_u32(node, DT_PRIVATE "entry_id") == entry_id)
			return node;
	}

	return NULL;
}

/*
 * The internal HDAT representation of the various types of slot is kinda
 * dumb, translate it into something more sensible
 */
enum slot_types {
	st_root,
	st_slot,
	st_rc_slot,
	st_sw_upstream,
	st_sw_downstream,
	st_builtin
};

static const char *st_name(enum slot_types type)
{
	switch(type) {
	case st_root:		return "root-complex";
	case st_slot:		return "pluggable";
	case st_rc_slot:	return "pluggable"; /* differentiate? */
	case st_sw_upstream:	return "switch-up";
	case st_sw_downstream:	return "switch-down";
	case st_builtin:	return "builtin";
	}

	return "(none)";
}

static enum slot_types xlate_type(uint8_t type, u32 features)
{
	bool is_slot = features & SLOT_FEAT_SLOT;

	switch (type) {
	case SLOT_TYPE_ROOT_COMPLEX:
		return is_slot ? st_rc_slot : st_root;
	case SLOT_TYPE_BUILTIN:
		return st_builtin;
	case SLOT_TYPE_SWITCH_UP:
		return st_sw_upstream;
	case SLOT_TYPE_SWITCH_DOWN:
		return is_slot ? st_slot : st_sw_downstream;
	}

	return -1; /* shouldn't happen */
}

static bool is_port(struct dt_node *n)
{
	//return dt_node_is_compatible(n, "compatible", "ibm,pcie-port");
	return dt_node_is_compatible(n, "ibm,pcie-port");
}

/* this only works inside parse_one_ioslot() */
#define SM_LOG(level, fmt, ...) \
	prlog(level, "SLOTMAP: %x:%d:%d " \
		fmt, /* user input */ \
		chip_id, entry->phb_index, eid, \
		##__VA_ARGS__ /* user args */)

#define SM_ERR(fmt, ...) SM_LOG(PR_ERR, fmt, ##__VA_ARGS__)
#define SM_DBG(fmt, ...) SM_LOG(PR_DEBUG, fmt, ##__VA_ARGS__)

static void parse_one_slot(const struct slot_map_entry *entry,
		const struct slot_map_details *details, int chip_id)
{
	struct dt_node *node, *parent = NULL;
	u16 eid, pid, vid, did;
	u32 flags;
	int type;

	flags = be32_to_cpu(entry->features);
	type = xlate_type(entry->type, flags);

	eid = be16_to_cpu(entry->entry_id);
	pid = be16_to_cpu(entry->parent_id);

	SM_DBG("%s - eid = %d, pid = %d, name = %8s\n",
		st_name(type), eid, pid,
		strnlen(entry->name, 8) ? entry->name : "");

	/* empty slot, ignore it */
	if (eid == 0x0 && pid == 0x0)
		return;

	if (type != st_root && type != st_rc_slot) {
		parent = find_slot_entry_node(dt_slots, pid);
		if (!parent) {
			SM_ERR("Unable to find node for parent slot (id = %d)\n",
				pid);
			return;
		}
	}

	switch (type) {
	case st_root:
	case st_rc_slot:
		node = dt_new_2addr(dt_slots, "root-complex",
						chip_id, entry->phb_index);
		dt_add_property_cells(node, "reg", chip_id, entry->phb_index);
		dt_add_property_cells(node, "#address-cells", 2);
		dt_add_property_cells(node, "#size-cells", 0);
		dt_add_property_strings(node, "compatible",
				"ibm,pcie-port", "ibm,pcie-root-port");
		dt_add_property_cells(node, "ibm,chip-id", chip_id);
		parent = node;

		/*
		 * The representation of slots attached directly to the
		 * root complex is a bit wierd. If this is just a root
		 * complex then stop here, otherwise fall through to create
		 * the slot node.
		 */
		if (type == st_root)
			break;

		/* fallthrough*/
	case st_sw_upstream:
	case st_builtin:
	case st_slot:
		if (!is_port(parent)) {
			SM_ERR("%s connected to %s (%d), should be %s or %s!\n",
				st_name(type), parent->name, pid,
				st_name(st_root), st_name(st_sw_downstream));
			return;
		}

		vid = (be32_to_cpu(entry->vendor_id) & 0xffff);
		did = (be32_to_cpu(entry->device_id) & 0xffff);

		prlog(PR_DEBUG, "Found %s slot with %x:%x\n",
			st_name(type), vid, did);

		/* The VID:DID is only meaningful for builtins and switches */
		if (type == st_sw_upstream && vid && did) {
			node = dt_new_2addr(parent, st_name(type), vid, did);
			dt_add_property_cells(node, "reg", vid, did);
		} else {
			/*
			 * If we get no vdid then create a "wildcard" slot
			 * that matches any device
			 */
			node = dt_new(parent, st_name(type));
		}

		if (type == st_sw_upstream) {
			dt_add_property_cells(node, "#address-cells", 1);
			dt_add_property_cells(node, "#size-cells", 0);
			dt_add_property_cells(node, "upstream-port",
					entry->up_port);
		}
		break;

	case st_sw_downstream: /* slot connected to switch output */
		node = dt_new_addr(parent, "down-port", entry->down_port);
		dt_add_property_strings(node, "compatible",
				"ibm,pcie-port");
		dt_add_property_cells(node, "reg", entry->down_port);

		break;

	default:
		SM_ERR("Unknown slot map type %x\n", entry->type);
		return;
	}

	/*
	 * Now add any generic slot map properties.
	 */

	/* private since we don't want hdat stuff leaking */
	dt_add_property_cells(node, DT_PRIVATE "entry_id", eid);

	if (entry->mrw_slot_id)
		dt_add_property_cells(node, "mrw-slot-id",
				be16_to_cpu(entry->mrw_slot_id));

	if (entry->lane_mask)
		dt_add_property_cells(node, "lane-mask",
				be16_to_cpu(entry->lane_mask));

	/* what is the difference between this and the lane reverse? */
	if (entry->lane_reverse)
		dt_add_property_cells(node, "lanes-reversed",
				be16_to_cpu(entry->lane_reverse));

	if (strnlen(entry->name, sizeof(entry->name))) {
		/*
		 * HACK: On some platforms (witherspoon) the slot label is
		 * applied to the device rather than the pcie downstream port
		 * that has the slot under it. Hack around this by moving the
		 * slot label up if the parent port doesn't have one.
		 */
		if (dt_node_is_compatible(node->parent, "ibm,pcie-port") &&
		    !dt_find_property(node->parent, "ibm,slot-label")) {
			dt_add_property_nstr(node->parent, "ibm,slot-label",
					entry->name, sizeof(entry->name));
		}

		dt_add_property_nstr(node, "ibm,slot-label",
				entry->name, sizeof(entry->name));
	}

	if (entry->type == st_slot || entry->type == st_rc_slot)
		dt_add_property(node, "ibm,pluggable", NULL, 0);

	if (details)
		parse_slot_details(node, details);
}

/*
 * Under the IOHUB structure we have and idata array describing
 * the PHBs under each chip. The IOHUB structure also has a child
 * array called IOSLOT which describes slot map. The i`th element
 * of the IOSLOT array corresponds to the slot map of the i`th
 * element of the iohubs idata array.
 *
 * Probably.
 *
 * Furthermore, arrayarrayarrayarrayarray.
 */

static struct dt_node *get_slot_node(void)
{
	struct dt_node *slots = dt_find_by_name(dt_root, "ibm,pcie-slots");

	if (!slots) {
		slots = dt_new(dt_root, "ibm,pcie-slots");
		dt_add_property_cells(slots, "#address-cells", 2);
		dt_add_property_cells(slots, "#size-cells", 0);
	}

	return slots;
}

static void io_parse_slots(const struct HDIF_common_hdr *sp_iohubs, int hub_id)
{
	const struct HDIF_child_ptr *ioslot_arr;
	const struct HDIF_array_hdr *entry_arr;
	const struct HDIF_common_hdr *ioslot;
	const struct slot_map_entry *entry;
	unsigned int i, count;

	if (sp_iohubs->child_count <= CECHUB_CHILD_IOSLOTS)
		return;

	ioslot_arr = HDIF_child_arr(sp_iohubs, CECHUB_CHILD_IOSLOTS);
	if (!ioslot_arr)
		return;

	count = be32_to_cpu(ioslot_arr->count); /* should only be 1 */
	if (!count)
		return;

	dt_slots = get_slot_node();

	prlog(PR_DEBUG, "CEC: Found slot map for IOHUB %d\n", hub_id);
	if (count > 1)
		prerror("CEC: Multiple IOSLOTs found for IO HUB %d\n", hub_id);

	ioslot = HDIF_child(sp_iohubs, ioslot_arr, 0, "IOSLOT");
	if (!ioslot)
		return;

	entry_arr = HDIF_get_iarray(ioslot, IOSLOT_IDATA_SLOTMAP, NULL);
	HDIF_iarray_for_each(entry_arr, i, entry) {
		const struct slot_map_details *details;

		details = find_slot_details(ioslot,
				be16_to_cpu(entry->entry_id));
		parse_one_slot(entry, details, hub_id);
	}
}

static void io_parse_fru(const void *sp_iohubs)
{
	unsigned int i;
	struct dt_node *hn;
	int count;

	count = HDIF_get_iarray_size(sp_iohubs, CECHUB_FRU_IO_HUBS);
	if (count < 1) {
		prerror("CEC: IO FRU with no chips !\n");
		return;
	}

	prlog(PR_INFO, "CEC:   %d chips in FRU\n", count);

	/* Iterate IO hub array */
	for (i = 0; i < count; i++) {
		const struct cechub_io_hub *hub;
		unsigned int size, hub_id;
		uint32_t chip_id;

		hub = HDIF_get_iarray_item(sp_iohubs, CECHUB_FRU_IO_HUBS,
					   i, &size);
		if (!hub || size < CECHUB_IOHUB_MIN_SIZE) {
			prerror("CEC:     IO-HUB Chip %d bad idata\n", i);
			continue;
		}

		switch (hub->flags & CECHUB_HUB_FLAG_STATE_MASK) {
		case CECHUB_HUB_FLAG_STATE_OK:
			prlog(PR_DEBUG, "CEC:   IO Hub Chip #%d OK\n", i);
			break;
		case CECHUB_HUB_FLAG_STATE_FAILURES:
			prlog(PR_WARNING, "CEC:   IO Hub Chip #%d OK"
			      " with failures\n", i);
			break;
		case CECHUB_HUB_FLAG_STATE_NOT_INST:
			prlog(PR_DEBUG, "CEC:   IO Hub Chip #%d"
			      " Not installed\n", i);
			continue;
		case CECHUB_HUB_FLAG_STATE_UNUSABLE:
			prlog(PR_DEBUG, "CEC:   IO Hub Chip #%d Unusable\n", i);
			continue;
		}

		hub_id = be16_to_cpu(hub->iohub_id);

		/* GX BAR assignment */
		prlog(PR_DEBUG, "CEC:   PChip: %d HUB ID: %04x [EC=0x%x]"
		      " Hub#=%d)\n",
		      be32_to_cpu(hub->proc_chip_id), hub_id,
		      be32_to_cpu(hub->ec_level), be16_to_cpu(hub->hub_num));

		switch(hub_id) {
		case CECHUB_HUB_P7IOC:
			prlog(PR_INFO, "CEC:     P7IOC !\n");
			hn = io_add_p7ioc(hub, sp_iohubs);
			io_add_common(hn, hub);
			break;
		case CECHUB_HUB_MURANO:
		case CECHUB_HUB_MURANO_SEGU:
			prlog(PR_INFO, "CEC:     Murano !\n");
			hn = io_add_p8(hub, sp_iohubs);
			break;
		case CECHUB_HUB_VENICE_WYATT:
			prlog(PR_INFO, "CEC:     Venice !\n");
			hn = io_add_p8(hub, sp_iohubs);
			break;
		case CECHUB_HUB_NIMBUS_SFORAZ:
		case CECHUB_HUB_NIMBUS_MONZA:
		case CECHUB_HUB_NIMBUS_LAGRANGE:
			prlog(PR_INFO, "CEC:     Nimbus !\n");
			hn = io_add_p9(hub, sp_iohubs);
			break;
		case CECHUB_HUB_CUMULUS_DUOMO:
			prlog(PR_INFO, "CEC:     Cumulus !\n");
			hn = io_add_p9(hub, sp_iohubs);
			break;
		default:
			prlog(PR_ERR, "CEC:     Hub ID 0x%04x unsupported !\n",
			      hub_id);
			hn = NULL;
		}

		chip_id = pcid_to_chip_id(be32_to_cpu(hub->proc_chip_id));

		/* parse the slot map if we have one */
		io_parse_slots(sp_iohubs, chip_id);
	}

	/* On P8, grab the CEC VPD */
	if (proc_gen == proc_gen_p8)
		io_add_p8_cec_vpd(sp_iohubs);
}

void io_parse(void)
{
	const struct HDIF_common_hdr *sp_iohubs;
	unsigned int i, size;

	/* Look for IO Hubs */
	if (!get_hdif(&spira.ntuples.cec_iohub_fru, "IO HUB")) {
		prerror("CEC: Cannot locate IO Hub FRU data !\n");
		return;
	}

	/*
	 * Note about LXRn numbering ...
	 *
	 * I can't completely make sense of what that is supposed to be, so
	 * for now, what we do is look for the first one we can find and
	 * increment it for each chip. Works for the machines I have here
	 */

	for_each_ntuple_idx(&spira.ntuples.cec_iohub_fru, sp_iohubs, i,
			    CECHUB_FRU_HDIF_SIG) {
		const struct cechub_hub_fru_id *fru_id_data;
		unsigned int type;
		static const char *typestr[] = {
			"Reservation",
			"Card",
			"CPU Card",
			"Backplane",
			"Backplane Extension"
		};
		fru_id_data = HDIF_get_idata(sp_iohubs, CECHUB_FRU_ID_DATA_AREA,
					     &size);
		if (!fru_id_data || size < sizeof(struct cechub_hub_fru_id)) {
			prerror("CEC: IO-HUB FRU %d, bad ID data\n", i);
			continue;
		}
		type = be32_to_cpu(fru_id_data->card_type);

		prlog(PR_INFO, "CEC: HUB FRU %d is %s\n",
		      i, type > 4 ? "Unknown" : typestr[type]);

		/*
		 * We currently only handle the backplane (Juno) and
		 * processor FRU (P8 machines)
		 */
		if (type != CECHUB_FRU_TYPE_CEC_BKPLANE &&
		    type != CECHUB_FRU_TYPE_CPU_CARD) {
			prerror("CEC:   Unsupported type\n");
			continue;
		}

		/* We don't support Hubs connected to pass-through ports */
		if (fru_id_data->flags & (CECHUB_FRU_FLAG_HEADLESS |
					  CECHUB_FRU_FLAG_PASSTHROUGH)) {
			prerror("CEC:   Headless or Passthrough unsupported\n");
			continue;
		}

		/* Ok, we have a reasonable candidate */
		io_parse_fru(sp_iohubs);
	}
}

