Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/external/bsd/drm2 i915drmkms(4): Enable CONFIG_ACPI if N...



details:   https://anonhg.NetBSD.org/src/rev/0e4e26096f1d
branches:  trunk
changeset: 803636:0e4e26096f1d
user:      nonaka <nonaka%NetBSD.org@localhost>
date:      Wed Nov 05 23:46:09 2014 +0000

description:
i915drmkms(4): Enable CONFIG_ACPI if NACPICA > 0.
Now brightness can be adjusted via hotkey on Mouse Computer LB-J300X (Clevo W330SU2).

diffstat:

 sys/external/bsd/drm2/dist/drm/i915/i915_dma.c       |    4 +
 sys/external/bsd/drm2/dist/drm/i915/i915_drv.h       |   22 ++-
 sys/external/bsd/drm2/dist/drm/i915/intel_acpi.c     |  187 ++++++++++++++++++-
 sys/external/bsd/drm2/dist/drm/i915/intel_opregion.c |   72 +++++++
 sys/external/bsd/drm2/i915drm/files.i915drmkms       |    5 +-
 sys/external/bsd/drm2/include/linux/acpi.h           |    4 +-
 sys/external/bsd/drm2/include/linux/pci.h            |   25 ++-
 7 files changed, 310 insertions(+), 9 deletions(-)

diffs (truncated from 597 to 300 lines):

diff -r e0600f0cf698 -r 0e4e26096f1d sys/external/bsd/drm2/dist/drm/i915/i915_dma.c
--- a/sys/external/bsd/drm2/dist/drm/i915/i915_dma.c    Wed Nov 05 22:27:55 2014 +0000
+++ b/sys/external/bsd/drm2/dist/drm/i915/i915_dma.c    Wed Nov 05 23:46:09 2014 +0000
@@ -1375,7 +1375,11 @@
                goto out;
 #endif
 
+#ifdef __NetBSD__
+       intel_register_dsm_handler(dev);
+#else
        intel_register_dsm_handler();
+#endif
 
 #ifndef __NetBSD__             /* XXX vga */
        ret = vga_switcheroo_register_client(dev->pdev, &i915_switcheroo_ops, false);
diff -r e0600f0cf698 -r 0e4e26096f1d sys/external/bsd/drm2/dist/drm/i915/i915_drv.h
--- a/sys/external/bsd/drm2/dist/drm/i915/i915_drv.h    Wed Nov 05 22:27:55 2014 +0000
+++ b/sys/external/bsd/drm2/dist/drm/i915/i915_drv.h    Wed Nov 05 23:46:09 2014 +0000
@@ -30,6 +30,13 @@
 #ifndef _I915_DRV_H_
 #define _I915_DRV_H_
 
+#if defined(__NetBSD__) && (defined(i386) || defined(amd64))
+#include "acpica.h"
+#if (NACPICA > 0)
+#define CONFIG_ACPI
+#endif
+#endif
+
 #include <uapi/drm/i915_drm.h>
 
 #include "i915_reg.h"
@@ -2720,8 +2727,8 @@
 
 /* intel_opregion.c */
 struct intel_encoder;
+#ifdef CONFIG_ACPI
 extern int intel_opregion_setup(struct drm_device *dev);
-#ifdef CONFIG_ACPI
 extern void intel_opregion_init(struct drm_device *dev);
 extern void intel_opregion_fini(struct drm_device *dev);
 extern void intel_opregion_asle_intr(struct drm_device *dev);
@@ -2730,6 +2737,7 @@
 extern int intel_opregion_notify_adapter(struct drm_device *dev,
                                         pci_power_t state);
 #else
+static inline int intel_opregion_setup(struct drm_device *dev) { return 0; }
 static inline void intel_opregion_init(struct drm_device *dev) { return; }
 static inline void intel_opregion_fini(struct drm_device *dev) { return; }
 static inline void intel_opregion_asle_intr(struct drm_device *dev) { return; }
@@ -2747,10 +2755,22 @@
 
 /* intel_acpi.c */
 #ifdef CONFIG_ACPI
+#ifdef __NetBSD__
+extern void intel_register_dsm_handler(struct drm_device *);
+#else
 extern void intel_register_dsm_handler(void);
+#endif
 extern void intel_unregister_dsm_handler(void);
 #else
+#ifdef __NetBSD__
+static inline void
+intel_register_dsm_handler(struct drm_device *dev)
+{
+       return;
+}
+#else
 static inline void intel_register_dsm_handler(void) { return; }
+#endif
 static inline void intel_unregister_dsm_handler(void) { return; }
 #endif /* CONFIG_ACPI */
 
diff -r e0600f0cf698 -r 0e4e26096f1d sys/external/bsd/drm2/dist/drm/i915/intel_acpi.c
--- a/sys/external/bsd/drm2/dist/drm/i915/intel_acpi.c  Wed Nov 05 22:27:55 2014 +0000
+++ b/sys/external/bsd/drm2/dist/drm/i915/intel_acpi.c  Wed Nov 05 23:46:09 2014 +0000
@@ -9,11 +9,104 @@
 #include <drm/drmP.h>
 #include "i915_drv.h"
 
+#ifdef CONFIG_ACPI
+
+#ifdef __NetBSD__
+static ACPI_OBJECT *
+acpi_evaluate_dsm(ACPI_HANDLE handle, const uint8_t *uuid, int rev, int func,
+    ACPI_OBJECT *argv4)
+{
+       ACPI_OBJECT_LIST arg;
+       ACPI_OBJECT params[4];
+       ACPI_BUFFER buf;
+       ACPI_STATUS rv;
+
+       if (handle == NULL)
+               handle = ACPI_ROOT_OBJECT;
+
+       arg.Count = 4;
+       arg.Pointer = params;
+       params[0].Type = ACPI_TYPE_BUFFER;
+       params[0].Buffer.Length = 16;
+       params[0].Buffer.Pointer = (char *)__UNCONST(uuid);
+       params[1].Type = ACPI_TYPE_INTEGER;
+       params[1].Integer.Value = rev;
+       params[2].Type = ACPI_TYPE_INTEGER;
+       params[2].Integer.Value = func;
+       if (argv4 != NULL) {
+               params[3] = *argv4;
+       } else {
+               params[3].Type = ACPI_TYPE_PACKAGE;
+               params[3].Package.Count = 0;
+               params[3].Package.Elements = NULL;
+       }
+
+       buf.Pointer = NULL;
+       buf.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
+
+       rv = AcpiEvaluateObject(handle, "_DSM", &arg, &buf);
+       if (ACPI_SUCCESS(rv))
+               return (ACPI_OBJECT *)buf.Pointer;
+       return NULL;
+}
+
+static inline ACPI_OBJECT *
+acpi_evaluate_dsm_typed(ACPI_HANDLE handle, const uint8_t *uuid, int rev,
+    int func, ACPI_OBJECT *argv4, ACPI_OBJECT_TYPE type)
+{
+       ACPI_OBJECT *obj;
+
+       obj = acpi_evaluate_dsm(handle, uuid, rev, func, argv4);
+       if (obj != NULL && obj->Type != type) {
+               ACPI_FREE(obj);
+               obj = NULL;
+       }
+       return obj;
+}
+
+#define        ACPI_INIT_DSM_ARGV4(cnt, eles)          \
+{                                              \
+       .Package.Type = ACPI_TYPE_PACKAGE,      \
+       .Package.Count = (cnt),                 \
+       .Package.Elements = (eles)              \
+}
+
+static bool
+acpi_check_dsm(ACPI_HANDLE handle, const uint8_t *uuid, int rev, uint64_t funcs)
+{
+       ACPI_OBJECT *obj;
+       uint64_t mask = 0;
+       int i;
+
+       if (funcs == 0)
+               return false;
+
+       obj = acpi_evaluate_dsm(handle, uuid, rev, 0, NULL);
+       if (obj == NULL)
+               return false;
+
+       if (obj->Type == ACPI_TYPE_INTEGER)
+               mask = obj->Integer.Value;
+       else if (obj->Type == ACPI_TYPE_BUFFER)
+               for (i = 0; i < obj->Buffer.Length && i < 8; i++)
+                       mask |= (uint64_t)obj->Buffer.Pointer[i] << (i * 8);
+       ACPI_FREE(obj);
+
+       if ((mask & 0x1) == 0x1 && (mask & funcs) == funcs)
+               return true;
+       return false;
+}
+#endif
+
 #define INTEL_DSM_REVISION_ID 1 /* For Calpella anyway... */
 #define INTEL_DSM_FN_PLATFORM_MUX_INFO 1 /* No args */
 
 static struct intel_dsm_priv {
+#ifdef __NetBSD__
+       ACPI_HANDLE dhandle;
+#else
        acpi_handle dhandle;
+#endif
 } intel_dsm_priv;
 
 static const u8 intel_dsm_guid[] = {
@@ -79,7 +172,11 @@
 static void intel_dsm_platform_mux_info(void)
 {
        int i;
+#ifdef __NetBSD__
+       ACPI_OBJECT *pkg, *connector_count;
+#else
        union acpi_object *pkg, *connector_count;
+#endif
 
        pkg = acpi_evaluate_dsm_typed(intel_dsm_priv.dhandle, intel_dsm_guid,
                        INTEL_DSM_REVISION_ID, INTEL_DSM_FN_PLATFORM_MUX_INFO,
@@ -89,6 +186,26 @@
                return;
        }
 
+#ifdef __NetBSD__
+       connector_count = &pkg->Package.Elements[0];
+       DRM_DEBUG_DRIVER("MUX info connectors: %lld\n",
+                 (unsigned long long)connector_count->Integer.Value);
+       for (i = 1; i < pkg->Package.Count; i++) {
+               ACPI_OBJECT *obj = &pkg->Package.Elements[i];
+               ACPI_OBJECT *connector_id = &obj->Package.Elements[0];
+               ACPI_OBJECT *info = &obj->Package.Elements[1];
+               DRM_DEBUG_DRIVER("Connector id: 0x%016llx\n",
+                         (unsigned long long)connector_id->Integer.Value);
+               DRM_DEBUG_DRIVER("  port id: %s\n",
+                      intel_dsm_port_name(info->Buffer.Pointer[0]));
+               DRM_DEBUG_DRIVER("  display mux info: %s\n",
+                      intel_dsm_mux_type(info->Buffer.Pointer[1]));
+               DRM_DEBUG_DRIVER("  aux/dc mux info: %s\n",
+                      intel_dsm_mux_type(info->Buffer.Pointer[2]));
+               DRM_DEBUG_DRIVER("  hpd mux info: %s\n",
+                      intel_dsm_mux_type(info->Buffer.Pointer[3]));
+       }
+#else
        connector_count = &pkg->package.elements[0];
        DRM_DEBUG_DRIVER("MUX info connectors: %lld\n",
                  (unsigned long long)connector_count->integer.value);
@@ -107,15 +224,21 @@
                DRM_DEBUG_DRIVER("  hpd mux info: %s\n",
                       intel_dsm_mux_type(info->buffer.pointer[3]));
        }
-
+#endif
        ACPI_FREE(pkg);
 }
 
+#ifdef __NetBSD__
+static bool intel_dsm_pci_probe(ACPI_HANDLE dhandle)
+#else
 static bool intel_dsm_pci_probe(struct pci_dev *pdev)
+#endif
 {
+#ifndef __NetBSD__
        acpi_handle dhandle;
 
        dhandle = ACPI_HANDLE(&pdev->dev);
+#endif
        if (!dhandle)
                return false;
 
@@ -131,6 +254,57 @@
        return true;
 }
 
+#ifdef __NetBSD__
+struct dsm_pa {
+       struct pci_attach_args  pa;
+       int                     vga_count;
+       bool                    has_dsm;
+};
+
+/* XXX from sys/dev/pci/vga_pcivar.h */
+#define        DEVICE_IS_VGA_PCI(class, id)                                    \
+           (((PCI_CLASS(class) == PCI_CLASS_DISPLAY &&                 \
+             PCI_SUBCLASS(class) == PCI_SUBCLASS_DISPLAY_VGA) ||       \
+            (PCI_CLASS(class) == PCI_CLASS_PREHISTORIC &&              \
+             PCI_SUBCLASS(class) == PCI_SUBCLASS_PREHISTORIC_VGA)) ? 1 : 0)
+
+static int
+intel_dsm_vga_match(const struct pci_attach_args *pa)
+{
+       struct dsm_pa *dpa = (struct dsm_pa *)__UNCONST(pa);
+
+       if (!DEVICE_IS_VGA_PCI(pa->pa_class, pa->pa_id))
+               return 0;
+
+       dpa->vga_count++;
+       struct acpi_devnode *node = acpi_pcidev_find(0 /*XXX segment*/,
+           pa->pa_bus, pa->pa_device, pa->pa_function);
+       if (node != NULL)
+               dpa->has_dsm |= intel_dsm_pci_probe(node->ad_handle);
+       return 0;
+}
+
+static bool intel_dsm_detect(struct drm_device *dev)
+{
+       char acpi_method_name[255] = { 0 };
+       struct dsm_pa dpa;
+
+       dpa.pa = dev->pdev->pd_pa;
+       dpa.vga_count = 0;
+       dpa.has_dsm = false;
+       pci_find_device(&dpa.pa, intel_dsm_vga_match);
+
+       if (dpa.vga_count == 2 && dpa.has_dsm) {
+               const char *name = acpi_name(intel_dsm_priv.dhandle);
+               strlcpy(acpi_method_name, name, sizeof(acpi_method_name));
+               DRM_DEBUG_DRIVER("VGA switcheroo: detected DSM switching method %s handle\n",
+                                acpi_method_name);
+               return true;
+       }
+
+       return false;
+}
+#else
 static bool intel_dsm_detect(void)
 {



Home | Main Index | Thread Index | Old Index