cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

hsw_ips.c (7633B)


      1// SPDX-License-Identifier: MIT
      2/*
      3 * Copyright © 2022 Intel Corporation
      4 */
      5
      6#include "hsw_ips.h"
      7#include "i915_drv.h"
      8#include "i915_reg.h"
      9#include "intel_de.h"
     10#include "intel_display_types.h"
     11#include "intel_pcode.h"
     12
     13static void hsw_ips_enable(const struct intel_crtc_state *crtc_state)
     14{
     15	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
     16	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
     17
     18	if (!crtc_state->ips_enabled)
     19		return;
     20
     21	/*
     22	 * We can only enable IPS after we enable a plane and wait for a vblank
     23	 * This function is called from post_plane_update, which is run after
     24	 * a vblank wait.
     25	 */
     26	drm_WARN_ON(&i915->drm,
     27		    !(crtc_state->active_planes & ~BIT(PLANE_CURSOR)));
     28
     29	if (IS_BROADWELL(i915)) {
     30		drm_WARN_ON(&i915->drm,
     31			    snb_pcode_write(i915, DISPLAY_IPS_CONTROL,
     32					    IPS_ENABLE | IPS_PCODE_CONTROL));
     33		/*
     34		 * Quoting Art Runyan: "its not safe to expect any particular
     35		 * value in IPS_CTL bit 31 after enabling IPS through the
     36		 * mailbox." Moreover, the mailbox may return a bogus state,
     37		 * so we need to just enable it and continue on.
     38		 */
     39	} else {
     40		intel_de_write(i915, IPS_CTL, IPS_ENABLE);
     41		/*
     42		 * The bit only becomes 1 in the next vblank, so this wait here
     43		 * is essentially intel_wait_for_vblank. If we don't have this
     44		 * and don't wait for vblanks until the end of crtc_enable, then
     45		 * the HW state readout code will complain that the expected
     46		 * IPS_CTL value is not the one we read.
     47		 */
     48		if (intel_de_wait_for_set(i915, IPS_CTL, IPS_ENABLE, 50))
     49			drm_err(&i915->drm,
     50				"Timed out waiting for IPS enable\n");
     51	}
     52}
     53
     54bool hsw_ips_disable(const struct intel_crtc_state *crtc_state)
     55{
     56	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
     57	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
     58	bool need_vblank_wait = false;
     59
     60	if (!crtc_state->ips_enabled)
     61		return need_vblank_wait;
     62
     63	if (IS_BROADWELL(i915)) {
     64		drm_WARN_ON(&i915->drm,
     65			    snb_pcode_write(i915, DISPLAY_IPS_CONTROL, 0));
     66		/*
     67		 * Wait for PCODE to finish disabling IPS. The BSpec specified
     68		 * 42ms timeout value leads to occasional timeouts so use 100ms
     69		 * instead.
     70		 */
     71		if (intel_de_wait_for_clear(i915, IPS_CTL, IPS_ENABLE, 100))
     72			drm_err(&i915->drm,
     73				"Timed out waiting for IPS disable\n");
     74	} else {
     75		intel_de_write(i915, IPS_CTL, 0);
     76		intel_de_posting_read(i915, IPS_CTL);
     77	}
     78
     79	/* We need to wait for a vblank before we can disable the plane. */
     80	need_vblank_wait = true;
     81
     82	return need_vblank_wait;
     83}
     84
     85static bool hsw_ips_need_disable(struct intel_atomic_state *state,
     86				 struct intel_crtc *crtc)
     87{
     88	struct drm_i915_private *i915 = to_i915(state->base.dev);
     89	const struct intel_crtc_state *old_crtc_state =
     90		intel_atomic_get_old_crtc_state(state, crtc);
     91	const struct intel_crtc_state *new_crtc_state =
     92		intel_atomic_get_new_crtc_state(state, crtc);
     93
     94	if (!old_crtc_state->ips_enabled)
     95		return false;
     96
     97	if (intel_crtc_needs_modeset(new_crtc_state))
     98		return true;
     99
    100	/*
    101	 * Workaround : Do not read or write the pipe palette/gamma data while
    102	 * GAMMA_MODE is configured for split gamma and IPS_CTL has IPS enabled.
    103	 *
    104	 * Disable IPS before we program the LUT.
    105	 */
    106	if (IS_HASWELL(i915) &&
    107	    (new_crtc_state->uapi.color_mgmt_changed ||
    108	     new_crtc_state->update_pipe) &&
    109	    new_crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)
    110		return true;
    111
    112	return !new_crtc_state->ips_enabled;
    113}
    114
    115bool hsw_ips_pre_update(struct intel_atomic_state *state,
    116			struct intel_crtc *crtc)
    117{
    118	const struct intel_crtc_state *old_crtc_state =
    119		intel_atomic_get_old_crtc_state(state, crtc);
    120
    121	if (!hsw_ips_need_disable(state, crtc))
    122		return false;
    123
    124	return hsw_ips_disable(old_crtc_state);
    125}
    126
    127static bool hsw_ips_need_enable(struct intel_atomic_state *state,
    128				struct intel_crtc *crtc)
    129{
    130	struct drm_i915_private *i915 = to_i915(state->base.dev);
    131	const struct intel_crtc_state *old_crtc_state =
    132		intel_atomic_get_old_crtc_state(state, crtc);
    133	const struct intel_crtc_state *new_crtc_state =
    134		intel_atomic_get_new_crtc_state(state, crtc);
    135
    136	if (!new_crtc_state->ips_enabled)
    137		return false;
    138
    139	if (intel_crtc_needs_modeset(new_crtc_state))
    140		return true;
    141
    142	/*
    143	 * Workaround : Do not read or write the pipe palette/gamma data while
    144	 * GAMMA_MODE is configured for split gamma and IPS_CTL has IPS enabled.
    145	 *
    146	 * Re-enable IPS after the LUT has been programmed.
    147	 */
    148	if (IS_HASWELL(i915) &&
    149	    (new_crtc_state->uapi.color_mgmt_changed ||
    150	     new_crtc_state->update_pipe) &&
    151	    new_crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)
    152		return true;
    153
    154	/*
    155	 * We can't read out IPS on broadwell, assume the worst and
    156	 * forcibly enable IPS on the first fastset.
    157	 */
    158	if (new_crtc_state->update_pipe && old_crtc_state->inherited)
    159		return true;
    160
    161	return !old_crtc_state->ips_enabled;
    162}
    163
    164void hsw_ips_post_update(struct intel_atomic_state *state,
    165			 struct intel_crtc *crtc)
    166{
    167	const struct intel_crtc_state *new_crtc_state =
    168		intel_atomic_get_new_crtc_state(state, crtc);
    169
    170	if (!hsw_ips_need_enable(state, crtc))
    171		return;
    172
    173	hsw_ips_enable(new_crtc_state);
    174}
    175
    176/* IPS only exists on ULT machines and is tied to pipe A. */
    177bool hsw_crtc_supports_ips(struct intel_crtc *crtc)
    178{
    179	return HAS_IPS(to_i915(crtc->base.dev)) && crtc->pipe == PIPE_A;
    180}
    181
    182bool hsw_crtc_state_ips_capable(const struct intel_crtc_state *crtc_state)
    183{
    184	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
    185	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
    186
    187	/* IPS only exists on ULT machines and is tied to pipe A. */
    188	if (!hsw_crtc_supports_ips(crtc))
    189		return false;
    190
    191	if (!i915->params.enable_ips)
    192		return false;
    193
    194	if (crtc_state->pipe_bpp > 24)
    195		return false;
    196
    197	/*
    198	 * We compare against max which means we must take
    199	 * the increased cdclk requirement into account when
    200	 * calculating the new cdclk.
    201	 *
    202	 * Should measure whether using a lower cdclk w/o IPS
    203	 */
    204	if (IS_BROADWELL(i915) &&
    205	    crtc_state->pixel_rate > i915->max_cdclk_freq * 95 / 100)
    206		return false;
    207
    208	return true;
    209}
    210
    211int hsw_ips_compute_config(struct intel_atomic_state *state,
    212			   struct intel_crtc *crtc)
    213{
    214	struct drm_i915_private *i915 = to_i915(state->base.dev);
    215	struct intel_crtc_state *crtc_state =
    216		intel_atomic_get_new_crtc_state(state, crtc);
    217
    218	crtc_state->ips_enabled = false;
    219
    220	if (!hsw_crtc_state_ips_capable(crtc_state))
    221		return 0;
    222
    223	/*
    224	 * When IPS gets enabled, the pipe CRC changes. Since IPS gets
    225	 * enabled and disabled dynamically based on package C states,
    226	 * user space can't make reliable use of the CRCs, so let's just
    227	 * completely disable it.
    228	 */
    229	if (crtc_state->crc_enabled)
    230		return 0;
    231
    232	/* IPS should be fine as long as at least one plane is enabled. */
    233	if (!(crtc_state->active_planes & ~BIT(PLANE_CURSOR)))
    234		return 0;
    235
    236	if (IS_BROADWELL(i915)) {
    237		const struct intel_cdclk_state *cdclk_state;
    238
    239		cdclk_state = intel_atomic_get_cdclk_state(state);
    240		if (IS_ERR(cdclk_state))
    241			return PTR_ERR(cdclk_state);
    242
    243		/* pixel rate mustn't exceed 95% of cdclk with IPS on BDW */
    244		if (crtc_state->pixel_rate > cdclk_state->logical.cdclk * 95 / 100)
    245			return 0;
    246	}
    247
    248	crtc_state->ips_enabled = true;
    249
    250	return 0;
    251}
    252
    253void hsw_ips_get_config(struct intel_crtc_state *crtc_state)
    254{
    255	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
    256	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
    257
    258	if (!hsw_crtc_supports_ips(crtc))
    259		return;
    260
    261	if (IS_HASWELL(i915)) {
    262		crtc_state->ips_enabled = intel_de_read(i915, IPS_CTL) & IPS_ENABLE;
    263	} else {
    264		/*
    265		 * We cannot readout IPS state on broadwell, set to
    266		 * true so we can set it to a defined state on first
    267		 * commit.
    268		 */
    269		crtc_state->ips_enabled = true;
    270	}
    271}