aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/xe/xe_guc_pc.c
diff options
context:
space:
mode:
authorAshutosh Dixit <ashutosh.dixit@intel.com>2024-06-17 18:46:07 -0700
committerAshutosh Dixit <ashutosh.dixit@intel.com>2024-06-18 12:40:43 -0700
commit70af432b9acfb382dcd4f5f936528db2de992a8e (patch)
tree1623993cb08967794bc5e2192c07e3b01a8d800f /drivers/gpu/drm/xe/xe_guc_pc.c
parent828a8eaf37c3fac6ba048995f55f1647a4ac542d (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.c57
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);