diff mbox

[U-Boot,2/5] dm: x86: Allow TSC timer to be used before DM is ready

Message ID 20170715234120.177264-3-sjg@chromium.org
State Superseded
Delegated to: Tom Rini
Headers show

Commit Message

Simon Glass July 15, 2017, 11:41 p.m. UTC
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.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 arch/x86/include/asm/global_data.h |  1 +
 drivers/timer/tsc_timer.c          | 18 +++++++++++++-----
 2 files changed, 14 insertions(+), 5 deletions(-)

Comments

Bin Meng July 23, 2017, 4:36 a.m. UTC | #1
Hi Simon,

On Sun, Jul 16, 2017 at 7:41 AM, Simon Glass <sjg@chromium.org> wrote:
> 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.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
>  arch/x86/include/asm/global_data.h |  1 +
>  drivers/timer/tsc_timer.c          | 18 +++++++++++++-----
>  2 files changed, 14 insertions(+), 5 deletions(-)
>

Please check my comments against [1/5] in this series. We should be
able to do something with existing CONFIG_TIMER_EARLY. Updating TSC
timer can only solve this specific timer issue.

Regards,
Bin
Simon Glass Aug. 2, 2017, 6:08 p.m. UTC | #2
Hi Bin,

On 22 July 2017 at 22:36, Bin Meng <bmeng.cn@gmail.com> wrote:
> Hi Simon,
>
> On Sun, Jul 16, 2017 at 7:41 AM, Simon Glass <sjg@chromium.org> wrote:
>> 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.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> ---
>>
>>  arch/x86/include/asm/global_data.h |  1 +
>>  drivers/timer/tsc_timer.c          | 18 +++++++++++++-----
>>  2 files changed, 14 insertions(+), 5 deletions(-)
>>
>
> Please check my comments against [1/5] in this series. We should be
> able to do something with existing CONFIG_TIMER_EARLY. Updating TSC
> timer can only solve this specific timer issue.

Yes I agree. I did wonder about that at the time, but didn't investigate it.

I'll take a look at this next week when I have access to a link.

Regards,
Simon
diff mbox

Patch

diff --git a/arch/x86/include/asm/global_data.h b/arch/x86/include/asm/global_data.h
index 93a80fe2b6..fcb6853a38 100644
--- a/arch/x86/include/asm/global_data.h
+++ b/arch/x86/include/asm/global_data.h
@@ -77,6 +77,7 @@  struct arch_global_data {
 	uint8_t x86_mask;
 	uint32_t x86_device;
 	uint64_t tsc_base;		/* Initial value returned by rdtsc() */
+	unsigned long clock_rate;	/* Clock rate of timer in Hz */
 	void *new_fdt;			/* Relocated FDT */
 	uint32_t bist;			/* Built-in self test value */
 	enum pei_boot_mode_t pei_boot_mode;
diff --git a/drivers/timer/tsc_timer.c b/drivers/timer/tsc_timer.c
index 5c4ec0018f..9f1cfb1242 100644
--- a/drivers/timer/tsc_timer.c
+++ b/drivers/timer/tsc_timer.c
@@ -334,17 +334,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 = try_msr_calibrate_tsc();
@@ -354,8 +354,16 @@  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;
 }