Ok,if it is drivercode,card should not work with other pci-controllers or these controllers allowing classless devices…
Anyone here have this googlecard running on another pcie-controller and which?
As workaround is in generic framework and i guess driver should work with other controller (class maybe set by any read value) it looks like assignment issue.
I wonder why class is shifted to variable compared with none…maybe the bits for class are not on right position?
I have apply the pci interrupt patch and pci controller splitting dts patch from frank. And I have tested 10PCS WLE900VX, but not all WLE900VX working with R64.
3PCS WLE900VX work perfect with R64.
3PCS WLE900VX can’t detect by R64.
4PCS WLE900VX sometimes work, sometimes can’t detect by R64.
I also think it’s the RESET signal sequence problem, I try to sleep 1000ms before end reset, but it can’t fix all the problem.
static int mtk_pcie_startup_port_v2(struct mtk_pcie_port *port)
{
struct mtk_pcie *pcie = port->pcie;
struct resource *mem = &pcie->mem;
const struct mtk_pcie_soc *soc = port->pcie->soc;
u32 val;
size_t size;
int err;
/* MT7622 platforms need to enable LTSSM and ASPM from PCIe subsys */
if (pcie->base) {
val = readl(pcie->base + PCIE_SYS_CFG_V2);
val |= PCIE_CSR_LTSSM_EN(port->slot) |
PCIE_CSR_ASPM_L1_EN(port->slot);
writel(val, pcie->base + PCIE_SYS_CFG_V2);
}
/* Assert all reset signals */
writel(0, port->base + PCIE_RST_CTRL);
/*
* Enable PCIe link down reset, if link status changed from link up to
* link down, this will reset MAC control registers and configuration
* space.
*/
writel(PCIE_LINKDOWN_RST_EN, port->base + PCIE_RST_CTRL);
if (port->slot == 0){
dev_err(pcie->dev, "pcie port0 sleep 1000ms to wait reset for QCA988X device!!!!\n");
msleep(1000);
}
/* De-assert PHY, PE, PIPE, MAC and configuration reset */
val = readl(port->base + PCIE_RST_CTRL);
val |= PCIE_PHY_RSTB | PCIE_PERSTB | PCIE_PIPE_SRSTB |
PCIE_MAC_SRSTB | PCIE_CRSTB;
writel(val, port->base + PCIE_RST_CTRL);
/* Set up vendor ID and class code */
if (soc->need_fix_class_id) {
val = PCI_VENDOR_ID_MEDIATEK;
writew(val, port->base + PCIE_CONF_VEND_ID);
val = PCI_CLASS_BRIDGE_PCI;
writew(val, port->base + PCIE_CONF_CLASS_ID);
}
/* 100ms timeout value should be enough for Gen1/2 training */
err = readl_poll_timeout(port->base + PCIE_LINK_STATUS_V2, val,
!!(val & PCIE_PORT_LINKUP_V2), 20,
100 * USEC_PER_MSEC);
if (err)
return -ETIMEDOUT;
/* Set INTx mask */
val = readl(port->base + PCIE_INT_MASK);
val &= ~INTX_MASK;
writel(val, port->base + PCIE_INT_MASK);
if (IS_ENABLED(CONFIG_PCI_MSI))
mtk_pcie_enable_msi(port);
/* Set AHB to PCIe translation windows */
size = mem->end - mem->start;
val = lower_32_bits(mem->start) | AHB2PCIE_SIZE(fls(size));
writel(val, port->base + PCIE_AHB_TRANS_BASE0_L);
val = upper_32_bits(mem->start);
writel(val, port->base + PCIE_AHB_TRANS_BASE0_H);
/* Set PCIe to AXI translation memory space.*/
val = fls(0xffffffff) | WIN_ENABLE;
writel(val, port->base + PCIE_AXI_WINDOW0);
return 0;
}
I will try your way, hope it can support WLE900VX.
I have compared the branches 5.4-main and 5.4-dsa w.r.t. the PCIe sources. The memory map range is the same. PCI splitting is also the same.
I am sure it will give me the same memory not claimed issue with 5.4-main.
Additionally if I apply the changes to detect PCIe device with class code 0000 it should give me resource collision error.
I was able to glean through this thread and put together a patch that works, atleast with WLE900VX modules. Thanks to @frank-w (for PCIe split patches) @bourne_hlm (for identifying RESET signal sequence problem - although I find 3000 msecs sleep works better than 1000msec) . I did not try @jasmin patches though. I’ve attached consolidated patch for helping whoever is hitting this problem. This patch is on top of clean, latest openwrt 4.19.101. With this patch, I see WLE900VX is consistently recognized and ath10k driver is coming up successfully. Phew!!!
Can you help me what this register bits indicate. the bit 5 is responsible for resetting the pci port.
For Comparison I have a PCIe Coral inserted in Laptop (ubuntu 16.04 kernel 4.4) Following is the 32 bit value from Laptop 0xe0050804 whereas following is the 32 bit value from R64 0xe0050014
/* Reset the hardware, then quit reset. Called on device open. */ static int apex_reset(struct gasket_dev *gasket_dev) { int ret;
if (bypass_top_level) return 0;
if (!is_gcb_in_reset(gasket_dev)) { /* We are not in reset - toggle the reset bit so as to force * re-init of custom block */ dev_dbg(gasket_dev->dev, “%s: toggle reset\n”, func );
ret = apex_enter_reset(gasket_dev);
if (ret)
return ret;
} ret = apex_quit_reset(gasket_dev);
return ret; }
From this I think it is necessary to reset the PCI driver (apex)when accessed first time.
This happens in laptop but not in R64.
Can anyone pleasehelp me understand this bitwise structure of the gasket(apex) driver and its impact?
I have try many ways to support WLE900VX (QCA9880)on R64, but not success. It seems the R64 reset signal sequence not compatible with QCA9880.
Your splitting-patch can fix the driver crash problem, but can’t fix the pcie probe problem. I think it’s better to use the “pci=nomsi” kernel cmdline.
Is that patch can fix the pcie device probe problem?