コード例 #1
0
ファイル: timer.c プロジェクト: zizilala/projects_etest
//------------------------------------------------------------------------------
//
//  Function:  UpdatePeriod
//
VOID
UpdatePeriod(
    UINT32 periodMSec
    )
{
    UINT32 period, match;
    INT32 delta;
    UINT64 offsetMSec = periodMSec;
    UINT64 tickCount = OALGetTickCount();
    INT nDelay;

    // Calculate count difference
    period = (UINT32)MSEC_TO_TICK(offsetMSec);

    nDelay = min(period, DELTA_TIME);
    // This is compare value
    match = ((UINT32)MSEC_TO_TICK(tickCount)) + nDelay;

    delta = (INT32)(OALTimerGetCount()+ g_oalTimerContext.margin - match);

    // If we are behind, issue interrupt as soon as possible
    if (delta > 0)
    {
        match += MSEC_TO_TICK(1);
    }

    // Save off match value
    g_oalTimerContext.match = match;

    // Set timer match value
    OALTimerSetCompare(match);
}
コード例 #2
0
ファイル: timer.c プロジェクト: zizilala/projects_etest
//------------------------------------------------------------------------------
//
//  Function: OEMGetTickCount
//
//  This returns the number of milliseconds that have elapsed since Windows
//  CE was started. If the system timer period is 1ms the function simply
//  returns the value of CurMSec. If the system timer period is greater then
//  1 ms, the HiRes offset is added to the value of CurMSec.
//
UINT32
OEMGetTickCount(
    )
{
    UINT64 baseCounts;
    UINT32 offset;

    // This code adjusts the accuracy of the returned value to the nearest
    // MSec when the system tick exceeds 1 ms. The following code checks if
    // a system timer interrupt occurred between reading the CurMSec value
    // and the call to fetch the HiResTicksSinceSysTick. If so, the value of
    // CurMSec and Offset is re-read, with the certainty that a system timer
    // interrupt will not occur again.
    do
        {
        baseCounts = g_oalTimerContext.curCounts;
        offset = OALTimerGetCount() - g_oalTimerContext.base;
        }
    while (baseCounts != g_oalTimerContext.curCounts);


   //  Update CurMSec (kernel uses both CurMSec and GetTickCount() at different places) and return msec tick count
    CurMSec = (UINT32)TICK_TO_MSEC(baseCounts + offset);

    return CurMSec;

}
コード例 #3
0
//------------------------------------------------------------------------------
//
//  Function:  OALTimerReduceSysTick
//
UINT32 OALTimerReduceSysTick(UINT32 count, UINT32 margin)
{
    UINT32 rc, edge, compare;

    edge = OALTimerGetCount();
    compare = OALTimerGetCompare();

    // Update the countdown value
    OALTimerSetCompare(count);

    if (edge > margin) 
    {
        // We are far enough from the interrupt that we should return the
        // number of ticks that would have occurred since the last tick based
        // on the new number of counts per tick. We will avoid the interrupt and
        // just start fresh.
        rc = (compare - edge) / count;
        OALTimerSetCount(count); 
    } 
    else {
        // We are close enough to the next interrupt that we will let the
        // interrupt occur. We will also return the number of counts that would
        // have happened since the last tick based on the new number of counts
        // per tick, but we will subtract one because another is just about to
        // happen.
        rc = (compare / count) - 1;
    }

    return rc;
}
コード例 #4
0
//------------------------------------------------------------------------------
//
//  Function:  OALTimerExtendSysTick
//
VOID OALTimerExtendSysTick(UINT32 count, UINT32 margin, UINT32 offset)
{
    UINT32 compare, edge;

    edge = OALTimerGetCount();
    compare = OALTimerGetCompare();

    if (edge > ((count - compare) + margin + offset))
    {
        // We are far enough away from the interrupt that we should just
        // increase the time it will take to hit the next interrupt taking into
        // account the offset provided.
        OALTimerSetCount(edge - (count - offset - compare)); 
    }
    OALTimerSetCompare(count);
}
コード例 #5
0
ファイル: cntcmp.c プロジェクト: zizilala/projects_etest
//------------------------------------------------------------------------------
//
//  Function: OALTimerUpdate
//
//  This function is called to change length of actual system timer period.
//  When end of new period is closer to actual time than margin period end
//  is shifted by margin (but next period should fix this shift - this is
//  reason why OALTimerRecharge doesn't read back compare register and it
//  uses saved value instead).
//
UINT32 OALTimerUpdate(UINT32 period, UINT32 margin)
{
    UINT32 edge;

    // New compare value is base plus period
    g_timer.compare = g_timer.base + period;
    // Are we more than margin before new compare?
    edge = OALTimerGetCount() + margin;
    if ((INT32)(g_timer.compare - edge) > 0) {
       // Yes, then use calculated value
       OALTimerSetCompare(g_timer.compare);
    } else {
       // No, shift real compare value
       OALTimerSetCompare(edge);
    }            
    return 0;
}
コード例 #6
0
ファイル: cntcmp.c プロジェクト: zizilala/projects_etest
//------------------------------------------------------------------------------
//
//  Function:  OALTimerRecharge
//
//  This function recharge count/compare timer. In case that we are late more
//  than margin value we will use count as new counter base. Under
//  normal conditions previous compare value stored in global variable is used.
//  Using global variable instead reading compare register allows compensate
//  offset when we reduce system tick to value which can cause hazard.
//
VOID OALTimerRecharge(UINT32 period, UINT32 margin)
{
    UINT32 count;

    count = OALTimerGetCount();
    // Check if recharge was called in required margin
    if ((INT32)(count - OALTimerGetCompare() - margin) < 0) {
        // Yes, base new period on previous (no shift)
        g_timer.base = g_timer.compare;
        g_timer.compare += period;
    } else {
        // No, base new period on actual counter value (shift)
        g_timer.base = count;
        g_timer.compare = g_timer.base + period;
    }
    OALTimerSetCompare(g_timer.compare); 
}
コード例 #7
0
ファイル: timer.c プロジェクト: zizilala/projects_etest
//------------------------------------------------------------------------------
//
//  Function:  OALTimerUpdateRescheduleTime
//
//  This function is called by kernel to set next reschedule time.
//
VOID
OALTimerUpdateRescheduleTime(
    DWORD timeMSec
    )
{
    UINT32 baseMSec, periodMSec;
    INT32 delta;

    // Get current system timer counter
    baseMSec = CurMSec;

    // How far we are from next tick
    delta = (INT32)(g_oalTimerContext.match - OALTimerGetCount());

    if( delta < 0 )
    {
        UpdatePeriod(0);
        goto cleanUp;
    }

    // If timer interrupts occurs, or we are within 1 ms of the scheduled
    // interrupt, just return - timer ISR will take care of it.
    if ((baseMSec != CurMSec) || (delta < MSEC_TO_TICK(1))) goto cleanUp;

    // Calculate the distance between the new time and the last timer interrupt
      periodMSec = timeMSec - OEMGetTickCount();


    // Trying to set reschedule time prior or equal to CurMSec - this could
    // happen if a thread is on its way to sleep while preempted before
    // getting into the Sleep Queue
    if ((INT32)periodMSec < 0)
        {
        periodMSec = 0;
        }
    else if (periodMSec > g_oalTimerContext.maxPeriodMSec)
        {
        periodMSec = g_oalTimerContext.maxPeriodMSec;
        }

    // Now we find new period, so update timer
    UpdatePeriod(periodMSec);

cleanUp:
    return;
}
コード例 #8
0
ファイル: cntcmp.c プロジェクト: zizilala/projects_etest
//------------------------------------------------------------------------------
//
//  Function:  OALTimerCountsSinceSysTick
//
INT32 OALTimerCountsSinceSysTick()
{
    return OALTimerGetCount() - g_timer.base;
}
コード例 #9
0
ファイル: cntcmp.c プロジェクト: zizilala/projects_etest
//------------------------------------------------------------------------------
//
//  Function:  OALTimerInitCount
//
//  This function initialize count/compare timer.
//
VOID OALTimerInitCount(UINT32 period)
{
    g_timer.base = OALTimerGetCount();
    g_timer.compare = g_timer.base + period;
    OALTimerSetCompare(g_timer.compare); 
}
コード例 #10
0
/**
 * PrcmVoltScaleVoltageABB - controls ABB ldo during voltage scaling
 * @target_volt: target voltage determines if ABB ldo is active or bypassed
 *
 * Adaptive Body-Bias is a technique in all OMAP silicon that uses the 45nm
 * process.  ABB can boost voltage in high OPPs for silicon with weak
 * characteristics (forward Body-Bias) as well as lower voltage in low OPPs
 * for silicon with strong characteristics (Reverse Body-Bias).
 *
 * Only Foward Body-Bias for operating at high OPPs is implemented below, per
 * recommendations from silicon team.
 * Reverse Body-Bias for saving power in active cases and sleep cases is not
 * yet implemented.
 */
int PrcmVoltScaleVoltageABB(UINT32 target_opp_no)
{
	UINT32 sr2en_enabled;
	UINT32 timeout;
	int sr2_wtcnt_value;
    UINT32 regVal =0;
    UINT32 tcrr;

	/* calculate SR2_WTCNT_VALUE settling time */
	sr2_wtcnt_value = (ABB_MAX_SETTLING_TIME * (PrcmClockGetClockRate(SYS_CLK)) / 8);

	/* has SR2EN been enabled previously? */
	sr2en_enabled = INREG32(&g_pPrcmPrm->pOMAP_GLOBAL_PRM->PRM_LDO_ABB_CTRL) & SMPS_SR2EN;

    // enable voltage processor
    PrcmVoltEnableVp(kVDD1, TRUE);

	/* select fast, nominal or slow OPP for ABB ldo */
	if (target_opp_no >= ABB_FAST_OPP_VAL) {
        
		/* program for fast opp - enable FBB */
        regVal = INREG32(&g_pPrcmPrm->pOMAP_GLOBAL_PRM->PRM_LDO_ABB_SETUP);
        regVal = (regVal & ~(SMPS_OPP_SEL_MASK)) | (ABB_FAST_OPP << SMPS_OPP_SEL_SHIFT);
        OUTREG32(&g_pPrcmPrm->pOMAP_GLOBAL_PRM->PRM_LDO_ABB_SETUP,regVal);
        
		/* enable the ABB ldo if not done already */
		if (!sr2en_enabled)
			SETREG32(&g_pPrcmPrm->pOMAP_GLOBAL_PRM->PRM_LDO_ABB_CTRL,SMPS_SR2EN);
        
	} else if (sr2en_enabled) {
	
		/* program for nominal opp - bypass ABB ldo */        
        regVal = INREG32(&g_pPrcmPrm->pOMAP_GLOBAL_PRM->PRM_LDO_ABB_SETUP);
        regVal = (regVal & ~(SMPS_OPP_SEL_MASK)) | (ABB_NOMINAL_OPP << SMPS_OPP_SEL_SHIFT);
        OUTREG32(&g_pPrcmPrm->pOMAP_GLOBAL_PRM->PRM_LDO_ABB_SETUP,regVal);
        
	} else {
	
		/* nothing to do here yet... might enable RBB here someday */
		goto cleanUp;
        
	}

	/* set ACTIVE_FBB_SEL for all 45nm silicon */
    SETREG32(&g_pPrcmPrm->pOMAP_GLOBAL_PRM->PRM_LDO_ABB_CTRL,SMPS_ACTIVE_FBB_SEL);

	/* program settling time of 30us for ABB ldo transition */
    regVal = INREG32(&g_pPrcmPrm->pOMAP_GLOBAL_PRM->PRM_LDO_ABB_CTRL);
    regVal = (regVal & ~(SMPS_SR2_WTCNT_VALUE_MASK)) | (sr2_wtcnt_value << SMPS_SR2_WTCNT_VALUE_SHIFT);
    OUTREG32(&g_pPrcmPrm->pOMAP_GLOBAL_PRM->PRM_LDO_ABB_CTRL,regVal);
    
	/* clear ABB ldo interrupt status */    
    OUTREG32(&g_pPrcmPrm->pOMAP_OCP_SYSTEM_PRM->PRM_IRQSTATUS_MPU, PRM_IRQENABLE_ABB_LDO_TRANXDONE_ST);
    	
	/* enable ABB LDO OPP change */
    SETREG32(&g_pPrcmPrm->pOMAP_GLOBAL_PRM->PRM_LDO_ABB_SETUP,SMPS_OPP_CHANGE);

	
	/* wait until OPP change completes */
    timeout=tcrr=OALTimerGetCount();
    while (((INREG32(&g_pPrcmPrm->pOMAP_OCP_SYSTEM_PRM->PRM_IRQSTATUS_MPU) & 
			    PRM_IRQENABLE_ABB_LDO_TRANXDONE_ST) == 0) &&
        ((timeout - tcrr) < ABB_MAX_SETTLING_TIME_IN_TICKS))
    {
        timeout=OALTimerGetCount();        
    }

	if (timeout >= tcrr+ABB_MAX_SETTLING_TIME_IN_TICKS)
		RETAILMSG(0,(L"ABB: TRANXDONE timed out waiting for OPP change\r\n"));
    
    timeout=tcrr=OALTimerGetCount();
	
	/* Clear all pending TRANXDONE interrupts/status */
	while ((timeout - tcrr) < ABB_MAX_SETTLING_TIME_IN_TICKS) {
		OUTREG32(&g_pPrcmPrm->pOMAP_OCP_SYSTEM_PRM->PRM_IRQSTATUS_MPU, PRM_IRQENABLE_ABB_LDO_TRANXDONE_ST);
		if (!(INREG32(&g_pPrcmPrm->pOMAP_OCP_SYSTEM_PRM->PRM_IRQSTATUS_MPU) & 
			    PRM_IRQENABLE_ABB_LDO_TRANXDONE_ST))
			break;

		timeout=OALTimerGetCount();  
	}
	if (timeout >= tcrr+ABB_MAX_SETTLING_TIME_IN_TICKS)
		RETAILMSG(0,(L"ABB: TRANXDONE timed out trying to clear status\n"));

cleanUp:
    // disable the voltage processor sub-chip
    PrcmVoltEnableVp(kVDD1, FALSE);
	return 0;
}
コード例 #11
0
ファイル: timer.c プロジェクト: zizilala/projects_etest
//------------------------------------------------------------------------------
//
//  Function: OALTimerIntrHandler
//
//  This function implement timer interrupt handler. It is called from common
//  ARM interrupt handler.
//
UINT32 OALTimerIntrHandler()
{
    UINT32 count;
    INT32 period, delta;
    UINT32 sysIntr = SYSINTR_NOP;



    // allow bsp to process timer interrupt first
    sysIntr = OALTickTimerIntr();
    if (sysIntr != SYSINTR_NOP) return sysIntr;

    // Clear interrupt
    OALTimerSetReg(&g_pTimerRegs->TISR, GPTIMER_TIER_MATCH);

    // How far from interrupt we are?
    count = OALTimerGetCount();
    delta = count - g_oalTimerContext.match;
    

    // If delta is negative, timer fired for some reason
    // To be safe, reprogram the timer for minimum delta
    if (delta < 0)
    {
        delta = 0;
        goto cleanUp;
    }

#ifdef OAL_ILTIMING
    if (g_oalILT.active)
    {
        g_oalILT.isrTime1 = delta;
    }        
#endif

    // Find how long period was
    period = count - g_oalTimerContext.base;
    g_oalTimerContext.curCounts += period;    
    g_oalTimerContext.base += period;

    // Calculate actual CurMSec
    CurMSec = (UINT32) TICK_TO_MSEC(g_oalTimerContext.curCounts);

    OALLED(LED_IDX_TIMER, CurMSec >> 10);

    // Reschedule?
    delta = dwReschedTime - CurMSec;
    if (delta <= 0)
        {
        sysIntr = SYSINTR_RESCHED;
        delta = g_oalTimerContext.maxPeriodMSec;
        }

cleanUp:
    // Set new period
    UpdatePeriod(delta);

#ifdef OAL_ILTIMING
    if (g_oalILT.active) {
        if (--g_oalILT.counter == 0) {
            sysIntr = SYSINTR_TIMING;
            g_oalILT.counter = g_oalILT.counterSet;
            g_oalILT.isrTime2 = 0;
        }
    }
#endif

    return sysIntr;
}
コード例 #12
0
//------------------------------------------------------------------------------
//
//  Function:  OALTimerCountsSinceSysTick
//
INT32 OALTimerCountsSinceSysTick()
{
    return OALTimerGetCompare() - OALTimerGetCount();
}