timer: Add generic udelay() implementation
Add GENERIC_UDELAY Kconfig option so that a generic udelay() implementation is provided utilizing the monotonic timer. That way each board/chipset doesn't need to duplicate the same udelay(). Additionally, assume that GENERIC_UDELAY implies init_timer() is not required. BUG=None BRANCH=None TEST=Built nyan, ryu, and rambi. May need help testing. Change-Id: I7f511a2324b5aa5d1b2959f4519be85a6a7360e8 Signed-off-by: Patrick Georgi <pgeorgi@chromium.org> Original-Commit-Id: 1a85fbcad778933d13eaef545135abe7e4de46ed Original-Change-Id: Idd26de19eefc91ee3b0ceddfb1bc2152e19fd8ab Original-Signed-off-by: Aaron Durbin <adurbin@chromium.org> Original-Reviewed-on: https://chromium-review.googlesource.com/219719 Original-Reviewed-by: Julius Werner <jwerner@chromium.org> Original-Reviewed-by: Furquan Shaikh <furquan@chromium.org> Reviewed-on: http://review.coreboot.org/9334 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi <pgeorgi@google.com>
This commit is contained in:
parent
23b4e4c4e8
commit
e5e36306a9
|
@ -360,6 +360,13 @@ config HAVE_MONOTONIC_TIMER
|
|||
help
|
||||
The board/chipset provides a monotonic timer.
|
||||
|
||||
config GENERIC_UDELAY
|
||||
def_bool n
|
||||
depends on HAVE_MONOTONIC_TIMER
|
||||
help
|
||||
The board/chipset uses a generic udelay function utilizing the
|
||||
monotonic timer.
|
||||
|
||||
config TIMER_QUEUE
|
||||
def_bool n
|
||||
depends on HAVE_MONOTONIC_TIMER
|
||||
|
|
|
@ -38,7 +38,6 @@ bootblock-y += boot.c
|
|||
bootblock-y += bootblock.S
|
||||
bootblock-y += bootblock_simple.c
|
||||
bootblock-y += stages.c
|
||||
bootblock-y += timer.c
|
||||
bootblock-y += ../../lib/memcpy.c
|
||||
bootblock-y += ../../lib/memmove.c
|
||||
bootblock-y += ../../lib/memset.c
|
||||
|
@ -64,7 +63,6 @@ ifeq ($(CONFIG_ARCH_ROMSTAGE_MIPS),y)
|
|||
romstage-y += boot.c
|
||||
romstage-$(CONFIG_EARLY_CONSOLE) += early_console.c
|
||||
romstage-y += stages.c
|
||||
romstage-y += timer.c
|
||||
romstage-y += ../../lib/memcpy.c
|
||||
romstage-y += ../../lib/memmove.c
|
||||
romstage-y += ../../lib/memset.c
|
||||
|
@ -85,7 +83,6 @@ ramstage-y += ashldi3.c
|
|||
ramstage-y += boot.c
|
||||
ramstage-y += stages.c
|
||||
ramstage-y += tables.c
|
||||
ramstage-y += timer.c
|
||||
ramstage-y += ../../lib/memcpy.c
|
||||
ramstage-y += ../../lib/memmove.c
|
||||
ramstage-y += ../../lib/memset.c
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2014 Imagination Technologies
|
||||
*
|
||||
* 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 <delay.h>
|
||||
#include <timer.h>
|
||||
|
||||
void init_timer(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
void udelay(unsigned usec)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
|
@ -1,7 +1,11 @@
|
|||
#ifndef DELAY_H
|
||||
#define DELAY_H
|
||||
|
||||
#if IS_ENABLED(CONFIG_GENERIC_UDELAY)
|
||||
static inline void init_timer(void) {}
|
||||
#else
|
||||
void init_timer(void);
|
||||
#endif
|
||||
|
||||
void udelay(unsigned usecs);
|
||||
void mdelay(unsigned msecs);
|
||||
|
|
|
@ -22,6 +22,8 @@ bootblock-y += prog_ops.c
|
|||
bootblock-y += cbfs.c cbfs_core.c
|
||||
bootblock-$(CONFIG_COMMON_CBFS_SPI_WRAPPER) += cbfs_spi.c
|
||||
|
||||
bootblock-$(CONFIG_GENERIC_UDELAY) += timer.c
|
||||
|
||||
bootblock-$(CONFIG_CONSOLE_CBMEM) += cbmem_console.c
|
||||
bootblock-y += memchr.c
|
||||
bootblock-y += memcmp.c
|
||||
|
@ -61,6 +63,8 @@ romstage-$(CONFIG_ARCH_ROMSTAGE_X86_32) += gcc.c
|
|||
ramstage-$(CONFIG_ARCH_RAMSTAGE_X86_32) += gcc.c
|
||||
endif
|
||||
|
||||
romstage-$(CONFIG_GENERIC_UDELAY) += timer.c
|
||||
|
||||
ramstage-y += prog_ops.c
|
||||
ramstage-y += hardwaremain.c
|
||||
ramstage-y += selfboot.c
|
||||
|
@ -89,6 +93,7 @@ ramstage-y += memrange.c
|
|||
ramstage-$(CONFIG_COOP_MULTITASKING) += thread.c
|
||||
ramstage-$(CONFIG_TIMER_QUEUE) += timer_queue.c
|
||||
ramstage-$(CONFIG_TERTIARY_BOARD_ID) += tristate_gpios.c
|
||||
ramstage-$(CONFIG_GENERIC_UDELAY) += timer.c
|
||||
|
||||
romstage-y += cbmem_common.c dynamic_cbmem.c
|
||||
ramstage-y += cbmem_common.c dynamic_cbmem.c
|
||||
|
|
|
@ -22,16 +22,12 @@
|
|||
#include <delay.h>
|
||||
#include <thread.h>
|
||||
|
||||
void init_timer(void)
|
||||
{
|
||||
}
|
||||
|
||||
void udelay(unsigned usec)
|
||||
{
|
||||
struct stopwatch sw;
|
||||
|
||||
/*
|
||||
* As the hardware clock granularity is in microseconds pad the
|
||||
* As the timer granularity is in microseconds pad the
|
||||
* requested delay by one to get at least >= requested usec delay.
|
||||
*/
|
||||
usec += 1;
|
||||
|
@ -40,6 +36,7 @@ void udelay(unsigned usec)
|
|||
return;
|
||||
|
||||
stopwatch_init_usecs_expire(&sw, usec);
|
||||
|
||||
while (!stopwatch_expired(&sw))
|
||||
;
|
||||
}
|
|
@ -7,6 +7,8 @@ config SOC_NVIDIA_TEGRA124
|
|||
select ARCH_RAMSTAGE_ARMV7
|
||||
select HAVE_UART_SPECIAL
|
||||
select HAVE_HARD_RESET
|
||||
select HAVE_MONOTONIC_TIMER
|
||||
select GENERIC_UDELAY
|
||||
select BOOTBLOCK_CONSOLE
|
||||
select ARM_BOOTBLOCK_CUSTOM
|
||||
select ARM_LPAE
|
||||
|
|
|
@ -15,7 +15,6 @@ bootblock-$(CONFIG_SOFTWARE_I2C) += ../tegra/software_i2c.c
|
|||
bootblock-y += ../tegra/pingroup.c
|
||||
bootblock-y += ../tegra/pinmux.c
|
||||
bootblock-y += ../tegra/apbmisc.c
|
||||
bootblock-y += timer.c
|
||||
ifeq ($(CONFIG_BOOTBLOCK_CONSOLE),y)
|
||||
bootblock-$(CONFIG_DRIVERS_UART) += uart.c
|
||||
endif
|
||||
|
@ -25,7 +24,6 @@ verstage-y += cbfs.c
|
|||
verstage-y += dma.c
|
||||
verstage-y += monotonic_timer.c
|
||||
verstage-y += spi.c
|
||||
verstage-y += timer.c
|
||||
verstage-$(CONFIG_DRIVERS_UART) += uart.c
|
||||
verstage-y += ../tegra/gpio.c
|
||||
verstage-y += ../tegra/i2c.c
|
||||
|
@ -48,7 +46,6 @@ romstage-y += ../tegra/gpio.c
|
|||
romstage-y += ../tegra/i2c.c
|
||||
romstage-$(CONFIG_SOFTWARE_I2C) += ../tegra/software_i2c.c
|
||||
romstage-y += ../tegra/pinmux.c
|
||||
romstage-y += timer.c
|
||||
romstage-y += cache.c
|
||||
romstage-$(CONFIG_DRIVERS_UART) += uart.c
|
||||
|
||||
|
@ -70,7 +67,6 @@ ramstage-y += ../tegra/i2c.c
|
|||
ramstage-$(CONFIG_SOFTWARE_I2C) += ../tegra/software_i2c.c
|
||||
ramstage-y += ../tegra/pinmux.c
|
||||
ramstage-y += ../tegra/usb.c
|
||||
ramstage-y += timer.c
|
||||
ramstage-$(CONFIG_DRIVERS_UART) += uart.c
|
||||
|
||||
rmodules_$(ARCH-romstage-y)-y += monotonic_timer.c
|
||||
|
|
|
@ -1,53 +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
|
||||
*/
|
||||
|
||||
#include <console/console.h>
|
||||
#include <timer.h>
|
||||
#include <delay.h>
|
||||
#include <thread.h>
|
||||
|
||||
void init_timer(void)
|
||||
{
|
||||
}
|
||||
|
||||
/* delay x useconds */
|
||||
void udelay(unsigned usec)
|
||||
{
|
||||
struct mono_time current, end;
|
||||
|
||||
if (!thread_yield_microseconds(usec))
|
||||
return;
|
||||
|
||||
timer_monotonic_get(¤t);
|
||||
end = current;
|
||||
mono_time_add_usecs(&end, usec);
|
||||
|
||||
if (mono_time_after(¤t, &end)) {
|
||||
printk(BIOS_EMERG, "udelay: 0x%08x is impossibly large\n",
|
||||
usec);
|
||||
/* There's not much we can do if usec is too big. Use a long,
|
||||
* paranoid delay value and hope for the best... */
|
||||
end = current;
|
||||
mono_time_add_usecs(&end, USECS_PER_SEC);
|
||||
}
|
||||
|
||||
while (mono_time_before(¤t, &end))
|
||||
timer_monotonic_get(¤t);
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@ config SOC_NVIDIA_TEGRA132
|
|||
select BOOTBLOCK_CONSOLE
|
||||
select GIC
|
||||
select HAVE_MONOTONIC_TIMER
|
||||
select GENERIC_UDELAY
|
||||
select HAVE_HARD_RESET
|
||||
select HAVE_UART_SPECIAL
|
||||
select HAVE_UART_MEMORY_MAPPED
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
bootblock-y += bootblock.c
|
||||
bootblock-y += bootblock_asm.S
|
||||
bootblock-y += cbfs.c
|
||||
bootblock-y += timer.c
|
||||
bootblock-y += clock.c
|
||||
bootblock-y += spi.c
|
||||
bootblock-y += i2c.c
|
||||
|
@ -26,7 +25,6 @@ romstage-y += romstage_asm.S
|
|||
romstage-y += addressmap.c
|
||||
romstage-y += cbfs.c
|
||||
romstage-y += cbmem.c
|
||||
romstage-y += timer.c
|
||||
romstage-y += ccplex.c
|
||||
romstage-y += clock.c
|
||||
romstage-y += cpu.c
|
||||
|
@ -53,7 +51,6 @@ ramstage-y += cbfs.c
|
|||
ramstage-y += cbmem.c
|
||||
ramstage-y += cpu.c
|
||||
ramstage-y += cpu_lib.S
|
||||
ramstage-y += timer.c
|
||||
ramstage-y += clock.c
|
||||
ramstage-y += soc.c
|
||||
ramstage-y += spi.c
|
||||
|
|
|
@ -26,6 +26,7 @@ config SOC_ROCKCHIP_RK3288
|
|||
select ARCH_RAMSTAGE_ARMV7
|
||||
select CPU_HAS_BOOTBLOCK_INIT
|
||||
select HAVE_MONOTONIC_TIMER
|
||||
select GENERIC_UDELAY
|
||||
select HAVE_UART_MEMORY_MAPPED
|
||||
select HAVE_UART_SPECIAL
|
||||
select BOOTBLOCK_CONSOLE
|
||||
|
|
|
@ -23,36 +23,9 @@
|
|||
#include <soc/timer.h>
|
||||
#include <timer.h>
|
||||
|
||||
void init_timer(void)
|
||||
{
|
||||
}
|
||||
|
||||
void rk3288_init_timer(void)
|
||||
{
|
||||
write32(TIMER_LOAD_VAL, &timer7_ptr->timer_load_count0);
|
||||
write32(TIMER_LOAD_VAL, &timer7_ptr->timer_load_count1);
|
||||
write32(1, &timer7_ptr->timer_ctrl_reg);
|
||||
}
|
||||
|
||||
/* delay x useconds */
|
||||
void udelay(unsigned usec)
|
||||
{
|
||||
struct mono_time current, end;
|
||||
|
||||
timer_monotonic_get(¤t);
|
||||
end = current;
|
||||
mono_time_add_usecs(&end, usec);
|
||||
|
||||
if (mono_time_after(¤t, &end)) {
|
||||
printk(BIOS_EMERG, "udelay: 0x%08x is impossibly large\n",
|
||||
usec);
|
||||
/* There's not much we can do if usec is too big. Use a long,
|
||||
* paranoid delay value and hope for the best... */
|
||||
end = current;
|
||||
mono_time_add_usecs(&end, USECS_PER_SEC);
|
||||
}
|
||||
|
||||
while (mono_time_before(¤t, &end))
|
||||
timer_monotonic_get(¤t);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ config CPU_SAMSUNG_EXYNOS5250
|
|||
select ARCH_RAMSTAGE_ARMV7
|
||||
select CPU_HAS_BOOTBLOCK_INIT
|
||||
select HAVE_MONOTONIC_TIMER
|
||||
select GENERIC_UDELAY
|
||||
select HAVE_UART_SPECIAL
|
||||
bool
|
||||
default n
|
||||
|
|
|
@ -10,7 +10,6 @@ bootblock-$(CONFIG_BOOTBLOCK_CONSOLE) += uart.c
|
|||
endif
|
||||
bootblock-y += wakeup.c
|
||||
bootblock-y += gpio.c
|
||||
bootblock-$(CONFIG_BOOTBLOCK_CONSOLE) += timer.c
|
||||
|
||||
romstage-y += spi.c alternate_cbfs.c
|
||||
romstage-y += clock.c
|
||||
|
@ -24,7 +23,6 @@ romstage-y += monotonic_timer.c
|
|||
romstage-$(CONFIG_DRIVERS_UART) += uart.c
|
||||
romstage-y += wakeup.c
|
||||
romstage-y += gpio.c
|
||||
romstage-y += timer.c
|
||||
romstage-y += trustzone.c
|
||||
romstage-y += i2c.c
|
||||
#romstage-y += wdt.c
|
||||
|
@ -40,7 +38,6 @@ ramstage-y += cpu.c
|
|||
ramstage-y += tmu.c
|
||||
ramstage-y += mct.c
|
||||
ramstage-y += monotonic_timer.c
|
||||
ramstage-y += timer.c
|
||||
ramstage-y += gpio.c
|
||||
ramstage-y += i2c.c
|
||||
ramstage-y += dp-reg.c
|
||||
|
|
|
@ -1,52 +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
|
||||
*/
|
||||
|
||||
#include <console/console.h>
|
||||
#include <delay.h>
|
||||
#include <soc/clk.h>
|
||||
#include <timer.h>
|
||||
|
||||
void init_timer(void)
|
||||
{
|
||||
/* Nothing to do because we manually
|
||||
* call mct_start() in the bootblock
|
||||
*/
|
||||
}
|
||||
|
||||
/* delay x useconds */
|
||||
void udelay(unsigned usec)
|
||||
{
|
||||
struct mono_time current, end;
|
||||
|
||||
timer_monotonic_get(¤t);
|
||||
end = current;
|
||||
mono_time_add_usecs(&end, usec);
|
||||
|
||||
if (mono_time_after(¤t, &end)) {
|
||||
printk(BIOS_EMERG, "udelay: 0x%08x is impossibly large\n",
|
||||
usec);
|
||||
/* There's not much we can do if usec is too big. Use a long,
|
||||
* paranoid delay value and hope for the best... */
|
||||
end = current;
|
||||
mono_time_add_usecs(&end, USECS_PER_SEC);
|
||||
}
|
||||
|
||||
while (mono_time_before(¤t, &end))
|
||||
timer_monotonic_get(¤t);
|
||||
}
|
|
@ -5,6 +5,7 @@ config CPU_SAMSUNG_EXYNOS5420
|
|||
select ARCH_RAMSTAGE_ARMV7
|
||||
select CPU_HAS_BOOTBLOCK_INIT
|
||||
select HAVE_MONOTONIC_TIMER
|
||||
select GENERIC_UDELAY
|
||||
select HAVE_UART_SPECIAL
|
||||
select RELOCATABLE_MODULES
|
||||
bool
|
||||
|
|
|
@ -10,7 +10,6 @@ bootblock-$(CONFIG_BOOTBLOCK_CONSOLE) += uart.c
|
|||
endif
|
||||
bootblock-y += wakeup.c
|
||||
bootblock-y += gpio.c
|
||||
bootblock-$(CONFIG_BOOTBLOCK_CONSOLE) += timer.c
|
||||
|
||||
romstage-y += spi.c alternate_cbfs.c
|
||||
romstage-y += smp.c
|
||||
|
@ -25,7 +24,6 @@ romstage-y += monotonic_timer.c
|
|||
romstage-$(CONFIG_DRIVERS_UART) += uart.c
|
||||
romstage-y += wakeup.c
|
||||
romstage-y += gpio.c
|
||||
romstage-y += timer.c
|
||||
romstage-y += i2c.c
|
||||
#romstage-y += wdt.c
|
||||
romstage-y += cbmem.c
|
||||
|
@ -41,7 +39,6 @@ ramstage-y += cpu.c
|
|||
ramstage-y += tmu.c
|
||||
ramstage-y += mct.c
|
||||
ramstage-y += monotonic_timer.c
|
||||
ramstage-y += timer.c
|
||||
ramstage-y += gpio.c
|
||||
ramstage-y += i2c.c
|
||||
ramstage-y += dp.c dp_lowlevel.c fimd.c
|
||||
|
|
|
@ -1,56 +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
|
||||
*/
|
||||
|
||||
#include <console/console.h>
|
||||
#include <delay.h>
|
||||
#include <soc/clk.h>
|
||||
#include <thread.h>
|
||||
#include <timer.h>
|
||||
|
||||
void init_timer(void)
|
||||
{
|
||||
/* Nothing to do because we manually
|
||||
* call mct_start() in the bootblock
|
||||
*/
|
||||
}
|
||||
|
||||
/* delay x useconds */
|
||||
void udelay(unsigned usec)
|
||||
{
|
||||
struct mono_time current, end;
|
||||
|
||||
if (!thread_yield_microseconds(usec))
|
||||
return;
|
||||
|
||||
timer_monotonic_get(¤t);
|
||||
end = current;
|
||||
mono_time_add_usecs(&end, usec);
|
||||
|
||||
if (mono_time_after(¤t, &end)) {
|
||||
printk(BIOS_EMERG, "udelay: 0x%08x is impossibly large\n",
|
||||
usec);
|
||||
/* There's not much we can do if usec is too big. Use a long,
|
||||
* paranoid delay value and hope for the best... */
|
||||
end = current;
|
||||
mono_time_add_usecs(&end, USECS_PER_SEC);
|
||||
}
|
||||
|
||||
while (mono_time_before(¤t, &end))
|
||||
timer_monotonic_get(¤t);
|
||||
}
|
Loading…
Reference in New Issue