- Add irq mapping for PCI - Add PCI for Sequoia in Makefile - Add PCI ops - Add PCI setup and functions Signed-Off-By: Kiran Kumar Thota <kiran_thota@xxxxxxxxxxxxxx> diff -Naur a/arch/mips/pci/fixup-sequoia.c b/arch/mips/pci/fixup-sequoia.c --- a/arch/mips/pci/fixup-sequoia.c 1969-12-31 16:00:00.000000000 -0800 +++ b/arch/mips/pci/fixup-sequoia.c 2006-06-22 11:48:21.000000000 -0700 @@ -0,0 +1,43 @@ +/* + * Copyright 2006 PMC-Sierra + * Author: PMC Sierra Inc (thotakir@xxxxxxxxxxxxxx) + * + */ + +#include <linux/types.h> +#include <linux/pci.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <asm/pci.h> + + +int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + if (pin == 0) + return -1; + + if ((dev->bus->number == 0) && + (slot== 2)) { + /* bus 0, slot 0 */ + return 11; + } else if ((dev->bus->number == 0) && + (slot == 3)) { + /* bus 0, slot 1 */ + return 12; + } else if ((dev->bus->number == 1) && + (slot == 2)) { + /* bus 1, slot 0 */ + return 13; + } else if ((dev->bus->number == 1) && + (slot == 3)) { + /* bus 1, slot 1 */ + return 14; + } +} + +/* Do platform specific device initialization at pci_enable_device() time */ +int pcibios_plat_dev_init(struct pci_dev *dev) +{ + return 0; +} + diff -Naur a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile --- a/arch/mips/pci/Makefile 2005-07-11 11:28:10.000000000 -0700 +++ b/arch/mips/pci/Makefile 2006-06-22 11:48:21.000000000 -0700 @@ -42,6 +42,8 @@ obj-$(CONFIG_MOMENCO_OCELOT_G) += fixup-ocelot-g.o pci-ocelot-g.o obj-$(CONFIG_PMC_YOSEMITE) += fixup-yosemite.o ops-titan.o ops-titan-ht.o \ pci-yosemite.o +obj-$(CONFIG_PMC_SEQUOIA) += fixup-sequoia.o ops-sequoia.o pci-sequoia.o + obj-$(CONFIG_SGI_IP27) += pci-ip27.o obj-$(CONFIG_SGI_IP32) += fixup-ip32.o ops-mace.o pci-ip32.o obj-$(CONFIG_SIBYTE_SB1250) += fixup-sb1250.o pci-sb1250.o diff -Naur a/arch/mips/pci/ops-sequoia.c b/arch/mips/pci/ops-sequoia.c --- a/arch/mips/pci/ops-sequoia.c 1969-12-31 16:00:00.000000000 -0800 +++ b/arch/mips/pci/ops-sequoia.c 2006-06-22 14:51:08.000000000 -0700 @@ -0,0 +1,187 @@ +/* + * Copyright 2006 PMC-Sierra + * Author: PMC Sierra Inc (thotakir@xxxxxxxxxxxxxx) + * + */ + +#include <linux/config.h> +#include <linux/types.h> +#include <linux/pci.h> +#include <linux/kernel.h> +#include <linux/slab.h> +#include <linux/version.h> +#include <asm/pci.h> +#include <asm/io.h> + +#include <linux/init.h> +#include <asm/pmc_sequoia.h> + + +void sequoia_pcibios_fixup_bus(struct pci_bus* c); + + +/* + * Sequoia PCI Config Read Byte + */ +static int sequoia_pci_read_config(struct pci_bus *bus, + unsigned int devfn, int offset, int size, u32* val) +{ + int dev, busno, func; + uint32_t address_reg, data_reg; + uint32_t address, data = 0; + + int local_busno = 0; + + busno = bus->number; + dev = PCI_SLOT(devfn); + func = PCI_FUNC(devfn); + + address_reg = RM9150_PCI_CONFIG_ADDR; + data_reg = RM9150_PCI_CONFIG_DATA; + + address = (local_busno << 16) | (dev << 11) | (func << 8) | + (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + if (busno == 0) + SEQUOIA_PCI0_WRITE(address_reg, address); + else + SEQUOIA_PCI1_WRITE(address_reg, address); + + /* read the data */ + switch (size) { + case 1: + + if (busno == 0) + { + data = SEQUOIA_PCI0_READ(data_reg); + *val = (data >> ((offset & 3) << 3)) & 0xff; + } + else + { + data = SEQUOIA_PCI1_READ(data_reg); + *val = (data >> ((offset & 3) << 3)) & 0xff; + } + break; + + case 2: + + if (busno == 0) + { + data = SEQUOIA_PCI0_READ(data_reg); + *val = (data >> ((offset & 3) << 3)) & 0xffff; + } + else + { + data = SEQUOIA_PCI1_READ(data_reg); + *val = (data >> ((offset & 3) << 3)) & 0xffff; + } + break; + + case 4: + if (busno == 0) + *val = SEQUOIA_PCI0_READ(data_reg); + else + *val = SEQUOIA_PCI1_READ(data_reg); + break; + } + + return PCIBIOS_SUCCESSFUL; +} + +/* + * Sequoia PCI Config Byte Write + */ +static int sequoia_pci_write_config(struct pci_bus *bus, + unsigned int devfn, int offset, int size, u32 val) +{ + int dev, busno, func; + uint32_t address_reg, data_reg; + uint32_t address, data = 0; + + int local_busno = 0; + + busno = bus->number; + dev = PCI_SLOT(devfn); + func = PCI_FUNC(devfn); + + address_reg = RM9150_PCI_CONFIG_ADDR; + data_reg = RM9150_PCI_CONFIG_DATA; + + address = (local_busno << 16) | (dev << 11) | (func << 8) | + (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + if (busno == 0) + SEQUOIA_PCI0_WRITE(address_reg, address); + else + SEQUOIA_PCI1_WRITE(address_reg, address); + + /* write the data */ + switch (size) { + case 1: + if (busno == 0) + { + /* read the data first */ + data = SEQUOIA_PCI0_READ(data_reg); + data = (data & ~(0xff << ((offset & 3) << 3))) | + (val << ((offset & 3) << 3)); + + /* write the data */ + SEQUOIA_PCI0_WRITE(data_reg, data); + } + else + { + /* read the data first */ + data = SEQUOIA_PCI1_READ(data_reg); + data = (data & ~(0xff << ((offset & 3) << 3))) | + (val << ((offset & 3) << 3)); + + /* write the data */ + SEQUOIA_PCI1_WRITE(data_reg, data); + } + break; + case 2: + if (busno == 0) + { + /* read the data first */ + data = SEQUOIA_PCI0_READ(data_reg); + data = (data & ~(0xffff << ((offset & 3) << 3))) | + (val << ((offset & 3) << 3)); + + /* write the data */ + SEQUOIA_PCI0_WRITE(data_reg, data); + } + else + { + /* read the data first */ + data = SEQUOIA_PCI1_READ(data_reg); + data = (data & ~(0xffff << ((offset & 3) << 3))) | + (val << ((offset & 3) << 3)); + + /* write the data */ + SEQUOIA_PCI1_WRITE(data_reg, data); + } + break; + case 4: + if (busno == 0) + SEQUOIA_PCI0_WRITE(data_reg, val); + else + SEQUOIA_PCI1_WRITE(data_reg, val); + break; + } + + return PCIBIOS_SUCCESSFUL; +} + +/* + * Sequoia PCI structure + */ +struct pci_ops sequoia_pci_ops = { + sequoia_pci_read_config, + sequoia_pci_write_config, +}; + +struct pci_fixup pcibios_fixups[] = { + {0} +}; diff -Naur a/arch/mips/pci/pci-sequoia.c b/arch/mips/pci/pci-sequoia.c --- a/arch/mips/pci/pci-sequoia.c 1969-12-31 16:00:00.000000000 -0800 +++ b/arch/mips/pci/pci-sequoia.c 2006-06-22 11:48:21.000000000 -0700 @@ -0,0 +1,78 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2004 by Ralf Baechle (ralf@xxxxxxxxxxxxxx) + */ +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/pci.h> +#include <asm/gt64240.h> +#include <asm/pmc_sequoia.h> + + +extern struct pci_ops sequoia_pci_ops; + +static struct resource py_mem_resource0 = { + "Sequoia PCI MEM", SEQUOIA_PCI0_MEM_BASE, + SEQUOIA_PCI0_MEM_BASE+SEQUOIA_PCI0_MEM_SIZE-1, IORESOURCE_MEM +}; + +static struct resource py_mem_resource1 = { + "Sequoia PCI MEM", SEQUOIA_PCI1_MEM_BASE, + SEQUOIA_PCI1_MEM_BASE+SEQUOIA_PCI1_MEM_SIZE-1, IORESOURCE_MEM +}; + +/* + * PMON really reserves 16MB of I/O port space but that's stupid, nothing + * needs that much since allocations are limited to 256 bytes per device + * anyway. So we just claim 64kB here. + */ +#define SEQUOIA_IO_SIZE 0x0000ffffUL + +static struct resource py_io_resource0 = { + "Sequoia IO MEM", SEQUOIA_PCI0_IO_BASE, + SEQUOIA_PCI0_IO_BASE + SEQUOIA_PCI0_IO_SIZE - 1, IORESOURCE_IO, +}; + +static struct resource py_io_resource1 = { + "Sequoia IO MEM", SEQUOIA_PCI1_IO_BASE, + SEQUOIA_PCI1_IO_BASE + SEQUOIA_PCI1_IO_SIZE - 1, IORESOURCE_IO, +}; + +static struct pci_controller py_controller0 = { + .pci_ops = &sequoia_pci_ops, + .mem_resource = &py_mem_resource0, + .mem_offset = 0x00000000UL, + .io_resource = &py_io_resource0, + .io_offset = 0x00000000UL +}; + +static struct pci_controller py_controller1 = { + .pci_ops = &sequoia_pci_ops, + .mem_resource = &py_mem_resource1, + .mem_offset = 0x00000000UL, + .io_resource = &py_io_resource1, + .io_offset = 0x00000000UL +}; + +static char ioremap_failed[] __initdata = "Could not ioremap I/O port range"; + +static int __init pmc_sequoia_setup(void) +{ + unsigned long io_v_base; + + set_io_port_base(0); + + ioport_resource.end = SEQUOIA_PCI1_IO_BASE + SEQUOIA_PCI1_IO_SIZE - 1; + + register_pci_controller(&py_controller0); + register_pci_controller(&py_controller1); + + return 0; +} + +arch_initcall(pmc_sequoia_setup); +