diff options
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_dp.c | 55 |
1 files changed, 46 insertions, 9 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c index c51c68b045a8..1a613ab4e08f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dp.c +++ b/drivers/gpu/drm/nouveau/nouveau_dp.c | |||
@@ -554,6 +554,49 @@ dp_link_train_eq(struct drm_device *dev, struct dp_state *dp) | |||
554 | return eq_done ? 0 : -1; | 554 | return eq_done ? 0 : -1; |
555 | } | 555 | } |
556 | 556 | ||
557 | static void | ||
558 | dp_set_downspread(struct drm_device *dev, struct dp_state *dp, bool enable) | ||
559 | { | ||
560 | u16 script = 0x0000; | ||
561 | u8 *entry, *table = nouveau_dp_bios_data(dev, dp->dcb, &entry); | ||
562 | if (table) { | ||
563 | if (table[0] >= 0x20 && table[0] <= 0x30) { | ||
564 | if (enable) | ||
565 | script = ROM16(entry[12]); | ||
566 | else | ||
567 | script = ROM16(entry[14]); | ||
568 | } | ||
569 | } | ||
570 | |||
571 | nouveau_bios_run_init_table(dev, script, dp->dcb, dp->crtc); | ||
572 | } | ||
573 | |||
574 | static void | ||
575 | dp_link_train_init(struct drm_device *dev, struct dp_state *dp) | ||
576 | { | ||
577 | u16 script = 0x0000; | ||
578 | u8 *entry, *table = nouveau_dp_bios_data(dev, dp->dcb, &entry); | ||
579 | if (table) { | ||
580 | if (table[0] >= 0x20 && table[0] <= 0x30) | ||
581 | script = ROM16(entry[6]); | ||
582 | } | ||
583 | |||
584 | nouveau_bios_run_init_table(dev, script, dp->dcb, dp->crtc); | ||
585 | } | ||
586 | |||
587 | static void | ||
588 | dp_link_train_fini(struct drm_device *dev, struct dp_state *dp) | ||
589 | { | ||
590 | u16 script = 0x0000; | ||
591 | u8 *entry, *table = nouveau_dp_bios_data(dev, dp->dcb, &entry); | ||
592 | if (table) { | ||
593 | if (table[0] >= 0x20 && table[0] <= 0x30) | ||
594 | script = ROM16(entry[8]); | ||
595 | } | ||
596 | |||
597 | nouveau_bios_run_init_table(dev, script, dp->dcb, dp->crtc); | ||
598 | } | ||
599 | |||
557 | bool | 600 | bool |
558 | nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate) | 601 | nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate) |
559 | { | 602 | { |
@@ -589,16 +632,10 @@ nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate) | |||
589 | nouveau_gpio_irq(dev, 0, nv_connector->hpd, 0xff, false); | 632 | nouveau_gpio_irq(dev, 0, nv_connector->hpd, 0xff, false); |
590 | 633 | ||
591 | /* enable down-spreading, if possible */ | 634 | /* enable down-spreading, if possible */ |
592 | if (dp.table[1] >= 16) { | 635 | dp_set_downspread(dev, &dp, nv_encoder->dp.dpcd[3] & 1); |
593 | u16 script = ROM16(dp.entry[14]); | ||
594 | if (nv_encoder->dp.dpcd[3] & 1) | ||
595 | script = ROM16(dp.entry[12]); | ||
596 | |||
597 | nouveau_bios_run_init_table(dev, script, dp.dcb, dp.crtc); | ||
598 | } | ||
599 | 636 | ||
600 | /* execute pre-train script from vbios */ | 637 | /* execute pre-train script from vbios */ |
601 | nouveau_bios_run_init_table(dev, ROM16(dp.entry[6]), dp.dcb, dp.crtc); | 638 | dp_link_train_init(dev, &dp); |
602 | 639 | ||
603 | /* start off at highest link rate supported by encoder and display */ | 640 | /* start off at highest link rate supported by encoder and display */ |
604 | while (*link_bw > nv_encoder->dp.link_bw) | 641 | while (*link_bw > nv_encoder->dp.link_bw) |
@@ -632,7 +669,7 @@ nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate) | |||
632 | dp_set_training_pattern(dev, &dp, DP_TRAINING_PATTERN_DISABLE); | 669 | dp_set_training_pattern(dev, &dp, DP_TRAINING_PATTERN_DISABLE); |
633 | 670 | ||
634 | /* execute post-train script from vbios */ | 671 | /* execute post-train script from vbios */ |
635 | nouveau_bios_run_init_table(dev, ROM16(dp.entry[8]), dp.dcb, dp.crtc); | 672 | dp_link_train_fini(dev, &dp); |
636 | 673 | ||
637 | /* re-enable hotplug detect */ | 674 | /* re-enable hotplug detect */ |
638 | nouveau_gpio_irq(dev, 0, nv_connector->hpd, 0xff, true); | 675 | nouveau_gpio_irq(dev, 0, nv_connector->hpd, 0xff, true); |