I recently solved what I believe is a similar if not identical problem. The BSP is not compliant with the RM, as you noticed with respect to issuing type 1 PCI configuration transactions. Here's is how I approached it.
Please see arch/arm/mach-mx6/pcie.c
- Do not use the address shift mode. Use the approach in RM Sec. 48.3.9.2 (rev 0) i.e. PCI bus # is shifted 24 bits.
- The memory mapped register address should be constructed as:
va_address = (u32)base + PCIE_CONF_REG(where);
- Use the iATU to set the appropriate BDF bits (via the target address register (low 32-bits)), i.e.:
atu_bdf_addr = PCIE_CONF_BUS(bus->number) | PCIE_CONF_DEVFN(devfn);
writel(atu_bdf_addr, dbi_base + ATU_REGION_LOW_TRGT_ADDR_R);
-If the bus number is greater than 1: Since PCI-bridges are being traversed, ATU must translate this request to Type-1 Config transaction.
writel(CfgRdWr1, dbi_base + ATU_REGION_CTRL1_R);
- If the bus number is 1 or less: You need to use a type 0 config transaction.
writel(CfgRdWr0, dbi_base + ATU_REGION_CTRL1_R);
I.e. you are updating the iATU configuration for each transaction. I have not included all the changes I had to make, these are just the main ideas. I am not sure how to submit the entire file to this forum, but that would obviously be easier.
Hope this helps,
Nils