diff mbox

[U-Boot,2/3] x86: Allow a hardcoded TSC frequency provided by Kconfig

Message ID 1420296026-8764-3-git-send-email-bmeng.cn@gmail.com
State Superseded
Delegated to: Simon Glass
Headers show

Commit Message

Bin Meng Jan. 3, 2015, 2:40 p.m. UTC
By default U-Boot automatically calibrates TSC running frequency via
MSR and PIT. The calibration may not work on every x86 processor, so
a new Kconfig option CONFIG_TSC_CALIBRATION_BYPASS is introduced to
allow bypassing the calibration and assign a hardcoded TSC frequency
CONFIG_TSC_FREQ_IN_MHZ.

Normally the bypass should be turned on in a simulation environment
like qemu.

Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
---

 arch/x86/Kconfig         | 18 ++++++++++++++++++
 arch/x86/lib/tsc_timer.c |  8 ++++++--
 2 files changed, 24 insertions(+), 2 deletions(-)

Comments

Simon Glass Jan. 4, 2015, 2:31 a.m. UTC | #1
Hi Bin,

On 3 January 2015 at 07:40, Bin Meng <bmeng.cn@gmail.com> wrote:
> By default U-Boot automatically calibrates TSC running frequency via
> MSR and PIT. The calibration may not work on every x86 processor, so
> a new Kconfig option CONFIG_TSC_CALIBRATION_BYPASS is introduced to
> allow bypassing the calibration and assign a hardcoded TSC frequency
> CONFIG_TSC_FREQ_IN_MHZ.
>
> Normally the bypass should be turned on in a simulation environment
> like qemu.
>
> Signed-off-by: Bin Meng <bmeng.cn@gmail.com>

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

But see my optional thoughts below.

> ---
>
>  arch/x86/Kconfig         | 18 ++++++++++++++++++
>  arch/x86/lib/tsc_timer.c |  8 ++++++--
>  2 files changed, 24 insertions(+), 2 deletions(-)
>
> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> index ebf72b3..9c11f0e 100644
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -317,6 +317,24 @@ config FRAMEBUFFER_VESA_MODE
>
>  endmenu
>
> +config TSC_CALIBRATION_BYPASS
> +       bool "Bypass TSC calibration"
> +       default n
> +       help
> +         By default U-Boot automatically calibrates TSC running frequency via
> +         MSR and PIT. If the calibration does not work on your board, select
> +         this option and provide a hardcoded TSC running frequency below.

Do you think TSC, MSR and PIT should be spelled out in the help? I
worry that people won't make much sense of this. For example, if PIT
is Platform Independent Timer we could save 'Platform Independent
Timer (PIT)'.

> +
> +         Normally this option should be turned on in a simulation environment
> +         like qemu.
> +
> +config TSC_FREQ_IN_MHZ
> +       int "TSC running frequency in MHz"
> +       depends on TSC_CALIBRATION_BYPASS
> +       default 1000
> +       help
> +         The running frequency in MHz of TSC
> +
>  source "arch/x86/cpu/ivybridge/Kconfig"
>
>  source "arch/x86/cpu/queensbay/Kconfig"
> diff --git a/arch/x86/lib/tsc_timer.c b/arch/x86/lib/tsc_timer.c
> index fb9afed..7f5ba2c 100644
> --- a/arch/x86/lib/tsc_timer.c
> +++ b/arch/x86/lib/tsc_timer.c
> @@ -78,7 +78,7 @@ static int match_cpu(u8 family, u8 model)
>   *
>   * Returns the calibration value or 0 if MSR calibration failed.
>   */
> -static unsigned long try_msr_calibrate_tsc(void)
> +static unsigned long __maybe_unused try_msr_calibrate_tsc(void)
>  {
>         u32 lo, hi, ratio, freq_id, freq;
>         unsigned long res;
> @@ -199,7 +199,7 @@ static inline int pit_expect_msb(unsigned char val, u64 *tscp,
>  #define MAX_QUICK_PIT_MS 50
>  #define MAX_QUICK_PIT_ITERATIONS (MAX_QUICK_PIT_MS * PIT_TICK_RATE / 1000 / 256)
>
> -static unsigned long quick_pit_calibrate(void)
> +static unsigned long __maybe_unused quick_pit_calibrate(void)
>  {
>         int i;
>         u64 tsc, delta;
> @@ -306,6 +306,9 @@ unsigned __attribute__((no_instrument_function)) long get_tbclk_mhz(void)
>         if (gd->arch.tsc_mhz)
>                 return gd->arch.tsc_mhz;
>
> +#ifdef CONFIG_TSC_CALIBRATION_BYPASS
> +       fast_calibrate = CONFIG_TSC_FREQ_IN_MHZ;
> +#else
>         fast_calibrate = try_msr_calibrate_tsc();
>         if (!fast_calibrate) {
>
> @@ -313,6 +316,7 @@ unsigned __attribute__((no_instrument_function)) long get_tbclk_mhz(void)
>                 if (!fast_calibrate)
>                         panic("TSC frequency is ZERO");
>         }
> +#endif
>
>         gd->arch.tsc_mhz = fast_calibrate;
>         return fast_calibrate;
> --
> 1.8.2.1
>

Regards,
Simon
Bin Meng Jan. 4, 2015, 2:38 a.m. UTC | #2
Hi Simon,

On Sun, Jan 4, 2015 at 10:31 AM, Simon Glass <sjg@chromium.org> wrote:
> Hi Bin,
>
> On 3 January 2015 at 07:40, Bin Meng <bmeng.cn@gmail.com> wrote:
>> By default U-Boot automatically calibrates TSC running frequency via
>> MSR and PIT. The calibration may not work on every x86 processor, so
>> a new Kconfig option CONFIG_TSC_CALIBRATION_BYPASS is introduced to
>> allow bypassing the calibration and assign a hardcoded TSC frequency
>> CONFIG_TSC_FREQ_IN_MHZ.
>>
>> Normally the bypass should be turned on in a simulation environment
>> like qemu.
>>
>> Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
>
> Acked-by: Simon Glass <sjg@chromium.org>
>
> But see my optional thoughts below.
>
>> ---
>>
>>  arch/x86/Kconfig         | 18 ++++++++++++++++++
>>  arch/x86/lib/tsc_timer.c |  8 ++++++--
>>  2 files changed, 24 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
>> index ebf72b3..9c11f0e 100644
>> --- a/arch/x86/Kconfig
>> +++ b/arch/x86/Kconfig
>> @@ -317,6 +317,24 @@ config FRAMEBUFFER_VESA_MODE
>>
>>  endmenu
>>
>> +config TSC_CALIBRATION_BYPASS
>> +       bool "Bypass TSC calibration"
>> +       default n
>> +       help
>> +         By default U-Boot automatically calibrates TSC running frequency via
>> +         MSR and PIT. If the calibration does not work on your board, select
>> +         this option and provide a hardcoded TSC running frequency below.
>
> Do you think TSC, MSR and PIT should be spelled out in the help? I
> worry that people won't make much sense of this. For example, if PIT
> is Platform Independent Timer we could save 'Platform Independent
> Timer (PIT)'.

Yes, a good idea. I can respin a v2 patch.

Regards,
Bin
diff mbox

Patch

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index ebf72b3..9c11f0e 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -317,6 +317,24 @@  config FRAMEBUFFER_VESA_MODE
 
 endmenu
 
+config TSC_CALIBRATION_BYPASS
+	bool "Bypass TSC calibration"
+	default n
+	help
+	  By default U-Boot automatically calibrates TSC running frequency via
+	  MSR and PIT. If the calibration does not work on your board, select
+	  this option and provide a hardcoded TSC running frequency below.
+
+	  Normally this option should be turned on in a simulation environment
+	  like qemu.
+
+config TSC_FREQ_IN_MHZ
+	int "TSC running frequency in MHz"
+	depends on TSC_CALIBRATION_BYPASS
+	default 1000
+	help
+	  The running frequency in MHz of TSC
+
 source "arch/x86/cpu/ivybridge/Kconfig"
 
 source "arch/x86/cpu/queensbay/Kconfig"
diff --git a/arch/x86/lib/tsc_timer.c b/arch/x86/lib/tsc_timer.c
index fb9afed..7f5ba2c 100644
--- a/arch/x86/lib/tsc_timer.c
+++ b/arch/x86/lib/tsc_timer.c
@@ -78,7 +78,7 @@  static int match_cpu(u8 family, u8 model)
  *
  * Returns the calibration value or 0 if MSR calibration failed.
  */
-static unsigned long try_msr_calibrate_tsc(void)
+static unsigned long __maybe_unused try_msr_calibrate_tsc(void)
 {
 	u32 lo, hi, ratio, freq_id, freq;
 	unsigned long res;
@@ -199,7 +199,7 @@  static inline int pit_expect_msb(unsigned char val, u64 *tscp,
 #define MAX_QUICK_PIT_MS 50
 #define MAX_QUICK_PIT_ITERATIONS (MAX_QUICK_PIT_MS * PIT_TICK_RATE / 1000 / 256)
 
-static unsigned long quick_pit_calibrate(void)
+static unsigned long __maybe_unused quick_pit_calibrate(void)
 {
 	int i;
 	u64 tsc, delta;
@@ -306,6 +306,9 @@  unsigned __attribute__((no_instrument_function)) long get_tbclk_mhz(void)
 	if (gd->arch.tsc_mhz)
 		return gd->arch.tsc_mhz;
 
+#ifdef CONFIG_TSC_CALIBRATION_BYPASS
+	fast_calibrate = CONFIG_TSC_FREQ_IN_MHZ;
+#else
 	fast_calibrate = try_msr_calibrate_tsc();
 	if (!fast_calibrate) {
 
@@ -313,6 +316,7 @@  unsigned __attribute__((no_instrument_function)) long get_tbclk_mhz(void)
 		if (!fast_calibrate)
 			panic("TSC frequency is ZERO");
 	}
+#endif
 
 	gd->arch.tsc_mhz = fast_calibrate;
 	return fast_calibrate;