Skip to content

Commit

Permalink
fix: Use old PWM brightness control logic on Raven
Browse files Browse the repository at this point in the history
Closes #236
Temporary workaround. FIXME!
  • Loading branch information
VisualEhrmanntraut committed Oct 8, 2024
1 parent 86f2c96 commit 0a0cdc4
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 18 deletions.
54 changes: 41 additions & 13 deletions NootedRed/X6000FB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ bool X6000FB::processKext(KernelPatcher &patcher, size_t id, mach_vm_address_t s
PANIC_COND(!solveRequest.solve(patcher, id, slide, size), "X6000FB", "Failed to resolve CAIL_ASIC_CAPS_TABLE");

if (NRed::callback->attributes.isBacklightEnabled()) {
if (NRed::callback->attributes.isBigSurAndLater() && NRed::callback->attributes.isRaven()) {
SolveRequestPlus solveRequest {"_dce_driver_set_backlight", this->orgDceDriverSetBacklight,
kDceDriverSetBacklightPattern, kDceDriverSetBacklightPatternMask};
PANIC_COND(!solveRequest.solve(patcher, id, slide, size), "X6000FB",
"Failed to resolve dce_driver_set_backlight");
}
if (NRed::callback->attributes.isSonoma1404AndLater()) {
SolveRequestPlus solveRequest {"_dc_link_set_backlight_level", this->orgDcLinkSetBacklightLevel,
kDcLinkSetBacklightLevelPattern14_4};
Expand Down Expand Up @@ -145,6 +151,19 @@ bool X6000FB::processKext(KernelPatcher &patcher, size_t id, mach_vm_address_t s
}

if (NRed::callback->attributes.isBacklightEnabled()) {
if (NRed::callback->attributes.isBigSurAndLater() && NRed::callback->attributes.isRaven()) {
if (NRed::callback->attributes.isSonoma1404AndLater()) {
RouteRequestPlus request = {"_dce_panel_cntl_hw_init", wrapDcePanelCntlHwInit,
this->orgDcePanelCntlHwInit, kDcePanelCntlHwInitPattern14_4};
PANIC_COND(!request.route(patcher, id, slide, size), "X6000FB",
"Failed to route dce_panel_cntl_hw_init (14.4+)");
} else {
RouteRequestPlus request = {"_dce_panel_cntl_hw_init", wrapDcePanelCntlHwInit,
this->orgDcePanelCntlHwInit, kDcePanelCntlHwInitPattern};
PANIC_COND(!request.route(patcher, id, slide, size), "X6000FB",
"Failed to route dce_panel_cntl_hw_init");
}
}
RouteRequestPlus requests[] = {
{"_link_create", wrapLinkCreate, this->orgLinkCreate, kLinkCreatePattern, kLinkCreateMask},
{"__ZN35AMDRadeonX6000_AmdRadeonFramebuffer25setAttributeForConnectionEijm",
Expand Down Expand Up @@ -354,7 +373,7 @@ bool X6000FB::OnAppleBacklightDisplayLoad(void *, void *, IOService *newService,
}

void X6000FB::registerDispMaxBrightnessNotif() {
if (callback->dispNotif) { return; }
if (callback->dispNotif != nullptr) { return; }

auto *matching = IOService::serviceMatching("AppleBacklightDisplay");
if (matching == nullptr) {
Expand All @@ -374,27 +393,31 @@ IOReturn X6000FB::wrapSetAttributeForConnection(IOService *framebuffer, IOIndex
connectIndex, attribute, value);
if (attribute != FbAttributeBacklight) { return ret; }

if (callback->maxPwmBacklightLvl == 0) { return kIOReturnSuccess; }
if (callback->embeddedPanelLink == nullptr) { return kIOReturnNoDevice; }

// Set the backlight
callback->curPwmBacklightLvl = static_cast<UInt32>(value);

if (callback->panelCntlPtr == nullptr || callback->embeddedPanelLink == nullptr) { return kIOReturnNoDevice; }

if (callback->maxPwmBacklightLvl == 0) { return kIOReturnInternalError; }

UInt32 percentage = callback->curPwmBacklightLvl * 100 / callback->maxPwmBacklightLvl;

// AMDGPU doesn't use AUX on HDR/SDR displays that can use it. Why?
if (callback->supportsAUX) {
// TODO: Obtain the actual max brightness for the screen
UInt32 auxValue = (callback->maxOLED * percentage) / 100;
// dc_link_set_backlight_level_nits doesn't print the new backlight level, so we'll do it
DBGLOG("X6000FB", "setAttributeForConnection: New AUX brightness: %d millinits (%d nits)", auxValue,
(auxValue / 1000));
if (callback->orgDcLinkSetBacklightLevelNits(callback->embeddedPanelLink, true, auxValue, 15000)) {
return kIOReturnSuccess;
}
DBGLOG("X6000FB", "%s: New AUX brightness: %d millinits (%d nits)", __FUNCTION__, auxValue, (auxValue / 1000));
callback->orgDcLinkSetBacklightLevelNits(callback->embeddedPanelLink, true, auxValue, 15000);
} else if (NRed::callback->attributes.isRaven() && NRed::callback->attributes.isBigSurAndLater()) {
// XX: Use the old brightness logic for now on Raven
// until I can find out the actual problem with DMCU.
UInt32 pwmValue = percentage >= 100 ? 0x1FF00 : ((percentage * 0xFF) / 100) << 8U;
DBGLOG("X6000FB", "%s: New PWM brightness: 0x%X", __FUNCTION__, pwmValue);
callback->orgDceDriverSetBacklight(callback->panelCntlPtr, pwmValue);
return kIOReturnSuccess;
} else {
UInt32 pwmValue = (percentage * 0xFFFF) / 100;
DBGLOG("X6000FB", "setAttributeForConnection: New PWM brightness: 0x%X", pwmValue);

DBGLOG("X6000FB", "%s: New PWM brightness: 0x%X", __FUNCTION__, pwmValue);
if (callback->orgDcLinkSetBacklightLevel(callback->embeddedPanelLink, pwmValue, 0)) { return kIOReturnSuccess; }
}

Expand Down Expand Up @@ -459,6 +482,11 @@ void X6000FB::wrapDpReceiverPowerCtrl(void *link, bool power_on) {
IOSleep(250); // Link needs a bit of delay to change power state
}

UInt32 X6000FB::wrapDcePanelCntlHwInit(void *panelCntl) {
callback->panelCntlPtr = panelCntl;
return FunctionCast(wrapDcePanelCntlHwInit, callback->orgDcePanelCntlHwInit)(panelCntl);
}

void *X6000FB::wrapLinkCreate(void *data) {
void *ret = FunctionCast(wrapLinkCreate, callback->orgLinkCreate)(data);

Expand All @@ -480,7 +508,7 @@ void *X6000FB::wrapLinkCreate(void *data) {
SYSLOG("X6000FB", "REPORT THIS TO THE DEVELOPERS AS SOON AS POSSIBLE!!!!");
}
callback->embeddedPanelLink = ret;
if ((callback->dcLinkCapsField.get(ret) & DC_DPCD_EXT_CAPS_OLED) != 0) { callback->supportsAUX = true; }
callback->supportsAUX = (callback->dcLinkCapsField.get(ret) & DC_DPCD_EXT_CAPS_OLED) != 0;

DBGLOG("X6000FB", "Will use %s for display brightness control.", callback->supportsAUX ? "AUX" : "DMCU");
}
Expand Down
24 changes: 19 additions & 5 deletions NootedRed/X6000FB.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <IOKit/graphics/IOGraphicsTypes.h>

using t_MessageAccelerator = IOReturn (*)(void *that, UInt32 requestType, void *arg2, void *arg3, void *arg4);
using t_DceDriverSetBacklight = void (*)(void *panelCntl, UInt32 backlightPwm);
using t_DcLinkSetBacklightLevel = bool (*)(void *link, UInt32 backlightPwm, UInt32 frameRamp);
using t_DcLinkSetBacklightLevelNits = bool (*)(void *link, bool isHDR, UInt32 backlightMillinits,
UInt32 transitionTimeMs);
Expand All @@ -25,7 +26,7 @@ class X6000FB {
ObjectField<UInt8> dcLinkCapsField {};
bool fixedVBIOS {false};

UInt32 curPwmBacklightLvl {0}, maxPwmBacklightLvl {0xFF};
UInt32 curPwmBacklightLvl {0}, maxPwmBacklightLvl {0xFFFF};
UInt32 maxOLED {1000 * 512};
IONotifier *dispNotif {nullptr};
void *embeddedPanelLink {nullptr};
Expand All @@ -39,6 +40,9 @@ class X6000FB {
t_MessageAccelerator orgMessageAccelerator {nullptr};
mach_vm_address_t orgControllerPowerUp {0};
mach_vm_address_t orgDpReceiverPowerCtrl {0};
t_DceDriverSetBacklight orgDceDriverSetBacklight {nullptr};
mach_vm_address_t orgDcePanelCntlHwInit {0};
void *panelCntlPtr {nullptr};
mach_vm_address_t orgLinkCreate {0};
t_DcLinkSetBacklightLevel orgDcLinkSetBacklightLevel {0};
t_DcLinkSetBacklightLevelNits orgDcLinkSetBacklightLevelNits {0};
Expand All @@ -58,6 +62,7 @@ class X6000FB {
static void wrapIRQMGRWriteRegister(void *ctx, UInt64 index, UInt32 value);
static UInt32 wrapControllerPowerUp(void *that);
static void wrapDpReceiverPowerCtrl(void *link, bool power_on);
static UInt32 wrapDcePanelCntlHwInit(void *panelCntl);
static void *wrapLinkCreate(void *data);
static bool wrapInitWithPciInfo(void *that, void *pciDevice);
static void wrapDoGPUPanic(char const *fmt, ...);
Expand All @@ -69,10 +74,6 @@ class X6000FB {
static const UInt8 kCailAsicCapsTablePattern[] = {0x6E, 0x00, 0x00, 0x00, 0x98, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00};

static const UInt8 kDceDriverSetBacklight[] = {0x55, 0x48, 0x89, 0xE5, 0x41, 0x57, 0x41, 0x56, 0x41, 0x55, 0x41, 0x54,
0x53, 0x50, 0x41, 0x89, 0xF7, 0x49, 0x89, 0xFE, 0x31, 0xC0, 0x4C, 0x8D, 0x65, 0xD0, 0x41, 0x89, 0x04, 0x24, 0x4C,
0x8D, 0x6D, 0xD4, 0x41, 0x89, 0x45, 0x00, 0x48, 0x8B, 0x7F, 0x08, 0x49, 0x8B, 0x46, 0x28, 0x8B, 0x70, 0x10};

static const UInt8 kPopulateVramInfoPattern[] = {0x55, 0x48, 0x89, 0xE5, 0x41, 0x57, 0x41, 0x56, 0x53, 0x48, 0x81, 0xEC,
0x08, 0x01, 0x00, 0x00, 0x40, 0x89, 0xF0, 0x40, 0x89, 0xF0, 0x4C, 0x8D, 0xBD, 0xE0, 0xFE, 0xFF, 0xFF};
static const UInt8 kPopulateVramInfoMask[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
Expand Down Expand Up @@ -100,6 +101,19 @@ static const UInt8 kDpReceiverPowerCtrl[] = {0x55, 0x48, 0x89, 0xE5, 0x41, 0x57,
static const UInt8 kDpReceiverPowerCtrl14_4[] = {0x55, 0x48, 0x89, 0xE5, 0x41, 0x57, 0x41, 0x56, 0x41, 0x54, 0x53, 0x48,
0x83, 0xEC, 0x10, 0x41, 0x89, 0xF7, 0xB0, 0x02, 0x44, 0x28, 0xF8};

static const UInt8 kDcePanelCntlHwInitPattern[] = {0x55, 0x48, 0x89, 0xE5, 0x41, 0x57, 0x41, 0x56, 0x41, 0x55, 0x41,
0x54, 0x53, 0x50, 0x49, 0x89, 0xFD, 0x4C, 0x8D, 0x45, 0xD4, 0x41, 0xC7, 0x00, 0x00, 0x00, 0x00, 0x00};
static const UInt8 kDcePanelCntlHwInitPattern14_4[] = {0x55, 0x48, 0x89, 0xE5, 0x41, 0x57, 0x41, 0x56, 0x41, 0x54, 0x53,
0x48, 0x83, 0xEC, 0x10, 0x48, 0x89, 0xFB, 0x4C, 0x8D, 0x45, 0xDC, 0x41, 0xC7, 0x00, 0x00, 0x00, 0x00, 0x00};

static const UInt8 kDceDriverSetBacklightPattern[] = {0x55, 0x48, 0x89, 0xE5, 0x41, 0x57, 0x41, 0x56, 0x41, 0x55, 0x41,
0x54, 0x53, 0x50, 0x41, 0x89, 0xF0, 0x40, 0x89, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x8B, 0x7F, 0x08, 0x40, 0x8B, 0x40, 0x28, 0x8B, 0x70, 0x10};
static const UInt8 kDceDriverSetBacklightPatternMask[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF,
0xFF};

static const UInt8 kLinkCreatePattern[] = {0x55, 0x48, 0x89, 0xE5, 0x41, 0x57, 0x41, 0x56, 0x41, 0x55, 0x41, 0x54, 0x53,
0x48, 0x81, 0xEC, 0x00, 0x03, 0x00, 0x00, 0x49, 0x89, 0xFD, 0x48, 0x8B, 0x05, 0x00, 0x00, 0x00, 0x00, 0x48, 0x8B,
0x00, 0x48, 0x00, 0x00, 0x00, 0xBF, 0x00, 0x00, 0x00, 0x00, 0xE8, 0x00, 0x00, 0x00, 0x00};
Expand Down

0 comments on commit 0a0cdc4

Please sign in to comment.