// SPDX-License-Identifier: MIT
/*
 * Copyright © 2022 Intel Corporation
 */

#include "xe_gt.h"

#include <linux/minmax.h>

#include <drm/drm_managed.h>
#include <uapi/drm/xe_drm.h>

#include <generated/xe_wa_oob.h>

#include "instructions/xe_gfxpipe_commands.h"
#include "instructions/xe_mi_commands.h"
#include "regs/xe_gt_regs.h"
#include "xe_assert.h"
#include "xe_bb.h"
#include "xe_bo.h"
#include "xe_device.h"
#include "xe_exec_queue.h"
#include "xe_execlist.h"
#include "xe_force_wake.h"
#include "xe_ggtt.h"
#include "xe_gsc.h"
#include "xe_gt_ccs_mode.h"
#include "xe_gt_clock.h"
#include "xe_gt_freq.h"
#include "xe_gt_idle.h"
#include "xe_gt_mcr.h"
#include "xe_gt_pagefault.h"
#include "xe_gt_printk.h"
#include "xe_gt_sriov_pf.h"
#include "xe_gt_sysfs.h"
#include "xe_gt_tlb_invalidation.h"
#include "xe_gt_topology.h"
#include "xe_guc_exec_queue_types.h"
#include "xe_guc_pc.h"
#include "xe_hw_fence.h"
#include "xe_hw_engine_class_sysfs.h"
#include "xe_irq.h"
#include "xe_lmtt.h"
#include "xe_lrc.h"
#include "xe_map.h"
#include "xe_migrate.h"
#include "xe_mmio.h"
#include "xe_pat.h"
#include "xe_pm.h"
#include "xe_mocs.h"
#include "xe_reg_sr.h"
#include "xe_ring_ops.h"
#include "xe_sa.h"
#include "xe_sched_job.h"
#include "xe_sriov.h"
#include "xe_tuning.h"
#include "xe_uc.h"
#include "xe_uc_fw.h"
#include "xe_vm.h"
#include "xe_wa.h"
#include "xe_wopcm.h"

static void gt_fini(struct drm_device *drm, void *arg)
{
	struct xe_gt *gt = arg;

	destroy_workqueue(gt->ordered_wq);
}

struct xe_gt *xe_gt_alloc(struct xe_tile *tile)
{
	struct xe_gt *gt;
	int err;

	gt = drmm_kzalloc(&tile_to_xe(tile)->drm, sizeof(*gt), GFP_KERNEL);
	if (!gt)
		return ERR_PTR(-ENOMEM);

	gt->tile = tile;
	gt->ordered_wq = alloc_ordered_workqueue("gt-ordered-wq", 0);

	err = drmm_add_action_or_reset(&gt_to_xe(gt)->drm, gt_fini, gt);
	if (err)
		return ERR_PTR(err);

	return gt;
}

void xe_gt_sanitize(struct xe_gt *gt)
{
	/*
	 * FIXME: if xe_uc_sanitize is called here, on TGL driver will not
	 * reload
	 */
	gt->uc.guc.submission_state.enabled = false;
}

static void xe_gt_enable_host_l2_vram(struct xe_gt *gt)
{
	u32 reg;
	int err;

	if (!XE_WA(gt, 16023588340))
		return;

	err = xe_force_wake_get(gt_to_fw(gt), XE_FW_GT);
	if (WARN_ON(err))
		return;

	if (!xe_gt_is_media_type(gt)) {
		xe_mmio_write32(gt, SCRATCH1LPFC, EN_L3_RW_CCS_CACHE_FLUSH);
		reg = xe_gt_mcr_unicast_read_any(gt, XE2_GAMREQSTRM_CTRL);
		reg |= CG_DIS_CNTLBUS;
		xe_gt_mcr_multicast_write(gt, XE2_GAMREQSTRM_CTRL, reg);
	}

	xe_gt_mcr_multicast_write(gt, XEHPC_L3CLOS_MASK(3), 0x3);
	xe_force_wake_put(gt_to_fw(gt), XE_FW_GT);
}

static void xe_gt_disable_host_l2_vram(struct xe_gt *gt)
{
	u32 reg;
	int err;

	if (!XE_WA(gt, 16023588340))
		return;

	if (xe_gt_is_media_type(gt))
		return;

	err = xe_force_wake_get(gt_to_fw(gt), XE_FW_GT);
	if (WARN_ON(err))
		return;

	reg = xe_gt_mcr_unicast_read_any(gt, XE2_GAMREQSTRM_CTRL);
	reg &= ~CG_DIS_CNTLBUS;
	xe_gt_mcr_multicast_write(gt, XE2_GAMREQSTRM_CTRL, reg);

	xe_force_wake_put(gt_to_fw(gt), XE_FW_GT);
}

/**
 * xe_gt_remove() - Clean up the GT structures before driver removal
 * @gt: the GT object
 *
 * This function should only act on objects/structures that must be cleaned
 * before the driver removal callback is complete and therefore can't be
 * deferred to a drmm action.
 */
void xe_gt_remove(struct xe_gt *gt)
{
	int i;

	xe_uc_remove(&gt->uc);

	for (i = 0; i < XE_ENGINE_CLASS_MAX; ++i)
		xe_hw_fence_irq_finish(&gt->fence_irq[i]);

	xe_gt_disable_host_l2_vram(gt);
}

static void gt_reset_worker(struct work_struct *w);

static int emit_nop_job(struct xe_gt *gt, struct xe_exec_queue *q)
{
	struct xe_sched_job *job;
	struct xe_bb *bb;
	struct dma_fence *fence;
	long timeout;

	bb = xe_bb_new(gt, 4, false);
	if (IS_ERR(bb))
		return PTR_ERR(bb);

	job = xe_bb_create_job(q, bb);
	if (IS_ERR(job)) {
		xe_bb_free(bb, NULL);
		return PTR_ERR(job);
	}

	xe_sched_job_arm(job);
	fence = dma_fence_get(&job->drm.s_fence->finished);
	xe_sched_job_push(job);

	timeout = dma_fence_wait_timeout(fence, false, HZ);
	dma_fence_put(fence);
	xe_bb_free(bb, NULL);
	if (timeout < 0)
		return timeout;
	else if (!timeout)
		return -ETIME;

	return 0;
}

/*
 * Convert back from encoded value to type-safe, only to be used when reg.mcr
 * is true
 */
static struct xe_reg_mcr to_xe_reg_mcr(const struct xe_reg reg)
{
	return (const struct xe_reg_mcr){.__reg.raw = reg.raw };
}

static int emit_wa_job(struct xe_gt *gt, struct xe_exec_queue *q)
{
	struct xe_reg_sr *sr = &q->hwe->reg_lrc;
	struct xe_reg_sr_entry *entry;
	unsigned long idx;
	struct xe_sched_job *job;
	struct xe_bb *bb;
	struct dma_fence *fence;
	long timeout;
	int count = 0;

	if (q->hwe->class == XE_ENGINE_CLASS_RENDER)
		/* Big enough to emit all of the context's 3DSTATE */
		bb = xe_bb_new(gt, xe_gt_lrc_size(gt, q->hwe->class), false);
	else
		/* Just pick a large BB size */
		bb = xe_bb_new(gt, SZ_4K, false);

	if (IS_ERR(bb))
		return PTR_ERR(bb);

	xa_for_each(&sr->xa, idx, entry)
		++count;

	if (count) {
		xe_gt_dbg(gt, "LRC WA %s save-restore batch\n", sr->name);

		bb->cs[bb->len++] = MI_LOAD_REGISTER_IMM | MI_LRI_NUM_REGS(count);

		xa_for_each(&sr->xa, idx, entry) {
			struct xe_reg reg = entry->reg;
			struct xe_reg_mcr reg_mcr = to_xe_reg_mcr(reg);
			u32 val;

			/*
			 * Skip reading the register if it's not really needed
			 */
			if (reg.masked)
				val = entry->clr_bits << 16;
			else if (entry->clr_bits + 1)
				val = (reg.mcr ?
				       xe_gt_mcr_unicast_read_any(gt, reg_mcr) :
				       xe_mmio_read32(gt, reg)) & (~entry->clr_bits);
			else
				val = 0;

			val |= entry->set_bits;

			bb->cs[bb->len++] = reg.addr;
			bb->cs[bb->len++] = val;
			xe_gt_dbg(gt, "REG[0x%x] = 0x%08x", reg.addr, val);
		}
	}

	xe_lrc_emit_hwe_state_instructions(q, bb);

	job = xe_bb_create_job(q, bb);
	if (IS_ERR(job)) {
		xe_bb_free(bb, NULL);
		return PTR_ERR(job);
	}

	xe_sched_job_arm(job);
	fence = dma_fence_get(&job->drm.s_fence->finished);
	xe_sched_job_push(job);

	timeout = dma_fence_wait_timeout(fence, false, HZ);
	dma_fence_put(fence);
	xe_bb_free(bb, NULL);
	if (timeout < 0)
		return timeout;
	else if (!timeout)
		return -ETIME;

	return 0;
}

int xe_gt_record_default_lrcs(struct xe_gt *gt)
{
	struct xe_device *xe = gt_to_xe(gt);
	struct xe_hw_engine *hwe;
	enum xe_hw_engine_id id;
	int err = 0;

	for_each_hw_engine(hwe, gt, id) {
		struct xe_exec_queue *q, *nop_q;
		void *default_lrc;

		if (gt->default_lrc[hwe->class])
			continue;

		xe_reg_sr_init(&hwe->reg_lrc, hwe->name, xe);
		xe_wa_process_lrc(hwe);
		xe_hw_engine_setup_default_lrc_state(hwe);
		xe_tuning_process_lrc(hwe);

		default_lrc = drmm_kzalloc(&xe->drm,
					   xe_gt_lrc_size(gt, hwe->class),
					   GFP_KERNEL);
		if (!default_lrc)
			return -ENOMEM;

		q = xe_exec_queue_create(xe, NULL, BIT(hwe->logical_instance), 1,
					 hwe, EXEC_QUEUE_FLAG_KERNEL, 0);
		if (IS_ERR(q)) {
			err = PTR_ERR(q);
			xe_gt_err(gt, "hwe %s: xe_exec_queue_create failed (%pe)\n",
				  hwe->name, q);
			return err;
		}

		/* Prime golden LRC with known good state */
		err = emit_wa_job(gt, q);
		if (err) {
			xe_gt_err(gt, "hwe %s: emit_wa_job failed (%pe) guc_id=%u\n",
				  hwe->name, ERR_PTR(err), q->guc->id);
			goto put_exec_queue;
		}

		nop_q = xe_exec_queue_create(xe, NULL, BIT(hwe->logical_instance),
					     1, hwe, EXEC_QUEUE_FLAG_KERNEL, 0);
		if (IS_ERR(nop_q)) {
			err = PTR_ERR(nop_q);
			xe_gt_err(gt, "hwe %s: nop xe_exec_queue_create failed (%pe)\n",
				  hwe->name, nop_q);
			goto put_exec_queue;
		}

		/* Switch to different LRC */
		err = emit_nop_job(gt, nop_q);
		if (err) {
			xe_gt_err(gt, "hwe %s: nop emit_nop_job failed (%pe) guc_id=%u\n",
				  hwe->name, ERR_PTR(err), nop_q->guc->id);
			goto put_nop_q;
		}

		/* Reload golden LRC to record the effect of any indirect W/A */
		err = emit_nop_job(gt, q);
		if (err) {
			xe_gt_err(gt, "hwe %s: emit_nop_job failed (%pe) guc_id=%u\n",
				  hwe->name, ERR_PTR(err), q->guc->id);
			goto put_nop_q;
		}

		xe_map_memcpy_from(xe, default_lrc,
				   &q->lrc[0]->bo->vmap,
				   xe_lrc_pphwsp_offset(q->lrc[0]),
				   xe_gt_lrc_size(gt, hwe->class));

		gt->default_lrc[hwe->class] = default_lrc;
put_nop_q:
		xe_exec_queue_put(nop_q);
put_exec_queue:
		xe_exec_queue_put(q);
		if (err)
			break;
	}

	return err;
}

int xe_gt_init_early(struct xe_gt *gt)
{
	int err;

	if (IS_SRIOV_PF(gt_to_xe(gt))) {
		err = xe_gt_sriov_pf_init_early(gt);
		if (err)
			return err;
	}

	xe_reg_sr_init(&gt->reg_sr, "GT", gt_to_xe(gt));

	err = xe_wa_init(gt);
	if (err)
		return err;

	xe_wa_process_gt(gt);
	xe_wa_process_oob(gt);
	xe_tuning_process_gt(gt);

	xe_force_wake_init_gt(gt, gt_to_fw(gt));
	spin_lock_init(&gt->global_invl_lock);

	return 0;
}

static void dump_pat_on_error(struct xe_gt *gt)
{
	struct drm_printer p;
	char prefix[32];

	snprintf(prefix, sizeof(prefix), "[GT%u Error]", gt->info.id);
	p = drm_dbg_printer(&gt_to_xe(gt)->drm, DRM_UT_DRIVER, prefix);

	xe_pat_dump(gt, &p);
}

static int gt_fw_domain_init(struct xe_gt *gt)
{
	int err, i;

	err = xe_force_wake_get(gt_to_fw(gt), XE_FW_GT);
	if (err)
		goto err_hw_fence_irq;

	if (!xe_gt_is_media_type(gt)) {
		err = xe_ggtt_init(gt_to_tile(gt)->mem.ggtt);
		if (err)
			goto err_force_wake;
		if (IS_SRIOV_PF(gt_to_xe(gt)))
			xe_lmtt_init(&gt_to_tile(gt)->sriov.pf.lmtt);
	}

	/* Enable per hw engine IRQs */
	xe_irq_enable_hwe(gt);

	/* Rerun MCR init as we now have hw engine list */
	xe_gt_mcr_init(gt);

	err = xe_hw_engines_init_early(gt);
	if (err)
		goto err_force_wake;

	err = xe_hw_engine_class_sysfs_init(gt);
	if (err)
		goto err_force_wake;

	/* Initialize CCS mode sysfs after early initialization of HW engines */
	err = xe_gt_ccs_mode_sysfs_init(gt);
	if (err)
		goto err_force_wake;

	/*
	 * Stash hardware-reported version.  Since this register does not exist
	 * on pre-MTL platforms, reading it there will (correctly) return 0.
	 */
	gt->info.gmdid = xe_mmio_read32(gt, GMD_ID);

	err = xe_force_wake_put(gt_to_fw(gt), XE_FW_GT);
	XE_WARN_ON(err);

	return 0;

err_force_wake:
	dump_pat_on_error(gt);
	xe_force_wake_put(gt_to_fw(gt), XE_FW_GT);
err_hw_fence_irq:
	for (i = 0; i < XE_ENGINE_CLASS_MAX; ++i)
		xe_hw_fence_irq_finish(&gt->fence_irq[i]);

	return err;
}

static int all_fw_domain_init(struct xe_gt *gt)
{
	int err, i;

	err = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL);
	if (err)
		goto err_hw_fence_irq;

	xe_gt_mcr_set_implicit_defaults(gt);
	xe_reg_sr_apply_mmio(&gt->reg_sr, gt);

	err = xe_gt_clock_init(gt);
	if (err)
		goto err_force_wake;

	xe_mocs_init(gt);
	err = xe_execlist_init(gt);
	if (err)
		goto err_force_wake;

	err = xe_hw_engines_init(gt);
	if (err)
		goto err_force_wake;

	err = xe_uc_init_post_hwconfig(&gt->uc);
	if (err)
		goto err_force_wake;

	if (!xe_gt_is_media_type(gt)) {
		/*
		 * USM has its only SA pool to non-block behind user operations
		 */
		if (gt_to_xe(gt)->info.has_usm) {
			struct xe_device *xe = gt_to_xe(gt);

			gt->usm.bb_pool = xe_sa_bo_manager_init(gt_to_tile(gt),
								IS_DGFX(xe) ? SZ_1M : SZ_512K, 16);
			if (IS_ERR(gt->usm.bb_pool)) {
				err = PTR_ERR(gt->usm.bb_pool);
				goto err_force_wake;
			}
		}
	}

	if (!xe_gt_is_media_type(gt)) {
		struct xe_tile *tile = gt_to_tile(gt);

		tile->migrate = xe_migrate_init(tile);
		if (IS_ERR(tile->migrate)) {
			err = PTR_ERR(tile->migrate);
			goto err_force_wake;
		}
	}

	err = xe_uc_init_hw(&gt->uc);
	if (err)
		goto err_force_wake;

	/* Configure default CCS mode of 1 engine with all resources */
	if (xe_gt_ccs_mode_enabled(gt)) {
		gt->ccs_mode = 1;
		xe_gt_apply_ccs_mode(gt);
	}

	if (IS_SRIOV_PF(gt_to_xe(gt)) && !xe_gt_is_media_type(gt))
		xe_lmtt_init_hw(&gt_to_tile(gt)->sriov.pf.lmtt);

	if (IS_SRIOV_PF(gt_to_xe(gt)))
		xe_gt_sriov_pf_init_hw(gt);

	err = xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL);
	XE_WARN_ON(err);

	return 0;

err_force_wake:
	xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL);
err_hw_fence_irq:
	for (i = 0; i < XE_ENGINE_CLASS_MAX; ++i)
		xe_hw_fence_irq_finish(&gt->fence_irq[i]);

	return err;
}

/*
 * Initialize enough GT to be able to load GuC in order to obtain hwconfig and
 * enable CTB communication.
 */
int xe_gt_init_hwconfig(struct xe_gt *gt)
{
	int err;

	err = xe_force_wake_get(gt_to_fw(gt), XE_FW_GT);
	if (err)
		goto out;

	xe_gt_mcr_init_early(gt);
	xe_pat_init(gt);

	err = xe_uc_init(&gt->uc);
	if (err)
		goto out_fw;

	err = xe_uc_init_hwconfig(&gt->uc);
	if (err)
		goto out_fw;

	xe_gt_topology_init(gt);
	xe_gt_mcr_init(gt);
	xe_gt_enable_host_l2_vram(gt);

out_fw:
	xe_force_wake_put(gt_to_fw(gt), XE_FW_GT);
out:
	return err;
}

int xe_gt_init(struct xe_gt *gt)
{
	int err;
	int i;

	INIT_WORK(&gt->reset.worker, gt_reset_worker);

	for (i = 0; i < XE_ENGINE_CLASS_MAX; ++i) {
		gt->ring_ops[i] = xe_ring_ops_get(gt, i);
		xe_hw_fence_irq_init(&gt->fence_irq[i]);
	}

	err = xe_gt_tlb_invalidation_init(gt);
	if (err)
		return err;

	err = xe_gt_pagefault_init(gt);
	if (err)
		return err;

	xe_mocs_init_early(gt);

	err = xe_gt_sysfs_init(gt);
	if (err)
		return err;

	err = gt_fw_domain_init(gt);
	if (err)
		return err;

	err = xe_gt_idle_init(&gt->gtidle);
	if (err)
		return err;

	err = xe_gt_freq_init(gt);
	if (err)
		return err;

	xe_force_wake_init_engines(gt, gt_to_fw(gt));

	err = all_fw_domain_init(gt);
	if (err)
		return err;

	xe_gt_record_user_engines(gt);

	return 0;
}

void xe_gt_record_user_engines(struct xe_gt *gt)
{
	struct xe_hw_engine *hwe;
	enum xe_hw_engine_id id;

	gt->user_engines.mask = 0;
	memset(gt->user_engines.instances_per_class, 0,
	       sizeof(gt->user_engines.instances_per_class));

	for_each_hw_engine(hwe, gt, id) {
		if (xe_hw_engine_is_reserved(hwe))
			continue;

		gt->user_engines.mask |= BIT_ULL(id);
		gt->user_engines.instances_per_class[hwe->class]++;
	}

	xe_gt_assert(gt, (gt->user_engines.mask | gt->info.engine_mask)
		     == gt->info.engine_mask);
}

static int do_gt_reset(struct xe_gt *gt)
{
	int err;

	xe_gsc_wa_14015076503(gt, true);

	xe_mmio_write32(gt, GDRST, GRDOM_FULL);
	err = xe_mmio_wait32(gt, GDRST, GRDOM_FULL, 0, 5000, NULL, false);
	if (err)
		xe_gt_err(gt, "failed to clear GRDOM_FULL (%pe)\n",
			  ERR_PTR(err));

	xe_gsc_wa_14015076503(gt, false);

	return err;
}

static int vf_gt_restart(struct xe_gt *gt)
{
	int err;

	err = xe_uc_sanitize_reset(&gt->uc);
	if (err)
		return err;

	err = xe_uc_init_hw(&gt->uc);
	if (err)
		return err;

	err = xe_uc_start(&gt->uc);
	if (err)
		return err;

	return 0;
}

static int do_gt_restart(struct xe_gt *gt)
{
	struct xe_hw_engine *hwe;
	enum xe_hw_engine_id id;
	int err;

	if (IS_SRIOV_VF(gt_to_xe(gt)))
		return vf_gt_restart(gt);

	xe_pat_init(gt);

	xe_gt_enable_host_l2_vram(gt);

	xe_gt_mcr_set_implicit_defaults(gt);
	xe_reg_sr_apply_mmio(&gt->reg_sr, gt);

	err = xe_wopcm_init(&gt->uc.wopcm);
	if (err)
		return err;

	for_each_hw_engine(hwe, gt, id)
		xe_hw_engine_enable_ring(hwe);

	err = xe_uc_sanitize_reset(&gt->uc);
	if (err)
		return err;

	err = xe_uc_init_hw(&gt->uc);
	if (err)
		return err;

	if (IS_SRIOV_PF(gt_to_xe(gt)) && !xe_gt_is_media_type(gt))
		xe_lmtt_init_hw(&gt_to_tile(gt)->sriov.pf.lmtt);

	if (IS_SRIOV_PF(gt_to_xe(gt)))
		xe_gt_sriov_pf_init_hw(gt);

	xe_mocs_init(gt);
	err = xe_uc_start(&gt->uc);
	if (err)
		return err;

	for_each_hw_engine(hwe, gt, id) {
		xe_reg_sr_apply_mmio(&hwe->reg_sr, gt);
		xe_reg_sr_apply_whitelist(hwe);
	}

	/* Get CCS mode in sync between sw/hw */
	xe_gt_apply_ccs_mode(gt);

	/* Restore GT freq to expected values */
	xe_gt_sanitize_freq(gt);

	if (IS_SRIOV_PF(gt_to_xe(gt)))
		xe_gt_sriov_pf_restart(gt);

	return 0;
}

static int gt_reset(struct xe_gt *gt)
{
	int err;

	if (xe_device_wedged(gt_to_xe(gt)))
		return -ECANCELED;

	/* We only support GT resets with GuC submission */
	if (!xe_device_uc_enabled(gt_to_xe(gt)))
		return -ENODEV;

	xe_gt_info(gt, "reset started\n");

	xe_pm_runtime_get(gt_to_xe(gt));

	if (xe_fault_inject_gt_reset()) {
		err = -ECANCELED;
		goto err_fail;
	}

	xe_gt_sanitize(gt);

	err = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL);
	if (err)
		goto err_msg;

	xe_uc_gucrc_disable(&gt->uc);
	xe_uc_stop_prepare(&gt->uc);
	xe_gt_pagefault_reset(gt);

	xe_uc_stop(&gt->uc);

	xe_gt_tlb_invalidation_reset(gt);

	err = do_gt_reset(gt);
	if (err)
		goto err_out;

	err = do_gt_restart(gt);
	if (err)
		goto err_out;

	err = xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL);
	XE_WARN_ON(err);
	xe_pm_runtime_put(gt_to_xe(gt));

	xe_gt_info(gt, "reset done\n");

	return 0;

err_out:
	XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL));
err_msg:
	XE_WARN_ON(xe_uc_start(&gt->uc));
err_fail:
	xe_gt_err(gt, "reset failed (%pe)\n", ERR_PTR(err));

	xe_device_declare_wedged(gt_to_xe(gt));
	xe_pm_runtime_put(gt_to_xe(gt));

	return err;
}

static void gt_reset_worker(struct work_struct *w)
{
	struct xe_gt *gt = container_of(w, typeof(*gt), reset.worker);

	gt_reset(gt);
}

void xe_gt_reset_async(struct xe_gt *gt)
{
	xe_gt_info(gt, "trying reset\n");

	/* Don't do a reset while one is already in flight */
	if (!xe_fault_inject_gt_reset() && xe_uc_reset_prepare(&gt->uc))
		return;

	xe_gt_info(gt, "reset queued\n");
	queue_work(gt->ordered_wq, &gt->reset.worker);
}

void xe_gt_suspend_prepare(struct xe_gt *gt)
{
	XE_WARN_ON(xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL));

	xe_uc_stop_prepare(&gt->uc);

	XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL));
}

int xe_gt_suspend(struct xe_gt *gt)
{
	int err;

	xe_gt_dbg(gt, "suspending\n");
	xe_gt_sanitize(gt);

	err = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL);
	if (err)
		goto err_msg;

	err = xe_uc_suspend(&gt->uc);
	if (err)
		goto err_force_wake;

	xe_gt_idle_disable_pg(gt);

	xe_gt_disable_host_l2_vram(gt);

	XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL));
	xe_gt_dbg(gt, "suspended\n");

	return 0;

err_force_wake:
	XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL));
err_msg:
	xe_gt_err(gt, "suspend failed (%pe)\n", ERR_PTR(err));

	return err;
}

/**
 * xe_gt_sanitize_freq() - Restore saved frequencies if necessary.
 * @gt: the GT object
 *
 * Called after driver init/GSC load completes to restore GT frequencies if we
 * limited them for any WAs.
 */
int xe_gt_sanitize_freq(struct xe_gt *gt)
{
	int ret = 0;

	if ((!xe_uc_fw_is_available(&gt->uc.gsc.fw) ||
	     xe_uc_fw_is_loaded(&gt->uc.gsc.fw)) && XE_WA(gt, 22019338487))
		ret = xe_guc_pc_restore_stashed_freq(&gt->uc.guc.pc);

	return ret;
}

int xe_gt_resume(struct xe_gt *gt)
{
	int err;

	xe_gt_dbg(gt, "resuming\n");
	err = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL);
	if (err)
		goto err_msg;

	err = do_gt_restart(gt);
	if (err)
		goto err_force_wake;

	xe_gt_idle_enable_pg(gt);

	XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL));
	xe_gt_dbg(gt, "resumed\n");

	return 0;

err_force_wake:
	XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL));
err_msg:
	xe_gt_err(gt, "resume failed (%pe)\n", ERR_PTR(err));

	return err;
}

struct xe_hw_engine *xe_gt_hw_engine(struct xe_gt *gt,
				     enum xe_engine_class class,
				     u16 instance, bool logical)
{
	struct xe_hw_engine *hwe;
	enum xe_hw_engine_id id;

	for_each_hw_engine(hwe, gt, id)
		if (hwe->class == class &&
		    ((!logical && hwe->instance == instance) ||
		    (logical && hwe->logical_instance == instance)))
			return hwe;

	return NULL;
}

struct xe_hw_engine *xe_gt_any_hw_engine_by_reset_domain(struct xe_gt *gt,
							 enum xe_engine_class class)
{
	struct xe_hw_engine *hwe;
	enum xe_hw_engine_id id;

	for_each_hw_engine(hwe, gt, id) {
		switch (class) {
		case XE_ENGINE_CLASS_RENDER:
		case XE_ENGINE_CLASS_COMPUTE:
			if (hwe->class == XE_ENGINE_CLASS_RENDER ||
			    hwe->class == XE_ENGINE_CLASS_COMPUTE)
				return hwe;
			break;
		default:
			if (hwe->class == class)
				return hwe;
		}
	}

	return NULL;
}

struct xe_hw_engine *xe_gt_any_hw_engine(struct xe_gt *gt)
{
	struct xe_hw_engine *hwe;
	enum xe_hw_engine_id id;

	for_each_hw_engine(hwe, gt, id)
		return hwe;

	return NULL;
}

/**
 * xe_gt_declare_wedged() - Declare GT wedged
 * @gt: the GT object
 *
 * Wedge the GT which stops all submission, saves desired debug state, and
 * cleans up anything which could timeout.
 */
void xe_gt_declare_wedged(struct xe_gt *gt)
{
	xe_gt_assert(gt, gt_to_xe(gt)->wedged.mode);

	xe_uc_declare_wedged(&gt->uc);
	xe_gt_tlb_invalidation_reset(gt);
}
