From mboxrd@z Thu Jan 1 00:00:00 1970 Received: with ECARTIS (v1.0.0; list linux-mips); Thu, 09 Apr 2009 00:38:02 +0100 (BST) Received: from mx1.rmicorp.com ([12.239.216.72]:17511 "EHLO mx1.rmicorp.com") by ftp.linux-mips.org with ESMTP id S20031361AbZDHXgU (ORCPT ); Thu, 9 Apr 2009 00:36:20 +0100 Received: from sark.razamicroelectronics.com ([10.8.0.254]) by mx1.rmicorp.com with Microsoft SMTPSVC(6.0.3790.3959); Wed, 8 Apr 2009 16:36:09 -0700 Received: from localhost.localdomain (unknown [10.8.0.44]) by sark.razamicroelectronics.com (Postfix) with ESMTP id C3B767B7FC6; Sat, 4 Apr 2009 05:34:46 -0600 (CST) From: Kevin Hickey To: linux-mips@linux-mips.org, ralf@linux-mips.org Cc: Kevin Hickey Subject: [PATCH v3 2/5] Alchemy: Au1300 new interrupt controller Date: Wed, 8 Apr 2009 18:36:05 -0500 Message-Id: <1239233768-11927-3-git-send-email-khickey@rmicorp.com> X-Mailer: git-send-email 1.5.4.3 In-Reply-To: <1239233768-11927-2-git-send-email-khickey@rmicorp.com> References: <> <1239233768-11927-1-git-send-email-khickey@rmicorp.com> <1239233768-11927-2-git-send-email-khickey@rmicorp.com> X-OriginalArrivalTime: 08 Apr 2009 23:36:09.0353 (UTC) FILETIME=[CB675790:01C9B8A2] Return-Path: X-Envelope-To: <"|/home/ecartis/ecartis -s linux-mips"> (uid 0) X-Orcpt: rfc822;linux-mips@linux-mips.org Original-Recipient: rfc822;linux-mips@linux-mips.org X-archive-position: 22283 X-ecartis-version: Ecartis v1.0.0 Sender: linux-mips-bounce@linux-mips.org Errors-to: linux-mips-bounce@linux-mips.org X-original-sender: khickey@rmicorp.com Precedence: bulk X-list: linux-mips The Au1300 has a new interrupt controller (relative to the rest of the Alchemy line). The differences were great enough to justify adding a whole new module. Included in this patch is the new interrupt controller, a new implementation of the cascade interrupt controller on the DB1300 board and some code to drive LEDs on the DB1300 that is used by the interrupt controller. Since the cascade interrupt controller is virtually indentical (with the exception of some constants) between the DB1300 and DB1200, a future optimization may be to use the same code for both boards. Signed-off-by: Kevin Hickey --- arch/mips/alchemy/Kconfig | 16 ++ arch/mips/alchemy/common/Makefile | 5 +- arch/mips/alchemy/common/gpio_int.c | 265 ++++++++++++++++++++++++++ arch/mips/alchemy/devboards/Makefile | 5 + arch/mips/alchemy/devboards/cascade_irq.c | 142 ++++++++++++++ arch/mips/alchemy/devboards/leds.c | 58 ++++++ arch/mips/include/asm/mach-au1x00/gpio_int.h | 237 +++++++++++++++++++++++ arch/mips/include/asm/mach-au1x00/irq.h | 34 ++++ 8 files changed, 761 insertions(+), 1 deletions(-) create mode 100644 arch/mips/alchemy/common/gpio_int.c create mode 100644 arch/mips/alchemy/devboards/cascade_irq.c create mode 100644 arch/mips/alchemy/devboards/leds.c create mode 100644 arch/mips/include/asm/mach-au1x00/gpio_int.h create mode 100644 arch/mips/include/asm/mach-au1x00/irq.h diff --git a/arch/mips/alchemy/Kconfig b/arch/mips/alchemy/Kconfig index 50d426d..2e189c2 100644 --- a/arch/mips/alchemy/Kconfig +++ b/arch/mips/alchemy/Kconfig @@ -114,22 +114,32 @@ endchoice config SOC_AU1000 bool select SOC_AU1X00 + select AU_INT_CNTLR config SOC_AU1100 bool select SOC_AU1X00 + select AU_INT_CNTLR config SOC_AU1500 bool select SOC_AU1X00 + select AU_INT_CNTLR config SOC_AU1550 bool select SOC_AU1X00 + select AU_INT_CNTLR config SOC_AU1200 bool select SOC_AU1X00 + select AU_INT_CNTLR + +config SOC_AU13XX + bool + select SOC_AU1X00 + select AU_GPIO_INT_CNTLR config SOC_AU1X00 bool @@ -141,3 +151,9 @@ config SOC_AU1X00 select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_APM_EMULATION select GENERIC_HARDIRQS_NO__DO_IRQ + +config AU_INT_CNTLR + bool + +config AU_GPIO_INT_CNTLR + bool diff --git a/arch/mips/alchemy/common/Makefile b/arch/mips/alchemy/common/Makefile index d50d476..faa6afd 100644 --- a/arch/mips/alchemy/common/Makefile +++ b/arch/mips/alchemy/common/Makefile @@ -5,10 +5,13 @@ # Makefile for the Alchemy Au1xx0 CPUs, generic files. # -obj-y += prom.o irq.o puts.o time.o reset.o \ +obj-y += prom.o puts.o time.o reset.o \ clocks.o platform.o power.o setup.o \ sleeper.o dma.o dbdma.o gpio.o obj-$(CONFIG_PCI) += pci.o +obj-$(CONFIG_AU_GPIO_INT_CNTLR) += gpio_int.o +obj-$(CONFIG_AU_INT_CNTLR) += irq.o + EXTRA_CFLAGS += -Werror diff --git a/arch/mips/alchemy/common/gpio_int.c b/arch/mips/alchemy/common/gpio_int.c new file mode 100644 index 0000000..e6ae8a7 --- /dev/null +++ b/arch/mips/alchemy/common/gpio_int.c @@ -0,0 +1,265 @@ +/* + * Copyright 2008 RMI Corporation + * Author: Kevin Hickey + * + * 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 +#include +#include /* For functions called by do_IRQ */ +#include + +#include +#include + +struct gpio_int_regs *const gpio_int = + (struct gpio_int_regs *)(GPIO_INT_CTRLR_BASE + KSEG1); + +static struct gpio_int_cfg __initdata basic_irqs[]; + +void (*board_irq_dispatch)(int) = NULL; + +#ifdef CONFIG_SOC_AU13XX +static struct gpio_int_cfg __initdata basic_irqs[] = { + { AU1300_IRQ_DDMA, 1, LEVEL_HIGH, HW_INT_1, DEV_CTRL }, + + { AU1300_IRQ_RTC_TICK, 1, RISING, HW_INT_1, DEV_CTRL }, + { AU1300_IRQ_TOY_TICK, 1, RISING, HW_INT_1, DEV_CTRL }, + + { AU1300_IRQ_LCD, 1, LEVEL_HIGH, HW_INT_1, DEV_CTRL }, + + { AU1300_IRQ_UART1, 1, LEVEL_HIGH, HW_INT_1, DEV_CTRL }, + { AU1300_IRQ_UART1, 1, LEVEL_HIGH, HW_INT_1, DEV_CTRL }, + { AU1300_IRQ_UART2, 1, LEVEL_HIGH, HW_INT_1, DEV_CTRL }, + { AU1300_IRQ_UART3, 1, LEVEL_HIGH, HW_INT_1, DEV_CTRL }, + + { AU1300_IRQ_SD1, 1, LEVEL_HIGH, HW_INT_1, DEV_CTRL }, + { AU1300_IRQ_SD2, 1, LEVEL_HIGH, HW_INT_1, DEV_CTRL }, + + { AU1300_IRQ_USB, 1, LEVEL_HIGH, HW_INT_1, DEV_CTRL }, + + { AU1300_IRQ_BSA, 1, LEVEL_HIGH, HW_INT_1, DEV_CTRL }, + { AU1300_IRQ_MPE, 1, RISING, HW_INT_1, DEV_CTRL }, + { AU1300_IRQ_ITE, 1, LEVEL_HIGH, HW_INT_1, DEV_CTRL }, + + { AU1300_IRQ_RTCMATCH_1, 1, RISING, HW_INT_1, DEV_CTRL }, + { AU1300_IRQ_RTCMATCH_1, 1, RISING, HW_INT_1, DEV_CTRL }, + { AU1300_IRQ_RTCMATCH_2, 0, RISING, HW_INT_0, DEV_CTRL }, + + { AU1300_IRQ_TOYMATCH_1, 1, RISING, HW_INT_1, DEV_CTRL }, + { AU1300_IRQ_TOYMATCH_1, 1, RISING, HW_INT_1, DEV_CTRL }, + { AU1300_IRQ_TOYMATCH_2, 1, RISING, HW_INT_1, DEV_CTRL }, + + + /* KH: TODO - Move this to the board file. */ + { 5, 0, LEVEL_HIGH, HW_INT_0, GPIO_IN }, +}; + +/* + * KH: TODO - Consider moving to board specific location... + */ +static struct gpio_int_cfg __initdata basic_gpios[] = { + { 32, 0, DISABLED, HW_INT_0, DEV_CTRL }, + { 33, 0, DISABLED, HW_INT_0, DEV_CTRL }, + { 34, 0, DISABLED, HW_INT_0, DEV_CTRL }, + { 35, 0, DISABLED, HW_INT_0, DEV_CTRL }, + { 36, 0, DISABLED, HW_INT_0, DEV_CTRL }, + { 37, 0, DISABLED, HW_INT_0, DEV_CTRL }, +}; +#endif + +int __initdata nr_basic_irqs = ARRAY_SIZE(basic_irqs); + +/* + **************************************************************************** + * Functions and delcaration for irq_chip + **************************************************************************** + */ +void gpio_int_ack(unsigned int irq) +{ + u32 intr = irq - GPINT_LINUX_IRQ_OFFSET; + u32 bank = GPINT_BANK_FROM_INT(intr); + u32 bit = GPINT_BIT_FROM_INT(bank, intr); + + au_iowrite32(bit, &gpio_int->int_pend[bank]); +} + +void gpio_int_mask(unsigned int irq) +{ + u32 intr = irq - GPINT_LINUX_IRQ_OFFSET; + u32 bank = GPINT_BANK_FROM_INT(intr); + u32 bit = GPINT_BIT_FROM_INT(bank, intr); + + au_iowrite32(bit, &gpio_int->int_maskclr[bank]); +} + +void gpio_int_unmask(unsigned int irq) +{ + u32 intr = irq - GPINT_LINUX_IRQ_OFFSET; + u32 bank = GPINT_BANK_FROM_INT(intr); + u32 bit = GPINT_BIT_FROM_INT(bank, intr); + + au_iowrite32(bit, &gpio_int->int_mask[bank]); +} + +void gpio_int_mask_ack(unsigned int irq) +{ + u32 intr = irq - GPINT_LINUX_IRQ_OFFSET; + u32 bank = GPINT_BANK_FROM_INT(intr); + u32 bit = GPINT_BIT_FROM_INT(bank, intr); + + au_iowrite32(bit, &gpio_int->int_maskclr[bank]); + au_iowrite32(bit, &gpio_int->int_pend[bank]); +} + +static struct irq_chip gpio_int_irq_type = { + .name = "Au GPIO/INT", + .ack = gpio_int_ack, + .mask = gpio_int_mask, + .unmask = gpio_int_unmask, + .mask_ack = gpio_int_mask_ack +}; +/*****************************************************************************/ + +void set_pin_cfg(const struct gpio_int_cfg *cfg) +{ + u32 tmp; + tmp = GPINT_PINCTL_N(cfg->pinctl); + tmp |= GPINT_INTLINE_N(cfg->intline); + tmp |= GPINT_INTCFG_N(cfg->intcfg); + tmp |= cfg->intwake ? GPINT_INTWAKE_ENABLE : 0; + au_iowrite32(tmp, &gpio_int->gp_int[cfg->number]); +} + +void set_gpio(u8 gpio, u8 value) +{ + u32 bank = GPINT_BANK_FROM_GPIO(gpio); + u32 bit = GPINT_BIT_FROM_GPIO(bank, gpio); + + if (value == 0) + au_iowrite32(1 << bit, &gpio_int->pin_valclr[bank]); + else + au_iowrite32(1 << bit, &gpio_int->pin_val[bank]); +} + +u8 get_gpio(u8 gpio) +{ + u32 bank = GPINT_BANK_FROM_GPIO(gpio); + u32 bit = GPINT_BIT_FROM_GPIO(bank, gpio); + u32 tmp; + + tmp = au_ioread32(&gpio_int->pin_val[bank]); + return tmp >> bit; +} + + +void __init arch_init_irq(void) +{ + int i; + + /* + * Initialize the basic MIPS interrupt components. + */ + mips_cpu_irq_init(); + + for (i = 0; i < GPINT_NUM_BANKS; ++i) + gpio_int->int_maskclr[i] = ~0UL; + + + for (i = 0; i < ARRAY_SIZE(basic_gpios); ++i) + set_pin_cfg(&basic_gpios[i]); + + for (i = 0; i < nr_basic_irqs; ++i) { + printk(KERN_DEBUG "Initializing IRQ %d\n", + basic_irqs[i].number); + set_pin_cfg(&basic_irqs[i]); + if (basic_irqs[i].intcfg == LEVEL_LOW) + set_irq_chip_and_handler_name( + basic_irqs[i].number + GPINT_LINUX_IRQ_OFFSET, + &gpio_int_irq_type, + handle_level_irq, + "lowlevel"); + else if (basic_irqs[i].intcfg == LEVEL_HIGH) + set_irq_chip_and_handler_name( + basic_irqs[i].number + GPINT_LINUX_IRQ_OFFSET, + &gpio_int_irq_type, + handle_level_irq, + "highlevel"); + else if (basic_irqs[i].intcfg == FALLING) + set_irq_chip_and_handler_name( + basic_irqs[i].number + GPINT_LINUX_IRQ_OFFSET, + &gpio_int_irq_type, + handle_edge_irq, + "fallingedge"); + else if (basic_irqs[i].intcfg == RISING) + set_irq_chip_and_handler_name( + basic_irqs[i].number + GPINT_LINUX_IRQ_OFFSET, + &gpio_int_irq_type, + handle_edge_irq, + "risingedge"); + else if (basic_irqs[i].intcfg == ANY_CHANGE) + set_irq_chip_and_handler_name( + basic_irqs[i].number + GPINT_LINUX_IRQ_OFFSET, + &gpio_int_irq_type, + handle_edge_irq, + "bothedge"); + else + set_irq_chip( + basic_irqs[i].number + GPINT_LINUX_IRQ_OFFSET, + &gpio_int_irq_type); + } + + set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4); + + board_init_irq(); +} + +asmlinkage void plat_irq_dispatch(void) +{ + unsigned int intr; + u32 bank; + u32 reg_msk; + unsigned int pending = read_c0_status() & read_c0_cause(); + /* + * C0 timer tick + */ + if (pending & CAUSEF_IP7) + do_IRQ(MIPS_CPU_IRQ_BASE + 7); + else if (pending & (CAUSEF_IP2 | CAUSEF_IP3)) { + intr = au_ioread32(&gpio_int->pri_enc); + bank = GPINT_BANK_FROM_INT(intr); + reg_msk = GPINT_BIT_FROM_INT(bank, intr); + + if (intr != 127) { + if (board_irq_dispatch) + board_irq_dispatch(intr); + + do_IRQ(GPINT_LINUX_IRQ_OFFSET + intr); + } + } else { + printk(KERN_WARNING + "ALCHEMY GPIO_INT: Unexpected cause was set. %08x\n", + pending); + spurious_interrupt(); + } + +} + diff --git a/arch/mips/alchemy/devboards/Makefile b/arch/mips/alchemy/devboards/Makefile index 0d2d224..8cce4d0 100644 --- a/arch/mips/alchemy/devboards/Makefile +++ b/arch/mips/alchemy/devboards/Makefile @@ -17,3 +17,8 @@ obj-$(CONFIG_MIPS_DB1500) += db1x00/ obj-$(CONFIG_MIPS_DB1550) += db1x00/ obj-$(CONFIG_MIPS_BOSPORUS) += db1x00/ obj-$(CONFIG_MIPS_MIRAGE) += db1x00/ + +# These two files are used only by DB1300 today but will be used by DB1200 and +# possibly others in the future. +obj-$(CONFIG_MIPS_DB1300) += cascade_irq.o +obj-$(CONFIG_MIPS_DB1300) += leds.o diff --git a/arch/mips/alchemy/devboards/cascade_irq.c b/arch/mips/alchemy/devboards/cascade_irq.c new file mode 100644 index 0000000..6d0a965 --- /dev/null +++ b/arch/mips/alchemy/devboards/cascade_irq.c @@ -0,0 +1,142 @@ +/* + * Copyright 2003-2008 RMI Corporation. All rights reserved. + * Author: Kevin Hickey + * + * 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 BY RMI Corporation '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 RMI OR CONTRIBUTORS 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 +#include +#include +#include +#include +#include + +#include + +/* + * The following must be declared/defined in an included file: + * - volatile struct bcsr_regs (declared) + * (which much include fields int_status, intset_mask, intclr_mask, intset, + * and intclr) + * - volatile struct bcsr_regs *const bcsr (defined) + * - CASCADE_IRQ_MIN + * - CASCADE_IRQ_MAX + * - CASCADE_IRQ_TYPE_STRING + * - CASCADE_IRQ (System IRQ to which the cascade is connected) + */ + +void __init board_init_irq(void); + +irqreturn_t cascade_handler(int irq, void *dev_id) +{ + u16 int_status = au_ioread16(&db_bcsr->int_status); + int irq_in_service; + + au_iowrite16(int_status, &db_bcsr->int_status); + for ( ; int_status; int_status &= int_status - 1) { + irq_in_service = CASCADE_IRQ_MIN + __ffs(int_status); + db_set_hex((u8)(irq_in_service)); + do_IRQ(irq_in_service); + } + + return IRQ_RETVAL(1); +} + +DEFINE_MUTEX(cascade_use_count_mutex); +static int cascade_use_count; + +static void cascade_mask(unsigned int irq) +{ + au_iowrite16(1 << (irq - CASCADE_IRQ_MIN), &db_bcsr->intclr_mask); +} + +static void cascade_unmask(unsigned int irq) +{ + au_iowrite16(1 << (irq - CASCADE_IRQ_MIN), &db_bcsr->intset_mask); +} + +static void cascade_enable(unsigned int irq) +{ + au_iowrite16(1 << (irq - CASCADE_IRQ_MIN), &db_bcsr->intset); + cascade_unmask(irq); +} + +static void cascade_disable(unsigned int irq) +{ + au_iowrite16(1 << (irq - CASCADE_IRQ_MIN), &db_bcsr->intclr); + cascade_mask(irq); +} + + +static unsigned int cascade_startup(unsigned int irq) +{ + int retval = 0; + + mutex_lock(&cascade_use_count_mutex); + ++cascade_use_count; + if (cascade_use_count == 1) + retval = request_irq(CASCADE_IRQ, + &cascade_handler, 0, "Cascade", + &cascade_handler); + mutex_unlock(&cascade_use_count_mutex); + + cascade_enable(irq); + cascade_unmask(irq); + + return retval; +} + +static void cascade_shutdown(unsigned int irq) +{ + cascade_mask(irq); + cascade_disable(irq); + + mutex_lock(&cascade_use_count_mutex); + --cascade_use_count; + if (cascade_use_count == 0) + free_irq(CASCADE_IRQ, &cascade_handler); + mutex_unlock(&cascade_use_count_mutex); +} + +static struct irq_chip cascade_irq_type = { + .name = CASCADE_IRQ_TYPE_STRING, + .startup = cascade_startup, + .shutdown = cascade_shutdown, + .mask = cascade_mask, + .enable = cascade_enable, + .disable = cascade_disable, + .unmask = cascade_unmask, + .mask_ack = cascade_mask +}; + +void __init board_init_irq(void) +{ + int irq; + + for (irq = CASCADE_IRQ_MIN; + irq < CASCADE_IRQ_MAX; ++irq) { + printk(KERN_DEBUG "Initializing IRQ %d\n", irq); + set_irq_chip_and_handler(irq, &cascade_irq_type, + handle_level_irq); + cascade_disable(irq); + } +} diff --git a/arch/mips/alchemy/devboards/leds.c b/arch/mips/alchemy/devboards/leds.c new file mode 100644 index 0000000..75be345 --- /dev/null +++ b/arch/mips/alchemy/devboards/leds.c @@ -0,0 +1,58 @@ +/* + * Copyright 2003-2008 RMI Corporation. All rights reserved. + * Author: Kevin Hickey + * + * 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 BY RMI Corporation '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 RMI OR CONTRIBUTORS 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 +#include + +/* + * Requires the following to be defined in the board-specifc .h file: + * - HEX_REGS_KSEG1_ADDR + * - struct hex_regs with members: + * - hex (set the hex value) + * - BCSR_REGS_KSEG1_ADDR + * - struct bcsr_regs + */ + +static hex_regs *const hex = (hex_regs *)(HEX_REGS_KSEG1_ADDR); + +/* + * Takes a u8 because though the register is 16 bits, only 8 appear + */ +void db_set_hex(u8 val) +{ + au_iowrite16((u16)val, &hex->hex); +} + +/* + * 2 dots use the least significant 2 bits + * Setting a bit lights the LED (opposite of the register) + */ +void db_set_hex_dots(u8 val) +{ + u16 leds = au_ioread16(&db_bcsr->disk_leds); + leds |= 0x3; + leds &= (~(val & 0x3)); + au_iowrite16(leds, &db_bcsr->disk_leds); +} diff --git a/arch/mips/include/asm/mach-au1x00/gpio_int.h b/arch/mips/include/asm/mach-au1x00/gpio_int.h new file mode 100644 index 0000000..f1b11fa --- /dev/null +++ b/arch/mips/include/asm/mach-au1x00/gpio_int.h @@ -0,0 +1,237 @@ +/* + * Copyright 2008 RMI Corporation + * Author: Kevin Hickey + * + * Defines and macros for the GPIO and Interrupt controller for Alchemy, + * introduced in the Au13xx series. + * + * 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. + */ +#ifndef _GPIO_INT_H +#define _GPIO_INT_H + +#include + +/* + * There are a total 128 'channels' defined by the Au13xx databook. However, + * this requires 4 sperate 32bit registers for programming. Each register is + * called a 'bank' for ease of use. + */ +#define GPINT_BANK0 0 +#define GPINT_BANK1 1 +#define GPINT_BANK2 2 +#define GPINT_BANK3 3 + +#define GPINT_NUM_BANKS 4 /* 0-3 */ +#define GPINT_MAX_BANK (GPINT_BANK3) + +#define GPINT_GPIO_PER_BANK 32 +#define GPINT_INTS_PER_BANK GPINT_GPIO_PER_BANK + +/* Total number of interrupts our architecture allows */ +#define GPINT_MAX_INTS (GPINT_NUM_BANKS*GPINT_INTS_PER_BANK) + +/* Current maximum supported GPIO/INTERRUPTs */ +#define GPINT_NUM_GPIO GPINT_MAX_INTS +#define GPINT_NUM_INTERRUPTS GPINT_MAX_INTS + +/* Starting GPIO/INTERRUPT for each bank */ +#define GPINT_BANK0_START 0 +#define GPINT_BANK1_START 32 +#define GPINT_BANK2_START 64 +#define GPINT_BANK3_START 96 + +/* divide by 32 to get bank */ +#define GPINT_BANK_FROM_GPIO(n) (n>>5) +#define GPINT_BANK_FROM_INT(n) GPINT_BANK_FROM_GPIO(n) +/* multiply by 32 to get base */ +#define GPINT_BIT_FROM_GPIO(b, n) (1<<(n-(b<<5))) +#define GPINT_BIT_FROM_INT(b, n) GPINT_BIT_FROM_GPIO(b, n) + +struct gpio_int_regs { + /* R/W1S */ + /* u32 pin_val0; 0x00 */ + /* u32 pin_val1; 0x04 */ + /* u32 pin_val2; 0x08 */ + /* u32 pin_val3; 0x0C */ + u32 pin_val[GPINT_NUM_BANKS]; + + /* W1C */ + /* u32 pin_valclr0 0x10 */ + /* u32 pin_valclr1; 0x14 */ + /* u32 pin_valclr2; 0x18 */ + /* u32 pin_valclr3; 0x1C */ + u32 pin_valclr[GPINT_NUM_BANKS]; + + /* R/W1C */ + /* u32 int_pend0; 0x20 */ + /* u32 int_pend1; 0x24 */ + /* u32 int_pend2; 0x28 */ + /* u32 int_pend3; 0x2c */ + u32 int_pend[GPINT_NUM_BANKS]; + + u32 pri_enc; /* 0x30 */ + u32 _resvd0[3]; /* 0x34-0x3c */ + + /* R/W1S */ + /* u32 int_mask0; 0x40 */ + /* u32 int_mask1; 0x44 */ + /* u32 int_mask2; 0x48 */ + /* u32 int_mask3; 0x4c */ + u32 int_mask[GPINT_NUM_BANKS]; + + /* W1C */ + /* u32 int_maskclr0; 0x50 */ + /* u32 int_maskclr1; 0x54 */ + /* u32 int_maskclr2; 0x58 */ + /* u32 int_maskclr3; 0x5C */ + u32 int_maskclr[GPINT_NUM_BANKS]; + + /* R/W */ + u32 dma_sel; /* 0x60 */ + u32 _resvd1[(0x80-0x64)/4]; /* 0x64-0x7C */ + + /* W */ + /* u32 dev_sel0; 0x80 */ + /* u32 dev_sel1; 0x84 */ + /* u32 dev_sel2; 0x88 */ + /* u32 dev_sel3; 0x8C */ + u32 dev_sel[GPINT_NUM_BANKS]; + + /* W */ + /* u32 dev_selclr0; 0x90 */ + /* u32 dev_selclr1; 0x94 */ + /* u32 dev_selclr2; 0x98 */ + /* u32 dev_selclr3; 0x9C */ + u32 dev_selclr[GPINT_NUM_BANKS]; + + /* R */ + /* u32 reset_val0; 0xA0 */ + /* u32 reset_val1; 0xA4 */ + /* u32 reset_val2; 0xA8 */ + /* u32 reset_val3; 0xAC */ + u32 reset_val[GPINT_NUM_BANKS]; + + /* 0xB0 - 0xFFC */ + u32 _resvd2[(0x1000-0xB0)/4]; + + /* R/W -- when interrupt mask is clear */ + /* R -- when interrupt mask is set */ + /* u32 gp_int0; 0x1000 */ + /* u32 gp_int1; 0x1004 */ + /* u32 gp_int2; 0x1008 */ + /* u32 gp_int2; 0x100C */ + /* u32 gp_intN; 0x1000 + (N*4) */ + u32 gp_int[GPINT_MAX_INTS]; +}; + +extern struct gpio_int_regs *const gpio_int; + +#define GPINT_DMASEL_DMA0 (0) +#define GPINT_DMASEL_DMA0_N(n) (((n)&0xFF)< + * + * Defines and macros for the GPIO and Interrupt controller for Alchemy, + * introduced in the Au13xx series. + * + * 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. + */ +#ifndef _MACH_AU1X00_INT_H +#define _MACH_AU1X00_INT_H + +#define NR_IRQS 255 +#define MIPS_CPU_IRQ_BASE 0 + +#endif /* _MACH_AU1X00_INT_H */ -- 1.5.4.3