aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_acpi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_acpi.c')
-rw-r--r--drivers/gpu/drm/i915/intel_acpi.c146
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
19static struct intel_dsm_priv { 15static 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
31static 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
86static char *intel_dsm_port_name(u8 id) 27static 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
138static void intel_dsm_platform_mux_info(void) 79static 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
190out: 111 ACPI_FREE(pkg);
191 kfree(output.pointer);
192} 112}
193 113
194static bool intel_dsm_pci_probe(struct pci_dev *pdev) 114static 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