Commit 4c4cc7ac authored by Mika Kahola's avatar Mika Kahola Committed by Radhakrishna Sripada
Browse files

drm/i915/mtl: Add support for PM DEMAND



MTL introduces a new way to instruct the PUnit with
power and bandwidth requirements of DE. Add the functionality
to program the registers and handle waits using interrupts.
The current wait time for timeouts is programmed for 10 msecs to
factor in the worst case scenarios. Changes made to use REG_BIT
for a register that we touched(GEN8_DE_MISC_IER _MMIO).

Wa_14016740474 is added which applies to Xe_LPD+ display

v2: checkpatch warning fixes, simplify program pmdemand part

v3: update to dbufs and pipes values to pmdemand register(stan)
    Removed the macro usage in update_pmdemand_values()

v4: move the pmdemand_pre_plane_update before cdclk update
    pmdemand_needs_update included cdclk params comparisons
    pmdemand_state NULL check (Gustavo)
    pmdemand.o in sorted order in the makefile (Jani)
    update pmdemand misc irq handler loop (Gustavo)
    active phys bitmask and programming correction (Gustavo)

v5: simplify pmdemand_state structure
    simplify methods to find active phys and max port clock
    Timeout in case of previou pmdemand task pending (Gustavo)

v6: rebasing
    updates to max_ddiclk calculations (Gustavo)
    updates to active_phys count method (Gustavo)

v7: use two separate loop to iterate throug old and new
    crtc states to calculate the active phys (Gustavo)

v8: use uniform function names (Gustavo)

v9: For phys change iterate through connectors (Imre)
    Look for change in phys for pmdemand update (Gustavo, Imre)
    Some more stlying changes (Imre)
    Update pmdemand state during HW readout/sanitize (Imre)

v10: Fix CI checkpatch warnings

v11: use correct pmdemand object pointer during hw readout,
     simplify the check for phys need update (Gustavo)

v12: Handle possible non serialize cases (Imre)
     Initialise also pmdemand params HW readout (Imre)
     Update active phys mask during sanitize calls (Imre)
     Check TC/encoder changes to limit connector update (Imre)

v13: Check display version before accessing pmdemand functions

v14: Move is_serialized to intel_global_state.c
     simplify update params and other stlying issues (Imre)

Bspec: 66451, 64636, 64602, 64603
Cc: Matt Atwood <matthew.s.atwood@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Lucas De Marchi <lucas.demarchi@intel.com>
Cc: Gustavo Sousa <gustavo.sousa@intel.com>
Signed-off-by: default avatarJosé Roberto de Souza <jose.souza@intel.com>
Signed-off-by: default avatarGustavo Sousa <gustavo.sousa@intel.com>
Signed-off-by: default avatarMika Kahola <mika.kahola@intel.com>
Signed-off-by: default avatarVinod Govindapillai <vinod.govindapillai@intel.com>
Reviewed-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com> #v4
Acked-by: Gustavo Sousa <gustavo.sousa@intel.com> #v11
Reviewed-by: default avatarImre Deak <imre.deak@intel.com>
[RK: Fixed minor typo in one of the comments. s/qclck_gc/qclk_gv/]
Signed-off-by: default avatarRadhakrishna Sripada <radhakrishna.sripada@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230606201032.347449-1-vinod.govindapillai@intel.com
parent a5819e51
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -269,6 +269,7 @@ i915-y += \
	display/intel_pch_display.o \
	display/intel_pch_refclk.o \
	display/intel_plane_initial.o \
	display/intel_pmdemand.o \
	display/intel_psr.o \
	display/intel_quirks.o \
	display/intel_sprite.o \
+14 −0
Original line number Diff line number Diff line
@@ -99,6 +99,7 @@
#include "intel_pcode.h"
#include "intel_pipe_crc.h"
#include "intel_plane_initial.h"
#include "intel_pmdemand.h"
#include "intel_pps.h"
#include "intel_psr.h"
#include "intel_sdvo.h"
@@ -6354,6 +6355,10 @@ int intel_atomic_check(struct drm_device *dev,
			return ret;
	}

	ret = intel_pmdemand_atomic_check(state);
	if (ret)
		goto fail;

	ret = intel_atomic_check_crtcs(state);
	if (ret)
		goto fail;
@@ -6999,6 +7004,14 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
	for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i)
		crtc->config = new_crtc_state;

	/*
	 * In XE_LPD+ Pmdemand combines many parameters such as voltage index,
	 * plls, cdclk frequency, QGV point selection parameter etc. Voltage
	 * index, cdclk/ddiclk frequencies are supposed to be configured before
	 * the cdclk config is set.
	 */
	intel_pmdemand_pre_plane_update(state);

	if (state->modeset) {
		drm_atomic_helper_update_legacy_modeset_state(dev, &state->base);

@@ -7118,6 +7131,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
		intel_verify_planes(state);

	intel_sagv_post_plane_update(state);
	intel_pmdemand_post_plane_update(state);

	drm_atomic_helper_commit_hw_done(&state->base);

+9 −0
Original line number Diff line number Diff line
@@ -345,6 +345,15 @@ struct intel_display {
		struct intel_global_obj obj;
	} dbuf;

	struct {
		wait_queue_head_t waitqueue;

		/* mutex to protect pmdemand programming sequence */
		struct mutex lock;

		struct intel_global_obj obj;
	} pmdemand;

	struct {
		/*
		 * dkl.phy_lock protects against concurrent access of the
+7 −0
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@
#include "intel_opregion.h"
#include "intel_overlay.h"
#include "intel_plane_initial.h"
#include "intel_pmdemand.h"
#include "intel_pps.h"
#include "intel_quirks.h"
#include "intel_vga.h"
@@ -211,6 +212,8 @@ int intel_display_driver_probe_noirq(struct drm_i915_private *i915)
	if (ret < 0)
		goto cleanup_vga;

	intel_pmdemand_init_early(i915);

	intel_power_domains_init_hw(i915, false);

	if (!HAS_DISPLAY(i915))
@@ -240,6 +243,10 @@ int intel_display_driver_probe_noirq(struct drm_i915_private *i915)
	if (ret)
		goto cleanup_vga_client_pw_domain_dmc;

	ret = intel_pmdemand_init(i915);
	if (ret)
		goto cleanup_vga_client_pw_domain_dmc;

	init_llist_head(&i915->display.atomic_helper.free_list);
	INIT_WORK(&i915->display.atomic_helper.free_work,
		  intel_atomic_helper_free_state_worker);
+21 −2
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#include "intel_fifo_underrun.h"
#include "intel_gmbus.h"
#include "intel_hotplug_irq.h"
#include "intel_pmdemand.h"
#include "intel_psr.h"
#include "intel_psr_regs.h"

@@ -827,12 +828,27 @@ static u32 gen8_de_pipe_fault_mask(struct drm_i915_private *dev_priv)
		return GEN8_DE_PIPE_IRQ_FAULT_ERRORS;
}

static void intel_pmdemand_irq_handler(struct drm_i915_private *dev_priv)
{
	wake_up_all(&dev_priv->display.pmdemand.waitqueue);
}

static void
gen8_de_misc_irq_handler(struct drm_i915_private *dev_priv, u32 iir)
{
	bool found = false;

	if (iir & GEN8_DE_MISC_GSE) {
	if (DISPLAY_VER(dev_priv) >= 14) {
		if (iir & (XELPDP_PMDEMAND_RSP |
			   XELPDP_PMDEMAND_RSPTOUT_ERR)) {
			if (iir & XELPDP_PMDEMAND_RSPTOUT_ERR)
				drm_dbg(&dev_priv->drm,
					"Error waiting for Punit PM Demand Response\n");

			intel_pmdemand_irq_handler(dev_priv);
			found = true;
		}
	} else if (iir & GEN8_DE_MISC_GSE) {
		intel_opregion_asle_intr(dev_priv);
		found = true;
	}
@@ -1576,7 +1592,10 @@ void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv)
	if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
		de_port_masked |= BXT_DE_PORT_GMBUS;

	if (DISPLAY_VER(dev_priv) >= 11) {
	if (DISPLAY_VER(dev_priv) >= 14) {
		de_misc_masked |= XELPDP_PMDEMAND_RSPTOUT_ERR |
				  XELPDP_PMDEMAND_RSP;
	} else if (DISPLAY_VER(dev_priv) >= 11) {
		enum port port;

		if (intel_bios_is_dsi_present(dev_priv, &port))
Loading