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

#include <linux/debugfs.h>

#include <drm/drm_print.h>

#include "intel_atomic.h"
#include "intel_de.h"
#include "intel_display_regs.h"
#include "intel_display_types.h"
#include "intel_drrs.h"
#include "intel_frontbuffer.h"
#include "intel_panel.h"

/**
 * DOC: Display Refresh Rate Switching (DRRS)
 *
 * Display Refresh Rate Switching (DRRS) is a power conservation feature
 * which enables swtching between low and high refresh rates,
 * dynamically, based on the usage scenario. This feature is applicable
 * for internal panels.
 *
 * Indication that the panel supports DRRS is given by the panel EDID, which
 * would list multiple refresh rates for one resolution.
 *
 * DRRS is of 2 types - static and seamless.
 * Static DRRS involves changing refresh rate (RR) by doing a full modeset
 * (may appear as a blink on screen) and is used in dock-undock scenario.
 * Seamless DRRS involves changing RR without any visual effect to the user
 * and can be used during normal system usage. This is done by programming
 * certain registers.
 *
 * Support for static/seamless DRRS may be indicated in the VBT based on
 * inputs from the panel spec.
 *
 * DRRS saves power by switching to low RR based on usage scenarios.
 *
 * The implementation is based on frontbuffer tracking implementation.  When
 * there is a disturbance on the screen triggered by user activity or a periodic
 * system activity, DRRS is disabled (RR is changed to high RR).  When there is
 * no movement on screen, after a timeout of 1 second, a switch to low RR is
 * made.
 *
 * For integration with frontbuffer tracking code, intel_drrs_invalidate()
 * and intel_drrs_flush() are called.
 *
 * DRRS can be further extended to support other internal panels and also
 * the scenario of video playback wherein RR is set based on the rate
 * requested by userspace.
 */

const char *intel_drrs_type_str(enum drrs_type drrs_type)
{
	static const char * const str[] = {
		[DRRS_TYPE_NONE] = "none",
		[DRRS_TYPE_STATIC] = "static",
		[DRRS_TYPE_SEAMLESS] = "seamless",
	};

	if (drrs_type >= ARRAY_SIZE(str))
		return "<invalid>";

	return str[drrs_type];
}

bool intel_cpu_transcoder_has_drrs(struct intel_display *display,
				   enum transcoder cpu_transcoder)
{
	if (HAS_DOUBLE_BUFFERED_M_N(display))
		return true;

	return intel_cpu_transcoder_has_m2_n2(display, cpu_transcoder);
}

static void
intel_drrs_set_refresh_rate_pipeconf(struct intel_crtc *crtc,
				     enum drrs_refresh_rate refresh_rate)
{
	struct intel_display *display = to_intel_display(crtc);
	enum transcoder cpu_transcoder = crtc->drrs.cpu_transcoder;
	u32 bit;

	if (display->platform.valleyview || display->platform.cherryview)
		bit = TRANSCONF_REFRESH_RATE_ALT_VLV;
	else
		bit = TRANSCONF_REFRESH_RATE_ALT_ILK;

	intel_de_rmw(display, TRANSCONF(display, cpu_transcoder),
		     bit, refresh_rate == DRRS_REFRESH_RATE_LOW ? bit : 0);
}

static void
intel_drrs_set_refresh_rate_m_n(struct intel_crtc *crtc,
				enum drrs_refresh_rate refresh_rate)
{
	intel_cpu_transcoder_set_m1_n1(crtc, crtc->drrs.cpu_transcoder,
				       refresh_rate == DRRS_REFRESH_RATE_LOW ?
				       &crtc->drrs.m2_n2 : &crtc->drrs.m_n);
}

bool intel_drrs_is_active(struct intel_crtc *crtc)
{
	return crtc->drrs.cpu_transcoder != INVALID_TRANSCODER;
}

static void intel_drrs_set_state(struct intel_crtc *crtc,
				 enum drrs_refresh_rate refresh_rate)
{
	struct intel_display *display = to_intel_display(crtc);

	if (refresh_rate == crtc->drrs.refresh_rate)
		return;

	if (intel_cpu_transcoder_has_m2_n2(display, crtc->drrs.cpu_transcoder))
		intel_drrs_set_refresh_rate_pipeconf(crtc, refresh_rate);
	else
		intel_drrs_set_refresh_rate_m_n(crtc, refresh_rate);

	crtc->drrs.refresh_rate = refresh_rate;
}

static void intel_drrs_schedule_work(struct intel_crtc *crtc)
{
	struct intel_display *display = to_intel_display(crtc);

	mod_delayed_work(display->wq.unordered, &crtc->drrs.work, msecs_to_jiffies(1000));
}

static unsigned int intel_drrs_frontbuffer_bits(const struct intel_crtc_state *crtc_state)
{
	struct intel_display *display = to_intel_display(crtc_state);
	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
	unsigned int frontbuffer_bits;

	frontbuffer_bits = INTEL_FRONTBUFFER_ALL_MASK(crtc->pipe);

	for_each_intel_crtc_in_pipe_mask(display->drm, crtc,
					 crtc_state->joiner_pipes)
		frontbuffer_bits |= INTEL_FRONTBUFFER_ALL_MASK(crtc->pipe);

	return frontbuffer_bits;
}

/**
 * intel_drrs_activate - activate DRRS
 * @crtc_state: the crtc state
 *
 * Activates DRRS on the crtc.
 */
void intel_drrs_activate(const struct intel_crtc_state *crtc_state)
{
	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);

	if (!crtc_state->has_drrs)
		return;

	if (!crtc_state->hw.active)
		return;

	if (intel_crtc_is_joiner_secondary(crtc_state))
		return;

	mutex_lock(&crtc->drrs.mutex);

	crtc->drrs.cpu_transcoder = crtc_state->cpu_transcoder;
	crtc->drrs.m_n = crtc_state->dp_m_n;
	crtc->drrs.m2_n2 = crtc_state->dp_m2_n2;
	crtc->drrs.frontbuffer_bits = intel_drrs_frontbuffer_bits(crtc_state);
	crtc->drrs.busy_frontbuffer_bits = 0;

	intel_drrs_schedule_work(crtc);

	mutex_unlock(&crtc->drrs.mutex);
}

/**
 * intel_drrs_deactivate - deactivate DRRS
 * @old_crtc_state: the old crtc state
 *
 * Deactivates DRRS on the crtc.
 */
void intel_drrs_deactivate(const struct intel_crtc_state *old_crtc_state)
{
	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);

	if (!old_crtc_state->has_drrs)
		return;

	if (!old_crtc_state->hw.active)
		return;

	if (intel_crtc_is_joiner_secondary(old_crtc_state))
		return;

	mutex_lock(&crtc->drrs.mutex);

	if (intel_drrs_is_active(crtc))
		intel_drrs_set_state(crtc, DRRS_REFRESH_RATE_HIGH);

	crtc->drrs.cpu_transcoder = INVALID_TRANSCODER;
	crtc->drrs.frontbuffer_bits = 0;
	crtc->drrs.busy_frontbuffer_bits = 0;

	mutex_unlock(&crtc->drrs.mutex);

	cancel_delayed_work_sync(&crtc->drrs.work);
}

static void intel_drrs_downclock_work(struct work_struct *work)
{
	struct intel_crtc *crtc = container_of(work, typeof(*crtc), drrs.work.work);

	mutex_lock(&crtc->drrs.mutex);

	if (intel_drrs_is_active(crtc) && !crtc->drrs.busy_frontbuffer_bits)
		intel_drrs_set_state(crtc, DRRS_REFRESH_RATE_LOW);

	mutex_unlock(&crtc->drrs.mutex);
}

static void intel_drrs_frontbuffer_update(struct intel_display *display,
					  unsigned int all_frontbuffer_bits,
					  bool invalidate)
{
	struct intel_crtc *crtc;

	for_each_intel_crtc(display->drm, crtc) {
		unsigned int frontbuffer_bits;

		mutex_lock(&crtc->drrs.mutex);

		frontbuffer_bits = all_frontbuffer_bits & crtc->drrs.frontbuffer_bits;
		if (!frontbuffer_bits) {
			mutex_unlock(&crtc->drrs.mutex);
			continue;
		}

		if (invalidate)
			crtc->drrs.busy_frontbuffer_bits |= frontbuffer_bits;
		else
			crtc->drrs.busy_frontbuffer_bits &= ~frontbuffer_bits;

		/* flush/invalidate means busy screen hence upclock */
		intel_drrs_set_state(crtc, DRRS_REFRESH_RATE_HIGH);

		/*
		 * flush also means no more activity hence schedule downclock, if all
		 * other fbs are quiescent too
		 */
		if (!crtc->drrs.busy_frontbuffer_bits)
			intel_drrs_schedule_work(crtc);
		else
			cancel_delayed_work(&crtc->drrs.work);

		mutex_unlock(&crtc->drrs.mutex);
	}
}

/**
 * intel_drrs_invalidate - Disable Idleness DRRS
 * @display: display device
 * @frontbuffer_bits: frontbuffer plane tracking bits
 *
 * This function gets called everytime rendering on the given planes start.
 * Hence DRRS needs to be Upclocked, i.e. (LOW_RR -> HIGH_RR).
 *
 * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits.
 */
void intel_drrs_invalidate(struct intel_display *display,
			   unsigned int frontbuffer_bits)
{
	intel_drrs_frontbuffer_update(display, frontbuffer_bits, true);
}

/**
 * intel_drrs_flush - Restart Idleness DRRS
 * @display: display device
 * @frontbuffer_bits: frontbuffer plane tracking bits
 *
 * This function gets called every time rendering on the given planes has
 * completed or flip on a crtc is completed. So DRRS should be upclocked
 * (LOW_RR -> HIGH_RR). And also Idleness detection should be started again,
 * if no other planes are dirty.
 *
 * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits.
 */
void intel_drrs_flush(struct intel_display *display,
		      unsigned int frontbuffer_bits)
{
	intel_drrs_frontbuffer_update(display, frontbuffer_bits, false);
}

/**
 * intel_drrs_crtc_init - Init DRRS for CRTC
 * @crtc: crtc
 *
 * This function is called only once at driver load to initialize basic
 * DRRS stuff.
 *
 */
void intel_drrs_crtc_init(struct intel_crtc *crtc)
{
	INIT_DELAYED_WORK(&crtc->drrs.work, intel_drrs_downclock_work);
	mutex_init(&crtc->drrs.mutex);
	crtc->drrs.cpu_transcoder = INVALID_TRANSCODER;
}

static int intel_drrs_debugfs_status_show(struct seq_file *m, void *unused)
{
	struct intel_crtc *crtc = m->private;
	struct intel_display *display = to_intel_display(crtc);
	const struct intel_crtc_state *crtc_state;
	int ret;

	ret = drm_modeset_lock_single_interruptible(&crtc->base.mutex);
	if (ret)
		return ret;

	crtc_state = to_intel_crtc_state(crtc->base.state);

	mutex_lock(&crtc->drrs.mutex);

	seq_printf(m, "DRRS capable: %s\n",
		   str_yes_no(intel_cpu_transcoder_has_drrs(display,
							    crtc_state->cpu_transcoder)));

	seq_printf(m, "DRRS enabled: %s\n",
		   str_yes_no(crtc_state->has_drrs));

	seq_printf(m, "DRRS active: %s\n",
		   str_yes_no(intel_drrs_is_active(crtc)));

	seq_printf(m, "DRRS refresh rate: %s\n",
		   crtc->drrs.refresh_rate == DRRS_REFRESH_RATE_LOW ?
		   "low" : "high");

	seq_printf(m, "DRRS busy frontbuffer bits: 0x%x\n",
		   crtc->drrs.busy_frontbuffer_bits);

	mutex_unlock(&crtc->drrs.mutex);

	drm_modeset_unlock(&crtc->base.mutex);

	return 0;
}

DEFINE_SHOW_ATTRIBUTE(intel_drrs_debugfs_status);

static int intel_drrs_debugfs_ctl_set(void *data, u64 val)
{
	struct intel_crtc *crtc = data;
	struct intel_display *display = to_intel_display(crtc);
	struct intel_crtc_state *crtc_state;
	struct drm_crtc_commit *commit;
	int ret;

	ret = drm_modeset_lock_single_interruptible(&crtc->base.mutex);
	if (ret)
		return ret;

	crtc_state = to_intel_crtc_state(crtc->base.state);

	if (!crtc_state->hw.active ||
	    !crtc_state->has_drrs)
		goto out;

	commit = crtc_state->uapi.commit;
	if (commit) {
		ret = wait_for_completion_interruptible(&commit->hw_done);
		if (ret)
			goto out;
	}

	drm_dbg_kms(display->drm, "Manually %sactivating DRRS\n", val ? "" : "de");

	if (val)
		intel_drrs_activate(crtc_state);
	else
		intel_drrs_deactivate(crtc_state);

out:
	drm_modeset_unlock(&crtc->base.mutex);

	return ret;
}

DEFINE_DEBUGFS_ATTRIBUTE(intel_drrs_debugfs_ctl_fops,
			 NULL, intel_drrs_debugfs_ctl_set, "%llu\n");

void intel_drrs_crtc_debugfs_add(struct intel_crtc *crtc)
{
	debugfs_create_file("i915_drrs_status", 0444, crtc->base.debugfs_entry,
			    crtc, &intel_drrs_debugfs_status_fops);

	debugfs_create_file_unsafe("i915_drrs_ctl", 0644, crtc->base.debugfs_entry,
				   crtc, &intel_drrs_debugfs_ctl_fops);
}

static int intel_drrs_debugfs_type_show(struct seq_file *m, void *unused)
{
	struct intel_connector *connector = m->private;

	seq_printf(m, "DRRS type: %s\n",
		   intel_drrs_type_str(intel_panel_drrs_type(connector)));

	return 0;
}

DEFINE_SHOW_ATTRIBUTE(intel_drrs_debugfs_type);

void intel_drrs_connector_debugfs_add(struct intel_connector *connector)
{
	if (intel_panel_drrs_type(connector) == DRRS_TYPE_NONE)
		return;

	debugfs_create_file("i915_drrs_type", 0444, connector->base.debugfs_entry,
			    connector, &intel_drrs_debugfs_type_fops);
}
