]> git.hungrycats.org Git - linux/commitdiff
drm/xe/xe_ras: Add support to clear error counter value
authorRiana Tauro <riana.tauro@intel.com>
Thu, 18 Jun 2026 06:06:37 +0000 (11:36 +0530)
committerRiana Tauro <riana.tauro@intel.com>
Mon, 22 Jun 2026 04:57:30 +0000 (10:27 +0530)
Add structures and helper function to clear error counter value.

Reviewed-by: Raag Jadav <raag.jadav@intel.com>
Link: https://patch.msgid.link/20260618060633.2790109-11-riana.tauro@intel.com
Signed-off-by: Riana Tauro <riana.tauro@intel.com>
drivers/gpu/drm/xe/xe_ras.c
drivers/gpu/drm/xe/xe_ras.h
drivers/gpu/drm/xe/xe_ras_types.h
drivers/gpu/drm/xe/xe_sysctrl_mailbox_types.h

index 96702234d7ece2272d45e8458f3696ed4f13d701..a11ea841f9f101634e409087ccacc6cec20d6532 100644 (file)
@@ -34,6 +34,17 @@ enum xe_ras_component {
        XE_RAS_COMP_MAX
 };
 
+/* RAS response status codes */
+enum xe_ras_response_status {
+       XE_RAS_STATUS_SUCCESS = 0,
+       XE_RAS_STATUS_INVALID_PARAM,
+       XE_RAS_STATUS_OP_NOT_SUPPORTED,
+       XE_RAS_STATUS_TIMEOUT,
+       XE_RAS_STATUS_HARDWARE_FAILURE,
+       XE_RAS_STATUS_INSUFFICIENT_RESOURCES,
+       XE_RAS_STATUS_MAX
+};
+
 static const char *const xe_ras_severities[] = {
        [XE_RAS_SEV_NOT_SUPPORTED]              = "Not Supported",
        [XE_RAS_SEV_CORRECTABLE]                = "Correctable Error",
@@ -83,6 +94,26 @@ static u8 drm_to_xe_ras_component(u8 component)
        }
 }
 
+static int ras_status_to_errno(u32 status)
+{
+       switch (status) {
+       case XE_RAS_STATUS_SUCCESS:
+               return 0;
+       case XE_RAS_STATUS_INVALID_PARAM:
+               return -EINVAL;
+       case XE_RAS_STATUS_OP_NOT_SUPPORTED:
+               return -EOPNOTSUPP;
+       case XE_RAS_STATUS_TIMEOUT:
+               return -ETIMEDOUT;
+       case XE_RAS_STATUS_HARDWARE_FAILURE:
+               return -EIO;
+       case XE_RAS_STATUS_INSUFFICIENT_RESOURCES:
+               return -ENOSPC;
+       default:
+               return -EPROTO;
+       }
+}
+
 static inline const char *sev_to_str(u8 severity)
 {
        if (severity >= XE_RAS_SEV_MAX)
@@ -182,3 +213,58 @@ int xe_ras_get_counter(struct xe_device *xe, u8 severity, u8 component, u32 *val
        guard(xe_pm_runtime)(xe);
        return get_counter(xe, &counter, value);
 }
+
+/**
+ * xe_ras_clear_counter() - Clear error counter value
+ * @xe: Xe device instance
+ * @severity: Error severity to be cleared (&enum drm_xe_ras_error_severity)
+ * @component: Error component to be cleared (&enum drm_xe_ras_error_component)
+ *
+ * This function clears the value of a specific error counter based on
+ * the error severity and component.
+ *
+ * Return: 0 on success, negative error code on failure.
+ */
+int xe_ras_clear_counter(struct xe_device *xe, u8 severity, u8 component)
+{
+       struct xe_ras_clear_counter_response response = {0};
+       struct xe_ras_clear_counter_request request = {0};
+       struct xe_sysctrl_mailbox_command command = {0};
+       struct xe_ras_error_class *counter;
+       size_t rlen;
+       int ret;
+
+       counter = &request.counter;
+       counter->common.severity = drm_to_xe_ras_severity(severity);
+       counter->common.component = drm_to_xe_ras_component(component);
+
+       xe_sysctrl_create_command(&command, XE_SYSCTRL_GROUP_GFSP, XE_SYSCTRL_CMD_CLEAR_COUNTER,
+                                 &request, sizeof(request), &response, sizeof(response));
+
+       guard(xe_pm_runtime)(xe);
+       ret = xe_sysctrl_send_command(&xe->sc, &command, &rlen);
+       if (ret) {
+               xe_err(xe, "sysctrl: failed to clear counter %d\n", ret);
+               return ret;
+       }
+
+       if (rlen != sizeof(response)) {
+               xe_err(xe, "sysctrl: unexpected clear counter response length %zu (expected %zu)\n",
+                      rlen, sizeof(response));
+               return -EIO;
+       }
+
+       ret = ras_status_to_errno(response.status);
+       if (ret) {
+               xe_err(xe, "sysctrl: clear counter command failed with status %#x\n",
+                      response.status);
+               return ret;
+       }
+
+       counter = &response.counter;
+
+       xe_dbg(xe, "[RAS]: clear counter for %s %s\n", comp_to_str(counter->common.component),
+              sev_to_str(counter->common.severity));
+
+       return 0;
+}
index e148debd5d418dac3706d8008962ee8671a9410e..a2089fc3c3ff014d1a71cfb21891eed1b364fe45 100644 (file)
@@ -14,5 +14,6 @@ struct xe_sysctrl_event_response;
 void xe_ras_counter_threshold_crossed(struct xe_device *xe,
                                      struct xe_sysctrl_event_response *response);
 int xe_ras_get_counter(struct xe_device *xe, u8 severity, u8 component, u32 *value);
+int xe_ras_clear_counter(struct xe_device *xe, u8 severity, u8 component);
 
 #endif
index fdfebaeb5ed2614cdc0f5d95f5df3ccfe9bb23a8..6688e11f57a862f3a6a3c40a5c0c26ec1e418937 100644 (file)
@@ -96,4 +96,29 @@ struct xe_ras_get_counter_response {
        u32 reserved[57];
 } __packed;
 
+/**
+ * struct xe_ras_clear_counter_request - Request structure for clear counter
+ */
+struct xe_ras_clear_counter_request {
+       /** @counter: Counter class to be cleared */
+       struct xe_ras_error_class counter;
+       /** @reserved: Reserved for future use */
+       u32 reserved;
+} __packed;
+
+/**
+ * struct xe_ras_clear_counter_response - Response structure for clear counter
+ */
+struct xe_ras_clear_counter_response {
+       /** @counter: Counter class that was cleared */
+       struct xe_ras_error_class counter;
+       /** @reserved: Reserved */
+       u32 reserved;
+       /** @timestamp: Timestamp when the counter was cleared */
+       u64 timestamp;
+       /** @status: Status of the clear operation */
+       u32 status;
+       /** @reserved1: Reserved for future use */
+       u32 reserved1[3];
+} __packed;
 #endif
index b315847cbf64f88cf29d5192fcfa2d2bb5f6dc7b..6e3753554510a55ff532a773604b0085a8c2d638 100644 (file)
@@ -23,10 +23,12 @@ enum xe_sysctrl_group {
  * enum xe_sysctrl_gfsp_cmd - Commands supported by GFSP group
  *
  * @XE_SYSCTRL_CMD_GET_COUNTER: Get error counter value
+ * @XE_SYSCTRL_CMD_CLEAR_COUNTER: Clear error counter value
  * @XE_SYSCTRL_CMD_GET_PENDING_EVENT: Retrieve pending event
  */
 enum xe_sysctrl_gfsp_cmd {
        XE_SYSCTRL_CMD_GET_COUNTER              = 0x03,
+       XE_SYSCTRL_CMD_CLEAR_COUNTER            = 0x04,
        XE_SYSCTRL_CMD_GET_PENDING_EVENT        = 0x07,
 };