summaryrefslogblamecommitdiffstats
path: root/c/src/lib/libbsp/powerpc/mvme5500/irq/GT64260Int.c
blob: a9daa3d2a8b9779ffd71f7a93093f5860dfb7234 (plain) (tree)























































                                                                        
                        




















































                                                                            
                                                        
 

                               


                                                      
                                  












                                                  
                                







                                                                            
                                                         
 

                               


                                                      
                                 












                                                  
                                








                                                                               
                                                       
 




                               


                                                     
                                 
















                                                             
                                








                                                                               
                                                        
 





                               


                                                     
                                 












                                                                
                                














                                                 
/* GT64260Int.c - GT64260 Interrupt controller support functions 
 *
 * Copyright 2003, 2004, Brookhaven National Laboratory and
 *                 Shuchen Kate Feng <feng1@bnl.gov>
 *
 * The license and distribution terms for this file may be
 * found in the file LICENSE in this distribution.
 *
 */
#include <libcpu/io.h>
#include <rtems/bspIo.h> /* for printk */

#include "bsp/gtreg.h"
#include "bsp/irq.h"

extern rtems_irq_prio BSPirqPrioTable[BSP_MAIN_IRQ_NUMBER];

rtems_GTirq_masks GT_GPPirq_cache=0; 
rtems_GTirq_masks GT_MAINirqLO_cache=0, GT_MAINirqHI_cache=0;

void BSP_GT64260INT_init()
{

    /* Page 401, Table 598:
     * Comm Unit Arbiter Control register :
     * bit 10:GPP interrupts as level sensitive(1) or edge sensitive(0).
     * We set the GPP interrupts to be edge sensitive.
     * MOTload default is set as level sensitive(1).
     */
    outl((inl(GT_CommUnitArb_Ctrl)& (~(1<<10))), GT_CommUnitArb_Ctrl);

    /* Initialize the interrupt related GT64260 registers */
    outl( 0, GT_CPU_INT_MASK_LO);
    outl( 0, GT_CPU_INT_MASK_HI);

    outl( 0, GT_PCI0_INT_MASK_LO);
    outl( 0, GT_PCI0_INT_MASK_HI);


    outl( 0, GT_PCI1_INT_MASK_LO);
    outl( 0, GT_PCI1_INT_MASK_HI);
 
    outl( 0, GT_CPU_INT0_MASK);
    outl( 0, GT_CPU_INT1_MASK);
    outl( 0, GT_CPU_INT2_MASK);
    outl( 0, GT_CPU_INT3_MASK);
    outl(0, GT_GPP_Interrupt_Mask);
    outl( 0, GT_GPP_Value);
    outl( 0, GT_GPP_Interrupt_Cause);
#if 0
    printk("watchdog timer 0x%x\n",inl(0xb410));
#endif
}

static void UpdateMainIrqTbl(int irqNum)
{
  int i=0, j, shifted=0;

#ifdef SHOW_MORE_INIT_SETTINGS
  unsigned long val2, val1;

  val2 = (MainIrqInTbl>>32) & 0xffffffff;
  val1 = MainIrqInTbl&0xffffffff;
  printk("irqNum %d, MainIrqInTbl 0x%x%x\n", irqNum, val2, val1); 
  printMainIrqTbl();
#endif

  /* If entry not in table*/
  if ( !((unsigned long long)(1LLU << irqNum) & MainIrqInTbl)) { 
      while ( mainIrqTbl[i]!=-1) {
        if (BSPirqPrioTable[irqNum]>BSPirqPrioTable[mainIrqTbl[i]]) {
          /* all other lower priority entries shifted right */
          for (j=MainIrqTblPtr;j>i; j--) 
              mainIrqTbl[j]=mainIrqTbl[j-1];
          mainIrqTbl[i]=irqNum;
          shifted=1;
          break;
       }
       i++;
     }
     if (!shifted) mainIrqTbl[MainIrqTblPtr]=irqNum;
     MainIrqInTbl |= (unsigned long long)(1LLU << irqNum);
     MainIrqTblPtr++;
  }
}

static void CleanMainIrqTbl(int irqNum)
{
  int i, j;

  if (((1LLU << irqNum) & MainIrqInTbl)) { /* If entry in table*/
     for (i=0; i<64; i++) {
       if (mainIrqTbl[i]==irqNum) {/*remove it from the entry */
          /* all other lower priority entries shifted left */
          for (j=i;j<MainIrqTblPtr; j++) 
              mainIrqTbl[j]=mainIrqTbl[j+1];
          MainIrqInTbl &= ~(1LLU << irqNum);
          MainIrqTblPtr--;
          break;
       }
     }
  }
}

/***************************************************************************
*
* BSP_enable_main_irq enables the corresponding bit in the low or high
* "main cause cpu int mask register".  
*
*/
void BSP_enable_main_irq(const rtems_irq_number irqNum) 
{
  unsigned              bitNum;
  rtems_interrupt_level level;

  bitNum = ((int)irqNum) - BSP_MICL_IRQ_LOWEST_OFFSET;

  rtems_interrupt_disable(level); 

#if DynamicIrqTbl 
  UpdateMainIrqTbl((int) irqNum);
#endif       
  if (bitNum <32) {
     GT_MAINirqLO_cache |= (1 << bitNum);
     outl(GT_MAINirqLO_cache, GT_CPU_INT_MASK_LO);
  }
  else {
     bitNum-=32;
     GT_MAINirqHI_cache |= (1 << bitNum);
     outl(GT_MAINirqHI_cache, GT_CPU_INT_MASK_HI);
  }
  rtems_interrupt_enable(level);
}

/***************************************************************************
*
* BSP_disable_main_irq disables the corresponding bit in the low or high
* main cause cpu int mask register. 
*
*/
void BSP_disable_main_irq(const rtems_irq_number irqNum) 
{
  unsigned              bitNum;
  rtems_interrupt_level level;

  bitNum = ((int)irqNum) - BSP_MICL_IRQ_LOWEST_OFFSET;

  rtems_interrupt_disable(level);

#if DynamicIrqTbl 
  CleanMainIrqTbl((int) irqNum);
#endif
  if (bitNum <32) {
     GT_MAINirqLO_cache &= ~(1 << bitNum);
     outl(GT_MAINirqLO_cache, GT_CPU_INT_MASK_LO);
  }
  else	{
     bitNum-=32;
     GT_MAINirqHI_cache &= ~(1 << bitNum);
     outl(GT_MAINirqHI_cache, GT_CPU_INT_MASK_HI);
  }
  rtems_interrupt_enable(level);
}

/******************************************************************************
*
* BSP_enable_gpp_irq enables the corresponding bit in the GPP interrupt
* mask register.  The interrupt level is numerically equivalent to the
* corresponding interrupt vector.
*
*/
void BSP_enable_gpp_irq(const rtems_irq_number irqNum) 
{
  unsigned              bitNum;
  unsigned int          mask;
  int                   group;
  int                   bit;
  rtems_interrupt_level level;

  bitNum = ((int)irqNum) - BSP_GPP_IRQ_LOWEST_OFFSET;

  rtems_interrupt_disable(level);

#if DynamicIrqTbl 
  group = bitNum/8;
  if ( !GPPinMainIrqTbl[group])  /* avoid duplicated entry */
     UpdateMainIrqTbl(BSP_MAIN_GPP7_0_IRQ+group);
  bit = bitNum%8;
  GPPinMainIrqTbl[group] |= (1<<bit);
#endif
 
  mask = 1 << bitNum;
  GT_GPPirq_cache |= mask;
  outl(GT_GPPirq_cache, GT_GPP_Interrupt_Mask);
#ifdef SHOW_MORE_INIT_SETTINGS
  printk("enable irqNum %d, bitnum %d \n", irqNum, bitNum);
  printk("GPP mask %d \n", inl(GT_GPP_Interrupt_Mask)); 
#endif

  rtems_interrupt_enable(level);
}

/******************************************************************************
*
* BSP_disable_gpp_irq disables the corresponding bit in the General Purpose
* Port Interrupt.  The interrupt level is numerically equivalent to the
* corresponding interrupt vector.
*
*/
void BSP_disable_gpp_irq(const rtems_irq_number irqNum) 
{
  unsigned              bitNum;
  unsigned int          mask;
  int                   group;
  int                   bit;
  rtems_interrupt_level level;


  bitNum = ((int)irqNum) - BSP_GPP_IRQ_LOWEST_OFFSET;

  rtems_interrupt_disable(level);
#if DynamicIrqTbl 
  group = bitNum/8;
  bit = bitNum%8;
  GPPinMainIrqTbl[group] &= ~(1<<bit);
  if ( !GPPinMainIrqTbl[group])/* If it's really the last one */
     CleanMainIrqTbl(BSP_MAIN_GPP7_0_IRQ+group);
#endif
#ifdef SHOW_MORE_INIT_SETTINGS
  printk("disable irqNum %d, bitnum %d \n", irqNum, bitNum);
#endif
  mask = ~ (1 << bitNum);
  GT_GPPirq_cache &= mask;
  outl(GT_GPPirq_cache, GT_GPP_Interrupt_Mask);
  rtems_interrupt_enable(level);
}

/* Only print ten entries for now */
void BSP_printMainIrqTbl()
{
  int i;

  printk("mainIrqTbl[10]={");
  for (i=0; i<10; i++)
    printk("%d,", mainIrqTbl[i]);
  printk("}\n");
  printk("GPPinMainIrqTbl 0x%x 0x%x 0x%x 0x%x\n",
	 GPPinMainIrqTbl[0], GPPinMainIrqTbl[1],
	 GPPinMainIrqTbl[2], GPPinMainIrqTbl[3]);
}