#!/usr/bin/env python3 """ Patch 1: gfx_v10_0.c — Disable GFXOFF for Cyan Skillfish (IP 10.1.3) Layer 1 of the v3 three-layer protection. Prevents the GPU from entering the GFXOFF power-saving state, from which it cannot reliably wake. When the GPU is unresponsive, any MMIO register read hangs the CPU indefinitely on the BC-250's internal PCIe fabric (no completion timeout). Usage: python3 patch1_gfxoff.py /path/to/drivers/gpu/drm/amd/amdgpu """ import sys import os if len(sys.argv) < 2: print("Usage: python3 patch1_gfxoff.py ") print(" e.g.: python3 patch1_gfxoff.py ~/kernel-build/linux-6.19.6/drivers/gpu/drm/amd/amdgpu") sys.exit(1) AMDGPU = sys.argv[1] filepath = os.path.join(AMDGPU, "gfx_v10_0.c") if not os.path.isfile(filepath): print(f"ERROR: File not found: {filepath}") sys.exit(1) with open(filepath, 'r') as f: content = f.read() if 'BC-250' in content: print("Already patched, skipping.") sys.exit(0) # Find gfx_v10_0_check_gfxoff_flag function func_start = content.find('static void gfx_v10_0_check_gfxoff_flag') if func_start == -1: print("ERROR: gfx_v10_0_check_gfxoff_flag not found") sys.exit(1) # Find the 'default:' case in the switch inside this function func_region_end = func_start + 2000 default_pos = content.find('\tdefault:', func_start, func_region_end) if default_pos == -1: default_pos = content.find('default:', func_start, func_region_end) if default_pos == -1: print("ERROR: default case not found in gfx_v10_0_check_gfxoff_flag") print("Region:", content[func_start:func_start+500]) sys.exit(1) # Insert our case BEFORE the default case new_case = ( '\t/* ===== BC-250 v3 PATCH START ===== */\n' '\tcase IP_VERSION(10, 1, 3):\n' '\t\t/*\n' '\t\t * BC-250 / Cyan Skillfish (gfx1013): GFXOFF causes the GPU to\n' '\t\t * enter a power-saving state from which it cannot reliably wake.\n' '\t\t * Unconditionally disable GFXOFF to prevent GPU hangs.\n' '\t\t */\n' '\t\tadev->pm.pp_feature &= ~PP_GFXOFF_MASK;\n' '\t\tdev_info(adev->dev,\n' '\t\t\t "BC-250: GFXOFF disabled to prevent GPU power-state hangs\\n");\n' '\t\tbreak;\n' '\t/* ===== BC-250 v3 PATCH END ===== */\n' ) content = content[:default_pos] + new_case + content[default_pos:] with open(filepath, 'w') as f: f.write(content) print("Patch 1 applied: gfx_v10_0.c — GFXOFF disable for Cyan Skillfish (IP 10.1.3)")