Skip to content

Commit

Permalink
drm/xe/gsc: Initialize GSC proxy
Browse files Browse the repository at this point in the history
The GSC uC needs to communicate with the CSME to perform certain
operations. Since the GSC can't perform this communication directly on
platforms where it is integrated in GT, the graphics driver needs to
transfer the messages from GSC to CSME and back. The proxy flow must be
manually started after the GSC is loaded to signal to GSC that we're
ready to handle its messages and allow it to query its init data from
CSME.

Note that the component must be removed before the pci_remove call
completes, so we can't use a drmm helper for it and we need to instead
perform the cleanup as part of the removal flow.

v2: add function documentation, more targeted memory clear, clearer logs
and variable names (Alan)

Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Alan Previn <alan.previn.teres.alexis@intel.com>
Cc: Suraj Kandpal <suraj.kandpal@intel.com>
Reviewed-by: Alan Previn <alan.previn.teres.alexis@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240117182621.2653049-2-daniele.ceraolospurio@intel.com
  • Loading branch information
Daniele Ceraolo Spurio committed Jan 18, 2024
1 parent 6af7ee0 commit 997a55c
Show file tree
Hide file tree
Showing 14 changed files with 659 additions and 13 deletions.
1 change: 1 addition & 0 deletions drivers/gpu/drm/xe/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ xe-y += xe_bb.o \
xe_ggtt.o \
xe_gpu_scheduler.o \
xe_gsc.o \
xe_gsc_proxy.o \
xe_gsc_submit.o \
xe_gt.o \
xe_gt_ccs_mode.o \
Expand Down
44 changes: 44 additions & 0 deletions drivers/gpu/drm/xe/abi/gsc_proxy_commands_abi.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/* SPDX-License-Identifier: MIT */
/*
* Copyright © 2023 Intel Corporation
*/

#ifndef _ABI_GSC_PROXY_COMMANDS_ABI_H
#define _ABI_GSC_PROXY_COMMANDS_ABI_H

#include <linux/types.h>

/* Heci client ID for proxy commands */
#define HECI_MEADDRESS_PROXY 10

/* FW-defined proxy header */
struct xe_gsc_proxy_header {
/*
* hdr:
* Bits 0-7: type of the proxy message (see enum xe_gsc_proxy_type)
* Bits 8-15: rsvd
* Bits 16-31: length in bytes of the payload following the proxy header
*/
u32 hdr;
#define GSC_PROXY_TYPE GENMASK(7, 0)
#define GSC_PROXY_PAYLOAD_LENGTH GENMASK(31, 16)

u32 source; /* Source of the Proxy message */
u32 destination; /* Destination of the Proxy message */
#define GSC_PROXY_ADDRESSING_KMD 0x10000
#define GSC_PROXY_ADDRESSING_GSC 0x20000
#define GSC_PROXY_ADDRESSING_CSME 0x30000

u32 status; /* Command status */
} __packed;

/* FW-defined proxy types */
enum xe_gsc_proxy_type {
GSC_PROXY_MSG_TYPE_PROXY_INVALID = 0,
GSC_PROXY_MSG_TYPE_PROXY_QUERY = 1,
GSC_PROXY_MSG_TYPE_PROXY_PAYLOAD = 2,
GSC_PROXY_MSG_TYPE_PROXY_END = 3,
GSC_PROXY_MSG_TYPE_PROXY_NOTIFICATION = 4,
};

#endif
22 changes: 20 additions & 2 deletions drivers/gpu/drm/xe/xe_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "xe_exec_queue.h"
#include "xe_exec.h"
#include "xe_ggtt.h"
#include "xe_gsc_proxy.h"
#include "xe_gt.h"
#include "xe_gt_mcr.h"
#include "xe_irq.h"
Expand Down Expand Up @@ -434,6 +435,7 @@ int xe_device_probe(struct xe_device *xe)
struct xe_tile *tile;
struct xe_gt *gt;
int err;
u8 last_gt;
u8 id;

xe_pat_init_early(xe);
Expand Down Expand Up @@ -521,16 +523,18 @@ int xe_device_probe(struct xe_device *xe)
goto err_irq_shutdown;

for_each_gt(gt, xe, id) {
last_gt = id;

err = xe_gt_init(gt);
if (err)
goto err_irq_shutdown;
goto err_fini_gt;
}

xe_heci_gsc_init(xe);

err = xe_display_init(xe);
if (err)
goto err_irq_shutdown;
goto err_fini_gt;

err = drm_dev_register(&xe->drm, 0);
if (err)
Expand All @@ -551,6 +555,14 @@ int xe_device_probe(struct xe_device *xe)
err_fini_display:
xe_display_driver_remove(xe);

err_fini_gt:
for_each_gt(gt, xe, id) {
if (id < last_gt)
xe_gt_remove(gt);
else
break;
}

err_irq_shutdown:
xe_irq_shutdown(xe);
err:
Expand All @@ -568,12 +580,18 @@ static void xe_device_remove_display(struct xe_device *xe)

void xe_device_remove(struct xe_device *xe)
{
struct xe_gt *gt;
u8 id;

xe_device_remove_display(xe);

xe_display_fini(xe);

xe_heci_gsc_fini(xe);

for_each_gt(gt, xe, id)
xe_gt_remove(gt);

xe_irq_shutdown(xe);
}

Expand Down
52 changes: 41 additions & 11 deletions drivers/gpu/drm/xe/xe_gsc.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "xe_bo.h"
#include "xe_device.h"
#include "xe_exec_queue.h"
#include "xe_gsc_proxy.h"
#include "xe_gsc_submit.h"
#include "xe_gt.h"
#include "xe_gt_printk.h"
Expand Down Expand Up @@ -242,8 +243,31 @@ static int gsc_upload(struct xe_gsc *gsc)
if (err)
return err;

return 0;
}

static int gsc_upload_and_init(struct xe_gsc *gsc)
{
struct xe_gt *gt = gsc_to_gt(gsc);
int ret;

ret = gsc_upload(gsc);
if (ret)
return ret;

xe_uc_fw_change_status(&gsc->fw, XE_UC_FIRMWARE_TRANSFERRED);
xe_gt_dbg(gt, "GSC FW async load completed\n");

/* HuC auth failure is not fatal */
if (xe_huc_is_authenticated(&gt->uc.huc, XE_HUC_AUTH_VIA_GUC))
xe_huc_auth(&gt->uc.huc, XE_HUC_AUTH_VIA_GSC);

ret = xe_gsc_proxy_start(gsc);
if (ret)
return ret;

xe_gt_dbg(gt, "GSC proxy init completed\n");

return 0;
}

Expand All @@ -257,19 +281,12 @@ static void gsc_work(struct work_struct *work)
xe_device_mem_access_get(xe);
xe_force_wake_get(gt_to_fw(gt), XE_FW_GSC);

ret = gsc_upload(gsc);
if (ret && ret != -EEXIST) {
ret = gsc_upload_and_init(gsc);
if (ret && ret != -EEXIST)
xe_uc_fw_change_status(&gsc->fw, XE_UC_FIRMWARE_LOAD_FAIL);
goto out;
}

xe_uc_fw_change_status(&gsc->fw, XE_UC_FIRMWARE_TRANSFERRED);

/* HuC auth failure is not fatal */
if (xe_huc_is_authenticated(&gt->uc.huc, XE_HUC_AUTH_VIA_GUC))
xe_huc_auth(&gt->uc.huc, XE_HUC_AUTH_VIA_GSC);
else
xe_uc_fw_change_status(&gsc->fw, XE_UC_FIRMWARE_RUNNING);

out:
xe_force_wake_put(gt_to_fw(gt), XE_FW_GSC);
xe_device_mem_access_put(xe);
}
Expand Down Expand Up @@ -302,6 +319,10 @@ int xe_gsc_init(struct xe_gsc *gsc)
else if (ret)
goto out;

ret = xe_gsc_proxy_init(gsc);
if (ret && ret != -ENODEV)
goto out;

return 0;

out:
Expand Down Expand Up @@ -410,6 +431,15 @@ void xe_gsc_wait_for_worker_completion(struct xe_gsc *gsc)
flush_work(&gsc->work);
}

/**
* xe_gsc_remove() - Clean up the GSC structures before driver removal
* @gsc: the GSC uC
*/
void xe_gsc_remove(struct xe_gsc *gsc)
{
xe_gsc_proxy_remove(gsc);
}

/*
* wa_14015076503: if the GSC FW is loaded, we need to alert it before doing a
* GSC engine reset by writing a notification bit in the GS1 register and then
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/xe/xe_gsc.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ int xe_gsc_init(struct xe_gsc *gsc);
int xe_gsc_init_post_hwconfig(struct xe_gsc *gsc);
void xe_gsc_wait_for_worker_completion(struct xe_gsc *gsc);
void xe_gsc_load_start(struct xe_gsc *gsc);
void xe_gsc_remove(struct xe_gsc *gsc);

void xe_gsc_wa_14015076503(struct xe_gt *gt, bool prep);

Expand Down
Loading

0 comments on commit 997a55c

Please sign in to comment.