1
0
Fork 0
mirror of synced 2025-03-06 20:59:54 +01:00
linux/drivers/gpu/drm/i915/gt/uc/intel_guc_rc.c
Vinay Belgaumkar 216d56c5da drm/i915/guc/rc: Setup and enable GuCRC feature
This feature hands over the control of HW RC6 to the GuC.
GuC decides when to put HW into RC6 based on it's internal
busyness algorithms.

GuCRC needs GuC submission to be enabled, and only
supported on Gen12+ for now.

When GuCRC is enabled, do not set HW RC6. Use a H2G message
to tell GuC to enable GuCRC. When disabling RC6, tell GuC to
revert RC6 control back to KMD. KMD is still responsible for
enabling everything related to Coarse Power Gating though.

v2: Address comments (Michal W)
v3: Don't set hysterisis values when GuCRC is used (Matt Roper)
v4: checkpatch()

Reviewed-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
Signed-off-by: Vinay Belgaumkar <vinay.belgaumkar@intel.com>
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210730202119.23810-15-vinay.belgaumkar@intel.com
2021-08-03 16:05:44 -07:00

80 lines
1.6 KiB
C

// SPDX-License-Identifier: MIT
/*
* Copyright © 2021 Intel Corporation
*/
#include "intel_guc_rc.h"
#include "gt/intel_gt.h"
#include "i915_drv.h"
static bool __guc_rc_supported(struct intel_guc *guc)
{
/* GuC RC is unavailable for pre-Gen12 */
return guc->submission_supported &&
GRAPHICS_VER(guc_to_gt(guc)->i915) >= 12;
}
static bool __guc_rc_selected(struct intel_guc *guc)
{
if (!intel_guc_rc_is_supported(guc))
return false;
return guc->submission_selected;
}
void intel_guc_rc_init_early(struct intel_guc *guc)
{
guc->rc_supported = __guc_rc_supported(guc);
guc->rc_selected = __guc_rc_selected(guc);
}
static int guc_action_control_gucrc(struct intel_guc *guc, bool enable)
{
u32 rc_mode = enable ? INTEL_GUCRC_FIRMWARE_CONTROL :
INTEL_GUCRC_HOST_CONTROL;
u32 action[] = {
INTEL_GUC_ACTION_SETUP_PC_GUCRC,
rc_mode
};
int ret;
ret = intel_guc_send(guc, action, ARRAY_SIZE(action));
ret = ret > 0 ? -EPROTO : ret;
return ret;
}
static int __guc_rc_control(struct intel_guc *guc, bool enable)
{
struct intel_gt *gt = guc_to_gt(guc);
struct drm_device *drm = &guc_to_gt(guc)->i915->drm;
int ret;
if (!intel_uc_uses_guc_rc(&gt->uc))
return -EOPNOTSUPP;
if (!intel_guc_is_ready(guc))
return -EINVAL;
ret = guc_action_control_gucrc(guc, enable);
if (ret) {
drm_err(drm, "Failed to %s GuC RC (%pe)\n",
enabledisable(enable), ERR_PTR(ret));
return ret;
}
drm_info(&gt->i915->drm, "GuC RC: %s\n",
enableddisabled(enable));
return 0;
}
int intel_guc_rc_enable(struct intel_guc *guc)
{
return __guc_rc_control(guc, true);
}
int intel_guc_rc_disable(struct intel_guc *guc)
{
return __guc_rc_control(guc, false);
}