diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_acpi.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_acpi.c | 146 |
1 files changed, 30 insertions, 116 deletions
diff --git a/drivers/gpu/drm/i915/intel_acpi.c b/drivers/gpu/drm/i915/intel_acpi.c index dfff0907f70e..d96eee1ae9c5 100644 --- a/drivers/gpu/drm/i915/intel_acpi.c +++ b/drivers/gpu/drm/i915/intel_acpi.c | |||
@@ -6,14 +6,10 @@ | |||
6 | #include <linux/pci.h> | 6 | #include <linux/pci.h> |
7 | #include <linux/acpi.h> | 7 | #include <linux/acpi.h> |
8 | #include <linux/vga_switcheroo.h> | 8 | #include <linux/vga_switcheroo.h> |
9 | #include <acpi/acpi_drivers.h> | ||
10 | |||
11 | #include <drm/drmP.h> | 9 | #include <drm/drmP.h> |
12 | #include "i915_drv.h" | 10 | #include "i915_drv.h" |
13 | 11 | ||
14 | #define INTEL_DSM_REVISION_ID 1 /* For Calpella anyway... */ | 12 | #define INTEL_DSM_REVISION_ID 1 /* For Calpella anyway... */ |
15 | |||
16 | #define INTEL_DSM_FN_SUPPORTED_FUNCTIONS 0 /* No args */ | ||
17 | #define INTEL_DSM_FN_PLATFORM_MUX_INFO 1 /* No args */ | 13 | #define INTEL_DSM_FN_PLATFORM_MUX_INFO 1 /* No args */ |
18 | 14 | ||
19 | static struct intel_dsm_priv { | 15 | static struct intel_dsm_priv { |
@@ -28,61 +24,6 @@ static const u8 intel_dsm_guid[] = { | |||
28 | 0x0f, 0x13, 0x17, 0xb0, 0x1c, 0x2c | 24 | 0x0f, 0x13, 0x17, 0xb0, 0x1c, 0x2c |
29 | }; | 25 | }; |
30 | 26 | ||
31 | static int intel_dsm(acpi_handle handle, int func) | ||
32 | { | ||
33 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
34 | struct acpi_object_list input; | ||
35 | union acpi_object params[4]; | ||
36 | union acpi_object *obj; | ||
37 | u32 result; | ||
38 | int ret = 0; | ||
39 | |||
40 | input.count = 4; | ||
41 | input.pointer = params; | ||
42 | params[0].type = ACPI_TYPE_BUFFER; | ||
43 | params[0].buffer.length = sizeof(intel_dsm_guid); | ||
44 | params[0].buffer.pointer = (char *)intel_dsm_guid; | ||
45 | params[1].type = ACPI_TYPE_INTEGER; | ||
46 | params[1].integer.value = INTEL_DSM_REVISION_ID; | ||
47 | params[2].type = ACPI_TYPE_INTEGER; | ||
48 | params[2].integer.value = func; | ||
49 | params[3].type = ACPI_TYPE_PACKAGE; | ||
50 | params[3].package.count = 0; | ||
51 | params[3].package.elements = NULL; | ||
52 | |||
53 | ret = acpi_evaluate_object(handle, "_DSM", &input, &output); | ||
54 | if (ret) { | ||
55 | DRM_DEBUG_DRIVER("failed to evaluate _DSM: %d\n", ret); | ||
56 | return ret; | ||
57 | } | ||
58 | |||
59 | obj = (union acpi_object *)output.pointer; | ||
60 | |||
61 | result = 0; | ||
62 | switch (obj->type) { | ||
63 | case ACPI_TYPE_INTEGER: | ||
64 | result = obj->integer.value; | ||
65 | break; | ||
66 | |||
67 | case ACPI_TYPE_BUFFER: | ||
68 | if (obj->buffer.length == 4) { | ||
69 | result = (obj->buffer.pointer[0] | | ||
70 | (obj->buffer.pointer[1] << 8) | | ||
71 | (obj->buffer.pointer[2] << 16) | | ||
72 | (obj->buffer.pointer[3] << 24)); | ||
73 | break; | ||
74 | } | ||
75 | default: | ||
76 | ret = -EINVAL; | ||
77 | break; | ||
78 | } | ||
79 | if (result == 0x80000002) | ||
80 | ret = -ENODEV; | ||
81 | |||
82 | kfree(output.pointer); | ||
83 | return ret; | ||
84 | } | ||
85 | |||
86 | static char *intel_dsm_port_name(u8 id) | 27 | static char *intel_dsm_port_name(u8 id) |
87 | { | 28 | { |
88 | switch (id) { | 29 | switch (id) { |
@@ -137,83 +78,56 @@ static char *intel_dsm_mux_type(u8 type) | |||
137 | 78 | ||
138 | static void intel_dsm_platform_mux_info(void) | 79 | static void intel_dsm_platform_mux_info(void) |
139 | { | 80 | { |
140 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; | 81 | int i; |
141 | struct acpi_object_list input; | 82 | union acpi_object *pkg, *connector_count; |
142 | union acpi_object params[4]; | 83 | |
143 | union acpi_object *pkg; | 84 | pkg = acpi_evaluate_dsm_typed(intel_dsm_priv.dhandle, intel_dsm_guid, |
144 | int i, ret; | 85 | INTEL_DSM_REVISION_ID, INTEL_DSM_FN_PLATFORM_MUX_INFO, |
145 | 86 | NULL, ACPI_TYPE_PACKAGE); | |
146 | input.count = 4; | 87 | if (!pkg) { |
147 | input.pointer = params; | 88 | DRM_DEBUG_DRIVER("failed to evaluate _DSM\n"); |
148 | params[0].type = ACPI_TYPE_BUFFER; | 89 | return; |
149 | params[0].buffer.length = sizeof(intel_dsm_guid); | ||
150 | params[0].buffer.pointer = (char *)intel_dsm_guid; | ||
151 | params[1].type = ACPI_TYPE_INTEGER; | ||
152 | params[1].integer.value = INTEL_DSM_REVISION_ID; | ||
153 | params[2].type = ACPI_TYPE_INTEGER; | ||
154 | params[2].integer.value = INTEL_DSM_FN_PLATFORM_MUX_INFO; | ||
155 | params[3].type = ACPI_TYPE_PACKAGE; | ||
156 | params[3].package.count = 0; | ||
157 | params[3].package.elements = NULL; | ||
158 | |||
159 | ret = acpi_evaluate_object(intel_dsm_priv.dhandle, "_DSM", &input, | ||
160 | &output); | ||
161 | if (ret) { | ||
162 | DRM_DEBUG_DRIVER("failed to evaluate _DSM: %d\n", ret); | ||
163 | goto out; | ||
164 | } | 90 | } |
165 | 91 | ||
166 | pkg = (union acpi_object *)output.pointer; | 92 | connector_count = &pkg->package.elements[0]; |
167 | 93 | DRM_DEBUG_DRIVER("MUX info connectors: %lld\n", | |
168 | if (pkg->type == ACPI_TYPE_PACKAGE) { | 94 | (unsigned long long)connector_count->integer.value); |
169 | union acpi_object *connector_count = &pkg->package.elements[0]; | 95 | for (i = 1; i < pkg->package.count; i++) { |
170 | DRM_DEBUG_DRIVER("MUX info connectors: %lld\n", | 96 | union acpi_object *obj = &pkg->package.elements[i]; |
171 | (unsigned long long)connector_count->integer.value); | 97 | union acpi_object *connector_id = &obj->package.elements[0]; |
172 | for (i = 1; i < pkg->package.count; i++) { | 98 | union acpi_object *info = &obj->package.elements[1]; |
173 | union acpi_object *obj = &pkg->package.elements[i]; | 99 | DRM_DEBUG_DRIVER("Connector id: 0x%016llx\n", |
174 | union acpi_object *connector_id = | 100 | (unsigned long long)connector_id->integer.value); |
175 | &obj->package.elements[0]; | 101 | DRM_DEBUG_DRIVER(" port id: %s\n", |
176 | union acpi_object *info = &obj->package.elements[1]; | 102 | intel_dsm_port_name(info->buffer.pointer[0])); |
177 | DRM_DEBUG_DRIVER("Connector id: 0x%016llx\n", | 103 | DRM_DEBUG_DRIVER(" display mux info: %s\n", |
178 | (unsigned long long)connector_id->integer.value); | 104 | intel_dsm_mux_type(info->buffer.pointer[1])); |
179 | DRM_DEBUG_DRIVER(" port id: %s\n", | 105 | DRM_DEBUG_DRIVER(" aux/dc mux info: %s\n", |
180 | intel_dsm_port_name(info->buffer.pointer[0])); | 106 | intel_dsm_mux_type(info->buffer.pointer[2])); |
181 | DRM_DEBUG_DRIVER(" display mux info: %s\n", | 107 | DRM_DEBUG_DRIVER(" hpd mux info: %s\n", |
182 | intel_dsm_mux_type(info->buffer.pointer[1])); | 108 | intel_dsm_mux_type(info->buffer.pointer[3])); |
183 | DRM_DEBUG_DRIVER(" aux/dc mux info: %s\n", | ||
184 | intel_dsm_mux_type(info->buffer.pointer[2])); | ||
185 | DRM_DEBUG_DRIVER(" hpd mux info: %s\n", | ||
186 | intel_dsm_mux_type(info->buffer.pointer[3])); | ||
187 | } | ||
188 | } | 109 | } |
189 | 110 | ||
190 | out: | 111 | ACPI_FREE(pkg); |
191 | kfree(output.pointer); | ||
192 | } | 112 | } |
193 | 113 | ||
194 | static bool intel_dsm_pci_probe(struct pci_dev *pdev) | 114 | static bool intel_dsm_pci_probe(struct pci_dev *pdev) |
195 | { | 115 | { |
196 | acpi_handle dhandle; | 116 | acpi_handle dhandle; |
197 | int ret; | ||
198 | 117 | ||
199 | dhandle = ACPI_HANDLE(&pdev->dev); | 118 | dhandle = ACPI_HANDLE(&pdev->dev); |
200 | if (!dhandle) | 119 | if (!dhandle) |
201 | return false; | 120 | return false; |
202 | 121 | ||
203 | if (!acpi_has_method(dhandle, "_DSM")) { | 122 | if (!acpi_check_dsm(dhandle, intel_dsm_guid, INTEL_DSM_REVISION_ID, |
123 | 1 << INTEL_DSM_FN_PLATFORM_MUX_INFO)) { | ||
204 | DRM_DEBUG_KMS("no _DSM method for intel device\n"); | 124 | DRM_DEBUG_KMS("no _DSM method for intel device\n"); |
205 | return false; | 125 | return false; |
206 | } | 126 | } |
207 | 127 | ||
208 | ret = intel_dsm(dhandle, INTEL_DSM_FN_SUPPORTED_FUNCTIONS); | ||
209 | if (ret < 0) { | ||
210 | DRM_DEBUG_KMS("failed to get supported _DSM functions\n"); | ||
211 | return false; | ||
212 | } | ||
213 | |||
214 | intel_dsm_priv.dhandle = dhandle; | 128 | intel_dsm_priv.dhandle = dhandle; |
215 | |||
216 | intel_dsm_platform_mux_info(); | 129 | intel_dsm_platform_mux_info(); |
130 | |||
217 | return true; | 131 | return true; |
218 | } | 132 | } |
219 | 133 | ||