linux/arch/mips/alchemy/mtx-1/board_setup.c
Bruno Randolf 98a0f86a54 MIPS: MTX-1: Fix PCI on the MeshCube and related boards
This patch fixes a regression introduced by commit "MIPS: Alchemy: MTX-1:
Use linux gpio api." (bb706b28bb) which broke
PCI bus operation. The problem is caused by alchemy_gpio2_enable() which
resets the GPIO2 block. Two PCI signals (PCI_SERR and PCI_RST) are connected
to GPIO2 and they obviously do not to like the reset. Since GPIO2 is
correctly initialized by the boot monitor (YAMON) it is not necessary to
call this function, so just remove it.

Also replace gpio_set_value() with alchemy_gpio_set_value() to avoid
problems in case gpiolib gets initialized after PCI. And since alchemy
gpio_set_value() calls au_sync() we don't have to au_sync() again later.

Signed-off-by: Bruno Randolf <br1@einfach.org>
To: linux-mips@linux-mips.org
To: manuel.lauss@googlemail.com
Patchwork: https://patchwork.linux-mips.org/patch/1448/
Tested-by: Florian Fainelli <florian@openwrt.org>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
2010-07-26 19:08:17 +01:00

136 lines
4.7 KiB
C

/*
*
* BRIEF MODULE DESCRIPTION
* 4G Systems MTX-1 board setup.
*
* Copyright 2003, 2008 MontaVista Software Inc.
* Author: MontaVista Software, Inc. <source@mvista.com>
* Bruno Randolf <bruno.randolf@4g-systems.biz>
*
* 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/gpio.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/pm.h>
#include <asm/reboot.h>
#include <asm/mach-au1x00/au1000.h>
#include <prom.h>
char irq_tab_alchemy[][5] __initdata = {
[0] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTA, 0xff, 0xff }, /* IDSEL 00 - AdapterA-Slot0 (top) */
[1] = { -1, AU1500_PCI_INTB, AU1500_PCI_INTA, 0xff, 0xff }, /* IDSEL 01 - AdapterA-Slot1 (bottom) */
[2] = { -1, AU1500_PCI_INTC, AU1500_PCI_INTD, 0xff, 0xff }, /* IDSEL 02 - AdapterB-Slot0 (top) */
[3] = { -1, AU1500_PCI_INTD, AU1500_PCI_INTC, 0xff, 0xff }, /* IDSEL 03 - AdapterB-Slot1 (bottom) */
[4] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff }, /* IDSEL 04 - AdapterC-Slot0 (top) */
[5] = { -1, AU1500_PCI_INTB, AU1500_PCI_INTA, 0xff, 0xff }, /* IDSEL 05 - AdapterC-Slot1 (bottom) */
[6] = { -1, AU1500_PCI_INTC, AU1500_PCI_INTD, 0xff, 0xff }, /* IDSEL 06 - AdapterD-Slot0 (top) */
[7] = { -1, AU1500_PCI_INTD, AU1500_PCI_INTC, 0xff, 0xff }, /* IDSEL 07 - AdapterD-Slot1 (bottom) */
};
extern int (*board_pci_idsel)(unsigned int devsel, int assert);
int mtx1_pci_idsel(unsigned int devsel, int assert);
static void mtx1_reset(char *c)
{
/* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
au_writel(0x00000000, 0xAE00001C);
}
static void mtx1_power_off(void)
{
printk(KERN_ALERT "It's now safe to remove power\n");
while (1)
asm volatile (".set mips3 ; wait ; .set mips1");
}
void __init board_setup(void)
{
#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
/* Enable USB power switch */
alchemy_gpio_direction_output(204, 0);
#endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */
#ifdef CONFIG_PCI
#if defined(__MIPSEB__)
au_writel(0xf | (2 << 6) | (1 << 4), Au1500_PCI_CFG);
#else
au_writel(0xf, Au1500_PCI_CFG);
#endif
board_pci_idsel = mtx1_pci_idsel;
#endif
/* Initialize sys_pinfunc */
au_writel(SYS_PF_NI2, SYS_PINFUNC);
/* Initialize GPIO */
au_writel(0xFFFFFFFF, SYS_TRIOUTCLR);
alchemy_gpio_direction_output(0, 0); /* Disable M66EN (PCI 66MHz) */
alchemy_gpio_direction_output(3, 1); /* Disable PCI CLKRUN# */
alchemy_gpio_direction_output(1, 1); /* Enable EXT_IO3 */
alchemy_gpio_direction_output(5, 0); /* Disable eth PHY TX_ER */
/* Enable LED and set it to green */
alchemy_gpio_direction_output(211, 1); /* green on */
alchemy_gpio_direction_output(212, 0); /* red off */
pm_power_off = mtx1_power_off;
_machine_halt = mtx1_power_off;
_machine_restart = mtx1_reset;
printk(KERN_INFO "4G Systems MTX-1 Board\n");
}
int
mtx1_pci_idsel(unsigned int devsel, int assert)
{
#define MTX_IDSEL_ONLY_0_AND_3 0
#if MTX_IDSEL_ONLY_0_AND_3
if (devsel != 0 && devsel != 3) {
printk(KERN_ERR "*** not 0 or 3\n");
return 0;
}
#endif
if (assert && devsel != 0)
/* Suppress signal to Cardbus */
alchemy_gpio_set_value(1, 0); /* set EXT_IO3 OFF */
else
alchemy_gpio_set_value(1, 1); /* set EXT_IO3 ON */
udelay(1);
return 1;
}
static int __init mtx1_init_irq(void)
{
set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH);
set_irq_type(AU1500_GPIO201_INT, IRQF_TRIGGER_LOW);
set_irq_type(AU1500_GPIO202_INT, IRQF_TRIGGER_LOW);
set_irq_type(AU1500_GPIO203_INT, IRQF_TRIGGER_LOW);
set_irq_type(AU1500_GPIO205_INT, IRQF_TRIGGER_LOW);
return 0;
}
arch_initcall(mtx1_init_irq);