diff --git a/Lilu/Headers/kern_devinfo.hpp b/Lilu/Headers/kern_devinfo.hpp index ce798a4b..f2f74d08 100644 --- a/Lilu/Headers/kern_devinfo.hpp +++ b/Lilu/Headers/kern_devinfo.hpp @@ -42,6 +42,13 @@ class DeviceInfo { * @param obj wait for (PCI) object publishing */ void awaitPublishing(IORegistryEntry *obj); + + /** + * Checks if an ATIAMD object is an AMD iGPU + * + * @param obj Object to run the check on. + */ + bool checkForAndSetAMDiGPU(IORegistryEntry *obj); public: /** @@ -246,6 +253,41 @@ class DeviceInfo { static constexpr uint32_t ConnectorLessCoffeeLakePlatformId5 {0x9BC50003}; static constexpr uint32_t ConnectorLessCoffeeLakePlatformId6 {0x9BC40003}; + /** + * Kaveri, and also catches the new Granite Ridge rDNA 2 iGPU. + */ + static constexpr uint32_t GenericAMDKvGr = 0x1300; + + /** + * Kabini, Mullins, Carrizo, Stoney Ridge, Wrestler. + */ + static constexpr uint32_t GenericAMDKbMlCzStnWr = 0x9800; + + /** + * Raven/Raven2, Picasso, Barcelo, Phoenix & Phoenix 2 (?) + */ + static constexpr uint32_t GenericAMDRvPcBcPhn = 0x1500; + + /** + * Renoir, Cezanne, Lucienne, Van Gogh, Rembrandt, Raphael. + */ + static constexpr uint32_t GenericAMDRnCznLcVghRmbRph = 0x1600; + + /** + * Trinity + */ + static constexpr uint32_t GenericAMDTrinity = 0x9900; + + /** + * Sumo & Sumo2? + */ + static constexpr uint32_t GenericAMDSumo = 0x9600; + + /** + * Phoenix. + */ + static constexpr uint32_t GenericAMDPhoenix2 = 0x1900; + public: /** * Vesa framebuffer identifier diff --git a/Lilu/Sources/kern_devinfo.cpp b/Lilu/Sources/kern_devinfo.cpp index 5a37ac02..cce0f2eb 100644 --- a/Lilu/Sources/kern_devinfo.cpp +++ b/Lilu/Sources/kern_devinfo.cpp @@ -184,6 +184,27 @@ void DeviceInfo::awaitPublishing(IORegistryEntry *obj) { SYSLOG("dev", "found unconfigured pci bridge %s", safeString(obj->getName())); } +bool DeviceInfo::checkForAndSetAMDiGPU(IORegistryEntry *obj) { + uint32_t dev = 0; + WIOKit::getOSDataValue(obj, "device-id", dev); + dev &= 0xFF00; + switch (dev) { + case GenericAMDKvGr: + case GenericAMDRvPcBcPhn: + case GenericAMDRnCznLcVghRmbRph: + case GenericAMDPhoenix2: + case GenericAMDSumo: + case GenericAMDKbMlCzStnWr: + case GenericAMDTrinity: + DBGLOG("dev", "found IGPU device %s", safeString(obj->getName())); + videoBuiltin = obj; + requestedExternalSwitchOff |= videoBuiltin->getProperty(RequestedExternalSwitchOffName) != nullptr; + return true; + default: + return false; + } +} + void DeviceInfo::grabDevicesFromPciRoot(IORegistryEntry *pciRoot) { awaitPublishing(pciRoot); @@ -209,6 +230,8 @@ void DeviceInfo::grabDevicesFromPciRoot(IORegistryEntry *pciRoot) { DBGLOG("dev", "found IGPU device %s", safeString(name)); videoBuiltin = obj; requestedExternalSwitchOff |= videoBuiltin->getProperty(RequestedExternalSwitchOffName) != nullptr; + } else if (vendor == WIOKit::VendorID::ATIAMD && (code == WIOKit::ClassCode::DisplayController || code == WIOKit::ClassCode::VGAController)) { + checkForAndSetAMDiGPU(obj); } else if (code == WIOKit::ClassCode::HDADevice || code == WIOKit::ClassCode::HDAMmDevice) { if (vendor == WIOKit::VendorID::Intel && name && (!strcmp(name, "HDAU") || !strcmp(name, "B0D3"))) { DBGLOG("dev", "found HDAU device %s", safeString(name)); @@ -245,6 +268,14 @@ void DeviceInfo::grabDevicesFromPciRoot(IORegistryEntry *pciRoot) { pcicode == WIOKit::ClassCode::VGAController || pcicode == WIOKit::ClassCode::Ex3DController || pcicode == WIOKit::ClassCode::XGAController) { + if (pcivendor == WIOKit::VendorID::ATIAMD) { + // The iGPU can live in places other than the root bridge. + // This can be seen in Ryzen Mobile. + // This may be why the older iGPUs had issues, as the device seemingly lives under the root bridge on those platforms. + if (checkForAndSetAMDiGPU(pciobj)) { + continue; + } + } DBGLOG("dev", "found GFX0 device %s at %s by %04X", safeString(pciobj->getName()), safeString(name), pcivendor); v.video = pciobj; @@ -272,10 +303,6 @@ void DeviceInfo::grabDevicesFromPciRoot(IORegistryEntry *pciRoot) { // To distinguish the devices we use audio card presence as a marker. DBGLOG("dev", "marking audio device as HDEF at %s", safeString(v.audio->getName())); audioBuiltinAnalog = v.audio; - - if (v.video && v.vendor == WIOKit::VendorID::ATIAMD) { - videoBuiltin = v.video; - } } } }