nios2: convert altera timer to driver model

Convert altera timer to driver model.

Signed-off-by: Thomas Chou <thomas@wytron.com.tw>
Acked-by: Chin Liang See <clsee@altera.com>
This commit is contained in:
Thomas Chou 2015-10-22 22:28:53 +08:00
parent 8f41b8785b
commit a54915d8a1
9 changed files with 135 additions and 73 deletions

View File

@ -7,5 +7,5 @@
extra-y = start.o
obj-y = exceptions.o
obj-y += cpu.o interrupts.o sysid.o timer.o traps.o
obj-y += cpu.o interrupts.o sysid.o traps.o
obj-y += fdt.o

View File

@ -1,65 +0,0 @@
/*
* (C) Copyright 2000-2002
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* (C) Copyright 2004, Psyent Corporation <www.psyent.com>
* Scott McNutt <smcnutt@psyent.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <asm/nios2.h>
#include <asm/types.h>
#include <asm/io.h>
struct nios_timer {
u32 status; /* Timer status reg */
u32 control; /* Timer control reg */
u32 periodl; /* Timeout period low */
u32 periodh; /* Timeout period high */
u32 snapl; /* Snapshot low */
u32 snaph; /* Snapshot high */
};
/* status register */
#define NIOS_TIMER_TO (1 << 0) /* Timeout */
#define NIOS_TIMER_RUN (1 << 1) /* Timer running */
/* control register */
#define NIOS_TIMER_ITO (1 << 0) /* Timeout interrupt enable */
#define NIOS_TIMER_CONT (1 << 1) /* Continuous mode */
#define NIOS_TIMER_START (1 << 2) /* Start timer */
#define NIOS_TIMER_STOP (1 << 3) /* Stop timer */
/*************************************************************************/
unsigned long notrace timer_read_counter(void)
{
struct nios_timer *tmr = (struct nios_timer *)CONFIG_SYS_TIMER_BASE;
u32 val;
/* Trigger update */
writel(0x0, &tmr->snapl);
/* Read timer value */
val = readl(&tmr->snapl) & 0xffff;
val |= (readl(&tmr->snaph) & 0xffff) << 16;
return ~val;
}
int timer_init(void)
{
struct nios_timer *tmr = (struct nios_timer *)CONFIG_SYS_TIMER_BASE;
writel(0, &tmr->status);
writel(0, &tmr->control);
writel(NIOS_TIMER_STOP, &tmr->control);
writel(0xffff, &tmr->periodl);
writel(0xffff, &tmr->periodh);
writel(NIOS_TIMER_CONT | NIOS_TIMER_START, &tmr->control);
return 0;
}

View File

@ -795,8 +795,7 @@ static init_fnc_t init_sequence_f[] = {
init_timebase,
#endif
#if defined(CONFIG_ARM) || defined(CONFIG_MIPS) || \
defined(CONFIG_BLACKFIN) || defined(CONFIG_NDS32) || \
defined(CONFIG_NIOS2)
defined(CONFIG_BLACKFIN) || defined(CONFIG_NDS32)
timer_init, /* initialize timer */
#endif
#ifdef CONFIG_SYS_ALLOC_DPRAM

View File

@ -18,3 +18,5 @@ CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_ALTERA_PIO=y
CONFIG_ALTERA_JTAG_UART=y
CONFIG_ALTERA_JTAG_UART_BYPASS=y
CONFIG_TIMER=y
CONFIG_ALTERA_TIMER=y

View File

@ -0,0 +1,19 @@
Altera Timer
Required properties:
- compatible : should be "altr,timer-1.0"
- reg : Specifies base physical address and size of the registers.
- interrupt-parent: phandle of the interrupt controller
- interrupts : Should contain the timer interrupt number
- clock-frequency : The frequency of the clock that drives the counter, in Hz.
Example:
timer {
compatible = "altr,timer-1.0";
reg = <0x00400000 0x00000020>;
interrupt-parent = <&cpu>;
interrupts = <11>;
clock-frequency = <125000000>;
};

View File

@ -9,4 +9,11 @@ config TIMER
will be used. The timer is usually a 32 bits free-running up
counter. There may be no real tick, and no timer interrupt.
config ALTERA_TIMER
bool "Altera Timer support"
depends on TIMER
help
Select this to enable an timer for Altera devices. Please find
details on the "Embedded Peripherals IP User Guide" of Altera.
endmenu

View File

@ -5,3 +5,4 @@
#
obj-$(CONFIG_TIMER) += timer-uclass.o
obj-$(CONFIG_ALTERA_TIMER) += altera_timer.o

View File

@ -0,0 +1,104 @@
/*
* (C) Copyright 2000-2002
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* (C) Copyright 2004, Psyent Corporation <www.psyent.com>
* Scott McNutt <smcnutt@psyent.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <timer.h>
#include <asm/io.h>
DECLARE_GLOBAL_DATA_PTR;
struct altera_timer_regs {
u32 status; /* Timer status reg */
u32 control; /* Timer control reg */
u32 periodl; /* Timeout period low */
u32 periodh; /* Timeout period high */
u32 snapl; /* Snapshot low */
u32 snaph; /* Snapshot high */
};
struct altera_timer_platdata {
struct altera_timer_regs *regs;
unsigned long clock_rate;
};
/* control register */
#define ALTERA_TIMER_CONT (1 << 1) /* Continuous mode */
#define ALTERA_TIMER_START (1 << 2) /* Start timer */
#define ALTERA_TIMER_STOP (1 << 3) /* Stop timer */
static int altera_timer_get_count(struct udevice *dev, unsigned long *count)
{
struct altera_timer_platdata *plat = dev->platdata;
struct altera_timer_regs *const regs = plat->regs;
u32 val;
/* Trigger update */
writel(0x0, &regs->snapl);
/* Read timer value */
val = readl(&regs->snapl) & 0xffff;
val |= (readl(&regs->snaph) & 0xffff) << 16;
*count = ~val;
return 0;
}
static int altera_timer_probe(struct udevice *dev)
{
struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
struct altera_timer_platdata *plat = dev->platdata;
struct altera_timer_regs *const regs = plat->regs;
uc_priv->clock_rate = plat->clock_rate;
writel(0, &regs->status);
writel(0, &regs->control);
writel(ALTERA_TIMER_STOP, &regs->control);
writel(0xffff, &regs->periodl);
writel(0xffff, &regs->periodh);
writel(ALTERA_TIMER_CONT | ALTERA_TIMER_START, &regs->control);
return 0;
}
static int altera_timer_ofdata_to_platdata(struct udevice *dev)
{
struct altera_timer_platdata *plat = dev_get_platdata(dev);
plat->regs = ioremap(dev_get_addr(dev),
sizeof(struct altera_timer_regs));
plat->clock_rate = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
"clock-frequency", 0);
return 0;
}
static const struct timer_ops altera_timer_ops = {
.get_count = altera_timer_get_count,
};
static const struct udevice_id altera_timer_ids[] = {
{ .compatible = "altr,timer-1.0", },
{ }
};
U_BOOT_DRIVER(altera_timer) = {
.name = "altera_timer",
.id = UCLASS_TIMER,
.of_match = altera_timer_ids,
.ofdata_to_platdata = altera_timer_ofdata_to_platdata,
.platdata_auto_alloc_size = sizeof(struct altera_timer_platdata),
.probe = altera_timer_probe,
.ops = &altera_timer_ops,
.flags = DM_FLAG_PRE_RELOC,
};

View File

@ -25,11 +25,6 @@
#define CONFIG_BAUDRATE 115200
#define CONFIG_SYS_CONSOLE_INFO_QUIET /* Suppress console info */
/*
* TIMER
*/
#define CONFIG_SYS_TIMER_RATE CONFIG_SYS_TIMER_FREQ
/*
* BOOTP options
*/