Commit f1dd6ad5 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus

* 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus: (141 commits)
  MIPS: Alchemy: defconfig updates
  MIPS: Alchemy: Fix Au1100 ethernet build failure
  MIPS: Alchemy: Repair db1500/bosporus builds
  MIPS: ARC: Cleanup unused definitions from sgialib.h
  MIPS: Cobalt: convert legacy port addresses to GT-64111 bus addresses
  MIPS: Alchemy: use 36bit addresses for PCMCIA resources.
  MIPS: Cobalt: Fix theoretical port aliasing issue
  MIPS: Use ALIGN(x, bytes) instead of __ALIGN_MASK(x, bytes - 1)
  MIPS: Crazy spinlock speed test.
  MIPS: Optimize spinlocks.
  MIPS: Alchemy: devboard PM needs to save CPLD registers.
  MIPS: PowerTV: Eliminate duplicate opcode definition macros
  MIPS: Lemote 2F: Move printks out of port_access_lock.
  MIPS: PNX833x: Convert IRQ controller locks to raw spinlocks.
  MIPS: Octeon: Replace spinlock with raw_spinlocks in dma-octeon.c.
  MIPS: Octeon: Replace rwlocks in irq_chip handlers with raw_spinlocks.
  MIPS: Octeon: Convert octeon_irq_msi_lock to raw spinlock.
  MIPS: Loongson: Remove pointless sample_lock from oprofile code.
  MIPS: SNI: Convert sni_rm200_i8259A_lock to raw spinlock.
  MIPS: i8259: Convert IRQ controller lock to raw spinlock.
  ...
parents 8d37a371 e10b234b
......@@ -41,7 +41,7 @@ config AR7
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_SUPPORTS_ZBOOT_UART16550
select GENERIC_GPIO
select ARCH_REQUIRE_GPIOLIB
select GCD
select VLYNQ
help
......@@ -180,7 +180,7 @@ config LASAT
config MACH_LOONGSON
bool "Loongson family of machines"
select SYS_SUPPORTS_ZBOOT_UART16550
select SYS_SUPPORTS_ZBOOT
help
This enables the support of Loongson family of machines.
......@@ -1295,7 +1295,6 @@ config CPU_CAVIUM_OCTEON
select SYS_SUPPORTS_SMP
select NR_CPUS_DEFAULT_16
select WEAK_ORDERING
select WEAK_REORDERING_BEYOND_LLSC
select CPU_SUPPORTS_HIGHMEM
select CPU_SUPPORTS_HUGEPAGES
help
......@@ -1726,6 +1725,9 @@ config SB1_PASS_2_1_WORKAROUNDS
config 64BIT_PHYS_ADDR
bool
config ARCH_PHYS_ADDR_T_64BIT
def_bool 64BIT_PHYS_ADDR
config CPU_HAS_SMARTMIPS
depends on SYS_SUPPORTS_SMARTMIPS
bool "Support for the SmartMIPS ASE"
......
......@@ -102,4 +102,30 @@ config RUNTIME_DEBUG
arch/mips/include/asm/debug.h for debugging macros.
If unsure, say N.
config DEBUG_ZBOOT
bool "Enable compressed kernel support debugging"
depends on DEBUG_KERNEL && SYS_SUPPORTS_ZBOOT
default n
help
If you want to add compressed kernel support to a new board, and the
board supports uart16550 compatible serial port, please select
SYS_SUPPORTS_ZBOOT_UART16550 for your board and enable this option to
debug it.
If your board doesn't support uart16550 compatible serial port, you
can try to select SYS_SUPPORTS_ZBOOT and use the other methods to
debug it. for example, add a new serial port support just as
arch/mips/boot/compressed/uart-16550.c does.
After the compressed kernel support works, please disable this option
to reduce the kernel image size and speed up the booting procedure a
little.
config SPINLOCK_TEST
bool "Enable spinlock timing tests in debugfs"
depends on DEBUG_FS
default n
help
Add several files to the debugfs to test spinlock speed.
endmenu
......@@ -184,6 +184,15 @@ libs-$(CONFIG_CFE) += arch/mips/fw/cfe/
libs-$(CONFIG_SNIPROM) += arch/mips/fw/sni/
libs-y += arch/mips/fw/lib/
#
# Kernel compression
#
ifdef SYS_SUPPORTS_ZBOOT
COMPRESSION_FNAME = vmlinuz
else
COMPRESSION_FNAME = vmlinux
endif
#
# Board-dependent options and extra files
#
......@@ -332,11 +341,11 @@ load-$(CONFIG_WR_PPMC) += 0xffffffff80100000
#
# Loongson family
#
core-$(CONFIG_MACH_LOONGSON) +=arch/mips/loongson/
core-$(CONFIG_MACH_LOONGSON) += arch/mips/loongson/
cflags-$(CONFIG_MACH_LOONGSON) += -I$(srctree)/arch/mips/include/asm/mach-loongson \
-mno-branch-likely
load-$(CONFIG_LEMOTE_FULOONG2E) +=0xffffffff80100000
load-$(CONFIG_LEMOTE_MACH2F) +=0xffffffff80200000
load-$(CONFIG_LEMOTE_FULOONG2E) += 0xffffffff80100000
load-$(CONFIG_LEMOTE_MACH2F) += 0xffffffff80200000
#
# MIPS Malta board
......@@ -344,7 +353,7 @@ load-$(CONFIG_LEMOTE_MACH2F) +=0xffffffff80200000
core-$(CONFIG_MIPS_MALTA) += arch/mips/mti-malta/
cflags-$(CONFIG_MIPS_MALTA) += -I$(srctree)/arch/mips/include/asm/mach-malta
load-$(CONFIG_MIPS_MALTA) += 0xffffffff80100000
all-$(CONFIG_MIPS_MALTA) := vmlinuz.bin
all-$(CONFIG_MIPS_MALTA) := $(COMPRESSION_FNAME).bin
#
# MIPS SIM
......@@ -594,7 +603,7 @@ load-$(CONFIG_SNI_RM) += 0xffffffff80600000
else
load-$(CONFIG_SNI_RM) += 0xffffffff80030000
endif
all-$(CONFIG_SNI_RM) := vmlinuz.ecoff
all-$(CONFIG_SNI_RM) := $(COMPRESSION_FNAME).ecoff
#
# Common TXx9
......
# au1000-style gpio
config ALCHEMY_GPIO_AU1000
# au1000-style gpio and interrupt controllers
config ALCHEMY_GPIOINT_AU1000
bool
# select this in your board config if you don't want to use the gpio
......@@ -20,12 +20,14 @@ config MIPS_MTX1
select HW_HAS_PCI
select SOC_AU1500
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_HAS_EARLY_PRINTK
config MIPS_BOSPORUS
bool "Alchemy Bosporus board"
select SOC_AU1500
select DMA_NONCOHERENT
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_HAS_EARLY_PRINTK
config MIPS_DB1000
bool "Alchemy DB1000 board"
......@@ -33,12 +35,14 @@ config MIPS_DB1000
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 SOC_AU1100
select DMA_NONCOHERENT
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_HAS_EARLY_PRINTK
config MIPS_DB1200
bool "Alchemy DB1200 board"
......@@ -46,6 +50,7 @@ config MIPS_DB1200
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"
......@@ -55,6 +60,7 @@ config MIPS_DB1500
select MIPS_DISABLE_OBSOLETE_IDE
select SYS_SUPPORTS_BIG_ENDIAN
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_HAS_EARLY_PRINTK
config MIPS_DB1550
bool "Alchemy DB1550 board"
......@@ -63,12 +69,14 @@ config MIPS_DB1550
select DMA_NONCOHERENT
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 SOC_AU1500
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_HAS_EARLY_PRINTK
config MIPS_PB1000
bool "Alchemy PB1000 board"
......@@ -77,6 +85,7 @@ config MIPS_PB1000
select HW_HAS_PCI
select SWAP_IO_SPACE
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_HAS_EARLY_PRINTK
config MIPS_PB1100
bool "Alchemy PB1100 board"
......@@ -85,6 +94,7 @@ config MIPS_PB1100
select HW_HAS_PCI
select SWAP_IO_SPACE
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_HAS_EARLY_PRINTK
config MIPS_PB1200
bool "Alchemy PB1200 board"
......@@ -92,6 +102,7 @@ config MIPS_PB1200
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"
......@@ -99,6 +110,7 @@ config MIPS_PB1500
select DMA_NONCOHERENT
select HW_HAS_PCI
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_HAS_EARLY_PRINTK
config MIPS_PB1550
bool "Alchemy PB1550 board"
......@@ -107,39 +119,41 @@ config MIPS_PB1550
select HW_HAS_PCI
select MIPS_DISABLE_OBSOLETE_IDE
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_HAS_EARLY_PRINTK
config MIPS_XXS1500
bool "MyCable XXS1500 board"
select DMA_NONCOHERENT
select SOC_AU1500
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_HAS_EARLY_PRINTK
endchoice
config SOC_AU1000
bool
select SOC_AU1X00
select ALCHEMY_GPIO_AU1000
select ALCHEMY_GPIOINT_AU1000
config SOC_AU1100
bool
select SOC_AU1X00
select ALCHEMY_GPIO_AU1000
select ALCHEMY_GPIOINT_AU1000
config SOC_AU1500
bool
select SOC_AU1X00
select ALCHEMY_GPIO_AU1000
select ALCHEMY_GPIOINT_AU1000
config SOC_AU1550
bool
select SOC_AU1X00
select ALCHEMY_GPIO_AU1000
select ALCHEMY_GPIOINT_AU1000
config SOC_AU1200
bool
select SOC_AU1X00
select ALCHEMY_GPIO_AU1000
select ALCHEMY_GPIOINT_AU1000
config SOC_AU1X00
bool
......
......@@ -5,14 +5,15 @@
# Makefile for the Alchemy Au1xx0 CPUs, generic files.
#
obj-y += prom.o irq.o puts.o time.o reset.o \
clocks.o platform.o power.o setup.o \
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
# optional gpiolib support
ifeq ($(CONFIG_ALCHEMY_GPIO_INDIRECT),)
ifeq ($(CONFIG_GPIOLIB),y)
obj-$(CONFIG_ALCHEMY_GPIO_AU1000) += gpiolib-au1000.o
obj-$(CONFIG_ALCHEMY_GPIOINT_AU1000) += gpiolib-au1000.o
endif
endif
......
......@@ -40,8 +40,6 @@
static unsigned int au1x00_clock; /* Hz */
static unsigned long uart_baud_base;
static DEFINE_SPINLOCK(time_lock);
/*
* Set the au1000_clock
*/
......@@ -84,9 +82,6 @@ void set_au1x00_uart_baud_base(unsigned long new_baud_base)
unsigned long au1xxx_calc_clock(void)
{
unsigned long cpu_speed;
unsigned long flags;
spin_lock_irqsave(&time_lock, flags);
/*
* On early Au1000, sys_cpupll was write-only. Since these
......@@ -108,8 +103,6 @@ unsigned long au1xxx_calc_clock(void)
set_au1x00_uart_baud_base(cpu_speed / (2 * ((int)(au_readl(SYS_POWERCTRL)
& 0x03) + 2) * 16));
spin_unlock_irqrestore(&time_lock, flags);
set_au1x00_speed(cpu_speed);
return cpu_speed;
......
......@@ -30,6 +30,7 @@
*
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
......@@ -58,7 +59,6 @@ static DEFINE_SPINLOCK(au1xxx_dbdma_spin_lock);
static dbdma_global_t *dbdma_gptr = (dbdma_global_t *)DDMA_GLOBAL_BASE;
static int dbdma_initialized;
static void au1xxx_dbdma_init(void);
static dbdev_tab_t dbdev_tab[] = {
#ifdef CONFIG_SOC_AU1550
......@@ -237,7 +237,7 @@ u32 au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
void (*callback)(int, void *), void *callparam)
{
unsigned long flags;
u32 used, chan, rv;
u32 used, chan;
u32 dcp;
int i;
dbdev_tab_t *stp, *dtp;
......@@ -250,8 +250,7 @@ u32 au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
* which can't be done successfully during board set up.
*/
if (!dbdma_initialized)
au1xxx_dbdma_init();
dbdma_initialized = 1;
return 0;
stp = find_dbdev_id(srcid);
if (stp == NULL)
......@@ -261,7 +260,6 @@ u32 au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
return 0;
used = 0;
rv = 0;
/* Check to see if we can get both channels. */
spin_lock_irqsave(&au1xxx_dbdma_spin_lock, flags);
......@@ -282,63 +280,65 @@ u32 au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
used++;
spin_unlock_irqrestore(&au1xxx_dbdma_spin_lock, flags);
if (!used) {
/* Let's see if we can allocate a channel for it. */
ctp = NULL;
chan = 0;
spin_lock_irqsave(&au1xxx_dbdma_spin_lock, flags);
for (i = 0; i < NUM_DBDMA_CHANS; i++)
if (chan_tab_ptr[i] == NULL) {
/*
* If kmalloc fails, it is caught below same
* as a channel not available.
*/
ctp = kmalloc(sizeof(chan_tab_t), GFP_ATOMIC);
chan_tab_ptr[i] = ctp;
break;
}
spin_unlock_irqrestore(&au1xxx_dbdma_spin_lock, flags);
if (ctp != NULL) {
memset(ctp, 0, sizeof(chan_tab_t));
ctp->chan_index = chan = i;
dcp = DDMA_CHANNEL_BASE;
dcp += (0x0100 * chan);
ctp->chan_ptr = (au1x_dma_chan_t *)dcp;
cp = (au1x_dma_chan_t *)dcp;
ctp->chan_src = stp;
ctp->chan_dest = dtp;
ctp->chan_callback = callback;
ctp->chan_callparam = callparam;
/* Initialize channel configuration. */
i = 0;
if (stp->dev_intlevel)
i |= DDMA_CFG_SED;
if (stp->dev_intpolarity)
i |= DDMA_CFG_SP;
if (dtp->dev_intlevel)
i |= DDMA_CFG_DED;
if (dtp->dev_intpolarity)
i |= DDMA_CFG_DP;
if ((stp->dev_flags & DEV_FLAGS_SYNC) ||
(dtp->dev_flags & DEV_FLAGS_SYNC))
i |= DDMA_CFG_SYNC;
cp->ddma_cfg = i;
au_sync();
if (used)
return 0;
/* Return a non-zero value that can be used to
* find the channel information in subsequent
* operations.
/* Let's see if we can allocate a channel for it. */
ctp = NULL;
chan = 0;
spin_lock_irqsave(&au1xxx_dbdma_spin_lock, flags);
for (i = 0; i < NUM_DBDMA_CHANS; i++)
if (chan_tab_ptr[i] == NULL) {
/*
* If kmalloc fails, it is caught below same
* as a channel not available.
*/
rv = (u32)(&chan_tab_ptr[chan]);
} else {
/* Release devices */
stp->dev_flags &= ~DEV_FLAGS_INUSE;
dtp->dev_flags &= ~DEV_FLAGS_INUSE;
ctp = kmalloc(sizeof(chan_tab_t), GFP_ATOMIC);
chan_tab_ptr[i] = ctp;
break;
}
spin_unlock_irqrestore(&au1xxx_dbdma_spin_lock, flags);
if (ctp != NULL) {
memset(ctp, 0, sizeof(chan_tab_t));
ctp->chan_index = chan = i;
dcp = DDMA_CHANNEL_BASE;
dcp += (0x0100 * chan);
ctp->chan_ptr = (au1x_dma_chan_t *)dcp;
cp = (au1x_dma_chan_t *)dcp;
ctp->chan_src = stp;
ctp->chan_dest = dtp;
ctp->chan_callback = callback;
ctp->chan_callparam = callparam;
/* Initialize channel configuration. */
i = 0;
if (stp->dev_intlevel)
i |= DDMA_CFG_SED;
if (stp->dev_intpolarity)
i |= DDMA_CFG_SP;
if (dtp->dev_intlevel)
i |= DDMA_CFG_DED;
if (dtp->dev_intpolarity)
i |= DDMA_CFG_DP;
if ((stp->dev_flags & DEV_FLAGS_SYNC) ||
(dtp->dev_flags & DEV_FLAGS_SYNC))
i |= DDMA_CFG_SYNC;
cp->ddma_cfg = i;
au_sync();
/*
* Return a non-zero value that can be used to find the channel
* information in subsequent operations.
*/
return (u32)(&chan_tab_ptr[chan]);
}
return rv;
/* Release devices */
stp->dev_flags &= ~DEV_FLAGS_INUSE;
dtp->dev_flags &= ~DEV_FLAGS_INUSE;
return 0;
}
EXPORT_SYMBOL(au1xxx_dbdma_chan_alloc);
......@@ -572,7 +572,7 @@ EXPORT_SYMBOL(au1xxx_dbdma_ring_alloc);
* This updates the source pointer and byte count. Normally used
* for memory to fifo transfers.
*/
u32 _au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags)
u32 au1xxx_dbdma_put_source(u32 chanid, dma_addr_t buf, int nbytes, u32 flags)
{
chan_tab_t *ctp;
au1x_ddma_desc_t *dp;
......@@ -598,7 +598,7 @@ u32 _au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags)
return 0;
/* Load up buffer address and byte count. */
dp->dscr_source0 = virt_to_phys(buf);
dp->dscr_source0 = buf & ~0UL;
dp->dscr_cmd1 = nbytes;
/* Check flags */
if (flags & DDMA_FLAGS_IE)
......@@ -625,14 +625,13 @@ u32 _au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags)
/* Return something non-zero. */
return nbytes;
}
EXPORT_SYMBOL(_au1xxx_dbdma_put_source);
EXPORT_SYMBOL(au1xxx_dbdma_put_source);
/* Put a destination buffer into the DMA ring.
* This updates the destination pointer and byte count. Normally used
* to place an empty buffer into the ring for fifo to memory transfers.
*/
u32
_au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes, u32 flags)
u32 au1xxx_dbdma_put_dest(u32 chanid, dma_addr_t buf, int nbytes, u32 flags)
{
chan_tab_t *ctp;
au1x_ddma_desc_t *dp;
......@@ -662,7 +661,7 @@ _au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes, u32 flags)
if (flags & DDMA_FLAGS_NOIE)
dp->dscr_cmd0 &= ~DSCR_CMD0_IE;
dp->dscr_dest0 = virt_to_phys(buf);
dp->dscr_dest0 = buf & ~0UL;
dp->dscr_cmd1 = nbytes;
#if 0
printk(KERN_DEBUG "cmd0:%x cmd1:%x source0:%x source1:%x dest0:%x dest1:%x\n",
......@@ -688,7 +687,7 @@ _au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes, u32 flags)
/* Return something non-zero. */
return nbytes;
}
EXPORT_SYMBOL(_au1xxx_dbdma_put_dest);
EXPORT_SYMBOL(au1xxx_dbdma_put_dest);
/*
* Get a destination buffer into the DMA ring.
......@@ -871,28 +870,6 @@ static irqreturn_t dbdma_interrupt(int irq, void *dev_id)
return IRQ_RETVAL(1);
}
static void au1xxx_dbdma_init(void)
{
int irq_nr;
dbdma_gptr->ddma_config = 0;
dbdma_gptr->ddma_throttle = 0;
dbdma_gptr->ddma_inten = 0xffff;
au_sync();
#if defined(CONFIG_SOC_AU1550)
irq_nr = AU1550_DDMA_INT;
#elif defined(CONFIG_SOC_AU1200)
irq_nr = AU1200_DDMA_INT;
#else
#error Unknown Au1x00 SOC
#endif
if (request_irq(irq_nr, dbdma_interrupt, IRQF_DISABLED,
"Au1xxx dbdma", (void *)dbdma_gptr))
printk(KERN_ERR "Can't get 1550 dbdma irq");
}
void au1xxx_dbdma_dump(u32 chanid)
{
chan_tab_t *ctp;
......@@ -906,7 +883,7 @@ void au1xxx_dbdma_dump(u32 chanid)
dtp = ctp->chan_dest;
cp = ctp->chan_ptr;
printk(KERN_DEBUG "Chan %x, stp %x (dev %d) dtp %x (dev %d) \n",
printk(KERN_DEBUG "Chan %x, stp %x (dev %d) dtp %x (dev %d)\n",
(u32)ctp, (u32)stp, stp - dbdev_tab, (u32)dtp,
dtp - dbdev_tab);
printk(KERN_DEBUG "desc base %x, get %x, put %x, cur %x\n",
......@@ -1041,4 +1018,38 @@ void au1xxx_dbdma_resume(void)
}
}
#endif /* CONFIG_PM */
static int __init au1xxx_dbdma_init(void)
{
int irq_nr, ret;
dbdma_gptr->ddma_config = 0;
dbdma_gptr->ddma_throttle = 0;
dbdma_gptr->ddma_inten = 0xffff;
au_sync();
switch (alchemy_get_cputype()) {
case ALCHEMY_CPU_AU1550:
irq_nr = AU1550_DDMA_INT;
break;
case ALCHEMY_CPU_AU1200:
irq_nr = AU1200_DDMA_INT;
break;
default:
return -ENODEV;
}
ret = request_irq(irq_nr, dbdma_interrupt, IRQF_DISABLED,
"Au1xxx dbdma", (void *)dbdma_gptr);
if (ret)
printk(KERN_ERR "Cannot grab DBDMA interrupt!\n");
else {
dbdma_initialized = 1;
printk(KERN_INFO "Alchemy DBDMA initialized\n");
}
return ret;
}
subsys_initcall(au1xxx_dbdma_init);
#endif /* defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) */
......@@ -29,6 +29,8 @@
* 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
......@@ -188,17 +190,14 @@ int request_au1000_dma(int dev_id, const char *dev_str,
dev = &dma_dev_table[dev_id];
if (irqhandler) {
chan->irq = AU1000_DMA_INT_BASE + i;
chan->irq_dev = irq_dev_id;
ret = request_irq(chan->irq, irqhandler, irqflags, dev_str,
chan->irq_dev);
if (ret) {
chan->irq = 0;
chan->irq_dev = NULL;
return ret;
}
} else {
chan->irq = 0;
chan->irq_dev = NULL;
}
......@@ -226,13 +225,40 @@ void free_au1000_dma(unsigned int dmanr)
}
disable_dma(dmanr);
if (chan->irq)
if (chan->irq_dev)
free_irq(chan->irq, chan->irq_dev);
chan->irq = 0;
chan->irq_dev = NULL;
chan->dev_id = -1;
}
EXPORT_SYMBOL(free_au1000_dma);
static int __init au1000_dma_init(void)
{
int base, i;
switch (alchemy_get_cputype()) {
case ALCHEMY_CPU_AU1000:
base = AU1000_DMA_INT_BASE;
break;
case ALCHEMY_CPU_AU1500:
base = AU1500_DMA_INT_BASE;
break;
case ALCHEMY_CPU_AU1100:
base = AU1100_DMA_INT_BASE;
break;
default:
goto out;
}
for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++)
au1000_dma_table[i].irq = base + i;
printk(KERN_INFO "Alchemy DMA initialized\n");
out:
return 0;
}
arch_initcall(au1000_dma_init);
#endif /* AU1000 AU1500 AU1100 */
......@@ -36,7 +36,6 @@
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/gpio.h>
#if !defined(CONFIG_SOC_AU1000)
static int gpio2_get(struct gpio_chip *chip, unsigned offset)
{
return alchemy_gpio2_get_value(offset + ALCHEMY_GPIO2_BASE);
......@@ -63,7 +62,7 @@ static int gpio2_to_irq(struct gpio_chip *chip, unsigned offset)
{
return alchemy_gpio2_to_irq(offset + ALCHEMY_GPIO2_BASE);
}
#endif /* !defined(CONFIG_SOC_AU1000) */
static int gpio1_get(struct gpio_chip *chip, unsigned offset)
{
......@@ -104,7 +103,6 @@ struct gpio_chip alchemy_gpio_chip[] = {
.base = ALCHEMY_GPIO1_BASE,
.ngpio = ALCHEMY_GPIO1_NUM,
},
#if !defined(CONFIG_SOC_AU1000)
[1] = {
.label = "alchemy-gpio2",
.direction_input = gpio2_direction_input,
......@@ -115,15 +113,13 @@ struct gpio_chip alchemy_gpio_chip[] = {
.base = ALCHEMY_GPIO2_BASE,
.ngpio = ALCHEMY_GPIO2_NUM,
},
#endif
};
static int __init alchemy_gpiolib_init(void)
{
gpiochip_add(&alchemy_gpio_chip[0]);
#if !defined(CONFIG_SOC_AU1000)
gpiochip_add(&alchemy_gpio_chip[1]);
#endif
if (alchemy_get_cputype() != ALCHEMY_CPU_AU1000)
gpiochip_add(&alchemy_gpio_chip[1]);
return 0;
}
......
This diff is collapsed.
......@@ -19,39 +19,40 @@
#include <asm/mach-au1x00/au1xxx.h>
#include <asm/mach-au1x00/au1xxx_dbdma.h>
#include <asm/mach-au1x00/au1100_mmc.h>
#define PORT(_base, _irq) \
{ \
.iobase = _base, \
.membase = (void __iomem *)_base,\
.mapbase = CPHYSADDR(_base), \
.irq = _irq, \
.regshift = 2, \
.iotype = UPIO_AU, \
.flags = UPF_SKIP_TEST \
#include <asm/mach-au1x00/au1xxx_eth.h>
#define PORT(_base, _irq) \
{ \
.mapbase = _base, \
.irq = _irq, \
.regshift = 2, \
.iotype = UPIO_AU, \
.flags = UPF_SKIP_TEST | UPF_IOREMAP | \
UPF_FIXED_TYPE, \
.type = PORT_16550A, \
}
static struct plat_serial8250_port au1x00_uart_data[] = {
#if defined(CONFIG_SERIAL_8250_AU1X00)
#if defined(CONFIG_SOC_AU1000)
PORT(UART0_ADDR, AU1000_UART0_INT),
PORT(UART1_ADDR, AU1000_UART1_INT),
PORT(UART2_ADDR, AU1000_UART2_INT),
PORT(UART3_ADDR, AU1000_UART3_INT),
PORT(UART0_PHYS_ADDR, AU1000_UART0_INT),
PORT(UART1_PHYS_ADDR, AU1000_UART1_INT),
PORT(UART2_PHYS_ADDR, AU1000_UART2_INT),
PORT(UART3_PHYS_ADDR, AU1000_UART3_INT),
#elif defined(CONFIG_SOC_AU1500)
PORT(UART0_ADDR, AU1500_UART0_INT),
PORT(UART3_ADDR, AU1500_UART3_INT),
PORT(UART0_PHYS_ADDR, AU1500_UART0_INT),
PORT(UART3_PHYS_ADDR, AU1500_UART3_INT),
#elif defined(CONFIG_SOC_AU1100)
PORT(UART0_ADDR, AU1100_UART0_INT),
PORT(UART1_ADDR, AU1100_UART1_INT),
PORT(UART3_ADDR, AU1100_UART3_INT),
PORT(UART0_PHYS_ADDR, AU1100_UART0_INT),
PORT(UART1_PHYS_ADDR, AU1100_UART1_INT),
PORT(UART3_PHYS_ADDR, AU1100_UART3_INT),
#elif defined(CONFIG_SOC_AU1550)
PORT(UART0_ADDR, AU1550_UART0_INT),
PORT(UART1_ADDR, AU1550_UART1_INT),
PORT(UART3_ADDR, AU1550_UART3_INT),
PORT(UART0_PHYS_ADDR, AU1550_UART0_INT),
PORT(UART1_PHYS_ADDR, AU1550_UART1_INT),
PORT(UART3_PHYS_ADDR, AU1550_UART3_INT),
#elif defined(CONFIG_SOC_AU1200)
PORT(UART0_ADDR, AU1200_UART0_INT),
PORT(UART1_ADDR, AU1200_UART1_INT),
PORT(UART0_PHYS_ADDR, AU1200_UART0_INT),
PORT(UART1_PHYS_ADDR, AU1200_UART1_INT),
#endif
#endif /* CONFIG_SERIAL_8250_AU1X00 */
{ },
......@@ -73,8 +74,8 @@ static struct resource au1xxx_usb_ohci_resources[] = {
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AU1000_USB_HOST_INT,
.end = AU1000_USB_HOST_INT,
.start = FOR_PLATFORM_C_USB_HOST_INT,
.end = FOR_PLATFORM_C_USB_HOST_INT,
.flags = IORESOURCE_IRQ,
},
};
......@@ -132,8 +133,8 @@ static struct resource au1xxx_usb_ehci_resources[] = {
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AU1000_USB_HOST_INT,
.end = AU1000_USB_HOST_INT,
.start = AU1200_USB_INT,
.end = AU1200_USB_INT,
.flags = IORESOURCE_IRQ,
},
};
......@@ -308,11 +309,6 @@ static struct platform_device au1200_mmc1_device = {
#endif /* #ifndef CONFIG_MIPS_DB1200 */
#endif /* #ifdef CONFIG_SOC_AU1200 */
static struct platform_device au1x00_pcmcia_device = {
.name = "au1x00-pcmcia",
.id = 0,
};
/* All Alchemy demoboards with I2C have this #define in their headers */
#ifdef SMBUS_PSC_BASE
static struct resource pbdb_smbus_resources[] = {
......@@ -331,10 +327,92 @@ static struct platform_device pbdb_smbus_device = {
};
#endif
/* Macro to help defining the Ethernet MAC resources */
#define MAC_RES(_base, _enable, _irq) \
{ \
.start = CPHYSADDR(_base), \
.end = CPHYSADDR(_base + 0xffff), \
.flags = IORESOURCE_MEM, \
}, \
{ \
.start = CPHYSADDR(_enable), \
.end = CPHYSADDR(_enable + 0x3), \
.flags = IORESOURCE_MEM, \
}, \
{ \
.start = _irq, \
.end = _irq, \
.flags = IORESOURCE_IRQ \
}
static struct resource au1xxx_eth0_resources[] = {
#if defined(CONFIG_SOC_AU1000)
MAC_RES(AU1000_ETH0_BASE, AU1000_MAC0_ENABLE, AU1000_MAC0_DMA_INT),
#elif defined(CONFIG_SOC_AU1100)
MAC_RES(AU1100_ETH0_BASE, AU1100_MAC0_ENABLE, AU1100_MAC0_DMA_INT),
#elif defined(CONFIG_SOC_AU1550)
MAC_RES(AU1550_ETH0_BASE, AU1550_MAC0_ENABLE, AU1550_MAC0_DMA_INT),
#elif defined(CONFIG_SOC_AU1500)
MAC_RES(AU1500_ETH0_BASE, AU1500_MAC0_ENABLE, AU1500_MAC0_DMA_INT),
#endif
};
static struct au1000_eth_platform_data au1xxx_eth0_platform_data = {
.phy1_search_mac0 = 1,
};
static struct platform_device au1xxx_eth0_device = {
.name = "au1000-eth",
.id = 0,
.num_resources = ARRAY_SIZE(au1xxx_eth0_resources),
.resource = au1xxx_eth0_resources,
.dev.platform_data = &au1xxx_eth0_platform_data,
};
#ifndef CONFIG_SOC_AU1100
static struct resource au1xxx_eth1_resources[] = {
#if defined(CONFIG_SOC_AU1000)
MAC_RES(AU1000_ETH1_BASE, AU1000_MAC1_ENABLE, AU1000_MAC1_DMA_INT),
#elif defined(CONFIG_SOC_AU1550)
MAC_RES(AU1550_ETH1_BASE, AU1550_MAC1_ENABLE, AU1550_MAC1_DMA_INT),
#elif defined(CONFIG_SOC_AU1500)
MAC_RES(AU1500_ETH1_BASE, AU1500_MAC1_ENABLE, AU1500_MAC1_DMA_INT),
#endif
};
static struct au1000_eth_platform_data au1xxx_eth1_platform_data = {
.phy1_search_mac0 = 1,
};
static struct platform_device au1xxx_eth1_device = {
.name = "au1000-eth",
.id = 1,
.num_resources = ARRAY_SIZE(au1xxx_eth1_resources),
.resource = au1xxx_eth1_resources,
.dev.platform_data = &au1xxx_eth1_platform_data,
};
#endif
void __init au1xxx_override_eth_cfg(unsigned int port,
struct au1000_eth_platform_data *eth_data)
{
if (!eth_data || port > 1)
return;
if (port == 0)
memcpy(&au1xxx_eth0_platform_data, eth_data,
sizeof(struct au1000_eth_platform_data));
#ifndef CONFIG_SOC_AU1100
else
memcpy(&au1xxx_eth1_platform_data, eth_data,
sizeof(struct au1000_eth_platform_data));
#endif
}
static struct platform_device *au1xxx_platform_devices[] __initdata = {
&au1xx0_uart_device,
&au1xxx_usb_ohci_device,
&au1x00_pcmcia_device,
#ifdef CONFIG_FB_AU1100
&au1100_lcd_device,
#endif
......@@ -351,6 +429,7 @@ static struct platform_device *au1xxx_platform_devices[] __initdata = {
#ifdef SMBUS_PSC_BASE
&pbdb_smbus_device,
#endif
&au1xxx_eth0_device,
};
static int __init au1xxx_platform_init(void)
......@@ -362,6 +441,12 @@ static int __init au1xxx_platform_init(void)
for (i = 0; au1x00_uart_data[i].flags; i++)
au1x00_uart_data[i].uartclk = uartclk;
#ifndef CONFIG_SOC_AU1100
/* Register second MAC if enabled in pinfunc */
if (!(au_readl(SYS_PINFUNC) & (u32)SYS_PF_NI2))
platform_device_register(&au1xxx_eth1_device);
#endif
return platform_add_devices(au1xxx_platform_devices,
ARRAY_SIZE(au1xxx_platform_devices));
}
......
......@@ -43,29 +43,15 @@ int prom_argc;
char **prom_argv;
char **prom_envp;
char * __init_or_module prom_getcmdline(void)
{
return &(arcs_cmdline[0]);
}
void prom_init_cmdline(void)
{
char *cp;
int actr;
actr = 1; /* Always ignore argv[0] */
int i;
cp = &(arcs_cmdline[0]);
while (actr < prom_argc) {
strcpy(cp, prom_argv[actr]);
cp += strlen(prom_argv[actr]);
*cp++ = ' ';
actr++;
for (i = 1; i < prom_argc; i++) {
strlcat(arcs_cmdline, prom_argv[i], COMMAND_LINE_SIZE);
if (i < (prom_argc - 1))
strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE);
}
if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */
--cp;
if (prom_argc > 1)
*cp = '\0';
}
char *prom_getenv(char *envname)
......@@ -121,14 +107,12 @@ static inline void str2eaddr(unsigned char *ea, unsigned char *str)
int prom_get_ethernet_addr(char *ethernet_addr)
{
char *ethaddr_str;
char *argptr;
/* Check the environment variables first */
ethaddr_str = prom_getenv("ethaddr");
if (!ethaddr_str) {
/* Check command line */
argptr = prom_getcmdline();
ethaddr_str = strstr(argptr, "ethaddr=");
ethaddr_str = strstr(arcs_cmdline, "ethaddr=");
if (!ethaddr_str)
return -1;
......
/*
*
* BRIEF MODULE DESCRIPTION
* Low level UART routines to directly access Alchemy UART.
*
* Copyright 2001, 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 <asm/mach-au1x00/au1000.h>
#define SERIAL_BASE UART_BASE
#define SER_CMD 0x7
#define SER_DATA 0x1
#define TX_BUSY 0x20
#define TIMEOUT 0xffffff
#define SLOW_DOWN
static volatile unsigned long * const com1 = (unsigned long *)SERIAL_BASE;
#ifdef SLOW_DOWN
static inline void slow_down(void)
{
int k;
for (k = 0; k < 10000; k++);
}
#else
#define slow_down()
#endif
void
prom_putchar(const unsigned char c)
{
unsigned char ch;
int i = 0;
do {
ch = com1[SER_CMD];
slow_down();
i++;
if (i > TIMEOUT)
break;
} while (0 == (ch & TX_BUSY));
com1[SER_DATA] = c;
}
/*
*
* BRIEF MODULE DESCRIPTION
* Au1xx0 reset routines.
*
* Copyright 2001, 2006, 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 <asm/cacheflush.h>
#include <asm/mach-au1x00/au1000.h>
void au1000_restart(char *command)
{
/* Set all integrated peripherals to disabled states */
extern void board_reset(void);
u32 prid = read_c0_prid();
printk(KERN_NOTICE "\n** Resetting Integrated Peripherals\n");
switch (prid & 0xFF000000) {
case 0x00000000: /* Au1000 */
au_writel(0x02, 0xb0000010); /* ac97_enable */
au_writel(0x08, 0xb017fffc); /* usbh_enable - early errata */
asm("sync");
au_writel(0x00, 0xb017fffc); /* usbh_enable */
au_writel(0x00, 0xb0200058); /* usbd_enable */
au_writel(0x00, 0xb0300040); /* ir_enable */
au_writel(0x00, 0xb4004104); /* mac dma */
au_writel(0x00, 0xb4004114); /* mac dma */
au_writel(0x00, 0xb4004124); /* mac dma */
au_writel(0x00, 0xb4004134); /* mac dma */
au_writel(0x00, 0xb0520000); /* macen0 */
au_writel(0x00, 0xb0520004); /* macen1 */
au_writel(0x00, 0xb1000008); /* i2s_enable */
au_writel(0x00, 0xb1100100); /* uart0_enable */
au_writel(0x00, 0xb1200100); /* uart1_enable */
au_writel(0x00, 0xb1300100); /* uart2_enable */
au_writel(0x00, 0xb1400100); /* uart3_enable */
au_writel(0x02, 0xb1600100); /* ssi0_enable */
au_writel(0x02, 0xb1680100); /* ssi1_enable */
au_writel(0x00, 0xb1900020); /* sys_freqctrl0 */
au_writel(0x00, 0xb1900024); /* sys_freqctrl1 */
au_writel(0x00, 0xb1900028); /* sys_clksrc */
au_writel(0x10, 0xb1900060); /* sys_cpupll */
au_writel(0x00, 0xb1900064); /* sys_auxpll */
au_writel(0x00, 0xb1900100); /* sys_pininputen */
break;
case 0x01000000: /* Au1500 */
au_writel(0x02, 0xb0000010); /* ac97_enable */
au_writel(0x08, 0xb017fffc); /* usbh_enable - early errata */
asm("sync");
au_writel(0x00, 0xb017fffc); /* usbh_enable */
au_writel(0x00, 0xb0200058); /* usbd_enable */
au_writel(0x00, 0xb4004104); /* mac dma */
au_writel(0x00, 0xb4004114); /* mac dma */
au_writel(0x00, 0xb4004124); /* mac dma */
au_writel(0x00, 0xb4004134); /* mac dma */
au_writel(0x00, 0xb1520000); /* macen0 */
au_writel(0x00, 0xb1520004); /* macen1 */
au_writel(0x00, 0xb1100100); /* uart0_enable */
au_writel(0x00, 0xb1400100); /* uart3_enable */
au_writel(0x00, 0xb1900020); /* sys_freqctrl0 */
au_writel(0x00, 0xb1900024); /* sys_freqctrl1 */
au_writel(0x00, 0xb1900028); /* sys_clksrc */
au_writel(0x10, 0xb1900060); /* sys_cpupll */
au_writel(0x00, 0xb1900064); /* sys_auxpll */
au_writel(0x00, 0xb1900100); /* sys_pininputen */
break;
case 0x02000000: /* Au1100 */
au_writel(0x02, 0xb0000010); /* ac97_enable */
au_writel(0x08, 0xb017fffc); /* usbh_enable - early errata */
asm("sync");
au_writel(0x00, 0xb017fffc); /* usbh_enable */
au_writel(0x00, 0xb0200058); /* usbd_enable */
au_writel(0x00, 0xb0300040); /* ir_enable */
au_writel(0x00, 0xb4004104); /* mac dma */
au_writel(0x00, 0xb4004114); /* mac dma */
au_writel(0x00, 0xb4004124); /* mac dma */
au_writel(0x00, 0xb4004134); /* mac dma */
au_writel(0x00, 0xb0520000); /* macen0 */
au_writel(0x00, 0xb1000008); /* i2s_enable */
au_writel(0x00, 0xb1100100); /* uart0_enable */
au_writel(0x00, 0xb1200100); /* uart1_enable */
au_writel(0x00, 0xb1400100); /* uart3_enable */
au_writel(0x02, 0xb1600100); /* ssi0_enable */
au_writel(0x02, 0xb1680100); /* ssi1_enable */
au_writel(0x00, 0xb1900020); /* sys_freqctrl0 */
au_writel(0x00, 0xb1900024); /* sys_freqctrl1 */
au_writel(0x00, 0xb1900028); /* sys_clksrc */
au_writel(0x10, 0xb1900060); /* sys_cpupll */
au_writel(0x00, 0xb1900064); /* sys_auxpll */
au_writel(0x00, 0xb1900100); /* sys_pininputen */
break;
case 0x03000000: /* Au1550 */
au_writel(0x00, 0xb1a00004); /* psc 0 */
au_writel(0x00, 0xb1b00004); /* psc 1 */
au_writel(0x00, 0xb0a00004); /* psc 2 */
au_writel(0x00, 0xb0b00004); /* psc 3 */
au_writel(0x00, 0xb017fffc); /* usbh_enable */
au_writel(0x00, 0xb0200058); /* usbd_enable */
au_writel(0x00, 0xb4004104); /* mac dma */
au_writel(0x00, 0xb4004114); /* mac dma */
au_writel(0x00, 0xb4004124); /* mac dma */
au_writel(0x00, 0xb4004134); /* mac dma */
au_writel(0x00, 0xb1520000); /* macen0 */
au_writel(0x00, 0xb1520004); /* macen1 */
au_writel(0x00, 0xb1100100); /* uart0_enable */
au_writel(0x00, 0xb1200100); /* uart1_enable */
au_writel(0x00, 0xb1400100); /* uart3_enable */
au_writel(0x00, 0xb1900020); /* sys_freqctrl0 */
au_writel(0x00, 0xb1900024); /* sys_freqctrl1 */
au_writel(0x00, 0xb1900028); /* sys_clksrc */
au_writel(0x10, 0xb1900060); /* sys_cpupll */
au_writel(0x00, 0xb1900064); /* sys_auxpll */
au_writel(0x00, 0xb1900100); /* sys_pininputen */
break;
}
set_c0_status(ST0_BEV | ST0_ERL);
change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
flush_cache_all();
write_c0_wired(0);
/* Give board a chance to do a hardware reset */
board_reset();
/* Jump to the beggining in case board_reset() is empty */
__asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
}
void au1000_halt(void)
{
#if defined(CONFIG_MIPS_PB1550) || defined(CONFIG_MIPS_DB1550)
/* Power off system */
printk(KERN_NOTICE "\n** Powering off...\n");
au_writew(au_readw(0xAF00001C) | (3 << 14), 0xAF00001C);
au_sync();
while (1); /* should not get here */
#else
printk(KERN_NOTICE "\n** You can safely turn off the power\n");
#ifdef CONFIG_MIPS_MIRAGE
gpio_direction_output(210, 1);
#endif
#ifdef CONFIG_MIPS_DB1200
au_writew(au_readw(0xB980001C) | (1 << 14), 0xB980001C);
#endif
#ifdef CONFIG_PM
au_sleep();
/* Should not get here */
printk(KERN_ERR "Unable to put CPU in sleep mode\n");
while (1);
#else
while (1)
__asm__(".set\tmips3\n\t"
"wait\n\t"
".set\tmips0");
#endif
#endif /* defined(CONFIG_MIPS_PB1550) || defined(CONFIG_MIPS_DB1550) */
}
void au1000_power_off(void)
{
au1000_halt();
}
......@@ -29,18 +29,13 @@
#include <linux/ioport.h>
#include <linux/jiffies.h>
#include <linux/module.h>
#include <linux/pm.h>
#include <asm/mipsregs.h>
#include <asm/reboot.h>
#include <asm/time.h>
#include <au1000.h>
extern void __init board_setup(void);
extern void au1000_restart(char *);
extern void au1000_halt(void);
extern void au1000_power_off(void);
extern void set_cpuspec(void);
void __init plat_mem_setup(void)
......@@ -57,10 +52,6 @@ void __init plat_mem_setup(void)
/* this is faster than wasting cycles trying to approximate it */
preset_lpj = (est_freq >> 1) / HZ;
_machine_restart = au1000_restart;
_machine_halt = au1000_halt;
pm_power_off = au1000_power_off;
board_setup(); /* board specific setup */
if (au1xxx_cpu_needs_config_od())
......@@ -78,37 +69,20 @@ void __init plat_mem_setup(void)
iomem_resource.end = IOMEM_RESOURCE_END;
}
#if defined(CONFIG_64BIT_PHYS_ADDR)
#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_PCI)
/* This routine should be valid for all Au1x based boards */
phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size)
{
u32 start = (u32)Au1500_PCI_MEM_START;
u32 end = (u32)Au1500_PCI_MEM_END;
/* Don't fixup 36-bit addresses */
if ((phys_addr >> 32) != 0)
return phys_addr;
#ifdef CONFIG_PCI
{
u32 start = (u32)Au1500_PCI_MEM_START;
u32 end = (u32)Au1500_PCI_MEM_END;
/* Check for PCI memory window */
if (phys_addr >= start && (phys_addr + size - 1) <= end)
return (phys_t)
((phys_addr - start) + Au1500_PCI_MEM_START);
}
#endif
/*
* All Au1xx0 SOCs have a PCMCIA controller.
* We setup our 32-bit pseudo addresses to be equal to the
* 36-bit addr >> 4, to make it easier to check the address
* and fix it.
* The PCMCIA socket 0 physical attribute address is 0xF 4000 0000.
* The pseudo address we use is 0xF400 0000. Any address over
* 0xF400 0000 is a PCMCIA pseudo address.
*/
if ((phys_addr >= 0xF4000000) && (phys_addr < 0xFFFFFFFF))
return (phys_t)(phys_addr << 4);
/* Check for PCI memory window */
if (phys_addr >= start && (phys_addr + size - 1) <= end)
return (phys_t)((phys_addr - start) + Au1500_PCI_MEM_START);
/* default nop */
return phys_addr;
......
/*
* Copyright (C) 2008 Manuel Lauss <mano@roarinelk.homelinux.net>
* Copyright (C) 2008-2009 Manuel Lauss <manuel.lauss@gmail.com>
*
* Previous incarnations were:
* Copyright (C) 2001, 2006, 2008 MontaVista Software, <source@mvista.com>
......@@ -85,7 +85,6 @@ static struct clock_event_device au1x_rtcmatch2_clockdev = {
.name = "rtcmatch2",
.features = CLOCK_EVT_FEAT_ONESHOT,
.rating = 100,
.irq = AU1000_RTC_MATCH2_INT,
.set_next_event = au1x_rtcmatch2_set_next_event,
.set_mode = au1x_rtcmatch2_set_mode,
.cpumask = cpu_all_mask,
......@@ -98,11 +97,13 @@ static struct irqaction au1x_rtcmatch2_irqaction = {
.dev_id = &au1x_rtcmatch2_clockdev,
};
void __init plat_time_init(void)
static int __init alchemy_time_init(unsigned int m2int)
{
struct clock_event_device *cd = &au1x_rtcmatch2_clockdev;
unsigned long t;
au1x_rtcmatch2_clockdev.irq = m2int;
/* Check if firmware (YAMON, ...) has enabled 32kHz and clock
* has been detected. If so install the rtcmatch2 clocksource,
* otherwise don't bother. Note that both bits being set is by
......@@ -148,13 +149,18 @@ void __init plat_time_init(void)
cd->max_delta_ns = clockevent_delta2ns(0xffffffff, cd);
cd->min_delta_ns = clockevent_delta2ns(8, cd); /* ~0.25ms */
clockevents_register_device(cd);
setup_irq(AU1000_RTC_MATCH2_INT, &au1x_rtcmatch2_irqaction);
setup_irq(m2int, &au1x_rtcmatch2_irqaction);
printk(KERN_INFO "Alchemy clocksource installed\n");
return;
return 0;
cntr_err:
return -1;
}
static void __init alchemy_setup_c0timer(void)
{
/*
* MIPS kernel assigns 'au1k_wait' to 'cpu_wait' before this
* function is called. Because the Alchemy counters are unusable
......@@ -166,3 +172,22 @@ void __init plat_time_init(void)
r4k_clockevent_init();
init_r4k_clocksource();
}
static int alchemy_m2inttab[] __initdata = {
AU1000_RTC_MATCH2_INT,
AU1500_RTC_MATCH2_INT,
AU1100_RTC_MATCH2_INT,
AU1550_RTC_MATCH2_INT,
AU1200_RTC_MATCH2_INT,
};
void __init plat_time_init(void)
{
int t;
t = alchemy_get_cputype();
if (t == ALCHEMY_CPU_UNKNOWN)
alchemy_setup_c0timer();
else if (alchemy_time_init(alchemy_m2inttab[t]))
alchemy_setup_c0timer();
}
......@@ -2,7 +2,7 @@
# Alchemy Develboards
#
obj-y += prom.o
obj-y += prom.o bcsr.o platform.o
obj-$(CONFIG_PM) += pm.o
obj-$(CONFIG_MIPS_PB1000) += pb1000/
obj-$(CONFIG_MIPS_PB1100) += pb1100/
......@@ -11,8 +11,10 @@ obj-$(CONFIG_MIPS_PB1500) += pb1500/
obj-$(CONFIG_MIPS_PB1550) += pb1550/
obj-$(CONFIG_MIPS_DB1000) += db1x00/
obj-$(CONFIG_MIPS_DB1100) += db1x00/
obj-$(CONFIG_MIPS_DB1200) += pb1200/
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/
EXTRA_CFLAGS += -Werror
/*
* bcsr.h -- Db1xxx/Pb1xxx Devboard CPLD registers ("BCSR") abstraction.
*
* All Alchemy development boards (except, of course, the weird PB1000)
* have a few registers in a CPLD with standardised layout; they mostly
* only differ in base address.
* All registers are 16bits wide with 32bit spacing.
*/
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <asm/addrspace.h>
#include <asm/io.h>
#include <asm/mach-db1x00/bcsr.h>
static struct bcsr_reg {
void __iomem *raddr;
spinlock_t lock;
} bcsr_regs[BCSR_CNT];
static void __iomem *bcsr_virt; /* KSEG1 addr of BCSR base */
static int bcsr_csc_base; /* linux-irq of first cascaded irq */
void __init bcsr_init(unsigned long bcsr1_phys, unsigned long bcsr2_phys)
{
int i;
bcsr1_phys = KSEG1ADDR(CPHYSADDR(bcsr1_phys));
bcsr2_phys = KSEG1ADDR(CPHYSADDR(bcsr2_phys));
bcsr_virt = (void __iomem *)bcsr1_phys;
for (i = 0; i < BCSR_CNT; i++) {
if (i >= BCSR_HEXLEDS)
bcsr_regs[i].raddr = (void __iomem *)bcsr2_phys +
(0x04 * (i - BCSR_HEXLEDS));
else
bcsr_regs[i].raddr = (void __iomem *)bcsr1_phys +
(0x04 * i);
spin_lock_init(&bcsr_regs[i].lock);
}
}
unsigned short bcsr_read(enum bcsr_id reg)
{
unsigned short r;
unsigned long flags;
spin_lock_irqsave(&bcsr_regs[reg].lock, flags);
r = __raw_readw(bcsr_regs[reg].raddr);
spin_unlock_irqrestore(&bcsr_regs[reg].lock, flags);
return r;
}
EXPORT_SYMBOL_GPL(bcsr_read);
void bcsr_write(enum bcsr_id reg, unsigned short val)
{
unsigned long flags;
spin_lock_irqsave(&bcsr_regs[reg].lock, flags);
__raw_writew(val, bcsr_regs[reg].raddr);
wmb();
spin_unlock_irqrestore(&bcsr_regs[reg].lock, flags);
}
EXPORT_SYMBOL_GPL(bcsr_write);
void bcsr_mod(enum bcsr_id reg, unsigned short clr, unsigned short set)
{
unsigned short r;
unsigned long flags;
spin_lock_irqsave(&bcsr_regs[reg].lock, flags);
r = __raw_readw(bcsr_regs[reg].raddr);
r &= ~clr;
r |= set;
__raw_writew(r, bcsr_regs[reg].raddr);
wmb();
spin_unlock_irqrestore(&bcsr_regs[reg].lock, flags);
}
EXPORT_SYMBOL_GPL(bcsr_mod);
/*
* DB1200/PB1200 CPLD IRQ muxer
*/
static void bcsr_csc_handler(unsigned int irq, struct irq_desc *d)
{
unsigned short bisr = __raw_readw(bcsr_virt + BCSR_REG_INTSTAT);
for ( ; bisr; bisr &= bisr - 1)
generic_handle_irq(bcsr_csc_base + __ffs(bisr));
}
/* 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(unsigned int irq_nr)
{
unsigned short v = 1 << (irq_nr - bcsr_csc_base);
__raw_writew(v, bcsr_virt + BCSR_REG_INTCLR);
__raw_writew(v, bcsr_virt + BCSR_REG_MASKCLR);
wmb();
}
static void bcsr_irq_maskack(unsigned int irq_nr)
{
unsigned short v = 1 << (irq_nr - 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();
}
static void bcsr_irq_unmask(unsigned int irq_nr)
{
unsigned short v = 1 << (irq_nr - bcsr_csc_base);
__raw_writew(v, bcsr_virt + BCSR_REG_INTSET);
__raw_writew(v, bcsr_virt + BCSR_REG_MASKSET);
wmb();
}
static struct irq_chip bcsr_irq_type = {
.name = "CPLD",
.mask = bcsr_irq_mask,
.mask_ack = bcsr_irq_maskack,
.unmask = bcsr_irq_unmask,
};
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);
__raw_writew(0xffff, bcsr_virt + BCSR_REG_MASKCLR);
__raw_writew(0xffff, bcsr_virt + BCSR_REG_INTSTAT);
wmb();
bcsr_csc_base = csc_start;
for (irq = csc_start; irq <= csc_end; irq++)
set_irq_chip_and_handler_name(irq, &bcsr_irq_type,
handle_level_irq, "level");
set_irq_chained_handler(hook_irq, bcsr_csc_handler);
}
This diff is collapsed.
/*
* 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();
}
/* use the hexleds to count the number of times the cpu has entered
* wait, the dots to indicate whether the CPU is currently idle or
* active (dots off = sleeping, dots on = working) for cases where
* the number doesn't change for a long(er) period of time.
*/
static void db1200_wait(void)
{
__asm__(" .set push \n"
" .set mips3 \n"
" .set noreorder \n"
" cache 0x14, 0(%0) \n"
" cache 0x14, 32(%0) \n"
" cache 0x14, 64(%0) \n"
/* dots off: we're about to call wait */
" lui $26, 0xb980 \n"
" ori $27, $0, 3 \n"
" sb $27, 0x18($26) \n"
" sync \n"
" nop \n"
" wait \n"
" nop \n"
" nop \n"
" nop \n"
" nop \n"
" nop \n"
/* dots on: there's work to do, increment cntr */
" lui $26, 0xb980 \n"
" sb $0, 0x18($26) \n"
" lui $26, 0xb9c0 \n"
" lb $27, 0($26) \n"
" addiu $27, $27, 1 \n"
" sb $27, 0($26) \n"
" sync \n"
" .set pop \n"
: : "r" (db1200_wait));
}
static int __init db1200_arch_init(void)
{
/* GPIO7 is low-level triggered CPLD cascade */
set_irq_type(AU1200_GPIO7_INT, IRQF_TRIGGER_LOW);
bcsr_init_irq(DB1200_INT_BEGIN, DB1200_INT_END, AU1200_GPIO7_INT);
/* do not autoenable these: CPLD has broken edge int handling,
* and the CD handler setup requires manual enabling to work
* around that.
*/
irq_to_desc(DB1200_SD0_INSERT_INT)->status |= IRQ_NOAUTOEN;
irq_to_desc(DB1200_SD0_EJECT_INT)->status |= IRQ_NOAUTOEN;
if (cpu_wait)
cpu_wait = db1200_wait;
return 0;
}
arch_initcall(db1200_arch_init);
......@@ -5,4 +5,4 @@
# Makefile for the Alchemy Semiconductor DBAu1xx0 boards.
#
obj-y := board_setup.o irqmap.o
obj-y := board_setup.o platform.o
......@@ -29,59 +29,139 @@
#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_DB1500
char irq_tab_alchemy[][5] __initdata = {
[12] = { -1, AU1500_PCI_INTA, 0xff, 0xff, 0xff }, /* IDSEL 12 - HPT371 */
[13] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, AU1500_PCI_INTC, AU1500_PCI_INTD }, /* IDSEL 13 - PCI slot */
};
#endif
static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
#ifdef CONFIG_MIPS_DB1550
char irq_tab_alchemy[][5] __initdata = {
[11] = { -1, AU1550_PCI_INTC, 0xff, 0xff, 0xff }, /* IDSEL 11 - on-board HPT371 */
[12] = { -1, AU1550_PCI_INTB, AU1550_PCI_INTC, AU1550_PCI_INTD, AU1550_PCI_INTA }, /* IDSEL 12 - PCI slot 2 (left) */
[13] = { -1, AU1550_PCI_INTA, AU1550_PCI_INTB, AU1550_PCI_INTC, AU1550_PCI_INTD }, /* IDSEL 13 - PCI slot 1 (right) */
};
#endif
#ifdef CONFIG_MIPS_BOSPORUS
char irq_tab_alchemy[][5] __initdata = {
[11] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff }, /* IDSEL 11 - miniPCI */
[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)
{
printk(KERN_INFO "It's now safe to turn off power\n");
while (1)
asm volatile (".set mips3 ; wait ; .set mips0");
}
const char *get_system_type(void)
{
#ifdef CONFIG_MIPS_BOSPORUS
return "Alchemy Bosporus Gateway Reference";
#else
return "Alchemy Db1x00";
}
#endif
#ifdef CONFIG_MIPS_MIRAGE
char irq_tab_alchemy[][5] __initdata = {
[11] = { -1, AU1500_PCI_INTD, 0xff, 0xff, 0xff }, /* IDSEL 11 - SMI VGX */
[12] = { -1, 0xff, 0xff, AU1500_PCI_INTC, 0xff }, /* IDSEL 12 - PNX1300 */
[13] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff }, /* IDSEL 13 - miniPCI */
};
static void mirage_power_off(void)
{
alchemy_gpio_direction_output(210, 1);
}
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));
}
void board_reset(void)
#else
const char *get_system_type(void)
{
/* Hit BCSR.SW_RESET[RESET] */
bcsr->swreset = 0x0000;
return "Alchemy Db1x00";
}
#endif
void __init board_setup(void)
{
u32 pin_func = 0;
char *argptr;
argptr = prom_getcmdline();
#ifdef CONFIG_SERIAL_8250_CONSOLE
argptr = strstr(argptr, "console=");
if (argptr == NULL) {
argptr = prom_getcmdline();
strcat(argptr, " console=ttyS0,115200");
}
unsigned long bcsr1, bcsr2;
u32 pin_func;
bcsr1 = DB1000_BCSR_PHYS_ADDR;
bcsr2 = DB1000_BCSR_PHYS_ADDR + DB1000_BCSR_HEXLED_OFS;
pin_func = 0;
#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);
#ifdef CONFIG_FB_AU1100
argptr = strstr(argptr, "video=");
if (argptr == NULL) {
argptr = prom_getcmdline();
/* default panel */
/*strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16");*/
}
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");
#if defined(CONFIG_SOUND_AU1X00) && !defined(CONFIG_SOC_AU1000)
/* au1000 does not support vra, au1500 and au1100 do */
strcat(argptr, " au1000_audio=vra");
argptr = prom_getcmdline();
bcsr1 = DB1550_BCSR_PHYS_ADDR;
bcsr2 = DB1550_BCSR_PHYS_ADDR + DB1550_BCSR_HEXLED_OFS;
#endif
/* initialize board register space */
bcsr_init(bcsr1, bcsr2);
/* Not valid for Au1550 */
#if defined(CONFIG_IRDA) && \
(defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1100))
......@@ -89,11 +169,10 @@ void __init board_setup(void)
pin_func = au_readl(SYS_PINFUNC) | SYS_PF_IRF;
au_writel(pin_func, SYS_PINFUNC);
/* Power off until the driver is in use */
bcsr->resets &= ~BCSR_RESETS_IRDA_MODE_MASK;
bcsr->resets |= BCSR_RESETS_IRDA_MODE_OFF;
au_sync();
bcsr_mod(BCSR_RESETS, BCSR_RESETS_IRDA_MODE_MASK,
BCSR_RESETS_IRDA_MODE_OFF);
#endif
bcsr->pcmcia = 0x0000; /* turn off PCMCIA power */
bcsr_write(BCSR_PCMCIA, 0); /* turn off PCMCIA power */
/* Enable GPIO[31:0] inputs */
alchemy_gpio1_input_enable();
......@@ -120,26 +199,53 @@ void __init board_setup(void)
* be part of the audio driver.
*/
alchemy_gpio_direction_output(209, 1);
#endif
au_sync();
#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");
pm_power_off = mirage_power_off;
_machine_halt = mirage_power_off;
_machine_restart = (void(*)(char *))mips_softreset;
#endif
#ifdef CONFIG_MIPS_BOSPORUS
printk(KERN_INFO "AMD Alchemy Bosporus Board\n");
pm_power_off = bosporus_power_off;
_machine_halt = bosporus_power_off;
_machine_restart = (void(*)(char *))mips_softreset;
#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");
au_sync();
}
static int __init db1x00_init_irq(void)
{
#if defined(CONFIG_MIPS_MIRAGE)
set_irq_type(AU1500_GPIO7_INT, IRQF_TRIGGER_RISING); /* TS pendown */
#elif defined(CONFIG_MIPS_DB1550)
set_irq_type(AU1550_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */
set_irq_type(AU1550_GPIO1_INT, IRQF_TRIGGER_LOW); /* CD1# */
set_irq_type(AU1550_GPIO3_INT, IRQF_TRIGGER_LOW); /* CARD0# */
set_irq_type(AU1550_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */
set_irq_type(AU1550_GPIO21_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
set_irq_type(AU1550_GPIO22_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */
#elif defined(CONFIG_MIPS_DB1500)
set_irq_type(AU1500_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */
set_irq_type(AU1500_GPIO3_INT, IRQF_TRIGGER_LOW); /* CD1# */
set_irq_type(AU1500_GPIO2_INT, IRQF_TRIGGER_LOW); /* CARD0# */
set_irq_type(AU1500_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */
set_irq_type(AU1500_GPIO1_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
set_irq_type(AU1500_GPIO4_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */
#elif defined(CONFIG_MIPS_DB1100)
set_irq_type(AU1100_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */
set_irq_type(AU1100_GPIO3_INT, IRQF_TRIGGER_LOW); /* CD1# */
set_irq_type(AU1100_GPIO2_INT, IRQF_TRIGGER_LOW); /* CARD0# */
set_irq_type(AU1100_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */
set_irq_type(AU1100_GPIO1_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
set_irq_type(AU1100_GPIO4_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */
#elif defined(CONFIG_MIPS_DB1000)
set_irq_type(AU1000_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */
set_irq_type(AU1000_GPIO3_INT, IRQF_TRIGGER_LOW); /* CD1# */
set_irq_type(AU1000_GPIO2_INT, IRQF_TRIGGER_LOW); /* CARD0# */
set_irq_type(AU1000_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */
set_irq_type(AU1000_GPIO1_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
set_irq_type(AU1000_GPIO4_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */
#endif
return 0;
}
arch_initcall(db1x00_init_irq);
/*
* BRIEF MODULE DESCRIPTION
* Au1xxx irq map table
*
* Copyright 2003 Embedded Edge, LLC
* dan@embeddededge.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>
#ifdef CONFIG_MIPS_DB1500
char irq_tab_alchemy[][5] __initdata = {
[12] = { -1, INTA, INTX, INTX, INTX }, /* IDSEL 12 - HPT371 */
[13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot */
};
#endif
#ifdef CONFIG_MIPS_BOSPORUS
char irq_tab_alchemy[][5] __initdata = {
[11] = { -1, INTA, INTB, INTX, INTX }, /* IDSEL 11 - miniPCI */
[12] = { -1, INTA, INTX, INTX, INTX }, /* IDSEL 12 - SN1741 */
[13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot */
};
#endif
#ifdef CONFIG_MIPS_MIRAGE
char irq_tab_alchemy[][5] __initdata = {
[11] = { -1, INTD, INTX, INTX, INTX }, /* IDSEL 11 - SMI VGX */
[12] = { -1, INTX, INTX, INTC, INTX }, /* IDSEL 12 - PNX1300 */
[13] = { -1, INTA, INTB, INTX, INTX }, /* IDSEL 13 - miniPCI */
};
#endif
#ifdef CONFIG_MIPS_DB1550
char irq_tab_alchemy[][5] __initdata = {
[11] = { -1, INTC, INTX, INTX, INTX }, /* IDSEL 11 - on-board HPT371 */
[12] = { -1, INTB, INTC, INTD, INTA }, /* IDSEL 12 - PCI slot 2 (left) */
[13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot 1 (right) */
};
#endif
struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
#ifndef CONFIG_MIPS_MIRAGE
#ifdef CONFIG_MIPS_DB1550
{ AU1000_GPIO_3, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 0 IRQ# */
{ AU1000_GPIO_5, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 1 IRQ# */
#else
{ AU1000_GPIO_0, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 0 Fully_Interted# */
{ AU1000_GPIO_1, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 0 STSCHG# */
{ AU1000_GPIO_2, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 0 IRQ# */
{ AU1000_GPIO_3, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 1 Fully_Interted# */
{ AU1000_GPIO_4, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 1 STSCHG# */
{ AU1000_GPIO_5, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 1 IRQ# */
#endif
#else
{ AU1000_GPIO_7, IRQF_TRIGGER_RISING, 0 }, /* touchscreen pen down */
#endif
};
void __init board_init_irq(void)
{
au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map));
}
/*
* 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/platform_device.h>
#include <asm/mach-au1x00/au1xxx.h>
#include <asm/mach-db1x00/bcsr.h>
#include "../platform.h"
/* 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
static int __init db1xxx_dev_init(void)
{
#ifdef DB1XXX_HAS_PCMCIA
db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR,
PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
PCMCIA_MEM_PHYS_ADDR,
PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
PCMCIA_IO_PHYS_ADDR,
PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
DB1XXX_PCMCIA_CARD0,
DB1XXX_PCMCIA_CD0,
/*DB1XXX_PCMCIA_STSCHG0*/0,
0,
0);
db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR + 0x004000000,
PCMCIA_ATTR_PHYS_ADDR + 0x004400000 - 1,
PCMCIA_MEM_PHYS_ADDR + 0x004000000,
PCMCIA_MEM_PHYS_ADDR + 0x004400000 - 1,
PCMCIA_IO_PHYS_ADDR + 0x004000000,
PCMCIA_IO_PHYS_ADDR + 0x004010000 - 1,
DB1XXX_PCMCIA_CARD1,
DB1XXX_PCMCIA_CD1,
/*DB1XXX_PCMCIA_STSCHG1*/0,
0,
1);
#endif
db1x_register_norflash(BOARD_FLASH_SIZE, BOARD_FLASH_WIDTH, F_SWAPPED);
return 0;
}
device_initcall(db1xxx_dev_init);
......@@ -31,11 +31,7 @@
#include <asm/mach-pb1x00/pb1000.h>
#include <prom.h>
struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
{ AU1000_GPIO_15, IRQF_TRIGGER_LOW, 0 },
};
#include "../platform.h"
const char *get_system_type(void)
{
......@@ -46,25 +42,14 @@ void board_reset(void)
{
}
void __init board_init_irq(void)
{
au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map));
}
void __init board_setup(void)
{
u32 pin_func, static_cfg0;
u32 sys_freqctrl, sys_clksrc;
u32 prid = read_c0_prid();
#ifdef CONFIG_SERIAL_8250_CONSOLE
char *argptr = prom_getcmdline();
argptr = strstr(argptr, "console=");
if (argptr == NULL) {
argptr = prom_getcmdline();
strcat(argptr, " console=ttyS0,115200");
}
#endif
sys_freqctrl = 0;
sys_clksrc = 0;
/* Set AUX clock to 12 MHz * 8 = 96 MHz */
au_writel(8, SYS_AUXPLL);
......@@ -193,3 +178,16 @@ void __init board_setup(void)
break;
}
}
static int __init pb1000_init_irq(void)
{
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);
......@@ -5,4 +5,4 @@
# Makefile for the Alchemy Semiconductor Pb1100 board.
#
obj-y := board_setup.o
obj-y := board_setup.o platform.o
......@@ -29,19 +29,11 @@
#include <linux/interrupt.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-pb1x00/pb1100.h>
#include <asm/mach-db1x00/bcsr.h>
#include <prom.h>
struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
{ AU1000_GPIO_9, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card Fully_Inserted# */
{ AU1000_GPIO_10, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card STSCHG# */
{ AU1000_GPIO_11, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card IRQ# */
{ AU1000_GPIO_13, IRQF_TRIGGER_LOW, 0 }, /* DC_IRQ# */
};
const char *get_system_type(void)
{
return "Alchemy Pb1100";
......@@ -49,43 +41,15 @@ const char *get_system_type(void)
void board_reset(void)
{
/* Hit BCSR.RST_VDDI[SOFT_RESET] */
au_writel(0x00000000, PB1100_RST_VDDI);
}
void __init board_init_irq(void)
{
au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map));
bcsr_write(BCSR_SYSTEM, 0);
}
void __init board_setup(void)
{
volatile void __iomem *base = (volatile void __iomem *)0xac000000UL;
char *argptr;
argptr = prom_getcmdline();
#ifdef CONFIG_SERIAL_8250_CONSOLE
argptr = strstr(argptr, "console=");
if (argptr == NULL) {
argptr = prom_getcmdline();
strcat(argptr, " console=ttyS0,115200");
}
#endif
#ifdef CONFIG_FB_AU1100
argptr = strstr(argptr, "video=");
if (argptr == NULL) {
argptr = prom_getcmdline();
/* default panel */
/*strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16");*/
}
#endif
#if defined(CONFIG_SOUND_AU1X00) && !defined(CONFIG_SOC_AU1000)
/* au1000 does not support vra, au1500 and au1100 do */
strcat(argptr, " au1000_audio=vra");
argptr = prom_getcmdline();
#endif
bcsr_init(DB1000_BCSR_PHYS_ADDR,
DB1000_BCSR_PHYS_ADDR + DB1000_BCSR_HEXLED_OFS);
/* Set AUX clock to 12 MHz * 8 = 96 MHz */
au_writel(8, SYS_AUXPLL);
......@@ -155,3 +119,14 @@ void __init board_setup(void)
au_sync();
}
}
static int __init pb1100_init_irq(void)
{
set_irq_type(AU1100_GPIO9_INT, IRQF_TRIGGER_LOW); /* PCCD# */
set_irq_type(AU1100_GPIO10_INT, IRQF_TRIGGER_LOW); /* PCSTSCHG# */
set_irq_type(AU1100_GPIO11_INT, IRQF_TRIGGER_LOW); /* PCCard# */
set_irq_type(AU1100_GPIO13_INT, IRQF_TRIGGER_LOW); /* DC_IRQ# */
return 0;
}
arch_initcall(pb1100_init_irq);
/*
* 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 <asm/mach-au1x00/au1000.h>
#include <asm/mach-db1x00/bcsr.h>
#include "../platform.h"
static int __init pb1100_dev_init(void)
{
int swapped;
/* PCMCIA. single socket, identical to Pb1500 */
db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR,
PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
PCMCIA_MEM_PHYS_ADDR,
PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
PCMCIA_IO_PHYS_ADDR,
PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
AU1100_GPIO11_INT, /* card */
AU1100_GPIO9_INT, /* insert */
/*AU1100_GPIO10_INT*/0, /* stschg */
0, /* eject */
0); /* id */
swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT;
db1x_register_norflash(64 * 1024 * 1024, 4, swapped);
return 0;
}
device_initcall(pb1100_dev_init);
......@@ -2,6 +2,6 @@
# Makefile for the Alchemy Semiconductor Pb1200/DBAu1200 boards.
#
obj-y := board_setup.o irqmap.o platform.o
obj-y := board_setup.o platform.o
EXTRA_CFLAGS += -Werror
......@@ -25,11 +25,23 @@
*/
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <prom.h>
#include <au1xxx.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)
{
......@@ -38,25 +50,15 @@ const char *get_system_type(void)
void board_reset(void)
{
bcsr->resets = 0;
bcsr->system = 0;
bcsr_write(BCSR_RESETS, 0);
bcsr_write(BCSR_SYSTEM, 0);
}
void __init board_setup(void)
{
char *argptr;
argptr = prom_getcmdline();
#ifdef CONFIG_SERIAL_8250_CONSOLE
argptr = strstr(argptr, "console=");
if (argptr == NULL) {
argptr = prom_getcmdline();
strcat(argptr, " console=ttyS0,115200");
}
#endif
#ifdef CONFIG_FB_AU1200
strcat(argptr, " video=au1200fb:panel:bs");
#endif
printk(KERN_INFO "AMD Alchemy Pb1200 Board\n");
bcsr_init(PB1200_BCSR_PHYS_ADDR,
PB1200_BCSR_PHYS_ADDR + PB1200_BCSR_HEXLED_OFS);
#if 0
{
......@@ -82,7 +84,7 @@ void __init board_setup(void)
u32 pin_func;
/* Select SMBus in CPLD */
bcsr->resets &= ~BCSR_RESETS_PCS0MUX;
bcsr_mod(BCSR_RESETS, BCSR_RESETS_PSC0MUX, 0);
pin_func = au_readl(SYS_PINFUNC);
au_sync();
......@@ -116,38 +118,54 @@ void __init board_setup(void)
/*
* The Pb1200 development board uses external MUX for PSC0 to
* support SMB/SPI. bcsr->resets bit 12: 0=SMB 1=SPI
* support SMB/SPI. bcsr_resets bit 12: 0=SMB 1=SPI
*/
#ifdef CONFIG_I2C_AU1550
bcsr->resets &= ~BCSR_RESETS_PCS0MUX;
bcsr_mod(BCSR_RESETS, BCSR_RESETS_PSC0MUX, 0);
#endif
au_sync();
}
#ifdef CONFIG_MIPS_PB1200
printk(KERN_INFO "AMD Alchemy Pb1200 Board\n");
#endif
#ifdef CONFIG_MIPS_DB1200
printk(KERN_INFO "AMD Alchemy Db1200 Board\n");
#endif
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.");
}
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)
{
BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR;
int p;
p = bcsr->switches;
p >>= 8;
p &= 0x0F;
return p;
return (bcsr_read(BCSR_SWITCHES) >> 8) & 0x0f;
}
int board_au1200fb_panel_init(void)
{
/* Apply power */
BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR;
bcsr->board |= BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD | BCSR_BOARD_LCDBL;
bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD |
BCSR_BOARD_LCDBL);
/* printk(KERN_DEBUG "board_au1200fb_panel_init()\n"); */
return 0;
}
......@@ -155,10 +173,8 @@ int board_au1200fb_panel_init(void)
int board_au1200fb_panel_shutdown(void)
{
/* Remove power */
BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR;
bcsr->board &= ~(BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD |
BCSR_BOARD_LCDBL);
bcsr_mod(BCSR_BOARD, BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD |
BCSR_BOARD_LCDBL, 0);
/* printk(KERN_DEBUG "board_au1200fb_panel_shutdown()\n"); */
return 0;
}
/*
* BRIEF MODULE DESCRIPTION
* Au1xxx irq map table
*
* 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>
#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
struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
/* This is external interrupt cascade */
{ AU1000_GPIO_7, IRQF_TRIGGER_LOW, 0 },
};
/*
* Support for External interrupts on the Pb1200 Development platform.
*/
static void pb1200_cascade_handler(unsigned int irq, struct irq_desc *d)
{
unsigned short bisr = bcsr->int_status;
for ( ; bisr; bisr &= bisr - 1)
generic_handle_irq(PB1200_INT_BEGIN + __ffs(bisr));
}
/* NOTE: both the enable and mask bits must be cleared, otherwise the
* CPLD generates tons of spurious interrupts (at least on the DB1200).
*/
static void pb1200_mask_irq(unsigned int irq_nr)
{
bcsr->intclr_mask = 1 << (irq_nr - PB1200_INT_BEGIN);
bcsr->intclr = 1 << (irq_nr - PB1200_INT_BEGIN);
au_sync();
}
static void pb1200_maskack_irq(unsigned int irq_nr)
{
bcsr->intclr_mask = 1 << (irq_nr - PB1200_INT_BEGIN);
bcsr->intclr = 1 << (irq_nr - PB1200_INT_BEGIN);
bcsr->int_status = 1 << (irq_nr - PB1200_INT_BEGIN); /* ack */
au_sync();
}
static void pb1200_unmask_irq(unsigned int irq_nr)
{
bcsr->intset = 1 << (irq_nr - PB1200_INT_BEGIN);
bcsr->intset_mask = 1 << (irq_nr - PB1200_INT_BEGIN);
au_sync();
}
static struct irq_chip pb1200_cpld_irq_type = {
#ifdef CONFIG_MIPS_PB1200
.name = "Pb1200 Ext",
#endif
#ifdef CONFIG_MIPS_DB1200
.name = "Db1200 Ext",
#endif
.mask = pb1200_mask_irq,
.mask_ack = pb1200_maskack_irq,
.unmask = pb1200_unmask_irq,
};
void __init board_init_irq(void)
{
unsigned int irq;
au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map));
#ifdef CONFIG_MIPS_PB1200
/* We have a problem with CPLD rev 3. */
if (((bcsr->whoami & BCSR_WHOAMI_CPLD) >> 4) <= 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.");
}
#endif
/* mask & disable & ack all */
bcsr->intclr_mask = 0xffff;
bcsr->intclr = 0xffff;
bcsr->int_status = 0xffff;
au_sync();
for (irq = PB1200_INT_BEGIN; irq <= PB1200_INT_END; irq++)
set_irq_chip_and_handler_name(irq, &pb1200_cpld_irq_type,
handle_level_irq, "level");
set_irq_chained_handler(AU1000_GPIO_7, pb1200_cascade_handler);
}
......@@ -26,27 +26,30 @@
#include <asm/mach-au1x00/au1xxx.h>
#include <asm/mach-au1x00/au1100_mmc.h>
#include <asm/mach-db1x00/bcsr.h>
#include "../platform.h"
static int mmc_activity;
static void pb1200mmc0_set_power(void *mmc_host, int state)
{
if (state)
bcsr->board |= BCSR_BOARD_SD0PWR;
bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_SD0PWR);
else
bcsr->board &= ~BCSR_BOARD_SD0PWR;
bcsr_mod(BCSR_BOARD, BCSR_BOARD_SD0PWR, 0);
au_sync_delay(1);
msleep(1);
}
static int pb1200mmc0_card_readonly(void *mmc_host)
{
return (bcsr->status & BCSR_STATUS_SD0WP) ? 1 : 0;
return (bcsr_read(BCSR_STATUS) & BCSR_STATUS_SD0WP) ? 1 : 0;
}
static int pb1200mmc0_card_inserted(void *mmc_host)
{
return (bcsr->sig_status & BCSR_INT_SD0INSERT) ? 1 : 0;
return (bcsr_read(BCSR_SIGSTAT) & BCSR_INT_SD0INSERT) ? 1 : 0;
}
static void pb1200_mmcled_set(struct led_classdev *led,
......@@ -54,10 +57,10 @@ static void pb1200_mmcled_set(struct led_classdev *led,
{
if (brightness != LED_OFF) {
if (++mmc_activity == 1)
bcsr->disk_leds &= ~(1 << 8);
bcsr_mod(BCSR_LEDS, BCSR_LEDS_LED0, 0);
} else {
if (--mmc_activity == 0)
bcsr->disk_leds |= (1 << 8);
bcsr_mod(BCSR_LEDS, 0, BCSR_LEDS_LED0);
}
}
......@@ -65,27 +68,25 @@ static struct led_classdev pb1200mmc_led = {
.brightness_set = pb1200_mmcled_set,
};
#ifndef CONFIG_MIPS_DB1200
static void pb1200mmc1_set_power(void *mmc_host, int state)
{
if (state)
bcsr->board |= BCSR_BOARD_SD1PWR;
bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_SD1PWR);
else
bcsr->board &= ~BCSR_BOARD_SD1PWR;
bcsr_mod(BCSR_BOARD, BCSR_BOARD_SD1PWR, 0);
au_sync_delay(1);
msleep(1);
}
static int pb1200mmc1_card_readonly(void *mmc_host)
{
return (bcsr->status & BCSR_STATUS_SD1WP) ? 1 : 0;
return (bcsr_read(BCSR_STATUS) & BCSR_STATUS_SD1WP) ? 1 : 0;
}
static int pb1200mmc1_card_inserted(void *mmc_host)
{
return (bcsr->sig_status & BCSR_INT_SD1INSERT) ? 1 : 0;
return (bcsr_read(BCSR_SIGSTAT) & BCSR_INT_SD1INSERT) ? 1 : 0;
}
#endif
const struct au1xmmc_platform_data au1xmmc_platdata[2] = {
[0] = {
......@@ -95,7 +96,6 @@ const struct au1xmmc_platform_data au1xmmc_platdata[2] = {
.cd_setup = NULL, /* use poll-timer in driver */
.led = &pb1200mmc_led,
},
#ifndef CONFIG_MIPS_DB1200
[1] = {
.set_power = pb1200mmc1_set_power,
.card_inserted = pb1200mmc1_card_inserted,
......@@ -103,7 +103,6 @@ const struct au1xmmc_platform_data au1xmmc_platdata[2] = {
.cd_setup = NULL, /* use poll-timer in driver */
.led = &pb1200mmc_led,
},
#endif
};
static struct resource ide_resources[] = {
......@@ -169,8 +168,36 @@ static struct platform_device *board_platform_devices[] __initdata = {
static int __init board_register_devices(void)
{
int swapped;
db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR,
PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
PCMCIA_MEM_PHYS_ADDR,
PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
PCMCIA_IO_PHYS_ADDR,
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(PCMCIA_ATTR_PHYS_ADDR + 0x008000000,
PCMCIA_ATTR_PHYS_ADDR + 0x008400000 - 1,
PCMCIA_MEM_PHYS_ADDR + 0x008000000,
PCMCIA_MEM_PHYS_ADDR + 0x008400000 - 1,
PCMCIA_IO_PHYS_ADDR + 0x008000000,
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));
}
arch_initcall(board_register_devices);
device_initcall(board_register_devices);
......@@ -5,4 +5,4 @@
# Makefile for the Alchemy Semiconductor Pb1500 board.
#
obj-y := board_setup.o
obj-y := board_setup.o platform.o
......@@ -29,22 +29,14 @@
#include <linux/interrupt.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-pb1x00/pb1500.h>
#include <asm/mach-db1x00/bcsr.h>
#include <prom.h>
char irq_tab_alchemy[][5] __initdata = {
[12] = { -1, INTA, INTX, INTX, INTX }, /* IDSEL 12 - HPT370 */
[13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot */
};
struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
{ AU1500_GPIO_204, IRQF_TRIGGER_HIGH, 0 },
{ AU1500_GPIO_201, IRQF_TRIGGER_LOW, 0 },
{ AU1500_GPIO_202, IRQF_TRIGGER_LOW, 0 },
{ AU1500_GPIO_203, IRQF_TRIGGER_LOW, 0 },
{ AU1500_GPIO_205, IRQF_TRIGGER_LOW, 0 },
[12] = { -1, AU1500_PCI_INTA, 0xff, 0xff, 0xff }, /* IDSEL 12 - HPT370 */
[13] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, AU1500_PCI_INTC, AU1500_PCI_INTD }, /* IDSEL 13 - PCI slot */
};
......@@ -55,35 +47,16 @@ const char *get_system_type(void)
void board_reset(void)
{
/* Hit BCSR.RST_VDDI[SOFT_RESET] */
au_writel(0x00000000, PB1500_RST_VDDI);
}
void __init board_init_irq(void)
{
au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map));
bcsr_write(BCSR_SYSTEM, 0);
}
void __init board_setup(void)
{
u32 pin_func;
u32 sys_freqctrl, sys_clksrc;
char *argptr;
argptr = prom_getcmdline();
#ifdef CONFIG_SERIAL_8250_CONSOLE
argptr = strstr(argptr, "console=");
if (argptr == NULL) {
argptr = prom_getcmdline();
strcat(argptr, " console=ttyS0,115200");
}
#endif
#if defined(CONFIG_SOUND_AU1X00) && !defined(CONFIG_SOC_AU1000)
/* au1000 does not support vra, au1500 and au1100 do */
strcat(argptr, " au1000_audio=vra");
argptr = prom_getcmdline();
#endif
bcsr_init(DB1000_BCSR_PHYS_ADDR,
DB1000_BCSR_PHYS_ADDR + DB1000_BCSR_HEXLED_OFS);
sys_clksrc = sys_freqctrl = pin_func = 0;
/* Set AUX clock to 12 MHz * 8 = 96 MHz */
......@@ -163,3 +136,18 @@ void __init board_setup(void)
au_sync();
}
}
static int __init pb1500_init_irq(void)
{
set_irq_type(AU1500_GPIO9_INT, IRQF_TRIGGER_LOW); /* CD0# */
set_irq_type(AU1500_GPIO10_INT, IRQF_TRIGGER_LOW); /* CARD0 */
set_irq_type(AU1500_GPIO11_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH);
set_irq_type(AU1500_GPIO201_INT, IRQF_TRIGGER_LOW);
set_irq_type(AU1500_GPIO202_INT, IRQF_TRIGGER_LOW);
set_irq_type(AU1500_GPIO203_INT, IRQF_TRIGGER_LOW);
set_irq_type(AU1500_GPIO205_INT, IRQF_TRIGGER_LOW);
return 0;
}
arch_initcall(pb1500_init_irq);
/*
* 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/init.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-db1x00/bcsr.h>
#include "../platform.h"
static int __init pb1500_dev_init(void)
{
int swapped;
/* PCMCIA. single socket, identical to Pb1500 */
db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR,
PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
PCMCIA_MEM_PHYS_ADDR,
PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
PCMCIA_IO_PHYS_ADDR,
PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
AU1500_GPIO11_INT, /* card */
AU1500_GPIO9_INT, /* insert */
/*AU1500_GPIO10_INT*/0, /* stschg */
0, /* eject */
0); /* id */
swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT;
db1x_register_norflash(64 * 1024 * 1024, 4, swapped);
return 0;
}
device_initcall(pb1500_dev_init);
......@@ -5,4 +5,4 @@
# Makefile for the Alchemy Semiconductor Pb1550 board.
#
obj-y := board_setup.o
obj-y := board_setup.o platform.o
......@@ -32,18 +32,15 @@
#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>
char irq_tab_alchemy[][5] __initdata = {
[12] = { -1, INTB, INTC, INTD, INTA }, /* IDSEL 12 - PCI slot 2 (left) */
[13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot 1 (right) */
};
struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
{ AU1000_GPIO_0, IRQF_TRIGGER_LOW, 0 },
{ AU1000_GPIO_1, IRQF_TRIGGER_LOW, 0 },
[12] = { -1, AU1550_PCI_INTB, AU1550_PCI_INTC, AU1550_PCI_INTD, AU1550_PCI_INTA }, /* IDSEL 12 - PCI slot 2 (left) */
[13] = { -1, AU1550_PCI_INTA, AU1550_PCI_INTB, AU1550_PCI_INTC, AU1550_PCI_INTD }, /* IDSEL 13 - PCI slot 1 (right) */
};
const char *get_system_type(void)
......@@ -53,28 +50,17 @@ const char *get_system_type(void)
void board_reset(void)
{
/* Hit BCSR.SYSTEM[RESET] */
au_writew(au_readw(0xAF00001C) & ~BCSR_SYSTEM_RESET, 0xAF00001C);
}
void __init board_init_irq(void)
{
au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map));
bcsr_write(BCSR_SYSTEM, 0);
}
void __init board_setup(void)
{
u32 pin_func;
#ifdef CONFIG_SERIAL_8250_CONSOLE
char *argptr;
argptr = prom_getcmdline();
argptr = strstr(argptr, "console=");
if (argptr == NULL) {
argptr = prom_getcmdline();
strcat(argptr, " console=ttyS0,115200");
}
#endif
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,
......@@ -85,8 +71,21 @@ void __init board_setup(void)
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();
bcsr_write(BCSR_PCMCIA, 0); /* turn off PCMCIA power */
printk(KERN_INFO "AMD Alchemy Pb1550 Board\n");
}
static int __init pb1550_init_irq(void)
{
set_irq_type(AU1550_GPIO0_INT, IRQF_TRIGGER_LOW);
set_irq_type(AU1550_GPIO1_INT, IRQF_TRIGGER_LOW);
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);
/*
* Pb1550 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 <asm/mach-au1x00/au1000.h>
#include <asm/mach-pb1x00/pb1550.h>
#include <asm/mach-db1x00/bcsr.h>
#include "../platform.h"
static int __init pb1550_dev_init(void)
{
int swapped;
/* 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
* use the GPIO201_205 exclusively for card interrupts, since a) pcmcia
* drivers are used to shared irqs and b) statuschange isn't really use-
* ful anyway.
*/
db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR,
PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
PCMCIA_MEM_PHYS_ADDR,
PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
PCMCIA_IO_PHYS_ADDR,
PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
AU1550_GPIO201_205_INT,
AU1550_GPIO0_INT,
0,
0,
0);
db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR + 0x008000000,
PCMCIA_ATTR_PHYS_ADDR + 0x008400000 - 1,
PCMCIA_MEM_PHYS_ADDR + 0x008000000,
PCMCIA_MEM_PHYS_ADDR + 0x008400000 - 1,
PCMCIA_IO_PHYS_ADDR + 0x008000000,
PCMCIA_IO_PHYS_ADDR + 0x008010000 - 1,
AU1550_GPIO201_205_INT,
AU1550_GPIO1_INT,
0,
0,
1);
swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_PB1550_SWAPBOOT;
db1x_register_norflash(128 * 1024 * 1024, 4, swapped);
return 0;
}
device_initcall(pb1550_dev_init);
/*
* devoard misc stuff.
*/
#include <linux/init.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/physmap.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <asm/reboot.h>
#include <asm/mach-db1x00/bcsr.h>
static void db1x_power_off(void)
{
bcsr_write(BCSR_RESETS, 0);
bcsr_write(BCSR_SYSTEM, BCSR_SYSTEM_PWROFF | BCSR_SYSTEM_RESET);
}
static void db1x_reset(char *c)
{
bcsr_write(BCSR_RESETS, 0);
bcsr_write(BCSR_SYSTEM, 0);
}
static int __init db1x_poweroff_setup(void)
{
if (!pm_power_off)
pm_power_off = db1x_power_off;
if (!_machine_halt)
_machine_halt = db1x_power_off;
if (!_machine_restart)
_machine_restart = db1x_reset;
return 0;
}
late_initcall(db1x_poweroff_setup);
/* register a pcmcia socket */
int __init db1x_register_pcmcia_socket(phys_addr_t pcmcia_attr_start,
phys_addr_t pcmcia_attr_end,
phys_addr_t pcmcia_mem_start,
phys_addr_t pcmcia_mem_end,
phys_addr_t pcmcia_io_start,
phys_addr_t pcmcia_io_end,
int card_irq,
int cd_irq,
int stschg_irq,
int eject_irq,
int id)
{
int cnt, i, ret;
struct resource *sr;
struct platform_device *pd;
cnt = 5;
if (eject_irq)
cnt++;
if (stschg_irq)
cnt++;
sr = kzalloc(sizeof(struct resource) * cnt, GFP_KERNEL);
if (!sr)
return -ENOMEM;
pd = platform_device_alloc("db1xxx_pcmcia", id);
if (!pd) {
ret = -ENOMEM;
goto out;
}
sr[0].name = "pcmcia-attr";
sr[0].flags = IORESOURCE_MEM;
sr[0].start = pcmcia_attr_start;
sr[0].end = pcmcia_attr_end;
sr[1].name = "pcmcia-mem";
sr[1].flags = IORESOURCE_MEM;
sr[1].start = pcmcia_mem_start;
sr[1].end = pcmcia_mem_end;
sr[2].name = "pcmcia-io";
sr[2].flags = IORESOURCE_MEM;
sr[2].start = pcmcia_io_start;
sr[2].end = pcmcia_io_end;
sr[3].name = "insert";
sr[3].flags = IORESOURCE_IRQ;
sr[3].start = sr[3].end = cd_irq;
sr[4].name = "card";
sr[4].flags = IORESOURCE_IRQ;
sr[4].start = sr[4].end = card_irq;
i = 5;
if (stschg_irq) {
sr[i].name = "stschg";
sr[i].flags = IORESOURCE_IRQ;
sr[i].start = sr[i].end = stschg_irq;
i++;
}
if (eject_irq) {
sr[i].name = "eject";
sr[i].flags = IORESOURCE_IRQ;
sr[i].start = sr[i].end = eject_irq;
}
pd->resource = sr;
pd->num_resources = cnt;
ret = platform_device_add(pd);
if (!ret)
return 0;
platform_device_put(pd);
out:
kfree(sr);
return ret;
}
#define YAMON_SIZE 0x00100000
#define YAMON_ENV_SIZE 0x00040000
int __init db1x_register_norflash(unsigned long size, int width,
int swapped)
{
struct physmap_flash_data *pfd;
struct platform_device *pd;
struct mtd_partition *parts;
struct resource *res;
int ret, i;
if (size < (8 * 1024 * 1024))
return -EINVAL;
ret = -ENOMEM;
parts = kzalloc(sizeof(struct mtd_partition) * 5, GFP_KERNEL);
if (!parts)
goto out;
res = kzalloc(sizeof(struct resource), GFP_KERNEL);
if (!res)
goto out1;
pfd = kzalloc(sizeof(struct physmap_flash_data), GFP_KERNEL);
if (!pfd)
goto out2;
pd = platform_device_alloc("physmap-flash", 0);
if (!pd)
goto out3;
/* NOR flash ends at 0x20000000, regardless of size */
res->start = 0x20000000 - size;
res->end = 0x20000000 - 1;
res->flags = IORESOURCE_MEM;
/* partition setup. Most Develboards have a switch which allows
* to swap the physical locations of the 2 NOR flash banks.
*/
i = 0;
if (!swapped) {
/* first NOR chip */
parts[i].offset = 0;
parts[i].name = "User FS";
parts[i].size = size / 2;
i++;
}
parts[i].offset = MTDPART_OFS_APPEND;
parts[i].name = "User FS 2";
parts[i].size = (size / 2) - (0x20000000 - 0x1fc00000);
i++;
parts[i].offset = MTDPART_OFS_APPEND;
parts[i].name = "YAMON";
parts[i].size = YAMON_SIZE;
parts[i].mask_flags = MTD_WRITEABLE;
i++;
parts[i].offset = MTDPART_OFS_APPEND;
parts[i].name = "raw kernel";
parts[i].size = 0x00400000 - YAMON_SIZE - YAMON_ENV_SIZE;
i++;
parts[i].offset = MTDPART_OFS_APPEND;
parts[i].name = "YAMON Env";
parts[i].size = YAMON_ENV_SIZE;
parts[i].mask_flags = MTD_WRITEABLE;
i++;
if (swapped) {
parts[i].offset = MTDPART_OFS_APPEND;
parts[i].name = "User FS";
parts[i].size = size / 2;
i++;
}
pfd->width = width;
pfd->parts = parts;
pfd->nr_parts = 5;
pd->dev.platform_data = pfd;
pd->resource = res;
pd->num_resources = 1;
ret = platform_device_add(pd);
if (!ret)
return ret;
platform_device_put(pd);
out3:
kfree(pfd);
out2:
kfree(res);
out1:
kfree(parts);
out:
return ret;
}
#ifndef _DEVBOARD_PLATFORM_H_
#define _DEVBOARD_PLATFORM_H_
#include <linux/init.h>
int __init db1x_register_pcmcia_socket(phys_addr_t pcmcia_attr_start,
phys_addr_t pcmcia_attr_len,
phys_addr_t pcmcia_mem_start,
phys_addr_t pcmcia_mem_end,
phys_addr_t pcmcia_io_start,
phys_addr_t pcmcia_io_end,
int card_irq,
int cd_irq,
int stschg_irq,
int eject_irq,
int id);
int __init db1x_register_norflash(unsigned long size, int width,
int swapped);
#endif
......@@ -10,6 +10,7 @@
#include <linux/sysfs.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/gpio.h>
#include <asm/mach-db1x00/bcsr.h>
/*
* Generic suspend userspace interface for Alchemy development boards.
......@@ -26,6 +27,20 @@ static unsigned long db1x_pm_last_wakesrc;
static int db1x_pm_enter(suspend_state_t state)
{
unsigned short bcsrs[16];
int i, j, hasint;
/* save CPLD regs */
hasint = bcsr_read(BCSR_WHOAMI);
hasint = BCSR_WHOAMI_BOARD(hasint) >= BCSR_WHOAMI_DB1200;
j = (hasint) ? BCSR_MASKSET : BCSR_SYSTEM;
for (i = BCSR_STATUS; i <= j; i++)
bcsrs[i] = bcsr_read(i);
/* shut off hexleds */
bcsr_write(BCSR_HEXCLEAR, 3);
/* enable GPIO based wakeup */
alchemy_gpio1_input_enable();
......@@ -52,6 +67,23 @@ static int db1x_pm_enter(suspend_state_t state)
/* ...and now the sandman can come! */
au_sleep();
/* restore CPLD regs */
for (i = BCSR_STATUS; i <= BCSR_SYSTEM; i++)
bcsr_write(i, bcsrs[i]);
/* restore CPLD int registers */
if (hasint) {
bcsr_write(BCSR_INTCLR, 0xffff);
bcsr_write(BCSR_MASKCLR, 0xffff);
bcsr_write(BCSR_INTSTAT, 0xffff);
bcsr_write(BCSR_INTSET, bcsrs[BCSR_INTSET]);
bcsr_write(BCSR_MASKSET, bcsrs[BCSR_MASKSET]);
}
/* light up hexleds */
bcsr_write(BCSR_HEXCLEAR, 0);
return 0;
}
......
......@@ -60,3 +60,8 @@ void __init prom_init(void)
strict_strtoul(memsize_str, 0, &memsize);
add_memory_region(0, memsize, BOOT_MEM_RAM);
}
void prom_putchar(unsigned char c)
{
alchemy_uart_putchar(UART0_PHYS_ADDR, c);
}
......@@ -6,7 +6,7 @@
# Makefile for 4G Systems MTX-1 board.
#
lib-y := init.o board_setup.o irqmap.o
lib-y := init.o board_setup.o
obj-y := platform.o
EXTRA_CFLAGS += -Werror
......@@ -30,32 +30,43 @@
#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/pm.h>
#include <asm/reboot.h>
#include <asm/mach-au1x00/au1000.h>
#include <prom.h>
char irq_tab_alchemy[][5] __initdata = {
[0] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTA, 0xff, 0xff }, /* IDSEL 00 - AdapterA-Slot0 (top) */
[1] = { -1, AU1500_PCI_INTB, AU1500_PCI_INTA, 0xff, 0xff }, /* IDSEL 01 - AdapterA-Slot1 (bottom) */
[2] = { -1, AU1500_PCI_INTC, AU1500_PCI_INTD, 0xff, 0xff }, /* IDSEL 02 - AdapterB-Slot0 (top) */
[3] = { -1, AU1500_PCI_INTD, AU1500_PCI_INTC, 0xff, 0xff }, /* IDSEL 03 - AdapterB-Slot1 (bottom) */
[4] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff }, /* IDSEL 04 - AdapterC-Slot0 (top) */
[5] = { -1, AU1500_PCI_INTB, AU1500_PCI_INTA, 0xff, 0xff }, /* IDSEL 05 - AdapterC-Slot1 (bottom) */
[6] = { -1, AU1500_PCI_INTC, AU1500_PCI_INTD, 0xff, 0xff }, /* IDSEL 06 - AdapterD-Slot0 (top) */
[7] = { -1, AU1500_PCI_INTD, AU1500_PCI_INTC, 0xff, 0xff }, /* IDSEL 07 - AdapterD-Slot1 (bottom) */
};
extern int (*board_pci_idsel)(unsigned int devsel, int assert);
int mtx1_pci_idsel(unsigned int devsel, int assert);
void board_reset(void)
static void mtx1_reset(char *c)
{
/* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
au_writel(0x00000000, 0xAE00001C);
}
void __init board_setup(void)
static void mtx1_power_off(void)
{
#ifdef CONFIG_SERIAL_8250_CONSOLE
char *argptr;
argptr = prom_getcmdline();
argptr = strstr(argptr, "console=");
if (argptr == NULL) {
argptr = prom_getcmdline();
strcat(argptr, " console=ttyS0,115200");
}
#endif
printk(KERN_ALERT "It's now safe to remove power\n");
while (1)
asm volatile (".set mips3 ; wait ; .set mips1");
}
void __init board_setup(void)
{
alchemy_gpio2_enable();
#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
......@@ -86,6 +97,10 @@ void __init board_setup(void)
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");
}
......@@ -109,3 +124,15 @@ mtx1_pci_idsel(unsigned int devsel, int assert)
au_sync_udelay(1);
return 1;
}
static int __init mtx1_init_irq(void)
{
set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH);
set_irq_type(AU1500_GPIO201_INT, IRQF_TRIGGER_LOW);
set_irq_type(AU1500_GPIO202_INT, IRQF_TRIGGER_LOW);
set_irq_type(AU1500_GPIO203_INT, IRQF_TRIGGER_LOW);
set_irq_type(AU1500_GPIO205_INT, IRQF_TRIGGER_LOW);
return 0;
}
arch_initcall(mtx1_init_irq);
......@@ -32,6 +32,7 @@
#include <linux/init.h>
#include <asm/bootinfo.h>
#include <asm/mach-au1x00/au1000.h>
#include <prom.h>
......@@ -58,3 +59,8 @@ void __init prom_init(void)
strict_strtoul(memsize_str, 0, &memsize);
add_memory_region(0, memsize, BOOT_MEM_RAM);
}
void prom_putchar(unsigned char c)
{
alchemy_uart_putchar(UART0_PHYS_ADDR, c);
}
/*
* BRIEF MODULE DESCRIPTION
* Au1xxx irq map table
*
* Copyright 2003 Embedded Edge, LLC
* dan@embeddededge.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>
char irq_tab_alchemy[][5] __initdata = {
[0] = { -1, INTA, INTA, INTX, INTX }, /* IDSEL 00 - AdapterA-Slot0 (top) */
[1] = { -1, INTB, INTA, INTX, INTX }, /* IDSEL 01 - AdapterA-Slot1 (bottom) */
[2] = { -1, INTC, INTD, INTX, INTX }, /* IDSEL 02 - AdapterB-Slot0 (top) */
[3] = { -1, INTD, INTC, INTX, INTX }, /* IDSEL 03 - AdapterB-Slot1 (bottom) */
[4] = { -1, INTA, INTB, INTX, INTX }, /* IDSEL 04 - AdapterC-Slot0 (top) */
[5] = { -1, INTB, INTA, INTX, INTX }, /* IDSEL 05 - AdapterC-Slot1 (bottom) */
[6] = { -1, INTC, INTD, INTX, INTX }, /* IDSEL 06 - AdapterD-Slot0 (top) */
[7] = { -1, INTD, INTC, INTX, INTX }, /* IDSEL 07 - AdapterD-Slot1 (bottom) */
};
struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
{ AU1500_GPIO_204, IRQF_TRIGGER_HIGH, 0 },
{ AU1500_GPIO_201, IRQF_TRIGGER_LOW, 0 },
{ AU1500_GPIO_202, IRQF_TRIGGER_LOW, 0 },
{ AU1500_GPIO_203, IRQF_TRIGGER_LOW, 0 },
{ AU1500_GPIO_205, IRQF_TRIGGER_LOW, 0 },
};
void __init board_init_irq(void)
{
au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map));
}
......@@ -5,4 +5,6 @@
# Makefile for MyCable XXS1500 board.
#
lib-y := init.o board_setup.o irqmap.o
lib-y := init.o board_setup.o platform.o
EXTRA_CFLAGS += -Werror
......@@ -25,31 +25,35 @@
#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>
void board_reset(void)
static void xxs1500_reset(char *c)
{
/* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
au_writel(0x00000000, 0xAE00001C);
}
static void xxs1500_power_off(void)
{
printk(KERN_ALERT "It's now safe to remove power\n");
while (1)
asm volatile (".set mips3 ; wait ; .set mips1");
}
void __init board_setup(void)
{
u32 pin_func;
#ifdef CONFIG_SERIAL_8250_CONSOLE
char *argptr;
argptr = prom_getcmdline();
argptr = strstr(argptr, "console=");
if (argptr == NULL) {
argptr = prom_getcmdline();
strcat(argptr, " console=ttyS0,115200");
}
#endif
pm_power_off = xxs1500_power_off;
_machine_halt = xxs1500_power_off;
_machine_restart = xxs1500_reset;
alchemy_gpio1_input_enable();
alchemy_gpio2_enable();
......@@ -68,22 +72,6 @@ void __init board_setup(void)
/* Enable DTR = USB power up */
au_writel(0x01, UART3_ADDR + UART_MCR); /* UART_MCR_DTR is 0x01??? */
#ifdef CONFIG_PCMCIA_XXS1500
/* GPIO 0, 1, and 4 are inputs */
alchemy_gpio_direction_input(0);
alchemy_gpio_direction_input(1);
alchemy_gpio_direction_input(4);
/* GPIO2 208/9/10/11 are inputs */
alchemy_gpio_direction_input(208);
alchemy_gpio_direction_input(209);
alchemy_gpio_direction_input(210);
alchemy_gpio_direction_input(211);
/* Turn off power */
alchemy_gpio_direction_output(214, 0);
#endif
#ifdef CONFIG_PCI
#if defined(__MIPSEB__)
au_writel(0xf | (2 << 6) | (1 << 4), Au1500_PCI_CFG);
......@@ -92,3 +80,23 @@ void __init board_setup(void)
#endif
#endif
}
static int __init xxs1500_init_irq(void)
{
set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH);
set_irq_type(AU1500_GPIO201_INT, IRQF_TRIGGER_LOW);
set_irq_type(AU1500_GPIO202_INT, IRQF_TRIGGER_LOW);
set_irq_type(AU1500_GPIO203_INT, IRQF_TRIGGER_LOW);
set_irq_type(AU1500_GPIO205_INT, IRQF_TRIGGER_LOW);
set_irq_type(AU1500_GPIO207_INT, IRQF_TRIGGER_LOW);
set_irq_type(AU1500_GPIO0_INT, IRQF_TRIGGER_LOW);
set_irq_type(AU1500_GPIO1_INT, IRQF_TRIGGER_LOW);
set_irq_type(AU1500_GPIO2_INT, IRQF_TRIGGER_LOW);
set_irq_type(AU1500_GPIO3_INT, IRQF_TRIGGER_LOW);
set_irq_type(AU1500_GPIO4_INT, IRQF_TRIGGER_LOW); /* CF irq */
set_irq_type(AU1500_GPIO5_INT, IRQF_TRIGGER_LOW);
return 0;
}
arch_initcall(xxs1500_init_irq);
......@@ -30,6 +30,7 @@
#include <linux/kernel.h>
#include <asm/bootinfo.h>
#include <asm/mach-au1x00/au1000.h>
#include <prom.h>
......@@ -56,3 +57,8 @@ void __init prom_init(void)
strict_strtoul(memsize_str, 0, &memsize);
add_memory_region(0, memsize, BOOT_MEM_RAM);
}
void prom_putchar(unsigned char c)
{
alchemy_uart_putchar(UART0_PHYS_ADDR, c);
}
/*
* BRIEF MODULE DESCRIPTION
* Au1xxx irq map table
*
* Copyright 2003 Embedded Edge, LLC
* dan@embeddededge.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>
struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
{ AU1500_GPIO_204, IRQF_TRIGGER_HIGH, 0 },
{ AU1500_GPIO_201, IRQF_TRIGGER_LOW, 0 },
{ AU1500_GPIO_202, IRQF_TRIGGER_LOW, 0 },
{ AU1500_GPIO_203, IRQF_TRIGGER_LOW, 0 },
{ AU1500_GPIO_205, IRQF_TRIGGER_LOW, 0 },
{ AU1500_GPIO_207, IRQF_TRIGGER_LOW, 0 },
{ AU1000_GPIO_0, IRQF_TRIGGER_LOW, 0 },
{ AU1000_GPIO_1, IRQF_TRIGGER_LOW, 0 },
{ AU1000_GPIO_2, IRQF_TRIGGER_LOW, 0 },
{ AU1000_GPIO_3, IRQF_TRIGGER_LOW, 0 },
{ AU1000_GPIO_4, IRQF_TRIGGER_LOW, 0 }, /* CF interrupt */
{ AU1000_GPIO_5, IRQF_TRIGGER_LOW, 0 },
};
void __init board_init_irq(void)
{
au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map));
}
/*
* 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 = PCMCIA_IO_PHYS_ADDR,
.end = PCMCIA_IO_PHYS_ADDR + 0x000400000 - 1,
},
{
.name = "pcmcia-attr",
.flags = IORESOURCE_MEM,
.start = PCMCIA_ATTR_PHYS_ADDR,
.end = PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
},
{
.name = "pcmcia-mem",
.flags = IORESOURCE_MEM,
.start = PCMCIA_MEM_PHYS_ADDR,
.end = 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);
/*
* Copyright (C) 2007 Felix Fietkau <nbd@openwrt.org>
* Copyright (C) 2007 Eugene Konev <ejka@openwrt.org>
* Copyright (C) 2009 Florian Fainelli <florian@openwrt.org>
*
* 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
......@@ -24,6 +25,8 @@
#include <linux/delay.h>
#include <linux/gcd.h>
#include <linux/io.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <asm/addrspace.h>
#include <asm/mach-ar7/ar7.h>
......@@ -94,12 +97,16 @@ struct tnetd7200_clocks {
struct tnetd7200_clock usb;
};
int ar7_cpu_clock = 150000000;
EXPORT_SYMBOL(ar7_cpu_clock);
int ar7_bus_clock = 125000000;
EXPORT_SYMBOL(ar7_bus_clock);
int ar7_dsp_clock;
EXPORT_SYMBOL(ar7_dsp_clock);
static struct clk bus_clk = {
.rate = 125000000,
};
static struct clk cpu_clk = {
.rate = 150000000,
};
static struct clk dsp_clk;
static struct clk vbus_clk;
static void approximate(int base, int target, int *prediv,
int *postdiv, int *mul)
......@@ -185,7 +192,7 @@ static int tnetd7300_get_clock(u32 shift, struct tnetd7300_clock *clock,
base_clock = AR7_XTAL_CLOCK;
break;
case BOOT_PLL_SOURCE_CPU:
base_clock = ar7_cpu_clock;
base_clock = cpu_clk.rate;
break;
}
......@@ -212,11 +219,11 @@ static void tnetd7300_set_clock(u32 shift, struct tnetd7300_clock *clock,
u32 *bootcr, u32 frequency)
{
int prediv, postdiv, mul;
int base_clock = ar7_bus_clock;
int base_clock = bus_clk.rate;
switch ((*bootcr & (BOOT_PLL_SOURCE_MASK << shift)) >> shift) {
case BOOT_PLL_SOURCE_BUS:
base_clock = ar7_bus_clock;
base_clock = bus_clk.rate;
break;
case BOOT_PLL_SOURCE_REF:
base_clock = AR7_REF_CLOCK;
......@@ -225,7 +232,7 @@ static void tnetd7300_set_clock(u32 shift, struct tnetd7300_clock *clock,
base_clock = AR7_XTAL_CLOCK;
break;
case BOOT_PLL_SOURCE_CPU:
base_clock = ar7_cpu_clock;
base_clock = cpu_clk.rate;
break;
}
......@@ -247,18 +254,18 @@ static void __init tnetd7300_init_clocks(void)
ioremap_nocache(UR8_REGS_CLOCKS,
sizeof(struct tnetd7300_clocks));
ar7_bus_clock = tnetd7300_get_clock(BUS_PLL_SOURCE_SHIFT,
bus_clk.rate = tnetd7300_get_clock(BUS_PLL_SOURCE_SHIFT,
&clocks->bus, bootcr, AR7_AFE_CLOCK);
if (*bootcr & BOOT_PLL_ASYNC_MODE)
ar7_cpu_clock = tnetd7300_get_clock(CPU_PLL_SOURCE_SHIFT,
cpu_clk.rate = tnetd7300_get_clock(CPU_PLL_SOURCE_SHIFT,
&clocks->cpu, bootcr, AR7_AFE_CLOCK);
else
ar7_cpu_clock = ar7_bus_clock;
cpu_clk.rate = bus_clk.rate;
if (ar7_dsp_clock == 250000000)
if (dsp_clk.rate == 250000000)
tnetd7300_set_clock(DSP_PLL_SOURCE_SHIFT, &clocks->dsp,
bootcr, ar7_dsp_clock);
bootcr, dsp_clk.rate);
iounmap(clocks);
iounmap(bootcr);
......@@ -343,20 +350,20 @@ static void __init tnetd7200_init_clocks(void)
printk(KERN_INFO "Clocks: Setting DSP clock\n");
calculate(dsp_base, TNETD7200_DEF_DSP_CLK,
&dsp_prediv, &dsp_postdiv, &dsp_mul);
ar7_bus_clock =
bus_clk.rate =
((dsp_base / dsp_prediv) * dsp_mul) / dsp_postdiv;
tnetd7200_set_clock(dsp_base, &clocks->dsp,
dsp_prediv, dsp_postdiv * 2, dsp_postdiv, dsp_mul * 2,
ar7_bus_clock);
bus_clk.rate);
printk(KERN_INFO "Clocks: Setting CPU clock\n");
calculate(cpu_base, TNETD7200_DEF_CPU_CLK, &cpu_prediv,
&cpu_postdiv, &cpu_mul);
ar7_cpu_clock =
cpu_clk.rate =
((cpu_base / cpu_prediv) * cpu_mul) / cpu_postdiv;
tnetd7200_set_clock(cpu_base, &clocks->cpu,
cpu_prediv, cpu_postdiv, -1, cpu_mul,
ar7_cpu_clock);
cpu_clk.rate);
} else
if (*bootcr & BOOT_PLL_2TO1_MODE) {
......@@ -365,48 +372,90 @@ static void __init tnetd7200_init_clocks(void)
printk(KERN_INFO "Clocks: Setting CPU clock\n");
calculate(cpu_base, TNETD7200_DEF_CPU_CLK, &cpu_prediv,
&cpu_postdiv, &cpu_mul);
ar7_cpu_clock = ((cpu_base / cpu_prediv) * cpu_mul)
cpu_clk.rate = ((cpu_base / cpu_prediv) * cpu_mul)
/ cpu_postdiv;
tnetd7200_set_clock(cpu_base, &clocks->cpu,
cpu_prediv, cpu_postdiv, -1, cpu_mul,
ar7_cpu_clock);
cpu_clk.rate);
printk(KERN_INFO "Clocks: Setting DSP clock\n");
calculate(dsp_base, TNETD7200_DEF_DSP_CLK, &dsp_prediv,
&dsp_postdiv, &dsp_mul);
ar7_bus_clock = ar7_cpu_clock / 2;
bus_clk.rate = cpu_clk.rate / 2;
tnetd7200_set_clock(dsp_base, &clocks->dsp,
dsp_prediv, dsp_postdiv * 2, dsp_postdiv,
dsp_mul * 2, ar7_bus_clock);
dsp_mul * 2, bus_clk.rate);
} else {
printk(KERN_INFO "Clocks: Sync 1:1 mode\n");
printk(KERN_INFO "Clocks: Setting DSP clock\n");
calculate(dsp_base, TNETD7200_DEF_DSP_CLK, &dsp_prediv,
&dsp_postdiv, &dsp_mul);
ar7_bus_clock = ((dsp_base / dsp_prediv) * dsp_mul)
bus_clk.rate = ((dsp_base / dsp_prediv) * dsp_mul)
/ dsp_postdiv;
tnetd7200_set_clock(dsp_base, &clocks->dsp,
dsp_prediv, dsp_postdiv * 2, dsp_postdiv,
dsp_mul * 2, ar7_bus_clock);
dsp_mul * 2, bus_clk.rate);
ar7_cpu_clock = ar7_bus_clock;
cpu_clk.rate = bus_clk.rate;
}
printk(KERN_INFO "Clocks: Setting USB clock\n");
usb_base = ar7_bus_clock;
usb_base = bus_clk.rate;
calculate(usb_base, TNETD7200_DEF_USB_CLK, &usb_prediv,
&usb_postdiv, &usb_mul);
tnetd7200_set_clock(usb_base, &clocks->usb,
usb_prediv, usb_postdiv, -1, usb_mul,
TNETD7200_DEF_USB_CLK);
ar7_dsp_clock = ar7_cpu_clock;
dsp_clk.rate = cpu_clk.rate;
iounmap(clocks);
iounmap(bootcr);
}
/*
* Linux clock API
*/
int clk_enable(struct clk *clk)
{
return 0;
}
EXPORT_SYMBOL(clk_enable);
void clk_disable(struct clk *clk)
{
}
EXPORT_SYMBOL(clk_disable);
unsigned long clk_get_rate(struct clk *clk)
{
return clk->rate;
}
EXPORT_SYMBOL(clk_get_rate);
struct clk *clk_get(struct device *dev, const char *id)
{
if (!strcmp(id, "bus"))
return &bus_clk;
/* cpmac and vbus share the same rate */
if (!strcmp(id, "cpmac"))
return &vbus_clk;
if (!strcmp(id, "cpu"))
return &cpu_clk;
if (!strcmp(id, "dsp"));
return &dsp_clk;
if (!strcmp(id, "vbus"))
return &vbus_clk;
return ERR_PTR(-ENOENT);
}
EXPORT_SYMBOL(clk_get);
void clk_put(struct clk *clk)
{
}
EXPORT_SYMBOL(clk_put);
int __init ar7_init_clocks(void)
{
switch (ar7_chip_id()) {
......@@ -415,12 +464,14 @@ int __init ar7_init_clocks(void)
tnetd7200_init_clocks();
break;
case AR7_CHIP_7300:
ar7_dsp_clock = tnetd7300_dsp_clock();
dsp_clk.rate = tnetd7300_dsp_clock();
tnetd7300_init_clocks();
break;
default:
break;
}
/* adjust vbus clock rate */
vbus_clk.rate = bus_clk.rate / 2;
return 0;
}
......
This diff is collapsed.
......@@ -62,8 +62,7 @@ void __init prom_meminit(void)
unsigned long pages;
pages = memsize() >> PAGE_SHIFT;
add_memory_region(PHYS_OFFSET, pages << PAGE_SHIFT,
BOOT_MEM_RAM);
add_memory_region(PHYS_OFFSET, pages << PAGE_SHIFT, BOOT_MEM_RAM);
}
void __init prom_free_prom_memory(void)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -20,11 +20,21 @@
#include <linux/init.h>
#include <linux/time.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <asm/time.h>
#include <asm/mach-ar7/ar7.h>
void __init plat_time_init(void)
{
mips_hpt_frequency = ar7_cpu_freq() / 2;
struct clk *cpu_clk;
cpu_clk = clk_get(NULL, "cpu");
if (IS_ERR(cpu_clk)) {
printk(KERN_ERR "unable to get cpu clock\n");
return;
}
mips_hpt_frequency = clk_get_rate(cpu_clk) / 2;
}
......@@ -59,4 +59,3 @@ int gpio_to_irq(unsigned gpio)
return -EINVAL;
}
EXPORT_SYMBOL_GPL(gpio_to_irq);
......@@ -163,4 +163,3 @@ void __init prom_init(void)
void __init prom_free_prom_memory(void)
{
}
......@@ -121,4 +121,3 @@ void __init plat_mem_setup(void)
_machine_halt = bcm47xx_machine_halt;
pm_power_off = bcm47xx_machine_halt;
}
......@@ -164,4 +164,3 @@ static int __init wgt634u_init(void)
}
module_init(wgt634u_init);
......@@ -836,4 +836,3 @@ int __init board_register_devices(void)
return 0;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment