powerpc/44x: Fix address decoding setup of PCI 2.x cells
The PCI 2.x cells used on some 44x SoCs only let us configure the decode for the low 32-bit of the incoming PLB addresses. The top 4 bits (this is a 36-bit bus) are hard wired to different values depending on the specific SoC in use. Our code used to work "by accident" until I added support for the ISA memory holes and while at it added more validity checking of the addresses. This patch should bring it back to working condition. It still relies on the device-tree being correct but that's somewhat a pre-requisite for anything to work anyway. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Acked-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com> Acked-by: Josh Boyer <jwboyer@linux.vnet.ibm.com>
This commit is contained in:
Родитель
64e71303e4
Коммит
1ac00cc213
|
@ -204,6 +204,23 @@ static int __init ppc4xx_setup_one_pci_PMM(struct pci_controller *hose,
|
||||||
{
|
{
|
||||||
u32 ma, pcila, pciha;
|
u32 ma, pcila, pciha;
|
||||||
|
|
||||||
|
/* Hack warning ! The "old" PCI 2.x cell only let us configure the low
|
||||||
|
* 32-bit of incoming PLB addresses. The top 4 bits of the 36-bit
|
||||||
|
* address are actually hard wired to a value that appears to depend
|
||||||
|
* on the specific SoC. For example, it's 0 on 440EP and 1 on 440EPx.
|
||||||
|
*
|
||||||
|
* The trick here is we just crop those top bits and ignore them when
|
||||||
|
* programming the chip. That means the device-tree has to be right
|
||||||
|
* for the specific part used (we don't print a warning if it's wrong
|
||||||
|
* but on the other hand, you'll crash quickly enough), but at least
|
||||||
|
* this code should work whatever the hard coded value is
|
||||||
|
*/
|
||||||
|
plb_addr &= 0xffffffffull;
|
||||||
|
|
||||||
|
/* Note: Due to the above hack, the test below doesn't actually test
|
||||||
|
* if you address is above 4G, but it tests that address and
|
||||||
|
* (address + size) are both contained in the same 4G
|
||||||
|
*/
|
||||||
if ((plb_addr + size) > 0xffffffffull || !is_power_of_2(size) ||
|
if ((plb_addr + size) > 0xffffffffull || !is_power_of_2(size) ||
|
||||||
size < 0x1000 || (plb_addr & (size - 1)) != 0) {
|
size < 0x1000 || (plb_addr & (size - 1)) != 0) {
|
||||||
printk(KERN_WARNING "%s: Resource out of range\n",
|
printk(KERN_WARNING "%s: Resource out of range\n",
|
||||||
|
|
Загрузка…
Ссылка в новой задаче