<p>Patrick Rudolph has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/23811">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">drivers/arm: Add driver for SP804 timer<br><br>Add a new driver for SP804 timers.<br>Make use of it in mb/emulation/qemu-armv7.<br><br>Tested on qemu-system-arm.<br><br>Change-Id: I742335014d415e97a20f8b7ccf66e5262a80149d<br>Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com><br>---<br>A src/drivers/arm/sp804/Kconfig<br>A src/drivers/arm/sp804/Makefile.inc<br>A src/drivers/arm/sp804/sp804.c<br>A src/drivers/arm/sp804/sp804.h<br>M src/mainboard/emulation/qemu-armv7/Kconfig<br>M src/mainboard/emulation/qemu-armv7/mmio.c<br>M src/mainboard/emulation/qemu-armv7/timer.c<br>7 files changed, 126 insertions(+), 7 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/11/23811/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/drivers/arm/sp804/Kconfig b/src/drivers/arm/sp804/Kconfig</span><br><span>new file mode 100644</span><br><span>index 0000000..17d3c87</span><br><span>--- /dev/null</span><br><span>+++ b/src/drivers/arm/sp804/Kconfig</span><br><span>@@ -0,0 +1,4 @@</span><br><span style="color: hsl(120, 100%, 40%);">+config DRIVERS_ARM_SP804</span><br><span style="color: hsl(120, 100%, 40%);">+       bool</span><br><span style="color: hsl(120, 100%, 40%);">+  default n</span><br><span style="color: hsl(120, 100%, 40%);">+     select HAVE_MONOTONIC_TIMER</span><br><span>diff --git a/src/drivers/arm/sp804/Makefile.inc b/src/drivers/arm/sp804/Makefile.inc</span><br><span>new file mode 100644</span><br><span>index 0000000..56bb97f</span><br><span>--- /dev/null</span><br><span>+++ b/src/drivers/arm/sp804/Makefile.inc</span><br><span>@@ -0,0 +1,4 @@</span><br><span style="color: hsl(120, 100%, 40%);">+bootblock-$(CONFIG_DRIVERS_ARM_SP804) += sp804.c</span><br><span style="color: hsl(120, 100%, 40%);">+ramstage-$(CONFIG_DRIVERS_ARM_SP804) += sp804.c</span><br><span style="color: hsl(120, 100%, 40%);">+romstage-$(CONFIG_DRIVERS_ARM_SP804) += sp804.c</span><br><span style="color: hsl(120, 100%, 40%);">+verstage-$(CONFIG_DRIVERS_ARM_SP804) += sp804.c</span><br><span>diff --git a/src/drivers/arm/sp804/sp804.c b/src/drivers/arm/sp804/sp804.c</span><br><span>new file mode 100644</span><br><span>index 0000000..ed0dcc6</span><br><span>--- /dev/null</span><br><span>+++ b/src/drivers/arm/sp804/sp804.c</span><br><span>@@ -0,0 +1,67 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * This file is part of the coreboot project.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright 2018-present  Facebook, Inc.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; version 2 or, at your option, any later</span><br><span style="color: hsl(120, 100%, 40%);">+ * version of the License.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+#include <types.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <drivers/arm/sp804/sp804.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <arch/io.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+union sp804_timer_control {</span><br><span style="color: hsl(120, 100%, 40%);">+       u8 u;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct {</span><br><span style="color: hsl(120, 100%, 40%);">+              u8 oneshot :    1;</span><br><span style="color: hsl(120, 100%, 40%);">+            u8 mode32bit :  1;</span><br><span style="color: hsl(120, 100%, 40%);">+            u8 div :        2;</span><br><span style="color: hsl(120, 100%, 40%);">+            u8 :            1;</span><br><span style="color: hsl(120, 100%, 40%);">+            u8 ie :         1;</span><br><span style="color: hsl(120, 100%, 40%);">+            u8 periodic :   1;</span><br><span style="color: hsl(120, 100%, 40%);">+            u8 enable :     1;</span><br><span style="color: hsl(120, 100%, 40%);">+    } s;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct sp804_timer {</span><br><span style="color: hsl(120, 100%, 40%);">+      u32 load;</span><br><span style="color: hsl(120, 100%, 40%);">+     u32 value;</span><br><span style="color: hsl(120, 100%, 40%);">+    union sp804_timer_control control;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void sp804_init(const size_t idx)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        struct sp804_timer *regs = (void *)timer_platform_baseptr(idx);</span><br><span style="color: hsl(120, 100%, 40%);">+       union sp804_timer_control control;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  control.u = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+        write32(&regs->control, control.u);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Counter decrements, initialize with max. value */</span><br><span style="color: hsl(120, 100%, 40%);">+  write32(&regs->load, UINT32_MAX);</span><br><span style="color: hsl(120, 100%, 40%);">+      write32(&regs->value, UINT32_MAX);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Enable 32bit mode, no prescaler */</span><br><span style="color: hsl(120, 100%, 40%);">+ control.s.mode32bit = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+      control.s.div = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+    control.s.enable = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ write32(&regs->control, control.u);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+u32 sp804_timer_raw_value(const size_t idx)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     struct sp804_timer *regs =</span><br><span style="color: hsl(120, 100%, 40%);">+        (void *)timer_platform_baseptr(idx);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Counter decrements, need to subtract initial value */</span><br><span style="color: hsl(120, 100%, 40%);">+      return UINT32_MAX - read32(&regs->value);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/src/drivers/arm/sp804/sp804.h b/src/drivers/arm/sp804/sp804.h</span><br><span>new file mode 100644</span><br><span>index 0000000..0625a4a</span><br><span>--- /dev/null</span><br><span>+++ b/src/drivers/arm/sp804/sp804.h</span><br><span>@@ -0,0 +1,25 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * This file is part of the coreboot project.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright 2018-present  Facebook, Inc.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; version 2 or, at your option, any later</span><br><span style="color: hsl(120, 100%, 40%);">+ * version of the License.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+#include <types.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#ifndef ARM_SP804_TABLES_H</span><br><span style="color: hsl(120, 100%, 40%);">+#define ARM_SP804_TABLES_H</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void sp804_init(const size_t idx);</span><br><span style="color: hsl(120, 100%, 40%);">+uintptr_t timer_platform_baseptr(const size_t idx);</span><br><span style="color: hsl(120, 100%, 40%);">+u32 sp804_timer_raw_value(const size_t idx);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span>diff --git a/src/mainboard/emulation/qemu-armv7/Kconfig b/src/mainboard/emulation/qemu-armv7/Kconfig</span><br><span>index 74e0163..bdd3189 100644</span><br><span>--- a/src/mainboard/emulation/qemu-armv7/Kconfig</span><br><span>+++ b/src/mainboard/emulation/qemu-armv7/Kconfig</span><br><span>@@ -35,6 +35,8 @@</span><br><span>   select ARCH_RAMSTAGE_ARMV7</span><br><span>   select BOARD_ROMSIZE_KB_4096</span><br><span>         select BOOT_DEVICE_NOT_SPI_FLASH</span><br><span style="color: hsl(120, 100%, 40%);">+      select DRIVERS_ARM_SP804</span><br><span style="color: hsl(120, 100%, 40%);">+      select GENERIC_UDELAY</span><br><span> </span><br><span> config MAINBOARD_DIR</span><br><span>    string</span><br><span>diff --git a/src/mainboard/emulation/qemu-armv7/mmio.c b/src/mainboard/emulation/qemu-armv7/mmio.c</span><br><span>index 00a20a2..9981c15 100644</span><br><span>--- a/src/mainboard/emulation/qemu-armv7/mmio.c</span><br><span>+++ b/src/mainboard/emulation/qemu-armv7/mmio.c</span><br><span>@@ -12,10 +12,23 @@</span><br><span>  */</span><br><span> </span><br><span> #include <console/uart.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <drivers/arm/sp804/sp804.h></span><br><span> </span><br><span> #define VEXPRESS_UART0_IO_ADDRESS      (0x10009000)</span><br><span style="color: hsl(120, 100%, 40%);">+#define VEXPRESS_TIMER01               (0x10011000)</span><br><span> </span><br><span> uintptr_t uart_platform_base(int idx)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-       return VEXPRESS_UART0_IO_ADDRESS;</span><br><span style="color: hsl(120, 100%, 40%);">+     if (idx == 0)</span><br><span style="color: hsl(120, 100%, 40%);">+         return VEXPRESS_UART0_IO_ADDRESS;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+uintptr_t timer_platform_baseptr(const size_t idx)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ if (idx == 0)</span><br><span style="color: hsl(120, 100%, 40%);">+         return VEXPRESS_TIMER01;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    return 0;</span><br><span> }</span><br><span>diff --git a/src/mainboard/emulation/qemu-armv7/timer.c b/src/mainboard/emulation/qemu-armv7/timer.c</span><br><span>index b479d42..8163200 100644</span><br><span>--- a/src/mainboard/emulation/qemu-armv7/timer.c</span><br><span>+++ b/src/mainboard/emulation/qemu-armv7/timer.c</span><br><span>@@ -2,6 +2,7 @@</span><br><span>  * This file is part of the coreboot project.</span><br><span>  *</span><br><span>  * Copyright (C) 2013 Google, Inc.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright 2018-present  Facebook, Inc.</span><br><span>  *</span><br><span>  * This software is licensed under the terms of the GNU General Public</span><br><span>  * License version 2, as published by the Free Software Foundation, and</span><br><span>@@ -13,14 +14,17 @@</span><br><span>  * GNU General Public License for more details.</span><br><span>  */</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-void udelay(unsigned int n);</span><br><span style="color: hsl(0, 100%, 40%);">-void udelay(unsigned int n)</span><br><span style="color: hsl(120, 100%, 40%);">+#include <drivers/arm/sp804/sp804.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <delay.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <timer.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void init_timer(void)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-       /* TODO provide delay here. */</span><br><span style="color: hsl(120, 100%, 40%);">+        sp804_init(0);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int init_timer(void);</span><br><span style="color: hsl(0, 100%, 40%);">-int init_timer(void)</span><br><span style="color: hsl(120, 100%, 40%);">+void timer_monotonic_get(struct mono_time *mt)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     /* QEMU's timer runs at 1MHz, no need to change the raw value */</span><br><span style="color: hsl(120, 100%, 40%);">+  mono_time_set_usecs(mt, sp804_timer_raw_value(0));</span><br><span> }</span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/23811">change 23811</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://review.coreboot.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://review.coreboot.org/23811"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I742335014d415e97a20f8b7ccf66e5262a80149d </div>
<div style="display:none"> Gerrit-Change-Number: 23811 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Patrick Rudolph <patrick.rudolph@9elements.com> </div>