powerpc/fsl-pci: use 'Header Type' to identify PCIE mode
The original code uses 'Programming Interface' field to judge if PCIE is EP or RC mode, however, some latest silicons do not support this functionality. According to PCIE specification, 'Header Type' offset 0x0e is used to indicate header type, so change code to use 'Header Type' field to judge PCIE mode. Because FSL PCI controller does not support 'Header Type', patch still uses 'Programming Interface' to identify PCI mode. Signed-off-by: Minghuan Lian <Minghuan.Lian@freescale.com> Signed-off-by: Roy Zang <tie-fei.zang@freescale.com> Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
This commit is contained in:
Родитель
7844663a31
Коммит
59c58c324a
|
@ -38,15 +38,15 @@ static int fsl_pcie_bus_fixup, is_mpc83xx_pci;
|
|||
|
||||
static void __devinit quirk_fsl_pcie_header(struct pci_dev *dev)
|
||||
{
|
||||
u8 progif;
|
||||
u8 hdr_type;
|
||||
|
||||
/* if we aren't a PCIe don't bother */
|
||||
if (!pci_find_capability(dev, PCI_CAP_ID_EXP))
|
||||
return;
|
||||
|
||||
/* if we aren't in host mode don't bother */
|
||||
pci_read_config_byte(dev, PCI_CLASS_PROG, &progif);
|
||||
if (progif & 0x1)
|
||||
pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type);
|
||||
if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE)
|
||||
return;
|
||||
|
||||
dev->class = PCI_CLASS_BRIDGE_PCI << 8;
|
||||
|
@ -427,7 +427,7 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary)
|
|||
struct pci_controller *hose;
|
||||
struct resource rsrc;
|
||||
const int *bus_range;
|
||||
u8 progif;
|
||||
u8 hdr_type, progif;
|
||||
|
||||
if (!of_device_is_available(dev)) {
|
||||
pr_warning("%s: disabled\n", dev->full_name);
|
||||
|
@ -459,15 +459,17 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary)
|
|||
setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4,
|
||||
PPC_INDIRECT_TYPE_BIG_ENDIAN);
|
||||
|
||||
early_read_config_byte(hose, 0, 0, PCI_CLASS_PROG, &progif);
|
||||
if ((progif & 1) == 1) {
|
||||
/* unmap cfg_data & cfg_addr separately if not on same page */
|
||||
if (((unsigned long)hose->cfg_data & PAGE_MASK) !=
|
||||
((unsigned long)hose->cfg_addr & PAGE_MASK))
|
||||
iounmap(hose->cfg_data);
|
||||
iounmap(hose->cfg_addr);
|
||||
pcibios_free_controller(hose);
|
||||
return -ENODEV;
|
||||
if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
|
||||
/* For PCIE read HEADER_TYPE to identify controler mode */
|
||||
early_read_config_byte(hose, 0, 0, PCI_HEADER_TYPE, &hdr_type);
|
||||
if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE)
|
||||
goto no_bridge;
|
||||
|
||||
} else {
|
||||
/* For PCI read PROG to identify controller mode */
|
||||
early_read_config_byte(hose, 0, 0, PCI_CLASS_PROG, &progif);
|
||||
if ((progif & 1) == 1)
|
||||
goto no_bridge;
|
||||
}
|
||||
|
||||
setup_pci_cmd(hose);
|
||||
|
@ -496,6 +498,15 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary)
|
|||
setup_pci_atmu(hose, &rsrc);
|
||||
|
||||
return 0;
|
||||
|
||||
no_bridge:
|
||||
/* unmap cfg_data & cfg_addr separately if not on same page */
|
||||
if (((unsigned long)hose->cfg_data & PAGE_MASK) !=
|
||||
((unsigned long)hose->cfg_addr & PAGE_MASK))
|
||||
iounmap(hose->cfg_data);
|
||||
iounmap(hose->cfg_addr);
|
||||
pcibios_free_controller(hose);
|
||||
return -ENODEV;
|
||||
}
|
||||
#endif /* CONFIG_FSL_SOC_BOOKE || CONFIG_PPC_86xx */
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче