rv1126-uboot/test/rockchip/test-timer.c

142 lines
3.5 KiB
C

/*
* (C) Copyright 2017 Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <asm/io.h>
#include <common.h>
#include <irq-generic.h>
#include <irq-platform.h>
#include "test-rockchip.h"
#define TIMER_LOAD_COUNT0 0x00
#define TIMER_LOAD_COUNT1 0x04
#define TIMER_CTRL 0x10
#define TIMER_INTSTATUS 0x18
#define SYS_COUNTER_FREQ0 24000000
#define SYS_COUNTER_FREQ1 0
#define TIMER_EN BIT(0)
#define TIMER_INT_EN BIT(2)
#define TIMER_CLR_INT BIT(0)
#if defined(CONFIG_ROCKCHIP_RK3128)
#define TIMER_BASE (0x20044000 + 0x20) /* TIMER 1 */
#define TIMER_IRQ IRQ_TIMER1
#elif defined(CONFIG_ROCKCHIP_RK322X)
#define TIMER_BASE (0x110C0000 + 0x20) /* TIMER 1 */
#define TIMER_IRQ IRQ_TIMER1
#elif defined(CONFIG_ROCKCHIP_RK3288)
#define TIMER_BASE (0xFF6B0000 + 0x20) /* TIMER 1 */
#define TIMER_IRQ IRQ_TIMER1
#elif defined(CONFIG_ROCKCHIP_RK3328)
#define TIMER_BASE (0xFF1C0000 + 0x20) /* TIMER 1 */
#define TIMER_IRQ IRQ_TIMER1
#elif defined(CONFIG_ROCKCHIP_RK3368)
#define TIMER_BASE (0xFF810000 + 0x20) /* TIMER 1 */
#define TIMER_IRQ IRQ_TIMER1
#elif defined(CONFIG_ROCKCHIP_RK3399)
#define TIMER_BASE (0xFF850000 + 0x20) /* TIMER 1 */
#define TIMER_IRQ IRQ_TIMER1
#else
"Missing definitions of timer module test"
#endif
/*************************** timer irq test ***********************************/
static ulong seconds;
/* must use volatile to avoid being optimized by complier */
static int volatile exit;
static void timer_irq_handler(int irq, void *data)
{
static int count;
int period;
writel(TIMER_CLR_INT, TIMER_BASE + TIMER_INTSTATUS);
period = get_timer(seconds);
printf("timer_irq_handler: round-%d, irq=%d, period=%dms\n",
count++, irq, period);
seconds = get_timer(0);
if (count >= 5) {
exit = 1;
irq_free_handler(TIMER_IRQ);
printf("timer_irq_handler: irq test finish.\n");
}
}
static int soc_timer_irq_test_init(void)
{
writel(SYS_COUNTER_FREQ0, TIMER_BASE + TIMER_LOAD_COUNT0);
writel(SYS_COUNTER_FREQ1, TIMER_BASE + TIMER_LOAD_COUNT1);
writel(TIMER_CLR_INT, TIMER_BASE + TIMER_INTSTATUS);
writel(TIMER_EN | TIMER_INT_EN, TIMER_BASE + TIMER_CTRL);
irq_install_handler(TIMER_IRQ, timer_irq_handler, NULL);
irq_handler_enable(TIMER_IRQ);
seconds = get_timer(0);
while (!exit)
;
return 0;
}
/*************************** timer delay test *********************************/
static inline uint64_t arch_counter_get_cntpct(void)
{
uint64_t cval;
isb();
asm volatile("mrrc p15, 0, %Q0, %R0, c14" : "=r" (cval));
return cval;
}
static void sys_timer_delay_test_init(void)
{
ulong delay_t = 100, cost_t;
u64 tick_start;
int i;
for (i = 0; i < 5; i++) {
printf("sys timer delay test, round-%d\n", i);
/* us delay */
tick_start = arch_counter_get_cntpct();
udelay(delay_t);
cost_t = (arch_counter_get_cntpct() - tick_start) / 24;
printf("\tdesire delay %luus, actually delay %luus\n",
delay_t, cost_t);
/* ms delay */
tick_start = arch_counter_get_cntpct();
mdelay(delay_t);
cost_t = (arch_counter_get_cntpct() - tick_start) / 24000;
printf("\tdesire delay %lums, actually delay: %lums\n",
delay_t, cost_t);
/* ms delay */
tick_start = arch_counter_get_cntpct();
mdelay(delay_t * 10);
cost_t = (arch_counter_get_cntpct() - tick_start) / 24000;
printf("\tdesire delay %lums, actually delay: %lums\n",
delay_t * 10, cost_t);
}
}
int board_timer_test(int argc, char * const argv[])
{
sys_timer_delay_test_init();
soc_timer_irq_test_init();
return 0;
}