1 #include <linux/pci.h> 2 #include <linux/acpi.h> 3 #include <linux/slab.h> 4 #include <acpi/acpi_drivers.h> 5 #include <acpi/acpi_bus.h> 6 #include <acpi/video.h> 7 #include <acpi/acpi.h> 8 #include <linux/mxm-wmi.h> 9 10 #include <linux/vga_switcheroo.h> 11 12 #include <drm/drm_edid.h> 13 14 #include "nouveau_drm.h" 15 #include "nouveau_acpi.h" 16 17 #define NOUVEAU_DSM_LED 0x02 18 #define NOUVEAU_DSM_LED_STATE 0x00 19 #define NOUVEAU_DSM_LED_OFF 0x10 20 #define NOUVEAU_DSM_LED_STAMINA 0x11 21 #define NOUVEAU_DSM_LED_SPEED 0x12 22 23 #define NOUVEAU_DSM_POWER 0x03 24 #define NOUVEAU_DSM_POWER_STATE 0x00 25 #define NOUVEAU_DSM_POWER_SPEED 0x01 26 #define NOUVEAU_DSM_POWER_STAMINA 0x02 27 28 #define NOUVEAU_DSM_OPTIMUS_FN 0x1A 29 #define NOUVEAU_DSM_OPTIMUS_ARGS 0x03000001 30 31 static struct nouveau_dsm_priv { 32 bool dsm_detected; 33 bool optimus_detected; 34 acpi_handle dhandle; 35 acpi_handle rom_handle; 36 } nouveau_dsm_priv; 37 38 bool nouveau_is_optimus(void) { 39 return nouveau_dsm_priv.optimus_detected; 40 } 41 42 bool nouveau_is_v1_dsm(void) { 43 return nouveau_dsm_priv.dsm_detected; 44 } 45 46 #define NOUVEAU_DSM_HAS_MUX 0x1 47 #define NOUVEAU_DSM_HAS_OPT 0x2 48 49 static const char nouveau_dsm_muid[] = { 50 0xA0, 0xA0, 0x95, 0x9D, 0x60, 0x00, 0x48, 0x4D, 51 0xB3, 0x4D, 0x7E, 0x5F, 0xEA, 0x12, 0x9F, 0xD4, 52 }; 53 54 static const char nouveau_op_dsm_muid[] = { 55 0xF8, 0xD8, 0x86, 0xA4, 0xDA, 0x0B, 0x1B, 0x47, 56 0xA7, 0x2B, 0x60, 0x42, 0xA6, 0xB5, 0xBE, 0xE0, 57 }; 58 59 static int nouveau_optimus_dsm(acpi_handle handle, int func, int arg, uint32_t *result) 60 { 61 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 62 struct acpi_object_list input; 63 union acpi_object params[4]; 64 union acpi_object *obj; 65 int i, err; 66 char args_buff[4]; 67 68 input.count = 4; 69 input.pointer = params; 70 params[0].type = ACPI_TYPE_BUFFER; 71 params[0].buffer.length = sizeof(nouveau_op_dsm_muid); 72 params[0].buffer.pointer = (char *)nouveau_op_dsm_muid; 73 params[1].type = ACPI_TYPE_INTEGER; 74 params[1].integer.value = 0x00000100; 75 params[2].type = ACPI_TYPE_INTEGER; 76 params[2].integer.value = func; 77 params[3].type = ACPI_TYPE_BUFFER; 78 params[3].buffer.length = 4; 79 /* ACPI is little endian, AABBCCDD becomes {DD,CC,BB,AA} */ 80 for (i = 0; i < 4; i++) 81 args_buff[i] = (arg >> i * 8) & 0xFF; 82 params[3].buffer.pointer = args_buff; 83 84 err = acpi_evaluate_object(handle, "_DSM", &input, &output); 85 if (err) { 86 printk(KERN_INFO "failed to evaluate _DSM: %d\n", err); 87 return err; 88 } 89 90 obj = (union acpi_object *)output.pointer; 91 92 if (obj->type == ACPI_TYPE_INTEGER) 93 if (obj->integer.value == 0x80000002) { 94 return -ENODEV; 95 } 96 97 if (obj->type == ACPI_TYPE_BUFFER) { 98 if (obj->buffer.length == 4 && result) { 99 *result = 0; 100 *result |= obj->buffer.pointer[0]; 101 *result |= (obj->buffer.pointer[1] << 8); 102 *result |= (obj->buffer.pointer[2] << 16); 103 *result |= (obj->buffer.pointer[3] << 24); 104 } 105 } 106 107 kfree(output.pointer); 108 return 0; 109 } 110 111 static int nouveau_dsm(acpi_handle handle, int func, int arg, uint32_t *result) 112 { 113 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 114 struct acpi_object_list input; 115 union acpi_object params[4]; 116 union acpi_object *obj; 117 int err; 118 119 input.count = 4; 120 input.pointer = params; 121 params[0].type = ACPI_TYPE_BUFFER; 122 params[0].buffer.length = sizeof(nouveau_dsm_muid); 123 params[0].buffer.pointer = (char *)nouveau_dsm_muid; 124 params[1].type = ACPI_TYPE_INTEGER; 125 params[1].integer.value = 0x00000102; 126 params[2].type = ACPI_TYPE_INTEGER; 127 params[2].integer.value = func; 128 params[3].type = ACPI_TYPE_INTEGER; 129 params[3].integer.value = arg; 130 131 err = acpi_evaluate_object(handle, "_DSM", &input, &output); 132 if (err) { 133 printk(KERN_INFO "failed to evaluate _DSM: %d\n", err); 134 return err; 135 } 136 137 obj = (union acpi_object *)output.pointer; 138 139 if (obj->type == ACPI_TYPE_INTEGER) 140 if (obj->integer.value == 0x80000002) 141 return -ENODEV; 142 143 if (obj->type == ACPI_TYPE_BUFFER) { 144 if (obj->buffer.length == 4 && result) { 145 *result = 0; 146 *result |= obj->buffer.pointer[0]; 147 *result |= (obj->buffer.pointer[1] << 8); 148 *result |= (obj->buffer.pointer[2] << 16); 149 *result |= (obj->buffer.pointer[3] << 24); 150 } 151 } 152 153 kfree(output.pointer); 154 return 0; 155 } 156 157 /* Returns 1 if a DSM function is usable and 0 otherwise */ 158 static int nouveau_test_dsm(acpi_handle test_handle, 159 int (*dsm_func)(acpi_handle, int, int, uint32_t *), 160 int sfnc) 161 { 162 u32 result = 0; 163 164 /* Function 0 returns a Buffer containing available functions. The args 165 * parameter is ignored for function 0, so just put 0 in it */ 166 if (dsm_func(test_handle, 0, 0, &result)) 167 return 0; 168 169 /* ACPI Spec v4 9.14.1: if bit 0 is zero, no function is supported. If 170 * the n-th bit is enabled, function n is supported */ 171 return result & 1 && result & (1 << sfnc); 172 } 173 174 static int nouveau_dsm_switch_mux(acpi_handle handle, int mux_id) 175 { 176 mxm_wmi_call_mxmx(mux_id == NOUVEAU_DSM_LED_STAMINA ? MXM_MXDS_ADAPTER_IGD : MXM_MXDS_ADAPTER_0); 177 mxm_wmi_call_mxds(mux_id == NOUVEAU_DSM_LED_STAMINA ? MXM_MXDS_ADAPTER_IGD : MXM_MXDS_ADAPTER_0); 178 return nouveau_dsm(handle, NOUVEAU_DSM_LED, mux_id, NULL); 179 } 180 181 static int nouveau_dsm_set_discrete_state(acpi_handle handle, enum vga_switcheroo_state state) 182 { 183 int arg; 184 if (state == VGA_SWITCHEROO_ON) 185 arg = NOUVEAU_DSM_POWER_SPEED; 186 else 187 arg = NOUVEAU_DSM_POWER_STAMINA; 188 nouveau_dsm(handle, NOUVEAU_DSM_POWER, arg, NULL); 189 return 0; 190 } 191 192 static int nouveau_dsm_switchto(enum vga_switcheroo_client_id id) 193 { 194 if (!nouveau_dsm_priv.dsm_detected) 195 return 0; 196 if (id == VGA_SWITCHEROO_IGD) 197 return nouveau_dsm_switch_mux(nouveau_dsm_priv.dhandle, NOUVEAU_DSM_LED_STAMINA); 198 else 199 return nouveau_dsm_switch_mux(nouveau_dsm_priv.dhandle, NOUVEAU_DSM_LED_SPEED); 200 } 201 202 static int nouveau_dsm_power_state(enum vga_switcheroo_client_id id, 203 enum vga_switcheroo_state state) 204 { 205 if (id == VGA_SWITCHEROO_IGD) 206 return 0; 207 208 /* Optimus laptops have the card already disabled in 209 * nouveau_switcheroo_set_state */ 210 if (!nouveau_dsm_priv.dsm_detected) 211 return 0; 212 213 return nouveau_dsm_set_discrete_state(nouveau_dsm_priv.dhandle, state); 214 } 215 216 static int nouveau_dsm_get_client_id(struct pci_dev *pdev) 217 { 218 /* easy option one - intel vendor ID means Integrated */ 219 if (pdev->vendor == PCI_VENDOR_ID_INTEL) 220 return VGA_SWITCHEROO_IGD; 221 222 /* is this device on Bus 0? - this may need improving */ 223 if (pdev->bus->number == 0) 224 return VGA_SWITCHEROO_IGD; 225 226 return VGA_SWITCHEROO_DIS; 227 } 228 229 static struct vga_switcheroo_handler nouveau_dsm_handler = { 230 .switchto = nouveau_dsm_switchto, 231 .power_state = nouveau_dsm_power_state, 232 .get_client_id = nouveau_dsm_get_client_id, 233 }; 234 235 static int nouveau_dsm_pci_probe(struct pci_dev *pdev) 236 { 237 acpi_handle dhandle, nvidia_handle; 238 acpi_status status; 239 int retval = 0; 240 241 dhandle = DEVICE_ACPI_HANDLE(&pdev->dev); 242 if (!dhandle) 243 return false; 244 245 status = acpi_get_handle(dhandle, "_DSM", &nvidia_handle); 246 if (ACPI_FAILURE(status)) { 247 return false; 248 } 249 250 if (nouveau_test_dsm(dhandle, nouveau_dsm, NOUVEAU_DSM_POWER)) 251 retval |= NOUVEAU_DSM_HAS_MUX; 252 253 if (nouveau_test_dsm(dhandle, nouveau_optimus_dsm, 254 NOUVEAU_DSM_OPTIMUS_FN)) 255 retval |= NOUVEAU_DSM_HAS_OPT; 256 257 if (retval) 258 nouveau_dsm_priv.dhandle = dhandle; 259 260 return retval; 261 } 262 263 static bool nouveau_dsm_detect(void) 264 { 265 char acpi_method_name[255] = { 0 }; 266 struct acpi_buffer buffer = {sizeof(acpi_method_name), acpi_method_name}; 267 struct pci_dev *pdev = NULL; 268 int has_dsm = 0; 269 int has_optimus = 0; 270 int vga_count = 0; 271 bool guid_valid; 272 int retval; 273 bool ret = false; 274 275 /* lookup the MXM GUID */ 276 guid_valid = mxm_wmi_supported(); 277 278 if (guid_valid) 279 printk("MXM: GUID detected in BIOS\n"); 280 281 /* now do DSM detection */ 282 while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) { 283 vga_count++; 284 285 retval = nouveau_dsm_pci_probe(pdev); 286 if (retval & NOUVEAU_DSM_HAS_MUX) 287 has_dsm |= 1; 288 if (retval & NOUVEAU_DSM_HAS_OPT) 289 has_optimus = 1; 290 } 291 292 /* find the optimus DSM or the old v1 DSM */ 293 if (has_optimus == 1) { 294 acpi_get_name(nouveau_dsm_priv.dhandle, ACPI_FULL_PATHNAME, 295 &buffer); 296 printk(KERN_INFO "VGA switcheroo: detected Optimus DSM method %s handle\n", 297 acpi_method_name); 298 nouveau_dsm_priv.optimus_detected = true; 299 ret = true; 300 } else if (vga_count == 2 && has_dsm && guid_valid) { 301 acpi_get_name(nouveau_dsm_priv.dhandle, ACPI_FULL_PATHNAME, 302 &buffer); 303 printk(KERN_INFO "VGA switcheroo: detected DSM switching method %s handle\n", 304 acpi_method_name); 305 nouveau_dsm_priv.dsm_detected = true; 306 ret = true; 307 } 308 309 310 return ret; 311 } 312 313 void nouveau_register_dsm_handler(void) 314 { 315 bool r; 316 317 r = nouveau_dsm_detect(); 318 if (!r) 319 return; 320 321 vga_switcheroo_register_handler(&nouveau_dsm_handler); 322 } 323 324 /* Must be called for Optimus models before the card can be turned off */ 325 void nouveau_switcheroo_optimus_dsm(void) 326 { 327 u32 result = 0; 328 if (!nouveau_dsm_priv.optimus_detected) 329 return; 330 331 nouveau_optimus_dsm(nouveau_dsm_priv.dhandle, NOUVEAU_DSM_OPTIMUS_FN, 332 NOUVEAU_DSM_OPTIMUS_ARGS, &result); 333 } 334 335 void nouveau_unregister_dsm_handler(void) 336 { 337 if (nouveau_dsm_priv.optimus_detected || nouveau_dsm_priv.dsm_detected) 338 vga_switcheroo_unregister_handler(); 339 } 340 341 /* retrieve the ROM in 4k blocks */ 342 static int nouveau_rom_call(acpi_handle rom_handle, uint8_t *bios, 343 int offset, int len) 344 { 345 acpi_status status; 346 union acpi_object rom_arg_elements[2], *obj; 347 struct acpi_object_list rom_arg; 348 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL}; 349 350 rom_arg.count = 2; 351 rom_arg.pointer = &rom_arg_elements[0]; 352 353 rom_arg_elements[0].type = ACPI_TYPE_INTEGER; 354 rom_arg_elements[0].integer.value = offset; 355 356 rom_arg_elements[1].type = ACPI_TYPE_INTEGER; 357 rom_arg_elements[1].integer.value = len; 358 359 status = acpi_evaluate_object(rom_handle, NULL, &rom_arg, &buffer); 360 if (ACPI_FAILURE(status)) { 361 printk(KERN_INFO "failed to evaluate ROM got %s\n", acpi_format_exception(status)); 362 return -ENODEV; 363 } 364 obj = (union acpi_object *)buffer.pointer; 365 memcpy(bios+offset, obj->buffer.pointer, len); 366 kfree(buffer.pointer); 367 return len; 368 } 369 370 bool nouveau_acpi_rom_supported(struct pci_dev *pdev) 371 { 372 acpi_status status; 373 acpi_handle dhandle, rom_handle; 374 375 if (!nouveau_dsm_priv.dsm_detected && !nouveau_dsm_priv.optimus_detected) 376 return false; 377 378 dhandle = DEVICE_ACPI_HANDLE(&pdev->dev); 379 if (!dhandle) 380 return false; 381 382 status = acpi_get_handle(dhandle, "_ROM", &rom_handle); 383 if (ACPI_FAILURE(status)) 384 return false; 385 386 nouveau_dsm_priv.rom_handle = rom_handle; 387 return true; 388 } 389 390 int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len) 391 { 392 return nouveau_rom_call(nouveau_dsm_priv.rom_handle, bios, offset, len); 393 } 394 395 void * 396 nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector) 397 { 398 struct acpi_device *acpidev; 399 acpi_handle handle; 400 int type, ret; 401 void *edid; 402 403 switch (connector->connector_type) { 404 case DRM_MODE_CONNECTOR_LVDS: 405 case DRM_MODE_CONNECTOR_eDP: 406 type = ACPI_VIDEO_DISPLAY_LCD; 407 break; 408 default: 409 return NULL; 410 } 411 412 handle = DEVICE_ACPI_HANDLE(&dev->pdev->dev); 413 if (!handle) 414 return NULL; 415 416 ret = acpi_bus_get_device(handle, &acpidev); 417 if (ret) 418 return NULL; 419 420 ret = acpi_video_get_edid(acpidev, type, -1, &edid); 421 if (ret < 0) 422 return NULL; 423 424 return kmemdup(edid, EDID_LENGTH, GFP_KERNEL); 425 } 426