microblaze: Read information about timer/interrupts from DT
Read information about timer and interrupts from DT. This is the first small step to move timer and intc to DM. Signed-off-by: Michal Simek <michal.simek@xilinx.com>utp
parent
66de226f9f
commit
9aa65cab73
|
@ -10,10 +10,13 @@
|
||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <command.h>
|
#include <command.h>
|
||||||
|
#include <fdtdec.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <asm/microblaze_intc.h>
|
#include <asm/microblaze_intc.h>
|
||||||
#include <asm/asm.h>
|
#include <asm/asm.h>
|
||||||
|
|
||||||
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
void enable_interrupts(void)
|
void enable_interrupts(void)
|
||||||
{
|
{
|
||||||
debug("Enable interrupts for the whole CPU\n");
|
debug("Enable interrupts for the whole CPU\n");
|
||||||
|
@ -113,9 +116,31 @@ int interrupt_init(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
#ifdef CONFIG_OF_CONTROL
|
||||||
|
const void *blob = gd->fdt_blob;
|
||||||
|
int node = 0;
|
||||||
|
|
||||||
|
debug("INTC: Initialization\n");
|
||||||
|
|
||||||
|
node = fdt_node_offset_by_compatible(blob, node,
|
||||||
|
"xlnx,xps-intc-1.00.a");
|
||||||
|
if (node != -1) {
|
||||||
|
fdt_addr_t base = fdtdec_get_addr(blob, node, "reg");
|
||||||
|
if (base == FDT_ADDR_T_NONE)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
debug("INTC: Base addr %lx\n", base);
|
||||||
|
intc = (microblaze_intc_t *)base;
|
||||||
|
irq_no = fdtdec_get_int(blob, node, "xlnx,num-intr-inputs", 0);
|
||||||
|
debug("INTC: IRQ NO %x\n", irq_no);
|
||||||
|
} else {
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
#else
|
||||||
#if defined(CONFIG_SYS_INTC_0_ADDR) && defined(CONFIG_SYS_INTC_0_NUM)
|
#if defined(CONFIG_SYS_INTC_0_ADDR) && defined(CONFIG_SYS_INTC_0_NUM)
|
||||||
intc = (microblaze_intc_t *)CONFIG_SYS_INTC_0_ADDR;
|
intc = (microblaze_intc_t *)CONFIG_SYS_INTC_0_ADDR;
|
||||||
irq_no = CONFIG_SYS_INTC_0_NUM;
|
irq_no = CONFIG_SYS_INTC_0_NUM;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
if (irq_no) {
|
if (irq_no) {
|
||||||
vecs = calloc(1, sizeof(struct irq_action) * irq_no);
|
vecs = calloc(1, sizeof(struct irq_action) * irq_no);
|
||||||
|
|
|
@ -7,9 +7,12 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
|
#include <fdtdec.h>
|
||||||
#include <asm/microblaze_timer.h>
|
#include <asm/microblaze_timer.h>
|
||||||
#include <asm/microblaze_intc.h>
|
#include <asm/microblaze_intc.h>
|
||||||
|
|
||||||
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
volatile int timestamp = 0;
|
volatile int timestamp = 0;
|
||||||
microblaze_timer_t *tmr;
|
microblaze_timer_t *tmr;
|
||||||
|
|
||||||
|
@ -29,8 +32,10 @@ void __udelay(unsigned long usec)
|
||||||
while ((get_timer(0) - i) < (usec / 1000))
|
while ((get_timer(0) - i) < (usec / 1000))
|
||||||
;
|
;
|
||||||
} else {
|
} else {
|
||||||
|
#ifndef CONFIG_OF_CONTROL
|
||||||
for (i = 0; i < (usec * XILINX_CLOCK_FREQ / 10000000); i++)
|
for (i = 0; i < (usec * XILINX_CLOCK_FREQ / 10000000); i++)
|
||||||
;
|
;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,12 +52,44 @@ int timer_init (void)
|
||||||
u32 preload = 0;
|
u32 preload = 0;
|
||||||
u32 ret = 0;
|
u32 ret = 0;
|
||||||
|
|
||||||
|
#ifdef CONFIG_OF_CONTROL
|
||||||
|
const void *blob = gd->fdt_blob;
|
||||||
|
int node = 0;
|
||||||
|
u32 cell[2];
|
||||||
|
|
||||||
|
debug("TIMER: Initialization\n");
|
||||||
|
|
||||||
|
node = fdt_node_offset_by_compatible(blob, node,
|
||||||
|
"xlnx,xps-timer-1.00.a");
|
||||||
|
if (node != -1) {
|
||||||
|
fdt_addr_t base = fdtdec_get_addr(blob, node, "reg");
|
||||||
|
if (base == FDT_ADDR_T_NONE)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
debug("TIMER: Base addr %lx\n", base);
|
||||||
|
tmr = (microblaze_timer_t *)base;
|
||||||
|
|
||||||
|
ret = fdtdec_get_int_array(blob, node, "interrupts",
|
||||||
|
cell, ARRAY_SIZE(cell));
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
irq = cell[0];
|
||||||
|
debug("TIMER: IRQ %x\n", irq);
|
||||||
|
|
||||||
|
preload = fdtdec_get_int(blob, node, "clock-frequency", 0);
|
||||||
|
preload /= CONFIG_SYS_HZ;
|
||||||
|
} else {
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
#if defined(CONFIG_SYS_TIMER_0_ADDR) && defined(CONFIG_SYS_INTC_0_NUM)
|
#if defined(CONFIG_SYS_TIMER_0_ADDR) && defined(CONFIG_SYS_INTC_0_NUM)
|
||||||
preload = XILINX_CLOCK_FREQ / CONFIG_SYS_HZ;
|
preload = XILINX_CLOCK_FREQ / CONFIG_SYS_HZ;
|
||||||
irq = CONFIG_SYS_TIMER_0_IRQ;
|
irq = CONFIG_SYS_TIMER_0_IRQ;
|
||||||
tmr = (microblaze_timer_t *) (CONFIG_SYS_TIMER_0_ADDR);
|
tmr = (microblaze_timer_t *) (CONFIG_SYS_TIMER_0_ADDR);
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
if (tmr && preload && irq >= 0) {
|
if (tmr && preload && irq >= 0) {
|
||||||
tmr->loadreg = preload;
|
tmr->loadreg = preload;
|
||||||
tmr->control = TIMER_INTERRUPT | TIMER_RESET;
|
tmr->control = TIMER_INTERRUPT | TIMER_RESET;
|
||||||
|
|
Loading…
Reference in New Issue