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

Reviewed-by: Raag Jadav <raag.jadav@intel.com>
Link: https://patch.msgid.link/20260618060633.2790109-10-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.c
drivers/gpu/drm/xe/xe_sysctrl_mailbox.h
drivers/gpu/drm/xe/xe_sysctrl_mailbox_types.h

index 4cb16b419b0c6657637e7136346d10be4da23130..96702234d7ece2272d45e8458f3696ed4f13d701 100644 (file)
@@ -4,11 +4,14 @@
  */
 
 #include "xe_device.h"
+#include "xe_pm.h"
 #include "xe_printk.h"
 #include "xe_ras.h"
 #include "xe_ras_types.h"
 #include "xe_sysctrl.h"
 #include "xe_sysctrl_event_types.h"
+#include "xe_sysctrl_mailbox.h"
+#include "xe_sysctrl_mailbox_types.h"
 
 /* Severity of detected errors  */
 enum xe_ras_severity {
@@ -50,6 +53,36 @@ static const char *const xe_ras_components[] = {
 };
 static_assert(ARRAY_SIZE(xe_ras_components) == XE_RAS_COMP_MAX);
 
+static u8 drm_to_xe_ras_severity(u8 severity)
+{
+       switch (severity) {
+       case DRM_XE_RAS_ERR_SEV_CORRECTABLE:
+               return XE_RAS_SEV_CORRECTABLE;
+       case DRM_XE_RAS_ERR_SEV_UNCORRECTABLE:
+               return XE_RAS_SEV_UNCORRECTABLE;
+       default:
+               return XE_RAS_SEV_NOT_SUPPORTED;
+       }
+}
+
+static u8 drm_to_xe_ras_component(u8 component)
+{
+       switch (component) {
+       case DRM_XE_RAS_ERR_COMP_CORE_COMPUTE:
+               return XE_RAS_COMP_CORE_COMPUTE;
+       case DRM_XE_RAS_ERR_COMP_SOC_INTERNAL:
+               return XE_RAS_COMP_SOC_INTERNAL;
+       case DRM_XE_RAS_ERR_COMP_DEVICE_MEMORY:
+               return XE_RAS_COMP_DEVICE_MEMORY;
+       case DRM_XE_RAS_ERR_COMP_PCIE:
+               return XE_RAS_COMP_PCIE;
+       case DRM_XE_RAS_ERR_COMP_FABRIC:
+               return XE_RAS_COMP_FABRIC;
+       default:
+               return XE_RAS_COMP_NOT_SUPPORTED;
+       }
+}
+
 static inline const char *sev_to_str(u8 severity)
 {
        if (severity >= XE_RAS_SEV_MAX)
@@ -91,3 +124,61 @@ void xe_ras_counter_threshold_crossed(struct xe_device *xe,
                        comp_to_str(component), sev_to_str(severity));
        }
 }
+
+static int get_counter(struct xe_device *xe, struct xe_ras_error_class *counter, u32 *value)
+{
+       struct xe_ras_get_counter_response response = {0};
+       struct xe_ras_get_counter_request request = {0};
+       struct xe_sysctrl_mailbox_command command = {0};
+       struct xe_ras_error_common *common;
+       size_t rlen;
+       int ret;
+
+       request.counter = *counter;
+
+       xe_sysctrl_create_command(&command, XE_SYSCTRL_GROUP_GFSP, XE_SYSCTRL_CMD_GET_COUNTER,
+                                 &request, sizeof(request), &response, sizeof(response));
+
+       ret = xe_sysctrl_send_command(&xe->sc, &command, &rlen);
+       if (ret) {
+               xe_err(xe, "sysctrl: failed to get counter %d\n", ret);
+               return ret;
+       }
+
+       if (rlen != sizeof(response)) {
+               xe_err(xe, "sysctrl: unexpected get counter response length %zu (expected %zu)\n",
+                      rlen, sizeof(response));
+               return -EIO;
+       }
+
+       common = &response.counter.common;
+       *value = response.value;
+
+       xe_dbg(xe, "[RAS]: get counter %u for %s %s\n", *value, comp_to_str(common->component),
+              sev_to_str(common->severity));
+
+       return 0;
+}
+
+/**
+ * xe_ras_get_counter() - Get error counter value
+ * @xe: Xe device instance
+ * @severity: Error severity to be queried (&enum drm_xe_ras_error_severity)
+ * @component: Error component to be queried (&enum drm_xe_ras_error_component)
+ * @value: Counter value
+ *
+ * This function retrieves 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_get_counter(struct xe_device *xe, u8 severity, u8 component, u32 *value)
+{
+       struct xe_ras_error_class counter = {0};
+
+       counter.common.severity = drm_to_xe_ras_severity(severity);
+       counter.common.component = drm_to_xe_ras_component(component);
+
+       guard(xe_pm_runtime)(xe);
+       return get_counter(xe, &counter, value);
+}
index ea90593b62dc1288420dc2c126da3eead18bbf97..e148debd5d418dac3706d8008962ee8671a9410e 100644 (file)
@@ -6,10 +6,13 @@
 #ifndef _XE_RAS_H_
 #define _XE_RAS_H_
 
+#include <linux/types.h>
+
 struct xe_device;
 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);
 
 #endif
index 4e63c67f806a268b262b8ee900d5d07ae7124d27..fdfebaeb5ed2614cdc0f5d95f5df3ccfe9bb23a8 100644 (file)
@@ -70,4 +70,30 @@ struct xe_ras_threshold_crossed {
        struct xe_ras_error_class counters[XE_RAS_NUM_COUNTERS];
 } __packed;
 
+/**
+ * struct xe_ras_get_counter_request - Request structure for get counter
+ */
+struct xe_ras_get_counter_request {
+       /** @counter: Error counter to be queried */
+       struct xe_ras_error_class counter;
+       /** @reserved: Reserved for future use */
+       u32 reserved;
+} __packed;
+
+/**
+ * struct xe_ras_get_counter_response - Response structure for get counter
+ */
+struct xe_ras_get_counter_response {
+       /** @counter: Error counter that was queried */
+       struct xe_ras_error_class counter;
+       /** @value: Current counter value */
+       u32 value;
+       /** @timestamp: Timestamp when counter was last updated */
+       u64 timestamp;
+       /** @threshold: Threshold value for the counter */
+       u32 threshold;
+       /** @reserved: Reserved  */
+       u32 reserved[57];
+} __packed;
+
 #endif
index 3caa9f15875f5690cee33cd6f12a24ee9a1f3d75..e13eebaac1d006ce2dcb00f27703dc735ff008c7 100644 (file)
@@ -293,6 +293,34 @@ static int sysctrl_send_command(struct xe_sysctrl *sc,
        return 0;
 }
 
+/**
+ * xe_sysctrl_create_command() - Create system controller command
+ * @command: Sysctrl command structure
+ * @group_id: Command group ID
+ * @cmd_id: Command ID
+ * @request: Pointer to request buffer (can be NULL)
+ * @request_len: Size of request buffer
+ * @response: Pointer to response buffer
+ * @response_len: Size of response buffer
+ *
+ * Helper function to create sysctrl command to be sent via %xe_sysctrl_send_command()
+ */
+void xe_sysctrl_create_command(struct xe_sysctrl_mailbox_command *command, u8 group_id, u8 cmd_id,
+                              void *request, size_t request_len, void *response,
+                              size_t response_len)
+{
+       struct xe_sysctrl_app_msg_hdr header = {0};
+
+       header.data = FIELD_PREP(APP_HDR_GROUP_ID_MASK, group_id) |
+                     FIELD_PREP(APP_HDR_COMMAND_MASK, cmd_id);
+
+       command->header = header;
+       command->data_in = request;
+       command->data_in_len = request_len;
+       command->data_out = response;
+       command->data_out_len = response_len;
+}
+
 /**
  * xe_sysctrl_mailbox_init - Initialize System Controller mailbox interface
  * @sc: System controller structure
index f67e9234de482ff0b585d945c0dc8dd811d7844a..fb434cc165b2aab1fb76d4957e704ab2c450bdab 100644 (file)
@@ -23,6 +23,9 @@ struct xe_sysctrl_mailbox_command;
 #define XE_SYSCTRL_APP_HDR_VERSION(hdr) \
        FIELD_GET(APP_HDR_VERSION_MASK, (hdr)->data)
 
+void xe_sysctrl_create_command(struct xe_sysctrl_mailbox_command *command, u8 group_id, u8 cmd_id,
+                              void *request, size_t request_len, void *response,
+                              size_t response_len);
 void xe_sysctrl_mailbox_init(struct xe_sysctrl *sc);
 int xe_sysctrl_send_command(struct xe_sysctrl *sc,
                            struct xe_sysctrl_mailbox_command *cmd,
index 84d7c647e7432c7bc24b53e11c3664fde9935d3a..b315847cbf64f88cf29d5192fcfa2d2bb5f6dc7b 100644 (file)
@@ -22,9 +22,11 @@ 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_GET_PENDING_EVENT: Retrieve pending event
  */
 enum xe_sysctrl_gfsp_cmd {
+       XE_SYSCTRL_CMD_GET_COUNTER              = 0x03,
        XE_SYSCTRL_CMD_GET_PENDING_EVENT        = 0x07,
 };