From patchwork Mon Oct 15 09:21:21 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bin Meng X-Patchwork-Id: 984048 X-Patchwork-Delegate: sjg@chromium.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="ZbxKWfyI"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 42YYHJ1KZzz9s5c for ; Mon, 15 Oct 2018 20:36:44 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id DB008C21E53; Mon, 15 Oct 2018 09:27:46 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=-0.0 required=5.0 tests=FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 38498C21F21; Mon, 15 Oct 2018 09:17:21 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 90F9AC21F13; Mon, 15 Oct 2018 09:17:10 +0000 (UTC) Received: from mail-pl1-f195.google.com (mail-pl1-f195.google.com [209.85.214.195]) by lists.denx.de (Postfix) with ESMTPS id 3C058C21EA6 for ; Mon, 15 Oct 2018 09:17:03 +0000 (UTC) Received: by mail-pl1-f195.google.com with SMTP id v5-v6so8984771plz.13 for ; Mon, 15 Oct 2018 02:17:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=n0zdNnNOmLwL6iISpK1XdElYBMAMLo17zbXz0g6uCFM=; b=ZbxKWfyI7tvr/ey/NgFvJbmlMeZE3OMd+KxTmTg7UNhMB6sJDqCN4VCXhNMyu33CQS x+deOYaA09oE+KgNd06K1dGzFqbU6xOffmbDxVmrqpyy8o7IihqrQmsCZKkinMfwHRs8 B1RKkpLzMI27k/FAIvkScUwd38jjXrUHbs1L2ZPsqSTXQdetsqBcte8CxMJFQj9vF44Q 8d5131OthTwlTgQjbTrbdIvg6PIzNxcUrx7QTORN+OGV0d9WhPhMKOI2zncRTF9nYeuw 5nXGjdlKqCGpJs+LQGdZEoEKjdAAPa8TtBu1WsIUc6QEEkEJ1igckuMkg/9kgOGDBZUL FYJA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=n0zdNnNOmLwL6iISpK1XdElYBMAMLo17zbXz0g6uCFM=; b=c/W5WXwo0Cv6LPR9kD+hB1WjaehigXE+mT6C76ifrYt6nsKpqmHrvGtVVDSF7WuAX4 EQad6XjD8RmEaBFsODArrs+akeutaaS6oKSrKqWg2/nukZVs5astjAkSuzSOX2BdzYDC L/SAIc2kTknZ6xXgi+sK2u+b9yLtw3rScIJdNaKVeAYgkEDJsgKtj93kYU4pDUbHkvfY 57X7tlD9p1yxJsyYmzWtqFJ6b5JlYbR5M29XnN1QFO2yk0Y2yOQFH4Pg1ni2OE1f9p4b M1439B7O8qVwkO8DBgHVOY4jVA7cfr74I/f0ImJyuENTnVSQbsC4rrv72NTx8BSEEOHJ qCyQ== X-Gm-Message-State: ABuFfoj/642H9+NYKHVVVpeVeJ8yjI252k2NaaMBKmef0WAYuujBIMzD Ig6Ycm3fSamAUC6BRur646weR4/E X-Google-Smtp-Source: ACcGV61a7vgiockY7kexfHwgeziLu1D2kbjnwrAeHsl4RNvJ08YqSHlAQUwhImqR6FuqQYISPGtsGQ== X-Received: by 2002:a17:902:7486:: with SMTP id h6-v6mr15813680pll.29.1539595021830; Mon, 15 Oct 2018 02:17:01 -0700 (PDT) Received: from ala-d2121-lx1.wrs.com (unknown-156-139.windriver.com. [147.11.156.139]) by smtp.gmail.com with ESMTPSA id a11-v6sm10798256pgw.54.2018.10.15.02.17.00 (version=TLS1_1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 15 Oct 2018 02:17:01 -0700 (PDT) From: Bin Meng To: Simon Glass , U-Boot Mailing List Date: Mon, 15 Oct 2018 02:21:21 -0700 Message-Id: <1539595287-31378-26-git-send-email-bmeng.cn@gmail.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1539595287-31378-1-git-send-email-bmeng.cn@gmail.com> References: <1539595287-31378-1-git-send-email-bmeng.cn@gmail.com> Subject: [U-Boot] [PATCH v3 25/31] dm: pci: Add APIs to find next capability and extended capability X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" This introduces two new APIs dm_pci_find_next_capability() and dm_pci_find_next_ext_capability() to get PCI capability address and PCI express extended capability address for a given PCI device starting from a given offset. Signed-off-by: Bin Meng Reviewed-by: Simon Glass Signed-off-by: Bin Meng Reviewed-by: Simon Glass --- Changes in v3: None Changes in v2: - use an internal function _dm_pci_find_next_capability() for dm_pci_find_capability() and dm_pci_find_next_capability() drivers/pci/pci-uclass.c | 51 ++++++++++++++++++++++++++++++++++-------------- include/pci.h | 48 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 15 deletions(-) diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index eb118f3..0455c72 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -1318,26 +1318,14 @@ void *dm_pci_map_bar(struct udevice *dev, int bar, int flags) return dm_pci_bus_to_virt(dev, pci_bus_addr, flags, 0, MAP_NOCACHE); } -int dm_pci_find_capability(struct udevice *dev, int cap) +static int _dm_pci_find_next_capability(struct udevice *dev, u8 pos, int cap) { - u16 status; - u8 header_type; int ttl = PCI_FIND_CAP_TTL; u8 id; u16 ent; - u8 pos; - - dm_pci_read_config16(dev, PCI_STATUS, &status); - if (!(status & PCI_STATUS_CAP_LIST)) - return 0; - - dm_pci_read_config8(dev, PCI_HEADER_TYPE, &header_type); - if ((header_type & 0x7f) == PCI_HEADER_TYPE_CARDBUS) - pos = PCI_CB_CAPABILITY_LIST; - else - pos = PCI_CAPABILITY_LIST; dm_pci_read_config8(dev, pos, &pos); + while (ttl--) { if (pos < PCI_STD_HEADER_SIZEOF) break; @@ -1355,7 +1343,32 @@ int dm_pci_find_capability(struct udevice *dev, int cap) return 0; } -int dm_pci_find_ext_capability(struct udevice *dev, int cap) +int dm_pci_find_next_capability(struct udevice *dev, u8 start, int cap) +{ + return _dm_pci_find_next_capability(dev, start + PCI_CAP_LIST_NEXT, + cap); +} + +int dm_pci_find_capability(struct udevice *dev, int cap) +{ + u16 status; + u8 header_type; + u8 pos; + + dm_pci_read_config16(dev, PCI_STATUS, &status); + if (!(status & PCI_STATUS_CAP_LIST)) + return 0; + + dm_pci_read_config8(dev, PCI_HEADER_TYPE, &header_type); + if ((header_type & 0x7f) == PCI_HEADER_TYPE_CARDBUS) + pos = PCI_CB_CAPABILITY_LIST; + else + pos = PCI_CAPABILITY_LIST; + + return _dm_pci_find_next_capability(dev, pos, cap); +} + +int dm_pci_find_next_ext_capability(struct udevice *dev, int start, int cap) { u32 header; int ttl; @@ -1364,6 +1377,9 @@ int dm_pci_find_ext_capability(struct udevice *dev, int cap) /* minimum 8 bytes per capability */ ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8; + if (start) + pos = start; + dm_pci_read_config32(dev, pos, &header); /* * If we have no capabilities, this is indicated by cap ID, @@ -1386,6 +1402,11 @@ int dm_pci_find_ext_capability(struct udevice *dev, int cap) return 0; } +int dm_pci_find_ext_capability(struct udevice *dev, int cap) +{ + return dm_pci_find_next_ext_capability(dev, 0, cap); +} + UCLASS_DRIVER(pci) = { .id = UCLASS_PCI, .name = "pci", diff --git a/include/pci.h b/include/pci.h index 938a839..785d7d2 100644 --- a/include/pci.h +++ b/include/pci.h @@ -1313,6 +1313,29 @@ pci_addr_t dm_pci_phys_to_bus(struct udevice *dev, phys_addr_t addr, void *dm_pci_map_bar(struct udevice *dev, int bar, int flags); /** + * dm_pci_find_next_capability() - find a capability starting from an offset + * + * Tell if a device supports a given PCI capability. Returns the + * address of the requested capability structure within the device's + * PCI configuration space or 0 in case the device does not support it. + * + * Possible values for @cap: + * + * %PCI_CAP_ID_MSI Message Signalled Interrupts + * %PCI_CAP_ID_PCIX PCI-X + * %PCI_CAP_ID_EXP PCI Express + * %PCI_CAP_ID_MSIX MSI-X + * + * See PCI_CAP_ID_xxx for the complete capability ID codes. + * + * @dev: PCI device to query + * @start: offset to start from + * @cap: capability code + * @return: capability address or 0 if not supported + */ +int dm_pci_find_next_capability(struct udevice *dev, u8 start, int cap); + +/** * dm_pci_find_capability() - find a capability * * Tell if a device supports a given PCI capability. Returns the @@ -1335,6 +1358,31 @@ void *dm_pci_map_bar(struct udevice *dev, int bar, int flags); int dm_pci_find_capability(struct udevice *dev, int cap); /** + * dm_pci_find_next_ext_capability() - find an extended capability + * starting from an offset + * + * Tell if a device supports a given PCI express extended capability. + * Returns the address of the requested extended capability structure + * within the device's PCI configuration space or 0 in case the device + * does not support it. + * + * Possible values for @cap: + * + * %PCI_EXT_CAP_ID_ERR Advanced Error Reporting + * %PCI_EXT_CAP_ID_VC Virtual Channel + * %PCI_EXT_CAP_ID_DSN Device Serial Number + * %PCI_EXT_CAP_ID_PWR Power Budgeting + * + * See PCI_EXT_CAP_ID_xxx for the complete extended capability ID codes. + * + * @dev: PCI device to query + * @start: offset to start from + * @cap: extended capability code + * @return: extended capability address or 0 if not supported + */ +int dm_pci_find_next_ext_capability(struct udevice *dev, int start, int cap); + +/** * dm_pci_find_ext_capability() - find an extended capability * * Tell if a device supports a given PCI express extended capability.