.. | .. |
---|
29 | 29 | #include <linux/pm_runtime.h> |
---|
30 | 30 | #include <linux/vga_switcheroo.h> |
---|
31 | 31 | |
---|
32 | | -#include <drm/drmP.h> |
---|
33 | 32 | #include <drm/drm_atomic_helper.h> |
---|
34 | 33 | #include <drm/drm_edid.h> |
---|
35 | 34 | #include <drm/drm_crtc_helper.h> |
---|
| 35 | +#include <drm/drm_probe_helper.h> |
---|
36 | 36 | #include <drm/drm_atomic.h> |
---|
37 | 37 | |
---|
38 | 38 | #include "nouveau_reg.h" |
---|
39 | 39 | #include "nouveau_drv.h" |
---|
40 | 40 | #include "dispnv04/hw.h" |
---|
| 41 | +#include "dispnv50/disp.h" |
---|
41 | 42 | #include "nouveau_acpi.h" |
---|
42 | 43 | |
---|
43 | 44 | #include "nouveau_display.h" |
---|
.. | .. |
---|
59 | 60 | int high_w = 0, high_h = 0, high_v = 0; |
---|
60 | 61 | |
---|
61 | 62 | list_for_each_entry(mode, &connector->probed_modes, head) { |
---|
62 | | - mode->vrefresh = drm_mode_vrefresh(mode); |
---|
63 | 63 | if (helper->mode_valid(connector, mode) != MODE_OK || |
---|
64 | 64 | (mode->flags & DRM_MODE_FLAG_INTERLACE)) |
---|
65 | 65 | continue; |
---|
.. | .. |
---|
80 | 80 | continue; |
---|
81 | 81 | |
---|
82 | 82 | if (mode->hdisplay == high_w && mode->vdisplay == high_h && |
---|
83 | | - mode->vrefresh < high_v) |
---|
| 83 | + drm_mode_vrefresh(mode) < high_v) |
---|
84 | 84 | continue; |
---|
85 | 85 | |
---|
86 | 86 | high_w = mode->hdisplay; |
---|
87 | 87 | high_h = mode->vdisplay; |
---|
88 | | - high_v = mode->vrefresh; |
---|
| 88 | + high_v = drm_mode_vrefresh(mode); |
---|
89 | 89 | largest = mode; |
---|
90 | 90 | } |
---|
91 | 91 | |
---|
.. | .. |
---|
245 | 245 | void |
---|
246 | 246 | nouveau_conn_reset(struct drm_connector *connector) |
---|
247 | 247 | { |
---|
| 248 | + struct nouveau_connector *nv_connector = nouveau_connector(connector); |
---|
248 | 249 | struct nouveau_conn_atom *asyc; |
---|
249 | 250 | |
---|
250 | | - if (WARN_ON(!(asyc = kzalloc(sizeof(*asyc), GFP_KERNEL)))) |
---|
251 | | - return; |
---|
| 251 | + if (drm_drv_uses_atomic_modeset(connector->dev)) { |
---|
| 252 | + if (WARN_ON(!(asyc = kzalloc(sizeof(*asyc), GFP_KERNEL)))) |
---|
| 253 | + return; |
---|
252 | 254 | |
---|
253 | | - if (connector->state) |
---|
254 | | - nouveau_conn_atomic_destroy_state(connector, connector->state); |
---|
255 | | - __drm_atomic_helper_connector_reset(connector, &asyc->state); |
---|
| 255 | + if (connector->state) |
---|
| 256 | + nouveau_conn_atomic_destroy_state(connector, |
---|
| 257 | + connector->state); |
---|
| 258 | + |
---|
| 259 | + __drm_atomic_helper_connector_reset(connector, &asyc->state); |
---|
| 260 | + } else { |
---|
| 261 | + asyc = &nv_connector->properties_state; |
---|
| 262 | + } |
---|
| 263 | + |
---|
256 | 264 | asyc->dither.mode = DITHERING_MODE_AUTO; |
---|
257 | 265 | asyc->dither.depth = DITHERING_DEPTH_AUTO; |
---|
258 | 266 | asyc->scaler.mode = DRM_MODE_SCALE_NONE; |
---|
.. | .. |
---|
276 | 284 | nouveau_conn_attach_properties(struct drm_connector *connector) |
---|
277 | 285 | { |
---|
278 | 286 | struct drm_device *dev = connector->dev; |
---|
279 | | - struct nouveau_conn_atom *armc = nouveau_conn_atom(connector->state); |
---|
280 | 287 | struct nouveau_display *disp = nouveau_display(dev); |
---|
| 288 | + struct nouveau_connector *nv_connector = nouveau_connector(connector); |
---|
| 289 | + struct nouveau_conn_atom *armc; |
---|
| 290 | + |
---|
| 291 | + if (drm_drv_uses_atomic_modeset(connector->dev)) |
---|
| 292 | + armc = nouveau_conn_atom(connector->state); |
---|
| 293 | + else |
---|
| 294 | + armc = &nv_connector->properties_state; |
---|
281 | 295 | |
---|
282 | 296 | /* Init DVI-I specific properties. */ |
---|
283 | 297 | if (connector->connector_type == DRM_MODE_CONNECTOR_DVII) |
---|
.. | .. |
---|
316 | 330 | case DRM_MODE_CONNECTOR_VGA: |
---|
317 | 331 | if (disp->disp.object.oclass < NV50_DISP) |
---|
318 | 332 | break; /* Can only scale on DFPs. */ |
---|
319 | | - /* Fall-through. */ |
---|
| 333 | + fallthrough; |
---|
320 | 334 | default: |
---|
321 | 335 | drm_object_attach_property(&connector->base, dev->mode_config. |
---|
322 | 336 | scaling_mode_property, |
---|
.. | .. |
---|
365 | 379 | { |
---|
366 | 380 | struct nouveau_encoder *nv_encoder; |
---|
367 | 381 | struct drm_encoder *enc; |
---|
368 | | - int i; |
---|
369 | 382 | |
---|
370 | | - drm_connector_for_each_possible_encoder(connector, enc, i) { |
---|
| 383 | + drm_connector_for_each_possible_encoder(connector, enc) { |
---|
371 | 384 | nv_encoder = nouveau_encoder(enc); |
---|
372 | 385 | |
---|
373 | 386 | if (type == DCB_OUTPUT_ANY || |
---|
.. | .. |
---|
378 | 391 | return NULL; |
---|
379 | 392 | } |
---|
380 | 393 | |
---|
381 | | -struct nouveau_connector * |
---|
382 | | -nouveau_encoder_connector_get(struct nouveau_encoder *encoder) |
---|
383 | | -{ |
---|
384 | | - struct drm_device *dev = to_drm_encoder(encoder)->dev; |
---|
385 | | - struct drm_connector *drm_connector; |
---|
386 | | - |
---|
387 | | - list_for_each_entry(drm_connector, &dev->mode_config.connector_list, head) { |
---|
388 | | - if (drm_connector->encoder == to_drm_encoder(encoder)) |
---|
389 | | - return nouveau_connector(drm_connector); |
---|
390 | | - } |
---|
391 | | - |
---|
392 | | - return NULL; |
---|
393 | | -} |
---|
394 | | - |
---|
395 | 394 | static void |
---|
396 | 395 | nouveau_connector_destroy(struct drm_connector *connector) |
---|
397 | 396 | { |
---|
398 | 397 | struct nouveau_connector *nv_connector = nouveau_connector(connector); |
---|
399 | | - nvif_notify_fini(&nv_connector->hpd); |
---|
| 398 | + nvif_notify_dtor(&nv_connector->hpd); |
---|
400 | 399 | kfree(nv_connector->edid); |
---|
401 | 400 | drm_connector_unregister(connector); |
---|
402 | 401 | drm_connector_cleanup(connector); |
---|
403 | | - if (nv_connector->aux.transfer) |
---|
| 402 | + if (nv_connector->aux.transfer) { |
---|
| 403 | + drm_dp_cec_unregister_connector(&nv_connector->aux); |
---|
404 | 404 | drm_dp_aux_unregister(&nv_connector->aux); |
---|
| 405 | + kfree(nv_connector->aux.name); |
---|
| 406 | + } |
---|
405 | 407 | kfree(connector); |
---|
406 | 408 | } |
---|
407 | 409 | |
---|
.. | .. |
---|
411 | 413 | struct drm_device *dev = connector->dev; |
---|
412 | 414 | struct nouveau_encoder *nv_encoder = NULL, *found = NULL; |
---|
413 | 415 | struct drm_encoder *encoder; |
---|
414 | | - int i, ret; |
---|
| 416 | + int ret; |
---|
415 | 417 | bool switcheroo_ddc = false; |
---|
416 | 418 | |
---|
417 | | - drm_connector_for_each_possible_encoder(connector, encoder, i) { |
---|
| 419 | + drm_connector_for_each_possible_encoder(connector, encoder) { |
---|
418 | 420 | nv_encoder = nouveau_encoder(encoder); |
---|
419 | 421 | |
---|
420 | 422 | switch (nv_encoder->dcb->type) { |
---|
421 | 423 | case DCB_OUTPUT_DP: |
---|
422 | | - ret = nouveau_dp_detect(nv_encoder); |
---|
| 424 | + ret = nouveau_dp_detect(nouveau_connector(connector), |
---|
| 425 | + nv_encoder); |
---|
423 | 426 | if (ret == NOUVEAU_DP_MST) |
---|
424 | 427 | return NULL; |
---|
425 | 428 | else if (ret == NOUVEAU_DP_SST) |
---|
.. | .. |
---|
429 | 432 | case DCB_OUTPUT_LVDS: |
---|
430 | 433 | switcheroo_ddc = !!(vga_switcheroo_handler_flags() & |
---|
431 | 434 | VGA_SWITCHEROO_CAN_SWITCH_DDC); |
---|
432 | | - /* fall-through */ |
---|
| 435 | + fallthrough; |
---|
433 | 436 | default: |
---|
434 | 437 | if (!nv_encoder->i2c) |
---|
435 | 438 | break; |
---|
.. | .. |
---|
493 | 496 | nv_connector->detected_encoder = nv_encoder; |
---|
494 | 497 | |
---|
495 | 498 | if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA) { |
---|
496 | | - connector->interlace_allowed = true; |
---|
| 499 | + if (nv_encoder->dcb->type == DCB_OUTPUT_DP) |
---|
| 500 | + connector->interlace_allowed = |
---|
| 501 | + nv_encoder->caps.dp_interlace; |
---|
| 502 | + else |
---|
| 503 | + connector->interlace_allowed = |
---|
| 504 | + drm->client.device.info.family < NV_DEVICE_INFO_V0_VOLTA; |
---|
497 | 505 | connector->doublescan_allowed = true; |
---|
498 | 506 | } else |
---|
499 | 507 | if (nv_encoder->dcb->type == DCB_OUTPUT_LVDS || |
---|
.. | .. |
---|
521 | 529 | } |
---|
522 | 530 | } |
---|
523 | 531 | |
---|
| 532 | +static void |
---|
| 533 | +nouveau_connector_set_edid(struct nouveau_connector *nv_connector, |
---|
| 534 | + struct edid *edid) |
---|
| 535 | +{ |
---|
| 536 | + if (nv_connector->edid != edid) { |
---|
| 537 | + struct edid *old_edid = nv_connector->edid; |
---|
| 538 | + |
---|
| 539 | + drm_connector_update_edid_property(&nv_connector->base, edid); |
---|
| 540 | + kfree(old_edid); |
---|
| 541 | + nv_connector->edid = edid; |
---|
| 542 | + } |
---|
| 543 | +} |
---|
| 544 | + |
---|
524 | 545 | static enum drm_connector_status |
---|
525 | 546 | nouveau_connector_detect(struct drm_connector *connector, bool force) |
---|
526 | 547 | { |
---|
.. | .. |
---|
534 | 555 | int ret; |
---|
535 | 556 | enum drm_connector_status conn_status = connector_status_disconnected; |
---|
536 | 557 | |
---|
537 | | - /* Cleanup the previous EDID block. */ |
---|
538 | | - if (nv_connector->edid) { |
---|
539 | | - drm_connector_update_edid_property(connector, NULL); |
---|
540 | | - kfree(nv_connector->edid); |
---|
541 | | - nv_connector->edid = NULL; |
---|
542 | | - } |
---|
543 | | - |
---|
544 | 558 | /* Outputs are only polled while runtime active, so resuming the |
---|
545 | 559 | * device here is unnecessary (and would deadlock upon runtime suspend |
---|
546 | 560 | * because it waits for polling to finish). We do however, want to |
---|
.. | .. |
---|
553 | 567 | ret = pm_runtime_get_sync(dev->dev); |
---|
554 | 568 | if (ret < 0 && ret != -EACCES) { |
---|
555 | 569 | pm_runtime_put_autosuspend(dev->dev); |
---|
| 570 | + nouveau_connector_set_edid(nv_connector, NULL); |
---|
556 | 571 | return conn_status; |
---|
557 | 572 | } |
---|
558 | 573 | } |
---|
559 | 574 | |
---|
560 | 575 | nv_encoder = nouveau_connector_ddc_detect(connector); |
---|
561 | 576 | if (nv_encoder && (i2c = nv_encoder->i2c) != NULL) { |
---|
| 577 | + struct edid *new_edid; |
---|
| 578 | + |
---|
562 | 579 | if ((vga_switcheroo_handler_flags() & |
---|
563 | 580 | VGA_SWITCHEROO_CAN_SWITCH_DDC) && |
---|
564 | 581 | nv_connector->type == DCB_CONNECTOR_LVDS) |
---|
565 | | - nv_connector->edid = drm_get_edid_switcheroo(connector, |
---|
566 | | - i2c); |
---|
| 582 | + new_edid = drm_get_edid_switcheroo(connector, i2c); |
---|
567 | 583 | else |
---|
568 | | - nv_connector->edid = drm_get_edid(connector, i2c); |
---|
| 584 | + new_edid = drm_get_edid(connector, i2c); |
---|
569 | 585 | |
---|
570 | | - drm_connector_update_edid_property(connector, |
---|
571 | | - nv_connector->edid); |
---|
| 586 | + nouveau_connector_set_edid(nv_connector, new_edid); |
---|
572 | 587 | if (!nv_connector->edid) { |
---|
573 | 588 | NV_ERROR(drm, "DDC responded, but no EDID for %s\n", |
---|
574 | 589 | connector->name); |
---|
.. | .. |
---|
600 | 615 | |
---|
601 | 616 | nouveau_connector_set_encoder(connector, nv_encoder); |
---|
602 | 617 | conn_status = connector_status_connected; |
---|
| 618 | + drm_dp_cec_set_edid(&nv_connector->aux, nv_connector->edid); |
---|
603 | 619 | goto out; |
---|
| 620 | + } else { |
---|
| 621 | + nouveau_connector_set_edid(nv_connector, NULL); |
---|
604 | 622 | } |
---|
605 | 623 | |
---|
606 | 624 | nv_encoder = nouveau_connector_of_detect(connector); |
---|
.. | .. |
---|
625 | 643 | conn_status = connector_status_connected; |
---|
626 | 644 | goto out; |
---|
627 | 645 | } |
---|
628 | | - |
---|
629 | 646 | } |
---|
630 | 647 | |
---|
631 | 648 | out: |
---|
| 649 | + if (!nv_connector->edid) |
---|
| 650 | + drm_dp_cec_unset_edid(&nv_connector->aux); |
---|
632 | 651 | |
---|
633 | 652 | pm_runtime_mark_last_busy(dev->dev); |
---|
634 | 653 | pm_runtime_put_autosuspend(dev->dev); |
---|
.. | .. |
---|
643 | 662 | struct nouveau_drm *drm = nouveau_drm(dev); |
---|
644 | 663 | struct nouveau_connector *nv_connector = nouveau_connector(connector); |
---|
645 | 664 | struct nouveau_encoder *nv_encoder = NULL; |
---|
| 665 | + struct edid *edid = NULL; |
---|
646 | 666 | enum drm_connector_status status = connector_status_disconnected; |
---|
647 | | - |
---|
648 | | - /* Cleanup the previous EDID block. */ |
---|
649 | | - if (nv_connector->edid) { |
---|
650 | | - drm_connector_update_edid_property(connector, NULL); |
---|
651 | | - kfree(nv_connector->edid); |
---|
652 | | - nv_connector->edid = NULL; |
---|
653 | | - } |
---|
654 | 667 | |
---|
655 | 668 | nv_encoder = find_encoder(connector, DCB_OUTPUT_LVDS); |
---|
656 | 669 | if (!nv_encoder) |
---|
657 | | - return connector_status_disconnected; |
---|
| 670 | + goto out; |
---|
658 | 671 | |
---|
659 | 672 | /* Try retrieving EDID via DDC */ |
---|
660 | 673 | if (!drm->vbios.fp_no_ddc) { |
---|
661 | 674 | status = nouveau_connector_detect(connector, force); |
---|
662 | | - if (status == connector_status_connected) |
---|
| 675 | + if (status == connector_status_connected) { |
---|
| 676 | + edid = nv_connector->edid; |
---|
663 | 677 | goto out; |
---|
| 678 | + } |
---|
664 | 679 | } |
---|
665 | 680 | |
---|
666 | 681 | /* On some laptops (Sony, i'm looking at you) there appears to |
---|
.. | .. |
---|
673 | 688 | * valid - it's not (rh#613284) |
---|
674 | 689 | */ |
---|
675 | 690 | if (nv_encoder->dcb->lvdsconf.use_acpi_for_edid) { |
---|
676 | | - if ((nv_connector->edid = nouveau_acpi_edid(dev, connector))) { |
---|
| 691 | + edid = nouveau_acpi_edid(dev, connector); |
---|
| 692 | + if (edid) { |
---|
677 | 693 | status = connector_status_connected; |
---|
678 | 694 | goto out; |
---|
679 | 695 | } |
---|
.. | .. |
---|
693 | 709 | * stored for the panel stored in them. |
---|
694 | 710 | */ |
---|
695 | 711 | if (!drm->vbios.fp_no_ddc) { |
---|
696 | | - struct edid *edid = |
---|
697 | | - (struct edid *)nouveau_bios_embedded_edid(dev); |
---|
| 712 | + edid = (struct edid *)nouveau_bios_embedded_edid(dev); |
---|
698 | 713 | if (edid) { |
---|
699 | | - nv_connector->edid = |
---|
700 | | - kmemdup(edid, EDID_LENGTH, GFP_KERNEL); |
---|
701 | | - if (nv_connector->edid) |
---|
| 714 | + edid = kmemdup(edid, EDID_LENGTH, GFP_KERNEL); |
---|
| 715 | + if (edid) |
---|
702 | 716 | status = connector_status_connected; |
---|
703 | 717 | } |
---|
704 | 718 | } |
---|
.. | .. |
---|
711 | 725 | status = connector_status_unknown; |
---|
712 | 726 | #endif |
---|
713 | 727 | |
---|
714 | | - drm_connector_update_edid_property(connector, nv_connector->edid); |
---|
715 | | - nouveau_connector_set_encoder(connector, nv_encoder); |
---|
| 728 | + nouveau_connector_set_edid(nv_connector, edid); |
---|
| 729 | + if (nv_encoder) |
---|
| 730 | + nouveau_connector_set_encoder(connector, nv_encoder); |
---|
716 | 731 | return status; |
---|
717 | 732 | } |
---|
718 | 733 | |
---|
.. | .. |
---|
747 | 762 | nouveau_connector_set_property(struct drm_connector *connector, |
---|
748 | 763 | struct drm_property *property, uint64_t value) |
---|
749 | 764 | { |
---|
750 | | - struct nouveau_conn_atom *asyc = nouveau_conn_atom(connector->state); |
---|
751 | 765 | struct nouveau_connector *nv_connector = nouveau_connector(connector); |
---|
752 | 766 | struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; |
---|
| 767 | + struct nouveau_conn_atom *asyc = &nv_connector->properties_state; |
---|
753 | 768 | struct drm_encoder *encoder = to_drm_encoder(nv_encoder); |
---|
754 | 769 | int ret; |
---|
755 | 770 | |
---|
.. | .. |
---|
885 | 900 | } |
---|
886 | 901 | |
---|
887 | 902 | static int |
---|
| 903 | +nouveau_connector_late_register(struct drm_connector *connector) |
---|
| 904 | +{ |
---|
| 905 | + int ret; |
---|
| 906 | + |
---|
| 907 | + ret = nouveau_backlight_init(connector); |
---|
| 908 | + |
---|
| 909 | + return ret; |
---|
| 910 | +} |
---|
| 911 | + |
---|
| 912 | +static void |
---|
| 913 | +nouveau_connector_early_unregister(struct drm_connector *connector) |
---|
| 914 | +{ |
---|
| 915 | + nouveau_backlight_fini(connector); |
---|
| 916 | +} |
---|
| 917 | + |
---|
| 918 | +static int |
---|
888 | 919 | nouveau_connector_get_modes(struct drm_connector *connector) |
---|
889 | 920 | { |
---|
890 | 921 | struct drm_device *dev = connector->dev; |
---|
.. | .. |
---|
937 | 968 | * "native" mode as some VBIOS tables require us to use the |
---|
938 | 969 | * pixel clock as part of the lookup... |
---|
939 | 970 | */ |
---|
940 | | - if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS) |
---|
| 971 | + if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS && nv_connector->native_mode) |
---|
941 | 972 | nouveau_connector_detect_depth(connector); |
---|
942 | 973 | |
---|
943 | 974 | if (nv_encoder->dcb->type == DCB_OUTPUT_TV) |
---|
.. | .. |
---|
952 | 983 | } |
---|
953 | 984 | |
---|
954 | 985 | static unsigned |
---|
955 | | -get_tmds_link_bandwidth(struct drm_connector *connector, bool hdmi) |
---|
| 986 | +get_tmds_link_bandwidth(struct drm_connector *connector) |
---|
956 | 987 | { |
---|
957 | 988 | struct nouveau_connector *nv_connector = nouveau_connector(connector); |
---|
| 989 | + struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; |
---|
958 | 990 | struct nouveau_drm *drm = nouveau_drm(connector->dev); |
---|
959 | 991 | struct dcb_output *dcb = nv_connector->detected_encoder->dcb; |
---|
| 992 | + struct drm_display_info *info = NULL; |
---|
| 993 | + unsigned duallink_scale = |
---|
| 994 | + nouveau_duallink && nv_encoder->dcb->duallink_possible ? 2 : 1; |
---|
960 | 995 | |
---|
961 | | - if (hdmi) { |
---|
| 996 | + if (drm_detect_hdmi_monitor(nv_connector->edid)) { |
---|
| 997 | + info = &nv_connector->base.display_info; |
---|
| 998 | + duallink_scale = 1; |
---|
| 999 | + } |
---|
| 1000 | + |
---|
| 1001 | + if (info) { |
---|
962 | 1002 | if (nouveau_hdmimhz > 0) |
---|
963 | 1003 | return nouveau_hdmimhz * 1000; |
---|
964 | 1004 | /* Note: these limits are conservative, some Fermi's |
---|
965 | 1005 | * can do 297 MHz. Unclear how this can be determined. |
---|
966 | 1006 | */ |
---|
| 1007 | + if (drm->client.device.info.chipset >= 0x120) { |
---|
| 1008 | + const int max_tmds_clock = |
---|
| 1009 | + info->hdmi.scdc.scrambling.supported ? |
---|
| 1010 | + 594000 : 340000; |
---|
| 1011 | + return info->max_tmds_clock ? |
---|
| 1012 | + min(info->max_tmds_clock, max_tmds_clock) : |
---|
| 1013 | + max_tmds_clock; |
---|
| 1014 | + } |
---|
967 | 1015 | if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_KEPLER) |
---|
968 | 1016 | return 297000; |
---|
969 | 1017 | if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_FERMI) |
---|
970 | 1018 | return 225000; |
---|
971 | 1019 | } |
---|
| 1020 | + |
---|
972 | 1021 | if (dcb->location != DCB_LOC_ON_CHIP || |
---|
973 | 1022 | drm->client.device.info.chipset >= 0x46) |
---|
974 | | - return 165000; |
---|
| 1023 | + return 165000 * duallink_scale; |
---|
975 | 1024 | else if (drm->client.device.info.chipset >= 0x40) |
---|
976 | | - return 155000; |
---|
| 1025 | + return 155000 * duallink_scale; |
---|
977 | 1026 | else if (drm->client.device.info.chipset >= 0x18) |
---|
978 | | - return 135000; |
---|
| 1027 | + return 135000 * duallink_scale; |
---|
979 | 1028 | else |
---|
980 | | - return 112000; |
---|
| 1029 | + return 112000 * duallink_scale; |
---|
981 | 1030 | } |
---|
982 | 1031 | |
---|
983 | 1032 | static enum drm_mode_status |
---|
.. | .. |
---|
987 | 1036 | struct nouveau_connector *nv_connector = nouveau_connector(connector); |
---|
988 | 1037 | struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; |
---|
989 | 1038 | struct drm_encoder *encoder = to_drm_encoder(nv_encoder); |
---|
990 | | - unsigned min_clock = 25000, max_clock = min_clock; |
---|
991 | | - unsigned clock = mode->clock; |
---|
992 | | - bool hdmi; |
---|
| 1039 | + unsigned int min_clock = 25000, max_clock = min_clock, clock = mode->clock; |
---|
993 | 1040 | |
---|
994 | 1041 | switch (nv_encoder->dcb->type) { |
---|
995 | 1042 | case DCB_OUTPUT_LVDS: |
---|
.. | .. |
---|
1002 | 1049 | max_clock = 400000; |
---|
1003 | 1050 | break; |
---|
1004 | 1051 | case DCB_OUTPUT_TMDS: |
---|
1005 | | - hdmi = drm_detect_hdmi_monitor(nv_connector->edid); |
---|
1006 | | - max_clock = get_tmds_link_bandwidth(connector, hdmi); |
---|
1007 | | - if (!hdmi && nouveau_duallink && |
---|
1008 | | - nv_encoder->dcb->duallink_possible) |
---|
1009 | | - max_clock *= 2; |
---|
| 1052 | + max_clock = get_tmds_link_bandwidth(connector); |
---|
1010 | 1053 | break; |
---|
1011 | 1054 | case DCB_OUTPUT_ANALOG: |
---|
1012 | 1055 | max_clock = nv_encoder->dcb->crtconf.maxfreq; |
---|
.. | .. |
---|
1016 | 1059 | case DCB_OUTPUT_TV: |
---|
1017 | 1060 | return get_slave_funcs(encoder)->mode_valid(encoder, mode); |
---|
1018 | 1061 | case DCB_OUTPUT_DP: |
---|
1019 | | - max_clock = nv_encoder->dp.link_nr; |
---|
1020 | | - max_clock *= nv_encoder->dp.link_bw; |
---|
1021 | | - clock = clock * (connector->display_info.bpc * 3) / 10; |
---|
1022 | | - break; |
---|
| 1062 | + return nv50_dp_mode_valid(connector, nv_encoder, mode, NULL); |
---|
1023 | 1063 | default: |
---|
1024 | 1064 | BUG(); |
---|
1025 | 1065 | return MODE_BAD; |
---|
.. | .. |
---|
1030 | 1070 | |
---|
1031 | 1071 | if (clock < min_clock) |
---|
1032 | 1072 | return MODE_CLOCK_LOW; |
---|
1033 | | - |
---|
1034 | 1073 | if (clock > max_clock) |
---|
1035 | 1074 | return MODE_CLOCK_HIGH; |
---|
1036 | 1075 | |
---|
.. | .. |
---|
1068 | 1107 | .atomic_destroy_state = nouveau_conn_atomic_destroy_state, |
---|
1069 | 1108 | .atomic_set_property = nouveau_conn_atomic_set_property, |
---|
1070 | 1109 | .atomic_get_property = nouveau_conn_atomic_get_property, |
---|
| 1110 | + .late_register = nouveau_connector_late_register, |
---|
| 1111 | + .early_unregister = nouveau_connector_early_unregister, |
---|
1071 | 1112 | }; |
---|
1072 | 1113 | |
---|
1073 | 1114 | static const struct drm_connector_funcs |
---|
.. | .. |
---|
1083 | 1124 | .atomic_destroy_state = nouveau_conn_atomic_destroy_state, |
---|
1084 | 1125 | .atomic_set_property = nouveau_conn_atomic_set_property, |
---|
1085 | 1126 | .atomic_get_property = nouveau_conn_atomic_get_property, |
---|
| 1127 | + .late_register = nouveau_connector_late_register, |
---|
| 1128 | + .early_unregister = nouveau_connector_early_unregister, |
---|
1086 | 1129 | }; |
---|
| 1130 | + |
---|
| 1131 | +void |
---|
| 1132 | +nouveau_connector_hpd(struct drm_connector *connector) |
---|
| 1133 | +{ |
---|
| 1134 | + struct nouveau_drm *drm = nouveau_drm(connector->dev); |
---|
| 1135 | + u32 mask = drm_connector_mask(connector); |
---|
| 1136 | + |
---|
| 1137 | + mutex_lock(&drm->hpd_lock); |
---|
| 1138 | + if (!(drm->hpd_pending & mask)) { |
---|
| 1139 | + drm->hpd_pending |= mask; |
---|
| 1140 | + schedule_work(&drm->hpd_work); |
---|
| 1141 | + } |
---|
| 1142 | + mutex_unlock(&drm->hpd_lock); |
---|
| 1143 | +} |
---|
1087 | 1144 | |
---|
1088 | 1145 | static int |
---|
1089 | 1146 | nouveau_connector_hotplug(struct nvif_notify *notify) |
---|
.. | .. |
---|
1091 | 1148 | struct nouveau_connector *nv_connector = |
---|
1092 | 1149 | container_of(notify, typeof(*nv_connector), hpd); |
---|
1093 | 1150 | struct drm_connector *connector = &nv_connector->base; |
---|
1094 | | - struct nouveau_drm *drm = nouveau_drm(connector->dev); |
---|
| 1151 | + struct drm_device *dev = connector->dev; |
---|
| 1152 | + struct nouveau_drm *drm = nouveau_drm(dev); |
---|
1095 | 1153 | const struct nvif_notify_conn_rep_v0 *rep = notify->data; |
---|
1096 | | - const char *name = connector->name; |
---|
1097 | | - struct nouveau_encoder *nv_encoder; |
---|
1098 | | - int ret; |
---|
1099 | | - |
---|
1100 | | - ret = pm_runtime_get(drm->dev->dev); |
---|
1101 | | - if (ret == 0) { |
---|
1102 | | - /* We can't block here if there's a pending PM request |
---|
1103 | | - * running, as we'll deadlock nouveau_display_fini() when it |
---|
1104 | | - * calls nvif_put() on our nvif_notify struct. So, simply |
---|
1105 | | - * defer the hotplug event until the device finishes resuming |
---|
1106 | | - */ |
---|
1107 | | - NV_DEBUG(drm, "Deferring HPD on %s until runtime resume\n", |
---|
1108 | | - name); |
---|
1109 | | - schedule_work(&drm->hpd_work); |
---|
1110 | | - |
---|
1111 | | - pm_runtime_put_noidle(drm->dev->dev); |
---|
1112 | | - return NVIF_NOTIFY_KEEP; |
---|
1113 | | - } else if (ret != 1 && ret != -EACCES) { |
---|
1114 | | - NV_WARN(drm, "HPD on %s dropped due to RPM failure: %d\n", |
---|
1115 | | - name, ret); |
---|
1116 | | - return NVIF_NOTIFY_DROP; |
---|
1117 | | - } |
---|
| 1154 | + bool plugged = (rep->mask != NVIF_NOTIFY_CONN_V0_UNPLUG); |
---|
1118 | 1155 | |
---|
1119 | 1156 | if (rep->mask & NVIF_NOTIFY_CONN_V0_IRQ) { |
---|
1120 | | - NV_DEBUG(drm, "service %s\n", name); |
---|
1121 | | - if ((nv_encoder = find_encoder(connector, DCB_OUTPUT_DP))) |
---|
1122 | | - nv50_mstm_service(nv_encoder->dp.mstm); |
---|
1123 | | - } else { |
---|
1124 | | - bool plugged = (rep->mask != NVIF_NOTIFY_CONN_V0_UNPLUG); |
---|
1125 | | - |
---|
1126 | | - NV_DEBUG(drm, "%splugged %s\n", plugged ? "" : "un", name); |
---|
1127 | | - if ((nv_encoder = find_encoder(connector, DCB_OUTPUT_DP))) { |
---|
1128 | | - if (!plugged) |
---|
1129 | | - nv50_mstm_remove(nv_encoder->dp.mstm); |
---|
1130 | | - } |
---|
1131 | | - |
---|
1132 | | - drm_helper_hpd_irq_event(connector->dev); |
---|
| 1157 | + nouveau_dp_irq(drm, nv_connector); |
---|
| 1158 | + return NVIF_NOTIFY_KEEP; |
---|
1133 | 1159 | } |
---|
1134 | 1160 | |
---|
1135 | | - pm_runtime_mark_last_busy(drm->dev->dev); |
---|
1136 | | - pm_runtime_put_autosuspend(drm->dev->dev); |
---|
| 1161 | + NV_DEBUG(drm, "%splugged %s\n", plugged ? "" : "un", connector->name); |
---|
| 1162 | + nouveau_connector_hpd(connector); |
---|
| 1163 | + |
---|
1137 | 1164 | return NVIF_NOTIFY_KEEP; |
---|
1138 | 1165 | } |
---|
1139 | 1166 | |
---|
.. | .. |
---|
1184 | 1211 | case DCB_CONNECTOR_LVDS_SPWG: return DRM_MODE_CONNECTOR_LVDS; |
---|
1185 | 1212 | case DCB_CONNECTOR_DMS59_DP0: |
---|
1186 | 1213 | case DCB_CONNECTOR_DMS59_DP1: |
---|
1187 | | - case DCB_CONNECTOR_DP : return DRM_MODE_CONNECTOR_DisplayPort; |
---|
| 1214 | + case DCB_CONNECTOR_DP : |
---|
| 1215 | + case DCB_CONNECTOR_mDP : |
---|
| 1216 | + case DCB_CONNECTOR_USB_C : return DRM_MODE_CONNECTOR_DisplayPort; |
---|
1188 | 1217 | case DCB_CONNECTOR_eDP : return DRM_MODE_CONNECTOR_eDP; |
---|
1189 | 1218 | case DCB_CONNECTOR_HDMI_0 : |
---|
1190 | 1219 | case DCB_CONNECTOR_HDMI_1 : |
---|
.. | .. |
---|
1198 | 1227 | } |
---|
1199 | 1228 | |
---|
1200 | 1229 | struct drm_connector * |
---|
1201 | | -nouveau_connector_create(struct drm_device *dev, int index) |
---|
| 1230 | +nouveau_connector_create(struct drm_device *dev, |
---|
| 1231 | + const struct dcb_output *dcbe) |
---|
1202 | 1232 | { |
---|
1203 | 1233 | const struct drm_connector_funcs *funcs = &nouveau_connector_funcs; |
---|
1204 | 1234 | struct nouveau_drm *drm = nouveau_drm(dev); |
---|
.. | .. |
---|
1206 | 1236 | struct nouveau_connector *nv_connector = NULL; |
---|
1207 | 1237 | struct drm_connector *connector; |
---|
1208 | 1238 | struct drm_connector_list_iter conn_iter; |
---|
| 1239 | + char aux_name[48] = {0}; |
---|
| 1240 | + int index = dcbe->connector; |
---|
1209 | 1241 | int type, ret = 0; |
---|
1210 | 1242 | bool dummy; |
---|
1211 | 1243 | |
---|
.. | .. |
---|
1306 | 1338 | break; |
---|
1307 | 1339 | case DRM_MODE_CONNECTOR_DisplayPort: |
---|
1308 | 1340 | case DRM_MODE_CONNECTOR_eDP: |
---|
1309 | | - nv_connector->aux.dev = dev->dev; |
---|
| 1341 | + nv_connector->aux.dev = connector->kdev; |
---|
1310 | 1342 | nv_connector->aux.transfer = nouveau_connector_aux_xfer; |
---|
| 1343 | + snprintf(aux_name, sizeof(aux_name), "sor-%04x-%04x", |
---|
| 1344 | + dcbe->hasht, dcbe->hashm); |
---|
| 1345 | + nv_connector->aux.name = kstrdup(aux_name, GFP_KERNEL); |
---|
1311 | 1346 | ret = drm_dp_aux_register(&nv_connector->aux); |
---|
1312 | 1347 | if (ret) { |
---|
1313 | 1348 | NV_ERROR(drm, "failed to register aux channel\n"); |
---|
1314 | 1349 | kfree(nv_connector); |
---|
1315 | 1350 | return ERR_PTR(ret); |
---|
1316 | 1351 | } |
---|
1317 | | - |
---|
1318 | 1352 | funcs = &nouveau_connector_funcs; |
---|
1319 | 1353 | break; |
---|
1320 | 1354 | default: |
---|
.. | .. |
---|
1368 | 1402 | break; |
---|
1369 | 1403 | } |
---|
1370 | 1404 | |
---|
1371 | | - ret = nvif_notify_init(&disp->disp.object, nouveau_connector_hotplug, |
---|
| 1405 | + switch (type) { |
---|
| 1406 | + case DRM_MODE_CONNECTOR_DisplayPort: |
---|
| 1407 | + case DRM_MODE_CONNECTOR_eDP: |
---|
| 1408 | + drm_dp_cec_register_connector(&nv_connector->aux, connector); |
---|
| 1409 | + break; |
---|
| 1410 | + } |
---|
| 1411 | + |
---|
| 1412 | + ret = nvif_notify_ctor(&disp->disp.object, "kmsHotplug", |
---|
| 1413 | + nouveau_connector_hotplug, |
---|
1372 | 1414 | true, NV04_DISP_NTFY_CONN, |
---|
1373 | 1415 | &(struct nvif_notify_conn_req_v0) { |
---|
1374 | 1416 | .mask = NVIF_NOTIFY_CONN_V0_ANY, |
---|