Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 34099
b: refs/heads/master
c: 1e76875
h: refs/heads/master
i:
  34097: 7676245
  34095: 906e63c
v: v3
  • Loading branch information
Olof Johansson authored and Paul Mackerras committed Sep 13, 2006
1 parent 71a4cd2 commit 2bc4b37
Show file tree
Hide file tree
Showing 8 changed files with 437 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b3ebd1d862d6c23caa58e40d341eefc426f835e1
refs/heads/master: 1e76875e51266a5c43f601ecf08a92be5769228c
11 changes: 11 additions & 0 deletions trunk/arch/powerpc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,17 @@ config PPC_MAPLE
This option enables support for the Maple 970FX Evaluation Board.
For more informations, refer to <http://www.970eval.com>

config PPC_PASEMI
depends on PPC_MULTIPLATFORM && PPC64
bool "PA Semi SoC-based platforms"
default n
select MPIC
select PPC_UDBG_16550
select GENERIC_TBSYNC
help
This option enables support for PA Semi's PWRficient line
of SoC processors, including PA6T-1682M

config PPC_CELL
bool
default n
Expand Down
1 change: 1 addition & 0 deletions trunk/arch/powerpc/platforms/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ obj-$(CONFIG_PPC_86xx) += 86xx/
obj-$(CONFIG_PPC_PSERIES) += pseries/
obj-$(CONFIG_PPC_ISERIES) += iseries/
obj-$(CONFIG_PPC_MAPLE) += maple/
obj-$(CONFIG_PPC_PASEMI) += pasemi/
obj-$(CONFIG_PPC_CELL) += cell/
obj-$(CONFIG_EMBEDDED6xx) += embedded6xx/
1 change: 1 addition & 0 deletions trunk/arch/powerpc/platforms/pasemi/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
obj-y += setup.o pci.o time.o
8 changes: 8 additions & 0 deletions trunk/arch/powerpc/platforms/pasemi/pasemi.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ifndef _PASEMI_PASEMI_H
#define _PASEMI_PASEMI_H

extern unsigned long pas_get_boot_time(void);
extern void pas_pci_init(void);
extern void pas_pcibios_fixup(void);

#endif /* _PASEMI_PASEMI_H */
198 changes: 198 additions & 0 deletions trunk/arch/powerpc/platforms/pasemi/pci.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
/*
* Copyright (C) 2006 PA Semi, Inc
*
* Authors: Kip Walker, PA Semi
* Olof Johansson, PA Semi
*
* Maintained by: Olof Johansson <olof@lixom.net>
*
* Based on arch/powerpc/platforms/maple/pci.c
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/


#include <linux/kernel.h>
#include <linux/pci.h>

#include <asm/pci-bridge.h>
#include <asm/machdep.h>

#include <asm/ppc-pci.h>

#define PA_PXP_CFA(bus, devfn, off) (((bus) << 20) | ((devfn) << 12) | (off))

#define CONFIG_OFFSET_VALID(off) ((off) < 4096)

static unsigned long pa_pxp_cfg_addr(struct pci_controller *hose,
u8 bus, u8 devfn, int offset)
{
return ((unsigned long)hose->cfg_data) + PA_PXP_CFA(bus, devfn, offset);
}

static int pa_pxp_read_config(struct pci_bus *bus, unsigned int devfn,
int offset, int len, u32 *val)
{
struct pci_controller *hose;
unsigned long addr;

hose = pci_bus_to_host(bus);
if (!hose)
return PCIBIOS_DEVICE_NOT_FOUND;

if (!CONFIG_OFFSET_VALID(offset))
return PCIBIOS_BAD_REGISTER_NUMBER;

addr = pa_pxp_cfg_addr(hose, bus->number, devfn, offset);

/*
* Note: the caller has already checked that offset is
* suitably aligned and that len is 1, 2 or 4.
*/
switch (len) {
case 1:
*val = in_8((u8 *)addr);
break;
case 2:
*val = in_le16((u16 *)addr);
break;
default:
*val = in_le32((u32 *)addr);
break;
}

return PCIBIOS_SUCCESSFUL;
}

static int pa_pxp_write_config(struct pci_bus *bus, unsigned int devfn,
int offset, int len, u32 val)
{
struct pci_controller *hose;
unsigned long addr;

hose = pci_bus_to_host(bus);
if (!hose)
return PCIBIOS_DEVICE_NOT_FOUND;

if (!CONFIG_OFFSET_VALID(offset))
return PCIBIOS_BAD_REGISTER_NUMBER;

addr = pa_pxp_cfg_addr(hose, bus->number, devfn, offset);

/*
* Note: the caller has already checked that offset is
* suitably aligned and that len is 1, 2 or 4.
*/
switch (len) {
case 1:
out_8((u8 *)addr, val);
(void) in_8((u8 *)addr);
break;
case 2:
out_le16((u16 *)addr, val);
(void) in_le16((u16 *)addr);
break;
default:
out_le32((u32 *)addr, val);
(void) in_le32((u32 *)addr);
break;
}
return PCIBIOS_SUCCESSFUL;
}

static struct pci_ops pa_pxp_ops = {
pa_pxp_read_config,
pa_pxp_write_config,
};

static void __init setup_pa_pxp(struct pci_controller *hose)
{
hose->ops = &pa_pxp_ops;
hose->cfg_data = ioremap(0xe0000000, 0x10000000);
}

static int __init add_bridge(struct device_node *dev)
{
struct pci_controller *hose;

pr_debug("Adding PCI host bridge %s\n", dev->full_name);

hose = pcibios_alloc_controller(dev);
if (!hose)
return -ENOMEM;

hose->first_busno = 0;
hose->last_busno = 0xff;

setup_pa_pxp(hose);

printk(KERN_INFO "Found PA-PXP PCI host bridge.\n");

/* Interpret the "ranges" property */
/* This also maps the I/O region and sets isa_io/mem_base */
pci_process_bridge_OF_ranges(hose, dev, 1);
pci_setup_phb_io(hose, 1);

return 0;
}


void __init pas_pcibios_fixup(void)
{
struct pci_dev *dev = NULL;

for_each_pci_dev(dev)
pci_read_irq_line(dev);
}

static void __init pas_fixup_phb_resources(void)
{
struct pci_controller *hose, *tmp;

list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
unsigned long offset = (unsigned long)hose->io_base_virt - pci_io_base;
hose->io_resource.start += offset;
hose->io_resource.end += offset;
printk(KERN_INFO "PCI Host %d, io start: %lx; io end: %lx\n",
hose->global_number,
hose->io_resource.start, hose->io_resource.end);
}
}


void __init pas_pci_init(void)
{
struct device_node *np, *root;

root = of_find_node_by_path("/");
if (!root) {
printk(KERN_CRIT "pas_pci_init: can't find root "
"of device tree\n");
return;
}

for (np = NULL; (np = of_get_next_child(root, np)) != NULL;)
if (np->name && !strcmp(np->name, "pxp") && !add_bridge(np))
of_node_get(np);

of_node_put(root);

pas_fixup_phb_resources();

/* Setup the linkage between OF nodes and PHBs */
pci_devs_phb_init();

/* Use the common resource allocation mechanism */
pci_probe_only = 1;
}
Loading

0 comments on commit 2bc4b37

Please sign in to comment.