All of lore.kernel.org
 help / color / mirror / Atom feed
From: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v2 08/19] rockchip: timer: implement timer_get_boot_us
Date: Mon, 11 Sep 2017 11:18:14 +0200	[thread overview]
Message-ID: <1505121512-23283-9-git-send-email-philipp.tomsich@theobroma-systems.com> (raw)
In-Reply-To: <1505121512-23283-1-git-send-email-philipp.tomsich@theobroma-systems.com>

To make the Rockchip DM timer driver useful for the timing of
bootstages, we need a few enhancements:
 - This implements timer_get_boot_us.
 - This avoids reinitialising the timer, if it has already been
   set up (e.g. by our TPL and SPL stages). Now, we have a single
   timebase ticking from TPL through the full U-Boot.
 - This adds support for reading the timer even before the
   device-model is ready: we find the timer via /chosen/tick-timer,
   then read its address and clock-frequency, and finally read the
   timeval directly).

Signed-off-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Acked-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
---

Changes in v2: None

 drivers/timer/rockchip_timer.c | 72 +++++++++++++++++++++++++++++++++++++++---
 1 file changed, 67 insertions(+), 5 deletions(-)

diff --git a/drivers/timer/rockchip_timer.c b/drivers/timer/rockchip_timer.c
index cd349ca..b19aaed 100644
--- a/drivers/timer/rockchip_timer.c
+++ b/drivers/timer/rockchip_timer.c
@@ -6,6 +6,7 @@
 
 #include <common.h>
 #include <dm.h>
+#include <dm/ofnode.h>
 #include <mapmem.h>
 #include <asm/arch/timer.h>
 #include <dt-structs.h>
@@ -25,17 +26,72 @@ struct rockchip_timer_priv {
 	struct rk_timer *timer;
 };
 
-static int rockchip_timer_get_count(struct udevice *dev, u64 *count)
+static inline int64_t rockchip_timer_get_curr_value(struct rk_timer *timer)
 {
-	struct rockchip_timer_priv *priv = dev_get_priv(dev);
 	uint64_t timebase_h, timebase_l;
 	uint64_t cntr;
 
-	timebase_l = readl(&priv->timer->timer_curr_value0);
-	timebase_h = readl(&priv->timer->timer_curr_value1);
+	timebase_l = readl(&timer->timer_curr_value0);
+	timebase_h = readl(&timer->timer_curr_value1);
 
-	/* timers are down-counting */
 	cntr = timebase_h << 32 | timebase_l;
+	return cntr;
+}
+
+#if CONFIG_IS_ENABLED(BOOTSTAGE)
+ulong timer_get_boot_us(void)
+{
+	uint64_t  ticks = 0;
+	uint32_t  rate;
+	uint64_t  us;
+	int ret;
+
+	ret = dm_timer_init();
+
+	if (!ret) {
+		/* The timer is available */
+		rate = timer_get_rate(gd->timer);
+		timer_get_count(gd->timer, &ticks);
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
+	} else if (ret == -EAGAIN) {
+		/* We have been called so early that the DM is not ready,... */
+		ofnode node = offset_to_ofnode(-1);
+		struct rk_timer *timer = NULL;
+
+		/*
+		 * ... so we try to access the raw timer, if it is specified
+		 * via the tick-timer property in /chosen.
+		 */
+		node = ofnode_get_chosen_node("tick-timer");
+		if (!ofnode_valid(node)) {
+			debug("%s: no /chosen/tick-timer\n", __func__);
+			return 0;
+		}
+
+		timer = (struct rk_timer *)ofnode_get_addr(node);
+
+		/* This timer is down-counting */
+		ticks = ~0uLL - rockchip_timer_get_curr_value(timer);
+		if (ofnode_read_u32(node, "clock-frequency", &rate)) {
+			debug("%s: could not read clock-frequency\n", __func__);
+			return 0;
+		}
+#endif
+	} else {
+		return 0;
+	}
+
+	us = (ticks * 1000) / rate;
+	return us;
+}
+#endif
+
+static int rockchip_timer_get_count(struct udevice *dev, u64 *count)
+{
+	struct rockchip_timer_priv *priv = dev_get_priv(dev);
+	uint64_t cntr = rockchip_timer_get_curr_value(priv->timer);
+
+	/* timers are down-counting */
 	*count = ~0ull - cntr;
 	return 0;
 }
@@ -58,6 +114,12 @@ static int rockchip_timer_start(struct udevice *dev)
 	const uint32_t reload_val_l = reload_val & 0xffffffff;
 	const uint32_t reload_val_h = reload_val >> 32;
 
+	/* don't reinit, if the timer is already running and set up */
+	if ((readl(&priv->timer->timer_ctrl_reg) & 1) == 1 &&
+	    (readl(&priv->timer->timer_load_count0) == reload_val_l) &&
+	    (readl(&priv->timer->timer_load_count1) == reload_val_h))
+		return 0;
+
 	/* disable timer and reset all control */
 	writel(0, &priv->timer->timer_ctrl_reg);
 	/* write reload value */
-- 
2.1.4

  parent reply	other threads:[~2017-09-11  9:18 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-09-11  9:18 [U-Boot] [PATCH v2 00/19] rockchip: convert the RK3368 to OF_LIVE and validate on the RK3368-uQ7 Philipp Tomsich
2017-09-11  9:18 ` [U-Boot] [PATCH v2 01/19] bootstage: adjust Makefile to allow including bootstage in SPL, but not in TPL Philipp Tomsich
2017-09-11  9:18 ` [U-Boot] [PATCH v2 02/19] dm: timer: Convert to livetree Philipp Tomsich
2017-09-11  9:18 ` [U-Boot] [PATCH v2 03/19] dm: timer: handle being called before dm_root is ready Philipp Tomsich
2017-09-11  9:18 ` [U-Boot] [PATCH v2 04/19] dm: core: add dev_read_addr_ptr() Philipp Tomsich
2017-09-12  2:44   ` Simon Glass
2017-09-11  9:18 ` [U-Boot] [PATCH v2 05/19] net: designware: Convert to livetree Philipp Tomsich
2017-09-11  9:18 ` [U-Boot] [PATCH v2 06/19] net: phy: micrel: " Philipp Tomsich
2017-09-11 19:34   ` Joe Hershberger
2017-09-11 19:54     ` Dr. Philipp Tomsich
2017-09-11  9:18 ` [U-Boot] [PATCH v2 07/19] rockchip: mmc: convert " Philipp Tomsich
2017-09-11  9:18 ` Philipp Tomsich [this message]
2017-09-11  9:18 ` [U-Boot] [PATCH v2 09/19] rockchip: timer: Convert " Philipp Tomsich
2017-09-11  9:18 ` [U-Boot] [PATCH v2 10/19] rockchip: clk: rk3368: " Philipp Tomsich
2017-09-11  9:18 ` [U-Boot] [PATCH v2 11/19] rockchip: pinctrl: " Philipp Tomsich
2017-09-11  9:18 ` [U-Boot] [PATCH v2 12/19] rockchip: spi: " Philipp Tomsich
2017-09-11  9:32   ` Jagan Teki
2017-09-11  9:18 ` [U-Boot] [PATCH v2 13/19] rockchip: sdhci: " Philipp Tomsich
2017-09-11  9:18 ` [U-Boot] [PATCH v2 14/19] rockchip: rk8xx: remove unused header includes Philipp Tomsich
2017-09-11  9:18 ` [U-Boot] [PATCH v2 15/19] rockchip: i2c: Convert to livetree Philipp Tomsich
2017-09-11 11:29   ` Heiko Schocher
2017-09-13  2:31   ` Simon Glass
2017-09-11  9:18 ` [U-Boot] [PATCH v2 16/19] rockchip: gpio: convert " Philipp Tomsich
2017-09-11  9:18 ` [U-Boot] [PATCH v2 17/19] rockchip: gpio: remove outdated/misleading comment Philipp Tomsich
2017-09-11  9:18 ` [U-Boot] [PATCH v2 18/19] rockchip: dts: rk3368-lion: add /chosen/tick-timer Philipp Tomsich
2017-09-11  9:18 ` [U-Boot] [PATCH v2 19/19] rockchip: lion-rk3368: defconfig: resync w/ OF_LIVE and BOOTSTAGE enabled Philipp Tomsich

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1505121512-23283-9-git-send-email-philipp.tomsich@theobroma-systems.com \
    --to=philipp.tomsich@theobroma-systems.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.