/*
 * Copyright © 2012-2014 Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 *
 * Authors:
 *    Eugeni Dodonov <eugeni.dodonov@intel.com>
 *    Daniel Vetter <daniel.vetter@ffwll.ch>
 *
 */

#include <linux/pm_runtime.h>
#include <linux/vgaarb.h>

#include <drm/drm_print.h>

#include "i915_drv.h"
#include "i915_trace.h"

/**
 * DOC: runtime pm
 *
 * The i915 driver supports dynamic enabling and disabling of entire hardware
 * blocks at runtime. This is especially important on the display side where
 * software is supposed to control many power gates manually on recent hardware,
 * since on the GT side a lot of the power management is done by the hardware.
 * But even there some manual control at the device level is required.
 *
 * Since i915 supports a diverse set of platforms with a unified codebase and
 * hardware engineers just love to shuffle functionality around between power
 * domains there's a sizeable amount of indirection required. This file provides
 * generic functions to the driver for grabbing and releasing references for
 * abstract power domains. It then maps those to the actual power wells
 * present for a given platform.
 */

#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM)

#include <linux/sort.h>

#define STACKDEPTH 8

static noinline depot_stack_handle_t __save_depot_stack(void)
{
	unsigned long entries[STACKDEPTH];
	unsigned int n;

	n = stack_trace_save(entries, ARRAY_SIZE(entries), 1);
	return stack_depot_save(entries, n, GFP_NOWAIT | __GFP_NOWARN);
}

static void __print_depot_stack(depot_stack_handle_t stack,
				char *buf, int sz, int indent)
{
	unsigned long *entries;
	unsigned int nr_entries;

	nr_entries = stack_depot_fetch(stack, &entries);
	stack_trace_snprint(buf, sz, entries, nr_entries, indent);
}

static void init_intel_runtime_pm_wakeref(struct intel_runtime_pm *rpm)
{
	spin_lock_init(&rpm->debug.lock);
}

static noinline depot_stack_handle_t
track_intel_runtime_pm_wakeref(struct intel_runtime_pm *rpm)
{
	depot_stack_handle_t stack, *stacks;
	unsigned long flags;

	if (!rpm->available)
		return -1;

	stack = __save_depot_stack();
	if (!stack)
		return -1;

	spin_lock_irqsave(&rpm->debug.lock, flags);

	if (!rpm->debug.count)
		rpm->debug.last_acquire = stack;

	stacks = krealloc(rpm->debug.owners,
			  (rpm->debug.count + 1) * sizeof(*stacks),
			  GFP_NOWAIT | __GFP_NOWARN);
	if (stacks) {
		stacks[rpm->debug.count++] = stack;
		rpm->debug.owners = stacks;
	} else {
		stack = -1;
	}

	spin_unlock_irqrestore(&rpm->debug.lock, flags);

	return stack;
}

static void untrack_intel_runtime_pm_wakeref(struct intel_runtime_pm *rpm,
					     depot_stack_handle_t stack)
{
	unsigned long flags, n;
	bool found = false;

	if (unlikely(stack == -1))
		return;

	spin_lock_irqsave(&rpm->debug.lock, flags);
	for (n = rpm->debug.count; n--; ) {
		if (rpm->debug.owners[n] == stack) {
			memmove(rpm->debug.owners + n,
				rpm->debug.owners + n + 1,
				(--rpm->debug.count - n) * sizeof(stack));
			found = true;
			break;
		}
	}
	spin_unlock_irqrestore(&rpm->debug.lock, flags);

	if (WARN(!found,
		 "Unmatched wakeref (tracking %lu), count %u\n",
		 rpm->debug.count, atomic_read(&rpm->wakeref_count))) {
		char *buf;

		buf = kmalloc(PAGE_SIZE, GFP_NOWAIT | __GFP_NOWARN);
		if (!buf)
			return;

		__print_depot_stack(stack, buf, PAGE_SIZE, 2);
		DRM_DEBUG_DRIVER("wakeref %x from\n%s", stack, buf);

		stack = READ_ONCE(rpm->debug.last_release);
		if (stack) {
			__print_depot_stack(stack, buf, PAGE_SIZE, 2);
			DRM_DEBUG_DRIVER("wakeref last released at\n%s", buf);
		}

		kfree(buf);
	}
}

static int cmphandle(const void *_a, const void *_b)
{
	const depot_stack_handle_t * const a = _a, * const b = _b;

	if (*a < *b)
		return -1;
	else if (*a > *b)
		return 1;
	else
		return 0;
}

static void
__print_intel_runtime_pm_wakeref(struct drm_printer *p,
				 const struct intel_runtime_pm_debug *dbg)
{
	unsigned long i;
	char *buf;

	buf = kmalloc(PAGE_SIZE, GFP_NOWAIT | __GFP_NOWARN);
	if (!buf)
		return;

	if (dbg->last_acquire) {
		__print_depot_stack(dbg->last_acquire, buf, PAGE_SIZE, 2);
		drm_printf(p, "Wakeref last acquired:\n%s", buf);
	}

	if (dbg->last_release) {
		__print_depot_stack(dbg->last_release, buf, PAGE_SIZE, 2);
		drm_printf(p, "Wakeref last released:\n%s", buf);
	}

	drm_printf(p, "Wakeref count: %lu\n", dbg->count);

	sort(dbg->owners, dbg->count, sizeof(*dbg->owners), cmphandle, NULL);

	for (i = 0; i < dbg->count; i++) {
		depot_stack_handle_t stack = dbg->owners[i];
		unsigned long rep;

		rep = 1;
		while (i + 1 < dbg->count && dbg->owners[i + 1] == stack)
			rep++, i++;
		__print_depot_stack(stack, buf, PAGE_SIZE, 2);
		drm_printf(p, "Wakeref x%lu taken at:\n%s", rep, buf);
	}

	kfree(buf);
}

static noinline void
__untrack_all_wakerefs(struct intel_runtime_pm_debug *debug,
		       struct intel_runtime_pm_debug *saved)
{
	*saved = *debug;

	debug->owners = NULL;
	debug->count = 0;
	debug->last_release = __save_depot_stack();
}

static void
dump_and_free_wakeref_tracking(struct intel_runtime_pm_debug *debug)
{
	if (debug->count) {
		struct drm_printer p = drm_debug_printer("i915");

		__print_intel_runtime_pm_wakeref(&p, debug);
	}

	kfree(debug->owners);
}

static noinline void
__intel_wakeref_dec_and_check_tracking(struct intel_runtime_pm *rpm)
{
	struct intel_runtime_pm_debug dbg = {};
	unsigned long flags;

	if (!atomic_dec_and_lock_irqsave(&rpm->wakeref_count,
					 &rpm->debug.lock,
					 flags))
		return;

	__untrack_all_wakerefs(&rpm->debug, &dbg);
	spin_unlock_irqrestore(&rpm->debug.lock, flags);

	dump_and_free_wakeref_tracking(&dbg);
}

static noinline void
untrack_all_intel_runtime_pm_wakerefs(struct intel_runtime_pm *rpm)
{
	struct intel_runtime_pm_debug dbg = {};
	unsigned long flags;

	spin_lock_irqsave(&rpm->debug.lock, flags);
	__untrack_all_wakerefs(&rpm->debug, &dbg);
	spin_unlock_irqrestore(&rpm->debug.lock, flags);

	dump_and_free_wakeref_tracking(&dbg);
}

void print_intel_runtime_pm_wakeref(struct intel_runtime_pm *rpm,
				    struct drm_printer *p)
{
	struct intel_runtime_pm_debug dbg = {};

	do {
		unsigned long alloc = dbg.count;
		depot_stack_handle_t *s;

		spin_lock_irq(&rpm->debug.lock);
		dbg.count = rpm->debug.count;
		if (dbg.count <= alloc) {
			memcpy(dbg.owners,
			       rpm->debug.owners,
			       dbg.count * sizeof(*s));
		}
		dbg.last_acquire = rpm->debug.last_acquire;
		dbg.last_release = rpm->debug.last_release;
		spin_unlock_irq(&rpm->debug.lock);
		if (dbg.count <= alloc)
			break;

		s = krealloc(dbg.owners,
			     dbg.count * sizeof(*s),
			     GFP_NOWAIT | __GFP_NOWARN);
		if (!s)
			goto out;

		dbg.owners = s;
	} while (1);

	__print_intel_runtime_pm_wakeref(p, &dbg);

out:
	kfree(dbg.owners);
}

#else

static void init_intel_runtime_pm_wakeref(struct intel_runtime_pm *rpm)
{
}

static depot_stack_handle_t
track_intel_runtime_pm_wakeref(struct intel_runtime_pm *rpm)
{
	return -1;
}

static void untrack_intel_runtime_pm_wakeref(struct intel_runtime_pm *rpm,
					     intel_wakeref_t wref)
{
}

static void
__intel_wakeref_dec_and_check_tracking(struct intel_runtime_pm *rpm)
{
	atomic_dec(&rpm->wakeref_count);
}

static void
untrack_all_intel_runtime_pm_wakerefs(struct intel_runtime_pm *rpm)
{
}

#endif

static void
intel_runtime_pm_acquire(struct intel_runtime_pm *rpm, bool wakelock)
{
	if (wakelock) {
		atomic_add(1 + INTEL_RPM_WAKELOCK_BIAS, &rpm->wakeref_count);
		assert_rpm_wakelock_held(rpm);
	} else {
		atomic_inc(&rpm->wakeref_count);
		assert_rpm_raw_wakeref_held(rpm);
	}
}

static void
intel_runtime_pm_release(struct intel_runtime_pm *rpm, int wakelock)
{
	if (wakelock) {
		assert_rpm_wakelock_held(rpm);
		atomic_sub(INTEL_RPM_WAKELOCK_BIAS, &rpm->wakeref_count);
	} else {
		assert_rpm_raw_wakeref_held(rpm);
	}

	__intel_wakeref_dec_and_check_tracking(rpm);
}

static intel_wakeref_t __intel_runtime_pm_get(struct intel_runtime_pm *rpm,
					      bool wakelock)
{
	int ret;

	ret = pm_runtime_get_sync(rpm->kdev);
	WARN_ONCE(ret < 0, "pm_runtime_get_sync() failed: %d\n", ret);

	intel_runtime_pm_acquire(rpm, wakelock);

	return track_intel_runtime_pm_wakeref(rpm);
}

/**
 * intel_runtime_pm_get_raw - grab a raw runtime pm reference
 * @rpm: the intel_runtime_pm structure
 *
 * This is the unlocked version of intel_display_power_is_enabled() and should
 * only be used from error capture and recovery code where deadlocks are
 * possible.
 * This function grabs a device-level runtime pm reference (mostly used for
 * asynchronous PM management from display code) and ensures that it is powered
 * up. Raw references are not considered during wakelock assert checks.
 *
 * Any runtime pm reference obtained by this function must have a symmetric
 * call to intel_runtime_pm_put_raw() to release the reference again.
 *
 * Returns: the wakeref cookie to pass to intel_runtime_pm_put_raw(), evaluates
 * as True if the wakeref was acquired, or False otherwise.
 */
intel_wakeref_t intel_runtime_pm_get_raw(struct intel_runtime_pm *rpm)
{
	return __intel_runtime_pm_get(rpm, false);
}

/**
 * intel_runtime_pm_get - grab a runtime pm reference
 * @rpm: the intel_runtime_pm structure
 *
 * This function grabs a device-level runtime pm reference (mostly used for GEM
 * code to ensure the GTT or GT is on) and ensures that it is powered up.
 *
 * Any runtime pm reference obtained by this function must have a symmetric
 * call to intel_runtime_pm_put() to release the reference again.
 *
 * Returns: the wakeref cookie to pass to intel_runtime_pm_put()
 */
intel_wakeref_t intel_runtime_pm_get(struct intel_runtime_pm *rpm)
{
	return __intel_runtime_pm_get(rpm, true);
}

/**
 * intel_runtime_pm_get_if_in_use - grab a runtime pm reference if device in use
 * @rpm: the intel_runtime_pm structure
 *
 * This function grabs a device-level runtime pm reference if the device is
 * already in use and ensures that it is powered up. It is illegal to try
 * and access the HW should intel_runtime_pm_get_if_in_use() report failure.
 *
 * Any runtime pm reference obtained by this function must have a symmetric
 * call to intel_runtime_pm_put() to release the reference again.
 *
 * Returns: the wakeref cookie to pass to intel_runtime_pm_put(), evaluates
 * as True if the wakeref was acquired, or False otherwise.
 */
intel_wakeref_t intel_runtime_pm_get_if_in_use(struct intel_runtime_pm *rpm)
{
	if (IS_ENABLED(CONFIG_PM)) {
		/*
		 * In cases runtime PM is disabled by the RPM core and we get
		 * an -EINVAL return value we are not supposed to call this
		 * function, since the power state is undefined. This applies
		 * atm to the late/early system suspend/resume handlers.
		 */
		if (pm_runtime_get_if_in_use(rpm->kdev) <= 0)
			return 0;
	}

	intel_runtime_pm_acquire(rpm, true);

	return track_intel_runtime_pm_wakeref(rpm);
}

/**
 * intel_runtime_pm_get_noresume - grab a runtime pm reference
 * @rpm: the intel_runtime_pm structure
 *
 * This function grabs a device-level runtime pm reference (mostly used for GEM
 * code to ensure the GTT or GT is on).
 *
 * It will _not_ power up the device but instead only check that it's powered
 * on.  Therefore it is only valid to call this functions from contexts where
 * the device is known to be powered up and where trying to power it up would
 * result in hilarity and deadlocks. That pretty much means only the system
 * suspend/resume code where this is used to grab runtime pm references for
 * delayed setup down in work items.
 *
 * Any runtime pm reference obtained by this function must have a symmetric
 * call to intel_runtime_pm_put() to release the reference again.
 *
 * Returns: the wakeref cookie to pass to intel_runtime_pm_put()
 */
intel_wakeref_t intel_runtime_pm_get_noresume(struct intel_runtime_pm *rpm)
{
	assert_rpm_wakelock_held(rpm);
	pm_runtime_get_noresume(rpm->kdev);

	intel_runtime_pm_acquire(rpm, true);

	return track_intel_runtime_pm_wakeref(rpm);
}

static void __intel_runtime_pm_put(struct intel_runtime_pm *rpm,
				   intel_wakeref_t wref,
				   bool wakelock)
{
	struct device *kdev = rpm->kdev;

	untrack_intel_runtime_pm_wakeref(rpm, wref);

	intel_runtime_pm_release(rpm, wakelock);

	pm_runtime_mark_last_busy(kdev);
	pm_runtime_put_autosuspend(kdev);
}

/**
 * intel_runtime_pm_put_raw - release a raw runtime pm reference
 * @rpm: the intel_runtime_pm structure
 * @wref: wakeref acquired for the reference that is being released
 *
 * This function drops the device-level runtime pm reference obtained by
 * intel_runtime_pm_get_raw() and might power down the corresponding
 * hardware block right away if this is the last reference.
 */
void
intel_runtime_pm_put_raw(struct intel_runtime_pm *rpm, intel_wakeref_t wref)
{
	__intel_runtime_pm_put(rpm, wref, false);
}

/**
 * intel_runtime_pm_put_unchecked - release an unchecked runtime pm reference
 * @rpm: the intel_runtime_pm structure
 *
 * This function drops the device-level runtime pm reference obtained by
 * intel_runtime_pm_get() and might power down the corresponding
 * hardware block right away if this is the last reference.
 *
 * This function exists only for historical reasons and should be avoided in
 * new code, as the correctness of its use cannot be checked. Always use
 * intel_runtime_pm_put() instead.
 */
void intel_runtime_pm_put_unchecked(struct intel_runtime_pm *rpm)
{
	__intel_runtime_pm_put(rpm, -1, true);
}

#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM)
/**
 * intel_runtime_pm_put - release a runtime pm reference
 * @rpm: the intel_runtime_pm structure
 * @wref: wakeref acquired for the reference that is being released
 *
 * This function drops the device-level runtime pm reference obtained by
 * intel_runtime_pm_get() and might power down the corresponding
 * hardware block right away if this is the last reference.
 */
void intel_runtime_pm_put(struct intel_runtime_pm *rpm, intel_wakeref_t wref)
{
	__intel_runtime_pm_put(rpm, wref, true);
}
#endif

/**
 * intel_runtime_pm_enable - enable runtime pm
 * @rpm: the intel_runtime_pm structure
 *
 * This function enables runtime pm at the end of the driver load sequence.
 *
 * Note that this function does currently not enable runtime pm for the
 * subordinate display power domains. That is done by
 * intel_power_domains_enable().
 */
void intel_runtime_pm_enable(struct intel_runtime_pm *rpm)
{
	struct device *kdev = rpm->kdev;

	/*
	 * Disable the system suspend direct complete optimization, which can
	 * leave the device suspended skipping the driver's suspend handlers
	 * if the device was already runtime suspended. This is needed due to
	 * the difference in our runtime and system suspend sequence and
	 * becaue the HDA driver may require us to enable the audio power
	 * domain during system suspend.
	 */
	dev_pm_set_driver_flags(kdev, DPM_FLAG_NEVER_SKIP);

	pm_runtime_set_autosuspend_delay(kdev, 10000); /* 10s */
	pm_runtime_mark_last_busy(kdev);

	/*
	 * Take a permanent reference to disable the RPM functionality and drop
	 * it only when unloading the driver. Use the low level get/put helpers,
	 * so the driver's own RPM reference tracking asserts also work on
	 * platforms without RPM support.
	 */
	if (!rpm->available) {
		int ret;

		pm_runtime_dont_use_autosuspend(kdev);
		ret = pm_runtime_get_sync(kdev);
		WARN(ret < 0, "pm_runtime_get_sync() failed: %d\n", ret);
	} else {
		pm_runtime_use_autosuspend(kdev);
	}

	/*
	 * The core calls the driver load handler with an RPM reference held.
	 * We drop that here and will reacquire it during unloading in
	 * intel_power_domains_fini().
	 */
	pm_runtime_put_autosuspend(kdev);
}

void intel_runtime_pm_disable(struct intel_runtime_pm *rpm)
{
	struct device *kdev = rpm->kdev;

	/* Transfer rpm ownership back to core */
	WARN(pm_runtime_get_sync(kdev) < 0,
	     "Failed to pass rpm ownership back to core\n");

	pm_runtime_dont_use_autosuspend(kdev);

	if (!rpm->available)
		pm_runtime_put(kdev);
}

void intel_runtime_pm_driver_release(struct intel_runtime_pm *rpm)
{
	int count = atomic_read(&rpm->wakeref_count);

	WARN(count,
	     "i915 raw-wakerefs=%d wakelocks=%d on cleanup\n",
	     intel_rpm_raw_wakeref_count(count),
	     intel_rpm_wakelock_count(count));

	untrack_all_intel_runtime_pm_wakerefs(rpm);
}

void intel_runtime_pm_init_early(struct intel_runtime_pm *rpm)
{
	struct drm_i915_private *i915 =
			container_of(rpm, struct drm_i915_private, runtime_pm);
	struct pci_dev *pdev = i915->drm.pdev;
	struct device *kdev = &pdev->dev;

	rpm->kdev = kdev;
	rpm->available = HAS_RUNTIME_PM(i915);

	init_intel_runtime_pm_wakeref(rpm);
}
