aboutsummaryrefslogtreecommitdiff
path: root/arch/mips/alchemy/devboards
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/alchemy/devboards')
-rw-r--r--arch/mips/alchemy/devboards/Makefile6
-rw-r--r--arch/mips/alchemy/devboards/bcsr.c148
-rw-r--r--arch/mips/alchemy/devboards/db1200/Makefile1
-rw-r--r--arch/mips/alchemy/devboards/db1200/platform.c561
-rw-r--r--arch/mips/alchemy/devboards/db1200/setup.c118
-rw-r--r--arch/mips/alchemy/devboards/db1x00/Makefile2
-rw-r--r--arch/mips/alchemy/devboards/db1x00/board_setup.c204
-rw-r--r--arch/mips/alchemy/devboards/db1x00/irqmap.c90
-rw-r--r--arch/mips/alchemy/devboards/db1x00/platform.c118
-rw-r--r--arch/mips/alchemy/devboards/pb1000/board_setup.c34
-rw-r--r--arch/mips/alchemy/devboards/pb1100/Makefile2
-rw-r--r--arch/mips/alchemy/devboards/pb1100/board_setup.c55
-rw-r--r--arch/mips/alchemy/devboards/pb1100/platform.c50
-rw-r--r--arch/mips/alchemy/devboards/pb1200/Makefile2
-rw-r--r--arch/mips/alchemy/devboards/pb1200/board_setup.c96
-rw-r--r--arch/mips/alchemy/devboards/pb1200/irqmap.c134
-rw-r--r--arch/mips/alchemy/devboards/pb1200/platform.c63
-rw-r--r--arch/mips/alchemy/devboards/pb1500/Makefile2
-rw-r--r--arch/mips/alchemy/devboards/pb1500/board_setup.c54
-rw-r--r--arch/mips/alchemy/devboards/pb1500/platform.c49
-rw-r--r--arch/mips/alchemy/devboards/pb1550/Makefile2
-rw-r--r--arch/mips/alchemy/devboards/pb1550/board_setup.c49
-rw-r--r--arch/mips/alchemy/devboards/pb1550/platform.c69
-rw-r--r--arch/mips/alchemy/devboards/platform.c222
-rw-r--r--arch/mips/alchemy/devboards/platform.h21
-rw-r--r--arch/mips/alchemy/devboards/pm.c32
-rw-r--r--arch/mips/alchemy/devboards/prom.c5
27 files changed, 1735 insertions, 454 deletions
diff --git a/arch/mips/alchemy/devboards/Makefile b/arch/mips/alchemy/devboards/Makefile
index 730f9f2b30e..ecbd37f9ee8 100644
--- a/arch/mips/alchemy/devboards/Makefile
+++ b/arch/mips/alchemy/devboards/Makefile
@@ -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
diff --git a/arch/mips/alchemy/devboards/bcsr.c b/arch/mips/alchemy/devboards/bcsr.c
new file mode 100644
index 00000000000..3bc4fd2155d
--- /dev/null
+++ b/arch/mips/alchemy/devboards/bcsr.c
@@ -0,0 +1,148 @@
+/*
+ * 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);
+}
diff --git a/arch/mips/alchemy/devboards/db1200/Makefile b/arch/mips/alchemy/devboards/db1200/Makefile
new file mode 100644
index 00000000000..17840a5e273
--- /dev/null
+++ b/arch/mips/alchemy/devboards/db1200/Makefile
@@ -0,0 +1 @@
+obj-y += setup.o platform.o
diff --git a/arch/mips/alchemy/devboards/db1200/platform.c b/arch/mips/alchemy/devboards/db1200/platform.c
new file mode 100644
index 00000000000..3cb95a98ab3
--- /dev/null
+++ b/arch/mips/alchemy/devboards/db1200/platform.c
@@ -0,0 +1,561 @@
+/*
+ * DBAu1200 board platform device registration
+ *
+ * Copyright (C) 2008-2009 Manuel Lauss
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/leds.h>
+#include <linux/mmc/host.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/smc91x.h>
+
+#include <asm/mach-au1x00/au1100_mmc.h>
+#include <asm/mach-au1x00/au1xxx_dbdma.h>
+#include <asm/mach-au1x00/au1550_spi.h>
+#include <asm/mach-db1x00/bcsr.h>
+#include <asm/mach-db1x00/db1200.h>
+
+#include "../platform.h"
+
+static struct mtd_partition db1200_spiflash_parts[] = {
+ {
+ .name = "DB1200 SPI flash",
+ .offset = 0,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct flash_platform_data db1200_spiflash_data = {
+ .name = "s25fl001",
+ .parts = db1200_spiflash_parts,
+ .nr_parts = ARRAY_SIZE(db1200_spiflash_parts),
+ .type = "m25p10",
+};
+
+static struct spi_board_info db1200_spi_devs[] __initdata = {
+ {
+ /* TI TMP121AIDBVR temp sensor */
+ .modalias = "tmp121",
+ .max_speed_hz = 2000000,
+ .bus_num = 0,
+ .chip_select = 0,
+ .mode = 0,
+ },
+ {
+ /* Spansion S25FL001D0FMA SPI flash */
+ .modalias = "m25p80",
+ .max_speed_hz = 50000000,
+ .bus_num = 0,
+ .chip_select = 1,
+ .mode = 0,
+ .platform_data = &db1200_spiflash_data,
+ },
+};
+
+static struct i2c_board_info db1200_i2c_devs[] __initdata = {
+ {
+ /* AT24C04-10 I2C eeprom */
+ I2C_BOARD_INFO("24c04", 0x52),
+ },
+ {
+ /* Philips NE1619 temp/voltage sensor (adm1025 drv) */
+ I2C_BOARD_INFO("ne1619", 0x2d),
+ },
+ {
+ /* I2S audio codec WM8731 */
+ I2C_BOARD_INFO("wm8731", 0x1b),
+ },
+};
+
+/**********************************************************************/
+
+static void au1200_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
+ unsigned int ctrl)
+{
+ struct nand_chip *this = mtd->priv;
+ unsigned long ioaddr = (unsigned long)this->IO_ADDR_W;
+
+ ioaddr &= 0xffffff00;
+
+ if (ctrl & NAND_CLE) {
+ ioaddr += MEM_STNAND_CMD;
+ } else if (ctrl & NAND_ALE) {
+ ioaddr += MEM_STNAND_ADDR;
+ } else {
+ /* assume we want to r/w real data by default */
+ ioaddr += MEM_STNAND_DATA;
+ }
+ this->IO_ADDR_R = this->IO_ADDR_W = (void __iomem *)ioaddr;
+ if (cmd != NAND_CMD_NONE) {
+ __raw_writeb(cmd, this->IO_ADDR_W);
+ wmb();
+ }
+}
+
+static int au1200_nand_device_ready(struct mtd_info *mtd)
+{
+ return __raw_readl((void __iomem *)MEM_STSTAT) & 1;
+}
+
+static const char *db1200_part_probes[] = { "cmdlinepart", NULL };
+
+static struct mtd_partition db1200_nand_parts[] = {
+ {
+ .name = "NAND FS 0",
+ .offset = 0,
+ .size = 8 * 1024 * 1024,
+ },
+ {
+ .name = "NAND FS 1",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL
+ },
+};
+
+struct platform_nand_data db1200_nand_platdata = {
+ .chip = {
+ .nr_chips = 1,
+ .chip_offset = 0,
+ .nr_partitions = ARRAY_SIZE(db1200_nand_parts),
+ .partitions = db1200_nand_parts,
+ .chip_delay = 20,
+ .part_probe_types = db1200_part_probes,
+ },
+ .ctrl = {
+ .dev_ready = au1200_nand_device_ready,
+ .cmd_ctrl = au1200_nand_cmd_ctrl,
+ },
+};
+
+static struct resource db1200_nand_res[] = {
+ [0] = {
+ .start = DB1200_NAND_PHYS_ADDR,
+ .end = DB1200_NAND_PHYS_ADDR + 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device db1200_nand_dev = {
+ .name = "gen_nand",
+ .num_resources = ARRAY_SIZE(db1200_nand_res),
+ .resource = db1200_nand_res,
+ .id = -1,
+ .dev = {
+ .platform_data = &db1200_nand_platdata,
+ }
+};
+
+/**********************************************************************/
+
+static struct smc91x_platdata db1200_eth_data = {
+ .flags = SMC91X_NOWAIT | SMC91X_USE_16BIT,
+ .leda = RPC_LED_100_10,
+ .ledb = RPC_LED_TX_RX,
+};
+
+static struct resource db1200_eth_res[] = {
+ [0] = {
+ .start = DB1200_ETH_PHYS_ADDR,
+ .end = DB1200_ETH_PHYS_ADDR + 0xf,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DB1200_ETH_INT,
+ .end = DB1200_ETH_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device db1200_eth_dev = {
+ .dev = {
+ .platform_data = &db1200_eth_data,
+ },
+ .name = "smc91x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(db1200_eth_res),
+ .resource = db1200_eth_res,
+};
+
+/**********************************************************************/
+
+static struct resource db1200_ide_res[] = {
+ [0] = {
+ .start = DB1200_IDE_PHYS_ADDR,
+ .end = DB1200_IDE_PHYS_ADDR + DB1200_IDE_PHYS_LEN - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DB1200_IDE_INT,
+ .end = DB1200_IDE_INT,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 ide_dmamask = DMA_32BIT_MASK;
+
+static struct platform_device db1200_ide_dev = {
+ .name = "au1200-ide",
+ .id = 0,
+ .dev = {
+ .dma_mask = &ide_dmamask,
+ .coherent_dma_mask = DMA_32BIT_MASK,
+ },
+ .num_resources = ARRAY_SIZE(db1200_ide_res),
+ .resource = db1200_ide_res,
+};
+
+/**********************************************************************/
+
+static struct platform_device db1200_rtc_dev = {
+ .name = "rtc-au1xxx",
+ .id = -1,
+};
+
+/**********************************************************************/
+
+/* SD carddetects: they're supposed to be edge-triggered, but ack
+ * doesn't seem to work (CPLD Rev 2). Instead, the screaming one
+ * is disabled and its counterpart enabled. The 500ms timeout is
+ * because the carddetect isn't debounced in hardware.
+ */
+static irqreturn_t db1200_mmc_cd(int irq, void *ptr)
+{
+ void(*mmc_cd)(struct mmc_host *, unsigned long);
+
+ if (irq == DB1200_SD0_INSERT_INT) {
+ disable_irq_nosync(DB1200_SD0_INSERT_INT);
+ enable_irq(DB1200_SD0_EJECT_INT);
+ } else {
+ disable_irq_nosync(DB1200_SD0_EJECT_INT);
+ enable_irq(DB1200_SD0_INSERT_INT);
+ }
+
+ /* link against CONFIG_MMC=m */
+ mmc_cd = symbol_get(mmc_detect_change);
+ if (mmc_cd) {
+ mmc_cd(ptr, msecs_to_jiffies(500));
+ symbol_put(mmc_detect_change);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int db1200_mmc_cd_setup(void *mmc_host, int en)
+{
+ int ret;
+
+ if (en) {
+ ret = request_irq(DB1200_SD0_INSERT_INT, db1200_mmc_cd,
+ IRQF_DISABLED, "sd_insert", mmc_host);
+ if (ret)
+ goto out;
+
+ ret = request_irq(DB1200_SD0_EJECT_INT, db1200_mmc_cd,
+ IRQF_DISABLED, "sd_eject", mmc_host);
+ if (ret) {
+ free_irq(DB1200_SD0_INSERT_INT, mmc_host);
+ goto out;
+ }
+
+ if (bcsr_read(BCSR_SIGSTAT) & BCSR_INT_SD0INSERT)
+ enable_irq(DB1200_SD0_EJECT_INT);
+ else
+ enable_irq(DB1200_SD0_INSERT_INT);
+
+ } else {
+ free_irq(DB1200_SD0_INSERT_INT, mmc_host);
+ free_irq(DB1200_SD0_EJECT_INT, mmc_host);
+ }
+ ret = 0;
+out:
+ return ret;
+}
+
+static void db1200_mmc_set_power(void *mmc_host, int state)
+{
+ if (state) {
+ bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_SD0PWR);
+ msleep(400); /* stabilization time */
+ } else
+ bcsr_mod(BCSR_BOARD, BCSR_BOARD_SD0PWR, 0);
+}
+
+static int db1200_mmc_card_readonly(void *mmc_host)
+{
+ return (bcsr_read(BCSR_STATUS) & BCSR_STATUS_SD0WP) ? 1 : 0;
+}
+
+static int db1200_mmc_card_inserted(void *mmc_host)
+{
+ return (bcsr_read(BCSR_SIGSTAT) & BCSR_INT_SD0INSERT) ? 1 : 0;
+}
+
+static void db1200_mmcled_set(struct led_classdev *led,
+ enum led_brightness brightness)
+{
+ if (brightness != LED_OFF)
+ bcsr_mod(BCSR_LEDS, BCSR_LEDS_LED0, 0);
+ else
+ bcsr_mod(BCSR_LEDS, 0, BCSR_LEDS_LED0);
+}
+
+static struct led_classdev db1200_mmc_led = {
+ .brightness_set = db1200_mmcled_set,
+};
+
+/* needed by arch/mips/alchemy/common/platform.c */
+struct au1xmmc_platform_data au1xmmc_platdata[] = {
+ [0] = {
+ .cd_setup = db1200_mmc_cd_setup,
+ .set_power = db1200_mmc_set_power,
+ .card_inserted = db1200_mmc_card_inserted,
+ .card_readonly = db1200_mmc_card_readonly,
+ .led = &db1200_mmc_led,
+ },
+};
+
+/**********************************************************************/
+
+static struct resource au1200_psc0_res[] = {
+ [0] = {
+ .start = PSC0_PHYS_ADDR,
+ .end = PSC0_PHYS_ADDR + 0x000fffff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AU1200_PSC0_INT,
+ .end = AU1200_PSC0_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = DSCR_CMD0_PSC0_TX,
+ .end = DSCR_CMD0_PSC0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ .start = DSCR_CMD0_PSC0_RX,
+ .end = DSCR_CMD0_PSC0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device db1200_i2c_dev = {
+ .name = "au1xpsc_smbus",
+ .id = 0, /* bus number */
+ .num_resources = ARRAY_SIZE(au1200_psc0_res),
+ .resource = au1200_psc0_res,
+};
+
+static void db1200_spi_cs_en(struct au1550_spi_info *spi, int cs, int pol)
+{
+ if (cs)
+ bcsr_mod(BCSR_RESETS, 0, BCSR_RESETS_SPISEL);
+ else
+ bcsr_mod(BCSR_RESETS, BCSR_RESETS_SPISEL, 0);
+}
+
+static struct au1550_spi_info db1200_spi_platdata = {
+ .mainclk_hz = 50000000, /* PSC0 clock */
+ .num_chipselect = 2,
+ .activate_cs = db1200_spi_cs_en,
+};
+
+static u64 spi_dmamask = DMA_32BIT_MASK;
+
+static struct platform_device db1200_spi_dev = {
+ .dev = {
+ .dma_mask = &spi_dmamask,
+ .coherent_dma_mask = DMA_32BIT_MASK,
+ .platform_data = &db1200_spi_platdata,
+ },
+ .name = "au1550-spi",
+ .id = 0, /* bus number */
+ .num_resources = ARRAY_SIZE(au1200_psc0_res),
+ .resource = au1200_psc0_res,
+};
+
+static struct resource au1200_psc1_res[] = {
+ [0] = {
+ .start = PSC1_PHYS_ADDR,
+ .end = PSC1_PHYS_ADDR + 0x000fffff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AU1200_PSC1_INT,
+ .end = AU1200_PSC1_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = DSCR_CMD0_PSC1_TX,
+ .end = DSCR_CMD0_PSC1_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ .start = DSCR_CMD0_PSC1_RX,
+ .end = DSCR_CMD0_PSC1_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device db1200_audio_dev = {
+ /* name assigned later based on switch setting */
+ .id = 1, /* PSC ID */
+ .num_resources = ARRAY_SIZE(au1200_psc1_res),
+ .resource = au1200_psc1_res,
+};
+
+static struct platform_device *db1200_devs[] __initdata = {
+ NULL, /* PSC0, selected by S6.8 */
+ &db1200_ide_dev,
+ &db1200_eth_dev,
+ &db1200_rtc_dev,
+ &db1200_nand_dev,
+ &db1200_audio_dev,
+};
+
+static int __init db1200_dev_init(void)
+{
+ unsigned long pfc;
+ unsigned short sw;
+ int swapped;
+
+ i2c_register_board_info(0, db1200_i2c_devs,
+ ARRAY_SIZE(db1200_i2c_devs));
+ spi_register_board_info(db1200_spi_devs,
+ ARRAY_SIZE(db1200_i2c_devs));
+
+ /* SWITCHES: S6.8 I2C/SPI selector (OFF=I2C ON=SPI)
+ * S6.7 AC97/I2S selector (OFF=AC97 ON=I2S)
+ */
+
+ /* NOTE: GPIO215 controls OTG VBUS supply. In SPI mode however
+ * this pin is claimed by PSC0 (unused though, but pinmux doesn't
+ * allow to free it without crippling the SPI interface).
+ * As a result, in SPI mode, OTG simply won't work (PSC0 uses
+ * it as an input pin which is pulled high on the boards).
+ */
+ pfc = __raw_readl((void __iomem *)SYS_PINFUNC) & ~SYS_PINFUNC_P0A;
+
+ /* switch off OTG VBUS supply */
+ gpio_request(215, "otg-vbus");
+ gpio_direction_output(215, 1);
+
+ printk(KERN_INFO "DB1200 device configuration:\n");
+
+ sw = bcsr_read(BCSR_SWITCHES);
+ if (sw & BCSR_SWITCHES_DIP_8) {
+ db1200_devs[0] = &db1200_i2c_dev;
+ bcsr_mod(BCSR_RESETS, BCSR_RESETS_PSC0MUX, 0);
+
+ pfc |= (2 << 17); /* GPIO2 block owns GPIO215 */
+
+ printk(KERN_INFO " S6.8 OFF: PSC0 mode I2C\n");
+ printk(KERN_INFO " OTG port VBUS supply available!\n");
+ } else {
+ db1200_devs[0] = &db1200_spi_dev;
+ bcsr_mod(BCSR_RESETS, 0, BCSR_RESETS_PSC0MUX);
+
+ pfc |= (1 << 17); /* PSC0 owns GPIO215 */
+
+ printk(KERN_INFO " S6.8 ON : PSC0 mode SPI\n");
+ printk(KERN_INFO " OTG port VBUS supply disabled\n");
+ }
+ __raw_writel(pfc, (void __iomem *)SYS_PINFUNC);
+ wmb();
+
+ /* Audio: DIP7 selects I2S(0)/AC97(1), but need I2C for I2S!
+ * so: DIP7=1 || DIP8=0 => AC97, DIP7=0 && DIP8=1 => I2S
+ */
+ sw &= BCSR_SWITCHES_DIP_8 | BCSR_SWITCHES_DIP_7;
+ if (sw == BCSR_SWITCHES_DIP_8) {
+ bcsr_mod(BCSR_RESETS, 0, BCSR_RESETS_PSC1MUX);
+ db1200_audio_dev.name = "au1xpsc_i2s";
+ printk(KERN_INFO " S6.7 ON : PSC1 mode I2S\n");
+ } else {
+ bcsr_mod(BCSR_RESETS, BCSR_RESETS_PSC1MUX, 0);
+ db1200_audio_dev.name = "au1xpsc_ac97";
+ printk(KERN_INFO " S6.7 OFF: PSC1 mode AC97\n");
+ }
+
+ /* Audio PSC clock is supplied externally. (FIXME: platdata!!) */
+ __raw_writel(PSC_SEL_CLK_SERCLK,
+ (void __iomem *)KSEG1ADDR(PSC1_PHYS_ADDR) + PSC_SEL_OFFSET);
+ wmb();
+
+ 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,
+ DB1200_PC0_INT,
+ DB1200_PC0_INSERT_INT,
+ /*DB1200_PC0_STSCHG_INT*/0,
+ DB1200_PC0_EJECT_INT,
+ 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,
+ DB1200_PC1_INT,
+ DB1200_PC1_INSERT_INT,
+ /*DB1200_PC1_STSCHG_INT*/0,
+ DB1200_PC1_EJECT_INT,
+ 1);
+
+ swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1200_SWAPBOOT;
+ db1x_register_norflash(64 << 20, 2, swapped);
+
+ return platform_add_devices(db1200_devs, ARRAY_SIZE(db1200_devs));
+}
+device_initcall(db1200_dev_init);
+
+/* au1200fb calls these: STERBT EINEN TRAGISCHEN TOD!!! */
+int board_au1200fb_panel(void)
+{
+ return (bcsr_read(BCSR_SWITCHES) >> 8) & 0x0f;
+}
+
+int board_au1200fb_panel_init(void)
+{
+ /* Apply power */
+ bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD |
+ BCSR_BOARD_LCDBL);
+ return 0;
+}
+
+int board_au1200fb_panel_shutdown(void)
+{
+ /* Remove power */
+ bcsr_mod(BCSR_BOARD, BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD |
+ BCSR_BOARD_LCDBL, 0);
+ return 0;
+}
diff --git a/arch/mips/alchemy/devboards/db1200/setup.c b/arch/mips/alchemy/devboards/db1200/setup.c
new file mode 100644
index 00000000000..379536e3abd
--- /dev/null
+++ b/arch/mips/alchemy/devboards/db1200/setup.c
@@ -0,0 +1,118 @@
+/*
+ * 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);
diff --git a/arch/mips/alchemy/devboards/db1x00/Makefile b/arch/mips/alchemy/devboards/db1x00/Makefile
index 432241ab867..613c0c0c8be 100644
--- a/arch/mips/alchemy/devboards/db1x00/Makefile
+++ b/arch/mips/alchemy/devboards/db1x00/Makefile
@@ -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
diff --git a/arch/mips/alchemy/devboards/db1x00/board_setup.c b/arch/mips/alchemy/devboards/db1x00/board_setup.c
index de30d8ea717..50c9bef99da 100644
--- a/arch/mips/alchemy/devboards/db1x00/board_setup.c
+++ b/arch/mips/alchemy/devboards/db1x00/board_setup.c
@@ -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);
diff --git a/arch/mips/alchemy/devboards/db1x00/irqmap.c b/arch/mips/alchemy/devboards/db1x00/irqmap.c
deleted file mode 100644
index 0b09025087c..00000000000
--- a/arch/mips/alchemy/devboards/db1x00/irqmap.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * 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));
-}
diff --git a/arch/mips/alchemy/devboards/db1x00/platform.c b/arch/mips/alchemy/devboards/db1x00/platform.c
new file mode 100644
index 00000000000..978d5ab3d67
--- /dev/null
+++ b/arch/mips/alchemy/devboards/db1x00/platform.c
@@ -0,0 +1,118 @@
+/*
+ * 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);
diff --git a/arch/mips/alchemy/devboards/pb1000/board_setup.c b/arch/mips/alchemy/devboards/pb1000/board_setup.c
index cd273545e81..b5311d8a29a 100644
--- a/arch/mips/alchemy/devboards/pb1000/board_setup.c
+++ b/arch/mips/alchemy/devboards/pb1000/board_setup.c
@@ -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);
diff --git a/arch/mips/alchemy/devboards/pb1100/Makefile b/arch/mips/alchemy/devboards/pb1100/Makefile
index c586dd7e91d..7e3756c83fe 100644
--- a/arch/mips/alchemy/devboards/pb1100/Makefile
+++ b/arch/mips/alchemy/devboards/pb1100/Makefile
@@ -5,4 +5,4 @@
# Makefile for the Alchemy Semiconductor Pb1100 board.
#
-obj-y := board_setup.o
+obj-y := board_setup.o platform.o
diff --git a/arch/mips/alchemy/devboards/pb1100/board_setup.c b/arch/mips/alchemy/devboards/pb1100/board_setup.c
index 61263081ef5..c7b4caa81a3 100644
--- a/arch/mips/alchemy/devboards/pb1100/board_setup.c
+++ b/arch/mips/alchemy/devboards/pb1100/board_setup.c
@@ -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);
diff --git a/arch/mips/alchemy/devboards/pb1100/platform.c b/arch/mips/alchemy/devboards/pb1100/platform.c
new file mode 100644
index 00000000000..2c8dc29759f
--- /dev/null
+++ b/arch/mips/alchemy/devboards/pb1100/platform.c
@@ -0,0 +1,50 @@
+/*
+ * 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);
diff --git a/arch/mips/alchemy/devboards/pb1200/Makefile b/arch/mips/alchemy/devboards/pb1200/Makefile
index c8c3a99fb68..2ea9b02ef09 100644
--- a/arch/mips/alchemy/devboards/pb1200/Makefile
+++ b/arch/mips/alchemy/devboards/pb1200/Makefile
@@ -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
diff --git a/arch/mips/alchemy/devboards/pb1200/board_setup.c b/arch/mips/alchemy/devboards/pb1200/board_setup.c
index 94e6b7e7753..3184063f804 100644
--- a/arch/mips/alchemy/devboards/pb1200/board_setup.c
+++ b/arch/mips/alchemy/devboards/pb1200/board_setup.c
@@ -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;
}
diff --git a/arch/mips/alchemy/devboards/pb1200/irqmap.c b/arch/mips/alchemy/devboards/pb1200/irqmap.c
deleted file mode 100644
index fe47498da28..00000000000
--- a/arch/mips/alchemy/devboards/pb1200/irqmap.c
+++ /dev/null
@@ -1,134 +0,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);
-}
diff --git a/arch/mips/alchemy/devboards/pb1200/platform.c b/arch/mips/alchemy/devboards/pb1200/platform.c
index b93dff4a678..3ef2dceeb79 100644
--- a/arch/mips/alchemy/devboards/pb1200/platform.c
+++ b/arch/mips/alchemy/devboards/pb1200/platform.c
@@ -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);
diff --git a/arch/mips/alchemy/devboards/pb1500/Makefile b/arch/mips/alchemy/devboards/pb1500/Makefile
index 173b419a747..e83b151b5b6 100644
--- a/arch/mips/alchemy/devboards/pb1500/Makefile
+++ b/arch/mips/alchemy/devboards/pb1500/Makefile
@@ -5,4 +5,4 @@
# Makefile for the Alchemy Semiconductor Pb1500 board.
#
-obj-y := board_setup.o
+obj-y := board_setup.o platform.o
diff --git a/arch/mips/alchemy/devboards/pb1500/board_setup.c b/arch/mips/alchemy/devboards/pb1500/board_setup.c
index d7a56569e7e..fa9770ac358 100644
--- a/arch/mips/alchemy/devboards/pb1500/board_setup.c
+++ b/arch/mips/alchemy/devboards/pb1500/board_setup.c
@@ -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);
diff --git a/arch/mips/alchemy/devboards/pb1500/platform.c b/arch/mips/alchemy/devboards/pb1500/platform.c
new file mode 100644
index 00000000000..d443bc7aa76
--- /dev/null
+++ b/arch/mips/alchemy/devboards/pb1500/platform.c
@@ -0,0 +1,49 @@
+/*
+ * 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);
diff --git a/arch/mips/alchemy/devboards/pb1550/Makefile b/arch/mips/alchemy/devboards/pb1550/Makefile
index cff95bcdb2c..9661b6ec5dd 100644
--- a/arch/mips/alchemy/devboards/pb1550/Makefile
+++ b/arch/mips/alchemy/devboards/pb1550/Makefile
@@ -5,4 +5,4 @@
# Makefile for the Alchemy Semiconductor Pb1550 board.
#
-obj-y := board_setup.o
+obj-y := board_setup.o platform.o
diff --git a/arch/mips/alchemy/devboards/pb1550/board_setup.c b/arch/mips/alchemy/devboards/pb1550/board_setup.c
index b6e9e7d247a..1e8fb3ddd72 100644
--- a/arch/mips/alchemy/devboards/pb1550/board_setup.c
+++ b/arch/mips/alchemy/devboards/pb1550/board_setup.c
@@ -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);
diff --git a/arch/mips/alchemy/devboards/pb1550/platform.c b/arch/mips/alchemy/devboards/pb1550/platform.c
new file mode 100644
index 00000000000..d7150d0f49c
--- /dev/null
+++ b/arch/mips/alchemy/devboards/pb1550/platform.c
@@ -0,0 +1,69 @@
+/*
+ * 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);
diff --git a/arch/mips/alchemy/devboards/platform.c b/arch/mips/alchemy/devboards/platform.c
new file mode 100644
index 00000000000..49a4b3244d8
--- /dev/null
+++ b/arch/mips/alchemy/devboards/platform.c
@@ -0,0 +1,222 @@
+/*
+ * 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;
+}
diff --git a/arch/mips/alchemy/devboards/platform.h b/arch/mips/alchemy/devboards/platform.h
new file mode 100644
index 00000000000..5ac055d2cda
--- /dev/null
+++ b/arch/mips/alchemy/devboards/platform.h
@@ -0,0 +1,21 @@
+#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
diff --git a/arch/mips/alchemy/devboards/pm.c b/arch/mips/alchemy/devboards/pm.c
index 632f9862a0f..4bbd3133e45 100644
--- a/arch/mips/alchemy/devboards/pm.c
+++ b/arch/mips/alchemy/devboards/pm.c
@@ -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;
}
diff --git a/arch/mips/alchemy/devboards/prom.c b/arch/mips/alchemy/devboards/prom.c
index 0042bd6b1d7..b30df5c97ad 100644
--- a/arch/mips/alchemy/devboards/prom.c
+++ b/arch/mips/alchemy/devboards/prom.c
@@ -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);
+}