Revert "PCI: brcmstb: Configure HW CLKREQ# mode appropriate for downstream device"

This reverts commit e2596dcf1e.
This commit is contained in:
Dom Cobley
2024-02-02 13:04:00 +00:00
parent 92d7a7f05f
commit c3733c007c

View File

@@ -48,9 +48,6 @@
#define PCIE_RC_CFG_PRIV1_LINK_CAPABILITY 0x04dc
#define PCIE_RC_CFG_PRIV1_LINK_CAPABILITY_ASPM_SUPPORT_MASK 0xc00
#define PCIE_RC_CFG_PRIV1_ROOT_CAP 0x4f8
#define PCIE_RC_CFG_PRIV1_ROOT_CAP_L1SS_MODE_MASK 0xf8
#define PCIE_RC_DL_MDIO_ADDR 0x1100
#define PCIE_RC_DL_MDIO_WR_DATA 0x1104
#define PCIE_RC_DL_MDIO_RD_DATA 0x1108
@@ -124,12 +121,9 @@
#define PCIE_MISC_HARD_PCIE_HARD_DEBUG 0x4204
#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK 0x2
#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_L1SS_ENABLE_MASK 0x200000
#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK 0x08000000
#define PCIE_BMIPS_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK 0x00800000
#define PCIE_CLKREQ_MASK \
(PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK | \
PCIE_MISC_HARD_PCIE_HARD_DEBUG_L1SS_ENABLE_MASK)
#define PCIE_INTR2_CPU_BASE 0x4300
#define PCIE_MSI_INTR2_BASE 0x4500
@@ -1034,89 +1028,13 @@ static int brcm_pcie_setup(struct brcm_pcie *pcie)
return 0;
}
/*
* This extends the timeout period for an access to an internal bus. This
* access timeout may occur during L1SS sleep periods, even without the
* presence of a PCIe access.
*/
static void brcm_extend_rbus_timeout(struct brcm_pcie *pcie)
{
/* TIMEOUT register is two registers before RGR1_SW_INIT_1 */
const unsigned int REG_OFFSET = PCIE_RGR1_SW_INIT_1(pcie) - 8;
u32 timeout_us = 4000000; /* 4 seconds, our setting for L1SS */
/* Each unit in timeout register is 1/216,000,000 seconds */
writel(216 * timeout_us, pcie->base + REG_OFFSET);
}
static void brcm_config_clkreq(struct brcm_pcie *pcie)
{
static const char err_msg[] = "invalid 'brcm,clkreq-mode' DT string\n";
const char *mode = "default";
u32 clkreq_cntl;
int ret, tmp;
ret = of_property_read_string(pcie->np, "brcm,clkreq-mode", &mode);
if (ret && ret != -EINVAL) {
dev_err(pcie->dev, err_msg);
mode = "safe";
}
/* Start out assuming safe mode (both mode bits cleared) */
clkreq_cntl = readl(pcie->base + PCIE_MISC_HARD_PCIE_HARD_DEBUG);
clkreq_cntl &= ~PCIE_CLKREQ_MASK;
if (strcmp(mode, "no-l1ss") == 0) {
/*
* "no-l1ss" -- Provides Clock Power Management, L0s, and
* L1, but cannot provide L1 substate (L1SS) power
* savings. If the downstream device connected to the RC is
* L1SS capable AND the OS enables L1SS, all PCIe traffic
* may abruptly halt, potentially hanging the system.
*/
clkreq_cntl |= PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK;
/*
* We want to un-advertise L1 substates because if the OS
* tries to configure the controller into using L1 substate
* power savings it may fail or hang when the RC HW is in
* "no-l1ss" mode.
*/
tmp = readl(pcie->base + PCIE_RC_CFG_PRIV1_ROOT_CAP);
u32p_replace_bits(&tmp, 2, PCIE_RC_CFG_PRIV1_ROOT_CAP_L1SS_MODE_MASK);
writel(tmp, pcie->base + PCIE_RC_CFG_PRIV1_ROOT_CAP);
} else if (strcmp(mode, "default") == 0) {
/*
* "default" -- Provides L0s, L1, and L1SS, but not
* compliant to provide Clock Power Management;
* specifically, may not be able to meet the Tclron max
* timing of 400ns as specified in "Dynamic Clock Control",
* section 3.2.5.2.2 of the PCIe spec. This situation is
* atypical and should happen only with older devices.
*/
clkreq_cntl |= PCIE_MISC_HARD_PCIE_HARD_DEBUG_L1SS_ENABLE_MASK;
brcm_extend_rbus_timeout(pcie);
} else {
/*
* "safe" -- No power savings; refclk is driven by RC
* unconditionally.
*/
if (strcmp(mode, "safe") != 0)
dev_err(pcie->dev, err_msg);
mode = "safe";
}
writel(clkreq_cntl, pcie->base + PCIE_MISC_HARD_PCIE_HARD_DEBUG);
dev_info(pcie->dev, "clkreq-mode set to %s\n", mode);
}
static int brcm_pcie_start_link(struct brcm_pcie *pcie)
{
struct device *dev = pcie->dev;
void __iomem *base = pcie->base;
u16 nlw, cls, lnksta;
bool ssc_good = false;
u32 tmp;
int ret, i;
/* Unassert the fundamental reset */
@@ -1141,8 +1059,6 @@ static int brcm_pcie_start_link(struct brcm_pcie *pcie)
return -ENODEV;
}
brcm_config_clkreq(pcie);
if (pcie->gen)
brcm_pcie_set_gen(pcie, pcie->gen);
@@ -1161,6 +1077,14 @@ static int brcm_pcie_start_link(struct brcm_pcie *pcie)
pci_speed_string(pcie_link_speed[cls]), nlw,
ssc_good ? "(SSC)" : "(!SSC)");
/*
* Refclk from RC should be gated with CLKREQ# input when ASPM L0s,L1
* is enabled => setting the CLKREQ_DEBUG_ENABLE field to 1.
*/
tmp = readl(base + PCIE_MISC_HARD_PCIE_HARD_DEBUG);
tmp |= PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK;
writel(tmp, base + PCIE_MISC_HARD_PCIE_HARD_DEBUG);
return 0;
}