Commit 8bd0fc38 authored by Sergei Poselenov's avatar Sergei Poselenov
Browse files

RT #72064. Moved target-specific CM3 timer_init() code into common function.

parent c615cdac
......@@ -30,7 +30,7 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(CPU).a
START := start.o
COBJS := cpu.o cmd_cptf.o
COBJS := cpu.o cmd_cptf.o timer.o
SRCS := $(START:.o=.c) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS))
......
......@@ -29,7 +29,7 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(SOC).a
COBJS := clock.o cpu.o envm.o timer.o wdt.o
COBJS := clock.o cpu.o envm.o wdt.o
SOBJS :=
SRCS := $(COBJS:.o=.c)
......
......@@ -66,7 +66,7 @@
#define SYSBOOT_VERSION_2_X 0x00020000
#define MAX_SYSBOOT_VERSION 0x00030000
static unsigned long clock[5];
static unsigned long clock[CLOCK_END];
/*
* Retrieve the system clock frequency from eNVM spare page if available.
......@@ -181,6 +181,33 @@ void clock_init(void)
clock[CLOCK_PCLK1] = clock[CLOCK_FCLK] / pclk1_div;
clock[CLOCK_ACE] = clock[CLOCK_FCLK] / ace_div;
clock[CLOCK_FPGA] = (clock[CLOCK_FCLK] * fpga_div_half) / fpga_div;
/*
* Now, initialize the system timer clock source.
* Release systimer from reset
*/
A2F_SYSREG->soft_rst_cr &= ~A2F_SOFT_RST_TIMER_SR;
/*
* enable 32bit timer1
*/
A2F_TIMER->timer64_mode &= ~A2F_TIM64_64MODE_EN;
/*
* timer1 is used by envm driver
*/
A2F_TIMER->timer1_ctrl = A2F_TIM_CTRL_MODE_ONESHOT | A2F_TIM_CTRL_EN;
/*
* No reference clock
*/
A2F_SYSREG->systick_cr &= ~A2F_SYSTICK_NOREF;
/*
* div by 32
*/
A2F_SYSREG->systick_cr |= (A2F_SYSTICK_STCLK_DIV_32 <<
A2F_SYSTICK_STCLK_DIV_SHIFT);
A2F_SYSREG->systick_cr &= ~A2F_SYSTICK_TENMS_MSK;
A2F_SYSREG->systick_cr |= 0x7a12;
clock[CLOCK_SYSTICK] = clock[CLOCK_FCLK] / 32;
}
/*
......@@ -202,4 +229,3 @@ unsigned long __attribute__((section(".ramcode")))
return res;
}
/*
* (C) Copyright 2010,2011
* Sergei Poselenov, Emcraft Systems, sposelenov@emcraft.com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <common.h>
/* system core clock /32 */
#define SYSTICK_FREQ (clock_get(CLOCK_FCLK)/32)
/* Internal tick units */
static unsigned long long timestamp; /* Monotonic incrementing timer */
static ulong lastdec; /* Last decrementer snapshot */
int timer_init()
{
volatile struct a2f_sysreg *a2f_sysreg =
(volatile struct a2f_sysreg *)A2F_SYSREG_BASE;
volatile struct a2f_timer *a2f_timer =
(volatile struct a2f_timer *)A2F_TIMER_BASE;
volatile struct cm3_systick *systick =
(volatile struct cm3_systick *)CM3_SYSTICK_BASE;
/* Release systimer from reset */
a2f_sysreg->soft_rst_cr &= ~A2F_SOFT_RST_TIMER_SR;
/* enable 32bit timer1 */
a2f_timer->timer64_mode &= ~A2F_TIM64_64MODE_EN;
/* timer1 is used by envm driver */
a2f_timer->timer1_ctrl = A2F_TIM_CTRL_MODE_ONESHOT|A2F_TIM_CTRL_EN;
/* No reference clock */
a2f_sysreg->systick_cr &= ~A2F_SYSTICK_NOREF;
/* div by 32 */
a2f_sysreg->systick_cr |= (A2F_SYSTICK_STCLK_DIV_32 <<
A2F_SYSTICK_STCLK_DIV_SHIFT);
a2f_sysreg->systick_cr &= ~A2F_SYSTICK_TENMS_MSK;
a2f_sysreg->systick_cr |= 0x7a12;
systick->load = CM3_SYSTICK_LOAD_RELOAD_MSK - 1;
systick->val = 0;
/* Use external clock, no ints */
systick->ctrl = CM3_SYSTICK_CTRL_EN;
timestamp = 0;
return 0;
}
ulong get_timer(ulong base)
{
volatile struct cm3_systick *systick =
(volatile struct cm3_systick *)CM3_SYSTICK_BASE;
ulong now = systick->val;
if (lastdec >= now)
timestamp += lastdec - now;
else
timestamp += lastdec + CM3_SYSTICK_LOAD_RELOAD_MSK - 1 - now;
lastdec = now;
return timestamp / (SYSTICK_FREQ / 1000) - base;
}
void reset_timer(void)
{
volatile struct cm3_systick *systick =
(volatile struct cm3_systick *)(CM3_SYSTICK_BASE);
lastdec = systick->val;
timestamp = 0;
}
/* delay x useconds */
void __udelay(ulong usec)
{
ulong clc, tmp;
volatile struct cm3_systick *systick =
(volatile struct cm3_systick *)(CM3_SYSTICK_BASE);
clc = usec * (SYSTICK_FREQ / 1000000);
/* get current timestamp */
tmp = systick->val;
if (tmp < clc) {
/* loop till event */
while (systick->val < tmp ||
systick->val > (CM3_SYSTICK_LOAD_RELOAD_MSK - 1 -
clc + tmp)) ; /* nop */
} else {
while (systick->val > (tmp - clc)) ;
}
}
/*
* This function is derived from PowerPC code (timebase clock frequency).
* On ARM it returns the number of timer ticks per second.
*/
ulong get_tbclk(void)
{
return SYSTICK_FREQ;
}
......@@ -29,7 +29,7 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(SOC).a
COBJS := clock.o cpu.o envm.o timer.o wdt.o
COBJS := clock.o cpu.o envm.o wdt.o
SOBJS :=
SRCS := $(COBJS:.o=.c)
......
......@@ -406,6 +406,11 @@ void clock_init(void)
presc = apbahb_presc_tbl[tmp];
clock_val[CLOCK_PCLK2] = clock_val[CLOCK_HCLK] >> presc;
/*
* Set SYSTICK. Divider "8" is the SOC hardcoded.
*/
clock_val[CLOCK_SYSTICK] = clock_val[CLOCK_HCLK] / 8;
return;
}
......
/*
* (C) Copyright 2011
*
* Yuri Tikhonov, Emcraft Systems, yur@emcraft.com
* (C) Copyright 2010,2011
* Sergei Poselenov, Emcraft Systems, sposelenov@emcraft.com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
......@@ -15,23 +14,15 @@
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <common.h>
/* HCLK/8 */
#define SYSTICK_FREQ (clock_get(CLOCK_HCLK)/8)
/* Internal tick units */
static unsigned long long timestamp; /* Monotonic incrementing timer */
static ulong lastdec; /* Last decrementer snapshot */
/*
* Init timer.
*/
int timer_init(void)
int timer_init()
{
volatile struct cm3_systick *systick =
(volatile struct cm3_systick *)CM3_SYSTICK_BASE;
......@@ -45,10 +36,7 @@ int timer_init(void)
return 0;
}
/*
* Return difference between timer ticks and 'base'.
*/
unsigned long get_timer(unsigned long base)
ulong get_timer(ulong base)
{
volatile struct cm3_systick *systick =
(volatile struct cm3_systick *)CM3_SYSTICK_BASE;
......@@ -61,12 +49,9 @@ unsigned long get_timer(unsigned long base)
lastdec = now;
return timestamp / (SYSTICK_FREQ / 1000) - base;
return timestamp / (clock_get(CLOCK_SYSTICK) / 1000) - base;
}
/*
* Reset timer.
*/
void reset_timer(void)
{
volatile struct cm3_systick *systick =
......@@ -75,17 +60,15 @@ void reset_timer(void)
timestamp = 0;
}
/*
* Delay for 'usec' useconds.
*/
void __udelay(unsigned long usec)
/* delay x useconds */
void __udelay(ulong usec)
{
ulong clc, tmp;
volatile struct cm3_systick *systick =
(volatile struct cm3_systick *)(CM3_SYSTICK_BASE);
clc = usec * (SYSTICK_FREQ / 1000000);
clc = usec * (clock_get(CLOCK_SYSTICK) / 1000000);
/* get current timestamp */
tmp = systick->val;
......@@ -104,7 +87,7 @@ void __udelay(unsigned long usec)
* This function is derived from PowerPC code (timebase clock frequency).
* On ARM it returns the number of timer ticks per second.
*/
unsigned long get_tbclk(void)
ulong get_tbclk(void)
{
return SYSTICK_FREQ;
return clock_get(CLOCK_SYSTICK);
}
......@@ -122,6 +122,7 @@ enum clock {
CLOCK_PCLK1,
CLOCK_ACE,
CLOCK_FPGA,
CLOCK_SYSTICK,
CLOCK_END
};
......
......@@ -83,7 +83,7 @@ enum clock {
CLOCK_HCLK, /* HCLK clock frequency expressed in Hz */
CLOCK_PCLK1, /* PCLK1 clock frequency expressed in Hz */
CLOCK_PCLK2, /* PCLK2 clock frequency expressed in Hz */
CLOCK_SYSTICK, /* Systimer clock frequency expressed in Hz */
CLOCK_END /* for internal usage */
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment