Bug 98677

Summary: [NVAC] iMac9,1 effective backlight brightness range changes after S3
Product: xorg Reporter: Jeffery Miller <jefferym>
Component: Driver/nouveauAssignee: Nouveau Project <nouveau>
Status: NEW --- QA Contact: Xorg Project Team <xorg-team>
Severity: normal    
Priority: medium    
Version: unspecified   
Hardware: x86-64 (AMD64)   
OS: Linux (All)   
Whiteboard:
i915 platform: i915 features:
Attachments:
Description Flags
dmesg output after the resume with some nouveau trace options
none
ACPI dump of the system
none
dmidecode binary output
none
lspci output for the machine
none
VBIOS retrieved with nvagetbios
none
mmiotrace of nvidia driver performing brightness changes
none
Force NV50_PDISP_SOR_PWM_DIV when setting brightness for the iMac9,1 subvendor none

Description Jeffery Miller 2016-11-10 17:33:18 UTC
Created attachment 127900 [details]
dmesg output after the resume with some nouveau trace options

I have an iMac 9,1 where the behaviour of the backlight of the built in screen works differently between the first boot and after a suspend to ram.
It appears to be darker at lower values before a suspend than after.

kernel: 4.8.6-300.fc25.x86_64
lspci adapter: VGA adapter NVIDIA Corporation C79 [GeForce 9400] [10de:0867]
DMI: Apple Inc. iMac9,1/Mac-F2218EA9
I've been booting in EFI mode.
I do not know of a regression. I've only tried 4.4 and this 4.8 kernels.
I've observed this with X running but I've been testing this without starting a graphical environment.

I've been testing by setting setting backlight values via the /sys/backlight/nv_backlight/brightness interface.
Before a suspend I can set values such as 40, 70, 100 and the brightness seems to be reasonable on the screen.

I then suspend to ram via the /sys/power/state interface.
Upon resuming the backlight appears to be at 100 percent. If I set the brightness to values such as 30 and 60 the screen remains dark. It is barely visible as a flicker at 70. At 100 it is visible.

I've observed that the value of NV50_PDISP_SOR_PWM_DIV (0x0061c080) is 0x1 after a boot but is set to 0x84 after a resume.
It appears there's an init script in the bios dump which sets it to the value of 0x84. I have confirmed if I use the nouveau option nouveau.config=NvForcePost=1 that the behavior after booting is the same as after a resume. The value of 0x61c080 is 0x84.

If I `nvapoke 0x061c080 0x1` after a resume the backlight seems to work fairly well. I created patch to test this. I expect it isn't the proper solution.

I'm attaching the dmesg which includes a resume with the nouveau driver.
I'll also attach the vbios dump, acpidump, dmidecode, lspci, 

I've gathered an mmiotrace of the binary driver as it sets a few brightness values as well.
Comment 1 Jeffery Miller 2016-11-10 17:35:27 UTC
Created attachment 127901 [details]
ACPI dump of the system

acpidump of the system
Comment 2 Jeffery Miller 2016-11-10 17:35:48 UTC
Created attachment 127902 [details]
dmidecode binary output
Comment 3 Jeffery Miller 2016-11-10 17:36:18 UTC
Created attachment 127903 [details]
lspci output for the machine
Comment 4 Jeffery Miller 2016-11-10 17:37:10 UTC
Created attachment 127904 [details]
VBIOS retrieved with nvagetbios
Comment 5 Ilia Mirkin 2016-11-10 17:42:07 UTC
An observation is that the nouveau code in nva3_get/set_intensity takes the existing divider into account. However we only use that for nva3/5/8/f, not nvaa/nvac.

Could you try changing nouveau_backlight.c:nv50_backlight_init to use nva3_bl_ops for your chipset and seeing whether that fixes everything?

(Let me know if you're not sure how to do that, and I can put a patch together.)
Comment 6 Jeffery Miller 2016-11-10 17:55:02 UTC
Created attachment 127905 [details]
mmiotrace of nvidia driver performing brightness changes

mmio trace of the nvidia driver 340.96
I set the brightness with the nvidia-settings command following the steps:

   modprobe nvidia-uvm
   Xorg &
   DISPLAY=:0 nvidia-settings -n -a BacklightBrightness=50
   DISPLAY=:0 nvidia-settings -n -a BacklightBrightness=70
   DISPLAY=:0 nvidia-settings -n -a BacklightBrightness=100
Comment 7 Jeffery Miller 2016-11-10 17:55:41 UTC
I will patch and attempt to use the nva routines and report back.
Comment 8 Jeffery Miller 2016-11-10 21:23:30 UTC
I patched as suggested having it use the nva3_bl_ops. The backlight remained dark in this case. I was able to get the backlight to turn on by setting values with nvapoke to match values I had seen earlier:

nvapoke 0x0061c080 0x1
nvapoke 0x0061c084 0x80000401

I noticed from the mmiotrace of the binary driver that it seems to set these two registers when the brightness changes.
I'm away from the machine at the moment to post the details that seemed relevant to me. 

I am not sure which registers might be important to check before and after. 

I'll look at the trace again and pop into it for some questions
Comment 9 Jeffery Miller 2016-11-11 22:40:01 UTC
I tried a few more brightness tests with the nvidia binary blob. There's a similar mmiotrace already attached.

I've observed that the nvidia driver sets the values of 
I observed that the nvidia driver sets both 0x0061c080 and 0x0061c084 on each brightness change.
It always sets 0x0061c080 to 0x17 and 61c084 with the following
percent values:

% setting    |  0x0061c084 poke
---
21              0x800000d8
22              0x800000e2
30              0x80000134
50              0x80000201
70              0x800002ce
78              0x80000320
100             0x80000401

I noticed that if I change value to 21% (d8) or below the screen is dark/black. It then stays dark at levels such as 30%, 50%, and such that worked previously. If I set it to 78% or 100% the screen will appear again. Once it reappears the 50%, 30% values work as they did previously.

I patched the nouveau backlight code to always set the PWM_DIV to 0x17. The nouveau driver then behaved the same for the various percent values mentioned above. It also had the off at low requiring a high % to have it show again.

I reverted to my original patch which would always set the DIV to 0x1 on each change. This makes it consistent with the fresh boot value. This has the side effect that after a post (and a resume from suspend) the value is always the same.
The visible range is wider for the 0x1 case. The screen doesn't turn fully dark until around 14%. Additionally it would return to the previous value without having to jump all the way up to a high value. It could go from the 14% off case back to 50% and the screen had the same brightness. I am observing the brightness with my eye.
The percent to DUTY value being set to 0x61c084 is similar in each driver. Nouveau sets 0x401 for 100%, 0x200 for 50%.
Comment 10 Jeffery Miller 2016-11-11 22:45:03 UTC
Created attachment 127925 [details] [review]
Force NV50_PDISP_SOR_PWM_DIV when setting brightness for the iMac9,1 subvendor

This patch always sets the div to 0x1 for the device on this machine. It allows consistent behavior between the first boot of the system and after a resume.

I apply it on each backlight change mimicking the nvidia blob's behavior in this case. However, the nvidia blob sets the value to 0x17 in my observations.
Comment 11 Jeffery Miller 2016-11-12 01:22:48 UTC
I was prepared to implement some additions to adjust the values to make the percentage values representative of the output.
I realized there is an apple_bl acpi backlight driver that may be applicable to this problem.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.