Commit 35ec7128 authored by Ville Syrjälä's avatar Ville Syrjälä
Browse files

drm/i915/pc8: Add parent interface for PC8 forcewake tricks



We use forcewake to prevent the SoC from actually entering
PC8 while performing the PC8 disable sequence. Hide that
behind a new parent interface to eliminate the naked
forcewake/uncore usage from the display power code.

v2: Mark the interface optional and warn if
    someone calls it when not provided (Jani)
    Include the header to make sure the extern
    declaration matches the definition (Jani)
v3: Rebase due to shuffling

Reviewed-by: default avatarJani Nikula <jani.nikula@intel.com>
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patch.msgid.link/20251218182052.18756-1-ville.syrjala@linux.intel.com
parent 9236cf0a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -76,6 +76,7 @@ i915-$(CONFIG_PERF_EVENTS) += \

# core display adaptation
i915-y += \
	i915_display_pc8.o \
	i915_hdcp_gsc.o \
	i915_panic.o

+4 −4
Original line number Diff line number Diff line
@@ -1339,10 +1339,10 @@ static void hsw_restore_lcpll(struct intel_display *display)
		return;

	/*
	 * Make sure we're not on PC8 state before disabling PC8, otherwise
	 * we'll hang the machine. To prevent PC8 state, just enable force_wake.
	 * Make sure we're not on PC8 state before disabling
	 * PC8, otherwise we'll hang the machine.
	 */
	intel_uncore_forcewake_get(&dev_priv->uncore, FORCEWAKE_ALL);
	intel_parent_pc8_block(display);

	if (val & LCPLL_POWER_DOWN_ALLOW) {
		val &= ~LCPLL_POWER_DOWN_ALLOW;
@@ -1372,7 +1372,7 @@ static void hsw_restore_lcpll(struct intel_display *display)
				"Switching back to LCPLL failed\n");
	}

	intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL);
	intel_parent_pc8_unblock(display);

	intel_update_cdclk(display);
	intel_cdclk_dump_config(display, &display->cdclk.hw, "Current CDCLK");
+17 −0
Original line number Diff line number Diff line
@@ -75,6 +75,23 @@ void intel_parent_panic_finish(struct intel_display *display, struct intel_panic
	display->parent->panic->finish(panic);
}

/* pc8 */
void intel_parent_pc8_block(struct intel_display *display)
{
	if (drm_WARN_ON_ONCE(display->drm, !display->parent->pc8))
		return;

	display->parent->pc8->block(display->drm);
}

void intel_parent_pc8_unblock(struct intel_display *display)
{
	if (drm_WARN_ON_ONCE(display->drm, !display->parent->pc8))
		return;

	display->parent->pc8->unblock(display->drm);
}

/* rps */
bool intel_parent_rps_available(struct intel_display *display)
{
+4 −0
Original line number Diff line number Diff line
@@ -32,6 +32,10 @@ struct intel_panic *intel_parent_panic_alloc(struct intel_display *display);
int intel_parent_panic_setup(struct intel_display *display, struct intel_panic *panic, struct drm_scanout_buffer *sb);
void intel_parent_panic_finish(struct intel_display *display, struct intel_panic *panic);

/* pc8 */
void intel_parent_pc8_block(struct intel_display *display);
void intel_parent_pc8_unblock(struct intel_display *display);

/* rps */
bool intel_parent_rps_available(struct intel_display *display);
void intel_parent_rps_boost_if_not_started(struct intel_display *display, struct dma_fence *fence);
+31 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: MIT
/*
 * Copyright 2025, Intel Corporation.
 */

#include <drm/drm_print.h>
#include <drm/intel/display_parent_interface.h>

#include "i915_display_pc8.h"
#include "i915_drv.h"
#include "intel_uncore.h"

static void i915_display_pc8_block(struct drm_device *drm)
{
	struct intel_uncore *uncore = &to_i915(drm)->uncore;

	/* to prevent PC8 state, just enable force_wake */
	intel_uncore_forcewake_get(uncore, FORCEWAKE_ALL);
}

static void i915_display_pc8_unblock(struct drm_device *drm)
{
	struct intel_uncore *uncore = &to_i915(drm)->uncore;

	intel_uncore_forcewake_put(uncore, FORCEWAKE_ALL);
}

const struct intel_display_pc8_interface i915_display_pc8_interface = {
	.block = i915_display_pc8_block,
	.unblock = i915_display_pc8_unblock,
};
Loading