STiH410: Add STi timer driver

Add ARM global timer based timer

Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Patrice Chotard 2017-02-21 13:37:05 +01:00 committed by Tom Rini
parent 94e9a4ef91
commit 347cb2edf9
3 changed files with 86 additions and 0 deletions

View File

@ -58,4 +58,11 @@ config AST_TIMER
This is mostly because they all share several registers which This is mostly because they all share several registers which
makes it difficult to completely separate them. makes it difficult to completely separate them.
config STI_TIMER
bool "STi timer support"
depends on TIMER
default y if ARCH_STI
help
Select this to enable a timer for STi devices.
endmenu endmenu

View File

@ -10,3 +10,4 @@ obj-$(CONFIG_SANDBOX_TIMER) += sandbox_timer.o
obj-$(CONFIG_X86_TSC_TIMER) += tsc_timer.o obj-$(CONFIG_X86_TSC_TIMER) += tsc_timer.o
obj-$(CONFIG_OMAP_TIMER) += omap-timer.o obj-$(CONFIG_OMAP_TIMER) += omap-timer.o
obj-$(CONFIG_AST_TIMER) += ast_timer.o obj-$(CONFIG_AST_TIMER) += ast_timer.o
obj-$(CONFIG_STI_TIMER) += sti-timer.o

78
drivers/timer/sti-timer.c Normal file
View File

@ -0,0 +1,78 @@
/*
* (C) Copyright 2017 Patrice Chotard <patrice.chotard@st.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <dm.h>
#include <fdtdec.h>
#include <timer.h>
#include <asm/io.h>
#include <asm/arch-armv7/globaltimer.h>
DECLARE_GLOBAL_DATA_PTR;
struct sti_timer_priv {
struct globaltimer *global_timer;
};
static int sti_timer_get_count(struct udevice *dev, u64 *count)
{
struct sti_timer_priv *priv = dev_get_priv(dev);
struct globaltimer *global_timer = priv->global_timer;
u32 low, high;
u64 timer;
u32 old = readl(&global_timer->cnt_h);
while (1) {
low = readl(&global_timer->cnt_l);
high = readl(&global_timer->cnt_h);
if (old == high)
break;
else
old = high;
}
timer = high;
*count = (u64)((timer << 32) | low);
return 0;
}
static int sti_timer_probe(struct udevice *dev)
{
struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
struct sti_timer_priv *priv = dev_get_priv(dev);
fdt_addr_t addr;
uc_priv->clock_rate = CONFIG_SYS_HZ_CLOCK;
/* get arm global timer base address */
addr = fdtdec_get_addr(gd->fdt_blob, dev_of_offset(dev), "reg");
priv->global_timer = (struct globaltimer *)addr;
/* init timer */
writel(0x01, &priv->global_timer->ctl);
return 0;
}
static const struct timer_ops sti_timer_ops = {
.get_count = sti_timer_get_count,
};
static const struct udevice_id sti_timer_ids[] = {
{ .compatible = "arm,cortex-a9-global-timer" },
{}
};
U_BOOT_DRIVER(sti_timer) = {
.name = "sti_timer",
.id = UCLASS_TIMER,
.of_match = sti_timer_ids,
.priv_auto_alloc_size = sizeof(struct sti_timer_priv),
.probe = sti_timer_probe,
.ops = &sti_timer_ops,
.flags = DM_FLAG_PRE_RELOC,
};