summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2026-01-19 13:08:48 -0600
committerTom Rini <[email protected]>2026-01-19 13:08:48 -0600
commit55ca2110d74f8e5a594aecc11ce4103dc73e9e02 (patch)
tree0799796b7890d22ec9bce3451c32c25a4338f42b /drivers
parent8f16767dccffe504eae796ccc0ddf305dbee245e (diff)
parent8a532b5a2219d9e275fd1b9de40391852b30784a (diff)
Merge tag 'xilinx-for-v2026.04-rc1-v2' of https://source.denx.de/u-boot/custodians/u-boot-microblaze
AMD/Xilinx/FPGA changes for v2026.04-rc1 v2 microblaze: - Fix spl_boot_list order versal2: - Fix EMMC distro boot setup - Align distro boot variables with memory layout zynqmp-phy: - Sync with Linux kernel driver zynqmp: - Add verify_auth command - DT sync - Add placing variables to FAT/EXT4 - Enable PCIe driver by default pcie - xilinx-nwl: - Fix Link down crash ufs: - Align clock/reset with DT binding # -----BEGIN PGP SIGNATURE----- # # iHUEABYIAB0WIQSXAixArPbWpRanWW+rB/7wTvUR9QUCaW3p3wAKCRCrB/7wTvUR # 9VkwAP4jPRALpM34VpTimNe/iwigIx8hAHxbvkUU0oJ/DW6W8AEAhCSL+ydgreuv # kKCyNiOF1sm8IrOh4TdtMIFn37d4Dwg= # =AkKK # -----END PGP SIGNATURE----- # gpg: Signature made Mon 19 Jan 2026 02:22:55 AM CST # gpg: using EDDSA key 97022C40ACF6D6A516A7596FAB07FEF04EF511F5 # gpg: Can't check signature: No public key
Diffstat (limited to 'drivers')
-rw-r--r--drivers/pci/pcie-xilinx-nwl.c17
-rw-r--r--drivers/phy/phy-zynqmp.c178
-rw-r--r--drivers/ufs/ufs-amd-versal2.c8
3 files changed, 79 insertions, 124 deletions
diff --git a/drivers/pci/pcie-xilinx-nwl.c b/drivers/pci/pcie-xilinx-nwl.c
index e03ab3be912..ab597c83e47 100644
--- a/drivers/pci/pcie-xilinx-nwl.c
+++ b/drivers/pci/pcie-xilinx-nwl.c
@@ -135,6 +135,13 @@ struct nwl_pcie {
u32 ecam_value;
};
+static bool nwl_pcie_link_up(struct nwl_pcie *pcie)
+{
+ if (readl(pcie->pcireg_base + PS_LINKUP_OFFSET) & PCIE_PHY_LINKUP_BIT)
+ return true;
+ return false;
+}
+
static int nwl_pcie_config_address(const struct udevice *bus,
pci_dev_t bdf, uint offset,
void **paddress)
@@ -142,6 +149,9 @@ static int nwl_pcie_config_address(const struct udevice *bus,
struct nwl_pcie *pcie = dev_get_priv(bus);
void *addr;
+ if (PCI_BUS(bdf) != dev_seq(bus) && !nwl_pcie_link_up(pcie))
+ return -EIO;
+
addr = pcie->ecam_base;
addr += PCIE_ECAM_OFFSET(PCI_BUS(bdf) - dev_seq(bus),
PCI_DEV(bdf), PCI_FUNC(bdf), offset);
@@ -181,13 +191,6 @@ static inline void nwl_bridge_writel(struct nwl_pcie *pcie, u32 val, u32 off)
writel(val, pcie->breg_base + off);
}
-static bool nwl_pcie_link_up(struct nwl_pcie *pcie)
-{
- if (readl(pcie->pcireg_base + PS_LINKUP_OFFSET) & PCIE_PHY_LINKUP_BIT)
- return true;
- return false;
-}
-
static bool nwl_phy_link_up(struct nwl_pcie *pcie)
{
if (readl(pcie->pcireg_base + PS_LINKUP_OFFSET) & PHY_RDY_LINKUP_BIT)
diff --git a/drivers/phy/phy-zynqmp.c b/drivers/phy/phy-zynqmp.c
index 9649e660220..e5181c59f29 100644
--- a/drivers/phy/phy-zynqmp.c
+++ b/drivers/phy/phy-zynqmp.c
@@ -82,7 +82,8 @@
/* Reference clock selection parameters */
#define L0_Ln_REF_CLK_SEL(n) (0x2860 + (n) * 4)
-#define L0_REF_CLK_SEL_MASK 0x8f
+#define L0_REF_CLK_LCL_SEL BIT(7)
+#define L0_REF_CLK_SEL_MASK 0x9f
/* Calibration digital logic parameters */
#define L3_TM_CALIB_DIG19 0xec4c
@@ -149,24 +150,6 @@
/* Total number of controllers */
#define CONTROLLERS_PER_LANE 5
-/* Protocol Type parameters */
-enum {
- XPSGTR_TYPE_USB0 = 0, /* USB controller 0 */
- XPSGTR_TYPE_USB1 = 1, /* USB controller 1 */
- XPSGTR_TYPE_SATA_0 = 2, /* SATA controller lane 0 */
- XPSGTR_TYPE_SATA_1 = 3, /* SATA controller lane 1 */
- XPSGTR_TYPE_PCIE_0 = 4, /* PCIe controller lane 0 */
- XPSGTR_TYPE_PCIE_1 = 5, /* PCIe controller lane 1 */
- XPSGTR_TYPE_PCIE_2 = 6, /* PCIe controller lane 2 */
- XPSGTR_TYPE_PCIE_3 = 7, /* PCIe controller lane 3 */
- XPSGTR_TYPE_DP_0 = 8, /* Display Port controller lane 0 */
- XPSGTR_TYPE_DP_1 = 9, /* Display Port controller lane 1 */
- XPSGTR_TYPE_SGMII0 = 10, /* Ethernet SGMII controller 0 */
- XPSGTR_TYPE_SGMII1 = 11, /* Ethernet SGMII controller 1 */
- XPSGTR_TYPE_SGMII2 = 12, /* Ethernet SGMII controller 2 */
- XPSGTR_TYPE_SGMII3 = 13, /* Ethernet SGMII controller 3 */
-};
-
/* Timeout values */
#define TIMEOUT_US 10000
@@ -195,14 +178,15 @@ struct xpsgtr_ssc {
* struct xpsgtr_phy - representation of a lane
* @dev: pointer to the xpsgtr_dev instance
* @refclk: reference clock index
- * @type: controller which uses this lane
+ * @instance: instance of the protocol type (such as the lane within a
+ * protocol, or the USB/Ethernet controller)
* @lane: lane number
* @protocol: protocol in which the lane operates
*/
struct xpsgtr_phy {
struct xpsgtr_dev *dev;
unsigned int refclk;
- u8 type;
+ u8 instance;
u8 lane;
u8 protocol;
};
@@ -303,11 +287,12 @@ static void xpsgtr_configure_pll(struct xpsgtr_phy *gtr_phy)
PLL_FREQ_MASK, ssc->pll_ref_clk);
/* Enable lane clock sharing, if required */
- if (gtr_phy->refclk != gtr_phy->lane) {
- /* Lane3 Ref Clock Selection Register */
+ if (gtr_phy->refclk == gtr_phy->lane)
+ xpsgtr_clr_set(gtr_phy->dev, L0_Ln_REF_CLK_SEL(gtr_phy->lane),
+ L0_REF_CLK_SEL_MASK, L0_REF_CLK_LCL_SEL);
+ else
xpsgtr_clr_set(gtr_phy->dev, L0_Ln_REF_CLK_SEL(gtr_phy->lane),
L0_REF_CLK_SEL_MASK, 1 << gtr_phy->refclk);
- }
/* SSC step size [7:0] */
xpsgtr_clr_set_phy(gtr_phy, L0_PLL_SS_STEP_SIZE_0_LSB,
@@ -459,8 +444,8 @@ static int xpsgtr_init(struct phy *x)
break;
}
- dev_dbg(gtr_dev->dev, "lane %u (type %u, protocol %u): init done\n",
- gtr_phy->lane, gtr_phy->type, gtr_phy->protocol);
+ dev_dbg(gtr_dev->dev, "lane %u (protocol %u, instance %u): init done\n",
+ gtr_phy->lane, gtr_phy->protocol, gtr_phy->instance);
return 0;
}
@@ -469,15 +454,32 @@ static int xpsgtr_init(struct phy *x)
static int xpsgtr_wait_pll_lock(struct phy *phy)
{
struct xpsgtr_dev *gtr_dev = dev_get_priv(phy->dev);
- struct xpsgtr_phy *gtr_phy;
- u32 phy_lane = phy->id;
- int ret = 0;
+ struct xpsgtr_phy *gtr_phy = &gtr_dev->phys[phy->id];
unsigned int timeout = TIMEOUT_US;
-
- gtr_phy = &gtr_dev->phys[phy_lane];
+ u8 protocol = gtr_phy->protocol;
+ int ret = 0;
dev_dbg(gtr_dev->dev, "Waiting for PLL lock\n");
+ /*
+ * For DP and PCIe, only the instance 0 PLL is used. Switch to that phy
+ * so we wait on the right PLL.
+ */
+ if ((protocol == ICM_PROTOCOL_DP || protocol == ICM_PROTOCOL_PCIE) &&
+ gtr_phy->instance) {
+ int i;
+
+ for (i = 0; i < NUM_LANES; i++) {
+ gtr_phy = &gtr_dev->phys[i];
+
+ if (gtr_phy->protocol == protocol && !gtr_phy->instance)
+ goto got_phy;
+ }
+
+ return -EBUSY;
+ }
+
+got_phy:
while (1) {
u32 reg = xpsgtr_read_phy(gtr_phy, L0_PLL_STATUS_READ_1);
@@ -496,104 +498,48 @@ static int xpsgtr_wait_pll_lock(struct phy *phy)
if (ret == -ETIMEDOUT)
dev_err(gtr_dev->dev,
- "lane %u (type %u, protocol %u): PLL lock timeout\n",
- gtr_phy->lane, gtr_phy->type, gtr_phy->protocol);
+ "lane %u (protocol %u, instance %u): PLL lock timeout\n",
+ gtr_phy->lane, gtr_phy->protocol, gtr_phy->protocol);
return ret;
}
static int xpsgtr_power_on(struct phy *phy)
{
- struct xpsgtr_dev *gtr_dev = dev_get_priv(phy->dev);
- struct xpsgtr_phy *gtr_phy;
- u32 phy_lane = phy->id;
- int ret = 0;
-
- gtr_phy = &gtr_dev->phys[phy_lane];
-
- /*
- * Wait for the PLL to lock. For DP, only wait on DP0 to avoid
- * cumulating waits for both lanes. The user is expected to initialize
- * lane 0 last.
- */
- if (gtr_phy->protocol != ICM_PROTOCOL_DP ||
- gtr_phy->type == XPSGTR_TYPE_DP_0)
- ret = xpsgtr_wait_pll_lock(phy);
-
- return ret;
+ return xpsgtr_wait_pll_lock(phy);
}
/*
* OF Xlate Support
*/
-/* Set the lane type and protocol based on the PHY type and instance number. */
+/* Set the lane protocol and instance based on the PHY type and instance number. */
static int xpsgtr_set_lane_type(struct xpsgtr_phy *gtr_phy, u8 phy_type,
unsigned int phy_instance)
{
unsigned int num_phy_types;
- const int *phy_types;
switch (phy_type) {
- case PHY_TYPE_SATA: {
- static const int types[] = {
- XPSGTR_TYPE_SATA_0,
- XPSGTR_TYPE_SATA_1,
- };
-
- phy_types = types;
- num_phy_types = ARRAY_SIZE(types);
+ case PHY_TYPE_SATA:
+ num_phy_types = 2;
gtr_phy->protocol = ICM_PROTOCOL_SATA;
break;
- }
- case PHY_TYPE_USB3: {
- static const int types[] = {
- XPSGTR_TYPE_USB0,
- XPSGTR_TYPE_USB1,
- };
-
- phy_types = types;
- num_phy_types = ARRAY_SIZE(types);
+ case PHY_TYPE_USB3:
+ num_phy_types = 2;
gtr_phy->protocol = ICM_PROTOCOL_USB;
break;
- }
- case PHY_TYPE_DP: {
- static const int types[] = {
- XPSGTR_TYPE_DP_0,
- XPSGTR_TYPE_DP_1,
- };
-
- phy_types = types;
- num_phy_types = ARRAY_SIZE(types);
+ case PHY_TYPE_DP:
+ num_phy_types = 2;
gtr_phy->protocol = ICM_PROTOCOL_DP;
break;
- }
- case PHY_TYPE_PCIE: {
- static const int types[] = {
- XPSGTR_TYPE_PCIE_0,
- XPSGTR_TYPE_PCIE_1,
- XPSGTR_TYPE_PCIE_2,
- XPSGTR_TYPE_PCIE_3,
- };
-
- phy_types = types;
- num_phy_types = ARRAY_SIZE(types);
+ case PHY_TYPE_PCIE:
+ num_phy_types = 4;
gtr_phy->protocol = ICM_PROTOCOL_PCIE;
break;
- }
- case PHY_TYPE_SGMII: {
- static const int types[] = {
- XPSGTR_TYPE_SGMII0,
- XPSGTR_TYPE_SGMII1,
- XPSGTR_TYPE_SGMII2,
- XPSGTR_TYPE_SGMII3,
- };
-
- phy_types = types;
- num_phy_types = ARRAY_SIZE(types);
+ case PHY_TYPE_SGMII:
+ num_phy_types = 4;
gtr_phy->protocol = ICM_PROTOCOL_SGMII;
break;
- }
default:
return -EINVAL;
}
@@ -601,22 +547,25 @@ static int xpsgtr_set_lane_type(struct xpsgtr_phy *gtr_phy, u8 phy_type,
if (phy_instance >= num_phy_types)
return -EINVAL;
- gtr_phy->type = phy_types[phy_instance];
+ gtr_phy->instance = phy_instance;
return 0;
}
/*
- * Valid combinations of controllers and lanes (Interconnect Matrix).
+ * Valid combinations of controllers and lanes (Interconnect Matrix). Each
+ * "instance" represents one controller for a lane. For PCIe and DP, the
+ * "instance" is the logical lane in the link. For SATA, USB, and SGMII,
+ * the instance is the index of the controller.
+ *
+ * This information is only used to validate the devicetree reference, and is
+ * not used when programming the hardware.
*/
static const unsigned int icm_matrix[NUM_LANES][CONTROLLERS_PER_LANE] = {
- { XPSGTR_TYPE_PCIE_0, XPSGTR_TYPE_SATA_0, XPSGTR_TYPE_USB0,
- XPSGTR_TYPE_DP_1, XPSGTR_TYPE_SGMII0 },
- { XPSGTR_TYPE_PCIE_1, XPSGTR_TYPE_SATA_1, XPSGTR_TYPE_USB0,
- XPSGTR_TYPE_DP_0, XPSGTR_TYPE_SGMII1 },
- { XPSGTR_TYPE_PCIE_2, XPSGTR_TYPE_SATA_0, XPSGTR_TYPE_USB0,
- XPSGTR_TYPE_DP_1, XPSGTR_TYPE_SGMII2 },
- { XPSGTR_TYPE_PCIE_3, XPSGTR_TYPE_SATA_1, XPSGTR_TYPE_USB1,
- XPSGTR_TYPE_DP_0, XPSGTR_TYPE_SGMII3 }
+ /* PCIe, SATA, USB, DP, SGMII */
+ { 0, 0, 0, 1, 0 }, /* Lane 0 */
+ { 1, 1, 0, 0, 1 }, /* Lane 1 */
+ { 2, 0, 0, 1, 2 }, /* Lane 2 */
+ { 3, 1, 1, 0, 3 }, /* Lane 3 */
};
/* Translate OF phandle and args to PHY instance. */
@@ -676,7 +625,7 @@ static int xpsgtr_of_xlate(struct phy *x,
* is allowed to operate on the lane.
*/
for (i = 0; i < CONTROLLERS_PER_LANE; i++) {
- if (icm_matrix[phy_lane][i] == gtr_phy->type) {
+ if (icm_matrix[phy_lane][i] == gtr_phy->instance) {
x->id = phy_lane;
return 0;
}
@@ -725,7 +674,10 @@ static int xpsgtr_get_ref_clocks(struct udevice *dev)
}
for (i = 0 ; i < ARRAY_SIZE(ssc_lookup); i++) {
- if (rate == ssc_lookup[i].refclk_rate) {
+ /* Allow an error of 100 ppm */
+ unsigned long error = ssc_lookup[i].refclk_rate / 10000;
+
+ if (abs(rate - ssc_lookup[i].refclk_rate) < error) {
gtr_dev->refclk_sscs[refclk] = &ssc_lookup[i];
dev_dbg(dev, "Found rate %d\n", i);
break;
diff --git a/drivers/ufs/ufs-amd-versal2.c b/drivers/ufs/ufs-amd-versal2.c
index bf23439e59d..dd62c9819ba 100644
--- a/drivers/ufs/ufs-amd-versal2.c
+++ b/drivers/ufs/ufs-amd-versal2.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/*
- * Copyright (C) 2024 Advanced Micro Devices, Inc.
+ * Copyright (C) 2024-2025 Advanced Micro Devices, Inc.
*/
#include <clk.h>
@@ -305,7 +305,7 @@ static int ufs_versal2_init(struct ufs_hba *hba)
priv->phy_mode = UFSHCD_DWC_PHY_MODE_ROM;
- ret = clk_get_by_name(hba->dev, "core_clk", &clk);
+ ret = clk_get_by_name(hba->dev, "core", &clk);
if (ret) {
dev_err(hba->dev, "failed to get core_clk clock\n");
return ret;
@@ -319,12 +319,12 @@ static int ufs_versal2_init(struct ufs_hba *hba)
}
priv->host_clk = core_clk_rate;
- priv->rstc = devm_reset_control_get(hba->dev, "ufshc-rst");
+ priv->rstc = devm_reset_control_get(hba->dev, "host");
if (IS_ERR(priv->rstc)) {
dev_err(hba->dev, "failed to get reset ctl: ufshc-rst\n");
return PTR_ERR(priv->rstc);
}
- priv->rstphy = devm_reset_control_get(hba->dev, "ufsphy-rst");
+ priv->rstphy = devm_reset_control_get(hba->dev, "phy");
if (IS_ERR(priv->rstphy)) {
dev_err(hba->dev, "failed to get reset ctl: ufsphy-rst\n");
return PTR_ERR(priv->rstphy);