// SPDX-License-Identifier: MIT
/*
 * Copyright(c) 2020, Intel Corporation. All rights reserved.
 */

#include "i915_drv.h"

#include "intel_pxp.h"
#include "intel_pxp_cmd.h"
#include "intel_pxp_session.h"
#include "intel_pxp_tee.h"
#include "intel_pxp_types.h"

#define ARB_SESSION I915_PROTECTED_CONTENT_DEFAULT_SESSION /* shorter define */

#define GEN12_KCR_SIP _MMIO(0x32260) /* KCR hwdrm session in play 0-31 */

/* PXP global terminate register for session termination */
#define PXP_GLOBAL_TERMINATE _MMIO(0x320f8)

static bool intel_pxp_session_is_in_play(struct intel_pxp *pxp, u32 id)
{
	struct intel_uncore *uncore = pxp_to_gt(pxp)->uncore;
	intel_wakeref_t wakeref;
	u32 sip = 0;

	/* if we're suspended the session is considered off */
	with_intel_runtime_pm_if_in_use(uncore->rpm, wakeref)
		sip = intel_uncore_read(uncore, GEN12_KCR_SIP);

	return sip & BIT(id);
}

static int pxp_wait_for_session_state(struct intel_pxp *pxp, u32 id, bool in_play)
{
	struct intel_uncore *uncore = pxp_to_gt(pxp)->uncore;
	intel_wakeref_t wakeref;
	u32 mask = BIT(id);
	int ret;

	/* if we're suspended the session is considered off */
	wakeref = intel_runtime_pm_get_if_in_use(uncore->rpm);
	if (!wakeref)
		return in_play ? -ENODEV : 0;

	ret = intel_wait_for_register(uncore,
				      GEN12_KCR_SIP,
				      mask,
				      in_play ? mask : 0,
				      100);

	intel_runtime_pm_put(uncore->rpm, wakeref);

	return ret;
}

static int pxp_create_arb_session(struct intel_pxp *pxp)
{
	struct intel_gt *gt = pxp_to_gt(pxp);
	int ret;

	pxp->arb_is_valid = false;

	if (intel_pxp_session_is_in_play(pxp, ARB_SESSION)) {
		drm_err(&gt->i915->drm, "arb session already in play at creation time\n");
		return -EEXIST;
	}

	ret = intel_pxp_tee_cmd_create_arb_session(pxp, ARB_SESSION);
	if (ret) {
		drm_err(&gt->i915->drm, "tee cmd for arb session creation failed\n");
		return ret;
	}

	ret = pxp_wait_for_session_state(pxp, ARB_SESSION, true);
	if (ret) {
		drm_err(&gt->i915->drm, "arb session failed to go in play\n");
		return ret;
	}
	drm_dbg(&gt->i915->drm, "PXP ARB session is alive\n");

	if (!++pxp->key_instance)
		++pxp->key_instance;

	pxp->arb_is_valid = true;

	return 0;
}

static int pxp_terminate_arb_session_and_global(struct intel_pxp *pxp)
{
	int ret;
	struct intel_gt *gt = pxp_to_gt(pxp);

	/* must mark termination in progress calling this function */
	GEM_WARN_ON(pxp->arb_is_valid);

	/* terminate the hw sessions */
	ret = intel_pxp_terminate_session(pxp, ARB_SESSION);
	if (ret) {
		drm_err(&gt->i915->drm, "Failed to submit session termination\n");
		return ret;
	}

	ret = pxp_wait_for_session_state(pxp, ARB_SESSION, false);
	if (ret) {
		drm_err(&gt->i915->drm, "Session state did not clear\n");
		return ret;
	}

	intel_uncore_write(gt->uncore, PXP_GLOBAL_TERMINATE, 1);

	return ret;
}

static void pxp_terminate(struct intel_pxp *pxp)
{
	int ret;

	pxp->hw_state_invalidated = true;

	/*
	 * if we fail to submit the termination there is no point in waiting for
	 * it to complete. PXP will be marked as non-active until the next
	 * termination is issued.
	 */
	ret = pxp_terminate_arb_session_and_global(pxp);
	if (ret)
		complete_all(&pxp->termination);
}

static void pxp_terminate_complete(struct intel_pxp *pxp)
{
	/* Re-create the arb session after teardown handle complete */
	if (fetch_and_zero(&pxp->hw_state_invalidated))
		pxp_create_arb_session(pxp);

	complete_all(&pxp->termination);
}

static void pxp_session_work(struct work_struct *work)
{
	struct intel_pxp *pxp = container_of(work, typeof(*pxp), session_work);
	struct intel_gt *gt = pxp_to_gt(pxp);
	intel_wakeref_t wakeref;
	u32 events = 0;

	spin_lock_irq(gt->irq_lock);
	events = fetch_and_zero(&pxp->session_events);
	spin_unlock_irq(gt->irq_lock);

	if (!events)
		return;

	if (events & PXP_INVAL_REQUIRED)
		intel_pxp_invalidate(pxp);

	/*
	 * If we're processing an event while suspending then don't bother,
	 * we're going to re-init everything on resume anyway.
	 */
	wakeref = intel_runtime_pm_get_if_in_use(gt->uncore->rpm);
	if (!wakeref)
		return;

	if (events & PXP_TERMINATION_REQUEST) {
		events &= ~PXP_TERMINATION_COMPLETE;
		pxp_terminate(pxp);
	}

	if (events & PXP_TERMINATION_COMPLETE)
		pxp_terminate_complete(pxp);

	intel_runtime_pm_put(gt->uncore->rpm, wakeref);
}

void intel_pxp_session_management_init(struct intel_pxp *pxp)
{
	mutex_init(&pxp->arb_mutex);
	INIT_WORK(&pxp->session_work, pxp_session_work);
}
