diff options
-rw-r--r-- | arch/arm/dts/armada-375.dtsi | 2 | ||||
-rw-r--r-- | arch/arm/dts/armada-380.dtsi | 3 | ||||
-rw-r--r-- | arch/arm/dts/armada-385.dtsi | 4 | ||||
-rw-r--r-- | arch/arm/dts/armada-xp-98dx3236.dtsi | 1 | ||||
-rw-r--r-- | arch/arm/dts/armada-xp-mv78230.dtsi | 5 | ||||
-rw-r--r-- | arch/arm/dts/armada-xp-mv78260.dtsi | 9 | ||||
-rw-r--r-- | arch/arm/dts/armada-xp-mv78460.dtsi | 10 | ||||
-rw-r--r-- | arch/arm/dts/armada-xp-synology-ds414.dts | 1 | ||||
-rw-r--r-- | arch/arm/dts/armada-xp-theadorable.dts | 1 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/serdes/a38x/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c | 57 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.h | 27 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.c | 19 | ||||
-rw-r--r-- | drivers/pci/Kconfig | 1 | ||||
-rw-r--r-- | drivers/pci/pci_mvebu.c | 43 |
15 files changed, 79 insertions, 105 deletions
diff --git a/arch/arm/dts/armada-375.dtsi b/arch/arm/dts/armada-375.dtsi index fdf2d6dbdc8..ff0ad7a9c7f 100644 --- a/arch/arm/dts/armada-375.dtsi +++ b/arch/arm/dts/armada-375.dtsi @@ -617,6 +617,7 @@ marvell,pcie-port = <0>; marvell,pcie-lane = <0>; clocks = <&gateclk 5>; + resets = <&systemc 0 0>; status = "disabled"; }; @@ -635,6 +636,7 @@ marvell,pcie-port = <0>; marvell,pcie-lane = <1>; clocks = <&gateclk 6>; + resets = <&systemc 0 1>; status = "disabled"; }; diff --git a/arch/arm/dts/armada-380.dtsi b/arch/arm/dts/armada-380.dtsi index cff1269f3fb..f3d7f4b27dd 100644 --- a/arch/arm/dts/armada-380.dtsi +++ b/arch/arm/dts/armada-380.dtsi @@ -73,6 +73,7 @@ marvell,pcie-port = <0>; marvell,pcie-lane = <0>; clocks = <&gateclk 8>; + resets = <&systemc 0 0>; status = "disabled"; }; @@ -92,6 +93,7 @@ marvell,pcie-port = <1>; marvell,pcie-lane = <0>; clocks = <&gateclk 5>; + resets = <&systemc 0 1>; status = "disabled"; }; @@ -111,6 +113,7 @@ marvell,pcie-port = <2>; marvell,pcie-lane = <0>; clocks = <&gateclk 6>; + resets = <&systemc 0 2>; status = "disabled"; }; }; diff --git a/arch/arm/dts/armada-385.dtsi b/arch/arm/dts/armada-385.dtsi index f0022d10c71..581a7d9beac 100644 --- a/arch/arm/dts/armada-385.dtsi +++ b/arch/arm/dts/armada-385.dtsi @@ -78,6 +78,7 @@ marvell,pcie-port = <0>; marvell,pcie-lane = <0>; clocks = <&gateclk 8>; + resets = <&systemc 0 0>; status = "disabled"; }; @@ -97,6 +98,7 @@ marvell,pcie-port = <1>; marvell,pcie-lane = <0>; clocks = <&gateclk 5>; + resets = <&systemc 0 1>; status = "disabled"; }; @@ -116,6 +118,7 @@ marvell,pcie-port = <2>; marvell,pcie-lane = <0>; clocks = <&gateclk 6>; + resets = <&systemc 0 2>; status = "disabled"; }; @@ -138,6 +141,7 @@ marvell,pcie-port = <3>; marvell,pcie-lane = <0>; clocks = <&gateclk 7>; + resets = <&systemc 0 3>; status = "disabled"; }; }; diff --git a/arch/arm/dts/armada-xp-98dx3236.dtsi b/arch/arm/dts/armada-xp-98dx3236.dtsi index 8369de79afa..1a48ff3c616 100644 --- a/arch/arm/dts/armada-xp-98dx3236.dtsi +++ b/arch/arm/dts/armada-xp-98dx3236.dtsi @@ -85,6 +85,7 @@ marvell,pcie-port = <0>; marvell,pcie-lane = <0>; clocks = <&gateclk 5>; + resets = <&systemc 0 0>; status = "disabled"; }; }; diff --git a/arch/arm/dts/armada-xp-mv78230.dtsi b/arch/arm/dts/armada-xp-mv78230.dtsi index 8558bf6bb54..63d7f48cf45 100644 --- a/arch/arm/dts/armada-xp-mv78230.dtsi +++ b/arch/arm/dts/armada-xp-mv78230.dtsi @@ -92,6 +92,7 @@ marvell,pcie-port = <0>; marvell,pcie-lane = <0>; clocks = <&gateclk 5>; + resets = <&systemc 0 0>; status = "disabled"; }; @@ -110,6 +111,7 @@ marvell,pcie-port = <0>; marvell,pcie-lane = <1>; clocks = <&gateclk 6>; + resets = <&systemc 0 0>; status = "disabled"; }; @@ -128,6 +130,7 @@ marvell,pcie-port = <0>; marvell,pcie-lane = <2>; clocks = <&gateclk 7>; + resets = <&systemc 0 0>; status = "disabled"; }; @@ -146,6 +149,7 @@ marvell,pcie-port = <0>; marvell,pcie-lane = <3>; clocks = <&gateclk 8>; + resets = <&systemc 0 0>; status = "disabled"; }; @@ -164,6 +168,7 @@ marvell,pcie-port = <1>; marvell,pcie-lane = <0>; clocks = <&gateclk 9>; + resets = <&systemc 0 1>; status = "disabled"; }; }; diff --git a/arch/arm/dts/armada-xp-mv78260.dtsi b/arch/arm/dts/armada-xp-mv78260.dtsi index 2d85fe8ac32..5dc413dd14b 100644 --- a/arch/arm/dts/armada-xp-mv78260.dtsi +++ b/arch/arm/dts/armada-xp-mv78260.dtsi @@ -107,6 +107,7 @@ marvell,pcie-port = <0>; marvell,pcie-lane = <0>; clocks = <&gateclk 5>; + resets = <&systemc 0 0>; status = "disabled"; }; @@ -125,6 +126,7 @@ marvell,pcie-port = <0>; marvell,pcie-lane = <1>; clocks = <&gateclk 6>; + resets = <&systemc 0 0>; status = "disabled"; }; @@ -143,6 +145,7 @@ marvell,pcie-port = <0>; marvell,pcie-lane = <2>; clocks = <&gateclk 7>; + resets = <&systemc 0 0>; status = "disabled"; }; @@ -161,6 +164,7 @@ marvell,pcie-port = <0>; marvell,pcie-lane = <3>; clocks = <&gateclk 8>; + resets = <&systemc 0 0>; status = "disabled"; }; @@ -179,6 +183,7 @@ marvell,pcie-port = <1>; marvell,pcie-lane = <0>; clocks = <&gateclk 9>; + resets = <&systemc 0 1>; status = "disabled"; }; @@ -197,6 +202,7 @@ marvell,pcie-port = <1>; marvell,pcie-lane = <1>; clocks = <&gateclk 10>; + resets = <&systemc 0 1>; status = "disabled"; }; @@ -215,6 +221,7 @@ marvell,pcie-port = <1>; marvell,pcie-lane = <2>; clocks = <&gateclk 11>; + resets = <&systemc 0 1>; status = "disabled"; }; @@ -233,6 +240,7 @@ marvell,pcie-port = <1>; marvell,pcie-lane = <3>; clocks = <&gateclk 12>; + resets = <&systemc 0 1>; status = "disabled"; }; @@ -251,6 +259,7 @@ marvell,pcie-port = <2>; marvell,pcie-lane = <0>; clocks = <&gateclk 26>; + resets = <&systemc 0 2>; status = "disabled"; }; }; diff --git a/arch/arm/dts/armada-xp-mv78460.dtsi b/arch/arm/dts/armada-xp-mv78460.dtsi index 230a3fd36b3..6fbd0ce215f 100644 --- a/arch/arm/dts/armada-xp-mv78460.dtsi +++ b/arch/arm/dts/armada-xp-mv78460.dtsi @@ -128,6 +128,7 @@ marvell,pcie-port = <0>; marvell,pcie-lane = <0>; clocks = <&gateclk 5>; + resets = <&systemc 0 0>; status = "disabled"; }; @@ -146,6 +147,7 @@ marvell,pcie-port = <0>; marvell,pcie-lane = <1>; clocks = <&gateclk 6>; + resets = <&systemc 0 0>; status = "disabled"; }; @@ -164,6 +166,7 @@ marvell,pcie-port = <0>; marvell,pcie-lane = <2>; clocks = <&gateclk 7>; + resets = <&systemc 0 0>; status = "disabled"; }; @@ -182,6 +185,7 @@ marvell,pcie-port = <0>; marvell,pcie-lane = <3>; clocks = <&gateclk 8>; + resets = <&systemc 0 0>; status = "disabled"; }; @@ -200,6 +204,7 @@ marvell,pcie-port = <1>; marvell,pcie-lane = <0>; clocks = <&gateclk 9>; + resets = <&systemc 0 1>; status = "disabled"; }; @@ -218,6 +223,7 @@ marvell,pcie-port = <1>; marvell,pcie-lane = <1>; clocks = <&gateclk 10>; + resets = <&systemc 0 1>; status = "disabled"; }; @@ -236,6 +242,7 @@ marvell,pcie-port = <1>; marvell,pcie-lane = <2>; clocks = <&gateclk 11>; + resets = <&systemc 0 1>; status = "disabled"; }; @@ -254,6 +261,7 @@ marvell,pcie-port = <1>; marvell,pcie-lane = <3>; clocks = <&gateclk 12>; + resets = <&systemc 0 1>; status = "disabled"; }; @@ -272,6 +280,7 @@ marvell,pcie-port = <2>; marvell,pcie-lane = <0>; clocks = <&gateclk 26>; + resets = <&systemc 0 2>; status = "disabled"; }; @@ -290,6 +299,7 @@ marvell,pcie-port = <3>; marvell,pcie-lane = <0>; clocks = <&gateclk 27>; + resets = <&systemc 0 3>; status = "disabled"; }; }; diff --git a/arch/arm/dts/armada-xp-synology-ds414.dts b/arch/arm/dts/armada-xp-synology-ds414.dts index 861967cd7e8..35909e3c69c 100644 --- a/arch/arm/dts/armada-xp-synology-ds414.dts +++ b/arch/arm/dts/armada-xp-synology-ds414.dts @@ -187,6 +187,7 @@ pcie@1,0 { /* Port 0, Lane 0 */ status = "okay"; + num-lanes = <4>; }; /* diff --git a/arch/arm/dts/armada-xp-theadorable.dts b/arch/arm/dts/armada-xp-theadorable.dts index 24cc1cc5278..a06a65af158 100644 --- a/arch/arm/dts/armada-xp-theadorable.dts +++ b/arch/arm/dts/armada-xp-theadorable.dts @@ -214,5 +214,6 @@ pcie@9,0 { /* Port 2, Lane 0 */ status = "okay"; + num-lanes = <4>; }; }; diff --git a/arch/arm/mach-mvebu/serdes/a38x/Makefile b/arch/arm/mach-mvebu/serdes/a38x/Makefile index 917fc1350ce..5a70b375966 100644 --- a/arch/arm/mach-mvebu/serdes/a38x/Makefile +++ b/arch/arm/mach-mvebu/serdes/a38x/Makefile @@ -1,6 +1,5 @@ # SPDX-License-Identifier: GPL-2.0+ -obj-$(CONFIG_SPL_BUILD) = ctrl_pex.o obj-$(CONFIG_SPL_BUILD) += high_speed_env_spec.o obj-$(CONFIG_SPL_BUILD) += high_speed_env_spec-38x.o obj-$(CONFIG_SPL_BUILD) += seq_exec.o diff --git a/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c b/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c deleted file mode 100644 index b3cbddf6a2f..00000000000 --- a/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c +++ /dev/null @@ -1,57 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright (C) Marvell International Ltd. and its affiliates - */ - -#include <common.h> -#include <spl.h> -#include <asm/io.h> -#include <asm/arch/cpu.h> -#include <asm/arch/soc.h> -#include <linux/bitops.h> -#include <linux/delay.h> - -#include "ctrl_pex.h" -#include "sys_env_lib.h" - -int hws_pex_config(const struct serdes_map *serdes_map, u8 count) -{ - enum serdes_type serdes_type; - u32 idx, tmp; - - DEBUG_INIT_FULL_S("\n### hws_pex_config ###\n"); - - tmp = reg_read(SOC_CONTROL_REG1); - tmp &= ~0x03; - - for (idx = 0; idx < count; idx++) { - serdes_type = serdes_map[idx].serdes_type; - if ((serdes_type != PEX0) && - ((serdes_map[idx].serdes_mode == PEX_ROOT_COMPLEX_X4) || - (serdes_map[idx].serdes_mode == PEX_END_POINT_X4))) { - /* for PEX by4 - relevant for the first port only */ - continue; - } - - switch (serdes_type) { - case PEX0: - tmp |= 0x1 << PCIE0_ENABLE_OFFS; - break; - case PEX1: - tmp |= 0x1 << PCIE1_ENABLE_OFFS; - break; - case PEX2: - tmp |= 0x1 << PCIE2_ENABLE_OFFS; - break; - case PEX3: - tmp |= 0x1 << PCIE3_ENABLE_OFFS; - break; - default: - break; - } - } - - reg_write(SOC_CONTROL_REG1, tmp); - - return MV_OK; -} diff --git a/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.h b/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.h deleted file mode 100644 index abdbe3c6604..00000000000 --- a/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.h +++ /dev/null @@ -1,27 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright (C) Marvell International Ltd. and its affiliates - */ - -#ifndef _CTRL_PEX_H -#define _CTRL_PEX_H - -#include <pci.h> -#include "high_speed_env_spec.h" - -/* Direct access to PEX0 Root Port's PCIe Capability structure */ -#define PEX0_RP_PCIE_CFG_OFFSET (0x00080000 + 0x60) - -/* SOC_CONTROL_REG1 fields */ -#define PCIE0_ENABLE_OFFS 0 -#define PCIE0_ENABLE_MASK (0x1 << PCIE0_ENABLE_OFFS) -#define PCIE1_ENABLE_OFFS 1 -#define PCIE1_ENABLE_MASK (0x1 << PCIE1_ENABLE_OFFS) -#define PCIE2_ENABLE_OFFS 2 -#define PCIE2_ENABLE_MASK (0x1 << PCIE2_ENABLE_OFFS) -#define PCIE3_ENABLE_OFFS 3 -#define PCIE4_ENABLE_MASK (0x1 << PCIE3_ENABLE_OFFS) - -int hws_pex_config(const struct serdes_map *serdes_map, u8 count); - -#endif diff --git a/arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.c b/arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.c index 9ba60b57aac..2e467b546d5 100644 --- a/arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.c +++ b/arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.c @@ -12,7 +12,6 @@ #include "high_speed_env_spec.h" #include "sys_env_lib.h" -#include "ctrl_pex.h" /* * serdes_seq_db - holds all serdes sequences, their size and the @@ -1555,9 +1554,6 @@ int hws_power_up_serdes_lanes(struct serdes_map *serdes_map, u8 count) After finish the Power_up sequence for all lanes, the lanes should be released from reset state. */ CHECK_STATUS(hws_pex_tx_config_seq(serdes_map, count)); - - /* PEX configuration */ - CHECK_STATUS(hws_pex_config(serdes_map, count)); } /* USB2 configuration */ @@ -1743,21 +1739,6 @@ int serdes_power_up_ctrl(u32 serdes_num, int serdes_power_up, else reg_data &= ~0x4000; reg_write(SOC_CONTROL_REG1, reg_data); - - /* - * Set Maximum Link Width to X1 or X4 in Root - * Port's PCIe Link Capability register. - * This register is read-only but if is not set - * correctly then access to PCI config space of - * endpoint card behind this Root Port does not - * work. - */ - reg_data = reg_read(PEX0_RP_PCIE_CFG_OFFSET + - PCI_EXP_LNKCAP); - reg_data &= ~PCI_EXP_LNKCAP_MLW; - reg_data |= (is_pex_by1 ? 1 : 4) << 4; - reg_write(PEX0_RP_PCIE_CFG_OFFSET + - PCI_EXP_LNKCAP, reg_data); } CHECK_STATUS(mv_seq_exec(serdes_num, PEX_POWER_UP_SEQ)); diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 42f8cb6be0d..630d6e6cc5e 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -265,6 +265,7 @@ config PCI_MVEBU bool "Enable Armada XP/38x PCIe driver" depends on ARCH_MVEBU select MISC + select DM_RESET help Say Y here if you want to enable PCIe controller support on Armada XP/38x SoCs. diff --git a/drivers/pci/pci_mvebu.c b/drivers/pci/pci_mvebu.c index 55cde2dd83e..b3ea034a284 100644 --- a/drivers/pci/pci_mvebu.c +++ b/drivers/pci/pci_mvebu.c @@ -18,6 +18,7 @@ #include <dm/lists.h> #include <dm/of_access.h> #include <pci.h> +#include <reset.h> #include <asm/io.h> #include <asm/arch/cpu.h> #include <asm/arch/soc.h> @@ -74,6 +75,7 @@ struct mvebu_pcie { u32 intregs; u32 port; u32 lane; + bool is_x4; int devfn; u32 lane_mask; int first_busno; @@ -379,7 +381,30 @@ static void mvebu_pcie_setup_wins(struct mvebu_pcie *pcie) /* Only enable PCIe link, do not setup it */ static int mvebu_pcie_enable_link(struct mvebu_pcie *pcie, ofnode node) { - /* PCIe link is currently automatically enabled in SerDes code */ + struct reset_ctl rst; + int ret; + + ret = reset_get_by_index_nodev(node, 0, &rst); + if (ret == -ENOENT) { + return 0; + } else if (ret < 0) { + printf("%s: cannot get reset controller: %d\n", pcie->name, ret); + return ret; + } + + ret = reset_request(&rst); + if (ret) { + printf("%s: cannot request reset controller: %d\n", pcie->name, ret); + return ret; + } + + ret = reset_deassert(&rst); + reset_free(&rst); + if (ret) { + printf("%s: cannot enable PCIe port: %d\n", pcie->name, ret); + return ret; + } + return 0; } @@ -392,6 +417,18 @@ static void mvebu_pcie_setup_link(struct mvebu_pcie *pcie) reg = readl(pcie->base + PCIE_CTRL_OFF); reg |= PCIE_CTRL_RC_MODE; writel(reg, pcie->base + PCIE_CTRL_OFF); + + /* + * Set Maximum Link Width to X1 or X4 in Root Port's PCIe Link + * Capability register. This register is defined by PCIe specification + * as read-only but this mvebu controller has it as read-write and must + * be set to number of SerDes PCIe lanes (1 or 4). If this register is + * not set correctly then link with endpoint card is not established. + */ + reg = readl(pcie->base + PCIE_CAPAB_OFF + PCI_EXP_LNKCAP); + reg &= ~PCI_EXP_LNKCAP_MLW; + reg |= (pcie->is_x4 ? 4 : 1) << 4; + writel(reg, pcie->base + PCIE_CAPAB_OFF + PCI_EXP_LNKCAP); } static int mvebu_pcie_probe(struct udevice *dev) @@ -582,6 +619,7 @@ static int mvebu_pcie_port_parse_dt(ofnode node, ofnode parent, struct mvebu_pci { struct fdt_pci_addr pci_addr; const u32 *addr; + u32 num_lanes; int ret = 0; int len; @@ -597,6 +635,9 @@ static int mvebu_pcie_port_parse_dt(ofnode node, ofnode parent, struct mvebu_pci sprintf(pcie->name, "pcie%d.%d", pcie->port, pcie->lane); + if (!ofnode_read_u32(node, "num-lanes", &num_lanes) && num_lanes == 4) + pcie->is_x4 = true; + /* devfn is in bits [15:8], see PCI_DEV usage */ ret = ofnode_read_pci_addr(node, FDT_PCI_SPACE_CONFIG, "reg", &pci_addr); if (ret < 0) { |