Loading drivers/video/msm/mdss/mdss_mdp.c +1 −0 Original line number Diff line number Diff line Loading @@ -3391,6 +3391,7 @@ static int mdss_mdp_cdm_addr_setup(struct mdss_data_type *mdata, head[i].base = (mdata->mdss_io.base) + cdm_offsets[i]; atomic_set(&head[i].kref.refcount, 0); mutex_init(&head[i].lock); init_completion(&head[i].free_comp); pr_debug("%s: cdm off (%d) = %p\n", __func__, i, head[i].base); } Loading drivers/video/msm/mdss/mdss_mdp_cdm.c +25 −11 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ static u32 cdm_cdwn2_offsite_h_coeff[] = {0x000b0005, 0x01db01eb, 0x00e40046}; static u32 cdm_cdwn2_cosite_v_coeff[] = {0x00080004}; static u32 cdm_cdwn2_offsite_v_coeff[] = {0x00060002}; #define VSYNC_TIMEOUT_US 16000 /** * @mdss_mdp_cdm_alloc() - Allocates a cdm block by parsing the list of * available cdm blocks. Loading Loading @@ -66,6 +68,7 @@ static void mdss_mdp_cdm_free(struct kref *kref) if (!cdm) return; complete_all(&cdm->free_comp); pr_debug("free cdm_num = %d\n", cdm->num); } Loading @@ -84,6 +87,28 @@ struct mdss_mdp_cdm *mdss_mdp_cdm_init(struct mdss_mdp_ctl *ctl, u32 intf_type) cdm = mdss_mdp_cdm_alloc(mdata); /** * give hdmi interface priority to alloc the cdm block. It will wait * for one vsync cycle to allow wfd to finish its job and try to reserve * the block the again. */ if (!cdm && (intf_type == MDP_CDM_CDWN_OUTPUT_HDMI)) { /* always wait for first cdm block */ cdm = mdata->cdm_off; if (cdm) { reinit_completion(&cdm->free_comp); /* * no need to check the return status of completion * timeout. Next cdm_alloc call will try to reserve * the cdm block and returns failure if allocation * fails. */ wait_for_completion_timeout(&cdm->free_comp, usecs_to_jiffies(VSYNC_TIMEOUT_US)); cdm = mdss_mdp_cdm_alloc(mdata); } } if (!cdm) { pr_err("%s: Unable to allocate cdm\n", __func__); return ERR_PTR(-EBUSY); Loading Loading @@ -352,17 +377,6 @@ int mdss_mdp_cdm_destroy(struct mdss_mdp_cdm *cdm) return -EINVAL; } mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON); mutex_lock(&cdm->lock); /* Disable HDMI packer */ writel_relaxed(0x0, cdm->base + MDSS_MDP_REG_CDM_HDMI_PACK_OP_MODE); /* Put CDM in bypass */ writel_relaxed(0x0, cdm->mdata->mdp_base + MDSS_MDP_MDP_OUT_CTL_0); mutex_unlock(&cdm->lock); mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF); kref_put(&cdm->kref, mdss_mdp_cdm_free); return rc; Loading drivers/video/msm/mdss/mdss_mdp_cdm.h +2 −1 Original line number Diff line number Diff line /* * Copyright (c) 2014, The Linux Foundation. All rights reserved. * Copyright (c) 2014,2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -59,6 +59,7 @@ struct mdss_mdp_cdm { u32 out_intf; bool is_bypassed; struct mdp_cdm_cfg setup; struct completion free_comp; }; struct mdss_mdp_cdm *mdss_mdp_cdm_init(struct mdss_mdp_ctl *ctl, Loading drivers/video/msm/mdss/mdss_mdp_intf_video.c +26 −18 Original line number Diff line number Diff line Loading @@ -1695,19 +1695,10 @@ static inline bool mdss_mdp_video_need_pixel_drop(u32 vic) } static int mdss_mdp_video_cdm_setup(struct mdss_mdp_cdm *cdm, struct mdss_panel_info *pinfo) struct mdss_panel_info *pinfo, struct mdss_mdp_format_params *fmt) { struct mdss_mdp_format_params *fmt; struct mdp_cdm_cfg setup; fmt = mdss_mdp_get_format_params(pinfo->out_format); if (!fmt) { pr_err("%s: format %d not supported\n", __func__, pinfo->out_format); return -EINVAL; } setup.out_format = pinfo->out_format; if (fmt->is_yuv) setup.csc_type = MDSS_MDP_CSC_RGB2YUV_601FR; else Loading Loading @@ -1737,6 +1728,7 @@ static int mdss_mdp_video_cdm_setup(struct mdss_mdp_cdm *cdm, return -EINVAL; } setup.out_format = pinfo->out_format; setup.mdp_csc_bit_depth = MDP_CDM_CSC_8BIT; setup.output_width = pinfo->xres + pinfo->lcdc.xres_pad; setup.output_height = pinfo->yres + pinfo->lcdc.yres_pad; Loading Loading @@ -1770,6 +1762,7 @@ static int mdss_mdp_video_ctx_setup(struct mdss_mdp_ctl *ctl, { struct intf_timing_params *itp = &ctx->itp; u32 dst_bpp; struct mdss_mdp_format_params *fmt; struct mdss_data_type *mdata = ctl->mdata; struct dsc_desc *dsc = NULL; Loading Loading @@ -1803,18 +1796,33 @@ static int mdss_mdp_video_ctx_setup(struct mdss_mdp_ctl *ctl, } if (mdss_mdp_is_cdm_supported(mdata, ctl->intf_type, 0)) { ctl->cdm = mdss_mdp_cdm_init(ctl, MDP_CDM_CDWN_OUTPUT_HDMI); fmt = mdss_mdp_get_format_params(pinfo->out_format); if (!fmt) { pr_err("%s: format %d not supported\n", __func__, pinfo->out_format); return -EINVAL; } if (fmt->is_yuv) { ctl->cdm = mdss_mdp_cdm_init(ctl, MDP_CDM_CDWN_OUTPUT_HDMI); if (!IS_ERR_OR_NULL(ctl->cdm)) { if (mdss_mdp_video_cdm_setup(ctl->cdm, pinfo)) { if (mdss_mdp_video_cdm_setup(ctl->cdm, pinfo, fmt)) { pr_err("%s: setting up cdm failed\n", __func__); return -EINVAL; } ctl->flush_bits |= BIT(26); } else { pr_err("%s: failed to initialize cdm\n", __func__); pr_err("%s: failed to initialize cdm\n", __func__); return -EINVAL; } } else { pr_debug("%s: Format is not YUV,cdm not required\n", __func__); } } else { pr_debug("%s: cdm not supported\n", __func__); } Loading drivers/video/msm/mdss/mdss_mdp_intf_writeback.c +12 −17 Original line number Diff line number Diff line Loading @@ -155,17 +155,10 @@ static int mdss_mdp_writeback_addr_setup(struct mdss_mdp_writeback_ctx *ctx, } static int mdss_mdp_writeback_cdm_setup(struct mdss_mdp_writeback_ctx *ctx, struct mdss_mdp_cdm *cdm, u32 format) struct mdss_mdp_cdm *cdm, struct mdss_mdp_format_params *fmt) { struct mdss_mdp_format_params *fmt; struct mdp_cdm_cfg setup; fmt = mdss_mdp_get_format_params(format); if (!fmt) { pr_err("%s: format %d not supported\n", __func__, format); return -EINVAL; } switch (fmt->chroma_sample) { case MDSS_MDP_CHROMA_RGB: setup.horz_downsampling_type = MDP_CDM_CDWN_DISABLE; Loading @@ -185,7 +178,7 @@ static int mdss_mdp_writeback_cdm_setup(struct mdss_mdp_writeback_ctx *ctx, return -EINVAL; } setup.out_format = format; setup.out_format = fmt->format; setup.mdp_csc_bit_depth = MDP_CDM_CSC_8BIT; setup.output_width = ctx->width; setup.output_height = ctx->height; Loading Loading @@ -248,10 +241,9 @@ static int mdss_mdp_writeback_format_setup(struct mdss_mdp_writeback_ctx *ctx, chroma_samp = fmt->chroma_sample; if (ctl->cdm) { rc = mdss_mdp_writeback_cdm_setup(ctx, ctl->cdm, format); rc = mdss_mdp_writeback_cdm_setup(ctx, ctl->cdm, fmt); if (rc) { pr_err("%s: CDM configuration failed with error %d\n", pr_err("%s: CDM config failed with error %d\n", __func__, rc); return rc; } Loading Loading @@ -826,6 +818,7 @@ int mdss_mdp_writeback_start(struct mdss_mdp_ctl *ctl) struct mdss_mdp_writeback *wb; u32 mem_sel; u32 mixer_type = MDSS_MDP_MIXER_TYPE_UNUSED; struct mdss_mdp_format_params *fmt = NULL; bool is_rot; pr_debug("start ctl=%d\n", ctl->num); Loading @@ -849,6 +842,10 @@ int mdss_mdp_writeback_start(struct mdss_mdp_ctl *ctl) return -EINVAL; } fmt = mdss_mdp_get_format_params(ctl->dst_format); if (!fmt) return -EINVAL; is_rot = (ctx->type == MDSS_MDP_WRITEBACK_TYPE_ROTATOR) ? true : false; if (ctl->mixer_left) { Loading @@ -862,15 +859,13 @@ int mdss_mdp_writeback_start(struct mdss_mdp_ctl *ctl) } if (mdss_mdp_is_cdm_supported(ctl->mdata, ctl->intf_type, mixer_type)) { mixer_type) && fmt->is_yuv) { ctl->cdm = mdss_mdp_cdm_init(ctl, MDP_CDM_CDWN_OUTPUT_WB); if (IS_ERR_OR_NULL(ctl->cdm)) { pr_err("%s failed to init cdm\n", __func__); pr_err("cdm block already in use\n"); ctl->cdm = NULL; return -EBUSY; } } else { ctl->cdm = NULL; pr_debug("%s: cdm not supported\n", __func__); } ctl->priv_data = ctx; ctx->wb_num = wb->num; Loading Loading
drivers/video/msm/mdss/mdss_mdp.c +1 −0 Original line number Diff line number Diff line Loading @@ -3391,6 +3391,7 @@ static int mdss_mdp_cdm_addr_setup(struct mdss_data_type *mdata, head[i].base = (mdata->mdss_io.base) + cdm_offsets[i]; atomic_set(&head[i].kref.refcount, 0); mutex_init(&head[i].lock); init_completion(&head[i].free_comp); pr_debug("%s: cdm off (%d) = %p\n", __func__, i, head[i].base); } Loading
drivers/video/msm/mdss/mdss_mdp_cdm.c +25 −11 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ static u32 cdm_cdwn2_offsite_h_coeff[] = {0x000b0005, 0x01db01eb, 0x00e40046}; static u32 cdm_cdwn2_cosite_v_coeff[] = {0x00080004}; static u32 cdm_cdwn2_offsite_v_coeff[] = {0x00060002}; #define VSYNC_TIMEOUT_US 16000 /** * @mdss_mdp_cdm_alloc() - Allocates a cdm block by parsing the list of * available cdm blocks. Loading Loading @@ -66,6 +68,7 @@ static void mdss_mdp_cdm_free(struct kref *kref) if (!cdm) return; complete_all(&cdm->free_comp); pr_debug("free cdm_num = %d\n", cdm->num); } Loading @@ -84,6 +87,28 @@ struct mdss_mdp_cdm *mdss_mdp_cdm_init(struct mdss_mdp_ctl *ctl, u32 intf_type) cdm = mdss_mdp_cdm_alloc(mdata); /** * give hdmi interface priority to alloc the cdm block. It will wait * for one vsync cycle to allow wfd to finish its job and try to reserve * the block the again. */ if (!cdm && (intf_type == MDP_CDM_CDWN_OUTPUT_HDMI)) { /* always wait for first cdm block */ cdm = mdata->cdm_off; if (cdm) { reinit_completion(&cdm->free_comp); /* * no need to check the return status of completion * timeout. Next cdm_alloc call will try to reserve * the cdm block and returns failure if allocation * fails. */ wait_for_completion_timeout(&cdm->free_comp, usecs_to_jiffies(VSYNC_TIMEOUT_US)); cdm = mdss_mdp_cdm_alloc(mdata); } } if (!cdm) { pr_err("%s: Unable to allocate cdm\n", __func__); return ERR_PTR(-EBUSY); Loading Loading @@ -352,17 +377,6 @@ int mdss_mdp_cdm_destroy(struct mdss_mdp_cdm *cdm) return -EINVAL; } mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON); mutex_lock(&cdm->lock); /* Disable HDMI packer */ writel_relaxed(0x0, cdm->base + MDSS_MDP_REG_CDM_HDMI_PACK_OP_MODE); /* Put CDM in bypass */ writel_relaxed(0x0, cdm->mdata->mdp_base + MDSS_MDP_MDP_OUT_CTL_0); mutex_unlock(&cdm->lock); mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF); kref_put(&cdm->kref, mdss_mdp_cdm_free); return rc; Loading
drivers/video/msm/mdss/mdss_mdp_cdm.h +2 −1 Original line number Diff line number Diff line /* * Copyright (c) 2014, The Linux Foundation. All rights reserved. * Copyright (c) 2014,2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -59,6 +59,7 @@ struct mdss_mdp_cdm { u32 out_intf; bool is_bypassed; struct mdp_cdm_cfg setup; struct completion free_comp; }; struct mdss_mdp_cdm *mdss_mdp_cdm_init(struct mdss_mdp_ctl *ctl, Loading
drivers/video/msm/mdss/mdss_mdp_intf_video.c +26 −18 Original line number Diff line number Diff line Loading @@ -1695,19 +1695,10 @@ static inline bool mdss_mdp_video_need_pixel_drop(u32 vic) } static int mdss_mdp_video_cdm_setup(struct mdss_mdp_cdm *cdm, struct mdss_panel_info *pinfo) struct mdss_panel_info *pinfo, struct mdss_mdp_format_params *fmt) { struct mdss_mdp_format_params *fmt; struct mdp_cdm_cfg setup; fmt = mdss_mdp_get_format_params(pinfo->out_format); if (!fmt) { pr_err("%s: format %d not supported\n", __func__, pinfo->out_format); return -EINVAL; } setup.out_format = pinfo->out_format; if (fmt->is_yuv) setup.csc_type = MDSS_MDP_CSC_RGB2YUV_601FR; else Loading Loading @@ -1737,6 +1728,7 @@ static int mdss_mdp_video_cdm_setup(struct mdss_mdp_cdm *cdm, return -EINVAL; } setup.out_format = pinfo->out_format; setup.mdp_csc_bit_depth = MDP_CDM_CSC_8BIT; setup.output_width = pinfo->xres + pinfo->lcdc.xres_pad; setup.output_height = pinfo->yres + pinfo->lcdc.yres_pad; Loading Loading @@ -1770,6 +1762,7 @@ static int mdss_mdp_video_ctx_setup(struct mdss_mdp_ctl *ctl, { struct intf_timing_params *itp = &ctx->itp; u32 dst_bpp; struct mdss_mdp_format_params *fmt; struct mdss_data_type *mdata = ctl->mdata; struct dsc_desc *dsc = NULL; Loading Loading @@ -1803,18 +1796,33 @@ static int mdss_mdp_video_ctx_setup(struct mdss_mdp_ctl *ctl, } if (mdss_mdp_is_cdm_supported(mdata, ctl->intf_type, 0)) { ctl->cdm = mdss_mdp_cdm_init(ctl, MDP_CDM_CDWN_OUTPUT_HDMI); fmt = mdss_mdp_get_format_params(pinfo->out_format); if (!fmt) { pr_err("%s: format %d not supported\n", __func__, pinfo->out_format); return -EINVAL; } if (fmt->is_yuv) { ctl->cdm = mdss_mdp_cdm_init(ctl, MDP_CDM_CDWN_OUTPUT_HDMI); if (!IS_ERR_OR_NULL(ctl->cdm)) { if (mdss_mdp_video_cdm_setup(ctl->cdm, pinfo)) { if (mdss_mdp_video_cdm_setup(ctl->cdm, pinfo, fmt)) { pr_err("%s: setting up cdm failed\n", __func__); return -EINVAL; } ctl->flush_bits |= BIT(26); } else { pr_err("%s: failed to initialize cdm\n", __func__); pr_err("%s: failed to initialize cdm\n", __func__); return -EINVAL; } } else { pr_debug("%s: Format is not YUV,cdm not required\n", __func__); } } else { pr_debug("%s: cdm not supported\n", __func__); } Loading
drivers/video/msm/mdss/mdss_mdp_intf_writeback.c +12 −17 Original line number Diff line number Diff line Loading @@ -155,17 +155,10 @@ static int mdss_mdp_writeback_addr_setup(struct mdss_mdp_writeback_ctx *ctx, } static int mdss_mdp_writeback_cdm_setup(struct mdss_mdp_writeback_ctx *ctx, struct mdss_mdp_cdm *cdm, u32 format) struct mdss_mdp_cdm *cdm, struct mdss_mdp_format_params *fmt) { struct mdss_mdp_format_params *fmt; struct mdp_cdm_cfg setup; fmt = mdss_mdp_get_format_params(format); if (!fmt) { pr_err("%s: format %d not supported\n", __func__, format); return -EINVAL; } switch (fmt->chroma_sample) { case MDSS_MDP_CHROMA_RGB: setup.horz_downsampling_type = MDP_CDM_CDWN_DISABLE; Loading @@ -185,7 +178,7 @@ static int mdss_mdp_writeback_cdm_setup(struct mdss_mdp_writeback_ctx *ctx, return -EINVAL; } setup.out_format = format; setup.out_format = fmt->format; setup.mdp_csc_bit_depth = MDP_CDM_CSC_8BIT; setup.output_width = ctx->width; setup.output_height = ctx->height; Loading Loading @@ -248,10 +241,9 @@ static int mdss_mdp_writeback_format_setup(struct mdss_mdp_writeback_ctx *ctx, chroma_samp = fmt->chroma_sample; if (ctl->cdm) { rc = mdss_mdp_writeback_cdm_setup(ctx, ctl->cdm, format); rc = mdss_mdp_writeback_cdm_setup(ctx, ctl->cdm, fmt); if (rc) { pr_err("%s: CDM configuration failed with error %d\n", pr_err("%s: CDM config failed with error %d\n", __func__, rc); return rc; } Loading Loading @@ -826,6 +818,7 @@ int mdss_mdp_writeback_start(struct mdss_mdp_ctl *ctl) struct mdss_mdp_writeback *wb; u32 mem_sel; u32 mixer_type = MDSS_MDP_MIXER_TYPE_UNUSED; struct mdss_mdp_format_params *fmt = NULL; bool is_rot; pr_debug("start ctl=%d\n", ctl->num); Loading @@ -849,6 +842,10 @@ int mdss_mdp_writeback_start(struct mdss_mdp_ctl *ctl) return -EINVAL; } fmt = mdss_mdp_get_format_params(ctl->dst_format); if (!fmt) return -EINVAL; is_rot = (ctx->type == MDSS_MDP_WRITEBACK_TYPE_ROTATOR) ? true : false; if (ctl->mixer_left) { Loading @@ -862,15 +859,13 @@ int mdss_mdp_writeback_start(struct mdss_mdp_ctl *ctl) } if (mdss_mdp_is_cdm_supported(ctl->mdata, ctl->intf_type, mixer_type)) { mixer_type) && fmt->is_yuv) { ctl->cdm = mdss_mdp_cdm_init(ctl, MDP_CDM_CDWN_OUTPUT_WB); if (IS_ERR_OR_NULL(ctl->cdm)) { pr_err("%s failed to init cdm\n", __func__); pr_err("cdm block already in use\n"); ctl->cdm = NULL; return -EBUSY; } } else { ctl->cdm = NULL; pr_debug("%s: cdm not supported\n", __func__); } ctl->priv_data = ctx; ctx->wb_num = wb->num; Loading