Patrick Rudolph has uploaded this change for review. ( https://review.coreboot.org/23811
Change subject: drivers/arm: Add driver for SP804 timer ......................................................................
drivers/arm: Add driver for SP804 timer
Add a new driver for SP804 timers. Make use of it in mb/emulation/qemu-armv7.
Tested on qemu-system-arm.
Change-Id: I742335014d415e97a20f8b7ccf66e5262a80149d Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com --- A src/drivers/arm/sp804/Kconfig A src/drivers/arm/sp804/Makefile.inc A src/drivers/arm/sp804/sp804.c A src/drivers/arm/sp804/sp804.h M src/mainboard/emulation/qemu-armv7/Kconfig M src/mainboard/emulation/qemu-armv7/mmio.c M src/mainboard/emulation/qemu-armv7/timer.c 7 files changed, 126 insertions(+), 7 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/11/23811/1
diff --git a/src/drivers/arm/sp804/Kconfig b/src/drivers/arm/sp804/Kconfig new file mode 100644 index 0000000..17d3c87 --- /dev/null +++ b/src/drivers/arm/sp804/Kconfig @@ -0,0 +1,4 @@ +config DRIVERS_ARM_SP804 + bool + default n + select HAVE_MONOTONIC_TIMER diff --git a/src/drivers/arm/sp804/Makefile.inc b/src/drivers/arm/sp804/Makefile.inc new file mode 100644 index 0000000..56bb97f --- /dev/null +++ b/src/drivers/arm/sp804/Makefile.inc @@ -0,0 +1,4 @@ +bootblock-$(CONFIG_DRIVERS_ARM_SP804) += sp804.c +ramstage-$(CONFIG_DRIVERS_ARM_SP804) += sp804.c +romstage-$(CONFIG_DRIVERS_ARM_SP804) += sp804.c +verstage-$(CONFIG_DRIVERS_ARM_SP804) += sp804.c diff --git a/src/drivers/arm/sp804/sp804.c b/src/drivers/arm/sp804/sp804.c new file mode 100644 index 0000000..ed0dcc6 --- /dev/null +++ b/src/drivers/arm/sp804/sp804.c @@ -0,0 +1,67 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2018-present Facebook, 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 or, at your option, any later + * version 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. + */ +#include <types.h> +#include <drivers/arm/sp804/sp804.h> +#include <arch/io.h> +#include <stdint.h> + +union sp804_timer_control { + u8 u; + struct { + u8 oneshot : 1; + u8 mode32bit : 1; + u8 div : 2; + u8 : 1; + u8 ie : 1; + u8 periodic : 1; + u8 enable : 1; + } s; +}; + +struct sp804_timer { + u32 load; + u32 value; + union sp804_timer_control control; +}; + +void sp804_init(const size_t idx) +{ + struct sp804_timer *regs = (void *)timer_platform_baseptr(idx); + union sp804_timer_control control; + + control.u = 0; + write32(®s->control, control.u); + + /* Counter decrements, initialize with max. value */ + write32(®s->load, UINT32_MAX); + write32(®s->value, UINT32_MAX); + + /* Enable 32bit mode, no prescaler */ + control.s.mode32bit = 1; + control.s.div = 0; + control.s.enable = 1; + write32(®s->control, control.u); + +} + +u32 sp804_timer_raw_value(const size_t idx) +{ + struct sp804_timer *regs = + (void *)timer_platform_baseptr(idx); + + /* Counter decrements, need to subtract initial value */ + return UINT32_MAX - read32(®s->value); +} diff --git a/src/drivers/arm/sp804/sp804.h b/src/drivers/arm/sp804/sp804.h new file mode 100644 index 0000000..0625a4a --- /dev/null +++ b/src/drivers/arm/sp804/sp804.h @@ -0,0 +1,25 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2018-present Facebook, 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 or, at your option, any later + * version 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. + */ +#include <types.h> + +#ifndef ARM_SP804_TABLES_H +#define ARM_SP804_TABLES_H + +void sp804_init(const size_t idx); +uintptr_t timer_platform_baseptr(const size_t idx); +u32 sp804_timer_raw_value(const size_t idx); + +#endif diff --git a/src/mainboard/emulation/qemu-armv7/Kconfig b/src/mainboard/emulation/qemu-armv7/Kconfig index 74e0163..bdd3189 100644 --- a/src/mainboard/emulation/qemu-armv7/Kconfig +++ b/src/mainboard/emulation/qemu-armv7/Kconfig @@ -35,6 +35,8 @@ select ARCH_RAMSTAGE_ARMV7 select BOARD_ROMSIZE_KB_4096 select BOOT_DEVICE_NOT_SPI_FLASH + select DRIVERS_ARM_SP804 + select GENERIC_UDELAY
config MAINBOARD_DIR string diff --git a/src/mainboard/emulation/qemu-armv7/mmio.c b/src/mainboard/emulation/qemu-armv7/mmio.c index 00a20a2..9981c15 100644 --- a/src/mainboard/emulation/qemu-armv7/mmio.c +++ b/src/mainboard/emulation/qemu-armv7/mmio.c @@ -12,10 +12,23 @@ */
#include <console/uart.h> +#include <drivers/arm/sp804/sp804.h>
#define VEXPRESS_UART0_IO_ADDRESS (0x10009000) +#define VEXPRESS_TIMER01 (0x10011000)
uintptr_t uart_platform_base(int idx) { - return VEXPRESS_UART0_IO_ADDRESS; + if (idx == 0) + return VEXPRESS_UART0_IO_ADDRESS; + + return 0; +} + +uintptr_t timer_platform_baseptr(const size_t idx) +{ + if (idx == 0) + return VEXPRESS_TIMER01; + + return 0; } diff --git a/src/mainboard/emulation/qemu-armv7/timer.c b/src/mainboard/emulation/qemu-armv7/timer.c index b479d42..8163200 100644 --- a/src/mainboard/emulation/qemu-armv7/timer.c +++ b/src/mainboard/emulation/qemu-armv7/timer.c @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2013 Google, Inc. + * Copyright 2018-present Facebook, Inc. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -13,14 +14,17 @@ * GNU General Public License for more details. */
-void udelay(unsigned int n); -void udelay(unsigned int n) +#include <drivers/arm/sp804/sp804.h> +#include <delay.h> +#include <timer.h> + +void init_timer(void) { - /* TODO provide delay here. */ + sp804_init(0); }
-int init_timer(void); -int init_timer(void) +void timer_monotonic_get(struct mono_time *mt) { - return 0; + /* QEMU's timer runs at 1MHz, no need to change the raw value */ + mono_time_set_usecs(mt, sp804_timer_raw_value(0)); }