Support #597
opensuccess mb/dell: OptiPlex 5040 SFF works with adjusted Optiplex 3050 Micro code port
0%
Description
Not sure to put this under support or refactoring, since adding this code to upstream coreboot using gerrit may look straight forward and easy to have a nice working optiplex_5040 port. My concern is however that the original dell/optiplex_3050
code might need to be refactored into a variant first before this code will be accepted and that refactoring may be to much for me as a newbie.
But it works... it works really well indeed.
By mostly reusing dell/optiplex_3050
port code which takes care of handling some variants 'SFF/MICRO' hinted by 'ramstage.c' for its own 3050 series itself, I just reused all of the code which I mostly don't understand and therefor may be wrong to put that as NEW board into the code tree. Although I have 'autoport logs' made for my 'optiplex_5040_sff' I don't know how to translate/apply correct that to my model(if needed). But since you have to start somewhere, and autoport only made logs I therefor just want to share this code and progress.
Specs: Dell Optiplex 5040 SFF
Motherboard: DP/N 0T7D40, CN-0T7D40-72200, 588-00HF-A00
OEM BIOS version: 1.22.0 03/16/2022
Reg Model: D11S
Reg Type: D11S001
Service tag: HPR6C92
CPU: i3-6100
This Optiplex 5040 SFF motherboard looks very similar to the 3050 SFF(shares the same OEM BIOS as the 3050 micro) except for the following visual differences:
4 DDR3L slots vs 2 DDR4 slots (DDR4-sodimm on the micro)
1 PCIe 4x length (open) black slot vs 1x length (closed), micro none
3 SATA connectors vs 2 SATA (black missing), micro one
4 USB3 back ports vs 2 USB3
2 DisplayPorts vs 1 DisplayPort
1 serial vs 0 serial port
1 VGA(using motherboard header) vs 0 VGA
2 PS2 vs 0 PS2 ports
Q170 chipset vs B250 chipset
First the initial deguard requirement was the same for my optiplex_5040 sff as for the optiplex_3050 micro, as well as flashing or recovery. A minor edit to the deguard code is necessary to complete the deguard instruction.
With the following crucial edits to the 'optiplex_3050' port its 'Kconfig', 'romstage.c' and minor edits to the existing 'devicetree.cb' almost everything started working:
First hang on RAM issue "[EMERG] FspMemoryInit error, status=0x80000007" was fixed by adjusting 'Kconfig' config DIMM_SPD_SIZE
from default 512 # DDR4
to 256 # DDR3
and editing 'romstage.c' with additional addresses and changing CaVrefConfig 2
to 0
made all 4 DIMM slots work:
> struct spd_block blk = { .addr_map = { 0x50, 0x51, 0x52, 0x53 } };
mem_cfg->DqPinsInterleaved = 1;
> mem_cfg->CaVrefConfig = 0;
mem_cfg->MemorySpdDataLen = blk.len;
> mem_cfg->MemorySpdPtr00 = (uintptr_t)blk.spd_array[0];
> mem_cfg->MemorySpdPtr10 = (uintptr_t)blk.spd_array[2];
> mem_cfg->MemorySpdPtr01 = (uintptr_t)blk.spd_array[1];
> mem_cfg->MemorySpdPtr11 = (uintptr_t)blk.spd_array[3];
By some additional edits to 'devicetree.cb' all PCIe slots(16x,4x,M2-ssd), all USB2&3 ports, all SATA ports and both PS2 ports started to function. Only the USB OC values have my concern, don't know what they stand for.
> # SLOT2 x16
> device ref peg0 on
> register "Peg0MaxLinkWidth" = "Peg0_x16"
>
> # Configure PCIe clockgen in PCH
> register "PcieRpClkReqSupport[0]" = "1"
> register "PcieRpClkReqNumber[0]" = "0"
> register "PcieRpClkSrcNumber[0]" = "0"
> end
>
---
> device ref south_xhci on
> register "usb2_ports" = "{
> [0] = USB2_PORT_MID(OC0), // Front panel (blue)
> [1] = USB2_PORT_MID(OC0), // Front panel (blue)
> [2] = USB2_PORT_MID(OC3), // Back panel (blue)
> [3] = USB2_PORT_MID(OC2), // Back panel (blue)
> [4] = USB2_PORT_MID(OC1), // Back panel (blue)
> [5] = USB2_PORT_MID(OC1), // Back panel rightup (black)
> [6] = USB2_PORT_MID(OC1), // Back panel (blue)
> [7] = USB2_PORT_MID(OC1), // Back panel rightlow (black)
> [8] = USB2_PORT_MID(OC_SKIP), // Front Panel rightlow (black)
> [9] = USB2_PORT_MID(OC_SKIP), // Front Panel rightup (black)
>
> }"
> register "usb3_ports" = "{
> [0] = USB3_PORT_DEFAULT(OC0), // Front panel (blue)
> [1] = USB3_PORT_DEFAULT(OC0), // Front panel (blue)
> [2] = USB3_PORT_DEFAULT(OC2), // Back panel (blue)
> [3] = USB3_PORT_DEFAULT(OC2), // Back panel (blue)
> [4] = USB3_PORT_DEFAULT(OC1), // Back panel (blue)
> [5] = USB3_PORT_DEFAULT(OC1), // Back panel (blue)
> }"
> end
---
> register "SataPortsEnable[1]" = "1"
> register "SataPortsEnable[2]" = "1"
---
< device ref pcie_rp21 on
< register "PcieRpClkReqSupport[20]" = "1"
< register "PcieRpClkReqNumber[20]" = "3"
< register "PcieRpAdvancedErrorReporting[20]" = "1"
< register "PcieRpLtrEnable[20]" = "true"
< register "PcieRpClkSrcNumber[20]" = "3"
< register "PcieRpHotPlug[20]" = "1"
< end
<
< # Realtek LAN
< device ref pcie_rp5 on
< register "PcieRpClkReqSupport[4]" = "0"
< register "PcieRpHotPlug[4]" = "0"
< end
<
< # M.2 WiFi
< device ref pcie_rp8 on
< register "PcieRpClkReqSupport[7]" = "0"
< register "PcieRpHotPlug[7]" = "1"
---
> # SLOT3_M.2
> device ref pcie_rp17 on
> register "PcieRpClkReqSupport[16]" = "1"
> register "PcieRpClkReqNumber[16]" = "3"
> register "PcieRpAdvancedErrorReporting[16]" = "1"
> register "PcieRpLtrEnable[16]" = "true"
> register "PcieRpClkSrcNumber[16]" = "3"
> register "PcieRpHotPlug[16]" = "1"
> end
>
> # SLOT1 x4
> device ref pcie_rp9 on
> register "PcieRpClkReqSupport[8]" = "0"
> register "PcieRpHotPlug[8]" = "1"
> end
---
> device pnp 2e.1 on # 8042
> io 0x60 = 0x60
> irq 0x0f = 0
> irq 0x70 = 1
> irq 0x72 = 12
> end
---
> chip drivers/pc80/tpm
> device pnp 0c31.0 on end
> end
---
> device ref gbe on end
Also TPM2 and onboard ethernet came alive with final edits to 'Kconfig':
> select MAINBOARD_HAS_TPM2
> select MEMORY_MAPPED_TPM
> select MAINBOARD_USES_IFD_GBE_REGION
All audio ports including chassis speaker(soundcard) work using unchanged optiplex_3050 code, however autoport logs ran on OEM show different codec(chipset) and parameters for the 5040_sff compared to 3050 micro this may need to be alterned for correctness?
Video output was unreliable until I replaced 'data.vbt' with the one extracted from original Dell Optiplex 5040 SFF 1.22 OEM bios (debugfs) and altered 'gma-mainboard.ads' to have HDMI and 2 DisplayPorts working perfectly. Only the VGA port, which is shown as 3rd DisplayPort (xrandr) uses the original motherboard breakout to the chassis VGA won't work at all (port not detected no BOOT nor OS).
ports : constant Port_List :=
(HDMI1, -- External HDMI
DP2, -- External DP (bottom)
DP1, -- External DP (top)
DP3, -- External VGA (opt. breakout cable)
others => Disabled);
Tested this on coreboot-25.03-519-ga2010cf5eeea both SeaBIOS 1.16.3 and EDK2 MrChromeBox 2502 payloads booting KDE NEON Linux 6.11 fine.
Besides the "VGA port" only "Wake for LAN" isn't working for me yet every other port/connection/slot does work even combined iGPU and dGPU, leds, and CPU Fan speed also varies boot/restart. My concern is with the USB OC values, allot of GPIO values copied from the 3050 port and not correct to autoport and other stuff I might overlook.
Feel free to check the added drop in optiplex_5040_sff.zip file with mostly a copy of 3050 micro port code to build a functional optiplex_5040_sff target or spin a variant into gerrit which I can assist and confirm testing.
Files