Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7517de34 authored by Manuel Lauss's avatar Manuel Lauss Committed by Ralf Baechle
Browse files

MIPS: Alchemy: Redo PCI as platform driver



- Rewrite Alchemy PCI support as a platform driver.
- Fixup boards which have PCI.

Run-tested on DB1500 and DB1550.

Signed-off-by: default avatarManuel Lauss <manuel.lauss@googlemail.com>
To: Linux-MIPS <linux-mips@linux-mips.org>
Patchwork: https://patchwork.linux-mips.org/patch/2706/


Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>

 delete mode 100644 arch/mips/alchemy/common/pci.c
 delete mode 100644 arch/mips/pci/fixup-au1000.c
 delete mode 100644 arch/mips/pci/ops-au1000.c
 create mode 100644 arch/mips/pci/pci-alchemy.c
parent 7cc2e272
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -14,5 +14,3 @@ obj-$(CONFIG_ALCHEMY_GPIOINT_AU1000) += irq.o
ifeq ($(CONFIG_ALCHEMY_GPIO_INDIRECT),)
 obj-$(CONFIG_GPIOLIB) += gpiolib.o
endif

obj-$(CONFIG_PCI)		+= pci.o

arch/mips/alchemy/common/pci.c

deleted100644 → 0
+0 −104
Original line number Diff line number Diff line
/*
 * BRIEF MODULE DESCRIPTION
 *	Alchemy/AMD Au1x00 PCI support.
 *
 * Copyright 2001-2003, 2007-2008 MontaVista Software Inc.
 * Author: MontaVista Software, Inc. <source@mvista.com>
 *
 * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
 *
 *  Support for all devices (greater than 16) added by David Gathright.
 *
 *  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.
 *
 *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
 *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
 *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
 *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *  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.,
 *  675 Mass Ave, Cambridge, MA 02139, USA.
 */

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

#include <asm/mach-au1x00/au1000.h>

/* TBD */
static struct resource pci_io_resource = {
	.start	= PCI_IO_START,
	.end	= PCI_IO_END,
	.name	= "PCI IO space",
	.flags	= IORESOURCE_IO
};

static struct resource pci_mem_resource = {
	.start	= PCI_MEM_START,
	.end	= PCI_MEM_END,
	.name	= "PCI memory space",
	.flags	= IORESOURCE_MEM
};

extern struct pci_ops au1x_pci_ops;

static struct pci_controller au1x_controller = {
	.pci_ops	= &au1x_pci_ops,
	.io_resource	= &pci_io_resource,
	.mem_resource	= &pci_mem_resource,
};

#if defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550)
static unsigned long virt_io_addr;
#endif

static int __init au1x_pci_setup(void)
{
	extern void au1x_pci_cfg_init(void);

#if defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550)
	virt_io_addr = (unsigned long)ioremap(Au1500_PCI_IO_START,
			Au1500_PCI_IO_END - Au1500_PCI_IO_START + 1);

	if (!virt_io_addr) {
		printk(KERN_ERR "Unable to ioremap pci space\n");
		return 1;
	}
	au1x_controller.io_map_base = virt_io_addr;

#ifdef CONFIG_DMA_NONCOHERENT
	{
		/*
		 *  Set the NC bit in controller for Au1500 pre-AC silicon
		 */
		u32 prid = read_c0_prid();

		if ((prid & 0xFF000000) == 0x01000000 && prid < 0x01030202) {
			au_writel((1 << 16) | au_readl(Au1500_PCI_CFG),
				  Au1500_PCI_CFG);
			printk(KERN_INFO "Non-coherent PCI accesses enabled\n");
		}
	}
#endif

	set_io_port_base(virt_io_addr);
#endif

	au1x_pci_cfg_init();

	register_pci_controller(&au1x_controller);
	return 0;
}

arch_initcall(au1x_pci_setup);
+3 −3
Original line number Diff line number Diff line
@@ -73,8 +73,8 @@ void __init plat_mem_setup(void)
/* This routine should be valid for all Au1x based boards */
phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size)
{
	u32 start = (u32)Au1500_PCI_MEM_START;
	u32 end   = (u32)Au1500_PCI_MEM_END;
	unsigned long start = ALCHEMY_PCI_MEMWIN_START;
	unsigned long end = ALCHEMY_PCI_MEMWIN_END;

	/* Don't fixup 36-bit addresses */
	if ((phys_addr >> 32) != 0)
@@ -82,7 +82,7 @@ phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size)

	/* Check for PCI memory window */
	if (phys_addr >= start && (phys_addr + size - 1) <= end)
		return (phys_t)((phys_addr - start) + Au1500_PCI_MEM_START);
		return (phys_t)(AU1500_PCI_MEM_PHYS_ADDR + phys_addr);

	/* default nop */
	return phys_addr;
+0 −24
Original line number Diff line number Diff line
@@ -40,24 +40,6 @@

#include <prom.h>

#ifdef CONFIG_MIPS_DB1500
char irq_tab_alchemy[][5] __initdata = {
	[12] = { -1, AU1500_PCI_INTA, 0xff, 0xff, 0xff }, /* IDSEL 12 - HPT371   */
	[13] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, AU1500_PCI_INTC, AU1500_PCI_INTD }, /* IDSEL 13 - PCI slot */
};

#endif


#ifdef CONFIG_MIPS_DB1550
char irq_tab_alchemy[][5] __initdata = {
	[11] = { -1, AU1550_PCI_INTC, 0xff, 0xff, 0xff }, /* IDSEL 11 - on-board HPT371 */
	[12] = { -1, AU1550_PCI_INTB, AU1550_PCI_INTC, AU1550_PCI_INTD, AU1550_PCI_INTA }, /* IDSEL 12 - PCI slot 2 (left) */
	[13] = { -1, AU1550_PCI_INTA, AU1550_PCI_INTB, AU1550_PCI_INTC, AU1550_PCI_INTD }, /* IDSEL 13 - PCI slot 1 (right) */
};
#endif


#ifdef CONFIG_MIPS_BOSPORUS
char irq_tab_alchemy[][5] __initdata = {
	[11] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff }, /* IDSEL 11 - miniPCI  */
@@ -91,12 +73,6 @@ const char *get_system_type(void)


#ifdef CONFIG_MIPS_MIRAGE
char irq_tab_alchemy[][5] __initdata = {
	[11] = { -1, AU1500_PCI_INTD, 0xff, 0xff, 0xff }, /* IDSEL 11 - SMI VGX */
	[12] = { -1, 0xff, 0xff, AU1500_PCI_INTC, 0xff }, /* IDSEL 12 - PNX1300 */
	[13] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff }, /* IDSEL 13 - miniPCI */
};

static void mirage_power_off(void)
{
	alchemy_gpio_direction_output(210, 1);
+123 −0
Original line number Diff line number Diff line
@@ -25,6 +25,8 @@
#include <asm/mach-db1x00/bcsr.h>
#include "../platform.h"

struct pci_dev;

/* DB1xxx PCMCIA interrupt sources:
 * CD0/1 	GPIO0/3
 * STSCHG0/1	GPIO1/4
@@ -85,6 +87,127 @@
#endif
#endif

#ifdef CONFIG_PCI
#ifdef CONFIG_MIPS_DB1500
static int db1xxx_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin)
{
	if ((slot < 12) || (slot > 13) || pin == 0)
		return -1;
	if (slot == 12)
		return (pin == 1) ? AU1500_PCI_INTA : 0xff;
	if (slot == 13) {
		switch (pin) {
		case 1: return AU1500_PCI_INTA;
		case 2: return AU1500_PCI_INTB;
		case 3: return AU1500_PCI_INTC;
		case 4: return AU1500_PCI_INTD;
		}
	}
	return -1;
}
#endif

#ifdef CONFIG_MIPS_DB1550
static int db1xxx_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin)
{
	if ((slot < 11) || (slot > 13) || pin == 0)
		return -1;
	if (slot == 11)
		return (pin == 1) ? AU1550_PCI_INTC : 0xff;
	if (slot == 12) {
		switch (pin) {
		case 1: return AU1550_PCI_INTB;
		case 2: return AU1550_PCI_INTC;
		case 3: return AU1550_PCI_INTD;
		case 4: return AU1550_PCI_INTA;
		}
	}
	if (slot == 13) {
		switch (pin) {
		case 1: return AU1550_PCI_INTA;
		case 2: return AU1550_PCI_INTB;
		case 3: return AU1550_PCI_INTC;
		case 4: return AU1550_PCI_INTD;
		}
	}
	return -1;
}
#endif

#ifdef CONFIG_MIPS_BOSPORUS
static int db1xxx_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin)
{
	if ((slot < 11) || (slot > 13) || pin == 0)
		return -1;
	if (slot == 12)
		return (pin == 1) ? AU1500_PCI_INTA : 0xff;
	if (slot == 11) {
		switch (pin) {
		case 1: return AU1500_PCI_INTA;
		case 2: return AU1500_PCI_INTB;
		default: return 0xff;
		}
	}
	if (slot == 13) {
		switch (pin) {
		case 1: return AU1500_PCI_INTA;
		case 2: return AU1500_PCI_INTB;
		case 3: return AU1500_PCI_INTC;
		case 4: return AU1500_PCI_INTD;
		}
	}
	return -1;
}
#endif

#ifdef CONFIG_MIPS_MIRAGE
static int db1xxx_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin)
{
	if ((slot < 11) || (slot > 13) || pin == 0)
		return -1;
	if (slot == 11)
		return (pin == 1) ? AU1500_PCI_INTD : 0xff;
	if (slot == 12)
		return (pin == 3) ? AU1500_PCI_INTC : 0xff;
	if (slot == 13) {
		switch (pin) {
		case 1: return AU1500_PCI_INTA;
		case 2: return AU1500_PCI_INTB;
		default: return 0xff;
		}
	}
	return -1;
}
#endif

static struct resource alchemy_pci_host_res[] = {
	[0] = {
		.start	= AU1500_PCI_PHYS_ADDR,
		.end	= AU1500_PCI_PHYS_ADDR + 0xfff,
		.flags	= IORESOURCE_MEM,
	},
};

static struct alchemy_pci_platdata db1xxx_pci_pd = {
	.board_map_irq	= db1xxx_map_pci_irq,
};

static struct platform_device db1xxx_pci_host_dev = {
	.dev.platform_data = &db1xxx_pci_pd,
	.name		= "alchemy-pci",
	.id		= 0,
	.num_resources	= ARRAY_SIZE(alchemy_pci_host_res),
	.resource	= alchemy_pci_host_res,
};

static int __init db15x0_pci_init(void)
{
	return platform_device_register(&db1xxx_pci_host_dev);
}
/* must be arch_initcall; MIPS PCI scans busses in a subsys_initcall */
arch_initcall(db15x0_pci_init);
#endif

static int __init db1xxx_dev_init(void)
{
#ifdef DB1XXX_HAS_PCMCIA
Loading