예제 #1
0
/*
 *  XXX:may be call at interrupt.
 * 20091116,HSL@RK,bug:if TIMER_CLKSRC down to 0 and set to max, and irq was disabled
 * 
 */
cycle_t rockchip_timer_read(void)
{
#if CHIP_RK281X
        unsigned int t = RK_TIMER_READVALUE(TIMER_CLKSRC);
        return ~t;
#else
        unsigned int t = RK_TIMER_READVALUE(TIMER_CLKSRC);
        unsigned int c = RK_TIMER_GETCOUNT(TIMER_CLKSRC);
        static unsigned int last_cycle; // for debug cycle reverse.
        t = (c-t);
        last_cycle = t;
        return t/rockchip_apb_clk;
#endif                
}
예제 #2
0
static int rk29_timer_set_next_event(unsigned long cycles, struct clock_event_device *evt)
{
    do {
        RK_TIMER_DISABLE(TIMER_CLKEVT);
        RK_TIMER_SETCOUNT(TIMER_CLKEVT, cycles);
        RK_TIMER_ENABLE(TIMER_CLKEVT);
    } while (RK_TIMER_READVALUE(TIMER_CLKEVT) > cycles);
    return 0;
}
예제 #3
0
static inline u32 rk30_timer_read_current_value(u32 n)
{
	unsigned long flags;
	u32 v[3];
	int loop = 100;

	do {
		local_irq_save(flags);
		v[0] = RK_TIMER_READVALUE(n);
		v[1] = RK_TIMER_READVALUE(n);
		v[2] = RK_TIMER_READVALUE(n);
		local_irq_restore(flags);
		if ((v[0] >= v[1]) && ((v[0] - v[1]) < 24)
		 && (v[1] >= v[2]) && ((v[1] - v[2]) < 24))
			break;
	} while (loop--);

	return v[1];
}
예제 #4
0
void rockchip_timer_freeze(int freeze )
{
        unsigned long flags;
        local_irq_save( flags );
        if( freeze ) {
                clock_event_freeze_count = RK_TIMER_READVALUE(TIMER_CLKSRC);
                 RK_TIMER_DISABLE(TIMER_CLKSRC);
                 RK_TIMER_DISABLE(TIMER_CLKEVT);
        } else {
                RK_TIMER_SETCOUNT(TIMER_CLKSRC,clock_event_freeze_count);
                RK_TIMER_ENABLE(TIMER_CLKSRC);
                RK_TIMER_ENABLE(TIMER_CLKEVT);
        }
        clock_source_freezed = freeze;
        local_irq_restore(flags);
}
예제 #5
0
static void rk29_timer_set_mode(enum clock_event_mode mode, struct clock_event_device *evt)
{
    switch (mode) {
    case CLOCK_EVT_MODE_PERIODIC:
        do {
            RK_TIMER_DISABLE(TIMER_CLKEVT);
            RK_TIMER_SETCOUNT(TIMER_CLKEVT, 24000000/HZ - 1);
            RK_TIMER_ENABLE(TIMER_CLKEVT);
        } while (RK_TIMER_READVALUE(TIMER_CLKEVT) > (24000000/HZ - 1));
        break;
    case CLOCK_EVT_MODE_RESUME:
    case CLOCK_EVT_MODE_ONESHOT:
        break;
    case CLOCK_EVT_MODE_UNUSED:
    case CLOCK_EVT_MODE_SHUTDOWN:
        RK_TIMER_DISABLE(TIMER_CLKEVT);
        break;
    }
}
예제 #6
0
/*
 * 20091120,HSL@RK,disable irq for enable timer and set count . 
 *
 */
void rockchip_timer_clocksource_suspend_resume(int suspend )
{
	unsigned long flags;
	local_irq_save( flags );
	
	RK_TIMER_DISABLE(TIMER_CLKEVT);
#if 0
	if( suspend ) {
		RK_TIMER_SETCOUNT(TIMER_CLKEVT,RK_CHECK_VBUS_COUNT*rockchip_apb_clk); 
		RK_TIMER_ENABLE(TIMER_CLKEVT);
	} else {
		int cyl = RK_TIMER_GETCOUNT(TIMER_CLKEVT) -
		RK_TIMER_READVALUE(TIMER_CLKEVT);
		rktimer_update_suspend_ms( CHECK_VBUS_MS*cyl / RK_TIMER_GETCOUNT(TIMER_CLKEVT) );
	}
	S_INFO("r/s timer,load cnt=0x%x,clk_source_suspend=%ld\n" , 
	RK_TIMER_GETCOUNT(TIMER_CLKEVT), clk_source_suspend_second);
#endif
	local_irq_restore(flags);
}