Ejemplo n.º 1
0
static void kona_clock_delay(struct kona_timer *lkt, unsigned long clock_delay)
{
	u64 count;

	count = (u64)kona_timer_get_counter(lkt);

	/* Add 1 to guarantee minimum delay clock count */
	while ((u64)kona_timer_get_counter(lkt) - count < (u64)clock_delay + 1)
		;
}
static cycle_t notrace gptimer_clksrc_read(struct clocksource *cs)
{
	cycle_t count = 0;

	count = kona_timer_get_counter(gpt_src);
	return count;
}
Ejemplo n.º 3
0
static int kona_timer_set_next_event(unsigned long clc,
				  struct clock_event_device *unused)
{
	/*
	 * timer (0) is disabled by the timer interrupt already
	 * so, here we reload the next event value and re-enable
	 * the timer.
	 *
	 * This way, we are potentially losing the time between
	 * timer-interrupt->set_next_event. CPU local timers, when
	 * they come in should get rid of skew.
	 */

	uint32_t lsw, msw;
	uint32_t reg;

	kona_timer_get_counter(timers.tmr_regs, &msw, &lsw);

	/* Load the "next" event tick value */
	writel(lsw + clc, timers.tmr_regs + KONA_GPTIMER_STCM0_OFFSET);

	/* Enable compare */
	reg = readl(timers.tmr_regs + KONA_GPTIMER_STCS_OFFSET);
	reg |= (1 << KONA_GPTIMER_STCS_COMPARE_ENABLE_SHIFT);
	writel(reg, timers.tmr_regs + KONA_GPTIMER_STCS_OFFSET);

	return 0;
}
Ejemplo n.º 4
0
/* Note that this is called back from ISR context */
static int timer_callback(void *p)
{
	unsigned long flags;
	struct kona_timer *lkt = (struct kona_timer *)p;
	u64 exp_time;

	exp_time = (u64)kona_timer_get_counter(lkt);

	if (timer_m) {
		atomic_inc(&timer_exp_count);

		/* SMP safe handling, timer_m can be modified in irq isr.
		 * Consider to be no interrupt on unit test.
		 * Just count interrupt only.
		 */
		if (timer_m->busy)
			goto ret;

		spin_lock_irqsave(&timer_m->lock, flags);
		timer_m->end[timer_m->counter] = exp_time;

		if (lkt->cfg.mode == MODE_PERIODIC &&
		   timer_m->counter < TIMER_MEASURE_MAX - 1) {
			timer_m->counter++;

			timer_m->start[timer_m->counter] =
				timer_m->end[timer_m->counter-1];
		}
		spin_unlock_irqrestore(&timer_m->lock, flags);

		pr_debug("%s: curr: %lld\n", __func__, exp_time);
	} else {
		pr_info("%s: curr: %lld\n", __func__, exp_time);
	}
ret:
	return 0;
}
Ejemplo n.º 5
0
static int kona_timer_unit_test_run(const char *clk_name,
				     unsigned long clk_rate)
{
	struct kona_timer *lkt;
	int i;
	unsigned long flags;
	unsigned long req_cycle;

	pr_info("%s started!\n", __func__);

	lkt = kona_timer_request((char *)clk_name, -1);
	if (lkt == NULL) {
		pr_err("kona_timer_request returned error\n");
		return -EINVAL;
	}
	pr_info("%s ch_num: %d acquired!\n", clk_name, lkt->ch_num);

	timer_m = (struct timer_measure *)
			kmalloc(sizeof(struct timer_measure), GFP_KERNEL);

	if (!timer_m) {
		pr_err("%s memory allocation failed!\n", __func__);
		return -EINVAL;
	}

	spin_lock_init(&timer_m->lock);

#ifdef CONFIG_PREEMPT
	/* Ensure that cond_resched() won't try to preempt anybody */
	add_preempt_count(PREEMPT_ACTIVE);
#endif

	/*----------------------------------------------------------------------
	 * Test 1 : 1 clock cycle test
	 *  - set up 1 clock cycle timer request and measure the expiration
	 *    time.
	 */
	msleep(50);
	pr_info("=== Test case 1 ===\n");
	pr_info("1 clock tick one shot for 1 ms\n");

	req_cycle = 1;
	atomic_set(&timer_exp_count, 0);

	spin_lock_irqsave(&timer_m->lock, flags);
	memset(timer_m, 0, sizeof(struct timer_measure));
	timer_m->start[timer_m->counter] = (u64)kona_timer_get_counter(lkt);
	timer_m->req_cycle[timer_m->counter] = req_cycle;
	spin_unlock_irqrestore(&timer_m->lock, flags);

	kona_timer_unit_test_program(lkt, MODE_ONESHOT, req_cycle);

	mdelay(1);
	kona_timer_stop(lkt);

	/* Error check */
	print_unit_test_result(atomic_read(&timer_exp_count), 1, clk_rate);

	if (atomic_read(&timer_exp_count) != 1)
		goto error;

	/*----------------------------------------------------------------------
	 * Test 2 : peridic 1 clock timer test
	 *  - set up periodic 1 clock cycle timer request. SW will handle
	 *    periodic timer on every timer expiration. Wait for certain time
	 *    and check how many timers were expired and mesaure the time.
	 */
	msleep(50);
	pr_info("=== Test case 2 ===\n");
	pr_info("Periodic 1 clock tick for 1 ms\n");

	req_cycle = 1;
	atomic_set(&timer_exp_count, 0);

	spin_lock_irqsave(&timer_m->lock, flags);
	memset(timer_m, 0, sizeof(struct timer_measure));
	timer_m->start[timer_m->counter] = (u64)kona_timer_get_counter(lkt);

	for (i = 0; i < TIMER_MEASURE_MAX; i++)
		timer_m->req_cycle[i] = req_cycle;
	spin_unlock_irqrestore(&timer_m->lock, flags);

	kona_timer_unit_test_program(lkt, MODE_PERIODIC, req_cycle);

	/* mdelay() may be delayed by busy timer request. Should be short */
	mdelay(1);
	kona_timer_stop(lkt);
	pr_info("Total expiration count: %d\n", atomic_read(&timer_exp_count));
	print_unit_test_result(atomic_read(&timer_exp_count),
			       atomic_read(&timer_exp_count), clk_rate);

	/*----------------------------------------------------------------------
	* Test 3 : one-shot timer test with various time values
	*  - test various short clock cycles and check
	*    timer expiration and real run time of timer.
	*/
	msleep(50);
	pr_info("=== Test case 3 ===\n");
	pr_info("0~20 clock tick test for 1s, 50ms delay between each req\n");
	atomic_set(&timer_exp_count, 0);

	spin_lock_irqsave(&timer_m->lock, flags);
	memset(timer_m, 0, sizeof(struct timer_measure));
	spin_unlock_irqrestore(&timer_m->lock, flags);

	for (i = 0; i < 20; i++) {
		spin_lock_irqsave(&timer_m->lock, flags);
		timer_m->busy = 1;
		timer_m->counter = i;
		timer_m->start[i] =
			(u64)kona_timer_get_counter(lkt);
		timer_m->req_cycle[i] = i;
		kona_timer_unit_test_program(lkt, MODE_ONESHOT, i);
		timer_m->busy = 0;
		spin_unlock_irqrestore(&timer_m->lock, flags);

		mdelay(50);
		kona_timer_stop(lkt);
	}

	print_unit_test_result(atomic_read(&timer_exp_count), 20, clk_rate);

	if (atomic_read(&timer_exp_count) != 20)
		goto error;

	/*----------------------------------------------------------------------
	* Test 4 : one-shot timer test with various time values and delays.
	*  - test various short clock cycles with various short delays.
	*    Verify the timer expiration and timer run-time.
	*/
	msleep(50);
	pr_info("=== Test case 4 ===\n");
	pr_info("0~29 cycle timer test, 0~29 + 3 clock cycle wait\n");
	pr_info("   Ex)1 clock : wait for 4 clock cycle time\n");
	pr_info("   Ex)10 clock : wait for 13 clock cycle time\n");
	atomic_set(&timer_exp_count, 0);

	spin_lock_irqsave(&timer_m->lock, flags);
	memset(timer_m, 0, sizeof(struct timer_measure));
	spin_unlock_irqrestore(&timer_m->lock, flags);

	for (i = 0; i < 30; i++) {
		spin_lock_irqsave(&timer_m->lock, flags);
		timer_m->busy = 1;
		timer_m->counter = i;
		timer_m->start[i] =
			(u64)kona_timer_get_counter(lkt);
		timer_m->req_cycle[i] = i;
		kona_timer_unit_test_program(lkt, MODE_ONESHOT, i);
		timer_m->busy = 0;
		spin_unlock_irqrestore(&timer_m->lock, flags);

		kona_clock_delay(lkt, i + 3);
	}
	kona_timer_stop(lkt);
	pr_info("Total expiration count: %d\n", atomic_read(&timer_exp_count));
	print_unit_test_result(atomic_read(&timer_exp_count), 30, clk_rate);

	/*----------------------------------------------------------------------
	 * Test 5 : one-shot timer test with short-long time/delay.
	 *  - test various short/long clock cycles with various short/long
	 *    delays. Verify the timer expiration and timer run-time.
	 */
	msleep(50);
	pr_info("=== Test case 5 ===\n");
	pr_info("short and long timer test\n");
	pr_info("   short delay: 0~19 clock cycle wait\n");
	pr_info("   long  delay: 50 ms wait\n");
	atomic_set(&timer_exp_count, 0);

	spin_lock_irqsave(&timer_m->lock, flags);
	memset(timer_m, 0, sizeof(struct timer_measure));
	spin_unlock_irqrestore(&timer_m->lock, flags);

	for (i = 0; i < 20; i++) {
		/* Short timer request */
		spin_lock_irqsave(&timer_m->lock, flags);
		timer_m->busy = 1;
		timer_m->counter = 2 * i;
		timer_m->start[2 * i] =
			(u64)kona_timer_get_counter(lkt);
		timer_m->req_cycle[2 * i] = i;
		kona_timer_unit_test_program(lkt, MODE_ONESHOT, i);
		timer_m->busy = 0;
		spin_unlock_irqrestore(&timer_m->lock, flags);

		kona_clock_delay(lkt, i + 1);

		/* Long timer request */
		req_cycle = clk_rate / 50; /* 20ms */
		spin_lock_irqsave(&timer_m->lock, flags);
		timer_m->busy = 1;
		timer_m->counter = 2 * i + 1;
		timer_m->start[2 * i + 1] =
			(u64)kona_timer_get_counter(lkt);
		timer_m->req_cycle[2 * i + 1] = req_cycle;
		kona_timer_unit_test_program(lkt, MODE_ONESHOT, req_cycle);
		timer_m->busy = 0;
		spin_unlock_irqrestore(&timer_m->lock, flags);

		mdelay(1000/50 * 2); /* 40 ms */
	}
	kona_timer_stop(lkt);
	pr_info("Total expiration count: %d\n", atomic_read(&timer_exp_count));
	print_unit_test_result(atomic_read(&timer_exp_count), 20 * 2, clk_rate);

	/*----------------------------------------------------------------------
	 * Test 6 : periodic 1s timer test
	 *          wait for 10.5 sec with 1s periodic timer request
	 */
	msleep(50);
	pr_info("=== Test case 6 ===\n");
	pr_info("Periodic 1s timer test for 10.5s\n");

	req_cycle = clk_rate;
	atomic_set(&timer_exp_count, 0);

	spin_lock_irqsave(&timer_m->lock, flags);
	memset(timer_m, 0, sizeof(struct timer_measure));
	timer_m->start[timer_m->counter] = (u64)kona_timer_get_counter(lkt);

	for (i = 0; i < TIMER_MEASURE_MAX; i++)
		timer_m->req_cycle[i] = req_cycle;
	spin_unlock_irqrestore(&timer_m->lock, flags);

	kona_timer_unit_test_program(lkt, MODE_PERIODIC, clk_rate);

	msleep(10500);
	kona_timer_stop(lkt);

	print_unit_test_result(atomic_read(&timer_exp_count),
			       atomic_read(&timer_exp_count), clk_rate);

	if (atomic_read(&timer_exp_count) != 10)
		goto error;
	msleep(50);

	/*
	 * End of kona timer unit test
	 */

	kona_timer_free(lkt);

	pr_info("%s Passed!\n", __func__);

#ifdef CONFIG_PREEMPT
	sub_preempt_count(PREEMPT_ACTIVE);
#endif
	kfree(timer_m);
	timer_m = NULL;

	return 0;

error:
	kona_timer_stop(lkt);
	kona_timer_free(lkt);

	pr_err("%s Failed\n", __func__);

#ifdef CONFIG_PREEMPT
	sub_preempt_count(PREEMPT_ACTIVE);
#endif
	kfree(timer_m);
	timer_m = NULL;

	return -EINVAL;
}