mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-28 19:14:35 -04:00
Production PVC hardware had a graphics stepping of C0. Xe1 platforms already aren't officially supported by the Xe driver, but pre-production steppings are especially out of scope (and 'has_pre_prod_wa' is not set in the device descriptor). Drop the workarounds that aren't relevant to production hardware. v2: - Drop the stream->override_gucrc which is no longer set anywhere after the removal of Wa_1509372804. (Bala) - Drop xe_guc_rc_set_mode / xe_guc_rc_unset_mode which are no longer used after the removal of Wa_1509372804. Bspec: 44484 Cc: Balasubramani Vivekanandan <balasubramani.vivekanandan@intel.com> Reviewed-by: Balasubramani Vivekanandan <balasubramani.vivekanandan@intel.com> Link: https://patch.msgid.link/20260220-forupstream-wa_cleanup-v2-2-b12005a05af6@intel.com Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
132 lines
3.2 KiB
C
132 lines
3.2 KiB
C
// SPDX-License-Identifier: MIT
|
|
/*
|
|
* Copyright © 2026 Intel Corporation
|
|
*/
|
|
|
|
#include <drm/drm_print.h>
|
|
|
|
#include "abi/guc_actions_slpc_abi.h"
|
|
#include "xe_device.h"
|
|
#include "xe_force_wake.h"
|
|
#include "xe_gt.h"
|
|
#include "xe_gt_idle.h"
|
|
#include "xe_gt_printk.h"
|
|
#include "xe_guc.h"
|
|
#include "xe_guc_ct.h"
|
|
#include "xe_guc_pc.h"
|
|
#include "xe_guc_rc.h"
|
|
#include "xe_pm.h"
|
|
|
|
/**
|
|
* DOC: GuC RC (Render C-states)
|
|
*
|
|
* GuC handles the GT transition to deeper C-states in conjunction with Pcode.
|
|
* GuC RC can be enabled independently of the frequency component in SLPC,
|
|
* which is also controlled by GuC.
|
|
*
|
|
* This file will contain all H2G related logic for handling Render C-states.
|
|
* There are some calls to xe_gt_idle, where we enable host C6 when GuC RC is
|
|
* skipped. GuC RC is mostly independent of xe_guc_pc with the exception of
|
|
* functions that override the mode for which we have to rely on the SLPC H2G
|
|
* calls.
|
|
*/
|
|
|
|
static int guc_action_setup_gucrc(struct xe_guc *guc, u32 control)
|
|
{
|
|
u32 action[] = {
|
|
GUC_ACTION_HOST2GUC_SETUP_PC_GUCRC,
|
|
control,
|
|
};
|
|
int ret;
|
|
|
|
ret = xe_guc_ct_send(&guc->ct, action, ARRAY_SIZE(action), 0, 0);
|
|
if (ret && !(xe_device_wedged(guc_to_xe(guc)) && ret == -ECANCELED))
|
|
xe_gt_err(guc_to_gt(guc),
|
|
"GuC RC setup %s(%u) failed (%pe)\n",
|
|
control == GUCRC_HOST_CONTROL ? "HOST_CONTROL" :
|
|
control == GUCRC_FIRMWARE_CONTROL ? "FIRMWARE_CONTROL" :
|
|
"UNKNOWN", control, ERR_PTR(ret));
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* xe_guc_rc_disable() - Disable GuC RC
|
|
* @guc: Xe GuC instance
|
|
*
|
|
* Disables GuC RC by taking control of RC6 back from GuC.
|
|
*/
|
|
void xe_guc_rc_disable(struct xe_guc *guc)
|
|
{
|
|
struct xe_device *xe = guc_to_xe(guc);
|
|
struct xe_gt *gt = guc_to_gt(guc);
|
|
|
|
if (!xe->info.skip_guc_pc && xe->info.platform != XE_PVC)
|
|
if (guc_action_setup_gucrc(guc, GUCRC_HOST_CONTROL))
|
|
return;
|
|
|
|
xe_gt_WARN_ON(gt, xe_gt_idle_disable_c6(gt));
|
|
}
|
|
|
|
static void xe_guc_rc_fini_hw(void *arg)
|
|
{
|
|
struct xe_guc *guc = arg;
|
|
struct xe_device *xe = guc_to_xe(guc);
|
|
struct xe_gt *gt = guc_to_gt(guc);
|
|
|
|
if (xe_device_wedged(xe))
|
|
return;
|
|
|
|
CLASS(xe_force_wake, fw_ref)(gt_to_fw(gt), XE_FW_GT);
|
|
xe_guc_rc_disable(guc);
|
|
}
|
|
|
|
/**
|
|
* xe_guc_rc_init() - Init GuC RC
|
|
* @guc: Xe GuC instance
|
|
*
|
|
* Add callback action for GuC RC
|
|
*
|
|
* Return: 0 on success, negative error code on error.
|
|
*/
|
|
int xe_guc_rc_init(struct xe_guc *guc)
|
|
{
|
|
struct xe_device *xe = guc_to_xe(guc);
|
|
struct xe_gt *gt = guc_to_gt(guc);
|
|
|
|
xe_gt_assert(gt, xe_device_uc_enabled(xe));
|
|
|
|
return devm_add_action_or_reset(xe->drm.dev, xe_guc_rc_fini_hw, guc);
|
|
}
|
|
|
|
/**
|
|
* xe_guc_rc_enable() - Enable GuC RC feature if applicable
|
|
* @guc: Xe GuC instance
|
|
*
|
|
* Enables GuC RC feature.
|
|
*
|
|
* Return: 0 on success, negative error code on error.
|
|
*/
|
|
int xe_guc_rc_enable(struct xe_guc *guc)
|
|
{
|
|
struct xe_device *xe = guc_to_xe(guc);
|
|
struct xe_gt *gt = guc_to_gt(guc);
|
|
|
|
xe_gt_assert(gt, xe_device_uc_enabled(xe));
|
|
|
|
CLASS(xe_force_wake, fw_ref)(gt_to_fw(gt), XE_FW_GT);
|
|
if (!xe_force_wake_ref_has_domain(fw_ref.domains, XE_FW_GT))
|
|
return -ETIMEDOUT;
|
|
|
|
if (xe->info.platform == XE_PVC) {
|
|
xe_guc_rc_disable(guc);
|
|
return 0;
|
|
}
|
|
|
|
if (xe->info.skip_guc_pc) {
|
|
xe_gt_idle_enable_c6(gt);
|
|
return 0;
|
|
}
|
|
|
|
return guc_action_setup_gucrc(guc, GUCRC_FIRMWARE_CONTROL);
|
|
}
|