20d3d53433
This service is required by various coreboot code modules. It looks like the 8064 SOC does not provide anything better than a 32 KHz free running counter (it is used in u-boot for us timer as well). Let's use this for now. BUG=chrome-os-partner:27784 TEST=manual . with the rest of the patches applied AP148 boots all the way to trying to start the payload. Original-Change-Id: I98b91ce179f7388d59c769a59caf49ca7640e047 Original-Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Original-Reviewed-on: https://chromium-review.googlesource.com/197896 (cherry picked from commit d526830f9d9618e4ca3460165d7b9ecc8ab268cf) Signed-off-by: Marc Jones <marc.jones@se-eng.com> Change-Id: Id37ed21193db67ceee11a795713c34ef26383380 Reviewed-on: http://review.coreboot.org/7993 Tested-by: build bot (Jenkins) Reviewed-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
138 lines
3.8 KiB
C
138 lines
3.8 KiB
C
/*
|
|
* Copyright (c) 2012 - 2013 The Linux Foundation. All rights reserved.
|
|
* Source : APQ8064 LK boot
|
|
*
|
|
* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* * Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in
|
|
* the documentation and/or other materials provided with the
|
|
* distribution.
|
|
* * Neither the name of Google, Inc. nor the names of its contributors
|
|
* may be used to endorse or promote products derived from this
|
|
* software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
|
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
* SUCH DAMAGE.
|
|
*/
|
|
|
|
#include <delay.h>
|
|
#include <iomap.h>
|
|
#include <ipq_timer.h>
|
|
#include <timer.h>
|
|
|
|
#define GPT_FREQ_KHZ 32
|
|
#define GPT_FREQ (GPT_FREQ_KHZ * 1000) /* 32 KHz */
|
|
|
|
/**
|
|
* init_timer - initialize timer
|
|
*/
|
|
void init_timer(void)
|
|
{
|
|
writel(0, GPT_ENABLE);
|
|
writel(GPT_ENABLE_EN, GPT_ENABLE);
|
|
}
|
|
|
|
/**
|
|
* udelay - generates micro second delay.
|
|
* @usec: delay duration in microseconds
|
|
*
|
|
* With 32KHz clock, minimum possible delay is 31.25 Micro seconds and
|
|
* its multiples. In Rumi GPT clock is 32 KHz
|
|
*/
|
|
void udelay(unsigned usec)
|
|
{
|
|
unsigned val;
|
|
unsigned now, last;
|
|
unsigned runcount;
|
|
|
|
usec = (usec + GPT_FREQ_KHZ - 1) / GPT_FREQ_KHZ;
|
|
last = readl(GPT_COUNT_VAL);
|
|
runcount = last;
|
|
val = usec + last;
|
|
|
|
do {
|
|
now = readl(GPT_COUNT_VAL);
|
|
if (last > now)
|
|
runcount += ((GPT_FREQ - last) + now);
|
|
else
|
|
runcount += (now - last);
|
|
last = now;
|
|
} while (runcount < val);
|
|
}
|
|
|
|
void timer_monotonic_get(struct mono_time *mt)
|
|
{
|
|
mono_time_set_usecs(mt, (readl(GPT_COUNT_VAL) * 1000) / GPT_FREQ_KHZ);
|
|
}
|
|
|
|
#if 0
|
|
|
|
/*
|
|
* TODO(vbendeb) clean it up later.
|
|
* Compile out the below code but leave it for now in case it will become
|
|
* necessary later in order to make the platform fully functional.
|
|
*/
|
|
static unsigned long timestamp;
|
|
static unsigned long lastinc;
|
|
|
|
inline ulong gpt_to_sys_freq(unsigned int gpt)
|
|
{
|
|
/*
|
|
* get_timer() expects the timer increments to be in terms
|
|
* of CONFIG_SYS_HZ. Convert GPT timer values to CONFIG_SYS_HZ
|
|
* units.
|
|
*/
|
|
return (((ulong)gpt) / (GPT_FREQ / CONFIG_SYS_HZ));
|
|
}
|
|
|
|
/**
|
|
* get_timer_masked - returns current ticks
|
|
*
|
|
* Returns the current timer ticks, since boot.
|
|
*/
|
|
ulong get_timer_masked(void)
|
|
{
|
|
ulong now = gpt_to_sys_freq(readl(GPT_COUNT_VAL));
|
|
|
|
if (lastinc <= now) { /* normal mode (non roll) */
|
|
/* normal mode */
|
|
timestamp += now - lastinc;
|
|
/* move stamp forward with absolute diff ticks */
|
|
} else { /* we have overflow of the count down timer */
|
|
timestamp += now + (TIMER_LOAD_VAL - lastinc);
|
|
}
|
|
|
|
lastinc = now;
|
|
|
|
return timestamp;
|
|
}
|
|
|
|
unsigned long long get_ticks(void)
|
|
{
|
|
return readl(GPT_COUNT_VAL);
|
|
}
|
|
|
|
/*
|
|
* Return the number of timer ticks per second.
|
|
*/
|
|
ulong get_tbclk(void)
|
|
{
|
|
return GPT_FREQ;
|
|
}
|
|
#endif
|