# Experimental 40CU Guide This guide is for the experimental `-40cu` images. > [!IMPORTANT] > Start with temporary live changes. Only save a boot table after the board survives real game or benchmark testing. ## What the 40CU image does The `-40cu` images include: - The same current Bazzite base as the normal images. - `cyan-skillfish-governor-smu`. - `umr`. - `bc250-cu-live-manager` for runtime WGP/CU dispatch. - Original 40CU research, scripts, and documentation from [`duggasco/bc250-40cu-unlock`](https://github.com/duggasco/bc250-40cu-unlock). - Short `ujust` helpers. They do not enable 40CU automatically on first boot. > [!NOTE] > This image packages the tooling and safer commands around the original research. It does not claim the register research as original to this repository. ## What it can and cannot prove What this image can validate: - The image boots. - The governor works. - `umr` and the live manager are present. - Runtime WGP dispatch can be changed to 32CU/40CU. - A chosen WGP table can be saved and replayed at boot. - Factory 24CU dispatch can be restored. What it cannot guarantee: - That every disabled WGP/CU on every BC-250 is healthy. - That 40CU will be stable in games on every board. - That 32CU will be stable if your extra WGPs are marginal. - That lower clocks can fix genuinely defective CUs. > [!CAUTION] > If your board works at 24CU but crashes, artifacts, or fails to launch games at 32CU/40CU, the image may still be fine. Your board likely cannot run those extra WGPs reliably. ## Install a 40CU image ```bash # Deck 40CU rpm-ostree rebase ostree-image-signed:docker://ghcr.io/62fixolab/bazzite-bc250-patched-deck-40cu:latest # GNOME 40CU rpm-ostree rebase ostree-image-signed:docker://ghcr.io/62fixolab/bazzite-bc250-patched-gnome-40cu:latest # KDE 40CU rpm-ostree rebase ostree-image-signed:docker://ghcr.io/62fixolab/bazzite-bc250-patched-kde-40cu:latest systemctl reboot ``` > [!NOTE] > Branch builds can also publish traceability tags such as `br-40cu-43` or `br-40cu-44`. Use those only if `latest` is not available yet. ## First checks ```bash rpm-ostree status command -v bc250-cu-live-manager command -v umr systemctl status cyan-skillfish-governor-smu --no-pager ``` Then check the current CU/WGP state: ```bash ujust bc250-cu-status ujust bc250-cu-dry-run-40 ``` ## Test full 40CU temporarily Apply the conservative governor profile first: ```bash ujust bc250-cu-sweet-spot ``` This writes a 1500 MHz / 900 mV profile based on the upstream 40CU report. Then apply full 40CU until the next reboot: ```bash ujust bc250-cu-enable-40 ujust bc250-cu-status ``` > [!WARNING] > Test games or benchmarks before making this persistent. Watch for crashes, artifacts, black screens, temperature spikes, or games failing to launch. ## Interpreting status You may see this: ```text SPI total : 40/40 CUs Driver lock : 24/40 CUs active ``` `Driver lock` is what `amdgpu` saw when it initialized. `SPI total` is the live dispatch table written through UMR. For runtime testing, this is the value to watch. For a saved boot profile, check: ```text Service : enabled Boot sync : current table saved Boot table: SE0.SH0=0x1f SE0.SH1=0x1f SE1.SH0=0x1f SE1.SH1=0x1f ``` That means the boot service is installed and the saved table matches the current table. ## Try 32CU instead of 40CU If 40CU is unstable, try one extra WGP per shader row: ```bash ujust bc250-cu-disable-boot ujust bc250-cu-restore-24 sudo bc250-cu-live-manager enable-wgp 0.0.3 0.1.3 1.0.3 1.1.3 ujust bc250-cu-status ``` Expected result: ```text SPI total : 32/40 CUs ``` > [!CAUTION] > If 32CU is also unstable, stay on factory 24CU. That is a valid result. ## Find a stable custom CU layout If 40CU, 38CU, or the simple 32CU test is unstable, test from the other direction: start at factory 24CU and add one extra WGP at a time. `bc250-cu-live-manager` works at WGP granularity. Each WGP adds 2 CUs: ```text 24CU + 1 WGP = 26CU 24CU + 2 WGP = 28CU 24CU + 3 WGP = 30CU 24CU + 4 WGP = 32CU 24CU + 5 WGP = 34CU 24CU + 6 WGP = 36CU 24CU + 7 WGP = 38CU 24CU + 8 WGP = 40CU ``` Start clean: ```bash ujust bc250-cu-disable-boot ujust bc250-cu-restore-24 ujust bc250-cu-sweet-spot ``` Then enable one extra WGP and test a demanding real game: ```bash sudo bc250-cu-live-manager enable-wgp 0.0.3 ujust bc250-cu-status ``` If it is stable, keep it enabled and add the next candidate. This is a cumulative test: do not reset between successful WGPs. ```bash sudo bc250-cu-live-manager enable-wgp 0.0.4 ujust bc250-cu-status ``` If the game still works, keep both enabled and continue with the next candidate. If the game crashes right after adding a WGP, mark only the WGP you just added as bad. Then restore factory dispatch, re-enable the known-good WGPs, skip the failed one, and continue with the next candidate. Example: ```bash # 0.0.3 and 0.0.4 were already tested as stable. # 0.1.3 crashed, so rebuild the known-good list and skip it. ujust bc250-cu-restore-24 sudo bc250-cu-live-manager enable-wgp 0.0.3 0.0.4 ujust bc250-cu-status # Continue testing the next candidate while keeping the known-good list active. sudo bc250-cu-live-manager enable-wgp 0.1.4 ujust bc250-cu-status ``` Suggested candidate order: ```text 0.0.3 0.0.4 0.1.3 0.1.4 1.0.3 1.0.4 1.1.3 1.1.4 ``` Use a real game that reliably stresses your board. One tested board used Forza Horizon 4: if the game crashed after the cinematic shown after pressing Continue in the main menu, the WGP that had just been added was treated as unstable and skipped. Previously stable WGPs stayed in the known-good list. Example real result from one board: ```text Stable: 0.0.3 0.0.4 1.0.3 1.0.4 1.1.3 1.1.4 Unstable: 0.1.3 0.1.4 ``` That board ended up stable at 36CU: ```bash ujust bc250-cu-disable-boot ujust bc250-cu-restore-24 ujust bc250-cu-sweet-spot sudo bc250-cu-live-manager enable-wgp 0.0.3 0.0.4 1.0.3 1.0.4 1.1.3 1.1.4 ujust bc250-cu-status ``` Expected result: ```text SPI total : 36/40 CUs ``` > [!NOTE] > This 36CU layout is only an example from one board. Your stable WGP list can be different. ## Save a stable table at boot Only do this after extended testing: ```bash ujust bc250-cu-save-boot systemctl reboot ujust bc250-cu-status systemctl status bc250-cu-live-manager.service --no-pager ``` ## Roll back to factory 24CU ```bash ujust bc250-cu-disable-boot ujust bc250-cu-restore-24 ``` If a saved boot table causes trouble, boot a previous deployment or recovery shell and run: ```bash sudo systemctl disable --now bc250-cu-live-manager.service sudo rm -f /etc/bc250-cu-live-manager.conf ``` ## 40CU commands ```bash # Show current BC-250 CU/WGP state ujust bc250-cu-status # Open the interactive manager ujust bc250-cu-menu # Preview the 40CU register writes without applying them ujust bc250-cu-dry-run-40 # Apply full 40CU dispatch until reboot ujust bc250-cu-enable-40 # Save the current table and enable boot restore ujust bc250-cu-save-boot # Restore factory 24CU dispatch live ujust bc250-cu-restore-24 # Remove the boot restore service and saved table ujust bc250-cu-disable-boot # Apply the conservative 1500 MHz / 900 mV governor profile ujust bc250-cu-sweet-spot # Restore the previous governor config backed up by the helper ujust bc250-cu-governor-restore ``` ## Health checker The upstream health checker is included as documentation/tooling, but it is not wired into `ujust` and is not run automatically. > [!WARNING] > The health checker can reboot repeatedly and has already caused black-screen recovery situations for some users. Do not run it unless you understand the recovery path. ## Updating vendor sources This repository keeps upstream tooling in `vendor/` and copies runtime files into `files/system/usr/share/bc250-40cu/vendor/`. To refresh both copies from upstream: ```bash scripts/update-40cu-vendors.sh ``` > [!IMPORTANT] > Review the diff before building. Local wrappers live outside `vendor/`, so upstream updates can be applied without rewriting the image integration. ## References - [`duggasco/bc250-40cu-unlock`](https://github.com/duggasco/bc250-40cu-unlock) - [`duggasco/bc250-40cu-unlock` technical report](https://github.com/duggasco/bc250-40cu-unlock/blob/main/docs/technical-report.md) - [`duggasco/bc250-40cu-unlock` whitepaper](https://github.com/duggasco/bc250-40cu-unlock/blob/main/docs/whitepaper-cu-unlock.pdf) - [`WinnieLV/bc250-cu-live-manager`](https://github.com/WinnieLV/bc250-cu-live-manager)