/* Copyright 2015 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 <device.h>
#include <console.h>
#include <chip.h>
#include <pci-cfg.h>
#include <pci.h>
#include <pci-slot.h>

#include "astbmc.h"

static const struct slot_table_entry *slot_top_table;

void slot_table_init(const struct slot_table_entry *top_table)
{
	slot_top_table = top_table;
}

static const struct slot_table_entry *match_slot_phb_entry(struct phb *phb)
{
	uint32_t chip_id = dt_get_chip_id(phb->dt_node);
	uint32_t phb_idx = dt_prop_get_u32_def(phb->dt_node,
					       "ibm,phb-index", 0);
	const struct slot_table_entry *ent;

	if (!slot_top_table)
		return NULL;

	for (ent = slot_top_table; ent->etype != st_end; ent++) {
		if (ent->etype != st_phb) {
			prerror("SLOT: Bad DEV entry type in table !\n");
			continue;
		}
		if (ent->location == ST_LOC_PHB(chip_id, phb_idx))
			return ent;
	}
	return NULL;
}

static const struct slot_table_entry *match_slot_dev_entry(struct phb *phb,
							   struct pci_device *pd)
{
	const struct slot_table_entry *parent, *ent;
	uint32_t bdfn;

	/* Find a parent recursively */
	if (pd->parent)
		parent = match_slot_dev_entry(phb, pd->parent);
	else {
		/* No parent, this is a root complex, find the PHB */
		parent = match_slot_phb_entry(phb);
	}
	/* No parent ? Oops ... */
	if (!parent || !parent->children)
		return NULL;
	for (ent = parent->children; ent->etype != st_end; ent++) {
		if (ent->etype == st_phb) {
			prerror("SLOT: Bad PHB entry type in table !\n");
			continue;
		}

		/* NPU slots match on device, not function */
		if (ent->etype == st_npu_slot)
			bdfn = pd->bdfn & 0xf8;
		else
			bdfn = pd->bdfn & 0xff;

		if (ent->location == bdfn)
			return ent;
	}
	return NULL;
}

static void slot_table_add_properties(struct pci_slot *slot,
				struct dt_node *np)
{
	struct slot_table_entry *ent = slot->data;

	if (ent)
		pci_slot_add_loc(slot, np, ent->name);
	else
		pci_slot_add_loc(slot, np, NULL);
}

void slot_table_get_slot_info(struct phb *phb, struct pci_device *pd)
{
	const struct slot_table_entry *ent;
	struct pci_slot *slot;

	if (!pd || pd->slot)
		return;

	ent = match_slot_dev_entry(phb, pd);

	if (!ent || !ent->name) {
		slot = pcie_slot_create_dynamic(phb, pd);
		if (slot) {
			slot->ops.add_properties = slot_table_add_properties;
			slot->pluggable = true;
		}

		return;
	}

	slot = pcie_slot_create(phb, pd);
	assert(slot);

	slot->pluggable = !!(ent->etype == st_pluggable_slot);
	slot->ops.add_properties = slot_table_add_properties;
	slot->power_limit = ent->power_limit;
	slot->data = (void *)ent;
}

static void dt_slot_add_properties(struct pci_slot *slot,
				struct dt_node *np)
{
	struct dt_node *slot_np = slot->data;
	const char *label = NULL;

	if (slot_np)
		label = dt_prop_get_def(slot_np, "ibm,slot-label", NULL);

	pci_slot_add_loc(slot, np, label);
}

void dt_slot_get_slot_info(struct phb *phb, struct pci_device *pd)
{
	struct dt_node *slot_np;
	struct pci_slot *slot;
	const char *name = NULL;
	uint32_t power_limit = 0;
	bool pluggable = false;

	if (!pd || pd->slot)
		return;

	slot_np = map_pci_dev_to_slot(phb, pd);
	if (slot_np) {
		pluggable = dt_has_node_property(slot_np,
					"ibm,pluggable", NULL);
		power_limit = dt_prop_get_u32_def(slot_np,
					"ibm,power-limit", 0);
		name = dt_prop_get_def(slot_np, "ibm,slot-label", NULL);
	}

	if (!slot_np || !name) {
		slot = pcie_slot_create_dynamic(phb, pd);
		if (slot) {
			slot->ops.add_properties = dt_slot_add_properties;
			slot->pluggable = true;
			slot->data = (void *)slot_np;
		}

		return;
	}

	slot = pcie_slot_create(phb, pd);
	assert(slot);

	slot->ops.add_properties = dt_slot_add_properties;
	slot->pluggable = pluggable;
	slot->power_limit = power_limit;
	slot->data = (void *)slot_np;
}

static int __pci_find_dev_by_location(struct phb *phb,
				      struct pci_device *pd, void *userdata)
{
	uint16_t location = *((uint16_t *)userdata);

	if (!phb || !pd)
		return 0;

	if ((pd->bdfn & 0xff) == location)
		return 1;

	return 0;
}

static struct pci_device *pci_find_dev_by_location(struct phb *phb, uint16_t location)
{
	return pci_walk_dev(phb, NULL, __pci_find_dev_by_location, &location);
}

static struct phb* get_phb_by_location(uint32_t location)
{
	struct phb *phb = NULL;
	uint32_t chip_id, phb_idx;

	for_each_phb(phb) {
		chip_id = dt_get_chip_id(phb->dt_node);
		phb_idx = dt_prop_get_u32_def(phb->dt_node,
					      "ibm,phb-index", 0);
		if (location == ST_LOC_PHB(chip_id, phb_idx))
			break;
	}

	return phb;
}

static int check_slot_table(struct phb *phb,
			    const struct slot_table_entry *parent)
{
	const struct slot_table_entry *ent;
	struct pci_device *dev = NULL;
	int r = 0;

	if (parent == NULL)
		return 0;

	for (ent = parent; ent->etype != st_end; ent++) {
		switch (ent->etype) {
		case st_phb:
			phb = get_phb_by_location(ent->location);
			if (!phb) {
				prlog(PR_ERR, "PCI: PHB %s (%x) not found\n",
				      ent->name, ent->location);
				r++;
			}
			break;
		case st_pluggable_slot:
		case st_builtin_dev:
			if (!phb)
				break;
			phb_lock(phb);
			dev = pci_find_dev_by_location(phb, ent->location);
			phb_unlock(phb);
			if (!dev) {
				prlog(PR_ERR, "PCI: built-in device not found: %s (loc: %x)\n",
				      ent->name, ent->location);
				r++;
			}
			break;
		case st_end:
		case st_npu_slot:
			break;
		}
		if (ent->children)
			r+= check_slot_table(phb, ent->children);
	}
	return r;
}

void check_all_slot_table(void)
{
	if (!slot_top_table)
		return;

	prlog(PR_DEBUG, "PCI: Checking slot table against detected devices\n");
	check_slot_table(NULL, slot_top_table);
}
