diff mbox series

Add support for DYTC MMC_GET BIOS API.

Message ID 20210406022215.199998-1-markpearson@lenovo.com (mailing list archive)
State Superseded, archived
Headers show
Series Add support for DYTC MMC_GET BIOS API. | expand

Commit Message

Mark Pearson April 6, 2021, 2:22 a.m. UTC
The BIOS team have added a new API that allows us to retrieve the
current performance profile without having to disable/enable CQL
mode. Adding the changes to use this API.

Tested on P15 and X1C8

Signed-off-by: Mark Pearson <markpearson@lenovo.com>
---
 drivers/platform/x86/thinkpad_acpi.c | 24 ++++++++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)

Comments

Hans de Goede April 6, 2021, 1:50 p.m. UTC | #1
Hi,

On 4/6/21 4:22 AM, Mark Pearson wrote:
> The BIOS team have added a new API that allows us to retrieve the
> current performance profile without having to disable/enable CQL
> mode. Adding the changes to use this API.
> 
> Tested on P15 and X1C8
> 
> Signed-off-by: Mark Pearson <markpearson@lenovo.com>
> ---
>  drivers/platform/x86/thinkpad_acpi.c | 24 ++++++++++++++++++++++--
>  1 file changed, 22 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
> index 0d9e2ddbf..4eb1ad443 100644
> --- a/drivers/platform/x86/thinkpad_acpi.c
> +++ b/drivers/platform/x86/thinkpad_acpi.c
> @@ -10050,6 +10050,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_RESET    0x1ff /* To reset back to default */
>  
>  #define DYTC_GET_FUNCTION_BIT 8  /* Bits  8-11 - function setting */
> @@ -10066,6 +10067,10 @@ static struct ibm_struct proxsensor_driver_data = {
>  #define DYTC_MODE_PERFORM     2  /* High power mode aka performance */
>  #define DYTC_MODE_LOWPOWER    3  /* Low power mode */
>  #define DYTC_MODE_BALANCE   0xF  /* Default mode aka balanced */
> +#define DYTC_MODE_MMC_BALANCE 0  /* Default mode from MMC_GET, aka balanced */
> +
> +#define DYTC_ERR_MASK       0xF  /* Bits 0-3 in cmd result are the error result */
> +#define DYTC_ERR_SUCCESS      1  /* CMD completed successful */
>  
>  #define DYTC_SET_COMMAND(function, mode, on) \
>  	(DYTC_CMD_SET | (function) << DYTC_SET_FUNCTION_BIT | \
> @@ -10080,6 +10085,7 @@ static bool dytc_profile_available;
>  static enum platform_profile_option dytc_current_profile;
>  static atomic_t dytc_ignore_event = ATOMIC_INIT(0);
>  static DEFINE_MUTEX(dytc_mutex);
> +static bool dytc_mmc_get_available;
>  
>  static int convert_dytc_to_profile(int dytcmode, enum platform_profile_option *profile)
>  {
> @@ -10088,6 +10094,7 @@ static int convert_dytc_to_profile(int dytcmode, enum platform_profile_option *p
>  		*profile = PLATFORM_PROFILE_LOW_POWER;
>  		break;
>  	case DYTC_MODE_BALANCE:
> +	case DYTC_MODE_MMC_BALANCE:
>  		*profile =  PLATFORM_PROFILE_BALANCED;
>  		break;
>  	case DYTC_MODE_PERFORM:
> @@ -10165,7 +10172,6 @@ static int dytc_cql_command(int command, int *output)
>  		if (err)
>  			return err;
>  	}
> -
>  	return cmd_err;
>  }
>  
> @@ -10222,7 +10228,10 @@ static void dytc_profile_refresh(void)
>  	int perfmode;
>  
>  	mutex_lock(&dytc_mutex);
> -	err = dytc_cql_command(DYTC_CMD_GET, &output);
> +	if (dytc_mmc_get_available)
> +		err = dytc_command(DYTC_CMD_MMC_GET, &output);
> +	else
> +		err = dytc_cql_command(DYTC_CMD_GET, &output);
>  	mutex_unlock(&dytc_mutex);
>  	if (err)
>  		return;
> @@ -10271,6 +10280,17 @@ static int tpacpi_dytc_profile_init(struct ibm_init_struct *iibm)
>  	if (dytc_version >= 5) {
>  		dbg_printk(TPACPI_DBG_INIT,
>  				"DYTC version %d: thermal mode available\n", dytc_version);
> +		/*
> +		 * Check if MMC_GET functionality available
> +		 * Version > 6 and return success from MMC_GET command
> +		 */
> +		dytc_mmc_get_available = false;
> +		if (dytc_version >= 6) {
> +			err = dytc_command(DYTC_CMD_MMC_GET, &output);
> +			if (!err && ((output & DYTC_ERR_MASK) == DYTC_ERR_SUCCESS))
> +				dytc_mmc_get_available = true;
> +		}
> +		err = dytc_command(DYTC_CMD_QUERY, &output);

It seems this last:

		err = dytc_command(DYTC_CMD_QUERY, &output);

Line snuck in as a copy and paste error? Or is this intentional ?

If this is intentional, may I ask why this is done / needed ?

Regards,

Hans


>  		/* Create platform_profile structure and register */
>  		err = platform_profile_register(&dytc_profile);
>  		/*
>
Mark Pearson April 6, 2021, 3:25 p.m. UTC | #2
On 06/04/2021 09:50, Hans de Goede wrote:
> Hi,
> 
> On 4/6/21 4:22 AM, Mark Pearson wrote:
>> The BIOS team have added a new API that allows us to retrieve the 
>> current performance profile without having to disable/enable CQL 
>> mode. Adding the changes to use this API.
>> 
>> Tested on P15 and X1C8
>> 
>> Signed-off-by: Mark Pearson <markpearson@lenovo.com> --- 
>> drivers/platform/x86/thinkpad_acpi.c | 24 ++++++++++++++++++++++-- 
>> 1 file changed, 22 insertions(+), 2 deletions(-)
>> 
>> diff --git a/drivers/platform/x86/thinkpad_acpi.c
>> b/drivers/platform/x86/thinkpad_acpi.c index 0d9e2ddbf..4eb1ad443
>> 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++
>> b/drivers/platform/x86/thinkpad_acpi.c @@ -10050,6 +10050,7 @@
>> static struct ibm_struct proxsensor_driver_data = { */
>> 
<snip>

>> @@ -10271,6 +10280,17 @@ static int tpacpi_dytc_profile_init(struct
>> ibm_init_struct *iibm) if (dytc_version >= 5) { 
>> dbg_printk(TPACPI_DBG_INIT, "DYTC version %d: thermal mode
>> available\n", dytc_version); +		/* +		 * Check if MMC_GET
>> functionality available +		 * Version > 6 and return success from
>> MMC_GET command +		 */ +		dytc_mmc_get_available = false; +		if
>> (dytc_version >= 6) { +			err = dytc_command(DYTC_CMD_MMC_GET,
>> &output); +			if (!err && ((output & DYTC_ERR_MASK) ==
>> DYTC_ERR_SUCCESS)) +				dytc_mmc_get_available = true; +		} +		err
>> = dytc_command(DYTC_CMD_QUERY, &output);
> 
> It seems this last:
> 
> err = dytc_command(DYTC_CMD_QUERY, &output);
> 
> Line snuck in as a copy and paste error? Or is this intentional ?
> 
> If this is intentional, may I ask why this is done / needed ?
> 
Well that's embarrassing - that is left over from some debug I
was running and it shouldn't be there.

I'll submit a new version with that removed.

Apologies - should have caught that one before pushing for review

Mark
diff mbox series

Patch

diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index 0d9e2ddbf..4eb1ad443 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -10050,6 +10050,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_RESET    0x1ff /* To reset back to default */
 
 #define DYTC_GET_FUNCTION_BIT 8  /* Bits  8-11 - function setting */
@@ -10066,6 +10067,10 @@  static struct ibm_struct proxsensor_driver_data = {
 #define DYTC_MODE_PERFORM     2  /* High power mode aka performance */
 #define DYTC_MODE_LOWPOWER    3  /* Low power mode */
 #define DYTC_MODE_BALANCE   0xF  /* Default mode aka balanced */
+#define DYTC_MODE_MMC_BALANCE 0  /* Default mode from MMC_GET, aka balanced */
+
+#define DYTC_ERR_MASK       0xF  /* Bits 0-3 in cmd result are the error result */
+#define DYTC_ERR_SUCCESS      1  /* CMD completed successful */
 
 #define DYTC_SET_COMMAND(function, mode, on) \
 	(DYTC_CMD_SET | (function) << DYTC_SET_FUNCTION_BIT | \
@@ -10080,6 +10085,7 @@  static bool dytc_profile_available;
 static enum platform_profile_option dytc_current_profile;
 static atomic_t dytc_ignore_event = ATOMIC_INIT(0);
 static DEFINE_MUTEX(dytc_mutex);
+static bool dytc_mmc_get_available;
 
 static int convert_dytc_to_profile(int dytcmode, enum platform_profile_option *profile)
 {
@@ -10088,6 +10094,7 @@  static int convert_dytc_to_profile(int dytcmode, enum platform_profile_option *p
 		*profile = PLATFORM_PROFILE_LOW_POWER;
 		break;
 	case DYTC_MODE_BALANCE:
+	case DYTC_MODE_MMC_BALANCE:
 		*profile =  PLATFORM_PROFILE_BALANCED;
 		break;
 	case DYTC_MODE_PERFORM:
@@ -10165,7 +10172,6 @@  static int dytc_cql_command(int command, int *output)
 		if (err)
 			return err;
 	}
-
 	return cmd_err;
 }
 
@@ -10222,7 +10228,10 @@  static void dytc_profile_refresh(void)
 	int perfmode;
 
 	mutex_lock(&dytc_mutex);
-	err = dytc_cql_command(DYTC_CMD_GET, &output);
+	if (dytc_mmc_get_available)
+		err = dytc_command(DYTC_CMD_MMC_GET, &output);
+	else
+		err = dytc_cql_command(DYTC_CMD_GET, &output);
 	mutex_unlock(&dytc_mutex);
 	if (err)
 		return;
@@ -10271,6 +10280,17 @@  static int tpacpi_dytc_profile_init(struct ibm_init_struct *iibm)
 	if (dytc_version >= 5) {
 		dbg_printk(TPACPI_DBG_INIT,
 				"DYTC version %d: thermal mode available\n", dytc_version);
+		/*
+		 * Check if MMC_GET functionality available
+		 * Version > 6 and return success from MMC_GET command
+		 */
+		dytc_mmc_get_available = false;
+		if (dytc_version >= 6) {
+			err = dytc_command(DYTC_CMD_MMC_GET, &output);
+			if (!err && ((output & DYTC_ERR_MASK) == DYTC_ERR_SUCCESS))
+				dytc_mmc_get_available = true;
+		}
+		err = dytc_command(DYTC_CMD_QUERY, &output);
 		/* Create platform_profile structure and register */
 		err = platform_profile_register(&dytc_profile);
 		/*