diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/nouveau/nvd0_display.c | 73 |
1 files changed, 48 insertions, 25 deletions
diff --git a/drivers/gpu/drm/nouveau/nvd0_display.c b/drivers/gpu/drm/nouveau/nvd0_display.c index 8abc3edb4612..037602b72d6c 100644 --- a/drivers/gpu/drm/nouveau/nvd0_display.c +++ b/drivers/gpu/drm/nouveau/nvd0_display.c | |||
@@ -1264,30 +1264,46 @@ static void | |||
1264 | nvd0_dac_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | 1264 | nvd0_dac_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, |
1265 | struct drm_display_mode *adjusted_mode) | 1265 | struct drm_display_mode *adjusted_mode) |
1266 | { | 1266 | { |
1267 | struct nvd0_mast *mast = nvd0_mast(encoder->dev); | ||
1267 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 1268 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
1268 | struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); | 1269 | struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); |
1269 | u32 syncs, magic, *push; | 1270 | u32 *push; |
1270 | |||
1271 | syncs = 0x00000001; | ||
1272 | if (mode->flags & DRM_MODE_FLAG_NHSYNC) | ||
1273 | syncs |= 0x00000008; | ||
1274 | if (mode->flags & DRM_MODE_FLAG_NVSYNC) | ||
1275 | syncs |= 0x00000010; | ||
1276 | |||
1277 | magic = 0x31ec6000 | (nv_crtc->index << 25); | ||
1278 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) | ||
1279 | magic |= 0x00000001; | ||
1280 | 1271 | ||
1281 | nvd0_dac_dpms(encoder, DRM_MODE_DPMS_ON); | 1272 | nvd0_dac_dpms(encoder, DRM_MODE_DPMS_ON); |
1282 | 1273 | ||
1283 | push = evo_wait(nvd0_mast(encoder->dev), 8); | 1274 | push = evo_wait(mast, 8); |
1284 | if (push) { | 1275 | if (push) { |
1285 | evo_mthd(push, 0x0404 + (nv_crtc->index * 0x300), 2); | 1276 | if (nvd0_vers(mast) < NVD0_DISP_MAST_CLASS) { |
1286 | evo_data(push, syncs); | 1277 | u32 syncs = 0x00000000; |
1287 | evo_data(push, magic); | 1278 | |
1288 | evo_mthd(push, 0x0180 + (nv_encoder->or * 0x020), 1); | 1279 | if (mode->flags & DRM_MODE_FLAG_NHSYNC) |
1289 | evo_data(push, 1 << nv_crtc->index); | 1280 | syncs |= 0x00000001; |
1290 | evo_kick(push, nvd0_mast(encoder->dev)); | 1281 | if (mode->flags & DRM_MODE_FLAG_NVSYNC) |
1282 | syncs |= 0x00000002; | ||
1283 | |||
1284 | evo_mthd(push, 0x0400 + (nv_encoder->or * 0x080), 2); | ||
1285 | evo_data(push, 1 << nv_crtc->index); | ||
1286 | evo_data(push, syncs); | ||
1287 | } else { | ||
1288 | u32 magic = 0x31ec6000 | (nv_crtc->index << 25); | ||
1289 | u32 syncs = 0x00000001; | ||
1290 | |||
1291 | if (mode->flags & DRM_MODE_FLAG_NHSYNC) | ||
1292 | syncs |= 0x00000008; | ||
1293 | if (mode->flags & DRM_MODE_FLAG_NVSYNC) | ||
1294 | syncs |= 0x00000010; | ||
1295 | |||
1296 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) | ||
1297 | magic |= 0x00000001; | ||
1298 | |||
1299 | evo_mthd(push, 0x0404 + (nv_crtc->index * 0x300), 2); | ||
1300 | evo_data(push, syncs); | ||
1301 | evo_data(push, magic); | ||
1302 | evo_mthd(push, 0x0180 + (nv_encoder->or * 0x020), 1); | ||
1303 | evo_data(push, 1 << nv_crtc->index); | ||
1304 | } | ||
1305 | |||
1306 | evo_kick(push, mast); | ||
1291 | } | 1307 | } |
1292 | 1308 | ||
1293 | nv_encoder->crtc = encoder->crtc; | 1309 | nv_encoder->crtc = encoder->crtc; |
@@ -1297,23 +1313,30 @@ static void | |||
1297 | nvd0_dac_disconnect(struct drm_encoder *encoder) | 1313 | nvd0_dac_disconnect(struct drm_encoder *encoder) |
1298 | { | 1314 | { |
1299 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 1315 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
1300 | struct drm_device *dev = encoder->dev; | 1316 | struct nvd0_mast *mast = nvd0_mast(encoder->dev); |
1317 | const int or = nv_encoder->or; | ||
1301 | u32 *push; | 1318 | u32 *push; |
1302 | 1319 | ||
1303 | if (nv_encoder->crtc) { | 1320 | if (nv_encoder->crtc) { |
1304 | nvd0_crtc_prepare(nv_encoder->crtc); | 1321 | nvd0_crtc_prepare(nv_encoder->crtc); |
1305 | 1322 | ||
1306 | push = evo_wait(nvd0_mast(dev), 4); | 1323 | push = evo_wait(mast, 4); |
1307 | if (push) { | 1324 | if (push) { |
1308 | evo_mthd(push, 0x0180 + (nv_encoder->or * 0x20), 1); | 1325 | if (nvd0_vers(mast) < NVD0_DISP_MAST_CLASS) { |
1309 | evo_data(push, 0x00000000); | 1326 | evo_mthd(push, 0x0400 + (or * 0x080), 1); |
1327 | evo_data(push, 0x00000000); | ||
1328 | } else { | ||
1329 | evo_mthd(push, 0x0180 + (or * 0x020), 1); | ||
1330 | evo_data(push, 0x00000000); | ||
1331 | } | ||
1332 | |||
1310 | evo_mthd(push, 0x0080, 1); | 1333 | evo_mthd(push, 0x0080, 1); |
1311 | evo_data(push, 0x00000000); | 1334 | evo_data(push, 0x00000000); |
1312 | evo_kick(push, nvd0_mast(dev)); | 1335 | evo_kick(push, mast); |
1313 | } | 1336 | } |
1314 | |||
1315 | nv_encoder->crtc = NULL; | ||
1316 | } | 1337 | } |
1338 | |||
1339 | nv_encoder->crtc = NULL; | ||
1317 | } | 1340 | } |
1318 | 1341 | ||
1319 | static enum drm_connector_status | 1342 | static enum drm_connector_status |