diff mbox series

[U-Boot,054/126] x86: Add common functions for TDP and perf control

Message ID 20190925145750.200592-55-sjg@chromium.org
State Accepted
Delegated to: Bin Meng
Headers show
Series x86: Add initial support for apollolake | expand

Commit Message

Simon Glass Sept. 25, 2019, 2:56 p.m. UTC
These functions are the same on modern Intel CPUs, so use common code to
set them.

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

 arch/x86/cpu/broadwell/cpu.c                  |  7 ++----
 arch/x86/cpu/broadwell/cpu_full.c             |  9 -------
 arch/x86/cpu/intel_common/cpu.c               | 20 +++++++++++++++
 arch/x86/cpu/ivybridge/model_206ax.c          | 25 +++++++------------
 arch/x86/cpu/ivybridge/northbridge.c          |  2 +-
 .../include/asm/arch-ivybridge/model_206ax.h  |  2 +-
 arch/x86/include/asm/cpu_common.h             | 18 +++++++++++++
 7 files changed, 51 insertions(+), 32 deletions(-)

Comments

Bin Meng Oct. 6, 2019, 4:09 p.m. UTC | #1
On Wed, Sep 25, 2019 at 10:58 PM Simon Glass <sjg@chromium.org> wrote:
>
> These functions are the same on modern Intel CPUs, so use common code to
> set them.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
>  arch/x86/cpu/broadwell/cpu.c                  |  7 ++----
>  arch/x86/cpu/broadwell/cpu_full.c             |  9 -------
>  arch/x86/cpu/intel_common/cpu.c               | 20 +++++++++++++++
>  arch/x86/cpu/ivybridge/model_206ax.c          | 25 +++++++------------
>  arch/x86/cpu/ivybridge/northbridge.c          |  2 +-
>  .../include/asm/arch-ivybridge/model_206ax.h  |  2 +-
>  arch/x86/include/asm/cpu_common.h             | 18 +++++++++++++
>  7 files changed, 51 insertions(+), 32 deletions(-)
>
> diff --git a/arch/x86/cpu/broadwell/cpu.c b/arch/x86/cpu/broadwell/cpu.c
> index 586a2e8f05a..55a7439f1c1 100644
> --- a/arch/x86/cpu/broadwell/cpu.c
> +++ b/arch/x86/cpu/broadwell/cpu.c
> @@ -41,12 +41,9 @@ int arch_cpu_init_dm(void)
>
>  void set_max_freq(void)
>  {
> -       msr_t msr, perf_ctl, platform_info;
> +       msr_t msr, perf_ctl;
>
> -       /* Check for configurable TDP option */
> -       platform_info = msr_read(MSR_PLATFORM_INFO);
> -
> -       if ((platform_info.hi >> 1) & 3) {
> +       if (cpu_config_tdp_levels()) {
>                 /* Set to nominal TDP ratio */
>                 msr = msr_read(MSR_CONFIG_TDP_NOMINAL);
>                 perf_ctl.lo = (msr.lo & 0xff) << 8;
> diff --git a/arch/x86/cpu/broadwell/cpu_full.c b/arch/x86/cpu/broadwell/cpu_full.c
> index 58cc2f362cc..169b5b02a6a 100644
> --- a/arch/x86/cpu/broadwell/cpu_full.c
> +++ b/arch/x86/cpu/broadwell/cpu_full.c
> @@ -329,15 +329,6 @@ static int bsp_init_before_ap_bringup(struct udevice *dev)
>         return 0;
>  }
>
> -static int cpu_config_tdp_levels(void)
> -{
> -       msr_t platform_info;
> -
> -       /* Bits 34:33 indicate how many levels supported */
> -       platform_info = msr_read(MSR_PLATFORM_INFO);
> -       return (platform_info.hi >> 1) & 3;
> -}
> -
>  static void set_max_ratio(void)
>  {
>         msr_t msr, perf_ctl;
> diff --git a/arch/x86/cpu/intel_common/cpu.c b/arch/x86/cpu/intel_common/cpu.c
> index 7d0ed73b4b6..1898903853f 100644
> --- a/arch/x86/cpu/intel_common/cpu.c
> +++ b/arch/x86/cpu/intel_common/cpu.c
> @@ -145,3 +145,23 @@ int cpu_configure_thermal_target(struct udevice *dev)
>
>         return 0;
>  }
> +
> +void cpu_set_perf_control(uint clk_ratio)
> +{
> +       msr_t perf_ctl;
> +
> +       perf_ctl.lo = (clk_ratio & 0xff) << 8;
> +       perf_ctl.hi = 0;
> +       msr_write(MSR_IA32_PERF_CTL, perf_ctl);
> +       debug("CPU: frequency set to %d MHz\n", clk_ratio * INTEL_BCLK_MHZ);
> +}
> +
> +bool cpu_config_tdp_levels(void)
> +{
> +       msr_t platform_info;
> +
> +       /* Bits 34:33 indicate how many levels supported */
> +       platform_info = msr_read(MSR_PLATFORM_INFO);
> +
> +       return ((platform_info.hi >> 1) & 3) != 0;
> +}
> diff --git a/arch/x86/cpu/ivybridge/model_206ax.c b/arch/x86/cpu/ivybridge/model_206ax.c
> index 3177ba3297f..2c8cedbaea2 100644
> --- a/arch/x86/cpu/ivybridge/model_206ax.c
> +++ b/arch/x86/cpu/ivybridge/model_206ax.c
> @@ -140,19 +140,16 @@ static const u8 power_limit_time_msr_to_sec[] = {
>         [0x11] = 128,
>  };
>
> -int cpu_config_tdp_levels(void)
> +bool cpu_ivybridge_config_tdp_levels(void)
>  {
>         struct cpuid_result result;
> -       msr_t platform_info;
>
>         /* Minimum CPU revision */
>         result = cpuid(1);
>         if (result.eax < IVB_CONFIG_TDP_MIN_CPUID)
>                 return 0;

We should return false here, since the return value type is now changed to bool.

>
> -       /* Bits 34:33 indicate how many levels supported */
> -       platform_info = msr_read(MSR_PLATFORM_INFO);
> -       return (platform_info.hi >> 1) & 3;
> +       return cpu_config_tdp_levels();
>  }
>
>  /*
> @@ -213,7 +210,7 @@ void set_power_limits(u8 power_limit_1_time)
>         msr_write(MSR_PKG_POWER_LIMIT, limit);
>
>         /* Use nominal TDP values for CPUs with configurable TDP */
> -       if (cpu_config_tdp_levels()) {
> +       if (cpu_ivybridge_config_tdp_levels()) {
>                 msr = msr_read(MSR_CONFIG_TDP_NOMINAL);
>                 limit.hi = 0;
>                 limit.lo = msr.lo & 0xff;
> @@ -329,24 +326,20 @@ static void configure_dca_cap(void)
>
>  static void set_max_ratio(void)
>  {
> -       msr_t msr, perf_ctl;
> -
> -       perf_ctl.hi = 0;
> +       msr_t msr;
> +       uint ratio;
>
>         /* Check for configurable TDP option */
> -       if (cpu_config_tdp_levels()) {
> +       if (cpu_ivybridge_config_tdp_levels()) {
>                 /* Set to nominal TDP ratio */
>                 msr = msr_read(MSR_CONFIG_TDP_NOMINAL);
> -               perf_ctl.lo = (msr.lo & 0xff) << 8;
> +               ratio = msr.lo & 0xff;
>         } else {
>                 /* Platform Info bits 15:8 give max ratio */
>                 msr = msr_read(MSR_PLATFORM_INFO);
> -               perf_ctl.lo = msr.lo & 0xff00;
> +               ratio = (msr.lo & 0xff00) >> 8;
>         }
> -       msr_write(MSR_IA32_PERF_CTL, perf_ctl);
> -
> -       debug("model_x06ax: frequency set to %d\n",
> -             ((perf_ctl.lo >> 8) & 0xff) * INTEL_BCLK_MHZ);
> +       cpu_set_perf_control(ratio);
>  }
>
>  static void set_energy_perf_bias(u8 policy)
> diff --git a/arch/x86/cpu/ivybridge/northbridge.c b/arch/x86/cpu/ivybridge/northbridge.c
> index a809b823b3b..0f427afcb82 100644
> --- a/arch/x86/cpu/ivybridge/northbridge.c
> +++ b/arch/x86/cpu/ivybridge/northbridge.c
> @@ -141,7 +141,7 @@ static void northbridge_init(struct udevice *dev, int rev)
>          * CPUs with configurable TDP also need power limits set
>          * in MCHBAR.  Use same values from MSR_PKG_POWER_LIMIT.
>          */
> -       if (cpu_config_tdp_levels()) {
> +       if (cpu_ivybridge_config_tdp_levels()) {
>                 msr_t msr = msr_read(MSR_PKG_POWER_LIMIT);
>
>                 writel(msr.lo, MCHBAR_REG(0x59A0));
> diff --git a/arch/x86/include/asm/arch-ivybridge/model_206ax.h b/arch/x86/include/asm/arch-ivybridge/model_206ax.h
> index 10caaa24226..4839ebc3124 100644
> --- a/arch/x86/include/asm/arch-ivybridge/model_206ax.h
> +++ b/arch/x86/include/asm/arch-ivybridge/model_206ax.h
> @@ -58,6 +58,6 @@
>
>  /* Configure power limits for turbo mode */
>  void set_power_limits(u8 power_limit_1_time);
> -int cpu_config_tdp_levels(void);
> +bool cpu_ivybridge_config_tdp_levels(void);
>
>  #endif
> diff --git a/arch/x86/include/asm/cpu_common.h b/arch/x86/include/asm/cpu_common.h
> index 3d093021ae6..e6a2a0eb3e5 100644
> --- a/arch/x86/include/asm/cpu_common.h
> +++ b/arch/x86/include/asm/cpu_common.h
> @@ -1,5 +1,7 @@
>  /* SPDX-License-Identifier: GPL-2.0 */
>  /*
> + * Common code for Intel CPUs
> + *
>   * Copyright (c) 2016 Google, Inc
>   */
>
> @@ -56,4 +58,20 @@ int cpu_intel_get_info(struct cpu_info *info, int bclk_mz);
>   */
>  int cpu_configure_thermal_target(struct udevice *dev);
>
> +/**
> + * cpu_set_perf_control() - Set the nominal CPU clock speed
> + *
> + * This sets the clock speed as a muiltiplier of BCLK
> + *
> + * @clk_ratio: Ratio to use
> + */
> +void cpu_set_perf_control(uint clk_ratio);
> +
> +/**
> + * cpu_config_tdp_levels() - Check for configurable TDP option
> + *
> + * @return true if the CPU has configurable TDP (Thermal-desgn power)
> + */
> +bool cpu_config_tdp_levels(void);
> +
>  #endif
> --

Other than above,

Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Bin Meng Oct. 6, 2019, 4:15 p.m. UTC | #2
On Mon, Oct 7, 2019 at 12:09 AM Bin Meng <bmeng.cn@gmail.com> wrote:
>
> On Wed, Sep 25, 2019 at 10:58 PM Simon Glass <sjg@chromium.org> wrote:
> >
> > These functions are the same on modern Intel CPUs, so use common code to
> > set them.
> >
> > Signed-off-by: Simon Glass <sjg@chromium.org>
> > ---
> >
> >  arch/x86/cpu/broadwell/cpu.c                  |  7 ++----
> >  arch/x86/cpu/broadwell/cpu_full.c             |  9 -------
> >  arch/x86/cpu/intel_common/cpu.c               | 20 +++++++++++++++
> >  arch/x86/cpu/ivybridge/model_206ax.c          | 25 +++++++------------
> >  arch/x86/cpu/ivybridge/northbridge.c          |  2 +-
> >  .../include/asm/arch-ivybridge/model_206ax.h  |  2 +-
> >  arch/x86/include/asm/cpu_common.h             | 18 +++++++++++++
> >  7 files changed, 51 insertions(+), 32 deletions(-)
> >

[snip]

> > diff --git a/arch/x86/include/asm/cpu_common.h b/arch/x86/include/asm/cpu_common.h
> > index 3d093021ae6..e6a2a0eb3e5 100644
> > --- a/arch/x86/include/asm/cpu_common.h
> > +++ b/arch/x86/include/asm/cpu_common.h
> > @@ -1,5 +1,7 @@
> >  /* SPDX-License-Identifier: GPL-2.0 */
> >  /*
> > + * Common code for Intel CPUs
> > + *
> >   * Copyright (c) 2016 Google, Inc
> >   */
> >
> > @@ -56,4 +58,20 @@ int cpu_intel_get_info(struct cpu_info *info, int bclk_mz);
> >   */
> >  int cpu_configure_thermal_target(struct udevice *dev);
> >
> > +/**
> > + * cpu_set_perf_control() - Set the nominal CPU clock speed
> > + *
> > + * This sets the clock speed as a muiltiplier of BCLK

typo: multiplier

> > + *
> > + * @clk_ratio: Ratio to use
> > + */
> > +void cpu_set_perf_control(uint clk_ratio);
> > +
> > +/**
> > + * cpu_config_tdp_levels() - Check for configurable TDP option
> > + *
> > + * @return true if the CPU has configurable TDP (Thermal-desgn power)

typo: design

> > + */
> > +bool cpu_config_tdp_levels(void);
> > +
> >  #endif
> > --

Will fix these typos when applying.
Bin Meng Oct. 7, 2019, 12:52 p.m. UTC | #3
On Mon, Oct 7, 2019 at 12:15 AM Bin Meng <bmeng.cn@gmail.com> wrote:
>
> On Mon, Oct 7, 2019 at 12:09 AM Bin Meng <bmeng.cn@gmail.com> wrote:
> >
> > On Wed, Sep 25, 2019 at 10:58 PM Simon Glass <sjg@chromium.org> wrote:
> > >
> > > These functions are the same on modern Intel CPUs, so use common code to
> > > set them.
> > >
> > > Signed-off-by: Simon Glass <sjg@chromium.org>
> > > ---
> > >
> > >  arch/x86/cpu/broadwell/cpu.c                  |  7 ++----
> > >  arch/x86/cpu/broadwell/cpu_full.c             |  9 -------
> > >  arch/x86/cpu/intel_common/cpu.c               | 20 +++++++++++++++
> > >  arch/x86/cpu/ivybridge/model_206ax.c          | 25 +++++++------------
> > >  arch/x86/cpu/ivybridge/northbridge.c          |  2 +-
> > >  .../include/asm/arch-ivybridge/model_206ax.h  |  2 +-
> > >  arch/x86/include/asm/cpu_common.h             | 18 +++++++++++++
> > >  7 files changed, 51 insertions(+), 32 deletions(-)
> > >
>
> [snip]
>
> > > diff --git a/arch/x86/include/asm/cpu_common.h b/arch/x86/include/asm/cpu_common.h
> > > index 3d093021ae6..e6a2a0eb3e5 100644
> > > --- a/arch/x86/include/asm/cpu_common.h
> > > +++ b/arch/x86/include/asm/cpu_common.h
> > > @@ -1,5 +1,7 @@
> > >  /* SPDX-License-Identifier: GPL-2.0 */
> > >  /*
> > > + * Common code for Intel CPUs
> > > + *
> > >   * Copyright (c) 2016 Google, Inc
> > >   */
> > >
> > > @@ -56,4 +58,20 @@ int cpu_intel_get_info(struct cpu_info *info, int bclk_mz);
> > >   */
> > >  int cpu_configure_thermal_target(struct udevice *dev);
> > >
> > > +/**
> > > + * cpu_set_perf_control() - Set the nominal CPU clock speed
> > > + *
> > > + * This sets the clock speed as a muiltiplier of BCLK
>
> typo: multiplier
>
> > > + *
> > > + * @clk_ratio: Ratio to use
> > > + */
> > > +void cpu_set_perf_control(uint clk_ratio);
> > > +
> > > +/**
> > > + * cpu_config_tdp_levels() - Check for configurable TDP option
> > > + *
> > > + * @return true if the CPU has configurable TDP (Thermal-desgn power)
>
> typo: design
>
> > > + */
> > > +bool cpu_config_tdp_levels(void);
> > > +
> > >  #endif
> > > --
>
> Will fix these typos when applying.

Fixed return value as false, and these typos, and,

applied to u-boot-x86/next, thanks!
diff mbox series

Patch

diff --git a/arch/x86/cpu/broadwell/cpu.c b/arch/x86/cpu/broadwell/cpu.c
index 586a2e8f05a..55a7439f1c1 100644
--- a/arch/x86/cpu/broadwell/cpu.c
+++ b/arch/x86/cpu/broadwell/cpu.c
@@ -41,12 +41,9 @@  int arch_cpu_init_dm(void)
 
 void set_max_freq(void)
 {
-	msr_t msr, perf_ctl, platform_info;
+	msr_t msr, perf_ctl;
 
-	/* Check for configurable TDP option */
-	platform_info = msr_read(MSR_PLATFORM_INFO);
-
-	if ((platform_info.hi >> 1) & 3) {
+	if (cpu_config_tdp_levels()) {
 		/* Set to nominal TDP ratio */
 		msr = msr_read(MSR_CONFIG_TDP_NOMINAL);
 		perf_ctl.lo = (msr.lo & 0xff) << 8;
diff --git a/arch/x86/cpu/broadwell/cpu_full.c b/arch/x86/cpu/broadwell/cpu_full.c
index 58cc2f362cc..169b5b02a6a 100644
--- a/arch/x86/cpu/broadwell/cpu_full.c
+++ b/arch/x86/cpu/broadwell/cpu_full.c
@@ -329,15 +329,6 @@  static int bsp_init_before_ap_bringup(struct udevice *dev)
 	return 0;
 }
 
-static int cpu_config_tdp_levels(void)
-{
-	msr_t platform_info;
-
-	/* Bits 34:33 indicate how many levels supported */
-	platform_info = msr_read(MSR_PLATFORM_INFO);
-	return (platform_info.hi >> 1) & 3;
-}
-
 static void set_max_ratio(void)
 {
 	msr_t msr, perf_ctl;
diff --git a/arch/x86/cpu/intel_common/cpu.c b/arch/x86/cpu/intel_common/cpu.c
index 7d0ed73b4b6..1898903853f 100644
--- a/arch/x86/cpu/intel_common/cpu.c
+++ b/arch/x86/cpu/intel_common/cpu.c
@@ -145,3 +145,23 @@  int cpu_configure_thermal_target(struct udevice *dev)
 
 	return 0;
 }
+
+void cpu_set_perf_control(uint clk_ratio)
+{
+	msr_t perf_ctl;
+
+	perf_ctl.lo = (clk_ratio & 0xff) << 8;
+	perf_ctl.hi = 0;
+	msr_write(MSR_IA32_PERF_CTL, perf_ctl);
+	debug("CPU: frequency set to %d MHz\n", clk_ratio * INTEL_BCLK_MHZ);
+}
+
+bool cpu_config_tdp_levels(void)
+{
+	msr_t platform_info;
+
+	/* Bits 34:33 indicate how many levels supported */
+	platform_info = msr_read(MSR_PLATFORM_INFO);
+
+	return ((platform_info.hi >> 1) & 3) != 0;
+}
diff --git a/arch/x86/cpu/ivybridge/model_206ax.c b/arch/x86/cpu/ivybridge/model_206ax.c
index 3177ba3297f..2c8cedbaea2 100644
--- a/arch/x86/cpu/ivybridge/model_206ax.c
+++ b/arch/x86/cpu/ivybridge/model_206ax.c
@@ -140,19 +140,16 @@  static const u8 power_limit_time_msr_to_sec[] = {
 	[0x11] = 128,
 };
 
-int cpu_config_tdp_levels(void)
+bool cpu_ivybridge_config_tdp_levels(void)
 {
 	struct cpuid_result result;
-	msr_t platform_info;
 
 	/* Minimum CPU revision */
 	result = cpuid(1);
 	if (result.eax < IVB_CONFIG_TDP_MIN_CPUID)
 		return 0;
 
-	/* Bits 34:33 indicate how many levels supported */
-	platform_info = msr_read(MSR_PLATFORM_INFO);
-	return (platform_info.hi >> 1) & 3;
+	return cpu_config_tdp_levels();
 }
 
 /*
@@ -213,7 +210,7 @@  void set_power_limits(u8 power_limit_1_time)
 	msr_write(MSR_PKG_POWER_LIMIT, limit);
 
 	/* Use nominal TDP values for CPUs with configurable TDP */
-	if (cpu_config_tdp_levels()) {
+	if (cpu_ivybridge_config_tdp_levels()) {
 		msr = msr_read(MSR_CONFIG_TDP_NOMINAL);
 		limit.hi = 0;
 		limit.lo = msr.lo & 0xff;
@@ -329,24 +326,20 @@  static void configure_dca_cap(void)
 
 static void set_max_ratio(void)
 {
-	msr_t msr, perf_ctl;
-
-	perf_ctl.hi = 0;
+	msr_t msr;
+	uint ratio;
 
 	/* Check for configurable TDP option */
-	if (cpu_config_tdp_levels()) {
+	if (cpu_ivybridge_config_tdp_levels()) {
 		/* Set to nominal TDP ratio */
 		msr = msr_read(MSR_CONFIG_TDP_NOMINAL);
-		perf_ctl.lo = (msr.lo & 0xff) << 8;
+		ratio = msr.lo & 0xff;
 	} else {
 		/* Platform Info bits 15:8 give max ratio */
 		msr = msr_read(MSR_PLATFORM_INFO);
-		perf_ctl.lo = msr.lo & 0xff00;
+		ratio = (msr.lo & 0xff00) >> 8;
 	}
-	msr_write(MSR_IA32_PERF_CTL, perf_ctl);
-
-	debug("model_x06ax: frequency set to %d\n",
-	      ((perf_ctl.lo >> 8) & 0xff) * INTEL_BCLK_MHZ);
+	cpu_set_perf_control(ratio);
 }
 
 static void set_energy_perf_bias(u8 policy)
diff --git a/arch/x86/cpu/ivybridge/northbridge.c b/arch/x86/cpu/ivybridge/northbridge.c
index a809b823b3b..0f427afcb82 100644
--- a/arch/x86/cpu/ivybridge/northbridge.c
+++ b/arch/x86/cpu/ivybridge/northbridge.c
@@ -141,7 +141,7 @@  static void northbridge_init(struct udevice *dev, int rev)
 	 * CPUs with configurable TDP also need power limits set
 	 * in MCHBAR.  Use same values from MSR_PKG_POWER_LIMIT.
 	 */
-	if (cpu_config_tdp_levels()) {
+	if (cpu_ivybridge_config_tdp_levels()) {
 		msr_t msr = msr_read(MSR_PKG_POWER_LIMIT);
 
 		writel(msr.lo, MCHBAR_REG(0x59A0));
diff --git a/arch/x86/include/asm/arch-ivybridge/model_206ax.h b/arch/x86/include/asm/arch-ivybridge/model_206ax.h
index 10caaa24226..4839ebc3124 100644
--- a/arch/x86/include/asm/arch-ivybridge/model_206ax.h
+++ b/arch/x86/include/asm/arch-ivybridge/model_206ax.h
@@ -58,6 +58,6 @@ 
 
 /* Configure power limits for turbo mode */
 void set_power_limits(u8 power_limit_1_time);
-int cpu_config_tdp_levels(void);
+bool cpu_ivybridge_config_tdp_levels(void);
 
 #endif
diff --git a/arch/x86/include/asm/cpu_common.h b/arch/x86/include/asm/cpu_common.h
index 3d093021ae6..e6a2a0eb3e5 100644
--- a/arch/x86/include/asm/cpu_common.h
+++ b/arch/x86/include/asm/cpu_common.h
@@ -1,5 +1,7 @@ 
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
+ * Common code for Intel CPUs
+ *
  * Copyright (c) 2016 Google, Inc
  */
 
@@ -56,4 +58,20 @@  int cpu_intel_get_info(struct cpu_info *info, int bclk_mz);
  */
 int cpu_configure_thermal_target(struct udevice *dev);
 
+/**
+ * cpu_set_perf_control() - Set the nominal CPU clock speed
+ *
+ * This sets the clock speed as a muiltiplier of BCLK
+ *
+ * @clk_ratio: Ratio to use
+ */
+void cpu_set_perf_control(uint clk_ratio);
+
+/**
+ * cpu_config_tdp_levels() - Check for configurable TDP option
+ *
+ * @return true if the CPU has configurable TDP (Thermal-desgn power)
+ */
+bool cpu_config_tdp_levels(void);
+
 #endif