// SPDX-License-Identifier: MIT
/*
 * Copyright © 2022 Intel Corporation
 *
 * High level crtc/connector/encoder modeset state verification.
 */

#include <drm/drm_atomic_state_helper.h>

#include "i915_drv.h"
#include "intel_atomic.h"
#include "intel_crtc.h"
#include "intel_crtc_state_dump.h"
#include "intel_cx0_phy.h"
#include "intel_display.h"
#include "intel_display_types.h"
#include "intel_fdi.h"
#include "intel_modeset_verify.h"
#include "intel_snps_phy.h"
#include "skl_watermark.h"

/*
 * Cross check the actual hw state with our own modeset state tracking (and its
 * internal consistency).
 */
static void intel_connector_verify_state(const struct intel_crtc_state *crtc_state,
					 const struct drm_connector_state *conn_state)
{
	struct intel_connector *connector = to_intel_connector(conn_state->connector);
	struct drm_i915_private *i915 = to_i915(connector->base.dev);

	drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s]\n",
		    connector->base.base.id, connector->base.name);

	if (connector->get_hw_state(connector)) {
		struct intel_encoder *encoder = intel_attached_encoder(connector);

		I915_STATE_WARN(i915, !crtc_state,
				"connector enabled without attached crtc\n");

		if (!crtc_state)
			return;

		I915_STATE_WARN(i915, !crtc_state->hw.active,
				"connector is active, but attached crtc isn't\n");

		if (!encoder || encoder->type == INTEL_OUTPUT_DP_MST)
			return;

		I915_STATE_WARN(i915,
				conn_state->best_encoder != &encoder->base,
				"atomic encoder doesn't match attached encoder\n");

		I915_STATE_WARN(i915, conn_state->crtc != encoder->base.crtc,
				"attached encoder crtc differs from connector crtc\n");
	} else {
		I915_STATE_WARN(i915, crtc_state && crtc_state->hw.active,
				"attached crtc is active, but connector isn't\n");
		I915_STATE_WARN(i915, !crtc_state && conn_state->best_encoder,
				"best encoder set without crtc!\n");
	}
}

static void
verify_connector_state(struct intel_atomic_state *state,
		       struct intel_crtc *crtc)
{
	struct drm_connector *connector;
	const struct drm_connector_state *new_conn_state;
	int i;

	for_each_new_connector_in_state(&state->base, connector, new_conn_state, i) {
		struct drm_encoder *encoder = connector->encoder;
		const struct intel_crtc_state *crtc_state = NULL;

		if (new_conn_state->crtc != &crtc->base)
			continue;

		if (crtc)
			crtc_state = intel_atomic_get_new_crtc_state(state, crtc);

		intel_connector_verify_state(crtc_state, new_conn_state);

		I915_STATE_WARN(to_i915(connector->dev), new_conn_state->best_encoder != encoder,
				"connector's atomic encoder doesn't match legacy encoder\n");
	}
}

static void intel_pipe_config_sanity_check(const struct intel_crtc_state *crtc_state)
{
	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);

	if (crtc_state->has_pch_encoder) {
		int fdi_dotclock = intel_dotclock_calculate(intel_fdi_link_freq(i915, crtc_state),
							    &crtc_state->fdi_m_n);
		int dotclock = crtc_state->hw.adjusted_mode.crtc_clock;

		/*
		 * FDI already provided one idea for the dotclock.
		 * Yell if the encoder disagrees. Allow for slight
		 * rounding differences.
		 */
		drm_WARN(&i915->drm, abs(fdi_dotclock - dotclock) > 1,
			 "FDI dotclock and encoder dotclock mismatch, fdi: %i, encoder: %i\n",
			 fdi_dotclock, dotclock);
	}
}

static void
verify_encoder_state(struct intel_atomic_state *state)
{
	struct drm_i915_private *i915 = to_i915(state->base.dev);
	struct intel_encoder *encoder;
	struct drm_connector *connector;
	const struct drm_connector_state *old_conn_state, *new_conn_state;
	int i;

	for_each_intel_encoder(&i915->drm, encoder) {
		bool enabled = false, found = false;
		enum pipe pipe;

		drm_dbg_kms(&i915->drm, "[ENCODER:%d:%s]\n",
			    encoder->base.base.id,
			    encoder->base.name);

		for_each_oldnew_connector_in_state(&state->base, connector, old_conn_state,
						   new_conn_state, i) {
			if (old_conn_state->best_encoder == &encoder->base)
				found = true;

			if (new_conn_state->best_encoder != &encoder->base)
				continue;

			found = true;
			enabled = true;

			I915_STATE_WARN(i915,
					new_conn_state->crtc != encoder->base.crtc,
					"connector's crtc doesn't match encoder crtc\n");
		}

		if (!found)
			continue;

		I915_STATE_WARN(i915, !!encoder->base.crtc != enabled,
				"encoder's enabled state mismatch (expected %i, found %i)\n",
				!!encoder->base.crtc, enabled);

		if (!encoder->base.crtc) {
			bool active;

			active = encoder->get_hw_state(encoder, &pipe);
			I915_STATE_WARN(i915, active,
					"encoder detached but still enabled on pipe %c.\n",
					pipe_name(pipe));
		}
	}
}

static void
verify_crtc_state(struct intel_atomic_state *state,
		  struct intel_crtc *crtc)
{
	struct drm_device *dev = crtc->base.dev;
	struct drm_i915_private *i915 = to_i915(dev);
	const struct intel_crtc_state *sw_crtc_state =
		intel_atomic_get_new_crtc_state(state, crtc);
	struct intel_crtc_state *hw_crtc_state;
	struct intel_crtc *primary_crtc;
	struct intel_encoder *encoder;

	hw_crtc_state = intel_crtc_state_alloc(crtc);
	if (!hw_crtc_state)
		return;

	drm_dbg_kms(&i915->drm, "[CRTC:%d:%s]\n", crtc->base.base.id,
		    crtc->base.name);

	hw_crtc_state->hw.enable = sw_crtc_state->hw.enable;

	intel_crtc_get_pipe_config(hw_crtc_state);

	/* we keep both pipes enabled on 830 */
	if (IS_I830(i915) && hw_crtc_state->hw.active)
		hw_crtc_state->hw.active = sw_crtc_state->hw.active;

	I915_STATE_WARN(i915,
			sw_crtc_state->hw.active != hw_crtc_state->hw.active,
			"crtc active state doesn't match with hw state (expected %i, found %i)\n",
			sw_crtc_state->hw.active, hw_crtc_state->hw.active);

	I915_STATE_WARN(i915, crtc->active != sw_crtc_state->hw.active,
			"transitional active state does not match atomic hw state (expected %i, found %i)\n",
			sw_crtc_state->hw.active, crtc->active);

	primary_crtc = intel_primary_crtc(sw_crtc_state);

	for_each_encoder_on_crtc(dev, &primary_crtc->base, encoder) {
		enum pipe pipe;
		bool active;

		active = encoder->get_hw_state(encoder, &pipe);
		I915_STATE_WARN(i915, active != sw_crtc_state->hw.active,
				"[ENCODER:%i] active %i with crtc active %i\n",
				encoder->base.base.id, active,
				sw_crtc_state->hw.active);

		I915_STATE_WARN(i915, active && primary_crtc->pipe != pipe,
				"Encoder connected to wrong pipe %c\n",
				pipe_name(pipe));

		if (active)
			intel_encoder_get_config(encoder, hw_crtc_state);
	}

	if (!sw_crtc_state->hw.active)
		goto destroy_state;

	intel_pipe_config_sanity_check(hw_crtc_state);

	if (!intel_pipe_config_compare(sw_crtc_state,
				       hw_crtc_state, false)) {
		I915_STATE_WARN(i915, 1, "pipe state doesn't match!\n");
		intel_crtc_state_dump(hw_crtc_state, NULL, "hw state");
		intel_crtc_state_dump(sw_crtc_state, NULL, "sw state");
	}

destroy_state:
	intel_crtc_destroy_state(&crtc->base, &hw_crtc_state->uapi);
}

void intel_modeset_verify_crtc(struct intel_atomic_state *state,
			       struct intel_crtc *crtc)
{
	const struct intel_crtc_state *new_crtc_state =
		intel_atomic_get_new_crtc_state(state, crtc);

	if (!intel_crtc_needs_modeset(new_crtc_state) &&
	    !intel_crtc_needs_fastset(new_crtc_state))
		return;

	intel_wm_state_verify(state, crtc);
	verify_connector_state(state, crtc);
	verify_crtc_state(state, crtc);
	intel_shared_dpll_state_verify(state, crtc);
	intel_mpllb_state_verify(state, crtc);
	intel_cx0pll_state_verify(state, crtc);
}

void intel_modeset_verify_disabled(struct intel_atomic_state *state)
{
	verify_encoder_state(state);
	verify_connector_state(state, NULL);
	intel_shared_dpll_verify_disabled(state);
}
