diff --git a/drivers/gpu/drm/xe/xe_drm_ras.c b/drivers/gpu/drm/xe/xe_drm_ras.c index cd236f53699e..7937d8ba0ed9 100644 --- a/drivers/gpu/drm/xe/xe_drm_ras.c +++ b/drivers/gpu/drm/xe/xe_drm_ras.c @@ -11,27 +11,46 @@ #include "xe_device_types.h" #include "xe_drm_ras.h" +#include "xe_ras.h" static const char * const error_components[] = DRM_XE_RAS_ERROR_COMPONENT_NAMES; static const char * const error_severity[] = DRM_XE_RAS_ERROR_SEVERITY_NAMES; -static int hw_query_error_counter(struct xe_drm_ras_counter *info, - u32 error_id, const char **name, u32 *val) +static int query_error_counter(struct xe_device *xe, + enum drm_xe_ras_error_severity severity, + u32 error_id, const char **name, u32 *val) { + struct xe_drm_ras *ras = &xe->ras; + struct xe_drm_ras_counter *info = ras->info[severity]; + if (!info || !info[error_id].name) return -ENOENT; *name = info[error_id].name; + + /* Fetch counter from system controller if supported */ + if (xe->info.has_sysctrl) + return xe_ras_get_counter(xe, severity, error_id, val); + *val = atomic_read(&info[error_id].counter); return 0; } -static int hw_clear_error_counter(struct xe_drm_ras_counter *info, u32 error_id) +static int clear_error_counter(struct xe_device *xe, + enum drm_xe_ras_error_severity severity, + u32 error_id) { + struct xe_drm_ras *ras = &xe->ras; + struct xe_drm_ras_counter *info = ras->info[severity]; + if (!info || !info[error_id].name) return -ENOENT; + /* Clear counter from system controller if supported */ + if (xe->info.has_sysctrl) + return xe_ras_clear_counter(xe, severity, error_id); + atomic_set(&info[error_id].counter, 0); return 0; @@ -41,38 +60,30 @@ static int query_uncorrectable_error_counter(struct drm_ras_node *ep, u32 error_ const char **name, u32 *val) { struct xe_device *xe = ep->priv; - struct xe_drm_ras *ras = &xe->ras; - struct xe_drm_ras_counter *info = ras->info[DRM_XE_RAS_ERR_SEV_UNCORRECTABLE]; - return hw_query_error_counter(info, error_id, name, val); + return query_error_counter(xe, DRM_XE_RAS_ERR_SEV_UNCORRECTABLE, error_id, name, val); } static int clear_uncorrectable_error_counter(struct drm_ras_node *node, u32 error_id) { struct xe_device *xe = node->priv; - struct xe_drm_ras *ras = &xe->ras; - struct xe_drm_ras_counter *info = ras->info[DRM_XE_RAS_ERR_SEV_UNCORRECTABLE]; - return hw_clear_error_counter(info, error_id); + return clear_error_counter(xe, DRM_XE_RAS_ERR_SEV_UNCORRECTABLE, error_id); } static int query_correctable_error_counter(struct drm_ras_node *ep, u32 error_id, const char **name, u32 *val) { struct xe_device *xe = ep->priv; - struct xe_drm_ras *ras = &xe->ras; - struct xe_drm_ras_counter *info = ras->info[DRM_XE_RAS_ERR_SEV_CORRECTABLE]; - return hw_query_error_counter(info, error_id, name, val); + return query_error_counter(xe, DRM_XE_RAS_ERR_SEV_CORRECTABLE, error_id, name, val); } static int clear_correctable_error_counter(struct drm_ras_node *node, u32 error_id) { struct xe_device *xe = node->priv; - struct xe_drm_ras *ras = &xe->ras; - struct xe_drm_ras_counter *info = ras->info[DRM_XE_RAS_ERR_SEV_CORRECTABLE]; - return hw_clear_error_counter(info, error_id); + return clear_error_counter(xe, DRM_XE_RAS_ERR_SEV_CORRECTABLE, error_id); } static struct xe_drm_ras_counter *allocate_and_copy_counters(struct xe_device *xe)