Merge branch 'next/alchemy' into mips-for-linux-next

This commit is contained in:
Ralf Baechle
2012-01-11 15:42:10 +01:00
98 changed files with 6701 additions and 5817 deletions

View File

@@ -2,6 +2,10 @@
config ALCHEMY_GPIOINT_AU1000
bool
# au1300-style GPIO/INT controller
config ALCHEMY_GPIOINT_AU1300
bool
# select this in your board config if you don't want to use the gpio
# namespace as documented in the manuals. In this case however you need
# to create the necessary gpio_* functions in your board code/headers!
@@ -22,38 +26,8 @@ config MIPS_MTX1
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_HAS_EARLY_PRINTK
config MIPS_BOSPORUS
bool "Alchemy Bosporus board"
select ALCHEMY_GPIOINT_AU1000
select DMA_NONCOHERENT
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_HAS_EARLY_PRINTK
config MIPS_DB1000
bool "Alchemy DB1000 board"
select ALCHEMY_GPIOINT_AU1000
select DMA_NONCOHERENT
select HW_HAS_PCI
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_HAS_EARLY_PRINTK
config MIPS_DB1100
bool "Alchemy DB1100 board"
select ALCHEMY_GPIOINT_AU1000
select DMA_NONCOHERENT
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_HAS_EARLY_PRINTK
config MIPS_DB1200
bool "Alchemy DB1200 board"
select ALCHEMY_GPIOINT_AU1000
select DMA_COHERENT
select MIPS_DISABLE_OBSOLETE_IDE
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_HAS_EARLY_PRINTK
config MIPS_DB1500
bool "Alchemy DB1500 board"
bool "Alchemy DB1000/DB1500/DB1100 boards"
select ALCHEMY_GPIOINT_AU1000
select DMA_NONCOHERENT
select HW_HAS_PCI
@@ -62,28 +36,28 @@ config MIPS_DB1500
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_HAS_EARLY_PRINTK
config MIPS_DB1550
bool "Alchemy DB1550 board"
config MIPS_DB1200
bool "Alchemy DB1200/PB1200 board"
select ALCHEMY_GPIOINT_AU1000
select HW_HAS_PCI
select DMA_NONCOHERENT
select DMA_COHERENT
select MIPS_DISABLE_OBSOLETE_IDE
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_HAS_EARLY_PRINTK
config MIPS_MIRAGE
bool "Alchemy Mirage board"
select DMA_NONCOHERENT
select ALCHEMY_GPIOINT_AU1000
config MIPS_DB1300
bool "NetLogic DB1300 board"
select ALCHEMY_GPIOINT_AU1300
select DMA_COHERENT
select MIPS_DISABLE_OBSOLETE_IDE
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_HAS_EARLY_PRINTK
config MIPS_PB1000
bool "Alchemy PB1000 board"
config MIPS_DB1550
bool "Alchemy DB1550 board"
select ALCHEMY_GPIOINT_AU1000
select DMA_NONCOHERENT
select HW_HAS_PCI
select SWAP_IO_SPACE
select DMA_COHERENT
select MIPS_DISABLE_OBSOLETE_IDE
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_HAS_EARLY_PRINTK
@@ -96,14 +70,6 @@ config MIPS_PB1100
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_HAS_EARLY_PRINTK
config MIPS_PB1200
bool "Alchemy PB1200 board"
select ALCHEMY_GPIOINT_AU1000
select DMA_NONCOHERENT
select MIPS_DISABLE_OBSOLETE_IDE
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_HAS_EARLY_PRINTK
config MIPS_PB1500
bool "Alchemy PB1500 board"
select ALCHEMY_GPIOINT_AU1000

View File

@@ -0,0 +1,3 @@
obj-$(CONFIG_MIPS_GPR) += board-gpr.o
obj-$(CONFIG_MIPS_MTX1) += board-mtx1.o
obj-$(CONFIG_MIPS_XXS1500) += board-xxs1500.o

View File

@@ -4,62 +4,31 @@
platform-$(CONFIG_MIPS_ALCHEMY) += alchemy/common/
#
# AMD Alchemy Pb1000 eval board
#
platform-$(CONFIG_MIPS_PB1000) += alchemy/devboards/
cflags-$(CONFIG_MIPS_PB1000) += -I$(srctree)/arch/mips/include/asm/mach-pb1x00
load-$(CONFIG_MIPS_PB1000) += 0xffffffff80100000
#
# AMD Alchemy Pb1100 eval board
#
platform-$(CONFIG_MIPS_PB1100) += alchemy/devboards/
cflags-$(CONFIG_MIPS_PB1100) += -I$(srctree)/arch/mips/include/asm/mach-pb1x00
load-$(CONFIG_MIPS_PB1100) += 0xffffffff80100000
#
# AMD Alchemy Pb1500 eval board
#
platform-$(CONFIG_MIPS_PB1500) += alchemy/devboards/
cflags-$(CONFIG_MIPS_PB1500) += -I$(srctree)/arch/mips/include/asm/mach-pb1x00
load-$(CONFIG_MIPS_PB1500) += 0xffffffff80100000
#
# AMD Alchemy Pb1550 eval board
#
platform-$(CONFIG_MIPS_PB1550) += alchemy/devboards/
cflags-$(CONFIG_MIPS_PB1550) += -I$(srctree)/arch/mips/include/asm/mach-pb1x00
load-$(CONFIG_MIPS_PB1550) += 0xffffffff80100000
#
# AMD Alchemy Pb1200 eval board
#
platform-$(CONFIG_MIPS_PB1200) += alchemy/devboards/
cflags-$(CONFIG_MIPS_PB1200) += -I$(srctree)/arch/mips/include/asm/mach-pb1x00
load-$(CONFIG_MIPS_PB1200) += 0xffffffff80100000
#
# AMD Alchemy Db1000 eval board
# AMD Alchemy Db1000/Db1500/Db1100 eval boards
#
platform-$(CONFIG_MIPS_DB1000) += alchemy/devboards/
cflags-$(CONFIG_MIPS_DB1000) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
load-$(CONFIG_MIPS_DB1000) += 0xffffffff80100000
#
# AMD Alchemy Db1100 eval board
#
platform-$(CONFIG_MIPS_DB1100) += alchemy/devboards/
cflags-$(CONFIG_MIPS_DB1100) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
load-$(CONFIG_MIPS_DB1100) += 0xffffffff80100000
#
# AMD Alchemy Db1500 eval board
#
platform-$(CONFIG_MIPS_DB1500) += alchemy/devboards/
cflags-$(CONFIG_MIPS_DB1500) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
load-$(CONFIG_MIPS_DB1500) += 0xffffffff80100000
#
# AMD Alchemy Db1550 eval board
#
@@ -68,42 +37,35 @@ cflags-$(CONFIG_MIPS_DB1550) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
load-$(CONFIG_MIPS_DB1550) += 0xffffffff80100000
#
# AMD Alchemy Db1200 eval board
# AMD Alchemy Db1200/Pb1200 eval boards
#
platform-$(CONFIG_MIPS_DB1200) += alchemy/devboards/
cflags-$(CONFIG_MIPS_DB1200) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
load-$(CONFIG_MIPS_DB1200) += 0xffffffff80100000
#
# AMD Alchemy Bosporus eval board
# NetLogic DBAu1300 development platform
#
platform-$(CONFIG_MIPS_BOSPORUS) += alchemy/devboards/
cflags-$(CONFIG_MIPS_BOSPORUS) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
load-$(CONFIG_MIPS_BOSPORUS) += 0xffffffff80100000
platform-$(CONFIG_MIPS_DB1300) += alchemy/devboards/
cflags-$(CONFIG_MIPS_DB1300) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
load-$(CONFIG_MIPS_DB1300) += 0xffffffff80100000
#
# AMD Alchemy Mirage eval board
# 4G-Systems MTX-1 "MeshCube" wireless router
#
platform-$(CONFIG_MIPS_MIRAGE) += alchemy/devboards/
cflags-$(CONFIG_MIPS_MIRAGE) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
load-$(CONFIG_MIPS_MIRAGE) += 0xffffffff80100000
#
# 4G-Systems eval board
#
platform-$(CONFIG_MIPS_MTX1) += alchemy/mtx-1/
platform-$(CONFIG_MIPS_MTX1) += alchemy/
load-$(CONFIG_MIPS_MTX1) += 0xffffffff80100000
#
# MyCable eval board
#
platform-$(CONFIG_MIPS_XXS1500) += alchemy/xxs1500/
platform-$(CONFIG_MIPS_XXS1500) += alchemy/
load-$(CONFIG_MIPS_XXS1500) += 0xffffffff80100000
#
# Trapeze ITS GRP board
#
platform-$(CONFIG_MIPS_GPR) += alchemy/gpr/
platform-$(CONFIG_MIPS_GPR) += alchemy/
load-$(CONFIG_MIPS_GPR) += 0xffffffff80100000
# boards can specify their own <gpio.h> in one of their include dirs.

View File

@@ -1,5 +1,5 @@
/*
* GPR board platform device registration
* GPR board platform device registration (Au1550)
*
* Copyright (C) 2010 Wolfgang Grandegger <wg@denx.de>
*
@@ -18,16 +18,89 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
#include <linux/leds.h>
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/i2c-gpio.h>
#include <asm/bootinfo.h>
#include <asm/reboot.h>
#include <asm/mach-au1x00/au1000.h>
#include <prom.h>
const char *get_system_type(void)
{
return "GPR";
}
void __init prom_init(void)
{
unsigned char *memsize_str;
unsigned long memsize;
prom_argc = fw_arg0;
prom_argv = (char **)fw_arg1;
prom_envp = (char **)fw_arg2;
prom_init_cmdline();
memsize_str = prom_getenv("memsize");
if (!memsize_str)
memsize = 0x04000000;
else
strict_strtoul(memsize_str, 0, &memsize);
add_memory_region(0, memsize, BOOT_MEM_RAM);
}
void prom_putchar(unsigned char c)
{
alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
}
static void gpr_reset(char *c)
{
/* switch System-LED to orange (red# and green# on) */
alchemy_gpio_direction_output(4, 0);
alchemy_gpio_direction_output(5, 0);
/* trigger watchdog to reset board in 200ms */
printk(KERN_EMERG "Triggering watchdog soft reset...\n");
raw_local_irq_disable();
alchemy_gpio_direction_output(1, 0);
udelay(1);
alchemy_gpio_set_value(1, 1);
while (1)
cpu_wait();
}
static void gpr_power_off(void)
{
while (1)
cpu_wait();
}
void __init board_setup(void)
{
printk(KERN_INFO "Trapeze ITS GPR board\n");
pm_power_off = gpr_power_off;
_machine_halt = gpr_power_off;
_machine_restart = gpr_reset;
/* Enable UART1/3 */
alchemy_uart_enable(AU1000_UART3_PHYS_ADDR);
alchemy_uart_enable(AU1000_UART1_PHYS_ADDR);
/* Take away Reset of UMTS-card */
alchemy_gpio_direction_output(215, 1);
}
/*
* Watchdog
@@ -152,7 +225,7 @@ static struct i2c_gpio_platform_data gpr_i2c_data = {
.scl_is_open_drain = 1,
.udelay = 2, /* ~100 kHz */
.timeout = HZ,
};
};
static struct platform_device gpr_i2c_device = {
.name = "i2c-gpio",
@@ -184,7 +257,7 @@ static int gpr_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin)
else if ((slot == 0) && (pin == 2))
return AU1550_PCI_INTB;
return -1;
return 0xff;
}
static struct alchemy_pci_platdata gpr_pci_pd = {

View File

@@ -1,5 +1,5 @@
/*
* MTX-1 platform devices registration
* MTX-1 platform devices registration (Au1500)
*
* Copyright (C) 2007-2009, Florian Fainelli <florian@openwrt.org>
*
@@ -19,6 +19,8 @@
*/
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/leds.h>
#include <linux/gpio.h>
@@ -27,8 +29,85 @@
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
#include <mtd/mtd-abi.h>
#include <asm/bootinfo.h>
#include <asm/reboot.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/au1xxx_eth.h>
#include <prom.h>
const char *get_system_type(void)
{
return "MTX-1";
}
void __init prom_init(void)
{
unsigned char *memsize_str;
unsigned long memsize;
prom_argc = fw_arg0;
prom_argv = (char **)fw_arg1;
prom_envp = (char **)fw_arg2;
prom_init_cmdline();
memsize_str = prom_getenv("memsize");
if (!memsize_str)
memsize = 0x04000000;
else
strict_strtoul(memsize_str, 0, &memsize);
add_memory_region(0, memsize, BOOT_MEM_RAM);
}
void prom_putchar(unsigned char c)
{
alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
}
static void mtx1_reset(char *c)
{
/* Jump to the reset vector */
__asm__ __volatile__("jr\t%0" : : "r"(0xbfc00000));
}
static void mtx1_power_off(void)
{
while (1)
asm volatile (
" .set mips32 \n"
" wait \n"
" .set mips0 \n");
}
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) */
/* Initialize sys_pinfunc */
au_writel(SYS_PF_NI2, SYS_PINFUNC);
/* Initialize GPIO */
au_writel(~0, KSEG1ADDR(AU1000_SYS_PHYS_ADDR) + 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");
}
/******************************************************************************/
static struct gpio_keys_button mtx1_gpio_button[] = {
{
@@ -195,7 +274,6 @@ static struct platform_device mtx1_pci_host = {
.resource = alchemy_pci_host_res,
};
static struct __initdata platform_device * mtx1_devs[] = {
&mtx1_pci_host,
&mtx1_gpio_leds,
@@ -206,13 +284,19 @@ static struct __initdata platform_device * mtx1_devs[] = {
static struct au1000_eth_platform_data mtx1_au1000_eth0_pdata = {
.phy_search_highest_addr = 1,
.phy1_search_mac0 = 1,
.phy1_search_mac0 = 1,
};
static int __init mtx1_register_devices(void)
{
int rc;
irq_set_irq_type(AU1500_GPIO204_INT, IRQ_TYPE_LEVEL_HIGH);
irq_set_irq_type(AU1500_GPIO201_INT, IRQ_TYPE_LEVEL_LOW);
irq_set_irq_type(AU1500_GPIO202_INT, IRQ_TYPE_LEVEL_LOW);
irq_set_irq_type(AU1500_GPIO203_INT, IRQ_TYPE_LEVEL_LOW);
irq_set_irq_type(AU1500_GPIO205_INT, IRQ_TYPE_LEVEL_LOW);
au1xxx_override_eth_cfg(0, &mtx1_au1000_eth0_pdata);
rc = gpio_request(mtx1_gpio_button[0].gpio,
@@ -226,5 +310,4 @@ static int __init mtx1_register_devices(void)
out:
return platform_add_devices(mtx1_devs, ARRAY_SIZE(mtx1_devs));
}
arch_initcall(mtx1_register_devices);

View File

@@ -0,0 +1,154 @@
/*
* BRIEF MODULE DESCRIPTION
* MyCable XXS1500 board support
*
* Copyright 2003, 2008 MontaVista Software Inc.
* Author: MontaVista Software, Inc. <source@mvista.com>
*
* 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 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/pm.h>
#include <asm/bootinfo.h>
#include <asm/reboot.h>
#include <asm/mach-au1x00/au1000.h>
#include <prom.h>
const char *get_system_type(void)
{
return "XXS1500";
}
void __init prom_init(void)
{
unsigned char *memsize_str;
unsigned long memsize;
prom_argc = fw_arg0;
prom_argv = (char **)fw_arg1;
prom_envp = (char **)fw_arg2;
prom_init_cmdline();
memsize_str = prom_getenv("memsize");
if (!memsize_str || strict_strtoul(memsize_str, 0, &memsize))
memsize = 0x04000000;
add_memory_region(0, memsize, BOOT_MEM_RAM);
}
void prom_putchar(unsigned char c)
{
alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
}
static void xxs1500_reset(char *c)
{
/* Jump to the reset vector */
__asm__ __volatile__("jr\t%0" : : "r"(0xbfc00000));
}
static void xxs1500_power_off(void)
{
while (1)
asm volatile (
" .set mips32 \n"
" wait \n"
" .set mips0 \n");
}
void __init board_setup(void)
{
u32 pin_func;
pm_power_off = xxs1500_power_off;
_machine_halt = xxs1500_power_off;
_machine_restart = xxs1500_reset;
alchemy_gpio1_input_enable();
alchemy_gpio2_enable();
/* Set multiple use pins (UART3/GPIO) to UART (it's used as UART too) */
pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_UR3;
pin_func |= SYS_PF_UR3;
au_writel(pin_func, SYS_PINFUNC);
/* Enable UART */
alchemy_uart_enable(AU1000_UART3_PHYS_ADDR);
/* Enable DTR (MCR bit 0) = USB power up */
__raw_writel(1, (void __iomem *)KSEG1ADDR(AU1000_UART3_PHYS_ADDR + 0x18));
wmb();
}
/******************************************************************************/
static struct resource xxs1500_pcmcia_res[] = {
{
.name = "pcmcia-io",
.flags = IORESOURCE_MEM,
.start = AU1000_PCMCIA_IO_PHYS_ADDR,
.end = AU1000_PCMCIA_IO_PHYS_ADDR + 0x000400000 - 1,
},
{
.name = "pcmcia-attr",
.flags = IORESOURCE_MEM,
.start = AU1000_PCMCIA_ATTR_PHYS_ADDR,
.end = AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
},
{
.name = "pcmcia-mem",
.flags = IORESOURCE_MEM,
.start = AU1000_PCMCIA_MEM_PHYS_ADDR,
.end = AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
},
};
static struct platform_device xxs1500_pcmcia_dev = {
.name = "xxs1500_pcmcia",
.id = -1,
.num_resources = ARRAY_SIZE(xxs1500_pcmcia_res),
.resource = xxs1500_pcmcia_res,
};
static struct platform_device *xxs1500_devs[] __initdata = {
&xxs1500_pcmcia_dev,
};
static int __init xxs1500_dev_init(void)
{
irq_set_irq_type(AU1500_GPIO204_INT, IRQ_TYPE_LEVEL_HIGH);
irq_set_irq_type(AU1500_GPIO201_INT, IRQ_TYPE_LEVEL_LOW);
irq_set_irq_type(AU1500_GPIO202_INT, IRQ_TYPE_LEVEL_LOW);
irq_set_irq_type(AU1500_GPIO203_INT, IRQ_TYPE_LEVEL_LOW);
irq_set_irq_type(AU1500_GPIO205_INT, IRQ_TYPE_LEVEL_LOW);
irq_set_irq_type(AU1500_GPIO207_INT, IRQ_TYPE_LEVEL_LOW);
irq_set_irq_type(AU1500_GPIO0_INT, IRQ_TYPE_LEVEL_LOW);
irq_set_irq_type(AU1500_GPIO1_INT, IRQ_TYPE_LEVEL_LOW);
irq_set_irq_type(AU1500_GPIO2_INT, IRQ_TYPE_LEVEL_LOW);
irq_set_irq_type(AU1500_GPIO3_INT, IRQ_TYPE_LEVEL_LOW);
irq_set_irq_type(AU1500_GPIO4_INT, IRQ_TYPE_LEVEL_LOW); /* CF irq */
irq_set_irq_type(AU1500_GPIO5_INT, IRQ_TYPE_LEVEL_LOW);
return platform_add_devices(xxs1500_devs,
ARRAY_SIZE(xxs1500_devs));
}
device_initcall(xxs1500_dev_init);

View File

@@ -6,9 +6,7 @@
#
obj-y += prom.o time.o clocks.o platform.o power.o setup.o \
sleeper.o dma.o dbdma.o
obj-$(CONFIG_ALCHEMY_GPIOINT_AU1000) += irq.o
sleeper.o dma.o dbdma.o vss.o irq.o
# optional gpiolib support
ifeq ($(CONFIG_ALCHEMY_GPIO_INDIRECT),)

View File

@@ -148,6 +148,50 @@ static dbdev_tab_t au1200_dbdev_tab[] __initdata = {
{ DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
};
static dbdev_tab_t au1300_dbdev_tab[] __initdata = {
{ AU1300_DSCR_CMD0_UART0_TX, DEV_FLAGS_OUT, 0, 8, 0x10100004, 0, 0 },
{ AU1300_DSCR_CMD0_UART0_RX, DEV_FLAGS_IN, 0, 8, 0x10100000, 0, 0 },
{ AU1300_DSCR_CMD0_UART1_TX, DEV_FLAGS_OUT, 0, 8, 0x10101004, 0, 0 },
{ AU1300_DSCR_CMD0_UART1_RX, DEV_FLAGS_IN, 0, 8, 0x10101000, 0, 0 },
{ AU1300_DSCR_CMD0_UART2_TX, DEV_FLAGS_OUT, 0, 8, 0x10102004, 0, 0 },
{ AU1300_DSCR_CMD0_UART2_RX, DEV_FLAGS_IN, 0, 8, 0x10102000, 0, 0 },
{ AU1300_DSCR_CMD0_UART3_TX, DEV_FLAGS_OUT, 0, 8, 0x10103004, 0, 0 },
{ AU1300_DSCR_CMD0_UART3_RX, DEV_FLAGS_IN, 0, 8, 0x10103000, 0, 0 },
{ AU1300_DSCR_CMD0_SDMS_TX0, DEV_FLAGS_OUT, 4, 8, 0x10600000, 0, 0 },
{ AU1300_DSCR_CMD0_SDMS_RX0, DEV_FLAGS_IN, 4, 8, 0x10600004, 0, 0 },
{ AU1300_DSCR_CMD0_SDMS_TX1, DEV_FLAGS_OUT, 8, 8, 0x10601000, 0, 0 },
{ AU1300_DSCR_CMD0_SDMS_RX1, DEV_FLAGS_IN, 8, 8, 0x10601004, 0, 0 },
{ AU1300_DSCR_CMD0_AES_RX, DEV_FLAGS_IN , 4, 32, 0x10300008, 0, 0 },
{ AU1300_DSCR_CMD0_AES_TX, DEV_FLAGS_OUT, 4, 32, 0x10300004, 0, 0 },
{ AU1300_DSCR_CMD0_PSC0_TX, DEV_FLAGS_OUT, 0, 16, 0x10a0001c, 0, 0 },
{ AU1300_DSCR_CMD0_PSC0_RX, DEV_FLAGS_IN, 0, 16, 0x10a0001c, 0, 0 },
{ AU1300_DSCR_CMD0_PSC1_TX, DEV_FLAGS_OUT, 0, 16, 0x10a0101c, 0, 0 },
{ AU1300_DSCR_CMD0_PSC1_RX, DEV_FLAGS_IN, 0, 16, 0x10a0101c, 0, 0 },
{ AU1300_DSCR_CMD0_PSC2_TX, DEV_FLAGS_OUT, 0, 16, 0x10a0201c, 0, 0 },
{ AU1300_DSCR_CMD0_PSC2_RX, DEV_FLAGS_IN, 0, 16, 0x10a0201c, 0, 0 },
{ AU1300_DSCR_CMD0_PSC3_TX, DEV_FLAGS_OUT, 0, 16, 0x10a0301c, 0, 0 },
{ AU1300_DSCR_CMD0_PSC3_RX, DEV_FLAGS_IN, 0, 16, 0x10a0301c, 0, 0 },
{ AU1300_DSCR_CMD0_LCD, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
{ AU1300_DSCR_CMD0_NAND_FLASH, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
{ AU1300_DSCR_CMD0_SDMS_TX2, DEV_FLAGS_OUT, 4, 8, 0x10602000, 0, 0 },
{ AU1300_DSCR_CMD0_SDMS_RX2, DEV_FLAGS_IN, 4, 8, 0x10602004, 0, 0 },
{ AU1300_DSCR_CMD0_CIM_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
{ AU1300_DSCR_CMD0_UDMA, DEV_FLAGS_ANYUSE, 0, 32, 0x14001810, 0, 0 },
{ AU1300_DSCR_CMD0_DMA_REQ0, 0, 0, 0, 0x00000000, 0, 0 },
{ AU1300_DSCR_CMD0_DMA_REQ1, 0, 0, 0, 0x00000000, 0, 0 },
{ DSCR_CMD0_THROTTLE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
{ DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
};
/* 32 predefined plus 32 custom */
#define DBDEV_TAB_SIZE 64
@@ -1037,6 +1081,8 @@ static int __init alchemy_dbdma_init(void)
return dbdma_setup(AU1550_DDMA_INT, au1550_dbdev_tab);
case ALCHEMY_CPU_AU1200:
return dbdma_setup(AU1200_DDMA_INT, au1200_dbdev_tab);
case ALCHEMY_CPU_AU1300:
return dbdma_setup(AU1300_DDMA_INT, au1300_dbdev_tab);
}
return 0;
}

View File

@@ -27,6 +27,7 @@
* CONFIG_ALCHEMY_GPIO_INDIRECT=n, otherwise compilation will fail!
* au1000 SoC have only one GPIO block : GPIO1
* Au1100, Au15x0, Au12x0 have a second one : GPIO2
* Au1300 is totally different: 1 block with up to 128 GPIOs
*/
#include <linux/init.h>
@@ -35,6 +36,7 @@
#include <linux/types.h>
#include <linux/gpio.h>
#include <asm/mach-au1x00/gpio-au1000.h>
#include <asm/mach-au1x00/gpio-au1300.h>
static int gpio2_get(struct gpio_chip *chip, unsigned offset)
{
@@ -115,6 +117,43 @@ struct gpio_chip alchemy_gpio_chip[] = {
},
};
static int alchemy_gpic_get(struct gpio_chip *chip, unsigned int off)
{
return au1300_gpio_get_value(off + AU1300_GPIO_BASE);
}
static void alchemy_gpic_set(struct gpio_chip *chip, unsigned int off, int v)
{
au1300_gpio_set_value(off + AU1300_GPIO_BASE, v);
}
static int alchemy_gpic_dir_input(struct gpio_chip *chip, unsigned int off)
{
return au1300_gpio_direction_input(off + AU1300_GPIO_BASE);
}
static int alchemy_gpic_dir_output(struct gpio_chip *chip, unsigned int off,
int v)
{
return au1300_gpio_direction_output(off + AU1300_GPIO_BASE, v);
}
static int alchemy_gpic_gpio_to_irq(struct gpio_chip *chip, unsigned int off)
{
return au1300_gpio_to_irq(off + AU1300_GPIO_BASE);
}
static struct gpio_chip au1300_gpiochip = {
.label = "alchemy-gpic",
.direction_input = alchemy_gpic_dir_input,
.direction_output = alchemy_gpic_dir_output,
.get = alchemy_gpic_get,
.set = alchemy_gpic_set,
.to_irq = alchemy_gpic_gpio_to_irq,
.base = AU1300_GPIO_BASE,
.ngpio = AU1300_GPIO_NUM,
};
static int __init alchemy_gpiochip_init(void)
{
int ret = 0;
@@ -127,6 +166,9 @@ static int __init alchemy_gpiochip_init(void)
ret = gpiochip_add(&alchemy_gpio_chip[0]);
ret |= gpiochip_add(&alchemy_gpio_chip[1]);
break;
case ALCHEMY_CPU_AU1300:
ret = gpiochip_add(&au1300_gpiochip);
break;
}
return ret;
}

View File

@@ -25,19 +25,15 @@
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/bitops.h>
#include <linux/export.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/slab.h>
#include <linux/syscore_ops.h>
#include <asm/irq_cpu.h>
#include <asm/mipsregs.h>
#include <asm/mach-au1x00/au1000.h>
#ifdef CONFIG_MIPS_PB1000
#include <asm/mach-pb1x00/pb1000.h>
#endif
#include <asm/mach-au1x00/gpio-au1300.h>
/* Interrupt Controller register offsets */
#define IC_CFG0RD 0x40
@@ -69,7 +65,17 @@
#define IC_FALLINGCLR 0x7C
#define IC_TESTBIT 0x80
static int au1x_ic_settype(struct irq_data *d, unsigned int flow_type);
/* per-processor fixed function irqs */
struct alchemy_irqmap {
int irq; /* linux IRQ number */
int type; /* IRQ_TYPE_ */
int prio; /* irq priority, 0 highest, 3 lowest */
int internal; /* GPIC: internal source (no ext. pin)? */
};
static int au1x_ic_settype(struct irq_data *d, unsigned int type);
static int au1300_gpic_settype(struct irq_data *d, unsigned int type);
/* NOTE on interrupt priorities: The original writers of this code said:
*
@@ -77,176 +83,207 @@ static int au1x_ic_settype(struct irq_data *d, unsigned int flow_type);
* the USB devices-side packet complete interrupt (USB_DEV_REQ_INT)
* needs the highest priority.
*/
/* per-processor fixed function irqs */
struct au1xxx_irqmap {
int im_irq;
int im_type;
int im_request; /* set 1 to get higher priority */
};
struct au1xxx_irqmap au1000_irqmap[] __initdata = {
{ AU1000_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_UART2_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
{ AU1000_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 1 },
{ AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
{ AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 },
struct alchemy_irqmap au1000_irqmap[] __initdata = {
{ AU1000_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1000_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1000_UART2_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1000_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1000_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1000_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1000_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1000_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1000_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1000_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1000_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1000_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1000_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1000_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0, 0 },
{ AU1000_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1000_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0, 0 },
{ AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 1, 0 },
{ AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1000_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1000_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1000_AC97C_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ -1, },
};
struct au1xxx_irqmap au1500_irqmap[] __initdata = {
{ AU1500_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1500_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 0 },
{ AU1500_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 0 },
{ AU1500_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1500_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 0 },
{ AU1500_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 0 },
{ AU1500_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1500_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1500_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1500_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1500_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1500_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1500_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1500_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1500_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1500_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1500_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1500_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1500_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1500_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1500_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1500_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
{ AU1500_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 1 },
{ AU1500_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1500_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
{ AU1500_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1500_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1500_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1500_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 },
struct alchemy_irqmap au1500_irqmap[] __initdata = {
{ AU1500_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1500_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 1, 0 },
{ AU1500_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 1, 0 },
{ AU1500_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1500_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 1, 0 },
{ AU1500_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 1, 0 },
{ AU1500_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1500_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1500_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1500_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1500_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1500_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1500_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1500_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1500_TOY_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1500_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1500_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1500_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1500_RTC_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1500_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1500_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1500_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0, 0 },
{ AU1500_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0, 0 },
{ AU1500_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1500_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 1, 0 },
{ AU1500_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1500_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1500_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1500_AC97C_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ -1, },
};
struct au1xxx_irqmap au1100_irqmap[] __initdata = {
{ AU1100_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1100_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1100_SD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1100_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1100_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1100_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1100_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1100_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1100_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1100_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1100_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1100_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1100_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1100_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1100_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1100_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1100_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1100_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1100_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1100_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1100_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1100_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
{ AU1100_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1100_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1100_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 1 },
{ AU1100_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1100_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
{ AU1100_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1100_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1100_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1100_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 },
struct alchemy_irqmap au1100_irqmap[] __initdata = {
{ AU1100_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1100_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1100_SD_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1100_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1100_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1100_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1100_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1100_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1100_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1100_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1100_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1100_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1100_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1100_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1100_TOY_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1100_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1100_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1100_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1100_RTC_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1100_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1100_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1100_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0, 0 },
{ AU1100_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1100_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1100_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0, 0 },
{ AU1100_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1100_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 1, 0 },
{ AU1100_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1100_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1100_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1100_AC97C_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ -1, },
};
struct au1xxx_irqmap au1550_irqmap[] __initdata = {
{ AU1550_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1550_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 0 },
{ AU1550_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 0 },
{ AU1550_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1550_CRYPTO_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1550_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 0 },
{ AU1550_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 0 },
{ AU1550_PCI_RST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
{ AU1550_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1550_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1550_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1550_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1550_PSC2_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1550_PSC3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1550_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1550_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1550_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1550_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1550_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1550_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1550_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1550_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
{ AU1550_NAND_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1550_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 1 },
{ AU1550_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1550_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
{ AU1550_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1550_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
struct alchemy_irqmap au1550_irqmap[] __initdata = {
{ AU1550_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1550_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 1, 0 },
{ AU1550_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 1, 0 },
{ AU1550_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1550_CRYPTO_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1550_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 1, 0 },
{ AU1550_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 1, 0 },
{ AU1550_PCI_RST_INT, IRQ_TYPE_LEVEL_LOW, 1, 0 },
{ AU1550_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1550_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1550_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1550_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1550_PSC2_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1550_PSC3_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1550_TOY_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1550_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1550_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1550_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1550_RTC_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1550_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1550_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1550_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0, 0 },
{ AU1550_NAND_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1550_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0, 0 },
{ AU1550_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1550_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 1, 0 },
{ AU1550_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1550_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ -1, },
};
struct au1xxx_irqmap au1200_irqmap[] __initdata = {
{ AU1200_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1200_SWT_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1200_SD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1200_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1200_MAE_BE_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1200_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1200_MAE_FE_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1200_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1200_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1200_AES_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1200_CAMERA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1200_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1200_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1200_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1200_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1200_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1200_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1200_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1200_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
{ AU1200_NAND_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1200_USB_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1200_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1200_MAE_BOTH_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
struct alchemy_irqmap au1200_irqmap[] __initdata = {
{ AU1200_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1200_SWT_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1200_SD_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1200_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1200_MAE_BE_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1200_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1200_MAE_FE_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1200_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1200_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1200_AES_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1200_CAMERA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1200_TOY_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1200_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1200_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1200_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1200_RTC_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1200_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1200_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1200_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0, 0 },
{ AU1200_NAND_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ AU1200_USB_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1200_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ AU1200_MAE_BOTH_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ -1, },
};
static struct alchemy_irqmap au1300_irqmap[] __initdata = {
/* multifunction: gpio pin or device */
{ AU1300_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0, },
{ AU1300_UART2_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0, },
{ AU1300_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0, },
{ AU1300_SD1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0, },
{ AU1300_SD2_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0, },
{ AU1300_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0, },
{ AU1300_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0, },
{ AU1300_PSC2_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0, },
{ AU1300_PSC3_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0, },
{ AU1300_NAND_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0, },
/* au1300 internal */
{ AU1300_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, },
{ AU1300_MMU_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, },
{ AU1300_MPU_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, },
{ AU1300_GPU_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, },
{ AU1300_UDMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, },
{ AU1300_TOY_INT, IRQ_TYPE_EDGE_RISING, 1, 1, },
{ AU1300_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 1, },
{ AU1300_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 1, },
{ AU1300_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1, 1, },
{ AU1300_RTC_INT, IRQ_TYPE_EDGE_RISING, 1, 1, },
{ AU1300_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 1, },
{ AU1300_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 1, },
{ AU1300_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0, 1, },
{ AU1300_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, },
{ AU1300_SD0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, },
{ AU1300_USB_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, },
{ AU1300_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, },
{ AU1300_BSA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, },
{ AU1300_MPE_INT, IRQ_TYPE_EDGE_RISING, 1, 1, },
{ AU1300_ITE_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, },
{ AU1300_AES_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, },
{ AU1300_CIM_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, },
{ -1, }, /* terminator */
};
/******************************************************************************/
static void au1x_ic0_unmask(struct irq_data *d)
{
@@ -265,14 +302,6 @@ static void au1x_ic1_unmask(struct irq_data *d)
__raw_writel(1 << bit, base + IC_MASKSET);
__raw_writel(1 << bit, base + IC_WAKESET);
/* very hacky. does the pb1000 cpld auto-disable this int?
* nowhere in the current kernel sources is it disabled. --mlau
*/
#if defined(CONFIG_MIPS_PB1000)
if (d->irq == AU1000_GPIO15_INT)
__raw_writel(0x4000, (void __iomem *)PB1000_MDR); /* enable int */
#endif
wmb();
}
@@ -470,40 +499,219 @@ static int au1x_ic_settype(struct irq_data *d, unsigned int flow_type)
return ret;
}
asmlinkage void plat_irq_dispatch(void)
/******************************************************************************/
/*
* au1300_gpic_chgcfg - change PIN configuration.
* @gpio: pin to change (0-based GPIO number from datasheet).
* @clr: clear all bits set in 'clr'.
* @set: set these bits.
*
* modifies a pins' configuration register, bits set in @clr will
* be cleared in the register, bits in @set will be set.
*/
static inline void au1300_gpic_chgcfg(unsigned int gpio,
unsigned long clr,
unsigned long set)
{
unsigned int pending = read_c0_status() & read_c0_cause();
unsigned long s, off;
void __iomem *r = AU1300_GPIC_ADDR;
unsigned long l;
if (pending & CAUSEF_IP7) {
off = MIPS_CPU_IRQ_BASE + 7;
goto handle;
} else if (pending & CAUSEF_IP2) {
s = KSEG1ADDR(AU1000_IC0_PHYS_ADDR) + IC_REQ0INT;
off = AU1000_INTC0_INT_BASE;
} else if (pending & CAUSEF_IP3) {
s = KSEG1ADDR(AU1000_IC0_PHYS_ADDR) + IC_REQ1INT;
off = AU1000_INTC0_INT_BASE;
} else if (pending & CAUSEF_IP4) {
s = KSEG1ADDR(AU1000_IC1_PHYS_ADDR) + IC_REQ0INT;
off = AU1000_INTC1_INT_BASE;
} else if (pending & CAUSEF_IP5) {
s = KSEG1ADDR(AU1000_IC1_PHYS_ADDR) + IC_REQ1INT;
off = AU1000_INTC1_INT_BASE;
} else
goto spurious;
s = __raw_readl((void __iomem *)s);
if (unlikely(!s)) {
spurious:
spurious_interrupt();
return;
}
off += __ffs(s);
handle:
do_IRQ(off);
r += gpio * 4; /* offset into pin config array */
l = __raw_readl(r + AU1300_GPIC_PINCFG);
l &= ~clr;
l |= set;
__raw_writel(l, r + AU1300_GPIC_PINCFG);
wmb();
}
/*
* au1300_pinfunc_to_gpio - assign a pin as GPIO input (GPIO ctrl).
* @pin: pin (0-based GPIO number from datasheet).
*
* Assigns a GPIO pin to the GPIO controller, so its level can either
* be read or set through the generic GPIO functions.
* If you need a GPOUT, use au1300_gpio_set_value(pin, 0/1).
* REVISIT: is this function really necessary?
*/
void au1300_pinfunc_to_gpio(enum au1300_multifunc_pins gpio)
{
au1300_gpio_direction_input(gpio + AU1300_GPIO_BASE);
}
EXPORT_SYMBOL_GPL(au1300_pinfunc_to_gpio);
/*
* au1300_pinfunc_to_dev - assign a pin to the device function.
* @pin: pin (0-based GPIO number from datasheet).
*
* Assigns a GPIO pin to its associated device function; the pin will be
* driven by the device and not through GPIO functions.
*/
void au1300_pinfunc_to_dev(enum au1300_multifunc_pins gpio)
{
void __iomem *r = AU1300_GPIC_ADDR;
unsigned long bit;
r += GPIC_GPIO_BANKOFF(gpio);
bit = GPIC_GPIO_TO_BIT(gpio);
__raw_writel(bit, r + AU1300_GPIC_DEVSEL);
wmb();
}
EXPORT_SYMBOL_GPL(au1300_pinfunc_to_dev);
/*
* au1300_set_irq_priority - set internal priority of IRQ.
* @irq: irq to set priority (linux irq number).
* @p: priority (0 = highest, 3 = lowest).
*/
void au1300_set_irq_priority(unsigned int irq, int p)
{
irq -= ALCHEMY_GPIC_INT_BASE;
au1300_gpic_chgcfg(irq, GPIC_CFG_IL_MASK, GPIC_CFG_IL_SET(p));
}
EXPORT_SYMBOL_GPL(au1300_set_irq_priority);
/*
* au1300_set_dbdma_gpio - assign a gpio to one of the DBDMA triggers.
* @dchan: dbdma trigger select (0, 1).
* @gpio: pin to assign as trigger.
*
* DBDMA controller has 2 external trigger sources; this function
* assigns a GPIO to the selected trigger.
*/
void au1300_set_dbdma_gpio(int dchan, unsigned int gpio)
{
unsigned long r;
if ((dchan >= 0) && (dchan <= 1)) {
r = __raw_readl(AU1300_GPIC_ADDR + AU1300_GPIC_DMASEL);
r &= ~(0xff << (8 * dchan));
r |= (gpio & 0x7f) << (8 * dchan);
__raw_writel(r, AU1300_GPIC_ADDR + AU1300_GPIC_DMASEL);
wmb();
}
}
static inline void gpic_pin_set_idlewake(unsigned int gpio, int allow)
{
au1300_gpic_chgcfg(gpio, GPIC_CFG_IDLEWAKE,
allow ? GPIC_CFG_IDLEWAKE : 0);
}
static void au1300_gpic_mask(struct irq_data *d)
{
void __iomem *r = AU1300_GPIC_ADDR;
unsigned long bit, irq = d->irq;
irq -= ALCHEMY_GPIC_INT_BASE;
r += GPIC_GPIO_BANKOFF(irq);
bit = GPIC_GPIO_TO_BIT(irq);
__raw_writel(bit, r + AU1300_GPIC_IDIS);
wmb();
gpic_pin_set_idlewake(irq, 0);
}
static void au1300_gpic_unmask(struct irq_data *d)
{
void __iomem *r = AU1300_GPIC_ADDR;
unsigned long bit, irq = d->irq;
irq -= ALCHEMY_GPIC_INT_BASE;
gpic_pin_set_idlewake(irq, 1);
r += GPIC_GPIO_BANKOFF(irq);
bit = GPIC_GPIO_TO_BIT(irq);
__raw_writel(bit, r + AU1300_GPIC_IEN);
wmb();
}
static void au1300_gpic_maskack(struct irq_data *d)
{
void __iomem *r = AU1300_GPIC_ADDR;
unsigned long bit, irq = d->irq;
irq -= ALCHEMY_GPIC_INT_BASE;
r += GPIC_GPIO_BANKOFF(irq);
bit = GPIC_GPIO_TO_BIT(irq);
__raw_writel(bit, r + AU1300_GPIC_IPEND); /* ack */
__raw_writel(bit, r + AU1300_GPIC_IDIS); /* mask */
wmb();
gpic_pin_set_idlewake(irq, 0);
}
static void au1300_gpic_ack(struct irq_data *d)
{
void __iomem *r = AU1300_GPIC_ADDR;
unsigned long bit, irq = d->irq;
irq -= ALCHEMY_GPIC_INT_BASE;
r += GPIC_GPIO_BANKOFF(irq);
bit = GPIC_GPIO_TO_BIT(irq);
__raw_writel(bit, r + AU1300_GPIC_IPEND); /* ack */
wmb();
}
static struct irq_chip au1300_gpic = {
.name = "GPIOINT",
.irq_ack = au1300_gpic_ack,
.irq_mask = au1300_gpic_mask,
.irq_mask_ack = au1300_gpic_maskack,
.irq_unmask = au1300_gpic_unmask,
.irq_set_type = au1300_gpic_settype,
};
static int au1300_gpic_settype(struct irq_data *d, unsigned int type)
{
unsigned long s;
unsigned char *name = NULL;
irq_flow_handler_t hdl = NULL;
switch (type) {
case IRQ_TYPE_LEVEL_HIGH:
s = GPIC_CFG_IC_LEVEL_HIGH;
name = "high";
hdl = handle_level_irq;
break;
case IRQ_TYPE_LEVEL_LOW:
s = GPIC_CFG_IC_LEVEL_LOW;
name = "low";
hdl = handle_level_irq;
break;
case IRQ_TYPE_EDGE_RISING:
s = GPIC_CFG_IC_EDGE_RISE;
name = "posedge";
hdl = handle_edge_irq;
break;
case IRQ_TYPE_EDGE_FALLING:
s = GPIC_CFG_IC_EDGE_FALL;
name = "negedge";
hdl = handle_edge_irq;
break;
case IRQ_TYPE_EDGE_BOTH:
s = GPIC_CFG_IC_EDGE_BOTH;
name = "bothedge";
hdl = handle_edge_irq;
break;
case IRQ_TYPE_NONE:
s = GPIC_CFG_IC_OFF;
name = "disabled";
hdl = handle_level_irq;
break;
default:
return -EINVAL;
}
__irq_set_chip_handler_name_locked(d->irq, &au1300_gpic, hdl, name);
au1300_gpic_chgcfg(d->irq - ALCHEMY_GPIC_INT_BASE, GPIC_CFG_IC_MASK, s);
return 0;
}
/******************************************************************************/
static inline void ic_init(void __iomem *base)
{
@@ -521,72 +729,7 @@ static inline void ic_init(void __iomem *base)
wmb();
}
static void __init au1000_init_irq(struct au1xxx_irqmap *map)
{
unsigned int bit, irq_nr;
void __iomem *base;
ic_init((void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR));
ic_init((void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR));
mips_cpu_irq_init();
/* register all 64 possible IC0+IC1 irq sources as type "none".
* Use set_irq_type() to set edge/level behaviour at runtime.
*/
for (irq_nr = AU1000_INTC0_INT_BASE;
(irq_nr < AU1000_INTC0_INT_BASE + 32); irq_nr++)
au1x_ic_settype(irq_get_irq_data(irq_nr), IRQ_TYPE_NONE);
for (irq_nr = AU1000_INTC1_INT_BASE;
(irq_nr < AU1000_INTC1_INT_BASE + 32); irq_nr++)
au1x_ic_settype(irq_get_irq_data(irq_nr), IRQ_TYPE_NONE);
/*
* Initialize IC0, which is fixed per processor.
*/
while (map->im_irq != -1) {
irq_nr = map->im_irq;
if (irq_nr >= AU1000_INTC1_INT_BASE) {
bit = irq_nr - AU1000_INTC1_INT_BASE;
base = (void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR);
} else {
bit = irq_nr - AU1000_INTC0_INT_BASE;
base = (void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR);
}
if (map->im_request)
__raw_writel(1 << bit, base + IC_ASSIGNSET);
au1x_ic_settype(irq_get_irq_data(irq_nr), map->im_type);
++map;
}
set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3);
}
void __init arch_init_irq(void)
{
switch (alchemy_get_cputype()) {
case ALCHEMY_CPU_AU1000:
au1000_init_irq(au1000_irqmap);
break;
case ALCHEMY_CPU_AU1500:
au1000_init_irq(au1500_irqmap);
break;
case ALCHEMY_CPU_AU1100:
au1000_init_irq(au1100_irqmap);
break;
case ALCHEMY_CPU_AU1550:
au1000_init_irq(au1550_irqmap);
break;
case ALCHEMY_CPU_AU1200:
au1000_init_irq(au1200_irqmap);
break;
}
}
static unsigned long alchemy_ic_pmdata[7 * 2];
static unsigned long alchemy_gpic_pmdata[ALCHEMY_GPIC_INT_NUM + 6];
static inline void alchemy_ic_suspend_one(void __iomem *base, unsigned long *d)
{
@@ -619,28 +762,236 @@ static inline void alchemy_ic_resume_one(void __iomem *base, unsigned long *d)
static int alchemy_ic_suspend(void)
{
alchemy_ic_suspend_one((void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR),
alchemy_ic_pmdata);
alchemy_gpic_pmdata);
alchemy_ic_suspend_one((void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR),
&alchemy_ic_pmdata[7]);
&alchemy_gpic_pmdata[7]);
return 0;
}
static void alchemy_ic_resume(void)
{
alchemy_ic_resume_one((void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR),
&alchemy_ic_pmdata[7]);
&alchemy_gpic_pmdata[7]);
alchemy_ic_resume_one((void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR),
alchemy_ic_pmdata);
alchemy_gpic_pmdata);
}
static struct syscore_ops alchemy_ic_syscore_ops = {
static int alchemy_gpic_suspend(void)
{
void __iomem *base = (void __iomem *)KSEG1ADDR(AU1300_GPIC_PHYS_ADDR);
int i;
/* save 4 interrupt mask status registers */
alchemy_gpic_pmdata[0] = __raw_readl(base + AU1300_GPIC_IEN + 0x0);
alchemy_gpic_pmdata[1] = __raw_readl(base + AU1300_GPIC_IEN + 0x4);
alchemy_gpic_pmdata[2] = __raw_readl(base + AU1300_GPIC_IEN + 0x8);
alchemy_gpic_pmdata[3] = __raw_readl(base + AU1300_GPIC_IEN + 0xc);
/* save misc register(s) */
alchemy_gpic_pmdata[4] = __raw_readl(base + AU1300_GPIC_DMASEL);
/* molto silenzioso */
__raw_writel(~0UL, base + AU1300_GPIC_IDIS + 0x0);
__raw_writel(~0UL, base + AU1300_GPIC_IDIS + 0x4);
__raw_writel(~0UL, base + AU1300_GPIC_IDIS + 0x8);
__raw_writel(~0UL, base + AU1300_GPIC_IDIS + 0xc);
wmb();
/* save pin/int-type configuration */
base += AU1300_GPIC_PINCFG;
for (i = 0; i < ALCHEMY_GPIC_INT_NUM; i++)
alchemy_gpic_pmdata[i + 5] = __raw_readl(base + (i << 2));
wmb();
return 0;
}
static void alchemy_gpic_resume(void)
{
void __iomem *base = (void __iomem *)KSEG1ADDR(AU1300_GPIC_PHYS_ADDR);
int i;
/* disable all first */
__raw_writel(~0UL, base + AU1300_GPIC_IDIS + 0x0);
__raw_writel(~0UL, base + AU1300_GPIC_IDIS + 0x4);
__raw_writel(~0UL, base + AU1300_GPIC_IDIS + 0x8);
__raw_writel(~0UL, base + AU1300_GPIC_IDIS + 0xc);
wmb();
/* restore pin/int-type configurations */
base += AU1300_GPIC_PINCFG;
for (i = 0; i < ALCHEMY_GPIC_INT_NUM; i++)
__raw_writel(alchemy_gpic_pmdata[i + 5], base + (i << 2));
wmb();
/* restore misc register(s) */
base = (void __iomem *)KSEG1ADDR(AU1300_GPIC_PHYS_ADDR);
__raw_writel(alchemy_gpic_pmdata[4], base + AU1300_GPIC_DMASEL);
wmb();
/* finally restore masks */
__raw_writel(alchemy_gpic_pmdata[0], base + AU1300_GPIC_IEN + 0x0);
__raw_writel(alchemy_gpic_pmdata[1], base + AU1300_GPIC_IEN + 0x4);
__raw_writel(alchemy_gpic_pmdata[2], base + AU1300_GPIC_IEN + 0x8);
__raw_writel(alchemy_gpic_pmdata[3], base + AU1300_GPIC_IEN + 0xc);
wmb();
}
static struct syscore_ops alchemy_ic_pmops = {
.suspend = alchemy_ic_suspend,
.resume = alchemy_ic_resume,
};
static int __init alchemy_ic_pm_init(void)
{
register_syscore_ops(&alchemy_ic_syscore_ops);
return 0;
static struct syscore_ops alchemy_gpic_pmops = {
.suspend = alchemy_gpic_suspend,
.resume = alchemy_gpic_resume,
};
/******************************************************************************/
/* create chained handlers for the 4 IC requests to the MIPS IRQ ctrl */
#define DISP(name, base, addr) \
static void au1000_##name##_dispatch(unsigned int irq, struct irq_desc *d) \
{ \
unsigned long r = __raw_readl((void __iomem *)KSEG1ADDR(addr)); \
if (likely(r)) \
generic_handle_irq(base + __ffs(r)); \
else \
spurious_interrupt(); \
}
DISP(ic0r0, AU1000_INTC0_INT_BASE, AU1000_IC0_PHYS_ADDR + IC_REQ0INT)
DISP(ic0r1, AU1000_INTC0_INT_BASE, AU1000_IC0_PHYS_ADDR + IC_REQ1INT)
DISP(ic1r0, AU1000_INTC1_INT_BASE, AU1000_IC1_PHYS_ADDR + IC_REQ0INT)
DISP(ic1r1, AU1000_INTC1_INT_BASE, AU1000_IC1_PHYS_ADDR + IC_REQ1INT)
static void alchemy_gpic_dispatch(unsigned int irq, struct irq_desc *d)
{
int i = __raw_readl(AU1300_GPIC_ADDR + AU1300_GPIC_PRIENC);
generic_handle_irq(ALCHEMY_GPIC_INT_BASE + i);
}
/******************************************************************************/
static void __init au1000_init_irq(struct alchemy_irqmap *map)
{
unsigned int bit, irq_nr;
void __iomem *base;
ic_init((void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR));
ic_init((void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR));
register_syscore_ops(&alchemy_ic_pmops);
mips_cpu_irq_init();
/* register all 64 possible IC0+IC1 irq sources as type "none".
* Use set_irq_type() to set edge/level behaviour at runtime.
*/
for (irq_nr = AU1000_INTC0_INT_BASE;
(irq_nr < AU1000_INTC0_INT_BASE + 32); irq_nr++)
au1x_ic_settype(irq_get_irq_data(irq_nr), IRQ_TYPE_NONE);
for (irq_nr = AU1000_INTC1_INT_BASE;
(irq_nr < AU1000_INTC1_INT_BASE + 32); irq_nr++)
au1x_ic_settype(irq_get_irq_data(irq_nr), IRQ_TYPE_NONE);
/*
* Initialize IC0, which is fixed per processor.
*/
while (map->irq != -1) {
irq_nr = map->irq;
if (irq_nr >= AU1000_INTC1_INT_BASE) {
bit = irq_nr - AU1000_INTC1_INT_BASE;
base = (void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR);
} else {
bit = irq_nr - AU1000_INTC0_INT_BASE;
base = (void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR);
}
if (map->prio == 0)
__raw_writel(1 << bit, base + IC_ASSIGNSET);
au1x_ic_settype(irq_get_irq_data(irq_nr), map->type);
++map;
}
irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 2, au1000_ic0r0_dispatch);
irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 3, au1000_ic0r1_dispatch);
irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 4, au1000_ic1r0_dispatch);
irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 5, au1000_ic1r1_dispatch);
}
static void __init alchemy_gpic_init_irq(const struct alchemy_irqmap *dints)
{
int i;
void __iomem *bank_base;
register_syscore_ops(&alchemy_gpic_pmops);
mips_cpu_irq_init();
/* disable & ack all possible interrupt sources */
for (i = 0; i < 4; i++) {
bank_base = AU1300_GPIC_ADDR + (i * 4);
__raw_writel(~0UL, bank_base + AU1300_GPIC_IDIS);
wmb();
__raw_writel(~0UL, bank_base + AU1300_GPIC_IPEND);
wmb();
}
/* register an irq_chip for them, with 2nd highest priority */
for (i = ALCHEMY_GPIC_INT_BASE; i <= ALCHEMY_GPIC_INT_LAST; i++) {
au1300_set_irq_priority(i, 1);
au1300_gpic_settype(irq_get_irq_data(i), IRQ_TYPE_NONE);
}
/* setup known on-chip sources */
while ((i = dints->irq) != -1) {
au1300_gpic_settype(irq_get_irq_data(i), dints->type);
au1300_set_irq_priority(i, dints->prio);
if (dints->internal)
au1300_pinfunc_to_dev(i - ALCHEMY_GPIC_INT_BASE);
dints++;
}
irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 2, alchemy_gpic_dispatch);
irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 3, alchemy_gpic_dispatch);
irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 4, alchemy_gpic_dispatch);
irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 5, alchemy_gpic_dispatch);
}
/******************************************************************************/
void __init arch_init_irq(void)
{
switch (alchemy_get_cputype()) {
case ALCHEMY_CPU_AU1000:
au1000_init_irq(au1000_irqmap);
break;
case ALCHEMY_CPU_AU1500:
au1000_init_irq(au1500_irqmap);
break;
case ALCHEMY_CPU_AU1100:
au1000_init_irq(au1100_irqmap);
break;
case ALCHEMY_CPU_AU1550:
au1000_init_irq(au1550_irqmap);
break;
case ALCHEMY_CPU_AU1200:
au1000_init_irq(au1200_irqmap);
break;
case ALCHEMY_CPU_AU1300:
alchemy_gpic_init_irq(au1300_irqmap);
break;
default:
pr_err("unknown Alchemy IRQ core\n");
break;
}
}
asmlinkage void plat_irq_dispatch(void)
{
unsigned long r = (read_c0_status() & read_c0_cause()) >> 8;
do_IRQ(MIPS_CPU_IRQ_BASE + __ffs(r & 0xff));
}
device_initcall(alchemy_ic_pm_init);

View File

@@ -82,6 +82,12 @@ static struct plat_serial8250_port au1x00_uart_data[][4] __initdata = {
PORT(AU1000_UART0_PHYS_ADDR, AU1200_UART0_INT),
PORT(AU1000_UART1_PHYS_ADDR, AU1200_UART1_INT),
},
[ALCHEMY_CPU_AU1300] = {
PORT(AU1300_UART0_PHYS_ADDR, AU1300_UART0_INT),
PORT(AU1300_UART1_PHYS_ADDR, AU1300_UART1_INT),
PORT(AU1300_UART2_PHYS_ADDR, AU1300_UART2_INT),
PORT(AU1300_UART3_PHYS_ADDR, AU1300_UART3_INT),
},
};
static struct platform_device au1xx0_uart_device = {
@@ -122,10 +128,12 @@ static unsigned long alchemy_ohci_data[][2] __initdata = {
[ALCHEMY_CPU_AU1100] = { AU1000_USB_OHCI_PHYS_ADDR, AU1100_USB_HOST_INT },
[ALCHEMY_CPU_AU1550] = { AU1550_USB_OHCI_PHYS_ADDR, AU1550_USB_HOST_INT },
[ALCHEMY_CPU_AU1200] = { AU1200_USB_OHCI_PHYS_ADDR, AU1200_USB_INT },
[ALCHEMY_CPU_AU1300] = { AU1300_USB_OHCI0_PHYS_ADDR, AU1300_USB_INT },
};
static unsigned long alchemy_ehci_data[][2] __initdata = {
[ALCHEMY_CPU_AU1200] = { AU1200_USB_EHCI_PHYS_ADDR, AU1200_USB_INT },
[ALCHEMY_CPU_AU1300] = { AU1300_USB_EHCI_PHYS_ADDR, AU1300_USB_INT },
};
static int __init _new_usbres(struct resource **r, struct platform_device **d)
@@ -169,8 +177,8 @@ static void __init alchemy_setup_usb(int ctype)
printk(KERN_INFO "Alchemy USB: cannot add OHCI0\n");
/* setup EHCI0: Au1200 */
if (ctype == ALCHEMY_CPU_AU1200) {
/* setup EHCI0: Au1200/Au1300 */
if ((ctype == ALCHEMY_CPU_AU1200) || (ctype == ALCHEMY_CPU_AU1300)) {
if (_new_usbres(&res, &pdev))
return;
@@ -187,6 +195,25 @@ static void __init alchemy_setup_usb(int ctype)
if (platform_device_register(pdev))
printk(KERN_INFO "Alchemy USB: cannot add EHCI0\n");
}
/* Au1300: OHCI1 */
if (ctype == ALCHEMY_CPU_AU1300) {
if (_new_usbres(&res, &pdev))
return;
res[0].start = AU1300_USB_OHCI1_PHYS_ADDR;
res[0].end = res[0].start + 0x100 - 1;
res[0].flags = IORESOURCE_MEM;
res[1].start = AU1300_USB_INT;
res[1].end = res[1].start;
res[1].flags = IORESOURCE_IRQ;
pdev->name = "au1xxx-ohci";
pdev->id = 1;
pdev->dev.dma_mask = &alchemy_ohci_dmamask;
if (platform_device_register(pdev))
printk(KERN_INFO "Alchemy USB: cannot add OHCI1\n");
}
}
/* Macro to help defining the Ethernet MAC resources */

View File

@@ -126,6 +126,9 @@ void au_sleep(void)
case ALCHEMY_CPU_AU1200:
alchemy_sleep_au1550();
break;
case ALCHEMY_CPU_AU1300:
alchemy_sleep_au1300();
break;
}
restore_core_regs();

View File

@@ -153,6 +153,79 @@ LEAF(alchemy_sleep_au1550)
END(alchemy_sleep_au1550)
/* sleepcode for Au1300 memory controller type */
LEAF(alchemy_sleep_au1300)
SETUP_SLEEP
/* cache following instructions, as memory gets put to sleep */
la t0, 2f
la t1, 4f
subu t2, t1, t0
.set mips3
1: cache 0x14, 0(t0)
subu t2, t2, 32
bgez t2, 1b
addu t0, t0, 32
.set mips0
2: lui a0, 0xb400 /* mem_xxx */
/* disable all ports in mem_sdportcfga */
sw zero, 0x868(a0) /* mem_sdportcfga */
sync
/* disable ODT */
li t0, 0x03010000
sw t0, 0x08d8(a0) /* mem_sdcmd0 */
sw t0, 0x08dc(a0) /* mem_sdcmd1 */
sync
/* precharge */
li t0, 0x23000400
sw t0, 0x08dc(a0) /* mem_sdcmd1 */
sw t0, 0x08d8(a0) /* mem_sdcmd0 */
sync
/* auto refresh */
sw zero, 0x08c8(a0) /* mem_sdautoref */
sync
/* block access to the DDR */
lw t0, 0x0848(a0) /* mem_sdconfigb */
li t1, (1 << 7 | 0x3F)
or t0, t0, t1
sw t0, 0x0848(a0) /* mem_sdconfigb */
sync
/* issue the Self Refresh command */
li t0, 0x10000000
sw t0, 0x08dc(a0) /* mem_sdcmd1 */
sw t0, 0x08d8(a0) /* mem_sdcmd0 */
sync
/* wait for sdram to enter self-refresh mode */
lui t0, 0x0300
3: lw t1, 0x0850(a0) /* mem_sdstat */
and t2, t1, t0
bne t2, t0, 3b
nop
/* disable SDRAM clocks */
li t0, ~(3<<28)
lw t1, 0x0840(a0) /* mem_sdconfiga */
and t1, t1, t0 /* clear CE[1:0] */
sw t1, 0x0840(a0) /* mem_sdconfiga */
sync
DO_SLEEP
4:
END(alchemy_sleep_au1300)
/* This is where we return upon wakeup.
* Reload all of the registers and return.

View File

@@ -178,6 +178,7 @@ static int alchemy_m2inttab[] __initdata = {
AU1100_RTC_MATCH2_INT,
AU1550_RTC_MATCH2_INT,
AU1200_RTC_MATCH2_INT,
AU1300_RTC_MATCH2_INT,
};
void __init plat_time_init(void)

View File

@@ -0,0 +1,84 @@
/*
* Au1300 media block power gating (VSS)
*
* This is a stop-gap solution until I have the clock framework integration
* ready. This stuff here really must be handled transparently when clocks
* for various media blocks are enabled/disabled.
*/
#include <linux/module.h>
#include <linux/spinlock.h>
#include <asm/mach-au1x00/au1000.h>
#define VSS_GATE 0x00 /* gate wait timers */
#define VSS_CLKRST 0x04 /* clock/block control */
#define VSS_FTR 0x08 /* footers */
#define VSS_ADDR(blk) (KSEG1ADDR(AU1300_VSS_PHYS_ADDR) + (blk * 0x0c))
static DEFINE_SPINLOCK(au1300_vss_lock);
/* enable a block as outlined in the databook */
static inline void __enable_block(int block)
{
void __iomem *base = (void __iomem *)VSS_ADDR(block);
__raw_writel(3, base + VSS_CLKRST); /* enable clock, assert reset */
wmb();
__raw_writel(0x01fffffe, base + VSS_GATE); /* maximum setup time */
wmb();
/* enable footers in sequence */
__raw_writel(0x01, base + VSS_FTR);
wmb();
__raw_writel(0x03, base + VSS_FTR);
wmb();
__raw_writel(0x07, base + VSS_FTR);
wmb();
__raw_writel(0x0f, base + VSS_FTR);
wmb();
__raw_writel(0x01ffffff, base + VSS_GATE); /* start FSM too */
wmb();
__raw_writel(2, base + VSS_CLKRST); /* deassert reset */
wmb();
__raw_writel(0x1f, base + VSS_FTR); /* enable isolation cells */
wmb();
}
/* disable a block as outlined in the databook */
static inline void __disable_block(int block)
{
void __iomem *base = (void __iomem *)VSS_ADDR(block);
__raw_writel(0x0f, base + VSS_FTR); /* disable isolation cells */
wmb();
__raw_writel(0, base + VSS_GATE); /* disable FSM */
wmb();
__raw_writel(3, base + VSS_CLKRST); /* assert reset */
wmb();
__raw_writel(1, base + VSS_CLKRST); /* disable clock */
wmb();
__raw_writel(0, base + VSS_FTR); /* disable all footers */
wmb();
}
void au1300_vss_block_control(int block, int enable)
{
unsigned long flags;
if (alchemy_get_cputype() != ALCHEMY_CPU_AU1300)
return;
/* only one block at a time */
spin_lock_irqsave(&au1300_vss_lock, flags);
if (enable)
__enable_block(block);
else
__disable_block(block);
spin_unlock_irqrestore(&au1300_vss_lock, flags);
}
EXPORT_SYMBOL_GPL(au1300_vss_block_control);

View File

@@ -4,15 +4,10 @@
obj-y += prom.o bcsr.o platform.o
obj-$(CONFIG_PM) += pm.o
obj-$(CONFIG_MIPS_PB1000) += pb1000/
obj-$(CONFIG_MIPS_PB1100) += pb1100/
obj-$(CONFIG_MIPS_PB1200) += pb1200/
obj-$(CONFIG_MIPS_PB1500) += pb1500/
obj-$(CONFIG_MIPS_PB1550) += pb1550/
obj-$(CONFIG_MIPS_DB1000) += db1x00/
obj-$(CONFIG_MIPS_DB1100) += db1x00/
obj-$(CONFIG_MIPS_DB1200) += db1200/
obj-$(CONFIG_MIPS_DB1500) += db1x00/
obj-$(CONFIG_MIPS_DB1550) += db1x00/
obj-$(CONFIG_MIPS_BOSPORUS) += db1x00/
obj-$(CONFIG_MIPS_MIRAGE) += db1x00/
obj-$(CONFIG_MIPS_PB1100) += pb1100.o
obj-$(CONFIG_MIPS_PB1500) += pb1500.o
obj-$(CONFIG_MIPS_PB1550) += pb1550.o
obj-$(CONFIG_MIPS_DB1000) += db1000.o
obj-$(CONFIG_MIPS_DB1200) += db1200.o
obj-$(CONFIG_MIPS_DB1300) += db1300.o
obj-$(CONFIG_MIPS_DB1550) += db1550.o

View File

@@ -97,14 +97,9 @@ static void bcsr_csc_handler(unsigned int irq, struct irq_desc *d)
enable_irq(irq);
}
/* NOTE: both the enable and mask bits must be cleared, otherwise the
* CPLD generates tons of spurious interrupts (at least on my DB1200).
* -- mlau
*/
static void bcsr_irq_mask(struct irq_data *d)
{
unsigned short v = 1 << (d->irq - bcsr_csc_base);
__raw_writew(v, bcsr_virt + BCSR_REG_INTCLR);
__raw_writew(v, bcsr_virt + BCSR_REG_MASKCLR);
wmb();
}
@@ -112,7 +107,6 @@ static void bcsr_irq_mask(struct irq_data *d)
static void bcsr_irq_maskack(struct irq_data *d)
{
unsigned short v = 1 << (d->irq - bcsr_csc_base);
__raw_writew(v, bcsr_virt + BCSR_REG_INTCLR);
__raw_writew(v, bcsr_virt + BCSR_REG_MASKCLR);
__raw_writew(v, bcsr_virt + BCSR_REG_INTSTAT); /* ack */
wmb();
@@ -121,7 +115,6 @@ static void bcsr_irq_maskack(struct irq_data *d)
static void bcsr_irq_unmask(struct irq_data *d)
{
unsigned short v = 1 << (d->irq - bcsr_csc_base);
__raw_writew(v, bcsr_virt + BCSR_REG_INTSET);
__raw_writew(v, bcsr_virt + BCSR_REG_MASKSET);
wmb();
}
@@ -137,9 +130,9 @@ void __init bcsr_init_irq(int csc_start, int csc_end, int hook_irq)
{
unsigned int irq;
/* mask & disable & ack all */
__raw_writew(0xffff, bcsr_virt + BCSR_REG_INTCLR);
/* mask & enable & ack all */
__raw_writew(0xffff, bcsr_virt + BCSR_REG_MASKCLR);
__raw_writew(0xffff, bcsr_virt + BCSR_REG_INTSET);
__raw_writew(0xffff, bcsr_virt + BCSR_REG_INTSTAT);
wmb();

View File

@@ -0,0 +1,565 @@
/*
* DBAu1000/1500/1100 board support
*
* Copyright 2000, 2008 MontaVista Software Inc.
* Author: MontaVista Software, Inc. <source@mvista.com>
*
* 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 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/dma-mapping.h>
#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/leds.h>
#include <linux/mmc/host.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_gpio.h>
#include <linux/spi/ads7846.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/au1000_dma.h>
#include <asm/mach-au1x00/au1100_mmc.h>
#include <asm/mach-db1x00/bcsr.h>
#include <asm/reboot.h>
#include <prom.h>
#include "platform.h"
#define F_SWAPPED (bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT)
struct pci_dev;
static const char *board_type_str(void)
{
switch (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI))) {
case BCSR_WHOAMI_DB1000:
return "DB1000";
case BCSR_WHOAMI_DB1500:
return "DB1500";
case BCSR_WHOAMI_DB1100:
return "DB1100";
default:
return "(unknown)";
}
}
const char *get_system_type(void)
{
return board_type_str();
}
void __init board_setup(void)
{
/* initialize board register space */
bcsr_init(DB1000_BCSR_PHYS_ADDR,
DB1000_BCSR_PHYS_ADDR + DB1000_BCSR_HEXLED_OFS);
printk(KERN_INFO "AMD Alchemy %s Board\n", board_type_str());
}
static int db1500_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;
}
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 db1500_pci_pd = {
.board_map_irq = db1500_map_pci_irq,
};
static struct platform_device db1500_pci_host_dev = {
.dev.platform_data = &db1500_pci_pd,
.name = "alchemy-pci",
.id = 0,
.num_resources = ARRAY_SIZE(alchemy_pci_host_res),
.resource = alchemy_pci_host_res,
};
static int __init db1500_pci_init(void)
{
if (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)) == BCSR_WHOAMI_DB1500)
return platform_device_register(&db1500_pci_host_dev);
return 0;
}
/* must be arch_initcall; MIPS PCI scans busses in a subsys_initcall */
arch_initcall(db1500_pci_init);
static struct resource au1100_lcd_resources[] = {
[0] = {
.start = AU1100_LCD_PHYS_ADDR,
.end = AU1100_LCD_PHYS_ADDR + 0x800 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AU1100_LCD_INT,
.end = AU1100_LCD_INT,
.flags = IORESOURCE_IRQ,
}
};
static u64 au1100_lcd_dmamask = DMA_BIT_MASK(32);
static struct platform_device au1100_lcd_device = {
.name = "au1100-lcd",
.id = 0,
.dev = {
.dma_mask = &au1100_lcd_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
.num_resources = ARRAY_SIZE(au1100_lcd_resources),
.resource = au1100_lcd_resources,
};
static struct resource alchemy_ac97c_res[] = {
[0] = {
.start = AU1000_AC97_PHYS_ADDR,
.end = AU1000_AC97_PHYS_ADDR + 0xfff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = DMA_ID_AC97C_TX,
.end = DMA_ID_AC97C_TX,
.flags = IORESOURCE_DMA,
},
[2] = {
.start = DMA_ID_AC97C_RX,
.end = DMA_ID_AC97C_RX,
.flags = IORESOURCE_DMA,
},
};
static struct platform_device alchemy_ac97c_dev = {
.name = "alchemy-ac97c",
.id = -1,
.resource = alchemy_ac97c_res,
.num_resources = ARRAY_SIZE(alchemy_ac97c_res),
};
static struct platform_device alchemy_ac97c_dma_dev = {
.name = "alchemy-pcm-dma",
.id = 0,
};
static struct platform_device db1x00_codec_dev = {
.name = "ac97-codec",
.id = -1,
};
static struct platform_device db1x00_audio_dev = {
.name = "db1000-audio",
};
/******************************************************************************/
static irqreturn_t db1100_mmc_cd(int irq, void *ptr)
{
void (*mmc_cd)(struct mmc_host *, unsigned long);
/* link against CONFIG_MMC=m */
mmc_cd = symbol_get(mmc_detect_change);
mmc_cd(ptr, msecs_to_jiffies(500));
symbol_put(mmc_detect_change);
return IRQ_HANDLED;
}
static int db1100_mmc_cd_setup(void *mmc_host, int en)
{
int ret = 0;
if (en) {
irq_set_irq_type(AU1100_GPIO19_INT, IRQ_TYPE_EDGE_BOTH);
ret = request_irq(AU1100_GPIO19_INT, db1100_mmc_cd, 0,
"sd0_cd", mmc_host);
} else
free_irq(AU1100_GPIO19_INT, mmc_host);
return ret;
}
static int db1100_mmc1_cd_setup(void *mmc_host, int en)
{
int ret = 0;
if (en) {
irq_set_irq_type(AU1100_GPIO20_INT, IRQ_TYPE_EDGE_BOTH);
ret = request_irq(AU1100_GPIO20_INT, db1100_mmc_cd, 0,
"sd1_cd", mmc_host);
} else
free_irq(AU1100_GPIO20_INT, mmc_host);
return ret;
}
static int db1100_mmc_card_readonly(void *mmc_host)
{
/* testing suggests that this bit is inverted */
return (bcsr_read(BCSR_STATUS) & BCSR_STATUS_SD0WP) ? 0 : 1;
}
static int db1100_mmc_card_inserted(void *mmc_host)
{
return !alchemy_gpio_get_value(19);
}
static void db1100_mmc_set_power(void *mmc_host, int state)
{
if (state) {
bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_SD0PWR);
msleep(400); /* stabilization time */
} else
bcsr_mod(BCSR_BOARD, BCSR_BOARD_SD0PWR, 0);
}
static void db1100_mmcled_set(struct led_classdev *led, enum led_brightness b)
{
if (b != LED_OFF)
bcsr_mod(BCSR_LEDS, BCSR_LEDS_LED0, 0);
else
bcsr_mod(BCSR_LEDS, 0, BCSR_LEDS_LED0);
}
static struct led_classdev db1100_mmc_led = {
.brightness_set = db1100_mmcled_set,
};
static int db1100_mmc1_card_readonly(void *mmc_host)
{
return (bcsr_read(BCSR_BOARD) & BCSR_BOARD_SD1WP) ? 1 : 0;
}
static int db1100_mmc1_card_inserted(void *mmc_host)
{
return !alchemy_gpio_get_value(20);
}
static void db1100_mmc1_set_power(void *mmc_host, int state)
{
if (state) {
bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_SD1PWR);
msleep(400); /* stabilization time */
} else
bcsr_mod(BCSR_BOARD, BCSR_BOARD_SD1PWR, 0);
}
static void db1100_mmc1led_set(struct led_classdev *led, enum led_brightness b)
{
if (b != LED_OFF)
bcsr_mod(BCSR_LEDS, BCSR_LEDS_LED1, 0);
else
bcsr_mod(BCSR_LEDS, 0, BCSR_LEDS_LED1);
}
static struct led_classdev db1100_mmc1_led = {
.brightness_set = db1100_mmc1led_set,
};
static struct au1xmmc_platform_data db1100_mmc_platdata[2] = {
[0] = {
.cd_setup = db1100_mmc_cd_setup,
.set_power = db1100_mmc_set_power,
.card_inserted = db1100_mmc_card_inserted,
.card_readonly = db1100_mmc_card_readonly,
.led = &db1100_mmc_led,
},
[1] = {
.cd_setup = db1100_mmc1_cd_setup,
.set_power = db1100_mmc1_set_power,
.card_inserted = db1100_mmc1_card_inserted,
.card_readonly = db1100_mmc1_card_readonly,
.led = &db1100_mmc1_led,
},
};
static struct resource au1100_mmc0_resources[] = {
[0] = {
.start = AU1100_SD0_PHYS_ADDR,
.end = AU1100_SD0_PHYS_ADDR + 0xfff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AU1100_SD_INT,
.end = AU1100_SD_INT,
.flags = IORESOURCE_IRQ,
},
[2] = {
.start = DMA_ID_SD0_TX,
.end = DMA_ID_SD0_TX,
.flags = IORESOURCE_DMA,
},
[3] = {
.start = DMA_ID_SD0_RX,
.end = DMA_ID_SD0_RX,
.flags = IORESOURCE_DMA,
}
};
static u64 au1xxx_mmc_dmamask = DMA_BIT_MASK(32);
static struct platform_device db1100_mmc0_dev = {
.name = "au1xxx-mmc",
.id = 0,
.dev = {
.dma_mask = &au1xxx_mmc_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = &db1100_mmc_platdata[0],
},
.num_resources = ARRAY_SIZE(au1100_mmc0_resources),
.resource = au1100_mmc0_resources,
};
static struct resource au1100_mmc1_res[] = {
[0] = {
.start = AU1100_SD1_PHYS_ADDR,
.end = AU1100_SD1_PHYS_ADDR + 0xfff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AU1100_SD_INT,
.end = AU1100_SD_INT,
.flags = IORESOURCE_IRQ,
},
[2] = {
.start = DMA_ID_SD1_TX,
.end = DMA_ID_SD1_TX,
.flags = IORESOURCE_DMA,
},
[3] = {
.start = DMA_ID_SD1_RX,
.end = DMA_ID_SD1_RX,
.flags = IORESOURCE_DMA,
}
};
static struct platform_device db1100_mmc1_dev = {
.name = "au1xxx-mmc",
.id = 1,
.dev = {
.dma_mask = &au1xxx_mmc_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = &db1100_mmc_platdata[1],
},
.num_resources = ARRAY_SIZE(au1100_mmc1_res),
.resource = au1100_mmc1_res,
};
/******************************************************************************/
static void db1000_irda_set_phy_mode(int mode)
{
unsigned short mask = BCSR_RESETS_IRDA_MODE_MASK | BCSR_RESETS_FIR_SEL;
switch (mode) {
case AU1000_IRDA_PHY_MODE_OFF:
bcsr_mod(BCSR_RESETS, mask, BCSR_RESETS_IRDA_MODE_OFF);
break;
case AU1000_IRDA_PHY_MODE_SIR:
bcsr_mod(BCSR_RESETS, mask, BCSR_RESETS_IRDA_MODE_FULL);
break;
case AU1000_IRDA_PHY_MODE_FIR:
bcsr_mod(BCSR_RESETS, mask, BCSR_RESETS_IRDA_MODE_FULL |
BCSR_RESETS_FIR_SEL);
break;
}
}
static struct au1k_irda_platform_data db1000_irda_platdata = {
.set_phy_mode = db1000_irda_set_phy_mode,
};
static struct resource au1000_irda_res[] = {
[0] = {
.start = AU1000_IRDA_PHYS_ADDR,
.end = AU1000_IRDA_PHYS_ADDR + 0x0fff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AU1000_IRDA_TX_INT,
.end = AU1000_IRDA_TX_INT,
.flags = IORESOURCE_IRQ,
},
[2] = {
.start = AU1000_IRDA_RX_INT,
.end = AU1000_IRDA_RX_INT,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device db1000_irda_dev = {
.name = "au1000-irda",
.id = -1,
.dev = {
.platform_data = &db1000_irda_platdata,
},
.resource = au1000_irda_res,
.num_resources = ARRAY_SIZE(au1000_irda_res),
};
/******************************************************************************/
static struct ads7846_platform_data db1100_touch_pd = {
.model = 7846,
.vref_mv = 3300,
.gpio_pendown = 21,
};
static struct spi_gpio_platform_data db1100_spictl_pd = {
.sck = 209,
.mosi = 208,
.miso = 207,
.num_chipselect = 1,
};
static struct spi_board_info db1100_spi_info[] __initdata = {
[0] = {
.modalias = "ads7846",
.max_speed_hz = 3250000,
.bus_num = 0,
.chip_select = 0,
.mode = 0,
.irq = AU1100_GPIO21_INT,
.platform_data = &db1100_touch_pd,
.controller_data = (void *)210, /* for spi_gpio: CS# GPIO210 */
},
};
static struct platform_device db1100_spi_dev = {
.name = "spi_gpio",
.id = 0,
.dev = {
.platform_data = &db1100_spictl_pd,
},
};
static struct platform_device *db1x00_devs[] = {
&db1x00_codec_dev,
&alchemy_ac97c_dma_dev,
&alchemy_ac97c_dev,
&db1x00_audio_dev,
};
static struct platform_device *db1000_devs[] = {
&db1000_irda_dev,
};
static struct platform_device *db1100_devs[] = {
&au1100_lcd_device,
&db1100_mmc0_dev,
&db1100_mmc1_dev,
&db1000_irda_dev,
&db1100_spi_dev,
};
static int __init db1000_dev_init(void)
{
int board = BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI));
int c0, c1, d0, d1, s0, s1;
unsigned long pfc;
if (board == BCSR_WHOAMI_DB1500) {
c0 = AU1500_GPIO2_INT;
c1 = AU1500_GPIO5_INT;
d0 = AU1500_GPIO0_INT;
d1 = AU1500_GPIO3_INT;
s0 = AU1500_GPIO1_INT;
s1 = AU1500_GPIO4_INT;
} else if (board == BCSR_WHOAMI_DB1100) {
c0 = AU1100_GPIO2_INT;
c1 = AU1100_GPIO5_INT;
d0 = AU1100_GPIO0_INT;
d1 = AU1100_GPIO3_INT;
s0 = AU1100_GPIO1_INT;
s1 = AU1100_GPIO4_INT;
gpio_direction_input(19); /* sd0 cd# */
gpio_direction_input(20); /* sd1 cd# */
gpio_direction_input(21); /* touch pendown# */
gpio_direction_input(207); /* SPI MISO */
gpio_direction_output(208, 0); /* SPI MOSI */
gpio_direction_output(209, 1); /* SPI SCK */
gpio_direction_output(210, 1); /* SPI CS# */
/* spi_gpio on SSI0 pins */
pfc = __raw_readl((void __iomem *)SYS_PINFUNC);
pfc |= (1 << 0); /* SSI0 pins as GPIOs */
__raw_writel(pfc, (void __iomem *)SYS_PINFUNC);
wmb();
spi_register_board_info(db1100_spi_info,
ARRAY_SIZE(db1100_spi_info));
platform_add_devices(db1100_devs, ARRAY_SIZE(db1100_devs));
} else if (board == BCSR_WHOAMI_DB1000) {
c0 = AU1000_GPIO2_INT;
c1 = AU1000_GPIO5_INT;
d0 = AU1000_GPIO0_INT;
d1 = AU1000_GPIO3_INT;
s0 = AU1000_GPIO1_INT;
s1 = AU1000_GPIO4_INT;
platform_add_devices(db1000_devs, ARRAY_SIZE(db1000_devs));
} else
return 0; /* unknown board, no further dev setup to do */
irq_set_irq_type(d0, IRQ_TYPE_EDGE_BOTH);
irq_set_irq_type(d1, IRQ_TYPE_EDGE_BOTH);
irq_set_irq_type(c0, IRQ_TYPE_LEVEL_LOW);
irq_set_irq_type(c1, IRQ_TYPE_LEVEL_LOW);
irq_set_irq_type(s0, IRQ_TYPE_LEVEL_LOW);
irq_set_irq_type(s1, IRQ_TYPE_LEVEL_LOW);
db1x_register_pcmcia_socket(
AU1000_PCMCIA_ATTR_PHYS_ADDR,
AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
AU1000_PCMCIA_MEM_PHYS_ADDR,
AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
AU1000_PCMCIA_IO_PHYS_ADDR,
AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
c0, d0, /*s0*/0, 0, 0);
db1x_register_pcmcia_socket(
AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004000000,
AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004400000 - 1,
AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004000000,
AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004400000 - 1,
AU1000_PCMCIA_IO_PHYS_ADDR + 0x004000000,
AU1000_PCMCIA_IO_PHYS_ADDR + 0x004010000 - 1,
c1, d1, /*s1*/0, 0, 1);
platform_add_devices(db1x00_devs, ARRAY_SIZE(db1x00_devs));
db1x_register_norflash(32 << 20, 4 /* 32bit */, F_SWAPPED);
return 0;
}
device_initcall(db1000_dev_init);

View File

@@ -1,7 +1,7 @@
/*
* DBAu1200 board platform device registration
* DBAu1200/PBAu1200 board platform device registration
*
* Copyright (C) 2008-2009 Manuel Lauss
* Copyright (C) 2008-2011 Manuel Lauss
*
* 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
@@ -22,6 +22,7 @@
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/leds.h>
#include <linux/mmc/host.h>
@@ -33,18 +34,116 @@
#include <linux/spi/spi.h>
#include <linux/spi/flash.h>
#include <linux/smc91x.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/au1100_mmc.h>
#include <asm/mach-au1x00/au1xxx_dbdma.h>
#include <asm/mach-au1x00/au1200fb.h>
#include <asm/mach-au1x00/au1550_spi.h>
#include <asm/mach-db1x00/bcsr.h>
#include <asm/mach-db1x00/db1200.h>
#include "../platform.h"
#include "platform.h"
static const char *board_type_str(void)
{
switch (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI))) {
case BCSR_WHOAMI_PB1200_DDR1:
case BCSR_WHOAMI_PB1200_DDR2:
return "PB1200";
case BCSR_WHOAMI_DB1200:
return "DB1200";
default:
return "(unknown)";
}
}
const char *get_system_type(void)
{
return board_type_str();
}
static int __init detect_board(void)
{
int bid;
/* try the DB1200 first */
bcsr_init(DB1200_BCSR_PHYS_ADDR,
DB1200_BCSR_PHYS_ADDR + DB1200_BCSR_HEXLED_OFS);
if (BCSR_WHOAMI_DB1200 == BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI))) {
unsigned short t = bcsr_read(BCSR_HEXLEDS);
bcsr_write(BCSR_HEXLEDS, ~t);
if (bcsr_read(BCSR_HEXLEDS) != t) {
bcsr_write(BCSR_HEXLEDS, t);
return 0;
}
}
/* okay, try the PB1200 then */
bcsr_init(PB1200_BCSR_PHYS_ADDR,
PB1200_BCSR_PHYS_ADDR + PB1200_BCSR_HEXLED_OFS);
bid = BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI));
if ((bid == BCSR_WHOAMI_PB1200_DDR1) ||
(bid == BCSR_WHOAMI_PB1200_DDR2)) {
unsigned short t = bcsr_read(BCSR_HEXLEDS);
bcsr_write(BCSR_HEXLEDS, ~t);
if (bcsr_read(BCSR_HEXLEDS) != t) {
bcsr_write(BCSR_HEXLEDS, t);
return 0;
}
}
return 1; /* it's neither */
}
void __init board_setup(void)
{
unsigned long freq0, clksrc, div, pfc;
unsigned short whoami;
if (detect_board()) {
printk(KERN_ERR "NOT running on a DB1200/PB1200 board!\n");
return;
}
whoami = bcsr_read(BCSR_WHOAMI);
printk(KERN_INFO "Alchemy/AMD/RMI %s Board, CPLD Rev %d"
" Board-ID %d Daughtercard ID %d\n", board_type_str(),
(whoami >> 4) & 0xf, (whoami >> 8) & 0xf, whoami & 0xf);
/* SMBus/SPI on PSC0, Audio on PSC1 */
pfc = __raw_readl((void __iomem *)SYS_PINFUNC);
pfc &= ~(SYS_PINFUNC_P0A | SYS_PINFUNC_P0B);
pfc &= ~(SYS_PINFUNC_P1A | SYS_PINFUNC_P1B | SYS_PINFUNC_FS3);
pfc |= SYS_PINFUNC_P1C; /* SPI is configured later */
__raw_writel(pfc, (void __iomem *)SYS_PINFUNC);
wmb();
/* Clock configurations: PSC0: ~50MHz via Clkgen0, derived from
* CPU clock; all other clock generators off/unused.
*/
div = (get_au1x00_speed() + 25000000) / 50000000;
if (div & 1)
div++;
div = ((div >> 1) - 1) & 0xff;
freq0 = div << SYS_FC_FRDIV0_BIT;
__raw_writel(freq0, (void __iomem *)SYS_FREQCTRL0);
wmb();
freq0 |= SYS_FC_FE0; /* enable F0 */
__raw_writel(freq0, (void __iomem *)SYS_FREQCTRL0);
wmb();
/* psc0_intclk comes 1:1 from F0 */
clksrc = SYS_CS_MUX_FQ0 << SYS_CS_ME0_BIT;
__raw_writel(clksrc, (void __iomem *)SYS_CLKSRC);
wmb();
}
/******************************************************************************/
static struct mtd_partition db1200_spiflash_parts[] = {
{
.name = "DB1200 SPI flash",
.name = "spi_flash",
.offset = 0,
.size = MTDPART_SIZ_FULL,
},
@@ -78,18 +177,9 @@ static struct spi_board_info db1200_spi_devs[] __initdata = {
};
static struct i2c_board_info db1200_i2c_devs[] __initdata = {
{
/* AT24C04-10 I2C eeprom */
I2C_BOARD_INFO("24c04", 0x52),
},
{
/* Philips NE1619 temp/voltage sensor (adm1025 drv) */
I2C_BOARD_INFO("ne1619", 0x2d),
},
{
/* I2S audio codec WM8731 */
I2C_BOARD_INFO("wm8731", 0x1b),
},
{ I2C_BOARD_INFO("24c04", 0x52), }, /* AT24C04-10 I2C eeprom */
{ I2C_BOARD_INFO("ne1619", 0x2d), }, /* adm1025-compat hwmon */
{ I2C_BOARD_INFO("wm8731", 0x1b), }, /* I2S audio codec WM8731 */
};
/**********************************************************************/
@@ -206,7 +296,7 @@ static struct platform_device db1200_eth_dev = {
static struct resource db1200_ide_res[] = {
[0] = {
.start = DB1200_IDE_PHYS_ADDR,
.end = DB1200_IDE_PHYS_ADDR + DB1200_IDE_PHYS_LEN - 1,
.end = DB1200_IDE_PHYS_ADDR + DB1200_IDE_PHYS_LEN - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -221,13 +311,13 @@ static struct resource db1200_ide_res[] = {
},
};
static u64 ide_dmamask = DMA_BIT_MASK(32);
static u64 au1200_ide_dmamask = DMA_BIT_MASK(32);
static struct platform_device db1200_ide_dev = {
.name = "au1200-ide",
.id = 0,
.dev = {
.dma_mask = &ide_dmamask,
.dma_mask = &au1200_ide_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
.num_resources = ARRAY_SIZE(db1200_ide_res),
@@ -236,13 +326,6 @@ static struct platform_device db1200_ide_dev = {
/**********************************************************************/
static struct platform_device db1200_rtc_dev = {
.name = "rtc-au1xxx",
.id = -1,
};
/**********************************************************************/
/* SD carddetects: they're supposed to be edge-triggered, but ack
* doesn't seem to work (CPLD Rev 2). Instead, the screaming one
* is disabled and its counterpart enabled. The 500ms timeout is
@@ -333,12 +416,109 @@ static struct led_classdev db1200_mmc_led = {
.brightness_set = db1200_mmcled_set,
};
static struct au1xmmc_platform_data db1200mmc_platdata = {
.cd_setup = db1200_mmc_cd_setup,
.set_power = db1200_mmc_set_power,
.card_inserted = db1200_mmc_card_inserted,
.card_readonly = db1200_mmc_card_readonly,
.led = &db1200_mmc_led,
/* -- */
static irqreturn_t pb1200_mmc1_cd(int irq, void *ptr)
{
void(*mmc_cd)(struct mmc_host *, unsigned long);
if (irq == PB1200_SD1_INSERT_INT) {
disable_irq_nosync(PB1200_SD1_INSERT_INT);
enable_irq(PB1200_SD1_EJECT_INT);
} else {
disable_irq_nosync(PB1200_SD1_EJECT_INT);
enable_irq(PB1200_SD1_INSERT_INT);
}
/* link against CONFIG_MMC=m */
mmc_cd = symbol_get(mmc_detect_change);
if (mmc_cd) {
mmc_cd(ptr, msecs_to_jiffies(500));
symbol_put(mmc_detect_change);
}
return IRQ_HANDLED;
}
static int pb1200_mmc1_cd_setup(void *mmc_host, int en)
{
int ret;
if (en) {
ret = request_irq(PB1200_SD1_INSERT_INT, pb1200_mmc1_cd, 0,
"sd1_insert", mmc_host);
if (ret)
goto out;
ret = request_irq(PB1200_SD1_EJECT_INT, pb1200_mmc1_cd, 0,
"sd1_eject", mmc_host);
if (ret) {
free_irq(PB1200_SD1_INSERT_INT, mmc_host);
goto out;
}
if (bcsr_read(BCSR_SIGSTAT) & BCSR_INT_SD1INSERT)
enable_irq(PB1200_SD1_EJECT_INT);
else
enable_irq(PB1200_SD1_INSERT_INT);
} else {
free_irq(PB1200_SD1_INSERT_INT, mmc_host);
free_irq(PB1200_SD1_EJECT_INT, mmc_host);
}
ret = 0;
out:
return ret;
}
static void pb1200_mmc1led_set(struct led_classdev *led,
enum led_brightness brightness)
{
if (brightness != LED_OFF)
bcsr_mod(BCSR_LEDS, BCSR_LEDS_LED1, 0);
else
bcsr_mod(BCSR_LEDS, 0, BCSR_LEDS_LED1);
}
static struct led_classdev pb1200_mmc1_led = {
.brightness_set = pb1200_mmc1led_set,
};
static void pb1200_mmc1_set_power(void *mmc_host, int state)
{
if (state) {
bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_SD1PWR);
msleep(400); /* stabilization time */
} else
bcsr_mod(BCSR_BOARD, BCSR_BOARD_SD1PWR, 0);
}
static int pb1200_mmc1_card_readonly(void *mmc_host)
{
return (bcsr_read(BCSR_STATUS) & BCSR_STATUS_SD1WP) ? 1 : 0;
}
static int pb1200_mmc1_card_inserted(void *mmc_host)
{
return (bcsr_read(BCSR_SIGSTAT) & BCSR_INT_SD1INSERT) ? 1 : 0;
}
static struct au1xmmc_platform_data db1200_mmc_platdata[2] = {
[0] = {
.cd_setup = db1200_mmc_cd_setup,
.set_power = db1200_mmc_set_power,
.card_inserted = db1200_mmc_card_inserted,
.card_readonly = db1200_mmc_card_readonly,
.led = &db1200_mmc_led,
},
[1] = {
.cd_setup = pb1200_mmc1_cd_setup,
.set_power = pb1200_mmc1_set_power,
.card_inserted = pb1200_mmc1_card_inserted,
.card_readonly = pb1200_mmc1_card_readonly,
.led = &pb1200_mmc1_led,
},
};
static struct resource au1200_mmc0_resources[] = {
@@ -372,14 +552,76 @@ static struct platform_device db1200_mmc0_dev = {
.dev = {
.dma_mask = &au1xxx_mmc_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = &db1200mmc_platdata,
.platform_data = &db1200_mmc_platdata[0],
},
.num_resources = ARRAY_SIZE(au1200_mmc0_resources),
.resource = au1200_mmc0_resources,
};
static struct resource au1200_mmc1_res[] = {
[0] = {
.start = AU1100_SD1_PHYS_ADDR,
.end = AU1100_SD1_PHYS_ADDR + 0xfff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AU1200_SD_INT,
.end = AU1200_SD_INT,
.flags = IORESOURCE_IRQ,
},
[2] = {
.start = AU1200_DSCR_CMD0_SDMS_TX1,
.end = AU1200_DSCR_CMD0_SDMS_TX1,
.flags = IORESOURCE_DMA,
},
[3] = {
.start = AU1200_DSCR_CMD0_SDMS_RX1,
.end = AU1200_DSCR_CMD0_SDMS_RX1,
.flags = IORESOURCE_DMA,
}
};
static struct platform_device pb1200_mmc1_dev = {
.name = "au1xxx-mmc",
.id = 1,
.dev = {
.dma_mask = &au1xxx_mmc_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = &db1200_mmc_platdata[1],
},
.num_resources = ARRAY_SIZE(au1200_mmc1_res),
.resource = au1200_mmc1_res,
};
/**********************************************************************/
static int db1200fb_panel_index(void)
{
return (bcsr_read(BCSR_SWITCHES) >> 8) & 0x0f;
}
static int db1200fb_panel_init(void)
{
/* Apply power */
bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD |
BCSR_BOARD_LCDBL);
return 0;
}
static int db1200fb_panel_shutdown(void)
{
/* Remove power */
bcsr_mod(BCSR_BOARD, BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD |
BCSR_BOARD_LCDBL, 0);
return 0;
}
static struct au1200fb_platdata db1200fb_pd = {
.panel_index = db1200fb_panel_index,
.panel_init = db1200fb_panel_init,
.panel_shutdown = db1200fb_panel_shutdown,
};
static struct resource au1200_lcd_res[] = {
[0] = {
.start = AU1200_LCD_PHYS_ADDR,
@@ -401,6 +643,7 @@ static struct platform_device au1200_lcd_dev = {
.dev = {
.dma_mask = &au1200_lcd_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = &db1200fb_pd,
},
.num_resources = ARRAY_SIZE(au1200_lcd_res),
.resource = au1200_lcd_res,
@@ -519,7 +762,6 @@ static struct platform_device *db1200_devs[] __initdata = {
&db1200_mmc0_dev,
&au1200_lcd_dev,
&db1200_eth_dev,
&db1200_rtc_dev,
&db1200_nand_dev,
&db1200_audiodma_dev,
&db1200_audio_dev,
@@ -527,11 +769,62 @@ static struct platform_device *db1200_devs[] __initdata = {
&db1200_sound_dev,
};
static struct platform_device *pb1200_devs[] __initdata = {
&pb1200_mmc1_dev,
};
/* Some peripheral base addresses differ on the PB1200 */
static int __init pb1200_res_fixup(void)
{
/* CPLD Revs earlier than 4 cause problems */
if (BCSR_WHOAMI_CPLD(bcsr_read(BCSR_WHOAMI)) <= 3) {
printk(KERN_ERR "WARNING!!!\n");
printk(KERN_ERR "WARNING!!!\n");
printk(KERN_ERR "PB1200 must be at CPLD rev 4. Please have\n");
printk(KERN_ERR "the board updated to latest revisions.\n");
printk(KERN_ERR "This software will not work reliably\n");
printk(KERN_ERR "on anything older than CPLD rev 4.!\n");
printk(KERN_ERR "WARNING!!!\n");
printk(KERN_ERR "WARNING!!!\n");
return 1;
}
db1200_nand_res[0].start = PB1200_NAND_PHYS_ADDR;
db1200_nand_res[0].end = PB1200_NAND_PHYS_ADDR + 0xff;
db1200_ide_res[0].start = PB1200_IDE_PHYS_ADDR;
db1200_ide_res[0].end = PB1200_IDE_PHYS_ADDR + DB1200_IDE_PHYS_LEN - 1;
db1200_eth_res[0].start = PB1200_ETH_PHYS_ADDR;
db1200_eth_res[0].end = PB1200_ETH_PHYS_ADDR + 0xff;
return 0;
}
static int __init db1200_dev_init(void)
{
unsigned long pfc;
unsigned short sw;
int swapped;
int swapped, bid;
bid = BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI));
if ((bid == BCSR_WHOAMI_PB1200_DDR1) ||
(bid == BCSR_WHOAMI_PB1200_DDR2)) {
if (pb1200_res_fixup())
return -ENODEV;
}
/* GPIO7 is low-level triggered CPLD cascade */
irq_set_irq_type(AU1200_GPIO7_INT, IRQ_TYPE_LEVEL_LOW);
bcsr_init_irq(DB1200_INT_BEGIN, DB1200_INT_END, AU1200_GPIO7_INT);
/* insert/eject pairs: one of both is always screaming. To avoid
* issues they must not be automatically enabled when initially
* requested.
*/
irq_set_status_flags(DB1200_SD0_INSERT_INT, IRQ_NOAUTOEN);
irq_set_status_flags(DB1200_SD0_EJECT_INT, IRQ_NOAUTOEN);
irq_set_status_flags(DB1200_PC0_INSERT_INT, IRQ_NOAUTOEN);
irq_set_status_flags(DB1200_PC0_EJECT_INT, IRQ_NOAUTOEN);
irq_set_status_flags(DB1200_PC1_INSERT_INT, IRQ_NOAUTOEN);
irq_set_status_flags(DB1200_PC1_EJECT_INT, IRQ_NOAUTOEN);
i2c_register_board_info(0, db1200_i2c_devs,
ARRAY_SIZE(db1200_i2c_devs));
@@ -540,6 +833,7 @@ static int __init db1200_dev_init(void)
/* SWITCHES: S6.8 I2C/SPI selector (OFF=I2C ON=SPI)
* S6.7 AC97/I2S selector (OFF=AC97 ON=I2S)
* or S12 on the PB1200.
*/
/* NOTE: GPIO215 controls OTG VBUS supply. In SPI mode however
@@ -554,7 +848,7 @@ static int __init db1200_dev_init(void)
gpio_request(215, "otg-vbus");
gpio_direction_output(215, 1);
printk(KERN_INFO "DB1200 device configuration:\n");
printk(KERN_INFO "%s device configuration:\n", board_type_str());
sw = bcsr_read(BCSR_SWITCHES);
if (sw & BCSR_SWITCHES_DIP_8) {
@@ -595,7 +889,7 @@ static int __init db1200_dev_init(void)
/* Audio PSC clock is supplied externally. (FIXME: platdata!!) */
__raw_writel(PSC_SEL_CLK_SERCLK,
(void __iomem *)KSEG1ADDR(AU1550_PSC1_PHYS_ADDR) + PSC_SEL_OFFSET);
(void __iomem *)KSEG1ADDR(AU1550_PSC1_PHYS_ADDR) + PSC_SEL_OFFSET);
wmb();
db1x_register_pcmcia_socket(
@@ -621,28 +915,13 @@ static int __init db1200_dev_init(void)
swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1200_SWAPBOOT;
db1x_register_norflash(64 << 20, 2, swapped);
return platform_add_devices(db1200_devs, ARRAY_SIZE(db1200_devs));
platform_add_devices(db1200_devs, ARRAY_SIZE(db1200_devs));
/* PB1200 is a DB1200 with a 2nd MMC and Camera connector */
if ((bid == BCSR_WHOAMI_PB1200_DDR1) ||
(bid == BCSR_WHOAMI_PB1200_DDR2))
platform_add_devices(pb1200_devs, ARRAY_SIZE(pb1200_devs));
return 0;
}
device_initcall(db1200_dev_init);
/* au1200fb calls these: STERBT EINEN TRAGISCHEN TOD!!! */
int board_au1200fb_panel(void)
{
return (bcsr_read(BCSR_SWITCHES) >> 8) & 0x0f;
}
int board_au1200fb_panel_init(void)
{
/* Apply power */
bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD |
BCSR_BOARD_LCDBL);
return 0;
}
int board_au1200fb_panel_shutdown(void)
{
/* Remove power */
bcsr_mod(BCSR_BOARD, BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD |
BCSR_BOARD_LCDBL, 0);
return 0;
}

View File

@@ -1 +0,0 @@
obj-y += setup.o platform.o

View File

@@ -1,81 +0,0 @@
/*
* Alchemy/AMD/RMI DB1200 board setup.
*
* Licensed under the terms outlined in the file COPYING in the root of
* this source archive.
*/
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-db1x00/bcsr.h>
#include <asm/mach-db1x00/db1200.h>
const char *get_system_type(void)
{
return "Alchemy Db1200";
}
void __init board_setup(void)
{
unsigned long freq0, clksrc, div, pfc;
unsigned short whoami;
bcsr_init(DB1200_BCSR_PHYS_ADDR,
DB1200_BCSR_PHYS_ADDR + DB1200_BCSR_HEXLED_OFS);
whoami = bcsr_read(BCSR_WHOAMI);
printk(KERN_INFO "Alchemy/AMD/RMI DB1200 Board, CPLD Rev %d"
" Board-ID %d Daughtercard ID %d\n",
(whoami >> 4) & 0xf, (whoami >> 8) & 0xf, whoami & 0xf);
/* SMBus/SPI on PSC0, Audio on PSC1 */
pfc = __raw_readl((void __iomem *)SYS_PINFUNC);
pfc &= ~(SYS_PINFUNC_P0A | SYS_PINFUNC_P0B);
pfc &= ~(SYS_PINFUNC_P1A | SYS_PINFUNC_P1B | SYS_PINFUNC_FS3);
pfc |= SYS_PINFUNC_P1C; /* SPI is configured later */
__raw_writel(pfc, (void __iomem *)SYS_PINFUNC);
wmb();
/* Clock configurations: PSC0: ~50MHz via Clkgen0, derived from
* CPU clock; all other clock generators off/unused.
*/
div = (get_au1x00_speed() + 25000000) / 50000000;
if (div & 1)
div++;
div = ((div >> 1) - 1) & 0xff;
freq0 = div << SYS_FC_FRDIV0_BIT;
__raw_writel(freq0, (void __iomem *)SYS_FREQCTRL0);
wmb();
freq0 |= SYS_FC_FE0; /* enable F0 */
__raw_writel(freq0, (void __iomem *)SYS_FREQCTRL0);
wmb();
/* psc0_intclk comes 1:1 from F0 */
clksrc = SYS_CS_MUX_FQ0 << SYS_CS_ME0_BIT;
__raw_writel(clksrc, (void __iomem *)SYS_CLKSRC);
wmb();
}
static int __init db1200_arch_init(void)
{
/* GPIO7 is low-level triggered CPLD cascade */
irq_set_irq_type(AU1200_GPIO7_INT, IRQF_TRIGGER_LOW);
bcsr_init_irq(DB1200_INT_BEGIN, DB1200_INT_END, AU1200_GPIO7_INT);
/* insert/eject pairs: one of both is always screaming. To avoid
* issues they must not be automatically enabled when initially
* requested.
*/
irq_set_status_flags(DB1200_SD0_INSERT_INT, IRQ_NOAUTOEN);
irq_set_status_flags(DB1200_SD0_EJECT_INT, IRQ_NOAUTOEN);
irq_set_status_flags(DB1200_PC0_INSERT_INT, IRQ_NOAUTOEN);
irq_set_status_flags(DB1200_PC0_EJECT_INT, IRQ_NOAUTOEN);
irq_set_status_flags(DB1200_PC1_INSERT_INT, IRQ_NOAUTOEN);
irq_set_status_flags(DB1200_PC1_EJECT_INT, IRQ_NOAUTOEN);
return 0;
}
arch_initcall(db1200_arch_init);

View File

@@ -0,0 +1,785 @@
/*
* DBAu1300 init and platform device setup.
*
* (c) 2009 Manuel Lauss <manuel.lauss@googlemail.com>
*/
#include <linux/dma-mapping.h>
#include <linux/gpio.h>
#include <linux/gpio_keys.h>
#include <linux/init.h>
#include <linux/input.h> /* KEY_* codes */
#include <linux/i2c.h>
#include <linux/io.h>
#include <linux/leds.h>
#include <linux/ata_platform.h>
#include <linux/mmc/host.h>
#include <linux/module.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#include <linux/platform_device.h>
#include <linux/smsc911x.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/au1100_mmc.h>
#include <asm/mach-au1x00/au1200fb.h>
#include <asm/mach-au1x00/au1xxx_dbdma.h>
#include <asm/mach-au1x00/au1xxx_psc.h>
#include <asm/mach-db1x00/db1300.h>
#include <asm/mach-db1x00/bcsr.h>
#include <asm/mach-au1x00/prom.h>
#include "platform.h"
static struct i2c_board_info db1300_i2c_devs[] __initdata = {
{ I2C_BOARD_INFO("wm8731", 0x1b), }, /* I2S audio codec */
{ I2C_BOARD_INFO("ne1619", 0x2d), }, /* adm1025-compat hwmon */
};
/* multifunction pins to assign to GPIO controller */
static int db1300_gpio_pins[] __initdata = {
AU1300_PIN_LCDPWM0, AU1300_PIN_PSC2SYNC1, AU1300_PIN_WAKE1,
AU1300_PIN_WAKE2, AU1300_PIN_WAKE3, AU1300_PIN_FG3AUX,
AU1300_PIN_EXTCLK1,
-1, /* terminator */
};
/* multifunction pins to assign to device functions */
static int db1300_dev_pins[] __initdata = {
/* wake-from-str pins 0-3 */
AU1300_PIN_WAKE0,
/* external clock sources for PSC0 */
AU1300_PIN_EXTCLK0,
/* 8bit MMC interface on SD0: 6-9 */
AU1300_PIN_SD0DAT4, AU1300_PIN_SD0DAT5, AU1300_PIN_SD0DAT6,
AU1300_PIN_SD0DAT7,
/* UART1 pins: 11-18 */
AU1300_PIN_U1RI, AU1300_PIN_U1DCD, AU1300_PIN_U1DSR,
AU1300_PIN_U1CTS, AU1300_PIN_U1RTS, AU1300_PIN_U1DTR,
AU1300_PIN_U1RX, AU1300_PIN_U1TX,
/* UART0 pins: 19-24 */
AU1300_PIN_U0RI, AU1300_PIN_U0DCD, AU1300_PIN_U0DSR,
AU1300_PIN_U0CTS, AU1300_PIN_U0RTS, AU1300_PIN_U0DTR,
/* UART2: 25-26 */
AU1300_PIN_U2RX, AU1300_PIN_U2TX,
/* UART3: 27-28 */
AU1300_PIN_U3RX, AU1300_PIN_U3TX,
/* LCD controller PWMs, ext pixclock: 30-31 */
AU1300_PIN_LCDPWM1, AU1300_PIN_LCDCLKIN,
/* SD1 interface: 32-37 */
AU1300_PIN_SD1DAT0, AU1300_PIN_SD1DAT1, AU1300_PIN_SD1DAT2,
AU1300_PIN_SD1DAT3, AU1300_PIN_SD1CMD, AU1300_PIN_SD1CLK,
/* SD2 interface: 38-43 */
AU1300_PIN_SD2DAT0, AU1300_PIN_SD2DAT1, AU1300_PIN_SD2DAT2,
AU1300_PIN_SD2DAT3, AU1300_PIN_SD2CMD, AU1300_PIN_SD2CLK,
/* PSC0/1 clocks: 44-45 */
AU1300_PIN_PSC0CLK, AU1300_PIN_PSC1CLK,
/* PSCs: 46-49/50-53/54-57/58-61 */
AU1300_PIN_PSC0SYNC0, AU1300_PIN_PSC0SYNC1, AU1300_PIN_PSC0D0,
AU1300_PIN_PSC0D1,
AU1300_PIN_PSC1SYNC0, AU1300_PIN_PSC1SYNC1, AU1300_PIN_PSC1D0,
AU1300_PIN_PSC1D1,
AU1300_PIN_PSC2SYNC0, AU1300_PIN_PSC2D0,
AU1300_PIN_PSC2D1,
AU1300_PIN_PSC3SYNC0, AU1300_PIN_PSC3SYNC1, AU1300_PIN_PSC3D0,
AU1300_PIN_PSC3D1,
/* PCMCIA interface: 62-70 */
AU1300_PIN_PCE2, AU1300_PIN_PCE1, AU1300_PIN_PIOS16,
AU1300_PIN_PIOR, AU1300_PIN_PWE, AU1300_PIN_PWAIT,
AU1300_PIN_PREG, AU1300_PIN_POE, AU1300_PIN_PIOW,
/* camera interface H/V sync inputs: 71-72 */
AU1300_PIN_CIMLS, AU1300_PIN_CIMFS,
/* PSC2/3 clocks: 73-74 */
AU1300_PIN_PSC2CLK, AU1300_PIN_PSC3CLK,
-1, /* terminator */
};
static void __init db1300_gpio_config(void)
{
int *i;
i = &db1300_dev_pins[0];
while (*i != -1)
au1300_pinfunc_to_dev(*i++);
i = &db1300_gpio_pins[0];
while (*i != -1)
au1300_gpio_direction_input(*i++);/* implies pin_to_gpio */
au1300_set_dbdma_gpio(1, AU1300_PIN_FG3AUX);
}
char *get_system_type(void)
{
return "DB1300";
}
/**********************************************************************/
static void au1300_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
unsigned int ctrl)
{
struct nand_chip *this = mtd->priv;
unsigned long ioaddr = (unsigned long)this->IO_ADDR_W;
ioaddr &= 0xffffff00;
if (ctrl & NAND_CLE) {
ioaddr += MEM_STNAND_CMD;
} else if (ctrl & NAND_ALE) {
ioaddr += MEM_STNAND_ADDR;
} else {
/* assume we want to r/w real data by default */
ioaddr += MEM_STNAND_DATA;
}
this->IO_ADDR_R = this->IO_ADDR_W = (void __iomem *)ioaddr;
if (cmd != NAND_CMD_NONE) {
__raw_writeb(cmd, this->IO_ADDR_W);
wmb();
}
}
static int au1300_nand_device_ready(struct mtd_info *mtd)
{
return __raw_readl((void __iomem *)MEM_STSTAT) & 1;
}
static const char *db1300_part_probes[] = { "cmdlinepart", NULL };
static struct mtd_partition db1300_nand_parts[] = {
{
.name = "NAND FS 0",
.offset = 0,
.size = 8 * 1024 * 1024,
},
{
.name = "NAND FS 1",
.offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL
},
};
struct platform_nand_data db1300_nand_platdata = {
.chip = {
.nr_chips = 1,
.chip_offset = 0,
.nr_partitions = ARRAY_SIZE(db1300_nand_parts),
.partitions = db1300_nand_parts,
.chip_delay = 20,
.part_probe_types = db1300_part_probes,
},
.ctrl = {
.dev_ready = au1300_nand_device_ready,
.cmd_ctrl = au1300_nand_cmd_ctrl,
},
};
static struct resource db1300_nand_res[] = {
[0] = {
.start = DB1300_NAND_PHYS_ADDR,
.end = DB1300_NAND_PHYS_ADDR + 0xff,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device db1300_nand_dev = {
.name = "gen_nand",
.num_resources = ARRAY_SIZE(db1300_nand_res),
.resource = db1300_nand_res,
.id = -1,
.dev = {
.platform_data = &db1300_nand_platdata,
}
};
/**********************************************************************/
static struct resource db1300_eth_res[] = {
[0] = {
.start = DB1300_ETH_PHYS_ADDR,
.end = DB1300_ETH_PHYS_END,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = DB1300_ETH_INT,
.end = DB1300_ETH_INT,
.flags = IORESOURCE_IRQ,
},
};
static struct smsc911x_platform_config db1300_eth_config = {
.phy_interface = PHY_INTERFACE_MODE_MII,
.irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
.irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
.flags = SMSC911X_USE_32BIT,
};
static struct platform_device db1300_eth_dev = {
.name = "smsc911x",
.id = -1,
.num_resources = ARRAY_SIZE(db1300_eth_res),
.resource = db1300_eth_res,
.dev = {
.platform_data = &db1300_eth_config,
},
};
/**********************************************************************/
static struct resource au1300_psc1_res[] = {
[0] = {
.start = AU1300_PSC1_PHYS_ADDR,
.end = AU1300_PSC1_PHYS_ADDR + 0x0fff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AU1300_PSC1_INT,
.end = AU1300_PSC1_INT,
.flags = IORESOURCE_IRQ,
},
[2] = {
.start = AU1300_DSCR_CMD0_PSC1_TX,
.end = AU1300_DSCR_CMD0_PSC1_TX,
.flags = IORESOURCE_DMA,
},
[3] = {
.start = AU1300_DSCR_CMD0_PSC1_RX,
.end = AU1300_DSCR_CMD0_PSC1_RX,
.flags = IORESOURCE_DMA,
},
};
static struct platform_device db1300_ac97_dev = {
.name = "au1xpsc_ac97",
.id = 1, /* PSC ID. match with AC97 codec ID! */
.num_resources = ARRAY_SIZE(au1300_psc1_res),
.resource = au1300_psc1_res,
};
/**********************************************************************/
static struct resource au1300_psc2_res[] = {
[0] = {
.start = AU1300_PSC2_PHYS_ADDR,
.end = AU1300_PSC2_PHYS_ADDR + 0x0fff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AU1300_PSC2_INT,
.end = AU1300_PSC2_INT,
.flags = IORESOURCE_IRQ,
},
[2] = {
.start = AU1300_DSCR_CMD0_PSC2_TX,
.end = AU1300_DSCR_CMD0_PSC2_TX,
.flags = IORESOURCE_DMA,
},
[3] = {
.start = AU1300_DSCR_CMD0_PSC2_RX,
.end = AU1300_DSCR_CMD0_PSC2_RX,
.flags = IORESOURCE_DMA,
},
};
static struct platform_device db1300_i2s_dev = {
.name = "au1xpsc_i2s",
.id = 2, /* PSC ID */
.num_resources = ARRAY_SIZE(au1300_psc2_res),
.resource = au1300_psc2_res,
};
/**********************************************************************/
static struct resource au1300_psc3_res[] = {
[0] = {
.start = AU1300_PSC3_PHYS_ADDR,
.end = AU1300_PSC3_PHYS_ADDR + 0x0fff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AU1300_PSC3_INT,
.end = AU1300_PSC3_INT,
.flags = IORESOURCE_IRQ,
},
[2] = {
.start = AU1300_DSCR_CMD0_PSC3_TX,
.end = AU1300_DSCR_CMD0_PSC3_TX,
.flags = IORESOURCE_DMA,
},
[3] = {
.start = AU1300_DSCR_CMD0_PSC3_RX,
.end = AU1300_DSCR_CMD0_PSC3_RX,
.flags = IORESOURCE_DMA,
},
};
static struct platform_device db1300_i2c_dev = {
.name = "au1xpsc_smbus",
.id = 0, /* bus number */
.num_resources = ARRAY_SIZE(au1300_psc3_res),
.resource = au1300_psc3_res,
};
/**********************************************************************/
/* proper key assignments when facing the LCD panel. For key assignments
* according to the schematics swap up with down and left with right.
* I chose to use it to emulate the arrow keys of a keyboard.
*/
static struct gpio_keys_button db1300_5waysw_arrowkeys[] = {
{
.code = KEY_DOWN,
.gpio = AU1300_PIN_LCDPWM0,
.type = EV_KEY,
.debounce_interval = 1,
.active_low = 1,
.desc = "5waysw-down",
},
{
.code = KEY_UP,
.gpio = AU1300_PIN_PSC2SYNC1,
.type = EV_KEY,
.debounce_interval = 1,
.active_low = 1,
.desc = "5waysw-up",
},
{
.code = KEY_RIGHT,
.gpio = AU1300_PIN_WAKE3,
.type = EV_KEY,
.debounce_interval = 1,
.active_low = 1,
.desc = "5waysw-right",
},
{
.code = KEY_LEFT,
.gpio = AU1300_PIN_WAKE2,
.type = EV_KEY,
.debounce_interval = 1,
.active_low = 1,
.desc = "5waysw-left",
},
{
.code = KEY_ENTER,
.gpio = AU1300_PIN_WAKE1,
.type = EV_KEY,
.debounce_interval = 1,
.active_low = 1,
.desc = "5waysw-push",
},
};
static struct gpio_keys_platform_data db1300_5waysw_data = {
.buttons = db1300_5waysw_arrowkeys,
.nbuttons = ARRAY_SIZE(db1300_5waysw_arrowkeys),
.rep = 1,
.name = "db1300-5wayswitch",
};
static struct platform_device db1300_5waysw_dev = {
.name = "gpio-keys",
.dev = {
.platform_data = &db1300_5waysw_data,
},
};
/**********************************************************************/
static struct pata_platform_info db1300_ide_info = {
.ioport_shift = DB1300_IDE_REG_SHIFT,
};
#define IDE_ALT_START (14 << DB1300_IDE_REG_SHIFT)
static struct resource db1300_ide_res[] = {
[0] = {
.start = DB1300_IDE_PHYS_ADDR,
.end = DB1300_IDE_PHYS_ADDR + IDE_ALT_START - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = DB1300_IDE_PHYS_ADDR + IDE_ALT_START,
.end = DB1300_IDE_PHYS_ADDR + DB1300_IDE_PHYS_LEN - 1,
.flags = IORESOURCE_MEM,
},
[2] = {
.start = DB1300_IDE_INT,
.end = DB1300_IDE_INT,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device db1300_ide_dev = {
.dev = {
.platform_data = &db1300_ide_info,
},
.name = "pata_platform",
.resource = db1300_ide_res,
.num_resources = ARRAY_SIZE(db1300_ide_res),
};
/**********************************************************************/
static irqreturn_t db1300_mmc_cd(int irq, void *ptr)
{
void(*mmc_cd)(struct mmc_host *, unsigned long);
/* disable the one currently screaming. No other way to shut it up */
if (irq == DB1300_SD1_INSERT_INT) {
disable_irq_nosync(DB1300_SD1_INSERT_INT);
enable_irq(DB1300_SD1_EJECT_INT);
} else {
disable_irq_nosync(DB1300_SD1_EJECT_INT);
enable_irq(DB1300_SD1_INSERT_INT);
}
/* link against CONFIG_MMC=m. We can only be called once MMC core has
* initialized the controller, so symbol_get() should always succeed.
*/
mmc_cd = symbol_get(mmc_detect_change);
mmc_cd(ptr, msecs_to_jiffies(500));
symbol_put(mmc_detect_change);
return IRQ_HANDLED;
}
static int db1300_mmc_card_readonly(void *mmc_host)
{
/* it uses SD1 interface, but the DB1200's SD0 bit in the CPLD */
return bcsr_read(BCSR_STATUS) & BCSR_STATUS_SD0WP;
}
static int db1300_mmc_card_inserted(void *mmc_host)
{
return bcsr_read(BCSR_SIGSTAT) & (1 << 12); /* insertion irq signal */
}
static int db1300_mmc_cd_setup(void *mmc_host, int en)
{
int ret;
if (en) {
ret = request_irq(DB1300_SD1_INSERT_INT, db1300_mmc_cd, 0,
"sd_insert", mmc_host);
if (ret)
goto out;
ret = request_irq(DB1300_SD1_EJECT_INT, db1300_mmc_cd, 0,
"sd_eject", mmc_host);
if (ret) {
free_irq(DB1300_SD1_INSERT_INT, mmc_host);
goto out;
}
if (db1300_mmc_card_inserted(mmc_host))
enable_irq(DB1300_SD1_EJECT_INT);
else
enable_irq(DB1300_SD1_INSERT_INT);
} else {
free_irq(DB1300_SD1_INSERT_INT, mmc_host);
free_irq(DB1300_SD1_EJECT_INT, mmc_host);
}
ret = 0;
out:
return ret;
}
static void db1300_mmcled_set(struct led_classdev *led,
enum led_brightness brightness)
{
if (brightness != LED_OFF)
bcsr_mod(BCSR_LEDS, BCSR_LEDS_LED0, 0);
else
bcsr_mod(BCSR_LEDS, 0, BCSR_LEDS_LED0);
}
static struct led_classdev db1300_mmc_led = {
.brightness_set = db1300_mmcled_set,
};
struct au1xmmc_platform_data db1300_sd1_platdata = {
.cd_setup = db1300_mmc_cd_setup,
.card_inserted = db1300_mmc_card_inserted,
.card_readonly = db1300_mmc_card_readonly,
.led = &db1300_mmc_led,
};
static struct resource au1300_sd1_res[] = {
[0] = {
.start = AU1300_SD1_PHYS_ADDR,
.end = AU1300_SD1_PHYS_ADDR,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AU1300_SD1_INT,
.end = AU1300_SD1_INT,
.flags = IORESOURCE_IRQ,
},
[2] = {
.start = AU1300_DSCR_CMD0_SDMS_TX1,
.end = AU1300_DSCR_CMD0_SDMS_TX1,
.flags = IORESOURCE_DMA,
},
[3] = {
.start = AU1300_DSCR_CMD0_SDMS_RX1,
.end = AU1300_DSCR_CMD0_SDMS_RX1,
.flags = IORESOURCE_DMA,
},
};
static struct platform_device db1300_sd1_dev = {
.dev = {
.platform_data = &db1300_sd1_platdata,
},
.name = "au1xxx-mmc",
.id = 1,
.resource = au1300_sd1_res,
.num_resources = ARRAY_SIZE(au1300_sd1_res),
};
/**********************************************************************/
static int db1300_movinand_inserted(void *mmc_host)
{
return 0; /* disable for now, it doesn't work yet */
}
static int db1300_movinand_readonly(void *mmc_host)
{
return 0;
}
static void db1300_movinand_led_set(struct led_classdev *led,
enum led_brightness brightness)
{
if (brightness != LED_OFF)
bcsr_mod(BCSR_LEDS, BCSR_LEDS_LED1, 0);
else
bcsr_mod(BCSR_LEDS, 0, BCSR_LEDS_LED1);
}
static struct led_classdev db1300_movinand_led = {
.brightness_set = db1300_movinand_led_set,
};
struct au1xmmc_platform_data db1300_sd0_platdata = {
.card_inserted = db1300_movinand_inserted,
.card_readonly = db1300_movinand_readonly,
.led = &db1300_movinand_led,
.mask_host_caps = MMC_CAP_NEEDS_POLL,
};
static struct resource au1300_sd0_res[] = {
[0] = {
.start = AU1100_SD0_PHYS_ADDR,
.end = AU1100_SD0_PHYS_ADDR,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AU1300_SD0_INT,
.end = AU1300_SD0_INT,
.flags = IORESOURCE_IRQ,
},
[2] = {
.start = AU1300_DSCR_CMD0_SDMS_TX0,
.end = AU1300_DSCR_CMD0_SDMS_TX0,
.flags = IORESOURCE_DMA,
},
[3] = {
.start = AU1300_DSCR_CMD0_SDMS_RX0,
.end = AU1300_DSCR_CMD0_SDMS_RX0,
.flags = IORESOURCE_DMA,
},
};
static struct platform_device db1300_sd0_dev = {
.dev = {
.platform_data = &db1300_sd0_platdata,
},
.name = "au1xxx-mmc",
.id = 0,
.resource = au1300_sd0_res,
.num_resources = ARRAY_SIZE(au1300_sd0_res),
};
/**********************************************************************/
static struct platform_device db1300_wm9715_dev = {
.name = "wm9712-codec",
.id = 1, /* ID of PSC for AC97 audio, see asoc glue! */
};
static struct platform_device db1300_ac97dma_dev = {
.name = "au1xpsc-pcm",
.id = 1, /* PSC ID */
};
static struct platform_device db1300_i2sdma_dev = {
.name = "au1xpsc-pcm",
.id = 2, /* PSC ID */
};
static struct platform_device db1300_sndac97_dev = {
.name = "db1300-ac97",
};
static struct platform_device db1300_sndi2s_dev = {
.name = "db1300-i2s",
};
/**********************************************************************/
static int db1300fb_panel_index(void)
{
return 9; /* DB1300_800x480 */
}
static int db1300fb_panel_init(void)
{
/* Apply power (Vee/Vdd logic is inverted on Panel DB1300_800x480) */
bcsr_mod(BCSR_BOARD, BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD,
BCSR_BOARD_LCDBL);
return 0;
}
static int db1300fb_panel_shutdown(void)
{
/* Remove power (Vee/Vdd logic is inverted on Panel DB1300_800x480) */
bcsr_mod(BCSR_BOARD, BCSR_BOARD_LCDBL,
BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD);
return 0;
}
static struct au1200fb_platdata db1300fb_pd = {
.panel_index = db1300fb_panel_index,
.panel_init = db1300fb_panel_init,
.panel_shutdown = db1300fb_panel_shutdown,
};
static struct resource au1300_lcd_res[] = {
[0] = {
.start = AU1200_LCD_PHYS_ADDR,
.end = AU1200_LCD_PHYS_ADDR + 0x800 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AU1300_LCD_INT,
.end = AU1300_LCD_INT,
.flags = IORESOURCE_IRQ,
}
};
static u64 au1300_lcd_dmamask = DMA_BIT_MASK(32);
static struct platform_device db1300_lcd_dev = {
.name = "au1200-lcd",
.id = 0,
.dev = {
.dma_mask = &au1300_lcd_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = &db1300fb_pd,
},
.num_resources = ARRAY_SIZE(au1300_lcd_res),
.resource = au1300_lcd_res,
};
/**********************************************************************/
static struct platform_device *db1300_dev[] __initdata = {
&db1300_eth_dev,
&db1300_i2c_dev,
&db1300_5waysw_dev,
&db1300_nand_dev,
&db1300_ide_dev,
&db1300_sd0_dev,
&db1300_sd1_dev,
&db1300_lcd_dev,
&db1300_ac97_dev,
&db1300_i2s_dev,
&db1300_wm9715_dev,
&db1300_ac97dma_dev,
&db1300_i2sdma_dev,
&db1300_sndac97_dev,
&db1300_sndi2s_dev,
};
static int __init db1300_device_init(void)
{
int swapped, cpldirq;
/* setup CPLD IRQ muxer */
cpldirq = au1300_gpio_to_irq(AU1300_PIN_EXTCLK1);
irq_set_irq_type(cpldirq, IRQ_TYPE_LEVEL_HIGH);
bcsr_init_irq(DB1300_FIRST_INT, DB1300_LAST_INT, cpldirq);
/* insert/eject IRQs: one always triggers so don't enable them
* when doing request_irq() on them. DB1200 has this bug too.
*/
irq_set_status_flags(DB1300_SD1_INSERT_INT, IRQ_NOAUTOEN);
irq_set_status_flags(DB1300_SD1_EJECT_INT, IRQ_NOAUTOEN);
irq_set_status_flags(DB1300_CF_INSERT_INT, IRQ_NOAUTOEN);
irq_set_status_flags(DB1300_CF_EJECT_INT, IRQ_NOAUTOEN);
/*
* setup board
*/
prom_get_ethernet_addr(&db1300_eth_config.mac[0]);
i2c_register_board_info(0, db1300_i2c_devs,
ARRAY_SIZE(db1300_i2c_devs));
/* Audio PSC clock is supplied by codecs (PSC1, 2) */
__raw_writel(PSC_SEL_CLK_SERCLK,
(void __iomem *)KSEG1ADDR(AU1300_PSC1_PHYS_ADDR) + PSC_SEL_OFFSET);
wmb();
__raw_writel(PSC_SEL_CLK_SERCLK,
(void __iomem *)KSEG1ADDR(AU1300_PSC2_PHYS_ADDR) + PSC_SEL_OFFSET);
wmb();
/* I2C uses internal 48MHz EXTCLK1 */
__raw_writel(PSC_SEL_CLK_INTCLK,
(void __iomem *)KSEG1ADDR(AU1300_PSC3_PHYS_ADDR) + PSC_SEL_OFFSET);
wmb();
/* enable power to USB ports */
bcsr_mod(BCSR_RESETS, 0, BCSR_RESETS_USBHPWR | BCSR_RESETS_OTGPWR);
/* although it is socket #0, it uses the CPLD bits which previous boards
* have used for socket #1.
*/
db1x_register_pcmcia_socket(
AU1000_PCMCIA_ATTR_PHYS_ADDR,
AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x00400000 - 1,
AU1000_PCMCIA_MEM_PHYS_ADDR,
AU1000_PCMCIA_MEM_PHYS_ADDR + 0x00400000 - 1,
AU1000_PCMCIA_IO_PHYS_ADDR,
AU1000_PCMCIA_IO_PHYS_ADDR + 0x00010000 - 1,
DB1300_CF_INT, DB1300_CF_INSERT_INT, 0, DB1300_CF_EJECT_INT, 1);
swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1200_SWAPBOOT;
db1x_register_norflash(64 << 20, 2, swapped);
return platform_add_devices(db1300_dev, ARRAY_SIZE(db1300_dev));
}
device_initcall(db1300_device_init);
void __init board_setup(void)
{
unsigned short whoami;
db1300_gpio_config();
bcsr_init(DB1300_BCSR_PHYS_ADDR,
DB1300_BCSR_PHYS_ADDR + DB1300_BCSR_HEXLED_OFS);
whoami = bcsr_read(BCSR_WHOAMI);
printk(KERN_INFO "NetLogic DBAu1300 Development Platform.\n\t"
"BoardID %d CPLD Rev %d DaughtercardID %d\n",
BCSR_WHOAMI_BOARD(whoami), BCSR_WHOAMI_CPLD(whoami),
BCSR_WHOAMI_DCID(whoami));
/* enable UARTs, YAMON only enables #2 */
alchemy_uart_enable(AU1300_UART0_PHYS_ADDR);
alchemy_uart_enable(AU1300_UART1_PHYS_ADDR);
alchemy_uart_enable(AU1300_UART3_PHYS_ADDR);
}

View File

@@ -0,0 +1,498 @@
/*
* Alchemy Db1550 board support
*
* (c) 2011 Manuel Lauss <manuel.lauss@googlemail.com>
*/
#include <linux/dma-mapping.h>
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/spi/spi.h>
#include <linux/spi/flash.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/au1xxx_eth.h>
#include <asm/mach-au1x00/au1xxx_dbdma.h>
#include <asm/mach-au1x00/au1xxx_psc.h>
#include <asm/mach-au1x00/au1550_spi.h>
#include <asm/mach-db1x00/bcsr.h>
#include <prom.h>
#include "platform.h"
const char *get_system_type(void)
{
return "DB1550";
}
static void __init db1550_hw_setup(void)
{
void __iomem *base;
alchemy_gpio_direction_output(203, 0); /* red led on */
/* complete SPI setup: link psc0_intclk to a 48MHz source,
* and assign GPIO16 to PSC0_SYNC1 (SPI cs# line)
*/
base = (void __iomem *)SYS_CLKSRC;
__raw_writel(__raw_readl(base) | 0x000001e0, base);
base = (void __iomem *)SYS_PINFUNC;
__raw_writel(__raw_readl(base) | 1, base);
wmb();
/* reset the AC97 codec now, the reset time in the psc-ac97 driver
* is apparently too short although it's ridiculous as it is.
*/
base = (void __iomem *)KSEG1ADDR(AU1550_PSC1_PHYS_ADDR);
__raw_writel(PSC_SEL_CLK_SERCLK | PSC_SEL_PS_AC97MODE,
base + PSC_SEL_OFFSET);
__raw_writel(PSC_CTRL_DISABLE, base + PSC_CTRL_OFFSET);
wmb();
__raw_writel(PSC_AC97RST_RST, base + PSC_AC97RST_OFFSET);
wmb();
alchemy_gpio_direction_output(202, 0); /* green led on */
}
void __init board_setup(void)
{
unsigned short whoami;
bcsr_init(DB1550_BCSR_PHYS_ADDR,
DB1550_BCSR_PHYS_ADDR + DB1550_BCSR_HEXLED_OFS);
whoami = bcsr_read(BCSR_WHOAMI);
printk(KERN_INFO "Alchemy/AMD DB1550 Board, CPLD Rev %d"
" Board-ID %d Daughtercard ID %d\n",
(whoami >> 4) & 0xf, (whoami >> 8) & 0xf, whoami & 0xf);
db1550_hw_setup();
}
/*****************************************************************************/
static struct mtd_partition db1550_spiflash_parts[] = {
{
.name = "spi_flash",
.offset = 0,
.size = MTDPART_SIZ_FULL,
},
};
static struct flash_platform_data db1550_spiflash_data = {
.name = "s25fl010",
.parts = db1550_spiflash_parts,
.nr_parts = ARRAY_SIZE(db1550_spiflash_parts),
.type = "m25p10",
};
static struct spi_board_info db1550_spi_devs[] __initdata = {
{
/* TI TMP121AIDBVR temp sensor */
.modalias = "tmp121",
.max_speed_hz = 2400000,
.bus_num = 0,
.chip_select = 0,
.mode = SPI_MODE_0,
},
{
/* Spansion S25FL001D0FMA SPI flash */
.modalias = "m25p80",
.max_speed_hz = 2400000,
.bus_num = 0,
.chip_select = 1,
.mode = SPI_MODE_0,
.platform_data = &db1550_spiflash_data,
},
};
static struct i2c_board_info db1550_i2c_devs[] __initdata = {
{ I2C_BOARD_INFO("24c04", 0x52),}, /* AT24C04-10 I2C eeprom */
{ I2C_BOARD_INFO("ne1619", 0x2d),}, /* adm1025-compat hwmon */
{ I2C_BOARD_INFO("wm8731", 0x1b),}, /* I2S audio codec WM8731 */
};
/**********************************************************************/
static void au1550_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
unsigned int ctrl)
{
struct nand_chip *this = mtd->priv;
unsigned long ioaddr = (unsigned long)this->IO_ADDR_W;
ioaddr &= 0xffffff00;
if (ctrl & NAND_CLE) {
ioaddr += MEM_STNAND_CMD;
} else if (ctrl & NAND_ALE) {
ioaddr += MEM_STNAND_ADDR;
} else {
/* assume we want to r/w real data by default */
ioaddr += MEM_STNAND_DATA;
}
this->IO_ADDR_R = this->IO_ADDR_W = (void __iomem *)ioaddr;
if (cmd != NAND_CMD_NONE) {
__raw_writeb(cmd, this->IO_ADDR_W);
wmb();
}
}
static int au1550_nand_device_ready(struct mtd_info *mtd)
{
return __raw_readl((void __iomem *)MEM_STSTAT) & 1;
}
static const char *db1550_part_probes[] = { "cmdlinepart", NULL };
static struct mtd_partition db1550_nand_parts[] = {
{
.name = "NAND FS 0",
.offset = 0,
.size = 8 * 1024 * 1024,
},
{
.name = "NAND FS 1",
.offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL
},
};
struct platform_nand_data db1550_nand_platdata = {
.chip = {
.nr_chips = 1,
.chip_offset = 0,
.nr_partitions = ARRAY_SIZE(db1550_nand_parts),
.partitions = db1550_nand_parts,
.chip_delay = 20,
.part_probe_types = db1550_part_probes,
},
.ctrl = {
.dev_ready = au1550_nand_device_ready,
.cmd_ctrl = au1550_nand_cmd_ctrl,
},
};
static struct resource db1550_nand_res[] = {
[0] = {
.start = 0x20000000,
.end = 0x200000ff,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device db1550_nand_dev = {
.name = "gen_nand",
.num_resources = ARRAY_SIZE(db1550_nand_res),
.resource = db1550_nand_res,
.id = -1,
.dev = {
.platform_data = &db1550_nand_platdata,
}
};
/**********************************************************************/
static struct resource au1550_psc0_res[] = {
[0] = {
.start = AU1550_PSC0_PHYS_ADDR,
.end = AU1550_PSC0_PHYS_ADDR + 0xfff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AU1550_PSC0_INT,
.end = AU1550_PSC0_INT,
.flags = IORESOURCE_IRQ,
},
[2] = {
.start = AU1550_DSCR_CMD0_PSC0_TX,
.end = AU1550_DSCR_CMD0_PSC0_TX,
.flags = IORESOURCE_DMA,
},
[3] = {
.start = AU1550_DSCR_CMD0_PSC0_RX,
.end = AU1550_DSCR_CMD0_PSC0_RX,
.flags = IORESOURCE_DMA,
},
};
static void db1550_spi_cs_en(struct au1550_spi_info *spi, int cs, int pol)
{
if (cs)
bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_SPISEL);
else
bcsr_mod(BCSR_BOARD, BCSR_BOARD_SPISEL, 0);
}
static struct au1550_spi_info db1550_spi_platdata = {
.mainclk_hz = 48000000, /* PSC0 clock: max. 2.4MHz SPI clk */
.num_chipselect = 2,
.activate_cs = db1550_spi_cs_en,
};
static u64 spi_dmamask = DMA_BIT_MASK(32);
static struct platform_device db1550_spi_dev = {
.dev = {
.dma_mask = &spi_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = &db1550_spi_platdata,
},
.name = "au1550-spi",
.id = 0, /* bus number */
.num_resources = ARRAY_SIZE(au1550_psc0_res),
.resource = au1550_psc0_res,
};
/**********************************************************************/
static struct resource au1550_psc1_res[] = {
[0] = {
.start = AU1550_PSC1_PHYS_ADDR,
.end = AU1550_PSC1_PHYS_ADDR + 0xfff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AU1550_PSC1_INT,
.end = AU1550_PSC1_INT,
.flags = IORESOURCE_IRQ,
},
[2] = {
.start = AU1550_DSCR_CMD0_PSC1_TX,
.end = AU1550_DSCR_CMD0_PSC1_TX,
.flags = IORESOURCE_DMA,
},
[3] = {
.start = AU1550_DSCR_CMD0_PSC1_RX,
.end = AU1550_DSCR_CMD0_PSC1_RX,
.flags = IORESOURCE_DMA,
},
};
static struct platform_device db1550_ac97_dev = {
.name = "au1xpsc_ac97",
.id = 1, /* PSC ID */
.num_resources = ARRAY_SIZE(au1550_psc1_res),
.resource = au1550_psc1_res,
};
static struct resource au1550_psc2_res[] = {
[0] = {
.start = AU1550_PSC2_PHYS_ADDR,
.end = AU1550_PSC2_PHYS_ADDR + 0xfff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AU1550_PSC2_INT,
.end = AU1550_PSC2_INT,
.flags = IORESOURCE_IRQ,
},
[2] = {
.start = AU1550_DSCR_CMD0_PSC2_TX,
.end = AU1550_DSCR_CMD0_PSC2_TX,
.flags = IORESOURCE_DMA,
},
[3] = {
.start = AU1550_DSCR_CMD0_PSC2_RX,
.end = AU1550_DSCR_CMD0_PSC2_RX,
.flags = IORESOURCE_DMA,
},
};
static struct platform_device db1550_i2c_dev = {
.name = "au1xpsc_smbus",
.id = 0, /* bus number */
.num_resources = ARRAY_SIZE(au1550_psc2_res),
.resource = au1550_psc2_res,
};
/**********************************************************************/
static struct resource au1550_psc3_res[] = {
[0] = {
.start = AU1550_PSC3_PHYS_ADDR,
.end = AU1550_PSC3_PHYS_ADDR + 0xfff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AU1550_PSC3_INT,
.end = AU1550_PSC3_INT,
.flags = IORESOURCE_IRQ,
},
[2] = {
.start = AU1550_DSCR_CMD0_PSC3_TX,
.end = AU1550_DSCR_CMD0_PSC3_TX,
.flags = IORESOURCE_DMA,
},
[3] = {
.start = AU1550_DSCR_CMD0_PSC3_RX,
.end = AU1550_DSCR_CMD0_PSC3_RX,
.flags = IORESOURCE_DMA,
},
};
static struct platform_device db1550_i2s_dev = {
.name = "au1xpsc_i2s",
.id = 3, /* PSC ID */
.num_resources = ARRAY_SIZE(au1550_psc3_res),
.resource = au1550_psc3_res,
};
/**********************************************************************/
static struct platform_device db1550_stac_dev = {
.name = "ac97-codec",
.id = 1, /* on PSC1 */
};
static struct platform_device db1550_ac97dma_dev = {
.name = "au1xpsc-pcm",
.id = 1, /* on PSC3 */
};
static struct platform_device db1550_i2sdma_dev = {
.name = "au1xpsc-pcm",
.id = 3, /* on PSC3 */
};
static struct platform_device db1550_sndac97_dev = {
.name = "db1550-ac97",
};
static struct platform_device db1550_sndi2s_dev = {
.name = "db1550-i2s",
};
/**********************************************************************/
static int db1550_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;
}
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 db1550_pci_pd = {
.board_map_irq = db1550_map_pci_irq,
};
static struct platform_device db1550_pci_host_dev = {
.dev.platform_data = &db1550_pci_pd,
.name = "alchemy-pci",
.id = 0,
.num_resources = ARRAY_SIZE(alchemy_pci_host_res),
.resource = alchemy_pci_host_res,
};
/**********************************************************************/
static struct platform_device *db1550_devs[] __initdata = {
&db1550_nand_dev,
&db1550_i2c_dev,
&db1550_ac97_dev,
&db1550_spi_dev,
&db1550_i2s_dev,
&db1550_stac_dev,
&db1550_ac97dma_dev,
&db1550_i2sdma_dev,
&db1550_sndac97_dev,
&db1550_sndi2s_dev,
};
/* must be arch_initcall; MIPS PCI scans busses in a subsys_initcall */
static int __init db1550_pci_init(void)
{
return platform_device_register(&db1550_pci_host_dev);
}
arch_initcall(db1550_pci_init);
static int __init db1550_dev_init(void)
{
int swapped;
irq_set_irq_type(AU1550_GPIO0_INT, IRQ_TYPE_EDGE_BOTH); /* CD0# */
irq_set_irq_type(AU1550_GPIO1_INT, IRQ_TYPE_EDGE_BOTH); /* CD1# */
irq_set_irq_type(AU1550_GPIO3_INT, IRQ_TYPE_LEVEL_LOW); /* CARD0# */
irq_set_irq_type(AU1550_GPIO5_INT, IRQ_TYPE_LEVEL_LOW); /* CARD1# */
irq_set_irq_type(AU1550_GPIO21_INT, IRQ_TYPE_LEVEL_LOW); /* STSCHG0# */
irq_set_irq_type(AU1550_GPIO22_INT, IRQ_TYPE_LEVEL_LOW); /* STSCHG1# */
i2c_register_board_info(0, db1550_i2c_devs,
ARRAY_SIZE(db1550_i2c_devs));
spi_register_board_info(db1550_spi_devs,
ARRAY_SIZE(db1550_i2c_devs));
/* Audio PSC clock is supplied by codecs (PSC1, 3) FIXME: platdata!! */
__raw_writel(PSC_SEL_CLK_SERCLK,
(void __iomem *)KSEG1ADDR(AU1550_PSC1_PHYS_ADDR) + PSC_SEL_OFFSET);
wmb();
__raw_writel(PSC_SEL_CLK_SERCLK,
(void __iomem *)KSEG1ADDR(AU1550_PSC3_PHYS_ADDR) + PSC_SEL_OFFSET);
wmb();
/* SPI/I2C use internally supplied 50MHz source */
__raw_writel(PSC_SEL_CLK_INTCLK,
(void __iomem *)KSEG1ADDR(AU1550_PSC0_PHYS_ADDR) + PSC_SEL_OFFSET);
wmb();
__raw_writel(PSC_SEL_CLK_INTCLK,
(void __iomem *)KSEG1ADDR(AU1550_PSC2_PHYS_ADDR) + PSC_SEL_OFFSET);
wmb();
db1x_register_pcmcia_socket(
AU1000_PCMCIA_ATTR_PHYS_ADDR,
AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
AU1000_PCMCIA_MEM_PHYS_ADDR,
AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
AU1000_PCMCIA_IO_PHYS_ADDR,
AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
AU1550_GPIO3_INT, AU1550_GPIO0_INT,
/*AU1550_GPIO21_INT*/0, 0, 0);
db1x_register_pcmcia_socket(
AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004000000,
AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004400000 - 1,
AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004000000,
AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004400000 - 1,
AU1000_PCMCIA_IO_PHYS_ADDR + 0x004000000,
AU1000_PCMCIA_IO_PHYS_ADDR + 0x004010000 - 1,
AU1550_GPIO5_INT, AU1550_GPIO1_INT,
/*AU1550_GPIO22_INT*/0, 0, 1);
swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT;
db1x_register_norflash(128 << 20, 4, swapped);
return platform_add_devices(db1550_devs, ARRAY_SIZE(db1550_devs));
}
device_initcall(db1550_dev_init);

View File

@@ -1,8 +0,0 @@
#
# Copyright 2000, 2008 MontaVista Software Inc.
# Author: MontaVista Software, Inc. <source@mvista.com>
#
# Makefile for the Alchemy Semiconductor DBAu1xx0 boards.
#
obj-y := board_setup.o platform.o

View File

@@ -1,229 +0,0 @@
/*
*
* BRIEF MODULE DESCRIPTION
* Alchemy Db1x00 board setup.
*
* Copyright 2000, 2008 MontaVista Software Inc.
* Author: MontaVista Software, Inc. <source@mvista.com>
*
* 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/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/au1xxx_eth.h>
#include <asm/mach-db1x00/db1x00.h>
#include <asm/mach-db1x00/bcsr.h>
#include <asm/reboot.h>
#include <prom.h>
#ifdef CONFIG_MIPS_BOSPORUS
char irq_tab_alchemy[][5] __initdata = {
[11] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff }, /* IDSEL 11 - miniPCI */
[12] = { -1, AU1500_PCI_INTA, 0xff, 0xff, 0xff }, /* IDSEL 12 - SN1741 */
[13] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, AU1500_PCI_INTC, AU1500_PCI_INTD }, /* IDSEL 13 - PCI slot */
};
/*
* Micrel/Kendin 5 port switch attached to MAC0,
* MAC0 is associated with PHY address 5 (== WAN port)
* MAC1 is not associated with any PHY, since it's connected directly
* to the switch.
* no interrupts are used
*/
static struct au1000_eth_platform_data eth0_pdata = {
.phy_static_config = 1,
.phy_addr = 5,
};
static void bosporus_power_off(void)
{
while (1)
asm volatile (".set mips3 ; wait ; .set mips0");
}
const char *get_system_type(void)
{
return "Alchemy Bosporus Gateway Reference";
}
#endif
#ifdef CONFIG_MIPS_MIRAGE
static void mirage_power_off(void)
{
alchemy_gpio_direction_output(210, 1);
}
const char *get_system_type(void)
{
return "Alchemy Mirage";
}
#endif
#if defined(CONFIG_MIPS_BOSPORUS) || defined(CONFIG_MIPS_MIRAGE)
static void mips_softreset(void)
{
asm volatile ("jr\t%0" : : "r"(0xbfc00000));
}
#else
const char *get_system_type(void)
{
return "Alchemy Db1x00";
}
#endif
void __init board_setup(void)
{
unsigned long bcsr1, bcsr2;
bcsr1 = DB1000_BCSR_PHYS_ADDR;
bcsr2 = DB1000_BCSR_PHYS_ADDR + DB1000_BCSR_HEXLED_OFS;
#ifdef CONFIG_MIPS_DB1000
printk(KERN_INFO "AMD Alchemy Au1000/Db1000 Board\n");
#endif
#ifdef CONFIG_MIPS_DB1500
printk(KERN_INFO "AMD Alchemy Au1500/Db1500 Board\n");
#endif
#ifdef CONFIG_MIPS_DB1100
printk(KERN_INFO "AMD Alchemy Au1100/Db1100 Board\n");
#endif
#ifdef CONFIG_MIPS_BOSPORUS
au1xxx_override_eth_cfg(0, &eth0_pdata);
printk(KERN_INFO "AMD Alchemy Bosporus Board\n");
#endif
#ifdef CONFIG_MIPS_MIRAGE
printk(KERN_INFO "AMD Alchemy Mirage Board\n");
#endif
#ifdef CONFIG_MIPS_DB1550
printk(KERN_INFO "AMD Alchemy Au1550/Db1550 Board\n");
bcsr1 = DB1550_BCSR_PHYS_ADDR;
bcsr2 = DB1550_BCSR_PHYS_ADDR + DB1550_BCSR_HEXLED_OFS;
#endif
/* initialize board register space */
bcsr_init(bcsr1, bcsr2);
#if defined(CONFIG_IRDA) && defined(CONFIG_AU1000_FIR)
{
u32 pin_func;
/* Set IRFIRSEL instead of GPIO15 */
pin_func = au_readl(SYS_PINFUNC) | SYS_PF_IRF;
au_writel(pin_func, SYS_PINFUNC);
/* Power off until the driver is in use */
bcsr_mod(BCSR_RESETS, BCSR_RESETS_IRDA_MODE_MASK,
BCSR_RESETS_IRDA_MODE_OFF);
}
#endif
bcsr_write(BCSR_PCMCIA, 0); /* turn off PCMCIA power */
/* Enable GPIO[31:0] inputs */
alchemy_gpio1_input_enable();
#ifdef CONFIG_MIPS_MIRAGE
{
u32 pin_func;
/* GPIO[20] is output */
alchemy_gpio_direction_output(20, 0);
/* Set GPIO[210:208] instead of SSI_0 */
pin_func = au_readl(SYS_PINFUNC) | SYS_PF_S0;
/* Set GPIO[215:211] for LEDs */
pin_func |= 5 << 2;
/* Set GPIO[214:213] for more LEDs */
pin_func |= 5 << 12;
/* Set GPIO[207:200] instead of PCMCIA/LCD */
pin_func |= SYS_PF_LCD | SYS_PF_PC;
au_writel(pin_func, SYS_PINFUNC);
/*
* Enable speaker amplifier. This should
* be part of the audio driver.
*/
alchemy_gpio_direction_output(209, 1);
pm_power_off = mirage_power_off;
_machine_halt = mirage_power_off;
_machine_restart = (void(*)(char *))mips_softreset;
}
#endif
#ifdef CONFIG_MIPS_BOSPORUS
pm_power_off = bosporus_power_off;
_machine_halt = bosporus_power_off;
_machine_restart = (void(*)(char *))mips_softreset;
#endif
au_sync();
}
static int __init db1x00_init_irq(void)
{
#if defined(CONFIG_MIPS_MIRAGE)
irq_set_irq_type(AU1500_GPIO7_INT, IRQF_TRIGGER_RISING); /* TS pendown */
#elif defined(CONFIG_MIPS_DB1550)
irq_set_irq_type(AU1550_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */
irq_set_irq_type(AU1550_GPIO1_INT, IRQF_TRIGGER_LOW); /* CD1# */
irq_set_irq_type(AU1550_GPIO3_INT, IRQF_TRIGGER_LOW); /* CARD0# */
irq_set_irq_type(AU1550_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */
irq_set_irq_type(AU1550_GPIO21_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
irq_set_irq_type(AU1550_GPIO22_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */
#elif defined(CONFIG_MIPS_DB1500)
irq_set_irq_type(AU1500_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */
irq_set_irq_type(AU1500_GPIO3_INT, IRQF_TRIGGER_LOW); /* CD1# */
irq_set_irq_type(AU1500_GPIO2_INT, IRQF_TRIGGER_LOW); /* CARD0# */
irq_set_irq_type(AU1500_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */
irq_set_irq_type(AU1500_GPIO1_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
irq_set_irq_type(AU1500_GPIO4_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */
#elif defined(CONFIG_MIPS_DB1100)
irq_set_irq_type(AU1100_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */
irq_set_irq_type(AU1100_GPIO3_INT, IRQF_TRIGGER_LOW); /* CD1# */
irq_set_irq_type(AU1100_GPIO2_INT, IRQF_TRIGGER_LOW); /* CARD0# */
irq_set_irq_type(AU1100_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */
irq_set_irq_type(AU1100_GPIO1_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
irq_set_irq_type(AU1100_GPIO4_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */
#elif defined(CONFIG_MIPS_DB1000)
irq_set_irq_type(AU1000_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */
irq_set_irq_type(AU1000_GPIO3_INT, IRQF_TRIGGER_LOW); /* CD1# */
irq_set_irq_type(AU1000_GPIO2_INT, IRQF_TRIGGER_LOW); /* CARD0# */
irq_set_irq_type(AU1000_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */
irq_set_irq_type(AU1000_GPIO1_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
irq_set_irq_type(AU1000_GPIO4_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */
#endif
return 0;
}
arch_initcall(db1x00_init_irq);

View File

@@ -1,316 +0,0 @@
/*
* DBAu1xxx board platform device registration
*
* Copyright (C) 2009 Manuel Lauss
*
* 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 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/au1000_dma.h>
#include <asm/mach-db1x00/bcsr.h>
#include "../platform.h"
struct pci_dev;
/* DB1xxx PCMCIA interrupt sources:
* CD0/1 GPIO0/3
* STSCHG0/1 GPIO1/4
* CARD0/1 GPIO2/5
* Db1550: 0/1, 21/22, 3/5
*/
#define DB1XXX_HAS_PCMCIA
#define F_SWAPPED (bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT)
#if defined(CONFIG_MIPS_DB1000)
#define DB1XXX_PCMCIA_CD0 AU1000_GPIO0_INT
#define DB1XXX_PCMCIA_STSCHG0 AU1000_GPIO1_INT
#define DB1XXX_PCMCIA_CARD0 AU1000_GPIO2_INT
#define DB1XXX_PCMCIA_CD1 AU1000_GPIO3_INT
#define DB1XXX_PCMCIA_STSCHG1 AU1000_GPIO4_INT
#define DB1XXX_PCMCIA_CARD1 AU1000_GPIO5_INT
#define BOARD_FLASH_SIZE 0x02000000 /* 32MB */
#define BOARD_FLASH_WIDTH 4 /* 32-bits */
#elif defined(CONFIG_MIPS_DB1100)
#define DB1XXX_PCMCIA_CD0 AU1100_GPIO0_INT
#define DB1XXX_PCMCIA_STSCHG0 AU1100_GPIO1_INT
#define DB1XXX_PCMCIA_CARD0 AU1100_GPIO2_INT
#define DB1XXX_PCMCIA_CD1 AU1100_GPIO3_INT
#define DB1XXX_PCMCIA_STSCHG1 AU1100_GPIO4_INT
#define DB1XXX_PCMCIA_CARD1 AU1100_GPIO5_INT
#define BOARD_FLASH_SIZE 0x02000000 /* 32MB */
#define BOARD_FLASH_WIDTH 4 /* 32-bits */
#elif defined(CONFIG_MIPS_DB1500)
#define DB1XXX_PCMCIA_CD0 AU1500_GPIO0_INT
#define DB1XXX_PCMCIA_STSCHG0 AU1500_GPIO1_INT
#define DB1XXX_PCMCIA_CARD0 AU1500_GPIO2_INT
#define DB1XXX_PCMCIA_CD1 AU1500_GPIO3_INT
#define DB1XXX_PCMCIA_STSCHG1 AU1500_GPIO4_INT
#define DB1XXX_PCMCIA_CARD1 AU1500_GPIO5_INT
#define BOARD_FLASH_SIZE 0x02000000 /* 32MB */
#define BOARD_FLASH_WIDTH 4 /* 32-bits */
#elif defined(CONFIG_MIPS_DB1550)
#define DB1XXX_PCMCIA_CD0 AU1550_GPIO0_INT
#define DB1XXX_PCMCIA_STSCHG0 AU1550_GPIO21_INT
#define DB1XXX_PCMCIA_CARD0 AU1550_GPIO3_INT
#define DB1XXX_PCMCIA_CD1 AU1550_GPIO1_INT
#define DB1XXX_PCMCIA_STSCHG1 AU1550_GPIO22_INT
#define DB1XXX_PCMCIA_CARD1 AU1550_GPIO5_INT
#define BOARD_FLASH_SIZE 0x08000000 /* 128MB */
#define BOARD_FLASH_WIDTH 4 /* 32-bits */
#else
/* other board: no PCMCIA */
#undef DB1XXX_HAS_PCMCIA
#undef F_SWAPPED
#define F_SWAPPED 0
#if defined(CONFIG_MIPS_BOSPORUS)
#define BOARD_FLASH_SIZE 0x01000000 /* 16MB */
#define BOARD_FLASH_WIDTH 2 /* 16-bits */
#elif defined(CONFIG_MIPS_MIRAGE)
#define BOARD_FLASH_SIZE 0x04000000 /* 64MB */
#define BOARD_FLASH_WIDTH 4 /* 32-bits */
#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
#ifdef CONFIG_MIPS_DB1100
static struct resource au1100_lcd_resources[] = {
[0] = {
.start = AU1100_LCD_PHYS_ADDR,
.end = AU1100_LCD_PHYS_ADDR + 0x800 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AU1100_LCD_INT,
.end = AU1100_LCD_INT,
.flags = IORESOURCE_IRQ,
}
};
static u64 au1100_lcd_dmamask = DMA_BIT_MASK(32);
static struct platform_device au1100_lcd_device = {
.name = "au1100-lcd",
.id = 0,
.dev = {
.dma_mask = &au1100_lcd_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
.num_resources = ARRAY_SIZE(au1100_lcd_resources),
.resource = au1100_lcd_resources,
};
#endif
static struct resource alchemy_ac97c_res[] = {
[0] = {
.start = AU1000_AC97_PHYS_ADDR,
.end = AU1000_AC97_PHYS_ADDR + 0xfff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = DMA_ID_AC97C_TX,
.end = DMA_ID_AC97C_TX,
.flags = IORESOURCE_DMA,
},
[2] = {
.start = DMA_ID_AC97C_RX,
.end = DMA_ID_AC97C_RX,
.flags = IORESOURCE_DMA,
},
};
static struct platform_device alchemy_ac97c_dev = {
.name = "alchemy-ac97c",
.id = -1,
.resource = alchemy_ac97c_res,
.num_resources = ARRAY_SIZE(alchemy_ac97c_res),
};
static struct platform_device alchemy_ac97c_dma_dev = {
.name = "alchemy-pcm-dma",
.id = 0,
};
static struct platform_device db1x00_codec_dev = {
.name = "ac97-codec",
.id = -1,
};
static struct platform_device db1x00_audio_dev = {
.name = "db1000-audio",
};
static int __init db1xxx_dev_init(void)
{
#ifdef DB1XXX_HAS_PCMCIA
db1x_register_pcmcia_socket(
AU1000_PCMCIA_ATTR_PHYS_ADDR,
AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
AU1000_PCMCIA_MEM_PHYS_ADDR,
AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
AU1000_PCMCIA_IO_PHYS_ADDR,
AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
DB1XXX_PCMCIA_CARD0, DB1XXX_PCMCIA_CD0,
/*DB1XXX_PCMCIA_STSCHG0*/0, 0, 0);
db1x_register_pcmcia_socket(
AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004000000,
AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004400000 - 1,
AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004000000,
AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004400000 - 1,
AU1000_PCMCIA_IO_PHYS_ADDR + 0x004000000,
AU1000_PCMCIA_IO_PHYS_ADDR + 0x004010000 - 1,
DB1XXX_PCMCIA_CARD1, DB1XXX_PCMCIA_CD1,
/*DB1XXX_PCMCIA_STSCHG1*/0, 0, 1);
#endif
#ifdef CONFIG_MIPS_DB1100
platform_device_register(&au1100_lcd_device);
#endif
db1x_register_norflash(BOARD_FLASH_SIZE, BOARD_FLASH_WIDTH, F_SWAPPED);
platform_device_register(&db1x00_codec_dev);
platform_device_register(&alchemy_ac97c_dma_dev);
platform_device_register(&alchemy_ac97c_dev);
platform_device_register(&db1x00_audio_dev);
return 0;
}
device_initcall(db1xxx_dev_init);

View File

@@ -1,8 +0,0 @@
#
# Copyright 2000, 2008 MontaVista Software Inc.
# Author: MontaVista Software, Inc. <source@mvista.com>
#
# Makefile for the Alchemy Semiconductor Pb1000 board.
#
obj-y := board_setup.o

View File

@@ -1,209 +0,0 @@
/*
* Copyright 2000, 2008 MontaVista Software Inc.
* Author: MontaVista Software, Inc. <source@mvista.com>
*
* 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/delay.h>
#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/pm.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-pb1x00/pb1000.h>
#include <asm/reboot.h>
#include <prom.h>
#include "../platform.h"
const char *get_system_type(void)
{
return "Alchemy Pb1000";
}
static void board_reset(char *c)
{
asm volatile ("jr %0" : : "r" (0xbfc00000));
}
static void board_power_off(void)
{
while (1)
asm volatile (
" .set mips32 \n"
" wait \n"
" .set mips0 \n");
}
void __init board_setup(void)
{
u32 pin_func, static_cfg0;
u32 sys_freqctrl, sys_clksrc;
u32 prid = read_c0_prid();
sys_freqctrl = 0;
sys_clksrc = 0;
/* Set AUX clock to 12 MHz * 8 = 96 MHz */
au_writel(8, SYS_AUXPLL);
alchemy_gpio1_input_enable();
udelay(100);
#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
/* Zero and disable FREQ2 */
sys_freqctrl = au_readl(SYS_FREQCTRL0);
sys_freqctrl &= ~0xFFF00000;
au_writel(sys_freqctrl, SYS_FREQCTRL0);
/* Zero and disable USBH/USBD clocks */
sys_clksrc = au_readl(SYS_CLKSRC);
sys_clksrc &= ~(SYS_CS_CUD | SYS_CS_DUD | SYS_CS_MUD_MASK |
SYS_CS_CUH | SYS_CS_DUH | SYS_CS_MUH_MASK);
au_writel(sys_clksrc, SYS_CLKSRC);
sys_freqctrl = au_readl(SYS_FREQCTRL0);
sys_freqctrl &= ~0xFFF00000;
sys_clksrc = au_readl(SYS_CLKSRC);
sys_clksrc &= ~(SYS_CS_CUD | SYS_CS_DUD | SYS_CS_MUD_MASK |
SYS_CS_CUH | SYS_CS_DUH | SYS_CS_MUH_MASK);
switch (prid & 0x000000FF) {
case 0x00: /* DA */
case 0x01: /* HA */
case 0x02: /* HB */
/* CPU core freq to 48 MHz to slow it way down... */
au_writel(4, SYS_CPUPLL);
/*
* Setup 48 MHz FREQ2 from CPUPLL for USB Host
* FRDIV2 = 3 -> div by 8 of 384 MHz -> 48 MHz
*/
sys_freqctrl |= (3 << SYS_FC_FRDIV2_BIT) | SYS_FC_FE2;
au_writel(sys_freqctrl, SYS_FREQCTRL0);
/* CPU core freq to 384 MHz */
au_writel(0x20, SYS_CPUPLL);
printk(KERN_INFO "Au1000: 48 MHz OHCI workaround enabled\n");
break;
default: /* HC and newer */
/* FREQ2 = aux / 2 = 48 MHz */
sys_freqctrl |= (0 << SYS_FC_FRDIV2_BIT) |
SYS_FC_FE2 | SYS_FC_FS2;
au_writel(sys_freqctrl, SYS_FREQCTRL0);
break;
}
/*
* Route 48 MHz FREQ2 into USB Host and/or Device
*/
sys_clksrc |= SYS_CS_MUX_FQ2 << SYS_CS_MUH_BIT;
au_writel(sys_clksrc, SYS_CLKSRC);
/* Configure pins GPIO[14:9] as GPIO */
pin_func = au_readl(SYS_PINFUNC) & ~(SYS_PF_UR3 | SYS_PF_USB);
/* 2nd USB port is USB host */
pin_func |= SYS_PF_USB;
au_writel(pin_func, SYS_PINFUNC);
alchemy_gpio_direction_input(11);
alchemy_gpio_direction_input(13);
alchemy_gpio_direction_output(4, 0);
alchemy_gpio_direction_output(5, 0);
#endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */
/* Make GPIO 15 an input (for interrupt line) */
pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_IRF;
/* We don't need I2S, so make it available for GPIO[31:29] */
pin_func |= SYS_PF_I2S;
au_writel(pin_func, SYS_PINFUNC);
alchemy_gpio_direction_input(15);
static_cfg0 = au_readl(MEM_STCFG0) & ~0xc00;
au_writel(static_cfg0, MEM_STCFG0);
/* configure RCE2* for LCD */
au_writel(0x00000004, MEM_STCFG2);
/* MEM_STTIME2 */
au_writel(0x09000000, MEM_STTIME2);
/* Set 32-bit base address decoding for RCE2* */
au_writel(0x10003ff0, MEM_STADDR2);
/*
* PCI CPLD setup
* Expand CE0 to cover PCI
*/
au_writel(0x11803e40, MEM_STADDR1);
/* Burst visibility on */
au_writel(au_readl(MEM_STCFG0) | 0x1000, MEM_STCFG0);
au_writel(0x83, MEM_STCFG1); /* ewait enabled, flash timing */
au_writel(0x33030a10, MEM_STTIME1); /* slower timing for FPGA */
/* Setup the static bus controller */
au_writel(0x00000002, MEM_STCFG3); /* type = PCMCIA */
au_writel(0x280E3D07, MEM_STTIME3); /* 250ns cycle time */
au_writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */
/*
* Enable Au1000 BCLK switching - note: sed1356 must not use
* its BCLK (Au1000 LCLK) for any timings
*/
switch (prid & 0x000000FF) {
case 0x00: /* DA */
case 0x01: /* HA */
case 0x02: /* HB */
break;
default: /* HC and newer */
/*
* Enable sys bus clock divider when IDLE state or no bus
* activity.
*/
au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL);
break;
}
pm_power_off = board_power_off;
_machine_halt = board_power_off;
_machine_restart = board_reset;
}
static int __init pb1000_init_irq(void)
{
irq_set_irq_type(AU1000_GPIO15_INT, IRQF_TRIGGER_LOW);
return 0;
}
arch_initcall(pb1000_init_irq);
static int __init pb1000_device_init(void)
{
return db1x_register_norflash(8 * 1024 * 1024, 4, 0);
}
device_initcall(pb1000_device_init);

View File

@@ -1,42 +1,37 @@
/*
* Copyright 2002, 2008 MontaVista Software Inc.
* Author: MontaVista Software, Inc. <source@mvista.com>
* Pb1100 board platform device registration
*
* 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.
* Copyright (C) 2009 Manuel Lauss
*
* 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.
* 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.
*
* 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.
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-db1x00/bcsr.h>
#include <prom.h>
#include "platform.h"
const char *get_system_type(void)
{
return "Alchemy Pb1100";
return "PB1100";
}
void __init board_setup(void)
@@ -115,13 +110,58 @@ void __init board_setup(void)
}
}
static int __init pb1100_init_irq(void)
/******************************************************************************/
static struct resource au1100_lcd_resources[] = {
[0] = {
.start = AU1100_LCD_PHYS_ADDR,
.end = AU1100_LCD_PHYS_ADDR + 0x800 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AU1100_LCD_INT,
.end = AU1100_LCD_INT,
.flags = IORESOURCE_IRQ,
}
};
static u64 au1100_lcd_dmamask = DMA_BIT_MASK(32);
static struct platform_device au1100_lcd_device = {
.name = "au1100-lcd",
.id = 0,
.dev = {
.dma_mask = &au1100_lcd_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
.num_resources = ARRAY_SIZE(au1100_lcd_resources),
.resource = au1100_lcd_resources,
};
static int __init pb1100_dev_init(void)
{
int swapped;
irq_set_irq_type(AU1100_GPIO9_INT, IRQF_TRIGGER_LOW); /* PCCD# */
irq_set_irq_type(AU1100_GPIO10_INT, IRQF_TRIGGER_LOW); /* PCSTSCHG# */
irq_set_irq_type(AU1100_GPIO11_INT, IRQF_TRIGGER_LOW); /* PCCard# */
irq_set_irq_type(AU1100_GPIO13_INT, IRQF_TRIGGER_LOW); /* DC_IRQ# */
/* PCMCIA. single socket, identical to Pb1500 */
db1x_register_pcmcia_socket(
AU1000_PCMCIA_ATTR_PHYS_ADDR,
AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
AU1000_PCMCIA_MEM_PHYS_ADDR,
AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
AU1000_PCMCIA_IO_PHYS_ADDR,
AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
AU1100_GPIO11_INT, AU1100_GPIO9_INT, /* card / insert */
/*AU1100_GPIO10_INT*/0, 0, 0); /* stschg / eject / id */
swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT;
db1x_register_norflash(64 * 1024 * 1024, 4, swapped);
platform_device_register(&au1100_lcd_device);
return 0;
}
arch_initcall(pb1100_init_irq);
device_initcall(pb1100_dev_init);

View File

@@ -1,8 +0,0 @@
#
# Copyright 2000, 2001, 2008 MontaVista Software Inc.
# Author: MontaVista Software, Inc. <source@mvista.com>
#
# Makefile for the Alchemy Semiconductor Pb1100 board.
#
obj-y := board_setup.o platform.o

View File

@@ -1,77 +0,0 @@
/*
* Pb1100 board platform device registration
*
* Copyright (C) 2009 Manuel Lauss
*
* 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 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/init.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-db1x00/bcsr.h>
#include "../platform.h"
static struct resource au1100_lcd_resources[] = {
[0] = {
.start = AU1100_LCD_PHYS_ADDR,
.end = AU1100_LCD_PHYS_ADDR + 0x800 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AU1100_LCD_INT,
.end = AU1100_LCD_INT,
.flags = IORESOURCE_IRQ,
}
};
static u64 au1100_lcd_dmamask = DMA_BIT_MASK(32);
static struct platform_device au1100_lcd_device = {
.name = "au1100-lcd",
.id = 0,
.dev = {
.dma_mask = &au1100_lcd_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
.num_resources = ARRAY_SIZE(au1100_lcd_resources),
.resource = au1100_lcd_resources,
};
static int __init pb1100_dev_init(void)
{
int swapped;
/* PCMCIA. single socket, identical to Pb1500 */
db1x_register_pcmcia_socket(
AU1000_PCMCIA_ATTR_PHYS_ADDR,
AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
AU1000_PCMCIA_MEM_PHYS_ADDR,
AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
AU1000_PCMCIA_IO_PHYS_ADDR,
AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
AU1100_GPIO11_INT, AU1100_GPIO9_INT, /* card / insert */
/*AU1100_GPIO10_INT*/0, 0, 0); /* stschg / eject / id */
swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT;
db1x_register_norflash(64 * 1024 * 1024, 4, swapped);
platform_device_register(&au1100_lcd_device);
return 0;
}
device_initcall(pb1100_dev_init);

View File

@@ -1,5 +0,0 @@
#
# Makefile for the Alchemy Semiconductor Pb1200/DBAu1200 boards.
#
obj-y := board_setup.o platform.o

View File

@@ -1,174 +0,0 @@
/*
*
* BRIEF MODULE DESCRIPTION
* Alchemy Pb1200/Db1200 board setup.
*
* 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/init.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-db1x00/bcsr.h>
#ifdef CONFIG_MIPS_PB1200
#include <asm/mach-pb1x00/pb1200.h>
#endif
#ifdef CONFIG_MIPS_DB1200
#include <asm/mach-db1x00/db1200.h>
#define PB1200_INT_BEGIN DB1200_INT_BEGIN
#define PB1200_INT_END DB1200_INT_END
#endif
#include <prom.h>
const char *get_system_type(void)
{
return "Alchemy Pb1200";
}
void __init board_setup(void)
{
printk(KERN_INFO "AMD Alchemy Pb1200 Board\n");
bcsr_init(PB1200_BCSR_PHYS_ADDR,
PB1200_BCSR_PHYS_ADDR + PB1200_BCSR_HEXLED_OFS);
#if 0
{
u32 pin_func;
/*
* Enable PSC1 SYNC for AC97. Normaly done in audio driver,
* but it is board specific code, so put it here.
*/
pin_func = au_readl(SYS_PINFUNC);
au_sync();
pin_func |= SYS_PF_MUST_BE_SET | SYS_PF_PSC1_S1;
au_writel(pin_func, SYS_PINFUNC);
au_writel(0, (u32)bcsr | 0x10); /* turn off PCMCIA power */
au_sync();
}
#endif
#if defined(CONFIG_I2C_AU1550)
{
u32 freq0, clksrc;
u32 pin_func;
/* Select SMBus in CPLD */
bcsr_mod(BCSR_RESETS, BCSR_RESETS_PSC0MUX, 0);
pin_func = au_readl(SYS_PINFUNC);
au_sync();
pin_func &= ~(SYS_PINFUNC_P0A | SYS_PINFUNC_P0B);
/* Set GPIOs correctly */
pin_func |= 2 << 17;
au_writel(pin_func, SYS_PINFUNC);
au_sync();
/* The I2C driver depends on 50 MHz clock */
freq0 = au_readl(SYS_FREQCTRL0);
au_sync();
freq0 &= ~(SYS_FC_FRDIV1_MASK | SYS_FC_FS1 | SYS_FC_FE1);
freq0 |= 3 << SYS_FC_FRDIV1_BIT;
/* 396 MHz / (3 + 1) * 2 == 49.5 MHz */
au_writel(freq0, SYS_FREQCTRL0);
au_sync();
freq0 |= SYS_FC_FE1;
au_writel(freq0, SYS_FREQCTRL0);
au_sync();
clksrc = au_readl(SYS_CLKSRC);
au_sync();
clksrc &= ~(SYS_CS_CE0 | SYS_CS_DE0 | SYS_CS_ME0_MASK);
/* Bit 22 is EXTCLK0 for PSC0 */
clksrc |= SYS_CS_MUX_FQ1 << SYS_CS_ME0_BIT;
au_writel(clksrc, SYS_CLKSRC);
au_sync();
}
#endif
/*
* The Pb1200 development board uses external MUX for PSC0 to
* support SMB/SPI. bcsr_resets bit 12: 0=SMB 1=SPI
*/
#ifdef CONFIG_I2C_AU1550
bcsr_mod(BCSR_RESETS, BCSR_RESETS_PSC0MUX, 0);
#endif
au_sync();
}
static int __init pb1200_init_irq(void)
{
/* We have a problem with CPLD rev 3. */
if (BCSR_WHOAMI_CPLD(bcsr_read(BCSR_WHOAMI)) <= 3) {
printk(KERN_ERR "WARNING!!!\n");
printk(KERN_ERR "WARNING!!!\n");
printk(KERN_ERR "WARNING!!!\n");
printk(KERN_ERR "WARNING!!!\n");
printk(KERN_ERR "WARNING!!!\n");
printk(KERN_ERR "WARNING!!!\n");
printk(KERN_ERR "Pb1200 must be at CPLD rev 4. Please have Pb1200\n");
printk(KERN_ERR "updated to latest revision. This software will\n");
printk(KERN_ERR "not work on anything less than CPLD rev 4.\n");
printk(KERN_ERR "WARNING!!!\n");
printk(KERN_ERR "WARNING!!!\n");
printk(KERN_ERR "WARNING!!!\n");
printk(KERN_ERR "WARNING!!!\n");
printk(KERN_ERR "WARNING!!!\n");
printk(KERN_ERR "WARNING!!!\n");
panic("Game over. Your score is 0.");
}
irq_set_irq_type(AU1200_GPIO7_INT, IRQF_TRIGGER_LOW);
bcsr_init_irq(PB1200_INT_BEGIN, PB1200_INT_END, AU1200_GPIO7_INT);
return 0;
}
arch_initcall(pb1200_init_irq);
int board_au1200fb_panel(void)
{
return (bcsr_read(BCSR_SWITCHES) >> 8) & 0x0f;
}
int board_au1200fb_panel_init(void)
{
/* Apply power */
bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD |
BCSR_BOARD_LCDBL);
/* printk(KERN_DEBUG "board_au1200fb_panel_init()\n"); */
return 0;
}
int board_au1200fb_panel_shutdown(void)
{
/* Remove power */
bcsr_mod(BCSR_BOARD, BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD |
BCSR_BOARD_LCDBL, 0);
/* printk(KERN_DEBUG "board_au1200fb_panel_shutdown()\n"); */
return 0;
}

View File

@@ -1,339 +0,0 @@
/*
* Pb1200/DBAu1200 board platform device registration
*
* Copyright (C) 2008 MontaVista Software Inc. <source@mvista.com>
*
* 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 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/dma-mapping.h>
#include <linux/init.h>
#include <linux/leds.h>
#include <linux/platform_device.h>
#include <linux/smc91x.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/au1100_mmc.h>
#include <asm/mach-au1x00/au1xxx_dbdma.h>
#include <asm/mach-db1x00/bcsr.h>
#include <asm/mach-pb1x00/pb1200.h>
#include "../platform.h"
static int mmc_activity;
static void pb1200mmc0_set_power(void *mmc_host, int state)
{
if (state)
bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_SD0PWR);
else
bcsr_mod(BCSR_BOARD, BCSR_BOARD_SD0PWR, 0);
msleep(1);
}
static int pb1200mmc0_card_readonly(void *mmc_host)
{
return (bcsr_read(BCSR_STATUS) & BCSR_STATUS_SD0WP) ? 1 : 0;
}
static int pb1200mmc0_card_inserted(void *mmc_host)
{
return (bcsr_read(BCSR_SIGSTAT) & BCSR_INT_SD0INSERT) ? 1 : 0;
}
static void pb1200_mmcled_set(struct led_classdev *led,
enum led_brightness brightness)
{
if (brightness != LED_OFF) {
if (++mmc_activity == 1)
bcsr_mod(BCSR_LEDS, BCSR_LEDS_LED0, 0);
} else {
if (--mmc_activity == 0)
bcsr_mod(BCSR_LEDS, 0, BCSR_LEDS_LED0);
}
}
static struct led_classdev pb1200mmc_led = {
.brightness_set = pb1200_mmcled_set,
};
static void pb1200mmc1_set_power(void *mmc_host, int state)
{
if (state)
bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_SD1PWR);
else
bcsr_mod(BCSR_BOARD, BCSR_BOARD_SD1PWR, 0);
msleep(1);
}
static int pb1200mmc1_card_readonly(void *mmc_host)
{
return (bcsr_read(BCSR_STATUS) & BCSR_STATUS_SD1WP) ? 1 : 0;
}
static int pb1200mmc1_card_inserted(void *mmc_host)
{
return (bcsr_read(BCSR_SIGSTAT) & BCSR_INT_SD1INSERT) ? 1 : 0;
}
static struct au1xmmc_platform_data pb1200mmc_platdata[2] = {
[0] = {
.set_power = pb1200mmc0_set_power,
.card_inserted = pb1200mmc0_card_inserted,
.card_readonly = pb1200mmc0_card_readonly,
.cd_setup = NULL, /* use poll-timer in driver */
.led = &pb1200mmc_led,
},
[1] = {
.set_power = pb1200mmc1_set_power,
.card_inserted = pb1200mmc1_card_inserted,
.card_readonly = pb1200mmc1_card_readonly,
.cd_setup = NULL, /* use poll-timer in driver */
.led = &pb1200mmc_led,
},
};
static u64 au1xxx_mmc_dmamask = DMA_BIT_MASK(32);
static struct resource au1200_mmc0_res[] = {
[0] = {
.start = AU1100_SD0_PHYS_ADDR,
.end = AU1100_SD0_PHYS_ADDR + 0xfff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AU1200_SD_INT,
.end = AU1200_SD_INT,
.flags = IORESOURCE_IRQ,
},
[2] = {
.start = AU1200_DSCR_CMD0_SDMS_TX0,
.end = AU1200_DSCR_CMD0_SDMS_TX0,
.flags = IORESOURCE_DMA,
},
[3] = {
.start = AU1200_DSCR_CMD0_SDMS_RX0,
.end = AU1200_DSCR_CMD0_SDMS_RX0,
.flags = IORESOURCE_DMA,
}
};
static struct platform_device pb1200_mmc0_dev = {
.name = "au1xxx-mmc",
.id = 0,
.dev = {
.dma_mask = &au1xxx_mmc_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = &pb1200mmc_platdata[0],
},
.num_resources = ARRAY_SIZE(au1200_mmc0_res),
.resource = au1200_mmc0_res,
};
static struct resource au1200_mmc1_res[] = {
[0] = {
.start = AU1100_SD1_PHYS_ADDR,
.end = AU1100_SD1_PHYS_ADDR + 0xfff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AU1200_SD_INT,
.end = AU1200_SD_INT,
.flags = IORESOURCE_IRQ,
},
[2] = {
.start = AU1200_DSCR_CMD0_SDMS_TX1,
.end = AU1200_DSCR_CMD0_SDMS_TX1,
.flags = IORESOURCE_DMA,
},
[3] = {
.start = AU1200_DSCR_CMD0_SDMS_RX1,
.end = AU1200_DSCR_CMD0_SDMS_RX1,
.flags = IORESOURCE_DMA,
}
};
static struct platform_device pb1200_mmc1_dev = {
.name = "au1xxx-mmc",
.id = 1,
.dev = {
.dma_mask = &au1xxx_mmc_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = &pb1200mmc_platdata[1],
},
.num_resources = ARRAY_SIZE(au1200_mmc1_res),
.resource = au1200_mmc1_res,
};
static struct resource ide_resources[] = {
[0] = {
.start = IDE_PHYS_ADDR,
.end = IDE_PHYS_ADDR + IDE_PHYS_LEN - 1,
.flags = IORESOURCE_MEM
},
[1] = {
.start = IDE_INT,
.end = IDE_INT,
.flags = IORESOURCE_IRQ
},
[2] = {
.start = AU1200_DSCR_CMD0_DMA_REQ1,
.end = AU1200_DSCR_CMD0_DMA_REQ1,
.flags = IORESOURCE_DMA,
},
};
static u64 ide_dmamask = DMA_BIT_MASK(32);
static struct platform_device ide_device = {
.name = "au1200-ide",
.id = 0,
.dev = {
.dma_mask = &ide_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
.num_resources = ARRAY_SIZE(ide_resources),
.resource = ide_resources
};
static struct smc91x_platdata smc_data = {
.flags = SMC91X_NOWAIT | SMC91X_USE_16BIT,
.leda = RPC_LED_100_10,
.ledb = RPC_LED_TX_RX,
};
static struct resource smc91c111_resources[] = {
[0] = {
.name = "smc91x-regs",
.start = SMC91C111_PHYS_ADDR,
.end = SMC91C111_PHYS_ADDR + 0xf,
.flags = IORESOURCE_MEM
},
[1] = {
.start = SMC91C111_INT,
.end = SMC91C111_INT,
.flags = IORESOURCE_IRQ
},
};
static struct platform_device smc91c111_device = {
.dev = {
.platform_data = &smc_data,
},
.name = "smc91x",
.id = -1,
.num_resources = ARRAY_SIZE(smc91c111_resources),
.resource = smc91c111_resources
};
static struct resource au1200_psc0_res[] = {
[0] = {
.start = AU1550_PSC0_PHYS_ADDR,
.end = AU1550_PSC0_PHYS_ADDR + 0xfff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AU1200_PSC0_INT,
.end = AU1200_PSC0_INT,
.flags = IORESOURCE_IRQ,
},
[2] = {
.start = AU1200_DSCR_CMD0_PSC0_TX,
.end = AU1200_DSCR_CMD0_PSC0_TX,
.flags = IORESOURCE_DMA,
},
[3] = {
.start = AU1200_DSCR_CMD0_PSC0_RX,
.end = AU1200_DSCR_CMD0_PSC0_RX,
.flags = IORESOURCE_DMA,
},
};
static struct platform_device pb1200_i2c_dev = {
.name = "au1xpsc_smbus",
.id = 0, /* bus number */
.num_resources = ARRAY_SIZE(au1200_psc0_res),
.resource = au1200_psc0_res,
};
static struct resource au1200_lcd_res[] = {
[0] = {
.start = AU1200_LCD_PHYS_ADDR,
.end = AU1200_LCD_PHYS_ADDR + 0x800 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AU1200_LCD_INT,
.end = AU1200_LCD_INT,
.flags = IORESOURCE_IRQ,
}
};
static u64 au1200_lcd_dmamask = DMA_BIT_MASK(32);
static struct platform_device au1200_lcd_dev = {
.name = "au1200-lcd",
.id = 0,
.dev = {
.dma_mask = &au1200_lcd_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
.num_resources = ARRAY_SIZE(au1200_lcd_res),
.resource = au1200_lcd_res,
};
static struct platform_device *board_platform_devices[] __initdata = {
&ide_device,
&smc91c111_device,
&pb1200_i2c_dev,
&pb1200_mmc0_dev,
&pb1200_mmc1_dev,
&au1200_lcd_dev,
};
static int __init board_register_devices(void)
{
int swapped;
db1x_register_pcmcia_socket(
AU1000_PCMCIA_ATTR_PHYS_ADDR,
AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
AU1000_PCMCIA_MEM_PHYS_ADDR,
AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
AU1000_PCMCIA_IO_PHYS_ADDR,
AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
PB1200_PC0_INT, PB1200_PC0_INSERT_INT,
/*PB1200_PC0_STSCHG_INT*/0, PB1200_PC0_EJECT_INT, 0);
db1x_register_pcmcia_socket(
AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x008000000,
AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x008400000 - 1,
AU1000_PCMCIA_MEM_PHYS_ADDR + 0x008000000,
AU1000_PCMCIA_MEM_PHYS_ADDR + 0x008400000 - 1,
AU1000_PCMCIA_IO_PHYS_ADDR + 0x008000000,
AU1000_PCMCIA_IO_PHYS_ADDR + 0x008010000 - 1,
PB1200_PC1_INT, PB1200_PC1_INSERT_INT,
/*PB1200_PC1_STSCHG_INT*/0, PB1200_PC1_EJECT_INT, 1);
swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1200_SWAPBOOT;
db1x_register_norflash(128 * 1024 * 1024, 2, swapped);
return platform_add_devices(board_platform_devices,
ARRAY_SIZE(board_platform_devices));
}
device_initcall(board_register_devices);

View File

@@ -1,41 +1,37 @@
/*
* Copyright 2000, 2008 MontaVista Software Inc.
* Author: MontaVista Software, Inc. <source@mvista.com>
* Pb1500 board support.
*
* 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.
* Copyright (C) 2009 Manuel Lauss
*
* 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.
* 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.
*
* 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.
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-db1x00/bcsr.h>
#include <prom.h>
#include "platform.h"
const char *get_system_type(void)
{
return "Alchemy Pb1500";
return "PB1500";
}
void __init board_setup(void)
@@ -123,17 +119,80 @@ void __init board_setup(void)
}
}
static int __init pb1500_init_irq(void)
/******************************************************************************/
static int pb1500_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin)
{
irq_set_irq_type(AU1500_GPIO9_INT, IRQF_TRIGGER_LOW); /* CD0# */
irq_set_irq_type(AU1500_GPIO10_INT, IRQF_TRIGGER_LOW); /* CARD0 */
irq_set_irq_type(AU1500_GPIO11_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
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;
}
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 pb1500_pci_pd = {
.board_map_irq = pb1500_map_pci_irq,
.pci_cfg_set = PCI_CONFIG_AEN | PCI_CONFIG_R2H | PCI_CONFIG_R1H |
PCI_CONFIG_CH |
#if defined(__MIPSEB__)
PCI_CONFIG_SIC_HWA_DAT | PCI_CONFIG_SM,
#else
0,
#endif
};
static struct platform_device pb1500_pci_host = {
.dev.platform_data = &pb1500_pci_pd,
.name = "alchemy-pci",
.id = 0,
.num_resources = ARRAY_SIZE(alchemy_pci_host_res),
.resource = alchemy_pci_host_res,
};
static int __init pb1500_dev_init(void)
{
int swapped;
irq_set_irq_type(AU1500_GPIO9_INT, IRQF_TRIGGER_LOW); /* CD0# */
irq_set_irq_type(AU1500_GPIO10_INT, IRQF_TRIGGER_LOW); /* CARD0 */
irq_set_irq_type(AU1500_GPIO11_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
irq_set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH);
irq_set_irq_type(AU1500_GPIO201_INT, IRQF_TRIGGER_LOW);
irq_set_irq_type(AU1500_GPIO202_INT, IRQF_TRIGGER_LOW);
irq_set_irq_type(AU1500_GPIO203_INT, IRQF_TRIGGER_LOW);
irq_set_irq_type(AU1500_GPIO205_INT, IRQF_TRIGGER_LOW);
/* PCMCIA. single socket, identical to Pb1100 */
db1x_register_pcmcia_socket(
AU1000_PCMCIA_ATTR_PHYS_ADDR,
AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
AU1000_PCMCIA_MEM_PHYS_ADDR,
AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
AU1000_PCMCIA_IO_PHYS_ADDR,
AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
AU1500_GPIO11_INT, AU1500_GPIO9_INT, /* card / insert */
/*AU1500_GPIO10_INT*/0, 0, 0); /* stschg / eject / id */
swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT;
db1x_register_norflash(64 * 1024 * 1024, 4, swapped);
platform_device_register(&pb1500_pci_host);
return 0;
}
arch_initcall(pb1500_init_irq);
arch_initcall(pb1500_dev_init);

View File

@@ -1,8 +0,0 @@
#
# Copyright 2000, 2001, 2008 MontaVista Software Inc.
# Author: MontaVista Software, Inc. <source@mvista.com>
#
# Makefile for the Alchemy Semiconductor Pb1500 board.
#
obj-y := board_setup.o platform.o

View File

@@ -1,94 +0,0 @@
/*
* Pb1500 board platform device registration
*
* Copyright (C) 2009 Manuel Lauss
*
* 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 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/dma-mapping.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-db1x00/bcsr.h>
#include "../platform.h"
static int pb1500_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;
}
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 pb1500_pci_pd = {
.board_map_irq = pb1500_map_pci_irq,
.pci_cfg_set = PCI_CONFIG_AEN | PCI_CONFIG_R2H | PCI_CONFIG_R1H |
PCI_CONFIG_CH |
#if defined(__MIPSEB__)
PCI_CONFIG_SIC_HWA_DAT | PCI_CONFIG_SM,
#else
0,
#endif
};
static struct platform_device pb1500_pci_host = {
.dev.platform_data = &pb1500_pci_pd,
.name = "alchemy-pci",
.id = 0,
.num_resources = ARRAY_SIZE(alchemy_pci_host_res),
.resource = alchemy_pci_host_res,
};
static int __init pb1500_dev_init(void)
{
int swapped;
/* PCMCIA. single socket, identical to Pb1100 */
db1x_register_pcmcia_socket(
AU1000_PCMCIA_ATTR_PHYS_ADDR,
AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
AU1000_PCMCIA_MEM_PHYS_ADDR,
AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
AU1000_PCMCIA_IO_PHYS_ADDR,
AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
AU1500_GPIO11_INT, AU1500_GPIO9_INT, /* card / insert */
/*AU1500_GPIO10_INT*/0, 0, 0); /* stschg / eject / id */
swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT;
db1x_register_norflash(64 * 1024 * 1024, 4, swapped);
platform_device_register(&pb1500_pci_host);
return 0;
}
arch_initcall(pb1500_dev_init);

View File

@@ -1,7 +1,7 @@
/*
* Pb1550 board platform device registration
* Pb1550 board support.
*
* Copyright (C) 2009 Manuel Lauss
* Copyright (C) 2009-2011 Manuel Lauss
*
* 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
@@ -20,13 +20,44 @@
#include <linux/dma-mapping.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/au1xxx_dbdma.h>
#include <asm/mach-pb1x00/pb1550.h>
#include <asm/mach-au1x00/au1550nd.h>
#include <asm/mach-au1x00/gpio.h>
#include <asm/mach-db1x00/bcsr.h>
#include "platform.h"
#include "../platform.h"
const char *get_system_type(void)
{
return "PB1550";
}
void __init board_setup(void)
{
u32 pin_func;
bcsr_init(PB1550_BCSR_PHYS_ADDR,
PB1550_BCSR_PHYS_ADDR + PB1550_BCSR_HEXLED_OFS);
alchemy_gpio2_enable();
/*
* Enable PSC1 SYNC for AC'97. Normaly done in audio driver,
* but it is board specific code, so put it here.
*/
pin_func = au_readl(SYS_PINFUNC);
au_sync();
pin_func |= SYS_PF_MUST_BE_SET | SYS_PF_PSC1_S1;
au_writel(pin_func, SYS_PINFUNC);
bcsr_write(BCSR_PCMCIA, 0); /* turn off PCMCIA power */
printk(KERN_INFO "AMD Alchemy Pb1550 Board\n");
}
/******************************************************************************/
static int pb1550_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin)
{
@@ -101,10 +132,79 @@ static struct platform_device pb1550_i2c_dev = {
.resource = au1550_psc2_res,
};
static struct mtd_partition pb1550_nand_parts[] = {
[0] = {
.name = "NAND FS 0",
.offset = 0,
.size = 8 * 1024 * 1024,
},
[1] = {
.name = "NAND FS 1",
.offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL,
},
};
static struct au1550nd_platdata pb1550_nand_pd = {
.parts = pb1550_nand_parts,
.num_parts = ARRAY_SIZE(pb1550_nand_parts),
.devwidth = 0, /* x8 NAND default, needs fixing up */
};
static struct resource pb1550_nand_res[] = {
[0] = {
.start = 0x20000000,
.end = 0x20000fff,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device pb1550_nand_dev = {
.name = "au1550-nand",
.id = -1,
.resource = pb1550_nand_res,
.num_resources = ARRAY_SIZE(pb1550_nand_res),
.dev = {
.platform_data = &pb1550_nand_pd,
},
};
static void __init pb1550_nand_setup(void)
{
int boot_swapboot = (au_readl(MEM_STSTAT) & (0x7 << 1)) |
((bcsr_read(BCSR_STATUS) >> 6) & 0x1);
switch (boot_swapboot) {
case 0:
case 2:
case 8:
case 0xC:
case 0xD:
/* x16 NAND Flash */
pb1550_nand_pd.devwidth = 1;
/* fallthrough */
case 1:
case 9:
case 3:
case 0xE:
case 0xF:
/* x8 NAND, already set up */
platform_device_register(&pb1550_nand_dev);
}
}
static int __init pb1550_dev_init(void)
{
int swapped;
irq_set_irq_type(AU1550_GPIO0_INT, IRQF_TRIGGER_LOW);
irq_set_irq_type(AU1550_GPIO1_INT, IRQF_TRIGGER_LOW);
irq_set_irq_type(AU1550_GPIO201_205_INT, IRQF_TRIGGER_HIGH);
/* enable both PCMCIA card irqs in the shared line */
alchemy_gpio2_enable_int(201);
alchemy_gpio2_enable_int(202);
/* Pb1550, like all others, also has statuschange irqs; however they're
* wired up on one of the Au1550's shared GPIO201_205 line, which also
* services the PCMCIA card interrupts. So we ignore statuschange and
@@ -130,6 +230,10 @@ static int __init pb1550_dev_init(void)
AU1000_PCMCIA_IO_PHYS_ADDR + 0x008010000 - 1,
AU1550_GPIO201_205_INT, AU1550_GPIO1_INT, 0, 0, 1);
/* NAND setup */
gpio_direction_input(206); /* GPIO206 high */
pb1550_nand_setup();
swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_PB1550_SWAPBOOT;
db1x_register_norflash(128 * 1024 * 1024, 4, swapped);
platform_device_register(&pb1550_pci_host);

View File

@@ -1,8 +0,0 @@
#
# Copyright 2000, 2008 MontaVista Software Inc.
# Author: MontaVista Software, Inc. <source@mvista.com>
#
# Makefile for the Alchemy Semiconductor Pb1550 board.
#
obj-y := board_setup.o platform.o

View File

@@ -1,80 +0,0 @@
/*
*
* BRIEF MODULE DESCRIPTION
* Alchemy Pb1550 board setup.
*
* Copyright 2000, 2008 MontaVista Software Inc.
* Author: MontaVista Software, Inc. <source@mvista.com>
*
* 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/init.h>
#include <linux/interrupt.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-pb1x00/pb1550.h>
#include <asm/mach-db1x00/bcsr.h>
#include <asm/mach-au1x00/gpio.h>
#include <prom.h>
const char *get_system_type(void)
{
return "Alchemy Pb1550";
}
void __init board_setup(void)
{
u32 pin_func;
bcsr_init(PB1550_BCSR_PHYS_ADDR,
PB1550_BCSR_PHYS_ADDR + PB1550_BCSR_HEXLED_OFS);
alchemy_gpio2_enable();
/*
* Enable PSC1 SYNC for AC'97. Normaly done in audio driver,
* but it is board specific code, so put it here.
*/
pin_func = au_readl(SYS_PINFUNC);
au_sync();
pin_func |= SYS_PF_MUST_BE_SET | SYS_PF_PSC1_S1;
au_writel(pin_func, SYS_PINFUNC);
bcsr_write(BCSR_PCMCIA, 0); /* turn off PCMCIA power */
printk(KERN_INFO "AMD Alchemy Pb1550 Board\n");
}
static int __init pb1550_init_irq(void)
{
irq_set_irq_type(AU1550_GPIO0_INT, IRQF_TRIGGER_LOW);
irq_set_irq_type(AU1550_GPIO1_INT, IRQF_TRIGGER_LOW);
irq_set_irq_type(AU1550_GPIO201_205_INT, IRQF_TRIGGER_HIGH);
/* enable both PCMCIA card irqs in the shared line */
alchemy_gpio2_enable_int(201);
alchemy_gpio2_enable_int(202);
return 0;
}
arch_initcall(pb1550_init_irq);

View File

@@ -13,6 +13,13 @@
#include <asm/reboot.h>
#include <asm/mach-db1x00/bcsr.h>
static struct platform_device db1x00_rtc_dev = {
.name = "rtc-au1xxx",
.id = -1,
};
static void db1x_power_off(void)
{
bcsr_write(BCSR_RESETS, 0);
@@ -25,7 +32,7 @@ static void db1x_reset(char *c)
bcsr_write(BCSR_SYSTEM, 0);
}
static int __init db1x_poweroff_setup(void)
static int __init db1x_late_setup(void)
{
if (!pm_power_off)
pm_power_off = db1x_power_off;
@@ -34,9 +41,11 @@ static int __init db1x_poweroff_setup(void)
if (!_machine_restart)
_machine_restart = db1x_reset;
platform_device_register(&db1x00_rtc_dev);
return 0;
}
late_initcall(db1x_poweroff_setup);
device_initcall(db1x_late_setup);
/* register a pcmcia socket */
int __init db1x_register_pcmcia_socket(phys_addr_t pcmcia_attr_start,

View File

@@ -33,10 +33,9 @@
#include <asm/mach-au1x00/au1000.h>
#include <prom.h>
#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_DB1000) || \
defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_DB1100) || \
defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_DB1500) || \
defined(CONFIG_MIPS_BOSPORUS) || defined(CONFIG_MIPS_MIRAGE)
#if defined(CONFIG_MIPS_DB1000) || \
defined(CONFIG_MIPS_PB1100) || \
defined(CONFIG_MIPS_PB1500)
#define ALCHEMY_BOARD_DEFAULT_MEMSIZE 0x04000000
#else /* Au1550/Au1200-based develboards */
@@ -62,5 +61,9 @@ void __init prom_init(void)
void prom_putchar(unsigned char c)
{
#ifdef CONFIG_MIPS_DB1300
alchemy_uart_putchar(AU1300_UART2_PHYS_ADDR, c);
#else
alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
#endif
}

View File

@@ -1,8 +0,0 @@
#
# Copyright 2003 MontaVista Software Inc.
# Author: MontaVista Software, Inc. <source@mvista.com>
#
# Makefile for Trapeze ITS GPR board.
#
obj-y += board_setup.o init.o platform.o

View File

@@ -1,75 +0,0 @@
/*
* Copyright 2010 Wolfgang Grandegger <wg@denx.de>
*
* Copyright 2000-2003, 2008 MontaVista Software Inc.
* Author: MontaVista Software, Inc. <source@mvista.com>
*
* 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/delay.h>
#include <linux/pm.h>
#include <asm/reboot.h>
#include <asm/mach-au1x00/au1000.h>
#include <prom.h>
static void gpr_reset(char *c)
{
/* switch System-LED to orange (red# and green# on) */
alchemy_gpio_direction_output(4, 0);
alchemy_gpio_direction_output(5, 0);
/* trigger watchdog to reset board in 200ms */
printk(KERN_EMERG "Triggering watchdog soft reset...\n");
raw_local_irq_disable();
alchemy_gpio_direction_output(1, 0);
udelay(1);
alchemy_gpio_set_value(1, 1);
while (1)
cpu_wait();
}
static void gpr_power_off(void)
{
while (1)
cpu_wait();
}
void __init board_setup(void)
{
printk(KERN_INFO "Trapeze ITS GPR board\n");
pm_power_off = gpr_power_off;
_machine_halt = gpr_power_off;
_machine_restart = gpr_reset;
/* Enable UART1/3 */
alchemy_uart_enable(AU1000_UART3_PHYS_ADDR);
alchemy_uart_enable(AU1000_UART1_PHYS_ADDR);
/* Take away Reset of UMTS-card */
alchemy_gpio_direction_output(215, 1);
}

View File

@@ -1,63 +0,0 @@
/*
* Copyright 2010 Wolfgang Grandegger <wg@denx.de>
*
* Copyright 2003, 2008 MontaVista Software Inc.
* Author: MontaVista Software, Inc. <source@mvista.com>
*
* 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/init.h>
#include <linux/kernel.h>
#include <asm/bootinfo.h>
#include <asm/mach-au1x00/au1000.h>
#include <prom.h>
const char *get_system_type(void)
{
return "GPR";
}
void __init prom_init(void)
{
unsigned char *memsize_str;
unsigned long memsize;
prom_argc = fw_arg0;
prom_argv = (char **)fw_arg1;
prom_envp = (char **)fw_arg2;
prom_init_cmdline();
memsize_str = prom_getenv("memsize");
if (!memsize_str)
memsize = 0x04000000;
else
strict_strtoul(memsize_str, 0, &memsize);
add_memory_region(0, memsize, BOOT_MEM_RAM);
}
void prom_putchar(unsigned char c)
{
alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
}

View File

@@ -1,9 +0,0 @@
#
# Copyright 2003 MontaVista Software Inc.
# Author: MontaVista Software, Inc. <source@mvista.com>
# Bruno Randolf <bruno.randolf@4g-systems.biz>
#
# Makefile for 4G Systems MTX-1 board.
#
obj-y += init.o board_setup.o platform.o

View File

@@ -1,94 +0,0 @@
/*
*
* 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>
static void mtx1_reset(char *c)
{
/* Jump to the reset vector */
__asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
}
static void mtx1_power_off(void)
{
while (1)
asm volatile (
" .set mips32 \n"
" wait \n"
" .set mips0 \n");
}
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) */
/* Initialize sys_pinfunc */
au_writel(SYS_PF_NI2, SYS_PINFUNC);
/* Initialize GPIO */
au_writel(~0, KSEG1ADDR(AU1000_SYS_PHYS_ADDR) + 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");
}
static int __init mtx1_init_irq(void)
{
irq_set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH);
irq_set_irq_type(AU1500_GPIO201_INT, IRQF_TRIGGER_LOW);
irq_set_irq_type(AU1500_GPIO202_INT, IRQF_TRIGGER_LOW);
irq_set_irq_type(AU1500_GPIO203_INT, IRQF_TRIGGER_LOW);
irq_set_irq_type(AU1500_GPIO205_INT, IRQF_TRIGGER_LOW);
return 0;
}
arch_initcall(mtx1_init_irq);

View File

@@ -1,66 +0,0 @@
/*
*
* 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/kernel.h>
#include <linux/init.h>
#include <asm/bootinfo.h>
#include <asm/mach-au1x00/au1000.h>
#include <prom.h>
const char *get_system_type(void)
{
return "MTX-1";
}
void __init prom_init(void)
{
unsigned char *memsize_str;
unsigned long memsize;
prom_argc = fw_arg0;
prom_argv = (char **)fw_arg1;
prom_envp = (char **)fw_arg2;
prom_init_cmdline();
memsize_str = prom_getenv("memsize");
if (!memsize_str)
memsize = 0x04000000;
else
strict_strtoul(memsize_str, 0, &memsize);
add_memory_region(0, memsize, BOOT_MEM_RAM);
}
void prom_putchar(unsigned char c)
{
alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
}

View File

@@ -1,8 +0,0 @@
#
# Copyright 2003 MontaVista Software Inc.
# Author: MontaVista Software, Inc. <source@mvista.com>
#
# Makefile for MyCable XXS1500 board.
#
obj-y += init.o board_setup.o platform.o

View File

@@ -1,93 +0,0 @@
/*
* Copyright 2000-2003, 2008 MontaVista Software Inc.
* Author: MontaVista Software, Inc. <source@mvista.com>
*
* 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/delay.h>
#include <linux/pm.h>
#include <asm/reboot.h>
#include <asm/mach-au1x00/au1000.h>
#include <prom.h>
static void xxs1500_reset(char *c)
{
/* Jump to the reset vector */
__asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
}
static void xxs1500_power_off(void)
{
while (1)
asm volatile (
" .set mips32 \n"
" wait \n"
" .set mips0 \n");
}
void __init board_setup(void)
{
u32 pin_func;
pm_power_off = xxs1500_power_off;
_machine_halt = xxs1500_power_off;
_machine_restart = xxs1500_reset;
alchemy_gpio1_input_enable();
alchemy_gpio2_enable();
/* Set multiple use pins (UART3/GPIO) to UART (it's used as UART too) */
pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_UR3;
pin_func |= SYS_PF_UR3;
au_writel(pin_func, SYS_PINFUNC);
/* Enable UART */
alchemy_uart_enable(AU1000_UART3_PHYS_ADDR);
/* Enable DTR (MCR bit 0) = USB power up */
__raw_writel(1, (void __iomem *)KSEG1ADDR(AU1000_UART3_PHYS_ADDR + 0x18));
wmb();
}
static int __init xxs1500_init_irq(void)
{
irq_set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH);
irq_set_irq_type(AU1500_GPIO201_INT, IRQF_TRIGGER_LOW);
irq_set_irq_type(AU1500_GPIO202_INT, IRQF_TRIGGER_LOW);
irq_set_irq_type(AU1500_GPIO203_INT, IRQF_TRIGGER_LOW);
irq_set_irq_type(AU1500_GPIO205_INT, IRQF_TRIGGER_LOW);
irq_set_irq_type(AU1500_GPIO207_INT, IRQF_TRIGGER_LOW);
irq_set_irq_type(AU1500_GPIO0_INT, IRQF_TRIGGER_LOW);
irq_set_irq_type(AU1500_GPIO1_INT, IRQF_TRIGGER_LOW);
irq_set_irq_type(AU1500_GPIO2_INT, IRQF_TRIGGER_LOW);
irq_set_irq_type(AU1500_GPIO3_INT, IRQF_TRIGGER_LOW);
irq_set_irq_type(AU1500_GPIO4_INT, IRQF_TRIGGER_LOW); /* CF irq */
irq_set_irq_type(AU1500_GPIO5_INT, IRQF_TRIGGER_LOW);
return 0;
}
arch_initcall(xxs1500_init_irq);

View File

@@ -1,63 +0,0 @@
/*
* BRIEF MODULE DESCRIPTION
* XXS1500 board setup
*
* Copyright 2003, 2008 MontaVista Software Inc.
* Author: MontaVista Software, Inc. <source@mvista.com>
*
* 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/init.h>
#include <linux/kernel.h>
#include <asm/bootinfo.h>
#include <asm/mach-au1x00/au1000.h>
#include <prom.h>
const char *get_system_type(void)
{
return "XXS1500";
}
void __init prom_init(void)
{
unsigned char *memsize_str;
unsigned long memsize;
prom_argc = fw_arg0;
prom_argv = (char **)fw_arg1;
prom_envp = (char **)fw_arg2;
prom_init_cmdline();
memsize_str = prom_getenv("memsize");
if (!memsize_str || strict_strtoul(memsize_str, 0, &memsize))
memsize = 0x04000000;
add_memory_region(0, memsize, BOOT_MEM_RAM);
}
void prom_putchar(unsigned char c)
{
alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
}

View File

@@ -1,63 +0,0 @@
/*
* XXS1500 board platform device registration
*
* Copyright (C) 2009 Manuel Lauss
*
* 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 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/init.h>
#include <linux/platform_device.h>
#include <asm/mach-au1x00/au1000.h>
static struct resource xxs1500_pcmcia_res[] = {
{
.name = "pcmcia-io",
.flags = IORESOURCE_MEM,
.start = AU1000_PCMCIA_IO_PHYS_ADDR,
.end = AU1000_PCMCIA_IO_PHYS_ADDR + 0x000400000 - 1,
},
{
.name = "pcmcia-attr",
.flags = IORESOURCE_MEM,
.start = AU1000_PCMCIA_ATTR_PHYS_ADDR,
.end = AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
},
{
.name = "pcmcia-mem",
.flags = IORESOURCE_MEM,
.start = AU1000_PCMCIA_MEM_PHYS_ADDR,
.end = AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
},
};
static struct platform_device xxs1500_pcmcia_dev = {
.name = "xxs1500_pcmcia",
.id = -1,
.num_resources = ARRAY_SIZE(xxs1500_pcmcia_res),
.resource = xxs1500_pcmcia_res,
};
static struct platform_device *xxs1500_devs[] __initdata = {
&xxs1500_pcmcia_dev,
};
static int __init xxs1500_dev_init(void)
{
return platform_add_devices(xxs1500_devs,
ARRAY_SIZE(xxs1500_devs));
}
device_initcall(xxs1500_dev_init);