Regarding doing your own mainboard pcb. The schematic is the easy bit. The really challenging and time consuming part is the routing of the pcb traces so it all works.
This is why i like some manufactures publishing full schematics and boardview. They don’t give any details of the pcb routing away. They say what is connected to what, but not the routing of how it gets there. So they don’t give the valuable bit away.
As an example. I worked on one project. Schematic took 30 days to do. The pcb routing took 600 days, of a team of 20 people, to get right, involving multiple cycles of test boards being made.
Hey!
Sorry to be that person but is there a way I can test this? I am very comfortable with flashing chips and have spent a lot of time with experimental coreboot builds. I would love to have this running on my framework 16, but it isn’t my daily driver.
Thank you for all your work! ![]()
Also, is there any way we can support your work?
Looks great! More strength to your arm!
Do you have scripts to pull device data into the (is it?) devicetree so I might test on the other Phoenix device, the FW13 AMD 7040?
Hi!
I would recommend waiting just a bit longer. I were given a soft-deadline until 4th of August (when I need to provide buildable code/builds and system for demonstration, which is likely going to be just my work laptop that I’ve done those “terrible” things to
)
Things will also progress on a daily basis from now on. For example, yesterday eDP (internal display) still wasn’t working and USB was really broken (only expansion cards would be detected, and not even all of them).
While asking around I were told that ATOMBIOS supposedly wasn’t storing device-specific information but that didn’t sit well with me so I re-flashed stock firmware, booted into Linux and dumped VBIOS from sysfs (`cat /sys/kernel/debug/dri/0000:c1:00.0/amdgpu_vbios > /tmp/vbios-phoenix.bin`).
This is my first time working on a modern AMD platform (last one I worked on was a Piledriver when I was still in high-school) and have zero documentation or NDA’d source-code so this is purely just my guess, but Intel has VBTs for this exact purpose so it sounds right ![]()
Of course my hunch was right and now GPU output (at least eDP) works correctly:
USB will be really annoying to bring-up correctly (not to mention USB4/TB4) but at least in the current state (despite code being terrible) at least BT/FP works, as well as USB3.2 ports (so upper ones on both side only accept charge at the moment, likely something to do with retimers. We’ll probably need to do testing to figure out which lane equalization values to use for most-stable connection as well.
The reason why I’m not recommending flashing it is that it might not be completely safe. For example when I booted the system and started KDE Plasma, I was greeted with a login sound and freaked out because I haven’t done any codec configuration so not only it shouldn’t be working, it could fry my speakers (which gives me flashbacks from working on ApolloLake Chromebooks).
Thankfully speakers were cold to the touch so it didn’t happen, but I wasn’t brave enough to play music on it or anything. Sure, I could always buy replacement speakers from Framework and easily swap them but explaining to my manager “Uhh, hey, so, I need new speakers for my laptop because it somehow worked without HDA verbs…” would be a funny coversation ![]()
Also, thank you for kind words. Not sure if Framework peeps would be okay with me advertising Ko-Fi or Liberapay though so I’ll say that I’m fine for now.
So yeah, it’s good enough to give a demo but I wouldn’t feel comfortable sharing current state knowing it might not be safe to run: https://www.youtube.com/watch?v=7XlH_1Z0slk
@Martin_L_Roth did some work on Azalea before OpenSIL was released publicly, but code will need some adjustments to actually build with OpenSIL.
You can find it here (really would prefer it to be a single patch like I do with my board ports): https://review.coreboot.org/c/coreboot/+/81994
I think I’ll start cleaning up and upstreaming my local tree by the end of this month, really not looking forward into splitting it into patches though ![]()
❯ git status
On branch main
Your branch is ahead of 'origin/main' by 6 commits.
(use "git push" to publish your local commits)
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: src/mainboard/framework/lotus/Makefile.mk
modified: src/mainboard/framework/lotus/devicetree.cb
modified: src/mainboard/framework/lotus/mainboard.c
modified: src/soc/amd/common/block/cpu/update_microcode.c
modified: src/soc/amd/phoenix/chipset_opensil.cb
modified: src/soc/amd/phoenix/fch.c
modified: src/vendorcode/amd/opensil/phoenix_poc/opensil_config.template
Unmerged paths:
(use "git restore --staged <file>..." to unstage)
(use "git add <file>..." to mark resolution)
both modified: src/vendorcode/amd/opensil/phoenix_poc/mpio/chip.c
both modified: src/vendorcode/amd/opensil/phoenix_poc/ramstage.c
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: 3rdparty/amd_blobs (new commits)
modified: payloads/external/Makefile.mk
modified: payloads/external/edk2/Kconfig
modified: payloads/external/edk2/Makefile
modified: src/mainboard/framework/common/ec.h
modified: src/mainboard/framework/common/smihandler.c
modified: src/mainboard/framework/lotus/Kconfig
modified: src/mainboard/framework/lotus/devicetree.cb
modified: src/mainboard/framework/lotus/dsdt.asl
modified: src/soc/amd/common/block/psp/psp.c
modified: src/soc/amd/phoenix/acpi/soc.asl
modified: src/soc/amd/phoenix/chipset_opensil.cb
modified: src/vendorcode/amd/opensil/phoenix_poc/opensil (new commits)
Untracked files:
(use "git add <file>..." to include in what will be committed)
bzImage
config-lotus-opensil
config-lotus-opensil-linux
opensil-dirty-patches.patch
src/drivers/amd/opensil/memmap_v1.c
src/drivers/amd/opensil/memmap_v2.c
Worked on EC a bit today, pretty sure we can get suspend working (currently platform goes into s0ix and power draw drops to ~0.33W, but EC doesn’t register s0ix state transition).
It will need some more ACPI code, all other functionality seems to work now:
Power on/off, AC/BAT reporting (it correctly reports that I don’t have battery installed, we’ll see once I get to un-soldering and moving wires around), fan speed control based on SoC temperature etc.
It also looks like we’re not doing terribly when it comes to (idle) power management, I honestly expected much worse given it’s still in early state (measured with USB-C power meter):
| Firmware | InsydeH2O | coreboot |
|---|---|---|
| Screen on | ~8.23W (33.1V*0.25A) | ~8.94W (33.1V*0.27A) |
| Screen off | ~5.10W (33.1V*0.15A) | ~5.30W (33.1V*0.16A) |
Did some minor tweaks today, nothing too fancy or advanced.
It seems like I2C is now working (can see EC sensors device, no touchpad as I don’t have it connected but I’m pretty sure it would be fine).
Also tested my script for fixing power management I wrote when I was using stock firmware on this laptop on a daily basis, Idle power draw dropped to ~3.65W (33.1V*0.11A) and system didn’t “blow up” (no lockup or warnings in dmesg). I’m pretty sure I can transfer that script into firmware so power management will be configured this way by coreboot, ending up being more power-efficient than stock firmware without those tweaks.
I’ve been following this for a while, hoping your coreboot implementation will end up being written better than Framework’s stock firmware so that I can flash it to my FW16 and stop getting these annoying system lockups that sometimes randomly happen when I connect peripherals or the power adapter. So far, it’s looking quite promising to my amateur eye. Hopefully it’ll end up being able to boot Windows as well as Linux though, as I use Windows for my games. Don’t know enough about coreboot to answer that question myself.
Minor question.
The FW16 180W power adapter supplies power at 36V, and not 33.1V. How are you measuring it?
The 36V is at the usb port, it is then down converted to 20V on the mainboard, with 20V fed into the battery charger chip and then onto the VRMs to the CPU/APU.
Looks like you’re right:
root@frame:/home/elly# framework_tool --pdports
USB-C Port 0:
PD Contract: No
Power Role: Sink
Data Role: Ufp
USB-C Port 1:
PD Contract: No
Power Role: Source
Data Role: Dfp
VCONN: Off
Negotiated: 5.000 V, 1500 mA, 7.500 W
CC Polarity: CC2
USB-C Port 2:
PD Contract: No
Power Role: Sink
Data Role: Ufp
USB-C Port 3:
PD Contract: Yes
Power Role: Sink
Data Role: Dfp
VCONN: Off
Negotiated: 36.000 V, 5000 mA, 180.0 W
CC Polarity: CC1
Port Partner: Source
EPR: Active (Supported)
Sink Active: Yes
In this case my cheapo USB-C power meter is probably misreporting the voltage, so measurments might not be completely accurate (aka take them with a grain of salt, but might be fine-ish in comparsion to each other).
I ran the system trough it’s paces today (compiling Linux kernel… twice, 3D benchmark) and it showed power consumption roughly in the ballpark that I would expect without a dGPU (~72W in Unigine Superposition, ~85W while building the Linux kernel).
Probably should look for a slightly nicer meter, but once I install the battery I will (or at least should) be able to measure power draw from battery internally. For now, the setup still looks like this:
Looked more into I2C init yesterday, looks like coreboot’s sconfig is a bit borked (it works with nodes/config added to chipset_opensil.cb, but not board’s devicetree where it belongs) and will need some investigation.
Regardless, with this configuration touchpad works so input deck is now functional:
@Daniel_Schaefer tested expansion bay (thanks!) and found that 2x SSD adapter shows up but only a single SSD was detected (which made sense, I configured PCIe lanes as 1x8). However, GPU wasn’t detected at all which… surprised me to say the least.
Need to look at schematics and poke my board with oscilloscope to make sure DGPU_PWR_EN, as well as clock and reset GPIOs are configured correctly. It also might be just that the GPU needs a bit more time for init, currently we’re going “as fast as possible” (which means roughly 3x faster than stock firmware).
We’ll see, I’ll ask my manager if I can get an OCuLink adapters (1x8, 2x4) to test PCIe and bifurfication. Will also need to add update_devicetree to control bifurfication based on what EC reports. It’s not very high on priority list for now ![]()
Also looked into GOP init (display output in firmware), of course AMD doesn’t ship any debug symbols with their drivers so I dropped it into IDA. My current theory is that the driver is trying to store some NVRAM variables, but because SMMSTORE is currently broken (will need to debug that) it fails silently.
It also looks like AMD is patching EDID, which is… strange, but driver seems relatively simple aside from that. If I’ll have some spare time this year (ha, ha, one can dream) I’d be up for RE-ing it and writing coreboot-native implementation instead.
I would say that current priority list would be:
- SMMSTORE/GOP init
- Suspend, sensors and other remaining EC stuff
- Non-eDP display outputs (at the moment AMDGPU “knows” it should initialize the DDI link as it receives the hotplug event but DP Alt-Mode init times out, need to
drm.debug=0xefor more details) - PCIe expansion bay
- USB4/Thunderbolt
… and I think that’s it? I personally could start daily-driving this as soon as suspend is fixed and have to say that I really missed using this machine. Having proper workstation on the go is just… nice.
For the (1x8, 2x4) to test PCIe and bifurcation.
The Expansion bay has a small EEPROM chip on it. The EC reads the EEPROM.
The FW BIOS then sends an EC command to the EC to read this data, and then the FW BIOS configures the PCIe bifurcation to match the EEPROM.
So, I think you might need to get Coreboot/OpenSIL to send the EC command for this to work.
Regarding the EDID. Some laptops read from the display panel, while others hard code it in the BIOS. Maybe this AMD GOP init is storing it in NVRAM. I think storing it in the BIOS improves boot time very slightly.
Yes, I know - and it’s exactly what I said. I have various dumps and logs from stock firmware.
As for EDID: That’s absolutely not the case, wouldn’t make any sense. GOP driver probes PCIe bus to talk to a GPU, reads EDID data from the display panel (or other available DDI links via I2C), and (seemingly) patches EDID/VBIOS as it publishes it’s own ACPI tables.
can confirm that it works pretty well! Amazing job by elly so far!
I’m working with her to make sure she knows how to interact with the EC.
Greatly looking forward to this being publicly available and more configurable than the stock bios (which is easily one of the worst I’ve ever seen) Amazing work elly
I do hope it also means we’ll get a port for the FW13 at some point too, after the FW16!
There’s been a WIP port for the Framework 13 AMD Ryzen 7040 series for a while: https://review.coreboot.org/q/file:^src/mainboard/framework/azalea/.*
Support for the Ryzen AI 300 series based FW13 and FW16 boards is probably unlikely at the moment, as there isn’t any support for those chips in coreboot and no openSIL or FSP blob available for them as far as I know.





