aboutsummaryrefslogtreecommitdiff
path: root/core/timebase.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2014-07-02 15:36:20 +1000
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2014-07-02 15:36:20 +1000
commit1d880992fd8c8457a2d990ac6622cfd58fb1b261 (patch)
treec4c843b12e96b5612c315db5a23c5da1a900618c /core/timebase.c
downloadskiboot-1d880992fd8c8457a2d990ac6622cfd58fb1b261.zip
skiboot-1d880992fd8c8457a2d990ac6622cfd58fb1b261.tar.gz
skiboot-1d880992fd8c8457a2d990ac6622cfd58fb1b261.tar.bz2
Initial commit of Open Source release
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'core/timebase.c')
-rw-r--r--core/timebase.c67
1 files changed, 67 insertions, 0 deletions
diff --git a/core/timebase.c b/core/timebase.c
new file mode 100644
index 0000000..d51e96b
--- /dev/null
+++ b/core/timebase.c
@@ -0,0 +1,67 @@
+/* Copyright 2013-2014 IBM Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <timebase.h>
+#include <fsp.h>
+
+void time_wait(unsigned long duration)
+{
+ unsigned long end = mftb() + duration;
+
+ while(tb_compare(mftb(), end) != TB_AAFTERB)
+ fsp_poll();
+}
+
+void time_wait_ms(unsigned long ms)
+{
+ time_wait(msecs_to_tb(ms));
+}
+
+void time_wait_us(unsigned long us)
+{
+ time_wait(usecs_to_tb(us));
+}
+
+unsigned long timespec_to_tb(const struct timespec *ts)
+{
+ unsigned long ns;
+
+ /* First convert to ns */
+ ns = ts->tv_sec * 1000000000ul;
+ ns += ts->tv_nsec;
+
+ /*
+ * This is a very rough approximation, it works provided
+ * we never try to pass too long delays here and the TB
+ * frequency isn't significantly lower than 512Mhz.
+ *
+ * We could improve the precision by shifting less bits
+ * at the expense of capacity or do 128 bit math which
+ * I'm not eager to do :-)
+ */
+ return (ns * (tb_hz >> 24)) / (1000000000ul >> 24);
+}
+
+int nanosleep(const struct timespec *req, struct timespec *rem)
+{
+ time_wait(timespec_to_tb(req));
+
+ if (rem) {
+ rem->tv_sec = 0;
+ rem->tv_nsec = 0;
+ }
+ return 0;
+}