Rev 5354 | Rev 6103 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 5354 | Rev 6084 | ||
---|---|---|---|
Line 51... | Line 51... | ||
51 | 51 | ||
52 | #define OPREGION_SIGNATURE "IntelGraphicsMem" |
52 | #define OPREGION_SIGNATURE "IntelGraphicsMem" |
53 | #define MBOX_ACPI (1<<0) |
53 | #define MBOX_ACPI (1<<0) |
54 | #define MBOX_SWSCI (1<<1) |
54 | #define MBOX_SWSCI (1<<1) |
- | 55 | #define MBOX_ASLE (1<<2) |
|
Line 55... | Line 56... | ||
55 | #define MBOX_ASLE (1<<2) |
56 | #define MBOX_ASLE_EXT (1<<4) |
56 | 57 | ||
57 | struct opregion_header { |
58 | struct opregion_header { |
58 | u8 signature[16]; |
59 | u8 signature[16]; |
59 | u32 size; |
60 | u32 size; |
60 | u32 opregion_ver; |
61 | u32 opregion_ver; |
61 | u8 bios_ver[32]; |
62 | u8 bios_ver[32]; |
62 | u8 vbios_ver[16]; |
63 | u8 vbios_ver[16]; |
- | 64 | u8 driver_ver[16]; |
|
- | 65 | u32 mboxes; |
|
- | 66 | u32 driver_model; |
|
63 | u8 driver_ver[16]; |
67 | u32 pcon; |
64 | u32 mboxes; |
68 | u8 dver[32]; |
Line 65... | Line 69... | ||
65 | u8 reserved[164]; |
69 | u8 rsvd[124]; |
66 | } __packed; |
70 | } __packed; |
67 | 71 | ||
Line 82... | Line 86... | ||
82 | u32 cdck; /* current docking state */ |
86 | u32 cdck; /* current docking state */ |
83 | u32 sxsw; /* Sx state resume */ |
87 | u32 sxsw; /* Sx state resume */ |
84 | u32 evts; /* ASL supported events */ |
88 | u32 evts; /* ASL supported events */ |
85 | u32 cnot; /* current OS notification */ |
89 | u32 cnot; /* current OS notification */ |
86 | u32 nrdy; /* driver status */ |
90 | u32 nrdy; /* driver status */ |
- | 91 | u32 did2[7]; /* extended supported display devices ID list */ |
|
- | 92 | u32 cpd2[7]; /* extended attached display devices list */ |
|
87 | u8 rsvd2[60]; |
93 | u8 rsvd2[4]; |
88 | } __packed; |
94 | } __packed; |
Line 89... | Line 95... | ||
89 | 95 | ||
90 | /* OpRegion mailbox #2: SWSCI */ |
96 | /* OpRegion mailbox #2: SWSCI */ |
91 | struct opregion_swsci { |
97 | struct opregion_swsci { |
Line 111... | Line 117... | ||
111 | u32 pfmb; /* PWM freq and min brightness */ |
117 | u32 pfmb; /* PWM freq and min brightness */ |
112 | u32 cddv; /* color correction default values */ |
118 | u32 cddv; /* color correction default values */ |
113 | u32 pcft; /* power conservation features */ |
119 | u32 pcft; /* power conservation features */ |
114 | u32 srot; /* supported rotation angles */ |
120 | u32 srot; /* supported rotation angles */ |
115 | u32 iuer; /* IUER events */ |
121 | u32 iuer; /* IUER events */ |
- | 122 | u64 fdss; |
|
- | 123 | u32 fdsp; |
|
- | 124 | u32 stat; |
|
116 | u8 rsvd[86]; |
125 | u8 rsvd[70]; |
117 | } __packed; |
126 | } __packed; |
Line 118... | Line 127... | ||
118 | 127 | ||
119 | /* Driver readiness indicator */ |
128 | /* Driver readiness indicator */ |
120 | #define ASLE_ARDY_READY (1 << 0) |
129 | #define ASLE_ARDY_READY (1 << 0) |
Line 230... | Line 239... | ||
230 | 239 | ||
231 | #ifdef CONFIG_ACPI |
240 | #ifdef CONFIG_ACPI |
232 | static int swsci(struct drm_device *dev, u32 function, u32 parm, u32 *parm_out) |
241 | static int swsci(struct drm_device *dev, u32 function, u32 parm, u32 *parm_out) |
233 | { |
242 | { |
234 | struct drm_i915_private *dev_priv = dev->dev_private; |
243 | struct drm_i915_private *dev_priv = dev->dev_private; |
235 | struct opregion_swsci __iomem *swsci = dev_priv->opregion.swsci; |
244 | struct opregion_swsci *swsci = dev_priv->opregion.swsci; |
236 | u32 main_function, sub_function, scic; |
245 | u32 main_function, sub_function, scic; |
237 | u16 pci_swsci; |
246 | u16 pci_swsci; |
Line 238... | Line 247... | ||
238 | u32 dslp; |
247 | u32 dslp; |
Line 255... | Line 264... | ||
255 | (1 << sub_function)) == 0) |
264 | (1 << sub_function)) == 0) |
256 | return -EINVAL; |
265 | return -EINVAL; |
257 | } |
266 | } |
Line 258... | Line 267... | ||
258 | 267 | ||
259 | /* Driver sleep timeout in ms. */ |
268 | /* Driver sleep timeout in ms. */ |
260 | dslp = ioread32(&swsci->dslp); |
269 | dslp = swsci->dslp; |
261 | if (!dslp) { |
270 | if (!dslp) { |
262 | /* The spec says 2ms should be the default, but it's too small |
271 | /* The spec says 2ms should be the default, but it's too small |
263 | * for some machines. */ |
272 | * for some machines. */ |
264 | dslp = 50; |
273 | dslp = 50; |
Line 268... | Line 277... | ||
268 | "using %u ms instead\n", dslp, MAX_DSLP); |
277 | "using %u ms instead\n", dslp, MAX_DSLP); |
269 | dslp = MAX_DSLP; |
278 | dslp = MAX_DSLP; |
270 | } |
279 | } |
Line 271... | Line 280... | ||
271 | 280 | ||
272 | /* The spec tells us to do this, but we are the only user... */ |
281 | /* The spec tells us to do this, but we are the only user... */ |
273 | scic = ioread32(&swsci->scic); |
282 | scic = swsci->scic; |
274 | if (scic & SWSCI_SCIC_INDICATOR) { |
283 | if (scic & SWSCI_SCIC_INDICATOR) { |
275 | DRM_DEBUG_DRIVER("SWSCI request already in progress\n"); |
284 | DRM_DEBUG_DRIVER("SWSCI request already in progress\n"); |
276 | return -EBUSY; |
285 | return -EBUSY; |
Line 277... | Line 286... | ||
277 | } |
286 | } |
Line 278... | Line 287... | ||
278 | 287 | ||
279 | scic = function | SWSCI_SCIC_INDICATOR; |
288 | scic = function | SWSCI_SCIC_INDICATOR; |
Line 280... | Line 289... | ||
280 | 289 | ||
281 | iowrite32(parm, &swsci->parm); |
290 | swsci->parm = parm; |
282 | iowrite32(scic, &swsci->scic); |
291 | swsci->scic = scic; |
283 | 292 | ||
Line 292... | Line 301... | ||
292 | /* Use event trigger to tell bios to check the mail. */ |
301 | /* Use event trigger to tell bios to check the mail. */ |
293 | pci_swsci |= PCI_SWSCI_GSSCIE; |
302 | pci_swsci |= PCI_SWSCI_GSSCIE; |
294 | pci_write_config_word(dev->pdev, PCI_SWSCI, pci_swsci); |
303 | pci_write_config_word(dev->pdev, PCI_SWSCI, pci_swsci); |
Line 295... | Line 304... | ||
295 | 304 | ||
296 | /* Poll for the result. */ |
305 | /* Poll for the result. */ |
297 | #define C (((scic = ioread32(&swsci->scic)) & SWSCI_SCIC_INDICATOR) == 0) |
306 | #define C (((scic = swsci->scic) & SWSCI_SCIC_INDICATOR) == 0) |
298 | if (wait_for(C, dslp)) { |
307 | if (wait_for(C, dslp)) { |
299 | DRM_DEBUG_DRIVER("SWSCI request timed out\n"); |
308 | DRM_DEBUG_DRIVER("SWSCI request timed out\n"); |
300 | return -ETIMEDOUT; |
309 | return -ETIMEDOUT; |
Line 308... | Line 317... | ||
308 | DRM_DEBUG_DRIVER("SWSCI request error %u\n", scic); |
317 | DRM_DEBUG_DRIVER("SWSCI request error %u\n", scic); |
309 | return -EIO; |
318 | return -EIO; |
310 | } |
319 | } |
Line 311... | Line 320... | ||
311 | 320 | ||
312 | if (parm_out) |
321 | if (parm_out) |
Line 313... | Line 322... | ||
313 | *parm_out = ioread32(&swsci->parm); |
322 | *parm_out = swsci->parm; |
Line 314... | Line 323... | ||
314 | 323 | ||
315 | return 0; |
324 | return 0; |
Line 332... | Line 341... | ||
332 | 341 | ||
333 | /* don't care about old stuff for now */ |
342 | /* don't care about old stuff for now */ |
334 | if (!HAS_DDI(dev)) |
343 | if (!HAS_DDI(dev)) |
Line -... | Line 344... | ||
- | 344 | return 0; |
|
- | 345 | ||
- | 346 | if (intel_encoder->type == INTEL_OUTPUT_DSI) |
|
335 | return 0; |
347 | port = 0; |
- | 348 | else |
|
336 | 349 | port = intel_ddi_get_encoder_port(intel_encoder); |
|
337 | port = intel_ddi_get_encoder_port(intel_encoder); |
350 | |
338 | if (port == PORT_E) { |
351 | if (port == PORT_E) { |
339 | port = 0; |
352 | port = 0; |
340 | } else { |
353 | } else { |
Line 354... | Line 367... | ||
354 | case INTEL_OUTPUT_HDMI: |
367 | case INTEL_OUTPUT_HDMI: |
355 | case INTEL_OUTPUT_DP_MST: |
368 | case INTEL_OUTPUT_DP_MST: |
356 | type = DISPLAY_TYPE_EXTERNAL_FLAT_PANEL; |
369 | type = DISPLAY_TYPE_EXTERNAL_FLAT_PANEL; |
357 | break; |
370 | break; |
358 | case INTEL_OUTPUT_EDP: |
371 | case INTEL_OUTPUT_EDP: |
- | 372 | case INTEL_OUTPUT_DSI: |
|
359 | type = DISPLAY_TYPE_INTERNAL_FLAT_PANEL; |
373 | type = DISPLAY_TYPE_INTERNAL_FLAT_PANEL; |
360 | break; |
374 | break; |
361 | default: |
375 | default: |
362 | WARN_ONCE(1, "unsupported intel_encoder type %d\n", |
376 | WARN_ONCE(1, "unsupported intel_encoder type %d\n", |
363 | intel_encoder->type); |
377 | intel_encoder->type); |
Line 394... | Line 408... | ||
394 | } |
408 | } |
Line 395... | Line 409... | ||
395 | 409 | ||
396 | return -EINVAL; |
410 | return -EINVAL; |
Line 397... | Line -... | ||
397 | } |
- | |
398 | - | ||
399 | /* |
- | |
400 | * If the vendor backlight interface is not in use and ACPI backlight interface |
- | |
401 | * is broken, do not bother processing backlight change requests from firmware. |
- | |
402 | */ |
- | |
403 | static bool should_ignore_backlight_request(void) |
- | |
404 | { |
- | |
405 | return acpi_video_backlight_support() && |
- | |
406 | !acpi_video_verify_backlight_support(); |
- | |
407 | } |
411 | } |
408 | 412 | ||
409 | static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) |
413 | static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) |
410 | { |
414 | { |
411 | struct drm_i915_private *dev_priv = dev->dev_private; |
415 | struct drm_i915_private *dev_priv = dev->dev_private; |
Line 412... | Line 416... | ||
412 | struct intel_connector *intel_connector; |
416 | struct intel_connector *intel_connector; |
Line 413... | Line 417... | ||
413 | struct opregion_asle __iomem *asle = dev_priv->opregion.asle; |
417 | struct opregion_asle *asle = dev_priv->opregion.asle; |
414 | 418 | ||
415 | DRM_DEBUG_DRIVER("bclp = 0x%08x\n", bclp); |
419 | DRM_DEBUG_DRIVER("bclp = 0x%08x\n", bclp); |
416 | 420 | ||
Line 417... | Line 421... | ||
417 | if (should_ignore_backlight_request()) { |
421 | if (acpi_video_get_backlight_type() == acpi_backlight_native) { |
Line 433... | Line 437... | ||
433 | * only one). |
437 | * only one). |
434 | */ |
438 | */ |
435 | DRM_DEBUG_KMS("updating opregion backlight %d/255\n", bclp); |
439 | DRM_DEBUG_KMS("updating opregion backlight %d/255\n", bclp); |
436 | list_for_each_entry(intel_connector, &dev->mode_config.connector_list, base.head) |
440 | list_for_each_entry(intel_connector, &dev->mode_config.connector_list, base.head) |
437 | intel_panel_set_backlight_acpi(intel_connector, bclp, 255); |
441 | intel_panel_set_backlight_acpi(intel_connector, bclp, 255); |
438 | iowrite32(DIV_ROUND_UP(bclp * 100, 255) | ASLE_CBLV_VALID, &asle->cblv); |
442 | asle->cblv = DIV_ROUND_UP(bclp * 100, 255) | ASLE_CBLV_VALID; |
Line 439... | Line 443... | ||
439 | 443 | ||
Line 440... | Line 444... | ||
440 | drm_modeset_unlock(&dev->mode_config.connection_mutex); |
444 | drm_modeset_unlock(&dev->mode_config.connection_mutex); |
Line 520... | Line 524... | ||
520 | struct intel_opregion *opregion = |
524 | struct intel_opregion *opregion = |
521 | container_of(work, struct intel_opregion, asle_work); |
525 | container_of(work, struct intel_opregion, asle_work); |
522 | struct drm_i915_private *dev_priv = |
526 | struct drm_i915_private *dev_priv = |
523 | container_of(opregion, struct drm_i915_private, opregion); |
527 | container_of(opregion, struct drm_i915_private, opregion); |
524 | struct drm_device *dev = dev_priv->dev; |
528 | struct drm_device *dev = dev_priv->dev; |
525 | struct opregion_asle __iomem *asle = dev_priv->opregion.asle; |
529 | struct opregion_asle *asle = dev_priv->opregion.asle; |
526 | u32 aslc_stat = 0; |
530 | u32 aslc_stat = 0; |
527 | u32 aslc_req; |
531 | u32 aslc_req; |
Line 528... | Line 532... | ||
528 | 532 | ||
529 | if (!asle) |
533 | if (!asle) |
Line 530... | Line 534... | ||
530 | return; |
534 | return; |
Line 531... | Line 535... | ||
531 | 535 | ||
532 | aslc_req = ioread32(&asle->aslc); |
536 | aslc_req = asle->aslc; |
533 | 537 | ||
534 | if (!(aslc_req & ASLC_REQ_MSK)) { |
538 | if (!(aslc_req & ASLC_REQ_MSK)) { |
535 | DRM_DEBUG_DRIVER("No request on ASLC interrupt 0x%08x\n", |
539 | DRM_DEBUG_DRIVER("No request on ASLC interrupt 0x%08x\n", |
Line 536... | Line 540... | ||
536 | aslc_req); |
540 | aslc_req); |
537 | return; |
541 | return; |
Line 538... | Line 542... | ||
538 | } |
542 | } |
539 | 543 | ||
Line 540... | Line 544... | ||
540 | if (aslc_req & ASLC_SET_ALS_ILLUM) |
544 | if (aslc_req & ASLC_SET_ALS_ILLUM) |
541 | aslc_stat |= asle_set_als_illum(dev, ioread32(&asle->alsi)); |
545 | aslc_stat |= asle_set_als_illum(dev, asle->alsi); |
Line 542... | Line 546... | ||
542 | 546 | ||
543 | if (aslc_req & ASLC_SET_BACKLIGHT) |
547 | if (aslc_req & ASLC_SET_BACKLIGHT) |
Line 544... | Line 548... | ||
544 | aslc_stat |= asle_set_backlight(dev, ioread32(&asle->bclp)); |
548 | aslc_stat |= asle_set_backlight(dev, asle->bclp); |
545 | 549 | ||
546 | if (aslc_req & ASLC_SET_PFIT) |
550 | if (aslc_req & ASLC_SET_PFIT) |
Line 547... | Line 551... | ||
547 | aslc_stat |= asle_set_pfit(dev, ioread32(&asle->pfit)); |
551 | aslc_stat |= asle_set_pfit(dev, asle->pfit); |
548 | 552 | ||
Line 549... | Line 553... | ||
549 | if (aslc_req & ASLC_SET_PWM_FREQ) |
553 | if (aslc_req & ASLC_SET_PWM_FREQ) |
550 | aslc_stat |= asle_set_pwm_freq(dev, ioread32(&asle->pfmb)); |
554 | aslc_stat |= asle_set_pwm_freq(dev, asle->pfmb); |
Line 551... | Line 555... | ||
551 | 555 | ||
552 | if (aslc_req & ASLC_SUPPORTED_ROTATION_ANGLES) |
556 | if (aslc_req & ASLC_SUPPORTED_ROTATION_ANGLES) |
Line 553... | Line 557... | ||
553 | aslc_stat |= asle_set_supported_rotation_angles(dev, |
557 | aslc_stat |= asle_set_supported_rotation_angles(dev, |
554 | ioread32(&asle->srot)); |
558 | asle->srot); |
Line 555... | Line 559... | ||
555 | 559 | ||
556 | if (aslc_req & ASLC_BUTTON_ARRAY) |
560 | if (aslc_req & ASLC_BUTTON_ARRAY) |
Line 557... | Line 561... | ||
557 | aslc_stat |= asle_set_button_array(dev, ioread32(&asle->iuer)); |
561 | aslc_stat |= asle_set_button_array(dev, asle->iuer); |
558 | 562 | ||
559 | if (aslc_req & ASLC_CONVERTIBLE_INDICATOR) |
563 | if (aslc_req & ASLC_CONVERTIBLE_INDICATOR) |
Line 588... | Line 592... | ||
588 | /* The only video events relevant to opregion are 0x80. These indicate |
592 | /* The only video events relevant to opregion are 0x80. These indicate |
589 | either a docking event, lid switch or display switch request. In |
593 | either a docking event, lid switch or display switch request. In |
590 | Linux, these are handled by the dock, button and video drivers. |
594 | Linux, these are handled by the dock, button and video drivers. |
591 | */ |
595 | */ |
Line 592... | Line -... | ||
592 | - | ||
593 | struct opregion_acpi __iomem *acpi; |
596 | |
- | 597 | struct acpi_bus_event *event = data; |
|
594 | struct acpi_bus_event *event = data; |
598 | struct opregion_acpi *acpi; |
Line 595... | Line 599... | ||
595 | int ret = NOTIFY_OK; |
599 | int ret = NOTIFY_OK; |
596 | 600 | ||
Line 597... | Line 601... | ||
597 | if (strcmp(event->device_class, ACPI_VIDEO_CLASS) != 0) |
601 | if (strcmp(event->device_class, ACPI_VIDEO_CLASS) != 0) |
598 | return NOTIFY_DONE; |
602 | return NOTIFY_DONE; |
Line 599... | Line 603... | ||
599 | 603 | ||
Line 600... | Line -... | ||
600 | if (!system_opregion) |
- | |
601 | return NOTIFY_DONE; |
604 | if (!system_opregion) |
602 | 605 | return NOTIFY_DONE; |
|
Line 603... | Line 606... | ||
603 | acpi = system_opregion->acpi; |
606 | |
Line 604... | Line 607... | ||
604 | 607 | acpi = system_opregion->acpi; |
|
605 | if (event->type == 0x80 && |
608 | |
Line 606... | Line 609... | ||
606 | (ioread32(&acpi->cevt) & 1) == 0) |
609 | if (event->type == 0x80 && ((acpi->cevt & 1) == 0)) |
Line 619... | Line 622... | ||
619 | * Initialise the DIDL field in opregion. This passes a list of devices to |
622 | * Initialise the DIDL field in opregion. This passes a list of devices to |
620 | * the firmware. Values are defined by section B.4.2 of the ACPI specification |
623 | * the firmware. Values are defined by section B.4.2 of the ACPI specification |
621 | * (version 3) |
624 | * (version 3) |
622 | */ |
625 | */ |
Line -... | Line 626... | ||
- | 626 | ||
- | 627 | static u32 get_did(struct intel_opregion *opregion, int i) |
|
- | 628 | { |
|
- | 629 | u32 did; |
|
- | 630 | ||
- | 631 | if (i < ARRAY_SIZE(opregion->acpi->didl)) { |
|
- | 632 | did = opregion->acpi->didl[i]; |
|
- | 633 | } else { |
|
- | 634 | i -= ARRAY_SIZE(opregion->acpi->didl); |
|
- | 635 | ||
- | 636 | if (WARN_ON(i >= ARRAY_SIZE(opregion->acpi->did2))) |
|
- | 637 | return 0; |
|
- | 638 | ||
- | 639 | did = opregion->acpi->did2[i]; |
|
- | 640 | } |
|
- | 641 | ||
- | 642 | return did; |
|
- | 643 | } |
|
- | 644 | ||
- | 645 | static void set_did(struct intel_opregion *opregion, int i, u32 val) |
|
- | 646 | { |
|
- | 647 | if (i < ARRAY_SIZE(opregion->acpi->didl)) { |
|
- | 648 | opregion->acpi->didl[i] = val; |
|
- | 649 | } else { |
|
- | 650 | i -= ARRAY_SIZE(opregion->acpi->didl); |
|
- | 651 | ||
- | 652 | if (WARN_ON(i >= ARRAY_SIZE(opregion->acpi->did2))) |
|
- | 653 | return; |
|
- | 654 | ||
- | 655 | opregion->acpi->did2[i] = val; |
|
- | 656 | } |
|
- | 657 | } |
|
623 | 658 | ||
624 | static void intel_didl_outputs(struct drm_device *dev) |
659 | static void intel_didl_outputs(struct drm_device *dev) |
625 | { |
660 | { |
626 | struct drm_i915_private *dev_priv = dev->dev_private; |
661 | struct drm_i915_private *dev_priv = dev->dev_private; |
627 | struct intel_opregion *opregion = &dev_priv->opregion; |
662 | struct intel_opregion *opregion = &dev_priv->opregion; |
628 | struct drm_connector *connector; |
663 | struct drm_connector *connector; |
629 | acpi_handle handle; |
664 | acpi_handle handle; |
630 | struct acpi_device *acpi_dev, *acpi_cdev, *acpi_video_bus = NULL; |
665 | struct acpi_device *acpi_dev, *acpi_cdev, *acpi_video_bus = NULL; |
631 | unsigned long long device_id; |
666 | unsigned long long device_id; |
632 | acpi_status status; |
667 | acpi_status status; |
633 | u32 temp; |
668 | u32 temp, max_outputs; |
Line 634... | Line 669... | ||
634 | int i = 0; |
669 | int i = 0; |
635 | 670 | ||
636 | handle = ACPI_HANDLE(&dev->pdev->dev); |
671 | handle = ACPI_HANDLE(&dev->pdev->dev); |
Line 647... | Line 682... | ||
647 | } |
682 | } |
648 | } |
683 | } |
649 | } |
684 | } |
Line 650... | Line 685... | ||
650 | 685 | ||
651 | if (!acpi_video_bus) { |
686 | if (!acpi_video_bus) { |
652 | pr_warn("No ACPI video bus found\n"); |
687 | DRM_ERROR("No ACPI video bus found\n"); |
653 | return; |
688 | return; |
Line -... | Line 689... | ||
- | 689 | } |
|
- | 690 | ||
- | 691 | /* |
|
- | 692 | * In theory, did2, the extended didl, gets added at opregion version |
|
- | 693 | * 3.0. In practice, however, we're supposed to set it for earlier |
|
- | 694 | * versions as well, since a BIOS that doesn't understand did2 should |
|
- | 695 | * not look at it anyway. Use a variable so we can tweak this if a need |
|
- | 696 | * arises later. |
|
- | 697 | */ |
|
- | 698 | max_outputs = ARRAY_SIZE(opregion->acpi->didl) + |
|
654 | } |
699 | ARRAY_SIZE(opregion->acpi->did2); |
655 | 700 | ||
656 | list_for_each_entry(acpi_cdev, &acpi_video_bus->children, node) { |
701 | list_for_each_entry(acpi_cdev, &acpi_video_bus->children, node) { |
657 | if (i >= 8) { |
702 | if (i >= max_outputs) { |
658 | dev_dbg(&dev->pdev->dev, |
703 | DRM_DEBUG_KMS("More than %u outputs detected via ACPI\n", |
659 | "More than 8 outputs detected via ACPI\n"); |
704 | max_outputs); |
660 | return; |
- | |
661 | } |
705 | return; |
662 | status = |
706 | } |
663 | acpi_evaluate_integer(acpi_cdev->handle, "_ADR", |
707 | status = acpi_evaluate_integer(acpi_cdev->handle, "_ADR", |
664 | NULL, &device_id); |
708 | NULL, &device_id); |
665 | if (ACPI_SUCCESS(status)) { |
709 | if (ACPI_SUCCESS(status)) { |
666 | if (!device_id) |
710 | if (!device_id) |
667 | goto blind_set; |
- | |
668 | iowrite32((u32)(device_id & 0x0f0f), |
- | |
669 | &opregion->acpi->didl[i]); |
711 | goto blind_set; |
670 | i++; |
712 | set_did(opregion, i++, (u32)(device_id & 0x0f0f)); |
Line 671... | Line 713... | ||
671 | } |
713 | } |
- | 714 | } |
|
- | 715 | ||
672 | } |
716 | end: |
673 | 717 | DRM_DEBUG_KMS("%d outputs detected\n", i); |
|
674 | end: |
718 | |
675 | /* If fewer than 8 outputs, the list must be null terminated */ |
719 | /* If fewer than max outputs, the list must be null terminated */ |
Line 676... | Line 720... | ||
676 | if (i < 8) |
720 | if (i < max_outputs) |
677 | iowrite32(0, &opregion->acpi->didl[i]); |
721 | set_did(opregion, i, 0); |
678 | return; |
722 | return; |
679 | 723 | ||
680 | blind_set: |
724 | blind_set: |
681 | i = 0; |
- | |
682 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
725 | i = 0; |
- | 726 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
|
683 | int output_type = ACPI_OTHER_OUTPUT; |
727 | int output_type = ACPI_OTHER_OUTPUT; |
684 | if (i >= 8) { |
728 | if (i >= max_outputs) { |
685 | dev_dbg(&dev->pdev->dev, |
729 | DRM_DEBUG_KMS("More than %u outputs in connector list\n", |
686 | "More than 8 outputs in connector list\n"); |
730 | max_outputs); |
687 | return; |
731 | return; |
Line 706... | Line 750... | ||
706 | break; |
750 | break; |
707 | case DRM_MODE_CONNECTOR_LVDS: |
751 | case DRM_MODE_CONNECTOR_LVDS: |
708 | output_type = ACPI_LVDS_OUTPUT; |
752 | output_type = ACPI_LVDS_OUTPUT; |
709 | break; |
753 | break; |
710 | } |
754 | } |
711 | temp = ioread32(&opregion->acpi->didl[i]); |
755 | temp = get_did(opregion, i); |
712 | iowrite32(temp | (1<<31) | output_type | i, |
756 | set_did(opregion, i, temp | (1 << 31) | output_type | i); |
713 | &opregion->acpi->didl[i]); |
- | |
714 | i++; |
757 | i++; |
715 | } |
758 | } |
716 | goto end; |
759 | goto end; |
717 | } |
760 | } |
Line 728... | Line 771... | ||
728 | * but not active. This initialization is necessary for some Clevo |
771 | * but not active. This initialization is necessary for some Clevo |
729 | * laptops that check this field before processing the brightness and |
772 | * laptops that check this field before processing the brightness and |
730 | * display switching hotkeys. Just like DIDL, CADL is NULL-terminated if |
773 | * display switching hotkeys. Just like DIDL, CADL is NULL-terminated if |
731 | * there are less than eight devices. */ |
774 | * there are less than eight devices. */ |
732 | do { |
775 | do { |
733 | disp_id = ioread32(&opregion->acpi->didl[i]); |
776 | disp_id = get_did(opregion, i); |
734 | iowrite32(disp_id, &opregion->acpi->cadl[i]); |
777 | opregion->acpi->cadl[i] = disp_id; |
735 | } while (++i < 8 && disp_id != 0); |
778 | } while (++i < 8 && disp_id != 0); |
736 | } |
779 | } |
Line 737... | Line 780... | ||
737 | 780 | ||
738 | void intel_opregion_init(struct drm_device *dev) |
781 | void intel_opregion_init(struct drm_device *dev) |
Line 742... | Line 785... | ||
742 | 785 | ||
743 | if (!opregion->header) |
786 | if (!opregion->header) |
Line 744... | Line 787... | ||
744 | return; |
787 | return; |
745 | - | ||
746 | if (opregion->acpi) { |
788 | |
747 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
789 | if (opregion->acpi) { |
748 | intel_didl_outputs(dev); |
- | |
Line 749... | Line 790... | ||
749 | intel_setup_cadls(dev); |
790 | intel_didl_outputs(dev); |
750 | } |
791 | intel_setup_cadls(dev); |
751 | 792 | ||
752 | /* Notify BIOS we are ready to handle ACPI video ext notifs. |
793 | /* Notify BIOS we are ready to handle ACPI video ext notifs. |
753 | * Right now, all the events are handled by the ACPI video module. |
794 | * Right now, all the events are handled by the ACPI video module. |
Line 754... | Line 795... | ||
754 | * We don't actually need to do anything with them. */ |
795 | * We don't actually need to do anything with them. */ |
755 | iowrite32(0, &opregion->acpi->csts); |
796 | opregion->acpi->csts = 0; |
756 | iowrite32(1, &opregion->acpi->drdy); |
797 | opregion->acpi->drdy = 1; |
Line 757... | Line 798... | ||
757 | 798 | ||
758 | system_opregion = opregion; |
799 | system_opregion = opregion; |
759 | register_acpi_notifier(&intel_opregion_notifier); |
800 | register_acpi_notifier(&intel_opregion_notifier); |
760 | } |
801 | } |
761 | 802 | ||
Line 762... | Line 803... | ||
762 | if (opregion->asle) { |
803 | if (opregion->asle) { |
763 | iowrite32(ASLE_TCHE_BLC_EN, &opregion->asle->tche); |
804 | opregion->asle->tche = ASLE_TCHE_BLC_EN; |
Line 772... | Line 813... | ||
772 | 813 | ||
773 | if (!opregion->header) |
814 | if (!opregion->header) |
Line 774... | Line 815... | ||
774 | return; |
815 | return; |
775 | 816 | ||
Line 776... | Line 817... | ||
776 | if (opregion->asle) |
817 | if (opregion->asle) |
Line 777... | Line 818... | ||
777 | iowrite32(ASLE_ARDY_NOT_READY, &opregion->asle->ardy); |
818 | opregion->asle->ardy = ASLE_ARDY_NOT_READY; |
778 | 819 | ||
Line 779... | Line 820... | ||
779 | cancel_work_sync(&dev_priv->opregion.asle_work); |
820 | cancel_work_sync(&dev_priv->opregion.asle_work); |
780 | 821 | ||
781 | if (opregion->acpi) { |
822 | if (opregion->acpi) { |
Line 782... | Line 823... | ||
782 | iowrite32(0, &opregion->acpi->drdy); |
823 | opregion->acpi->drdy = 0; |
783 | 824 | ||
784 | system_opregion = NULL; |
825 | system_opregion = NULL; |
785 | unregister_acpi_notifier(&intel_opregion_notifier); |
826 | unregister_acpi_notifier(&intel_opregion_notifier); |
786 | } |
827 | } |
787 | 828 | ||
788 | /* just clear all opregion memory pointers now */ |
829 | /* just clear all opregion memory pointers now */ |
Line 857... | Line 898... | ||
857 | 898 | ||
858 | int intel_opregion_setup(struct drm_device *dev) |
899 | int intel_opregion_setup(struct drm_device *dev) |
859 | { |
900 | { |
860 | struct drm_i915_private *dev_priv = dev->dev_private; |
901 | struct drm_i915_private *dev_priv = dev->dev_private; |
861 | struct intel_opregion *opregion = &dev_priv->opregion; |
- | |
862 | void __iomem *base; |
902 | struct intel_opregion *opregion = &dev_priv->opregion; |
863 | u32 asls, mboxes; |
903 | u32 asls, mboxes; |
864 | char buf[sizeof(OPREGION_SIGNATURE)]; |
904 | char buf[sizeof(OPREGION_SIGNATURE)]; |
- | 905 | int err = 0; |
|
- | 906 | void *base; |
|
- | 907 | ||
- | 908 | BUILD_BUG_ON(sizeof(struct opregion_header) != 0x100); |
|
- | 909 | BUILD_BUG_ON(sizeof(struct opregion_acpi) != 0x100); |
|
- | 910 | BUILD_BUG_ON(sizeof(struct opregion_swsci) != 0x100); |
|
Line 865... | Line 911... | ||
865 | int err = 0; |
911 | BUILD_BUG_ON(sizeof(struct opregion_asle) != 0x100); |
866 | 912 | ||
867 | pci_read_config_dword(dev->pdev, PCI_ASLS, &asls); |
913 | pci_read_config_dword(dev->pdev, PCI_ASLS, &asls); |
868 | DRM_DEBUG_DRIVER("graphic opregion physical addr: 0x%x\n", asls); |
914 | DRM_DEBUG_DRIVER("graphic opregion physical addr: 0x%x\n", asls); |
Line 873... | Line 919... | ||
873 | 919 | ||
874 | #ifdef CONFIG_ACPI |
920 | #ifdef CONFIG_ACPI |
875 | INIT_WORK(&opregion->asle_work, asle_work); |
921 | INIT_WORK(&opregion->asle_work, asle_work); |
Line 876... | Line 922... | ||
876 | #endif |
922 | #endif |
877 | 923 | ||
878 | base = acpi_os_ioremap(asls, OPREGION_SIZE); |
924 | base = memremap(asls, OPREGION_SIZE, MEMREMAP_WB); |
Line 879... | Line 925... | ||
879 | if (!base) |
925 | if (!base) |
Line 880... | Line 926... | ||
880 | return -ENOMEM; |
926 | return -ENOMEM; |
881 | 927 | ||
882 | memcpy_fromio(buf, base, sizeof(buf)); |
928 | memcpy(buf, base, sizeof(buf)); |
883 | 929 | ||
Line 889... | Line 935... | ||
889 | opregion->header = base; |
935 | opregion->header = base; |
890 | opregion->vbt = base + OPREGION_VBT_OFFSET; |
936 | opregion->vbt = base + OPREGION_VBT_OFFSET; |
Line 891... | Line 937... | ||
891 | 937 | ||
Line 892... | Line 938... | ||
892 | opregion->lid_state = base + ACPI_CLID; |
938 | opregion->lid_state = base + ACPI_CLID; |
893 | 939 | ||
894 | mboxes = ioread32(&opregion->header->mboxes); |
940 | mboxes = opregion->header->mboxes; |
895 | if (mboxes & MBOX_ACPI) { |
941 | if (mboxes & MBOX_ACPI) { |
896 | DRM_DEBUG_DRIVER("Public ACPI methods supported\n"); |
942 | DRM_DEBUG_DRIVER("Public ACPI methods supported\n"); |
Line 904... | Line 950... | ||
904 | } |
950 | } |
905 | if (mboxes & MBOX_ASLE) { |
951 | if (mboxes & MBOX_ASLE) { |
906 | DRM_DEBUG_DRIVER("ASLE supported\n"); |
952 | DRM_DEBUG_DRIVER("ASLE supported\n"); |
907 | opregion->asle = base + OPREGION_ASLE_OFFSET; |
953 | opregion->asle = base + OPREGION_ASLE_OFFSET; |
Line 908... | Line 954... | ||
908 | 954 | ||
909 | iowrite32(ASLE_ARDY_NOT_READY, &opregion->asle->ardy); |
955 | opregion->asle->ardy = ASLE_ARDY_NOT_READY; |
Line 910... | Line 956... | ||
910 | } |
956 | } |
Line 911... | Line 957... | ||
911 | 957 | ||
912 | return 0; |
958 | return 0; |
913 | 959 | ||
914 | err_out: |
960 | err_out: |