aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2011-11-06 22:36:08 -0500
committerBen Skeggs <bskeggs@redhat.com>2011-12-21 04:01:42 -0500
commit3952315b9d20fb04d43d184f9c1475327811c5aa (patch)
treefabff1baedd0a2a3daf2e8953d27cdef666ced37 /drivers/gpu/drm/nouveau
parent93d9206d08dd18e3aaeed90a3e076b8c323fdd72 (diff)
drm/nouveau/mxm: implement _DSM shadow method
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_mxm.c61
1 files changed, 60 insertions, 1 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_mxm.c b/drivers/gpu/drm/nouveau/nouveau_mxm.c
index f6f73568c4f..840c88fc4f0 100644
--- a/drivers/gpu/drm/nouveau/nouveau_mxm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_mxm.c
@@ -476,11 +476,68 @@ mxm_shadow_rom(struct drm_device *dev, u8 version)
476 return false; 476 return false;
477} 477}
478 478
479#if defined(CONFIG_ACPI)
479static bool 480static bool
480mxm_shadow_dsm(struct drm_device *dev, u8 version) 481mxm_shadow_dsm(struct drm_device *dev, u8 version)
481{ 482{
482 return false; 483 struct drm_nouveau_private *dev_priv = dev->dev_private;
484 static char muid[] = {
485 0x00, 0xA4, 0x04, 0x40, 0x7D, 0x91, 0xF2, 0x4C,
486 0xB8, 0x9C, 0x79, 0xB6, 0x2F, 0xD5, 0x56, 0x65
487 };
488 u32 mxms_args[] = { 0x00000000 };
489 union acpi_object args[4] = {
490 /* _DSM MUID */
491 { .buffer.type = 3,
492 .buffer.length = sizeof(muid),
493 .buffer.pointer = muid,
494 },
495 /* spec says this can be zero to mean "highest revision", but
496 * of course there's at least one bios out there which fails
497 * unless you pass in exactly the version it supports..
498 */
499 { .integer.type = ACPI_TYPE_INTEGER,
500 .integer.value = (version & 0xf0) << 4 | (version & 0x0f),
501 },
502 /* MXMS function */
503 { .integer.type = ACPI_TYPE_INTEGER,
504 .integer.value = 0x00000010,
505 },
506 /* Pointer to MXMS arguments */
507 { .buffer.type = ACPI_TYPE_BUFFER,
508 .buffer.length = sizeof(mxms_args),
509 .buffer.pointer = (char *)mxms_args,
510 },
511 };
512 struct acpi_object_list list = { ARRAY_SIZE(args), args };
513 struct acpi_buffer retn = { ACPI_ALLOCATE_BUFFER, NULL };
514 union acpi_object *obj;
515 acpi_handle handle;
516 int ret;
517
518 handle = DEVICE_ACPI_HANDLE(&dev->pdev->dev);
519 if (!handle)
520 return false;
521
522 ret = acpi_evaluate_object(handle, "_DSM", &list, &retn);
523 if (ret) {
524 MXM_DBG(dev, "DSM MXMS failed: %d\n", ret);
525 return false;
526 }
527
528 obj = retn.pointer;
529 if (obj->type == ACPI_TYPE_BUFFER) {
530 dev_priv->mxms = kmemdup(obj->buffer.pointer,
531 obj->buffer.length, GFP_KERNEL);
532 } else
533 if (obj->type == ACPI_TYPE_INTEGER) {
534 MXM_DBG(dev, "DSM MXMS returned 0x%llx\n", obj->integer.value);
535 }
536
537 kfree(obj);
538 return dev_priv->mxms != NULL;
483} 539}
540#endif
484 541
485#if defined(CONFIG_ACPI_WMI) || defined(CONFIG_ACPI_WMI_MODULE) 542#if defined(CONFIG_ACPI_WMI) || defined(CONFIG_ACPI_WMI_MODULE)
486 543
@@ -521,7 +578,9 @@ struct mxm_shadow_h {
521 bool (*exec)(struct drm_device *, u8 version); 578 bool (*exec)(struct drm_device *, u8 version);
522} _mxm_shadow[] = { 579} _mxm_shadow[] = {
523 { "ROM", mxm_shadow_rom }, 580 { "ROM", mxm_shadow_rom },
581#if defined(CONFIG_ACPI)
524 { "DSM", mxm_shadow_dsm }, 582 { "DSM", mxm_shadow_dsm },
583#endif
525#if defined(CONFIG_ACPI_WMI) || defined(CONFIG_ACPI_WMI_MODULE) 584#if defined(CONFIG_ACPI_WMI) || defined(CONFIG_ACPI_WMI_MODULE)
526 { "WMI", mxm_shadow_wmi }, 585 { "WMI", mxm_shadow_wmi },
527#endif 586#endif