Hi everyone,
I am having trouble getting PCIe hotplug to work on my SolidRun ClearFog CX board. I have tried writing to the PCI Express Capabilities Register (0x72) and the PCI Express Slot Capabilities Register (0x84) in u-boot-qoriq, and I have confirmed that the registers are set correctly using the lspci -vvv -s 0000:00:00.0 command.
SltCap: AttnBtn- PwrCtrl- MRL- AttnInd- PwrInd- HotPlug+ Surprise+
Slot #2, PowerLimit 0W; Interlock- NoCompl-
However, despite having HotPlug+ enabled in the SlotCap field, I am not able to get hotplug to work. Neither a hotplug eject nor a hotplug insert is detected by the system.
I am wondering if there is something else I need to do to enable hotplug functionality on this board. If anyone has experience with getting PCIe hotplug working on the ClearFog CX, I would greatly appreciate any advice or guidance you can offer. Thank you in advance for your help.
PS: the patch looks as follows:
diff --git a/drivers/pci/pcie_layerscape_rc.c b/drivers/pci/pcie_layerscape_rc.c
index 17969e2f23..b3fa690a43 100644
--- a/drivers/pci/pcie_layerscape_rc.c
+++ b/drivers/pci/pcie_layerscape_rc.c
@@ -231,6 +231,33 @@ static void ls_pcie_disable_bars(struct ls_pcie_rc *pcie_rc)
dbi_writel(pcie, 0xfffffffe, PCIE_CS2_OFFSET + PCI_ROM_ADDRESS1);
}
+/* Set slot implemented reg in PEX caps */
+static void ls_pcie_fix_slot(struct ls_pcie_rc *pcie_rc)
+{
+ struct ls_pcie *pcie = pcie_rc->pcie;
+
+ u16 val = readw(pcie->dbi + 0x72);
+ val = val | 0b100000000;
+
+ writew(val, pcie->dbi + 0x72);
+}
+
+/* Set slot implemented reg in PEX caps */
+static void ls_pcie_set_slot_caps(struct ls_pcie_rc *pcie_rc)
+{
+ struct ls_pcie *pcie = pcie_rc->pcie;
+
+ u32 oldval = readl(pcie->dbi + 0x84);
+ printf("fooooooo 0x%x foooooooooooooooooooooo\n", oldval);
+ u32 newval = oldval | (0b1 << 5); // set hot-plug surprise
+ newval |= (0b1 << 6); // set hot-plug capable
+ printf("set slot id %d\n", pcie->idx);
+ newval |= (pcie->idx & 0b1111111111111) << 19; // set slot number
+ writel(newval, pcie->dbi + 0x84);
+ oldval = readl(pcie->dbi + 0x84);
+ printf("baaaaaar 0x%x baaaaaaaaaaaaaaaaaaaaar\n", oldval);
+}
+
static void ls_pcie_setup_ctrl(struct ls_pcie_rc *pcie_rc)
{
struct ls_pcie *pcie = pcie_rc->pcie;
@@ -241,6 +268,8 @@ static void ls_pcie_setup_ctrl(struct ls_pcie_rc *pcie_rc)
ls_pcie_fix_class(pcie_rc);
ls_pcie_clear_multifunction(pcie_rc);
ls_pcie_drop_msg_tlp(pcie_rc);
+ ls_pcie_fix_slot(pcie_rc);
+ ls_pcie_set_slot_caps(pcie_rc);
ls_pcie_dbi_ro_wr_dis(pcie);
ls_pcie_disable_bars(pcie_rc);