From 9c2aee1b1943f538e3f38e4884f186033e29831c Mon Sep 17 00:00:00 2001 From: Alex Marginean Date: Tue, 10 Dec 2019 16:55:39 +0200 Subject: drivers: net: fsl_enetc: Pass on primary MAC address to Linux Passes on the primary address used by u-boot to Linux. The code does a DT fix-up for ENETC PFs and sets the primary MAC address in IERB. The address in IERB is restored on ENETC PCI functions at FLR. Signed-off-by: Alex Marginean Reviewed-by: Vladimir Oltean Reviewed-by: Priyanka Jain --- drivers/net/fsl_enetc.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++- drivers/net/fsl_enetc.h | 3 +++ 2 files changed, 67 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/fsl_enetc.c b/drivers/net/fsl_enetc.c index 02c1ee7..f8fe7d4 100644 --- a/drivers/net/fsl_enetc.c +++ b/drivers/net/fsl_enetc.c @@ -14,6 +14,69 @@ #include "fsl_enetc.h" +#define ENETC_DRIVER_NAME "enetc_eth" + +/* + * sets the MAC address in IERB registers, this setting is persistent and + * carried over to Linux. + */ +static void enetc_set_ierb_primary_mac(struct udevice *dev, int devfn, + const u8 *enetaddr) +{ +#ifdef CONFIG_ARCH_LS1028A +/* + * LS1028A is the only part with IERB at this time and there are plans to change + * its structure, keep this LS1028A specific for now + */ +#define IERB_BASE 0x1f0800000ULL +#define IERB_PFMAC(pf, vf, n) (IERB_BASE + 0x8000 + (pf) * 0x100 + (vf) * 8 \ + + (n) * 4) + +static int ierb_fn_to_pf[] = {0, 1, 2, -1, -1, -1, 3}; + + u16 lower = *(const u16 *)(enetaddr + 4); + u32 upper = *(const u32 *)enetaddr; + + if (ierb_fn_to_pf[devfn] < 0) + return; + + out_le32(IERB_PFMAC(ierb_fn_to_pf[devfn], 0, 0), upper); + out_le32(IERB_PFMAC(ierb_fn_to_pf[devfn], 0, 1), (u32)lower); +#endif +} + +/* sets up primary MAC addresses in DT/IERB */ +void fdt_fixup_enetc_mac(void *blob) +{ + struct pci_child_platdata *ppdata; + struct eth_pdata *pdata; + struct udevice *dev; + struct uclass *uc; + char path[256]; + int offset; + int devfn; + + uclass_get(UCLASS_ETH, &uc); + uclass_foreach_dev(dev, uc) { + if (!dev->driver || !dev->driver->name || + strcmp(dev->driver->name, ENETC_DRIVER_NAME)) + continue; + + pdata = dev_get_platdata(dev); + ppdata = dev_get_parent_platdata(dev); + devfn = PCI_FUNC(ppdata->devfn); + + enetc_set_ierb_primary_mac(dev, devfn, pdata->enetaddr); + + snprintf(path, 256, "/soc/pcie@1f0000000/ethernet@%x,%x", + PCI_DEV(ppdata->devfn), PCI_FUNC(ppdata->devfn)); + offset = fdt_path_offset(blob, path); + if (offset < 0) + continue; + fdt_setprop(blob, offset, "mac-address", pdata->enetaddr, 6); + } +} + /* * Bind the device: * - set a more explicit name on the interface @@ -551,7 +614,7 @@ static const struct eth_ops enetc_ops = { }; U_BOOT_DRIVER(eth_enetc) = { - .name = "enetc_eth", + .name = ENETC_DRIVER_NAME, .id = UCLASS_ETH, .bind = enetc_bind, .probe = enetc_probe, diff --git a/drivers/net/fsl_enetc.h b/drivers/net/fsl_enetc.h index 9a36cda..48c3005 100644 --- a/drivers/net/fsl_enetc.h +++ b/drivers/net/fsl_enetc.h @@ -227,4 +227,7 @@ int enetc_mdio_read_priv(struct enetc_mdio_priv *priv, int addr, int devad, int enetc_mdio_write_priv(struct enetc_mdio_priv *priv, int addr, int devad, int reg, u16 val); +/* sets up primary MAC addresses in DT/IERB */ +void fdt_fixup_enetc_mac(void *blob); + #endif /* _ENETC_H */ -- cgit v1.1 From f8203e3bb5f99c88199769034fe0f0af2879b96b Mon Sep 17 00:00:00 2001 From: Hou Zhiqiang Date: Tue, 17 Dec 2019 10:10:40 +0000 Subject: pci: layerscape: Fix the disabling of Expansion ROM BAR The software will still get non-zero Expansion ROM BAR size even when the BAR_EN bit is cleared. The BAR_EN bit of register EXP_ROM_BAR_MASK_RC is not working as expected, so this patch changes to mask all the bits. Fixes: 80afc63fc342 ("pci: layerscape: add pci driver based on DM") Signed-off-by: Hou Zhiqiang Reviewed-by: Priyanka Jain --- drivers/pci/pcie_layerscape.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pci/pcie_layerscape.c b/drivers/pci/pcie_layerscape.c index 47394bd..22d10cf 100644 --- a/drivers/pci/pcie_layerscape.c +++ b/drivers/pci/pcie_layerscape.c @@ -325,7 +325,7 @@ 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, 0, PCIE_CS2_OFFSET + PCI_ROM_ADDRESS1); + dbi_writel(pcie, 0xfffffffe, PCIE_CS2_OFFSET + PCI_ROM_ADDRESS1); } static void ls_pcie_setup_ctrl(struct ls_pcie *pcie) -- cgit v1.1 From 282d992e1a66ecd8e8cca74e0759b7e5b6516e40 Mon Sep 17 00:00:00 2001 From: Hou Zhiqiang Date: Tue, 17 Dec 2019 10:10:43 +0000 Subject: pci: layerscape: Fix the BARs disable function There is not any difference for disabling BARs in RC mode between PCIe controllers with and without SRIOV. Fixes: 80afc63fc342 ("pci: layerscape: add pci driver based on DM") Signed-off-by: Hou Zhiqiang Reviewed-by: Priyanka Jain --- drivers/pci/pcie_layerscape.c | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/pcie_layerscape.c b/drivers/pci/pcie_layerscape.c index 22d10cf..2ab67d1 100644 --- a/drivers/pci/pcie_layerscape.c +++ b/drivers/pci/pcie_layerscape.c @@ -312,17 +312,6 @@ static void ls_pcie_drop_msg_tlp(struct ls_pcie *pcie) /* Disable all bars in RC mode */ static void ls_pcie_disable_bars(struct ls_pcie *pcie) { - u32 sriov; - - sriov = in_le32(pcie->dbi + PCIE_SRIOV); - - /* - * TODO: For PCIe controller with SRIOV, the method to disable bars - * is different and more complex, so will add later. - */ - if (PCI_EXT_CAP_ID(sriov) == PCI_EXT_CAP_ID_SRIOV) - return; - 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); -- cgit v1.1 From ee5c70b8f74e4676327c9415cb8a36a7a7f35d8f Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Fri, 20 Dec 2019 14:16:47 +0100 Subject: drivers: net: fsl_enetc: use write_hwaddr() Intead of setting the MAC address in enetc_start() use the proper write_hwaddr(). U-Boot takes care of the random MAC address, too. Signed-off-by: Michael Walle Signed-off-by: Alex Marginean Reviewed-by: Priyanka Jain --- drivers/net/fsl_enetc.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/fsl_enetc.c b/drivers/net/fsl_enetc.c index f8fe7d4..7c0ed9f 100644 --- a/drivers/net/fsl_enetc.c +++ b/drivers/net/fsl_enetc.c @@ -330,14 +330,19 @@ static int enetc_remove(struct udevice *dev) return 0; } -/* ENETC Port MAC address registers, accepts big-endian format */ -static void enetc_set_primary_mac_addr(struct enetc_priv *priv, const u8 *addr) +static int enetc_write_hwaddr(struct udevice *dev) { + struct eth_pdata *plat = dev_get_platdata(dev); + struct enetc_priv *priv = dev_get_priv(dev); + u8 *addr = plat->enetaddr; + u16 lower = *(const u16 *)(addr + 4); u32 upper = *(const u32 *)addr; enetc_write_port(priv, ENETC_PSIPMAR0, upper); enetc_write_port(priv, ENETC_PSIPMAR1, lower); + + return 0; } /* Configure port parameters (# of rings, frame size, enable port) */ @@ -468,7 +473,6 @@ static void enetc_setup_rx_bdr(struct udevice *dev) */ static int enetc_start(struct udevice *dev) { - struct eth_pdata *plat = dev_get_platdata(dev); struct enetc_priv *priv = dev_get_priv(dev); /* reset and enable the PCI device */ @@ -476,12 +480,6 @@ static int enetc_start(struct udevice *dev) dm_pci_clrset_config16(dev, PCI_COMMAND, 0, PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); - if (!is_valid_ethaddr(plat->enetaddr)) { - enetc_dbg(dev, "invalid MAC address, generate random ...\n"); - net_random_ethaddr(plat->enetaddr); - } - enetc_set_primary_mac_addr(priv, plat->enetaddr); - enetc_enable_si_port(priv); /* setup Tx/Rx buffer descriptors */ @@ -611,6 +609,7 @@ static const struct eth_ops enetc_ops = { .send = enetc_send, .recv = enetc_recv, .stop = enetc_stop, + .write_hwaddr = enetc_write_hwaddr, }; U_BOOT_DRIVER(eth_enetc) = { -- cgit v1.1 From 42c66f057f6f35b4e3463a4ba37c7460cab48964 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Fri, 20 Dec 2019 14:16:48 +0100 Subject: drivers: net: fsl_enetc: add write_hwaddr() for LS1028A The LS1028A SoC is special in the handling of the MAC addresses. We need to write to the IERB version of the PSIPMAR0/1 register. This value will be sampled into the corresponding port PSIPMAR0/1 register if the PCI memory access is enabled. Signed-off-by: Michael Walle Signed-off-by: Alex Marginean Reviewed-by: Priyanka Jain --- drivers/net/fsl_enetc.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'drivers') diff --git a/drivers/net/fsl_enetc.c b/drivers/net/fsl_enetc.c index 7c0ed9f..2ffab1b 100644 --- a/drivers/net/fsl_enetc.c +++ b/drivers/net/fsl_enetc.c @@ -330,12 +330,50 @@ static int enetc_remove(struct udevice *dev) return 0; } +/* + * LS1028A is the only part with IERB at this time and there are plans to + * change its structure, keep this LS1028A specific for now. + */ +#define LS1028A_IERB_BASE 0x1f0800000ULL +#define LS1028A_IERB_PSIPMAR0(pf, vf) (LS1028A_IERB_BASE + 0x8000 \ + + (pf) * 0x100 + (vf) * 8) +#define LS1028A_IERB_PSIPMAR1(pf, vf) (LS1028A_IERB_PSIPMAR0(pf, vf) + 4) + +static int enetc_ls1028a_write_hwaddr(struct udevice *dev) +{ + struct pci_child_platdata *ppdata = dev_get_parent_platdata(dev); + const int devfn_to_pf[] = {0, 1, 2, -1, -1, -1, 3}; + struct eth_pdata *plat = dev_get_platdata(dev); + int devfn = PCI_FUNC(ppdata->devfn); + u8 *addr = plat->enetaddr; + u32 lower, upper; + int pf; + + if (devfn >= ARRAY_SIZE(devfn_to_pf)) + return 0; + + pf = devfn_to_pf[devfn]; + if (pf < 0) + return 0; + + lower = *(const u16 *)(addr + 4); + upper = *(const u32 *)addr; + + out_le32(LS1028A_IERB_PSIPMAR0(pf, 0), upper); + out_le32(LS1028A_IERB_PSIPMAR1(pf, 0), lower); + + return 0; +} + static int enetc_write_hwaddr(struct udevice *dev) { struct eth_pdata *plat = dev_get_platdata(dev); struct enetc_priv *priv = dev_get_priv(dev); u8 *addr = plat->enetaddr; + if (IS_ENABLED(CONFIG_ARCH_LS1028A)) + return enetc_ls1028a_write_hwaddr(dev); + u16 lower = *(const u16 *)(addr + 4); u32 upper = *(const u32 *)addr; -- cgit v1.1 From 1185b229cca55a5ce3ee7bb35b203f788254f1a1 Mon Sep 17 00:00:00 2001 From: Wasim Khan Date: Mon, 6 Jan 2020 12:05:57 +0000 Subject: pci: layerscape: Common device tree fixup for NXP SoCs Add Common device tree fixup for NXP SoCs. Based on SoC and revision call pcie_layerscape or pcie_layerscape_gen4 fixup. Signed-off-by: Wasim Khan Reviewed-by: Priyanka Jain --- drivers/pci/Makefile | 5 +++-- drivers/pci/pcie_layerscape_fixup.c | 7 ++++--- drivers/pci/pcie_layerscape_fixup_common.c | 27 +++++++++++++++++++++++++++ drivers/pci/pcie_layerscape_fixup_common.h | 20 ++++++++++++++++++++ drivers/pci/pcie_layerscape_gen4_fixup.c | 7 ++++--- 5 files changed, 58 insertions(+), 8 deletions(-) create mode 100644 drivers/pci/pcie_layerscape_fixup_common.c create mode 100644 drivers/pci/pcie_layerscape_fixup_common.h (limited to 'drivers') diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 8a33eb0..c051ecc 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -34,9 +34,10 @@ 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_fixup.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 pcie_layerscape.o + pcie_layerscape_gen4_fixup.o \ + pcie_layerscape_fixup_common.o obj-$(CONFIG_PCI_XILINX) += pcie_xilinx.o obj-$(CONFIG_PCI_PHYTIUM) += pcie_phytium.o obj-$(CONFIG_PCIE_INTEL_FPGA) += pcie_intel_fpga.o diff --git a/drivers/pci/pcie_layerscape_fixup.c b/drivers/pci/pcie_layerscape_fixup.c index 27ef20d..e77404c 100644 --- a/drivers/pci/pcie_layerscape_fixup.c +++ b/drivers/pci/pcie_layerscape_fixup.c @@ -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 */ @@ -17,6 +17,7 @@ #include #endif #include "pcie_layerscape.h" +#include "pcie_layerscape_fixup_common.h" #if defined(CONFIG_FSL_LSCH3) || defined(CONFIG_FSL_LSCH2) /* @@ -271,7 +272,7 @@ static void ft_pcie_ls_setup(void *blob, struct ls_pcie *pcie) } /* Fixup Kernel DT for PCIe */ -void ft_pci_setup(void *blob, bd_t *bd) +void ft_pci_setup_ls(void *blob, bd_t *bd) { struct ls_pcie *pcie; @@ -284,7 +285,7 @@ void ft_pci_setup(void *blob, bd_t *bd) } #else /* !CONFIG_OF_BOARD_SETUP */ -void ft_pci_setup(void *blob, bd_t *bd) +void ft_pci_setup_ls(void *blob, bd_t *bd) { } #endif diff --git a/drivers/pci/pcie_layerscape_fixup_common.c b/drivers/pci/pcie_layerscape_fixup_common.c new file mode 100644 index 0000000..b32236e --- /dev/null +++ b/drivers/pci/pcie_layerscape_fixup_common.c @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2019-2020 NXP + * + * PCIe DT fixup for NXP Layerscape SoCs + * Author: Wasim Khan + * + */ + +#include +#include +#include +#include "pcie_layerscape_fixup_common.h" + +void ft_pci_setup(void *blob, bd_t *bd) +{ +#if defined(CONFIG_PCIE_LAYERSCAPE_GEN4) + uint svr; + + svr = SVR_SOC_VER(get_svr()); + + if (svr == SVR_LX2160A && IS_SVR_REV(get_svr(), 1, 0)) + ft_pci_setup_ls_gen4(blob, bd); + else +#endif /* CONFIG_PCIE_LAYERSCAPE_GEN4 */ + ft_pci_setup_ls(blob, bd); +} diff --git a/drivers/pci/pcie_layerscape_fixup_common.h b/drivers/pci/pcie_layerscape_fixup_common.h new file mode 100644 index 0000000..be729b6 --- /dev/null +++ b/drivers/pci/pcie_layerscape_fixup_common.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2019-2020 NXP + * + * PCIe DT fixup for NXP Layerscape SoCs + * Author: Wasim Khan + * + */ +#ifndef _PCIE_LAYERSCAPE_FIXUP_COMMON_H_ +#define _PCIE_LAYERSCAPE_FIXUP_COMMON_H_ + +#include + +void ft_pci_setup_ls(void *blob, bd_t *bd); + +#ifdef CONFIG_PCIE_LAYERSCAPE_GEN4 +void ft_pci_setup_ls_gen4(void *blob, bd_t *bd); +#endif /* CONFIG_PCIE_LAYERSCAPE_GEN4 */ + +#endif //_PCIE_LAYERSCAPE_FIXUP_COMMON_H_ diff --git a/drivers/pci/pcie_layerscape_gen4_fixup.c b/drivers/pci/pcie_layerscape_gen4_fixup.c index da98171..b99ab0f 100644 --- a/drivers/pci/pcie_layerscape_gen4_fixup.c +++ b/drivers/pci/pcie_layerscape_gen4_fixup.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ OR X11 /* - * Copyright 2018-2019 NXP + * Copyright 2018-2020 NXP * * PCIe Gen4 driver for NXP Layerscape SoCs * Author: Hou Zhiqiang @@ -19,6 +19,7 @@ #include #endif #include "pcie_layerscape_gen4.h" +#include "pcie_layerscape_fixup_common.h" #if defined(CONFIG_FSL_LSCH3) || defined(CONFIG_FSL_LSCH2) /* @@ -234,7 +235,7 @@ static void ft_pcie_layerscape_gen4_setup(void *blob, struct ls_pcie_g4 *pcie) } /* Fixup Kernel DT for PCIe */ -void ft_pci_setup(void *blob, bd_t *bd) +void ft_pci_setup_ls_gen4(void *blob, bd_t *bd) { struct ls_pcie_g4 *pcie; @@ -247,7 +248,7 @@ void ft_pci_setup(void *blob, bd_t *bd) } #else /* !CONFIG_OF_BOARD_SETUP */ -void ft_pci_setup(void *blob, bd_t *bd) +void ft_pci_setup_ls_gen4(void *blob, bd_t *bd) { } #endif -- cgit v1.1 From d20eb7a6db2e297cd16a85cdbef9c183abdade1c Mon Sep 17 00:00:00 2001 From: Wasim Khan Date: Mon, 6 Jan 2020 12:05:59 +0000 Subject: pci: layerscape: Move streamId allocation to common device tree fixup Move streamId allocation to layerscape common device tree fixup. Calculate streamId based on SoC variant. Signed-off-by: Wasim Khan Reviewed-by: Priyanka Jain --- drivers/pci/pcie_layerscape_fixup.c | 15 +++------------ drivers/pci/pcie_layerscape_fixup_common.c | 24 ++++++++++++++++++++++++ drivers/pci/pcie_layerscape_fixup_common.h | 1 + drivers/pci/pcie_layerscape_gen4_fixup.c | 17 +++-------------- 4 files changed, 31 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/pcie_layerscape_fixup.c b/drivers/pci/pcie_layerscape_fixup.c index e77404c..56de6d9 100644 --- a/drivers/pci/pcie_layerscape_fixup.c +++ b/drivers/pci/pcie_layerscape_fixup.c @@ -31,17 +31,6 @@ static int ls_pcie_next_lut_index(struct ls_pcie *pcie) return -ENOSPC; /* LUT is full */ } -/* returns the next available streamid for pcie, -errno if failed */ -static int ls_pcie_next_streamid(void) -{ - static int next_stream_id = FSL_PEX_STREAM_ID_START; - - if (next_stream_id > FSL_PEX_STREAM_ID_END) - return -EINVAL; - - return next_stream_id++; -} - static void lut_writel(struct ls_pcie *pcie, unsigned int value, unsigned int offset) { @@ -192,10 +181,12 @@ static void fdt_fixup_pcie_ls(void *blob) bus = bus->parent; pcie = dev_get_priv(bus); - streamid = ls_pcie_next_streamid(); + streamid = pcie_next_streamid(pcie->stream_id_cur, pcie->idx); if (streamid < 0) { debug("ERROR: no stream ids free\n"); continue; + } else { + pcie->stream_id_cur++; } index = ls_pcie_next_lut_index(pcie); diff --git a/drivers/pci/pcie_layerscape_fixup_common.c b/drivers/pci/pcie_layerscape_fixup_common.c index b32236e..828dfff 100644 --- a/drivers/pci/pcie_layerscape_fixup_common.c +++ b/drivers/pci/pcie_layerscape_fixup_common.c @@ -25,3 +25,27 @@ void ft_pci_setup(void *blob, bd_t *bd) #endif /* CONFIG_PCIE_LAYERSCAPE_GEN4 */ ft_pci_setup_ls(blob, bd); } + +#if defined(CONFIG_FSL_LAYERSCAPE) +#ifdef CONFIG_ARCH_LX2160A +/* returns the next available streamid for pcie, -errno if failed */ +int pcie_next_streamid(int currentid, int idx) +{ + if (currentid > FSL_PEX_STREAM_ID_END) + return -EINVAL; + + return currentid | ((idx + 1) << 11); +} +#else +/* returns the next available streamid for pcie, -errno if failed */ +int pcie_next_streamid(int currentid, int idx) +{ + static int next_stream_id = FSL_PEX_STREAM_ID_START; + + if (next_stream_id > FSL_PEX_STREAM_ID_END) + return -EINVAL; + + return next_stream_id++; +} +#endif +#endif /* CONFIG_FSL_LAYERSCAPE */ diff --git a/drivers/pci/pcie_layerscape_fixup_common.h b/drivers/pci/pcie_layerscape_fixup_common.h index be729b6..ecf4f44 100644 --- a/drivers/pci/pcie_layerscape_fixup_common.h +++ b/drivers/pci/pcie_layerscape_fixup_common.h @@ -16,5 +16,6 @@ void ft_pci_setup_ls(void *blob, bd_t *bd); #ifdef CONFIG_PCIE_LAYERSCAPE_GEN4 void ft_pci_setup_ls_gen4(void *blob, bd_t *bd); #endif /* CONFIG_PCIE_LAYERSCAPE_GEN4 */ +int pcie_next_streamid(int currentid, int id); #endif //_PCIE_LAYERSCAPE_FIXUP_COMMON_H_ diff --git a/drivers/pci/pcie_layerscape_gen4_fixup.c b/drivers/pci/pcie_layerscape_gen4_fixup.c index b99ab0f..bfe197e 100644 --- a/drivers/pci/pcie_layerscape_gen4_fixup.c +++ b/drivers/pci/pcie_layerscape_gen4_fixup.c @@ -33,19 +33,6 @@ static int ls_pcie_g4_next_lut_index(struct ls_pcie_g4 *pcie) return -ENOSPC; /* LUT is full */ } -/* returns the next available streamid for pcie, -errno if failed */ -static int ls_pcie_g4_next_streamid(struct ls_pcie_g4 *pcie) -{ - int stream_id = pcie->stream_id_cur; - - if (stream_id > FSL_PEX_STREAM_ID_END) - return -EINVAL; - - pcie->stream_id_cur++; - - return stream_id | ((pcie->idx + 1) << 11); -} - /* * Program a single LUT entry */ @@ -162,10 +149,12 @@ static void fdt_fixup_pcie_ls_gen4(void *blob) bus = bus->parent; pcie = dev_get_priv(bus); - streamid = ls_pcie_g4_next_streamid(pcie); + streamid = pcie_next_streamid(pcie->stream_id_cur, pcie->idx); if (streamid < 0) { debug("ERROR: no stream ids free\n"); continue; + } else { + pcie->stream_id_cur++; } index = ls_pcie_g4_next_lut_index(pcie); -- cgit v1.1 From 9c2969e92cdf57c73d6667bed10fa23e3489b055 Mon Sep 17 00:00:00 2001 From: Wasim Khan Date: Mon, 6 Jan 2020 12:06:00 +0000 Subject: pci: layerscape: device tree fixup based on SoC and lx2160a rev1 requires layerscape_gen4 device tree fixup and lx2160a rev2 requires layerscape device tree fixup. Add device tree fixup for lx2160a based on SoC and Version. Signed-off-by: Wasim Khan Reviewed-by: Priyanka Jain --- drivers/pci/pcie_layerscape_fixup.c | 1 + drivers/pci/pcie_layerscape_fixup_common.c | 73 ++++++++++++++++++++++++++++++ drivers/pci/pcie_layerscape_fixup_common.h | 1 + 3 files changed, 75 insertions(+) (limited to 'drivers') diff --git a/drivers/pci/pcie_layerscape_fixup.c b/drivers/pci/pcie_layerscape_fixup.c index 56de6d9..ec6acbb 100644 --- a/drivers/pci/pcie_layerscape_fixup.c +++ b/drivers/pci/pcie_layerscape_fixup.c @@ -207,6 +207,7 @@ static void fdt_fixup_pcie_ls(void *blob) fdt_pcie_set_iommu_map_entry_ls(blob, pcie, bdf >> 8, streamid); } + pcie_board_fix_fdt(blob); } #endif diff --git a/drivers/pci/pcie_layerscape_fixup_common.c b/drivers/pci/pcie_layerscape_fixup_common.c index 828dfff..b010a63 100644 --- a/drivers/pci/pcie_layerscape_fixup_common.c +++ b/drivers/pci/pcie_layerscape_fixup_common.c @@ -27,6 +27,79 @@ void ft_pci_setup(void *blob, bd_t *bd) } #if defined(CONFIG_FSL_LAYERSCAPE) +int lx2_board_fix_fdt(void *fdt) +{ + char *reg_name, *old_str, *new_str; + const char *reg_names; + int names_len, old_str_len, new_str_len, remaining_str_len; + struct str_map { + char *old_str; + char *new_str; + } reg_names_map[] = { + { "csr_axi_slave", "regs" }, + { "config_axi_slave", "config" } + }; + int off = -1, i; + + off = fdt_node_offset_by_compatible(fdt, -1, "fsl,lx2160a-pcie"); + while (off != -FDT_ERR_NOTFOUND) { + fdt_setprop(fdt, off, "compatible", "fsl,ls2088a-pcie", + strlen("fsl,ls2088a-pcie") + 1); + + reg_names = fdt_getprop(fdt, off, "reg-names", &names_len); + if (!reg_names) + continue; + reg_name = (char *)reg_names; + remaining_str_len = names_len - (reg_name - reg_names); + i = 0; + while ((i < ARRAY_SIZE(reg_names_map)) && remaining_str_len) { + old_str = reg_names_map[i].old_str; + new_str = reg_names_map[i].new_str; + old_str_len = strlen(old_str); + new_str_len = strlen(new_str); + if (memcmp(reg_name, old_str, old_str_len) == 0) { + /* first only leave required bytes for new_str + * and copy rest of the string after it + */ + memcpy(reg_name + new_str_len, + reg_name + old_str_len, + remaining_str_len - old_str_len); + + /* Now copy new_str */ + memcpy(reg_name, new_str, new_str_len); + names_len -= old_str_len; + names_len += new_str_len; + i++; + } + + reg_name = memchr(reg_name, '\0', remaining_str_len); + if (!reg_name) + break; + reg_name += 1; + + remaining_str_len = names_len - (reg_name - reg_names); + } + fdt_setprop(fdt, off, "reg-names", reg_names, names_len); + fdt_delprop(fdt, off, "apio-wins"); + fdt_delprop(fdt, off, "ppio-wins"); + off = fdt_node_offset_by_compatible(fdt, off, + "fsl,lx2160a-pcie"); + } + return 0; +} + +int pcie_board_fix_fdt(void *fdt) +{ + uint svr; + + svr = SVR_SOC_VER(get_svr()); + + if (svr == SVR_LX2160A && IS_SVR_REV(get_svr(), 2, 0)) + return lx2_board_fix_fdt(fdt); + + return 0; +} + #ifdef CONFIG_ARCH_LX2160A /* returns the next available streamid for pcie, -errno if failed */ int pcie_next_streamid(int currentid, int idx) diff --git a/drivers/pci/pcie_layerscape_fixup_common.h b/drivers/pci/pcie_layerscape_fixup_common.h index ecf4f44..e1970a5 100644 --- a/drivers/pci/pcie_layerscape_fixup_common.h +++ b/drivers/pci/pcie_layerscape_fixup_common.h @@ -17,5 +17,6 @@ void ft_pci_setup_ls(void *blob, bd_t *bd); void ft_pci_setup_ls_gen4(void *blob, bd_t *bd); #endif /* CONFIG_PCIE_LAYERSCAPE_GEN4 */ int pcie_next_streamid(int currentid, int id); +int pcie_board_fix_fdt(void *fdt); #endif //_PCIE_LAYERSCAPE_FIXUP_COMMON_H_ -- cgit v1.1 From b8e4eec79cb4e4c9a08084050a2111d13aa6a260 Mon Sep 17 00:00:00 2001 From: Alex Marginean Date: Fri, 10 Jan 2020 23:32:20 +0200 Subject: drivers: net: fsl_enetc: fix SXGMII MAC configuration Separate MAC and serdes configuration, MAC configuration must be applied at each enetc_start() as FLR clears it. This restores traffic for ENETC interfaces in USXGMII mode. Signed-off-by: Alex Marginean Reviewed-by: Priyanka Jain --- drivers/net/fsl_enetc.c | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/fsl_enetc.c b/drivers/net/fsl_enetc.c index 2ffab1b..f0d15fe 100644 --- a/drivers/net/fsl_enetc.c +++ b/drivers/net/fsl_enetc.c @@ -185,16 +185,34 @@ static int enetc_init_rgmii(struct udevice *dev) return 0; } -/* set up MAC and serdes for SXGMII */ -static int enetc_init_sxgmii(struct udevice *dev) +/* set up MAC configuration for the given interface type */ +static void enetc_setup_mac_iface(struct udevice *dev) { struct enetc_priv *priv = dev_get_priv(dev); u32 if_mode; - /* set ifmode to (US)XGMII */ - if_mode = enetc_read_port(priv, ENETC_PM_IF_MODE); - if_mode &= ~ENETC_PM_IF_IFMODE_MASK; - enetc_write_port(priv, ENETC_PM_IF_MODE, if_mode); + switch (priv->if_type) { + case PHY_INTERFACE_MODE_RGMII: + case PHY_INTERFACE_MODE_RGMII_ID: + case PHY_INTERFACE_MODE_RGMII_RXID: + case PHY_INTERFACE_MODE_RGMII_TXID: + enetc_init_rgmii(dev); + break; + case PHY_INTERFACE_MODE_XGMII: + case PHY_INTERFACE_MODE_USXGMII: + case PHY_INTERFACE_MODE_XFI: + /* set ifmode to (US)XGMII */ + if_mode = enetc_read_port(priv, ENETC_PM_IF_MODE); + if_mode &= ~ENETC_PM_IF_IFMODE_MASK; + enetc_write_port(priv, ENETC_PM_IF_MODE, if_mode); + break; + }; +} + +/* set up serdes for SXGMII */ +static int enetc_init_sxgmii(struct udevice *dev) +{ + struct enetc_priv *priv = dev_get_priv(dev); if (!enetc_has_imdio(dev)) return 0; @@ -524,11 +542,7 @@ static int enetc_start(struct udevice *dev) enetc_setup_tx_bdr(dev); enetc_setup_rx_bdr(dev); - if (priv->if_type == PHY_INTERFACE_MODE_RGMII || - priv->if_type == PHY_INTERFACE_MODE_RGMII_ID || - priv->if_type == PHY_INTERFACE_MODE_RGMII_RXID || - priv->if_type == PHY_INTERFACE_MODE_RGMII_TXID) - enetc_init_rgmii(dev); + enetc_setup_mac_iface(dev); if (priv->phy) phy_startup(priv->phy); -- cgit v1.1