Exemple #1
0
//------------------------------------------------------------------------------
//
//  Function:  OEMInterruptEnable
//
//  This function enables the IRQ given its corresponding SysIntr value.
//  Function returns true if SysIntr is valid, else false.
//
BOOL OEMInterruptEnable(DWORD sysIntr, LPVOID pvData, DWORD cbData)
{
    BOOL rc = FALSE;
    const UINT32 *pIrqs;
    UINT32 count;

	UNREFERENCED_PARAMETER(pvData);
	UNREFERENCED_PARAMETER(cbData);

    OALMSG(OAL_INTR&&OAL_VERBOSE,(L"+OEMInterruptEnable(%d, 0x%x, %d)\r\n", sysIntr, pvData, cbData));

    // SYSINTR_VMINI & SYSINTR_TIMING are special cases
    if (sysIntr == SYSINTR_VMINI || sysIntr == SYSINTR_TIMING) {
        rc = TRUE;
        goto cleanUp;
    }

    // Obtain the SYSINTR's underlying IRQ number
    if (!OALIntrTranslateSysIntr(sysIntr, &count, &pIrqs)) {
        // Indicate invalid SysIntr
        OALMSG(OAL_ERROR, (
            L"ERROR: OEMInterruptEnable: IRQs are undefined for SysIntr %d\r\n", 
            sysIntr ));
        goto cleanUp;
    }

    // Enable the interrupt
    rc = OALIntrEnableIrqs(count, pIrqs);

cleanUp:    
    OALMSG(OAL_INTR&&OAL_VERBOSE, (L"-OEMInterruptEnable(rc = 1)\r\n"));
    return rc;
}
Exemple #2
0
//------------------------------------------------------------------------------
//
//  Function:  OEMInterruptMask
//
//  This function masks the IRQ given its corresponding SysIntr value.
//
//
VOID
OEMInterruptMask(DWORD SysIntr, BOOL mask)
{
	OALMSG(OAL_INTR&&OAL_VERBOSE, (L"+OEMInterruptMask(%d, %d)\r\n", SysIntr, mask));

	// Based on mask enable or disable
	if (mask)
	{
		OALIntrDisableIrqs(1, &g_oalSysIntr2Irq[SysIntr]);
	}
	else
	{
		OALIntrEnableIrqs(1, &g_oalSysIntr2Irq[SysIntr]);
	}

	OALMSG(OAL_INTR&&OAL_VERBOSE, (L"-OEMInterruptMask\r\n"));
}
Exemple #3
0
//------------------------------------------------------------------------------
//
//  Function:  OEMInterruptEnable
//
//  This function enables the IRQ given its corresponding SysIntr value.
//  Function returns true if SysIntr is valid, else false.
//
BOOL
OEMInterruptEnable(DWORD SysIntr, VOID* pData, DWORD dataSize)
{
	BOOL rc = FALSE;

	OALMSG(OAL_INTR&&OAL_VERBOSE,	(L"+OEMInterruptEnable(%d, 0x%x, %d)\r\n", SysIntr, pData, dataSize));

	// SYSINTR_VMINI & SYSINTR_TIMING are special cases
	if ((SysIntr == SYSINTR_VMINI) || (SysIntr == SYSINTR_TIMING))
	{
		rc = TRUE;
		goto cleanUp;
	}

	// Enable interrupts
	rc = OALIntrEnableIrqs(1, &g_oalSysIntr2Irq[SysIntr]);

cleanUp:

	OALMSG(OAL_INTR&&OAL_VERBOSE, (L"-OEMInterruptEnable(rc = 1)\r\n"));

	return rc;
}
Exemple #4
0
//------------------------------------------------------------------------------
//
//  Function:  BSPIntrInit
//
//  This function is called from OALIntrInit to initialize secondary interrupt
//  controller.
//
BOOL BSPIntrInit()
{
    UINT8 *pPIC1Edge, *pPIC2Edge;
    UINT32 irq;
    
    OALMSG(OAL_INTR&&OAL_FUNC, (L"+BSPIntrInit\r\n"));

    // Add static mapping for on chip devices...
    OALIntrStaticTranslate(SYSINTR_FIRMWARE + 0, IRQ_UART1);   // UART1

    // Add GPIO static mapping for RTC alarm
    OALIntrStaticTranslate(SYSINTR_RTC_ALARM, IRQ_GPIO);
    // And enable it (it will not occur until it is set in OEMSetAlarmTime)
    irq = IRQ_GPIO; OALIntrEnableIrqs(1, &irq);


    // Get and save uncached virtual addresses for VRC5477 and PIC1/PIC2
    g_pVRC5477Regs = OALPAtoUA(VRC5477_REG_PA);
    g_pPIC1Regs = OALPAtoUA(BSP_REG_PA_M1535_PIC1);
    g_pPIC2Regs = OALPAtoUA(BSP_REG_PA_M1535_PIC2);

    // M1535+ INTR uses positive logic (active on high), set VRC5477
    CLRPORT32(&g_pVRC5477Regs->INTPPES0, 1 << 4);

    // We have to enable PCI interrupts
    irq = IRQ_INTA; OALIntrEnableIrqs(1, &irq);
    irq = IRQ_INTB; OALIntrEnableIrqs(1, &irq);
    irq = IRQ_INTC; OALIntrEnableIrqs(1, &irq);
    irq = IRQ_INTD; OALIntrEnableIrqs(1, &irq);

    // PIC1/PIC2 edge registers are needed only for initialization
    pPIC1Edge = OALPAtoUA(BSP_REG_PA_M1535_EDGE1);
    pPIC2Edge = OALPAtoUA(BSP_REG_PA_M1535_EDGE2);
    
    // Initialize the 8259 PIC1
    OUTREG8(&g_pPIC1Regs->ctrl, 0x11);          // ICW1, cascade & ICW4
    OUTREG8(&g_pPIC1Regs->mask, IRQ_PIC_0);     // ICW2, vector to 32
    OUTREG8(&g_pPIC1Regs->mask, 0x04);          // ICW3, slave on IRQ 2
    OUTREG8(&g_pPIC1Regs->mask, 0x01);          // ICW4, normal EOI
    OUTREG8(&g_pPIC1Regs->ctrl, 0x0B);          // OCW2, read IS register
    OUTREG8(&g_pPIC1Regs->mask, 0xFF);          // OCW1, all disabled
    
    // Now initialize the 8259 PIC2
    OUTREG8(&g_pPIC2Regs->ctrl, 0x11);          // ICW1, cascade & ICW4
    OUTREG8(&g_pPIC2Regs->mask, IRQ_PIC_8);     // ICW2, vector to 40
    OUTREG8(&g_pPIC2Regs->mask, 0x02);          // ICW3, we are IRQ 2
    OUTREG8(&g_pPIC2Regs->mask, 0x01);          // ICW4, normal EOI
    OUTREG8(&g_pPIC2Regs->ctrl, 0x0B);          // OCW2, read IS register
    OUTREG8(&g_pPIC2Regs->mask, 0xFF);          // OCW1, all disabled

    // IRQ0-IRQ7 Edge sensitive(IRQ2 cannot be set to level sensitive)
    OUTREG8(pPIC1Edge, 0x00);

    // IRQ9&IRQ11 level (USB host, PCI INTC), other edge sensitive
    OUTREG8(pPIC2Edge, 0x0A);

    // Enable interrupt from PIC2 on PIC1
    CLRREG8(&g_pPIC1Regs->mask, 1 << 2);

    // Set static interrupt mappings for legacy devices
    
    OALIntrStaticTranslate(SYSINTR_FIRMWARE + 8, IRQ_PIC_1);    // keyboard
    OALIntrStaticTranslate(SYSINTR_FIRMWARE + 9, IRQ_PIC_12);   // mouse

    // We are done    
    OALMSG(OAL_INTR&&OAL_FUNC, (L"-BSPIntrInit(rc = 1)\r\n"));
    return TRUE;
}
Exemple #5
0
//------------------------------------------------------------------------------
//
//  Function:  OEMPowerOff
//
//  Called when the system is to transition to it's lowest power mode (off)
//
VOID
OEMPowerOff(
    )
{
    DWORD i;
    UINT32 sysIntr;
    UINT intr[3];
    BOOL bPowerOn;
    BOOL bPrevIntrState;
    UINT irq = 0;
    UINT32 mask = 0;
	
    // disable interrupts (note: this should not be needed)
    bPrevIntrState = INTERRUPTS_ENABLE(FALSE);

    // UNDONE: verify if this is still necessary
    // Disable hardware watchdog
    OALWatchdogEnable(FALSE);
    
    // Make sure that KITL is powered off
    bPowerOn = FALSE;
    KITLIoctl(IOCTL_KITL_POWER_CALL, &bPowerOn, sizeof(bPowerOn), NULL, 0, NULL);    

	
    //Save Perf Timer
    OALContextSavePerfTimer();
    // Disable GPTimer2 (used for high perf/monte carlo profiling)
    EnableDeviceClocks(BSPGetGPTPerfDevice(), FALSE);

    // Give chance to do board specific stuff
    BSPPowerOff();

    //----------------------------------------------
    // capture all enabled interrupts and disable interrupts
    intr[0] = INREG32(&g_pIntr->pICLRegs->INTC_MIR0);
    intr[1] = INREG32(&g_pIntr->pICLRegs->INTC_MIR1);
    intr[2] = INREG32(&g_pIntr->pICLRegs->INTC_MIR2);

    OUTREG32(&g_pIntr->pICLRegs->INTC_MIR_SET0, OMAP_MPUIC_MASKALL);
    OUTREG32(&g_pIntr->pICLRegs->INTC_MIR_SET1, OMAP_MPUIC_MASKALL);
    OUTREG32(&g_pIntr->pICLRegs->INTC_MIR_SET2, OMAP_MPUIC_MASKALL);

    //----------------------------------------------
    // Context Save/Restore       
	// Save state then mask all GPIO interrupts
	for (i=0; i<g_pIntr->nbGpioBank; i++)
    {
		INTR_GPIO_CTXT* pCurrGpioCtxt = &g_pIntr->pGpioCtxt[i];

		// Save current state
		pCurrGpioCtxt->restoreCtxt.IRQENABLE1 = INREG32(&pCurrGpioCtxt->pRegs->IRQENABLE1);
		pCurrGpioCtxt->restoreCtxt.WAKEUPENABLE = INREG32(&pCurrGpioCtxt->pRegs->WAKEUPENABLE);

		// Disable all GPIO interrupts in the bank
        OUTREG32(&pCurrGpioCtxt->pRegs->IRQENABLE1, 0);
        OUTREG32(&pCurrGpioCtxt->pRegs->WAKEUPENABLE, 0);

		OALIntrEnableIrqs(1,&pCurrGpioCtxt->bank_irq);

	}

    //----------------------------------------------
    // Clear all enabled IO PAD wakeups for GPIOs
    for (i = 0; i < g_pIntr->nbGpioBank; ++i) 
    {
		INTR_GPIO_CTXT* pCurrGpioCtxt = &g_pIntr->pGpioCtxt[i];

        irq = BSPGetGpioIrq(0) + (i * 32);
        mask = pCurrGpioCtxt->restoreCtxt.WAKEUPENABLE;
        while (mask != 0)
        {
            // If a GPIO was wakeup enabled, then clear the wakeup
            if (mask & 0x1)
            {
                OEMEnableIOPadWakeup((irq - BSPGetGpioIrq(0)), FALSE);
            }
            
            irq++;
            mask >>= 1;    
        }
    }

    //----------------------------------------------
    // Enable wake sources interrupts
    for (sysIntr = SYSINTR_DEVICES; sysIntr < SYSINTR_MAXIMUM; sysIntr++)
        {
        // Skip if sysIntr isn't allowed as wake source
        if (!OALPowerWakeSource(sysIntr)) 
		    continue;

        // Enable it as interrupt
        OEMInterruptEnable(sysIntr, NULL, 0);
        }

    // enter full retention
    PrcmSuspend();
    
    //----------------------------------------------
    // Find wakeup source
    for (sysIntr = SYSINTR_DEVICES; sysIntr < SYSINTR_MAXIMUM; sysIntr++)
        {            
        // Skip if sysIntr isn't allowed as wake source
        if (!OALPowerWakeSource(sysIntr)) 
		    continue;

        // When this sysIntr is pending we find wake source
        if (OEMInterruptPending(sysIntr))
            {
            g_oalWakeSource = sysIntr;
            break;
            }
        }
  
    //----------------------------------------------
    // Context Save/Restore
    // Put GPIO interrupt state back to the way it was before suspend
    for (i=0; i<g_pIntr->nbGpioBank; i++)
    {
		INTR_GPIO_CTXT* pCurrGpioCtxt = &g_pIntr->pGpioCtxt[i];		

        // Write registers with the previously saved values
        OUTREG32(&pCurrGpioCtxt->pRegs->IRQENABLE1, pCurrGpioCtxt->restoreCtxt.IRQENABLE1);
        OUTREG32(&pCurrGpioCtxt->pRegs->WAKEUPENABLE, pCurrGpioCtxt->restoreCtxt.WAKEUPENABLE);

    }

    //-------------------------------------------------------
    // Enable all previously enabled IO PAD wakeups for GPIOs
    for (i = 0; i < g_pIntr->nbGpioBank; ++i) 
    {
		INTR_GPIO_CTXT* pCurrGpioCtxt = &g_pIntr->pGpioCtxt[i];

        irq = BSPGetGpioIrq(0) + (i * 32);
        mask = pCurrGpioCtxt->restoreCtxt.WAKEUPENABLE;
        while (mask != 0)
        {
            // If a GPIO was wakeup enabled, then clear the wakeup
            if (mask & 0x1)
            {
                OEMEnableIOPadWakeup((irq - BSPGetGpioIrq(0)), TRUE);
            }
            
            irq++;
            mask >>= 1;    
        }
    }

    //----------------------------------------------
    // Re-enable interrupts    
    OUTREG32(&g_pIntr->pICLRegs->INTC_MIR_CLEAR0, ~intr[0]);
    OUTREG32(&g_pIntr->pICLRegs->INTC_MIR_CLEAR1, ~intr[1]);
    OUTREG32(&g_pIntr->pICLRegs->INTC_MIR_CLEAR2, ~intr[2]);  
    
    //----------------------------------------------
    // Do board specific stuff    
    BSPPowerOn();   
        
    //Sync to Hardware RTC after suspend\resume
    OALIoCtlHalRtcTime( 0,  NULL, 0, NULL, 0, NULL);    

    // Enable GPTimer (used for high perf/monte carlo profiling)
    EnableDeviceClocks(BSPGetGPTPerfDevice(), TRUE);	
    //Restore Perf Timer
    OALContextRestorePerfTimer();
		
    // Reinitialize KITL
    bPowerOn = TRUE;
    KITLIoctl(IOCTL_KITL_POWER_CALL, &bPowerOn, sizeof(bPowerOn), NULL, 0, NULL);    
    
    // Enable hardware watchdog
    OALWatchdogEnable(TRUE);
	
#ifndef SHIP_BUILD
    if (g_PrcmDebugSuspendResume)
	{
        OALMSG(1, (L"Enabled wake sources:\r\n"));
        for (sysIntr = SYSINTR_FIRMWARE; sysIntr < SYSINTR_MAXIMUM; sysIntr++)
        {
            if (OALPowerWakeSource(sysIntr)) 
                OALMSG(1, (L"  SYSINTR %d\r\n", sysIntr));
        }

    	OALMSG(1, (L"\r\nWake due to SYSINTR %d\r\n", g_oalWakeSource));
        OALWakeupLatency_DumpSnapshot();
        PrcmDumpSavedRefCounts();
        DumpPrcmRegsSnapshot();
    }
#endif

    // restore interrupts
    INTERRUPTS_ENABLE(bPrevIntrState);
}