mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 18:09:56 +00:00
Revert "PCI: brcmstb: Configure HW CLKREQ# mode appropriate for downstream device"
This reverts commit e2596dcf1e.
This commit is contained in:
@@ -48,9 +48,6 @@
|
|||||||
#define PCIE_RC_CFG_PRIV1_LINK_CAPABILITY 0x04dc
|
#define PCIE_RC_CFG_PRIV1_LINK_CAPABILITY 0x04dc
|
||||||
#define PCIE_RC_CFG_PRIV1_LINK_CAPABILITY_ASPM_SUPPORT_MASK 0xc00
|
#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_ADDR 0x1100
|
||||||
#define PCIE_RC_DL_MDIO_WR_DATA 0x1104
|
#define PCIE_RC_DL_MDIO_WR_DATA 0x1104
|
||||||
#define PCIE_RC_DL_MDIO_RD_DATA 0x1108
|
#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 0x4204
|
||||||
#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK 0x2
|
#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_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK 0x08000000
|
||||||
#define PCIE_BMIPS_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK 0x00800000
|
#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_INTR2_CPU_BASE 0x4300
|
||||||
#define PCIE_MSI_INTR2_BASE 0x4500
|
#define PCIE_MSI_INTR2_BASE 0x4500
|
||||||
@@ -1034,89 +1028,13 @@ static int brcm_pcie_setup(struct brcm_pcie *pcie)
|
|||||||
return 0;
|
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)
|
static int brcm_pcie_start_link(struct brcm_pcie *pcie)
|
||||||
{
|
{
|
||||||
struct device *dev = pcie->dev;
|
struct device *dev = pcie->dev;
|
||||||
void __iomem *base = pcie->base;
|
void __iomem *base = pcie->base;
|
||||||
u16 nlw, cls, lnksta;
|
u16 nlw, cls, lnksta;
|
||||||
bool ssc_good = false;
|
bool ssc_good = false;
|
||||||
|
u32 tmp;
|
||||||
int ret, i;
|
int ret, i;
|
||||||
|
|
||||||
/* Unassert the fundamental reset */
|
/* Unassert the fundamental reset */
|
||||||
@@ -1141,8 +1059,6 @@ static int brcm_pcie_start_link(struct brcm_pcie *pcie)
|
|||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
brcm_config_clkreq(pcie);
|
|
||||||
|
|
||||||
if (pcie->gen)
|
if (pcie->gen)
|
||||||
brcm_pcie_set_gen(pcie, 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,
|
pci_speed_string(pcie_link_speed[cls]), nlw,
|
||||||
ssc_good ? "(SSC)" : "(!SSC)");
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user