aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/nouveau')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_dp.c55
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
557static void
558dp_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
574static void
575dp_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
587static void
588dp_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
557bool 600bool
558nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate) 601nouveau_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);