|
16 | 16 | #include <drm/drm_crtc.h> |
17 | 17 | #include <drm/drm_file.h> |
18 | 18 | #include <drm/drm_probe_helper.h> |
| 19 | +#include <drm/drm_framebuffer.h> |
19 | 20 |
|
20 | 21 | #include "msm_drv.h" |
21 | 22 | #include "dpu_kms.h" |
|
26 | 27 | #include "dpu_hw_dspp.h" |
27 | 28 | #include "dpu_hw_dsc.h" |
28 | 29 | #include "dpu_hw_merge3d.h" |
| 30 | +#include "dpu_hw_cdm.h" |
29 | 31 | #include "dpu_formats.h" |
30 | 32 | #include "dpu_encoder_phys.h" |
31 | 33 | #include "dpu_crtc.h" |
@@ -584,6 +586,7 @@ static int dpu_encoder_virt_atomic_check( |
584 | 586 | struct drm_display_mode *adj_mode; |
585 | 587 | struct msm_display_topology topology; |
586 | 588 | struct dpu_global_state *global_state; |
| 589 | + struct drm_framebuffer *fb; |
587 | 590 | struct drm_dsc_config *dsc; |
588 | 591 | int i = 0; |
589 | 592 | int ret = 0; |
@@ -624,6 +627,22 @@ static int dpu_encoder_virt_atomic_check( |
624 | 627 |
|
625 | 628 | topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode, crtc_state, dsc); |
626 | 629 |
|
| 630 | + /* |
| 631 | + * Use CDM only for writeback at the moment as other interfaces cannot handle it. |
| 632 | + * if writeback itself cannot handle cdm for some reason it will fail in its atomic_check() |
| 633 | + * earlier. |
| 634 | + */ |
| 635 | + if (dpu_enc->disp_info.intf_type == INTF_WB && conn_state->writeback_job) { |
| 636 | + fb = conn_state->writeback_job->fb; |
| 637 | + |
| 638 | + if (fb && DPU_FORMAT_IS_YUV(to_dpu_format(msm_framebuffer_format(fb)))) |
| 639 | + topology.needs_cdm = true; |
| 640 | + if (topology.needs_cdm && !dpu_enc->cur_master->hw_cdm) |
| 641 | + crtc_state->mode_changed = true; |
| 642 | + else if (!topology.needs_cdm && dpu_enc->cur_master->hw_cdm) |
| 643 | + crtc_state->mode_changed = true; |
| 644 | + } |
| 645 | + |
627 | 646 | /* |
628 | 647 | * Release and Allocate resources on every modeset |
629 | 648 | * Dont allocate when active is false. |
@@ -1064,6 +1083,15 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc, |
1064 | 1083 |
|
1065 | 1084 | dpu_enc->dsc_mask = dsc_mask; |
1066 | 1085 |
|
| 1086 | + if (dpu_enc->disp_info.intf_type == INTF_WB && conn_state->writeback_job) { |
| 1087 | + struct dpu_hw_blk *hw_cdm = NULL; |
| 1088 | + |
| 1089 | + dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, |
| 1090 | + drm_enc->base.id, DPU_HW_BLK_CDM, |
| 1091 | + &hw_cdm, 1); |
| 1092 | + dpu_enc->cur_master->hw_cdm = hw_cdm ? to_dpu_hw_cdm(hw_cdm) : NULL; |
| 1093 | + } |
| 1094 | + |
1067 | 1095 | cstate = to_dpu_crtc_state(crtc_state); |
1068 | 1096 |
|
1069 | 1097 | for (i = 0; i < num_lm; i++) { |
@@ -2052,6 +2080,15 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc) |
2052 | 2080 | phys_enc->hw_pp->merge_3d->idx); |
2053 | 2081 | } |
2054 | 2082 |
|
| 2083 | + if (phys_enc->hw_cdm) { |
| 2084 | + if (phys_enc->hw_cdm->ops.bind_pingpong_blk && phys_enc->hw_pp) |
| 2085 | + phys_enc->hw_cdm->ops.bind_pingpong_blk(phys_enc->hw_cdm, |
| 2086 | + PINGPONG_NONE); |
| 2087 | + if (phys_enc->hw_ctl->ops.update_pending_flush_cdm) |
| 2088 | + phys_enc->hw_ctl->ops.update_pending_flush_cdm(phys_enc->hw_ctl, |
| 2089 | + phys_enc->hw_cdm->idx); |
| 2090 | + } |
| 2091 | + |
2055 | 2092 | if (dpu_enc->dsc) { |
2056 | 2093 | dpu_encoder_unprep_dsc(dpu_enc); |
2057 | 2094 | dpu_enc->dsc = NULL; |
|
0 commit comments