98 lines · c
1// SPDX-License-Identifier: MIT2/*3 * Copyright © 2019 Intel Corporation4 */5 6#include "i915_drv.h"7#include "i915_vma.h"8#include "intel_context.h"9#include "intel_engine_pm.h"10#include "intel_gpu_commands.h"11#include "intel_lrc.h"12#include "intel_lrc_reg.h"13#include "intel_ring.h"14#include "intel_sseu.h"15 16static int gen8_emit_rpcs_config(struct i915_request *rq,17 const struct intel_context *ce,18 const struct intel_sseu sseu)19{20 u64 offset;21 u32 *cs;22 23 cs = intel_ring_begin(rq, 4);24 if (IS_ERR(cs))25 return PTR_ERR(cs);26 27 offset = i915_ggtt_offset(ce->state) +28 LRC_STATE_OFFSET + CTX_R_PWR_CLK_STATE * 4;29 30 *cs++ = MI_STORE_DWORD_IMM_GEN4 | MI_USE_GGTT;31 *cs++ = lower_32_bits(offset);32 *cs++ = upper_32_bits(offset);33 *cs++ = intel_sseu_make_rpcs(rq->engine->gt, &sseu);34 35 intel_ring_advance(rq, cs);36 37 return 0;38}39 40static int41gen8_modify_rpcs(struct intel_context *ce, const struct intel_sseu sseu)42{43 struct i915_request *rq;44 int ret;45 46 lockdep_assert_held(&ce->pin_mutex);47 48 /*49 * If the context is not idle, we have to submit an ordered request to50 * modify its context image via the kernel context (writing to our own51 * image, or into the registers directory, does not stick). Pristine52 * and idle contexts will be configured on pinning.53 */54 if (!intel_context_pin_if_active(ce))55 return 0;56 57 rq = intel_engine_create_kernel_request(ce->engine);58 if (IS_ERR(rq)) {59 ret = PTR_ERR(rq);60 goto out_unpin;61 }62 63 /* Serialise with the remote context */64 ret = intel_context_prepare_remote_request(ce, rq);65 if (ret == 0)66 ret = gen8_emit_rpcs_config(rq, ce, sseu);67 68 i915_request_add(rq);69out_unpin:70 intel_context_unpin(ce);71 return ret;72}73 74int75intel_context_reconfigure_sseu(struct intel_context *ce,76 const struct intel_sseu sseu)77{78 int ret;79 80 GEM_BUG_ON(GRAPHICS_VER(ce->engine->i915) < 8);81 82 ret = intel_context_lock_pinned(ce);83 if (ret)84 return ret;85 86 /* Nothing to do if unmodified. */87 if (!memcmp(&ce->sseu, &sseu, sizeof(sseu)))88 goto unlock;89 90 ret = gen8_modify_rpcs(ce, sseu);91 if (!ret)92 ce->sseu = sseu;93 94unlock:95 intel_context_unlock_pinned(ce);96 return ret;97}98