~ubuntu-branches/ubuntu/maverick/linux-backports-modules-2.6.32/maverick

« back to all changes in this revision

Viewing changes to updates/nouveau/nouveau/nouveau_acpi.c

  • Committer: Bazaar Package Importer
  • Author(s): Andy Whitcroft, Andy Whitcroft
  • Date: 2010-02-04 23:15:51 UTC
  • Revision ID: james.westby@ubuntu.com-20100204231551-vjz5pkvxclukjxm1
Tags: 2.6.32-12.1
[ Andy Whitcroft ]

* initial LBM for lucid
* drop generated files
* printchanges -- rebase tree does not have stable tags use changelog
* printenv -- add revisions to printenv output
* formally rename compat-wireless to linux-backports-modules-wireless
* Update to compat-wireless-2.6.33-rc5
* update nouveau to mainline 2.6.33-rc4
* add new LBM package for nouveau
* nouveau -- fix major numbers and proc entry names
* fix up firmware installs for -wireless
* clean up UPDATE-NOVEAU
* update Nouveau to v2.6.33-rc6

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <linux/pci.h>
 
2
#include <linux/acpi.h>
 
3
#include <acpi/acpi_drivers.h>
 
4
#include <acpi/acpi_bus.h>
 
5
 
 
6
#include "drmP.h"
 
7
#include "drm.h"
 
8
#include "drm_sarea.h"
 
9
#include "drm_crtc_helper.h"
 
10
#include "nouveau_drv.h"
 
11
#include "nouveau_drm.h"
 
12
#include "nv50_display.h"
 
13
 
 
14
#define NOUVEAU_DSM_SUPPORTED 0x00
 
15
#define NOUVEAU_DSM_SUPPORTED_FUNCTIONS 0x00
 
16
 
 
17
#define NOUVEAU_DSM_ACTIVE 0x01
 
18
#define NOUVEAU_DSM_ACTIVE_QUERY 0x00
 
19
 
 
20
#define NOUVEAU_DSM_LED 0x02
 
21
#define NOUVEAU_DSM_LED_STATE 0x00
 
22
#define NOUVEAU_DSM_LED_OFF 0x10
 
23
#define NOUVEAU_DSM_LED_STAMINA 0x11
 
24
#define NOUVEAU_DSM_LED_SPEED 0x12
 
25
 
 
26
#define NOUVEAU_DSM_POWER 0x03
 
27
#define NOUVEAU_DSM_POWER_STATE 0x00
 
28
#define NOUVEAU_DSM_POWER_SPEED 0x01
 
29
#define NOUVEAU_DSM_POWER_STAMINA 0x02
 
30
 
 
31
static int nouveau_dsm(struct drm_device *dev, int func, int arg, int *result)
 
32
{
 
33
        static char muid[] = {
 
34
                0xA0, 0xA0, 0x95, 0x9D, 0x60, 0x00, 0x48, 0x4D,
 
35
                0xB3, 0x4D, 0x7E, 0x5F, 0xEA, 0x12, 0x9F, 0xD4,
 
36
        };
 
37
 
 
38
        struct pci_dev *pdev = dev->pdev;
 
39
        struct acpi_handle *handle;
 
40
        struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
 
41
        struct acpi_object_list input;
 
42
        union acpi_object params[4];
 
43
        union acpi_object *obj;
 
44
        int err;
 
45
 
 
46
        handle = DEVICE_ACPI_HANDLE(&pdev->dev);
 
47
 
 
48
        if (!handle)
 
49
                return -ENODEV;
 
50
 
 
51
        input.count = 4;
 
52
        input.pointer = params;
 
53
        params[0].type = ACPI_TYPE_BUFFER;
 
54
        params[0].buffer.length = sizeof(muid);
 
55
        params[0].buffer.pointer = (char *)muid;
 
56
        params[1].type = ACPI_TYPE_INTEGER;
 
57
        params[1].integer.value = 0x00000102;
 
58
        params[2].type = ACPI_TYPE_INTEGER;
 
59
        params[2].integer.value = func;
 
60
        params[3].type = ACPI_TYPE_INTEGER;
 
61
        params[3].integer.value = arg;
 
62
 
 
63
        err = acpi_evaluate_object(handle, "_DSM", &input, &output);
 
64
        if (err) {
 
65
                NV_INFO(dev, "failed to evaluate _DSM: %d\n", err);
 
66
                return err;
 
67
        }
 
68
 
 
69
        obj = (union acpi_object *)output.pointer;
 
70
 
 
71
        if (obj->type == ACPI_TYPE_INTEGER)
 
72
                if (obj->integer.value == 0x80000002)
 
73
                        return -ENODEV;
 
74
 
 
75
        if (obj->type == ACPI_TYPE_BUFFER) {
 
76
                if (obj->buffer.length == 4 && result) {
 
77
                        *result = 0;
 
78
                        *result |= obj->buffer.pointer[0];
 
79
                        *result |= (obj->buffer.pointer[1] << 8);
 
80
                        *result |= (obj->buffer.pointer[2] << 16);
 
81
                        *result |= (obj->buffer.pointer[3] << 24);
 
82
                }
 
83
        }
 
84
 
 
85
        kfree(output.pointer);
 
86
        return 0;
 
87
}
 
88
 
 
89
int nouveau_hybrid_setup(struct drm_device *dev)
 
90
{
 
91
        int result;
 
92
 
 
93
        if (nouveau_dsm(dev, NOUVEAU_DSM_ACTIVE, NOUVEAU_DSM_ACTIVE_QUERY,
 
94
                                                                &result))
 
95
                return -ENODEV;
 
96
 
 
97
        NV_INFO(dev, "_DSM hardware status gave 0x%x\n", result);
 
98
 
 
99
        if (result & 0x1) {     /* Stamina mode - disable the external GPU */
 
100
                nouveau_dsm(dev, NOUVEAU_DSM_LED, NOUVEAU_DSM_LED_STAMINA,
 
101
                                                                        NULL);
 
102
                nouveau_dsm(dev, NOUVEAU_DSM_POWER, NOUVEAU_DSM_POWER_STAMINA,
 
103
                                                                        NULL);
 
104
        } else {                /* Ensure that the external GPU is enabled */
 
105
                nouveau_dsm(dev, NOUVEAU_DSM_LED, NOUVEAU_DSM_LED_SPEED, NULL);
 
106
                nouveau_dsm(dev, NOUVEAU_DSM_POWER, NOUVEAU_DSM_POWER_SPEED,
 
107
                                                                        NULL);
 
108
        }
 
109
 
 
110
        return 0;
 
111
}
 
112
 
 
113
bool nouveau_dsm_probe(struct drm_device *dev)
 
114
{
 
115
        int support = 0;
 
116
 
 
117
        if (nouveau_dsm(dev, NOUVEAU_DSM_SUPPORTED,
 
118
                                NOUVEAU_DSM_SUPPORTED_FUNCTIONS, &support))
 
119
                return false;
 
120
 
 
121
        if (!support)
 
122
                return false;
 
123
 
 
124
        return true;
 
125
}