diff options
author | Ashutosh Dixit <ashutosh.dixit@intel.com> | 2024-06-17 18:46:07 -0700 |
---|---|---|
committer | Ashutosh Dixit <ashutosh.dixit@intel.com> | 2024-06-18 12:40:43 -0700 |
commit | 70af432b9acfb382dcd4f5f936528db2de992a8e (patch) | |
tree | 1623993cb08967794bc5e2192c07e3b01a8d800f /drivers/gpu/drm/xe/xe_guc_pc.c | |
parent | 828a8eaf37c3fac6ba048995f55f1647a4ac542d (diff) |
drm/xe/oa: Override GuC RC with OA on PVC
On PVC, a w/a resets RCS/CCS before it goes into RC6. This breaks OA since
OA does not expect engine resets during its use. Fix it by disabling RC6.
v2: Convert to gt oriented error/warn messages (Michal)
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: Umesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com>
Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240618014609.3233427-16-ashutosh.dixit@intel.com
Diffstat (limited to 'drivers/gpu/drm/xe/xe_guc_pc.c')
-rw-r--r-- | drivers/gpu/drm/xe/xe_guc_pc.c | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/drivers/gpu/drm/xe/xe_guc_pc.c b/drivers/gpu/drm/xe/xe_guc_pc.c index 666a37106bc5..2b45a9cd3ec0 100644 --- a/drivers/gpu/drm/xe/xe_guc_pc.c +++ b/drivers/gpu/drm/xe/xe_guc_pc.c @@ -24,6 +24,7 @@ #include "xe_map.h" #include "xe_mmio.h" #include "xe_pcode.h" +#include "xe_pm.h" #define MCHBAR_MIRROR_BASE_SNB 0x140000 @@ -190,6 +191,27 @@ static int pc_action_set_param(struct xe_guc_pc *pc, u8 id, u32 value) return ret; } +static int pc_action_unset_param(struct xe_guc_pc *pc, u8 id) +{ + u32 action[] = { + GUC_ACTION_HOST2GUC_PC_SLPC_REQUEST, + SLPC_EVENT(SLPC_EVENT_PARAMETER_UNSET, 1), + id, + }; + struct xe_guc_ct *ct = &pc_to_guc(pc)->ct; + int ret; + + if (wait_for_pc_state(pc, SLPC_GLOBAL_STATE_RUNNING)) + return -EAGAIN; + + ret = xe_guc_ct_send(ct, action, ARRAY_SIZE(action), 0, 0); + if (ret) + xe_gt_err(pc_to_gt(pc), "GuC PC unset param failed: %pe", + ERR_PTR(ret)); + + return ret; +} + static int pc_action_setup_gucrc(struct xe_guc_pc *pc, u32 mode) { struct xe_guc_ct *ct = pc_to_ct(pc); @@ -772,6 +794,41 @@ int xe_guc_pc_gucrc_disable(struct xe_guc_pc *pc) return 0; } +/** + * xe_guc_pc_override_gucrc_mode - override GUCRC mode + * @pc: Xe_GuC_PC instance + * @mode: new value of the mode. + * + * Return: 0 on success, negative error code on error + */ +int xe_guc_pc_override_gucrc_mode(struct xe_guc_pc *pc, enum slpc_gucrc_mode mode) +{ + int ret; + + xe_pm_runtime_get(pc_to_xe(pc)); + ret = pc_action_set_param(pc, SLPC_PARAM_PWRGATE_RC_MODE, mode); + xe_pm_runtime_put(pc_to_xe(pc)); + + return ret; +} + +/** + * xe_guc_pc_unset_gucrc_mode - unset GUCRC mode override + * @pc: Xe_GuC_PC instance + * + * Return: 0 on success, negative error code on error + */ +int xe_guc_pc_unset_gucrc_mode(struct xe_guc_pc *pc) +{ + int ret; + + xe_pm_runtime_get(pc_to_xe(pc)); + ret = pc_action_unset_param(pc, SLPC_PARAM_PWRGATE_RC_MODE); + xe_pm_runtime_put(pc_to_xe(pc)); + + return ret; +} + static void pc_init_pcode_freq(struct xe_guc_pc *pc) { u32 min = DIV_ROUND_CLOSEST(pc->rpn_freq, GT_FREQUENCY_MULTIPLIER); |