From owner-freebsd-mobile@FreeBSD.ORG Mon Aug 25 18:37:24 2014 Return-Path: Delivered-To: freebsd-mobile@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 379B9B8D; Mon, 25 Aug 2014 18:37:24 +0000 (UTC) Received: from pandora.amnic.net (pandora.amnic.net [IPv6:2001:67c:21c:a610::11]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id DAA7A3C9B; Mon, 25 Aug 2014 18:37:23 +0000 (UTC) Received: from ran by pandora.amnic.net with local (Exim 4.84 (FreeBSD)) (envelope-from ) id 1XLz8p-000LdV-6g; Mon, 25 Aug 2014 22:37:19 +0400 Subject: Re: Fwd: svn commit: r270516 - head/sys/dev/drm2/i915 In-Reply-To: To: Adrian Chadd Date: Mon, 25 Aug 2014 22:37:19 +0400 (AMT) From: Hrant Dadivanyan Reply-To: Hrant Dadivanyan X-PGP: https://amnic.net/pgpkeys/hrant.asc X-NCC-RegID: am.isoc X-Mailer: ELM [version 2.4ME+ PL126 (25)] MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="UTF-8" Message-Id: Sender: Hrant Dadivanyan Cc: "freebsd-mobile@freebsd.org" X-BeenThere: freebsd-mobile@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: Mobile computing with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 25 Aug 2014 18:37:24 -0000 > This fixes the brightness on a Lenovo X230. The buttons don't yet work > - they end up setting the value +1 or -1 from the current setting, but > no further. > The same on Lenovo X1 Carbon with 10-STABLE - buttons do +1 or -1 only, but hw.acpi.video.lcd0.brightness accepts any value. Not all values actually changes the brightness, but some do - all tenths for example. hw.acpi.video.lcd0.fullpower and .economy are also ignored, but custom entry on /etc/devd.conf solves this by setting .brightness directly, depending on AC status. Finally can enjoy long battery life, thank you very much ! Hrant > But, I can at least now control the brightness on this damned thing! > > > -a > > > ---------- Forwarded message ---------- > From: Adrian Chadd > Date: 24 August 2014 22:03 > Subject: svn commit: r270516 - head/sys/dev/drm2/i915 > To: src-committers@freebsd.org, svn-src-all@freebsd.org, > svn-src-head@freebsd.org > > > Author: adrian > Date: Mon Aug 25 05:03:10 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 > Reviewed by: dumbbell > > Modified: > head/sys/dev/drm2/i915/i915_drv.h > head/sys/dev/drm2/i915/i915_irq.c > head/sys/dev/drm2/i915/intel_opregion.c > > Modified: head/sys/dev/drm2/i915/i915_drv.h > ============================================================================== > --- head/sys/dev/drm2/i915/i915_drv.h Mon Aug 25 03:02:38 2014 > (r270515) > +++ head/sys/dev/drm2/i915/i915_drv.h Mon Aug 25 05:03:10 2014 > (r270516) > @@ -1242,10 +1242,11 @@ extern void intel_iic_reset(struct drm_d > > /* intel_opregion.c */ > int intel_opregion_setup(struct drm_device *dev); > -extern int intel_opregion_init(struct drm_device *dev); > +extern void intel_opregion_init(struct drm_device *dev); > extern void intel_opregion_fini(struct drm_device *dev); > -extern void opregion_asle_intr(struct drm_device *dev); > -extern void opregion_enable_asle(struct drm_device *dev); > +extern void intel_opregion_asle_intr(struct drm_device *dev); > +extern void intel_opregion_gse_intr(struct drm_device *dev); > +extern void intel_opregion_enable_asle(struct drm_device *dev); > > /* i915_gem_gtt.c */ > int i915_gem_init_aliasing_ppgtt(struct drm_device *dev); > > Modified: head/sys/dev/drm2/i915/i915_irq.c > ============================================================================== > --- head/sys/dev/drm2/i915/i915_irq.c Mon Aug 25 03:02:38 2014 > (r270515) > +++ head/sys/dev/drm2/i915/i915_irq.c Mon Aug 25 05:03:10 2014 > (r270516) > @@ -537,11 +537,7 @@ ivybridge_irq_handler(void *arg) > notify_ring(dev, &dev_priv->rings[BCS]); > > if (de_iir & DE_GSE_IVB) { > -#if 1 > - KIB_NOTYET(); > -#else > intel_opregion_gse_intr(dev); > -#endif > } > > if (de_iir & DE_PLANEA_FLIP_DONE_IVB) { > @@ -649,11 +645,7 @@ ironlake_irq_handler(void *arg) > notify_ring(dev, &dev_priv->rings[BCS]); > > if (de_iir & DE_GSE) { > -#if 1 > - KIB_NOTYET(); > -#else > intel_opregion_gse_intr(dev); > -#endif > } > > if (de_iir & DE_PLANEA_FLIP_DONE) { > @@ -1055,11 +1047,7 @@ i915_driver_irq_handler(void *arg) > > > if (blc_event || (iir & I915_ASLE_INTERRUPT)) { > -#if 1 > - KIB_NOTYET(); > -#else > intel_opregion_asle_intr(dev); > -#endif > } > > /* With MSI, interrupts are only generated when iir > @@ -1781,11 +1769,7 @@ i915_driver_irq_postinstall(struct drm_d > I915_WRITE(PORT_HOTPLUG_EN, hotplug_en); > } > > -#if 1 > - KIB_NOTYET(); > -#else > intel_opregion_enable_asle(dev); > -#endif > > return 0; > } > > Modified: head/sys/dev/drm2/i915/intel_opregion.c > ============================================================================== > --- head/sys/dev/drm2/i915/intel_opregion.c Mon Aug 25 03:02:38 > 2014 (r270515) > +++ head/sys/dev/drm2/i915/intel_opregion.c Mon Aug 25 05:03:10 > 2014 (r270516) > @@ -32,6 +32,9 @@ __FBSDID("$FreeBSD$"); > #include > #include > #include > +#include > +#include > +#include > > #define PCI_ASLE 0xe4 > #define PCI_ASLS 0xfc > @@ -144,7 +147,7 @@ struct opregion_asle { > #define ACPI_DIGITAL_OUTPUT (3<<8) > #define ACPI_LVDS_OUTPUT (4<<8) > > -#ifdef CONFIG_ACPI > +#if 1 > static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) > { > struct drm_i915_private *dev_priv = dev->dev_private; > @@ -289,6 +292,7 @@ void intel_opregion_enable_asle(struct d > > static struct intel_opregion *system_opregion; > > +#if 0 > static int intel_opregion_video_event(struct notifier_block *nb, > unsigned long val, void *data) > { > @@ -319,6 +323,7 @@ static int intel_opregion_video_event(st > static struct notifier_block intel_opregion_notifier = { > .notifier_call = intel_opregion_video_event, > }; > +#endif > > /* > * Initialise the DIDL field in opregion. This passes a list of devices to > @@ -326,37 +331,72 @@ static struct notifier_block intel_opreg > * (version 3) > */ > > +static int acpi_is_video_device(ACPI_HANDLE devh) { > + ACPI_HANDLE h; > + if (ACPI_FAILURE(AcpiGetHandle(devh, "_DOD", &h)) || > + ACPI_FAILURE(AcpiGetHandle(devh, "_DOS", &h))) { > + return 0; > + } > + return 1; > +} > + > static void intel_didl_outputs(struct drm_device *dev) > { > struct drm_i915_private *dev_priv = dev->dev_private; > struct intel_opregion *opregion = &dev_priv->opregion; > struct drm_connector *connector; > - acpi_handle handle; > - struct acpi_device *acpi_dev, *acpi_cdev, *acpi_video_bus = NULL; > - unsigned long long device_id; > - acpi_status status; > + u32 device_id; > + ACPI_HANDLE handle, acpi_video_bus, acpi_cdev; > + ACPI_STATUS status; > int i = 0; > > - handle = DEVICE_ACPI_HANDLE(&dev->pdev->dev); > - if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &acpi_dev))) > + handle = acpi_get_handle(dev->device); > + if (!handle) > return; > > - if (acpi_is_video_device(acpi_dev)) > - acpi_video_bus = acpi_dev; > + if (acpi_is_video_device(handle)) > + acpi_video_bus = handle; > else { > + acpi_cdev = NULL; > + acpi_video_bus = NULL; > + while (AcpiGetNextObject(ACPI_TYPE_DEVICE, handle, acpi_cdev, > + &acpi_cdev) != AE_NOT_FOUND) { > + if (acpi_is_video_device(acpi_cdev)) { > + acpi_video_bus = acpi_cdev; > + break; > + } > + } > +#if 0 > list_for_each_entry(acpi_cdev, &acpi_dev->children, node) { > if (acpi_is_video_device(acpi_cdev)) { > acpi_video_bus = acpi_cdev; > break; > } > } > +#endif > } > > if (!acpi_video_bus) { > - printk(KERN_WARNING "No ACPI video bus found\n"); > + device_printf(dev->device, "No ACPI video bus found\n"); > return; > } > > + acpi_cdev = NULL; > + while (AcpiGetNextObject(ACPI_TYPE_DEVICE, acpi_video_bus, acpi_cdev, > + &acpi_cdev) != AE_NOT_FOUND) { > + if (i >= 8) { > + device_printf(dev->device, "More than 8 > outputs detected\n"); > + return; > + } > + status = acpi_GetInteger(acpi_cdev, "_ADR", &device_id); > + if (ACPI_SUCCESS(status)) { > + if (!device_id) > + goto blind_set; > + opregion->acpi->didl[i] = (u32)(device_id & 0x0f0f); > + i++; > + } > + } > +#if 0 > list_for_each_entry(acpi_cdev, &acpi_video_bus->children, node) { > if (i >= 8) { > dev_printk(KERN_ERR, &dev->pdev->dev, > @@ -373,6 +413,7 @@ static void intel_didl_outputs(struct dr > i++; > } > } > +#endif > > end: > /* If fewer than 8 outputs, the list must be null terminated */ > @@ -417,6 +458,25 @@ blind_set: > goto end; > } > > +static void intel_setup_cadls(struct drm_device *dev) > +{ > + struct drm_i915_private *dev_priv = dev->dev_private; > + struct intel_opregion *opregion = &dev_priv->opregion; > + int i = 0; > + u32 disp_id; > + > + /* Initialize the CADL field by duplicating the DIDL values. > + * Technically, this is not always correct as display outputs may exist, > + * but not active. This initialization is necessary for some Clevo > + * laptops that check this field before processing the brightness and > + * display switching hotkeys. Just like DIDL, CADL is NULL-terminated if > + * there are less than eight devices. */ > + do { > + disp_id = opregion->acpi->didl[i]; > + opregion->acpi->cadl[i] = disp_id; > + } while (++i < 8 && disp_id != 0); > +} > + > void intel_opregion_init(struct drm_device *dev) > { > struct drm_i915_private *dev_priv = dev->dev_private; > @@ -426,8 +486,10 @@ void intel_opregion_init(struct drm_devi > return; > > if (opregion->acpi) { > - if (drm_core_check_feature(dev, DRIVER_MODESET)) > + if (drm_core_check_feature(dev, DRIVER_MODESET)) { > intel_didl_outputs(dev); > + intel_setup_cadls(dev); > + } > > /* Notify BIOS we are ready to handle ACPI video ext notifs. > * Right now, all the events are handled by the ACPI > video module. > @@ -436,7 +498,9 @@ void intel_opregion_init(struct drm_devi > opregion->acpi->drdy = 1; > > system_opregion = opregion; > +#if 0 > register_acpi_notifier(&intel_opregion_notifier); > +#endif > } > > if (opregion->asle) > @@ -455,11 +519,13 @@ void intel_opregion_fini(struct drm_devi > opregion->acpi->drdy = 0; > > system_opregion = NULL; > +#if 0 > unregister_acpi_notifier(&intel_opregion_notifier); > +#endif > } > > /* just clear all opregion memory pointers now */ > - iounmap(opregion->header); > + pmap_unmapdev((vm_offset_t)opregion->header, OPREGION_SIZE); > opregion->header = NULL; > opregion->acpi = NULL; > opregion->swsci = NULL; > _______________________________________________ > freebsd-mobile@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-mobile > To unsubscribe, send any mail to "freebsd-mobile-unsubscribe@freebsd.org" -- Hrant Dadivanyan (aka Ran d'Adi) hrant(at)dadivanyan.net /* "Feci quod potui, faciant meliora potentes." */ ran(at)psg.com