diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_dp.c')
-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 c51c68b045a..1a613ab4e08 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) return eq_done ? 0 : -1; } +static void +dp_set_downspread(struct drm_device *dev, struct dp_state *dp, bool enable) +{ + u16 script = 0x0000; + u8 *entry, *table = nouveau_dp_bios_data(dev, dp->dcb, &entry); + if (table) { + if (table[0] >= 0x20 && table[0] <= 0x30) { + if (enable) + script = ROM16(entry[12]); + else + script = ROM16(entry[14]); + } + } + + nouveau_bios_run_init_table(dev, script, dp->dcb, dp->crtc); +} + +static void +dp_link_train_init(struct drm_device *dev, struct dp_state *dp) +{ + u16 script = 0x0000; + u8 *entry, *table = nouveau_dp_bios_data(dev, dp->dcb, &entry); + if (table) { + if (table[0] >= 0x20 && table[0] <= 0x30) + script = ROM16(entry[6]); + } + + nouveau_bios_run_init_table(dev, script, dp->dcb, dp->crtc); +} + +static void +dp_link_train_fini(struct drm_device *dev, struct dp_state *dp) +{ + u16 script = 0x0000; + u8 *entry, *table = nouveau_dp_bios_data(dev, dp->dcb, &entry); + if (table) { + if (table[0] >= 0x20 && table[0] <= 0x30) + script = ROM16(entry[8]); + } + + nouveau_bios_run_init_table(dev, script, dp->dcb, dp->crtc); +} + bool nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate) { @@ -589,16 +632,10 @@ nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate) nouveau_gpio_irq(dev, 0, nv_connector->hpd, 0xff, false); /* enable down-spreading, if possible */ - if (dp.table[1] >= 16) { - u16 script = ROM16(dp.entry[14]); - if (nv_encoder->dp.dpcd[3] & 1) - script = ROM16(dp.entry[12]); - - nouveau_bios_run_init_table(dev, script, dp.dcb, dp.crtc); - } + dp_set_downspread(dev, &dp, nv_encoder->dp.dpcd[3] & 1); /* execute pre-train script from vbios */ - nouveau_bios_run_init_table(dev, ROM16(dp.entry[6]), dp.dcb, dp.crtc); + dp_link_train_init(dev, &dp); /* start off at highest link rate supported by encoder and display */ while (*link_bw > nv_encoder->dp.link_bw) @@ -632,7 +669,7 @@ nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate) dp_set_training_pattern(dev, &dp, DP_TRAINING_PATTERN_DISABLE); /* execute post-train script from vbios */ - nouveau_bios_run_init_table(dev, ROM16(dp.entry[8]), dp.dcb, dp.crtc); + dp_link_train_fini(dev, &dp); /* re-enable hotplug detect */ nouveau_gpio_irq(dev, 0, nv_connector->hpd, 0xff, true); |