Connect the helpers to allow save and restore of MMIO migration data in stop_copy / resume device state. Signed-off-by: MichaƂ Winiarski --- drivers/gpu/drm/xe/xe_gt_sriov_pf_control.c | 13 +++ .../gpu/drm/xe/xe_gt_sriov_pf_control_types.h | 1 + drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.c | 104 ++++++++++++++++++ drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.h | 4 + 4 files changed, 122 insertions(+) diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_control.c b/drivers/gpu/drm/xe/xe_gt_sriov_pf_control.c index a74f6feca4830..7f8f816c10f20 100644 --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_control.c +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_control.c @@ -189,6 +189,7 @@ static const char *control_bit_to_string(enum xe_gt_sriov_control_bits bit) CASE2STR(SAVE_WIP); CASE2STR(SAVE_DATA_GUC); CASE2STR(SAVE_DATA_GGTT); + CASE2STR(SAVE_DATA_MMIO); CASE2STR(SAVE_FAILED); CASE2STR(SAVED); CASE2STR(RESTORE_WIP); @@ -804,6 +805,7 @@ void xe_gt_sriov_pf_control_vf_data_eof(struct xe_gt *gt, unsigned int vfid) static void pf_exit_vf_save_wip(struct xe_gt *gt, unsigned int vfid) { + pf_escape_vf_state(gt, vfid, XE_GT_SRIOV_STATE_SAVE_DATA_MMIO); pf_escape_vf_state(gt, vfid, XE_GT_SRIOV_STATE_SAVE_DATA_GGTT); pf_escape_vf_state(gt, vfid, XE_GT_SRIOV_STATE_SAVE_DATA_GUC); pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_SAVE_WIP); @@ -852,6 +854,13 @@ static bool pf_handle_vf_save_wip(struct xe_gt *gt, unsigned int vfid) return true; } + if (pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_SAVE_DATA_MMIO)) { + ret = xe_gt_sriov_pf_migration_mmio_save(gt, vfid); + if (ret) + goto err; + return true; + } + xe_gt_sriov_pf_control_vf_data_eof(gt, vfid); pf_exit_vf_save_wip(gt, vfid); pf_enter_vf_saved(gt, vfid); @@ -873,6 +882,8 @@ static bool pf_enter_vf_save_wip(struct xe_gt *gt, unsigned int vfid) pf_enter_vf_state(gt, vfid, XE_GT_SRIOV_STATE_SAVE_DATA_GUC); if (xe_gt_sriov_pf_migration_ggtt_size(gt, vfid) > 0) pf_enter_vf_state(gt, vfid, XE_GT_SRIOV_STATE_SAVE_DATA_GGTT); + if (xe_gt_sriov_pf_migration_mmio_size(gt, vfid) > 0) + pf_enter_vf_state(gt, vfid, XE_GT_SRIOV_STATE_SAVE_DATA_MMIO); pf_queue_vf(gt, vfid); return true; } @@ -983,6 +994,8 @@ static int pf_handle_vf_restore_data(struct xe_gt *gt, unsigned int vfid, switch (data->type) { case XE_SRIOV_MIG_DATA_GGTT: return xe_gt_sriov_pf_migration_ggtt_restore(gt, vfid, data); + case XE_SRIOV_MIG_DATA_MMIO: + return xe_gt_sriov_pf_migration_mmio_restore(gt, vfid, data); case XE_SRIOV_MIG_DATA_GUC: return xe_gt_sriov_pf_migration_guc_restore(gt, vfid, data); default: diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_control_types.h b/drivers/gpu/drm/xe/xe_gt_sriov_pf_control_types.h index c94ff0258306a..f8647722bfb3c 100644 --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_control_types.h +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_control_types.h @@ -73,6 +73,7 @@ enum xe_gt_sriov_control_bits { XE_GT_SRIOV_STATE_SAVE_WIP, XE_GT_SRIOV_STATE_SAVE_DATA_GUC, XE_GT_SRIOV_STATE_SAVE_DATA_GGTT, + XE_GT_SRIOV_STATE_SAVE_DATA_MMIO, XE_GT_SRIOV_STATE_SAVE_FAILED, XE_GT_SRIOV_STATE_SAVED, diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.c b/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.c index 92ecf47e71bc7..43e6e1abb92f9 100644 --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.c +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.c @@ -7,6 +7,7 @@ #include "abi/guc_actions_sriov_abi.h" #include "xe_bo.h" +#include "xe_gt_sriov_pf.h" #include "xe_gt_sriov_pf_config.h" #include "xe_gt_sriov_pf_control.h" #include "xe_gt_sriov_pf_helpers.h" @@ -379,6 +380,102 @@ int xe_gt_sriov_pf_migration_guc_restore(struct xe_gt *gt, unsigned int vfid, return pf_restore_vf_guc_state(gt, vfid, data); } +/** + * xe_gt_sriov_pf_migration_mmio_size() - Get the size of VF MMIO migration data. + * @gt: the &struct xe_gt + * @vfid: the VF identifier + * + * This function is for PF only. + * + * Return: size in bytes or a negative error code on failure. + */ +ssize_t xe_gt_sriov_pf_migration_mmio_size(struct xe_gt *gt, unsigned int vfid) +{ + return xe_gt_sriov_pf_mmio_vf_size(gt, vfid); +} + +static int pf_save_vf_mmio_mig_data(struct xe_gt *gt, unsigned int vfid) +{ + struct xe_sriov_pf_migration_data *data; + size_t size; + int ret; + + size = xe_gt_sriov_pf_migration_mmio_size(gt, vfid); + if (size == 0) + return 0; + + data = xe_sriov_pf_migration_data_alloc(gt_to_xe(gt)); + if (!data) + return -ENOMEM; + + ret = xe_sriov_pf_migration_data_init(data, gt->tile->id, gt->info.id, + XE_SRIOV_MIG_DATA_MMIO, 0, size); + if (ret) + goto fail; + + ret = xe_gt_sriov_pf_mmio_vf_save(gt, vfid, data->vaddr, size); + if (ret) + goto fail; + + pf_dump_mig_data(gt, vfid, data); + + ret = xe_gt_sriov_pf_migration_ring_produce(gt, vfid, data); + if (ret) + goto fail; + + return 0; + +fail: + xe_sriov_pf_migration_data_free(data); + xe_gt_sriov_err(gt, "Unable to save VF%u MMIO data (%d)\n", vfid, ret); + return ret; +} + +static int pf_restore_vf_mmio_mig_data(struct xe_gt *gt, unsigned int vfid, + struct xe_sriov_pf_migration_data *data) +{ + pf_dump_mig_data(gt, vfid, data); + + return xe_gt_sriov_pf_mmio_vf_restore(gt, vfid, data->vaddr, data->size); +} + +/** + * xe_gt_sriov_pf_migration_mmio_save() - Save VF MMIO migration data. + * @gt: the &struct xe_gt + * @vfid: the VF identifier + * + * This function is for PF only. + * + * Return: 0 on success or a negative error code on failure. + */ +int xe_gt_sriov_pf_migration_mmio_save(struct xe_gt *gt, unsigned int vfid) +{ + xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); + xe_gt_assert(gt, vfid != PFID); + xe_gt_assert(gt, vfid <= xe_sriov_pf_get_totalvfs(gt_to_xe(gt))); + + return pf_save_vf_mmio_mig_data(gt, vfid); +} + +/** + * xe_gt_sriov_pf_migration_mmio_restore() - Restore VF MMIO migration data. + * @gt: the &struct xe_gt + * @vfid: the VF identifier + * + * This function is for PF only. + * + * Return: 0 on success or a negative error code on failure. + */ +int xe_gt_sriov_pf_migration_mmio_restore(struct xe_gt *gt, unsigned int vfid, + struct xe_sriov_pf_migration_data *data) +{ + xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); + xe_gt_assert(gt, vfid != PFID); + xe_gt_assert(gt, vfid <= xe_sriov_pf_get_totalvfs(gt_to_xe(gt))); + + return pf_restore_vf_mmio_mig_data(gt, vfid, data); +} + /** * xe_gt_sriov_pf_migration_size() - Total size of migration data from all components within a GT * @gt: the &struct xe_gt @@ -409,6 +506,13 @@ ssize_t xe_gt_sriov_pf_migration_size(struct xe_gt *gt, unsigned int vfid) size += sizeof(struct xe_sriov_pf_migration_hdr); total += size; + size = xe_gt_sriov_pf_migration_mmio_size(gt, vfid); + if (size < 0) + return size; + else if (size > 0) + size += sizeof(struct xe_sriov_pf_migration_hdr); + total += size; + return total; } diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.h b/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.h index 5bb8cba2ea0cb..66967da761254 100644 --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.h +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.h @@ -20,6 +20,10 @@ ssize_t xe_gt_sriov_pf_migration_ggtt_size(struct xe_gt *gt, unsigned int vfid); int xe_gt_sriov_pf_migration_ggtt_save(struct xe_gt *gt, unsigned int vfid); int xe_gt_sriov_pf_migration_ggtt_restore(struct xe_gt *gt, unsigned int vfid, struct xe_sriov_pf_migration_data *data); +ssize_t xe_gt_sriov_pf_migration_mmio_size(struct xe_gt *gt, unsigned int vfid); +int xe_gt_sriov_pf_migration_mmio_save(struct xe_gt *gt, unsigned int vfid); +int xe_gt_sriov_pf_migration_mmio_restore(struct xe_gt *gt, unsigned int vfid, + struct xe_sriov_pf_migration_data *data); ssize_t xe_gt_sriov_pf_migration_size(struct xe_gt *gt, unsigned int vfid); -- 2.50.1