| .. | .. |
|---|
| 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; |
|---|