|
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