Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 188362
b: refs/heads/master
c: a6475c1
h: refs/heads/master
v: v3
  • Loading branch information
Michal Simek committed Mar 11, 2010
1 parent d2fe948 commit cc12fd9
Show file tree
Hide file tree
Showing 10 changed files with 270 additions and 2 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: d3afa58c20b65155af9f0d5eaa59fe2d367ac432
refs/heads/master: a6475c132278c1be158a13872c233aeab8a00176
15 changes: 15 additions & 0 deletions trunk/arch/microblaze/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,21 @@ source "fs/Kconfig.binfmt"

endmenu

menu "Bus Options"

config PCI
bool "PCI support"

config PCI_DOMAINS
def_bool PCI

config PCI_SYSCALL
def_bool PCI

source "drivers/pci/Kconfig"

endmenu

source "net/Kconfig"

source "drivers/Kconfig"
Expand Down
1 change: 1 addition & 0 deletions trunk/arch/microblaze/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ libs-y += $(LIBGCC)
core-y += arch/microblaze/kernel/
core-y += arch/microblaze/mm/
core-y += arch/microblaze/platform/
core-$(CONFIG_PCI) += arch/microblaze/pci/

drivers-$(CONFIG_OPROFILE) += arch/microblaze/oprofile/

Expand Down
16 changes: 15 additions & 1 deletion trunk/arch/microblaze/include/asm/io.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,21 @@
#include <linux/mm.h> /* Get struct page {...} */
#include <asm-generic/iomap.h>

#define PCI_DRAM_OFFSET 0
#ifndef CONFIG_PCI
#define _IO_BASE 0
#define _ISA_MEM_BASE 0
#define PCI_DRAM_OFFSET 0
#else
#define _IO_BASE isa_io_base
#define _ISA_MEM_BASE isa_mem_base
#define PCI_DRAM_OFFSET pci_dram_offset
#endif

extern unsigned long isa_io_base;
extern unsigned long pci_io_base;
extern unsigned long pci_dram_offset;

extern resource_size_t isa_mem_base;

#define IO_SPACE_LIMIT (0xFFFFFFFF)

Expand Down
15 changes: 15 additions & 0 deletions trunk/arch/microblaze/include/asm/pgtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,21 @@ static inline pte_t pte_mkspecial(pte_t pte) { return pte; }

#endif /* __ASSEMBLY__ */

/*
* Macro to mark a page protection value as "uncacheable".
*/

#define _PAGE_CACHE_CTL (_PAGE_GUARDED | _PAGE_NO_CACHE | \
_PAGE_WRITETHRU)

#define pgprot_noncached(prot) \
(__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \
_PAGE_NO_CACHE | _PAGE_GUARDED))

#define pgprot_noncached_wc(prot) \
(__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \
_PAGE_NO_CACHE))

/*
* The MicroBlaze MMU is identical to the PPC-40x MMU, and uses a hash
* table containing PTEs, together with a set of 16 segment registers, to
Expand Down
15 changes: 15 additions & 0 deletions trunk/arch/microblaze/include/asm/prom.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,21 @@
/* Other Prototypes */
extern int early_uartlite_console(void);

#ifdef CONFIG_PCI
/*
* PCI <-> OF matching functions
* (XXX should these be here?)
*/
struct pci_bus;
struct pci_dev;
extern int pci_device_from_OF_node(struct device_node *node,
u8 *bus, u8 *devfn);
extern struct device_node *pci_busdev_to_OF_node(struct pci_bus *bus,
int devfn);
extern struct device_node *pci_device_to_OF_node(struct pci_dev *dev);
extern void pci_create_OF_bus_map(void);
#endif

/*
* OF address retreival & translation
*/
Expand Down
5 changes: 5 additions & 0 deletions trunk/arch/microblaze/pci/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#
# Makefile
#

obj-$(CONFIG_PCI) += pci_32.o pci-common.o indirect_pci.o iomap.o
163 changes: 163 additions & 0 deletions trunk/arch/microblaze/pci/indirect_pci.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
/*
* 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.
*/

#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/string.h>
#include <linux/init.h>

#include <asm/io.h>
#include <asm/prom.h>
#include <asm/pci-bridge.h>

static int
indirect_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
int len, u32 *val)
{
struct pci_controller *hose = pci_bus_to_host(bus);
volatile void __iomem *cfg_data;
u8 cfg_type = 0;
u32 bus_no, reg;

if (hose->indirect_type & INDIRECT_TYPE_NO_PCIE_LINK) {
if (bus->number != hose->first_busno)
return PCIBIOS_DEVICE_NOT_FOUND;
if (devfn != 0)
return PCIBIOS_DEVICE_NOT_FOUND;
}

if (hose->indirect_type & 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 & INDIRECT_TYPE_EXT_REG)
reg = ((offset & 0xf00) << 16) | (offset & 0xfc);
else
reg = offset & 0xfc; /* Only 3 bits for function */

if (hose->indirect_type & INDIRECT_TYPE_BIG_ENDIAN)
out_be32(hose->cfg_addr, (0x80000000 | (bus_no << 16) |
(devfn << 8) | reg | cfg_type));
else
out_le32(hose->cfg_addr, (0x80000000 | (bus_no << 16) |
(devfn << 8) | reg | cfg_type));

/*
* Note: the caller has already checked that offset is
* suitably aligned and that len is 1, 2 or 4.
*/
cfg_data = hose->cfg_data + (offset & 3); /* Only 3 bits for function */
switch (len) {
case 1:
*val = in_8(cfg_data);
break;
case 2:
*val = in_le16(cfg_data);
break;
default:
*val = in_le32(cfg_data);
break;
}
return PCIBIOS_SUCCESSFUL;
}

static int
indirect_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
int len, u32 val)
{
struct pci_controller *hose = pci_bus_to_host(bus);
volatile void __iomem *cfg_data;
u8 cfg_type = 0;
u32 bus_no, reg;

if (hose->indirect_type & INDIRECT_TYPE_NO_PCIE_LINK) {
if (bus->number != hose->first_busno)
return PCIBIOS_DEVICE_NOT_FOUND;
if (devfn != 0)
return PCIBIOS_DEVICE_NOT_FOUND;
}

if (hose->indirect_type & 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 & INDIRECT_TYPE_EXT_REG)
reg = ((offset & 0xf00) << 16) | (offset & 0xfc);
else
reg = offset & 0xfc;

if (hose->indirect_type & INDIRECT_TYPE_BIG_ENDIAN)
out_be32(hose->cfg_addr, (0x80000000 | (bus_no << 16) |
(devfn << 8) | reg | cfg_type));
else
out_le32(hose->cfg_addr, (0x80000000 | (bus_no << 16) |
(devfn << 8) | reg | cfg_type));

/* surpress setting of PCI_PRIMARY_BUS */
if (hose->indirect_type & INDIRECT_TYPE_SURPRESS_PRIMARY_BUS)
if ((offset == PCI_PRIMARY_BUS) &&
(bus->number == hose->first_busno))
val &= 0xffffff00;

/* Workaround for PCI_28 Errata in 440EPx/GRx */
if ((hose->indirect_type & INDIRECT_TYPE_BROKEN_MRM) &&
offset == PCI_CACHE_LINE_SIZE) {
val = 0;
}

/*
* Note: the caller has already checked that offset is
* suitably aligned and that len is 1, 2 or 4.
*/
cfg_data = hose->cfg_data + (offset & 3);
switch (len) {
case 1:
out_8(cfg_data, val);
break;
case 2:
out_le16(cfg_data, val);
break;
default:
out_le32(cfg_data, val);
break;
}

return PCIBIOS_SUCCESSFUL;
}

static struct pci_ops indirect_pci_ops = {
.read = indirect_read_config,
.write = indirect_write_config,
};

void __init
setup_indirect_pci(struct pci_controller *hose,
resource_size_t cfg_addr,
resource_size_t cfg_data, u32 flags)
{
resource_size_t base = cfg_addr & PAGE_MASK;
void __iomem *mbase;

mbase = ioremap(base, PAGE_SIZE);
hose->cfg_addr = mbase + (cfg_addr & ~PAGE_MASK);
if ((cfg_data & PAGE_MASK) != base)
mbase = ioremap(cfg_data & PAGE_MASK, PAGE_SIZE);
hose->cfg_data = mbase + (cfg_data & ~PAGE_MASK);
hose->ops = &indirect_pci_ops;
hose->indirect_type = flags;
}
39 changes: 39 additions & 0 deletions trunk/arch/microblaze/pci/iomap.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* ppc64 "iomap" interface implementation.
*
* (C) Copyright 2004 Linus Torvalds
*/
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/mm.h>
#include <asm/io.h>
#include <asm/pci-bridge.h>

void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max)
{
resource_size_t start = pci_resource_start(dev, bar);
resource_size_t len = pci_resource_len(dev, bar);
unsigned long flags = pci_resource_flags(dev, bar);

if (!len)
return NULL;
if (max && len > max)
len = max;
if (flags & IORESOURCE_IO)
return ioport_map(start, len);
if (flags & IORESOURCE_MEM)
return ioremap(start, len);
/* What? */
return NULL;
}
EXPORT_SYMBOL(pci_iomap);

void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
{
if (isa_vaddr_is_ioport(addr))
return;
if (pcibios_vaddr_is_ioport(addr))
return;
iounmap(addr);
}
EXPORT_SYMBOL(pci_iounmap);
1 change: 1 addition & 0 deletions trunk/drivers/pci/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ obj-$(CONFIG_PPC) += setup-bus.o
obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o
obj-$(CONFIG_X86_VISWS) += setup-irq.o
obj-$(CONFIG_MN10300) += setup-bus.o
obj-$(CONFIG_MICROBLAZE) += setup-bus.o

#
# ACPI Related PCI FW Functions
Expand Down

0 comments on commit cc12fd9

Please sign in to comment.