diff options
author | Vinay Belgaumkar <vinay.belgaumkar@intel.com> | 2023-11-17 16:14:49 -0800 |
---|---|---|
committer | Rodrigo Vivi <rodrigo.vivi@intel.com> | 2023-12-21 11:45:08 -0500 |
commit | 975e4a3795d4f1373be538177525c0b714e0e65e (patch) | |
tree | 3c90febd24b445e133e8d6d4cdd465b1ceebea4c /drivers/gpu/drm | |
parent | f1cb5f647e8959a1034941d85b311d7485a7095f (diff) | |
download | lwn-975e4a3795d4f1373be538177525c0b714e0e65e.tar.gz lwn-975e4a3795d4f1373be538177525c0b714e0e65e.zip |
drm/xe: Manually setup C6 when skip_guc_pc is set
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>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r-- | drivers/gpu/drm/xe/regs/xe_gt_regs.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/xe/xe_gt_idle.c | 24 | ||||
-rw-r--r-- | drivers/gpu/drm/xe/xe_gt_idle.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/xe/xe_guc_pc.c | 35 |
4 files changed, 64 insertions, 3 deletions
diff --git a/drivers/gpu/drm/xe/regs/xe_gt_regs.h b/drivers/gpu/drm/xe/regs/xe_gt_regs.h index 18b13224480d..d318ec0efd7d 100644 --- a/drivers/gpu/drm/xe/regs/xe_gt_regs.h +++ b/drivers/gpu/drm/xe/regs/xe_gt_regs.h @@ -272,7 +272,11 @@ #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) diff --git a/drivers/gpu/drm/xe/xe_gt_idle.c b/drivers/gpu/drm/xe/xe_gt_idle.c index e5b7e5d38e76..9358f7336889 100644 --- a/drivers/gpu/drm/xe/xe_gt_idle.c +++ b/drivers/gpu/drm/xe/xe_gt_idle.c @@ -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); +} diff --git a/drivers/gpu/drm/xe/xe_gt_idle.h b/drivers/gpu/drm/xe/xe_gt_idle.h index 9b36bf7db3a7..69280fd16b03 100644 --- a/drivers/gpu/drm/xe/xe_gt_idle.h +++ b/drivers/gpu/drm/xe/xe_gt_idle.h @@ -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_ */ diff --git a/drivers/gpu/drm/xe/xe_guc_pc.c b/drivers/gpu/drm/xe/xe_guc_pc.c index 2919c6aea403..1943893a3fd7 100644 --- a/drivers/gpu/drm/xe/xe_guc_pc.c +++ b/drivers/gpu/drm/xe/xe_guc_pc.c @@ -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, |