diff --git a/drivers/gpu/drm/xe/xe_ras.c b/drivers/gpu/drm/xe/xe_ras.c index ed609912fda1..73f9949286b4 100644 --- a/drivers/gpu/drm/xe/xe_ras.c +++ b/drivers/gpu/drm/xe/xe_ras.c @@ -8,6 +8,7 @@ #include "xe_pm.h" #include "xe_printk.h" #include "xe_ras.h" +#include "xe_survivability_mode.h" #include "xe_sysctrl.h" #include "xe_sysctrl_event_types.h" #include "xe_sysctrl_mailbox.h" @@ -235,6 +236,46 @@ static u8 handle_core_compute_errors(struct xe_ras_error_array *arr) return XE_RAS_RECOVERY_ACTION_RECOVERED; } +static u8 handle_soc_internal_errors(struct xe_device *xe, struct xe_ras_error_array *arr) +{ + struct xe_ras_soc_error *info = (void *)arr->details; + struct xe_ras_soc_error_source *source = &info->source; + struct xe_ras_error_class *counter = &arr->counter; + + if (source->csc) { + struct xe_ras_csc_error *csc_error = (void *)info->details; + + /* + * CSC uncorrectable errors are classified as hardware errors and firmware errors. + * CSC firmware errors are critical errors that can be recovered only by firmware + * update via SPI driver. On a CSC firmware error, PCODE enables FDO mode and sets + * the bit in the capability register. On receiving this error, the driver enables + * runtime survivability mode which notifies userspace that a firmware update + * is required. + */ + if (csc_error->hec_fw_error) { + xe_err(xe, "[RAS]: CSC %s detected: 0x%x\n", + sev_to_str(counter->common.severity), + csc_error->hec_fw_error); + xe_survivability_mode_runtime_enable(xe); + return XE_RAS_RECOVERY_ACTION_DISCONNECT; + } + } else if (source->ieh) { + struct xe_ras_ieh_error *ieh_error = (void *)info->details; + + if (ieh_error->global_error_status & XE_RAS_SOC_IEH_PUNIT) { + xe_err(xe, "[RAS]: PUNIT %s detected: 0x%x\n", + sev_to_str(counter->common.severity), + ieh_error->global_error_status); + /* TODO: Add PUNIT error handling */ + return XE_RAS_RECOVERY_ACTION_DISCONNECT; + } + } + + /* For other SoC internal errors, request a reset as recovery mechanism */ + return XE_RAS_RECOVERY_ACTION_RESET; +} + void xe_ras_counter_threshold_crossed(struct xe_device *xe, struct xe_sysctrl_event_response *response) { @@ -358,6 +399,9 @@ enum xe_ras_recovery_action xe_ras_process_errors(struct xe_device *xe) case XE_RAS_COMP_CORE_COMPUTE: action = handle_core_compute_errors(arr); break; + case XE_RAS_COMP_SOC_INTERNAL: + action = handle_soc_internal_errors(xe, arr); + break; default: /* For any other component, reset */ action = XE_RAS_RECOVERY_ACTION_RESET; diff --git a/drivers/gpu/drm/xe/xe_ras_types.h b/drivers/gpu/drm/xe/xe_ras_types.h index 766b4b41768e..066c1c39fc89 100644 --- a/drivers/gpu/drm/xe/xe_ras_types.h +++ b/drivers/gpu/drm/xe/xe_ras_types.h @@ -10,6 +10,8 @@ #define XE_RAS_NUM_COUNTERS 16 #define XE_RAS_NUM_ERROR_ARR 3 +/* Error bits in IEH global error status register */ +#define XE_RAS_SOC_IEH_PUNIT BIT(1) /** * enum xe_ras_recovery_action - RAS recovery actions @@ -177,6 +179,52 @@ struct xe_ras_compute_error { u32 reserved[15]; } __packed; +/** + * struct xe_ras_soc_error_source - Source of SoC error + */ +struct xe_ras_soc_error_source { + /** @csc: CSC */ + u32 csc:1; + /** @ieh: IEH (Integrated Error Handler) */ + u32 ieh:1; + /** @reserved: Reserved for future use */ + u32 reserved:30; +} __packed; + +/** + * struct xe_ras_soc_error - Error details of SoC internal error + */ +struct xe_ras_soc_error { + /** @source: Error source */ + struct xe_ras_soc_error_source source; + /** @details: Error details specific to the error source */ + u32 details[15]; +} __packed; + +/** + * struct xe_ras_csc_error - CSC error details + */ +struct xe_ras_csc_error { + /** @reserved: Reserved for future use */ + u32 reserved; + /** @hec_fw_error: CSC firmware error */ + u32 hec_fw_error; +} __packed; + +/** + * struct xe_ras_ieh_error - IEH (Integrated Error Handler) error details + */ +struct xe_ras_ieh_error { + /** @reserved: Reserved for future use */ + u32 reserved; + /** @global_error_status: Global error status */ + u32 global_error_status; + /** @reserved1: Reserved for future use */ + u32 reserved1[2]; + /** @info: Additional information */ + u32 info[10]; +} __packed; + /** * struct xe_ras_get_health_request - Request structure for obtaining gpu health */