diff options
Diffstat (limited to 'drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c')
-rw-r--r-- | drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 188 |
1 files changed, 27 insertions, 161 deletions
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c index 4cd2d9e3131a..1924a2b28e53 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c @@ -265,149 +265,6 @@ static void dpu_encoder_phys_wb_setup_ctl(struct dpu_encoder_phys *phys_enc) } /** - * dpu_encoder_helper_phys_setup_cdm - setup chroma down sampling block - * This API does not handle DPU_CHROMA_H1V2. - * @phys_enc:Pointer to physical encoder - */ -static void dpu_encoder_helper_phys_setup_cdm(struct dpu_encoder_phys *phys_enc) -{ - struct dpu_hw_cdm *hw_cdm; - struct dpu_hw_cdm_cfg *cdm_cfg; - struct dpu_hw_pingpong *hw_pp; - struct dpu_encoder_phys_wb *wb_enc; - const struct msm_format *format; - const struct dpu_format *dpu_fmt; - struct drm_writeback_job *wb_job; - int ret; - - if (!phys_enc) - return; - - wb_enc = to_dpu_encoder_phys_wb(phys_enc); - cdm_cfg = &wb_enc->cdm_cfg; - hw_pp = phys_enc->hw_pp; - hw_cdm = phys_enc->hw_cdm; - wb_job = wb_enc->wb_job; - - format = msm_framebuffer_format(wb_enc->wb_job->fb); - dpu_fmt = dpu_get_dpu_format_ext(format->pixel_format, wb_job->fb->modifier); - - if (!hw_cdm) - return; - - if (!DPU_FORMAT_IS_YUV(dpu_fmt)) { - DPU_DEBUG("[enc:%d] cdm_disable fmt:%x\n", DRMID(phys_enc->parent), - dpu_fmt->base.pixel_format); - if (hw_cdm->ops.bind_pingpong_blk) - hw_cdm->ops.bind_pingpong_blk(hw_cdm, PINGPONG_NONE); - - return; - } - - memset(cdm_cfg, 0, sizeof(struct dpu_hw_cdm_cfg)); - - cdm_cfg->output_width = wb_job->fb->width; - cdm_cfg->output_height = wb_job->fb->height; - cdm_cfg->output_fmt = dpu_fmt; - cdm_cfg->output_type = CDM_CDWN_OUTPUT_WB; - cdm_cfg->output_bit_depth = DPU_FORMAT_IS_DX(dpu_fmt) ? - CDM_CDWN_OUTPUT_10BIT : CDM_CDWN_OUTPUT_8BIT; - cdm_cfg->csc_cfg = &dpu_csc10_rgb2yuv_601l; - - /* enable 10 bit logic */ - switch (cdm_cfg->output_fmt->chroma_sample) { - case DPU_CHROMA_RGB: - cdm_cfg->h_cdwn_type = CDM_CDWN_DISABLE; - cdm_cfg->v_cdwn_type = CDM_CDWN_DISABLE; - break; - case DPU_CHROMA_H2V1: - cdm_cfg->h_cdwn_type = CDM_CDWN_COSITE; - cdm_cfg->v_cdwn_type = CDM_CDWN_DISABLE; - break; - case DPU_CHROMA_420: - cdm_cfg->h_cdwn_type = CDM_CDWN_COSITE; - cdm_cfg->v_cdwn_type = CDM_CDWN_OFFSITE; - break; - case DPU_CHROMA_H1V2: - default: - DPU_ERROR("[enc:%d] unsupported chroma sampling type\n", - DRMID(phys_enc->parent)); - cdm_cfg->h_cdwn_type = CDM_CDWN_DISABLE; - cdm_cfg->v_cdwn_type = CDM_CDWN_DISABLE; - break; - } - - DPU_DEBUG("[enc:%d] cdm_enable:%d,%d,%X,%d,%d,%d,%d]\n", - DRMID(phys_enc->parent), cdm_cfg->output_width, - cdm_cfg->output_height, cdm_cfg->output_fmt->base.pixel_format, - cdm_cfg->output_type, cdm_cfg->output_bit_depth, - cdm_cfg->h_cdwn_type, cdm_cfg->v_cdwn_type); - - if (hw_cdm->ops.enable) { - cdm_cfg->pp_id = hw_pp->idx; - ret = hw_cdm->ops.enable(hw_cdm, cdm_cfg); - if (ret < 0) { - DPU_ERROR("[enc:%d] failed to enable CDM; ret:%d\n", - DRMID(phys_enc->parent), ret); - return; - } - } -} - -/** - * dpu_encoder_phys_wb_atomic_check - verify and fixup given atomic states - * @phys_enc: Pointer to physical encoder - * @crtc_state: Pointer to CRTC atomic state - * @conn_state: Pointer to connector atomic state - */ -static int dpu_encoder_phys_wb_atomic_check( - struct dpu_encoder_phys *phys_enc, - struct drm_crtc_state *crtc_state, - struct drm_connector_state *conn_state) -{ - struct drm_framebuffer *fb; - const struct drm_display_mode *mode = &crtc_state->mode; - - DPU_DEBUG("[atomic_check:%d, \"%s\",%d,%d]\n", - phys_enc->hw_wb->idx, mode->name, mode->hdisplay, mode->vdisplay); - - if (!conn_state || !conn_state->connector) { - DPU_ERROR("invalid connector state\n"); - return -EINVAL; - } else if (conn_state->connector->status != - connector_status_connected) { - DPU_ERROR("connector not connected %d\n", - conn_state->connector->status); - return -EINVAL; - } - - if (!conn_state->writeback_job || !conn_state->writeback_job->fb) - return 0; - - fb = conn_state->writeback_job->fb; - - DPU_DEBUG("[fb_id:%u][fb:%u,%u]\n", fb->base.id, - fb->width, fb->height); - - if (fb->width != mode->hdisplay) { - DPU_ERROR("invalid fb w=%d, mode w=%d\n", fb->width, - mode->hdisplay); - return -EINVAL; - } else if (fb->height != mode->vdisplay) { - DPU_ERROR("invalid fb h=%d, mode h=%d\n", fb->height, - mode->vdisplay); - return -EINVAL; - } else if (fb->width > phys_enc->hw_wb->caps->maxlinewidth) { - DPU_ERROR("invalid fb w=%d, maxlinewidth=%u\n", - fb->width, phys_enc->hw_wb->caps->maxlinewidth); - return -EINVAL; - } - - return drm_atomic_helper_check_wb_connector_state(conn_state->connector, conn_state->state); -} - - -/** * _dpu_encoder_phys_wb_update_flush - flush hardware update * @phys_enc: Pointer to physical encoder */ @@ -462,6 +319,14 @@ static void dpu_encoder_phys_wb_setup( struct dpu_hw_wb *hw_wb = phys_enc->hw_wb; struct drm_display_mode mode = phys_enc->cached_mode; struct drm_framebuffer *fb = NULL; + struct dpu_encoder_phys_wb *wb_enc = to_dpu_encoder_phys_wb(phys_enc); + struct drm_writeback_job *wb_job; + const struct msm_format *format; + const struct dpu_format *dpu_fmt; + + wb_job = wb_enc->wb_job; + format = msm_framebuffer_format(wb_enc->wb_job->fb); + dpu_fmt = dpu_get_dpu_format_ext(format->pixel_format, wb_job->fb->modifier); DPU_DEBUG("[mode_set:%d, \"%s\",%d,%d]\n", hw_wb->idx - WB_0, mode.name, @@ -475,7 +340,7 @@ static void dpu_encoder_phys_wb_setup( dpu_encoder_phys_wb_setup_fb(phys_enc, fb); - dpu_encoder_helper_phys_setup_cdm(phys_enc); + dpu_encoder_helper_phys_setup_cdm(phys_enc, dpu_fmt, CDM_CDWN_OUTPUT_WB); dpu_encoder_phys_wb_setup_ctl(phys_enc); } @@ -511,31 +376,32 @@ static void dpu_encoder_phys_wb_done_irq(void *arg) } /** - * dpu_encoder_phys_wb_irq_ctrl - irq control of WB + * dpu_encoder_phys_wb_irq_enable - irq control of WB * @phys: Pointer to physical encoder - * @enable: indicates enable or disable interrupts */ -static void dpu_encoder_phys_wb_irq_ctrl( - struct dpu_encoder_phys *phys, bool enable) +static void dpu_encoder_phys_wb_irq_enable(struct dpu_encoder_phys *phys) { struct dpu_encoder_phys_wb *wb_enc = to_dpu_encoder_phys_wb(phys); - if (enable && atomic_inc_return(&wb_enc->wbirq_refcount) == 1) + if (atomic_inc_return(&wb_enc->wbirq_refcount) == 1) dpu_core_irq_register_callback(phys->dpu_kms, - phys->irq[INTR_IDX_WB_DONE], dpu_encoder_phys_wb_done_irq, phys); - else if (!enable && - atomic_dec_return(&wb_enc->wbirq_refcount) == 0) - dpu_core_irq_unregister_callback(phys->dpu_kms, phys->irq[INTR_IDX_WB_DONE]); + phys->irq[INTR_IDX_WB_DONE], + dpu_encoder_phys_wb_done_irq, + phys); } -static void dpu_encoder_phys_wb_atomic_mode_set( - struct dpu_encoder_phys *phys_enc, - struct drm_crtc_state *crtc_state, - struct drm_connector_state *conn_state) +/** + * dpu_encoder_phys_wb_irq_disable - irq control of WB + * @phys: Pointer to physical encoder + */ +static void dpu_encoder_phys_wb_irq_disable(struct dpu_encoder_phys *phys) { - phys_enc->irq[INTR_IDX_WB_DONE] = phys_enc->hw_wb->caps->intr_wb_done; + struct dpu_encoder_phys_wb *wb_enc = to_dpu_encoder_phys_wb(phys); + + if (atomic_dec_return(&wb_enc->wbirq_refcount) == 0) + dpu_core_irq_unregister_callback(phys->dpu_kms, phys->irq[INTR_IDX_WB_DONE]); } static void _dpu_encoder_phys_wb_handle_wbdone_timeout( @@ -774,10 +640,8 @@ static bool dpu_encoder_phys_wb_is_valid_for_commit(struct dpu_encoder_phys *phy static void dpu_encoder_phys_wb_init_ops(struct dpu_encoder_phys_ops *ops) { ops->is_master = dpu_encoder_phys_wb_is_master; - ops->atomic_mode_set = dpu_encoder_phys_wb_atomic_mode_set; ops->enable = dpu_encoder_phys_wb_enable; ops->disable = dpu_encoder_phys_wb_disable; - ops->atomic_check = dpu_encoder_phys_wb_atomic_check; ops->wait_for_commit_done = dpu_encoder_phys_wb_wait_for_commit_done; ops->prepare_for_kickoff = dpu_encoder_phys_wb_prepare_for_kickoff; ops->handle_post_kickoff = dpu_encoder_phys_wb_handle_post_kickoff; @@ -785,7 +649,8 @@ static void dpu_encoder_phys_wb_init_ops(struct dpu_encoder_phys_ops *ops) ops->trigger_start = dpu_encoder_helper_trigger_start; ops->prepare_wb_job = dpu_encoder_phys_wb_prepare_wb_job; ops->cleanup_wb_job = dpu_encoder_phys_wb_cleanup_wb_job; - ops->irq_control = dpu_encoder_phys_wb_irq_ctrl; + ops->irq_enable = dpu_encoder_phys_wb_irq_enable; + ops->irq_disable = dpu_encoder_phys_wb_irq_disable; ops->is_valid_for_commit = dpu_encoder_phys_wb_is_valid_for_commit; } @@ -820,6 +685,7 @@ struct dpu_encoder_phys *dpu_encoder_phys_wb_init(struct drm_device *dev, dpu_encoder_phys_wb_init_ops(&phys_enc->ops); phys_enc->intf_mode = INTF_MODE_WB_LINE; + phys_enc->irq[INTR_IDX_WB_DONE] = phys_enc->hw_wb->caps->intr_wb_done; atomic_set(&wb_enc->wbirq_refcount, 0); |