Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp1391624ybl; Mon, 2 Dec 2019 02:50:05 -0800 (PST) X-Google-Smtp-Source: APXvYqz/uEXvnYYljVY8O5IVyOfuj7d/5vHdcPS+lbTOP3cw4rlNwb5X5SlBLw4+raWYzuMpZwJY X-Received: by 2002:a17:906:4899:: with SMTP id v25mr77201266ejq.235.1575283805257; Mon, 02 Dec 2019 02:50:05 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1575283805; cv=none; d=google.com; s=arc-20160816; b=Ro87eDMztlh5hgUjRgnCOenV2Q1DJoaX4kmv9HLhsfGqQqXE9an2KEwVkNkcSSNNfF C5PA9OH1D3MaP6pO7wMlWLzlfDJKdKHwNEB/jVBi8GlFdsDO6gvaajqPJuug1vBxlnFR w28gr4HzTbtTSzSzJq5hv83ZOh2kLQyXvA65SGRWyP/ZRwaM54c5DIozakRjRn31Q4Qn 9uh9j2IQBYzcBkZB0HsApYHZoEBDUdfV9y8QSR9T4Iz+JAjEh9ep4/39XYOR32zvWb2j 9jyZ2yDGTl//NcqJeSF2si5GyxAsIF8BokfPgtcXUHaF16+6uvI9HI8Wde3d0X7QFgPH rN5w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from; bh=SrqiTcDKthQ4S+ZlqPBqPgS1qWpIFLmx9ZVSEE8Wiic=; b=bBVaPb2IS/w8FAHtZ1hvDofsA44RRV7mjxF6COOaik1k4F2WM8yhb8Bh0GqeJf5VOM A2iB3yYaj2CK/aRfvUfYVLauVabfBTusL9aUMshcvjDkoga04JCfin0hVqrlxPZELMmg gayjB4/YDN4kBWmhtVQwNxbXATdQEeV1Q3R7hoALlgx0lGMQ3mHd11k7/ghkKrEkMCus XDO1T7jGFOgAWMCTw1rXR2ffKIR9sMWF9VuxM/WDBXOo514YpuQwyRuOiPq1J2AGVuUn 9v1OFtPxwjqlG6xWa4PWmI5+j0yHluZ/g32WT3YrIQtLa2pblUSnqgiapJ2ap+9JpEwm Kj3w== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=nxp.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id z16si7955502edq.340.2019.12.02.02.49.41; Mon, 02 Dec 2019 02:50:05 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=nxp.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727444AbfLBKps (ORCPT + 99 others); Mon, 2 Dec 2019 05:45:48 -0500 Received: from inva020.nxp.com ([92.121.34.13]:33170 "EHLO inva020.nxp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727332AbfLBKps (ORCPT ); Mon, 2 Dec 2019 05:45:48 -0500 Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id E66DB1A06E0; Mon, 2 Dec 2019 11:45:44 +0100 (CET) Received: from invc005.ap-rdc01.nxp.com (invc005.ap-rdc01.nxp.com [165.114.16.14]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id A58371A01EA; Mon, 2 Dec 2019 11:45:38 +0100 (CET) Received: from localhost.localdomain (mega.ap.freescale.net [10.192.208.232]) by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id CFF3C4024E; Mon, 2 Dec 2019 18:45:30 +0800 (SGT) From: Xiaowei Bao To: robh+dt@kernel.org, frowand.list@gmail.com, minghuan.Lian@nxp.com, mingkai.hu@nxp.com, roy.zang@nxp.com, lorenzo.pieralisi@arm.com, andrew.murray@arm.com, bhelgaas@google.com, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Zhiqiang.Hou@nxp.com Cc: Xiaowei Bao Subject: [PATCH] PCI: layerscape: Add the SRIOV support in host side Date: Mon, 2 Dec 2019 18:45:06 +0800 Message-Id: <20191202104506.27916-1-xiaowei.bao@nxp.com> X-Mailer: git-send-email 2.17.1 X-Virus-Scanned: ClamAV using ClamSMTP Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org GIC get the map relations of devid and stream id from the msi-map property of DTS, our platform add this property in u-boot base on the PCIe device in the bus, but if enable the vf device in kernel, the vf device msi-map will not set, so the vf device can't work, this patch purpose is that manage the stream id and device id map relations dynamically in kernel, and make the new PCIe device work in kernel. Signed-off-by: Xiaowei Bao --- drivers/of/irq.c | 9 +++ drivers/pci/controller/dwc/pci-layerscape.c | 94 +++++++++++++++++++++++++++++ drivers/pci/probe.c | 6 ++ drivers/pci/remove.c | 6 ++ 4 files changed, 115 insertions(+) diff --git a/drivers/of/irq.c b/drivers/of/irq.c index a296eaf..791e609 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -576,6 +576,11 @@ void __init of_irq_init(const struct of_device_id *matches) } } +u32 __weak ls_pcie_streamid_fix(struct device *dev, u32 rid) +{ + return rid; +} + static u32 __of_msi_map_rid(struct device *dev, struct device_node **np, u32 rid_in) { @@ -590,6 +595,10 @@ static u32 __of_msi_map_rid(struct device *dev, struct device_node **np, if (!of_map_rid(parent_dev->of_node, rid_in, "msi-map", "msi-map-mask", np, &rid_out)) break; + + if (rid_out == rid_in) + rid_out = ls_pcie_streamid_fix(parent_dev, rid_in); + return rid_out; } diff --git a/drivers/pci/controller/dwc/pci-layerscape.c b/drivers/pci/controller/dwc/pci-layerscape.c index f24f79a..c1b3675 100644 --- a/drivers/pci/controller/dwc/pci-layerscape.c +++ b/drivers/pci/controller/dwc/pci-layerscape.c @@ -22,6 +22,8 @@ #include "pcie-designware.h" +#define FSL_PEX_STREAM_ID_START 7 +#define FSL_PEX_STREAM_ID_END 22 /* PEX1/2 Misc Ports Status Register */ #define SCFG_PEXMSCPORTSR(pex_idx) (0x94 + (pex_idx) * 4) #define LTSSM_STATE_SHIFT 20 @@ -33,8 +35,16 @@ #define PCIE_ABSERR 0x8d0 /* Bridge Slave Error Response Register */ #define PCIE_ABSERR_SETTING 0x9401 /* Forward error of non-posted request */ +/* LUT registers */ +#define PCIE_LUT_UDR(n) (0x800 + (n) * 8) +#define PCIE_LUT_LDR(n) (0x804 + (n) * 8) +#define PCIE_LUT_ENABLE (1 << 31) +#define PCIE_LUT_ENTRY_COUNT 32 + #define PCIE_IATU_NUM 6 +unsigned long *stream_id_map; + struct ls_pcie_drvdata { u32 lut_offset; u32 ltssm_shift; @@ -49,6 +59,7 @@ struct ls_pcie { struct regmap *scfg; const struct ls_pcie_drvdata *drvdata; int index; + unsigned long *lut_reg_map; }; #define to_ls_pcie(x) dev_get_drvdata((x)->dev) @@ -291,6 +302,77 @@ static int __init ls_add_pcie_port(struct ls_pcie *pcie) return 0; } +u32 ls_pcie_streamid_fix(struct device *dev, u32 rid) +{ + u32 lut_idx, streamid, val; + struct platform_device *pdev = to_platform_device(dev); + struct ls_pcie *pcie = platform_get_drvdata(pdev); + + for (lut_idx = 0; lut_idx < PCIE_LUT_ENTRY_COUNT; lut_idx++) { + val = ioread32(pcie->lut + PCIE_LUT_UDR(lut_idx)) >> 16; + if (val == rid) { + streamid = ioread32(pcie->lut + PCIE_LUT_LDR(lut_idx)) & + (~PCIE_LUT_ENABLE); + break; + } + } + + return streamid; +} + +void ls_pcie_remove_streamid(struct pci_bus *bus, struct pci_dev *pdev) +{ + struct pcie_port *pp = bus->sysdata; + struct dw_pcie *pci = to_dw_pcie_from_pp(pp); + struct ls_pcie *pcie = to_ls_pcie(pci); + u32 lut_idx, streamid, rid, val; + + rid = PCI_DEVID(pdev->bus->number, pdev->devfn); + + for (lut_idx = 0; lut_idx < PCIE_LUT_ENTRY_COUNT; lut_idx++) { + val = ioread32(pcie->lut + PCIE_LUT_UDR(lut_idx)) >> 16; + if (val == rid) { + streamid = ioread32(pcie->lut + PCIE_LUT_LDR(lut_idx)) & + (~PCIE_LUT_ENABLE); + break; + } + } + + if (lut_idx >= PCIE_LUT_ENTRY_COUNT) { + pr_err("Don't find the streamid relate to the rid !\n"); + return; + } + + iowrite32(0, pcie->lut + PCIE_LUT_UDR(lut_idx)); + iowrite32(0, pcie->lut + PCIE_LUT_LDR(lut_idx)); + + clear_bit(streamid, stream_id_map); + clear_bit(lut_idx, pcie->lut_reg_map); +} + +void ls_pcie_add_streamid(struct pci_bus *bus, struct pci_dev *pdev) +{ + u32 free_lut, free_streamid, rid; + struct pcie_port *pp = bus->sysdata; + struct dw_pcie *pci = to_dw_pcie_from_pp(pp); + struct ls_pcie *pcie = to_ls_pcie(pci); + + rid = PCI_DEVID(pdev->bus->number, pdev->devfn); + + free_streamid = find_first_zero_bit(stream_id_map, + FSL_PEX_STREAM_ID_END); + + free_lut = find_first_zero_bit(pcie->lut_reg_map, + PCIE_LUT_ENTRY_COUNT); + + iowrite32(rid << 16, pcie->lut + PCIE_LUT_UDR(free_lut)); + iowrite32(free_streamid | PCIE_LUT_ENABLE, + pcie->lut + PCIE_LUT_LDR(free_lut)); + + set_bit(free_streamid, stream_id_map); + set_bit(free_lut, pcie->lut_reg_map); +} + static int __init ls_pcie_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -298,6 +380,7 @@ static int __init ls_pcie_probe(struct platform_device *pdev) struct ls_pcie *pcie; struct resource *dbi_base; int ret; + u32 id; pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL); if (!pcie) @@ -324,6 +407,17 @@ static int __init ls_pcie_probe(struct platform_device *pdev) if (!ls_pcie_is_bridge(pcie)) return -ENODEV; + stream_id_map = devm_kcalloc(dev, + BITS_TO_LONGS(FSL_PEX_STREAM_ID_END), + sizeof(long), GFP_KERNEL); + + for (id = 0; id < FSL_PEX_STREAM_ID_START; id++) + set_bit(id, stream_id_map); + + pcie->lut_reg_map = devm_kcalloc(dev, + BITS_TO_LONGS(PCIE_LUT_ENTRY_COUNT), + sizeof(long), GFP_KERNEL); + platform_set_drvdata(pdev, pcie); ret = ls_add_pcie_port(pcie); diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 512cb43..d4729b4 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -2380,6 +2380,10 @@ static void pci_set_msi_domain(struct pci_dev *dev) dev_set_msi_domain(&dev->dev, d); } +void __weak ls_pcie_add_streamid(struct pci_bus *bus, struct pci_dev *pdev) +{ +} + void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) { int ret; @@ -2417,6 +2421,8 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) ret = pcibios_add_device(dev); WARN_ON(ret < 0); + ls_pcie_add_streamid(bus, dev); + /* Set up MSI IRQ domain */ pci_set_msi_domain(dev); diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index e9c6b12..af6cc7f 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c @@ -62,11 +62,17 @@ void pci_remove_bus(struct pci_bus *bus) } EXPORT_SYMBOL(pci_remove_bus); +void __weak ls_pcie_remove_streamid(struct pci_bus *bus, struct pci_dev *pdev) +{ +} + static void pci_stop_bus_device(struct pci_dev *dev) { struct pci_bus *bus = dev->subordinate; struct pci_dev *child, *tmp; + ls_pcie_remove_streamid(dev->bus, dev); + /* * Stopping an SR-IOV PF device removes all the associated VFs, * which will update the bus->devices list and confuse the -- 2.9.5