During last week I was bringing up PCIe root complex on MX6 Dual application. There is Linux ecosystem, with freescale kernel (3.14.34 line). I found some bugs which I would like to discuss here.
First of all, I was unable to bring up any consumer PCI device. Device detection is successful (I can see device identifier after typing "lspci"), but the driver can't talk to device. Actually writes to BAR are lost and reads return value of 0. After investigation I found there is ATU turned on. Why? I disabled ATU changing imx_pcie_regions_setup function:
writel(0, pp->dbi_base + PCIE_ATU_CR2);
and PCIe devices works now. PCIe works without address translation, all TLPs have just physical address space addresses.
The question is why I wasn't getting exceptions? The answer is pretty simple. Exception handler has been changed in the same pci-imx6.c file, forever. The question is why do we need this? Further analysis shows that access to PCIE_PL_PFLR register generates exception sometimes. Yes, sometimes, only when FORCE_LINK bit is set. And that's not a bug, that's a feature Yes, the controller says we can't trigger FORCE_LINK in current state. The reason is pretty simple and obvious, also MX6Q reference manual clearly states that. During and after reset (configuration), APP_LTSSM_ENABLE must be kept low. We can do it easily changing imx6_pcie_assert_core_reset. The following statement should be added there:
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, IMX6Q_GPR12_PCIE_CTL_2, 0);
Then we can safely remove exception handler. It will just work without exceptions.