diff mbox series

platform/x86: Add support for improved performance mode

Message ID 20231108162039.13737-1-mpearson-lenovo@squebb.ca (mailing list archive)
State Superseded, archived
Headers show
Series platform/x86: Add support for improved performance mode | expand

Commit Message

Mark Pearson Nov. 8, 2023, 4:20 p.m. UTC
Some new Thinkpads have a new improved performance mode available.
Add support to make this mode usable.

To avoid having to create a new profile, just use the improved performance
mode in place of the existing performance mode, when available.

Tested on T14 AMD G4 AMD.

Signed-off-by: Mark Pearson <mpearson-lenovo@squebb.ca>
---
 drivers/platform/x86/thinkpad_acpi.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

Comments

Ilpo Järvinen Nov. 9, 2023, 10:10 a.m. UTC | #1
On Wed, 8 Nov 2023, Mark Pearson wrote:

> Some new Thinkpads have a new improved performance mode available.
> Add support to make this mode usable.
> 
> To avoid having to create a new profile, just use the improved performance
> mode in place of the existing performance mode, when available.
> 
> Tested on T14 AMD G4 AMD.
> 
> Signed-off-by: Mark Pearson <mpearson-lenovo@squebb.ca>
> ---
>  drivers/platform/x86/thinkpad_acpi.c | 28 ++++++++++++++++++++++++++++
>  1 file changed, 28 insertions(+)
> 
> diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
> index ad460417f901..eba701ab340e 100644
> --- a/drivers/platform/x86/thinkpad_acpi.c
> +++ b/drivers/platform/x86/thinkpad_acpi.c
> @@ -10136,6 +10136,7 @@ static struct ibm_struct proxsensor_driver_data = {
>  
>  #define DYTC_CMD_SET          1 /* To enable/disable IC function mode */
>  #define DYTC_CMD_MMC_GET      8 /* To get current MMC function and mode */
> +#define DYTC_CMD_UP_CAP     0xA /* To get Ultra-performance capability */
>  #define DYTC_CMD_RESET    0x1ff /* To reset back to default */
>  
>  #define DYTC_CMD_FUNC_CAP     3 /* To get DYTC capabilities */
> @@ -10152,6 +10153,7 @@ static struct ibm_struct proxsensor_driver_data = {
>  
>  #define DYTC_FUNCTION_STD     0  /* Function = 0, standard mode */
>  #define DYTC_FUNCTION_CQL     1  /* Function = 1, lap mode */
> +#define DYTC_FUNCTION_TMS     9  /* Function = 9, TMS mode */
>  #define DYTC_FUNCTION_MMC     11 /* Function = 11, MMC mode */
>  #define DYTC_FUNCTION_PSC     13 /* Function = 13, PSC mode */
>  #define DYTC_FUNCTION_AMT     15 /* Function = 15, AMT mode */
> @@ -10163,11 +10165,14 @@ static struct ibm_struct proxsensor_driver_data = {
>  #define DYTC_MODE_MMC_LOWPOWER 3  /* Low power mode */
>  #define DYTC_MODE_MMC_BALANCE  0xF  /* Default mode aka balanced */
>  #define DYTC_MODE_MMC_DEFAULT  0  /* Default mode from MMC_GET, aka balanced */
> +#define DYTC_NOMODE            0xF  /* When Function does not have a mode */
>  
>  #define DYTC_MODE_PSC_LOWPOWER 3  /* Low power mode */
>  #define DYTC_MODE_PSC_BALANCE  5  /* Default mode aka balanced */
>  #define DYTC_MODE_PSC_PERFORM  7  /* High power mode aka performance */
>  
> +#define DYTC_UP_SUPPORT_BIT    8  /* Bit 8 - 1 = supported, 0 = not */

It would be preferrable to comment what is supported rather than have a 
comment like above which isn't particularly helpful.

>  #define DYTC_ERR_MASK       0xF  /* Bits 0-3 in cmd result are the error result */
>  #define DYTC_ERR_SUCCESS      1  /* CMD completed successful */
>  
> @@ -10185,6 +10190,7 @@ static enum platform_profile_option dytc_current_profile;
>  static atomic_t dytc_ignore_event = ATOMIC_INIT(0);
>  static DEFINE_MUTEX(dytc_mutex);
>  static int dytc_capabilities;
> +static bool dytc_ultraperf_cap; /* ultra performance capable */
>  static bool dytc_mmc_get_available;
>  static int profile_force;
>  
> @@ -10355,6 +10361,17 @@ static int dytc_profile_set(struct platform_profile_handler *pprof,
>  	if (err)
>  		goto unlock;
>  
> +	/* Set TMS mode appropriately (enable for performance), if available */
> +	if (dytc_ultraperf_cap) {
> +		int cmd;
> +
> +		cmd = DYTC_SET_COMMAND(DYTC_FUNCTION_TMS, DYTC_NOMODE,
> +				       profile == PLATFORM_PROFILE_PERFORMANCE);
> +		err = dytc_command(cmd, &output);
> +		if (err)
> +			return err;
> +	}
> +
>  	if (dytc_capabilities & BIT(DYTC_FC_MMC)) {
>  		if (profile == PLATFORM_PROFILE_BALANCED) {
>  			/*
> @@ -10429,6 +10446,7 @@ static struct platform_profile_handler dytc_profile = {
>  static int tpacpi_dytc_profile_init(struct ibm_init_struct *iibm)
>  {
>  	int err, output;
> +	int cmd;
>  
>  	/* Setup supported modes */
>  	set_bit(PLATFORM_PROFILE_LOW_POWER, dytc_profile.choices);
> @@ -10484,6 +10502,16 @@ static int tpacpi_dytc_profile_init(struct ibm_init_struct *iibm)
>  		dbg_printk(TPACPI_DBG_INIT, "No DYTC support available\n");
>  		return -ENODEV;
>  	}
> +	err = dytc_command(DYTC_CMD_UP_CAP, &output);
> +	dytc_ultraperf_cap = output & BIT(DYTC_UP_SUPPORT_BIT) ? true : false;

It would be better to put this BIT() into the define itself and remove 
_BIT from the name because it doesn't really add that much information.
Since you're assigning to bool, ? true : false construct is not required 
but implicit cast will handle it for you. So in the end, this line would 
be:

	dytc_ultraperf_cap = output & DYTC_UP_SUPPORT;

Looking into the driver a bit more, there are a few other defines which 
could also move BIT() from the code into defines. Please tell if you're 
going to look at those because if not, I might try to make the patches.

> +	if (dytc_ultraperf_cap) {
> +		pr_debug("TMS is supported\n");
> +		/* Disable TMS by default - only use with performance mode */
> +		cmd = DYTC_SET_COMMAND(DYTC_FUNCTION_TMS, DYTC_NOMODE, 0);
> +		err = dytc_command(cmd, &output);
> +		if (err)
> +			return err;
> +	}
>  
>  	dbg_printk(TPACPI_DBG_INIT,
>  			"DYTC version %d: thermal mode available\n", dytc_version);
>
Mark Pearson Nov. 9, 2023, 5:57 p.m. UTC | #2
Hi Ilpo,

On Thu, Nov 9, 2023, at 5:10 AM, Ilpo Järvinen wrote:
> On Wed, 8 Nov 2023, Mark Pearson wrote:
>
>> Some new Thinkpads have a new improved performance mode available.
>> Add support to make this mode usable.
>> 
>> To avoid having to create a new profile, just use the improved performance
>> mode in place of the existing performance mode, when available.
>> 
>> Tested on T14 AMD G4 AMD.
>> 
>> Signed-off-by: Mark Pearson <mpearson-lenovo@squebb.ca>
>> ---
>>  drivers/platform/x86/thinkpad_acpi.c | 28 ++++++++++++++++++++++++++++
>>  1 file changed, 28 insertions(+)
>> 
>> diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
>> index ad460417f901..eba701ab340e 100644
>> --- a/drivers/platform/x86/thinkpad_acpi.c
>> +++ b/drivers/platform/x86/thinkpad_acpi.c
>> @@ -10136,6 +10136,7 @@ static struct ibm_struct proxsensor_driver_data = {
>>  
>>  #define DYTC_CMD_SET          1 /* To enable/disable IC function mode */
>>  #define DYTC_CMD_MMC_GET      8 /* To get current MMC function and mode */
>> +#define DYTC_CMD_UP_CAP     0xA /* To get Ultra-performance capability */
>>  #define DYTC_CMD_RESET    0x1ff /* To reset back to default */
>>  
>>  #define DYTC_CMD_FUNC_CAP     3 /* To get DYTC capabilities */
>> @@ -10152,6 +10153,7 @@ static struct ibm_struct proxsensor_driver_data = {
>>  
>>  #define DYTC_FUNCTION_STD     0  /* Function = 0, standard mode */
>>  #define DYTC_FUNCTION_CQL     1  /* Function = 1, lap mode */
>> +#define DYTC_FUNCTION_TMS     9  /* Function = 9, TMS mode */
>>  #define DYTC_FUNCTION_MMC     11 /* Function = 11, MMC mode */
>>  #define DYTC_FUNCTION_PSC     13 /* Function = 13, PSC mode */
>>  #define DYTC_FUNCTION_AMT     15 /* Function = 15, AMT mode */
>> @@ -10163,11 +10165,14 @@ static struct ibm_struct proxsensor_driver_data = {
>>  #define DYTC_MODE_MMC_LOWPOWER 3  /* Low power mode */
>>  #define DYTC_MODE_MMC_BALANCE  0xF  /* Default mode aka balanced */
>>  #define DYTC_MODE_MMC_DEFAULT  0  /* Default mode from MMC_GET, aka balanced */
>> +#define DYTC_NOMODE            0xF  /* When Function does not have a mode */
>>  
>>  #define DYTC_MODE_PSC_LOWPOWER 3  /* Low power mode */
>>  #define DYTC_MODE_PSC_BALANCE  5  /* Default mode aka balanced */
>>  #define DYTC_MODE_PSC_PERFORM  7  /* High power mode aka performance */
>>  
>> +#define DYTC_UP_SUPPORT_BIT    8  /* Bit 8 - 1 = supported, 0 = not */
>
> It would be preferrable to comment what is supported rather than have a 
> comment like above which isn't particularly helpful.

OK - so  just have:
#define DYTC_UP_SUPPORT_BIT    8  /* Ultra-performance (TMS) mode support */

Or...reading ahead in the review this should actually be
#define DYTC_UP_SUPPORT_BIT    BIT(8)  /* Ultra-performance (TMS) mode support */

>
>>  #define DYTC_ERR_MASK       0xF  /* Bits 0-3 in cmd result are the error result */
>>  #define DYTC_ERR_SUCCESS      1  /* CMD completed successful */
>>  
>> @@ -10185,6 +10190,7 @@ static enum platform_profile_option dytc_current_profile;
>>  static atomic_t dytc_ignore_event = ATOMIC_INIT(0);
>>  static DEFINE_MUTEX(dytc_mutex);
>>  static int dytc_capabilities;
>> +static bool dytc_ultraperf_cap; /* ultra performance capable */
>>  static bool dytc_mmc_get_available;
>>  static int profile_force;
>>  
>> @@ -10355,6 +10361,17 @@ static int dytc_profile_set(struct platform_profile_handler *pprof,
>>  	if (err)
>>  		goto unlock;
>>  
>> +	/* Set TMS mode appropriately (enable for performance), if available */
>> +	if (dytc_ultraperf_cap) {
>> +		int cmd;
>> +
>> +		cmd = DYTC_SET_COMMAND(DYTC_FUNCTION_TMS, DYTC_NOMODE,
>> +				       profile == PLATFORM_PROFILE_PERFORMANCE);
>> +		err = dytc_command(cmd, &output);
>> +		if (err)
>> +			return err;
>> +	}
>> +
>>  	if (dytc_capabilities & BIT(DYTC_FC_MMC)) {
>>  		if (profile == PLATFORM_PROFILE_BALANCED) {
>>  			/*
>> @@ -10429,6 +10446,7 @@ static struct platform_profile_handler dytc_profile = {
>>  static int tpacpi_dytc_profile_init(struct ibm_init_struct *iibm)
>>  {
>>  	int err, output;
>> +	int cmd;
>>  
>>  	/* Setup supported modes */
>>  	set_bit(PLATFORM_PROFILE_LOW_POWER, dytc_profile.choices);
>> @@ -10484,6 +10502,16 @@ static int tpacpi_dytc_profile_init(struct ibm_init_struct *iibm)
>>  		dbg_printk(TPACPI_DBG_INIT, "No DYTC support available\n");
>>  		return -ENODEV;
>>  	}
>> +	err = dytc_command(DYTC_CMD_UP_CAP, &output);
>> +	dytc_ultraperf_cap = output & BIT(DYTC_UP_SUPPORT_BIT) ? true : false;
>
> It would be better to put this BIT() into the define itself and remove 
> _BIT from the name because it doesn't really add that much information.
> Since you're assigning to bool, ? true : false construct is not required 
> but implicit cast will handle it for you. So in the end, this line would 
> be:
>
> 	dytc_ultraperf_cap = output & DYTC_UP_SUPPORT;

Agreed. I will make that change.
I'll wait and see if there is any more feedback and then do that with a v2 patch.

>
> Looking into the driver a bit more, there are a few other defines which 
> could also move BIT() from the code into defines. Please tell if you're 
> going to look at those because if not, I might try to make the patches.

Happy to look at doing that as I'm playing around with this driver anyway.

Thanks for the review!
Mark
Ilpo Järvinen Nov. 10, 2023, 12:37 p.m. UTC | #3
On Thu, 9 Nov 2023, Mark Pearson wrote:
> On Thu, Nov 9, 2023, at 5:10 AM, Ilpo Järvinen wrote:
> > On Wed, 8 Nov 2023, Mark Pearson wrote:
> >
> >> Some new Thinkpads have a new improved performance mode available.
> >> Add support to make this mode usable.
> >> 
> >> To avoid having to create a new profile, just use the improved performance
> >> mode in place of the existing performance mode, when available.
> >> 
> >> Tested on T14 AMD G4 AMD.
> >> 
> >> Signed-off-by: Mark Pearson <mpearson-lenovo@squebb.ca>
> >> ---
> >>  drivers/platform/x86/thinkpad_acpi.c | 28 ++++++++++++++++++++++++++++
> >>  1 file changed, 28 insertions(+)
> >> 
> >> diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
> >> index ad460417f901..eba701ab340e 100644
> >> @@ -10163,11 +10165,14 @@ static struct ibm_struct proxsensor_driver_data = {
> >>  #define DYTC_MODE_MMC_LOWPOWER 3  /* Low power mode */
> >>  #define DYTC_MODE_MMC_BALANCE  0xF  /* Default mode aka balanced */
> >>  #define DYTC_MODE_MMC_DEFAULT  0  /* Default mode from MMC_GET, aka balanced */
> >> +#define DYTC_NOMODE            0xF  /* When Function does not have a mode */
> >>  
> >>  #define DYTC_MODE_PSC_LOWPOWER 3  /* Low power mode */
> >>  #define DYTC_MODE_PSC_BALANCE  5  /* Default mode aka balanced */
> >>  #define DYTC_MODE_PSC_PERFORM  7  /* High power mode aka performance */
> >>  
> >> +#define DYTC_UP_SUPPORT_BIT    8  /* Bit 8 - 1 = supported, 0 = not */
> >
> > It would be preferrable to comment what is supported rather than have a 
> > comment like above which isn't particularly helpful.
> 
> OK - so  just have:
> #define DYTC_UP_SUPPORT_BIT    8  /* Ultra-performance (TMS) mode support */
> 
> Or...reading ahead in the review this should actually be
> #define DYTC_UP_SUPPORT_BIT    BIT(8)  /* Ultra-performance (TMS) mode support */

Yes, the latter look good except I'd just drop the "_BIT" suffix from the 
name.

> >> @@ -10484,6 +10502,16 @@ static int tpacpi_dytc_profile_init(struct ibm_init_struct *iibm)
> >>  		dbg_printk(TPACPI_DBG_INIT, "No DYTC support available\n");
> >>  		return -ENODEV;
> >>  	}
> >> +	err = dytc_command(DYTC_CMD_UP_CAP, &output);
> >> +	dytc_ultraperf_cap = output & BIT(DYTC_UP_SUPPORT_BIT) ? true : false;
> >
> > It would be better to put this BIT() into the define itself and remove 
> > _BIT from the name because it doesn't really add that much information.
> > Since you're assigning to bool, ? true : false construct is not required 
> > but implicit cast will handle it for you. So in the end, this line would 
> > be:
> >
> > 	dytc_ultraperf_cap = output & DYTC_UP_SUPPORT;
> 
> Agreed. I will make that change.
> I'll wait and see if there is any more feedback and then do that with a v2 patch.
> 
> >
> > Looking into the driver a bit more, there are a few other defines which 
> > could also move BIT() from the code into defines. Please tell if you're 
> > going to look at those because if not, I might try to make the patches.
> 
> Happy to look at doing that as I'm playing around with this driver anyway.

Okay, thanks.
Mark Pearson Nov. 13, 2023, 2 p.m. UTC | #4
Hi Ilpo

On Fri, Nov 10, 2023, at 7:37 AM, Ilpo Järvinen wrote:
> On Thu, 9 Nov 2023, Mark Pearson wrote:
>> On Thu, Nov 9, 2023, at 5:10 AM, Ilpo Järvinen wrote:
>> > On Wed, 8 Nov 2023, Mark Pearson wrote:
<snip>
>> 
>> >
>> > Looking into the driver a bit more, there are a few other defines which 
>> > could also move BIT() from the code into defines. Please tell if you're 
>> > going to look at those because if not, I might try to make the patches.
>> 
>> Happy to look at doing that as I'm playing around with this driver anyway.
>
> Okay, thanks.
>
Just a quick note - I pushed v2 for this patch, and I'll tackle the other BIT changes separately (rather than adding it as part of a series). Looking through the code I wanted to spend more time on that piece - I'm not ignoring it :)

Mark
Ilpo Järvinen Nov. 13, 2023, 2:24 p.m. UTC | #5
On Mon, 13 Nov 2023, Mark Pearson wrote:
> On Fri, Nov 10, 2023, at 7:37 AM, Ilpo Järvinen wrote:
> > On Thu, 9 Nov 2023, Mark Pearson wrote:
> >> On Thu, Nov 9, 2023, at 5:10 AM, Ilpo Järvinen wrote:
> >> > On Wed, 8 Nov 2023, Mark Pearson wrote:
> <snip>
> >> 
> >> >
> >> > Looking into the driver a bit more, there are a few other defines which 
> >> > could also move BIT() from the code into defines. Please tell if you're 
> >> > going to look at those because if not, I might try to make the patches.
> >> 
> >> Happy to look at doing that as I'm playing around with this driver anyway.
> >
> > Okay, thanks.
> >
> Just a quick note - I pushed v2 for this patch, and I'll tackle the 
> other BIT changes separately (rather than adding it as part of a 
> series). Looking through the code I wanted to spend more time on that 
> piece - I'm not ignoring it :) 

Yeah, no problem. I was expecting it separately anyway. :-)
diff mbox series

Patch

diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index ad460417f901..eba701ab340e 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -10136,6 +10136,7 @@  static struct ibm_struct proxsensor_driver_data = {
 
 #define DYTC_CMD_SET          1 /* To enable/disable IC function mode */
 #define DYTC_CMD_MMC_GET      8 /* To get current MMC function and mode */
+#define DYTC_CMD_UP_CAP     0xA /* To get Ultra-performance capability */
 #define DYTC_CMD_RESET    0x1ff /* To reset back to default */
 
 #define DYTC_CMD_FUNC_CAP     3 /* To get DYTC capabilities */
@@ -10152,6 +10153,7 @@  static struct ibm_struct proxsensor_driver_data = {
 
 #define DYTC_FUNCTION_STD     0  /* Function = 0, standard mode */
 #define DYTC_FUNCTION_CQL     1  /* Function = 1, lap mode */
+#define DYTC_FUNCTION_TMS     9  /* Function = 9, TMS mode */
 #define DYTC_FUNCTION_MMC     11 /* Function = 11, MMC mode */
 #define DYTC_FUNCTION_PSC     13 /* Function = 13, PSC mode */
 #define DYTC_FUNCTION_AMT     15 /* Function = 15, AMT mode */
@@ -10163,11 +10165,14 @@  static struct ibm_struct proxsensor_driver_data = {
 #define DYTC_MODE_MMC_LOWPOWER 3  /* Low power mode */
 #define DYTC_MODE_MMC_BALANCE  0xF  /* Default mode aka balanced */
 #define DYTC_MODE_MMC_DEFAULT  0  /* Default mode from MMC_GET, aka balanced */
+#define DYTC_NOMODE            0xF  /* When Function does not have a mode */
 
 #define DYTC_MODE_PSC_LOWPOWER 3  /* Low power mode */
 #define DYTC_MODE_PSC_BALANCE  5  /* Default mode aka balanced */
 #define DYTC_MODE_PSC_PERFORM  7  /* High power mode aka performance */
 
+#define DYTC_UP_SUPPORT_BIT    8  /* Bit 8 - 1 = supported, 0 = not */
+
 #define DYTC_ERR_MASK       0xF  /* Bits 0-3 in cmd result are the error result */
 #define DYTC_ERR_SUCCESS      1  /* CMD completed successful */
 
@@ -10185,6 +10190,7 @@  static enum platform_profile_option dytc_current_profile;
 static atomic_t dytc_ignore_event = ATOMIC_INIT(0);
 static DEFINE_MUTEX(dytc_mutex);
 static int dytc_capabilities;
+static bool dytc_ultraperf_cap; /* ultra performance capable */
 static bool dytc_mmc_get_available;
 static int profile_force;
 
@@ -10355,6 +10361,17 @@  static int dytc_profile_set(struct platform_profile_handler *pprof,
 	if (err)
 		goto unlock;
 
+	/* Set TMS mode appropriately (enable for performance), if available */
+	if (dytc_ultraperf_cap) {
+		int cmd;
+
+		cmd = DYTC_SET_COMMAND(DYTC_FUNCTION_TMS, DYTC_NOMODE,
+				       profile == PLATFORM_PROFILE_PERFORMANCE);
+		err = dytc_command(cmd, &output);
+		if (err)
+			return err;
+	}
+
 	if (dytc_capabilities & BIT(DYTC_FC_MMC)) {
 		if (profile == PLATFORM_PROFILE_BALANCED) {
 			/*
@@ -10429,6 +10446,7 @@  static struct platform_profile_handler dytc_profile = {
 static int tpacpi_dytc_profile_init(struct ibm_init_struct *iibm)
 {
 	int err, output;
+	int cmd;
 
 	/* Setup supported modes */
 	set_bit(PLATFORM_PROFILE_LOW_POWER, dytc_profile.choices);
@@ -10484,6 +10502,16 @@  static int tpacpi_dytc_profile_init(struct ibm_init_struct *iibm)
 		dbg_printk(TPACPI_DBG_INIT, "No DYTC support available\n");
 		return -ENODEV;
 	}
+	err = dytc_command(DYTC_CMD_UP_CAP, &output);
+	dytc_ultraperf_cap = output & BIT(DYTC_UP_SUPPORT_BIT) ? true : false;
+	if (dytc_ultraperf_cap) {
+		pr_debug("TMS is supported\n");
+		/* Disable TMS by default - only use with performance mode */
+		cmd = DYTC_SET_COMMAND(DYTC_FUNCTION_TMS, DYTC_NOMODE, 0);
+		err = dytc_command(cmd, &output);
+		if (err)
+			return err;
+	}
 
 	dbg_printk(TPACPI_DBG_INIT,
 			"DYTC version %d: thermal mode available\n", dytc_version);