exynos5250: Get rid of the PWM timer code we shouldn't be using anymore
This code was left over from U-Boot and was superceded by the MCT. Change-Id: Ia85e3b7281dcdd4740238dddd0dfc6f0ba2c94da Signed-off-by: Gabe Black <gabeblack@google.com> Reviewed-on: https://gerrit.chromium.org/gerrit/63778 Commit-Queue: Gabe Black <gabeblack@chromium.org> Reviewed-by: Gabe Black <gabeblack@chromium.org> Tested-by: Gabe Black <gabeblack@chromium.org> Reviewed-on: http://review.coreboot.org/4401 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi <patrick@georgi-clan.de>
This commit is contained in:
parent
2c116febab
commit
9b764a0dcc
|
@ -14,7 +14,6 @@ bootblock-$(CONFIG_BOOTBLOCK_CONSOLE) += uart.c
|
|||
endif
|
||||
bootblock-y += wakeup.c
|
||||
bootblock-y += gpio.c
|
||||
bootblock-$(CONFIG_BOOTBLOCK_CONSOLE) += pwm.c
|
||||
bootblock-$(CONFIG_BOOTBLOCK_CONSOLE) += timer.c
|
||||
|
||||
romstage-y += spi.c
|
||||
|
@ -30,7 +29,6 @@ ifeq ($(CONFIG_CONSOLE_SERIAL_UART),y)
|
|||
romstage-$(CONFIG_EARLY_CONSOLE) += uart.c
|
||||
endif
|
||||
romstage-y += wakeup.c
|
||||
romstage-y += pwm.c # needed by timer.c
|
||||
romstage-y += gpio.c
|
||||
romstage-y += timer.c
|
||||
romstage-y += i2c.c
|
||||
|
@ -46,7 +44,6 @@ ramstage-y += cpu.c
|
|||
ramstage-y += tmu.c
|
||||
ramstage-y += mct.c
|
||||
ramstage-y += monotonic_timer.c
|
||||
ramstage-y += pwm.c # needed by timer.c
|
||||
ramstage-y += timer.c
|
||||
ramstage-y += gpio.c
|
||||
ramstage-y += i2c.c
|
||||
|
|
|
@ -610,9 +610,8 @@ int clock_epll_set_rate(unsigned long rate)
|
|||
unsigned int epll_con, epll_con_k;
|
||||
unsigned int i;
|
||||
unsigned int lockcnt;
|
||||
unsigned int start;
|
||||
struct exynos5_clock *clk =
|
||||
samsung_get_base_clock();
|
||||
struct mono_time current, end;
|
||||
struct exynos5_clock *clk = samsung_get_base_clock();
|
||||
|
||||
epll_con = readl(&clk->epll_con0);
|
||||
epll_con &= ~((EPLL_CON0_LOCK_DET_EN_MASK <<
|
||||
|
@ -646,14 +645,19 @@ int clock_epll_set_rate(unsigned long rate)
|
|||
writel(epll_con, &clk->epll_con0);
|
||||
writel(epll_con_k, &clk->epll_con1);
|
||||
|
||||
start = get_timer(0);
|
||||
timer_monotonic_get(¤t);
|
||||
end = current;
|
||||
mono_time_add_msecs(&end, TIMEOUT_EPLL_LOCK);
|
||||
|
||||
while (!(readl(&clk->epll_con0) &
|
||||
(0x1 << EXYNOS5_EPLLCON0_LOCKED_SHIFT))) {
|
||||
if (get_timer(start) > TIMEOUT_EPLL_LOCK) {
|
||||
printk(BIOS_DEBUG, "%s: Timeout waiting for EPLL lock\n", __func__);
|
||||
if (mono_time_after(¤t, &end)) {
|
||||
printk(BIOS_DEBUG,
|
||||
"%s: Timeout waiting for EPLL lock\n",
|
||||
__func__);
|
||||
return -1;
|
||||
}
|
||||
timer_monotonic_get(¤t);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -73,7 +73,6 @@
|
|||
#define EXYNOS5_SPI1_BASE 0x12D30000
|
||||
#define EXYNOS5_I2C_BASE 0x12C60000
|
||||
#define EXYNOS5_SPI_BASE 0x12D20000
|
||||
#define EXYNOS5_PWMTIMER_BASE 0x12DD0000
|
||||
#define EXYNOS5_SPI_ISP_BASE 0x131A0000
|
||||
#define EXYNOS5_I2S_BASE 0x12D60000
|
||||
#define EXYNOS5_GPIO_PART3_BASE 0x13400000 /* E00..H17 */
|
||||
|
@ -108,7 +107,6 @@
|
|||
#define samsung_get_base_sromc() ((struct exynos5_sromc *)EXYNOS5_SROMC_BASE)
|
||||
#define samsung_get_base_swreset() ((struct exynos5_swreset *)EXYNOS5_SWRESET)
|
||||
#define samsung_get_base_sysreg() ((struct exynos5_sysreg *)EXYNOS5_SYSREG_BASE)
|
||||
#define samsung_get_base_timer() ((struct s5p_timer *)EXYNOS5_PWMTIMER_BASE)
|
||||
#define samsung_get_base_uart() ((struct exynos5_uart *)EXYNOS5_UART_BASE)
|
||||
#define samsung_get_base_usb_phy() ((struct exynos5_usb_phy *)EXYNOS5_USBPHY_BASE)
|
||||
#define samsung_get_base_usb_otg() ((struct exynos5_usb_otg *)EXYNOS5_USBOTG_BASE)
|
||||
|
|
|
@ -120,7 +120,7 @@ unsigned int s5p_dp_get_pll_lock_status(struct s5p_dp_device *dp)
|
|||
int s5p_dp_init_analog_func(struct s5p_dp_device *dp)
|
||||
{
|
||||
u32 reg;
|
||||
u32 start;
|
||||
struct mono_time current, end;
|
||||
struct exynos5_dp *base = dp->base;
|
||||
|
||||
writel(0x00, &base->dp_phy_pd);
|
||||
|
@ -135,13 +135,17 @@ int s5p_dp_init_analog_func(struct s5p_dp_device *dp)
|
|||
|
||||
clrbits_le32(&base->dp_pll_ctl, DP_PLL_PD);
|
||||
|
||||
start = get_timer(0);
|
||||
timer_monotonic_get(¤t);
|
||||
end = current;
|
||||
mono_time_add_msecs(&end, PLL_LOCK_TIMEOUT);
|
||||
|
||||
while (s5p_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
|
||||
if (get_timer(start) > PLL_LOCK_TIMEOUT) {
|
||||
if (mono_time_after(¤t, &end)) {
|
||||
printk(BIOS_ERR, "%s: PLL is not locked\n",
|
||||
__func__);
|
||||
return -1;
|
||||
}
|
||||
timer_monotonic_get(¤t);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -431,11 +435,14 @@ void s5p_dp_enable_video_master(struct s5p_dp_device *dp)
|
|||
int s5p_dp_is_video_stream_on(struct s5p_dp_device *dp)
|
||||
{
|
||||
u32 reg, i = 0;
|
||||
u32 start;
|
||||
struct mono_time current, end;
|
||||
struct exynos5_dp *base = dp->base;
|
||||
|
||||
/* Wait for 4 VSYNC_DET interrupts */
|
||||
start = get_timer(0);
|
||||
timer_monotonic_get(¤t);
|
||||
end = current;
|
||||
mono_time_add_msecs(&end, STREAM_ON_TIMEOUT);
|
||||
|
||||
do {
|
||||
reg = readl(&base->common_int_sta_1);
|
||||
if (reg & VSYNC_DET) {
|
||||
|
@ -444,7 +451,8 @@ int s5p_dp_is_video_stream_on(struct s5p_dp_device *dp)
|
|||
}
|
||||
if (i == 4)
|
||||
break;
|
||||
} while (get_timer(start) <= STREAM_ON_TIMEOUT);
|
||||
timer_monotonic_get(¤t);
|
||||
} while (mono_time_before(¤t, &end));
|
||||
|
||||
if (i != 4) {
|
||||
printk(BIOS_DEBUG, "s5p_dp_is_video_stream_on timeout\n");
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#include <timer.h>
|
||||
#include <delay.h>
|
||||
#include <console/console.h>
|
||||
#include "timer.h"
|
||||
#include "cpu.h"
|
||||
#include "power.h"
|
||||
#include "sysreg.h"
|
||||
|
@ -411,20 +410,24 @@ static int s5p_dp_hw_link_training(struct s5p_dp_device *dp,
|
|||
{
|
||||
int pll_is_locked = 0;
|
||||
u32 data;
|
||||
u32 start;
|
||||
int lane;
|
||||
struct mono_time current, end;
|
||||
struct exynos5_dp *base = dp->base;
|
||||
|
||||
/* Stop Video */
|
||||
clrbits_le32(&base->video_ctl_1, VIDEO_EN);
|
||||
|
||||
start = get_timer(0);
|
||||
timer_monotonic_get(¤t);
|
||||
end = current;
|
||||
mono_time_add_msecs(&end, PLL_LOCK_TIMEOUT);
|
||||
|
||||
while ((pll_is_locked = s5p_dp_get_pll_lock_status(dp)) == PLL_UNLOCKED) {
|
||||
if (get_timer(start) > PLL_LOCK_TIMEOUT) {
|
||||
if (mono_time_after(¤t, &end)) {
|
||||
/* Ignore this error, and try to continue */
|
||||
printk(BIOS_ERR, "PLL is not locked yet.\n");
|
||||
break;
|
||||
}
|
||||
timer_monotonic_get(¤t);
|
||||
}
|
||||
printk(BIOS_SPEW, "PLL is %slocked\n",
|
||||
pll_is_locked == PLL_LOCKED ? "": "not ");
|
||||
|
|
|
@ -37,7 +37,6 @@ void timer_monotonic_get(struct mono_time *mt)
|
|||
uint64_t usecs_elapsed;
|
||||
|
||||
if (!mono_counter.initialized) {
|
||||
init_timer();
|
||||
mono_counter.last_value = mct_raw_value();
|
||||
mono_counter.initialized = 1;
|
||||
}
|
||||
|
|
|
@ -1,186 +0,0 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2011 Samsung Electronics
|
||||
*
|
||||
* 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; version 2 of the License.
|
||||
*
|
||||
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <arch/io.h>
|
||||
#include "clk.h"
|
||||
#include "cpu.h"
|
||||
#include "periph.h"
|
||||
#include "pwm.h"
|
||||
|
||||
int pwm_enable(int pwm_id)
|
||||
{
|
||||
struct s5p_timer *const pwm = samsung_get_base_timer();
|
||||
unsigned long tcon;
|
||||
|
||||
tcon = readl(&pwm->tcon);
|
||||
tcon |= TCON_START(pwm_id);
|
||||
|
||||
writel(tcon, &pwm->tcon);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pwm_check_enabled(int pwm_id)
|
||||
{
|
||||
const struct s5p_timer *pwm = samsung_get_base_timer();
|
||||
const unsigned long tcon = readl(&pwm->tcon);
|
||||
|
||||
return tcon & TCON_START(pwm_id);
|
||||
}
|
||||
|
||||
void pwm_disable(int pwm_id)
|
||||
{
|
||||
struct s5p_timer *const pwm = samsung_get_base_timer();
|
||||
unsigned long tcon;
|
||||
|
||||
tcon = readl(&pwm->tcon);
|
||||
tcon &= ~TCON_START(pwm_id);
|
||||
|
||||
writel(tcon, &pwm->tcon);
|
||||
}
|
||||
|
||||
static unsigned long pwm_calc_tin(int pwm_id, unsigned long freq)
|
||||
{
|
||||
unsigned long tin_parent_rate;
|
||||
unsigned int div;
|
||||
|
||||
tin_parent_rate = clock_get_periph_rate(PERIPH_ID_PWM0);
|
||||
|
||||
for (div = 2; div <= 16; div *= 2) {
|
||||
if ((tin_parent_rate / (div << 16)) < freq)
|
||||
return tin_parent_rate / div;
|
||||
}
|
||||
|
||||
return tin_parent_rate / 16;
|
||||
}
|
||||
|
||||
#define NS_IN_SEC 1000000000UL
|
||||
|
||||
int pwm_config(int pwm_id, int duty_ns, int period_ns)
|
||||
{
|
||||
struct s5p_timer *const pwm = samsung_get_base_timer();
|
||||
unsigned int offset;
|
||||
unsigned long tin_rate;
|
||||
unsigned long tin_ns;
|
||||
unsigned long frequency;
|
||||
unsigned long tcon;
|
||||
unsigned long tcnt;
|
||||
unsigned long tcmp;
|
||||
|
||||
/*
|
||||
* We currently avoid using 64bit arithmetic by using the
|
||||
* fact that anything faster than 1GHz is easily representable
|
||||
* by 32bits.
|
||||
*/
|
||||
if (period_ns > NS_IN_SEC || duty_ns > NS_IN_SEC || period_ns == 0)
|
||||
return -1;
|
||||
|
||||
if (duty_ns > period_ns)
|
||||
return -1;
|
||||
|
||||
frequency = NS_IN_SEC / period_ns;
|
||||
|
||||
/* Check to see if we are changing the clock rate of the PWM */
|
||||
tin_rate = pwm_calc_tin(pwm_id, frequency);
|
||||
|
||||
tin_ns = NS_IN_SEC / tin_rate;
|
||||
tcnt = period_ns / tin_ns;
|
||||
|
||||
/* Note, counters count down */
|
||||
tcmp = duty_ns / tin_ns;
|
||||
tcmp = tcnt - tcmp;
|
||||
|
||||
/* Update the PWM register block. */
|
||||
offset = pwm_id * 3;
|
||||
if (pwm_id < 4) {
|
||||
writel(tcnt, &pwm->tcntb0 + offset);
|
||||
writel(tcmp, &pwm->tcmpb0 + offset);
|
||||
}
|
||||
|
||||
tcon = readl(&pwm->tcon);
|
||||
tcon |= TCON_UPDATE(pwm_id);
|
||||
if (pwm_id < 4)
|
||||
tcon |= TCON_AUTO_RELOAD(pwm_id);
|
||||
else
|
||||
tcon |= TCON4_AUTO_RELOAD;
|
||||
writel(tcon, &pwm->tcon);
|
||||
|
||||
tcon &= ~TCON_UPDATE(pwm_id);
|
||||
writel(tcon, &pwm->tcon);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pwm_init(int pwm_id, int div, int invert)
|
||||
{
|
||||
u32 val;
|
||||
struct s5p_timer *const pwm = samsung_get_base_timer();
|
||||
unsigned long ticks_per_period;
|
||||
unsigned int offset, prescaler;
|
||||
|
||||
/*
|
||||
* Timer Freq(HZ) =
|
||||
* PWM_CLK / { (prescaler_value + 1) * (divider_value) }
|
||||
*/
|
||||
|
||||
val = readl(&pwm->tcfg0);
|
||||
if (pwm_id < 2) {
|
||||
prescaler = PRESCALER_0;
|
||||
val &= ~0xff;
|
||||
val |= (prescaler & 0xff);
|
||||
} else {
|
||||
prescaler = PRESCALER_1;
|
||||
val &= ~(0xff << 8);
|
||||
val |= (prescaler & 0xff) << 8;
|
||||
}
|
||||
writel(val, &pwm->tcfg0);
|
||||
val = readl(&pwm->tcfg1);
|
||||
val &= ~(0xf << MUX_DIV_SHIFT(pwm_id));
|
||||
val |= (div & 0xf) << MUX_DIV_SHIFT(pwm_id);
|
||||
writel(val, &pwm->tcfg1);
|
||||
|
||||
|
||||
if (pwm_id == 4) {
|
||||
/*
|
||||
* TODO(sjg): Use this as a countdown timer for now. We count
|
||||
* down from the maximum value to 0, then reset.
|
||||
*/
|
||||
ticks_per_period = -1UL;
|
||||
} else {
|
||||
const unsigned long pwm_hz = 1000;
|
||||
unsigned long timer_rate_hz = clock_get_periph_rate(
|
||||
PERIPH_ID_PWM0) / ((prescaler + 1) * (1 << div));
|
||||
|
||||
ticks_per_period = timer_rate_hz / pwm_hz;
|
||||
}
|
||||
|
||||
/* set count value */
|
||||
offset = pwm_id * 3;
|
||||
|
||||
writel(ticks_per_period, &pwm->tcntb0 + offset);
|
||||
|
||||
val = readl(&pwm->tcon) & ~(0xf << TCON_OFFSET(pwm_id));
|
||||
if (invert && (pwm_id < 4))
|
||||
val |= TCON_INVERTER(pwm_id);
|
||||
writel(val, &pwm->tcon);
|
||||
|
||||
pwm_enable(pwm_id);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2009 Samsung Electronics
|
||||
*
|
||||
* 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; version 2 of the License.
|
||||
*
|
||||
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef CPU_SAMSUNG_EXYNOS5250_PWM_H
|
||||
#define CPU_SAMSUNG_EXYNOS5250_PWM_H
|
||||
|
||||
#define PRESCALER_0 (8 - 1) /* prescaler of timer 0, 1 */
|
||||
#define PRESCALER_1 (16 - 1) /* prescaler of timer 2, 3, 4 */
|
||||
|
||||
/* Divider MUX */
|
||||
#define MUX_DIV_1 0 /* 1/1 period */
|
||||
#define MUX_DIV_2 1 /* 1/2 period */
|
||||
#define MUX_DIV_4 2 /* 1/4 period */
|
||||
#define MUX_DIV_8 3 /* 1/8 period */
|
||||
#define MUX_DIV_16 4 /* 1/16 period */
|
||||
|
||||
#define MUX_DIV_SHIFT(x) (x * 4)
|
||||
|
||||
#define TCON_OFFSET(x) ((x + 1) * (!!x) << 2)
|
||||
|
||||
#define TCON_START(x) (1 << TCON_OFFSET(x))
|
||||
#define TCON_UPDATE(x) (1 << (TCON_OFFSET(x) + 1))
|
||||
#define TCON_INVERTER(x) (1 << (TCON_OFFSET(x) + 2))
|
||||
#define TCON_AUTO_RELOAD(x) (1 << (TCON_OFFSET(x) + 3))
|
||||
#define TCON4_AUTO_RELOAD (1 << 22)
|
||||
|
||||
struct s5p_timer {
|
||||
unsigned int tcfg0;
|
||||
unsigned int tcfg1;
|
||||
unsigned int tcon;
|
||||
unsigned int tcntb0;
|
||||
unsigned int tcmpb0;
|
||||
unsigned int tcnto0;
|
||||
unsigned int tcntb1;
|
||||
unsigned int tcmpb1;
|
||||
unsigned int tcnto1;
|
||||
unsigned int tcntb2;
|
||||
unsigned int tcmpb2;
|
||||
unsigned int tcnto2;
|
||||
unsigned int tcntb3;
|
||||
unsigned int tcmpb3;
|
||||
unsigned int tcnto3;
|
||||
unsigned int tcntb4;
|
||||
unsigned int tcnto4;
|
||||
unsigned int tintcstat;
|
||||
};
|
||||
|
||||
int pwm_config(int pwm_id, int duty_ns, int period_ns);
|
||||
int pwm_check_enabled(int pwm_id);
|
||||
void pwm_disable(int pwm_id);
|
||||
int pwm_enable(int pwm_id);
|
||||
int pwm_init(int pwm_id, int div, int invert);
|
||||
|
||||
#endif
|
|
@ -18,72 +18,14 @@
|
|||
*/
|
||||
|
||||
#include <console/console.h>
|
||||
#include <arch/io.h>
|
||||
#include <timer.h>
|
||||
#include <delay.h>
|
||||
#include "timer.h"
|
||||
#include "pwm.h"
|
||||
|
||||
#include "clk.h"
|
||||
#include "cpu.h"
|
||||
|
||||
static unsigned long long timer_reset_value;
|
||||
static unsigned long lastinc;
|
||||
|
||||
/* macro to read the 16 bit timer */
|
||||
static inline struct s5p_timer *s5p_get_base_timer(void)
|
||||
{
|
||||
return samsung_get_base_timer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the countdown timer.
|
||||
*
|
||||
* This operates at 1MHz and counts downwards. It will wrap about every
|
||||
* hour (2^32 microseconds).
|
||||
*
|
||||
* @return current value of timer
|
||||
*/
|
||||
static unsigned long timer_get_us_down(void)
|
||||
{
|
||||
struct s5p_timer *const timer = s5p_get_base_timer();
|
||||
|
||||
return readl(&timer->tcnto4);
|
||||
}
|
||||
|
||||
void init_timer(void)
|
||||
{
|
||||
/* Timer may have been enabled in SPL */
|
||||
if (!pwm_check_enabled(4)) {
|
||||
/* PWM Timer 4 */
|
||||
pwm_init(4, MUX_DIV_4, 0);
|
||||
pwm_config(4, 100000, 100000);
|
||||
pwm_enable(4);
|
||||
|
||||
/* Use this as the current monotonic time in us */
|
||||
timer_reset_value = 0;
|
||||
|
||||
/* Use this as the last timer value we saw */
|
||||
lastinc = timer_get_us_down();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* timer without interrupts
|
||||
*/
|
||||
unsigned long get_timer(unsigned long base)
|
||||
{
|
||||
unsigned long now = timer_get_us_down();
|
||||
|
||||
/*
|
||||
* Increment the time by the amount elapsed since the last read.
|
||||
* The timer may have wrapped around, but it makes no difference to
|
||||
* our arithmetic here.
|
||||
*/
|
||||
timer_reset_value += lastinc - now;
|
||||
lastinc = now;
|
||||
|
||||
/* Divide by 1000 to convert from us to ms */
|
||||
return timer_reset_value / 1000 - base;
|
||||
mct_start();
|
||||
}
|
||||
|
||||
/* delay x useconds */
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright 2013 Google Inc.
|
||||
*
|
||||
* 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; version 2 of the License.
|
||||
*
|
||||
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef CPU_SAMSUNG_EXYNOS5250_TIMER_H
|
||||
#define CPU_SAMSUNG_EXYNOS5250_TIMER_H
|
||||
|
||||
unsigned long get_timer(unsigned long base);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue