Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/imagination: Implement handling of context reset notification

The firmware will send the context reset notification message as
part of handling hardware recovery (HWR) events deecoding the message
and printing via drm_info(). This eliminates the "Unknown FWCCB command"
message that was previously printed.

Co-developed-by: Sarah Walker <sarah.walker@imgtec.com>
Signed-off-by: Sarah Walker <sarah.walker@imgtec.com>
Signed-off-by: Alexandru Dadu <alexandru.dadu@imgtec.com>
Reviewed-by: Matt Coster <matt.coster@imgtec.com>
Link: https://patch.msgid.link/20260323-b4-firmware-context-reset-notification-handling-v3-3-1a66049a9a65@imgtec.com
Signed-off-by: Matt Coster <matt.coster@imgtec.com>

authored by

Alexandru Dadu and committed by
Matt Coster
d994acc5 d2f83a6c

+136
+1
drivers/gpu/drm/imagination/Makefile
··· 8 8 pvr_device.o \ 9 9 pvr_device_info.o \ 10 10 pvr_drv.o \ 11 + pvr_dump.o \ 11 12 pvr_free_list.o \ 12 13 pvr_fw.o \ 13 14 pvr_fw_meta.o \
+5
drivers/gpu/drm/imagination/pvr_ccb.c
··· 4 4 #include "pvr_ccb.h" 5 5 #include "pvr_device.h" 6 6 #include "pvr_drv.h" 7 + #include "pvr_dump.h" 7 8 #include "pvr_free_list.h" 8 9 #include "pvr_fw.h" 9 10 #include "pvr_gem.h" ··· 165 164 * stats. It may be added in the future, but for now just 166 165 * suppress the "unknown" warning when receiving this command. 167 166 */ 167 + break; 168 + case ROGUE_FWIF_FWCCB_CMD_CONTEXT_RESET_NOTIFICATION: 169 + pvr_dump_context_reset_notification(pvr_dev, 170 + &cmd->cmd_data.cmd_context_reset_notification); 168 171 break; 169 172 170 173 default:
+113
drivers/gpu/drm/imagination/pvr_dump.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 OR MIT 2 + /* Copyright (c) 2026 Imagination Technologies Ltd. */ 3 + 4 + #include "pvr_device.h" 5 + #include "pvr_dump.h" 6 + #include "pvr_rogue_fwif.h" 7 + 8 + #include <drm/drm_print.h> 9 + #include <linux/types.h> 10 + 11 + static const char * 12 + get_reset_reason_desc(enum rogue_context_reset_reason reason) 13 + { 14 + switch (reason) { 15 + case ROGUE_CONTEXT_RESET_REASON_NONE: 16 + return "None"; 17 + case ROGUE_CONTEXT_RESET_REASON_GUILTY_LOCKUP: 18 + return "Guilty lockup"; 19 + case ROGUE_CONTEXT_RESET_REASON_INNOCENT_LOCKUP: 20 + return "Innocent lockup"; 21 + case ROGUE_CONTEXT_RESET_REASON_GUILTY_OVERRUNING: 22 + return "Guilty overrunning"; 23 + case ROGUE_CONTEXT_RESET_REASON_INNOCENT_OVERRUNING: 24 + return "Innocent overrunning"; 25 + case ROGUE_CONTEXT_RESET_REASON_HARD_CONTEXT_SWITCH: 26 + return "Hard context switch"; 27 + case ROGUE_CONTEXT_RESET_REASON_WGP_CHECKSUM: 28 + return "CDM Mission/safety checksum mismatch"; 29 + case ROGUE_CONTEXT_RESET_REASON_TRP_CHECKSUM: 30 + return "TRP checksum mismatch"; 31 + case ROGUE_CONTEXT_RESET_REASON_GPU_ECC_OK: 32 + return "GPU ECC error (corrected, OK)"; 33 + case ROGUE_CONTEXT_RESET_REASON_GPU_ECC_HWR: 34 + return "GPU ECC error (uncorrected, HWR)"; 35 + case ROGUE_CONTEXT_RESET_REASON_FW_ECC_OK: 36 + return "Firmware ECC error (corrected, OK)"; 37 + case ROGUE_CONTEXT_RESET_REASON_FW_ECC_ERR: 38 + return "Firmware ECC error (uncorrected, ERR)"; 39 + case ROGUE_CONTEXT_RESET_REASON_FW_WATCHDOG: 40 + return "Firmware watchdog"; 41 + case ROGUE_CONTEXT_RESET_REASON_FW_PAGEFAULT: 42 + return "Firmware pagefault"; 43 + case ROGUE_CONTEXT_RESET_REASON_FW_EXEC_ERR: 44 + return "Firmware execution error"; 45 + case ROGUE_CONTEXT_RESET_REASON_HOST_WDG_FW_ERR: 46 + return "Host watchdog"; 47 + case ROGUE_CONTEXT_GEOM_OOM_DISABLED: 48 + return "Geometry OOM disabled"; 49 + 50 + default: 51 + return "Unknown"; 52 + } 53 + } 54 + 55 + static const char * 56 + get_dm_name(u32 dm) 57 + { 58 + switch (dm) { 59 + case PVR_FWIF_DM_GP: 60 + return "General purpose"; 61 + /* PVR_FWIF_DM_TDM has the same index, but is discriminated by a device feature */ 62 + case PVR_FWIF_DM_2D: 63 + return "2D or TDM"; 64 + case PVR_FWIF_DM_GEOM: 65 + return "Geometry"; 66 + case PVR_FWIF_DM_FRAG: 67 + return "Fragment"; 68 + case PVR_FWIF_DM_CDM: 69 + return "Compute"; 70 + case PVR_FWIF_DM_RAY: 71 + return "Raytracing"; 72 + case PVR_FWIF_DM_GEOM2: 73 + return "Geometry 2"; 74 + case PVR_FWIF_DM_GEOM3: 75 + return "Geometry 3"; 76 + case PVR_FWIF_DM_GEOM4: 77 + return "Geometry 4"; 78 + 79 + default: 80 + return "Unknown"; 81 + } 82 + } 83 + 84 + /** 85 + * pvr_dump_context_reset_notification() - Handle context reset notification from FW 86 + * @pvr_dev: Device pointer. 87 + * @data: Data provided by FW. 88 + * 89 + * This will decode the data structure provided by FW and print the results via drm_info(). 90 + */ 91 + void 92 + pvr_dump_context_reset_notification(struct pvr_device *pvr_dev, 93 + struct rogue_fwif_fwccb_cmd_context_reset_data *data) 94 + { 95 + struct drm_device *drm_dev = from_pvr_device(pvr_dev); 96 + 97 + if (data->flags & ROGUE_FWIF_FWCCB_CMD_CONTEXT_RESET_FLAG_ALL_CTXS) { 98 + drm_info(drm_dev, "Received context reset notification for all contexts\n"); 99 + } else { 100 + drm_info(drm_dev, "Received context reset notification on context %u\n", 101 + data->server_common_context_id); 102 + } 103 + 104 + drm_info(drm_dev, " Reset reason=%u (%s)\n", data->reset_reason, 105 + get_reset_reason_desc((enum rogue_context_reset_reason)data->reset_reason)); 106 + drm_info(drm_dev, " Data Master=%u (%s)\n", data->dm, get_dm_name(data->dm)); 107 + drm_info(drm_dev, " Job ref=%u\n", data->reset_job_ref); 108 + 109 + if (data->flags & ROGUE_FWIF_FWCCB_CMD_CONTEXT_RESET_FLAG_PF) { 110 + drm_info(drm_dev, " Page fault occurred, fault address=%llx\n", 111 + data->fault_address); 112 + } 113 + }
+17
drivers/gpu/drm/imagination/pvr_dump.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 OR MIT */ 2 + /* Copyright (c) 2026 Imagination Technologies Ltd. */ 3 + 4 + #ifndef PVR_DUMP_H 5 + #define PVR_DUMP_H 6 + 7 + /* Forward declaration from pvr_device.h. */ 8 + struct pvr_device; 9 + 10 + /* Forward declaration from pvr_rogue_fwif.h. */ 11 + struct rogue_fwif_fwccb_cmd_context_reset_data; 12 + 13 + void 14 + pvr_dump_context_reset_notification(struct pvr_device *pvr_dev, 15 + struct rogue_fwif_fwccb_cmd_context_reset_data *data); 16 + 17 + #endif /* PVR_DUMP_H */