Lines Matching full:gsc
20 * GSC proxy:
21 * The GSC uC needs to communicate with the CSME to perform certain operations.
22 * Since the GSC can't perform this communication directly on platforms where it
23 * is integrated in GT, i915 needs to transfer the messages from GSC to CSME
24 * and back. i915 must manually start the proxy flow after the GSC is loaded to
25 * signal to GSC that we're ready to handle its messages and allow it to query
26 * its init data from CSME; GSC will then trigger an HECI2 interrupt if it needs
29 * 1 - i915 submits a request to GSC asking for the message to CSME
30 * 2 - GSC replies with the proxy header + payload for CSME
31 * 3 - i915 sends the reply from GSC as-is to CSME via the mei proxy component
32 * 4 - CSME replies with the proxy header + payload for GSC
33 * 5 - i915 submits a request to GSC with the reply from CSME
34 * 6 - GSC replies either with a new header + payload (same as step 2, so we
84 static int proxy_send_to_csme(struct intel_gsc_uc *gsc) in proxy_send_to_csme() argument
86 struct intel_gt *gt = gsc_uc_to_gt(gsc); in proxy_send_to_csme()
87 struct i915_gsc_proxy_component *comp = gsc->proxy.component; in proxy_send_to_csme()
89 void *in = gsc->proxy.to_csme; in proxy_send_to_csme()
90 void *out = gsc->proxy.to_gsc; in proxy_send_to_csme()
123 static int proxy_send_to_gsc(struct intel_gsc_uc *gsc) in proxy_send_to_gsc() argument
125 struct intel_gt *gt = gsc_uc_to_gt(gsc); in proxy_send_to_gsc()
126 u32 *marker = gsc->proxy.to_csme; /* first dw of the reply header */ in proxy_send_to_gsc()
127 u64 addr_in = i915_ggtt_offset(gsc->proxy.vma); in proxy_send_to_gsc()
129 u32 size = ((struct gsc_proxy_msg *)gsc->proxy.to_gsc)->header.message_size; in proxy_send_to_gsc()
132 /* the message must contain at least the gsc and proxy headers */ in proxy_send_to_gsc()
134 gt_err(gt, "Invalid GSC proxy message size: %u\n", size); in proxy_send_to_gsc()
145 err = intel_gsc_uc_heci_cmd_submit_packet(gsc, addr_in, size, in proxy_send_to_gsc()
152 gt_err(gt, "Failed to get a proxy reply from gsc\n"); in proxy_send_to_gsc()
186 static int proxy_query(struct intel_gsc_uc *gsc) in proxy_query() argument
188 struct intel_gt *gt = gsc_uc_to_gt(gsc); in proxy_query()
189 struct gsc_proxy_msg *to_gsc = gsc->proxy.to_gsc; in proxy_query()
190 struct gsc_proxy_msg *to_csme = gsc->proxy.to_csme; in proxy_query()
207 /* clear the GSC response header space */ in proxy_query()
208 memset(gsc->proxy.to_csme, 0, sizeof(struct gsc_proxy_msg)); in proxy_query()
210 /* send proxy message to GSC */ in proxy_query()
211 ret = proxy_send_to_gsc(gsc); in proxy_query()
213 gt_err(gt, "failed to send proxy message to GSC! %d\n", ret); in proxy_query()
222 /* make sure the GSC-to-CSME proxy header is sane */ in proxy_query()
227 gt_err(gt, "invalid GSC to CSME proxy header! %d\n", ret); in proxy_query()
231 /* send the GSC message to the CSME */ in proxy_query()
232 ret = proxy_send_to_csme(gsc); in proxy_query()
238 /* update the GSC message size with the returned value from CSME */ in proxy_query()
241 /* make sure the CSME-to-GSC proxy header is sane */ in proxy_query()
246 gt_err(gt, "invalid CSME to GSC proxy header! %d\n", ret); in proxy_query()
255 int intel_gsc_proxy_request_handler(struct intel_gsc_uc *gsc) in intel_gsc_proxy_request_handler() argument
257 struct intel_gt *gt = gsc_uc_to_gt(gsc); in intel_gsc_proxy_request_handler()
260 if (!gsc->proxy.component_added) in intel_gsc_proxy_request_handler()
265 /* when GSC is loaded, we can queue this before the component is bound */ in intel_gsc_proxy_request_handler()
266 err = wait_for(gsc->proxy.component, GSC_PROXY_INIT_TIMEOUT_MS); in intel_gsc_proxy_request_handler()
268 gt_err(gt, "GSC proxy component didn't bind within the expected timeout\n"); in intel_gsc_proxy_request_handler()
272 mutex_lock(&gsc->proxy.mutex); in intel_gsc_proxy_request_handler()
273 if (!gsc->proxy.component) { in intel_gsc_proxy_request_handler()
274 gt_err(gt, "GSC proxy worker called without the component being bound!\n"); in intel_gsc_proxy_request_handler()
284 err = proxy_query(gsc); in intel_gsc_proxy_request_handler()
286 mutex_unlock(&gsc->proxy.mutex); in intel_gsc_proxy_request_handler()
290 void intel_gsc_proxy_irq_handler(struct intel_gsc_uc *gsc, u32 iir) in intel_gsc_proxy_irq_handler() argument
292 struct intel_gt *gt = gsc_uc_to_gt(gsc); in intel_gsc_proxy_irq_handler()
299 if (!gsc->proxy.component) { in intel_gsc_proxy_irq_handler()
300 gt_err(gt, "GSC proxy irq received without the component being bound!\n"); in intel_gsc_proxy_irq_handler()
304 gsc->gsc_work_actions |= GSC_ACTION_SW_PROXY; in intel_gsc_proxy_irq_handler()
305 queue_work(gsc->wq, &gsc->work); in intel_gsc_proxy_irq_handler()
313 struct intel_gsc_uc *gsc = >->uc.gsc; in i915_gsc_proxy_component_bind() local
321 mutex_lock(&gsc->proxy.mutex); in i915_gsc_proxy_component_bind()
322 gsc->proxy.component = data; in i915_gsc_proxy_component_bind()
323 gsc->proxy.component->mei_dev = mei_kdev; in i915_gsc_proxy_component_bind()
324 mutex_unlock(&gsc->proxy.mutex); in i915_gsc_proxy_component_bind()
325 gt_dbg(gt, "GSC proxy mei component bound\n"); in i915_gsc_proxy_component_bind()
335 struct intel_gsc_uc *gsc = >->uc.gsc; in i915_gsc_proxy_component_unbind() local
338 mutex_lock(&gsc->proxy.mutex); in i915_gsc_proxy_component_unbind()
339 gsc->proxy.component = NULL; in i915_gsc_proxy_component_unbind()
340 mutex_unlock(&gsc->proxy.mutex); in i915_gsc_proxy_component_unbind()
346 gt_dbg(gt, "GSC proxy mei component unbound\n"); in i915_gsc_proxy_component_unbind()
354 static int proxy_channel_alloc(struct intel_gsc_uc *gsc) in proxy_channel_alloc() argument
356 struct intel_gt *gt = gsc_uc_to_gt(gsc); in proxy_channel_alloc()
367 gsc->proxy.vma = vma; in proxy_channel_alloc()
368 gsc->proxy.to_gsc = vaddr; in proxy_channel_alloc()
369 gsc->proxy.to_csme = vaddr + GSC_PROXY_BUFFER_SIZE; in proxy_channel_alloc()
374 static void proxy_channel_free(struct intel_gsc_uc *gsc) in proxy_channel_free() argument
376 if (!gsc->proxy.vma) in proxy_channel_free()
379 gsc->proxy.to_gsc = NULL; in proxy_channel_free()
380 gsc->proxy.to_csme = NULL; in proxy_channel_free()
381 i915_vma_unpin_and_release(&gsc->proxy.vma, I915_VMA_RELEASE_MAP); in proxy_channel_free()
384 void intel_gsc_proxy_fini(struct intel_gsc_uc *gsc) in intel_gsc_proxy_fini() argument
386 struct intel_gt *gt = gsc_uc_to_gt(gsc); in intel_gsc_proxy_fini()
389 if (fetch_and_zero(&gsc->proxy.component_added)) in intel_gsc_proxy_fini()
392 proxy_channel_free(gsc); in intel_gsc_proxy_fini()
395 int intel_gsc_proxy_init(struct intel_gsc_uc *gsc) in intel_gsc_proxy_init() argument
398 struct intel_gt *gt = gsc_uc_to_gt(gsc); in intel_gsc_proxy_init()
401 mutex_init(&gsc->proxy.mutex); in intel_gsc_proxy_init()
404 gt_info(gt, "can't init GSC proxy due to missing mei component\n"); in intel_gsc_proxy_init()
408 err = proxy_channel_alloc(gsc); in intel_gsc_proxy_init()
419 gsc->proxy.component_added = true; in intel_gsc_proxy_init()
424 proxy_channel_free(gsc); in intel_gsc_proxy_init()