Skip to content

Commit

Permalink
[POWERPC] Added indirect_type to handle variants of PCI ops
Browse files Browse the repository at this point in the history
The generic PCI config ops indirect support for ppc32 covers only two
cases (implicit vs explicit) type 0/1 config cycles via set_cfg_type.
Added a indirect_type bit mask to handle other variants.

Added support for PCI-e extended registers and moved the cfg_type
handling into the bit mask for ARCH=powerpc.  We can also use this to
handle indirect quirks.

Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
  • Loading branch information
Kumar Gala committed Jun 29, 2007
1 parent dfac6fa commit ab0f9ad
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 6 deletions.
22 changes: 16 additions & 6 deletions arch/powerpc/sysdev/indirect_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,22 +33,27 @@ indirect_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
struct pci_controller *hose = bus->sysdata;
volatile void __iomem *cfg_data;
u8 cfg_type = 0;
u32 bus_no;
u32 bus_no, reg;

if (ppc_md.pci_exclude_device)
if (ppc_md.pci_exclude_device(hose, bus->number, devfn))
return PCIBIOS_DEVICE_NOT_FOUND;

if (hose->set_cfg_type)
if (hose->indirect_type & PPC_INDIRECT_TYPE_SET_CFG_TYPE)
if (bus->number != hose->first_busno)
cfg_type = 1;

bus_no = (bus->number == hose->first_busno) ?
hose->self_busno : bus->number;

if (hose->indirect_type & PPC_INDIRECT_TYPE_EXT_REG)
reg = ((offset & 0xf00) << 16) | (offset & 0xfc);
else
reg = offset & 0xfc;

PCI_CFG_OUT(hose->cfg_addr,
(0x80000000 | (bus_no << 16)
| (devfn << 8) | ((offset & 0xfc) | cfg_type)));
| (devfn << 8) | reg | cfg_type));

/*
* Note: the caller has already checked that offset is
Expand Down Expand Up @@ -76,22 +81,27 @@ indirect_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
struct pci_controller *hose = bus->sysdata;
volatile void __iomem *cfg_data;
u8 cfg_type = 0;
u32 bus_no;
u32 bus_no, reg;

if (ppc_md.pci_exclude_device)
if (ppc_md.pci_exclude_device(hose, bus->number, devfn))
return PCIBIOS_DEVICE_NOT_FOUND;

if (hose->set_cfg_type)
if (hose->indirect_type & PPC_INDIRECT_TYPE_SET_CFG_TYPE)
if (bus->number != hose->first_busno)
cfg_type = 1;

bus_no = (bus->number == hose->first_busno) ?
hose->self_busno : bus->number;

if (hose->indirect_type & PPC_INDIRECT_TYPE_EXT_REG)
reg = ((offset & 0xf00) << 16) | (offset & 0xfc);
else
reg = offset & 0xfc;

PCI_CFG_OUT(hose->cfg_addr,
(0x80000000 | (bus_no << 16)
| (devfn << 8) | ((offset & 0xfc) | cfg_type)));
| (devfn << 8) | reg | cfg_type));

/*
* Note: the caller has already checked that offset is
Expand Down
10 changes: 10 additions & 0 deletions include/asm-ppc/pci-bridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,19 @@ struct pci_controller {
/*
* If set, indirect method will set the cfg_type bit as
* needed to generate type 1 configuration transactions.
* use only on ARCH=ppc
*/
int set_cfg_type;

/*
* Used for variants of PCI indirect handling and possible quirks:
* SET_CFG_TYPE - used on 4xx or any PHB that does explicit type0/1
* EXT_REG - provides access to PCI-e extended registers
*/
#define PPC_INDIRECT_TYPE_SET_CFG_TYPE (0x00000001)
#define PPC_INDIRECT_TYPE_EXT_REG (0x00000002)
u32 indirect_type;

/* Currently, we limit ourselves to 1 IO range and 3 mem
* ranges since the common pci_bus structure can't handle more
*/
Expand Down

0 comments on commit ab0f9ad

Please sign in to comment.