[PATCH 2/6] Sequoia PCI

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



- 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);
+


[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux