summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
diff options
context:
space:
mode:
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.c188
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 4cd2d9e31..1924a2b28 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);