From patchwork Mon Apr 27 06:26:31 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gavin Shan X-Patchwork-Id: 464811 X-Patchwork-Delegate: benh@kernel.crashing.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [103.22.144.68]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id A1AED140082 for ; Mon, 27 Apr 2015 16:28:30 +1000 (AEST) Received: from ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 8066B1A0BE4 for ; Mon, 27 Apr 2015 16:28:30 +1000 (AEST) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Received: from e23smtp05.au.ibm.com (e23smtp05.au.ibm.com [202.81.31.147]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id D87301A0AE1 for ; Mon, 27 Apr 2015 16:27:59 +1000 (AEST) Received: from /spool/local by e23smtp05.au.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Mon, 27 Apr 2015 16:27:59 +1000 Received: from d23dlp03.au.ibm.com (202.81.31.214) by e23smtp05.au.ibm.com (202.81.31.211) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Mon, 27 Apr 2015 16:27:57 +1000 Received: from d23relay08.au.ibm.com (d23relay08.au.ibm.com [9.185.71.33]) by d23dlp03.au.ibm.com (Postfix) with ESMTP id 6C1F2357804C for ; Mon, 27 Apr 2015 16:27:57 +1000 (EST) Received: from d23av01.au.ibm.com (d23av01.au.ibm.com [9.190.234.96]) by d23relay08.au.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id t3R6RndF38862920 for ; Mon, 27 Apr 2015 16:27:57 +1000 Received: from d23av01.au.ibm.com (localhost [127.0.0.1]) by d23av01.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id t3R6RNnx021982 for ; Mon, 27 Apr 2015 16:27:23 +1000 Received: from ozlabs.au.ibm.com (ozlabs.au.ibm.com [9.192.253.14]) by d23av01.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id t3R6RNjU021473; Mon, 27 Apr 2015 16:27:23 +1000 Received: from bran.ozlabs.ibm.com (haven.au.ibm.com [9.192.253.15]) by ozlabs.au.ibm.com (Postfix) with ESMTP id 89809A03DC; Mon, 27 Apr 2015 16:26:41 +1000 (AEST) Received: from gwshan (shangw.ozlabs.ibm.com [10.61.2.199]) by bran.ozlabs.ibm.com (Postfix) with ESMTP id 463FC16AA06; Mon, 27 Apr 2015 16:26:40 +1000 (AEST) Received: by gwshan (Postfix, from userid 1000) id 00D0E942234; Mon, 27 Apr 2015 16:26:39 +1000 (AEST) From: Gavin Shan To: skiboot@lists.ozlabs.org Date: Mon, 27 Apr 2015 16:26:31 +1000 Message-Id: <1430115993-20560-14-git-send-email-gwshan@linux.vnet.ibm.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1430115993-20560-1-git-send-email-gwshan@linux.vnet.ibm.com> References: <1430115993-20560-1-git-send-email-gwshan@linux.vnet.ibm.com> X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 15042706-0017-0000-0000-0000012612D0 Subject: [Skiboot] [PATCH v5 13/15] core/pci: PCI slot X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" Prior to PCI enumeration, fundamental reset and checking RC link status are carried out. Now, all of them are covered by PHB slot. The patch switches to PHB slot to do fundamental reset and checking RC link status. Signed-off-by: Gavin Shan --- core/pci.c | 162 +++++++++++++++------------------------------------------- include/pci.h | 20 -------- 2 files changed, 40 insertions(+), 142 deletions(-) diff --git a/core/pci.c b/core/pci.c index 5540d75..d7f969e 100644 --- a/core/pci.c +++ b/core/pci.c @@ -27,22 +27,22 @@ static struct phb *phbs[64]; #define PCITRACE(_p, _bdfn, fmt, a...) \ - prlog(PR_TRACE, "PHB%d:%02x:%02x.%x " fmt, \ + prlog(PR_TRACE, "PHB%04x:%02x:%02x.%x " fmt, \ (_p)->opal_id, \ ((_bdfn) >> 8) & 0xff, \ ((_bdfn) >> 3) & 0x1f, (_bdfn) & 0x7, ## a) #define PCIDBG(_p, _bdfn, fmt, a...) \ - prlog(PR_DEBUG, "PHB%d:%02x:%02x.%x " fmt, \ + prlog(PR_DEBUG, "PHB%04x:%02x:%02x.%x " fmt, \ (_p)->opal_id, \ ((_bdfn) >> 8) & 0xff, \ ((_bdfn) >> 3) & 0x1f, (_bdfn) & 0x7, ## a) #define PCINOTICE(_p, _bdfn, fmt, a...) \ - prlog(PR_NOTICE, "PHB%d:%02x:%02x.%x " fmt, \ + prlog(PR_NOTICE, "PHB%04x:%02x:%02x.%x " fmt, \ (_p)->opal_id, \ ((_bdfn) >> 8) & 0xff, \ ((_bdfn) >> 3) & 0x1f, (_bdfn) & 0x7, ## a) #define PCIERR(_p, _bdfn, fmt, a...) \ - prlog(PR_ERR, "PHB%d:%02x:%02x.%x " fmt, \ + prlog(PR_ERR, "PHB%04x:%02x:%02x.%x " fmt, \ (_p)->opal_id, \ ((_bdfn) >> 8) & 0xff, \ ((_bdfn) >> 3) & 0x1f, (_bdfn) & 0x7, ## a) @@ -735,110 +735,66 @@ void pci_device_init(struct phb *phb, struct pci_device *pd) pci_disable_completion_timeout(phb, pd); } -/* - * The power state would be checked. If the power has - * been on, we will issue fundamental reset. Otherwise, - * we will power it on before issuing fundamental reset. - */ -static int64_t pci_phb_reset(struct phb *phb) +static void pci_reset_phb(void *data) { - const char *desc; + struct phb *phb = data; + struct pci_slot *slot = phb->slot; int64_t rc; - rc = phb->ops->power_state(phb); - if (rc < 0) { - PCIERR(phb, 0, "Failed to get power state, rc=%lld\n", rc); - return rc; - } - - if (rc == OPAL_SHPC_POWER_ON) { - desc = "fundamental reset"; - rc = phb->ops->fundamental_reset(phb); - } else { - desc = "power on"; - rc = phb->ops->slot_power_on(phb); - } - - if (rc < 0) { - /* Don't warn if it's just an empty slot */ - if (rc != OPAL_CLOSED) - goto warn_err; - return rc; + /* Skip reset without supported PHB slot as we + * rely on the slot callbacks for fundamental + * reset + */ + if (!slot) { + PCINOTICE(phb, 0, "Skip reset without slot\n"); + return; + } else if (!slot->ops.freset) { + PCINOTICE(phb, 0, "Skip reset without supported freset\n"); + return; } - /* Wait the internal state machine */ + /* Issue fundamental reset */ + pci_slot_add_flags(slot, PCI_SLOT_FLAG_BOOTUP); + rc = slot->ops.freset(slot); while (rc > 0) { time_wait(rc); - rc = phb->ops->poll(phb); + rc = slot->ops.poll(slot, NULL); } - warn_err: + pci_slot_remove_flags(slot, PCI_SLOT_FLAG_BOOTUP); if (rc < 0) - PCIERR(phb, 0, "Failed to %s, rc=%lld\n", desc, rc); - - return rc; + PCIERR(phb, 0, "Failure %lld polling slot\n", rc); } -static void pci_reset_phb(void *data) +static void pci_scan_phb(void *data) { struct phb *phb = data; + struct pci_slot *slot = phb->slot; + uint32_t mps = 0xfffffff; + uint8_t link = 0; int64_t rc; - PCIDBG(phb, 0, "Init slot...\n"); - - /* - * For PCI/PCI-X, we get the slot info and we also - * check if the PHB has anything connected to it - */ - if (phb->phb_type < phb_type_pcie_v1) { - if (platform.pci_get_slot_info) - platform.pci_get_slot_info(phb, NULL); - rc = phb->ops->presence_detect(phb); - if (rc != OPAL_SHPC_DEV_PRESENT) { - PCIDBG(phb, 0, "Slot empty\n"); + /* Retrieve the link state */ + if (slot && slot->ops.get_link_status) { + rc = slot->ops.get_link_status(slot, &link); + if (rc != OPAL_SUCCESS) { + PCIERR(phb, 0, "Error %lld to query link state\n", rc); return; } } - /* - * Power on the PHB, the PHB should be reset in - * fundamental way while powering on. The reset - * state machine is going to wait for the link - */ - pci_phb_reset(phb); -} - -static void pci_scan_phb(void *data) -{ - struct phb *phb = data; - uint32_t mps = 0xffffffff; - bool has_link = false; - int64_t rc; - - rc = phb->ops->link_state(phb); - if (rc < 0) { - PCIERR(phb, 0, "Failed to query link state, rc=%lld\n", rc); - return; - } - - /* - * We will probe the root port. If the PHB has trained - * link, we will probe the downstream port as well. - */ - if (rc != OPAL_SHPC_LINK_DOWN) - has_link = true; - - if (has_link && phb->phb_type >= phb_type_pcie_v1) - PCIDBG(phb, 0, "Link up at x%lld width\n", rc); - else if (has_link) + /* Output the link info */ + if (link && phb->phb_type >= phb_type_pcie_v1) + PCIDBG(phb, 0, "Link up at x%d width\n", link); + else if (link) PCIDBG(phb, 0, "Link up\n"); else PCIDBG(phb, 0, "Link down\n"); /* Scan root port and downstream ports if applicable */ PCIDBG(phb, 0, "Scanning (upstream%s)...\n", - has_link ? "+downsteam" : " only"); - pci_bus_scan(phb, 0, 0xff, &phb->devices, NULL, has_link); + link ? "+downsteam" : " only"); + pci_bus_scan(phb, 0, 0xff, &phb->devices, NULL, link); /* Configre MPS (Max Payload Size) for PCIe domain */ pci_walk_dev(phb, NULL, pci_get_mps, &mps); @@ -1190,40 +1146,6 @@ void pci_std_swizzle_irq_map(struct dt_node *np, free(map); } -static void pci_add_slot_properties(struct phb *phb, struct pci_slot_info *info, - struct dt_node *np) -{ - char loc_code[LOC_CODE_SIZE]; - size_t base_loc_code_len, slot_label_len; - - if (phb->base_loc_code) { - base_loc_code_len = strlen(phb->base_loc_code); - slot_label_len = strlen(info->label); - if ((base_loc_code_len + slot_label_len +1) < LOC_CODE_SIZE) { - strcpy(loc_code, phb->base_loc_code); - strcat(loc_code, "-"); - strcat(loc_code, info->label); - dt_add_property(np, "ibm,slot-location-code", - loc_code, strlen(loc_code) + 1); - } else - PCIERR(phb, 0, "Loc Code too long - %zu + %zu + 1\n", - base_loc_code_len, slot_label_len); - } else - PCIERR(phb, 0, "Base Loc code not found...\n"); - - /* Add other slot information */ - dt_add_property_cells(np, "ibm,slot-pluggable", info->pluggable); - dt_add_property_cells(np, "ibm,slot-power-ctl", info->power_ctl); - dt_add_property_cells(np, "ibm,slot-wired-lanes", info->wired_lanes); - /*dt_add_property(np, "ibm,slot-bus-clock", &pd->slot_info->bus_clock, sizeof(uint8_t));*/ - dt_add_property_cells(np, "ibm,slot-connector-type", info->connector_type); - dt_add_property_cells(np, "ibm,slot-card-desc", info->card_desc); - dt_add_property_cells(np, "ibm,slot-card-mech", info->card_mech); - dt_add_property_cells(np, "ibm,slot-pwr-led-ctl", info->pwr_led_ctl); - dt_add_property_cells(np, "ibm,slot-attn-led-ctl", info->attn_led_ctl); - dt_add_property_string(np, "ibm,slot-label", info->label); -} - static void pci_add_loc_code(struct dt_node *np) { struct dt_node *p = np->parent; @@ -1363,8 +1285,8 @@ static void pci_add_one_device_node(struct phb *phb, */ /* Add slot properties if needed */ - if (pd->slot_info) - pci_add_slot_properties(phb, pd->slot_info, np); + if (pd->slot) + pci_slot_add_properties(pd->slot, np); /* Make up location code */ pci_add_loc_code(np); @@ -1425,10 +1347,6 @@ void pci_add_device_nodes(struct phb *phb, { struct pci_device *pd; - /* If the PHB has its own slot info, add them */ - if (phb->slot_info) - pci_add_slot_properties(phb, phb->slot_info, NULL); - list_for_each(list, pd, link) { pci_add_one_device_node(phb, pd, parent_node, lstate, swizzle); diff --git a/include/pci.h b/include/pci.h index ec104ad..7fa49e3 100644 --- a/include/pci.h +++ b/include/pci.h @@ -21,24 +21,6 @@ #include #include -/* PCI Slot Entry Information */ -struct pci_slot_info { - uint8_t switch_id; - uint8_t vswitch_id; - uint8_t dev_id; - char label[9]; - bool pluggable; - bool power_ctl; - uint8_t wired_lanes; - uint8_t bus_clock; - uint8_t connector_type; - uint8_t card_desc; - uint8_t card_mech; - uint8_t pwr_led_ctl; - uint8_t attn_led_ctl; - uint8_t slot_index; -}; - /* * While this might not be necessary in the long run, the existing * Linux kernels expect us to provide a device-tree that contains @@ -74,7 +56,6 @@ struct pci_device { struct dt_node *dt_node; struct pci_slot *slot; - struct pci_slot_info *slot_info; struct pci_device *parent; struct list_head children; struct list_node link; @@ -386,7 +367,6 @@ struct phb { /* PCI-X only slot info, for PCI-E this is in the RC bridge */ struct pci_slot *slot; - struct pci_slot_info *slot_info; /* Base location code used to generate the children one */ const char *base_loc_code;