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

#include "gem/i915_gem_pm.h"
#include "gem/i915_gem_ttm_pm.h"
#include "gt/intel_gt.h"
#include "gt/intel_gt_pm.h"
#include "gt/intel_gt_requests.h"

#include "i915_driver.h"
#include "i915_drv.h"

#if defined(CONFIG_X86)
#include <asm/smp.h>
#else
#define wbinvd_on_all_cpus() \
	pr_warn(DRIVER_NAME ": Missing cache flush in %s\n", __func__)
#endif

void i915_gem_suspend(struct drm_i915_private *i915)
{
	struct intel_gt *gt;
	unsigned int i;

	GEM_TRACE("%s\n", dev_name(i915->drm.dev));

	intel_wakeref_auto(&i915->runtime_pm.userfault_wakeref, 0);
	/*
	 * On rare occasions, we've observed the fence completion triggers
	 * free_engines asynchronously via rcu_call. Ensure those are done.
	 * This path is only called on suspend, so it's an acceptable cost.
	 */
	rcu_barrier();

	flush_workqueue(i915->wq);

	/*
	 * We have to flush all the executing contexts to main memory so
	 * that they can saved in the hibernation image. To ensure the last
	 * context image is coherent, we have to switch away from it. That
	 * leaves the i915->kernel_context still active when
	 * we actually suspend, and its image in memory may not match the GPU
	 * state. Fortunately, the kernel_context is disposable and we do
	 * not rely on its state.
	 */
	for_each_gt(gt, i915, i)
		intel_gt_suspend_prepare(gt);

	i915_gem_drain_freed_objects(i915);
}

static int lmem_restore(struct drm_i915_private *i915, u32 flags)
{
	struct intel_memory_region *mr;
	int ret = 0, id;

	for_each_memory_region(mr, i915, id) {
		if (mr->type == INTEL_MEMORY_LOCAL) {
			ret = i915_ttm_restore_region(mr, flags);
			if (ret)
				break;
		}
	}

	return ret;
}

static int lmem_suspend(struct drm_i915_private *i915, u32 flags)
{
	struct intel_memory_region *mr;
	int ret = 0, id;

	for_each_memory_region(mr, i915, id) {
		if (mr->type == INTEL_MEMORY_LOCAL) {
			ret = i915_ttm_backup_region(mr, flags);
			if (ret)
				break;
		}
	}

	return ret;
}

static void lmem_recover(struct drm_i915_private *i915)
{
	struct intel_memory_region *mr;
	int id;

	for_each_memory_region(mr, i915, id)
		if (mr->type == INTEL_MEMORY_LOCAL)
			i915_ttm_recover_region(mr);
}

int i915_gem_backup_suspend(struct drm_i915_private *i915)
{
	int ret;

	/* Opportunistically try to evict unpinned objects */
	ret = lmem_suspend(i915, I915_TTM_BACKUP_ALLOW_GPU);
	if (ret)
		goto out_recover;

	i915_gem_suspend(i915);

	/*
	 * More objects may have become unpinned as requests were
	 * retired. Now try to evict again. The gt may be wedged here
	 * in which case we automatically fall back to memcpy.
	 * We allow also backing up pinned objects that have not been
	 * marked for early recover, and that may contain, for example,
	 * page-tables for the migrate context.
	 */
	ret = lmem_suspend(i915, I915_TTM_BACKUP_ALLOW_GPU |
			   I915_TTM_BACKUP_PINNED);
	if (ret)
		goto out_recover;

	/*
	 * Remaining objects are backed up using memcpy once we've stopped
	 * using the migrate context.
	 */
	ret = lmem_suspend(i915, I915_TTM_BACKUP_PINNED);
	if (ret)
		goto out_recover;

	return 0;

out_recover:
	lmem_recover(i915);

	return ret;
}

void i915_gem_suspend_late(struct drm_i915_private *i915)
{
	struct drm_i915_gem_object *obj;
	struct list_head *phases[] = {
		&i915->mm.shrink_list,
		&i915->mm.purge_list,
		NULL
	}, **phase;
	struct intel_gt *gt;
	unsigned long flags;
	unsigned int i;
	bool flush = false;

	/*
	 * Neither the BIOS, ourselves or any other kernel
	 * expects the system to be in execlists mode on startup,
	 * so we need to reset the GPU back to legacy mode. And the only
	 * known way to disable logical contexts is through a GPU reset.
	 *
	 * So in order to leave the system in a known default configuration,
	 * always reset the GPU upon unload and suspend. Afterwards we then
	 * clean up the GEM state tracking, flushing off the requests and
	 * leaving the system in a known idle state.
	 *
	 * Note that is of the upmost importance that the GPU is idle and
	 * all stray writes are flushed *before* we dismantle the backing
	 * storage for the pinned objects.
	 *
	 * However, since we are uncertain that resetting the GPU on older
	 * machines is a good idea, we don't - just in case it leaves the
	 * machine in an unusable condition.
	 */

	/* Like i915_gem_suspend, flush tasks staged from fence triggers */
	rcu_barrier();

	for_each_gt(gt, i915, i)
		intel_gt_suspend_late(gt);

	spin_lock_irqsave(&i915->mm.obj_lock, flags);
	for (phase = phases; *phase; phase++) {
		list_for_each_entry(obj, *phase, mm.link) {
			if (!(obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ))
				flush |= (obj->read_domains & I915_GEM_DOMAIN_CPU) == 0;
			__start_cpu_write(obj); /* presume auto-hibernate */
		}
	}
	spin_unlock_irqrestore(&i915->mm.obj_lock, flags);
	if (flush)
		wbinvd_on_all_cpus();
}

int i915_gem_freeze(struct drm_i915_private *i915)
{
	/* Discard all purgeable objects, let userspace recover those as
	 * required after resuming.
	 */
	i915_gem_shrink_all(i915);

	return 0;
}

int i915_gem_freeze_late(struct drm_i915_private *i915)
{
	struct drm_i915_gem_object *obj;
	intel_wakeref_t wakeref;

	/*
	 * Called just before we write the hibernation image.
	 *
	 * We need to update the domain tracking to reflect that the CPU
	 * will be accessing all the pages to create and restore from the
	 * hibernation, and so upon restoration those pages will be in the
	 * CPU domain.
	 *
	 * To make sure the hibernation image contains the latest state,
	 * we update that state just before writing out the image.
	 *
	 * To try and reduce the hibernation image, we manually shrink
	 * the objects as well, see i915_gem_freeze()
	 */

	with_intel_runtime_pm(&i915->runtime_pm, wakeref)
		i915_gem_shrink(NULL, i915, -1UL, NULL, ~0);
	i915_gem_drain_freed_objects(i915);

	wbinvd_on_all_cpus();
	list_for_each_entry(obj, &i915->mm.shrink_list, mm.link)
		__start_cpu_write(obj);

	return 0;
}

void i915_gem_resume(struct drm_i915_private *i915)
{
	struct intel_gt *gt;
	int ret, i, j;

	GEM_TRACE("%s\n", dev_name(i915->drm.dev));

	ret = lmem_restore(i915, 0);
	GEM_WARN_ON(ret);

	/*
	 * As we didn't flush the kernel context before suspend, we cannot
	 * guarantee that the context image is complete. So let's just reset
	 * it and start again.
	 */
	for_each_gt(gt, i915, i)
		if (intel_gt_resume(gt))
			goto err_wedged;

	ret = lmem_restore(i915, I915_TTM_BACKUP_ALLOW_GPU);
	GEM_WARN_ON(ret);

	return;

err_wedged:
	for_each_gt(gt, i915, j) {
		if (!intel_gt_is_wedged(gt)) {
			dev_err(i915->drm.dev,
				"Failed to re-initialize GPU[%u], declaring it wedged!\n",
				j);
			intel_gt_set_wedged(gt);
		}

		if (j == i)
			break;
	}
}
