Skip to content

Commit 9dd3c7c

Browse files
rwk-gitLorenzo Pieralisi
authored andcommitted
PCI: rockchip: Add poll and timeout to wait for PHY PLLs to be locked
The RK3399 PCIe controller should wait until the PHY PLLs are locked. Add poll and timeout to wait for PHY PLLs to be locked. If they cannot be locked generate error message and jump to error handler. Accessing registers in the PHY clock domain when PLLs are not locked causes hang The PHY PLLs status is checked through a side channel register. This is documented in the TRM section 17.5.8.1 "PCIe Initialization Sequence". Link: https://lore.kernel.org/r/20230418074700.1083505-5-rick.wertenbroek@gmail.com Fixes: cf590b0 ("PCI: rockchip: Add EP driver for Rockchip PCIe controller") Tested-by: Damien Le Moal <dlemoal@kernel.org> Signed-off-by: Rick Wertenbroek <rick.wertenbroek@gmail.com> Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org> Reviewed-by: Damien Le Moal <dlemoal@kernel.org> Cc: stable@vger.kernel.org
1 parent f397fd4 commit 9dd3c7c

File tree

2 files changed

+19
-0
lines changed

2 files changed

+19
-0
lines changed

drivers/pci/controller/pcie-rockchip.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <linux/clk.h>
1515
#include <linux/delay.h>
1616
#include <linux/gpio/consumer.h>
17+
#include <linux/iopoll.h>
1718
#include <linux/of_pci.h>
1819
#include <linux/phy/phy.h>
1920
#include <linux/platform_device.h>
@@ -153,6 +154,12 @@ int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip)
153154
}
154155
EXPORT_SYMBOL_GPL(rockchip_pcie_parse_dt);
155156

157+
#define rockchip_pcie_read_addr(addr) rockchip_pcie_read(rockchip, addr)
158+
/* 100 ms max wait time for PHY PLLs to lock */
159+
#define RK_PHY_PLL_LOCK_TIMEOUT_US 100000
160+
/* Sleep should be less than 20ms */
161+
#define RK_PHY_PLL_LOCK_SLEEP_US 1000
162+
156163
int rockchip_pcie_init_port(struct rockchip_pcie *rockchip)
157164
{
158165
struct device *dev = rockchip->dev;
@@ -254,6 +261,16 @@ int rockchip_pcie_init_port(struct rockchip_pcie *rockchip)
254261
}
255262
}
256263

264+
err = readx_poll_timeout(rockchip_pcie_read_addr,
265+
PCIE_CLIENT_SIDE_BAND_STATUS,
266+
regs, !(regs & PCIE_CLIENT_PHY_ST),
267+
RK_PHY_PLL_LOCK_SLEEP_US,
268+
RK_PHY_PLL_LOCK_TIMEOUT_US);
269+
if (err) {
270+
dev_err(dev, "PHY PLLs could not lock, %d\n", err);
271+
goto err_power_off_phy;
272+
}
273+
257274
/*
258275
* Please don't reorder the deassert sequence of the following
259276
* four reset pins.

drivers/pci/controller/pcie-rockchip.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
#define PCIE_CLIENT_MODE_EP HIWORD_UPDATE(0x0040, 0)
3939
#define PCIE_CLIENT_GEN_SEL_1 HIWORD_UPDATE(0x0080, 0)
4040
#define PCIE_CLIENT_GEN_SEL_2 HIWORD_UPDATE_BIT(0x0080)
41+
#define PCIE_CLIENT_SIDE_BAND_STATUS (PCIE_CLIENT_BASE + 0x20)
42+
#define PCIE_CLIENT_PHY_ST BIT(12)
4143
#define PCIE_CLIENT_DEBUG_OUT_0 (PCIE_CLIENT_BASE + 0x3c)
4244
#define PCIE_CLIENT_DEBUG_LTSSM_MASK GENMASK(5, 0)
4345
#define PCIE_CLIENT_DEBUG_LTSSM_L1 0x18

0 commit comments

Comments
 (0)