Add mpc8641hpcn PCI/PCI-Express platform files.
PATCH v3 6/9 Add mpc8641hpcn PCI/PCI-Express platform files.
Signed-off-by Xianghua Xiao <[email protected]>
Signed-off-by Wei Zhang <[email protected]>
Signed-off-by Haiying Wang <[email protected]>
Signed-off-by Jon Loeliger <[email protected]>
---
arch/powerpc/platforms/86xx/mpc86xx_pcie.c | 173 +++++++++++++++ arch/powerpc/platforms/86xx/pci.c | 325 ++++++++++++++++++++++++++++ 2 files changed, 498 insertions(+), 0 deletions(-)
arch/powerpc/platforms/86xx/mpc86xx_pcie.c new file +173 -0
@@ -0,0 +1,173 @@ +/* +* Support for indirect PCI bridges. +* +* Copyright (C) 1998 Gabriel Paubert. +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version +* 2 of the License, or (at your option) any later version. +* +* "Temporary" MPC8548 Errata file - +* The standard indirect_pci code should work with future silicon versions. +*/ + +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/delay.h> +#include <linux/string.h> +#include <linux/init.h> +#include <linux/bootmem.h> + +#include <asm/io.h> +#include <asm/prom.h> +#include <asm/pci-bridge.h> +#include <asm/machdep.h> + +#include "mpc86xx.h" + +#define PCI_CFG_OUT out_be32 + +/* ERRATA PCI-Ex 14 PCIE Controller timeout */ +#define PCIE_FIX out_be32(hose->cfg_addr+0x4, 0x0400ffff) + + +static int +indirect_read_config_pcie (struct pci_bus *bus,unsigned int devfn,int offset, +int len,u32 *val) +{ +struct pci_controller *hose = bus->sysdata; +volatile void __iomem *cfg_data; +u32 temp; + +if (ppc_md.pci_exclude_device) +if (ppc_md.pci_exclude_device (bus->number, devfn)) +return PCIBIOS_DEVICE_NOT_FOUND ; + +/* Possible artifact of CDCpp50937 needs further investigation */ +if (devfn !=0x0 && bus->number ==0xff ) +return PCIBIOS_DEVICE_NOT_FOUND ; + +PCIE_FIX ; +if (bus->number ==0xff ) { +PCI_CFG_OUT (hose->cfg_addr, + (0x80000000 | ((offset &0xf00 ) <<16 ) | + ((bus->number - hose->bus_offset) <<16 ) + | (devfn <<8 ) | ((offset &0xfc ) ))); + }else { +PCI_CFG_OUT (hose->cfg_addr, + (0x80000001 | ((offset &0xf00 ) <<16 ) | + ((bus->number - hose->bus_offset) <<16 ) + | (devfn <<8 ) | ((offset &0xfc ) ))); + } + +/* +* Note: the caller has already checked that offset is +* suitably aligned and that len is 1, 2 or 4. +*/ +/* ERRATA PCI-Ex 12 - Configuration Address/Data Alignment */ + cfg_data = hose->cfg_data; +PCIE_FIX ; + temp =in_le32 (cfg_data); +switch (len) { +case 1 : + *val = (temp >> (((offset &3 ))*8 )) &0xff ; +break ; +case 2 : + *val = (temp >> (((offset &3 ))*8 )) &0xffff ; +break ; +default : + *val = temp; +break ; + } +return PCIBIOS_SUCCESSFUL ; +} + +static int +indirect_write_config_pcie (struct pci_bus *bus,unsigned int devfn,int offset, +int len,u32 val) +{ +struct pci_controller *hose = bus->sysdata; +volatile void __iomem *cfg_data; +u32 temp; + +if (ppc_md.pci_exclude_device) +if (ppc_md.pci_exclude_device (bus->number, devfn)) +return PCIBIOS_DEVICE_NOT_FOUND ; + +/* Possible artifact of CDCpp50937 needs further investigation */ +if (devfn !=0x0 && bus->number ==0xff ) +return PCIBIOS_DEVICE_NOT_FOUND ; + +PCIE_FIX ; +if (bus->number ==0xff ) { +PCI_CFG_OUT (hose->cfg_addr, + (0x80000000 | ((offset &0xf00 ) <<16 ) | + ((bus->number - hose->bus_offset) <<16 ) + | (devfn <<8 ) | ((offset &0xfc ) ))); + }else { +PCI_CFG_OUT (hose->cfg_addr, + (0x80000001 | ((offset &0xf00 ) <<16 ) | + ((bus->number - hose->bus_offset) <<16 ) + | (devfn <<8 ) | ((offset &0xfc ) ))); + } + +/* +* Note: the caller has already checked that offset is +* suitably aligned and that len is 1, 2 or 4. +*/ +/* ERRATA PCI-Ex 12 - Configuration Address/Data Alignment */ + cfg_data = hose->cfg_data; +switch (len) { +case 1 : +PCIE_FIX ; + temp =in_le32 (cfg_data); + temp = (temp & ~(0xff << ((offset &3 ) *8 ))) | + (val << ((offset &3 ) *8 )); +PCIE_FIX ; +out_le32 (cfg_data, temp); +break ; +case 2 : +PCIE_FIX ; + temp =in_le32 (cfg_data); + temp = (temp & ~(0xffff << ((offset &3 ) *8 ))); + temp |= (val << ((offset &3 ) *8 )) ; +PCIE_FIX ; +out_le32 (cfg_data, temp); +break ; +default : +PCIE_FIX ; +out_le32 (cfg_data, val); +break ; + } +PCIE_FIX ; +return PCIBIOS_SUCCESSFUL ; +} + +static struct pci_ops indirect_pcie_ops = { + indirect_read_config_pcie, + indirect_write_config_pcie +}; + +void __init +setup_indirect_pcie_nomap (struct pci_controller * hose,void __iomem * cfg_addr, +void __iomem * cfg_data) +{ + hose->cfg_addr = cfg_addr; + hose->cfg_data = cfg_data; + hose->ops = &indirect_pcie_ops; +} + +void __init +setup_indirect_pcie (struct pci_controller * hose,u32 cfg_addr,u32 cfg_data) +{ +unsigned long base = cfg_addr &PAGE_MASK ; +void __iomem *mbase, *addr, *data; + + mbase =ioremap (base,PAGE_SIZE ); + addr = mbase + (cfg_addr & ~PAGE_MASK ); +if ((cfg_data &PAGE_MASK ) != base) + mbase =ioremap (cfg_data &PAGE_MASK ,PAGE_SIZE ); + data = mbase + (cfg_data & ~PAGE_MASK ); +setup_indirect_pcie_nomap (hose, addr, data); +}
arch/powerpc/platforms/86xx/pci.c new file +325 -0
325 lines not on this page · raw message