diff options
Diffstat (limited to 'arch/powerpc/sysdev/fsl_pci.c')
| -rw-r--r-- | arch/powerpc/sysdev/fsl_pci.c | 58 | 
1 files changed, 37 insertions, 21 deletions
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index 61e6d77efa4..5b264eb4b1f 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -1,7 +1,7 @@  /* - * MPC85xx/86xx PCI/PCIE support routing. + * MPC83xx/85xx/86xx PCI/PCIE support routing.   * - * Copyright 2007 Freescale Semiconductor, Inc + * Copyright 2007,2008 Freescale Semiconductor, Inc   *   * Initial author: Xianghua Xiao <x.xiao@freescale.com>   * Recode: ZHANG WEI <wei.zhang@freescale.com> @@ -251,20 +251,47 @@ DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8641D, quirk_fsl_pcie_header);  DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8610, quirk_fsl_pcie_header);  #endif /* CONFIG_PPC_85xx || CONFIG_PPC_86xx */ -#if defined(CONFIG_PPC_83xx) +#if defined(CONFIG_PPC_83xx) || defined(CONFIG_PPC_MPC512x)  int __init mpc83xx_add_bridge(struct device_node *dev)  {  	int len;  	struct pci_controller *hose; -	struct resource rsrc; +	struct resource rsrc_reg; +	struct resource rsrc_cfg;  	const int *bus_range; -	int primary = 1, has_address = 0; -	phys_addr_t immr = get_immrbase(); +	int primary;  	pr_debug("Adding PCI host bridge %s\n", dev->full_name);  	/* Fetch host bridge registers address */ -	has_address = (of_address_to_resource(dev, 0, &rsrc) == 0); +	if (of_address_to_resource(dev, 0, &rsrc_reg)) { +		printk(KERN_WARNING "Can't get pci register base!\n"); +		return -ENOMEM; +	} + +	memset(&rsrc_cfg, 0, sizeof(rsrc_cfg)); + +	if (of_address_to_resource(dev, 1, &rsrc_cfg)) { +		printk(KERN_WARNING +			"No pci config register base in dev tree, " +			"using default\n"); +		/* +		 * MPC83xx supports up to two host controllers +		 * 	one at 0x8500 has config space registers at 0x8300 +		 * 	one at 0x8600 has config space registers at 0x8380 +		 */ +		if ((rsrc_reg.start & 0xfffff) == 0x8500) +			rsrc_cfg.start = (rsrc_reg.start & 0xfff00000) + 0x8300; +		else if ((rsrc_reg.start & 0xfffff) == 0x8600) +			rsrc_cfg.start = (rsrc_reg.start & 0xfff00000) + 0x8380; +	} +	/* +	 * Controller at offset 0x8500 is primary +	 */ +	if ((rsrc_reg.start & 0xfffff) == 0x8500) +		primary = 1; +	else +		primary = 0;  	/* Get bus range if any */  	bus_range = of_get_property(dev, "bus-range", &len); @@ -281,22 +308,11 @@ int __init mpc83xx_add_bridge(struct device_node *dev)  	hose->first_busno = bus_range ? bus_range[0] : 0;  	hose->last_busno = bus_range ? bus_range[1] : 0xff; -	/* MPC83xx supports up to two host controllers one at 0x8500 from immrbar -	 * the other at 0x8600, we consider the 0x8500 the primary controller -	 */ -	/* PCI 1 */ -	if ((rsrc.start & 0xfffff) == 0x8500) { -		setup_indirect_pci(hose, immr + 0x8300, immr + 0x8304, 0); -	} -	/* PCI 2 */ -	if ((rsrc.start & 0xfffff) == 0x8600) { -		setup_indirect_pci(hose, immr + 0x8380, immr + 0x8384, 0); -		primary = 0; -	} +	setup_indirect_pci(hose, rsrc_cfg.start, rsrc_cfg.start + 4, 0); -	printk(KERN_INFO "Found MPC83xx PCI host bridge at 0x%016llx. " +	printk(KERN_INFO "Found FSL PCI host bridge at 0x%016llx. "  	       "Firmware bus number: %d->%d\n", -	       (unsigned long long)rsrc.start, hose->first_busno, +	       (unsigned long long)rsrc_reg.start, hose->first_busno,  	       hose->last_busno);  	pr_debug(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n",  | 
