so, I am working on Linux source (from 2.6.26 to 4.11), and noticed they are full of comments: problems with PCI, most of them located in arch/powerpc.
At some point, they decided they wanted to move to "DeviceTree". Therefore since 2.6.26 we have it, and code changed in a way that ... you have legacy code (things before 2.6.25), and current state of art (things after 2.6.26)
PowerMac still seems to be a stable branch since it depends on OF, so it doesn't require particular care on Device Tree code, everything is already built-in in their OpenFirmware PROM, which provides a decent "early initialization" of the PCI.
Completely different story with embedded boards, like ones have uboot in their prom. In this case uBoot misses special code, as well as linux requires a "boot wrapper", which must be provided and it's platform-specific.
It happens the PCI-code now contains common routines for ppc32 and ppc64 platforms, including PowerMac (PPC32) and pSeries and iSeries brands (PPC64), but for PPC32 machines the probing of PCI controllers from OF_Platform (open firmware) is currently recycled from the 64 bits only, mostly due to gratuitous differences between the 32 and 64 bits PCI code on PowerPC and the 32 bits one lacking some bits needed here.
It's a mess, at the end, it also requires specific code (through patches), which is hard to be maintain so it's often missing if there isn't enough demand for a board.
As consequence, a lot of embedded boards are doomed to stay code-broken until someone has the occasion ( is payed to ) fix things.
Also starting from kernel 3.* they have removed a lot or pre-initialization, assuming the kernel must start with all the hardware already pre-initialized. Well, uBoot v1.4 doesn't. It's not as smart as OpenBIOS or as OpenFirmware.
The chicken or the egg causality dilemma is commonly stated as "which came first: the chicken or the egg?"
Who has to provide the PCI pre-initialization? uboot? or the bootwrapper in linux kernel ?
None of them (in kernel 4) -> the PCI doesn't work
Therefore we have problems! A lot of problems! I had to create a new bootwrapper follows the kernel section. So now, when u-boot attempts to load the image with the 'bootm' command it now extracts the image (the decompression is handled by u-boot) to the $kernel_entry, and then jumps to the bootwrapper start address, located after the kernel image.
The bootwrapper code executes and fixes up a flat device tree for use by the kernel proper, and then jumps the $kernel_entry and the kernel starts up.
before kernel v2.6.25: uboot ----> kernel(@$kernel_entry)
after kernel v2.6.25+: uboot ---> bootwrapper ---> kernel(@kernel_entry)
I had to change Makefiles, linker scripts, Config changes to allow the new Image target, and the boot wrapper also needs to create a correct flat device tree for the target board based off information passed to via the board device structure.
All of the above just to boot the board, and fix the PCI: Crazy!!! Three working weeks gone!
p.s.
and I still have some PCI quirk, but only with PCI_IO, thanks God PCI_MEM is working ..
I am late, will probably try to fix it later. I am not sure I am able to fix. Too damn complex.