clocksource: add ARM AMBA SP804 support
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
This commit is contained in:
parent
650e2daa9f
commit
51d9e037ab
|
@ -1,3 +1,7 @@
|
|||
config AMBA_SP804
|
||||
bool
|
||||
depends on ARM_AMBA
|
||||
|
||||
config ARM_SMP_TWD
|
||||
bool
|
||||
depends on ARM && CPU_V7
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
obj-$(CONFIG_AMBA_SP804) += amba-sp804.o
|
||||
obj-$(CONFIG_ARM_SMP_TWD) += arm_smp_twd.o
|
||||
obj-$(CONFIG_CLOCKSOURCE_BCM2835) += bcm2835.o
|
||||
obj-$(CONFIG_CLOCKSOURCE_NOMADIK) += nomadik.o
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
|
||||
*
|
||||
* Under GPL v2
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <init.h>
|
||||
#include <clock.h>
|
||||
#include <io.h>
|
||||
#include <driver.h>
|
||||
#include <errno.h>
|
||||
#include <linux/amba/bus.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
#include <asm/hardware/arm_timer.h>
|
||||
|
||||
static __iomem void *sp804_base;
|
||||
static struct clk *sp804_clk;
|
||||
|
||||
static uint64_t sp804_read(void)
|
||||
{
|
||||
return ~readl(sp804_base + TIMER_VALUE);
|
||||
}
|
||||
|
||||
static struct clocksource sp804_clksrc = {
|
||||
.read = sp804_read,
|
||||
.shift = 20,
|
||||
.mask = CLOCKSOURCE_MASK(32),
|
||||
};
|
||||
|
||||
static int sp804_probe(struct amba_device *dev, const struct amba_id *id)
|
||||
{
|
||||
u32 tick_rate;
|
||||
int ret;
|
||||
|
||||
if (sp804_base) {
|
||||
dev_err(&dev->dev, "single instance driver\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
sp804_clk = clk_get(&dev->dev, NULL);
|
||||
if (IS_ERR(sp804_clk)) {
|
||||
ret = PTR_ERR(sp804_clk);
|
||||
dev_err(&dev->dev, "clock not found: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = clk_enable(sp804_clk);
|
||||
if (ret < 0) {
|
||||
dev_err(&dev->dev, "clock failed to enable: %d\n", ret);
|
||||
clk_put(sp804_clk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
sp804_base = amba_get_mem_region(dev);
|
||||
|
||||
tick_rate = clk_get_rate(sp804_clk);
|
||||
|
||||
/* setup timer 0 as free-running clocksource */
|
||||
writel(0, sp804_base + TIMER_CTRL);
|
||||
writel(0xffffffff, sp804_base + TIMER_LOAD);
|
||||
writel(0xffffffff, sp804_base + TIMER_VALUE);
|
||||
writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC,
|
||||
sp804_base + TIMER_CTRL);
|
||||
|
||||
sp804_clksrc.mult = clocksource_hz2mult(tick_rate, sp804_clksrc.shift);
|
||||
|
||||
init_clock(&sp804_clksrc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct amba_id sp804_ids[] = {
|
||||
{
|
||||
.id = 0x00141804,
|
||||
.mask = 0x00ffffff,
|
||||
},
|
||||
{ 0, 0 },
|
||||
};
|
||||
|
||||
struct amba_driver sp804_driver = {
|
||||
.drv = {
|
||||
.name = "sp804",
|
||||
},
|
||||
.probe = sp804_probe,
|
||||
.id_table = sp804_ids,
|
||||
};
|
||||
|
||||
static int sp804_init(void)
|
||||
{
|
||||
return amba_driver_register(&sp804_driver);
|
||||
}
|
||||
coredevice_initcall(sp804_init);
|
Loading…
Reference in New Issue