示例#1
0
static void
kw_clkevt_mode(enum clock_event_mode mode, struct clock_event_device *dev)
{
	unsigned long flags;

	local_irq_save(flags);

	if (mode == CLOCK_EVT_MODE_PERIODIC) {
		/*
		 * Setup latch cycles in timer and enable reload interrupt.
		 */
		MV_REG_WRITE(CNTMR_RELOAD_REG(CLOCKEVENT), ((mvBoardTclkGet() + HZ/2) / HZ));
		MV_REG_WRITE(CNTMR_VAL_REG(CLOCKEVENT), ((mvBoardTclkGet() + HZ/2) / HZ));
		MV_REG_BIT_SET(BRIDGE_INT_MASK_REG, BRIDGE_INT_TIMER(CLOCKEVENT));
		MV_REG_BIT_SET(CNTMR_CTRL_REG, TIMER_RELOAD_EN(CLOCKEVENT) |
					  TIMER_EN(CLOCKEVENT));
	} else {
		/*
		 * Disable timer and interrupt
		 */
		MV_REG_BIT_RESET(BRIDGE_INT_MASK_REG, BRIDGE_INT_TIMER(CLOCKEVENT));
		MV_REG_WRITE(BRIDGE_INT_CAUSE_REG, ~BRIDGE_INT_TIMER(CLOCKEVENT));
		MV_REG_BIT_RESET(CNTMR_CTRL_REG, TIMER_RELOAD_EN(CLOCKEVENT) |
					  TIMER_EN(CLOCKEVENT));
	}

	local_irq_restore(flags);
}
示例#2
0
int mv_enable_fc_events(void *fc_event_handler, unsigned long period_ns)
{
	unsigned long flags;
	uint64_t  clock_ticks = period_ns;

	if (fc_event_handler == 0)
		return -1;

	local_irq_save(flags);

	mv_fc_event_handler = fc_event_handler;

	clock_ticks *= kw_clkevt.mult;
	clock_ticks >>= kw_clkevt.shift;

	/* Setup timer value */
	MV_REG_WRITE(CNTMR_RELOAD_REG(FCTRLEVENT), (unsigned long)clock_ticks);
	MV_REG_WRITE(CNTMR_VAL_REG(FCTRLEVENT), (unsigned long)clock_ticks);

	/* Enable periodic timer and timer interrupt */
	MV_REG_BIT_SET(BRIDGE_INT_MASK_REG, BRIDGE_INT_TIMER(FCTRLEVENT));
	MV_REG_BIT_SET(CNTMR_CTRL_REG, TIMER_RELOAD_EN(FCTRLEVENT) | TIMER_EN(FCTRLEVENT));

	fc_disabled = 0;

	local_irq_restore(flags);

	return 0;
}
示例#3
0
static int
kw_clkevt_next_event(unsigned long delta, struct clock_event_device *dev)
{
	unsigned long flags;

	if (delta == 0)
		return -ETIME;

	local_irq_save(flags);

	/*
	 * Clear and enable timer interrupt bit
	 */
	MV_REG_WRITE(BRIDGE_INT_CAUSE_REG, ~BRIDGE_INT_TIMER(CLOCKEVENT));
	MV_REG_BIT_SET(BRIDGE_INT_MASK_REG, BRIDGE_INT_TIMER(CLOCKEVENT));

	/*
	 * Setup new timer value
	 */
	MV_REG_WRITE(CNTMR_VAL_REG(CLOCKEVENT), delta);

	/*
	 * Disable auto reload and kickoff the timer
	 */
	MV_REG_BIT_RESET(CNTMR_CTRL_REG, TIMER_RELOAD_EN(CLOCKEVENT));
	MV_REG_BIT_SET(CNTMR_CTRL_REG, TIMER_EN(CLOCKEVENT));

	local_irq_restore(flags);

	return 0;
}
示例#4
0
void __udelay(unsigned long usec)
{
	uint current;
	ulong delayticks;

	current = readl(CNTMR_VAL_REG(UBOOT_CNTR));
	delayticks = (usec * (CONFIG_SYS_TCLK / 1000000));

	if (current < delayticks) {
		delayticks -= current;
		while (readl(CNTMR_VAL_REG(UBOOT_CNTR)) < current) ;
		while ((TIMER_LOAD_VAL - delayticks) <
			readl(CNTMR_VAL_REG(UBOOT_CNTR))) ;
	} else {
		while (readl(CNTMR_VAL_REG(UBOOT_CNTR)) >
			(current - delayticks)) ;
	}
}
/*******************************************************************************
* mvCntmrLoad -
*
* DESCRIPTION:
*       Load an init Value to a given counter/timer
*
* INPUT:
*       countNum - counter number
*       value - value to be loaded
*
* OUTPUT:
*       None.
*
* RETURN:
*       MV_BAD_PARAM on bad parameters , MV_ERROR on error ,MV_OK on sucess
*******************************************************************************/
MV_STATUS mvCntmrLoad(MV_U32 countNum, MV_U32 value)
{
	if (countNum >= MV_CNTMR_MAX_COUNTER) {

		mvOsPrintf(("mvCntmrLoad: Err. illegal counter number \n"));
		return MV_BAD_PARAM;;

	}

	MV_REG_WRITE(CNTMR_RELOAD_REG(countNum), value);
	MV_REG_WRITE(CNTMR_VAL_REG(countNum), value);

	return MV_OK;
}
示例#6
0
/*
 * init the counter
 */
int timer_init(void)
{
	unsigned int cntmrctrl;

	/* load value into timer */
	writel(TIMER_LOAD_VAL, CNTMR_RELOAD_REG(UBOOT_CNTR));
	writel(TIMER_LOAD_VAL, CNTMR_VAL_REG(UBOOT_CNTR));

	/* enable timer in auto reload mode */
	cntmrctrl = readl(CNTMR_CTRL_REG);
	cntmrctrl |= CTCR_ARM_TIMER_EN(UBOOT_CNTR);
	cntmrctrl |= CTCR_ARM_TIMER_AUTO_EN(UBOOT_CNTR);
	writel(cntmrctrl, CNTMR_CTRL_REG);
	return 0;
}
示例#7
0
static void mv_init_timer(void)
{
	/*
	 * Setup clocksource free running timer (no interrupt on reload)
	 */
 	MV_REG_WRITE(CNTMR_VAL_REG(CLOCKSOURCE), 0xffffffff);
	MV_REG_WRITE(CNTMR_RELOAD_REG(CLOCKSOURCE), 0xffffffff);
	MV_REG_BIT_RESET(BRIDGE_INT_MASK_REG, BRIDGE_INT_TIMER(CLOCKSOURCE));
	MV_REG_BIT_SET(CNTMR_CTRL_REG, TIMER_RELOAD_EN(CLOCKSOURCE) |
				  TIMER_EN(CLOCKSOURCE));

	kw_clkevt.cpumask = cpumask_of(0);

	/*
	 * Register clocksource
	 */
	kw_clksrc.mult =
		clocksource_hz2mult(mvBoardTclkGet(), kw_clksrc.shift);

	clocksource_register(&kw_clksrc);

	/*
	 * Connect and enable tick handler
	 */
	setup_irq(IRQ_BRIDGE, &kw_timer_irq);

	/*
	 * Register clockevent
	 */
	kw_clkevt.mult =
		div_sc(mvBoardTclkGet(), NSEC_PER_SEC, kw_clkevt.shift);
	kw_clkevt.max_delta_ns =
		clockevent_delta2ns(0xfffffffe, &kw_clkevt);
	kw_clkevt.min_delta_ns =
		clockevent_delta2ns(1, &kw_clkevt);

	/*
	 * Setup clockevent timer (interrupt-driven.)
	 */
	clockevents_register_device(&kw_clkevt);
}
/*******************************************************************************
* mvCntmrWrite -
*
* DESCRIPTION:
*  	Returns the value of the given Counter/Timer
*
* INPUT:
*       countNum - counter number
*		countVal - value to write
*
* OUTPUT:
*       None.
*
* RETURN:
*       None
*******************************************************************************/
void mvCntmrWrite(MV_U32 countNum, MV_U32 countVal)
{
	MV_REG_WRITE(CNTMR_VAL_REG(countNum), countVal);
}
/*******************************************************************************
* mvCntmrReadDiff -
*
* DESCRIPTION:
*  	Returns the number of counts of the given Counter/Timer
*
* INPUT:
*       countNum - counter number
*
* OUTPUT:
*       None.
*
* RETURN:
*       MV_U32 the number of counts of the given Counter/Timer
*******************************************************************************/
MV_U32 mvCntmrReadDiff(MV_U32 countNum)
{
	/* counter counts down */
	return TVR_ARM_TIMER_MAX - MV_REG_READ(CNTMR_VAL_REG(countNum));
}
示例#10
0
/*******************************************************************************
* mvCntmrRead -
*
* DESCRIPTION:
*  	Returns the value of the given Counter/Timer
*
* INPUT:
*       countNum - counter number
*
* OUTPUT:
*       None.
*
* RETURN:
*       MV_U32 counter value
*******************************************************************************/
MV_U32 mvCntmrRead(MV_U32 countNum)
{
	return MV_REG_READ(CNTMR_VAL_REG(countNum));
}
示例#11
0
static cycle_t kw_clksrc_read(struct clocksource *cs)
{
	return (0xffffffff - MV_REG_READ(CNTMR_VAL_REG(CLOCKSOURCE)));
}
示例#12
0
static inline ulong read_timer(void)
{
	return readl(CNTMR_VAL_REG(UBOOT_CNTR))
	      / (CONFIG_SYS_TCLK / 1000);
}
示例#13
0
static inline ulong uboot_cntr_val(void)
{
	return readl(CNTMR_VAL_REG(UBOOT_CNTR));
}
示例#14
0
static cycle_t orion_clksrc_read(void)
{
	return (0xffffffff - MV_REG_READ(CNTMR_VAL_REG(CLOCKSOURCE)));
}