Merge branch 'master' of git://www.denx.de/git/u-boot-mips
[oweals/u-boot.git] / cpu / mpc85xx / interrupts.c
index 745b3b2a4a3d991f935658501815eb1d78fcec7d..18e5377b32ba7c7abdd31f5e8c83ccfe38029750 100644 (file)
@@ -49,6 +49,22 @@ static __inline__ void set_msr(unsigned long msr)
        asm volatile("isync");
 }
 
+static __inline__ unsigned long get_dec (void)
+{
+       unsigned long val;
+
+       asm volatile ("mfdec %0":"=r" (val):);
+
+       return val;
+}
+
+
+static __inline__ void set_dec (unsigned long val)
+{
+       if (val)
+               asm volatile ("mtdec %0"::"r" (val));
+}
+
 void enable_interrupts (void)
 {
        set_msr (get_msr() | MSR_EE);
@@ -62,9 +78,48 @@ int disable_interrupts (void)
        return ((msr & MSR_EE) != 0);
 }
 
-/* interrupt is not supported yet */
 int interrupt_init (void)
 {
+       volatile ccsr_pic_t *pic = (void *)(CFG_MPC85xx_PIC_ADDR);
+
+       pic->gcr = MPC85xx_PICGCR_RST;
+       while (pic->gcr & MPC85xx_PICGCR_RST);
+       pic->gcr = MPC85xx_PICGCR_M;
+       decrementer_count = get_tbclk() / CFG_HZ;
+       mtspr(SPRN_TCR, TCR_PIE);
+       set_dec (decrementer_count);
+       set_msr (get_msr () | MSR_EE);
+
+#ifdef CONFIG_INTERRUPTS
+       pic->iivpr1 = 0x810002; /* 50220 enable ecm interrupts */
+       debug("iivpr1@%x = %x\n",&pic->iivpr1, pic->iivpr1);
+
+       pic->iivpr2 = 0x810002; /* 50240 enable ddr interrupts */
+       debug("iivpr2@%x = %x\n",&pic->iivpr2, pic->iivpr2);
+
+       pic->iivpr3 = 0x810003; /* 50260 enable lbc interrupts */
+       debug("iivpr3@%x = %x\n",&pic->iivpr3, pic->iivpr3);
+
+#ifdef CONFIG_PCI1
+       pic->iivpr8 = 0x810008; /* enable pci1 interrupts */
+       debug("iivpr8@%x = %x\n",&pic->iivpr8, pic->iivpr8);
+#endif
+#if defined(CONFIG_PCI2) || defined(CONFIG_PCIE2)
+       pic->iivpr9 = 0x810009; /* enable pci1 interrupts */
+       debug("iivpr9@%x = %x\n",&pic->iivpr9, pic->iivpr9);
+#endif
+#ifdef CONFIG_PCIE1
+       pic->iivpr10 = 0x81000a;        /* enable pcie1 interrupts */
+       debug("iivpr10@%x = %x\n",&pic->iivpr10, pic->iivpr10);
+#endif
+#ifdef CONFIG_PCIE3
+       pic->iivpr11 = 0x81000b;        /* enable pcie3 interrupts */
+       debug("iivpr11@%x = %x\n",&pic->iivpr11, pic->iivpr11);
+#endif
+
+       pic->ctpr=0;            /* 40080 clear current task priority register */
+#endif
+
        return (0);
 }
 
@@ -96,9 +151,9 @@ volatile ulong timestamp = 0;
  */
 void timer_interrupt(struct pt_regs *regs)
 {
-       printf ("*** Timer Interrupt *** ");
        timestamp++;
-
+       set_dec (decrementer_count);
+       mtspr(SPRN_TSR, TSR_PIS);
 #if defined(CONFIG_WATCHDOG)
        if ((timestamp % 1000) == 0)
                reset_85xx_watchdog();
@@ -120,7 +175,7 @@ void set_timer (ulong t)
        timestamp = t;
 }
 
-#if (CONFIG_COMMANDS & CFG_CMD_IRQ)
+#if defined(CONFIG_CMD_IRQ)
 
 /*******************************************************************************
  *
@@ -135,4 +190,4 @@ do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
        return 0;
 }
 
-#endif  /* CONFIG_COMMANDS & CFG_CMD_IRQ */
+#endif