To measure the termination values, the combo PHY calibration also programs the PHY as for PCIe: refclk driver mode, the 24 MHz reference, the 100 MHz output and no spread spectrum, then writes 0xb78 over the whole of PCIE_PU_ADDR_CLK_CFG and CFG_FORCE_RCV_RETRY over the whole of PCIE_RC_DONE_STATUS. 0xb78 includes CFG_SW_PHY_INIT_DONE, so the port A PHY PLL is started in PCIe mode and left running, whatever the combo PHY is used for afterwards. On a board that uses it for USB 3, the PLL is then already running with the PCIe timer and spread-spectrum settings when the USB 3 settings are written.
Linux does none of this. k1_pcie_combo_phy_calibrate() deasserts the PHY reset, clears APP_HOLD_PHY_RST, selects PCIe mode, enables the port A application clocks and resets and waits for R_TUNE_DONE; the PLL is programmed and started only when the PHY is initialised for the mode it is used in. Do the same and drop the PHY register writes from the calibration. Doing so also removes the two whole-register writes, which cleared every other field of those registers. Signed-off-by: Dave Klotz <[email protected]> --- drivers/phy/spacemit/phy-k1-pcie.c | 34 ------------------------------ 1 file changed, 34 deletions(-) diff --git a/drivers/phy/spacemit/phy-k1-pcie.c b/drivers/phy/spacemit/phy-k1-pcie.c index b445ee9d01..734d1f9b4f 100644 --- a/drivers/phy/spacemit/phy-k1-pcie.c +++ b/drivers/phy/spacemit/phy-k1-pcie.c @@ -166,40 +166,6 @@ int k1_pcie_combo_phy_calibrate(struct udevice *dev, struct k1_pcie_phy *k1_phy) /* Put the combo PHY into PCIe mode for calibration */ k1_combo_phy_sel(k1_phy, false); - /* Set refclk override + clear CFG_REFCLK_MODE */ - val = readl(regs + PCIE_LTSSM_DIS_ENTRY); - val |= OVRD_REFCLK_MODE; - writel(val, regs + PCIE_LTSSM_DIS_ENTRY); - - val = readl(regs + PCIE_LTSSM_DIS_ENTRY); - val &= ~CFG_REFCLK_MODE; - writel(val, regs + PCIE_LTSSM_DIS_ENTRY); - - val = readl(regs + PCIE_LTSSM_DIS_ENTRY); - val |= FIELD_PREP(CFG_REFCLK_MODE, RFCLK_MODE_DRIVER); - writel(val, regs + PCIE_LTSSM_DIS_ENTRY); - - /* Configure PLL: select 24MHz reference, enable 100MHz output */ - val = readl(regs + PCIE_PU_PLL_1); - val &= ~(FREF_SEL | REF_100_WSSC); - writel(val, regs + PCIE_PU_PLL_1); - - val = readl(regs + PCIE_PU_PLL_1); - val |= FIELD_PREP(FREF_SEL, FREF_24M); - writel(val, regs + PCIE_PU_PLL_1); - - val = readl(regs + PCIE_PU_PLL_2); - val |= GEN_REF100; - writel(val, regs + PCIE_PU_PLL_2); - - val = readl(regs + PCIE_PU_PLL_1); - val &= ~SSC_DEP_SEL; - writel(val, regs + PCIE_PU_PLL_1); - - /* Start PHY init + force receiver */ - writel(0x00000B78, regs + PCIE_PU_ADDR_CLK_CFG); - writel(CFG_FORCE_RCV_RETRY, regs + PCIE_RC_DONE_STATUS); - /* Wait for calibration to complete */ ret = readl_poll_sleep_timeout(regs + PCIE_RCAL_RESULT, val, val & R_TUNE_DONE, -- 2.55.0
