drm/xe: Manually setup C6 when skip_guc_pc is set
authorVinay Belgaumkar <vinay.belgaumkar@intel.com>
Sat, 18 Nov 2023 00:14:49 +0000 (16:14 -0800)
committerRodrigo Vivi <rodrigo.vivi@intel.com>
Thu, 21 Dec 2023 16:45:08 +0000 (11:45 -0500)
Skip the init/start/stop GuC PC functions and toggle C6 using
register writes instead. Also request max possible frequency
as dynamic freq management is disabled.

v2: Fix compile warning

Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Vinay Belgaumkar <vinay.belgaumkar@intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
drivers/gpu/drm/xe/regs/xe_gt_regs.h
drivers/gpu/drm/xe/xe_gt_idle.c
drivers/gpu/drm/xe/xe_gt_idle.h
drivers/gpu/drm/xe/xe_guc_pc.c

index 18b1322..d318ec0 100644 (file)
 #define   RPSWCTL_ENABLE                       REG_FIELD_PREP(RPSWCTL_MASK, 2)
 #define   RPSWCTL_DISABLE                      REG_FIELD_PREP(RPSWCTL_MASK, 0)
 #define RC_CONTROL                             XE_REG(0xa090)
+#define   RC_CTL_HW_ENABLE                     REG_BIT(31)
+#define   RC_CTL_TO_MODE                       REG_BIT(28)
+#define   RC_CTL_RC6_ENABLE                    REG_BIT(18)
 #define RC_STATE                               XE_REG(0xa094)
+#define RC_IDLE_HYSTERSIS                      XE_REG(0xa0ac)
 
 #define PMINTRMSK                              XE_REG(0xa168)
 #define   PMINTR_DISABLE_REDIRECT_TO_GUC       REG_BIT(31)
index e5b7e5d..9358f73 100644 (file)
@@ -10,6 +10,8 @@
 #include "xe_gt_idle.h"
 #include "xe_gt_sysfs.h"
 #include "xe_guc_pc.h"
+#include "regs/xe_gt_regs.h"
+#include "xe_mmio.h"
 
 /**
  * DOC: Xe GT Idle
@@ -166,3 +168,25 @@ void xe_gt_idle_sysfs_init(struct xe_gt_idle *gtidle)
                drm_warn(&xe->drm, "%s: drmm_add_action_or_reset failed, err: %d\n",
                         __func__, err);
 }
+
+void xe_gt_idle_enable_c6(struct xe_gt *gt)
+{
+       xe_device_assert_mem_access(gt_to_xe(gt));
+       xe_force_wake_assert_held(gt_to_fw(gt), XE_FW_GT);
+
+       /* Units of 1280 ns for a total of 5s */
+       xe_mmio_write32(gt, RC_IDLE_HYSTERSIS, 0x3B9ACA);
+       /* Enable RC6 */
+       xe_mmio_write32(gt, RC_CONTROL,
+                       RC_CTL_HW_ENABLE | RC_CTL_TO_MODE | RC_CTL_RC6_ENABLE);
+}
+
+void xe_gt_idle_disable_c6(struct xe_gt *gt)
+{
+       xe_device_assert_mem_access(gt_to_xe(gt));
+       xe_force_wake_assert_held(gt_to_fw(gt), XE_FORCEWAKE_ALL);
+
+       xe_mmio_write32(gt, PG_ENABLE, 0);
+       xe_mmio_write32(gt, RC_CONTROL, 0);
+       xe_mmio_write32(gt, RC_STATE, 0);
+}
index 9b36bf7..69280fd 100644 (file)
@@ -8,6 +8,10 @@
 
 #include "xe_gt_idle_types.h"
 
+struct xe_gt;
+
 void xe_gt_idle_sysfs_init(struct xe_gt_idle *gtidle);
+void xe_gt_idle_enable_c6(struct xe_gt *gt);
+void xe_gt_idle_disable_c6(struct xe_gt *gt);
 
 #endif /* _XE_GT_IDLE_H_ */
index 2919c6a..1943893 100644 (file)
@@ -16,6 +16,7 @@
 #include "xe_bo.h"
 #include "xe_device.h"
 #include "xe_gt.h"
+#include "xe_gt_idle.h"
 #include "xe_gt_sysfs.h"
 #include "xe_gt_types.h"
 #include "xe_guc_ct.h"
@@ -869,13 +870,24 @@ int xe_guc_pc_start(struct xe_guc_pc *pc)
 
        xe_device_mem_access_get(pc_to_xe(pc));
 
-       memset(pc->bo->vmap.vaddr, 0, size);
-       slpc_shared_data_write(pc, header.size, size);
-
        ret = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL);
        if (ret)
                goto out_fail_force_wake;
 
+       if (xe->info.skip_guc_pc) {
+               if (xe->info.platform != XE_PVC)
+                       xe_gt_idle_enable_c6(gt);
+
+               /* Request max possible since dynamic freq mgmt is not enabled */
+               pc_set_cur_freq(pc, UINT_MAX);
+
+               ret = 0;
+               goto out;
+       }
+
+       memset(pc->bo->vmap.vaddr, 0, size);
+       slpc_shared_data_write(pc, header.size, size);
+
        ret = pc_action_reset(pc);
        if (ret)
                goto out;
@@ -911,10 +923,17 @@ out_fail_force_wake:
  */
 int xe_guc_pc_stop(struct xe_guc_pc *pc)
 {
+       struct xe_device *xe = pc_to_xe(pc);
        int ret;
 
        xe_device_mem_access_get(pc_to_xe(pc));
 
+       if (xe->info.skip_guc_pc) {
+               xe_gt_idle_disable_c6(pc_to_gt(pc));
+               ret = 0;
+               goto out;
+       }
+
        mutex_lock(&pc->freq_lock);
        pc->freq_ready = false;
        mutex_unlock(&pc->freq_lock);
@@ -935,6 +954,13 @@ out:
 
 void xe_guc_pc_fini(struct xe_guc_pc *pc)
 {
+       struct xe_device *xe = pc_to_xe(pc);
+
+       if (xe->info.skip_guc_pc) {
+               xe_gt_idle_disable_c6(pc_to_gt(pc));
+               return;
+       }
+
        XE_WARN_ON(xe_guc_pc_gucrc_disable(pc));
        XE_WARN_ON(xe_guc_pc_stop(pc));
        sysfs_remove_files(pc_to_gt(pc)->sysfs, pc_attrs);
@@ -955,6 +981,9 @@ int xe_guc_pc_init(struct xe_guc_pc *pc)
        u32 size = PAGE_ALIGN(sizeof(struct slpc_shared_data));
        int err;
 
+       if (xe->info.skip_guc_pc)
+               return 0;
+
        mutex_init(&pc->freq_lock);
 
        bo = xe_bo_create_pin_map(xe, tile, NULL, size,