summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/dts/armada-375.dtsi2
-rw-r--r--arch/arm/dts/armada-380.dtsi3
-rw-r--r--arch/arm/dts/armada-385.dtsi4
-rw-r--r--arch/arm/dts/armada-xp-98dx3236.dtsi1
-rw-r--r--arch/arm/dts/armada-xp-mv78230.dtsi5
-rw-r--r--arch/arm/dts/armada-xp-mv78260.dtsi9
-rw-r--r--arch/arm/dts/armada-xp-mv78460.dtsi10
-rw-r--r--arch/arm/dts/armada-xp-synology-ds414.dts1
-rw-r--r--arch/arm/dts/armada-xp-theadorable.dts1
-rw-r--r--arch/arm/mach-mvebu/serdes/a38x/Makefile1
-rw-r--r--arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c57
-rw-r--r--arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.h27
-rw-r--r--arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.c19
-rw-r--r--drivers/pci/Kconfig1
-rw-r--r--drivers/pci/pci_mvebu.c43
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) {