[Skiboot] [PATCH] activate shared PCI slot support on witherspoon
Michael Neuling
mikey at neuling.org
Tue May 23 10:33:06 AEST 2017
> [PATCH] activate shared PCI slot support on witherspoon
Subject should start with a capital letter and also have a prefix.
I'd suggest:
phb4: Activate shared PCI slot on witherspoon
On Mon, 2017-05-22 at 20:49 +0200, Frederic Barrat wrote:
> Witherspoon systems come with a 'shared' PCI slot: it looks like a x16
> slot, but it's actually two x8 connected to two PHBs of two different
> chips. Taking advantage of it requires some logic on the PCI
> adapter. Only the Mellanox CX5 adapter is known to support it at the
> time of this writing.
>
> This patch enables support for the shared slot on witherspoon. It
> looks for the presence bits from the 2 PHBs and activate sharing
> through a gpio setup.
What happens if you plug in a x8 or some other PCIe device?
If you can document the various configurations so we have something to point
people to when this becomes a support issue. x8 in this x16 slot. x16 that
doesn't understand this shared stuff in this slot? CX5 in this slot. Nothing in
this slot?
> Note that there's no easy way to be sure that the card is indeed a
> shared-slot compatible PCI adapter and not a normal x16 card. Plugging
> a normal x16 adapter on the shared slot should be avoided on
> witherspoon, as the link won't train on the second slot. Link training
> results in a timeout and a longer boot time.
>
> Signed-off-by: Frederic Barrat <fbarrat at linux.vnet.ibm.com>
> ---
> core/init.c | 2 ++
> hw/phb4.c | 62
> +++++++++++++++++++++++++++++++++++++++++-
> include/platform.h | 5 ++++
> include/skiboot.h | 1 +
> include/xscom-p9-regs.h | 3 ++
> platforms/astbmc/witherspoon.c | 6 ++++
> 6 files changed, 78 insertions(+), 1 deletion(-)
>
> diff --git a/core/init.c b/core/init.c
> index dce10fd6..54c13a16 100644
> --- a/core/init.c
> +++ b/core/init.c
> @@ -1018,6 +1018,8 @@ void __noreturn __nomcount main_cpu_entry(const void
> *fdt)
> probe_npu();
> probe_npu2();
>
> + if (platform.pre_pci_fixup)
> + platform.pre_pci_fixup();
Do this this check in a wrapper function to keep this function cleaner..
> /* Initialize PCI */
> pci_init_slots();
>
> diff --git a/hw/phb4.c b/hw/phb4.c
> index 318d934d..2843e6d7 100644
> --- a/hw/phb4.c
> +++ b/hw/phb4.c
> @@ -77,6 +77,66 @@ static void phb4_init_hw(struct phb4 *p, bool first_init);
> #define PHBLOGCFG(p, fmt, a...) do {} while (0)
> #endif
>
> +static int get_opal_id(unsigned int chip_id, unsigned int index)
> +{
> + return chip_id * 6 + index;
6?
> +}
> +
> +static void phb4_activate_shared_slot(struct proc_chip *chip)
This should be phb4_activate_shared_slot_witherspoon?
What is this function actually doing? There needs to be some documentation
here.
> +{
> + uint64_t val;
> +
> + xscom_read(chip->id, P9_GPIO_DATA_OUT_ENABLE, &val);
> + val |= PPC_BIT(2);
> + xscom_write(chip->id, P9_GPIO_DATA_OUT_ENABLE, val);
> +
> + xscom_read(chip->id, P9_GPIO_DATA_OUT, &val);
> + val |= PPC_BIT(2);
> + xscom_write(chip->id, P9_GPIO_DATA_OUT, val);
> + time_wait_us(100);
> + prlog(PR_INFO, "Shared PCI slot activated\n");
> +}
> +
> +void phb4_pre_pci_fixup_witherspoon(void)
> +{
> + struct pci_slot *slot0, *slot1;
> + struct proc_chip *chip0, *chip1;
> + uint8_t p0 = 0, p1 = 0;
> +
> + /*
> + * Detect if a card (Mellanox CX5) is present on the
Why have the CX5 comment here? None of this seems to be CX5 specific.
> + * shared slot and do some extra configuration if it is.
> + *
> + * The shared slot, a.k.a "Slot 2", is connected to
> + * PEC2 phb index 3 on both chips.
> + *
> + * One issue is that if the presence bits of the 2 slots are set,
> + * we don't really know if it is a CX5 card or a 'normal' x16 PCI
> + * card. So we activate the shared slot when we see a card in the
> + * 2 slots. If it's not a Mellanox CX5, it doesn't hurt.
> + *
> + * On the 2nd slot, the link won't train for a normal x16 card, the
> + * procedure will timeout, thus adding some delay to the boot time.
> + */
> + chip0 = next_chip(NULL);
> + slot0 = pci_slot_find(get_opal_id(chip0->id, 3));
> + chip1 = next_chip(chip0);
> + slot1 = pci_slot_find(get_opal_id(chip1->id, 3));
> + if (next_chip(chip1)) {
> + prlog(PR_WARNING,
> + "Unexpected number of chips, skipping shared slot
> detection\n");
> + return;
> + }
> + if (slot0 && slot1) {
> + if (slot0->ops.get_presence_state)
> + slot0->ops.get_presence_state(slot0, &p0);
> + if (slot1->ops.get_presence_state)
> + slot1->ops.get_presence_state(slot1, &p1);
> + if (p0 == 1 && p1 == 1)
> + phb4_activate_shared_slot(chip1);
> + }
> +}
> +
> /* Note: The "ASB" name is historical, practically this means access via
> * the XSCOM backdoor
> */
> @@ -3284,7 +3344,7 @@ static void phb4_create(struct dt_node *np)
> /* We register the PHB before we initialize it so we
> * get a useful OPAL ID for it
> */
> - pci_register_phb(&p->phb, p->chip_id * 6 + p->index); //6 PHBs per
> chip?
This "6" comment should be above?
> + pci_register_phb(&p->phb, get_opal_id(p->chip_id, p->index));
>
> /* Create slot structure */
> slot = phb4_slot_create(&p->phb);
> diff --git a/include/platform.h b/include/platform.h
> index 91332042..4dcdb335 100644
> --- a/include/platform.h
> +++ b/include/platform.h
> @@ -101,6 +101,11 @@ struct platform {
> void (*pci_setup_phb)(struct phb *phb, unsigned int
> index);
>
> /*
> + * This is called before resetting the PHBs (lift PERST) and
> + * probing the devices. The PHBs have already been initialized.
> + */
> + void (*pre_pci_fixup)(void);
> + /*
> * Called during PCI scan for each device. For bridges, this is
> * called before its children are probed. This is called for
> * every device and for the PHB itself with a NULL pd though
> diff --git a/include/skiboot.h b/include/skiboot.h
> index 5c8b0c85..14953cab 100644
> --- a/include/skiboot.h
> +++ b/include/skiboot.h
> @@ -218,6 +218,7 @@ extern int phb3_preload_capp_ucode(void);
> extern void phb3_preload_vpd(void);
> extern int phb4_preload_capp_ucode(void);
> extern void phb4_preload_vpd(void);
> +extern void phb4_pre_pci_fixup_witherspoon(void);
> extern void probe_npu(void);
> extern void probe_npu2(void);
> extern void uart_init(void);
> diff --git a/include/xscom-p9-regs.h b/include/xscom-p9-regs.h
> index 7da404ba..4738e812 100644
> --- a/include/xscom-p9-regs.h
> +++ b/include/xscom-p9-regs.h
> @@ -18,4 +18,7 @@
> #define P9X_EX_NCU_DARN_BAR 0x11011
> #define P9X_EX_NCU_DARN_BAR_EN PPC_BIT(0)
>
> +#define P9_GPIO_DATA_OUT_ENABLE 0x00000000000B0054ull
> +#define P9_GPIO_DATA_OUT 0x00000000000B0051ull
> +
> #endif /* __XSCOM_P9_REGS_H__ */
> diff --git a/platforms/astbmc/witherspoon.c b/platforms/astbmc/witherspoon.c
> index abaa7c9b..083e7cff 100644
> --- a/platforms/astbmc/witherspoon.c
> +++ b/platforms/astbmc/witherspoon.c
> @@ -38,10 +38,16 @@ static bool witherspoon_probe(void)
> return true;
> }
>
> +static void witherspoon_pre_pci_fixup(void)
> +{
> + phb4_pre_pci_fixup_witherspoon();
> +}
> +
> DECLARE_PLATFORM(witherspoon_platform) = {
> .name = "Witherspoon",
> .probe = witherspoon_probe,
> .init = astbmc_init,
> + .pre_pci_fixup = witherspoon_pre_pci_fixup,
> .start_preload_resource = flash_start_preload_resource,
> .resource_loaded = flash_resource_loaded,
> .bmc = NULL, /* FIXME: Add openBMC */
More information about the Skiboot
mailing list