diff options
author | Stefan Richter <ichgeh@l--putt.de> | 2011-05-24 21:16:47 +0200 |
---|---|---|
committer | Stefan Richter <ichgeh@l--putt.de> | 2011-05-24 21:16:47 +0200 |
commit | 8afdac199224e7a88093c4c0fa6a4bc03a644d88 (patch) | |
tree | 656025126ea10e87aeaaa631b0cb506763f027e5 /nuttx | |
parent | d73914537ece09078706ed17a072fb0b29949210 (diff) |
Initial support for Nuttx on TI Calypso platform:
IRQ support for Calypso
Main patches Osmocom code to match Nuttx API
Diffstat (limited to 'nuttx')
-rw-r--r-- | nuttx/arch/arm/include/calypso/irq.h | 67 | ||||
-rw-r--r-- | nuttx/arch/arm/src/calypso/calypso_irq.c | 300 |
2 files changed, 367 insertions, 0 deletions
diff --git a/nuttx/arch/arm/include/calypso/irq.h b/nuttx/arch/arm/include/calypso/irq.h new file mode 100644 index 0000000000..1333a6e091 --- /dev/null +++ b/nuttx/arch/arm/include/calypso/irq.h @@ -0,0 +1,67 @@ +/**************************************************************************** + * arch/arm/include/calypso/irq.h + * Driver for Calypso IRQ controller + * + * (C) 2010 by Harald Welte <laforge@gnumonks.org> + * (C) 2011 by Stefan Richter <ichgeh@l--putt.de> + * + * All Rights Reserved + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + ****************************************************************************/ + +#ifndef __INCLUDE_NUTTX_IRQ_H +#error "This file should never be included directly! Use <nuttx/irq.h>" +#endif + +#ifndef _CALYPSO_IRQ_H +#define _CALYPSO_IRQ_H + +#ifndef __ASSEMBLY__ + +enum irq_nr { + IRQ_WATCHDOG = 0, + IRQ_TIMER1 = 1, + IRQ_TIMER2 = 2, + IRQ_TSP_RX = 3, + IRQ_TPU_FRAME = 4, + IRQ_TPU_PAGE = 5, + IRQ_SIMCARD = 6, + IRQ_UART_MODEM = 7, + IRQ_KEYPAD_GPIO = 8, + IRQ_RTC_TIMER = 9, + IRQ_RTC_ALARM_I2C = 10, + IRQ_ULPD_GAUGING = 11, + IRQ_EXTERNAL = 12, + IRQ_SPI = 13, + IRQ_DMA = 14, + IRQ_API = 15, + IRQ_SIM_DETECT = 16, + IRQ_EXTERNAL_FIQ = 17, + IRQ_UART_IRDA = 18, + IRQ_ULPD_GSM_TIMER = 19, + IRQ_GEA = 20, + _NR_IRQS +}; + +#endif /* __ASSEMBLY__ */ + +/* Don't use _NR_IRQS!!! Won't work in preprocessor... */ +#define NR_IRQS 21 + +#define IRQ_SYSTIMER IRQ_TIMER2 + +#endif /* _CALYPSO_IRQ_H */ diff --git a/nuttx/arch/arm/src/calypso/calypso_irq.c b/nuttx/arch/arm/src/calypso/calypso_irq.c new file mode 100644 index 0000000000..993e4758d0 --- /dev/null +++ b/nuttx/arch/arm/src/calypso/calypso_irq.c @@ -0,0 +1,300 @@ +/**************************************************************************** + * arch/arm/src/calypso/calypso_irq.c + * Driver for Calypso IRQ controller + * + * (C) 2010 by Harald Welte <laforge@gnumonks.org> + * (C) 2011 by Stefan Richter <ichgeh@l--putt.de> + * + * All Rights Reserved + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdio.h> +#include <stdint.h> +#include <nuttx/irq.h> +#include <nuttx/arch.h> +#include <arch/calypso/memory.h> + +#include "arm.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define BASE_ADDR_IRQ 0xfffffa00 +#define BASE_ADDR_IBOOT_EXC 0x0080001C + +enum irq_reg { + IT_REG1 = 0x00, + IT_REG2 = 0x02, + MASK_IT_REG1 = 0x08, + MASK_IT_REG2 = 0x0a, + IRQ_NUM = 0x10, + FIQ_NUM = 0x12, + IRQ_CTRL = 0x14, +}; + +#define ILR_IRQ(x) (0x20 + (x*2)) +#define IRQ_REG(x) ((void *)BASE_ADDR_IRQ + (x)) + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +volatile uint32_t *current_regs; +extern uint32_t _exceptions; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static uint8_t default_irq_prio[] = { + [IRQ_WATCHDOG] = 0xff, + [IRQ_TIMER1] = 0xff, + [IRQ_TIMER2] = 0xff, + [IRQ_TSP_RX] = 0, + [IRQ_TPU_FRAME] = 3, + [IRQ_TPU_PAGE] = 0xff, + [IRQ_SIMCARD] = 0xff, + [IRQ_UART_MODEM] = 8, + [IRQ_KEYPAD_GPIO] = 4, + [IRQ_RTC_TIMER] = 9, + [IRQ_RTC_ALARM_I2C] = 10, + [IRQ_ULPD_GAUGING] = 2, + [IRQ_EXTERNAL] = 12, + [IRQ_SPI] = 0xff, + [IRQ_DMA] = 0xff, + [IRQ_API] = 0xff, + [IRQ_SIM_DETECT] = 0, + [IRQ_EXTERNAL_FIQ] = 7, + [IRQ_UART_IRDA] = 2, + [IRQ_ULPD_GSM_TIMER] = 1, + [IRQ_GEA] = 0xff, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static void _irq_enable(enum irq_nr nr, int enable) +{ + uint16_t *reg = IRQ_REG(MASK_IT_REG1); + uint16_t val; + + if (nr > 15) { + reg = IRQ_REG(MASK_IT_REG2); + nr -= 16; + } + + val = readw(reg); + if (enable) + val &= ~(1 << nr); + else + val |= (1 << nr); + writew(val, reg); +} + +static void set_default_priorities(void) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(default_irq_prio); i++) { + uint16_t val; + uint8_t prio = default_irq_prio[i]; + if (prio > 31) + prio = 31; + + val = readw(IRQ_REG(ILR_IRQ(i))); + val &= ~(0x1f << 2); + val |= prio << 2; + writew(val, IRQ_REG(ILR_IRQ(i))); + } +} + +/* Install the exception handlers to where the ROM loader jumps */ +static void calypso_exceptions_install(void) +{ + uint32_t *exceptions_dst = (uint32_t *) BASE_ADDR_IBOOT_EXC; + uint32_t *exceptions_src = &_exceptions; + int i; + + for (i = 0; i < 7; i++) + *exceptions_dst++ = *exceptions_src++; + +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + * + * Description: + * Setup the IRQ and FIQ controllers + * + ****************************************************************************/ + +void up_irqinitialize(void) +{ + /* Prepare hardware */ + calypso_exceptions_install(); + current_regs = NULL; + + /* Switch to internal ROM */ + calypso_bootrom(1); + + /* set default priorities */ + set_default_priorities(); + + /* mask all interrupts off */ + writew(0xffff, IRQ_REG(MASK_IT_REG1)); + writew(0xffff, IRQ_REG(MASK_IT_REG2)); + + /* clear all pending interrupts */ + writew(0, IRQ_REG(IT_REG1)); + writew(0, IRQ_REG(IT_REG2)); + + /* enable interrupts globally to the ARM core */ +#ifndef CONFIG_SUPPRESS_INTERRUPTS + irqrestore(SVC_MODE | PSR_F_BIT); +#endif +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + if((unsigned)irq < NR_IRQS) + _irq_enable(irq, 0); +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + if((unsigned)irq < NR_IRQS) + _irq_enable(irq, 1); +} + +/**************************************************************************** + * Name: up_prioritize_irq + * + * Description: + * Set the priority of an IRQ. + * + ****************************************************************************/ + +#ifndef CONFIG_ARCH_IRQPRIO +int up_prioritize_irq(int nr, int prio) +{ + uint16_t val; + + if (prio == -1) + prio = default_irq_prio[nr]; + + if (prio > 31) + prio = 31; + + val = prio << 2; +/* + if (edge) + val |= 0x02; + if (fiq) + val |= 0x01; +*/ + writew(val, IRQ_REG(ILR_IRQ(nr))); + + return 0; // XXX: what's the return??? +} +#endif + +/**************************************************************************** + * Entry point for interrupts + ****************************************************************************/ + +void up_decodeirq(uint32_t *regs) +{ + uint8_t num, tmp; + uint32_t *saved_regs; + + /* XXX: What is this??? + * Passed to but ignored in IRQ handlers + * Only valid meaning is apparently non-NULL == IRQ context */ + saved_regs = (uint32_t *)current_regs; + current_regs = regs; + + /* Detect & deliver the IRQ */ + num = readb(IRQ_REG(IRQ_NUM)) & 0x1f; + irq_dispatch(num, regs); + + /* Start new IRQ agreement */ + tmp = readb(IRQ_REG(IRQ_CTRL)); + tmp |= 0x01; + writeb(tmp, IRQ_REG(IRQ_CTRL)); + + current_regs = saved_regs; +} + +/**************************************************************************** + * Entry point for FIQs + ****************************************************************************/ + +void calypso_fiq(void) +{ + uint8_t num, tmp; + uint32_t *regs; + + /* XXX: What is this??? + * Passed to but ignored in IRQ handlers + * Only valid meaning is apparently non-NULL == IRQ context */ + regs = (uint32_t *)current_regs; + current_regs = (uint32_t *)# + + /* Detect & deliver like an IRQ but we are in FIQ context */ + num = readb(IRQ_REG(FIQ_NUM)) & 0x1f; + irq_dispatch(num, regs); + + /* Start new FIQ agreement */ + tmp = readb(IRQ_REG(IRQ_CTRL)); + tmp |= 0x02; + writeb(tmp, IRQ_REG(IRQ_CTRL)); + + current_regs = regs; +} |