diff options
author | Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com> | 2024-01-17 10:26:20 -0800 |
---|---|---|
committer | Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com> | 2024-01-18 11:04:37 -0800 |
commit | eb08104f90fc474054211244d668d3fe1d84bccb (patch) | |
tree | 7ce6166cc027558b88e065fa51b10a276aca246b /drivers/gpu/drm/xe/xe_gsc.c | |
parent | 997a55caa1c3b770979836bbfd82b311addf95c7 (diff) |
drm/xe/gsc: add support for GSC proxy interrupt
The GSC notifies us of a proxy request via the HECI2 interrupt. The
interrupt must be enabled both in the HECI layer and in our usual gt irq
programming; for the latter, the interrupt is enabled via the same enable
register as the GSC CS, but it does have its own mask register. When the
interrupt is received, we also need to de-assert it in both layers.
The handling of the proxy request is deferred to the same worker that we
use for GSC load. New flags have been added to distinguish between the
init case and the proxy interrupt.
v2: rename irq define, fix include ordering (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-3-daniele.ceraolospurio@intel.com
Diffstat (limited to 'drivers/gpu/drm/xe/xe_gsc.c')
-rw-r--r-- | drivers/gpu/drm/xe/xe_gsc.c | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/drivers/gpu/drm/xe/xe_gsc.c b/drivers/gpu/drm/xe/xe_gsc.c index 85074b730402..0b90fd9ef63a 100644 --- a/drivers/gpu/drm/xe/xe_gsc.c +++ b/drivers/gpu/drm/xe/xe_gsc.c @@ -276,16 +276,27 @@ static void gsc_work(struct work_struct *work) struct xe_gsc *gsc = container_of(work, typeof(*gsc), work); struct xe_gt *gt = gsc_to_gt(gsc); struct xe_device *xe = gt_to_xe(gt); + u32 actions; int ret; + spin_lock_irq(&gsc->lock); + actions = gsc->work_actions; + gsc->work_actions = 0; + spin_unlock_irq(&gsc->lock); + xe_device_mem_access_get(xe); xe_force_wake_get(gt_to_fw(gt), XE_FW_GSC); - ret = gsc_upload_and_init(gsc); - if (ret && ret != -EEXIST) - xe_uc_fw_change_status(&gsc->fw, XE_UC_FIRMWARE_LOAD_FAIL); - else - xe_uc_fw_change_status(&gsc->fw, XE_UC_FIRMWARE_RUNNING); + if (actions & GSC_ACTION_FW_LOAD) { + ret = gsc_upload_and_init(gsc); + if (ret && ret != -EEXIST) + xe_uc_fw_change_status(&gsc->fw, XE_UC_FIRMWARE_LOAD_FAIL); + else + xe_uc_fw_change_status(&gsc->fw, XE_UC_FIRMWARE_RUNNING); + } + + if (actions & GSC_ACTION_SW_PROXY) + xe_gsc_proxy_request_handler(gsc); xe_force_wake_put(gt_to_fw(gt), XE_FW_GSC); xe_device_mem_access_put(xe); @@ -299,6 +310,7 @@ int xe_gsc_init(struct xe_gsc *gsc) gsc->fw.type = XE_UC_FW_TYPE_GSC; INIT_WORK(&gsc->work, gsc_work); + spin_lock_init(&gsc->lock); /* The GSC uC is only available on the media GT */ if (tile->media_gt && (gt != tile->media_gt)) { @@ -422,6 +434,10 @@ void xe_gsc_load_start(struct xe_gsc *gsc) return; } + spin_lock_irq(&gsc->lock); + gsc->work_actions |= GSC_ACTION_FW_LOAD; + spin_unlock_irq(&gsc->lock); + queue_work(gsc->wq, &gsc->work); } |