1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2023 Intel Corporation 4 */ 5 6 #include "gt/intel_engine_pm.h" 7 #include "gt/intel_gpu_commands.h" 8 #include "gt/intel_gt.h" 9 #include "gt/intel_ring.h" 10 #include "intel_gsc_uc_heci_cmd_submit.h" 11 12 struct gsc_heci_pkt { 13 u64 addr_in; 14 u32 size_in; 15 u64 addr_out; 16 u32 size_out; 17 }; 18 19 static int emit_gsc_heci_pkt(struct i915_request *rq, struct gsc_heci_pkt *pkt) 20 { 21 u32 *cs; 22 23 cs = intel_ring_begin(rq, 8); 24 if (IS_ERR(cs)) 25 return PTR_ERR(cs); 26 27 *cs++ = GSC_HECI_CMD_PKT; 28 *cs++ = lower_32_bits(pkt->addr_in); 29 *cs++ = upper_32_bits(pkt->addr_in); 30 *cs++ = pkt->size_in; 31 *cs++ = lower_32_bits(pkt->addr_out); 32 *cs++ = upper_32_bits(pkt->addr_out); 33 *cs++ = pkt->size_out; 34 *cs++ = 0; 35 36 intel_ring_advance(rq, cs); 37 38 return 0; 39 } 40 41 int intel_gsc_uc_heci_cmd_submit_packet(struct intel_gsc_uc *gsc, u64 addr_in, 42 u32 size_in, u64 addr_out, 43 u32 size_out) 44 { 45 struct intel_context *ce = gsc->ce; 46 struct i915_request *rq; 47 struct gsc_heci_pkt pkt = { 48 .addr_in = addr_in, 49 .size_in = size_in, 50 .addr_out = addr_out, 51 .size_out = size_out 52 }; 53 int err; 54 55 if (!ce) 56 return -ENODEV; 57 58 rq = i915_request_create(ce); 59 if (IS_ERR(rq)) 60 return PTR_ERR(rq); 61 62 if (ce->engine->emit_init_breadcrumb) { 63 err = ce->engine->emit_init_breadcrumb(rq); 64 if (err) 65 goto out_rq; 66 } 67 68 err = emit_gsc_heci_pkt(rq, &pkt); 69 70 if (err) 71 goto out_rq; 72 73 err = ce->engine->emit_flush(rq, 0); 74 75 out_rq: 76 i915_request_get(rq); 77 78 if (unlikely(err)) 79 i915_request_set_error_once(rq, err); 80 81 i915_request_add(rq); 82 83 if (!err && i915_request_wait(rq, 0, msecs_to_jiffies(500)) < 0) 84 err = -ETIME; 85 86 i915_request_put(rq); 87 88 if (err) 89 drm_err(&gsc_uc_to_gt(gsc)->i915->drm, 90 "Request submission for GSC heci cmd failed (%d)\n", 91 err); 92 93 return err; 94 } 95 96 void intel_gsc_uc_heci_cmd_emit_mtl_header(struct intel_gsc_mtl_header *header, 97 u8 heci_client_id, u32 message_size, 98 u64 host_session_id) 99 { 100 host_session_id &= ~HOST_SESSION_MASK; 101 if (heci_client_id == HECI_MEADDRESS_PXP) 102 host_session_id |= HOST_SESSION_PXP_SINGLE; 103 104 header->validity_marker = GSC_HECI_VALIDITY_MARKER; 105 header->heci_client_id = heci_client_id; 106 header->host_session_handle = host_session_id; 107 header->header_version = MTL_GSC_HEADER_VERSION; 108 header->message_size = message_size; 109 } 110