All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ivan Gorinov <ivan.gorinov@intel.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v6 1/2] x86: Add TSC-specific timer functions
Date: Mon, 23 Apr 2018 16:56:16 -0700	[thread overview]
Message-ID: <20180423235616.GA17404@intel.com> (raw)
In-Reply-To: <CAEUhbmUup2OBEbSMdYzg7Ui-QABqC7ZHd____Aa1qLcZOzMUeA@mail.gmail.com>

Hi Bin,

On Mon, Apr 23, 2018 at 01:38:05AM -0600, Bin Meng wrote:
> > Coreboot timestamp functions and Quark memory reference code use
> > get_tbclk() to get TSC frequency. This will not work if another
> > early timer is selected.
> 
> Thanks for working on this. But get_tbclk() is one API provided by the
> timer library. The get_tbclk_mhz() is something that is implemented by
> the TSC timer driver, so can we get rid of the get_tbclk_mhz() and use
> the get_tbclk() instead in coreboot/timestamp.c and quark/mrc_util.c?

The Coreboot timestamp code and Quark MRC specifically use rdtsc().
We can replace it with timer_early_get_count() or provide a function
to get the TSC frequency even when another early timer is selected.

> > Add tsc_rate_mhz() function and use it in the code that specifically
> > needs to get TSC rate regardless of currently selected early timer.
> >
> > Signed-off-by: Ivan Gorinov <ivan.gorinov@intel.com>
> > ---
> >  arch/x86/cpu/coreboot/timestamp.c |  2 +-
> >  arch/x86/cpu/quark/mrc_util.c     | 13 ++++++-------
> >  arch/x86/include/asm/u-boot-x86.h |  2 +-
> >  drivers/timer/tsc_timer.c         | 33 ++++++++++++++++++++++++---------
> >  4 files changed, 32 insertions(+), 18 deletions(-)
> >
> > diff --git a/arch/x86/cpu/coreboot/timestamp.c b/arch/x86/cpu/coreboot/timestamp.c
> > index b382795..05bb214 100644
> > --- a/arch/x86/cpu/coreboot/timestamp.c
> > +++ b/arch/x86/cpu/coreboot/timestamp.c
> > @@ -78,7 +78,7 @@ int timestamp_add_to_bootstage(void)
> >                 if (name) {
> >                         bootstage_add_record(0, name, BOOTSTAGEF_ALLOC,
> >                                              tse->entry_stamp /
> > -                                                       get_tbclk_mhz());
> > +                                                       tsc_rate_mhz());
> >                 }
> >         }
> >
> > diff --git a/arch/x86/cpu/quark/mrc_util.c b/arch/x86/cpu/quark/mrc_util.c
> > index fac2d72..4794395 100644
> > --- a/arch/x86/cpu/quark/mrc_util.c
> > +++ b/arch/x86/cpu/quark/mrc_util.c
> > @@ -57,19 +57,18 @@ void mrc_post_code(uint8_t major, uint8_t minor)
> >  void delay_n(uint32_t ns)
> >  {
> >         /* 1000 MHz clock has 1ns period --> no conversion required */
> > -       uint64_t final_tsc = rdtsc();
> > +       uint64_t start_tsc = rdtsc();
> > +       uint64_t ticks;
> >
> > -       final_tsc += ((get_tbclk_mhz() * ns) / 1000);
> > -
> > -       while (rdtsc() < final_tsc)
> > -               ;
> > +       ticks = (tsc_rate_mhz() * ns) / 1000;
> > +       while (rdtsc() - start_tsc < ticks);
> >  }
> >
> >  /* Delay number of microseconds */
> > -void delay_u(uint32_t ms)
> > +void delay_u(uint32_t us)
> >  {
> >         /* 64-bit math is not an option, just use loops */
> > -       while (ms--)
> > +       while (us--)
> >                 delay_n(1000);
> >  }
> >
> > diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h
> > index 187fe5f..de68120 100644
> > --- a/arch/x86/include/asm/u-boot-x86.h
> > +++ b/arch/x86/include/asm/u-boot-x86.h
> > @@ -29,7 +29,7 @@ int cleanup_before_linux(void);
> >  void timer_isr(void *);
> >  typedef void (timer_fnc_t) (void);
> >  int register_timer_isr (timer_fnc_t *isr_func);
> > -unsigned long get_tbclk_mhz(void);
> > +unsigned long tsc_rate_mhz(void);
> >  void timer_set_base(uint64_t base);
> >  int i8254_init(void);
> >
> > diff --git a/drivers/timer/tsc_timer.c b/drivers/timer/tsc_timer.c
> > index 9296de6..98cbf12 100644
> > --- a/drivers/timer/tsc_timer.c
> > +++ b/drivers/timer/tsc_timer.c
> > @@ -277,15 +277,12 @@ success:
> >         return delta / 1000;
> >  }
> >
> > -/* Get the speed of the TSC timer in MHz */
> > -unsigned notrace long get_tbclk_mhz(void)
> > -{
> > -       return get_tbclk() / 1000000;
> > -}
> > -
> >  static ulong get_ms_timer(void)
> >  {
> > -       return (get_ticks() * 1000) / get_tbclk();
> > +       if (gd->arch.clock_rate == 0)
> > +               return 0;
> > +
> > +       return (rdtsc() * 1000) / gd->arch.clock_rate;
> >  }
> >
> >  ulong get_timer(ulong base)
> > @@ -295,7 +292,10 @@ ulong get_timer(ulong base)
> >
> >  ulong notrace timer_get_us(void)
> >  {
> > -       return get_ticks() / get_tbclk_mhz();
> > +       if (gd->arch.clock_rate == 0)
> > +               return 0;
> > +
> > +       return (rdtsc() * 1000000) / gd->arch.clock_rate;
> >  }
> >
> >  ulong timer_get_boot_us(void)
> > @@ -308,7 +308,7 @@ void __udelay(unsigned long usec)
> >         u64 now = get_ticks();
> >         u64 stop;
> >
> > -       stop = now + usec * get_tbclk_mhz();
> > +       stop = now + ((u64)usec * gd->arch.clock_rate) / 1000000;
> >
> >         while ((int64_t)(stop - get_ticks()) > 0)
> >  #if defined(CONFIG_QEMU) && defined(CONFIG_SMP)
> > @@ -355,6 +355,14 @@ static void tsc_timer_ensure_setup(void)
> >         }
> >  }
> >
> > +/* Get the speed of the TSC timer in MHz */
> > +unsigned notrace long tsc_rate_mhz(void)
> > +{
> > +       tsc_timer_ensure_setup();
> > +
> > +       return gd->arch.clock_rate / 1000000;
> > +}
> > +
> >  static int tsc_timer_probe(struct udevice *dev)
> >  {
> >         struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
> > @@ -365,6 +373,13 @@ static int tsc_timer_probe(struct udevice *dev)
> >         return 0;
> >  }
> >
> > +int timer_init(void)
> > +{
> > +       tsc_timer_ensure_setup();
> > +
> > +       return 0;
> > +}
> > +
> >  unsigned long notrace timer_early_get_rate(void)
> >  {
> >         tsc_timer_ensure_setup();
> > --

  parent reply	other threads:[~2018-04-23 23:56 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-04-12 22:11 [U-Boot] [PATCH v6 0/2] timer: Add High Precision Event Timers (HPET) support Ivan Gorinov
2018-04-12 22:12 ` [U-Boot] [PATCH v6 1/2] x86: Add TSC-specific timer functions Ivan Gorinov
2018-04-20 12:25   ` Andy Shevchenko
2018-04-20 18:00     ` Ivan Gorinov
2018-04-23  8:22       ` Andy Shevchenko
2018-04-23  7:38   ` Bin Meng
2018-04-23  7:53     ` Bin Meng
2018-04-23 23:56     ` Ivan Gorinov [this message]
2018-04-24  8:41       ` Bin Meng
2018-04-26  3:42         ` Bin Meng
2018-04-30 23:13           ` Simon Glass
2018-04-12 22:12 ` [U-Boot] [PATCH v6 2/2] timer: Add High Precision Event Timers (HPET) support Ivan Gorinov

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=20180423235616.GA17404@intel.com \
    --to=ivan.gorinov@intel.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.