summaryrefslogtreecommitdiff
path: root/drivers/timer
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2017-09-06 04:49:46 +0300
committerBin Meng <bmeng.cn@gmail.com>2017-09-16 09:57:44 +0300
commit2ff50f5fa4009adf5e23a69a4269e6bb054edd79 (patch)
tree9272443ed20aae4ffbdbfee71edfc24926cf18c4 /drivers/timer
parent5ee94b4f4032502c26cd3c9ede6a910d7e2c9b46 (diff)
downloadu-boot-2ff50f5fa4009adf5e23a69a4269e6bb054edd79.tar.xz
dm: x86: Allow TSC timer to be used before DM is ready
With bootstage we need access to the timer before driver model is set up. To handle this, put the required state in global_data and provide a new function to set up the device, separate from the driver's probe() method. This will be used by the 'early' timer also. Signed-off-by: Simon Glass <sjg@chromium.org> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Diffstat (limited to 'drivers/timer')
-rw-r--r--drivers/timer/tsc_timer.c30
1 files changed, 25 insertions, 5 deletions
diff --git a/drivers/timer/tsc_timer.c b/drivers/timer/tsc_timer.c
index 77040afafe..9296de6543 100644
--- a/drivers/timer/tsc_timer.c
+++ b/drivers/timer/tsc_timer.c
@@ -331,17 +331,17 @@ static int tsc_timer_get_count(struct udevice *dev, u64 *count)
return 0;
}
-static int tsc_timer_probe(struct udevice *dev)
+static void tsc_timer_ensure_setup(void)
{
- struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
-
+ if (gd->arch.tsc_base)
+ return;
gd->arch.tsc_base = rdtsc();
/*
* If there is no clock frequency specified in the device tree,
* calibrate it by ourselves.
*/
- if (!uc_priv->clock_rate) {
+ if (!gd->arch.clock_rate) {
unsigned long fast_calibrate;
fast_calibrate = cpu_mhz_from_msr();
@@ -351,12 +351,32 @@ static int tsc_timer_probe(struct udevice *dev)
panic("TSC frequency is ZERO");
}
- uc_priv->clock_rate = fast_calibrate * 1000000;
+ gd->arch.clock_rate = fast_calibrate * 1000000;
}
+}
+
+static int tsc_timer_probe(struct udevice *dev)
+{
+ struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+
+ tsc_timer_ensure_setup();
+ uc_priv->clock_rate = gd->arch.clock_rate;
return 0;
}
+unsigned long notrace timer_early_get_rate(void)
+{
+ tsc_timer_ensure_setup();
+
+ return gd->arch.clock_rate;
+}
+
+u64 notrace timer_early_get_count(void)
+{
+ return rdtsc() - gd->arch.tsc_base;
+}
+
static const struct timer_ops tsc_timer_ops = {
.get_count = tsc_timer_get_count,
};