diff options
| author | Roy Spliet <rspliet@eclipso.eu> | 2014-10-30 17:57:45 -0400 |
|---|---|---|
| committer | Ben Skeggs <bskeggs@redhat.com> | 2014-11-13 00:54:55 -0500 |
| commit | eae7382bc5547391e72f8cde83f5e2be9c359d5b (patch) | |
| tree | b2b1a60b70afc602aebdfe0fc0194bb9d28f7bdf | |
| parent | b2c19870063f81209fbdb471a56ab6c4a9d9e172 (diff) | |
drm/nouveau/nv50/disp: Fix modeset on G94
Commit 1dce6264045cd23e9c07574ed0bb31c7dce9354f introduced a regression
spotted on several G94 (FDObz #85160). This device seems to expect the
vblank period to be set after setting scale instead of before.
V2: shove this in a separate function
This is a candidate bug-fix for 3.18
Signed-off-by: Roy Spliet <rspliet@eclipso.eu>
Tested-by: Zlatko Calusic <zcalusic@bitsync.net>
Tested-by: Michael Riesch <michael@riesch.at>
Tested-by: "poma" <pomidorabelisima@gmail.com>
Tested-by: Adam Williamson <adamw@happyassassin.net>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
| -rw-r--r-- | drivers/gpu/drm/nouveau/nv50_display.c | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index ae873d1a8d46..eb8b36714fa1 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c | |||
| @@ -791,6 +791,22 @@ nv50_crtc_set_scale(struct nouveau_crtc *nv_crtc, bool update) | |||
| 791 | } | 791 | } |
| 792 | 792 | ||
| 793 | static int | 793 | static int |
| 794 | nv50_crtc_set_raster_vblank_dmi(struct nouveau_crtc *nv_crtc, u32 usec) | ||
| 795 | { | ||
| 796 | struct nv50_mast *mast = nv50_mast(nv_crtc->base.dev); | ||
| 797 | u32 *push; | ||
| 798 | |||
| 799 | push = evo_wait(mast, 8); | ||
| 800 | if (!push) | ||
| 801 | return -ENOMEM; | ||
| 802 | |||
| 803 | evo_mthd(push, 0x0828 + (nv_crtc->index * 0x400), 1); | ||
| 804 | evo_data(push, usec); | ||
| 805 | evo_kick(push, mast); | ||
| 806 | return 0; | ||
| 807 | } | ||
| 808 | |||
| 809 | static int | ||
| 794 | nv50_crtc_set_color_vibrance(struct nouveau_crtc *nv_crtc, bool update) | 810 | nv50_crtc_set_color_vibrance(struct nouveau_crtc *nv_crtc, bool update) |
| 795 | { | 811 | { |
| 796 | struct nv50_mast *mast = nv50_mast(nv_crtc->base.dev); | 812 | struct nv50_mast *mast = nv50_mast(nv_crtc->base.dev); |
| @@ -1104,14 +1120,14 @@ nv50_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *umode, | |||
| 1104 | evo_mthd(push, 0x0804 + (nv_crtc->index * 0x400), 2); | 1120 | evo_mthd(push, 0x0804 + (nv_crtc->index * 0x400), 2); |
| 1105 | evo_data(push, 0x00800000 | mode->clock); | 1121 | evo_data(push, 0x00800000 | mode->clock); |
| 1106 | evo_data(push, (ilace == 2) ? 2 : 0); | 1122 | evo_data(push, (ilace == 2) ? 2 : 0); |
| 1107 | evo_mthd(push, 0x0810 + (nv_crtc->index * 0x400), 8); | 1123 | evo_mthd(push, 0x0810 + (nv_crtc->index * 0x400), 6); |
| 1108 | evo_data(push, 0x00000000); | 1124 | evo_data(push, 0x00000000); |
| 1109 | evo_data(push, (vactive << 16) | hactive); | 1125 | evo_data(push, (vactive << 16) | hactive); |
| 1110 | evo_data(push, ( vsynce << 16) | hsynce); | 1126 | evo_data(push, ( vsynce << 16) | hsynce); |
| 1111 | evo_data(push, (vblanke << 16) | hblanke); | 1127 | evo_data(push, (vblanke << 16) | hblanke); |
| 1112 | evo_data(push, (vblanks << 16) | hblanks); | 1128 | evo_data(push, (vblanks << 16) | hblanks); |
| 1113 | evo_data(push, (vblan2e << 16) | vblan2s); | 1129 | evo_data(push, (vblan2e << 16) | vblan2s); |
| 1114 | evo_data(push, vblankus); | 1130 | evo_mthd(push, 0x082c + (nv_crtc->index * 0x400), 1); |
| 1115 | evo_data(push, 0x00000000); | 1131 | evo_data(push, 0x00000000); |
| 1116 | evo_mthd(push, 0x0900 + (nv_crtc->index * 0x400), 2); | 1132 | evo_mthd(push, 0x0900 + (nv_crtc->index * 0x400), 2); |
| 1117 | evo_data(push, 0x00000311); | 1133 | evo_data(push, 0x00000311); |
| @@ -1141,6 +1157,11 @@ nv50_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *umode, | |||
| 1141 | nv_connector = nouveau_crtc_connector_get(nv_crtc); | 1157 | nv_connector = nouveau_crtc_connector_get(nv_crtc); |
| 1142 | nv50_crtc_set_dither(nv_crtc, false); | 1158 | nv50_crtc_set_dither(nv_crtc, false); |
| 1143 | nv50_crtc_set_scale(nv_crtc, false); | 1159 | nv50_crtc_set_scale(nv_crtc, false); |
| 1160 | |||
| 1161 | /* G94 only accepts this after setting scale */ | ||
| 1162 | if (nv50_vers(mast) < GF110_DISP_CORE_CHANNEL_DMA) | ||
| 1163 | nv50_crtc_set_raster_vblank_dmi(nv_crtc, vblankus); | ||
| 1164 | |||
| 1144 | nv50_crtc_set_color_vibrance(nv_crtc, false); | 1165 | nv50_crtc_set_color_vibrance(nv_crtc, false); |
| 1145 | nv50_crtc_set_image(nv_crtc, crtc->primary->fb, x, y, false); | 1166 | nv50_crtc_set_image(nv_crtc, crtc->primary->fb, x, y, false); |
| 1146 | return 0; | 1167 | return 0; |
