Bug 190186

Summary: [patch] i915 driver: enable opregion handling
Product: Base System Reporter: Henry Hu <henry.hu.sh>
Component: kernAssignee: freebsd-bugs (Nobody) <bugs>
Status: Closed FIXED    
Severity: Affects Only Me CC: adrian, emaste, fidaj, jan.kokemueller, jhb
Priority: Normal Keywords: i915, patch
Version: UnspecifiedFlags: bugmeister: mfc-stable10?
bugmeister: mfc-stable9?
bugmeister: mfc-stable8?
Hardware: Any   
OS: Any   
See Also: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=193500
Attachments:
Description Flags
file.diff none

Description Henry Hu 2014-05-24 21:50:00 UTC
My laptop is ASUS UX51VZ which has an integrated graphics adapter Intel HD4000 (IvyBridge). I'm using the KMS driver with new Xorg.
Currently, opregion handling in i915 driver is disabled. In intel_opregion.c, the relevant code is surrounded by #ifdef CONFIG_ACPI which only works for linux. Related interrupt handling is also disabled.
As a result, opregion support is disabled, and status reported by ACPI video extension is wrong (for example, hw.acpi.video.lcd0.active is always 0). Brightness keys on the keyboard do not work, and setting brightness through ACPI video extension sysctls (like hw.acpi.video.lcd0.brightness) has no effect.

Fix: The attached patch enables OpRegion handling code. It also enables opregion-related interrupts.
The Linux-specific parts are rewritten for FreeBSD. The logic is the same.
The video event handler is still disabled because it does not have any functionality. 
After applying the patch, both the brightness keys and the ACPI video extension sysctls work correctly.

Patch attached with submission follows:
How-To-Repeat: Try FreeBSD 11-CURRENT on a recent intel laptop, and change brightness by pressing the Brightness keys on the keyboard, or adjust brightness by hw.acpi.video.lcd0.brightness.
Comment 1 Ivan Klymenko 2014-05-24 22:33:01 UTC
Cool! Thanks. It works for my laptop HP ProBook 4530s
Comment 2 Adrian Chadd freebsd_committer freebsd_triage 2014-06-06 23:53:18 UTC
It didn't do anything for me. Lenovo Thinkpad X230; Ivy Bridge CPU. But yes, it's now showing up as lcd0.active=1.

If I set hw.acpi.video.lcd0.brightness to something other than 99, then the value is taken but the brightness doesn't change. If I use the keyboard to change the LCD  brightness - up or down - it resets the value to 99.
Comment 3 Adrian Chadd freebsd_committer freebsd_triage 2014-06-06 23:59:01 UTC
So if I then do this:

# cd /usr/ports/sysutils/acpi_call && make install clean 
# rehash 
# kldload acpi_ibm 
# kldload acpi_call 
# acpi_call -p '\VBRC' -i 14

.. then if I use sysctl hw.acpi.video.lcd0.brightness=X, things work fine. I can even set it to 99 and it works fine. The buttons don't work fine - they only vary the brightness a couple of values around whatever I set it.

So I wonder what else is problematic with this thing! Any ideas/suggestions?
Comment 4 Henry Hu 2014-06-07 00:09:05 UTC
(In reply to Adrian Chadd from comment #3)
> So if I then do this:
> 
> # cd /usr/ports/sysutils/acpi_call && make install clean 
> # rehash 
> # kldload acpi_ibm 
> # kldload acpi_call 
> # acpi_call -p '\VBRC' -i 14
> 
> .. then if I use sysctl hw.acpi.video.lcd0.brightness=X, things work fine. I
> can even set it to 99 and it works fine. The buttons don't work fine - they
> only vary the brightness a couple of values around whatever I set it.
> 
> So I wonder what else is problematic with this thing! Any ideas/suggestions?

I don't have \VBRC in my ACPI DSDT. Maybe you can post your DSDT and we can have a look at it.
Comment 5 Adrian Chadd freebsd_committer freebsd_triage 2014-06-07 00:12:11 UTC
Absolutely!

http://people.freebsd.org/~adrian/laptop/lenovo_x230/


-a
Comment 6 Henry Hu 2014-06-07 01:11:45 UTC
(In reply to Adrian Chadd from comment #5)
> Absolutely!
> 
> http://people.freebsd.org/~adrian/laptop/lenovo_x230/
> 
> 
> -a

Have you tried 
acpi_call -p "\_SB.PCI0.VID.LCD0._BCM" -i <brightness>

And what's the value of
acpi_call -p "\VIGD"
acpi_call -p "\_SB.PCI0.VID.DRDY"

VBRC() calls SMI directly. I have no idea what it is doing inside SMI.

_SB.PCI0.VID.LCD0._BCM stores brightness in BRLV and calls _SB.PCI0.LPC.EC.BRNS() and UCMS(0x16). UCMS() calls SMI directly so I have no idea what it is doing. If _SB.PCI0.VID.DRDY is true, it calls _SB.PCI0.VID.AINT(). AINT() triggers an ASLE interrupt to set the brightness through the driver. I'm not sure what went wrong here.
Comment 7 Adrian Chadd freebsd_committer freebsd_triage 2014-06-07 01:41:26 UTC
root@sabrina:/home/adrian # acpi_call -p "\VIGD"
1
root@sabrina:/home/adrian # acpi_call -p "\_SB.PCI0.VID.DRDY"
1


and yes:

acpi_call -p "\_SB.PCI0.VID.LCD0._BCM" -i <x>

works, but unpredictably.

I can't go 5, then 99. I have to go 5, 10, 20, 30, 40, .. 99 or going straight to 99 doesn't work.
Comment 8 Henry Hu 2014-06-09 11:01:23 UTC
(In reply to Adrian Chadd from comment #7)
> root@sabrina:/home/adrian # acpi_call -p "\VIGD"
> 1
> root@sabrina:/home/adrian # acpi_call -p "\_SB.PCI0.VID.DRDY"
> 1
> 
> 
> and yes:
> 
> acpi_call -p "\_SB.PCI0.VID.LCD0._BCM" -i <x>
> 
> works, but unpredictably.
> 
> I can't go 5, then 99. I have to go 5, 10, 20, 30, 40, .. 99 or going
> straight to 99 doesn't work.

That's strange. Setting hw.acpi.video.lcd0.brightness should be the same as calling _BCM.
Have you tried calling _BCM without calling VBRC(14) first?

For the brightness levels, only the ones in hw.acpi.video.lcd0.levels are accepted, but I still have no idea why you can't change the brightness level directly.
Comment 9 Adrian Chadd freebsd_committer freebsd_triage 2014-06-14 23:57:06 UTC
ok lemme sit down and try it again.
Comment 10 Adrian Chadd freebsd_committer freebsd_triage 2014-08-24 22:31:08 UTC
Hm, I think I'm just going to commit this and then work out the issue with my laptop separately!
Comment 11 Adrian Chadd freebsd_committer freebsd_triage 2014-08-24 22:32:45 UTC
Sorry for letting this go too long - lemme re-test it.
Comment 12 commit-hook freebsd_committer freebsd_triage 2014-08-25 05:03:49 UTC
A commit references this bug:

Author: adrian
Date: Mon Aug 25 05:03:10 UTC 2014
New revision: 270516
URL: http://svnweb.freebsd.org/changeset/base/270516

Log:
  i915 driver - enable opregion handle; program CADL.

  add opregion handling for drm2 - which exposes some ACPI video configuration
  pieces that some Lenovo laptop models use to flesh out which video device
  to speak to.  This enables the brightness control in ACPI to work these models.

  The CADL bits are also important - it's used to figure out which ACPI
  events to hook the brightness buttons into.  It doesn't yet seem to work
  for me, but it does for the OP.

  Tested:

  * Lenovo X230 (mine)
  * OP: ASUS UX51VZ

  PR:	190186
  Submitted by:	Henry Hu <henry.hu.sh@gmail.com>
  Reviewed by:	dumbbell

Changes:
  head/sys/dev/drm2/i915/i915_drv.h
  head/sys/dev/drm2/i915/i915_irq.c
  head/sys/dev/drm2/i915/intel_opregion.c
Comment 13 Ivan Klymenko 2014-08-25 07:23:15 UTC
(In reply to commit-hook from comment #12)
> A commit references this bug:
> 
> Author: adrian
> Date: Mon Aug 25 05:03:10 UTC 2014
> New revision: 270516
> URL: http://svnweb.freebsd.org/changeset/base/270516
> 
> Log:
>   i915 driver - enable opregion handle; program CADL.
> 

Should we expect MFC for STABLE 10?
Comment 14 Adrian Chadd freebsd_committer freebsd_triage 2014-08-25 07:38:01 UTC
Maybe eventually! Someone else can do the MFC though!
Comment 15 Jan Kokemüller 2014-09-09 15:04:44 UTC
When I test the new i915 code (r270990 snapshot iso or backported to 10-stable, doesn't matter) on my gen4 Intel GPU (GMA 4500MHD), I'm getting reproducible interrupt storms from "irq16: uhci0" after loading the i915kms module. It does not matter if I start X or not. This looks very similar to the situation here:

https://lists.freebsd.org/pipermail/freebsd-hackers/2014-June/045369.html

Setting hw.drm.msi=0 in /boot/loader.conf doesn't help. One suspend/resume cycle makes the problem go away. When I revert commit r270516 (the opregion changes) the problem goes away, too. Then there is no irq16 at all in the output of "vmstat -i".

Some more info:

$ grep 'irq 16' /var/run/dmesg.boot
vgapci0: <VGA-compatible display> port 0x1800-0x1807 mem 0xf2400000-0xf27fffff,0xd0000000-0xdfffffff irq 16 at device 2.0 on pci0
uhci0: <Intel 82801I (ICH9) USB controller> port 0x1820-0x183f irq 16 at device 26.0 on pci0
sdhci_pci0: <JMicron JMB38X SD> mem 0xf2300400-0xf23004ff irq 16 at device 0.2 on pci2
pcib2: <ACPI PCI-PCI bridge> irq 16 at device 28.1 on pci0
pcib6: <ACPI PCI-PCI bridge> irq 16 at device 28.5 on pci0


pciconf -lvc for vgapci0:

vgapci0@pci0:0:2:0:     class=0x030000 card=0x213a17aa chip=0x2a428086 rev=0x07 hdr=0x00
    vendor     = 'Intel Corporation'
    device     = 'Mobile 4 Series Chipset Integrated Graphics Controller'
    class      = display
    subclass   = VGA
    cap 05[90] = MSI supports 1 message enabled with 1 message
    cap 01[d0] = powerspec 3  supports D0 D3  current D0


Should I open a new bug? Can somebody reproduce? Let me know if you need more logs.
Comment 16 Ed Maste freebsd_committer freebsd_triage 2014-09-09 15:13:04 UTC
Yes - please open a new bug for tracking.

I planned to MFC r270516 for 10.1 but will wait pending the resolution here.  FWIW the issue is not reproducible on my Thinkpad X220 w/ r270516 MFC'd.
Comment 17 Ed Maste freebsd_committer freebsd_triage 2014-09-09 15:14:19 UTC
Update status: opregion patch is committed to HEAD.
Comment 18 Jan Kokemüller 2014-09-09 17:34:05 UTC
I've opened a bug concerning the interrupt issue:

https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=193500
Comment 19 John Baldwin freebsd_committer freebsd_triage 2015-03-13 19:51:29 UTC
I think this might be a bit risky to merge to 9, so I've only merged it to 10.  If a user reports it working fine on 9 then I will be happy to do the merge then.