.. | .. |
---|
396 | 396 | return 0; |
---|
397 | 397 | } |
---|
398 | 398 | |
---|
| 399 | +static void |
---|
| 400 | +nv50_outp_atomic_fix_depth(struct drm_encoder *encoder, struct drm_crtc_state *crtc_state) |
---|
| 401 | +{ |
---|
| 402 | + struct nv50_head_atom *asyh = nv50_head_atom(crtc_state); |
---|
| 403 | + struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
---|
| 404 | + struct drm_display_mode *mode = &asyh->state.adjusted_mode; |
---|
| 405 | + unsigned int max_rate, mode_rate; |
---|
| 406 | + |
---|
| 407 | + switch (nv_encoder->dcb->type) { |
---|
| 408 | + case DCB_OUTPUT_DP: |
---|
| 409 | + max_rate = nv_encoder->dp.link_nr * nv_encoder->dp.link_bw; |
---|
| 410 | + |
---|
| 411 | + /* we don't support more than 10 anyway */ |
---|
| 412 | + asyh->or.bpc = min_t(u8, asyh->or.bpc, 10); |
---|
| 413 | + |
---|
| 414 | + /* reduce the bpc until it works out */ |
---|
| 415 | + while (asyh->or.bpc > 6) { |
---|
| 416 | + mode_rate = DIV_ROUND_UP(mode->clock * asyh->or.bpc * 3, 8); |
---|
| 417 | + if (mode_rate <= max_rate) |
---|
| 418 | + break; |
---|
| 419 | + |
---|
| 420 | + asyh->or.bpc -= 2; |
---|
| 421 | + } |
---|
| 422 | + break; |
---|
| 423 | + default: |
---|
| 424 | + break; |
---|
| 425 | + } |
---|
| 426 | +} |
---|
| 427 | + |
---|
399 | 428 | static int |
---|
400 | 429 | nv50_outp_atomic_check(struct drm_encoder *encoder, |
---|
401 | 430 | struct drm_crtc_state *crtc_state, |
---|
.. | .. |
---|
413 | 442 | |
---|
414 | 443 | if (crtc_state->mode_changed || crtc_state->connectors_changed) |
---|
415 | 444 | asyh->or.bpc = connector->display_info.bpc; |
---|
| 445 | + |
---|
| 446 | + /* We might have to reduce the bpc */ |
---|
| 447 | + nv50_outp_atomic_fix_depth(encoder, crtc_state); |
---|
416 | 448 | |
---|
417 | 449 | return 0; |
---|
418 | 450 | } |
---|
.. | .. |
---|
2555 | 2587 | { |
---|
2556 | 2588 | struct nouveau_drm *drm = nouveau_drm(dev); |
---|
2557 | 2589 | struct drm_encoder *encoder; |
---|
2558 | | - struct drm_plane *plane; |
---|
2559 | | - |
---|
2560 | | - drm_for_each_plane(plane, dev) { |
---|
2561 | | - struct nv50_wndw *wndw = nv50_wndw(plane); |
---|
2562 | | - if (plane->funcs != &nv50_wndw) |
---|
2563 | | - continue; |
---|
2564 | | - nv50_wndw_fini(wndw); |
---|
2565 | | - } |
---|
2566 | 2590 | |
---|
2567 | 2591 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
---|
2568 | 2592 | if (encoder->encoder_type != DRM_MODE_ENCODER_DPMST) |
---|
.. | .. |
---|
2578 | 2602 | { |
---|
2579 | 2603 | struct nv50_core *core = nv50_disp(dev)->core; |
---|
2580 | 2604 | struct drm_encoder *encoder; |
---|
2581 | | - struct drm_plane *plane; |
---|
2582 | 2605 | |
---|
2583 | 2606 | if (resume || runtime) |
---|
2584 | 2607 | core->func->init(core); |
---|
.. | .. |
---|
2589 | 2612 | nouveau_encoder(encoder); |
---|
2590 | 2613 | nv50_mstm_init(nv_encoder, runtime); |
---|
2591 | 2614 | } |
---|
2592 | | - } |
---|
2593 | | - |
---|
2594 | | - drm_for_each_plane(plane, dev) { |
---|
2595 | | - struct nv50_wndw *wndw = nv50_wndw(plane); |
---|
2596 | | - if (plane->funcs != &nv50_wndw) |
---|
2597 | | - continue; |
---|
2598 | | - nv50_wndw_init(wndw); |
---|
2599 | 2615 | } |
---|
2600 | 2616 | |
---|
2601 | 2617 | return 0; |
---|