Re: [PATCH] drm/i915/slpc: Use platform limits for min/max frequency

2022-10-13 Thread Belgaumkar, Vinay



On 10/13/2022 8:14 AM, Das, Nirmoy wrote:


On 10/12/2022 8:26 PM, Vinay Belgaumkar wrote:

GuC will set the min/max frequencies to theoretical max on
ATS-M. This will break kernel ABI, so limit min/max frequency
to RP0(platform max) instead.

Also modify the SLPC selftest to update the min frequency
when we have a server part so that we can iterate between
platform min and max.

Signed-off-by: Vinay Belgaumkar 
---
  drivers/gpu/drm/i915/gt/selftest_slpc.c   | 40 +--
  drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c   | 29 ++
  .../gpu/drm/i915/gt/uc/intel_guc_slpc_types.h |  3 ++
  3 files changed, 60 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/selftest_slpc.c 
b/drivers/gpu/drm/i915/gt/selftest_slpc.c

index 4c6e9257e593..1f84362af737 100644
--- a/drivers/gpu/drm/i915/gt/selftest_slpc.c
+++ b/drivers/gpu/drm/i915/gt/selftest_slpc.c
@@ -234,6 +234,7 @@ static int run_test(struct intel_gt *gt, int 
test_type)

  enum intel_engine_id id;
  struct igt_spinner spin;
  u32 slpc_min_freq, slpc_max_freq;
+    u32 saved_min_freq;
  int err = 0;
    if (!intel_uc_uses_guc_slpc(>uc))
@@ -252,20 +253,35 @@ static int run_test(struct intel_gt *gt, int 
test_type)

  return -EIO;
  }
  -    /*
- * FIXME: With efficient frequency enabled, GuC can request
- * frequencies higher than the SLPC max. While this is fixed
- * in GuC, we level set these tests with RPn as min.
- */
-    err = slpc_set_min_freq(slpc, slpc->min_freq);
-    if (err)
-    return err;
-
  if (slpc->min_freq == slpc->rp0_freq) {
-    pr_err("Min/Max are fused to the same value\n");
-    return -EINVAL;
+    /* Servers will have min/max clamped to RP0 */



This should be "server parts". Tested the patch with Riana's suggested 
changes.


Acked-by: Nirmoy Das  with above changes.


Thanks, v2 sent with corrections.

Vinay.




Nirmoy


+    if (slpc->min_is_rpmax) {
+    err = slpc_set_min_freq(slpc, slpc->min_freq);
+    if (err) {
+    pr_err("Unable to update min freq on server part");
+    return err;
+    }
+
+    } else {
+    pr_err("Min/Max are fused to the same value\n");
+    return -EINVAL;
+    }
+    } else {
+    /*
+ * FIXME: With efficient frequency enabled, GuC can request
+ * frequencies higher than the SLPC max. While this is fixed
+ * in GuC, we level set these tests with RPn as min.
+ */
+    err = slpc_set_min_freq(slpc, slpc->min_freq);
+    if (err)
+    return err;
  }
  +    saved_min_freq = slpc_min_freq;
+
+    /* New temp min freq = RPn */
+    slpc_min_freq = slpc->min_freq;
+
  intel_gt_pm_wait_for_idle(gt);
  intel_gt_pm_get(gt);
  for_each_engine(engine, gt, id) {
@@ -347,7 +363,7 @@ static int run_test(struct intel_gt *gt, int 
test_type)

    /* Restore min/max frequencies */
  slpc_set_max_freq(slpc, slpc_max_freq);
-    slpc_set_min_freq(slpc, slpc_min_freq);
+    slpc_set_min_freq(slpc, saved_min_freq);
    if (igt_flush_test(gt->i915))
  err = -EIO;
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c

index fdd895f73f9f..11613d373a49 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
@@ -263,6 +263,7 @@ int intel_guc_slpc_init(struct intel_guc_slpc *slpc)
    slpc->max_freq_softlimit = 0;
  slpc->min_freq_softlimit = 0;
+    slpc->min_is_rpmax = false;
    slpc->boost_freq = 0;
  atomic_set(>num_waiters, 0);
@@ -588,6 +589,31 @@ static int slpc_set_softlimits(struct 
intel_guc_slpc *slpc)

  return 0;
  }
  +static bool is_slpc_min_freq_rpmax(struct intel_guc_slpc *slpc)
+{
+    int slpc_min_freq;
+
+    if (intel_guc_slpc_get_min_freq(slpc, _min_freq))
+    return false;
+
+    if (slpc_min_freq > slpc->rp0_freq)
+    return true;
+    else
+    return false;
+}
+
+static void update_server_min_softlimit(struct intel_guc_slpc *slpc)
+{
+    /* For server parts, SLPC min will be at RPMax.
+ * Use min softlimit to clamp it to RP0 instead.
+ */
+    if (is_slpc_min_freq_rpmax(slpc) &&
+    !slpc->min_freq_softlimit) {
+    slpc->min_is_rpmax = true;
+    slpc->min_freq_softlimit = slpc->rp0_freq;
+    }
+}
+
  static int slpc_use_fused_rp0(struct intel_guc_slpc *slpc)
  {
  /* Force SLPC to used platform rp0 */
@@ -647,6 +673,9 @@ int intel_guc_slpc_enable(struct intel_guc_slpc 
*slpc)

    slpc_get_rp_values(slpc);
  +    /* Handle the case where min=max=RPmax */
+    update_server_min_softlimit(slpc);
+
  /* Set SLPC max limit to RP0 */
  ret = slpc_use_fused_rp0(slpc);
  if (unlikely(ret)) {
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc_types.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc_types.h

index 73d208123528..a6ef53b04e04 100644
--- 

Re: [Intel-gfx] [PATCH] drm/i915/slpc: Use platform limits for min/max frequency

2022-10-13 Thread Belgaumkar, Vinay



On 10/13/2022 4:34 AM, Tauro, Riana wrote:



On 10/12/2022 11:56 PM, Vinay Belgaumkar wrote:

GuC will set the min/max frequencies to theoretical max on
ATS-M. This will break kernel ABI, so limit min/max frequency
to RP0(platform max) instead.

Also modify the SLPC selftest to update the min frequency
when we have a server part so that we can iterate between
platform min and max.

Signed-off-by: Vinay Belgaumkar 
---
  drivers/gpu/drm/i915/gt/selftest_slpc.c   | 40 +--
  drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c   | 29 ++
  .../gpu/drm/i915/gt/uc/intel_guc_slpc_types.h |  3 ++
  3 files changed, 60 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/selftest_slpc.c 
b/drivers/gpu/drm/i915/gt/selftest_slpc.c

index 4c6e9257e593..1f84362af737 100644
--- a/drivers/gpu/drm/i915/gt/selftest_slpc.c
+++ b/drivers/gpu/drm/i915/gt/selftest_slpc.c
@@ -234,6 +234,7 @@ static int run_test(struct intel_gt *gt, int 
test_type)

  enum intel_engine_id id;
  struct igt_spinner spin;
  u32 slpc_min_freq, slpc_max_freq;
+    u32 saved_min_freq;
  int err = 0;
    if (!intel_uc_uses_guc_slpc(>uc))
@@ -252,20 +253,35 @@ static int run_test(struct intel_gt *gt, int 
test_type)

  return -EIO;
  }
  -    /*
- * FIXME: With efficient frequency enabled, GuC can request
- * frequencies higher than the SLPC max. While this is fixed
- * in GuC, we level set these tests with RPn as min.
- */
-    err = slpc_set_min_freq(slpc, slpc->min_freq);
-    if (err)
-    return err;
-
  if (slpc->min_freq == slpc->rp0_freq) {

This has to be (slpc_min_freq == slpc_max_freq) instead of
(slpc->min_freq == slpc->rp0_freq).

Servers will have min/max softlimits clamped to RP0


Agree. will send out v2.

Thanks,

Vinay.



Thanks
Riana

-    pr_err("Min/Max are fused to the same value\n");
-    return -EINVAL;
+    /* Servers will have min/max clamped to RP0 */
+    if (slpc->min_is_rpmax) {
+    err = slpc_set_min_freq(slpc, slpc->min_freq);
+    if (err) {
+    pr_err("Unable to update min freq on server part");
+    return err;
+    }
+
+    } else {
+    pr_err("Min/Max are fused to the same value\n");
+    return -EINVAL;
+    }
+    } else {
+    /*
+ * FIXME: With efficient frequency enabled, GuC can request
+ * frequencies higher than the SLPC max. While this is fixed
+ * in GuC, we level set these tests with RPn as min.
+ */
+    err = slpc_set_min_freq(slpc, slpc->min_freq);
+    if (err)
+    return err;
  }
  +    saved_min_freq = slpc_min_freq;
+
+    /* New temp min freq = RPn */
+    slpc_min_freq = slpc->min_freq;
+
  intel_gt_pm_wait_for_idle(gt);
  intel_gt_pm_get(gt);
  for_each_engine(engine, gt, id) {
@@ -347,7 +363,7 @@ static int run_test(struct intel_gt *gt, int 
test_type)

    /* Restore min/max frequencies */
  slpc_set_max_freq(slpc, slpc_max_freq);
-    slpc_set_min_freq(slpc, slpc_min_freq);
+    slpc_set_min_freq(slpc, saved_min_freq);
    if (igt_flush_test(gt->i915))
  err = -EIO;
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c

index fdd895f73f9f..11613d373a49 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
@@ -263,6 +263,7 @@ int intel_guc_slpc_init(struct intel_guc_slpc *slpc)
    slpc->max_freq_softlimit = 0;
  slpc->min_freq_softlimit = 0;
+    slpc->min_is_rpmax = false;
    slpc->boost_freq = 0;
  atomic_set(>num_waiters, 0);
@@ -588,6 +589,31 @@ static int slpc_set_softlimits(struct 
intel_guc_slpc *slpc)

  return 0;
  }
  +static bool is_slpc_min_freq_rpmax(struct intel_guc_slpc *slpc)
+{
+    int slpc_min_freq;
+
+    if (intel_guc_slpc_get_min_freq(slpc, _min_freq))
+    return false;
+
+    if (slpc_min_freq > slpc->rp0_freq)
+    return true;
+    else
+    return false;
+}
+
+static void update_server_min_softlimit(struct intel_guc_slpc *slpc)
+{
+    /* For server parts, SLPC min will be at RPMax.
+ * Use min softlimit to clamp it to RP0 instead.
+ */
+    if (is_slpc_min_freq_rpmax(slpc) &&
+    !slpc->min_freq_softlimit) {
+    slpc->min_is_rpmax = true;
+    slpc->min_freq_softlimit = slpc->rp0_freq;
+    }
+}
+
  static int slpc_use_fused_rp0(struct intel_guc_slpc *slpc)
  {
  /* Force SLPC to used platform rp0 */
@@ -647,6 +673,9 @@ int intel_guc_slpc_enable(struct intel_guc_slpc 
*slpc)

    slpc_get_rp_values(slpc);
  +    /* Handle the case where min=max=RPmax */
+    update_server_min_softlimit(slpc);
+
  /* Set SLPC max limit to RP0 */
  ret = slpc_use_fused_rp0(slpc);
  if (unlikely(ret)) {
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc_types.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc_types.h

index 

Re: [PATCH] drm/i915/slpc: Use platform limits for min/max frequency

2022-10-13 Thread Das, Nirmoy



On 10/12/2022 8:26 PM, Vinay Belgaumkar wrote:

GuC will set the min/max frequencies to theoretical max on
ATS-M. This will break kernel ABI, so limit min/max frequency
to RP0(platform max) instead.

Also modify the SLPC selftest to update the min frequency
when we have a server part so that we can iterate between
platform min and max.

Signed-off-by: Vinay Belgaumkar 
---
  drivers/gpu/drm/i915/gt/selftest_slpc.c   | 40 +--
  drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c   | 29 ++
  .../gpu/drm/i915/gt/uc/intel_guc_slpc_types.h |  3 ++
  3 files changed, 60 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/selftest_slpc.c 
b/drivers/gpu/drm/i915/gt/selftest_slpc.c
index 4c6e9257e593..1f84362af737 100644
--- a/drivers/gpu/drm/i915/gt/selftest_slpc.c
+++ b/drivers/gpu/drm/i915/gt/selftest_slpc.c
@@ -234,6 +234,7 @@ static int run_test(struct intel_gt *gt, int test_type)
enum intel_engine_id id;
struct igt_spinner spin;
u32 slpc_min_freq, slpc_max_freq;
+   u32 saved_min_freq;
int err = 0;
  
  	if (!intel_uc_uses_guc_slpc(>uc))

@@ -252,20 +253,35 @@ static int run_test(struct intel_gt *gt, int test_type)
return -EIO;
}
  
-	/*

-* FIXME: With efficient frequency enabled, GuC can request
-* frequencies higher than the SLPC max. While this is fixed
-* in GuC, we level set these tests with RPn as min.
-*/
-   err = slpc_set_min_freq(slpc, slpc->min_freq);
-   if (err)
-   return err;
-
if (slpc->min_freq == slpc->rp0_freq) {
-   pr_err("Min/Max are fused to the same value\n");
-   return -EINVAL;
+   /* Servers will have min/max clamped to RP0 */



This should be "server parts". Tested the patch with Riana's suggested 
changes.


Acked-by: Nirmoy Das  with above changes.


Nirmoy


+   if (slpc->min_is_rpmax) {
+   err = slpc_set_min_freq(slpc, slpc->min_freq);
+   if (err) {
+   pr_err("Unable to update min freq on server 
part");
+   return err;
+   }
+
+   } else {
+   pr_err("Min/Max are fused to the same value\n");
+   return -EINVAL;
+   }
+   } else {
+   /*
+* FIXME: With efficient frequency enabled, GuC can request
+* frequencies higher than the SLPC max. While this is fixed
+* in GuC, we level set these tests with RPn as min.
+*/
+   err = slpc_set_min_freq(slpc, slpc->min_freq);
+   if (err)
+   return err;
}
  
+	saved_min_freq = slpc_min_freq;

+
+   /* New temp min freq = RPn */
+   slpc_min_freq = slpc->min_freq;
+
intel_gt_pm_wait_for_idle(gt);
intel_gt_pm_get(gt);
for_each_engine(engine, gt, id) {
@@ -347,7 +363,7 @@ static int run_test(struct intel_gt *gt, int test_type)
  
  	/* Restore min/max frequencies */

slpc_set_max_freq(slpc, slpc_max_freq);
-   slpc_set_min_freq(slpc, slpc_min_freq);
+   slpc_set_min_freq(slpc, saved_min_freq);
  
  	if (igt_flush_test(gt->i915))

err = -EIO;
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
index fdd895f73f9f..11613d373a49 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
@@ -263,6 +263,7 @@ int intel_guc_slpc_init(struct intel_guc_slpc *slpc)
  
  	slpc->max_freq_softlimit = 0;

slpc->min_freq_softlimit = 0;
+   slpc->min_is_rpmax = false;
  
  	slpc->boost_freq = 0;

atomic_set(>num_waiters, 0);
@@ -588,6 +589,31 @@ static int slpc_set_softlimits(struct intel_guc_slpc *slpc)
return 0;
  }
  
+static bool is_slpc_min_freq_rpmax(struct intel_guc_slpc *slpc)

+{
+   int slpc_min_freq;
+
+   if (intel_guc_slpc_get_min_freq(slpc, _min_freq))
+   return false;
+
+   if (slpc_min_freq > slpc->rp0_freq)
+   return true;
+   else
+   return false;
+}
+
+static void update_server_min_softlimit(struct intel_guc_slpc *slpc)
+{
+   /* For server parts, SLPC min will be at RPMax.
+* Use min softlimit to clamp it to RP0 instead.
+*/
+   if (is_slpc_min_freq_rpmax(slpc) &&
+   !slpc->min_freq_softlimit) {
+   slpc->min_is_rpmax = true;
+   slpc->min_freq_softlimit = slpc->rp0_freq;
+   }
+}
+
  static int slpc_use_fused_rp0(struct intel_guc_slpc *slpc)
  {
/* Force SLPC to used platform rp0 */
@@ -647,6 +673,9 @@ int intel_guc_slpc_enable(struct intel_guc_slpc *slpc)
  
  	slpc_get_rp_values(slpc);
  
+	/* Handle the case where min=max=RPmax */

+   update_server_min_softlimit(slpc);
+
/* Set SLPC max limit 

Re: [Intel-gfx] [PATCH] drm/i915/slpc: Use platform limits for min/max frequency

2022-10-13 Thread Tauro, Riana




On 10/12/2022 11:56 PM, Vinay Belgaumkar wrote:

GuC will set the min/max frequencies to theoretical max on
ATS-M. This will break kernel ABI, so limit min/max frequency
to RP0(platform max) instead.

Also modify the SLPC selftest to update the min frequency
when we have a server part so that we can iterate between
platform min and max.

Signed-off-by: Vinay Belgaumkar 
---
  drivers/gpu/drm/i915/gt/selftest_slpc.c   | 40 +--
  drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c   | 29 ++
  .../gpu/drm/i915/gt/uc/intel_guc_slpc_types.h |  3 ++
  3 files changed, 60 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/selftest_slpc.c 
b/drivers/gpu/drm/i915/gt/selftest_slpc.c
index 4c6e9257e593..1f84362af737 100644
--- a/drivers/gpu/drm/i915/gt/selftest_slpc.c
+++ b/drivers/gpu/drm/i915/gt/selftest_slpc.c
@@ -234,6 +234,7 @@ static int run_test(struct intel_gt *gt, int test_type)
enum intel_engine_id id;
struct igt_spinner spin;
u32 slpc_min_freq, slpc_max_freq;
+   u32 saved_min_freq;
int err = 0;
  
  	if (!intel_uc_uses_guc_slpc(>uc))

@@ -252,20 +253,35 @@ static int run_test(struct intel_gt *gt, int test_type)
return -EIO;
}
  
-	/*

-* FIXME: With efficient frequency enabled, GuC can request
-* frequencies higher than the SLPC max. While this is fixed
-* in GuC, we level set these tests with RPn as min.
-*/
-   err = slpc_set_min_freq(slpc, slpc->min_freq);
-   if (err)
-   return err;
-
if (slpc->min_freq == slpc->rp0_freq) {

This has to be (slpc_min_freq == slpc_max_freq) instead of
(slpc->min_freq == slpc->rp0_freq).

Servers will have min/max softlimits clamped to RP0

Thanks
Riana

-   pr_err("Min/Max are fused to the same value\n");
-   return -EINVAL;
+   /* Servers will have min/max clamped to RP0 */
+   if (slpc->min_is_rpmax) {
+   err = slpc_set_min_freq(slpc, slpc->min_freq);
+   if (err) {
+   pr_err("Unable to update min freq on server 
part");
+   return err;
+   }
+
+   } else {
+   pr_err("Min/Max are fused to the same value\n");
+   return -EINVAL;
+   }
+   } else {
+   /*
+* FIXME: With efficient frequency enabled, GuC can request
+* frequencies higher than the SLPC max. While this is fixed
+* in GuC, we level set these tests with RPn as min.
+*/
+   err = slpc_set_min_freq(slpc, slpc->min_freq);
+   if (err)
+   return err;
}
  
+	saved_min_freq = slpc_min_freq;

+
+   /* New temp min freq = RPn */
+   slpc_min_freq = slpc->min_freq;
+
intel_gt_pm_wait_for_idle(gt);
intel_gt_pm_get(gt);
for_each_engine(engine, gt, id) {
@@ -347,7 +363,7 @@ static int run_test(struct intel_gt *gt, int test_type)
  
  	/* Restore min/max frequencies */

slpc_set_max_freq(slpc, slpc_max_freq);
-   slpc_set_min_freq(slpc, slpc_min_freq);
+   slpc_set_min_freq(slpc, saved_min_freq);
  
  	if (igt_flush_test(gt->i915))

err = -EIO;
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
index fdd895f73f9f..11613d373a49 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
@@ -263,6 +263,7 @@ int intel_guc_slpc_init(struct intel_guc_slpc *slpc)
  
  	slpc->max_freq_softlimit = 0;

slpc->min_freq_softlimit = 0;
+   slpc->min_is_rpmax = false;
  
  	slpc->boost_freq = 0;

atomic_set(>num_waiters, 0);
@@ -588,6 +589,31 @@ static int slpc_set_softlimits(struct intel_guc_slpc *slpc)
return 0;
  }
  
+static bool is_slpc_min_freq_rpmax(struct intel_guc_slpc *slpc)

+{
+   int slpc_min_freq;
+
+   if (intel_guc_slpc_get_min_freq(slpc, _min_freq))
+   return false;
+
+   if (slpc_min_freq > slpc->rp0_freq)
+   return true;
+   else
+   return false;
+}
+
+static void update_server_min_softlimit(struct intel_guc_slpc *slpc)
+{
+   /* For server parts, SLPC min will be at RPMax.
+* Use min softlimit to clamp it to RP0 instead.
+*/
+   if (is_slpc_min_freq_rpmax(slpc) &&
+   !slpc->min_freq_softlimit) {
+   slpc->min_is_rpmax = true;
+   slpc->min_freq_softlimit = slpc->rp0_freq;
+   }
+}
+
  static int slpc_use_fused_rp0(struct intel_guc_slpc *slpc)
  {
/* Force SLPC to used platform rp0 */
@@ -647,6 +673,9 @@ int intel_guc_slpc_enable(struct intel_guc_slpc *slpc)
  
  	slpc_get_rp_values(slpc);
  
+	/* Handle the case where min=max=RPmax */

+   update_server_min_softlimit(slpc);
+
 

[PATCH] drm/i915/slpc: Use platform limits for min/max frequency

2022-10-12 Thread Vinay Belgaumkar
GuC will set the min/max frequencies to theoretical max on
ATS-M. This will break kernel ABI, so limit min/max frequency
to RP0(platform max) instead.

Also modify the SLPC selftest to update the min frequency
when we have a server part so that we can iterate between
platform min and max.

Signed-off-by: Vinay Belgaumkar 
---
 drivers/gpu/drm/i915/gt/selftest_slpc.c   | 40 +--
 drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c   | 29 ++
 .../gpu/drm/i915/gt/uc/intel_guc_slpc_types.h |  3 ++
 3 files changed, 60 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/selftest_slpc.c 
b/drivers/gpu/drm/i915/gt/selftest_slpc.c
index 4c6e9257e593..1f84362af737 100644
--- a/drivers/gpu/drm/i915/gt/selftest_slpc.c
+++ b/drivers/gpu/drm/i915/gt/selftest_slpc.c
@@ -234,6 +234,7 @@ static int run_test(struct intel_gt *gt, int test_type)
enum intel_engine_id id;
struct igt_spinner spin;
u32 slpc_min_freq, slpc_max_freq;
+   u32 saved_min_freq;
int err = 0;
 
if (!intel_uc_uses_guc_slpc(>uc))
@@ -252,20 +253,35 @@ static int run_test(struct intel_gt *gt, int test_type)
return -EIO;
}
 
-   /*
-* FIXME: With efficient frequency enabled, GuC can request
-* frequencies higher than the SLPC max. While this is fixed
-* in GuC, we level set these tests with RPn as min.
-*/
-   err = slpc_set_min_freq(slpc, slpc->min_freq);
-   if (err)
-   return err;
-
if (slpc->min_freq == slpc->rp0_freq) {
-   pr_err("Min/Max are fused to the same value\n");
-   return -EINVAL;
+   /* Servers will have min/max clamped to RP0 */
+   if (slpc->min_is_rpmax) {
+   err = slpc_set_min_freq(slpc, slpc->min_freq);
+   if (err) {
+   pr_err("Unable to update min freq on server 
part");
+   return err;
+   }
+
+   } else {
+   pr_err("Min/Max are fused to the same value\n");
+   return -EINVAL;
+   }
+   } else {
+   /*
+* FIXME: With efficient frequency enabled, GuC can request
+* frequencies higher than the SLPC max. While this is fixed
+* in GuC, we level set these tests with RPn as min.
+*/
+   err = slpc_set_min_freq(slpc, slpc->min_freq);
+   if (err)
+   return err;
}
 
+   saved_min_freq = slpc_min_freq;
+
+   /* New temp min freq = RPn */
+   slpc_min_freq = slpc->min_freq;
+
intel_gt_pm_wait_for_idle(gt);
intel_gt_pm_get(gt);
for_each_engine(engine, gt, id) {
@@ -347,7 +363,7 @@ static int run_test(struct intel_gt *gt, int test_type)
 
/* Restore min/max frequencies */
slpc_set_max_freq(slpc, slpc_max_freq);
-   slpc_set_min_freq(slpc, slpc_min_freq);
+   slpc_set_min_freq(slpc, saved_min_freq);
 
if (igt_flush_test(gt->i915))
err = -EIO;
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
index fdd895f73f9f..11613d373a49 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
@@ -263,6 +263,7 @@ int intel_guc_slpc_init(struct intel_guc_slpc *slpc)
 
slpc->max_freq_softlimit = 0;
slpc->min_freq_softlimit = 0;
+   slpc->min_is_rpmax = false;
 
slpc->boost_freq = 0;
atomic_set(>num_waiters, 0);
@@ -588,6 +589,31 @@ static int slpc_set_softlimits(struct intel_guc_slpc *slpc)
return 0;
 }
 
+static bool is_slpc_min_freq_rpmax(struct intel_guc_slpc *slpc)
+{
+   int slpc_min_freq;
+
+   if (intel_guc_slpc_get_min_freq(slpc, _min_freq))
+   return false;
+
+   if (slpc_min_freq > slpc->rp0_freq)
+   return true;
+   else
+   return false;
+}
+
+static void update_server_min_softlimit(struct intel_guc_slpc *slpc)
+{
+   /* For server parts, SLPC min will be at RPMax.
+* Use min softlimit to clamp it to RP0 instead.
+*/
+   if (is_slpc_min_freq_rpmax(slpc) &&
+   !slpc->min_freq_softlimit) {
+   slpc->min_is_rpmax = true;
+   slpc->min_freq_softlimit = slpc->rp0_freq;
+   }
+}
+
 static int slpc_use_fused_rp0(struct intel_guc_slpc *slpc)
 {
/* Force SLPC to used platform rp0 */
@@ -647,6 +673,9 @@ int intel_guc_slpc_enable(struct intel_guc_slpc *slpc)
 
slpc_get_rp_values(slpc);
 
+   /* Handle the case where min=max=RPmax */
+   update_server_min_softlimit(slpc);
+
/* Set SLPC max limit to RP0 */
ret = slpc_use_fused_rp0(slpc);
if (unlikely(ret)) {
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc_types.h