File Index
Files and directories
Sign in
FILE

intel_gsc_uc_heci_cmd_submit.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_heci_cmd_submit.c C
  1// SPDX-License-Identifier: MIT
  2/*
  3 * Copyright © 2023 Intel Corporation
  4 */
  5
  6#include <drm/drm_print.h>
  7
  8#include "gt/intel_context.h"
  9#include "gt/intel_engine_pm.h"
 10#include "gt/intel_gpu_commands.h"
 11#include "gt/intel_gt.h"
 12#include "gt/intel_ring.h"
 13
 14#include "i915_wait_util.h"
 15#include "intel_gsc_uc_heci_cmd_submit.h"
 16
 17struct gsc_heci_pkt {
 18	u64 addr_in;
 19	u32 size_in;
 20	u64 addr_out;
 21	u32 size_out;
 22};
 23
 24static int emit_gsc_heci_pkt(struct i915_request *rq, struct gsc_heci_pkt *pkt)
 25{
 26	u32 *cs;
 27
 28	cs = intel_ring_begin(rq, 8);
 29	if (IS_ERR(cs))
 30		return PTR_ERR(cs);
 31
 32	*cs++ = GSC_HECI_CMD_PKT;
 33	*cs++ = lower_32_bits(pkt->addr_in);
 34	*cs++ = upper_32_bits(pkt->addr_in);
 35	*cs++ = pkt->size_in;
 36	*cs++ = lower_32_bits(pkt->addr_out);
 37	*cs++ = upper_32_bits(pkt->addr_out);
 38	*cs++ = pkt->size_out;
 39	*cs++ = 0;
 40
 41	intel_ring_advance(rq, cs);
 42
 43	return 0;
 44}
 45
 46int intel_gsc_uc_heci_cmd_submit_packet(struct intel_gsc_uc *gsc, u64 addr_in,
 47					u32 size_in, u64 addr_out,
 48					u32 size_out)
 49{
 50	struct intel_context *ce = gsc->ce;
 51	struct i915_request *rq;
 52	struct gsc_heci_pkt pkt = {
 53	.addr_in = addr_in,
 54	.size_in = size_in,
 55	.addr_out = addr_out,
 56	.size_out = size_out
 57	};
 58	int err;
 59
 60	if (!ce)
 61		return -ENODEV;
 62
 63	rq = i915_request_create(ce);
 64	if (IS_ERR(rq))
 65		return PTR_ERR(rq);
 66
 67	if (ce->engine->emit_init_breadcrumb) {
 68		err = ce->engine->emit_init_breadcrumb(rq);
 69		if (err)
 70			goto out_rq;
 71	}
 72
 73	err = emit_gsc_heci_pkt(rq, &pkt);
 74
 75	if (err)
 76		goto out_rq;
 77
 78	err = ce->engine->emit_flush(rq, 0);
 79
 80out_rq:
 81	i915_request_get(rq);
 82
 83	if (unlikely(err))
 84		i915_request_set_error_once(rq, err);
 85
 86	i915_request_add(rq);
 87
 88	if (!err) {
 89		/*
 90		 * Start timeout for i915_request_wait only after considering one possible
 91		 * pending GSC-HECI submission cycle on the other (non-privileged) path.
 92		 */
 93		if (wait_for(i915_request_started(rq), GSC_HECI_REPLY_LATENCY_MS))
 94			drm_dbg(&gsc_uc_to_gt(gsc)->i915->drm,
 95				"Delay in gsc-heci-priv submission to gsccs-hw");
 96		if (i915_request_wait(rq, 0, msecs_to_jiffies(GSC_HECI_REPLY_LATENCY_MS)) < 0)
 97			err = -ETIME;
 98	}
 99
100	i915_request_put(rq);
101
102	if (err)
103		drm_err(&gsc_uc_to_gt(gsc)->i915->drm,
104			"Request submission for GSC heci cmd failed (%d)\n",
105			err);
106
107	return err;
108}
109
110void intel_gsc_uc_heci_cmd_emit_mtl_header(struct intel_gsc_mtl_header *header,
111					   u8 heci_client_id, u32 message_size,
112					   u64 host_session_id)
113{
114	host_session_id &= ~HOST_SESSION_MASK;
115	if (host_session_id && heci_client_id == HECI_MEADDRESS_PXP)
116		host_session_id |= HOST_SESSION_PXP_SINGLE;
117
118	header->validity_marker = GSC_HECI_VALIDITY_MARKER;
119	header->heci_client_id = heci_client_id;
120	header->host_session_handle = host_session_id;
121	header->header_version = MTL_GSC_HEADER_VERSION;
122	header->message_size = message_size;
123}
124
125static void
126emit_gsc_heci_pkt_nonpriv(u32 *cmd, struct intel_gsc_heci_non_priv_pkt *pkt)
127{
128	*cmd++ = GSC_HECI_CMD_PKT;
129	*cmd++ = lower_32_bits(pkt->addr_in);
130	*cmd++ = upper_32_bits(pkt->addr_in);
131	*cmd++ = pkt->size_in;
132	*cmd++ = lower_32_bits(pkt->addr_out);
133	*cmd++ = upper_32_bits(pkt->addr_out);
134	*cmd++ = pkt->size_out;
135	*cmd++ = 0;
136	*cmd++ = MI_BATCH_BUFFER_END;
137}
138
139int
140intel_gsc_uc_heci_cmd_submit_nonpriv(struct intel_gsc_uc *gsc,
141				     struct intel_context *ce,
142				     struct intel_gsc_heci_non_priv_pkt *pkt,
143				     u32 *cmd, int timeout_ms)
144{
145	struct intel_engine_cs *engine;
146	struct i915_gem_ww_ctx ww;
147	struct i915_request *rq;
148	int err, trials = 0;
149
150	i915_gem_ww_ctx_init(&ww, false);
151retry:
152	err = i915_gem_object_lock(pkt->bb_vma->obj, &ww);
153	if (err)
154		goto out_ww;
155	err = i915_gem_object_lock(pkt->heci_pkt_vma->obj, &ww);
156	if (err)
157		goto out_ww;
158	err = intel_context_pin_ww(ce, &ww);
159	if (err)
160		goto out_ww;
161
162	rq = i915_request_create(ce);
163	if (IS_ERR(rq)) {
164		err = PTR_ERR(rq);
165		goto out_unpin_ce;
166	}
167
168	emit_gsc_heci_pkt_nonpriv(cmd, pkt);
169
170	err = i915_vma_move_to_active(pkt->bb_vma, rq, 0);
171	if (err)
172		goto out_rq;
173	err = i915_vma_move_to_active(pkt->heci_pkt_vma, rq, EXEC_OBJECT_WRITE);
174	if (err)
175		goto out_rq;
176
177	engine = rq->context->engine;
178	if (engine->emit_init_breadcrumb) {
179		err = engine->emit_init_breadcrumb(rq);
180		if (err)
181			goto out_rq;
182	}
183
184	err = engine->emit_bb_start(rq, i915_vma_offset(pkt->bb_vma), PAGE_SIZE, 0);
185	if (err)
186		goto out_rq;
187
188	err = ce->engine->emit_flush(rq, 0);
189	if (err)
190		drm_err(&gsc_uc_to_gt(gsc)->i915->drm,
191			"Failed emit-flush for gsc-heci-non-priv-pkterr=%d\n", err);
192
193out_rq:
194	i915_request_get(rq);
195
196	if (unlikely(err))
197		i915_request_set_error_once(rq, err);
198
199	i915_request_add(rq);
200
201	if (!err) {
202		/*
203		 * Start timeout for i915_request_wait only after considering one possible
204		 * pending GSC-HECI submission cycle on the other (privileged) path.
205		 */
206		if (wait_for(i915_request_started(rq), GSC_HECI_REPLY_LATENCY_MS))
207			drm_dbg(&gsc_uc_to_gt(gsc)->i915->drm,
208				"Delay in gsc-heci-non-priv submission to gsccs-hw");
209		if (i915_request_wait(rq, I915_WAIT_INTERRUPTIBLE,
210				      msecs_to_jiffies(timeout_ms)) < 0)
211			err = -ETIME;
212	}
213
214	i915_request_put(rq);
215
216out_unpin_ce:
217	intel_context_unpin(ce);
218out_ww:
219	if (err == -EDEADLK) {
220		err = i915_gem_ww_ctx_backoff(&ww);
221		if (!err) {
222			if (++trials < 10)
223				goto retry;
224			else
225				err = -EAGAIN;
226		}
227	}
228	i915_gem_ww_ctx_fini(&ww);
229
230	return err;
231}
~/ Read-only file preview.