Upgrade Framework with NVIDIA
on frame.work
- Motivation
- Ordering Process and Timeline
- Upgrading the Power Adapter
- Upgrading the Firmware
- Replace Hardware
- Install Drivers
- Performance Comparison
- External G-SYNC Monitor
- Conclusion
Motivation Permalink
When I purchased the Framework 16 in July of 2023, it came with the AMD Radeon™ RX 7700S in the expansion bay. I had been hoping for an NVIDIA GPU, but that was not available at the time.
Some of you might ask why I would opt for NVIDIA over the AMD (ATI) GPU. Enough people have commented on it that it’s worth at least touching on briefly.
The first reason is that my primary external monitor is the Asus Rog Swift PG35VQ. This is a G-SYNC monitor. I have been buying NVIDIA products for quite some time. The last ATI GPU that I bought was the All-in-Wonder cards. That was decades ago. As such, I also have not been buying Freesync monitors.
The second reason is AI compatability. When I built my desktop in 2017-2018, it was using a GTX 1080 Ti card. That card is quite old by todays standards - and yet it was easier to get things like Stable Diffusion working on it than on the Framework 16 with Radeon GPU. My eight year old desktop should not be my goto for AI workloads when I have newer machines.
As such, I decided to replace the Radeon with the NVIDIA GeForce RTX 5070.
Ordering Process and Timeline Permalink
| Date | Description |
|---|---|
| 26 August 2025 | Down payment on Power Adapter - 240W - US/Canada (Batch 2) |
| 26 August 2025 | Down payment on Framework Laptop 16 Graphics Module (NVIDIA® GeForce RTX™ 5070) (Batch 1) |
| 20 November 2025 | Final payment of Framework Laptop 16 Graphics Module (NVIDIA® GeForce RTX™ 5070) |
| 23 November 2025 | Final payment on Power Adapter - 240W - US/Canada |
| 24 November 2025 | Delivery of Framework Laptop 16 Graphics Module (NVIDIA® GeForce RTX™ 5070) |
| 28 November 2025 | Delivery of Power Adapter - 240W - US/Canada |
| 18 December 2025 | Order of Framework Laptop Display Kit (2nd Gen) |
| 20 December 2025 | Delivery of Framework Laptop Display Kit (2nd Gen) |
The down payment for the power adapter was almost the entire purchase price.
Ordering the display kit was tricky since they always sold out quickly. I received multiple emails telling me they were in stock, but they were out of stock by the time I could get to the order page. I finally got it in December. As such, I waited to do the upgrade until I had all parts in hand.
Upgrading the Power Adapter Permalink
I am currently running my OS via the modules, with the NVME reserved for my work drive (git repos, etc). As such, I have a module for Ubuntu 24.04, Windows 11, Arch, nixOS, Ventoy, etc. As opposed to prior methods of dual booting, I am enjoying this method as Windows never attempts to overwrite Grub.
I have the power profile set to Balanced and have the BIOS set to a 60% limit. Since I always have it plugged in, I never see the battery go below 60%. That is, until recently. Starting a few months ago, the battery would drop to 47% while playing Elder Scrolls Online in Windows.
I upgraded the power adapter from 180 watt to 240 watt first. With just that change, the battery no longer drops below 60% while playing the game.
Upgrading the Firmware Permalink
I have not been very consistent keeping my BIOS up to date.
We can see this in Linux by running:
sudo apt install lshw dmidecode -y && clear && sudo dmidecode | grep -A3 'Vendor:\|Product:' && sudo lshw -C cpu | grep -A3 'product:\|vendor:'
This resulted in
Vendor: INSYDE Corp.
Version: 03.05
Release Date: 11/13/2024
Address: 0xE0000
product: AMD Ryzen 9 7940HS w/ Radeon 780M Graphics
vendor: Advanced Micro Devices [AMD]
physical id: 4
bus info: cpu@0
version: 25.116.1
Here we can see that we are on BIOS 03.05, not 04.02 as required. According to this doc, we have to update the keyboard firmware first.
As you can see there were some dependencies that needed to be addressed:
- The new GPU requires BIOS 4.02 (I was on 3.05)
- BIOS 4.02 requires Keyboard firmware 0.31 (I forgot to check what version I was on)
- The BIOS upgrade required fwupd 2.0.16 (which was only available via SNAP, I had APT version 1.9.31 installed)
- The SNAP version of fwupd has some open bugs that prevent it from accessing certain files
- Upgrading the keyboard firmware theoretically needed BIOS 4.01 or higher (again, I was on 3.05)
- The USB-PD on the new GPU also needs newer firmware (0.0.22) which it gets by doing a BIOS update, but we are supposed to install the BIOS before the hardware
After much trial and error, the process that I went through was:
- Replace the APT fwupd with the SNAP fwupd
- Manually install the keyboard firmware to 0.31
- Manually install the numpad firmware to 0.31
- Update the BIOS to 4.02
- Replace the hardware
- Update the GPU USB-PD firmware
- Re-install the BIOS update
- Install the GPU drivers
Let’s walk through one step at a time.
Replace fwupd Permalink
Since the APT version of fwupd was too old to work, we have to switch to the SNAP version. To be honest, I would have preferred to stick with the APT version - but not at the risk of not being able to update the laptop.
We can confirm that the APT version is too old:
sudo apt-cache policy fwupd
[sudo] password for malachi:
fwupd:
Installed: 1.9.31-0ubuntu1~24.04.1
Candidate: 1.9.31-0ubuntu1~24.04.1
Version table:
1.9.33-0ubuntu1~24.04.1ubuntu1 100
100 http://archive.ubuntu.com/ubuntu noble-proposed/main amd64 Packages
*** 1.9.31-0ubuntu1~24.04.1 500
500 http://us.archive.ubuntu.com/ubuntu noble-updates/main amd64 Packages
100 /var/lib/dpkg/status
1.9.16-1 500
500 http://us.archive.ubuntu.com/ubuntu noble/main amd64 Packages
The framework page says it requires fwupd 2.0.16 or later.
To switch to the SNAP version:
sudo apt remove fwupd
sudo snap install fwupd --classic
fwupdmgr refresh --force
I might not have needed to, but at this point I rebooted just to clear out anything that might have been running.
Upgrade Keyboard Firmware Permalink
If we run
fwupdmgr get-updates && fwupdmgr update
We can see the BIOS is available:
╔══════════════════════════════════════════════════════════════════════════════╗
║ Upgrade System Firmware from 0.0.3.5 to 0.0.4.2? ║
╠══════════════════════════════════════════════════════════════════════════════╣
║ Enhancements and Fixes: ║
║ ║
║ • Added support for the NVIDIA® GeForce RTX™ 5070. ║
║ • Integrated the NVIDIA DR and VK keys to support the NVIDIA G-SYNC ║
║ feature (requires a 2nd Gen Display kit). ║
║ • Added support for the NVIDIA Advanced Optimus feature (requires a 2nd ║
║ Gen Display kit). ║
║ • Updated the 7040 Series STT table. ║
║ • Updated the standalone detection user interface (UI). ║
║ • Updated the Framework Input Module application. ║
║ • Updated the PD firmware to 0x22 for NVIDIA® GeForce RTX™ 5070. ║
║ • Enabled the USCI 2.0 feature. ║
║ • Fixed the issue causing PROCHOT to occur when the system was under ║
║ heavy load. ║
║ • Fixed an issue where the CPU became locked at 0.55 GHz during Furmark ║
║ and CPU burn stress tests. ║
║ • Fixed an issue where the screen would flash when switching between two ║
║ EPR adapters. ║
║ • Fixed an issue where the Supervisor Password incorrectly displayed "Not ║
║ Installed" after the user had successfully set the password. ║
║ • Fixed an issue where the system always displayed an "invalid supervisor ║
║ password" error when the user set TPM to Hidden and set the supervisor ║
║ password within the same BIOS session. ║
║ • Fixed an issue where the Wooting 80HE Keyboard did not function while ║
║ in the BIOS. ║
║ • Fixed an issue where the system would flash a black screen during DDS. ║
║ ║
║ Laptop 16 (AMD Ryzen 7040 Series) must remain plugged into a power source ║
║ for the duration of the update to avoid damage. ║
╚══════════════════════════════════════════════════════════════════════════════╝
Perform operation? [Y|n]: n
Devices with the latest available firmware version:
• Fingerprint Sensor
• UEFI dbx
Devices with no available firmware updates:
• DisplayPort Expansion Card
• KEK CA
• SBAT
• USB2.1 Hub
• WD BLACK SN850X 4000GB
• frame.work-LaptopAMDKEK
However, the keyboard is not listed in the firmware. The official documentation said that it would update automatically when running that command, however, our current BIOS is too old to support it.
At this stage, I tried a couple different ways to install the firmware.
I downloaded the .cab files and tried to install them manually. I tried with both fwupdmgr local-install and
by putting them in /var/snap/fwupd/common/share/fwupd/remotes.d/vendor/firmware/. You can see
Failed to open cab file error when local install is executed on Snap version of fwupd for more information.
The UF2 method showed a lot more promise.
- Download the ANSI Keyboard file
- Download the Numpad file
- Slide touchpad down until the input deck powers off (backlights turn off)
- Hold the two buttons (left and right alt for the keyboard, keys 1 and 6 for numpad) while sliding the touchpad back into place
- The keyboard/numpad is now in bootloader mode. Use the touchpad to drag the .uf2 file onto the RPI-2 drive
- The keyboard/numpad will auto update itself and restart
That process seemed to go pretty smoothly and was very quick!
How do I validate that the keyboard firmware was installed correctly? If I run:
lsusb -vd 32ac:
The output shows: Shows a lot of output, but in it we can see:
Bus 001 Device 014: ID 32ac:0012 Framework Laptop 16 Keyboard Module - ANSI
Couldn't open device, some information will be missing
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.10
bDeviceClass 0 [unknown]
bDeviceSubClass 0 [unknown]
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x32ac Framework
idProduct 0x0012 Laptop 16 Keyboard Module - ANSI
bcdDevice 0.31
Bus 001 Device 015: ID 32ac:0014 Framework Laptop 16 Numpad Module
Couldn't open device, some information will be missing
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.10
bDeviceClass 0 [unknown]
bDeviceSubClass 0 [unknown]
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x32ac Framework
idProduct 0x0014 Laptop 16 Numpad Module
bcdDevice 0.31
Note that the Framework Page says v0.3.1 but
the firmware says 0.31. I have noticed a lot of inconsistencies in the documentation with regard to dots and extra zeros.
Update BIOS Permalink
Now, we can try to update the BIOS.
We’ll run the same command from earlier:
fwupdmgr get-updates && fwupdmgr update
You will be prompted with a few Y/N questions.
Uploading firmware reports helps hardware vendors to quickly identify failing and successful updates on real devices.
Review and upload report now? (Requires internet connection) [Y|n]: n
Do you want to disable this feature for future updates? [y|N]: n
If you choose to upload the report, it will fail: For the snap version of fwupd since v2.0.17, an error message is shown after an update is installed and a reboot is required. Most likely, snapd needs to grant rw permission for fwupd to write the /run/reboot* files.
This appears to be a bug in the snap version of fwupd. It’s OK, we can skip the report for now and upload it later.
Once the command finishes, it is queued up for install. I ran the command multiple times, and it seemed to queue up the BIOS update multiple times.
Reboot the laptop and the BIOS update should start. It may reboot a few times (see my previous comment).
Once it has finished booting back into the OS, we can check the BIOS version:
fwupdmgr get-updates | cat /sys/class/dmi/id/bios_version
04.02
Idle…: 0%
No updates available
I re-ran the fwupdmgr and let it upload the reports. It shows there are no updates now.
Surprisingly, it still does not show the keyboard or numpad.
Replace Hardware Permalink
Now we will start replacing the hardware. Before we do that, let’s capture some performance for comparison.
Original Performance Permalink
I wanted to compare the performance of the old GPU and the new GPU. I didn’t want to run the same Geekbench or Cinebench tests as everyone else. As I mentioned before, the ability to easily install some hardware (like Stable Diffusion) makes this almost like comparing apples to oranges. That being said, there was one easy test we can run:
Let’s just check Ollama. We’ll use the same install, same model, same search (though rebooting). Really, we are just comparing ROCm to CUDA.
On the Radeon/ROCm:
ollama run --verbose llama3.2:1b
What is the proper way to use the Rust programming language to write a promiscuous mode driver?
...
total duration: 14.576339717s
load duration: 73.155187ms
prompt eval count: 45 token(s)
prompt eval duration: 38.804071ms
prompt eval rate: 1159.67 tokens/s
eval count: 1171 token(s)
eval duration: 13.525496642s
eval rate: 86.58 tokens/s
We’ll revisit this later.
Upgrade Screen Permalink
Next, we’ll upgrade the screen.
Framework is really good about their tutorials. Following this tutorial was a breeze. The only thing I did differently than what they showed is that I used the spunger end of my framework screwdriver to get under the corner of the screen. I couldn’t lift it with my fingernails.
Upgrade GPU Permalink
For the GPU, I followed this tutorial.
My module was mislabeled. While the shipping box said it was Nvidia, the sticker on the GPU said it was a Radeon. At the risk of affecting my warranty, I wrote on the sticker to make sure that down the road I knew what it really was.
When re-installing the interposer, I was surprised that the sticker was placed to be read upside down. Also, it wasn’t fully attached.
On boot it asked me to upgrade the dGPU firmware. It said it was at 0.0.21 and it expected 0.0.22. There was a QR on the screen to take you to these instructions.
It allows you to boot anyway so that you can fix it.
It tells you that you need to install BIOS 4.02 with the GPU connected. This is an interesting thing to note because their instructions said to install the GPU after installing the BIOS.
fwupdmgr get-updates && fwupdmgr update
Showed no updates available.
I tried
fwupdmgr refresh --force
But it had lost the Wi-Fi password.
Re-entering that, re-refreshing, re-updating… still no updates
fwupdmgr reinstall
0. Cancel
1. a6ac74eb9d266e92632936d19976d755b043b55c (Fingerprint Sensor)
2. 7010981714ee5c9258de42216cae163ef272c7ab (System Firmware)
3. 362301da643102b9f38477387e2193e57abaa590 (UEFI dbx)
Choose device [0-3]: 2
╔══════════════════════════════════════════════════════════════════════════════╗
║ Reinstall System Firmware to 0.0.4.2? ║
╠══════════════════════════════════════════════════════════════════════════════╣
║ Enhancements and Fixes: ║
║ ║
║ • Added support for the NVIDIA® GeForce RTX™ 5070. ║
║ • Integrated the NVIDIA DR and VK keys to support the NVIDIA G-SYNC ║
║ feature (requires a 2nd Gen Display kit). ║
║ • Added support for the NVIDIA Advanced Optimus feature (requires a 2nd ║
║ Gen Display kit). ║
║ • Updated the 7040 Series STT table. ║
║ • Updated the standalone detection user interface (UI). ║
║ • Updated the Framework Input Module application. ║
║ • Updated the PD firmware to 0x22 for NVIDIA® GeForce RTX™ 5070. ║
║ • Enabled the USCI 2.0 feature. ║
║ • Fixed the issue causing PROCHOT to occur when the system was under ║
║ heavy load. ║
║ • Fixed an issue where the CPU became locked at 0.55 GHz during Furmark ║
║ and CPU burn stress tests. ║
║ • Fixed an issue where the screen would flash when switching between two ║
║ EPR adapters. ║
║ • Fixed an issue where the Supervisor Password incorrectly displayed "Not ║
║ Installed" after the user had successfully set the password. ║
║ • Fixed an issue where the system always displayed an "invalid supervisor ║
║ password" error when the user set TPM to Hidden and set the supervisor ║
║ password within the same BIOS session. ║
║ • Fixed an issue where the Wooting 80HE Keyboard did not function while ║
║ in the BIOS. ║
║ • Fixed an issue where the system would flash a black screen during DDS. ║
║ ║
║ Laptop 16 (AMD Ryzen 7040 Series) must remain plugged into a power source ║
║ for the duration of the update to avoid damage. ║
╚══════════════════════════════════════════════════════════════════════════════╝
Perform operation? [Y|n]:
Waiting… [***************************************]
Failed to create file “/run/reboot-required.ER04H3”: Permission denied
That error is the previously identified one caused by us needing to use the SNAP version instead of the APT version.
Reboot allowed the BIOS to be updated. We can see PD3 updated to 0.0.22
Install Drivers Permalink
So far I have updated Ubuntu and Windows. I have not yet updated NixOS or Arch.
Ubuntu 24.04 Permalink
Opening the Additional Drivers UI, I can see that we are currently using xserver-xorg-video-nouveau.
I switched it to nvidia-driver-580-open.
nvidia-smi didn’t detect the driver until I rebooted.
nvidia-smi
Thu Dec 25 12:55:39 2025
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 580.95.05 Driver Version: 580.95.05 CUDA Version: 13.0 |
+-----------------------------------------+------------------------+----------------------+
| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|=========================================+========================+======================|
| 0 NVIDIA GeForce RTX 5070 ... Off | 00000000:01:00.0 Off | N/A |
| N/A 40C P0 17W / 100W | 15MiB / 8151MiB | 0% Default |
| | | N/A |
+-----------------------------------------+------------------------+----------------------+
+-----------------------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=========================================================================================|
| 0 N/A N/A 5287 G /usr/lib/xorg/Xorg 4MiB |
+-----------------------------------------------------------------------------------------+
Windows 11 Permalink
I downloaded the Windows drivers from the BIOS 4.02 page.
Easy install and reboot. That being said, when launching a game there was no longer an indication that it switched to the GPU. Previously, the AMD popup would tell me it was switching to the external GPU.
There are a couple Nvidia tray icons.
One of them showed the Epic launcher was using the GPU when I tried launching a game.
Another one was the NVidia App. If you launch that, you can login and download newer (by a month) drivers than was provided by Framework.
From the App, on the System tab, I can see that the display mode is “Auto (Integrated Graphics)”
By turning on the overlay, you can tell when games are using it because you’ll briefly get the Alt-Z tooltip on launch. This is similar to the previous AMD behavior.
Performance Comparison Permalink
Back in Linux, we grab the new performance numbers using the same commands:
total duration: 4.717006368s
load duration: 80.50099ms
prompt eval count: 45 token(s)
prompt eval duration: 11.463198ms
prompt eval rate: 3925.61 tokens/s
eval count: 930 token(s)
eval duration: 4.219326541s
eval rate: 220.41 tokens/s
How did it compare?
| Metric | AMD | NVIDIA | Comparison |
|---|---|---|---|
| Total Duration (sec) | 14.576339717 | 4.219 | ~3.45x faster |
| Load Duration (ms) | 73.155187 | 80.5 | roughly same |
| Prompt Eval Count (tokens) | 45 | 45 | same |
| Prompt Eval Duration (ms) | 38.804071 | 11.46 | ~3.39x faster |
| Prompt Eval Rate (token/s) | 1159.67 | 3925.61 | ~3.39x more |
| Eval Count (tokens) | 1171 | 930 | roughly same |
| Eval Duration (sec) | 13.525496642 | 4.219 | ~3.2x faster |
| Eval Rate (token/s) | 86.58 | 220.41 | ~2.55x more |
This is a significant improvement.
External G-SYNC Monitor Permalink
I mentioned earlier that I was using an Asus Rog Swift PG35VQ. I am connecting to it via DP using the Framework DP Module.
Testing whether G-SYNC was working on the external monitor was a little tricky.
In Linux, I checked the nvidia-settings app. It showed that the GPU was set to On-Demand Mode. There was, however, no
G-SYNC settings like I am used to seeing on my desktop. On the monitor OSD screen, it said it was in G-SYNC mode and
at 3440x1440@180Hz. I did not have the 200Hz overclock option enabled. It did not appear to matter whether the DP module
was plugged into the side of the laptop or directly into the GPU. The monitor saw it the same either way, as did nvidia-settings.
On Windows, it was a similar situation. The tray icon didn’t show that any monitor was connected even though it was displaying on it. I didn’t try plugging directly into the GPU there because let’s me honest, I do not need my cat to try to sit on the DP module. The monitor still showed that it was in G-SYNC mode at 3440x1440@180Hz. I did need to go into the Windows System settings and tell it to only show the external monitor when avaialble. That allowed it to auto-scale to the full size.
In the end I was not able to verify G-SYNC on the laptop side, but the monitor did indicate that it was using it. I should have tested plugging it into the monitor before installing the hardware. I seem to recall it was stuck at 59Hz on the AMD GPU, but… I’m not sure.
Conclusion Permalink
Upgrading everything took the better part of a day. If I had been keeping my BIOS updated all along, I think it easily would have cut the time in half. The hardware changes went pretty smoothly. Most of the time was due to trying to figure out why the keyboard didn’t show up in the BIOS update with fwupdmgr.
The UF2 process of updating the keyboard and numpad firmware was interesting as well.
While I only did performance analysis in Ollama, the combination of that and the ability to install software that is only CUDA-compatible makes this upgrade a no-brainer for me.
There was one gotcha on the ordering process. Ideally, you would upgrade the display kit, power adapter and GPU all at the same time. Unfortunately, the display kit is often out of stock. Hopefully they improve the stock for that component.
If they ever release the touchscreen, I suspect that will just be a new display kit that can be swapped in.
I guess one final note: there is no noticeable difference in size. The laptop still fits in my laptop bag.

