diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2015-08-20 11:29:29 +1000 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2015-09-01 16:18:35 +1000 |
commit | 9fb3a04fd25d18b4865e44d461e6a8993b7717a0 (patch) | |
tree | 56d2eefbb6c5893aa468ab087ad8ac38fcdbef19 /platforms/astbmc | |
parent | 58ccf6a977ade80e4475d7d350c4c076ab1accad (diff) | |
download | talos-skiboot-9fb3a04fd25d18b4865e44d461e6a8993b7717a0.tar.gz talos-skiboot-9fb3a04fd25d18b4865e44d461e6a8993b7717a0.zip |
plat/bmc: Add infrastructure for slot tables
This adds some basic infrastructure for simple slot tables allowing
us to name slots and built-in devices on OPP machines.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
[stewart@linux.vnet.ibm.com: add IBM (C) in new file, trim trailing whitespace]
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'platforms/astbmc')
-rw-r--r-- | platforms/astbmc/Makefile.inc | 2 | ||||
-rw-r--r-- | platforms/astbmc/astbmc.h | 18 | ||||
-rw-r--r-- | platforms/astbmc/slots.c | 100 |
3 files changed, 119 insertions, 1 deletions
diff --git a/platforms/astbmc/Makefile.inc b/platforms/astbmc/Makefile.inc index d0151d26..8c749e8a 100644 --- a/platforms/astbmc/Makefile.inc +++ b/platforms/astbmc/Makefile.inc @@ -1,6 +1,6 @@ SUBDIRS += $(PLATDIR)/astbmc -ASTBMC_OBJS = palmetto.o habanero.o firestone.o garrison.o pnor.o common.o +ASTBMC_OBJS = palmetto.o habanero.o firestone.o garrison.o pnor.o common.o slots.o ASTBMC = $(PLATDIR)/astbmc/built-in.o $(ASTBMC): $(ASTBMC_OBJS:%=$(PLATDIR)/astbmc/%) diff --git a/platforms/astbmc/astbmc.h b/platforms/astbmc/astbmc.h index 489ffd20..23c31c7c 100644 --- a/platforms/astbmc/astbmc.h +++ b/platforms/astbmc/astbmc.h @@ -18,6 +18,21 @@ #ifndef __ASTBMC_H #define __ASTBMC_H +#define ST_LOC_PHB(chip_id, phb_idx) ((chip_id) << 16 | (phb_idx)) +#define ST_LOC_DEVFN(dev, fn) ((dev) << 3 | (fn)) + +struct slot_table_entry { + enum slot_table_etype { + st_end, /* End of list */ + st_phb, + st_pluggable_slot, + st_builtin_dev, + } etype; + uint32_t location; + const char *name; + const struct slot_table_entry *children; +}; + extern void astbmc_early_init(void); extern int64_t astbmc_ipmi_reboot(void); extern int64_t astbmc_ipmi_power_down(uint64_t request); @@ -25,4 +40,7 @@ extern void astbmc_init(void); extern void astbmc_ext_irq_serirq_cpld(unsigned int chip_id); extern int pnor_init(void); +extern void slot_table_init(const struct slot_table_entry *top_table); +extern void slot_table_get_slot_info(struct phb *phb, struct pci_device * pd); + #endif /* __ASTBMC_H */ diff --git a/platforms/astbmc/slots.c b/platforms/astbmc/slots.c new file mode 100644 index 00000000..2144112f --- /dev/null +++ b/platforms/astbmc/slots.c @@ -0,0 +1,100 @@ +/* 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.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; + + /* 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; + } + if (ent->location == (pd->bdfn & 0xff)) + return ent; + } + return NULL; +} + +void slot_table_get_slot_info(struct phb *phb, struct pci_device * pd) +{ + const struct slot_table_entry *ent; + struct pci_slot_info *si; + + if (!pd || pd->slot_info) + return; + ent = match_slot_dev_entry(phb, pd); + if (!ent || !ent->name) + return; + pd->slot_info = si = zalloc(sizeof(struct pci_slot_info)); + assert(pd->slot_info); + strncpy(si->label, ent->name, sizeof(si->label) - 1); + si->pluggable = ent->etype == st_pluggable_slot; + si->power_ctl = false; + si->wired_lanes = -1; + si->bus_clock = -1; + si->connector_type = -1; + si->card_desc = -1; + si->card_mech = -1; + si->pwr_led_ctl = -1; + si->attn_led_ctl = -1; +} |