Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 59c58c32 authored by Minghuan Lian's avatar Minghuan Lian Committed by Kumar Gala
Browse files

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: default avatarMinghuan Lian <Minghuan.Lian@freescale.com>
Signed-off-by: default avatarRoy Zang <tie-fei.zang@freescale.com>
Signed-off-by: default avatarKumar Gala <galak@kernel.crashing.org>
parent 7844663a
Loading
Loading
Loading
Loading
+24 −13
Original line number Original line Diff line number Diff line
@@ -38,15 +38,15 @@ static int fsl_pcie_bus_fixup, is_mpc83xx_pci;


static void __devinit quirk_fsl_pcie_header(struct pci_dev *dev)
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 we aren't a PCIe don't bother */
	if (!pci_find_capability(dev, PCI_CAP_ID_EXP))
	if (!pci_find_capability(dev, PCI_CAP_ID_EXP))
		return;
		return;


	/* if we aren't in host mode don't bother */
	/* if we aren't in host mode don't bother */
	pci_read_config_byte(dev, PCI_CLASS_PROG, &progif);
	pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type);
	if (progif & 0x1)
	if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE)
		return;
		return;


	dev->class = PCI_CLASS_BRIDGE_PCI << 8;
	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 pci_controller *hose;
	struct resource rsrc;
	struct resource rsrc;
	const int *bus_range;
	const int *bus_range;
	u8 progif;
	u8 hdr_type, progif;


	if (!of_device_is_available(dev)) {
	if (!of_device_is_available(dev)) {
		pr_warning("%s: disabled\n", dev->full_name);
		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,
	setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4,
		PPC_INDIRECT_TYPE_BIG_ENDIAN);
		PPC_INDIRECT_TYPE_BIG_ENDIAN);


	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);
		early_read_config_byte(hose, 0, 0, PCI_CLASS_PROG, &progif);
	if ((progif & 1) == 1) {
		if ((progif & 1) == 1)
		/* unmap cfg_data & cfg_addr separately if not on same page */
			goto no_bridge;
		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;
	}
	}


	setup_pci_cmd(hose);
	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);
	setup_pci_atmu(hose, &rsrc);


	return 0;
	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 */
#endif /* CONFIG_FSL_SOC_BOOKE || CONFIG_PPC_86xx */