[U-Boot] [PATCH 4/6] x86: tsc: Try hardware calibration first

Bin Meng bmeng.cn at gmail.com
Tue Aug 14 07:07:47 UTC 2018


Hi Christian,

On Tue, Aug 14, 2018 at 2:54 PM, Christian Gmeiner
<christian.gmeiner at gmail.com> wrote:
> Am Fr., 10. Aug. 2018 um 11:40 Uhr schrieb Bin Meng <bmeng.cn at gmail.com>:
>>
>> At present if TSC frequency is provided in the device tree, it takes
>> precedence over hardware calibration result. This swaps the order to
>> try hardware calibration first and uses device tree as last resort.
>>
>> This can be helpful when a generic dts (eg: coreboot/efi payload) is
>> supposed to work on as many hardware as possible, including emulators
>> like QEMU where TSC hardware calibration sometimes fails.
>>
>> Signed-off-by: Bin Meng <bmeng.cn at gmail.com>
>> ---
>>
>>  drivers/timer/tsc_timer.c | 27 ++++++++++++++++-----------
>>  1 file changed, 16 insertions(+), 11 deletions(-)
>>
>> diff --git a/drivers/timer/tsc_timer.c b/drivers/timer/tsc_timer.c
>> index 747f190..6473de2 100644
>> --- a/drivers/timer/tsc_timer.c
>> +++ b/drivers/timer/tsc_timer.c
>> @@ -341,16 +341,12 @@ static int tsc_timer_get_count(struct udevice *dev, u64 *count)
>>         return 0;
>>  }
>>
>> -static void tsc_timer_ensure_setup(void)
>> +static void tsc_timer_ensure_setup(bool stop)
>>  {
>>         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 (!gd->arch.clock_rate) {
>>                 unsigned long fast_calibrate;
>>
>> @@ -366,7 +362,10 @@ static void tsc_timer_ensure_setup(void)
>>                 if (fast_calibrate)
>>                         goto done;
>>
>> -               panic("TSC frequency is ZERO");
>> +               if (stop)
>> +                       panic("TSC frequency is ZERO");
>> +               else
>> +                       return;
>>
>>  done:
>>                 gd->arch.clock_rate = fast_calibrate * 1000000;
>> @@ -377,11 +376,17 @@ static int tsc_timer_probe(struct udevice *dev)
>>  {
>>         struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
>>
>> -       if (!uc_priv->clock_rate) {
>> -               tsc_timer_ensure_setup();
>> -               uc_priv->clock_rate = gd->arch.clock_rate;
>> +       /* Try hardware calibration first */
>> +       tsc_timer_ensure_setup(false);
>> +       if (!gd->arch.clock_rate) {
>> +               /*
>> +                * Use the clock frequency specified in the
>> +                * device tree as last resort
>> +                */
>> +               if (!uc_priv->clock_rate)
>
> Where gets uc_priv->clock_rate set to something? DM should set zero-out
> the whole uc_priv thing when bind/probe - or?
>

uc_priv->clock_rate is set in timer_pre_probe()

>
>> +                       panic("TSC frequency is ZERO");
>>         } else {
>> -               gd->arch.tsc_base = rdtsc();
>> +               uc_priv->clock_rate = gd->arch.clock_rate;
>>         }
>>
>>         return 0;
>> @@ -394,7 +399,7 @@ unsigned long notrace timer_early_get_rate(void)
>>          * clock rate can only be calibrated via some hardware ways. Specifying
>>          * it in the device tree won't work for the early timer.
>>          */
>> -       tsc_timer_ensure_setup();
>> +       tsc_timer_ensure_setup(true);
>>
>>         return gd->arch.clock_rate;
>>  }
>> --

Regards,
Bin


More information about the U-Boot mailing list