1 /* 2 * Copyright 2008 Intel Corporation <hong.liu@intel.com> 3 * Copyright 2008 Red Hat <mjg@redhat.com> 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining 6 * a copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sub license, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the 14 * next paragraph) shall be included in all copies or substantial 15 * portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 * NON-INFRINGEMENT. IN NO EVENT SHALL INTEL AND/OR ITS SUPPLIERS BE 21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 22 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 * SOFTWARE. 25 * 26 */ 27 28 #include <linux/acpi.h> 29 #include <linux/debugfs.h> 30 #include <linux/dmi.h> 31 #include <linux/iopoll.h> 32 #include <acpi/video.h> 33 34 #include <drm/drm_edid.h> 35 #include <drm/drm_file.h> 36 #include <drm/drm_print.h> 37 38 #include "intel_acpi.h" 39 #include "intel_backlight.h" 40 #include "intel_display_core.h" 41 #include "intel_display_types.h" 42 #include "intel_opregion.h" 43 #include "intel_pci_config.h" 44 45 #define OPREGION_HEADER_OFFSET 0 46 #define OPREGION_ACPI_OFFSET 0x100 47 #define ACPI_CLID 0x01ac /* current lid state indicator */ 48 #define ACPI_CDCK 0x01b0 /* current docking state indicator */ 49 #define OPREGION_SWSCI_OFFSET 0x200 50 #define OPREGION_ASLE_OFFSET 0x300 51 #define OPREGION_VBT_OFFSET 0x400 52 #define OPREGION_ASLE_EXT_OFFSET 0x1C00 53 54 #define OPREGION_SIGNATURE "IntelGraphicsMem" 55 #define MBOX_ACPI BIT(0) /* Mailbox #1 */ 56 #define MBOX_SWSCI BIT(1) /* Mailbox #2 (obsolete from v2.x) */ 57 #define MBOX_ASLE BIT(2) /* Mailbox #3 */ 58 #define MBOX_ASLE_EXT BIT(4) /* Mailbox #5 */ 59 #define MBOX_BACKLIGHT BIT(5) /* Mailbox #2 (valid from v3.x) */ 60 61 #define PCON_HEADLESS_SKU BIT(13) 62 63 struct opregion_header { 64 u8 signature[16]; 65 u32 size; 66 struct { 67 u8 rsvd; 68 u8 revision; 69 u8 minor; 70 u8 major; 71 } __packed over; 72 u8 bios_ver[32]; 73 u8 vbios_ver[16]; 74 u8 driver_ver[16]; 75 u32 mboxes; 76 u32 driver_model; 77 u32 pcon; 78 u8 dver[32]; 79 u8 rsvd[124]; 80 } __packed; 81 82 /* OpRegion mailbox #1: public ACPI methods */ 83 struct opregion_acpi { 84 u32 drdy; /* driver readiness */ 85 u32 csts; /* notification status */ 86 u32 cevt; /* current event */ 87 u8 rsvd1[20]; 88 u32 didl[8]; /* supported display devices ID list */ 89 u32 cpdl[8]; /* currently presented display list */ 90 u32 cadl[8]; /* currently active display list */ 91 u32 nadl[8]; /* next active devices list */ 92 u32 aslp; /* ASL sleep time-out */ 93 u32 tidx; /* toggle table index */ 94 u32 chpd; /* current hotplug enable indicator */ 95 u32 clid; /* current lid state*/ 96 u32 cdck; /* current docking state */ 97 u32 sxsw; /* Sx state resume */ 98 u32 evts; /* ASL supported events */ 99 u32 cnot; /* current OS notification */ 100 u32 nrdy; /* driver status */ 101 u32 did2[7]; /* extended supported display devices ID list */ 102 u32 cpd2[7]; /* extended attached display devices list */ 103 u8 rsvd2[4]; 104 } __packed; 105 106 /* OpRegion mailbox #2: SWSCI */ 107 struct opregion_swsci { 108 u32 scic; /* SWSCI command|status|data */ 109 u32 parm; /* command parameters */ 110 u32 dslp; /* driver sleep time-out */ 111 u8 rsvd[244]; 112 } __packed; 113 114 /* OpRegion mailbox #3: ASLE */ 115 struct opregion_asle { 116 u32 ardy; /* driver readiness */ 117 u32 aslc; /* ASLE interrupt command */ 118 u32 tche; /* technology enabled indicator */ 119 u32 alsi; /* current ALS illuminance reading */ 120 u32 bclp; /* backlight brightness to set */ 121 u32 pfit; /* panel fitting state */ 122 u32 cblv; /* current brightness level */ 123 u16 bclm[20]; /* backlight level duty cycle mapping table */ 124 u32 cpfm; /* current panel fitting mode */ 125 u32 epfm; /* enabled panel fitting modes */ 126 u8 plut[74]; /* panel LUT and identifier */ 127 u32 pfmb; /* PWM freq and min brightness */ 128 u32 cddv; /* color correction default values */ 129 u32 pcft; /* power conservation features */ 130 u32 srot; /* supported rotation angles */ 131 u32 iuer; /* IUER events */ 132 u64 fdss; 133 u32 fdsp; 134 u32 stat; 135 u64 rvda; /* Physical (2.0) or relative from opregion (2.1+) 136 * address of raw VBT data. */ 137 u32 rvds; /* Size of raw vbt data */ 138 u8 rsvd[58]; 139 } __packed; 140 141 /* OpRegion mailbox #5: ASLE ext */ 142 struct opregion_asle_ext { 143 u32 phed; /* Panel Header */ 144 u8 bddc[256]; /* Panel EDID */ 145 u8 rsvd[764]; 146 } __packed; 147 148 /* Driver readiness indicator */ 149 #define ASLE_ARDY_READY (1 << 0) 150 #define ASLE_ARDY_NOT_READY (0 << 0) 151 152 /* ASLE Interrupt Command (ASLC) bits */ 153 #define ASLC_SET_ALS_ILLUM (1 << 0) 154 #define ASLC_SET_BACKLIGHT (1 << 1) 155 #define ASLC_SET_PFIT (1 << 2) 156 #define ASLC_SET_PWM_FREQ (1 << 3) 157 #define ASLC_SUPPORTED_ROTATION_ANGLES (1 << 4) 158 #define ASLC_BUTTON_ARRAY (1 << 5) 159 #define ASLC_CONVERTIBLE_INDICATOR (1 << 6) 160 #define ASLC_DOCKING_INDICATOR (1 << 7) 161 #define ASLC_ISCT_STATE_CHANGE (1 << 8) 162 #define ASLC_REQ_MSK 0x1ff 163 /* response bits */ 164 #define ASLC_ALS_ILLUM_FAILED (1 << 10) 165 #define ASLC_BACKLIGHT_FAILED (1 << 12) 166 #define ASLC_PFIT_FAILED (1 << 14) 167 #define ASLC_PWM_FREQ_FAILED (1 << 16) 168 #define ASLC_ROTATION_ANGLES_FAILED (1 << 18) 169 #define ASLC_BUTTON_ARRAY_FAILED (1 << 20) 170 #define ASLC_CONVERTIBLE_FAILED (1 << 22) 171 #define ASLC_DOCKING_FAILED (1 << 24) 172 #define ASLC_ISCT_STATE_FAILED (1 << 26) 173 174 /* Technology enabled indicator */ 175 #define ASLE_TCHE_ALS_EN (1 << 0) 176 #define ASLE_TCHE_BLC_EN (1 << 1) 177 #define ASLE_TCHE_PFIT_EN (1 << 2) 178 #define ASLE_TCHE_PFMB_EN (1 << 3) 179 180 /* ASLE backlight brightness to set */ 181 #define ASLE_BCLP_VALID (1<<31) 182 #define ASLE_BCLP_MSK (~(1<<31)) 183 184 /* ASLE panel fitting request */ 185 #define ASLE_PFIT_VALID (1<<31) 186 #define ASLE_PFIT_CENTER (1<<0) 187 #define ASLE_PFIT_STRETCH_TEXT (1<<1) 188 #define ASLE_PFIT_STRETCH_GFX (1<<2) 189 190 /* PWM frequency and minimum brightness */ 191 #define ASLE_PFMB_BRIGHTNESS_MASK (0xff) 192 #define ASLE_PFMB_BRIGHTNESS_VALID (1<<8) 193 #define ASLE_PFMB_PWM_MASK (0x7ffffe00) 194 #define ASLE_PFMB_PWM_VALID (1<<31) 195 196 #define ASLE_CBLV_VALID (1<<31) 197 198 /* IUER */ 199 #define ASLE_IUER_DOCKING (1 << 7) 200 #define ASLE_IUER_CONVERTIBLE (1 << 6) 201 #define ASLE_IUER_ROTATION_LOCK_BTN (1 << 4) 202 #define ASLE_IUER_VOLUME_DOWN_BTN (1 << 3) 203 #define ASLE_IUER_VOLUME_UP_BTN (1 << 2) 204 #define ASLE_IUER_WINDOWS_BTN (1 << 1) 205 #define ASLE_IUER_POWER_BTN (1 << 0) 206 207 #define ASLE_PHED_EDID_VALID_MASK 0x3 208 209 /* Software System Control Interrupt (SWSCI) */ 210 #define SWSCI_SCIC_INDICATOR (1 << 0) 211 #define SWSCI_SCIC_MAIN_FUNCTION_SHIFT 1 212 #define SWSCI_SCIC_MAIN_FUNCTION_MASK (0xf << 1) 213 #define SWSCI_SCIC_SUB_FUNCTION_SHIFT 8 214 #define SWSCI_SCIC_SUB_FUNCTION_MASK (0xff << 8) 215 #define SWSCI_SCIC_EXIT_PARAMETER_SHIFT 8 216 #define SWSCI_SCIC_EXIT_PARAMETER_MASK (0xff << 8) 217 #define SWSCI_SCIC_EXIT_STATUS_SHIFT 5 218 #define SWSCI_SCIC_EXIT_STATUS_MASK (7 << 5) 219 #define SWSCI_SCIC_EXIT_STATUS_SUCCESS 1 220 221 #define SWSCI_FUNCTION_CODE(main, sub) \ 222 ((main) << SWSCI_SCIC_MAIN_FUNCTION_SHIFT | \ 223 (sub) << SWSCI_SCIC_SUB_FUNCTION_SHIFT) 224 225 /* SWSCI: Get BIOS Data (GBDA) */ 226 #define SWSCI_GBDA 4 227 #define SWSCI_GBDA_SUPPORTED_CALLS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 0) 228 #define SWSCI_GBDA_REQUESTED_CALLBACKS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 1) 229 #define SWSCI_GBDA_BOOT_DISPLAY_PREF SWSCI_FUNCTION_CODE(SWSCI_GBDA, 4) 230 #define SWSCI_GBDA_PANEL_DETAILS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 5) 231 #define SWSCI_GBDA_TV_STANDARD SWSCI_FUNCTION_CODE(SWSCI_GBDA, 6) 232 #define SWSCI_GBDA_INTERNAL_GRAPHICS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 7) 233 #define SWSCI_GBDA_SPREAD_SPECTRUM SWSCI_FUNCTION_CODE(SWSCI_GBDA, 10) 234 235 /* SWSCI: System BIOS Callbacks (SBCB) */ 236 #define SWSCI_SBCB 6 237 #define SWSCI_SBCB_SUPPORTED_CALLBACKS SWSCI_FUNCTION_CODE(SWSCI_SBCB, 0) 238 #define SWSCI_SBCB_INIT_COMPLETION SWSCI_FUNCTION_CODE(SWSCI_SBCB, 1) 239 #define SWSCI_SBCB_PRE_HIRES_SET_MODE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 3) 240 #define SWSCI_SBCB_POST_HIRES_SET_MODE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 4) 241 #define SWSCI_SBCB_DISPLAY_SWITCH SWSCI_FUNCTION_CODE(SWSCI_SBCB, 5) 242 #define SWSCI_SBCB_SET_TV_FORMAT SWSCI_FUNCTION_CODE(SWSCI_SBCB, 6) 243 #define SWSCI_SBCB_ADAPTER_POWER_STATE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 7) 244 #define SWSCI_SBCB_DISPLAY_POWER_STATE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 8) 245 #define SWSCI_SBCB_SET_BOOT_DISPLAY SWSCI_FUNCTION_CODE(SWSCI_SBCB, 9) 246 #define SWSCI_SBCB_SET_PANEL_DETAILS SWSCI_FUNCTION_CODE(SWSCI_SBCB, 10) 247 #define SWSCI_SBCB_SET_INTERNAL_GFX SWSCI_FUNCTION_CODE(SWSCI_SBCB, 11) 248 #define SWSCI_SBCB_POST_HIRES_TO_DOS_FS SWSCI_FUNCTION_CODE(SWSCI_SBCB, 16) 249 #define SWSCI_SBCB_SUSPEND_RESUME SWSCI_FUNCTION_CODE(SWSCI_SBCB, 17) 250 #define SWSCI_SBCB_SET_SPREAD_SPECTRUM SWSCI_FUNCTION_CODE(SWSCI_SBCB, 18) 251 #define SWSCI_SBCB_POST_VBE_PM SWSCI_FUNCTION_CODE(SWSCI_SBCB, 19) 252 #define SWSCI_SBCB_ENABLE_DISABLE_AUDIO SWSCI_FUNCTION_CODE(SWSCI_SBCB, 21) 253 254 #define MAX_DSLP 1500 255 256 #define OPREGION_SIZE (8 * 1024) 257 258 struct intel_opregion { 259 struct intel_display *display; 260 261 struct opregion_header *header; 262 struct opregion_acpi *acpi; 263 struct opregion_swsci *swsci; 264 u32 swsci_gbda_sub_functions; 265 u32 swsci_sbcb_sub_functions; 266 struct opregion_asle *asle; 267 struct opregion_asle_ext *asle_ext; 268 void *rvda; 269 const void *vbt; 270 u32 vbt_size; 271 struct work_struct asle_work; 272 struct notifier_block acpi_notifier; 273 }; 274 275 static int check_swsci_function(struct intel_display *display, u32 function) 276 { 277 struct intel_opregion *opregion = display->opregion; 278 struct opregion_swsci *swsci; 279 u32 main_function, sub_function; 280 281 if (!opregion) 282 return -ENODEV; 283 284 swsci = opregion->swsci; 285 if (!swsci) 286 return -ENODEV; 287 288 main_function = (function & SWSCI_SCIC_MAIN_FUNCTION_MASK) >> 289 SWSCI_SCIC_MAIN_FUNCTION_SHIFT; 290 sub_function = (function & SWSCI_SCIC_SUB_FUNCTION_MASK) >> 291 SWSCI_SCIC_SUB_FUNCTION_SHIFT; 292 293 /* Check if we can call the function. See swsci_setup for details. */ 294 if (main_function == SWSCI_SBCB) { 295 if ((opregion->swsci_sbcb_sub_functions & 296 (1 << sub_function)) == 0) 297 return -EINVAL; 298 } else if (main_function == SWSCI_GBDA) { 299 if ((opregion->swsci_gbda_sub_functions & 300 (1 << sub_function)) == 0) 301 return -EINVAL; 302 } 303 304 return 0; 305 } 306 307 static int swsci(struct intel_display *display, 308 u32 function, u32 parm, u32 *parm_out) 309 { 310 struct opregion_swsci *swsci; 311 struct pci_dev *pdev = to_pci_dev(display->drm->dev); 312 u32 scic, dslp; 313 u16 swsci_val; 314 int ret; 315 316 ret = check_swsci_function(display, function); 317 if (ret) 318 return ret; 319 320 swsci = display->opregion->swsci; 321 322 /* Driver sleep timeout in ms. */ 323 dslp = swsci->dslp; 324 if (!dslp) { 325 /* The spec says 2ms should be the default, but it's too small 326 * for some machines. */ 327 dslp = 50; 328 } else if (dslp > MAX_DSLP) { 329 /* Hey bios, trust must be earned. */ 330 DRM_INFO_ONCE("ACPI BIOS requests an excessive sleep of %u ms, " 331 "using %u ms instead\n", dslp, MAX_DSLP); 332 dslp = MAX_DSLP; 333 } 334 335 /* The spec tells us to do this, but we are the only user... */ 336 scic = swsci->scic; 337 if (scic & SWSCI_SCIC_INDICATOR) { 338 drm_dbg(display->drm, "SWSCI request already in progress\n"); 339 return -EBUSY; 340 } 341 342 scic = function | SWSCI_SCIC_INDICATOR; 343 344 swsci->parm = parm; 345 swsci->scic = scic; 346 347 /* Ensure SCI event is selected and event trigger is cleared. */ 348 pci_read_config_word(pdev, SWSCI, &swsci_val); 349 if (!(swsci_val & SWSCI_SCISEL) || (swsci_val & SWSCI_GSSCIE)) { 350 swsci_val |= SWSCI_SCISEL; 351 swsci_val &= ~SWSCI_GSSCIE; 352 pci_write_config_word(pdev, SWSCI, swsci_val); 353 } 354 355 /* Use event trigger to tell bios to check the mail. */ 356 swsci_val |= SWSCI_GSSCIE; 357 pci_write_config_word(pdev, SWSCI, swsci_val); 358 359 /* Poll for the result. */ 360 ret = poll_timeout_us(scic = swsci->scic, 361 (scic & SWSCI_SCIC_INDICATOR) == 0, 362 1000, dslp * 1000, false); 363 if (ret) { 364 drm_dbg(display->drm, "SWSCI request timed out\n"); 365 return ret; 366 } 367 368 scic = (scic & SWSCI_SCIC_EXIT_STATUS_MASK) >> 369 SWSCI_SCIC_EXIT_STATUS_SHIFT; 370 371 /* Note: scic == 0 is an error! */ 372 if (scic != SWSCI_SCIC_EXIT_STATUS_SUCCESS) { 373 drm_dbg(display->drm, "SWSCI request error %u\n", scic); 374 return -EIO; 375 } 376 377 if (parm_out) 378 *parm_out = swsci->parm; 379 380 return 0; 381 382 #undef C 383 } 384 385 #define DISPLAY_TYPE_CRT 0 386 #define DISPLAY_TYPE_TV 1 387 #define DISPLAY_TYPE_EXTERNAL_FLAT_PANEL 2 388 #define DISPLAY_TYPE_INTERNAL_FLAT_PANEL 3 389 390 int intel_opregion_notify_encoder(struct intel_encoder *encoder, 391 bool enable) 392 { 393 struct intel_display *display = to_intel_display(encoder); 394 u32 parm = 0; 395 u32 type = 0; 396 u32 port; 397 int ret; 398 399 /* don't care about old stuff for now */ 400 if (!HAS_DDI(display)) 401 return 0; 402 403 /* Avoid port out of bounds checks if SWSCI isn't there. */ 404 ret = check_swsci_function(display, SWSCI_SBCB_DISPLAY_POWER_STATE); 405 if (ret) 406 return ret; 407 408 if (encoder->type == INTEL_OUTPUT_DSI) 409 port = 0; 410 else 411 port = encoder->port; 412 413 if (port == PORT_E) { 414 port = 0; 415 } else { 416 parm |= 1 << port; 417 port++; 418 } 419 420 /* 421 * The port numbering and mapping here is bizarre. The now-obsolete 422 * swsci spec supports ports numbered [0..4]. Port E is handled as a 423 * special case, but port F and beyond are not. The functionality is 424 * supposed to be obsolete for new platforms. Just bail out if the port 425 * number is out of bounds after mapping. 426 */ 427 if (port > 4) { 428 drm_dbg_kms(display->drm, 429 "[ENCODER:%d:%s] port %c (index %u) out of bounds for display power state notification\n", 430 encoder->base.base.id, encoder->base.name, 431 port_name(encoder->port), port); 432 return -EINVAL; 433 } 434 435 if (!enable) 436 parm |= 4 << 8; 437 438 switch (encoder->type) { 439 case INTEL_OUTPUT_ANALOG: 440 type = DISPLAY_TYPE_CRT; 441 break; 442 case INTEL_OUTPUT_DDI: 443 case INTEL_OUTPUT_DP: 444 case INTEL_OUTPUT_HDMI: 445 case INTEL_OUTPUT_DP_MST: 446 type = DISPLAY_TYPE_EXTERNAL_FLAT_PANEL; 447 break; 448 case INTEL_OUTPUT_EDP: 449 case INTEL_OUTPUT_DSI: 450 type = DISPLAY_TYPE_INTERNAL_FLAT_PANEL; 451 break; 452 default: 453 drm_WARN_ONCE(display->drm, 1, 454 "unsupported intel_encoder type %d\n", 455 encoder->type); 456 return -EINVAL; 457 } 458 459 parm |= type << (16 + port * 3); 460 461 return swsci(display, SWSCI_SBCB_DISPLAY_POWER_STATE, parm, NULL); 462 } 463 464 static const struct { 465 pci_power_t pci_power_state; 466 u32 parm; 467 } power_state_map[] = { 468 { PCI_D0, 0x00 }, 469 { PCI_D1, 0x01 }, 470 { PCI_D2, 0x02 }, 471 { PCI_D3hot, 0x04 }, 472 { PCI_D3cold, 0x04 }, 473 }; 474 475 int intel_opregion_notify_adapter(struct intel_display *display, 476 pci_power_t state) 477 { 478 int i; 479 480 if (!HAS_DDI(display)) 481 return 0; 482 483 for (i = 0; i < ARRAY_SIZE(power_state_map); i++) { 484 if (state == power_state_map[i].pci_power_state) 485 return swsci(display, SWSCI_SBCB_ADAPTER_POWER_STATE, 486 power_state_map[i].parm, NULL); 487 } 488 489 return -EINVAL; 490 } 491 492 static u32 asle_set_backlight(struct intel_display *display, u32 bclp) 493 { 494 struct intel_connector *connector; 495 struct drm_connector_list_iter conn_iter; 496 struct opregion_asle *asle = display->opregion->asle; 497 498 drm_dbg(display->drm, "bclp = 0x%08x\n", bclp); 499 500 if (acpi_video_get_backlight_type() == acpi_backlight_native) { 501 drm_dbg_kms(display->drm, 502 "opregion backlight request ignored\n"); 503 return 0; 504 } 505 506 if (!(bclp & ASLE_BCLP_VALID)) 507 return ASLC_BACKLIGHT_FAILED; 508 509 bclp &= ASLE_BCLP_MSK; 510 if (bclp > 255) 511 return ASLC_BACKLIGHT_FAILED; 512 513 drm_modeset_lock(&display->drm->mode_config.connection_mutex, NULL); 514 515 /* 516 * Update backlight on all connectors that support backlight (usually 517 * only one). 518 */ 519 drm_dbg_kms(display->drm, "updating opregion backlight %d/255\n", 520 bclp); 521 drm_connector_list_iter_begin(display->drm, &conn_iter); 522 for_each_intel_connector_iter(connector, &conn_iter) 523 intel_backlight_set_acpi(connector->base.state, bclp, 255); 524 drm_connector_list_iter_end(&conn_iter); 525 asle->cblv = DIV_ROUND_UP(bclp * 100, 255) | ASLE_CBLV_VALID; 526 527 drm_modeset_unlock(&display->drm->mode_config.connection_mutex); 528 529 530 return 0; 531 } 532 533 static u32 asle_set_als_illum(struct intel_display *display, u32 alsi) 534 { 535 /* alsi is the current ALS reading in lux. 0 indicates below sensor 536 range, 0xffff indicates above sensor range. 1-0xfffe are valid */ 537 drm_dbg(display->drm, "Illum is not supported\n"); 538 return ASLC_ALS_ILLUM_FAILED; 539 } 540 541 static u32 asle_set_pwm_freq(struct intel_display *display, u32 pfmb) 542 { 543 drm_dbg(display->drm, "PWM freq is not supported\n"); 544 return ASLC_PWM_FREQ_FAILED; 545 } 546 547 static u32 asle_set_pfit(struct intel_display *display, u32 pfit) 548 { 549 /* Panel fitting is currently controlled by the X code, so this is a 550 noop until modesetting support works fully */ 551 drm_dbg(display->drm, "Pfit is not supported\n"); 552 return ASLC_PFIT_FAILED; 553 } 554 555 static u32 asle_set_supported_rotation_angles(struct intel_display *display, u32 srot) 556 { 557 drm_dbg(display->drm, "SROT is not supported\n"); 558 return ASLC_ROTATION_ANGLES_FAILED; 559 } 560 561 static u32 asle_set_button_array(struct intel_display *display, u32 iuer) 562 { 563 if (!iuer) 564 drm_dbg(display->drm, 565 "Button array event is not supported (nothing)\n"); 566 if (iuer & ASLE_IUER_ROTATION_LOCK_BTN) 567 drm_dbg(display->drm, 568 "Button array event is not supported (rotation lock)\n"); 569 if (iuer & ASLE_IUER_VOLUME_DOWN_BTN) 570 drm_dbg(display->drm, 571 "Button array event is not supported (volume down)\n"); 572 if (iuer & ASLE_IUER_VOLUME_UP_BTN) 573 drm_dbg(display->drm, 574 "Button array event is not supported (volume up)\n"); 575 if (iuer & ASLE_IUER_WINDOWS_BTN) 576 drm_dbg(display->drm, 577 "Button array event is not supported (windows)\n"); 578 if (iuer & ASLE_IUER_POWER_BTN) 579 drm_dbg(display->drm, 580 "Button array event is not supported (power)\n"); 581 582 return ASLC_BUTTON_ARRAY_FAILED; 583 } 584 585 static u32 asle_set_convertible(struct intel_display *display, u32 iuer) 586 { 587 if (iuer & ASLE_IUER_CONVERTIBLE) 588 drm_dbg(display->drm, 589 "Convertible is not supported (clamshell)\n"); 590 else 591 drm_dbg(display->drm, 592 "Convertible is not supported (slate)\n"); 593 594 return ASLC_CONVERTIBLE_FAILED; 595 } 596 597 static u32 asle_set_docking(struct intel_display *display, u32 iuer) 598 { 599 if (iuer & ASLE_IUER_DOCKING) 600 drm_dbg(display->drm, "Docking is not supported (docked)\n"); 601 else 602 drm_dbg(display->drm, 603 "Docking is not supported (undocked)\n"); 604 605 return ASLC_DOCKING_FAILED; 606 } 607 608 static u32 asle_isct_state(struct intel_display *display) 609 { 610 drm_dbg(display->drm, "ISCT is not supported\n"); 611 return ASLC_ISCT_STATE_FAILED; 612 } 613 614 static void asle_work(struct work_struct *work) 615 { 616 struct intel_opregion *opregion = 617 container_of(work, struct intel_opregion, asle_work); 618 struct intel_display *display = opregion->display; 619 struct opregion_asle *asle = opregion->asle; 620 u32 aslc_stat = 0; 621 u32 aslc_req; 622 623 if (!asle) 624 return; 625 626 aslc_req = asle->aslc; 627 628 if (!(aslc_req & ASLC_REQ_MSK)) { 629 drm_dbg(display->drm, 630 "No request on ASLC interrupt 0x%08x\n", aslc_req); 631 return; 632 } 633 634 if (aslc_req & ASLC_SET_ALS_ILLUM) 635 aslc_stat |= asle_set_als_illum(display, asle->alsi); 636 637 if (aslc_req & ASLC_SET_BACKLIGHT) 638 aslc_stat |= asle_set_backlight(display, asle->bclp); 639 640 if (aslc_req & ASLC_SET_PFIT) 641 aslc_stat |= asle_set_pfit(display, asle->pfit); 642 643 if (aslc_req & ASLC_SET_PWM_FREQ) 644 aslc_stat |= asle_set_pwm_freq(display, asle->pfmb); 645 646 if (aslc_req & ASLC_SUPPORTED_ROTATION_ANGLES) 647 aslc_stat |= asle_set_supported_rotation_angles(display, 648 asle->srot); 649 650 if (aslc_req & ASLC_BUTTON_ARRAY) 651 aslc_stat |= asle_set_button_array(display, asle->iuer); 652 653 if (aslc_req & ASLC_CONVERTIBLE_INDICATOR) 654 aslc_stat |= asle_set_convertible(display, asle->iuer); 655 656 if (aslc_req & ASLC_DOCKING_INDICATOR) 657 aslc_stat |= asle_set_docking(display, asle->iuer); 658 659 if (aslc_req & ASLC_ISCT_STATE_CHANGE) 660 aslc_stat |= asle_isct_state(display); 661 662 asle->aslc = aslc_stat; 663 } 664 665 bool intel_opregion_asle_present(struct intel_display *display) 666 { 667 return display->opregion && display->opregion->asle; 668 } 669 670 void intel_opregion_asle_intr(struct intel_display *display) 671 { 672 struct intel_opregion *opregion = display->opregion; 673 674 if (opregion && opregion->asle) 675 queue_work(display->wq.unordered, &opregion->asle_work); 676 } 677 678 #define ACPI_EV_DISPLAY_SWITCH (1<<0) 679 #define ACPI_EV_LID (1<<1) 680 #define ACPI_EV_DOCK (1<<2) 681 682 /* 683 * The only video events relevant to opregion are 0x80. These indicate either a 684 * docking event, lid switch or display switch request. In Linux, these are 685 * handled by the dock, button and video drivers. 686 */ 687 static int intel_opregion_video_event(struct notifier_block *nb, 688 unsigned long val, void *data) 689 { 690 struct intel_opregion *opregion = container_of(nb, struct intel_opregion, 691 acpi_notifier); 692 struct acpi_bus_event *event = data; 693 struct opregion_acpi *acpi; 694 int ret = NOTIFY_OK; 695 696 if (strcmp(event->device_class, ACPI_VIDEO_CLASS) != 0) 697 return NOTIFY_DONE; 698 699 acpi = opregion->acpi; 700 701 if (event->type == 0x80 && ((acpi->cevt & 1) == 0)) 702 ret = NOTIFY_BAD; 703 704 acpi->csts = 0; 705 706 return ret; 707 } 708 709 /* 710 * Initialise the DIDL field in opregion. This passes a list of devices to 711 * the firmware. Values are defined by section B.4.2 of the ACPI specification 712 * (version 3) 713 */ 714 715 static void set_did(struct intel_opregion *opregion, int i, u32 val) 716 { 717 if (i < ARRAY_SIZE(opregion->acpi->didl)) { 718 opregion->acpi->didl[i] = val; 719 } else { 720 i -= ARRAY_SIZE(opregion->acpi->didl); 721 722 if (WARN_ON(i >= ARRAY_SIZE(opregion->acpi->did2))) 723 return; 724 725 opregion->acpi->did2[i] = val; 726 } 727 } 728 729 static void intel_didl_outputs(struct intel_display *display) 730 { 731 struct intel_opregion *opregion = display->opregion; 732 struct intel_connector *connector; 733 struct drm_connector_list_iter conn_iter; 734 int i = 0, max_outputs; 735 736 /* 737 * In theory, did2, the extended didl, gets added at opregion version 738 * 3.0. In practice, however, we're supposed to set it for earlier 739 * versions as well, since a BIOS that doesn't understand did2 should 740 * not look at it anyway. Use a variable so we can tweak this if a need 741 * arises later. 742 */ 743 max_outputs = ARRAY_SIZE(opregion->acpi->didl) + 744 ARRAY_SIZE(opregion->acpi->did2); 745 746 intel_acpi_device_id_update(display); 747 748 drm_connector_list_iter_begin(display->drm, &conn_iter); 749 for_each_intel_connector_iter(connector, &conn_iter) { 750 if (i < max_outputs) 751 set_did(opregion, i, connector->acpi_device_id); 752 i++; 753 } 754 drm_connector_list_iter_end(&conn_iter); 755 756 drm_dbg_kms(display->drm, "%d outputs detected\n", i); 757 758 if (i > max_outputs) 759 drm_err(display->drm, 760 "More than %d outputs in connector list\n", 761 max_outputs); 762 763 /* If fewer than max outputs, the list must be null terminated */ 764 if (i < max_outputs) 765 set_did(opregion, i, 0); 766 } 767 768 static void intel_setup_cadls(struct intel_display *display) 769 { 770 struct intel_opregion *opregion = display->opregion; 771 struct intel_connector *connector; 772 struct drm_connector_list_iter conn_iter; 773 int i = 0; 774 775 /* 776 * Initialize the CADL field from the connector device ids. This is 777 * essentially the same as copying from the DIDL. Technically, this is 778 * not always correct as display outputs may exist, but not active. This 779 * initialization is necessary for some Clevo laptops that check this 780 * field before processing the brightness and display switching hotkeys. 781 * 782 * Note that internal panels should be at the front of the connector 783 * list already, ensuring they're not left out. 784 */ 785 drm_connector_list_iter_begin(display->drm, &conn_iter); 786 for_each_intel_connector_iter(connector, &conn_iter) { 787 if (i >= ARRAY_SIZE(opregion->acpi->cadl)) 788 break; 789 opregion->acpi->cadl[i++] = connector->acpi_device_id; 790 } 791 drm_connector_list_iter_end(&conn_iter); 792 793 /* If fewer than 8 active devices, the list must be null terminated */ 794 if (i < ARRAY_SIZE(opregion->acpi->cadl)) 795 opregion->acpi->cadl[i] = 0; 796 } 797 798 static void swsci_setup(struct intel_display *display) 799 { 800 struct intel_opregion *opregion = display->opregion; 801 bool requested_callbacks = false; 802 u32 tmp; 803 804 /* Sub-function code 0 is okay, let's allow them. */ 805 opregion->swsci_gbda_sub_functions = 1; 806 opregion->swsci_sbcb_sub_functions = 1; 807 808 /* We use GBDA to ask for supported GBDA calls. */ 809 if (swsci(display, SWSCI_GBDA_SUPPORTED_CALLS, 0, &tmp) == 0) { 810 /* make the bits match the sub-function codes */ 811 tmp <<= 1; 812 opregion->swsci_gbda_sub_functions |= tmp; 813 } 814 815 /* 816 * We also use GBDA to ask for _requested_ SBCB callbacks. The driver 817 * must not call interfaces that are not specifically requested by the 818 * bios. 819 */ 820 if (swsci(display, SWSCI_GBDA_REQUESTED_CALLBACKS, 0, &tmp) == 0) { 821 /* here, the bits already match sub-function codes */ 822 opregion->swsci_sbcb_sub_functions |= tmp; 823 requested_callbacks = true; 824 } 825 826 /* 827 * But we use SBCB to ask for _supported_ SBCB calls. This does not mean 828 * the callback is _requested_. But we still can't call interfaces that 829 * are not requested. 830 */ 831 if (swsci(display, SWSCI_SBCB_SUPPORTED_CALLBACKS, 0, &tmp) == 0) { 832 /* make the bits match the sub-function codes */ 833 u32 low = tmp & 0x7ff; 834 u32 high = tmp & ~0xfff; /* bit 11 is reserved */ 835 tmp = (high << 4) | (low << 1) | 1; 836 837 /* best guess what to do with supported wrt requested */ 838 if (requested_callbacks) { 839 u32 req = opregion->swsci_sbcb_sub_functions; 840 if ((req & tmp) != req) 841 drm_dbg(display->drm, 842 "SWSCI BIOS requested (%08x) SBCB callbacks that are not supported (%08x)\n", 843 req, tmp); 844 /* XXX: for now, trust the requested callbacks */ 845 /* opregion->swsci_sbcb_sub_functions &= tmp; */ 846 } else { 847 opregion->swsci_sbcb_sub_functions |= tmp; 848 } 849 } 850 851 drm_dbg(display->drm, 852 "SWSCI GBDA callbacks %08x, SBCB callbacks %08x\n", 853 opregion->swsci_gbda_sub_functions, 854 opregion->swsci_sbcb_sub_functions); 855 } 856 857 static int intel_no_opregion_vbt_callback(const struct dmi_system_id *id) 858 { 859 DRM_DEBUG_KMS("Falling back to manually reading VBT from " 860 "VBIOS ROM for %s\n", id->ident); 861 return 1; 862 } 863 864 static const struct dmi_system_id intel_no_opregion_vbt[] = { 865 { 866 .callback = intel_no_opregion_vbt_callback, 867 .ident = "ThinkCentre A57", 868 .matches = { 869 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 870 DMI_MATCH(DMI_PRODUCT_NAME, "97027RG"), 871 }, 872 }, 873 { } 874 }; 875 876 int intel_opregion_setup(struct intel_display *display) 877 { 878 struct intel_opregion *opregion; 879 struct pci_dev *pdev = to_pci_dev(display->drm->dev); 880 u32 asls, mboxes; 881 char buf[sizeof(OPREGION_SIGNATURE)]; 882 int err = 0; 883 void *base; 884 const void *vbt; 885 u32 vbt_size; 886 887 BUILD_BUG_ON(sizeof(struct opregion_header) != 0x100); 888 BUILD_BUG_ON(sizeof(struct opregion_acpi) != 0x100); 889 BUILD_BUG_ON(sizeof(struct opregion_swsci) != 0x100); 890 BUILD_BUG_ON(sizeof(struct opregion_asle) != 0x100); 891 BUILD_BUG_ON(sizeof(struct opregion_asle_ext) != 0x400); 892 893 pci_read_config_dword(pdev, ASLS, &asls); 894 drm_dbg(display->drm, "graphic opregion physical addr: 0x%x\n", 895 asls); 896 if (asls == 0) { 897 drm_dbg(display->drm, "ACPI OpRegion not supported!\n"); 898 return -ENOTSUPP; 899 } 900 901 opregion = kzalloc(sizeof(*opregion), GFP_KERNEL); 902 if (!opregion) 903 return -ENOMEM; 904 905 opregion->display = display; 906 display->opregion = opregion; 907 908 INIT_WORK(&opregion->asle_work, asle_work); 909 910 base = memremap(asls, OPREGION_SIZE, MEMREMAP_WB); 911 if (!base) { 912 err = -ENOMEM; 913 goto err_memremap; 914 } 915 916 memcpy(buf, base, sizeof(buf)); 917 918 if (memcmp(buf, OPREGION_SIGNATURE, 16)) { 919 drm_dbg(display->drm, "opregion signature mismatch\n"); 920 err = -EINVAL; 921 goto err_out; 922 } 923 opregion->header = base; 924 925 drm_dbg(display->drm, "ACPI OpRegion version %u.%u.%u\n", 926 opregion->header->over.major, 927 opregion->header->over.minor, 928 opregion->header->over.revision); 929 930 mboxes = opregion->header->mboxes; 931 if (mboxes & MBOX_ACPI) { 932 drm_dbg(display->drm, "Public ACPI methods supported\n"); 933 opregion->acpi = base + OPREGION_ACPI_OFFSET; 934 /* 935 * Indicate we handle monitor hotplug events ourselves so we do 936 * not need ACPI notifications for them. Disabling these avoids 937 * triggering the AML code doing the notifation, which may be 938 * broken as Windows also seems to disable these. 939 */ 940 opregion->acpi->chpd = 1; 941 } 942 943 if (mboxes & MBOX_SWSCI) { 944 u8 major = opregion->header->over.major; 945 946 if (major >= 3) { 947 drm_err(display->drm, "SWSCI Mailbox #2 present for opregion v3.x, ignoring\n"); 948 } else { 949 if (major >= 2) 950 drm_dbg(display->drm, "SWSCI Mailbox #2 present for opregion v2.x\n"); 951 drm_dbg(display->drm, "SWSCI supported\n"); 952 opregion->swsci = base + OPREGION_SWSCI_OFFSET; 953 swsci_setup(display); 954 } 955 } 956 957 if (mboxes & MBOX_ASLE) { 958 drm_dbg(display->drm, "ASLE supported\n"); 959 opregion->asle = base + OPREGION_ASLE_OFFSET; 960 961 opregion->asle->ardy = ASLE_ARDY_NOT_READY; 962 } 963 964 if (mboxes & MBOX_ASLE_EXT) { 965 drm_dbg(display->drm, "ASLE extension supported\n"); 966 opregion->asle_ext = base + OPREGION_ASLE_EXT_OFFSET; 967 } 968 969 if (mboxes & MBOX_BACKLIGHT) { 970 drm_dbg(display->drm, "Mailbox #2 for backlight present\n"); 971 } 972 973 if (dmi_check_system(intel_no_opregion_vbt)) 974 goto out; 975 976 if (opregion->header->over.major >= 2 && opregion->asle && 977 opregion->asle->rvda && opregion->asle->rvds) { 978 resource_size_t rvda = opregion->asle->rvda; 979 980 /* 981 * opregion 2.0: rvda is the physical VBT address. 982 * 983 * opregion 2.1+: rvda is unsigned, relative offset from 984 * opregion base, and should never point within opregion. 985 */ 986 if (opregion->header->over.major > 2 || 987 opregion->header->over.minor >= 1) { 988 drm_WARN_ON(display->drm, rvda < OPREGION_SIZE); 989 990 rvda += asls; 991 } 992 993 opregion->rvda = memremap(rvda, opregion->asle->rvds, 994 MEMREMAP_WB); 995 996 vbt = opregion->rvda; 997 vbt_size = opregion->asle->rvds; 998 if (intel_bios_is_valid_vbt(display, vbt, vbt_size)) { 999 drm_dbg_kms(display->drm, 1000 "Found valid VBT in ACPI OpRegion (RVDA)\n"); 1001 opregion->vbt = vbt; 1002 opregion->vbt_size = vbt_size; 1003 goto out; 1004 } else { 1005 drm_dbg_kms(display->drm, 1006 "Invalid VBT in ACPI OpRegion (RVDA)\n"); 1007 memunmap(opregion->rvda); 1008 opregion->rvda = NULL; 1009 } 1010 } 1011 1012 vbt = base + OPREGION_VBT_OFFSET; 1013 /* 1014 * The VBT specification says that if the ASLE ext mailbox is not used 1015 * its area is reserved, but on some CHT boards the VBT extends into the 1016 * ASLE ext area. Allow this even though it is against the spec, so we 1017 * do not end up rejecting the VBT on those boards (and end up not 1018 * finding the LCD panel because of this). 1019 */ 1020 vbt_size = (mboxes & MBOX_ASLE_EXT) ? 1021 OPREGION_ASLE_EXT_OFFSET : OPREGION_SIZE; 1022 vbt_size -= OPREGION_VBT_OFFSET; 1023 if (intel_bios_is_valid_vbt(display, vbt, vbt_size)) { 1024 drm_dbg_kms(display->drm, 1025 "Found valid VBT in ACPI OpRegion (Mailbox #4)\n"); 1026 opregion->vbt = vbt; 1027 opregion->vbt_size = vbt_size; 1028 } else { 1029 drm_dbg_kms(display->drm, 1030 "Invalid VBT in ACPI OpRegion (Mailbox #4)\n"); 1031 } 1032 1033 out: 1034 return 0; 1035 1036 err_out: 1037 memunmap(base); 1038 err_memremap: 1039 kfree(opregion); 1040 display->opregion = NULL; 1041 1042 return err; 1043 } 1044 1045 static int intel_use_opregion_panel_type_callback(const struct dmi_system_id *id) 1046 { 1047 DRM_INFO("Using panel type from OpRegion on %s\n", id->ident); 1048 return 1; 1049 } 1050 1051 static const struct dmi_system_id intel_use_opregion_panel_type[] = { 1052 { 1053 .callback = intel_use_opregion_panel_type_callback, 1054 .ident = "Conrac GmbH IX45GM2", 1055 .matches = {DMI_MATCH(DMI_SYS_VENDOR, "Conrac GmbH"), 1056 DMI_MATCH(DMI_PRODUCT_NAME, "IX45GM2"), 1057 }, 1058 }, 1059 { } 1060 }; 1061 1062 int 1063 intel_opregion_get_panel_type(struct intel_display *display) 1064 { 1065 u32 panel_details; 1066 int ret; 1067 1068 ret = swsci(display, SWSCI_GBDA_PANEL_DETAILS, 0x0, &panel_details); 1069 if (ret) 1070 return ret; 1071 1072 ret = (panel_details >> 8) & 0xff; 1073 if (ret > 0x10) { 1074 drm_dbg_kms(display->drm, 1075 "Invalid OpRegion panel type 0x%x\n", ret); 1076 return -EINVAL; 1077 } 1078 1079 /* fall back to VBT panel type? */ 1080 if (ret == 0x0) { 1081 drm_dbg_kms(display->drm, "No panel type in OpRegion\n"); 1082 return -ENODEV; 1083 } 1084 1085 /* 1086 * So far we know that some machined must use it, others must not use it. 1087 * There doesn't seem to be any way to determine which way to go, except 1088 * via a quirk list :( 1089 */ 1090 if (!dmi_check_system(intel_use_opregion_panel_type)) { 1091 drm_dbg_kms(display->drm, 1092 "Ignoring OpRegion panel type (%d)\n", ret - 1); 1093 return -ENODEV; 1094 } 1095 1096 return ret - 1; 1097 } 1098 1099 /** 1100 * intel_opregion_get_edid - Fetch EDID from ACPI OpRegion mailbox #5 1101 * @connector: eDP connector 1102 * 1103 * This reads the ACPI Opregion mailbox #5 to extract the EDID that is passed 1104 * to it. 1105 * 1106 * Returns: 1107 * The EDID in the OpRegion, or NULL if there is none or it's invalid. 1108 * 1109 */ 1110 const struct drm_edid *intel_opregion_get_edid(struct intel_connector *connector) 1111 { 1112 struct intel_display *display = to_intel_display(connector); 1113 struct intel_opregion *opregion = display->opregion; 1114 const struct drm_edid *drm_edid; 1115 const void *edid; 1116 int len; 1117 1118 if (!opregion || !opregion->asle_ext) 1119 return NULL; 1120 1121 edid = opregion->asle_ext->bddc; 1122 1123 /* Validity corresponds to number of 128-byte blocks */ 1124 len = (opregion->asle_ext->phed & ASLE_PHED_EDID_VALID_MASK) * 128; 1125 if (!len || mem_is_zero(edid, len)) 1126 return NULL; 1127 1128 drm_edid = drm_edid_alloc(edid, len); 1129 1130 if (!drm_edid_valid(drm_edid)) { 1131 drm_dbg_kms(display->drm, "Invalid EDID in ACPI OpRegion (Mailbox #5)\n"); 1132 drm_edid_free(drm_edid); 1133 drm_edid = NULL; 1134 } 1135 1136 return drm_edid; 1137 } 1138 1139 bool intel_opregion_vbt_present(struct intel_display *display) 1140 { 1141 struct intel_opregion *opregion = display->opregion; 1142 1143 if (!opregion || !opregion->vbt) 1144 return false; 1145 1146 return true; 1147 } 1148 1149 const void *intel_opregion_get_vbt(struct intel_display *display, size_t *size) 1150 { 1151 struct intel_opregion *opregion = display->opregion; 1152 1153 if (!opregion || !opregion->vbt) 1154 return NULL; 1155 1156 if (size) 1157 *size = opregion->vbt_size; 1158 1159 return kmemdup(opregion->vbt, opregion->vbt_size, GFP_KERNEL); 1160 } 1161 1162 bool intel_opregion_headless_sku(struct intel_display *display) 1163 { 1164 struct intel_opregion *opregion = display->opregion; 1165 struct opregion_header *header; 1166 1167 if (!opregion) 1168 return false; 1169 1170 header = opregion->header; 1171 1172 if (!header || header->over.major < 2 || 1173 (header->over.major == 2 && header->over.minor < 3)) 1174 return false; 1175 1176 return opregion->header->pcon & PCON_HEADLESS_SKU; 1177 } 1178 1179 void intel_opregion_register(struct intel_display *display) 1180 { 1181 struct intel_opregion *opregion = display->opregion; 1182 1183 if (!opregion) 1184 return; 1185 1186 if (opregion->acpi) { 1187 opregion->acpi_notifier.notifier_call = 1188 intel_opregion_video_event; 1189 register_acpi_notifier(&opregion->acpi_notifier); 1190 } 1191 1192 intel_opregion_resume(display); 1193 } 1194 1195 static void intel_opregion_resume_display(struct intel_display *display) 1196 { 1197 struct intel_opregion *opregion = display->opregion; 1198 1199 if (opregion->acpi) { 1200 intel_didl_outputs(display); 1201 intel_setup_cadls(display); 1202 1203 /* 1204 * Notify BIOS we are ready to handle ACPI video ext notifs. 1205 * Right now, all the events are handled by the ACPI video 1206 * module. We don't actually need to do anything with them. 1207 */ 1208 opregion->acpi->csts = 0; 1209 opregion->acpi->drdy = 1; 1210 } 1211 1212 if (opregion->asle) { 1213 opregion->asle->tche = ASLE_TCHE_BLC_EN; 1214 opregion->asle->ardy = ASLE_ARDY_READY; 1215 } 1216 1217 /* Some platforms abuse the _DSM to enable MUX */ 1218 intel_dsm_get_bios_data_funcs_supported(display); 1219 } 1220 1221 void intel_opregion_resume(struct intel_display *display) 1222 { 1223 struct intel_opregion *opregion = display->opregion; 1224 1225 if (!opregion) 1226 return; 1227 1228 if (HAS_DISPLAY(display)) 1229 intel_opregion_resume_display(display); 1230 1231 intel_opregion_notify_adapter(display, PCI_D0); 1232 } 1233 1234 static void intel_opregion_suspend_display(struct intel_display *display) 1235 { 1236 struct intel_opregion *opregion = display->opregion; 1237 1238 if (opregion->asle) 1239 opregion->asle->ardy = ASLE_ARDY_NOT_READY; 1240 1241 cancel_work_sync(&opregion->asle_work); 1242 1243 if (opregion->acpi) 1244 opregion->acpi->drdy = 0; 1245 } 1246 1247 void intel_opregion_suspend(struct intel_display *display, pci_power_t state) 1248 { 1249 struct intel_opregion *opregion = display->opregion; 1250 1251 if (!opregion) 1252 return; 1253 1254 intel_opregion_notify_adapter(display, state); 1255 1256 if (HAS_DISPLAY(display)) 1257 intel_opregion_suspend_display(display); 1258 } 1259 1260 void intel_opregion_unregister(struct intel_display *display) 1261 { 1262 struct intel_opregion *opregion = display->opregion; 1263 1264 intel_opregion_suspend(display, PCI_D1); 1265 1266 if (!opregion) 1267 return; 1268 1269 if (opregion->acpi_notifier.notifier_call) { 1270 unregister_acpi_notifier(&opregion->acpi_notifier); 1271 opregion->acpi_notifier.notifier_call = NULL; 1272 } 1273 } 1274 1275 void intel_opregion_cleanup(struct intel_display *display) 1276 { 1277 struct intel_opregion *opregion = display->opregion; 1278 1279 if (!opregion) 1280 return; 1281 1282 memunmap(opregion->header); 1283 if (opregion->rvda) 1284 memunmap(opregion->rvda); 1285 kfree(opregion); 1286 display->opregion = NULL; 1287 } 1288 1289 static int intel_opregion_show(struct seq_file *m, void *unused) 1290 { 1291 struct intel_display *display = m->private; 1292 struct intel_opregion *opregion = display->opregion; 1293 1294 if (opregion) 1295 seq_write(m, opregion->header, OPREGION_SIZE); 1296 1297 return 0; 1298 } 1299 1300 DEFINE_SHOW_ATTRIBUTE(intel_opregion); 1301 1302 void intel_opregion_debugfs_register(struct intel_display *display) 1303 { 1304 debugfs_create_file("i915_opregion", 0444, display->drm->debugfs_root, 1305 display, &intel_opregion_fops); 1306 } 1307