Contribute
Register

[Guide] Dell XPS 13 9360 on MacOS Sierra 10.12.x - LTS (Long-Term Support) Guide

Status
Not open for further replies.
Activity monitor works fine for me but I lost brightness control (as reported on the mention thread). Is yours working @bozma88 ?

But if I remember right, on my other laptop (10.12.4 beta 4), activity monitor started crashing while trying to check the Energy tab and wont start at all. While I can't confirm thats the trigger .. Just be aware :)
 
Last edited:
Activity monitor works fine for me but I lost brightness control (as reported on the mention thread). Is yours working @bozma88 ?

But if I remember right, on my other laptop (10.12.4 beta 4), activity monitor started crashing while trying to check the Energy tab and wont start at all. While I can't confirm thats the trigger .. Just be aware :)

Use Syscl's injector instead of Rehabman's backlight kext. Link >here<.
 
Use Syscl's injector instead of Rehabman's backlight kext. Link >here<.

Yes, this is my AppleBacklightInjector method, which I created years ago...
https://www.tonymacx86.com/threads/...een-using-patched-applebacklight-kext.121031/

Keep in mind it also requires specific code in ACPI to initialize PWMMax to what OS X/macOS expects. See SSDT-PNLF.dsl (and SSDT-Config.dsl) at my hotpatch github: https://github.com/RehabMan/OS-X-Clover-Laptop-Config/tree/master/hotpatch.
 
Yes, this is my AppleBacklightInjector method, which I created years ago...
https://www.tonymacx86.com/threads/...een-using-patched-applebacklight-kext.121031/

Keep in mind it also requires specific code in ACPI to initialize PWMMax to what OS X/macOS expects. See SSDT-PNLF.dsl (and SSDT-Config.dsl) at my hotpatch github: https://github.com/RehabMan/OS-X-Clover-Laptop-Config/tree/master/hotpatch.
Luckily it works OOB wothout ACPI patches. Brightness transitions are smooth, brightness range is amazing, can go as low as a few nits, way lower than on Windows.
 
Luckily it works OOB wothout ACPI patches.

Not likely.
The only way(s) that could happen is if:
- PWMMax as initialized by BIOS is the same (or at least very close) to the value assumed by macOS. You should verify.
OR
- PWMMax is initialized by the graphics drivers. For Ivy, Sandy, Haswell, the graphics drivers only initialize PWMMax on wake from sleep, so often full backlight levels are not correct until after a sleep wake cycle. Again... you should verify.

Brightness transitions are smooth

Surprised you are getting smooth transitions with the brightness keys (you should verify)

brightness range is amazing,

Verify PWMMax. Verify brigthness range is the same both before and after sleep.

can go as low as a few nits, way lower than on Windows.

Levels can be changed in the injector plist...
 
Not likely.
The only way(s) that could happen is if:
- PWMMax as initialized by BIOS is the same (or at least very close) to the value assumed by macOS. You should verify.
OR
- PWMMax is initialized by the graphics drivers. For Ivy, Sandy, Haswell, the graphics drivers only initialize PWMMax on wake from sleep, so often full backlight levels are not correct until after a sleep wake cycle. Again... you should verify.



Surprised you are getting smooth transitions with the brightness keys (you should verify)



Verify PWMMax. Verify brigthness range is the same both before and after sleep.



Levels can be changed in the injector plist...

Verified a few things:

1) Brightness range is the same (~1%-100%) before and after sleep. Will test with a hardware cd/m2 sensor tomorrow, just to be sure.
2) Brightness level transition is smooth like on MacBooks.
3) ACPI patch only consists of a basic PNLF device injection.
4) No SSDT injection, as we are not using your patched Backlight kext, we are only injecting/sideloading a new panel id.

How to verify PWMMax?
 
Verified a few things:

1) Brightness range is the same (~1%-100%) before and after sleep. Will test with a hardware cd/m2 sensor tomorrow, just to be sure.
2) Brightness level transition is smooth like on MacBooks.
3) ACPI patch only consists of a basic PNLF device injection.
4) No SSDT injection, as we are not using your patched Backlight kext, we are only injecting/sideloading a new panel id.

How to verify PWMMax?

I think you're using ig-platform-id 0x19160000. PWMMax assumed by that platform-id is 0x056c (1388).

It corresponds well to the brightness data in the AppleBacklightInjector.kext that you're using:
Code:
ProBook-4540s:Downloads Admin$ echo -n ABEAAAAYACcAOgBSAHEAlgDEAPwBQAGTAfYCbgL+A6oEeAVs|base64 --decode|xxd
00000000: 0011 0000 0018 0027 003a 0052 0071 0096  .......'.:.R.q..
00000010: 00c4 00fc 0140 0193 01f6 026e 02fe 03aa  [email protected]....
00000020: 0478 056c                                .x.l

So two possibilities (since you're claiming it is working well):
- The new drivers for SKL graphics initialize the PWMMax... (as I noted before, typically this was not the case)
OR
- Your BIOS also happens to use 0x56c for PWMMax initialization

There are various ways to find out PWMMax. Here are a couple:
- use RWEverything in Windows (involves tracking down the value in SystemMemory... I describe it in one of my older brightness guides, or you can read the ACPI code below to understand how to get from the BAR1 address to LEVX)
- use ACPIDebug to print the value out...

Refer to SSDT-PNLF.dsl for how it is addressed in ACPI code... For Haswell/Skylake/KabyLake it is the MSW of LEVX from below:
Code:
        OperationRegion(RMB1, SystemMemory, \_SB.PCI0.IGPU.BAR1 & ~0xF, 0xe1184)
        Field(RMB1, AnyAcc, Lock, Preserve)
        {
            Offset(0x48250),
            LEV2, 32,
            LEVL, 32,
            Offset(0x70040),
            P0BL, 32,
            Offset(0xc8250),
            LEVW, 32,
            LEVX, 32,
            Offset(0xe1180),
            PCHL, 32,
        }

IGPU.BAR1 is defined in SSDT-IGPU.dsl
Code:
    Scope(_SB.PCI0.IGPU)
    {
        // need the device-id from PCI_config to inject correct properties
        OperationRegion(RMP1, PCI_Config, 0, 0x14)
        Field(RMP1, AnyAcc, NoLock, Preserve)
        {
            Offset(0x02), GDID,16,
            Offset(0x10), BAR1,32,
        }

Code from SSDT-PNLF.dsl:
Code:
        Method(_INI)
        {
...
                // otherwise... Assume Haswell/Broadwell/Skylake
                Local2 = \RMCF.LMAX
                if (Ones == \RMCF.LMAX) { Local2 = HASWELL_PWMMAX }

                // This 0xC value comes from looking what OS X initializes this\n
                // register to after display sleep (using ACPIDebug/ACPIPoller)\n
                LEVW = 0xC0000000

                // change/scale only if different than current...
                Local1 = LEVX >> 16
                If (!Local1) { Local1 = Local2 }
                If (Local2 != Local1)
                {
                    // set new backlight PWMAX but retain current backlight level by scaling
                    Local0 = (((LEVX & 0xFFFF) * Local2) / Local1) | (Local2 << 16)
                    //REVIEW: wait for vblank before setting new PWM config
                    //For (Local7 = P0BL, P0BL == Local7, ) { }
                    LEVX = Local0
                }
...

If you wanted to only print out the value:
Code:
        Method(_INI)
        {
             \RMDT.P2("LEVX is", LEVX)
        }

Hopefully that is enough for you to put together the puzzle...
 
I think you're using ig-platform-id 0x19160000. PWMMax assumed by that platform-id is 0x056c (1388).

It corresponds well to the brightness data in the AppleBacklightInjector.kext that you're using:
Code:
ProBook-4540s:Downloads Admin$ echo -n ABEAAAAYACcAOgBSAHEAlgDEAPwBQAGTAfYCbgL+A6oEeAVs|base64 --decode|xxd
00000000: 0011 0000 0018 0027 003a 0052 0071 0096  .......'.:.R.q..
00000010: 00c4 00fc 0140 0193 01f6 026e 02fe 03aa  [email protected]....
00000020: 0478 056c                                .x.l

So two possibilities (since you're claiming it is working well):
- The new drivers for SKL graphics initialize the PWMMax... (as I noted before, typically this was not the case)
OR
- Your BIOS also happens to use 0x56c for PWMMax initialization

There are various ways to find out PWMMax. Here are a couple:
- use RWEverything in Windows (involves tracking down the value in SystemMemory... I describe it in one of my older brightness guides, or you can read the ACPI code below to understand how to get from the BAR1 address to LEVX)
- use ACPIDebug to print the value out...

Refer to SSDT-PNLF.dsl for how it is addressed in ACPI code... For Haswell/Skylake/KabyLake it is the MSW of LEVX from below:
Code:
        OperationRegion(RMB1, SystemMemory, \_SB.PCI0.IGPU.BAR1 & ~0xF, 0xe1184)
        Field(RMB1, AnyAcc, Lock, Preserve)
        {
            Offset(0x48250),
            LEV2, 32,
            LEVL, 32,
            Offset(0x70040),
            P0BL, 32,
            Offset(0xc8250),
            LEVW, 32,
            LEVX, 32,
            Offset(0xe1180),
            PCHL, 32,
        }

IGPU.BAR1 is defined in SSDT-IGPU.dsl
Code:
    Scope(_SB.PCI0.IGPU)
    {
        // need the device-id from PCI_config to inject correct properties
        OperationRegion(RMP1, PCI_Config, 0, 0x14)
        Field(RMP1, AnyAcc, NoLock, Preserve)
        {
            Offset(0x02), GDID,16,
            Offset(0x10), BAR1,32,
        }

Code from SSDT-PNLF.dsl:
Code:
        Method(_INI)
        {
...
                // otherwise... Assume Haswell/Broadwell/Skylake
                Local2 = \RMCF.LMAX
                if (Ones == \RMCF.LMAX) { Local2 = HASWELL_PWMMAX }

                // This 0xC value comes from looking what OS X initializes this\n
                // register to after display sleep (using ACPIDebug/ACPIPoller)\n
                LEVW = 0xC0000000

                // change/scale only if different than current...
                Local1 = LEVX >> 16
                If (!Local1) { Local1 = Local2 }
                If (Local2 != Local1)
                {
                    // set new backlight PWMAX but retain current backlight level by scaling
                    Local0 = (((LEVX & 0xFFFF) * Local2) / Local1) | (Local2 << 16)
                    //REVIEW: wait for vblank before setting new PWM config
                    //For (Local7 = P0BL, P0BL == Local7, ) { }
                    LEVX = Local0
                }
...

If you wanted to only print out the value:
Code:
        Method(_INI)
        {
             \RMDT.P2("LEVX is", LEVX)
        }

Hopefully that is enough for you to put together the puzzle...


I'm proceeding with incremental steps.
First of all, I can already confirm you that the injected plist values are honoured immediately at boot. No sleep/wake cycle required. The info.plist values are read and the highest value is applied at boot.
As a proof, I edited the steps array, putting a very low value on the last 8 steps, and the machine booted with a very low backlight setting (even though OSD indicates 100% brightness). So, it seems that setting proper steps is trivial and the graphics driver reads these plist values at boot (1st possibility you mentioned).

Screen Shot 2017-03-29 at 01.54.07.png

Now I have to figure out if 0x56c is actually the highest PWM value of my panel.
My guess it is, since at 100% it's as bright on macOS as it is on Windows.

As a side note, are you aware of this backdoor kext I am attaching to the message? When installed, you have access to all HW low-level registers, just like R-W Everything on Windows. I used this kext to confirm that PCIe ASPM is natively working on this build (and it is!).
 

Attachments

  • DirectHW.kext.zip
    11.8 KB · Views: 69
I'm proceeding with incremental steps.
First of all, I can already confirm you that the injected plist values are honoured immediately at boot. No sleep/wake cycle required. The info.plist values are read and the highest value is applied at boot.

The problem is if PWMMax is not set correctly, the brightness levels may be off.
If it is larger than expected, you will not reach 100% brightness. The degree to which you can detect the problem, is dependent on the degree to which PWMMax is larger than the expected value.
If it is smaller than expected, the display will go dark above a certain brightness level (quite easy to detect).

So, it seems that setting proper steps is trivial and the graphics driver reads these plist values at boot (1st possibility you mentioned).

As noted above, PWMMax setting has nothing to do with the data in AppleBacklight[Injector].kext.

Now I have to figure out if 0x56c is actually the highest PWM value of my panel.

It is possible to set PWMMax to anything. Then the current backlight level (LSW of LEVX) is set as a percentage of that max...
I have no idea on why certain values for PWMMax are used.
We already know that various BIOS will use different values on similar hardware.
And we already know that OS X/macOS uses different values depending on ig-platform-id and graphics platform.

My guess it is, since at 100% it's as bright on macOS as it is on Windows.

Sounds like you're using subjective observations.
It would be great to confirm that the SKL graphics drivers set PWMMax at boot instead of relying on the firmware to do it.

As a side note, are you aware of this backdoor kext I am attaching to the message? When installed, you have access to all HW low-level registers, just like R-W Everything on Windows. I used this kext to confirm that PCIe ASPM is natively working on this build (and it is!).

I have never used DirectHW.kext, but it isn't much of a "backdoor". All hardware registers are available at the kernel level... there is no protection there.
 
Last edited:
Status
Not open for further replies.
Back
Top