Files
beaglefw/omap35x_intc.c
2013-06-21 22:14:11 +02:00

88 lines
2.5 KiB
C

#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "omap35x_intc.h"
#include "cortexa8.h"
static volatile uint32_t *const intc_sysconfig = (uint32_t*)0x48200010;
static volatile uint32_t *const intc_idle = (uint32_t*)0x48200050;
static volatile uint32_t *const intc_mir_clear0 = (uint32_t*)0x48200088;
static volatile uint32_t *const intc_mir_clear1 = (uint32_t*)0x482000a8;
static volatile uint32_t *const intc_mir_clear2 = (uint32_t*)0x482000c8;
static volatile uint32_t *const intc_mir_set0 = (uint32_t*)0x4820008c;
static volatile uint32_t *const intc_mir_set1 = (uint32_t*)0x482000ac;
static volatile uint32_t *const intc_mir_set2 = (uint32_t*)0x482000cc;
static volatile uint32_t *const intc_sir_irq = (uint32_t*)0x48200040;
static volatile uint32_t *const intc_control = (uint32_t*)0x48200048;
static volatile uint32_t *const intc_ilr = (uint32_t*)0x48200100; // 96 words
static omap35x_intc_hfunc handler_tbl[96];
static void* handler_data[96];
void omap35x_intc_init() {
// Interrupts should (still) be disabled from boot
assert(!cortexa8_get_int());
memset(handler_tbl, 0, sizeof(omap35x_intc_hfunc)*96);
*intc_sysconfig = 0x1; // Autoidle = 1
*intc_idle = 0x2; // Turbo = 1, Funcidle = 0
// Disable all ints
*intc_mir_set0 = 0xffffffff;
*intc_mir_set1 = 0xffffffff;
*intc_mir_set2 = 0xffffffff;
}
void omap35x_intc_register(int irq, omap35x_intc_hfunc handler, void *data, int prio) {
assert(irq >= 0 && irq <= 95);
assert(prio >= 0 && prio <= 63);
handler_tbl[irq] = handler;
handler_data[irq] = data;
intc_ilr[irq] = prio<<2;
}
void omap35x_intc_ena(int irq) {
assert(irq >= 0 && irq <= 95);
assert(handler_tbl[irq] != NULL);
int i = irq/32, j = irq%32;
if(i == 0)
*intc_mir_clear0 = (1<<j);
else if(i == 1)
*intc_mir_clear1 = (1<<j);
else //if(i == 2)
*intc_mir_clear2 = (1<<j);
}
void omap35x_intc_dis(int irq) {
assert(irq >= 0 && irq <= 95);
int i = irq/32, j = irq%32;
if(i == 0)
*intc_mir_set0 = (1<<j);
else if(i == 1)
*intc_mir_set1 = (1<<j);
else //if(i == 2)
*intc_mir_set2 = (1<<j);
}
void omap35x_intc_handler() __attribute__((interrupt ("IRQ")));
void omap35x_intc_handler() {
uint32_t sir = *intc_sir_irq;
int irq = sir&0x7f;
if(sir&0xffffff80) {
printf("WARNING: Spurious interrupt (%.8lx)\n", sir);
return;
}
assert(irq >= 0 && irq <= 95);
assert(handler_tbl[irq] != NULL);
handler_tbl[irq](handler_data[irq]);
*intc_control = 0x1;
__asm__ __volatile__ ("dsb");
}