From patchwork Sun Mar 22 11:12:44 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiaowei Bao X-Patchwork-Id: 1259630 X-Patchwork-Delegate: priyanka.jain@nxp.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=nxp.com Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48lZxc1fnZz9sPR for ; Sun, 22 Mar 2020 22:27:48 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 7B91281851; Sun, 22 Mar 2020 12:27:12 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=nxp.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Received: by phobos.denx.de (Postfix, from userid 109) id EC4648185D; Sun, 22 Mar 2020 12:26:59 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from inva021.nxp.com (inva021.nxp.com [92.121.34.21]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 663BA8181E for ; Sun, 22 Mar 2020 12:26:49 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=nxp.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=xiaowei.bao@nxp.com Received: from inva021.nxp.com (localhost [127.0.0.1]) by inva021.eu-rdc02.nxp.com (Postfix) with ESMTP id AC017200D7C; Sun, 22 Mar 2020 12:26:48 +0100 (CET) Received: from invc005.ap-rdc01.nxp.com (invc005.ap-rdc01.nxp.com [165.114.16.14]) by inva021.eu-rdc02.nxp.com (Postfix) with ESMTP id 17657200D80; Sun, 22 Mar 2020 12:26:44 +0100 (CET) Received: from titan.ap.freescale.net (titan.ap.freescale.net [10.192.208.233]) by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id CFABF402D3; Sun, 22 Mar 2020 19:26:38 +0800 (SGT) From: Xiaowei Bao To: Minghuan.Lian@nxp.com, Zhiqiang.Hou@nxp.com, Mingkai.hu@nxp.com, bmeng.cn@gmail.com, yamada.masahiro@socionext.com, u-boot@lists.denx.de Cc: Xiaowei Bao Subject: [PATCH 1/9] pci: layerscape: Split the EP and RC driver Date: Sun, 22 Mar 2020 19:12:44 +0800 Message-Id: <20200322111252.44001-1-xiaowei.bao@nxp.com> X-Mailer: git-send-email 2.9.5 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.30rc1 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.2 at phobos.denx.de X-Virus-Status: Clean Split the RC and EP driver, and reimplement the EP driver base on the EP framework. Signed-off-by: Xiaowei Bao Reviewed-by: Hou Zhiqiang --- drivers/pci/Makefile | 2 +- drivers/pci/pcie_layerscape.c | 492 +++--------------------------------- drivers/pci/pcie_layerscape.h | 44 +++- drivers/pci/pcie_layerscape_ep.c | 240 ++++++++++++++++++ drivers/pci/pcie_layerscape_fixup.c | 79 +++--- drivers/pci/pcie_layerscape_rc.c | 378 +++++++++++++++++++++++++++ 6 files changed, 734 insertions(+), 501 deletions(-) create mode 100644 drivers/pci/pcie_layerscape_ep.c create mode 100644 drivers/pci/pcie_layerscape_rc.c diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index c051ecc..440b5af 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -33,7 +33,7 @@ obj-$(CONFIG_PCI_TEGRA) += pci_tegra.o obj-$(CONFIG_PCI_AARDVARK) += pci-aardvark.o obj-$(CONFIG_PCIE_DW_MVEBU) += pcie_dw_mvebu.o obj-$(CONFIG_PCIE_FSL) += pcie_fsl.o pcie_fsl_fixup.o -obj-$(CONFIG_PCIE_LAYERSCAPE) += pcie_layerscape.o +obj-$(CONFIG_PCIE_LAYERSCAPE) += pcie_layerscape.o pcie_layerscape_rc.o pcie_layerscape_ep.o obj-$(CONFIG_PCIE_LAYERSCAPE) += pcie_layerscape_fixup.o pcie_layerscape_fixup_common.o obj-$(CONFIG_PCIE_LAYERSCAPE_GEN4) += pcie_layerscape_gen4.o \ pcie_layerscape_gen4_fixup.o \ diff --git a/drivers/pci/pcie_layerscape.c b/drivers/pci/pcie_layerscape.c index 2ab67d1..3ca75c5 100644 --- a/drivers/pci/pcie_layerscape.c +++ b/drivers/pci/pcie_layerscape.c @@ -1,39 +1,32 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * Copyright 2017-2019 NXP + * Copyright 2017-2020 NXP * Copyright 2014-2015 Freescale Semiconductor, Inc. * Layerscape PCIe driver */ #include -#include -#include #include #include #include -#include -#if defined(CONFIG_FSL_LSCH2) || defined(CONFIG_FSL_LSCH3) || \ - defined(CONFIG_ARM) -#include -#endif #include "pcie_layerscape.h" DECLARE_GLOBAL_DATA_PTR; LIST_HEAD(ls_pcie_list); -static unsigned int dbi_readl(struct ls_pcie *pcie, unsigned int offset) +unsigned int dbi_readl(struct ls_pcie *pcie, unsigned int offset) { return in_le32(pcie->dbi + offset); } -static void dbi_writel(struct ls_pcie *pcie, unsigned int value, - unsigned int offset) +void dbi_writel(struct ls_pcie *pcie, unsigned int value, + unsigned int offset) { out_le32(pcie->dbi + offset, value); } -static unsigned int ctrl_readl(struct ls_pcie *pcie, unsigned int offset) +unsigned int ctrl_readl(struct ls_pcie *pcie, unsigned int offset) { if (pcie->big_endian) return in_be32(pcie->ctrl + offset); @@ -41,8 +34,8 @@ static unsigned int ctrl_readl(struct ls_pcie *pcie, unsigned int offset) return in_le32(pcie->ctrl + offset); } -static void ctrl_writel(struct ls_pcie *pcie, unsigned int value, - unsigned int offset) +void ctrl_writel(struct ls_pcie *pcie, unsigned int value, + unsigned int offset) { if (pcie->big_endian) out_be32(pcie->ctrl + offset, value); @@ -50,6 +43,26 @@ static void ctrl_writel(struct ls_pcie *pcie, unsigned int value, out_le32(pcie->ctrl + offset, value); } +void ls_pcie_dbi_ro_wr_en(struct ls_pcie *pcie) +{ + u32 reg, val; + + reg = PCIE_MISC_CONTROL_1_OFF; + val = dbi_readl(pcie, reg); + val |= PCIE_DBI_RO_WR_EN; + dbi_writel(pcie, val, reg); +} + +void ls_pcie_dbi_ro_wr_dis(struct ls_pcie *pcie) +{ + u32 reg, val; + + reg = PCIE_MISC_CONTROL_1_OFF; + val = dbi_readl(pcie, reg); + val &= ~PCIE_DBI_RO_WR_EN; + dbi_writel(pcie, val, reg); +} + static int ls_pcie_ltssm(struct ls_pcie *pcie) { u32 state; @@ -66,7 +79,7 @@ static int ls_pcie_ltssm(struct ls_pcie *pcie) return state; } -static int ls_pcie_link_up(struct ls_pcie *pcie) +int ls_pcie_link_up(struct ls_pcie *pcie) { int ltssm; @@ -77,22 +90,8 @@ static int ls_pcie_link_up(struct ls_pcie *pcie) return 1; } -static void ls_pcie_cfg0_set_busdev(struct ls_pcie *pcie, u32 busdev) -{ - dbi_writel(pcie, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX0, - PCIE_ATU_VIEWPORT); - dbi_writel(pcie, busdev, PCIE_ATU_LOWER_TARGET); -} - -static void ls_pcie_cfg1_set_busdev(struct ls_pcie *pcie, u32 busdev) -{ - dbi_writel(pcie, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1, - PCIE_ATU_VIEWPORT); - dbi_writel(pcie, busdev, PCIE_ATU_LOWER_TARGET); -} - -static void ls_pcie_atu_outbound_set(struct ls_pcie *pcie, int idx, int type, - u64 phys, u64 bus_addr, pci_size_t size) +void ls_pcie_atu_outbound_set(struct ls_pcie *pcie, int idx, int type, + u64 phys, u64 bus_addr, pci_size_t size) { dbi_writel(pcie, PCIE_ATU_REGION_OUTBOUND | idx, PCIE_ATU_VIEWPORT); dbi_writel(pcie, (u32)phys, PCIE_ATU_LOWER_BASE); @@ -105,18 +104,18 @@ static void ls_pcie_atu_outbound_set(struct ls_pcie *pcie, int idx, int type, } /* Use bar match mode and MEM type as default */ -static void ls_pcie_atu_inbound_set(struct ls_pcie *pcie, int idx, - int bar, u64 phys) +void ls_pcie_atu_inbound_set(struct ls_pcie *pcie, int idx, int type, + int bar, u64 phys) { dbi_writel(pcie, PCIE_ATU_REGION_INBOUND | idx, PCIE_ATU_VIEWPORT); dbi_writel(pcie, (u32)phys, PCIE_ATU_LOWER_TARGET); dbi_writel(pcie, phys >> 32, PCIE_ATU_UPPER_TARGET); - dbi_writel(pcie, PCIE_ATU_TYPE_MEM, PCIE_ATU_CR1); + dbi_writel(pcie, type, PCIE_ATU_CR1); dbi_writel(pcie, PCIE_ATU_ENABLE | PCIE_ATU_BAR_MODE_ENABLE | PCIE_ATU_BAR_NUM(bar), PCIE_ATU_CR2); } -static void ls_pcie_dump_atu(struct ls_pcie *pcie) +void ls_pcie_dump_atu(struct ls_pcie *pcie) { int i; @@ -133,431 +132,10 @@ static void ls_pcie_dump_atu(struct ls_pcie *pcie) debug("\tUPPER BUS 0x%08x\n", dbi_readl(pcie, PCIE_ATU_UPPER_TARGET)); debug("\tLIMIT 0x%08x\n", - readl(pcie->dbi + PCIE_ATU_LIMIT)); + dbi_readl(pcie, PCIE_ATU_LIMIT)); debug("\tCR1 0x%08x\n", dbi_readl(pcie, PCIE_ATU_CR1)); debug("\tCR2 0x%08x\n", dbi_readl(pcie, PCIE_ATU_CR2)); } } - -static void ls_pcie_setup_atu(struct ls_pcie *pcie) -{ - struct pci_region *io, *mem, *pref; - unsigned long long offset = 0; - int idx = 0; - uint svr; - - svr = get_svr(); - if (((svr >> SVR_VAR_PER_SHIFT) & SVR_LS102XA_MASK) == SVR_LS102XA) { - offset = LS1021_PCIE_SPACE_OFFSET + - LS1021_PCIE_SPACE_SIZE * pcie->idx; - } - - /* ATU 0 : OUTBOUND : CFG0 */ - ls_pcie_atu_outbound_set(pcie, PCIE_ATU_REGION_INDEX0, - PCIE_ATU_TYPE_CFG0, - pcie->cfg_res.start + offset, - 0, - fdt_resource_size(&pcie->cfg_res) / 2); - /* ATU 1 : OUTBOUND : CFG1 */ - ls_pcie_atu_outbound_set(pcie, PCIE_ATU_REGION_INDEX1, - PCIE_ATU_TYPE_CFG1, - pcie->cfg_res.start + offset + - fdt_resource_size(&pcie->cfg_res) / 2, - 0, - fdt_resource_size(&pcie->cfg_res) / 2); - - pci_get_regions(pcie->bus, &io, &mem, &pref); - idx = PCIE_ATU_REGION_INDEX1 + 1; - - /* Fix the pcie memory map for LS2088A series SoCs */ - svr = (svr >> SVR_VAR_PER_SHIFT) & 0xFFFFFE; - if (svr == SVR_LS2088A || svr == SVR_LS2084A || - svr == SVR_LS2048A || svr == SVR_LS2044A || - svr == SVR_LS2081A || svr == SVR_LS2041A) { - if (io) - io->phys_start = (io->phys_start & - (PCIE_PHYS_SIZE - 1)) + - LS2088A_PCIE1_PHYS_ADDR + - LS2088A_PCIE_PHYS_SIZE * pcie->idx; - if (mem) - mem->phys_start = (mem->phys_start & - (PCIE_PHYS_SIZE - 1)) + - LS2088A_PCIE1_PHYS_ADDR + - LS2088A_PCIE_PHYS_SIZE * pcie->idx; - if (pref) - pref->phys_start = (pref->phys_start & - (PCIE_PHYS_SIZE - 1)) + - LS2088A_PCIE1_PHYS_ADDR + - LS2088A_PCIE_PHYS_SIZE * pcie->idx; - } - - if (io) - /* ATU : OUTBOUND : IO */ - ls_pcie_atu_outbound_set(pcie, idx++, - PCIE_ATU_TYPE_IO, - io->phys_start + offset, - io->bus_start, - io->size); - - if (mem) - /* ATU : OUTBOUND : MEM */ - ls_pcie_atu_outbound_set(pcie, idx++, - PCIE_ATU_TYPE_MEM, - mem->phys_start + offset, - mem->bus_start, - mem->size); - - if (pref) - /* ATU : OUTBOUND : pref */ - ls_pcie_atu_outbound_set(pcie, idx++, - PCIE_ATU_TYPE_MEM, - pref->phys_start + offset, - pref->bus_start, - pref->size); - - ls_pcie_dump_atu(pcie); -} - -/* Return 0 if the address is valid, -errno if not valid */ -static int ls_pcie_addr_valid(struct ls_pcie *pcie, pci_dev_t bdf) -{ - struct udevice *bus = pcie->bus; - - if (pcie->mode == PCI_HEADER_TYPE_NORMAL) - return -ENODEV; - - if (!pcie->enabled) - return -ENXIO; - - if (PCI_BUS(bdf) < bus->seq) - return -EINVAL; - - if ((PCI_BUS(bdf) > bus->seq) && (!ls_pcie_link_up(pcie))) - return -EINVAL; - - if (PCI_BUS(bdf) <= (bus->seq + 1) && (PCI_DEV(bdf) > 0)) - return -EINVAL; - - return 0; -} - -int ls_pcie_conf_address(struct udevice *bus, pci_dev_t bdf, - uint offset, void **paddress) -{ - struct ls_pcie *pcie = dev_get_priv(bus); - u32 busdev; - - if (ls_pcie_addr_valid(pcie, bdf)) - return -EINVAL; - - if (PCI_BUS(bdf) == bus->seq) { - *paddress = pcie->dbi + offset; - return 0; - } - - busdev = PCIE_ATU_BUS(PCI_BUS(bdf) - bus->seq) | - PCIE_ATU_DEV(PCI_DEV(bdf)) | - PCIE_ATU_FUNC(PCI_FUNC(bdf)); - - if (PCI_BUS(bdf) == bus->seq + 1) { - ls_pcie_cfg0_set_busdev(pcie, busdev); - *paddress = pcie->cfg0 + offset; - } else { - ls_pcie_cfg1_set_busdev(pcie, busdev); - *paddress = pcie->cfg1 + offset; - } - return 0; -} - -static int ls_pcie_read_config(struct udevice *bus, pci_dev_t bdf, - uint offset, ulong *valuep, - enum pci_size_t size) -{ - return pci_generic_mmap_read_config(bus, ls_pcie_conf_address, - bdf, offset, valuep, size); -} - -static int ls_pcie_write_config(struct udevice *bus, pci_dev_t bdf, - uint offset, ulong value, - enum pci_size_t size) -{ - return pci_generic_mmap_write_config(bus, ls_pcie_conf_address, - bdf, offset, value, size); -} - -/* Clear multi-function bit */ -static void ls_pcie_clear_multifunction(struct ls_pcie *pcie) -{ - writeb(PCI_HEADER_TYPE_BRIDGE, pcie->dbi + PCI_HEADER_TYPE); -} - -/* Fix class value */ -static void ls_pcie_fix_class(struct ls_pcie *pcie) -{ - writew(PCI_CLASS_BRIDGE_PCI, pcie->dbi + PCI_CLASS_DEVICE); -} - -/* Drop MSG TLP except for Vendor MSG */ -static void ls_pcie_drop_msg_tlp(struct ls_pcie *pcie) -{ - u32 val; - - val = dbi_readl(pcie, PCIE_STRFMR1); - val &= 0xDFFFFFFF; - dbi_writel(pcie, val, PCIE_STRFMR1); -} - -/* Disable all bars in RC mode */ -static void ls_pcie_disable_bars(struct ls_pcie *pcie) -{ - dbi_writel(pcie, 0, PCIE_CS2_OFFSET + PCI_BASE_ADDRESS_0); - dbi_writel(pcie, 0, PCIE_CS2_OFFSET + PCI_BASE_ADDRESS_1); - dbi_writel(pcie, 0xfffffffe, PCIE_CS2_OFFSET + PCI_ROM_ADDRESS1); -} - -static void ls_pcie_setup_ctrl(struct ls_pcie *pcie) -{ - ls_pcie_setup_atu(pcie); - - dbi_writel(pcie, 1, PCIE_DBI_RO_WR_EN); - ls_pcie_fix_class(pcie); - ls_pcie_clear_multifunction(pcie); - ls_pcie_drop_msg_tlp(pcie); - dbi_writel(pcie, 0, PCIE_DBI_RO_WR_EN); - - ls_pcie_disable_bars(pcie); - pcie->stream_id_cur = 0; -} - -static void ls_pcie_ep_setup_atu(struct ls_pcie *pcie) -{ - u64 phys = CONFIG_SYS_PCI_EP_MEMORY_BASE; - - /* ATU 0 : INBOUND : map BAR0 */ - ls_pcie_atu_inbound_set(pcie, 0, 0, phys); - /* ATU 1 : INBOUND : map BAR1 */ - phys += PCIE_BAR1_SIZE; - ls_pcie_atu_inbound_set(pcie, 1, 1, phys); - /* ATU 2 : INBOUND : map BAR2 */ - phys += PCIE_BAR2_SIZE; - ls_pcie_atu_inbound_set(pcie, 2, 2, phys); - /* ATU 3 : INBOUND : map BAR4 */ - phys = CONFIG_SYS_PCI_EP_MEMORY_BASE + PCIE_BAR4_SIZE; - ls_pcie_atu_inbound_set(pcie, 3, 4, phys); - - /* ATU 0 : OUTBOUND : map MEM */ - ls_pcie_atu_outbound_set(pcie, 0, - PCIE_ATU_TYPE_MEM, - pcie->cfg_res.start, - 0, - CONFIG_SYS_PCI_MEMORY_SIZE); -} - -/* BAR0 and BAR1 are 32bit BAR2 and BAR4 are 64bit */ -static void ls_pcie_ep_setup_bar(void *bar_base, int bar, u32 size) -{ - /* The least inbound window is 4KiB */ - if (size < 4 * 1024) - return; - - switch (bar) { - case 0: - writel(size - 1, bar_base + PCI_BASE_ADDRESS_0); - break; - case 1: - writel(size - 1, bar_base + PCI_BASE_ADDRESS_1); - break; - case 2: - writel(size - 1, bar_base + PCI_BASE_ADDRESS_2); - writel(0, bar_base + PCI_BASE_ADDRESS_3); - break; - case 4: - writel(size - 1, bar_base + PCI_BASE_ADDRESS_4); - writel(0, bar_base + PCI_BASE_ADDRESS_5); - break; - default: - break; - } -} - -static void ls_pcie_ep_setup_bars(void *bar_base) -{ - /* BAR0 - 32bit - 4K configuration */ - ls_pcie_ep_setup_bar(bar_base, 0, PCIE_BAR0_SIZE); - /* BAR1 - 32bit - 8K MSIX*/ - ls_pcie_ep_setup_bar(bar_base, 1, PCIE_BAR1_SIZE); - /* BAR2 - 64bit - 4K MEM desciptor */ - ls_pcie_ep_setup_bar(bar_base, 2, PCIE_BAR2_SIZE); - /* BAR4 - 64bit - 1M MEM*/ - ls_pcie_ep_setup_bar(bar_base, 4, PCIE_BAR4_SIZE); -} - -static void ls_pcie_ep_enable_cfg(struct ls_pcie *pcie) -{ - u32 config; - - config = ctrl_readl(pcie, PCIE_PF_CONFIG); - config |= PCIE_CONFIG_READY; - ctrl_writel(pcie, config, PCIE_PF_CONFIG); -} - -static void ls_pcie_setup_ep(struct ls_pcie *pcie) -{ - u32 sriov; - - sriov = readl(pcie->dbi + PCIE_SRIOV); - if (PCI_EXT_CAP_ID(sriov) == PCI_EXT_CAP_ID_SRIOV) { - int pf, vf; - - for (pf = 0; pf < PCIE_PF_NUM; pf++) { - for (vf = 0; vf <= PCIE_VF_NUM; vf++) { - ctrl_writel(pcie, PCIE_LCTRL0_VAL(pf, vf), - PCIE_PF_VF_CTRL); - - ls_pcie_ep_setup_bars(pcie->dbi); - ls_pcie_ep_setup_atu(pcie); - } - } - /* Disable CFG2 */ - ctrl_writel(pcie, 0, PCIE_PF_VF_CTRL); - } else { - ls_pcie_ep_setup_bars(pcie->dbi + PCIE_NO_SRIOV_BAR_BASE); - ls_pcie_ep_setup_atu(pcie); - } - - ls_pcie_ep_enable_cfg(pcie); -} - -static int ls_pcie_probe(struct udevice *dev) -{ - struct ls_pcie *pcie = dev_get_priv(dev); - const void *fdt = gd->fdt_blob; - int node = dev_of_offset(dev); - u16 link_sta; - uint svr; - int ret; - fdt_size_t cfg_size; - - pcie->bus = dev; - - ret = fdt_get_named_resource(fdt, node, "reg", "reg-names", - "dbi", &pcie->dbi_res); - if (ret) { - printf("ls-pcie: resource \"dbi\" not found\n"); - return ret; - } - - pcie->idx = (pcie->dbi_res.start - PCIE_SYS_BASE_ADDR) / PCIE_CCSR_SIZE; - - list_add(&pcie->list, &ls_pcie_list); - - pcie->enabled = is_serdes_configured(PCIE_SRDS_PRTCL(pcie->idx)); - if (!pcie->enabled) { - printf("PCIe%d: %s disabled\n", pcie->idx, dev->name); - return 0; - } - - pcie->dbi = map_physmem(pcie->dbi_res.start, - fdt_resource_size(&pcie->dbi_res), - MAP_NOCACHE); - - ret = fdt_get_named_resource(fdt, node, "reg", "reg-names", - "lut", &pcie->lut_res); - if (!ret) - pcie->lut = map_physmem(pcie->lut_res.start, - fdt_resource_size(&pcie->lut_res), - MAP_NOCACHE); - - ret = fdt_get_named_resource(fdt, node, "reg", "reg-names", - "ctrl", &pcie->ctrl_res); - if (!ret) - pcie->ctrl = map_physmem(pcie->ctrl_res.start, - fdt_resource_size(&pcie->ctrl_res), - MAP_NOCACHE); - if (!pcie->ctrl) - pcie->ctrl = pcie->lut; - - if (!pcie->ctrl) { - printf("%s: NOT find CTRL\n", dev->name); - return -1; - } - - ret = fdt_get_named_resource(fdt, node, "reg", "reg-names", - "config", &pcie->cfg_res); - if (ret) { - printf("%s: resource \"config\" not found\n", dev->name); - return ret; - } - - /* - * Fix the pcie memory map address and PF control registers address - * for LS2088A series SoCs - */ - svr = get_svr(); - svr = (svr >> SVR_VAR_PER_SHIFT) & 0xFFFFFE; - if (svr == SVR_LS2088A || svr == SVR_LS2084A || - svr == SVR_LS2048A || svr == SVR_LS2044A || - svr == SVR_LS2081A || svr == SVR_LS2041A) { - cfg_size = fdt_resource_size(&pcie->cfg_res); - pcie->cfg_res.start = LS2088A_PCIE1_PHYS_ADDR + - LS2088A_PCIE_PHYS_SIZE * pcie->idx; - pcie->cfg_res.end = pcie->cfg_res.start + cfg_size; - pcie->ctrl = pcie->lut + 0x40000; - } - - pcie->cfg0 = map_physmem(pcie->cfg_res.start, - fdt_resource_size(&pcie->cfg_res), - MAP_NOCACHE); - pcie->cfg1 = pcie->cfg0 + fdt_resource_size(&pcie->cfg_res) / 2; - - pcie->big_endian = fdtdec_get_bool(fdt, node, "big-endian"); - - debug("%s dbi:%lx lut:%lx ctrl:0x%lx cfg0:0x%lx, big-endian:%d\n", - dev->name, (unsigned long)pcie->dbi, (unsigned long)pcie->lut, - (unsigned long)pcie->ctrl, (unsigned long)pcie->cfg0, - pcie->big_endian); - - pcie->mode = readb(pcie->dbi + PCI_HEADER_TYPE) & 0x7f; - - if (pcie->mode == PCI_HEADER_TYPE_NORMAL) { - printf("PCIe%u: %s %s", pcie->idx, dev->name, "Endpoint"); - ls_pcie_setup_ep(pcie); - } else { - printf("PCIe%u: %s %s", pcie->idx, dev->name, "Root Complex"); - ls_pcie_setup_ctrl(pcie); - } - - if (!ls_pcie_link_up(pcie)) { - /* Let the user know there's no PCIe link */ - printf(": no link\n"); - return 0; - } - - /* Print the negotiated PCIe link width */ - link_sta = readw(pcie->dbi + PCIE_LINK_STA); - printf(": x%d gen%d\n", (link_sta & PCIE_LINK_WIDTH_MASK) >> 4, - link_sta & PCIE_LINK_SPEED_MASK); - - return 0; -} - -static const struct dm_pci_ops ls_pcie_ops = { - .read_config = ls_pcie_read_config, - .write_config = ls_pcie_write_config, -}; - -static const struct udevice_id ls_pcie_ids[] = { - { .compatible = "fsl,ls-pcie" }, - { } -}; - -U_BOOT_DRIVER(pci_layerscape) = { - .name = "pci_layerscape", - .id = UCLASS_PCI, - .of_match = ls_pcie_ids, - .ops = &ls_pcie_ops, - .probe = ls_pcie_probe, - .priv_auto_alloc_size = sizeof(struct ls_pcie), -}; diff --git a/drivers/pci/pcie_layerscape.h b/drivers/pci/pcie_layerscape.h index 95454bc..217dcda 100644 --- a/drivers/pci/pcie_layerscape.h +++ b/drivers/pci/pcie_layerscape.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0+ */ /* - * Copyright 2017-2019 NXP + * Copyright 2017-2020 NXP * Copyright 2014-2015 Freescale Semiconductor, Inc. * Layerscape PCIe driver */ @@ -60,7 +60,8 @@ /* DBI registers */ #define PCIE_SRIOV 0x178 #define PCIE_STRFMR1 0x71c /* Symbol Timer & Filter Mask Register1 */ -#define PCIE_DBI_RO_WR_EN 0x8bc +#define PCIE_DBI_RO_WR_EN BIT(0) +#define PCIE_MISC_CONTROL_1_OFF 0x8BC #define PCIE_LINK_CAP 0x7c #define PCIE_LINK_SPEED_MASK 0xf @@ -82,7 +83,7 @@ PCIE_LCTRL0_CFG2_ENABLE) #define PCIE_NO_SRIOV_BAR_BASE 0x1000 - +#define FSL_PCIE_EP_MIN_APERTURE 4096 /* 4 Kbytes */ #define PCIE_PF_NUM 2 #define PCIE_VF_NUM 64 @@ -129,25 +130,52 @@ #define LS1021_LTSSM_STATE_SHIFT 20 struct ls_pcie { + void __iomem *dbi; + void __iomem *lut; + void __iomem *ctrl; int idx; + bool big_endian; + int mode; +}; + +struct ls_pcie_rc { + struct ls_pcie *pcie; struct list_head list; struct udevice *bus; struct fdt_resource dbi_res; struct fdt_resource lut_res; struct fdt_resource ctrl_res; struct fdt_resource cfg_res; - void __iomem *dbi; - void __iomem *lut; - void __iomem *ctrl; void __iomem *cfg0; void __iomem *cfg1; - bool big_endian; bool enabled; int next_lut_index; int stream_id_cur; - int mode; +}; + +struct ls_pcie_ep { + struct fdt_resource addr_res; + struct ls_pcie *pcie; + struct udevice *bus; + void __iomem *addr; + u32 num_ib_wins; + u32 num_ob_wins; + u8 max_functions; }; extern struct list_head ls_pcie_list; +unsigned int dbi_readl(struct ls_pcie *pcie, unsigned int offset); +void dbi_writel(struct ls_pcie *pcie, unsigned int value, unsigned int offset); +unsigned int ctrl_readl(struct ls_pcie *pcie, unsigned int offset); +void ctrl_writel(struct ls_pcie *pcie, unsigned int value, unsigned int offset); +void ls_pcie_atu_outbound_set(struct ls_pcie *pcie, int idx, int type, + u64 phys, u64 bus_addr, pci_size_t size); +void ls_pcie_atu_inbound_set(struct ls_pcie *pcie, int idx, int type, + int bar, u64 phys); +void ls_pcie_dump_atu(struct ls_pcie *pcie); +int ls_pcie_link_up(struct ls_pcie *pcie); +void ls_pcie_dbi_ro_wr_en(struct ls_pcie *pcie); +void ls_pcie_dbi_ro_wr_dis(struct ls_pcie *pcie); + #endif /* _PCIE_LAYERSCAPE_H_ */ diff --git a/drivers/pci/pcie_layerscape_ep.c b/drivers/pci/pcie_layerscape_ep.c new file mode 100644 index 0000000..8d0c99a --- /dev/null +++ b/drivers/pci/pcie_layerscape_ep.c @@ -0,0 +1,240 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2020 NXP + * Layerscape PCIe EP driver + */ + +#include +#include +#include +#include +#include +#include +#include +#include "pcie_layerscape.h" + +DECLARE_GLOBAL_DATA_PTR; + +static void ls_pcie_ep_enable_cfg(struct ls_pcie_ep *pcie_ep) +{ + struct ls_pcie *pcie = pcie_ep->pcie; + u32 config; + + config = ctrl_readl(pcie, PCIE_PF_CONFIG); + config |= PCIE_CONFIG_READY; + ctrl_writel(pcie, config, PCIE_PF_CONFIG); +} + +static int ls_ep_set_bar(struct udevice *dev, uint fn, struct pci_bar *ep_bar) +{ + struct ls_pcie_ep *pcie_ep = dev_get_priv(dev); + struct ls_pcie *pcie = pcie_ep->pcie; + dma_addr_t bar_phys = ep_bar->phys_addr; + enum pci_barno bar = ep_bar->barno; + u32 reg = PCI_BASE_ADDRESS_0 + (4 * bar); + int flags = ep_bar->flags; + int type, idx; + u64 size; + + idx = bar; + /* BAR size is 2^(aperture + 11) */ + size = max_t(size_t, ep_bar->size, FSL_PCIE_EP_MIN_APERTURE); + + if (!(flags & PCI_BASE_ADDRESS_SPACE)) + type = PCIE_ATU_TYPE_MEM; + else + type = PCIE_ATU_TYPE_IO; + + ls_pcie_atu_inbound_set(pcie, idx, bar, bar_phys, type); + + dbi_writel(pcie, lower_32_bits(size - 1), reg + PCIE_NO_SRIOV_BAR_BASE); + dbi_writel(pcie, flags, reg); + + if (flags & PCI_BASE_ADDRESS_MEM_TYPE_64) { + dbi_writel(pcie, upper_32_bits(size - 1), + reg + 4 + PCIE_NO_SRIOV_BAR_BASE); + dbi_writel(pcie, 0, reg + 4); + } + + return 0; +} + +static struct pci_ep_ops ls_pcie_ep_ops = { + .set_bar = ls_ep_set_bar, +}; + +static void ls_pcie_ep_setup_atu(struct ls_pcie_ep *pcie_ep) +{ + struct ls_pcie *pcie = pcie_ep->pcie; + u64 phys = CONFIG_SYS_PCI_EP_MEMORY_BASE; + + /* ATU 0 : INBOUND : map BAR0 */ + ls_pcie_atu_inbound_set(pcie, 0, PCIE_ATU_TYPE_MEM, 0, phys); + /* ATU 1 : INBOUND : map BAR1 */ + phys += PCIE_BAR1_SIZE; + ls_pcie_atu_inbound_set(pcie, 1, PCIE_ATU_TYPE_MEM, 1, phys); + /* ATU 2 : INBOUND : map BAR2 */ + phys += PCIE_BAR2_SIZE; + ls_pcie_atu_inbound_set(pcie, 2, PCIE_ATU_TYPE_MEM, 2, phys); + /* ATU 3 : INBOUND : map BAR4 */ + phys = CONFIG_SYS_PCI_EP_MEMORY_BASE + PCIE_BAR4_SIZE; + ls_pcie_atu_inbound_set(pcie, 3, PCIE_ATU_TYPE_MEM, 4, phys); + + /* ATU 0 : OUTBOUND : map MEM */ + ls_pcie_atu_outbound_set(pcie, 0, + PCIE_ATU_TYPE_MEM, + pcie_ep->addr_res.start, + 0, + CONFIG_SYS_PCI_MEMORY_SIZE); +} + +/* BAR0 and BAR1 are 32bit BAR2 and BAR4 are 64bit */ +static void ls_pcie_ep_setup_bar(void *bar_base, int bar, u32 size) +{ + /* The least inbound window is 4KiB */ + if (size < 4 * 1024) + return; + + switch (bar) { + case 0: + writel(size - 1, bar_base + PCI_BASE_ADDRESS_0); + break; + case 1: + writel(size - 1, bar_base + PCI_BASE_ADDRESS_1); + break; + case 2: + writel(size - 1, bar_base + PCI_BASE_ADDRESS_2); + writel(0, bar_base + PCI_BASE_ADDRESS_3); + break; + case 4: + writel(size - 1, bar_base + PCI_BASE_ADDRESS_4); + writel(0, bar_base + PCI_BASE_ADDRESS_5); + break; + default: + break; + } +} + +static void ls_pcie_ep_setup_bars(void *bar_base) +{ + /* BAR0 - 32bit - 4K configuration */ + ls_pcie_ep_setup_bar(bar_base, 0, PCIE_BAR0_SIZE); + /* BAR1 - 32bit - 8K MSIX */ + ls_pcie_ep_setup_bar(bar_base, 1, PCIE_BAR1_SIZE); + /* BAR2 - 64bit - 4K MEM descriptor */ + ls_pcie_ep_setup_bar(bar_base, 2, PCIE_BAR2_SIZE); + /* BAR4 - 64bit - 1M MEM */ + ls_pcie_ep_setup_bar(bar_base, 4, PCIE_BAR4_SIZE); +} + +static void ls_pcie_setup_ep(struct ls_pcie_ep *pcie_ep) +{ + u32 sriov; + struct ls_pcie *pcie = pcie_ep->pcie; + + sriov = readl(pcie->dbi + PCIE_SRIOV); + if (PCI_EXT_CAP_ID(sriov) == PCI_EXT_CAP_ID_SRIOV) { + int pf, vf; + + for (pf = 0; pf < PCIE_PF_NUM; pf++) { + for (vf = 0; vf <= PCIE_VF_NUM; vf++) { + ctrl_writel(pcie, PCIE_LCTRL0_VAL(pf, vf), + PCIE_PF_VF_CTRL); + + ls_pcie_ep_setup_bars(pcie->dbi); + ls_pcie_ep_setup_atu(pcie_ep); + } + } + /* Disable CFG2 */ + ctrl_writel(pcie, 0, PCIE_PF_VF_CTRL); + } else { + ls_pcie_ep_setup_bars(pcie->dbi + PCIE_NO_SRIOV_BAR_BASE); + ls_pcie_ep_setup_atu(pcie_ep); + } + + ls_pcie_ep_enable_cfg(pcie_ep); +} + +static int ls_pcie_ep_probe(struct udevice *dev) +{ + struct ls_pcie_ep *pcie_ep = dev_get_priv(dev); + struct ls_pcie *pcie; + u16 link_sta; + int ret; + + pcie = devm_kmalloc(dev, sizeof(*pcie), GFP_KERNEL); + if (!pcie) + return -ENOMEM; + + pcie_ep->pcie = pcie; + + pcie->dbi = (void __iomem *)devfdt_get_addr_index(dev, 0); + if (!pcie->dbi) + return -ENOMEM; + + pcie->ctrl = (void __iomem *)devfdt_get_addr_index(dev, 1); + if (!pcie->ctrl) + return -ENOMEM; + + ret = fdt_get_named_resource(gd->fdt_blob, dev_of_offset(dev), + "reg", "reg-names", + "addr_space", &pcie_ep->addr_res); + if (ret) { + printf("%s: resource \"addr_space\" not found\n", dev->name); + return ret; + } + + pcie->idx = ((unsigned long)pcie->dbi - PCIE_SYS_BASE_ADDR) / + PCIE_CCSR_SIZE; + + pcie->big_endian = fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev), + "big-endian"); + + pcie->mode = readb(pcie->dbi + PCI_HEADER_TYPE) & 0x7f; + if (pcie->mode != PCI_HEADER_TYPE_NORMAL) + return 0; + + pcie_ep->max_functions = fdtdec_get_int(gd->fdt_blob, + dev_of_offset(dev), + "max-functions", 1); + pcie_ep->num_ib_wins = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), + "num-ib-windows", 8); + pcie_ep->num_ob_wins = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), + "num-ob-windows", 8); + + printf("PCIe%u: %s %s", pcie->idx, dev->name, "Endpoint"); + ls_pcie_setup_ep(pcie_ep); + + if (!ls_pcie_link_up(pcie)) { + /* Let the user know there's no PCIe link */ + printf(": no link\n"); + return 0; + } + + /* Print the negotiated PCIe link width */ + link_sta = readw(pcie->dbi + PCIE_LINK_STA); + printf(": x%d gen%d\n", (link_sta & PCIE_LINK_WIDTH_MASK) >> 4, + link_sta & PCIE_LINK_SPEED_MASK); + + return 0; +} + +static int ls_pcie_ep_remove(struct udevice *dev) +{ + return 0; +} + +const struct udevice_id ls_pcie_ep_ids[] = { + { .compatible = "fsl,ls-pcie-ep" }, + { } +}; + +U_BOOT_DRIVER(pci_layerscape_ep) = { + .name = "pci_layerscape_ep", + .id = UCLASS_PCI_EP, + .of_match = ls_pcie_ep_ids, + .ops = &ls_pcie_ep_ops, + .probe = ls_pcie_ep_probe, + .remove = ls_pcie_ep_remove, + .priv_auto_alloc_size = sizeof(struct ls_pcie_ep), +}; diff --git a/drivers/pci/pcie_layerscape_fixup.c b/drivers/pci/pcie_layerscape_fixup.c index ec6acbb..a981f8c 100644 --- a/drivers/pci/pcie_layerscape_fixup.c +++ b/drivers/pci/pcie_layerscape_fixup.c @@ -23,17 +23,19 @@ /* * Return next available LUT index. */ -static int ls_pcie_next_lut_index(struct ls_pcie *pcie) +static int ls_pcie_next_lut_index(struct ls_pcie_rc *pcie_rc) { - if (pcie->next_lut_index < PCIE_LUT_ENTRY_COUNT) - return pcie->next_lut_index++; + if (pcie_rc->next_lut_index < PCIE_LUT_ENTRY_COUNT) + return pcie_rc->next_lut_index++; else return -ENOSPC; /* LUT is full */ } -static void lut_writel(struct ls_pcie *pcie, unsigned int value, +static void lut_writel(struct ls_pcie_rc *pcie_rc, unsigned int value, unsigned int offset) { + struct ls_pcie *pcie = pcie_rc->pcie; + if (pcie->big_endian) out_be32(pcie->lut + offset, value); else @@ -43,12 +45,12 @@ static void lut_writel(struct ls_pcie *pcie, unsigned int value, /* * Program a single LUT entry */ -static void ls_pcie_lut_set_mapping(struct ls_pcie *pcie, int index, u32 devid, - u32 streamid) +static void ls_pcie_lut_set_mapping(struct ls_pcie_rc *pcie_rc, int index, + u32 devid, u32 streamid) { /* leave mask as all zeroes, want to match all bits */ - lut_writel(pcie, devid << 16, PCIE_LUT_UDR(index)); - lut_writel(pcie, streamid | PCIE_LUT_ENABLE, PCIE_LUT_LDR(index)); + lut_writel(pcie_rc, devid << 16, PCIE_LUT_UDR(index)); + lut_writel(pcie_rc, streamid | PCIE_LUT_ENABLE, PCIE_LUT_LDR(index)); } /* @@ -59,7 +61,8 @@ static void ls_pcie_lut_set_mapping(struct ls_pcie *pcie, int index, u32 devid, * msi-map = <[devid] [phandle-to-msi-ctrl] [stream-id] [count] * [devid] [phandle-to-msi-ctrl] [stream-id] [count]>; */ -static void fdt_pcie_set_msi_map_entry_ls(void *blob, struct ls_pcie *pcie, +static void fdt_pcie_set_msi_map_entry_ls(void *blob, + struct ls_pcie_rc *pcie_rc, u32 devid, u32 streamid) { u32 *prop; @@ -67,10 +70,11 @@ static void fdt_pcie_set_msi_map_entry_ls(void *blob, struct ls_pcie *pcie, int nodeoffset; uint svr; char *compat = NULL; + struct ls_pcie *pcie = pcie_rc->pcie; /* find pci controller node */ nodeoffset = fdt_node_offset_by_compat_reg(blob, "fsl,ls-pcie", - pcie->dbi_res.start); + pcie_rc->dbi_res.start); if (nodeoffset < 0) { #ifdef CONFIG_FSL_PCIE_COMPAT /* Compatible with older version of dts node */ svr = (get_svr() >> SVR_VAR_PER_SHIFT) & 0xFFFFFE; @@ -82,7 +86,7 @@ static void fdt_pcie_set_msi_map_entry_ls(void *blob, struct ls_pcie *pcie, compat = CONFIG_FSL_PCIE_COMPAT; if (compat) nodeoffset = fdt_node_offset_by_compat_reg(blob, - compat, pcie->dbi_res.start); + compat, pcie_rc->dbi_res.start); #endif if (nodeoffset < 0) return; @@ -112,7 +116,8 @@ static void fdt_pcie_set_msi_map_entry_ls(void *blob, struct ls_pcie *pcie, * iommu-map = <[devid] [phandle-to-iommu-ctrl] [stream-id] [count] * [devid] [phandle-to-iommu-ctrl] [stream-id] [count]>; */ -static void fdt_pcie_set_iommu_map_entry_ls(void *blob, struct ls_pcie *pcie, +static void fdt_pcie_set_iommu_map_entry_ls(void *blob, + struct ls_pcie_rc *pcie_rc, u32 devid, u32 streamid) { u32 *prop; @@ -121,10 +126,11 @@ static void fdt_pcie_set_iommu_map_entry_ls(void *blob, struct ls_pcie *pcie, int lenp; uint svr; char *compat = NULL; + struct ls_pcie *pcie = pcie_rc->pcie; /* find pci controller node */ nodeoffset = fdt_node_offset_by_compat_reg(blob, "fsl,ls-pcie", - pcie->dbi_res.start); + pcie_rc->dbi_res.start); if (nodeoffset < 0) { #ifdef CONFIG_FSL_PCIE_COMPAT /* Compatible with older version of dts node */ svr = (get_svr() >> SVR_VAR_PER_SHIFT) & 0xFFFFFE; @@ -137,7 +143,7 @@ static void fdt_pcie_set_iommu_map_entry_ls(void *blob, struct ls_pcie *pcie, if (compat) nodeoffset = fdt_node_offset_by_compat_reg(blob, - compat, pcie->dbi_res.start); + compat, pcie_rc->dbi_res.start); #endif if (nodeoffset < 0) return; @@ -168,7 +174,7 @@ static void fdt_pcie_set_iommu_map_entry_ls(void *blob, struct ls_pcie *pcie, static void fdt_fixup_pcie_ls(void *blob) { struct udevice *dev, *bus; - struct ls_pcie *pcie; + struct ls_pcie_rc *pcie_rc; int streamid; int index; pci_dev_t bdf; @@ -179,17 +185,18 @@ static void fdt_fixup_pcie_ls(void *blob) pci_find_next_device(&dev)) { for (bus = dev; device_is_on_pci_bus(bus);) bus = bus->parent; - pcie = dev_get_priv(bus); + pcie_rc = dev_get_priv(bus); - streamid = pcie_next_streamid(pcie->stream_id_cur, pcie->idx); + streamid = pcie_next_streamid(pcie_rc->stream_id_cur, + pcie_rc->pcie->idx); if (streamid < 0) { debug("ERROR: no stream ids free\n"); continue; } else { - pcie->stream_id_cur++; + pcie_rc->stream_id_cur++; } - index = ls_pcie_next_lut_index(pcie); + index = ls_pcie_next_lut_index(pcie_rc); if (index < 0) { debug("ERROR: no LUT indexes free\n"); continue; @@ -198,27 +205,28 @@ static void fdt_fixup_pcie_ls(void *blob) /* the DT fixup must be relative to the hose first_busno */ bdf = dm_pci_get_bdf(dev) - PCI_BDF(bus->seq, 0, 0); /* map PCI b.d.f to streamID in LUT */ - ls_pcie_lut_set_mapping(pcie, index, bdf >> 8, + ls_pcie_lut_set_mapping(pcie_rc, index, bdf >> 8, streamid); /* update msi-map in device tree */ - fdt_pcie_set_msi_map_entry_ls(blob, pcie, bdf >> 8, + fdt_pcie_set_msi_map_entry_ls(blob, pcie_rc, bdf >> 8, streamid); /* update iommu-map in device tree */ - fdt_pcie_set_iommu_map_entry_ls(blob, pcie, bdf >> 8, + fdt_pcie_set_iommu_map_entry_ls(blob, pcie_rc, bdf >> 8, streamid); } pcie_board_fix_fdt(blob); } #endif -static void ft_pcie_rc_fix(void *blob, struct ls_pcie *pcie) +static void ft_pcie_rc_fix(void *blob, struct ls_pcie_rc *pcie_rc) { int off; uint svr; char *compat = NULL; + struct ls_pcie *pcie = pcie_rc->pcie; off = fdt_node_offset_by_compat_reg(blob, "fsl,ls-pcie", - pcie->dbi_res.start); + pcie_rc->dbi_res.start); if (off < 0) { #ifdef CONFIG_FSL_PCIE_COMPAT /* Compatible with older version of dts node */ svr = (get_svr() >> SVR_VAR_PER_SHIFT) & 0xFFFFFE; @@ -230,46 +238,47 @@ static void ft_pcie_rc_fix(void *blob, struct ls_pcie *pcie) compat = CONFIG_FSL_PCIE_COMPAT; if (compat) off = fdt_node_offset_by_compat_reg(blob, - compat, pcie->dbi_res.start); + compat, pcie_rc->dbi_res.start); #endif if (off < 0) return; } - if (pcie->enabled && pcie->mode == PCI_HEADER_TYPE_BRIDGE) + if (pcie_rc->enabled && pcie->mode == PCI_HEADER_TYPE_BRIDGE) fdt_set_node_status(blob, off, FDT_STATUS_OKAY, 0); else fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0); } -static void ft_pcie_ep_fix(void *blob, struct ls_pcie *pcie) +static void ft_pcie_ep_fix(void *blob, struct ls_pcie_rc *pcie_rc) { int off; + struct ls_pcie *pcie = pcie_rc->pcie; off = fdt_node_offset_by_compat_reg(blob, CONFIG_FSL_PCIE_EP_COMPAT, - pcie->dbi_res.start); + pcie_rc->dbi_res.start); if (off < 0) return; - if (pcie->enabled && pcie->mode == PCI_HEADER_TYPE_NORMAL) + if (pcie_rc->enabled && pcie->mode == PCI_HEADER_TYPE_NORMAL) fdt_set_node_status(blob, off, FDT_STATUS_OKAY, 0); else fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0); } -static void ft_pcie_ls_setup(void *blob, struct ls_pcie *pcie) +static void ft_pcie_ls_setup(void *blob, struct ls_pcie_rc *pcie_rc) { - ft_pcie_ep_fix(blob, pcie); - ft_pcie_rc_fix(blob, pcie); + ft_pcie_ep_fix(blob, pcie_rc); + ft_pcie_rc_fix(blob, pcie_rc); } /* Fixup Kernel DT for PCIe */ void ft_pci_setup_ls(void *blob, bd_t *bd) { - struct ls_pcie *pcie; + struct ls_pcie_rc *pcie_rc; - list_for_each_entry(pcie, &ls_pcie_list, list) - ft_pcie_ls_setup(blob, pcie); + list_for_each_entry(pcie_rc, &ls_pcie_list, list) + ft_pcie_ls_setup(blob, pcie_rc); #if defined(CONFIG_FSL_LSCH3) || defined(CONFIG_FSL_LSCH2) fdt_fixup_pcie_ls(blob); diff --git a/drivers/pci/pcie_layerscape_rc.c b/drivers/pci/pcie_layerscape_rc.c new file mode 100644 index 0000000..927722d --- /dev/null +++ b/drivers/pci/pcie_layerscape_rc.c @@ -0,0 +1,378 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2020 NXP + * Layerscape PCIe driver + */ + +#include +#include +#include +#include +#include +#include +#include +#if defined(CONFIG_FSL_LSCH2) || defined(CONFIG_FSL_LSCH3) || \ + defined(CONFIG_ARM) +#include +#endif +#include "pcie_layerscape.h" + +DECLARE_GLOBAL_DATA_PTR; + +static void ls_pcie_cfg0_set_busdev(struct ls_pcie_rc *pcie_rc, u32 busdev) +{ + struct ls_pcie *pcie = pcie_rc->pcie; + + dbi_writel(pcie, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX0, + PCIE_ATU_VIEWPORT); + dbi_writel(pcie, busdev, PCIE_ATU_LOWER_TARGET); +} + +static void ls_pcie_cfg1_set_busdev(struct ls_pcie_rc *pcie_rc, u32 busdev) +{ + struct ls_pcie *pcie = pcie_rc->pcie; + + dbi_writel(pcie, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1, + PCIE_ATU_VIEWPORT); + dbi_writel(pcie, busdev, PCIE_ATU_LOWER_TARGET); +} + +static void ls_pcie_setup_atu(struct ls_pcie_rc *pcie_rc) +{ + struct pci_region *io, *mem, *pref; + unsigned long long offset = 0; + struct ls_pcie *pcie = pcie_rc->pcie; + int idx = 0; + uint svr; + + svr = get_svr(); + if (((svr >> SVR_VAR_PER_SHIFT) & SVR_LS102XA_MASK) == SVR_LS102XA) { + offset = LS1021_PCIE_SPACE_OFFSET + + LS1021_PCIE_SPACE_SIZE * pcie->idx; + } + + /* ATU 0 : OUTBOUND : CFG0 */ + ls_pcie_atu_outbound_set(pcie, PCIE_ATU_REGION_INDEX0, + PCIE_ATU_TYPE_CFG0, + pcie_rc->cfg_res.start + offset, + 0, + fdt_resource_size(&pcie_rc->cfg_res) / 2); + /* ATU 1 : OUTBOUND : CFG1 */ + ls_pcie_atu_outbound_set(pcie, PCIE_ATU_REGION_INDEX1, + PCIE_ATU_TYPE_CFG1, + pcie_rc->cfg_res.start + offset + + fdt_resource_size(&pcie_rc->cfg_res) / 2, + 0, + fdt_resource_size(&pcie_rc->cfg_res) / 2); + + pci_get_regions(pcie_rc->bus, &io, &mem, &pref); + idx = PCIE_ATU_REGION_INDEX1 + 1; + + /* Fix the pcie memory map for LS2088A series SoCs */ + svr = (svr >> SVR_VAR_PER_SHIFT) & 0xFFFFFE; + if (svr == SVR_LS2088A || svr == SVR_LS2084A || + svr == SVR_LS2048A || svr == SVR_LS2044A || + svr == SVR_LS2081A || svr == SVR_LS2041A) { + if (io) + io->phys_start = (io->phys_start & + (PCIE_PHYS_SIZE - 1)) + + LS2088A_PCIE1_PHYS_ADDR + + LS2088A_PCIE_PHYS_SIZE * pcie->idx; + if (mem) + mem->phys_start = (mem->phys_start & + (PCIE_PHYS_SIZE - 1)) + + LS2088A_PCIE1_PHYS_ADDR + + LS2088A_PCIE_PHYS_SIZE * pcie->idx; + if (pref) + pref->phys_start = (pref->phys_start & + (PCIE_PHYS_SIZE - 1)) + + LS2088A_PCIE1_PHYS_ADDR + + LS2088A_PCIE_PHYS_SIZE * pcie->idx; + } + + if (io) + /* ATU : OUTBOUND : IO */ + ls_pcie_atu_outbound_set(pcie, idx++, + PCIE_ATU_TYPE_IO, + io->phys_start + offset, + io->bus_start, + io->size); + + if (mem) + /* ATU : OUTBOUND : MEM */ + ls_pcie_atu_outbound_set(pcie, idx++, + PCIE_ATU_TYPE_MEM, + mem->phys_start + offset, + mem->bus_start, + mem->size); + + if (pref) + /* ATU : OUTBOUND : pref */ + ls_pcie_atu_outbound_set(pcie, idx++, + PCIE_ATU_TYPE_MEM, + pref->phys_start + offset, + pref->bus_start, + pref->size); + + ls_pcie_dump_atu(pcie); +} + +/* Return 0 if the address is valid, -errno if not valid */ +static int ls_pcie_addr_valid(struct ls_pcie_rc *pcie_rc, pci_dev_t bdf) +{ + struct udevice *bus = pcie_rc->bus; + struct ls_pcie *pcie = pcie_rc->pcie; + + if (pcie->mode == PCI_HEADER_TYPE_NORMAL) + return -ENODEV; + + if (!pcie_rc->enabled) + return -ENXIO; + + if (PCI_BUS(bdf) < bus->seq) + return -EINVAL; + + if ((PCI_BUS(bdf) > bus->seq) && (!ls_pcie_link_up(pcie))) + return -EINVAL; + + if (PCI_BUS(bdf) <= (bus->seq + 1) && (PCI_DEV(bdf) > 0)) + return -EINVAL; + + return 0; +} + +int ls_pcie_conf_address(struct udevice *bus, pci_dev_t bdf, + uint offset, void **paddress) +{ + struct ls_pcie_rc *pcie_rc = dev_get_priv(bus); + struct ls_pcie *pcie = pcie_rc->pcie; + u32 busdev; + + if (ls_pcie_addr_valid(pcie_rc, bdf)) + return -EINVAL; + + if (PCI_BUS(bdf) == bus->seq) { + *paddress = pcie->dbi + offset; + return 0; + } + + busdev = PCIE_ATU_BUS(PCI_BUS(bdf) - bus->seq) | + PCIE_ATU_DEV(PCI_DEV(bdf)) | + PCIE_ATU_FUNC(PCI_FUNC(bdf)); + + if (PCI_BUS(bdf) == bus->seq + 1) { + ls_pcie_cfg0_set_busdev(pcie_rc, busdev); + *paddress = pcie_rc->cfg0 + offset; + } else { + ls_pcie_cfg1_set_busdev(pcie_rc, busdev); + *paddress = pcie_rc->cfg1 + offset; + } + return 0; +} + +static int ls_pcie_read_config(struct udevice *bus, pci_dev_t bdf, + uint offset, ulong *valuep, + enum pci_size_t size) +{ + return pci_generic_mmap_read_config(bus, ls_pcie_conf_address, + bdf, offset, valuep, size); +} + +static int ls_pcie_write_config(struct udevice *bus, pci_dev_t bdf, + uint offset, ulong value, + enum pci_size_t size) +{ + return pci_generic_mmap_write_config(bus, ls_pcie_conf_address, + bdf, offset, value, size); +} + +/* Clear multi-function bit */ +static void ls_pcie_clear_multifunction(struct ls_pcie_rc *pcie_rc) +{ + struct ls_pcie *pcie = pcie_rc->pcie; + + writeb(PCI_HEADER_TYPE_BRIDGE, pcie->dbi + PCI_HEADER_TYPE); +} + +/* Fix class value */ +static void ls_pcie_fix_class(struct ls_pcie_rc *pcie_rc) +{ + struct ls_pcie *pcie = pcie_rc->pcie; + + writew(PCI_CLASS_BRIDGE_PCI, pcie->dbi + PCI_CLASS_DEVICE); +} + +/* Drop MSG TLP except for Vendor MSG */ +static void ls_pcie_drop_msg_tlp(struct ls_pcie_rc *pcie_rc) +{ + struct ls_pcie *pcie = pcie_rc->pcie; + u32 val; + + val = dbi_readl(pcie, PCIE_STRFMR1); + val &= 0xDFFFFFFF; + dbi_writel(pcie, val, PCIE_STRFMR1); +} + +/* Disable all bars in RC mode */ +static void ls_pcie_disable_bars(struct ls_pcie_rc *pcie_rc) +{ + struct ls_pcie *pcie = pcie_rc->pcie; + + dbi_writel(pcie, 0, PCIE_CS2_OFFSET + PCI_BASE_ADDRESS_0); + dbi_writel(pcie, 0, PCIE_CS2_OFFSET + PCI_BASE_ADDRESS_1); + dbi_writel(pcie, 0xfffffffe, PCIE_CS2_OFFSET + PCI_ROM_ADDRESS1); +} + +static void ls_pcie_setup_ctrl(struct ls_pcie_rc *pcie_rc) +{ + struct ls_pcie *pcie = pcie_rc->pcie; + + ls_pcie_setup_atu(pcie_rc); + + ls_pcie_dbi_ro_wr_en(pcie); + ls_pcie_fix_class(pcie_rc); + ls_pcie_clear_multifunction(pcie_rc); + ls_pcie_drop_msg_tlp(pcie_rc); + ls_pcie_dbi_ro_wr_dis(pcie); + + ls_pcie_disable_bars(pcie_rc); + pcie_rc->stream_id_cur = 0; +} + +static int ls_pcie_probe(struct udevice *dev) +{ + struct ls_pcie_rc *pcie_rc = dev_get_priv(dev); + const void *fdt = gd->fdt_blob; + int node = dev_of_offset(dev); + struct ls_pcie *pcie; + u16 link_sta; + uint svr; + int ret; + fdt_size_t cfg_size; + + pcie_rc->bus = dev; + + pcie = devm_kmalloc(dev, sizeof(*pcie), GFP_KERNEL); + if (!pcie) + return -ENOMEM; + + pcie_rc->pcie = pcie; + + ret = fdt_get_named_resource(fdt, node, "reg", "reg-names", + "dbi", &pcie_rc->dbi_res); + if (ret) { + printf("ls-pcie: resource \"dbi\" not found\n"); + return ret; + } + + pcie->idx = (pcie_rc->dbi_res.start - PCIE_SYS_BASE_ADDR) / + PCIE_CCSR_SIZE; + + list_add(&pcie_rc->list, &ls_pcie_list); + + pcie_rc->enabled = is_serdes_configured(PCIE_SRDS_PRTCL(pcie->idx)); + if (!pcie_rc->enabled) { + printf("PCIe%d: %s disabled\n", pcie->idx, dev->name); + return 0; + } + + pcie->dbi = map_physmem(pcie_rc->dbi_res.start, + fdt_resource_size(&pcie_rc->dbi_res), + MAP_NOCACHE); + + pcie->mode = readb(pcie->dbi + PCI_HEADER_TYPE) & 0x7f; + if (pcie->mode == PCI_HEADER_TYPE_NORMAL) + return 0; + + ret = fdt_get_named_resource(fdt, node, "reg", "reg-names", + "lut", &pcie_rc->lut_res); + if (!ret) + pcie->lut = map_physmem(pcie_rc->lut_res.start, + fdt_resource_size(&pcie_rc->lut_res), + MAP_NOCACHE); + + ret = fdt_get_named_resource(fdt, node, "reg", "reg-names", + "ctrl", &pcie_rc->ctrl_res); + if (!ret) + pcie->ctrl = map_physmem(pcie_rc->ctrl_res.start, + fdt_resource_size(&pcie_rc->ctrl_res), + MAP_NOCACHE); + if (!pcie->ctrl) + pcie->ctrl = pcie->lut; + + if (!pcie->ctrl) { + printf("%s: NOT find CTRL\n", dev->name); + return -1; + } + + ret = fdt_get_named_resource(fdt, node, "reg", "reg-names", + "config", &pcie_rc->cfg_res); + if (ret) { + printf("%s: resource \"config\" not found\n", dev->name); + return ret; + } + + /* + * Fix the pcie memory map address and PF control registers address + * for LS2088A series SoCs + */ + svr = get_svr(); + svr = (svr >> SVR_VAR_PER_SHIFT) & 0xFFFFFE; + if (svr == SVR_LS2088A || svr == SVR_LS2084A || + svr == SVR_LS2048A || svr == SVR_LS2044A || + svr == SVR_LS2081A || svr == SVR_LS2041A) { + cfg_size = fdt_resource_size(&pcie_rc->cfg_res); + pcie_rc->cfg_res.start = LS2088A_PCIE1_PHYS_ADDR + + LS2088A_PCIE_PHYS_SIZE * pcie->idx; + pcie_rc->cfg_res.end = pcie_rc->cfg_res.start + cfg_size; + pcie->ctrl = pcie->lut + 0x40000; + } + + pcie_rc->cfg0 = map_physmem(pcie_rc->cfg_res.start, + fdt_resource_size(&pcie_rc->cfg_res), + MAP_NOCACHE); + pcie_rc->cfg1 = pcie_rc->cfg0 + + fdt_resource_size(&pcie_rc->cfg_res) / 2; + + pcie->big_endian = fdtdec_get_bool(fdt, node, "big-endian"); + + debug("%s dbi:%lx lut:%lx ctrl:0x%lx cfg0:0x%lx, big-endian:%d\n", + dev->name, (unsigned long)pcie->dbi, (unsigned long)pcie->lut, + (unsigned long)pcie->ctrl, (unsigned long)pcie_rc->cfg0, + pcie->big_endian); + + printf("PCIe%u: %s %s", pcie->idx, dev->name, "Root Complex"); + ls_pcie_setup_ctrl(pcie_rc); + + if (!ls_pcie_link_up(pcie)) { + /* Let the user know there's no PCIe link */ + printf(": no link\n"); + return 0; + } + + /* Print the negotiated PCIe link width */ + link_sta = readw(pcie->dbi + PCIE_LINK_STA); + printf(": x%d gen%d\n", (link_sta & PCIE_LINK_WIDTH_MASK) >> 4, + link_sta & PCIE_LINK_SPEED_MASK); + + return 0; +} + +static const struct dm_pci_ops ls_pcie_ops = { + .read_config = ls_pcie_read_config, + .write_config = ls_pcie_write_config, +}; + +static const struct udevice_id ls_pcie_ids[] = { + { .compatible = "fsl,ls-pcie" }, + { } +}; + +U_BOOT_DRIVER(pci_layerscape) = { + .name = "pci_layerscape", + .id = UCLASS_PCI, + .of_match = ls_pcie_ids, + .ops = &ls_pcie_ops, + .probe = ls_pcie_probe, + .priv_auto_alloc_size = sizeof(struct ls_pcie_rc), +}; From patchwork Sun Mar 22 11:12:45 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiaowei Bao X-Patchwork-Id: 1259628 X-Patchwork-Delegate: priyanka.jain@nxp.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=nxp.com Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48lZx03KvRz9sPR for ; Sun, 22 Mar 2020 22:27:16 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id C877C8185A; Sun, 22 Mar 2020 12:27:01 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=nxp.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Received: by phobos.denx.de (Postfix, from userid 109) id 62AE28186F; Sun, 22 Mar 2020 12:26:58 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from inva020.nxp.com (inva020.nxp.com [92.121.34.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 0D3BD8183D for ; Sun, 22 Mar 2020 12:26:54 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=nxp.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=xiaowei.bao@nxp.com Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id C78911A0EA2; Sun, 22 Mar 2020 12:26:48 +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 E0AC01A0E9A; Sun, 22 Mar 2020 12:26:44 +0100 (CET) Received: from titan.ap.freescale.net (titan.ap.freescale.net [10.192.208.233]) by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id C9B31402EC; Sun, 22 Mar 2020 19:26:39 +0800 (SGT) From: Xiaowei Bao To: Minghuan.Lian@nxp.com, Zhiqiang.Hou@nxp.com, Mingkai.hu@nxp.com, bmeng.cn@gmail.com, yamada.masahiro@socionext.com, u-boot@lists.denx.de Cc: Xiaowei Bao Subject: [PATCH 2/9] pci_ep: Add the init function Date: Sun, 22 Mar 2020 19:12:45 +0800 Message-Id: <20200322111252.44001-2-xiaowei.bao@nxp.com> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20200322111252.44001-1-xiaowei.bao@nxp.com> References: <20200322111252.44001-1-xiaowei.bao@nxp.com> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.30rc1 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.2 at phobos.denx.de X-Virus-Status: Clean Some EP deivces need to initialize before RC scan it, e.g. NXP layerscape platform, so add the init function in pci_ep uclass. Signed-off-by: Xiaowei Bao Reviewed-by: Hou Zhiqiang --- common/board_r.c | 12 ++++++++++++ drivers/pci_endpoint/pci_ep-uclass.c | 11 +++++++++++ include/init.h | 1 + 3 files changed, 24 insertions(+) diff --git a/common/board_r.c b/common/board_r.c index 0bbeaa7..856b47f 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -229,6 +229,15 @@ static int initr_unlock_ram_in_cache(void) } #endif +#ifdef CONFIG_PCI_ENDPOINT +static int initr_pci_ep(void) +{ + pci_ep_init(); + + return 0; +} +#endif + #ifdef CONFIG_PCI static int initr_pci(void) { @@ -839,6 +848,9 @@ static init_fnc_t init_sequence_r[] = { #ifdef CONFIG_BITBANGMII initr_bbmii, #endif +#ifdef CONFIG_PCI_ENDPOINT + initr_pci_ep, +#endif #ifdef CONFIG_CMD_NET INIT_FUNC_WATCHDOG_RESET initr_net, diff --git a/drivers/pci_endpoint/pci_ep-uclass.c b/drivers/pci_endpoint/pci_ep-uclass.c index 9f53a9a..38a5f08 100644 --- a/drivers/pci_endpoint/pci_ep-uclass.c +++ b/drivers/pci_endpoint/pci_ep-uclass.c @@ -209,3 +209,14 @@ UCLASS_DRIVER(pci_ep) = { .name = "pci_ep", .flags = DM_UC_FLAG_SEQ_ALIAS, }; + +void pci_ep_init(void) +{ + struct udevice *dev; + + for (uclass_first_device_check(UCLASS_PCI_EP, &dev); + dev; + uclass_next_device_check(&dev)) { + ; + } +} diff --git a/include/init.h b/include/init.h index 2a33a3f..fbc26a8 100644 --- a/include/init.h +++ b/include/init.h @@ -202,6 +202,7 @@ int set_cpu_clk_info(void); int update_flash_size(int flash_size); int arch_early_init_r(void); void pci_init(void); +void pci_ep_init(void); int misc_init_r(void); #if defined(CONFIG_VID) int init_func_vid(void); From patchwork Sun Mar 22 11:12:46 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiaowei Bao X-Patchwork-Id: 1259627 X-Patchwork-Delegate: priyanka.jain@nxp.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=nxp.com Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48lZwl32Flz9sRf for ; Sun, 22 Mar 2020 22:27:03 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id D423881850; Sun, 22 Mar 2020 12:26:56 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=nxp.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Received: by phobos.denx.de (Postfix, from userid 109) id 0AEB48184C; Sun, 22 Mar 2020 12:26:55 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from inva020.nxp.com (inva020.nxp.com [92.121.34.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id C18B781829 for ; Sun, 22 Mar 2020 12:26:50 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=nxp.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=xiaowei.bao@nxp.com Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 9C54F1A0E9A; Sun, 22 Mar 2020 12:26:49 +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 B4DA61A0E9C; Sun, 22 Mar 2020 12:26:45 +0100 (CET) Received: from titan.ap.freescale.net (titan.ap.freescale.net [10.192.208.233]) by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id 9DE5F40305; Sun, 22 Mar 2020 19:26:40 +0800 (SGT) From: Xiaowei Bao To: Minghuan.Lian@nxp.com, Zhiqiang.Hou@nxp.com, Mingkai.hu@nxp.com, bmeng.cn@gmail.com, yamada.masahiro@socionext.com, u-boot@lists.denx.de Cc: Xiaowei Bao Subject: [PATCH 3/9] armv8: dts: ls1046a: Add the PCIe EP node Date: Sun, 22 Mar 2020 19:12:46 +0800 Message-Id: <20200322111252.44001-3-xiaowei.bao@nxp.com> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20200322111252.44001-1-xiaowei.bao@nxp.com> References: <20200322111252.44001-1-xiaowei.bao@nxp.com> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.30rc1 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.2 at phobos.denx.de X-Virus-Status: Clean Add the PCIe EP node for ls1046a. Signed-off-by: Xiaowei Bao Reviewed-by: Hou Zhiqiang --- arch/arm/dts/fsl-ls1046a.dtsi | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/arch/arm/dts/fsl-ls1046a.dtsi b/arch/arm/dts/fsl-ls1046a.dtsi index fdf93fd..e4b4a8e 100644 --- a/arch/arm/dts/fsl-ls1046a.dtsi +++ b/arch/arm/dts/fsl-ls1046a.dtsi @@ -259,6 +259,17 @@ 0x82000000 0x0 0x40000000 0x40 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ }; + pcie_ep@3400000 { + compatible = "fsl,ls-pcie-ep"; + reg = <0x00 0x03400000 0x0 0x80000 + 0x00 0x034c0000 0x0 0x40000 + 0x40 0x00000000 0x8 0x00000000>; + reg-names = "regs", "ctrl", "addr_space"; + num-ib-windows = <6>; + num-ob-windows = <8>; + big-endian; + }; + pcie@3500000 { compatible = "fsl,ls-pcie", "snps,dw-pcie"; reg = <0x00 0x03500000 0x0 0x80000 /* dbi registers */ @@ -276,6 +287,17 @@ 0x82000000 0x0 0x40000000 0x48 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ }; + pcie_ep@3500000 { + compatible = "fsl,ls-pcie-ep"; + reg = <0x00 0x03500000 0x0 0x80000 + 0x00 0x035c0000 0x0 0x40000 + 0x48 0x00000000 0x8 0x00000000>; + reg-names = "regs", "ctrl", "addr_space"; + num-ib-windows = <6>; + num-ob-windows = <8>; + big-endian; + }; + pcie@3600000 { compatible = "fsl,ls-pcie", "snps,dw-pcie"; reg = <0x00 0x03600000 0x0 0x80000 /* dbi registers */ @@ -292,6 +314,17 @@ 0x82000000 0x0 0x40000000 0x50 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ }; + pcie_ep@3600000 { + compatible = "fsl,ls-pcie-ep"; + reg = <0x00 0x03600000 0x0 0x80000 + 0x00 0x036c0000 0x0 0x40000 + 0x50 0x00000000 0x8 0x00000000>; + reg-names = "regs", "ctrl", "addr_space"; + num-ib-windows = <6>; + num-ob-windows = <8>; + big-endian; + }; + sata: sata@3200000 { compatible = "fsl,ls1046a-ahci"; reg = <0x0 0x3200000 0x0 0x10000 /* ccsr sata base */ From patchwork Sun Mar 22 11:12:47 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiaowei Bao X-Patchwork-Id: 1259629 X-Patchwork-Delegate: priyanka.jain@nxp.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=nxp.com Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48lZxC6FBXz9sRf for ; Sun, 22 Mar 2020 22:27:27 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 449A781856; Sun, 22 Mar 2020 12:27:05 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=nxp.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Received: by phobos.denx.de (Postfix, from userid 109) id DB8DC81831; Sun, 22 Mar 2020 12:26:58 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from inva020.nxp.com (inva020.nxp.com [92.121.34.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id E36E381831 for ; Sun, 22 Mar 2020 12:26:52 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=nxp.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=xiaowei.bao@nxp.com Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 5FBBD1A0E9C; Sun, 22 Mar 2020 12:26:51 +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 320F61A0E9E; Sun, 22 Mar 2020 12:26:47 +0100 (CET) Received: from titan.ap.freescale.net (titan.ap.freescale.net [10.192.208.233]) by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id 724DD4030B; Sun, 22 Mar 2020 19:26:41 +0800 (SGT) From: Xiaowei Bao To: Minghuan.Lian@nxp.com, Zhiqiang.Hou@nxp.com, Mingkai.hu@nxp.com, bmeng.cn@gmail.com, yamada.masahiro@socionext.com, u-boot@lists.denx.de Cc: Xiaowei Bao Subject: [PATCH 4/9] PCI_EP: layerscape: Add the multiple function supprot Date: Sun, 22 Mar 2020 19:12:47 +0800 Message-Id: <20200322111252.44001-4-xiaowei.bao@nxp.com> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20200322111252.44001-1-xiaowei.bao@nxp.com> References: <20200322111252.44001-1-xiaowei.bao@nxp.com> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.30rc1 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.2 at phobos.denx.de X-Virus-Status: Clean Add the multiple function support for Layerscape platform, some PEXs of Layerscaple platform have more than one PF. Signed-off-by: Xiaowei Bao Reviewed-by: Hou Zhiqiang --- drivers/pci/pcie_layerscape.c | 6 +- drivers/pci/pcie_layerscape.h | 21 +++++-- drivers/pci/pcie_layerscape_ep.c | 119 ++++++++++++++++++++++++++------------- 3 files changed, 98 insertions(+), 48 deletions(-) diff --git a/drivers/pci/pcie_layerscape.c b/drivers/pci/pcie_layerscape.c index 3ca75c5..88a0e8a 100644 --- a/drivers/pci/pcie_layerscape.c +++ b/drivers/pci/pcie_layerscape.c @@ -104,13 +104,13 @@ void ls_pcie_atu_outbound_set(struct ls_pcie *pcie, int idx, int type, } /* Use bar match mode and MEM type as default */ -void ls_pcie_atu_inbound_set(struct ls_pcie *pcie, int idx, int type, - int bar, u64 phys) +void ls_pcie_atu_inbound_set(struct ls_pcie *pcie, u32 pf, int type, + int idx, int bar, u64 phys) { dbi_writel(pcie, PCIE_ATU_REGION_INBOUND | idx, PCIE_ATU_VIEWPORT); dbi_writel(pcie, (u32)phys, PCIE_ATU_LOWER_TARGET); dbi_writel(pcie, phys >> 32, PCIE_ATU_UPPER_TARGET); - dbi_writel(pcie, type, PCIE_ATU_CR1); + dbi_writel(pcie, type | PCIE_ATU_FUNC_NUM(pf), PCIE_ATU_CR1); dbi_writel(pcie, PCIE_ATU_ENABLE | PCIE_ATU_BAR_MODE_ENABLE | PCIE_ATU_BAR_NUM(bar), PCIE_ATU_CR2); } diff --git a/drivers/pci/pcie_layerscape.h b/drivers/pci/pcie_layerscape.h index 217dcda..dabfff3 100644 --- a/drivers/pci/pcie_layerscape.h +++ b/drivers/pci/pcie_layerscape.h @@ -9,6 +9,7 @@ #define _PCIE_LAYERSCAPE_H_ #include #include +#include #ifndef CONFIG_SYS_PCI_MEMORY_BUS #define CONFIG_SYS_PCI_MEMORY_BUS CONFIG_SYS_SDRAM_BASE @@ -44,6 +45,7 @@ #define PCIE_ATU_TYPE_IO (0x2 << 0) #define PCIE_ATU_TYPE_CFG0 (0x4 << 0) #define PCIE_ATU_TYPE_CFG1 (0x5 << 0) +#define PCIE_ATU_FUNC_NUM(pf) ((pf) << 20) #define PCIE_ATU_CR2 0x908 #define PCIE_ATU_ENABLE (0x1 << 31) #define PCIE_ATU_BAR_MODE_ENABLE (0x1 << 30) @@ -86,11 +88,16 @@ #define FSL_PCIE_EP_MIN_APERTURE 4096 /* 4 Kbytes */ #define PCIE_PF_NUM 2 #define PCIE_VF_NUM 64 +#define BAR_NUM 4 -#define PCIE_BAR0_SIZE (4 * 1024) /* 4K */ -#define PCIE_BAR1_SIZE (8 * 1024) /* 8K for MSIX */ -#define PCIE_BAR2_SIZE (4 * 1024) /* 4K */ -#define PCIE_BAR4_SIZE (1 * 1024 * 1024) /* 1M */ +#define PCIE_BAR0_SIZE SZ_4K +#define PCIE_BAR1_SIZE SZ_8K +#define PCIE_BAR2_SIZE SZ_4K +#define PCIE_BAR4_SIZE SZ_1M + +#define PCIE_SRIOV_VFBAR0 0x19C + +#define PCIE_MASK_OFFSET(flag, pf) ((flag) ? 0 : (0x1000 + 0x20000 * (pf))) /* LUT registers */ #define PCIE_LUT_UDR(n) (0x800 + (n) * 8) @@ -158,6 +165,8 @@ struct ls_pcie_ep { struct ls_pcie *pcie; struct udevice *bus; void __iomem *addr; + u32 cfg2_flag; + u32 sriov_flag; u32 num_ib_wins; u32 num_ob_wins; u8 max_functions; @@ -171,8 +180,8 @@ unsigned int ctrl_readl(struct ls_pcie *pcie, unsigned int offset); void ctrl_writel(struct ls_pcie *pcie, unsigned int value, unsigned int offset); void ls_pcie_atu_outbound_set(struct ls_pcie *pcie, int idx, int type, u64 phys, u64 bus_addr, pci_size_t size); -void ls_pcie_atu_inbound_set(struct ls_pcie *pcie, int idx, int type, - int bar, u64 phys); +void ls_pcie_atu_inbound_set(struct ls_pcie *pcie, u32 pf, int type, + int idx, int bar, u64 phys); void ls_pcie_dump_atu(struct ls_pcie *pcie); int ls_pcie_link_up(struct ls_pcie *pcie); void ls_pcie_dbi_ro_wr_en(struct ls_pcie *pcie); diff --git a/drivers/pci/pcie_layerscape_ep.c b/drivers/pci/pcie_layerscape_ep.c index 8d0c99a..bec374b 100644 --- a/drivers/pci/pcie_layerscape_ep.c +++ b/drivers/pci/pcie_layerscape_ep.c @@ -45,7 +45,7 @@ static int ls_ep_set_bar(struct udevice *dev, uint fn, struct pci_bar *ep_bar) else type = PCIE_ATU_TYPE_IO; - ls_pcie_atu_inbound_set(pcie, idx, bar, bar_phys, type); + ls_pcie_atu_inbound_set(pcie, fn, type, idx, bar, bar_phys); dbi_writel(pcie, lower_32_bits(size - 1), reg + PCIE_NO_SRIOV_BAR_BASE); dbi_writel(pcie, flags, reg); @@ -63,51 +63,61 @@ static struct pci_ep_ops ls_pcie_ep_ops = { .set_bar = ls_ep_set_bar, }; -static void ls_pcie_ep_setup_atu(struct ls_pcie_ep *pcie_ep) +static void ls_pcie_ep_setup_atu(struct ls_pcie_ep *pcie_ep, u32 pf) { struct ls_pcie *pcie = pcie_ep->pcie; - u64 phys = CONFIG_SYS_PCI_EP_MEMORY_BASE; + u64 phys = 0; + phys = CONFIG_SYS_PCI_EP_MEMORY_BASE + pf * SZ_64M; + + phys = ALIGN(phys, PCIE_BAR0_SIZE); /* ATU 0 : INBOUND : map BAR0 */ - ls_pcie_atu_inbound_set(pcie, 0, PCIE_ATU_TYPE_MEM, 0, phys); + ls_pcie_atu_inbound_set(pcie, pf, PCIE_ATU_TYPE_MEM, + 0 + pf * BAR_NUM, 0, phys); /* ATU 1 : INBOUND : map BAR1 */ - phys += PCIE_BAR1_SIZE; - ls_pcie_atu_inbound_set(pcie, 1, PCIE_ATU_TYPE_MEM, 1, phys); + phys = ALIGN(phys + PCIE_BAR0_SIZE, PCIE_BAR1_SIZE); + ls_pcie_atu_inbound_set(pcie, pf, PCIE_ATU_TYPE_MEM, + 1 + pf * BAR_NUM, 1, phys); /* ATU 2 : INBOUND : map BAR2 */ - phys += PCIE_BAR2_SIZE; - ls_pcie_atu_inbound_set(pcie, 2, PCIE_ATU_TYPE_MEM, 2, phys); - /* ATU 3 : INBOUND : map BAR4 */ - phys = CONFIG_SYS_PCI_EP_MEMORY_BASE + PCIE_BAR4_SIZE; - ls_pcie_atu_inbound_set(pcie, 3, PCIE_ATU_TYPE_MEM, 4, phys); - - /* ATU 0 : OUTBOUND : map MEM */ - ls_pcie_atu_outbound_set(pcie, 0, - PCIE_ATU_TYPE_MEM, - pcie_ep->addr_res.start, - 0, - CONFIG_SYS_PCI_MEMORY_SIZE); + phys = ALIGN(phys + PCIE_BAR1_SIZE, PCIE_BAR2_SIZE); + ls_pcie_atu_inbound_set(pcie, pf, PCIE_ATU_TYPE_MEM, + 2 + pf * BAR_NUM, 2, phys); + /* ATU 3 : INBOUND : map BAR2 */ + phys = ALIGN(phys + PCIE_BAR2_SIZE, PCIE_BAR4_SIZE); + ls_pcie_atu_inbound_set(pcie, pf, PCIE_ATU_TYPE_MEM, + 3 + pf * BAR_NUM, 4, phys); + + /* ATU: OUTBOUND : map MEM */ + ls_pcie_atu_outbound_set(pcie, pf, PCIE_ATU_TYPE_MEM, + (u64)pcie_ep->addr_res.start + + pf * CONFIG_SYS_PCI_MEMORY_SIZE, + 0, CONFIG_SYS_PCI_MEMORY_SIZE); } /* BAR0 and BAR1 are 32bit BAR2 and BAR4 are 64bit */ static void ls_pcie_ep_setup_bar(void *bar_base, int bar, u32 size) { + u32 mask; + /* The least inbound window is 4KiB */ - if (size < 4 * 1024) - return; + if (size < SZ_4K) + mask = 0; + else + mask = size - 1; switch (bar) { case 0: - writel(size - 1, bar_base + PCI_BASE_ADDRESS_0); + writel(mask, bar_base + PCI_BASE_ADDRESS_0); break; case 1: - writel(size - 1, bar_base + PCI_BASE_ADDRESS_1); + writel(mask, bar_base + PCI_BASE_ADDRESS_1); break; case 2: - writel(size - 1, bar_base + PCI_BASE_ADDRESS_2); + writel(mask, bar_base + PCI_BASE_ADDRESS_2); writel(0, bar_base + PCI_BASE_ADDRESS_3); break; case 4: - writel(size - 1, bar_base + PCI_BASE_ADDRESS_4); + writel(mask, bar_base + PCI_BASE_ADDRESS_4); writel(0, bar_base + PCI_BASE_ADDRESS_5); break; default: @@ -117,39 +127,62 @@ static void ls_pcie_ep_setup_bar(void *bar_base, int bar, u32 size) static void ls_pcie_ep_setup_bars(void *bar_base) { - /* BAR0 - 32bit - 4K configuration */ + /* BAR0 - 32bit - MEM */ + ls_pcie_ep_setup_bar(bar_base, 0, PCIE_BAR0_SIZE); + /* BAR1 - 32bit - MEM*/ + ls_pcie_ep_setup_bar(bar_base, 1, PCIE_BAR1_SIZE); + /* BAR2 - 64bit - MEM */ + ls_pcie_ep_setup_bar(bar_base, 2, PCIE_BAR2_SIZE); + /* BAR4 - 64bit - MEM */ + ls_pcie_ep_setup_bar(bar_base, 4, PCIE_BAR4_SIZE); +} + +static void ls_pcie_ep_setup_vf_bars(void *bar_base) +{ + /* VF BAR0 MASK register at offset 0x19c*/ + bar_base += PCIE_SRIOV_VFBAR0 - PCI_BASE_ADDRESS_0; + + /* VF-BAR0 - 32bit - MEM */ ls_pcie_ep_setup_bar(bar_base, 0, PCIE_BAR0_SIZE); - /* BAR1 - 32bit - 8K MSIX */ + /* VF-BAR1 - 32bit - MEM*/ ls_pcie_ep_setup_bar(bar_base, 1, PCIE_BAR1_SIZE); - /* BAR2 - 64bit - 4K MEM descriptor */ + /* VF-BAR2 - 64bit - MEM */ ls_pcie_ep_setup_bar(bar_base, 2, PCIE_BAR2_SIZE); - /* BAR4 - 64bit - 1M MEM */ + /* VF-BAR4 - 64bit - MEM */ ls_pcie_ep_setup_bar(bar_base, 4, PCIE_BAR4_SIZE); } static void ls_pcie_setup_ep(struct ls_pcie_ep *pcie_ep) { u32 sriov; + u32 pf, vf; + void *bar_base = NULL; struct ls_pcie *pcie = pcie_ep->pcie; sriov = readl(pcie->dbi + PCIE_SRIOV); if (PCI_EXT_CAP_ID(sriov) == PCI_EXT_CAP_ID_SRIOV) { - int pf, vf; - + pcie_ep->sriov_flag = 1; for (pf = 0; pf < PCIE_PF_NUM; pf++) { - for (vf = 0; vf <= PCIE_VF_NUM; vf++) { - ctrl_writel(pcie, PCIE_LCTRL0_VAL(pf, vf), - PCIE_PF_VF_CTRL); - - ls_pcie_ep_setup_bars(pcie->dbi); - ls_pcie_ep_setup_atu(pcie_ep); + if (pcie_ep->cfg2_flag) { + for (vf = 0; vf <= PCIE_VF_NUM; vf++) { + ctrl_writel(pcie, + PCIE_LCTRL0_VAL(pf, vf), + PCIE_PF_VF_CTRL); + } } + bar_base = pcie->dbi + + PCIE_MASK_OFFSET(pcie_ep->cfg2_flag, pf); + ls_pcie_ep_setup_bars(bar_base); + ls_pcie_ep_setup_vf_bars(bar_base); + + ls_pcie_ep_setup_atu(pcie_ep, pf); } - /* Disable CFG2 */ - ctrl_writel(pcie, 0, PCIE_PF_VF_CTRL); + + if (pcie_ep->cfg2_flag) /* Disable CFG2 */ + ctrl_writel(pcie, 0, PCIE_PF_VF_CTRL); } else { ls_pcie_ep_setup_bars(pcie->dbi + PCIE_NO_SRIOV_BAR_BASE); - ls_pcie_ep_setup_atu(pcie_ep); + ls_pcie_ep_setup_atu(pcie_ep, 0); } ls_pcie_ep_enable_cfg(pcie_ep); @@ -161,6 +194,7 @@ static int ls_pcie_ep_probe(struct udevice *dev) struct ls_pcie *pcie; u16 link_sta; int ret; + u32 svr; pcie = devm_kmalloc(dev, sizeof(*pcie), GFP_KERNEL); if (!pcie) @@ -190,6 +224,13 @@ static int ls_pcie_ep_probe(struct udevice *dev) pcie->big_endian = fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev), "big-endian"); + svr = SVR_SOC_VER(get_svr()); + + if (svr == SVR_LS2080A || svr == SVR_LS2085A) + pcie_ep->cfg2_flag = 1; + else + pcie_ep->cfg2_flag = 0; + pcie->mode = readb(pcie->dbi + PCI_HEADER_TYPE) & 0x7f; if (pcie->mode != PCI_HEADER_TYPE_NORMAL) return 0; From patchwork Sun Mar 22 11:12:48 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiaowei Bao X-Patchwork-Id: 1259631 X-Patchwork-Delegate: priyanka.jain@nxp.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=nxp.com Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48lZxh4wY4z9sPR for ; Sun, 22 Mar 2020 22:27:52 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id B525381885; Sun, 22 Mar 2020 12:27:14 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=nxp.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Received: by phobos.denx.de (Postfix, from userid 109) id 5A36181831; Sun, 22 Mar 2020 12:27:00 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from inva020.nxp.com (inva020.nxp.com [92.121.34.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 4312481829 for ; Sun, 22 Mar 2020 12:26:56 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=nxp.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=xiaowei.bao@nxp.com Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 0F1F31A0EB4; Sun, 22 Mar 2020 12:26:56 +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 278F21A0EA1; Sun, 22 Mar 2020 12:26:52 +0100 (CET) Received: from titan.ap.freescale.net (titan.ap.freescale.net [10.192.208.233]) by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id 466D04030D; Sun, 22 Mar 2020 19:26:42 +0800 (SGT) From: Xiaowei Bao To: Minghuan.Lian@nxp.com, Zhiqiang.Hou@nxp.com, Mingkai.hu@nxp.com, bmeng.cn@gmail.com, yamada.masahiro@socionext.com, u-boot@lists.denx.de Cc: Xiaowei Bao Subject: [PATCH 5/9] pci_ep: layerscape: Add the workaround for errata A-009460 Date: Sun, 22 Mar 2020 19:12:48 +0800 Message-Id: <20200322111252.44001-5-xiaowei.bao@nxp.com> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20200322111252.44001-1-xiaowei.bao@nxp.com> References: <20200322111252.44001-1-xiaowei.bao@nxp.com> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.30rc1 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.2 at phobos.denx.de X-Virus-Status: Clean The VF_BARn_REG register's Prefetchable and Type bit fields are overwritten by a write to VF's BAR Mask register. workaround: Before writing to the VF_BARn_MASK_REG register, write 0b to the PCIE_MISC_CONTROL_1_OFF register. Signed-off-by: Xiaowei Bao Reviewed-by: Hou Zhiqiang --- drivers/pci/pcie_layerscape_ep.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/pci/pcie_layerscape_ep.c b/drivers/pci/pcie_layerscape_ep.c index bec374b..a2b18ad 100644 --- a/drivers/pci/pcie_layerscape_ep.c +++ b/drivers/pci/pcie_layerscape_ep.c @@ -163,6 +163,15 @@ static void ls_pcie_setup_ep(struct ls_pcie_ep *pcie_ep) if (PCI_EXT_CAP_ID(sriov) == PCI_EXT_CAP_ID_SRIOV) { pcie_ep->sriov_flag = 1; for (pf = 0; pf < PCIE_PF_NUM; pf++) { + /* + * The VF_BARn_REG register's Prefetchable and Type bit + * fields are overwritten by a write to VF's BAR Mask + * register. Before writing to the VF_BARn_MASK_REG + * register, write 0b to the PCIE_MISC_CONTROL_1_OFF + * register. + */ + writel(0, pcie->dbi + PCIE_MISC_CONTROL_1_OFF); + if (pcie_ep->cfg2_flag) { for (vf = 0; vf <= PCIE_VF_NUM; vf++) { ctrl_writel(pcie, From patchwork Sun Mar 22 11:12:49 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiaowei Bao X-Patchwork-Id: 1259635 X-Patchwork-Delegate: priyanka.jain@nxp.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=nxp.com Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48lZyV4WVWz9sPR for ; Sun, 22 Mar 2020 22:28:34 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id EF0D1818B8; Sun, 22 Mar 2020 12:27:29 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=nxp.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Received: by phobos.denx.de (Postfix, from userid 109) id 0A87681829; Sun, 22 Mar 2020 12:27:04 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from inva021.nxp.com (inva021.nxp.com [92.121.34.21]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 657E681843 for ; Sun, 22 Mar 2020 12:26:56 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=nxp.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=xiaowei.bao@nxp.com Received: from inva021.nxp.com (localhost [127.0.0.1]) by inva021.eu-rdc02.nxp.com (Postfix) with ESMTP id 0FACD200D86; Sun, 22 Mar 2020 12:26:56 +0100 (CET) Received: from invc005.ap-rdc01.nxp.com (invc005.ap-rdc01.nxp.com [165.114.16.14]) by inva021.eu-rdc02.nxp.com (Postfix) with ESMTP id 2808D200D80; Sun, 22 Mar 2020 12:26:52 +0100 (CET) Received: from titan.ap.freescale.net (titan.ap.freescale.net [10.192.208.233]) by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id 22DB9402BF; Sun, 22 Mar 2020 19:26:43 +0800 (SGT) From: Xiaowei Bao To: Minghuan.Lian@nxp.com, Zhiqiang.Hou@nxp.com, Mingkai.hu@nxp.com, bmeng.cn@gmail.com, yamada.masahiro@socionext.com, u-boot@lists.denx.de Cc: Xiaowei Bao Subject: [PATCH 6/9] pci_ep: layerscape: Add Support for ls2085a and ls2080a EP mode Date: Sun, 22 Mar 2020 19:12:49 +0800 Message-Id: <20200322111252.44001-6-xiaowei.bao@nxp.com> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20200322111252.44001-1-xiaowei.bao@nxp.com> References: <20200322111252.44001-1-xiaowei.bao@nxp.com> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.30rc1 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.2 at phobos.denx.de X-Virus-Status: Clean Due to the ls2085a and ls2080a use difference way to set the BAR size, so add the BAR size init code here. Signed-off-by: Xiaowei Bao Reviewed-by: Hou Zhiqiang --- drivers/pci/pcie_layerscape_ep.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/pci/pcie_layerscape_ep.c b/drivers/pci/pcie_layerscape_ep.c index a2b18ad..cd7ea26 100644 --- a/drivers/pci/pcie_layerscape_ep.c +++ b/drivers/pci/pcie_layerscape_ep.c @@ -172,17 +172,25 @@ static void ls_pcie_setup_ep(struct ls_pcie_ep *pcie_ep) */ writel(0, pcie->dbi + PCIE_MISC_CONTROL_1_OFF); + bar_base = pcie->dbi + + PCIE_MASK_OFFSET(pcie_ep->cfg2_flag, pf); + if (pcie_ep->cfg2_flag) { - for (vf = 0; vf <= PCIE_VF_NUM; vf++) { + ctrl_writel(pcie, + PCIE_LCTRL0_VAL(pf, 0), + PCIE_PF_VF_CTRL); + ls_pcie_ep_setup_bars(bar_base); + + for (vf = 1; vf <= PCIE_VF_NUM; vf++) { ctrl_writel(pcie, PCIE_LCTRL0_VAL(pf, vf), PCIE_PF_VF_CTRL); + ls_pcie_ep_setup_vf_bars(bar_base); } + } else { + ls_pcie_ep_setup_bars(bar_base); + ls_pcie_ep_setup_vf_bars(bar_base); } - bar_base = pcie->dbi + - PCIE_MASK_OFFSET(pcie_ep->cfg2_flag, pf); - ls_pcie_ep_setup_bars(bar_base); - ls_pcie_ep_setup_vf_bars(bar_base); ls_pcie_ep_setup_atu(pcie_ep, pf); } From patchwork Sun Mar 22 11:12:50 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiaowei Bao X-Patchwork-Id: 1259634 X-Patchwork-Delegate: priyanka.jain@nxp.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=nxp.com Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48lZyJ5KXRz9sPR for ; Sun, 22 Mar 2020 22:28:24 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 085F2818AF; Sun, 22 Mar 2020 12:27:22 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=nxp.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Received: by phobos.denx.de (Postfix, from userid 109) id 618F781881; Sun, 22 Mar 2020 12:27:04 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from inva020.nxp.com (inva020.nxp.com [92.121.34.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 8DE7081860 for ; Sun, 22 Mar 2020 12:26:57 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=nxp.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=xiaowei.bao@nxp.com Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 4C1D01A0EAE; Sun, 22 Mar 2020 12:26:57 +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 2E06C1A0EA7; Sun, 22 Mar 2020 12:26:53 +0100 (CET) Received: from titan.ap.freescale.net (titan.ap.freescale.net [10.192.208.233]) by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id EAE3E4030E; Sun, 22 Mar 2020 19:26:43 +0800 (SGT) From: Xiaowei Bao To: Minghuan.Lian@nxp.com, Zhiqiang.Hou@nxp.com, Mingkai.hu@nxp.com, bmeng.cn@gmail.com, yamada.masahiro@socionext.com, u-boot@lists.denx.de Cc: Xiaowei Bao Subject: [PATCH 7/9] pci_ep: layerscape: Add the SRIOV VFs of PF support Date: Sun, 22 Mar 2020 19:12:50 +0800 Message-Id: <20200322111252.44001-7-xiaowei.bao@nxp.com> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20200322111252.44001-1-xiaowei.bao@nxp.com> References: <20200322111252.44001-1-xiaowei.bao@nxp.com> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.30rc1 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.2 at phobos.denx.de X-Virus-Status: Clean Add the INBOUND configuration for VFs of PF. Signed-off-by: Xiaowei Bao Reviewed-by: Hou Zhiqiang --- drivers/pci/pcie_layerscape.c | 8 +++++--- drivers/pci/pcie_layerscape.h | 13 ++++++++----- drivers/pci/pcie_layerscape_ep.c | 34 +++++++++++++++++++++++++++++----- 3 files changed, 42 insertions(+), 13 deletions(-) diff --git a/drivers/pci/pcie_layerscape.c b/drivers/pci/pcie_layerscape.c index 88a0e8a..c7a96ed 100644 --- a/drivers/pci/pcie_layerscape.c +++ b/drivers/pci/pcie_layerscape.c @@ -91,7 +91,7 @@ int ls_pcie_link_up(struct ls_pcie *pcie) } void ls_pcie_atu_outbound_set(struct ls_pcie *pcie, int idx, int type, - u64 phys, u64 bus_addr, pci_size_t size) + u64 phys, u64 bus_addr, u64 size) { dbi_writel(pcie, PCIE_ATU_REGION_OUTBOUND | idx, PCIE_ATU_VIEWPORT); dbi_writel(pcie, (u32)phys, PCIE_ATU_LOWER_BASE); @@ -104,14 +104,16 @@ void ls_pcie_atu_outbound_set(struct ls_pcie *pcie, int idx, int type, } /* Use bar match mode and MEM type as default */ -void ls_pcie_atu_inbound_set(struct ls_pcie *pcie, u32 pf, int type, - int idx, int bar, u64 phys) +void ls_pcie_atu_inbound_set(struct ls_pcie *pcie, u32 pf, u32 vf_flag, + int type, int idx, int bar, u64 phys) { dbi_writel(pcie, PCIE_ATU_REGION_INBOUND | idx, PCIE_ATU_VIEWPORT); dbi_writel(pcie, (u32)phys, PCIE_ATU_LOWER_TARGET); dbi_writel(pcie, phys >> 32, PCIE_ATU_UPPER_TARGET); dbi_writel(pcie, type | PCIE_ATU_FUNC_NUM(pf), PCIE_ATU_CR1); dbi_writel(pcie, PCIE_ATU_ENABLE | PCIE_ATU_BAR_MODE_ENABLE | + (vf_flag ? PCIE_ATU_FUNC_NUM_MATCH_EN : 0) | + (vf_flag ? PCIE_ATU_VFBAR_MATCH_MODE_EN : 0) | PCIE_ATU_BAR_NUM(bar), PCIE_ATU_CR2); } diff --git a/drivers/pci/pcie_layerscape.h b/drivers/pci/pcie_layerscape.h index dabfff3..26d0177 100644 --- a/drivers/pci/pcie_layerscape.h +++ b/drivers/pci/pcie_layerscape.h @@ -20,7 +20,7 @@ #endif #ifndef CONFIG_SYS_PCI_MEMORY_SIZE -#define CONFIG_SYS_PCI_MEMORY_SIZE (2 * 1024 * 1024 * 1024UL) /* 2G */ +#define CONFIG_SYS_PCI_MEMORY_SIZE SZ_4G #endif #ifndef CONFIG_SYS_PCI_EP_MEMORY_BASE @@ -40,6 +40,7 @@ #define PCIE_ATU_REGION_INDEX2 (0x2 << 0) #define PCIE_ATU_REGION_INDEX3 (0x3 << 0) #define PCIE_ATU_REGION_NUM 6 +#define PCIE_ATU_REGION_NUM_SRIOV 24 #define PCIE_ATU_CR1 0x904 #define PCIE_ATU_TYPE_MEM (0x0 << 0) #define PCIE_ATU_TYPE_IO (0x2 << 0) @@ -49,6 +50,8 @@ #define PCIE_ATU_CR2 0x908 #define PCIE_ATU_ENABLE (0x1 << 31) #define PCIE_ATU_BAR_MODE_ENABLE (0x1 << 30) +#define PCIE_ATU_FUNC_NUM_MATCH_EN BIT(19) +#define PCIE_ATU_VFBAR_MATCH_MODE_EN BIT(26) #define PCIE_ATU_BAR_NUM(bar) ((bar) << 8) #define PCIE_ATU_LOWER_BASE 0x90C #define PCIE_ATU_UPPER_BASE 0x910 @@ -88,7 +91,7 @@ #define FSL_PCIE_EP_MIN_APERTURE 4096 /* 4 Kbytes */ #define PCIE_PF_NUM 2 #define PCIE_VF_NUM 64 -#define BAR_NUM 4 +#define BAR_NUM 8 #define PCIE_BAR0_SIZE SZ_4K #define PCIE_BAR1_SIZE SZ_8K @@ -179,9 +182,9 @@ void dbi_writel(struct ls_pcie *pcie, unsigned int value, unsigned int offset); unsigned int ctrl_readl(struct ls_pcie *pcie, unsigned int offset); void ctrl_writel(struct ls_pcie *pcie, unsigned int value, unsigned int offset); void ls_pcie_atu_outbound_set(struct ls_pcie *pcie, int idx, int type, - u64 phys, u64 bus_addr, pci_size_t size); -void ls_pcie_atu_inbound_set(struct ls_pcie *pcie, u32 pf, int type, - int idx, int bar, u64 phys); + u64 phys, u64 bus_addr, u64 size); +void ls_pcie_atu_inbound_set(struct ls_pcie *pcie, u32 pf, u32 vf_flag, + int type, int idx, int bar, u64 phys); void ls_pcie_dump_atu(struct ls_pcie *pcie); int ls_pcie_link_up(struct ls_pcie *pcie); void ls_pcie_dbi_ro_wr_en(struct ls_pcie *pcie); diff --git a/drivers/pci/pcie_layerscape_ep.c b/drivers/pci/pcie_layerscape_ep.c index cd7ea26..67ce36c 100644 --- a/drivers/pci/pcie_layerscape_ep.c +++ b/drivers/pci/pcie_layerscape_ep.c @@ -45,7 +45,7 @@ static int ls_ep_set_bar(struct udevice *dev, uint fn, struct pci_bar *ep_bar) else type = PCIE_ATU_TYPE_IO; - ls_pcie_atu_inbound_set(pcie, fn, type, idx, bar, bar_phys); + ls_pcie_atu_inbound_set(pcie, fn, 0, type, idx, bar, bar_phys); dbi_writel(pcie, lower_32_bits(size - 1), reg + PCIE_NO_SRIOV_BAR_BASE); dbi_writel(pcie, flags, reg); @@ -66,27 +66,51 @@ static struct pci_ep_ops ls_pcie_ep_ops = { static void ls_pcie_ep_setup_atu(struct ls_pcie_ep *pcie_ep, u32 pf) { struct ls_pcie *pcie = pcie_ep->pcie; + u32 vf_flag = 0; u64 phys = 0; phys = CONFIG_SYS_PCI_EP_MEMORY_BASE + pf * SZ_64M; phys = ALIGN(phys, PCIE_BAR0_SIZE); /* ATU 0 : INBOUND : map BAR0 */ - ls_pcie_atu_inbound_set(pcie, pf, PCIE_ATU_TYPE_MEM, + ls_pcie_atu_inbound_set(pcie, pf, vf_flag, PCIE_ATU_TYPE_MEM, 0 + pf * BAR_NUM, 0, phys); /* ATU 1 : INBOUND : map BAR1 */ phys = ALIGN(phys + PCIE_BAR0_SIZE, PCIE_BAR1_SIZE); - ls_pcie_atu_inbound_set(pcie, pf, PCIE_ATU_TYPE_MEM, + ls_pcie_atu_inbound_set(pcie, pf, vf_flag, PCIE_ATU_TYPE_MEM, 1 + pf * BAR_NUM, 1, phys); /* ATU 2 : INBOUND : map BAR2 */ phys = ALIGN(phys + PCIE_BAR1_SIZE, PCIE_BAR2_SIZE); - ls_pcie_atu_inbound_set(pcie, pf, PCIE_ATU_TYPE_MEM, + ls_pcie_atu_inbound_set(pcie, pf, vf_flag, PCIE_ATU_TYPE_MEM, 2 + pf * BAR_NUM, 2, phys); /* ATU 3 : INBOUND : map BAR2 */ phys = ALIGN(phys + PCIE_BAR2_SIZE, PCIE_BAR4_SIZE); - ls_pcie_atu_inbound_set(pcie, pf, PCIE_ATU_TYPE_MEM, + ls_pcie_atu_inbound_set(pcie, pf, vf_flag, PCIE_ATU_TYPE_MEM, 3 + pf * BAR_NUM, 4, phys); + if (pcie_ep->sriov_flag) { + vf_flag = 1; + /* ATU 4 : INBOUND : map BAR0 */ + phys = ALIGN(phys + PCIE_BAR4_SIZE, PCIE_BAR0_SIZE); + ls_pcie_atu_inbound_set(pcie, pf, vf_flag, PCIE_ATU_TYPE_MEM, + 4 + pf * BAR_NUM, 0, phys); + /* ATU 5 : INBOUND : map BAR1 */ + phys = ALIGN(phys + PCIE_BAR0_SIZE * PCIE_VF_NUM, + PCIE_BAR1_SIZE); + ls_pcie_atu_inbound_set(pcie, pf, vf_flag, PCIE_ATU_TYPE_MEM, + 5 + pf * BAR_NUM, 1, phys); + /* ATU 6 : INBOUND : map BAR2 */ + phys = ALIGN(phys + PCIE_BAR1_SIZE * PCIE_VF_NUM, + PCIE_BAR2_SIZE); + ls_pcie_atu_inbound_set(pcie, pf, vf_flag, PCIE_ATU_TYPE_MEM, + 6 + pf * BAR_NUM, 2, phys); + /* ATU 7 : INBOUND : map BAR4 */ + phys = ALIGN(phys + PCIE_BAR2_SIZE * PCIE_VF_NUM, + PCIE_BAR4_SIZE); + ls_pcie_atu_inbound_set(pcie, pf, vf_flag, PCIE_ATU_TYPE_MEM, + 7 + pf * BAR_NUM, 4, phys); + } + /* ATU: OUTBOUND : map MEM */ ls_pcie_atu_outbound_set(pcie, pf, PCIE_ATU_TYPE_MEM, (u64)pcie_ep->addr_res.start + From patchwork Sun Mar 22 11:12:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiaowei Bao X-Patchwork-Id: 1259633 X-Patchwork-Delegate: priyanka.jain@nxp.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=nxp.com Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48lZy629bPz9sPR for ; Sun, 22 Mar 2020 22:28:14 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id A1E4881890; Sun, 22 Mar 2020 12:27:19 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=nxp.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Received: by phobos.denx.de (Postfix, from userid 109) id BA7238188A; Sun, 22 Mar 2020 12:27:03 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from inva021.nxp.com (inva021.nxp.com [92.121.34.21]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id A57AE81869 for ; Sun, 22 Mar 2020 12:26:57 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=nxp.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=xiaowei.bao@nxp.com Received: from inva021.nxp.com (localhost [127.0.0.1]) by inva021.eu-rdc02.nxp.com (Postfix) with ESMTP id 54E7E200D80; Sun, 22 Mar 2020 12:26:57 +0100 (CET) Received: from invc005.ap-rdc01.nxp.com (invc005.ap-rdc01.nxp.com [165.114.16.14]) by inva021.eu-rdc02.nxp.com (Postfix) with ESMTP id 2DA83200D7C; Sun, 22 Mar 2020 12:26:53 +0100 (CET) Received: from titan.ap.freescale.net (titan.ap.freescale.net [10.192.208.233]) by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id BEEE640310; Sun, 22 Mar 2020 19:26:44 +0800 (SGT) From: Xiaowei Bao To: Minghuan.Lian@nxp.com, Zhiqiang.Hou@nxp.com, Mingkai.hu@nxp.com, bmeng.cn@gmail.com, yamada.masahiro@socionext.com, u-boot@lists.denx.de Cc: Xiaowei Bao Subject: [PATCH 8/9] pci: layerscaple: Modify the ls_pcie_dump_atu function Date: Sun, 22 Mar 2020 19:12:51 +0800 Message-Id: <20200322111252.44001-8-xiaowei.bao@nxp.com> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20200322111252.44001-1-xiaowei.bao@nxp.com> References: <20200322111252.44001-1-xiaowei.bao@nxp.com> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.30rc1 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.2 at phobos.denx.de X-Virus-Status: Clean Modify the ls_pcie_dump_atu function, make it can print the INBOUND windows registers. Signed-off-by: Xiaowei Bao Reviewed-by: Hou Zhiqiang --- drivers/pci/pcie_layerscape.c | 25 +++++++++++++------------ drivers/pci/pcie_layerscape.h | 2 +- drivers/pci/pcie_layerscape_ep.c | 3 +++ drivers/pci/pcie_layerscape_rc.c | 2 +- 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/drivers/pci/pcie_layerscape.c b/drivers/pci/pcie_layerscape.c index c7a96ed..4015a0d 100644 --- a/drivers/pci/pcie_layerscape.c +++ b/drivers/pci/pcie_layerscape.c @@ -117,24 +117,25 @@ void ls_pcie_atu_inbound_set(struct ls_pcie *pcie, u32 pf, u32 vf_flag, PCIE_ATU_BAR_NUM(bar), PCIE_ATU_CR2); } -void ls_pcie_dump_atu(struct ls_pcie *pcie) +void ls_pcie_dump_atu(struct ls_pcie *pcie, u32 win_num, u32 type) { - int i; + int win_idx; - for (i = 0; i < PCIE_ATU_REGION_NUM; i++) { - dbi_writel(pcie, PCIE_ATU_REGION_OUTBOUND | i, - PCIE_ATU_VIEWPORT); - debug("iATU%d:\n", i); + for (win_idx = 0; win_idx < win_num; win_idx++) { + dbi_writel(pcie, type | win_idx, PCIE_ATU_VIEWPORT); + debug("iATU%d:\n", win_idx); debug("\tLOWER PHYS 0x%08x\n", dbi_readl(pcie, PCIE_ATU_LOWER_BASE)); debug("\tUPPER PHYS 0x%08x\n", dbi_readl(pcie, PCIE_ATU_UPPER_BASE)); - debug("\tLOWER BUS 0x%08x\n", - dbi_readl(pcie, PCIE_ATU_LOWER_TARGET)); - debug("\tUPPER BUS 0x%08x\n", - dbi_readl(pcie, PCIE_ATU_UPPER_TARGET)); - debug("\tLIMIT 0x%08x\n", - dbi_readl(pcie, PCIE_ATU_LIMIT)); + if (type == PCIE_ATU_REGION_OUTBOUND) { + debug("\tLOWER BUS 0x%08x\n", + dbi_readl(pcie, PCIE_ATU_LOWER_TARGET)); + debug("\tUPPER BUS 0x%08x\n", + dbi_readl(pcie, PCIE_ATU_UPPER_TARGET)); + debug("\tLIMIT 0x%08x\n", + dbi_readl(pcie, PCIE_ATU_LIMIT)); + } debug("\tCR1 0x%08x\n", dbi_readl(pcie, PCIE_ATU_CR1)); debug("\tCR2 0x%08x\n", diff --git a/drivers/pci/pcie_layerscape.h b/drivers/pci/pcie_layerscape.h index 26d0177..5f5c51d 100644 --- a/drivers/pci/pcie_layerscape.h +++ b/drivers/pci/pcie_layerscape.h @@ -185,7 +185,7 @@ void ls_pcie_atu_outbound_set(struct ls_pcie *pcie, int idx, int type, u64 phys, u64 bus_addr, u64 size); void ls_pcie_atu_inbound_set(struct ls_pcie *pcie, u32 pf, u32 vf_flag, int type, int idx, int bar, u64 phys); -void ls_pcie_dump_atu(struct ls_pcie *pcie); +void ls_pcie_dump_atu(struct ls_pcie *pcie, u32 win_num, u32 type); int ls_pcie_link_up(struct ls_pcie *pcie); void ls_pcie_dbi_ro_wr_en(struct ls_pcie *pcie); void ls_pcie_dbi_ro_wr_dis(struct ls_pcie *pcie); diff --git a/drivers/pci/pcie_layerscape_ep.c b/drivers/pci/pcie_layerscape_ep.c index 67ce36c..ebf69ee 100644 --- a/drivers/pci/pcie_layerscape_ep.c +++ b/drivers/pci/pcie_layerscape_ep.c @@ -226,6 +226,9 @@ static void ls_pcie_setup_ep(struct ls_pcie_ep *pcie_ep) ls_pcie_ep_setup_atu(pcie_ep, 0); } + ls_pcie_dump_atu(pcie, PCIE_ATU_REGION_NUM_SRIOV, + PCIE_ATU_REGION_INBOUND); + ls_pcie_ep_enable_cfg(pcie_ep); } diff --git a/drivers/pci/pcie_layerscape_rc.c b/drivers/pci/pcie_layerscape_rc.c index 927722d..b045159 100644 --- a/drivers/pci/pcie_layerscape_rc.c +++ b/drivers/pci/pcie_layerscape_rc.c @@ -114,7 +114,7 @@ static void ls_pcie_setup_atu(struct ls_pcie_rc *pcie_rc) pref->bus_start, pref->size); - ls_pcie_dump_atu(pcie); + ls_pcie_dump_atu(pcie, PCIE_ATU_REGION_NUM, PCIE_ATU_REGION_OUTBOUND); } /* Return 0 if the address is valid, -errno if not valid */ From patchwork Sun Mar 22 11:12:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiaowei Bao X-Patchwork-Id: 1259632 X-Patchwork-Delegate: priyanka.jain@nxp.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=nxp.com Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48lZxw2xmxz9sPR for ; Sun, 22 Mar 2020 22:28:03 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 5ABF6818A0; Sun, 22 Mar 2020 12:27:17 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=nxp.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Received: by phobos.denx.de (Postfix, from userid 109) id A615381856; Sun, 22 Mar 2020 12:27:02 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from inva020.nxp.com (inva020.nxp.com [92.121.34.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 6700D81856 for ; Sun, 22 Mar 2020 12:26:57 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=nxp.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=xiaowei.bao@nxp.com Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 305951A0EB5; Sun, 22 Mar 2020 12:26:57 +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 498831A0E9E; Sun, 22 Mar 2020 12:26:53 +0100 (CET) Received: from titan.ap.freescale.net (titan.ap.freescale.net [10.192.208.233]) by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id 9301340313; Sun, 22 Mar 2020 19:26:45 +0800 (SGT) From: Xiaowei Bao To: Minghuan.Lian@nxp.com, Zhiqiang.Hou@nxp.com, Mingkai.hu@nxp.com, bmeng.cn@gmail.com, yamada.masahiro@socionext.com, u-boot@lists.denx.de Cc: Xiaowei Bao Subject: [PATCH 9/9] pci_ep: layerscape: Add the PCIe EP mode support for lx2160a-v2 Date: Sun, 22 Mar 2020 19:12:52 +0800 Message-Id: <20200322111252.44001-9-xiaowei.bao@nxp.com> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20200322111252.44001-1-xiaowei.bao@nxp.com> References: <20200322111252.44001-1-xiaowei.bao@nxp.com> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.30rc1 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.2 at phobos.denx.de X-Virus-Status: Clean Add the PCIe EP mode support for lx2160a-v2 platform. Signed-off-by: Xiaowei Bao Reviewed-by: Hou Zhiqiang --- drivers/pci/pcie_layerscape.h | 9 ++++++++- drivers/pci/pcie_layerscape_ep.c | 8 +++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/pci/pcie_layerscape.h b/drivers/pci/pcie_layerscape.h index 5f5c51d..593798e 100644 --- a/drivers/pci/pcie_layerscape.h +++ b/drivers/pci/pcie_layerscape.h @@ -100,7 +100,7 @@ #define PCIE_SRIOV_VFBAR0 0x19C -#define PCIE_MASK_OFFSET(flag, pf) ((flag) ? 0 : (0x1000 + 0x20000 * (pf))) +#define PCIE_MASK_OFFSET(flag, pf, off) ((flag) ? 0 : (0x1000 + (off) * (pf))) /* LUT registers */ #define PCIE_LUT_UDR(n) (0x800 + (n) * 8) @@ -139,6 +139,12 @@ #define LS1021_PEXMSCPORTSR(pex_idx) (0x94 + (pex_idx) * 4) #define LS1021_LTSSM_STATE_SHIFT 20 +/* LX2160a PF1 offset */ +#define LX2160_PCIE_PF1_OFFSET 0x8000 + +/* layerscape PF1 offset */ +#define LS_PCIE_PF1_OFFSET 0x20000 + struct ls_pcie { void __iomem *dbi; void __iomem *lut; @@ -170,6 +176,7 @@ struct ls_pcie_ep { void __iomem *addr; u32 cfg2_flag; u32 sriov_flag; + u32 pf1_offset; u32 num_ib_wins; u32 num_ob_wins; u8 max_functions; diff --git a/drivers/pci/pcie_layerscape_ep.c b/drivers/pci/pcie_layerscape_ep.c index ebf69ee..0228863 100644 --- a/drivers/pci/pcie_layerscape_ep.c +++ b/drivers/pci/pcie_layerscape_ep.c @@ -197,7 +197,8 @@ static void ls_pcie_setup_ep(struct ls_pcie_ep *pcie_ep) writel(0, pcie->dbi + PCIE_MISC_CONTROL_1_OFF); bar_base = pcie->dbi + - PCIE_MASK_OFFSET(pcie_ep->cfg2_flag, pf); + PCIE_MASK_OFFSET(pcie_ep->cfg2_flag, pf, + pcie_ep->pf1_offset); if (pcie_ep->cfg2_flag) { ctrl_writel(pcie, @@ -270,6 +271,11 @@ static int ls_pcie_ep_probe(struct udevice *dev) svr = SVR_SOC_VER(get_svr()); + if (svr == SVR_LX2160A) + pcie_ep->pf1_offset = LX2160_PCIE_PF1_OFFSET; + else + pcie_ep->pf1_offset = LS_PCIE_PF1_OFFSET; + if (svr == SVR_LS2080A || svr == SVR_LS2085A) pcie_ep->cfg2_flag = 1; else