device_remove_file(adev->dev, &dev_attr_sdma_reset_mask);
}
}
+
+/**
+ * amdgpu_sdma_register_on_reset_callbacks - Register SDMA reset callbacks
+ * @funcs: Pointer to the callback structure containing pre_reset and post_reset functions
+ *
+ * This function allows KFD and AMDGPU to register their own callbacks for handling
+ * pre-reset and post-reset operations for engine reset. These are needed because engine
+ * reset will stop all queues on that engine.
+ */
+void amdgpu_sdma_register_on_reset_callbacks(struct amdgpu_device *adev, struct sdma_on_reset_funcs *funcs)
+{
+ if (!funcs)
+ return;
+
+ /* Initialize the list node in the callback structure */
+ INIT_LIST_HEAD(&funcs->list);
+
+ /* Add the callback structure to the global list */
+ list_add_tail(&funcs->list, &adev->sdma.reset_callback_list);
+}
+
+/**
+ * amdgpu_sdma_reset_engine - Reset a specific SDMA engine
+ * @adev: Pointer to the AMDGPU device
+ * @instance_id: ID of the SDMA engine instance to reset
+ *
+ * This function performs the following steps:
+ * 1. Calls all registered pre_reset callbacks to allow KFD and AMDGPU to save their state.
+ * 2. Resets the specified SDMA engine instance.
+ * 3. Calls all registered post_reset callbacks to allow KFD and AMDGPU to restore their state.
+ *
+ * Returns: 0 on success, or a negative error code on failure.
+ */
+int amdgpu_sdma_reset_engine(struct amdgpu_device *adev, uint32_t instance_id)
+{
+ struct sdma_on_reset_funcs *funcs;
+ int ret;
+
+ /* Invoke all registered pre_reset callbacks */
+ list_for_each_entry(funcs, &adev->sdma.reset_callback_list, list) {
+ if (funcs->pre_reset) {
+ ret = funcs->pre_reset(adev, instance_id);
+ if (ret) {
+ dev_err(adev->dev,
+ "beforeReset callback failed for instance %u: %d\n",
+ instance_id, ret);
+ return ret;
+ }
+ }
+ }
+
+ /* Perform the SDMA reset for the specified instance */
+ ret = amdgpu_dpm_reset_sdma(adev, 1 << instance_id);
+ if (ret) {
+ dev_err(adev->dev, "Failed to reset SDMA instance %u\n", instance_id);
+ return ret;
+ }
+
+ /* Invoke all registered post_reset callbacks */
+ list_for_each_entry(funcs, &adev->sdma.reset_callback_list, list) {
+ if (funcs->post_reset) {
+ ret = funcs->post_reset(adev, instance_id);
+ if (ret) {
+ dev_err(adev->dev,
+ "afterReset callback failed for instance %u: %d\n",
+ instance_id, ret);
+ return ret;
+ }
+ }
+ }
+
+ return 0;
+}
struct amdgpu_ras_block_object ras_block;
};
+struct sdma_on_reset_funcs {
+ int (*pre_reset)(struct amdgpu_device *adev, uint32_t instance_id);
+ int (*post_reset)(struct amdgpu_device *adev, uint32_t instance_id);
+ /* Linked list node to store this structure in a list; */
+ struct list_head list;
+};
+
struct amdgpu_sdma {
struct amdgpu_sdma_instance instance[AMDGPU_MAX_SDMA_INSTANCES];
struct amdgpu_irq_src trap_irq;
struct amdgpu_sdma_ras *ras;
uint32_t *ip_dump;
uint32_t supported_reset;
+ struct list_head reset_callback_list;
};
/*
uint32_t byte_count);
};
+void amdgpu_sdma_register_on_reset_callbacks(struct amdgpu_device *adev, struct sdma_on_reset_funcs *funcs);
+int amdgpu_sdma_reset_engine(struct amdgpu_device *adev, uint32_t instance_id);
+
#define amdgpu_emit_copy_buffer(adev, ib, s, d, b, t) (adev)->mman.buffer_funcs->emit_copy_buffer((ib), (s), (d), (b), (t))
#define amdgpu_emit_fill_buffer(adev, ib, s, d, b) (adev)->mman.buffer_funcs->emit_fill_buffer((ib), (s), (d), (b))