Set Rev 2.x 86xx PIC in mixed mode.
authorHaiying Wang <haiying.wang@freescale.com>
Thu, 7 Dec 2006 16:35:55 +0000 (10:35 -0600)
committerJon Loeliger <jdl@freescale.com>
Thu, 22 Mar 2007 16:02:35 +0000 (11:02 -0500)
Prevent false interrupt from hanging Linux as MSR[EE] is set
to enable interrupts by changing the PIC out of the default
pass through mode into mixed mode.

Signed-off-by: Haiying Wang <haiying.wang@freescale.com>
Signed-off-by: Jon Loeliger <jdl@freescale.com>
cpu/mpc86xx/interrupts.c
include/asm-ppc/immap_86xx.h

index 1df6cdc..49820bb 100644 (file)
@@ -80,6 +80,26 @@ int interrupt_init(void)
 {
        int ret;
 
+       /*
+        * The IRQ0 on Rev 2 is pulled high (low in Rev 1.x) to
+        * implement PEX10 errata.  As INT is active high, it
+        * will cause core to take 0x500 interrupt.
+        *
+        * Due to the PIC's default pass through mode, as soon
+        * as interrupts are enabled (MSR[EE] = 1), an interrupt
+        * will be taken and u-boot will hang.  This is due to a
+        * hardware change (per an errata fix) on new revisions
+        * of the board with Rev 2.x parts.
+        *
+        * Setting the PIC to mixed mode prevents the hang.
+        */
+       if ((get_svr() & 0xf0) == 0x20) {
+               volatile immap_t *immr = (immap_t *)CFG_IMMR;
+               immr->im_pic.gcr = MPC86xx_PICGCR_RST;
+               while (immr->im_pic.gcr & MPC86xx_PICGCR_RST);
+               immr->im_pic.gcr = MPC86xx_PICGCR_MODE;
+       }
+
        /* call cpu specific function from $(CPU)/interrupts.c */
        ret = interrupt_init_cpu(&decrementer_count);
 
index a5552c4..0e3fc34 100644 (file)
@@ -721,6 +721,8 @@ typedef struct ccsr_pic {
        uint    frr;            /* 0x41000 - Feature Reporting Register */
        char    res10[28];
        uint    gcr;            /* 0x41020 - Global Configuration Register */
+#define MPC86xx_PICGCR_RST     0x80000000
+#define MPC86xx_PICGCR_MODE    0x20000000
        char    res11[92];
        uint    vir;            /* 0x41080 - Vendor Identification Register */
        char    res12[12];