diff options
| -rw-r--r-- | drivers/gpu/drm/i915/intel_acpi.c | 144 |
1 files changed, 30 insertions, 114 deletions
diff --git a/drivers/gpu/drm/i915/intel_acpi.c b/drivers/gpu/drm/i915/intel_acpi.c index dfff0907f70e..1bfac94adb34 100644 --- a/drivers/gpu/drm/i915/intel_acpi.c +++ b/drivers/gpu/drm/i915/intel_acpi.c | |||
| @@ -12,8 +12,6 @@ | |||
| 12 | #include "i915_drv.h" | 12 | #include "i915_drv.h" |
| 13 | 13 | ||
| 14 | #define INTEL_DSM_REVISION_ID 1 /* For Calpella anyway... */ | 14 | #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 */ | 15 | #define INTEL_DSM_FN_PLATFORM_MUX_INFO 1 /* No args */ |
| 18 | 16 | ||
| 19 | static struct intel_dsm_priv { | 17 | static struct intel_dsm_priv { |
| @@ -28,61 +26,6 @@ static const u8 intel_dsm_guid[] = { | |||
| 28 | 0x0f, 0x13, 0x17, 0xb0, 0x1c, 0x2c | 26 | 0x0f, 0x13, 0x17, 0xb0, 0x1c, 0x2c |
| 29 | }; | 27 | }; |
| 30 | 28 | ||
| 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) | 29 | static char *intel_dsm_port_name(u8 id) |
| 87 | { | 30 | { |
| 88 | switch (id) { | 31 | switch (id) { |
| @@ -137,83 +80,56 @@ static char *intel_dsm_mux_type(u8 type) | |||
| 137 | 80 | ||
| 138 | static void intel_dsm_platform_mux_info(void) | 81 | static void intel_dsm_platform_mux_info(void) |
| 139 | { | 82 | { |
| 140 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; | 83 | int i; |
| 141 | struct acpi_object_list input; | 84 | union acpi_object *pkg, *connector_count; |
| 142 | union acpi_object params[4]; | 85 | |
| 143 | union acpi_object *pkg; | 86 | pkg = acpi_evaluate_dsm_typed(intel_dsm_priv.dhandle, intel_dsm_guid, |
| 144 | int i, ret; | 87 | INTEL_DSM_REVISION_ID, INTEL_DSM_FN_PLATFORM_MUX_INFO, |
| 145 | 88 | NULL, ACPI_TYPE_PACKAGE); | |
| 146 | input.count = 4; | 89 | if (!pkg) { |
| 147 | input.pointer = params; | 90 | DRM_DEBUG_DRIVER("failed to evaluate _DSM\n"); |
| 148 | params[0].type = ACPI_TYPE_BUFFER; | 91 | 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 | } | 92 | } |
| 165 | 93 | ||
| 166 | pkg = (union acpi_object *)output.pointer; | 94 | connector_count = &pkg->package.elements[0]; |
| 167 | 95 | DRM_DEBUG_DRIVER("MUX info connectors: %lld\n", | |
| 168 | if (pkg->type == ACPI_TYPE_PACKAGE) { | 96 | (unsigned long long)connector_count->integer.value); |
| 169 | union acpi_object *connector_count = &pkg->package.elements[0]; | 97 | for (i = 1; i < pkg->package.count; i++) { |
| 170 | DRM_DEBUG_DRIVER("MUX info connectors: %lld\n", | 98 | union acpi_object *obj = &pkg->package.elements[i]; |
| 171 | (unsigned long long)connector_count->integer.value); | 99 | union acpi_object *connector_id = &obj->package.elements[0]; |
| 172 | for (i = 1; i < pkg->package.count; i++) { | 100 | union acpi_object *info = &obj->package.elements[1]; |
| 173 | union acpi_object *obj = &pkg->package.elements[i]; | 101 | DRM_DEBUG_DRIVER("Connector id: 0x%016llx\n", |
| 174 | union acpi_object *connector_id = | 102 | (unsigned long long)connector_id->integer.value); |
| 175 | &obj->package.elements[0]; | 103 | DRM_DEBUG_DRIVER(" port id: %s\n", |
| 176 | union acpi_object *info = &obj->package.elements[1]; | 104 | intel_dsm_port_name(info->buffer.pointer[0])); |
| 177 | DRM_DEBUG_DRIVER("Connector id: 0x%016llx\n", | 105 | DRM_DEBUG_DRIVER(" display mux info: %s\n", |
| 178 | (unsigned long long)connector_id->integer.value); | 106 | intel_dsm_mux_type(info->buffer.pointer[1])); |
| 179 | DRM_DEBUG_DRIVER(" port id: %s\n", | 107 | DRM_DEBUG_DRIVER(" aux/dc mux info: %s\n", |
| 180 | intel_dsm_port_name(info->buffer.pointer[0])); | 108 | intel_dsm_mux_type(info->buffer.pointer[2])); |
| 181 | DRM_DEBUG_DRIVER(" display mux info: %s\n", | 109 | DRM_DEBUG_DRIVER(" hpd mux info: %s\n", |
| 182 | intel_dsm_mux_type(info->buffer.pointer[1])); | 110 | 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 | } | 111 | } |
| 189 | 112 | ||
| 190 | out: | 113 | ACPI_FREE(pkg); |
| 191 | kfree(output.pointer); | ||
| 192 | } | 114 | } |
| 193 | 115 | ||
| 194 | static bool intel_dsm_pci_probe(struct pci_dev *pdev) | 116 | static bool intel_dsm_pci_probe(struct pci_dev *pdev) |
| 195 | { | 117 | { |
| 196 | acpi_handle dhandle; | 118 | acpi_handle dhandle; |
| 197 | int ret; | ||
| 198 | 119 | ||
| 199 | dhandle = ACPI_HANDLE(&pdev->dev); | 120 | dhandle = ACPI_HANDLE(&pdev->dev); |
| 200 | if (!dhandle) | 121 | if (!dhandle) |
| 201 | return false; | 122 | return false; |
| 202 | 123 | ||
| 203 | if (!acpi_has_method(dhandle, "_DSM")) { | 124 | if (!acpi_check_dsm(dhandle, intel_dsm_guid, INTEL_DSM_REVISION_ID, |
| 125 | 1 << INTEL_DSM_FN_PLATFORM_MUX_INFO)) { | ||
| 204 | DRM_DEBUG_KMS("no _DSM method for intel device\n"); | 126 | DRM_DEBUG_KMS("no _DSM method for intel device\n"); |
| 205 | return false; | 127 | return false; |
| 206 | } | 128 | } |
| 207 | 129 | ||
| 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; | 130 | intel_dsm_priv.dhandle = dhandle; |
| 215 | |||
| 216 | intel_dsm_platform_mux_info(); | 131 | intel_dsm_platform_mux_info(); |
| 132 | |||
| 217 | return true; | 133 | return true; |
| 218 | } | 134 | } |
| 219 | 135 | ||
